From fb52d10cd3e7b4359f2ae934ac12396d65cd8163 Mon Sep 17 00:00:00 2001 From: Umer Shahid Date: Mon, 7 Oct 2024 21:32:48 +0500 Subject: [PATCH 1/9] Ci update, ISAC+CTG merged, added converpoints (#495) * Updated CI and added riscof-plugin directory * Added RISCV-CTG and RISCV-ISAC tools * Added covergroups * Updated Readme --------- Co-authored-by: James Shi --- .github/workflows/test.yml | 74 +- README.md | 175 + coverage/README.md | 13 + coverage/Zifencei/rv32e_fencei.cgf | 6 + coverage/Zifencei/rv32i_fencei.cgf | 6 + coverage/Zifencei/rv64i_fencei.cgf | 8 + coverage/{ => Zifencei}/rvi_fencei.cgf | 0 coverage/a/rv32ia.cgf | 170 + coverage/a/rv64ia.cgf | 341 + coverage/b/rv32e_b.cgf | 705 + coverage/b/rv32i_b.cgf | 734 + coverage/b/rv64i_b.cgf | 973 ++ coverage/c/rv32ec.cgf | 446 + coverage/c/rv32i_zcb.cgf | 176 + coverage/c/rv32ic.cgf | 478 + coverage/c/rv64i_zcb.cgf | 190 + coverage/c/rv64ic.cgf | 586 + coverage/{ => c}/rvi_c.cgf | 0 coverage/cgf.yaml | 2239 +++ coverage/cgfs_fext/RV32D/fadd.d.cgf | 188 + coverage/cgfs_fext/RV32D/fclass.d.cgf | 15 + coverage/cgfs_fext/RV32D/fcvt.d.s.cgf | 106 + coverage/cgfs_fext/RV32D/fcvt.d.w.cgf | 28 + coverage/cgfs_fext/RV32D/fcvt.d.wu.cgf | 28 + coverage/cgfs_fext/RV32D/fcvt.s.d.cgf | 106 + coverage/cgfs_fext/RV32D/fcvt.w.d.cgf | 92 + coverage/cgfs_fext/RV32D/fcvt.wu.d.cgf | 92 + coverage/cgfs_fext/RV32D/fdiv.d.cgf | 188 + coverage/cgfs_fext/RV32D/feq.d.cgf | 35 + coverage/cgfs_fext/RV32D/fld-align.cgf | 23 + coverage/cgfs_fext/RV32D/fle.d.cgf | 35 + coverage/cgfs_fext/RV32D/flt.d.cgf | 35 + coverage/cgfs_fext/RV32D/fmadd.d.cgf | 248 + coverage/cgfs_fext/RV32D/fmax.d.cgf | 35 + coverage/cgfs_fext/RV32D/fmin.d.cgf | 35 + coverage/cgfs_fext/RV32D/fmsub.d.cgf | 248 + coverage/cgfs_fext/RV32D/fmul.d.cgf | 155 + coverage/cgfs_fext/RV32D/fnmadd.d.cgf | 248 + coverage/cgfs_fext/RV32D/fnmsub.d.cgf | 248 + coverage/cgfs_fext/RV32D/fsd-align.cgf | 23 + coverage/cgfs_fext/RV32D/fsgnj.d.cgf | 19 + coverage/cgfs_fext/RV32D/fsgnjn.d.cgf | 19 + coverage/cgfs_fext/RV32D/fsgnjx.d.cgf | 19 + coverage/cgfs_fext/RV32D/fsqrt.d.cgf | 137 + coverage/cgfs_fext/RV32D/fsub.d.cgf | 188 + coverage/cgfs_fext/RV32F/fadd.s.cgf | 188 + coverage/cgfs_fext/RV32F/fclass.s.cgf | 15 + coverage/cgfs_fext/RV32F/fcvt.s.w.cgf | 28 + coverage/cgfs_fext/RV32F/fcvt.s.wu.cgf | 28 + coverage/cgfs_fext/RV32F/fcvt.w.s.cgf | 92 + coverage/cgfs_fext/RV32F/fcvt.wu.s.cgf | 92 + coverage/cgfs_fext/RV32F/fdiv.s.cgf | 188 + coverage/cgfs_fext/RV32F/feq.s.cgf | 35 + coverage/cgfs_fext/RV32F/fle.s.cgf | 35 + coverage/cgfs_fext/RV32F/flt.s.cgf | 35 + coverage/cgfs_fext/RV32F/flw-align.cgf | 19 + coverage/cgfs_fext/RV32F/fmadd.s.cgf | 248 + coverage/cgfs_fext/RV32F/fmax.s.cgf | 35 + coverage/cgfs_fext/RV32F/fmin.s.cgf | 35 + coverage/cgfs_fext/RV32F/fmsub.s.cgf | 248 + coverage/cgfs_fext/RV32F/fmul.s.cgf | 155 + coverage/cgfs_fext/RV32F/fmv.w.x.cgf | 28 + coverage/cgfs_fext/RV32F/fmv.x.w.cgf | 92 + coverage/cgfs_fext/RV32F/fnmadd.s.cgf | 248 + coverage/cgfs_fext/RV32F/fnmsub.s.cgf | 248 + coverage/cgfs_fext/RV32F/fsgnj.s.cgf | 19 + coverage/cgfs_fext/RV32F/fsgnjn.s.cgf | 19 + coverage/cgfs_fext/RV32F/fsgnjx.s.cgf | 19 + coverage/cgfs_fext/RV32F/fsqrt.s.cgf | 137 + coverage/cgfs_fext/RV32F/fsub.s.cgf | 188 + coverage/cgfs_fext/RV32F/fsw-align.cgf | 19 + coverage/cgfs_fext/RV32H/rv32h_fadd.cgf | 188 + coverage/cgfs_fext/RV32H/rv32h_fclass.cgf | 15 + coverage/cgfs_fext/RV32H/rv32h_fcvt.d.h.cgf | 106 + coverage/cgfs_fext/RV32H/rv32h_fcvt.h.d.cgf | 106 + coverage/cgfs_fext/RV32H/rv32h_fcvt.h.l.cgf | 27 + coverage/cgfs_fext/RV32H/rv32h_fcvt.h.lu.cgf | 27 + coverage/cgfs_fext/RV32H/rv32h_fcvt.h.s.cgf | 106 + coverage/cgfs_fext/RV32H/rv32h_fcvt.h.w.cgf | 27 + coverage/cgfs_fext/RV32H/rv32h_fcvt.h.wu.cgf | 27 + coverage/cgfs_fext/RV32H/rv32h_fcvt.s.h.cgf | 106 + coverage/cgfs_fext/RV32H/rv32h_fcvt.w.h.cgf | 92 + coverage/cgfs_fext/RV32H/rv32h_fcvt.wu.h.cgf | 92 + coverage/cgfs_fext/RV32H/rv32h_fdiv.cgf | 188 + coverage/cgfs_fext/RV32H/rv32h_feq.cgf | 35 + coverage/cgfs_fext/RV32H/rv32h_fle.cgf | 35 + coverage/cgfs_fext/RV32H/rv32h_flh.cgf | 19 + coverage/cgfs_fext/RV32H/rv32h_flt.cgf | 35 + coverage/cgfs_fext/RV32H/rv32h_fmadd.cgf | 229 + coverage/cgfs_fext/RV32H/rv32h_fmax.cgf | 35 + coverage/cgfs_fext/RV32H/rv32h_fmin.cgf | 35 + coverage/cgfs_fext/RV32H/rv32h_fmsub.cgf | 229 + coverage/cgfs_fext/RV32H/rv32h_fmul.cgf | 155 + coverage/cgfs_fext/RV32H/rv32h_fmv.h.x.cgf | 28 + coverage/cgfs_fext/RV32H/rv32h_fmv.x.h.cgf | 92 + coverage/cgfs_fext/RV32H/rv32h_fnmadd.cgf | 229 + coverage/cgfs_fext/RV32H/rv32h_fnmsub.cgf | 229 + coverage/cgfs_fext/RV32H/rv32h_fsgnj.cgf | 19 + coverage/cgfs_fext/RV32H/rv32h_fsgnjn.cgf | 19 + coverage/cgfs_fext/RV32H/rv32h_fsgnjx.cgf | 19 + coverage/cgfs_fext/RV32H/rv32h_fsh.cgf | 19 + coverage/cgfs_fext/RV32H/rv32h_fsqrt.cgf | 136 + coverage/cgfs_fext/RV32H/rv32h_fsub.cgf | 188 + coverage/cgfs_fext/RV64D/fcvt.d.l.cgf | 28 + coverage/cgfs_fext/RV64D/fcvt.d.lu.cgf | 28 + coverage/cgfs_fext/RV64D/fcvt.l.d.cgf | 92 + coverage/cgfs_fext/RV64D/fcvt.lu.d.cgf | 92 + coverage/cgfs_fext/RV64D/fmv.d.x.cgf | 28 + coverage/cgfs_fext/RV64D/fmv.x.d.cgf | 92 + coverage/cgfs_fext/RV64F/fcvt.l.s.cgf | 92 + coverage/cgfs_fext/RV64F/fcvt.lu.s.cgf | 92 + coverage/cgfs_fext/RV64F/fcvt.s.l.cgf | 28 + coverage/cgfs_fext/RV64F/fcvt.s.lu.cgf | 28 + coverage/cgfs_fext/RV64H/rv64h_fcvt.h.l.cgf | 14 + coverage/cgfs_fext/RV64H/rv64h_fcvt.h.lu.cgf | 14 + coverage/cgfs_fext/RV64H/rv64h_fcvt.l.h.cgf | 14 + coverage/cgfs_fext/RV64H/rv64h_fcvt.lu.h.cgf | 14 + coverage/cgfs_fext/RV64Zfinx/fadd.s.cgf | 188 + coverage/cgfs_fext/RV64Zfinx/fclass.s.cgf | 14 + coverage/cgfs_fext/RV64Zfinx/fcvt.l.s.cgf | 92 + coverage/cgfs_fext/RV64Zfinx/fcvt.lu.s.cgf | 92 + coverage/cgfs_fext/RV64Zfinx/fcvt.w.s.cgf | 92 + coverage/cgfs_fext/RV64Zfinx/fcvt.wu.s.cgf | 92 + coverage/cgfs_fext/RV64Zfinx/fdiv.s.cgf | 188 + coverage/cgfs_fext/RV64Zfinx/feq.s.cgf | 35 + coverage/cgfs_fext/RV64Zfinx/fle.s.cgf | 35 + coverage/cgfs_fext/RV64Zfinx/flt.s.cgf | 35 + coverage/cgfs_fext/RV64Zfinx/fmadd.s.cgf | 248 + coverage/cgfs_fext/RV64Zfinx/fmax.s.cgf | 35 + coverage/cgfs_fext/RV64Zfinx/fmin.s.cgf | 35 + coverage/cgfs_fext/RV64Zfinx/fmsub.s.cgf | 247 + coverage/cgfs_fext/RV64Zfinx/fmul.s.cgf | 155 + coverage/cgfs_fext/RV64Zfinx/fnmadd.s.cgf | 247 + coverage/cgfs_fext/RV64Zfinx/fnmsub.s.cgf | 247 + coverage/cgfs_fext/RV64Zfinx/fsgnj.s.cgf | 19 + coverage/cgfs_fext/RV64Zfinx/fsgnjn.s.cgf | 17 + coverage/cgfs_fext/RV64Zfinx/fsgnjx.s.cgf | 19 + coverage/cgfs_fext/RV64Zfinx/fsqrt.s.cgf | 136 + coverage/cgfs_fext/RV64Zfinx/fsub.s.cgf | 188 + coverage/{ => cmo}/rvi_cmo.cgf | 0 coverage/coverpoints.yaml | 1915 +++ coverage/dataset.cgf | 209 +- coverage/e/rv32e.cgf | 752 + coverage/i/rv32i.cgf | 752 + coverage/i/rv64i.cgf | 1003 ++ coverage/{ => i}/rvi.cgf | 0 coverage/k/rv32i_k.cgf | 537 + coverage/k/rv64i_k.cgf | 517 + coverage/m/rv32em.cgf | 154 + coverage/m/rv32im.cgf | 154 + coverage/m/rv64im.cgf | 250 + coverage/{ => m}/rvi_m.cgf | 0 coverage/p/rv32ip.cgf | 4419 ++++++ coverage/p/rv64ip.cgf | 1578 ++ coverage/priv/rv32e_priv.cgf | 146 + coverage/priv/rv32i_priv.cgf | 174 + coverage/priv/rv64i_priv.cgf | 215 + coverage/{ => priv}/rvi_priv.cgf | 0 coverage/srm/srmcfg.cgf | 77 + coverage/{ => svadu}/rv32_svadu.cgf | 0 coverage/{ => svadu}/rv64_svadu.cgf | 0 coverage/zabha/rv32zabha.cgf | 362 + coverage/{ => zacas}/rv32zacas.cgf | 0 coverage/{ => zacas}/rv64zacas.cgf | 0 coverage/{ => zcmop}/zcmop.cgf | 14 +- coverage/zfa/fcvtmod.w.d.cgf | 92 + coverage/zfa/fleq.d.cgf | 35 + coverage/zfa/fleq.s.cgf | 35 + coverage/zfa/fli.d.cgf | 9 + coverage/zfa/fli.s.cgf | 9 + coverage/zfa/fltq.d.cgf | 35 + coverage/zfa/fltq.s.cgf | 35 + coverage/zfa/fmaxm.d.cgf | 35 + coverage/zfa/fmaxm.s.cgf | 35 + coverage/zfa/fminm.d.cgf | 35 + coverage/zfa/fminm.s.cgf | 35 + coverage/zfa/fmvh.x.d.cgf | 92 + coverage/zfa/fmvp.d.x.cgf | 33 + coverage/zfa/fround.d.cgf | 16 + coverage/zfa/fround.s.cgf | 16 + coverage/zfa/froundnx.d.cgf | 16 + coverage/zfa/froundnx.s.cgf | 16 + coverage/zicfiss/zicfiss.cgf | 133 + coverage/zicflip/zicfilp.cgf | 44 + coverage/{ => zicond}/zicond.cgf | 4 +- coverage/{ => zimop}/zimop.cgf | 80 +- coverage/zvk/vaesdf.cgf | 27 + coverage/zvk/vaesdm.cgf | 27 + coverage/zvk/vaesef.cgf | 27 + coverage/zvk/vaesem.cgf | 27 + coverage/zvk/vaeskf1.cgf | 14 + coverage/zvk/vaeskf2.cgf | 14 + coverage/zvk/vaesz.cgf | 16 + coverage/zvk/vandn.cgf | 29 + coverage/zvk/vbrev8.cgf | 14 + coverage/zvk/vclmul.cgf | 29 + coverage/zvk/vclmulh.cgf | 29 + coverage/zvk/vghsh.cgf | 15 + coverage/zvk/vgmul.cgf | 14 + coverage/zvk/vrev8.cgf | 14 + coverage/zvk/vrol.cgf | 29 + coverage/zvk/vror.cgf | 42 + coverage/zvk/vsha2ch.cgf | 29 + coverage/zvk/vsha2cl.cfg | 29 + coverage/zvk/vsha2ms.cgf | 29 + coverage/zvk/vsm3c.cgf | 14 + coverage/zvk/vsm3me.cgf | 14 + coverage/zvk/vsm4k.cgf | 14 + coverage/zvk/vsm4r.cgf | 27 + riscof-plugins/rv32/config.ini | 14 + riscof-plugins/rv32/makeplugin/README.md | 95 + riscof-plugins/rv32/makeplugin/__init__.py | 2 + riscof-plugins/rv32/makeplugin/env/link.ld | 18 + .../rv32/makeplugin/env/model_test.h | 60 + .../rv32/makeplugin/riscof_makeplugin.py | 180 + riscof-plugins/rv32/makeplugin/sail.include | 21 + riscof-plugins/rv32/sail_cSim/README.md | 90 + riscof-plugins/rv32/sail_cSim/__init__.py | 2 + .../riscof_sail_cSim.cpython-310.pyc | Bin 0 -> 5456 bytes riscof-plugins/rv32/sail_cSim/env/link.ld | 18 + .../rv32/sail_cSim/env/model_test.h | 57 + .../rv32/sail_cSim/riscof_sail_cSim.py | 165 + riscof-plugins/rv32/sail_cSim/sail_isa.yaml | 38 + .../rv32/sail_cSim/sail_platform.yaml | 4 + riscof-plugins/rv32/spike_simple/README.md | 30 + riscof-plugins/rv32/spike_simple/__init__.py | 2 + .../riscof_spike_simple.cpython-310.pyc | Bin 0 -> 3476 bytes riscof-plugins/rv32/spike_simple/env/link.ld | 18 + .../rv32/spike_simple/env/model_test.h | 60 + .../rv32/spike_simple/env/sign_fix.sh | 3 + .../rv32/spike_simple/riscof_spike_simple.py | 254 + .../rv32/spike_simple/spike_simple_isa.yaml | 29 + .../spike_simple/spike_simple_platform.yaml | 10 + riscof-plugins/rv64/config.ini | 14 + riscof-plugins/rv64/makeplugin/README.md | 95 + riscof-plugins/rv64/makeplugin/__init__.py | 2 + riscof-plugins/rv64/makeplugin/env/link.ld | 18 + .../rv64/makeplugin/env/model_test.h | 60 + .../rv64/makeplugin/riscof_makeplugin.py | 180 + riscof-plugins/rv64/makeplugin/sail.include | 21 + riscof-plugins/rv64/sail_cSim/__init__.py | 2 + .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 243 bytes .../riscof_sail_cSim.cpython-310.pyc | Bin 0 -> 4759 bytes .../riscof_sail_cSim.cpython-38.pyc | Bin 0 -> 4450 bytes riscof-plugins/rv64/sail_cSim/env/link.ld | 18 + .../rv64/sail_cSim/env/model_test.h | 55 + .../rv64/sail_cSim/riscof_sail_cSim.py | 133 + riscof-plugins/rv64/spike_simple/README.md | 30 + riscof-plugins/rv64/spike_simple/__init__.py | 2 + .../__pycache__/riscof_model.cpython-38.pyc | Bin 0 -> 3225 bytes .../__pycache__/riscof_spike.cpython-310.pyc | Bin 0 -> 3360 bytes .../__pycache__/riscof_spike.cpython-38.pyc | Bin 0 -> 3197 bytes .../riscof_spike_simple.cpython-310.pyc | Bin 0 -> 3455 bytes .../riscof_spike_simple.cpython-38.pyc | Bin 0 -> 3496 bytes riscof-plugins/rv64/spike_simple/env/link.ld | 18 + .../rv64/spike_simple/env/model_test.h | 60 + .../rv64/spike_simple/env/sign_fix.sh | 3 + .../rv64/spike_simple/riscof_spike_simple.py | 254 + .../rv64/spike_simple/spike_simple_isa.yaml | 29 + .../spike_simple/spike_simple_platform.yaml | 10 + riscv-ctg/.gitignore | 107 + riscv-ctg/CHANGELOG.md | 206 + riscv-ctg/CONTRIBUTING.rst | 119 + riscv-ctg/LICENSE.incore | 30 + riscv-ctg/MANIFEST.in | 9 + riscv-ctg/README.rst | 7 + riscv-ctg/docs/Makefile | 26 + riscv-ctg/docs/README.md | 15 + riscv-ctg/docs/requirements.txt | 38 + riscv-ctg/docs/source/_static/custom.css | 305 + riscv-ctg/docs/source/_static/incore_logo.png | Bin 0 -> 113714 bytes riscv-ctg/docs/source/_static/l1cache.png | Bin 0 -> 85241 bytes riscv-ctg/docs/source/_static/onlyC.png | Bin 0 -> 24234 bytes riscv-ctg/docs/source/_static/riscv-ctg.png | Bin 0 -> 38028 bytes .../docs/source/_static/theme_overrides.css | 13 + .../docs/source/_templates/breadcrumbs.html | 14 + riscv-ctg/docs/source/_templates/layout.html | 14 + .../docs/source/_templates/versions.html | 25 + riscv-ctg/docs/source/add_instr.rst | 48 + riscv-ctg/docs/source/cli.rst | 91 + riscv-ctg/docs/source/code.rst | 21 + riscv-ctg/docs/source/conf.py | 450 + riscv-ctg/docs/source/contributing.rst | 1 + riscv-ctg/docs/source/cross_comb.rst | 35 + riscv-ctg/docs/source/csr_comb.rst | 26 + riscv-ctg/docs/source/diagrams/git_flow.png | Bin 0 -> 21845 bytes riscv-ctg/docs/source/index.rst | 25 + riscv-ctg/docs/source/index_bkp | 103 + riscv-ctg/docs/source/installation.rst | 162 + riscv-ctg/docs/source/licensing.rst | 10 + riscv-ctg/docs/source/overview.rst | 166 + riscv-ctg/docs/source/pseudo_op_support.rst | 45 + riscv-ctg/docs/source/refs.bib | 19 + riscv-ctg/docs/source/revisions.rst | 7 + riscv-ctg/docs/sphinxext/cairosvgconverter.py | 38 + riscv-ctg/riscv_ctg/__init__.py | 7 + riscv-ctg/riscv_ctg/constants.py | 334 + riscv-ctg/riscv_ctg/cross_comb.py | 501 + riscv-ctg/riscv_ctg/csr_comb.py | 425 + riscv-ctg/riscv_ctg/ctg.py | 139 + riscv-ctg/riscv_ctg/data/fd.yaml | 3043 ++++ riscv-ctg/riscv_ctg/data/imc.yaml | 1892 +++ riscv-ctg/riscv_ctg/data/inx.yaml | 1530 ++ riscv-ctg/riscv_ctg/data/template.yaml | 12663 ++++++++++++++++ riscv-ctg/riscv_ctg/dsp_function.py | 243 + riscv-ctg/riscv_ctg/function_generators.py | 260 + riscv-ctg/riscv_ctg/generator.py | 1452 ++ riscv-ctg/riscv_ctg/helpers.py | 98 + riscv-ctg/riscv_ctg/log.py | 92 + riscv-ctg/riscv_ctg/main.py | 30 + .../riscv_ctg/misc/bitmanip_real_world.py | 442 + riscv-ctg/riscv_ctg/requirements.txt | 5 + riscv-ctg/riscv_ctg/utils.py | 359 + riscv-ctg/setup.cfg | 16 + riscv-ctg/setup.py | 63 + riscv-ctg/tests/__init__.py | 2 + riscv-ctg/tests/test_riscv_ctg.py | 21 + riscv-isac/.gitignore | 105 + riscv-isac/CHANGELOG.md | 169 + riscv-isac/CONTRIBUTING.rst | 105 + riscv-isac/LICENSE.incore | 30 + riscv-isac/MANIFEST.in | 7 + riscv-isac/README.rst | 5 + riscv-isac/docs/Makefile | 26 + riscv-isac/docs/README.md | 15 + riscv-isac/docs/requirements.txt | 40 + riscv-isac/docs/source/Cross_coverage.rst | 134 + riscv-isac/docs/source/_static/custom.css | 309 + .../docs/source/_static/incore_logo.png | Bin 0 -> 113714 bytes riscv-isac/docs/source/_static/l1cache.png | Bin 0 -> 85241 bytes riscv-isac/docs/source/_static/onlyC.png | Bin 0 -> 24234 bytes riscv-isac/docs/source/_static/riscv-isac.png | Bin 0 -> 98484 bytes .../docs/source/_static/theme_overrides.css | 18 + .../docs/source/_templates/breadcrumbs.html | 14 + riscv-isac/docs/source/_templates/layout.html | 14 + .../docs/source/_templates/versions.html | 25 + riscv-isac/docs/source/add_instr.rst | 40 + riscv-isac/docs/source/cgf.rst | 770 + riscv-isac/docs/source/code.rst | 38 + riscv-isac/docs/source/conf.py | 449 + riscv-isac/docs/source/contributing.rst | 1 + riscv-isac/docs/source/diagrams/git_flow.png | Bin 0 -> 21845 bytes riscv-isac/docs/source/dpr.rst | 12 + riscv-isac/docs/source/index.rst | 27 + riscv-isac/docs/source/index_bkp | 103 + riscv-isac/docs/source/isac_cov_calc.rst | 48 + riscv-isac/docs/source/licensing.rst | 10 + riscv-isac/docs/source/overview.rst | 130 + riscv-isac/docs/source/pseudo_op_support.rst | 48 + riscv-isac/docs/source/python_plugins.rst | 184 + riscv-isac/docs/source/quickstart.rst | 335 + riscv-isac/docs/source/refs.bib | 19 + riscv-isac/docs/source/revisions.rst | 7 + riscv-isac/docs/source/rvopcodesdecoder.rst | 39 + .../docs/sphinxext/cairosvgconverter.py | 38 + riscv-isac/interface.py | 38 + riscv-isac/riscv_isac/InstructionObject.py | 728 + riscv-isac/riscv_isac/__init__.py | 8 + riscv-isac/riscv_isac/cgf_normalize.py | 624 + riscv-isac/riscv_isac/constants.py | 83 + riscv-isac/riscv_isac/coverage.py | 1781 +++ riscv-isac/riscv_isac/data/__init__.py | 0 riscv-isac/riscv_isac/data/constants.py | 599 + riscv-isac/riscv_isac/data/instr_alias.yaml | 93 + .../riscv_isac/data/rvopcodesdecoder.py | 724 + riscv-isac/riscv_isac/fp_dataset.py | 5449 +++++++ riscv-isac/riscv_isac/isac.py | 100 + riscv-isac/riscv_isac/log.py | 92 + riscv-isac/riscv_isac/main.py | 274 + riscv-isac/riscv_isac/plugins/__init__.py | 5 + riscv-isac/riscv_isac/plugins/c_sail.py | 143 + .../riscv_isac/plugins/internaldecoder.py | 2381 +++ .../riscv_isac/plugins/specification.py | 22 + riscv-isac/riscv_isac/plugins/spike.py | 56 + .../riscv_isac/plugins/translator_cgf.py | 749 + riscv-isac/riscv_isac/requirements.txt | 8 + riscv-isac/riscv_isac/test_requirements.txt | 1 + riscv-isac/riscv_isac/utils.py | 428 + riscv-isac/setup.cfg | 20 + riscv-isac/setup.py | 58 + riscv-isac/tests/__init__.py | 2 + riscv-isac/tests/test_riscv_isac.py | 19 + 382 files changed, 78686 insertions(+), 80 deletions(-) create mode 100644 coverage/README.md create mode 100644 coverage/Zifencei/rv32e_fencei.cgf create mode 100644 coverage/Zifencei/rv32i_fencei.cgf create mode 100644 coverage/Zifencei/rv64i_fencei.cgf rename coverage/{ => Zifencei}/rvi_fencei.cgf (100%) create mode 100644 coverage/a/rv32ia.cgf create mode 100644 coverage/a/rv64ia.cgf create mode 100644 coverage/b/rv32e_b.cgf create mode 100644 coverage/b/rv32i_b.cgf create mode 100644 coverage/b/rv64i_b.cgf create mode 100644 coverage/c/rv32ec.cgf create mode 100644 coverage/c/rv32i_zcb.cgf create mode 100644 coverage/c/rv32ic.cgf create mode 100644 coverage/c/rv64i_zcb.cgf create mode 100644 coverage/c/rv64ic.cgf rename coverage/{ => c}/rvi_c.cgf (100%) create mode 100644 coverage/cgf.yaml create mode 100644 coverage/cgfs_fext/RV32D/fadd.d.cgf create mode 100644 coverage/cgfs_fext/RV32D/fclass.d.cgf create mode 100644 coverage/cgfs_fext/RV32D/fcvt.d.s.cgf create mode 100644 coverage/cgfs_fext/RV32D/fcvt.d.w.cgf create mode 100644 coverage/cgfs_fext/RV32D/fcvt.d.wu.cgf create mode 100644 coverage/cgfs_fext/RV32D/fcvt.s.d.cgf create mode 100644 coverage/cgfs_fext/RV32D/fcvt.w.d.cgf create mode 100644 coverage/cgfs_fext/RV32D/fcvt.wu.d.cgf create mode 100644 coverage/cgfs_fext/RV32D/fdiv.d.cgf create mode 100644 coverage/cgfs_fext/RV32D/feq.d.cgf create mode 100644 coverage/cgfs_fext/RV32D/fld-align.cgf create mode 100644 coverage/cgfs_fext/RV32D/fle.d.cgf create mode 100644 coverage/cgfs_fext/RV32D/flt.d.cgf create mode 100644 coverage/cgfs_fext/RV32D/fmadd.d.cgf create mode 100644 coverage/cgfs_fext/RV32D/fmax.d.cgf create mode 100644 coverage/cgfs_fext/RV32D/fmin.d.cgf create mode 100644 coverage/cgfs_fext/RV32D/fmsub.d.cgf create mode 100644 coverage/cgfs_fext/RV32D/fmul.d.cgf create mode 100644 coverage/cgfs_fext/RV32D/fnmadd.d.cgf create mode 100644 coverage/cgfs_fext/RV32D/fnmsub.d.cgf create mode 100644 coverage/cgfs_fext/RV32D/fsd-align.cgf create mode 100644 coverage/cgfs_fext/RV32D/fsgnj.d.cgf create mode 100644 coverage/cgfs_fext/RV32D/fsgnjn.d.cgf create mode 100644 coverage/cgfs_fext/RV32D/fsgnjx.d.cgf create mode 100644 coverage/cgfs_fext/RV32D/fsqrt.d.cgf create mode 100644 coverage/cgfs_fext/RV32D/fsub.d.cgf create mode 100644 coverage/cgfs_fext/RV32F/fadd.s.cgf create mode 100644 coverage/cgfs_fext/RV32F/fclass.s.cgf create mode 100644 coverage/cgfs_fext/RV32F/fcvt.s.w.cgf create mode 100644 coverage/cgfs_fext/RV32F/fcvt.s.wu.cgf create mode 100644 coverage/cgfs_fext/RV32F/fcvt.w.s.cgf create mode 100644 coverage/cgfs_fext/RV32F/fcvt.wu.s.cgf create mode 100644 coverage/cgfs_fext/RV32F/fdiv.s.cgf create mode 100644 coverage/cgfs_fext/RV32F/feq.s.cgf create mode 100644 coverage/cgfs_fext/RV32F/fle.s.cgf create mode 100644 coverage/cgfs_fext/RV32F/flt.s.cgf create mode 100644 coverage/cgfs_fext/RV32F/flw-align.cgf create mode 100644 coverage/cgfs_fext/RV32F/fmadd.s.cgf create mode 100644 coverage/cgfs_fext/RV32F/fmax.s.cgf create mode 100644 coverage/cgfs_fext/RV32F/fmin.s.cgf create mode 100644 coverage/cgfs_fext/RV32F/fmsub.s.cgf create mode 100644 coverage/cgfs_fext/RV32F/fmul.s.cgf create mode 100644 coverage/cgfs_fext/RV32F/fmv.w.x.cgf create mode 100644 coverage/cgfs_fext/RV32F/fmv.x.w.cgf create mode 100644 coverage/cgfs_fext/RV32F/fnmadd.s.cgf create mode 100644 coverage/cgfs_fext/RV32F/fnmsub.s.cgf create mode 100644 coverage/cgfs_fext/RV32F/fsgnj.s.cgf create mode 100644 coverage/cgfs_fext/RV32F/fsgnjn.s.cgf create mode 100644 coverage/cgfs_fext/RV32F/fsgnjx.s.cgf create mode 100644 coverage/cgfs_fext/RV32F/fsqrt.s.cgf create mode 100644 coverage/cgfs_fext/RV32F/fsub.s.cgf create mode 100644 coverage/cgfs_fext/RV32F/fsw-align.cgf create mode 100644 coverage/cgfs_fext/RV32H/rv32h_fadd.cgf create mode 100644 coverage/cgfs_fext/RV32H/rv32h_fclass.cgf create mode 100644 coverage/cgfs_fext/RV32H/rv32h_fcvt.d.h.cgf create mode 100644 coverage/cgfs_fext/RV32H/rv32h_fcvt.h.d.cgf create mode 100644 coverage/cgfs_fext/RV32H/rv32h_fcvt.h.l.cgf create mode 100644 coverage/cgfs_fext/RV32H/rv32h_fcvt.h.lu.cgf create mode 100644 coverage/cgfs_fext/RV32H/rv32h_fcvt.h.s.cgf create mode 100644 coverage/cgfs_fext/RV32H/rv32h_fcvt.h.w.cgf create mode 100644 coverage/cgfs_fext/RV32H/rv32h_fcvt.h.wu.cgf create mode 100644 coverage/cgfs_fext/RV32H/rv32h_fcvt.s.h.cgf create mode 100644 coverage/cgfs_fext/RV32H/rv32h_fcvt.w.h.cgf create mode 100644 coverage/cgfs_fext/RV32H/rv32h_fcvt.wu.h.cgf create mode 100644 coverage/cgfs_fext/RV32H/rv32h_fdiv.cgf create mode 100644 coverage/cgfs_fext/RV32H/rv32h_feq.cgf create mode 100644 coverage/cgfs_fext/RV32H/rv32h_fle.cgf create mode 100644 coverage/cgfs_fext/RV32H/rv32h_flh.cgf create mode 100644 coverage/cgfs_fext/RV32H/rv32h_flt.cgf create mode 100644 coverage/cgfs_fext/RV32H/rv32h_fmadd.cgf create mode 100644 coverage/cgfs_fext/RV32H/rv32h_fmax.cgf create mode 100644 coverage/cgfs_fext/RV32H/rv32h_fmin.cgf create mode 100644 coverage/cgfs_fext/RV32H/rv32h_fmsub.cgf create mode 100644 coverage/cgfs_fext/RV32H/rv32h_fmul.cgf create mode 100644 coverage/cgfs_fext/RV32H/rv32h_fmv.h.x.cgf create mode 100644 coverage/cgfs_fext/RV32H/rv32h_fmv.x.h.cgf create mode 100644 coverage/cgfs_fext/RV32H/rv32h_fnmadd.cgf create mode 100644 coverage/cgfs_fext/RV32H/rv32h_fnmsub.cgf create mode 100644 coverage/cgfs_fext/RV32H/rv32h_fsgnj.cgf create mode 100644 coverage/cgfs_fext/RV32H/rv32h_fsgnjn.cgf create mode 100644 coverage/cgfs_fext/RV32H/rv32h_fsgnjx.cgf create mode 100644 coverage/cgfs_fext/RV32H/rv32h_fsh.cgf create mode 100644 coverage/cgfs_fext/RV32H/rv32h_fsqrt.cgf create mode 100644 coverage/cgfs_fext/RV32H/rv32h_fsub.cgf create mode 100644 coverage/cgfs_fext/RV64D/fcvt.d.l.cgf create mode 100644 coverage/cgfs_fext/RV64D/fcvt.d.lu.cgf create mode 100644 coverage/cgfs_fext/RV64D/fcvt.l.d.cgf create mode 100644 coverage/cgfs_fext/RV64D/fcvt.lu.d.cgf create mode 100644 coverage/cgfs_fext/RV64D/fmv.d.x.cgf create mode 100644 coverage/cgfs_fext/RV64D/fmv.x.d.cgf create mode 100644 coverage/cgfs_fext/RV64F/fcvt.l.s.cgf create mode 100644 coverage/cgfs_fext/RV64F/fcvt.lu.s.cgf create mode 100644 coverage/cgfs_fext/RV64F/fcvt.s.l.cgf create mode 100644 coverage/cgfs_fext/RV64F/fcvt.s.lu.cgf create mode 100644 coverage/cgfs_fext/RV64H/rv64h_fcvt.h.l.cgf create mode 100644 coverage/cgfs_fext/RV64H/rv64h_fcvt.h.lu.cgf create mode 100644 coverage/cgfs_fext/RV64H/rv64h_fcvt.l.h.cgf create mode 100644 coverage/cgfs_fext/RV64H/rv64h_fcvt.lu.h.cgf create mode 100644 coverage/cgfs_fext/RV64Zfinx/fadd.s.cgf create mode 100644 coverage/cgfs_fext/RV64Zfinx/fclass.s.cgf create mode 100644 coverage/cgfs_fext/RV64Zfinx/fcvt.l.s.cgf create mode 100644 coverage/cgfs_fext/RV64Zfinx/fcvt.lu.s.cgf create mode 100644 coverage/cgfs_fext/RV64Zfinx/fcvt.w.s.cgf create mode 100644 coverage/cgfs_fext/RV64Zfinx/fcvt.wu.s.cgf create mode 100644 coverage/cgfs_fext/RV64Zfinx/fdiv.s.cgf create mode 100644 coverage/cgfs_fext/RV64Zfinx/feq.s.cgf create mode 100644 coverage/cgfs_fext/RV64Zfinx/fle.s.cgf create mode 100644 coverage/cgfs_fext/RV64Zfinx/flt.s.cgf create mode 100644 coverage/cgfs_fext/RV64Zfinx/fmadd.s.cgf create mode 100644 coverage/cgfs_fext/RV64Zfinx/fmax.s.cgf create mode 100644 coverage/cgfs_fext/RV64Zfinx/fmin.s.cgf create mode 100644 coverage/cgfs_fext/RV64Zfinx/fmsub.s.cgf create mode 100644 coverage/cgfs_fext/RV64Zfinx/fmul.s.cgf create mode 100644 coverage/cgfs_fext/RV64Zfinx/fnmadd.s.cgf create mode 100644 coverage/cgfs_fext/RV64Zfinx/fnmsub.s.cgf create mode 100644 coverage/cgfs_fext/RV64Zfinx/fsgnj.s.cgf create mode 100644 coverage/cgfs_fext/RV64Zfinx/fsgnjn.s.cgf create mode 100644 coverage/cgfs_fext/RV64Zfinx/fsgnjx.s.cgf create mode 100644 coverage/cgfs_fext/RV64Zfinx/fsqrt.s.cgf create mode 100644 coverage/cgfs_fext/RV64Zfinx/fsub.s.cgf rename coverage/{ => cmo}/rvi_cmo.cgf (100%) create mode 100644 coverage/coverpoints.yaml create mode 100644 coverage/e/rv32e.cgf create mode 100644 coverage/i/rv32i.cgf create mode 100644 coverage/i/rv64i.cgf rename coverage/{ => i}/rvi.cgf (100%) create mode 100644 coverage/k/rv32i_k.cgf create mode 100644 coverage/k/rv64i_k.cgf create mode 100644 coverage/m/rv32em.cgf create mode 100644 coverage/m/rv32im.cgf create mode 100644 coverage/m/rv64im.cgf rename coverage/{ => m}/rvi_m.cgf (100%) create mode 100644 coverage/p/rv32ip.cgf create mode 100644 coverage/p/rv64ip.cgf create mode 100644 coverage/priv/rv32e_priv.cgf create mode 100644 coverage/priv/rv32i_priv.cgf create mode 100644 coverage/priv/rv64i_priv.cgf rename coverage/{ => priv}/rvi_priv.cgf (100%) create mode 100644 coverage/srm/srmcfg.cgf rename coverage/{ => svadu}/rv32_svadu.cgf (100%) rename coverage/{ => svadu}/rv64_svadu.cgf (100%) create mode 100644 coverage/zabha/rv32zabha.cgf rename coverage/{ => zacas}/rv32zacas.cgf (100%) rename coverage/{ => zacas}/rv64zacas.cgf (100%) rename coverage/{ => zcmop}/zcmop.cgf (91%) create mode 100644 coverage/zfa/fcvtmod.w.d.cgf create mode 100644 coverage/zfa/fleq.d.cgf create mode 100644 coverage/zfa/fleq.s.cgf create mode 100644 coverage/zfa/fli.d.cgf create mode 100644 coverage/zfa/fli.s.cgf create mode 100644 coverage/zfa/fltq.d.cgf create mode 100644 coverage/zfa/fltq.s.cgf create mode 100644 coverage/zfa/fmaxm.d.cgf create mode 100644 coverage/zfa/fmaxm.s.cgf create mode 100644 coverage/zfa/fminm.d.cgf create mode 100644 coverage/zfa/fminm.s.cgf create mode 100644 coverage/zfa/fmvh.x.d.cgf create mode 100644 coverage/zfa/fmvp.d.x.cgf create mode 100644 coverage/zfa/fround.d.cgf create mode 100644 coverage/zfa/fround.s.cgf create mode 100644 coverage/zfa/froundnx.d.cgf create mode 100644 coverage/zfa/froundnx.s.cgf create mode 100644 coverage/zicfiss/zicfiss.cgf create mode 100644 coverage/zicflip/zicfilp.cgf rename coverage/{ => zicond}/zicond.cgf (96%) rename coverage/{ => zimop}/zimop.cgf (96%) create mode 100644 coverage/zvk/vaesdf.cgf create mode 100644 coverage/zvk/vaesdm.cgf create mode 100644 coverage/zvk/vaesef.cgf create mode 100644 coverage/zvk/vaesem.cgf create mode 100644 coverage/zvk/vaeskf1.cgf create mode 100644 coverage/zvk/vaeskf2.cgf create mode 100644 coverage/zvk/vaesz.cgf create mode 100644 coverage/zvk/vandn.cgf create mode 100644 coverage/zvk/vbrev8.cgf create mode 100644 coverage/zvk/vclmul.cgf create mode 100644 coverage/zvk/vclmulh.cgf create mode 100644 coverage/zvk/vghsh.cgf create mode 100644 coverage/zvk/vgmul.cgf create mode 100644 coverage/zvk/vrev8.cgf create mode 100644 coverage/zvk/vrol.cgf create mode 100644 coverage/zvk/vror.cgf create mode 100644 coverage/zvk/vsha2ch.cgf create mode 100644 coverage/zvk/vsha2cl.cfg create mode 100644 coverage/zvk/vsha2ms.cgf create mode 100644 coverage/zvk/vsm3c.cgf create mode 100644 coverage/zvk/vsm3me.cgf create mode 100644 coverage/zvk/vsm4k.cgf create mode 100644 coverage/zvk/vsm4r.cgf create mode 100755 riscof-plugins/rv32/config.ini create mode 100755 riscof-plugins/rv32/makeplugin/README.md create mode 100755 riscof-plugins/rv32/makeplugin/__init__.py create mode 100755 riscof-plugins/rv32/makeplugin/env/link.ld create mode 100755 riscof-plugins/rv32/makeplugin/env/model_test.h create mode 100755 riscof-plugins/rv32/makeplugin/riscof_makeplugin.py create mode 100755 riscof-plugins/rv32/makeplugin/sail.include create mode 100644 riscof-plugins/rv32/sail_cSim/README.md create mode 100644 riscof-plugins/rv32/sail_cSim/__init__.py create mode 100644 riscof-plugins/rv32/sail_cSim/__pycache__/riscof_sail_cSim.cpython-310.pyc create mode 100644 riscof-plugins/rv32/sail_cSim/env/link.ld create mode 100644 riscof-plugins/rv32/sail_cSim/env/model_test.h create mode 100644 riscof-plugins/rv32/sail_cSim/riscof_sail_cSim.py create mode 100644 riscof-plugins/rv32/sail_cSim/sail_isa.yaml create mode 100644 riscof-plugins/rv32/sail_cSim/sail_platform.yaml create mode 100644 riscof-plugins/rv32/spike_simple/README.md create mode 100644 riscof-plugins/rv32/spike_simple/__init__.py create mode 100644 riscof-plugins/rv32/spike_simple/__pycache__/riscof_spike_simple.cpython-310.pyc create mode 100644 riscof-plugins/rv32/spike_simple/env/link.ld create mode 100644 riscof-plugins/rv32/spike_simple/env/model_test.h create mode 100755 riscof-plugins/rv32/spike_simple/env/sign_fix.sh create mode 100644 riscof-plugins/rv32/spike_simple/riscof_spike_simple.py create mode 100644 riscof-plugins/rv32/spike_simple/spike_simple_isa.yaml create mode 100644 riscof-plugins/rv32/spike_simple/spike_simple_platform.yaml create mode 100755 riscof-plugins/rv64/config.ini create mode 100755 riscof-plugins/rv64/makeplugin/README.md create mode 100755 riscof-plugins/rv64/makeplugin/__init__.py create mode 100755 riscof-plugins/rv64/makeplugin/env/link.ld create mode 100755 riscof-plugins/rv64/makeplugin/env/model_test.h create mode 100755 riscof-plugins/rv64/makeplugin/riscof_makeplugin.py create mode 100755 riscof-plugins/rv64/makeplugin/sail.include create mode 100644 riscof-plugins/rv64/sail_cSim/__init__.py create mode 100644 riscof-plugins/rv64/sail_cSim/__pycache__/__init__.cpython-38.pyc create mode 100644 riscof-plugins/rv64/sail_cSim/__pycache__/riscof_sail_cSim.cpython-310.pyc create mode 100644 riscof-plugins/rv64/sail_cSim/__pycache__/riscof_sail_cSim.cpython-38.pyc create mode 100644 riscof-plugins/rv64/sail_cSim/env/link.ld create mode 100644 riscof-plugins/rv64/sail_cSim/env/model_test.h create mode 100644 riscof-plugins/rv64/sail_cSim/riscof_sail_cSim.py create mode 100755 riscof-plugins/rv64/spike_simple/README.md create mode 100755 riscof-plugins/rv64/spike_simple/__init__.py create mode 100644 riscof-plugins/rv64/spike_simple/__pycache__/riscof_model.cpython-38.pyc create mode 100644 riscof-plugins/rv64/spike_simple/__pycache__/riscof_spike.cpython-310.pyc create mode 100644 riscof-plugins/rv64/spike_simple/__pycache__/riscof_spike.cpython-38.pyc create mode 100644 riscof-plugins/rv64/spike_simple/__pycache__/riscof_spike_simple.cpython-310.pyc create mode 100755 riscof-plugins/rv64/spike_simple/__pycache__/riscof_spike_simple.cpython-38.pyc create mode 100644 riscof-plugins/rv64/spike_simple/env/link.ld create mode 100644 riscof-plugins/rv64/spike_simple/env/model_test.h create mode 100755 riscof-plugins/rv64/spike_simple/env/sign_fix.sh create mode 100644 riscof-plugins/rv64/spike_simple/riscof_spike_simple.py create mode 100755 riscof-plugins/rv64/spike_simple/spike_simple_isa.yaml create mode 100644 riscof-plugins/rv64/spike_simple/spike_simple_platform.yaml create mode 100644 riscv-ctg/.gitignore create mode 100644 riscv-ctg/CHANGELOG.md create mode 100644 riscv-ctg/CONTRIBUTING.rst create mode 100644 riscv-ctg/LICENSE.incore create mode 100644 riscv-ctg/MANIFEST.in create mode 100644 riscv-ctg/README.rst create mode 100644 riscv-ctg/docs/Makefile create mode 100644 riscv-ctg/docs/README.md create mode 100644 riscv-ctg/docs/requirements.txt create mode 100644 riscv-ctg/docs/source/_static/custom.css create mode 100644 riscv-ctg/docs/source/_static/incore_logo.png create mode 100644 riscv-ctg/docs/source/_static/l1cache.png create mode 100644 riscv-ctg/docs/source/_static/onlyC.png create mode 100644 riscv-ctg/docs/source/_static/riscv-ctg.png create mode 100644 riscv-ctg/docs/source/_static/theme_overrides.css create mode 100644 riscv-ctg/docs/source/_templates/breadcrumbs.html create mode 100644 riscv-ctg/docs/source/_templates/layout.html create mode 100644 riscv-ctg/docs/source/_templates/versions.html create mode 100644 riscv-ctg/docs/source/add_instr.rst create mode 100644 riscv-ctg/docs/source/cli.rst create mode 100644 riscv-ctg/docs/source/code.rst create mode 100644 riscv-ctg/docs/source/conf.py create mode 100644 riscv-ctg/docs/source/contributing.rst create mode 100644 riscv-ctg/docs/source/cross_comb.rst create mode 100644 riscv-ctg/docs/source/csr_comb.rst create mode 100644 riscv-ctg/docs/source/diagrams/git_flow.png create mode 100644 riscv-ctg/docs/source/index.rst create mode 100644 riscv-ctg/docs/source/index_bkp create mode 100644 riscv-ctg/docs/source/installation.rst create mode 100644 riscv-ctg/docs/source/licensing.rst create mode 100644 riscv-ctg/docs/source/overview.rst create mode 100644 riscv-ctg/docs/source/pseudo_op_support.rst create mode 100644 riscv-ctg/docs/source/refs.bib create mode 100644 riscv-ctg/docs/source/revisions.rst create mode 100644 riscv-ctg/docs/sphinxext/cairosvgconverter.py create mode 100644 riscv-ctg/riscv_ctg/__init__.py create mode 100644 riscv-ctg/riscv_ctg/constants.py create mode 100644 riscv-ctg/riscv_ctg/cross_comb.py create mode 100644 riscv-ctg/riscv_ctg/csr_comb.py create mode 100644 riscv-ctg/riscv_ctg/ctg.py create mode 100644 riscv-ctg/riscv_ctg/data/fd.yaml create mode 100644 riscv-ctg/riscv_ctg/data/imc.yaml create mode 100644 riscv-ctg/riscv_ctg/data/inx.yaml create mode 100644 riscv-ctg/riscv_ctg/data/template.yaml create mode 100644 riscv-ctg/riscv_ctg/dsp_function.py create mode 100644 riscv-ctg/riscv_ctg/function_generators.py create mode 100644 riscv-ctg/riscv_ctg/generator.py create mode 100644 riscv-ctg/riscv_ctg/helpers.py create mode 100644 riscv-ctg/riscv_ctg/log.py create mode 100644 riscv-ctg/riscv_ctg/main.py create mode 100644 riscv-ctg/riscv_ctg/misc/bitmanip_real_world.py create mode 100644 riscv-ctg/riscv_ctg/requirements.txt create mode 100644 riscv-ctg/riscv_ctg/utils.py create mode 100644 riscv-ctg/setup.cfg create mode 100644 riscv-ctg/setup.py create mode 100644 riscv-ctg/tests/__init__.py create mode 100644 riscv-ctg/tests/test_riscv_ctg.py create mode 100644 riscv-isac/.gitignore create mode 100644 riscv-isac/CHANGELOG.md create mode 100644 riscv-isac/CONTRIBUTING.rst create mode 100644 riscv-isac/LICENSE.incore create mode 100644 riscv-isac/MANIFEST.in create mode 100644 riscv-isac/README.rst create mode 100644 riscv-isac/docs/Makefile create mode 100644 riscv-isac/docs/README.md create mode 100644 riscv-isac/docs/requirements.txt create mode 100644 riscv-isac/docs/source/Cross_coverage.rst create mode 100644 riscv-isac/docs/source/_static/custom.css create mode 100644 riscv-isac/docs/source/_static/incore_logo.png create mode 100644 riscv-isac/docs/source/_static/l1cache.png create mode 100644 riscv-isac/docs/source/_static/onlyC.png create mode 100644 riscv-isac/docs/source/_static/riscv-isac.png create mode 100644 riscv-isac/docs/source/_static/theme_overrides.css create mode 100644 riscv-isac/docs/source/_templates/breadcrumbs.html create mode 100644 riscv-isac/docs/source/_templates/layout.html create mode 100644 riscv-isac/docs/source/_templates/versions.html create mode 100644 riscv-isac/docs/source/add_instr.rst create mode 100644 riscv-isac/docs/source/cgf.rst create mode 100644 riscv-isac/docs/source/code.rst create mode 100644 riscv-isac/docs/source/conf.py create mode 100644 riscv-isac/docs/source/contributing.rst create mode 100644 riscv-isac/docs/source/diagrams/git_flow.png create mode 100644 riscv-isac/docs/source/dpr.rst create mode 100644 riscv-isac/docs/source/index.rst create mode 100644 riscv-isac/docs/source/index_bkp create mode 100644 riscv-isac/docs/source/isac_cov_calc.rst create mode 100644 riscv-isac/docs/source/licensing.rst create mode 100644 riscv-isac/docs/source/overview.rst create mode 100644 riscv-isac/docs/source/pseudo_op_support.rst create mode 100644 riscv-isac/docs/source/python_plugins.rst create mode 100644 riscv-isac/docs/source/quickstart.rst create mode 100644 riscv-isac/docs/source/refs.bib create mode 100644 riscv-isac/docs/source/revisions.rst create mode 100644 riscv-isac/docs/source/rvopcodesdecoder.rst create mode 100644 riscv-isac/docs/sphinxext/cairosvgconverter.py create mode 100644 riscv-isac/interface.py create mode 100644 riscv-isac/riscv_isac/InstructionObject.py create mode 100644 riscv-isac/riscv_isac/__init__.py create mode 100644 riscv-isac/riscv_isac/cgf_normalize.py create mode 100644 riscv-isac/riscv_isac/constants.py create mode 100644 riscv-isac/riscv_isac/coverage.py create mode 100644 riscv-isac/riscv_isac/data/__init__.py create mode 100644 riscv-isac/riscv_isac/data/constants.py create mode 100644 riscv-isac/riscv_isac/data/instr_alias.yaml create mode 100644 riscv-isac/riscv_isac/data/rvopcodesdecoder.py create mode 100644 riscv-isac/riscv_isac/fp_dataset.py create mode 100644 riscv-isac/riscv_isac/isac.py create mode 100644 riscv-isac/riscv_isac/log.py create mode 100644 riscv-isac/riscv_isac/main.py create mode 100644 riscv-isac/riscv_isac/plugins/__init__.py create mode 100644 riscv-isac/riscv_isac/plugins/c_sail.py create mode 100644 riscv-isac/riscv_isac/plugins/internaldecoder.py create mode 100644 riscv-isac/riscv_isac/plugins/specification.py create mode 100644 riscv-isac/riscv_isac/plugins/spike.py create mode 100644 riscv-isac/riscv_isac/plugins/translator_cgf.py create mode 100644 riscv-isac/riscv_isac/requirements.txt create mode 100644 riscv-isac/riscv_isac/test_requirements.txt create mode 100644 riscv-isac/riscv_isac/utils.py create mode 100644 riscv-isac/setup.cfg create mode 100644 riscv-isac/setup.py create mode 100644 riscv-isac/tests/__init__.py create mode 100644 riscv-isac/tests/test_riscv_isac.py diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 312b63b96..cec5b80aa 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -26,27 +26,81 @@ jobs: ACT-sail-spike: runs-on: ubuntu-latest - container: ghcr.io/riscv-software-src/riscof/act:latest strategy: fail-fast: false matrix: isa_group: - - RV32IMCZicsr_Zifencei - - RV64IMCZicsr_Zifencei - + - RVIMAFDCZicsr_Zifencei steps: - name: Checkout source uses: actions/checkout@v4 - - name: Config riscof + - name: Install Dependencies + run: | + sudo apt-get update + sudo apt-get install -y python3 python3-pip python3-venv + sudo apt-get install -y gcc git autoconf automake libtool curl make unzip + sudo apt-get install autoconf automake autotools-dev curl python3 python3-pip libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev ninja-build git cmake libglib2.0-dev libslirp-dev + pip3 install git+https://github.com/riscv/riscof.git + + - name: Build RISCV-GNU Toolchain (32 bit) + run: | + wget -c https://github.com/riscv-collab/riscv-gnu-toolchain/releases/download/2024.09.03/riscv32-elf-ubuntu-20.04-gcc-nightly-2024.09.03-nightly.tar.gz + tar -xzf riscv32-elf-ubuntu-20.04-gcc-nightly-2024.09.03-nightly.tar.gz + mv riscv riscv32 + echo $GITHUB_WORKSPACE/riscv32/bin >> $GITHUB_PATH + + - name: Build RISCV-GNU Toolchain (64 bit) + run: | + wget -c https://github.com/riscv-collab/riscv-gnu-toolchain/releases/download/2024.09.03/riscv64-elf-ubuntu-20.04-gcc-nightly-2024.09.03-nightly.tar.gz + tar -xzf riscv64-elf-ubuntu-20.04-gcc-nightly-2024.09.03-nightly.tar.gz + mv riscv riscv64 + echo $GITHUB_WORKSPACE/riscv64/bin >> $GITHUB_PATH + + - name: Install Spike run: | - git config --global --add safe.directory '*' - riscof setup --dutname=spike - cp .github/isa_templates/${{ matrix.isa_group }}.yaml spike/spike_isa.yaml + git clone https://github.com/riscv/riscv-isa-sim.git + sudo apt-get install device-tree-compiler libboost-regex-dev libboost-system-dev + cd riscv-isa-sim + mkdir build + cd build + ../configure --prefix=$GITHUB_WORKSPACE/riscv64 + make -j$(nproc) + sudo make install + echo $GITHUB_WORKSPACE/riscv64/bin >> $GITHUB_PATH + - name: Install Sail + run: | + sudo apt-get install opam build-essential libgmp-dev z3 pkg-config zlib1g-dev + opam init -y --disable-sandboxing + opam switch create ocaml-base-compiler + opam install sail -y + eval $(opam config env) + git clone https://github.com/riscv/sail-riscv.git + cd sail-riscv + ARCH=RV32 make + ARCH=RV64 make + echo $PWD/c_emulator >> $GITHUB_PATH + + - name: Install riscv-isac + run: | + cd riscv-isac + pip3 install --editable . + + - name: Install riscv-ctg + run: | + cd riscv-ctg + pip3 install --editable . + + + - name: Config and run riscof for RV32 + run: | + cd riscof-plugins/rv32 + riscof run --config config.ini --suite ../../riscv-test-suite/rv32i_m/ --env ../../riscv-test-suite/env - - name: Run riscof + - name: Config and run riscof for RV64 run: | - riscof --verbose debug run --suite . --env ./riscv-test-suite/env + cd riscof-plugins/rv64 + riscof run --config config.ini --suite ../../riscv-test-suite/rv64i_m/ --env ../../riscv-test-suite/env diff --git a/README.md b/README.md index 6d02a250f..ffffc68e6 100644 --- a/README.md +++ b/README.md @@ -79,3 +79,178 @@ The files [`COPYING.BSD`](./COPYING.BSD), [`COPYING.APACHE`](./COPYING.APACHE) a - [riscvOVPsim](https://github.com/riscv-ovpsim/imperas-riscv-tests): Imperas freeware RISC-V reference simulator for compliance testing - [riscvOVPsimPlus](https://www.ovpworld.org/riscvOVPsimPlus/): Imperas enhanced freeware RISC-V reference simulator for test development and verification +# Getting Started + +This section serves as a quick guide to set up RISCOF and perform a sample validation check between Spike (DUT in this case) and Sail-riscv (Reference Golden Model). This guide will help you set up all the required tooling for running RISCOF on your system. + +### Install Python + +### Ubuntu + +For Ubuntu, you can directly install Python using the Universe repository: + +```bash +$ sudo apt-get install python3.6 +$ pip3 install --upgrade pip +``` +You should now have two binaries: `python3` and `pip3` available in your `$PATH`. + +### Install RISCOF +To install RISCOF, run this command in your terminal: + +``` +$ pip3 install git+https://github.com/riscv/riscof.git +``` +This is the preferred method to install RISCOF, as it will always install the most recent stable release. + +### Install riscv-ctg +To install riscv-ctg, run this command in your terminal: + +``` +$ cd riscv-ctg +$ pip3 install --editable . +``` + +### Install riscv-isac +To install riscv-isac, run this command in your terminal: + +``` +$ cd riscv-isac +$ pip3 install --editable . +``` +This is the preferred method to install riscv-isac and riscv-ctg, as updated riscv-ctg will always be maintained here. + + +### Test RISCOF +Once you have installed `RISCOF`, you can execute `riscof --help` to print the help routine: + +```bash +$ riscof --help +Usage: riscof [OPTIONS] COMMAND [ARGS]... + +Options: + --version Show the version and exit. + -v, --verbose [info|error|debug] + Set verbose level + --help Show this message and exit. + +Commands: + arch-test Setup and maintenance for Architectural TestSuite. + coverage Run the tests on DUT and reference and compare signatures + gendb Generate Database for the Suite. + run Run the tests on DUT and reference and compare signatures + setup Initiate Setup for riscof. + testlist Generate the test list for the given DUT and suite. + validateyaml Validate the Input YAMLs using riscv-config. +``` + + +## Install RISCV-GNU Toolchain + +This guide will use the 32-bit riscv-gnu toolchain to compile the architectural suite. If you already have the 32-bit gnu-toolchain available, you can skip to the next section. + +> **Note**: The git clone and installation will take significant time. Please be patient. If you face issues with any of the following steps, please refer to [riscv-gnu-toolchain](https://github.com/riscv-collab/riscv-gnu-toolchain) for further help in installation. + +### Ubuntu + +```bash +$ sudo apt-get install autoconf automake autotools-dev curl python3 libmpc-dev \ + libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool \ + patchutils bc zlib1g-dev libexpat-dev +$ git clone --recursive https://github.com/riscv/riscv-gnu-toolchain +$ git clone --recursive https://github.com/riscv/riscv-opcodes.git +$ cd riscv-gnu-toolchain +$ ./configure --prefix=/path/to/install --with-arch=rv32gc --with-abi=ilp32d # for 32-bit toolchain +$ [sudo] make # sudo is required depending on the path chosen in the previous setup +``` + +Make sure to add the path `/path/to/install` to your `$PATH` in the `.bashrc/cshrc`. + +With this, you should now have all the following available as command line arguments: + +```bash +riscv32-unknown-elf-addr2line riscv32-unknown-elf-elfedit +riscv32-unknown-elf-ar riscv32-unknown-elf-g++ +riscv32-unknown-elf-as riscv32-unknown-elf-gcc +riscv32-unknown-elf-c++ riscv32-unknown-elf-gcc-8.3.0 +riscv32-unknown-elf-c++filt riscv32-unknown-elf-gcc-ar +riscv32-unknown-elf-cpp riscv32-unknown-elf-gcc-nm +riscv32-unknown-elf-gcc-ranlib riscv32-unknown-elf-gprof +riscv32-unknown-elf-gcov riscv32-unknown-elf-ld +riscv32-unknown-elf-gcov-dump riscv32-unknown-elf-ld.bfd +riscv32-unknown-elf-gcov-tool riscv32-unknown-elf-nm +riscv32-unknown-elf-gdb riscv32-unknown-elf-objcopy +riscv32-unknown-elf-gdb-add-index riscv32-unknown-elf-objdump +riscv32-unknown-elf-ranlib riscv32-unknown-elf-readelf +riscv32-unknown-elf-run riscv32-unknown-elf-size +riscv32-unknown-elf-strings riscv32-unknown-elf-strip +``` +# Installing RISC-V Reference Models: Spike and SAIL +This section will guide you through the installation of two important RISC-V reference models: Spike and SAIL. These models are often used as reference models in the RISCOF framework. + + +### 1. Spike (riscv-isa-sim) + +Spike is the official RISC-V ISA simulator, also known as the RISC-V ISA simulator (riscv-isa-sim). It is commonly used as a reference model in RISCOF for compliance testing. + +### Installation Steps for Spike + +```bash +$ sudo apt-get install device-tree-compiler +$ git clone https://github.com/riscv-software-src/riscv-isa-sim.git +$ cd riscv-isa-sim +$ mkdir build +$ cd build +$ ../configure --prefix=/path/to/install +$ make +$ [sudo] make install +``` +Note: Use sudo if the installation path requires administrative privileges. + + +### 2. SAIL (SAIL C-emulator) + +```bash +$ sudo apt-get install opam build-essential libgmp-dev z3 pkg-config zlib1g-dev +$ opam init -y --disable-sandboxing +$ opam switch create ocaml-base-compiler +$ opam install sail -y +$ eval $(opam config env) +$ git clone https://github.com/riscv/sail-riscv.git +$ cd sail-riscv +$ ARCH=RV32 make +$ ARCH=RV64 make +$ ln -s sail-riscv/c_emulator/riscv_sim_RV64 /usr/bin/riscv_sim_RV64 +$ ln -s sail-riscv/c_emulator/riscv_sim_RV32 /usr/bin/riscv_sim_RV32 +``` + +This will create a C simulator in `c_emulator/riscv_sim_RV64` and `c_emulator/riscv_sim_RV32`. You will need to add these paths to your `$PATH` or create an alias to execute them from the command line. + + +## Necessary Env Files + +To run tests via RISCOF, you will need to provide the following items: + +- **config.ini**: This file is a basic configuration file following the INI syntax. This file will capture information like the name of the DUT/reference plugins, path to the plugins, path to the riscv-config based YAMLs, etc. This file is located at `riscof-plugins/rv32/config.ini` for RV32 and at `riscof-plugins/rv64/config.ini` for `RV64` + +- **riscv-test-suite/**: The directory contains the architectural test suites. + +- **riscv-config/**: The repository containing the configuration files for various RISC-V implementations. You can clone the required repository using the following commands: + +``` +$ git clone https://github.com/riscv/riscv-config.git +``` + +## Running the Tests +Once everything is set up, you can run the tests using the following command: + +``` +$ riscof run --config config.ini --suite riscv-test-suite/ --env riscv-test-suite/env +``` + +## Running the coverage command +You can run the coverage using the following command: + +``` +$ riscof coverage --config=config.ini --cgf-file covergroups/dataset.cgf --cgf-file covergroups/m/rv32im.cgf --suite /riscv-test-suite/rv32i_m/M --env /riscv-test-suite/env +``` diff --git a/coverage/README.md b/coverage/README.md new file mode 100644 index 000000000..ea1e47ae8 --- /dev/null +++ b/coverage/README.md @@ -0,0 +1,13 @@ +## CGF: Cover Group Format + +- Uses a simple to use and a human readable YAML format to define cover groups and cover-points for the RISC-V ISA. +- Declares datasets separately which can be used across coverpoints: + - Operand Addresses for a single instruction + - Operand Value for a single instruction + - Abstract functions like walking1s and walking0s which get unrolled by the extraction tool +- Covergroups include multiple datasets + - Each coverpoint is defined as a boolean expression which can to be evaluated by the "eval" + tool of python. + - Coverpoints to use a standard set of keywords like: rs1, rs2, rd, rs1_val, rs2_val, etc +- Uses Anchors and Aliases to keep the size of the YAML file small + diff --git a/coverage/Zifencei/rv32e_fencei.cgf b/coverage/Zifencei/rv32e_fencei.cgf new file mode 100644 index 000000000..0339821ee --- /dev/null +++ b/coverage/Zifencei/rv32e_fencei.cgf @@ -0,0 +1,6 @@ +fencei: + config: + - check ISA:=regex(.*E.*Zifencei.*) ;def RVTEST_E = True + mnemonics: + fence.i: 0 + diff --git a/coverage/Zifencei/rv32i_fencei.cgf b/coverage/Zifencei/rv32i_fencei.cgf new file mode 100644 index 000000000..7699d7c47 --- /dev/null +++ b/coverage/Zifencei/rv32i_fencei.cgf @@ -0,0 +1,6 @@ +fencei: + config: + - check ISA:=regex(.*I.*Zifencei.*) + mnemonics: + fence.i: 0 + diff --git a/coverage/Zifencei/rv64i_fencei.cgf b/coverage/Zifencei/rv64i_fencei.cgf new file mode 100644 index 000000000..3397e5a00 --- /dev/null +++ b/coverage/Zifencei/rv64i_fencei.cgf @@ -0,0 +1,8 @@ + +fencei: + config: + - check ISA:=regex(.*I.*Zifencei.*) + mnemonics: + fence.i: 0 + + diff --git a/coverage/rvi_fencei.cgf b/coverage/Zifencei/rvi_fencei.cgf similarity index 100% rename from coverage/rvi_fencei.cgf rename to coverage/Zifencei/rvi_fencei.cgf diff --git a/coverage/a/rv32ia.cgf b/coverage/a/rv32ia.cgf new file mode 100644 index 000000000..cf5f345c7 --- /dev/null +++ b/coverage/a/rv32ia.cgf @@ -0,0 +1,170 @@ +amoadd.w: + config: + - check ISA:=regex(.*32.*I.*A.*) + - check ISA:=regex(.*32.*I.*Zaamo.*) + mnemonics: + amoadd.w: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: [*ramofmt_op_comb] + val_comb: + <<: [*base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +amoand.w: + config: + - check ISA:=regex(.*32.*I.*A.*) + - check ISA:=regex(.*32.*I.*Zaamo.*) + mnemonics: + amoand.w: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: [*ramofmt_op_comb] + val_comb: + <<: [*base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +amoswap.w: + config: + - check ISA:=regex(.*32.*I.*A.*) + - check ISA:=regex(.*32.*I.*Zaamo.*) + mnemonics: + amoswap.w: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: [*ramofmt_op_comb] + val_comb: + <<: [*base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +amoxor.w: + config: + - check ISA:=regex(.*32.*I.*A.*) + - check ISA:=regex(.*32.*I.*Zaamo.*) + mnemonics: + amoxor.w: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: [*ramofmt_op_comb] + val_comb: + <<: [*base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +amoor.w: + config: + - check ISA:=regex(.*32.*I.*A.*) + - check ISA:=regex(.*32.*I.*Zaamo.*) + mnemonics: + amoor.w: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: [*ramofmt_op_comb] + val_comb: + <<: [*base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +amomin.w: + config: + - check ISA:=regex(.*32.*I.*A.*) + - check ISA:=regex(.*32.*I.*Zaamo.*) + mnemonics: + amomin.w: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: [*ramofmt_op_comb] + val_comb: + <<: [*base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +amominu.w: + config: + - check ISA:=regex(.*32.*I.*A.*) + - check ISA:=regex(.*32.*I.*Zaamo.*) + mnemonics: + amominu.w: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: [*ramofmt_op_comb] + val_comb: + <<: [*base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +amomax.w: + config: + - check ISA:=regex(.*32.*I.*A.*) + - check ISA:=regex(.*32.*I.*Zaamo.*) + mnemonics: + amomax.w: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: [*ramofmt_op_comb] + val_comb: + <<: [*base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +amomaxu.w: + config: + - check ISA:=regex(.*32.*I.*A.*) + - check ISA:=regex(.*32.*I.*Zaamo.*) + mnemonics: + amomaxu.w: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: [*ramofmt_op_comb] + val_comb: + <<: [*base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] diff --git a/coverage/a/rv64ia.cgf b/coverage/a/rv64ia.cgf new file mode 100644 index 000000000..2cd7895da --- /dev/null +++ b/coverage/a/rv64ia.cgf @@ -0,0 +1,341 @@ +amoadd.w: + config: + - check ISA:=regex(.*64.*I.*A.*) + - check ISA:=regex(.*64.*I.*Zaamo.*) + mnemonics: + amoadd.w: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: [*ramofmt_op_comb] + val_comb: + <<: [*base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +amoand.w: + config: + - check ISA:=regex(.*64.*I.*A.*) + - check ISA:=regex(.*64.*I.*Zaamo.*) + mnemonics: + amoand.w: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: [*ramofmt_op_comb] + val_comb: + <<: [*base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +amoswap.w: + config: + - check ISA:=regex(.*64.*I.*A.*) + - check ISA:=regex(.*64.*I.*Zaamo.*) + mnemonics: + amoswap.w: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: [*ramofmt_op_comb] + val_comb: + <<: [*base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +amoxor.w: + config: + - check ISA:=regex(.*64.*I.*A.*) + - check ISA:=regex(.*64.*I.*Zaamo.*) + mnemonics: + amoxor.w: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: [*ramofmt_op_comb] + val_comb: + <<: [*base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +amoor.w: + config: + - check ISA:=regex(.*64.*I.*A.*) + - check ISA:=regex(.*64.*I.*Zaamo.*) + mnemonics: + amoor.w: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: [*ramofmt_op_comb] + val_comb: + <<: [*base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +amomin.w: + config: + - check ISA:=regex(.*64.*I.*A.*) + - check ISA:=regex(.*64.*I.*Zaamo.*) + mnemonics: + amomin.w: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: [*ramofmt_op_comb] + val_comb: + <<: [*base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +amominu.w: + config: + - check ISA:=regex(.*64.*I.*A.*) + - check ISA:=regex(.*64.*I.*Zaamo.*) + mnemonics: + amominu.w: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: [*ramofmt_op_comb] + val_comb: + <<: [*base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +amomax.w: + config: + - check ISA:=regex(.*64.*I.*A.*) + - check ISA:=regex(.*64.*I.*Zaamo.*) + mnemonics: + amomax.w: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: [*ramofmt_op_comb] + val_comb: + <<: [*base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +amomaxu.w: + config: + - check ISA:=regex(.*64.*I.*A.*) + - check ISA:=regex(.*64.*I.*Zaamo.*) + mnemonics: + amomaxu.w: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: [*ramofmt_op_comb] + val_comb: + <<: [*base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +amoadd.d: + config: + - check ISA:=regex(.*64.*I.*A.*) + - check ISA:=regex(.*64.*I.*Zaamo.*) + mnemonics: + amoadd.d: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: [*ramofmt_op_comb] + val_comb: + <<: [*base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +amoand.d: + config: + - check ISA:=regex(.*64.*I.*A.*) + - check ISA:=regex(.*64.*I.*Zaamo.*) + mnemonics: + amoand.d: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: [*ramofmt_op_comb] + val_comb: + <<: [*base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +amoswap.d: + config: + - check ISA:=regex(.*64.*I.*A.*) + - check ISA:=regex(.*64.*I.*Zaamo.*) + mnemonics: + amoswap.d: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: [*ramofmt_op_comb] + val_comb: + <<: [*base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +amoxor.d: + config: + - check ISA:=regex(.*64.*I.*A.*) + - check ISA:=regex(.*64.*I.*Zaamo.*) + mnemonics: + amoxor.d: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: [*ramofmt_op_comb] + val_comb: + <<: [*base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +amoor.d: + config: + - check ISA:=regex(.*64.*I.*A.*) + - check ISA:=regex(.*64.*I.*Zaamo.*) + mnemonics: + amoor.d: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: [*ramofmt_op_comb] + val_comb: + <<: [*base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +amomin.d: + config: + - check ISA:=regex(.*64.*I.*A.*) + - check ISA:=regex(.*64.*I.*Zaamo.*) + mnemonics: + amomin.d: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: [*ramofmt_op_comb] + val_comb: + <<: [*base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +amominu.d: + config: + - check ISA:=regex(.*64.*I.*A.*) + - check ISA:=regex(.*64.*I.*Zaamo.*) + mnemonics: + amominu.d: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: [*ramofmt_op_comb] + val_comb: + <<: [*base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +amomax.d: + config: + - check ISA:=regex(.*64.*I.*A.*) + - check ISA:=regex(.*64.*I.*Zaamo.*) + mnemonics: + amomax.d: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: [*ramofmt_op_comb] + val_comb: + <<: [*base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +amomaxu.d: + config: + - check ISA:=regex(.*64.*I.*A.*) + - check ISA:=regex(.*64.*I.*Zaamo.*) + mnemonics: + amomaxu.d: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: [*ramofmt_op_comb] + val_comb: + <<: [*base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] diff --git a/coverage/b/rv32e_b.cgf b/coverage/b/rv32e_b.cgf new file mode 100644 index 000000000..6ab80eb1f --- /dev/null +++ b/coverage/b/rv32e_b.cgf @@ -0,0 +1,705 @@ +sh1add: + config: + - check ISA:=regex(.*E.*Zba.*) ;def RVTEST_E = True + mnemonics: + sh1add: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'bitmanip_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +sh2add: + config: + - check ISA:=regex(.*E.*Zba.*) ;def RVTEST_E = True + mnemonics: + sh2add: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'bitmanip_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +sh3add: + config: + - check ISA:=regex(.*E.*Zba.*) ;def RVTEST_E = True + mnemonics: + sh3add: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'bitmanip_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +xnor: + config: + - check ISA:=regex(.*E.*Zbb.*) ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zbkb.*) ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zk.*) ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zkn.*) ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zks.*) ;def RVTEST_E = True + mnemonics: + xnor: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + 'bitmanip_dataset(xlen,signed=False)': 0 + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + 'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0 + +zext.h_32: + config: + - check ISA:=regex(.*E.*Zbb.*) ;def RVTEST_E = True + mnemonics: + zext.h: 0 + base_op: pack + p_op_cond: rs2 == x0 + rs1: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'rs1_val == 0': 0 + 'rs1_val == 0x80': 0 + 'rs1_val == 0xFF80': 0 + abstract_comb: + 'walking_ones("rs1_val", xlen, False)': 0 + 'walking_zeros("rs1_val", xlen, False)': 0 + 'uniform_random(20, 100, ["rs1_val"], [xlen])': 0 +andn: + config: + - check ISA:=regex(.*E.*Zbb.*) ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zbkb.*) ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zk.*) ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zkn.*) ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zks.*) ;def RVTEST_E = True + mnemonics: + andn: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + 'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0 + 'bitmanip_dataset(xlen,["rs1_val","rs2_val"],False)': 0 + +clz: + config: + - check ISA:=regex(.*E.*Zbb.*) ;def RVTEST_E = True + mnemonics: + clz: 0 + rs1: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + <<: [*rs1val_walking_unsgn] + 'leading_zeros(xlen, ["rs1_val"], [xlen], 11)': 0 + 'leading_ones(xlen, ["rs1_val"], [xlen], 10)': 0 + 'trailing_zeros(xlen, ["rs1_val"], [xlen], 12)': 0 + 'trailing_ones(xlen, ["rs1_val"], [xlen], 13)': 0 + +ctz: + config: + - check ISA:=regex(.*E.*Zbb.*) ;def RVTEST_E = True + mnemonics: + ctz: 0 + rs1: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + <<: [*rs1val_walking_unsgn] + 'leading_zeros(xlen, ["rs1_val"], [xlen], 11)': 0 + 'leading_ones(xlen, ["rs1_val"], [xlen], 10)': 0 + 'trailing_zeros(xlen, ["rs1_val"], [xlen], 12)': 0 + 'trailing_ones(xlen, ["rs1_val"], [xlen], 13)': 0 + +cpop: + config: + - check ISA:=regex(.*E.*Zbb.*) ;def RVTEST_E = True + mnemonics: + cpop: 0 + rs1: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + <<: [*rs1val_walking_unsgn] + 'leading_zeros(xlen, ["rs1_val"], [xlen], 11)': 0 + 'leading_ones(xlen, ["rs1_val"], [xlen], 10)': 0 + 'trailing_zeros(xlen, ["rs1_val"], [xlen], 12)': 0 + 'trailing_ones(xlen, ["rs1_val"], [xlen], 13)': 0 + +max: + config: + - check ISA:=regex(.*E.*Zbb.*) ;def RVTEST_E = True + mnemonics: + max: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'bitmanip_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +maxu: + config: + - check ISA:=regex(.*E.*Zbb.*) ;def RVTEST_E = True + mnemonics: + maxu: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + 'bitmanip_dataset(xlen,signed=False)': 0 + <<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn] + +min: + config: + - check ISA:=regex(.*E.*Zbb.*) ;def RVTEST_E = True + mnemonics: + min: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'bitmanip_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +minu: + config: + - check ISA:=regex(.*E.*Zbb.*) ;def RVTEST_E = True + mnemonics: + minu: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + 'bitmanip_dataset(xlen,signed=False)': 0 + <<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn] + +orcb_32: + config: + - check ISA:=regex(.*E.*Zbb.*) ;def RVTEST_E = True + mnemonics: + orc.b: 0 + base_op: gorci + p_op_cond: imm_val == 7 + rs1: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'rs1_val == 0x1020408': 0 + 'rs1_val == 0x2040801': 0 + 'rs1_val == 0x4080102': 0 + 'rs1_val == 0x8010204': 0 + abstract_comb: + <<: [*rs1val_walking_unsgn] + + +orn: + config: + - check ISA:=regex(.*E.*Zbb.*) ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zbkb.*) ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zk.*) ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zkn.*) ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zks.*) ;def RVTEST_E = True + mnemonics: + orn: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + 'bitmanip_dataset(xlen,signed=False)': 0 + <<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn] + 'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0 + +rev8_32: + config: + - check ISA:=regex(.*E.*Zbb.*) ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zbkb.*) ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zk.*) ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zkn.*) ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zks.*) ;def RVTEST_E = True + mnemonics: + rev8: 0 + base_op: grevi + p_op_cond: imm_val == 24 + rs1: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'rs1_val == 0x1020408': 0 + 'rs1_val == 0x2040801': 0 + 'rs1_val == 0x4080102': 0 + 'rs1_val == 0x8010204': 0 + abstract_comb: + 'leading_ones(32, ["rs1_val"], [32])': 0 + 'trailing_ones(32, ["rs1_val"], [32])': 0 + 'leading_zeros(32, ["rs1_val"], [32])': 0 + 'trailing_zeros(32, ["rs1_val"], [32])': 0 + 'bitmanip_dataset(xlen,["rs1_val"],signed=False)': 0 + +rol: + config: + - check ISA:=regex(.*E.*Zbb.*) ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zbkb.*) ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zk.*) ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zkn.*) ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zks.*) ;def RVTEST_E = True + mnemonics: + rol: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'leading_ones(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + 'trailing_ones(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + 'leading_zeros(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + 'trailing_zeros(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + +ror: + config: + - check ISA:=regex(.*E.*Zbb.*) ;def RVTEST_E = True + - check ISA:=regex(.*I.*Zbkb.*) ;def RVTEST_E = True + - check ISA:=regex(.*I.*Zk.*) ;def RVTEST_E = True + - check ISA:=regex(.*I.*Zkn.*) ;def RVTEST_E = True + - check ISA:=regex(.*I.*Zks.*) ;def RVTEST_E = True + mnemonics: + ror: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'leading_ones(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + 'trailing_ones(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + 'leading_zeros(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + 'trailing_zeros(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + +rori: + config: + - check ISA:=regex(.*E.*Zbb.*) ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zbkb.*) ;def RVTEST_E = True + - check ISA:=regex(.*.*Zk.*) ;def RVTEST_E = True + - check ISA:=regex(.*I.*Zkn.*) ;def RVTEST_E = True + - check ISA:=regex(.*I.*Zks.*) ;def RVTEST_E = True + mnemonics: + rori: 0 + rs1: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'leading_ones(32, ["rs1_val","imm_val"],[32,5])': 0 + 'trailing_ones(32, ["rs1_val","imm_val"],[32,5])': 0 + 'leading_zeros(32, ["rs1_val","imm_val"],[32,5])': 0 + 'trailing_zeros(32, ["rs1_val","imm_val"],[32,5])': 0 + +sext.b: + config: + - check ISA:=regex(.*E.*Zbb.*) ;def RVTEST_E = True + mnemonics: + sext.b: 0 + rs1: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'rs1_val == 0': 0 + 'rs1_val == 0x8000': 0 + abstract_comb: + 'walking_ones("rs1_val", xlen, False)': 0 + 'walking_zeros("rs1_val", xlen, False)': 0 + 'uniform_random(20, 100, ["rs1_val"], [xlen])': 0 + +sext.h: + config: + - check ISA:=regex(.*E.*Zbb.*) ;def RVTEST_E = True + mnemonics: + sext.h: 0 + rs1: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'rs1_val == 0': 0 + 'rs1_val == 0x80': 0 + 'rs1_val == 0xff80': 0 + abstract_comb: + 'walking_ones("rs1_val", xlen, False)': 0 + 'walking_zeros("rs1_val", xlen, False)': 0 + 'uniform_random(20, 100, ["rs1_val"], [xlen])': 0 + +clmul: + config: + - check ISA:=regex(.*E.*Zbc.*) ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zbkc.*) ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zk.*) ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zks.*) ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zkn.*) ;def RVTEST_E = True + mnemonics: + clmul: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + 'rs1_val==1 and rs2_val==1': 0 + 'rs1_val==1 and rs2_val==0': 0 + 'rs1_val==1 and rs2_val==0x1000': 0 + 'rs1_val==0 and rs2_val==1': 0 + 'rs1_val==0 and rs2_val==0': 0 + 'rs1_val==0 and rs2_val==0x1000': 0 + abstract_comb: + <<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn] + 'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0 + +clmulh: + config: + - check ISA:=regex(.*E.*Zbc.*) ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zbkc.*) ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zk.*) ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zkn.*) ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zks.*) ;def RVTEST_E = True + mnemonics: + clmulh: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + 'rs1_val==1 and rs2_val==1': 0 + 'rs1_val==1 and rs2_val==0': 0 + 'rs1_val==1 and rs2_val==0x1000': 0 + 'rs1_val==0 and rs2_val==1': 0 + 'rs1_val==0 and rs2_val==0': 0 + 'rs1_val==0 and rs2_val==0x1000': 0 + abstract_comb: + <<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn] + 'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0 + + +clmulr: + config: + - check ISA:=regex(.*E.*Zbc.*) ;def RVTEST_E = True + mnemonics: + clmulr: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + 'rs1_val==1 and rs2_val==1': 0 + 'rs1_val==1 and rs2_val==0': 0 + 'rs1_val==1 and rs2_val==0x1000': 0 + 'rs1_val==0 and rs2_val==1': 0 + 'rs1_val==0 and rs2_val==0': 0 + 'rs1_val==0 and rs2_val==0x1000': 0 + abstract_comb: + <<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn] + 'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0 + +bclr: + config: + - check ISA:=regex(.*E.*Zbs.*) ;def RVTEST_E = True + mnemonics: + bclr: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: +# 'xlenlim("rs1_val", xlen)': 0 +# 'xlenlim("rs2_val", xlen )': 0 + 'walking_ones("rs1_val", ceil(log(xlen, 2)), False)': 0 + 'walking_ones("rs2_val", ceil(log(xlen, 2)), False)': 0 + 'leading_ones(32, ["rs1_val", "rs2_val"], [32,5])': 0 + 'trailing_ones(32, ["rs1_val", "rs2_val"], [32,5])': 0 + 'leading_zeros(32, ["rs1_val", "rs2_val"], [32,5])': 0 + 'trailing_zeros(32, ["rs1_val", "rs2_val"], [32,5])': 0 + <<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn] + + +bclri: + config: + - check ISA:=regex(.*E.*Zbs.*) ;def RVTEST_E = True + mnemonics: + bclri: 0 + rs1: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: +# 'xlenlim("rs1_val", xlen)': 0 + 'leading_ones(32, ["rs1_val", "imm_val"], [32,5])': 0 + 'trailing_ones(32, ["rs1_val", "imm_val"], [32,5])': 0 + 'leading_zeros(32, ["rs1_val", "imm_val"], [32,5])': 0 + 'trailing_zeros(32, ["rs1_val", "imm_val"], [32,5])': 0 + + +bext: + config: + - check ISA:=regex(.*E.*Zbs.*) ;def RVTEST_E = True + mnemonics: + bext: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: +# 'xlenlim("rs1_val", xlen)': 0 +# 'xlenlim("rs2_val", xlen )': 0 + 'walking_ones("rs1_val", ceil(log(xlen, 2)), False)': 0 + 'walking_ones("rs2_val", ceil(log(xlen, 2)), False)': 0 + 'leading_ones(32, ["rs1_val", "rs2_val"], [32,5])': 0 + 'trailing_ones(32, ["rs1_val", "rs2_val"], [32,5])': 0 + 'leading_zeros(32, ["rs1_val", "rs2_val"], [32,5])': 0 + 'trailing_zeros(32, ["rs1_val", "rs2_val"], [32,5])': 0 + <<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn] + + +bexti: + config: + - check ISA:=regex(.*E.*Zbs.*) ;def RVTEST_E = True + mnemonics: + bexti: 0 + rs1: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: +# 'xlenlim("rs1_val", xlen)': 0 + 'leading_ones(32, ["rs1_val", "imm_val"], [32,5])': 0 + 'trailing_ones(32, ["rs1_val", "imm_val"], [32,5])': 0 + 'leading_zeros(32, ["rs1_val", "imm_val"], [32,5])': 0 + 'trailing_zeros(32, ["rs1_val", "imm_val"], [32,5])': 0 + + +binv: + config: + - check ISA:=regex(.*E.*Zbs.*) ;def RVTEST_E = True + mnemonics: + binv: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: +# 'xlenlim("rs1_val", xlen)': 0 +# 'xlenlim("rs2_val", xlen )': 0 + 'walking_ones("rs1_val", ceil(log(xlen, 2)), False)': 0 + 'walking_ones("rs2_val", ceil(log(xlen, 2)), False)': 0 + 'leading_ones(32, ["rs1_val", "rs2_val"], [32,5])': 0 + 'trailing_ones(32, ["rs1_val", "rs2_val"], [32,5])': 0 + 'leading_zeros(32, ["rs1_val", "rs2_val"], [32,5])': 0 + 'trailing_zeros(32, ["rs1_val", "rs2_val"], [32,5])': 0 + <<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn] + + +binvi: + config: + - check ISA:=regex(.*E.*Zbs.*) ;def RVTEST_E = True + mnemonics: + binvi: 0 + rs1: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: +# 'xlenlim("rs1_val", xlen)': 0 + 'leading_ones(32, ["rs1_val", "imm_val"], [32,5])': 0 + 'trailing_ones(32, ["rs1_val", "imm_val"], [32,5])': 0 + 'leading_zeros(32, ["rs1_val", "imm_val"], [32,5])': 0 + 'trailing_zeros(32, ["rs1_val", "imm_val"], [32,5])': 0 + +bset: + config: + - check ISA:=regex(.*E.*Zbs.*) ;def RVTEST_E = True + mnemonics: + bset: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: +# 'xlenlim("rs1_val", xlen)': 0 +# 'xlenlim("rs2_val", xlen )': 0 + 'walking_ones("rs1_val", ceil(log(xlen, 2)), False)': 0 + 'walking_ones("rs2_val", ceil(log(xlen, 2)), False)': 0 + 'leading_ones(32, ["rs1_val", "rs2_val"], [32,5])': 0 + 'trailing_ones(32, ["rs1_val", "rs2_val"], [32,5])': 0 + 'leading_zeros(32, ["rs1_val", "rs2_val"], [32,5])': 0 + 'trailing_zeros(32, ["rs1_val", "rs2_val"], [32,5])': 0 + <<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn] + + +bseti: + config: + - check ISA:=regex(.*E.*Zbs.*) ;def RVTEST_E = True + mnemonics: + bseti: 0 + rs1: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: +# 'xlenlim("rs1_val", xlen)': 0 + 'leading_ones(32, ["rs1_val", "imm_val"], [32,5])': 0 + 'trailing_ones(32, ["rs1_val", "imm_val"], [32,5])': 0 + 'leading_zeros(32, ["rs1_val", "imm_val"], [32,5])': 0 + 'trailing_zeros(32, ["rs1_val", "imm_val"], [32,5])': 0 diff --git a/coverage/b/rv32i_b.cgf b/coverage/b/rv32i_b.cgf new file mode 100644 index 000000000..14fe4a017 --- /dev/null +++ b/coverage/b/rv32i_b.cgf @@ -0,0 +1,734 @@ +sh1add: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zba.*) + mnemonics: + sh1add: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'bitmanip_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +sh2add: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zba.*) + mnemonics: + sh2add: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'bitmanip_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +sh3add: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zba.*) + mnemonics: + sh3add: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'bitmanip_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +xnor: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbb.*) + - check ISA:=regex(.*I.*Zbkb.*) + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*I.*Zkn.*) + - check ISA:=regex(.*I.*Zks.*) + mnemonics: + xnor: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + 'bitmanip_dataset(xlen,signed=False)': 0 + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + 'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0 + +zext.h_32: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbb.*) + mnemonics: + zext.h: 0 + base_op: pack + p_op_cond: rs2 == x0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'rs1_val == 0': 0 + 'rs1_val == 0x80': 0 + 'rs1_val == 0xFF80': 0 + abstract_comb: + 'walking_ones("rs1_val", xlen, False)': 0 + 'walking_zeros("rs1_val", xlen, False)': 0 + 'uniform_random(20, 100, ["rs1_val"], [xlen])': 0 +andn: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbb.*) + - check ISA:=regex(.*I.*Zbkb.*) + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*I.*Zkn.*) + - check ISA:=regex(.*I.*Zks.*) + mnemonics: + andn: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + 'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0 + 'bitmanip_dataset(xlen,["rs1_val","rs2_val"],False)': 0 + +clz: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbb.*) + mnemonics: + clz: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + <<: [*rs1val_walking_unsgn] + 'leading_zeros(xlen, ["rs1_val"], [xlen], 11)': 0 + 'leading_ones(xlen, ["rs1_val"], [xlen], 10)': 0 + 'trailing_zeros(xlen, ["rs1_val"], [xlen], 12)': 0 + 'trailing_ones(xlen, ["rs1_val"], [xlen], 13)': 0 + +ctz: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbb.*) + mnemonics: + ctz: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + <<: [*rs1val_walking_unsgn] + 'leading_zeros(xlen, ["rs1_val"], [xlen], 11)': 0 + 'leading_ones(xlen, ["rs1_val"], [xlen], 10)': 0 + 'trailing_zeros(xlen, ["rs1_val"], [xlen], 12)': 0 + 'trailing_ones(xlen, ["rs1_val"], [xlen], 13)': 0 + +cpop: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbb.*) + mnemonics: + cpop: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + <<: [*rs1val_walking_unsgn] + 'leading_zeros(xlen, ["rs1_val"], [xlen], 11)': 0 + 'leading_ones(xlen, ["rs1_val"], [xlen], 10)': 0 + 'trailing_zeros(xlen, ["rs1_val"], [xlen], 12)': 0 + 'trailing_ones(xlen, ["rs1_val"], [xlen], 13)': 0 + +max: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbb.*) + mnemonics: + max: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'bitmanip_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +maxu: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbb.*) + mnemonics: + maxu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + 'bitmanip_dataset(xlen,signed=False)': 0 + <<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn] + +min: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbb.*) + mnemonics: + min: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'bitmanip_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +minu: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbb.*) + mnemonics: + minu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + 'bitmanip_dataset(xlen,signed=False)': 0 + <<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn] + +orcb_32: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbb.*) + mnemonics: + orc.b: 0 + base_op: gorci + p_op_cond: imm_val == 7 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'rs1_val == 0x1020408': 0 + 'rs1_val == 0x2040801': 0 + 'rs1_val == 0x4080102': 0 + 'rs1_val == 0x8010204': 0 + abstract_comb: + <<: [*rs1val_walking_unsgn] + + +orn: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbb.*) + - check ISA:=regex(.*I.*Zbkb.*) + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*I.*Zkn.*) + - check ISA:=regex(.*I.*Zks.*) + mnemonics: + orn: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + 'bitmanip_dataset(xlen,signed=False)': 0 + <<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn] + 'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0 + +rev8_32: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbb.*) + - check ISA:=regex(.*I.*Zbkb.*) + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*I.*Zkn.*) + - check ISA:=regex(.*I.*Zks.*) + mnemonics: + rev8: 0 + base_op: grevi + p_op_cond: imm_val == 24 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'rs1_val == 0x1020408': 0 + 'rs1_val == 0x2040801': 0 + 'rs1_val == 0x4080102': 0 + 'rs1_val == 0x8010204': 0 + abstract_comb: + 'leading_ones(32, ["rs1_val"], [32])': 0 + 'trailing_ones(32, ["rs1_val"], [32])': 0 + 'leading_zeros(32, ["rs1_val"], [32])': 0 + 'trailing_zeros(32, ["rs1_val"], [32])': 0 + 'bitmanip_dataset(xlen,["rs1_val"],signed=False)': 0 + +rol: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbb.*) + - check ISA:=regex(.*I.*Zbkb.*) + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*I.*Zkn.*) + - check ISA:=regex(.*I.*Zks.*) + mnemonics: + rol: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'leading_ones(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + 'trailing_ones(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + 'leading_zeros(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + 'trailing_zeros(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + +ror: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbb.*) + - check ISA:=regex(.*I.*Zbkb.*) + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*I.*Zkn.*) + - check ISA:=regex(.*I.*Zks.*) + mnemonics: + ror: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'leading_ones(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + 'trailing_ones(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + 'leading_zeros(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + 'trailing_zeros(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + +rori: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbb.*) + - check ISA:=regex(.*I.*Zbkb.*) + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*I.*Zkn.*) + - check ISA:=regex(.*I.*Zks.*) + mnemonics: + rori: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'leading_ones(32, ["rs1_val","imm_val"],[32,5])': 0 + 'trailing_ones(32, ["rs1_val","imm_val"],[32,5])': 0 + 'leading_zeros(32, ["rs1_val","imm_val"],[32,5])': 0 + 'trailing_zeros(32, ["rs1_val","imm_val"],[32,5])': 0 + +sext.b: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbb.*) + mnemonics: + sext.b: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'rs1_val == 0': 0 + 'rs1_val == 0x8000': 0 + abstract_comb: + 'walking_ones("rs1_val", xlen, False)': 0 + 'walking_zeros("rs1_val", xlen, False)': 0 + 'uniform_random(20, 100, ["rs1_val"], [xlen])': 0 + +sext.h: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbb.*) + mnemonics: + sext.h: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'rs1_val == 0': 0 + 'rs1_val == 0x80': 0 + 'rs1_val == 0xff80': 0 + abstract_comb: + 'walking_ones("rs1_val", xlen, False)': 0 + 'walking_zeros("rs1_val", xlen, False)': 0 + 'uniform_random(20, 100, ["rs1_val"], [xlen])': 0 + +clmul: + config: + - check ISA:=regex(.*I.*Zbc.*) + - check ISA:=regex(.*I.*Zbkc.*) + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*I.*Zks.*) + - check ISA:=regex(.*I.*Zkn.*) + mnemonics: + clmul: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + 'rs1_val==1 and rs2_val==1': 0 + 'rs1_val==1 and rs2_val==0': 0 + 'rs1_val==1 and rs2_val==0x1000': 0 + 'rs1_val==0 and rs2_val==1': 0 + 'rs1_val==0 and rs2_val==0': 0 + 'rs1_val==0 and rs2_val==0x1000': 0 + abstract_comb: + <<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn] + 'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0 + +clmulh: + config: + - check ISA:=regex(.*I.*Zbc.*) + - check ISA:=regex(.*I.*Zbkc.*) + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*I.*Zkn.*) + - check ISA:=regex(.*I.*Zks.*) + mnemonics: + clmulh: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + 'rs1_val==1 and rs2_val==1': 0 + 'rs1_val==1 and rs2_val==0': 0 + 'rs1_val==1 and rs2_val==0x1000': 0 + 'rs1_val==0 and rs2_val==1': 0 + 'rs1_val==0 and rs2_val==0': 0 + 'rs1_val==0 and rs2_val==0x1000': 0 + abstract_comb: + <<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn] + 'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0 + + +clmulr: + config: + - check ISA:=regex(.*I.*Zbc.*) + mnemonics: + clmulr: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + 'rs1_val==1 and rs2_val==1': 0 + 'rs1_val==1 and rs2_val==0': 0 + 'rs1_val==1 and rs2_val==0x1000': 0 + 'rs1_val==0 and rs2_val==1': 0 + 'rs1_val==0 and rs2_val==0': 0 + 'rs1_val==0 and rs2_val==0x1000': 0 + abstract_comb: + <<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn] + 'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0 + +bclr: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbs.*) + mnemonics: + bclr: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: +# 'xlenlim("rs1_val", xlen)': 0 +# 'xlenlim("rs2_val", xlen )': 0 + 'walking_ones("rs1_val", ceil(log(xlen, 2)), False)': 0 + 'walking_ones("rs2_val", ceil(log(xlen, 2)), False)': 0 + 'leading_ones(32, ["rs1_val", "rs2_val"], [32,5])': 0 + 'trailing_ones(32, ["rs1_val", "rs2_val"], [32,5])': 0 + 'leading_zeros(32, ["rs1_val", "rs2_val"], [32,5])': 0 + 'trailing_zeros(32, ["rs1_val", "rs2_val"], [32,5])': 0 + <<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn] + + +bclri: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbs.*) + mnemonics: + bclri: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: +# 'xlenlim("rs1_val", xlen)': 0 + 'leading_ones(32, ["rs1_val", "imm_val"], [32,5])': 0 + 'trailing_ones(32, ["rs1_val", "imm_val"], [32,5])': 0 + 'leading_zeros(32, ["rs1_val", "imm_val"], [32,5])': 0 + 'trailing_zeros(32, ["rs1_val", "imm_val"], [32,5])': 0 + + +bext: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbs.*) + mnemonics: + bext: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: +# 'xlenlim("rs1_val", xlen)': 0 +# 'xlenlim("rs2_val", xlen )': 0 + 'walking_ones("rs1_val", ceil(log(xlen, 2)), False)': 0 + 'walking_ones("rs2_val", ceil(log(xlen, 2)), False)': 0 + 'leading_ones(32, ["rs1_val", "rs2_val"], [32,5])': 0 + 'trailing_ones(32, ["rs1_val", "rs2_val"], [32,5])': 0 + 'leading_zeros(32, ["rs1_val", "rs2_val"], [32,5])': 0 + 'trailing_zeros(32, ["rs1_val", "rs2_val"], [32,5])': 0 + <<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn] + + +bexti: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbs.*) + mnemonics: + bexti: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: +# 'xlenlim("rs1_val", xlen)': 0 + 'leading_ones(32, ["rs1_val", "imm_val"], [32,5])': 0 + 'trailing_ones(32, ["rs1_val", "imm_val"], [32,5])': 0 + 'leading_zeros(32, ["rs1_val", "imm_val"], [32,5])': 0 + 'trailing_zeros(32, ["rs1_val", "imm_val"], [32,5])': 0 + + +binv: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbs.*) + mnemonics: + binv: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: +# 'xlenlim("rs1_val", xlen)': 0 +# 'xlenlim("rs2_val", xlen )': 0 + 'walking_ones("rs1_val", ceil(log(xlen, 2)), False)': 0 + 'walking_ones("rs2_val", ceil(log(xlen, 2)), False)': 0 + 'leading_ones(32, ["rs1_val", "rs2_val"], [32,5])': 0 + 'trailing_ones(32, ["rs1_val", "rs2_val"], [32,5])': 0 + 'leading_zeros(32, ["rs1_val", "rs2_val"], [32,5])': 0 + 'trailing_zeros(32, ["rs1_val", "rs2_val"], [32,5])': 0 + <<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn] + + +binvi: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbs.*) + mnemonics: + binvi: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: +# 'xlenlim("rs1_val", xlen)': 0 + 'leading_ones(32, ["rs1_val", "imm_val"], [32,5])': 0 + 'trailing_ones(32, ["rs1_val", "imm_val"], [32,5])': 0 + 'leading_zeros(32, ["rs1_val", "imm_val"], [32,5])': 0 + 'trailing_zeros(32, ["rs1_val", "imm_val"], [32,5])': 0 + +bset: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbs.*) + mnemonics: + bset: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: +# 'xlenlim("rs1_val", xlen)': 0 +# 'xlenlim("rs2_val", xlen )': 0 + 'walking_ones("rs1_val", ceil(log(xlen, 2)), False)': 0 + 'walking_ones("rs2_val", ceil(log(xlen, 2)), False)': 0 + 'leading_ones(32, ["rs1_val", "rs2_val"], [32,5])': 0 + 'trailing_ones(32, ["rs1_val", "rs2_val"], [32,5])': 0 + 'leading_zeros(32, ["rs1_val", "rs2_val"], [32,5])': 0 + 'trailing_zeros(32, ["rs1_val", "rs2_val"], [32,5])': 0 + <<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn] + + +bseti: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbs.*) + mnemonics: + bseti: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: +# 'xlenlim("rs1_val", xlen)': 0 + 'leading_ones(32, ["rs1_val", "imm_val"], [32,5])': 0 + 'trailing_ones(32, ["rs1_val", "imm_val"], [32,5])': 0 + 'leading_zeros(32, ["rs1_val", "imm_val"], [32,5])': 0 + 'trailing_zeros(32, ["rs1_val", "imm_val"], [32,5])': 0 diff --git a/coverage/b/rv64i_b.cgf b/coverage/b/rv64i_b.cgf new file mode 100644 index 000000000..5cd7cca4c --- /dev/null +++ b/coverage/b/rv64i_b.cgf @@ -0,0 +1,973 @@ +add.uw: + config: + - check ISA:=regex(.*RV64.*I.*B.*) + - check ISA:=regex(.*RV64.*I.*Zba.*) + mnemonics: + add.uw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + 'bitmanip_dataset(xlen,signed=False)': 0 + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + +sh1add: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zba.*) + mnemonics: + sh1add: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'bitmanip_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + + +sh1add.uw: + config: + - check ISA:=regex(.*RV64.*I.*B.*) + - check ISA:=regex(.*RV64.*I.*Zba.*) + mnemonics: + sh1add.uw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + 'bitmanip_dataset(xlen,signed=False)': 0 + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + +sh2add: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zba.*) + mnemonics: + sh2add: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'bitmanip_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +sh2add.uw: + config: + - check ISA:=regex(.*RV64.*I.*B.*) + - check ISA:=regex(.*RV64.*I.*Zba.*) + mnemonics: + sh2add.uw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + 'bitmanip_dataset(xlen,signed=False)': 0 + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + +sh3add: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zba.*) + mnemonics: + sh3add: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'bitmanip_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +sh3add.uw: + config: + - check ISA:=regex(.*RV64.*I.*B.*) + - check ISA:=regex(.*RV64.*I.*Zba.*) + mnemonics: + sh3add.uw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + 'bitmanip_dataset(xlen,signed=False)': 0 + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + +slli.uw: + config: + - check ISA:=regex(.*RV64.*I.*B.*) + - check ISA:=regex(.*RV64.*I.*Zba.*) + mnemonics: + slli.uw: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'bitmanip_dataset(xlen,["rs1_val"],signed=False)': 0 + <<: [*rs1val_walking_unsgn] + 'walking_ones("imm_val", 5, False)': 0 + 'walking_zeros("imm_val", 5, False)': 0 + 'alternate("imm_val", 5, False)': 0 + +xnor: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbb.*) + - check ISA:=regex(.*I.*Zbkb.*) + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*I.*Zkn.*) + - check ISA:=regex(.*I.*Zks.*) + mnemonics: + xnor: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + 'bitmanip_dataset(xlen,signed=False)': 0 + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + 'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0 + +zext.h_64: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbb.*) + mnemonics: + zext.h: 0 + base_op: packw + p_op_cond: rs2 == x0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'rs1_val == 0': 0 + 'rs1_val == 0x80': 0 + 'rs1_val == 0xFF80': 0 + abstract_comb: + 'walking_ones("rs1_val", xlen, False)': 0 + 'walking_zeros("rs1_val", xlen, False)': 0 + 'uniform_random(20, 100, ["rs1_val"], [xlen])': 0 +andn: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbb.*) + - check ISA:=regex(.*I.*Zbkb.*) + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*I.*Zkn.*) + - check ISA:=regex(.*I.*Zks.*) + mnemonics: + andn: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + 'uniform_random(5, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0 + 'bitmanip_dataset(xlen,["rs1_val","rs2_val"],False)': 0 + +clz: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbb.*) + mnemonics: + clz: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + <<: [*rs1val_walking_unsgn] + 'leading_zeros(xlen, ["rs1_val"], [xlen], 11)': 0 + 'leading_ones(xlen, ["rs1_val"], [xlen], 10)': 0 + 'trailing_zeros(xlen, ["rs1_val"], [xlen], 12)': 0 + 'trailing_ones(xlen, ["rs1_val"], [xlen], 13)': 0 + + +clzw: + config: + - check ISA:=regex(.*RV64.*I.*B.*) + - check ISA:=regex(.*RV64.*I.*Zbb.*) + mnemonics: + clzw: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + <<: [*rs1val_walking_unsgn] + 'leading_zeros(xlen, ["rs1_val"], [xlen], 11)': 0 + 'leading_ones(xlen, ["rs1_val"], [xlen], 10)': 0 + 'trailing_zeros(xlen, ["rs1_val"], [xlen], 12)': 0 + 'trailing_ones(xlen, ["rs1_val"], [xlen], 13)': 0 + +ctz: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbb.*) + mnemonics: + ctz: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + <<: [*rs1val_walking_unsgn] + 'leading_zeros(xlen, ["rs1_val"], [xlen], 11)': 0 + 'leading_ones(xlen, ["rs1_val"], [xlen], 10)': 0 + 'trailing_zeros(xlen, ["rs1_val"], [xlen], 12)': 0 + 'trailing_ones(xlen, ["rs1_val"], [xlen], 13)': 0 + +ctzw: + config: + - check ISA:=regex(.*RV64.*I.*B.*) + - check ISA:=regex(.*RV64.*I.*Zbb.*) + mnemonics: + ctzw: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + <<: [*rs1val_walking_unsgn] + 'leading_zeros(xlen, ["rs1_val"], [xlen], 11)': 0 + 'leading_ones(xlen, ["rs1_val"], [xlen], 10)': 0 + 'trailing_zeros(xlen, ["rs1_val"], [xlen], 12)': 0 + 'trailing_ones(xlen, ["rs1_val"], [xlen], 13)': 0 + + +cpop: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbb.*) + mnemonics: + cpop: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + <<: [*rs1val_walking_unsgn] + 'leading_zeros(xlen, ["rs1_val"], [xlen], 11)': 0 + 'leading_ones(xlen, ["rs1_val"], [xlen], 10)': 0 + 'trailing_zeros(xlen, ["rs1_val"], [xlen], 12)': 0 + 'trailing_ones(xlen, ["rs1_val"], [xlen], 13)': 0 + +cpopw: + config: + - check ISA:=regex(.*RV64.*I.*B.*) + - check ISA:=regex(.*RV64.*I.*Zbb.*) + mnemonics: + cpopw: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + <<: [*rs1val_walking_unsgn] + 'leading_zeros(xlen, ["rs1_val"], [xlen], 11)': 0 + 'leading_ones(xlen, ["rs1_val"], [xlen], 10)': 0 + 'trailing_zeros(xlen, ["rs1_val"], [xlen], 12)': 0 + 'trailing_ones(xlen, ["rs1_val"], [xlen], 13)': 0 + +max: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbb.*) + mnemonics: + max: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'bitmanip_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +maxu: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbb.*) + mnemonics: + maxu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + 'bitmanip_dataset(xlen,signed=False)': 0 + <<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn] + +min: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbb.*) + mnemonics: + min: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'bitmanip_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +minu: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbb.*) + mnemonics: + minu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + 'bitmanip_dataset(xlen,signed=False)': 0 + <<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn] + +orcb_64: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbb.*) + mnemonics: + orc.b: 0 + base_op: gorci + p_op_cond: imm_val == 7 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'rs1_val == 0x102040801020408': 0 + 'rs1_val == 0x204080102040801': 0 + 'rs1_val == 0x408010204080102': 0 + 'rs1_val == 0x801020408010204': 0 + abstract_comb: + <<: [*rs1val_walking_unsgn] + + +orn: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbb.*) + - check ISA:=regex(.*I.*Zbkb.*) + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*I.*Zkn.*) + - check ISA:=regex(.*I.*Zks.*) + mnemonics: + orn: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + 'bitmanip_dataset(xlen,signed=False)': 0 + <<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn] + 'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0 + +rev8: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbb.*) + - check ISA:=regex(.*I.*Zbkb.*) + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*I.*Zkn.*) + - check ISA:=regex(.*I.*Zks.*) + mnemonics: + rev8: 0 + base_op: grevi + p_op_cond: imm_val == 56 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'rs1_val == 0x102040801020408': 0 + 'rs1_val == 0x204080102040801': 0 + 'rs1_val == 0x408010204080102': 0 + 'rs1_val == 0x801020408010204': 0 + abstract_comb: + 'leading_ones(64, ["rs1_val"], [32])': 0 + 'trailing_ones(64, ["rs1_val"], [32])': 0 + 'leading_zeros(64, ["rs1_val"], [32])': 0 + 'trailing_zeros(64, ["rs1_val"], [32])': 0 + 'bitmanip_dataset(xlen,["rs1_val"],signed=False)': 0 + +rol: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbb.*) + - check ISA:=regex(.*I.*Zbkb.*) + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*I.*Zkn.*) + - check ISA:=regex(.*I.*Zks.*) + mnemonics: + rol: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'leading_ones(64, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + 'trailing_ones(64, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + 'leading_zeros(64, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + 'trailing_zeros(64, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + +rolw: + config: + - check ISA:=regex(.*RV64.*I.*B.*) + - check ISA:=regex(.*RV64.*I.*Zbb.*) + - check ISA:=regex(.*RV64.*I.*Zbkb.*) + - check ISA:=regex(.*RV64.*I.*Zk.*) + - check ISA:=regex(.*RV64.*I.*Zkn.*) + - check ISA:=regex(.*RV64.*I.*Zks.*) + mnemonics: + rolw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'leading_ones(64, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + 'trailing_ones(64, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + 'leading_zeros(64, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + 'trailing_zeros(64, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + +ror: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbb.*) + - check ISA:=regex(.*I.*Zbkb.*) + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*I.*Zkn.*) + - check ISA:=regex(.*I.*Zks.*) + mnemonics: + ror: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'leading_ones(64, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + 'trailing_ones(64, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + 'leading_zeros(64, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + 'trailing_zeros(64, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + +rori: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbb.*) + - check ISA:=regex(.*I.*Zbkb.*) + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*I.*Zkn.*) + - check ISA:=regex(.*I.*Zks.*) + mnemonics: + rori: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'leading_ones(64, ["rs1_val","imm_val"],[32,5])': 0 + 'trailing_ones(64, ["rs1_val","imm_val"],[32,5])': 0 + 'leading_zeros(64, ["rs1_val","imm_val"],[32,5])': 0 + 'trailing_zeros(64, ["rs1_val","imm_val"],[32,5])': 0 + + +roriw: + config: + - check ISA:=regex(.*RV64.*I.*B.*) + - check ISA:=regex(.*RV64.*I.*Zbb.*) + - check ISA:=regex(.*RV64.*I.*Zbkb.*) + - check ISA:=regex(.*RV64.*I.*Zk.*) + - check ISA:=regex(.*RV64.*I.*Zkn.*) + - check ISA:=regex(.*RV64.*I.*Zks.*) + mnemonics: + roriw: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'leading_ones(64, ["rs1_val","imm_val"],[32,5])': 0 + 'trailing_ones(64, ["rs1_val","imm_val"],[32,5])': 0 + 'leading_zeros(64, ["rs1_val","imm_val"],[32,5])': 0 + 'trailing_zeros(64, ["rs1_val","imm_val"],[32,5])': 0 + +rorw: + config: + - check ISA:=regex(.*RV64.*I.*B.*) + - check ISA:=regex(.*RV64.*I.*Zbb.*) + - check ISA:=regex(.*RV64.*I.*Zbkb.*) + - check ISA:=regex(.*RV64.*I.*Zk.*) + - check ISA:=regex(.*RV64.*I.*Zkn.*) + - check ISA:=regex(.*RV64.*I.*Zks.*) + mnemonics: + rorw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'leading_ones(64, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + 'trailing_ones(64, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + 'leading_zeros(64, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + 'trailing_zeros(64, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + + +sext.b: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbb.*) + mnemonics: + sext.b: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'rs1_val == 0': 0 + 'rs1_val == 0x8000': 0 + abstract_comb: + 'walking_ones("rs1_val", xlen, False)': 0 + 'walking_zeros("rs1_val", xlen, False)': 0 + 'uniform_random(20, 100, ["rs1_val"], [xlen])': 0 + +sext.h: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbb.*) + mnemonics: + sext.h: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'rs1_val == 0': 0 + 'rs1_val == 0x80': 0 + 'rs1_val == 0xff80': 0 + abstract_comb: + 'walking_ones("rs1_val", xlen, False)': 0 + 'walking_zeros("rs1_val", xlen, False)': 0 + 'uniform_random(20, 100, ["rs1_val"], [xlen])': 0 + +clmul: + config: + - check ISA:=regex(.*I.*Zbc.*) + - check ISA:=regex(.*I.*Zbkc.*) + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*I.*Zkn.*) + - check ISA:=regex(.*I.*Zks.*) + mnemonics: + clmul: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + 'rs1_val==1 and rs2_val==1': 0 + 'rs1_val==1 and rs2_val==0': 0 + 'rs1_val==1 and rs2_val==0x1000': 0 + 'rs1_val==0 and rs2_val==1': 0 + 'rs1_val==0 and rs2_val==0': 0 + 'rs1_val==0 and rs2_val==0x1000': 0 + abstract_comb: + <<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn] + 'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0 + +clmulh: + config: + - check ISA:=regex(.*I.*Zbc.*) + - check ISA:=regex(.*I.*Zbkc.*) + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*I.*Zkn.*) + - check ISA:=regex(.*I.*Zks.*) + mnemonics: + clmulh: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + 'rs1_val==1 and rs2_val==1': 0 + 'rs1_val==1 and rs2_val==0': 0 + 'rs1_val==1 and rs2_val==0x1000': 0 + 'rs1_val==0 and rs2_val==1': 0 + 'rs1_val==0 and rs2_val==0': 0 + 'rs1_val==0 and rs2_val==0x1000': 0 + abstract_comb: + <<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn] + 'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0 + + +clmulr: + config: + - check ISA:=regex(.*I.*Zbc.*) + mnemonics: + clmulr: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + 'rs1_val==1 and rs2_val==1': 0 + 'rs1_val==1 and rs2_val==0': 0 + 'rs1_val==1 and rs2_val==0x1000': 0 + 'rs1_val==0 and rs2_val==1': 0 + 'rs1_val==0 and rs2_val==0': 0 + 'rs1_val==0 and rs2_val==0x1000': 0 + abstract_comb: + <<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn] + 'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0 + +bclr: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbs.*) + mnemonics: + bclr: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: +# 'xlenlim("rs1_val", xlen)': 0 +# 'xlenlim("rs2_val", xlen )': 0 + 'walking_ones("rs1_val", ceil(log(xlen, 2)), False)': 0 + 'walking_ones("rs2_val", ceil(log(xlen, 2)), False)': 0 + 'leading_ones(64, ["rs1_val", "rs2_val"], [32,5])': 0 + 'trailing_ones(64, ["rs1_val", "rs2_val"], [32,5])': 0 + 'leading_zeros(64, ["rs1_val", "rs2_val"], [32,5])': 0 + 'trailing_zeros(64, ["rs1_val", "rs2_val"], [32,5])': 0 + <<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn] + + +bclri: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbs.*) + mnemonics: + bclri: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: +# 'xlenlim("rs1_val", xlen)': 0 + 'leading_ones(64, ["rs1_val", "imm_val"], [32,5])': 0 + 'trailing_ones(64, ["rs1_val", "imm_val"], [32,5])': 0 + 'leading_zeros(64, ["rs1_val", "imm_val"], [32,5])': 0 + 'trailing_zeros(64, ["rs1_val", "imm_val"], [32,5])': 0 + + +bext: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbs.*) + mnemonics: + bext: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: +# 'xlenlim("rs1_val", xlen)': 0 +# 'xlenlim("rs2_val", xlen )': 0 + 'walking_ones("rs1_val", ceil(log(xlen, 2)), False)': 0 + 'walking_ones("rs2_val", ceil(log(xlen, 2)), False)': 0 + 'leading_ones(64, ["rs1_val", "rs2_val"], [32,5])': 0 + 'trailing_ones(64, ["rs1_val", "rs2_val"], [32,5])': 0 + 'leading_zeros(64, ["rs1_val", "rs2_val"], [32,5])': 0 + 'trailing_zeros(64, ["rs1_val", "rs2_val"], [32,5])': 0 + <<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn] + + +bexti: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbs.*) + mnemonics: + bexti: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: +# 'xlenlim("rs1_val", xlen)': 0 + 'leading_ones(64, ["rs1_val", "imm_val"], [32,5])': 0 + 'trailing_ones(64, ["rs1_val", "imm_val"], [32,5])': 0 + 'leading_zeros(64, ["rs1_val", "imm_val"], [32,5])': 0 + 'trailing_zeros(64, ["rs1_val", "imm_val"], [32,5])': 0 + + +binv: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbs.*) + mnemonics: + binv: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: +# 'xlenlim("rs1_val", xlen)': 0 +# 'xlenlim("rs2_val", xlen )': 0 + 'walking_ones("rs1_val", ceil(log(xlen, 2)), False)': 0 + 'walking_ones("rs2_val", ceil(log(xlen, 2)), False)': 0 + 'leading_ones(64, ["rs1_val", "rs2_val"], [32,5])': 0 + 'trailing_ones(64, ["rs1_val", "rs2_val"], [32,5])': 0 + 'leading_zeros(64, ["rs1_val", "rs2_val"], [32,5])': 0 + 'trailing_zeros(64, ["rs1_val", "rs2_val"], [32,5])': 0 + <<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn] + + +binvi: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbs.*) + mnemonics: + binvi: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: +# 'xlenlim("rs1_val", xlen)': 0 + 'leading_ones(64, ["rs1_val", "imm_val"], [32,5])': 0 + 'trailing_ones(64, ["rs1_val", "imm_val"], [32,5])': 0 + 'leading_zeros(64, ["rs1_val", "imm_val"], [32,5])': 0 + 'trailing_zeros(64, ["rs1_val", "imm_val"], [32,5])': 0 + +bset: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbs.*) + mnemonics: + bset: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: +# 'xlenlim("rs1_val", xlen)': 0 +# 'xlenlim("rs2_val", xlen )': 0 + 'walking_ones("rs1_val", ceil(log(xlen, 2)), False)': 0 + 'walking_ones("rs2_val", ceil(log(xlen, 2)), False)': 0 + 'leading_ones(64, ["rs1_val", "rs2_val"], [32,5])': 0 + 'trailing_ones(64, ["rs1_val", "rs2_val"], [32,5])': 0 + 'leading_zeros(64, ["rs1_val", "rs2_val"], [32,5])': 0 + 'trailing_zeros(64, ["rs1_val", "rs2_val"], [32,5])': 0 + <<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn] + + + +bseti: + config: + - check ISA:=regex(.*I.*B.*) + - check ISA:=regex(.*I.*Zbs.*) + mnemonics: + bseti: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: +# 'xlenlim("rs1_val", xlen)': 0 + 'leading_ones(64, ["rs1_val", "imm_val"], [32,5])': 0 + 'trailing_ones(64, ["rs1_val", "imm_val"], [32,5])': 0 + 'leading_zeros(64, ["rs1_val", "imm_val"], [32,5])': 0 + 'trailing_zeros(64, ["rs1_val", "imm_val"], [32,5])': 0 diff --git a/coverage/c/rv32ec.cgf b/coverage/c/rv32ec.cgf new file mode 100644 index 000000000..c995686e4 --- /dev/null +++ b/coverage/c/rv32ec.cgf @@ -0,0 +1,446 @@ +# For Licence details look at https://github.com/riscv-software-src/riscv-ctg/-/blob/master/LICENSE.incore + +cebreak: + config: + - check ISA:=regex(.*E.*Zicsr.*.C*) ;def RVTEST_E = True + mnemonics: + c.ebreak: 0 + +caddi4spn: + config: + - check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True + mnemonics: + c.addi4spn: 0 + rd: + <<: *c_regs + val_comb: + 'imm_val > 0' : 0 + 'imm_val == 1020': 0 + abstract_comb: + 'walking_ones("imm_val", 8,False,scale_func = lambda x: x*4)': 0 + 'walking_zeros("imm_val", 8,False,scale_func = lambda x: x*4)': 0 + 'alternate("imm_val",8,False,scale_func = lambda x: x*4)': 0 + +clw: + config: + - check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True + mnemonics: + c.lw: 0 + rs1: + <<: *c_regs + rd: + <<: *c_regs + op_comb: + 'rs1 == rd': 0 + 'rs1 != rd': 0 + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + abstract_comb: + 'walking_ones("imm_val",5,False, scale_func = lambda x: x*4)': 0 + 'walking_zeros("imm_val",5,False, scale_func = lambda x: x*4)': 0 + 'alternate("imm_val",5, False,scale_func = lambda x: x*4)': 0 + + +csw: + config: + - check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True + mnemonics: + c.sw: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + 'rs1 != rs2': 0 + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + <<: [ *base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + 'walking_ones("imm_val",5,False, scale_func = lambda x: x*4)': 0 + 'walking_zeros("imm_val",5,False, scale_func = lambda x: x*4)': 0 + 'alternate("imm_val",5, False,scale_func = lambda x: x*4)': 0 + + +cnop: + config: + - check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True + mnemonics: + c.nop: 0 + val_comb: + abstract_comb: + <<: *cbimm_val_walking + +caddi: + config: + - check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True + mnemonics: + c.addi: 0 + rd: + <<: *rv32e_regs_mx0 + val_comb: + <<: [*base_rs1val_sgn, *cbfmt_immval_sgn, *ifmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val",("imm_val",6)])': 0 + <<: [*rs1val_walking, *cbimm_val_walking] + +cjal: + config: + - check ISA:=regex(.*RV32.*E.*C.*) ;def RVTEST_E = True + mnemonics: + c.jal: 0 + val_comb: + 'imm_val > 0': 0 + 'imm_val < 0': 0 + abstract_comb: + 'walking_ones("imm_val", 11,fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030),scale_func = lambda x: x*2)': 0 + 'walking_zeros("imm_val", 11,fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030),scale_func = lambda x: x*2)': 0 + 'alternate("imm_val",11, fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030) ,scale_func = lambda x: x*2)': 0 + +cli: + config: + - check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True + mnemonics: + c.li: 0 + rd: + <<: *rv32e_regs + val_comb: + <<: [*cbfmt_immval_sgn] + abstract_comb: + 'walking_ones("imm_val", 6)': 0 + 'walking_zeros("imm_val", 6)': 0 + 'alternate("imm_val", 6)': 0 + +caddi16sp: + config: + - check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True + mnemonics: + c.addi16sp: 0 + rd: + x2: 0 + val_comb: + <<: [*base_rs1val_sgn,*ifmt_val_comb_sgn] + 'imm_val == -512': 0 + 'imm_val == 496': 0 + abstract_comb: + <<: [*rs1val_walking] + 'walking_ones("imm_val", 6,True,scale_func = lambda x: x*16)': 0 + 'walking_zeros("imm_val", 6,True,scale_func = lambda x: x*16)': 0 + 'alternate("imm_val",6,True,scale_func = lambda x: x*16)': 0 + +clui: + config: + - check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True + mnemonics: + c.lui: 0 + rd: + <<: *rv32e_regs_mx2 + val_comb: + 'rs1_val > 0 and imm_val > 32': 0 + 'rs1_val > 0 and imm_val < 32 and imm_val !=0 ': 0 + 'rs1_val < 0 and imm_val > 32': 0 + 'rs1_val < 0 and imm_val < 32 and imm_val !=0 ': 0 + abstract_comb: + 'walking_ones("imm_val", 6, False)': 0 + 'walking_zeros("imm_val", 6, False)': 0 + 'alternate("imm_val", 6, False)': 0 + +csrli: + config: + - check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True + mnemonics: + c.srli: 0 + rs1: + <<: *c_regs + val_comb: + 'rs1_val < 0 and imm_val < xlen': 0 + 'rs1_val > 0 and imm_val < xlen': 0 + 'rs1_val == imm_val and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == (-2**(xlen-1)) and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == 0 and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == (2**(xlen-1)-1) and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == 1 and imm_val != 0 and imm_val < xlen': 0 + abstract_comb: + 'sp_dataset(xlen,["rs1_val"])': 0 + <<: [*rs1val_walking] + 'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0 + 'alternate("imm_val", ceil(log(xlen,2)), False)': 0 + +csrai: + config: + - check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True + mnemonics: + c.srai: 0 + rs1: + <<: *c_regs + val_comb: + 'rs1_val < 0 and imm_val < xlen': 0 + 'rs1_val > 0 and imm_val < xlen': 0 + 'rs1_val == imm_val and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == (-2**(xlen-1)) and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == 0 and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == (2**(xlen-1)-1) and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == 1 and imm_val != 0 and imm_val < xlen': 0 + abstract_comb: + 'sp_dataset(xlen,["rs1_val"])': 0 + <<: [*rs1val_walking] + 'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0 + 'alternate("imm_val", ceil(log(xlen,2)), False)': 0 + +candi: + config: + - check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True + mnemonics: + c.andi: 0 + rs1: + <<: *c_regs + val_comb: + <<: [*base_rs1val_sgn,*cbfmt_immval_sgn,*ifmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val",("imm_val",6)])': 0 + <<: [*rs1val_walking, *cbimm_val_walking] + +csub: + config: + - check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True + mnemonics: + c.sub: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*crfmt_val_comb_sgn, *base_rs1val_sgn, *base_rs2val_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking,*rs2val_walking] + +cxor: + config: + - check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True + mnemonics: + c.xor: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*crfmt_val_comb_sgn, *base_rs1val_sgn, *base_rs2val_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking,*rs2val_walking] + +cor: + config: + - check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True + mnemonics: + c.or: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*crfmt_val_comb_sgn, *base_rs1val_sgn,*base_rs2val_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking,*rs2val_walking] + +cand: + config: + - check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True + mnemonics: + c.and: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*crfmt_val_comb_sgn, *base_rs1val_sgn,*base_rs2val_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking,*rs2val_walking] + + + +cj: + config: + - check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True + mnemonics: + c.j: 0 + val_comb: + 'imm_val > 0': 0 + 'imm_val < 0': 0 + abstract_comb: + 'walking_ones("imm_val", 11,fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030),scale_func = lambda x: x*2)': 0 + 'walking_zeros("imm_val", 11,fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030),scale_func = lambda x: x*2)': 0 + 'alternate("imm_val",11, fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030) ,scale_func = lambda x: x*2)': 0 + +cbeqz: + config: + - check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True + mnemonics: + c.beqz: 0 + rs1: + <<: *c_regs + val_comb: + 'rs1_val > 0 and imm_val > 0': 0 + 'rs1_val < 0 and imm_val > 0': 0 + 'rs1_val == 0 and imm_val > 0': 0 + 'rs1_val > 0 and imm_val < 0': 0 + 'rs1_val < 0 and imm_val < 0': 0 + 'rs1_val == 0 and imm_val < 0': 0 + <<: [*base_rs1val_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val"])': 0 + <<: [*rs1val_walking] + +cbnez: + config: + - check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True + mnemonics: + c.bnez: 0 + rs1: + <<: *c_regs + val_comb: + 'rs1_val > 0 and imm_val > 0': 0 + 'rs1_val < 0 and imm_val > 0': 0 + 'rs1_val == 0 and imm_val > 0': 0 + 'rs1_val > 0 and imm_val < 0': 0 + 'rs1_val < 0 and imm_val < 0': 0 + 'rs1_val == 0 and imm_val < 0': 0 + <<: [*base_rs1val_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val"])': 0 + <<: [*rs1val_walking] + +cslli: + config: + - check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True + mnemonics: + c.slli: 0 + rd: + <<: *c_regs + val_comb: + 'rs1_val < 0 and imm_val < xlen': 0 + 'rs1_val > 0 and imm_val < xlen': 0 + 'rs1_val == imm_val and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == (-2**(xlen-1)) and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == 0 and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == (2**(xlen-1)-1) and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == 1 and imm_val != 0 and imm_val < xlen': 0 + abstract_comb: + 'sp_dataset(xlen,["rs1_val"])': 0 + <<: [*rs1val_walking] + 'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0 + 'alternate("imm_val", ceil(log(xlen,2)), False)': 0 + +clwsp: + config: + - check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True + mnemonics: + c.lwsp: 0 + rd: + <<: *rv32e_regs_mx0 + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + abstract_comb: + 'walking_ones("imm_val",6,False, scale_func = lambda x: x*4)': 0 + 'walking_zeros("imm_val",6,False, scale_func = lambda x: x*4)': 0 + 'alternate("imm_val",6, False,scale_func = lambda x: x*4)': 0 + + +cjr: + config: + - check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True + mnemonics: + c.jr: 0 + rs1: + <<: *rv32e_regs_mx0 + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *base_rs1val_sgn_rs2val_zero + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: *rs1val_walking + +cmv: + config: + - check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True + mnemonics: + c.mv: 0 + rs2: + <<: *rv32e_regs_mx0 + rd: + <<: *rv32e_regs + op_comb: + 'rs2 == rd and rs2 != 0': 0 + 'rs2 != rd and rs2 != 0': 0 + val_comb: + <<: [*base_rs2val_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs2_val"])': 0 + <<: [*rs2val_walking] + +cadd: + config: + - check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True + mnemonics: + c.add: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs_mx0 + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*crfmt_val_comb_sgn, *base_rs1val_sgn,*base_rs2val_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking,*rs2val_walking] + +cjalr: + config: + - check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True + mnemonics: + c.jalr: 0 + rs1: + <<: *rv32e_regs_mx0 + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *base_rs1val_sgn_rs2val_zero + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: *rs1val_walking + +cswsp: + config: + - check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True + mnemonics: + c.swsp: 0 + rs2: + <<: *rv32e_regs_mx2 + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + <<: [ *base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + 'walking_ones("imm_val",6,False, scale_func = lambda x: x*4)': 0 + 'walking_zeros("imm_val",6,False, scale_func = lambda x: x*4)': 0 + 'alternate("imm_val",6, False,scale_func = lambda x: x*4)': 0 diff --git a/coverage/c/rv32i_zcb.cgf b/coverage/c/rv32i_zcb.cgf new file mode 100644 index 000000000..2fc963758 --- /dev/null +++ b/coverage/c/rv32i_zcb.cgf @@ -0,0 +1,176 @@ + +clbu: + config: + - check ISA:=regex(.*I.*Zca.*Zcb.*) + mnemonics: + c.lbu: 0 + rs1: + <<: *c_regs + rd: + <<: *c_regs + op_comb: + 'rs1 == rd': 0 + 'rs1 != rd': 0 + val_comb: + 'imm_val == 0': 0 + 'imm_val == 1': 0 + 'imm_val == 2': 0 + 'imm_val == 3': 0 + +clhu: + config: + - check ISA:=regex(.*I.*Zca.*Zcb.*) + mnemonics: + c.lhu: 0 + rs1: + <<: *c_regs + rd: + <<: *c_regs + op_comb: + 'rs1 == rd': 0 + 'rs1 != rd': 0 + val_comb: + 'imm_val == 0': 0 + 'imm_val == 2': 0 + +clh: + config: + - check ISA:=regex(.*I.*Zca.*Zcb.*) + mnemonics: + c.lh: 0 + rs1: + <<: *c_regs + rd: + <<: *c_regs + op_comb: + 'rs1 == rd': 0 + 'rs1 != rd': 0 + val_comb: + 'imm_val == 0': 0 + 'imm_val == 2': 0 + +csb: + config: + - check ISA:=regex(.*I.*Zca.*Zcb.*) + mnemonics: + c.sb: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + 'rs1 != rs2': 0 + val_comb: + 'imm_val == 0': 0 + 'imm_val == 1': 0 + 'imm_val == 2': 0 + 'imm_val == 3': 0 + +csh: + config: + - check ISA:=regex(.*I.*Zca.*Zcb.*) + mnemonics: + c.sh: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + 'rs1 != rs2': 0 + val_comb: + 'imm_val == 0': 0 + 'imm_val == 2': 0 + +csext.b: + config: + - check ISA:=regex(.*I.*Zca.*Zcb.*.Zbb.*) + mnemonics: + c.sext.b: 0 + rs1: + <<: *c_regs + val_comb: + 'rs1_val == 0': 0 + 'rs1_val == 0x80': 0 + 'rs1_val == 0x8000': 0 + abstract_comb: + 'walking_ones("rs1_val", xlen, False)': 0 + 'walking_zeros("rs1_val", xlen, False)': 0 +csext.h: + config: + - check ISA:=regex(.*I.*Zca.*Zcb.*.Zbb.*) + mnemonics: + c.sext.h: 0 + rs1: + <<: *c_regs + val_comb: + 'rs1_val == 0': 0 + 'rs1_val == 0x800': 0 + 'rs1_val == 0xFF80': 0 + abstract_comb: + 'walking_ones("rs1_val", xlen, False)': 0 + 'walking_zeros("rs1_val", xlen, False)': 0 + +czext.b: + config: + - check ISA:=regex(.*I.*Zca.*Zcb.*) + mnemonics: + c.zext.b: 0 + rs1: + <<: *c_regs + val_comb: + 'rs1_val == 0': 0 + 'rs1_val == 0x80': 0 + 'rs1_val == 0x8000': 0 + abstract_comb: + 'walking_ones("rs1_val", xlen, False)': 0 + 'walking_zeros("rs1_val", xlen, False)': 0 + +czext.h: + config: + - check ISA:=regex(.*I.*Zca.*Zcb.*.Zbb.*) + mnemonics: + c.zext.h: 0 + rs1: + <<: *c_regs + val_comb: + 'rs1_val == 0': 0 + 'rs1_val == 0x800': 0 + 'rs1_val == 0xFF80': 0 + abstract_comb: + 'walking_ones("rs1_val", xlen, False)': 0 + 'walking_zeros("rs1_val", xlen, False)': 0 + +cnot: + config: + - check ISA:=regex(.*I.*Zca.*Zcb.*) + mnemonics: + c.not: 0 + rs1: + <<: *c_regs + op_comb: + <<: *r0fmt_op_comb + val_comb: + 'rs1_val == 0': 0 + 'rs1_val == 0x800': 0 + 'rs1_val == 0xFF80': 0 + abstract_comb: + 'walking_ones("rs1_val", xlen, False)': 0 + 'walking_zeros("rs1_val", xlen, False)': 0 + +cmul: + config: + - check ISA:=regex(.*I.*M.*Zca.*Zcb.*) + mnemonics: + c.mul: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + \ No newline at end of file diff --git a/coverage/c/rv32ic.cgf b/coverage/c/rv32ic.cgf new file mode 100644 index 000000000..0c8eb4f49 --- /dev/null +++ b/coverage/c/rv32ic.cgf @@ -0,0 +1,478 @@ +# For Licence details look at https://github.com/riscv-software-src/riscv-ctg/-/blob/master/LICENSE.incore + +cebreak: + config: + - check ISA:=regex(.*I.*Zicsr.*.C*) + mnemonics: + c.ebreak: 0 + +caddi4spn: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.addi4spn: 0 + rd: + <<: *c_regs + val_comb: + 'imm_val > 0' : 0 + 'imm_val == 1020': 0 + abstract_comb: + 'walking_ones("imm_val", 8,False,scale_func = lambda x: x*4)': 0 + 'walking_zeros("imm_val", 8,False,scale_func = lambda x: x*4)': 0 + 'alternate("imm_val",8,False,scale_func = lambda x: x*4)': 0 + +clw: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.lw: 0 + rs1: + <<: *c_regs + rd: + <<: *c_regs + op_comb: + 'rs1 == rd': 0 + 'rs1 != rd': 0 + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + abstract_comb: + 'walking_ones("imm_val",5,False, scale_func = lambda x: x*4)': 0 + 'walking_zeros("imm_val",5,False, scale_func = lambda x: x*4)': 0 + 'alternate("imm_val",5, False,scale_func = lambda x: x*4)': 0 + + +csw: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.sw: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + 'rs1 != rs2': 0 + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + <<: [ *base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + 'walking_ones("imm_val",5,False, scale_func = lambda x: x*4)': 0 + 'walking_zeros("imm_val",5,False, scale_func = lambda x: x*4)': 0 + 'alternate("imm_val",5, False,scale_func = lambda x: x*4)': 0 + + +cnop: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.nop: 0 + val_comb: + abstract_comb: + <<: *cbimm_val_walking + +caddi: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.addi: 0 + rd: + <<: *all_regs_mx0 + val_comb: + <<: [*base_rs1val_sgn, *cbfmt_immval_sgn, *ifmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val",("imm_val",6)])': 0 + <<: [*rs1val_walking, *cbimm_val_walking] + +cjal: + config: + - check ISA:=regex(.*RV32.*I.*C.*) + mnemonics: + c.jal: 0 + val_comb: + 'imm_val > 0': 0 + 'imm_val < 0': 0 + abstract_comb: + 'walking_ones("imm_val", 11,fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030),scale_func = lambda x: x*2)': 0 + 'walking_zeros("imm_val", 11,fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030),scale_func = lambda x: x*2)': 0 + 'alternate("imm_val",11, fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030) ,scale_func = lambda x: x*2)': 0 + +cli: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.li: 0 + rd: + <<: *all_regs + val_comb: + <<: [*cbfmt_immval_sgn] + abstract_comb: + 'walking_ones("imm_val", 6)': 0 + 'walking_zeros("imm_val", 6)': 0 + 'alternate("imm_val", 6)': 0 + +caddi16sp: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.addi16sp: 0 + rd: + x2: 0 + val_comb: + <<: [*base_rs1val_sgn,*ifmt_val_comb_sgn] + 'imm_val == -512': 0 + 'imm_val == 496': 0 + abstract_comb: + <<: [*rs1val_walking] + 'walking_ones("imm_val", 6,True,scale_func = lambda x: x*16)': 0 + 'walking_zeros("imm_val", 6,True,scale_func = lambda x: x*16)': 0 + 'alternate("imm_val",6,True,scale_func = lambda x: x*16)': 0 + +clui: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.lui: 0 + rd: + x0: 0 + x1: 0 + x3: 0 + x4: 0 + x5: 0 + x6: 0 + x7: 0 + x8: 0 + x9: 0 + x10: 0 + x11: 0 + x12: 0 + x13: 0 + x14: 0 + x15: 0 + x16: 0 + x17: 0 + x18: 0 + x19: 0 + x20: 0 + x21: 0 + x22: 0 + x23: 0 + x24: 0 + x25: 0 + x26: 0 + x27: 0 + x28: 0 + x29: 0 + x30: 0 + x31: 0 + + val_comb: + 'rs1_val > 0 and imm_val > 32': 0 + 'rs1_val > 0 and imm_val < 32 and imm_val !=0 ': 0 + 'rs1_val < 0 and imm_val > 32': 0 + 'rs1_val < 0 and imm_val < 32 and imm_val !=0 ': 0 + abstract_comb: + 'walking_ones("imm_val", 6, False)': 0 + 'walking_zeros("imm_val", 6, False)': 0 + 'alternate("imm_val", 6, False)': 0 + +csrli: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.srli: 0 + rs1: + <<: *c_regs + val_comb: + 'rs1_val < 0 and imm_val < xlen': 0 + 'rs1_val > 0 and imm_val < xlen': 0 + 'rs1_val == imm_val and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == (-2**(xlen-1)) and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == 0 and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == (2**(xlen-1)-1) and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == 1 and imm_val != 0 and imm_val < xlen': 0 + abstract_comb: + 'sp_dataset(xlen,["rs1_val"])': 0 + <<: [*rs1val_walking] + 'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0 + 'alternate("imm_val", ceil(log(xlen,2)), False)': 0 + +csrai: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.srai: 0 + rs1: + <<: *c_regs + val_comb: + 'rs1_val < 0 and imm_val < xlen': 0 + 'rs1_val > 0 and imm_val < xlen': 0 + 'rs1_val == imm_val and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == (-2**(xlen-1)) and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == 0 and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == (2**(xlen-1)-1) and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == 1 and imm_val != 0 and imm_val < xlen': 0 + abstract_comb: + 'sp_dataset(xlen,["rs1_val"])': 0 + <<: [*rs1val_walking] + 'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0 + 'alternate("imm_val", ceil(log(xlen,2)), False)': 0 + +candi: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.andi: 0 + rs1: + <<: *c_regs + val_comb: + <<: [*base_rs1val_sgn,*cbfmt_immval_sgn,*ifmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val",("imm_val",6)])': 0 + <<: [*rs1val_walking, *cbimm_val_walking] + +csub: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.sub: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*crfmt_val_comb_sgn, *base_rs1val_sgn, *base_rs2val_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking,*rs2val_walking] + +cxor: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.xor: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*crfmt_val_comb_sgn, *base_rs1val_sgn, *base_rs2val_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking,*rs2val_walking] + +cor: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.or: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*crfmt_val_comb_sgn, *base_rs1val_sgn,*base_rs2val_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking,*rs2val_walking] + +cand: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.and: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*crfmt_val_comb_sgn, *base_rs1val_sgn,*base_rs2val_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking,*rs2val_walking] + + + +cj: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.j: 0 + val_comb: + 'imm_val > 0': 0 + 'imm_val < 0': 0 + abstract_comb: + 'walking_ones("imm_val", 11,fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030),scale_func = lambda x: x*2)': 0 + 'walking_zeros("imm_val", 11,fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030),scale_func = lambda x: x*2)': 0 + 'alternate("imm_val",11, fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030) ,scale_func = lambda x: x*2)': 0 + +cbeqz: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.beqz: 0 + rs1: + <<: *c_regs + val_comb: + 'rs1_val > 0 and imm_val > 0': 0 + 'rs1_val < 0 and imm_val > 0': 0 + 'rs1_val == 0 and imm_val > 0': 0 + 'rs1_val > 0 and imm_val < 0': 0 + 'rs1_val < 0 and imm_val < 0': 0 + 'rs1_val == 0 and imm_val < 0': 0 + <<: [*base_rs1val_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val"])': 0 + <<: [*rs1val_walking] + +cbnez: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.bnez: 0 + rs1: + <<: *c_regs + val_comb: + 'rs1_val > 0 and imm_val > 0': 0 + 'rs1_val < 0 and imm_val > 0': 0 + 'rs1_val == 0 and imm_val > 0': 0 + 'rs1_val > 0 and imm_val < 0': 0 + 'rs1_val < 0 and imm_val < 0': 0 + 'rs1_val == 0 and imm_val < 0': 0 + <<: [*base_rs1val_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val"])': 0 + <<: [*rs1val_walking] + +cslli: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.slli: 0 + rd: + <<: *c_regs + val_comb: + 'rs1_val < 0 and imm_val < xlen': 0 + 'rs1_val > 0 and imm_val < xlen': 0 + 'rs1_val == imm_val and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == (-2**(xlen-1)) and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == 0 and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == (2**(xlen-1)-1) and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == 1 and imm_val != 0 and imm_val < xlen': 0 + abstract_comb: + 'sp_dataset(xlen,["rs1_val"])': 0 + <<: [*rs1val_walking] + 'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0 + 'alternate("imm_val", ceil(log(xlen,2)), False)': 0 + +clwsp: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.lwsp: 0 + rd: + <<: *all_regs_mx0 + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + abstract_comb: + 'walking_ones("imm_val",6,False, scale_func = lambda x: x*4)': 0 + 'walking_zeros("imm_val",6,False, scale_func = lambda x: x*4)': 0 + 'alternate("imm_val",6, False,scale_func = lambda x: x*4)': 0 + + +cjr: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.jr: 0 + rs1: + <<: *all_regs_mx0 + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *base_rs1val_sgn_rs2val_zero + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: *rs1val_walking + +cmv: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.mv: 0 + rs2: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + 'rs2 == rd and rs2 != 0': 0 + 'rs2 != rd and rs2 != 0': 0 + val_comb: + <<: [*base_rs2val_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs2_val"])': 0 + <<: [*rs2val_walking] + +cadd: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.add: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs_mx0 + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*crfmt_val_comb_sgn, *base_rs1val_sgn,*base_rs2val_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking,*rs2val_walking] + +cjalr: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.jalr: 0 + rs1: + <<: *all_regs_mx0 + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *base_rs1val_sgn_rs2val_zero + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: *rs1val_walking + +cswsp: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.swsp: 0 + rs2: + <<: *all_regs_mx2 + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + <<: [ *base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + 'walking_ones("imm_val",6,False, scale_func = lambda x: x*4)': 0 + 'walking_zeros("imm_val",6,False, scale_func = lambda x: x*4)': 0 + 'alternate("imm_val",6, False,scale_func = lambda x: x*4)': 0 + diff --git a/coverage/c/rv64i_zcb.cgf b/coverage/c/rv64i_zcb.cgf new file mode 100644 index 000000000..3bad58b78 --- /dev/null +++ b/coverage/c/rv64i_zcb.cgf @@ -0,0 +1,190 @@ + +clbu: + config: + - check ISA:=regex(.*I.*Zca.*Zcb.*) + mnemonics: + c.lbu: 0 + rs1: + <<: *c_regs + rd: + <<: *c_regs + op_comb: + 'rs1 == rd': 0 + 'rs1 != rd': 0 + val_comb: + 'imm_val == 0': 0 + 'imm_val == 1': 0 + 'imm_val == 2': 0 + 'imm_val == 3': 0 + +clhu: + config: + - check ISA:=regex(.*I.*Zca.*Zcb.*) + mnemonics: + c.lhu: 0 + rs1: + <<: *c_regs + rd: + <<: *c_regs + op_comb: + 'rs1 == rd': 0 + 'rs1 != rd': 0 + val_comb: + 'imm_val == 0': 0 + 'imm_val == 2': 0 + +clh: + config: + - check ISA:=regex(.*I.*Zca.*Zcb.*) + mnemonics: + c.lh: 0 + rs1: + <<: *c_regs + rd: + <<: *c_regs + op_comb: + 'rs1 == rd': 0 + 'rs1 != rd': 0 + val_comb: + 'imm_val == 0': 0 + 'imm_val == 2': 0 + +csb: + config: + - check ISA:=regex(.*I.*Zca.*Zcb.*) + mnemonics: + c.sb: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + 'rs1 != rs2': 0 + val_comb: + 'imm_val == 0': 0 + 'imm_val == 1': 0 + 'imm_val == 2': 0 + 'imm_val == 3': 0 + +csh: + config: + - check ISA:=regex(.*I.*Zca.*Zcb.*) + mnemonics: + c.sh: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + 'rs1 != rs2': 0 + val_comb: + 'imm_val == 0': 0 + 'imm_val == 2': 0 + +csext.b: + config: + - check ISA:=regex(.*I.*Zca.*Zcb.*.Zbb.*) + mnemonics: + c.sext.b: 0 + rs1: + <<: *c_regs + val_comb: + 'rs1_val == 0': 0 + 'rs1_val == 0x80': 0 + 'rs1_val == 0x8000': 0 + abstract_comb: + 'walking_ones("rs1_val", xlen, False)': 0 + 'walking_zeros("rs1_val", xlen, False)': 0 +csext.h: + config: + - check ISA:=regex(.*I.*Zca.*Zcb.*.Zbb.*) + mnemonics: + c.sext.h: 0 + rs1: + <<: *c_regs + val_comb: + 'rs1_val == 0': 0 + 'rs1_val == 0x800': 0 + 'rs1_val == 0xFF80': 0 + abstract_comb: + 'walking_ones("rs1_val", xlen, False)': 0 + 'walking_zeros("rs1_val", xlen, False)': 0 + +czext.b: + config: + - check ISA:=regex(.*I.*Zca.*Zcb.*) + mnemonics: + c.zext.b: 0 + rs1: + <<: *c_regs + val_comb: + 'rs1_val == 0': 0 + 'rs1_val == 0x80': 0 + 'rs1_val == 0x8000': 0 + abstract_comb: + 'walking_ones("rs1_val", xlen, False)': 0 + 'walking_zeros("rs1_val", xlen, False)': 0 + +czext.h: + config: + - check ISA:=regex(.*I.*Zca.*Zcb.*.Zbb.*) + mnemonics: + c.zext.h: 0 + rs1: + <<: *c_regs + val_comb: + 'rs1_val == 0': 0 + 'rs1_val == 0x800': 0 + 'rs1_val == 0xFF80': 0 + abstract_comb: + 'walking_ones("rs1_val", xlen, False)': 0 + 'walking_zeros("rs1_val", xlen, False)': 0 + +czext.w: + config: + - check ISA:=regex(.*I.*Zca.*Zcb.*.Zba.*) + mnemonics: + c.zext.w: 0 + rs1: + <<: *c_regs + val_comb: + 'rs1_val == 0': 0 + 'rs1_val == 0x800': 0 + 'rs1_val == 0xFF80': 0 + abstract_comb: + 'walking_ones("rs1_val", xlen, False)': 0 + 'walking_zeros("rs1_val", xlen, False)': 0 + +cnot: + config: + - check ISA:=regex(.*I.*Zca.*Zcb.*) + mnemonics: + c.not: 0 + rs1: + <<: *c_regs + op_comb: + <<: *r0fmt_op_comb + val_comb: + 'rs1_val == 0': 0 + 'rs1_val == 0x800': 0 + 'rs1_val == 0xFF80': 0 + abstract_comb: + 'walking_ones("rs1_val", xlen, False)': 0 + 'walking_zeros("rs1_val", xlen, False)': 0 + +cmul: + config: + - check ISA:=regex(.*I.*M.*Zca.*Zcb.*) + mnemonics: + c.mul: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] diff --git a/coverage/c/rv64ic.cgf b/coverage/c/rv64ic.cgf new file mode 100644 index 000000000..9492e1d70 --- /dev/null +++ b/coverage/c/rv64ic.cgf @@ -0,0 +1,586 @@ +# For Licence details look at https://github.com/riscv-software-src/riscv-ctg/-/blob/master/LICENSE.incore + +cebreak: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.ebreak: 0 + +caddi4spn: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.addi4spn: 0 + rd: + <<: *c_regs + val_comb: + 'imm_val > 0' : 0 + 'imm_val == 1020': 0 + abstract_comb: + 'walking_ones("imm_val", 8,False,scale_func = lambda x: x*4)': 0 + 'walking_zeros("imm_val", 8,False,scale_func = lambda x: x*4)': 0 + 'alternate("imm_val",8,False,scale_func = lambda x: x*4)': 0 + +clw: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.lw: 0 + rs1: + <<: *c_regs + rd: + <<: *c_regs + op_comb: + 'rs1 == rd': 0 + 'rs1 != rd': 0 + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + abstract_comb: + 'walking_ones("imm_val",5,False, scale_func = lambda x: x*4)': 0 + 'walking_zeros("imm_val",5,False, scale_func = lambda x: x*4)': 0 + 'alternate("imm_val",5, False,scale_func = lambda x: x*4)': 0 + +cld: + config: + - check ISA:=regex(.*RV64.*I.*C.*) + mnemonics: + c.ld: 0 + rs1: + <<: *c_regs + rd: + <<: *c_regs + op_comb: + 'rs1 == rd': 0 + 'rs1 != rd': 0 + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + abstract_comb: + 'walking_ones("imm_val",5,False, scale_func = lambda x: x*8)': 0 + 'walking_zeros("imm_val",5,False, scale_func = lambda x: x*8)': 0 + 'alternate("imm_val",5, False,scale_func = lambda x: x*8)': 0 + +csw: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.sw: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + 'rs1 != rs2': 0 + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + <<: [ *base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + 'walking_ones("imm_val",5,False, scale_func = lambda x: x*4)': 0 + 'walking_zeros("imm_val",5,False, scale_func = lambda x: x*4)': 0 + 'alternate("imm_val",5, False,scale_func = lambda x: x*4)': 0 + +csd: + config: + - check ISA:=regex(.*RV64.*I.*C.*) + mnemonics: + c.sd: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + 'rs1 != rs2': 0 + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + <<: [ *base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + 'walking_ones("imm_val",5,False, scale_func = lambda x: x*8)': 0 + 'walking_zeros("imm_val",5,False, scale_func = lambda x: x*8)': 0 + 'alternate("imm_val",5, False,scale_func = lambda x: x*8)': 0 + +cnop: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.nop: 0 + val_comb: + abstract_comb: + <<: *cbimm_val_walking + +caddi: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.addi: 0 + rd: + <<: *all_regs_mx0 + val_comb: + <<: [*base_rs1val_sgn, *cbfmt_immval_sgn, *ifmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val",("imm_val",6)])': 0 + <<: [*rs1val_walking, *cbimm_val_walking] + +caddiw: + config: + - check ISA:=regex(.*RV64.*I.*C.*) + mnemonics: + c.addiw: 0 + rd: + <<: *all_regs_mx0 + val_comb: + 'rs1_val == (-2**(xlen-1))': 0 + 'rs1_val == 0': 0 + 'rs1_val == (2**(xlen-1)-1)': 0 + 'rs1_val == 1': 0 + <<: [*cbfmt_immval_sgn, *ifmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val",("imm_val",6)])': 0 + 'walking_ones("rs1_val", xlen)': 0 + 'walking_zeros("rs1_val", xlen)': 0 + 'alternate("rs1_val",xlen)': 0 + <<: [*cbimm_val_walking] + +cli: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.li: 0 + rd: + <<: *all_regs + val_comb: + <<: [*cbfmt_immval_sgn] + abstract_comb: + 'walking_ones("imm_val", 6)': 0 + 'walking_zeros("imm_val", 6)': 0 + 'alternate("imm_val", 6)': 0 + +caddi16sp: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.addi16sp: 0 + rd: + x2: 0 + val_comb: + <<: [*base_rs1val_sgn,*ifmt_val_comb_sgn] + 'imm_val == -512': 0 + 'imm_val == 496': 0 + abstract_comb: + <<: [*rs1val_walking] + 'walking_ones("imm_val", 6,True,scale_func = lambda x: x*16)': 0 + 'walking_zeros("imm_val", 6,True,scale_func = lambda x: x*16)': 0 + 'alternate("imm_val",6,True,scale_func = lambda x: x*16)': 0 + +clui: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.lui: 0 + rd: + x0: 0 + x1: 0 + x3: 0 + x4: 0 + x5: 0 + x6: 0 + x7: 0 + x8: 0 + x9: 0 + x10: 0 + x11: 0 + x12: 0 + x13: 0 + x14: 0 + x15: 0 + x16: 0 + x17: 0 + x18: 0 + x19: 0 + x20: 0 + x21: 0 + x22: 0 + x23: 0 + x24: 0 + x25: 0 + x26: 0 + x27: 0 + x28: 0 + x29: 0 + x30: 0 + x31: 0 + + val_comb: + 'rs1_val > 0 and imm_val > 32': 0 + 'rs1_val > 0 and imm_val < 32 and imm_val !=0 ': 0 + 'rs1_val < 0 and imm_val > 32': 0 + 'rs1_val < 0 and imm_val < 32 and imm_val !=0 ': 0 + abstract_comb: + 'walking_ones("imm_val", 6, False)': 0 + 'walking_zeros("imm_val", 6, False)': 0 + 'alternate("imm_val", 6, False)': 0 + +csrli: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.srli: 0 + rs1: + <<: *c_regs + val_comb: + 'rs1_val < 0 and imm_val < xlen': 0 + 'rs1_val > 0 and imm_val < xlen': 0 + 'rs1_val == imm_val and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == (-2**(xlen-1)) and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == 0 and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == (2**(xlen-1)-1) and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == 1 and imm_val != 0 and imm_val < xlen': 0 + abstract_comb: + 'sp_dataset(xlen,["rs1_val"])': 0 + <<: [*rs1val_walking] + 'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0 + 'alternate("imm_val", ceil(log(xlen,2)), False)': 0 + +csrai: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.srai: 0 + rs1: + <<: *c_regs + val_comb: + 'rs1_val < 0 and imm_val < xlen': 0 + 'rs1_val > 0 and imm_val < xlen': 0 + 'rs1_val == imm_val and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == (-2**(xlen-1)) and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == 0 and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == (2**(xlen-1)-1) and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == 1 and imm_val != 0 and imm_val < xlen': 0 + abstract_comb: + 'sp_dataset(xlen,["rs1_val"])': 0 + <<: [*rs1val_walking] + 'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0 + 'alternate("imm_val", ceil(log(xlen,2)), False)': 0 + +candi: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.andi: 0 + rs1: + <<: *c_regs + val_comb: + <<: [*base_rs1val_sgn,*cbfmt_immval_sgn,*ifmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val",("imm_val",6)])': 0 + <<: [*rs1val_walking, *cbimm_val_walking] + +csub: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.sub: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*crfmt_val_comb_sgn, *base_rs1val_sgn, *base_rs2val_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking,*rs2val_walking] + +cxor: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.xor: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*crfmt_val_comb_sgn, *base_rs1val_sgn, *base_rs2val_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking,*rs2val_walking] + +cor: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.or: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*crfmt_val_comb_sgn, *base_rs1val_sgn,*base_rs2val_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking,*rs2val_walking] + +cand: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.and: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*crfmt_val_comb_sgn, *base_rs1val_sgn,*base_rs2val_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking,*rs2val_walking] + +csubw: + config: + - check ISA:=regex(.*RV64.*I.*C.*) + mnemonics: + c.subw: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*crfmt_val_comb_sgn, *base_rs1val_sgn, *base_rs2val_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking,*rs2val_walking] + +caddw: + config: + - check ISA:=regex(.*RV64.*I.*C.*) + mnemonics: + c.addw: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*crfmt_val_comb_sgn, *base_rs1val_sgn, *base_rs2val_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking,*rs2val_walking] + +cj: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.j: 0 + val_comb: + 'imm_val > 0': 0 + 'imm_val < 0': 0 + abstract_comb: + 'walking_ones("imm_val", 11,fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030),scale_func = lambda x: x*2)': 0 + 'walking_zeros("imm_val", 11,fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030),scale_func = lambda x: x*2)': 0 + 'alternate("imm_val",11, fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030) ,scale_func = lambda x: x*2)': 0 + +cbeqz: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.beqz: 0 + rs1: + <<: *c_regs + val_comb: + 'rs1_val > 0 and imm_val > 0': 0 + 'rs1_val < 0 and imm_val > 0': 0 + 'rs1_val == 0 and imm_val > 0': 0 + 'rs1_val > 0 and imm_val < 0': 0 + 'rs1_val < 0 and imm_val < 0': 0 + 'rs1_val == 0 and imm_val < 0': 0 + <<: [*base_rs1val_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val"])': 0 + <<: [*rs1val_walking] + +cbnez: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.bnez: 0 + rs1: + <<: *c_regs + val_comb: + 'rs1_val > 0 and imm_val > 0': 0 + 'rs1_val < 0 and imm_val > 0': 0 + 'rs1_val == 0 and imm_val > 0': 0 + 'rs1_val > 0 and imm_val < 0': 0 + 'rs1_val < 0 and imm_val < 0': 0 + 'rs1_val == 0 and imm_val < 0': 0 + <<: [*base_rs1val_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val"])': 0 + <<: [*rs1val_walking] + +cslli: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.slli: 0 + rd: + <<: *c_regs + val_comb: + 'rs1_val < 0 and imm_val < xlen': 0 + 'rs1_val > 0 and imm_val < xlen': 0 + 'rs1_val == imm_val and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == (-2**(xlen-1)) and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == 0 and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == (2**(xlen-1)-1) and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == 1 and imm_val != 0 and imm_val < xlen': 0 + abstract_comb: + 'sp_dataset(xlen,["rs1_val"])': 0 + <<: [*rs1val_walking] + 'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0 + 'alternate("imm_val", ceil(log(xlen,2)), False)': 0 + +clwsp: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.lwsp: 0 + rd: + <<: *all_regs_mx0 + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + abstract_comb: + 'walking_ones("imm_val",6,False, scale_func = lambda x: x*4)': 0 + 'walking_zeros("imm_val",6,False, scale_func = lambda x: x*4)': 0 + 'alternate("imm_val",6, False,scale_func = lambda x: x*4)': 0 + +cldsp: + config: + - check ISA:=regex(.*RV64.*I.*C.*) + mnemonics: + c.ldsp: 0 + rd: + <<: *all_regs_mx0 + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + abstract_comb: + 'walking_ones("imm_val",6,False, scale_func = lambda x: x*8)': 0 + 'walking_zeros("imm_val",6,False, scale_func = lambda x: x*8)': 0 + 'alternate("imm_val",6, False,scale_func = lambda x: x*8)': 0 + +cjr: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.jr: 0 + rs1: + <<: *all_regs_mx0 + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *base_rs1val_sgn_rs2val_zero + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: *rs1val_walking + +cmv: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.mv: 0 + rs2: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + 'rs2 == rd and rs2 != 0': 0 + 'rs2 != rd and rs2 != 0': 0 + val_comb: + <<: [*base_rs2val_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs2_val"])': 0 + <<: [*rs2val_walking] + +cadd: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.add: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs_mx0 + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*crfmt_val_comb_sgn, *base_rs1val_sgn,*base_rs2val_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking,*rs2val_walking] + +cjalr: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.jalr: 0 + rs1: + <<: *all_regs_mx0 + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *base_rs1val_sgn_rs2val_zero + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: *rs1val_walking + +cswsp: + config: + - check ISA:=regex(.*I.*C.*) + mnemonics: + c.swsp: 0 + rs2: + <<: *all_regs_mx2 + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + <<: [ *base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + 'walking_ones("imm_val",6,False, scale_func = lambda x: x*4)': 0 + 'walking_zeros("imm_val",6,False, scale_func = lambda x: x*4)': 0 + 'alternate("imm_val",6, False,scale_func = lambda x: x*4)': 0 + +csdsp: + config: + - check ISA:=regex(.*RV64.*I.*C.*) + mnemonics: + c.sdsp: 0 + rs2: + <<: *all_regs_mx2 + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + <<: [ *base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + 'walking_ones("imm_val",6,False, scale_func = lambda x: x*8)': 0 + 'walking_zeros("imm_val",6,False, scale_func = lambda x: x*8)': 0 + 'alternate("imm_val",6, False,scale_func = lambda x: x*8)': 0 diff --git a/coverage/rvi_c.cgf b/coverage/c/rvi_c.cgf similarity index 100% rename from coverage/rvi_c.cgf rename to coverage/c/rvi_c.cgf diff --git a/coverage/cgf.yaml b/coverage/cgf.yaml new file mode 100644 index 000000000..ab8e8101d --- /dev/null +++ b/coverage/cgf.yaml @@ -0,0 +1,2239 @@ +# For Licence details look at https://github.com/riscv-software-src/riscv-ctg/-/blob/master/LICENSE.incore + +datasets: + all_regs: &all_regs + x0: 0 + x1: 0 + x2: 0 + x3: 0 + x4: 0 + x5: 0 + x6: 0 + x7: 0 + x8: 0 + x9: 0 + x10: 0 + x11: 0 + x12: 0 + x13: 0 + x14: 0 + x15: 0 + x16: 0 + x17: 0 + x18: 0 + x19: 0 + x20: 0 + x21: 0 + x22: 0 + x23: 0 + x24: 0 + x25: 0 + x26: 0 + x27: 0 + x28: 0 + x29: 0 + x30: 0 + x31: 0 + + pair_regs: &pair_regs + x0: 0 + x2: 0 + x4: 0 + x6: 0 + x8: 0 + x10: 0 + x12: 0 + x14: 0 + x16: 0 + x18: 0 + x20: 0 + x22: 0 + x24: 0 + x26: 0 + x28: 0 + x30: 0 + + + c_regs: &c_regs + x8: 0 + x9: 0 + x10: 0 + x11: 0 + x12: 0 + x13: 0 + x14: 0 + x15: 0 + + all_regs_mx0: &all_regs_mx0 + x1: 0 + x2: 0 + x3: 0 + x4: 0 + x5: 0 + x6: 0 + x7: 0 + x8: 0 + x9: 0 + x10: 0 + x11: 0 + x12: 0 + x13: 0 + x14: 0 + x15: 0 + x16: 0 + x17: 0 + x18: 0 + x19: 0 + x20: 0 + x21: 0 + x22: 0 + x23: 0 + x24: 0 + x25: 0 + x26: 0 + x27: 0 + x28: 0 + x29: 0 + x30: 0 + x31: 0 + + cbfmt_immval_sgn: &cbfmt_immval_sgn + 'imm_val == (-2**(6-1))': 0 + 'imm_val == 0': 0 + 'imm_val == (2**(6-1)-1)': 0 + 'imm_val == 1': 0 + + rfmt_op_comb: &rfmt_op_comb + 'rs1 == rs2 != rd': 0 + 'rs1 == rd != rs2': 0 + 'rs2 == rd != rs1': 0 + 'rs1 == rs2 == rd': 0 + 'rs1 != rs2 and rs1 != rd and rs2 != rd': 0 + + ifmt_op_comb: &ifmt_op_comb + 'rs1 == rd': 0 + 'rs1 != rd': 0 + + sfmt_op_comb: &sfmt_op_comb + 'rs1 == rs2': 0 + 'rs1 != rs2': 0 + + base_rs1val_sgn: &base_rs1val_sgn + 'rs1_val == (-2**(xlen-1))': 0 + 'rs1_val == 0': 0 + 'rs1_val == (2**(xlen-1)-1)': 0 + 'rs1_val == 1': 0 + + base_rs2val_sgn: &base_rs2val_sgn + 'rs2_val == (-2**(xlen-1))': 0 + 'rs2_val == 0': 0 + 'rs2_val == (2**(xlen-1)-1)': 0 + 'rs2_val == 1': 0 + + base_rs1val_unsgn: &base_rs1val_unsgn + 'rs1_val == 0': 0 + 'rs1_val == (2**(xlen)-1)': 0 + 'rs1_val == 1': 0 + + base_rs2val_unsgn: &base_rs2val_unsgn + 'rs2_val == 0': 0 + 'rs2_val == (2**(xlen)-1)': 0 + 'rs2_val == 1': 0 + + base_rs3val_unsgn: &base_rs3val_unsgn + 'rs3_val == 0': 0 + 'rs3_val == (2**(xlen)-1)': 0 + 'rs3_val == 1': 0 + + + rfmt_val_comb_sgn: &rfmt_val_comb_sgn + 'rs1_val > 0 and rs2_val > 0': 0 + 'rs1_val > 0 and rs2_val < 0': 0 + 'rs1_val < 0 and rs2_val < 0': 0 + 'rs1_val < 0 and rs2_val > 0': 0 + 'rs1_val == rs2_val': 0 + 'rs1_val != rs2_val': 0 + + rfmt_val_comb_unsgn: &rfmt_val_comb_unsgn + 'rs1_val > 0 and rs2_val > 0': 0 + 'rs1_val == rs2_val and rs1_val > 0 and rs2_val > 0': 0 + 'rs1_val != rs2_val and rs1_val > 0 and rs2_val > 0': 0 + + ifmt_val_comb_sgn: &ifmt_val_comb_sgn + 'rs1_val == imm_val': 0 + 'rs1_val != imm_val': 0 + 'rs1_val > 0 and imm_val > 0': 0 + 'rs1_val > 0 and imm_val < 0': 0 + 'rs1_val < 0 and imm_val > 0': 0 + 'rs1_val < 0 and imm_val < 0': 0 + + ifmt_val_comb_unsgn: &ifmt_val_comb_unsgn + 'rs1_val == imm_val and rs1_val > 0 and imm_val > 0': 0 + 'rs1_val != imm_val and rs1_val > 0 and imm_val > 0': 0 + + ifmt_base_immval_sgn: &ifmt_base_immval_sgn + 'imm_val == (-2**(12-1))': 0 + 'imm_val == 0': 0 + 'imm_val == (2**(12-1)-1)': 0 + 'imm_val == 1': 0 + + ifmt_base_immval_unsgn: &ifmt_base_immval_unsgn + 'imm_val == 0': 0 + 'imm_val == (2**(12)-1)': 0 + 'imm_val == 1': 0 + + ifmt_base_shift: &ifmt_base_shift + 'rs1_val < 0 and imm_val > 0 and imm_val < xlen': 0 + 'rs1_val > 0 and imm_val > 0 and imm_val < xlen': 0 + 'rs1_val < 0 and imm_val == 0': 0 + 'rs1_val > 0 and imm_val == 0': 0 + 'rs1_val < 0 and imm_val == (xlen-1)': 0 + 'rs1_val > 0 and imm_val == (xlen-1)': 0 + 'rs1_val == imm_val and imm_val > 0 and imm_val < xlen': 0 + 'rs1_val == (-2**(xlen-1)) and imm_val >= 0 and imm_val < xlen': 0 + 'rs1_val == 0 and imm_val >= 0 and imm_val < xlen': 0 + 'rs1_val == (2**(xlen-1)-1) and imm_val >= 0 and imm_val < xlen': 0 + 'rs1_val == 1 and imm_val >= 0 and imm_val < xlen': 0 + + ifmt_base_shift_32w: &ifmt_base_shift_32w + 'rs1_val < 0 and imm_val > 0 and imm_val < 32': 0 + 'rs1_val > 0 and imm_val > 0 and imm_val < 32': 0 + 'rs1_val < 0 and imm_val == 0': 0 + 'rs1_val > 0 and imm_val == 0': 0 + 'rs1_val < 0 and imm_val == 31': 0 + 'rs1_val > 0 and imm_val == 31': 0 + 'rs1_val == imm_val and imm_val > 0 and imm_val < 32': 0 + 'rs1_val == (-2**(xlen-1)) and imm_val >= 0 and imm_val < 32': 0 + 'rs1_val == 0 and imm_val >= 0 and imm_val < 32': 0 + 'rs1_val == (2**(xlen-1)-1) and imm_val >= 0 and imm_val < 32': 0 + 'rs1_val == 1 and imm_val >= 0 and imm_val < 32': 0 + + + rfmt_base_shift: &rfmt_base_shift + 'rs1_val < 0 and rs2_val > 0 and rs2_val < xlen': 0 + 'rs1_val > 0 and rs2_val > 0 and rs2_val < xlen': 0 + 'rs1_val < 0 and rs2_val == 0': 0 + 'rs1_val > 0 and rs2_val == 0': 0 + 'rs1_val == rs2_val and rs2_val > 0 and rs2_val < xlen': 0 + 'rs1_val == (-2**(xlen-1)) and rs2_val >= 0 and rs2_val < xlen': 0 + 'rs1_val == 0 and rs2_val >= 0 and rs2_val < xlen': 0 + 'rs1_val == (2**(xlen-1)-1) and rs2_val >= 0 and rs2_val < xlen': 0 + 'rs1_val == 1 and rs2_val >= 0 and rs2_val < xlen': 0 + + bfmt_base_branch_val_align_sgn: &bfmt_base_branch_val_align_sgn + 'rs1_val > 0 and rs2_val > 0 and imm_val & 0x03 == 0': 0 + 'rs1_val > 0 and rs2_val < 0 and imm_val & 0x03 == 0': 0 + 'rs1_val < 0 and rs2_val < 0 and imm_val & 0x03 == 0': 0 + 'rs1_val < 0 and rs2_val > 0 and imm_val & 0x03 == 0': 0 + 'rs1_val == rs2_val and imm_val > 0 and imm_val & 0x03 == 0': 0 + 'rs1_val == rs2_val and imm_val < 0 and imm_val & 0x03 == 0': 0 + 'rs1_val > rs2_val and imm_val > 0 and imm_val & 0x03 == 0': 0 + 'rs1_val > rs2_val and imm_val < 0 and imm_val & 0x03 == 0': 0 + 'rs1_val < rs2_val and imm_val > 0 and imm_val & 0x03 == 0': 0 + 'rs1_val < rs2_val and imm_val < 0 and imm_val & 0x03 == 0': 0 + + bfmt_base_branch_val_align_unsgn: &bfmt_base_branch_val_align_unsgn + 'rs1_val > 0 and rs2_val > 0': 0 + 'rs1_val > 0 and rs2_val > 0 and rs1_val == rs2_val and imm_val > 0': 0 + 'rs1_val > 0 and rs2_val > 0 and rs1_val == rs2_val and imm_val < 0': 0 + 'rs1_val > 0 and rs2_val > 0 and rs1_val > rs2_val and imm_val > 0 ': 0 + 'rs1_val > 0 and rs2_val > 0 and rs1_val > rs2_val and imm_val < 0 ': 0 + 'rs1_val > 0 and rs2_val > 0 and rs1_val < rs2_val and imm_val > 0 ': 0 + 'rs1_val > 0 and rs2_val > 0 and rs1_val < rs2_val and imm_val < 0 ': 0 + + rs1val_walking: &rs1val_walking + 'walking_ones("rs1_val", xlen)': 0 + 'walking_zeros("rs1_val", xlen)': 0 + 'alternate("rs1_val",xlen)': 0 + + rs2val_walking: &rs2val_walking + 'walking_ones("rs2_val", xlen)': 0 + 'walking_zeros("rs2_val", xlen)': 0 + 'alternate("rs2_val",xlen)': 0 + + rs3val_walking: &rs3val_walking + 'walking_ones("rs3_val", xlen)': 0 + 'walking_zeros("rs3_val", xlen)': 0 + 'alternate("rs3_val",xlen)': 0 + + ifmt_immval_walking: &ifmt_immval_walking + 'walking_ones("imm_val", 12)': 0 + 'walking_zeros("imm_val", 12)': 0 + 'alternate("imm_val",12)': 0 + + rs1val_walking_unsgn: &rs1val_walking_unsgn + 'walking_ones("rs1_val", xlen,False)': 0 + 'walking_zeros("rs1_val", xlen,False)': 0 + 'alternate("rs1_val",xlen,False)': 0 + + rs2val_walking_unsgn: &rs2val_walking_unsgn + 'walking_ones("rs2_val", xlen,False)': 0 + 'walking_zeros("rs2_val", xlen,False)': 0 + 'alternate("rs2_val",xlen,False)': 0 + + crfmt_val_comb_sgn: &crfmt_val_comb_sgn + 'rs2_val > 0': 0 + 'rs2_val < 0': 0 + + cbimm_val_walking: &cbimm_val_walking + 'walking_ones("imm_val", 6)': 0 + 'walking_zeros("imm_val", 6)': 0 + 'alternate("imm_val",6)': 0 + + ifmt_immval_walking_unsgn: &ifmt_immval_walking_unsgn + 'walking_ones("imm_val", 12,False)': 0 + 'walking_zeros("imm_val", 12,False)': 0 + 'alternate("imm_val",12,False)': 0 + +ecall: + config: + - check ISA:=regex(.*I.*); def rvtest_mtrap_routine=True + opcode: + ecall: 0 + +ebreak: + config: + - check ISA:=regex(.*I.*); def rvtest_mtrap_routine=True + opcode: + ebreak: 0 + +fencei: + config: + - check ISA:=regex(.*I.*Zifencei.*) + opcode: + fence.i: 0 + +misalign-lh: + cond: check ISA:=regex(.*I.*Zicsr.*) + config: + - check ISA:=regex(.*I.*); check hw_data_misaligned_support:=True + - check ISA:=regex(.*I.*Zicsr.*); check hw_data_misaligned_support:=False; def rvtest_mtrap_routine=True + opcode: + lh: 0 + val_comb: + 'ea_align == 1': 0 + +misalign-lhu: + config: + - check ISA:=regex(.*I.*); check hw_data_misaligned_support:=True + - check ISA:=regex(.*I.*Zicsr.*); check hw_data_misaligned_support:=False; def rvtest_mtrap_routine=True + cond: check ISA:=regex(.*I.*Zicsr.*) + opcode: + lhu: 0 + val_comb: + 'ea_align == 1': 0 + +misalign-lwu: + config: + - check ISA:=regex(.*I.*); check hw_data_misaligned_support:=True + - check ISA:=regex(.*I.*Zicsr.*); check hw_data_misaligned_support:=False; def rvtest_mtrap_routine=True + cond: check ISA:=regex(.*64.*I.*Zicsr.*) + opcode: + lwu: 0 + val_comb: + 'ea_align == 1': 0 + 'ea_align == 2': 0 + 'ea_align == 3': 0 + +misalign-sd: + config: + - check ISA:=regex(.*I.*); check hw_data_misaligned_support:=True + - check ISA:=regex(.*I.*Zicsr.*); check hw_data_misaligned_support:=False; def rvtest_mtrap_routine=True + cond: check ISA:=regex(.*64.*I.*Zicsr.*) + opcode: + sd: 0 + val_comb: + 'ea_align == 1': 0 + 'ea_align == 2': 0 + 'ea_align == 3': 0 + 'ea_align == 4': 0 + 'ea_align == 5': 0 + 'ea_align == 6': 0 + 'ea_align == 7': 0 + +misalign-ld: + config: + - check ISA:=regex(.*I.*); check hw_data_misaligned_support:=True + - check ISA:=regex(.*I.*Zicsr.*); check hw_data_misaligned_support:=False; def rvtest_mtrap_routine=True + cond: check ISA:=regex(.*64.*I.*) + opcode: + ld: 0 + val_comb: + 'ea_align == 1': 0 + 'ea_align == 2': 0 + 'ea_align == 3': 0 + 'ea_align == 4': 0 + 'ea_align == 5': 0 + 'ea_align == 6': 0 + 'ea_align == 7': 0 + +misalign-lw: + config: + - check ISA:=regex(.*I.*); check hw_data_misaligned_support:=True + - check ISA:=regex(.*I.*Zicsr.*); check hw_data_misaligned_support:=False; def rvtest_mtrap_routine=True + cond: check ISA:=regex(.*I.*Zicsr.*) + opcode: + lw: 0 + val_comb: + 'ea_align == 1': 0 + 'ea_align == 2': 0 + 'ea_align == 3': 0 + +misalign-sh: + config: + - check ISA:=regex(.*I.*); check hw_data_misaligned_support:=True + - check ISA:=regex(.*I.*Zicsr.*); check hw_data_misaligned_support:=False; def rvtest_mtrap_routine=True + cond: check ISA:=regex(.*I.*Zicsr.*) + opcode: + sh: 0 + val_comb: + 'ea_align == 1': 0 + +misalign-sw: + config: + - check ISA:=regex(.*I.*); check hw_data_misaligned_support:=True + - check ISA:=regex(.*I.*Zicsr.*); check hw_data_misaligned_support:=False; def rvtest_mtrap_routine=True + cond: check ISA:=regex(.*I.*Zicsr.*) + opcode: + sw: 0 + val_comb: + 'ea_align == 1': 0 + 'ea_align == 2': 0 + 'ea_align == 3': 0 + +misalign2-jalr: + config: + - check ISA:=regex(.*I.*C.*) + - check ISA:=regex(.*I.*Zicsr.*); check ISA:=regex(^[^C]+$); def rvtest_mtrap_routine=True + cond: check ISA:=regex(.*I.*) + opcode: + jalr: 0 + val_comb: + 'ea_align == 2': 0 + +misalign1-jalr: + config: + - check ISA:=regex(.*I.*); def rvtest_mtrap_routine=True + opcode: + jalr: 0 + val_comb: + 'ea_align == 1': 0 + +misalign-jal: + config: + - check ISA:=regex(.*I.*C.*) + - check ISA:=regex(.*I.*Zicsr.*); check ISA:=regex(^[^C]+$); def rvtest_mtrap_routine=True + cond: check ISA:=regex(.*I.*) + opcode: + jal: 0 + val_comb: + 'ea_align == 2': 0 + +misalign-bge: + config: + - check ISA:=regex(.*I.*C.*) + - check ISA:=regex(.*I.*Zicsr.*); check ISA:=regex(^[^C]+$); def rvtest_mtrap_routine=True + cond: check ISA:=regex(.*I.*) + opcode: + bge: 0 + val_comb: + ' rs1_val>rs2_val and ea_align == 2': 0 + +misalign-bgeu: + config: + - check ISA:=regex(.*I.*C.*) + - check ISA:=regex(.*I.*Zicsr.*); check ISA:=regex(^[^C]+$); def rvtest_mtrap_routine=True + cond: check ISA:=regex(.*I.*) + opcode: + bgeu: 0 + val_comb: + ' rs1_val>rs2_val and ea_align == 2': 0 + +misalign-blt: + config: + - check ISA:=regex(.*I.*C.*) + - check ISA:=regex(.*I.*Zicsr.*); check ISA:=regex(^[^C]+$); def rvtest_mtrap_routine=True + cond: check ISA:=regex(.*I.*) + opcode: + blt: 0 + val_comb: + ' rs1_val 0' : 0 + 'imm_val == 1020': 0 + abstract_comb: + 'walking_ones("imm_val", 8,False,scale_func = lambda x: x*4)': 0 + 'walking_zeros("imm_val", 8,False,scale_func = lambda x: x*4)': 0 + 'alternate("imm_val",8,False,scale_func = lambda x: x*4)': 0 + +clw: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.lw: 0 + rs1: + <<: *c_regs + rd: + <<: *c_regs + op_comb: + 'rs1 == rd': 0 + 'rs1 != rd': 0 + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + abstract_comb: + 'walking_ones("imm_val",5,False, scale_func = lambda x: x*4)': 0 + 'walking_zeros("imm_val",5,False, scale_func = lambda x: x*4)': 0 + 'alternate("imm_val",5, False,scale_func = lambda x: x*4)': 0 + +cld: + config: + - check ISA:=regex(.*RV64.*I.*C.*) + opcode: + c.ld: 0 + rs1: + <<: *c_regs + rd: + <<: *c_regs + op_comb: + 'rs1 == rd': 0 + 'rs1 != rd': 0 + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + abstract_comb: + 'walking_ones("imm_val",5,False, scale_func = lambda x: x*8)': 0 + 'walking_zeros("imm_val",5,False, scale_func = lambda x: x*8)': 0 + 'alternate("imm_val",5, False,scale_func = lambda x: x*8)': 0 + +csw: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.sw: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + 'rs1 != rs2': 0 + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + <<: [ *base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + 'walking_ones("imm_val",5,False, scale_func = lambda x: x*4)': 0 + 'walking_zeros("imm_val",5,False, scale_func = lambda x: x*4)': 0 + 'alternate("imm_val",5, False,scale_func = lambda x: x*4)': 0 + +csd: + config: + - check ISA:=regex(.*RV64.*I.*C.*) + opcode: + c.sd: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + 'rs1 != rs2': 0 + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + <<: [ *base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + 'walking_ones("imm_val",5,False, scale_func = lambda x: x*8)': 0 + 'walking_zeros("imm_val",5,False, scale_func = lambda x: x*8)': 0 + 'alternate("imm_val",5, False,scale_func = lambda x: x*8)': 0 + +cnop: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.nop: 0 + val_comb: + abstract_comb: + <<: *cbimm_val_walking + +caddi: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.addi: 0 + rd: + <<: *all_regs_mx0 + val_comb: + <<: [*base_rs1val_sgn, *cbfmt_immval_sgn, *ifmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *cbimm_val_walking] + +cjal: + config: + - check ISA:=regex(.*RV32.*I.*C.*) + opcode: + c.jal: 0 + val_comb: + 'imm_val > 0': 0 + 'imm_val < 0': 0 + abstract_comb: + 'walking_ones("imm_val", 11,fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030),scale_func = lambda x: x*2)': 0 + 'walking_zeros("imm_val", 11,fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030),scale_func = lambda x: x*2)': 0 + 'alternate("imm_val",11, fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030) ,scale_func = lambda x: x*2)': 0 + +caddiw: + config: + - check ISA:=regex(.*RV64.*I.*C.*) + opcode: + c.addiw: 0 + rd: + <<: *all_regs_mx0 + val_comb: + 'rs1_val == (-2**(xlen-1))': 0 + 'rs1_val == 0': 0 + 'rs1_val == (2**(xlen-1)-1)': 0 + 'rs1_val == 1': 0 + <<: [*cbfmt_immval_sgn, *ifmt_val_comb_sgn] + abstract_comb: + 'walking_ones("rs1_val", xlen)': 0 + 'walking_zeros("rs1_val", xlen)': 0 + 'alternate("rs1_val",xlen)': 0 + <<: [*cbimm_val_walking] + +cli: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.li: 0 + rd: + <<: *all_regs + val_comb: + <<: [*cbfmt_immval_sgn] + abstract_comb: + 'walking_ones("imm_val", 6)': 0 + 'walking_zeros("imm_val", 6)': 0 + 'alternate("imm_val", 6)': 0 + +caddi16sp: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.addi16sp: 0 + rd: + x2: 0 + val_comb: + <<: [*base_rs1val_sgn,*ifmt_val_comb_sgn] + 'imm_val == -512': 0 + 'imm_val == 496': 0 + abstract_comb: + <<: [*rs1val_walking] + 'walking_ones("imm_val", 6,True,scale_func = lambda x: x*16)': 0 + 'walking_zeros("imm_val", 6,True,scale_func = lambda x: x*16)': 0 + 'alternate("imm_val",6,True,scale_func = lambda x: x*16)': 0 + +clui: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.lui: 0 + rd: + x0: 0 + x1: 0 + x3: 0 + x4: 0 + x5: 0 + x6: 0 + x7: 0 + x8: 0 + x9: 0 + x10: 0 + x11: 0 + x12: 0 + x13: 0 + x14: 0 + x15: 0 + x16: 0 + x17: 0 + x18: 0 + x19: 0 + x20: 0 + x21: 0 + x22: 0 + x23: 0 + x24: 0 + x25: 0 + x26: 0 + x27: 0 + x28: 0 + x29: 0 + x30: 0 + x31: 0 + + val_comb: + 'rs1_val > 0 and imm_val > 32': 0 + 'rs1_val > 0 and imm_val < 32 and imm_val !=0 ': 0 + 'rs1_val < 0 and imm_val > 32': 0 + 'rs1_val < 0 and imm_val < 32 and imm_val !=0 ': 0 + abstract_comb: + 'walking_ones("imm_val", 6, False)': 0 + 'walking_zeros("imm_val", 6, False)': 0 + 'alternate("imm_val", 6, False)': 0 + +csrli: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.srli: 0 + rs1: + <<: *c_regs + val_comb: + 'rs1_val < 0 and imm_val < xlen': 0 + 'rs1_val > 0 and imm_val < xlen': 0 + 'rs1_val == imm_val and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == (-2**(xlen-1)) and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == 0 and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == (2**(xlen-1)-1) and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == 1 and imm_val != 0 and imm_val < xlen': 0 + abstract_comb: + <<: [*rs1val_walking] + 'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0 + 'alternate("imm_val", ceil(log(xlen,2)), False)': 0 + +csrai: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.srai: 0 + rs1: + <<: *c_regs + val_comb: + 'rs1_val < 0 and imm_val < xlen': 0 + 'rs1_val > 0 and imm_val < xlen': 0 + 'rs1_val == imm_val and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == (-2**(xlen-1)) and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == 0 and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == (2**(xlen-1)-1) and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == 1 and imm_val != 0 and imm_val < xlen': 0 + abstract_comb: + <<: [*rs1val_walking] + 'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0 + 'alternate("imm_val", ceil(log(xlen,2)), False)': 0 + +candi: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.andi: 0 + rs1: + <<: *c_regs + val_comb: + <<: [*base_rs1val_sgn,*cbfmt_immval_sgn,*ifmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *cbimm_val_walking] + +csub: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.sub: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*crfmt_val_comb_sgn, *base_rs1val_sgn, *base_rs2val_sgn] + abstract_comb: + <<: [*rs1val_walking,*rs2val_walking] + +cxor: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.xor: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*crfmt_val_comb_sgn, *base_rs1val_sgn, *base_rs2val_sgn] + abstract_comb: + <<: [*rs1val_walking,*rs2val_walking] + +cor: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.or: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*crfmt_val_comb_sgn, *base_rs1val_sgn,*base_rs2val_sgn] + abstract_comb: + <<: [*rs1val_walking,*rs2val_walking] + +cand: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.and: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*crfmt_val_comb_sgn, *base_rs1val_sgn,*base_rs2val_sgn] + abstract_comb: + <<: [*rs1val_walking,*rs2val_walking] + +csubw: + config: + - check ISA:=regex(.*RV64.*I.*C.*) + opcode: + c.subw: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*crfmt_val_comb_sgn, *base_rs1val_sgn, *base_rs2val_sgn] + abstract_comb: + <<: [*rs1val_walking,*rs2val_walking] + +caddw: + config: + - check ISA:=regex(.*RV64.*I.*C.*) + opcode: + c.addw: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*crfmt_val_comb_sgn, *base_rs1val_sgn, *base_rs2val_sgn] + abstract_comb: + <<: [*rs1val_walking,*rs2val_walking] + +cj: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.j: 0 + val_comb: + 'imm_val > 0': 0 + 'imm_val < 0': 0 + abstract_comb: + 'walking_ones("imm_val", 11,fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030),scale_func = lambda x: x*2)': 0 + 'walking_zeros("imm_val", 11,fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030),scale_func = lambda x: x*2)': 0 + 'alternate("imm_val",11, fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030) ,scale_func = lambda x: x*2)': 0 + +cbeqz: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.beqz: 0 + rs1: + <<: *c_regs + val_comb: + 'rs1_val > 0 and imm_val > 0': 0 + 'rs1_val < 0 and imm_val > 0': 0 + 'rs1_val == 0 and imm_val > 0': 0 + 'rs1_val > 0 and imm_val < 0': 0 + 'rs1_val < 0 and imm_val < 0': 0 + 'rs1_val == 0 and imm_val < 0': 0 + <<: [*base_rs1val_sgn] + abstract_comb: + <<: [*rs1val_walking] + +cbnez: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.bnez: 0 + rs1: + <<: *c_regs + val_comb: + 'rs1_val > 0 and imm_val > 0': 0 + 'rs1_val < 0 and imm_val > 0': 0 + 'rs1_val == 0 and imm_val > 0': 0 + 'rs1_val > 0 and imm_val < 0': 0 + 'rs1_val < 0 and imm_val < 0': 0 + 'rs1_val == 0 and imm_val < 0': 0 + <<: [*base_rs1val_sgn] + abstract_comb: + <<: [*rs1val_walking] + +cslli: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.slli: 0 + rd: + <<: *c_regs + val_comb: + 'rs1_val < 0 and imm_val < xlen': 0 + 'rs1_val > 0 and imm_val < xlen': 0 + 'rs1_val == imm_val and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == (-2**(xlen-1)) and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == 0 and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == (2**(xlen-1)-1) and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == 1 and imm_val != 0 and imm_val < xlen': 0 + abstract_comb: + <<: [*rs1val_walking] + 'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0 + 'alternate("imm_val", ceil(log(xlen,2)), False)': 0 + +clwsp: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.lwsp: 0 + rd: + <<: *all_regs_mx0 + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + abstract_comb: + 'walking_ones("imm_val",6,False, scale_func = lambda x: x*4)': 0 + 'walking_zeros("imm_val",6,False, scale_func = lambda x: x*4)': 0 + 'alternate("imm_val",6, False,scale_func = lambda x: x*4)': 0 + +cldsp: + config: + - check ISA:=regex(.*RV64.*I.*C.*) + opcode: + c.ldsp: 0 + rd: + <<: *all_regs_mx0 + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + abstract_comb: + 'walking_ones("imm_val",6,False, scale_func = lambda x: x*8)': 0 + 'walking_zeros("imm_val",6,False, scale_func = lambda x: x*8)': 0 + 'alternate("imm_val",6, False,scale_func = lambda x: x*8)': 0 + +cjr: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.jr: 0 + rs1: + <<: *all_regs_mx0 + +cmv: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.mv: 0 + rs2: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + 'rs2 == rd and rs2 != 0': 0 + 'rs2 != rd and rs2 != 0': 0 + val_comb: + <<: [*base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +cadd: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.add: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs_mx0 + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*crfmt_val_comb_sgn, *base_rs1val_sgn,*base_rs2val_sgn] + abstract_comb: + <<: [*rs1val_walking,*rs2val_walking] + +cjalr: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.jalr: 0 + rs1: + <<: *all_regs_mx0 + +cswsp: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.swsp: 0 + rs2: + <<: *all_regs + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + <<: [ *base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + 'walking_ones("imm_val",6,False, scale_func = lambda x: x*4)': 0 + 'walking_zeros("imm_val",6,False, scale_func = lambda x: x*4)': 0 + 'alternate("imm_val",6, False,scale_func = lambda x: x*4)': 0 + +csdsp: + config: + - check ISA:=regex(.*RV64.*I.*C.*) + opcode: + c.sdsp: 0 + rs2: + <<: *all_regs + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + <<: [ *base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + 'walking_ones("imm_val",6,False, scale_func = lambda x: x*8)': 0 + 'walking_zeros("imm_val",6,False, scale_func = lambda x: x*8)': 0 + 'alternate("imm_val",6, False,scale_func = lambda x: x*8)': 0 + +addi: + config: + - check ISA:=regex(.*I.*) + opcode: + addi: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [ *ifmt_val_comb_sgn, *base_rs1val_sgn, *ifmt_base_immval_sgn] + abstract_comb: + <<: [*rs1val_walking, *ifmt_immval_walking] + +slti: + config: + - check ISA:=regex(.*I.*) + opcode: + slti: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [*ifmt_val_comb_sgn , *base_rs1val_sgn , *ifmt_base_immval_sgn] + abstract_comb: + <<: [*rs1val_walking, *ifmt_immval_walking] + +sltiu: + config: + - check ISA:=regex(.*I.*) + opcode: + sltiu: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [*ifmt_val_comb_unsgn , *base_rs1val_unsgn , *ifmt_base_immval_unsgn] + abstract_comb: + <<: [*rs1val_walking_unsgn, *ifmt_immval_walking_unsgn] + +andi: + config: + - check ISA:=regex(.*I.*) + opcode: + andi: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [*ifmt_val_comb_sgn , *base_rs1val_sgn , *ifmt_base_immval_sgn] + abstract_comb: + <<: [*rs1val_walking, *ifmt_immval_walking] + +ori: + config: + - check ISA:=regex(.*I.*) + opcode: + ori: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [*ifmt_val_comb_sgn , *base_rs1val_sgn , *ifmt_base_immval_sgn] + abstract_comb: + <<: [*rs1val_walking, *ifmt_immval_walking] + +xori: + config: + - check ISA:=regex(.*I.*) + opcode: + xori: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [*ifmt_val_comb_sgn , *base_rs1val_sgn , *ifmt_base_immval_sgn] + abstract_comb: + <<: [*rs1val_walking, *ifmt_immval_walking] + +slli: + config: + - check ISA:=regex(.*I.*) + opcode: + slli: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: *ifmt_base_shift + abstract_comb: + <<: [*rs1val_walking] + 'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0 + 'alternate("imm_val", ceil(log(xlen,2)), False)': 0 + +srai: + config: + - check ISA:=regex(.*I.*) + opcode: + srai: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: *ifmt_base_shift + abstract_comb: + <<: [*rs1val_walking] + 'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0 + 'alternate("imm_val", ceil(log(xlen,2)), False)': 0 + +srli: + config: + - check ISA:=regex(.*I.*) + opcode: + srli: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: *ifmt_base_shift + abstract_comb: + <<: [*rs1val_walking] + 'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0 + 'alternate("imm_val", ceil(log(xlen,2)), False)': 0 + +add: + config: + - check ISA:=regex(.*I.*) + opcode: + add: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +sub: + config: + - check ISA:=regex(.*I.*) + opcode: + sub: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +slt: + config: + - check ISA:=regex(.*I.*) + opcode: + slt: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +sltu: + config: + - check ISA:=regex(.*I.*) + opcode: + sltu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + +and: + config: + - check ISA:=regex(.*I.*) + opcode: + and: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +or: + config: + - check ISA:=regex(.*I.*) + opcode: + or: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +xor: + config: + - check ISA:=regex(.*I.*) + opcode: + xor: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +sll: + config: + - check ISA:=regex(.*I.*) + opcode: + sll: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: *rfmt_base_shift + abstract_comb: + <<: [*rs1val_walking] + 'walking_ones("rs2_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("rs2_val", ceil(log(xlen,2)), False)': 0 + 'alternate("rs2_val", ceil(log(xlen,2)), False)': 0 + +srl: + config: + - check ISA:=regex(.*I.*) + opcode: + srl: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: *rfmt_base_shift + abstract_comb: + <<: [*rs1val_walking] + 'walking_ones("rs2_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("rs2_val", ceil(log(xlen,2)), False)': 0 + 'alternate("rs2_val", ceil(log(xlen,2)), False)': 0 + +sra: + config: + - check ISA:=regex(.*I.*) + opcode: + sra: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: *rfmt_base_shift + abstract_comb: + <<: [*rs1val_walking] + 'walking_ones("rs2_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("rs2_val", ceil(log(xlen,2)), False)': 0 + 'alternate("rs2_val", ceil(log(xlen,2)), False)': 0 + +beq: + config: + - check ISA:=regex(.*I.*) + opcode: + beq: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *bfmt_base_branch_val_align_sgn + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +bge: + config: + - check ISA:=regex(.*I.*) + opcode: + bge: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *bfmt_base_branch_val_align_sgn + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +bgeu: + config: + - check ISA:=regex(.*I.*) + opcode: + bgeu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *bfmt_base_branch_val_align_unsgn + abstract_comb: + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + +blt: + config: + - check ISA:=regex(.*I.*) + opcode: + blt: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *bfmt_base_branch_val_align_sgn + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +bltu: + config: + - check ISA:=regex(.*I.*) + opcode: + bltu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *bfmt_base_branch_val_align_unsgn + abstract_comb: + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + +bne: + config: + - check ISA:=regex(.*I.*) + opcode: + bne: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *bfmt_base_branch_val_align_sgn + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +lhu-align: + config: + - check ISA:=regex(.*I.*) + opcode: + lhu: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'ea_align == 2 and (imm_val % 4) == 0': 0 + 'ea_align == 2 and (imm_val % 4) == 1': 0 + 'ea_align == 2 and (imm_val % 4) == 2': 0 + 'ea_align == 2 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + +lh-align: + config: + - check ISA:=regex(.*I.*) + opcode: + lh: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'ea_align == 2 and (imm_val % 4) == 0': 0 + 'ea_align == 2 and (imm_val % 4) == 1': 0 + 'ea_align == 2 and (imm_val % 4) == 2': 0 + 'ea_align == 2 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + +lbu-align: + config: + - check ISA:=regex(.*I.*) + opcode: + lbu: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'ea_align == 2 and (imm_val % 4) == 0': 0 + 'ea_align == 2 and (imm_val % 4) == 1': 0 + 'ea_align == 2 and (imm_val % 4) == 2': 0 + 'ea_align == 2 and (imm_val % 4) == 3': 0 + 'ea_align == 1 and (imm_val % 4) == 0': 0 + 'ea_align == 1 and (imm_val % 4) == 1': 0 + 'ea_align == 1 and (imm_val % 4) == 2': 0 + 'ea_align == 1 and (imm_val % 4) == 3': 0 + 'ea_align == 3 and (imm_val % 4) == 0': 0 + 'ea_align == 3 and (imm_val % 4) == 1': 0 + 'ea_align == 3 and (imm_val % 4) == 2': 0 + 'ea_align == 3 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + +lb-align: + config: + - check ISA:=regex(.*I.*) + opcode: + lb: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'ea_align == 2 and (imm_val % 4) == 0': 0 + 'ea_align == 2 and (imm_val % 4) == 1': 0 + 'ea_align == 2 and (imm_val % 4) == 2': 0 + 'ea_align == 2 and (imm_val % 4) == 3': 0 + 'ea_align == 1 and (imm_val % 4) == 0': 0 + 'ea_align == 1 and (imm_val % 4) == 1': 0 + 'ea_align == 1 and (imm_val % 4) == 2': 0 + 'ea_align == 1 and (imm_val % 4) == 3': 0 + 'ea_align == 3 and (imm_val % 4) == 0': 0 + 'ea_align == 3 and (imm_val % 4) == 1': 0 + 'ea_align == 3 and (imm_val % 4) == 2': 0 + 'ea_align == 3 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + +lw-align: + config: + - check ISA:=regex(.*I.*) + opcode: + lw: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + + +sh-align: + config: + - check ISA:=regex(.*I.*) + opcode: + sh: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + op_comb: + 'rs1 != rs2': 0 + val_comb: + <<: [ *base_rs2val_sgn] + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'ea_align == 2 and (imm_val % 4) == 0': 0 + 'ea_align == 2 and (imm_val % 4) == 1': 0 + 'ea_align == 2 and (imm_val % 4) == 2': 0 + 'ea_align == 2 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + abstract_comb: + <<: [*rs2val_walking] + +sb-align: + config: + - check ISA:=regex(.*I.*) + opcode: + sb: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + op_comb: + 'rs1 != rs2': 0 + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'ea_align == 2 and (imm_val % 4) == 0': 0 + 'ea_align == 2 and (imm_val % 4) == 1': 0 + 'ea_align == 2 and (imm_val % 4) == 2': 0 + 'ea_align == 2 and (imm_val % 4) == 3': 0 + 'ea_align == 1 and (imm_val % 4) == 0': 0 + 'ea_align == 1 and (imm_val % 4) == 1': 0 + 'ea_align == 1 and (imm_val % 4) == 2': 0 + 'ea_align == 1 and (imm_val % 4) == 3': 0 + 'ea_align == 3 and (imm_val % 4) == 0': 0 + 'ea_align == 3 and (imm_val % 4) == 1': 0 + 'ea_align == 3 and (imm_val % 4) == 2': 0 + 'ea_align == 3 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + <<: [ *base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +sw-align: + config: + - check ISA:=regex(.*I.*) + opcode: + sw: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + op_comb: + 'rs1 != rs2': 0 + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + <<: [ *base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +auipc: + config: + - check ISA:=regex(.*I.*) + opcode: + auipc: 0 + rd: + <<: *all_regs + val_comb: + 'imm_val == 0': 0 + 'imm_val > 0': 0 + 'imm_val == ((2**20)-1)': 0 + +lui: + config: + - check ISA:=regex(.*I.*) + opcode: + lui: 0 + rd: + <<: *all_regs + val_comb: + 'imm_val == 0': 0 + 'imm_val > 0': 0 + 'imm_val == ((2**20)-1)': 0 + +jal: + config: + - check ISA:=regex(.*I.*) + opcode: + jal: 0 + rd: + <<: *all_regs + val_comb: + 'imm_val < 0' : 0 + 'imm_val > 0': 0 + 'imm_val == (-(2**(18)))': 0 + 'imm_val == ((2**(18)))': 0 + +jalr: + config: + - check ISA:=regex(.*I.*) + opcode: + jalr: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'imm_val > 0': 0 + 'imm_val < 0': 0 + abstract_comb: + <<: *ifmt_immval_walking + +mul: + config: + - check ISA:=regex(.*I.*M.*) + opcode: + mul: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +mulh: + config: + - check ISA:=regex(.*I.*M.*) + opcode: + mulh: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +mulhu: + config: + - check ISA:=regex(.*I.*M.*) + opcode: + mulhu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +mulhsu: + config: + - check ISA:=regex(.*I.*M.*) + opcode: + mulhsu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +div: + config: + - check ISA:=regex(.*I.*M.*) + opcode: + div: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +divu: + config: + - check ISA:=regex(.*I.*M.*) + opcode: + divu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +rem: + config: + - check ISA:=regex(.*I.*M.*) + opcode: + rem: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +remu: + config: + - check ISA:=regex(.*I.*M.*) + opcode: + remu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +lwu-align: + config: + - check ISA:=regex(.*RV64.*I.*) + opcode: + lwu: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + +ld-align: + config: + - check ISA:=regex(.*RV64.*I.*) + opcode: + ld: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'ea_align == 0 and (imm_val % 8) == 0': 0 + 'ea_align == 0 and (imm_val % 8) == 1': 0 + 'ea_align == 0 and (imm_val % 8) == 2': 0 + 'ea_align == 0 and (imm_val % 8) == 3': 0 + 'ea_align == 0 and (imm_val % 8) == 4': 0 + 'ea_align == 0 and (imm_val % 8) == 5': 0 + 'ea_align == 0 and (imm_val % 8) == 6': 0 + 'ea_align == 0 and (imm_val % 8) == 7': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + +sd-align: + config: + - check ISA:=regex(.*RV64.*I.*) + opcode: + sd: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + op_comb: + 'rs1 != rs2': 0 + val_comb: + 'ea_align == 0 and (imm_val % 8) == 0': 0 + 'ea_align == 0 and (imm_val % 8) == 1': 0 + 'ea_align == 0 and (imm_val % 8) == 2': 0 + 'ea_align == 0 and (imm_val % 8) == 3': 0 + 'ea_align == 0 and (imm_val % 8) == 4': 0 + 'ea_align == 0 and (imm_val % 8) == 5': 0 + 'ea_align == 0 and (imm_val % 8) == 6': 0 + 'ea_align == 0 and (imm_val % 8) == 7': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + <<: [ *base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +addiw: + config: + - check ISA:=regex(.*RV64.*I.*) + opcode: + addiw: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [ *ifmt_val_comb_sgn, *base_rs1val_sgn, *ifmt_base_immval_sgn] + abstract_comb: + <<: [*rs1val_walking, *ifmt_immval_walking] + +slliw: + config: + - check ISA:=regex(.*RV64.*I.*) + opcode: + slliw: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: *ifmt_base_shift_32w + abstract_comb: + <<: [*rs1val_walking] + 'walking_ones("imm_val", 5, False)': 0 + 'walking_zeros("imm_val", 5, False)': 0 + 'alternate("imm_val", 5, False)': 0 + +srliw: + config: + - check ISA:=regex(.*RV64.*I.*) + opcode: + srliw: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: *ifmt_base_shift_32w + abstract_comb: + <<: [*rs1val_walking] + 'walking_ones("imm_val", 5, False)': 0 + 'walking_zeros("imm_val", 5, False)': 0 + 'alternate("imm_val", 5, False)': 0 + +sraiw: + config: + - check ISA:=regex(.*RV64.*I.*) + opcode: + sraiw: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: *ifmt_base_shift_32w + abstract_comb: + <<: [*rs1val_walking] + 'walking_ones("imm_val", 5, False)': 0 + 'walking_zeros("imm_val", 5, False)': 0 + 'alternate("imm_val", 5, False)': 0 + +addw: + config: + - check ISA:=regex(.*RV64.*I.*) + opcode: + addw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +subw: + config: + - check ISA:=regex(.*RV64.*I.*) + opcode: + subw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +sllw: + config: + - check ISA:=regex(.*RV64.*I.*) + opcode: + sllw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: *rfmt_base_shift + abstract_comb: + <<: [*rs1val_walking] + 'walking_ones("rs2_val", 5, False)': 0 + 'walking_zeros("rs2_val", 5, False)': 0 + 'alternate("rs2_val", 5, False)': 0 + +srlw: + config: + - check ISA:=regex(.*RV64.*I.*) + opcode: + srlw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: *rfmt_base_shift + abstract_comb: + <<: [*rs1val_walking] + 'walking_ones("rs2_val", 5, False)': 0 + 'walking_zeros("rs2_val", 5, False)': 0 + 'alternate("rs2_val", 5, False)': 0 +sraw: + config: + - check ISA:=regex(.*RV64.*I.*) + opcode: + sraw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: *rfmt_base_shift + abstract_comb: + <<: [*rs1val_walking] + 'walking_ones("rs2_val", 5, False)': 0 + 'walking_zeros("rs2_val", 5, False)': 0 + 'alternate("rs2_val", 5, False)': 0 + +mulw: + config: + - check ISA:=regex(.*RV64.*I.*M.*) + opcode: + mulw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +divw: + config: + - check ISA:=regex(.*RV64.*I.*M.*) + opcode: + divw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +divuw: + config: + - check ISA:=regex(.*RV64.*I.*M.*) + opcode: + divuw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +remw: + config: + - check ISA:=regex(.*RV64.*I.*M.*) + opcode: + remw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +remuw: + config: + - check ISA:=regex(.*RV64.*I.*M.*) + opcode: + remuw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + diff --git a/coverage/cgfs_fext/RV32D/fadd.d.cgf b/coverage/cgfs_fext/RV32D/fadd.d.cgf new file mode 100644 index 000000000..fd1092a36 --- /dev/null +++ b/coverage/cgfs_fext/RV32D/fadd.d.cgf @@ -0,0 +1,188 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fadd.d_b1: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fadd.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,64, "fadd.d", 2)': 0 + +fadd.d_b2: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fadd.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b2(flen,64, "fadd.d", 2)': 0 + +fadd.d_b3: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fadd.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b3(flen,64, "fadd.d", 2)': 0 + +fadd.d_b4: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fadd.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b4(flen,64, "fadd.d", 2)': 0 + +fadd.d_b5: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fadd.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b5(flen,64, "fadd.d", 2)': 0 + +fadd.d_b7: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fadd.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b7(flen,64, "fadd.d", 2)': 0 + +fadd.d_b8: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fadd.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b8(flen,64, "fadd.d", 2)': 0 + +fadd.d_b10: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fadd.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b10(flen,64, "fadd.d", 2)': 0 + +fadd.d_b11: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fadd.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b11(flen,64, "fadd.d", 2)': 0 + +fadd.d_b12: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fadd.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b12(flen,64, "fadd.d", 2)': 0 + +fadd.d_b13: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fadd.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b13(flen,64, "fadd.d", 2)': 0 diff --git a/coverage/cgfs_fext/RV32D/fclass.d.cgf b/coverage/cgfs_fext/RV32D/fclass.d.cgf new file mode 100644 index 000000000..a400d6d81 --- /dev/null +++ b/coverage/cgfs_fext/RV32D/fclass.d.cgf @@ -0,0 +1,15 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fclass.d_b1: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fclass.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b1(flen,64, "fclass.d", 1)': 0 + diff --git a/coverage/cgfs_fext/RV32D/fcvt.d.s.cgf b/coverage/cgfs_fext/RV32D/fcvt.d.s.cgf new file mode 100644 index 000000000..def774ab4 --- /dev/null +++ b/coverage/cgfs_fext/RV32D/fcvt.d.s.cgf @@ -0,0 +1,106 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fcvt.d.s_b1: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fcvt.d.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fcvt.d.s", 1)': 0 + +fcvt.d.s_b22: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fcvt.d.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b22(flen,32, "fcvt.d.s", 1)': 0 + +fcvt.d.s_b23: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fcvt.d.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b23(flen,32, "fcvt.d.s", 1)': 0 + +fcvt.d.s_b24: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fcvt.d.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b24(flen,32, "fcvt.d.s", 1)': 0 + +fcvt.d.s_b27: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fcvt.d.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b27(flen,32, "fcvt.d.s", 1)': 0 + +fcvt.d.s_b28: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fcvt.d.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b28(flen,32, "fcvt.d.s", 1)': 0 + +fcvt.d.s_b29: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fcvt.d.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b29(flen,32, "fcvt.d.s", 1)': 0 diff --git a/coverage/cgfs_fext/RV32D/fcvt.d.w.cgf b/coverage/cgfs_fext/RV32D/fcvt.d.w.cgf new file mode 100644 index 000000000..2dcf295fb --- /dev/null +++ b/coverage/cgfs_fext/RV32D/fcvt.d.w.cgf @@ -0,0 +1,28 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fcvt.d.w_b25: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fcvt.d.w: 0 + rs1: + <<: *all_regs + rd: + <<: *all_fregs + val_comb: + abstract_comb: + 'ibm_b25(flen,32, "fcvt.d.w", 1)': 0 + +fcvt.d.w_b26: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fcvt.d.w: 0 + rs1: + <<: *all_regs + rd: + <<: *all_fregs + val_comb: + abstract_comb: + 'ibm_b26(32, "fcvt.d.w", 1)': 0 + diff --git a/coverage/cgfs_fext/RV32D/fcvt.d.wu.cgf b/coverage/cgfs_fext/RV32D/fcvt.d.wu.cgf new file mode 100644 index 000000000..0f9ed15c3 --- /dev/null +++ b/coverage/cgfs_fext/RV32D/fcvt.d.wu.cgf @@ -0,0 +1,28 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fcvt.d.wu_b25: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fcvt.d.wu: 0 + rs1: + <<: *all_regs + rd: + <<: *all_fregs + val_comb: + abstract_comb: + 'ibm_b25(flen,32, "fcvt.d.wu", 1)': 0 + +fcvt.d.wu_b26: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fcvt.d.wu: 0 + rs1: + <<: *all_regs + rd: + <<: *all_fregs + val_comb: + abstract_comb: + 'ibm_b26(32, "fcvt.d.wu", 1)': 0 + diff --git a/coverage/cgfs_fext/RV32D/fcvt.s.d.cgf b/coverage/cgfs_fext/RV32D/fcvt.s.d.cgf new file mode 100644 index 000000000..9d87ab7b9 --- /dev/null +++ b/coverage/cgfs_fext/RV32D/fcvt.s.d.cgf @@ -0,0 +1,106 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fcvt.s.d_b1: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fcvt.s.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,64, "fcvt.s.d", 1)': 0 + +fcvt.s.d_b22: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fcvt.s.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b22(flen,64, "fcvt.s.d", 1)': 0 + +fcvt.s.d_b23: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fcvt.s.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b23(flen,64, "fcvt.s.d", 1)': 0 + +fcvt.s.d_b24: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fcvt.s.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b24(flen,64, "fcvt.s.d", 1)': 0 + +fcvt.s.d_b27: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fcvt.s.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b27(flen,64, "fcvt.s.d", 1)': 0 + +fcvt.s.d_b28: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fcvt.s.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b28(flen,64, "fcvt.s.d", 1)': 0 + +fcvt.s.d_b29: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fcvt.s.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b29(flen,64, "fcvt.s.d", 1)': 0 diff --git a/coverage/cgfs_fext/RV32D/fcvt.w.d.cgf b/coverage/cgfs_fext/RV32D/fcvt.w.d.cgf new file mode 100644 index 000000000..dc81adfa9 --- /dev/null +++ b/coverage/cgfs_fext/RV32D/fcvt.w.d.cgf @@ -0,0 +1,92 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fcvt.w.d_b1: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fcvt.w.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b1(flen,64, "fcvt.w.d", 1)': 0 + +fcvt.w.d_b22: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fcvt.w.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b22(flen,64, "fcvt.w.d", 1)': 0 + +fcvt.w.d_b23: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fcvt.w.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b23(flen,64, "fcvt.w.d", 1)': 0 + +fcvt.w.d_b24: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fcvt.w.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b24(flen,64, "fcvt.w.d", 1)': 0 + +fcvt.w.d_b27: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fcvt.w.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b27(flen,64, "fcvt.w.d", 1)': 0 + +fcvt.w.d_b28: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fcvt.w.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b28(flen,64, "fcvt.w.d", 1)': 0 + +fcvt.w.d_b29: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fcvt.w.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b29(flen,64, "fcvt.w.d", 1)': 0 diff --git a/coverage/cgfs_fext/RV32D/fcvt.wu.d.cgf b/coverage/cgfs_fext/RV32D/fcvt.wu.d.cgf new file mode 100644 index 000000000..dacb2e398 --- /dev/null +++ b/coverage/cgfs_fext/RV32D/fcvt.wu.d.cgf @@ -0,0 +1,92 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fcvt.wu.d_b1: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fcvt.wu.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b1(flen,64, "fcvt.wu.d", 1)': 0 + +fcvt.wu.d_b22: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fcvt.wu.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b22(flen,64, "fcvt.wu.d", 1)': 0 + +fcvt.wu.d_b23: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fcvt.wu.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b23(flen,64, "fcvt.wu.d", 1)': 0 + +fcvt.wu.d_b24: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fcvt.wu.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b24(flen,64, "fcvt.wu.d", 1)': 0 + +fcvt.wu.d_b27: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fcvt.wu.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b27(flen,64, "fcvt.wu.d", 1)': 0 + +fcvt.wu.d_b28: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fcvt.wu.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b28(flen,64, "fcvt.wu.d", 1)': 0 + +fcvt.wu.d_b29: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fcvt.wu.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b29(flen,64, "fcvt.wu.d", 1)': 0 diff --git a/coverage/cgfs_fext/RV32D/fdiv.d.cgf b/coverage/cgfs_fext/RV32D/fdiv.d.cgf new file mode 100644 index 000000000..d1e37d833 --- /dev/null +++ b/coverage/cgfs_fext/RV32D/fdiv.d.cgf @@ -0,0 +1,188 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fdiv.d_b1: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fdiv.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,64, "fdiv.d", 2)': 0 + +fdiv.d_b2: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fdiv.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b2(flen,64, "fdiv.d", 2)': 0 + +fdiv.d_b3: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fdiv.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b3(flen,64, "fdiv.d", 2)': 0 + +fdiv.d_b4: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fdiv.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b4(flen,64, "fdiv.d", 2)': 0 + +fdiv.d_b5: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fdiv.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b5(flen,64, "fdiv.d", 2)': 0 + +fdiv.d_b6: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fdiv.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b6(flen,64, "fdiv.d", 2)': 0 + +fdiv.d_b7: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fdiv.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b7(flen,64, "fdiv.d", 2)': 0 + +fdiv.d_b8: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fdiv.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b8(flen,64, "fdiv.d", 2)': 0 + +fdiv.d_b9: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fdiv.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b9(flen,64, "fdiv.d", 2)': 0 + +fdiv.d_b20: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fdiv.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b20(flen,64, "fdiv.d", 2)': 0 + +fdiv.d_b21: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fdiv.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b21(flen,64, "fdiv.d", 2)': 0 diff --git a/coverage/cgfs_fext/RV32D/feq.d.cgf b/coverage/cgfs_fext/RV32D/feq.d.cgf new file mode 100644 index 000000000..9d86e46f6 --- /dev/null +++ b/coverage/cgfs_fext/RV32D/feq.d.cgf @@ -0,0 +1,35 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +feq.d_b1: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + feq.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,64, "feq.d", 2)': 0 + +feq.d_b19: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + feq.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b19(flen,64, "feq.d", 2)': 0 diff --git a/coverage/cgfs_fext/RV32D/fld-align.cgf b/coverage/cgfs_fext/RV32D/fld-align.cgf new file mode 100644 index 000000000..8ddbe6339 --- /dev/null +++ b/coverage/cgfs_fext/RV32D/fld-align.cgf @@ -0,0 +1,23 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fld-align: + config: + - check ISA:=regex(.*D.*) + mnemonics: + fld: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_fregs + val_comb: + 'ea_align == 0 and (imm_val % 8) == 0 and fcsr == 0': 0 + 'ea_align == 0 and (imm_val % 8) == 1 and fcsr == 0': 0 + 'ea_align == 0 and (imm_val % 8) == 2 and fcsr == 0': 0 + 'ea_align == 0 and (imm_val % 8) == 3 and fcsr == 0': 0 + 'ea_align == 0 and (imm_val % 8) == 4 and fcsr == 0': 0 + 'ea_align == 0 and (imm_val % 8) == 5 and fcsr == 0': 0 + 'ea_align == 0 and (imm_val % 8) == 6 and fcsr == 0': 0 + 'ea_align == 0 and (imm_val % 8) == 7 and fcsr == 0': 0 + 'imm_val > 0 and fcsr == 0': 0 + 'imm_val < 0 and fcsr == 0': 0 + 'imm_val == 0 and fcsr == 0': 0 diff --git a/coverage/cgfs_fext/RV32D/fle.d.cgf b/coverage/cgfs_fext/RV32D/fle.d.cgf new file mode 100644 index 000000000..d5a6e7642 --- /dev/null +++ b/coverage/cgfs_fext/RV32D/fle.d.cgf @@ -0,0 +1,35 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fle.d_b1: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fle.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,64, "fle.d", 2)': 0 + +fle.d_b19: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fle.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b19(flen,64, "fle.d", 2)': 0 diff --git a/coverage/cgfs_fext/RV32D/flt.d.cgf b/coverage/cgfs_fext/RV32D/flt.d.cgf new file mode 100644 index 000000000..f350b32e3 --- /dev/null +++ b/coverage/cgfs_fext/RV32D/flt.d.cgf @@ -0,0 +1,35 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +flt.d_b1: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + flt.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,64, "flt.d", 2)': 0 + +flt.d_b19: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + flt.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b19(flen,64, "flt.d", 2)': 0 diff --git a/coverage/cgfs_fext/RV32D/fmadd.d.cgf b/coverage/cgfs_fext/RV32D/fmadd.d.cgf new file mode 100644 index 000000000..a9a49cfbb --- /dev/null +++ b/coverage/cgfs_fext/RV32D/fmadd.d.cgf @@ -0,0 +1,248 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fmadd.d_b1: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmadd.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,64, "fmadd.d", 3)': 0 + +fmadd.d_b2: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmadd.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b2(flen,64, "fmadd.d", 3)': 0 + +fmadd.d_b3: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmadd.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b3(flen,64, "fmadd.d", 3)': 0 + +fmadd.d_b4: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmadd.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b4(flen,64, "fmadd.d", 3)': 0 + +fmadd.d_b5: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmadd.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b5(flen,64, "fmadd.d", 3)': 0 + +fmadd.d_b6: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmadd.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b6(flen,64, "fmadd.d", 3)': 0 + +fmadd.d_b7: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmadd.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b7(flen,64, "fmadd.d", 3)': 0 + +fmadd.d_b8: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmadd.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b8(flen,64, "fmadd.d", 3)': 0 + +fmadd.d_b14: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmadd.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b14(flen,64, "fmadd.d", 3)': 0 + +fmadd.d_b15: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmadd.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b15(flen,64, "fmadd.d", 3)': 0 + +fmadd.d_b16: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmadd.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b16(flen,64, "fmadd.d", 3)': 0 + +fmadd.d_b17: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmadd.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b17(flen,64, "fmadd.d", 3)': 0 + +fmadd.d_b18: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmadd.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b18(flen,64, "fmadd.d", 3)': 0 diff --git a/coverage/cgfs_fext/RV32D/fmax.d.cgf b/coverage/cgfs_fext/RV32D/fmax.d.cgf new file mode 100644 index 000000000..73633a2fc --- /dev/null +++ b/coverage/cgfs_fext/RV32D/fmax.d.cgf @@ -0,0 +1,35 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fmax.d_b1: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmax.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,64, "fmax.d", 2)': 0 + +fmax.d_b19: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmax.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b19(flen,64, "fmax.d", 2)': 0 diff --git a/coverage/cgfs_fext/RV32D/fmin.d.cgf b/coverage/cgfs_fext/RV32D/fmin.d.cgf new file mode 100644 index 000000000..df0a710ef --- /dev/null +++ b/coverage/cgfs_fext/RV32D/fmin.d.cgf @@ -0,0 +1,35 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fmin.d_b1: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmin.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,64, "fmin.d", 2)': 0 + +fmin.d_b19: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmin.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b19(flen,64, "fmin.d", 2)': 0 diff --git a/coverage/cgfs_fext/RV32D/fmsub.d.cgf b/coverage/cgfs_fext/RV32D/fmsub.d.cgf new file mode 100644 index 000000000..7f734f8f9 --- /dev/null +++ b/coverage/cgfs_fext/RV32D/fmsub.d.cgf @@ -0,0 +1,248 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fmsub.d_b1: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmsub.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,64, "fmsub.d", 3)': 0 + +fmsub.d_b2: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmsub.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b2(flen,64, "fmsub.d", 3)': 0 + +fmsub.d_b3: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmsub.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b3(flen,64, "fmsub.d", 3)': 0 + +fmsub.d_b4: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmsub.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b4(flen,64, "fmsub.d", 3)': 0 + +fmsub.d_b5: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmsub.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b5(flen,64, "fmsub.d", 3)': 0 + +fmsub.d_b6: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmsub.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b6(flen,64, "fmsub.d", 3)': 0 + +fmsub.d_b7: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmsub.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b7(flen,64, "fmsub.d", 3)': 0 + +fmsub.d_b8: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmsub.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b8(flen,64, "fmsub.d", 3)': 0 + +fmsub.d_b14: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmsub.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b14(flen,64, "fmsub.d", 3)': 0 + +fmsub.d_b15: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmsub.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b15(flen,64, "fmsub.d", 3)': 0 + +fmsub.d_b16: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmsub.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b16(flen,64, "fmsub.d", 3)': 0 + +fmsub.d_b17: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmsub.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b17(flen,64, "fmsub.d", 3)': 0 + +fmsub.d_b18: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmsub.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b18(flen,64, "fmsub.d", 3)': 0 diff --git a/coverage/cgfs_fext/RV32D/fmul.d.cgf b/coverage/cgfs_fext/RV32D/fmul.d.cgf new file mode 100644 index 000000000..48db171f3 --- /dev/null +++ b/coverage/cgfs_fext/RV32D/fmul.d.cgf @@ -0,0 +1,155 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fmul.d_b1: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmul.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,64, "fmul.d", 2)': 0 + +fmul.d_b2: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmul.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b2(flen,64, "fmul.d", 2)': 0 + +fmul.d_b3: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmul.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b3(flen,64, "fmul.d", 2)': 0 + +fmul.d_b4: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmul.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b4(flen,64, "fmul.d", 2)': 0 + +fmul.d_b5: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmul.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b5(flen,64, "fmul.d", 2)': 0 + +fmul.d_b6: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmul.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b6(flen,64, "fmul.d", 2)': 0 + +fmul.d_b7: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmul.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b7(flen,64, "fmul.d", 2)': 0 + +fmul.d_b8: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmul.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b8(flen,64, "fmul.d", 2)': 0 + +fmul.d_b9: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fmul.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b9(flen,64, "fmul.d", 2)': 0 + diff --git a/coverage/cgfs_fext/RV32D/fnmadd.d.cgf b/coverage/cgfs_fext/RV32D/fnmadd.d.cgf new file mode 100644 index 000000000..192d998c5 --- /dev/null +++ b/coverage/cgfs_fext/RV32D/fnmadd.d.cgf @@ -0,0 +1,248 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fnmadd.d_b1: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fnmadd.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,64, "fnmadd.d", 3)': 0 + +fnmadd.d_b2: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fnmadd.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b2(flen,64, "fnmadd.d", 3)': 0 + +fnmadd.d_b3: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fnmadd.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b3(flen,64, "fnmadd.d", 3)': 0 + +fnmadd.d_b4: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fnmadd.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b4(flen,64, "fnmadd.d", 3)': 0 + +fnmadd.d_b5: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fnmadd.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b5(flen,64, "fnmadd.d", 3)': 0 + +fnmadd.d_b6: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fnmadd.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b6(flen,64, "fnmadd.d", 3)': 0 + +fnmadd.d_b7: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fnmadd.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b7(flen,64, "fnmadd.d", 3)': 0 + +fnmadd.d_b8: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fnmadd.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b8(flen,64, "fnmadd.d", 3)': 0 + +fnmadd.d_b14: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fnmadd.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b14(flen,64, "fnmadd.d", 3)': 0 + +fnmadd.d_b15: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fnmadd.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b15(flen,64, "fnmadd.d", 3)': 0 + +fnmadd.d_b16: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fnmadd.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b16(flen,64, "fnmadd.d", 3)': 0 + +fnmadd.d_b17: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fnmadd.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b17(flen,64, "fnmadd.d", 3)': 0 + +fnmadd.d_b18: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fnmadd.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b18(flen,64, "fnmadd.d", 3)': 0 diff --git a/coverage/cgfs_fext/RV32D/fnmsub.d.cgf b/coverage/cgfs_fext/RV32D/fnmsub.d.cgf new file mode 100644 index 000000000..5c8c2b6d9 --- /dev/null +++ b/coverage/cgfs_fext/RV32D/fnmsub.d.cgf @@ -0,0 +1,248 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fnmsub.d_b1: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fnmsub.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,64, "fnmsub.d", 3)': 0 + +fnmsub.d_b2: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fnmsub.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b2(flen,64, "fnmsub.d", 3)': 0 + +fnmsub.d_b3: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fnmsub.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b3(flen,64, "fnmsub.d", 3)': 0 + +fnmsub.d_b4: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fnmsub.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b4(flen,64, "fnmsub.d", 3)': 0 + +fnmsub.d_b5: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fnmsub.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b5(flen,64, "fnmsub.d", 3)': 0 + +fnmsub.d_b6: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fnmsub.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b6(flen,64, "fnmsub.d", 3)': 0 + +fnmsub.d_b7: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fnmsub.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b7(flen,64, "fnmsub.d", 3)': 0 + +fnmsub.d_b8: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fnmsub.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b8(flen,64, "fnmsub.d", 3)': 0 + +fnmsub.d_b14: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fnmsub.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b14(flen,64, "fnmsub.d", 3)': 0 + +fnmsub.d_b15: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fnmsub.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b15(flen,64, "fnmsub.d", 3)': 0 + +fnmsub.d_b16: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fnmsub.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b16(flen,64, "fnmsub.d", 3)': 0 + +fnmsub.d_b17: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fnmsub.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b17(flen,64, "fnmsub.d", 3)': 0 + +fnmsub.d_b18: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fnmsub.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b18(flen,64, "fnmsub.d", 3)': 0 diff --git a/coverage/cgfs_fext/RV32D/fsd-align.cgf b/coverage/cgfs_fext/RV32D/fsd-align.cgf new file mode 100644 index 000000000..4897723b2 --- /dev/null +++ b/coverage/cgfs_fext/RV32D/fsd-align.cgf @@ -0,0 +1,23 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fsd-align: + config: + - check ISA:=regex(.*D.*) + mnemonics: + fsd: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_fregs + val_comb: + 'ea_align == 0 and (imm_val % 8) == 0 and fcsr == 0': 0 + 'ea_align == 0 and (imm_val % 8) == 1 and fcsr == 0': 0 + 'ea_align == 0 and (imm_val % 8) == 2 and fcsr == 0': 0 + 'ea_align == 0 and (imm_val % 8) == 3 and fcsr == 0': 0 + 'ea_align == 0 and (imm_val % 8) == 4 and fcsr == 0': 0 + 'ea_align == 0 and (imm_val % 8) == 5 and fcsr == 0': 0 + 'ea_align == 0 and (imm_val % 8) == 6 and fcsr == 0': 0 + 'ea_align == 0 and (imm_val % 8) == 7 and fcsr == 0': 0 + 'imm_val > 0 and fcsr == 0': 0 + 'imm_val < 0 and fcsr == 0': 0 + 'imm_val == 0 and fcsr == 0': 0 diff --git a/coverage/cgfs_fext/RV32D/fsgnj.d.cgf b/coverage/cgfs_fext/RV32D/fsgnj.d.cgf new file mode 100644 index 000000000..c92ce150e --- /dev/null +++ b/coverage/cgfs_fext/RV32D/fsgnj.d.cgf @@ -0,0 +1,19 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fsgnj.d_b1: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fsgnj.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,64, "fsgnj.d", 2)': 0 + diff --git a/coverage/cgfs_fext/RV32D/fsgnjn.d.cgf b/coverage/cgfs_fext/RV32D/fsgnjn.d.cgf new file mode 100644 index 000000000..7eab86eca --- /dev/null +++ b/coverage/cgfs_fext/RV32D/fsgnjn.d.cgf @@ -0,0 +1,19 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fsgnjn.d_b1: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fsgnjn.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,64, "fsgnjn.d", 2)': 0 + diff --git a/coverage/cgfs_fext/RV32D/fsgnjx.d.cgf b/coverage/cgfs_fext/RV32D/fsgnjx.d.cgf new file mode 100644 index 000000000..ba00bff1f --- /dev/null +++ b/coverage/cgfs_fext/RV32D/fsgnjx.d.cgf @@ -0,0 +1,19 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fsgnjx.d_b1: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fsgnjx.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,64, "fsgnjx.d", 2)': 0 + diff --git a/coverage/cgfs_fext/RV32D/fsqrt.d.cgf b/coverage/cgfs_fext/RV32D/fsqrt.d.cgf new file mode 100644 index 000000000..4c12d7bba --- /dev/null +++ b/coverage/cgfs_fext/RV32D/fsqrt.d.cgf @@ -0,0 +1,137 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fsqrt.d_b1: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fsqrt.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,64, "fsqrt.d", 1)': 0 + +fsqrt.d_b2: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fsqrt.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b2(flen,64, "fsqrt.d", 1)': 0 + +fsqrt.d_b3: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fsqrt.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b3(flen,64, "fsqrt.d", 1)': 0 + +fsqrt.d_b4: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fsqrt.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b4(flen,64, "fsqrt.d", 1)': 0 + +fsqrt.d_b5: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fsqrt.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b5(flen,64, "fsqrt.d", 1)': 0 + +fsqrt.d_b7: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fsqrt.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b7(flen,64, "fsqrt.d", 1)': 0 + +fsqrt.d_b8: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fsqrt.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b8(flen,64, "fsqrt.d", 1)': 0 + +fsqrt.d_b9: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fsqrt.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b9(flen,64, "fsqrt.d", 1)': 0 + +fsqrt.d_b20: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fsqrt.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b20(flen,64, "fsqrt.d", 1)': 0 + diff --git a/coverage/cgfs_fext/RV32D/fsub.d.cgf b/coverage/cgfs_fext/RV32D/fsub.d.cgf new file mode 100644 index 000000000..df8a6f946 --- /dev/null +++ b/coverage/cgfs_fext/RV32D/fsub.d.cgf @@ -0,0 +1,188 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fssub.d_b1: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fsub.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,64, "fsub.d", 2)': 0 + +fssub.d_b2: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fsub.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b2(flen,64, "fsub.d", 2)': 0 + +fssub.d_b3: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fsub.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b3(flen,64, "fsub.d", 2)': 0 + +fssub.d_b4: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fsub.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b4(flen,64, "fsub.d", 2)': 0 + +fssub.d_b5: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fsub.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b5(flen,64, "fsub.d", 2)': 0 + +fssub.d_b7: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fsub.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b7(flen,64, "fsub.d", 2)': 0 + +fssub.d_b8: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fsub.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b8(flen,64, "fsub.d", 2)': 0 + +fssub.d_b10: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fsub.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b10(flen,64, "fsub.d", 2)': 0 + +fssub.d_b11: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fsub.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b11(flen,64, "fsub.d", 2)': 0 + +fssub.d_b12: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fsub.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b12(flen,64, "fsub.d", 2)': 0 + +fssub.d_b13: + config: + - check ISA:=regex(.*I.*D.*) + mnemonics: + fsub.d: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b13(flen,64, "fsub.d", 2)': 0 diff --git a/coverage/cgfs_fext/RV32F/fadd.s.cgf b/coverage/cgfs_fext/RV32F/fadd.s.cgf new file mode 100644 index 000000000..01fc5104f --- /dev/null +++ b/coverage/cgfs_fext/RV32F/fadd.s.cgf @@ -0,0 +1,188 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fadd_b1: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fadd.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fadd.s", 2)': 0 + +fadd_b2: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fadd.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b2(flen,32, "fadd.s", 2)': 0 + +fadd_b3: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fadd.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b3(flen,32, "fadd.s", 2)': 0 + +fadd_b4: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fadd.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b4(flen,32, "fadd.s", 2)': 0 + +fadd_b5: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fadd.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b5(flen,32, "fadd.s", 2)': 0 + +fadd_b7: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fadd.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b7(flen,32, "fadd.s", 2)': 0 + +fadd_b8: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fadd.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b8(flen,32, "fadd.s", 2)': 0 + +fadd_b10: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fadd.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b10(flen,32, "fadd.s", 2)': 0 + +fadd_b11: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fadd.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b11(flen,32, "fadd.s", 2)': 0 + +fadd_b12: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fadd.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b12(flen,32, "fadd.s", 2)': 0 + +fadd_b13: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fadd.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b13(flen,32, "fadd.s", 2)': 0 diff --git a/coverage/cgfs_fext/RV32F/fclass.s.cgf b/coverage/cgfs_fext/RV32F/fclass.s.cgf new file mode 100644 index 000000000..cf7cd1dbc --- /dev/null +++ b/coverage/cgfs_fext/RV32F/fclass.s.cgf @@ -0,0 +1,15 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fclass_b1: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fclass.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fclass.s", 1)': 0 + diff --git a/coverage/cgfs_fext/RV32F/fcvt.s.w.cgf b/coverage/cgfs_fext/RV32F/fcvt.s.w.cgf new file mode 100644 index 000000000..49dc0f9c5 --- /dev/null +++ b/coverage/cgfs_fext/RV32F/fcvt.s.w.cgf @@ -0,0 +1,28 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fcvt.s.w_b25: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fcvt.s.w: 0 + rs1: + <<: *all_regs + rd: + <<: *all_fregs + val_comb: + abstract_comb: + 'ibm_b25(flen,32, "fcvt.s.w", 1)': 0 + +fcvt.s.w_b26: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fcvt.s.w: 0 + rs1: + <<: *all_regs + rd: + <<: *all_fregs + val_comb: + abstract_comb: + 'ibm_b26(32, "fcvt.s.w", 1)': 0 + diff --git a/coverage/cgfs_fext/RV32F/fcvt.s.wu.cgf b/coverage/cgfs_fext/RV32F/fcvt.s.wu.cgf new file mode 100644 index 000000000..eff472660 --- /dev/null +++ b/coverage/cgfs_fext/RV32F/fcvt.s.wu.cgf @@ -0,0 +1,28 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fcvt.s.wu_b25: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fcvt.s.wu: 0 + rs1: + <<: *all_regs + rd: + <<: *all_fregs + val_comb: + abstract_comb: + 'ibm_b25(flen,32, "fcvt.s.wu", 1)': 0 + +fcvt.s.wu_b26: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fcvt.s.wu: 0 + rs1: + <<: *all_regs + rd: + <<: *all_fregs + val_comb: + abstract_comb: + 'ibm_b26(32, "fcvt.s.wu", 1)': 0 + diff --git a/coverage/cgfs_fext/RV32F/fcvt.w.s.cgf b/coverage/cgfs_fext/RV32F/fcvt.w.s.cgf new file mode 100644 index 000000000..1950bc326 --- /dev/null +++ b/coverage/cgfs_fext/RV32F/fcvt.w.s.cgf @@ -0,0 +1,92 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fcvt.w.s_b1: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fcvt.w.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fcvt.w.s", 1)': 0 + +fcvt.w.s_b22: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fcvt.w.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b22(flen,32, "fcvt.w.s", 1)': 0 + +fcvt.w.s_b23: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fcvt.w.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b23(flen,32, "fcvt.w.s", 1)': 0 + +fcvt.w.s_b24: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fcvt.w.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b24(flen,32, "fcvt.w.s", 1)': 0 + +fcvt.w.s_b27: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fcvt.w.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b27(flen,32, "fcvt.w.s", 1)': 0 + +fcvt.w.s_b28: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fcvt.w.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b28(flen,32, "fcvt.w.s", 1)': 0 + +fcvt.w.s_b29: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fcvt.w.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b29(flen,32, "fcvt.w.s", 1)': 0 diff --git a/coverage/cgfs_fext/RV32F/fcvt.wu.s.cgf b/coverage/cgfs_fext/RV32F/fcvt.wu.s.cgf new file mode 100644 index 000000000..4ab625dd6 --- /dev/null +++ b/coverage/cgfs_fext/RV32F/fcvt.wu.s.cgf @@ -0,0 +1,92 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fcvt.wu.s_b1: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fcvt.wu.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fcvt.wu.s", 1)': 0 + +fcvt.wu.s_b22: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fcvt.wu.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b22(flen,32, "fcvt.wu.s", 1)': 0 + +fcvt.wu.s_b23: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fcvt.wu.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b23(flen,32, "fcvt.wu.s", 1)': 0 + +fcvt.wu.s_b24: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fcvt.wu.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b24(flen,32, "fcvt.wu.s", 1)': 0 + +fcvt.wu.s_b27: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fcvt.wu.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b27(flen,32, "fcvt.wu.s", 1)': 0 + +fcvt.wu.s_b28: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fcvt.wu.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b28(flen,32, "fcvt.wu.s", 1)': 0 + +fcvt.wu.s_b29: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fcvt.wu.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b29(flen,32, "fcvt.wu.s", 1)': 0 diff --git a/coverage/cgfs_fext/RV32F/fdiv.s.cgf b/coverage/cgfs_fext/RV32F/fdiv.s.cgf new file mode 100644 index 000000000..f4b3e143b --- /dev/null +++ b/coverage/cgfs_fext/RV32F/fdiv.s.cgf @@ -0,0 +1,188 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fdiv_b1: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fdiv.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fdiv.s", 2)': 0 + +fdiv_b2: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fdiv.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b2(flen,32, "fdiv.s", 2)': 0 + +fdiv_b3: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fdiv.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b3(flen,32, "fdiv.s", 2)': 0 + +fdiv_b4: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fdiv.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b4(flen,32, "fdiv.s", 2)': 0 + +fdiv_b5: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fdiv.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b5(flen,32, "fdiv.s", 2)': 0 + +fdiv_b6: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fdiv.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b6(flen,32, "fdiv.s", 2)': 0 + +fdiv_b7: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fdiv.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b7(flen,32, "fdiv.s", 2)': 0 + +fdiv_b8: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fdiv.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b8(flen,32, "fdiv.s", 2)': 0 + +fdiv_b9: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fdiv.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b9(flen,32, "fdiv.s", 2)': 0 + +fdiv_b20: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fdiv.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b20(flen,32, "fdiv.s", 2)': 0 + +fdiv_b21: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fdiv.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b21(flen,32, "fdiv.s", 2)': 0 diff --git a/coverage/cgfs_fext/RV32F/feq.s.cgf b/coverage/cgfs_fext/RV32F/feq.s.cgf new file mode 100644 index 000000000..7cf20e824 --- /dev/null +++ b/coverage/cgfs_fext/RV32F/feq.s.cgf @@ -0,0 +1,35 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +feq_b1: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + feq.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "feq.s", 2)': 0 + +feq_b19: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + feq.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b19(flen,32, "feq.s", 2)': 0 diff --git a/coverage/cgfs_fext/RV32F/fle.s.cgf b/coverage/cgfs_fext/RV32F/fle.s.cgf new file mode 100644 index 000000000..0e743cfb2 --- /dev/null +++ b/coverage/cgfs_fext/RV32F/fle.s.cgf @@ -0,0 +1,35 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fle_b1: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fle.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fle.s", 2)': 0 + +fle_b19: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fle.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b19(flen,32, "fle.s", 2)': 0 diff --git a/coverage/cgfs_fext/RV32F/flt.s.cgf b/coverage/cgfs_fext/RV32F/flt.s.cgf new file mode 100644 index 000000000..0cbfc4966 --- /dev/null +++ b/coverage/cgfs_fext/RV32F/flt.s.cgf @@ -0,0 +1,35 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +flt_b1: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + flt.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "flt.s", 2)': 0 + +flt_b19: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + flt.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b19(flen,32, "flt.s", 2)': 0 diff --git a/coverage/cgfs_fext/RV32F/flw-align.cgf b/coverage/cgfs_fext/RV32F/flw-align.cgf new file mode 100644 index 000000000..62ed7d1bb --- /dev/null +++ b/coverage/cgfs_fext/RV32F/flw-align.cgf @@ -0,0 +1,19 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +flw-align: + config: + - check ISA:=regex(.*F.*) + mnemonics: + flw: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_fregs + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0 and fcsr == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1 and fcsr == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 2 and fcsr == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 3 and fcsr == 0': 0 + 'imm_val > 0 and fcsr == 0': 0 + 'imm_val < 0 and fcsr == 0': 0 + 'imm_val == 0 and fcsr == 0': 0 diff --git a/coverage/cgfs_fext/RV32F/fmadd.s.cgf b/coverage/cgfs_fext/RV32F/fmadd.s.cgf new file mode 100644 index 000000000..b5f3c9a85 --- /dev/null +++ b/coverage/cgfs_fext/RV32F/fmadd.s.cgf @@ -0,0 +1,248 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fmadd_b1: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmadd.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fmadd.s", 3)': 0 + +fmadd_b2: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmadd.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b2(flen,32, "fmadd.s", 3)': 0 + +fmadd_b3: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmadd.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b3(flen,32, "fmadd.s", 3)': 0 + +fmadd_b4: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmadd.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b4(flen,32, "fmadd.s", 3)': 0 + +fmadd_b5: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmadd.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b5(flen,32, "fmadd.s", 3)': 0 + +fmadd_b6: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmadd.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b6(flen,32, "fmadd.s", 3)': 0 + +fmadd_b7: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmadd.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b7(flen,32, "fmadd.s", 3)': 0 + +fmadd_b8: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmadd.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b8(flen,32, "fmadd.s", 3)': 0 + +fmadd_b14: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmadd.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b14(flen,32, "fmadd.s", 3)': 0 + +fmadd_b15: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmadd.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b15(flen,32, "fmadd.s", 3)': 0 + +fmadd_b16: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmadd.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b16(flen,32, "fmadd.s", 3)': 0 + +fmadd_b17: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmadd.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b17(flen,32, "fmadd.s", 3)': 0 + +fmadd_b18: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmadd.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b18(flen,32, "fmadd.s", 3)': 0 diff --git a/coverage/cgfs_fext/RV32F/fmax.s.cgf b/coverage/cgfs_fext/RV32F/fmax.s.cgf new file mode 100644 index 000000000..6652fcbf9 --- /dev/null +++ b/coverage/cgfs_fext/RV32F/fmax.s.cgf @@ -0,0 +1,35 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fmax_b1: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmax.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fmax.s", 2)': 0 + +fmax_b19: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmax.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b19(flen,32, "fmax.s", 2)': 0 diff --git a/coverage/cgfs_fext/RV32F/fmin.s.cgf b/coverage/cgfs_fext/RV32F/fmin.s.cgf new file mode 100644 index 000000000..81d4ba06e --- /dev/null +++ b/coverage/cgfs_fext/RV32F/fmin.s.cgf @@ -0,0 +1,35 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fmin_b1: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmin.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fmin.s", 2)': 0 + +fmin_b19: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmin.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b19(flen,32, "fmin.s", 2)': 0 diff --git a/coverage/cgfs_fext/RV32F/fmsub.s.cgf b/coverage/cgfs_fext/RV32F/fmsub.s.cgf new file mode 100644 index 000000000..ff6b74642 --- /dev/null +++ b/coverage/cgfs_fext/RV32F/fmsub.s.cgf @@ -0,0 +1,248 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fmsub_b1: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmsub.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fmsub.s", 3)': 0 + +fmsub_b2: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmsub.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b2(flen,32, "fmsub.s", 3)': 0 + +fmsub_b3: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmsub.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b3(flen,32, "fmsub.s", 3)': 0 + +fmsub_b4: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmsub.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b4(flen,32, "fmsub.s", 3)': 0 + +fmsub_b5: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmsub.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b5(flen,32, "fmsub.s", 3)': 0 + +fmsub_b6: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmsub.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b6(flen,32, "fmsub.s", 3)': 0 + +fmsub_b7: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmsub.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b7(flen,32, "fmsub.s", 3)': 0 + +fmsub_b8: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmsub.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b8(flen,32, "fmsub.s", 3)': 0 + +fmsub_b14: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmsub.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b14(flen,32, "fmsub.s", 3)': 0 + +fmsub_b15: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmsub.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b15(flen,32, "fmsub.s", 3)': 0 + +fmsub_b16: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmsub.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b16(flen,32, "fmsub.s", 3)': 0 + +fmsub_b17: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmsub.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b17(flen,32, "fmsub.s", 3)': 0 + +fmsub_b18: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmsub.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b18(flen,32, "fmsub.s", 3)': 0 diff --git a/coverage/cgfs_fext/RV32F/fmul.s.cgf b/coverage/cgfs_fext/RV32F/fmul.s.cgf new file mode 100644 index 000000000..5d09eba25 --- /dev/null +++ b/coverage/cgfs_fext/RV32F/fmul.s.cgf @@ -0,0 +1,155 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fmul_b1: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmul.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fmul.s", 2)': 0 + +fmul_b2: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmul.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b2(flen,32, "fmul.s", 2)': 0 + +fmul_b3: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmul.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b3(flen,32, "fmul.s", 2)': 0 + +fmul_b4: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmul.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b4(flen,32, "fmul.s", 2)': 0 + +fmul_b5: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmul.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b5(flen,32, "fmul.s", 2)': 0 + +fmul_b6: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmul.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b6(flen,32, "fmul.s", 2)': 0 + +fmul_b7: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmul.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b7(flen,32, "fmul.s", 2)': 0 + +fmul_b8: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmul.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b8(flen,32, "fmul.s", 2)': 0 + +fmul_b9: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmul.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b9(flen,32, "fmul.s", 2)': 0 + diff --git a/coverage/cgfs_fext/RV32F/fmv.w.x.cgf b/coverage/cgfs_fext/RV32F/fmv.w.x.cgf new file mode 100644 index 000000000..fae501eae --- /dev/null +++ b/coverage/cgfs_fext/RV32F/fmv.w.x.cgf @@ -0,0 +1,28 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fmv.w.x_b25: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmv.w.x: 0 + rs1: + <<: *all_regs + rd: + <<: *all_fregs + val_comb: + abstract_comb: + 'ibm_b25(flen,32, "fmv.w.x", 1)': 0 + +fmv.w.x_b26: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmv.w.x: 0 + rs1: + <<: *all_regs + rd: + <<: *all_fregs + val_comb: + abstract_comb: + 'ibm_b26(32, "fmv.w.x", 1)': 0 + diff --git a/coverage/cgfs_fext/RV32F/fmv.x.w.cgf b/coverage/cgfs_fext/RV32F/fmv.x.w.cgf new file mode 100644 index 000000000..e58bacec0 --- /dev/null +++ b/coverage/cgfs_fext/RV32F/fmv.x.w.cgf @@ -0,0 +1,92 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fmv.x.w_b1: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmv.x.w: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fmv.x.w", 1)': 0 + +fmv.x.w_b22: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmv.x.w: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b22(flen,32, "fmv.x.w", 1)': 0 + +fmv.x.w_b23: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmv.x.w: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b23(flen,32, "fmv.x.w", 1)': 0 + +fmv.x.w_b24: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmv.x.w: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b24(flen,32, "fmv.x.w", 1)': 0 + +fmv.x.w_b27: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmv.x.w: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b27(flen,32, "fmv.x.w", 1)': 0 + +fmv.x.w_b28: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmv.x.w: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b28(flen,32, "fmv.x.w", 1)': 0 + +fmv.x.w_b29: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fmv.x.w: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b29(flen,32, "fmv.x.w", 1)': 0 diff --git a/coverage/cgfs_fext/RV32F/fnmadd.s.cgf b/coverage/cgfs_fext/RV32F/fnmadd.s.cgf new file mode 100644 index 000000000..f8834ff4c --- /dev/null +++ b/coverage/cgfs_fext/RV32F/fnmadd.s.cgf @@ -0,0 +1,248 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fnmadd_b1: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fnmadd.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fnmadd.s", 3)': 0 + +fnmadd_b2: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fnmadd.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b2(flen,32, "fnmadd.s", 3)': 0 + +fnmadd_b3: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fnmadd.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b3(flen,32, "fnmadd.s", 3)': 0 + +fnmadd_b4: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fnmadd.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b4(flen,32, "fnmadd.s", 3)': 0 + +fnmadd_b5: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fnmadd.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b5(flen,32, "fnmadd.s", 3)': 0 + +fnmadd_b6: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fnmadd.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b6(flen,32, "fnmadd.s", 3)': 0 + +fnmadd_b7: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fnmadd.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b7(flen,32, "fnmadd.s", 3)': 0 + +fnmadd_b8: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fnmadd.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b8(flen,32, "fnmadd.s", 3)': 0 + +fnmadd_b14: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fnmadd.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b14(flen,32, "fnmadd.s", 3)': 0 + +fnmadd_b15: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fnmadd.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b15(flen,32, "fnmadd.s", 3)': 0 + +fnmadd_b16: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fnmadd.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b16(flen,32, "fnmadd.s", 3)': 0 + +fnmadd_b17: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fnmadd.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b17(flen,32, "fnmadd.s", 3)': 0 + +fnmadd_b18: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fnmadd.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b18(flen,32, "fnmadd.s", 3)': 0 diff --git a/coverage/cgfs_fext/RV32F/fnmsub.s.cgf b/coverage/cgfs_fext/RV32F/fnmsub.s.cgf new file mode 100644 index 000000000..f163e3ce4 --- /dev/null +++ b/coverage/cgfs_fext/RV32F/fnmsub.s.cgf @@ -0,0 +1,248 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fnmsub_b1: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fnmsub.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fnmsub.s", 3)': 0 + +fnmsub_b2: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fnmsub.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b2(flen,32, "fnmsub.s", 3)': 0 + +fnmsub_b3: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fnmsub.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b3(flen,32, "fnmsub.s", 3)': 0 + +fnmsub_b4: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fnmsub.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b4(flen,32, "fnmsub.s", 3)': 0 + +fnmsub_b5: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fnmsub.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b5(flen,32, "fnmsub.s", 3)': 0 + +fnmsub_b6: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fnmsub.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b6(flen,32, "fnmsub.s", 3)': 0 + +fnmsub_b7: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fnmsub.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b7(flen,32, "fnmsub.s", 3)': 0 + +fnmsub_b8: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fnmsub.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b8(flen,32, "fnmsub.s", 3)': 0 + +fnmsub_b14: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fnmsub.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b14(flen,32, "fnmsub.s", 3)': 0 + +fnmsub_b15: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fnmsub.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b15(flen,32, "fnmsub.s", 3)': 0 + +fnmsub_b16: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fnmsub.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b16(flen,32, "fnmsub.s", 3)': 0 + +fnmsub_b17: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fnmsub.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b17(flen,32, "fnmsub.s", 3)': 0 + +fnmsub_b18: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fnmsub.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b18(flen,32, "fnmsub.s", 3)': 0 diff --git a/coverage/cgfs_fext/RV32F/fsgnj.s.cgf b/coverage/cgfs_fext/RV32F/fsgnj.s.cgf new file mode 100644 index 000000000..cd04be5fe --- /dev/null +++ b/coverage/cgfs_fext/RV32F/fsgnj.s.cgf @@ -0,0 +1,19 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fsgnj_b1: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fsgnj.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fsgnj.s", 2)': 0 + diff --git a/coverage/cgfs_fext/RV32F/fsgnjn.s.cgf b/coverage/cgfs_fext/RV32F/fsgnjn.s.cgf new file mode 100644 index 000000000..9b115f283 --- /dev/null +++ b/coverage/cgfs_fext/RV32F/fsgnjn.s.cgf @@ -0,0 +1,19 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fsgnjn_b1: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fsgnjn.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fsgnjn.s", 2)': 0 + diff --git a/coverage/cgfs_fext/RV32F/fsgnjx.s.cgf b/coverage/cgfs_fext/RV32F/fsgnjx.s.cgf new file mode 100644 index 000000000..f157bf009 --- /dev/null +++ b/coverage/cgfs_fext/RV32F/fsgnjx.s.cgf @@ -0,0 +1,19 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fsgnjx_b1: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fsgnjx.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fsgnjx.s", 2)': 0 + diff --git a/coverage/cgfs_fext/RV32F/fsqrt.s.cgf b/coverage/cgfs_fext/RV32F/fsqrt.s.cgf new file mode 100644 index 000000000..0595ee6ab --- /dev/null +++ b/coverage/cgfs_fext/RV32F/fsqrt.s.cgf @@ -0,0 +1,137 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fsqrt_b1: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fsqrt.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fsqrt.s", 1)': 0 + +fsqrt_b2: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fsqrt.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b2(flen,32, "fsqrt.s", 1)': 0 + +fsqrt_b3: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fsqrt.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b3(flen,32, "fsqrt.s", 1)': 0 + +fsqrt_b4: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fsqrt.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b4(flen,32, "fsqrt.s", 1)': 0 + +fsqrt_b5: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fsqrt.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b5(flen,32, "fsqrt.s", 1)': 0 + +fsqrt_b7: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fsqrt.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b7(flen,32, "fsqrt.s", 1)': 0 + +fsqrt_b8: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fsqrt.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b8(flen,32, "fsqrt.s", 1)': 0 + +fsqrt_b9: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fsqrt.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b9(flen,32, "fsqrt.s", 1)': 0 + +fsqrt_b20: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fsqrt.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b20(flen,32, "fsqrt.s", 1)': 0 + diff --git a/coverage/cgfs_fext/RV32F/fsub.s.cgf b/coverage/cgfs_fext/RV32F/fsub.s.cgf new file mode 100644 index 000000000..30eba0362 --- /dev/null +++ b/coverage/cgfs_fext/RV32F/fsub.s.cgf @@ -0,0 +1,188 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fsub_b1: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fsub.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fsub.s", 2)': 0 + +fsub_b2: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fsub.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b2(flen,32, "fsub.s", 2)': 0 + +fsub_b3: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fsub.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b3(flen,32, "fsub.s", 2)': 0 + +fsub_b4: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fsub.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b4(flen,32, "fsub.s", 2)': 0 + +fsub_b5: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fsub.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b5(flen,32, "fsub.s", 2)': 0 + +fsub_b7: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fsub.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b7(flen,32, "fsub.s", 2)': 0 + +fsub_b8: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fsub.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b8(flen,32, "fsub.s", 2)': 0 + +fsub_b10: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fsub.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b10(flen,32, "fsub.s", 2)': 0 + +fsub_b11: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fsub.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b11(flen,32, "fsub.s", 2)': 0 + +fsub_b12: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fsub.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b12(flen,32, "fsub.s", 2)': 0 + +fsub_b13: + config: + - check ISA:=regex(.*I.*F.*) + mnemonics: + fsub.s: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b13(flen,32, "fsub.s", 2)': 0 diff --git a/coverage/cgfs_fext/RV32F/fsw-align.cgf b/coverage/cgfs_fext/RV32F/fsw-align.cgf new file mode 100644 index 000000000..3188c369d --- /dev/null +++ b/coverage/cgfs_fext/RV32F/fsw-align.cgf @@ -0,0 +1,19 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fsw-align: + config: + - check ISA:=regex(.*F.*) + mnemonics: + fsw: 0 + rs2: + <<: *all_fregs + rs1: + <<: *all_regs_mx0 + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0 and fcsr == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1 and fcsr == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 2 and fcsr == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 3 and fcsr == 0': 0 + 'imm_val > 0 and fcsr == 0': 0 + 'imm_val < 0 and fcsr == 0': 0 + 'imm_val == 0 and fcsr == 0': 0 diff --git a/coverage/cgfs_fext/RV32H/rv32h_fadd.cgf b/coverage/cgfs_fext/RV32H/rv32h_fadd.cgf new file mode 100644 index 000000000..cf5c4301d --- /dev/null +++ b/coverage/cgfs_fext/RV32H/rv32h_fadd.cgf @@ -0,0 +1,188 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fadd_b1: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fadd.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,16, "fadd.h", 2)': 0 + +fadd_b2: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fadd.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b2(flen,16, "fadd.h", 2)': 0 + +fadd_b3: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fadd.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b3(flen,16, "fadd.h", 2)': 0 + +fadd_b4: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fadd.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b4(flen,16, "fadd.h", 2)': 0 + +fadd_b5: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fadd.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b5(flen,16, "fadd.h", 2)': 0 + +fadd_b7: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fadd.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b7(flen,16, "fadd.h", 2)': 0 + +fadd_b8: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fadd.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b8(flen,16, "fadd.h", 2)': 0 + +fadd_b10: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fadd.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b10(flen,16, "fadd.h", 2)': 0 + +fadd_b11: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fadd.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b11(flen,16, "fadd.h", 2)': 0 + +fadd_b12: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fadd.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b12(flen,16, "fadd.h", 2)': 0 + +fadd_b13: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fadd.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b13(flen,16, "fadd.h", 2)': 0 diff --git a/coverage/cgfs_fext/RV32H/rv32h_fclass.cgf b/coverage/cgfs_fext/RV32H/rv32h_fclass.cgf new file mode 100644 index 000000000..f83b1a8ad --- /dev/null +++ b/coverage/cgfs_fext/RV32H/rv32h_fclass.cgf @@ -0,0 +1,15 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fclass_b1: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fclass.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b1(flen,16, "fclass.h", 1)': 0 + diff --git a/coverage/cgfs_fext/RV32H/rv32h_fcvt.d.h.cgf b/coverage/cgfs_fext/RV32H/rv32h_fcvt.d.h.cgf new file mode 100644 index 000000000..1d47c5cfe --- /dev/null +++ b/coverage/cgfs_fext/RV32H/rv32h_fcvt.d.h.cgf @@ -0,0 +1,106 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fcvt.d.h_b1: + config: + - check ISA:=regex(.*I.*F.*D.*Zfh.*) + mnemonics: + fcvt.d.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,16, "fcvt.d.h", 1)': 0 + +fcvt.d.h_b22: + config: + - check ISA:=regex(.*I.*F.*D.*Zfh.*) + mnemonics: + fcvt.d.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b22(flen,16, "fcvt.d.h", 1)': 0 + +fcvt.d.h_b23: + config: + - check ISA:=regex(.*I.*F.*D.*Zfh.*) + mnemonics: + fcvt.d.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b23(flen,16, "fcvt.d.h", 1)': 0 + +fcvt.d.h_b24: + config: + - check ISA:=regex(.*I.*F.*D.*Zfh.*) + mnemonics: + fcvt.d.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b24(flen,16, "fcvt.d.h", 1)': 0 + +fcvt.d.h_b27: + config: + - check ISA:=regex(.*I.*F.*D.*Zfh.*) + mnemonics: + fcvt.d.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b27(flen,16, "fcvt.d.h", 1)': 0 + +fcvt.d.h_b28: + config: + - check ISA:=regex(.*I.*F.*D.*Zfh.*) + mnemonics: + fcvt.d.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b28(flen,16, "fcvt.d.h", 1)': 0 + +fcvt.d.h_b29: + config: + - check ISA:=regex(.*I.*F.*D.*Zfh.*) + mnemonics: + fcvt.d.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b29(flen,16, "fcvt.d.h", 1)': 0 diff --git a/coverage/cgfs_fext/RV32H/rv32h_fcvt.h.d.cgf b/coverage/cgfs_fext/RV32H/rv32h_fcvt.h.d.cgf new file mode 100644 index 000000000..07af2333d --- /dev/null +++ b/coverage/cgfs_fext/RV32H/rv32h_fcvt.h.d.cgf @@ -0,0 +1,106 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fcvt.h.d_b1: + config: + - check ISA:=regex(.*I.*F.*D.*Zfh.*) + mnemonics: + fcvt.h.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,64, "fcvt.h.d", 1)': 0 + +fcvt.h.d_b22: + config: + - check ISA:=regex(.*I.*F.*D.*Zfh.*) + mnemonics: + fcvt.h.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b22(flen,64, "fcvt.h.d", 1)': 0 + +fcvt.h.d_b23: + config: + - check ISA:=regex(.*I.*F.*D.*Zfh.*) + mnemonics: + fcvt.h.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b23(flen,64, "fcvt.h.d", 1)': 0 + +fcvt.h.d_b24: + config: + - check ISA:=regex(.*I.*F.*D.*Zfh.*) + mnemonics: + fcvt.h.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b24(flen,64, "fcvt.h.d", 1)': 0 + +fcvt.h.d_b27: + config: + - check ISA:=regex(.*I.*F.*D.*Zfh.*) + mnemonics: + fcvt.h.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b27(flen,64, "fcvt.h.d", 1)': 0 + +fcvt.h.d_b28: + config: + - check ISA:=regex(.*I.*F.*D.*Zfh.*) + mnemonics: + fcvt.h.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b28(flen,64, "fcvt.h.d", 1)': 0 + +fcvt.h.d_b29: + config: + - check ISA:=regex(.*I.*F.*D.*Zfh.*) + mnemonics: + fcvt.h.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b29(flen,64, "fcvt.h.d", 1)': 0 diff --git a/coverage/cgfs_fext/RV32H/rv32h_fcvt.h.l.cgf b/coverage/cgfs_fext/RV32H/rv32h_fcvt.h.l.cgf new file mode 100644 index 000000000..45e9c45fe --- /dev/null +++ b/coverage/cgfs_fext/RV32H/rv32h_fcvt.h.l.cgf @@ -0,0 +1,27 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fcvt.h.l_b25: + config: + - check ISA:=regex(.*I.*F.*D.*Zfh.*) + opcode: + fcvt.h.l: 0 + rs1: + <<: *all_regs + rd: + <<: *all_fregs + val_comb: + abstract_comb: + 'ibm_b25(flen,16, "fcvt.h.l", 1)': 0 + +fcvt.h.l_b26: + config: + - check ISA:=regex(.*I.*F.*D.*Zfh.*) + opcode: + fcvt.h.l: 0 + rs1: + <<: *all_regs + rd: + <<: *all_fregs + val_comb: + abstract_comb: + 'ibm_b26(16, "fcvt.h.l", 1)': 0 diff --git a/coverage/cgfs_fext/RV32H/rv32h_fcvt.h.lu.cgf b/coverage/cgfs_fext/RV32H/rv32h_fcvt.h.lu.cgf new file mode 100644 index 000000000..886da1506 --- /dev/null +++ b/coverage/cgfs_fext/RV32H/rv32h_fcvt.h.lu.cgf @@ -0,0 +1,27 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fcvt.h.lu_b25: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fcvt.h.lu: 0 + rs1: + <<: *all_regs + rd: + <<: *all_fregs + val_comb: + abstract_comb: + 'ibm_b25(flen,16, "fcvt.h.lu", 1)': 0 + +fcvt.h.lu_b26: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fcvt.h.lu: 0 + rs1: + <<: *all_regs + rd: + <<: *all_fregs + val_comb: + abstract_comb: + 'ibm_b26(16, "fcvt.h.lu", 1)': 0 diff --git a/coverage/cgfs_fext/RV32H/rv32h_fcvt.h.s.cgf b/coverage/cgfs_fext/RV32H/rv32h_fcvt.h.s.cgf new file mode 100644 index 000000000..5ddc2fa50 --- /dev/null +++ b/coverage/cgfs_fext/RV32H/rv32h_fcvt.h.s.cgf @@ -0,0 +1,106 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fcvt.h.s_b1: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fcvt.h.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fcvt.h.s", 1)': 0 + +fcvt.h.s_b22: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fcvt.h.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b22(flen,32, "fcvt.h.s", 1)': 0 + +fcvt.h.s_b23: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fcvt.h.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b23(flen,32, "fcvt.h.s", 1)': 0 + +fcvt.h.s_b24: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fcvt.h.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b24(flen,32, "fcvt.h.s", 1)': 0 + +fcvt.h.s_b27: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fcvt.h.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b27(flen,32, "fcvt.h.s", 1)': 0 + +fcvt.h.s_b28: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fcvt.h.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b28(flen,32, "fcvt.h.s", 1)': 0 + +fcvt.h.s_b29: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fcvt.h.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b29(flen,32, "fcvt.h.s", 1)': 0 diff --git a/coverage/cgfs_fext/RV32H/rv32h_fcvt.h.w.cgf b/coverage/cgfs_fext/RV32H/rv32h_fcvt.h.w.cgf new file mode 100644 index 000000000..cd976f40d --- /dev/null +++ b/coverage/cgfs_fext/RV32H/rv32h_fcvt.h.w.cgf @@ -0,0 +1,27 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fcvt.h.w_b25: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fcvt.h.w: 0 + rs1: + <<: *all_regs + rd: + <<: *all_fregs + val_comb: + abstract_comb: + 'ibm_b25(flen,32, "fcvt.h.w", 1)': 0 + +fcvt.h.w_b26: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fcvt.h.w: 0 + rs1: + <<: *all_regs + rd: + <<: *all_fregs + val_comb: + abstract_comb: + 'ibm_b26(32, "fcvt.h.w", 1)': 0 diff --git a/coverage/cgfs_fext/RV32H/rv32h_fcvt.h.wu.cgf b/coverage/cgfs_fext/RV32H/rv32h_fcvt.h.wu.cgf new file mode 100644 index 000000000..ee7cad709 --- /dev/null +++ b/coverage/cgfs_fext/RV32H/rv32h_fcvt.h.wu.cgf @@ -0,0 +1,27 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fcvt.h.wu_b25: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fcvt.h.wu: 0 + rs1: + <<: *all_regs + rd: + <<: *all_fregs + val_comb: + abstract_comb: + 'ibm_b25(flen,32, "fcvt.h.wu", 1)': 0 + +fcvt.h.wu_b26: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fcvt.h.wu: 0 + rs1: + <<: *all_regs + rd: + <<: *all_fregs + val_comb: + abstract_comb: + 'ibm_b26(32, "fcvt.h.wu", 1)': 0 diff --git a/coverage/cgfs_fext/RV32H/rv32h_fcvt.s.h.cgf b/coverage/cgfs_fext/RV32H/rv32h_fcvt.s.h.cgf new file mode 100644 index 000000000..ba74626b1 --- /dev/null +++ b/coverage/cgfs_fext/RV32H/rv32h_fcvt.s.h.cgf @@ -0,0 +1,106 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fcvt.s.h_b1: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + mnemonics: + fcvt.s.h: 0 + rs1: + <<: *all_regs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,16, "fcvt.s.h", 1)': 0 + +fcvt.s.h_b22: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + mnemonics: + fcvt.s.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b22(flen,16, "fcvt.s.h", 1)': 0 + +fcvt.s.h_b23: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + mnemonics: + fcvt.s.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b23(flen,16, "fcvt.s.h", 1)': 0 + +fcvt.s.h_b24: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + mnemonics: + fcvt.s.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b24(flen,16, "fcvt.s.h", 1)': 0 + +fcvt.s.h_b27: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + mnemonics: + fcvt.s.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b27(flen,16, "fcvt.s.h", 1)': 0 + +fcvt.s.h_b28: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + mnemonics: + fcvt.s.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b28(flen,16, "fcvt.s.h", 1)': 0 + +fcvt.s.h_b29: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + mnemonics: + fcvt.s.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b29(flen,16, "fcvt.s.h", 1)': 0 diff --git a/coverage/cgfs_fext/RV32H/rv32h_fcvt.w.h.cgf b/coverage/cgfs_fext/RV32H/rv32h_fcvt.w.h.cgf new file mode 100644 index 000000000..8ce3cbd09 --- /dev/null +++ b/coverage/cgfs_fext/RV32H/rv32h_fcvt.w.h.cgf @@ -0,0 +1,92 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fcvt.w.h_b1: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fcvt.w.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b1(flen,16, "fcvt.w.h", 1)': 0 + +fcvt.w.h_b22: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fcvt.w.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b22(flen,16, "fcvt.w.h", 1)': 0 + +fcvt.w.h_b23: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fcvt.w.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b23(flen,16, "fcvt.w.h", 1)': 0 + +fcvt.w.h_b24: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fcvt.w.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b24(flen,16, "fcvt.w.h", 1)': 0 + +fcvt.w.h_b27: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fcvt.w.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b27(flen,16, "fcvt.w.h", 1)': 0 + +fcvt.w.h_b28: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fcvt.w.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b28(flen,16, "fcvt.w.h", 1)': 0 + +fcvt.w.h_b29: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fcvt.w.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b29(flen,16, "fcvt.w.h", 1)': 0 diff --git a/coverage/cgfs_fext/RV32H/rv32h_fcvt.wu.h.cgf b/coverage/cgfs_fext/RV32H/rv32h_fcvt.wu.h.cgf new file mode 100644 index 000000000..667accdf9 --- /dev/null +++ b/coverage/cgfs_fext/RV32H/rv32h_fcvt.wu.h.cgf @@ -0,0 +1,92 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fcvt.wu.h_b1: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fcvt.wu.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b1(flen,16, "fcvt.wu.h", 1)': 0 + +fcvt.wu.h_b22: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fcvt.wu.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b22(flen,16, "fcvt.wu.h", 1)': 0 + +fcvt.wu.h_b23: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fcvt.wu.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b23(flen,16, "fcvt.wu.h", 1)': 0 + +fcvt.wu.h_b24: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fcvt.wu.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b24(flen,16, "fcvt.wu.h", 1)': 0 + +fcvt.wu.h_b27: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fcvt.wu.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b27(flen,16, "fcvt.wu.h", 1)': 0 + +fcvt.wu.h_b28: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fcvt.wu.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b28(flen,16, "fcvt.wu.h", 1)': 0 + +fcvt.wu.h_b29: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fcvt.wu.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b29(flen,16, "fcvt.wu.h", 1)': 0 diff --git a/coverage/cgfs_fext/RV32H/rv32h_fdiv.cgf b/coverage/cgfs_fext/RV32H/rv32h_fdiv.cgf new file mode 100644 index 000000000..afbfb25c6 --- /dev/null +++ b/coverage/cgfs_fext/RV32H/rv32h_fdiv.cgf @@ -0,0 +1,188 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fdiv_b1: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fdiv.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,16, "fdiv.h", 2)': 0 + +fdiv_b2: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fdiv.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b2(flen,16, "fdiv.h", 2)': 0 + +fdiv_b3: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fdiv.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b3(flen,16, "fdiv.h", 2)': 0 + +fdiv_b4: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fdiv.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b4(flen,16, "fdiv.h", 2)': 0 + +fdiv_b5: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fdiv.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b5(flen,16, "fdiv.h", 2)': 0 + +fdiv_b6: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fdiv.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b6(flen,16, "fdiv.h", 2)': 0 + +fdiv_b7: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fdiv.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b7(flen,16, "fdiv.h", 2)': 0 + +fdiv_b8: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fdiv.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b8(flen,16, "fdiv.h", 2)': 0 + +fdiv_b9: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fdiv.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b9(flen,16, "fdiv.h", 2)': 0 + +fdiv_b20: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fdiv.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b20(flen,16, "fdiv.h", 2)': 0 + +fdiv_b21: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fdiv.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b21(flen,16, "fdiv.h", 2)': 0 diff --git a/coverage/cgfs_fext/RV32H/rv32h_feq.cgf b/coverage/cgfs_fext/RV32H/rv32h_feq.cgf new file mode 100644 index 000000000..65e332ab0 --- /dev/null +++ b/coverage/cgfs_fext/RV32H/rv32h_feq.cgf @@ -0,0 +1,35 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +feq_b1: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + feq.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,16, "feq.h", 2)': 0 + +feq_b19: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + feq.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b19(flen,16, "feq.h", 2)': 0 diff --git a/coverage/cgfs_fext/RV32H/rv32h_fle.cgf b/coverage/cgfs_fext/RV32H/rv32h_fle.cgf new file mode 100644 index 000000000..b3747e79e --- /dev/null +++ b/coverage/cgfs_fext/RV32H/rv32h_fle.cgf @@ -0,0 +1,35 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fle_b1: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fle.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,16, "fle.h", 2)': 0 + +fle_b19: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fle.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b19(flen,16, "fle.h", 2)': 0 diff --git a/coverage/cgfs_fext/RV32H/rv32h_flh.cgf b/coverage/cgfs_fext/RV32H/rv32h_flh.cgf new file mode 100644 index 000000000..d0c0bc988 --- /dev/null +++ b/coverage/cgfs_fext/RV32H/rv32h_flh.cgf @@ -0,0 +1,19 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +flh-align: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + flh: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_fregs + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 diff --git a/coverage/cgfs_fext/RV32H/rv32h_flt.cgf b/coverage/cgfs_fext/RV32H/rv32h_flt.cgf new file mode 100644 index 000000000..863f2df30 --- /dev/null +++ b/coverage/cgfs_fext/RV32H/rv32h_flt.cgf @@ -0,0 +1,35 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +flt_b1: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + flt.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen, 16, "flt.h", 2)': 0 + +flt_b19: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + flt.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b19(flen,16, "flt.h", 2)': 0 diff --git a/coverage/cgfs_fext/RV32H/rv32h_fmadd.cgf b/coverage/cgfs_fext/RV32H/rv32h_fmadd.cgf new file mode 100644 index 000000000..4725656f8 --- /dev/null +++ b/coverage/cgfs_fext/RV32H/rv32h_fmadd.cgf @@ -0,0 +1,229 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fmadd_b1: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmadd.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,16, "fmadd.h", 3)': 0 + +fmadd_b2: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmadd.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b2(flen,16, "fmadd.h", 3)': 0 + +fmadd_b3: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmadd.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b3(flen,16, "fmadd.h", 3)': 0 + +fmadd_b4: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmadd.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b4(flen,16, "fmadd.h", 3)': 0 + +fmadd_b5: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmadd.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b5(flen,16, "fmadd.h", 3)': 0 + +fmadd_b6: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmadd.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b6(flen,16, "fmadd.h", 3)': 0 + +fmadd_b7: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmadd.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b7(flen,16, "fmadd.h", 3)': 0 + +fmadd_b8: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmadd.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b8(flen,16, "fmadd.h", 3)': 0 + +fmadd_b14: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmadd.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b14(flen,16, "fmadd.h", 3)': 0 + +fmadd_b16: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmadd.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b16(flen,16, "fmadd.h", 3)': 0 + +fmadd_b17: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmadd.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b17(flen,16, "fmadd.h", 3)': 0 + +fmadd_b18: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmadd.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b18(flen,16, "fmadd.h", 3)': 0 diff --git a/coverage/cgfs_fext/RV32H/rv32h_fmax.cgf b/coverage/cgfs_fext/RV32H/rv32h_fmax.cgf new file mode 100644 index 000000000..f9d08a408 --- /dev/null +++ b/coverage/cgfs_fext/RV32H/rv32h_fmax.cgf @@ -0,0 +1,35 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fmax_b1: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmax.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,16, "fmax.h", 2)': 0 + +fmax_b19: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmax.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b19(flen,16, "fmax.h", 2)': 0 diff --git a/coverage/cgfs_fext/RV32H/rv32h_fmin.cgf b/coverage/cgfs_fext/RV32H/rv32h_fmin.cgf new file mode 100644 index 000000000..91db1bf14 --- /dev/null +++ b/coverage/cgfs_fext/RV32H/rv32h_fmin.cgf @@ -0,0 +1,35 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fmin_b1: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmin.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,16, "fmin.h", 2)': 0 + +fmin_b19: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmin.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b19(flen,16, "fmin.h", 2)': 0 diff --git a/coverage/cgfs_fext/RV32H/rv32h_fmsub.cgf b/coverage/cgfs_fext/RV32H/rv32h_fmsub.cgf new file mode 100644 index 000000000..ea60b6b2f --- /dev/null +++ b/coverage/cgfs_fext/RV32H/rv32h_fmsub.cgf @@ -0,0 +1,229 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fmsub_b1: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmsub.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,16, "fmsub.h", 3)': 0 + +fmsub_b2: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmsub.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b2(flen,16, "fmsub.h", 3)': 0 + +fmsub_b3: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmsub.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b3(flen,16, "fmsub.h", 3)': 0 + +fmsub_b4: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmsub.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b4(flen,16, "fmsub.h", 3)': 0 + +fmsub_b5: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmsub.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b5(flen,16, "fmsub.h", 3)': 0 + +fmsub_b6: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmsub.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b6(flen,16, "fmsub.h", 3)': 0 + +fmsub_b7: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmsub.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b7(flen,16, "fmsub.h", 3)': 0 + +fmsub_b8: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmsub.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b8(flen,16, "fmsub.h", 3)': 0 + +fmsub_b14: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmsub.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b14(flen,16, "fmsub.h", 3)': 0 + +fmsub_b16: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmsub.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b16(flen,16, "fmsub.h", 3)': 0 + +fmsub_b17: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmsub.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b17(flen,16, "fmsub.h", 3)': 0 + +fmsub_b18: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmsub.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b18(flen,16, "fmsub.h", 3)': 0 diff --git a/coverage/cgfs_fext/RV32H/rv32h_fmul.cgf b/coverage/cgfs_fext/RV32H/rv32h_fmul.cgf new file mode 100644 index 000000000..f53aefee5 --- /dev/null +++ b/coverage/cgfs_fext/RV32H/rv32h_fmul.cgf @@ -0,0 +1,155 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fmul_b1: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmul.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,16, "fmul.h", 2)': 0 + +fmul_b2: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmul.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b2(flen,16, "fmul.h", 2)': 0 + +fmul_b3: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmul.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b3(flen,16, "fmul.h", 2)': 0 + +fmul_b4: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmul.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b4(flen,16, "fmul.h", 2)': 0 + +fmul_b5: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmul.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b5(flen,16, "fmul.h", 2)': 0 + +fmul_b6: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmul.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b6(flen,16, "fmul.h", 2)': 0 + +fmul_b7: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmul.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b7(flen,16, "fmul.h", 2)': 0 + +fmul_b8: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmul.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b8(flen,16, "fmul.h", 2)': 0 + +fmul_b9: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmul.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b9(flen,16, "fmul.h", 2)': 0 + diff --git a/coverage/cgfs_fext/RV32H/rv32h_fmv.h.x.cgf b/coverage/cgfs_fext/RV32H/rv32h_fmv.h.x.cgf new file mode 100644 index 000000000..1a24a485b --- /dev/null +++ b/coverage/cgfs_fext/RV32H/rv32h_fmv.h.x.cgf @@ -0,0 +1,28 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fmv.h.x_b25: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmv.h.x: 0 + rs1: + <<: *all_regs + rd: + <<: *all_fregs + val_comb: + abstract_comb: + 'ibm_b25(flen,32, "fmv.h.x", 1)': 0 + +fmv.h.x_b26: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmv.h.x: 0 + rs1: + <<: *all_regs + rd: + <<: *all_fregs + val_comb: + abstract_comb: + 'ibm_b26(flen,"fmv.h.x", 1)': 0 + diff --git a/coverage/cgfs_fext/RV32H/rv32h_fmv.x.h.cgf b/coverage/cgfs_fext/RV32H/rv32h_fmv.x.h.cgf new file mode 100644 index 000000000..3f6fb1854 --- /dev/null +++ b/coverage/cgfs_fext/RV32H/rv32h_fmv.x.h.cgf @@ -0,0 +1,92 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fmv.x.h_b1: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmv.x.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b1(flen,16, "fmv.x.h", 1)': 0 + +fmv.x.h_b22: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmv.x.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b22(flen,16, "fmv.x.h", 1)': 0 + +fmv.x.h_b23: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmv.x.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b23(flen,16, "fmv.x.h", 1)': 0 + +fmv.x.h_b24: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmv.x.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b24(flen,16, "fmv.x.h", 1)': 0 + +fmv.x.h_b27: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmv.x.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b27(flen,16, "fmv.x.h", 1)': 0 + +fmv.x.h_b28: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmv.x.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b28(flen,16, "fmv.x.h", 1)': 0 + +fmv.x.h_b29: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fmv.x.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b29(flen, 16, "fmv.x.h", 1)': 0 diff --git a/coverage/cgfs_fext/RV32H/rv32h_fnmadd.cgf b/coverage/cgfs_fext/RV32H/rv32h_fnmadd.cgf new file mode 100644 index 000000000..92ebf1ac4 --- /dev/null +++ b/coverage/cgfs_fext/RV32H/rv32h_fnmadd.cgf @@ -0,0 +1,229 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fnmadd_b1: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fnmadd.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,16, "fnmadd.h", 3)': 0 + +fnmadd_b2: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fnmadd.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b2(flen,16, "fnmadd.h", 3)': 0 + +fnmadd_b3: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fnmadd.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b3(flen,16, "fnmadd.h", 3)': 0 + +fnmadd_b4: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fnmadd.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b4(flen,16, "fnmadd.h", 3)': 0 + +fnmadd_b5: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fnmadd.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b5(flen,16, "fnmadd.h", 3)': 0 + +fnmadd_b6: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fnmadd.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b6(flen,16, "fnmadd.h", 3)': 0 + +fnmadd_b7: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fnmadd.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b7(flen,16, "fnmadd.h", 3)': 0 + +fnmadd_b8: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fnmadd.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b8(flen,16, "fnmadd.h", 3)': 0 + +fnmadd_b14: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fnmadd.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b14(flen,16, "fnmadd.h", 3)': 0 + +fnmadd_b16: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fnmadd.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b16(flen,16, "fnmadd.h", 3)': 0 + +fnmadd_b17: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fnmadd.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b17(flen,16, "fnmadd.h", 3)': 0 + +fnmadd_b18: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fnmadd.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b18(flen,16, "fnmadd.h", 3)': 0 diff --git a/coverage/cgfs_fext/RV32H/rv32h_fnmsub.cgf b/coverage/cgfs_fext/RV32H/rv32h_fnmsub.cgf new file mode 100644 index 000000000..f59970def --- /dev/null +++ b/coverage/cgfs_fext/RV32H/rv32h_fnmsub.cgf @@ -0,0 +1,229 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fnmsub_b1: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fnmsub.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,16, "fnmsub.h", 3)': 0 + +fnmsub_b2: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fnmsub.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b2(flen,16, "fnmsub.h", 3)': 0 + +fnmsub_b3: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fnmsub.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b3(flen,16, "fnmsub.h", 3)': 0 + +fnmsub_b4: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fnmsub.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b4(flen,16, "fnmsub.h", 3)': 0 + +fnmsub_b5: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fnmsub.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b5(flen,16, "fnmsub.h", 3)': 0 + +fnmsub_b6: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fnmsub.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b6(flen,16, "fnmsub.h", 3)': 0 + +fnmsub_b7: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fnmsub.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b7(flen,16, "fnmsub.h", 3)': 0 + +fnmsub_b8: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fnmsub.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b8(flen,16, "fnmsub.h", 3)': 0 + +fnmsub_b14: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fnmsub.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b14(flen,16, "fnmsub.h", 3)': 0 + +fnmsub_b16: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fnmsub.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b16(flen,16, "fnmsub.h", 3)': 0 + +fnmsub_b17: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fnmsub.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b17(flen,16, "fnmsub.h", 3)': 0 + +fnmsub_b18: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fnmsub.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rs3: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b18(flen,16, "fnmsub.h", 3)': 0 diff --git a/coverage/cgfs_fext/RV32H/rv32h_fsgnj.cgf b/coverage/cgfs_fext/RV32H/rv32h_fsgnj.cgf new file mode 100644 index 000000000..f325b0aa3 --- /dev/null +++ b/coverage/cgfs_fext/RV32H/rv32h_fsgnj.cgf @@ -0,0 +1,19 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fsgnj_b1: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fsgnj.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,16, "fsgnj.h", 2)': 0 + diff --git a/coverage/cgfs_fext/RV32H/rv32h_fsgnjn.cgf b/coverage/cgfs_fext/RV32H/rv32h_fsgnjn.cgf new file mode 100644 index 000000000..d371df88f --- /dev/null +++ b/coverage/cgfs_fext/RV32H/rv32h_fsgnjn.cgf @@ -0,0 +1,19 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fsgnjn_b1: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fsgnjn.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,16, "fsgnjn.h", 2)': 0 + diff --git a/coverage/cgfs_fext/RV32H/rv32h_fsgnjx.cgf b/coverage/cgfs_fext/RV32H/rv32h_fsgnjx.cgf new file mode 100644 index 000000000..b0cc19c80 --- /dev/null +++ b/coverage/cgfs_fext/RV32H/rv32h_fsgnjx.cgf @@ -0,0 +1,19 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fsgnjx_b1: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fsgnjx.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,16, "fsgnjx.h", 2)': 0 + diff --git a/coverage/cgfs_fext/RV32H/rv32h_fsh.cgf b/coverage/cgfs_fext/RV32H/rv32h_fsh.cgf new file mode 100644 index 000000000..a3bb9b930 --- /dev/null +++ b/coverage/cgfs_fext/RV32H/rv32h_fsh.cgf @@ -0,0 +1,19 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fsh-align: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fsh: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_fregs + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 diff --git a/coverage/cgfs_fext/RV32H/rv32h_fsqrt.cgf b/coverage/cgfs_fext/RV32H/rv32h_fsqrt.cgf new file mode 100644 index 000000000..91686f9ea --- /dev/null +++ b/coverage/cgfs_fext/RV32H/rv32h_fsqrt.cgf @@ -0,0 +1,136 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fsqrt_b1: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fsqrt.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,16, "fsqrt.h", 1)': 0 + +fsqrt_b2: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fsqrt.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b2(flen,16, "fsqrt.h", 1)': 0 + +fsqrt_b3: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fsqrt.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b3(flen,16, "fsqrt.h", 1)': 0 + +fsqrt_b4: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fsqrt.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b4(flen,16, "fsqrt.h", 1)': 0 + +fsqrt_b5: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fsqrt.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b5(flen,16, "fsqrt.h", 1)': 0 + +fsqrt_b7: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fsqrt.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b7(flen,16, "fsqrt.h", 1)': 0 + +fsqrt_b8: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fsqrt.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b8(flen,16, "fsqrt.h", 1)': 0 + +fsqrt_b9: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fsqrt.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b9(flen,16, "fsqrt.h", 1)': 0 + +fsqrt_b20: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fsqrt.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b20(flen,16, "fsqrt.h", 1)': 0 diff --git a/coverage/cgfs_fext/RV32H/rv32h_fsub.cgf b/coverage/cgfs_fext/RV32H/rv32h_fsub.cgf new file mode 100644 index 000000000..5fe7229d5 --- /dev/null +++ b/coverage/cgfs_fext/RV32H/rv32h_fsub.cgf @@ -0,0 +1,188 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fsub_b1: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fsub.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,16, "fsub.h", 2)': 0 + +fsub_b2: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fsub.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b2(flen,16, "fsub.h", 2)': 0 + +fsub_b3: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fsub.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b3(flen,16, "fsub.h", 2)': 0 + +fsub_b4: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fsub.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b4(flen,16, "fsub.h", 2)': 0 + +fsub_b5: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fsub.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b5(flen,16, "fsub.h", 2)': 0 + +fsub_b7: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fsub.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b7(flen,16, "fsub.h", 2)': 0 + +fsub_b8: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fsub.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b8(flen,16, "fsub.h", 2)': 0 + +fsub_b10: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fsub.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b10(flen,16, "fsub.h", 2)': 0 + +fsub_b11: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fsub.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b11(flen,16, "fsub.h", 2)': 0 + +fsub_b12: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fsub.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b12(flen,16, "fsub.h", 2)': 0 + +fsub_b13: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fsub.h: 0 + rs1: + <<: *all_fregs + rs2: + <<: *all_fregs + rd: + <<: *all_fregs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b13(flen,16, "fsub.h", 2)': 0 diff --git a/coverage/cgfs_fext/RV64D/fcvt.d.l.cgf b/coverage/cgfs_fext/RV64D/fcvt.d.l.cgf new file mode 100644 index 000000000..7db8eeb9c --- /dev/null +++ b/coverage/cgfs_fext/RV64D/fcvt.d.l.cgf @@ -0,0 +1,28 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fcvt.d.l_b25: + config: + - check ISA:=regex(.*RV64.*I.*D.*) + mnemonics: + fcvt.d.l: 0 + rs1: + <<: *all_regs + rd: + <<: *all_fregs + val_comb: + abstract_comb: + 'ibm_b25(flen,64, "fcvt.d.l", 1)': 0 + +fcvt.d.l_b26: + config: + - check ISA:=regex(.*RV64.*I.*D.*) + mnemonics: + fcvt.d.l: 0 + rs1: + <<: *all_regs + rd: + <<: *all_fregs + val_comb: + abstract_comb: + 'ibm_b26(64, "fcvt.d.l", 1)': 0 + diff --git a/coverage/cgfs_fext/RV64D/fcvt.d.lu.cgf b/coverage/cgfs_fext/RV64D/fcvt.d.lu.cgf new file mode 100644 index 000000000..a2dac71c7 --- /dev/null +++ b/coverage/cgfs_fext/RV64D/fcvt.d.lu.cgf @@ -0,0 +1,28 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fcvt.d.lu_b25: + config: + - check ISA:=regex(.*RV64.*I.*D.*) + mnemonics: + fcvt.d.lu: 0 + rs1: + <<: *all_regs + rd: + <<: *all_fregs + val_comb: + abstract_comb: + 'ibm_b25(flen,64, "fcvt.d.lu", 1)': 0 + +fcvt.d.lu_b26: + config: + - check ISA:=regex(.*RV64.*I.*D.*) + mnemonics: + fcvt.d.lu: 0 + rs1: + <<: *all_regs + rd: + <<: *all_fregs + val_comb: + abstract_comb: + 'ibm_b26(64, "fcvt.d.lu", 1)': 0 + diff --git a/coverage/cgfs_fext/RV64D/fcvt.l.d.cgf b/coverage/cgfs_fext/RV64D/fcvt.l.d.cgf new file mode 100644 index 000000000..a5079b4d6 --- /dev/null +++ b/coverage/cgfs_fext/RV64D/fcvt.l.d.cgf @@ -0,0 +1,92 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fcvt.l.d_b1: + config: + - check ISA:=regex(.*RV64.*I.*D.*) + mnemonics: + fcvt.l.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b1(flen,64, "fcvt.l.d", 1)': 0 + +fcvt.l.d_b22: + config: + - check ISA:=regex(.*RV64.*I.*D.*) + mnemonics: + fcvt.l.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b22(flen,64, "fcvt.l.d", 1)': 0 + +fcvt.l.d_b23: + config: + - check ISA:=regex(.*RV64.*I.*D.*) + mnemonics: + fcvt.l.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b23(flen,64, "fcvt.l.d", 1)': 0 + +fcvt.l.d_b24: + config: + - check ISA:=regex(.*RV64.*I.*D.*) + mnemonics: + fcvt.l.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b24(flen,64, "fcvt.l.d", 1)': 0 + +fcvt.l.d_b27: + config: + - check ISA:=regex(.*RV64.*I.*D.*) + mnemonics: + fcvt.l.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b27(flen,64, "fcvt.l.d", 1)': 0 + +fcvt.l.d_b28: + config: + - check ISA:=regex(.*RV64.*I.*D.*) + mnemonics: + fcvt.l.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b28(flen,64, "fcvt.l.d", 1)': 0 + +fcvt.l.d_b29: + config: + - check ISA:=regex(.*RV64.*I.*D.*) + mnemonics: + fcvt.l.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b29(flen,64, "fcvt.l.d", 1)': 0 diff --git a/coverage/cgfs_fext/RV64D/fcvt.lu.d.cgf b/coverage/cgfs_fext/RV64D/fcvt.lu.d.cgf new file mode 100644 index 000000000..7402e4520 --- /dev/null +++ b/coverage/cgfs_fext/RV64D/fcvt.lu.d.cgf @@ -0,0 +1,92 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fcvt.lu.d_b1: + config: + - check ISA:=regex(.*RV64.*I.*D.*) + mnemonics: + fcvt.lu.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b1(flen,64, "fcvt.lu.d", 1)': 0 + +fcvt.lu.d_b22: + config: + - check ISA:=regex(.*RV64.*I.*D.*) + mnemonics: + fcvt.lu.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b22(flen,64, "fcvt.lu.d", 1)': 0 + +fcvt.lu.d_b23: + config: + - check ISA:=regex(.*RV64.*I.*D.*) + mnemonics: + fcvt.lu.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b23(flen,64, "fcvt.lu.d", 1)': 0 + +fcvt.lu.d_b24: + config: + - check ISA:=regex(.*RV64.*I.*D.*) + mnemonics: + fcvt.lu.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b24(flen,64, "fcvt.lu.d", 1)': 0 + +fcvt.lu.d_b27: + config: + - check ISA:=regex(.*RV64.*I.*D.*) + mnemonics: + fcvt.lu.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b27(flen,64, "fcvt.lu.d", 1)': 0 + +fcvt.lu.d_b28: + config: + - check ISA:=regex(.*RV64.*I.*D.*) + mnemonics: + fcvt.lu.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b28(flen,64, "fcvt.lu.d", 1)': 0 + +fcvt.lu.d_b29: + config: + - check ISA:=regex(.*RV64.*I.*D.*) + mnemonics: + fcvt.lu.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b29(flen,64, "fcvt.lu.d", 1)': 0 diff --git a/coverage/cgfs_fext/RV64D/fmv.d.x.cgf b/coverage/cgfs_fext/RV64D/fmv.d.x.cgf new file mode 100644 index 000000000..05d67690e --- /dev/null +++ b/coverage/cgfs_fext/RV64D/fmv.d.x.cgf @@ -0,0 +1,28 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fmv.d.x_b25: + config: + - check ISA:=regex(.*RV64.*I.*D.*) + mnemonics: + fmv.d.x: 0 + rs1: + <<: *all_regs + rd: + <<: *all_fregs + val_comb: + abstract_comb: + 'ibm_b25(flen,64, "fmv.d.x", 1)': 0 + +fmv.d.x_b26: + config: + - check ISA:=regex(.*RV64.*I.*D.*) + mnemonics: + fmv.d.x: 0 + rs1: + <<: *all_regs + rd: + <<: *all_fregs + val_comb: + abstract_comb: + 'ibm_b26(64, "fmv.d.x", 1)': 0 + diff --git a/coverage/cgfs_fext/RV64D/fmv.x.d.cgf b/coverage/cgfs_fext/RV64D/fmv.x.d.cgf new file mode 100644 index 000000000..2cc96bdc2 --- /dev/null +++ b/coverage/cgfs_fext/RV64D/fmv.x.d.cgf @@ -0,0 +1,92 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fmv.x.d_b1: + config: + - check ISA:=regex(.*RV64.*I.*D.*) + mnemonics: + fmv.x.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b1(flen,64, "fmv.x.d", 1)': 0 + +fmv.x.d_b22: + config: + - check ISA:=regex(.*RV64.*I.*D.*) + mnemonics: + fmv.x.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b22(flen,64, "fmv.x.d", 1)': 0 + +fmv.x.d_b23: + config: + - check ISA:=regex(.*RV64.*I.*D.*) + mnemonics: + fmv.x.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b23(flen,64, "fmv.x.d", 1)': 0 + +fmv.x.d_b24: + config: + - check ISA:=regex(.*RV64.*I.*D.*) + mnemonics: + fmv.x.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b24(flen,64, "fmv.x.d", 1)': 0 + +fmv.x.d_b27: + config: + - check ISA:=regex(.*RV64.*I.*D.*) + mnemonics: + fmv.x.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b27(flen,64, "fmv.x.d", 1)': 0 + +fmv.x.d_b28: + config: + - check ISA:=regex(.*RV64.*I.*D.*) + mnemonics: + fmv.x.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b28(flen,64, "fmv.x.d", 1)': 0 + +fmv.x.d_b29: + config: + - check ISA:=regex(.*RV64.*I.*D.*) + mnemonics: + fmv.x.d: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b29(flen,64, "fmv.x.d", 1)': 0 diff --git a/coverage/cgfs_fext/RV64F/fcvt.l.s.cgf b/coverage/cgfs_fext/RV64F/fcvt.l.s.cgf new file mode 100644 index 000000000..152ad7539 --- /dev/null +++ b/coverage/cgfs_fext/RV64F/fcvt.l.s.cgf @@ -0,0 +1,92 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fcvt.l.s_b1: + config: + - check ISA:=regex(.*RV64.*I.*F.*) + mnemonics: + fcvt.l.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fcvt.l.s", 1)': 0 + +fcvt.l.s_b22: + config: + - check ISA:=regex(.*RV64.*I.*F.*) + mnemonics: + fcvt.l.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b22(flen,32, "fcvt.l.s", 1)': 0 + +fcvt.l.s_b23: + config: + - check ISA:=regex(.*RV64.*I.*F.*) + mnemonics: + fcvt.l.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b23(flen,32, "fcvt.l.s", 1)': 0 + +fcvt.l.s_b24: + config: + - check ISA:=regex(.*RV64.*I.*F.*) + mnemonics: + fcvt.l.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b24(flen,32, "fcvt.l.s", 1)': 0 + +fcvt.l.s_b27: + config: + - check ISA:=regex(.*RV64.*I.*F.*) + mnemonics: + fcvt.l.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b27(flen,32, "fcvt.l.s", 1)': 0 + +fcvt.l.s_b28: + config: + - check ISA:=regex(.*RV64.*I.*F.*) + mnemonics: + fcvt.l.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b28(flen,32, "fcvt.l.s", 1)': 0 + +fcvt.l.s_b29: + config: + - check ISA:=regex(.*RV64.*I.*F.*) + mnemonics: + fcvt.l.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b29(flen,32, "fcvt.l.s", 1)': 0 diff --git a/coverage/cgfs_fext/RV64F/fcvt.lu.s.cgf b/coverage/cgfs_fext/RV64F/fcvt.lu.s.cgf new file mode 100644 index 000000000..544a79664 --- /dev/null +++ b/coverage/cgfs_fext/RV64F/fcvt.lu.s.cgf @@ -0,0 +1,92 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fcvt.lu.s_b1: + config: + - check ISA:=regex(.*RV64.*I.*F.*) + mnemonics: + fcvt.lu.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fcvt.lu.s", 1)': 0 + +fcvt.lu.s_b22: + config: + - check ISA:=regex(.*RV64.*I.*F.*) + mnemonics: + fcvt.lu.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b22(flen,32, "fcvt.lu.s", 1)': 0 + +fcvt.lu.s_b23: + config: + - check ISA:=regex(.*RV64.*I.*F.*) + mnemonics: + fcvt.lu.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b23(flen,32, "fcvt.lu.s", 1)': 0 + +fcvt.lu.s_b24: + config: + - check ISA:=regex(.*RV64.*I.*F.*) + mnemonics: + fcvt.lu.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b24(flen,32, "fcvt.lu.s", 1)': 0 + +fcvt.lu.s_b27: + config: + - check ISA:=regex(.*RV64.*I.*F.*) + mnemonics: + fcvt.lu.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b27(flen,32, "fcvt.lu.s", 1)': 0 + +fcvt.lu.s_b28: + config: + - check ISA:=regex(.*RV64.*I.*F.*) + mnemonics: + fcvt.lu.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b28(flen,32, "fcvt.lu.s", 1)': 0 + +fcvt.lu.s_b29: + config: + - check ISA:=regex(.*RV64.*I.*F.*) + mnemonics: + fcvt.lu.s: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b29(flen,32, "fcvt.lu.s", 1)': 0 diff --git a/coverage/cgfs_fext/RV64F/fcvt.s.l.cgf b/coverage/cgfs_fext/RV64F/fcvt.s.l.cgf new file mode 100644 index 000000000..e6eeebcee --- /dev/null +++ b/coverage/cgfs_fext/RV64F/fcvt.s.l.cgf @@ -0,0 +1,28 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fcvt.s.l_b25: + config: + - check ISA:=regex(.*RV64.*I.*F.*) + mnemonics: + fcvt.s.l: 0 + rs1: + <<: *all_regs + rd: + <<: *all_fregs + val_comb: + abstract_comb: + 'ibm_b25(flen,64, "fcvt.s.l", 1)': 0 + +fcvt.s.l_b26: + config: + - check ISA:=regex(.*RV64.*I.*F.*) + mnemonics: + fcvt.s.l: 0 + rs1: + <<: *all_regs + rd: + <<: *all_fregs + val_comb: + abstract_comb: + 'ibm_b26(64, "fcvt.s.l", 1)': 0 + diff --git a/coverage/cgfs_fext/RV64F/fcvt.s.lu.cgf b/coverage/cgfs_fext/RV64F/fcvt.s.lu.cgf new file mode 100644 index 000000000..4a23073de --- /dev/null +++ b/coverage/cgfs_fext/RV64F/fcvt.s.lu.cgf @@ -0,0 +1,28 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fcvt.s.lu_b25: + config: + - check ISA:=regex(.*RV64.*I.*F.*) + mnemonics: + fcvt.s.lu: 0 + rs1: + <<: *all_regs + rd: + <<: *all_fregs + val_comb: + abstract_comb: + 'ibm_b25(flen,64, "fcvt.s.lu", 1)': 0 + +fcvt.s.lu_b26: + config: + - check ISA:=regex(.*RV64.*I.*F.*) + mnemonics: + fcvt.s.lu: 0 + rs1: + <<: *all_regs + rd: + <<: *all_fregs + val_comb: + abstract_comb: + 'ibm_b26(64, "fcvt.s.lu", 1)': 0 + diff --git a/coverage/cgfs_fext/RV64H/rv64h_fcvt.h.l.cgf b/coverage/cgfs_fext/RV64H/rv64h_fcvt.h.l.cgf new file mode 100644 index 000000000..57e8900be --- /dev/null +++ b/coverage/cgfs_fext/RV64H/rv64h_fcvt.h.l.cgf @@ -0,0 +1,14 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fcvt.h.l_b25: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fcvt.h.l: 0 + rs1: + <<: *all_regs + rd: + <<: *all_fregs + val_comb: + abstract_comb: + 'ibm_b25(flen,64, "fcvt.h.l", 1)': 0 diff --git a/coverage/cgfs_fext/RV64H/rv64h_fcvt.h.lu.cgf b/coverage/cgfs_fext/RV64H/rv64h_fcvt.h.lu.cgf new file mode 100644 index 000000000..b079a5dac --- /dev/null +++ b/coverage/cgfs_fext/RV64H/rv64h_fcvt.h.lu.cgf @@ -0,0 +1,14 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fcvt.h.lu_b25: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + opcode: + fcvt.h.lu: 0 + rs1: + <<: *all_regs + rd: + <<: *all_fregs + val_comb: + abstract_comb: + 'ibm_b25(flen,64, "fcvt.h.lu", 1)': 0 diff --git a/coverage/cgfs_fext/RV64H/rv64h_fcvt.l.h.cgf b/coverage/cgfs_fext/RV64H/rv64h_fcvt.l.h.cgf new file mode 100644 index 000000000..7a3290cf0 --- /dev/null +++ b/coverage/cgfs_fext/RV64H/rv64h_fcvt.l.h.cgf @@ -0,0 +1,14 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fcvt.l.h_b1: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + mnemonics: + fcvt.l.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b1(flen,16, "fcvt.l.h", 1)': 0 diff --git a/coverage/cgfs_fext/RV64H/rv64h_fcvt.lu.h.cgf b/coverage/cgfs_fext/RV64H/rv64h_fcvt.lu.h.cgf new file mode 100644 index 000000000..1077ecddc --- /dev/null +++ b/coverage/cgfs_fext/RV64H/rv64h_fcvt.lu.h.cgf @@ -0,0 +1,14 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fcvt.lu.h_b1: + config: + - check ISA:=regex(.*I.*F.*Zfh.*) + mnemonics: + fcvt.lu.h: 0 + rs1: + <<: *all_fregs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b1(flen,16, "fcvt.lu.h", 1)': 0 diff --git a/coverage/cgfs_fext/RV64Zfinx/fadd.s.cgf b/coverage/cgfs_fext/RV64Zfinx/fadd.s.cgf new file mode 100644 index 000000000..a49a5ad07 --- /dev/null +++ b/coverage/cgfs_fext/RV64Zfinx/fadd.s.cgf @@ -0,0 +1,188 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fadd_b1: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fadd.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fadd.s", 2, True)': 0 + +fadd_b2: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fadd.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b2(flen,32, "fadd.s", 2, True)': 0 + +fadd_b3: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fadd.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b3(flen,32, "fadd.s", 2, True)': 0 + +fadd_b4: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fadd.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b4(flen,32, "fadd.s", 2, True)': 0 + +fadd_b5: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fadd.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b5(flen,32, "fadd.s", 2, True)': 0 + +fadd_b7: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fadd.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b7(flen,32, "fadd.s", 2, True)': 0 + +fadd_b8: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fadd.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b8(flen,32, "fadd.s", 2, True)': 0 + +fadd_b10: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fadd.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b10(flen,32, "fadd.s", 2, True)': 0 + +fadd_b11: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fadd.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b11(flen,32, "fadd.s", 2, True)': 0 + +fadd_b12: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fadd.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b12(flen,32, "fadd.s", 2, True)': 0 + +fadd_b13: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fadd.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b13(flen,32, "fadd.s", 2, True)': 0 diff --git a/coverage/cgfs_fext/RV64Zfinx/fclass.s.cgf b/coverage/cgfs_fext/RV64Zfinx/fclass.s.cgf new file mode 100644 index 000000000..61b12b714 --- /dev/null +++ b/coverage/cgfs_fext/RV64Zfinx/fclass.s.cgf @@ -0,0 +1,14 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fclass_b1: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fclass.s: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fclass.s", 1, True)': 0 diff --git a/coverage/cgfs_fext/RV64Zfinx/fcvt.l.s.cgf b/coverage/cgfs_fext/RV64Zfinx/fcvt.l.s.cgf new file mode 100644 index 000000000..23f0b7936 --- /dev/null +++ b/coverage/cgfs_fext/RV64Zfinx/fcvt.l.s.cgf @@ -0,0 +1,92 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fcvt.l.s_b1: + config: + - check ISA:=regex(.*RV64.*I.*Zfinx.*) + mnemonics: + fcvt.l.s: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fcvt.l.s", 1, True)': 0 + +fcvt.l.s_b22: + config: + - check ISA:=regex(.*RV64.*I.*Zfinx.*) + mnemonics: + fcvt.l.s: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b22(flen,32, "fcvt.l.s", 1, True)': 0 + +fcvt.l.s_b23: + config: + - check ISA:=regex(.*RV64.*I.*Zfinx.*) + mnemonics: + fcvt.l.s: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b23(flen,32, "fcvt.l.s", 1, True)': 0 + +fcvt.l.s_b24: + config: + - check ISA:=regex(.*RV64.*I.*Zfinx.*) + mnemonics: + fcvt.l.s: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b24(flen,32, "fcvt.l.s", 1, True)': 0 + +fcvt.l.s_b27: + config: + - check ISA:=regex(.*RV64.*I.*Zfinx.*) + mnemonics: + fcvt.l.s: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b27(flen,32, "fcvt.l.s", 1, True)': 0 + +fcvt.l.s_b28: + config: + - check ISA:=regex(.*RV64.*I.*Zfinx.*) + mnemonics: + fcvt.l.s: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b28(flen,32, "fcvt.l.s", 1, True)': 0 + +fcvt.l.s_b29: + config: + - check ISA:=regex(.*RV64.*I.*Zfinx.*) + mnemonics: + fcvt.l.s: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b29(flen,32, "fcvt.l.s", 1, True)': 0 diff --git a/coverage/cgfs_fext/RV64Zfinx/fcvt.lu.s.cgf b/coverage/cgfs_fext/RV64Zfinx/fcvt.lu.s.cgf new file mode 100644 index 000000000..6453ece25 --- /dev/null +++ b/coverage/cgfs_fext/RV64Zfinx/fcvt.lu.s.cgf @@ -0,0 +1,92 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fcvt.lu.s_b1: + config: + - check ISA:=regex(.*RV64.*I.*Zfinx.*) + mnemonics: + fcvt.lu.s: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fcvt.lu.s", 1, True)': 0 + +fcvt.lu.s_b22: + config: + - check ISA:=regex(.*RV64.*I.*Zfinx.*) + mnemonics: + fcvt.lu.s: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b22(flen,32, "fcvt.lu.s", 1, True)': 0 + +fcvt.lu.s_b23: + config: + - check ISA:=regex(.*RV64.*I.*Zfinx.*) + mnemonics: + fcvt.lu.s: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b23(flen,32, "fcvt.lu.s", 1, True)': 0 + +fcvt.lu.s_b24: + config: + - check ISA:=regex(.*RV64.*I.*Zfinx.*) + mnemonics: + fcvt.lu.s: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b24(flen,32, "fcvt.lu.s", 1, True)': 0 + +fcvt.lu.s_b27: + config: + - check ISA:=regex(.*RV64.*I.*Zfinx.*) + mnemonics: + fcvt.lu.s: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b27(flen,32, "fcvt.lu.s", 1, True)': 0 + +fcvt.lu.s_b28: + config: + - check ISA:=regex(.*RV64.*I.*Zfinx.*) + mnemonics: + fcvt.lu.s: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b28(flen,32, "fcvt.lu.s", 1, True)': 0 + +fcvt.lu.s_b29: + config: + - check ISA:=regex(.*RV64.*I.*Zfinx.*) + mnemonics: + fcvt.lu.s: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b29(flen,32, "fcvt.lu.s", 1, True)': 0 diff --git a/coverage/cgfs_fext/RV64Zfinx/fcvt.w.s.cgf b/coverage/cgfs_fext/RV64Zfinx/fcvt.w.s.cgf new file mode 100644 index 000000000..b00ad8abc --- /dev/null +++ b/coverage/cgfs_fext/RV64Zfinx/fcvt.w.s.cgf @@ -0,0 +1,92 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fcvt.w.s_b1: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fcvt.w.s: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fcvt.w.s", 1, True)': 0 + +fcvt.w.s_b22: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fcvt.w.s: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b22(flen,32, "fcvt.w.s", 1, True)': 0 + +fcvt.w.s_b23: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fcvt.w.s: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b23(flen,32, "fcvt.w.s", 1, True)': 0 + +fcvt.w.s_b24: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fcvt.w.s: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b24(flen,32, "fcvt.w.s", 1, True)': 0 + +fcvt.w.s_b27: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fcvt.w.s: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b27(flen,32, "fcvt.w.s", 1, True)': 0 + +fcvt.w.s_b28: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fcvt.w.s: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b28(flen,32, "fcvt.w.s", 1, True)': 0 + +fcvt.w.s_b29: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fcvt.w.s: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b29(flen,32, "fcvt.w.s", 1, True)': 0 diff --git a/coverage/cgfs_fext/RV64Zfinx/fcvt.wu.s.cgf b/coverage/cgfs_fext/RV64Zfinx/fcvt.wu.s.cgf new file mode 100644 index 000000000..ad4dec668 --- /dev/null +++ b/coverage/cgfs_fext/RV64Zfinx/fcvt.wu.s.cgf @@ -0,0 +1,92 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fcvt.wu.s_b1: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fcvt.wu.s: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fcvt.wu.s", 1, True)': 0 + +fcvt.wu.s_b22: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fcvt.wu.s: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b22(flen,32, "fcvt.wu.s", 1, True)': 0 + +fcvt.wu.s_b23: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fcvt.wu.s: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b23(flen,32, "fcvt.wu.s", 1, True)': 0 + +fcvt.wu.s_b24: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fcvt.wu.s: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b24(flen,32, "fcvt.wu.s", 1, True)': 0 + +fcvt.wu.s_b27: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fcvt.wu.s: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b27(flen,32, "fcvt.wu.s", 1, True)': 0 + +fcvt.wu.s_b28: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fcvt.wu.s: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b28(flen,32, "fcvt.wu.s", 1, True)': 0 + +fcvt.wu.s_b29: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fcvt.wu.s: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'ibm_b29(flen,32, "fcvt.wu.s", 1, True)': 0 diff --git a/coverage/cgfs_fext/RV64Zfinx/fdiv.s.cgf b/coverage/cgfs_fext/RV64Zfinx/fdiv.s.cgf new file mode 100644 index 000000000..20191510d --- /dev/null +++ b/coverage/cgfs_fext/RV64Zfinx/fdiv.s.cgf @@ -0,0 +1,188 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fdiv_b1: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fdiv.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fdiv.s", 2, True)': 0 + +fdiv_b2: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fdiv.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b2(flen,32, "fdiv.s", 2, True)': 0 + +fdiv_b3: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fdiv.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b3(flen,32, "fdiv.s", 2, True)': 0 + +fdiv_b4: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fdiv.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b4(flen,32, "fdiv.s", 2, True)': 0 + +fdiv_b5: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fdiv.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b5(flen,32, "fdiv.s", 2, True)': 0 + +fdiv_b6: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fdiv.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b6(flen,32, "fdiv.s", 2, True)': 0 + +fdiv_b7: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fdiv.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b7(flen,32, "fdiv.s", 2, True)': 0 + +fdiv_b8: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fdiv.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b8(flen,32, "fdiv.s", 2, True)': 0 + +fdiv_b9: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fdiv.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b9(flen,32, "fdiv.s", 2, True)': 0 + +fdiv_b20: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fdiv.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b20(flen,32, "fdiv.s", 2, True)': 0 + +fdiv_b21: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fdiv.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b21(flen,32, "fdiv.s", 2, True)': 0 diff --git a/coverage/cgfs_fext/RV64Zfinx/feq.s.cgf b/coverage/cgfs_fext/RV64Zfinx/feq.s.cgf new file mode 100644 index 000000000..abe30ff13 --- /dev/null +++ b/coverage/cgfs_fext/RV64Zfinx/feq.s.cgf @@ -0,0 +1,35 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +feq_b1: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + feq.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "feq.s", 2, True)': 0 + +feq_b19: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + feq.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b19(flen,32, "feq.s", 2, True)': 0 diff --git a/coverage/cgfs_fext/RV64Zfinx/fle.s.cgf b/coverage/cgfs_fext/RV64Zfinx/fle.s.cgf new file mode 100644 index 000000000..8ad88e5ee --- /dev/null +++ b/coverage/cgfs_fext/RV64Zfinx/fle.s.cgf @@ -0,0 +1,35 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fle_b1: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fle.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fle.s", 2, True)': 0 + +fle_b19: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fle.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b19(flen,32, "fle.s", 2, True)': 0 diff --git a/coverage/cgfs_fext/RV64Zfinx/flt.s.cgf b/coverage/cgfs_fext/RV64Zfinx/flt.s.cgf new file mode 100644 index 000000000..e947d2a25 --- /dev/null +++ b/coverage/cgfs_fext/RV64Zfinx/flt.s.cgf @@ -0,0 +1,35 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +flt_b1: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + flt.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "flt.s", 2, True)': 0 + +flt_b19: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + flt.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b19(flen, 32, "flt.s", 2, True)': 0 diff --git a/coverage/cgfs_fext/RV64Zfinx/fmadd.s.cgf b/coverage/cgfs_fext/RV64Zfinx/fmadd.s.cgf new file mode 100644 index 000000000..e44f02fd6 --- /dev/null +++ b/coverage/cgfs_fext/RV64Zfinx/fmadd.s.cgf @@ -0,0 +1,248 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fmadd_b1: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmadd.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fmadd.s", 3, True)': 0 + +fmadd_b2: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmadd.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b2(flen,32, "fmadd.s", 3, True)': 0 + +fmadd_b3: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmadd.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b3(flen,32, "fmadd.s", 3, True)': 0 + +fmadd_b4: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmadd.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b4(flen,32, "fmadd.s", 3, True)': 0 + +fmadd_b5: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmadd.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b5(flen,32, "fmadd.s", 3, True)': 0 + +fmadd_b6: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmadd.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b6(flen,32, "fmadd.s", 3, True)': 0 + +fmadd_b7: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmadd.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b7(flen,32, "fmadd.s", 3, True)': 0 + +fmadd_b8: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmadd.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b8(flen,32, "fmadd.s", 3, True)': 0 + +fmadd_b14: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmadd.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b14(flen,32, "fmadd.s", 3, True)': 0 + +fmadd_b15: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmadd.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b15(flen,32, "fmadd.s", 3, True)': 0 + +fmadd_b16: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmadd.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b16(flen,32, "fmadd.s", 3, True)': 0 + +fmadd_b17: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmadd.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b17(flen,32, "fmadd.s", 3, True)': 0 + +fmadd_b18: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmadd.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b18(flen,32, "fmadd.s", 3, True)': 0 \ No newline at end of file diff --git a/coverage/cgfs_fext/RV64Zfinx/fmax.s.cgf b/coverage/cgfs_fext/RV64Zfinx/fmax.s.cgf new file mode 100644 index 000000000..746931097 --- /dev/null +++ b/coverage/cgfs_fext/RV64Zfinx/fmax.s.cgf @@ -0,0 +1,35 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fmax_b1: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmax.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fmax.s", 2, True)': 0 + +fmax_b19: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmax.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b19(flen,32, "fmax.s", 2, True)': 0 diff --git a/coverage/cgfs_fext/RV64Zfinx/fmin.s.cgf b/coverage/cgfs_fext/RV64Zfinx/fmin.s.cgf new file mode 100644 index 000000000..fdbeeced9 --- /dev/null +++ b/coverage/cgfs_fext/RV64Zfinx/fmin.s.cgf @@ -0,0 +1,35 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fmin_b1: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmin.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fmin.s", 2, True)': 0 + +fmin_b19: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmin.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b19(flen,32, "fmin.s", 2, True)': 0 diff --git a/coverage/cgfs_fext/RV64Zfinx/fmsub.s.cgf b/coverage/cgfs_fext/RV64Zfinx/fmsub.s.cgf new file mode 100644 index 000000000..37f87d22d --- /dev/null +++ b/coverage/cgfs_fext/RV64Zfinx/fmsub.s.cgf @@ -0,0 +1,247 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore +fmsub_b1: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmsub.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fmsub.s", 3, True)': 0 + +fmsub_b2: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmsub.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b2(flen,32, "fmsub.s", 3, True)': 0 + +fmsub_b3: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmsub.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b3(flen,32, "fmsub.s", 3, True)': 0 + +fmsub_b4: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmsub.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b4(flen,32, "fmsub.s", 3, True)': 0 + +fmsub_b5: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmsub.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b5(flen,32, "fmsub.s", 3, True)': 0 + +fmsub_b6: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmsub.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b6(flen,32, "fmsub.s", 3, True)': 0 + +fmsub_b7: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmsub.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b7(flen,32, "fmsub.s", 3, True)': 0 + +fmsub_b8: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmsub.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b8(flen,32, "fmsub.s", 3, True)': 0 + +fmsub_b14: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmsub.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b14(flen,32, "fmsub.s", 3, True)': 0 + +fmsub_b15: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmsub.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b15(flen,32, "fmsub.s", 3, True)': 0 + +fmsub_b16: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmsub.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b16(flen,32, "fmsub.s", 3, True)': 0 + +fmsub_b17: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmsub.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b17(flen,32, "fmsub.s", 3, True)': 0 + +fmsub_b18: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmsub.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b18(flen,32, "fmsub.s", 3, True)': 0 \ No newline at end of file diff --git a/coverage/cgfs_fext/RV64Zfinx/fmul.s.cgf b/coverage/cgfs_fext/RV64Zfinx/fmul.s.cgf new file mode 100644 index 000000000..624f49ff4 --- /dev/null +++ b/coverage/cgfs_fext/RV64Zfinx/fmul.s.cgf @@ -0,0 +1,155 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fmul_b1: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmul.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fmul.s", 2, True)': 0 + +fmul_b2: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmul.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b2(flen,32, "fmul.s", 2, True)': 0 + +fmul_b3: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmul.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b3(flen,32, "fmul.s", 2, True)': 0 + +fmul_b4: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmul.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b4(flen,32, "fmul.s", 2, True)': 0 + +fmul_b5: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmul.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b5(flen,32, "fmul.s", 2, True)': 0 + +fmul_b6: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmul.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b6(flen,32, "fmul.s", 2, True)': 0 + +fmul_b7: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmul.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b7(flen,32, "fmul.s", 2, True)': 0 + +fmul_b8: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmul.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b8(flen,32, "fmul.s", 2, True)': 0 + +fmul_b9: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fmul.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b9(flen,32, "fmul.s", 2, True)': 0 + diff --git a/coverage/cgfs_fext/RV64Zfinx/fnmadd.s.cgf b/coverage/cgfs_fext/RV64Zfinx/fnmadd.s.cgf new file mode 100644 index 000000000..582b3c40b --- /dev/null +++ b/coverage/cgfs_fext/RV64Zfinx/fnmadd.s.cgf @@ -0,0 +1,247 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore +fnmadd_b1: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fnmadd.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fnmadd.s", 3, True)': 0 + +fnmadd_b2: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fnmadd.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b2(flen,32, "fnmadd.s", 3, True)': 0 + +fnmadd_b3: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fnmadd.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b3(flen,32, "fnmadd.s", 3, True)': 0 + +fnmadd_b4: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fnmadd.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b4(flen,32, "fnmadd.s", 3, True)': 0 + +fnmadd_b5: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fnmadd.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b5(flen,32, "fnmadd.s", 3, True)': 0 + +fnmadd_b6: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fnmadd.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b6(flen,32, "fnmadd.s", 3, True)': 0 + +fnmadd_b7: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fnmadd.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b7(flen,32, "fnmadd.s", 3, True)': 0 + +fnmadd_b8: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fnmadd.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b8(flen,32, "fnmadd.s", 3, True)': 0 + +fnmadd_b14: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fnmadd.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b14(flen,32, "fnmadd.s", 3, True)': 0 + +fnmadd_b15: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fnmadd.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b15(flen,32, "fnmadd.s", 3, True)': 0 + +fnmadd_b16: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fnmadd.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b16(flen,32, "fnmadd.s", 3, True)': 0 + +fnmadd_b17: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fnmadd.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b17(flen,32, "fnmadd.s", 3, True)': 0 + +fnmadd_b18: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fnmadd.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b18(flen,32, "fnmadd.s", 3, True)': 0 \ No newline at end of file diff --git a/coverage/cgfs_fext/RV64Zfinx/fnmsub.s.cgf b/coverage/cgfs_fext/RV64Zfinx/fnmsub.s.cgf new file mode 100644 index 000000000..73c7e3412 --- /dev/null +++ b/coverage/cgfs_fext/RV64Zfinx/fnmsub.s.cgf @@ -0,0 +1,247 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore +fnmsub_b1: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fnmsub.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fnmsub.s", 3, True)': 0 + +fnmsub_b2: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fnmsub.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b2(flen,32, "fnmsub.s", 3, True)': 0 + +fnmsub_b3: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fnmsub.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b3(flen,32, "fnmsub.s", 3, True)': 0 + +fnmsub_b4: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fnmsub.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b4(flen,32, "fnmsub.s", 3, True)': 0 + +fnmsub_b5: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fnmsub.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b5(flen,32, "fnmsub.s", 3, True)': 0 + +fnmsub_b6: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fnmsub.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b6(flen,32, "fnmsub.s", 3, True)': 0 + +fnmsub_b7: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fnmsub.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b7(flen,32, "fnmsub.s", 3, True)': 0 + +fnmsub_b8: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fnmsub.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b8(flen,32, "fnmsub.s", 3, True)': 0 + +fnmsub_b14: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fnmsub.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b14(flen,32, "fnmsub.s", 3, True)': 0 + +fnmsub_b15: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fnmsub.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b15(flen,32, "fnmsub.s", 3, True)': 0 + +fnmsub_b16: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fnmsub.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b16(flen,32, "fnmsub.s", 3, True)': 0 + +fnmsub_b17: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fnmsub.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b17(flen,32, "fnmsub.s", 3, True)': 0 + +fnmsub_b18: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fnmsub.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rs3: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *r4fmt_op_comb + val_comb: + abstract_comb: + 'ibm_b18(flen,32, "fnmsub.s", 3, True)': 0 \ No newline at end of file diff --git a/coverage/cgfs_fext/RV64Zfinx/fsgnj.s.cgf b/coverage/cgfs_fext/RV64Zfinx/fsgnj.s.cgf new file mode 100644 index 000000000..46a03b038 --- /dev/null +++ b/coverage/cgfs_fext/RV64Zfinx/fsgnj.s.cgf @@ -0,0 +1,19 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fsgnj_b1: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fsgnj.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fsgnj.s", 2, True)': 0 + diff --git a/coverage/cgfs_fext/RV64Zfinx/fsgnjn.s.cgf b/coverage/cgfs_fext/RV64Zfinx/fsgnjn.s.cgf new file mode 100644 index 000000000..81ae1f946 --- /dev/null +++ b/coverage/cgfs_fext/RV64Zfinx/fsgnjn.s.cgf @@ -0,0 +1,17 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore +fsgnjn_b1: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fsgnjn.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fsgnjn.s", 2, True)': 0 \ No newline at end of file diff --git a/coverage/cgfs_fext/RV64Zfinx/fsgnjx.s.cgf b/coverage/cgfs_fext/RV64Zfinx/fsgnjx.s.cgf new file mode 100644 index 000000000..bc84394df --- /dev/null +++ b/coverage/cgfs_fext/RV64Zfinx/fsgnjx.s.cgf @@ -0,0 +1,19 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fsgnjx_b1: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fsgnjx.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fsgnjx.s", 2, True)': 0 + diff --git a/coverage/cgfs_fext/RV64Zfinx/fsqrt.s.cgf b/coverage/cgfs_fext/RV64Zfinx/fsqrt.s.cgf new file mode 100644 index 000000000..bb3170fac --- /dev/null +++ b/coverage/cgfs_fext/RV64Zfinx/fsqrt.s.cgf @@ -0,0 +1,136 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fsqrt_b1: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fsqrt.s: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fsqrt.s", 1, True)': 0 + +fsqrt_b2: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fsqrt.s: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b2(flen,32, "fsqrt.s", 1, True)': 0 + +fsqrt_b3: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fsqrt.s: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b3(flen,32, "fsqrt.s", 1, True)': 0 + +fsqrt_b4: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fsqrt.s: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b4(flen,32, "fsqrt.s", 1, True)': 0 + +fsqrt_b5: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fsqrt.s: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b5(flen,32, "fsqrt.s", 1, True)': 0 + +fsqrt_b7: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fsqrt.s: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b7(flen,32, "fsqrt.s", 1, True)': 0 + +fsqrt_b8: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fsqrt.s: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b8(flen,32, "fsqrt.s", 1, True)': 0 + +fsqrt_b9: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fsqrt.s: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b9(flen,32, "fsqrt.s", 1, True)': 0 + +fsqrt_b20: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fsqrt.s: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'ibm_b20(flen,32, "fsqrt.s", 1, True)': 0 \ No newline at end of file diff --git a/coverage/cgfs_fext/RV64Zfinx/fsub.s.cgf b/coverage/cgfs_fext/RV64Zfinx/fsub.s.cgf new file mode 100644 index 000000000..0f5aa2d74 --- /dev/null +++ b/coverage/cgfs_fext/RV64Zfinx/fsub.s.cgf @@ -0,0 +1,188 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fsub_b1: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fsub.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b1(flen,32, "fsub.s", 2, True)': 0 + +fsub_b2: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fsub.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b2(flen,32, "fsub.s", 2, True)': 0 + +fsub_b3: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fsub.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b3(flen,32, "fsub.s", 2, True)': 0 + +fsub_b4: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fsub.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b4(flen,32, "fsub.s", 2, True)': 0 + +fsub_b5: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fsub.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b5(flen,32, "fsub.s", 2, True)': 0 + +fsub_b7: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fsub.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b7(flen,32, "fsub.s", 2, True)': 0 + +fsub_b8: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fsub.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b8(flen,32, "fsub.s", 2, True)': 0 + +fsub_b10: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fsub.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b10(flen,32, "fsub.s", 2, True)': 0 + +fsub_b11: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fsub.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b11(flen,32, "fsub.s", 2, True)': 0 + +fsub_b12: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fsub.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b12(flen,32, "fsub.s", 2, True)': 0 + +fsub_b13: + config: + - check ISA:=regex(.*I.*Zfinx.*) + mnemonics: + fsub.s: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'ibm_b13(flen,32, "fsub.s", 2, True)': 0 \ No newline at end of file diff --git a/coverage/rvi_cmo.cgf b/coverage/cmo/rvi_cmo.cgf similarity index 100% rename from coverage/rvi_cmo.cgf rename to coverage/cmo/rvi_cmo.cgf diff --git a/coverage/coverpoints.yaml b/coverage/coverpoints.yaml new file mode 100644 index 000000000..6472b78d8 --- /dev/null +++ b/coverage/coverpoints.yaml @@ -0,0 +1,1915 @@ +# For Licence details look at https://github.com/riscv-software-src/riscv-ctg/-/blob/master/LICENSE.incore + +datasets: + all_regs: &all_regs + x0: 0 + x1: 0 + x2: 0 + x3: 0 + x4: 0 + x5: 0 + x6: 0 + x7: 0 + x8: 0 + x9: 0 + x10: 0 + x11: 0 + x12: 0 + x13: 0 + x14: 0 + x15: 0 + x16: 0 + x17: 0 + x18: 0 + x19: 0 + x20: 0 + x21: 0 + x22: 0 + x23: 0 + x24: 0 + x25: 0 + x26: 0 + x27: 0 + x28: 0 + x29: 0 + x30: 0 + x31: 0 + + c_regs: &c_regs + x8: 0 + x9: 0 + x10: 0 + x11: 0 + x12: 0 + x13: 0 + x14: 0 + x15: 0 + + all_regs_mx0: &all_regs_mx0 + x1: 0 + x2: 0 + x3: 0 + x4: 0 + x5: 0 + x6: 0 + x7: 0 + x8: 0 + x9: 0 + x10: 0 + x11: 0 + x12: 0 + x13: 0 + x14: 0 + x15: 0 + x16: 0 + x17: 0 + x18: 0 + x19: 0 + x20: 0 + x21: 0 + x22: 0 + x23: 0 + x24: 0 + x25: 0 + x26: 0 + x27: 0 + x28: 0 + x29: 0 + x30: 0 + x31: 0 + + cbfmt_immval_sgn: &cbfmt_immval_sgn + 'imm_val == (-2**(6-1))': 0 + 'imm_val == 0': 0 + 'imm_val == (2**(6-1)-1)': 0 + 'imm_val == 1': 0 + + rfmt_op_comb: &rfmt_op_comb + 'rs1 == rs2 != rd': 0 + 'rs1 == rd != rs2': 0 + 'rs2 == rd != rs1': 0 + 'rs1 == rs2 == rd': 0 + 'rs1 != rs2 and rs1 != rd and rs2 != rd': 0 + + ifmt_op_comb: &ifmt_op_comb + 'rs1 == rd': 0 + 'rs1 != rd': 0 + + sfmt_op_comb: &sfmt_op_comb + 'rs1 == rs2': 0 + 'rs1 != rs2': 0 + + base_rs1val_sgn: &base_rs1val_sgn + 'rs1_val == (-2**(xlen-1))': 0 + 'rs1_val == 0': 0 + 'rs1_val == (2**(xlen-1)-1)': 0 + 'rs1_val == 1': 0 + + base_rs2val_sgn: &base_rs2val_sgn + 'rs2_val == (-2**(xlen-1))': 0 + 'rs2_val == 0': 0 + 'rs2_val == (2**(xlen-1)-1)': 0 + 'rs2_val == 1': 0 + + base_rs1val_unsgn: &base_rs1val_unsgn + 'rs1_val == 0': 0 + 'rs1_val == (2**(xlen)-1)': 0 + 'rs1_val == 1': 0 + + base_rs2val_unsgn: &base_rs2val_unsgn + 'rs2_val == 0': 0 + 'rs2_val == (2**(xlen)-1)': 0 + 'rs2_val == 1': 0 + + rfmt_val_comb_sgn: &rfmt_val_comb_sgn + 'rs1_val > 0 and rs2_val > 0': 0 + 'rs1_val > 0 and rs2_val < 0': 0 + 'rs1_val < 0 and rs2_val < 0': 0 + 'rs1_val < 0 and rs2_val > 0': 0 + 'rs1_val == rs2_val': 0 + 'rs1_val != rs2_val': 0 + + rfmt_val_comb_unsgn: &rfmt_val_comb_unsgn + 'rs1_val > 0 and rs2_val > 0': 0 + 'rs1_val == rs2_val and rs1_val > 0 and rs2_val > 0': 0 + 'rs1_val != rs2_val and rs1_val > 0 and rs2_val > 0': 0 + + ifmt_val_comb_sgn: &ifmt_val_comb_sgn + 'rs1_val == imm_val': 0 + 'rs1_val != imm_val': 0 + 'rs1_val > 0 and imm_val > 0': 0 + 'rs1_val > 0 and imm_val < 0': 0 + 'rs1_val < 0 and imm_val > 0': 0 + 'rs1_val < 0 and imm_val < 0': 0 + + ifmt_val_comb_unsgn: &ifmt_val_comb_unsgn + 'rs1_val == imm_val and rs1_val > 0 and imm_val > 0': 0 + 'rs1_val != imm_val and rs1_val > 0 and imm_val > 0': 0 + + ifmt_base_immval_sgn: &ifmt_base_immval_sgn + 'imm_val == (-2**(12-1))': 0 + 'imm_val == 0': 0 + 'imm_val == (2**(12-1)-1)': 0 + 'imm_val == 1': 0 + + ifmt_base_immval_unsgn: &ifmt_base_immval_unsgn + 'imm_val == 0': 0 + 'imm_val == (2**(12)-1)': 0 + 'imm_val == 1': 0 + + ifmt_base_shift: &ifmt_base_shift + 'rs1_val < 0 and imm_val > 0 and imm_val < xlen': 0 + 'rs1_val > 0 and imm_val > 0 and imm_val < xlen': 0 + 'rs1_val < 0 and imm_val == 0': 0 + 'rs1_val > 0 and imm_val == 0': 0 + 'rs1_val < 0 and imm_val == (xlen-1)': 0 + 'rs1_val > 0 and imm_val == (xlen-1)': 0 + 'rs1_val == imm_val and imm_val > 0 and imm_val < xlen': 0 + 'rs1_val == (-2**(xlen-1)) and imm_val >= 0 and imm_val < xlen': 0 + 'rs1_val == 0 and imm_val >= 0 and imm_val < xlen': 0 + 'rs1_val == (2**(xlen-1)-1) and imm_val >= 0 and imm_val < xlen': 0 + 'rs1_val == 1 and imm_val >= 0 and imm_val < xlen': 0 + + ifmt_base_shift_32w: &ifmt_base_shift_32w + 'rs1_val < 0 and imm_val > 0 and imm_val < 32': 0 + 'rs1_val > 0 and imm_val > 0 and imm_val < 32': 0 + 'rs1_val < 0 and imm_val == 0': 0 + 'rs1_val > 0 and imm_val == 0': 0 + 'rs1_val < 0 and imm_val == 31': 0 + 'rs1_val > 0 and imm_val == 31': 0 + 'rs1_val == imm_val and imm_val > 0 and imm_val < 32': 0 + 'rs1_val == (-2**(xlen-1)) and imm_val >= 0 and imm_val < 32': 0 + 'rs1_val == 0 and imm_val >= 0 and imm_val < 32': 0 + 'rs1_val == (2**(xlen-1)-1) and imm_val >= 0 and imm_val < 32': 0 + 'rs1_val == 1 and imm_val >= 0 and imm_val < 32': 0 + + + rfmt_base_shift: &rfmt_base_shift + 'rs1_val < 0 and rs2_val > 0 and rs2_val < xlen': 0 + 'rs1_val > 0 and rs2_val > 0 and rs2_val < xlen': 0 + 'rs1_val < 0 and rs2_val == 0': 0 + 'rs1_val > 0 and rs2_val == 0': 0 + 'rs1_val == rs2_val and rs2_val > 0 and rs2_val < xlen': 0 + 'rs1_val == (-2**(xlen-1)) and rs2_val >= 0 and rs2_val < xlen': 0 + 'rs1_val == 0 and rs2_val >= 0 and rs2_val < xlen': 0 + 'rs1_val == (2**(xlen-1)-1) and rs2_val >= 0 and rs2_val < xlen': 0 + 'rs1_val == 1 and rs2_val >= 0 and rs2_val < xlen': 0 + + bfmt_base_branch_val_align_sgn: &bfmt_base_branch_val_align_sgn + 'rs1_val > 0 and rs2_val > 0 and imm_val & 0x03 == 0': 0 + 'rs1_val > 0 and rs2_val < 0 and imm_val & 0x03 == 0': 0 + 'rs1_val < 0 and rs2_val < 0 and imm_val & 0x03 == 0': 0 + 'rs1_val < 0 and rs2_val > 0 and imm_val & 0x03 == 0': 0 + 'rs1_val == rs2_val and imm_val > 0 and imm_val & 0x03 == 0': 0 + 'rs1_val == rs2_val and imm_val < 0 and imm_val & 0x03 == 0': 0 + 'rs1_val > rs2_val and imm_val > 0 and imm_val & 0x03 == 0': 0 + 'rs1_val > rs2_val and imm_val < 0 and imm_val & 0x03 == 0': 0 + 'rs1_val < rs2_val and imm_val > 0 and imm_val & 0x03 == 0': 0 + 'rs1_val < rs2_val and imm_val < 0 and imm_val & 0x03 == 0': 0 + + bfmt_base_branch_val_align_unsgn: &bfmt_base_branch_val_align_unsgn + 'rs1_val > 0 and rs2_val > 0': 0 + 'rs1_val > 0 and rs2_val > 0 and rs1_val == rs2_val and imm_val > 0': 0 + 'rs1_val > 0 and rs2_val > 0 and rs1_val == rs2_val and imm_val < 0': 0 + 'rs1_val > 0 and rs2_val > 0 and rs1_val > rs2_val and imm_val > 0 ': 0 + 'rs1_val > 0 and rs2_val > 0 and rs1_val > rs2_val and imm_val < 0 ': 0 + 'rs1_val > 0 and rs2_val > 0 and rs1_val < rs2_val and imm_val > 0 ': 0 + 'rs1_val > 0 and rs2_val > 0 and rs1_val < rs2_val and imm_val < 0 ': 0 + + rs1val_walking: &rs1val_walking + 'walking_ones("rs1_val", xlen)': 0 + 'walking_zeros("rs1_val", xlen)': 0 + 'alternate("rs1_val",xlen)': 0 + + rs2val_walking: &rs2val_walking + 'walking_ones("rs2_val", xlen)': 0 + 'walking_zeros("rs2_val", xlen)': 0 + 'alternate("rs2_val",xlen)': 0 + + rs3val_walking: &rs3val_walking + 'walking_ones("rs3_val", xlen)': 0 + 'walking_zeros("rs3_val", xlen)': 0 + 'alternate("rs3_val",xlen)': 0 + + ifmt_immval_walking: &ifmt_immval_walking + 'walking_ones("imm_val", 12)': 0 + 'walking_zeros("imm_val", 12)': 0 + 'alternate("imm_val",12)': 0 + + rs1val_walking_unsgn: &rs1val_walking_unsgn + 'walking_ones("rs1_val", xlen,False)': 0 + 'walking_zeros("rs1_val", xlen,False)': 0 + 'alternate("rs1_val",xlen,False)': 0 + + rs2val_walking_unsgn: &rs2val_walking_unsgn + 'walking_ones("rs2_val", xlen,False)': 0 + 'walking_zeros("rs2_val", xlen,False)': 0 + 'alternate("rs2_val",xlen,False)': 0 + + crfmt_val_comb_sgn: &crfmt_val_comb_sgn + 'rs2_val > 0': 0 + 'rs2_val < 0': 0 + + cbimm_val_walking: &cbimm_val_walking + 'walking_ones("imm_val", 6)': 0 + 'walking_zeros("imm_val", 6)': 0 + 'alternate("imm_val",6)': 0 + + ifmt_immval_walking_unsgn: &ifmt_immval_walking_unsgn + 'walking_ones("imm_val", 12,False)': 0 + 'walking_zeros("imm_val", 12,False)': 0 + 'alternate("imm_val",12,False)': 0 + +caddi4spn: + config: check ISA:=regex(.*I.*C.*) + opcode: + c.addi4spn: 0 + rd: + <<: *c_regs + val_comb: + 'imm_val > 0' : 0 + 'imm_val == 1020': 0 + abstract_comb: + 'walking_ones("imm_val", 8,False,scale_func = lambda x: x*4)': 0 + 'walking_zeros("imm_val", 8,False,scale_func = lambda x: x*4)': 0 + 'alternate("imm_val",8,False,scale_func = lambda x: x*4)': 0 + +clw: + config: check ISA:=regex(.*I.*C.*) + opcode: + c.lw: 0 + rs1: + <<: *c_regs + rd: + <<: *c_regs + op_comb: + 'rs1 == rd': 0 + 'rs1 != rd': 0 + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + abstract_comb: + 'walking_ones("imm_val",5,False, scale_func = lambda x: x*4)': 0 + 'walking_zeros("imm_val",5,False, scale_func = lambda x: x*4)': 0 + 'alternate("imm_val",5, False,scale_func = lambda x: x*4)': 0 + +cld: + config: check ISA:=regex(.*RV64.*I.*C.*) + opcode: + c.ld: 0 + rs1: + <<: *c_regs + rd: + <<: *c_regs + op_comb: + 'rs1 == rd': 0 + 'rs1 != rd': 0 + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + abstract_comb: + 'walking_ones("imm_val",5,False, scale_func = lambda x: x*8)': 0 + 'walking_zeros("imm_val",5,False, scale_func = lambda x: x*8)': 0 + 'alternate("imm_val",5, False,scale_func = lambda x: x*8)': 0 + +csw: + config: check ISA:=regex(.*I.*C.*) + opcode: + c.sw: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + 'rs1 != rs2': 0 + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + <<: [ *base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + 'walking_ones("imm_val",5,False, scale_func = lambda x: x*4)': 0 + 'walking_zeros("imm_val",5,False, scale_func = lambda x: x*4)': 0 + 'alternate("imm_val",5, False,scale_func = lambda x: x*4)': 0 + +csd: + config: check ISA:=regex(.*RV64.*I.*C.*) + opcode: + c.sd: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + 'rs1 != rs2': 0 + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + <<: [ *base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + 'walking_ones("imm_val",5,False, scale_func = lambda x: x*8)': 0 + 'walking_zeros("imm_val",5,False, scale_func = lambda x: x*8)': 0 + 'alternate("imm_val",5, False,scale_func = lambda x: x*8)': 0 + +cnop: + config: check ISA:=regex(.*I.*C.*) + opcode: + c.nop: 0 + val_comb: + abstract_comb: + <<: *cbimm_val_walking + +caddi: + config: check ISA:=regex(.*I.*C.*) + opcode: + c.addi: 0 + rd: + <<: *all_regs_mx0 + val_comb: + <<: [*base_rs1val_sgn, *cbfmt_immval_sgn, *ifmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *cbimm_val_walking] + +cjal: + config: check ISA:=regex(.*RV32.*I.*C.*) + opcode: + c.jal: 0 + val_comb: + 'imm_val > 0': 0 + 'imm_val < 0': 0 + abstract_comb: + 'walking_ones("imm_val", 11,fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030),scale_func = lambda x: x*2)': 0 + 'walking_zeros("imm_val", 11,fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030),scale_func = lambda x: x*2)': 0 + 'alternate("imm_val",11, fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030) ,scale_func = lambda x: x*2)': 0 + +caddiw: + config: check ISA:=regex(.*RV64.*I.*C.*) + opcode: + c.addiw: 0 + rd: + <<: *all_regs_mx0 + val_comb: + 'rs1_val == (-2**(xlen-1))': 0 + 'rs1_val == 0': 0 + 'rs1_val == (2**(xlen-1)-1)': 0 + 'rs1_val == 1': 0 + <<: [*cbfmt_immval_sgn, *ifmt_val_comb_sgn] + abstract_comb: + 'walking_ones("rs1_val", xlen)': 0 + 'walking_zeros("rs1_val", xlen)': 0 + 'alternate("rs1_val",xlen)': 0 + <<: [*cbimm_val_walking] + +cli: + config: check ISA:=regex(.*I.*C.*) + opcode: + c.li: 0 + rd: + <<: *all_regs + val_comb: + <<: [*cbfmt_immval_sgn] + abstract_comb: + 'walking_ones("imm_val", 6)': 0 + 'walking_zeros("imm_val", 6)': 0 + 'alternate("imm_val", 6)': 0 + +caddi16sp: + config: check ISA:=regex(.*I.*C.*) + opcode: + c.addi16sp: 0 + rd: + x2: 0 + val_comb: + <<: [*base_rs1val_sgn,*ifmt_val_comb_sgn] + 'imm_val == -512': 0 + 'imm_val == 496': 0 + abstract_comb: + <<: [*rs1val_walking] + 'walking_ones("imm_val", 6,True,scale_func = lambda x: x*16)': 0 + 'walking_zeros("imm_val", 6,True,scale_func = lambda x: x*16)': 0 + 'alternate("imm_val",6,True,scale_func = lambda x: x*16)': 0 + +clui: + config: check ISA:=regex(.*I.*C.*) + opcode: + c.lui: 0 + rd: + x0: 0 + x1: 0 + x3: 0 + x4: 0 + x5: 0 + x6: 0 + x7: 0 + x8: 0 + x9: 0 + x10: 0 + x11: 0 + x12: 0 + x13: 0 + x14: 0 + x15: 0 + x16: 0 + x17: 0 + x18: 0 + x19: 0 + x20: 0 + x21: 0 + x22: 0 + x23: 0 + x24: 0 + x25: 0 + x26: 0 + x27: 0 + x28: 0 + x29: 0 + x30: 0 + x31: 0 + + val_comb: + 'rs1_val > 0 and imm_val > 32': 0 + 'rs1_val > 0 and imm_val < 32 and imm_val !=0 ': 0 + 'rs1_val < 0 and imm_val > 32': 0 + 'rs1_val < 0 and imm_val < 32 and imm_val !=0 ': 0 + abstract_comb: + 'walking_ones("imm_val", 6, False)': 0 + 'walking_zeros("imm_val", 6, False)': 0 + 'alternate("imm_val", 6, False)': 0 + +csrli: + config: check ISA:=regex(.*I.*C.*) + opcode: + c.srli: 0 + rs1: + <<: *c_regs + val_comb: + 'rs1_val < 0 and imm_val < xlen': 0 + 'rs1_val > 0 and imm_val < xlen': 0 + 'rs1_val == imm_val and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == (-2**(xlen-1)) and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == 0 and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == (2**(xlen-1)-1) and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == 1 and imm_val != 0 and imm_val < xlen': 0 + abstract_comb: + <<: [*rs1val_walking] + 'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0 + 'alternate("imm_val", ceil(log(xlen,2)), False)': 0 + +csrai: + config: check ISA:=regex(.*I.*C.*) + opcode: + c.srai: 0 + rs1: + <<: *c_regs + val_comb: + 'rs1_val < 0 and imm_val < xlen': 0 + 'rs1_val > 0 and imm_val < xlen': 0 + 'rs1_val == imm_val and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == (-2**(xlen-1)) and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == 0 and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == (2**(xlen-1)-1) and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == 1 and imm_val != 0 and imm_val < xlen': 0 + abstract_comb: + <<: [*rs1val_walking] + 'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0 + 'alternate("imm_val", ceil(log(xlen,2)), False)': 0 + +candi: + config: check ISA:=regex(.*I.*C.*) + opcode: + c.andi: 0 + rs1: + <<: *c_regs + val_comb: + <<: [*base_rs1val_sgn,*cbfmt_immval_sgn,*ifmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *cbimm_val_walking] + +csub: + config: check ISA:=regex(.*I.*C.*) + opcode: + c.sub: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*crfmt_val_comb_sgn, *base_rs1val_sgn, *base_rs2val_sgn] + abstract_comb: + <<: [*rs1val_walking,*rs2val_walking] + +cxor: + config: check ISA:=regex(.*I.*C.*) + opcode: + c.xor: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*crfmt_val_comb_sgn, *base_rs1val_sgn, *base_rs2val_sgn] + abstract_comb: + <<: [*rs1val_walking,*rs2val_walking] + +cor: + config: check ISA:=regex(.*I.*C.*) + opcode: + c.or: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*crfmt_val_comb_sgn, *base_rs1val_sgn,*base_rs2val_sgn] + abstract_comb: + <<: [*rs1val_walking,*rs2val_walking] + +cand: + config: check ISA:=regex(.*I.*C.*) + opcode: + c.and: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*crfmt_val_comb_sgn, *base_rs1val_sgn,*base_rs2val_sgn] + abstract_comb: + <<: [*rs1val_walking,*rs2val_walking] + +csubw: + config: check ISA:=regex(.*RV64.*I.*C.*) + opcode: + c.subw: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*crfmt_val_comb_sgn, *base_rs1val_sgn, *base_rs2val_sgn] + abstract_comb: + <<: [*rs1val_walking,*rs2val_walking] + +caddw: + config: check ISA:=regex(.*RV64.*I.*C.*) + opcode: + c.addw: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*crfmt_val_comb_sgn, *base_rs1val_sgn, *base_rs2val_sgn] + abstract_comb: + <<: [*rs1val_walking,*rs2val_walking] + +cj: + config: check ISA:=regex(.*I.*C.*) + opcode: + c.j: 0 + val_comb: + 'imm_val > 0': 0 + 'imm_val < 0': 0 + abstract_comb: + 'walking_ones("imm_val", 11,fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030),scale_func = lambda x: x*2)': 0 + 'walking_zeros("imm_val", 11,fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030),scale_func = lambda x: x*2)': 0 + 'alternate("imm_val",11, fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030) ,scale_func = lambda x: x*2)': 0 + +cbeqz: + config: check ISA:=regex(.*I.*C.*) + opcode: + c.beqz: 0 + rs1: + <<: *c_regs + val_comb: + 'rs1_val > 0 and imm_val > 0': 0 + 'rs1_val < 0 and imm_val > 0': 0 + 'rs1_val == 0 and imm_val > 0': 0 + 'rs1_val > 0 and imm_val < 0': 0 + 'rs1_val < 0 and imm_val < 0': 0 + 'rs1_val == 0 and imm_val < 0': 0 + <<: [*base_rs1val_sgn] + abstract_comb: + <<: [*rs1val_walking] + +cbnez: + config: check ISA:=regex(.*I.*C.*) + opcode: + c.bnez: 0 + rs1: + <<: *c_regs + val_comb: + 'rs1_val > 0 and imm_val > 0': 0 + 'rs1_val < 0 and imm_val > 0': 0 + 'rs1_val == 0 and imm_val > 0': 0 + 'rs1_val > 0 and imm_val < 0': 0 + 'rs1_val < 0 and imm_val < 0': 0 + 'rs1_val == 0 and imm_val < 0': 0 + <<: [*base_rs1val_sgn] + abstract_comb: + <<: [*rs1val_walking] + +cslli: + config: check ISA:=regex(.*I.*C.*) + opcode: + c.slli: 0 + rd: + <<: *c_regs + val_comb: + 'rs1_val < 0 and imm_val < xlen': 0 + 'rs1_val > 0 and imm_val < xlen': 0 + 'rs1_val == imm_val and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == (-2**(xlen-1)) and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == 0 and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == (2**(xlen-1)-1) and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == 1 and imm_val != 0 and imm_val < xlen': 0 + abstract_comb: + <<: [*rs1val_walking] + 'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0 + 'alternate("imm_val", ceil(log(xlen,2)), False)': 0 + +clwsp: + config: check ISA:=regex(.*I.*C.*) + opcode: + c.lwsp: 0 + rd: + <<: *all_regs_mx0 + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + abstract_comb: + 'walking_ones("imm_val",6,False, scale_func = lambda x: x*4)': 0 + 'walking_zeros("imm_val",6,False, scale_func = lambda x: x*4)': 0 + 'alternate("imm_val",6, False,scale_func = lambda x: x*4)': 0 + +cldsp: + config: check ISA:=regex(.*RV64.*I.*C.*) + opcode: + c.ldsp: 0 + rd: + <<: *all_regs_mx0 + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + abstract_comb: + 'walking_ones("imm_val",6,False, scale_func = lambda x: x*8)': 0 + 'walking_zeros("imm_val",6,False, scale_func = lambda x: x*8)': 0 + 'alternate("imm_val",6, False,scale_func = lambda x: x*8)': 0 + +cjr: + config: check ISA:=regex(.*I.*C.*) + opcode: + c.jr: 0 + rs1: + <<: *all_regs_mx0 + +cmv: + config: check ISA:=regex(.*I.*C.*) + opcode: + c.mv: 0 + rs2: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + 'rs2 == rd and rs2 != 0': 0 + 'rs2 != rd and rs2 != 0': 0 + val_comb: + <<: [*base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +cadd: + config: check ISA:=regex(.*I.*C.*) + opcode: + c.add: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs_mx0 + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*crfmt_val_comb_sgn, *base_rs1val_sgn,*base_rs2val_sgn] + abstract_comb: + <<: [*rs1val_walking,*rs2val_walking] + +cjalr: + config: check ISA:=regex(.*I.*C.*) + opcode: + c.jalr: 0 + rs1: + <<: *all_regs_mx0 + +cswsp: + config: check ISA:=regex(.*I.*C.*) + opcode: + c.swsp: 0 + rs2: + <<: *all_regs + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + <<: [ *base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + 'walking_ones("imm_val",6,False, scale_func = lambda x: x*4)': 0 + 'walking_zeros("imm_val",6,False, scale_func = lambda x: x*4)': 0 + 'alternate("imm_val",6, False,scale_func = lambda x: x*4)': 0 + +csdsp: + config: check ISA:=regex(.*RV64.*I.*C.*) + opcode: + c.sdsp: 0 + rs2: + <<: *all_regs + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + <<: [ *base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + 'walking_ones("imm_val",6,False, scale_func = lambda x: x*8)': 0 + 'walking_zeros("imm_val",6,False, scale_func = lambda x: x*8)': 0 + 'alternate("imm_val",6, False,scale_func = lambda x: x*8)': 0 + +addi: + config: check ISA:=regex(.*I.*) + opcode: + addi: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [ *ifmt_val_comb_sgn, *base_rs1val_sgn, *ifmt_base_immval_sgn] + abstract_comb: + <<: [*rs1val_walking, *ifmt_immval_walking] + +slti: + config: check ISA:=regex(.*I.*) + opcode: + slti: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [*ifmt_val_comb_sgn , *base_rs1val_sgn , *ifmt_base_immval_sgn] + abstract_comb: + <<: [*rs1val_walking, *ifmt_immval_walking] + +sltiu: + config: check ISA:=regex(.*I.*) + opcode: + sltiu: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [*ifmt_val_comb_unsgn , *base_rs1val_unsgn , *ifmt_base_immval_unsgn] + abstract_comb: + <<: [*rs1val_walking_unsgn, *ifmt_immval_walking_unsgn] + +andi: + config: check ISA:=regex(.*I.*) + opcode: + andi: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [*ifmt_val_comb_sgn , *base_rs1val_sgn , *ifmt_base_immval_sgn] + abstract_comb: + <<: [*rs1val_walking, *ifmt_immval_walking] + +ori: + config: check ISA:=regex(.*I.*) + opcode: + ori: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [*ifmt_val_comb_sgn , *base_rs1val_sgn , *ifmt_base_immval_sgn] + abstract_comb: + <<: [*rs1val_walking, *ifmt_immval_walking] + +xori: + config: check ISA:=regex(.*I.*) + opcode: + xori: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [*ifmt_val_comb_sgn , *base_rs1val_sgn , *ifmt_base_immval_sgn] + abstract_comb: + <<: [*rs1val_walking, *ifmt_immval_walking] + +slli: + config: check ISA:=regex(.*I.*) + opcode: + slli: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: *ifmt_base_shift + abstract_comb: + <<: [*rs1val_walking] + 'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0 + 'alternate("imm_val", ceil(log(xlen,2)), False)': 0 + +srai: + config: check ISA:=regex(.*I.*) + opcode: + srai: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: *ifmt_base_shift + abstract_comb: + <<: [*rs1val_walking] + 'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0 + 'alternate("imm_val", ceil(log(xlen,2)), False)': 0 + +srli: + config: check ISA:=regex(.*I.*) + opcode: + srli: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: *ifmt_base_shift + abstract_comb: + <<: [*rs1val_walking] + 'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0 + 'alternate("imm_val", ceil(log(xlen,2)), False)': 0 + +add: + config: check ISA:=regex(.*I.*) + opcode: + add: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +sub: + config: check ISA:=regex(.*I.*) + opcode: + sub: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +slt: + config: check ISA:=regex(.*I.*) + opcode: + slt: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +sltu: + config: check ISA:=regex(.*I.*) + opcode: + sltu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + +and: + config: check ISA:=regex(.*I.*) + opcode: + and: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +or: + config: check ISA:=regex(.*I.*) + opcode: + or: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +xor: + config: check ISA:=regex(.*I.*) + opcode: + xor: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +sll: + config: check ISA:=regex(.*I.*) + opcode: + sll: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: *rfmt_base_shift + abstract_comb: + <<: [*rs1val_walking] + 'walking_ones("rs2_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("rs2_val", ceil(log(xlen,2)), False)': 0 + 'alternate("rs2_val", ceil(log(xlen,2)), False)': 0 + +srl: + config: check ISA:=regex(.*I.*) + opcode: + srl: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: *rfmt_base_shift + abstract_comb: + <<: [*rs1val_walking] + 'walking_ones("rs2_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("rs2_val", ceil(log(xlen,2)), False)': 0 + 'alternate("rs2_val", ceil(log(xlen,2)), False)': 0 + +sra: + config: check ISA:=regex(.*I.*) + opcode: + sra: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: *rfmt_base_shift + abstract_comb: + <<: [*rs1val_walking] + 'walking_ones("rs2_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("rs2_val", ceil(log(xlen,2)), False)': 0 + 'alternate("rs2_val", ceil(log(xlen,2)), False)': 0 + +beq: + config: check ISA:=regex(.*I.*) + opcode: + beq: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *bfmt_base_branch_val_align_sgn + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +bge: + config: check ISA:=regex(.*I.*) + opcode: + bge: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *bfmt_base_branch_val_align_sgn + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +bgeu: + config: check ISA:=regex(.*I.*) + opcode: + bgeu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *bfmt_base_branch_val_align_unsgn + abstract_comb: + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + +blt: + config: check ISA:=regex(.*I.*) + opcode: + blt: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *bfmt_base_branch_val_align_sgn + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +bltu: + config: check ISA:=regex(.*I.*) + opcode: + bltu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *bfmt_base_branch_val_align_unsgn + abstract_comb: + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + +bne: + config: check ISA:=regex(.*I.*) + opcode: + bne: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *bfmt_base_branch_val_align_sgn + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +lhu-align: + config: check ISA:=regex(.*I.*) + opcode: + lhu: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'ea_align == 2 and (imm_val % 4) == 0': 0 + 'ea_align == 2 and (imm_val % 4) == 1': 0 + 'ea_align == 2 and (imm_val % 4) == 2': 0 + 'ea_align == 2 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + +lh-align: + config: check ISA:=regex(.*I.*) + opcode: + lh: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'ea_align == 2 and (imm_val % 4) == 0': 0 + 'ea_align == 2 and (imm_val % 4) == 1': 0 + 'ea_align == 2 and (imm_val % 4) == 2': 0 + 'ea_align == 2 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + +lbu-align: + config: check ISA:=regex(.*I.*) + opcode: + lbu: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'ea_align == 2 and (imm_val % 4) == 0': 0 + 'ea_align == 2 and (imm_val % 4) == 1': 0 + 'ea_align == 2 and (imm_val % 4) == 2': 0 + 'ea_align == 2 and (imm_val % 4) == 3': 0 + 'ea_align == 1 and (imm_val % 4) == 0': 0 + 'ea_align == 1 and (imm_val % 4) == 1': 0 + 'ea_align == 1 and (imm_val % 4) == 2': 0 + 'ea_align == 1 and (imm_val % 4) == 3': 0 + 'ea_align == 3 and (imm_val % 4) == 0': 0 + 'ea_align == 3 and (imm_val % 4) == 1': 0 + 'ea_align == 3 and (imm_val % 4) == 2': 0 + 'ea_align == 3 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + +lb-align: + config: check ISA:=regex(.*I.*) + opcode: + lb: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'ea_align == 2 and (imm_val % 4) == 0': 0 + 'ea_align == 2 and (imm_val % 4) == 1': 0 + 'ea_align == 2 and (imm_val % 4) == 2': 0 + 'ea_align == 2 and (imm_val % 4) == 3': 0 + 'ea_align == 1 and (imm_val % 4) == 0': 0 + 'ea_align == 1 and (imm_val % 4) == 1': 0 + 'ea_align == 1 and (imm_val % 4) == 2': 0 + 'ea_align == 1 and (imm_val % 4) == 3': 0 + 'ea_align == 3 and (imm_val % 4) == 0': 0 + 'ea_align == 3 and (imm_val % 4) == 1': 0 + 'ea_align == 3 and (imm_val % 4) == 2': 0 + 'ea_align == 3 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + +lw-align: + config: check ISA:=regex(.*I.*) + opcode: + lw: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + + +sh-align: + config: check ISA:=regex(.*I.*) + opcode: + sh: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + op_comb: + 'rs1 != rs2': 0 + val_comb: + <<: [ *base_rs2val_sgn] + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'ea_align == 2 and (imm_val % 4) == 0': 0 + 'ea_align == 2 and (imm_val % 4) == 1': 0 + 'ea_align == 2 and (imm_val % 4) == 2': 0 + 'ea_align == 2 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + abstract_comb: + <<: [*rs2val_walking] + +sb-align: + config: check ISA:=regex(.*I.*) + opcode: + sb: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + op_comb: + 'rs1 != rs2': 0 + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'ea_align == 2 and (imm_val % 4) == 0': 0 + 'ea_align == 2 and (imm_val % 4) == 1': 0 + 'ea_align == 2 and (imm_val % 4) == 2': 0 + 'ea_align == 2 and (imm_val % 4) == 3': 0 + 'ea_align == 1 and (imm_val % 4) == 0': 0 + 'ea_align == 1 and (imm_val % 4) == 1': 0 + 'ea_align == 1 and (imm_val % 4) == 2': 0 + 'ea_align == 1 and (imm_val % 4) == 3': 0 + 'ea_align == 3 and (imm_val % 4) == 0': 0 + 'ea_align == 3 and (imm_val % 4) == 1': 0 + 'ea_align == 3 and (imm_val % 4) == 2': 0 + 'ea_align == 3 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + <<: [ *base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +sw-align: + config: check ISA:=regex(.*I.*) + opcode: + sw: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + op_comb: + 'rs1 != rs2': 0 + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + <<: [ *base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +auipc: + config: check ISA:=regex(.*I.*) + opcode: + auipc: 0 + rd: + <<: *all_regs + val_comb: + 'imm_val == 0': 0 + 'imm_val > 0': 0 + 'imm_val == ((2**20)-1)': 0 + +lui: + config: check ISA:=regex(.*I.*) + opcode: + lui: 0 + rd: + <<: *all_regs + val_comb: + 'imm_val == 0': 0 + 'imm_val > 0': 0 + 'imm_val == ((2**20)-1)': 0 + +jal: + config: check ISA:=regex(.*I.*) + opcode: + jal: 0 + rd: + <<: *all_regs + val_comb: + 'imm_val < 0' : 0 + 'imm_val > 0': 0 + 'imm_val == (-(2**(18)))': 0 + 'imm_val == ((2**(18)))': 0 + +jalr: + config: check ISA:=regex(.*I.*) + opcode: + jalr: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'imm_val > 0': 0 + 'imm_val < 0': 0 + abstract_comb: + <<: *ifmt_immval_walking + +mul: + config: check ISA:=regex(.*I.*M.*) + opcode: + mul: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +mulh: + config: check ISA:=regex(.*I.*M.*) + opcode: + mulh: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +mulhu: + config: check ISA:=regex(.*I.*M.*) + opcode: + mulhu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +mulhsu: + config: check ISA:=regex(.*I.*M.*) + opcode: + mulhsu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +div: + config: check ISA:=regex(.*I.*M.*) + opcode: + div: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +divu: + config: check ISA:=regex(.*I.*M.*) + opcode: + divu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +rem: + config: check ISA:=regex(.*I.*M.*) + opcode: + rem: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +remu: + config: check ISA:=regex(.*I.*M.*) + opcode: + remu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +lwu-align: + config: check ISA:=regex(.*RV64.*I.*) + opcode: + lwu: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + +ld-align: + config: check ISA:=regex(.*RV64.*I.*) + opcode: + ld: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'ea_align == 0 and (imm_val % 8) == 0': 0 + 'ea_align == 0 and (imm_val % 8) == 1': 0 + 'ea_align == 0 and (imm_val % 8) == 2': 0 + 'ea_align == 0 and (imm_val % 8) == 3': 0 + 'ea_align == 0 and (imm_val % 8) == 4': 0 + 'ea_align == 0 and (imm_val % 8) == 5': 0 + 'ea_align == 0 and (imm_val % 8) == 6': 0 + 'ea_align == 0 and (imm_val % 8) == 7': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + +sd-align: + config: check ISA:=regex(.*RV64.*I.*) + opcode: + sd: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + op_comb: + 'rs1 != rs2': 0 + val_comb: + 'ea_align == 0 and (imm_val % 8) == 0': 0 + 'ea_align == 0 and (imm_val % 8) == 1': 0 + 'ea_align == 0 and (imm_val % 8) == 2': 0 + 'ea_align == 0 and (imm_val % 8) == 3': 0 + 'ea_align == 0 and (imm_val % 8) == 4': 0 + 'ea_align == 0 and (imm_val % 8) == 5': 0 + 'ea_align == 0 and (imm_val % 8) == 6': 0 + 'ea_align == 0 and (imm_val % 8) == 7': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + <<: [ *base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +addiw: + config: check ISA:=regex(.*RV64.*I.*) + opcode: + addiw: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [ *ifmt_val_comb_sgn, *base_rs1val_sgn, *ifmt_base_immval_sgn] + abstract_comb: + <<: [*rs1val_walking, *ifmt_immval_walking] + +slliw: + config: check ISA:=regex(.*RV64.*I.*) + opcode: + slliw: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: *ifmt_base_shift_32w + abstract_comb: + <<: [*rs1val_walking] + 'walking_ones("imm_val", 5, False)': 0 + 'walking_zeros("imm_val", 5, False)': 0 + 'alternate("imm_val", 5, False)': 0 + +srliw: + config: check ISA:=regex(.*RV64.*I.*) + opcode: + srliw: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: *ifmt_base_shift_32w + abstract_comb: + <<: [*rs1val_walking] + 'walking_ones("imm_val", 5, False)': 0 + 'walking_zeros("imm_val", 5, False)': 0 + 'alternate("imm_val", 5, False)': 0 + +sraiw: + config: check ISA:=regex(.*RV64.*I.*) + opcode: + sraiw: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: *ifmt_base_shift_32w + abstract_comb: + <<: [*rs1val_walking] + 'walking_ones("imm_val", 5, False)': 0 + 'walking_zeros("imm_val", 5, False)': 0 + 'alternate("imm_val", 5, False)': 0 + +addw: + config: check ISA:=regex(.*RV64.*I.*) + opcode: + addw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +subw: + config: check ISA:=regex(.*RV64.*I.*) + opcode: + subw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +sllw: + config: check ISA:=regex(.*RV64.*I.*) + opcode: + sllw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: *rfmt_base_shift + abstract_comb: + <<: [*rs1val_walking] + 'walking_ones("rs2_val", 5, False)': 0 + 'walking_zeros("rs2_val", 5, False)': 0 + 'alternate("rs2_val", 5, False)': 0 + +srlw: + config: check ISA:=regex(.*RV64.*I.*) + opcode: + srlw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: *rfmt_base_shift + abstract_comb: + <<: [*rs1val_walking] + 'walking_ones("rs2_val", 5, False)': 0 + 'walking_zeros("rs2_val", 5, False)': 0 + 'alternate("rs2_val", 5, False)': 0 +sraw: + config: check ISA:=regex(.*RV64.*I.*) + opcode: + sraw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: *rfmt_base_shift + abstract_comb: + <<: [*rs1val_walking] + 'walking_ones("rs2_val", 5, False)': 0 + 'walking_zeros("rs2_val", 5, False)': 0 + 'alternate("rs2_val", 5, False)': 0 + +mulw: + config: check ISA:=regex(.*RV64.*I.*M.*) + opcode: + mulw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +divw: + config: check ISA:=regex(.*RV64.*I.*M.*) + opcode: + divw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +divuw: + config: check ISA:=regex(.*RV64.*I.*M.*) + opcode: + divuw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +remw: + config: check ISA:=regex(.*RV64.*I.*M.*) + opcode: + remw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +remuw: + config: check ISA:=regex(.*RV64.*I.*M.*) + opcode: + remuw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + diff --git a/coverage/dataset.cgf b/coverage/dataset.cgf index 1f3426e7c..a1a1a01f4 100644 --- a/coverage/dataset.cgf +++ b/coverage/dataset.cgf @@ -1,4 +1,4 @@ -# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore +# For Licence details look at https://github.com/riscv-software-src/riscv-ctg/-/blob/master/LICENSE.incore datasets: rv32e_regs_mx0: &rv32e_regs_mx0 @@ -17,6 +17,23 @@ datasets: x13: 0 x14: 0 x15: 0 + + rv32e_regs_mx2: &rv32e_regs_mx2 + x1: 0 + x3: 0 + x4: 0 + x5: 0 + x6: 0 + x7: 0 + x8: 0 + x9: 0 + x10: 0 + x11: 0 + x12: 0 + x13: 0 + x14: 0 + x15: 0 + rv32e_regs: &rv32e_regs x0: 0 x1: 0 @@ -69,6 +86,91 @@ datasets: x30: 0 x31: 0 + all_fregs: &all_fregs + f0: 0 + f1: 0 + f2: 0 + f3: 0 + f4: 0 + f5: 0 + f6: 0 + f7: 0 + f8: 0 + f9: 0 + f10: 0 + f11: 0 + f12: 0 + f13: 0 + f14: 0 + f15: 0 + f16: 0 + f17: 0 + f18: 0 + f19: 0 + f20: 0 + f21: 0 + f22: 0 + f23: 0 + f24: 0 + f25: 0 + f26: 0 + f27: 0 + f28: 0 + f29: 0 + f30: 0 + f31: 0 + + all_vregs: &all_vregs + v0: 0 + v1: 0 + v2: 0 + v3: 0 + v4: 0 + v5: 0 + v6: 0 + v7: 0 + v8: 0 + v9: 0 + v10: 0 + v11: 0 + v12: 0 + v13: 0 + v14: 0 + v15: 0 + v16: 0 + v17: 0 + v18: 0 + v19: 0 + v20: 0 + v21: 0 + v22: 0 + v23: 0 + v24: 0 + v25: 0 + v26: 0 + v27: 0 + v28: 0 + v29: 0 + v30: 0 + v31: 0 + + pair_regs: &pair_regs + x2: 0 + x4: 0 + x6: 0 + x8: 0 + x10: 0 + x12: 0 + x14: 0 + x16: 0 + x18: 0 + x20: 0 + x22: 0 + x24: 0 + x26: 0 + x28: 0 + x30: 0 + c_regs: &c_regs x8: 0 x9: 0 @@ -144,23 +246,6 @@ datasets: x30: 0 x31: 0 - pair_regs: &pair_regs - x2: 0 - x4: 0 - x6: 0 - x8: 0 - x10: 0 - x12: 0 - x14: 0 - x16: 0 - x18: 0 - x20: 0 - x22: 0 - x24: 0 - x26: 0 - x28: 0 - x30: 0 - cbfmt_immval_sgn: &cbfmt_immval_sgn 'imm_val == (-2**(6-1))': 0 'imm_val == 0': 0 @@ -174,6 +259,31 @@ datasets: 'rs1 == rs2 == rd': 0 'rs1 != rs2 and rs1 != rd and rs2 != rd': 0 + div_hardcoded_opcomb: &div_hardcoded_opcomb + 'rs1 == rd != rs2 and rd != "x0"': 0 + 'rs1 == rd != rs2 and rd == "x0"': 0 + 'rs1 == "x0" != rd': 0 + 'rd == "x0" != rs1': 0 + + ramofmt_op_comb: &ramofmt_op_comb + 'rs1 == rd != rs2': 0 + 'rs2 == rd != rs1': 0 + 'rs1 != rs2 and rs1 != rd and rs2 != rd': 0 + + r4fmt_op_comb: &r4fmt_op_comb + 'rs1 == rs2 == rs3 == rd': 0 + 'rs1 == rs2 == rs3 != rd': 0 + 'rs1 == rs2 == rd != rs3': 0 + 'rs1 == rd == rs3 != rs2': 0 + 'rd == rs2 == rs3 != rs1': 0 + 'rs2 == rd != rs1 and rs2 == rd != rs3 and rs3 != rs1': 0 + 'rs3 == rd != rs1 and rs3 == rd != rs2 and rs2 != rs1': 0 + 'rs2 == rs3 != rs1 and rs2 == rs3 != rd and rd != rs1': 0 + 'rs1 == rd != rs2 and rs1 == rd != rs3 and rs3 != rs2': 0 + 'rs1 == rs3 != rs2 and rs1 == rs3 != rd and rd != rs2': 0 + 'rs1 == rs2 != rs3 and rs1 == rs2 != rd and rd != rs3': 0 + 'rs1 != rs2 and rs1 != rd and rs1 != rs3 and rs2 != rs3 and rs2 != rd and rs3 != rd': 0 + ifmt_op_comb: &ifmt_op_comb 'rs1 == rd': 0 'rs1 != rd': 0 @@ -181,18 +291,35 @@ datasets: sfmt_op_comb: &sfmt_op_comb 'rs1 == rs2': 0 'rs1 != rs2': 0 + + r0fmt_op_comb: &r0fmt_op_comb + 'rs1 == 0': 0 + 'rs1 != 0': 0 base_rs1val_sgn: &base_rs1val_sgn 'rs1_val == (-2**(xlen-1))': 0 'rs1_val == 0': 0 'rs1_val == (2**(xlen-1)-1)': 0 'rs1_val == 1': 0 + + base_rs1val_sgn_rs2val_zero: &base_rs1val_sgn_rs2val_zero + 'rs1_val == (-2**(xlen-1)) and rs2_val == 0': 0 + 'rs1_val == 0 and rs2_val == 0': 0 + 'rs1_val == (2**(xlen-1)-1) and rs2_val == 0': 0 + 'rs1_val == 1 and rs2_val == 0': 0 base_rs2val_sgn: &base_rs2val_sgn 'rs2_val == (-2**(xlen-1))': 0 'rs2_val == 0': 0 'rs2_val == (2**(xlen-1)-1)': 0 'rs2_val == 1': 0 + + base_rs3val_sgn: &base_rs3val_sgn + 'rs3_val == (-2**(xlen-1))': 0 + 'rs3_val == 0': 0 + 'rs3_val == (2**(xlen-1)-1)': 0 + 'rs3_val == 1': 0 + base_rs1val_unsgn: &base_rs1val_unsgn 'rs1_val == 0': 0 @@ -204,6 +331,11 @@ datasets: 'rs2_val == (2**(xlen)-1)': 0 'rs2_val == 1': 0 + base_rs3val_unsgn: &base_rs3val_unsgn + 'rs3_val == 0': 0 + 'rs3_val == (2**(xlen)-1)': 0 + 'rs3_val == 1': 0 + rfmt_val_comb_sgn: &rfmt_val_comb_sgn 'rs1_val > 0 and rs2_val > 0': 0 'rs1_val > 0 and rs2_val < 0': 0 @@ -211,6 +343,9 @@ datasets: 'rs1_val < 0 and rs2_val > 0': 0 'rs1_val == rs2_val': 0 'rs1_val != rs2_val': 0 + + div_corner_case: &div_corner_case + 'rs1_val == -(2**(xlen-1)) and rs2_val == -0x01': 0 rfmt_val_comb_unsgn: &rfmt_val_comb_unsgn 'rs1_val > 0 and rs2_val > 0': 0 @@ -224,7 +359,7 @@ datasets: 'rs1_val > 0 and imm_val < 0': 0 'rs1_val < 0 and imm_val > 0': 0 'rs1_val < 0 and imm_val < 0': 0 - + ifmt_val_comb_unsgn: &ifmt_val_comb_unsgn 'rs1_val == imm_val and rs1_val > 0 and imm_val > 0': 0 'rs1_val != imm_val and rs1_val > 0 and imm_val > 0': 0 @@ -234,7 +369,18 @@ datasets: 'imm_val == 0': 0 'imm_val == (2**(12-1)-1)': 0 'imm_val == 1': 0 - + + ifmt_base_immval_sgn_len: &ifmt_base_immval_sgn_len + 'imm_val == (-2**(ceil(log(xlen,2))-1))': 0 + 'imm_val == 0': 0 + 'imm_val == (2**(ceil(log(xlen,2))-1)-1)': 0 + 'imm_val == 1': 0 + + ifmt_base_immval_unsgn_len_sub_3: &ifmt_base_immval_unsgn_len_sub_3 + 'imm_val == 0': 0 + 'imm_val == (2**(ceil(log(xlen,2))-3)-1)': 0 + 'imm_val == 1': 0 + ifmt_base_immval_unsgn: &ifmt_base_immval_unsgn 'imm_val == 0': 0 'imm_val == (2**(12)-1)': 0 @@ -308,11 +454,32 @@ datasets: 'walking_ones("rs2_val", xlen)': 0 'walking_zeros("rs2_val", xlen)': 0 'alternate("rs2_val",xlen)': 0 - + + rs3val_walking: &rs3val_walking + 'walking_ones("rs3_val", xlen)': 0 + 'walking_zeros("rs3_val", xlen)': 0 + 'alternate("rs3_val",xlen)': 0 + ifmt_immval_walking: &ifmt_immval_walking 'walking_ones("imm_val", 12)': 0 'walking_zeros("imm_val", 12)': 0 'alternate("imm_val",12)': 0 + + ifmt_immval_walking_len: &ifmt_immval_walking_len + 'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0 + 'alternate("imm_val",ceil(log(xlen,2)), False)': 0 + + ifmt_immval_walking_len_sub_3: &ifmt_immval_walking_len_sub_3 + 'walking_ones("imm_val", ceil(log(xlen,2))-3, False)': 0 + 'walking_zeros("imm_val", ceil(log(xlen,2))-3, False)': 0 + 'alternate("imm_val", ceil(log(xlen,2))-3, False)': 0 + + + ifmt_immval_walking_5u: &ifmt_immval_walking_5u + 'walking_ones("imm_val", 5, False)': 0 + 'walking_zeros("imm_val", 5, False)': 0 + 'alternate("imm_val", 5, False)': 0 rs1val_walking_unsgn: &rs1val_walking_unsgn 'walking_ones("rs1_val", xlen,False)': 0 diff --git a/coverage/e/rv32e.cgf b/coverage/e/rv32e.cgf new file mode 100644 index 000000000..31b4c8af7 --- /dev/null +++ b/coverage/e/rv32e.cgf @@ -0,0 +1,752 @@ +# For Licence details look at https://github.com/riscv-software-src/riscv-ctg/-/blob/master/LICENSE.incore + +fence: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + fence: 0 + +addi: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + addi: 0 + rs1: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [ *ifmt_val_comb_sgn, *base_rs1val_sgn, *ifmt_base_immval_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val",("imm_val",12)])': 0 + <<: [*rs1val_walking, *ifmt_immval_walking] + +slti: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + slti: 0 + rs1: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [*ifmt_val_comb_sgn , *base_rs1val_sgn , *ifmt_base_immval_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val",("imm_val",12)])': 0 + <<: [*rs1val_walking, *ifmt_immval_walking] + +sltiu: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + sltiu: 0 + rs1: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [*ifmt_val_comb_unsgn , *base_rs1val_unsgn , *ifmt_base_immval_unsgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val",("imm_val",12)],signed=False)': 0 + <<: [*rs1val_walking_unsgn, *ifmt_immval_walking_unsgn] + +andi: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + andi: 0 + rs1: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [*ifmt_val_comb_sgn , *base_rs1val_sgn , *ifmt_base_immval_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val",("imm_val",12)])': 0 + <<: [*rs1val_walking, *ifmt_immval_walking] + +ori: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + ori: 0 + rs1: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [*ifmt_val_comb_sgn , *base_rs1val_sgn , *ifmt_base_immval_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val",("imm_val",12)])': 0 + <<: [*rs1val_walking, *ifmt_immval_walking] + +xori: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + xori: 0 + rs1: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [*ifmt_val_comb_sgn , *base_rs1val_sgn , *ifmt_base_immval_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val",("imm_val",12)])': 0 + <<: [*rs1val_walking, *ifmt_immval_walking] + +slli: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + slli: 0 + rs1: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: *ifmt_base_shift + abstract_comb: + 'sp_dataset(xlen,["rs1_val"])': 0 + <<: [*rs1val_walking] + 'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0 + 'alternate("imm_val", ceil(log(xlen,2)), False)': 0 + +srai: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + srai: 0 + rs1: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: *ifmt_base_shift + abstract_comb: + 'sp_dataset(xlen,["rs1_val"])': 0 + <<: [*rs1val_walking] + 'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0 + 'alternate("imm_val", ceil(log(xlen,2)), False)': 0 + +srli: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + srli: 0 + rs1: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: *ifmt_base_shift + abstract_comb: + 'sp_dataset(xlen,["rs1_val"])': 0 + <<: [*rs1val_walking] + 'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0 + 'alternate("imm_val", ceil(log(xlen,2)), False)': 0 + +add: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + add: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +sub: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + sub: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +slt: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + slt: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +sltu: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + sltu: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + 'sp_dataset(xlen,signed=False)': 0 + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + +and: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + and: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +or: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + or: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +xor: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + xor: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +sll: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + sll: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: *rfmt_base_shift + abstract_comb: + <<: [*rs1val_walking] + 'sp_dataset(xlen,var_lst=["rs1_val"])': 0 + 'walking_ones("rs2_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("rs2_val", ceil(log(xlen,2)), False)': 0 + 'alternate("rs2_val", ceil(log(xlen,2)), False)': 0 + +srl: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + srl: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: *rfmt_base_shift + abstract_comb: + <<: [*rs1val_walking] + 'sp_dataset(xlen,var_lst=["rs1_val"])': 0 + 'walking_ones("rs2_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("rs2_val", ceil(log(xlen,2)), False)': 0 + 'alternate("rs2_val", ceil(log(xlen,2)), False)': 0 + +sra: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + sra: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: *rfmt_base_shift + abstract_comb: + <<: [*rs1val_walking] + 'sp_dataset(xlen,var_lst=["rs1_val"])': 0 + 'walking_ones("rs2_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("rs2_val", ceil(log(xlen,2)), False)': 0 + 'alternate("rs2_val", ceil(log(xlen,2)), False)': 0 + +beq: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + beq: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *bfmt_base_branch_val_align_sgn + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + 'sp_dataset(xlen)': 0 + +bge: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + bge: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *bfmt_base_branch_val_align_sgn + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + 'sp_dataset(xlen)': 0 + +bgeu: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + bgeu: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *bfmt_base_branch_val_align_unsgn + abstract_comb: + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + 'sp_dataset(xlen,signed=False)': 0 + +blt: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + blt: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *bfmt_base_branch_val_align_sgn + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + 'sp_dataset(xlen)': 0 + +bltu: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + bltu: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *bfmt_base_branch_val_align_unsgn + abstract_comb: + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + 'sp_dataset(xlen,signed=False)': 0 + +bne: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + bne: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *bfmt_base_branch_val_align_sgn + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + 'sp_dataset(xlen)': 0 + +lhu-align: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + lhu: 0 + rs1: + <<: *rv32e_regs_mx0 + rd: + <<: *rv32e_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'ea_align == 2 and (imm_val % 4) == 0': 0 + 'ea_align == 2 and (imm_val % 4) == 1': 0 + 'ea_align == 2 and (imm_val % 4) == 2': 0 + 'ea_align == 2 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + +lh-align: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + lh: 0 + rs1: + <<: *rv32e_regs_mx0 + rd: + <<: *rv32e_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'ea_align == 2 and (imm_val % 4) == 0': 0 + 'ea_align == 2 and (imm_val % 4) == 1': 0 + 'ea_align == 2 and (imm_val % 4) == 2': 0 + 'ea_align == 2 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + +lbu-align: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + lbu: 0 + rs1: + <<: *rv32e_regs_mx0 + rd: + <<: *rv32e_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'ea_align == 2 and (imm_val % 4) == 0': 0 + 'ea_align == 2 and (imm_val % 4) == 1': 0 + 'ea_align == 2 and (imm_val % 4) == 2': 0 + 'ea_align == 2 and (imm_val % 4) == 3': 0 + 'ea_align == 1 and (imm_val % 4) == 0': 0 + 'ea_align == 1 and (imm_val % 4) == 1': 0 + 'ea_align == 1 and (imm_val % 4) == 2': 0 + 'ea_align == 1 and (imm_val % 4) == 3': 0 + 'ea_align == 3 and (imm_val % 4) == 0': 0 + 'ea_align == 3 and (imm_val % 4) == 1': 0 + 'ea_align == 3 and (imm_val % 4) == 2': 0 + 'ea_align == 3 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + +lb-align: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + lb: 0 + rs1: + <<: *rv32e_regs_mx0 + rd: + <<: *rv32e_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'ea_align == 2 and (imm_val % 4) == 0': 0 + 'ea_align == 2 and (imm_val % 4) == 1': 0 + 'ea_align == 2 and (imm_val % 4) == 2': 0 + 'ea_align == 2 and (imm_val % 4) == 3': 0 + 'ea_align == 1 and (imm_val % 4) == 0': 0 + 'ea_align == 1 and (imm_val % 4) == 1': 0 + 'ea_align == 1 and (imm_val % 4) == 2': 0 + 'ea_align == 1 and (imm_val % 4) == 3': 0 + 'ea_align == 3 and (imm_val % 4) == 0': 0 + 'ea_align == 3 and (imm_val % 4) == 1': 0 + 'ea_align == 3 and (imm_val % 4) == 2': 0 + 'ea_align == 3 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + +lw-align: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + lw: 0 + rs1: + <<: *rv32e_regs_mx0 + rd: + <<: *rv32e_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + + +sh-align: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + sh: 0 + rs1: + <<: *rv32e_regs_mx0 + rs2: + <<: *rv32e_regs + op_comb: + 'rs1 != rs2': 0 + val_comb: + <<: [ *base_rs2val_sgn] + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'ea_align == 2 and (imm_val % 4) == 0': 0 + 'ea_align == 2 and (imm_val % 4) == 1': 0 + 'ea_align == 2 and (imm_val % 4) == 2': 0 + 'ea_align == 2 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + abstract_comb: + <<: [*rs2val_walking] + +sb-align: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + sb: 0 + rs1: + <<: *rv32e_regs_mx0 + rs2: + <<: *rv32e_regs + op_comb: + 'rs1 != rs2': 0 + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'ea_align == 2 and (imm_val % 4) == 0': 0 + 'ea_align == 2 and (imm_val % 4) == 1': 0 + 'ea_align == 2 and (imm_val % 4) == 2': 0 + 'ea_align == 2 and (imm_val % 4) == 3': 0 + 'ea_align == 1 and (imm_val % 4) == 0': 0 + 'ea_align == 1 and (imm_val % 4) == 1': 0 + 'ea_align == 1 and (imm_val % 4) == 2': 0 + 'ea_align == 1 and (imm_val % 4) == 3': 0 + 'ea_align == 3 and (imm_val % 4) == 0': 0 + 'ea_align == 3 and (imm_val % 4) == 1': 0 + 'ea_align == 3 and (imm_val % 4) == 2': 0 + 'ea_align == 3 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + <<: [ *base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +sw-align: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + sw: 0 + rs1: + <<: *rv32e_regs_mx0 + rs2: + <<: *rv32e_regs + op_comb: + 'rs1 != rs2': 0 + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + <<: [ *base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +auipc: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + auipc: 0 + rd: + <<: *rv32e_regs + val_comb: + 'imm_val == 0': 0 + 'imm_val > 0': 0 + 'imm_val == ((2**20)-1)': 0 + abstract_comb: + 'sp_dataset(20,["imm_val"],signed=False)': 0 + 'walking_ones("imm_val", 20, False)': 0 + 'walking_zeros("imm_val", 20, False)': 0 + 'alternate("imm_val", 20, False)': 0 + +lui: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + lui: 0 + rd: + <<: *rv32e_regs + val_comb: + 'imm_val == 0': 0 + 'imm_val > 0': 0 + 'imm_val == ((2**20)-1)': 0 + abstract_comb: + 'sp_dataset(20,["imm_val"],signed=False)': 0 + 'walking_ones("imm_val", 20, False)': 0 + 'walking_zeros("imm_val", 20, False)': 0 + 'alternate("imm_val", 20, False)': 0 + +jal: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + jal: 0 + rd: + <<: *rv32e_regs + val_comb: + 'imm_val < 0' : 0 + 'imm_val > 0': 0 + 'imm_val == (-(2**(18)))': 0 + 'imm_val == ((2**(18)))': 0 + +jalr: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + jalr: 0 + rs1: + <<: *rv32e_regs_mx0 + rd: + <<: *rv32e_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'imm_val > 0': 0 + 'imm_val < 0': 0 + abstract_comb: + <<: *ifmt_immval_walking diff --git a/coverage/i/rv32i.cgf b/coverage/i/rv32i.cgf new file mode 100644 index 000000000..54ce07fb9 --- /dev/null +++ b/coverage/i/rv32i.cgf @@ -0,0 +1,752 @@ +# For Licence details look at https://github.com/riscv-software-src/riscv-ctg/-/blob/master/LICENSE.incore + +fence: + config: + - check ISA:=regex(.*I.*) + mnemonics: + fence: 0 + +addi: + config: + - check ISA:=regex(.*I.*) + mnemonics: + addi: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [ *ifmt_val_comb_sgn, *base_rs1val_sgn, *ifmt_base_immval_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val",("imm_val",12)])': 0 + <<: [*rs1val_walking, *ifmt_immval_walking] + +slti: + config: + - check ISA:=regex(.*I.*) + mnemonics: + slti: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [*ifmt_val_comb_sgn , *base_rs1val_sgn , *ifmt_base_immval_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val",("imm_val",12)])': 0 + <<: [*rs1val_walking, *ifmt_immval_walking] + +sltiu: + config: + - check ISA:=regex(.*I.*) + mnemonics: + sltiu: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [*ifmt_val_comb_unsgn , *base_rs1val_unsgn , *ifmt_base_immval_unsgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val",("imm_val",12)],signed=False)': 0 + <<: [*rs1val_walking_unsgn, *ifmt_immval_walking_unsgn] + +andi: + config: + - check ISA:=regex(.*I.*) + mnemonics: + andi: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [*ifmt_val_comb_sgn , *base_rs1val_sgn , *ifmt_base_immval_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val",("imm_val",12)])': 0 + <<: [*rs1val_walking, *ifmt_immval_walking] + +ori: + config: + - check ISA:=regex(.*I.*) + mnemonics: + ori: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [*ifmt_val_comb_sgn , *base_rs1val_sgn , *ifmt_base_immval_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val",("imm_val",12)])': 0 + <<: [*rs1val_walking, *ifmt_immval_walking] + +xori: + config: + - check ISA:=regex(.*I.*) + mnemonics: + xori: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [*ifmt_val_comb_sgn , *base_rs1val_sgn , *ifmt_base_immval_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val",("imm_val",12)])': 0 + <<: [*rs1val_walking, *ifmt_immval_walking] + +slli: + config: + - check ISA:=regex(.*I.*) + mnemonics: + slli: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: *ifmt_base_shift + abstract_comb: + 'sp_dataset(xlen,["rs1_val"])': 0 + <<: [*rs1val_walking] + 'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0 + 'alternate("imm_val", ceil(log(xlen,2)), False)': 0 + +srai: + config: + - check ISA:=regex(.*I.*) + mnemonics: + srai: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: *ifmt_base_shift + abstract_comb: + 'sp_dataset(xlen,["rs1_val"])': 0 + <<: [*rs1val_walking] + 'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0 + 'alternate("imm_val", ceil(log(xlen,2)), False)': 0 + +srli: + config: + - check ISA:=regex(.*I.*) + mnemonics: + srli: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: *ifmt_base_shift + abstract_comb: + 'sp_dataset(xlen,["rs1_val"])': 0 + <<: [*rs1val_walking] + 'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0 + 'alternate("imm_val", ceil(log(xlen,2)), False)': 0 + +add: + config: + - check ISA:=regex(.*I.*) + mnemonics: + add: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +sub: + config: + - check ISA:=regex(.*I.*) + mnemonics: + sub: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +slt: + config: + - check ISA:=regex(.*I.*) + mnemonics: + slt: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +sltu: + config: + - check ISA:=regex(.*I.*) + mnemonics: + sltu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + 'sp_dataset(xlen,signed=False)': 0 + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + +and: + config: + - check ISA:=regex(.*I.*) + mnemonics: + and: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +or: + config: + - check ISA:=regex(.*I.*) + mnemonics: + or: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +xor: + config: + - check ISA:=regex(.*I.*) + mnemonics: + xor: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +sll: + config: + - check ISA:=regex(.*I.*) + mnemonics: + sll: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: *rfmt_base_shift + abstract_comb: + <<: [*rs1val_walking] + 'sp_dataset(xlen,var_lst=["rs1_val"])': 0 + 'walking_ones("rs2_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("rs2_val", ceil(log(xlen,2)), False)': 0 + 'alternate("rs2_val", ceil(log(xlen,2)), False)': 0 + +srl: + config: + - check ISA:=regex(.*I.*) + mnemonics: + srl: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: *rfmt_base_shift + abstract_comb: + <<: [*rs1val_walking] + 'sp_dataset(xlen,var_lst=["rs1_val"])': 0 + 'walking_ones("rs2_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("rs2_val", ceil(log(xlen,2)), False)': 0 + 'alternate("rs2_val", ceil(log(xlen,2)), False)': 0 + +sra: + config: + - check ISA:=regex(.*I.*) + mnemonics: + sra: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: *rfmt_base_shift + abstract_comb: + <<: [*rs1val_walking] + 'sp_dataset(xlen,var_lst=["rs1_val"])': 0 + 'walking_ones("rs2_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("rs2_val", ceil(log(xlen,2)), False)': 0 + 'alternate("rs2_val", ceil(log(xlen,2)), False)': 0 + +beq: + config: + - check ISA:=regex(.*I.*) + mnemonics: + beq: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *bfmt_base_branch_val_align_sgn + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + 'sp_dataset(xlen)': 0 + +bge: + config: + - check ISA:=regex(.*I.*) + mnemonics: + bge: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *bfmt_base_branch_val_align_sgn + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + 'sp_dataset(xlen)': 0 + +bgeu: + config: + - check ISA:=regex(.*I.*) + mnemonics: + bgeu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *bfmt_base_branch_val_align_unsgn + abstract_comb: + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + 'sp_dataset(xlen,signed=False)': 0 + +blt: + config: + - check ISA:=regex(.*I.*) + mnemonics: + blt: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *bfmt_base_branch_val_align_sgn + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + 'sp_dataset(xlen)': 0 + +bltu: + config: + - check ISA:=regex(.*I.*) + mnemonics: + bltu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *bfmt_base_branch_val_align_unsgn + abstract_comb: + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + 'sp_dataset(xlen,signed=False)': 0 + +bne: + config: + - check ISA:=regex(.*I.*) + mnemonics: + bne: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *bfmt_base_branch_val_align_sgn + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + 'sp_dataset(xlen)': 0 + +lhu-align: + config: + - check ISA:=regex(.*I.*) + mnemonics: + lhu: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'ea_align == 2 and (imm_val % 4) == 0': 0 + 'ea_align == 2 and (imm_val % 4) == 1': 0 + 'ea_align == 2 and (imm_val % 4) == 2': 0 + 'ea_align == 2 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + +lh-align: + config: + - check ISA:=regex(.*I.*) + mnemonics: + lh: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'ea_align == 2 and (imm_val % 4) == 0': 0 + 'ea_align == 2 and (imm_val % 4) == 1': 0 + 'ea_align == 2 and (imm_val % 4) == 2': 0 + 'ea_align == 2 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + +lbu-align: + config: + - check ISA:=regex(.*I.*) + mnemonics: + lbu: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'ea_align == 2 and (imm_val % 4) == 0': 0 + 'ea_align == 2 and (imm_val % 4) == 1': 0 + 'ea_align == 2 and (imm_val % 4) == 2': 0 + 'ea_align == 2 and (imm_val % 4) == 3': 0 + 'ea_align == 1 and (imm_val % 4) == 0': 0 + 'ea_align == 1 and (imm_val % 4) == 1': 0 + 'ea_align == 1 and (imm_val % 4) == 2': 0 + 'ea_align == 1 and (imm_val % 4) == 3': 0 + 'ea_align == 3 and (imm_val % 4) == 0': 0 + 'ea_align == 3 and (imm_val % 4) == 1': 0 + 'ea_align == 3 and (imm_val % 4) == 2': 0 + 'ea_align == 3 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + +lb-align: + config: + - check ISA:=regex(.*I.*) + mnemonics: + lb: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'ea_align == 2 and (imm_val % 4) == 0': 0 + 'ea_align == 2 and (imm_val % 4) == 1': 0 + 'ea_align == 2 and (imm_val % 4) == 2': 0 + 'ea_align == 2 and (imm_val % 4) == 3': 0 + 'ea_align == 1 and (imm_val % 4) == 0': 0 + 'ea_align == 1 and (imm_val % 4) == 1': 0 + 'ea_align == 1 and (imm_val % 4) == 2': 0 + 'ea_align == 1 and (imm_val % 4) == 3': 0 + 'ea_align == 3 and (imm_val % 4) == 0': 0 + 'ea_align == 3 and (imm_val % 4) == 1': 0 + 'ea_align == 3 and (imm_val % 4) == 2': 0 + 'ea_align == 3 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + +lw-align: + config: + - check ISA:=regex(.*I.*) + mnemonics: + lw: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + + +sh-align: + config: + - check ISA:=regex(.*I.*) + mnemonics: + sh: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + op_comb: + 'rs1 != rs2': 0 + val_comb: + <<: [ *base_rs2val_sgn] + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'ea_align == 2 and (imm_val % 4) == 0': 0 + 'ea_align == 2 and (imm_val % 4) == 1': 0 + 'ea_align == 2 and (imm_val % 4) == 2': 0 + 'ea_align == 2 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + abstract_comb: + <<: [*rs2val_walking] + +sb-align: + config: + - check ISA:=regex(.*I.*) + mnemonics: + sb: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + op_comb: + 'rs1 != rs2': 0 + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'ea_align == 2 and (imm_val % 4) == 0': 0 + 'ea_align == 2 and (imm_val % 4) == 1': 0 + 'ea_align == 2 and (imm_val % 4) == 2': 0 + 'ea_align == 2 and (imm_val % 4) == 3': 0 + 'ea_align == 1 and (imm_val % 4) == 0': 0 + 'ea_align == 1 and (imm_val % 4) == 1': 0 + 'ea_align == 1 and (imm_val % 4) == 2': 0 + 'ea_align == 1 and (imm_val % 4) == 3': 0 + 'ea_align == 3 and (imm_val % 4) == 0': 0 + 'ea_align == 3 and (imm_val % 4) == 1': 0 + 'ea_align == 3 and (imm_val % 4) == 2': 0 + 'ea_align == 3 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + <<: [ *base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +sw-align: + config: + - check ISA:=regex(.*I.*) + mnemonics: + sw: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + op_comb: + 'rs1 != rs2': 0 + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + <<: [ *base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +auipc: + config: + - check ISA:=regex(.*I.*) + mnemonics: + auipc: 0 + rd: + <<: *all_regs + val_comb: + 'imm_val == 0': 0 + 'imm_val > 0': 0 + 'imm_val == ((2**20)-1)': 0 + abstract_comb: + 'sp_dataset(20,["imm_val"],signed=False)': 0 + 'walking_ones("imm_val", 20, False)': 0 + 'walking_zeros("imm_val", 20, False)': 0 + 'alternate("imm_val", 20, False)': 0 + +lui: + config: + - check ISA:=regex(.*I.*) + mnemonics: + lui: 0 + rd: + <<: *all_regs + val_comb: + 'imm_val == 0': 0 + 'imm_val > 0': 0 + 'imm_val == ((2**20)-1)': 0 + abstract_comb: + 'sp_dataset(20,["imm_val"],signed=False)': 0 + 'walking_ones("imm_val", 20, False)': 0 + 'walking_zeros("imm_val", 20, False)': 0 + 'alternate("imm_val", 20, False)': 0 + +jal: + config: + - check ISA:=regex(.*I.*) + mnemonics: + jal: 0 + rd: + <<: *all_regs + val_comb: + 'imm_val < 0' : 0 + 'imm_val > 0': 0 + 'imm_val == (-(2**(18)))': 0 + 'imm_val == ((2**(18)))': 0 + +jalr: + config: + - check ISA:=regex(.*I.*) + mnemonics: + jalr: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'imm_val > 0': 0 + 'imm_val < 0': 0 + abstract_comb: + <<: *ifmt_immval_walking diff --git a/coverage/i/rv64i.cgf b/coverage/i/rv64i.cgf new file mode 100644 index 000000000..0a4a816dc --- /dev/null +++ b/coverage/i/rv64i.cgf @@ -0,0 +1,1003 @@ +# For Licence details look at https://github.com/riscv-software-src/riscv-ctg/-/blob/master/LICENSE.incore + +fence: + config: + - check ISA:=regex(.*I.*) + mnemonics: + fence: 0 + +addi: + config: + - check ISA:=regex(.*I.*) + mnemonics: + addi: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [ *ifmt_val_comb_sgn, *base_rs1val_sgn, *ifmt_base_immval_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val",("imm_val",12)])': 0 + <<: [*rs1val_walking, *ifmt_immval_walking] + +slti: + config: + - check ISA:=regex(.*I.*) + mnemonics: + slti: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [*ifmt_val_comb_sgn , *base_rs1val_sgn , *ifmt_base_immval_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val",("imm_val",12)])': 0 + <<: [*rs1val_walking, *ifmt_immval_walking] + +sltiu: + config: + - check ISA:=regex(.*I.*) + mnemonics: + sltiu: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [*ifmt_val_comb_unsgn , *base_rs1val_unsgn , *ifmt_base_immval_unsgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val",("imm_val",12)],signed=False)': 0 + <<: [*rs1val_walking_unsgn, *ifmt_immval_walking_unsgn] + +andi: + config: + - check ISA:=regex(.*I.*) + mnemonics: + andi: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [*ifmt_val_comb_sgn , *base_rs1val_sgn , *ifmt_base_immval_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val",("imm_val",12)])': 0 + <<: [*rs1val_walking, *ifmt_immval_walking] + +ori: + config: + - check ISA:=regex(.*I.*) + mnemonics: + ori: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [*ifmt_val_comb_sgn , *base_rs1val_sgn , *ifmt_base_immval_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val",("imm_val",12)])': 0 + <<: [*rs1val_walking, *ifmt_immval_walking] + +xori: + config: + - check ISA:=regex(.*I.*) + mnemonics: + xori: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [*ifmt_val_comb_sgn , *base_rs1val_sgn , *ifmt_base_immval_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val",("imm_val",12)])': 0 + <<: [*rs1val_walking, *ifmt_immval_walking] + +slli: + config: + - check ISA:=regex(.*I.*) + mnemonics: + slli: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: *ifmt_base_shift + abstract_comb: + 'sp_dataset(xlen,["rs1_val"])': 0 + <<: [*rs1val_walking] + 'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0 + 'alternate("imm_val", ceil(log(xlen,2)), False)': 0 + +srai: + config: + - check ISA:=regex(.*I.*) + mnemonics: + srai: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: *ifmt_base_shift + abstract_comb: + 'sp_dataset(xlen,["rs1_val"])': 0 + <<: [*rs1val_walking] + 'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0 + 'alternate("imm_val", ceil(log(xlen,2)), False)': 0 + +srli: + config: + - check ISA:=regex(.*I.*) + mnemonics: + srli: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: *ifmt_base_shift + abstract_comb: + 'sp_dataset(xlen,["rs1_val"])': 0 + <<: [*rs1val_walking] + 'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0 + 'alternate("imm_val", ceil(log(xlen,2)), False)': 0 + +add: + config: + - check ISA:=regex(.*I.*) + mnemonics: + add: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +sub: + config: + - check ISA:=regex(.*I.*) + mnemonics: + sub: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +slt: + config: + - check ISA:=regex(.*I.*) + mnemonics: + slt: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +sltu: + config: + - check ISA:=regex(.*I.*) + mnemonics: + sltu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + 'sp_dataset(xlen,signed=False)': 0 + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + +and: + config: + - check ISA:=regex(.*I.*) + mnemonics: + and: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +or: + config: + - check ISA:=regex(.*I.*) + mnemonics: + or: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +xor: + config: + - check ISA:=regex(.*I.*) + mnemonics: + xor: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +sll: + config: + - check ISA:=regex(.*I.*) + mnemonics: + sll: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: *rfmt_base_shift + abstract_comb: + <<: [*rs1val_walking] + 'sp_dataset(xlen,var_lst=["rs1_val"])': 0 + 'walking_ones("rs2_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("rs2_val", ceil(log(xlen,2)), False)': 0 + 'alternate("rs2_val", ceil(log(xlen,2)), False)': 0 + +srl: + config: + - check ISA:=regex(.*I.*) + mnemonics: + srl: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: *rfmt_base_shift + abstract_comb: + <<: [*rs1val_walking] + 'sp_dataset(xlen,var_lst=["rs1_val"])': 0 + 'walking_ones("rs2_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("rs2_val", ceil(log(xlen,2)), False)': 0 + 'alternate("rs2_val", ceil(log(xlen,2)), False)': 0 + +sra: + config: + - check ISA:=regex(.*I.*) + mnemonics: + sra: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: *rfmt_base_shift + abstract_comb: + <<: [*rs1val_walking] + 'sp_dataset(xlen,var_lst=["rs1_val"])': 0 + 'walking_ones("rs2_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("rs2_val", ceil(log(xlen,2)), False)': 0 + 'alternate("rs2_val", ceil(log(xlen,2)), False)': 0 + +beq: + config: + - check ISA:=regex(.*I.*) + mnemonics: + beq: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *bfmt_base_branch_val_align_sgn + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + 'sp_dataset(xlen)': 0 + +bge: + config: + - check ISA:=regex(.*I.*) + mnemonics: + bge: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *bfmt_base_branch_val_align_sgn + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + 'sp_dataset(xlen)': 0 + +bgeu: + config: + - check ISA:=regex(.*I.*) + mnemonics: + bgeu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *bfmt_base_branch_val_align_unsgn + abstract_comb: + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + 'sp_dataset(xlen,signed=False)': 0 + +blt: + config: + - check ISA:=regex(.*I.*) + mnemonics: + blt: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *bfmt_base_branch_val_align_sgn + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + 'sp_dataset(xlen)': 0 + +bltu: + config: + - check ISA:=regex(.*I.*) + mnemonics: + bltu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *bfmt_base_branch_val_align_unsgn + abstract_comb: + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + 'sp_dataset(xlen,signed=False)': 0 + +bne: + config: + - check ISA:=regex(.*I.*) + mnemonics: + bne: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *bfmt_base_branch_val_align_sgn + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + 'sp_dataset(xlen)': 0 + +lhu-align: + config: + - check ISA:=regex(.*I.*) + mnemonics: + lhu: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'ea_align == 2 and (imm_val % 4) == 0': 0 + 'ea_align == 2 and (imm_val % 4) == 1': 0 + 'ea_align == 2 and (imm_val % 4) == 2': 0 + 'ea_align == 2 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + +lh-align: + config: + - check ISA:=regex(.*I.*) + mnemonics: + lh: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'ea_align == 2 and (imm_val % 4) == 0': 0 + 'ea_align == 2 and (imm_val % 4) == 1': 0 + 'ea_align == 2 and (imm_val % 4) == 2': 0 + 'ea_align == 2 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + +lbu-align: + config: + - check ISA:=regex(.*I.*) + mnemonics: + lbu: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'ea_align == 2 and (imm_val % 4) == 0': 0 + 'ea_align == 2 and (imm_val % 4) == 1': 0 + 'ea_align == 2 and (imm_val % 4) == 2': 0 + 'ea_align == 2 and (imm_val % 4) == 3': 0 + 'ea_align == 1 and (imm_val % 4) == 0': 0 + 'ea_align == 1 and (imm_val % 4) == 1': 0 + 'ea_align == 1 and (imm_val % 4) == 2': 0 + 'ea_align == 1 and (imm_val % 4) == 3': 0 + 'ea_align == 3 and (imm_val % 4) == 0': 0 + 'ea_align == 3 and (imm_val % 4) == 1': 0 + 'ea_align == 3 and (imm_val % 4) == 2': 0 + 'ea_align == 3 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + +lb-align: + config: + - check ISA:=regex(.*I.*) + mnemonics: + lb: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'ea_align == 2 and (imm_val % 4) == 0': 0 + 'ea_align == 2 and (imm_val % 4) == 1': 0 + 'ea_align == 2 and (imm_val % 4) == 2': 0 + 'ea_align == 2 and (imm_val % 4) == 3': 0 + 'ea_align == 1 and (imm_val % 4) == 0': 0 + 'ea_align == 1 and (imm_val % 4) == 1': 0 + 'ea_align == 1 and (imm_val % 4) == 2': 0 + 'ea_align == 1 and (imm_val % 4) == 3': 0 + 'ea_align == 3 and (imm_val % 4) == 0': 0 + 'ea_align == 3 and (imm_val % 4) == 1': 0 + 'ea_align == 3 and (imm_val % 4) == 2': 0 + 'ea_align == 3 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + +lw-align: + config: + - check ISA:=regex(.*I.*) + mnemonics: + lw: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + + +sh-align: + config: + - check ISA:=regex(.*I.*) + mnemonics: + sh: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + op_comb: + 'rs1 != rs2': 0 + val_comb: + <<: [ *base_rs2val_sgn] + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'ea_align == 2 and (imm_val % 4) == 0': 0 + 'ea_align == 2 and (imm_val % 4) == 1': 0 + 'ea_align == 2 and (imm_val % 4) == 2': 0 + 'ea_align == 2 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + abstract_comb: + <<: [*rs2val_walking] + +sb-align: + config: + - check ISA:=regex(.*I.*) + mnemonics: + sb: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + op_comb: + 'rs1 != rs2': 0 + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'ea_align == 2 and (imm_val % 4) == 0': 0 + 'ea_align == 2 and (imm_val % 4) == 1': 0 + 'ea_align == 2 and (imm_val % 4) == 2': 0 + 'ea_align == 2 and (imm_val % 4) == 3': 0 + 'ea_align == 1 and (imm_val % 4) == 0': 0 + 'ea_align == 1 and (imm_val % 4) == 1': 0 + 'ea_align == 1 and (imm_val % 4) == 2': 0 + 'ea_align == 1 and (imm_val % 4) == 3': 0 + 'ea_align == 3 and (imm_val % 4) == 0': 0 + 'ea_align == 3 and (imm_val % 4) == 1': 0 + 'ea_align == 3 and (imm_val % 4) == 2': 0 + 'ea_align == 3 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + <<: [ *base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +sw-align: + config: + - check ISA:=regex(.*I.*) + mnemonics: + sw: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + op_comb: + 'rs1 != rs2': 0 + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + <<: [ *base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +auipc: + config: + - check ISA:=regex(.*I.*) + mnemonics: + auipc: 0 + rd: + <<: *all_regs + val_comb: + 'imm_val == 0': 0 + 'imm_val > 0': 0 + 'imm_val == ((2**20)-1)': 0 + abstract_comb: + 'sp_dataset(20,["imm_val"],signed=False)': 0 + 'walking_ones("imm_val", 20, False)': 0 + 'walking_zeros("imm_val", 20, False)': 0 + 'alternate("imm_val", 20, False)': 0 + +lui: + config: + - check ISA:=regex(.*I.*) + mnemonics: + lui: 0 + rd: + <<: *all_regs + val_comb: + 'imm_val == 0': 0 + 'imm_val > 0': 0 + 'imm_val == ((2**20)-1)': 0 + abstract_comb: + 'sp_dataset(20,["imm_val"],signed=False)': 0 + 'walking_ones("imm_val", 20, False)': 0 + 'walking_zeros("imm_val", 20, False)': 0 + 'alternate("imm_val", 20, False)': 0 + +jal: + config: + - check ISA:=regex(.*I.*) + mnemonics: + jal: 0 + rd: + <<: *all_regs + val_comb: + 'imm_val < 0' : 0 + 'imm_val > 0': 0 + 'imm_val == (-(2**(18)))': 0 + 'imm_val == ((2**(18)))': 0 + +jalr: + config: + - check ISA:=regex(.*I.*) + mnemonics: + jalr: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'imm_val > 0': 0 + 'imm_val < 0': 0 + abstract_comb: + <<: *ifmt_immval_walking + +lwu-align: + config: + - check ISA:=regex(.*RV64.*I.*) + mnemonics: + lwu: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + +ld-align: + config: + - check ISA:=regex(.*RV64.*I.*) + mnemonics: + ld: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'ea_align == 0 and (imm_val % 8) == 0': 0 + 'ea_align == 0 and (imm_val % 8) == 1': 0 + 'ea_align == 0 and (imm_val % 8) == 2': 0 + 'ea_align == 0 and (imm_val % 8) == 3': 0 + 'ea_align == 0 and (imm_val % 8) == 4': 0 + 'ea_align == 0 and (imm_val % 8) == 5': 0 + 'ea_align == 0 and (imm_val % 8) == 6': 0 + 'ea_align == 0 and (imm_val % 8) == 7': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + +sd-align: + config: + - check ISA:=regex(.*RV64.*I.*) + mnemonics: + sd: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + op_comb: + 'rs1 != rs2': 0 + val_comb: + 'ea_align == 0 and (imm_val % 8) == 0': 0 + 'ea_align == 0 and (imm_val % 8) == 1': 0 + 'ea_align == 0 and (imm_val % 8) == 2': 0 + 'ea_align == 0 and (imm_val % 8) == 3': 0 + 'ea_align == 0 and (imm_val % 8) == 4': 0 + 'ea_align == 0 and (imm_val % 8) == 5': 0 + 'ea_align == 0 and (imm_val % 8) == 6': 0 + 'ea_align == 0 and (imm_val % 8) == 7': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + <<: [ *base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +addiw: + config: + - check ISA:=regex(.*RV64.*I.*) + mnemonics: + addiw: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [ *ifmt_val_comb_sgn, *base_rs1val_sgn, *ifmt_base_immval_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val",("imm_val",12)])': 0 + <<: [*rs1val_walking, *ifmt_immval_walking] + +slliw: + config: + - check ISA:=regex(.*RV64.*I.*) + mnemonics: + slliw: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: *ifmt_base_shift_32w + abstract_comb: + 'sp_dataset(xlen,["rs1_val"])': 0 + <<: [*rs1val_walking] + 'walking_ones("imm_val", 5, False)': 0 + 'walking_zeros("imm_val", 5, False)': 0 + 'alternate("imm_val", 5, False)': 0 + +srliw: + config: + - check ISA:=regex(.*RV64.*I.*) + mnemonics: + srliw: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: *ifmt_base_shift_32w + abstract_comb: + 'sp_dataset(xlen,["rs1_val"])': 0 + <<: [*rs1val_walking] + 'walking_ones("imm_val", 5, False)': 0 + 'walking_zeros("imm_val", 5, False)': 0 + 'alternate("imm_val", 5, False)': 0 + +sraiw: + config: + - check ISA:=regex(.*RV64.*I.*) + mnemonics: + sraiw: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: *ifmt_base_shift_32w + abstract_comb: + 'sp_dataset(xlen,["rs1_val"])': 0 + <<: [*rs1val_walking] + 'walking_ones("imm_val", 5, False)': 0 + 'walking_zeros("imm_val", 5, False)': 0 + 'alternate("imm_val", 5, False)': 0 + +addw: + config: + - check ISA:=regex(.*RV64.*I.*) + mnemonics: + addw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +subw: + config: + - check ISA:=regex(.*RV64.*I.*) + mnemonics: + subw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +sllw: + config: + - check ISA:=regex(.*RV64.*I.*) + mnemonics: + sllw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: *rfmt_base_shift + abstract_comb: + <<: [*rs1val_walking] + 'sp_dataset(xlen,var_lst=["rs1_val"])': 0 + 'walking_ones("rs2_val", 5, False)': 0 + 'walking_zeros("rs2_val", 5, False)': 0 + 'alternate("rs2_val", 5, False)': 0 + +srlw: + config: + - check ISA:=regex(.*RV64.*I.*) + mnemonics: + srlw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: *rfmt_base_shift + abstract_comb: + <<: [*rs1val_walking] + 'sp_dataset(xlen,var_lst=["rs1_val"])': 0 + 'walking_ones("rs2_val", 5, False)': 0 + 'walking_zeros("rs2_val", 5, False)': 0 + 'alternate("rs2_val", 5, False)': 0 +sraw: + config: + - check ISA:=regex(.*RV64.*I.*) + mnemonics: + sraw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: *rfmt_base_shift + abstract_comb: + <<: [*rs1val_walking] + 'sp_dataset(xlen,var_lst=["rs1_val"])': 0 + 'walking_ones("rs2_val", 5, False)': 0 + 'walking_zeros("rs2_val", 5, False)': 0 + 'alternate("rs2_val", 5, False)': 0 diff --git a/coverage/rvi.cgf b/coverage/i/rvi.cgf similarity index 100% rename from coverage/rvi.cgf rename to coverage/i/rvi.cgf diff --git a/coverage/k/rv32i_k.cgf b/coverage/k/rv32i_k.cgf new file mode 100644 index 000000000..d75c7dc79 --- /dev/null +++ b/coverage/k/rv32i_k.cgf @@ -0,0 +1,537 @@ +aes32dsi: + config: + - check ISA:=regex(.*RV32.*I.*Zk.*) + - check ISA:=regex(.*RV32.*I.*Zkn.*) + - check ISA:=regex(.*RV32.*I.*Zknd.*) + mnemonics: + aes32dsi: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'byte_count(32,["rs1_val","rs2_val","imm_val"])': 0 + 'uniform_random(20, 100, ["rs1_val","rs2_val","imm_val"], [32, 32, 2])': 0 + +aes32dsmi: + config: + - check ISA:=regex(.*RV32.*I.*Zk.*) + - check ISA:=regex(.*RV32.*I.*Zkn.*) + - check ISA:=regex(.*RV32.*I.*Zknd.*) + mnemonics: + aes32dsmi: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'byte_count(32,["rs1_val","rs2_val","imm_val"])': 0 + 'uniform_random(20, 100, ["rs1_val","rs2_val","imm_val"], [32, 32, 2])': 0 + +aes32esi: + config: + - check ISA:=regex(.*RV32.*I.*Zk.*) + - check ISA:=regex(.*RV32.*I.*Zkn.*) + - check ISA:=regex(.*RV32.*I.*Zkne.*) + mnemonics: + aes32esi: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'byte_count(32,["rs1_val","rs2_val","imm_val"])': 0 + 'uniform_random(20, 100, ["rs1_val","rs2_val","imm_val"], [32, 32, 2])': 0 + +aes32esmi: + config: + - check ISA:=regex(.*RV32.*I.*Zk.*) + - check ISA:=regex(.*RV32.*I.*Zkn.*) + - check ISA:=regex(.*RV32.*I.*Zkne.*) + mnemonics: + aes32esmi: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'byte_count(32,["rs1_val","rs2_val","imm_val"])': 0 + 'uniform_random(20, 100, ["rs1_val","rs2_val","imm_val"], [32, 32, 2])': 0 + +sm4ed: + config: + - check ISA:=regex(.*I.*Zks.*) + - check ISA:=regex(.*I.*Zksed.*) + mnemonics: + sm4ed: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'byte_count(32,["rs1_val","rs2_val","imm_val"])': 0 + 'uniform_random(20, 100, ["rs1_val","rs2_val","imm_val"], [32, 32, 2])': 0 + +sm4ks: + config: + - check ISA:=regex(.*I.*Zks.*) + - check ISA:=regex(.*I.*Zksed.*) + mnemonics: + sm4ks: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'byte_count(32,["rs1_val","rs2_val","imm_val"])': 0 + 'uniform_random(20, 100, ["rs1_val","rs2_val","imm_val"], [32, 32, 2])': 0 + +sha256sig0: + config: + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*I.*Zkn.*) + - check ISA:=regex(.*I.*Zknh.*) + mnemonics: + sha256sig0: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'walking_ones("rs1_val", xlen, False)': 0 + 'walking_zeros("rs1_val", xlen, False)': 0 + 'uniform_random(20, 100, ["rs1_val"], [xlen])': 0 + +sha256sig1: + config: + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*I.*Zkn.*) + - check ISA:=regex(.*I.*Zknh.*) + mnemonics: + sha256sig1: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'walking_ones("rs1_val", xlen, False)': 0 + 'walking_zeros("rs1_val", xlen, False)': 0 + 'uniform_random(20, 100, ["rs1_val"], [xlen])': 0 + +sha256sum0: + config: + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*I.*Zkn.*) + - check ISA:=regex(.*I.*Zknh.*) + mnemonics: + sha256sum0: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'walking_ones("rs1_val", xlen, False)': 0 + 'walking_zeros("rs1_val", xlen, False)': 0 + 'uniform_random(20, 100, ["rs1_val"], [xlen])': 0 + +sha256sum1: + config: + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*I.*Zkn.*) + - check ISA:=regex(.*I.*Zknh.*) + mnemonics: + sha256sum1: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'walking_ones("rs1_val", xlen, False)': 0 + 'walking_zeros("rs1_val", xlen, False)': 0 + 'uniform_random(20, 100, ["rs1_val"], [xlen])': 0 + +sm3p0: + config: + - check ISA:=regex(.*I.*Zks.*) + - check ISA:=regex(.*I.*Zksh.*) + mnemonics: + sm3p0: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'walking_ones("rs1_val", xlen, False)': 0 + 'walking_zeros("rs1_val", xlen, False)': 0 + 'uniform_random(20, 100, ["rs1_val"], [xlen])': 0 + +sm3p1: + config: + - check ISA:=regex(.*I.*Zks.*) + - check ISA:=regex(.*I.*Zksh.*) + mnemonics: + sm3p1: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'walking_ones("rs1_val", xlen, False)': 0 + 'walking_zeros("rs1_val", xlen, False)': 0 + 'uniform_random(20, 100, ["rs1_val"], [xlen])': 0 + +sha512sig0h: + config: + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*RV32.*I.*Zkn.*) + - check ISA:=regex(.*RV32.*I.*Zknh.*) + mnemonics: + sha512sig0h: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'walking_ones("rs1_val", xlen, False)': 0 + 'walking_ones("rs2_val", xlen, False)': 0 + 'walking_zeros("rs1_val", xlen, False)': 0 + 'walking_zeros("rs2_val", xlen, False)': 0 + 'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0 + +sha512sig0l: + config: + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*RV32.*I.*Zkn.*) + - check ISA:=regex(.*RV32.*I.*Zknh.*) + mnemonics: + sha512sig0l: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'walking_ones("rs1_val", xlen, False)': 0 + 'walking_ones("rs2_val", xlen, False)': 0 + 'walking_zeros("rs1_val", xlen, False)': 0 + 'walking_zeros("rs2_val", xlen, False)': 0 + 'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0 + +sha512sig1h: + config: + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*RV32.*I.*Zkn.*) + - check ISA:=regex(.*RV32.*I.*Zknh.*) + mnemonics: + sha512sig1h: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'walking_ones("rs1_val", xlen, False)': 0 + 'walking_ones("rs2_val", xlen, False)': 0 + 'walking_zeros("rs1_val", xlen, False)': 0 + 'walking_zeros("rs2_val", xlen, False)': 0 + 'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0 + +sha512sig1l: + config: + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*RV32.*I.*Zkn.*) + - check ISA:=regex(.*RV32.*I.*Zknh.*) + mnemonics: + sha512sig1l: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'walking_ones("rs1_val", xlen, False)': 0 + 'walking_ones("rs2_val", xlen, False)': 0 + 'walking_zeros("rs1_val", xlen, False)': 0 + 'walking_zeros("rs2_val", xlen, False)': 0 + 'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0 + +sha512sum0r: + config: + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*RV32.*I.*Zkn.*) + - check ISA:=regex(.*RV32.*I.*Zknh.*) + mnemonics: + sha512sum0r: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'walking_ones("rs1_val", xlen, False)': 0 + 'walking_ones("rs2_val", xlen, False)': 0 + 'walking_zeros("rs1_val", xlen, False)': 0 + 'walking_zeros("rs2_val", xlen, False)': 0 + 'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0 + +sha512sum1r: + config: + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*RV32.*I.*Zkn.*) + - check ISA:=regex(.*RV32.*I.*Zknh.*) + mnemonics: + sha512sum1r: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'walking_ones("rs1_val", xlen, False)': 0 + 'walking_ones("rs2_val", xlen, False)': 0 + 'walking_zeros("rs1_val", xlen, False)': 0 + 'walking_zeros("rs2_val", xlen, False)': 0 + 'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0 + + + +brev8_32: + config: + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*I.*Zks.*) + - check ISA:=regex(.*I.*Zkn.*) + - check ISA:=regex(.*I.*Zbkb.*) + mnemonics: + brev8: 0 + base_op: grevi + p_op_cond: imm_val == 7 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'rs1_val == 0x1020408': 0 + 'rs1_val == 0x2040801': 0 + 'rs1_val == 0x4080102': 0 + 'rs1_val == 0x8010204': 0 + abstract_comb: + 'leading_ones(64, ["rs1_val"], [32])': 0 + 'trailing_ones(64, ["rs1_val"], [32])': 0 + 'leading_zeros(64, ["rs1_val"], [32])': 0 + 'trailing_zeros(64, ["rs1_val"], [32])': 0 + 'bitmanip_dataset(xlen,["rs1_val"],signed=False)': 0 + +zip: + config: + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*I.*Zkn.*) + - check ISA:=regex(.*I.*Zks.*) + - check ISA:=regex(.*I.*Zbkb.*) + mnemonics: + zip: 0 + base_op: shfli + p_op_cond: imm_val == 15 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'leading_ones(32, ["rs1_val"],[xlen])': 0 + 'trailing_ones(32, ["rs1_val"],[xlen])': 0 + 'leading_zeros(32, ["rs1_val"],[xlen])': 0 + 'trailing_zeros(32, ["rs1_val"],[xlen])': 0 + +unzip: + config: + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*I.*Zkn.*) + - check ISA:=regex(.*I.*Zks.*) + - check ISA:=regex(.*I.*Zbkb.*) + mnemonics: + unzip: 0 + base_op: unshfli + p_op_cond: imm_val == 15 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'leading_ones(32, ["rs1_val"],[xlen])': 0 + 'trailing_ones(32, ["rs1_val"],[xlen])': 0 + 'leading_zeros(32, ["rs1_val"],[xlen])': 0 + 'trailing_zeros(32, ["rs1_val"],[xlen])': 0 + +pack: + config: + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*I.*Zkn.*) + - check ISA:=regex(.*I.*Zks.*) + - check ISA:=regex(.*I.*Zbkb.*) + mnemonics: + pack: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'leading_ones(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + 'trailing_ones(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + 'leading_zeros(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + 'trailing_zeros(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + +packh: + config: + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*I.*Zks.*) + - check ISA:=regex(.*I.*Zkn.*) + - check ISA:=regex(.*I.*Zbkb.*) + mnemonics: + packh: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'leading_ones(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + 'trailing_ones(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + 'leading_zeros(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + 'trailing_zeros(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + +xperm8: + config: + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*I.*Zks.*) + - check ISA:=regex(.*I.*Zkn.*) + - check ISA:=regex(.*I.*Zbkx.*) + mnemonics: + xperm8: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0 + 'leading_ones(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + 'trailing_ones(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + 'leading_zeros(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + 'trailing_zeros(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + +xperm4: + config: + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*I.*Zkn.*) + - check ISA:=regex(.*I.*Zks.*) + - check ISA:=regex(.*I.*Zbkx.*) + mnemonics: + xperm4: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0 + 'leading_ones(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + 'trailing_ones(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + 'leading_zeros(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0 + 'trailing_zeros(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0 diff --git a/coverage/k/rv64i_k.cgf b/coverage/k/rv64i_k.cgf new file mode 100644 index 000000000..87d34b960 --- /dev/null +++ b/coverage/k/rv64i_k.cgf @@ -0,0 +1,517 @@ +# For Licence details look at https://github.com/riscv-software-src/riscv-ctg/-/blob/master/LICENSE.incore + + +brev8: + config: + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*I.*Zks.*) + - check ISA:=regex(.*I.*Zkn.*) + - check ISA:=regex(.*I.*Zbkb.*) + mnemonics: + brev8: 0 + base_op: grevi + p_op_cond: imm_val == 7 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'rs1_val == 0x102040801020408': 0 + 'rs1_val == 0x204080102040801': 0 + 'rs1_val == 0x408010204080102': 0 + 'rs1_val == 0x801020408010204': 0 + abstract_comb: + 'leading_ones(64, ["rs1_val"], [32])': 0 + 'trailing_ones(64, ["rs1_val"], [32])': 0 + 'leading_zeros(64, ["rs1_val"], [32])': 0 + 'trailing_zeros(64, ["rs1_val"], [32])': 0 + + +pack: + config: + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*I.*Zks.*) + - check ISA:=regex(.*I.*Zkn.*) + - check ISA:=regex(.*I.*Zbkb.*) + mnemonics: + pack: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'leading_ones(64, ["rs1_val","rs2_val"], [64,64])': 0 + 'trailing_ones(64, ["rs1_val","rs2_val"], [64,64])': 0 + 'leading_zeros(64, ["rs1_val","rs2_val"], [64,64])': 0 + 'trailing_zeros(64, ["rs1_val","rs2_val"], [64,64])': 0 + +packh: + config: + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*I.*Zks.*) + - check ISA:=regex(.*I.*Zkn.*) + - check ISA:=regex(.*I.*Zbkb.*) + mnemonics: + packh: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'leading_ones(64, ["rs1_val","rs2_val"], [64,64])': 0 + 'trailing_ones(64, ["rs1_val","rs2_val"], [64,64])': 0 + 'leading_zeros(64, ["rs1_val","rs2_val"], [64,64])': 0 + 'trailing_zeros(64, ["rs1_val","rs2_val"], [64,64])': 0 + +packw: + config: + - check ISA:=regex(.*RV64.*I.*Zk.*) + - check ISA:=regex(.*RV64.*I.*Zks.*) + - check ISA:=regex(.*RV64.*I.*Zkn.*) + - check ISA:=regex(.*RV64.*I.*Zbkb.*) + mnemonics: + packw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'leading_ones(64, ["rs1_val","rs2_val"], [64,64])': 0 + 'trailing_ones(64, ["rs1_val","rs2_val"], [64,64])': 0 + 'leading_zeros(64, ["rs1_val","rs2_val"], [64,64])': 0 + 'trailing_zeros(64, ["rs1_val","rs2_val"], [64,64])': 0 + +xperm4: + config: + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*I.*Zks.*) + - check ISA:=regex(.*I.*Zkn.*) + - check ISA:=regex(.*I.*Zbkx.*) + mnemonics: + xperm4: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'uniform_random(20, 100, ["rs1_val","rs2_val"], [64, 64])': 0 + 'leading_ones(64, ["rs1_val","rs2_val"], [64,64])': 0 + 'trailing_ones(64, ["rs1_val","rs2_val"], [64,64])': 0 + 'leading_zeros(64, ["rs1_val","rs2_val"], [64,64])': 0 + 'trailing_zeros(64, ["rs1_val","rs2_val"], [64,64])': 0 + +xperm8: + config: + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*I.*Zks.*) + - check ISA:=regex(.*I.*Zkn.*) + - check ISA:=regex(.*I.*Zbkx.*) + mnemonics: + xperm8: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'uniform_random(20, 100, ["rs1_val","rs2_val"], [64, 64])': 0 + 'walking_ones("rs1_val", 64, False)': 0 + 'walking_ones("rs2_val", 64, False)': 0 + 'trailing_ones(64, ["rs1_val","rs2_val"], [64,64],False)': 0 + 'leading_zeros(64, ["rs1_val","rs2_val"], [64,64],False)': 0 + 'trailing_zeros(64, ["rs1_val","rs2_val"], [64,64],False)': 0 + + +aes64ds: + config: + - check ISA:=regex(.*RV64.*I.*Zk.*) + - check ISA:=regex(.*RV64.*I.*Zkn.*) + - check ISA:=regex(.*RV64.*I.*Zknd.*) + mnemonics: + aes64ds: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'byte_count(64, ["rs1_val","rs2_val"])': 0 + 'uniform_random(20, 100, ["rs1_val","rs2_val"], [64, 64])': 0 + +aes64dsm: + config: + - check ISA:=regex(.*RV64.*I.*Zk.*) + - check ISA:=regex(.*RV64.*I.*Zkn.*) + - check ISA:=regex(.*RV64.*I.*Zknd.*) + mnemonics: + aes64dsm: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'byte_count(64, ["rs1_val","rs2_val"])': 0 + 'uniform_random(20, 100, ["rs1_val","rs2_val"], [64, 64])': 0 + +aes64es: + config: + - check ISA:=regex(.*RV64.*I.*Zk.*) + - check ISA:=regex(.*RV64.*I.*Zkn.*) + - check ISA:=regex(.*RV64.*I.*Zkne.*) + mnemonics: + aes64es: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'byte_count(64, ["rs1_val","rs2_val"])': 0 + 'uniform_random(20, 100, ["rs1_val","rs2_val"], [64, 64])': 0 + +aes64esm: + config: + - check ISA:=regex(.*RV64.*I.*Zk.*) + - check ISA:=regex(.*RV64.*I.*Zkn.*) + - check ISA:=regex(.*RV64.*I.*Zkne.*) + mnemonics: + aes64esm: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'byte_count(64, ["rs1_val","rs2_val"])': 0 + 'uniform_random(20, 100, ["rs1_val","rs2_val"], [64, 64])': 0 + +aes64im: + config: + - check ISA:=regex(.*RV64.*I.*Zk.*) + - check ISA:=regex(.*RV64.*I.*Zkn.*) + - check ISA:=regex(.*RV64.*I.*Zknd.*) + mnemonics: + aes64im: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'walking_ones("rs1_val", 64, False)': 0 + 'walking_zeros("rs1_val", 64, False)': 0 + 'uniform_random(20, 100, ["rs1_val"], [64])': 0 + +aes64ks1i: + config: + - check ISA:=regex(.*RV64.*I.*Zk.*) + - check ISA:=regex(.*RV64.*I.*Zkn.*) + - check ISA:=regex(.*RV64.*I.*Zknd.*) + - check ISA:=regex(.*RV64.*I.*Zkne.*) + mnemonics: + aes64ks1i: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'byte_count(64, ["rs1_val", "imm_val"], "Y")': 0 + 'uniform_random(20, 100, ["rs1_val","imm_val"], [64, log(10,2)])': 0 + +aes64ks2: + config: + - check ISA:=regex(.*RV64.*I.*Zk.*) + - check ISA:=regex(.*RV64.*I.*Zkn.*) + - check ISA:=regex(.*RV64.*I.*Zknd.*) + - check ISA:=regex(.*RV64.*I.*Zkne.*) + mnemonics: + aes64ks2: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'walking_ones("rs1_val", 64, False)': 0 + 'walking_ones("rs2_val", 64, False)': 0 + 'walking_zeros("rs1_val", 64, False)': 0 + 'walking_zeros("rs2_val", 64, False)': 0 + 'uniform_random(20, 100, ["rs1_val","rs2_val"], [64, 64])': 0 + +sha256sig0: + config: + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*I.*Zkn.*) + - check ISA:=regex(.*I.*Zknh.*) + mnemonics: + sha256sig0: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'walking_ones("rs1_val", 64, False)': 0 + 'walking_zeros("rs1_val", 64, False)': 0 + 'uniform_random(20, 100, ["rs1_val"], [64])': 0 + +sha256sig1: + config: + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*I.*Zkn.*) + - check ISA:=regex(.*I.*Zknh.*) + mnemonics: + sha256sig1: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'walking_ones("rs1_val", 64, False)': 0 + 'walking_zeros("rs1_val", 64, False)': 0 + 'uniform_random(20, 100, ["rs1_val"], [64])': 0 + +sha256sum0: + config: + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*I.*Zkn.*) + - check ISA:=regex(.*I.*Zknh.*) + mnemonics: + sha256sum0: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'walking_ones("rs1_val", 64, False)': 0 + 'walking_zeros("rs1_val", 64, False)': 0 + 'uniform_random(20, 100, ["rs1_val"], [64])': 0 + +sha256sum1: + config: + - check ISA:=regex(.*I.*Zk.*) + - check ISA:=regex(.*I.*Zkn.*) + - check ISA:=regex(.*I.*Zknh.*) + mnemonics: + sha256sum1: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'walking_ones("rs1_val", 64, False)': 0 + 'walking_zeros("rs1_val", 64, False)': 0 + 'uniform_random(20, 100, ["rs1_val"], [64])': 0 + +sha512sig0: + config: + - check ISA:=regex(.*RV64.*I.*Zk.*) + - check ISA:=regex(.*RV64.*I.*Zkn.*) + - check ISA:=regex(.*RV64.*I.*Zknh.*) + mnemonics: + sha512sig0: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'walking_ones("rs1_val", 64, False)': 0 + 'walking_zeros("rs1_val", 64, False)': 0 + 'uniform_random(20, 100, ["rs1_val"], [64])': 0 + +sha512sig1: + config: + - check ISA:=regex(.*RV64.*I.*Zk.*) + - check ISA:=regex(.*RV64.*I.*Zkn.*) + - check ISA:=regex(.*RV64.*I.*Zknh.*) + mnemonics: + sha512sig1: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'walking_ones("rs1_val", 64, False)': 0 + 'walking_zeros("rs1_val", 64, False)': 0 + 'uniform_random(20, 100, ["rs1_val"], [64])': 0 + +sha512sum0: + config: + - check ISA:=regex(.*RV64.*I.*Zk.*) + - check ISA:=regex(.*RV64.*I.*Zkn.*) + - check ISA:=regex(.*RV64.*I.*Zknh.*) + mnemonics: + sha512sum0: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'walking_ones("rs1_val", 64, False)': 0 + 'walking_zeros("rs1_val", 64, False)': 0 + 'uniform_random(20, 100, ["rs1_val"], [64])': 0 + +sha512sum1: + config: + - check ISA:=regex(.*RV64.*I.*Zk.*) + - check ISA:=regex(.*RV64.*I.*Zkn.*) + - check ISA:=regex(.*RV64.*I.*Zknh.*) + mnemonics: + sha512sum1: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'walking_ones("rs1_val", 64, False)': 0 + 'walking_zeros("rs1_val", 64, False)': 0 + 'uniform_random(20, 100, ["rs1_val"], [64])': 0 + +sm3p0: + config: + - check ISA:=regex(.*I.*Zks.*) + - check ISA:=regex(.*I.*Zksh.*) + mnemonics: + sm3p0: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'walking_ones("rs1_val", 64, False)': 0 + 'walking_zeros("rs1_val", 64, False)': 0 + 'uniform_random(20, 100, ["rs1_val"], [64])': 0 + +sm3p1: + config: + - check ISA:=regex(.*I.*Zks.*) + - check ISA:=regex(.*I.*Zksh.*) + mnemonics: + sm3p1: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'walking_ones("rs1_val", 64, False)': 0 + 'walking_zeros("rs1_val", 64, False)': 0 + 'uniform_random(20, 100, ["rs1_val"], [64])': 0 + +sm4ed: + config: + - check ISA:=regex(.*I.*Zks.*) + - check ISA:=regex(.*I.*Zksed.*) + mnemonics: + sm4ed: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'byte_count(64, ["rs1_val","rs2_val","imm_val"], "Y")': 0 + 'uniform_random(20, 100, ["rs1_val","rs2_val","imm_val"], [64, 64, 2])': 0 + +sm4ks: + config: + - check ISA:=regex(.*I.*Zks.*) + - check ISA:=regex(.*I.*Zksed.*) + mnemonics: + sm4ks: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'byte_count(64, ["rs1_val","rs2_val","imm_val"], "Y")': 0 + 'uniform_random(20, 100, ["rs1_val","rs2_val","imm_val"], [64, 64, 2])': 0 diff --git a/coverage/m/rv32em.cgf b/coverage/m/rv32em.cgf new file mode 100644 index 000000000..0bee96553 --- /dev/null +++ b/coverage/m/rv32em.cgf @@ -0,0 +1,154 @@ +# For Licence details look at https://github.com/riscv-software-src/riscv-ctg/-/blob/master/LICENSE.incore + +mul: + config: + - check ISA:=regex(.*E.*M.*) ;def RVTEST_E = True + mnemonics: + mul: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +mulh: + config: + - check ISA:=regex(.*E.*M.*) ;def RVTEST_E = True + mnemonics: + mulh: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +mulhu: + config: + - check ISA:=regex(.*E.*M.*) ;def RVTEST_E = True + mnemonics: + mulhu: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + 'sp_dataset(xlen,signed=False)': 0 + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + +mulhsu: + config: + - check ISA:=regex(.*E.*M.*) ;def RVTEST_E = True + mnemonics: + mulhsu: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_unsgn, *rfmt_val_comb_unsgn] + 'rs1_val > 0 and rs2_val > 0': 0 + abstract_comb: + 'sp_dataset(xlen,[("rs1_val",xlen),("rs2_val",xlen,False)])': 0 + <<: [*rs1val_walking, *rs2val_walking_unsgn] + +div: + config: + - check ISA:=regex(.*E.*M.*) ;def RVTEST_E = True + mnemonics: + div: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +divu: + config: + - check ISA:=regex(.*E.*M.*) ;def RVTEST_E = True + mnemonics: + divu: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + 'sp_dataset(xlen,signed=False)': 0 + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + +rem: + config: + - check ISA:=regex(.*E.*M.*) ;def RVTEST_E = True + mnemonics: + rem: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +remu: + config: + - check ISA:=regex(.*E.*M.*) ;def RVTEST_E = True + mnemonics: + remu: 0 + rs1: + <<: *rv32e_regs + rs2: + <<: *rv32e_regs + rd: + <<: *rv32e_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + 'sp_dataset(xlen,signed=False)': 0 + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] diff --git a/coverage/m/rv32im.cgf b/coverage/m/rv32im.cgf new file mode 100644 index 000000000..d69131e4d --- /dev/null +++ b/coverage/m/rv32im.cgf @@ -0,0 +1,154 @@ +# For Licence details look at https://github.com/riscv-software-src/riscv-ctg/-/blob/master/LICENSE.incore + +mul: + config: + - check ISA:=regex(.*I.*M.*) + mnemonics: + mul: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +mulh: + config: + - check ISA:=regex(.*I.*M.*) + mnemonics: + mulh: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +mulhu: + config: + - check ISA:=regex(.*I.*M.*) + mnemonics: + mulhu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + 'sp_dataset(xlen,signed=False)': 0 + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + +mulhsu: + config: + - check ISA:=regex(.*I.*M.*) + mnemonics: + mulhsu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_unsgn, *rfmt_val_comb_unsgn] + 'rs1_val > 0 and rs2_val > 0': 0 + abstract_comb: + 'sp_dataset(xlen,[("rs1_val",xlen),("rs2_val",xlen,False)])': 0 + <<: [*rs1val_walking, *rs2val_walking_unsgn] + +div: + config: + - check ISA:=regex(.*I.*M.*) + mnemonics: + div: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: [*rfmt_op_comb , *div_hardcoded_opcomb] + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn, *div_corner_case] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +divu: + config: + - check ISA:=regex(.*I.*M.*) + mnemonics: + divu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: [*rfmt_op_comb , *div_hardcoded_opcomb] + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + 'sp_dataset(xlen,signed=False)': 0 + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + +rem: + config: + - check ISA:=regex(.*I.*M.*) + mnemonics: + rem: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: [*rfmt_op_comb , *div_hardcoded_opcomb] + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn, *div_corner_case] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +remu: + config: + - check ISA:=regex(.*I.*M.*) + mnemonics: + remu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: [*rfmt_op_comb , *div_hardcoded_opcomb] + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + 'sp_dataset(xlen,signed=False)': 0 + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] diff --git a/coverage/m/rv64im.cgf b/coverage/m/rv64im.cgf new file mode 100644 index 000000000..92ac8c096 --- /dev/null +++ b/coverage/m/rv64im.cgf @@ -0,0 +1,250 @@ +# For Licence details look at https://github.com/riscv-software-src/riscv-ctg/-/blob/master/LICENSE.incore + +mul: + config: + - check ISA:=regex(.*I.*M.*) + mnemonics: + mul: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +mulh: + config: + - check ISA:=regex(.*I.*M.*) + mnemonics: + mulh: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +mulhu: + config: + - check ISA:=regex(.*I.*M.*) + mnemonics: + mulhu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + 'sp_dataset(xlen,signed=False)': 0 + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + +mulhsu: + config: + - check ISA:=regex(.*I.*M.*) + mnemonics: + mulhsu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_unsgn, *rfmt_val_comb_unsgn] + 'rs1_val < 0 and rs2_val > 0': 0 + abstract_comb: + 'sp_dataset(xlen,[("rs1_val",xlen),("rs2_val",xlen,False)])': 0 + <<: [*rs1val_walking, *rs2val_walking_unsgn] + +div: + config: + - check ISA:=regex(.*I.*M.*) + mnemonics: + div: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn, *div_corner_case] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +divu: + config: + - check ISA:=regex(.*I.*M.*) + mnemonics: + divu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + 'sp_dataset(xlen,signed=False)': 0 + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + +rem: + config: + - check ISA:=regex(.*I.*M.*) + mnemonics: + rem: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn, *div_corner_case] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +remu: + config: + - check ISA:=regex(.*I.*M.*) + mnemonics: + remu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + 'sp_dataset(xlen,signed=False)': 0 + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + +mulw: + config: + - check ISA:=regex(.*RV64.*I.*M.*) + mnemonics: + mulw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +divw: + config: + - check ISA:=regex(.*RV64.*I.*M.*) + mnemonics: + divw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn, *div_corner_case] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +divuw: + config: + - check ISA:=regex(.*RV64.*I.*M.*) + mnemonics: + divuw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + 'sp_dataset(xlen,signed=False)': 0 + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + +remw: + config: + - check ISA:=regex(.*RV64.*I.*M.*) + mnemonics: + remw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn, *div_corner_case] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +remuw: + config: + - check ISA:=regex(.*RV64.*I.*M.*) + mnemonics: + remuw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + 'sp_dataset(xlen,signed=False)': 0 + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + diff --git a/coverage/rvi_m.cgf b/coverage/m/rvi_m.cgf similarity index 100% rename from coverage/rvi_m.cgf rename to coverage/m/rvi_m.cgf diff --git a/coverage/p/rv32ip.cgf b/coverage/p/rv32ip.cgf new file mode 100644 index 000000000..3fa586ed5 --- /dev/null +++ b/coverage/p/rv32ip.cgf @@ -0,0 +1,4419 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +add16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + add16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +radd16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + radd16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +uradd16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + uradd16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=False)': 0 + 'simd_base_val("rs2", xlen, 16, signed=False)': 0 + 'simd_val_comb(xlen, 16, signed=False)': 0 + +kadd16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kadd16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +ukadd16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + ukadd16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=False)': 0 + 'simd_base_val("rs2", xlen, 16, signed=False)': 0 + 'simd_val_comb(xlen, 16, signed=False)': 0 + +sub16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + sub16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +rsub16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + rsub16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + + +ursub16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + ursub16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=False)': 0 + 'simd_base_val("rs2", xlen, 16, signed=False)': 0 + 'simd_val_comb(xlen, 16, signed=False)': 0 + +ksub16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + ksub16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +uksub16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + uksub16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=False)': 0 + 'simd_base_val("rs2", xlen, 16, signed=False)': 0 + 'simd_val_comb(xlen, 16, signed=False)': 0 + +cras16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + cras16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +rcras16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + rcras16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +urcras16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + urcras16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=False)': 0 + 'simd_base_val("rs2", xlen, 16, signed=False)': 0 + 'simd_val_comb(xlen, 16, signed=False)': 0 + +kcras16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kcras16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +ukcras16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + ukcras16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=False)': 0 + 'simd_base_val("rs2", xlen, 16, signed=False)': 0 + 'simd_val_comb(xlen, 16, signed=False)': 0 + +crsa16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + crsa16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +rcrsa16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + rcrsa16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +urcrsa16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + urcrsa16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=False)': 0 + 'simd_base_val("rs2", xlen, 16, signed=False)': 0 + 'simd_val_comb(xlen, 16, signed=False)': 0 + +kcrsa16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kcrsa16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +ukcrsa16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + ukcrsa16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=False)': 0 + 'simd_base_val("rs2", xlen, 16, signed=False)': 0 + 'simd_val_comb(xlen, 16, signed=False)': 0 + +stas16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + stas16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +rstas16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + rstas16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +urstas16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + urstas16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=False)': 0 + 'simd_base_val("rs2", xlen, 16, signed=False)': 0 + 'simd_val_comb(xlen, 16, signed=False)': 0 + +kstas16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kstas16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +ukstas16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + ukstas16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=False)': 0 + 'simd_base_val("rs2", xlen, 16, signed=False)': 0 + 'simd_val_comb(xlen, 16, signed=False)': 0 + +stsa16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + stsa16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +rstsa16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + rstsa16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +urstsa16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + urstsa16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=False)': 0 + 'simd_base_val("rs2", xlen, 16, signed=False)': 0 + 'simd_val_comb(xlen, 16, signed=False)': 0 + +kstsa16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kstsa16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +ukstsa16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + ukstsa16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=False)': 0 + 'simd_base_val("rs2", xlen, 16, signed=False)': 0 + 'simd_val_comb(xlen, 16, signed=False)': 0 + +add8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + add8: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=True)': 0 + 'simd_base_val("rs2", xlen, 8, signed=True)': 0 + 'simd_val_comb(xlen, 8, signed=True)': 0 + +radd8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + radd8: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=True)': 0 + 'simd_base_val("rs2", xlen, 8, signed=True)': 0 + 'simd_val_comb(xlen, 8, signed=True)': 0 + +uradd8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + uradd8: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=False)': 0 + 'simd_base_val("rs2", xlen, 8, signed=False)': 0 + 'simd_val_comb(xlen, 8, signed=False)': 0 + +kadd8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kadd8: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=True)': 0 + 'simd_base_val("rs2", xlen, 8, signed=True)': 0 + 'simd_val_comb(xlen, 8, signed=True)': 0 + +ukadd8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + ukadd8: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=False)': 0 + 'simd_base_val("rs2", xlen, 8, signed=False)': 0 + 'simd_val_comb(xlen, 8, signed=False)': 0 + +sub8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + sub8: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=True)': 0 + 'simd_base_val("rs2", xlen, 8, signed=True)': 0 + 'simd_val_comb(xlen, 8, signed=True)': 0 + +rsub8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + rsub8: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=True)': 0 + 'simd_base_val("rs2", xlen, 8, signed=True)': 0 + 'simd_val_comb(xlen, 8, signed=True)': 0 + +ursub8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + ursub8: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=False)': 0 + 'simd_base_val("rs2", xlen, 8, signed=False)': 0 + 'simd_val_comb(xlen, 8, signed=False)': 0 + +ksub8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + ksub8: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=True)': 0 + 'simd_base_val("rs2", xlen, 8, signed=True)': 0 + 'simd_val_comb(xlen, 8, signed=True)': 0 + +uksub8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + uksub8: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=False)': 0 + 'simd_base_val("rs2", xlen, 8, signed=False)': 0 + 'simd_val_comb(xlen, 8, signed=False)': 0 + +sra16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + sra16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'walking_ones("rs2_val", ceil(log(16, 2)), False)': 0 + 'walking_zeros("rs2_val", ceil(log(16, 2)), False)': 0 + 'alternate("rs2_val", ceil(log(16, 2)), False)': 0 + +srai16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + srai16: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_imm_val("imm_val", 4)': 0 + +sra16.u: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + sra16.u: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'walking_ones("rs2_val", ceil(log(16, 2)), False)': 0 + 'walking_zeros("rs2_val", ceil(log(16, 2)), False)': 0 + 'alternate("rs2_val", ceil(log(16, 2)), False)': 0 + +srai16.u: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + srai16.u: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_imm_val("imm_val", 4)': 0 + +srl16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + srl16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=False)': 0 + 'walking_ones("rs2_val", ceil(log(16, 2)), False)': 0 + 'walking_zeros("rs2_val", ceil(log(16, 2)), False)': 0 + 'alternate("rs2_val", ceil(log(16, 2)), False)': 0 + +srli16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + srli16: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=False)': 0 + 'simd_imm_val("imm_val", 4)': 0 + +srl16.u: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + srl16.u: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=False)': 0 + 'walking_ones("rs2_val", ceil(log(16, 2)), False)': 0 + 'walking_zeros("rs2_val", ceil(log(16, 2)), False)': 0 + 'alternate("rs2_val", ceil(log(16, 2)), False)': 0 + +srli16.u: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + srli16.u: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=False)': 0 + 'simd_imm_val("imm_val", 4)': 0 + +sll16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + sll16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=False)': 0 + 'walking_ones("rs2_val", ceil(log(16, 2)), False)': 0 + 'walking_zeros("rs2_val", ceil(log(16, 2)), False)': 0 + 'alternate("rs2_val", ceil(log(16, 2)), False)': 0 + +slli16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + slli16: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=False)': 0 + 'simd_imm_val("imm_val", 4)': 0 + +ksll16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + ksll16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'walking_ones("rs2_val", ceil(log(16, 2)), False)': 0 + 'walking_zeros("rs2_val", ceil(log(16, 2)), False)': 0 + 'alternate("rs2_val", ceil(log(16, 2)), False)': 0 + +kslli16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kslli16: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_imm_val("imm_val", 4)': 0 + +kslra16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kslra16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'walking_ones("rs2_val", xlen, True)': 0 + 'walking_zeros("rs2_val", xlen, True)': 0 + 'alternate("rs2_val", xlen, True)': 0 + +kslra16.u: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kslra16.u: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=False)': 0 + 'walking_ones("rs2_val", xlen, True)': 0 + 'walking_zeros("rs2_val", xlen, True)': 0 + 'alternate("rs2_val", xlen, True)': 0 + +sra8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + sra8: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=True)': 0 + 'walking_ones("rs2_val", ceil(log(8, 2)), False)': 0 + 'walking_zeros("rs2_val", ceil(log(8, 2)), False)': 0 + 'alternate("rs2_val", ceil(log(8, 2)), False)': 0 + +srai8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + srai8: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=True)': 0 + 'simd_imm_val("imm_val", 3)': 0 + +sra8.u: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + sra8.u: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=True)': 0 + 'walking_ones("rs2_val", ceil(log(8, 2)), False)': 0 + 'walking_zeros("rs2_val", ceil(log(8, 2)), False)': 0 + 'alternate("rs2_val", ceil(log(8, 2)), False)': 0 + +srai8.u: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + srai8.u: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=True)': 0 + 'simd_imm_val("imm_val", 3)': 0 + +srl8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + srl8: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=False)': 0 + 'walking_ones("rs2_val", ceil(log(8, 2)), False)': 0 + 'walking_zeros("rs2_val", ceil(log(8, 2)), False)': 0 + 'alternate("rs2_val", ceil(log(8, 2)), False)': 0 + +srli8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + srli8: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=False)': 0 + 'simd_imm_val("imm_val", 3)': 0 + +srl8.u: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + srl8.u: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=False)': 0 + 'walking_ones("rs2_val", ceil(log(8, 2)), False)': 0 + 'walking_zeros("rs2_val", ceil(log(8, 2)), False)': 0 + 'alternate("rs2_val", ceil(log(8, 2)), False)': 0 + +srli8.u: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + srli8.u: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=False)': 0 + 'simd_imm_val("imm_val", 3)': 0 + +sll8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + sll8: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=False)': 0 + 'walking_ones("rs2_val", ceil(log(8, 2)), False)': 0 + 'walking_zeros("rs2_val", ceil(log(8, 2)), False)': 0 + 'alternate("rs2_val", ceil(log(8, 2)), False)': 0 + +slli8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + slli8: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=False)': 0 + 'simd_imm_val("imm_val", 3)': 0 + +ksll8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + ksll8: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=True)': 0 + 'walking_ones("rs2_val", ceil(log(8, 2)), False)': 0 + 'walking_zeros("rs2_val", ceil(log(8, 2)), False)': 0 + 'alternate("rs2_val", ceil(log(8, 2)), False)': 0 + +kslli8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kslli8: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=True)': 0 + 'simd_imm_val("imm_val", 3)': 0 + +kslra8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kslra8: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=True)': 0 + 'walking_ones("rs2_val", xlen, True)': 0 + 'walking_zeros("rs2_val", xlen, True)': 0 + 'alternate("rs2_val", xlen, True)': 0 + +kslra8.u: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kslra8.u: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=False)': 0 + 'walking_ones("rs2_val", xlen, True)': 0 + 'walking_zeros("rs2_val", xlen, True)': 0 + 'alternate("rs2_val", xlen, True)': 0 + +cmpeq16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + cmpeq16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +scmplt16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + scmplt16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +scmple16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + scmple16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +ucmplt16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + ucmplt16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=False)': 0 + 'simd_base_val("rs2", xlen, 16, signed=False)': 0 + 'simd_val_comb(xlen, 16, signed=False)': 0 + +ucmple16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + ucmple16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=False)': 0 + 'simd_base_val("rs2", xlen, 16, signed=False)': 0 + 'simd_val_comb(xlen, 16, signed=False)': 0 + +cmpeq8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + cmpeq8: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=True)': 0 + 'simd_base_val("rs2", xlen, 8, signed=True)': 0 + 'simd_val_comb(xlen, 8, signed=True)': 0 + +scmplt8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + scmplt8: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=True)': 0 + 'simd_base_val("rs2", xlen, 8, signed=True)': 0 + 'simd_val_comb(xlen, 8, signed=True)': 0 + +scmple8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + scmple8: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=True)': 0 + 'simd_base_val("rs2", xlen, 8, signed=True)': 0 + 'simd_val_comb(xlen, 8, signed=True)': 0 + +ucmplt8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + ucmplt8: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=False)': 0 + 'simd_base_val("rs2", xlen, 8, signed=False)': 0 + 'simd_val_comb(xlen, 8, signed=False)': 0 + +ucmple8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + ucmple8: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=False)': 0 + 'simd_base_val("rs2", xlen, 8, signed=False)': 0 + 'simd_val_comb(xlen, 8, signed=False)': 0 + +smul16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smul16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +smulx16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smulx16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +umul16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + umul16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=False)': 0 + 'simd_base_val("rs2", xlen, 16, signed=False)': 0 + 'simd_val_comb(xlen, 16, signed=False)': 0 + +umulx16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + umulx16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=False)': 0 + 'simd_base_val("rs2", xlen, 16, signed=False)': 0 + 'simd_val_comb(xlen, 16, signed=False)': 0 + +khm16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + khm16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +khmx16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + khmx16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +smul8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smul8: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=True)': 0 + 'simd_base_val("rs2", xlen, 8, signed=True)': 0 + 'simd_val_comb(xlen, 8, signed=True)': 0 + +smulx8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smulx8: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=True)': 0 + 'simd_base_val("rs2", xlen, 8, signed=True)': 0 + 'simd_val_comb(xlen, 8, signed=True)': 0 + +umul8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + umul8: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=False)': 0 + 'simd_base_val("rs2", xlen, 8, signed=False)': 0 + 'simd_val_comb(xlen, 8, signed=False)': 0 + +umulx8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + umulx8: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=False)': 0 + 'simd_base_val("rs2", xlen, 8, signed=False)': 0 + 'simd_val_comb(xlen, 8, signed=False)': 0 + +khm8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + khm8: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=True)': 0 + 'simd_base_val("rs2", xlen, 8, signed=True)': 0 + 'simd_val_comb(xlen, 8, signed=True)': 0 + +khmx8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + khmx8: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=True)': 0 + 'simd_base_val("rs2", xlen, 8, signed=True)': 0 + 'simd_val_comb(xlen, 8, signed=True)': 0 + +smin16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smin16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +umin16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + umin16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=False)': 0 + 'simd_base_val("rs2", xlen, 16, signed=False)': 0 + 'simd_val_comb(xlen, 16, signed=False)': 0 + +smax16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smax16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +umax16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + umax16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=False)': 0 + 'simd_base_val("rs2", xlen, 16, signed=False)': 0 + 'simd_val_comb(xlen, 16, signed=False)': 0 + +sclip16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + sclip16: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_imm_val("imm_val", 4)': 0 + +uclip16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + uclip16: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=False)': 0 + 'simd_imm_val("imm_val", 4)': 0 + +kabs16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kabs16: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + +clrs16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + clrs16: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + +clz16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + clz16: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=False)': 0 + +# alias of pkbt16 +# swap16: +# config: +# - check ISA:=regex(.*I.*P.*Zicsr.*) +# mnemonics: +# swap16: 0 +# rs1: +# <<: *all_regs +# rd: +# <<: *all_regs +# val_comb: +# abstract_comb: +# 'simd_base_val("rs1", xlen, 16, signed=False)': 0 + +smin8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smin8: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=True)': 0 + 'simd_base_val("rs2", xlen, 8, signed=True)': 0 + 'simd_val_comb(xlen, 8, signed=True)': 0 + +umin8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + umin8: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=False)': 0 + 'simd_base_val("rs2", xlen, 8, signed=False)': 0 + 'simd_val_comb(xlen, 8, signed=False)': 0 + +smax8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smax8: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=True)': 0 + 'simd_base_val("rs2", xlen, 8, signed=True)': 0 + 'simd_val_comb(xlen, 8, signed=True)': 0 + +umax8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + umax8: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=False)': 0 + 'simd_base_val("rs2", xlen, 8, signed=False)': 0 + 'simd_val_comb(xlen, 8, signed=False)': 0 + +kabs8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kabs8: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=True)': 0 + +sclip8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + sclip8: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=True)': 0 + 'simd_imm_val("imm_val", 3)': 0 + +uclip8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + uclip8: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=False)': 0 + 'simd_imm_val("imm_val", 3)': 0 + +clrs8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + clrs8: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=True)': 0 + +clz8: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + clz8: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=False)': 0 + +# instructions overlapping with those in the B extension in RV32/RV64 configuration (Zbpbo) +# swap8: +# config: +# - check ISA:=regex(.*I.*P.*Zicsr.*) +# mnemonics: +# swap8: 0 +# rs1: +# <<: *all_regs +# rd: +# <<: *all_regs +# val_comb: +# abstract_comb: +# 'simd_base_val("rs1", xlen, 8, signed=False)': 0 + +sunpkd810: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + sunpkd810: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=True)': 0 + +sunpkd820: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + sunpkd820: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=True)': 0 + +sunpkd830: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + sunpkd830: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=True)': 0 + +sunpkd831: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + sunpkd831: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=True)': 0 + +sunpkd832: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + sunpkd832: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=True)': 0 + +zunpkd810: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + zunpkd810: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=False)': 0 + +zunpkd820: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + zunpkd820: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=False)': 0 + +zunpkd830: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + zunpkd830: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=False)': 0 + +zunpkd831: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + zunpkd831: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=False)': 0 + +zunpkd832: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + zunpkd832: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=False)': 0 + +# instructions overlapping with those in the B extension in RV32 configuration (Zbpbo) +# pkbb16: +# config: +# - check ISA:=regex(.*I.*P.*Zicsr.*) +# mnemonics: +# pkbb16: 0 +# rs1: +# <<: *all_regs +# rs2: +# <<: *all_regs +# rd: +# <<: *all_regs +# op_comb: +# <<: *rfmt_op_comb +# val_comb: +# abstract_comb: +# 'simd_base_val("rs1", xlen, 16, signed=False)': 0 +# 'simd_base_val("rs2", xlen, 16, signed=False)': 0 +# 'simd_val_comb(xlen, 16, signed=False)': 0 + +pkbt16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + pkbt16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=False)': 0 + 'simd_base_val("rs2", xlen, 16, signed=False)': 0 + 'simd_val_comb(xlen, 16, signed=False)': 0 + +pktb16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + pktb16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=False)': 0 + 'simd_base_val("rs2", xlen, 16, signed=False)': 0 + 'simd_val_comb(xlen, 16, signed=False)': 0 + +# instructions overlapping with those in the B extension in RV32 configuration (Zbpbo) +# pktt16: +# config: +# - check ISA:=regex(.*I.*P.*Zicsr.*) +# mnemonics: +# pktt16: 0 +# rs1: +# <<: *all_regs +# rs2: +# <<: *all_regs +# rd: +# <<: *all_regs +# op_comb: +# <<: *rfmt_op_comb +# val_comb: +# abstract_comb: +# 'simd_base_val("rs1", xlen, 16, signed=False)': 0 +# 'simd_base_val("rs2", xlen, 16, signed=False)': 0 +# 'simd_val_comb(xlen, 16, signed=False)': 0 + +# 2.3.2. +smmul: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smmul: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + +smmul.u: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smmul.u: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + +kmmac: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmmac: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + +kmmac.u: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmmac.u: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + +kmmsb: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmmsb: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + +kmmsb.u: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmmsb.u: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + +kwmmul: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kwmmul: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + +kwmmul.u: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kwmmul.u: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + + +# 2.3.3 Most Significant Word 32x32 Multiply & Add Instructions + +smmwb: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smmwb: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + +smmwb.u: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smmwb.u: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + +smmwt: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smmwt: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + +smmwt.u: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smmwt.u: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + + +kmmawb: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmmawb: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + +kmmawb.u: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmmawb.u: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + +kmmawt: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmmawt: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + +kmmawt.u: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmmawt.u: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + + +kmmwb2: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmmwb2: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + +kmmwb2.u: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmmwb2.u: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + +kmmwt2: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmmwt2: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + +kmmwt2.u: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmmwt2.u: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + + +kmmawb2: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmmawb2: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + +kmmawb2.u: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmmawb2.u: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + +kmmawt2: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmmawt2: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + +kmmawt2.u: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmmawt2.u: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + +# 2.3.4 + +smbb16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smbb16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +smbt16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smbt16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +smtt16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smtt16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +kmda: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmda: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +kmxda: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmxda: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 +smds: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smds: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +smdrs: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smdrs: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +smxds: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smxds: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +kmabb: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmabb: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +kmabt: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmabt: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +kmatt: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmatt: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +kmada: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmada: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +kmaxda: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmaxda: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +kmads: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmads: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +kmadrs: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmadrs: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +kmaxds: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmaxds: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +kmsda: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmsda: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +kmsxda: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmsxda: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +# 2.3.5 +smal: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smal: 0 + rs1: + <<: *pair_regs + rs2: + <<: *all_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*rvp64_rs1val_sgn] + abstract_comb: + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + +# 2.3.6 Miscellaneous Instructions + +sclip32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + sclip32: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_imm_val("imm_val", 5)': 0 + +uclip32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + uclip32: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=False)': 0 + 'simd_imm_val("imm_val", 5)': 0 + +clrs32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + clrs32: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + +# instructions overlapping with those in the B extension in RV32 configuration (Zbpbo) +# clz32: +# config: +# - check ISA:=regex(.*I.*P.*Zicsr.*) +# mnemonics: +# clz32: 0 +# rs1: +# <<: *all_regs +# rd: +# <<: *all_regs +# val_comb: +# abstract_comb: +# 'simd_base_val("rs1", xlen, 32, signed=False)': 0 + +pbsad: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + pbsad: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=False)': 0 + 'simd_base_val("rs2", xlen, 8, signed=False)': 0 + 'simd_val_comb(xlen, 8, signed=False)': 0 + +pbsada: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + pbsada: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=False)': 0 + 'simd_base_val("rs2", xlen, 8, signed=False)': 0 + 'simd_val_comb(xlen, 8, signed=False)': 0 + +smaqa: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smaqa: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=True)': 0 + 'simd_base_val("rs2", xlen, 8, signed=True)': 0 + 'simd_val_comb(xlen, 8, signed=True)': 0 + +umaqa: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + umaqa: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=False)': 0 + 'simd_base_val("rs2", xlen, 8, signed=False)': 0 + 'simd_val_comb(xlen, 8, signed=False)': 0 + +smaqa.su: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smaqa.su: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 8, signed=True)': 0 + 'simd_base_val("rs2", xlen, 8, signed=True)': 0 + 'simd_val_comb(xlen, 8, signed=True)': 0 + +# 2.4.1 +add64: + config: + - check ISA:=regex(.*32.*I.*P.*Zicsr.*) + mnemonics: + add64: 0 + rs1: + <<: *pair_regs + rs2: + <<: *pair_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*rvp64_rs1val_sgn, *rvp64_rs2val_sgn, *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rvp64_rs1val_walking_sgn, *rvp64_rs2val_walking_sgn] + +radd64: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + radd64: 0 + rs1: + <<: *pair_regs + rs2: + <<: *pair_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*rvp64_rs1val_sgn, *rvp64_rs2val_sgn, *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rvp64_rs1val_walking_sgn, *rvp64_rs2val_walking_sgn] + +uradd64: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + uradd64: 0 + rs1: + <<: *pair_regs + rs2: + <<: *pair_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*rvp64_rs1val_unsgn, *rvp64_rs2val_unsgn, *rfmt_val_comb_unsgn] + abstract_comb: + <<: [*rvp64_rs1val_walking_unsgn, *rvp64_rs2val_walking_unsgn] + +kadd64: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kadd64: 0 + rs1: + <<: *pair_regs + rs2: + <<: *pair_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*rvp64_rs1val_sgn, *rvp64_rs2val_sgn, *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rvp64_rs1val_walking_sgn, *rvp64_rs2val_walking_sgn] + +ukadd64: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + ukadd64: 0 + rs1: + <<: *pair_regs + rs2: + <<: *pair_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*rvp64_rs1val_unsgn, *rvp64_rs2val_unsgn, *rfmt_val_comb_unsgn] + abstract_comb: + <<: [*rvp64_rs1val_walking_unsgn, *rvp64_rs2val_walking_unsgn] + +sub64: + config: + - check ISA:=regex(.*32.*I.*P.*Zicsr.*) + mnemonics: + sub64: 0 + rs1: + <<: *pair_regs + rs2: + <<: *pair_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*rvp64_rs1val_sgn, *rvp64_rs2val_sgn, *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rvp64_rs1val_walking_sgn, *rvp64_rs2val_walking_sgn] + +rsub64: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + rsub64: 0 + rs1: + <<: *pair_regs + rs2: + <<: *pair_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*rvp64_rs1val_sgn, *rvp64_rs2val_sgn, *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rvp64_rs1val_walking_sgn, *rvp64_rs2val_walking_sgn] + +ursub64: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + ursub64: 0 + rs1: + <<: *pair_regs + rs2: + <<: *pair_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*rvp64_rs1val_unsgn, *rvp64_rs2val_unsgn, *rfmt_val_comb_unsgn] + abstract_comb: + <<: [*rvp64_rs1val_walking_unsgn, *rvp64_rs2val_walking_unsgn] + +ksub64: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + ksub64: 0 + rs1: + <<: *pair_regs + rs2: + <<: *pair_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*rvp64_rs1val_sgn, *rvp64_rs2val_sgn, *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rvp64_rs1val_walking_sgn, *rvp64_rs2val_walking_sgn] + +uksub64: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + uksub64: 0 + rs1: + <<: *pair_regs + rs2: + <<: *pair_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*rvp64_rs1val_unsgn, *rvp64_rs2val_unsgn, *rfmt_val_comb_unsgn] + abstract_comb: + <<: [*rvp64_rs1val_walking_unsgn, *rvp64_rs2val_walking_unsgn] + +# 2.4.2 +smar64: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smar64: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +smsr64: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smsr64: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +umar64: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + umar64: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=False)': 0 + 'simd_base_val("rs2", xlen, 32, signed=False)': 0 + 'simd_val_comb(xlen, 32, signed=False)': 0 + +umsr64: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + umsr64: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=False)': 0 + 'simd_base_val("rs2", xlen, 32, signed=False)': 0 + 'simd_val_comb(xlen, 32, signed=False)': 0 + +kmar64: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmar64: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +kmsr64: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmsr64: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +ukmar64: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + ukmar64: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=False)': 0 + 'simd_base_val("rs2", xlen, 32, signed=False)': 0 + 'simd_val_comb(xlen, 32, signed=False)': 0 + +ukmsr64: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + ukmsr64: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=False)': 0 + 'simd_base_val("rs2", xlen, 32, signed=False)': 0 + 'simd_val_comb(xlen, 32, signed=False)': 0 + +# 2.4.3 +smalbb: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smalbb: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +smalbt: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smalbt: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +smaltt: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smaltt: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +smalda: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smalda: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +smalxda: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smalxda: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +smalds: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smalds: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +smaldrs: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smaldrs: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +smalxds: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smalxds: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +smslda: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smslda: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +smslxda: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smslxda: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +# 2.5 Non-SIMD Instructions + +kaddh: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kaddh: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +ksubh: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + ksubh: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +khmbb: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + khmbb: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +khmbt: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + khmbt: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +khmtt: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + khmtt: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +ukaddh: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + ukaddh: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=False)': 0 + 'simd_base_val("rs2", xlen, 16, signed=False)': 0 + 'simd_val_comb(xlen, 16, signed=False)': 0 + +uksubh: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + uksubh: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=False)': 0 + 'simd_base_val("rs2", xlen, 16, signed=False)': 0 + 'simd_val_comb(xlen, 16, signed=False)': 0 + +kaddw: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kaddw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +ukaddw: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + ukaddw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=False)': 0 + 'simd_base_val("rs2", xlen, 32, signed=False)': 0 + 'simd_val_comb(xlen, 32, signed=False)': 0 + +ksubw: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + ksubw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +uksubw: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + uksubw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=False)': 0 + 'simd_base_val("rs2", xlen, 32, signed=False)': 0 + 'simd_val_comb(xlen, 32, signed=False)': 0 + +kdmbb: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kdmbb: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +kdmbt: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kdmbt: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +kdmtt: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kdmtt: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +kslraw: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kslraw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +kslraw.u: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kslraw.u: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + 'rs1_w0_val == rs2_w0_val': 0 + 'rs1_w0_val != rs2_w0_val': 0 + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=False)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + +ksllw: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + ksllw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'walking_ones("rs2_val", ceil(log(32, 2)), False)': 0 + 'walking_zeros("rs2_val", ceil(log(32, 2)), False)': 0 + 'alternate("rs2_val", ceil(log(32, 2)), False)': 0 + +kslliw: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kslliw: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_imm_val("imm_val", 5)': 0 + +kdmabb: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kdmabb: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +kdmabt: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kdmabt: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +kdmatt: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kdmatt: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +kabsw: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kabsw: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + +# 2.5.3. +raddw: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + raddw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + +uraddw: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + uraddw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=False)': 0 + 'simd_base_val("rs2", xlen, 32, signed=False)': 0 + +rsubw: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + rsubw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + +ursubw: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + ursubw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=False)': 0 + 'simd_base_val("rs2", xlen, 32, signed=False)': 0 + +mulr64: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + mulr64: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=False)': 0 + 'simd_base_val("rs2", xlen, 32, signed=False)': 0 +mulsr64: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + mulsr64: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *pair_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + +maddr32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + maddr32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + +msubr32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + msubr32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + +# 2.5.4 +# alias of csr operations +# rdov: +# config: +# - check ISA:=regex(.*I.*P.*Zicsr.*) +# mnemonics: +# rdov: 0 +# rd: +# <<: *all_regs +# +# +# clrov: +# config: +# - check ISA:=regex(.*I.*P.*Zicsr.*) +# mnemonics: +# clrov: 0 +# rd: +# <<: *all_regs + +# 2.5.5. +ave: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + ave: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn, *base_rs2val_sgn, *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +sra.u: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + sra.u: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn, *base_rs2val_sgn, *rfmt_val_comb_sgn] + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + +srai.u: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + srai.u: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + <<: [*rs1val_walking, *ifmt_immval_walking_len] + + +# instructions overlapping with those in the B extension in RV32/RV64 configuration (Zbpbo) +# bitrev: +# config: +# - check ISA:=regex(.*I.*P.*Zicsr.*) +# mnemonics: +# bitrev: 0 +# rs1: +# <<: *all_regs +# rs2: +# <<: *all_regs +# rd: +# <<: *all_regs +# op_comb: +# <<: *rfmt_op_comb +# val_comb: +# <<: [*base_rs1val_sgn, *base_rs2val_sgn, *rfmt_val_comb_sgn] +# abstract_comb: +# <<: [*rs1val_walking, *rs2val_walking] +# +# +# bitrevi: +# config: +# - check ISA:=regex(.*I.*P.*Zicsr.*) +# mnemonics: +# bitrevi: 0 +# rs1: +# <<: *all_regs +# rd: +# <<: *all_regs +# op_comb: +# <<: *ifmt_op_comb +# val_comb: +# abstract_comb: +# <<: [*rs1val_walking, *ifmt_immval_walking_len] + +# instructions overlapping with those in the B extension in RV32/RV64 configuration (Zbpbo) +# wext: +# config: +# - check ISA:=regex(.*I.*P.*Zicsr.*) +# mnemonics: +# wext: 0 +# rs1: +# <<: *pair_regs +# rs2: +# <<: *all_regs +# rd: +# <<: *all_regs +# op_comb: +# <<: *rfmt_op_comb +# val_comb: +# <<: [*rvp64_rs1val_sgn] +# abstract_comb: +# 'simd_base_val("rs2", xlen, 8, signed=False)': 0 +# +# wexti: +# config: +# - check ISA:=regex(.*I.*P.*Zicsr.*) +# mnemonics: +# wexti: 0 +# rs1: +# <<: *pair_regs +# rd: +# <<: *all_regs +# op_comb: +# <<: *ifmt_op_comb +# val_comb: +# <<: [*rvp64_rs1val_sgn] +# abstract_comb: +# 'simd_imm_val("imm_val", 5)': 0 + +insb: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + insb: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [*base_rs1val_sgn] + abstract_comb: + 'simd_imm_val("imm_val", ceil(log(xlen,2))-3)': 0 diff --git a/coverage/p/rv64ip.cgf b/coverage/p/rv64ip.cgf new file mode 100644 index 000000000..cf0ca4bab --- /dev/null +++ b/coverage/p/rv64ip.cgf @@ -0,0 +1,1578 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +add32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + add32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +radd32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + radd32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +uradd32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + uradd32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=False)': 0 + 'simd_base_val("rs2", xlen, 32, signed=False)': 0 + 'simd_val_comb(xlen, 32, signed=False)': 0 + +kadd32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kadd32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +ukadd32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + ukadd32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=False)': 0 + 'simd_base_val("rs2", xlen, 32, signed=False)': 0 + 'simd_val_comb(xlen, 32, signed=False)': 0 + +sub32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + sub32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +rsub32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + rsub32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + + +ursub32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + ursub32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=False)': 0 + 'simd_base_val("rs2", xlen, 32, signed=False)': 0 + 'simd_val_comb(xlen, 32, signed=False)': 0 + +ksub32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + ksub32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +uksub32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + uksub32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=False)': 0 + 'simd_base_val("rs2", xlen, 32, signed=False)': 0 + 'simd_val_comb(xlen, 32, signed=False)': 0 + +cras32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + cras32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +rcras32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + rcras32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +urcras32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + urcras32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=False)': 0 + 'simd_base_val("rs2", xlen, 32, signed=False)': 0 + 'simd_val_comb(xlen, 32, signed=False)': 0 + +kcras32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kcras32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +ukcras32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + ukcras32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=False)': 0 + 'simd_base_val("rs2", xlen, 32, signed=False)': 0 + 'simd_val_comb(xlen, 32, signed=False)': 0 + +crsa32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + crsa32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +rcrsa32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + rcrsa32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +urcrsa32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + urcrsa32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=False)': 0 + 'simd_base_val("rs2", xlen, 32, signed=False)': 0 + 'simd_val_comb(xlen, 32, signed=False)': 0 + +kcrsa32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kcrsa32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +ukcrsa32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + ukcrsa32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=False)': 0 + 'simd_base_val("rs2", xlen, 32, signed=False)': 0 + 'simd_val_comb(xlen, 32, signed=False)': 0 + +stas32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + stas32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +rstas32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + rstas32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +urstas32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + urstas32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=False)': 0 + 'simd_base_val("rs2", xlen, 32, signed=False)': 0 + 'simd_val_comb(xlen, 32, signed=False)': 0 + +kstas32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kstas32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +ukstas32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + ukstas32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=False)': 0 + 'simd_base_val("rs2", xlen, 32, signed=False)': 0 + 'simd_val_comb(xlen, 32, signed=False)': 0 + +stsa32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + stsa32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +rstsa32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + rstsa32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +urstsa32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + urstsa32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=False)': 0 + 'simd_base_val("rs2", xlen, 32, signed=False)': 0 + 'simd_val_comb(xlen, 32, signed=False)': 0 + +kstsa32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kstsa32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +ukstsa32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + ukstsa32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=False)': 0 + 'simd_base_val("rs2", xlen, 32, signed=False)': 0 + 'simd_val_comb(xlen, 32, signed=False)': 0 + +sra32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + sra32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'walking_ones("rs2_val", ceil(log(32, 2)), False)': 0 + 'walking_zeros("rs2_val", ceil(log(32, 2)), False)': 0 + 'alternate("rs2_val", ceil(log(32, 2)), False)': 0 + +srai32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + srai32: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_imm_val("imm_val", 5)': 0 + +sra32.u: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + sra32.u: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'walking_ones("rs2_val", ceil(log(32, 2)), False)': 0 + 'walking_zeros("rs2_val", ceil(log(32, 2)), False)': 0 + 'alternate("rs2_val", ceil(log(32, 2)), False)': 0 + +srai32.u: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + srai32.u: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_imm_val("imm_val", 5)': 0 + +srl32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + srl32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=False)': 0 + 'walking_ones("rs2_val", ceil(log(32, 2)), False)': 0 + 'walking_zeros("rs2_val", ceil(log(32, 2)), False)': 0 + 'alternate("rs2_val", ceil(log(32, 2)), False)': 0 + +srli32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + srli32: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=False)': 0 + 'simd_imm_val("imm_val", 5)': 0 + +srl32.u: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + srl32.u: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=False)': 0 + 'walking_ones("rs2_val", ceil(log(32, 2)), False)': 0 + 'walking_zeros("rs2_val", ceil(log(32, 2)), False)': 0 + 'alternate("rs2_val", ceil(log(32, 2)), False)': 0 + +srli32.u: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + srli32.u: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=False)': 0 + 'simd_imm_val("imm_val", 5)': 0 + +sll32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + sll32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=False)': 0 + 'walking_ones("rs2_val", ceil(log(32, 2)), False)': 0 + 'walking_zeros("rs2_val", ceil(log(32, 2)), False)': 0 + 'alternate("rs2_val", ceil(log(32, 2)), False)': 0 + +slli32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + slli32: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=False)': 0 + 'simd_imm_val("imm_val", 5)': 0 + +ksll32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + ksll32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'walking_ones("rs2_val", ceil(log(32, 2)), False)': 0 + 'walking_zeros("rs2_val", ceil(log(32, 2)), False)': 0 + 'alternate("rs2_val", ceil(log(32, 2)), False)': 0 + +kslli32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kslli32: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_imm_val("imm_val", 5)': 0 + +kslra32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kslra32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'walking_ones("rs2_val", xlen, True)': 0 + 'walking_zeros("rs2_val", xlen, True)': 0 + 'alternate("rs2_val", xlen, True)': 0 + +kslra32.u: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kslra32.u: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=False)': 0 + 'walking_ones("rs2_val", xlen, True)': 0 + 'walking_zeros("rs2_val", xlen, True)': 0 + 'alternate("rs2_val", xlen, True)': 0 + +smin32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smin32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +umin32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + umin32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=False)': 0 + 'simd_base_val("rs2", xlen, 32, signed=False)': 0 + 'simd_val_comb(xlen, 32, signed=False)': 0 + +smax32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smax32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +umax32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + umax32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=False)': 0 + 'simd_base_val("rs2", xlen, 32, signed=False)': 0 + 'simd_val_comb(xlen, 32, signed=False)': 0 + +kabs32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kabs32: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + +khmbb16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + khmbb16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +khmbt16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + khmbt16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +khmtt16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + khmtt16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +kdmbb16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kdmbb16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +kdmbt16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kdmbt16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +kdmtt16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kdmtt16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +kdmabb16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kdmabb16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +kdmabt16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kdmabt16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +kdmatt16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kdmatt16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=True)': 0 + 'simd_base_val("rs2", xlen, 16, signed=True)': 0 + 'simd_val_comb(xlen, 16, signed=True)': 0 + +# alias of mulsr64 +# smbb32: +# config: +# - check ISA:=regex(.*I.*P.*Zicsr.*) +# mnemonics: +# smbb32: 0 +# rs1: +# <<: *all_regs +# rs2: +# <<: *all_regs +# rd: +# <<: *all_regs +# op_comb: +# <<: *rfmt_op_comb +# val_comb: +# abstract_comb: +# 'simd_base_val("rs1", xlen, 32, signed=True)': 0 +# 'simd_base_val("rs2", xlen, 32, signed=True)': 0 +# 'simd_val_comb(xlen, 32, signed=True)': 0 + +smbt32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smbt32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +smtt32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smtt32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +kmabb32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmabb32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +kmabt32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmabt32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +kmatt32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmatt32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +kmda32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmda32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +kmxda32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmxda32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +# alias of kmar64 +# kmada32: +# config: +# - check ISA:=regex(.*I.*P.*Zicsr.*) +# mnemonics: +# kmada32: 0 +# rs1: +# <<: *all_regs +# rs2: +# <<: *all_regs +# rd: +# <<: *all_regs +# op_comb: +# <<: *rfmt_op_comb +# val_comb: +# abstract_comb: +# 'simd_base_val("rs1", xlen, 32, signed=True)': 0 +# 'simd_base_val("rs2", xlen, 32, signed=True)': 0 +# 'simd_val_comb(xlen, 32, signed=True)': 0 + +kmaxda32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmaxda32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +kmads32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmads32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +kmadrs32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmadrs32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +kmaxds32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmaxds32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +kmsda32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmsda32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +kmsxda32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + kmsxda32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +smds32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smds32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +smdrs32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smdrs32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +smxds32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + smxds32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_base_val("rs2", xlen, 32, signed=True)': 0 + 'simd_val_comb(xlen, 32, signed=True)': 0 + +sraiw.u: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + sraiw.u: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=True)': 0 + 'simd_imm_val("imm_val", 5)': 0 + +# instructions overlapping with those in the B extension in RV64 configuration (Zbpbo) +# pkbb32: +# config: +# - check ISA:=regex(.*I.*P.*Zicsr.*) +# mnemonics: +# pkbb32: 0 +# rs1: +# <<: *all_regs +# rs2: +# <<: *all_regs +# rd: +# <<: *all_regs +# op_comb: +# <<: *rfmt_op_comb +# val_comb: +# abstract_comb: +# 'simd_base_val("rs1", xlen, 32, signed=False)': 0 +# 'simd_base_val("rs2", xlen, 32, signed=False)': 0 +# 'simd_val_comb(xlen, 32, signed=False)': 0 + +pkbt32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + pkbt32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=False)': 0 + 'simd_base_val("rs2", xlen, 32, signed=False)': 0 + 'simd_val_comb(xlen, 32, signed=False)': 0 + +pktb32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + pktb32: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=False)': 0 + 'simd_base_val("rs2", xlen, 32, signed=False)': 0 + 'simd_val_comb(xlen, 32, signed=False)': 0 + +# instructions overlapping with those in the B extension in RV64 configuration (Zbpbo) +# pktt32: +# config: +# - check ISA:=regex(.*I.*P.*Zicsr.*) +# mnemonics: +# pktt32: 0 +# rs1: +# <<: *all_regs +# rs2: +# <<: *all_regs +# rd: +# <<: *all_regs +# op_comb: +# <<: *rfmt_op_comb +# val_comb: +# abstract_comb: +# 'simd_base_val("rs1", xlen, 32, signed=False)': 0 +# 'simd_base_val("rs2", xlen, 32, signed=False)': 0 +# 'simd_val_comb(xlen, 32, signed=False)': 0 + +# instructions overlapping with those in the B extension in RV32 configuration (Zbpbo) +clz32: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + clz32: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 32, signed=False)': 0 + +pkbb16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + pkbb16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=False)': 0 + 'simd_base_val("rs2", xlen, 16, signed=False)': 0 + 'simd_val_comb(xlen, 16, signed=False)': 0 + +pktt16: + config: + - check ISA:=regex(.*I.*P.*Zicsr.*) + mnemonics: + pktt16: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + abstract_comb: + 'simd_base_val("rs1", xlen, 16, signed=False)': 0 + 'simd_base_val("rs2", xlen, 16, signed=False)': 0 + 'simd_val_comb(xlen, 16, signed=False)': 0 diff --git a/coverage/priv/rv32e_priv.cgf b/coverage/priv/rv32e_priv.cgf new file mode 100644 index 000000000..129677f1a --- /dev/null +++ b/coverage/priv/rv32e_priv.cgf @@ -0,0 +1,146 @@ +misalign-lh: + cond: check ISA:=regex(.*E.*Zicsr.*) ;def RVTEST_E = True + config: + - check ISA:=regex(.*E.*); check hw_data_misaligned_support:=True ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zicsr.*); check hw_data_misaligned_support:=False; def rvtest_mtrap_routine=True ;def RVTEST_E = True + mnemonics: + lh: 0 + val_comb: + 'ea_align == 1': 0 + +misalign-lhu: + config: + - check ISA:=regex(.*E.*); check hw_data_misaligned_support:=True ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zicsr.*); check hw_data_misaligned_support:=False; def rvtest_mtrap_routine=True ;def RVTEST_E = True + cond: check ISA:=regex(.*E.*Zicsr.*) ;def RVTEST_E = True + mnemonics: + lhu: 0 + val_comb: + 'ea_align == 1': 0 + + +misalign-lw: + config: + - check ISA:=regex(.*E.*); check hw_data_misaligned_support:=True ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zicsr.*); check hw_data_misaligned_support:=False; def rvtest_mtrap_routine=True ;def RVTEST_E = True + cond: check ISA:=regex(.*E.*Zicsr.*) ;def RVTEST_E = True + mnemonics: + lw: 0 + val_comb: + 'ea_align == 1': 0 + 'ea_align == 2': 0 + 'ea_align == 3': 0 + +misalign-sh: + config: + - check ISA:=regex(.*E.*); check hw_data_misaligned_support:=True ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zicsr.*); check hw_data_misaligned_support:=False; def rvtest_mtrap_routine=True ;def RVTEST_E = True + cond: check ISA:=regex(.*E.*Zicsr.*) ;def RVTEST_E = True + mnemonics: + sh: 0 + val_comb: + 'ea_align == 1': 0 + +misalign-sw: + config: + - check ISA:=regex(.*E.*); check hw_data_misaligned_support:=True ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zicsr.*); check hw_data_misaligned_support:=False; def rvtest_mtrap_routine=True ;def RVTEST_E = True + cond: check ISA:=regex(.*E.*Zicsr.*) ;def RVTEST_E = True + mnemonics: + sw: 0 + val_comb: + 'ea_align == 1': 0 + 'ea_align == 2': 0 + 'ea_align == 3': 0 + +misalign2-jalr: + config: + - check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zicsr.*); check ISA:=regex(^[^C]+$); def rvtest_mtrap_routine=True ;def RVTEST_E = True + cond: check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + jalr: 0 + val_comb: + 'imm_val%2 == 1 and ea_align == 2': 0 + 'imm_val%2 == 0 and ea_align == 2': 0 + +misalign1-jalr: + config: + - check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + jalr: 0 + val_comb: + 'imm_val%2 == 1 and ea_align == 1': 0 + 'imm_val%2 == 0 and ea_align == 1': 0 + +misalign-jal: + config: + - check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zicsr.*); check ISA:=regex(^[^C]+$); def rvtest_mtrap_routine=True ;def RVTEST_E = True + cond: check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + jal: 0 + val_comb: + 'ea_align == 2': 0 + +misalign-bge: + config: + - check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zicsr.*); check ISA:=regex(^[^C]+$); def rvtest_mtrap_routine=True ;def RVTEST_E = True + cond: check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + bge: 0 + val_comb: + ' rs1_val>rs2_val and ea_align == 2': 0 + +misalign-bgeu: + config: + - check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zicsr.*); check ISA:=regex(^[^C]+$); def rvtest_mtrap_routine=True ;def RVTEST_E = True + cond: check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + bgeu: 0 + val_comb: + ' rs1_val>rs2_val and ea_align == 2': 0 + +misalign-blt: + config: + - check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True + - check ISA:=regex(.*E.*Zicsr.*); check ISA:=regex(^[^C]+$); def rvtest_mtrap_routine=True ;def RVTEST_E = True + cond: check ISA:=regex(.*E.*) ;def RVTEST_E = True + mnemonics: + blt: 0 + val_comb: + ' rs1_valrs2_val and ea_align == 2': 0 + +misalign-bgeu: + config: + - check ISA:=regex(.*I.*C.*) + - check ISA:=regex(.*I.*Zicsr.*); check ISA:=regex(^[^C]+$); def rvtest_mtrap_routine=True + cond: check ISA:=regex(.*I.*) + mnemonics: + bgeu: 0 + val_comb: + ' rs1_val>rs2_val and ea_align == 2': 0 + +misalign-blt: + config: + - check ISA:=regex(.*I.*C.*) + - check ISA:=regex(.*I.*Zicsr.*); check ISA:=regex(^[^C]+$); def rvtest_mtrap_routine=True + cond: check ISA:=regex(.*I.*) + mnemonics: + blt: 0 + val_comb: + ' rs1_valrs2_val and ea_align == 2': 0 + +misalign-bgeu: + config: + - check ISA:=regex(.*I.*C.*) + - check ISA:=regex(.*I.*Zicsr.*); check ISA:=regex(^[^C]+$); def rvtest_mtrap_routine=True + cond: check ISA:=regex(.*I.*) + mnemonics: + bgeu: 0 + val_comb: + ' rs1_val>rs2_val and ea_align == 2': 0 + +misalign-blt: + config: + - check ISA:=regex(.*I.*C.*) + - check ISA:=regex(.*I.*Zicsr.*); check ISA:=regex(^[^C]+$); def rvtest_mtrap_routine=True + cond: check ISA:=regex(.*I.*) + mnemonics: + blt: 0 + val_comb: + ' rs1_val 0': 0 + 'imm_val == ((2**20)-1)': 0 + abstract_comb: + 'sp_dataset(20,["imm_val"],signed=False)': 0 + 'walking_ones("imm_val", 20, False)': 0 + 'walking_zeros("imm_val", 20, False)': 0 + 'alternate("imm_val", 20, False)': 0 + +lpad-s: + config: + - check ISA:=regex(.*I.*Zicsr.*Zicfilp.*); def rvtest_mtrap_routine=True; def rvtest_strap_routine=True + mnemonics: + lpad-s: 0 + val_comb: + 'imm_val == 0': 0 + 'imm_val > 0': 0 + 'imm_val == ((2**20)-1)': 0 + abstract_comb: + 'sp_dataset(20,["imm_val"],signed=False)': 0 + 'walking_ones("imm_val", 20, False)': 0 + 'walking_zeros("imm_val", 20, False)': 0 + 'alternate("imm_val", 20, False)': 0 + +lpad-u: + config: + - check ISA:=regex(.*I.*Zicsr.*Zicfilp.*); def rvtest_mtrap_routine=True; def rvtest_strap_routine=True + mnemonics: + lpad-u: 0 + val_comb: + 'imm_val == 0': 0 + 'imm_val > 0': 0 + 'imm_val == ((2**20)-1)': 0 + abstract_comb: + 'sp_dataset(20,["imm_val"],signed=False)': 0 + 'walking_ones("imm_val", 20, False)': 0 + 'walking_zeros("imm_val", 20, False)': 0 + 'alternate("imm_val", 20, False)': 0 diff --git a/coverage/zicond.cgf b/coverage/zicond/zicond.cgf similarity index 96% rename from coverage/zicond.cgf rename to coverage/zicond/zicond.cgf index f7f2a499e..af6c1b824 100644 --- a/coverage/zicond.cgf +++ b/coverage/zicond/zicond.cgf @@ -1,7 +1,7 @@ czero.eqz: config: - check ISA:=regex(.*Zicond.*) - opcode: + mnemonics: czero.eqz: 0 rs1: <<: *all_regs @@ -20,7 +20,7 @@ czero.eqz: czero.nez: config: - check ISA:=regex(.*Zicond.*) - opcode: + mnemonics: czero.nez: 0 rs1: <<: *all_regs diff --git a/coverage/zimop.cgf b/coverage/zimop/zimop.cgf similarity index 96% rename from coverage/zimop.cgf rename to coverage/zimop/zimop.cgf index a47cbdb92..25fb014c0 100644 --- a/coverage/zimop.cgf +++ b/coverage/zimop/zimop.cgf @@ -3,7 +3,7 @@ mop.rr.0: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.rr.0: 0 rs1: <<: *all_regs @@ -22,7 +22,7 @@ mop.rr.0: mop.rr.1: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.rr.1: 0 rs1: <<: *all_regs @@ -41,7 +41,7 @@ mop.rr.1: mop.rr.2: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.rr.2: 0 rs1: <<: *all_regs @@ -60,7 +60,7 @@ mop.rr.2: mop.rr.3: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.rr.3: 0 rs1: <<: *all_regs @@ -79,7 +79,7 @@ mop.rr.3: mop.rr.4: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.rr.4: 0 rs1: <<: *all_regs @@ -98,7 +98,7 @@ mop.rr.4: mop.rr.5: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.rr.5: 0 rs1: <<: *all_regs @@ -117,7 +117,7 @@ mop.rr.5: mop.rr.6: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.rr.6: 0 rs1: <<: *all_regs @@ -136,7 +136,7 @@ mop.rr.6: mop.rr.7: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.rr.7: 0 rs1: <<: *all_regs @@ -155,7 +155,7 @@ mop.rr.7: mop.r.0: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.r.0: 0 rs1: <<: *all_regs @@ -172,7 +172,7 @@ mop.r.0: mop.r.1: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.r.1: 0 rs1: <<: *all_regs @@ -189,7 +189,7 @@ mop.r.1: mop.r.2: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.r.2: 0 rs1: <<: *all_regs @@ -206,7 +206,7 @@ mop.r.2: mop.r.3: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.r.3: 0 rs1: <<: *all_regs @@ -223,7 +223,7 @@ mop.r.3: mop.r.4: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.r.4: 0 rs1: <<: *all_regs @@ -240,7 +240,7 @@ mop.r.4: mop.r.5: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.r.5: 0 rs1: <<: *all_regs @@ -257,7 +257,7 @@ mop.r.5: mop.r.6: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.r.6: 0 rs1: <<: *all_regs @@ -274,7 +274,7 @@ mop.r.6: mop.r.7: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.r.7: 0 rs1: <<: *all_regs @@ -291,7 +291,7 @@ mop.r.7: mop.r.8: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.r.8: 0 rs1: <<: *all_regs @@ -308,7 +308,7 @@ mop.r.8: mop.r.9: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.r.9: 0 rs1: <<: *all_regs @@ -325,7 +325,7 @@ mop.r.9: mop.r.10: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.r.10: 0 rs1: <<: *all_regs @@ -342,7 +342,7 @@ mop.r.10: mop.r.11: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.r.11: 0 rs1: <<: *all_regs @@ -359,7 +359,7 @@ mop.r.11: mop.r.12: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.r.12: 0 rs1: <<: *all_regs @@ -376,7 +376,7 @@ mop.r.12: mop.r.13: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.r.13: 0 rs1: <<: *all_regs @@ -393,7 +393,7 @@ mop.r.13: mop.r.14: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.r.14: 0 rs1: <<: *all_regs @@ -410,7 +410,7 @@ mop.r.14: mop.r.15: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.r.15: 0 rs1: <<: *all_regs @@ -427,7 +427,7 @@ mop.r.15: mop.r.16: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.r.16: 0 rs1: <<: *all_regs @@ -444,7 +444,7 @@ mop.r.16: mop.r.17: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.r.17: 0 rs1: <<: *all_regs @@ -461,7 +461,7 @@ mop.r.17: mop.r.18: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.r.18: 0 rs1: <<: *all_regs @@ -478,7 +478,7 @@ mop.r.18: mop.r.19: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.r.19: 0 rs1: <<: *all_regs @@ -495,7 +495,7 @@ mop.r.19: mop.r.20: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.r.20: 0 rs1: <<: *all_regs @@ -512,7 +512,7 @@ mop.r.20: mop.r.21: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.r.21: 0 rs1: <<: *all_regs @@ -529,7 +529,7 @@ mop.r.21: mop.r.22: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.r.22: 0 rs1: <<: *all_regs @@ -546,7 +546,7 @@ mop.r.22: mop.r.23: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.r.23: 0 rs1: <<: *all_regs @@ -563,7 +563,7 @@ mop.r.23: mop.r.24: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.r.24: 0 rs1: <<: *all_regs @@ -580,7 +580,7 @@ mop.r.24: mop.r.25: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.r.25: 0 rs1: <<: *all_regs @@ -597,7 +597,7 @@ mop.r.25: mop.r.26: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.r.26: 0 rs1: <<: *all_regs @@ -614,7 +614,7 @@ mop.r.26: mop.r.27: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.r.27: 0 rs1: <<: *all_regs @@ -631,7 +631,7 @@ mop.r.27: mop.r.28: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.r.28: 0 rs1: <<: *all_regs @@ -648,7 +648,7 @@ mop.r.28: mop.r.29: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.r.29: 0 rs1: <<: *all_regs @@ -665,7 +665,7 @@ mop.r.29: mop.r.30: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.r.30: 0 rs1: <<: *all_regs @@ -682,7 +682,7 @@ mop.r.30: mop.r.31: config: - check ISA:=regex(.*Zimop.*) - opcode: + mnemonics: mop.r.31: 0 rs1: <<: *all_regs diff --git a/coverage/zvk/vaesdf.cgf b/coverage/zvk/vaesdf.cgf new file mode 100644 index 000000000..be9eccad4 --- /dev/null +++ b/coverage/zvk/vaesdf.cgf @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: BSD-3-Clause + +vaesdf.vv: + config: + - check ISA:=(.*I.*V.*Zvkned) + mnemonics: + vaesdf.vv: 0 + rs2: + <<: *all_vregs + rd: + <<: *all_vregs + op_comb: + 'rs2 == rd and rs2 != 0': 0 + 'rs2 != rd and rs2 != 0': 0 + +vaesdf.vs: + config: + - check ISA:=(.*I.*V.*Zvkned) + mnemonics: + vaesdf.vs: 0 + rs2: + <<: *all_vregs + rd: + <<: *all_vregs + op_comb: + 'rs2 == rd and rs2 != 0': 0 + 'rs2 != rd and rs2 != 0': 0 diff --git a/coverage/zvk/vaesdm.cgf b/coverage/zvk/vaesdm.cgf new file mode 100644 index 000000000..2a8d96a64 --- /dev/null +++ b/coverage/zvk/vaesdm.cgf @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: BSD-3-Clause + +vaesdm.vv: + config: + - check ISA:=(.*I.*V.*Zvkned) + mnemonics: + vaesdm.vv: 0 + rs2: + <<: *all_vregs + rd: + <<: *all_vregs + op_comb: + 'rs2 == rd and rs2 != 0': 0 + 'rs2 != rd and rs2 != 0': 0 + +vaesdm.vs: + config: + - check ISA:=(.*I.*V.*Zvkned) + mnemonics: + vaesdm.vs: 0 + rs2: + <<: *all_vregs + rd: + <<: *all_vregs + op_comb: + 'rs2 == rd and rs2 != 0': 0 + 'rs2 != rd and rs2 != 0': 0 diff --git a/coverage/zvk/vaesef.cgf b/coverage/zvk/vaesef.cgf new file mode 100644 index 000000000..3ee274f82 --- /dev/null +++ b/coverage/zvk/vaesef.cgf @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: BSD-3-Clause + +vaesef.vv: + config: + - check ISA:=(.*I.*V.*Zvkned) + mnemonics: + vaesef.vv: 0 + rs2: + <<: *all_vregs + rd: + <<: *all_vregs + op_comb: + 'rs2 == rd and rs2 != 0': 0 + 'rs2 != rd and rs2 != 0': 0 + +vaesef.vs: + config: + - check ISA:=(.*I.*V.*Zvkned) + mnemonics: + vaesef.vs: 0 + rs2: + <<: *all_vregs + rd: + <<: *all_vregs + op_comb: + 'rs2 == rd and rs2 != 0': 0 + 'rs2 != rd and rs2 != 0': 0 diff --git a/coverage/zvk/vaesem.cgf b/coverage/zvk/vaesem.cgf new file mode 100644 index 000000000..e080c3c62 --- /dev/null +++ b/coverage/zvk/vaesem.cgf @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: BSD-3-Clause + +vaesem.vv: + config: + - check ISA:=(.*I.*V.*Zvkned) + mnemonics: + vaesem.vv: 0 + rs2: + <<: *all_vregs + rd: + <<: *all_vregs + op_comb: + 'rs2 == rd and rs2 != 0': 0 + 'rs2 != rd and rs2 != 0': 0 + +vaesem.vs: + config: + - check ISA:=(.*I.*V.*Zvkned) + mnemonics: + vaesem.vs: 0 + rs2: + <<: *all_vregs + rd: + <<: *all_vregs + op_comb: + 'rs2 == rd and rs2 != 0': 0 + 'rs2 != rd and rs2 != 0': 0 diff --git a/coverage/zvk/vaeskf1.cgf b/coverage/zvk/vaeskf1.cgf new file mode 100644 index 000000000..15ffee26e --- /dev/null +++ b/coverage/zvk/vaeskf1.cgf @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: BSD-3-Clause + +vaeskf1.vi: + config: + - check ISA:=(.*I.*V.*Zvkned) + mnemonics: + vaeskf1.vi: 0 + rs2: + <<: *all_vregs + rd: + <<: *all_vregs + op_comb: + 'rs2 == rd and rs2 != 0': 0 + 'rs2 != rd and rs2 != 0': 0 diff --git a/coverage/zvk/vaeskf2.cgf b/coverage/zvk/vaeskf2.cgf new file mode 100644 index 000000000..352a0c0c7 --- /dev/null +++ b/coverage/zvk/vaeskf2.cgf @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: BSD-3-Clause + +vaeskf2.vi: + config: + - check ISA:=(.*I.*V.*Zvkned) + mnemonics: + vaeskf2.vi: 0 + rs2: + <<: *all_vregs + rd: + <<: *all_vregs + op_comb: + 'rs2 == rd and rs2 != 0': 0 + 'rs2 != rd and rs2 != 0': 0 diff --git a/coverage/zvk/vaesz.cgf b/coverage/zvk/vaesz.cgf new file mode 100644 index 000000000..918194ed8 --- /dev/null +++ b/coverage/zvk/vaesz.cgf @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: BSD-3-Clause + +vaesz.vs: + config: + - check ISA:=(.*I.*V.*Zvkned) + mnemonics: + vaesz.vs: 0 + rs2: + <<: *all_vregs + rd: + <<: *all_vregs + op_comb: + 'rs2 == rd and rs2 != 0': 0 + 'rs2 != rd and rs2 != 0': 0 + + diff --git a/coverage/zvk/vandn.cgf b/coverage/zvk/vandn.cgf new file mode 100644 index 000000000..403493eae --- /dev/null +++ b/coverage/zvk/vandn.cgf @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: BSD-3-Clause + +vandn.vv: + config: + - check ISA:=(.*I.*V.*Zvkb) + mnemonics: + vandn.vv: 0 + rs1: + <<: *all_vregs + rs2: + <<: *all_vregs + rd: + <<: *all_vregs + op_comb: + <<: *sfmt_op_comb + +vandn.vx: + config: + - check ISA:=(.*I.*V.*Zvkb) + mnemonics: + vandn.vx: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_vregs + rd: + <<: *all_vregs + op_comb: + <<: *sfmt_op_comb diff --git a/coverage/zvk/vbrev8.cgf b/coverage/zvk/vbrev8.cgf new file mode 100644 index 000000000..f4a60ee12 --- /dev/null +++ b/coverage/zvk/vbrev8.cgf @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: BSD-3-Clause + +vbrev8.v: + config: + - check ISA:=(.*I.*V.*Zvkb) + mnemonics: + vbrev8.v: 0 + rs2: + <<: *all_vregs + rd: + <<: *all_vregs + op_comb: + 'rs2 == rd and rs2 != 0': 0 + 'rs2 != rd and rs2 != 0': 0 diff --git a/coverage/zvk/vclmul.cgf b/coverage/zvk/vclmul.cgf new file mode 100644 index 000000000..ccd772bd7 --- /dev/null +++ b/coverage/zvk/vclmul.cgf @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: BSD-3-Clause + +vclmul.vv: + config: + - check ISA:=(.*I.*V.*Zvkb) + mnemonics: + vclmul.vv: 0 + rs1: + <<: *all_vregs + rs2: + <<: *all_vregs + rd: + <<: *all_vregs + op_comb: + <<: *sfmt_op_comb + +vclmul.vx: + config: + - check ISA:=(.*I.*V.*Zvkb) + mnemonics: + vclmul.vx: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_vregs + rd: + <<: *all_vregs + op_comb: + <<: *sfmt_op_comb diff --git a/coverage/zvk/vclmulh.cgf b/coverage/zvk/vclmulh.cgf new file mode 100644 index 000000000..b817719e7 --- /dev/null +++ b/coverage/zvk/vclmulh.cgf @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: BSD-3-Clause + +vclmulh.vv: + config: + - check ISA:=(.*I.*V.*Zvkb) + mnemonics: + vclmulh.vv: 0 + rs1: + <<: *all_vregs + rs2: + <<: *all_vregs + rd: + <<: *all_vregs + op_comb: + <<: *sfmt_op_comb + +vclmulh.vx: + config: + - check ISA:=(.*I.*V.*Zvkb) + mnemonics: + vclmulh.vx: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_vregs + rd: + <<: *all_vregs + op_comb: + <<: *sfmt_op_comb diff --git a/coverage/zvk/vghsh.cgf b/coverage/zvk/vghsh.cgf new file mode 100644 index 000000000..43ed9e620 --- /dev/null +++ b/coverage/zvk/vghsh.cgf @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: BSD-3-Clause + +vghsh.vv: + config: + - check ISA:=(.*I.*V.*Zvkg) + mnemonics: + vghsh.vv: 0 + rs1: + <<: *all_vregs + rs2: + <<: *all_vregs + rd: + <<: *all_vregs + op_comb: + <<: *sfmt_op_comb diff --git a/coverage/zvk/vgmul.cgf b/coverage/zvk/vgmul.cgf new file mode 100644 index 000000000..f0e5d7a85 --- /dev/null +++ b/coverage/zvk/vgmul.cgf @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: BSD-3-Clause + +vgmul.vv: + config: + - check ISA:=(.*I.*V.*Zvkg) + mnemonics: + vgmul.vv: 0 + rs2: + <<: *all_vregs + rd: + <<: *all_vregs + op_comb: + 'rs2 == rd and rs2 != 0': 0 + 'rs2 != rd and rs2 != 0': 0 diff --git a/coverage/zvk/vrev8.cgf b/coverage/zvk/vrev8.cgf new file mode 100644 index 000000000..6dd373e26 --- /dev/null +++ b/coverage/zvk/vrev8.cgf @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: BSD-3-Clause + +vrev8.v: + config: + - check ISA:=(.*I.*V.*Zvkb) + mnemonics: + vrev8.v: 0 + rs2: + <<: *all_vregs + rd: + <<: *all_vregs + op_comb: + 'rs2 == rd and rs2 != 0': 0 + 'rs2 != rd and rs2 != 0': 0 diff --git a/coverage/zvk/vrol.cgf b/coverage/zvk/vrol.cgf new file mode 100644 index 000000000..36ab5818a --- /dev/null +++ b/coverage/zvk/vrol.cgf @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: BSD-3-Clause + +vrol.vv: + config: + - check ISA:=(.*I.*V.*Zvkb) + mnemonics: + vrol.vv: 0 + rs1: + <<: *all_vregs + rs2: + <<: *all_vregs + rd: + <<: *all_vregs + op_comb: + <<: *sfmt_op_comb + +vrol.vx: + config: + - check ISA:=(.*I.*V.*Zvkb) + mnemonics: + vrol.vx: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_vregs + rd: + <<: *all_vregs + op_comb: + <<: *sfmt_op_comb diff --git a/coverage/zvk/vror.cgf b/coverage/zvk/vror.cgf new file mode 100644 index 000000000..6d0974e12 --- /dev/null +++ b/coverage/zvk/vror.cgf @@ -0,0 +1,42 @@ +# SPDX-License-Identifier: BSD-3-Clause + +vror.vv: + config: + - check ISA:=(.*I.*V.*Zvkb) + mnemonics: + vror.vv: 0 + rs1: + <<: *all_vregs + rs2: + <<: *all_vregs + rd: + <<: *all_vregs + op_comb: + <<: *sfmt_op_comb + +vror.vx: + config: + - check ISA:=(.*I.*V.*Zvkb) + mnemonics: + vror.vx: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_vregs + rd: + <<: *all_vregs + op_comb: + <<: *sfmt_op_comb + +vror.vi: + config: + - check ISA:=(.*I.*V.*Zvkb) + mnemonics: + vror.vi: 0 + rs2: + <<: *all_vregs + rd: + <<: *all_vregs + op_comb: + 'rs2 == rd and rs2 != 0': 0 + 'rs2 != rd and rs2 != 0': 0 diff --git a/coverage/zvk/vsha2ch.cgf b/coverage/zvk/vsha2ch.cgf new file mode 100644 index 000000000..267781234 --- /dev/null +++ b/coverage/zvk/vsha2ch.cgf @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: BSD-3-Clause + +vsha2ch.vv: + config: + - check ISA:=(.*I.*V.*Zvknha) + mnemonics: + vsha2ch.vv: 0 + rs1: + <<: *all_vregs + rs2: + <<: *all_vregs + rd: + <<: *all_vregs + op_comb: + <<: *sfmt_op_comb + +vsha2ch.vv: + config: + - check ISA:=(.*I.*V.*Zvknhb) + mnemonics: + vsha2ch.vv: 0 + rs1: + <<: *all_vregs + rs2: + <<: *all_vregs + rd: + <<: *all_vregs + op_comb: + <<: *sfmt_op_comb diff --git a/coverage/zvk/vsha2cl.cfg b/coverage/zvk/vsha2cl.cfg new file mode 100644 index 000000000..3a190c429 --- /dev/null +++ b/coverage/zvk/vsha2cl.cfg @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: BSD-3-Clause + +vsha2cl.vv: + config: + - check ISA:=(.*I.*V.*Zvknha) + mnemonics: + vsha2cl.vv: 0 + rs1: + <<: *all_vregs + rs2: + <<: *all_vregs + rd: + <<: *all_vregs + op_comb: + <<: *sfmt_op_comb + +vsha2cl.vv: + config: + - check ISA:=(.*I.*V.*Zvknhb) + mnemonics: + vsha2cl.vv: 0 + rs1: + <<: *all_vregs + rs2: + <<: *all_vregs + rd: + <<: *all_vregs + op_comb: + <<: *sfmt_op_comb diff --git a/coverage/zvk/vsha2ms.cgf b/coverage/zvk/vsha2ms.cgf new file mode 100644 index 000000000..e7598d429 --- /dev/null +++ b/coverage/zvk/vsha2ms.cgf @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: BSD-3-Clause + +vsha2ms.vv: + config: + - check ISA:=(.*I.*V.*Zvknha) + mnemonics: + vsha2ms.vv: 0 + rs1: + <<: *all_vregs + rs2: + <<: *all_vregs + rd: + <<: *all_vregs + op_comb: + <<: *sfmt_op_comb + +vsha2ms.vv: + config: + - check ISA:=(.*I.*V.*Zvknhb) + mnemonics: + vsha2ms.vv: 0 + rs1: + <<: *all_vregs + rs2: + <<: *all_vregs + rd: + <<: *all_vregs + op_comb: + <<: *sfmt_op_comb diff --git a/coverage/zvk/vsm3c.cgf b/coverage/zvk/vsm3c.cgf new file mode 100644 index 000000000..4d2a16944 --- /dev/null +++ b/coverage/zvk/vsm3c.cgf @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: BSD-3-Clause + +vsm3c.vi: + config: + - check ISA:=(.*I.*V.*Zvksh) + mnemonics: + vsm3c.vi: 0 + rs2: + <<: *all_vregs + rd: + <<: *all_vregs + op_comb: + 'rs2 == rd and rs2 != 0': 0 + 'rs2 != rd and rs2 != 0': 0 diff --git a/coverage/zvk/vsm3me.cgf b/coverage/zvk/vsm3me.cgf new file mode 100644 index 000000000..8685d3738 --- /dev/null +++ b/coverage/zvk/vsm3me.cgf @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: BSD-3-Clause + +vsm3me.vi: + config: + - check ISA:=(.*I.*V.*Zvksh) + mnemonics: + vsm3me.vi: 0 + rs2: + <<: *all_vregs + rd: + <<: *all_vregs + op_comb: + 'rs2 == rd and rs2 != 0': 0 + 'rs2 != rd and rs2 != 0': 0 diff --git a/coverage/zvk/vsm4k.cgf b/coverage/zvk/vsm4k.cgf new file mode 100644 index 000000000..c1685e8cb --- /dev/null +++ b/coverage/zvk/vsm4k.cgf @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: BSD-3-Clause + +vsm4k.vi: + config: + - check ISA:=(.*I.*V.*Zvksed) + mnemonics: + vsm4k.vi: 0 + rs2: + <<: *all_vregs + rd: + <<: *all_vregs + op_comb: + 'rs2 == rd and rs2 != 0': 0 + 'rs2 != rd and rs2 != 0': 0 diff --git a/coverage/zvk/vsm4r.cgf b/coverage/zvk/vsm4r.cgf new file mode 100644 index 000000000..9e20e54cd --- /dev/null +++ b/coverage/zvk/vsm4r.cgf @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: BSD-3-Clause + +vsm4r.vv: + config: + - check ISA:=(.*I.*V.*Zvksed) + mnemonics: + vsm4r.vv: 0 + rs2: + <<: *all_vregs + rd: + <<: *all_vregs + op_comb: + 'rs2 == rd and rs2 != 0': 0 + 'rs2 != rd and rs2 != 0': 0 + +vsm4r.vs: + config: + - check ISA:=(.*I.*V.*Zvksed) + mnemonics: + vsm4r.vs: 0 + rs2: + <<: *all_vregs + rd: + <<: *all_vregs + op_comb: + 'rs2 == rd and rs2 != 0': 0 + 'rs2 != rd and rs2 != 0': 0 diff --git a/riscof-plugins/rv32/config.ini b/riscof-plugins/rv32/config.ini new file mode 100755 index 000000000..dfe45f860 --- /dev/null +++ b/riscof-plugins/rv32/config.ini @@ -0,0 +1,14 @@ +[RISCOF] +ReferencePlugin=sail_cSim +ReferencePluginPath=sail_cSim +DUTPlugin=spike_simple +DUTPluginPath=spike_simple + +[spike_simple] +pluginpath=spike_simple +ispec=spike_simple/spike_simple_isa.yaml +pspec=spike_simple/spike_simple_platform.yaml +target_run=1 + +[sail_cSim] +pluginpath=sail_cSim diff --git a/riscof-plugins/rv32/makeplugin/README.md b/riscof-plugins/rv32/makeplugin/README.md new file mode 100755 index 000000000..6df224c4d --- /dev/null +++ b/riscof-plugins/rv32/makeplugin/README.md @@ -0,0 +1,95 @@ +### Plugin to use Makefile.include from old framework with riscof + +- This plugin facilitates the use of Makefile.include from the targets of the old framework with + riscof and is intented to be used as a base for transition. +- The config node of the plugin can contain the following variables/ + - **makefiles** (*required*)- Comma separated paths to the makefiles. If multiple are specified, all will be + merged in the final output makefile. Note that only the varaibles in the makefiles are written + out into the final makefiles. Any targets or includes will be left out. Such cases can be + handled by editing the plugin to output the relevant lines as a part of the `build` function. + - **jobs** - The number of threads to launch parallely. (Default is `1`) + - **ispec** (*required*)- The path to the input ISA yaml specification of the target. + - **pspec** (*required*)- The path to the input platform yaml specification of the target. + - **make** - The make utility to use like make,bmake,pmake etc. (Default is `make`) + +- The commands in the makefiles need to be modified to make use of the following variables. The + values for these are resolved based on the inputs from riscof and are substituted before writing + out the final targets. An additional Makefile variable, `TARGET_DIR`, which contains the path + where the plugin resides is written out at the starting of the makefile and can be used as an anchor + point for resolving paths to other files. + + | Variable | Description | + | ------------- | ----------- | + | `${target_dir}` | The directory where the plugin file resides. (riscof_makeplugin.py) | + | `${asm}` | Absolute path to the assemble test file i.e the .S file for the test. | + | `${work_dir}` | The absolute path to the work directory for the test. | + | `${test_name}` | The name of the test, for example add-01 etc. Can be used for naming any intermediate files generated. | + | `${include}` | The path to the directory which containts the test header files. This needs to be specified as an include path in the compile command. | + | `${march}` | The ISA to be used for compiling the test. This is in the format expected by march argument of gcc. | + | `${mabi}` | The abi to be used for compiling the test. This is in the format expected by mabi argument of gcc. | + | `${target_isa}` | This is the ISA specified in the input ISA yaml. The idea is that it can be used to configure the model at run time via cli arguments if necessary. | + | `${test_bin}` | The name of the binary file to be created after compilation. Can be ignored. Custom names can be used as long as the RUN_TARGET command picks up the correct binary to execute on the target. | + | `${signature_file}` | The absolute path to the signature file. This path cannot be changed and the signature file should be present at this path for riscof to verify at the end of testing. | + | `${macros}` | The macros to be defined while compilation. Currently they are in the format expected by gcc i.e. `-D =` | + + + The rewritten Makefile.include for the SAIL C Simulator from [here](https://github.com/riscv/riscv-arch-test/blob/2.4.4/riscv-target/sail-riscv-c/device/rv32i_m/I/Makefile.include) is included in the directory + for reference(`sail.include`). + + **Note** - Value substitution for these variables happens only in the + `COMPILE_TARGET` and `RUN_TARGET` values in the makefile. There is no resolution of makefile + variables while substituting the values. The format of the output for each target is: + ``` + cd ;;; + ``` + +- Examples + + **Correct** : + + ``` + TARGET_SIM ?= riscv_sim_RV32 -V + TARGET_FLAGS = + + RISCV_PREFIX ?= riscv32-unknown-elf- + RISCV_GCC ?= $(RISCV_PREFIX)gcc + RISCV_GCC_OPTS ?= -g -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles \ + -I$(TARGET_DIR)/env/ + + COMPILE_TARGET=\ + $$(RISCV_GCC) -march=${march} -mabi=${mabi} $$(RISCV_GCC_OPTS) \ + -I${include} \ + -T${target_dir}/env/link.ld \ + ${asm} -o ${test_bin} ${macros}; + + RUN_TARGET=\ + $(TARGET_SIM) $(TARGET_FLAGS)\ + --test-signature=${signature_file} \ + ${test_bin} + + ``` + + **Wrong** : + + ``` + TARGET_SIM ?= riscv_sim_RV32 -V + TARGET_FLAGS = + + RISCV_PREFIX ?= riscv32-unknown-elf- + RISCV_GCC ?= $(RISCV_PREFIX)gcc + RISCV_GCC_OPTS ?= -g -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles \ + -I$(TARGET_DIR)/env/ -I${include} \ + + COMPILE_TARGET=\ + $$(RISCV_GCC) -march=${march} -mabi=${mabi} $$(RISCV_GCC_OPTS) \ + -T${target_dir}/env/link.ld \ + ${asm} -o ${test_bin} ${macros}; + + RUN_TARGET=\ + $(TARGET_SIM) $(TARGET_FLAGS)\ + --test-signature=${signature_file} \ + ${test_bin} + ``` + The commands produced using the above makefile will result in an error when executed because the + value of `${include}` will not be substituted in the `RISCV_GCC_OPTS` (Variable substitutions + are performed only for the `COMPILE_TARGET` and `RUN_TARGET` commands). diff --git a/riscof-plugins/rv32/makeplugin/__init__.py b/riscof-plugins/rv32/makeplugin/__init__.py new file mode 100755 index 000000000..0bfb5a62b --- /dev/null +++ b/riscof-plugins/rv32/makeplugin/__init__.py @@ -0,0 +1,2 @@ +from pkgutil import extend_path +__path__ = extend_path(__path__, __name__) \ No newline at end of file diff --git a/riscof-plugins/rv32/makeplugin/env/link.ld b/riscof-plugins/rv32/makeplugin/env/link.ld new file mode 100755 index 000000000..8ad95e049 --- /dev/null +++ b/riscof-plugins/rv32/makeplugin/env/link.ld @@ -0,0 +1,18 @@ +OUTPUT_ARCH( "riscv" ) +ENTRY(rvtest_entry_point) + +SECTIONS +{ + . = 0x80000000; + .text.init : { *(.text.init) } + . = ALIGN(0x1000); + .tohost : { *(.tohost) } + . = ALIGN(0x1000); + .text : { *(.text) } + . = ALIGN(0x1000); + .data : { *(.data) } + .data.string : { *(.data.string)} + .bss : { *(.bss) } + _end = .; +} + diff --git a/riscof-plugins/rv32/makeplugin/env/model_test.h b/riscof-plugins/rv32/makeplugin/env/model_test.h new file mode 100755 index 000000000..5a362683c --- /dev/null +++ b/riscof-plugins/rv32/makeplugin/env/model_test.h @@ -0,0 +1,60 @@ +#ifndef _COMPLIANCE_MODEL_H +#define _COMPLIANCE_MODEL_H +#if XLEN == 64 + #define ALIGNMENT 3 +#else + #define ALIGNMENT 2 +#endif + +#define RVMODEL_DATA_SECTION \ + .pushsection .tohost,"aw",@progbits; \ + .align 8; .global tohost; tohost: .dword 0; \ + .align 8; .global fromhost; fromhost: .dword 0; \ + .popsection; \ + .align 8; .global begin_regstate; begin_regstate: \ + .word 128; \ + .align 8; .global end_regstate; end_regstate: \ + .word 4; + +//RV_COMPLIANCE_HALT +#define RVMODEL_HALT \ + li x1, 1; \ + write_tohost: \ + sw x1, tohost, t5; \ + j write_tohost; + +#define RVMODEL_BOOT + +//RV_COMPLIANCE_DATA_BEGIN +#define RVMODEL_DATA_BEGIN \ + RVMODEL_DATA_SECTION \ + .align ALIGNMENT;\ + .global begin_signature; begin_signature: + +//RV_COMPLIANCE_DATA_END +#define RVMODEL_DATA_END \ + .global end_signature; end_signature: + +//RVTEST_IO_INIT +#define RVMODEL_IO_INIT +//RVTEST_IO_WRITE_STR +#define RVMODEL_IO_WRITE_STR(_R, _STR) +//RVTEST_IO_CHECK +#define RVMODEL_IO_CHECK() +//RVTEST_IO_ASSERT_GPR_EQ +#define RVMODEL_IO_ASSERT_GPR_EQ(_S, _R, _I) +//RVTEST_IO_ASSERT_SFPR_EQ +#define RVMODEL_IO_ASSERT_SFPR_EQ(_F, _R, _I) +//RVTEST_IO_ASSERT_DFPR_EQ +#define RVMODEL_IO_ASSERT_DFPR_EQ(_D, _R, _I) + +#define RVMODEL_SET_MSW_INT + +#define RVMODEL_CLEAR_MSW_INT + +#define RVMODEL_CLEAR_MTIMER_INT + +#define RVMODEL_CLEAR_MEXT_INT + + +#endif // _COMPLIANCE_MODEL_H diff --git a/riscof-plugins/rv32/makeplugin/riscof_makeplugin.py b/riscof-plugins/rv32/makeplugin/riscof_makeplugin.py new file mode 100755 index 000000000..22869a306 --- /dev/null +++ b/riscof-plugins/rv32/makeplugin/riscof_makeplugin.py @@ -0,0 +1,180 @@ +import os +import re +import shutil +import subprocess +import shlex +import logging +import random +import string +from string import Template + +import riscof.utils as utils +from riscof.pluginTemplate import pluginTemplate +import riscof.constants as constants +from riscv_isac.isac import isac + +logger = logging.getLogger() + +var_regex = r"^([a-zA-Z0-9_]+)[ ]*[?]?=(.*)$" +# The abi string to be passed to the compiler. The format adheres to the mabi +# argument of GCC. To change how this string is derived, change this function. +def mabi(isa): + isa = isa.lower() + abi = 'lp64' if '64' in isa else 'ilp32' + if 'd' in isa: + abi += 'd' + elif 'f' in isa: + abi += 'f' + return abi +def getmakevars(arg): + with open(arg,"r") as fp: + lines = [line.strip() for line in fp.readlines()] + lines = '\n'.join(lines) + lines = lines.replace("\\\n"," ") + larr = lines.split("\n") + ret_dict = {} + for entry in larr: + x = re.sub("((\\t)+)",lambda x:" ",entry) + x = re.sub("(( )+)",lambda x:" ",entry) + match = re.match(var_regex,x) + if match: + key = match.group(1) + val = match.group(2) + ret_dict[key] = val + return ret_dict + +class makeplugin(pluginTemplate): + # The target name and version info printed in the reports. These variables can be defined here + # statically or dynamically extracted from other sources. + __model__ = "makeplugin" + __version__ = "0.0.1" + + def __init__(self, *args, **kwargs): + sclass = super().__init__(*args, **kwargs) + + # Get the node for the plugin in the config.ini file. This is extracted by riscof and only + # the node relevant to the plugin is passed. + config = kwargs.get('config') + + # Extract all information from the nodes. If any required values are missing, an error and a + # system exit is raised. + if 'makefiles' not in config: + logger.error("Path to the Makefiles not specified for "+self.__model__) + raise SystemExit + if 'ispec' not in config or 'pspec' not in config: + logger.error("Path to the input YAML files not specified for "+self.__model__) + raise SystemExit + # Paths to the Makefile.include files. Mandatory to be provided + self.makefiles = [os.path.abspath(path) for path in config['makefiles'].split(",")] + # Number of jobs to launch in parallel + self.num_jobs = str(config['jobs'] if 'jobs' in config else 1) + # Path to the directory in which this file is present + self.pluginpath = os.path.dirname(__file__) + # Path to the input ISA yaml as per riscv-config format. + self.isa_spec = os.path.abspath(config['ispec']) if 'ispec' in config else '' + # Path to the input platform yaml as per riscv-config format. + self.platform_spec = os.path.abspath(config['pspec']) if 'ispec' in config else '' + self.make = config['make'] if 'make' in config else 'make' + return sclass + + def initialise(self, suite, work_dir, archtest_env): + # Store the path to the suite. + self.suite = suite + # Store the path to the root level work directory. + self.work_dir = work_dir + # Store the path to the folder which contains the header files for the tests. + self.archtest_env = archtest_env + + def build(self, isa_yaml, platform_yaml): + # Extract the configuration of hart0 from isa yaml to figure out the configuration of the + # hart being tested. + ispec = utils.load_yaml(isa_yaml)['hart0'] + # Resolve xlen value from the isa yaml + self.xlen = ('64' if 64 in ispec['supported_xlen'] else '32') + # Store the ISA of the target. + self.isa = ispec["ISA"] + self.var_dict = {} + # Extract all variables from the makefiles + for fpath in self.makefiles: + self.var_dict.update(getmakevars(fpath)) + # The path where the Makefile is created + self.makefilepath = os.path.join(self.work_dir, "Makefile." + self.name[:-1]) + with open(self.makefilepath,"w") as fp: + # The path to the target directory, i.e the directory where this python file is + # present. This variable is written out to the makefile so that other variables can use + # this value. + fp.write("TARGET_DIR = "+self.pluginpath+"\n") + # Write out all values except the COMPILE_TARGET and RUN_TARGET commands + for entry in self.var_dict.keys(): + if not entry.endswith("_TARGET"): + fp.write(entry+" = "+self.var_dict[entry]+"\n") + else: + self.var_dict[entry] = Template(self.var_dict[entry]) + + + def runTests(self, testList,cgf_file=None): + # Initialise the Make Utility from riscof with the output path for the Makefile + make = utils.makeUtil(makefilePath=self.makefilepath) + # Modify the make command based on the input values in the config file. + make.makeCommand = self.make + ' -j' + self.num_jobs + # Iterate over all the entries in the test list + for entry in testList: + # Extract the entry from the testlist + testentry = testList[entry] + # Extract the path to the assembly test file from the test list entry + test = testentry['test_path'] + # Extract the path to the work directory for the test. + test_dir = testentry['work_dir'] + # Macros to be defined are added in the GCC command format + # -D = + # Change this if the toolchain uses a different format + macros = ' -D' + " -D".join(testentry['macros']) + # Variables accessible in the *_TARGET commands + # Add more variables below if you wish to use these variables in the *_TARGET commands. + substitute = { + # The path to the target directory, i.e the directory where this python file is + # present + 'target_dir': self.pluginpath, + # Path to the test assembly file + 'asm': test, + # Path to the work directory + 'work_dir': testentry['work_dir'], + # Name of the Test. Can be used to name files in the work directory. + 'test_name': test.rsplit('/',1)[1][:-2], + # The path to the env folder containing the header files for the suite. This path + # should be passed as an include path in the compile commands. + 'include': self.archtest_env, + # The isa string to be passed to the compiler. The format adheres to the march + # argument of GCC + 'march': testentry['isa'].lower(), + # The abi string to be passed to the compiler. The format adheres to the mabi + # argument of GCC. To change how this string is derived, change function on line 21. + 'mabi': mabi(testentry['isa']), + # The ISA string present in the input yaml. Can be used to set the ISA of the target + 'target_isa': self.isa, + # Name of the generated binary file. Can be custom. + 'test_bin': 'ref.elf', + # Name of the signature file. Note the name of the file should be in the same + # particular format and inside the test work directory. + 'signature_file': os.path.join(test_dir, self.name[:-1] + ".signature"), + # The string which specifies all the macros to be defined for the test. As computed + # in line 108. + 'macros': macros + } + + # Construct the command for the test and add a target in the makefile. The format of the + # command is as follows: + # cd ;substitute(COMPILE_TARGET);substitute(RUN_TARGET); + # The RUN_TARGET is optional and can be skipped if the same is not defined in the input + # makefile + execute = "@cd "+testentry['work_dir']+";" + + compile_cmd = self.var_dict['COMPILE_TARGET'].safe_substitute(substitute) + execute+=compile_cmd+";" + if 'RUN_TARGET' in self.var_dict: + run_cmd = self.var_dict['RUN_TARGET'].safe_substitute(substitute) + execute+=run_cmd+";" + # Add target in the makefile for the test + make.add_target(execute,) + # Execute all targets. + make.execute_all(self.work_dir) diff --git a/riscof-plugins/rv32/makeplugin/sail.include b/riscof-plugins/rv32/makeplugin/sail.include new file mode 100755 index 000000000..4c07fea40 --- /dev/null +++ b/riscof-plugins/rv32/makeplugin/sail.include @@ -0,0 +1,21 @@ +TARGET_SIM ?= riscv_sim_RV32 -V +TARGET_FLAGS = + +RISCV_PREFIX ?= riscv32-unknown-elf- +RISCV_GCC ?= $(RISCV_PREFIX)gcc +RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump +RISCV_GCC_OPTS ?= -g -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles + +COMPILE_TARGET=\ + $$(RISCV_GCC) -march=${march} -mabi=${mabi} $$(RISCV_GCC_OPTS) \ + -I${include} \ + -I${target_dir}/env/ \ + -T${target_dir}/env/link.ld \ + ${asm} -o ${test_bin} ${macros};\ + $$(RISCV_OBJDUMP) ${test_bin} -D > ${test_name}.disass; \ + $$(RISCV_OBJDUMP) ${test_bin} --source > ${test_name}.debug + +RUN_TARGET=\ + $(TARGET_SIM) $(TARGET_FLAGS)\ + --test-signature=${signature_file} \ + ${test_bin} diff --git a/riscof-plugins/rv32/sail_cSim/README.md b/riscof-plugins/rv32/sail_cSim/README.md new file mode 100644 index 000000000..def128af5 --- /dev/null +++ b/riscof-plugins/rv32/sail_cSim/README.md @@ -0,0 +1,90 @@ +# Riscof Plugin for Sail RISC-V formal model + +- Using the simulators from the Sail RISC-V formal model + +The [Sail RISC-V formal model](https://github.com/rems-project/sail-riscv) generates two +simulators, in C and OCaml. They can be used as targets for running tests using riscof. + +For this purpose, the Sail model needs to be checked out and built on +the machine running the compliance suite. Follow the build +instructions described the README for building the RV32 and RV64 +models. Once built, please add `$SAIL_RISCV/c_emulator` and +`$SAIL_RISCV/ocaml_emulator` to your path, where $SAIL_RISCV is the +top-level directory containing the model. + +This plugin allows using the C Simulator generated by the SAIL model. + +- Config file entry + +``` +# Name of the Plugin. All entries are case sensitive. Including the name. +[sail_cSim] + +#path to the directory where the plugin is present +pluginpath= + +#path where the SAIL binaries are available. (optional) +#if this value is absent, it is assumed that the binaries are available as executables by default +PATH= + +#path to the ISA config file. (required if the plugin is used as DUT) +ispec= + +#path to the Platform config file. (required if the plugin is used as DUT) +pspec= + +#number of jobs to spawn in parallel (optional) +jobs=1 + +#the make command to use while executing the make file. Any of bmake,cmake,pmake,make etc. (optional) +#Default is make +make=make + +#The following arguments are necessary only if executed through docker + +#Flag indicating that the execution is through docker +docker= + +#Name of the docker image +image= +``` + +- Export command + +``` +pwd=pwd;export PYTHONPATH=$pwd:$PYTHONPATH; +``` + +- This plugin also supports coverage collection using ISAC. + +## Using Docker with this plugin + +- Setup + +Ensure that docker is installed and configured properly before running this step. +Run the following command. +``` +docker pull registry.gitlab.com/incoresemi/docker-images/compliance +``` + +- Running with riscof + +To use the docker image with the plugin the `sail_cSim` node in the `config.ini` must +contain the following values too. +``` +# Name of the Plugin. All entries are case sensitive. Including the name. +[sail_cSim] +docker=True +image=registry.gitlab.com/incoresemi/docker-images/compliance +``` + +## References + +- [Installing Docker](https://docs.docker.com/engine/install/) - Distro specific installation + instructions and quirks are present on the same website. For example ubuntu specific instructions + can be found [here](https://docs.docker.com/engine/install/ubuntu/). + +- The docker file for the image can be found [here](https://gitlab.com/incoresemi/docker-images/-/blob/master/compliance/Dockerfile). + +- The docker containers are hosted [here](https://gitlab.com/incoresemi/docker-images/container_registry/2205130). + diff --git a/riscof-plugins/rv32/sail_cSim/__init__.py b/riscof-plugins/rv32/sail_cSim/__init__.py new file mode 100644 index 000000000..0bfb5a62b --- /dev/null +++ b/riscof-plugins/rv32/sail_cSim/__init__.py @@ -0,0 +1,2 @@ +from pkgutil import extend_path +__path__ = extend_path(__path__, __name__) \ No newline at end of file diff --git a/riscof-plugins/rv32/sail_cSim/__pycache__/riscof_sail_cSim.cpython-310.pyc b/riscof-plugins/rv32/sail_cSim/__pycache__/riscof_sail_cSim.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eb7e0f53f432994e21791e6142809a0326be7c93 GIT binary patch literal 5456 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 beSV#O<75sJTiHM3B9~{0v!&P87PS8Whd{a( literal 0 HcmV?d00001 diff --git a/riscof-plugins/rv32/sail_cSim/env/link.ld b/riscof-plugins/rv32/sail_cSim/env/link.ld new file mode 100644 index 000000000..8ad95e049 --- /dev/null +++ b/riscof-plugins/rv32/sail_cSim/env/link.ld @@ -0,0 +1,18 @@ +OUTPUT_ARCH( "riscv" ) +ENTRY(rvtest_entry_point) + +SECTIONS +{ + . = 0x80000000; + .text.init : { *(.text.init) } + . = ALIGN(0x1000); + .tohost : { *(.tohost) } + . = ALIGN(0x1000); + .text : { *(.text) } + . = ALIGN(0x1000); + .data : { *(.data) } + .data.string : { *(.data.string)} + .bss : { *(.bss) } + _end = .; +} + diff --git a/riscof-plugins/rv32/sail_cSim/env/model_test.h b/riscof-plugins/rv32/sail_cSim/env/model_test.h new file mode 100644 index 000000000..94f54405d --- /dev/null +++ b/riscof-plugins/rv32/sail_cSim/env/model_test.h @@ -0,0 +1,57 @@ +#ifndef _COMPLIANCE_MODEL_H +#define _COMPLIANCE_MODEL_H + +#define RVMODEL_DATA_SECTION \ + .pushsection .tohost,"aw",@progbits; \ + .align 8; .global tohost; tohost: .dword 0; \ + .align 8; .global fromhost; fromhost: .dword 0; \ + .popsection; \ + .align 8; .global begin_regstate; begin_regstate: \ + .word 128; \ + .align 8; .global end_regstate; end_regstate: \ + .word 4; + +//RV_COMPLIANCE_HALT +#define RVMODEL_HALT ;\ +li x1, 1 ;\ +1: ;\ + sw x1, tohost, t2 ;\ + j 1b ;\ + +#define RVMODEL_BOOT + +//RV_COMPLIANCE_DATA_BEGIN +#define RVMODEL_DATA_BEGIN ;\ +RVMODEL_DATA_SECTION ;\ +.align 4 ;\ +.global begin_signature ;\ +begin_signature: + +//RV_COMPLIANCE_DATA_END +#define RVMODEL_DATA_END \ +.global end_signature; end_signature: + + +//RVTEST_IO_INIT +#define RVMODEL_IO_INIT +//RVTEST_IO_WRITE_STR +#define RVMODEL_IO_WRITE_STR(_R, _STR) +//RVTEST_IO_CHECK +#define RVMODEL_IO_CHECK() +//RVTEST_IO_ASSERT_GPR_EQ +#define RVMODEL_IO_ASSERT_GPR_EQ(_S, _R, _I) +//RVTEST_IO_ASSERT_SFPR_EQ +#define RVMODEL_IO_ASSERT_SFPR_EQ(_F, _R, _I) +//RVTEST_IO_ASSERT_DFPR_EQ +#define RVMODEL_IO_ASSERT_DFPR_EQ(_D, _R, _I) + +#define RVMODEL_SET_MSW_INT + +#define RVMODEL_CLEAR_MSW_INT + +#define RVMODEL_CLEAR_MTIMER_INT + +#define RVMODEL_CLEAR_MEXT_INT + + +#endif // _COMPLIANCE_MODEL_H diff --git a/riscof-plugins/rv32/sail_cSim/riscof_sail_cSim.py b/riscof-plugins/rv32/sail_cSim/riscof_sail_cSim.py new file mode 100644 index 000000000..e62a1be66 --- /dev/null +++ b/riscof-plugins/rv32/sail_cSim/riscof_sail_cSim.py @@ -0,0 +1,165 @@ +import os +import re +import shutil +import subprocess +import shlex +import logging +import random +import string +from string import Template +import distutils + +import riscof.utils as utils +from riscof.pluginTemplate import pluginTemplate +import riscof.constants as constants +from riscv_isac.isac import isac + +logger = logging.getLogger() + +class sail_cSim(pluginTemplate): + __model__ = "sail_c_simulator" + __version__ = "0.5.0" + + docker_cmd = 'docker run -w /work -v{0}:/work -a stdout -a stderr --init {1} {2}' + + def __init__(self, *args, **kwargs): + sclass = super().__init__(*args, **kwargs) + + config = kwargs.get('config') + if config is None: + logger.error("Config node for sail_cSim missing.") + raise SystemExit + self.num_jobs = str(config['jobs'] if 'jobs' in config else 1) + self.docker = bool(config['docker']) if 'docker' in config else False + self.docker_img = str(config['image']) if 'image' in config else 'riscv_compliance' + self.pluginpath = os.path.abspath(config['pluginpath']) + path = config['PATH'] if 'PATH' in config else "" + + + self.sail_exe = { '32' : os.path.join(path,"riscv_sim_RV32"), + '64' : os.path.join(path,"riscv_sim_RV64")} + self.isa_spec = os.path.abspath(config['ispec']) if 'ispec' in config else '' + self.platform_spec = os.path.abspath(config['pspec']) if 'ispec' in config else '' + self.make = config['make'] if 'make' in config else 'make' + logger.debug("SAIL CSim plugin initialised using the following configuration.") + for entry in config: + logger.debug(entry+' : '+config[entry]) + return sclass + + def initialise(self, suite, work_dir, archtest_env): + self.suite = suite + self.work_dir = work_dir + self.objdump_cmd = 'riscv{1}-unknown-elf-objdump -D {0} > {2};' + self.archtest_env = archtest_env + compile_cmd = 'riscv{1}-unknown-elf-gcc -march={0} \ + -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles' + + if not self.docker: + compile_cmd += ' -T '+self.pluginpath+'/env/link.ld\ + -I '+self.pluginpath+'/env/\ + -I ' + archtest_env + else: + compile_cmd += ' -T /work/sail_work/env/link.ld\ + -I /work/sail_work/env/\ + -I /work/test/includes' + self.compile_cmd = compile_cmd + + def build(self, isa_yaml, platform_yaml): + ispec = utils.load_yaml(isa_yaml)['hart0'] + self.xlen = ('64' if 64 in ispec['supported_xlen'] else '32') + self.isa = 'rv' + self.xlen + if "64I" in ispec["ISA"]: + self.compile_cmd = self.compile_cmd+' -mabi='+'lp64 ' + elif "32I" in ispec["ISA"]: + self.compile_cmd = self.compile_cmd+' -mabi='+'ilp32 ' + elif "32E" in ispec["ISA"]: + self.compile_cmd = self.compile_cmd+' -mabi='+'ilp32e ' + if "I" in ispec["ISA"]: + self.isa += 'i' + if "E" in ispec["ISA"]: + self.isa += 'e' + if "M" in ispec["ISA"]: + self.isa += 'm' + if "A" in ispec["ISA"]: + self.isa += 'a' + if "C" in ispec["ISA"]: + self.isa += 'c' + if "F" in ispec["ISA"]: + self.isa += 'f' + if "D" in ispec["ISA"]: + self.isa += 'd' + objdump = "riscv{0}-unknown-elf-objdump".format(self.xlen) + if not self.docker: + if shutil.which(objdump) is None: + logger.error(objdump+": executable not found. Please check environment setup.") + raise SystemExit + compiler = "riscv{0}-unknown-elf-gcc".format(self.xlen) + if shutil.which(compiler) is None: + logger.error(compiler+": executable not found. Please check environment setup.") + raise SystemExit + if shutil.which(self.sail_exe[self.xlen]) is None: + logger.error(self.sail_exe[self.xlen]+ ": executable not found. Please check environment setup.") + raise SystemExit + if shutil.which(self.make) is None: + logger.error(self.make+": executable not found. Please check environment setup.") + raise SystemExit + else: + os.mkdir(os.path.join(self.work_dir,"sail_work")) + os.mkdir(os.path.join(self.work_dir,"test")) + self.test_dir = os.path.join(self.work_dir,"test") + distutils.dir_util.copy_tree(self.archtest_env,os.path.join(self.test_dir,"includes")) + distutils.dir_util.copy_tree( + os.path.join(self.pluginpath,"env"), + os.path.join(self.work_dir,"sail_work/env")) + + def runTests(self, testList, cgf_file=None, header_file= None): + if os.path.exists(self.work_dir+ "/Makefile." + self.name[:-1]): + os.remove(self.work_dir+ "/Makefile." + self.name[:-1]) + make = utils.makeUtil(makefilePath=os.path.join(self.work_dir, "Makefile." + self.name[:-1])) + make.makeCommand = self.make + ' -j' + self.num_jobs + for file in testList: + testentry = testList[file] + test = testentry['test_path'] + test_dir = testentry['work_dir'] + test_name = test.rsplit('/',1)[1][:-2] + + elf = 'ref.elf' + + execute = "@cd "+testentry['work_dir']+";" + + cmd = self.compile_cmd.format(testentry['isa'].lower(), self.xlen) + ' ' + test + ' -o ' + elf + compile_cmd = cmd + ' -D' + " -D".join(testentry['macros']) + execute+=compile_cmd+";" + + execute += self.objdump_cmd.format(elf, self.xlen, 'ref.disass') + sig_file = os.path.join(test_dir, self.name[:-1] + ".signature") + + execute += self.sail_exe[self.xlen] + ' -i -v --trace=step --pmp-count=16 --pmp-grain=0 --test-signature={0} {1} > {2}.log 2>&1;'.format(sig_file, elf, test_name) + + cov_str = ' ' + for label in testentry['coverage_labels']: + cov_str+=' -l '+label + + cgf_mac = ' ' + header_file_flag = ' ' + if header_file is not None: + header_file_flag = f' -h {header_file} ' + cgf_mac += ' -cm common ' + for macro in testentry['mac']: + cgf_mac+=' -cm '+macro + + if cgf_file is not None: + coverage_cmd = 'riscv_isac --verbose info coverage -d \ + -t {0}.log --parser-name c_sail -o coverage.rpt \ + --sig-label begin_signature end_signature \ + --test-label rvtest_code_begin rvtest_code_end \ + -e ref.elf -c {1} -x{2} {3} {4} {5};'.format(\ + test_name, ' -c '.join(cgf_file), self.xlen, cov_str, header_file_flag, cgf_mac) + else: + coverage_cmd = '' + + + execute+=coverage_cmd + + make.add_target(execute) + make.execute_all(self.work_dir) diff --git a/riscof-plugins/rv32/sail_cSim/sail_isa.yaml b/riscof-plugins/rv32/sail_cSim/sail_isa.yaml new file mode 100644 index 000000000..eeb44ab34 --- /dev/null +++ b/riscof-plugins/rv32/sail_cSim/sail_isa.yaml @@ -0,0 +1,38 @@ +hart_ids: [0] +hart0: + ISA: RV32IMACZicsr_Zifencei + physical_addr_sz: 32 + supported_xlen: [32] + misa: + reset-val: 0x0 + rv32: + mxl: + implemented: false + extensions: + implemented: false + accessible: true + rv64: + accessible: false + mtvec: + reset-val: 0x80000000 + rv32: + base: + implemented: true + type: + warl: + dependency_fields: [] + legal: + - base[29:0] in [0x20000000] + wr_illegal: + - Unchanged + mode: + implemented: true + type: + warl: + dependency_fields: [] + legal: + - mode[1:0] in [0x0] + wr_illegal: + - Unchanged + + accessible: true diff --git a/riscof-plugins/rv32/sail_cSim/sail_platform.yaml b/riscof-plugins/rv32/sail_cSim/sail_platform.yaml new file mode 100644 index 000000000..4b99ed9c1 --- /dev/null +++ b/riscof-plugins/rv32/sail_cSim/sail_platform.yaml @@ -0,0 +1,4 @@ +nmi: + label: nmi_vector +reset: + label: reset_vector diff --git a/riscof-plugins/rv32/spike_simple/README.md b/riscof-plugins/rv32/spike_simple/README.md new file mode 100644 index 000000000..f0cce8a90 --- /dev/null +++ b/riscof-plugins/rv32/spike_simple/README.md @@ -0,0 +1,30 @@ +### Riscof Plugin for SPIKE RISC-V ISA Simulator + +- Using the SPIKE RISC-V ISA Simulator + +The [Spike, RISC-V ISA Simulator](https://github.com/riscv/riscv-isa-sim) implements a functional +model of one or more RISC-V Harts. It can be used as a target for running tests using riscof. + +- Config file entry +``` +# Name of the Plugin. All entries are case sensitive. Including the name. +[spike_simple] + +#path to the directory where the plugin is present. (required) +pluginpath= + +#path where the riscv-isa-sim binary is available. (optional) +#if this value is absent, it is assumed that the binaries are available as executables by default +PATH= + +#path to the ISA config file. (required) +ispec= + +#path to the Platform config file. (required) +pspec= +``` + +- Export command +``` +pwd=pwd;export PYTHONPATH=$pwd:$PYTHONPATH; +``` diff --git a/riscof-plugins/rv32/spike_simple/__init__.py b/riscof-plugins/rv32/spike_simple/__init__.py new file mode 100644 index 000000000..0bfb5a62b --- /dev/null +++ b/riscof-plugins/rv32/spike_simple/__init__.py @@ -0,0 +1,2 @@ +from pkgutil import extend_path +__path__ = extend_path(__path__, __name__) \ No newline at end of file diff --git a/riscof-plugins/rv32/spike_simple/__pycache__/riscof_spike_simple.cpython-310.pyc b/riscof-plugins/rv32/spike_simple/__pycache__/riscof_spike_simple.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f4d1ac5c7fabf9df470e81867f313ed7f91aa6a4 GIT binary patch literal 3476 zcmaJ^O>Y~=8Q$5QT`rePQl>2{a#LqvBu0sVk}4TaT*r=GJ8lg)su4S=OQ6`UI7?}z z{h()-vPF|9P`k*fJ@uB02=tOee?b33`v>OQlW#o-Y13zhlw=t}mzdAzozM53=Y3h! z>z;vc<8S}$f4yQD|5A-NKZ?dJB=Hwy%wQxny0emWiEf)+Q^6xJ+lLENqkHBT2BXY=WiUH# zzO=e6Mjjb$=QVa_Y_^GXAII4sjmjAH#vmPTC;3rNPszObS@VYY1eMrOXTdoL&R}-w zS4N*Oi_upu&R{d=m4P!5DanzSOIlB!Jn4}) zmQ**XQWHu116gUjGm~UEDeYb7 zu)^rr+Bf(IkfO^*PShT!=GX|`vdStN+W=P47{&qd^vD`|-DP8{di>*_>b$3Z+~duA z8Vn<_QiO4}WrO*9CXZMhqnpflWU$6jt=-&|POr%O$@XaVVH!sw4&uCwd649TVHxz3 zG!6z)xg*dK%mjx#Dw85#d97|q(ucPn|56&<){Wg_OGs~~Lp4m=i5SE^X%BSal@Z^L z%a9LqN!IQ?ZZF{4hl7|)Hw=?JDZ@}&5P&>S@=|(_4n!GepFK}XX%<3KJty5Ql3Z5U zungnpv9v^q@%b6Vco6M7+1tDPvLU zcG2(5?m(>a{f+h2Hw|qrfL)vz-^$>Cx3KCvNa6yr7V%7%y2K@cbHQ#|E!raIY!AJo z#Zv>1uC1p`^ypJ{6X_0;SVuNiMrMqa`4EPD*IdGrUNYu23pFH0RZj>L#`CZ@N59uc zd-2mrXPEEh#k0JFyXtKBdO;^s=e_Y_Z4w-R9Z|wA6xPcM7N<9|m__+P(CP0dBH2pP zq&&E>lQ0(NK_@Rn$X44MjA!evzqlQLG-nOW3&MK-{aVJ~BC%HP8sDNBS5zpU!M zI-gQ!h#m0v(KX9HP@tzQHHp$h#5d6v7m+!(W0^KJ&HtK6)H45LszlB2OzM3%S~{h) zlkvSHKEo86Wt8f)+Ww77X&i!Qrcl|kF#)6CHCxLD-gT2v#U46yK&9R>vOb<6wK?J+BcINZ`W$H-BM;_CbB-(=Bfps=XXZ%j80pWEvoi#{ zr0kqBJ4nn$mRdfPhetznX~M?ge?tYMv} zKJ`h1{7`zIj#{ToLl5q$$9wcOP;rs8RqTUvOL(6{JZNZ_=qIfFw)sbM*;s;y;P1g| zU>QG*!Xr7m6+MHiWh||ilkp~_e{M4Md^VLpcp2n)I#%hNyX7ZKiS~4acW~d$d=&3IohxMtVsK(eH zSH|Adp48B4@~@FEum+@z-7{l%T$zHrCjQuGO?@8=u(E|YTAhOCCVpL0E6%;5 zi1Ax;eRS>rOx5XN`3_hyOG@x?8qBsBtltbU^{5{Ac8cKA=C6V;zTCVtYTfFw0PKHV zfymY;*SU%Y+Kc==3ciF)I`Q*FlwwAxG>@`aIy}yb{g{8Ma97>Xmw19)xjp_P)mKw} zcd&~nXZi_BN4e|>5kXo!i#floM3wL6%PLb>B)y2Sa28p}8X|(;5L6$fDPIKIZp_%- zRXTWp4N0ojkh-lmrL}{ghaX6)gl3R-8R#gl7w-ABIndQ94Hu&S<|3pcaNufrIXqCkXp2SWNP3@Q36nyqK1voP;M zK#Hg%FG1ob)x|k@`kw?>o>o>7Tt2{xh&Ua!GAv3R temp; mv \ +temp sign; exit 0 diff --git a/riscof-plugins/rv32/spike_simple/riscof_spike_simple.py b/riscof-plugins/rv32/spike_simple/riscof_spike_simple.py new file mode 100644 index 000000000..a590aad0a --- /dev/null +++ b/riscof-plugins/rv32/spike_simple/riscof_spike_simple.py @@ -0,0 +1,254 @@ +import os +import re +import shutil +import subprocess +import shlex +import logging +import random +import string +from string import Template +import sys + +import riscof.utils as utils +import riscof.constants as constants +from riscof.pluginTemplate import pluginTemplate + +logger = logging.getLogger() + +class spike_simple(pluginTemplate): + __model__ = "spike" + + #TODO: please update the below to indicate family, version, etc of your DUT. + __version__ = "XXX" + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + config = kwargs.get('config') + + # If the config node for this DUT is missing or empty. Raise an error. At minimum we need + # the paths to the ispec and pspec files + if config is None: + print("Please enter input file paths in configuration.") + raise SystemExit(1) + + # In case of an RTL based DUT, this would be point to the final binary executable of your + # test-bench produced by a simulator (like verilator, vcs, incisive, etc). In case of an iss or + # emulator, this variable could point to where the iss binary is located. If 'PATH variable + # is missing in the config.ini we can hardcode the alternate here. + self.dut_exe = os.path.join(config['PATH'] if 'PATH' in config else "","spike") + + # Number of parallel jobs that can be spawned off by RISCOF + # for various actions performed in later functions, specifically to run the tests in + # parallel on the DUT executable. Can also be used in the build function if required. + self.num_jobs = str(config['jobs'] if 'jobs' in config else 1) + + # Path to the directory where this python file is located. Collect it from the config.ini + self.pluginpath=os.path.abspath(config['pluginpath']) + + # Collect the paths to the riscv-config absed ISA and platform yaml files. One can choose + # to hardcode these here itself instead of picking it from the config.ini file. + self.isa_spec = os.path.abspath(config['ispec']) + self.platform_spec = os.path.abspath(config['pspec']) + + #We capture if the user would like the run the tests on the target or + #not. If you are interested in just compiling the tests and not running + #them on the target, then following variable should be set to False + if 'target_run' in config and config['target_run']=='0': + self.target_run = False + else: + self.target_run = True + + def initialise(self, suite, work_dir, archtest_env): + + # capture the working directory. Any artifacts that the DUT creates should be placed in this + # directory. Other artifacts from the framework and the Reference plugin will also be placed + # here itself. + self.work_dir = work_dir + + # capture the architectural test-suite directory. + self.suite_dir = suite + + # Note the march is not hardwired here, because it will change for each + # test. Similarly the output elf name and compile macros will be assigned later in the + # runTests function + self.compile_cmd = 'riscv{1}-unknown-elf-gcc -march={0} \ + -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles -g\ + -T '+self.pluginpath+'/env/link.ld\ + -I '+self.pluginpath+'/env/\ + -I ' + archtest_env + ' {2} -o {3} {4}' + + # add more utility snippets here + + def build(self, isa_yaml, platform_yaml): + + # load the isa yaml as a dictionary in python. + ispec = utils.load_yaml(isa_yaml)['hart0'] + + # capture the XLEN value by picking the max value in 'supported_xlen' field of isa yaml. This + # will be useful in setting integer value in the compiler string (if not already hardcoded); + self.xlen = ('64' if 64 in ispec['supported_xlen'] else '32') + + # for spike start building the '--isa' argument. the self.isa is dutnmae specific and may not be + # useful for all DUTs + self.isa = 'rv' + self.xlen + if "I" in ispec["ISA"]: + self.isa += 'i' + if "M" in ispec["ISA"]: + self.isa += 'm' + if "A" in ispec["ISA"]: + self.isa += 'a' + if "F" in ispec["ISA"]: + self.isa += 'f' + if "D" in ispec["ISA"]: + self.isa += 'd' + if "C" in ispec["ISA"]: + self.isa += 'c' + + #TODO: The following assumes you are using the riscv-gcc toolchain. If + # not please change appropriately + self.compile_cmd = self.compile_cmd+' -mabi='+('lp64 ' if 64 in ispec['supported_xlen'] else 'ilp32 ') + + def runTests(self, testList): + + # Delete Makefile if it already exists. + if os.path.exists(self.work_dir+ "/Makefile." + self.name[:-1]): + os.remove(self.work_dir+ "/Makefile." + self.name[:-1]) + # create an instance the makeUtil class that we will use to create targets. + make = utils.makeUtil(makefilePath=os.path.join(self.work_dir, "Makefile." + self.name[:-1])) + + # set the make command that will be used. The num_jobs parameter was set in the __init__ + # function earlier + make.makeCommand = 'make -k -j' + self.num_jobs + + # we will iterate over each entry in the testList. Each entry node will be refered to by the + # variable testname. + for testname in testList: + + # for each testname we get all its fields (as described by the testList format) + testentry = testList[testname] + + # we capture the path to the assembly file of this test + test = testentry['test_path'] + + # capture the directory where the artifacts of this test will be dumped/created. RISCOF is + # going to look into this directory for the signature files + test_dir = testentry['work_dir'] + + # name of the elf file after compilation of the test + elf = 'my.elf' + + # name of the signature file as per requirement of RISCOF. RISCOF expects the signature to + # be named as DUT-.signature. The below variable creates an absolute path of + # signature file. + sig_file = os.path.join(test_dir, self.name[:-1] + ".signature") + log_file = os.path.join(test_dir, self.name[:-1] + ".log") + + # for each test there are specific compile macros that need to be enabled. The macros in + # the testList node only contain the macros/values. For the gcc toolchain we need to + # prefix with "-D". The following does precisely that. + compile_macros= ' -D' + " -D".join(testentry['macros']) + + # substitute all variables in the compile command that we created in the initialize + # function + cmd = self.compile_cmd.format(testentry['isa'].lower(), self.xlen, test, elf, compile_macros) + + # if the user wants to disable running the tests and only compile the tests, then + # the "else" clause is executed below assigning the sim command to simple no action + # echo statement. + if self.target_run: + # set up the simulation command. Template is for spike. Please change. + simcmd = self.dut_exe + ' -m8796093022208 --isa={0} +signature={1} +signature-granularity=4 {2}'.format(self.isa, sig_file, elf) + simcmd = simcmd + ';' + self.dut_exe + ' -m8796093022208 --isa={0} --log-commits -l my.elf 2> {1}'.format(self.isa, log_file) + else: + simcmd = 'echo "NO RUN"' + + # concatenate all commands that need to be executed within a make-target. + execute = '@cd {0}; {1}; {2};'.format(testentry['work_dir'], cmd, simcmd) + + # create a target. The makeutil will create a target with the name "TARGET" where num + # starts from 0 and increments automatically for each new target that is added + make.add_target(execute) + + # if you would like to exit the framework once the makefile generation is complete uncomment the + # following line. Note this will prevent any signature checking or report generation. + #raise SystemExit + + # once the make-targets are done and the makefile has been created, run all the targets in + # parallel using the make command set above. + make.execute_all(self.work_dir) + + # if target runs are not required then we simply exit as this point after running all + # the makefile targets. + if not self.target_run: + raise SystemExit(0) + +#The following is an alternate template that can be used instead of the above. +#The following template only uses shell commands to compile and run the tests. + +# def runTests(self, testList): +# +# # we will iterate over each entry in the testList. Each entry node will be referred to by the +# # variable testname. +# for testname in testList: +# +# logger.debug('Running Test: {0} on DUT'.format(testname)) +# # for each testname we get all its fields (as described by the testList format) +# testentry = testList[testname] +# +# # we capture the path to the assembly file of this test +# test = testentry['test_path'] +# +# # capture the directory where the artifacts of this test will be dumped/created. +# test_dir = testentry['work_dir'] +# +# # name of the elf file after compilation of the test +# elf = 'my.elf' +# +# # name of the signature file as per requirement of RISCOF. RISCOF expects the signature to +# # be named as DUT-.signature. The below variable creates an absolute path of +# # signature file. +# sig_file = os.path.join(test_dir, self.name[:-1] + ".signature") +# +# # for each test there are specific compile macros that need to be enabled. The macros in +# # the testList node only contain the macros/values. For the gcc toolchain we need to +# # prefix with "-D". The following does precisely that. +# compile_macros= ' -D' + " -D".join(testentry['macros']) +# +# # collect the march string required for the compiler +# marchstr = testentry['isa'].lower() +# +# # substitute all variables in the compile command that we created in the initialize +# # function +# cmd = self.compile_cmd.format(marchstr, self.xlen, test, elf, compile_macros) +# +# # just a simple logger statement that shows up on the terminal +# logger.debug('Compiling test: ' + test) +# +# # the following command spawns a process to run the compile command. Note here, we are +# # changing the directory for this command to that pointed by test_dir. If you would like +# # the artifacts to be dumped else where change the test_dir variable to the path of your +# # choice. +# utils.shellCommand(cmd).run(cwd=test_dir) +# +# # for debug purposes if you would like stop the DUT plugin after compilation, you can +# # comment out the lines below and raise a SystemExit +# +# if self.target_run: +# # build the command for running the elf on the DUT. In this case we use spike and indicate +# # the isa arg that we parsed in the build stage, elf filename and signature filename. +# # Template is for spike. Please change for your DUT +# execute = self.dut_exe + ' --isa={0} +signature={1} +signature-granularity=4 {2}'.format(self.isa, sig_file, elf) +# logger.debug('Executing on Spike ' + execute) +# +# # launch the execute command. Change the test_dir if required. +# utils.shellCommand(execute).run(cwd=test_dir) +# +# # post-processing steps can be added here in the template below +# #postprocess = 'mv {0} temp.sig'.format(sig_file)' +# #utils.shellCommand(postprocess).run(cwd=test_dir) +# +# # if target runs are not required then we simply exit as this point after running all +# # the makefile targets. +# if not self.target_run: +# raise SystemExit diff --git a/riscof-plugins/rv32/spike_simple/spike_simple_isa.yaml b/riscof-plugins/rv32/spike_simple/spike_simple_isa.yaml new file mode 100644 index 000000000..69e1c6cb9 --- /dev/null +++ b/riscof-plugins/rv32/spike_simple/spike_simple_isa.yaml @@ -0,0 +1,29 @@ +hart_ids: [0] +hart0: + ISA: RV32IMACZicsr_Zifencei + physical_addr_sz: 32 + User_Spec_Version: '2.3' + supported_xlen: [32] + misa: + reset-val: 0x40001105 + rv32: + accessible: true + mxl: + implemented: true + type: + warl: + dependency_fields: [] + legal: + - mxl[1:0] in [0x1] + wr_illegal: + - Unchanged + extensions: + implemented: true + type: + warl: + dependency_fields: [] + legal: + - extensions[25:0] bitmask [0x0001105, 0x0000000] + wr_illegal: + - Unchanged + diff --git a/riscof-plugins/rv32/spike_simple/spike_simple_platform.yaml b/riscof-plugins/rv32/spike_simple/spike_simple_platform.yaml new file mode 100644 index 000000000..8e1a3d8e3 --- /dev/null +++ b/riscof-plugins/rv32/spike_simple/spike_simple_platform.yaml @@ -0,0 +1,10 @@ +mtime: + implemented: true + address: 0xbff8 +mtimecmp: + implemented: true + address: 0x4000 +nmi: + label: nmi_vector +reset: + label: reset_vector diff --git a/riscof-plugins/rv64/config.ini b/riscof-plugins/rv64/config.ini new file mode 100755 index 000000000..dfe45f860 --- /dev/null +++ b/riscof-plugins/rv64/config.ini @@ -0,0 +1,14 @@ +[RISCOF] +ReferencePlugin=sail_cSim +ReferencePluginPath=sail_cSim +DUTPlugin=spike_simple +DUTPluginPath=spike_simple + +[spike_simple] +pluginpath=spike_simple +ispec=spike_simple/spike_simple_isa.yaml +pspec=spike_simple/spike_simple_platform.yaml +target_run=1 + +[sail_cSim] +pluginpath=sail_cSim diff --git a/riscof-plugins/rv64/makeplugin/README.md b/riscof-plugins/rv64/makeplugin/README.md new file mode 100755 index 000000000..6df224c4d --- /dev/null +++ b/riscof-plugins/rv64/makeplugin/README.md @@ -0,0 +1,95 @@ +### Plugin to use Makefile.include from old framework with riscof + +- This plugin facilitates the use of Makefile.include from the targets of the old framework with + riscof and is intented to be used as a base for transition. +- The config node of the plugin can contain the following variables/ + - **makefiles** (*required*)- Comma separated paths to the makefiles. If multiple are specified, all will be + merged in the final output makefile. Note that only the varaibles in the makefiles are written + out into the final makefiles. Any targets or includes will be left out. Such cases can be + handled by editing the plugin to output the relevant lines as a part of the `build` function. + - **jobs** - The number of threads to launch parallely. (Default is `1`) + - **ispec** (*required*)- The path to the input ISA yaml specification of the target. + - **pspec** (*required*)- The path to the input platform yaml specification of the target. + - **make** - The make utility to use like make,bmake,pmake etc. (Default is `make`) + +- The commands in the makefiles need to be modified to make use of the following variables. The + values for these are resolved based on the inputs from riscof and are substituted before writing + out the final targets. An additional Makefile variable, `TARGET_DIR`, which contains the path + where the plugin resides is written out at the starting of the makefile and can be used as an anchor + point for resolving paths to other files. + + | Variable | Description | + | ------------- | ----------- | + | `${target_dir}` | The directory where the plugin file resides. (riscof_makeplugin.py) | + | `${asm}` | Absolute path to the assemble test file i.e the .S file for the test. | + | `${work_dir}` | The absolute path to the work directory for the test. | + | `${test_name}` | The name of the test, for example add-01 etc. Can be used for naming any intermediate files generated. | + | `${include}` | The path to the directory which containts the test header files. This needs to be specified as an include path in the compile command. | + | `${march}` | The ISA to be used for compiling the test. This is in the format expected by march argument of gcc. | + | `${mabi}` | The abi to be used for compiling the test. This is in the format expected by mabi argument of gcc. | + | `${target_isa}` | This is the ISA specified in the input ISA yaml. The idea is that it can be used to configure the model at run time via cli arguments if necessary. | + | `${test_bin}` | The name of the binary file to be created after compilation. Can be ignored. Custom names can be used as long as the RUN_TARGET command picks up the correct binary to execute on the target. | + | `${signature_file}` | The absolute path to the signature file. This path cannot be changed and the signature file should be present at this path for riscof to verify at the end of testing. | + | `${macros}` | The macros to be defined while compilation. Currently they are in the format expected by gcc i.e. `-D =` | + + + The rewritten Makefile.include for the SAIL C Simulator from [here](https://github.com/riscv/riscv-arch-test/blob/2.4.4/riscv-target/sail-riscv-c/device/rv32i_m/I/Makefile.include) is included in the directory + for reference(`sail.include`). + + **Note** - Value substitution for these variables happens only in the + `COMPILE_TARGET` and `RUN_TARGET` values in the makefile. There is no resolution of makefile + variables while substituting the values. The format of the output for each target is: + ``` + cd ;;; + ``` + +- Examples + + **Correct** : + + ``` + TARGET_SIM ?= riscv_sim_RV32 -V + TARGET_FLAGS = + + RISCV_PREFIX ?= riscv32-unknown-elf- + RISCV_GCC ?= $(RISCV_PREFIX)gcc + RISCV_GCC_OPTS ?= -g -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles \ + -I$(TARGET_DIR)/env/ + + COMPILE_TARGET=\ + $$(RISCV_GCC) -march=${march} -mabi=${mabi} $$(RISCV_GCC_OPTS) \ + -I${include} \ + -T${target_dir}/env/link.ld \ + ${asm} -o ${test_bin} ${macros}; + + RUN_TARGET=\ + $(TARGET_SIM) $(TARGET_FLAGS)\ + --test-signature=${signature_file} \ + ${test_bin} + + ``` + + **Wrong** : + + ``` + TARGET_SIM ?= riscv_sim_RV32 -V + TARGET_FLAGS = + + RISCV_PREFIX ?= riscv32-unknown-elf- + RISCV_GCC ?= $(RISCV_PREFIX)gcc + RISCV_GCC_OPTS ?= -g -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles \ + -I$(TARGET_DIR)/env/ -I${include} \ + + COMPILE_TARGET=\ + $$(RISCV_GCC) -march=${march} -mabi=${mabi} $$(RISCV_GCC_OPTS) \ + -T${target_dir}/env/link.ld \ + ${asm} -o ${test_bin} ${macros}; + + RUN_TARGET=\ + $(TARGET_SIM) $(TARGET_FLAGS)\ + --test-signature=${signature_file} \ + ${test_bin} + ``` + The commands produced using the above makefile will result in an error when executed because the + value of `${include}` will not be substituted in the `RISCV_GCC_OPTS` (Variable substitutions + are performed only for the `COMPILE_TARGET` and `RUN_TARGET` commands). diff --git a/riscof-plugins/rv64/makeplugin/__init__.py b/riscof-plugins/rv64/makeplugin/__init__.py new file mode 100755 index 000000000..0bfb5a62b --- /dev/null +++ b/riscof-plugins/rv64/makeplugin/__init__.py @@ -0,0 +1,2 @@ +from pkgutil import extend_path +__path__ = extend_path(__path__, __name__) \ No newline at end of file diff --git a/riscof-plugins/rv64/makeplugin/env/link.ld b/riscof-plugins/rv64/makeplugin/env/link.ld new file mode 100755 index 000000000..8ad95e049 --- /dev/null +++ b/riscof-plugins/rv64/makeplugin/env/link.ld @@ -0,0 +1,18 @@ +OUTPUT_ARCH( "riscv" ) +ENTRY(rvtest_entry_point) + +SECTIONS +{ + . = 0x80000000; + .text.init : { *(.text.init) } + . = ALIGN(0x1000); + .tohost : { *(.tohost) } + . = ALIGN(0x1000); + .text : { *(.text) } + . = ALIGN(0x1000); + .data : { *(.data) } + .data.string : { *(.data.string)} + .bss : { *(.bss) } + _end = .; +} + diff --git a/riscof-plugins/rv64/makeplugin/env/model_test.h b/riscof-plugins/rv64/makeplugin/env/model_test.h new file mode 100755 index 000000000..5a362683c --- /dev/null +++ b/riscof-plugins/rv64/makeplugin/env/model_test.h @@ -0,0 +1,60 @@ +#ifndef _COMPLIANCE_MODEL_H +#define _COMPLIANCE_MODEL_H +#if XLEN == 64 + #define ALIGNMENT 3 +#else + #define ALIGNMENT 2 +#endif + +#define RVMODEL_DATA_SECTION \ + .pushsection .tohost,"aw",@progbits; \ + .align 8; .global tohost; tohost: .dword 0; \ + .align 8; .global fromhost; fromhost: .dword 0; \ + .popsection; \ + .align 8; .global begin_regstate; begin_regstate: \ + .word 128; \ + .align 8; .global end_regstate; end_regstate: \ + .word 4; + +//RV_COMPLIANCE_HALT +#define RVMODEL_HALT \ + li x1, 1; \ + write_tohost: \ + sw x1, tohost, t5; \ + j write_tohost; + +#define RVMODEL_BOOT + +//RV_COMPLIANCE_DATA_BEGIN +#define RVMODEL_DATA_BEGIN \ + RVMODEL_DATA_SECTION \ + .align ALIGNMENT;\ + .global begin_signature; begin_signature: + +//RV_COMPLIANCE_DATA_END +#define RVMODEL_DATA_END \ + .global end_signature; end_signature: + +//RVTEST_IO_INIT +#define RVMODEL_IO_INIT +//RVTEST_IO_WRITE_STR +#define RVMODEL_IO_WRITE_STR(_R, _STR) +//RVTEST_IO_CHECK +#define RVMODEL_IO_CHECK() +//RVTEST_IO_ASSERT_GPR_EQ +#define RVMODEL_IO_ASSERT_GPR_EQ(_S, _R, _I) +//RVTEST_IO_ASSERT_SFPR_EQ +#define RVMODEL_IO_ASSERT_SFPR_EQ(_F, _R, _I) +//RVTEST_IO_ASSERT_DFPR_EQ +#define RVMODEL_IO_ASSERT_DFPR_EQ(_D, _R, _I) + +#define RVMODEL_SET_MSW_INT + +#define RVMODEL_CLEAR_MSW_INT + +#define RVMODEL_CLEAR_MTIMER_INT + +#define RVMODEL_CLEAR_MEXT_INT + + +#endif // _COMPLIANCE_MODEL_H diff --git a/riscof-plugins/rv64/makeplugin/riscof_makeplugin.py b/riscof-plugins/rv64/makeplugin/riscof_makeplugin.py new file mode 100755 index 000000000..22869a306 --- /dev/null +++ b/riscof-plugins/rv64/makeplugin/riscof_makeplugin.py @@ -0,0 +1,180 @@ +import os +import re +import shutil +import subprocess +import shlex +import logging +import random +import string +from string import Template + +import riscof.utils as utils +from riscof.pluginTemplate import pluginTemplate +import riscof.constants as constants +from riscv_isac.isac import isac + +logger = logging.getLogger() + +var_regex = r"^([a-zA-Z0-9_]+)[ ]*[?]?=(.*)$" +# The abi string to be passed to the compiler. The format adheres to the mabi +# argument of GCC. To change how this string is derived, change this function. +def mabi(isa): + isa = isa.lower() + abi = 'lp64' if '64' in isa else 'ilp32' + if 'd' in isa: + abi += 'd' + elif 'f' in isa: + abi += 'f' + return abi +def getmakevars(arg): + with open(arg,"r") as fp: + lines = [line.strip() for line in fp.readlines()] + lines = '\n'.join(lines) + lines = lines.replace("\\\n"," ") + larr = lines.split("\n") + ret_dict = {} + for entry in larr: + x = re.sub("((\\t)+)",lambda x:" ",entry) + x = re.sub("(( )+)",lambda x:" ",entry) + match = re.match(var_regex,x) + if match: + key = match.group(1) + val = match.group(2) + ret_dict[key] = val + return ret_dict + +class makeplugin(pluginTemplate): + # The target name and version info printed in the reports. These variables can be defined here + # statically or dynamically extracted from other sources. + __model__ = "makeplugin" + __version__ = "0.0.1" + + def __init__(self, *args, **kwargs): + sclass = super().__init__(*args, **kwargs) + + # Get the node for the plugin in the config.ini file. This is extracted by riscof and only + # the node relevant to the plugin is passed. + config = kwargs.get('config') + + # Extract all information from the nodes. If any required values are missing, an error and a + # system exit is raised. + if 'makefiles' not in config: + logger.error("Path to the Makefiles not specified for "+self.__model__) + raise SystemExit + if 'ispec' not in config or 'pspec' not in config: + logger.error("Path to the input YAML files not specified for "+self.__model__) + raise SystemExit + # Paths to the Makefile.include files. Mandatory to be provided + self.makefiles = [os.path.abspath(path) for path in config['makefiles'].split(",")] + # Number of jobs to launch in parallel + self.num_jobs = str(config['jobs'] if 'jobs' in config else 1) + # Path to the directory in which this file is present + self.pluginpath = os.path.dirname(__file__) + # Path to the input ISA yaml as per riscv-config format. + self.isa_spec = os.path.abspath(config['ispec']) if 'ispec' in config else '' + # Path to the input platform yaml as per riscv-config format. + self.platform_spec = os.path.abspath(config['pspec']) if 'ispec' in config else '' + self.make = config['make'] if 'make' in config else 'make' + return sclass + + def initialise(self, suite, work_dir, archtest_env): + # Store the path to the suite. + self.suite = suite + # Store the path to the root level work directory. + self.work_dir = work_dir + # Store the path to the folder which contains the header files for the tests. + self.archtest_env = archtest_env + + def build(self, isa_yaml, platform_yaml): + # Extract the configuration of hart0 from isa yaml to figure out the configuration of the + # hart being tested. + ispec = utils.load_yaml(isa_yaml)['hart0'] + # Resolve xlen value from the isa yaml + self.xlen = ('64' if 64 in ispec['supported_xlen'] else '32') + # Store the ISA of the target. + self.isa = ispec["ISA"] + self.var_dict = {} + # Extract all variables from the makefiles + for fpath in self.makefiles: + self.var_dict.update(getmakevars(fpath)) + # The path where the Makefile is created + self.makefilepath = os.path.join(self.work_dir, "Makefile." + self.name[:-1]) + with open(self.makefilepath,"w") as fp: + # The path to the target directory, i.e the directory where this python file is + # present. This variable is written out to the makefile so that other variables can use + # this value. + fp.write("TARGET_DIR = "+self.pluginpath+"\n") + # Write out all values except the COMPILE_TARGET and RUN_TARGET commands + for entry in self.var_dict.keys(): + if not entry.endswith("_TARGET"): + fp.write(entry+" = "+self.var_dict[entry]+"\n") + else: + self.var_dict[entry] = Template(self.var_dict[entry]) + + + def runTests(self, testList,cgf_file=None): + # Initialise the Make Utility from riscof with the output path for the Makefile + make = utils.makeUtil(makefilePath=self.makefilepath) + # Modify the make command based on the input values in the config file. + make.makeCommand = self.make + ' -j' + self.num_jobs + # Iterate over all the entries in the test list + for entry in testList: + # Extract the entry from the testlist + testentry = testList[entry] + # Extract the path to the assembly test file from the test list entry + test = testentry['test_path'] + # Extract the path to the work directory for the test. + test_dir = testentry['work_dir'] + # Macros to be defined are added in the GCC command format + # -D = + # Change this if the toolchain uses a different format + macros = ' -D' + " -D".join(testentry['macros']) + # Variables accessible in the *_TARGET commands + # Add more variables below if you wish to use these variables in the *_TARGET commands. + substitute = { + # The path to the target directory, i.e the directory where this python file is + # present + 'target_dir': self.pluginpath, + # Path to the test assembly file + 'asm': test, + # Path to the work directory + 'work_dir': testentry['work_dir'], + # Name of the Test. Can be used to name files in the work directory. + 'test_name': test.rsplit('/',1)[1][:-2], + # The path to the env folder containing the header files for the suite. This path + # should be passed as an include path in the compile commands. + 'include': self.archtest_env, + # The isa string to be passed to the compiler. The format adheres to the march + # argument of GCC + 'march': testentry['isa'].lower(), + # The abi string to be passed to the compiler. The format adheres to the mabi + # argument of GCC. To change how this string is derived, change function on line 21. + 'mabi': mabi(testentry['isa']), + # The ISA string present in the input yaml. Can be used to set the ISA of the target + 'target_isa': self.isa, + # Name of the generated binary file. Can be custom. + 'test_bin': 'ref.elf', + # Name of the signature file. Note the name of the file should be in the same + # particular format and inside the test work directory. + 'signature_file': os.path.join(test_dir, self.name[:-1] + ".signature"), + # The string which specifies all the macros to be defined for the test. As computed + # in line 108. + 'macros': macros + } + + # Construct the command for the test and add a target in the makefile. The format of the + # command is as follows: + # cd ;substitute(COMPILE_TARGET);substitute(RUN_TARGET); + # The RUN_TARGET is optional and can be skipped if the same is not defined in the input + # makefile + execute = "@cd "+testentry['work_dir']+";" + + compile_cmd = self.var_dict['COMPILE_TARGET'].safe_substitute(substitute) + execute+=compile_cmd+";" + if 'RUN_TARGET' in self.var_dict: + run_cmd = self.var_dict['RUN_TARGET'].safe_substitute(substitute) + execute+=run_cmd+";" + # Add target in the makefile for the test + make.add_target(execute,) + # Execute all targets. + make.execute_all(self.work_dir) diff --git a/riscof-plugins/rv64/makeplugin/sail.include b/riscof-plugins/rv64/makeplugin/sail.include new file mode 100755 index 000000000..4c07fea40 --- /dev/null +++ b/riscof-plugins/rv64/makeplugin/sail.include @@ -0,0 +1,21 @@ +TARGET_SIM ?= riscv_sim_RV32 -V +TARGET_FLAGS = + +RISCV_PREFIX ?= riscv32-unknown-elf- +RISCV_GCC ?= $(RISCV_PREFIX)gcc +RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump +RISCV_GCC_OPTS ?= -g -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles + +COMPILE_TARGET=\ + $$(RISCV_GCC) -march=${march} -mabi=${mabi} $$(RISCV_GCC_OPTS) \ + -I${include} \ + -I${target_dir}/env/ \ + -T${target_dir}/env/link.ld \ + ${asm} -o ${test_bin} ${macros};\ + $$(RISCV_OBJDUMP) ${test_bin} -D > ${test_name}.disass; \ + $$(RISCV_OBJDUMP) ${test_bin} --source > ${test_name}.debug + +RUN_TARGET=\ + $(TARGET_SIM) $(TARGET_FLAGS)\ + --test-signature=${signature_file} \ + ${test_bin} diff --git a/riscof-plugins/rv64/sail_cSim/__init__.py b/riscof-plugins/rv64/sail_cSim/__init__.py new file mode 100644 index 000000000..0bfb5a62b --- /dev/null +++ b/riscof-plugins/rv64/sail_cSim/__init__.py @@ -0,0 +1,2 @@ +from pkgutil import extend_path +__path__ = extend_path(__path__, __name__) \ No newline at end of file diff --git a/riscof-plugins/rv64/sail_cSim/__pycache__/__init__.cpython-38.pyc b/riscof-plugins/rv64/sail_cSim/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2094ccfbb0216dae115e1064bfa9a9d98698d0c6 GIT binary patch literal 243 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 {2}.log 2>&1;'.format(sig_file, elf, test_name) + + cov_str = ' ' + for label in testentry['coverage_labels']: + cov_str+=' -l '+label + + cgf_mac = ' ' + header_file_flag = ' ' + if header_file is not None: + header_file_flag = f' -h {header_file} ' + cgf_mac += ' -cm common ' + for macro in testentry['mac']: + cgf_mac+=' -cm '+macro + + if cgf_file is not None: + coverage_cmd = 'riscv_isac --verbose info coverage -d \ + -t {0}.log --parser-name c_sail -o coverage.rpt \ + --sig-label begin_signature end_signature \ + --test-label rvtest_code_begin rvtest_code_end \ + -e ref.elf -c {1} -x{2} {3} {4} {5};'.format(\ + test_name, ' -c '.join(cgf_file), self.xlen, cov_str, header_file_flag, cgf_mac) + else: + coverage_cmd = '' + + + execute+=coverage_cmd + + make.add_target(execute) + make.execute_all(self.work_dir) diff --git a/riscof-plugins/rv64/spike_simple/README.md b/riscof-plugins/rv64/spike_simple/README.md new file mode 100755 index 000000000..f0cce8a90 --- /dev/null +++ b/riscof-plugins/rv64/spike_simple/README.md @@ -0,0 +1,30 @@ +### Riscof Plugin for SPIKE RISC-V ISA Simulator + +- Using the SPIKE RISC-V ISA Simulator + +The [Spike, RISC-V ISA Simulator](https://github.com/riscv/riscv-isa-sim) implements a functional +model of one or more RISC-V Harts. It can be used as a target for running tests using riscof. + +- Config file entry +``` +# Name of the Plugin. All entries are case sensitive. Including the name. +[spike_simple] + +#path to the directory where the plugin is present. (required) +pluginpath= + +#path where the riscv-isa-sim binary is available. (optional) +#if this value is absent, it is assumed that the binaries are available as executables by default +PATH= + +#path to the ISA config file. (required) +ispec= + +#path to the Platform config file. (required) +pspec= +``` + +- Export command +``` +pwd=pwd;export PYTHONPATH=$pwd:$PYTHONPATH; +``` diff --git a/riscof-plugins/rv64/spike_simple/__init__.py b/riscof-plugins/rv64/spike_simple/__init__.py new file mode 100755 index 000000000..0bfb5a62b --- /dev/null +++ b/riscof-plugins/rv64/spike_simple/__init__.py @@ -0,0 +1,2 @@ +from pkgutil import extend_path +__path__ = extend_path(__path__, __name__) \ No newline at end of file diff --git a/riscof-plugins/rv64/spike_simple/__pycache__/riscof_model.cpython-38.pyc b/riscof-plugins/rv64/spike_simple/__pycache__/riscof_model.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8ce4f473b782a3bd49fdd3c2711892acbb6a7b18 GIT binary patch literal 3225 zcmZuzOK%)m6|P&auC9LAags?q450|pfQ8yloG2_N2^l2>GMbo(I8sy+DwXS&?Xv69 zb8mHGce+6$8O;jBf(1+Wa#*sS1uG=@0W9uzR{0Bv34G`F! zbbJHf5C8Eu{&~+ZzNXIGpN-BP6!|9*Zg7?x;k0HU(|t2Eb!~-~uIxRWlu zw89n69vf@!Yn;s3T4T!FPK$mX*D2cFem>aC%K1n_Ja2#2tRrutks5Rtx(DvSLi-D2 zmvNI@uRPpA?}$6Nyz$Dw9X#Gd?R{a`M%cvuzH0D6UB*QkT2G%oP1sx8ko2f5p~%03 z)W%EWfQ{J5`~zdg$UHGQo3ODpg6s}GaizAn`4UKNbL%Dh9jl!K_oTt?k#*>b`{1%y zjnd=}cPHk^h`hSV8yedI*3cN{0rBx4D9q3=CxK0 z-aa(NSGe-f-hlp2ji_(y~rPkd^&G9qeX#8ua6OUt%Db zG7dysXH~iWn&hMGM;~whLK%XDqwIrfM=F1+F`A~FO!m_xbox{&zmCOTT1R3~Dt6`m z_S&*?$1b|M*zeY4Nk8tX5_vm95vrE?KE{6{Sb1vSf|< z<)Dc4?u~dy5}Tms5PF%6BYlJp8Pski3f&cLpli0WWt#6Q8^@B$J$z2JZ~%SDR5OZ_ zJeD$wzBK;*aHB5z8~v=`8Hhs@;vboyrZF)`R{= zQSo#RM!K`!KNe(07g6N7^M+04tii-z(c)Y%vu&&DBPxz2!;v+aJGiOrK3N4adnKl9hTMevIm*; z_L3y%6|qS6Z@suO4i;Ze*3ds;iN4OQBIR*;9Q1adWis2z@~l3-wV!dGmO-zqWX|{M|Kw+J)^pmb5Hes@ z=eI& zRqUQ(T(P@~CBp_8;!bvJ=;Zwy*Mp&(<^5}$!J4C-L7n9?Z01$WqvN>9l}#Hc3(sC$ z#@2JCYd=5?;i(^>u4sYjUBx>)gDmHdfyfU)46AFuXSZ3Kb>A)aurt@Vo|DjXoPQlO zJQS_$JMfk@BE|`xD3r$Zqonw1er~QB7vR~&Z5RU-{{K-#68E5?SMW5Cr4?~H-{ki1 z*;t#*K@+Q+kw0Shj9>o+F^P?!sIfh=xr^FCjR-S#xi_A#NG7&84afY6Irg~E{Syz| zh#(W3c-#b6>!gj5_NsBxnUG`Yj+{|r)SNhDAH5~<26UNsz-1hq8F{0|1TJUXDsA2! zxA>BtjonB7s5P<1ZA8wMQG3Fe@mY=bS)9ei{7g z$=2oJ%AJG<@S-0DmtTstq$q7vsol$#!9vXOV literal 0 HcmV?d00001 diff --git a/riscof-plugins/rv64/spike_simple/__pycache__/riscof_spike.cpython-310.pyc b/riscof-plugins/rv64/spike_simple/__pycache__/riscof_spike.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8895634b1d11fcb2a6808237d6f3d7ea1a85b0a1 GIT binary patch literal 3360 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 literal 0 HcmV?d00001 diff --git a/riscof-plugins/rv64/spike_simple/__pycache__/riscof_spike.cpython-38.pyc b/riscof-plugins/rv64/spike_simple/__pycache__/riscof_spike.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..62174dc94d2feb29e54e0a35277e88cc10b2f3cf GIT binary patch literal 3197 zcmZuz&2Jn@74PbCDdwnwe7b1 zW45X%i6=84k)S<+IB?+TIW9-e%XJT&5r?{R%D;fv!0*+J?QBH1>hrxPwEsK~L+mUTrCvr^7BW_wZa!u<+o@rZA z3$0zWNVsL`*RipbrYS;qPx&Na0eFg&#i4H zY~j4}aR;*_?%;{mD+_nze#;tn&pT`hK5_Ov`4PDIs#V#- z72eFASh3%3DvwlGyCsBX`=aWod@83+fuzTxG?!<~Wwp-u^Rcr3=y*Ot<4WEfS^T z_zUabH#TU2~>O=?5tDt$UgWV$j4eg{`<}m~W5!bBQBWq@>fMkNP&sT@-Z%)r8!}f&*GH6R7v> zb9j>HtVPd34@GdAiQ$wmw!1n0jXCj)A5I6OYQL(VRRi3Au#=|Y05?l_Z@suY4UfNp zYG7-krDZL$;#Qf7q&f%(+fQ?qZ{4ksYJa^DCzSi)_>`f1V`?dUab+3~>hQ(YY53yW6bAF3)p9=;xs2Lsls6f5 z=cewYbveYAaaxKsEd$h*KJzl(mJb`;G1JuWiTv+UE9usEn8A);bYPj{*_NlD()Hd;Jrg#yUi}n88-7))c`3 z57Sw-@I)^NPJsYcvV}Ldp0OCh0X=ze{9=No_8igv5nKSa42~&cLFp_g-DAqH7nI(D z(m$sBc|loPP?nD=e_c>c%_%qw7c1md;FzEF@8UGhddBz^paDL0c2m2%F!trwcW_DF z$8#RmvdKjJyvQnTU%#g9t5>uwpK5krJNF-cs9CPrCz_R-eWcm8X7@A`n%&hb9k<90 zxAI$Kw-{c(7LL8V7+$>+uDRMBHF=?QyQmWpA0%a=x!J(M1DD^!)<-5cFWxYmym%T) z0>^jF?rx3pLOcXTk-u0@pTEbutjqfE7C!FG?QJAddWuJ14;>%HnEDQ)VgqD2#Pfv7 zn0b(dqW16XRqGrgxV#NlfVuxa6^P;Owaf~>;c<)^PULODf6u1IVfNZs-Hw9^yJ!9C zFTfr)ftjX!!i9&{MGGXEdcvO`tw;`bd>R4ynLYJIAc8|5+(3#MPCRXct8>`JOn22f z?9C{s^e675HEGY>X@Jp^e1m#f^uT59otpTQ)(qih+NrqcPdj4CNMrX&FzL*kX%`5& zGU?73vp#FkKMg5|Mzq!+nY!7W5zB;=#;Hzij)RR)lKqTA$olL5;v2V*$4Cjf<%0MC zk$xP|C>-pEgFW3gFWdkCz520N9;_q8je~WS?^H=MlG)e^2lupBCaJ8Iyg^*o!@&TK zWTM{>ju~$uPKGDL!H!I-QISZBdeM9>={BvDFZ-0 zNORg_J~oFkngq(p1I>wPPNI0L9cVQ2p{JM(6!niH?_8zYK?IIGl>;?|ZY_3x_v!ga z0v=&mRpB)1`=~4@WEbp9yvuzDKWgrN;I8lsu4kXOIgqmJgT{_<@@N61ZAc&J%t#-C zI0jUW00Xh^#_?yPq*zdZ=LW<;=)^I!t&qjUu|a2f3ENAG{PI&&y0^goG%E_QoPfo* ziG>iuBs`=@MOyb6cevfXjl~i7U|qFK!Al2fv^A7eLW zNNsoE0kCXcg115Dvm+_KAhS78x=V;%Z?Bv9H}{a`#T4=}05tLt-9GL{XBWh8Ce4zt zNw<+(eT*HEaCx*d9EULKt^1jq8btJO&h>bk9N0uhle19XviQ5mStwR^ZQuSMH|t0M literal 0 HcmV?d00001 diff --git a/riscof-plugins/rv64/spike_simple/__pycache__/riscof_spike_simple.cpython-310.pyc b/riscof-plugins/rv64/spike_simple/__pycache__/riscof_spike_simple.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..12489fb7dc036babfe670bb7513117c867fc2aff GIT binary patch literal 3455 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 KL2zm5j{ZONVxs{7 literal 0 HcmV?d00001 diff --git a/riscof-plugins/rv64/spike_simple/env/link.ld b/riscof-plugins/rv64/spike_simple/env/link.ld new file mode 100644 index 000000000..eddbdcc14 --- /dev/null +++ b/riscof-plugins/rv64/spike_simple/env/link.ld @@ -0,0 +1,18 @@ +OUTPUT_ARCH( "riscv" ) +ENTRY(rvtest_entry_point) + +SECTIONS +{ + . = 0x80000000000000; + .text.init : { *(.text.init) } + . = ALIGN(0x1000); + .tohost : { *(.tohost) } + . = ALIGN(0x1000); + .text : { *(.text) } + . = ALIGN(0x1000); + .data : { *(.data) } + .data.string : { *(.data.string)} + .bss : { *(.bss) } + _end = .; +} + diff --git a/riscof-plugins/rv64/spike_simple/env/model_test.h b/riscof-plugins/rv64/spike_simple/env/model_test.h new file mode 100644 index 000000000..d10c9cd73 --- /dev/null +++ b/riscof-plugins/rv64/spike_simple/env/model_test.h @@ -0,0 +1,60 @@ +#ifndef _COMPLIANCE_MODEL_H +#define _COMPLIANCE_MODEL_H +#define RVMODEL_DATA_SECTION \ + .pushsection .tohost,"aw",@progbits; \ + .align 8; .global tohost; tohost: .dword 0; \ + .align 8; .global fromhost; fromhost: .dword 0; \ + .popsection; \ + .align 8; .global begin_regstate; begin_regstate: \ + .word 128; \ + .align 8; .global end_regstate; end_regstate: \ + .word 4; + +//RV_COMPLIANCE_HALT +#define RVMODEL_HALT ;\ +li x1, 1 ;\ +1: ;\ + sw x1, tohost, t2 ;\ + j 1b ;\ + +#define RVMODEL_BOOT + +//RV_COMPLIANCE_DATA_BEGIN +#define RVMODEL_DATA_BEGIN \ + RVMODEL_DATA_SECTION \ + .align 4;\ + .global begin_signature; begin_signature: + +//RV_COMPLIANCE_DATA_END +#define RVMODEL_DATA_END \ + .align 4;\ + .global end_signature; end_signature: + +//RVTEST_IO_INIT +#define RVMODEL_IO_INIT +//RVTEST_IO_WRITE_STR +#define RVMODEL_IO_WRITE_STR(_R, _STR) +//RVTEST_IO_CHECK +#define RVMODEL_IO_CHECK() +//RVTEST_IO_ASSERT_GPR_EQ +#define RVMODEL_IO_ASSERT_GPR_EQ(_S, _R, _I) +//RVTEST_IO_ASSERT_SFPR_EQ +#define RVMODEL_IO_ASSERT_SFPR_EQ(_F, _R, _I) +//RVTEST_IO_ASSERT_DFPR_EQ +#define RVMODEL_IO_ASSERT_DFPR_EQ(_D, _R, _I) + +#define RVMODEL_SET_MSW_INT \ + li t1, 1; \ + li t2, 0x2000000; \ + sw t1, 0(t2); + +#define RVMODEL_CLEAR_MSW_INT \ + li t2, 0x2000000; \ + sw x0, 0(t2); + +#define RVMODEL_CLEAR_MTIMER_INT + +#define RVMODEL_CLEAR_MEXT_INT + + +#endif // _COMPLIANCE_MODEL_H diff --git a/riscof-plugins/rv64/spike_simple/env/sign_fix.sh b/riscof-plugins/rv64/spike_simple/env/sign_fix.sh new file mode 100755 index 000000000..7542178eb --- /dev/null +++ b/riscof-plugins/rv64/spike_simple/env/sign_fix.sh @@ -0,0 +1,3 @@ +#!/bin/sh +cat sign | sed 's/.\{8\}/& /g' | awk '{print $4 " " $3 " " $2 " " $1}' | sed 's/ /\n/g' > temp; mv \ +temp sign; exit 0 diff --git a/riscof-plugins/rv64/spike_simple/riscof_spike_simple.py b/riscof-plugins/rv64/spike_simple/riscof_spike_simple.py new file mode 100644 index 000000000..e347a2ca2 --- /dev/null +++ b/riscof-plugins/rv64/spike_simple/riscof_spike_simple.py @@ -0,0 +1,254 @@ +import os +import re +import shutil +import subprocess +import shlex +import logging +import random +import string +from string import Template +import sys + +import riscof.utils as utils +import riscof.constants as constants +from riscof.pluginTemplate import pluginTemplate + +logger = logging.getLogger() + +class spike_simple(pluginTemplate): + __model__ = "spike" + + #TODO: please update the below to indicate family, version, etc of your DUT. + __version__ = "XXX" + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + config = kwargs.get('config') + + # If the config node for this DUT is missing or empty. Raise an error. At minimum we need + # the paths to the ispec and pspec files + if config is None: + print("Please enter input file paths in configuration.") + raise SystemExit(1) + + # In case of an RTL based DUT, this would be point to the final binary executable of your + # test-bench produced by a simulator (like verilator, vcs, incisive, etc). In case of an iss or + # emulator, this variable could point to where the iss binary is located. If 'PATH variable + # is missing in the config.ini we can hardcode the alternate here. + self.dut_exe = os.path.join(config['PATH'] if 'PATH' in config else "","spike") + + # Number of parallel jobs that can be spawned off by RISCOF + # for various actions performed in later functions, specifically to run the tests in + # parallel on the DUT executable. Can also be used in the build function if required. + self.num_jobs = str(config['jobs'] if 'jobs' in config else 1) + + # Path to the directory where this python file is located. Collect it from the config.ini + self.pluginpath=os.path.abspath(config['pluginpath']) + + # Collect the paths to the riscv-config absed ISA and platform yaml files. One can choose + # to hardcode these here itself instead of picking it from the config.ini file. + self.isa_spec = os.path.abspath(config['ispec']) + self.platform_spec = os.path.abspath(config['pspec']) + + #We capture if the user would like the run the tests on the target or + #not. If you are interested in just compiling the tests and not running + #them on the target, then following variable should be set to False + if 'target_run' in config and config['target_run']=='0': + self.target_run = False + else: + self.target_run = True + + def initialise(self, suite, work_dir, archtest_env): + + # capture the working directory. Any artifacts that the DUT creates should be placed in this + # directory. Other artifacts from the framework and the Reference plugin will also be placed + # here itself. + self.work_dir = work_dir + + # capture the architectural test-suite directory. + self.suite_dir = suite + + # Note the march is not hardwired here, because it will change for each + # test. Similarly the output elf name and compile macros will be assigned later in the + # runTests function + self.compile_cmd = 'riscv{1}-unknown-elf-gcc -march={0} \ + -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles -g\ + -T '+self.pluginpath+'/env/link.ld\ + -I '+self.pluginpath+'/env/\ + -I ' + archtest_env + ' {2} -o {3} {4}' + + # add more utility snippets here + + def build(self, isa_yaml, platform_yaml): + + # load the isa yaml as a dictionary in python. + ispec = utils.load_yaml(isa_yaml)['hart0'] + + # capture the XLEN value by picking the max value in 'supported_xlen' field of isa yaml. This + # will be useful in setting integer value in the compiler string (if not already hardcoded); + self.xlen = ('64' if 64 in ispec['supported_xlen'] else '32') + + # for spike start building the '--isa' argument. the self.isa is dutnmae specific and may not be + # useful for all DUTs + self.isa = 'rv' + self.xlen + if "I" in ispec["ISA"]: + self.isa += 'i' + if "M" in ispec["ISA"]: + self.isa += 'm' + if "A" in ispec["ISA"]: + self.isa += 'a' + if "F" in ispec["ISA"]: + self.isa += 'f' + if "D" in ispec["ISA"]: + self.isa += 'd' + if "C" in ispec["ISA"]: + self.isa += 'c' + + #TODO: The following assumes you are using the riscv-gcc toolchain. If + # not please change appropriately + self.compile_cmd = self.compile_cmd+' -mabi='+('lp64 ' if 64 in ispec['supported_xlen'] else 'ilp32 ') + + def runTests(self, testList): + + # Delete Makefile if it already exists. + if os.path.exists(self.work_dir+ "/Makefile." + self.name[:-1]): + os.remove(self.work_dir+ "/Makefile." + self.name[:-1]) + # create an instance the makeUtil class that we will use to create targets. + make = utils.makeUtil(makefilePath=os.path.join(self.work_dir, "Makefile." + self.name[:-1])) + + # set the make command that will be used. The num_jobs parameter was set in the __init__ + # function earlier + make.makeCommand = 'make -k -j' + self.num_jobs + + # we will iterate over each entry in the testList. Each entry node will be refered to by the + # variable testname. + for testname in testList: + + # for each testname we get all its fields (as described by the testList format) + testentry = testList[testname] + + # we capture the path to the assembly file of this test + test = testentry['test_path'] + + # capture the directory where the artifacts of this test will be dumped/created. RISCOF is + # going to look into this directory for the signature files + test_dir = testentry['work_dir'] + + # name of the elf file after compilation of the test + elf = 'my.elf' + + # name of the signature file as per requirement of RISCOF. RISCOF expects the signature to + # be named as DUT-.signature. The below variable creates an absolute path of + # signature file. + sig_file = os.path.join(test_dir, self.name[:-1] + ".signature") + log_file = os.path.join(test_dir, self.name[:-1] + ".log") + + # for each test there are specific compile macros that need to be enabled. The macros in + # the testList node only contain the macros/values. For the gcc toolchain we need to + # prefix with "-D". The following does precisely that. + compile_macros= ' -D' + " -D".join(testentry['macros']) + + # substitute all variables in the compile command that we created in the initialize + # function + cmd = self.compile_cmd.format(testentry['isa'].lower(), self.xlen, test, elf, compile_macros) + + # if the user wants to disable running the tests and only compile the tests, then + # the "else" clause is executed below assigning the sim command to simple no action + # echo statement. + if self.target_run: + # set up the simulation command. Template is for spike. Please change. + simcmd = self.dut_exe + ' -m8796093022208 --isa={0} +signature={1} +signature-granularity=8 {2}'.format(self.isa, sig_file, elf) + simcmd = simcmd + ';' + self.dut_exe + ' -m8796093022208 --isa={0} --log-commits -l my.elf 2> {1}'.format(self.isa, log_file) + else: + simcmd = 'echo "NO RUN"' + + # concatenate all commands that need to be executed within a make-target. + execute = '@cd {0}; {1}; {2};'.format(testentry['work_dir'], cmd, simcmd) + + # create a target. The makeutil will create a target with the name "TARGET" where num + # starts from 0 and increments automatically for each new target that is added + make.add_target(execute) + + # if you would like to exit the framework once the makefile generation is complete uncomment the + # following line. Note this will prevent any signature checking or report generation. + #raise SystemExit + + # once the make-targets are done and the makefile has been created, run all the targets in + # parallel using the make command set above. + make.execute_all(self.work_dir) + + # if target runs are not required then we simply exit as this point after running all + # the makefile targets. + if not self.target_run: + raise SystemExit(0) + +#The following is an alternate template that can be used instead of the above. +#The following template only uses shell commands to compile and run the tests. + +# def runTests(self, testList): +# +# # we will iterate over each entry in the testList. Each entry node will be referred to by the +# # variable testname. +# for testname in testList: +# +# logger.debug('Running Test: {0} on DUT'.format(testname)) +# # for each testname we get all its fields (as described by the testList format) +# testentry = testList[testname] +# +# # we capture the path to the assembly file of this test +# test = testentry['test_path'] +# +# # capture the directory where the artifacts of this test will be dumped/created. +# test_dir = testentry['work_dir'] +# +# # name of the elf file after compilation of the test +# elf = 'my.elf' +# +# # name of the signature file as per requirement of RISCOF. RISCOF expects the signature to +# # be named as DUT-.signature. The below variable creates an absolute path of +# # signature file. +# sig_file = os.path.join(test_dir, self.name[:-1] + ".signature") +# +# # for each test there are specific compile macros that need to be enabled. The macros in +# # the testList node only contain the macros/values. For the gcc toolchain we need to +# # prefix with "-D". The following does precisely that. +# compile_macros= ' -D' + " -D".join(testentry['macros']) +# +# # collect the march string required for the compiler +# marchstr = testentry['isa'].lower() +# +# # substitute all variables in the compile command that we created in the initialize +# # function +# cmd = self.compile_cmd.format(marchstr, self.xlen, test, elf, compile_macros) +# +# # just a simple logger statement that shows up on the terminal +# logger.debug('Compiling test: ' + test) +# +# # the following command spawns a process to run the compile command. Note here, we are +# # changing the directory for this command to that pointed by test_dir. If you would like +# # the artifacts to be dumped else where change the test_dir variable to the path of your +# # choice. +# utils.shellCommand(cmd).run(cwd=test_dir) +# +# # for debug purposes if you would like stop the DUT plugin after compilation, you can +# # comment out the lines below and raise a SystemExit +# +# if self.target_run: +# # build the command for running the elf on the DUT. In this case we use spike and indicate +# # the isa arg that we parsed in the build stage, elf filename and signature filename. +# # Template is for spike. Please change for your DUT +# execute = self.dut_exe + ' --isa={0} +signature={1} +signature-granularity=4 {2}'.format(self.isa, sig_file, elf) +# logger.debug('Executing on Spike ' + execute) +# +# # launch the execute command. Change the test_dir if required. +# utils.shellCommand(execute).run(cwd=test_dir) +# +# # post-processing steps can be added here in the template below +# #postprocess = 'mv {0} temp.sig'.format(sig_file)' +# #utils.shellCommand(postprocess).run(cwd=test_dir) +# +# # if target runs are not required then we simply exit as this point after running all +# # the makefile targets. +# if not self.target_run: +# raise SystemExit diff --git a/riscof-plugins/rv64/spike_simple/spike_simple_isa.yaml b/riscof-plugins/rv64/spike_simple/spike_simple_isa.yaml new file mode 100755 index 000000000..a8032e4cd --- /dev/null +++ b/riscof-plugins/rv64/spike_simple/spike_simple_isa.yaml @@ -0,0 +1,29 @@ +hart_ids: [0] +hart0: + ISA: RV64IMACZicsr_Zifencei + physical_addr_sz: 56 + User_Spec_Version: '2.3' + supported_xlen: [64] + misa: + reset-val: 0x8000000000001105 + rv64: + accessible: true + mxl: + implemented: true + type: + warl: + dependency_fields: [] + legal: + - mxl[1:0] in [0x2] + wr_illegal: + - Unchanged + extensions: + implemented: true + type: + warl: + dependency_fields: [] + legal: + - extensions[25:0] bitmask [0x0001105, 0x0000000] + wr_illegal: + - Unchanged + diff --git a/riscof-plugins/rv64/spike_simple/spike_simple_platform.yaml b/riscof-plugins/rv64/spike_simple/spike_simple_platform.yaml new file mode 100644 index 000000000..8e1a3d8e3 --- /dev/null +++ b/riscof-plugins/rv64/spike_simple/spike_simple_platform.yaml @@ -0,0 +1,10 @@ +mtime: + implemented: true + address: 0xbff8 +mtimecmp: + implemented: true + address: 0x4000 +nmi: + label: nmi_vector +reset: + label: reset_vector diff --git a/riscv-ctg/.gitignore b/riscv-ctg/.gitignore new file mode 100644 index 000000000..20a5d918f --- /dev/null +++ b/riscv-ctg/.gitignore @@ -0,0 +1,107 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# dotenv +.env + +# virtualenv +.venv +venv/ +ENV/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ + +# IDE settings +.vscode/ + +work/* diff --git a/riscv-ctg/CHANGELOG.md b/riscv-ctg/CHANGELOG.md new file mode 100644 index 000000000..0371043af --- /dev/null +++ b/riscv-ctg/CHANGELOG.md @@ -0,0 +1,206 @@ +# CHANGELOG + +This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + + +Please note the header `WIP-DEV` is to always remain indicating the changes done on the dev branch. +Only when a release to the main branch is done, the contents of the WIP-DEV are put under a +versioned header while the `WIP-DEV` is left empty + +## [0.12.2] - 2024-03-06 +- Add Zfa support. (PR#60) +- Initial covergroups for Zvk* instructions (PR#61) + +## [0.12.1] - 2024-02-27 +- Fix test.yml + +## [0.12.0] - 2024-02-22 +- Update generator.py to take care of hard coded register testcases only if a hard coded register is assigned in the op_comb node of a coverpoint of an instruction. +- Add hardcoded register testcases to dataset.cgf and rv32im.cgf +- Define rs1_val_data for c.ldsp in imc.yaml +- Update "opcode" to "mnemonics" in the cgf files +- Delete main.yml +- Update test.yml for CI +- Define rs1_val_data for instructions from zicfiss.cgf in template.yaml +- Add "warning" in the verbose definition +- Add unratified Zicfiss extension +- Add unratified Zicfilp extension +- Add corner case of division for division operations for RV64 +- Fix csr_comb to write test information +- Add unratified Zaamo subcomponent of A extension +- Add unratified B extension +- Fix issues with csr_comb +- Minor fix in kslraw.u in rv32ip +- Fix incorrect 'sig:' entry in aes32dsi in template.yaml +- Add sig and sz for instructions in template.yaml +- Minor change of rd definition in c.lui in rv32ec +- Minor fix in rv32i_k +- Add rs1_val_data, rs2_val_data, imm_val_data for instructions in template.yaml +- Comment xlenlim out of val_comb in rv32i_b, rv64i_b +- Fix the formats of leading_ones, leading_zeros, trailing_ones, trailing_zeros for instructions in rv32i_b, rv32e_b +- Add op_comb for instructions in rv32i_zcb +- Add rs1_val_data for instructions in imc.yaml +- Add op_comb and val_comb for instructions in rv32ic, rv64ic, rv32ec +- Add corner case of division for division operations for RV32 +- Comment print statements out from generator.py +- Fix whitespaces on empty lines in yaml template files. +- Add unratified Zabha extension +- Add support for unratified Zcmop extension +- Add support for unratified Zimop extension +- Add missing coverage for hard coded register testcases +- Updated CONTRIBUTING.rst to capture the new git strategy adopted to follow a monthly release cadence. +- Add Zifencei, Bit Manipulation and Privilege tests cgf files for RV32E +- Add unratified Zacas extension +- Add support for standard Atomic(A) extension + +## [0.11.1] - 2023-08-15 +- Fixed hex values handling for K extensions +- Fixed set indexing error during opcomb gen +- Fixed whitespaces on empty lines in yaml template files. + +## [0.11.0] - 2022-12-11 +- Added support for csr_comb test generation + +## [0.10.4] - 2023-03-28 +- Adding Zicond support + +## [0.10.3] - 2022-11-22 +- Fixed canary definition + +## [0.10.2] - 2022-10-20 +- Fixed use of lowercase LI. +- Fixed correctval to ?? in comments. +- Fixed sw to SREG for K tests. +- Added canaries and signature boundary labels. + +## [0.10.1] - 2022-09-30 +- Added support for evaluating derived fields for evaluating coverpoints using the instruction object class + +## [0.10.0] - 2022-09-05 +- Added support for bitmanip and crypto scalar coverpoint test generation + +## [0.9.0] - 2022-08-25 +- Added support for cross_comb coverpoint test generation + +## [0.8.0] - 2022-08-08 +- Added support for a distributed template database. +- Added generic mechanisms to generate data sections based on test instances. +- Update templates for floating point tests. +- Fix test generation and macros for floating point tests. + +## [0.7.2] +- Fix errors related to global variables across processes. + +## [0.7.1] - 2022-02-07 +- Fixed mistune version for doc build. + +## [0.7.0] - 2022-02-05 +- Included support for pseudoinstructions + +## [0.6.3] - 2022-03-14 +- Read the vxsat.OV flag before updating signatures in TEST_PKRR_OP() macro +- Use RDOV() macro to read the vxsat.OV flag. + +## [0.6.2] - 2022-03-15 +- Added method to generate data patterns for bitmanip instructions. + +## [0.6.1] - 2022-03-04 +- Check the vxsat.OV flag for P-extension instructions that saturate their results. +- Correct test generation of P-extension instructions affected by the template.yaml ISA node change in 0.6.0. +- update SIGUPD macros to automatically adjust base and offset if offset gets too big + +## [0.6.0] - 2022-01-27 +- Add CGFs for B extensions. +- Modify ISA node in template.yaml to support multiple ISAs per instruction. + +## [0.5.9] - 2021-12-20 +- Add CGFs for P extensions +- Add support for P extension test generation + +## [0.5.8] - 2021-10-21 +- Updated and added bitmanip_real_world.py script to generate test with real world patterns. + +## [0.5.7] - 2021-09-20 +- Fix the generation of rv32ec/cswsp test + +## [0.5.6] - 2021-09-19 +- rvtest\_data section now includes 16 bytes of rotated versions of `0xbabecafe` + +## [0.5.5] - 2021-09-10 +- Add CGFs for F&D extensions +- Add support for F & D extension test generation +- Add support for test splitting based on number of macro instances +- Add macro based signature entry sizes + +## [0.5.4] - 2021-09-02 +- Updated logger to enable logging for API calls. + +## [0.5.3] - 2021-08-12 + +- Update instruction format of aes32 and sm4 instructions for K extensions. +- Improve the coverage of S-boxes for sm4 instructions by setting overlap = "Y" in byte_count. + +## [0.5.2] - 2021-08-09 +- Fix sign of immediate value for branching instructions while filtering. +- Fix instruction generation while result shadowing. + +## [0.5.1] - 2021-07-16 +- Update the sample cgf for RV32E +- fix the generation of RV32E Tests + +## [0.5.0] - 2021-05-27 +- support for K extension and subextension instructions +- support for comments in coverpoints +- added std_op field in template.yaml to indicate is standard-instruction the pseudo op belongs to. +- added support for parsing #nosat in coverpoint which disables the solvers for the current resolution. +- added sample cgf files for rv64ik and rv32ik + +## [0.4.5] - 2021-05-15 +- Minor code restructure to support API calls. +- Fixes to include env files in pip package. + +## [0.4.4] - 2021-02-23 +- Added missing coverpoints for JALR +- fixed CI to run main.yml on pushes to master. +- added version check for PRs in test.yml + +## [0.4.3] - 2021-02-23 +- Updated CI to actions + +## [0.4.2] - 2021-01-15 +- Fixed header base_isa argument +- Change header configuration argument list +- Remove first empty line in assembler output +- Add header randomization argument + +## [0.4.1] - 2020-12-13 +- Fixed correctval generation for existing ops. +- Fixed signedness of operand values for m ext instructions. +- Added operation strings for m and c extensions. + +## [0.4.0] - 2020-11-19 +- Added base_isa as option in cli +- Added support for register set based on base isa. +- Reformatted output values in tests to be hex strings. +- change compliance_model to model_test + +## [0.3.0] - 2020-11-18 +- minor doc updates +- renamed compliance_test.h to arch_test.h +- added aliasing macros for v0.1 compliance framework +- split datasets and coverpoints into multiple cgfs +- support for multiple cgf as inputs +- added support for special datasets to relevant instructions +- adding explicit entry point label to all tests +- remove x2 as coverpoint in cswsp and csdsp + +## [0.2.0] - 2020-11-10 +- initial draft of CTG +- parallelization support added +- random solvers can be used +- support rv32/64imc instructions +- docs updated + +## [0.1.0] - 2020-07025 +- initial draft + diff --git a/riscv-ctg/CONTRIBUTING.rst b/riscv-ctg/CONTRIBUTING.rst new file mode 100644 index 000000000..391e27116 --- /dev/null +++ b/riscv-ctg/CONTRIBUTING.rst @@ -0,0 +1,119 @@ +.. See LICENSE.incore for details + +.. highlight:: shell + +====================== +Developer Contribution +====================== + +Contributions are welcome, and they are greatly appreciated and credit will always be given. + +You can contribute in many ways: + +Types of Contributions +---------------------- + +Report Bugs +~~~~~~~~~~~ + +Report bugs at https://github.com/riscv-software-src/riscv-ctg/issues/. + +Submit Feedback +~~~~~~~~~~~~~~~ + +The best way to send feedback is to file an issue at https://github.com/riscv-software-src/riscv-ctg/issues/. + +If you are proposing a feature: + +* Explain in detail how it would work. +* Keep the scope as narrow as possible, to make it easier to implement. +* Remember that this is a volunteer-driven project, and that contributions + are welcome :) + +Git Strategy +------------ + +The repo adopts a simple git strategy where all contributions to the repo are made to the ``dev`` +branch (i.e. all Pull-Requests must use ``dev`` as the target branch). On a monthly cadence (decided +and controlled by the SIG-ARCH-TEST members) the ``dev`` branch will be merged to the ``main`` to by +the official maintainers of the repo. This will create an official release capturing all the +development over the month into a single release. + +To implement the above strategy successfully the following needs be followed: + +* Developers: All pull-requests from developers must target the ``dev`` branch and the PR must +contain an entry in the CHANGELOG.md file under `[WIP-DEV]` section. +* Maintainers: When a making a release the maintainers shall assign semantic version number by +updating the CHANGELOG and the respective python files before raising a PR from the `dev` to `main`. + +Get Started! +------------ + +Ready to contribute? Here's how to set up `riscv_ctg` for local development. + +1. Fork the `riscv_ctg` repo on GitHub. +2. Clone your fork locally and checkout the ``dev`` branch:: + + $ git clone https://github.com/riscv-software-src/riscv-ctg.git -b dev + +3. Create an issue and WIP merge request that creates a working branch for you:: + + $ git checkout -b name-of-your-bugfix-or-feature + + Now you can make your changes locally. + +4. When you're done making changes, check that your changes pass pytest + tests, including testing other Python versions with tox:: + + $ cd tests + $ pytest test_riscv_ctg.py -v + +5. Commit your changes and push your branch to GitLab:: + + $ git add . + $ git commit -m "Your detailed description of your changes." + $ git push origin name-of-your-bugfix-or-feature + +6. Submit a pull-request through the GitHub website. Make sure the pull-request is on the `dev` +branch of the origin repo. + +7. Do not forget to make an entry in the CHANGELOG.md file under the `[WIP-DEV]` section +highlighting the changes you have done. + +Merge Request Guidelines +------------------------ + +Before you submit a merge request, check that it meets these guidelines: + +1. The merge request should include tests (if any). +2. If the merge request adds functionality, the docs should be updated. +3. The target branch must always be the `dev` branch. + + +Versioning (only for maintainers) +--------------------------------- + +When issuing pull requests to the main branch (from dev), a version entry in the CHANGELOG.md is mandatory. The tool adheres to +the [`Semantic Versioning`](https://semver.org/spec/v2.0.0.html) scheme. Following guidelines must +be followed while assigning a new version number : + +- Patch-updates: all doc updates (like typos, more clarification,etc). +- Minor-updates: Fixing bugs in current features, adding new features which do not break current + features or working. Adding new extensions. +- Major-updates: Backward incompatible changes. + +Note: You can have either a patch or minor or major update. +Note: In case of a conflict, the maintainers will decide the final version to be assigned. + +To update the version of the python package for deployment you can use `bumpversion` (installed +using ``pip install bumpversion``):: + +$ bumpversion --no-tag --config-file setup.cfg patch # last arg can be: major or minor or patch + +If you don't have bumpversion installed you can manually update the version in the following files: + +- change the value of variable ``current_version`` in `./setup.cfg` +- change the value of variable ``__version__`` in `./riscv_ctg/__init__.py` + + + diff --git a/riscv-ctg/LICENSE.incore b/riscv-ctg/LICENSE.incore new file mode 100644 index 000000000..c1c837a28 --- /dev/null +++ b/riscv-ctg/LICENSE.incore @@ -0,0 +1,30 @@ +BSD 3-Clause License + +Copyright (c) 2020, InCore Semiconductors Pvt. Ltd. + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/riscv-ctg/MANIFEST.in b/riscv-ctg/MANIFEST.in new file mode 100644 index 000000000..25aeae64e --- /dev/null +++ b/riscv-ctg/MANIFEST.in @@ -0,0 +1,9 @@ +include LICENSE.incore +include README.rst +include riscv_ctg/requirements.txt +recursive-include riscv_ctg/data/ * +recursive-include riscv_ctg/env/ * + +recursive-exclude * __pycache__ +recursive-exclude * *.py[co] +recursive-exclude tests/ * diff --git a/riscv-ctg/README.rst b/riscv-ctg/README.rst new file mode 100644 index 000000000..43f12f3de --- /dev/null +++ b/riscv-ctg/README.rst @@ -0,0 +1,7 @@ +################################################# +**RISC-V Compliance Test Generator** : RISC-V CTG +################################################# + + +Latest documentation of riscv_ctg : `click here `_ + diff --git a/riscv-ctg/docs/Makefile b/riscv-ctg/docs/Makefile new file mode 100644 index 000000000..2da5341cd --- /dev/null +++ b/riscv-ctg/docs/Makefile @@ -0,0 +1,26 @@ +# See LICENSE.incore for details + +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SPHINXPROJ = riscv_ctg +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +clean: + @$(SPHINXBUILD) -M clean "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + diff --git a/riscv-ctg/docs/README.md b/riscv-ctg/docs/README.md new file mode 100644 index 000000000..50c16d0d6 --- /dev/null +++ b/riscv-ctg/docs/README.md @@ -0,0 +1,15 @@ +# Build the docs + +## For PDF +``` +pip install -r requirements.txt +make latexpdf +evince build/latex/*.pdf +``` + +## HTML +``` +pip install -r requirements.txt +make html +firefox build/html/index.html +``` diff --git a/riscv-ctg/docs/requirements.txt b/riscv-ctg/docs/requirements.txt new file mode 100644 index 000000000..56bbcfbe5 --- /dev/null +++ b/riscv-ctg/docs/requirements.txt @@ -0,0 +1,38 @@ +alabaster==0.7.12 +Babel==2.7.0 +Cerberus==1.3.1 +certifi==2019.6.16 +chardet==3.0.4 +doc8==0.8.0 +docutils==0.14 +gitdb2==2.0.5 +idna==2.8 +imagesize==1.1.0 +Jinja2==2.10.1 +MarkupSafe==1.1.1 +oyaml==0.9 +packaging==19.0 +pbr==5.3.1 +Pygments==2.4.2 +pyparsing==2.4.0 +python-dateutil==2.8.0 +pytz==2019.1 +PyYAML==5.1.1 +requests==2.22.0 +restructuredtext-lint==1.3.0 +ruamel.yaml==0.15.97 +six==1.12.0 +smmap2==2.0.5 +snowballstemmer==1.2.1 +Sphinx==3.0.4 +sphinx-rtd-theme==0.4.3 +sphinxcontrib-autoyaml==0.5.0 +sphinxcontrib-mermaid +sphinxcontrib-websupport==1.1.2 +sphinxcontrib-bibtex==1.0.0 +stevedore==1.30.1 +urllib3==1.25.3 +twine==1.13.0 +sphinx_tabs +m2r2==0.2.7 +mistune==0.8.4 diff --git a/riscv-ctg/docs/source/_static/custom.css b/riscv-ctg/docs/source/_static/custom.css new file mode 100644 index 000000000..784228836 --- /dev/null +++ b/riscv-ctg/docs/source/_static/custom.css @@ -0,0 +1,305 @@ +/* -- Extra CSS styles for Zephyr content (RTD theme) ----------------------- */ + +/* make the page width fill the window */ +.wy-nav-content { + max-width: none; +} + +/* pygments tweak for white-on-black console */ +/* hold off on this change for now + +.highlight-console .highlight { + background-color: black; +} +.highlight-console .highlight .go, .highlight-console .highlight .gp { + color: white; +} +.highlight-console .highlight .hll { + background-color: white; +} +.highlight-console .highlight .hll .go, .highlight-console .highlight .hll .gp { + color: black; + font-weight: bold; +} +*/ + +/* tweak doc version selection */ +.rst-versions { + position: static !important; +} + + +.rst-versions .rst-current-version { + padding: 5px; + background-color: #2980B9; + color: #80FF80; +} + +.rst-versions .rst-other-versions { + padding: 5px; +} + +div.rst-other-versions dl { + margin-bottom: 0; +} + +/* tweak spacing after a toctree, fixing issue from sphinx-tabs */ +.toctree-wrapper ul, ul.simple ol.simple { + margin-bottom: 24px !important; +} + +/* code block highlight color in rtd changed to lime green, no no no */ + +.rst-content tt.literal, .rst-content code.literal, .highlight { + background: #f0f0f0; +} +.rst-content tt.literal, .rst-content code.literal { + color: #000000; +} + +/* code literal links should be blue, and purple after visiting */ +a.internal code.literal { + color: #2980B9; +} +a.internal:visited code.literal { + color: #9B59B9; +} + +/* Make the version number more visible */ +.wy-side-nav-search>div.version { + color: rgba(255,255,255,1); +} + +/* squish the space between a paragraph before a list */ +div > p + ul, div > p + ol { + margin-top: -20px; +} + +/* squish space before an hlist in a list */ +li table.hlist { + margin-top: -10px; + margin-bottom: 5px; +} + +/* add some space before the figure caption */ +p.caption { +# border-top: 1px solid; + margin-top: 1em; +} + +/* decrease line leading a bit, 24px is too wide */ + +p { + line-height: 22px; +} + +/* add a colon after the figure/table number (before the caption) */ +span.caption-number::after { + content: ": "; +} + +p.extrafooter { + text-align: right; + margin-top: -36px; +} + +table.align-center { + display: table !important; +} + +/* put the table caption at the bottom, as done for figures */ +table { + caption-side: bottom; +} + +.code-block-caption { + color: #000; + font: italic 85%/1 arial,sans-serif; + padding: 1em 0; + text-align: center; +} + +/* make .. hlist:: tables fill the page */ +table.hlist { + width: 95% !important; + table-layout: fixed; +} + +/* override rtd theme white-space no-wrap in table heading and content */ +th,td { + white-space: normal !important; +} + +/* dbk tweak for doxygen-generated API headings (for RTD theme) */ +.rst-content dl.group>dt, .rst-content dl.group>dd>p { + display:none !important; +} +.rst-content dl.group { + margin: 0 0 12px 0px; +} +.rst-content dl.group>dd { + margin-left: 0 !important; +} +.rst-content p.breathe-sectiondef-title { + text-decoration: underline; /* dbk for API sub-headings */ + font-size: 1.25rem; + font-weight: bold; + margin-bottom: 12px; +} +.rst-content div.breathe-sectiondef { + padding-left: 0 !important; +} + +/* doxygenXX item color tweaks, light blue background with dark blue top border */ +.rst-content dl:not(.docutils) dl dt, dl:not(.docutils,.rst-other-versions) dt { + background: #e7f2fa !important; + border-top: none !important; + border-left: none !important; */ +} + + +/* tweak display of option tables to make first column wider */ +col.option { + width: 25%; +} + +/* tweak format for (:kbd:`F10`) */ +kbd +{ + -moz-border-radius:3px; + -moz-box-shadow:0 1px 0 rgba(0,0,0,0.2),0 0 0 2px #fff inset; + -webkit-border-radius:3px; + -webkit-box-shadow:0 1px 0 rgba(0,0,0,0.2),0 0 0 2px #fff inset; + background-color:#f7f7f7; + border:1px solid #ccc; + border-radius:3px; + box-shadow:0 1px 0 rgba(0,0,0,0.2),0 0 0 2px #fff inset; + color:#333; + display:inline-block; + font-family:Arial,Helvetica,sans-serif; + font-size:11px; + line-height:1.4; + margin:0 .1em; + padding:.1em .6em; + text-shadow:0 1px 0 #fff; +} + +/* home page grid display */ + +.grid { + list-style-type: none !important; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + margin: 1rem auto; + max-width: calc((250px + 2rem) * 4); +} + +.grid-item { + list-style-type: none !important; + -webkit-box-flex: 0; + -ms-flex: 0 0 auto; + flex: 0 0 auto; + width: 200px; + text-align: center; + margin: 1rem; +} + +.grid-item a { + display: block; + width: 200px; + height: 200px; + padding: 20px; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + border: 1px solid #c6cbce; + background-color: #1ab4e7; + color: white; +} + +.grid-item h2 { + font-size: 1.1rem; +} + +.grid-item img { + margin-bottom: 1.1rem; + max-width: 75%; +} + + +.grid-item a:hover { + background-color: #1892BA; + color: white; +} + + +.grid-item p { + margin-top: 0.5rem; + color: #333e48; +} + +.grid-icon { + line-height: 1.8; + font-size: 4rem; + color: white; +} + +/* add a class for multi-column support + * in docs to replace use of .hlist with + * a .. rst-class:: rst-columns + */ + +.rst-columns { + column-width: 18em; +} + +/* numbered "h2" steps */ + +body { + counter-reset: step-count; +} + +div.numbered-step h2::before { + counter-increment: step-count; + content: counter(step-count); + background: #cccccc; + border-radius: 0.8em; + -moz-border-radius: 0.8em; + -webkit-border-radius: 0.8em; + color: #ffffff; + display: inline-block; + font-weight: bold; + line-height: 1.6em; + margin-right: 5px; + text-align: center; + width: 1.6em; +} + +/* tweak bottom margin of a code block in a list */ + +.tab div[class^='highlight']:last-child { + margin-bottom: 1em; +} + +/* force table content font-size in responsive tables to be 100% + * fixing larger font size for paragraphs in the kconfig tables */ + +.wy-table-responsive td p { + font-size:100%; +} diff --git a/riscv-ctg/docs/source/_static/incore_logo.png b/riscv-ctg/docs/source/_static/incore_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..dfbf6c43d3117faa316124c8766a941f30154bb9 GIT binary patch literal 113714 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

i16B`ikF6i!01rvg@9+|ONa~t& zyC$jqE>4h}&Lg3u+R=#E8bRfePB?xb=JZWHUXSruIli8o73Nzp37s?Dv6k7aGwgRW zXyp3xp=Zl7^iE|LCk22BMGTM0`xn=8`1~WlQ@+}dQnf>63^D0JmBT(%lItupmP}zB zFl!sAm>>XH1zR$T41MVD_P{*V;LT9e8>fuRjUsE zT5W3C9vmYZL?A2xD3>r1HY{~`rrP)*!U!<+svr(2D1chMzcQF@Li{NL2%L{|^!g3U zL%B0nHzvmypXUSfsV`Tm@HX$Dn1^~AE3oY~vo}~^$C#9v^2m?sv1S~%(=B;-Ds;sJ zql*xYB%`dUKPa-3Vu^cgvD&fqgl|+bu4ehYXab`Y6Z&K=9gkPhbR5VRJ@#j0V1^?} zXhr-3kN$srPbd;(dL%xz$6ysaO9cI;C$uG;AQhQdr6@#>Svu|Vfz^J+8BU_2W10gu zc(wr0Z!N2%CQIQc@oVl&*4&njqo(NR zWVZfpBg=2qNp}@%rgqp`syF2FIck2i45`y7@_Uuh&9Lp;L8UQZYSI2*CX#e7pzdH6 zI?1}pDjlk7e%0dj{CqkA_G98|N-j7?R|aE+x0lK2fBcAW0+Efll9kNam>}r7#d}kI zWKIGZv+Mc4{?vb#qO+Wo-PblChtTyTC{pGa^o{CmFp>J84WNr1t9t@%(hdQ294H;3 zSrm}B+`p%H5v8YUXqo2OX|ku554s2^VEks|nk<_j&AnXKhwN|+UB!SuzzJ|Dlg8x2 zqS&aIM%`dU{?}gBXLy0 zvnIXOlJiG_IHT{km3js}7@y~E0JYx76YYf6vuZT_W#CUNkAVJ3D%yq}?N_4W`2o+u7bq~v1y6TX{4wsI{3urv%BS)}}!Prq#9C1n0A zn9r#Os9tpDXrNj!MDP8jj#~q`b!=b^`FCFtxFsm->&8@!$sFs^OY!wKYpK@KAqU8d zUYu)CZiXO_kAg|OasYea;fj{ushKbc1hlS$1eZOQ9Mq4k>W>8b*;|uB>-#A*oVD-^ zO6|GUFev{DoP2;`Ce%Q<4~CL7PY370W8aSSg3(mv?7B9V?BVMgV4TZImC@&Ji|*{e zCNV9ffsM`9qJY5hbGV+wB=>ec`C3^gj2{zoCX|pr2x)Oo?kDEKC2|<$<>QWjf|W>L zvdPko#x+6Vmf6HG5f?vMwb#UZl%Bm>7mS-&`qGC4sU9)0JDYl!b6M?({tevbF%Et8}Mx3sKU~U~`iTs`3)Z2mD3^9UG-DucOduBCO zyAm~!PBY<0Iie0r9fg8YSU@$T^-kpi4X`0$Pu{|SzQ`Tr#~F}L2-<6==&4n1S%EsN zhM{U-+>c|mi#9~7MF5)5R|8o?9~xn?sV+%?Wd%3MEFXX-%#VdI{7lGnBm35txlw|065F1tgO*+2|nTzwY1_gAm(`Uve|6LW(~U0!s)Yt>`2L?|Azj2d-mDXZ7;Px zYV5`8ge%RQNRev|F`r^C=FCg7*Kyxw)_q5Ey^xMY%RdmAm0Di`#R3 zR3w7Ms+cf`0dzxwP%aG?l5@aw*0r!>yuMM9g#;%$_$7xT2{=wXkjCF)=*Z&}lnKcY zNPrCIgEjcfiwhx`WVYp8OZcX|auPCUH5DKBYp*DnJZ7Ush>}3Ob*ZO$944fZLug=; zO2p;2oZSF+@VXBg3A;GU^~G;_NWS({vif1Fm4usS8#1fNa5V_Aw`9H~cVMR5sX_YFQ=gKhqIk`@z zi0Q7Je$Q-*!g0!9$-|+wB6zJszy@5FeV=61=bh(Ca zcKubhtYdd@uoKLhQ&-&JAsIBO;s?t`q1M^H=0yn zxe;a`)ulHX2TFfQ0YQ@QyfZ@>zsXY)@X>cKGD_OSj6-7$FBw6)P}Po^0Me$l^FssH4$EEx$3qz1D!&t*=KhdMvSK39@| zs4-0iiTe{*JXo}oxl!a}vY?eFv4^I&H?0pa;C$`RBPA;5Q}G~>=y>gEfXk@Q5hgQ) zEAFh`fNG)!q7fovjT6MlD!vu2KGp`N*C|Mh2=AK1uu`Jr1d zb3pYe;4$TP(GEdAWmkJwhpPzV`~^@THYMz~uO`-JU5qG)0*%0fT6t{awM1R_-WxRR zEt1H7#LrXuXx}&9;lC#&6q3I<2pObD@3b7!-tbQ?JQ$I&c@KSi%*w2HryqZ7iDh)oH$uA6xWYvWVi z=``=HeEjtT=XkQZ*u5V^BLG+iIZ-Q*u_P%434QL!653V~kZo6kwf~_l)_`IV%$V!c zXA2y3>sdA5nT9u>&`7OCSNPdmY)PuL3ywjpJjkV6aBldQDOf>SLkw(8uX%djljC7@ zX4J@tl!xTo8Jb98`o=AF-(|eMPybucScTa5mbm-8@&3%GT!vofG({8czb_;Yj z&j_|x6NRMvPw)R@J%Ya6PxTt-Z8yFQM|P0xTjOcJLd2BgG;M+=p1SJfXU%hM!QAjl z80qqydNITrKpNG--xES&+J#U<=}|**TqZen52%a87w8$V=mFx+i&+h-Ohj$}RDJpK z!Zp*nU|FYLP0M-AyPca2zahJXpD})a0l^A$V+$mNFX<{}3Vc&{s>7@lC6%sueEg5* z;@W#H%}D{H9 zz-V(15l{O|&lFaa?S0i$><7W0T-vbhX@`4Q<-CWnc)5p9fq{^25(Si{@uS{POAxv@ zA&k-hV10o;k@4Y=GI(HHJuBz8ciQ*Ww1rv70vT{#`qZE<$E@!zy=KN(C%>Xf48{3( zf#-&(O$fgqIB>{`@cbY3dv>>OcL2Hhc)x3PITqCpa^c*mupJaQ!oTQ9u`-5I`p#ehD^7%K zjptYUYU9*@Y`28+Xf%`Oi~_K#;1UlSzaD3mJUx8j&qAcoT!w(##S=D_8=BzP!#i41 zMIwyEOvwHi9VEz2td$`gKovTW;9pMTTHVR5VdL}l+c9E~Vf*yr>b0&Aezl4pTi(M$ z7*H?>s;LKK|H!pnk`0?;G$bT>a=)$>vgjD9$l)E?0S2}PJ_v;<_4BuHw@)1uVhUl5 zL;5or<>z}iu!CbnB76Ynj#!kt><-Y|m~rDmgYe7>f6k~Bq`!BYkGv9Opm830$PkaTjm@DH;SzLrn! zODamj_HCmFY}0^nNM?hpt9u8tF$Ee%$(+)N{EL(?vCS-$*y*aN%9#>48@&p|eYf0m zZ~YOX4aMJdM{2%b<$A7q)TAw~{Ildv2p>~jF(O})2sJ#~X8uyY7=8LY98zD!cKghbtNtD2bPsr<7345p3*k|s20w-nxMt8Px zq`yB^4H@c^o1imb@;Ht@I&y1c<)Th&4_o#Ms?1g#BVMbGAOlPQ`QHf)G1ap+ zKW0t^W<>TJKMLmNs0iRt_sQ7K-X>{uql1#Kpv>gNvcQesyTuomf+l|{gxFsM*Y{wi zYp!yU7t-SZP!wzcjx@_o7RWLdTtO3jcu5Q>)Y%3O`JTH?6u2F$wau1-&UKxMuQ_2%$fFSyK3MYm#V~l9ofvV?)-=X28D+H)b-+EpB;vKf2 zFyzJZA`z)+{cnqzz7-90mv8|QbdWxvRfqA9N06`b))O5&Fc2g0$`WGD6dFiWKW~-> z7(4SfYEQI4i?##f#(Bs%NDoSXKA{XK6s+28P3Qmu9pxdi#_=pb>LiAPj}VL2@@F#w ze=7;R83rl5&7{#CUtxxX<5nf%&Iw?ID`M3*@Qcj;>nrTzu^pgr4rZ=@-6?3C>3N=f zkX!}r92G^Gh558aIq|@DZvHopQpSqm_4hj*Xv|*5r;KMYhirE7Gs1Xyxg*tOyFeVD z5Fp8~Lv z6;GML&gBi6!X&BuR!Fv>KX}l+nb=$=zW($(fbBQ`lEA8K!dbSr z?_~9{o88YN5g6;`c=tIjR_putBy=NYjB6NuB3~Dg(gW zuQdCKpz26_x{oie@&X7hk6@(b`og)Fx8oI0FOr#NvGcQxj1%oPy{|x}2yrE3M9OA< z%2>q-)aB6LerXfJy`QTz2^R7juNrLfF|__LEG&vxB)bDGI%C9+?NAtT-7yedPn)Ite3{JD=0qs8Lzq6HU^(4P0nKLt zqQ3MV)cThq+MoZP-2QBt672e^O{)J&!92^#YXbVpr>Kz0jnE-|L=jmsYc)L$jFp8B)~k~V4rOqHy34p0TROU)=?Pc#EO ze{zW}vA5ZJf?&5tU#AyXS2r0>Uf~FKk1>8k4uihk+eT@8ummcK$EDcHq{lp#y(JEq zQ9+)_R#5>+|9s0h^dboNCdY{=lVwE_^y@BJ20}{+KvTJ?56G2d{dNr*#k;+b#h;*U zw{iUA)E*Sx&Qo|ILCoF|s-B*PoWgV=A1BTbn%k~kceB9S^6T{pa<8UdCqnG7w>>C| zeA9~6?$nJ)K|~tdJOBD>V9jT=y?Sg_8n~yAgro+oP}|-e0cBFVuw5nSY22;{6Qugg zQs+jcNr(m^OGCpad_1p!2t9;Ak#u}I+zY0PqvqJ>WtbcW4F2X0h_CzAqeZ5WTt{OM zI;0)*+2ziN(Rfh$pwjT;!ZYT#s4SJaYLp&sB}iG4Im%6vF>H*yGm#UqCGskj*X}j( zWeSskE@UC%a?wIcecE0glwzcnyzcCspR+&r(ePj2l*3*`d+Zdw|ArnQ;YDRzZA?75Imnuf~^B*bs7RY-~l&!?OQP}*m zGrT)L1#^{Xv8k@?{ZQ#7U~?mkN~Ch-VF*?-C2&Cs8=Z$bhM(liQ>C@5Sw>Z z#~8MJaXQW#NE^<5c))vr9c4r^0Lvms-mW3YbaSG_#z~Pm@_+3I7$BsXPNt7~gb;9~ zkq>ec<|{bAEvGYdA0eA{;{ya7A9aMJpHx+x^jN~7>;k2lIwIt(ShO5h->_ux=;Z1pa7-~Ayw|p zZFbROg^Va=iOr;=+LwaB4C%@OOmvKs1K zHyo+@DJdx$odTYoK{E&`2`ifVP!vSioT3~3P$fvAo6NuCB23fo=z@>OKFOK#93&13 zk;o^nUp`I{tF>9Lf%L}hlf7`iPky1tgF=1EPlB1@UND-JCEml|H@ED27`K^5jF(Gg zTy|u?^$;>4n7_)XcONxYxu=NPv|l-2dNv%=mV8m6+0u*Q*2Sa|ym<7rmwP|>9#<;w zT4VpiGs>jcgdxkbCY~l!E2}UTQ>R23V2DxHOSy*yp+^KU{j(rK^*Lm@m});&!UIdd zMGu%vVqM*2g4%{fP)$#dFz3-1?YQr&f|>$?y27`t-Z!c5aJMq%T=)eC)q=+?iJH&5 zlCTS!f6`2NEZ&lJ0;w=i3jOBMOG{r;<&N^0l-;FKdX(Y;Pb2l}>DPkiAT!mJE^&aL zKUp@;!@S#)q5Bw&IhonDbN@CtFwGBbdpNh4d%@%8Q~Rd--sd`h^+c!-R@mRw+cA;k z#<@9y_k08hV0wu4T1j_%Ce_axy$2KiZb43eLz{v~MELK4TeoL!xIk2vJy~h~l0}$s zH@C~(n&twv9<#7cEoQJ_E2JF@k~Mt$MZ9}aI9IVU|5f78){v64RWpcA{aTQf35831 zXtnWG1jw-OBR%!2ELBZX0>@>HJ7Xk*qLxoc3BJ&x1`+~0`Y+6Bz8>Or!U5D;tSczt zOZ$><-p?K@%G3)S)HUG}7vik?9`mhyw5Wgz;4kSh;h|$>-}-1`K8RE`3GL2K^Ri|- z3XyY?rhnNR>Uf#xNT&MhTlG)UVA z2Y3ip=^0fYU*AG;U{JlW+t2RLXoJWfJ7_?AwjVbUpx}~gcowG%0S16idclv~qz_i8 zJcq{}*U~>YV-|A+1nIEjdSa{&IGv<^Wv{Em#7JU7rz`t_c@+TXaTe`VY|^%A$W#}C z#+J|5hz99FL-51*4$4UpoJh8+1v3aq>gWEY1rZr^HDhX!g!u{1o&9(7C?WmZI9zGyI>`F#5JHCBzXa5X-po zh74&4RY3>4tlUMKZQ`9To@<;Wb!=oqwVC-EjD>ZSI8ph&COFj_NpRjf|JaKKA&z{v@V`s+R@%7343Xu$^s{$t2|#@tq4s^ETCP=K278?Spi9dP=W8 z{q5ocMe6YPEf%Pdb|)Rxmph=`{h)@GR+K7=k!BR$jJ5dEYm;?R`utq^G20c>$tZ*F zz8_8X;xh^##`Kw7s=`blp_LkL@;;~!{MUT@dg#jI&sH_)D2aq)MN@Hhynf)jft(rG zl@C|{m-j@P)Xe*8(!XwExLf63J_Q`wjw^~oCsMsEG}LdK*H%O771O#NgE`^2I7^8K%(MxlRBZGtUa zFnod|35;(T%b-9e0V_Oxoi^qQA3aZ9e${?4{UIQ2XX4EV*TJVxBwRHZ=?F)4M2&_J z^!u+(i1lI5moIl;7YljFfye+2k5;RtqT4_xZ_;*}vj;1+Bl1XQFcRYx>B22e<2IuO ze3BZ%EWiplb?KpfKF>Ome0|Qp(91cIbaPXhjR)0{_wU^sPKOCN67U-OO?0;u<&_fC z1h8lpJN1h;XOu1yw@N0|`B-1?X@$-$P@4F%iwg;n1eo6OUnjcyfco6`>B9e2;u=Qx zM(RblB-)pkeMliV*PqI$0NCwS4LeaUQI`t3GdQTT?1 z(OgTQz<(wo{A@&UYyGT~D%p$v{Lp+M8>)bAw3x3cDGaA3wu1r&wq-1339dt#fL`Vc zKadcyQ8e10igcAUO8{z2jS?%|Mvn?FMWH$B%YzFZCRpN74~ZtCd-mEID(E}Gwt+ikdK9}nAnvQJK*9{hS)c<7#{FZVF!s(ZE6|Zi<7kz1R`?4kHkeCV zS+zgy@fr*&(Fh)^FwVHGQ3tzo^e0RI4l?nogL#}eQh$N`DSrKShw?R8q2u@}T|nB8 zQHf8&b_N1sG>O@mwc$KX=_x0LTFr>+J?dnr*+g6uIFc~h{pC;$rViQ6x!f7j1S}{Cfk#oVoLMz(Dr@w zoP&%MF^&W|##dJzFf^nf7M|lC{g|JZIb{oUcL%yJmMSW92Xu6F32ej(S54NBR^Hwf zXQaz!u%9qfbkal`B+!yjtPQ;x0C;CKYdl2Z9g_L>Fq#0mQ31guKm^WKMob7r5BlaQ zp%}`^I7vy1(*!y6MK#3{CnpniI_g5cL0nD+lHSM%qCH)UZ1znjlHow+v!W$Yi=~Ma z`Et1-#8LaPKXr?zWojn!KQqQ`kw#J76o1jo2l0;Ubc^lSO$=D(JSp21Q4ph<#@;A7 zT;%9{Zt=;g9&*5f2s`*&oDB5`0V)^jr@%Xe=pdwjuD?Wa!1p={(ze-NoWr7Hljd$C z8H4-kzi~rYET7^Au)9sl*_hK}#@0eS=`!zUYoZiYjhVu%tz+I&_W9$=o}RoZMEe7=nGs4#8O5g385NDdb>!Xa?#KjdpQwpvea zEmvP#d9Vhq7gTZRVtMfHD;L82_67}>>wAhPZkM-b#I&$%FIeBlapg@^s;A`UZlr6p zz8Br(Au*JN19Bj@`dl_mBr?6ptObSQV%siw_RVwNh$G{y+mb`uetaP{(l|L2{|~!_ zA*QJGvY;6)81!b|b4Wa^Q2I8x2;AZBg`4}jC?zy!+LVIx5p9C=H3Js`W69;-t`udX zOw!$`Cm3818L%yI@HZ>+{^w2M8sqm!DU7Ge;=^!3@T>ZK)9dMW5-7esR|nReIEpaa zz;6lMFkmAD^aQiz-A!@^TZgc++ln*HTbFqlXo>M)d0Z;yq?ok!fiX-gqPuWncu-)` zl2R~4Fuo;N@Io9<=T*-lm!0abSdjHR~~ zO{-Ryc(Tmf6}Hbmtnt8oXP&oXUXJQFmL#We43MWv^rg;cB?^5gCiSIjc;;8egAI-apY( zaL1tW$I|_}RT4jgQO1e>XyA8_i_nDrCey^UA5Smhwo+Q(-u?DwARd9CewKB+PxrK` z%XO<)W+QdpP7cWsal51O1gWm8d-R}*ZNtRCEL@qUL`Xw7lGt~Fy18^DJOC3- zZ}-^Zp#s7zko)2^N#`JOf4bgj^niUmq;OhYY4dJbW+a2nv5K6pukxrBl-6U+LH^2b zPEMQe@&`KNZ9sB?vxz<%=pW`k;tnT>wL}deQ^~nu^HTiFW&$5i(!3=o+Pu4sy+>!_ z#rK%gkfioy4bzlcyu34y&xhGyL6?nZubI?=`c>r?V_#Qt<%V+q41F5K)KBR59sxH~ z9@?xBkL~TH!uL*31fNZ%cL-D#VmUEX?z5*tp!`YpK|jSZ;>P{CWIoI*ET_sit#8ZG z=;J#M<;zuJW7K3)X>^!Dsw=C{^;mfCNi5^U@q|=UA!s(g8UU4c%BkU#^lgEJNrlQ zg?GXJA`@zy21=&H8)N$lPshVWqtjQHBA%`W;mg;jA~^dA%96){DZ+4x{2E@J!x~tU zQOA{>)>H80fjdJFe_@ zMHaF~X&gSF797=J-WTvzp_g`8O%^dY#PcvG+}~Fu5VDSfSDqd!OzkiZ2e5tmo;iKd zW;Y*j(bgo+u@j1AGg}f^_ByJqh~P_Yga>iMQQm$1$%go%17rfNZjPmDj0Lo`yv+Wc zkl>2a-ma7BK5~l?*#@baedsb+tV)#G*)mR8Du-#NpdXmZ%IGMu|7e#4C1amy&zS~K zoP@C3(+*F_$>~Os!dO}y;`gK*SP^r<^_cT_^Z??7kbjYd6crV<(#I{EK9ErD<1)zs zI|Q;8BUQ>gJRA)6A~eKXsc$W+YNegGD}uzmtuFFc=4P5kO5y>m^l8d+Egf8^o4Mg` z-2&^*|B(8Q&bjqpWjNc>qY(;T7=t43$~@*a)1sVK8@D}+S~ra^`d;z^2sf3RPrFUz zxmcIauZKrOz4akOznyI_pr1?3eE#7JX;7-P1+?RK2G9YXx{#ZEWO5U2y0(0OG*N~b z0SlxpF=0xh_axDIUT0>jC(UQI<{^T8QfF$uNul= z+tl|nir2>sZR8t&K(wfI@+8`q8r6LQFAPKz&t!r(?|}W8-tuwI8{GMHa6!W~5u{$2 zNs9v(Dq&6Y5=e!H`|IPs>mLBgaQ%RcpFNS21eTh(+TB~klsx>A5!^9aKDMac^CJr9fFUD+ zRR|`QB09G8=|a=HSdMy1Re07hb8KuP{3Ut)H~xs=g}Jl=A^XogELvuuLxzi(yV<+>!4dSY@0Y%a+cOhZO3*;esW&ixIbr&6$FR;!*G#YmHR%d8a_`|{O<*5$wT{%3VAO?3YSBBt3=BJu>V2KGH z-MhEFgp>~f)!_6Sg2xyceOk3SdQ#~XL_}x@Uqt?AvFIT&B&6jl5u)!%w;Hv${YVKs zSAgk+3%qcZ1VgUMx7>FXOax3Mew8Z8AU;|--PNy3Kvu@@Tj#o%_%uBYC#)k4GC{M$L*> zr&6h2>4k1t1iDFoq|p87K>bP6g9~}yojrLV#a?HB9)B~O%$OFjM&K~}a-fjrj=S=A zIfP0Z_VQspD`?1XU7M5LTJxiQNKo610?u@yQ|U&?EsV=K;uIei`6-?iM(IaS+V%H? zYZv`S_eM^d0An!e@aAPDG3yL8FsMMV#D54)F7~m=!2zCOY&t;8fI$e@Qzq|px3yU+ z98Knksg0Ckpd4TXG&}+R0FtHKs!bWhddeMrxOYF3-!8Y2# zynG3`@Mz;rn7JSndfNi~v(Bqd!=1+zz~@m*6Zoow7zow85@!;A6$XEbvy+=#Xrs`) z4xQ9g5-{!MXO6UqH2T9twh)J0l1PU9Mbf#-$9#zCQ+e6BV_@K#wxCnCX4m1`Q;n9~ zrfGS4Csrq`v^19Wc$GB+`R;@xBT6mP7?&>WOX(gn)v`xC2TY0z zOxWcmT4O%8|1Os`YZ@x`mOz@K5H9NFghy#vn-jUBtHDV}ypDO}n9Tk->tIWNfLEtp ziN^!|7P22v5f5ds5-H=~tFJWJzu40QgkpnB>vlu2Sw_%|)$TX8STrLr(u3FA;(Z~c z=8kDK_jA(q&2yjJxPh(D8c?LNtdwhdr-EO6*yT{+lUwj1#Z$%gDb!*|hXh)|%WAEn^Pa`;CXq^T2 zDLJCH=7Lr}!W!|l8B?u!Q;fec*z@gOk6{w_V=aF{!a&ZKA`~o#7QE26JCV2f>n7OZ zhTfb1MCJ7&x1V)dtjAzucTie~>PQm_}q8`d~#P%&`#t8`#R%9$ClT9 zjIV!w`8l)M!#fUFqEle&C1%JFhY&QJtt8W9bmzFb-g4aArBr20RNU-)H~}962_{7I ztJZo~Dm&BbgwXZYQb4Qo^?pO*K!4T##*HU239HY1)`;UGn1&kI;0Ggly3~3B#nBkO zbpZ?W*#T7Dy;f7S|Lv>poLS=i`XpuIN{g~vN1E7cY}T7Jen|6Y|LdQwCUaiW_~ZeZ zKg81Rj;t^Q6~{jJn1CTCH7D-j7RKj$nqxI(V+(EFLD^Q+qf*H`mqL+RnVvc0m^#y# zg0J23%EiB>^-8PI2usJ$o)P&Om_{lp#-CMh9Hv!0{gB;P!)KZf%Pk?s_RpP22?Y0n z%UXwgl&uCUZ{OklANHlBtpCGd`J@_M?{(rZtlPHGpH;J}3l~yALw{x%w&|p@2_O4q4z#XxLv99sBj{X}#2#{8v7l+c15z&9{*{BtWe= z?=rAlcfdNiZ@HTN?T1(x4PxTEdeKL%v@+M6bU!xBe#6g?;?Ad%#5a6uV* zdabh1SZ<>D5gSP|sxscA^lRhB+5VS)D`Elyow}-g%Qd5?vt2E;dluvT)&!4q^7m$i z%{vtoDcyF)J!C)q;(tdx{t=?3G}=)8*P_yFX|e}`YblYS2!x0$_h26LM2ILBOBQA2 zr?lOJN^z4eZVEtOOPnvT50?W3HX;3LwGcOuwzpyt=#gKtd!!Q=Y0S}az zI5?Q#;TeHbB|DZMgO01Z+E%=Ll)KI7DvY6&SM^Xup=4Q#(!y25mOguy0uN_nV`%7u z)6?C+5|0>tKG>iqZkh}$if{}*LP4JP=gYC^fTfwA!wDY2vJ%nf&!WFKr^2G}i8i!V z7H=oNWHe1kOZ!elTIql6_=_?|{J$4Kc5E=NdMsOML|9>VXp255_a`Vb^GW+(u*%&{ zz!olV$Yg^V+oS9F)*NWTu%dH#4jhYWN`pT_Ri`Ati)_KUKZjhUOyNYHpT8_}uur=( zfPxJK2%;fa;nak@X*=WhuL^DIKZ;SnjDbx}(~?PcJ#x;ZvGv_p2a^`yd*)hA2IUnM zk?xZ>C&{~|u^C3$o+ZkJO7WYim)}?8^lqISez;0o>ODNx2bD%gNZb62W-SR6zD3VI zrc?g4=-Mmz|0rPnBGwK=Ua!2>B$}7$1@d_~|2?C6bIf0;W-;8Gllr3eEvzD8kf zSGe1i<00w1Mvwz8uk>2AIPME7_+%0^Q*?=!EaR;Ycc$y*+Bhlyr&egEZ8&`l0Ehk5 z!djFTSY&@W1WyKSPPnAvwcta>jp_1zIe14RhcQt+`wO9=3WMAbPL-aDq{zcrhM}?r zSy5Kzc@#bu`uth^m`^-zNxfB7*|3lKVZ5%Oi{som4)hZ3WqkVWB<6OV_apm4;H;w5MnFq@QMtXT%H(M!IJwY* z!$y9V6nf%iS>zBCS(u;~{Qv@I5Ts znu!`BGybyy;B<^k%urcZn1m?&M#kR9G=-IO zF)n>9TfyWM)uO&~G<;pIB0gkk0Uk42x^rNPG8fbLt2ux)>egvp(CuSA8Ww(@EgaZy z)?ISx5odx>JRYL)Y@#~l!Y4*!m3?k@oV#EBDekIMWXp5lIfjBgx;b8gC-1kWRNmOr zih4%nB}|6ZkWJXRw%ux8dhou_%c;q(no_Xy$CWkE=EG4u9ym7{Yf4aK0l(nYgZ`da z&>7Dc6m14(yoQ=o3dW7?mJ%_{_7YVp(v1=rn=#4twxO-i6<2~lM_*-FYA64l%-lbt zO2^55VGwNYv;d2rVyB+EXyNT_67=T*^urK`{ZM{|D{#Q9ZRyFstNh~ah)o)wx_=~m zOmB#4!R$^vlG}se-BrHpImJN+v4y3bZEvw!HFQu6DSGK@Oq$_*_N>GDbuFe6($=MH z$1v5B(w8=`S66HA3LGqvv^~d^3SAKmLUBx3wbmGrDB(g$X>aB(ET7JeliHkr$k%L{ z8!+;{3n|k^vOz$5zCV&iJJEta{6z8jnW^{QGHKdAXIfwDU4^u;!1*CH*Z7t)?TAUh zZHE^Pk7~^Qq>ro_O?BJu9;_(oXOr95)&w4?+(w&$`5cI*wK}8f)B5FlCd{AD6|gcI z8s0SJDdKbnIJbDLPHAg&@5zF_Ut6zwv7)PPhh2T-tWin?2(Ch4e7H44DXZVQZ;4byQS0j|_TLFJ~y)$4bUpKTJ2{vVM zfivryo68;0?V5vo$^YeqlKt+tE)t zJm+s*{%Ul5C)+FRaIzh!S~C{dMlAK{1b1{q%@t~3#QJz$<{^M4MXYS)ApWy>hCU0e0OTgDb5*xVv6Hh3G8ztUpSFju_`{r4YI7s zUlXxjYM*L)E_hg;DhqiZ+e@;kurhDmDjMI_;6@4V9QN2swI#zrqN3VFm5Mi(Qid`R z0~2K4x)womh2w+GKIpYuOB2LvM4lZyny*`Z|EFJ2;@jCU?!_;-WuP*xn-VFC%(g^`8=^zdV*V2mEm`BjM8a)Z zx2QF$yJ)uAlHTsaMZ)`D32Zy+HgLx3kYcEOcZ#1cC%Oz$JG~wNi15KTZ^u$9OhfSn zKgXTj{pU+eQ)aT=qZq7C)pF^G53gqO*46XxWq!1ayp6@Sx~4o6D~^Ym>aw!ahh6$L zdv8AkH)*XBUbOJsdKajBzd1w;ymXsv>voGW?>_<)*quTRl(t3wfx}no+vZeg@ZY1^ zZ$}oKnh>Y&Z_1N5nucv?y3glQCS819XWgjjM}kI66i%KD>*&ewqDXMUdk#?hcJ2Tf zy^niq=<<;38CLT5I&YxL`Wu(?Hv2uHWxs5tWbIbcoa^HtA>YF`ht)5mgXTv2Q}ciH zWvM{6TwVJ;m0%_rvOZa~qpyUhG$>-6DTMy81U0yt+$mR1oC>>VG7x_Rm7;5eY4RP? zWNLQIq}e7WDck2Y^NC{SD6tid5ls-<%#jS9Qses%g+5680~b>R=^2R-mP>c>r2X)ViEUjw_1rppd^#0j`rG~;sm zNc-5}-?D}OfNn)Mn(0n3pT)KbTN`{ue<*=BNPmOVh$mkHVY)Ud1P^jv0@{;Ws`aW= z#cecLal}>7%{E2hD5)%3$VzS;geN!1X1&vNQj-ZzyR+ijcIn%5TzNHD_d(J4xRP=v zYJz4?Z3Keyz+!AH1#Uhy2}W2S5nM0JmheXp97^V)h|vkPb8}O&g(zk|Dx=VFS+cJ2W0+5C3X{@{BoR+qh1L zw~QLfi>;Gue`>lZ*y*cM6e<&A&EWpM!QLi4OMaf*Md+;Rc_2e&{0scm0a@JTLh}W5 z#rVPLnvZZa#RapFQCqBB+;mwk#56Uv#$$_SuJzUftG1GF5gh~;LzEsE(vi}auAWOC z9kA19=YcF-*G9=R8qt#J>5e88x=bqygl#)SSq21FyvQ-DA&yeqBdkFHB#>ML!$W!g zez@9LSCqH++w$vSb;rTN`uldo13m4y-?FjP7}OFlaUXq7f^>VA@@c|OZgu#jY`(mc z?APUkSRtetgS02HjWC&TC>dxZu7fgRru`z|)M)QoyB*%9%W%|$XxZ&$Py8EKGm?4) z%Sk-h?^L+v;h6Vcr4H{BSf*3%!Ud?T$;ON(ouuQX+2!*u788RwKB92Z4)LA5tpVsl z)OwM`W}$AkZDYGA$!T0a>dXWRN4+#tKNqRP5a$BcpBoO5iRFB{OwL;KcY;IYvC1h} zFzLkaL^(nywS=bvD`^E70o9e2tE`+rz{zoJjr<|gyKiEQA_JQ}^ouk7Sf9$E2ImsO z(lq(!A|g48MU|zM*~Sc^fin;8Xxrqzei;wv(o)ib%TizFoKi7lK?h>FUH*2vRX29yXefgZ{ zO~B*&OO@eSZ==RQ)}9UlM?#oOrk+27C?(hhckHnjGJ#1Mta0R@H95lA;>kR?-DTM- z>u=xqyZ1W*TLm|zdX^v!-lr|QmztArobMg&n3Vb(F^dad1Sh(NmVfjIGf;59_r6(W z>85l#8WIfix&xHJoPAN0oJk8mI3OHKu9FbS^}lr0H&yNBsSYP0K})=9Qg@r18;GMv z!ssdw!3Fgnp5u#XPp76Gj(l`1HaV-EgD|SW^_iJyYCDpQFCdUxSeQ5*Z?ch5-*18N zy*thz1(No=ll2u~J<(00(sjEc#rm`>RJ~ZV7xfl`9yQ1;aNgHtO%>S1e}kNV&s!Qz z0|Mz`dsk9(a3~OPfzwjD_(}I6q9I`SjA~OQ|9z<^B6q4m;%I~;Q0s$e0Ry^pdR}lA zcub1Eq4@m1OaE}zL#GwhkOceRfL8~Q8SP!cLQp_y!~J(KvWIMPh6DQ87&Q^ImSl<4 zg^!V$cH>XFUGKK9 zruA5eZpLK4v*7mH;X0(H#{vD~dmf7=5oIhzTU%*q7z51B=NAi~jw%s?=N2wU40a5u zXIGsqPbvS;&Ws1+(nRzD=%m9w==CRyc6eBUXo?t2*V0bxa?ei-bsx4K_R~*ijfFzq zRccrBPhej7%(JVBVN{@^`5=$l(n?>@I7G_a$LCtg36h_5;q#{$X|&r}HOl-P+ryYQ4CS2&QkL{;!$8 z=ovF*07*}`pK+Hf=77875f}rJ#%||){naLN+O0uw=6jk0ykIdi2pfhWV*T6clk>M_ z;4L!;j0VP*%3m*EOg?-DQZE~*QO-w0DG^h*!B_1-AxtbE2M>REp&xR|r^PCoa(Ah| z>U|o) zK718V8Kj-R=Jk-``NfIB=Ue*XlaPj;!0S7)p`qbN7ByH5lW#z=q@9WIi5UPPeZ1$d zS3mBpSM>n3#AWe0q^tcKkxqYF1c`?PCf+!&Ato6bY>X)XgR->%uJ?PCli>T|@Wsnh z9%>zcBY8n!UEfp|b?)x`n!-xug3Vp4b%j$nByKJVTQ{nlfmHJGy?0xo? zQ%qRUP6Up6FZZ{(CSXYZmMBC*7inDdqOsQI;Pu8ALWr*;?Mob7DeCM*6GQI1@v`i}#~tNNB*Ye7}GI zxKg|_XayD!JJ$3Bqg`&dVhBd+3Wqu8*&71OQa0{Y%Zy~PFrr@drQHUb4|xBy`5EvU z>iP5yhe{aY;MDEd@Vm8in%CqN75xx)a@uQ0alGpk^tv@ab4f}19Fg)n7m+=AZJB_b zKnUn(R<03)T5&cSE4Q}BtM%Utno!%ik3Tird~3fts$BGBzkUo-w>yf^UV4{SXUBCK&}(|S{&P`$<8rPa^q!EQG5fXYxCw_kR!Z&1JinTy+=uDU z>7j_+M52PXhmj2%1lHn5MdXdP38tBv=_k6!OcFTeA3m13fdBiOF3aCduoBcwPcTqX zZis69$x&HZ8EWTc3|RiJTU8#l^!U+gd%U1Tawsg;f3hAy-W3eHCR2cqtavPJHA9^C z>bUHt{mVC}_tg>AU;tEVTo51Ui$59~KLqU^=z4y)(!H?)%zy7c%XW_}82If9@31*SU%5cYI?& zAy9Cow~>ToloCB-PRc4Sg}Wm%U%$LGSyX*1c?&qVndj_U6Q=2GD^hZ~xXxGU_9z(1 z?1eDjOUD7;oTloJWWz*#$!RR+n@{!6c>)|Qt{{vN)Vl4b{4Y`@cc4m5Ie zn7rRsUc8@+HF4SdM^*T5KKc8CVf_bD3CjSn5opfe*Y65>-;3!4L(~qs#Q}f8+SX8Z zK^9z~_&g{DD!Z)IqSf5<@=?K(1OJ7@q~xFT4KDkAa=2~iIvQov){UyfCZ`@1Jd3FsPL+RGdGeG@4ofFUott zDi*i~4p!~6w1XkE+(=Ck>c2ohc@;1}@a^9~0g#4C$qMS%HLd5@liC3v*X!PP?K&qa z%HDTkJ_Jn`iv-}lC@ejFuujN+^Dv34+M2QF+8fz-P3?`>$|RSK_w3H5v_ECbx3?IK zeQ(^h_QS0{R;UGMj!d3^!Rq!1<>QT8yaWh%=R*Xq_#Wm9e*q?+BgA<+T75Yu%P``y zf^H_7oQL%wl*S*f6Y$N$DVHq9(!oZ3Q7NkqHD#MUfIhTe45;OQpRHHDO@piq7u!PA z890JD>=#H!&T9jQZ=xSPchEwp?yuk<+1TAMa$uzV%vD`CqU!%N-J!0xC=$G8jLl7l6@XHcJec}~srj+3|8Bdi zI^}$Q_g(fI2^?5uE8>aYC9_HM6M_Ry!(Z6xkD`hS#YKR(&8OvR19*%ClyLr!0DnJGbAvo4hyL^si)+jTwt z6b8rMbQGmg6RQWwfQe8WYW=f&=!mg&)|yLnn?-^PcI1mNO;=O<2}nnLHRVHqf-ty6 zUA~&_lILsp3FSmN)2(mnYBlH&KDaAIiE%3igeGgXxtXrNqLl{%ZX;1fXS$c}Z<+}s zIiz7%cOaDJht1Nr0{_9en?*^^FFvFITIoBk_8dH6OXBym5{B9<3{oslNGL`I47DJF z-VI(du}{eFSDoI))m<0G88DCWi$UAs#OcdV^T2RbsHhdQjDVGN#m7u`RFi|ises0Y z!^vjn!|TD>wttM*E8-$Ox6`89V9WOG4YP|pd?d{JDsAa(jzlHIFg)6wTeziPlSAd% zGxTGzMrAb&&-%~6*W#pw>^V;|N+EOpGpsus-`cK>mH6+W<;HDVX^NZGY z?(~ROIrN{DwBlifH&sB&TK|kN&Dd1D?w3p6obEB_Z+zHZv-pbGKg5#YX{HMSSp6N4 z6zr8ePAnJ4?trdnmj2~qrUJ0l3PyByyRDuV1Pfl^_Z^*kLqX(KOs0j#L&dB{Kn{DI#)Lckei$S^P=~K$ZP&v;+T5dW?h8$TFG!Kf zTMR{6ARsWvGl`Ct`c(p}%>NSSpbHppHeH>%Yg*kmI{Xr47K<$@Ke=K=Yc>X%q7v+_ zcC@p&{=zo+wkC))MnjeYMy!`EC~eArlZHEk`GIFKNcs{l{)ssq31C*v6cJp#z#Z?9 zwwJxUTn#Rcpg%v1iUM;==fInpxCKm2xj>?Q3L15@JZS3Aa>xiPQT!GgP##Xh6>TB)$D12L1YSvgIHe&!)>wdopa=ZFsP0Z+y$Idk1zOotX>yY?GVDE zSJTx@k-7O5aCl$s%WlM#{JlIOd`=>J34eOH6eA zi+smTg51H9=H6^;r+Fm4`1+tx&G@j^+JL2@(*}jO zpWJ82DpILTqPtk3Y@u4C70I=M1_j;xW&UcSNcV*Bc|oMMS~~S`YcTI#Q+5|K3C44@ z73UK|TUE!yR`ujqu4Z5XL6k;CF;Dz5OVSq-8TYVW&+p^O42UmI6dNz9b~v93#b?Y_ zfoU5CXi+4;11twJgg*xRk5 zIBu$%q4NC&Gj`VUq=LY?8+XiOT<2;YRs%E-qK&0}7`~GA_qgcEG$UuGT&vhK@;QQN0&dqb;}WFrKZ`tKe#CTsOe4Y zPT?LIVNZ~1fz-COP&({jeZ-sU*Spb7sJAtVd-hV})cu>-na4j;0w|Xs%<78D>bAcd zKi>2g8E`(1XAO0H?gqIoGFt&!*-x(+e7JDhDGQAGupw1L9Zbvdyv5;i2^b+~*S@dz zxqLtzJeTB>eJ}a0s5UHM7#4J5UDULoQir z2c_N+hNLvz<@WFXzZakZ?@M^Z_04QDQ;rt%}6r?d3^ z3Cd|0v?~iUq`1O?d8$($R|o|H#O=e{dwl!MVIGU)^lpoKE45RR$oiw-L&-M_oE%p3 z59iPQ8_wCPoENx4W{bpYdPK&WZf*hJPc7|th|iIw^fJl3_RQG zSh0TZc^+T}8K_Rs1gmFcrbHzwx9|xNn4k22ABL}|j->*o35w1NZhm_ZJs*MT-v=u; zpbf+(B&Pn2BDf`9@PHFpQur*x-@T&!Qm`U+{^8-W{;5Py=_#Z}UEj3z^10gkydXls z%jgHAfX5_;j{O#Qs)iC$#4=o^1W3PuKFARUgmCR}dDRC8(bgAY#gRekee_WMv6XWm z{?a8q%tNy5VdiAnWllow#R$R(?{XBKcLCM&xF+W&7F_9r{7-$_3W zWPFV-tK4`M`+;;rCzCh#11Nzj@g@i{(=pjy=zPu9_zD-e4Q1{wZ&qIY$@{?Qbb9Ac z$bJ2aa*zAII_`dtf@0_Qi#b?OpT!HWU0ppYVGL`If@wGz)aL~F6b5>5!3Q!bM7i6r zz;mKNd4|#Kk+&kMc)d}sLC-UIaA;WmfBggwNuvFc6M}R!J@?RjxlMTBmxW_|*}+kK zv#({MV{q~G27PC}R|&e02VE$9ZUdF!4Hu7-nSJL47Wi7pfVmlKl6MP}1_)<0`-n~AT-*5sbGC!- zUWb(l^{G|eR>%Il*N6q3%t-!q=NIgAm+oTJ%Sgg2PI{KTUlw(o_auqBAJQ?d%4NrG zcN$Z+;}Jg_^scdfqo+J*CKqUAZ94 zCOT@@#N&Z?Gc;EpKBySnw3qqaKl!xRsMeHX>U2pj!foUXz*AHDIB zHRJ?RQr05th~(rcP;lQ^A!Oy@{KV>{;oPKSAeVd*TQoE~Q_j3xOs8H#jN?55?AG(w zpZv#%bF#9`)Z6RLvfZW}ESIjHNB}EG-wD4B^uCg8p)#o;CrD!#+&k^M9VS4SD`$Gz zlSM-g!@l;q4^vT5WOMG(XfKu`o`yl|{A@v^>Jd`k_UOf-?rua%HXS2^NCFDMwL{<* zIoj~WEaYm45%azEWduq0p-Dl{<1EES{!Z*Cd0t|C@Zzd5B;hk#%kKX`zU3&qK_K#2E!` z-+oJ2Tnu-+a?s(tlvT5ODr+=ufO*q3njhukn$p`aES8G`l5YPmlU9s?%lTQ zp%?6TLdz3v!Vcn*E;h{eF23B(oOE@!@o|1Gi(MU5SlNOFxNrpkst%aOrv2oL#cvhB z1%1SX11HaWuFkzJm%ZUmT$V=8`Cl$%aGo3Lf9&jI7u&Ob!C+^%(Ytq78MoG4l+5_3 zE9ZZ>JEJ^Z@N&UF>iKQ$>0T29&GcGkU}W(;O6YC!w!^=!b6@Ellx@$w zCxn);^np(MsTY+nn0X-z%Yct={P$wxnHs>WUhr$o&%-$A-h~g9rI$rmYGPv*B{8|* zjzQN8lxwGoU379mb28En$3r`?w0GbPiZ4qk$olJ52T2t8E0_A}4EdR)*6Tg^f+?0K zN_~|cSW6rH#w{xff~VN1tkijLzVY}Kx3@DyMM#St>^#^Cd*^q)o~tJ*^`KykFj6

^DRU}TWh=zWZ3Y-{BMV)=#4gS%YCIyXL|wL z(-}x~slFRTMn?JQ`EDD+X=2`pm-y)*uY#)|cB}$!q7l ztzA!ii5PXBTqL=F!BO^LKsmB5GX4r-JL^fof#lHa=FRhFToH6Odd_rA?G;$2JSt4c za1AG0l&0eCsOU{SmeUD`rMtZGfRhCsavno@X5T_{gI@2|U#hfo)D&;#{J!6Wu}=J%_2d7iY$K28SILxDFduKYzA$6&0DvRCNrFq)N)(%wEtp)|Ig& ze4>nCpcWNXLNj1pz52aHf^{S~s+7d=d^Qw?pHivSIQC)^qyOB4dEwLcK6-&w`j}&@ zIoJCD5*Zn)05*hq2(NRP*PD*WlvG=p?HEmB&%fvLq_*qU|1{zBJpki-m_4y6ELGm) zoFd&uMqKOH7@cIdUdj_r;Y2MUgyCq1L@CAxMluBS!MwXs32lI-wxYRMs=snoGYO79 z4o-&Z=o4k2F?JlKq{D}AE4b)KRbD2gO&VBxqX^--aPZob??Nx*cL<;9yZg#%Ae*YfC`$^nLXx^p|GUNx$EIpmpF zX{yHM|Izf7L3K94(zwe(f&_O7PH=Y(1b3I` zd*mXvCHAT(FhG~$w0mH_RqTVI;JTr5H$UnfR7=9tYQ>^Rl^V<81PX;>2-G=C(f1!t zmOw0`#9>m&zx>Lxko&6ab@l3fu!J_ore%ZonN0-270M{GAi4MKs`umuXwEk@{2p_b zQC2q~v6_>WMCM<4b=SlhwC$&?W5)gYT$3VUx;aE{n4{|ZV^v(OUT(5K3;j@@9p5ut zY>%CL4>Q%3VkU58E-$$`FN_^=zvyQucU~SO&$P(|S4Fw-F06UKScr`l4^_)v_~r@m zLEANPS#S~f`UwH&^sss@3mMgC-{Y?+}&x-N(>`{Lo>!-Nc~n8^p^fau5CB@Cev9?o`Mjw(rAQhiVL% zrsOm8& zb1n=tYK-1=QQICB(uN>msk&IW?3kznb8^sFXMiJWaF~=7G>qn z+7>1F;!vXEQ?%t!JRuRV4rTuxo=Q9vxQ|v;+XsV;kS^DQgYL8Yo}w(d7_h12pIG(E@mZO1y(TiRIajRZV(R{Os+=!DU^ zxob@=3PDwjlj-GV!G@AaD})af4Ge>j_lb;PZ;*Rd7IB@u3It?6eM>1;LCu4K2;4{l zt=qH7s756O6_lEOWdbiY*mT-k=6M|iP^CGx^8eA!j`u74p@2xA~kpeh~rk*VSm*0XqzR zE~Ac&9<(!)_-Jy4=EJoi$bW1fjqdC;TFSQbc=J2D-eoxYsy#+K+(#u5k)Qpq^GX=> z1Kk;0r6%#nMq;IQaN^Ae>N{MuxZ)ULE#)&v)VTPZ_H$f)r_<9x45O`3JO7UpFts&Y z?6cR_mGqh0L@H?{mMt}P(zC!D#p741z~tRVgNCp3-YGOy-D`i0X1#=8J@p#4J(|I& zMa9Jn+&L5mCgQcqLd|b=KTY_T*~#BXFz!MrLQ92|kJ1e`UULr?hUaaj1ptVy^!J` z1Y9<}x;lDSZArH5P4`1`_Z&V4!s?hKT7hAP$H=laG*V>0p1a%5rp!|5WhFFjItQh! zzS%sxj#?4pqdT%d1YE3n*C2NfB>}d{qxPL;KRT{eMKK;~{LP^Fzn~2$%hjFL;LEwT zpVe6UXjEGeh58p#+}gTQ*V2V-f$J@Wl5}bd_an|qyk5W5G~xV%+IWyc_hoxalgh%w z!}~dU61aGftC^k!g%j$)7@9M!iit;dl>J!>Smd{MlTzww@bheKfMR^#y+%lyqt zo+%x3@{h21`%P_q#9n9V3|JosD%;hrObdNQ5{XBum%jXcKVY);%Qo+_%9^ zYY6@XD%7KS^X4hM7qWbFQ%emokeP5XO4ifawWDH7ai-| z#)#yC@{5(*IB4D~Z1Es%!~P&+@n9$cy#5$s_1S99Ti?6oDO=CF!fun`ym>;^_wE{< zK%0|8H?^a|Zz(yjV90yx0lp+&3PkgK;P3UDpbTjwc_Qk=tZ#6E%C!Q;TcI(=Ql33c z?i)`|Y9zm`MEL%cf3!p#>ifiGckwRS7nybzeHWB-O?#i+9ge{?G2$`0%8nO1zJOV) zZOp31uIJr2r`NYlrAq~B78jH`BP1OLc_%arW#ZPB*Od@-e#aRC4Vrc!^>_A~Jl}-1 zp;7sHSwL`xVJValynYG_J@>SS^313ylG%g;gvxfw6A;Lt`ciBOx;no91y@imK^>(PrZnkgree{Kb{ zs~+H9zB9k1DZ$1*Xt8qh!-dTkRQN zLXvq#=PMx|94SLcUjkFddm>#F1Z&b*+(O@1Jd}40&cmW)!kI)j55>uwypp|*JV>?WpbP&GryT|%TC13{677A}O4 zT7n4}f^=)sSsZbXZ+{byn#SE+&0;buflrHI|Gb&Ff``H*;@Gx_H z+-!X`J=0Ick9n=8Hd$`|=T1|CQ-q)zY>1B}Yhw@*36g9RJ~R3LBY7k;IVbnb`f=h- z!FH`7%@2H4+OEVs@AJAcD~APD+@uVxmyvIR5|{`6E&6!9EN@JmzDw@%&#ANiGLXhV zU>;1s`B%T>@7?=-hn~QQfK;ndL)(^9n<9?_0*r@dB`2XBdN){RD0{acbB-N{3!)k5 z%#-aW55_2PU3)b9w@aImr%cqayEdn$(Y`pfc3)wAO0sEIM_th7E)4_+wEp3HKH?f& zz(Vt_uV5(`6qkjf#KUD$>g9%1=2vwTW6~}^FDrgM@#{EpeLI#1FlA%Zby`?r>rLE~ zz1Uj(1P#CQ@Qde^=sM5d5T*cZ?!hkzQy5}9Nsz7nv(6H>nZbZDn*CQBYUt`uLB2TX zgwF8Zz@Vx0qh&~87=m*UWuh~V7|C+!-4=b{duVFoQ1$53=Cb!Vi zfmZqDlpsc@Ihp^4|9dN5GShN%r=?|k8GG&I&H!uEXJ4>FbgT}GU0v_dRqw%-ToglC zfHIwwmlb)ZuLK&Q%)p0=LCX%wcI=VO{5*cviH`O~2YtnjJ@i0J|Ji-_K7v9U5yYj3 z?|)7>eDKMo%D#zmNVxA^KpOjEZH3av?EU)sxxia)R&hi#r;(-*cSwa^^lxa%eA}U` z=;;b7Cl7(vuxQJq-O=0Wyws*L^+?4C>R`HsEvBU#M@KptR_Mm?r7MFWlpRp~lJSlk z#YDtRLd?ic(@nB6m3r>elz91oL%%iAkB6Pyag%4$<{WZieJLtot7OX6~kRba!*An?Jta zpDqI&jA~lgc6}jW5u$O0N`2#A$r}(--bu*pEOD``d-PBW+PNw&=JN8$DF23?v6=CV z)kF|8T6~+G{9hUu8qytr;2M5BU;RrF2KHir^s!L-{i8cHFoAXH%+AC2{dd(kc7>`e ztSnN!qi-yPv+`3?-Y=>#NJ>fdO2|S2+-*@|S`n{S6|Xlc72JqQ4z3{jkuJ12q*WdExN-^(^%lIaeNzje3n5(jW3A6FN)x&0@?P7L|s%UA%J~BwkGjKI4n=Ro9nSk$K;WMY{Gx|osZ+%IY2MU%Ag2s(UnmTrXLs7YR(7w)geb@vbcbhlfPnB(q?LZ{;sV3kwTE;?5sFsYS{0cv{G@ zuN4`Pfpc7nPUpv6j%}8Da;sc+45v?T@pN&`0?KXKHxUQ0z}0NlB~E8l2X3cvoI=!Y zKlg6&jprWX4uu5bE{2|RUPWz-Ei%uot?k>&aAMqlMeD~boC)IHwx+VVOrkIXj5VJ2xqLn( z^J8EiX}O<;GV-SZtF&6*^_2z_%Ch&F){+f09Ya>bp=X+0X&lKe5*lvR{J!9B3z|}) zR~cGPL1@YX7(Lw$MP{v=TX)5~$I$%+`m?F(MStHZse9t{-~pgv_!}vlS z^w7rf_i#2*fA5{-pEq&)tj@oJ>!yxM9V)hNhqCnNS_ z62eEY?BAhJKF~UT(+8|=7o#y#5vfTC!A0wMY?82KN~NT zzDN!+{#nkxe1b-J^qj)u<_be56E-#`G*_G)sGK2elNwyZA34E@jmLXFn)z2=`N^bk z63vJf4+;e}RdVixIUx&CRs`cyS^g{tI(P2ZuRSqT0_}_D7K=yU%r9w=uY#I3vFY6R z4txnqfQpt+7jK)}fe;ygNVG&vtYlWW?7MJTvRFlNwD#V(^6(M^>ZsVzbvQ6FahUEa z5ki&;moIM)p48^JFi`v+IZ^=!COgF%h00~g(z4NFclq+A zBdLVHJG-l_7dN($-E|K}SK2NbxxO~}f{)ubgkqL%BG%7B*7p%s-o+Doja>~V^U(e+ zDX&cswb-G|`p>VdcnuA&=<8|Nezjk=U?{em$;nbkq$2|{{uGJ2a`_$y?K7zl(!<15 zM#99xPHjTtxk$GL9YADgaRdw>BAW@ zeE=~macJnAtM_OBh(_V=ad5v8-W7V)|2~rfYT5mgTi$%tQ>!%Vz%x2p>yHToay{~4 zNBEAZ;3qmNR#gruhybWy>6E9$8>v3-t_s>5=R2Q+gd?{Sf<6jrgdkN0Oq6`-?Yn2d z5^>9=nT6L}M2ag+0EwsZ@Nf7cUqbR>#H7OawdAVHjpPCo(%C^HF_WnIlDRV&2|ma( z5aQAAV7HOC^4J@WD33RSi^5)JbEPTcgx|pd$pPWBdxArRl7* zO&fcR8~Ti$yTNx9AOuoUwXLvd^@73ZMEz-d~d>X`* zrF#wR#vlrnPKA}j13`g8AxCQssSi4^pl|~G zcJ%n4Qp9N9CFw%Ck$+=@N)cq~pdg8ZNJR^G#Dny)$&`gbFbMe&fw*Mfl|ExjAvDNF z^uq|8>!pYEUx%FOhieF^dZ$qVfo~T>lW+Une}4G$4Ki?sAFv9Ypu;%$ zj73T0&&kS=beF?Sj|TdRb5NU}l&Dal5_{)Pl`<0C;r^ha1@gD`?IF%^Zuh!%vf z)Af+u?NU(xrv*@KoUtD_483Ts<$AbVY75LA>ic#CSOMV{d9wv=;mF%|26#auH z@(1=>%}m8F%6%ovytUaIkvfMMS@L z+I61&C7rls^wpwu?;~ zecr()rIr}-HdwRlQl18qdFtc`7Hu)`Xy=w4b zV*nSruuBHTj?@cmC~TTqXaJMg;cgvD6p6=ic8wQzQSw(HM3$91ul9AFnb%rhV5E;N z{Pw99m&HIp06`0al;pWD_`*Ta|K2McZRB+qp-2IkRmNdXU9Ej(YOV29`+@W4cur(> zj);fvOvix(h6GaAKj@D}($-~jc(H%G494a=ilMN5^78gS{`GfZ0I?PX0tG!-(@dPco?lDE}0ntLwckRca6zg%!HH0L#3r?#JU)$v}} z4xNOJZ=)Owz6D0;Z|Xd_{WL>J9ox^fS^5)ERZ;EnTG5!P@lr7AUiI;=^WQ2ZvtChV&dJfhNJP-)ImxmF=NESPS zizPh|q&T|Hl8lCO`dBh;e~Ua<|6rM>X3Dqog9-dMv(!@f#-(i5Nompkm%hQ}zFn>( zOcoeY5*j*0V_qps4xQbs^(7Jt)Q_K(h#(G;tsiwgBf6$6U;0hM!y5qqavVbX`uiDg z5k7sHH9>$78HtoB=9WDYH}jk8O0tyS_*1Ia@v0&>Gsf|W3dXDm76{_g{z*FI5e|TH z_LUdWxmJ8g7BUX{6ReY&?cVi-!_X($hWXGY!WLxxuHpa@BR^_Ydb6pAqX&2vHuGL7 z@3yP$cYO;z=s1qQe+B%@&-QCP&nMipCa{8-Vn(j_A+q=nYjfz1T}AP%!n)p6!u!so zukTB+VZBIxogZ^t0O(O*+@g?H{eVSu24^7&*PFw0?BK=6t3w}G*bkUkk}sDJo8^vZ zw2wU|mn1LPy$;^u)YlQR@LE0mOLNN$c1+&;MJ3X^O^uCp_@4EC6NE3N`yIq+t3pE9 zbK-&!EDXp+qG;qv(5fh_1Ac#McTA5g#wvTIgy|qD?#9w!Wc0Foj(*H@F*1C+8p}`$ z0P;Qp7IH3Q1Z7>>JiYvvk%20S0CsTx#bOQTD@WE93xsj8yZCMcc4W*VkvNP|I)e8Z zRU*5T$u_&3N#Vs&T4_bO$9i_#WzilLp)8W~@A=X`qC|1b`ma`>cEEp|y^V0{4jA!^ zf;-CJ-}z!g_^KT)j}E!OvIiusf4{=T&1<0 zcScS=g8McQSQ@i;*SC~Qp3I(Zgp+^$9`aHLLb4esaAFd4xPiJbC&A_`us8cytx-aA z_k_m9Kli2uE;wndH$pu8jG)hvDZAsJc1jB28X;BpSJ zS&y4kvg7X-5^EeB1fo~lmkaveznW(UNn=BOWV+7s zX-ZB)5>rN#Zr5qotO%%a82|kp<*X?y2blDs{y@-3fA6AwVfHIR5i2`gkir@}k~<#e zaLaEL>dBM@H#VM+{0{_0CM_uv)--)>H$B4_4q`=KUT^rVtKcHkod3V=J1)SsQ#&zh z8e@tt&o`ue3hO1(X!aR3y!^`9v?16<={s4PrqsHwj}rHbEV5^u$`jcA*k~|CLYM)_ zQKjXhXD}x7t0Xw}GmuOC>&{Z=@IU^Z?fn>0{&bxk;i(HHOlyS zTbWg5wgA-{eV3SWgLc~dK;+Hpis(4}Yo)vJ%_CgaiY4eKWP_d{vf z0}_#|!YtyM?DqgKB2YFMVQEO@Eyp3u^E1NI92AQT&*3)PW{2T;oSnct&VO}W_`nC> z!L(w{lMZuFbqBmr1ALR(CkRj|(4R`qtdEw)c|Zi_QhfK!IM!4u#6moGkizuAI=iN! zzwzvq9`=#>4irfqO-6miB>MIrm#k?txM6XweRPcBUlM`|ha3U@N$ug6Ci*H=`-C4yi|xFLdLTRX}5 z^N?d`lD-DUGEXP(W-%e7sOeJGlDb95ew{oV0py0cjEem>9*EzN%%!798)lHMS|TCB z&3yv4;>8e|JVfoh5~uNI0UiKlB9 zi7S}XGs)b4FQI*BpyWfvN-(3tQu%2DCHh{~5igD@Zt@17BTuKt@*?{&k-2{E0!Y?- z&oY!Bk^p&Ij1e9s&7jftDfw7#s-^2_%A#u3^Dl}uN67B}EhhEUDzXGMB<8`f?l8Zr zOmQ|fC0WbIi>^>ndBR6*uPhu`!qL=_ zHVZD?&6JA>NsjZq@Wdats;lj<&-*qRZ9i5M&ZpOGhlrNkAGviWrp5&09SN0_u#|E# zA^Zpbx?5`yCe5DkXA3ruf4mcDK2iL zE_*AVI9W;+d@%&f9oKZBHtfYTTF(mJgXa~s(Kdk9MK~ThO zzzd34&0%#wXM#h!N;zvvA^$Oc zZlwBWaBCzsy2`bnR(<+XZp&Qed*7y$`Ti2O%sWr=H^hoV$N_tfD4Edx@;lPBE%aI= z^LxY}!rybE#ZzpEPHJov8q{LdSrVorHIOg}Ae2fSMvsU!ih#T8U{_?rEOIkja-%VF zO?I>J3}N}_Iz3FKXcMwx2T&s3$jRQ;JmFr7>?6;_$CLQ8>aNI}e)k3Bo#L7g!s8lN z)Plm59KR?+da}u!J2s^hMOxCj|7xbMoz52>)f&Gx zJMA{2^CzqHf9*fq;1RQubxYYkFhx+FB4k*kaW%E$jmq&@ef#D5!}ji41qUk_^I;(W z4{Jh4#9s`_;1G%gX@$rffZW@okwZEfbLstAK_C0oX3b{+b#_gsqxb6*O)gRBuuT{! zFA54c1(=X7pE+)MQU5EQfZ9|NHla=1s_JGBfy@Ow7?X1P7gl2QagzDoqXR(4gC}uc z)eVD4du?isHuDr7p*@?2J6uy6ZF=rQV=}wco2;HDYF6AF$5nJ1ZN8dQiQO2PS39K| z5(Tp?Aj)qO6sm4PrhN*s-Wlx2l@dijD1k{B?x|%{9~%Cfy!|&gCD4H_fCZv2AU;Ac z*|7OT;4g?8^Q+7Ch3b|F^+%y71n3n3#s@3qUg_Ca9Q*U1jM?sr9ZTG#yCgZQ+_&>1 zn}?Cm@u;0pw>Oi~Kk}VmVcb~v`@REoCD<>JF50NFQBICx>H#at=4&mDGb}j2vcu3H zB--$iFp=xu=pYe?;55 zj4Q#4U3156z0l38i`!5R1&dZ?ympZ+2e+YYdPRO=Et-SMm02azzYQZg~EctFs~qjk9FzZ8}6Tft&R?|oE5ZM zn{t~hV{)O^nHbyHF!lLLqjdFGH}fCTe`M7+kvP6WT3A#MVQ3X2rDbWcZff(OZ*&16 za)0kB_I{08=e~{*NYH$3v}x5@eCr{&h&deo;f-Ek?*J1hd`Pe1`kBM2e%8^o6Kd!0 zfKXLO&CUbaswW;sZ#WH3SIqN>kEo+@kwIV*Tu|bawvOw|hAROVW0&i%8v!AMvC}ng zZ0e*>`7XBf30WH24M?+*&W;!IR5qSzobzhc9!zVjzW8vpiKbK#5rz7EN_UP}++4WTBxm z42#d47Wtyk=x8@RqtPY!e1G14DttVfy4O zJR>{xW%SA4*F=UcZ84iSL6MHChV%W^bNf)LYi+HHl;mP5Y~y`9p8A@@ib`1p(@{-} zZAbRNH@y_63%4#iEQ2%>n6>*aWn(uGGXSP=#7E|EzNXw`^B1r6d?aS-1Rb-aXggZ8 z%QkgF7ME2D=0FHfvvVq3XYW84@ri&Y!FjquC?u(}Y<{~V3@DTE*Sfjz>3)XegRIRq`9qh5#I2kAWNUP@8wC z%zTA&BTZqc9LjF0b}Dt+#G~# zIBUv>HXLc61w3Xm0lL0qY_Mx;rTlqsROsc!;vi6J;|%+9_{R(DS1YumXHNPeD4B>W zO-?@C0e15{<%V;&pFN=Lx42H2p@^hCrdn1%$|MsZh5z!NjNW`CS0zsx|LvVJPQ5uc z8IwLd`6qlC$^-c-^?Vi~`-&xgv{r>)0%Q@bHq5ZHs zB3Q$Qu#&QMV5Cj+GrC{difo_t{#X=ohc#SS%N|vD)S}F%XUt)I^0EFP<>3fNkHc$u zhuJhDEOGOrUus`~B)Y1q+Eu>e>pgS(VxP%Wa$}A|!NbaAis<_vGyR{ZE=?{;53^uB z)Y+?SOwPQfo;Sj(CGEJR5t!mw=vqA?zv)5_ zQ}*6BG7}TqZv$yIgtBcHZI`mrmK&O!f23J1zrZst)j!ZO;J}Nsx-70EwGc)i@-k%T z1w64w+2qT*tG#jA#np8x8GHkYKi8NY<@?Cr+9S)sh6Az`#N6kR$TU4qwoU&jI&@`Nm&6xqPFN|!ZW8rasvr`7hWHCsT}MW*d?aLNLTkj4}DKM6-5)a_R& zASxS=H9e+aonsKXo=8n7s2;hbu$~C|Xf4U=Yp*lzACh5or%aq300nVp<5&(yJl1@v z7nVySgrQ*4YxDB-Z#KysIW9*TZ=7pE*GOhd*He!U_OO+%xCJn8Ab7l>xoxF+6CU#X zasD;JQCFW=bazrx|3>vd5SOyp`F(9-PiRNE1lH8knMV8KA9fF#9ws$V^#ZrHZfzM) z!yMh6_8J#pEm~?)2%<|G5}g5h>aO)1o%ekz;K@yraZiFX?1Kzo)TQx7w zb5}px{MM)1E&KkHRq|vXXaYP=uA3E`vUkgvzq0RV(~z5<;$6sKRJX^(??#$`=sW@G zP#70en*EQP+-&`i`e;C(>F2|n`5$s2deaq_S6L5C0j{^!}t^g0({bV6|Y?*lj1 zBmq>?*P9{HydOlqQ8l6YZg_WXONL4=8Xn|v9Kx3WFXD!t23%;ZBeN9qK;-jJrMcN` z4+V$)2R4}kv)Z8?_+r6W2J>^;&VySKmn}mb$*m^67uxu zo}a__jEu(L_Zc(_5BU1FmW*J&hubqA!OL!YblyKVH+_JZDa<8L2V#pG4H3~xm#qzf z%RrZwd;aL*KaCLX3@JGR4VZc%IWnTUd^bwy?SHHMT%gLg)=*P@L1MOUH-U?~J_?yS z`8(58B<}Qij-Kk;iS5tMj!U6@mmx{u>&VJV8^eFQ=lB~WVr*ng81pv;(gLOZ5aPeQ zGY5hU=vRG9*sYjTt9n!u8>M!nY6EL9WGJ|u@kKh;qlzNnZX`*Q6ZNr$FIp-or-!Ui zY5k#`e3p)XvD5Z`SO;V zD%n+iXN0(R(!EMiS@p%ivrcBj;%+M(Av>Gp8tpqkxo&`c2 zByF<85}uMwnt;=tA`Z#hV$2a!X{VRSQc+RqvHHvH>MS%v)@b^bt&nm^j2hfalq!yi zp_wXSoQ3B6W7lMS@99tBgwJG2$)aq;>lRt?RBh)^SL3T4E)DrKll|MBKdMI&K?s@a z5fdAbua4gE8yg&BtVAS&_KlBC9j%Tk!$*RX`70${I19!7O`}LT&a^5Wx(g`(keDC} zFNw1afj@ds0QpryoARAWv^7u{|Bgw5=iWBi{ryW_m9CRfsw#Bf1G*0DG%m8~hT1cVq~litWGO!)AhfGK!?tK?dK!IJ9%b4X_`aNiu2>6T zoDMKpDNnW2<}`J7-y*|fSi4Qn+4J?iBX;F6LKSYu;sT>m4uyJeDjHjN+-v^Yv|d@C z<~?Ydx1NI6&+xdkwr{c*c>OSCRCl;>5U+q+Qx9q~$byyAon{{NPO69*G|M}S!1x(0 zSzrMSl1Nc*7jF#md361a03YYpZI0}iLJSM2lV1IZnR0Q#`zQ+iN1{Q&EToQQhFJ9? z*q@`>5&O(Jukrx>=v^keXHIeP!<=DO938LF^ZSdKw$pE4(9fR*4z2v4J_jBeFgNAk zNv)w9q+MreIB$cND**8kh!IP}V8R3rj#bY4pHNdGI2~0|M9?OEdTxjzK=em%s(N3v zL3AVGM~fPO6iGHmm7|0SP^b_w(x>heq#<6h#C=a9ThUQp^clxEUz&iU!6e6&1sPfQ z!HGnpu#ryzOw9Bv|qGzaP9wl0&dthjmcD9MZg>k9n+GB&e&Qc4eg* z6d@e^hg=w>QsNFr8V%Gv5&TKuN_c`_tMcxwd^tPKM~^liO6iPfm+h)@WD$BOWK$;% zw2Tu2BN_A#MQOIzd}{7Of9^x+ylW>g5)^ze26~C^5I&oMzSBptUj8yMo(W4PNtSm_ z#{7)6{CX(V{kyD!&BpiXpev_My7*lxD0=_hu?EHWzay}w>?ecC4$!~K$~%tp?NAIk zD#F<#(HDyvYOl?m^lJ$N!~ir2_*UCnklnXs*lv1dG7bh(3>nq(l1AnU&?x~5a?h=s zC!?meDWR-ro~lrnQBYVA^dkax~kRZmHJItqi>sXN=HeS z-O$s#Fw<-(^e{m_;+PNs+PL(H!g6&4(!`gP*!@e8C92I9z6~bl$b0iKLMO|Z}!IV zK%UA6HtH8Tf(_nE-df@#4uoKODy$s1?S$ob-t>vxdpSqCT zb!%I<$T}qgv4nh($7T)QxotyvHweHR3xS! zQ|PM6YpLpNtlO!Y&F*1+YR-jvJX)XzXGc_?!4H2EtLgqfEdbrIkCrl%_z42cC`9Qd z)*5uAL@+E?8VaW%mUz+6u+m2i>MIgK^^b8mYhnSXV#US(bZX`C1b2OW#IF|diErz6 zF874MX@-~#ySNr%N+aW-!dTS*9uUQxe(qk2_~oRWegjcQ7$Y(b@gr3(JO+cZ=)bB! zy!~0W?|Bf_7TlCV+FQPFQco`Y*$$wf~#ud;3nouGf zhFk?5$n$pkMVYqIs9?w$KH)0$z)YKxNLY4LWX#a!u{wfPoX&~$T{Gt`*6J8cT3ff7 z>{j10QwF$QDhbrvphfYpurOsVK^AjJ*n2rr>`Ar=`6mLQX8+aI9K0yI32Y5tLL${dy%yJk0H!*|TL;A~q zJnw$ak2Ylwt0*)&d!B%cNfb09?sKWBj;a?ZO-IDj@bi7K^ZQ_=1%6IKLMjaf#>hbz zD8iX(re}C0WkmSvrS%KCZui?nu+L0Ql@}ph$1lu3yqyEtuFaP}*6psxxUmO(6LKdi zlNV1RK!wOPIVrMSsl}A5>nx|Y7wI3&od0j&PbD6OipGa)I86M_e|X*Xyn2m=PE+2v zPfGhmhet-~^NS$<^Rv|Uy+FL6v4q!2=x2*-4;0#MUrELJw1nYGmyjdmQM(E%3? zn|z=@nN{X+>d>HY3pwe6;Rs2Vtq9|@SgzL5$yU}krfaSGYO~p%7gdsuzcKMN3<$F?nM47w(6*bydGyk#ra05Mydp30S zC&KWOLt_ZRmMb07692E8NRvq6wy4B7)XZUUk8VhCW$JO|MbPtA3{WnCe_UrJrEGKA zv3}-JD}T)9_Eom6_W2h{NSvkX-Citv!(%J7nDP?EV&$e+pj)23%|+nCXrq0ijH^fr=y`@ev@9Z2$p^S#zr-#QS<1wL&moL2=H3YGGSnTxZjVKZ;-#xBS_ z^mNuY8xNlgFtr}+U96@YVP*JP7|cD!$Q+o5?XbuET)_Zpt~b9U0&mBDyWTsl_@ceQ z(WGscGyB#kIY=wWGZmA!&FbO1-8OvqaKoZ=>Hu^{6LaJVu&0dGxomiNwjP8o{_?vj zCQTD+F`pkfXZM^K9&pNqzFdPxjoT|l%!!nfZf8`=P5h@soIeXSZ3*Y9E&N2+cCQ79 z8B%bf1!1G@$OA7ZoTmHxNv=S8vl8frdQ7Z2^XZ*sWir$bGHU%h{>lqY6yOUnC&F{K z0((PjK!F~Fw=V|^WidyejBQ$A?8fghi{paa-EdcdI@C*`X_{I3J?^^p3in^XKa8QK zLTh7+Jic|gz0jqT+)4Xw2JY)S)ABuR<|m}T?)Sas&LZ)4c5?X$WH7wha4i{S&Bo?P zBO{S7M7nDnt|_DF0El@L16?XTEPl~sfnzBpg@9o~ogfA&TWH#8YE_UtliqxVzZV7w zWdU_s^LfL!o76J+kMyEE9{-IR5yedq;YU{oUtCgs`8C`---DKwf%j%wAr>Z7umri$ z&?jF#QW@0W2r@L1Gl3cziy59j2x)l1Y<`5HxRxxzlsoXSav+RPx)`dUWDd%}`1qov zji!~8<#XSUQdw~XXw$s%it`6CUrgTYiL&G4gO*9p2?3gHSZ3F2(ZtyJYHJI-%07JL z*2@GfCf0S25sl+lV?749kal_oXKQbhhxIx#zk68ZH}q#$rH3$Erc-=8aZa6H+XtwB z1k@;f;=D-%TbFo^O<$+VvYB-~)u9Dz{rc9Me%9Ai>JzO#xOLq=`5NFu{K4!Vk+OSR zRC!x_UNkJ-4{{*IH`)S8!tt{s=Hx)tA%{VViTUK-X9dF)xqTWAf*Lrk-dq|Vz zzB+#{C> zMZJ5l1H`JqO3ab?=VB_{shKem@k>vE^!5253FptXr6ru~XBUrc9A8r3D(7lt?AL#( z)s}QNTvdmZFl9X$YVOf|3|4{nG~nW8f5`nB!+~((fqrU_P^FK06EpFsE=piL^f{l6 zqG(Y&S=@Atljvmr-)|sweK*;)znKf^KnKBpUB&F;$?@8uIP61t3>f-Nb3(b3I?-L~ zLh)w?{40h~GLq9&?rs-hF~GZo>sb>CK#;jUz+|{|QNOcegS%SaIS-{+=;GO+C2XA# z+5dd8QPLY1OY31YNqLWkLXk4kP5+Y;(02@iVqj_=-feWKP74ckTv~_F-zXGe<&c)yYDxSFpn+%S;&ntwkCX0SFT>yUjrk3`H zax+R!EnmfZ$+EsSVbx*@{NwC8S+EH3=fsIpv+>vY1SJak;!1dtT&HCYf~mP(2f<_f zAQf@yp%}MOwMf=_5^6~KK#?n|VNQi}@cbBjWKMl~cX?3^LQXDe>Wr?vf~i~9eaiYx zd4x(k(8znU@3Ot-hRP@)uv*fv6;`8%zp8hQ}vM~z3SmVD{xevR+SK}b$Htd_T zymUW9EKj3MwaGylEX9M57vng> zqb|qyhL2i;Zfyu_68)x$v+5xlJqBFlN9U3-pW#wC_<(?aMLo_DqKQJeaFx3FdP?nx zgTk%oV`uPdek^e$yVua-{}P52{&b%cws#GK?7nOqa$CI-oaew7`zUa+=k9ptI=>mo z_cV5Zm$+Dh0Lr8eA2qDNlK$ALmm8eSqsgYzqYB2~#3NXG_Ft^xt5X-9|5s<*Q=Z2L z;{Gd64N+`4o?H+>*`Z)ye|qvp;Qx3#(78>*>E&_x!0d&7_PM%s-Et;cQvC9X-=Z?k zc>0yI{fGX~3>4R@;}gB-b>$(q_A&@=HL(UdNL2+f&4>}pf^J6%O48D3eQz0FQ5aT} z>dm6-`9*>kg^$p-+{bkL#hO*0`b__NR}g&YV1lffA>Z|Px)hqG)sX!`-Ym8nXxt`k zmez@l-=wbV4WlM?$<}Z>9nTb6Wc`UcToneLD=)iUYv2sI$*yJsFj$3Ul=NtXM~XU0 zj5Bj+P8GB50o6#(glOE(fA6*4x~}VG;v3ib@U!-Z%I;J4070?TZm;XfHH00r;N|7M ztC7Y;%L?kvPkn>;!T_$>Eu2tggb~Qe5;8QwXa>VQvMkKgI%6bh*FaU&DP2+tco+2a zb2t}f=~*Ss4v_L#u3Un-@<`7VYz+k`Uk$}!o z9tKg(DN!HbW?IOmwd8iRsaUh`*fzDI95;a6>Nsr^C-5m_adok+a)fZ1 zhr7#gcXxMZP~82&9fl8QxD+2S+}+2p;cjpD`@j7HP47*Ulau6JY=EkCjgf3rl`a5p z(R<-Kpma7wwzFfjE;LiiJGw-rg+tUq^u$o&{kCx-S@};wOPc7)Sg+BMXr$BPcPIj7nVn_c= z|G`Na%(_kh04lz*GhTj@(5-MdOxbGp>+T_*pKPjaxo;^_0GO^Sd+d%BvIaJXLvo%) z#q6@pP(&nIXRoOW{~H*CTKK@E4kLxYjxVk%TDM|2A;$L8(RwtG?I)KB#~A|J)1FGR z|5o?0v2?$#~7o2E$lQ9+IgeXT7a)0$o#24+Bljkb z?S>HO=1l`-Hujr)_XfUp%fD$HFI!Pcsq$4>wDN)b!)wSv!c8|w(sKM?zA~|pMUCto z@?Jv+!!?V_>$*j@2U#g%{!FjE<$NC?0 z7(E@%@$khj`akrbD)oO4NO^=El;Z08&8snCV8rAr=a&P|4ntv4LVA?hE=({E)7BU? zCnVC#|L}{nwr4s`x32Os;dOTID5C;~{2Q%=D1?`no+oeMtt4M7Y~Nx|=2(ySL^%tokkj^p>(H&?v$UuIPq z@9=tSgVbLVGr}TyxDhhXSp{B~1=zwY_~FWbIsN>y5YLX-I~89xte5L4jy9RMWK$ZN z7u0L@IGYnY#Golb14c8$FX&+23sAsBG7@Ro_+irOBR*zek7GKwO zS`DS#F0`oBaxZ;1c=`neNvwbP8GQU>4=t=iJCOBqusm3h&pS;6Yp#r2Hv;eL9Lm;f++E+t(i%q1Ne76kmn>n{jRU%9f>tlm z5UC2Tdu9rjI6O}Wdpu>_>~EPY$HdE&?ZlS z*c6)_ly#lFcYg05(cNwD{{GHpRq$RwQSchBbE@VW?}mq-sI5}`;foQt(jrVz&f zgXVud_zh(10ngn*{0Gf{?tecN2tN0z09d;lvDDS&+U<21(O3*+==UX*wTXpSO9tlL zSLJPg$J87dKD}gbs>$3>s`EvKmN0%{uZ&wg1xxY~d?z6ce+#ixo28MHi3$U1x>l;u zjFh@Hc^#y51168RK)rsJe@52=RsDJzyPOD*Pl_`II^oW3 z8+Hn~?z7;1S@qXCJ!H68{;O7XJ|9s7ywwKn3H82dJhbZv61Y`P^|WC@>p@Fjv2$LM z6^Ej_w|xuPx>G(dA*C4S;)04b^p!CYn*V}=+Grs>>u;f3ptzyvLFMQ4kqCMG^Gh3V zcfoaFqW=wNcO-oJO!M{S_F&8QW`nKZ=OVN7X?W?8a<)8KD(6hgr7wpIAamr0ZX0L& z!Cl`8o%N~%x|7LnhqEhr%j$Y_(HRbdC`Ja=l767D8A+C`Qf+2w%>RD%rO(St1McMG z3mvgn;K5GRWd1697~H^~+fuy-2U7Lr$%$RPixZRZ{GL?f&i*Z5@5B0SLutF(h&Cgm z7&4ypbOwL=p3;BNHC7;XRcTv%GJW-uQA&b==gY4zrE}1fJ{eEk^S+JHS9#8iez@iS zKCXJY+D%sJfw+qH7iBb5I zUxw44Eth*TVPJMZ;oOL|5Du!@;onzT+Rv7LVyu{&C*_~{&=VDROAT2B)d|HU@`m(| z3;ef8lz)G1vRl{b4ZI#t|NV}Qayi!!?3h@i-&#vjFfH(R7-P$MI`a+&_?D4fFZ_pi z184bj{=l_5BcgQKzniZ-qP~hinQI&i)ctnyp?C+V^ydgNv=OFqczQ_NyiK!ItJBgs z-=K*~Q{=88$3n)t?35}-dN*z!p^+S8-%}T4@BU&PJNc*Wd2kx{n#_+TF5{jAvaf*y zMd^(q5Ayf}r6==XFDk46+n7UZ57{qC* zuVwYiEB^zrHj;zY=73ray8=VcA!P9VopTJUA?epU=o>l%@dP5PI8R%q=B;aCd&KYn+l$=_x03s*KjX&JV3_loq?pUg+-cfckZ zJknHVO%yNs`$h(qm?;A{A>HZY##Yf5j-lSE3x4=_?mjbRA zZSYQmZJZ)C)Pwukn03lD)4MN>W23gOeW&MDLg$qK3=WYdWZD_sI0u6t?CQGsd=>Z- zw)i=l+rKQ1!it)kcf14vsgLLlIt5z}B79!Z&%3UBJTzZhdV`uLr}9_%!h+$bWUbxm z9ewH363D{Y9|DZ#m!w@*QJ5c0S_z}e)Vb-h{9X^!jX4aDAI5^m~wwl`#&}h3d-@*S!BqP-aQf zrl!_-e=89uZxdpfUyz)h+lX<`L1Av{l$pz4RjxB^P-rPg!aO>OErkiFf+k?BVevI* zXB37_I^z$0J+A|@mTs1MrSICg?)z7WZoY7H(bOJaL988yKEfZwIB`T3Ev&z7%E)&J zJ<`;u@^EhkoLFqCKkJA17yw^K<&VlUSdH^pZ?Aa?7V8otNe~W^r+vwDPvp+|)pM51 z(WyzhQWhG51Vf`MscFkoWGx%nVo_eQJcf#G8O8r$wI931D}f%9c0~DCT+B!M4W|uI zAB_G$JlE1KBjss zmy8xy&Z6m&$Td_un=cCaV|7@0ba>#(bH848YXc#FR`^3i=wIPaQ`y4yM(Gn;|{ zQ;tX)S4em>w%Cr&W;`*9lE^k3CwMEV;+odJ3hH|ADq`NS)*4+GL?7TA#2(TMI1??J;7w{xc<;YUcF8hmy%g+H(5r7y7K+GrX z=+k&ZdE~ohgsd^J9I^jjz z7>AMF+m%o60b4PamRu@rDT8M0hyL%kmYCp)=KEi3Qa~i{T=Tb=hOxlLlp98St)YCq z-oRJedH28XkDX=R#;Z`CHnA%gvKeejJx2tRe*8P1YK3XI1ibK_nKg*?zMnUBRc0>0 zoOt7QxSX>0%b@u}YTT}hGKhl8__~iqL9U}q^Pg|p{*_qBC`{XIoXlVtxZAT^V7FkXhe^bSmLzlh)|hMEZm9(Pr>yD<$Sz6iY@MFs?cgxJ-4jDLb%*` z_a4xhH0+$y66^$^qe>(F#D11Dm1D_8-(z!(SMEf&;!C*g$gzkizFep_uj}OPK1e^8 z!X&O=BZUF%Qtku2KdS{K04Wf65LJaxW>~;liCkQ3X&?U*Jby$>uvUoMM>bE77$sp# zlcmZUBTt(&VN4FT&8q)I+;aBok9*X3DHYyDNoNVl;S{EslFWw1?3VA!>VbTa=J9e> zFwidTR|u6#QE5_Alf^f?Ccj%dG{}-u&)Hx9H6`0~WA*2Z`?n6Rm~wA)Gan1|N)G}h zA}ooFv5bDahZm>$B}ulrPJBXdWZsR~Hx3l9i67na?`qI!m4?dry`%C&BafvE6hy;w^MF4+?rgqAU0vu=DGQPWZk06~o~K`bb=& z0(ssjWdYAYtFj-dl;%GtS)2v0kYe!GO@?*4|Gn!X=<+%nv+QN?44D1Z)Z%UXQl@wr zsf?!Angl;%P_)msP6ZBXr1zZ=HlL z?S-t>43w7ccqz|6c7=M1)p==&x&k#mg=t_GOzx-y(%6CKDjN7I2H`={bA7R|L+!tZ zyx+Gl>ad1B@ZIQJS&FSAu5goo0=x6J7)C9*CbfVW^riYWlH5QXEirMXR5?>rIb2Dj zhshJalfPIejT6;7c4l@R0zaSU-0-8CUpxxge6QXSj6-C@pkzA=}Z>4yUiK|9qfRn zF1D+PfVwZxgEXomcAW71W9K}~cS|eYt5QPH4K_&eFP!Ly%v@P9RZwPsVSQ*X4oJPQ3cadI zY)PY{O6{S`3SrNLuzF4S6vqwlBx|9ZenCuCC#Hdqj z_uV2Cj^!hVqPFkau+e>HW@e+@tq@$yyqi+5yd9KKPtXbs+a2~NdSkxfps-Y#z_J97 zF%~HpT%ZPxVyOaLD3G?ld?v-pT5ab1KqH;l1h{ zNnCF}1&olPvsCMisf>XwmJ>5+cprZQKTP2_ zWIC)HzZ#Bt4&>ERCEaPo6yaInUko`ny5~J_ho|cOyk4 zDOe^?jZ(C$!C?2DE$-YuPtWRv&UMPLwNvpC}5P#O3p9MEO-Y0HD_^(yEDt5I!AfzbO+im1s7TN7?CI1H!*h<9xQE%%&zqY&g~p)EIB5 zoc+%5DQvRM@)~RERrF+;XLHV^>$xGC;1mQJnf}RJmcp=qCA~mBUxf(6VkiMQm(Z6N z;?F*DwWXH)W7E`R+gvMr3uQgZIro;M~!flq7~Vi z$Gp^)B)80oLTK9(tqw5-BCRmS0wp`qO&^JChm5@v%uH zxN?$W8rMXUzGpE>->Aspal`j44&Jx5-adbKuuo@w76LapbqfXlF1}mOV72kNdreG~ zIXXz@jF1^-=jRT0*aUN>KI_Vx#Pyxcs^DUjRQ4b?WtaGP=b_ZNzaXE8+d#}7g_AHn+AV}l|T^Dc!Kiz%xK^&m&dV9mmyBZ3$d?(xz+_HM!-Z;BiUv2*A)*h$M&~O{iV4Z?{IIi&?Jm)PndfYAU7}0)p zqW_|QA7^S~L6YTwsmn*M?1wRoY?O#pl!SH0tjOE65t}M-a;ni>9`xabX{knsTk9B9 z+Dn7C@NH=_utJm?^<24@-i8SlWpA2Q^vil!x z8)8wFG@pSWohGJ<2Q7!fBw(7k7k9q304MEmWLvxJt(EHEK^w-`-JT~b|81R`OVXHe zM`;cX4m4K%irki5NES3DM}}$tlWZj{rs-1gJz-Cci^0j)&}+{7Z~lUA9aQFP^ExZ} zHQ_L;Qu>rQZ}{PXbC|9yd7PMy8R<$$B@krpa`FLI40=EIGn*Qb2&T9~irB)2-n-qt z+rvHh;~$wkb5lHcmkjU)047kO;lbWOt=L<#SmOMymmN6Io7o=hxHx6<9Cp;SCyq+v z1x&5oNO72E&V`-k1mNbv--F84)ZQGtW~Z|l8h?4x5)Yq*{?jpIGB{q&b-lEuA1OE7 z2AyU{tbmu|AoG{pMd_!*g_gY+lL`GtXu&DrF(!T+bKh9VID>Wh3I%_$`H!U9`PO>x`oz9of6+={x>AlI zf0ps2hiTc_vqU#JEz#m|s9-$|BbWBXzZ$}0{NUm(nhBk=BZ*3Xr1D+pwMBL4R&bH~ zJoKa5tP>_+_xIZ0w^;1yJ@h8-YNx$X>mXw^F(P=LrryD z#*U4A4k#)AWFuzCOE@~hV{lvIB3c}2eRm-x z$3<5+|IBi`-|yr!|JBu=b^lA$^xa$`Cb%Vx%SWuD@XImzte(^S zCtz}Q&HL^6_-v1YC+1qdj<2STd;Q11Xjh1X%gv6kFnw5?>-RhKXCb3)wlN7YW9s8< z+;G+Jzr_2mF^p;s6IaWM-kXoQ6Yi4-<*98~FZ20BNO$ah>?>fnR6YeIIyP>;cne0j z0k(tsD)Tt@kTOyO5E6EL*vuxV4+RFz{n$X3JGVKH=`RM#g@9$9O=U`em6QW9IB~0S zCqH${hUa}JB)yz9D1d& ztZP`K#5n!f%{i$3?3dB4am-uVIzpSFN-8i}$p*-<{pV#Pkkx9IJitY~kKmi}p2wZc z?;n>_pN<0`zlKVDyc=wb=$6<6krhZY=1FaGnh>QMV08^3gUjq)PWVG8$m~i?J)m(Q zjvx2z2MqNIp6$b^q)oVmQ~TJbI(m$+DZC1-=>vUI#whJk9HIeY@&t{L!JxyE zr;G;JO5=(ni*xO_Grbdisq@~T6Ul*0;fx&yJa#01+4Map&){ru-*;ckbTyI`5SpwGjqVB1F@M80S@e zQEG^0hJudVEIVH85D7p8@nSEBdwuN~YpVS!)XOT(-a~$=rGY-5tcjhMBf4P}ispSY zrFT9+-|b1-3k4`@?zkO6N$ZOEh#4q6O|?V5wgVdsyfCO=2Z>PF>_JB#gw>B-s?)wu zJBayd?mI{6Jf1GmnA(&k?BtQF_&B?+Sjl9sR4iM`XuR~PX-JH#9|gHgT#erY9vH!O zfl&VSn{38bUA+A;JFT%hOyjFooe>B8HX5`IYHV9O zk|uOi6eM?Aem5esR`32!FFjnIq-34^8Dm*%W&Tjs8I0_5#J~QL5b8Uei!$u3eUYE- zNTXWXpFeTkOeh#R{5>(uX7T(!JA(}#MNZqYibVZdj9`++k0)29u~ehiNCsH~1f1!& zZuxupf9~xV$&IlsVMT0J;5J!{iZ8m9Q&6Bup4>OdB0wKcY3fP9p+Z#DEb!uF^#I%h2kk<43|3wMZ8rOhlE| z08Aw604Iv&^{V`AGLTx5i-cAcgIT$>^>p>1ff>*Ocu;#kyIiSlSIo#KzbHajH~5a; zU3f-%Z%V!t0rl7;3&d!P54h@bAZdyft2M6$%?Tj3hGuXX{j>*uU@zg02_QL%41qOD+&eoddE>dR{mPrb0pS; z-`k6|jNP9{3f$0=Jy4DUdB(&5nf(!QC_++;xjR;~eK-V9 z%6+9zM(%qqraL^Ds&~XIzNl!KLitclO%Nnp!Ax#eV0$%9{tbCM@zSTudEIl-pMR~v zBhbo&f!Lp~jY>7KCKWRM=YPy;8OP5Y+D~&4G_kRpIGU=3CyX8$2{!a$*|Go(46aPV zMs}Wk@IrGoO3<@}u9!&U#^ZDC^Zu+wrFr_>mxDnESj|9=0zmMU+;0i;nnF~kVxUUJ z4gOpyrc_Eo1Q3b%OrvkC5H-K}=I*v8?hO6{1F+S0G$|1JWzP28(QbGM1O424rP52d z4GpP`gEz@>$Yr%pgEC%&KlDfvHA~@Ry1MLN0nEsXBzO@jL@7%sdr(ycIhe&peSlKy zz#D&6V$9+R=aMyRst>4?x&lE++RX*T5LU;vS6Sn8nK5faN;%7jD0naujG)i;*}c~< zJJ(u%8lji0m#EpBeI2wGGFcM~4_NiNa0=gaTZx~zI&wBus2in}+tYR;t6q~ zD%HZ|E~-a3EHnjXH^ndAvaA>%>y+++lQcCW#1XU+aKW`e2)+8T3Uy^Rl;^}9x`lLj zV%60;R(IC7r=~aSKPDp48rgxe(6_^ziJylXK?T{v9{+wN+IXYs8s?|9+D!XIDrs<4 z#k2-OM;Qg^f|3NYm=;G;zJ}~NK({&E@aN*B;s?D8I=N!9!yl&-1@H45zFkb}j41n2 z6^xARa{o<5YXcP-DiT8Q81d|=zmP^!lS1`x$#E8Du$!Uh@8J<6bQh!%u$``W?{&SX z&T8W@fPeu($j)<|8}T-CU<@yEfQx8El~(t);NY`x^ZhnQ1Z6FkTi`}qP27>z3AT&T zr()sRh6_0m%h>1@f~y!V+6*op*Dw48FZ_j~!U8I;?QPt$Y;O6G!%756|E}0EK9#@= z3QOIU{F?@#znx3|mSuA`M&l0?po@HY4jsJl_*=PQ_9%tBRtqAzJW^JwSQg+6Z-|yt zpqph=Bu=-?IK2E8Qc;DPQH%d{v=|00qKcr)3b+Hbl*}8C|Fu5mlavS$zq~9pEOV?7 zR)(OES2Hcti__YKCwo`oAW_O`+HZ8AIRbhag@xV6Bm9*XiHDGs@gE@J(T0Zt>Iy5V zl_TQ}q@m_=3N$IQ4Ueo)TW7Xgpfe`8LGP&b|x#Qx(0tpAx3nw6$h37@bRj63j z0izgHK*8)#I2Sr{7P3}4aOO3zH?wo^vwh!=JNG>Z4fM)JNqC1~OR^R}{uc!SiJ78Tm5HmPF$+t; zh(K#uN>h<+34Z={-R39cPwVuvZNZRSe{63Lu|dssM>f*U2_-`A(1%L~uuC~rr&%?J zDtbjhE6&dO9TJ|n2DM0XO|Til69DWFApe-iM3p6)xZ-j(`lVZES)8{W!Gn@~wL1&D z%sS%V3|;y`CYz>$E^3)OCPzETl`mSEEff#&az{=$E~jJ6HJa)U)ifa?@t~a^c0q%`sGK+9h#B`Bw`CL3GL4YU4>XV>2lIRnJBXZI zkkZ)}mvp_a z2Ru~Q@@>WpY>+(Um>XVxK%n2B!hG$~xqV*hr_x$xRtOKFGWcNO;8uK>hkR` z*tu{_#gpPYJwyW>_hlqkuq_|5;o(G@scmiBGr-e_%c3=~iO1W8v_0+SgfYum#)knv zz*%{>^gB5+dh(87V2fou1{{H6hs-d+gt3VaeTmMST`PH*^Y?7Z5?IGWxgUxrKd`Jq zD&SxpH`jesrs4-C%aV97EEF+QKZC@BnL$3Tj%EU|@Gt|e0OX1U1SyKPEbtie#~&{F z?$z+&FnSG^nChC~c8DiW*zfQnM3Z(2OeA9X2Pg0yV40cx?i)%cpY~nc`4&h0U-yEf zEKxZ|s;}eb0{|yDm$iTM(2|2459m?ylT#!Q^opmqf3uw+*SPdf?aCB+laTsP(5$qU z^6C-Xe~<;un9btPxhnKvlj%sC>BQd^Sb0WphNk#krb?9MOM>t?SfG{%+pV$8^{@K3 zgAj%@>|dz-Y$U8CY&s_O2%!l01Pt4lCVZIaNG_5)s{{at90^fT7nsfmc9sX?O&478 zuAKt*VaO)AsWLr!ITGq9+rdJwHV6do5nfoy$eFfHiHX6jv8%EpN(0jh`(SrW4!`eN zLp=c)+JAG7!9u3^qwoDvsK0YM&o5TKh}xjiI#>Rz_DpPLmM3ho3tU%=~6ZN+Jmy&%9klTquvPC6-%^V$%`6#+b8J!`eC@jephgyvkP_aqHsymctkH`U6T*Ix%^EQu91HPkbIN znHLb3B$CuXmPCm{#S5ajf&qwyVPP}_kzqpcg)wD-G-zby-vA^bKheY!c!#4+VZ{}A z#j{j?5@|d5@6HwU1cr&!~(Z}NZp}lXQ^PmV$JL$$L{6q)qdQF4 zCzr$ltH0#J2P?pQNe0dhN+QDA0%sFUaDkk^@T|2je-}~9;hViaoiD9sb4T*tA{Qb- z9N5^`(&TfuIYz!(SeSwkugVYxc7N)^^5vMgk)Hz+3dJcnp+eR%cQw0~(Gw`BD9Ava z%PVmzJTFW*6%-c+*lgH8gGEeWC3r*p3%f9|e0XgqjG=eiZ({lOV`G92YeMonfEjDy zsitFBo8N6p(QKEWTBU~H{b8fGgy3J*rY_x`FL1%W;RB&6Kc%)|SbmPf8{|@4t@e(< zv%gglv(!n0F>!hZ-m<_lK)0Z4F-!?yw^zRC2kP&=Z$daX+05a&CTuvm6!cW&jdB0s zMarV=>f$Rg9;!>%CJwnJeM4;seD#}{wNs|-vlpXuyC^FMgjcp@Ndvimnu8MfAABU!3%N0({?G zf{atBy;*MPyeFDc_dv2P4mnn!{7EWkg2|hp%9x;X&USG? zYPnuQDv)FL!^F7IDy%@SDu$f7QvA8^JHLh;-jd^76!lF_pSDaBn5fw6OO9>zAVALH z2hR(u636cNpkJrPwc2+1CYpb!$M+wiRFM{iBpke+Xa$lA6__4ZgGzQDP}d$9WRDIo z2SmWc0XS)8#7%9?T)5!g^o?5PoAKD;_?=M1&+JQyR zJ>n`;@=!cqELSIrvmkK1;?nCJ*i`1!(X&!_f@&+G4 zS4ba}H0uA)06+iT%QlW&>Hne@*eHr&qd4A<&4e2v^k>NIHQ;hQ;(==IaV^i;seGf)`|$xFx4-B4}y;OM}gnEv}4|`ZKK?R9m~* zWI23iJ;Jt+O);~~@K5SEA1|O!%JnYIXRh5B9)=OKvt;+v_kMt2NEO307k>8dklIR@ zcFsQ?h^@5)XN%k3C&=w6*m+b{D3V>GgC`NB6;ia*!Ze~&D8Yx(7oS>>MlbsaTk7;% zoe&*)lK$^do&ND_|KC~<(8*$r`K{x%KfEagcm?1oVL~9f!NN4NtAzEL?sI(Q_wa8F zNlnPQwd72A`;Ow11ofmav?6jOs<{O0jX(1JX4X}+5(a!6*v6tV98AsYI%2512Q}~rEIR59f z|BO6x>^Leb=%i0Nqb$rJ*~BPT604wzqK98VCjX8)eln@_M8qR#q5|2W_e$@+vv-{s zM*w}=5E#l@W7n*M>&Jtih5rWl#z!wFt`M3;Ac`8s$(IR_ThhN%V$skCrII_~S;PN# e7%4ZHkMC|?6E~f!Si}J6M@~vfvR2$AeYSq)mN{lN($1XMASt4_U$8; zm65o1=Y$|@g|ybx+Q z>@6m1b0d`1OXh$fz2wzbOo>nYKbl=VK>F-z+z+B?8NGA52^KVF=Wj&rOyw4gt%-P# z@jFFjws#uOZFQyv1>K#?cAYA2bC?zCZ|idkDk>_vJSe&k2bb(0|9E^Ro)%LJUgh4m zZ$AOO`#=7Xa!>d7`sc^Hf9mO#{O^7eK3jFev8BkM{^#S6zb_*oqsSop_x~R}jr%`5 zZHKL_UQFcx)=E(Y+ya{^Capr-I$0g-hgi$~L-wK3`evG5*iQy-+zHaMeF=*YrTReN z&kwNT5fED?Uem$6x9CIofc)|r3GLo%on{nOqY6okQNk=7eb;_ZukVo}AEbXTriU)P z3)8*G6K65MN>%_*AHN}rgZ7=`C|j2oP8=eQvm zjkO~Sw)UNn+fBbcJHC;D9hH|kuVU@620I$#-S=aEGz%8U@F^b-#xPNO0{9d9V}{s8 zOlJ{QyWbwv_Q%w1W>K}O>)2D)LrIUac6*UPhWU*rUa4_)6OKaI80Y zf>~6NLPCrfFMN6wUcbefQ*G}lPZGc`3Fa3Wm{;*gfUT7>txTZYGwjtlQMKUD>ISvg z#}dF}8QwNyU4P&PSk6opk9`P%E)#qwghrJC^VodY{n}U_7wiXw6kx~vFsC)f4qvcC zH}07j){gtIwNg&o38yf2Fu-s6I_ST~+A$7xL@VOpVULR;tZDPn2m7(>AxZ{+a^+kT zKIW4pXJmVvb>j#5fmCg@OoWlIY zz%w{4ESy(pv4#!8Qw~dNN`_nH z>Ghn3_e}_=LACJ4G^0kYS>R-AQq91pM|#b1*RE&kUt8N;Y~cJ*bnoj6%h~*~YKO6i zv9@KQ!uVeI+pCF!A9H&zL;nL7>`0Vo z^PBL&Pi!W)#@ghiVHL2@X)Avb1{>MnDf#F6l!xgK=Hk708@tRmgCw= zx4B-smR)c3ntVk$Jhw(KNNbd(Wr;HT z(v@vI7B5&Yxt9Y7AR0+oG@UzvIl@n3M48ZoNoge)=$z+0F0YTjvs~#ks4U|Jll z3%K`!U&`^G=+??+yP`jd&OX^~6g-^EvYtQ0dj6?QgX2+sO1Hi+m@ zbKSpFp21eKDz?&P%yvT9Iq&uP8&aV>rWZtZHZwQjC1MKax3_|R zi_q(`cwrF&HXIC^U!ENwsbMSS68vdxH_Y9x$@rMoHu$7<VJ*Z=CvMII>Boe zUbNICXF1?;u=*h$vAhViZhe%9&MDW`!Oa4q)Ij<2@)oMpg2@Z{<1s!lc}oeH6>^4y zuwM4#Cf4sgYVkI`y{NAn2HUo&8+<#is)^oTAn8L9GBC3`CLo92NtjFbD@T9^rY!j^y5<;g}7-& z3s>`h^*QNHG{wf`t{REvn{;w4I(-sowOg%72S=MnQLkv2Jb}) zyXgM-{B(3Ki;a}H-)+amVI)wscBZ?V&b3^O6qSu%Y?=@5yihMVC-d>{7Y?0$nosxA z(Mw22zMr|2&tRennF~%DdJtU1D3Uy(p}KjDWHME(ctllPgtTy}aX`^-d?Hn>*CC-0 z$G9bdAydEZ)s;v1->RImK%zJUwkO%*c0(8%3Jtpc+Fl{2eO2TUiVXeCl#_i*`8+Z+Wv7e^)rLG zcU9^3G8;M7hmhIoS|$|Ao+e`@dNIbu0+aiSAWjbnmHHmS92^U&GGjHh`4F$fAKYau zs}IRZw<8@V&o5pU@AZn$?Va>dUK*iyOx7;$n!eCtWqlC6v%PgqjnA};i@YfN{`b@U zlH$@XD{p6|G&6Lc60Q;v6LZ%({pz)=o2hejUaaF~B5CdiF3-h@h zz=;D7(Fz39KBbN`R7)_w)uv&)%H6h-Y*A>9pjHgjSg>VFQ> zzr;1(N0?;v1W88LKhDu$&eW4oSeF)kUq?*FdZ(>7tlJ5K|jK9 zE?pk}T`B3qcS7O`0YbKiic%r+c3j(xe8$EZYHi@3~s)Yg|K80$j018%CV_E zi~i4bcXyY@>AjT)0cBGEkItOlq~ER3W)-Wj#3Hk z{jS6ncp;)piRYL_68(&Ky^y%`7S+$E@0~F~yco7?IzAW&yKsZVm9Z91p9WCqkt_Eogpi%?FV~b1 zhnJ&XlnC7Wx<5GP`CO)`H49_m1pGZ`dDAy^-w`q-#hhXSO?Qh67EQ_2y22TM3Kt7aD5riB#$3kO z?ru??!d>Q^$4z(h(ca2@f{H{)u_+L$KK|6v;-gwtL<% zOTihfNLhPJz4z+`NLWx)yp7$K{gm|KMB!XX_#u9O@fRnN+S~czIczOOA8u((%1&oi zcd&KOQ$_#jTKfiX4!l?Au5#A>^7YG}tph-vL=TZmV8igf!Pgqb?*B(ziYxqwg&aK_ zTSLl2tb39X$iN%Y%Y^Q^1`e(XVR}H_8x#E*j{o)b|Mm6%SABi5C6O_JSrNbdhzFF= zHBg10O!Vf!1Tv5R836Zrh~aj;{Mv-gGXKC+|I4QRFPruUqyJxH(+G&gMdRf#xvwl9 zvV|hM0+x{?tCELs&dHl9hAB5Jf#MF9GhN4ia1;d}416;f$H0mckaw%(k9%R!*LNUF zeOES>h4xU;83gB?Sgbv_hYR+3Gy;AQkJ?X!JuXdS~b{qhT zs{TU(?71!n!_={?=)V2@P-@l^azB``hU_blp)&imEx-puyBbi5@447$`S^; z5S+ORudm!(cL!5V#DHB#BKWE?*bO%ZxM!;D6YsS5OqYp)pEzm|aS2;pF+hpp?XD1n zK_u>qV0qM?@D~^?NB@sj((rY7Y*5z{wzqUf4LzV zv-ZvrV~01`!7&=5jNRI3z+v9Pc*ij17r}dgr}A>22{DH4+kXX2#gCSu!F=Mb1*R63 zWc@L9UIadQgQdI&N?>Ozs^_Fi990=Ak_;K6Hby(MuCmehz-s(8;Ze+l@BGxY-Zuv;qzWElxg1S`h%aiYL- z;ZJ;+wjEUSoba96o;)H9Zmo)i$FgQm5Mw@&Nrw*}GDk)4xr3-KtPdmStz*wHyDx!o zIbDm=%NRRI;5T(^Ip0ZOjZBBFxKqsKMS>-laZ)yLa+G1K4ICC9j>w{-!FJt`$N! zi9Pv5V3_Woef&SgG>{TgvT36NFWkD?l80^i(UYBpbvai@k&SieBNUD47SkOco8De| zMBw+Z3HvJc2#ez6dV&^H$_@CsdwaR8FTK<-%l{G*dJY$}J)(CsU>#I2?@W($y|_>a zX#@;8BlFgGLd;LNySu?(?&xb`A`$_;zX$xPxh(@Vr zNKn9bjZ_B)KyfWy9&bC-m0>w@mE3YN4Jcc=Fdoy>%7T*ET@yrl&RTyhm&Dt2;HM%q zrq3L=G-_O{I4n}d=y&<_BYe_VQ>lgZchk7AXZGK*ho8AoJ+3jiX1y2Mb=-req83NT5xFer$+~C<_9bE04;ux;JSbzls+S^X0z%OSayW$ zg=kZ`*sYS$P~+jE#rlA_Yhm7x6w z6+VkORUYq&&RjyZ2OjBw#F$37taNs(Z9x;!653HR;DmamTPp#E&2ckasGcH+ z%&hz0#nxA53M=|~jap=&t)!Kxl0uD+e#det5gqL+Y?eO)EUy*T9aCX@3WUX59`A-{ z_XGQbbX@aM+C?3n9(aB_ZdGiKCiH~sNz^%3cl z3`1Z2`bX#1f6cK$KkJep@l;!i@%o3GiA_9X_%6!m;TbnJM)AbWtsoL3ya$T2& z<9Bacn2pUZz0rd^GxI2H@%EU=&P(I8VwFCJF>zQMd(URk+a7M4Lv&1K z8$W#5o?Yh6&a^N!~)=$LaHt zPP3PCg-U^D?Dl+l0H1_?OviB|cA?WC>Ig+##CHn?ncw}I%tc#ZFbB(;Sup2n0B~XB zL5ld_$IAaEPO+C-6r+8oUXbk97qqdC%aa*!cxTIAvZ7je%TGDae_8-aeoQCnQ}irf zxUfq>_=Cz5qxs&9QojCarQ5f;G_TSYWX}KmO2=Dxcv)rS`#b5eoru1LWb_d9OY3GU z6K}*b*?b5;Wp}+oteAA?Gr8jHxze4!iM41xO!yQ<0N}wrM;nk8jZ*A*Cw=(4hTrlC z6LsUn3vn0kL1;tY>w=iMp7GL$t%R>si&PHbXJI3P2{)Ew9f=1uo1@<^5)k42dux>j*xP7>sS8>bUWEgm+~JKu%v6|TQ2lD&B;ReC32z3 z$Oycsp|ZsDBh0Meyw1-Ck)7Az@;#fKy>|T(J7d|#?Qf9IF8<+D;X4M2=}P8$tXc(G zOOvf~W+iL---8lKXa!n4z1OED%Ejy`4X;;}-%3&m;q^|_%x~)b7R`ZKt$zgsRcd#D z4;^jOEq1Yol)8qF?qk(VQn}bX%T~I1no`U9B_YwW>Zf}>c@Hc<;ZaU!x%Cz&^?8`hI7RMU;M=yR=)pm#-Pfd!C zbTkUn=QZm&hY-4BkxmM!CF_&4&{gqxR#GcruG6Lwy&TKL9B#269euz!HUT+ItU4t< zo@3CTw{rIWL)8t0{E?Q)FurY|Y0-GTeDO2&`ti#P3k$VYcd?` zieRfe($1NY@D|vumm0)viNq&B=oK>TW9z{&G_UJO3l(D8xy!ZBsa@)?=gdoe|w!P_@BIb<|pee)meSah? zBQ3N$vZAF`b~9bA*QaK=yHhlHztz-mdYv_$o~^?_j(1+k!t`LLS&r#hZd5q0d8EUE zRf8y(Hy0V&u`sU|;KrjL?-m4YK$n?fK8<|_3#ChxLw%MuEUwq82h?l>) zs8JoxZ)IX9xq(?u(Kbld>f}vGG9;rz9?XpLZRpZF(@nJdRo3n)gO%w{%L-E7D(C{= zEoAA!*7zB~B-Dob<0A{WN^oYz=Q0}Y+{VhtfU&h}@S!ZKRcBumKq| z5b$tK-h-k4?!^tu_2q!$s~>!&Wwz^gv3u*I|LGx~B?Q=Nv%(ps2tm6yoDG*b8&@h! zlJ)CCIjlzIJ8jyv>Q)u_266Kt&<=y#$Dk`C$E5Q#1N_-P)`LpuMR#Q6%c}R&vH>C z=k1*1RBmu)Z=#vI?n-$jKzL%sG*j9)Tcse_|;3OgBZnL}QuI-Qe z7yDf|Oi%Dxyan|}qy){%x00%2^}8c`GHu?#HxIAkQNx_he!znk-)UneH*5;YRok=RVXwVOX{y1Xa5poMv*|Uyz0#evHW43H-I91C z*0eikw1_1&PwWsVRzORpGmIcY1fGSb2{tP5j~wG44ZhbT1}i(snqN3uP&4i9H0VX? z`vr7MXQ^*aq~^fJHFVsvL0=pp($ii@{(%fG_sn)Q4`B;*9z zHm$b=H#eZCFp^$zh|@(SLFo!;_w>4`K#rI%RAAOyz!cp44l0;9DO0u}=}+nGt#i@B_eKl9Iq4127t)#guQ{w4SrZZdcCP)EB>GJ7w{X=Eio%$CE2h+7hYVyP7W@;c} z2^N8bYSf?)pn~Clj;r=tr_(+)SG{DcD_gd01ZY%^`^ashyI-Or$*Mu9eR|yJdyLmf zSYFHJR@E?iWxKY^KR=Tr^?9b1!U0;-sr9Ke-rTVX&R+%A6L%wj#(Ug)e28}VAu%g^ z!&=k4+<}yvYQZ0_Y!pI`P)GSd$PMZMCRB^7jX`)$V&Q^yZqJHz2YL_=lRRHM&KLlM zy49ryYlF8XWP{7?I=pA6GD$%Zm)8u?$J}{)ZESJuoqDD|(|F-@MvXk5eV1YUi32nD zHr(2Cc2`TBhCi<2LFG;+2-F{~e;Uu>=Sf-9%YV}L9>9lS1x9CVmFTla+n0>Z_Wr&g? zp=L6@M{)qY@P6&mDoPS!?k9qCMT@nRXwn^P)wi=^&Hdc-@IM)6L|u1CR7iRwM8vJ6 zb1k-T%sRJAj;&btVF@Ce5cD=@(tacM{Ly+&~NZ9smY8)V+)y=`JIf`>v;Qv-^%%&;M5Q9eJt3m zo*;;7l@pg1T5?=&{FxL~UkB&9w%>GT4ipLcyzly`6DbOa743{CS&Kjf*xU0k`3k7S zk{93RvW%^tL!mBDybq91a0Y=Q1+_f|332vp`NQusUynWB*EVIq-@Z5jF_V^SwY}jb z{?18kVw-~4l-fYHj5NmikIk=3mfTTG*x9V*YzQ8ZdL&A^h*YX#V!g3(g~ZD$w|j*W z1P8eITJFg0xFQH~wzn{hQf1uqYeAT4gU~N7!B5xGgHYfZm6roM6n5vqMub)N`phKf z@>2L$I=3EQ8J*YB=*ZdR=I&tb#tXMTye9n2#SXr+E-yjq1=)-)QSIXo9zo*6LQ6`E zO{6Ir=EiL+%M|xXOAiT*)8FU^;mh(4&=Tm-+MHYI%+nf<&L5q6+m~Rb8E2TArW5G zmyKlN8Ui*!0DJAm`gMF#1MZ&Q&eTdxR9%FZSAp^M3jJamjdm%thXDjME%s1qInDiQ zX;CAZwdha6nkh9okMMWa& zQkV@9cS1}E8MvX-5d(_Y{84K1R95XGdm6D~7ma?RQw8M8cHI;8^)XQAy@>KI zruLt(+Ockr#}DYzX^0f6qj`0hf0%4>fhvW~_Z_%wu9R_JqPcXNyOJB*h544T&xT5y zb8b5tAiGl4g_qEPm!OFnp&#vUEqF+!p=>&Cpl&YNC)|mU(6V&yV^v8jM14FtIPvt3K^ z=)u|$&c%x_gxBv|73TMyPLWpjFaR7{7v{el;-46lb&SF{4xch;AJ2G$rBcA0k=B*x zY3a606uP~ilGu*?z|zHAp_cqbq_ld5P0H55`)810K|U~B32;C|mcCNyc<0UYaCCN(JW@Of8D=V+t&sb_j-AQ4Es^3b#Cm zAmCJQFM*K*2M=-OHclQAcUheCXArODq_whX`EaY|@}jcc@yX27{11;*-P-%%hatV? z8s8gTHdlX+;)(sIXo7&rpo;R73W8cAGW0=vSSh0zm+MS8JNjW~N)48G{+k`}7yn&( z)DHfLNeahQ9s%#zXqtjfkkatf{&)CVUcQ>FC6$rlzKhH3T3`nCR`i`MHt z_Md7t`qC<6nHDJhk{-=b?*Q-0Yrhe#pD>&)Nq53XI2oripWc(uepB9;5!N>VR`#}kB>!q$l+4^cbw(l8wXKM9gWUu zgbGAq4A2rZZm)67C{~z$!JeD4p}wd+ZKbiLQ=ET0$kfLm(m{#>rA7}RFY`aw1`jt+ zn+xJDkcUH0GE=H}*RJrF-4m@1p}+2$$5+Q_*krSIQy|kBUc{8uAUHSu&mahQO|s9H zV3?VY0Yzf)+)-UIr(KqhF}FD>ihJ%$pF*IgmmoO+fuBFVG{q}Mv3E?6BZ(g=7Uw|< zJMQBX0KmY*o*4H8d&eP#uL2`eU}mSx!d9#Yu#Y@=HU^3{bkU4ZEUIWMB)y5D0Y(egMhSeEgxX(a!X z9`pzByBYkW20YW*!?~yRggUjE2Yq`K(vY2Z61;VkA`W*cX9(eQ+;%o}fbezE1(rGk zl>43F^dmF5{ck|a?|lhx39Fm^t6eN=iTjX*%H*-A>qGMLa*MX~pk-aB2v1H+!Qyqq z8)k0Gs;Mar03rS6(!ENPM=>}*lGQWI2jUem6?<6#G>(~>6cA~`D+V&%vOBxpfJ;l! zmZ~Lqg7|cevO?r#bztG1nZ!CQj&eX($4Y}q`ul$1@B#pJe}mpl^L4y6b%pK_KXUNo zuVl^<>re<(hZsbjFWp@5$xpTa`GdoC)1H58so5pF;u{9zi2gN@2|_?{?RL>?;`CvU z@tLV*^c;_!Ol$u*<$w%)X4Ob&1rb^MP-nr^$ipLLaXQrN4i|JvfXZ;Z5MO`4BR$%e zRR<;3pT+ue>%x(u)iZ-9cYW(=KxR~L zmiBZ-`h#rNFbZHfc?HFI&HGHYhoqoXGO?BJ#+v-EL<~fe?p;Uqs#A&+Bqk&-PI1`% z$)75QT=ffxyFR{Tq&k&h`ki*GY`_*2yWt)2gQ^j{WE;6E%}k(%!*q1%;ybmrxsM7CEMMQWSx02yzo z9XfAa|Li!6JY6EYCCq7X52B&zh74Rpb`6}t929yQptekw@+cr$JqZ!@*BLg&96O2+ z|2TFh($Xz}h+P0MCkL}j$N*YQ?one4yB1~X5npqN8BCWo)9-j7^Hfbx@-HR<)xe+R z@nR1Q(5u4=e+xC2LTJom=dtG!iPH1`jMDa=Uj5FC&j|^jX1qWvV9h?L`Sj@7a{BJL z20FLR?=7*VsioVFH&h{BiKY2qMqcT);UPam6{V2FqI(wm5IFpCm2ZyQ?q^kDb~&V> zERB@?z*t-d$vo~8UEa@7K_Co<-s=3IAq~+&W_S)K9dq7oRU?8M@e15mpx?JBPi6;0 zARAO#W{NZ2xoL^ZuWu+^%8s;YQ_sKX-iLY195CQx#BF>;PQ6Nr?4q{_j0OJG@$_SX z2IyJpx4M`x(8VV0h!f$)hK{ahD16uCWR&p1*e{*E_!g4^muXiEZaa06mgTpzAzVkQ zxz|yWq@*k=$>)GGa6ZS~cz!SVf0hF#M0@eueZ+B-af|TvwFRCc(EulyGU`nD&~A8s zV7ZbR*5>0v#lzaR3{x#N&^SdwLHYs+a(a?CqU*>knFG$V?NcKUa35Y_+zSo^=2LyU$Fb-Z_4CY4;h=)UIhP( zKnRDJY{@O8t{MT(f+IKS*Id8IWJR>=o;MQ6!i$`-FF;gBn#cad`;8X=UDyaL0QyYN zmRuMa8`M@W@__g^()c@?Sc{-e z!c3qw5bD!R&}osUBH^E~TApmx4;qA4849`+4YE<#d6%Ea%-h$?97OOE^kjc$M*oq) z!Xv-qrdC!3LQ~RIMlm(k_X5CWr?5tGr;tc5Ie0*pEqt#4TLff<%<^lK87@Ckip9y*Nqv47V#r{ zjxvCV@CvQO_29on>+$}|-{EX$o1^~`N+z_`I^q@S)_@?2wVUfhlXNBucLPBQ-NZoP zq&gD|&SB;pdO)9Ly*Kwja0?4=2nA5dkVO*~j|J89x~=;Tv);OdJf3o;{tnk{>3 zwgLtYtAJV`8(G@4dV^9wy>2xN!>{u;TB(X=U0I3N6HStUor7r$+HxhL?D`yH?)|wn zdjWbN&>2DhuAlo|$#VuQ!!*GzZ&rc-y0>Bx|u2#?F8k0ihsWg1&i4d@G1y4WjuM1v?ERG+ABN>If$bdxwvz^dmk{qdL1a&8SHxqw3(k+J zaI*3J6bK867~6HKkXy5(w|1sCC`NGNk81cou1Y0JT^^NV@@2n?M#-p6C(iR7dsC)_2|SEy#wh z%;)LXMUx+r-b?$PvV>{v8X(HAnRd0qfd4ZfeAPA)68@$1DZ+c|*h-BL1ij-Oo=S(1 zo@d;@04|lle?&=j>m;733()OH+EGlk@Vc}PAl;eL+37M=3oan#w~<>wL{z}cf8hUx z@RK;uGzMT(Q>q=cXg3;S5UTYQ$cO-dy2npYD1`HU_q2sRId9>PHRXW1K}2AG9DZQI zqLLkfk$tZ7nk6z=9Saz7ZDux^v^P7?Wvih1(yb{dd{`l`vT>j^vyB47UDqdo5wBU`fn{ z#JX>)5DxD7>BqanlVO@K=56{vc=9Gci--s4-W6sF+mUu4AHJ zsJAzM>iU5km6Y2dcg!}@Q{Z9;4wDXc^2@FO%SLksL3Gp6^C3y_fX%^3ZwutwfI_n6 zH$UKo;O!$VtIu;lE6s`~qwnZt5J}|^JR}~53F21=4)K-sa3q@|)x+pmTpP05Vck(T zzQRtor}iFNo|^p(jh)u%UDmsnwIaq$yln*`;H{=?;3*HoExYzq@E(8PqmX_U(#G1& zxB4t<&F-?L^Tzan6EA@$Zn!uENu!HUwIw7+d}QgC)EJ2fj)On&g@6L1PEWUG85}+_6=nc%1KJxJoDzB`qtTj-#9ds7%BSzhvrOnfeKX@oOSft zS7iZcFB*$U^?ph~$Is%obca^(anZMGyayo;mDDdRO>hYGlLA~PUL#4`^CFUzvAHO4 zvk?f)L zRS>2wjeSAx6cSDT8y{J`N%_aQ57|hchmIqcIlu6rCwV#5_2l)I?ih_66GQEiatw?4 z4H4MS_HbH4XuWgrZ{!*N<=^Gy4<&|n8$m}W;KmYCyyg*r`s6Wo5J(}RY zdEK$rjDM`kL}_b`Q7;fkb=?j&5k27Gf?V4$>>M(7+!aW%ZNbrJ5kx1gYA-E}hM9-b zVhaF&c_?yq>jmFQ?eoATK9+rh`EP>k(?1EaZHpJRQ>ES6yS_-2 z1ZePke2FB4u$JepzDw1sCix|8mbvI~y{K^_FPBoycZEkgJymD|vL_7^@ z?zLz%(gg6i2AxwThz^7%=Nc|A`Z}mzg$AojZb)5riQuBe6()3a$-sN5=hO&_aTxcw zfvI3$Ks0|4eyh?Gj@dB=r51$RP97oR1 zt+(kB0!S%FGi!gb=XY=<5kSdPx;t<`+i=h>H$b3%NCT@2C zbeTz`Jode$38hmF8xPUZv#68YMz1@S6AHJirDMEx3WgLP@sZLJw*?f~Zlo)9^KY*X z?Ml!m6XQd-ZKPwi*N}1+>HoXMMc@53+uQ8z<=SmE7~;j-WATVkojYq}7rMhgxp01a zBk4Yf@AEiGG;XTDt`}!DR)0NC{)E-W%}JgQC*QmbNG0k{e0T4#QG57qAiGXw6qn0z zQ15lXw?iL+$-eV*m$3Y#669b!(dV6fC1U&Xd8+DI$HhgSVYtOAG{S9b<5v&_l5ao| z)TWd=hFQRzf-b0H_2UPCG&k!@N5nW|bHXjXo^&otFF}`E({nd@un)Ow$hO8XY~9Wg z=)f*bCqOV`kKWsoO`3k9)U@#6FNLyb0nq?hT-P}l6CFE?LX;Yk;@3z?<_hP8t%%cv zMU?Cg#sRR2@G4;ZF6YD?Vg0Hzdz=}SwZ@~{%e@A7<{Y8Y-+nN-ciEifpE;^_yrnj_ z-m@_}n?GEChgXku_F0zmTdTioD$8AA%6{kJ-^jxa0z@UvPh?&74ejuIn?0j-6gJ_FJFpFv`iaKs`Cv}aGc-huy8Ig<#g{%w7_Aa}b=b!CN zJ301SkLE83=etL}nS4J1--WkVqFp^&a;2CC8xIaq=G^!ymp9Z}wcCR^pR8|7;TTa@ zTmPHFs=Z*hc;Pn$dY617zW$J(O(W%9`B1L&LzY+Hpw7eVWS_Js!#R;VSnU;3RLob^ z)t;ik4E#$np{VJp)KtZ=dvT_}tEreXkU(QQV^ko-Xo{K(wHcf{iZr}BH90$t?RI=oXsr`<)D@JyT^JkPl5e`=2&NAo2${R17L3U1NZWSe%Y zu;vdRO@s^DsKlS$iUP4xs)OylxxV6*7jpdsDQsj@&GCM%uJ=zutVGTm2llE&di?$C zZ9}a|s&XLWxXT`T$NO*07rZ=}d;B-Urjc1Qw%aPKph|jPpzSzuc5$#97Ae^+hwQpmlz_eP=)Q6(Gcy zqqmVe-H47~z`fa@$S9{ zB1hq#)7yd;(jiN2lh$mwa|F3lMGr*V#2Gyj*|DyP23=jJR$rZ!tEEY>v17ml%sfCv z<9*>uNA?p8%Rq&~$_~zj9$ejJUm@eZHDJMQaz`kpXy7s^=k`yOi)k^h$EhAN-w)Y+ zF>CbECdw(Pwp%@CvdQK>o1!w^i(1^Ji?z-1ioE7l^u619 zyymadhi&t@lG*>GQz@Bil$nYs;g?KH^r~MI-n;*D)(XaOETOWkh8Stdb12N1!Qjzb z#@~)}7uXi6=BIjUFg~a4&UV4mYZ@iL!~boRge~e)x!7E}rE3B|6;$zzsNP^mi4xAl5**(oPwa zF+y_*>fwp#L0RUAGl<69a0EUKM7mW7qa7Iqsxt8#J|&6ByxMD+S8MWo3iWpojAv9s zEr!-sc_+xQ9OAQHxScO72<-Ra+8Bm4k5a|xv01}E!6$k+bi~J;48qsI!L*QpbQ87n7-hY%XdQodAZ+wqB+N`$P@gv;t;++5+}tB`aHm|8@@UZ}>a zWwlb*;-ZCW7U|a5WAkcCgY`ou=2S>)lQ;lOpemgqZDl~ok1EJo2dVIi#2+e?w?)57TYM??# z|Kf*2(+u97h1@;cq_b&5Qn&#Hx6o-#70Ath{CbMB;Sxejy@wuQjNq^8Hy6X)!hRym z72hw|?Haf3MLJ|?bGYN4A9wDBsT%dAvy6^m8QR7hR3O83a9RRMhlyQw^GfliGeIo7 z0A@zKT&xYMg)^#f>})HGgP!)9@Ai*YIG9=!ZDp$fmqxzZ$! zypXZhbZVEw>`~cKHP26#)8Rn?_+lLTMJcXzyB*X7@8N7kzZ!PD=qaEk@O!?2{w_q4 zBVp{-lKVUca93l*)MV7Cdd3V5E;?Y(!kh|TgENFdU67WK#xlx^ES-1?n;rn=$zuh? zS;i%=!+szko)94l#y@kKfV6AtP|&&HgKHyozrjf@3~S7OSVG!K|I=7>>oUNuDnu4q zBl*g)$8jp<`p3JHhV7{l14%tM9V#fqs-bWcky?NIc)1?-fjm$s`gpDGvL@96JO2FcA+o~r`p>I*-qX*xgJT+si`Yx9V}u)J#OE}hXq zi#F5vg(xV-a@I>7tzuIl4pt+*SY#>ynaLv|N^)75=~e|A{yYp}A^GQ%kxmHDZ1wG` zEZ5ZE(VV^>DbOReDxt+JNi;9{#mwCZqjy@YD6283{a0;K#<+@B(iE^FZ=lT>s^txZ zxir-okCl9w@y!gIhamX|F6k6#%z0#1o1IOzw0i&deN!Ii5C+I$B>^V=GmZ}UJljgQ z0EI5nGEW{&O!qWHX6>_F~YR0Ntqs&v=V%OJC`vb}c?Z!+j z)Wm&EpFJ|Q9Y&5L!yzZ(#erV2ICx<}9p$@IE8Xeb6kQr7&Sn#SsQY8SMLuEK5%HsBnGI3)Ai zU~jIJl7c!eq{3gjaJrHia@fbr#*O`V45IClBEN-`LXBb5eHDp_!0=35BIQ!eX9mjbXX&VoDMt($; z-VB?|5?B7@vXl&=8~taJuk^r#3L~PqKx@LSfElJdQ&a89>h~s_baHzveG*wdm|L%a zamMV_1QG*4yZgiTUV&810F9FRe!O6!Wn18sK0Z0Dj?n^$u78&TbkVR$#*wY@08z`q zwSk6E&~;wo=NeHgjdxy1caOp4G9tv22J`0hbgjpz@D@M}%OVKnm)4`SAA;6~w4;Ypaz*8Y4nr~*vM^X0xe)TmSd4ewD& z{(=BSxBR7(S6qbe8U+m@3Vwudci8wnGWpl7ZZM>eKv{?)BI&x`p67XzvI-!MU=u;CtOGwfB&$Q zgyYgU10oJ-SSfa@rye8`Oio^Xp1Rh+O3qq}GV*6WV^?R9+3E;taNdgvsrS)5@{ zclE4r8+i38r|BcT9ww@5h@|ToOX_aR7MhHa9lkyuNaD>$h7_~;wiw*qIkCU};NSl? z7Ym}A8iC#56(kyRM7r1%teWRwB*94Yanx(m@U zq7orQEI^|=UnM7Vnaj9M-up0JWR9?^TS@+H)!Rx6aOq(-8J}SnJ~9cjI9;n<>?jKj z`KCy^WpaS;+*VG@K*X>DGwQQ$k$?;^RwY7TMBjH15<;qgICc=p$tttStDM3Wt;r<#k$r4&5)rpt)FgJ&6uR=lxl+{lo=Vy zNBXn55sy2%q5PHDVe~2CcL3Ggp^rxkklsTK=w_)>)?#i0uc5T-`-sZewgxXxp0W2e zpxj&rr>MJT;wxrfLS~8W*VYEM&&Aw8!-W_KsT*THpwRWvaoLD}x#fl)U?N$Xg211X z2JOp?lRF}&$k-fIS0T{9J+yNv8`y7z7psD{O)dm%jsK6bw}6VW``X4I5tT3)kW#6k z1cnd`=@`0|lu&R$K|;Eu6m;m4mQ)lFNktk(8U;a8Qb0sfP(Vul`=HOe-rxWIVts45 zo(0d+nfu)5oE_J`_O(mjZQb_+wsIS|sj|06SHKk`;2N~uRntGZL8DDG&{KGjegyD2 z9PXEbRb&UBaCX~nq{`40h)&X*ntcYjHFv&R9irvci3|~_P;%b;8srJm@)PmDCCtpQ zPg7*r{rvvx4t0?HH`@|?dYB%p{+n%W{G&S19c_mCBroiX&l!qRtuKT2wft~b9supt z;D&^u`u^^JT$b}zx-0%hnib^C$>sQdmNJ;W%Chh5>UNG=6` zA@-p9>Kl^8bGAt@?1n#WrTnhkAAL;N(&+}nd0?~B=vb={vQ&Gm#X*v0bk3%q>asz$ z%OPfQk=irfm@W|dP=B2xDCY^4Qo!!BnSe7K0|Bgur?@)THFk&q!ft{Mr6ZBqNsAFl z=Xei&t_!)qEc%lK|Mx5U*(Y!#^GNk}-1)sB9vLAEB0rW-9$346u8QLB@41Q*Q-iJz z_c(-w)4ZuO)yQPBC&^0LpA4@v;TWg)^JNPavxuM^ z5U8CjG6MB3H$-KC(m5=otM45 z%=`NCciz}_50rm~9y_aI3QgYKR40*g;apz3>FLKx2NE%`>ttfyCb%y8*b zW(m)PtD8^-c`)7(l3WWFS22r`Di3IW8;pc#DaAKxWaioIWw#He07xLQi&kJM@N0@M z1%#fs&=qheXE5^R@EvZlUPs`J7!_%_@i`Pq?L9U+~2X0^RjyTf4- zdNTSTZIgaBd&ylb!a>G1oZNW&!PsEowv1a!Q#`!ijta|9@yLef9Bhf?Nz@3|*qME~ zwdy3<@oOM$d#+l_%e`RMGv7V6y04;d*3@h9<>;pAY(DMYs6gC=H{{bp(cf<7mp>Ud z5RTsYBIsKLG#OE|;#-Wu=b~)BLD{b)R_}5PYNo85j8^4crIP>%C8cZ!<=;$Aj#J=u z7_nco;!Uj)g9gLqUXM}ihn)0g*unamPxWV@7I_>Re)j5LG<(dt)Lg)L`WQB z90bzH*?NcHX&2AFA(u^|cW55P98nIJJ!%@mr9O0lc%A5k|G_5Rt0P|Y9cZeKn{=Mz zT;p_^mcV#^n67)0&JG@>6f_-xuK1BRm*bLH-xQR$EulBs+1nkcQYnSCLym3b6T}hr z@uFMy_~>&fKoHh&&wDSqaRyic!BUqF?D)bWK2h-HjbYaq?)xx&VA&uNgRd(3A2IAx z#ZZQvVkN=siJPv2@>J)`x2CaV$+-E(1$d*q@^+535t;DD?&QuKh4;7*y~mtsXAJv~ zM!dP%i$}d3?$HL*qX(!dw@bRBTDZr){*K%-<>-^e2Dv-%tNBG5-<)`P(Ci=WI~Fm# zSu|vupVU3QvuG$54`z}E8DGnz-beH+1rNcUT2#;QIryYlKpE6h7&?hZ!zWG%r+Z~3 z7?goMsvt^7dmp6>kR*M>S5Q^l7!HTE%_c~NaN&$BCzig=qGc#F`&&>TnGIRsJ1ZdO zYH4$0f`|dQVa_EAZ`PzpqC^3e2l1+?&(^QtQ4ADVaO(Lv-46~WP88m~Q4gtb%YfR_ z+kZYE&d86XQMMSH)W=P3nI9|++x!JO9rM7vE`oATrXxT0zqN zF)_HY_s4010z1PmOHC-7XZW%x;eK|gC~~FwrESVBdqt`3&OcyRoq|;Eq1s-WtF&Or ziYE6NXPqH2yHcrKP;f@{GxPi3cgf^YL8dMEo#Qpl$L8cXlH=NT_`aghc<;kJWVZN^ zQDtxW8tUr+x;VBu;-P(e!~_4iNbstyR~lV#;E)@YV9*V5z&ul~u7hIL1&0nA%9h}F z%%Nm4y7BLee|muMfL)M-y0a& zk_AXyXd(Gjb&8yqjyEQ=w(~G|Tt>I9$h|B_wSRPHxL!Llt+p(k{vGYf&)p*sR(*rK zkVj(TmCyvi%o%_Aw6=mOzxzC)nPZ%2VaI!xhIJ;Wx)yOF*m$F)``4Bp_vvF(wT>vV zn)3*12i_JEpNy0nx@btDd;uoI%wvC@8?-t7$~WzNJO!4nc!#OY7<2L&T>!t}M*hqw zMT2ZTf1D!C^Cr`vxwG!zmi4JAgQnTVgg3tzT`}wF0wyo_SRfCbp874>u7t32pPJ|O zi6Y-lS1M;iQ#C>c%l<$crAFCIdSQ{0fTV3c zPP%)ZCLni42g)vx*I#aI2x?ba9z;!eGFe4|g-;7QYRHE=5^Eci*A^MYT?;v-e8 zNb71MxT|ZrrUQJ>n6r_eCf=L)J?%|;RZuG60(QN>BvJyp32mkie&?gZiWJ{YyhGM< zJ9I}dQ~+SGBPN+g?R{%%o(9l(+rmd?^*8I*_K z_=LV(VY@*vQy+-LoY9nAC#=0mx*l<5|D4k=0BvD6}zlUEGSX*thHQy}7j5a5YK)q=h3s3ydv`hA-%-JL@h= zETo*ZosPKbS0+8FW)MgqvB|!2wwOq7h$ZC4IkjJCviL^Gu~!eorC0q!FD8K7y!q@t z$Kk3EZ*{)-k_MA^nO%7bmv89WUYQVye=xyiHPvcw`vbM`XIL^ZZPwM}ia3smQ&GOK z>c>VSDl*dCyy4leq59nktMZ}mBq}K%KO38C&ZZh*$kis{SHYv(ARE_Hj7zlmNO0p4 zJMDEix@w<8v{K_qcFLk4Qei^!Zy+}gIa&qiEgWcIxaD2wy@%YwK;S*~b%Wx7K^jVB zrMtgceL}kLmk|wqK@6sgoL*$sv3uQN2Jc+zE?SE?XmSY`14mvXlJiY##cclZjRV-A zz%Ml$JvHzm2hfY;F;bMZ5wTa}pt~pHZk^rw|1;67MM4P?L{_tJpCKI@YMX$5Sl*y} z93o?!tHACg@0C7ueaXBv#LjH0D?K*GBsPBf)2bBZW&6k))6N0YKSmU>NT6;polzjoBOO}Gbtdhwxzo+mri~}syw-h-H!o(= zQCi*IGs5VEMavGtSh7-&ZZPdexfo=+H35j z4i(qMAsIsVPrMwpD;120BqW#{+nTcpwpNXmOeWURkrS?PE=Q@Qk{u-On|s;t+jxsf zn?$O_Ir?Dchy#bi)d3(_doWH7L3%huzW-rFx(qm2;X51QF%Z3%#oI-n&)$lVJ|*+1 zqon$1DjeGfHPijKsmFZYc@NM~mdMJOo9T(?_z?Zb9;mU-wJ5jj=lCA*C$41u`QPHo zE?15_6kbmyAYHX9r;nmIx~jdrD$c7$5?wl4((xcof>NS3>$z_~(^Fq!)e@;_1fy3d zlWV`3-A6CUjTBJ2%P`sRB2NcNOuj4df+~pgaWuuZqp}={et3q@ZrC&~i0IqB&q4R*^MMXT(U~C_TSfb zYZ3%ihJEl4pcvoTd&SrL+L4z@tA46-zA7&}JGL{rMSnQnHY2drsl$Jw__gtL#X1oj z2TaYr2_yy-R4#~eQ(!ep?MFxEM;nB1kV>wy$l(d>J_W3~dbE^`JKgGZ*D1ViJ9rlg zGI)6xJ;roKX3IvC1?UoS9CxCsKN|F^bM@!$^!^lEOu+4g5omNnxRpxITr@W`c%-#* zl=>H>gF}kK`O0xpPqUP8Y9UVvPsw1%esQGJ(*^}nQ+k`?_8j@)6sC;(c|;!~2|Z=W zu0b6p?F0To1q~hBYy~zmGp}CZk7l&ekPqzrz~``N*gUm?h_^}_-3>v!RA0ismqIr> zf@32%FBT|uO2vs$gHvCBQ6 z4la6{$8T#~V@$7bMCw{SCoSVTKR}?_1Z|e#)V!m`=Z-K4Nq3ubfq}Cev(_NRvtA&r zOMS@k^!gkA78IbpX$np|y&cLO6zHS$+e3}6z7A4B-NDLssXa`IoFqOAM+|4|4ZJ-- zk!yH)sDdKOea@;M;%==Ziw@aUN*h3TvNjOM?^W#-n96ThikAF}cfxHtL_ge;y!35I zVTM(uyr{7s9NItMXIY37EHU-~IH35FrbG`XWYb!4(~3NF#pkhYDHv{DUYe6!O833z z6|`9vspJUSHgP@QnR8GvXD@KiWE*IsWRG>3S5TFPko&f7C2YnW za^x{@>3b)~o#%pcb0kdqzy_lxgyE0g-!bS1K=oDH<noGDiqdHim zJS(LfP0>&XD;}8VX=TnC8F`XZmT=MTaedtbF|DZ(KQdBol*yKHwp{q*zgw0Jmic)~ z3p!6Vow$bcxVWU~hu?$$dXx|1ogh~1`W}p;2Ols*+_d#gpG;J()LQ$-h$@tf#e=>{ zxBLcMLUy-WIuPDm0pG0f#^|cBQ?0&C{<)#@=+UEDRTNniAu}n@%uZe0u?S$cITVyU zy`S~2b5chd7+{5%1i(%(k(g;}6iajMh7`a{ZMjp)zId0OTwh-fPp6T5?!7CdiOuuM zUVCkR)dD0^S=|~O``ENiZ8b;$FZ9kxh84A4)(7o;{q;D!GcQy%u0I@jV8B+4j}-{) zjW|Dg`y;=_!&BE3Zn#Y4WEK_-Kkkd?9_7j?0Cid?!w<^0&_ul{$C^k|sjGME>mIwy zy253z*FffZj)|E5W;ax(3yBMPeKsertHZrZn6Q)ozD{@&7!M;gTg$4Izs5th-Ne}y zqyHHPsP|dvqLD&{zT^3=Ar_T<9c~?}GI(xV5OfP3$~RMk`2Owch?l+CIFbE~ISJLD zY-GkI-CCcfBOYE+m51 z$o6F{8kH7Qdb*`C(EEs{r?>KIpbd@xNtAX+=g-hV5_ty2#X$>sniI>AL}qmOW4;Uh zNu0_IF_iWd-?+S>zr_}034V(eu%A|Z4TjGtCA?e?Qf6Ucx>3MqPQ7|KGzFE71!|5$ z-&_@;KWUU817`{+$v18=0Nau}M<6F5p$3Oe{UH>evU^P)G5P$vuwVnF2oQ6+as8pg zy_LCvk5d0ICGsE>kT`QIQS>cy<=pmJ_wQrEhLH~~%?csK9spWy^fes{e)8QMmd80t zjm}?-43fcpk9aY#EcRWDfuPkh^`B^tOkBOJrVxArzY~p_Qm=in;j=AeSd&a%9a|wV zRz3kOhX5Tznj*AM3gdt~Sh0N^=&x^%UQWZs{4saM({0Bv#0bCox?cv*I3Z98z@R{- zaABV?H;VK2ALFXgT;6qrjaG&Mq^Gv8hrKU^Otcitv)tds7{UM(Mt8n^==sJ z`_{9Y+Jm}c9sdq$!kDlX+4KB;idY|b`2+AE9n@FVH`M& z5&Tfbdyuuo8Tkv2@~mFBXMvTuUHIJCy;^rxb-$@tl7kM zpaCg-QY<+Fo>mGL@$4;CpZxo;W1oJPs|G-X8B~!Je8vqp8{y^Rmzh3*N1sERrz;%cK`3k) z3!FB;8DB3jbiRcQy4>#ee|qmJXI!Z)2;?gDilAamQff`G$>Sy*d*LEwV$OawlKqEo&GBPdV)s)CyslJT?t=YFhVj-A%X(fv7q{*!~7tB_X$W#wz|7At8)^)Fj-)(-bLApD1wL>{h2Hx=Cf zX8t|Z*-E$v1_^_0Qa_mbw)vUq*>gc0v`r!Wgy9Pr3%NK01LsJNF+b=H_%Ppe0qP&K zpjo;34Z1K%aGM_kP+MdF>7PKwKSlkLO1&S3#?|+8%Yhlgv+|L0z`T!`nfu`TTS$Kj z^P_dN#D{4pk?$EE9d|hDRl~-B!04qj2^o546k_JzA-OSf$1N(C{*vpO+$ZeHKHn=k zj^sRb$pWCZkyDrj(&9yfnfu}B;#mdZ3#J-A&OkgWeU`*iJIdf>k=FTpdDI_ZAsy|& z1gLPGpUI>IUz~pG^05L(X7v{t^zZus37WWnLymguyFJkJVre&!dQvBA%_$3%-Km_c~ z)@BDE)RUY3Q1IoyT!3vVOc_9on-G%aZXcxxAX`i&Q%>2kDQ@8kBCtK$eZOt!{SH*l zB*XGk&_gk4GB*epba>2pJ$yyv1lM05L<7wRcBRk((m3F3H`tXB-n8PA#_1Cg(loRD z3d{UuO~!!k9r#0XA{vbwLYk*cWiwh+UA;b)e3l{z5ZgSWo()tq4J>n*(W$5M_oRYo z<%qkeF1(6i_||B*`?n-jx0vH;1sXQkm>bBxE&e%u zSS?8sYRa}IQ+|lT9wfreX`TD$Y#JX4PW@UAqnFWAK`J9I$xF2EmpRoEhcEMg*PxZKz%H1oC-vtuyOh9wAFJj{hF@jbzqRqTx5;m3KmtTHDOzN#kU)kX)V+YDVei&_`^a*$$jWUL|@C!#Y{C(%Y`h;l0kN^9I-6Nk)YAbYd8ai7$ad{w;?+7(i6vSV2yX>xH4+iF<1_fHk z72JbY)T#~}_GQ)YQ^)Z=CQcqd+$A?=-HbOS1Xut|zaZ%IU$0deUaROf*E955S<~rX zQL*MyU{3nOQmC(f`_N7GT`Yf_IX)@8@1xdIHn(&N#Ou4}6a&tNfz4PK<@q+~NR|2$ zOjgO@2~#zD*mp3F;9)#oO#7riQ`|ig(xlNSD{}N^Z-Wzp<$@g~?s?{k$(EJwdw35| zM}EWjz>nPj`}q@s@Hu| z8kJaG7DtA`MOcBCdEp^WrHu?7$Ot|}4)WQse(k^aMi(~wNvnyl9vBNX5)WSo%9yMf zYJcF;^g}1P?ZQy`Dp33S!Mj`q8q6)J5#Iu!6oUOdff`w!mwvL2{cUnR#U&3Ir@ckj z6rmhh?H4R<{r6^^Wjb>822eEeK>V#2z*+=o*@T_#Edw_OZ4t~rJ3QlzkAfza~;l%qO_phF)}Pw=xd+`%m>K$nEGzJtS!vjq*Cof23E%kK%wZv5W;hLCf=`g|X zIe_O>=~SpIG%1Zio1x=4s}!EZ! z3RM)AX3GwHsa(r_^v62k;i&Xh&>pV_)nBL@LCF??W0mj(kJ>w z1gqBrk2<8AJqN-fFMv!UVyOZM$Zrm?PnkB&JI7C%I-B*N4|mpuka^d52*bHnyT?KZ z1Vh3Ihu{t0T`TL0q^+`7f!5LsTF+h}Z8`@qUkRWju?^uDk9kA+|G8$GWGR$gKY?bM z3CUhs3^4||m(hvw7uCkL7!wg_a;yYobl5boV(md2jkW&Yduk1Vm=^nAr#~KN)c0)S zEEQ5429|m&xgCeOk`Yp)e)z!y`sF?W_w~WK9~Sn(LI)J(r%1D}3u&mV6SsGLi##cb?dUn- zkG}}=3^Apjz`Q6O-BUfr*~%o$Wk~|<5b3t11C|1rLeIVcaq$&Oq=1GJ-y@KFg`5?g z5RDJjPtTZ&UjF++TV=rTUC4f>4j+oA`ao%l9b#oS=PJDQS$5F*qxyXAv;1Pv8epC3 zov^n9F-rmeIuHfEMljXI_!pwrIw^6yctOG}LcE9jul4Q3fc0fE>cN5ay+z`4Jik_kzpgH0XLxKk3>OTi!4+O92dIv-4gyD(4nHcn;gha5iI4^x~aI@Jl=rhlpSyoJk z^2q91?auHj@G-Vre($XO%DB&547v;hlPxh$ZPH9f(%{T0o0hQ6j$Dg->~+LQ7%XTL zl-TsXnTvdV=wt&$_YzPXXa6o=46~9h*ZOSF!Dl_segyMS0AX1i0MdcI*$Yg+NXp6G zcc(=Sx1aNK*BdxLhS;&SeS)gqdRLZ}{qQWfT3ySlPUI$W0w&hb9VsJu;I1c==pG4G zYsFlzj-7svFC&+d4Hy~&WxDbZ#%6kZNnU>#HQvC4udGcb^Nip>FVGWR*oXo`4qVt~ z(w}$eg|&3!l}O;Aq)R|ojw`6lb9dD^GPv}c-8TdsSz8E0c@%$GpT0)=6PGiPQL(1; zH9Ejc6RHxO_wcELFbN2x18zRcD-MQTRCI-oZbN93LpP%Y<({0u*5EjX0l4T{^&7tZ zp1Fed_8=hpHi(pl+T+jN?8R}@dD^08HsTB059$7Z1UG}KgT{epGmC)1Z-)-^ zcQc{GuXF@n(zm5p97IWE5UhTe-Jd%{t?XxEhTCIwE$r-!?I^%{b2B0!Loj2auTG2D z(WT&sDzmI17K?a%h&Kg>O1Mmac!Roen?Gqath0@MHIzLwyDO@>P;t`^MyxEhP`uz6 z@(Ke1N`}>7wDu6l^`i|;VrK&Wo})^L)bBBzp_HjQNUlT z5Ar33#hbVqauy*fuS@4W)KpUqS%yYBQtNoOZ3jI+?}KN1j_fXr36_=Plz0%pEwT{5 zH2SK-PZuSypt^!6wh}O?$QAy2&!??$v4v@@(y?B=2B`Kr0GyMt zcia_=Xbc3+0n9-jgrNXU0YJL9ye^m`s!n@YMG<86!=kQp)5RZHpw%WM1CE`JAL|8!jI(y}W+=apY9aWs{`H)e+&gpNSAA#a0y(a zh{V9|j{6DiDPomma;wiLO|O(4Oyp+;_TTkaYU^NMg%`HPLG9ecv?*u7tY&lc=sU-uQ*H0GFLvbp!fg|K}`EhsL%It+%*7f;uVMf(xPe-q(zc!+%9I%Idwp?ewu2-);ej7qK0;BorvkGJ<(@o%ARrRLM3_#0so`fQay{tgRf-GYy$ugb_tW(3Us=1jiXus%q~e zn5Ep`^FUf~+caQXVEcz!U3M6%dqvgIU}q;NyZXw!Kw9(RwI5q38k%l^YW#fXVXxav zAeFER{N~DQRGfIW$RNvEWB>k(=5ACa{KY;b-(Fq zkY)OWWXt*T3S~LZ10AmO3%p~uj-d4)U-fAyL2|$j=F26CrOgZe`XHxc)-$>dyv3Fu zLfWG!&`ZyQcN9lkdyF3L8>)1Ed0bHXh|8~V4KTWaHP)@#(%nAZ)(LjzJiWI2yHid5{s)+ER8dirE8($i?fKQKmtWO0 zE=9_6uxoRh@`U0zNTPPGz{H{u1%mSFz-c<4h;+j%MUg(3fn_MCDb646NjpvA;ZyUg zdTr81NoOX1LBeCTW@9%^`^E~88k0|SEF5wSRr8NFV^R@ai#ue9Sz_nQgReHvnn?|m z@cem8H3|_Rxld59zgZp!wQe1}O4M-i%xM4pn=t%IW9u6GZBoTz^I~PmOt!w`nA`YA zRO-z;?A-`1)F_ISioO;2rJL|T-kGE8gHfGvTC?m7S8miaJ=Q`8&x#`%`4Jd82qFe< z+65jb8x|zUf}qA}vX3Gzt?pj))wm2v5FJ>kX^^;oWbXqQ@$v}(@iA;HA|b}T@(i4| zk`yic;_oKe`CgkIJ6%`}-c7*jJ!0&xN;NDFv8?xx+YV|a^H;3l=Q(=>|M+%sLb&Pjfpk?0uu-MAY0FHA zIx&&>#Kj_`NpIL|{AU7+9Fbv;g>SzY^vxZ@zjpw{Brxjdvg?vjRi6iW;Yx6t4Nu7S zV0nPzx?2ybS0N>#VckQ8aoPcWHse)?R6*2R)Al_nPS%{7S_NlZR@f-PkmfPP7@t5) zg9$NxwwlsEPe`Hg0GjH1E#7i|dR6MBX=0wi{ko`@XLEdef@S9xrfVeiG0_pf9CbU0 zpp0LQ%1CLJte0)Sev@Q%FQK3t#8fK0^@`AF${wGl(ds+@D2w4Q7C<&C;D10odk555 zoG_jJus2EoRr(YilB+FovyH~bTgYuA_*|l*k8*wU`vTsk4FGE;_ zGMF5%np;e$1;Vby9uT>kRX56>Muy&D`RxU*LIN37QiNBWN#S$jbE=mIs}C&MWyR{{ zX0w<@lb*uKt=887`?!(V&t4okEk48jncDaI&AUhu%j6M3;(E&>$i3+);|RwCQQw(u zkTjh&mIgHTep%NVLA8Z%?y9{msT8TqhP3&i(o0tb^+;t%yXwY)ycqTUYNE55KbsM* z@JvPNooQvGr2C{^Dp7c1k)P5qctLJfD2U{|;r(a`?*jhxKt$M`4u=82=b*rH7w;*t z{ASr50X^pkUp>(-DgQGPS0FUMzJ-*XeGlBcP~2br)Bul(Kq3cXb8HdzaRiEJRx%waq1z3OQm!lpgS6hBS(mc5;kR=Y$rT}$R-uzr_ zYdKIH=%VEllXVo}KpO^BqW%0j4-SNO2zzS}8C- zyPJWwBh+C1AFVZc)(+CHpThCirE(UtXik>e8+-T*-AS&l;G0Sr=p< z809K6KwG)?fS1k=jG#iwQPK*~Tx?qHzjkC62Hl46B3coGX=CeUvGgG6p-Qhy{4N6H zq3Bl(KQ3m|7e!8=i93FYO2g3cz2l8~r8vtzF1qOMNyJrAPOhq}3B;dl2Z3ol7&duX zduD{j`9Y8O2vq1M8&6|0c>lciH}KpC+cmBu8}Lv%$#m*s_~of4wR8i8u7vl>&Q1iG zR8WT=bW)cmt;0sfeWlE#7*{cCC^u2hE%W#9iMl6g1O%aZDaTQCYo-60Dk z)cyvczRxN_5TwFiezogeO+Zw~K%dDIjNa(hjAcsXr+Gb*|^ zQ?d37Lm9*&K9l{(2AJe-E#_6;(?DGYNuF2GM_Os|7L>mWxahDOQJ){;TA<9}K(5hG zQ#7-vWI0YN+{CUHZ4kIkjp0zfbx{q+@tFb>g7e~Rjg-|RtZL)b(l5p)E=V*eXm9U? zlWCON@GIv_srJB8kJJRS`{SG23QB&-HO}l8*6_pS+04|wJuDW`d&%@pwORoO%T>Ws z`2CCb)u*auGY|M&`Bj;8kd2Zj8O92>FLg)wVHC}FNC*JguDNci=w12 z=k(mOHHeb9YwmKef4*$lVr#$|?4@Z?%9+IsCU*&c8Nca%Bb#>D>>^;V%l+F8FuMma zA2@{N+I94EF|3t>j2bZ2h58s1HN{bZ*=5o<8^pk!Urka&rdAx-?90A4?)6>7Y^D}H zJf)VwVV$h&yG-_Y-LUxmxxun}mbpU=dO_nOG;y}dIf`qk?&31zjH{D6ag*-u&){qQ zZ6GmE;P=fv4+oHwO6dosDfw`B#s#j|)JDR0i*Faye1Y7e5Nzone~%Z$1$^>Hd%5U} zx%+^;JbY0`IF#9QIs=jB;!_?FxdJLc+UhttISLo#L>~K?K0a{h7y-3ZoW0rmPN4ed zMKP!(4NF?i@hj95yeYj!;DVV@lh9(akNBUFQtf{fafAY<5UYNnnW}!;T^i$4wIH$N zLB{sbre*GK4)%|yJO(ByYpDz2V~p6yDf+5|#r&c1PlbyTGB!#x7b@23zcL2gO68oB z`aeHif;7l8*+S7(K(?R;xaaPm^j7(aZFh2n7eM{mYKoN>U#5o>uV(yvYau!CaE29GZU3Kv3HKbiz zxS+08p+$+6743`debwAPns^>!)9CS+yNJdTf`V9XzT|+*Cq$xM!@-&NOqlyCDH>_k zCQzA2Gc$8Z1w)BB0NPb@o6t2e4}zeDUzhp#F>enq47`k zt)W5&1$M;j@NBe}0R%jQ^o+k+_BDbY2PqOJhH@>-Rns;o(xphRkKH{oMeD!8vLnr z-09>5#0rr61IIx$6{d#fyd5fEozz?V!)-9!7|PauGX4`;O=`o4#te`;I0< z4q;1#e{q9I1X>kwI=z2Sfc{15v>wIua?69)|JRWS5onVmVyP zA>J`jn1+%aN1KRY3^}?E^;VS&5{V28IkWhO*Th|J5egBQ)D75S#ywO_wu6-?A~4p{ z^?%DeC;*k2A0>}Zl+KRC_{k)*)3lyybPCWn0T`!Q2v*JLnqL7psn+>D>a1sFmo>(s zRRxNWglUjf*zxo22g3mb>XBDRN}q_)W%=aFjFK=pZ1zQgL6=44DTDS*-7m)`3<)`s z01i%ufQ7xiZd45)f08ww{PDfJWC`m3NhUbCqGaHRhM9eW^d}G47&(g(qLH`Jf*-Vj zhR4n@RI9Dg?6n1n7MAgx(n8~F;yoV-RcP@EiS@FF_QI|YQGXy6ewDA^bdyyGVC&Sw}vNv9#4mza~d^#aYK7%Q35fDLd<)s zxjp(E${XF6m71~t^Gd@PAx9z0_8pL_3vcEDZ7PCh@N=|L9tcQV0r(NxIo-IO^IvqS zWE5&~V#ng8lhQc96sP1(5(D7sIPW~!9(mgo3?=dnCSg$l1rm5=r(Ctw5uPv2fsV-? z-B=Wo_`@-=`W|hAJK&F~28j1@T*{|v1=wNR&_-Hx;z@V^6nwcQ>Ovg`Ve^rCOuL4oR?!)7ikxPfe*DG4@tm)N||A~MmlhJl< zUa6+{H>QDQBCdru)i1CJDXdLLqNJdh;#>#8yxsJ~+^r+)p#H#1TF0fHq|*;A`5$i` zzi5lq!lH}XYF0_FJ8ia_Nl97sbRK;X=i!e-%mSm6y(=?iuto_8V)Fjf3L{NPlBA#X zxfP51kl?r6J8y&Py08!N9Aa4w*H(SMuS*p1L?kkxZ7jH4dvN(*F2Gl~GKJ7#q(c^f zuH!SF9(IxyuE?qD%0s2}3bdYM&lKqOT$GM2NH{p}U@ruqy&a)#M!08gjRN^84#omLjj>tSG4uP=1(q3;A z&doQoN1SO#+LkuZJ?WZx`U|8Zx8{*pCanvW`iGmak=MCfBbLdwmPm~nbr8}vVOe45 zafWNBJU#78p1HlqT@1Pg$TXhu3PJkE|5n*U=bAy4QD7$N@rc*>l)=#lhqGB(M{fx2 z2KYh{wcT~t%~lxUCKL8Q%ogCd_Zrat6u)0EsHa@%brPveKn|1>OBC3OAOWZC3bTmthGa9KyYD5y zgYm}YXXTaVEk#;!LK8?Mfwf$T_KkOWXiE@Me(wpJd4n(D)kUTkY_VL4?cR^z;r81Vv z1Sw^4hl;~?FYE+$b2!EjB{hjZcom3ZV}5(*a-OC--WdilFLTs_8Ra#nuIxGo{bxgV zP-UYqqFRUIh^Cu3NeAz=ku2QH)S zF1}P9DTr;x5l_u-+*%W2n^P#Z3FRXw9VT;U)VkSvJL&Gifthg-p)__LgTQX8UO3>4 zCJu>d3@;M|H>ffe?R__s2fyBW_Po^5@EPWV0SOF{aq9aGPWa1j(*&8M<~l@T>%DxF z9}O!V5?24cppUDU)J)G)Hh64OuNkMSnJQk6wT>EPGo^O;1xBe){xEU?^F2y3I#X*z zU%VD|RO|1cR0Gs5&0yY#h9bmWN02@FQ=pw6IU69GNud~i;@i$+s)*3Pi)6vB4(W1^ zPPTuUfw%(-2+)&6da(zL!{Z3>Qr~_g;xxGZ>kei&2&X+Mx&QgHdffpLkG7YLMdKc8Bc?M3XKU4?Hz>gW?(HwrI?EaMQZa`~$t{uyoWbip4aw=4_iEiViSk zaTP^Y^I=%49pUO8Z@EPz!x`VJf&mBR7R_6!#hnVr%Q+i~?>H1?PFM)OL%0q3ou4Vy z{D!jX-JIIt)Rd~n?}tV}jijvTQaJV3(;_panfbLRez&M3FRTA;v8h)FUocePlM0J6 zN4|hTzd16L=6fbZwHe>TgBBA%^}lP-F0|DKo|3Yo_- zKMhR7t}4Y%$QDJOY<(0i+RDlIxmFXV1haoE)hDt(zCzGaz!5qWq6vi&6L4efAqcoN zP%pbN&1t7 z%KdQqVrQUBWyp=H7!A>u`8W3qD**Wx#YDcV!;co7XKM?AilgDHgNa^@1AYU?zeD{Z zn~E}Cz+@)iLjC#7A4<1mIZS!X*@7-9h07Y5F7eShif1yDaF!P4C4A`yhJH@zb+)Ed zfQal2h1;?)s#Z;W#5=f43MW_UW#c$w#=b!0{0bEL;?;3^Ey>EhH9|E|f>&*-GUn7! z(0)bhvi)UQo96Yf3jP*!ORmi+sv7A`ui$K&lUE=VT=46Jny+*;c`(?f`J zmkh^vmk=eoCoa3#jal0P$GDPzp`L=;5rJ+*<4YL-JdD!Jk3gbqoLjun$@)dtc>w|-v_#~cDL{L%zGqMjB|Kzo@ur~aB4B{n) zx4JKbrEP(^6nOd^ms-MAO^KBUQJBQ-?O*F{SAJjQZ&46=o)dS5n)MAu;v<;YF}v!| zvDc-%n3?;t57kOF_sqsek^M2|CAVXaYBnE+XMTa6`CLScDg68at^wmQ6EREPIJh|ZVWZ$+5PbE@T`c%@%Bs3C-~(eUOHy;=mpg$mUrMYuG(>2Py^)m zImlnU;r(D(MDxKwFkJlaem7XnkOc)E+q;|B34ojWysTpjzwn?334X|V>9h=N%Qw3d zfC_j+nCS|7An`uM?Ld_aTN$68AROJb@DHDaM;c^9cRl>m&xqJ2pxFa?QY4lnY3OOQ zq3~H6*o)YOMxfKQ|6YAnI{;DxMjI`n>~tg`2$vgYe2as_e?%#Of_3RM;AtaP)V9eic4&5VlQVQ`iqa-iFU z^2jd72r+R40AS7h`egeb6Q?Y%Ld2T~OmGlDk;{J;ajfr+P*V#(vY%26W-0sjtSd~w zu1J&Kfpf#~hho?K4?Ohgv3lwXKLdB*7m3LfTCamfx(z4|mNp){`HPP7>-*%dr1Guc z{z8>9LBwPTXfny7&#htnPBlRIrC`wqWDYP9kN`ZwmpOlORNtRT;(PC=8i#X8j9?Vx zZQ)D@Uf+2K#}IV$jwl#hSH^WSAbaOO2DfDY^{1zyqHs|Ij>rSCLi~?eYD$={Y3fKY z%P=7F0O_kb1*o5{P=g)>dbSk`5TC`2Z%bj!5yhy~cJNcLk-aSqx5f)yeUlyoYZV>y zG)eC{RHChK+p~9n8Bva+>H7}SXh9^ZQmEp^^=}eRKF5>H=FC-DtC znd^y`lyyW#+`&Y|80}t1p*m4j^Nhw_wiqcwUPQ!Fpa>J`h)(a2KW7p&_Xe=k8JRHx zEe|-?dYp=MAbl5$$bu~`J*Jo*f!3(#U>8%V2HNGVwL zVL;qtnE-*?yvm$Q@!`I+`V~_3dCry&X>2U}*qOOs?b@}g0WQ!(6SnJ}$TYz7-f|Va z1h@MO>6voP^1Z5OSc(dPnA5ZBYh)3tI|q~venT8M{Vm9Sjt8m2OgLL2QKnut;0>tB z4s)t!;DDiW7zQ(D zuFP5nN60zd^tc>e{6aN%s(YQq81n_k$B0Wsn<#FW+RgwS8HoRxt4ApC!Y4Q`TXBrSS??;{<9rgsGjop0k|R_7h~y?M@K1rp@kv7vkav6T_KIA zsOOkdMkM=wxIQ+JV3iozSHILK`kq(PUW}%3?1s!)?;+{TSBPSZ0B>|2{DhkLUP$yXkWR0?7hnwhqizQC{_NmyXaDkOqci-657n+4km_2OG^%NNwbSGEKkN-nGisrH8V)Y0%XmsY zpC`BQjGY5BKg+(SOkcNIcTJ~=MGDX8jf4N&jQVjf`qxA9lgAiK1tE2s*EKj+(H|Zc zap%#$&%pAqxc!0snLkdE0UX+!vTrzen1fV+*zDENp}!~(4$W!-yLl?{CAh?SVcTaM z5q`Ii4srkc8tz`|OwmNpr$OJDGtfWN?xh%S-oL$|ni3GQ?FwWspJ08;3y- zGmoZt($`vBmFH4MFIbGwpOU%C=wD^ z)JPC|1Mw?4_hA93r^~*R>%R$FZZ{60?z)$sgQ6gT&ZIda=C)vS;KVKI8}pB|GDXtf z{PF8cR@Czk?4ze?2N34IANln$&H(`9smQ@avcE~nQQ@SsY)wg=0dQiY{0ETBN~CZan$TXP^d5Up^d+_3YgP${aYBoHhRwT9Rv9Bf=#wf7v}#;#l=JKXK$Pw z#s5K;2`R9!JTHT7#G{M_Gji-i16&!Lf|9QwJvuGTkb*a9u%fA&&tVpt#zUZ#D;KuP zir)mTaJzsH~jy!aTW<>g}3<+K-%Smgisd)%3xuGi1x=_WVd2Qim+XO4dn!7YD$_Zs>DkO@!om!0eYd5PhStG z8G-JqshxUZmKM`s;ynOAOMx6)@~$^v^!C3W{{7q6rwZ#_QZ;&-5FFHT!kITtMOrtk z^2n}5m9!Fa>+6L5^-JUdnZyM*Ly?UQ9&vjPsA{G8CY5wjY#EAbsp12i(w|4qtUcl# z`FFF)nUZpZRBMz2lL?Q(K9QjEZ2Bbvu<516;j=^UJ0%&BW9cM;I|#~@FV46bl{P6| zjR!IxRL{yM={V_n!{$IR`2{rawE~z*7@GZP3gZdQ!P^&rh@U4i=#Q%*to-*I6K}aE zin5J9Ag@XSTwO^5b~VQ>Lli8H=BqC8_@V#?EY(50$o^NBIy?nUwh8ORQEN z&H*nn8`TD8!-Rg&lG37#Fp2Ekv5BBtaw!U=D^c}zGX_vQ9S`u#B=3XVU{XvfJrI)L ztPo+u(RdD*de2Rs9V?k8AF8%LDeF(euUpE}HJwVkG2B%Y!~JP75|)O0c~IokxB$?s z847ccY+?C|3YW+Hn_$?-Jctsvzt0v$<;>+6IBim~-r;}USenWK?)n?+Tx{Wyj1aHq zAQR^z5Q7N4W{{2voz%XtT670&XCJ(;7`wtc(_AYcJ zq*de}VA_-sJ+>P^Jnj(vs!6gOrf>(<9!URJmJ_5q>iu-R$LI}%0(}psg2Gi-4fv!= zh!P#elG;I}*9b&R=7HL;Mtk?)4b5@1sSAy@r-rl54))?0*o#XOyo|iCq37UTzvW7* z-hiIAj;G4A+8;I}>t#zoMf4M(Km=$VP)aho_UbD@DlgT~4|jup5|h`U%<+Swt9M_} z|35$VKvhT}s+K?}3d4ZE?r)A;b>!UrU{$X}v~im^vi@Il@c*&*-tkz!|KBiD8I{vk z_GxpldmOJ^4u6<#hPR=p`HjM63hkkq&!|E40T@c^gTR9Rl=8M+rGB^%8E|J*pS@^cIkQ zW=pP)kl?)RCBise8c#$tePAGnKVH4=0OSoX_^f| z2aU#-b8`QunvU~pbHj*2Ilcd^uCDANo-0R*=Oo(1M3Iu&n2xscuFA7Xim!j^v30hA zKHpQ+42I(RTOvVan`f+kcVSthKq8OssG~sdhyUOEN&FYR1Ad@CE)t=i5!@e+$h~2Z z(fk&16Y8w5P$L`mt!WGJENcMAc>lUcWgdF_HDFUeEN%j#-yLfD_ky6Tw>r-F)ABSf zPxeY3s^i>d+f+7wjH=TJn~P!#!Ii|7CJ$2z3kKMhhe8|S_8t-_tf6FUt`zh0!B8b z3oeF0ou%^FOUrXfa%-R+dCfdLaf@RsW;-W+moLz;~s_3&)qfsgCMnc_G% z=-WM!wRl?pV-M{H(y=nG{Q=O>8pMi;qY*9{_J!`lL$M`bo0@`#xlnevY1fUs5bAuR zIwdfqZa>9doCS-0MT(~gT8Dk9c3L!-x%>77-UZ3vRGscz)2@atx!kU{$}h0Te#M8` zmw$E*0#W36NUSmrg$o~K-{vY{ZBn&A14dkEIC@pC=xA;70|Yohokja=9sf$K3Ne4Q z;&hgD%w>5_g1=2Y#X(bxsVxop`{(=K$e8z#V9#eLyFs3L`!7z(F%^!&`Un7lZJ`s? z03xiPRQowU>l4UiC*vjZq}vzqKEUq3;0vb6kS5FY_OI6}R42lsdoH6$Vjf;hy$Y4w zUE=|5>GPk2piJK2`VIWSy+=X6MgV_4&YR2Zem5l_^uBeui!C9rIjWo@X9Ho5qZ+GE z8mF?IP#fEPF9@LySovAq>&Tk9I}*!iW_r!E>jZvEY=e6#vF(kkoBh|9&|{r0<`n_< z8YB61IwUn8b>&tKe?e=)^2SF1iOgjAwN zZTm*j^W)48=rHZ$TF{c$dbn{?%jfaN6tji*%VQswJm#(d&-xa$dFXv62SGo=xUKaD z{rl#&%moBMByT|_3e=xT*n_2I6gL0N+f;*2xjVwR|7i^Yu&sv?kkLkmm!VYffLwMG z=|cN;_b$GL-tcts@kJ~50G20dJYzo-YR%7Ff!>H4@bfANxMsxH`ViQ1^AB8>w|^Fs zLZk!uMQwir*yHK<^_4JB%lM0LF3^}Ys?m1g0*>cB+DlD2{D9+mpX_+DzOXIz*kM`M zf$G$%ZrC>OwYzV1y)7~gg@MFyX<6IY<#N^GtZR$SPJe2EIq>iV-Kz}p@-}xboyh+-=KA+Ycg3kMV;)fKh3*a z*45T_g2B6W#MnPg_J^`8=fC8DFyw8L9(e6!W))(2a#E97;SdDc9U<>0Xh{x5Y8>v? zrS{Ikb80SjW@<1^uvt3|(rB9 zdof=ySrdxgInr}@m^8G__0r11gA!%F``$l`Gg&)Wvj z)DqgQnuG_#tvTdJX;1x$5}p%?5#39PzXy?IH){CV8+=p4ITWbP+9xsdmJobaR^jqq z>MkC?dJ$pE9|B7{K9hyF27tg*PbhB_8fv~QfSK~*A^qWWTH{e0mm7jK>yqK~9A!lp zPxatGN3h#*ZGG|6F3Yy$I`Z~3g?(%c(Qh;JL=jz(7&KwrI!C2mte)M>rHi1#?=0K2 z_Q{{i<4j}_TFL)|^=AX=`8BZYO;T6%Tlt3C<+ItYBJ>;Tn3pVc{$y~q2%$n9rt#Vy z7ab*FRVP$&52wBpd)pnt@DB@M@F{rjs{VCoEzn4;+sYd>BzIj+YU&ZFVjxwS$_Ol< zw4RFU8O~}Kby~twp-~Bb^6bB|R7CH69&tMQG>|YI_|AZzLEO*gPfX1{xC%$u88cXX7jFQtiMnH8@!b>eJA#i2FLb4QhKaC@JaV(Gc}^C!XmZl`4f*uo|j z_OfghzFVXaGj3A*u;Y6>&m4#c3WK8jZ%v$${P#(7!aULYI zv~&X6H%uusS8`0UBsqsbBh~sEb#Ru=73)B1A!@c5kIC^?(u0f9cj^ghXO-0L>%Itc zDPizq+%mNu*#N0v3?A=LTPRKaj;=gQ|Ugf`A2(VkIL6$?#pguq zr}f9mUTNYWNnPx|%vTpS5q+_?adrI%iZR)`s|O%cuez?I`xwP;+zjH3W0N--o2+N# z3H8Q9}=Xa9G-}} z!o;qY{YjK>VzSnRPnn0^Jo_Q%$6AWWq!*DEQ~ief*-y8~G0OdlxwJCtxOWeG2Go@| z)L&GR8NcHGKfLez(6AgvlD(uQZQ(@GOp+HyrSG|AmWyV@i^tfS358>+gUN*OohgwS zj?cAIo7?JMwK;YXoV8mq39`0tPG-a$nc%u6lHtaI!#eo)IfF7K_7$eWG`L5lQ|P0C zGpQzsCXOv*8K_r%KVESqVcIjX_sQnOoP#Pt?UfPvQh{1udXQVaZP6 zu9D2HaxBG-%$eYVCt+ZSki_dj(^W&w^ker@c3b#Dd9)PfYLe`dI^U7D0+An)eg3P| zl-Uje);|_meN59CJ#hYxIbn!f921s4 zIV%`%@|4f|=V7(8W;HfplSHl&nxKw)fxz}7mi^I_qmKFX5h!OZ|MHCmWC54_PWUsg z$fp6gJE=kTQ&q2)thLy2Y+GWNT=6f{iSE&q4Q!jGQEh^-rh07jkFNdZQ=IeiZAmyP6i?P6i5&y~Fo1ayIff@?rZ&ZY7b{{0_^lx8Cu9ZUhQ`;9Pjm;^$+eG`S2e^qQGA$+c=i!CrR@;Uvre((mjlyP|6 z(ptCuV|<+`?YJ@j=f%~mNdnG6;KDl~8E7As6HB=>IrqFhSPC!c9~pD>no$N3BLm*# zQ6pExV&su98qWF}q>ZBMu`I+;*Pl7_qH;or3l4>apx+5y5x-meV2P$Fbo@*m(SFu0_dhl z0u5K{IG4q;CZcN_o4>$8&ixfG+EcHZ}LnoEzbnpUX-o(yYiVyIS$=b)g-E1{i6kmaW7&CRlv`8CKn#KAzrI<0!4)~Udxc}Cbr)hI`qjcF%(a)>y!?M6nIa!+O`bzMVO{UL}dZu5;9CHqsb7?J7 zUi(3M>)FXy0Vi%>l>4}mqZp+s{%{qrPq!~#dsAPyUerv8?D5X>t9_@DL*XrjKZRww zvPOGw#$AKPPXVKz-EL$RM01Zda-Q>couf|jXL+T$L;m?2?$FuY8Y!Brq)omkDF_J? zo`Wgub*J)La1(S-N3Ta-A5!IJxW<#=zEsLs6v;KJVI(RvI?0U2@P5S!Ey7S}9=|4bqYXn@o8tH((1&lcX4b&* zqS=X*^ttz4OyfMEo|E({IEL9!XL$0Liy&69R5wUNt!6=X4)4aP$l1XuNUg6d%i|n{@CV=Qk2phW(0i4>52P3IbanVh2M#jtn$nAS zCM;osiZ{xmgK?-M(=y{m>mLB5dud&yK0-}d%lfzWZq64m9IMmD@oSdF{2GVa>Zq}z za%Fic+^o#bU}onpR2+XMMjnxy=~0?|mAy83vX&~0i8`r;CC0Es*lqdjL^}=TbN-iu zA*9ZAqV@gRcNXL2@X8q+lh>TQ%Z{+Ol!qlG6`Su z$aDw^WMK|h>^1m*9iTDm`V%t8*&g*4&qxzQz(oBtT6L8O=X9^7mg-B$i*x6m=BVuM zmhF)j#V2tt=`mirkRiyWh{aD*w;b*#U1Io-&( zqE7+{ka%+%>aIHXN7`oyM0h%f;%9HHBb2b?%{)UaSIeK*o#(aoa9of*due=j{#JXY zWrQ|OH^+55u449y>zTjzJ|0&f)%d-Ce=!U7VL1y~T{5?o%(>V7d#yWkI!@u$*KVwA z>XEhGF(sHrbHqyT-{V&H>1U6{QML?ILeQK}%tdFaM8X)Mm#od`@l!4v@d1p(bC#FV zVWpX>58y0G#V-DzE{^;}>X*v^e|=T9Y(GceUA%$OTuSFo1Mb@c`XiB5Ud4BXW_+dw z%gVp4yGAEg=|YLRe78ic30T-;MfEQDWrCS_}D@*2zMKZD}5a{9f^)CF5JQ$eVg zm(sjlETtjyFX*{y+Qk+Un9NmDqq#*^LlQ~VXGA;x?#{rN(|*=` zt!o#lg0uk(KO1;mhbEb{;690Ajz=yT-zr~5$qm1>2ok%muhXFo)zO|-?;%UD0|TAP z#`-lE#VpFoBUD03uM(oFbNHQX;|@2zwEdNFUlU#Wp#SF5BP~ebV}PL0PN>2jzl5d= zEU2#iS!pCqHvRdxsYTIfNh|c0$WUGQm&9WrYrMhA?71pC6X%xGsoZ$YcH=8R2b};1 zWRg%0Nd2ID*5gpiVayZ~|8(g6`{WymWbIz`Q=D$=%F0iqwa_9Gb{4@`t7pFrA8A9_ zAY5vt8Yzvg4U{a8UeSU2v*jBOn(@oo9dd8mug^{0dK5uLoNcm)SiI_*L)>RWw?RE4 z$peB6{?qBqGQQlM8D913F28>Ab*aTk#zp=N|LinJ-vW4(`wm`4>wC}rbzUPrM>Si` z__URrFK;aM^@i|VTu<;Dve00y>E8Sg*ZaR{GO6G>e@Q(PrfcJy+fX-}LaTfxqx%mt z5upluZOUzwM0O*z716PgP)B{5T%kHH!gjeX7G_{G&y8?vsBBV^T3tG&Q}2Mw+P zbcVGCTI!+0;@s5L&wG0xH2{EREGD?rJj=KC2Xq<4I)qXm)XMq-0m3(C7)e=1Pe6U_ z7|m3QHm+LPLGIN_nuT=pS?>!K?i(lM38w1dv^1}%`wshz@8OA=_~{3E<5BXDKtHjw z^0yp%Rx{0Iv;hdL{y#6gww81o$81KcNm>tag?<==;8pXh&`3{uoyq8R*$Fue#F zjs#`DH(h>u*y*QN2pUG?zW4GY&z8F5>{@4=5~(>5zVX}OodS1IIE>1AwHU}hwhg|8 ztnDHy5)2clxh(tb0gw~_<;^JL&kq0=`rO+Be|<~i8gFkIns{ssN$t1SMOR^5b06?$ zKF_+r6lPla0svC2E8X__Hh{(_4vHimmJhst3&t{|DtA-4CYH4JFq_XiwYxm4wVem3 z{oOJNV(GCM&3e|hfOvOjv1*)POCBc!Nab`_U?{&`c|Nsv z>Fh^>_?e1qB9R#==-8Jk(9A~=6jMygQ)ubK3PtLA6z-QzKDgZ!z0C~JH@>>>;OOJX zzgBM-Vz;(HcI7UrB$Ld8IM+glI`(x2bV)wJm=f0(X#E`={|mGgpYS1&>BxV5A39P) z@M0!2B$xj}9Pig11V`HjZuH5oUiezdXSr|qWL4wsXt^u8{y_pvB;vLENR9z8$B&a*?c*v4gsSifk|-^>ej(rv zTqDM^Qu`CG&XsnnRl}UN_o!l)HpB#D5}=%!hW#zfB$6K=!T*)k(rK_s)?h1*Q4I2pBi0 zCms#2fhm!`?~F{E{;p{X3?~Eo*@$t&51PnBz%)ykX4MKY;~j-UD?+lz(aAzz+A8V` zj9E6qv(xBwNwM60MPuI~mwF5HK|TL>g1BuPso!_qlkkJ2z!84;1C8gfsw8LppWYBIHm^GZbd;`@Npcvo zwq^h{9<~z0>1hNQn|S6uj?D9ND5;9dOR(U$S{>J z;!$)g7R_68QfcAZ6%6Gtwh(Ev0{VgPwf9%?ub^`46L36{NepWhWm3CVUXtk5{T$8c zyf@7ipowJwfb4UhH595b0;cYN$>VofOUW9bAYYz()|xlJTsLx;{$+NM6gF^~g8^y5 z&$C~KHk8X;|1}~Fi>|Jo(>dL!$GGM{3d&gXNIOS$>MO_wTiDs=ure3TD=pMg=iI1- z_7KHQbi@rvCpa-{5rSV=J5`Ks-9VCNk^v&Djr&_pPbuL#u0nsN28NyugFDPU z6wUiu^XDyq-Ggs?%=7xe8|@K@rmXCaq;@B_{vOGA765ohUW~G^uCV1YE6$d0 z6F!v@;WG-V6nlwz4X;bn>|>avcqqRnWI!EuA6{mB+$8|rY+`d6!6cMJFA4Ppr~Q)q z>!%%TgApA@YWi*_0*}Js-H%v4Fi!cbE)g27XJtJ900oO8cmA8GcNdt!agDT%ZjA`Y z*^=);A4A!ZzA>Tb$jukxY8>UL&$)uHnHj1r;pxo46KNDu|K#sdONL4TETln8q@^Fd zFH(OIR^COHbIo(WBmF9R|B%pODm2ReWcatJ^5@{m4|iAdFqD04Nx1}Z3%98e(n&i6 z&(;%m?VT#Jo0u>g(r`i~_~M4)dZ+!adQM*w6?3KB!PlGdte+IIZF%dNXLQrW!%Tuq1@rHDNrl=?r37q<(SBnBBM@7i4P;7 z?BpTibyT8&HZCn0mVx(cC$~l;>AG^`s{^wovN4gMFqe1>0zO~R5_=}j1WhR_3!wQW zI2@s?Tc}fj2^qIcZf&7Kayue0%c-WAH>k6X6wFhduV2i?oJ5SJ!6axb8|U4F5fnqv z>$DiJ8WB7I#gb#9|C`7HVgArIupqsdJ$#u>aZ1(>%iIjXfJyd+|Gl?Ql4FRwhoJ=A z_r-1wk`xn-fzf{lRpy=N_wl04Vc z_4xPomOZeqN3__RPr=09xe<4ePO6?i^==6Gkd}1}SPB6k4f>`;f%KAEz7BHaYg{{P z2C=9eq@yWZk0@1xRa9C7rN2bD7ClXpo~#st;-58e9p^!(s{#0v_gmJBj}jtbG-A{| zOh{M*W49fftZ8#UNC;@V?>TAdl^`FqIfMxD5UkvT5v)x-bp&JBz>3vxgRf#tf9H2# z!QrLfYF>JQI_Tvu@05o?-yET|M?#7B*ttr~M%iq$jlpW=JFC~xVh^G*1;F=iKYe}+ zF15h??H)imAr=G}#)GATI~qM*NCUxa*?DP`c12a{q8;aT*AEXGc1LA@oX!7!{buj*o`>&)z73ptSAS+<)MCA1(30Ca?bc<7@u6D#dBCFi zQu}KjHsH1_Tlyg4^MhF*|l0YfE|nOfcG+=mT-8Q*R*uZwOIsR8j|^zR_RgZZsQ z>VUiJb`r#1+~I}Nl#+L$9uVk0wE5@F~X3YWDTM1WPt)XtJU~6qpE2TXe zNkqyqmQQ3?c?Vxye^U-smAru3G>zRzc9AM8G6#k=+kVW zxwm|}NPr^0Xb4iEZ*NND;&6s^<3NoZH?XIVEMH!!G_05~2&F%G52SpM-D52MrrO9; ziB#ln-`B{=5tK;+#EcB6g(K?sEf5JTGjxsVa%`x1W!5-X+*ojn-SVCw@l=!%F)^7U z2McjW8w7BaB$!YlQi@O_J6mFHuj|oFzFZaryP~pLR1hK=f-!7N!#$1+(tW@AH9dZe zJ^9X}QrZHS;yqoHNtN-fV#Yymwn-ZEz{j<-b)0B^!|sHRBE$k>yC{;)p9t?vmB z5H0bx{|bQj4*Qs-U$CB56U+|)NRLNKu7z7|h9O-Wl^mCEJUPHtjkBYvLG- zgKZQ^9SYmt#(rwp#t&&vFDTloMk&)%9t(@*JrhQ$I&b8gs}S<&WSj?#N=X0UW4sj; z*Smy3O~!+Ki`aatilzdXz`F&_=|+Hfk09$drPn6!G`tiu65JT$c-kRTDNN4$%p`KHw2Al_QpbG!b#Rz;tt zlCjIBkr9a9owl){%2C7)vd-eG{2G#ZdbrWZ(q=@Ej1It5cPt0gdi# z1lY=hw9&hbkcJKcQ(BAV`qMvoRDu^txDH>s691KW`#sWV!h0;D&E&Y(e!+p7^6$k|K!zRRn?i%s$aAhJ z++G7SXk;;97J2@HV@xDSHuz3hnF-H%GYlEJtOE$kYLTe{ltlVA*XF+&6jD=8wk!$C ztS_>$?tB?~X_wq;55V&gK^TfTg)>Y;r~yn|3dn7}hbi2Ql-3@_4kUsDdS?v{HTYI&$+F|xxy_{i45#thLY;^OD~$C$QH(&t=7rdmCc{7251uBgzCQPJ?D zcH@7P}`h;Fp`IhAskDxWutlT*>Pab6MwBZ(2??=0V2~`vz zZ6idsMkqRh4a8+H0fxnSKkKDri0Zlk3Do~0D^_!U5{fqsXyy-)i%uYDb?F-Gz23Ba zpt*Y7>5H-I-V(sEyaDTH2N{Vdy;Ozu<41_4uNq|1A8dSetXL1eU2o_WoRwn?A#2e3eL3)e4J4*@pt~p| zbcUWjKF#Yl1euJboQw;1i`VLpkTOPMTSp_>p6VcTiJ>&xgZ>SV`-Ti-)-^&90&BYD zGzFX|U;QYct=;v3)buyAoqwmqD_MIq5~(i&7)bFIndu7y09;%!xLSW6z9&(7g3Pb6 z{7rHd+^+sotlT?67lm9g4;^We9v$fmqkG{|Lc4a&1zaIIcr0APeR$nH!RHLg@Y4j? zwWfgv*TK1qJl!IPEEBpC5A`UntJ zx|aih(2(zZ8OFOzohzid!v;*K2WJY8SYJUK`r5451AVM{@dA_eW^4oEBPqpOOmo#Rb)Kk2VystXJ32FwL@iZX# z$D!@pyrd4dIqApO2k4ZIGY|yHwFpQxVjiMmZ@WNWm(FyQ9eq-5p z0w+UWPRpz9L0zo*Di{Xv08LE87v{_30lW%InZ{Md!jKMsaNAh=A_Zz`zaUYM#mZCP zXzO)eSra0_)v z4=nA|3m3qMWYa!exzlTurdWO_^^KKK_s#q3ZyVh$kSdAKZ2$9ollutb<;{Yo5vg~! zA+aaKBun4y`h7UuFwo?XH|?jUClauNkFbJCIfcvnx6k(#?oiV#wV#))cwu^K2<2yx zlxRTOJ>-6xt{=dFe8}ujF&bTcXP9pmgxI)2@5=StSNlMs!-NoNEFTtk^g$N_@MZp~ zl3=|zWJmc6;(e>Twr01A!}}1?56shJcStgBGv|k0LF~kFgImRG-Rvh!B6#2~@H`9h zh~% z4Frk@O4O2Gf9GO|I`u4J=jQpsNk3mO{yCAVwg$$x_k|)!i(*5LKaLb(o7q^5JS-!f zv_o6T6KrBV=!pj;7*yx=J-f+BFWCoaYKyVpx#G$$#K2DphF~zf4S z(~XtJw;mYy+0H+U_VAapz3}Gby+|2xn8z4uc%bU?$?x|kwcouDfh4DxL|fnUg)z?X z(nny?o`=CqX3yz^2uPA_2#{G{i@(7GCbG$mguhq|yNcMS&r*?E>lZd}YWh#HBOgFw zWo{x)f<*wJxB^>5-_$PRg3py zPp)nwLKbpY zHgz~47_?%vIMh{+Lb>Un8jELyPJ#S~VG5?MXDH5o1i;s-GdB}g=id*i=I__B@292* z;F|Z>K}|~Q=F7DwGcQB7^1Tj1sb?*IXHpspV@iJanfAZ1FLVX*DKI+cf5}jT^aTwi&kPciDqWksABE(cfzmlw zT*6Z=AY-mP3VGx_Qnr{Ts~pPgJ-`C&Pn7u}1(lN^er`G9fob7S(f*3mEpG-KG}af0 z@rDwFu*tUQht=N)e}N2gDeZGX;>6{dqG-#NT>F+sbu=zb5!ndF?m*Pi)#~gipg+xCmiZ9r~hDf4bpb*LiTt?g$BYxVjIWz!9o)0U znkvnIYStSvA;gN${pk8_=s-*c&B1rb^0~`Ii)pLi4yYsq?1m_qu9#NTFOhE=$W?9; zC`I9GS9+*aOf0tlse0}^xTCM!M~+B3>y=eN2sYw@z<9d+{g0uVpZWf-%VfE+{;wvl zvCTPh(c{DQ6E7T~woy)HO<&6>8FNwdn~|Xf1fd8D?)}&RU(_K?9{S+44oNY#l;@D( zL1}4_@L~1C)$u7UmS&#y(hqT2oqZ<}<0Ocqmt>_Z>S|e{$WxcShT*Tp5%RX_!XuaD zZBSg=p{z;?>CmI^SF<=$^(L~hwKKVO}gW|>Yj$fM8y36f0=`3d~grzd~H zhH2&vDdG%Ae9xtbZAf04(PK2LSe%_x$S1ETS6}SunZaCCRdk6DQ{-ENf|zHJpqGJN z8Md#Up0eJy@Wi_z?#g}at=$(@Wi|0el9Q0ceTg{Ji_?DUoshX3iG}kN9@pH&TQ~)M zwcb6km%zWK1uHne<}isdrRExG-b)=^I!r0VglZq9-v#D%nMGN{?~olmPHCj?_g+=Krl4yqLcrG=5s3M{_dWxt!{3 zcvl-#YerYb>qsB<7@Eg;(X7*1F%cp`lBHQ_tcdrCt{R>{R)4LZuHo`r?K7EiZR)g6 zi}UZ2eXIbgJ-YwBQtTp9zvlh~75ESP4VBKA`>ucgV0GihAGWW7PbUUv)@Ow*fT*)C z_L2!*xxrnYLsiz~tx77m_;rbRznwiJCi^Wy+_LyKmpvxJza7b4QCoG*LSXB~TbNK( z>_q2T{IV!Vil8488GA_IAwlW|f{CXHZyuL^Cd5P(ZrFRq?EG=jmwK-Jx7Mv`^n>Njp5{jX%9-{xDs`IwY;Py?)1$Dwf{V)Vsz}7D9ik zj7o(rr7Z0W66uMF1e;i;Weh!QUK67bfyoTqctm6=G2TcO3Uq~Gt|F^5)nwT z3qa{MCWYo?TwDN+q|d%dNWV>>hE^>TqA!f0Bkg%$N$C=uiKSkb=y7|o)$W_lys zE?g$YRpmA}60(X_?~cE{q9;SCo%@61U`_E_d(GJOIWh+>UMHuRsu$S8er>rp`A+GA zHM$s_68}NfCz>+#dXuyPhz|M%=*zt#~p9^ zE{GK;;8u7T7(_gZsqSs(#hZKEO3wZ=($+fvJp1cNSQ3rOvHdg(^tSxtN1bU5dFb}p z72Ow7mY2{x<6Y*gRC?a2o#R>p_7k5@&gTxD;pD=~6{k1JS6)W#cy~pP0aEc2ialz8 z0b5NQXCbxI8iO9Emy`9^QN^H{!h_jwk|l)PGCns`iJhJf6rk716?flf6k{gv!bN`W z8H0Zt>$UrZUAZ=I3x14u3~VVzEDJo{2)upiTpcN0!JjX#;+jGp#p+7*AM{o~78XXH zWjAtDaT<1H$jk+?m;hdGZcRf2&iJuBxzc{k->K3!y?^wtv{X_!T{kNy;g?wu$?Z~J zT}5@B!MV-VZx1Cuk6CtVgV@8J({1K}s))sOhtM;p+|iGV)EqbZbfo@r<<}nN)jL!K z@e-k9zFWet`{M zk8^B|$w*W0O~bSb)327+tMrZfW8AnC->>fOSfM3}|8mLcM4z<;sZIa-(t3}y#v)0k zZG*N%=B#32{MJ?5Ot^ZcP@;(>Oz)0utijt%Y+AS-@$B*Ht)-_g7ld>bzvjd`jDX)2 zyl{ZB6mrGt=1%<_({gn=`Tzr^LoL1)8m+0AQaW>^?swD_n(P^uE1gfUR=oz*taW*v z^UwT4%BD+!hW9-n#uw>|3F-0`X;*a7lyf^*gmytXm)&5>9}?cBxOz*%=AC$_a*Qht z56@gBP5tlJ(JC}EbnnWYo69?uH*UOm5$j+=`mk5d@C?ti8rzkQm^{r@dJCfhV}Bpa zhue}Dwk+S}@(c-dn%TdkqjWSGrHd)&SMf|Yeb~uhA&oXJM`450)(c2&zIJ87W&JM0 z1E086{GRMJ)_0cakE=7l5X8m1{D!k|eYKE*Tk@)^=X zc{=^idA(2HLkZ)9*;W5fWdx~wb|HO(g+;oca;osSdt=(IJ>I10!BrG3H2vZAe_;=Y zU+?dx*_*!amgY)q&)Y>>5IyvzV!9v_-RENwTvD#^p*eI_J@$=d{AL56%P%p- z0%yjof|;9CNcJ{z^lIX5@@uD<_n#v~dS>kn+^)Vr9t;*{sHW53-{TO{(W4VBtrPg7 z>tvp8ctXNkls;&lyw~F8-3k(7h-|zSD$BPzLQj{Mv`16e!O@QKy`(4ZmWVBodQ_(8p$^FtKeOk<;xZ}R)nAz;SpQPc@u zob?E1oeD;P7>W8i4K)}fz6^dn>k(qh(d31%L7Z<6lyB{DPCHxi3?m4hMwR}`C}c7u zhW4ty9my1xh9+=&JO@LR{R^vM>enYi1pCq0r3WNJGI6Iry)EWZJmPgXu=db)&W{Og z{Yyjk&~`ruDTm$==_Sl#LD}yhoTPi>j8AV*8ATx^cz5I~?JCGl89j9aK?!|Elscj2 zP#Kn(5c%9Jm*#-cMmkx$hj&@qArxu7GhfxNXjSGog56mHtu%Bs-2vD3eINZkeQJi7 zC=fD#{*laN3J>p<&(d5mOEW(iy;4g z1=iKq{>6&+w|uN?NsT~AeM9cNPt#D(myy)Xzrd!{abgstmv{bFU7vWe{RcEZo(GM4 zsWm|fr(3mS@4xHylcP0iWWTB#)GM24VCr#e{HzuDorhvb%1#3ovq->}=)vG9C$~D|(zm>Pm5V zG}AzaUAn%;;AZid42*HPezMA##0S#NeD$Gfv-vIN&;7O3g8%5lAi0y8jsCqfuhG66k~G*?`90P z#YQ3p%9O7t_2kZQXhZ{mf|v(_uLLg#kafg_UT=VzrYCJhG30yxLM=@4%-3Z{fbd9x zfbrX3U2hU2)jyRlD_}d?e!n7S+b%&9kv7xXEYI#2VA=BMpdbyz+=o`iXtq6YSgrwi z_9eJ|CnWxE1+%gobJiDGE&|DR4a$|7LrGM>0NJ&NM4txfqauzek8hYM6VDYl5wp6E zOH#bIyih~q=tcis=WR$qEOjSXw7ri?ty-~le;6?MA^mTe!lqueqpLKicIk9H#{Npo zt|;kn$0>98-7=qZhfO$Xp+*hWySeQ%k!(&PFZHY<@>+ZASk@lg(MT9sV3>ayl#9zk zco@*MgMmju0Z`ss$53*eOS(dqrb<+syh@E=Qjubc+6Z(3f?KVQ$EzMPCc3Rry*Ox=dlpM)U zP`$cxo#;U{AXs3*p|KjfUf>aV&6QP&JsvCV)IyjaN*vPlq9zvl3eWW4zw&9eqzZch zlAsFg=I`(d2hAIAUh!wQ$5g1K}>4npFd+psvyL=9?kDpmc@{-72P+>aBh%%vJ~THdt(+tql0 z;TnP2ZPiznr;Z-nxJo5o0|3fFL!PE;2DC{*>~l4{o7@!%O}C?W?=$Q^CI;TmmNwnL z8;)?Ima}kELfrhNawX5(0q6H2RHvzGU+=d;mKHtLpG@!&TDu-1S($`j`JYow&-vp& zE*v5S5%JYsC+-GtYeFPFG0?2G!;dgKcv)sNyZ=E)qxgAAqGIRxm6L@58GQuew2Ls8 zAnzFH*mR{)KBz(;NXH9AgDz*N{FA=YM^oSg=J78oN7fpx&C^l1XqZ>9Zh$9h z1m%*EV}q8HZ>S+WbU~AEnD{}yeWfeDqM4`f4m&S}T982!`^ePVPA_wZyximG+iA70oe0Wl|~s73a4t zG;BV)*|A4Z2Uyk4_WYI+X(Lr4{nvs3Se&==_?gpkU*zx3fO_aJ%mn0IUUw9r?-tag zhQ%Y(S#WHpPlYLW17DD?llN!0RFtmRIyhxC9gbwzO8)@xEeTL0`m(VzXDVxZB}d)r zUs@U#bhMATJpnNxX{9?57#o*r(m#aj6?aN_(W5n#*ch5ys7;q&j^>;+)jvy=-*iU7 z0FpY9H5wzZnR#u~J3@f2;Lrh)6Z;?%!=t3i|#*?-X; z`@f{YvF!#o9MnE-|FvEg+<8jxkB5(KU-}z)+y3jow*LwXq#Jw-^E-8LJKz!6v4cAy9Y?{=qZXX@UD^5TNDX*Y(dm5soprs~UiOp!f7$<^-0hKO zU}2Qj9{vLQux^mxLerkH%Ai!!?YH17YB9@NJJl<%7!AdEA9>d&?f6{J7))A`MZ+EtT%{~;v zxO1Re0ZqX$6d_@`8yU)Plb*J#0}z^icr1zj|8!Lj7cmi+U+JAO!Miqt7<&5yBs<=U zh$MvuVFeIP#Sd%S;PP$`ruf#uD0q%H@?xk!Q0Uyg{P&Objb~s!>jt(zg2Nq7|68e& z_}$(fMuJ4i&~}WWFH$U*V>Ap@b@9Ses_qJ3-nReP`GqL>1$$|M`!H@6U3_)Qu%7ZZ z8*MyenWOLF{iLZ%JBxf?7{AkbN#+GJcRokwDap<+5DpWQUxil5gIh4Sbq(NT!!Rh- z4t1=AA#H-}^>NmfxRa2GAKCrt1n;)2ov;3%0S>_53`2khG|dLISgMd#bNInkkS=oA z2C~3_%Yj<^XB~-D&manLz!1!P;zokS`6m$$3Gj3=5GCfEyH@+pd})Us^oi%&Kga-*iowr{U1zbpsu&Aq zZG^UAi|+J6mF=7`EDJ1E{MU{#hMiXkZ(~UBru(VGRA?V(2d|gU^Ia7`yJIMG;Ea@= zmpV+j`?F8sXP;g6@;FE$z>8URJ>9={M)uf&gWLAf4#C>WXs=pqpGW|iQbS#;@vx&T zMtxscxpe@*JrBINOuqdz=do~l%Z43ryFbfBYoo$C`TWT-vKv{7{deT_-=ALW7u`OA z7=i$pzbxGY7q$ZlMRBq~5F7)IjOk&J5_JcFOe4%}8$zm^5a)aBVFJJ*jMm{weS))k z&_7^me-JRCIp^yipuyqY8N%}j+XasGc8~nujcIn*_l>uZWVjS)dqGgtJqHcd8gO5O zD5z8a?Wn>^ZX6Gr@nv_C!iDdLbDM`7g};8`pn#j*M%0z=-igOE~KBM3_&(B|~-+xjI@C?_@s z#Dscay1rC@N>L|#z25G2zWTiVl88tJbKzJy(%w|qIVcCiAeJ$OJ3J2u`yOmgwX-Dz zZC)usAPL?8V=xAQEw`WV<1GLI_yPxJ1YzLN?LdOZC>40H0H7^Ang>nG01%*K0nj*x zLE=gXn*1KX@bl0)Zpb<2db{KHebaJlH2d2Z($B2G%aAZx8cqUA@lP&+a6KV{to2V7-$V?j%a_ z!rZ`moYRW^wtX{*VC0@OK*sV-%L$L5q4{2wW*;g5ADy@e;oNt%SoyS8KPZ{L2aM!6 z=|hm;YjQPjaB&3aMiOAbUdCL4@?ov#0FSg3qw-j2$=;US=se(0auK|oVmiQhrIe?X*eXddVG{>ih9$T z2Ep~plWpI-Aoc_Qn-ozmJ~W~g>BR!;)9po?z(AqW9!6n)PS{e@o4Txw=lR8S(V#2Q zeAXclNo8!}t3`Dn@3pkvYJR0-TY)7BQeOH|G9{wUN)F>_){Q}+Pk!;9chPTRv_PRk z3$VV+K>2bA`Ll7;sKTJrrvc`~4FQbA%E7*@py}v7ss1LKNq;g_7TUg^3s;Gyb~m^Q zQm>v!hQZwf_JV_Bd;wBeU+ODpa2!Hl38^wv5-h zzd+K0kPY5X{l8nFI2r#jKd3F28Gi05YvZisubye^k^BsrvLguWh@@m6S~}4nOMja~ zQ_l^r5Q1PD4n?E4ppsFb0@jw^#?+sVw_E#fma@gpz!lZ)<9Pr0zBvHZu=) z->THLRKRI7`HF`4jqXXSz5HlG)$oZ1PRuW`T+gI(i7Ny_l40eY&E@maY|_Vf52iBsvIFFa?{|+arYiwjL!*~HA+8>a-nAks z#6r7PWDZ%8SFu97xdf)12;3xn=(Ahk`JH$D?@DXaZf6CP3RYF!V{|9pf*-j6&Tsl@ zTowGf0z}>OF(Z%IDNMJi0K{Ytr@{LL7+dc6H~8tjWHrFwki7skDrMRoe_gb{cLza7 z6qXFmT_t={YTIJNyYS*_jgmQj))Hd)pPW0MbxW_6V%O~kz-1^+xD0a(lG7C&*D2C`iDwrLLn4-V*W>IUmg#2zrJ4@GPE!Z+QkS%NR%WYV;MUm zOH!0wk|nZ~HB1{KC1WdVc9A8NkRr)ewrrIxdkd|<`#q!QInO!2@9Xz{{m%LC^o-B; z-tPOluj{&RteBKBuQt__fb8fB#1U}{iHt175N@!;^TX^W`Vt|+C_N@0(ox6rKa$Ud zZ=@s3_=5}|H$Dc;Scg8ocm{I@BNo!dykTu{*fX0Z!<1vx#eyM2^ij-N;{O59SabT_ z@IA$D%l%};2*a!eoZ5Xc_`6SX+Jh3#ve1|r*SFiHDzQ9X-Vi^J;e{I**S`YSPd{_G zeeaGghi@NZIG11y(De^;7c7U6jflekC8rEWzad+U(wi%TsIhc%9p70#rZ@{X&6~Z{ zX>6sgScmA|L;NdYg6x5aXGL8ZD?Q>76@-YV2x}upAD_V_rJGlhLu%m=>W03S?*~#i zcm|*}`(_bW`?F&J*ZdMz-A11rt1gGJmNHHztN{IaeqvG@jOk;ffrX$bMw{@2aXyZ* zhIF$+&+tO)P-E2}bF!(S?7Rq}LC0dXw)NB9E4NJwHOqfiSktV`e}nOC+q5#}7_ns* z0@f$SZCn}87L1;4{oK>AnW9|)5ARc?-)E$6=If= z7#6sXwJw@59Zz8K%cI>1gK2c2Y7K*6?Z?4d%=u~iuf^G;dm1ipH~|d0`~z^J{5Q{Y z1_F=rF%|5^``)u=_?A3gQK7V92Zzsj8>T!=CEpW=wRjMb41 zi!t5DX9HuUE%I~N3XUE6F*j7{yxDK|v96TDSaPu6t-7mrOp0AvH$5lL@!bqo5{Ep( zS@qPx8~SG$Y;!{dk94*-4boQ-#1K-Ol(!9ETR&iP2X^}DhbkoAwqZ@igN$gd%IAj$ zn)GewXWJu09f4JmjLw_)yNB5r`6_Wn$J;(C!AD~wW??%JCFG6e>3{v++0p=+-=wL z>A$(kv+KgBk>e@A(*K(oy$jkKRKgNHN;+w-z?jbt3J!yK%nyLIy2E>_k8Lzvu1&_k zky+rUX2JL@%)0!|YOP_5BkbRy#5$VFF2wgA^9QKa&S3Cx{)(;XNcW{RJ1^3YFMd7P zFBUL~E{y-TZ+T%W7pKKd%3N2~(9 z!Er_{C;HIxb6tvT5zB#;4B`0yF)6P;0$KD)VBZ!)HFKBrfcF=HLzk==$0--ATZO=k zBaBtNZh4_dsz9fiR0JM(L3n>`N8!k=fNP&|wltruEFbte_A}ww@Wyf;W37#T|C@K+ z0!w$t<5@^X=Ko_B2!fD-_YKbxXR8d_S@V)+4b1nlz3vBa}b2Q>rQ z>!IFJHC94sfB@S;I6%pqZ1sfZf$+Npb$X1eYcoYKlpS<$U|4l7yHOvl^06zZ%Q4KP z6Z>u>h=~U3n^JK1PWS=j=I_pnvqO2&w;L*u;ue`0@mhMPph~jv5d+JdM*NFsfFynd zK3qi6y_{3|po9GMY#v#sgDre9Dsg};!Xa$S*_-q_7Z_XEoVvsgP*trEIt2uCJ9y_H zbg1Bd$IQ;NC>^ooB@8}qZaXkMUgiOnOCV|%ETTLUUBHpz3os&lzHD^oXgnAQDRSA@ z#&2H%Nsx+ohikZ_d!S|WxtledOTuBRmq)V=OE46VaYguuDc~?iJ=L+H08131ln<$+ z5Xx|rsMps6bWF$V!g>-u3vQr+>V_oS4q7CLbao>9?5d$SsWK4FR&b||w`b7(Uj#S^ z0U%Y&wHKU)f*Z=JjK>eX{%{hNv_PU-MtOkR8&|9s@Tyb+K8d4)oHcWbxZx4*vxYVeroGa>qQh;J>EgK)C_IE+dQ z5}Tr~S$$yw28RzwT(N^!cSzdQz+j;~+Yu>O=n9qEQt(EkYh=->0qvG@?OA^PSkM#3 z{er42A`j<&s+7|;0)jlkwIGQD5yJgD*A#nDli1jc{I3jD#-VfHplUmm>dZmoF$J*A z^Gl|gnX#zKMQ=0LQ{p7<3WM}>M}v@mg#t)CoHEx64xXF9{hFONPPF_uTD--)donCZv#k8Oc<5utE|mOvWa{^4cPX@GEs zi0(^}Fqe&0f>lx9Pu-+FXf2?sYd4r7Cv;@_1(sl9;5^kS%OkxWyg^SFLJQr(!1-Yz`UpwOpeO- zPEt#anzRpf38zpU+3C2|{;B)z#E~dT96KIsV&1+_{nqL+F`suJa^97;Ra9UOm}u@< z>ei`eoDLPicCg*@R>uM`2A-; zntpO8&FqBER+L^8bQb59M^7R84|4Q=N}+dgPFp_%cbJwZU2^opg(1GO@4G1VzBhF? zAm5)(xEbApv}G_mOGJ&*V-|gPy%uhL9QeCO+ex>Cg`hG6XOoK##yw9%|3yYu;D<#p z<#*4rgbHBskrVN&(-uXu4JX5jAA4toD*2!o{~N~zKhDiyNIPC)f{${TBS0X{eJn%y zY>-+`&G!T|zL(`s?}3Tk!d`);JGL0c&S}dO!Nm?}z%=HbbE@Dc2OroBj!tB$3PsqE zH9I%Cox16<_^@TK!9-BVcGCFxZ(N|qqeYm_wp87FaNtb=SwYv?51@oTpUk6`rCeEr zVN|4*kk`q2^&(!@J@q)OK8x&vx;!9C?6cZ!B>n^Db1qDoyc&eQ4NT6?4Nu)XakUV2 z3&bW+qY=}@q+Bga4YXxv1$qIJT!ZeR)uF(#U4=HuZ zw7^W6qu3KjGxz;BxIiSVrLDT-evEMb0Bo;9U-HA%u&3pZ8CcZk5PFe=^%iK6l)mO9(lbW|9Olo9WSPDPrI}lABncnA=fpEf3-h zRQPZ5zlbl)E=fJ3B}GBK8!QguLSzSUSkDi4yF%+8gC4xhUN?8k=M0^jT{pcaFRNb3 zfPC)#mlr^sQTl;h9<8WXPQ{8GQO7kd2}2T=cHc9*rW{1QC6q%~M}LeM7hyw|Hbs5p z963N=Yo0{&6Ax=7sy^+2kLJNOmL^&dy(oc9E`pFy?? zaS}n?48=v) zTk3FT;lzZ9EKwox!lZjdX+tJKC^cv({)wR6$XcBP%p@(ekv;W+*kZz8&vu8Bf+mEU z(dx+$?Ih0$)}CM-w;pH>;LFoQYG4U)$EHs_q_Q?^8^?O@n9~}+6KI;5DnjL;u($aD zp<^VqQ3|VxYl^WH+peQ>)6iY0fmz32gsh*{cu@AE9FYgfn$8_^t2hf6<+yb+xNT{t zC<;5xM=`cnCEFjg)xCU^@DG{=AuzZe27AtWtO~~ZO3afJDM@&lVFQ=3f0dKRF6W5Mww@{ z#IJi3mG46(<^CI}X86W7s?bg$6=4OpL)thGFFW2$WEbV~{c?Dnkh^zlrGfB;>yG)A zd+ym~@s1@;)EH&|q@Eq|8wdOQ2Q3biPnj)(;u0Umzfui5UV2*I$+mBLFdP*s|5Tro zD!;dgP&i8!%X5tiC3{M~C6p40Q4kmq=ztV}KD_(38q2*sYd8C6_q4YxI-|@) zvaWH8mLq(F3cZB_kYtp({|-t&M`0^#yDBuhgkz6&lsH1pI6UEQdp$EJQyFh&aQ`l! z!&U(KTihsICw6sI;j*;AP;57Q@crrJYp1K18gdK4yEN{%sT%}59DDz)kxdyflH+{ z9%44gHp!oESul!Dh5CvU zAC+E|QzJc~EJmAIgkD!=B?4+VGvk|Tlj=@tilRD4MPJL0XfdUyN*RycCBSyjka-`aq=qNK`IPR7koFDs&KYFi<*yjG8#&x3u+{_VnNcP`0IGWo|BYct3X$U0r;f`Jde2d`*AzG1Fd zuR^oo=d~PZSeqSn+FqI|d zxKN<(=pJ%pjQ0*TW%IL|)+ryyw?<@V6UBGsLM3q8_mmt=C2DAe$#7bo3f4p3MBhDS zH{tUI*(CU>Xy_v9)61+*;1`oO^dD(Mu)?xSI@sG5e9Ua^FMj*@TR?ZaPU(NaV6>Jz3?NmR+fBf z0Px;Ck3`Opv6M3VySB+V8= z8Tr4yA|$}`8_qBSe{Q)y2kl4s$;0Z3WA@np{U6^=2xuvp0>i7UJ8Kvdqjqb;GkJ$L z!oNcu`jHs#FKli-8)P5?3Z$UQ!sk!Ya`aslykgk)WwBLIwK7>Lb3AmQ@>#=I=RBaJ zT^5r_qc;8%z$IK-@zS#B1N&)4UE?44qQ*YRm%Sgs$uUA~a%%Siw~ZXa#*2)Y+NuW9 zIPF)VxHXKJ`hT3Z|B7|2z&L`mowDLCRF_GqLqMc;LXke`?%%0C4qLo#6lPr{xc5#Bb`I$PGBW7MvbtLBrCF^J5Ks`Z{f6IrWkyee*30N`;$n0azfLK5*$r zZRoV`o4%>JZ~=wnfI&%mvGy5=qOu3`ZkiH5!Wg5D*Nf1j$ahhIT5la{XVA;)!a%B# zB7hC{I7#9mwn;sU3jG)8>E+^zr`Ka4<16ClkFB+Y*P}bcajI@`L zj&SX)L`xP%PTb9*FZ&LZ6O|`6Nt0>^-_kFqx2M|99nj-bedj`{5_jvbGZ3+c>nxVa z{AMssqGgYHv(xJ-?~z0yiPMC!LY`wELUPvyyh=m$4GcItvLC9A4reRl z2D`-?9qd|BhV(x}*(bo7r4-?-0>c0Mi6%k^vVq(10JY?t08*xxPqE$0Qq+{SfBj|= z+9TBZ5_}+vAx#c#fOzNP^yN(e!U({G5NBBqCty0_wr2jaj7Z{ z3fWU0haSzqPsH4YscypOR8Pf6GAe(pcag=FV|sKTu{?$s+({%_XiykpFqB~CYvOJMxgc*$u+YPKg(41d{s%b08W>mETJU8ww3MuyRE|4N`#`=txqUEf#mhv* zl&2S07hyy$zqEiAhaRIYCSXsH3@ah<5fv{MJ-9!M%pYR zn9H9;iJt(|CvvcCnVF>phr(Z9`p-|5`rvgN{4dU~r(ebm5egZc2KtI;u(tVUYv5*P zY>Xk?1521rL8C80`oF=|C>!BssGLjx2YpSnCt+p!>9Y^L5dFvFsQy{K&qfvfhz;Bb zty1z=G_3!}g+ibX$+vL}qqwi6jULa#+I3m-vi#WL2jOOmFFCg|;s_VGnfpk6=bvX; zz9|*$XMFTq|2x}o`8t_0@Gh|zi63?c!2LM)FOH^=Gzwdq|j^nC3Rk9Yp-Wt8}T!Ocbvs(UkjR1P<5zQSulFX;a@ ztQ;a}DO%It02qI;mGoYg-ujR0B)6e&yU|geK^;JA*HklkoH2R-yq(52__&{5hzinI z?HJsd-Jf|`NU;2Qfd2u%X&r-dIC=*}H!KL^a&O!o_6AzbRYu2xZAm{grxQblaZ_M} zi5$Laf~s779WWpv*!c%%{{kQsf*oz4icq|awXggm)ut~%4VZaqR9;3IB62l+L41fr z;Vc-$6avVZ(bxunm=m&#J__aEQaIXs0ETt+;Zpv-jR{CQ5mjK4qN|^)u?ge|G`HuX z$gF8UP(x|@a!^mFn}b29UIelG+a9ppijpYf{nsgF1EiLd%bPcv2ZvqNgm}QI?DZGm z-Q`-3L&?Zp;700OsQ7+m`x0}t7aAZqK{#82JYrO=hk%rI3Uz-)9#?8tH#>lu%A7M9 zsR|-OkY)l33U*>YCAM%c1H6nGX90I=u-P%oU@`fjsm1@S2%=(R1S26M4Ai09Ctlt& zd+lbqR?^mAKwdwa{SJXeE$L}zj#)d_8sq@E#<}L5M}5IWOa3-O zkWsdE)VMCjwhz5G(p z`Z(c>;2F}jIM?++MCFWpQ$=wL&}~(w`x~fPPC*Ij0rX<6+$EY;c{jaq;M^#!Wd>v+ zuCZD&)8L%A|A-@eb=syT5K-EKa@y_06wn$b)saVK36!RKkrED65v2ffSB^aeyhHx& zyiU$!N7hJLlFvjI-eOf}MIhvNCUMk+=?#p-s9~y5^c65=TPHupFZ@MRTJJ>E zwW2#awz~tVQa71$kes0itz17swtrujCSP8>(eqlJEJ+`HkVkbj`rvyctgpWv()#L- z`u-Hd)U1XF&?vsbx1K!y1k@!30JJ`hI70_?A?JE=d#_i}-PAozPB?jK|`;#656}{ z$!P}=?=KR$CJU39b%Ijr6e7%E7~bfBH7=@!N*G*_b?k7h?E*hV7sMyLM2T6!E7Ls* zDUJd8eqAlpq*{>iTdIf>){m-7c}M$km^<~GVaKu7bm*o2qjLr@@4dp0M6IRlaYLv_ zh*8BE*n&(_z611HY2U!V*6c*5Sum7Hs<@Pc(-p&@N?G$`{?esP@wXn=Fj{BC@|jaV zAg(UdJd9qw9~ORW@am%bhvq`0o{D%tyqTJAPbQsmd@BKVu&Lh(ZylR)d=CF|GKRuY zRZuXR^a}0a8iKH!vb8vZrI3x`aH8P_d@SO&zHWjR5L0cA_>{PAg5k5Pm||2hjW~r{ z3&r;d0oL8^&Z`QgI6g7$$FUm!{0b>m0Z7K$NqFM0qDeAnAQCBti$*K(TFpS{9fWM_ZE?)7?-1#l^}ehtq`%j6>3Y+C4+z0XwoGB zKoWhPlTKtKb5fc=pXx=HpJQ9++PlNaRq6B-lW}ZuOTe4g(tOp>LgddyYfi2hw?wGW zRAP&7`Dv7$C&08jR57iTSaAx#Ytt+f63bSgM(c`D+RM)sZ7(F-eHeE>m{yfdEvTzT zG*LpA%^uP-SaUvK8U?SFDSBRj<|b4Lvr^|tya3Z+U@Y8+RtC+)GNUbdFpLj@AB>`b=8pU%KUqwR@ozeI**cFXoluFUx}0U`rfruyIV;#;bX;tR4TY}I&Mz%rMVDe7r9I+?{6*227|M<~u>I7FVdzzaAmXY9p$ zJBIY_cqS4KlA5v>p90HbsD-d5USLZsPY#nXZfg@4yO1TZXc}aIrq4_w2))k5SNh=? zo^Dnl@uTV{>8A+U(4n~^{Vq>0BoO>Fo@iC^HW}R1s zaM`Ap8*Yg9jOQq0BXO&dW^lrYr0sF_?i-BGs|adWha8}rHtIDdEBPX>DjW3_eIPeG z{K8@c67+VpjNbN6dwVasOz-y(qdI{`((dhTf&*yLbk@(o4(|_=rh>kcV+YxH@ zv`FE{i=v zSoH9j^-HZFzV!v2#}s&EdyNVb+4Rqgy)esqj8hVl<2g-?Og)o5T#Px8wiTEbyR7dC5D4^v6 z4PQ52i>^~y%8NOjCe@T)M|u&KN(^@2AXesAR)v9SBF@0};Y5i>oFL8O(0uxK8o3r$ zi?c}V865}f6qj?zbXF?8QOQ4R{9_IH@KoMELi_p}+Jx|OX0knYlsD0{PByfMG50bN zEd$#?UA~y(FnOq^lr(GniYQi*xt+zy;URmWe(;iV&TMomIbcn;RGcsmdCm3T)Qd4M z<-_!&0&t_!f-8iy$sX-Xm*?~8@Fmt;NR~zuDWurph(vv6UG6KH0-{A}b6R&}M6zTi zn(q%qe-t&Gha$7P^*!%rr|~ylRo&{miJ#(g{Rz?MW-q)VCvQm`1bJ7orFL4)0|VV_ zAw>kfLreJGC1GI5CW-RUp)@!!!vEnby@VwA+on@|p-R=bC&E;Q^)3RPHrmDRT3%^w zDC?|pZ)&6`Pek})Auk@DE(EhLqJV+j>??i_6j}enIOhobLwEGBJUxHVV1qxo+uZT{ z+qjl^4F8?tb+Pgf!AU5@;8DK}LJ1c>N-y)LmA=6$PCu=?ffK_P5peaeQA%fXx?nrS z!&p6hTtjx8#oz%t8ah?=m0tl-qO5M(BPagqHlv-GPHvI66!sLDztfGyu!)hT=80cc z{g%F90M6GYt%p5%D44yXf##4aR{PEOrnC%P*T`fx2Mw$VeUL1eyBr9lM!z^LZc%hHg63L_ z%}YEqm(G+6ETSUtPFFZ>Z56g|%SWI=NV-iS{t;qOxYYbSTM1Sn7B8p-8EB#1Y{=~2 z@#Jop1-sE{+fRe{vP{E>LiZqEP8}0l_%3ojqdIl^j(E-Z!M8txmqhR3&gNYUdAWBk z+frhi|F^hF@3Lj>{))gwj@czeLB%_@Tu{`~XN@tw{~0A2Bwc)3hJBUDky7iFx+VbE zDwysh(O{>30=j`HV;&PFlHvlw zV~KhFjllxrs2X<|-y>rX9K0tu$R{HEdill2be=2Ch%lS+L$PUfc^{cUreD%L(b`e zY9yxO>8}K8mi+CFGmsHX`9*8=8uEttuEBzuO0Vmt} zt{rBkJrY`cxh6j$QVDqGsoat-w;Ge0jWeId+i7|LjC$4#z-iY%6T4LrND8<2xu>J! z_zT30W}wKhh_QFb>g$&9hs{Y-Xi=WT^A=)GmnhNCi?C;V+{psuc&BLr|6{=?pJj0T zYxi9#e$J3NLcKz$721ky+UsKBv%0a7pJV09q`;M&Wuw|V9;5MX-ATeWJpnSG3-Tt=V!y$kdARcIDc>2C%T*q|G~eq35!*zhBA$^8*o&~wj3vKR6egstC49evQ*jZs~?XRo<5|7g|v zH%Nu&7s;QQGyvJ?S!8*+35*#$tcPJ5P*UCpnwoC+dscbwO@Y;PN@p;?jrqXWkKMb^ zt$IAt0V%xpREM+_0|`-@Uqw;zE!_UX%2V*#d$1=QaU8~LkiQV}IKJ63*6x&=IvDdJ z^9u;zy8(kg3G{_Kr+}S@GUZ;dj!hWjmBHG;n|K|Dl2-Qd@YGLxdh7+iLq2TLk*cag z5`!wZUl#aYE$lb?VSGQiOMA9wXQ6)WAY`%$`z!Pee5sfTONcTIjID59X@GR->j2NcJT7r4}{(OqPnso|BqYx-Hg$Owketz*(c&OF0w0DYW+9IAoEP-Vl z8qubi9J441LF~V;!#aP0`{V*vd%>*6n3O|dJYA1A?8Fc?_@{>xPyZ%{i?#I%&1=?O z58#nu<{dx8K?{w$<<<+VtM3qPnTWP--=$xIi~05qMR*HqjX#?NB?x@t-Xa{R_fzAY zkxa6{7w&T2`-9a`kSOn1_(EvV1Xhwao!23zAQYDo#jReOThj|%yem_IiYj9U-%BHF;d{*VLm-6a z4Hx?vge2(|7I+6*>fD5mj#XSeP z^8P}7&P%sAqi{Uy_kWZ^-lC$zyPaV*XkVR@@pmW&l|GU(Y}SLV=f-VuM-gEl4`QD3k_}YB^gTCh!AS4k>d>D1~Vg)M&#Hp@e6NZHdTm z)IVRQAK8iGc?`_+8j_#aJ?;*u*x^{H-dqujRdr7oVKPXvlGn{u4Zbq*zS^Gh{Lb2ZthDNO0_5yfQ zjU|x83E8b*n@=!`H~f*CnaIKrgoSG{qw}SlYj$TteZS>&2yx~ry!pB0a9M0Xw#61o z{;$E{^*I-Q|C-KGqLrg0MYtnN`eD4`O;6pVw#eA{ob`t#D#ir7T9QHvV1pcpIDz}j zZ6;zcAFyhjYwa!7yku)PO^ozQ@s1heU}cg?Q1NO=IAizt1D~lfT*FxJMnKl{=Io6R zk!_DlDi3>SSc`egBVtnU^M1t3OiLD^JwTtVg+cpP~H;}I?=yuzzF-r=+z zh5DO~71UHxuRe>86lgqcV@L&C^Tsn7&vI z723(#NB5vH!6#!Ye!joT4W}`ndK(dt|1<-*SCw#eD#mXOHLBNL*#ZoO{hL&d$=eOX!Q=URLd(uN(@~mHkwb(T zPW||s>*7shHMjH~t2ytVy;b=1#yPok%&^4t(ih3}_JAW;$iQySV(a_?rt(G4ZIWX; zl+8~!js2_O6WE7c^MQ#-UCs0#uMlp=EzE`b!0RaD`WvncTSW zoPVRNW6YLw@1pWlq=3eb+IBRU*=TcUNI}kp(c7B$uT>s?b|y`3cGQ$0yBp!OrG0K% z2(v8a6OB{iN0{~XeW$(G2L4;n!vNdlm^8WASFhV_AG~_~*{Ber?IJ{0rZC-az1WN$ zlM{}}`(|G4ckb2i;H3KTflHFVeoyruB%jpcUOia5r)Zb#neEnh1E*^r;cwmyuU%EY zrxnk~w~=*PY1I`~SLW$Q8nf$rh>MvQZ=91FX)bokGk#EgQ7x+4c+_u{?ZvfT|KCeV z{Uwv{YirNGFxrcu@^bL-98_7$!LJmsVkHxXm1B{T98yp)FcW5(&s+N7!RqZp3kwU$ z8RO&QuAZK;Hm$L~D|mm((^>}i?b-8X?)&WNeLws9`f|S2n3|e?UX<12Ke*D$>ilj4 zPWsi*WdmcFghE1_nwo~j#zYhj9Qc{>`Ps8)ty5=<*HpNz9~|yG@SKB#=f*B!V_c@1 zlBwy7Oj+{s!|>~8DPgUKdV7z&85meUIXM}8k9FJDtt{qiNUM&+cTZtu^0~ ztH%_|%F52ZAx0Ye*Sq)`z^h1|uX#Ir#?_UhtE)>fPr9$W8!ILzcI@L@E6hB+{D*^r zcw8nKZrfQVtM%7yQ4eR3Bq#+a zl`s_-7Y_{&r}q4k)rCQ|U_Sq_cQ#Y@!&b$sJxL>2nVtON&gOmRF|2+>xBy?icwc}2 z&$6P~_wQ|5^0T7K zlexJw17>gL-6_6*{n;Jt-E|{w$4<-aROhm{gfIHAd<&LiQ8l@)!1aypnzbYSk(K>< zmD~3>{XGSKsPKPvmGt!2#W1D83u@iI>4Uv*k^HW}RWAPe_3H&?WpCy+9j-B^K0Mu{ z*BHaFGv)bTWrfr^7Zu^Ne(mnPwIVQy_5OBo8B?@Cmfzw0&Pd;~xC+Hlroc8Bsx%$# zDvY@Ve1oNc67@ghsb8fuAtmwkbM`j5fMNJm{T1!Un4X;+PikRNNgX_xl=G_W!?nGH z4K_pYb*1+1jdQLta6BXa_weADt;^yjexCby@cs9nLq0PzGeT|Ix0GF<9ZuoOBZ zJP?Q&Bqb)S;+}by<>s9%{xM{pT~Co=eNy}wFAoEY;+aHBTv}>y>FAm5cCviIH|gow z%sc5=V*X6y8c(Y0c@&HVV^R31*PL21_Vxi229vRFa=2_A`0Beps_e?jYLYWKG1ejy z&3v^Z&lP()ebV0H)#2qb&yGl8nqqobUSWAck5xe&31g^)0e01U2qO6cnqm{5WfPr+ z3*qCY5#VR1A+u4jbQF=a7g99v?^#JTUCz^6hJp4J-=`eIveNWW)f68;&aY2zA6$7U zeu!nr#t!{t#23j`q0T4m-!Ur4C+laKRi05sZ;&XVNr6*fv@zMjOfk`@T*xNWRhC(e z=-VNK4B5wI=jocZY|^Y$Q(%mN2@$D|9}NP3Z(vb2lOG+Oke&_x0tpTEZ=VGi|9b}$ zlO~Xujjb6glgsJG`T98j<|guM#rVOocpE%Sp7egwuf+JQv|sEz>~?Fv|32Y_=J9t` zZ-=O>R1?DlZWxqTS@GFF{jGi@8?QR&=hsSF-Z^$bq!Ex7S5y=d(YZ^6Y@phYiHU}} zzg3-XR5#F5LPQIiR?*S&*t)vzhYW$Fnz-uRI>tnVR}mQLyk1Va9h9FK9UhUrR(*E& z6wm%kM|)@xJ&t8%tbD4_fpj(@_+xWvW@DNnGQVVz{VdmlM+H4I6QkwlM>M39`4?zt zYRsPRtD)*DvAsCzD)R)qnvI6H)nr2otJaw%>TE3jC{Rxo=JFY}1{=|5V{>~-*V%g0 z@jI9)K3{~X8LHkKZmV^l!%j~!Z14}?#oPQxByjQ2xt+8&Vit9?QWD0PqJgJixQpMz zqlh5NRe3!SX!ckvPVbg<_28G~QgazwZp=_PmB@d^#ztR0bnE_c9eHA&uC>zh3QXgz zUwmL+4?dVTe$=#p^~b?Py7y{5g;IiHwq9(25S@!-OsTONU6qapLcJc3!)}P76`pp!u3!4tD1G5qQ&!d4 zZPv$qYi9@wj1tnmMfogg^i=RsJ#QC7>(3I=l(#jvsap=j!6+hvg7a_7%68h_f{8q~|kihoD-ql9yCzMulXiI6% zkJv5RZMx*DS3GWHh2mj|Lqe5ePvm%95^xsAN-I)-KhZr^C!vjYkkj2&-?VwM9Y44r ztSU*}9Y96tW0Je7FMj@Rt>alcZY4kdi`bwmORp`V=M z@0#cA4zFFCd=;?ZGwq4urn{|GtB*bp`{~A1QJrC32{7VH=tJh4KCd%Y*m@L6F~7g; z(J8CIX7|7)PUY z`-d$sAcB3I;8kZmW_a02MaLCWkIarbOkh%%$4+F&XuI`XPf&HOpi)w$7r%R}f_?aY zSoZjXnrdp|a%x8O&$00_wrU>W5fq`JN=?7fB@O=!Rr_bkCP#xQjZiyag!;u~mn$3F zJ+@`35-O;yM18Sh-o?%89;#s4gd>B#i^r!%ZL?xNL(YtCM&NNP*T00Y>vKiiNre4R zwq6u^HJcJMzuo%2Y944`pHXEI;_V zuq1T2^DV6{b)VPca{Ri~N?6@J=^qR=DapC0Np;W(a0PhCxLs8GeovQe8>V+V-{tj0 zJ^I{n#9IBd<5SKGoSFqBSP>*w6qKqz^??zthI=fi?^<5lc_UI3tFt9PZ zB@^BE7v|7$nfRd({6s~hKz?+yJ~+DD3x4|D`ukt))Yf*|7sCdJbAol3nDG=FoI%R8@)Zw6y$(lO8p zwt=|(Zmeu|+;&1X1Q&(jiq#`GM*iqP=$V@y!M@$x9zM4@Ki{CjyR!uQ#WH!{Yq z4`C;n4s##HZ=+wJp~xx!>hQb0tZ6Ef_Oa2XI2KCO+(Qpte@|*_EAlza4&r?ztS+;< zbMM6#S4u$5W8{B*n`=PSVztZ!$+hfIf!Gyzyg$hq{r$p;m&sv?%&26Wn zHt{=JU)w>dVcBtS=@^)u+dh$iy5{L}qkPkf+w)AwB;Q9yFQ^GRb$SQ}9aH4U+F}6j z^UZzo13XSAmn4`47q1*Pn}_BxHls!^It~^VDS3&E=0*d>zZW85C?6ySmVvlb2=Ses z#S+XMqO<7|QDe)WS|~mAgG5Dz1v5$H84BboxvS`*cXV_Hytu*gyctN!Zmup~(z?J_ zW(yo24-w%crJZOJT}z^2PQvp(;Co*;JzAY+@YRC^_2&y=jm;;2w;r8nPS2PI8E=HT z=$3XsT6Or>VO#JfG^0N@llgE?JsMQN5~Ct)83zh)%Rb01{}op;!nz6$=q|2y=>N42 zWK02Nor|&&WrwA&yt*rU z6`5z#fc8PFzwv_Y zO5H{*8}X}ab^sxk(R@y@BZ(cFXReTQH=<93mx9Bad>d%UKr4(Am&5aV#9Fg3$APe1 zh#_7S9jVXechFB~3xDM{kQ^+>GxsCt>qrRe>)#b4Yj%jO0DTsfmyydS_>2~Vqmu5- zg@=haLH#D5#enkk&^)$3Lj&KtZeJRbsGUEb zejXGbmbzwe4i_ef=_^||8jz~H#$RxQP@r;{hD{Uj(}FEE+-BSL*w!&UU##G$)@m6r zU_xB(yslI7^WDkAtH}^FVMS6_!i_1OKlSrGzPv=11F;7)@v)f<=U4c8eO3YC7UZ~Y zl!58S8C3-NHk?&j2JXb+A1X&pJ5KHQicIMhTC#Y}8c3|7GXMU%Yv+2&J2St|%a%l& za+CUbvjkMS&_P~4d~phxozqM2w`X-LmzO-Q5M_)eAUAkjwi-I>P2|qV)Qyv>VZ#nJ z=atWvHlTWW>es{bTD83`m~SzSp0jFKz9M0G-@k|IdLbjnT+{UG`)p=$3cN2xlKfQS zJQJI*nD2VrPW^oMo<|W&9X7EB!XESSTMnyJea@yo;uLrs4_-)O!P}qv))GW*Ia`(; zDex=~;pYs_+|4UEZb*bJPQNdL^Vud|fCK z8kNng=A$1E2Vnr#x{zNs(>y3X#pe4QyJRB~woNx`4KJ@MI4xS-*sOJF>A+0EA-dh_ zYFTq%fAa_XuIH$hx07stC6V_;+#D0#cpH_sJCoAm0TDXr?nyE+ZFyhe_jX(`+3nQQ z@Y^(v0{-yrye2NhaxK5YFo9!nw!&+B{*l9anF7Xk4J;Y%d2Lzw^J=wY(4-jQU-yva zz%NVN)k7my5{|pr@cwK9@44Qg$=N6z6fm%p*Nav|Yqb^aOJC2{+$o>wAU;OxmFA4% zvPC`jHG)UF$xD^S_4W^=ll)&%ixXT;UIwuB zlU@G`8#b-z`Mw7=;kmWa=;ziLZ3M4XF6uq)CWfeU$8q%G;CZ&u=PWgQN0!3{Fnznx z)(tb;TjUqB$mj2h{X>#E?AX96VNR~T$kE(J@B5WRMR{=v2m-Gca*JJhzBc9iyAwUH z*ZvxH8^=w;B3RgVo8_G$KetIC&qf2?5_`uMo5RJ{ie*&$}i(XFyd{WMyjsRcb8@x}U5JY|BcI7=s&5c%O2WHe)~p5V_c;L^T#36#&xKgPD6Iu_}^2iKU$8*Wh}5;T8)iuNcQ zM)&A;9j_zzG`0?rktEe|>T!Oi91`NC?7hjP3)UrRzgF8@a-#4hm7O5v_Jw7+g?Ud@ z#p5!IzY~B+qN8E5SeQ!yz*1gJNOJ5F!py)>b@%v)mysf`Cuv{mMyrJ3cESI)RWO+` zj^!pxPz>w4gZ#MZ-7iuiAu#u&|NJGCaS5&!Rgu^;cM5?Z;U7bL+<4mgvMjAz?jl}~ z=6^F&Zzn^;7AaMs{kRmY8BgO*Q&bnFrH#Jc4(y}Ke)m$1xqDVZ>03GqH_!1t3bi`q zeJ&zaqUIl|`V_L}J~B^wUv-w+DdY^i~2SG!*<|`7_4|0L=U2X2l_Mv1f{Nup+MhexDXrK-N!?_2M2Y z*bt}vDR5%>;4WfI6mM83D?FS6K&C9F^hlYoKd8ww*wiYD7ZBAjctNj672yvzr=K4d zi(nQu|4{l|HocjAM%+^+a3Tx9MUJBE7X2DLllGvTLv*_DRy=A1K3jJseXZvlJ9>8A ze1fV(QwP==5o9d#k6WE-c|xRd49Abm}`!Ax3r`9G@H+;+#=uY6P!dOK-StTD>kqu39n3|xeIe;kwo*Cre{m% z98@I95fH*64V9j}#L%~De6Jb(;_3DP9HiL?U0GESwKufRP~OK{1Y|S9ZCXZ&qMJ6K z=fu?P_n=+)B1PY^<_BFBeaiE*pk4{Nq2lQXP3s9&Cdz#{`vD}*KDIx0T{jq_$`y+? zNwnCb(!a<~Hzt>Uvh;jR45_lCrHbZLTMn#`5_()A4Mn0=OfGeMAT}ZEdNf1@NDG?n zkWzZ_5G2992lg^mpgB#JD0Vgb9&S#L#Xo-6`#4~a5i2)Bo*0{Eixm*|-dBQOqF*(=OeQLJKzkPl0 zhS*NF0dgmHj*l40 zCFe9s#@$-+rz7+NqUIH7m@l z(;0bvI9v-K7=KrL%jSD!QGWPBd%y9!rBF!6jFRZQjBK>piG3#HUpZa9ABkcs-blA|5W}`y&Amp|1Z_Fg|#` zpzyg{$*_l%^1ha(TQQeTzWa;u>zP(1>XSlk$-e)9lomQmtTHQ1#2#Ec@ zb^xOhSJlyKJF6Dt(s(z3o&O^ES+Ysr;VbO7jK5^P)%-!!a;W|2`Xh;E3HH|X_ApA<>%Te?sqYXVA()yr&jp*& z)VmA^YPh$6d*H`b1%uAm>EK`WCp{(_Kih$0G&5A|Wey00;P3B_ZjL3kL3u-pMFWCJ z0i#We48(x!a!?2ot$G;8`TOZc|6|H7iXr;> z-Kve~Gswe@9XcQ#=lLF)wasZwix<++q!yP)PPa?VrlqZ9d}%u0&VsqoCB5B~UaL#h zZYw(V4FX(-&XD9(0{wIn^-1~8pow{A3i7?2&7xYQg?dfK% z)^osKw^O*^Gil({qQd$C4wKf%x4eVtJi^ryjSOPEIc%qs;T@T5%syvxbHU;D8tc-^ zkjIy0O#p@X>D@gI74zX^GtI^1cX5R}m-OM-t=HL|KKLY7LV-|#fE^rFxUZm&4jEBy zuK75?5*LQS>^|EQuRkRUkfwRXj*vWKb7{g|mEjpdS|FmaWn_2!j#?mGc7)cbwjNu) zK0r{^lXEwS<*Bb?Wbg_4eS?;ECl#L(!P}pDWuqIFp|ed zS^|;&3>_y`j{y>z_|FCqj?|G zUTl-Xi!?`I!QQ9|N#~e>S2Z;Ay71=_JQ+;WFwHi-Z#0+K(_c%A_v7`MwrmAHI3$!0 z;5fcPV(zh{`t%qVE)q*$vJ&Zfj+uEFg4RYBZO^zg{7n4T^OWgJyuOJhkE_mVzxqt4 z?=4Hg4W9mf;H!=rG28vPtYE)KoMG!yrrqmldpsyhay;*euCsq2Zt*F)gC#&1jm|D_ zeU`#O6K9E5t!+M9ZC1Tl(yA+1pRz>_Z9JhLbobh?UTv_OfRV!+@#tC_aQRP-t6Z+t zEw`~eXzT%unw6zBQsHA=7{i~EQ@cGKB|YR=g_q4X&j?MNiIey6 zIJmqP32*ITc_RZ)74w;AWEpN@qaK%tD}$;7ryQwvrz{;q zx*UM!*Ohfp{gZu~djX!iI()>k3CJisWh}*mu~I$Hp&{?{;%Kz;_RoSKaKDLtp-@wE z`XpVS7ORxUu})K`=Y^&sJmC2Ack}8Z#C<_`+izU@+SW>14ros;=WA5M9GJi%@5>>C zonPvi$$jv&U4PY}G94HCH?s8XHjK5l8<@|PAh_Xt(~v|5oJ7f1@-lyr;zsg^VQ;QD zMdS{$psn3y{MMML(i}af?(Wvs(4{un!moG*XVmz#R!P@;UHhwnkMYju(Y{MH?3&wL z_C977t%E~ENPH*+EtQg}kpi1d%L?ID&qVNspO07I?Hdi5IhCJBB*e7+q z7r>>BZ$tVEM?@Zm5Og3*?_|KiA-G?4Yrj-%g?*iHcwI0!rj1d`bBN5y$%R5^ z4PX|~@w*EORG4VSmT5wG{4+B)6HSrVotLc_jtzpMD1V5p1_TgNMi4TI4j|i%S$MeW z518?{JR8FXQRR;4JB%tjza0e(-KTksE;y}zdOSg7sZ!0etU-UV_gqWX9{OfXW7qdt zYk)%3|036+wMyQqUh19vANP45goA+%c@6}Yw=K?k+sAn&_z(5S+jQL|usy6x4CCzt zp+cY;HW~$auQ{uH903Fs6`S)cyyi2~9Apvq_r$h$RrUTsJ=@2YCDQ3x1QK2gR9>Is z-Ue@{ITEEs(Z~e)&N!(YuHF{)$GOh>$8mJ}pwbR{ zdW=F5l|P2GF@x&p+jv+PcvxkzFxRk1icqEdzTGVPq4}nb@0~b|{V`w>maDNoPz7HQ z=di}IvXc!y@8UYNf|EM@F}f(gK+X#)W;^*{U#UF5b=jTynIB=!w~&dyO2|cJCF7zB+3|w$M!w7Dsql`bFIs;tod(bBv;@6=qYhw&wum}t@2X9U)_c*3OSz>eJ1048&#)$hWx?+kA0Wd+(6= zXecqu>2S)YmJE6Nq7aSiCpzd-(9ePqy@r?PX1Xh;Qe~4hBrmOq_Kl9!Wyk%Mz0$#} z%l#pjoINp@GCj-hP^j|uTHWDy4&$Id+O^V1BE<31>pndDIJ2`bu(3j8zAxCP9>no zv@RnH0x-P0cU`lFT}3=87nnFOjn>E$eZ509z;b`VU}X z;?_#2Lyd}u6qW~NprPt?N-Bx*bJiyJ#5oxwxfJTLCHgm@`fn9-gCZ6p)R zk61#i|Ey0fdbBL4iLS1OZCK5*OEDdrD#k}%$F=jn9t>E(&$9>);}Ln_qH>|l18i__ z-J!2v1ZZIPF}ZfvI=EH1d)9mz-y<<`tj<@a;_@j-Yw>nIYslwlF>(5bvpipLz{hlP zQJ5=Mlj%EtM^~P$r~Bucl~3X2uX&vOsH{TsYodlOIfoibEHWq;ob7DxH1pvYCE-bV zAeKP2W7xbilWB8`cW9%X%~;CcC^tY!uUh2=Q`JV-*ieaP`v@brg;C$S2M%)Z?T@D; zjq3ls0QW+X!5%zTJV_^=sVY(u%YLywQS+@L1mUE5W0KrA&ut1hX zD2ouC`ri{$eZ}u*Cm{A*dw`z8OU1dV9&v(TBUq9fo<9cfxhL(Kuj>Nj7xGF5J-1T5 zz~5U@O2aCP#q^$@FUES%$*ECwjI<2{o;PgA9B5lL+3^{sEqC88EU@X|hY7k>6mfWM zk?a?KwFs}a7MpZ6ayWmTL5}WtJ*dR%io9`zeGqrqx`Mr_y;G8^YvX=cjfYhYk%U8s z%;JWmTzd4^^~ZjGjPq5QRhAG~hXhXnLzZ*jdN|wHqsvJhtz#?)OaprZ?}LXXAV z(PDLXrC(z9Ne1M#Pv%y=8n2(WzYlxzgM%=lck()+ZO2+CDySJ<>u$xG-JG$pQqc5D zsUzDBhxt0<2%2$1^54mWAV8qtvERqel}WjUuEs+neReT3DfZV%uOA$C1N54lp31ge zcVSuf$1j5i?V)CU4#ov!EHe_zK2qNVW915CTJqMy(psl1&dxT{->J0WU=Q2<1C`de z9~MjtQav&E2f$p#RCQ;k7UVI+;7Kz1jY&tByl%t-1StYuQzE7Ek}{t{5IFi%OL}(2 zV!e4lAW>$S8LW*AuM%Xdn$~n|#?Rd!N)h=Q8Y}7n{koYQ4L*v@qAUR;IBx#M#6pkNMN zQ~cG8kS@yK{Mv{~HJmZle`InrC1!|PsZHmKGBFbtZAOIS7WYWIZ>snvq9R9cQ)N@Q zPda!Qtwwt`zb2aR{(!Q*rC4lIZ!XeChOT2ciYqmPq8aI7@WyXUmKiMUaqS4(gQ6;7 z-l8UP@@sr}qW1MrV==@t0&kEeSys9_XwgH7`X|q{@i9dvG&mP6mxa>E{Dz~E9@HoW zud0_Fqf!QIn=A*((1&`*l1@lW;UrI1GUEKh4(w;xMDeOxUC>&hyz*REo7?30$=7N`2rMN1VRHU?a#rG8`c-ptaCD+vI&>?2n=!q5%H`aK& zuml;auNz9;g;NSfe8p|dd1VV1WFQMP ze)BO(;!1MGrs~rRMwK^IsFzTcvymI8%_+UJ-JV-O1S1}r!twA72p@FH)nYcK{N|p) zDaH9bYLjZ{Y@uOfxNRr}I6TZy;;@NS#KX8L>Gd))t@jc2E3B3ej&*2$v(XLwe15VA zZCVx%9itx9zsdY^DtTFzvSiq6AU~4Y#UZMGFwqYG!P7!G$6QYdZUB(+xO}D*S9q#E zH!!8L5H>P04jvJP26N_qoTdddB>9j*k&pt!!qTqa=u$FHu~B0YckopBe@AOFbHr8E z721_423Ifj!y5_0TTAc=F3H0mG-hG@XuLIYEF6-$%mo>PGqF>~2VI;K77AiwPY!wY zHs$m-(jx6um}mc{op?&UgMq=h*zRfc33s}4GnQ9h=oKW)*PB<{C;w1<# zI;329(PW#R8~`MgLn{gpw>zeaz+~jjx2(lf!@wctT#ac!AdOYnFZqAUwj_HWR=3d& zRcdS+6IERvQl4X@uCm`dC3`)T(#Ei2sa9kIgTOK1cqjP}xC<|#!oOLs34URE|GuN? zE)&%q!oZE2(JpKff$@p`1mG2W`8)Q`M z7>#mayA9tAN9AU0L)DBkaY(9!kxY}v z^E+0~_;6EdsF17G3gHVBh&VD|-j4W8a_g`paT&1$#Y0l#C@w{q=#?^Fpphdhf^4QL zXN^;uK$s;kbsNbXGYV;Gp(l>#E29rAi8Z@n1*{7jOp(NIn#B>UHPL5YX%4`V&%?p@?0p?0gxL8A{p>p>M7~wg_qpwUb2wE?X;mUF&#Ngh45l7%R~CFW7z?< zhf*B`^2e}WLQ1Bp^oH^eJm##O8V&zm$w2z-Fn1wcH`2|ExfS6?`}*K44oi-CQ$#jTRw*)>9{tyu}eC!v9q%h6bm3GJGi_nO}tQcw%t_aAWv$%&2 zbxae?FpfpZejBV91VRysJS*$Ni3)tDTD_)Zt(``-$2k|?pwlC6RPe;j4hN@{jRVBQ zZc*`^QX#*v7O+5+lShyg)_2HWk6|A7EDC{6*zhH>W7DSq@c_2N@O-fSL;%Co;~_BH zGlAY$kcamGc#gxp@mF(ae5x-AD%l-3mU#LacZi#9_e36&ShQRD-dHerj~7!!(b<_# znW>NlZ||PI6G1{OfJql_1|b(px8gTANC+Z6{d+L`RP-)Z*95A&fzuwwqk3t?Aaw5R5{)OKzdHVs8A(iH5*-0F;Zg`V zXbQu$=l)XOqBeCqd_YoT5S~^g z_j8B(T^J066Z&vV=6S(9_&sUam!Hy{CUgSYtywwbHB?w=?s;%5qeHe(N>eYCfCHWq z9y8F9NCS z8rjaakk)@`sfLhP9)+i*WBUck-3%8hAiyPrSyuW&;|PU|yI*S^^-0Y?rV1cFO}ClNjr-#@LW-_)|~J-UZ_onJDAJNl9TIRK=? zqn>YhKpyIgYsC5?u3nTtR#CKVszG9}A+rEV&(G!gCycr1>sNjG>8&bI|0jolvA9FR zs&47IIII%k39@ZVxC5v1)X|X`J=w3ZNX$wtQB$0@OxFqna2IS8rn zf#F~-E#P>|6lsRU!}37?ozhtq3}pFgF@OjmLcrFCivk{|MKIqa1uG9ne6j4%T-B6>FDXN%VniP68yYS;k#;Uv}v>?OxgBuS#o~m z`v}{_dZDnTF^z7#@ie*(b?@G73gIoAI?h`v^Gh|=Q1c{;a#||5^C>*OqI!4keKcd8 z`-=UjWSW|;jQ!wBD0p-*L%9WsI`%&TqQo%?mKE^Mz-E`$%r?uB@^(3vAcU=J+;jwZ zc#RsPDc6w|IC3cMT=oZcb1$$ANSpR~Y+28bpc&t^b*wSANo6UWE_lle1% z#~KO+cZy4|w6xi;DnGCfq*;r0P-*0p5_E^dO-6*CeJqNl2@m=?$8lc1A+uC98U_7F zEotdT3@rL_5UKynVpGn$rix?QH|9U$77rvaBDy|F>#@;_dHMZ2Qc%#K++UV^O!cm^ z?rPMUD8!&%%9UpIixWy)&#eJv17k+ZYSM4dA|XS{)y3c5ztO4$s#0-UsX(V10$5q<$jDeYW!i|F6YUiqtrecLZn3ZdRJ{riNaR>)$nGD4 zT-*Z{yD>Nj0B9GbYv)~>F?{jV*}TGBP(?pP16M~FNjre%c~D?@yR##{U;fmGnTR-L z!l8foyg7at;p^x-cJUZhv<5T?M)GNAjV4F|Au^=|zjI<{EVy)ynCQnnIH=sqiX&$=^k1~3 zUMNo94tcF640K+8V(!>I*(#$LCMGHtF6#HzT=Wq0@dvaDka&aUEDZDzN0hx;&Msvi zcf#`Wwq`Io7|31e>1;2RDx>R}m<+1$5=$m7QLmI3ph$@bSMW-JU+eqVvX}|Wrj(q9 z%c7zmj#BVe;KUqixr7q09f?XhNsjE>-+X|t)uXKMn$}swApzCep=#}j;mS(v{r0mS zlq+*dI7=BrhKmG%te=+w;IB!L;wTK*Ab%~Zffb{n%d`|G{unNkvbcUk$egT~k?(6@ z^P?!lzwk+FWd4vJf)nN6RHjDK(yDo9aP zSzp<1@^!G*c?PF1(i8;BYXmi|BD0)9h;Z@yTDDWh*yjt#W*+B2ZwjvJ?KIUQoBxeW zGSWueCZ1vp2fPp_smU_p;Sc5c|%+5JA+Dd?RjX^oa1FaGx8k=O;9+%>Xusp z0VKccfQRW@Xe3GZxxu$zgyQ_MXgS2ei$#o)*Hq)3Z=1obxyOIKBm~)R#p)*Y*1lL) zpjW^R59KKjin3c+`0~on{0;tHt2pEEc)?h^T8lCBErU1J-W~+9EJvxx#Od%c?RJal zl9N|6Jq8CydV&XtW~@K6`2_EI*&)-__Bw=d zaM>d8qa6JsPi^pF9E>gP6A2nJD-vbtGKyZbT{C<%Lr$R;In*NRTMjDy<9jy6Ok`Nl9)B6wi)8}sYGRpUAA)HVErsNj2%?l1h>4p@)qhl=i-FBo9-}4G_k70W* zZKfH?OCBQ9jD<20iyi`GFh;btHRqF!&2DSCMn2QV5QuI=MEH6amgw@k68smoR4-P6 zVr_~y{t=!eMXW;}_WS-4k0>GxUT+p$9woUcqB8f;Uy178&b&m8lOiQEH&!!moeBRq}QMFKKB<1 zpYB2Qe6Z%2v35gdJ2f0IY17KNk&T2_MDMn)@CR~KooZm9=JTbR`Q=x5Wi~+9OBC9= zCH_nBg4)F6@XUwxIZc1 z9qOGa@PauHxZRl$%M81!yUTjei7~Mxs3cKjkSfgt{F-Jr^x(dC8};!g{3UQ>0E5WX z_u5*{V$8Bm=#>JPr$I&9>LY}qc8kCgGb^!X=jOl^WA{`3I(D-3b6UfG%DalhS7IDc z!$7vh0jS(jFbbhcR&*a z^i^EijuRI$vNJfeT7eplg{NppHlT?}su>I)mzz#Vn%jSXh|A!#7zUZs*?f8Kq?@8w zv88A*0|&im+z{YRPD>(#*04MY!Q*aoF-GItUC7Z3v=(%qCC)PF0?B@7R)9RdaSwWL z>vivi&vL%hj)YOJ<=~~s`RaD!6JGO{yM7vuD$^ITq%Z*r8!oWc=P}?yuPSSictBR?NUNb;X4_`%A!TW+l-7XAusbhK z!GoN^zY!-x7v;NL`+*a0yR>mi zzji3!8?t1$9rA91;m@uY;N`ILm?mctLMk3dd9D2YDiJaS1;cSnvkBr6m@WHcP$_~{ zg1oHYrEaHMfq~GevEf^A&KF)SRSJ2cn?s-wHcL&twO6wpN)@>_6w(t2&Nortlq->o zH_{XYniB%j1Hg?aoHJ8=B>Z4Sg_?^MtApByz|A}!N$M2^jpwgGhasHj>yeUi7RO0G zaS9GV=%|mWcVF#16~a|(Q(UrFwd%V1=cJUKf7cAs(MzF7$1ZXBis`Kb3|5?+w%SLL z_Hhm}Gd$9CX=f(VDW&ke0pYu{t?T#BE-qc^Jdv#N(z?w58W|jT@lulqdi%}|fhfhn z|`|4L|4~;eSA}V4TO|t=D|9W?t!j=e4a!GWeEmSfVQt zmnHW*@u#`LQ2r0S3GSBI!@yO`9xJ=y!giE)e`y01_~xm>q2Hj?sO6AfZO&} zdV5I$4gU?4+h?>tno}5#PRTG7Q3?W)2nXP`TpZ6QHcy?L9A~jQNo$l6G<+#S5~*q` z6%HJSBSy7aJ#K`ZT5RJF`>%JPWn<@4;2W;>?yBt>%bCM7qoKH@HD`DNqw=K`)ADkV zT}aU<;(X{c-p%P$l*5WU$t#6iR5#E`sZ2$HziXu*vJe%5G6~X{&u@Z_cM_$rw3aK+ zp0QTCPV>0kL7g>&)r+``;vMq@5WVO+D!w*}7SbWqCa}(1;308hRPuDViZ1_3-&i4x zTAW9ezBjZnBB2n`RV zVaJ;6oV>qyA*kqfWbi&+5Hkc&lIo*sYxc%RttPXHF%m+Mf30M{{-r6xEq>1}-S!ib z6d`hNZGDAp9xJ7cZ^j7((q6hP({IAhTPs1^4RJ19aizx%hyJL^552NlbZI&cH4VX! zq%U#{^D;&nJR?l|(9pe)MLd5#r5*$C z3_ba4A|JD-h`fnwAy44Div~tWVAaCqX5V+Ojfp>^L*}%;uN;_SI>DVi*UIMuDTb|8*iYKYh(HV7>ii>onO`J@U2!L8T>cQPu7&H-c$*C8RsP zkixjT;c5{Yq}Y9jN*U7lvl0S|oEC6*{QTDq0cmqyxG#tZl|&o~f3Px27Z48@g-$DP zWJ3j@JOdkO4!omee6CtqTEVu>;3Egh36*)}-R1WY8k{W#CpSYYB?}1;Z$+Kbk%`o~ z6tD%CWwkB}wX6g)E||1Ri+aF#aFt*WG<@MeTNO9VU&r6)od_|ST;$*n|0Pzxe`u>c=-@ZvYXlr>ra%@+D-MEUntA8` z@SLq3`olM5^HO7fMkRH_3j$3Eiut}@9{rrz;vE8d_8@=Y78-C*4*feI4Y>=~I=n@f zp_`nUE^xz?ZNbdxglHADX@UhvAeuT`e?^EO+@jAZT0Xm~wBMXkrZ+E?Lvujq|FwbT zbK3e3U%yS;S~D9wDp0X@y!qL5H)iy-;-}1Fd|Me z+Ln%i>pz8hM~<&Fw*Sfx`=)ftRsLrREbFZW8|8AgXlOmsxGmU}!RlzEdHvo*KfyUUdQ|wEO+QYFGyR;rjd} zrpYxU2n2!<1&oB?ChKR6!hCLh&Clq3|8|4p#>|(GiWv3ot<^M&Rm3OO#DsUR4Z91F zz7(GCEp$;yqcuDT=88~gyECdtsfF}02dx5EwDZz)2M?MPSzzG;U7a5cqDvGACz)JT zq%HCT2B;TOB+>X`0gWv$l%?{tP?-v0Bwt#XmV?+#X~df-tzK`{;A=HMoC%wk>WnPx z=rt0*#-hdRjp_E7Z<+iD2-G{WzbH5sokhRwKY`N-aLOOg)QpTB3s3fj@mYCDDugl(EY29$bx|SMyJ^RE$<+%f*>j(5n7|w zF>lMA`e$anK=ri@Xab(=&6jS$^sfGmRQ{0-&4h+G0yZeC(+*Fut{Ew{SSTNzO2rH^tbuuk?kqakWI2Gcj!*vOw8I8Z5G~gBmunn2OUTsjNesgqsMnc~p* zc4}IfJW4L6&n@OIJ#f*6Ve8|gvoubxavj^lOXPiN+HY!nZX)Hx`?tiXfKbtp9XV=$ z-Yciv*dxME;kpxC>Hw!UZF9lwK6lp5WwSlU6(OVDfj75d@VcGTckJy?{$cI0C2GZyu2jTxZILol8x-JZl$Or-g(p}PxG*W_e zH%Ll%Ez*LU9U-(2%&pESFQ4oNRd z0R7e3bhIpqc$F0YiX|f}fY)#OkFyHW6)O=auqHItc3AE0_sJLxQ~*=(kY%DQ1%2W{G9i!(M6#`KL=mOw;fF9ip>*EN!87JlukOaRO`d(C=<`T_l?Ysva@8R3r9 z=zE)Pb$x7U=c0gaI4J1%es)IE*Se`H8ALyv(?hShRnB1od${9uAyy`d*jgbySo9CdBqRprCDdZ9^;#h7P-Y zNg@^eS6en@`!o&H9 zuhZ-gegGc5hdttockOjskKO2ZP(e*8s+P zJ~(OY$y`$OYHrVHgT}*dv~^M)x0HE6`dt^;&81!6AH8u}E5mk|c(>t0J25am1J}ZS zUp^QvB9CfSGv@U_2fG&?W)Rl-G+)`&5XzhY*M#ibgC9Gr4l)xHsa*Xn^%XlkYxo$g zqHMh1ijALg8SsHqkh>>`7>Zv4#|YtzZvm{q9!>s-Y3H-MUk-&UGZjXE-E#hQRUIDe zQNjiP)eK`*MTyS)g`ZnkmaIoLTe@|o=W!r`>kz$oWrYR`s*KGFsCP^(@Lw(%7!$qt zC-@@+%{P@doudSvVqMI@#L%*gqOYhi!S^i%*HBZ}z>vwHEpft@m9uITu84#4sP2AggsE*oZ^DGk=RcafLytRrqT_AF2$Q{36n7;{7=uvmIH zf8%JQW<6YK(nu0fW$| zP^Ho1bJ*9xLm}rGh6{!t-xaHo9u+inPe`{WDU!UZWc;hSfm9t{4@r}=(4477#lyGHoMnhAVVXcPWOQp(*(r2SihqdUzhfrL3Ux?<|+^Kex zCnGh4r-r1jTnZ?(M-B2^KwIQOmeyBmD0qGIctHOOan}qqaP@y39zFu`1*}^ab|q!i z9q(tOH|9}&?{J3#( z#hEeadT$VUxtV`a&f$LhY%4^v^??fzeDv8rEc|#fXtrbe^iiZ=2%;>j`Z*j^;(!Qv z0DyG@09nwmb9Nn+SzqQy0zMO8Kd%jUS+=`(Xm#$4UKHB5z)_(|XbC})oh`+$7(140 zUWG9-Yf0(^p-C4mVF;W@TY(q1Hw_P))}-hoPGEI_^YgCVcZ?uaNuLr->j|q1-?%oIV!FIz%*ZpJ%9RS+ zR|>vc=iroE)zAvl_tmZxiSr>R#1rN#B9D0C_!k4b;7Bg9epO9)ptSVGtrLJ*r~@1T zxw$AzN(xk5ssD_K<&B0;mJelI3F!j%KNt5n?{mpz7?Nv~nYIa1b^rcVOeUE`<3eY` zh*4o20T3S#NIe1-ChLiU{%D<&CA_g^iCKVv5VxNGaNot>()=8RwI!|&qev9w)aaT2 ze6pzE{I9v`8y6q~S%X;*C0A#GXbF?|&lUo?N%1MYm)rds{_`*oy9ClZ=6&YjE!qB) zfmBp)BnJXMq4p4{j(`jxpG4{ZEY?lIpvc4}lgBG0)V)<(U5N4pYlD8{=L%>v3TV-Nihs_)4tN24&l<6NNRHqVr`I_q4o<1pL&bKtms?8NKKFv3 z@*aqSQSM{|AeuaRAJu0^DOd!icloc_Q_ zw>>pL)kvAF*jG6IvY>2GLme@cQCC_*3D6=M`&x=*9m|0sp0uTq7y3D7igCS^z{ST^ z?uh1!_N%$n$5typai7#Hr8HiL(}<%E0)kyd;oLl2LXc#&VAp+rceepYoWZuaZAKSh z;`@)5(K0J9XL^sqML=0obgE5sdOgIe-jnubv_gv$f1h2rfdrpMD;0G*N)uRL|W`O@O)@_wU$ zm%?d=gmzKgdf_zPm2t(Qglu5&o3<-GA>Pa9y=6V>yTqu^`Np}>%R_S~iCJ}?$N$GH zak91)Fb^Q+K9BCC>=}<~ploR;^x_BFHKPmR8(hKpa|$t*n8-XjJj(79M}@u|lk2BT zw(uJH&e+`UFmlFLke9hX&tb-r@IwQIScb)0WutZ z&$)O+UC!dpB*RNp5Rarg%}^LUaRNoqTF|Cs7fG~b5EGRCr7K<%g}gfmC9*gn3ni9v zj>U}US^ZZ8&$D@K60!+`T*pD@b`krXu=lrMqFnkC2}#v7G;rtA=oDW7ti}@2rovDJ zH%-T(RaT6=xk7UpD5rbzNQcBClwv;eKglt@chFJkWHXTvb-X?c^mQEiB`jzf=v76^ z-m7a|gIFHrOYs}2TBXEhI!^OMhDfaQ*mcH>abulbEK8FM1pZx|+>SO~(%1Q2+-y2b z_RgIJ3tUV#5AAum+0~<%EK$ON z2+Q7Mzw`*gJ%whbcW-Qq21oQ=WHWazUr*SWcAqT|IKhz$pZPv86FB-Ggbm@#UVYI- zCL2nFK|S2;B5##BlQX&4YeigMO!0rGIw-3Lt8na}r~F=4@{vr8mHz<^>!%A~n*8j2 z7BHa>b_M&vcngrz4ce5D;Se+ z#??wpe4Q+sb&v8d(ZTmC5-q#a#4|z%U@_OCHbyaijS|6>6rI-HbBo4#_@?Rj9#;Ar zEnlDCz&VW0BZHpEhy4Oujxx?Uo6}qFX9~~aO}vM-SR{BkzjUK|_dNU}@aZ^*`U`Bj zwY=xe*NqV(D~Y?m1XhXMZY?&5^rp7sI6jPVG7)Wcvn0`PTd4(ZY)OF8 zS}j@YoBvy&YT9MC;o{8r&Nz!rJU%r$<9a?OP+8&YhT9##3*kkYzE{=5Z$ZyF1IyjZ zaG%BHm+SNiFL3vgh4G1d5(Z78749>pt=o-!t(L+$h&jJs=^MA}|DcbO5w17&c^t}> z)Z@TD&R2g1Qf53O547xjjx=qkaGI;1X$N=x_*@+YNc+ zC|9850J){Y8jzwJeD$#3e=7)L=1zc zJ>?{vKap%k)qK*}EChSsGnbMqKh1Xn$!A=RNn)<)&RijE>fiiQ6W_1-(34dgg3R86(pd#?ZEMhCEi$9Lai7_F@?c``2y2c0brMs__U#&!DS zjbj!KF#9kiu_6=+sZ!s6%?g$Ix?40j5$9Vu1Ax*3yF6ABElQ049{5qFYuEWsPfAq# zv`7SKhi=B@p@7mxzl+@k`fvTYG7?-_|3?G;8616R0Fh|*mGR!KS@`iFqve>I!8u}q z;gKHh{=s1Bqun5aMiqpO6HlrTn;kq*Xz^@#VV*etQ`-FP_Eod<6VFv)@krmrOd##* z*-YpCd4A?x^CEJztb+1brlxo2W;4gwu{i&2slS!W=Z_`tx^CfFOu~RshFg}9hlS1KCducG7Cu@% z83AcyWpNn7QFi}haaU{^mkeX49>K>OFhOK(Bt5%GdZhfXkY8r%wnroLei68=9M#KR z4o_oDXB7@hkba#KYM#jD+g zxsl>ip$65ou; zl|+GRin3#Cl^+k%@9w(yD0m-`$p)AkG*wA!d9R(?m>#mV>D#|GSoEht1pykk`>{7T zl^<)>MaPFZLN|GVSRLo{xZW-E3S83E`nQ{C9Rm%iEto=P^Eo3c0i0lOrVa-F#AmZz z^Y*{;)$jYAb*taEsTMlPg>wR*#I}DPHh_dhd+^OCC7EAA>&%!jLncAYx@L7W?2<40 zPECe`mX=E-OUn#8pH?T{$f*&UFgI#A&rzd~B1wivTzdM(V5x z`N;)b#N5wg$-^;SqDQt+Uko0RrPiA7b?EC@y5^cEFuZ~dj7Qc!&-k1ojS~6EZ*;Iy zPL`vFBw;$_kigQ`viaF>Izt>(kn0Vo_t|@?fueAxAUa`!kvvJ1R)6SP0?jj3$q-c3 zy~W8XzCR5RTUOX#}k}(Zs?`zqpWjseAw{&imC2S zw*%xu1l9{R-OR1Cmc25CsS?Y$A>}`#@@qJiyuCIT`c*gJRQM(_rLb??x?+`*9?7`^ z-D?hmgonkcc&y6anO6U|K=UGb&i(Mia>c>ZT)s2JH+XVE3KuHH8TS?Ihwudq;B2r& zpkadj1+flOvt8fzvE;Ge4v^KG!2*XN#I~)$Yh%|Et&Wo zFNdGe0ysY1TT@2Xa8Z$Lq|)ef2tFB&EaUlP8w@z{x0Dp!@&%FhMqe)BK~NAV%<-bU z2#3QImxSiZ)9_304p7#E(!`3|rkye>_6MNL$w9Zt{G&-l9xcok9+5ke^2k1=T*70nvj7WKDMZU%NT zI(^?h#>p;B%uUY~UHoDfmZ#5`qc*x9KLt~f&LZOT@L413qW3S3?pMm{!;tCA;@)(5 zG%P%f;sPR!B6ObKu0c|aiIEKEiQ05{7+`-Y$nhr&l792rOZ_U}&>=JK{qufR6^OK! zgK>aXfR>VvOk6bu+p`?OFNcGTV`ACaZxdc&FIks{0okZ*?-3bcLB71SzbK}$1d?JV z!nD$i(xyvNDl)HCXI_nw`4t38S7uEdDWc1hq{m%Fg|8*hE4T_%B+=^=%^^OM15hA~ zdQE}o{KL-$LyJpQ2Qz!^ZJvN)+_6cYT{r7z?lh^VNa&pTNo%z+ZL0XydBGVniwe*4 zAda`Q7Z-~V6l68GKi`idKJRvX>{bO|oyvLrh|&vt+?pSI*5*4EiHmZ)k63J!Fd(9Z z>VFR#Z%$=YqR;o4o67d~l&NI>g_)D<%*Q9aWmc~d;jZR*XTDO_L026hb$kGZa`V2~ zS|h~t*j7EViK24hPWgW@kj8CSUp~|zVgdlsSvKXx)qw=XfR4r|w$v@rnroA?4~O`~ zr4HfVr4;|C{4PKcPp1dZohZrF1P7`Gaew7X_N`~m;jm|uQn#k z1%2Cuzvx9lLs~tGIpOJIpYEAWbA){c!iIl3?y+>Z-qdqlK6;9dIW{e(qx~co5&&n3 z_$&?=odK%ev%hsxJ8ja^UVm!wef+w_?$4t9pX$Hgfzep3ReyLtb@(x=k!<;s9>Tg^BE#t1@=uiXWqA^0F`MUsQdIw!95+V2-xRq48kphK+2&hdmHD7%=hm*LLO-hp@uF`bp!`Q^NmE1O01-kMcO8Bguma~1;+WI7&|z#@y1 zp8r<~?dAbnpqZ?bC8n2Ys_uX5n3(#v|5%7KHCg!W4a}_oxO9-DihhoYc5Sr^#`^xPr7h>?c2)*5aYKA5R}0&2ttW08K)MH#`o=&ZaE0!yUk*pRk>27H zAfK+9YHnyCBudR5;$p2Ro!E=ht@tzjPP&~eeq`&U1;~m%9~M(yT1;x;0kAs)jP#(f zGta4x6bWtEq(viuI7`)=F=8((b+82<*!gH&J!R<*r=@_+NSIxS^(`Nra{603abXq# zs}B@8J8Bx;*V0?=pWiK2O+mcu+S@Mpz2dA0b+*3o>+ru46VuK3L=tXA^1^%F!S#G( zO(=XrD0st&lS!9Qn2tw)g_cpAla*QWb#B5?A>Px{65=#snAeeD`fnj;x8_ti($-NI zV&4X2=Fa8ZDe}huvVdEkC<}H3!OJl7L`lYP@)@l_@@4XVq`YAid@?YMGu3KP^&LdTd zC#3y=E0o$BjGIKyf_sdL(iJpD90Pq@CeN9yShNlb6BSaYO;tkm?~_{_l%%AqOYWqk zsB|T|qokWluDQl+|FhKR`~ClZzlS}xowM`4z22|)^L2YVQju zh0;Q(Q6WsO8H>ULZUMhDBSUFnG)n0FGv*+3kSQ2!3I_RrYz!fA3rpY)YGDSkw)UTY zK7>kP{q4}g3Ik3z!IfYFc^5Gyl? zrMw9i<>TgRXzm1jXVB;r;KPMNrbo(~IE6<=GJ!itYls=h3P0?z3NM5@KXDi5Xe!0eCx{kGL4;v_P*xNiVSd5_N)(qC$(nx*3^B7Y16s-(^Mq{5 z{9S5fB$WY-DZk4G7Rdc84EY@h0+8lku>n8R{tAj4Ms^eN%tKKG8!*n*3rr^?$nzbr zLV)T25x57?l_@ZHc_&tQ7KzM9LlGXJ5ELC^5iRib@^*28U^pxciRmwhutxjwSpIY# zh{uQXMFf&H4-NOFATW3?9qohj2?tXx=`3FhNC?G>iYJ1Ep=41EIf{!6NAvwGUBaS} z0x!Hb*Dc(}91RGG$)j?k{VeI8NNy@l(%^7!uTVOI zD5PRhOgCpDD9Vu&!QjD3Sc?#AhPM^f8RF*e#y2!~j0{D)x$|jMOJMtu(GcK`hUP-J zqDWv^7KVw5;ZubSsuM>9isUmbkcenMxH&ikXvktYvH2vNHOU>gAbCW1SW=vwkxn8J zBOGr7+yY)uPd3zw3~}>_5n2P6&hEGf1cAk1F{orFgCFKdcaI>jVu&CHJd7E_3lC>8 z5nLxYlkLaB!J}AEIKs=9>gY%YkzJwQzCJ=Y(+kh`bhq?(CUad;&R}6U8pTHW)8GW} z5G=$c#9BxV69VJ-yP_y$kRR~P3qy1A_eVyD5iG)7qpguHR5B)<=LK;hIYAkhYQLH0CXOeFh@!?oToH_D8ZyF9 zK*mLYk)&w6D-vktMn!sZ+`ZTgEY1snI4d@$#h6`7Th73p*yt!v_@+DJ0`! z;MO!S*jK(PaEyBd%gU1B5eZz8Y!D=HI9X^Vh;&3pddhVK2lqk>nKWl`G$sN`umQA{ zL9~eSaSQ>YtU>Hh3oaf*APKP~ccFO<3mr-dv0%E3SRAgKFEI>3_a@R@Cq)j;9jY8uBGq3?svA!`7KQ_aU>xE`eINpwU zS2r6Zoe&v=@rZJybG?BxEO7E9ak(H~6qt@-L{adO)&Nc*u?Z-^tsoayU^qe7!; zUW4vBIR;h-_@KIYa@co&Q(Da^{(D#k60E#MRULag`%EQll^Lf9<42Ngu5J6VB+ zzR^zZD5$(kp%cxE=K_4;gn3(95b1cwD7b(@M!Morc&LR9Atra_X*<)EnUHWd}UJijpKFdMQv z!_o&6Ef6_bVxXWHf)hIw#}j&aT42J$BAqyq6dbU$P#a%QKE?*)A0?zl2(gjOFp(1$ z;vGsru)Xj+jz1~P$ra-*^zpVtfqXGQ|41(!iwgD*x3LmN16P*LVZcn0PF6e*3lFxX z4Kx%FMWaEk1hRQ3aNv<-mndLP0xK^#6ikGptvSG;j(8Er%|@Gm)hh%Y z62S`LI}`A9k}t&)>lPWpcY_ibG~f=zLx}PvLI4m#MuU9h`w@+n!z%{;V{C|M- z|3I))BpcX1P-GbJ_CIj^KQQhs3iVQgCAvMP4Y(iAOILAu@ROmU@OVt zPCgVXV4?!Pz|-H7f)VmbR38i!%%y-hUMxBIxNyQPZ7g{a5FsjzCUC|Huu$iS5Coj= zho^;r+F&skhf6a0(GNcNM4@q{#-9OU={)G1>Q*3mfpZe z2pvi@k8pH@TcANvfXEz$zHT9Suoo``7!k>32|2FBD0DOz;_v3|2Bwl|Y#JiWl@Srm zBind5hLGhNAITvQ!R$y@3=3%Dh+)yed<=-mvL*tT43tfT9~5J4MdvYW+}&9$jH^Fi zfOerWArOB~lpD(0+aHSzWk&%0a9J3hhf@R;P35zhTmlD5<}pN0-k}yWFHeClpX%%$ zPGfqLJUv;C{vJrUe+-Jv^+t1`0#_85PL$&m$QkLucZy)e__zx!;UYZOnc<3HdU#L} zLHjbVMzB?Q$h<5Yhdpcu*=b1#u@Mx-&R~W$=?gBx3Q2jY! zJRfThK88wnb>mQ7h|UnKJ5|8&v-Wqwg*t^=dUBoJeT9xf7XjVe73XHjWB?LCMw>@_ zaV)9k2zOU*7=r0#ZcTUgwWMOg@Cb$wO7*0>qdi^O7yz6t!ciXHD69>SVqrlN37CM2 zJ5nsd1%OAx$IGp$g(nx|Y>nXZTu=gni-n(n4fKz56q*CR04-9kmB3okeq<}HrPTr2r=Dq?b#?8;s&)Ln}9TNs( z(8Fw;kzVG0U~fmXD}&3nc12N{-fWr>fNMu8!UOC{#zc#(Jb){11mIcF{TKwHuNMlq z=6MLPTugL?AC=>e;yYTx$#@Shv?ZBsiA0jDy(sQ1W|)_gw-1HKaSlaC6L_KCj7VNI z3hChuhQhgm5HOEIc4A|ZWM=}?k{H9l5OJ;;>qtT_v)tuD zin#CyqASPKH_F-HlZOQ`*MAbCrV;-Wf`B4fjAqM*(OP=E+20LOuCjP8^qTsE^Ry59ucNg~bEhNaE)3W|iUBceiWULJ#fTv@Aiq>+HRjw5JT(moV=Gce@z6 z@5l~!#nQ~ZxvDVj1T#s1fy#7jL|tod&arn>d1vrrRZ=4m`*+QKmGaBW#(%(6WwwgH zL>htVi!c27`<$&PaTuR{IowG4l+s&U^8@UCz-Y4i`NW%dE7#O8IzJBp9?r#*^$JG<7mBn3pbFW74dTD|d{&^*K zyWDFKPfyU!`-OJr8oRxtC>RC*eHpGS8QHNSLH%5NL;VulCvMRBCct|lRMAB8%A>z4 z-b6B6Jski2zc!6W_9n|fKVP2PLEU@rbWJn9&z9>@T>$y7=|auN$M+_SkAhM{e2-3U zJdo3mHUIZxFHRxeK+^9|*!5^wX2mYVZ9RJVr(?YH`Su2Lc63T*)790|`pgQ?eJASm`XXC(5vw3Z&TU(D|(H7b!G!8BDXd|}52p+7A3jEXN zyk(AC3Ax98S7t z*jJEo8e5^Bxv@PiB|p|N2y2Ah+YjrCIiHb$rIduZDh#S!CTF?_{ikk z`FvgI^;lmtZ-JDYwzQ|iwT--XKP>TW#bsjsy|939OHTLHeXji{>J^Ee8Pi&u-DfI; z1HSE+dDJUx`CZ$kPpi!r<_UJ{spxNg)VeJbhpye$dhchR;2nMJe#UZi@4X;rrQy!v zo0{F}m**y~Emrh2+1}TbQS!*U0B%1o$VVAZjt?Nn)TmC*Xd%?AeeQTAUQVraSEyqy{nzGK)X`^yiro>A_|FXVB4`B`Yc_i;cEp8`^O;E^U5! zxj$9J$mfJ*B}aDnau=&@8~I3bj;0$t>PhVsYNZxV5k^%KP+CWCyR;Re24v8(U;51p zn<`#5A6itysxsZ$w+_ADa?_#DQglU*w%(${?Z5QVT_<^$@=f)-&vzQz>@LMXkD*w( zR<%Y-Fi>M&!-RpV)!f6@UEj;X!!8}Wm;OBZ)b@F-=;bRMobx8%uODy2(#LySyMyXa z(_URUBvyw>*hdz49$0Y{z871n2x=fr8>Xsv!aVlNVi#tXB<2@f5{>SK*zSN0Nh%}RAoFfYaWs_W50*+jAKGv~p_>Qm=h z&?4KzDhH|C-X025yS60Nen&MjdHJQUS*Pw%de7L}nOldP#P2Xm{J2|19JaMMt=}He z<}T!y{QP@h5-n9m+|(c+vLo-_a2)~`8nf^r|#@?8jyiTHfqb2n(s*Gk9xtL-P9X?zy) zed#;ZMM_7yZas)z9^k-YJH|}{D9yfj-7n*Q9Xb_8%JkG`L8hO3-_`itIL5W_mW@76 zHXPcZXi>gceE5O&+kyNVqb#fC2^6EmwaFEWgQmwW<&2gdb_rBehag-S3#~Bbdbg@r z$glyY&!bCexPbDY?cKR|9<>K|EywjW{yS<+1;WgZfY9TJFx)w7POxN}P+k$(QUVKZ z%SWFDg)|Hh%fmvPb?DE;7XuTr@)zYnE_A*0tz4YRs@PK&JQ5%KqKj>4OvIe0+}=_b z&dfO&J+y4;*)=b+t3EGty#IZ@`f7zFNM_>6-+Qtt6KKo4x0kPY;&lV|jXY~w7u2yy zadx9|U&ji)fbgS7+#95sRh&1woN7*dT|Jd+e~G+yZpAfc%Z&l4S++M;PlQT-Q=wb* z_Nf=U(5pB@--?U&i+`;@?I}CU<+k8n);STvM)M3(!@6+j$CZn4Lfe1 zVUkgqY+zm*a>x5dF9}NDu6@yGqQ_8DdJdA*;Gb)fwqJZly+Lv*BWv-!%PFo7qsmLV z(7?k-?YiWKDGE7PM|*&CvTIY zR;-lXMs1GDZn!pj#QA$???jkQRRpM(aW(MMyT7J~q@cKwl@iuRdw5XOzGP zCY^qzTYqqAZ>$TlRZ!+D+Fd@b>I-#@waN?GRKZ#t7jn7)+qCDzCD^RU%)}&oudhS%jFaVhttXE8Cz=m3D?g+74|a9uwEAENlLAc= z5C#^vJXiEq=rd39+SbXiXvv=4DC$$S#S7OQG2p0TPU9PLX7=AMJULLSZF6{*@R7Bi zf_U>DoJ%Lr#dnvlfJQ;Dh^@m;Cmhj((f6SjS?(L<+vzg_=M>aG1!trLLGT5#w-r+?s9KgeRsHIwY271u$%GhGMll|E1LUXK5oig zd`F|Nkd&&bj^}$td}(m9y+U69?HP5{?5Ms*7MDb9s#N|7!%yEn%L^GOXfb;Y*Ff1N z6PKFI<||*;DQtdLSr!Uy{jR9}YJQ|t7qW=2CF{XDcRcvZ1Qdj{&t9^02Z)9dxxsdXg1VpIF=lJa{arT;m& zZ;XPwb1#ZbB#?X9=q9n+K~Irv?jz@_0do3%dwJZ zExuuV-1+3J*VKL=f_1!J7XYOjhRU|GRx1-Mdb6iN=nZvqJ+#Q>3CTT0upof(hD- z=Geb_x>tpF2571D8R-A>WjkovNVILsDih`?ZsC*Lf1kMrGCoF}ZaHti`-Cy>ZHrjS zwV(dH&p)O+x$=|fXP+_b_o36fS-09oa|G?Q_Jr9%Ra#22coX5oDgWu7{qO&edF~49 zuJ1~i?aNCwYdd6o{#ttc0Qsy1{q#}$NkR_i(b`&>bhh&G=G0XOdeW>uz3lijS#@9n zvV|D+#BgHzYr1wD5NFWgmcH7b#jnWe_E)|hwR0ywI-=4v*XsgnJ3~Ex zJuz`1v!WGgJJWl~V))M3f%^}l?~du{a2~7>eLL>L8?Kv*sQxH;b!06BDwB-;yb7DU zZrRCpO4G5kRKqxoUsR{{zrHRSeW?Aj>e4H->XG4-0sUXw2oi6n zpWLph36(CSM(@M@iwRe6I);oEngln zGu{`n3nUs34+MnR&U@v?AG+0})GcmYW~F#P;dA1W{zvO0)%GQGzCKzEu79^Dwl8Nm z?y8`Z)1)U^yQ;AC(Yp57;kwGfs*e71+~(E?hcp`*jjwR9qN%%6b)vq@nU1sTD)-%Y zHh$PpuNlGAA$NCa6+g05CrtM^x4rp?h{G!%8%S`lIbII04P7gp`MGFeXPm?Ief8#x zqx*CvdW7N9nsQUYGa~ne1s@Qa(!%;?+n>E3sJY9UI{EJcXCytan<=^p*2=T1@dWtn zaJ~4w02urLx%lo(glW}#Qb@_jXu5bOqcI~rCYN4(tD*3I8+J#L-yY$2(*~KYY}%z! z5clgu?!dJrrV_h`x6N=Z>EO$VvYW|bcfG*0zgRgAN_1_IMc2>f+#OAeRQzebICsYQ ze9UIak>DU^<(rD3+Mh~^N59*fwZLR|+^xG6i)y|czTcL9d-?aF+r#I_?1o@gA9>y- zliqv8b9~dg(_d;Q-tOKvB72o9&HtVmyX(iA?NYuzO4pUa z{0@y!J$Ajl;G!E3mB=PLBGr4y8sLc6*JLZCk~&X2+lK_hZkVgRO`Ec8yFvVoE9xpk zIX8bq9vNyLthl*;Lv>Mp5OKQ4_05~VZsA^)RgQWmMy?`Yl5TaUZ8#~jE8y ztOS$APkr>e4Q%i3fY|pp1xlY^I;pSbDAtT<*s-5(y&8V~@@Y}(NRPGoqQKa}N>P*D zrxnhyqz&)%lJ>*q`fw>97IbE41@c;J2YV~hXHnB%E%zX)w?m}+&4&Jc#e7qCy}`$2*k zf@^?w2QRsDbp5vwbxQeGCvHOX^#niiznqdsyxg|TY}q7%yl#7ylF|BO1G+<-w^~bT zlQ@wSXp_jZ_-n0RHUb$Y2yajBZpo&UXX;uq(NZ3%}S=o}MhpU>ScuYB!|( zdu9iKmhQ`22D1Pw+-Y_r0g-$9fg|yw86bld)gvt``33*fXrqybO1Bt59eDt-`op$=J39z zSsjQcz^60oB@_bgLT{T(Lw)$kw0@kv$PUXxObCz=mu5#+sDwU+ysdxn#ynAs2rC zl;57U5A3zXVao{?(}%Ygza02bJ~0?6-c4>gx@^(jywqfI>;A?s1etaYWj&g@I^j{A zd$6u7&bn6XUq&x+gUU%WNsIMYwH$7<%~@N1L`@-Z8r^}=;x%?hU4ElFZ0A9V{!wd3 zUBDnV-l$*oAi+d(vtBBS|NSgz`4{n}G|M*0*w@3Ka!B1l)>OcK(dc+%{Qq-bcJ(#L z9_y#CQV^9s{8D*wRpIQ^$LOHx^&R4gf}p-9#<{Phv%@#zCqMLYmm zrd2QV(I>_ytLy7VSfwL7Hk1O|esIYj`(I3desa^Vl7BAwUX^j}#I|G^k(#r5zvQLH zP+QuwMd~{*EVJtL&<=_#-557=-$qOJZG}Al05~*T&6Njl58q9m%1;(|9|U41LxVS} zy;*x+)h;%yv+L0+KRe3h_ZOZoXrX*nB1YJp1dQ`{i$xlH^h}gYu6KIOPKr)%DAYa8 z%gg`RZU>$C^b=F--sX^Dgm9@dIF$XBd!0Ud^zYF+rYoPBCT{0NUp&!pdSXYt;&QSZ`lhfbecQY>o_SZd|RZ9aRfcS|w$@G_((jC@y?p5x!AFBB}J}j2))-<|9 zYv~mBXuEr zW?Q=14V3HyK(@G~AHzFTsr-{Dg7i1AE{ z_~zwc&e8nRjJrmCJakazc&cqvjtTA3y6)UcQ-rb%%ETl-{OhfbFHH2>FJpK6%MDjx z4X|xr4dV-sKCBlUKbU6ty>9w_^!k{Z@yddh%Nh7%6&Lf#n@68V#YbaE8;4pBHP6J2 zTb=d|yC%)bPc@9kwG}E4Wj&DYaM}JuXG@<;2L2S3xYFj1gXXPPXl(uGpA#*Qm(~~M zi_s!N+d7LSn_l){C4;|udj#!{I)EEW(D+(&ZEm|u`GWe?fTR(fOCiDX`ANTAAa+2h|z6h1XB~ZUd@5eo)P*_}5FGaMd%Xs%|#Q zL10Git{?bxGh<}O;|tk|?q+gSy>)I&4`#-HI>>-#kCx%uaQdUOcOSPb<+QZyaGnj& z?^}r`yvxlTKaOI5+PG}Z=`@nEMqlo!@q_ud^X@m`47z(JYVr#V=iqIZOl{3Kf*30g z1uGeSH7wfN_x3?)#lAC%$6NO%!Ic*$o~tsgnE{f6;}`K=FsU)Mk_McJ39;$23CAgc2kTG&}g`1sI$FqHQEI; z6P8w>PSR;@)+3jEe^Y;JQSmN9E%DU`$f z5Rq}kusLPBrkUOIouFPcee~*K5woE!oucb!sN~EE+12=5bpR#4x8UH~gY5|OH6A7A z8|N}z0uWElezE3NezDxLEdZjLMR#~9{?k{#zK*(Sz8{u%WS5tw^WuJ^W(}f~SE>P|M5e`MB+M z15D@Y=~({mY5lUEV%nQb{i(I5N#{4K)Qj5!RtDJNzOCb(${#bB19KRV?jU+AODXC7 zqPC-(e~k{}mZQR(HfAWVIfT94P+w)5wjcIxvhVBxbJe8VEAcbB-}EG$kF?XbwWf4B zv$oh_Y_~UR2?{Z}N1o2i{W_U_iLoPwVWU^?fbW)t!8NY52`_iNs z#G(03zpJ`@e58I;)O~c-zFpypR;^zMv*rGhL$NWwEB6(O7Dr#r)?80e-gmC1Myg@* z+;u@QDqvBm_TMR&vi)-fgb@lX%E))h zgD*%uV%UL|G@d$C=iXP6vhmq{L+iGG~mwC?41{Q~>hNB8S! zCQ_3�Us$!sT+B+Z)o5Kh`HPh^Nw$awQoV8414zfuaw4M^EEB2eYdf(tS`He zP|$O|Pdl0&S6vk~rPY?x@ttP~{G%5>ndULjAlz~d<)OLQlTqWJx4{xw z+4Fn48}Ru$8YbT6m;%|A*)AuJii}iorA>0{Z9o7;OX?YHc6aRC$*cMNi9?W<;BKRI z`>hTurb1`#SD)K3DKXW$uZ+ic8eVm9T)pBPa=Iz8{B;LoQ_A{F3_Hc&%?FFWsvaMP zffok&0VmWzvf{NGGF+9uRBveQdv+i@AG9D?uVErV|LH_aBfQF>-)*T(#9Vh!f#0Qn zXjj-<_j{KQuT@vl$vqMfp9TMXC*PM+^3Yb{o5c822p>&H*IugWX|l-vlac$I=I~u9 zU3`m8z3^)C;u@_{_O9{=$wyKR;F}7_#KprWLXk~1IxWbx+Yjw4G_9JxS~C5rH5RFX zzWF3vJ@Lf?g?AgA!QXW}+ndvo9V?2a#g|u0zqL^ zLl>0&(+&#z!`MzbPb^dq7U%_TyEXSjmOkAilPRNX)c&cGu0sC3yX>(S zR_|VFOqyg0l+~6m@6St}4y7|fH5fhY;n^UCa5J@|2BM3>y`kM+N7B~BKik%;SFy71 z(^lD`_J@rP{+<(ekne9s?iUkvzK)%pPhRd-slYA3{uuYXgrv>z-X7!8Qtp{QGr5$q zap|*;W6%dbJ1Z6q*Uy#}ul%ImnM#=Ez>FTP$Q&qB-MFU4!~6WvfV?NQ?{5&Mt2cie z{OjNZD_qtHR*HE5BtR;91J(uj|KkGWnS36~IB@Uz8Hhzx=;Qrq&rR^(t5^)f}8H-=L4eI zZNdh*SNAT!33bjrePxtSSWZXmIVr#EN^j0t!#(aePC&3q#dhF891QkaOl)EjEyD6 z)+v?{bm;xQ3d5}u6}1Gt!9>KM75hUCTw#mj2i{W;bH0~nk4f2{_Ii(#WN~HqxSPZK zJ=+z_I(3UOW{0;hsW$`nbdt=p88MZRoWOmYq-=WWl22Xn%&%$4o`DJ65DULnDOFImXBORDR zBh2rkvn#juqto_8tTk)M{eJFAA}rui-c h~|(r~Q#b!sb4UvbZPpr@y{ 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 + {# parameterize default name "Docs" in breadcrumb via docs_title in conf.py #} + {% if not docs_title %} + {% set docs_title = "Docs" %} + {% endif %} + +

  • {{ docs_title }} »
  • + {% for doc in parents %} +
  • {{ doc.title }} »
  • + {% endfor %} +
  • {{ title }}
  • +{% endblock %} diff --git a/riscv-ctg/docs/source/_templates/layout.html b/riscv-ctg/docs/source/_templates/layout.html new file mode 100644 index 000000000..24c127eb4 --- /dev/null +++ b/riscv-ctg/docs/source/_templates/layout.html @@ -0,0 +1,14 @@ +{% extends "!layout.html" %} +{% block document %} + {% if is_release %} +
    + The latest development version + of this page may be more current than this released {{ version }} version. +
    + {% endif %} + {{ super() }} +{% endblock %} +{% block menu %} + {% include "versions.html" %} + {{ super() }} +{% endblock %} diff --git a/riscv-ctg/docs/source/_templates/versions.html b/riscv-ctg/docs/source/_templates/versions.html new file mode 100644 index 000000000..5b5362b52 --- /dev/null +++ b/riscv-ctg/docs/source/_templates/versions.html @@ -0,0 +1,25 @@ +{# Add rst-badge after rst-versions for small badge style. #} +
    + + RISC-V Compatibility Test Generator + v: {{ current_version }} + + +
    +
    +
    {{ _('Release Versions') }}
    + {% for slug, url in versions %} +
    {{ slug }}
    + {% endfor %} +
    +
    +
    {{ _('Quick Links') }}
    +
    + Project Home +
    +
    + Releases +
    +
    +
    +
    diff --git a/riscv-ctg/docs/source/add_instr.rst b/riscv-ctg/docs/source/add_instr.rst new file mode 100644 index 000000000..3f2afc39e --- /dev/null +++ b/riscv-ctg/docs/source/add_instr.rst @@ -0,0 +1,48 @@ +.. _add_instr: + +################################### +Adding Support for New instructions +################################### + +This section discusses the tasks required to add support of a new instruction generation in CTG. + +Update the Attributes YAML +-------------------------- + +The first step would be to update the attributes YAML to define a node for the new instruction. The +new node must follow the same :ref:`template ` as defined earlier. + +One must try to use the existing datasets and fields as much as possible and avoid creation of new +redundant datasets unless absolutely required. One can also define abstract functions to generate +the datasets on the go instead of having to elaborate them completely in the YAML itself. + +Some of the abstract functions are available in :meth:`~riscv_ctg.constants` for reference. + +Create a new format +------------------- + +If the instruction uses a new instruction format type, which is not already present in the CTG +currently, then the behavior of that will have to be defined in the :meth:`~riscv_ctg.generator` +class. + +This would involve updating the dictionaries :meth:`~riscv_ctg.generator.OPS` and +:meth:`~riscv_ctg.generator.VALS` with the new type. Next create a function ``__XX_instr__`` in +:meth:`~riscv_ctg.generator` similar to the existing ones which defines how the +:ref:`op_comb and val_comb ` solutions are merged to create the corresponding instruction. + +Additional Register Allocations +------------------------------- + +Currently the signature register allocation assumes a max of 3 registers being used by an +instruction. However, if your instruction uses more registers then the +:meth:`~riscv_ctg.generator.Generator.swreg` function will also need an update. + +Similarly the test register allocation function :meth:`~riscv_ctg.generator.Generator.testreg` function will +also have to be updated. + +Adding Instruction Macros +------------------------- + +CTG does not generate direct instruction. It rather uses the template field in the attributes YAML +as a template to generate tests. This template is usually an assembly macro. The definition of these +macros must be defined in ``env/arch_test.h`` header file. diff --git a/riscv-ctg/docs/source/cli.rst b/riscv-ctg/docs/source/cli.rst new file mode 100644 index 000000000..6addf049b --- /dev/null +++ b/riscv-ctg/docs/source/cli.rst @@ -0,0 +1,91 @@ +.. See LICENSE.incore for details + +===== +Usage +===== +Once you have RISCV-CTG installed, executing ``riscv_ctg --help`` should print the following on the terminal. :: + + Usage: riscv_ctg [OPTIONS] + + Options: + --version Show the version and exit. + -v, --verbose [info|error|debug] + Set verbose level + -d, --out-dir PATH Output directory path + -r, --randomize Randomize Outputs. + -cf, --cgf PATH Path to the cgf file(s). Multiple allowed. + -p, --procs INTEGER Max number of processes to spawn + -bi, --base-isa [rv32e|rv32i|rv64i] + Base ISA string for the tests. + --help Show this message and exit. + +To use RISC-V Compatibility Test Generator in a project:: + + import riscv_ctg + +Running the Test generator +========================== + +In order to generate the tests for **RV32I** the following command is used. :: + + $ mkdir tests/ + $ riscv_ctg -v debug -d ./tests/ -r -cf ./sample_cgfs/dataset.cgf -cf ./sample_cgfs/rv32i.cgf -bi rv32i -p2 + +Suite Characteristics +===================== + +Directory structure +------------------- + +The various `.S` files are the tests themselves. + +.. code-block:: console + + . + ├── Addi.S + ├── Add.S + ├── Andi.S + ├── And.S + ├── Auipc.S + ├── Beq.S + ├── Bge.S + ├── Bgeu.S + ├── Blt.S + ├── Bltu.S + ├── Bne.S + ├── env # Contains the necessary environment files + │   ├── arch_test.h # Header file containing the macros used in tests + │   └── encoding.h # Header file containing varios encodings required + ├── Jalr.S + ├── Jal.S + ├── Lb-align.S + ├── Lbu-align.S + ├── Lh-align.S + ├── Lhu-align.S + ├── Lui.S + ├── Lw-align.S + ├── Ori.S + ├── Or.S + ├── Sb-align.S + ├── Sh-align.S + ├── Slli.S + ├── Sll.S + ├── Slti.S + ├── Sltiu.S + ├── Slt.S + ├── Sltu.S + ├── Srai.S + ├── Sra.S + ├── Srli.S + ├── Srl.S + ├── Sub.S + ├── Sw-align.S + ├── Xori.S + └── Xor.S + +Test Structure +-------------- + +All tests follow the test-spec format available here: `Test Spec Format`_ + +.. _Test Spec Format: https://riscof.readthedocs.io/en/latest/testformat.html#test-format-spec diff --git a/riscv-ctg/docs/source/code.rst b/riscv-ctg/docs/source/code.rst new file mode 100644 index 000000000..e07bdaa66 --- /dev/null +++ b/riscv-ctg/docs/source/code.rst @@ -0,0 +1,21 @@ + +.. _code: + +Code Docs +######### + +Generator-Module +================= + +.. automodule:: riscv_ctg.generator + :members: + :special-members: + :private-members: + +Constants-Module +================ + +.. automodule:: riscv_ctg.constants + :members: + :special-members: + :private-members: diff --git a/riscv-ctg/docs/source/conf.py b/riscv-ctg/docs/source/conf.py new file mode 100644 index 000000000..74e98437c --- /dev/null +++ b/riscv-ctg/docs/source/conf.py @@ -0,0 +1,450 @@ +# See LICENSE.incore for details + + +# riscv_ctg documentation build configuration file, created by +# sphinx-quickstart on Fri Jun 9 13:47:02 2017. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys +import os +import shlex +import re + +def get_version(): + changelog = open('../../CHANGELOG.md','r').read() + x = re.findall(r'## \[(.*?)\] -',changelog)[0] + return str(x) + +sys.path.insert(0, os.path.abspath('../..')) +sys.setrecursionlimit(1500) + +# General information about the project. +project = 'RISC-V Compatibility Test Generator' +copyright = u'2020 InCore Semiconductors Pvt. Ltd' + +author = '' + +version = str(get_version()) +# The full version, including alpha/beta/rc tags +release = version + +def setup(app): + app.add_stylesheet("custom.css") + app.add_css_file("_static/custom.css") + +# -- General configuration --------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +needs_sphinx = '1.7.5' +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.doctest', + 'sphinx.ext.intersphinx', + 'sphinx.ext.todo', + 'sphinx.ext.coverage', + 'sphinx.ext.mathjax', + 'sphinx.ext.viewcode', + 'sphinxcontrib.autoyaml', + 'sphinxcontrib.bibtex', + 'sphinx_tabs.tabs', + 'm2r2' +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +source_suffix = ['.rst', '.md'] +#source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ['_build'] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + + +# -- Options for HTML output ------------------------------------------------- + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = True + + +# -- Options for HTML output ---------------------------------------------- + +github_url = 'https://github.com/riscv/riscv-ctg' +html_show_sourcelink = True +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +#html_theme = 'bootstrap' +#html_theme = 'alabaster' +import sphinx_rtd_theme +html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] +html_theme = 'sphinx_rtd_theme' +html_theme_options = { + 'prev_next_buttons_location': 'both', + 'display_version': True, + 'includehidden': False, + 'collapse_navigation':True, + 'sticky_navigation': True, + 'navigation_depth': 4, + 'includehidden': True, + 'titles_only': False + } +#html_sidebars = { +# "**": ["about.html", "navigation.html", "searchbox.html", "donate.html"] +#} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] +html_logo='_static/incore_logo.png' +html_show_license = True +docs_title = 'Docs / %s' %(version) +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +html_favicon = '_static/onlyC.png' +html_context = { + 'show_license': html_show_license, + 'docs_title': docs_title, + 'is_release': False, + 'theme_logo_only': False, + 'current_version': version, + } +html_last_updated_fmt = '%b %d, %Y' +# If false, no module index is generated. +html_domain_indices = False + +# If false, no index is generated. +html_use_index = True + +# If true, the index is split into individual pages for each letter. +html_split_index = True + +# If true, links to the reST sources are added to the pages. +html_show_sourcelink = False + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +html_show_sphinx = False + +# If true, license is shown in the HTML footer. Default is True. +html_show_license = True + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# The default sidebars (for documents that don't match any pattern) are +# defined by theme itself. Builtin themes are using these templates by +# default: ``['localtoc.html', 'relations.html', 'sourcelink.html', +# 'searchbox.html']``. +# +# html_sidebars = {} + + + +# Output file base name for HTML help builder. +htmlhelp_basename = 'RISC-V Compatibility Test Generator' + +# -- Options for LaTeX output --------------------------------------------- + +# -- Options for LaTeX output ------------------------------------------------ +latex_engine='xelatex' +numfig = True +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). +# + 'papersize': 'letterpaper', + 'releasename':version, + 'extraclassoptions': 'openany, twoside', + + # Sonny, Lenny, Glenn, Conny, Rejne, Bjarne and Bjornstrup + #'fncychap': '\\usepackage[Bjornstrup]{fncychap}', + 'fncychap': '\\usepackage{fancyhdr}', + 'fontpkg': '\\usepackage{amsmath,amsfonts,amssymb,amsthm}', + + 'figure_align':'htbp', + # The font size ('10pt', '11pt' or '12pt'). +# + 'pointsize': '12pt', + + # Additional stuff for the LaTeX preamble. +# + 'preamble': r''' + % change the fon to san-serif + %\renewcommand{\familydefault}{\sfdefault} + + %%%%%%%%%%%%%%%%%%%% Meher %%%%%%%%%%%%%%%%%% + %%%add number to subsubsection 2=subsection, 3=subsubsection + %%% below subsubsection is not good idea. + \setcounter{secnumdepth}{3} + % + %%%% Table of content upto 2=subsection, 3=subsubsection + \setcounter{tocdepth}{2} + + \usepackage{amsmath,amsfonts,amssymb,amsthm} + \usepackage{graphicx} + \usepackage{array, caption, tabularx, ragged2e, booktabs, longtable} + \usepackage{stfloats} + \usepackage{multirow} + \usepackage{gensymb} + \usepackage{fontspec} + \setmainfont{Ubuntu Light} + \definecolor{light-gray}{gray}{0.85} + \usepackage{color,xesearch} + \usepackage{soul} + \sethlcolor{light-gray} + \makeatletter + + %%% reduce spaces for Table of contents, figures and tables + %%% it is used "\addtocontents{toc}{\vskip -1.2cm}" etc. in the document + \usepackage[notlot,nottoc,notlof]{} + + \usepackage{color} + \usepackage{transparent} + \usepackage{eso-pic} + \usepackage{lipsum} + + \usepackage{footnotebackref} %%link at the footnote to go to the place of footnote in the text + + %% spacing between line + \usepackage{setspace} + %%%%\onehalfspacing + %%%%\doublespacing + \singlespacing + + + %%%%%%%%%%% datetime + \usepackage{datetime} + + \newdateformat{MonthYearFormat}{% + \monthname[\THEMONTH], \THEYEAR} + + + %% RO, LE will not work for 'oneside' layout. + %% Change oneside to twoside in document class + \pagestyle{fancy} + \makeatletter + \fancypagestyle{normal}{ + \fancyhf{} + + %%% Alternating Header for oneside + %\fancyhead[L]{\ifthenelse{\isodd{\value{page}}}{ \small \nouppercase{\leftmark} }{}} + %\fancyhead[R]{\ifthenelse{\isodd{\value{page}}}{}{ \small \nouppercase{\rightmark} }} + + %%% Alternating Header for two side + \fancyhead[RO]{\small \nouppercase{\leftmark}} + \fancyhead[RE]{\small \nouppercase{\leftmark}} + \fancyhead[LE,LO]{\py@HeaderFamily \@title\sphinxheadercomma\releasename} + %\fancyhead[RE,RO]{\py@HeaderFamily \c@chapter} + + %% for oneside: change footer at right side. If you want to use Left and right then use same as header defined above. + %\fancyfoot[R]{\ifthenelse{\isodd{\value{page}}}{{\tiny Meher Krishna Patel} }{\href{http://pythondsp.readthedocs.io/en/latest/pythondsp/toc.html}{\tiny PythonDSP}}} + + %%% Alternating Footer for two side + \fancyfoot[LO, LE]{\small \bf{Copyright \textcopyright \the\year \textbf{ } InCore Semiconductors Pvt. Ltd.}} + %\fancyfoot[LO, LE]{\scriptsize \bf{RISC-V Compatibility Test Generator}} + + %%% page number + \fancyfoot[RO, RE]{\thepage} + + \renewcommand{\headrulewidth}{0.4pt} + \renewcommand{\footrulewidth}{0.4pt} + } + \makeatother + \RequirePackage{tocbibind} %%% comment this to remove page number for following + \addto\captionsenglish{\renewcommand{\contentsname}{Table of contents}} + \addto\captionsenglish{\renewcommand{\listfigurename}{List of figures}} + \addto\captionsenglish{\renewcommand{\listtablename}{List of tables}} + % \addto\captionsenglish{\renewcommand{\chaptername}{Chapter}} + + + %%reduce spacing for itemize + \usepackage{enumitem} + \setlist{nosep} + + %%%%%%%%%%% Quote Styles at the top of chapter + \usepackage{epigraph} + \setlength{\epigraphwidth}{0.8\columnwidth} + \newcommand{\chapterquote}[2]{\epigraphhead[60]{\epigraph{\textit{#1}}{\textbf {\textit{--#2}}}}} + %%%%%%%%%%% Quote for all places except Chapter + \newcommand{\sectionquote}[2]{{\quote{\textit{``#1''}}{\textbf {\textit{--#2}}}}} + + \linespread{1} + ''', + + + 'maketitle': r''' + \pagenumbering{Roman} %%% to avoid page 1 conflict with actual page 1 + + \begin{titlepage} + \centering + + \begin{figure}[!h] + \centering + \includegraphics[scale=0.2]{incore_logo.png} + \end{figure} + \vspace*{40mm} %%% * is used to give space from top + \textbf{\Huge {RISC-V Compatibility Test Generator}} + \vspace*{40mm} %%% * is used to give space from top + + + \vspace{10mm} + \Large \textbf{{Release: \releasename}} + \vspace{10mm} + + Last update on : \today + + \vspace*{0mm} + %\small Last updated : \MonthYearFormat\today + + + %% \vfill adds at the bottom + \vfill + Copyright \textcopyright \the\year \textbf{ } InCore Semiconductors Pvt. Ltd. + \end{titlepage} + \sloppy + + \clearpage +% \pagenumbering{roman} + \tableofcontents + \clearpage + \listoffigures + \clearpage + \listoftables + \clearpage + \pagenumbering{arabic} + ''', + # Latex figure (float) alignment +# + # 'figure_align': 'htbp', + 'sphinxsetup': \ + 'hmargin={0.7in,0.7in}, vmargin={1in,1in}, \ + verbatimwithframe=true, \ + TitleColor={rgb}{0,0,0}, \ + HeaderFamily=\\rmfamily\\bfseries, \ + InnerLinkColor={rgb}{0,0,1}, \ + OuterLinkColor={rgb}{0,0,1}', + + 'tableofcontents':' ', + + + +} + +#latex_elements = { +# # The paper size ('letterpaper' or 'a4paper'). +# # +# 'papersize': 'letterpaper', +# +# # The font size ('10pt', '11pt' or '12pt'). +# # +# 'pointsize': '10pt', +# +# # Additional stuff for the LaTeX preamble. +# # +# 'preamble': '', +# +# # Latex figure (float) alignment +# # +# 'figure_align': 'htbp', +# +# 'atendofbody' : ' InCore Semiconductors Pvt. Ltd.' +#} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'riscv_ctg.tex', 'RISC-V CTG Documentation', + 'InCore Semiconductors Pvt. Ltd.', 'manual'), +] + +latex_logo = '_static/incore_logo.png' + +latex_show_pagerefs = True + +# -- Options for manual page output ------------------------------------------ + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'riscv_ctg', 'RISC-V CTG Documentation', + 'InCore Semiconductors Pvt. Ltd.', 1) +] + + +# -- Options for Texinfo output ---------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'riscv_ctg', 'RISC-V CTG Documentation', + 'InCore Semiconductors Pvt. Ltd.', 'One line description of project.', + 'Miscellaneous'), +] + +# -- Options for Epub output ------------------------------------------------- + +# Bibliographic Dublin Core info. +epub_title = project +epub_author = author +epub_publisher = author +epub_copyright = copyright + +# The unique identifier of the text. This can be a ISBN number +# or the project homepage. +# +# epub_identifier = '' + +# A unique identification for the text. +# +# epub_uid = '' + +# A list of files that should not be packed into the epub file. +epub_exclude_files = ['search.html'] + + +# -- Extension configuration ------------------------------------------------- + +# -- Options for intersphinx extension --------------------------------------- + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = {'https://docs.python.org/': None} + +# -- Options for todo extension ---------------------------------------------- + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = True diff --git a/riscv-ctg/docs/source/contributing.rst b/riscv-ctg/docs/source/contributing.rst new file mode 100644 index 000000000..ac7b6bcf3 --- /dev/null +++ b/riscv-ctg/docs/source/contributing.rst @@ -0,0 +1 @@ +.. include:: ../../CONTRIBUTING.rst diff --git a/riscv-ctg/docs/source/cross_comb.rst b/riscv-ctg/docs/source/cross_comb.rst new file mode 100644 index 000000000..b876e4eff --- /dev/null +++ b/riscv-ctg/docs/source/cross_comb.rst @@ -0,0 +1,35 @@ +************************************************ +Test Generation using Cross Coverage Coverpoints +************************************************ + +Coverpoints constituting multiple instructions can help identify interesting instruction +sequences which have architectural significance such as structural hazards and data hazards. +The coverpoint node associated with the test generation is ``cross_comb`` defined `here `_. + +The test generator employs a constraint solver to generate relevant instruction sequence for a +``cross_comb`` coverpoint. + +Example +------- + + **Coverpoint Definition** + + An example cross combination coverpoint is given below: :: + + add: + cross_comb: + "[add : ? : rv32i_arith : ? : sub] :: [a=rd : ? : ? : ? : ?] :: [? : rs1==a or rs2==a : rs1==a or rs2==a : rs1==a or rs2==a : rd==a]" + + **Possible assembly sequence** + + A possible sequence of instructions CTG would generate is: :: + + add x3, x3, x4 + addi x5, x3, 1 + sub x6, x4, x3 + addi x4, x3, -3 + sub x3, x5, x6 + +The test generator also embeds appropriate macros for initialization of registers and signature region pointing registers. + +Note: The cross-combination test generator as of now, does not support load, store and branch instructions \ No newline at end of file diff --git a/riscv-ctg/docs/source/csr_comb.rst b/riscv-ctg/docs/source/csr_comb.rst new file mode 100644 index 000000000..f9f596de8 --- /dev/null +++ b/riscv-ctg/docs/source/csr_comb.rst @@ -0,0 +1,26 @@ +************************************************* +Test Generation using CSR Combination Coverpoints +************************************************* + +CSR Combination Coverpoints can help checking for some basic compliance with the privileged +part of the RISC-V spec by specifying conditions on the CSR values. +The coverpoint node associated with the test generation is ``csr_comb`` defined `here `_. + +Currently, the test generation is only possible for the coverpoints that test for the values of subfields in CSRs. +Thus, the only supported coverpoints are the form ``csr_reg & mask == val``, where: + +* ``mask`` and ``val`` are allowed to be any valid python expressions. +* ``csr_reg`` is allowed to be operated by a bit shift operator, i.e., ``(csr_reg >> shift) & mask == val`` is allowed where ``shift`` is a valid python expression. +* functions ``old("csr_name")`` and ``write("csr_name")`` are allowed to be used in the place of ``csr_reg`` to access the old value and write value of a CSR respectively. +* combination of multiple conditions with ``and`` and ``or`` is allowed. + +Example +------- + + **Coverpoint Definition** + + An example CSR combination coverpoint is given below: :: + + misa: + csr_comb: + 'old("misa") & 0x4 == 0 and (write("misa") >> 12) & 1 == 0 and misa & 0x1000 == 0x1000': 0 \ No newline at end of file diff --git a/riscv-ctg/docs/source/diagrams/git_flow.png b/riscv-ctg/docs/source/diagrams/git_flow.png new file mode 100644 index 0000000000000000000000000000000000000000..6c2db349bf58bacf4cb98950c3bd6795a824d3fe GIT binary patch literal 21845 zcmeFZXH-*N*ER|PqzMWLD2Sjmm0m(DWN4HK!79!LXCo=G!;8i6a^G1 z(mN6CD4tr)$a!`anKG2UvR>S1aH(7O69Fatp)i9M+ zSEo{`%D!P3sxqDk`~ofo5qsGL>fLY5F@J&11qZnq>ekQsmW?Ufp6CMU`hn=8KJG^sik=W_+}gu66lBa z^M>Qe%<&o!WeqLnEpQ7I!dh0{1o$3^C-?y$=6*f|BJ&m#To^G3I0J*IE2{#-)wPt> z)YX6s4j6w-82-P=Fy-(gW3Yc@h*S-RxmsxjJF6-A2dG=PP`rOj4vY!+3nSr)!GDIS zsVl1~Yy1(492w&G=PZ^;#0CPBGD(I2vXcJd!aSp424L!o$6&)SLBM7FU(C=Lr9cu! z6{Ai>h0|d6kthVke^SF(+ki;1(ViGz*0x3!PA4<4@_s21#M zW*>$n`ato1VGjP+e-n1aiAQ%}D;;mr~4Ue<{?gkDDfG^BK+ZF~G z5%aeON)x53?F4-D4}*{+eMs5_bdbHRh9%6#${3>!v80$fI$L6)j))*{yn`PWqC)`e z18S>{Hid$T0c3wW4Ii8h78*__h1gmV$u>}mBVcu~P}c}MIEJ8Z5~QQ%fnv8FK$6&?V<7@%S6 zgR^xG@HVj~qQend0W@D<;B=5BU|dk9;fDL`fbp*WreKV!j&B&5;_c@YVhN2tcq#xSE$vilW z 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 g{1v-k;B7%#Jus133~Uxc~qF literal 0 HcmV?d00001 diff --git a/riscv-ctg/docs/source/index.rst b/riscv-ctg/docs/source/index.rst new file mode 100644 index 000000000..a81b7407e --- /dev/null +++ b/riscv-ctg/docs/source/index.rst @@ -0,0 +1,25 @@ +.. See LICENSE.incore for details + +.. _home: + +RISC-V Compatibility Test Generator Documentation +################################################# + +Welcome to RISC-V Compatibility Test Generator documentation. + +For information about the changes and additions for releases, +please refer to the :ref:`Revisions ` documentation. + +.. toctree:: + :glob: + :maxdepth: 1 + :numbered: + + overview + installation + cli + add_instr + code + contributing + revisions + licensing diff --git a/riscv-ctg/docs/source/index_bkp b/riscv-ctg/docs/source/index_bkp new file mode 100644 index 000000000..e04f03405 --- /dev/null +++ b/riscv-ctg/docs/source/index_bkp @@ -0,0 +1,103 @@ +.. See LICENSE.incore for details + +.. _home: + +RISC-V Compliance Test Generator Documentation +############################################### + +Welcome to RISC-V Compliance Test Generator documentation version: |version| + +For information about the changes and additions for releases, +please refer to the :ref:`Revisions ` documentation. + +.. raw:: html + + + +.. include:: + +.. only:: latex + + .. note:: + + This document provides detailed information of the IPs generated and maintained by InCore + Semiconductors Pvt. Ltd. + + **Proprietary Notice** + + Copyright (c) 2020, InCore Semiconductors Pvt. Ltd. + + Information in this document is provided "as is" with faults, if any. + + InCore expressly disclaims all warranties, representations, and conditions of any kind, whether + express or implied, including, but not limited to, the implied warranties or conditions of + merchantability, fitness for a particular purpose and non-infringement. + + InCore does not assume any liability rising out of the application or use of any product or circuit, + and specifically disclaims any and all liability, including without limitation indirect, incidental, + special, exemplary, or consequential damages. + + InCore reserves the right to make changes without further notice to any products herein. + +.. only:: html + + Sections + ******** + +.. toctree:: + :glob: + :maxdepth: 1 + :numbered: + + overview + getting_started + features + installation + cli + tests + contriburing + revisions + licensing diff --git a/riscv-ctg/docs/source/installation.rst b/riscv-ctg/docs/source/installation.rst new file mode 100644 index 000000000..49a85c240 --- /dev/null +++ b/riscv-ctg/docs/source/installation.rst @@ -0,0 +1,162 @@ +.. See LICENSE.incore for details + +.. highlight:: shell + +============ +Installation +============ + +Install Python +============== + +.. tabs:: + + .. tab:: Ubuntu + + + Ubuntu 17.10 and 18.04 by default come with python-3.6.9 which is sufficient for using riscv-ctg. + + If you are are Ubuntu 16.10 and 17.04 you can directly install python3.6 using the Universe + repository + + .. code-block:: shell-session + + $ sudo apt-get install python3.6 + $ pip3 install --upgrade pip + + If you are using Ubuntu 14.04 or 16.04 you need to get python3.6 from a Personal Package Archive + (PPA) + + .. code-block:: shell-session + + $ sudo add-apt-repository ppa:deadsnakes/ppa + $ sudo apt-get update + $ sudo apt-get install python3.6 -y + $ pip3 install --upgrade pip + + You should now have 2 binaries: ``python3`` and ``pip3`` available in your $PATH. + You can check the versions as below + + .. code-block:: shell-session + + $ python3 --version + Python 3.6.9 + $ pip3 --version + pip 20.1 from .local/lib/python3.6/site-packages/pip (python 3.6) + + .. tab:: CentOS7 + + The CentOS 7 Linux distribution includes Python 2 by default. However, as of CentOS 7.7, Python 3 + is available in the base package repository which can be installed using the following commands + + .. code-block:: shell-session + + $ sudo yum update -y + $ sudo yum install -y python3 + $ pip3 install --upgrade pip + + For versions prior to 7.7 you can install python3.6 using third-party repositories, such as the + IUS repository + + .. code-block:: shell-session + + $ sudo yum update -y + $ sudo yum install yum-utils + $ sudo yum install https://centos7.iuscommunity.org/ius-release.rpm + $ sudo yum install python36u + $ pip3 install --upgrade pip + + You can check the versions + + .. code-block:: shell-session + + $ python3 --version + Python 3.6.8 + $ pip --version + pip 20.1 from .local/lib/python3.6/site-packages/pip (python 3.6) + +Using Virtualenv for Python +--------------------------- + +Many a times users face issues in installing and managing multiple python versions. This is actually +a major issue as many gui elements in Linux use the default python versions, in which case installing +python3.6 using the above methods might break other software. We thus advise the use of **pyenv** to +install python3.6. + +For Ubuntu and CentosOS, please follow the steps here: https://github.com/pyenv/pyenv#basic-github-checkout + +RHEL users can find more detailed guides for virtual-env here: https://developers.redhat.com/blog/2018/08/13/install-python3-rhel/#create-env + +Once you have pyenv installed do the following to install python 3.6.0:: + + $ pyenv install 3.6.0 + $ pip3 install --upgrade pip + $ pyenv shell 3.6.0 + +You can check the version in the **same shell**:: + + $ python --version + Python 3.6.0 + $ pip --version + pip 20.1 from .local/lib/python3.6/site-packages/pip (python 3.6) + +Install RISC-V CTG (From Git) +============================================================= + +To install RISC-V Compatibility Test Generator, run this command in your terminal: + +.. code-block:: console + + $ python3 -m pip3 install git+https://github.com/riscv/riscv-ctg.git + +This is the preferred method to install RISC-V Compatibility Test Generator, as it will always install the most recent stable release. + +If you don't have `pip`_ installed, this `Python installation guide`_ can guide +you through the process. + +.. _pip: https://pip.pypa.io +.. _Python installation guide: http://docs.python-guide.org/en/latest/starting/installation/ + +Install RISC-V CTG (via pip) +===================================================== + +.. note:: If you are using `pyenv` as mentioned above, make sure to enable that environment before + performing the following steps. + +.. code-block:: bash + + $ pip3 install riscv_ctg + +To update an already installed version of RISCV-CTG to the latest version: + +.. code-block:: bash + + $ pip3 install -U riscv_ctg + +To checkout a specific version of riscv_ctg: + +.. code-block:: bash + + $ pip3 install riscv_ctg==1.x.x + +Install CTG for Dev +=================== + +The sources for RISC-V Compatibility Test Generator can be downloaded from the `Github repo`_. + +You can clone the repository: + +.. code-block:: console + + $ git clone https://github.com/riscv/riscv-ctg + + +Once you have a copy of the source, you can install it with: + +.. code-block:: console + + $ cd riscv_ctg + $ pip3 install --editable . + + +.. _Github repo: https://github.com/riscv/riscv-ctg diff --git a/riscv-ctg/docs/source/licensing.rst b/riscv-ctg/docs/source/licensing.rst new file mode 100644 index 000000000..abb965d15 --- /dev/null +++ b/riscv-ctg/docs/source/licensing.rst @@ -0,0 +1,10 @@ +.. See LICENSE.incore for details + +##################### +Licensing and Support +##################### + +Please review the LICENSE.* files in the `repository `_ for licensing details. + +For more information about support, customization and other IP developments +please write to info@incoresemi.com. diff --git a/riscv-ctg/docs/source/overview.rst b/riscv-ctg/docs/source/overview.rst new file mode 100644 index 000000000..e7d265bc6 --- /dev/null +++ b/riscv-ctg/docs/source/overview.rst @@ -0,0 +1,166 @@ +.. See LICENSE.incore for details + +######## +Overview +######## + +RISCV-CTG is the RISC-V based Compatibility Test Generator. This tool is used to generate tests used in +the official `RISC-V Architectural Test Suite `_ and +the RISC-V architectural test framework `RISCOF `_. All tests generated by +the CTG are compliant with the official `Test Format Spec `_. + +The CTG is similar to a constrained test generator capable of generating tests targeting a specific +set of constraints. These constraints are supplied to the CTG using the `Coverage Group Format +`_ (CGF) File. The CGF file contains various +cover-points for different instructions. The CTG treats each cover-point as a constraint and employs a +solver to identify potential solutions. CTG uses the constraint satisfaction problem (CSPs) solvers +offered by the `python-constraint `_ package. + +Target Audience +=============== + +The target users/audience of the CTG would be verification and design engineers who would like to +create a suite of tests focusing on covering specific corner cases. These tests could then be used +as way of demonstrating the capabilities of the instruction itself. + +Note, that the capabilities of the CTG is completely limited by the limitations of the cover-points +in the CGF. A more elaborate CGF covering all corner cases of an instruction can be supplied to CTG +to create a near verification test for that instruction. + + +CTG Components and Flow +======================= + +The following diagram shows the internal flow of data of the CTG. The following sections will +discuss briefly about the working of the CTG. + +.. figure:: _static/riscv-ctg.png + :align: center + :alt: riscv-isac + + +.. _attributes: + +Instr Attributes +---------------- + +In order to generate tests for a given instructions attributes of the instruction need to be known +before hand. This information is stored within the CTG in a YAML format known as the `attributes file +`_. + +Each node in the attributes files has the following structure: + +.. code-block:: yaml + + name: # name of the instruction + xlen: # list of XLEN values under which this instruction is applicable + isa: # RISC-V ISA extension this instruction attribute belongs to + operation: # a python evaluated string which defines the function of the instruction + formattype: # a string indicating the format type of the instruction + rs1_op_data: # a list of legal registers that can be used as operand 1 + rs2_op_data: # a list of legal registers that can be used as operand 2 + rd_op_data: # a list of legal registers that can be used as destination + rs1_val_data: # a list of integers that can be used as values for operand 1 + rs2_val_data: # a list of integers that can be used as values for operand 2 + template: # a string indicating the assembly macro to be used to creating tests. + +Following is an example of the "add" instruction attribute + +.. code-block:: yaml + + add: + xlen: [32,64] + isa: I + operation: 'hex((rs1_val + rs2_val) & (2**(xlen)-1))' + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + template: | + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + + +Note in the above example `gen_sign_dataset(**)` and `gen_sp_dataset(**)` are custom functions +defined within the CTG to generate the relevant data points required for those fields. + +.. note:: \*all_reg is an alias to a node defined in the attributes yaml prior to the add node. + +.. _opval_comb: + +Op and Val Combinations +----------------------- + +The first two stages of the CTG receive the input CGF file and identify solutions for the +operands and value combinations. These solutions are carried out independent of each other. During +these phases solvers are employed to find solutions which satisfy the corresponding cover-points. +Immediate values are also assigned here. + +If randomization is enabled, then random solvers are employed. + + +Instruction Creation +-------------------- + +In this stage, the operand and value combination solutions derived in the previous phases are combined with +each other in this phase to complete all the fields of the instruction under test. + + +Signature and Test Register Allocation +--------------------------------------- + +Each instance of the instruction should also be provided a signature register to save the result of +the operation and an additional test register to perform alternate target-specific checks or debug. + +The registers are allocated in a greedy fashion, such that maximum number of instructions use the +same signature and test registers. This thus leads to minimal transfer of pointers across registers. + +CorrectVal Generation +--------------------- + +.. warning:: This feature is a WIP and is not completely supported yet. + +For a few arithmetic instructions like add, sll, sub, etc the corresponding operation field in the +:ref:`attributes ` YAML can be easily defined to capture the behavior of those +instructions. In this, phase CTG uses those fields to define the expected values/result of those +operations. These correctval fields in the tests can be used to perform inline checking of results +and debug failures. + +Generate Tests +-------------- + +Finally, with all the fields defined, specific templates of the tests which conform to the Test +Format Spec are used to generate the assembly files for each instruction. + +Parallel Runs +------------- + +Since CTG employs CSP solvers the runtime of certain constraints involving large data sets can soon +shoot up. Also typically CTG is used to generate a suite of test across instructions instead of a +single test. Thus to reduce runtime in suite generations, CTG internally allocates a cover-group in +the CGF to an individual host-process thereby parallelizing the runs. + +Why Random Solvers? +=================== + +The random solvers are essential in boosting speed. With loosely defined constraints in the CGF, +(like ``rs1_val >0 and rs2_val>0``) the solvers may spend quite some time to find all the solutions +when the datasets are large. Random solvers on the other hand provide the first solution that +satisfies the problem and quit after that, thereby saving time. + +A second benefit of using random values for loosely defined constraints, is that it increases the +chances of covering multiple cover-points (that may be presented later) in the same instruction. This +thereby reduces the number of instructions required to cover all the cover-points mentioned in the +cover-group of the CGF. + +One must note that at no point is the coverage of the test compromised due to the use of random +solvers. + +A obvious down-side of using random solvers is the fact that the same test cannot be reproduced +again. However, the typical intent of users of CTG would be to generates tests satisfying the +cover-points defined in the CGF. Since that is guaranteed by CTG, the reproducibility issue can be +set aside. diff --git a/riscv-ctg/docs/source/pseudo_op_support.rst b/riscv-ctg/docs/source/pseudo_op_support.rst new file mode 100644 index 000000000..7a98a481d --- /dev/null +++ b/riscv-ctg/docs/source/pseudo_op_support.rst @@ -0,0 +1,45 @@ +******************************** +Pseudo-Ops Support for RISCV-CTG +******************************** + +Coverpoints are defined in a CGF file under the ``opcode`` node in the CGF. This is a misnomer as ISAC and CTG +deals with mnemonics of the instruction rather than the actual encoding. In order to deal with mnemonics of pseudo-Ops, +and its congruent base instruction definition, changes are brought to the CGF format. + +Format +###### +The ``opcode`` field is renamed to ``mnemonics``. To support pseudo-instructions two new fields ``base_op`` and ``p_op_cond`` +are added to the covergroups. The ``base_op`` and ``p_op_cond`` are optional fields which specify the base operation and the +condition over the different fields of the instruction which when satisfied results in the instruction being recognized as the +pseudo-op mentioned in ``mnemonics``. As an example, ``zext.h`` is a pseudo-op of ``pack`` in RV32 and ``packw`` in RV64 with ``rs2`` +equal to ``x0``. Covergroup for ``zext.h`` pseudo-op can be expressed as follows: :: + + zext.h_32: + config: + - check ISA:=regex(.*RV32.*B.*) + - check ISA:=regex(.*RV32.*Zbb.*) + mnemonics: + zext.h: 0 + base_op: packw + p_op_cond: rs2 == x0 + ... + + zext.h_64: + config: + - check ISA:=regex(.*RV64.*B.*) + - check ISA:=regex(.*RV64.*Zbb.*) + mnemonics: + zext.h: 0 + base_op: pack + p_op_cond: rs2 == x0 + ... + +During CTG runtime, the ``base_op`` field is checked for in every covergroup. The template corresponding to the instruction found +in ``base_op`` node is extracted to generate the test. If ``base_op`` node does not exist, the instruction found in ``mnemonics`` +is used to extract the required template. ``p_op_cond`` fields are not used as additional constraints for the corresponding pseudo-op. +This is due to the assumption that test generation for a base-op encompasses all pseudo-ops associated with the base-op. + +Note +#### +- The ``p_op_cond`` node is relevant only if the ``base_op`` node has been defined. +- The ``mnemonics`` node is allowed to have multiple entries only if the ``base_op`` node is empty. diff --git a/riscv-ctg/docs/source/refs.bib b/riscv-ctg/docs/source/refs.bib new file mode 100644 index 000000000..6ae893ac7 --- /dev/null +++ b/riscv-ctg/docs/source/refs.bib @@ -0,0 +1,19 @@ +@article{riscvpriv, +author = {RISC-V ISA Privileged Specification}, +year = {2020}, +title = {}, +journal = {https://riscv.org/specifications/privileged-isa/}, +} +@article{riscv, +author = {RISC-V ISA Unprivileged Specification}, +year = {2020}, +title = {}, +journal = {https://riscv.org/specifications/isa-spec-pdf/}, +} + +@article{riscvdebug, + author = {RISC-V ISA Debug Specification}, + year = {2020}, + title = {}, + journal = {https://riscv.org/specifications/debug-specification/} +} diff --git a/riscv-ctg/docs/source/revisions.rst b/riscv-ctg/docs/source/revisions.rst new file mode 100644 index 000000000..affc7aa43 --- /dev/null +++ b/riscv-ctg/docs/source/revisions.rst @@ -0,0 +1,7 @@ +.. raw:: latex + + \pagebreak + +.. _revisions: + +.. mdinclude:: ../../CHANGELOG.md diff --git a/riscv-ctg/docs/sphinxext/cairosvgconverter.py b/riscv-ctg/docs/sphinxext/cairosvgconverter.py new file mode 100644 index 000000000..11bf2fc6f --- /dev/null +++ b/riscv-ctg/docs/sphinxext/cairosvgconverter.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +""" +""" +from sphinx.errors import ExtensionError +from sphinx.locale import _ +from sphinx.transforms.post_transforms.images import ImageConverter +from sphinx.util import logging +from sphinx.util.osutil import ENOENT, EPIPE, EINVAL +from cairosvg import svg2pdf + +logger = logging.getLogger(__name__) + +class CairoSvgConverter(ImageConverter): + conversion_rules = [ + ('image/svg+xml', 'application/pdf'), + ] + + def is_available(self): + # type: () -> bool + return True + + def convert(self, _from, _to): + # type: (unicode, unicode) -> bool + """Converts the image to expected one.""" + svg2pdf(url=_from, write_to=_to) + + return True + + +def setup(app): + # type: (Sphinx) -> Dict[unicode, Any] + app.add_post_transform(CairoSvgConverter) + + return { + 'version': 'builtin', + 'parallel_read_safe': True, + 'parallel_write_safe': True, + } diff --git a/riscv-ctg/riscv_ctg/__init__.py b/riscv-ctg/riscv_ctg/__init__.py new file mode 100644 index 000000000..29adebcf3 --- /dev/null +++ b/riscv-ctg/riscv_ctg/__init__.py @@ -0,0 +1,7 @@ +# See LICENSE.incore for details + +"""Top-level package for RISC-V Compliance Test Generator.""" + +__author__ = """InCore Semiconductors Pvt Ltd""" +__email__ = 'incorebot@gmail.com' +__version__ = '0.12.2' diff --git a/riscv-ctg/riscv_ctg/constants.py b/riscv-ctg/riscv_ctg/constants.py new file mode 100644 index 000000000..ccf8e4713 --- /dev/null +++ b/riscv-ctg/riscv_ctg/constants.py @@ -0,0 +1,334 @@ +# See LICENSE.incore for details + +import os +from math import * +from string import Template +from riscv_isac.fp_dataset import * + +root = os.path.abspath(os.path.dirname(__file__)) + +cwd = os.getcwd() +env = os.path.join(root,"env") + +default_regset = ['x0' ,'x1' ,'x2' ,'x3' ,'x4' ,'x5' ,'x6' ,'x7' ,'x8' ,'x9' + ,'x10' ,'x11' ,'x12' ,'x13' ,'x14' ,'x15' ,'x16' ,'x17' ,'x18' ,'x19' + ,'x20' ,'x21' ,'x22' ,'x23' ,'x24' ,'x25' ,'x26' ,'x27' ,'x28' ,'x29' + ,'x30' ,'x31'] +default_fregset = ['f0' ,'f1' ,'f2' ,'f3' ,'f4' ,'f5' ,'f6' ,'f7' ,'f8' ,'f9' + ,'f10' ,'f11' ,'f12' ,'f13' ,'f14' ,'f15' ,'f16' ,'f17' ,'f18' ,'f19' + ,'f20' ,'f21' ,'f22' ,'f23' ,'f24' ,'f25' ,'f26' ,'f27' ,'f28' ,'f29' + ,'f30' ,'f31'] +e_regset = ['x0' ,'x1' ,'x2' ,'x3' ,'x4' ,'x5' ,'x6' ,'x7' ,'x8' ,'x9' + ,'x10' ,'x11' ,'x12' ,'x13' ,'x14' ,'x15'] +default_regset_mx0 = ['x1' ,'x2' ,'x3' ,'x4' ,'x5' ,'x6' ,'x7' ,'x8' ,'x9' + ,'x10' ,'x11' ,'x12' ,'x13' ,'x14' ,'x15' ,'x16' ,'x17' ,'x18' ,'x19' + ,'x20' ,'x21' ,'x22' ,'x23' ,'x24' ,'x25' ,'x26' ,'x27' ,'x28' ,'x29' + ,'x30' ,'x31'] + +def sign_extend(value, bits): + sign_bit = 1 << (bits - 1) + return (value & (sign_bit - 1)) - (value & sign_bit) + +def twos(val,bits): + ''' + A function to generate the two's complement of a number which is of + arbitrary width + + :param val: the input which can be either a hexadecimal string or integer + :param bits: size of the input in terms of bits. + + :type val: Union[int, str] + :type bits: int + + :return: integer value in 2's complement representation + ''' + if isinstance(val,str): + if '0x' in val: + val = int(val,16) + else: + val = int(val,2) + if (val & (1 << (bits - 1))) != 0: + val = val - (1 << bits) + return val + +def gen_imm_dataset(bit_width): + ''' + Function to enumerate a dataset for immediate values: + - [0,2**bit_width] + + :param bit_width: Integer defining the size of the input + :type bit_width: int + :return: a list of integers + ''' + usign_val = (2**(bit_width)) + dataset = [] + for i in range(usign_val): + dataset.append(i) + return dataset + +def gen_sp_dataset(bit_width,sign=True): + ''' + Function generates a special dataset of interesting values: + - [3*1/3,3*2/3,5,5*1/5,5*2/5] + - sqrt (bit_width<<1) + - +/-1 variants of the above + + :param bit_width: Integer defining the size of the input + :param sign: Boolen value specifying whether the dataset should be interpreted as signed numbers or not. + :type sign: bool + :type bit_width: int + :return: a list of integers + ''' + if sign: + conv_func = lambda x: twos(x,bit_width) + sqrt_min = int(-sqrt(2**(bit_width-1))) + sqrt_max = int(sqrt((2**(bit_width-1)-1))) + else: + sqrt_min = 0 + sqrt_max = int(sqrt((2**bit_width)-1)) + conv_func = lambda x:(int(x,16) if '0x' in x else int(x,2)) if isinstance(x,str) else x + + dataset = [3, "0x"+"".join(["5"]*int(bit_width/4)), "0x"+"".join(["a"]*int(bit_width/4)), 5, "0x"+"".join(["3"]*int(bit_width/4)), "0x"+"".join(["6"]*int(bit_width/4))] + dataset = list(map(conv_func,dataset)) + [int(sqrt(abs(conv_func("0x8"+"".join(["0"]*int((bit_width/4)-1)))))*(-1 if sign else 1))] + [sqrt_min,sqrt_max] + return dataset + [x - 1 if x > 0 else 0 for x in dataset] + [x+1 for x in dataset] + +# def gen_fp_dataset(flen,instr,field): +# return (ibm_dataset(flen,instr,field)) # Dataset will be returned by isac + +def gen_sign_dataset(bit_width): + ''' + Function to generate the signed data set with datapoints from the following patterns. + - alternating ones + - alternating zeros + - walking ones + - walking zeros + - max val + - min val + - max val/2 + - min val/2 + - [-10,10] + + :param bit_width: integer defining the size of the input + :type bit_width: int + :return: a list of integers + ''' + rval_w0_base = ['1']*(bit_width-1)+['0'] + rval_w1_base = ['0']*(bit_width-1)+['1'] + data = [(-2**(bit_width-1)),int((-2**(bit_width-1))/2),0,(2**(bit_width-1)-1),int((2**(bit_width-1)-1)/2)] + list(range(-10,10)) + data += [twos(''.join(rval_w1_base[n:] + rval_w1_base[:n]),bit_width) for n in range(bit_width)] + data += [twos(''.join(rval_w0_base[n:] + rval_w0_base[:n]),bit_width) for n in range(bit_width)] + t1 =( '' if bit_width%2 == 0 else '1') + ''.join(['01']*int(bit_width/2)) + t2 =( '' if bit_width%2 == 0 else '0') + ''.join(['10']*int(bit_width/2)) + data += [twos(t1,bit_width),twos(t2,bit_width)] + return list(set(data)) + +def gen_usign_dataset(bit_width): + ''' + Function to generate the unsigned dataset + - alternating ones + - alternating zeros + - walking ones + - walking zeros + - max val + - min val + - max val/2 + - min val/2 + - [0,20] + + :param bit_width: integer defining the size of the input + :type bit_width: int + :return: a list of integers + ''' + rval_w0_base = ['1']*(bit_width-1)+['0'] + rval_w1_base = ['0']*(bit_width-1)+['1'] + data = [0,((2**bit_width)-1),int(((2**bit_width)-1)/2)] + list(range(0,20)) + data += [int(''.join(rval_w1_base[n:] + rval_w1_base[:n]),2) for n in range(bit_width)] + data += [int(''.join(rval_w0_base[n:] + rval_w0_base[:n]),2) for n in range(bit_width)] + t1 =( '' if bit_width%2 == 0 else '1') + ''.join(['01']*int(bit_width/2)) + t2 =( '' if bit_width%2 == 0 else '0') + ''.join(['10']*int(bit_width/2)) + data += [int(t1,2),int(t2,2)] + return list(set(data)) + +def zerotoxlen(bit_width): + vals = [] + for i in range(bit_width): + vals.append(i) + return vals + +def gen_bitmanip_dataset(bit_width,sign=True): + ''' + Function generates a special dataset of interesting values for bitmanip: + 0x0, 0x3, 0xc, 0x5,0xa,0x6,0x9 each of the pattern exenteding for bit_width + for 32 bit + 0x33333333,0xcccccccc,0x55555555, 0xaaaaaaaaa,0x66666666,0x99999999 + for 64 bit + 0x3333333333333333,0xcccccccccccccccc,0x5555555555555555, 0xaaaaaaaaaaaaaaaaa, + 0x6666666666666666,0x9999999999999999 + - +1 and -1 variants of the above pattern + + :param bit_width: Integer defining the size of the input + :param sign: Boolen value specifying whether the dataset should be interpreted as signed numbers or not. + :type sign: bool + :type bit_width: int + :return: a list of integers + ''' + if sign: + conv_func = lambda x: twos(x,bit_width) + else: + conv_func = lambda x:(int(x,16) if '0x' in x else int(x,2)) if isinstance(x,str) else x + +# dataset for 0x5, 0xa, 0x3, 0xc, 0x6, 0x9 patterns + + dataset = ["0x"+"".join(["5"]*int(bit_width/4)), "0x"+"".join(["a"]*int(bit_width/4)), "0x"+"".join(["3"]*int(bit_width/4)), "0x"+"".join(["6"]*int(bit_width/4)),"0x"+"".join(["9"]*int(bit_width/4)),"0x"+"".join(["c"]*int(bit_width/4))] + dataset = list(map(conv_func,dataset)) + +# dataset0 is for 0,1 and 0xf pattern. 0xf pattern is added instead of -1 so that code for checking coverpoints in coverage.py +# is kept simple. + + dataset0 = [0,1,"0x"+"".join(["f"]*int(bit_width/4))] + dataset0 = list(map(conv_func,dataset0)) + +# increment each value in dataset, increment each value in dataset, add them to the dataset + return dataset + [x - 1 for x in dataset] + [x+1 for x in dataset] + dataset0 + +template_fnames = ["template.yaml","imc.yaml","fd.yaml","inx.yaml"] + +template_files = [os.path.join(root,"data/"+f) for f in template_fnames] + +usage = Template(''' +// ----------- +// This file was generated by riscv_ctg (https://github.com/riscv-software-src/riscv-ctg) +// version : $version +// timestamp : $time +// usage : riscv_ctg \\ +// -- cgf $cgf \\ +// -- xlen $xlen $randomize \\ +// ----------- +//''') + +copyright_string = ''' +// ----------- +// Copyright (c) 2020. RISC-V International. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// ----------- +//''' + +comment_template = ''' +// This assembly file tests the $opcode instruction of the RISC-V $extension extension for the $label covergroup. +// ''' + +cross_comment_template = ''' +// This assembly file is used for the test of cross-combination coverpoint described in $label covergroup. +''' + +csr_comb_comment_template = ''' +// This assembly file is used for the test of CSR-combination coverpoint described in $label covergroup. +''' + +test_template = Template(copyright_string + comment_template+''' +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("$isa") + +.section .text.init +.globl rvtest_entry_point +rvtest_entry_point: +RVMODEL_BOOT +RVTEST_CODE_BEGIN +$test + +RVTEST_CODE_END +RVMODEL_HALT + +RVTEST_DATA_BEGIN +$data +RVTEST_DATA_END + +RVMODEL_DATA_BEGIN +rvtest_sig_begin: +sig_begin_canary: +CANARY; + +$sig + +sig_end_canary: +CANARY; +rvtest_sig_end: +RVMODEL_DATA_END +''') + +cross_test_template = Template(copyright_string + cross_comment_template+''' +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("$isa") + +.section .text.init +.globl rvtest_entry_point +rvtest_entry_point: +RVMODEL_BOOT +RVTEST_CODE_BEGIN +$test + +RVTEST_CODE_END +RVMODEL_HALT + +RVTEST_DATA_BEGIN +$data +RVTEST_DATA_END + +RVMODEL_DATA_BEGIN +$sig +RVMODEL_DATA_END +''') + +csr_comb_test_template = Template(copyright_string + csr_comb_comment_template + ''' +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("$isa") + +.section .text.init +.globl rvtest_entry_point +rvtest_entry_point: +RVMODEL_BOOT +RVTEST_CODE_BEGIN +$test + +RVTEST_CODE_END +RVMODEL_HALT + +RVTEST_DATA_BEGIN +$data +RVTEST_DATA_END + +RVMODEL_DATA_BEGIN +$sig +RVMODEL_DATA_END +''') + +case_template = Template(''' +RVTEST_CASE($num,"//$cond;def TEST_CASE_1=True;",$cov_label) +''') + +part_template = Template(''' +#ifdef TEST_CASE_1 +$case_str +$code +#endif +''') + +signode_template = Template(''' +$label: + .fill $n*$sz,4,0xdeadbeef +''') + +csr_reg_write_to_field_template = Template(''' +WRITE_TO_CSR_FIELD_W_MASK($csr_reg, $restore_reg, $temp_reg1, $temp_reg2, $mask, $val) +''') + +csr_reg_read_and_sig_upd_template = Template(''' +READ_CSR_REG_AND_UPD_SIG($csr_reg, $dest_reg, $offset, $base_reg) +''') + +csr_reg_restore_template = Template(''' +RESTORE_CSR_REG($csr_reg, $restore_reg) +''') diff --git a/riscv-ctg/riscv_ctg/cross_comb.py b/riscv-ctg/riscv_ctg/cross_comb.py new file mode 100644 index 000000000..25112a264 --- /dev/null +++ b/riscv-ctg/riscv_ctg/cross_comb.py @@ -0,0 +1,501 @@ +# See LICENSE.incore for details +import random +from constraint import * + +import riscv_isac.utils as isac_utils +from riscv_ctg import constants + +import riscv_ctg.utils as utils +import riscv_ctg.constants as const +from riscv_ctg.constants import * +from riscv_ctg.log import logger +from riscv_ctg.__init__ import __version__ +from riscv_ctg.generator import OPS +from riscv_ctg.dsp_function import * + +INSTR_FORMAT = { + 'rformat' : '$instr $rd, $rs1, $rs2', + 'iformat' : '$instr $rd, $rs1, SEXT_IMM($imm_val)', + 'sformat' : '$instr $rs2, $imm_val($rs1)', + 'bsformat' : '$instr $rd, $rs2, $imm_val', + 'bformat' : '$instr $rs1, $rs2, $label', + 'uformat' : '$instr $rd, $imm_val', + 'jformat' : '$instr $rd, $imm', + 'crformat' : '$instr $rs1 $rs2', + 'cmvformat' : '$instr $rd, $rs2', + 'ciformat' : '$instr $rd, $imm_val', + 'cssformat' : '$instr $rs2, $imm_val($rs1)', + 'ciwformat' : '$instr $rd, x2, $imm_val', + 'clformat' : '$instr $rd, $imm_val($rs1)', + 'csformat' : '$instr $rs2, $imm_val($rs2)', + 'caformat' : '$instr', + 'cbformat' : '$instr', + 'cjformat' : '$instr', + 'kformat' : '$instr', + 'frformat' : '$instr $rd, $rs1, $rs2', + 'fsrformat' : '$instr $rd, $rs1', + 'fr4format' : '$instr $rd, $rs1, $rs2, $rs3', + 'pbrrformat' : '$instr $rd, $rs1, $rs2', + 'phrrformat' : '$instr $rd, $rs1, $rs2', + 'pbrformat' : '$instr $rd, $rs1', + 'phrformat' : '$instr $rd, $rs1', + 'pbriformat' : '$instr $rd, $rs1, SEXT_IMM($imm_val)' , + 'phriformat' : '$instr $rd, $rs1, SEXT_IMM($imm_val)', + 'psbrrformat' : '$instr $rd, $rs1, $rs2', + 'pshrrformat' : '$instr $rd, $rs1, $rs2', + 'pwrrformat' : '$instr $rd, $rs1, $rs2', + 'pwriformat' : '$instr $rd, $rs1, SEXT_IMM($imm_val)' , + 'pwrformat' : '$instr $rd, $rs1', + 'pswrrformat' : '$instr $rd, $rs1, $rs2', + 'pwhrrformat' : '$instr $rd, $rs1, $rs2', + 'pphrrformat' : '$instr $rd, $rs1, $rs2', + 'ppbrrformat' : '$instr $rd, $rs1, $rs2', + 'prrformat' : '$instr ', + 'prrrformat' : '$instr', + 'dcasrformat' : '$instr ' +} +'''Dictionary to store instruction formats''' + +REG_INIT = { +'x1' : 'LI (x1, (0xFEEDBEADFEEDBEAD & MASK))', +'x2' : 'LI (x2, (0xFF76DF56FF76DF56 & MASK))', +'x3' : 'LI (x3, (0x7FBB6FAB7FBB6FAB & MASK))', +'x4' : 'LI (x4, (0xBFDDB7D5BFDDB7D5 & MASK))', +'x5' : 'LI (x5, (0xAB7FFB6FAB7FBB6F & MASK))', +'x6' : 'LI (x6, (0x6FAB71BB6F7B7FBB & MASK))', +'x7' : 'LI (x7, (0xB7FBB6FAB7FBB6FA & MASK))', +'x8' : 'LI (x8, (0x5BFDDB7D5BFDDB7D & MASK))', +'x9' : 'LI (x9, (0xADFEEDBEADFEEDBE & MASK))', +'x10' : 'LI (x10, (0x56FF76DF56FF76DF & MASK))', +'x11' : 'LI (x11, (0xAB7FBB6FAB7FBB6F & MASK))', +'x12' : 'LI (x12, (0xD5BFDDB7D5BFDDB7 & MASK))', +'x13' : 'LI (x13, (0xEADFEEDBEADFEEDB & MASK))', +'x14' : 'LI (x14, (0xF56FF76DF56FF76D & MASK))', +'x15' : 'LI (x15, (0xFAB7FBB6FAB7FBB6 & MASK))', +'x16' : 'LI (x16, (0x7D5BFDDB7D5BFDDB & MASK))', +'x17' : 'LI (x17, (0xBEADFEEDBEADFEED & MASK))', +'x18' : 'LI (x18, (0xDF56FF76DF56FF76 & MASK))', +'x19' : 'LI (x19, (0x6FAB7FBB6FAB7FBB & MASK))', +'x20' : 'LI (x20, (0xB7D5BFDDB7D5BFDD & MASK))', +'x21' : 'LI (x21, (0xDBEADFEEDBEADFEE & MASK))', +'x22' : 'LI (x22, (0x6DF56FF76DF56FF7 & MASK))', +'x23' : 'LI (x23, (0xB6FAB7FBB6FAB7FB & MASK))', +'x24' : 'LI (x24, (0xDB7D5BFDDB7D5BFD & MASK))', +'x25' : 'LI (x25, (0xEDBEADFEEDBEADFE & MASK))', +'x26' : 'LI (x26, (0x76DF56FF76DF56FF & MASK))', +'x27' : 'LI (x27, (0xBB6FAB7FBB6FAB7F & MASK))', +'x28' : 'LI (x28, (0xDDB7D5BFDDB7D5BF & MASK))', +'x29' : 'LI (x29, (0xEEDBEADFEEDBEADF & MASK))', +'x30' : 'LI (x30, (0xF76DF56FF76DF56F & MASK))', +'x31' : 'LI (x31, (0xFBB6FAB7FBB6FAB7 & MASK))', +} +''' Initial values for general purpose and floating point registers''' + +class cross(): + ''' + A cross class to genereate RISC-V assembly tests for cross-combination coverpoints. + ''' + + def __init__(self, base_isa_str, xlen_in, randomize, label): + global xlen + global flen + global base_isa + + # Template dictionary + self.OP_TEMPLATE = utils.load_yamls(const.template_files) + + xlen = xlen_in + base_isa = base_isa_str + + self.randomize = randomize + self.label = label + + # Flag if floating point instructions are chosen + self.if_fp = False + + def cross_comb(self, cgf_node): + ''' + This function finds solution for various cross-combinations defined by the coverpoints + in the CGF under the `cross_comb` node of the covergroup. + ''' + logger.debug('Generating CrossComb') + full_solution = [] + + if 'cross_comb' in cgf_node: + cross_comb = set(cgf_node['cross_comb']) + else: + return + + isa_set = [] + + # Generate register file and variables + reg_file = const.default_regset + for each in reg_file: + exec(f"{each} = '{each}'") + + dntcare_instrs = isac_utils.import_instr_alias(base_isa + '_arith') + isac_utils.import_instr_alias(base_isa + '_shift') + + # This function retrieves available operands in a string + def get_oprs(opr_str): + opr_lst = [] + if opr_str.find('rd') != -1: + opr_lst.append('rd') + if opr_str.find('rs1') != -1: + opr_lst.append('rs1') + if opr_str.find('rs2') != -1: + opr_lst.append('rs2') + if opr_str.find('rs3') != -1: + opr_lst.append('rs3') + + return opr_lst + + # Add conditions mentioned in the condition list in the cross-comb coverpoint + def add_cond(local_var): + def eval_conds(*oprs_lst): + i = 0 + for opr in oprs: + exec(opr + "='" + oprs_lst[i] + "'", local_var) + i = i + 1 + return eval(cond, locals(), local_var) + return eval_conds + + solution = [] + for each in cross_comb: + + solution = [] + + # Parse cross-comb coverpoint + parts = each.split('::') + + data = parts[0].replace(' ', '')[1:-1].split(':') + assgn_lst = parts[1].replace(' ', '')[1:-1].split(':') + cond_lst = parts[2].lstrip().rstrip()[1:-1].split(':') + + # Initialize CSP + problem = Problem() + + for i in range(len(data)): + if data[i] == '?': + # When instruction is not specified, + # - Gather conditions and assigngments if any and list requisite operands + # - Choose instruction from base instruction set based on operands + # - Based on conditions, choose operand values. Choose immediate value if required + # - Evaluate assignments + + # Get corresponding conditions and accordingly chose instruction + cond = cond_lst[i] + assgn = assgn_lst[i] + + if cond.find('?') != -1: # Don't care condition + + # Check variables in assignment list and generate required operand list + opr_lst = get_oprs(assgn) + + # Get possible instructions based on the operand list + problem.reset() + problem.addVariable('i', dntcare_instrs) + problem.addConstraint(lambda i: all(item in OPS[self.OP_TEMPLATE[i]['formattype']] for item in opr_lst)) + instrs_sol = problem.getSolutions() + + instrs_sol = [list(each.items())[0][1] for each in instrs_sol] + + else: # If condition is specified + + opr_lst = [] + + # Extract required operands from condition list + opr_lst += get_oprs(cond) + + # Extract required operands from assignment list + opr_lst += get_oprs(assgn) + + # Remove redundant operands + opr_lst = list(set(opr_lst)) + + # Get possible instructions + problem.reset() + problem.addVariable('i', dntcare_instrs) + problem.addConstraint(lambda i: all(item in OPS[self.OP_TEMPLATE[i]['formattype']] for item in opr_lst)) + instrs_sol = problem.getSolutions() + + instrs_sol = [list(each.items())[0][1] for each in instrs_sol] + + # Randomly choose an instruction + instr = random.choice(instrs_sol) + isa_set += (self.OP_TEMPLATE[instr]['isa']) + + # Choose operand values + formattype = self.OP_TEMPLATE[instr]['formattype'] + oprs = OPS[formattype] + instr_template = self.OP_TEMPLATE[instr] + + # Choose register values + problem.reset() + for opr in oprs: + opr_dom = instr_template[opr + '_op_data'] + problem.addVariable(opr, eval(opr_dom)) + + # Since rd = x0 is a trivial operation, it has to be excluded + if 'rd' in oprs: + # exclude zeros + def exc_rd_zero(*oprs_lst): + pos = oprs.index('rd') + if oprs_lst[pos] == 'x0': + return False + return True + + problem.addConstraint(exc_rd_zero, oprs) + + # Add additional contraints if any + if cond.find('?') != -1: + opr_sols = problem.getSolutions() + else: + local_vars = locals() + problem.addConstraint(add_cond(local_vars), oprs) + opr_sols = problem.getSolutions() + + opr_vals = random.choice(opr_sols) + + # Assign operand values to operands + for opr, val in opr_vals.items(): + exec(opr + "='" + val + "'") + + # Generate immediate value if required + if 'imm_val_data' in instr_template: + imm_val = eval(instr_template['imm_val_data']) + opr_vals['imm_val'] = random.choice(imm_val) + + # Get assignments if any and execute them + if assgn_lst[i] != '?': + assgns = assgn_lst[i].split(';') + for each in assgns: + exec(each) + + # Set floating point flag if instruction belongs to F or D extension + if instr[0] == 'f' and instr != 'fence': + self.if_fp = True + + opr_vals['instr'] = instr + solution += [opr_vals] + + else: + # When instruction(s)/alias is specified, + # - If an instruction is specified, operands are directly extracted and assigned values according to conditions + # - If a tuple of instructions is specified, one of the instruction is chosen at random + # - If an alias is specified, the alias is already substituted by its equivalent tuple of instructions at this point + # through expand_cgf method. + # - Immediate values are generated if required + # - Assignments are evaluated + cond = cond_lst[i] + assgn = assgn_lst[i] + + # Gather required operands + opr_lst = get_oprs(cond) + opr_lst += get_oprs(assgn) + + opr_lst = list(set(opr_lst)) + + if data[i] in self.OP_TEMPLATE: # If single instruction + instr = data[i] + else: + if data[i].find('(') != -1: # If data is a tuple of instructions + instrs_sol = data[i][1:-1].split(',') + instr = random.choice(instrs_sol) + else: + logger.error('Invalid instruction/alias in cross_comb: ' + data[i]) + + # Gather operands + formattype = self.OP_TEMPLATE[instr]['formattype'] + oprs = OPS[formattype] + instr_template = self.OP_TEMPLATE[instr] + + problem.reset() + for opr in oprs: + opr_dom = instr_template[opr + '_op_data'] + problem.addVariable(opr, eval(opr_dom)) + + # Since rd = x0 is a trivial operation, it has to be excluded + if 'rd' in oprs: + # exclude zeros + def exc_rd_zero(*oprs_lst): + pos = oprs.index('rd') + if oprs_lst[pos] == 'x0': + return False + return True + + problem.addConstraint(exc_rd_zero, oprs) + + # Assign values to operands + if cond.find('?') != -1: + opr_sols = problem.getSolutions() + else: + local_vars = locals() + problem.addConstraint(add_cond(local_vars), oprs) + opr_sols = problem.getSolutions() + + # Get operand values + opr_vals = random.choice(opr_sols) + + # Assign operand values to operands + for opr, val in opr_vals.items(): + exec(opr + "='" + val + "'") + + # Generate immediate value if required + if 'imm_val_data' in instr_template: + imm_val = eval(instr_template['imm_val_data']) + opr_vals['imm_val'] = random.choice(imm_val) + + # Execute assignments + # Get assignments if any and execute them + if assgn_lst[i] != '?': + assgns = assgn_lst[i].split(';') + for each in assgns: + exec(each) + + isa_set += (self.OP_TEMPLATE[instr]['isa']) + + # Set floating point flag if instruction belongs to F or D extension + if instr[0] == 'f' and instr != 'fence': + self.if_fp = True + + opr_vals['instr'] = instr + solution += [opr_vals] + + full_solution += [solution] + + self.isa = list(set(isa_set)) + return full_solution + + def swreg(cross_comb_instrs): + ''' + This function generates the register which can be used as a signature pointer for each instruction. + It also generates the register which stores the value used by floating point registers + ''' + + global base_isa + + op_vals = {'x0'} + + for instr_dict in cross_comb_instrs: + for key, val in instr_dict.items(): + if key != 'instr' and key != 'imm_val': + op_vals.add(val) + + swreg_sol = set(['x'+str(x) for x in range(0,32 if 'e' not in base_isa else 16)]) - op_vals + + sreg = random.choice(list(swreg_sol)) + freg_Sol = swreg_sol - set(sreg) + freg = random.choice(list(freg_Sol)) + return (sreg, freg) + + def get_reginit_str(cross_comb_instrs, freg): + ''' + This function fetches the register initlialization macro to initialize + used destination instructions after the cross-coverpoint instruction sequence + generation + + Input argument: + - cross_comb_instrs type: list(dict()) Holds info of various instructions in the sequence + + Return: + - List of initialization strings + ''' + + reg_init_lst = set() + + for instr_dict in cross_comb_instrs: + if 'rd' in instr_dict: + rd_val = instr_dict['rd'] + if rd_val[0] == 'f': + freg_init = REG_INIT[freg].replace('& MASK', '>> FREGWIDTH') + reg_init_lst.add(freg_init + '\n' + 'FLREG ' + rd_val + ', 0(' + freg + ')') + else: + reg_init_lst.add(REG_INIT[instr_dict['rd']]) + return list(reg_init_lst) + + def write_test(self, fprefix, cgf_node, usage_str, cov_label, full_solution): + ''' + Generate instruction sequence and write them into an assembly file + + #TODO Initialization of floating point registers + #TODO Handling loads/stores and branches in the sequence + ''' + global base_isa + + code = '\n' + data = [".align 4","rvtest_data:",".word 0xbabecafe", \ + ".word 0xabecafeb", ".word 0xbecafeba", ".word 0xecafebab"] + sig = [''] + sreg_dict = dict() + + # If floating point instructions are available + if self.if_fp: + code += "RVTEST_FP_ENABLE()" + + # Generate ISA and extension string + extension = "" + rvxlen = "RV"+str(xlen) + op_node_isa = ",".join([rvxlen + isa for isa in self.isa]) + op_node_isa = op_node_isa.replace("I","E") if 'e' in base_isa else op_node_isa + extension = op_node_isa.replace('I',"").replace('E',"") + + # Handle solutions related to each cross combination coverpoint + for cross_sol in full_solution: + + # Designate signature update register + (sreg, freg) = cross.swreg(cross_sol) + + # Designate count of sreg for signature label generation + if sreg not in sreg_dict: + sreg_dict[sreg] = 0 + else: + count = sreg_dict[sreg] + 1 + sreg_dict[sreg] = count + + sig_label = "signature_" + sreg + "_" + str(sreg_dict[sreg]) + code = code + "\nRVTEST_SIGBASE(" + sreg + ", "+ sig_label + ")\n\n" + + rd_lst = set() + # Generate instruction corresponding to each instruction dictionary + # Append signature update statements to store rd value after each instruction + code += '// Cross-combination test sequence\n' + for each in cross_sol: + + if 'rd' in each: + rd_lst.add(each['rd']) + + instr_str_format = Template(INSTR_FORMAT[self.OP_TEMPLATE[each['instr']]['formattype']]) + instr_str = instr_str_format.substitute(each) + code = code + instr_str + '\n' + + # Append .fill assembly directives to initialize signature regions + sig.append(signode_template.safe_substitute(label = sig_label, n = len(rd_lst))) + + offset = 0 + code += '\n// Store destination register values in the test signature region\n' + # Add signature update statement(s) for unique number of rds + for rd in rd_lst: + if rd[0] == 'f': + sig_upd = f'RVTEST_SIGUPD_F({sreg}, {rd}, {offset})' + else: + sig_upd = f'RVTEST_SIGUPD({sreg}, {rd}, {offset})' + offset = offset + int(xlen/8) + code = code + sig_upd + '\n' + + # Initialize registers for next cross-comb coverpoint + code = code + '\n// Initialize used registers\n' + '\n'.join(cross.get_reginit_str(cross_sol, freg)) + '\n' + + case_str = ''.join([case_template.safe_substitute(xlen = xlen,num = i, cond = cond, cov_label = cov_label) for i, cond in enumerate(cgf_node['config'])]) + test = part_template.safe_substitute(case_str = case_str, code = code) + + # Write test to file + with open(fprefix + '_cross-comb.S', 'w') as fp: + fp.write(usage_str + const.cross_test_template.safe_substitute(opcode = cov_label, + isa = op_node_isa, + test = test, + data = '\n'.join(data), + sig = '\n'.join(sig), + label = cov_label, + extension = extension + ) + ) diff --git a/riscv-ctg/riscv_ctg/csr_comb.py b/riscv-ctg/riscv_ctg/csr_comb.py new file mode 100644 index 000000000..ef75d388c --- /dev/null +++ b/riscv-ctg/riscv_ctg/csr_comb.py @@ -0,0 +1,425 @@ +# See LICENSE.incore for details +import re +import functools + +from riscv_ctg.log import logger +from riscv_ctg.constants import * + +import tokenize as tkn +from io import BytesIO + +OPS = ['not', 'and', 'or'] +OP_PRIORITY = { + 'not': -1, + 'and': -2, + 'or' : -3, +} + +CSR_REGS = ['mvendorid', 'marchid', 'mimpid', 'mhartid', 'mstatus', 'misa', 'medeleg', 'mideleg', 'mie', 'mtvec', 'mcounteren', 'mscratch', 'mepc', 'mcause', 'mtval', 'mip', 'pmpcfg0', 'pmpcfg1', 'pmpcfg2', 'pmpcfg3', 'mcycle', 'minstret', 'mcycleh', 'minstreth', 'mcountinhibit', 'tselect', 'tdata1', 'tdata2', 'tdata3', 'dcsr', 'dpc', 'dscratch0', 'dscratch1', 'sstatus', 'sedeleg', 'sideleg', 'sie', 'stvec', 'scounteren', 'sscratch', 'sepc', 'scause', 'stval', 'sip', 'satp', 'vxsat', 'fflags', 'frm', 'fcsr', 'CSR_SRMCFG'] +csr_regs_capture_group = f'({"|".join(CSR_REGS)})' +csr_regs_with_modifiers_capture_group = r'(write|old) *\( *"' + csr_regs_capture_group + r'" *\)' + +csr_comb_covpt_regex_strings = [ + csr_regs_capture_group + r' *& *([^ ].*)== *([^ ].*)', # regular + r'\( *' + csr_regs_capture_group + r' *(>>|<<) *([^ ].*)\) *& *([^ ].*)== *([^ ].*)', # with bitshifts only + csr_regs_with_modifiers_capture_group + r' *& *([^ ].*)== *([^ ].*)', # with modifiers only + r'\( *' + csr_regs_with_modifiers_capture_group + r' *(>>|<<) *([^ ].*)\) *& *([^ ].*)== *([^ ].*)', # with bitshifts and modifiers +] + +csr_comb_covpt_regexes = [re.compile(regex_string) for regex_string in csr_comb_covpt_regex_strings] + +def tokenize(s): + result = [] + g = tkn.tokenize(BytesIO(s.encode('utf-8')).readline) + for tok_num, tok_val, _, _, _ in g: + if tok_num in [tkn.ENCODING, tkn.NEWLINE, tkn.ENDMARKER]: + continue + result.append((tok_num, tok_val)) + return result + +def untokenize(tokens): + return tkn.untokenize(tokens) + +# a dummy class acting as an interface for boolean expressions +class BooleanExpression: + def SAT(self): + # returns the complete list of solutions for this expression's satisfiability + # a single solution is a tuple of two lists: + # - the literals in the first list must evaluate to true + # - the literals in the second list must evaluate to false + raise Exception("not implemented") + + def __str__(self): + raise Exception("not implemented") + +class NotExpression(BooleanExpression): + def __init__(self, operand): + self.operand = operand + + def SAT(self): + return [(operand_f, operand_t) for operand_t, operand_f in self.operand.SAT()] + + def __str__(self): + return f'not ({str(self.operand)})' + +class AndExpression(BooleanExpression): + def __init__(self, lhs, rhs): + self.lhs = lhs + self.rhs = rhs + + def SAT(self): + return [(lhs_t + rhs_t, lhs_f + rhs_f) for lhs_t, lhs_f in self.lhs.SAT() for rhs_t, rhs_f in self.rhs.SAT()] + + def __str__(self): + return f'({str(self.lhs)}) and ({str(self.rhs)})' + +class OrExpression(BooleanExpression): + def __init__(self, lhs, rhs): + self.lhs = lhs + self.rhs = rhs + + def SAT(self): + lhs_SAT = self.lhs.SAT() + rhs_SAT = self.rhs.SAT() + + sols = [] + for lhs_t, lhs_f in lhs_SAT: + for rhs_t, rhs_f in rhs_SAT: + sols.extend([ + (lhs_t + rhs_f, lhs_f + rhs_t), + (lhs_f + rhs_t, lhs_t + rhs_f), + (lhs_t + rhs_t, lhs_f + rhs_f), + ]) + + return sols + + def __str__(self): + return f'({str(self.lhs)}) or ({str(self.rhs)})' + +class LiteralExpression(BooleanExpression): + def __init__(self, val): + self.val = val + + def SAT(self): + return [([self.val], [])] + + def __str__(self): + return str(self.val) + +# This function parses coverpoints for the CSR-combination node +# The coverpoints are assumed of the form: multiple condition clauses combined with and's and or's +# A coverpoint condition clause is assumed of the form: 'csr_reg & mask == val' or '(csr_reg >> shift) & mask == val' +def parse_csr_covpt(covpt): + toks = tokenize(covpt) + + bracket_depth = 0 + clause_depths = [] + for tok_num, tok_val in toks: + if tok_val == '(': + bracket_depth += 1 + elif tok_val == ')': + bracket_depth -= 1 + elif tok_val == '==': + clause_depths.append(bracket_depth) + + bracket_depth = 0 + operator_stack = [] + clause_stack = [] + clause_index = 0 + current_clause = [] + current_clause_depth = clause_depths[clause_index] + for tok_num, tok_val in toks: + if tok_val == '(': + bracket_depth += 1 + + if bracket_depth > current_clause_depth: + current_clause.append((tok_num, tok_val)) + else: + operator_stack.append('(') + elif tok_val == ')': + bracket_depth -= 1 + + if current_clause: + if bracket_depth < current_clause_depth: + clause_stack.append(LiteralExpression(untokenize(current_clause))) + while operator_stack[-1] != '(': + op = operator_stack.pop() + if op == 'not': + operand = clause_stack.pop() + clause_stack.append(NotExpression(operand)) + else: + rhs = clause_stack.pop() + lhs = clause_stack.pop() + clause_stack.append(AndExpression(lhs, rhs) if op == 'and' else OrExpression(lhs, rhs)) + operator_stack.pop() + + current_clause = [] + clause_index += 1 + if (clause_index >= len(clause_depths)): + break + current_clause_depth = clause_depths[clause_index] + else: + current_clause.append((tok_num, tok_val)) + else: + while operator_stack[-1] != '(': + op = operator_stack.pop() + if op == 'not': + operand = clause_stack.pop() + clause_stack.append(NotExpression(operand)) + else: + rhs = clause_stack.pop() + lhs = clause_stack.pop() + clause_stack.append(AndExpression(lhs, rhs) if op == 'and' else OrExpression(lhs, rhs)) + operator_stack.pop() + elif tok_val in OPS: + if current_clause: + clause_stack.append(LiteralExpression(untokenize(current_clause))) + current_clause = [] + clause_index += 1 + current_clause_depth = clause_depths[clause_index] + + # prioritize not over and over or + while len(operator_stack) > 0 and operator_stack[-1] in OPS and OP_PRIORITY[operator_stack[-1]] > OP_PRIORITY[tok_val]: + op = operator_stack.pop() + if op == 'not': + operand = clause_stack.pop() + clause_stack.append(NotExpression(operand)) + else: + rhs = clause_stack.pop() + lhs = clause_stack.pop() + clause_stack.append(AndExpression(lhs, rhs) if op == 'and' else OrExpression(lhs, rhs)) + + operator_stack.append(tok_val) + else: + current_clause.append((tok_num, tok_val)) + + if current_clause: + clause_stack.append(LiteralExpression(untokenize(current_clause))) + + while len(operator_stack) > 0: + op = operator_stack.pop() + if op == 'not': + operand = clause_stack.pop() + clause_stack.append(NotExpression(operand)) + else: + rhs = clause_stack.pop() + lhs = clause_stack.pop() + clause_stack.append(AndExpression(lhs, rhs) if op == 'and' else OrExpression(lhs, rhs)) + + bool_expr = clause_stack.pop() + return bool_expr + +# This function extracts the csr register, the field mask, the field value and the csr register modifier (if present) from the coverpoint clause +# The coverpoint clause is assumed of the format: 'csr_reg & mask == val' or '(csr_reg >> shift) & mask == val' +# Modifiers `old()` and `write()` are also allowed on the `csr_reg`s. Example: `old("csr_reg") & mask == val` +# csr_reg must be a valid csr register; mask and val are allowed to be valid python expressions +def get_csr_mask_val_modifier(clause, instr_dict={}): + clause = clause.strip() + for i, regex in enumerate(csr_comb_covpt_regexes): + regex_match = regex.match(clause) + if regex_match is not None: + if i == 0: # regular covpt + csr_reg, mask_expr, val_expr = regex_match.groups() + mask = eval(mask_expr, {}, instr_dict) + val = eval(val_expr, {}, instr_dict) + return csr_reg, mask, val, None + elif i == 1: # with bitshifts only + csr_reg, shift_op, shift_expr, mask_expr, val_expr = regex_match.groups() + shift = eval(shift_expr, {}, instr_dict) + mask = eval(mask_expr, {}, instr_dict) + val = eval(val_expr, {}, instr_dict) + if shift_op == '>>': + mask = mask << shift + val = val << shift + else: + mask = mask >> shift + val = val >> shift + return csr_reg, mask, val, None + elif i == 2: # with modifiers only + mod, csr_reg, mask_expr, val_expr = regex_match.groups() + mask = eval(mask_expr, {}, instr_dict) + val = eval(val_expr, {}, instr_dict) + return csr_reg, mask, val, mod + elif i == 3: # with both modifiers and bitshifts + mod, csr_reg, shift_op, shift_expr, mask_expr, val_expr = regex_match.groups() + shift = eval(shift_expr, {}, instr_dict) + mask = eval(mask_expr, {}, instr_dict) + val = eval(val_expr, {}, instr_dict) + if shift_op == '>>': + mask = mask << shift + val = val << shift + else: + mask = mask >> shift + val = val >> shift + return csr_reg, mask, val, mod + return None, None, None, None + +class GeneratorCSRComb(): + ''' + A class to generate RISC-V assembly tests for CSR-combination coverpoints. + ''' + + def __init__(self, base_isa, xlen, randomize): + self.base_isa = base_isa + "_Zicsr" + self.xlen = xlen + self.randomize = randomize + + def csr_comb(self, cgf_node): + logger.debug('Generating tests for csr_comb') + if 'csr_comb' in cgf_node: + csr_comb = set(cgf_node['csr_comb']) + else: + return + + temp_regs = ['x30', 'x31'] + dest_reg = 'x29' + + instr_dict = [] + offset = 0 + + for covpt in csr_comb: + try: + bool_expr = parse_csr_covpt(covpt) + sols = bool_expr.SAT() + except: + logger.error(f'Invalid csr_comb coverpoint: {covpt}') + continue + + for sol, _ in sols: + reg_mask_val_mod_dict = {} # maps a csr_reg to the 6-tuple [mask, val, write_mask, write_val, old_mask, old_val] + reg_with_mod = None + for clause in sol: + csr_reg, mask, val, mod = get_csr_mask_val_modifier(clause, {'xlen': self.xlen}) + + if csr_reg is None: + logger.error(f'Skipping invalid csr_comb coverpoint condition clause: {clause}') + continue + if mod is not None: + if reg_with_mod is None: reg_with_mod = csr_reg + elif reg_with_mod != csr_reg: + logger.error(f'Skipping invalid csr_comb solution with modifiers on more than one registers for the coverpoint: {covpt}') + continue + + if not csr_reg in reg_mask_val_mod_dict: + if mod == 'old': + reg_mask_val_mod_dict[csr_reg] = [0, 0, 0, 0, mask, val] + elif mod == 'write': + reg_mask_val_mod_dict[csr_reg] = [0, 0, mask, val, 0, 0] + else: + reg_mask_val_mod_dict[csr_reg] = [mask, val, 0, 0, 0, 0] + else: + if mod == 'old': + reg_mask_val_mod_dict[csr_reg][4] |= mask + reg_mask_val_mod_dict[csr_reg][5] |= val + elif mod == 'write': + reg_mask_val_mod_dict[csr_reg][2] |= mask + reg_mask_val_mod_dict[csr_reg][3] |= val + else: + reg_mask_val_mod_dict[csr_reg][0] |= mask + reg_mask_val_mod_dict[csr_reg][1] |= val + + reg_mask_val_arr = list(reg_mask_val_mod_dict.items()) + reg_mask_val_arr.sort(key=functools.cmp_to_key(lambda x, y: 1 if x[0] == reg_with_mod else -1)) # put the register with modifier at the end + + instr_dict_csr_writes = [] + instr_dict_csr_restores = [] + uniq_csr_regs = [] + restore_reg = 1 + for csr_reg, mask_val in reg_mask_val_arr: + mask, val, write_mask, write_val, old_mask, old_val = mask_val + if old_mask != 0: + instr_dict_csr_writes.append({ + 'csr_reg': csr_reg, 'mask': hex(old_mask), 'val': hex(old_val), 'restore_reg': f'x{restore_reg}', + 'temp_reg1': temp_regs[0], 'temp_reg2': temp_regs[1] + }) + instr_dict_csr_restores.append({ + 'csr_reg': csr_reg, 'restore_reg': f'x{restore_reg}' + }) + restore_reg += 1 + + if write_mask != 0: + instr_dict_csr_writes.append({ + 'csr_reg': csr_reg, 'mask': hex(write_mask), 'val': hex(write_val), 'restore_reg': f'x{restore_reg}', + 'temp_reg1': temp_regs[0], 'temp_reg2': temp_regs[1] + }) + instr_dict_csr_restores.append({ + 'csr_reg': csr_reg, 'restore_reg': f'x{restore_reg}' + }) + restore_reg += 1 + elif mask != 0: + instr_dict_csr_writes.append({ + 'csr_reg': csr_reg, 'mask': hex(mask), 'val': hex(val), 'restore_reg': f'x{restore_reg}', + 'temp_reg1': temp_regs[0], 'temp_reg2': temp_regs[1] + }) + instr_dict_csr_restores.append({ + 'csr_reg': csr_reg, 'restore_reg': f'x{restore_reg}' + }) + restore_reg += 1 + + if csr_reg not in uniq_csr_regs: + uniq_csr_regs.append(csr_reg) + + instr_dict_csr_restores.reverse() + + instr_dict_csr_read_and_sig_upds = [] + for csr_reg in uniq_csr_regs: + instr_dict_csr_read_and_sig_upds.append({ + 'csr_reg': csr_reg, 'dest_reg': dest_reg, 'offset': offset + }) + offset += (self.xlen >> 3) + + instr_dict.append((instr_dict_csr_writes, instr_dict_csr_read_and_sig_upds, instr_dict_csr_restores)) + + return instr_dict + + def write_test(self, fprefix, cgf_node, usage_str, cov_label, instr_dict): + base_reg = 'x28' + + code = [""] + data = [".align 4","rvtest_data:",".word 0xbabecafe", \ + ".word 0xabecafeb", ".word 0xbecafeba", ".word 0xecafebab"] + sig = [""] + + sig_label = f"signature_{base_reg}_0" + sig.append(signode_template.safe_substitute(label = sig_label, n = len(instr_dict), sz = '(XLEN/32)')) + code.append(f"RVTEST_SIGBASE({base_reg}, {sig_label})\n") + + for i, instr in enumerate(instr_dict): + csr_writes, csr_read_sig_upds, csr_restores = instr + + for j, csr_write in enumerate(csr_writes): + code.extend([ + f"\ninst_{i}_csr_write_{j}:", + csr_reg_write_to_field_template.safe_substitute({ + 'base_reg': base_reg, **csr_write + }) + ]) + + for j, csr_read_sig_upd in enumerate(csr_read_sig_upds): + code.extend([ + f"\ninst_{i}_csr_read_sig_upd_{j}:", + csr_reg_read_and_sig_upd_template.safe_substitute({ + 'base_reg': base_reg, **csr_read_sig_upd + }) + ]) + + for j, csr_restore in enumerate(csr_restores): + code.extend([ + f"\ninst_{i}_csr_restore_{j}:", + csr_reg_restore_template.safe_substitute({ + 'base_reg': base_reg, **csr_restore + }) + ]) + + case_str = ''.join([case_template.safe_substitute(xlen = self.xlen, num = i, cov_label = cov_label) for i, cond in enumerate(cgf_node.get('config', []))]) + test_str = part_template.safe_substitute(case_str = case_str, code = '\n'.join(code)) + fname = fprefix + '_csr-comb.S' + logger.debug("Writing Test to %s", str(fname)) + with open(fname, 'w') as fp: + fp.write(usage_str + csr_comb_test_template.safe_substitute( + isa = self.base_isa.upper(), # how to get the extensions? + test = test_str, + data = '\n'.join(data), + sig = '\n'.join(sig), + label = cov_label + )) diff --git a/riscv-ctg/riscv_ctg/ctg.py b/riscv-ctg/riscv_ctg/ctg.py new file mode 100644 index 000000000..1d1dced19 --- /dev/null +++ b/riscv-ctg/riscv_ctg/ctg.py @@ -0,0 +1,139 @@ +# See LICENSE.incore file for details + +import copy +import os,re +import multiprocessing as mp + +import time +import shutil +from riscv_ctg.log import logger +import riscv_ctg.utils as utils +import riscv_ctg.constants as const +from riscv_isac.cgf_normalize import expand_cgf +from riscv_ctg.generator import Generator +from riscv_ctg.cross_comb import cross +from riscv_ctg.csr_comb import GeneratorCSRComb +from math import * +from riscv_ctg.__init__ import __version__ + +def create_test(usage_str, node,label,base_isa,max_inst, op_template, randomize, out_dir, xlen, flen, inxFlag): + iflen = 0 + if 'mnemonics' not in node and 'csr_comb' not in node: + logger.warning("Neither mnemonics nor csr_comb node not found in covergroup: " + str(label)) + return + if 'ignore' in node: + logger.info("Ignoring :" + str(label)) + if node['ignore']: + return + + if 'mnemonics' in node: + # Function to encompass checks and test generation + def gen_test(op_node, opcode): + iflen = 0 + if xlen not in op_node['xlen']: + logger.warning("Skipping {0} since its not supported in current XLEN:".format(opcode)) + return + if 'flen' in op_node: + if flen not in op_node['flen']: + logger.warning("Skipping {0} since its not supported in current FLEN({1}):".format(\ + opcode, flen)) + return + iflen = min(op_node['flen']) + fprefix = os.path.join(out_dir,str(label)) + logger.info('Generating Test for :' + str(label) +"-" + opcode) + formattype = op_node['formattype'] + gen = Generator(formattype,op_node,opcode,randomize,xlen,flen,iflen,base_isa,inxFlag) + op_comb = gen.opcomb(node) + val_comb = gen.valcomb(node) + instr_dict = gen.correct_val( + gen.valreg( + gen.testreg( + gen.swreg( + gen.gen_inst(op_comb, val_comb, node))))) + logger.info("Writing tests for :"+str(label)) + my_dict = gen.reformat_instr(instr_dict) + gen.write_test(fprefix,node,label,my_dict, op_node, usage_str, max_inst) + + # If base_op defined in covergroup, extract corresponding template + # else go through the instructions defined in mnemonics label + op_node = None + if 'base_op' in node: + # Extract pseudo and base instructions + base_op = node['base_op'] + pseudop = list(node['mnemonics'].keys())[0] + if base_op in op_template and pseudop in op_template: + op_node = copy.deepcopy(op_template[base_op]) + pseudo_template = op_template[pseudop] + + # Ovewrite/add nodes from pseudoinstruction template in base instruction template + for key, val in pseudo_template.items(): + op_node[key] = val + + # Generate tests + gen_test(op_node, pseudop) + else: + for opcode in node['mnemonics']: + if opcode in op_template: + op_node = op_template[opcode] + # Generate tests + gen_test(op_node, opcode) + else: + logger.warning(str(opcode) + " not found in template file. Skipping") + return + + if 'cross_comb' in node: + fprefix = os.path.join(out_dir,str(label)) + cross_obj = cross(base_isa, xlen, randomize, label) + cross_instr_dict = cross_obj.cross_comb(node) + logger.info('Writing cross-comb test') + cross_obj.write_test(fprefix, node, usage_str, label, cross_instr_dict) + + if op_node is None: + # Return if there is no corresponding template + logger.warning("Skipping :" + str(opcode)) + return + + if 'csr_comb' in node: + fprefix = os.path.join(out_dir,str(label)) + csr_comb_gen = GeneratorCSRComb(base_isa, xlen, randomize) + csr_comb_instr_dict = csr_comb_gen.csr_comb(node) + logger.info('Writing tests for csr_comb') + csr_comb_gen.write_test(fprefix, node, usage_str, label, csr_comb_instr_dict) + +def ctg(verbose, out, random ,xlen_arg,flen_arg, cgf_file,num_procs,base_isa, max_inst,inxFlag): + logger.level(verbose) + logger.info('****** RISC-V Compliance Test Generator {0} *******'.format(__version__ )) + logger.info('Copyright (c) 2020, InCore Semiconductors Pvt. Ltd.') + logger.info('All Rights Reserved.') + logger.info("Copying env folder to Output directory.") + env_dir = os.path.join(out,"env") + if not os.path.exists(env_dir): + shutil.copytree(const.env,env_dir) + xlen = int(xlen_arg) + flen = int(flen_arg) + out_dir = out + randomize = random + mytime = time.asctime(time.gmtime(time.time()) ) + ' GMT' + cgf_argument = '' + for cf in cgf_file: + cgf_argument += '// --cgf {} \\\n'.format(cf) + randomize_argument = '' + if random is True: + randomize_argument = ' \\\n// --randomize' + usage_str = const.usage.safe_substitute(base_isa=base_isa, \ + cgf=cgf_argument, version = __version__, time=mytime, \ + randomize=randomize_argument,xlen=str(xlen_arg)) + # --------------------------------- + # IITM Changes + # This is introduced to handle the template conflict over float instructions + # --------------------------------- + if inxFlag: + const.template_files.remove([fd for fd in const.template_files if "fd.yaml" in fd][0]) + else: + const.template_files.remove([fd for fd in const.template_files if "inx.yaml" in fd][0]) + op_template = utils.load_yamls(const.template_files) + cgf = expand_cgf(cgf_file,xlen,flen) + pool = mp.Pool(num_procs) + results = pool.starmap(create_test, [(usage_str, node,label,base_isa,max_inst, op_template, + randomize, out_dir, xlen, flen, inxFlag) for label,node in cgf.items()]) + pool.close() diff --git a/riscv-ctg/riscv_ctg/data/fd.yaml b/riscv-ctg/riscv_ctg/data/fd.yaml new file mode 100644 index 000000000..22cb8985c --- /dev/null +++ b/riscv-ctg/riscv_ctg/data/fd.yaml @@ -0,0 +1,3043 @@ +# See LICENSE.incore for details +fadd.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr + - IFD_Zicsr + flen: [32,64] + std_op: + formattype: 'rformat' + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; fcsr: $fcsr; + correctval:??; testreg:$testreg + */ + TEST_FPRR_OP($inst, $rd, $rs1, $rs2, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fadd.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IFD_Zicsr + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; fcsr: $fcsr; + correctval:??; testreg:$testreg + */ + TEST_FPRR_OP($inst, $rd, $rs1, $rs2, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fsub.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr + - IFD_Zicsr + flen: [32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; fcsr: $fcsr; + correctval:??; testreg:$testreg + */ + TEST_FPRR_OP($inst, $rd, $rs1, $rs2, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fsub.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IFD_Zicsr + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; fcsr: $fcsr; + correctval:??; testreg:$testreg + */ + TEST_FPRR_OP($inst, $rd, $rs1, $rs2, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fmul.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr + - IFD_Zicsr + flen: [32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; fcsr: $fcsr; + correctval:??; testreg:$testreg + */ + TEST_FPRR_OP($inst, $rd, $rs1, $rs2, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fmul.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IFD_Zicsr + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; fcsr: $fcsr; + correctval:??; testreg:$testreg + */ + TEST_FPRR_OP($inst, $rd, $rs1, $rs2, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fdiv.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr + - IFD_Zicsr + flen: [32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; fcsr: $fcsr; + correctval:??; testreg:$testreg + */ + TEST_FPRR_OP($inst, $rd, $rs1, $rs2, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fdiv.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IFD_Zicsr + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; fcsr: $fcsr; + correctval:??; testreg:$testreg + */ + TEST_FPRR_OP($inst, $rd, $rs1, $rs2, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fsqrt.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr + - IFD_Zicsr + flen: [32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:??; testreg:$testreg; + fcsr_val: $fcsr */ + TEST_FPSR_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fsqrt.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IFD_Zicsr + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:??; testreg:$testreg; + fcsr_val: $fcsr */ + TEST_FPSR_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fmadd.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 3 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr + - IFD_Zicsr + flen: [32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'r4format' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rs3_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; op3:$rs3; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + op3val:$rs3_val; valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; + testreg:$testreg; fcsr_val:$fcsr */ + TEST_FPR4_OP($inst, $rd, $rs1, $rs2, $rs3, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fmadd.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 3 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IFD_Zicsr + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'r4format' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rs3_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; op3:$rs3; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + op3val:$rs3_val; valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; + testreg:$testreg; fcsr_val:$fcsr */ + TEST_FPR4_OP($inst, $rd, $rs1, $rs2, $rs3, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fmsub.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 3 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr + - IFD_Zicsr + flen: [32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'r4format' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rs3_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; op3:$rs3; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + op3val:$rs3_val; valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; + testreg:$testreg; fcsr_val:$fcsr */ + TEST_FPR4_OP($inst, $rd, $rs1, $rs2, $rs3, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fmsub.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 3 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IFD_Zicsr + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'r4format' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rs3_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; op3:$rs3; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + op3val:$rs3_val; valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; + testreg:$testreg; fcsr_val:$fcsr */ + TEST_FPR4_OP($inst, $rd, $rs1, $rs2, $rs3, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fnmadd.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 3 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr + - IFD_Zicsr + flen: [32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'r4format' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rs3_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; op3:$rs3; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + op3val:$rs3_val; valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; + testreg:$testreg; fcsr_val:$fcsr */ + TEST_FPR4_OP($inst, $rd, $rs1, $rs2, $rs3, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fnmadd.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 3 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IFD_Zicsr + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'r4format' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rs3_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; op3:$rs3; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + op3val:$rs3_val; valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; + testreg:$testreg; fcsr_val:$fcsr */ + TEST_FPR4_OP($inst, $rd, $rs1, $rs2, $rs3, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fnmsub.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 3 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr + - IFD_Zicsr + flen: [32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'r4format' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rs3_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; op3:$rs3; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + op3val:$rs3_val; valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; + testreg:$testreg; fcsr_val:$fcsr */ + TEST_FPR4_OP($inst, $rd, $rs1, $rs2, $rs3, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fnmsub.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 3 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IFD_Zicsr + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'r4format' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rs3_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; op3:$rs3; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + op3val:$rs3_val; valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; + testreg:$testreg; fcsr_val:$fcsr */ + TEST_FPR4_OP($inst, $rd, $rs1, $rs2, $rs3, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fsgnj.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr + - IFD_Zicsr + flen: [32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; fcsr: $fcsr; + correctval:??; testreg:$testreg + */ + TEST_FPRR_OP_NRM($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fsgnj.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IFD_Zicsr + flen: [64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; fcsr: $fcsr; + correctval:??; testreg:$testreg + */ + TEST_FPRR_OP_NRM($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fsgnjn.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr + - IFD_Zicsr + flen: [32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; fcsr: $fcsr; + correctval:??; testreg:$testreg + */ + TEST_FPRR_OP_NRM($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fsgnjn.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IFD_Zicsr + flen: [64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; fcsr: $fcsr; + correctval:??; testreg:$testreg + */ + TEST_FPRR_OP_NRM($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fsgnjx.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr + - IFD_Zicsr + flen: [32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; fcsr: $fcsr; + correctval:??; testreg:$testreg + */ + TEST_FPRR_OP_NRM($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fsgnjx.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IFD_Zicsr + flen: [64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; fcsr: $fcsr; + correctval:??; testreg:$testreg + */ + TEST_FPRR_OP_NRM($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fmin.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr + - IFD_Zicsr + flen: [32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; fcsr: $fcsr; + correctval:??; testreg:$testreg + */ + TEST_FPRR_OP_NRM($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fmin.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IFD_Zicsr + flen: [64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; fcsr: $fcsr; + correctval:??; testreg:$testreg + */ + TEST_FPRR_OP_NRM($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fmax.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr + - IFD_Zicsr + flen: [32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; fcsr: $fcsr; + correctval:??; testreg:$testreg + */ + TEST_FPRR_OP_NRM($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fmax.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IFD_Zicsr + flen: [64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; fcsr: $fcsr; + correctval:??; testreg:$testreg + */ + TEST_FPRR_OP_NRM($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +feq.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr + - IFD_Zicsr + flen: [32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; correctval:??; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FCMP_OP($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +feq.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IFD_Zicsr + flen: [64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; correctval:??; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FCMP_OP($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +flt.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr + - IFD_Zicsr + flen: [32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; correctval:??; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FCMP_OP($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +flt.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IFD_Zicsr + flen: [64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; correctval:??; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FCMP_OP($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fle.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr + - IFD_Zicsr + flen: [32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; correctval:??; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FCMP_OP($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fle.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IFD_Zicsr + flen: [64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; correctval:??; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FCMP_OP($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fmv.w.x: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: '4' + val_template: "'.word $val;'" + load_instr: "lw" + xlen: [32,64] + isa: + - IF_Zicsr + - IFD_Zicsr + flen: [32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_regs + rd_op_data: *all_fregs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; correctval:??; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FPIO_OP_NRM($inst, $rd, $rs1, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fmv.x.w: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr + - IFD_Zicsr + flen: [32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_fregs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; correctval:??; testreg:$testreg; + fcsr_val:$fcsr*/ + TEST_FPID_OP_NRM($inst, $rd, $rs1, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fcvt.w.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr + - IFD_Zicsr + flen: [32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_fregs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:??; testreg:$testreg; + fcsr_val:$fcsr*/ + TEST_FPID_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fcvt.w.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IFD_Zicsr + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_fregs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:??; testreg:$testreg; + fcsr_val:$fcsr*/ + TEST_FPID_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fcvt.wu.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr + - IFD_Zicsr + flen: [32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_fregs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:??; testreg:$testreg; + fcsr_val:$fcsr*/ + TEST_FPID_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fcvt.wu.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IFD_Zicsr + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_fregs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:??; testreg:$testreg; + fcsr_val:$fcsr*/ + TEST_FPID_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fcvt.l.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [64] + isa: + - IFD_Zicsr + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_fregs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:??; testreg:$testreg; + fcsr_val:$fcsr*/ + TEST_FPID_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fcvt.lu.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [64] + isa: + - IFD_Zicsr + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_fregs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:??; testreg:$testreg; + fcsr_val:$fcsr*/ + TEST_FPID_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fmv.x.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [64] + isa: + - IFD_Zicsr + flen: [64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_fregs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; correctval:??; testreg:$testreg; + fcsr_val:$fcsr*/ + TEST_FPID_OP_NRM($inst, $rd, $rs1, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fcvt.s.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IFD_Zicsr + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:??; testreg:$testreg; + fcsr_val: $fcsr */ + TEST_FPSR_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fcvt.d.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IFD_Zicsr + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; correctval:??; testreg:$testreg; + fcsr_val: $fcsr */ + TEST_FPSR_OP_NRM($inst, $rd, $rs1, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fcvt.s.w: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: '4' + val_template: "'.word $val;'" + load_instr: "lw" + xlen: [32,64] + isa: + - IF_Zicsr + - IFD_Zicsr + flen: [32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_regs + rd_op_data: *all_fregs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:??; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FPIO_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fcvt.s.wu: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: '4' + val_template: "'.word $val;'" + load_instr: "LREGWU" + xlen: [32,64] + isa: + - IF_Zicsr + - IFD_Zicsr + flen: [32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_regs + rd_op_data: *all_fregs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:??; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FPIO_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fcvt.d.w: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: '4' + val_template: "'.word $val;'" + load_instr: "lw" + xlen: [32,64] + isa: + - IFD_Zicsr + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_regs + rd_op_data: *all_fregs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; correctval:??; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FPIO_OP_NRM($inst, $rd, $rs1, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fcvt.d.wu: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: '4' + val_template: "'.word $val;'" + load_instr: "LREGWU" + xlen: [32,64] + isa: + - IFD_Zicsr + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_regs + rd_op_data: *all_fregs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; correctval:??; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FPIO_OP_NRM($inst, $rd, $rs1, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fcvt.d.l: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: '8' + val_template: "'.dword $val;'" + load_instr: "ld" + xlen: [64] + isa: + - IFD_Zicsr + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_regs + rd_op_data: *all_fregs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:??; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FPIO_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fcvt.d.lu: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: '8' + val_template: "'.dword $val;'" + load_instr: "ld" + xlen: [64] + isa: + - IFD_Zicsr + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_regs + rd_op_data: *all_fregs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:??; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FPIO_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fmv.d.x: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: '8' + val_template: "'.dword $val;'" + load_instr: "ld" + xlen: [64] + isa: + - IFD_Zicsr + flen: [64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_regs + rd_op_data: *all_fregs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; correctval:??; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FPIO_OP_NRM($inst, $rd, $rs1, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fclass.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr + - IFD_Zicsr + flen: [32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_fregs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; correctval:??; testreg:$testreg; + fcsr_val:$fcsr*/ + TEST_FPID_OP_NRM($inst, $rd, $rs1, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fclass.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32, 64] + isa: + - IFD_Zicsr + flen: [64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_fregs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; correctval:??; testreg:$testreg; + fcsr_val:$fcsr*/ + TEST_FPID_OP_NRM($inst, $rd, $rs1, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +# The val nodes are present in the fmem ops right now as a hack to force allocation of flagreg. Once +# anxilliary registers are moved to their own functions, this can be removed. +fsw: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + rs1_op_data: *all_regs_mx0 + rs2_op_data: *all_fregs + xlen: [32,64] + isa: + - IF_Zicsr + - IFD_Zicsr + flen: [32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'sformat' + ea_align_data: '[0,1,2,3]' + rs2_val_data: '[0xABCDEF12]' + imm_val_data: 'gen_sign_dataset(12)' + template: |- + // $comment + // opcode: $inst; op1:$rs1; op2:$rs2; op2val:$rs2_val; immval:$imm_val; align:$ea_align; flagreg:$flagreg; + // valreg: $valaddr_reg; valoffset: $val_offset + TEST_STORE_F($swreg,$testreg,$fcsr,$rs1,$rs2,$imm_val,$offset,$inst,$ea_align,$flagreg,$valaddr_reg, $val_offset) + +flw: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: '4' + val_template: "''" + load_instr: "flw" + rs1_op_data: *all_regs_mx0 + rd_op_data: *all_fregs + xlen: [32,64] + std_op: + isa: + - IF_Zicsr + - IFD_Zicsr + flen: [32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + formattype: 'iformat' + ea_align_data: '[0,1,2,3]' + imm_val_data: 'gen_sign_dataset(12)' + template: |- + // $comment + // opcode:$inst op1:$rs1; dest:$rd; immval:$imm_val; align:$ea_align; flagreg:$flagreg + TEST_LOAD_F($swreg,$testreg,$fcsr,$rs1,$rd,$imm_val,$inst,$ea_align,$flagreg) + +fsd: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + rs1_op_data: *all_regs_mx0 + rs2_op_data: *all_fregs + std_op: + xlen: [32,64] + isa: + - IFD_Zicsr + flen: [64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + formattype: 'sformat' + ea_align_data: '[0,1,2,3]' + rs2_val_data: '[0x0123456789ABCDEF]' + imm_val_data: 'gen_sign_dataset(12)' + template: |- + // $comment + // opcode: $inst; op1:$rs1; op2:$rs2; op2val:$rs2_val; immval:$imm_val; align:$ea_align; flagreg:$flagreg; + // valreg: $valaddr_reg; valoffset: $val_offset + TEST_STORE_F($swreg,$testreg,$fcsr,$rs1,$rs2,$imm_val,$offset,$inst,$ea_align,$flagreg,$valaddr_reg, $val_offset) + +fld: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: '8' + val_template: "''" + load_instr: "fld" + rs1_op_data: *all_regs_mx0 + rd_op_data: *all_fregs + xlen: [32,64] + std_op: + isa: + - IFD_Zicsr + flen: [64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + formattype: 'iformat' + ea_align_data: '[0,1,2,3]' + imm_val_data: 'gen_sign_dataset(12)' + template: |- + // $comment + // opcode:$inst op1:$rs1; dest:$rd; immval:$imm_val; align:$ea_align; flagreg:$flag_reg + TEST_LOAD_F($swreg,$testreg,$fcsr,$rs1,$rd,$imm_val,$inst,$ea_align,$flagreg) + +fcvt.l.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [64] + std_op: + isa: + - IF_Zicsr + - IFD_Zicsr + flen: [32,64] + rm_val_data: '[0,1,2,3,4,7]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + formattype: 'fsrformat' + rs1_op_data: *all_fregs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:??; testreg:$testreg; + fcsr_val:$fcsr*/ + TEST_FPID_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fcvt.lu.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [64] + isa: + - IF_Zicsr + - IFD_Zicsr + flen: [32,64] + rm_val_data: '[0,1,2,3,4,7]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_fregs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:??; testreg:$testreg; + fcsr_val:$fcsr*/ + TEST_FPID_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fcvt.s.l: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: '8' + val_template: "'.dword $val;'" + load_instr: "ld" + xlen: [64] + isa: + - IF_Zicsr + - IFD_Zicsr + std_op: + flen: [32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + formattype: 'fsrformat' + rs1_op_data: *all_regs + rd_op_data: *all_fregs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:??; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FPIO_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fcvt.s.lu: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: '8' + val_template: "'.dword $val;'" + load_instr: "ld" + xlen: [64] + isa: + - IF_Zicsr + - IFD_Zicsr + flen: [32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_regs + rd_op_data: *all_fregs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:??; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FPIO_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +flh: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: '4' + val_template: "''" + load_instr: "flh" + rs1_op_data: *all_regs_mx0 + rd_op_data: *all_fregs + xlen: [32,64] + std_op: + isa: + - IF_Zicsr_Zfh + flen: [32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + formattype: 'iformat' + ea_align_data: '[0,1,2,3]' + imm_val_data: 'gen_sign_dataset(12)' + template: |- + // $comment + // opcode:$inst op1:$rs1; dest:$rd; immval:$imm_val; align:$ea_align; flagreg:$flagreg + TEST_LOAD_F($swreg,$testreg,$fcsr,$rs1,$rd,$imm_val,$inst,$ea_align,$flagreg) + +fsgnj.h: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr_Zfh + flen: [16,32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; fcsr: $fcsr; + correctval:??; testreg:$testreg + */ + TEST_FPRR_OP_NRM($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + + +fsgnjn.h: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr_Zfh + flen: [16,32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; fcsr: $fcsr; + correctval:??; testreg:$testreg + */ + TEST_FPRR_OP_NRM($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fsgnjx.h: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr_Zfh + flen: [16,32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; fcsr: $fcsr; + correctval:??; testreg:$testreg + */ + TEST_FPRR_OP_NRM($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fmadd.h: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 3 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr_Zfh + flen: [16,32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'r4format' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rs3_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; op3:$rs3; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + op3val:$rs3_val; valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; + testreg:$testreg; fcsr_val:$fcsr */ + TEST_FPR4_OP($inst, $rd, $rs1, $rs2, $rs3, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fmax.h: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED_Z($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr_Zfh + flen: [16,32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; fcsr: $fcsr; + correctval:??; testreg:$testreg + */ + TEST_FPRR_OP_NRM($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fnmadd.h: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 3 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr_Zfh + - IFD_Zicsr + flen: [16,32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'r4format' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rs3_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; op3:$rs3; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + op3val:$rs3_val; valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; + testreg:$testreg; fcsr_val:$fcsr */ + TEST_FPR4_OP($inst, $rd, $rs1, $rs2, $rs3, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fnmsub.h: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 3 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr_Zfh + - IFD_Zicsr + flen: [16,32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'r4format' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rs3_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; op3:$rs3; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + op3val:$rs3_val; valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; + testreg:$testreg; fcsr_val:$fcsr */ + TEST_FPR4_OP($inst, $rd, $rs1, $rs2, $rs3, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fsub.h: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr_Zfh + flen: [16,32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; fcsr: $fcsr; + correctval:??; testreg:$testreg*/ + TEST_FPRR_OP($inst, $rd, $rs1, $rs2, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fmul.h: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr_Zfh + flen: [16,32] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; fcsr: $fcsr; + correctval:??; testreg:$testreg + */ + TEST_FPRR_OP($inst, $rd, $rs1, $rs2, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fdiv.h: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr_Zfh + flen: [16,32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; fcsr: $fcsr; + correctval:??; testreg:$testreg + */ + TEST_FPRR_OP($inst, $rd, $rs1, $rs2, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fcvt.h.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'.dword $val;'" + load_instr: "ld" + xlen: [32,64] + isa: + - IFD_Zicsr_Zfh + flen: [32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; correctval:??; testreg:$testreg; + fcsr_val: $fcsr */ + TEST_FPSR_OP_NRM($inst, $rd, $rs1, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fcvt.h.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr_Zfh + flen: [32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; correctval:??; testreg:$testreg; + fcsr_val: $fcsr */ + TEST_FPSR_OP_NRM($inst, $rd, $rs1, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +feq.h: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED_Z($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr_Zfh + flen: [16,32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; correctval:??; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FCMP_OP($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fle.h: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED_Z($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr_Zfh + flen: [16,32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; correctval:??; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FCMP_OP($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +flt.h: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED_Z($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr_Zfh + flen: [16,32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; correctval:??; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FCMP_OP($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fsqrt.h: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr_Zfh + flen: [16,32] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:??; testreg:$testreg; + fcsr_val: $fcsr */ + TEST_FPSR_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fmsub.h: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 3 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr_Zfh + flen: [16,32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'r4format' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rs3_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; op3:$rs3; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + op3val:$rs3_val; valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; + testreg:$testreg; fcsr_val:$fcsr */ + TEST_FPR4_OP($inst, $rd, $rs1, $rs2, $rs3, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fsh: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/4' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + rs1_op_data: *all_regs_mx0 + rs2_op_data: *all_fregs + xlen: [32,64] + isa: + - IF_Zicsr_Zfh + flen: [32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'sformat' + ea_align_data: '[0,1,2,3]' + rs2_val_data: '[0xABCDEF12]' + imm_val_data: 'gen_sign_dataset(12)' + template: |- + // $comment + // opcode: $inst; op1:$rs1; op2:$rs2; op2val:$rs2_val; immval:$imm_val; align:$ea_align; flagreg:$flagreg; + // valreg: $valaddr_reg; valoffset: $val_offset + TEST_STORE_F($swreg,$testreg,$fcsr,$rs1,$rs2,$imm_val,$offset,$inst,$ea_align,$flagreg,$valaddr_reg, $val_offset) + +fcvt.s.h: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr_Zfh + flen: [16,32] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:??; testreg:$testreg; + fcsr_val: $fcsr */ + TEST_FPSR_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fcvt.h.l: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: '8' + val_template: "'.dword $val;'" + load_instr: "ld" + xlen: [32,64] + isa: + - IF_Zicsr_Zfh + std_op: + flen: [16,32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + formattype: 'fsrformat' + rs1_op_data: *all_regs + rd_op_data: *all_fregs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:??; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FPIO_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fcvt.h.lu: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: '8' + val_template: "'.dword $val;'" + load_instr: "ld" + xlen: [32,64] + isa: + - IF_Zicsr_Zfh + flen: [16,32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_regs + rd_op_data: *all_fregs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:??; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FPIO_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fcvt.w.h: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED_Z($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr_Zfh + flen: [16,32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_fregs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:??; testreg:$testreg; + fcsr_val:$fcsr*/ + TEST_FPID_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fcvt.wu.h: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED_Z($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr_Zfh + flen: [16,32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_fregs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:??; testreg:$testreg; + fcsr_val:$fcsr*/ + TEST_FPID_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fcvt.d.h: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'.word $val;'" + load_instr: "lw" + xlen: [32,64] + isa: + - IFD_Zicsr_Zfh + flen: [16,32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; correctval:??; testreg:$testreg; + fcsr_val: $fcsr */ + TEST_FPSR_OP_NRM($inst, $rd, $rs1, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fmv.h.x: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: '4' + val_template: "'.word $val;'" + load_instr: "lw" + xlen: [32,64] + isa: + - IF_Zicsr_Zfh + flen: [16,32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_regs + rd_op_data: *all_fregs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; correctval:??; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FPIO_OP_NRM($inst, $rd, $rs1, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fmv.x.h: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr_Zfh + flen: [16,32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_fregs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; correctval:??; testreg:$testreg; + fcsr_val:$fcsr*/ + TEST_FPID_OP_NRM($inst, $rd, $rs1, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fadd.h: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr_Zfh + flen: [16,32] + std_op: + formattype: 'rformat' + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; fcsr: $fcsr; + correctval:??; testreg:$testreg + */ + TEST_FPRR_OP($inst, $rd, $rs1, $rs2, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fmin.h: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED_Z($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr_Zfh + flen: [16,32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; fcsr: $fcsr; + correctval:??; testreg:$testreg + */ + TEST_FPRR_OP_NRM($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fclass.h: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr_Zfh + flen: [16,32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_fregs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; correctval:??; testreg:$testreg; + fcsr_val:$fcsr*/ + TEST_FPID_OP_NRM($inst, $rd, $rs1, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fcvt.h.w: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: '4' + val_template: "'.word $val;'" + load_instr: "lw" + xlen: [32,64] + isa: + - IF_Zicsr_Zfh + flen: [16,32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_regs + rd_op_data: *all_fregs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:??; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FPIO_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fcvt.h.wu: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: '4' + val_template: "'.word $val;'" + load_instr: "LREGWU" + xlen: [32,64] + isa: + - IF_Zicsr_Zfh + flen: [16,32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_regs + rd_op_data: *all_fregs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:??; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FPIO_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fcvt.l.h: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [64] + std_op: + isa: + - IF_Zicsr_Zfh + flen: [16,32,64] + rm_val_data: '[0,1,2,3,4,7]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + formattype: 'fsrformat' + rs1_op_data: *all_fregs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:??; testreg:$testreg; + fcsr_val:$fcsr*/ + TEST_FPID_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fcvt.lu.h: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [64] + isa: + - IF_Zicsr_Zfh + flen: [16,32,64] + rm_val_data: '[0,1,2,3,4,7]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_fregs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:??; testreg:$testreg; + fcsr_val:$fcsr*/ + TEST_FPID_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +# +# Zfa extension +# + +fminm.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr_Zfa + - IFD_Zicsr_Zfa + flen: [32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; fcsr: $fcsr; + correctval:??; testreg:$testreg + */ + TEST_FPRR_OP_NRM($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fminm.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IFD_Zicsr_Zfa + flen: [64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; fcsr: $fcsr; + correctval:??; testreg:$testreg + */ + TEST_FPRR_OP_NRM($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fmaxm.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr_Zfa + - IFD_Zicsr_Zfa + flen: [32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; fcsr: $fcsr; + correctval:??; testreg:$testreg + */ + TEST_FPRR_OP_NRM($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fmaxm.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IFD_Zicsr_Zfa + flen: [64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; fcsr: $fcsr; + correctval:??; testreg:$testreg + */ + TEST_FPRR_OP_NRM($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fround.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr_Zfa + - IFD_Zicsr_Zfa + flen: [32,64] + std_op: + formattype: 'fsrformat' + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + rs1_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:??; testreg:$testreg; + fcsr_val: $fcsr */ + TEST_FPSR_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fround.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IFD_Zicsr_Zfa + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:??; testreg:$testreg; + fcsr_val: $fcsr */ + TEST_FPSR_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +froundnx.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr_Zfa + - IFD_Zicsr_Zfa + flen: [32,64] + std_op: + formattype: 'fsrformat' + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + rs1_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:??; testreg:$testreg; + fcsr_val: $fcsr */ + TEST_FPSR_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +froundnx.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IFD_Zicsr_Zfa + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_fregs + rd_op_data: *all_fregs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:??; testreg:$testreg; + fcsr_val: $fcsr */ + TEST_FPSR_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fmvh.x.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32] + isa: + - IFD_Zicsr_Zfa + flen: [64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_fregs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; correctval:??; testreg:$testreg; + fcsr_val:$fcsr*/ + TEST_FPID_OP_NRM($inst, $rd, $rs1, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fmvp.d.x: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: '4' + val_template: "'.word $val;'" + load_instr: "lw" + xlen: [32] + isa: + - IFD_Zicsr_Zfa + flen: [64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_fregs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; correctval:??; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FPIOIO_OP_NRM($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fcvtmod.w.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IFD_Zicsr_Zfa + flen: [64] + rm_val_data: '[1]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_fregs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:rtz; correctval:??; testreg:$testreg; + fcsr_val:$fcsr*/ + TEST_FPID_OP($inst, $rd, $rs1, rtz, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fltq.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr_Zfa + - IFD_Zicsr_Zfa + flen: [32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; correctval:??; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FCMP_OP($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fltq.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IFD_Zicsr_Zfa + flen: [64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; correctval:??; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FCMP_OP($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fleq.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IF_Zicsr_Zfa + - IFD_Zicsr_Zfa + flen: [32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; correctval:??; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FCMP_OP($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fleq.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "FLREG" + xlen: [32,64] + isa: + - IFD_Zicsr_Zfa + flen: [64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_fregs + rs2_op_data: *all_fregs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; correctval:??; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FCMP_OP($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) diff --git a/riscv-ctg/riscv_ctg/data/imc.yaml b/riscv-ctg/riscv_ctg/data/imc.yaml new file mode 100644 index 000000000..d77570efc --- /dev/null +++ b/riscv-ctg/riscv_ctg/data/imc.yaml @@ -0,0 +1,1892 @@ +# See LICENSE.incore for details +add: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - I + operation: 'hex((rs1_val + rs2_val) & (2**(xlen)-1))' + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +sub: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + isa: + - I + operation: 'hex((rs1_val - rs2_val) & (2**(xlen)-1))' + formattype: 'rformat' + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + + +addw: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + xlen: [64] + std_op: + isa: + - I + operation: 'hex(sign_extend( (rs1_val & 0xFFFFFFFF) + (rs2_val & 0xFFFFFFFF) ,32))' + formattype: 'rformat' + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +subw: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + xlen: [64] + std_op: + isa: + - I + operation: 'hex(sign_extend( (rs1_val & 0xFFFFFFFF) - (rs2_val & 0xFFFFFFFF) ,32))' + formattype: 'rformat' + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +and: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - I + operation: 'hex((rs1_val & rs2_val) & (2**(xlen)-1))' + formattype: 'rformat' + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +or: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - I + operation: 'hex((rs1_val | rs2_val) & (2**(xlen)-1))' + formattype: 'rformat' + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +slt: + rs1_op_data: *all_regs + sig: + stride: 1 + sz: 'XLEN/8' + rs2_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - I + operation: 'hex(int(rs1_val < rs2_val) & (2**(xlen)-1))' + formattype: 'rformat' + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +sltu: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - I + operation: 'hex(int(rs1_val < rs2_val) & (2**(xlen)-1))' + formattype: 'rformat' + rs1_val_data: 'gen_usign_dataset(xlen) + gen_sp_dataset(xlen,False)' + rs2_val_data: 'gen_usign_dataset(xlen) + gen_sp_dataset(xlen,False)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +xor: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - I + operation: 'hex((rs1_val ^ rs2_val) & (2**(xlen)-1))' + formattype: 'rformat' + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +sllw: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + xlen: [64] + std_op: + isa: + - I + operation: 'hex(sign_extend((rs1_val << (rs2_val%32)) ,32))' + formattype: 'rformat' + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_usign_dataset(5)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +srlw: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + xlen: [64] + std_op: + isa: + - I + operation: 'hex(sign_extend((rs1_val & 0xffffffff) >> (rs2_val%32), 32))' + formattype: 'rformat' + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_usign_dataset(5)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +sraw: + rs1_op_data: *all_regs + sig: + stride: 1 + sz: 'XLEN/8' + rs2_op_data: *all_regs + rd_op_data: *all_regs + xlen: [64] + std_op: + isa: + - I + operation: 'hex(sign_extend((sign_extend(rs1_val,32) >> ((rs2_val & 0xffffffff) %32))& 0xffffffff ,32))' + formattype: 'rformat' + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_usign_dataset(5)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +sll: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - I + operation: 'hex((rs1_val << (rs2_val%xlen)) & (2**(xlen)-1))' + formattype: 'rformat' + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_usign_dataset(ceil(log(xlen,2)))' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +srl: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - I + operation: 'hex((rs1_val & (2**(xlen)-1)) >> (rs2_val%xlen))' + formattype: 'rformat' + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_usign_dataset(ceil(log(xlen,2)))' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +sra: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - I + operation: 'hex(rs1_val >> (rs2_val%xlen) )' + formattype: 'rformat' + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_usign_dataset(ceil(log(xlen,2)))' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +addi: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - I + operation: 'hex((rs1_val + imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)+ gen_sp_dataset(12)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +addiw: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [64] + std_op: + isa: + - I + operation: 'hex(sign_extend( (rs1_val & 0xFFFFFFFF) + (imm_val & 0xffffffff) , 32))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)+ gen_sp_dataset(12,True)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +slti: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - I + operation: 'hex(int(rs1_val < imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)+ gen_sp_dataset(12,True)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +sltiu: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - I + operation: 'hex(int(rs1_val < int(imm_val if imm_val&0x800 == 0 else imm_val + int("0x"+"".join("f"*int((xlen-12)/4)+"000"),16))) & (2**(xlen)-1))' + rs1_val_data: 'gen_usign_dataset(xlen)+ gen_sp_dataset(xlen,False)' + imm_val_data: 'gen_usign_dataset(12)+ gen_sp_dataset(12,False)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +andi: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - I + operation: 'hex((rs1_val & imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)+ gen_sp_dataset(12)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +ori: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - I + operation: 'hex((rs1_val | imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)+ gen_sp_dataset(12)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +xori: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - I + operation: 'hex((rs1_val ^ imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)+ gen_sp_dataset(12)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +slli: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - I + operation: 'hex((rs1_val << imm_val) & (2**(xlen)-1))' + formattype: 'iformat' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_usign_dataset(ceil(log(xlen,2)))' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +srli: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - I + operation: 'hex((rs1_val & (2**(xlen)-1)) >> imm_val)' + formattype: 'iformat' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_usign_dataset(ceil(log(xlen,2)))' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +srai: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - I + operation: 'hex(rs1_val >> (imm_val))' + formattype: 'iformat' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_usign_dataset(ceil(log(xlen,2)))' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +slliw: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [64] + std_op: + isa: + - I + operation: 'hex(sign_extend((rs1_val << imm_val) , 32))' + formattype: 'iformat' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_usign_dataset(5)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +srliw: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [64] + std_op: + isa: + - I + operation: 'hex(sign_extend((rs1_val & 0xFFFFFFFF) >> imm_val , 32))' + formattype: 'iformat' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_usign_dataset(5)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +sraiw: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [64] + std_op: + isa: + - I + operation: 'hex(sign_extend((sign_extend(rs1_val,32) >> ((imm_val & 0xfff) %32)) & 0xffffffff, 32))' + formattype: 'iformat' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_usign_dataset(5)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +lui: + sig: + stride: 1 + sz: 'XLEN/8' + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - I + operation: 'hex(sign_extend(imm_val << (12), 32))' + formattype: 'uformat' + imm_val_data: 'gen_usign_dataset(20)+ gen_sp_dataset(20,False)' + template: |- + + // $comment + // opcode: $inst ; dest:$rd; immval:$imm_val + TEST_CASE($testreg, $rd, $correctval, $swreg, $offset, $inst $rd,$imm_val) + +auipc: + sig: + stride: 1 + sz: 'XLEN/8' + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - I + operation: 'hex(sign_extend(imm_val << (12) ,32))' + formattype: 'uformat' + imm_val_data: 'gen_usign_dataset(20)+ gen_sp_dataset(20, False)' + template: |- + + // $comment + // opcode: $inst ; dest:$rd; immval:$imm_val + TEST_AUIPC($inst, $rd, $correctval, $imm_val, $swreg, $offset, $testreg) + +beq: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - I + formattype: 'bformat' + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + ea_align_data: '[0,1,2,3]' + imm_val_data: 'list(filter(lambda x: x%2==0,gen_sign_dataset(12)))' + template: |- + + // $comment + // opcode: $inst, op1:$rs1; op2:$rs2; op1val:$rs1_val; op2val:$rs2_val; immval:$imm_val; align:$ea_align + TEST_BRANCH_OP($inst, $testreg, $rs1, $rs2, $rs1_val, $rs2_val, $imm_val, $label, $swreg, $offset,$ea_align) + +bge: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - I + formattype: 'bformat' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + ea_align_data: '[0,1,2,3]' + imm_val_data: 'list(filter(lambda x: x%2==0,gen_sign_dataset(12)))' + template: |- + + // $comment + // opcode: $inst, op1:$rs1; op2:$rs2; op1val:$rs1_val; op2val:$rs2_val; immval:$imm_val; align:$ea_align + TEST_BRANCH_OP($inst, $testreg, $rs1, $rs2, $rs1_val, $rs2_val, $imm_val, $label, $swreg, $offset,$ea_align) + +bgeu: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - I + formattype: 'bformat' + rs1_val_data: 'gen_usign_dataset(xlen)+ gen_sp_dataset(xlen,False)' + rs2_val_data: 'gen_usign_dataset(xlen)+ gen_sp_dataset(xlen,False)' + ea_align_data: '[0,1,2,3]' + imm_val_data: 'list(filter(lambda x: x%2==0,gen_sign_dataset(12)))' + template: |- + + // $comment + // opcode: $inst, op1:$rs1; op2:$rs2; op1val:$rs1_val; op2val:$rs2_val; immval:$imm_val; align:$ea_align + TEST_BRANCH_OP($inst, $testreg, $rs1, $rs2, $rs1_val, $rs2_val, $imm_val, $label, $swreg, $offset,$ea_align) + +blt: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - I + formattype: 'bformat' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + ea_align_data: '[0,1,2,3]' + imm_val_data: 'list(filter(lambda x: x%2==0,gen_sign_dataset(12)))' + template: |- + + // $comment + // opcode: $inst, op1:$rs1; op2:$rs2; op1val:$rs1_val; op2val:$rs2_val; immval:$imm_val; align:$ea_align + TEST_BRANCH_OP($inst, $testreg, $rs1, $rs2, $rs1_val, $rs2_val, $imm_val, $label, $swreg, $offset,$ea_align) + +bltu: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - I + formattype: 'bformat' + rs1_val_data: 'gen_usign_dataset(xlen)+ gen_sp_dataset(xlen,False)' + rs2_val_data: 'gen_usign_dataset(xlen)+ gen_sp_dataset(xlen,False)' + ea_align_data: '[0,1,2,3]' + imm_val_data: 'list(filter(lambda x: x%2==0,gen_sign_dataset(12)))' + template: |- + + // $comment + // opcode: $inst, op1:$rs1; op2:$rs2; op1val:$rs1_val; op2val:$rs2_val; immval:$imm_val; align:$ea_align + TEST_BRANCH_OP($inst, $testreg, $rs1, $rs2, $rs1_val, $rs2_val, $imm_val, $label, $swreg, $offset,$ea_align) + +bne: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - I + formattype: 'bformat' + rs1_val_data: 'gen_sign_dataset(xlen)+gen_sp_dataset(xlen) ' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_sp_dataset(xlen) ' + ea_align_data: '[0,1,2,3]' + imm_val_data: 'list(filter(lambda x: x%2==0,gen_sign_dataset(12)))' + template: |- + + // $comment + // opcode: $inst, op1:$rs1; op2:$rs2; op1val:$rs1_val; op2val:$rs2_val; immval:$imm_val; align:$ea_align + TEST_BRANCH_OP($inst, $testreg, $rs1, $rs2, $rs1_val, $rs2_val, $imm_val, $label, $swreg, $offset,$ea_align) + +sd: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs_mx0 + rs2_op_data: *all_regs + rd_op_data: *all_regs + xlen: [64] + std_op: + isa: + - I + formattype: 'sformat' + ea_align_data: '[0,1,2,3,4,5,6,7]' + rs2_val_data: 'gen_sign_dataset(xlen)' + imm_val_data: 'gen_sign_dataset(12)' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + template: |- + + // $comment + // opcode: $inst; op1:$rs1; op2:$rs2; op2val:$rs2_val; immval:$imm_val; align:$ea_align + TEST_STORE($swreg,$testreg,$index,$rs1,$rs2,$rs2_val,$imm_val,$offset,$inst,$ea_align) + +sw: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs_mx0 + rs2_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - I + formattype: 'sformat' + ea_align_data: '[0,1,2,3]' + rs2_val_data: 'gen_sign_dataset(xlen)' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)' + template: |- + + // $comment + // opcode: $inst; op1:$rs1; op2:$rs2; op2val:$rs2_val; immval:$imm_val; align:$ea_align + TEST_STORE($swreg,$testreg,$index,$rs1,$rs2,$rs2_val,$imm_val,$offset,$inst,$ea_align) + +sh: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs_mx0 + rs2_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - I + formattype: 'sformat' + ea_align_data: '[0,1,2,3]' + rs2_val_data: 'gen_sign_dataset(xlen)' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)' + template: |- + + // $comment + // opcode: $inst; op1:$rs1; op2:$rs2; op2val:$rs2_val; immval:$imm_val; align:$ea_align + TEST_STORE($swreg,$testreg,$index,$rs1,$rs2,$rs2_val,$imm_val,$offset,$inst,$ea_align) + +sb: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs_mx0 + rs2_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - I + formattype: 'sformat' + ea_align_data: '[0,1,2,3]' + rs2_val_data: 'gen_sign_dataset(xlen)' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)' + template: |- + + // $comment + // opcode: $inst; op1:$rs1; op2:$rs2; op2val:$rs2_val; immval:$imm_val; align:$ea_align + TEST_STORE($swreg,$testreg,$index,$rs1,$rs2,$rs2_val,$imm_val,$offset,$inst,$ea_align) + +ld: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs_mx0 + rd_op_data: *all_regs + isa: + - I + xlen: [64] + std_op: + formattype: 'iformat' + ea_align_data: '[0,1,2,3,4,5,6,7]' + imm_val_data: 'gen_sign_dataset(12)' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + template: |- + + // $comment + // opcode:$inst op1:$rs1; dest:$rd; immval:$imm_val; align:$ea_align + TEST_LOAD($swreg,$testreg,$index,$rs1,$rd,$imm_val,$offset,$inst,$ea_align) + +lwu: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs_mx0 + rd_op_data: *all_regs + isa: + - I + xlen: [64] + std_op: + formattype: 'iformat' + ea_align_data: '[0,1,2,3]' + imm_val_data: 'gen_sign_dataset(12)' + rs1_val_data: 'gen_usign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + template: |- + + // $comment + // opcode:$inst op1:$rs1; dest:$rd; immval:$imm_val; align:$ea_align + TEST_LOAD($swreg,$testreg,$index,$rs1,$rd,$imm_val,$offset,$inst,$ea_align) + +lw: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs_mx0 + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - I + formattype: 'iformat' + ea_align_data: '[0,1,2,3]' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)' + template: |- + + // $comment + // opcode:$inst op1:$rs1; dest:$rd; immval:$imm_val; align:$ea_align + TEST_LOAD($swreg,$testreg,$index,$rs1,$rd,$imm_val,$offset,$inst,$ea_align) + +lhu: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs_mx0 + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - I + formattype: 'iformat' + ea_align_data: '[0,1,2,3]' + rs1_val_data: 'gen_usign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)' + template: |- + + // $comment + // opcode:$inst op1:$rs1; dest:$rd; immval:$imm_val; align:$ea_align + TEST_LOAD($swreg,$testreg,$index,$rs1,$rd,$imm_val,$offset,$inst,$ea_align) + +lh: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs_mx0 + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - I + formattype: 'iformat' + ea_align_data: '[0,1,2,3]' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)' + template: |- + + // $comment + // opcode:$inst op1:$rs1; dest:$rd; immval:$imm_val; align:$ea_align + TEST_LOAD($swreg,$testreg,$index,$rs1,$rd,$imm_val,$offset,$inst,$ea_align) + +lbu: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs_mx0 + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - I + formattype: 'iformat' + ea_align_data: '[0,1,2,3]' + imm_val_data: 'gen_sign_dataset(12)' + rs1_val_data: 'gen_usign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + template: |- + + // $comment + // opcode:$inst op1:$rs1; dest:$rd; immval:$imm_val; align:$ea_align + TEST_LOAD($swreg,$testreg,$index,$rs1,$rd,$imm_val,$offset,$inst,$ea_align) + +lb: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs_mx0 + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - I + formattype: 'iformat' + ea_align_data: '[0,1,2,3]' + imm_val_data: 'gen_sign_dataset(12)' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + template: |- + + // $comment + // opcode:$inst op1:$rs1; dest:$rd; immval:$imm_val; align:$ea_align + TEST_LOAD($swreg,$testreg,$index,$rs1,$rd,$imm_val,$offset,$inst,$ea_align) + +jal: + sig: + stride: 1 + sz: 'XLEN/8' + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - I + formattype: 'jformat' + ea_align_data: '[0,1,2,3]' + imm_val_data: 'list(filter(lambda x: x%2==0,gen_sign_dataset(20)))' + template: |- + + // $comment + // opcode: jal; dest:$rd; immval:$imm_val; align:$ea_align + TEST_JAL_OP($testreg, $rd, $imm_val, $label, $swreg, $offset,$ea_align) + +jalr: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs_mx0 + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - I + formattype: 'iformat' + ea_align_data: '[0,1,2,3]' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)' + template: |- + + // $comment + // opcode: jalr; op1:$rs1; dest:$rd; immval:$imm_val; align:$ea_align + TEST_JALR_OP($testreg, $rd, $rs1, $imm_val, $swreg, $offset,$ea_align) + +mul: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IM + formattype: 'rformat' + operation: 'hex((rs1_val * rs2_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +mulh: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IM + formattype: 'rformat' + operation: 'hex(((rs1_val * rs2_val)>>xlen) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +mulhu: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IM + formattype: 'rformat' + operation: 'hex(((rs1_val * rs2_val)>>xlen) & (2**(xlen)-1))' + rs1_val_data: 'gen_usign_dataset(xlen) + gen_sp_dataset(xlen,False)' + rs2_val_data: 'gen_usign_dataset(xlen) + gen_sp_dataset(xlen,False)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +mulhsu: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IM + formattype: 'rformat' + operation: 'hex(((rs1_val * (rs2_val if rs2_val>=0 else int(hex((1<>xlen) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_usign_dataset(xlen) + gen_sp_dataset(xlen,False)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +div: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IM + formattype: 'rformat' + operation: 'hex(int(abs(rs1_val)//abs(rs2_val))) if (rs1_val * rs2_val > 0) else hex(-int(abs(rs1_val)//abs(rs2_val))) if rs2_val != 0 else "0x"+("F"*int(xlen/4))' + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True) + [-(2**(xlen-1))]' + rs2_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +divu: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IM + formattype: 'rformat' + operation: 'hex(int(rs1_val // rs2_val) & (2**(xlen)-1)) if rs2_val!=0 else "0x"+("F"*int(xlen/4))' + rs1_val_data: 'gen_usign_dataset(xlen) + gen_sp_dataset(xlen,False)' + rs2_val_data: 'gen_usign_dataset(xlen) + gen_sp_dataset(xlen,False)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +rem: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IM + formattype: 'rformat' + # operation: 'hex(rs1_val if rs2_val==0 or (rs1_val 0 else hex(-int(abs(rs1_val) % abs(rs2_val)))' + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True) + [-(2**(xlen-1))]' + rs2_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +remu: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IM + formattype: 'rformat' + operation: 'hex(rs1_val) if rs2_val == 0 else hex(int(abs(rs1_val) % abs(rs2_val))) ' + rs1_val_data: 'gen_usign_dataset(xlen) + gen_sp_dataset(xlen,False)' + rs2_val_data: 'gen_usign_dataset(xlen) + gen_sp_dataset(xlen,False)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +mulw: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + xlen: [64] + std_op: + isa: + - IM + formattype: 'rformat' + operation: 'hex(sign_extend((rs1_val & 0xFFFFFFFF) * (rs2_val & 0xFFFFFFFF) ,32))' + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +divw: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + xlen: [64] + std_op: + isa: + - IM + formattype: 'rformat' + # operation: 'hex(sign_extend(int((rs1_val & 0xFFFFFFFF) // (rs2_val & 0xFFFFFFFF)) ,32)) if (rs2_val&0xFFFFFFFF)!=0 else "0x"+("F"*int(xlen/4))' + operation: 'hex(sign_extend(int(abs(sign_extend(rs1_val,32))//abs(sign_extend(rs2_val,32))),32)) if (sign_extend(rs1_val,32) * sign_extend(rs2_val,32) > 0) else hex(-int(abs(sign_extend(rs1_val,32))//abs(sign_extend(rs2_val, 32)))) if sign_extend(rs2_val,32) != 0 else "0x"+("F"*int(xlen/4))' + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +divuw: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + xlen: [64] + std_op: + isa: + - IM + formattype: 'rformat' + operation: 'hex(sign_extend(int((rs1_val & 0xFFFFFFFF) // (rs2_val & 0xFFFFFFFF)) ,32)) if (rs2_val&0xFFFFFFFF)!=0 else "0x"+("F"*int(xlen/4))' + rs1_val_data: 'gen_usign_dataset(xlen) + gen_sp_dataset(xlen,False)' + rs2_val_data: 'gen_usign_dataset(xlen) + gen_sp_dataset(xlen,False)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +remw: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + xlen: [64] + std_op: + isa: + - IM + formattype: 'rformat' + # operation: 'hex(sign_extend(((rs1_val & 0xFFFFFFFF) % (rs2_val & 0xFFFFFFFF)) , 32)) if (rs2_val&0xFFFFFFFF)!=0 else hex(rs1_val)' + operation: 'hex(sign_extend(rs1_val,32)) if (rs2_val&0xffffffff) == 0 else hex(sign_extend(int(abs(sign_extend(rs1_val,32)) % abs(sign_extend(rs2_val,32))),32)) if sign_extend(rs1_val,32) > 0 else hex(-int(abs(sign_extend(rs1_val,32)) % abs(sign_extend(rs2_val,32))))' + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +remuw: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + xlen: [64] + std_op: + isa: + - IM + formattype: 'rformat' + operation: 'hex(sign_extend((rs1_val & 0xFFFFFFFF) % (rs2_val & 0xFFFFFFFF) , 32)) if (rs2_val&0xFFFFFFFF)!=0 else hex(sign_extend(rs1_val,32))' + rs1_val_data: 'gen_usign_dataset(xlen) + gen_sp_dataset(xlen,False)' + rs2_val_data: 'gen_usign_dataset(xlen) + gen_sp_dataset(xlen,False)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +c.mv: + sig: + stride: 1 + sz: 'XLEN/8' + rs2_op_data: *all_regs_mx0 + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IC + formattype: 'cmvformat' + operation: 'hex(rs2_val)' + rs2_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst; op2:$rs2; dest:$rd; op2val:$rs2_val + TEST_CMV_OP( $inst, $rd, $rs2, $correctval, $rs2_val, $swreg, $offset, $testreg) + +c.add: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rs2_op_data: *all_regs_mx0 + xlen: [32,64] + std_op: + isa: + - IC + formattype: 'crformat' + operation: 'hex((rs1_val + rs2_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_sp_dataset(xlen,True)' + template: |- + + // $comment + // opcode: $inst; op1:$rs1; op2:$rs2; op1val:$rs1_val; op2val:$rs2_val + TEST_CR_OP( $inst, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +c.addw: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *c_regs + rs2_op_data: *c_regs + xlen: [64] + std_op: + isa: + - IC + formattype: 'crformat' + operation: 'hex(sign_extend((rs1_val + rs2_val) ,32))' + rs1_val_data: 'gen_sign_dataset(xlen)+gen_sp_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_sp_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst; op1:$rs1; op2:$rs2; op1val:$rs1_val; op2val:$rs2_val + TEST_CR_OP( $inst, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +c.and: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *c_regs + rs2_op_data: *c_regs + xlen: [32,64] + std_op: + isa: + - IC + formattype: 'crformat' + operation: 'hex((rs1_val & rs2_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+gen_sp_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_sp_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst; op1:$rs1; op2:$rs2; op1val:$rs1_val; op2val:$rs2_val + TEST_CR_OP( $inst, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +c.or: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *c_regs + rs2_op_data: *c_regs + xlen: [32,64] + std_op: + isa: + - IC + formattype: 'crformat' + operation: 'hex((rs1_val | rs2_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+gen_sp_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_sp_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst; op1:$rs1; op2:$rs2; op1val:$rs1_val; op2val:$rs2_val + TEST_CR_OP( $inst, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +c.xor: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *c_regs + rs2_op_data: *c_regs + xlen: [32,64] + std_op: + isa: + - IC + formattype: 'crformat' + operation: 'hex((rs1_val ^ rs2_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+gen_sp_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_sp_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst; op1:$rs1; op2:$rs2; op1val:$rs1_val; op2val:$rs2_val + TEST_CR_OP( $inst, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +c.sub: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *c_regs + rs2_op_data: *c_regs + xlen: [32,64] + std_op: + isa: + - IC + formattype: 'crformat' + operation: 'hex((rs1_val - rs2_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+gen_sp_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_sp_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst; op1:$rs1; op2:$rs2; op1val:$rs1_val; op2val:$rs2_val + TEST_CR_OP( $inst, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +c.subw: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *c_regs + rs2_op_data: *c_regs + xlen: [64] + std_op: + isa: + - IC + formattype: 'crformat' + operation: 'hex(sign_extend((rs1_val & 0xFFFFFFFF) - (rs2_val & 0xFFFFFFFF) ,32))' + rs1_val_data: 'gen_sign_dataset(xlen)+gen_sp_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_sp_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst; op1:$rs1; op2:$rs2; op1val:$rs1_val; op2val:$rs2_val + TEST_CR_OP( $inst, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +c.andi: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *c_regs + xlen: [32,64] + std_op: + isa: + - IC + formattype: 'cbformat' + operation: 'hex((rs1_val & imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+gen_sp_dataset(xlen)' + imm_val_data: 'gen_sign_dataset(6)+gen_sp_dataset(6)' + template: |- + + // $comment + // opcode: $inst; op1:$rs1; immval:$imm_val + TEST_CI_OP( $inst, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +c.nop: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IC + formattype: 'ciformat' + imm_val_data: 'gen_sign_dataset(6)' + rs1_data: "['x0']" + rs1_val_data: "[0]" + template: |- + // $comment + // opcode:$inst; immval:$imm_val + TEST_CNOP_OP($inst, $testreg, $imm_val, $swreg, $offset) + +c.addi: + sig: + stride: 1 + sz: 'XLEN/8' + rd_op_data: *all_regs_mx0 + xlen: [32,64] + std_op: + isa: + - IC + formattype: 'ciformat' + operation: 'hex((rs1_val + imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen)' + imm_val_data: 'gen_sign_dataset(6) + gen_sp_dataset(6)' + template: |- + + // $comment + // opcode:$inst; op1:$rd; dest:$rd op1val:$rs1_val; immval:$imm_val + TEST_CI_OP( $inst, $rd, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +c.addiw: + sig: + stride: 1 + sz: 'XLEN/8' + rd_op_data: *all_regs_mx0 + xlen: [64] + std_op: + isa: + - IC + formattype: 'ciformat' + operation: 'hex(sign_extend(((rs1_val & 0xFFFFFFFF) + (imm_val & 0xffffffff)) , 32))' + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen)' + imm_val_data: 'gen_sign_dataset(6) + gen_sp_dataset(6)' + template: |- + + // $comment + // opcode:$inst; op1:$rd; dest:$rd op1val:$rs1_val; immval:$imm_val + TEST_CI_OP( $inst, $rd, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +c.addi16sp: + sig: + stride: 1 + sz: 'XLEN/8' + rd_op_data: "['x2']" + xlen: [32,64] + std_op: + isa: + - IC + formattype: 'ciformat' + operation: 'hex((rs1_val + imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)' + imm_val_data: 'list(filter( lambda x: x!=0 , [ 16*x for x in gen_sign_dataset(6)])) + [496]' + template: |- + + // $comment + // opcode:$inst; op1:x2; dest:x2 op1val:$rs1_val; immval:$imm_val + TEST_CI_OP( $inst, x2, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +c.addi4spn: + sig: + stride: 1 + sz: 'XLEN/8' + rd_op_data: *c_regs + xlen: [32,64] + std_op: + isa: + - IC + formattype: 'ciwformat' + operation: 'hex(imm_val)' + imm_val_data: 'list(filter( lambda x: x!=0 , [ 4*x for x in gen_usign_dataset(8)]))' + template: |- + + // $comment + // opcode:$inst; dest:$rd; immval:$imm_val + TEST_CADDI4SPN_OP( $inst, $rd, $correctval, $imm_val, $swreg, $offset, $testreg) + +c.slli: + sig: + stride: 1 + sz: 'XLEN/8' + rd_op_data: *c_regs + xlen: [32,64] + std_op: + isa: + - IC + formattype: 'ciformat' + operation: 'hex((rs1_val << imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen)' + imm_val_data: 'list(filter(lambda x: x!=0, gen_usign_dataset(ceil(log(xlen,2)))))' + template: |- + + // $comment + // opcode:$inst; op1:$rd; dest:$rd op1val:$rs1_val; immval:$imm_val + TEST_CI_OP( $inst, $rd, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +c.srli: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *c_regs + xlen: [32,64] + std_op: + isa: + - IC + formattype: 'cbformat' + operation: 'hex(((rs1_val & (2**(xlen)-1)) >> imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen)' + imm_val_data: 'list(filter(lambda x: x!=0, gen_usign_dataset(ceil(log(xlen,2)))))' + template: |- + + // $comment + // opcode:$inst; op1:$rs1; dest:$rs1 op1val:$rs1_val; immval:$imm_val + TEST_CI_OP( $inst, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +c.srai: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *c_regs + xlen: [32,64] + std_op: + isa: + - IC + formattype: 'cbformat' + operation: 'hex(rs1_val >> (imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen)' + imm_val_data: 'list(filter(lambda x: x!=0, gen_usign_dataset(ceil(log(xlen,2)))))' + template: |- + + // $comment + // opcode:$inst; op1:$rs1; dest:$rs1 op1val:$rs1_val; immval:$imm_val + TEST_CI_OP( $inst, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +c.li: + sig: + stride: 1 + sz: 'XLEN/8' + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IC + formattype: 'ciformat' + operation : 'hex(sign_extend(imm_val,6))' + imm_val_data: 'gen_sign_dataset(6)' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen)' + template: |- + + // $comment + // opcode:$inst; dest:$rd; immval:$imm_val + TEST_CASE($testreg, $rd, $correctval, $swreg, $offset, $inst $rd, $imm_val;) + +c.lui: + sig: + stride: 1 + sz: 'XLEN/8' + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IC + formattype: 'ciformat' + operation: 'hex(sign_extend(imm_val << 12,32))' + rs1_val_data: 'gen_sign_dataset(xlen)' + imm_val_data: 'list(filter(lambda x: x!=0 ,gen_usign_dataset(6)))' + template: |- + + // $comment + // opcode:$inst; op1:$rd; dest:$rd op1val:$rs1_val; immval:$imm_val + TEST_CI_OP( $inst, $rd, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +c.sw: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *c_regs + rs2_op_data: *c_regs + xlen: [32,64] + std_op: + isa: + - IC + formattype: 'csformat' + rs1_val_data: '[0]' + rs2_val_data: 'gen_sign_dataset(xlen)' + imm_val_data: '[x*4 for x in gen_usign_dataset(5)]' + template: |- + + // $comment + // opcode:$inst; op1:$rs1; op2:$rs2; op2val:$rs2_val; immval:$imm_val + TEST_STORE($swreg,$testreg,$index,$rs1,$rs2,$rs2_val,$imm_val,$offset,$inst,0) + +c.sd: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *c_regs + rs2_op_data: *c_regs + xlen: [64] + std_op: + isa: + - IC + formattype: 'csformat' + rs1_val_data: '[0]' + rs2_val_data: 'gen_sign_dataset(xlen)' + imm_val_data: '[x*8 for x in gen_usign_dataset(5)]' + template: |- + + // $comment + // opcode:$inst; op1:$rs1; op2:$rs2; op2val:$rs2_val; immval:$imm_val + TEST_STORE($swreg,$testreg,$index,$rs1,$rs2,$rs2_val,$imm_val,$offset,$inst,0) + +c.ld: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *c_regs + rd_op_data: *c_regs + xlen: [64] + std_op: + isa: + - IC + formattype: 'clformat' + rs1_val_data: '[0]' + imm_val_data: '[x*8 for x in gen_usign_dataset(5)]' + template: |- + + // $comment + // opcode: $inst; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_LOAD($swreg,$testreg,$index,$rs1,$rd,$imm_val,$offset,$inst,$rs1_val) + +c.lw: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *c_regs + rd_op_data: *c_regs + xlen: [32,64] + std_op: + isa: + - IC + formattype: 'clformat' + rs1_val_data: '[0]' + imm_val_data: '[x*4 for x in gen_usign_dataset(5)]' + template: |- + + // $comment + // opcode: $inst; op1:$rs1; dest:$rd; immval:$imm_val + TEST_LOAD($swreg,$testreg,$index,$rs1,$rd,$imm_val,$offset,$inst,0) + +c.lwsp: + sig: + stride: 1 + sz: 'XLEN/8' + rd_op_data: *all_regs_mx0 + xlen: [32,64] + std_op: + isa: + - IC + formattype: 'ciformat' + imm_val_data: '[x*4 for x in gen_usign_dataset(6)]' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst; op1:$rs1; dest:$rd; immval:$imm_val + TEST_LOAD($swreg,$testreg,$index,$rs1,$rd,$imm_val,$offset,$inst,0) + +c.ldsp: + sig: + stride: 1 + sz: 'XLEN/8' + rd_op_data: *all_regs_mx0 + xlen: [64] + std_op: + isa: + - IC + formattype: 'ciformat' + imm_val_data: '[x*8 for x in gen_usign_dataset(6)]' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst; op1:x2; dest:$rd; immval:$imm_val + TEST_LOAD($swreg,$testreg,$index,x2,$rd,$imm_val,$offset,$inst,0) + +c.swsp: + sig: + stride: 1 + sz: 'XLEN/8' + rs2_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IC + formattype: 'cssformat' + rs2_val_data: 'gen_sign_dataset(xlen)' + imm_val_data: '[x*4 for x in gen_usign_dataset(6)]' + template: |- + + // $comment + // opcode:$inst; op1:x2; op2:$rs2; op2val:$rs2_val; immval:$imm_val + TEST_STORE($swreg,$testreg,$index,x2,$rs2,$rs2_val,$imm_val,$offset,$inst,0) + +c.sdsp: + sig: + stride: 1 + sz: 'XLEN/8' + rs2_op_data: *all_regs + xlen: [64] + std_op: + isa: + - IC + formattype: 'cssformat' + rs2_val_data: 'gen_sign_dataset(xlen)' + imm_val_data: '[x*8 for x in gen_usign_dataset(6)]' + template: |- + + // $comment + // opcode:$inst; op1:x2; op2:$rs2; op2val:$rs2_val; immval:$imm_val + TEST_STORE($swreg,$testreg,$index,x2,$rs2,$rs2_val,$imm_val,$offset,$inst,0) + +c.beqz: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *c_regs + xlen: [32,64] + std_op: + isa: + - IC + formattype: 'cbformat' + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen)' + imm_val_data: 'list(filter(lambda x: (x >=4 and x<250) or (x<=-4 and x>=-250),[x*2 for x in gen_sign_dataset(8)]))' + template: |- + + // $comment + // opcode:$inst; op1:$rs1; op1val:$rs1_val; immval:$imm_val + TEST_CBRANCH_OP($inst, $testreg, $rs1, $rs1_val, $imm_val, $label, $swreg, $offset) + +c.bnez: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *c_regs + xlen: [32,64] + std_op: + isa: + - IC + formattype: 'cbformat' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen)' + imm_val_data: 'list(filter(lambda x: (x >=4 and x<250) if x>0 else (x<=-4 and x>=-250),[x*2 for x in gen_sign_dataset(8)]))' + template: |- + + // $comment + // opcode: $inst; op1:$rs1; op1val:$rs1_val; immval:$imm_val + TEST_CBRANCH_OP($inst, $testreg, $rs1, $rs1_val, $imm_val, $label, $swreg, $offset) + +c.j: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IC + formattype: 'cjformat' + imm_val_data: 'list(filter(lambda x: (x >=4 and x<2030) if x>0 else (x<=-4 and x> -2030 ),[x*2 for x in gen_sign_dataset(11)]))' + template: |- + + // $comment + // opcode:$inst; immval:$imm_val + TEST_CJ_OP($inst, $testreg, $imm_val, $label, $swreg, $offset) + +c.jal: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IC + formattype: 'cbformat' + imm_val_data: 'list(filter(lambda x: (x >=4 and x<2030) if x>0 else (x<=-4 and x> -2030 ),[x*2 for x in gen_sign_dataset(11)]))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen)' + template: |- + + // $comment + // opcode:$inst; immval:$imm_val + TEST_CJAL_OP($inst, $testreg, $imm_val, $label, $swreg, $offset) + +c.jr: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs_mx0 + xlen: [32,64] + std_op: + isa: + - IC + formattype: 'crformat' + ea_align_data: '[0,1]' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen)' + template: |- + + // $comment + // opcode: c.jr; op1:$rs1 + TEST_CJR_OP($testreg, $rs1, $swreg, $offset) + +c.jalr: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs_mx0 + xlen: [32,64] + std_op: + isa: + - IC + formattype: 'crformat' + ea_align_data: '[0,1]' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen)' + template: |- + + // $comment + // opcode: c.jalr; op1:$rs1 + TEST_CJALR_OP($testreg, $rs1, $swreg, $offset) + diff --git a/riscv-ctg/riscv_ctg/data/inx.yaml b/riscv-ctg/riscv_ctg/data/inx.yaml new file mode 100644 index 000000000..867e6a914 --- /dev/null +++ b/riscv-ctg/riscv_ctg/data/inx.yaml @@ -0,0 +1,1530 @@ +# See LICENSE.incore for details +# IITM Changes +# This new inx.yaml file handles all of the z*inx extensions +# ======= +fadd.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zfinx + - I_Zdinx + flen: [32,64] + std_op: + formattype: 'rformat' + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; fcsr: $fcsr; + correctval:$correctval; testreg:$testreg + */ + TEST_FPRR_OP($inst, $rd, $rs1, $rs2, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fadd.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zdinx + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *pair_regs + rs2_op_data: *pair_regs + rd_op_data: *pair_regs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; fcsr: $fcsr; + correctval:$correctval; testreg:$testreg + */ + TEST_FPRR_OP($inst, $rd, $rs1, $rs2, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fsub.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zfinx + - I_Zdinx + flen: [32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; fcsr: $fcsr; + correctval:$correctval; testreg:$testreg + */ + TEST_FPRR_OP($inst, $rd, $rs1, $rs2, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fsub.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zdinx + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *pair_regs + rs2_op_data: *pair_regs + rd_op_data: *pair_regs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; fcsr: $fcsr; + correctval:$correctval; testreg:$testreg + */ + TEST_FPRR_OP($inst, $rd, $rs1, $rs2, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fmul.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zfinx + - I_Zdinx + flen: [32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; fcsr: $fcsr; + correctval:$correctval; testreg:$testreg + */ + TEST_FPRR_OP($inst, $rd, $rs1, $rs2, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fmul.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zdinx + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *pair_regs + rs2_op_data: *pair_regs + rd_op_data: *pair_regs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; fcsr: $fcsr; + correctval:$correctval; testreg:$testreg + */ + TEST_FPRR_OP($inst, $rd, $rs1, $rs2, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fdiv.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zfinx + - I_Zdinx + flen: [32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; fcsr: $fcsr; + correctval:$correctval; testreg:$testreg + */ + TEST_FPRR_OP($inst, $rd, $rs1, $rs2, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fdiv.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zdinx + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *pair_regs + rs2_op_data: *pair_regs + rd_op_data: *pair_regs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; fcsr: $fcsr; + correctval:$correctval; testreg:$testreg + */ + TEST_FPRR_OP($inst, $rd, $rs1, $rs2, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fsqrt.s: + sig: + stride: 1 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zfinx + - I_Zdinx + flen: [32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:$correctval; testreg:$testreg; + fcsr_val: $fcsr */ + TEST_FPSR_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fsqrt.d: + sig: + stride: 1 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/4' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zdinx + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *pair_regs + rd_op_data: *pair_regs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:$correctval; testreg:$testreg; + fcsr_val: $fcsr */ + TEST_FPSR_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fmadd.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 3 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zfinx + - I_Zdinx + flen: [32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'r4format' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rs3_op_data: *all_regs + rd_op_data: *all_regs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; op3:$rs3; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + op3val:$rs3_val; valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; + testreg:$testreg; fcsr_val:$fcsr */ + TEST_FPR4_OP($inst, $rd, $rs1, $rs2, $rs3, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fmadd.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 3 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zdinx + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'r4format' + rs1_op_data: *pair_regs + rs2_op_data: *pair_regs + rs3_op_data: *pair_regs + rd_op_data: *pair_regs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; op3:$rs3; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + op3val:$rs3_val; valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; + testreg:$testreg; fcsr_val:$fcsr */ + TEST_FPR4_OP($inst, $rd, $rs1, $rs2, $rs3, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fmsub.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 3 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zfinx + - I_Zdinx + flen: [32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'r4format' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rs3_op_data: *all_regs + rd_op_data: *all_regs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; op3:$rs3; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + op3val:$rs3_val; valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; + testreg:$testreg; fcsr_val:$fcsr */ + TEST_FPR4_OP($inst, $rd, $rs1, $rs2, $rs3, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fmsub.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 3 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zdinx + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'r4format' + rs1_op_data: *pair_regs + rs2_op_data: *pair_regs + rs3_op_data: *pair_regs + rd_op_data: *pair_regs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; op3:$rs3; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + op3val:$rs3_val; valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; + testreg:$testreg; fcsr_val:$fcsr */ + TEST_FPR4_OP($inst, $rd, $rs1, $rs2, $rs3, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fnmadd.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 3 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zfinx + - I_Zdinx + flen: [32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'r4format' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rs3_op_data: *all_regs + rd_op_data: *all_regs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; op3:$rs3; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + op3val:$rs3_val; valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; + testreg:$testreg; fcsr_val:$fcsr */ + TEST_FPR4_OP($inst, $rd, $rs1, $rs2, $rs3, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fnmadd.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 3 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zdinx + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'r4format' + rs1_op_data: *pair_regs + rs2_op_data: *pair_regs + rs3_op_data: *pair_regs + rd_op_data: *pair_regs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; op3:$rs3; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + op3val:$rs3_val; valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; + testreg:$testreg; fcsr_val:$fcsr */ + TEST_FPR4_OP($inst, $rd, $rs1, $rs2, $rs3, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fnmsub.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 3 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zfinx + - I_Zdinx + flen: [32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'r4format' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rs3_op_data: *all_regs + rd_op_data: *all_regs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; op3:$rs3; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + op3val:$rs3_val; valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; + testreg:$testreg; fcsr_val:$fcsr */ + TEST_FPR4_OP($inst, $rd, $rs1, $rs2, $rs3, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fnmsub.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 3 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zdinx + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'r4format' + rs1_op_data: *pair_regs + rs2_op_data: *pair_regs + rs3_op_data: *pair_regs + rd_op_data: *pair_regs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; op3:$rs3; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + op3val:$rs3_val; valaddr_reg:$valaddr_reg; val_offset:$val_offset; rmval:$rm_val; + testreg:$testreg; fcsr_val:$fcsr */ + TEST_FPR4_OP($inst, $rd, $rs1, $rs2, $rs3, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fsgnj.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zfinx + - I_Zdinx + flen: [32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; fcsr: $fcsr; + correctval:$correctval; testreg:$testreg + */ + TEST_FPRR_OP_NRM($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fsgnj.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zdinx + flen: [64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *pair_regs + rs2_op_data: *pair_regs + rd_op_data: *pair_regs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; fcsr: $fcsr; + correctval:$correctval; testreg:$testreg + */ + TEST_FPRR_OP_NRM($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fsgnjn.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zfinx + - I_Zdinx + flen: [32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; fcsr: $fcsr; + correctval:$correctval; testreg:$testreg + */ + TEST_FPRR_OP_NRM($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fsgnjn.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zdinx + flen: [64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *pair_regs + rs2_op_data: *pair_regs + rd_op_data: *pair_regs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; fcsr: $fcsr; + correctval:$correctval; testreg:$testreg + */ + TEST_FPRR_OP_NRM($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fsgnjx.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zfinx + - I_Zdinx + flen: [32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; fcsr: $fcsr; + correctval:$correctval; testreg:$testreg + */ + TEST_FPRR_OP_NRM($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fsgnjx.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zdinx + flen: [64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *pair_regs + rs2_op_data: *pair_regs + rd_op_data: *pair_regs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; fcsr: $fcsr; + correctval:$correctval; testreg:$testreg + */ + TEST_FPRR_OP_NRM($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fmin.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zfinx + - I_Zdinx + flen: [32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; fcsr: $fcsr; + correctval:$correctval; testreg:$testreg + */ + TEST_FPRR_OP_NRM($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fmin.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zdinx + flen: [64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *pair_regs + rs2_op_data: *pair_regs + rd_op_data: *pair_regs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; fcsr: $fcsr; + correctval:$correctval; testreg:$testreg + */ + TEST_FPRR_OP_NRM($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fmax.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zfinx + - I_Zdinx + flen: [32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; fcsr: $fcsr; + correctval:$correctval; testreg:$testreg + */ + TEST_FPRR_OP_NRM($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fmax.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zdinx + flen: [64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *pair_regs + rs2_op_data: *pair_regs + rd_op_data: *pair_regs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; fcsr: $fcsr; + correctval:$correctval; testreg:$testreg + */ + TEST_FPRR_OP_NRM($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +feq.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zfinx + - I_Zdinx + flen: [32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; correctval:$correctval; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FCMP_OP($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +feq.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zdinx + flen: [64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *pair_regs + rs2_op_data: *pair_regs + rd_op_data: *pair_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; correctval:$correctval; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FCMP_OP($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +flt.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zfinx + - I_Zdinx + flen: [32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; correctval:$correctval; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FCMP_OP($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +flt.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zdinx + flen: [64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *pair_regs + rs2_op_data: *pair_regs + rd_op_data: *pair_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; correctval:$correctval; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FCMP_OP($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fle.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zfinx + - I_Zdinx + flen: [32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; correctval:$correctval; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FCMP_OP($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fle.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zdinx + flen: [64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'rformat' + rs1_op_data: *pair_regs + rs2_op_data: *pair_regs + rd_op_data: *pair_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + valaddr_reg:$valaddr_reg; val_offset:$val_offset; correctval:$correctval; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FCMP_OP($inst, $rd, $rs1, $rs2, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fcvt.w.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zfinx + - I_Zdinx + flen: [32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:$correctval; testreg:$testreg; + fcsr_val:$fcsr*/ + TEST_FPID_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fcvt.w.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zdinx + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *pair_regs + rd_op_data: *pair_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:$correctval; testreg:$testreg; + fcsr_val:$fcsr*/ + TEST_FPID_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fcvt.wu.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zfinx + - I_Zdinx + flen: [32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:$correctval; testreg:$testreg; + fcsr_val:$fcsr*/ + TEST_FPID_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fcvt.wu.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zdinx + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *pair_regs + rd_op_data: *pair_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:$correctval; testreg:$testreg; + fcsr_val:$fcsr*/ + TEST_FPID_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fcvt.l.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [64] + isa: + - I_Zdinx + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *pair_regs + rd_op_data: *pair_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:$correctval; testreg:$testreg; + fcsr_val:$fcsr*/ + TEST_FPID_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fcvt.lu.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [64] + isa: + - I_Zdinx + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *pair_regs + rd_op_data: *pair_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:$correctval; testreg:$testreg; + fcsr_val:$fcsr*/ + TEST_FPID_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fcvt.s.d: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zdinx + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *pair_regs + rd_op_data: *pair_regs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:$correctval; testreg:$testreg; + fcsr_val: $fcsr */ + TEST_FPSR_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fcvt.d.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 2 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zdinx + flen: [32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *pair_regs + rd_op_data: *pair_regs + template: |- + + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; correctval:$correctval; testreg:$testreg; + fcsr_val: $fcsr */ + TEST_FPSR_OP_NRM($inst, $rd, $rs1, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fcvt.s.w: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: '4' + val_template: "'.word $val;'" + load_instr: "lw" + xlen: [32,64] + isa: + - I_Zfinx + - I_Zdinx + flen: [32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:$correctval; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FPIO_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fcvt.s.wu: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: '4' + val_template: "'.word $val;'" + load_instr: "LREGWU" + xlen: [32,64] + isa: + - I_Zfinx + - I_Zdinx + flen: [32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:$correctval; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FPIO_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fcvt.d.w: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: '4' + val_template: "'.word $val;'" + load_instr: "lw" + xlen: [32,64] + isa: + - I_Zdinx + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *pair_regs + rd_op_data: *pair_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; correctval:$correctval; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FPIO_OP_NRM($inst, $rd, $rs1, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fcvt.d.wu: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: '4' + val_template: "'.word $val;'" + load_instr: "LREGWU" + xlen: [32,64] + isa: + - I_Zdinx + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *pair_regs + rd_op_data: *pair_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; correctval:$correctval; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FPIO_OP_NRM($inst, $rd, $rs1, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fcvt.d.l: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: '8' + val_template: "'.dword $val;'" + load_instr: "ld" + xlen: [64] + isa: + - I_Zdinx + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *pair_regs + rd_op_data: *pair_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:$correctval; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FPIO_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fcvt.d.lu: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: '8' + val_template: "'.dword $val;'" + load_instr: "ld" + xlen: [64] + isa: + - I_Zdinx + flen: [64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *pair_regs + rd_op_data: *pair_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:$correctval; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FPIO_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fmv.d.x: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: '8' + val_template: "'.dword $val;'" + load_instr: "ld" + xlen: [64] + isa: + - I_Zdinx + flen: [64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; correctval:$correctval; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FPIO_OP_NRM($inst, $rd, $rs1, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fclass.s: + sig: + stride: 1 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32,64] + isa: + - I_Zfinx + - I_Zdinx + flen: [32,64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; correctval:$correctval; testreg:$testreg; + fcsr_val:$fcsr*/ + TEST_FPID_OP_NRM($inst, $rd, $rs1, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +fclass.d: + sig: + stride: 1 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [32, 64] + isa: + - I_Zdinx + flen: [64] + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *pair_regs + rd_op_data: *pair_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; correctval:$correctval; testreg:$testreg; + fcsr_val:$fcsr*/ + TEST_FPID_OP_NRM($inst, $rd, $rs1, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg) + +# The val nodes are present in the fmem ops right now as a hack to force allocation of flagreg. Once +# anxilliary registers are moved to their own functions, this can be removed. + +fcvt.l.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/4' + val_template: "'NAN_BOXED($val,64,FLEN)'" + load_instr: "LREG" + xlen: [64] + std_op: + isa: + - I_Zfinx + - I_Zdinx + flen: [32,64] + rm_val_data: '[0,1,2,3,4,7]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + formattype: 'fsrformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:$correctval; testreg:$testreg; + fcsr_val:$fcsr*/ + TEST_FPID_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fcvt.lu.s: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: 'FLEN/8' + val_template: "'NAN_BOXED($val,$width,FLEN)'" + load_instr: "LREG" + xlen: [64] + isa: + - I_Zfinx + - I_Zdinx + flen: [32,64] + rm_val_data: '[0,1,2,3,4,7]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:$correctval; testreg:$testreg; + fcsr_val:$fcsr*/ + TEST_FPID_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fcvt.s.l: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: '8' + val_template: "'.dword $val;'" + load_instr: "ld" + xlen: [64] + isa: + - I_Zfinx + - I_Zdinx + std_op: + flen: [32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + formattype: 'fsrformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:$correctval; testreg:$testreg; + fcsr_val: $fcsr*/ + TEST_FPIO_OP($inst, $rd, $rs1, $rm_val, $fcsr, $correctval, $valaddr_reg, $val_offset, $flagreg, $swreg, $testreg,$load_instr) + +fcvt.s.lu: + sig: + stride: 2 + sz: 'SIGALIGN' + val: + stride: 1 + sz: '8' + val_template: "'.dword $val;'" + load_instr: "ld" + xlen: [64] + isa: + - I_Zfinx + - I_Zdinxz + flen: [32,64] + rm_val_data: '[7,0,1,2,3,4]' + fcsr_data: '[x<<5|y for x,y in itertools.product([0,1,2,3,4],range(0,2**5))]' + std_op: + formattype: 'fsrformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + template: |- + // $comment + /* opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; valaddr_reg:$valaddr_reg; + val_offset:$val_offset; rmval:$rm_val; correctval:$correctval; testreg:$testreg; + fcsr_val: $fcsr*/ \ No newline at end of file diff --git a/riscv-ctg/riscv_ctg/data/template.yaml b/riscv-ctg/riscv_ctg/data/template.yaml new file mode 100644 index 000000000..d1f87c8df --- /dev/null +++ b/riscv-ctg/riscv_ctg/data/template.yaml @@ -0,0 +1,12663 @@ +# See LICENSE.incore for details +metadata: + all_regs: &all_regs "['x'+str(x) for x in range(0,32 if 'e' not in base_isa else 16)]" + all_fregs: &all_fregs "['f'+str(x) for x in range(0,32 if 'e' not in base_isa else 16)]" + all_regs_mx0: &all_regs_mx0 "['x'+str(x) for x in range(1,32 if 'e' not in base_isa else 16)]" + c_regs: &c_regs "['x'+str(x) for x in range(8,16)]" + pair_regs: &pair_regs "['x'+str(x) for x in range(2,32 if 'e' not in base_isa else 16, 2 if xlen == 32 else 1)]" + rv32rv64pair_regs: &rv32rv64pair_regs "['x'+str(x) for x in range(2,30 if 'e' not in base_isa else 16, 2)]" + +aes32dsi: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + imm_val_data: 'gen_imm_dataset(ceil(log(xlen,2)))' + xlen: [32] + std_op: + isa: + - IZk + - IZkn + - IZknd + formattype: 'bsformat' + template: |- + + // $comment + // opcode: $inst; rd:$rd; op1:$rs1; op2:$rs2; op1val:$rs1_val; op2val:$rs2_val; immval:$imm_val + TEST_RRI_OP($inst, $rd, $rs1, $rs2, $imm_val, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +aes32dsmi: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + imm_val_data: 'gen_imm_dataset(ceil(log(xlen,2)))' + xlen: [32] + std_op: + isa: + - IZk + - IZkn + - IZknd + formattype: 'bsformat' + template: |- + + // $comment + // opcode: $inst; rd:$rd; op1:$rs1; op2:$rs2; op1val:$rs1_val; op2val:$rs2_val; immval:$imm_val + TEST_RRI_OP($inst, $rd, $rs1, $rs2, $imm_val, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +aes32esi: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + imm_val_data: 'gen_imm_dataset(ceil(log(xlen,2)))' + xlen: [32] + std_op: + isa: + - IZk + - IZkn + - IZkne + formattype: 'bsformat' + template: |- + + // $comment + // opcode: $inst; rd:$rd; op1:$rs1; op2:$rs2; op1val:$rs1_val; op2val:$rs2_val; immval:$imm_val + TEST_RRI_OP($inst, $rd, $rs1, $rs2, $imm_val, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +aes32esmi: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + imm_val_data: 'gen_imm_dataset(ceil(log(xlen,2)))' + xlen: [32] + std_op: + isa: + - IZk + - IZkn + - IZkne + formattype: 'bsformat' + template: |- + + // $comment + // opcode: $inst; rd:$rd; op1:$rs1; op2:$rs2; op1val:$rs1_val; op2val:$rs2_val; immval:$imm_val + TEST_RRI_OP($inst, $rd, $rs1, $rs2, $imm_val, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +sm4ed: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + imm_val_data: 'gen_imm_dataset(ceil(log(xlen,2)))' + xlen: [32,64] + std_op: + isa: + - IZks + - IZksed + formattype: 'bsformat' + template: |- + + // $comment + // opcode: $inst; rd:$rd; op1:$rs1; op2:$rs2; op1val:$rs1_val; op2val:$rs2_val; immval:$imm_val + TEST_RRI_OP($inst, $rd, $rs1, $rs2, $imm_val, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +sm4ks: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + imm_val_data: 'gen_imm_dataset(ceil(log(xlen,2)))' + xlen: [32,64] + std_op: + isa: + - IZks + - IZksed + formattype: 'bsformat' + template: |- + + // $comment + // opcode: $inst; rd:$rd; op1:$rs1; op2:$rs2; op1val:$rs1_val; op2val:$rs2_val; immval:$imm_val + TEST_RRI_OP($inst, $rd, $rs1, $rs2, $imm_val, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +sha256sig0: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZk + - IZkn + - IZknh + formattype: 'kformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + LI($rs1,$rs1_val) + sha256sig0 $rd, $rs1 + SREG $rd, $offset($swreg) + RVMODEL_IO_ASSERT_GPR_EQ($testreg, $rd, $correctval) + +sha256sig1: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZk + - IZkn + - IZknh + formattype: 'kformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + LI($rs1,$rs1_val) + sha256sig1 $rd, $rs1 + SREG $rd, $offset($swreg) + RVMODEL_IO_ASSERT_GPR_EQ($testreg, $rd, $correctval) + +sha256sum0: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZk + - IZkn + - IZknh + formattype: 'kformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + LI($rs1,$rs1_val) + sha256sum0 $rd, $rs1 + SREG $rd, $offset($swreg) + RVMODEL_IO_ASSERT_GPR_EQ($testreg, $rd, $correctval) + +sha256sum1: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZk + - IZkn + - IZknh + formattype: 'kformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + LI($rs1,$rs1_val) + sha256sum1 $rd, $rs1 + SREG $rd, $offset($swreg) + RVMODEL_IO_ASSERT_GPR_EQ($testreg, $rd, $correctval) + +sm3p0: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZks + - IZksh + formattype: 'kformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + LI($rs1,$rs1_val) + sm3p0 $rd, $rs1 + SREG $rd, $offset($swreg) + RVMODEL_IO_ASSERT_GPR_EQ($testreg, $rd, $correctval) + +sm3p1: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZks + - IZksh + formattype: 'kformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + LI($rs1,$rs1_val) + sm3p1 $rd, $rs1 + SREG $rd, $offset($swreg) + RVMODEL_IO_ASSERT_GPR_EQ($testreg, $rd, $correctval) + +sha512sig0h: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32] + std_op: + isa: + - IZk + - IZkn + - IZknh + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +sha512sig0l: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32] + std_op: + isa: + - IZk + - IZkn + - IZknh + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +sha512sig1h: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32] + std_op: + isa: + - IZk + - IZkn + - IZknh + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +sha512sig1l: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32] + std_op: + isa: + - IZk + - IZkn + - IZknh + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +sha512sum0r: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32] + std_op: + isa: + - IZk + - IZkn + - IZknh + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +sha512sum1r: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32] + std_op: + isa: + - IZk + - IZkn + - IZknh + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +rol: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + operation: 'hex((rs1_val << (rs2_val%xlen)) & (2**(xlen)-1))' + isa: + - IZbb + - IZbkb + - IZk + - IZkn + - IZks + - IB + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +rev.b: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: grevi + isa: + - I + formattype: 'kformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + LI($rs1,$rs1_val) + grevi $rd, $rs1, 7 + SREG $rd, $offset($swreg) + RVMODEL_IO_ASSERT_GPR_EQ($testreg, $rd, $correctval) + +zip: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32] + std_op: shfli + isa: + - IZk + - IZbkb + - IZkn + - IZks + formattype: 'kformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + LI($rs1,$rs1_val) + zip $rd, $rs1 + SREG $rd, $offset($swreg) + RVMODEL_IO_ASSERT_GPR_EQ($testreg, $rd, $correctval) + +unzip: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32] + std_op: unshfli + isa: + - IZk + - IZbkb + - IZkn + - IZks + formattype: 'kformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + LI($rs1,$rs1_val) + unzip $rd, $rs1 + SREG $rd, $offset($swreg) + RVMODEL_IO_ASSERT_GPR_EQ($testreg, $rd, $correctval) + +pack: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZk + - IZbkb + - IZkn + - IZks + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +packu: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - I + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +packh: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZk + - IZbkb + - IZkn + - IZks + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +xperm.n: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - I + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +xperm.b: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - I + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +aes64ds: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IZk + - IZkn + - IZknd + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +aes64dsm: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IZk + - IZkn + - IZknd + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +aes64es: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IZk + - IZkn + - IZkne + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +aes64esm: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IZk + - IZkn + - IZkne + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +aes64ks1i: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IZk + - IZkn + - IZknd + - IZkne + formattype: 'iformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + imm_val_data: 'gen_usign_dataset(ceil(log(xlen,2)))' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +aes64ks2: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IZk + - IZkn + - IZknd + - IZkne + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +sha512sig0: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IZk + - IZkn + - IZknh + formattype: 'kformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + LI($rs1,$rs1_val) + sha512sig0 $rd, $rs1 + SREG $rd, $offset($swreg) + RVMODEL_IO_ASSERT_GPR_EQ($testreg, $rd, $correctval) + +sha512sig1: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IZk + - IZkn + - IZknh + formattype: 'kformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + LI($rs1,$rs1_val) + sha512sig1 $rd, $rs1 + SREG $rd, $offset($swreg) + RVMODEL_IO_ASSERT_GPR_EQ($testreg, $rd, $correctval) + +sha512sum0: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IZk + - IZkn + - IZknh + formattype: 'kformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + LI($rs1,$rs1_val) + sha512sum0 $rd, $rs1 + SREG $rd, $offset($swreg) + RVMODEL_IO_ASSERT_GPR_EQ($testreg, $rd, $correctval) + +sha512sum1: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IZk + - IZkn + - IZknh + formattype: 'kformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + LI($rs1,$rs1_val) + sha512sum1 $rd, $rs1 + SREG $rd, $offset($swreg) + RVMODEL_IO_ASSERT_GPR_EQ($testreg, $rd, $correctval) + +aes64im: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IZk + - IZkn + - IZknd + formattype: 'kformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + LI($rs1,$rs1_val) + aes64im $rd, $rs1 + SREG $rd, $offset($swreg) + RVMODEL_IO_ASSERT_GPR_EQ($testreg, $rd, $correctval) + +rolw: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IZbb + - IZbkb + - IZk + - IZkn + - IZks + - IB + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +rev8.w: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: grevi + isa: + - I + formattype: 'kformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + LI($rs1,$rs1_val) + grevi $rd, $rs1, 24 + SREG $rd, $offset($swreg) + RVMODEL_IO_ASSERT_GPR_EQ($testreg, $rd, $correctval) + +packw: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IZk + - IZbkb + - IZkn + - IZks + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +packuw: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - I + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +add.uw: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IZba + - IB + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_bitmanip_dataset(xlen,False)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_bitmanip_dataset(xlen,False)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +sh1add: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZba + - IB + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen) + gen_bitmanip_dataset(xlen,True)' + rs2_val_data: 'gen_sign_dataset(xlen) + gen_bitmanip_dataset(xlen,True)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +sh1add.uw: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IZba + - IB + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_usign_dataset(xlen) + gen_bitmanip_dataset(xlen,False)' + rs2_val_data: 'gen_usign_dataset(xlen) + gen_bitmanip_dataset(xlen,False)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +sh2add: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZba + - IB + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_bitmanip_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_bitmanip_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +sh2add.uw: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IZba + - IB + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_usign_dataset(xlen) + gen_bitmanip_dataset(xlen,False)' + rs2_val_data: 'gen_usign_dataset(xlen) + gen_bitmanip_dataset(xlen,False)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +sh3add: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZba + - IB + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_bitmanip_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_bitmanip_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +sh3add.uw: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IZba + - IB + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_usign_dataset(xlen) + gen_bitmanip_dataset(xlen,False)' + rs2_val_data: 'gen_usign_dataset(xlen) + gen_bitmanip_dataset(xlen,False)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +slli.uw: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IZba + - IB + formattype: 'iformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + operation: 'hex(sign_extend((rs1_val << imm_val) , 32))' + rs1_val_data: 'gen_usign_dataset(xlen)+ gen_bitmanip_dataset(xlen,False)' + imm_val_data: 'gen_usign_dataset(5)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +andn: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZbb + - IZbkb + - IZk + - IZkn + - IZks + - IB + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + operation: 'hex((rs1_val & rs2_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_usign_dataset(xlen) + gen_bitmanip_dataset(xlen,False)' + rs2_val_data: 'gen_usign_dataset(xlen) + gen_bitmanip_dataset(xlen,False)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +# 3.1.1. 16-bit Addition & Subtraction Instructions + +add16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +radd16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +uradd16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_usign_dataset(16)' + rs1_h1_val_data: 'gen_usign_dataset(16)' + rs1_h2_val_data: 'gen_usign_dataset(16)' + rs1_h3_val_data: 'gen_usign_dataset(16)' + rs2_h0_val_data: 'gen_usign_dataset(16)' + rs2_h1_val_data: 'gen_usign_dataset(16)' + rs2_h2_val_data: 'gen_usign_dataset(16)' + rs2_h3_val_data: 'gen_usign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +kadd16: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +ukadd16: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_usign_dataset(16)' + rs1_h1_val_data: 'gen_usign_dataset(16)' + rs1_h2_val_data: 'gen_usign_dataset(16)' + rs1_h3_val_data: 'gen_usign_dataset(16)' + rs2_h0_val_data: 'gen_usign_dataset(16)' + rs2_h1_val_data: 'gen_usign_dataset(16)' + rs2_h2_val_data: 'gen_usign_dataset(16)' + rs2_h3_val_data: 'gen_usign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +sub16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + + +rsub16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + + +ursub16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_usign_dataset(16)' + rs1_h1_val_data: 'gen_usign_dataset(16)' + rs1_h2_val_data: 'gen_usign_dataset(16)' + rs1_h3_val_data: 'gen_usign_dataset(16)' + rs2_h0_val_data: 'gen_usign_dataset(16)' + rs2_h1_val_data: 'gen_usign_dataset(16)' + rs2_h2_val_data: 'gen_usign_dataset(16)' + rs2_h3_val_data: 'gen_usign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +ksub16: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +uksub16: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_usign_dataset(16)' + rs1_h1_val_data: 'gen_usign_dataset(16)' + rs1_h2_val_data: 'gen_usign_dataset(16)' + rs1_h3_val_data: 'gen_usign_dataset(16)' + rs2_h0_val_data: 'gen_usign_dataset(16)' + rs2_h1_val_data: 'gen_usign_dataset(16)' + rs2_h2_val_data: 'gen_usign_dataset(16)' + rs2_h3_val_data: 'gen_usign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +cras16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +rcras16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + + +urcras16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_usign_dataset(16)' + rs1_h1_val_data: 'gen_usign_dataset(16)' + rs1_h2_val_data: 'gen_usign_dataset(16)' + rs1_h3_val_data: 'gen_usign_dataset(16)' + rs2_h0_val_data: 'gen_usign_dataset(16)' + rs2_h1_val_data: 'gen_usign_dataset(16)' + rs2_h2_val_data: 'gen_usign_dataset(16)' + rs2_h3_val_data: 'gen_usign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +kcras16: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +clz: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZbb + - IB + formattype: 'kformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_usign_dataset(xlen)+gen_sign_dataset(xlen)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + TEST_RD_OP($inst, $rd, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +clzw: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IZbb + - IB + formattype: 'kformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + TEST_RD_OP($inst, $rd, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +cpop: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZbb + - IB + formattype: 'kformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_usign_dataset(xlen)+gen_sign_dataset(xlen)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + TEST_RD_OP($inst, $rd, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +cpopw: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IZbb + - IB + formattype: 'kformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + TEST_RD_OP($inst, $rd, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +ctz: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZbb + - IB + formattype: 'kformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_usign_dataset(xlen)+gen_sign_dataset(xlen)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + TEST_RD_OP($inst, $rd, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +ctzw: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IZbb + - IB + formattype: 'kformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_usign_dataset(xlen)+gen_sign_dataset(xlen)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + TEST_RD_OP($inst, $rd, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +max: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZbb + - IB + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen) + gen_bitmanip_dataset(xlen,True)' + rs2_val_data: 'gen_sign_dataset(xlen) + gen_bitmanip_dataset(xlen,True)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +ukcras16: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_usign_dataset(16)' + rs1_h1_val_data: 'gen_usign_dataset(16)' + rs1_h2_val_data: 'gen_usign_dataset(16)' + rs1_h3_val_data: 'gen_usign_dataset(16)' + rs2_h0_val_data: 'gen_usign_dataset(16)' + rs2_h1_val_data: 'gen_usign_dataset(16)' + rs2_h2_val_data: 'gen_usign_dataset(16)' + rs2_h3_val_data: 'gen_usign_dataset(16)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +maxu: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZbb + - IB + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_usign_dataset(xlen) + gen_bitmanip_dataset(xlen,False)' + rs2_val_data: 'gen_usign_dataset(xlen) + gen_bitmanip_dataset(xlen,False)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +crsa16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +min: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZbb + - IB + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen) + gen_bitmanip_dataset(xlen,True)' + rs2_val_data: 'gen_sign_dataset(xlen) + gen_bitmanip_dataset(xlen,True)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +rcrsa16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +minu: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZbb + - IB + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_usign_dataset(xlen) + gen_bitmanip_dataset(xlen,False)' + rs2_val_data: 'gen_usign_dataset(xlen) + gen_bitmanip_dataset(xlen,False)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +urcrsa16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_usign_dataset(16)' + rs1_h1_val_data: 'gen_usign_dataset(16)' + rs1_h2_val_data: 'gen_usign_dataset(16)' + rs1_h3_val_data: 'gen_usign_dataset(16)' + rs2_h0_val_data: 'gen_usign_dataset(16)' + rs2_h1_val_data: 'gen_usign_dataset(16)' + rs2_h2_val_data: 'gen_usign_dataset(16)' + rs2_h3_val_data: 'gen_usign_dataset(16)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +kcrsa16: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +orc.b: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: orc.b + isa: + - IZbb + - IB + formattype: 'kformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)+[16909320,33818625,67633410,134283780,72624976414508040,145249888404506625,290483284134592770,576744443617542660]' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + TEST_RD_OP($inst, $rd, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +orn: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZbb + - IZbkb + - IZk + - IZkn + - IZks + - IB + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_usign_dataset(xlen) + gen_bitmanip_dataset(xlen,False)' + rs2_val_data: 'gen_usign_dataset(xlen) + gen_bitmanip_dataset(xlen,False)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +ukcrsa16: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_usign_dataset(16)' + rs1_h1_val_data: 'gen_usign_dataset(16)' + rs1_h2_val_data: 'gen_usign_dataset(16)' + rs1_h3_val_data: 'gen_usign_dataset(16)' + rs2_h0_val_data: 'gen_usign_dataset(16)' + rs2_h1_val_data: 'gen_usign_dataset(16)' + rs2_h2_val_data: 'gen_usign_dataset(16)' + rs2_h3_val_data: 'gen_usign_dataset(16)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +stas16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +rstas16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +rev8: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: grevi + isa: + - IZbb + - IZbkb + - IZk + - IZkn + - IZks + - IB + formattype: 'kformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)+gen_bitmanip_dataset(xlen,False)+[16909320,33818625,67633410,134283780,72624976414508040,145249888404506625,290483284134592770,576744443617542660]' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + LI($rs1,$rs1_val) + rev8 $rd, $rs1 + RVTEST_SIGUPD($swreg,$rd,$offset) + RVMODEL_IO_ASSERT_GPR_EQ($testreg, $rd, $correctval) + + +ror: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZbb + - IZbkb + - IZk + - IZkn + - IZks + - IB + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_usign_dataset(ceil(log(xlen,2)))' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +urstas16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_usign_dataset(16)' + rs1_h1_val_data: 'gen_usign_dataset(16)' + rs1_h2_val_data: 'gen_usign_dataset(16)' + rs1_h3_val_data: 'gen_usign_dataset(16)' + rs2_h0_val_data: 'gen_usign_dataset(16)' + rs2_h1_val_data: 'gen_usign_dataset(16)' + rs2_h2_val_data: 'gen_usign_dataset(16)' + rs2_h3_val_data: 'gen_usign_dataset(16)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +kstas16: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +ukstas16: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_usign_dataset(16)' + rs1_h1_val_data: 'gen_usign_dataset(16)' + rs1_h2_val_data: 'gen_usign_dataset(16)' + rs1_h3_val_data: 'gen_usign_dataset(16)' + rs2_h0_val_data: 'gen_usign_dataset(16)' + rs2_h1_val_data: 'gen_usign_dataset(16)' + rs2_h2_val_data: 'gen_usign_dataset(16)' + rs2_h3_val_data: 'gen_usign_dataset(16)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +rori: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZbb + - IZbkb + - IZk + - IZkn + - IZks + - IB + formattype: 'iformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_usign_dataset(ceil(log(xlen,2)))' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +roriw: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IZbb + - IZbkb + - IZk + - IZkn + - IZks + - IB + formattype: 'iformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_usign_dataset(ceil(log(xlen,2)))' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +rorw: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IZbb + - IZbkb + - IZk + - IZkn + - IZks + - IB + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_sp_dataset(xlen)' + rs2_val_data: 'gen_usign_dataset(ceil(log(xlen,2)))' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +stsa16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +rstsa16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +urstsa16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_usign_dataset(16)' + rs1_h1_val_data: 'gen_usign_dataset(16)' + rs1_h2_val_data: 'gen_usign_dataset(16)' + rs1_h3_val_data: 'gen_usign_dataset(16)' + rs2_h0_val_data: 'gen_usign_dataset(16)' + rs2_h1_val_data: 'gen_usign_dataset(16)' + rs2_h2_val_data: 'gen_usign_dataset(16)' + rs2_h3_val_data: 'gen_usign_dataset(16)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +sext.b: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZbb + - IB + formattype: 'kformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + TEST_RD_OP($inst, $rd, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +sext.h: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZbb + - IB + formattype: 'kformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)+[65408]' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + TEST_RD_OP($inst, $rd, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +xnor: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZbb + - IZbkb + - IZk + - IZkn + - IZks + - IB + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_usign_dataset(xlen)+gen_bitmanip_dataset(xlen,False)' + rs2_val_data: 'gen_usign_dataset(xlen)+gen_bitmanip_dataset(xlen,False)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +kstsa16: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +ukstsa16: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_usign_dataset(16)' + rs1_h1_val_data: 'gen_usign_dataset(16)' + rs1_h2_val_data: 'gen_usign_dataset(16)' + rs1_h3_val_data: 'gen_usign_dataset(16)' + rs2_h0_val_data: 'gen_usign_dataset(16)' + rs2_h1_val_data: 'gen_usign_dataset(16)' + rs2_h2_val_data: 'gen_usign_dataset(16)' + rs2_h3_val_data: 'gen_usign_dataset(16)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +zext.h: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZbb + - IB + formattype: 'kformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_usign_dataset(xlen)+[65408]' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + TEST_RD_OP($inst, $rd, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +clmul: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZbc + - IZbkc + - IZk + - IZkn + - IZks + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + + +# 3.1.2. 8-bit Addition & Subtraction Instructions + +add8: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_sign_dataset(8)' + rs1_b1_val_data: 'gen_sign_dataset(8)' + rs1_b2_val_data: 'gen_sign_dataset(8)' + rs1_b3_val_data: 'gen_sign_dataset(8)' + rs1_b4_val_data: 'gen_sign_dataset(8)' + rs1_b5_val_data: 'gen_sign_dataset(8)' + rs1_b6_val_data: 'gen_sign_dataset(8)' + rs1_b7_val_data: 'gen_sign_dataset(8)' + rs2_b0_val_data: 'gen_sign_dataset(8)' + rs2_b1_val_data: 'gen_sign_dataset(8)' + rs2_b2_val_data: 'gen_sign_dataset(8)' + rs2_b3_val_data: 'gen_sign_dataset(8)' + rs2_b4_val_data: 'gen_sign_dataset(8)' + rs2_b5_val_data: 'gen_sign_dataset(8)' + rs2_b6_val_data: 'gen_sign_dataset(8)' + rs2_b7_val_data: 'gen_sign_dataset(8)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +clmulh: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZbc + - IZbkc + - IZk + - IZkn + - IZks + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + + +radd8: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_sign_dataset(8)' + rs1_b1_val_data: 'gen_sign_dataset(8)' + rs1_b2_val_data: 'gen_sign_dataset(8)' + rs1_b3_val_data: 'gen_sign_dataset(8)' + rs1_b4_val_data: 'gen_sign_dataset(8)' + rs1_b5_val_data: 'gen_sign_dataset(8)' + rs1_b6_val_data: 'gen_sign_dataset(8)' + rs1_b7_val_data: 'gen_sign_dataset(8)' + rs2_b0_val_data: 'gen_sign_dataset(8)' + rs2_b1_val_data: 'gen_sign_dataset(8)' + rs2_b2_val_data: 'gen_sign_dataset(8)' + rs2_b3_val_data: 'gen_sign_dataset(8)' + rs2_b4_val_data: 'gen_sign_dataset(8)' + rs2_b5_val_data: 'gen_sign_dataset(8)' + rs2_b6_val_data: 'gen_sign_dataset(8)' + rs2_b7_val_data: 'gen_sign_dataset(8)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + + +clmulr: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZbc + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +uradd8: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_usign_dataset(8)' + rs1_b1_val_data: 'gen_usign_dataset(8)' + rs1_b2_val_data: 'gen_usign_dataset(8)' + rs1_b3_val_data: 'gen_usign_dataset(8)' + rs1_b4_val_data: 'gen_usign_dataset(8)' + rs1_b5_val_data: 'gen_usign_dataset(8)' + rs1_b6_val_data: 'gen_usign_dataset(8)' + rs1_b7_val_data: 'gen_usign_dataset(8)' + rs2_b0_val_data: 'gen_usign_dataset(8)' + rs2_b1_val_data: 'gen_usign_dataset(8)' + rs2_b2_val_data: 'gen_usign_dataset(8)' + rs2_b3_val_data: 'gen_usign_dataset(8)' + rs2_b4_val_data: 'gen_usign_dataset(8)' + rs2_b5_val_data: 'gen_usign_dataset(8)' + rs2_b6_val_data: 'gen_usign_dataset(8)' + rs2_b7_val_data: 'gen_usign_dataset(8)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +bclr: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZbs + - IB + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'zerotoxlen(xlen)+gen_usign_dataset(xlen)+[-1]' + rs2_val_data: 'zerotoxlen(xlen)+gen_usign_dataset(xlen)+[-1]' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + + +kadd8: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_sign_dataset(8)' + rs1_b1_val_data: 'gen_sign_dataset(8)' + rs1_b2_val_data: 'gen_sign_dataset(8)' + rs1_b3_val_data: 'gen_sign_dataset(8)' + rs1_b4_val_data: 'gen_sign_dataset(8)' + rs1_b5_val_data: 'gen_sign_dataset(8)' + rs1_b6_val_data: 'gen_sign_dataset(8)' + rs1_b7_val_data: 'gen_sign_dataset(8)' + rs2_b0_val_data: 'gen_sign_dataset(8)' + rs2_b1_val_data: 'gen_sign_dataset(8)' + rs2_b2_val_data: 'gen_sign_dataset(8)' + rs2_b3_val_data: 'gen_sign_dataset(8)' + rs2_b4_val_data: 'gen_sign_dataset(8)' + rs2_b5_val_data: 'gen_sign_dataset(8)' + rs2_b6_val_data: 'gen_sign_dataset(8)' + rs2_b7_val_data: 'gen_sign_dataset(8)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +ukadd8: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_usign_dataset(8)' + rs1_b1_val_data: 'gen_usign_dataset(8)' + rs1_b2_val_data: 'gen_usign_dataset(8)' + rs1_b3_val_data: 'gen_usign_dataset(8)' + rs1_b4_val_data: 'gen_usign_dataset(8)' + rs1_b5_val_data: 'gen_usign_dataset(8)' + rs1_b6_val_data: 'gen_usign_dataset(8)' + rs1_b7_val_data: 'gen_usign_dataset(8)' + rs2_b0_val_data: 'gen_usign_dataset(8)' + rs2_b1_val_data: 'gen_usign_dataset(8)' + rs2_b2_val_data: 'gen_usign_dataset(8)' + rs2_b3_val_data: 'gen_usign_dataset(8)' + rs2_b4_val_data: 'gen_usign_dataset(8)' + rs2_b5_val_data: 'gen_usign_dataset(8)' + rs2_b6_val_data: 'gen_usign_dataset(8)' + rs2_b7_val_data: 'gen_usign_dataset(8)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +bclri: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZbs + - IB + formattype: 'iformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'zerotoxlen(xlen)+[-1]' + imm_val_data: 'gen_imm_dataset(ceil(log(xlen,2)))' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +bext: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZbs + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'zerotoxlen(xlen)+gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'zerotoxlen(xlen)+gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +sub8: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_sign_dataset(8)' + rs1_b1_val_data: 'gen_sign_dataset(8)' + rs1_b2_val_data: 'gen_sign_dataset(8)' + rs1_b3_val_data: 'gen_sign_dataset(8)' + rs1_b4_val_data: 'gen_sign_dataset(8)' + rs1_b5_val_data: 'gen_sign_dataset(8)' + rs1_b6_val_data: 'gen_sign_dataset(8)' + rs1_b7_val_data: 'gen_sign_dataset(8)' + rs2_b0_val_data: 'gen_sign_dataset(8)' + rs2_b1_val_data: 'gen_sign_dataset(8)' + rs2_b2_val_data: 'gen_sign_dataset(8)' + rs2_b3_val_data: 'gen_sign_dataset(8)' + rs2_b4_val_data: 'gen_sign_dataset(8)' + rs2_b5_val_data: 'gen_sign_dataset(8)' + rs2_b6_val_data: 'gen_sign_dataset(8)' + rs2_b7_val_data: 'gen_sign_dataset(8)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +rsub8: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_sign_dataset(8)' + rs1_b1_val_data: 'gen_sign_dataset(8)' + rs1_b2_val_data: 'gen_sign_dataset(8)' + rs1_b3_val_data: 'gen_sign_dataset(8)' + rs1_b4_val_data: 'gen_sign_dataset(8)' + rs1_b5_val_data: 'gen_sign_dataset(8)' + rs1_b6_val_data: 'gen_sign_dataset(8)' + rs1_b7_val_data: 'gen_sign_dataset(8)' + rs2_b0_val_data: 'gen_sign_dataset(8)' + rs2_b1_val_data: 'gen_sign_dataset(8)' + rs2_b2_val_data: 'gen_sign_dataset(8)' + rs2_b3_val_data: 'gen_sign_dataset(8)' + rs2_b4_val_data: 'gen_sign_dataset(8)' + rs2_b5_val_data: 'gen_sign_dataset(8)' + rs2_b6_val_data: 'gen_sign_dataset(8)' + rs2_b7_val_data: 'gen_sign_dataset(8)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + + +bexti: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZbs + - IB + formattype: 'iformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'zerotoxlen(xlen)+gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + imm_val_data: 'gen_imm_dataset(ceil(log(xlen,2)))' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +binv: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZbs + - IB + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'zerotoxlen(xlen)+gen_usign_dataset(xlen)+gen_sign_dataset(xlen)' + rs2_val_data: 'zerotoxlen(xlen)+gen_usign_dataset(xlen)+gen_sign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + + +ursub8: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_usign_dataset(8)' + rs1_b1_val_data: 'gen_usign_dataset(8)' + rs1_b2_val_data: 'gen_usign_dataset(8)' + rs1_b3_val_data: 'gen_usign_dataset(8)' + rs1_b4_val_data: 'gen_usign_dataset(8)' + rs1_b5_val_data: 'gen_usign_dataset(8)' + rs1_b6_val_data: 'gen_usign_dataset(8)' + rs1_b7_val_data: 'gen_usign_dataset(8)' + rs2_b0_val_data: 'gen_usign_dataset(8)' + rs2_b1_val_data: 'gen_usign_dataset(8)' + rs2_b2_val_data: 'gen_usign_dataset(8)' + rs2_b3_val_data: 'gen_usign_dataset(8)' + rs2_b4_val_data: 'gen_usign_dataset(8)' + rs2_b5_val_data: 'gen_usign_dataset(8)' + rs2_b6_val_data: 'gen_usign_dataset(8)' + rs2_b7_val_data: 'gen_usign_dataset(8)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + + +ksub8: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_sign_dataset(8)' + rs1_b1_val_data: 'gen_sign_dataset(8)' + rs1_b2_val_data: 'gen_sign_dataset(8)' + rs1_b3_val_data: 'gen_sign_dataset(8)' + rs1_b4_val_data: 'gen_sign_dataset(8)' + rs1_b5_val_data: 'gen_sign_dataset(8)' + rs1_b6_val_data: 'gen_sign_dataset(8)' + rs1_b7_val_data: 'gen_sign_dataset(8)' + rs2_b0_val_data: 'gen_sign_dataset(8)' + rs2_b1_val_data: 'gen_sign_dataset(8)' + rs2_b2_val_data: 'gen_sign_dataset(8)' + rs2_b3_val_data: 'gen_sign_dataset(8)' + rs2_b4_val_data: 'gen_sign_dataset(8)' + rs2_b5_val_data: 'gen_sign_dataset(8)' + rs2_b6_val_data: 'gen_sign_dataset(8)' + rs2_b7_val_data: 'gen_sign_dataset(8)' + template: |- + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + + +binvi: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZbs + - IB + formattype: 'iformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'zerotoxlen(xlen)+gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + imm_val_data: 'gen_imm_dataset(ceil(log(xlen,2)))' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +bset: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZbs + - IB + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'zerotoxlen(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'zerotoxlen(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +uksub8: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_usign_dataset(8)' + rs1_b1_val_data: 'gen_usign_dataset(8)' + rs1_b2_val_data: 'gen_usign_dataset(8)' + rs1_b3_val_data: 'gen_usign_dataset(8)' + rs1_b4_val_data: 'gen_usign_dataset(8)' + rs1_b5_val_data: 'gen_usign_dataset(8)' + rs1_b6_val_data: 'gen_usign_dataset(8)' + rs1_b7_val_data: 'gen_usign_dataset(8)' + rs2_b0_val_data: 'gen_usign_dataset(8)' + rs2_b1_val_data: 'gen_usign_dataset(8)' + rs2_b2_val_data: 'gen_usign_dataset(8)' + rs2_b3_val_data: 'gen_usign_dataset(8)' + rs2_b4_val_data: 'gen_usign_dataset(8)' + rs2_b5_val_data: 'gen_usign_dataset(8)' + rs2_b6_val_data: 'gen_usign_dataset(8)' + rs2_b7_val_data: 'gen_usign_dataset(8)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +# 3.1.3. 16-bit Shift Instructions + +sra16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'pshrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_val_data: 'gen_usign_dataset(ceil(log(16,2)))' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +srai16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phriformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + imm_val_data: 'gen_imm_dataset(4)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +sra16.u: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'pshrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_val_data: 'gen_usign_dataset(ceil(log(16,2)))' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +srai16.u: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phriformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + imm_val_data: 'gen_imm_dataset(4)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +srl16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'pshrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_usign_dataset(16)' + rs1_h1_val_data: 'gen_usign_dataset(16)' + rs1_h2_val_data: 'gen_usign_dataset(16)' + rs1_h3_val_data: 'gen_usign_dataset(16)' + rs2_val_data: 'gen_usign_dataset(ceil(log(16,2)))' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +srli16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phriformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_usign_dataset(16)' + rs1_h1_val_data: 'gen_usign_dataset(16)' + rs1_h2_val_data: 'gen_usign_dataset(16)' + rs1_h3_val_data: 'gen_usign_dataset(16)' + imm_val_data: 'gen_imm_dataset(4)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +srl16.u: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'pshrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_usign_dataset(16)' + rs1_h1_val_data: 'gen_usign_dataset(16)' + rs1_h2_val_data: 'gen_usign_dataset(16)' + rs1_h3_val_data: 'gen_usign_dataset(16)' + rs2_val_data: 'gen_usign_dataset(ceil(log(16,2)))' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +srli16.u: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phriformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_usign_dataset(16)' + rs1_h1_val_data: 'gen_usign_dataset(16)' + rs1_h2_val_data: 'gen_usign_dataset(16)' + rs1_h3_val_data: 'gen_usign_dataset(16)' + imm_val_data: 'gen_imm_dataset(4)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +sll16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'pshrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_usign_dataset(16)' + rs1_h1_val_data: 'gen_usign_dataset(16)' + rs1_h2_val_data: 'gen_usign_dataset(16)' + rs1_h3_val_data: 'gen_usign_dataset(16)' + rs2_val_data: 'gen_usign_dataset(ceil(log(16,2)))' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +slli16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phriformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_usign_dataset(16)' + rs1_h1_val_data: 'gen_usign_dataset(16)' + rs1_h2_val_data: 'gen_usign_dataset(16)' + rs1_h3_val_data: 'gen_usign_dataset(16)' + imm_val_data: 'gen_imm_dataset(4)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +ksll16: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'pshrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_val_data: 'gen_usign_dataset(ceil(log(16,2)))' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kslli16: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phriformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + imm_val_data: 'gen_imm_dataset(4)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_PKIMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $rs1, $swreg, $offset, $testreg) + +kslra16: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16,xlen + formattype: 'pshrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_val_data: 'gen_sign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kslra16.u: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16,xlen + formattype: 'pshrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_usign_dataset(16)' + rs1_h1_val_data: 'gen_usign_dataset(16)' + rs1_h2_val_data: 'gen_usign_dataset(16)' + rs1_h3_val_data: 'gen_usign_dataset(16)' + rs2_val_data: 'gen_sign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +# 3.1.4. 8-bit Shift Instructions + +sra8: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'psbrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_sign_dataset(8)' + rs1_b1_val_data: 'gen_sign_dataset(8)' + rs1_b2_val_data: 'gen_sign_dataset(8)' + rs1_b3_val_data: 'gen_sign_dataset(8)' + rs1_b4_val_data: 'gen_sign_dataset(8)' + rs1_b5_val_data: 'gen_sign_dataset(8)' + rs1_b6_val_data: 'gen_sign_dataset(8)' + rs1_b7_val_data: 'gen_sign_dataset(8)' + rs2_val_data: 'gen_usign_dataset(ceil(log(8,2)))' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +srai8: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbriformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_sign_dataset(8)' + rs1_b1_val_data: 'gen_sign_dataset(8)' + rs1_b2_val_data: 'gen_sign_dataset(8)' + rs1_b3_val_data: 'gen_sign_dataset(8)' + rs1_b4_val_data: 'gen_sign_dataset(8)' + rs1_b5_val_data: 'gen_sign_dataset(8)' + rs1_b6_val_data: 'gen_sign_dataset(8)' + rs1_b7_val_data: 'gen_sign_dataset(8)' + imm_val_data: 'gen_imm_dataset(3)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +sra8.u: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'psbrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_sign_dataset(8)' + rs1_b1_val_data: 'gen_sign_dataset(8)' + rs1_b2_val_data: 'gen_sign_dataset(8)' + rs1_b3_val_data: 'gen_sign_dataset(8)' + rs1_b4_val_data: 'gen_sign_dataset(8)' + rs1_b5_val_data: 'gen_sign_dataset(8)' + rs1_b6_val_data: 'gen_sign_dataset(8)' + rs1_b7_val_data: 'gen_sign_dataset(8)' + rs2_val_data: 'gen_usign_dataset(ceil(log(8,2)))' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +srai8.u: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbriformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_sign_dataset(8)' + rs1_b1_val_data: 'gen_sign_dataset(8)' + rs1_b2_val_data: 'gen_sign_dataset(8)' + rs1_b3_val_data: 'gen_sign_dataset(8)' + rs1_b4_val_data: 'gen_sign_dataset(8)' + rs1_b5_val_data: 'gen_sign_dataset(8)' + rs1_b6_val_data: 'gen_sign_dataset(8)' + rs1_b7_val_data: 'gen_sign_dataset(8)' + imm_val_data: 'gen_imm_dataset(3)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +srl8: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'psbrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_usign_dataset(8)' + rs1_b1_val_data: 'gen_usign_dataset(8)' + rs1_b2_val_data: 'gen_usign_dataset(8)' + rs1_b3_val_data: 'gen_usign_dataset(8)' + rs1_b4_val_data: 'gen_usign_dataset(8)' + rs1_b5_val_data: 'gen_usign_dataset(8)' + rs1_b6_val_data: 'gen_usign_dataset(8)' + rs1_b7_val_data: 'gen_usign_dataset(8)' + rs2_val_data: 'gen_usign_dataset(ceil(log(8,2)))' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +srli8: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbriformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_usign_dataset(8)' + rs1_b1_val_data: 'gen_usign_dataset(8)' + rs1_b2_val_data: 'gen_usign_dataset(8)' + rs1_b3_val_data: 'gen_usign_dataset(8)' + rs1_b4_val_data: 'gen_usign_dataset(8)' + rs1_b5_val_data: 'gen_usign_dataset(8)' + rs1_b6_val_data: 'gen_usign_dataset(8)' + rs1_b7_val_data: 'gen_usign_dataset(8)' + imm_val_data: 'gen_imm_dataset(3)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +srl8.u: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'psbrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_usign_dataset(8)' + rs1_b1_val_data: 'gen_usign_dataset(8)' + rs1_b2_val_data: 'gen_usign_dataset(8)' + rs1_b3_val_data: 'gen_usign_dataset(8)' + rs1_b4_val_data: 'gen_usign_dataset(8)' + rs1_b5_val_data: 'gen_usign_dataset(8)' + rs1_b6_val_data: 'gen_usign_dataset(8)' + rs1_b7_val_data: 'gen_usign_dataset(8)' + rs2_val_data: 'gen_usign_dataset(ceil(log(8,2)))' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +srli8.u: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbriformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_usign_dataset(8)' + rs1_b1_val_data: 'gen_usign_dataset(8)' + rs1_b2_val_data: 'gen_usign_dataset(8)' + rs1_b3_val_data: 'gen_usign_dataset(8)' + rs1_b4_val_data: 'gen_usign_dataset(8)' + rs1_b5_val_data: 'gen_usign_dataset(8)' + rs1_b6_val_data: 'gen_usign_dataset(8)' + rs1_b7_val_data: 'gen_usign_dataset(8)' + imm_val_data: 'gen_imm_dataset(3)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +sll8: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'psbrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_usign_dataset(8)' + rs1_b1_val_data: 'gen_usign_dataset(8)' + rs1_b2_val_data: 'gen_usign_dataset(8)' + rs1_b3_val_data: 'gen_usign_dataset(8)' + rs1_b4_val_data: 'gen_usign_dataset(8)' + rs1_b5_val_data: 'gen_usign_dataset(8)' + rs1_b6_val_data: 'gen_usign_dataset(8)' + rs1_b7_val_data: 'gen_usign_dataset(8)' + rs2_val_data: 'gen_usign_dataset(ceil(log(8,2)))' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +slli8: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbriformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_usign_dataset(8)' + rs1_b1_val_data: 'gen_usign_dataset(8)' + rs1_b2_val_data: 'gen_usign_dataset(8)' + rs1_b3_val_data: 'gen_usign_dataset(8)' + rs1_b4_val_data: 'gen_usign_dataset(8)' + rs1_b5_val_data: 'gen_usign_dataset(8)' + rs1_b6_val_data: 'gen_usign_dataset(8)' + rs1_b7_val_data: 'gen_usign_dataset(8)' + imm_val_data: 'gen_imm_dataset(3)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +ksll8: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'psbrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_sign_dataset(8)' + rs1_b1_val_data: 'gen_sign_dataset(8)' + rs1_b2_val_data: 'gen_sign_dataset(8)' + rs1_b3_val_data: 'gen_sign_dataset(8)' + rs1_b4_val_data: 'gen_sign_dataset(8)' + rs1_b5_val_data: 'gen_sign_dataset(8)' + rs1_b6_val_data: 'gen_sign_dataset(8)' + rs1_b7_val_data: 'gen_sign_dataset(8)' + rs2_val_data: 'gen_usign_dataset(ceil(log(8,2)))' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kslli8: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbriformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_sign_dataset(8)' + rs1_b1_val_data: 'gen_sign_dataset(8)' + rs1_b2_val_data: 'gen_sign_dataset(8)' + rs1_b3_val_data: 'gen_sign_dataset(8)' + rs1_b4_val_data: 'gen_sign_dataset(8)' + rs1_b5_val_data: 'gen_sign_dataset(8)' + rs1_b6_val_data: 'gen_sign_dataset(8)' + rs1_b7_val_data: 'gen_sign_dataset(8)' + imm_val_data: 'gen_imm_dataset(3)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_PKIMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $rs1, $swreg, $offset, $testreg) + +kslra8: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8,xlen + formattype: 'psbrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_sign_dataset(8)' + rs1_b1_val_data: 'gen_sign_dataset(8)' + rs1_b2_val_data: 'gen_sign_dataset(8)' + rs1_b3_val_data: 'gen_sign_dataset(8)' + rs1_b4_val_data: 'gen_sign_dataset(8)' + rs1_b5_val_data: 'gen_sign_dataset(8)' + rs1_b6_val_data: 'gen_sign_dataset(8)' + rs1_b7_val_data: 'gen_sign_dataset(8)' + rs2_val_data: 'gen_sign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kslra8.u: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8,xlen + formattype: 'psbrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_usign_dataset(8)' + rs1_b1_val_data: 'gen_usign_dataset(8)' + rs1_b2_val_data: 'gen_usign_dataset(8)' + rs1_b3_val_data: 'gen_usign_dataset(8)' + rs1_b4_val_data: 'gen_usign_dataset(8)' + rs1_b5_val_data: 'gen_usign_dataset(8)' + rs1_b6_val_data: 'gen_usign_dataset(8)' + rs1_b7_val_data: 'gen_usign_dataset(8)' + rs2_val_data: 'gen_sign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +# 3.1.5. 16-bit Compare Instructions + +cmpeq16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +scmplt16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +scmple16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +ucmplt16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_usign_dataset(16)' + rs1_h1_val_data: 'gen_usign_dataset(16)' + rs1_h2_val_data: 'gen_usign_dataset(16)' + rs1_h3_val_data: 'gen_usign_dataset(16)' + rs2_h0_val_data: 'gen_usign_dataset(16)' + rs2_h1_val_data: 'gen_usign_dataset(16)' + rs2_h2_val_data: 'gen_usign_dataset(16)' + rs2_h3_val_data: 'gen_usign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +ucmple16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_usign_dataset(16)' + rs1_h1_val_data: 'gen_usign_dataset(16)' + rs1_h2_val_data: 'gen_usign_dataset(16)' + rs1_h3_val_data: 'gen_usign_dataset(16)' + rs2_h0_val_data: 'gen_usign_dataset(16)' + rs2_h1_val_data: 'gen_usign_dataset(16)' + rs2_h2_val_data: 'gen_usign_dataset(16)' + rs2_h3_val_data: 'gen_usign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +# 3.1.6. 8-bit Compare Instructions + +cmpeq8: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_sign_dataset(8)' + rs1_b1_val_data: 'gen_sign_dataset(8)' + rs1_b2_val_data: 'gen_sign_dataset(8)' + rs1_b3_val_data: 'gen_sign_dataset(8)' + rs1_b4_val_data: 'gen_sign_dataset(8)' + rs1_b5_val_data: 'gen_sign_dataset(8)' + rs1_b6_val_data: 'gen_sign_dataset(8)' + rs1_b7_val_data: 'gen_sign_dataset(8)' + rs2_b0_val_data: 'gen_sign_dataset(8)' + rs2_b1_val_data: 'gen_sign_dataset(8)' + rs2_b2_val_data: 'gen_sign_dataset(8)' + rs2_b3_val_data: 'gen_sign_dataset(8)' + rs2_b4_val_data: 'gen_sign_dataset(8)' + rs2_b5_val_data: 'gen_sign_dataset(8)' + rs2_b6_val_data: 'gen_sign_dataset(8)' + rs2_b7_val_data: 'gen_sign_dataset(8)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +scmplt8: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_sign_dataset(8)' + rs1_b1_val_data: 'gen_sign_dataset(8)' + rs1_b2_val_data: 'gen_sign_dataset(8)' + rs1_b3_val_data: 'gen_sign_dataset(8)' + rs1_b4_val_data: 'gen_sign_dataset(8)' + rs1_b5_val_data: 'gen_sign_dataset(8)' + rs1_b6_val_data: 'gen_sign_dataset(8)' + rs1_b7_val_data: 'gen_sign_dataset(8)' + rs2_b0_val_data: 'gen_sign_dataset(8)' + rs2_b1_val_data: 'gen_sign_dataset(8)' + rs2_b2_val_data: 'gen_sign_dataset(8)' + rs2_b3_val_data: 'gen_sign_dataset(8)' + rs2_b4_val_data: 'gen_sign_dataset(8)' + rs2_b5_val_data: 'gen_sign_dataset(8)' + rs2_b6_val_data: 'gen_sign_dataset(8)' + rs2_b7_val_data: 'gen_sign_dataset(8)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +scmple8: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_sign_dataset(8)' + rs1_b1_val_data: 'gen_sign_dataset(8)' + rs1_b2_val_data: 'gen_sign_dataset(8)' + rs1_b3_val_data: 'gen_sign_dataset(8)' + rs1_b4_val_data: 'gen_sign_dataset(8)' + rs1_b5_val_data: 'gen_sign_dataset(8)' + rs1_b6_val_data: 'gen_sign_dataset(8)' + rs1_b7_val_data: 'gen_sign_dataset(8)' + rs2_b0_val_data: 'gen_sign_dataset(8)' + rs2_b1_val_data: 'gen_sign_dataset(8)' + rs2_b2_val_data: 'gen_sign_dataset(8)' + rs2_b3_val_data: 'gen_sign_dataset(8)' + rs2_b4_val_data: 'gen_sign_dataset(8)' + rs2_b5_val_data: 'gen_sign_dataset(8)' + rs2_b6_val_data: 'gen_sign_dataset(8)' + rs2_b7_val_data: 'gen_sign_dataset(8)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +ucmplt8: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_usign_dataset(8)' + rs1_b1_val_data: 'gen_usign_dataset(8)' + rs1_b2_val_data: 'gen_usign_dataset(8)' + rs1_b3_val_data: 'gen_usign_dataset(8)' + rs1_b4_val_data: 'gen_usign_dataset(8)' + rs1_b5_val_data: 'gen_usign_dataset(8)' + rs1_b6_val_data: 'gen_usign_dataset(8)' + rs1_b7_val_data: 'gen_usign_dataset(8)' + rs2_b0_val_data: 'gen_usign_dataset(8)' + rs2_b1_val_data: 'gen_usign_dataset(8)' + rs2_b2_val_data: 'gen_usign_dataset(8)' + rs2_b3_val_data: 'gen_usign_dataset(8)' + rs2_b4_val_data: 'gen_usign_dataset(8)' + rs2_b5_val_data: 'gen_usign_dataset(8)' + rs2_b6_val_data: 'gen_usign_dataset(8)' + rs2_b7_val_data: 'gen_usign_dataset(8)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +ucmple8: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_usign_dataset(8)' + rs1_b1_val_data: 'gen_usign_dataset(8)' + rs1_b2_val_data: 'gen_usign_dataset(8)' + rs1_b3_val_data: 'gen_usign_dataset(8)' + rs1_b4_val_data: 'gen_usign_dataset(8)' + rs1_b5_val_data: 'gen_usign_dataset(8)' + rs1_b6_val_data: 'gen_usign_dataset(8)' + rs1_b7_val_data: 'gen_usign_dataset(8)' + rs2_b0_val_data: 'gen_usign_dataset(8)' + rs2_b1_val_data: 'gen_usign_dataset(8)' + rs2_b2_val_data: 'gen_usign_dataset(8)' + rs2_b3_val_data: 'gen_usign_dataset(8)' + rs2_b4_val_data: 'gen_usign_dataset(8)' + rs2_b5_val_data: 'gen_usign_dataset(8)' + rs2_b6_val_data: 'gen_usign_dataset(8)' + rs2_b7_val_data: 'gen_usign_dataset(8)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +# 3.1.7. 16-bit Multiply Instructions + +smul16: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + p64_profile: 'pnn' + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *pair_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_P64_PNN_OP($inst, $rd, $rd_hi, $rs1, $rs2, $correctval, $correctval_hi, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +smulx16: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + p64_profile: 'pnn' + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *pair_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_P64_PNN_OP($inst, $rd, $rd_hi, $rs1, $rs2, $correctval, $correctval_hi, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +umul16: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + p64_profile: 'pnn' + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *pair_regs + rs1_h0_val_data: 'gen_usign_dataset(16)' + rs1_h1_val_data: 'gen_usign_dataset(16)' + rs1_h2_val_data: 'gen_usign_dataset(16)' + rs1_h3_val_data: 'gen_usign_dataset(16)' + rs2_h0_val_data: 'gen_usign_dataset(16)' + rs2_h1_val_data: 'gen_usign_dataset(16)' + rs2_h2_val_data: 'gen_usign_dataset(16)' + rs2_h3_val_data: 'gen_usign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_P64_PNN_OP($inst, $rd, $rd_hi, $rs1, $rs2, $correctval, $correctval_hi, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +umulx16: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + p64_profile: 'pnn' + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *pair_regs + rs1_h0_val_data: 'gen_usign_dataset(16)' + rs1_h1_val_data: 'gen_usign_dataset(16)' + rs1_h2_val_data: 'gen_usign_dataset(16)' + rs1_h3_val_data: 'gen_usign_dataset(16)' + rs2_h0_val_data: 'gen_usign_dataset(16)' + rs2_h1_val_data: 'gen_usign_dataset(16)' + rs2_h2_val_data: 'gen_usign_dataset(16)' + rs2_h3_val_data: 'gen_usign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_P64_PNN_OP($inst, $rd, $rd_hi, $rs1, $rs2, $correctval, $correctval_hi, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +khm16: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +khmx16: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +# 3.1.8. 8-bit Multiply Instructions + +smul8: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + p64_profile: 'pnn' + formattype: 'pbrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *pair_regs + rs1_b0_val_data: 'gen_sign_dataset(8)' + rs1_b1_val_data: 'gen_sign_dataset(8)' + rs1_b2_val_data: 'gen_sign_dataset(8)' + rs1_b3_val_data: 'gen_sign_dataset(8)' + rs1_b4_val_data: 'gen_sign_dataset(8)' + rs1_b5_val_data: 'gen_sign_dataset(8)' + rs1_b6_val_data: 'gen_sign_dataset(8)' + rs1_b7_val_data: 'gen_sign_dataset(8)' + rs2_b0_val_data: 'gen_sign_dataset(8)' + rs2_b1_val_data: 'gen_sign_dataset(8)' + rs2_b2_val_data: 'gen_sign_dataset(8)' + rs2_b3_val_data: 'gen_sign_dataset(8)' + rs2_b4_val_data: 'gen_sign_dataset(8)' + rs2_b5_val_data: 'gen_sign_dataset(8)' + rs2_b6_val_data: 'gen_sign_dataset(8)' + rs2_b7_val_data: 'gen_sign_dataset(8)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_P64_PNN_OP($inst, $rd, $rd_hi, $rs1, $rs2, $correctval, $correctval_hi, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +smulx8: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + p64_profile: 'pnn' + formattype: 'pbrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *pair_regs + rs1_b0_val_data: 'gen_sign_dataset(8)' + rs1_b1_val_data: 'gen_sign_dataset(8)' + rs1_b2_val_data: 'gen_sign_dataset(8)' + rs1_b3_val_data: 'gen_sign_dataset(8)' + rs1_b4_val_data: 'gen_sign_dataset(8)' + rs1_b5_val_data: 'gen_sign_dataset(8)' + rs1_b6_val_data: 'gen_sign_dataset(8)' + rs1_b7_val_data: 'gen_sign_dataset(8)' + rs2_b0_val_data: 'gen_sign_dataset(8)' + rs2_b1_val_data: 'gen_sign_dataset(8)' + rs2_b2_val_data: 'gen_sign_dataset(8)' + rs2_b3_val_data: 'gen_sign_dataset(8)' + rs2_b4_val_data: 'gen_sign_dataset(8)' + rs2_b5_val_data: 'gen_sign_dataset(8)' + rs2_b6_val_data: 'gen_sign_dataset(8)' + rs2_b7_val_data: 'gen_sign_dataset(8)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_P64_PNN_OP($inst, $rd, $rd_hi, $rs1, $rs2, $correctval, $correctval_hi, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +umul8: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + p64_profile: 'pnn' + formattype: 'pbrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *pair_regs + rs1_b0_val_data: 'gen_usign_dataset(8)' + rs1_b1_val_data: 'gen_usign_dataset(8)' + rs1_b2_val_data: 'gen_usign_dataset(8)' + rs1_b3_val_data: 'gen_usign_dataset(8)' + rs1_b4_val_data: 'gen_usign_dataset(8)' + rs1_b5_val_data: 'gen_usign_dataset(8)' + rs1_b6_val_data: 'gen_usign_dataset(8)' + rs1_b7_val_data: 'gen_usign_dataset(8)' + rs2_b0_val_data: 'gen_usign_dataset(8)' + rs2_b1_val_data: 'gen_usign_dataset(8)' + rs2_b2_val_data: 'gen_usign_dataset(8)' + rs2_b3_val_data: 'gen_usign_dataset(8)' + rs2_b4_val_data: 'gen_usign_dataset(8)' + rs2_b5_val_data: 'gen_usign_dataset(8)' + rs2_b6_val_data: 'gen_usign_dataset(8)' + rs2_b7_val_data: 'gen_usign_dataset(8)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_P64_PNN_OP($inst, $rd, $rd_hi, $rs1, $rs2, $correctval, $correctval_hi, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +umulx8: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + p64_profile: 'pnn' + formattype: 'pbrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *pair_regs + rs1_b0_val_data: 'gen_usign_dataset(8)' + rs1_b1_val_data: 'gen_usign_dataset(8)' + rs1_b2_val_data: 'gen_usign_dataset(8)' + rs1_b3_val_data: 'gen_usign_dataset(8)' + rs1_b4_val_data: 'gen_usign_dataset(8)' + rs1_b5_val_data: 'gen_usign_dataset(8)' + rs1_b6_val_data: 'gen_usign_dataset(8)' + rs1_b7_val_data: 'gen_usign_dataset(8)' + rs2_b0_val_data: 'gen_usign_dataset(8)' + rs2_b1_val_data: 'gen_usign_dataset(8)' + rs2_b2_val_data: 'gen_usign_dataset(8)' + rs2_b3_val_data: 'gen_usign_dataset(8)' + rs2_b4_val_data: 'gen_usign_dataset(8)' + rs2_b5_val_data: 'gen_usign_dataset(8)' + rs2_b6_val_data: 'gen_usign_dataset(8)' + rs2_b7_val_data: 'gen_usign_dataset(8)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_P64_PNN_OP($inst, $rd, $rd_hi, $rs1, $rs2, $correctval, $correctval_hi, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +khm8: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_sign_dataset(8)' + rs1_b1_val_data: 'gen_sign_dataset(8)' + rs1_b2_val_data: 'gen_sign_dataset(8)' + rs1_b3_val_data: 'gen_sign_dataset(8)' + rs1_b4_val_data: 'gen_sign_dataset(8)' + rs1_b5_val_data: 'gen_sign_dataset(8)' + rs1_b6_val_data: 'gen_sign_dataset(8)' + rs1_b7_val_data: 'gen_sign_dataset(8)' + rs2_b0_val_data: 'gen_sign_dataset(8)' + rs2_b1_val_data: 'gen_sign_dataset(8)' + rs2_b2_val_data: 'gen_sign_dataset(8)' + rs2_b3_val_data: 'gen_sign_dataset(8)' + rs2_b4_val_data: 'gen_sign_dataset(8)' + rs2_b5_val_data: 'gen_sign_dataset(8)' + rs2_b6_val_data: 'gen_sign_dataset(8)' + rs2_b7_val_data: 'gen_sign_dataset(8)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +khmx8: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_sign_dataset(8)' + rs1_b1_val_data: 'gen_sign_dataset(8)' + rs1_b2_val_data: 'gen_sign_dataset(8)' + rs1_b3_val_data: 'gen_sign_dataset(8)' + rs1_b4_val_data: 'gen_sign_dataset(8)' + rs1_b5_val_data: 'gen_sign_dataset(8)' + rs1_b6_val_data: 'gen_sign_dataset(8)' + rs1_b7_val_data: 'gen_sign_dataset(8)' + rs2_b0_val_data: 'gen_sign_dataset(8)' + rs2_b1_val_data: 'gen_sign_dataset(8)' + rs2_b2_val_data: 'gen_sign_dataset(8)' + rs2_b3_val_data: 'gen_sign_dataset(8)' + rs2_b4_val_data: 'gen_sign_dataset(8)' + rs2_b5_val_data: 'gen_sign_dataset(8)' + rs2_b6_val_data: 'gen_sign_dataset(8)' + rs2_b7_val_data: 'gen_sign_dataset(8)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +# 3.1.9. 16-bit Misc Instructions + +smin16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +umin16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_usign_dataset(16)' + rs1_h1_val_data: 'gen_usign_dataset(16)' + rs1_h2_val_data: 'gen_usign_dataset(16)' + rs1_h3_val_data: 'gen_usign_dataset(16)' + rs2_h0_val_data: 'gen_usign_dataset(16)' + rs2_h1_val_data: 'gen_usign_dataset(16)' + rs2_h2_val_data: 'gen_usign_dataset(16)' + rs2_h3_val_data: 'gen_usign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +smax16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +umax16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_usign_dataset(16)' + rs1_h1_val_data: 'gen_usign_dataset(16)' + rs1_h2_val_data: 'gen_usign_dataset(16)' + rs1_h3_val_data: 'gen_usign_dataset(16)' + rs2_h0_val_data: 'gen_usign_dataset(16)' + rs2_h1_val_data: 'gen_usign_dataset(16)' + rs2_h2_val_data: 'gen_usign_dataset(16)' + rs2_h3_val_data: 'gen_usign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +sclip16: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phriformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + imm_val_data: 'gen_imm_dataset(4)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_PKIMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $rs1, $swreg, $offset, $testreg) + +uclip16: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phriformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_usign_dataset(16)' + rs1_h1_val_data: 'gen_usign_dataset(16)' + rs1_h2_val_data: 'gen_usign_dataset(16)' + rs1_h3_val_data: 'gen_usign_dataset(16)' + imm_val_data: 'gen_imm_dataset(4)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_PKIMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $rs1, $swreg, $offset, $testreg) + +kabs16: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + TEST_PKR_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $rs1, $swreg, $offset, $testreg) + +clrs16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + TEST_RD_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +clz16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_usign_dataset(16)' + rs1_h1_val_data: 'gen_usign_dataset(16)' + rs1_h2_val_data: 'gen_usign_dataset(16)' + rs1_h3_val_data: 'gen_usign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + TEST_RD_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +swap16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_usign_dataset(16)' + rs1_h1_val_data: 'gen_usign_dataset(16)' + rs1_h2_val_data: 'gen_usign_dataset(16)' + rs1_h3_val_data: 'gen_usign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + TEST_RD_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +# 3.1.10. 8-bit Misc Instructions + +smin8: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_sign_dataset(8)' + rs1_b1_val_data: 'gen_sign_dataset(8)' + rs1_b2_val_data: 'gen_sign_dataset(8)' + rs1_b3_val_data: 'gen_sign_dataset(8)' + rs1_b4_val_data: 'gen_sign_dataset(8)' + rs1_b5_val_data: 'gen_sign_dataset(8)' + rs1_b6_val_data: 'gen_sign_dataset(8)' + rs1_b7_val_data: 'gen_sign_dataset(8)' + rs2_b0_val_data: 'gen_sign_dataset(8)' + rs2_b1_val_data: 'gen_sign_dataset(8)' + rs2_b2_val_data: 'gen_sign_dataset(8)' + rs2_b3_val_data: 'gen_sign_dataset(8)' + rs2_b4_val_data: 'gen_sign_dataset(8)' + rs2_b5_val_data: 'gen_sign_dataset(8)' + rs2_b6_val_data: 'gen_sign_dataset(8)' + rs2_b7_val_data: 'gen_sign_dataset(8)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +umin8: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_usign_dataset(8)' + rs1_b1_val_data: 'gen_usign_dataset(8)' + rs1_b2_val_data: 'gen_usign_dataset(8)' + rs1_b3_val_data: 'gen_usign_dataset(8)' + rs1_b4_val_data: 'gen_usign_dataset(8)' + rs1_b5_val_data: 'gen_usign_dataset(8)' + rs1_b6_val_data: 'gen_usign_dataset(8)' + rs1_b7_val_data: 'gen_usign_dataset(8)' + rs2_b0_val_data: 'gen_usign_dataset(8)' + rs2_b1_val_data: 'gen_usign_dataset(8)' + rs2_b2_val_data: 'gen_usign_dataset(8)' + rs2_b3_val_data: 'gen_usign_dataset(8)' + rs2_b4_val_data: 'gen_usign_dataset(8)' + rs2_b5_val_data: 'gen_usign_dataset(8)' + rs2_b6_val_data: 'gen_usign_dataset(8)' + rs2_b7_val_data: 'gen_usign_dataset(8)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +smax8: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_sign_dataset(8)' + rs1_b1_val_data: 'gen_sign_dataset(8)' + rs1_b2_val_data: 'gen_sign_dataset(8)' + rs1_b3_val_data: 'gen_sign_dataset(8)' + rs1_b4_val_data: 'gen_sign_dataset(8)' + rs1_b5_val_data: 'gen_sign_dataset(8)' + rs1_b6_val_data: 'gen_sign_dataset(8)' + rs1_b7_val_data: 'gen_sign_dataset(8)' + rs2_b0_val_data: 'gen_sign_dataset(8)' + rs2_b1_val_data: 'gen_sign_dataset(8)' + rs2_b2_val_data: 'gen_sign_dataset(8)' + rs2_b3_val_data: 'gen_sign_dataset(8)' + rs2_b4_val_data: 'gen_sign_dataset(8)' + rs2_b5_val_data: 'gen_sign_dataset(8)' + rs2_b6_val_data: 'gen_sign_dataset(8)' + rs2_b7_val_data: 'gen_sign_dataset(8)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +umax8: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_usign_dataset(8)' + rs1_b1_val_data: 'gen_usign_dataset(8)' + rs1_b2_val_data: 'gen_usign_dataset(8)' + rs1_b3_val_data: 'gen_usign_dataset(8)' + rs1_b4_val_data: 'gen_usign_dataset(8)' + rs1_b5_val_data: 'gen_usign_dataset(8)' + rs1_b6_val_data: 'gen_usign_dataset(8)' + rs1_b7_val_data: 'gen_usign_dataset(8)' + rs2_b0_val_data: 'gen_usign_dataset(8)' + rs2_b1_val_data: 'gen_usign_dataset(8)' + rs2_b2_val_data: 'gen_usign_dataset(8)' + rs2_b3_val_data: 'gen_usign_dataset(8)' + rs2_b4_val_data: 'gen_usign_dataset(8)' + rs2_b5_val_data: 'gen_usign_dataset(8)' + rs2_b6_val_data: 'gen_usign_dataset(8)' + rs2_b7_val_data: 'gen_usign_dataset(8)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +kabs8: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_sign_dataset(8)' + rs1_b1_val_data: 'gen_sign_dataset(8)' + rs1_b2_val_data: 'gen_sign_dataset(8)' + rs1_b3_val_data: 'gen_sign_dataset(8)' + rs1_b4_val_data: 'gen_sign_dataset(8)' + rs1_b5_val_data: 'gen_sign_dataset(8)' + rs1_b6_val_data: 'gen_sign_dataset(8)' + rs1_b7_val_data: 'gen_sign_dataset(8)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + TEST_PKR_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $rs1, $swreg, $offset, $testreg) + +sclip8: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbriformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_sign_dataset(8)' + rs1_b1_val_data: 'gen_sign_dataset(8)' + rs1_b2_val_data: 'gen_sign_dataset(8)' + rs1_b3_val_data: 'gen_sign_dataset(8)' + rs1_b4_val_data: 'gen_sign_dataset(8)' + rs1_b5_val_data: 'gen_sign_dataset(8)' + rs1_b6_val_data: 'gen_sign_dataset(8)' + rs1_b7_val_data: 'gen_sign_dataset(8)' + imm_val_data: 'gen_imm_dataset(3)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_PKIMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $rs1, $swreg, $offset, $testreg) + +uclip8: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbriformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_usign_dataset(8)' + rs1_b1_val_data: 'gen_usign_dataset(8)' + rs1_b2_val_data: 'gen_usign_dataset(8)' + rs1_b3_val_data: 'gen_usign_dataset(8)' + rs1_b4_val_data: 'gen_usign_dataset(8)' + rs1_b5_val_data: 'gen_usign_dataset(8)' + rs1_b6_val_data: 'gen_usign_dataset(8)' + rs1_b7_val_data: 'gen_usign_dataset(8)' + imm_val_data: 'gen_imm_dataset(3)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_PKIMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $rs1, $swreg, $offset, $testreg) + +clrs8: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_sign_dataset(8)' + rs1_b1_val_data: 'gen_sign_dataset(8)' + rs1_b2_val_data: 'gen_sign_dataset(8)' + rs1_b3_val_data: 'gen_sign_dataset(8)' + rs1_b4_val_data: 'gen_sign_dataset(8)' + rs1_b5_val_data: 'gen_sign_dataset(8)' + rs1_b6_val_data: 'gen_sign_dataset(8)' + rs1_b7_val_data: 'gen_sign_dataset(8)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + TEST_RD_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +clz8: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_usign_dataset(8)' + rs1_b1_val_data: 'gen_usign_dataset(8)' + rs1_b2_val_data: 'gen_usign_dataset(8)' + rs1_b3_val_data: 'gen_usign_dataset(8)' + rs1_b4_val_data: 'gen_usign_dataset(8)' + rs1_b5_val_data: 'gen_usign_dataset(8)' + rs1_b6_val_data: 'gen_usign_dataset(8)' + rs1_b7_val_data: 'gen_usign_dataset(8)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + TEST_RD_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +swap8: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_usign_dataset(8)' + rs1_b1_val_data: 'gen_usign_dataset(8)' + rs1_b2_val_data: 'gen_usign_dataset(8)' + rs1_b3_val_data: 'gen_usign_dataset(8)' + rs1_b4_val_data: 'gen_usign_dataset(8)' + rs1_b5_val_data: 'gen_usign_dataset(8)' + rs1_b6_val_data: 'gen_usign_dataset(8)' + rs1_b7_val_data: 'gen_usign_dataset(8)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + TEST_RD_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +# 3.1.11. 8-bit Unpacking Instructions + +sunpkd810: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_sign_dataset(8)' + rs1_b1_val_data: 'gen_sign_dataset(8)' + rs1_b2_val_data: 'gen_sign_dataset(8)' + rs1_b3_val_data: 'gen_sign_dataset(8)' + rs1_b4_val_data: 'gen_sign_dataset(8)' + rs1_b5_val_data: 'gen_sign_dataset(8)' + rs1_b6_val_data: 'gen_sign_dataset(8)' + rs1_b7_val_data: 'gen_sign_dataset(8)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + TEST_RD_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +sunpkd820: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_sign_dataset(8)' + rs1_b1_val_data: 'gen_sign_dataset(8)' + rs1_b2_val_data: 'gen_sign_dataset(8)' + rs1_b3_val_data: 'gen_sign_dataset(8)' + rs1_b4_val_data: 'gen_sign_dataset(8)' + rs1_b5_val_data: 'gen_sign_dataset(8)' + rs1_b6_val_data: 'gen_sign_dataset(8)' + rs1_b7_val_data: 'gen_sign_dataset(8)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + TEST_RD_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +sunpkd830: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_sign_dataset(8)' + rs1_b1_val_data: 'gen_sign_dataset(8)' + rs1_b2_val_data: 'gen_sign_dataset(8)' + rs1_b3_val_data: 'gen_sign_dataset(8)' + rs1_b4_val_data: 'gen_sign_dataset(8)' + rs1_b5_val_data: 'gen_sign_dataset(8)' + rs1_b6_val_data: 'gen_sign_dataset(8)' + rs1_b7_val_data: 'gen_sign_dataset(8)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + TEST_RD_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +sunpkd831: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_sign_dataset(8)' + rs1_b1_val_data: 'gen_sign_dataset(8)' + rs1_b2_val_data: 'gen_sign_dataset(8)' + rs1_b3_val_data: 'gen_sign_dataset(8)' + rs1_b4_val_data: 'gen_sign_dataset(8)' + rs1_b5_val_data: 'gen_sign_dataset(8)' + rs1_b6_val_data: 'gen_sign_dataset(8)' + rs1_b7_val_data: 'gen_sign_dataset(8)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + TEST_RD_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +sunpkd832: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_sign_dataset(8)' + rs1_b1_val_data: 'gen_sign_dataset(8)' + rs1_b2_val_data: 'gen_sign_dataset(8)' + rs1_b3_val_data: 'gen_sign_dataset(8)' + rs1_b4_val_data: 'gen_sign_dataset(8)' + rs1_b5_val_data: 'gen_sign_dataset(8)' + rs1_b6_val_data: 'gen_sign_dataset(8)' + rs1_b7_val_data: 'gen_sign_dataset(8)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + TEST_RD_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +zunpkd810: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_usign_dataset(8)' + rs1_b1_val_data: 'gen_usign_dataset(8)' + rs1_b2_val_data: 'gen_usign_dataset(8)' + rs1_b3_val_data: 'gen_usign_dataset(8)' + rs1_b4_val_data: 'gen_usign_dataset(8)' + rs1_b5_val_data: 'gen_usign_dataset(8)' + rs1_b6_val_data: 'gen_usign_dataset(8)' + rs1_b7_val_data: 'gen_usign_dataset(8)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + TEST_RD_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +zunpkd820: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_usign_dataset(8)' + rs1_b1_val_data: 'gen_usign_dataset(8)' + rs1_b2_val_data: 'gen_usign_dataset(8)' + rs1_b3_val_data: 'gen_usign_dataset(8)' + rs1_b4_val_data: 'gen_usign_dataset(8)' + rs1_b5_val_data: 'gen_usign_dataset(8)' + rs1_b6_val_data: 'gen_usign_dataset(8)' + rs1_b7_val_data: 'gen_usign_dataset(8)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + TEST_RD_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +zunpkd830: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_usign_dataset(8)' + rs1_b1_val_data: 'gen_usign_dataset(8)' + rs1_b2_val_data: 'gen_usign_dataset(8)' + rs1_b3_val_data: 'gen_usign_dataset(8)' + rs1_b4_val_data: 'gen_usign_dataset(8)' + rs1_b5_val_data: 'gen_usign_dataset(8)' + rs1_b6_val_data: 'gen_usign_dataset(8)' + rs1_b7_val_data: 'gen_usign_dataset(8)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + TEST_RD_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +zunpkd831: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_usign_dataset(8)' + rs1_b1_val_data: 'gen_usign_dataset(8)' + rs1_b2_val_data: 'gen_usign_dataset(8)' + rs1_b3_val_data: 'gen_usign_dataset(8)' + rs1_b4_val_data: 'gen_usign_dataset(8)' + rs1_b5_val_data: 'gen_usign_dataset(8)' + rs1_b6_val_data: 'gen_usign_dataset(8)' + rs1_b7_val_data: 'gen_usign_dataset(8)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + TEST_RD_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +zunpkd832: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_usign_dataset(8)' + rs1_b1_val_data: 'gen_usign_dataset(8)' + rs1_b2_val_data: 'gen_usign_dataset(8)' + rs1_b3_val_data: 'gen_usign_dataset(8)' + rs1_b4_val_data: 'gen_usign_dataset(8)' + rs1_b5_val_data: 'gen_usign_dataset(8)' + rs1_b6_val_data: 'gen_usign_dataset(8)' + rs1_b7_val_data: 'gen_usign_dataset(8)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + TEST_RD_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +# 3.2 Partial-SIMD Data Processing Instructions + +pkbb16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_usign_dataset(16)' + rs1_h1_val_data: 'gen_usign_dataset(16)' + rs1_h2_val_data: 'gen_usign_dataset(16)' + rs1_h3_val_data: 'gen_usign_dataset(16)' + rs2_h0_val_data: 'gen_usign_dataset(16)' + rs2_h1_val_data: 'gen_usign_dataset(16)' + rs2_h2_val_data: 'gen_usign_dataset(16)' + rs2_h3_val_data: 'gen_usign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +pkbt16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_usign_dataset(16)' + rs1_h1_val_data: 'gen_usign_dataset(16)' + rs1_h2_val_data: 'gen_usign_dataset(16)' + rs1_h3_val_data: 'gen_usign_dataset(16)' + rs2_h0_val_data: 'gen_usign_dataset(16)' + rs2_h1_val_data: 'gen_usign_dataset(16)' + rs2_h2_val_data: 'gen_usign_dataset(16)' + rs2_h3_val_data: 'gen_usign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +pktb16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_usign_dataset(16)' + rs1_h1_val_data: 'gen_usign_dataset(16)' + rs1_h2_val_data: 'gen_usign_dataset(16)' + rs1_h3_val_data: 'gen_usign_dataset(16)' + rs2_h0_val_data: 'gen_usign_dataset(16)' + rs2_h1_val_data: 'gen_usign_dataset(16)' + rs2_h2_val_data: 'gen_usign_dataset(16)' + rs2_h3_val_data: 'gen_usign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +pktt16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_usign_dataset(16)' + rs1_h1_val_data: 'gen_usign_dataset(16)' + rs1_h2_val_data: 'gen_usign_dataset(16)' + rs1_h3_val_data: 'gen_usign_dataset(16)' + rs2_h0_val_data: 'gen_usign_dataset(16)' + rs2_h1_val_data: 'gen_usign_dataset(16)' + rs2_h2_val_data: 'gen_usign_dataset(16)' + rs2_h3_val_data: 'gen_usign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) +# 3.2.2 Most Significant Word 32x32 Multiply & Add Instructions +smmul: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +smmul.u: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32) + gen_sp_dataset(32,True)' + rs1_w1_val_data: 'gen_sign_dataset(32) + gen_sp_dataset(32,True)' + rs2_w0_val_data: 'gen_sign_dataset(32) + gen_sp_dataset(32,True)' + rs2_w1_val_data: 'gen_sign_dataset(32) + gen_sp_dataset(32,True)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +kmmac: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32) + gen_sp_dataset(32,True)' + rs1_w1_val_data: 'gen_sign_dataset(32) + gen_sp_dataset(32,True)' + rs2_w0_val_data: 'gen_sign_dataset(32) + gen_sp_dataset(32,True)' + rs2_w1_val_data: 'gen_sign_dataset(32) + gen_sp_dataset(32,True)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kmmac.u: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32) + gen_sp_dataset(32,True)' + rs1_w1_val_data: 'gen_sign_dataset(32) + gen_sp_dataset(32,True)' + rs2_w0_val_data: 'gen_sign_dataset(32) + gen_sp_dataset(32,True)' + rs2_w1_val_data: 'gen_sign_dataset(32) + gen_sp_dataset(32,True)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kmmsb: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32) + gen_sp_dataset(32,True)' + rs1_w1_val_data: 'gen_sign_dataset(32) + gen_sp_dataset(32,True)' + rs2_w0_val_data: 'gen_sign_dataset(32) + gen_sp_dataset(32,True)' + rs2_w1_val_data: 'gen_sign_dataset(32) + gen_sp_dataset(32,True)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kmmsb.u: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32) + gen_sp_dataset(32,True)' + rs1_w1_val_data: 'gen_sign_dataset(32) + gen_sp_dataset(32,True)' + rs2_w0_val_data: 'gen_sign_dataset(32) + gen_sp_dataset(32,True)' + rs2_w1_val_data: 'gen_sign_dataset(32) + gen_sp_dataset(32,True)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kwmmul: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32) + gen_sp_dataset(32,True)' + rs1_w1_val_data: 'gen_sign_dataset(32) + gen_sp_dataset(32,True)' + rs2_w0_val_data: 'gen_sign_dataset(32) + gen_sp_dataset(32,True)' + rs2_w1_val_data: 'gen_sign_dataset(32) + gen_sp_dataset(32,True)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kwmmul.u: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32) + gen_sp_dataset(32,True)' + rs1_w1_val_data: 'gen_sign_dataset(32) + gen_sp_dataset(32,True)' + rs2_w0_val_data: 'gen_sign_dataset(32) + gen_sp_dataset(32,True)' + rs2_w1_val_data: 'gen_sign_dataset(32) + gen_sp_dataset(32,True)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + + +# 3.2.3 Most Significant Word 32x16 Multiply & Add Instructions +smmwb: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32, 16 + formattype: 'pwhrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +smmwb.u: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32, 16 + formattype: 'pwhrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +smmwt: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32, 16 + formattype: 'pwhrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +smmwt.u: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32, 16 + formattype: 'pwhrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +kmmawb: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32, 16 + formattype: 'pwhrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kmmawb.u: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32, 16 + formattype: 'pwhrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kmmawt: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32, 16 + formattype: 'pwhrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kmmawt.u: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32, 16 + formattype: 'pwhrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kmmwb2: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32, 16 + formattype: 'pwhrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + + +kmmwb2.u: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32, 16 + formattype: 'pwhrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kmmwt2: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32, 16 + formattype: 'pwhrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kmmwt2.u: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32, 16 + formattype: 'pwhrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + + +kmmawb2: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32, 16 + formattype: 'pwhrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kmmawb2.u: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32, 16 + formattype: 'pwhrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kmmawt2: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32, 16 + formattype: 'pwhrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kmmawt2.u: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32, 16 + formattype: 'pwhrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + + +# 3.2.4 Signed 16-bit Multiply with 32-bit Add/Subtract Instructions + +smbb16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +smbt16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +smtt16: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +kmda: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kmxda: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +smds: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +smdrs: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +smxds: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +kmabb: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kmabt: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kmatt: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kmada: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kmaxda: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kmads: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kmadrs: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kmaxds: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kmsda: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kmsxda: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +# 3.2.5 Signed 16-bit Multiply with 64-bit Add/Subtract Instructions + +smal: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 64,16 + p64_profile: 'ppn' + formattype: 'pphrrformat' + rs1_op_data: *pair_regs + rs2_op_data: *all_regs + + rd_op_data: *pair_regs + rs1_val_data: 'gen_sign_dataset(64)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val64; op2val:$rs2_val; + TEST_P64_PPN_OP($inst, $rd, $rd_hi, $rs1, $rs1_hi, $rs2, $correctval, $correctval_hi, $rs1_val, $rs1_val_hi, $rs2_val, $swreg, $offset, $testreg) + + +# 3.2.6 Miscellaneous Instructions + +sclip32: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwriformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + imm_val_data: 'gen_imm_dataset(5)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_PKIMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $rs1, $swreg, $offset, $testreg) + +uclip32: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwriformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_usign_dataset(32)' + rs1_w1_val_data: 'gen_usign_dataset(32)' + imm_val_data: 'gen_imm_dataset(5)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_PKIMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $rs1, $swreg, $offset, $testreg) + +clrs32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + TEST_RD_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +clz32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_usign_dataset(32)' + rs1_w1_val_data: 'gen_usign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + TEST_RD_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +pbsad: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_usign_dataset(8)' + rs1_b1_val_data: 'gen_usign_dataset(8)' + rs1_b2_val_data: 'gen_usign_dataset(8)' + rs1_b3_val_data: 'gen_usign_dataset(8)' + rs1_b4_val_data: 'gen_usign_dataset(8)' + rs1_b5_val_data: 'gen_usign_dataset(8)' + rs1_b6_val_data: 'gen_usign_dataset(8)' + rs1_b7_val_data: 'gen_usign_dataset(8)' + rs2_b0_val_data: 'gen_usign_dataset(8)' + rs2_b1_val_data: 'gen_usign_dataset(8)' + rs2_b2_val_data: 'gen_usign_dataset(8)' + rs2_b3_val_data: 'gen_usign_dataset(8)' + rs2_b4_val_data: 'gen_usign_dataset(8)' + rs2_b5_val_data: 'gen_usign_dataset(8)' + rs2_b6_val_data: 'gen_usign_dataset(8)' + rs2_b7_val_data: 'gen_usign_dataset(8)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +pbsada: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_usign_dataset(8)' + rs1_b1_val_data: 'gen_usign_dataset(8)' + rs1_b2_val_data: 'gen_usign_dataset(8)' + rs1_b3_val_data: 'gen_usign_dataset(8)' + rs1_b4_val_data: 'gen_usign_dataset(8)' + rs1_b5_val_data: 'gen_usign_dataset(8)' + rs1_b6_val_data: 'gen_usign_dataset(8)' + rs1_b7_val_data: 'gen_usign_dataset(8)' + rs2_b0_val_data: 'gen_usign_dataset(8)' + rs2_b1_val_data: 'gen_usign_dataset(8)' + rs2_b2_val_data: 'gen_usign_dataset(8)' + rs2_b3_val_data: 'gen_usign_dataset(8)' + rs2_b4_val_data: 'gen_usign_dataset(8)' + rs2_b5_val_data: 'gen_usign_dataset(8)' + rs2_b6_val_data: 'gen_usign_dataset(8)' + rs2_b7_val_data: 'gen_usign_dataset(8)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +# 3.2.7. 8-bit Multiply with 32-bit Add Instructions + +smaqa: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_sign_dataset(8)' + rs1_b1_val_data: 'gen_sign_dataset(8)' + rs1_b2_val_data: 'gen_sign_dataset(8)' + rs1_b3_val_data: 'gen_sign_dataset(8)' + rs1_b4_val_data: 'gen_sign_dataset(8)' + rs1_b5_val_data: 'gen_sign_dataset(8)' + rs1_b6_val_data: 'gen_sign_dataset(8)' + rs1_b7_val_data: 'gen_sign_dataset(8)' + rs2_b0_val_data: 'gen_sign_dataset(8)' + rs2_b1_val_data: 'gen_sign_dataset(8)' + rs2_b2_val_data: 'gen_sign_dataset(8)' + rs2_b3_val_data: 'gen_sign_dataset(8)' + rs2_b4_val_data: 'gen_sign_dataset(8)' + rs2_b5_val_data: 'gen_sign_dataset(8)' + rs2_b6_val_data: 'gen_sign_dataset(8)' + rs2_b7_val_data: 'gen_sign_dataset(8)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +umaqa: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_usign_dataset(8)' + rs1_b1_val_data: 'gen_usign_dataset(8)' + rs1_b2_val_data: 'gen_usign_dataset(8)' + rs1_b3_val_data: 'gen_usign_dataset(8)' + rs1_b4_val_data: 'gen_usign_dataset(8)' + rs1_b5_val_data: 'gen_usign_dataset(8)' + rs1_b6_val_data: 'gen_usign_dataset(8)' + rs1_b7_val_data: 'gen_usign_dataset(8)' + rs2_b0_val_data: 'gen_usign_dataset(8)' + rs2_b1_val_data: 'gen_usign_dataset(8)' + rs2_b2_val_data: 'gen_usign_dataset(8)' + rs2_b3_val_data: 'gen_usign_dataset(8)' + rs2_b4_val_data: 'gen_usign_dataset(8)' + rs2_b5_val_data: 'gen_usign_dataset(8)' + rs2_b6_val_data: 'gen_usign_dataset(8)' + rs2_b7_val_data: 'gen_usign_dataset(8)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +smaqa.su: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 8 + formattype: 'pbrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_b0_val_data: 'gen_sign_dataset(8)' + rs1_b1_val_data: 'gen_sign_dataset(8)' + rs1_b2_val_data: 'gen_sign_dataset(8)' + rs1_b3_val_data: 'gen_sign_dataset(8)' + rs1_b4_val_data: 'gen_sign_dataset(8)' + rs1_b5_val_data: 'gen_sign_dataset(8)' + rs1_b6_val_data: 'gen_sign_dataset(8)' + rs1_b7_val_data: 'gen_sign_dataset(8)' + rs2_b0_val_data: 'gen_sign_dataset(8)' + rs2_b1_val_data: 'gen_sign_dataset(8)' + rs2_b2_val_data: 'gen_sign_dataset(8)' + rs2_b3_val_data: 'gen_sign_dataset(8)' + rs2_b4_val_data: 'gen_sign_dataset(8)' + rs2_b5_val_data: 'gen_sign_dataset(8)' + rs2_b6_val_data: 'gen_sign_dataset(8)' + rs2_b7_val_data: 'gen_sign_dataset(8)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +# 3.3.1 64-bit Addition & Subtraction Instructions + +add64: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32] + std_op: + isa: + - IPZicsr + bit_width: 64 + p64_profile: 'ppp' + formattype: 'prrformat' + rs1_op_data: *pair_regs + rs2_op_data: *pair_regs + rd_op_data: *pair_regs + rs1_val_data: 'gen_sign_dataset(64)' + rs2_val_data: 'gen_sign_dataset(64)' + + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val64 op2val:$rs2_val64 + TEST_P64_PPP_OP($inst, $rd, $rd_hi, $rs1, $rs1_hi, $rs2, $rs2_hi, $correctval, $correctval_hi, $rs1_val, $rs1_val_hi, $rs2_val, $rs2_val_hi, $swreg, $offset, $testreg) + +radd64: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 64 + p64_profile: 'ppp' + formattype: 'prrformat' + rs1_op_data: *pair_regs + rs2_op_data: *pair_regs + rd_op_data: *pair_regs + rs1_val_data: 'gen_sign_dataset(64)' + rs2_val_data: 'gen_sign_dataset(64)' + + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val64; op2val:$rs2_val64; + TEST_P64_PPP_OP($inst, $rd, $rd_hi, $rs1, $rs1_hi, $rs2, $rs2_hi, $correctval, $correctval_hi, $rs1_val, $rs1_val_hi, $rs2_val, $rs2_val_hi, $swreg, $offset, $testreg) + +uradd64: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 64 + p64_profile: 'ppp' + formattype: 'prrformat' + rs1_op_data: *pair_regs + rs2_op_data: *pair_regs + rd_op_data: *pair_regs + rs1_val_data: 'gen_usign_dataset(64)' + rs2_val_data: 'gen_usign_dataset(64)' + + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val64; op2val:$rs2_val64; + TEST_P64_PPP_OP($inst, $rd, $rd_hi, $rs1, $rs1_hi, $rs2, $rs2_hi, $correctval, $correctval_hi, $rs1_val, $rs1_val_hi, $rs2_val, $rs2_val_hi, $swreg, $offset, $testreg) + +kadd64: + sig: + stride: 3 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 64 + p64_profile: 'ppp' + formattype: 'prrformat' + rs1_op_data: *pair_regs + rs2_op_data: *pair_regs + rd_op_data: *pair_regs + rs1_val_data: 'gen_sign_dataset(64)' + rs2_val_data: 'gen_sign_dataset(64)' + + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val64; op2val:$rs2_val64; + TEST_PK64_PPP_OP($inst, $rd, $rd_hi, $rs1, $rs1_hi, $rs2, $rs2_hi, $correctval, $correctval_hi, $rs1_val, $rs1_val_hi, $rs2_val, $rs2_val_hi, $rs1, $swreg, $offset, $testreg) + +ukadd64: + sig: + stride: 3 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 64 + p64_profile: 'ppp' + formattype: 'prrformat' + rs1_op_data: *pair_regs + rs2_op_data: *pair_regs + rd_op_data: *pair_regs + rs1_val_data: 'gen_usign_dataset(64)' + rs2_val_data: 'gen_usign_dataset(64)' + + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val64; op2val:$rs2_val64; + TEST_PK64_PPP_OP($inst, $rd, $rd_hi, $rs1, $rs1_hi, $rs2, $rs2_hi, $correctval, $correctval_hi, $rs1_val, $rs1_val_hi, $rs2_val, $rs2_val_hi, $rs1, $swreg, $offset, $testreg) + +sub64: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32] + std_op: + isa: + - IPZicsr + bit_width: 64 + p64_profile: 'ppp' + formattype: 'prrformat' + rs1_op_data: *pair_regs + rs2_op_data: *pair_regs + rd_op_data: *pair_regs + rs1_val_data: 'gen_sign_dataset(64)' + rs2_val_data: 'gen_sign_dataset(64)' + + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val64; op2val:$rs2_val64; + TEST_P64_PPP_OP($inst, $rd, $rd_hi, $rs1, $rs1_hi, $rs2, $rs2_hi, $correctval, $correctval_hi, $rs1_val, $rs1_val_hi, $rs2_val, $rs2_val_hi, $swreg, $offset, $testreg) + +rsub64: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 64 + p64_profile: 'ppp' + formattype: 'prrformat' + rs1_op_data: *pair_regs + rs2_op_data: *pair_regs + rd_op_data: *pair_regs + rs1_val_data: 'gen_sign_dataset(64)' + rs2_val_data: 'gen_sign_dataset(64)' + + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val64; op2val:$rs2_val64; + TEST_P64_PPP_OP($inst, $rd, $rd_hi, $rs1, $rs1_hi, $rs2, $rs2_hi, $correctval, $correctval_hi, $rs1_val, $rs1_val_hi, $rs2_val, $rs2_val_hi, $swreg, $offset, $testreg) + +ursub64: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 64 + p64_profile: 'ppp' + formattype: 'prrformat' + rs1_op_data: *pair_regs + rs2_op_data: *pair_regs + rd_op_data: *pair_regs + rs1_val_data: 'gen_usign_dataset(64)' + rs2_val_data: 'gen_usign_dataset(64)' + + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val64; op2val:$rs2_val64; + TEST_P64_PPP_OP($inst, $rd, $rd_hi, $rs1, $rs1_hi, $rs2, $rs2_hi, $correctval, $correctval_hi, $rs1_val, $rs1_val_hi, $rs2_val, $rs2_val_hi, $swreg, $offset, $testreg) + +ksub64: + sig: + stride: 3 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 64 + p64_profile: 'ppp' + formattype: 'prrformat' + rs1_op_data: *pair_regs + rs2_op_data: *pair_regs + rd_op_data: *pair_regs + rs1_val_data: 'gen_sign_dataset(64)' + rs2_val_data: 'gen_sign_dataset(64)' + + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val64; op2val:$rs2_val64; + TEST_PK64_PPP_OP($inst, $rd, $rd_hi, $rs1, $rs1_hi, $rs2, $rs2_hi, $correctval, $correctval_hi, $rs1_val, $rs1_val_hi, $rs2_val, $rs2_val_hi, $rs1, $swreg, $offset, $testreg) + +uksub64: + sig: + stride: 3 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 64 + p64_profile: 'ppp' + formattype: 'prrformat' + rs1_op_data: *pair_regs + rs2_op_data: *pair_regs + rd_op_data: *pair_regs + rs1_val_data: 'gen_usign_dataset(64)' + rs2_val_data: 'gen_usign_dataset(64)' + + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val64; op2val:$rs2_val64; + TEST_PK64_PPP_OP($inst, $rd, $rd_hi, $rs1, $rs1_hi, $rs2, $rs2_hi, $correctval, $correctval_hi, $rs1_val, $rs1_val_hi, $rs2_val, $rs2_val_hi, $rs1, $swreg, $offset, $testreg) + +# 3.2.2 32-bit Multiply with 64-bit Add/Subtract Instructions + +smar64: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32 + p64_profile: 'pnn' + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *pair_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_P64_PNN_OP($inst, $rd, $rd_hi, $rs1, $rs2, $correctval, $correctval_hi, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +smsr64: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32 + p64_profile: 'pnn' + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *pair_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_P64_PNN_OP($inst, $rd, $rd_hi, $rs1, $rs2, $correctval, $correctval_hi, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +umar64: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32 + p64_profile: 'pnn' + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *pair_regs + rs1_w0_val_data: 'gen_usign_dataset(32)' + rs1_w1_val_data: 'gen_usign_dataset(32)' + rs2_w0_val_data: 'gen_usign_dataset(32)' + rs2_w1_val_data: 'gen_usign_dataset(32)' + + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_P64_PNN_OP($inst, $rd, $rd_hi, $rs1, $rs2, $correctval, $correctval_hi, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +umsr64: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32 + p64_profile: 'pnn' + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *pair_regs + rs1_w0_val_data: 'gen_usign_dataset(32)' + rs1_w1_val_data: 'gen_usign_dataset(32)' + rs2_w0_val_data: 'gen_usign_dataset(32)' + rs2_w1_val_data: 'gen_usign_dataset(32)' + + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_P64_PNN_OP($inst, $rd, $rd_hi, $rs1, $rs2, $correctval, $correctval_hi, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +kmar64: + sig: + stride: 3 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32 + p64_profile: 'pnn' + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *pair_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PK64_PNN_OP($inst, $rd, $rd_hi, $rs1, $rs2, $correctval, $correctval_hi, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kmsr64: + sig: + stride: 3 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32 + p64_profile: 'pnn' + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *pair_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PK64_PNN_OP($inst, $rd, $rd_hi, $rs1, $rs2, $correctval, $correctval_hi, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +ukmar64: + sig: + stride: 3 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32 + p64_profile: 'pnn' + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *pair_regs + rs1_w0_val_data: 'gen_usign_dataset(32)' + rs1_w1_val_data: 'gen_usign_dataset(32)' + rs2_w0_val_data: 'gen_usign_dataset(32)' + rs2_w1_val_data: 'gen_usign_dataset(32)' + + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PK64_PNN_OP($inst, $rd, $rd_hi, $rs1, $rs2, $correctval, $correctval_hi, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +ukmsr64: + sig: + stride: 3 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32 + p64_profile: 'pnn' + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *pair_regs + rs1_w0_val_data: 'gen_usign_dataset(32)' + rs1_w1_val_data: 'gen_usign_dataset(32)' + rs2_w0_val_data: 'gen_usign_dataset(32)' + rs2_w1_val_data: 'gen_usign_dataset(32)' + + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PK64_PNN_OP($inst, $rd, $rd_hi, $rs1, $rs2, $correctval, $correctval_hi, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + + +# 3.3.3 Signed 16-bit Multiply with 64-bit Add/Subtract Instructions + +smalbb: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + p64_profile: 'pnn' + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *pair_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_P64_PNN_OP($inst, $rd, $rd_hi, $rs1, $rs2, $correctval, $correctval_hi, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +smalbt: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + p64_profile: 'pnn' + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *pair_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_P64_PNN_OP($inst, $rd, $rd_hi, $rs1, $rs2, $correctval, $correctval_hi, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +smaltt: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + p64_profile: 'pnn' + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *pair_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_P64_PNN_OP($inst, $rd, $rd_hi, $rs1, $rs2, $correctval, $correctval_hi, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +smalda: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + p64_profile: 'pnn' + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *pair_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_P64_PNN_OP($inst, $rd, $rd_hi, $rs1, $rs2, $correctval, $correctval_hi, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +smalxda: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + p64_profile: 'pnn' + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *pair_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_P64_PNN_OP($inst, $rd, $rd_hi, $rs1, $rs2, $correctval, $correctval_hi, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +smalds: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + p64_profile: 'pnn' + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *pair_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_P64_PNN_OP($inst, $rd, $rd_hi, $rs1, $rs2, $correctval, $correctval_hi, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +smaldrs: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + p64_profile: 'pnn' + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *pair_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_P64_PNN_OP($inst, $rd, $rd_hi, $rs1, $rs2, $correctval, $correctval_hi, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +smalxds: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + p64_profile: 'pnn' + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *pair_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_P64_PNN_OP($inst, $rd, $rd_hi, $rs1, $rs2, $correctval, $correctval_hi, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +smslda: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + p64_profile: 'pnn' + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *pair_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_P64_PNN_OP($inst, $rd, $rd_hi, $rs1, $rs2, $correctval, $correctval_hi, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +smslxda: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + p64_profile: 'pnn' + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *pair_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_P64_PNN_OP($inst, $rd, $rd_hi, $rs1, $rs2, $correctval, $correctval_hi, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +# 3.4.1 Q15 Saturation Instructions + +kaddh: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +ksubh: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +khmbb: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +khmbt: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +khmtt: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +ukaddh: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_usign_dataset(16)' + rs1_h1_val_data: 'gen_usign_dataset(16)' + rs1_h2_val_data: 'gen_usign_dataset(16)' + rs1_h3_val_data: 'gen_usign_dataset(16)' + rs2_h0_val_data: 'gen_usign_dataset(16)' + rs2_h1_val_data: 'gen_usign_dataset(16)' + rs2_h2_val_data: 'gen_usign_dataset(16)' + rs2_h3_val_data: 'gen_usign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +uksubh: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_usign_dataset(16)' + rs1_h1_val_data: 'gen_usign_dataset(16)' + rs1_h2_val_data: 'gen_usign_dataset(16)' + rs1_h3_val_data: 'gen_usign_dataset(16)' + rs2_h0_val_data: 'gen_usign_dataset(16)' + rs2_h1_val_data: 'gen_usign_dataset(16)' + rs2_h2_val_data: 'gen_usign_dataset(16)' + rs2_h3_val_data: 'gen_usign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +# 3.4.2 Q31 Saturation Instructions + +kaddw: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +ukaddw: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_usign_dataset(32)' + rs1_w1_val_data: 'gen_usign_dataset(32)' + rs2_w0_val_data: 'gen_usign_dataset(32)' + rs2_w1_val_data: 'gen_usign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +ksubw: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +uksubw: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_usign_dataset(32)' + rs1_w1_val_data: 'gen_usign_dataset(32)' + rs2_w0_val_data: 'gen_usign_dataset(32)' + rs2_w1_val_data: 'gen_usign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kdmbb: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kdmbt: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kdmtt: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kslraw: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kslraw.u: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_usign_dataset(32)' + rs1_w1_val_data: 'gen_usign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +ksllw: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pswrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_val_data: 'gen_usign_dataset(ceil(log(32,2)))' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kslliw: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwriformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + imm_val_data: 'gen_imm_dataset(5)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_PKIMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $rs1, $swreg, $offset, $testreg) + +kdmabb: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kdmabt: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kdmatt: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kabsw: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + TEST_PKR_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $rs1, $swreg, $offset, $testreg) + +# 3.4.3. 32-bit Computation Instructions + +raddw: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +uraddw: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_usign_dataset(32)' + rs1_w1_val_data: 'gen_usign_dataset(32)' + rs2_w0_val_data: 'gen_usign_dataset(32)' + rs2_w1_val_data: 'gen_usign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +rsubw: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +ursubw: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_usign_dataset(32)' + rs1_w1_val_data: 'gen_usign_dataset(32)' + rs2_w0_val_data: 'gen_usign_dataset(32)' + rs2_w1_val_data: 'gen_usign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +mulr64: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32 + p64_profile: 'pnn' + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *pair_regs + rs1_w0_val_data: 'gen_usign_dataset(32)' + rs2_w0_val_data: 'gen_usign_dataset(32)' + rs1_w1_val_data: 'gen_usign_dataset(32)' + rs2_w1_val_data: 'gen_usign_dataset(32)' + + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val; + TEST_P64_PNN_OP($inst, $rd, $rd_hi, $rs1, $rs2, $correctval, $correctval_hi, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +mulsr64: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32 + p64_profile: 'pnn' + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *pair_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_P64_PNN_OP($inst, $rd, $rd_hi, $rs1, $rs2, $correctval, $correctval_hi, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +maddr32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32) + gen_sp_dataset(32,True)' + rs1_w1_val_data: 'gen_sign_dataset(32) + gen_sp_dataset(32,True)' + rs2_w0_val_data: 'gen_sign_dataset(32) + gen_sp_dataset(32,True)' + rs2_w1_val_data: 'gen_sign_dataset(32) + gen_sp_dataset(32,True)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +msubr32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +# 3.4.4 Overflow/Saturation Status Manipulation Instructions +# alias for CSRR Rd, vxsat +# rdov: +# sig: +# stride: 1 +# sz: 'XLEN/8' +# rd_op_data: *all_regs +# xlen: [32,64] +# std_op: +# isa: +# - IP +# formattype: 'uformat' +# imm_val_data: 'gen_usign_dataset(2)' +# template: |- +# +# // $comment +# // opcode: $inst ; dest:$rd +# TEST_CASE($testreg, $rd, $correctval, $swreg, $offset, $inst $rd) + +# alias for CSRRCI x0, vxsat, 1 +# clrov: +# sig: +# stride: 1 +# sz: 'XLEN/8' +# rd_op_data: *all_regs +# xlen: [32,64] +# std_op: +# isa: +# - IP +# formattype: 'uformat' +# imm_val_data: 'gen_usign_dataset(2)' +# template: |- +# +# // $comment +# // opcode: $inst +# TEST_CASE($testreg, x0, $correctval, $swreg, $offset, $inst) + +# 3.4.5. Miscellaneous Instructions + +ave: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +sra.u: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +srai.u: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + formattype: 'iformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)' + imm_val_data: 'gen_imm_dataset(ceil(log(xlen,2)))' + + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +bitrev: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +bitrevi: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + formattype: 'iformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)' + imm_val_data: 'gen_imm_dataset(ceil(log(xlen,2)))' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +wext: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 64, 8 + p64_profile: 'npn' + formattype: 'ppbrrformat' + rs1_op_data: *pair_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(64)' + rs2_b0_val_data: 'gen_usign_dataset(8)' + rs2_b1_val_data: 'gen_usign_dataset(8)' + rs2_b2_val_data: 'gen_usign_dataset(8)' + rs2_b3_val_data: 'gen_usign_dataset(8)' + rs2_b4_val_data: 'gen_usign_dataset(8)' + rs2_b5_val_data: 'gen_usign_dataset(8)' + rs2_b6_val_data: 'gen_usign_dataset(8)' + rs2_b7_val_data: 'gen_usign_dataset(8)' + + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val64; op2val:$rs2_val + TEST_P64_NPN_OP($inst, $rd, $rs1, $rs1_hi, $rs2, $correctval, $rs1_val, $rs1_val_hi, $rs2_val, $swreg, $offset, $testreg) + +wexti: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + bit_width: 64 + p64_profile: 'npi' + formattype: 'iformat' + rs1_op_data: *pair_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(64)' + imm_val_data: 'gen_imm_dataset(ceil(log(32,2)))' + + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val64; immval:$imm_val + TEST_P64_NP_OP($inst, $rd, $rs1, $rs1_hi, $correctval, $rs1_val, $rs1_val_hi, $imm_val, $swreg, $offset, $testreg) + + +insb: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IPZicsr + formattype: 'iformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)' + imm_val_data: 'gen_imm_dataset(ceil(log(xlen,2))-3)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +# 8. RV64 Only Instructions +# Table 27. (RV64 Only) SIMD 32-bit Add/Subtract Instructions + +add32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +radd32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +uradd32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_usign_dataset(32)' + rs1_w1_val_data: 'gen_usign_dataset(32)' + rs2_w0_val_data: 'gen_usign_dataset(32)' + rs2_w1_val_data: 'gen_usign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +kadd32: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +ukadd32: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_usign_dataset(32)' + rs1_w1_val_data: 'gen_usign_dataset(32)' + rs2_w0_val_data: 'gen_usign_dataset(32)' + rs2_w1_val_data: 'gen_usign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +sub32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +rsub32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +ursub32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_usign_dataset(32)' + rs1_w1_val_data: 'gen_usign_dataset(32)' + rs2_w0_val_data: 'gen_usign_dataset(32)' + rs2_w1_val_data: 'gen_usign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +ksub32: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +uksub32: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_usign_dataset(32)' + rs1_w1_val_data: 'gen_usign_dataset(32)' + rs2_w0_val_data: 'gen_usign_dataset(32)' + rs2_w1_val_data: 'gen_usign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +cras32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +rcras32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +urcras32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_usign_dataset(32)' + rs1_w1_val_data: 'gen_usign_dataset(32)' + rs2_w0_val_data: 'gen_usign_dataset(32)' + rs2_w1_val_data: 'gen_usign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +kcras32: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +ukcras32: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_usign_dataset(32)' + rs1_w1_val_data: 'gen_usign_dataset(32)' + rs2_w0_val_data: 'gen_usign_dataset(32)' + rs2_w1_val_data: 'gen_usign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +crsa32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +rcrsa32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +urcrsa32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_usign_dataset(32)' + rs1_w1_val_data: 'gen_usign_dataset(32)' + rs2_w0_val_data: 'gen_usign_dataset(32)' + rs2_w1_val_data: 'gen_usign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +kcrsa32: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +ukcrsa32: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_usign_dataset(32)' + rs1_w1_val_data: 'gen_usign_dataset(32)' + rs2_w0_val_data: 'gen_usign_dataset(32)' + rs2_w1_val_data: 'gen_usign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +stas32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +rstas32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +urstas32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_usign_dataset(32)' + rs1_w1_val_data: 'gen_usign_dataset(32)' + rs2_w0_val_data: 'gen_usign_dataset(32)' + rs2_w1_val_data: 'gen_usign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +kstas32: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +ukstas32: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_usign_dataset(32)' + rs1_w1_val_data: 'gen_usign_dataset(32)' + rs2_w0_val_data: 'gen_usign_dataset(32)' + rs2_w1_val_data: 'gen_usign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +stsa32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +rstsa32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +urstsa32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_usign_dataset(32)' + rs1_w1_val_data: 'gen_usign_dataset(32)' + rs2_w0_val_data: 'gen_usign_dataset(32)' + rs2_w1_val_data: 'gen_usign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +kstsa32: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +ukstsa32: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_usign_dataset(32)' + rs1_w1_val_data: 'gen_usign_dataset(32)' + rs2_w0_val_data: 'gen_usign_dataset(32)' + rs2_w1_val_data: 'gen_usign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +# Table 28. (RV64 Only) SIMD 32-bit Shift Instructions + +sra32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pswrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_val_data: 'gen_usign_dataset(ceil(log(32,2)))' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +srai32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwriformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + imm_val_data: 'gen_imm_dataset(5)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +sra32.u: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pswrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_val_data: 'gen_usign_dataset(ceil(log(32,2)))' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +srai32.u: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwriformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + imm_val_data: 'gen_imm_dataset(5)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +srl32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pswrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_usign_dataset(32)' + rs1_w1_val_data: 'gen_usign_dataset(32)' + rs2_val_data: 'gen_usign_dataset(ceil(log(32,2)))' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +srli32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwriformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_usign_dataset(32)' + rs1_w1_val_data: 'gen_usign_dataset(32)' + imm_val_data: 'gen_imm_dataset(5)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +srl32.u: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pswrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_usign_dataset(32)' + rs1_w1_val_data: 'gen_usign_dataset(32)' + rs2_val_data: 'gen_usign_dataset(ceil(log(32,2)))' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +srli32.u: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwriformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_usign_dataset(32)' + rs1_w1_val_data: 'gen_usign_dataset(32)' + imm_val_data: 'gen_imm_dataset(5)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +sll32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pswrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_usign_dataset(32)' + rs1_w1_val_data: 'gen_usign_dataset(32)' + rs2_val_data: 'gen_usign_dataset(ceil(log(32,2)))' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +slli32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwriformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_usign_dataset(32)' + rs1_w1_val_data: 'gen_usign_dataset(32)' + imm_val_data: 'gen_imm_dataset(5)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +ksll32: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pswrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_val_data: 'gen_usign_dataset(ceil(log(32,2)))' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kslli32: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwriformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + imm_val_data: 'gen_imm_dataset(5)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_PKIMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $rs1, $swreg, $offset, $testreg) + +kslra32: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32,xlen + formattype: 'pswrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_val_data: 'gen_sign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kslra32.u: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32,xlen + formattype: 'pswrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_usign_dataset(32)' + rs1_w1_val_data: 'gen_usign_dataset(32)' + rs2_val_data: 'gen_sign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +# Table 29. (RV64 Only) SIMD 32-bit Miscellaneous Instructions + +smin32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +umin32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_usign_dataset(32)' + rs1_w1_val_data: 'gen_usign_dataset(32)' + rs2_w0_val_data: 'gen_usign_dataset(32)' + rs2_w1_val_data: 'gen_usign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +smax32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +umax32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_usign_dataset(32)' + rs1_w1_val_data: 'gen_usign_dataset(32)' + rs2_w0_val_data: 'gen_usign_dataset(32)' + rs2_w1_val_data: 'gen_usign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +kabs32: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + TEST_PKR_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $rs1, $swreg, $offset, $testreg) + +# Table 30. (RV64 Only) SIMD Q15 saturating Multiply Instructions + +khmbb16: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +khmbt16: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +khmtt16: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kdmbb16: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kdmbt16: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kdmtt16: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kdmabb16: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kdmabt16: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kdmatt16: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 16 + formattype: 'phrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_h0_val_data: 'gen_sign_dataset(16)' + rs1_h1_val_data: 'gen_sign_dataset(16)' + rs1_h2_val_data: 'gen_sign_dataset(16)' + rs1_h3_val_data: 'gen_sign_dataset(16)' + rs2_h0_val_data: 'gen_sign_dataset(16)' + rs2_h1_val_data: 'gen_sign_dataset(16)' + rs2_h2_val_data: 'gen_sign_dataset(16)' + rs2_h3_val_data: 'gen_sign_dataset(16)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +# Table 31. (RV64 Only) 32-bit Multiply Instructions + +smbb32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +smbt32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +smtt32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +# Table 32. (RV64 Only) 32-bit Multiply & Add Instructions + +kmabb32: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kmabt32: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kmatt32: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +# Table 33. (RV64 Only) 32-bit Parallel Multiply & Add Instructions + +kmda32: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kmxda32: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kmada32: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kmaxda32: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kmads32: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kmadrs32: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kmaxds32: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kmsda32: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +kmsxda32: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_PKRR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $rs1, $swreg, $offset, $testreg) + +smds32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +smdrs32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +smxds32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + rs2_w0_val_data: 'gen_sign_dataset(32)' + rs2_w1_val_data: 'gen_sign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +# Table 34. (RV64 Only) Non-SIMD 32-bit Shift Instructions + +sraiw.u: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwriformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_sign_dataset(32)' + rs1_w1_val_data: 'gen_sign_dataset(32)' + imm_val_data: 'gen_imm_dataset(5)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +# Table 35. (RV64 Only) 32-bit Packing Instructions + +pkbb32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_usign_dataset(32)' + rs1_w1_val_data: 'gen_usign_dataset(32)' + rs2_w0_val_data: 'gen_usign_dataset(32)' + rs2_w1_val_data: 'gen_usign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +pkbt32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_usign_dataset(32)' + rs1_w1_val_data: 'gen_usign_dataset(32)' + rs2_w0_val_data: 'gen_usign_dataset(32)' + rs2_w1_val_data: 'gen_usign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +pktb32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_usign_dataset(32)' + rs1_w1_val_data: 'gen_usign_dataset(32)' + rs2_w0_val_data: 'gen_usign_dataset(32)' + rs2_w1_val_data: 'gen_usign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +pktt32: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IPZicsr + bit_width: 32 + formattype: 'pwrrformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_w0_val_data: 'gen_usign_dataset(32)' + rs1_w1_val_data: 'gen_usign_dataset(32)' + rs2_w0_val_data: 'gen_usign_dataset(32)' + rs2_w1_val_data: 'gen_usign_dataset(32)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +bseti: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZbs + - IB + formattype: 'iformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'zerotoxlen(xlen)' + imm_val_data: 'gen_imm_dataset(ceil(log(xlen,2)))' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_IMM_OP( $inst, $rd, $rs1, $correctval, $rs1_val, $imm_val, $swreg, $offset, $testreg) + +xperm4: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZk + - IZbkx + - IZkn + - IZks + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_usign_dataset(xlen)+gen_sign_dataset(xlen)' + rs2_val_data: 'gen_usign_dataset(xlen)+gen_sign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +xperm8: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZk + - IZbkx + - IZkn + - IZks + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_usign_dataset(xlen) + gen_sp_dataset(xlen)+gen_sign_dataset(xlen)' + rs2_val_data: 'gen_usign_dataset(xlen) + gen_sp_dataset(xlen)+gen_sign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +brev8: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: brev8 + isa: + - IZbkb + - IZk + - IZkn + - IZks + formattype: 'kformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)+gen_bitmanip_dataset(xlen,False)+[16909320,33818625,67633410,134283780,72624976414508040,145249888404506625,290483284134592770,576744443617542660]' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; + LI($rs1,$rs1_val) + brev8 $rd, $rs1 + RVTEST_SIGUPD($swreg,$rd,$offset) + RVMODEL_IO_ASSERT_GPR_EQ($testreg, $rd, $correctval) + +# place holder for gorci instruction until it is rattified +gorci: + stride: 1 + xlen: [32,64] + std_op: gorci + isa: + - IB + formattype: 'iformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val; + LI($rs1,$rs1_val) + gorci $rd, $rs1, $imm_val + SREG $rd, $offset($swreg) + RVMODEL_IO_ASSERT_GPR_EQ($testreg, $rd, $correctval) + +# place holder for grevi instruction until it is rattified +grevi: + stride: 1 + xlen: [32,64] + std_op: grevi + isa: + - IB + formattype: 'iformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + template: |- + + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val; + LI($rs1,$rs1_val) + grevi $rd, $rs1, $imm_val + SREG $rd, $offset($swreg) + RVMODEL_IO_ASSERT_GPR_EQ($testreg, $rd, $correctval) + +shfli: + stride: 1 + xlen: [32] + std_op: shfli + isa: + - IB + formattype: 'iformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + template: |- + + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val; + LI($rs1,$rs1_val) + shfli $rd, $rs1, $imm_val + SREG $rd, $offset($swreg) + RVMODEL_IO_ASSERT_GPR_EQ($testreg, $rd, $correctval) + +unshfli: + stride: 1 + xlen: [32] + std_op: unshfli + isa: + - IB + formattype: 'iformat' + rs1_op_data: *all_regs + rd_op_data: *all_regs + template: |- + + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val; + LI($rs1,$rs1_val) + unshfli $rd, $rs1, $imm_val + SREG $rd, $offset($swreg) + RVMODEL_IO_ASSERT_GPR_EQ($testreg, $rd, $correctval) + +czero.eqz: + std_op: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + isa: + - IZicond + operation: 'hex(int(rs2_val != 0) * rs1_val)' + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +czero.nez: + std_op: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + isa: + - IZicond + operation: 'hex(int(rs2_val == 0) * rs1_val)' + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +amoadd.w: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IA + - IZaamo + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_AMO_OP($inst, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $offset) + +amoand.w: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IA + - IZaamo + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_AMO_OP($inst, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $offset) + +amoswap.w: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IA + - IZaamo + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_AMO_OP($inst, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $offset) + +amoxor.w: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IA + - IZaamo + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_AMO_OP($inst, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $offset) + +amoor.w: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IA + - IZaamo + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_AMO_OP($inst, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $offset) + +amomin.w: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IA + - IZaamo + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_AMO_OP($inst, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $offset) + +amominu.w: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IA + - IZaamo + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_AMO_OP($inst, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $offset) + +amomax.w: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IA + - IZaamo + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_AMO_OP($inst, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $offset) + +amomaxu.w: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IA + - IZaamo + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_AMO_OP($inst, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $offset) + +amoadd.d: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IA + - IZaamo + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_AMO_OP($inst, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $offset) + +amoand.d: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IA + - IZaamo + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_AMO_OP($inst, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $offset) + +amoswap.d: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IA + - IZaamo + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_AMO_OP($inst, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $offset) + +amoxor.d: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IA + - IZaamo + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_AMO_OP($inst, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $offset) + +amoor.d: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IA + - IZaamo + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_AMO_OP($inst, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $offset) + +amomin.d: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IA + - IZaamo + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_AMO_OP($inst, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $offset) + +amominu.d: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IA + - IZaamo + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_AMO_OP($inst, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $offset) + +amomax.d: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IA + - IZaamo + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_AMO_OP($inst, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $offset) + +amomaxu.d: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IA + - IZaamo + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_AMO_OP($inst, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $offset) + +amocas.w: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZacas + formattype: 'rformat' + rs1_op_data: *all_regs_mx0 + rs2_op_data: *pair_regs + rd_op_data: *pair_regs + rs1_val_data: 'gen_sign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)' + + template: |- + + // $comment + // opcode: $inst ; dest:$rd; addr:$rs1; src:$rs2; swap_val:$rs2_val; swreg:$swreg; $offset + TEST_CAS_OP($inst, $rd, $rs1, $rs2, $rs2_val, $swreg, $offset); + +amocas.d_32: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32] + std_op: + isa: + - IZacas + bit_width: 64 + dcas_profile: 'pnp' + formattype: 'dcasrformat' + rs1_op_data: *all_regs_mx0 + rs2_op_data: *pair_regs + rd_op_data: *pair_regs + rs1_val_data: 'gen_sign_dataset(64)' + rs2_val_data: 'gen_sign_dataset(64)' + + template: |- + + // $comment + // opcode: $inst ; dest($rd, $rd_hi) addr:$rs1; src:($rs2, $rs2_hi); swap_val:($rs2_val, $rs2_val_hi); swreg:$swreg; $offset + TEST_DCAS_OP(amocas.d, $rd, $rd_hi, $rs1, $rs2, $rs2_hi, $rs2_val, $rs2_val_hi, $swreg, $offset); + +amocas.d_64: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IZacas + formattype: 'rformat' + rs1_op_data: *all_regs_mx0 + rs2_op_data: *pair_regs + rd_op_data: *pair_regs + rs1_val_data: 'gen_sign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)' + + template: |- + + // $comment + // opcode: $inst ; dest:$rd; addr:$rs1; src:$rs2; swap_val:$rs2_val; swreg:$swreg; $offset + TEST_CAS_OP(amocas.d, $rd, $rs1, $rs2, $rs2_val, $swreg, $offset); + +amocas.q: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IZacas + bit_width: 128 + dcas_profile: 'pnp' + formattype: 'dcasrformat' + rs1_op_data: *all_regs_mx0 + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(128)' + rs2_val_data: 'gen_sign_dataset(128)' + + template: |- + + // $comment + // opcode: $inst ; dest($rd, $rd_hi) addr:$rs1; src:($rs2, $rs2_hi); swap_val:($rs2_val, $rs2_val_hi), swreg:$swreg, $offset + TEST_DCAS_OP($inst, $rd, $rd_hi, $rs1, $rs2, $rs2_hi, $rs2_val, $rs2_val_hi, $swreg, $offset); + +c.lbu: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *c_regs + rd_op_data: *c_regs + xlen: [32,64] + std_op: + isa: + - I_Zca_Zcb + formattype: 'clformat' + rs1_val_data: '[0]' + imm_val_data: 'gen_usign_dataset(2)' + template: |- + + // $comment + // opcode: $inst; op1:$rs1; dest:$rd; immval:$imm_val + TEST_LOAD($swreg,$testreg,$index,$rs1,$rd,$imm_val,$offset,$inst,0) + +c.lhu: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *c_regs + rd_op_data: *c_regs + xlen: [32,64] + std_op: + isa: + - I_Zca_Zcb + formattype: 'clformat' + rs1_val_data: '[0]' + imm_val_data: 'gen_usign_dataset(2)' + template: |- + + // $comment + // opcode: $inst; op1:$rs1; dest:$rd; immval:$imm_val + TEST_LOAD($swreg,$testreg,$index,$rs1,$rd,$imm_val,$offset,$inst,0) + +c.lh: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *c_regs + rd_op_data: *c_regs + xlen: [32,64] + std_op: + isa: + - I_Zca_Zcb + formattype: 'clformat' + rs1_val_data: '[0]' + imm_val_data: 'gen_usign_dataset(2)' + template: |- + + // $comment + // opcode: $inst; op1:$rs1; dest:$rd; immval:$imm_val + TEST_LOAD($swreg,$testreg,$index,$rs1,$rd,$imm_val,$offset,$inst,0) + +c.sb: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *c_regs + rs2_op_data: *c_regs + xlen: [32,64] + std_op: + isa: + - I_Zca_Zcb + formattype: 'csformat' + rs1_val_data: '[0]' + rs2_val_data: 'gen_sign_dataset(xlen)' + imm_val_data: 'gen_usign_dataset(2)' + template: |- + + // $comment + // opcode: $inst; op1:$rs1; op2:$rs2; op2val:$rs2_val; immval:$imm_val + TEST_STORE($swreg,$testreg,$index,$rs1,$rs2,$rs2_val,$imm_val,$offset,$inst,0) + +c.sh: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *c_regs + rs2_op_data: *c_regs + xlen: [32,64] + std_op: + isa: + - I_Zca_Zcb + formattype: 'csformat' + rs1_val_data: '[0]' + rs2_val_data: 'gen_sign_dataset(xlen)' + imm_val_data: 'gen_usign_dataset(2)' + template: |- + + // $comment + // opcode: $inst; op1:$rs1; op2:$rs2; op2val:$rs2_val; immval:$imm_val + TEST_STORE($swreg,$testreg,$index,$rs1,$rs2,$rs2_val,$imm_val,$offset,$inst,0) + +c.sext.b: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - I_Zca_Zcb_Zbb + formattype: 'ckformat' + rs1_op_data: *c_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1=dest:$rs1 ; op1val:$rs1_val; + TEST_CRD_OP($inst, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +c.sext.h: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - I_Zca_Zcb_Zbb + formattype: 'ckformat' + rs1_op_data: *c_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)+[65408]' + template: |- + + // $comment + // opcode: $inst ; op1=dest:$rs1 ; op1val:$rs1_val; + TEST_CRD_OP($inst, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +c.zext.b: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - I_Zca_Zcb + formattype: 'ckformat' + rs1_op_data: *c_regs + rs1_val_data: 'gen_usign_dataset(xlen)+[128]' + template: |- + + // $comment + // opcode: $inst ; op1=dest:$rs1 ; op1val:$rs1_val; + TEST_CRD_OP($inst, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +c.zext.h: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - I_Zca_Zcb_Zbb + formattype: 'ckformat' + rs1_op_data: *c_regs + rs1_val_data: 'gen_usign_dataset(xlen)+[65408]' + template: |- + + // $comment + // opcode: $inst ; op1=dest:$rs1 ; op1val:$rs1_val; + TEST_CRD_OP($inst, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +c.zext.w: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - I_Zca_Zcb_Zba + formattype: 'ckformat' + rs1_op_data: *c_regs + rs1_val_data: 'gen_usign_dataset(xlen)+[65408]' + template: |- + + // $comment + // opcode: $inst ; op1=dest:$rs1 ; op1val:$rs1_val; + TEST_CRD_OP($inst, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +c.not: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - I_Zca_Zcb + formattype: 'kformat' + rs1_op_data: *c_regs + rs1_val_data: 'gen_usign_dataset(xlen)+[65408]' + template: |- + + // $comment + // opcode: $inst ; op1=dest:$rs1 ; op1val:$rs1_val; + TEST_CRD_OP($inst, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +c.mul: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *c_regs + rs2_op_data: *c_regs + xlen: [32,64] + std_op: + isa: + - IM_Zca_Zcb + formattype: 'crformat' + operation: 'hex((rs1_val * rs2_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + template: |- + + // $comment + // opcode: $inst; op1:$rs1; op2:$rs2; op1val:$rs1_val; op2val:$rs2_val + TEST_CR_OP( $inst, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +amoadd.b: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IA + formattype: 'rformat' + rs1_op_data: *all_regs_mx0 + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_AMO_OP($inst, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $offset) + +amoand.b: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IA + formattype: 'rformat' + rs1_op_data: *all_regs_mx0 + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_AMO_OP($inst, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $offset) + +amoswap.b: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IA + formattype: 'rformat' + rs1_op_data: *all_regs_mx0 + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_AMO_OP($inst, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $offset) + +amoxor.b: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IA + formattype: 'rformat' + rs1_op_data: *all_regs_mx0 + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_AMO_OP($inst, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $offset) + +amoor.b: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IA + formattype: 'rformat' + rs1_op_data: *all_regs_mx0 + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_AMO_OP($inst, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $offset) + +amomin.b: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IA + formattype: 'rformat' + rs1_op_data: *all_regs_mx0 + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_AMO_OP($inst, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $offset) + +amominu.b: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IA + formattype: 'rformat' + rs1_op_data: *all_regs_mx0 + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_AMO_OP($inst, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $offset) + +amomax.b: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IA + formattype: 'rformat' + rs1_op_data: *all_regs_mx0 + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_AMO_OP($inst, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $offset) + +amomaxu.b: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IA + formattype: 'rformat' + rs1_op_data: *all_regs_mx0 + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_AMO_OP($inst, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $offset) + +amocas.b: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZacas + formattype: 'rformat' + rs1_op_data: *all_regs_mx0 + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)' + + template: |- + + // $comment + // opcode: $inst ; dest:$rd; addr:$rs1; src:$rs2; swap_val:$rs2_val; swreg:$swreg; $offset + TEST_CAS_OP($inst, $rd, $rs1, $rs2, $rs2_val, $swreg, $offset); + +amoadd.h: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IA + formattype: 'rformat' + rs1_op_data: *all_regs_mx0 + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_AMO_OP($inst, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $offset) + +amoand.h: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IA + formattype: 'rformat' + rs1_op_data: *all_regs_mx0 + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_AMO_OP($inst, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $offset) + +amoswap.h: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IA + formattype: 'rformat' + rs1_op_data: *all_regs_mx0 + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_AMO_OP($inst, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $offset) + +amoxor.h: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IA + formattype: 'rformat' + rs1_op_data: *all_regs_mx0 + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_AMO_OP($inst, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $offset) + +amoor.h: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IA + formattype: 'rformat' + rs1_op_data: *all_regs_mx0 + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_AMO_OP($inst, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $offset) + +amomin.h: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IA + formattype: 'rformat' + rs1_op_data: *all_regs_mx0 + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_AMO_OP($inst, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $offset) + +amominu.h: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IA + formattype: 'rformat' + rs1_op_data: *all_regs_mx0 + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_AMO_OP($inst, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $offset) + +amomax.h: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IA + formattype: 'rformat' + rs1_op_data: *all_regs_mx0 + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_AMO_OP($inst, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $offset) + +amomaxu.h: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IA + formattype: 'rformat' + rs1_op_data: *all_regs_mx0 + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_AMO_OP($inst, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $offset) + +amocas.h: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZacas + formattype: 'rformat' + rs1_op_data: *all_regs_mx0 + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)' + + template: |- + + // $comment + // opcode: $inst ; dest:$rd; addr:$rs1; src:$rs2; swap_val:$rs2_val; swreg:$swreg; $offset + TEST_CAS_OP($inst, $rd, $rs1, $rs2, $rs2_val, $swreg, $offset); + +mop.rr.0: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZimop + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, 0, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +mop.rr.1: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZimop + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, 0, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +mop.rr.2: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZimop + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, 0, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +mop.rr.3: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZimop + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, 0, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +mop.rr.4: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZimop + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, 0, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +mop.rr.5: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZimop + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, 0, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +mop.rr.6: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZimop + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, 0, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +mop.rr.7: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZimop + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + rs2_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val + TEST_RR_OP($inst, $rd, $rs1, $rs2, 0, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +mop.r.0: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IZimop + operation: 'hex((rs1_val + imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)+ gen_sp_dataset(12)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_R_OP( $inst, $rd, $rs1, 0, $rs1_val, $swreg, $offset, $testreg) + +mop.r.1: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IZimop + operation: 'hex((rs1_val + imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)+ gen_sp_dataset(12)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_R_OP( $inst, $rd, $rs1, 0, $rs1_val, $swreg, $offset, $testreg) + +mop.r.2: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IZimop + operation: 'hex((rs1_val + imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)+ gen_sp_dataset(12)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_R_OP( $inst, $rd, $rs1, 0, $rs1_val, $swreg, $offset, $testreg) + +mop.r.3: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IZimop + operation: 'hex((rs1_val + imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)+ gen_sp_dataset(12)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_R_OP( $inst, $rd, $rs1, 0, $rs1_val, $swreg, $offset, $testreg) + +mop.r.4: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IZimop + operation: 'hex((rs1_val + imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)+ gen_sp_dataset(12)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_R_OP( $inst, $rd, $rs1, 0, $rs1_val, $swreg, $offset, $testreg) + +mop.r.5: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IZimop + operation: 'hex((rs1_val + imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)+ gen_sp_dataset(12)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_R_OP( $inst, $rd, $rs1, 0, $rs1_val, $swreg, $offset, $testreg) + +mop.r.6: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IZimop + operation: 'hex((rs1_val + imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)+ gen_sp_dataset(12)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_R_OP( $inst, $rd, $rs1, 0, $rs1_val, $swreg, $offset, $testreg) + +mop.r.7: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IZimop + operation: 'hex((rs1_val + imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)+ gen_sp_dataset(12)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_R_OP( $inst, $rd, $rs1, 0, $rs1_val, $swreg, $offset, $testreg) + +mop.r.8: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IZimop + operation: 'hex((rs1_val + imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)+ gen_sp_dataset(12)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_R_OP( $inst, $rd, $rs1, 0, $rs1_val, $swreg, $offset, $testreg) + +mop.r.9: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IZimop + operation: 'hex((rs1_val + imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)+ gen_sp_dataset(12)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_R_OP( $inst, $rd, $rs1, 0, $rs1_val, $swreg, $offset, $testreg) + +mop.r.10: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IZimop + operation: 'hex((rs1_val + imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)+ gen_sp_dataset(12)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_R_OP( $inst, $rd, $rs1, 0, $rs1_val, $swreg, $offset, $testreg) + +mop.r.11: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IZimop + operation: 'hex((rs1_val + imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)+ gen_sp_dataset(12)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_R_OP( $inst, $rd, $rs1, 0, $rs1_val, $swreg, $offset, $testreg) + +mop.r.12: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IZimop + operation: 'hex((rs1_val + imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)+ gen_sp_dataset(12)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_R_OP( $inst, $rd, $rs1, 0, $rs1_val, $swreg, $offset, $testreg) + +mop.r.13: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IZimop + operation: 'hex((rs1_val + imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)+ gen_sp_dataset(12)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_R_OP( $inst, $rd, $rs1, 0, $rs1_val, $swreg, $offset, $testreg) + +mop.r.14: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IZimop + operation: 'hex((rs1_val + imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)+ gen_sp_dataset(12)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_R_OP( $inst, $rd, $rs1, 0, $rs1_val, $swreg, $offset, $testreg) + +mop.r.15: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IZimop + operation: 'hex((rs1_val + imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)+ gen_sp_dataset(12)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_R_OP( $inst, $rd, $rs1, 0, $rs1_val, $swreg, $offset, $testreg) + +mop.r.16: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IZimop + operation: 'hex((rs1_val + imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)+ gen_sp_dataset(12)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_R_OP( $inst, $rd, $rs1, 0, $rs1_val, $swreg, $offset, $testreg) + +mop.r.17: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IZimop + operation: 'hex((rs1_val + imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)+ gen_sp_dataset(12)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_R_OP( $inst, $rd, $rs1, 0, $rs1_val, $swreg, $offset, $testreg) + +mop.r.18: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IZimop + operation: 'hex((rs1_val + imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)+ gen_sp_dataset(12)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_R_OP( $inst, $rd, $rs1, 0, $rs1_val, $swreg, $offset, $testreg) + +mop.r.19: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IZimop + operation: 'hex((rs1_val + imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)+ gen_sp_dataset(12)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_R_OP( $inst, $rd, $rs1, 0, $rs1_val, $swreg, $offset, $testreg) + +mop.r.20: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IZimop + operation: 'hex((rs1_val + imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)+ gen_sp_dataset(12)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_R_OP( $inst, $rd, $rs1, 0, $rs1_val, $swreg, $offset, $testreg) + +mop.r.21: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IZimop + operation: 'hex((rs1_val + imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)+ gen_sp_dataset(12)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_R_OP( $inst, $rd, $rs1, 0, $rs1_val, $swreg, $offset, $testreg) + +mop.r.22: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IZimop + operation: 'hex((rs1_val + imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)+ gen_sp_dataset(12)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_R_OP( $inst, $rd, $rs1, 0, $rs1_val, $swreg, $offset, $testreg) + +mop.r.23: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IZimop + operation: 'hex((rs1_val + imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)+ gen_sp_dataset(12)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_R_OP( $inst, $rd, $rs1, 0, $rs1_val, $swreg, $offset, $testreg) + +mop.r.24: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IZimop + operation: 'hex((rs1_val + imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)+ gen_sp_dataset(12)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_R_OP( $inst, $rd, $rs1, 0, $rs1_val, $swreg, $offset, $testreg) + +mop.r.25: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IZimop + operation: 'hex((rs1_val + imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)+ gen_sp_dataset(12)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_R_OP( $inst, $rd, $rs1, 0, $rs1_val, $swreg, $offset, $testreg) + +mop.r.26: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IZimop + operation: 'hex((rs1_val + imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)+ gen_sp_dataset(12)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_R_OP( $inst, $rd, $rs1, 0, $rs1_val, $swreg, $offset, $testreg) + +mop.r.27: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IZimop + operation: 'hex((rs1_val + imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)+ gen_sp_dataset(12)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_R_OP( $inst, $rd, $rs1, 0, $rs1_val, $swreg, $offset, $testreg) + +mop.r.28: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IZimop + operation: 'hex((rs1_val + imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)+ gen_sp_dataset(12)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_R_OP( $inst, $rd, $rs1, 0, $rs1_val, $swreg, $offset, $testreg) + +mop.r.29: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IZimop + operation: 'hex((rs1_val + imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)+ gen_sp_dataset(12)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_R_OP( $inst, $rd, $rs1, 0, $rs1_val, $swreg, $offset, $testreg) + +mop.r.30: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IZimop + operation: 'hex((rs1_val + imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)+ gen_sp_dataset(12)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_R_OP( $inst, $rd, $rs1, 0, $rs1_val, $swreg, $offset, $testreg) + +mop.r.31: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *all_regs + rd_op_data: *all_regs + xlen: [32,64] + std_op: + isa: + - IZimop + operation: 'hex((rs1_val + imm_val) & (2**(xlen)-1))' + rs1_val_data: 'gen_sign_dataset(xlen)+ gen_sp_dataset(xlen,True)' + imm_val_data: 'gen_sign_dataset(12)+ gen_sp_dataset(12)' + formattype: 'iformat' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_R_OP( $inst, $rd, $rs1, 0, $rs1_val, $swreg, $offset, $testreg) + +c.mop.1: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - ICZcmop + formattype: 'cjformat' + imm_val_data: 'gen_sign_dataset(6)' + template: |- + // $comment + // opcode:$inst; immval:$imm_val + TEST_CMOP_OP($inst, x1, $imm_val, $swreg, $testreg, $offset) + +c.mop.3: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - ICZcmop + formattype: 'cjformat' + imm_val_data: 'gen_sign_dataset(6)' + template: |- + // $comment + // opcode:$inst; immval:$imm_val + TEST_CMOP_OP($inst, x3, $imm_val, $swreg, $testreg, $offset) + +c.mop.5: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - ICZcmop + formattype: 'cjformat' + imm_val_data: 'gen_sign_dataset(6)' + template: |- + // $comment + // opcode:$inst; immval:$imm_val + TEST_CMOP_OP($inst, x5, $imm_val, $swreg, $testreg, $offset) + +c.mop.7: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - ICZcmop + formattype: 'cjformat' + imm_val_data: 'gen_sign_dataset(6)' + template: |- + // $comment + // opcode:$inst; immval:$imm_val + TEST_CMOP_OP($inst, x7, $imm_val, $swreg, $testreg, $offset) + +c.mop.9: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - ICZcmop + formattype: 'cjformat' + imm_val_data: 'gen_sign_dataset(6)' + template: |- + // $comment + // opcode:$inst; immval:$imm_val + TEST_CMOP_OP($inst, x9, $imm_val, $swreg, $testreg, $offset) + +c.mop.11: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - ICZcmop + formattype: 'cjformat' + imm_val_data: 'gen_sign_dataset(6)' + template: |- + // $comment + // opcode:$inst; immval:$imm_val + TEST_CMOP_OP($inst, x11, $imm_val, $swreg, $testreg, $offset) + +c.mop.13: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - ICZcmop + formattype: 'cjformat' + imm_val_data: 'gen_sign_dataset(6)' + template: |- + // $comment + // opcode:$inst; immval:$imm_val + TEST_CMOP_OP($inst, x13, $imm_val, $swreg, $testreg, $offset) + +c.mop.15: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - ICZcmop + formattype: 'cjformat' + imm_val_data: 'gen_sign_dataset(6)' + template: |- + // $comment + // opcode:$inst; immval:$imm_val + TEST_CMOP_OP($inst, x15, $imm_val, $swreg, $testreg, $offset) + +lpad-m: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZicfilp + formattype: 'uformat' + imm_val_data: 'gen_usign_dataset(20)+ gen_sp_dataset(20,False)' + template: |- + // $comment + // opcode: lpad ; dest:x0; immval:$imm_val + TEST_LPAD_MMODE($testreg, $swreg, $offset, $imm_val) + +lpad-s: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZicfilp + formattype: 'uformat' + imm_val_data: 'gen_usign_dataset(20)+ gen_sp_dataset(20,False)' + template: |- + // $comment + // opcode: lpad ; dest:x0; immval:$imm_val + TEST_LPAD_SMODE($testreg, $swreg, $offset, $imm_val) + +lpad-u: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZicfilp + formattype: 'uformat' + imm_val_data: 'gen_usign_dataset(20)+ gen_sp_dataset(20,False)' + template: |- + // $comment + // opcode: lpad ; dest:x0; immval:$imm_val + TEST_LPAD_UMODE($testreg, $swreg, $offset, $imm_val) + +sspushpopchk_u: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32, 64] + std_op: + isa: + - I_Zicfiss_Zicsr + formattype: 'rformat' + rs1_val_data: 'gen_sign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)' + template: |- + // $comment + TEST_SSPUSH_SSPOP_OP($swreg, $offset, $rs2_val, Umode) + +sspushpopchk_s: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32, 64] + std_op: + isa: + - I_Zicfiss_Zicsr + formattype: 'rformat' + rs1_val_data: 'gen_sign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)' + template: |- + // $comment + TEST_SSPUSH_SSPOP_OP($swreg, $offset, $rs2_val, Smode) + +c.sspushpopchk_u: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32, 64] + std_op: + isa: + - IC_Zicfiss_Zicsr + formattype: 'crformat' + rs1_val_data: 'gen_sign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)' + template: |- + // $comment + TEST_C_SSPUSH_SSPOP_OP($swreg, $offset, $rs2_val, Umode) + +c.sspushpopchk_s: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32, 64] + std_op: + isa: + - IC_Zicfiss_Zicsr + formattype: 'crformat' + rs1_val_data: 'gen_sign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)' + template: |- + // $comment + TEST_C_SSPUSH_SSPOP_OP($swreg, $offset, $rs2_val, Smode) + +ssamoswap.w_s: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IA_Zicfiss_Zicsr + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + // $comment + // opcode: $inst ; dest: $rd op1:$rs1; op2:$rs2; op1val:$rs1_val; op2val:$rs2_val; $swreg; $testreg; Priv + #ifndef ZICFISS_SETUP_DONE + .set zicfiss_setup_done, 0 + #define ZICFISS_SETUP_DONE 1 + #endif + TEST_SSAMOSWAP_OP(ssamoswap.w, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $testreg, Smode) + +ssamoswap.d_s: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IA_Zicfiss_Zicsr + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + // $comment + // opcode: $inst ; dest: $rd op1:$rs1; op2:$rs2; op1val:$rs1_val; op2val:$rs2_val; $swreg; $testreg; Priv + #ifndef ZICFISS_SETUP_DONE + .set zicfiss_setup_done, 0 + #define ZICFISS_SETUP_DONE 1 + #endif + TEST_SSAMOSWAP_OP(ssamoswap.d, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $testreg, Smode) + +ssamoswap.w_u: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IA_Zicfiss_Zicsr + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + // $comment + // opcode: $inst ; dest: $rd op1:$rs1; op2:$rs2; op1val:$rs1_val; op2val:$rs2_val; $swreg; $testreg; Priv + #ifndef ZICFISS_SETUP_DONE + .set zicfiss_setup_done, 0 + #define ZICFISS_SETUP_DONE 1 + #endif + TEST_SSAMOSWAP_OP(ssamoswap.w, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $testreg, Umode) + +ssamoswap.d_u: + sig: + stride: 2 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - IA_Zicfiss_Zicsr + formattype: 'rformat' + rs1_op_data: *all_regs + rs2_op_data: *all_regs + rd_op_data: *all_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + // $comment + // opcode: $inst ; dest: $rd op1:$rs1; op2:$rs2; op1val:$rs1_val; op2val:$rs2_val; $swreg; $testreg; Priv + #ifndef ZICFISS_SETUP_DONE + .set zicfiss_setup_done, 0 + #define ZICFISS_SETUP_DONE 1 + #endif + TEST_SSAMOSWAP_OP(ssamoswap.d, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $testreg, Umode) + +ssrdp_s: + sig: + stride: 1 + sz: 'XLEN/8' + rd_op_data: *all_regs_mx0 + xlen: [32,64] + std_op: + isa: + - I_Zicfiss_Zicsr + rs1_val_data: 'gen_sign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)' + formattype: 'rformat' + template: |- + // $comment + // opcode:ssrdp; dest: $rd; $swreg; $testreg; Priv + #ifndef ZICFISS_SETUP_DONE + .set zicfiss_setup_done, 0 + #define ZICFISS_SETUP_DONE 1 + #endif + TEST_SSRDP_OP(ssrdp, $rd, $swreg, $testreg, Smode) + +ssrdp_u: + sig: + stride: 1 + sz: 'XLEN/8' + rd_op_data: *all_regs_mx0 + xlen: [32,64] + std_op: + isa: + - I_Zicfiss_Zicsr + rs1_val_data: 'gen_sign_dataset(xlen)' + rs2_val_data: 'gen_sign_dataset(xlen)' + formattype: 'rformat' + template: |- + // $comment + // opcode:ssrdp; dest: $rd; $swreg; $testreg; Priv + #ifndef ZICFISS_SETUP_DONE + .set zicfiss_setup_done, 0 + #define ZICFISS_SETUP_DONE 1 + #endif + TEST_SSRDP_OP(ssrdp, $rd, $swreg, $testreg, Umode) diff --git a/riscv-ctg/riscv_ctg/dsp_function.py b/riscv-ctg/riscv_ctg/dsp_function.py new file mode 100644 index 000000000..4b0f12bd0 --- /dev/null +++ b/riscv-ctg/riscv_ctg/dsp_function.py @@ -0,0 +1,243 @@ +def simd_val_vars(operand, xlen, bit_width): + ''' + This function generates the operand value variables for SIMD elements of the given operand. + + :param operand: a string indicating the name of the desired operand. + :param xlen: an integer indicating the XLEN value to be used. + :param bit_width: an integer indicating the element bit width for the current SIMD format. + + :type operand: str + :type xlen: int + :type bit_width: int + :return: a list containing the element value variables for the given operand. + ''' + val_list = [] + nelms = xlen // bit_width + if bit_width == 8: + sz = "b" + elif bit_width == 16: + sz = "h" + elif bit_width == 32: + sz = "w" + else: + sz = "d" + for i in range(nelms): + val_list += [f"{operand}_{sz}{i}_val"] + return val_list + +def get_fmt_sz(bit_width): + if bit_width == 8: + fmt = f"#02x" + elif bit_width == 16: + fmt = f"#04x" + elif bit_width == 32: + fmt = f"#08x" + else: + fmt = f"#016x" + if bit_width == 8: + sz = "b" + elif bit_width == 16: + sz = "h" + elif bit_width == 32: + sz = "w" + else: + sz = "d" + + return fmt, sz + +def gen_fmt(bit_width): + ''' + This function generate fmt string by bit_width. + + :param bit_width: an integer indicating the element bit width of the current RVP instruction. + + :type bit_width: int + ''' + + if bit_width == 8: + fmt = f"#02x" + elif bit_width == 16: + fmt = f"#04x" + elif bit_width == 32: + fmt = f"#08x" + else: + fmt = f"#016x" + return fmt + +def gen_sz(bit_width): + ''' + This function generate size string by bit_width. + + :param bit_width: an integer indicating the element bit width of the current RVP instruction. + + :type bit_width: int + ''' + + if bit_width == 8: + sz = "b" + elif bit_width == 16: + sz = "h" + elif bit_width == 32: + sz = "w" + else: + sz = "d" + return sz + +def concat_simd_data(instr_dict, xlen, _bit_width): + ''' + This function concatenates all element of a SIMD register into a single value in the hex format. + + :param instr_dict: a dict holding metadata and operand data for the current instruction. + :param xlen: an integer indicating the XLEN value to be used. + :param bit_width: an integer or string of integer pair indicating the element bit width of rs1/rs2 of the current RVP instruction. + + :type instr_dict: dict + :type xlen: int + :type bit_width: int + ''' + if type(_bit_width)==str: + _bit_width = eval(_bit_width) + + if type(_bit_width)==tuple: + bit_width1, bit_width2 = _bit_width + else: + bit_width1, bit_width2 = _bit_width, _bit_width + + for instr in instr_dict: + if 'rs1' in instr: + twocompl_offset = 1<= 3 and p64_profile[1]=='p' else xlen + rs2_width = 64 if len(p64_profile) >= 3 and p64_profile[2]=='p' else xlen + rd_width = 64 if len(p64_profile) >= 3 and p64_profile[0]=='p' else xlen + else: + rs1_width = 128 if len(p64_profile) >= 3 and p64_profile[1]=='p' else xlen + rs2_width = 128 if len(p64_profile) >= 3 and p64_profile[2]=='p' else xlen + rd_width = 128 if len(p64_profile) >= 3 and p64_profile[0]=='p' else xlen + + for instr in instr_dict: + if 'rs1' in instr: + twocompl_offset = 1< xlen: + instr['rs1_val'] = format(0xffffffff & rs1_val, f"#0{2+xlen//4}x") + instr['rs1_val_hi'] = format(0xffffffff & (rs1_val>>32), f"#0{2+xlen//4}x") + instr['rs1_hi'] = incr_reg_num(instr['rs1']) + else: + instr['rs1_val'] = format(rs1_val, f"#0{2+xlen//4}x") + if rs1_width == 64 and (len(p64_profile) >= 3): + instr['rs1_val64'] = format(rs1_val, f"#018x") + + if 'rs2' in instr: + twocompl_offset = 1< xlen: + instr['rs2_val'] = format(0xffffffff & rs2_val, f"#0{2+xlen//4}x") + instr['rs2_val_hi'] = format(0xffffffff & (rs2_val>>32), f"#0{2+xlen//4}x") + instr['rs2_hi'] = incr_reg_num(instr['rs2']) + else: + instr['rs2_val'] = format(rs2_val, f"#0{2+xlen//4}x") + if rs2_width == 64 and (len(p64_profile) >= 3): + instr['rs2_val64'] = format(rs2_val, f"#018x") + + if 'rd' in instr and rd_width > xlen: + instr['rd_hi'] = incr_reg_num(instr['rd']) + + if 'imm_val' in instr: + imm_val = int(instr['imm_val']) + instr['imm_val'] = format(imm_val, f"#0x") diff --git a/riscv-ctg/riscv_ctg/function_generators.py b/riscv-ctg/riscv_ctg/function_generators.py new file mode 100644 index 000000000..14d066451 --- /dev/null +++ b/riscv-ctg/riscv_ctg/function_generators.py @@ -0,0 +1,260 @@ +def get_cond_generator(opcode,fmt,val_vars,xlen,flen): + def fr64_generator(req_val_comb): + def condition(*argv): + rs1_val = argv[0] + rs2_val = argv[1] + rm = argv[2] + bin_val = '{:064b}'.format(rs1_val) + fs1 = int(bin_val[0],2) + fe1 = int(bin_val[1:12],2) + fm1 = int(bin_val[12:],2) + bin_val = '{:064b}'.format(rs2_val) + fs2 = int(bin_val[0],2) + fe2 = int(bin_val[1:12],2) + fm2 = int(bin_val[12:],2) + return eval(req_val_comb) + return condition + + def fr32_generator(req_val_comb): + def condition(*argv): + rs1_val = argv[0] + rs2_val = argv[1] + rm = argv[2] + bin_val = '{:032b}'.format(rs1_val) + fs1 = int(bin_val[0],2) + fe1 = int(bin_val[1:9],2) + fm1 = int(bin_val[9:],2) + bin_val = '{:032b}'.format(rs2_val) + fs2 = int(bin_val[0],2) + fe2 = int(bin_val[1:9],2) + fm2 = int(bin_val[9:],2) + return eval(req_val_comb) + return condition + + def fsr64_generator(req_val_comb): + def condition(*argv): + rs1_val = argv[0] + rm = argv[1] + bin_val = '{:064b}'.format(rs1_val) + fs1 = int(bin_val[0],2) + fe1 = int(bin_val[1:12],2) + fm1 = int(bin_val[12:],2) + return eval(req_val_comb) + return condition + + def fsr32_generator(req_val_comb): + def condition(*argv): + rs1_val = argv[0] + rm = argv[1] + bin_val = '{:032b}'.format(rs1_val) + fs1 = int(bin_val[0],2) + fe1 = int(bin_val[1:9],2) + fm1 = int(bin_val[9:],2) + return eval(req_val_comb) + return condition + + def fr4_64_generator(req_val_comb): + def condition(*argv): + rs1_val = argv[0] + rs2_val = argv[1] + rs3_val = argv[2] + rm = argv[3] + bin_val = '{:064b}'.format(rs1_val) + fs1 = int(bin_val[0],2) + fe1 = int(bin_val[1:12],2) + fm1 = int(bin_val[12:],2) + bin_val = '{:064b}'.format(rs2_val) + fs2 = int(bin_val[0],2) + fe2 = int(bin_val[1:12],2) + fm2 = int(bin_val[12:],2) + bin_val = '{:064b}'.format(rs3_val) + fs3 = int(bin_val[0],2) + fe3 = int(bin_val[1:12],2) + fm3 = int(bin_val[12:],2) + return eval(req_val_comb) + return condition + + def fr4_32_generator(req_val_comb): + def condition(*argv): + rs1_val = argv[0] + rs2_val = argv[1] + rs3_val = argv[2] + rm = argv[3] + bin_val = '{:032b}'.format(rs1_val) + fs1 = int(bin_val[0],2) + fe1 = int(bin_val[1:9],2) + fm1 = int(bin_val[9:],2) + bin_val = '{:032b}'.format(rs2_val) + fs2 = int(bin_val[0],2) + fe2 = int(bin_val[1:9],2) + fm2 = int(bin_val[9:],2) + bin_val = '{:032b}'.format(rs3_val) + fs3 = int(bin_val[0],2) + fe3 = int(bin_val[1:9],2) + fm3 = int(bin_val[9:],2) + return eval(req_val_comb) + return condition + + def i_generator(req_val_comb): + def condition(*argv): + for var,val in zip(val_vars,argv): + locals()[var]=val + return eval(req_val_comb) + return condition + + if opcode[0] == 'f' and 'fence' not in opcode: + if fmt == 'frformat': + if flen == 32: + return fr32_generator + else: + return fr64_generator + elif fmt == 'fsrformat': + if flen == 32: + return fsr32_generator + else: + return fsr64_generator + elif fmt == 'fr4format': + if flen == 32: + return fr4_32_generator + else: + return fr4_64_generator + else: + return i_generator + +def get_filter_generator(opcode,fmt,val_vars,xlen,flen): + def fr64_generator(argv): + bin_val1 = '{:064b}'.format(argv[0]) + bin_val2 = '{:064b}'.format(argv[1]) + local = { + 'rs1_val': argv[0] + ,'rs2_val': argv[1] + ,'rm': argv[2] + ,'fs1': int(bin_val1[0],2) + ,'fe1': int(bin_val1[1:12],2) + ,'fm1': int(bin_val1[12:],2) + ,'fs2': int(bin_val2[0],2) + ,'fe2': int(bin_val2[1:12],2) + ,'fm2': int(bin_val2[12:],2) + } + def filter_func(cond): + return eval(cond,{},local) + return filter_func + + def fr32_generator(argv): + bin_val1 = '{:032b}'.format(argv[0]) + bin_val2 = '{:032b}'.format(argv[1]) + local = { + 'rs1_val': argv[0] + ,'rs2_val': argv[1] + ,'rm': argv[2] + ,'fs1': int(bin_val1[0],2) + ,'fe1': int(bin_val1[1:9],2) + ,'fm1': int(bin_val1[9:],2) + ,'fs2': int(bin_val2[0],2) + ,'fe2': int(bin_val2[1:9],2) + ,'fm2': int(bin_val2[9:],2) + } + def filter_func(cond): + return eval(cond,{},local) + return filter_func + + def fsr64_generator(argv): + bin_val1 = '{:064b}'.format(argv[0]) + local = { + 'rs1_val': argv[0] + ,'rm': argv[1] + ,'fs1': int(bin_val1[0],2) + ,'fe1': int(bin_val1[1:12],2) + ,'fm1': int(bin_val1[12:],2) + } + def filter_func(cond): + return eval(cond,{},local) + return filter_func + + def fsr32_generator(argv): + bin_val1 = '{:032b}'.format(argv[0]) + local = { + 'rs1_val': argv[0] + ,'rm': argv[1] + ,'fs1': int(bin_val1[0],2) + ,'fe1': int(bin_val1[1:9],2) + ,'fm1': int(bin_val1[9:],2) + } + def filter_func(cond): + return eval(cond,{},local) + return filter_func + + def fr4_64_generator(argv): + bin_val1 = '{:064b}'.format(argv[0]) + bin_val2 = '{:064b}'.format(argv[1]) + bin_val3 = '{:064b}'.format(argv[2]) + local = { + 'rs1_val': argv[0] + ,'rs2_val': argv[1] + ,'rs3_val': argv[2] + ,'rm': argv[3] + ,'fs1': int(bin_val1[0],2) + ,'fe1': int(bin_val1[1:12],2) + ,'fm1': int(bin_val1[12:],2) + ,'fs2': int(bin_val2[0],2) + ,'fe2': int(bin_val2[1:12],2) + ,'fm2': int(bin_val2[12:],2) + ,'fs3': int(bin_val3[0],2) + ,'fe3': int(bin_val3[1:12],2) + ,'fm3': int(bin_val3[12:],2) + } + def filter_func(cond): + return eval(cond,{},local) + return filter_func + + def fr4_32_generator(argv): + bin_val1 = '{:032b}'.format(argv[0]) + bin_val2 = '{:032b}'.format(argv[1]) + bin_val3 = '{:032b}'.format(argv[2]) + local = { + 'rs1_val': argv[0] + ,'rs2_val': argv[1] + ,'rs3_val': argv[2] + ,'rm': argv[3] + ,'fs1': int(bin_val1[0],2) + ,'fe1': int(bin_val1[1:9],2) + ,'fm1': int(bin_val1[9:],2) + ,'fs2': int(bin_val2[0],2) + ,'fe2': int(bin_val2[1:9],2) + ,'fm2': int(bin_val2[9:],2) + ,'fs3': int(bin_val3[0],2) + ,'fe3': int(bin_val3[1:9],2) + ,'fm3': int(bin_val3[9:],2) + } + def filter_func(cond): + return eval(cond,{},local) + return filter_func + + + def i_generator(argv): + local = {} + for var,val in zip(val_vars,argv): + local[var]=val + def condition(req_val_comb): + return eval(req_val_comb,{},local) + return condition + + if opcode[0] == 'f' and 'fence' not in opcode: + if fmt == 'frformat': + if flen == 32: + return fr32_generator + else: + return fr64_generator + elif fmt == 'fsrformat': + if flen == 32: + return fsr32_generator + else: + return fsr64_generator + elif fmt == 'fr4format': + if flen == 32: + return fr4_32_generator + else: + return fr4_64_generator + else: + return i_generator + diff --git a/riscv-ctg/riscv_ctg/generator.py b/riscv-ctg/riscv_ctg/generator.py new file mode 100644 index 000000000..9f3fc8d0e --- /dev/null +++ b/riscv-ctg/riscv_ctg/generator.py @@ -0,0 +1,1452 @@ +# See LICENSE.incore for details +import random +from collections import defaultdict +from constraint import * +import re +from riscv_ctg.constants import * +from riscv_ctg.log import logger +from riscv_ctg.helpers import * +from riscv_isac.InstructionObject import instructionObject +import time +from math import * +import struct +import sys +import itertools +import re + +# F +one_operand_finstructions = ["fsqrt.s","fmv.x.w","fcvt.wu.s","fcvt.w.s","fclass.s","fcvt.l.s","fcvt.lu.s","fcvt.s.l","fcvt.s.lu"] +two_operand_finstructions = ["fadd.s","fsub.s","fmul.s","fdiv.s","fmax.s","fmin.s","feq.s","flt.s","fle.s","fsgnj.s","fsgnjn.s","fsgnjx.s"] +three_operand_finstructions = ["fmadd.s","fmsub.s","fnmadd.s","fnmsub.s"] +# Zfa/F: +one_operand_finstructions += ["fround.s", "froundnx.s", "fcvtmod.w.d","fmvh.x.d"] +two_operand_finstructions += ["fmaxm.s", "fminm.s", "fmvp.d.x", "fleq.s", "fltq.s"] + +# D +one_operand_dinstructions = ["fsqrt.d","fclass.d","fcvt.w.d","fcvt.wu.d","fcvt.d.w","fcvt.d.wu","fcvt.d.s","fcvt.s.d"] +two_operand_dinstructions = ["fadd.d","fsub.d","fmul.d","fdiv.d","fmax.d","fmin.d","feq.d","flt.d","fle.d","fsgnj.d","fsgnjn.d","fsgnjx.d"] +three_operand_dinstructions = ["fmadd.d","fmsub.d","fnmadd.d","fnmsub.d"] + +# H +one_operand_hinstructions = ["fsqrt.h","fclass.h","fcvt.w.h","fcvt.wu.h","fcvt.h.w","fcvt.h.wu","fcvt.h.l","fcvt.h.lu","fcvt.l.h","fcvt.d.h","fcvt.h.d","fcvt.s.h","fcvt.s.h"] +two_operand_hinstructions = ["fadd.h","fsub.h","fmul.h","fdiv.h","fmax.h","fmin.h","feq.h","flt.h","fle.h","fsgnj.h","fsgnjn.h","fsgnjx.h"] +three_operand_hinstructions = ["fmadd.h","fmsub.h","fnmadd.h","fnmsub.h"] + +# Zfa/D: +one_operand_dinstructions += ["fround.d", "froundnx.d"] +two_operand_dinstructions += ["fmaxm.d", "fminm.d", "fleq.d", "fltq.d"] + + +def is_fp_instruction(insn): + ''' + Takes an instruction string (e.g. 'fadd.s') and returns True if it is a FP instruction. + The function is compatible with all existing and future RISC-V ISA extensions. + + :param insn: String representing an instruction (e.g. 'fadd.s', 'lw') + ''' + return type(insn) == str and insn.lower()[0] == 'f' + + +from riscv_ctg.dsp_function import * + +twos_xlen = lambda x: twos(x,xlen) + +def toint(x: str): + if '0x' in x: + return int(x,16) + else: + return int(x) + +def get_rm(opcode): + insns = ['fsgnj','fle','flt','feq','fclass','fmv','flw','fsw','fld','fsd','fmin','fmax', + 'fcvt.d.s', 'fcvt.d.w','fcvt.d.wu'] + insns += ['fminm', 'fmaxm'] + if any([x in opcode for x in insns]): + return [] + else: + return ['rm_val'] + +OPS = { + 'rformat': ['rs1', 'rs2', 'rd'], + 'r4format': ['rs1', 'rs2', 'rs3', 'rd'], + 'iformat': ['rs1', 'rd'], + 'sformat': ['rs1', 'rs2'], + 'bsformat': ['rs1', 'rs2', 'rd'], + 'bformat': ['rs1', 'rs2'], + 'uformat': ['rd'], + 'jformat': ['rd'], + 'crformat': ['rs1', 'rs2'], + 'cmvformat': ['rd', 'rs2'], + 'ciformat': ['rd'], + 'cssformat': ['rs2'], + 'ciwformat': ['rd'], + 'clformat': ['rs1', 'rd'], + 'csformat': ['rs1', 'rs2'], + 'caformat': ['rs1', 'rs2'], + 'cuformat': ['rs1'], + 'cbformat': ['rs1'], + 'clbformat': ['rs1','rd'], + 'clhformat': ['rs1','rd'], + 'csbformat': ['rs1','rs2'], + 'cshformat': ['rs1','rs2'], + 'cjformat': [], + 'ckformat': ['rs1'], + 'kformat': ['rs1','rd'], + 'ckformat': ['rs1'], + # 'frformat': ['rs1', 'rs2', 'rd'], + 'fsrformat': ['rs1', 'rd'], + # 'fr4format': ['rs1', 'rs2', 'rs3', 'rd'], + 'pbrrformat': ['rs1', 'rs2', 'rd'], + 'phrrformat': ['rs1', 'rs2', 'rd'], + 'pbrformat': ['rs1', 'rd'], + 'phrformat': ['rs1', 'rd'], + 'pbriformat': ['rs1', 'rd'], + 'phriformat': ['rs1', 'rd'], + 'psbrrformat': ['rs1', 'rs2', 'rd'], + 'pshrrformat': ['rs1', 'rs2', 'rd'], + 'pwrrformat': ['rs1', 'rs2', 'rd'], + 'pwriformat': ['rs1', 'rd'], + 'pwrformat': ['rs1', 'rd'], + 'pswrrformat': ['rs1', 'rs2', 'rd'], + 'pwhrrformat': ['rs1', 'rs2', 'rd'], + 'pphrrformat': ['rs1', 'rs2', 'rd'], + 'ppbrrformat': ['rs1', 'rs2', 'rd'], + 'prrformat': ['rs1', 'rs2', 'rd'], + 'prrrformat': ['rs1', 'rs2', 'rs3', 'rd'], + 'dcasrformat': ['rs1', 'rs2', 'rd'] +} +''' Dictionary mapping instruction formats to operands used by those formats ''' + +VALS = { + 'rformat': "['rs1_val', 'rs2_val'] + ((get_rm(opcode)+['fcsr']) if is_fext else []) + \ + ([] if not is_nan_box else ['rs{0}_nan_prefix'.format(x) for x in range(1,3)]) + \ + (['rs{0}_sgn_prefix'.format(x) for x in range(1,3)] if is_sgn_extd else [])", + 'r4format': "['rs1_val', 'rs2_val', 'rs3_val'] + (['rm_val','fcsr'] if is_fext else []) + \ + ([] if not is_nan_box else ['rs{0}_nan_prefix'.format(x) for x in range(1,4)]) + \ + (['rs{0}_sgn_prefix'.format(x) for x in range(1,4)] if is_sgn_extd else [])", + 'iformat': "['rs1_val', 'imm_val'] + ([] if not is_fext else ['fcsr'])", + 'sformat': "['rs1_val', 'rs2_val', 'imm_val'] + ([] if not is_fext else ['fcsr'])", + 'bsformat': "['rs1_val', 'rs2_val', 'imm_val']", + 'bformat': "['rs1_val', 'rs2_val', 'imm_val']", + 'uformat': "['imm_val']", + 'jformat': "['imm_val']", + 'crformat': "['rs1_val', 'rs2_val']", + 'cmvformat': "['rs2_val']", + 'ciformat': "['rs1_val', 'imm_val']", + 'cssformat': "['rs2_val', 'imm_val']", + 'ciwformat': "['imm_val']", + 'clformat': "['rs1_val', 'imm_val', 'fcsr']", + 'cuformat': "['rs1_val']", + 'clbformat': "['rs1_val','imm_val']", + 'clhformat': "['rs1_val','imm_val']", + 'csbformat': "['rs1_val','rs2_val','imm_val']", + 'cshformat': "['rs1_val','rs2_val','imm_val']", + 'csformat': "['rs1_val', 'rs2_val', 'imm_val']", + 'caformat': "['rs1_val', 'rs2_val']", + 'cbformat': "['rs1_val', 'imm_val']", + 'cjformat': "['imm_val']", + 'ckformat': "['rs1_val']", + 'kformat': "['rs1_val']", + 'ckformat': "['rs1_val']", + # 'frformat': "['rs1_val', 'rs2_val', 'rm_val', 'fcsr']", + 'fsrformat': "['rs1_val','fcsr'] + get_rm(opcode) + \ + ([] if not is_nan_box else ['rs1_nan_prefix']) + \ + (['rs1_sgn_prefix'] if is_sgn_extd else [])", + # 'fr4format': "['rs1_val', 'rs2_val', 'rs3_val', 'rm_val', 'fcsr']", + 'pbrrformat': 'simd_val_vars("rs1", xlen, 8) + simd_val_vars("rs2", xlen, 8)', + 'phrrformat': 'simd_val_vars("rs1", xlen, 16) + simd_val_vars("rs2", xlen, 16)', + 'pbrformat': 'simd_val_vars("rs1", xlen, 8)', + 'phrformat': 'simd_val_vars("rs1", xlen, 16)', + 'pbriformat': 'simd_val_vars("rs1", xlen, 8) + ["imm_val"]', + 'phriformat': 'simd_val_vars("rs1", xlen, 16) + ["imm_val"]', + 'psbrrformat': 'simd_val_vars("rs1", xlen, 8) + ["rs2_val"]', + 'pshrrformat': 'simd_val_vars("rs1", xlen, 16) + ["rs2_val"]', + 'pwrrformat': 'simd_val_vars("rs1", xlen, 32) + simd_val_vars("rs2", xlen, 32)', + 'pwriformat': 'simd_val_vars("rs1", xlen, 32) + ["imm_val"]', + 'pwrformat': 'simd_val_vars("rs1", xlen, 32)', + 'pswrrformat': 'simd_val_vars("rs1", xlen, 32) + ["rs2_val"]', + 'pwhrrformat': 'simd_val_vars("rs1", xlen, 32) + simd_val_vars("rs2", xlen, 16)', + 'pphrrformat': '["rs1_val"] + simd_val_vars("rs2", xlen, 16)', + 'ppbrrformat': '["rs1_val"] + simd_val_vars("rs2", xlen, 8)', + 'prrformat': '["rs1_val", "rs2_val"]', + 'prrrformat': "['rs1_val', 'rs2_val' , 'rs3_val']", + 'dcasrformat': '["rs1_val", "rs2_val"]' +} +''' Dictionary mapping instruction formats to operand value variables used by those formats ''' + + + + +def isInt(s): + ''' + Utility function to check if the variable is an int type. Returns False if + not. + ''' + try: + int(s) + return True + except ValueError: + return False + +def get_default_registers(ops, datasets): + problem = Problem() + not_x0 = lambda x: x not in ['x0'] + + for op in ops: + dataset = datasets[op] + # problem.addVariable(op,list(random.sample(dataset, len(dataset)))) + problem.addVariable(op,dataset) + problem.addConstraint(not_x0,tuple([op])) + if len(ops) > 1: + cond = " and ".join(["!=".join(x) for x in itertools.combinations(ops,2) if x[0]!=x[1]]) + else: + cond = 'True' + def unique_constraint(*args): + for var,val in zip(ops,args): + locals()[var] = val + return eval(cond) + problem.addConstraint(unique_constraint,tuple(ops)) + solution = None + count = 0 + while solution is None and count < 5: + solution = problem.getSolution() + count += 1 + if count == 5: + return [] + else: + return solution + +class Generator(): + ''' + A generator class to generate RISC-V assembly tests for a given instruction + format, opcode and a set of coverpoints. + + :param fmt: the RISC-V instruction format type to be used for the test generation. + :param opnode: dictionary node from the attributes YAML that is to be used in the test generation. + :param opcode: name of the instruction opcode. + :param randomization: a boolean variable indicating if the random constraint solvers must be employed. + :param xl: an integer indicating the XLEN value to be used. + :param base_isa_str: The base isa to be used for the tests. One of [rv32e,rv32i,rv64i] + + :type fmt: str + :type opnode: dict + :type opcode: str + :type randomization: bool + :type xl: int + :type base_isa_str: str + ''' + def __init__(self,fmt,opnode,opcode,randomization, xl, fl, ifl ,base_isa_str,inxFlag): + ''' + This is a Constructor function which initializes various class variables + depending on the arguments. + + The function also creates a dictionary of datasets for each operand. The + dictionary basically indicates what registers from the register file are to be used + when generating solutions for coverpoints. The datasets are limited to + to reduce the time taken by solvers to arrive at a solution. + + A similar dictionary is created for the values to be used by the operand + registers. + + ''' + global xlen + global flen + global iflen + global base_isa + xlen = xl + flen = fl + iflen = ifl + base_isa = base_isa_str + + + is_nan_box = False + is_fext = any(['F' in x or 'D' in x or 'Zfh' in x or 'Zfinx' in x for x in opnode['isa']]) + is_sgn_extd = True if (inxFlag and iflen ifl: + is_int_src = any([opcode.endswith(x) for x in ['.x','.w','.l','.wu','.lu']]) + is_nan_box = not is_int_src and is_sgn_extd + + self.xlen = xl + self.flen = fl + self.iflen = ifl + self.base_isa = base_isa_str + self.fmt = fmt + self.opcode = opcode + self.op_vars = OPS[fmt] + self.val_vars = eval(VALS[fmt]) + self.is_fext = is_fext + self.is_nan_box = is_nan_box + self.inxFlag = inxFlag + self.is_sgn_extd = is_sgn_extd + + if opcode in ['sw', 'sh', 'sb', 'lw', 'lhu', 'lh', 'lb', 'lbu', 'ld', 'lwu', 'sd',"jal","beq","bge","bgeu","blt","bltu","bne","jalr","c.jalr","c.jr","flw","fsw","fld","fsd","flh","fsh","c.lbu","c.lhu","c.lh","c.sb","c.sh","c.flw"]: + self.val_vars = self.val_vars + ['ea_align'] + self.template = opnode['template'] + self.opnode = opnode + # self.stride = opnode['stride'] + if 'operation' in opnode: + self.operation = opnode['operation'] + else: + self.operation = None + datasets = {} + i=10 + for entry in self.op_vars: + key = entry+"_op_data" + if key in opnode: + datasets[entry] = eval(opnode[key]) + else: + datasets[entry] = ['x'+str(i)] + i+=1 + for entry in self.val_vars: + key = entry+"_data" + if key in opnode: + datasets[entry] = eval(opnode[key]) + else: + logger.warning("{0} not defined for {1}. Defaulting to [0].".format(key,self.opcode)) + datasets[entry] = [0] + + self.datasets = datasets + self.random=randomization + self.default_regs = get_default_registers(self.op_vars, self.datasets) + + def opcomb(self, cgf): + ''' + This function finds the solutions for the various operand combinations + defined by the coverpoints in the CGF under the "op_comb" node of the + covergroup. + + Depending on the registers chosen in the datasets, a contraint is created + to ensure that all those registers occur atleast once in the respective + operand/destination location in the instruction. These contraints are + then supplied to the solver for solutions + + If randomization is enabled we use the ``MinConflictsSolver`` solver to + find solutions. + + If harcoded registers are given in the cgf file, then for the conditions other + than the first one, there will be No Solution. To solve that problem, some code + is written which will find the required register in the condition and generate the + solution normally. + + :param cgf: a covergroup in cgf format containing the set of coverpoints to be satisfied. + + :type cgf: dict + + :return: a dictionary of solutions for the various operand combinations specified in the CGF file. + ''' + logger.debug(self.opcode + ' : Generating OpComb') + solutions = [] + op_conds = {} + opcomb_value = cgf.get("op_comb") + if "op_comb" in cgf: + op_comb = set(cgf["op_comb"]) + else: + op_comb = set([]) + for op in self.op_vars: + if op in cgf: + op_conds[op] = set(cgf[op]) + else: + op_conds[op] = set([]) + individual = False + nodiff = False + construct_constraint = lambda val: (lambda x: bool(x in val)) + while any([len(op_conds[x])!=0 for x in op_conds]+[len(op_comb)!=0]): + cond_str = '' + cond_vars = [] + if self.random: + problem = Problem(MinConflictsSolver()) + else: + problem = Problem() + + done = False + for var in self.op_vars: + problem.addVariable(var, list(self.datasets[var])) + if op_conds[var] and not(individual and done): + cond_vars.append(var) + problem.addConstraint(construct_constraint(op_conds[var]),tuple([var])) + done = True + if op_comb: + cond = op_comb.pop() + cond_str += cond+", " + def comb_constraint(*args): + for var,val in zip(self.op_vars,args): + locals()[var] = val + return eval(cond) + problem.addConstraint(comb_constraint,tuple(self.op_vars)) + elif not nodiff: + problem.addConstraint(AllDifferentConstraint()) + count = 0 + solution = problem.getSolution() + while solution is None and count < 5: + if opcomb_value: + for i in opcomb_value: + opcomb_match = re.search(r'x\d{1,2}', i) + if opcomb_match is not None: + pattern = r'(?:rs1|rs2|rd) == "(x\d+)"' + matches = re.findall(pattern, cond) + if not matches or any(int(match[1:]) > 31 for match in matches): + result = None + else: + result = matches + for match in result: + op_conds['rs1'].add(match) + op_conds['rs2'].add(match) + op_conds['rd'].add(match) + op_comb.add(cond) + break + solution = problem.getSolution() + count = count + 1 + + if solution is None: + if individual: + if nodiff: + logger.warn(self.opcode + " : Cannot find solution for Op combination") + break + else: + nodiff = True + else: + individual = True + continue + op_tuple = [] + for key in self.op_vars: + op_tuple.append(solution[key]) + op_conds[key].discard(solution[key]) + + def eval_func(cond): + for var,val in zip(self.op_vars,op_tuple): + locals()[var] = val + return eval(cond) + sat_set = set(filter(eval_func,op_comb)) + cond_str += ", ".join([var+"=="+solution[var] for var in cond_vars]+list(sat_set)) + op_tuple.append(cond_str) + problem.reset() + solutions.append( tuple(op_tuple) ) + + return solutions + + def valcomb(self, cgf): + ''' + This function finds the solutions for the various value combinations + defined by the coverpoints in the CGF under the "val_comb" node of the + covergroup. + + The constraints here are quite simply taken as `eval` strings from the CGF val_comb + nodes itself. + + If randomization is enabled we use the ``MinConflictsSolver`` solver to + find solutions. + + :param cgf: a covergroup in cgf format containing the set of coverpoints to be satisfied. + + :type cgf: dict + + :return: a dictionary of solutions for the various value combinations specified in the CGF file. + ''' + logger.debug(self.opcode + ' : Generating ValComb') + if 'val_comb' not in cgf: + return [] + val_comb = [] + + conds = list(cgf['val_comb'].keys()) + inds = set(range(len(conds))) + merge = True + if 'fcvt' in self.opcode or 'fmv' in self.opcode: + if self.opcode.split(".")[-1] in ['x','w','wu','l','lu']: + merge = "fmv.x.w" in self.opcode + while inds: + req_val_comb = conds[inds.pop()] + if("#nosat" in req_val_comb): + d={} + soln = [] + req_val_comb_minus_comm = req_val_comb.split("#")[0] + x = req_val_comb_minus_comm.split(" and ") + + if self.is_fext: + # fs + fe + fm -> Combiner Script + try: + d = merge_fields_f(self.val_vars,req_val_comb,self.flen,self.iflen,merge,self.inxFlag) + except ExtractException as e: + logger.warning("Valcomb skip: "+str(e)) + continue + else: + for i in self.val_vars: + for j in x: + if i in j: + if(d.get(i,"None") == "None"): + d[i] = j.split("==")[1] + else: + logger.error("Invalid Coverpoint: More than one value of "+ i +" found!") + sys.exit(1) + if(set(d.keys()) != set(self.val_vars)): + logger.warning( + "Valcomb skip: Cannot bypass SAT Solver for partially defined coverpoints!"\ + + str(req_val_comb)) + continue + for y in self.val_vars: + soln.append(d[y]) + + soln.append(req_val_comb_minus_comm) + val_tuple = soln + else: + if self.random: + problem = Problem(MinConflictsSolver()) + else: + problem = Problem() + + for var in self.val_vars: + if var == 'ea_align' and var not in req_val_comb: + problem.addVariable(var, [0]) + else: + problem.addVariable(var, self.datasets[var]) + + def condition(*argv): + for var,val in zip(self.val_vars,argv): + locals()[var]=val + return eval(req_val_comb) + + problem.addConstraint(condition,tuple(self.val_vars)) + # if boundconstraint: + # problem.addConstraint(boundconstraint,tuple(['rs1_val', 'imm_val'])) + solution = problem.getSolution() + count = 0 + while (solution is None and count < 5): + solution = problem.getSolution() + count+=1 + if solution is None: + logger.warn(self.opcode + " : Cannot find solution for Val condition "+str(req_val_comb)) + continue + val_tuple = [] + for i,key in enumerate(self.val_vars): + val_tuple.append(solution[key]) + + def eval_func(cond): + for var,val in zip(self.val_vars,val_tuple): + locals()[var] = val + return eval(cond) + sat_set=set(filter(lambda x: eval_func(conds[x]),inds)) + inds = inds - sat_set + val_tuple.append(req_val_comb+', '+', '.join([conds[i] for i in sat_set])) + problem.reset() + val_comb.append( tuple(val_tuple) ) + return val_comb + + def __jfmt_instr__(self,op=None,val=None): + cond_str = '' + if op: + cond_str += op[-1]+', ' + if val: + cond_str += val[-1] + instr = {'inst':self.opcode,'index':'0', 'comment':cond_str} + labelize = lambda x: (str((-x)%2**21),'1b') if x < 0 else (str((x%2**21)),'3f') + if op: + for var,reg in zip(self.op_vars,op): + instr[var] = str(reg) + else: + for i,var in enumerate(self.op_vars): + if self.opcode[0] == 'f' and 'fence' not in self.opcode: + if self.opnode[var+'_op_data'][2] == 'f': + instr[var] = 'f'+str(i+10) + else: + instr[var] = 'x'+str(i+10) + else: + instr[var] = 'x'+str(i+10) + if val: + for i,var in enumerate(self.val_vars): + if var == "imm_val": + instr[var],instr['label'] = labelize(val[i]) + else: + instr[var] = str(val[i]) + else: + for var in self.val_vars: + if var == "imm_val": + instr[var],instr['label'] = '0', '3f' + else: + instr[var] = '0' + return instr + + def __bfmt_instr__(self,op=None,val=None): + cond_str = '' + if op: + cond_str += op[-1]+', ' + if val: + cond_str += val[-1] + instr = {'inst':self.opcode,'index':'0', 'comment':cond_str} + + + labelize = lambda x: (str((-x)%2048),'1b') if x < 0 else (str((x%2048)),'3f') + + if op: + for var,reg in zip(self.op_vars,op): + instr[var] = str(reg) + else: + for i,var in enumerate(self.op_vars): + instr[var] = 'x'+str(i+10) + if val: + for i,var in enumerate(self.val_vars): + if var == "imm_val": + instr[var],instr['label'] = labelize(val[i]) + else: + instr[var] = str(val[i]) + else: + for var in self.val_vars: + if var == "imm_val": + instr[var],instr['label'] = '0', '3f' + else: + instr[var] = '0' + return instr + + def __cb_instr__(self,op=None,val=None): + cond_str = '' + if op: + cond_str += op[-1]+', ' + if val: + cond_str += val[-1] + instr = {'inst':self.opcode,'index':'0', 'comment':cond_str} + + + labelize = lambda x: (str((-x)%257),'1b') if x < 0 else (str((x%257)),'3f') + + if op: + for var,reg in zip(self.op_vars,op): + instr[var] = str(reg) + else: + for i,var in enumerate(self.op_vars): + instr[var] = 'x'+str(i+10) + if val: + for i,var in enumerate(self.val_vars): + if var == "imm_val": + instr[var],instr['label'] = labelize(val[i]) + else: + instr[var] = str(val[i]) + else: + for var in self.val_vars: + if var == "imm_val": + instr[var],instr['label'] = '0', '3f' + else: + instr[var] = '0' + return instr + + def __cj_instr__(self,op=None,val=None): + cond_str = '' + if op: + cond_str += op[-1]+', ' + if val: + cond_str += val[-1] + instr = {'inst':self.opcode,'index':'0', 'comment':cond_str} + + + labelize = lambda x: (str((-x)%2048),'1b') if x < 0 else (str((x%2048)),'3f') + + if op: + for var,reg in zip(self.op_vars,op): + instr[var] = str(reg) + else: + for i,var in enumerate(self.op_vars): + instr[var] = 'x'+str(i+10) + if val: + for i,var in enumerate(self.val_vars): + if var == "imm_val": + instr[var],instr['label'] = labelize(val[i]) + else: + instr[var] = str(val[i]) + else: + for var in self.val_vars: + if var == "imm_val": + instr[var],instr['label'] = '0', '3f' + else: + instr[var] = '0' + instr['rs2'] = 'x1' + return instr + + def __clui_instr__(self,op=None,val=None): + cond_str = '' + if op: + cond_str += op[-1]+', ' + if val: + cond_str += val[-1] + instr = {'inst':self.opcode,'index':'0', 'comment':cond_str} + + if op: + for var,reg in zip(self.op_vars,op): + instr[var] = str(reg) + else: + for i,var in enumerate(self.op_vars): + instr[var] = 'x'+str(i+10) + if val: + for i,var in enumerate(self.val_vars): + if var == "imm_val": + instr[var] = str(val[i]) if val[i] < 32 else str(val[i]+1048512) + else: + instr[var] = str(val[i]) + else: + for var in self.val_vars: + if var == "imm_val": + instr[var] = '16' + else: + instr[var] = '0' + return instr + + def __cmemsp_instr__(self, op=None, val=None): + cond_str = '' + if op: + cond_str += op[-1]+', ' + if val: + cond_str += val[-1] + instr = {'inst':self.opcode,'index':'0', 'comment':cond_str} + if op: + for var,reg in zip(self.op_vars,op): + instr[var] = str(reg) + else: + for i,var in enumerate(self.op_vars): + instr[var] = 'x'+str(i+10) + if val: + for i,var in enumerate(self.val_vars): + instr[var] = str(val[i]) + else: + for var in self.val_vars: + instr[var] = str(self.datasets[var][0]) + instr['rs1'] = 'x2' + return instr + + def __instr__(self, op=None, val=None): + cond_str = '' + if op: + cond_str += op[-1]+', ' + if val: + cond_str += val[-1] + instr = {'inst':self.opcode,'index':'0', 'comment':cond_str} + if op: + for var,reg in zip(self.op_vars,op): + instr[var] = str(reg) + else: + for i,var in enumerate(self.op_vars): + instr[var]=self.default_regs[var] + if val: + for i,var in enumerate(self.val_vars): + instr[var] = str(val[i]) + else: + for var in self.val_vars: + instr[var] = str(self.datasets[var][0]) + return instr + + def __fext_instr__(self,op=None,val=None): + rm_dict = { + 0: 'rne', + 1: 'rtz', + 2: 'rdn', + 3: 'rup', + 4: 'rmm', + 7: 'dyn'} + cond_str = '' + if op: + cond_str += op[-1]+',' + if val: + cond_str += val[-1] + instr = {'inst':self.opcode,'comment':cond_str,'index':'0'} + if op: + for var,reg in zip(self.op_vars,op): + instr[var] = str(reg) + else: + for i,var in enumerate(self.op_vars): + instr[var]=self.default_regs[var] + if val: + for i,var in enumerate(self.val_vars): + if var == 'rm_val': + instr[var] = str(rm_dict[val[i]]) + else: + instr[var] = str(val[i]) + else: + for var in self.val_vars: + if var == 'rm_val': + instr[var] = 'dyn' + else: + instr[var] = str(self.datasets[var][0]) + return instr + + def gen_inst(self,op_comb, val_comb, cgf): + ''' + This function combines the op_comb and val_comb solution dictionaries + to create a complete set of arguments of the instruction. + + Depending on the instruction opcode other subfunctions are called to + create the final merged dictionary of op_comb and val_comb. + + Note however, that using the integer register x0 as either source or + destination does not contribute to the coverage. Hence the respective + val_combs are repeated again with non-x0 registers. + + :param op_comb: list containing the operand combination solutions + :param val_comb: list containing the value combination solutions + :param cgf: a covergroup in cgf format containing the set of coverpoints to be satisfied. + + :type cgf: dict + :type op_comb: list + :type val_comb: list + + :return: list of dictionaries containing the various values necessary for the macro. + ''' + instr_dict = [] + cont = [] + if len(op_comb) < len(val_comb): + op_comb = list(op_comb) + [[]] * (len(val_comb) - len(op_comb)) + elif len(val_comb) < len(op_comb): + val_comb = list(val_comb) + [[self.datasets[var][0] for var in self.val_vars] + [""]] * (len(op_comb) - len(val_comb)) + + x = dict([(y,x) for x,y in enumerate(self.val_vars)]) + + ind_dict = {} + for ind,var in enumerate(self.op_vars): + if var+"_val" in x: + ind_dict[ind] = x[var+"_val"] + + for op,val_soln in zip(op_comb,val_comb): + val = [x for x in val_soln] + if any([x=='x0' for x in op]) or not (len(op) == len(set(op))): + cont.append(val_soln) + op_inds = list(ind_dict.keys()) + for i,x in enumerate(op_inds): + if op[x] == 'x0': + val[ind_dict[x]] = 0 + for y in op_inds[i:]: + if op[y] == op[x]: + val[ind_dict[y]] = val[ind_dict[x]] + if self.is_fext: + instr_dict.append(self.__fext_instr__(op,val)) + elif self.opcode == 'c.lui': + instr_dict.append(self.__clui_instr__(op,val)) + elif self.opcode in ['c.beqz', 'c.bnez']: + instr_dict.append(self.__cb_instr__(op,val)) + elif self.opcode in ['c.lwsp', 'c.swsp', 'c.ldsp', 'c.sdsp']: + if any([x == 'x2' for x in op]): + cont.append(val) + instr_dict.append(self.__cmemsp_instr__(op,val)) + elif self.fmt == 'bformat' or self.opcode in ['c.j']: + instr_dict.append(self.__bfmt_instr__(op,val)) + elif self.opcode in ['c.jal', 'c.jalr']: + instr_dict.append(self.__cj_instr__(op,val)) + elif self.fmt == 'jformat' or self.fmt == 'cjformat': + instr_dict.append(self.__jfmt_instr__(op,val)) + else: + instr_dict.append(self.__instr__(op,val)) + op = None + for val in cont: + if self.is_fext: + instr_dict.append(self.__fext_instr__(op,val)) + elif self.opcode == 'c.lui': + instr_dict.append(self.__clui_instr__(op,val)) + elif self.opcode in ['c.beqz', 'c.bnez','c.lbu','c.lhu','c.lh','c.sb','c.sh']: + instr_dict.append(self.__cb_instr__(op,val)) + elif self.opcode in ['c.lwsp', 'c.swsp', 'c.ldsp', 'c.sdsp']: + instr_dict.append(self.__cmemsp_instr__(op,val)) + elif self.fmt == 'bformat' or self.opcode in ['c.j']: + instr_dict.append(self.__bfmt_instr__(op,val)) + elif self.opcode in ['c.jal', 'c.jalr']: + instr_dict.append(self.__cj_instr__(op,val)) + elif self.fmt == 'jformat': + instr_dict.append(self.__jfmt_instr__(op,val)) + else: + instr_dict.append(self.__instr__(op,val)) + + hits = defaultdict(lambda:set([])) + final_instr = [] + + rm_dict = { + 'rne': 0, + 'rtz': 1, + 'rdn': 2, + 'rup': 3, + 'rmm': 4, + 'dyn': 7} + + def eval_inst_coverage(coverpoints,instr): + cover_hits = {} + var_dict = {} + for key in self.val_vars: + if key == 'imm_val': + if self.fmt in ['jformat','bformat'] or instr['inst'] in \ + ['c.beqz','c.bnez','c.jal','c.j','c.jalr']: + var_dict['imm_val'] = \ + (-1 if instr['label'] == '1b' else 1) * toint(instr['imm_val']) + else: + var_dict['imm_val'] = toint(instr['imm_val']) + elif key == 'rm_val': + var_dict['rm_val'] = rm_dict[instr['rm_val']] + else: + var_dict[key] = toint(instr[key]) + for key in self.op_vars: + var_dict[key] = instr[key] + + + instr_obj = instructionObject(None, instr['inst'], None) + ext_specific_vars = instr_obj.evaluate_instr_var("ext_specific_vars", {**var_dict, 'flen': self.flen, 'iflen': self.iflen, 'inxFlag': self.inxFlag, 'xlen': self.xlen}, None, {'fcsr': hex(var_dict.get('fcsr', 0))}) + insn = instr['inst'] + # instructionObject() has an outdated list of instructions. + # Let's make it support all FP instructions until this is fixed. + # See https://github.com/riscv-software-src/riscv-isac/issues/69 + if (is_fp_instruction(insn)): + insn = "fadd.s" + instr_obj = instructionObject(None, insn, None) + ext_specific_vars = instr_obj.evaluate_instr_var("ext_specific_vars", {**var_dict, 'flen': self.flen, 'iflen': self.iflen}, None, {'fcsr': hex(var_dict.get('fcsr', 0))}) + + if ext_specific_vars is not None: + var_dict.update(ext_specific_vars) + + if 'val_comb' in coverpoints: + valcomb_hits = set([]) + for coverpoint in coverpoints['val_comb']: + if eval(coverpoint,globals(),var_dict): + valcomb_hits.add(coverpoint) + cover_hits['val_comb']=valcomb_hits + if 'op_comb' in coverpoints: + opcomb_hits = set([]) + for coverpoint in coverpoints['op_comb']: + if eval(coverpoint,globals(),var_dict): + opcomb_hits.add(coverpoint) + cover_hits['op_comb']=opcomb_hits + if 'rs1' in coverpoints: + if var_dict['rs1'] in coverpoints['rs1']: + cover_hits['rs1'] = set([var_dict['rs1']]) + if 'rs2' in coverpoints: + if var_dict['rs2'] in coverpoints['rs2']: + cover_hits['rs2'] = set([var_dict['rs2']]) + if 'rs3' in coverpoints: + if var_dict['rs3'] in coverpoints['rs3']: + cover_hits['rs3'] = set([var_dict['rs3']]) + if 'rd' in coverpoints: + if var_dict['rd'] in coverpoints['rd']: + cover_hits['rd'] = set([var_dict['rd']]) + return cover_hits + i = 0 + + for instr in instr_dict: + unique = False + skip_val = False + if instr['inst'] in cgf['mnemonics']: + if 'rs1' in instr and 'rs2' in instr: + if instr['rs1'] == instr['rs2']: + skip_val = True + if 'rs1' in instr: + if instr['rs1'] == 'x0' or instr['rs1'] == 'f0': + skip_val = True + if 'rs2' in instr: + if instr['rs2'] == 'x0' or instr['rs2'] == 'f0': + skip_val = True + if 'rd' in instr: + if instr['rd'] == 'x0' or instr['rd'] == 'f0': + skip_val = True + cover_hits = eval_inst_coverage(cgf,instr) + for entry in cover_hits: + if entry=='val_comb' and skip_val: + continue + over = hits[entry] & cover_hits[entry] + if over != cover_hits[entry]: + unique = unique or True + hits[entry] |= cover_hits[entry] + if unique: + final_instr.append(instr) + else: + i+=1 + + if any('IP' in isa for isa in self.opnode['isa']): + if 'p64_profile' in self.opnode: + gen_pair_reg_data(final_instr, self.xlen, self.opnode['bit_width'], self.opnode['p64_profile']) + elif 'bit_width' in self.opnode: + concat_simd_data(final_instr, self.xlen, self.opnode['bit_width']) + + + ''' + Zacas introduces double xlen cas operations that need paired source and destination registers + ''' + if any('Zacas' in isa for isa in self.opnode['isa']): + if 'dcas_profile' in self.opnode: + gen_pair_reg_data(final_instr, self.xlen, self.opnode['bit_width'], self.opnode['dcas_profile']) + + return final_instr + + def valreg(self,instr_dict): + ''' + This function is responsible for identifying which register can be used to store addresses + to load values from memory. + + This register is calculated by traversing the dictionary of solutions + created so far and removing all the registers which are used as either + operands or destination. When 3 or less registers are pending, one of + those registers is used as signature pointer for all the solutions + traversed so far. + + Along with the register the offset is also assigned in this function. + The offset is incremented by the amount specified in the template node bytes always. + + Care is taken to never use 'x0' as signature pointer. + :param instr_dict: list of dictionaries containing the various values necessary for the macro + :type instr_dict: list + :return: list of dictionaries containing the various values necessary for the macro + ''' + # TODO: Move flagreg allocation to separate function. Preferable to club all anxilliary + # register allocations to a generalised function and club both swreg and valreg to it too. + if 'val' in self.opnode: + paired_regs=0 + if self.xlen == 32 and 'p64_profile' in self.opnode: + p64_profile = self.opnode['p64_profile'] + paired_regs = self.opnode['p64_profile'].count('p') + if 'dcas_profile' in self.opnode: + dcas_profile = self.opnode['dcas_profile'] + paired_regs = self.opnode['dcas_profile'].count('p') + + regset = e_regset if 'e' in self.base_isa else default_regset + total_instr = len(instr_dict) + available_reg = regset.copy() + available_reg.remove('x0') + count = 0 + assigned = 0 + offset = 0 + stride = self.opnode['val']['stride'] + num_vars = len(self.op_vars)-1 if 'rd' in self.op_vars else len(self.op_vars) + suffix = self.opnode['val']['sz'] + if flen in self.opnode: + FLEN = max(self.opnode['flen']) + else: + FLEN = 0 + XLEN = max(self.opnode['xlen']) + SIGALIGN = max(XLEN,FLEN)/8 + stride_sz = eval(suffix) + template = Template(eval(self.opnode['val']['val_template'])) + width = self.iflen if self.is_fext else self.flen + for instr in instr_dict: + if 'rs1' in instr and instr['rs1'] in available_reg: + available_reg.remove(instr['rs1']) + if 'rs2' in instr and instr['rs2'] in available_reg: + available_reg.remove(instr['rs2']) + if 'rd' in instr and instr['rd'] in available_reg: + available_reg.remove(instr['rd']) + if 'rs1_hi' in instr and instr['rs1_hi'] in available_reg: + available_reg.remove(instr['rs1_hi']) + if 'rs2_hi' in instr and instr['rs2_hi'] in available_reg: + available_reg.remove(instr['rs2_hi']) + if 'rd_hi' in instr and instr['rd_hi'] in available_reg: + available_reg.remove(instr['rd_hi']) + if 'swreg' in instr and instr['swreg'] in available_reg: + available_reg.remove(instr['swreg']) + if 'testreg' in instr and instr['testreg'] in available_reg: + available_reg.remove(instr['testreg']) + if len(available_reg) <= 3+len(self.op_vars)+paired_regs: + curr_reg = available_reg[0] + offset = 0 + for i in range(assigned, count+1): + if 'valaddr_reg' not in instr_dict[i]: + instr_dict[i]['valaddr_reg'] = curr_reg + instr_dict[i]['val_offset'] = str(offset) + '*' + suffix + offset += stride + if offset*stride_sz > 2047: + offset = 0 + assigned += 1 + instr_dict[i]['val_section'] = [] + for j in range(1,num_vars+1): + dval = () + if self.is_nan_box: + dval = nan_box(instr_dict[i]['rs{0}_nan_prefix'.format(j)], + instr_dict[i]['rs{0}_val'.format(j)],self.flen,self.iflen) + if self.is_sgn_extd: + dval = sgn_extd(instr_dict[i]['rs{0}_sgn_prefix'.format(j)], + instr_dict[i]['rs{0}_val'.format(j)],self.flen,self.iflen) + else: + dval = (instr_dict[i]['rs{0}_val'.format(j)],width) + if self.is_fext: + instr_dict[i]['flagreg'] = available_reg[1] + instr_dict[i]['val_section'].append( + template.substitute(val=dval[0],width=dval[1])) + instr_dict[i]['load_instr'] = self.opnode['val']['load_instr'] + available_reg = regset.copy() + available_reg.remove('x0') + count += 1 + if assigned != total_instr and len(available_reg) != 0: + curr_reg = available_reg[0] + offset = 0 + for i in range(len(instr_dict)): + if 'valaddr_reg' not in instr_dict[i]: + instr_dict[i]['valaddr_reg'] = curr_reg + instr_dict[i]['val_offset'] = str(offset) + '*' + suffix + offset += stride + if offset*stride_sz > 2047: + offset = 0 + assigned += 1 + instr_dict[i]['val_section'] = [] + for j in range(1,num_vars+1): + dval = () + if self.is_nan_box: + dval = nan_box(instr_dict[i]['rs{0}_nan_prefix'.format(j)], + instr_dict[i]['rs{0}_val'.format(j)],self.flen,self.iflen) + else: + dval = (instr_dict[i]['rs{0}_val'.format(j)],width) + if self.is_fext: + instr_dict[i]['flagreg'] = available_reg[1] + instr_dict[i]['val_section'].append( + template.substitute(val=dval[0],width=dval[1])) + instr_dict[i]['load_instr'] = self.opnode['val']['load_instr'] + return instr_dict + else: + return instr_dict + + + + def swreg(self, instr_dict): + ''' + This function is responsible for identifying which register can be used + as a signature pointer for each instruction. + + This register is calculated by traversing the dictionary of solutions + created so far and removing all the registers which are used as either + operands or destination. When 3 or less registers are pending, one of + those registers is used as signature pointer for all the solutions + traversed so far. + + Along with the register the offset is also assigned in this function. + The offset is incremented by the amount specified in the template node bytes always. + + Care is taken to never use 'x0' as signature pointer. + :param instr_dict: list of dictionaries containing the various values necessary for the macro + :type instr_dict: list + :return: list of dictionaries containing the various values necessary for the macro + ''' + # TODO: Clean this up and merge it with the code below to generalise adding val bases to + # generic macro templates. + + paired_regs=0 + if self.xlen == 32 and 'p64_profile' in self.opnode: + p64_profile = self.opnode['p64_profile'] + paired_regs = self.opnode['p64_profile'].count('p') + if 'dcas_profile' in self.opnode: + dcas_profile = self.opnode['dcas_profile'] + paired_regs = self.opnode['dcas_profile'].count('p') + + regset = e_regset if 'e' in self.base_isa else default_regset + total_instr = len(instr_dict) + available_reg = regset.copy() + available_reg.remove('x0') + count = 0 + assigned = 0 + offset = 0 + stride = self.opnode['sig']['stride'] + suffix = self.opnode['sig']['sz'] + if flen in self.opnode: + FLEN = max(self.opnode['flen']) + else: + FLEN = 0 + XLEN = max(self.opnode['xlen']) + SIGALIGN = max(XLEN,FLEN)/8 + stride_sz = eval(suffix) + for instr in instr_dict: + if 'rs1' in instr and instr['rs1'] in available_reg: + available_reg.remove(instr['rs1']) + if 'rs2' in instr and instr['rs2'] in available_reg: + available_reg.remove(instr['rs2']) + if 'rd' in instr and instr['rd'] in available_reg: + available_reg.remove(instr['rd']) + if 'rs1_hi' in instr and instr['rs1_hi'] in available_reg: + available_reg.remove(instr['rs1_hi']) + if 'rs2_hi' in instr and instr['rs2_hi'] in available_reg: + available_reg.remove(instr['rs2_hi']) + if 'rd_hi' in instr and instr['rd_hi'] in available_reg: + available_reg.remove(instr['rd_hi']) + if 'testreg' in instr and instr['testreg'] in available_reg: + available_reg.remove(instr['testreg']) + + if len(available_reg) <= 2+len(self.op_vars)+paired_regs: + curr_swreg = available_reg[0] + offset = 0 + for i in range(assigned, count+1): + if 'swreg' not in instr_dict[i]: + instr_dict[i]['offset'] = str(offset) + '*' + suffix + offset += stride + if offset*stride_sz > 2047: + offset = 0 + instr_dict[i]['swreg'] = curr_swreg + assigned += 1 + available_reg = regset.copy() + available_reg.remove('x0') + count += 1 + if assigned != total_instr and len(available_reg) != 0: + curr_swreg = available_reg[0] + offset = 0 + for i in range(len(instr_dict)): + if 'swreg' not in instr_dict[i]: + instr_dict[i]['offset'] = str(offset) + '*' + suffix + offset += stride + if offset*stride_sz > 2047: + offset = 0 + instr_dict[i]['swreg'] = curr_swreg + return instr_dict + + def testreg(self, instr_dict): + ''' + This function is responsible for identifying which register can be used + as a test register for each instruction. + + This register is calculated by traversing the dictionary of solutions + created so far and removing all the registers which are used as either + operands or destination or signature. When 3 or less registers are pending, one of + those registers is used as test register for all the solutions + traversed so far. + + Care is taken to never use 'x0' as test register. + :param instr_dict: list of dictionaries containing the various values necessary for the macro + :type instr_dict: list + :return: list of dictionaries containing the various values necessary for the macro + ''' + regset = e_regset if 'e' in self.base_isa else default_regset + total_instr = len(instr_dict) + available_reg = regset.copy() + available_reg.remove('x0') + count = 0 + assigned = 0 + + paired_regs=0 + if self.xlen == 32 and 'p64_profile' in self.opnode: + p64_profile = self.opnode['p64_profile'] + paired_regs = p64_profile.count('p') + if 'dcas_profile' in self.opnode: + dcas_profile = self.opnode['dcas_profile'] + paired_regs = dcas_profile.count('p') + + for instr in instr_dict: + if 'rs1' in instr and instr['rs1'] in available_reg: + available_reg.remove(instr['rs1']) + if 'rs1_hi' in instr and instr['rs1_hi'] in available_reg: + available_reg.remove(instr['rs1_hi']) + if 'rs2' in instr and instr['rs2'] in available_reg: + available_reg.remove(instr['rs2']) + if 'rs2_hi' in instr and instr['rs2_hi'] in available_reg: + available_reg.remove(instr['rs2_hi']) + if 'rd' in instr and instr['rd'] in available_reg: + available_reg.remove(instr['rd']) + if 'rd_hi' in instr and instr['rd_hi'] in available_reg: + available_reg.remove(instr['rd_hi']) + if 'swreg' in instr and instr['swreg'] in available_reg: + available_reg.remove(instr['swreg']) + + if len(available_reg) <= 2+len(self.op_vars)+paired_regs: + curr_testreg = available_reg[0] + for i in range(assigned, count+1): + if 'testreg' not in instr_dict[i]: + instr_dict[i]['testreg'] = curr_testreg + assigned += 1 + available_reg = regset.copy() + available_reg.remove('x0') + count += 1 + if assigned != total_instr and len(available_reg) != 0: + curr_testreg = available_reg[0] + for i in range(len(instr_dict)): + if 'testreg' not in instr_dict[i]: + instr_dict[i]['testreg'] = curr_testreg + return instr_dict + + def correct_val(self,instr_dict): + ''' + this function is responsible for assigning the correct-vals for all instructions. + The correctvals are calculated based on the `operation` field of the node + in the attributes YAML. If the operation field is empty, then a value of + 0 is assigned to the correctval. + :param instr_dict: list of dictionaries containing the various values necessary for the macro + :type instr_dict: list + :return: list of dictionaries containing the various values necessary for the macro + ''' + if self.opcode[0] == 'f' and 'fence' not in self.opcode: + for i in range(len(instr_dict)): + instr_dict[i]['correctval'] = '0' + return instr_dict + if self.xlen == 32 and 'p64_profile' in self.opnode: + p64_profile = self.opnode['p64_profile'] + if len(p64_profile) >= 3 and p64_profile[0]=='p': + for i in range(len(instr_dict)): + instr_dict[i]['correctval_hi'] = '0' + if 'dcas_profile' in self.opnode: + dcas_profile = self.opnode['dcas_profile'] + if len(dcas_profile) >= 3 and dcas_profile[0]=='p': + for i in range(len(instr_dict)): + instr_dict[i]['correctval_hi'] = '0' + if self.fmt in ['caformat','crformat']: + normalise = lambda x,y: 0 if y['rs1']=='x0' else x + else: + normalise = (lambda x,y: x) if 'rd' not in self.op_vars else (lambda x,y: 0 if y['rd']=='x0' else x) + if self.operation: + for i in range(len(instr_dict)): + for var in self.val_vars: + locals()[var]=toint(instr_dict[i][var]) + correctval = eval(self.operation) + instr_dict[i]['correctval'] = str(normalise(correctval,instr_dict[i])) + else: + for i in range(len(instr_dict)): + instr_dict[i]['correctval'] = '0x' + '0'.zfill(int(self.xlen/4)) + return instr_dict + + def reformat_instr(self, instr_dict): + ''' + This function basically sanitizes the integer values to a readable + hex values + :param instr_dict: list of dictionaries containing the various values necessary for the macro + :type instr_dict: list + :return: list of dictionaries containing the various values necessary for the macro + ''' + if any('IP' in isa for isa in self.opnode['isa']): + # instr_dict is already in the desired format for instructions that perform SIMD operations, or Zpsfoperand instructions in RV32. + if 'bit_width' in self.opnode or (self.xlen == 32 and 'p64_profile' in self.opnode): + return instr_dict + if any('Zacas' in isa for isa in self.opnode['isa']): + # instr_dict is already in the desired format for Zacas dcas instructions + if 'bit_width' in self.opnode or 'dcas_profile' in self.opnode: + return instr_dict + + # Fix all K instructions to be unsigned to output unsigned hex values into the test. Its + # only a cosmetic difference and has no impact on coverage + is_unsigned = any('IZk' in isa for isa in self.opnode['isa']) + + for i in range(len(instr_dict)): + for field in instr_dict[i]: + if xlen == 32: + if instr_dict[i]['inst'] in ['sltu', 'sltiu', 'bgeu', 'bltu'] or is_unsigned: + size = '>I' + else: + size = '>i' + else: + if instr_dict[i]['inst'] in ['sltu', 'sltiu', 'bgeu', 'bltu'] or is_unsigned: + size = '>Q' + else: + size = '>q' + if 'val' in field and field != 'correctval' and field != 'valaddr_reg' and \ + field != 'val_section' and field != 'val_offset' and field != 'rm_val': + value = (instr_dict[i][field]).strip() + #print(value) + if '0x' in value: + value = '0x' + value[2:].zfill(int(self.xlen/4)) + value = struct.unpack(size, bytes.fromhex(value[2:]))[0] + else: + value = int(value) +# value = '0x' + struct.pack(size,value).hex() + #print("test",hex(value)) + instr_dict[i][field] = hex(value) + return instr_dict + + def write_test(self, fprefix, node, label, instr_dict, op_node, usage_str,max_inst): + start = 0 + total = len(instr_dict) + end = len(instr_dict) + if max_inst: + end = max_inst + else: + max_inst = total + i = 1 + while end <= total and start=max_inst: + end += max_inst + else: + end = total + + + def __write_test__(self, file_name,node,label,instr_dict, op_node, usage_str): + ''' + This function generates the test using various templates. + + :param file_name: path of the output file + :param node: a covergroup in cgf format containing the set of coverpoints to be satisfied + :param label: the label for the covergroup in the input cgf file + :param instr_dict: list of dictionaries containing the various values necessary for the macro + :param op_node: dictionary node from the attributes YAML that is to be used in the test generation + :param usage_str: Banner string for the test + + :type file_name: str + :type node: dict + :type label: str + :type instr_dict: list + :type op_node: dict + :type usage_str: str + ''' + regs = defaultdict(lambda: 0) + sreg = instr_dict[0]['swreg'] + vreg = None + code = [] + sign = [""] + data = [".align 4","rvtest_data:",".word 0xbabecafe", \ + ".word 0xabecafeb", ".word 0xbecafeba", ".word 0xecafebab"] + stride = self.opnode['sig']['stride'] + if self.is_fext: + code.append("RVTEST_FP_ENABLE()") + + if any('IP' in isa for isa in self.opnode['isa']): + code.append("RVTEST_VXSAT_ENABLE()") + if self.xlen == 32 and 'p64_profile' in self.opnode: + p64_profile = self.opnode['p64_profile'] + if 'dcas_profile' in self.opnode: + dcas_profile = self.opnode['dcas_profile'] + + n = 0 + is_int_src = any([self.opcode.endswith(x) for x in ['.x','.w','.l','.wu','.lu']]) or self.inxFlag + src_len = xlen if self.opcode.endswith('.x') else (32 if 'w' in self.opcode else 64) + sz = 'word' if src_len == 32 else 'dword' + opcode = instr_dict[0]['inst'] + op_node_isa = "" + extension = "" + xlens = [self.xlen] + \ + (list(filter(lambda x: x>self.xlen,self.opnode['xlen'])) if self.is_fext else []) + for val in xlens: + rvxlen = "RV"+str(val) + op_node_isa += (("," if op_node_isa else "") \ + + ",".join([rvxlen + isa for isa in op_node['isa']])) + op_node_isa = op_node_isa.replace("I","E") if 'e' in self.base_isa else op_node_isa + extension = op_node_isa.replace('I',"").replace('E',"") + count = 0 + neg_offset = 0 + width = self.iflen if not self.is_nan_box else self.flen + dset_n = 0 + sig_sz = '(({0})/4)'.format(self.opnode['sig']['sz']) + cond_prefix = '' if self.is_fext else 'check ISA:=regex(.*{0}.*);'.format(self.xlen) + for instr in instr_dict: + switch = False + res = '\ninst_{0}:'.format(str(count)) + res += Template(op_node['template']).safe_substitute(instr) + if 'val' in self.opnode: + if eval(instr['val_offset'],{}, + {'FLEN':width,'XLEN':self.xlen,'SIGALIGN':max(self.xlen,self.flen)/8} + ) == 0 or instr['valaddr_reg'] != vreg: + dlabel = 'test_dataset_'+str(dset_n) + dset_n += 1 + data.append(dlabel+":") + vreg = instr['valaddr_reg'] + code.append("RVTEST_VALBASEUPD("+vreg+","+dlabel+")") + # for i in range(1,num_vars+1): + # dval = () + # if self.is_nan_box: + # dval = nan_box(instr['rs{0}_nan_prefix'.format(i)], + # instr['rs{0}_val'.format(i)],self.flen,self.iflen) + # else: + # dval = (instr['rs{0}_val'.format(i)],self.iflen) + data.extend(instr['val_section']) + if instr['swreg'] != sreg or eval(instr['offset'],{}, + {'FLEN':width,'XLEN':self.xlen,'SIGALIGN':max(self.xlen,self.flen)/8}) == 0: + sign.append(signode_template.substitute( + {'n':n,'label':"signature_"+sreg+"_"+str(regs[sreg]),'sz':sig_sz})) + n = stride + regs[sreg]+=1 + sreg = instr['swreg'] + code.append("RVTEST_SIGBASE("+sreg+",signature_"+sreg+"_"+str(regs[sreg])+")") + else: + n+=stride + code.append(res) + count = count + 1 + case_str = ''.join([case_template.safe_substitute(xlen=self.xlen,num=i,cond=cond,cov_label=label) for i,cond in enumerate(node['config'])]) + sign.append(signode_template.substitute({'n':n, + 'label':"signature_"+sreg+"_"+str(regs[sreg]),'sz':sig_sz})) + test = part_template.safe_substitute(case_str=case_str,code='\n'.join(code)) + sign.append("#ifdef rvtest_mtrap_routine\ntsig_begin_canary:\nCANARY;\n"+signode_template.substitute( + {'n':64,'label':"mtrap_sigptr",'sz':'XLEN/32'})+"\ntsig_end_canary:\nCANARY;\n#endif\n") + sign.append("#ifdef rvtest_gpr_save\n"+signode_template.substitute( + {'n':32,'label':"gpr_save",'sz':'XLEN/32'})+"\n#endif\n") + with open(file_name,"w") as fd: + fd.write(usage_str + test_template.safe_substitute(data='\n'.join(data),test=test,sig='\n'.join(sign),isa=op_node_isa,opcode=opcode,extension=extension,label=label)) diff --git a/riscv-ctg/riscv_ctg/helpers.py b/riscv-ctg/riscv_ctg/helpers.py new file mode 100644 index 000000000..ed8d2ca64 --- /dev/null +++ b/riscv-ctg/riscv_ctg/helpers.py @@ -0,0 +1,98 @@ +import re + +class ExtractException(Exception): + pass + +num_dict = { + 'rs1_val': '1', + 'rs2_val': '2', + 'rs3_val': '3', +} +fsub_vars = ['fe','fm','fs'] + +val_regex = "{0}\s*==\s*(?P<{1}>[0-9abcdefx+\-\*/\|\&]*)\s*" + +def to_int(x): + if '0x' in x: + return int(x,16) + else: + return int(x) + +def nan_box(prefix,rs,flen,iflen): + if int(prefix) == ((2**(flen-iflen))-1): + return (rs,iflen) + else: + return (str(to_int(rs)|(to_int(prefix)< iflen: + if inxFlag: + sgn_extd = True + else: + nan_box = True + fdict = {} + for var in val_vars: + if var in num_dict and merge: + fdict[var] = extract_frs_fields(num_dict[var],cvp,iflen) + if nan_box: + nan_var = 'rs{0}_nan_prefix'.format(num_dict[var]) + regex = val_regex.format(nan_var.replace("_","\\_"),nan_var) + match_obj = re.search(regex,cvp) + if match_obj is not None: + fdict[nan_var] = eval(match_obj.group(nan_var)) + else: + fdict[nan_var] = (2**(flen-iflen))-1 + elif sgn_extd: + sgn_var = 'rs{0}_sgn_prefix'.format(num_dict[var]) + regex = val_regex.format(sgn_var.replace("_","\\_"),sgn_var) + match_obj = re.search(regex,cvp) + if match_obj is not None: + fdict[sgn_var] = eval(match_obj.group(sgn_var)) + else: + fdict[sgn_var] = (2**(flen-iflen))-1 + else: + regex = val_regex.format(var.replace("_","\\_"),var) + match_obj = re.search(regex,cvp) + if match_obj is not None: + fdict[var] = eval(match_obj.group(var)) + elif 'nan_prefix' not in var: + raise ExtractException("{0} not defined in coverpoint:{1}".format(var,cvp)) + return fdict + + diff --git a/riscv-ctg/riscv_ctg/log.py b/riscv-ctg/riscv_ctg/log.py new file mode 100644 index 000000000..f4d2312b5 --- /dev/null +++ b/riscv-ctg/riscv_ctg/log.py @@ -0,0 +1,92 @@ +# See LICENSE.incore for details + +import logging +import colorlog + +class Log: + """ + this class holds all the logic; see the end of the script to + see how it's instantiated in order to have the line + "from zenlog import log" work + """ + + aliases = { + logging.CRITICAL: ("critical", "crit", "fatal"), + logging.ERROR: ("error", "err"), + logging.WARNING: ("warning", "warn"), + logging.INFO: ("info", "inf"), + logging.DEBUG: ("debug", "dbg") + } + + def __init__(self, format=None): + if not format: + format = "%(log_color)s%(levelname)8s%(reset)s | %(log_color)s%(message)s%(reset)s" + self.format = format + self.colors = { + 'DEBUG': 'purple', + 'INFO': 'green', + 'WARNING': 'red', + 'ERROR': 'bold_red', + 'CRITICAL': 'bold_red', + } + self.logger = logging.getLogger() + + + # the magic happens here: we use the "extra" argument documented in + # https://docs.python.org/2/library/logging.html#logging.Logger.debug + # to inject new items into the logging.LogRecord objects + # we also create our convenience methods here + def critical(self, message, *args, **kwargs): + for line in str(message).splitlines(): + self.logger.critical(line, + *args, **kwargs) + crit = c = fatal = critical + + def error(self, message, *args, **kwargs): + for line in str(message).splitlines(): + self.logger.error(line, + *args, **kwargs) + err = e = error + + def warn(self, message, *args, **kwargs): + for line in str(message).splitlines(): + self.logger.warning(line, + *args, **kwargs) + warning = w = warn + + def info(self, message, *args, **kwargs): + for line in str(message).splitlines(): + self.logger.info(line, + *args, **kwargs) + inf = nfo = i = info + + def debug(self, message, *args, **kwargs): + for line in str(message).splitlines(): + self.logger.debug(line, + *args, **kwargs) + dbg = d = debug + + # other convenience functions to set the global logging level + def _parse_level(self, lvl): + for log_level in self.aliases: + if lvl == log_level or lvl in self.aliases[log_level]: + return log_level + print('Invalid log level passed. Please select from debug | info | warning | error') + raise ValueError("{}-Invalid log level.".format(lvl)) + + def level(self, lvl=logging.CRITICAL): + '''Setup the Logger.''' + + self._lvl = self._parse_level(lvl) + + self.stream = logging.StreamHandler() + self.stream.setLevel(self._lvl) + + self.stream.setLevel(self._lvl) + + self.stream.setFormatter(colorlog.ColoredFormatter(self.format,log_colors=self.colors)) + self.logger.setLevel(self._lvl) + + self.logger.addHandler(self.stream) + logging.root.setLevel(self._lvl) +logger = Log() diff --git a/riscv-ctg/riscv_ctg/main.py b/riscv-ctg/riscv_ctg/main.py new file mode 100644 index 000000000..98d172e38 --- /dev/null +++ b/riscv-ctg/riscv_ctg/main.py @@ -0,0 +1,30 @@ +# See LICENSE.incore for details +"""Console script for riscv_ctg.""" + +import click,os + +from riscv_ctg.log import logger +from riscv_ctg.ctg import ctg +from riscv_ctg.__init__ import __version__ +from riscv_ctg.constants import env,gen_sign_dataset,gen_usign_dataset +from riscv_isac.cgf_normalize import expand_cgf +@click.command() +@click.version_option(prog_name="RISC-V Compliance Test Generator",version=__version__) +@click.option('--verbose', '-v', default='error', help='Set verbose level', type=click.Choice(['info','error','debug','warning'],case_sensitive=False)) +@click.option('--out-dir', '-d', default='./', type=click.Path(resolve_path=True,writable=True), help='Output directory path') +@click.option('--randomize','-r', default=False , is_flag='True', help='Randomize Outputs.') +@click.option('--cgf','-cf',multiple=True,type=click.Path(exists=True,resolve_path=True,readable=True),help="Path to the cgf file(s). Multiple allowed.") +@click.option('--procs','-p',type=int,default=1,help='Max number of processes to spawn') +@click.option('--base-isa','-bi',type=click.Choice(['rv32e','rv32i','rv64i']),help="Base ISA string for the tests.") +@click.option('--flen','-fl',type=click.Choice(['32','64','0']),help="Value of FLEN in\ + hardware.",default='32') +@click.option("--inst",type=int,help="Maximum number of Macro Instances per test.") +@click.option("--z-inx", '-ix', type=bool, default='False', help="If the extension is Z*inx then pass True otherwise defaulted to False") +def cli(verbose, out_dir, randomize , cgf,procs,base_isa, flen,inst,z_inx): + if not os.path.exists(out_dir): + os.mkdir(out_dir) + if '32' in base_isa: + xlen = 32 + elif '64' in base_isa: + xlen = 64 + ctg(verbose, out_dir, randomize ,xlen, int(flen), cgf,procs,base_isa,inst,z_inx) diff --git a/riscv-ctg/riscv_ctg/misc/bitmanip_real_world.py b/riscv-ctg/riscv_ctg/misc/bitmanip_real_world.py new file mode 100644 index 000000000..5109f2395 --- /dev/null +++ b/riscv-ctg/riscv_ctg/misc/bitmanip_real_world.py @@ -0,0 +1,442 @@ +import random +import os + +#---------------------------------------------------Start String-------------------------------------------------- + +start_str = ''' +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV$xlenIK") + +.section .text.init +.globl rvtest_entry_point +rvtest_entry_point: +RVMODEL_BOOT +RVTEST_CODE_BEGIN + +#ifdef TEST_CASE_1 + +RVTEST_CASE(0,"//check ISA:=regex(.*$xlen.*);check ISA:=regex(.*RV$xlen.*I.*K.*);def TEST_CASE_1=True;",$inst) + +RVTEST_CASE(1,"//check ISA:=regex(.*$xlen.*);check ISA:=regex(.*RV$xlen.*I.*$config.*);def TEST_CASE_1=True;",$inst) + +RVTEST_SIGBASE( $swreg1,signature_$swreg1_1)''' + +#---------------------------------------------Assembly String: aes64*---------------------------------------------- + +string1 = '''// $comment +// opcode: $inst; op1:$rs1; op2:$rs2; dest1:$rd1; dest2:$rd2; dest3:$rd3; op1val:$r1_val; op2val:$r2_val +li $rs1, $r1_val; +li $rs2, $r2_val; +xor $rs1, $rs1, $rs2; +$inst $rd1, $rs1, $rs2; +$inst $rd2, $rs2, $rs1; +xor $rd3, $rd2, $rs2; +RVTEST_SIGUPD($swreg1,$rd1,$offset1); +RVTEST_SIGUPD($swreg1,$rd2,$offset2); +RVTEST_SIGUPD($swreg1,$rd3,$offset3);''' + +#---------------------------------Assembly String: SHA2, SM3 & aes64im - Pattern 1--------------------------------- + +string2 = '''// $comment +// opcode: $inst2; op1:$rs3; dest1:$rs1; op1val:$r1_val; op2val:$r2_val +li $rs1, $r1_val; +li $rs2, $r2_val; +$inst1 $rs3, $rs1, $rs2; +$inst2 $rs1, $rs3; +$inst1 $rs4, $rs1, $rs2; +RVTEST_SIGUPD($swreg1,$rs3,$offset1); +RVTEST_SIGUPD($swreg1,$rs1,$offset2); +RVTEST_SIGUPD($swreg1,$rs4,$offset3);''' + +string2_not = '''// $comment +// opcode: $inst2; op1:$rs3; dest1:$rs1; op1val:$r1_val; op2val:$r2_val +li $rs1, $r1_val; +li $rs2, $r2_val; +$inst1 $rs3, $rs2; +$inst2 $rs1, $rs3; +$inst1 $rs4, $rs1; +RVTEST_SIGUPD($swreg1,$rs3,$offset1); +RVTEST_SIGUPD($swreg1,$rs1,$offset2); +RVTEST_SIGUPD($swreg1,$rs4,$offset3);''' + +#---------------------------------Assembly String: SHA2, SM3 & aes64im - Pattern 2--------------------------------- + +string3 = '''// $comment +// opcode: $inst; op1:$rs1; dest1:$rs2; +LREG $rs1, $offset1($rs0); +$inst $rs2, $rs1; +RVTEST_SIGUPD($swreg1,$rs1,$offset2); +RVTEST_SIGUPD($swreg1,$rs2,$offset3);''' + +#---------------------------------------Assembly String: SHA2-512 - Pattern 1-------------------------------------- + +string5 = '''// $comment +// opcode: $inst2; op1:$rs3; op2:$rs2; dest1:$rs1; op1val:$r1_val; op2val:$r2_val +li $rs1, $r1_val; +li $rs2, $r2_val; +$inst1 $rs3, $rs1, $rs2; +$inst2 $rs1, $rs3, $rs2; +$inst1 $rs4, $rs1, $rs2; +RVTEST_SIGUPD($swreg1,$rs3,$offset1); +RVTEST_SIGUPD($swreg1,$rs1,$offset2); +RVTEST_SIGUPD($swreg1,$rs4,$offset3);''' + +string5_not = '''// $comment +// opcode: $inst2; op1:$rs3; op2:$rs2; dest1:$rs1; op1val:$r1_val; op2val:$r2_val +li $rs1, $r1_val; +li $rs2, $r2_val; +$inst1 $rs3, $rs2; +$inst2 $rs1, $rs3, $rs2; +$inst1 $rs4, $rs1; +RVTEST_SIGUPD($swreg1,$rs3,$offset1); +RVTEST_SIGUPD($swreg1,$rs1,$offset2); +RVTEST_SIGUPD($swreg1,$rs4,$offset3);''' + +#---------------------------------------Assembly String: SHA2-512 - Pattern 2-------------------------------------- + +string6 = '''// $comment +// opcode: $inst; op1:$rs1; op2:$rs2; dest1:$rs3; +LREG $rs1, $offset1($rs0); +LREG $rs2, $offset2($rs0); +$inst $rs3, $rs1, $rs2; +RVTEST_SIGUPD($swreg1,$rs1,$offset3); +RVTEST_SIGUPD($swreg1,$rs3,$offset4);''' + +#----------------------------------------------Assembly String: aes32*--------------------------------------------- + +string4 = '''// $comment +// opcode: $inst; op1:$rs1; op1:$rs2; op1:$rs3; op1:$rs4; dest:$rs5; +li $rs1, $r1_val; +li $rs2, $r2_val; +li $rs3, $r3_val; +li $rs4, $r4_val; +li $rs5, $r5_val; +$inst $rs5, $rs1, 0; +$inst $rs5, $rs2, 1; +$inst $rs5, $rs3, 2; +$inst $rs5, $rs4, 3; +RVTEST_SIGUPD($swreg1,$rs5,$offset1);''' + +#----------------------------------------------Assembly String: sm4ed, sm4ks --------------------------------------------- + +string7 = '''// $comment +// opcode: $inst; $op1: $rs6; op2:$rs1; op2:$rs2; op2:$rs3; op2:$rs4; dest:$rs5; +li $rs1, $r1_val; +li $rs2, $r2_val; +li $rs3, $r3_val; +li $rs4, $r4_val; +li $rs5, $r5_val; +li $rs6, $r6_val; +$inst $rs5, $rs6, $rs1, 0; +$inst $rs5, $rs6, $rs2, 1; +$inst $rs5, $rs6, $rs3, 2; +$inst $rs5, $rs6, $rs4, 3; +RVTEST_SIGUPD($swreg1,$rs5,$offset1);''' + +#----------------------------------------------------End String---------------------------------------------------- + +end_str = '''#endif + +RVTEST_CODE_END +RVMODEL_HALT + +RVTEST_DATA_BEGIN +.align 4 +rvtest_data: +.word 0xbabecafe +RVTEST_DATA_END + +RVMODEL_DATA_BEGIN + + +signature_$swreg1_1: + .fill $fill_val*(XLEN/32),4,0xdeadbeef + +#ifdef rvtest_mtrap_routine + +mtrap_sigptr: + .fill 64*(XLEN/32),4,0xdeadbeef + +#endif + +#ifdef rvtest_gpr_save + +gpr_save: + .fill 32*(XLEN/32),4,0xdeadbeef + +#endif + +RVMODEL_DATA_END''' + +#-------------------------------------------------End String 1 & 2------------------------------------------------ + +end_str1 = '''#endif + +RVTEST_CODE_END +RVMODEL_HALT + +RVTEST_DATA_BEGIN +.align 4 +rvtest_data:''' + +end_str2 = '''RVTEST_DATA_END + +RVMODEL_DATA_BEGIN + + +signature_$swreg1_1: + .fill $fill_val*(XLEN/32),4,0xdeadbeef + +#ifdef rvtest_mtrap_routine + +mtrap_sigptr: + .fill 64*(XLEN/32),4,0xdeadbeef + +#endif + +#ifdef rvtest_gpr_save + +gpr_save: + .fill 32*(XLEN/32),4,0xdeadbeef + +#endif + +RVMODEL_DATA_END''' + +#----------------------------------------------------User Inputs--------------------------------------------------- + +instr_dict = { + 1: ["aes64ds","aes64dsm","aes64es","aes64esm","sm4ed","sm4ks"], + 2: ["sha256sig0","sha256sig1","sha256sum0","sha256sum1","sha512sig0",\ + "sha512sig1","sha512sum0","sha512sum1","sm3p0","sm3p1","aes64im"], + 3: ["aes32dsi","aes32dsmi","aes32esi","aes32esmi"], + 4: ["sha256sig0","sha256sig1","sha256sum0","sha256sum1","sm3p0","sm3p1"], + 5: ["sha512sig0h","sha512sig0l","sha512sig1h","sha512sig1l","sha512sum0r","sha512sum1r"], + 6: ["sm4ed","sm4ks"], + 7: ["sm4ed","sm4ks"]} + +instr_f = { + 1: ["xor"], + 2: ["xor","not","add"], + 3: ["none"], + 4: ["xor","not","add"], + 5: ["xor","not","add"], + 6: ["none"], + 7: ["none"] + } + +xlen = { + 1: 64, + 2: 64, + 3: 32, + 4: 32, + 5: 32, + 6: 64, + 7: 32} + +comment_dict = { + 1: ["1st Instruction => rs1 = $rs1; rs2 = $rs2 | 2nd Instruction => rs1 = $rs2; rs2 = $rs1\ + | Result of xor goes into $inst & vice versa"], + 2: ["Forwarded $inst1 into $inst2 & the result back into $inst1","Checking load-to-use hazard!"], + 3: ["Expected use-case sequence -> Aims to test things like pipeline forwarding"], + 4: ["Forwarded $inst1 into $inst2 & the result back into $inst1","Checking load-to-use hazard!"], + 5: ["Forwarded $inst1 into $inst2 & the result back into $inst1","Checking load-to-use hazard!"], + 6: ["Expected use-case sequence -> Aims to test things like pipeline forwarding"], + 7: ["Expected use-case sequence -> Aims to test things like pipeline forwarding"]} + +n_i = { + 1: [27,3], + 2: [28,30,3], + 3: [27,1], + 4: [28,30,3], + 5: [28,29,3], + 6: [27,1], + 7: [27,1] + } + +swreg1 = "x31" + +seed = 10 + +#------------------------------------------------------------------------------------------------------------------ + +config_ZKn = ['aes64ds','aes64dsm','aes64es','aes64esm','sha256sig0','sha256sig1','sha256sum0','sha256sum1',\ + 'sha512sig0','sha512sig1','sha512sum0','sha512sum1','aes64im','aes32esi','aes32esmi','aes32dsi',\ + 'aes32dsmi','sha512sig0h','sha512sig0l','sha512sig1h','sha512sig1l','sha512sum0r','sha512sum1r'] + +config_ZKs = ['sm3p0','sm3p1','sm4ed','sm4ks'] + +if os.path.isdir(os.getcwd()+"/real_world_tests") == False: + os.mkdir(os.getcwd()+"/real_world_tests") + os.mkdir(os.getcwd()+"/real_world_tests/RV32IK") + os.mkdir(os.getcwd()+"/real_world_tests/RV64IK") + +for key in instr_dict: + for z in instr_dict[key]: + with open(os.getcwd()+'/real_world_tests/RV'+str(xlen[key])+'IK/'+z+'-rwp1.S','w') as out: + offset_val = 0 + if z in config_ZKn: + config = "ZKn" + elif z in config_ZKs: + config = "ZKs" + sp = start_str.replace("$inst",z).replace("$swreg1",swreg1).replace("$xlen",str(xlen[key])).replace("$config",config) + out.write(sp) + out.write('\n\n') + random.seed(seed) + for i in range(1,n_i[key][0]): + out.write("inst_"+str(i-1)+":\n") + + r1 = random.randint(0,2**xlen[key]-1) + r2 = random.randint(0,2**xlen[key]-1) + r3 = random.randint(0,2**xlen[key]-1) + r4 = random.randint(0,2**xlen[key]-1) + r5 = random.randint(0,2**xlen[key]-1) + r6 = random.randint(0,2**xlen[key]-1) + r1_str = '{0:#0{1}x}'.format(r1,int(xlen[key]/4)+2) + r2_str = '{0:#0{1}x}'.format(r2,int(xlen[key]/4)+2) + r3_str = '{0:#0{1}x}'.format(r3,int(xlen[key]/4)+2) + r4_str = '{0:#0{1}x}'.format(r4,int(xlen[key]/4)+2) + r5_str = '{0:#0{1}x}'.format(r5,int(xlen[key]/4)+2) + r6_str = '{0:#0{1}x}'.format(r6,int(xlen[key]/4)+2) + + if key == 1: + comment_str = comment_dict[key][0].replace("$rs1","x"+str(i)).replace("$rs2","x"+str(i+1)).replace("$inst",z) + + sp = string1.replace("$rs1","x"+str(i)).replace("$rs2","x"+str(i+1))\ + .replace("$rd1","x"+str(i+2)).replace("$rd2","x"+str(i+3)).replace("$rd3","x"+str(i+4))\ + .replace("$inst",z).replace("$swreg1",swreg1).replace("$offset1",str(offset_val))\ + .replace("$offset2",str(int(offset_val+xlen[key]/8)))\ + .replace("$offset3",str(int(offset_val+xlen[key]/4)))\ + .replace("$r1_val",r1_str).replace("$r2_val",r2_str).replace("$comment",comment_str) + + offset_val = int(offset_val + (xlen[key]*6)/16) + out.write(sp) + out.write('\n\n') + + elif key == 2 or key == 4 or key == 5: + for j in instr_f[key]: + comment_str = comment_dict[key][0].replace("$inst1",j).replace("$inst2",z) + + if key == 2 or key == 4: + if j == 'not': + sp = string2_not.replace("$rs1","x"+str(i)).replace("$rs2","x"+str(i+1))\ + .replace("$rs3","x"+str(i+2)).replace("$rs4","x"+str(i+3)).replace("$inst1",j)\ + .replace("$inst2",z).replace("$swreg1",swreg1).replace("$offset1",str(offset_val))\ + .replace("$offset2",str(int(offset_val+xlen[key]/8)))\ + .replace("$offset3",str(int(offset_val+xlen[key]/4)))\ + .replace("$r1_val",r1_str).replace("$r2_val",r2_str).replace("$comment",comment_str) + else: + sp = string2.replace("$rs1","x"+str(i)).replace("$rs2","x"+str(i+1))\ + .replace("$rs3","x"+str(i+2)).replace("$rs4","x"+str(i+3)).replace("$inst1",j)\ + .replace("$inst2",z).replace("$swreg1",swreg1).replace("$offset1",str(offset_val))\ + .replace("$offset2",str(int(offset_val+xlen[key]/8)))\ + .replace("$offset3",str(int(offset_val+xlen[key]/4)))\ + .replace("$r1_val",r1_str).replace("$r2_val",r2_str).replace("$comment",comment_str) + elif key == 5: + if j == 'not': + sp = string5_not.replace("$rs1","x"+str(i)).replace("$rs2","x"+str(i+1))\ + .replace("$rs3","x"+str(i+2)).replace("$rs4","x"+str(i+3)).replace("$inst1",j)\ + .replace("$inst2",z).replace("$swreg1",swreg1).replace("$offset1",str(offset_val))\ + .replace("$offset2",str(int(offset_val+xlen[key]/8)))\ + .replace("$offset3",str(int(offset_val+xlen[key]/4)))\ + .replace("$r1_val",r1_str).replace("$r2_val",r2_str).replace("$comment",comment_str) + else : + sp = string5.replace("$rs1","x"+str(i)).replace("$rs2","x"+str(i+1))\ + .replace("$rs3","x"+str(i+2)).replace("$rs4","x"+str(i+3)).replace("$inst1",j)\ + .replace("$inst2",z).replace("$swreg1",swreg1).replace("$offset1",str(offset_val))\ + .replace("$offset2",str(int(offset_val+xlen[key]/8)))\ + .replace("$offset3",str(int(offset_val+xlen[key]/4)))\ + .replace("$r1_val",r1_str).replace("$r2_val",r2_str).replace("$comment",comment_str) + + offset_val = int(offset_val + (xlen[key]*6)/16) + out.write(sp) + out.write('\n\n') + + elif key == 3: + comment_str = comment_dict[key][0] + + sp = string4.replace("$rs1","x"+str(i)).replace("$rs2","x"+str(i+1))\ + .replace("$rs3","x"+str(i+2)).replace("$rs4","x"+str(i+3)).replace("$rs5","x"+str(i+4))\ + .replace("$inst",z).replace("$swreg1",swreg1).replace("$offset1",str(offset_val))\ + .replace("$r1_val",r1_str).replace("$r2_val",r2_str).replace("$r3_val",r3_str)\ + .replace("$r4_val",r4_str).replace("$r5_val",r5_str)\ + .replace("$comment",comment_str) + + offset_val = offset_val + int(xlen[key]/8) + out.write(sp) + out.write('\n\n') + elif key == 6 or key == 7: + comment_str = comment_dict[key][0] + + sp = string7.replace("$rs1","x"+str(i)).replace("$rs2","x"+str(i+1))\ + .replace("$rs3","x"+str(i+2)).replace("$rs4","x"+str(i+3)).replace("$rs5","x"+str(i+4))\ + .replace("$rs6","x"+str(i+5))\ + .replace("$inst",z).replace("$swreg1",swreg1).replace("$offset1",str(offset_val))\ + .replace("$r1_val",r1_str).replace("$r2_val",r2_str).replace("$r3_val",r3_str)\ + .replace("$r4_val",r4_str).replace("$r5_val",r5_str)\ + .replace("$r6_val",r6_str)\ + .replace("$comment",comment_str) + + offset_val = offset_val + int(xlen[key]/8) + out.write(sp) + out.write('\n\n') + + ed = end_str.replace("$swreg1",swreg1)\ + .replace("$fill_val",str(((n_i[key][0])-1)*n_i[key][len(n_i[key])-1]*len(instr_f[key]))) + out.write(ed) + out.write('\n') + out.close() + print("Test File Generated for "+str(xlen[key])+"-bit "+z+"-Test Pattern 1!") + + if key == 2 or key == 4 or key == 5: + with open(os.getcwd()+'/real_world_tests/RV'+str(xlen[key])+'IK/'+z+'-rwp2.S','w') as out: + offset_val1 = 0 + offset_val2 = 0 + if z in config_ZKn: + config = "ZKn" + elif z in config_ZKs: + config = "ZKs" + sp = start_str.replace("$inst",z).replace("$swreg1",swreg1).replace("$xlen",str(xlen[key])).replace("$config",config) + out.write(sp) + out.write('\n\n') + out.write("la x1, rvtest_data") + out.write('\n\n') + random.seed(seed) + for i in range(2,n_i[key][1]): + out.write("inst_"+str(i-2)+":\n") + + comment_str = comment_dict[key][1] + + if key == 2 or key ==4: + sp = string3.replace("$rs0","x1").replace("$rs1","x"+str(i))\ + .replace("$rs2","x"+str(i+1)).replace("$inst",z).replace("$swreg1",swreg1)\ + .replace("$offset1",str(offset_val1)).replace("$offset2",str(offset_val2))\ + .replace("$offset3",str(int(offset_val2+xlen[key]/8))).replace("$comment",comment_str) + elif key == 5: + sp = string6.replace("$rs0","x1").replace("$rs1","x"+str(i))\ + .replace("$rs2","x"+str(i+1)).replace("$rs3","x"+str(i+2))\ + .replace("$inst",z).replace("$swreg1",swreg1).replace("$offset1",str(offset_val1))\ + .replace("$offset2",str(int(offset_val1+xlen[key]/8))).replace("$offset3",str(offset_val2))\ + .replace("$offset4",str(int(offset_val2+xlen[key]/8))).replace("$comment",comment_str) + + offset_val1 = int(offset_val1 + xlen[key]/8) + offset_val2 = int(offset_val2 + xlen[key]/4) + out.write(sp) + out.write('\n\n') + + out.write(end_str1) + out.write('\n') + for j in range(2,30): + x = random.randint(0,2**xlen[key]-1) + x_str = '{0:#0{1}x}'.format(x,int(xlen[key]/4)+2) + if xlen[key] == 64: + out.write(".dword "+x_str+"\n") + else: + out.write(".word "+x_str+"\n") + + ed = end_str2.replace("$swreg1",swreg1).replace("$fill_val",str((n_i[key][1]-2)*2)) + out.write(ed) + out.write('\n') + out.close() + print("Test File Generated for "+str(xlen[key])+"-bit "+z+"-Test Pattern 2!") diff --git a/riscv-ctg/riscv_ctg/requirements.txt b/riscv-ctg/riscv_ctg/requirements.txt new file mode 100644 index 000000000..af94a163f --- /dev/null +++ b/riscv-ctg/riscv_ctg/requirements.txt @@ -0,0 +1,5 @@ +click +ruamel.yaml>=0.16.0 +colorlog +python-constraint +riscv_isac>=0.14.0 diff --git a/riscv-ctg/riscv_ctg/utils.py b/riscv-ctg/riscv_ctg/utils.py new file mode 100644 index 000000000..d3dd53127 --- /dev/null +++ b/riscv-ctg/riscv_ctg/utils.py @@ -0,0 +1,359 @@ +# See LICENSE.incore for details + +"""Common Utils """ +import sys +import os +import subprocess +import shlex +from riscv_ctg.log import logger +import ruamel +from ruamel.yaml import YAML +from collections import defaultdict +import riscv_ctg.constants as const +from riscv_isac.utils import combineReader + +yaml = YAML(typ="rt") +yaml.default_flow_style = False +yaml.allow_unicode = True + +def load_yaml(foo): + try: + with open(foo, "r") as file: + return dict(yaml.load(file)) + except ruamel.yaml.constructor.DuplicateKeyError as msg: + logger = logging.getLogger(__name__) + error = "\n".join(str(msg).split("\n")[2:-7]) + logger.error(error) + raise SystemExit + +def gen_format_data(): + ''' + Generate dictionary from template.yaml file with the structure: + Format: + - ISA + - Mnemonics + ''' + op_template = load_yaml(const.template_file) + + # Initialize nested dictionary + nested_dict = lambda: defaultdict(nested_dict) + format_dict = nested_dict() + + for mnemonic, data in op_template.items(): + if mnemonic not in ['metadata']: + format_type = data['formattype'] + isa = data['isa'] + + for each in isa: + format_dict[format_type][each][mnemonic] = None + + return format_dict + +def get_instr_list(): + ''' + Get list of all instructions defined in template file + ''' + op_template = load_yaml(const.template_file) + + instr_lst = list(op_template.keys()) + instr_lst.remove('metadata') + + return instr_lst + +def load_yamls(foo): + with combineReader(foo) as fp: + return dict(yaml.load(fp)) + +class makeUtil(): + """ + Utility for ease of use of make commands like `make` and `pmake`. + Supports automatic addition and execution of targets. Uses the class + :py:class:`shellCommand` to execute commands. + """ + def __init__(self,makeCommand='make',makefilePath="./Makefile"): + """ Constructor. + + :param makeCommand: The variant of make to be used with optional arguments. + Ex - `pmake -j 8` + + :type makeCommand: str + + :param makefilePath: The path to the makefile to be used. + + :type makefilePath: str + + """ + self.makeCommand=makeCommand + self.makefilePath = makefilePath + self.targets = [] + def add_target(self,command,tname=""): + """ + Function to add a target to the makefile. + + :param command: The command to be executed when the target is run. + + :type command: str + + :param tname: The name of the target to be used. If not specified, TARGET is used as the name. + + :type tname: str + """ + if tname == "": + tname = "TARGET"+str(len(self.targets)) + with open(self.makefilePath,"a") as makefile: + makefile.write("\n\n.PHONY : " + tname + "\n" + tname + " :\n\t"+command.replace("\n","\n\t")) + self.targets.append(tname) + def execute_target(self,tname,cwd="./"): + """ + Function to execute a particular target only. + + :param tname: Name of the target to execute. + + :type tname: str + + :param cwd: The working directory to be set while executing the make command. + + :type cwd: str + + :raise AssertionError: If target name is not present in the list of defined targets. + + """ + assert tname in self.targets, "Target does not exist." + shellCommand(self.makeCommand+" -f "+self.makefilePath+" "+tname).run(cwd=cwd) + def execute_all(self,cwd): + """ + Function to execute all the defined targets. + + :param cwd: The working directory to be set while executing the make command. + + :type cwd: str + + """ + shellCommand(self.makeCommand+" -f "+self.makefilePath+" "+" ".join(self.targets)).run(cwd=cwd) + + +class Command(): + """ + Class for command build which is supported + by :py:mod:`suprocess` module. Supports automatic + conversion of :py:class:`pathlib.Path` instances to + valid format for :py:mod:`subprocess` functions. + """ + + def __init__(self, *args, pathstyle='auto', ensure_absolute_paths=False): + """Constructor. + + :param pathstyle: Determine the path style when adding instance of + :py:class:`pathlib.Path`. Path style determines the slash type + which separates the path components. If pathstyle is `auto`, then + on Windows backslashes are used and on Linux forward slashes are used. + When backslashes should be prevented on all systems, the pathstyle + should be `posix`. No other values are allowed. + + :param ensure_absolute_paths: If true, then any passed path will be + converted to absolute path. + + :param args: Initial command. + + :type pathstyle: str + + :type ensure_absolute_paths: bool + """ + self.ensure_absolute_paths = ensure_absolute_paths + self.pathstyle = pathstyle + self.args = [] + + for arg in args: + self.append(arg) + + def append(self, arg): + """Add new argument to command. + + :param arg: Argument to be added. It may be list, tuple, + :py:class:`Command` instance or any instance which + supports :py:func:`str`. + """ + to_add = [] + if type(arg) is list: + to_add = arg + elif type(arg) is tuple: + to_add = list(arg) + elif isinstance(arg, type(self)): + to_add = arg.args + elif isinstance(arg, str) and not self._is_shell_command(): + to_add = shlex.split(arg) + else: + # any object which will be converted into str. + to_add.append(arg) + + # Convert all arguments to its string representation. + # pathlib.Path instances + to_add = [ + self._path2str(el) if isinstance(el, pathlib.Path) else str(el) + for el in to_add + ] + self.args.extend(to_add) + + def clear(self): + """Clear arguments.""" + self.args = [] + + def run(self, **kwargs): + """Execute the current command. + + Uses :py:class:`subprocess.Popen` to execute the command. + + :return: The return code of the process . + :raise subprocess.CalledProcessError: If `check` is set + to true in `kwargs` and the process returns + non-zero value. + """ + kwargs.setdefault('shell', self._is_shell_command()) + cwd = self._path2str(kwargs.get( + 'cwd')) if not kwargs.get('cwd') is None else self._path2str( + os.getcwd()) + kwargs.update({'cwd': cwd}) + logger.debug(cwd) + # When running as shell command, subprocess expects + # The arguments to be string. + logger.debug(str(self)) + cmd = str(self) if kwargs['shell'] else self + x = subprocess.Popen(cmd, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + **kwargs) + out, err = x.communicate() + out = out.rstrip() + err = err.rstrip() + if x.returncode != 0: + if out: + logger.error(out.decode("ascii")) + if err: + logger.error(err.decode("ascii")) + else: + if out: + logger.warning(out.decode("ascii")) + if err: + logger.warning(err.decode("ascii")) + return x.returncode + + def _is_shell_command(self): + """ + Return true if current command is supposed to be executed + as shell script otherwise false. + """ + return any('|' in arg for arg in self.args) + + def _path2str(self, path): + """Convert :py:class:`pathlib.Path` to string. + + The final form of the string is determined by the + configuration of `Command` instance. + + :param path: Path-like object which will be converted + into string. + :return: String representation of `path` + """ + path = pathlib.Path(path) + if self.ensure_absolute_paths and not path.is_absolute(): + path = path.resolve() + + if self.pathstyle == 'posix': + return path.as_posix() + elif self.pathstyle == 'auto': + return str(path) + else: + raise ValueError(f"Invalid pathstyle {self.pathstyle}") + + def __add__(self, other): + cmd = Command(self, + pathstyle=self.pathstyle, + ensure_absolute_paths=self.ensure_absolute_paths) + cmd += other + return cmd + + def __iadd__(self, other): + self.append(other) + return self + + def __iter__(self): + """ + Support iteration so functions from :py:mod:`subprocess` module + support `Command` instance. + """ + return iter(self.args) + + def __repr__(self): + return f'<{self.__class__.__name__} args={self.args}>' + + def __str__(self): + return ' '.join(self.args) + + +class shellCommand(Command): + """ + Sub Class of the command class which always executes commands as shell commands. + """ + + def __init__(self, *args, pathstyle='auto', ensure_absolute_paths=False): + """ + :param pathstyle: Determine the path style when adding instance of + :py:class:`pathlib.Path`. Path style determines the slash type + which separates the path components. If pathstyle is `auto`, then + on Windows backslashes are used and on Linux forward slashes are used. + When backslashes should be prevented on all systems, the pathstyle + should be `posix`. No other values are allowed. + + :param ensure_absolute_paths: If true, then any passed path will be + converted to absolute path. + + :param args: Initial command. + + :type pathstyle: str + + :type ensure_absolute_paths: bool + + """ + return super().__init__(*args, + pathstyle=pathstyle, + ensure_absolute_paths=ensure_absolute_paths) + + def _is_shell_command(self): + return True + +def sys_command(command): + logger.warning('$ {0} '.format(' '.join(shlex.split(command)))) + x = subprocess.Popen(shlex.split(command), + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) + try: + out, err = x.communicate(timeout=5) + except subprocess.TimeoutExpired: + x.kill() + out, err = x.communicate() + + out = out.rstrip() + err = err.rstrip() + if x.returncode != 0: + if out: + logger.error(out.decode("ascii")) + if err: + logger.error(err.decode("ascii")) + else: + if out: + logger.debug(out.decode("ascii")) + if err: + logger.debug(err.decode("ascii")) + return out.decode("ascii") + +def sys_command_file(command, filename): + cmd = command.split(' ') + cmd = [x.strip(' ') for x in cmd] + cmd = [i for i in cmd if i] + logger.debug('{0} > {1}'.format(' '.join(cmd), filename)) + fp = open(filename, 'w') + out = subprocess.Popen(cmd, stdout=fp, stderr=fp) + stdout, stderr = out.communicate() + fp.close() + diff --git a/riscv-ctg/setup.cfg b/riscv-ctg/setup.cfg new file mode 100644 index 000000000..7b4085942 --- /dev/null +++ b/riscv-ctg/setup.cfg @@ -0,0 +1,16 @@ +[bumpversion] +current_version = 0.12.1 +commit = True +tag = True + +[bumpversion:file:riscv_ctg/__init__.py] +search = __version__ = '{current_version}' +replace = __version__ = '{new_version}' + +[bdist_wheel] +universal = 1 + +[flake8] +exclude = docs + +[aliases] diff --git a/riscv-ctg/setup.py b/riscv-ctg/setup.py new file mode 100644 index 000000000..cfba8937c --- /dev/null +++ b/riscv-ctg/setup.py @@ -0,0 +1,63 @@ +# See LICENSE.incore.incore for details + +"""The setup script.""" + +from setuptools import setup, find_packages +import os +import riscv_ctg + +# Base directory of package +here = os.path.abspath(os.path.dirname(__file__)) + + +def read(*parts): + with codecs.open(os.path.join(here, *parts), 'r') as fp: + return fp.read() +def read_requires(): + with open(os.path.join(here, "riscv_ctg/requirements.txt"),"r") as reqfile: + return reqfile.read().splitlines() + +#Long Description +with open("README.rst", "r") as fh: + readme = fh.read() + +setup_requirements = [ ] + +test_requirements = [ ] + +setup( + name='riscv_ctg', + version=riscv_ctg.__version__, + description="RISC-V CTG", + long_description=readme + '\n\n', + classifiers=[ + "Programming Language :: Python :: 3.6", + "License :: OSI Approved :: BSD License", + "Development Status :: 4 - Beta" + ], + url='https://github.com/riscv/riscv-ctg', + author="InCore Semiconductors Pvt. Ltd.", + author_email='info@incoresemi.com', + license="BSD-3-Clause", + packages=find_packages(), + package_dir={'riscv_ctg': 'riscv_ctg'}, + package_data={ + 'riscv_ctg': [ + 'requirements.txt', + 'data/*', + 'env/*' + ] + }, + install_requires=read_requires(), + python_requires='>=3.6.0', + entry_points={ + 'console_scripts': [ + 'riscv_ctg=riscv_ctg.main:cli', + ], + }, + include_package_data=True, + keywords='riscv_ctg', + test_suite='tests', + tests_require=test_requirements, + zip_safe=False, +) diff --git a/riscv-ctg/tests/__init__.py b/riscv-ctg/tests/__init__.py new file mode 100644 index 000000000..4dbe8ae81 --- /dev/null +++ b/riscv-ctg/tests/__init__.py @@ -0,0 +1,2 @@ +# See LICENSE.incore for details +"""Unit test package for riscv_ctg.""" diff --git a/riscv-ctg/tests/test_riscv_ctg.py b/riscv-ctg/tests/test_riscv_ctg.py new file mode 100644 index 000000000..d457e7eb1 --- /dev/null +++ b/riscv-ctg/tests/test_riscv_ctg.py @@ -0,0 +1,21 @@ +# See Licence.incore for details. +from click.testing import CliRunner +from riscv_ctg.main import cli +from riscv_ctg.ctg import ctg +import pytest + +@pytest.fixture +def runner(): + return CliRunner() + +def test_version(runner): + '''Testing version option''' + result = runner.invoke(cli, ['--version']) + assert result.exit_code == 0 + +# -r -d temp1 -x 32 -cf sample_cgfs/rv32i.cgf -v debu +def test_rv32i(runner): + ''' Testing rv32 runs ''' + result = runner.invoke(cli, ['--randomize', '--out-dir', 'rv32i', '-cf', + '../sample_cgfs/rv32i.cgf', '-v', 'debug']) + assert result.exit_code == 0 or result.exit_code == 1 diff --git a/riscv-isac/.gitignore b/riscv-isac/.gitignore new file mode 100644 index 000000000..43091aa95 --- /dev/null +++ b/riscv-isac/.gitignore @@ -0,0 +1,105 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# dotenv +.env + +# virtualenv +.venv +venv/ +ENV/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ + +# IDE settings +.vscode/ \ No newline at end of file diff --git a/riscv-isac/CHANGELOG.md b/riscv-isac/CHANGELOG.md new file mode 100644 index 000000000..f10a284bd --- /dev/null +++ b/riscv-isac/CHANGELOG.md @@ -0,0 +1,169 @@ +# CHANGELOG + +This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +Please note the header `WIP-DEV` is to always remain indicating the changes done on the dev branch. +Only when a release to the main branch is done, the contents of the WIP-DEV are put under a +versioned header while the `WIP-DEV` is left empty + +## [WIP-DEV] +- Updating CONTRIBUTING.rst to capture the new git strategy adopted to follow a monthly release + cadence. +- Add pluggy to install\_requires and move pytest to tests\_requirements.txt +- Added `pmpaddr0` to `pmpaddr15` registers for coverage of Physical Memory Protection +- Minor fix to compressed immediate decoding and compressed register decoding +- Modified the regular expression to correctly match and return 'reg_commit' for registers x1 to x9. +- Changed compressed immediate decoding and added comments for readability + +## [0.18.0] - 2023-07-26 +- Add support to decode compressed instructions + +## [0.17.0] - 2022-10-25 +- Improve data propagation reports to capture multiple signature updates per coverpoint +- Add a CLI flag to explicitly log the redundant coverpoints while normalizing the CGF files + +## [0.16.1] - 2022-10-20 +- Fix length of commitval to 32 bits if flen is 32 for f registers in sail parser. + +## [0.16.0] - 2022-09-28 +- Refactored the instruction object class + +## [0.15.0] - 2022-08-25 +- Added support for instruction aliases + +## [0.14.0] - 2022-08-08 +- Add fields to instruction object +- Enable generic coverage evaluation mechanisms for floating point instructions +- Fix coverpoint generation to account for nan boxing of fp instructions. +- Add fields(frm, fcsr, nan_prefix) for fp instructions + +## [0.13.2] - 2022-05-23 +- Error reporting for missing coverlabel in cgf file + +## [0.13.1] - 2022-05-07 +- Fix mistune version for doc builds. + +## [0.13.0] - 2022-05-02 +- Covergroup format revised. +- Added support for Pseudoinstructions for coverage computation. + +## [0.12.0] - 2022-04-15 +- Parallelized coverage computation. +- Added feature to remove coverpoints when hit. +- Added CLI option to specify number of processes to be spawned. +- Added CLI option to turn on/off feature to remove hit coverpoints. + +## [0.11.0] - 2022-04-03 +- Added plugins to use new rvopcode format +- Added CLI option to setup rvopcode plugin + +## [0.10.2] - 2022-03-15 +- Added method to generate data patterns for bitmanip instructions + +## [0.10.1] - 2022-02-10 +- Added vxsat to supported csr_regs +- Added comments to coverpoint functions for P-ext +- Removed unused tuple type for bit_width parameters in P-ext coverpoint functions + +## [0.10.0] - 2022-01-27 +- Added support for instructions from B extension. +- Bug fix for bgeu instruction. + +## [0.9.0] - 2022-01-07 +- Added support for P extension cover point generation and instruction decoding. +- Allowed an instruction to generate results in multiple registers. + +## [0.8.0] - 2021-10-30 +- Added cross combination coverage support. + +## [0.7.3] - 2021-09-02 +- Updated logger to enable logging for API calls. + +## [0.7.2] - 2021-08-18 +- Added decoding support for K extension instructions based on latest spec + +## [0.7.1] - 2021-08-12 +- Bug fix for error while using byte_count with overlap = Y. + +## [0.7.0] - 2021-08-11 +- Adding support for floating point extension coverpoints +- Bug fixes for instruction decoder and improved pretty printing. +- fix for uninitialized total_categories variable in coverage. +- fixed CONTRIBUTING.rst file + +## [0.6.6] - 2021-08-03 +- Bug fix for error while decoding instruction name + +## [0.6.5] - 2021-07-14 +- Bug fix for error while generating Data Propagation Report. + +## [0.6.4] - 2021-07-08 +- Added support for CSR coverage and its architectural state +- Updated the merge function to support multiprocessing +- Added a parameter '-p' ( number of processes ) in merge command +- Documentation update for CSR coverpoints +- Return value of parsers changed from 5 independent values (hexcode, addr, reg commmit, csr commit, mnemonics) to instruction object updated with these values +- Argument of decode and all decoding functions (in internaldecoder) changed from hexcode and addr to instruction object + +## [0.6.3] - 2021-06-24 +- Documentation updates to reflect plugin usage. +- Minor bug fixes in coverage reporting. +- Improved CLI help messages. + +## [0.6.2] - 2021-06-15 +- Added parser plugins for sail and spike +- Added decoder plugin +- Added arguments in main.py for custom plugin paths and names. + +## [0.6.1] - 2021-06-11 +- Added initial support for F extension coverpoints based on IBM models. +- Added support for F extension architectural state +- Fixed author information and repo link in setup.py + +## [0.6.0] - 2021-05-27 +- added support in parsers for K-scalar crypto instructions +- added support for abstract functions: uniform random, byte-count, leading-ones, leading-zeros, + trailing-ones, trailing-zeros +- now maintain a separate list of instructions which require unsigned interpretation of rs1 and rs2. +- restructured coverage report handling to preserve comments throughout processing and merging. +- switched yaml to a round-trip parser for preserving comments + +## [0.5.2] - 2021-02-23 +- Moved ci to github actions +- fixed links in docs + +## [0.5.1] - 2020-12-14 +- Fixed operand signedness for m ext ops. + +## [0.5.0] - 2020-11-18 +- added support to take multiple cgf files as input. The order matters +- added support for abstract function of special dataset + +## [0.4.0] - 2020-11-10 +- added special data set for r-type instructions +- fixed data propagation report generation and templates +- using classes to manage architectural state and statistics +- updated docs + +## [0.3.1] - 2020-10-26 + - use logger instead of log in coverage.py + + +## [0.3.0] - 2020-10-26 +- Adding support for Data propagation report generation +- Added 'sig-label' as the new cli option under coverage to capture DP reports +- Added support in sail parsers to extract mnemonics also from the trace file +- added pytablewriter as part of the requirements + +## [0.2.0] - 2020-10-23 +- Added documentation for CGF and usage +- Added normalization routine as cli +- Added abstract functions +- using click for cli +- adding parsers for sail and spike +- added support for filtering based on labels +- added merge-reports cli command + + +## [0.1.0] - 2020-06-25 +- initial draft diff --git a/riscv-isac/CONTRIBUTING.rst b/riscv-isac/CONTRIBUTING.rst new file mode 100644 index 000000000..8b031ae17 --- /dev/null +++ b/riscv-isac/CONTRIBUTING.rst @@ -0,0 +1,105 @@ +.. See LICENSE.incore for details + +.. highlight:: shell + +============ +Contributing +============ + +Your inputs are welcome and greatly appreciated! We want to make contributing to this project as easy and transparent as possible, whether it's: + +- Reporting a bug +- Discussing the current state of the code +- Submitting a fix +- Proposing new features +- Becoming a maintainer + +We develop with Github +---------------------- + +We use github to host code, to track issues and feature requests, as well as accept pull requests. + +Git Strategy +------------ + +The repo adopts a simple git strategy where all contributions to the repo are made to the ``dev`` +branch (i.e. all Pull-Requests must use ``dev`` as the target branch). On a monthly cadence (decided +and controlled by the SIG-ARCH-TEST members) the ``dev`` branch will be merged to the ``main`` to by +the official maintainers of the repo. This will create an official release capturing all the +development over the month into a single release. + +To implement the above strategy successfully the following needs be followed: + +* Developers: All pull-requests from developers must target the ``dev`` branch and the PR must +contain an entry in the CHANGELOG.md file under `[WIP-DEV]` section. +* Maintainers: When a making a release the maintainers shall assign semantic version number by +updating the CHANGELOG and the respective python files before raising a PR from the `dev` to `main`. + +All changes happen through Pull Requests +---------------------------------------- + +Pull requests are the best way to propose changes to the codebase. We actively welcome your pull requests: + +1. Fork the repo and create your branch from `dev`. +2. If you have updated the docs, ensure that they render correctly in the respective format. +3. Make sure to create an entry in the CHANGELOG.md under the `WIP-DEV` section. +4. Ensure the existing framework is not broken and still passes the basic checks. +5. Please include a comment with the SPDX license identifier in all source files, for example: + ``` + // SPDX-License-Identifier: BSD-3-Clause + ``` +6. Issue that pull request - make sure the target is to the dev branch. + +Checks for a PR +--------------- + +Make sure your PR meets all the following requirements: + +1. You have made an entry in the CHANGELOG.md undet the `WIP-DEV` section. +3. The commit messages are verbose. +4. You PR doesn't break existing framework. + +Versioning (for maintainers only) +--------------------------------- + +When issuing pull requests from the `dev` branch to the `main` branch, an entry in the CHANGELOG.md +is mandatory. The repo adheres to the [`Semantic Versioning`](https://semver.org/spec/v2.0.0.html) scheme. +Following guidelines must be followed while assigning a new version number : + +- Patch-updates: all doc updates (like typos, more clarification,etc) will be patches. Beautification enhancements will also be treated as patch updates. Certain bug fixes to existing code may be treated as patches as well. +- Minor-updates: Updates to code with new extensions, features, run time optimizations can be + treated as minor updates. +- Major-updates: Changes to the framework flow (backward compatible or incompatible) will be treated + as major updates. + +Note: You can have either a patch or minor or major update. + +Each PR will also require the tools version to be bumped. This can be achieved using the following +commands:: + + $ bumpversion --allow-dirty --no-tag --config-file setup.cfg patch #options: major / minor / patch + +bumpversion can be installed using `pip install bumpversion` + +All contributions will be under the permissive open-source License +------------------------------------------------------------------ + +In short, when you submit code changes, your submissions are understood to be under a permissive open source license like BSD-3, Apache-2.0 and CC, etc that covers the project. Feel free to contact the maintainers if that's a concern. + +Report bugs using Github's `issues `_ +------------------------------------------------------------------------------------ + +We use GitHub issues to track public bugs. Report a bug by `opening a new issue `_ it's that easy! + +Write bug reports with detail, background, and sample code +---------------------------------------------------------- + +**Great Bug Reports** tend to have: + +- A quick summary and/or background +- Steps to reproduce + - Be specific! + - Give sample code if you can. +- What you expected would happen +- What actually happens +- Notes (possibly including why you think this might be happening, or stuff you tried that didn't work) diff --git a/riscv-isac/LICENSE.incore b/riscv-isac/LICENSE.incore new file mode 100644 index 000000000..c1c837a28 --- /dev/null +++ b/riscv-isac/LICENSE.incore @@ -0,0 +1,30 @@ +BSD 3-Clause License + +Copyright (c) 2020, InCore Semiconductors Pvt. Ltd. + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/riscv-isac/MANIFEST.in b/riscv-isac/MANIFEST.in new file mode 100644 index 000000000..b888a5a6d --- /dev/null +++ b/riscv-isac/MANIFEST.in @@ -0,0 +1,7 @@ +include LICENSE.incore +include README.rst +include riscv_isac/requirements.txt +recursive-include riscv_isac/data/* + +recursive-exclude * __pycache__ +recursive-exclude * *.py[co] diff --git a/riscv-isac/README.rst b/riscv-isac/README.rst new file mode 100644 index 000000000..819738270 --- /dev/null +++ b/riscv-isac/README.rst @@ -0,0 +1,5 @@ +##################################### +**RISC-V ISA Coverage** : RISC-V ISAC +##################################### + +Latest documentation of riscv_isac can be found on readthedocs `here `_ diff --git a/riscv-isac/docs/Makefile b/riscv-isac/docs/Makefile new file mode 100644 index 000000000..9dcaa1136 --- /dev/null +++ b/riscv-isac/docs/Makefile @@ -0,0 +1,26 @@ +# See LICENSE.incore for details + +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SPHINXPROJ = riscv_isac +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +clean: + @$(SPHINXBUILD) -M clean "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + diff --git a/riscv-isac/docs/README.md b/riscv-isac/docs/README.md new file mode 100644 index 000000000..50c16d0d6 --- /dev/null +++ b/riscv-isac/docs/README.md @@ -0,0 +1,15 @@ +# Build the docs + +## For PDF +``` +pip install -r requirements.txt +make latexpdf +evince build/latex/*.pdf +``` + +## HTML +``` +pip install -r requirements.txt +make html +firefox build/html/index.html +``` diff --git a/riscv-isac/docs/requirements.txt b/riscv-isac/docs/requirements.txt new file mode 100644 index 000000000..2a1d69448 --- /dev/null +++ b/riscv-isac/docs/requirements.txt @@ -0,0 +1,40 @@ +alabaster==0.7.12 +Babel==2.7.0 +Cerberus==1.3.1 +certifi==2019.6.16 +chardet==3.0.4 +doc8==0.8.0 +docutils==0.14 +gitdb2==2.0.5 +idna==2.8 +imagesize==1.1.0 +Jinja2==2.10.1 +MarkupSafe==1.1.1 +oyaml==0.9 +packaging==19.0 +pbr==5.3.1 +Pygments==2.4.2 +pyparsing==2.4.0 +python-dateutil==2.8.0 +pytz==2019.1 +PyYAML==5.1.1 +requests==2.22.0 +restructuredtext-lint==1.3.0 +ruamel.yaml==0.15.97 +six==1.12.0 +smmap2==2.0.5 +snowballstemmer==1.2.1 +Sphinx==3.0.4 +sphinx-rtd-theme==0.4.3 +sphinxcontrib-autoyaml==0.5.0 +sphinxcontrib-mermaid +sphinxcontrib-websupport==1.1.2 +sphinxcontrib-bibtex==1.0.0 +stevedore==1.30.1 +urllib3==1.25.3 +twine==1.13.0 +sphinx_tabs +m2r2==0.2.7 +mistune==0.8.4 +colorlog==4.1.0 +pyelftools==0.26 diff --git a/riscv-isac/docs/source/Cross_coverage.rst b/riscv-isac/docs/source/Cross_coverage.rst new file mode 100644 index 000000000..ae4f9be97 --- /dev/null +++ b/riscv-isac/docs/source/Cross_coverage.rst @@ -0,0 +1,134 @@ +############### +Cross Coverage +############### + +ISAC supports extraction of data dependencies across different instructions in the log file. It can check for possible data hazards (RAW, WAW, WAR) between instructions. +The hazards are checked for instructions belonging to the same window. The window size of the instruction is a parameter (by default taken as 32). +The coverpoints are updated whenever the conditions mentioned in them are matched for a given instruction. + +Syntax for the coverpoints +=========================== + +Each coverpoint is a string constituting of three sections - opcode list, assign list and condition list separated by ``::`` symbol. In each of these lists symbol +``?`` signifies a don't care condition. The delimiter for elements of the list is ``:`` symbol. The template of a generic coverpoint is shown below: + +``[list of opcodes]::[list of assignment statements]::[list of condition statements]`` + +Opcode List: +-------------- +This is the list of instruction names against which we check the name of the current instruction in the queue. Here ``?`` signifies that we needn't check the name +for that instruction as that won't affect the conditions of that coverpoint. Opcode list is a list of tuples and don't care conditions. + +An example of a opcode list : ``[(add,sub):?:?:(mul,mulh):?]`` + +Assign List: +------------- +This list contains the assigning statements for registers. These statements are evaluated using ``exec`` command. The register numbers are assigned to variables. +Under don't care conditions, no assignment is done. + +An example of assign list: ``[a=rd:?:?]`` + +Here a is any variable which is assigned the destination register number of the first instruction. + +Condition List: +---------------- +This contains the evaluation statements to check the data dependencies. In case of don't care conditions, we don't check for data dependecies for that +particular instruction. It conatins conditions for both source as well as destination registers. We can check for both consuming and non-consuming instructions. + +Example of condition list: ``[?:rs1==a or rs2==a]`` + +Here let a be the destination register of the first instruction (assigned by assign list). Then this checks whether any of the source registers are equal to the +destination register of the previous instruction. It basically checks for read after write hazard. + +Cross Coverage Queue +===================== + +This is list of instruction objects in which the data is pushed in the sequence they are parsed. Whenever the queue size becomes equal to the window size, we check for all potential data hazards between the front element of the queue and the rest of the instructions according to the coverpoint and then pop the first element. + +Cross Coverage Class +===================== + +def __init__(self,label,coverpoint): +--------------------------------------- + +The cross coverage class ``cross`` is initialized with the ``label`` and ``coverpoint``. ``result`` stores the coverage for that coverpoint. + +* Arguments: ``self`` instance of the class, ``label`` the instruction name, ``coverpoint`` the coverpoint to be evaluated. + + +.. code-block:: python + + def __init__(self,label,coverpoint): + self.label = label + self.coverpoint = coverpoint + self.result = 0 + +An instance of a class is created for each ``(label,coverpoint)`` pair present in the CGF and all the relevant information about the coverpoint - opcode list, assign list and condition list are extracted. + +def process(self, queue, window_size, addr_pairs): +---------------------------------------------------- + +The ``process`` function of ``cross`` evaluates each coverpoint and updates ``result`` if there is a hit. The data in the coverpoint is evaluated against their corresponding instruction in the queue i.e. if the index of an instruction is i, then it will check and assign statments at index i of the three lists of the coverpoints. If the instruction address doesn't belong to any list of addresses in ``addr_pairs`` we treat is as a don't care. These coverpoints are checked in three steps. + + - First, the name of the first instruction is checked against the corresponding entry in the opcode list. + - If the instruction is present, we assign its register value to a variable using ``exec`` command on the assign list elements. + - Then we check for the conditions in the condition list using ``eval`` command. + The above steps are repeated until the entire coverpoint is evaluated and it's a hit or the conditions are not satisfied and the loop breaks. + +* Arguments: ``self`` instance of the class, ``queue`` the list containing the instructions to be evaluated, ``window_size`` maximum number of instructions to be checked for any coverpoint, ``addr_pairs`` the addresses to be considered while evaluating an instruction +* Returns: None + +def get_metric(self): +---------------------- + +It returns the coverage for that instance. + +* Arguments: ``self`` instance of the class +* Returns: ``result`` the final coverage for that coverpoint + +Updating the CGF +======================== + + - An object dictionary ``obj_dict`` contains an instance of ``cross`` for each ``(label,coverpoint)`` pair. + - As the instrcutions are parsed, they are appended to the ``cross_cover_queue`` which is the list of instructions to be checked. + - When the size of queue becomes equal to the window size, for each entry in ``obj_dict``, the coverpoints are evaluated in ``process`` + - The first element of the queue is popped and the process is repeated. + - After all the instrcutions are parsed, all the instructions in the queue are again evaluated in the above manner till there is nothing to evaluate. + - The final metric for each ``(label,coverpoint)`` instance is updated for each node in the CGF. + +**Examples of coverpoints** + The window size is fixed and equal to 5. + + 1. RAW for an add instruction followed immediately by a subtract instruction. + + .. code-block:: python + + [(add,sub) : (add,sub) ] :: [a=rd : ? ] :: [? : rs1==a or rs2==a ] + + 2. RAW on x10 register for an add instruction followed by a subtract instruction with one non-consuming/non-updating instruction in between. + No update happens to the rd register in between. + + .. code-block:: python + + [(add,sub) : ? : (add,sub) ] :: [a=rd : ? : ? ] :: [rd==x10 : rd!=a and rs1!=a and rs2!=a : rs1==a or rs2==a ] + + 3. WAW for an add instruction followed by a subtract instruction with 3 non-consuming instructions in between. + + .. code-block:: python + + [add : ? : ? : ? : sub] :: [a=rd : ? : ? : ? : ?] :: [? : ? : ? : ? : rd==a] + + 4. WAW for add followed by subtract with 3 consuming instructions in between. + + .. code-block:: python + + [(add,sub) : ? : ? : ? : (add,sub)] :: [a=rd : ? : ? : ? : ?] :: [? : rs1==a or rs2==a : rs1==a or rs2==a : rs1==a or rs2==a : rd==a] + + 5. WAR for an add instruction followed immediately by a subtract instruction. + + .. code-block:: python + + [(add,sub) : (add,sub) ] :: [a=rs1; b=rs2 : ? ] :: [? : rd==a or rd==b ] + + + diff --git a/riscv-isac/docs/source/_static/custom.css b/riscv-isac/docs/source/_static/custom.css new file mode 100644 index 000000000..3f7e16db1 --- /dev/null +++ b/riscv-isac/docs/source/_static/custom.css @@ -0,0 +1,309 @@ +/* -- Extra CSS styles for Zephyr content (RTD theme) ----------------------- */ + +/* make the page width fill the window */ +.wy-nav-content { + max-width: none; +} + +/* pygments tweak for white-on-black console */ +/* hold off on this change for now + +.highlight-console .highlight { + background-color: black; +} +.highlight-console .highlight .go, .highlight-console .highlight .gp { + color: white; +} +.highlight-console .highlight .hll { + background-color: white; +} +.highlight-console .highlight .hll .go, .highlight-console .highlight .hll .gp { + color: black; + font-weight: bold; +} +*/ + +/* tweak doc version selection */ +.rst-versions { + position: static !important; +} + + +.rst-versions .rst-current-version { + padding: 5px; + background-color: #2980B9; + color: #80FF80; +} + +.rst-versions .rst-other-versions { + padding: 5px; +} + +div.rst-other-versions dl { + margin-bottom: 0; +} + +/* tweak spacing after a toctree, fixing issue from sphinx-tabs */ +.toctree-wrapper ul, ul.simple ol.simple { + margin-bottom: 24px !important; +} + +/* code block highlight color in rtd changed to lime green, no no no */ + +.rst-content tt.literal, .rst-content code.literal, .highlight { + background: #f0f0f0; +} +.rst-content tt.literal, .rst-content code.literal { + color: #000000; +} + +/* code literal links should be blue, and purple after visiting */ +a.internal code.literal { + color: #2980B9; +} +a.internal:visited code.literal { + color: #9B59B9; +} + +/* Make the version number more visible */ +.wy-side-nav-search>div.version { + color: rgba(255,255,255,1); +} + +/* squish the space between a paragraph before a list */ +div > p + ul, div > p + ol { + margin-top: -20px; +} + +/* squish space before an hlist in a list */ +li table.hlist { + margin-top: -10px; + margin-bottom: 5px; +} + +/* add some space before the figure caption */ +p.caption { +# border-top: 1px solid; + margin-top: 1em; +} + +/* decrease line leading a bit, 24px is too wide */ + +p { + line-height: 22px; +} + +/* add a colon after the figure/table number (before the caption) */ +span.caption-number::after { + content: ": "; +} + +p.extrafooter { + text-align: right; + margin-top: -36px; +} + +table.align-center { + display: table !important; +} + +/* put the table caption at the bottom, as done for figures */ +table { + caption-side: bottom; +} + +.code-block-caption { + color: #000; + font: italic 85%/1 arial,sans-serif; + padding: 1em 0; + text-align: center; +} + +/* make .. hlist:: tables fill the page */ +table.hlist { + width: 95% !important; + table-layout: fixed; +} + +/* override rtd theme white-space no-wrap in table heading and content */ +th,td { + white-space: normal !important; +} + +/* dbk tweak for doxygen-generated API headings (for RTD theme) */ +.rst-content dl.group>dt, .rst-content dl.group>dd>p { + display:none !important; +} +.rst-content dl.group { + margin: 0 0 12px 0px; +} +.rst-content dl.group>dd { + margin-left: 0 !important; +} +.rst-content p.breathe-sectiondef-title { + text-decoration: underline; /* dbk for API sub-headings */ + font-size: 1.25rem; + font-weight: bold; + margin-bottom: 12px; +} +.rst-content div.breathe-sectiondef { + padding-left: 0 !important; +} + +/* doxygenXX item color tweaks, light blue background with dark blue top border */ +.rst-content dl:not(.docutils) dl dt, dl:not(.docutils,.rst-other-versions) dt { + background: #e7f2fa !important; + border-top: none !important; + border-left: none !important; */ +} + + +/* tweak display of option tables to make first column wider */ +col.option { + width: 25%; +} + +/* tweak format for (:kbd:`F10`) */ +kbd +{ + -moz-border-radius:3px; + -moz-box-shadow:0 1px 0 rgba(0,0,0,0.2),0 0 0 2px #fff inset; + -webkit-border-radius:3px; + -webkit-box-shadow:0 1px 0 rgba(0,0,0,0.2),0 0 0 2px #fff inset; + background-color:#f7f7f7; + border:1px solid #ccc; + border-radius:3px; + box-shadow:0 1px 0 rgba(0,0,0,0.2),0 0 0 2px #fff inset; + color:#333; + display:inline-block; + font-family:Arial,Helvetica,sans-serif; + font-size:11px; + line-height:1.4; + margin:0 .1em; + padding:.1em .6em; + text-shadow:0 1px 0 #fff; +} + +/* home page grid display */ + +.grid { + list-style-type: none !important; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + margin: 1rem auto; + max-width: calc((250px + 2rem) * 4); +} + +.grid-item { + list-style-type: none !important; + -webkit-box-flex: 0; + -ms-flex: 0 0 auto; + flex: 0 0 auto; + width: 200px; + text-align: center; + margin: 1rem; +} + +.grid-item a { + display: block; + width: 200px; + height: 200px; + padding: 20px; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + border: 1px solid #c6cbce; + background-color: #1ab4e7; + color: white; +} + +.grid-item h2 { + font-size: 1.1rem; +} + +.grid-item img { + margin-bottom: 1.1rem; + max-width: 75%; +} + + +.grid-item a:hover { + background-color: #1892BA; + color: white; +} + + +.grid-item p { + margin-top: 0.5rem; + color: #333e48; +} + +.grid-icon { + line-height: 1.8; + font-size: 4rem; + color: white; +} + +/* add a class for multi-column support + * in docs to replace use of .hlist with + * a .. rst-class:: rst-columns + */ + +.rst-columns { + column-width: 18em; +} + +/* numbered "h2" steps */ + +body { + counter-reset: step-count; +} + +div.numbered-step h2::before { + counter-increment: step-count; + content: counter(step-count); + background: #cccccc; + border-radius: 0.8em; + -moz-border-radius: 0.8em; + -webkit-border-radius: 0.8em; + color: #ffffff; + display: inline-block; + font-weight: bold; + line-height: 1.6em; + margin-right: 5px; + text-align: center; + width: 1.6em; +} + +/* tweak bottom margin of a code block in a list */ + +.tab div[class^='highlight']:last-child { + margin-bottom: 1em; +} + +/* force table content font-size in responsive tables to be 100% + * fixing larger font size for paragraphs in the kconfig tables */ + +.wy-table-responsive td p { + font-size:100%; +} +.section #basic-2-flip-flop-synchronizer{ + text-align:justify; +} + diff --git a/riscv-isac/docs/source/_static/incore_logo.png b/riscv-isac/docs/source/_static/incore_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..dfbf6c43d3117faa316124c8766a941f30154bb9 GIT binary patch literal 113714 zcmXtf18`jL|8<-+ZroT68l%a^Zfx7OZEIuOw%yojY};m&cl-PP-<`X&vv=ms?tShD z=bX=Z!sTQ{k>GLR!N9%Q!;#R=bV5rzWmV zlFdd9=0j+3nl8yjMxt!~v4VnVlzO2Swe~5-56tPCwmnBr!*KDa5dO=ANq0N51qONU zSKKU5*>BlTouPjEI3fQX?!$t4s6;Y%KZA0^3sf+7#J)pUfsqKvX~^)8Q-7BM7RZQ8 ztH`5rl~lO&{(*x#XGF{{;N%CW1rP+u1uGbw=C48JMUVh)VXnmd{*c3s%0;l|iOCBN z!;Ju_qEW}9EoO%JJclRuihOwg`^i+r$V5)C|NC|Q)Y0-Py8U8gA6|bBl*9?xK`&I+ zwZwa^4%~|UM8uL&c;(7Mq2b@n?A;>rBB|h=NL+S zw`^EZFh4LTRA_Lv@K8;1J9sGM&7iE7Z7eA_5%`>FKWy^fhXM4^jR6In(`bc+@b~Ds zF>)Rl_`c-KZn-^8O$)D)u%nEK{h&kY%f6>3VKtijO-YbKFvRWJUla^6biqvzVljQW z*z+}BK#}{HfM>_n9xeISr7JB&5?SMQa*vSxc6Afoboa)VL26lU!<~Ih`5}}zTKLe- z$C6KVnuX4vld~(DA}uA}tv|QTSJok*n?KY<;of%0FbEbO{4rHO240BS z&Oe=TB51D`l6O8%2cKis!@;6z;;%CJvzd=xf+ca2?5rH*hr#EMYO~AYKZ1ZNOqfs3 zj{yY-fzmMvQ=%O(x8pZ%ER-h1-&UH}S4?I`8H+EI3Ur`5s^+!0Z4QKT;%ll+nQKg0 zs`*@A+cafD?C(V1^4JDXnL{0SyCxjp@4}Ko5e>^hJB8lq9LSG{-h~pi2IHp{OGL#6 zL-m7w=~n|nK+ENKZy2J<1;?|Gn#vmi;O}I8p%Uy^?@W7s?Cl`oX*gW%#(oRYm!bL7 z{nM$z(rj9Y@3f_tF-l?Bajca9S&J*wv-qIGRafg&4F`s5lW}pLw&D+z#&Cam6Wl4> zcV*%M6nG-NmoFqf5<8IFEmRK~At#Kq<1%yzA^IN&d@^AEN4<{tfNa=lbi1Gga3ipI zm`YYZRyc7q1akzV#J$R|k#_x^qeu?LOpP|$lCP{hn27xoas&h@DH)m8^aqt3V21$) z)%|01Xb3kZI+HJYxB=A_a!%;w0(of^QWAPJ-A+ zetU4_*|1=6_|URo;jjRRYka*uI4Iz6lH1yF?l59GR9@Sg=AiS6%SFHyxZuc_gxt`E zO7ws&hw5|P-{LCE(@)6hV-qqK+exO;qACo%&JnGl!vynri zeMe^a@`!-STsgVCGft`T0AmeCI)wRpJ@r8&o}v;{`dB+Ce3HQ%!eRft$Q*ZIV82b^ zoPMBD!nVWm&Ry&F6Q}%9ZmBC(sgncoC9%UtF?gV3C)_p%{Og+p%42h5W2bc;W{*dur@B(ZLTA}BlC*%%Z0F@F>=z=|*^ihS$yzkngWhJKOXiLqdWx@36IltYDp!zXqa zoJNCv7Ku2xvy8oGuXc&^hUTd*!p~<8X`$;dxfmWD{8T7{i6^hy)0Spl7 zMhB5ykXV54<$DWD#R?w}3npkD;gB07NRg`!k4Ba_L3%<>I;OP@HtgF84jPSRo4V;~r zjdO|^{Z!Zd0eQIUBiNi2G-eS&>{vG8eJR5FVj=p{*q;RL z#r=%ZIKOU$7FcoG!8aIl&xV9aCxb+8RKHIHfUv_~L3y9OM*@%UCg4W}A1iFX+W-bC zaT^qE7i^=}4VbtD+}<@Q?AzGRiEC0&S`gmPnx9zXP>1iE^E)JojK(r`=El&Kis8Gq>!P&*zLQ~-H;)sh3dnv+qLaDF0MU{6JJ=QkqH0HTdAt5 zdO(eI!&FtV+~b3sb`y3+`lmfC6B%QFSK_<6eB{woI8!Evd|2@r45H(%mxWp`n4Yv$*e=puEBk&? zrGZ?@z8V2CSNFy?%)9Mp$HaZ}i!ULPL;9?g`$T|9x&R}>Z(2WA$i_OoUT6d`QE)ji z4{&^^>vV{03*uxL1Kb&Dcscm|9wuvp0J(R0Ngl8Out;<;u*4L-FD}QO2ocf4hg0;? zU`(i-a1yWl;tbFpUr4+Y^IQH{BDa9DOC*VsMf*!ofs9lp;0_vkF#{2%gtJ2$!hLVh zUtgvk2$U-z+12vvgiXvon2N4Oebq&xs*n0A!Y}MdT!wDsz>FahTy8OQA5Ok7kULaQ zYu2t_DUtfTnctXN`y=`L`-*g-$mcZ=I5>%Iy-@}jHvlyo66_iuoZVh=7=b$|+@gA^ z{KYyRE|kpBkz@C+lYXrez9ZNoBj5*D@XoDzmi3b>&Es#D+-1wJ^(|wDU1MnPi2Y!` z*{v-!v&z8d%~v%E3ZaOgFdL!bT(XQ5`B-DBbYv0vIEE29BcxT~CYmOSDeoHJ%)T=K zH~w4Rc|AFHYhB+iy89wJU4(ID)8+g2 z(yNpsI$6x5fXbN9^>q?&WdC;L$QT3uhmnXsZAGjyX1h&aW5iP(R#C2Rqr!<(m5N7; zRXmjYD_fb~=0FRf+wX(Lb4l91ECGR(FUjqF>S5W`LAv&s_0WY%1ki!}vtMqpLOYT7 zStB}a1eT=DLcSy@{DyGqr>Z8d`(WI$o#m5i?0F>IZVlH$q&_t8GkEJm1YpvBg`NEfd`X_|esE8PkW-xB@%s8K-Ly^@YVGgPVf4Gnxnmj6jJacf#7 zRmvBFDzgYVK)*PBaZ!bSx%OTPdC^l~)IC0qYb$GAHEnvIi5LM#*$PK;RIH?7WFKA* zqe-nSw`}nHat+;RF&1sZJS2faCgvfWTc5O++=wt~BFgy_Bm`NAQrIzSf$%&un(8Csw!mHMFD+JlnQ|=~q-{M3%o!PTV`JPzQo?THwg4 zfCfmKs%ISb#Gj0X%S_oVu@a_nlbEp#BO^w4azDEOapvlb(FVcZ;z#S$dU?w&N76J} z;KUkQCrX)62gG*VR%~AgTOg4`36MjPd}_=q?kQClR_2u(covTc{NWpIUv`KAA5UN_ zNNPPAJmVYFagEXL?AErbL3aNHeF*#|;f zFJw|(lwb(vS0-gaji%TstXLWhiU@ins&Y`0=9&)?MMP3il ztrmZ`Kz{a4m%Es*ws5JaFmb1C^#VWJd?VsCv;UKTFY5c% z$&kHb-8A(iugN(DwNkb-^k{;H>U# z{YY@!Ex~wRG0a$fh87|9I5}q$8&$ISw2?l|)qxgd5RlwDzeie(Wz63YifX z!~x6!baNvIcOw>es&trsMhcZU*+b8j1fd4F0R`CJOpJ>Q6lmgbY&GHvax&L8cY{xL z@+{2PThbwnuXRd1Q#uNiK@m zE1lNELe(D|?7p6=IKyutCDs{Pn36|^{lQ7HThB?hS_-FbsbvM;keY4GwJVXKVWI^UE5s&!!&-mE z(T9z>hVnTE=Dv|D4!VHqxzv4A4#!a+A4}brHo$Dm)=6Xkl{4rlC|-|&=7n^8hca0Z zEMINMUmJ!I43yV1%@r1h;$VhKpOgqZ|6&R4i3j59is;eW1w<9LT$G>ix zY;Y;0G>)b!@AC$uoP|39X_Dl-(?Eq?mSMdW?1J-Vj+4Fhf6;ujQl{wyV?R6SZj3xqE#(wCRRqtv4#n zkO^|u4fjL}CR_?RyGHNJ6u$yWy+`qpTR} z!R2R+NX%?hK1D>b)@R~7fqAgQr5JsSuzZubwN(1p16 zLer-4iD0ld4#T?j`Tj=ddXAGKJp`mX=kgiqair7&e6_aC>TV`fWdqDP>3t&RmJ8|Bieu2TOiqWliyntx|JZ-!BT~KM}&Su|1)79zkSDXle>x zuT8KNIJU5@e}YUKDQ)Gm?hh9Ok5hxF6NafL69b27~<+xJx3pN5Xb8I^pzWwb2$q<`gaYt%r%lZT&$)qK}_E(u_OW zj1;^rS3tgLi9Op;hCzVp@yfa5q7)8BPF35#p&Sk?F>)j^XV&_57c1-Zb9^;|X`*ay z^P2|0fQ>`xsH|8VnKY02ww^?v86ZTBInd|_lJWxOrRj>%5fK86m)d9VcPh<+A9s`u zo}ZLTrYCB2>cKG`hN4sFk<|NQLm@kAF8RmIfm#A42}-u17zm8t1^hPjMMctxdi_uq zl8jRi6zWDy{Stp-)n^Y8_4XA682dVGv{xV$A!ocO7J{e|+3@e|p0}xL`{W5zlf)`b zA>$t-(Jnk~Kq9W@ce#LkE@@OCIchjX+=Nk{Ij2*9Y8*>z3B<5HI$kr}^;;(u%ImC} zatNjX!DJGz(T@~vQ}un4g#J(K&Z_Skr*7X&ic?Fs+cz@sp4~{e^|n%D|e-MGWm zXpz+Ab++!KI9>qRfzlWxE5cBngi6ZE`Z7%@G~=vLXX$bFOFf8vJa7g)_4?A1t@Ag` z6DQYIu!MGPh;PFH?YBl22fLGsJzO9K)vw__oS31waT+=0BusUwAA=Fz8PWku7lP8t zsE()Oc0O$|y3T=VH*9bm%UV_cnvgV<0KF$Yv3WGG%Tp_>6 z!iMI=ikW9vyITE^5G}LrWS}5<*Ka<)mumFIza&g{p>S)Mn;%+q;A&dNxYTgRlkeNb z>$!3JEB%NR=7f}H$u-BtL+O+ZLJbQ5%a9J*x)Kse13eD#iJKcWTseUsN9E9_56FV8 zM8YsA@5La^j%PLj%zO>&wXVQ-dVz%`t!F2Gti<-6^el}pAy|-vH=c|LgVwRi)N5-& zlnmaNc+ikFlb<}DpE)bA*qm|s&$%KH4E6h0my96h9_*w8@QG?9J!5_$5$mqBo1c6( z{_8|U+|L*tdW;jJEzXvuQai1h=NcYe7`%;owom{Z6(&M);$$g-WM!&!Ho9Txgm0p7 zlfE^+<3>8(HmIdefBl z(VvZt?t&Pk2q&5lMyV*5v@0R5V$Rg|RghSm^qdXv$C!6%MfpJ516!tiFPWzE5O`pN zx9pupj8}J&2)%P9BFjRf?NvJ*R$G4tw};^mPWtZ5n_O2~|5-ak5TuJJ7npNu4!Ets zKzyz}92+dv99lh>g4y~KjIRJwVIAbthq>vwQdjy5nOr0)XfJFaQrrvlFz`5+CExea zgADL^a)zVJ$C&4pQw+ON)D%qmsB~GY+aWXof`rfW=?lY>1ZPseR+~e7PI1;97o@}v zYkEo_UD>_c9{wl{_hm!c&z4~N7OJ)lBEEHI9GPo| zU(ol_QHI>{!rjC|3r@}N9`W05$SxUBDgD5)Td>peaeI}Yp(2=Q3JazLpzCxQABZY7 zT^%du>zF6D%B|m~97~OTRuWD>kHdTAFBfn^d+iVn_n7wYn3a?bB@auevXAsyR<>QZ z1MkU_wLx?;}9Z| z;fIsusODO5TCzXV|4W3|%|SD*srZ*7r|HKTW`j5`h?{=bD3QI#E+($metY3PadL%k zr4caN>;fxBALeA&+~gTy^?umOm;$VeN_u6ogPqL&#Wbqirtk(O=5y_An+}r2^L10K zge`xgHVAIFUfHNQZbTLV6ZDJYfk5P0 zj6nA5;&85+r)m}>xQI<<@$MFe_!x=lb9DkX!!zJ7w$wYzp{HKKvM;kT&@Mq*Z4 zMdjHiV%oj6$`)Q0%qH8l7aibC4M6l!`(`XPDo`J@U{5|uG$Gd5I3GSI4H*t>l%n^f zv7nqZi~}jDwQyCiwoYKOJ)^}=`13K#(&m)GITMj3t&Co^SEUjrvSP z7ZBbX2bX_Ct|Ve;jr#cuRL6;W44BfV^hV$3F8((%Fq^{Da(KQ|d47(^MrXsv8#l1x z4pAe87Fk&NksvOJ0kwRA_75bK(++2zf=yA6_p0-#PP$w8ioyNe4Eag-CP8o{C9ulb z;d5}jZdMvcAxn_fBJsaAl_j+x$s`f=WXtcMSK0^ z`J?%9-x{{LL)8}taNtlm;l%t3v24ZGitnPN48v4WjdrA*QEF+G`^|N3nik>n?+I7+ zr*+w$QEJPd)zvX*yksAxpa;yg8A($0C$o455)4t!0Qpsjw|dzV1B_?rfaW&4KGu>IOQ6s=nJFQ_RZJvoWW4oa`T>9%_sUfB(N zyy+u&3+)&LN9NZ{ESU>pKm!Os5iusGtLooiX|1MWEn4jHBFTyQaaX-o?U{&Fm^K=u zAhFuwsy(c@ZcXH2zjMj7Jz@vnzXPXGMvI|tj2^{;IBjnSxS+c8oLQF(jKsB0U6V5| z`s+x@>VBuo?z20D{%@ION+vZ0RpA33oUfKYB2l6&0r9(xtlYr7IQ#uuW~adD9hqhj zfyiLcj9Q^lXZ}>`a6JPiK@FvB7tMV&aCi^CH6UT<0F4j#xyRi zsTg?wfigv{sJBSZk+=N*X?~#fIeyDp0%N|m`p{@-_as7_HZ7(6PgkBN#~c4M%;)LE zxVy|HGs}n8s|E-OsI1+bo`VDTH$vZe0LbeqhPxwSw&rRDSDBkD)j@w~vz|ZIXu3M* z&D%3emHkW1wfw~;$U31GLfonAX{2!+96}-PwBX9pxm(<6DJeHjt832Rd_ZXA56*frVP0^&W;_deJ$hv3MbyI9Z8 z4WDd>%1GT4jw(tIW4Bt{P}xVDZIc0Ub(_&(E)@_5K7LrnNU;)F>d zdDh3*>|GsAj`OE>IbF?gj)x>Q$N!;-dqX;eGgM(Ti32 z6zAKak;T>dD{7a#9q1Qn@OSRoU#X+3BPzfVaN;(F5LAUc*w(AgvogV6^9L=t=kfPih3&SLiNCL!6j_ zyjsuIxgR*!J0X%OdYfrS4Mrd0e>PVh1jMJ`Q`l;KPijQJXX4=ZgV>Lkj>!eDDVzZ6 zw#(|QoM!lnv@?LcG`BrZW~$ZnFPHqu6PuOUXcFg8nG_hm1i`=wzv+;^jOG6zSuBIQ zVi#V_eMpgLsPa8BkTgz8$V9y2n@k+ zrsH%vj$2$@JYiQHolyH3CD~a*`5c8FK)z>BT4m2Dwxr@aN&O$K-NKhN82j`oC zL=7Cm=xu&$Och{{-6C|;y6xp!^B!ffxtDoA0XreJbLGT+gZbRFRRGtMv8K&CQJ*MK zl8-R&_=HG+J1&5>f>vPgU72=Vke)#(Ss8?t?vbEt&7z*P7o3dHt$E*AE;NO5)O|h2 zWhDtH`#TkDs#M?yP;{GI0WpDl@UJj^a52LX!8k?8b|LxaX?)a|D}S8JB*VRHX8ulm z<3ou&zKkTr7tfW`6Ms(|Vni%t<}kWrhWRyQ-`Nb`uou4Pmq4qIIm@tPM!`2QSNePv8;_~6P+8y{!m2dB&IP&hF zmmzk>fdLQyYq$U)uNe(pmpwFIo(OxEKK&x7X==6?(nQzs@87@EX=rM;MT88tINZ*( zG;|G*6B5p~FFo$EiO%cFrFxMTr#vA)%P1s{eT0wI%vSXDiFwvwq%$6{lW3>tnFCGvRl zdlXfJ!DoLC)u~+mrK$p$=j0__fenrFiA}X(!^vsfNo(_ruz#@y^PM!Vz zqLP8m#9>ck`PEz6kg=}KR{NgifzDZPaxzx)$^jR#oP>!~$Qs0Ob*!S8r6rB3PS3Mp z=eL*Q)vg|sBjVnh5BZ>iFC);w4=6^Pi8eT5J<-$7MA`x5pnz*zEAKEzT~^ z@?+lNbU8-F`Twvmy4j)5YJ=xs3@kMM36dc<@r^QZyjp}n@RschG&B5=WaX~q*AvBVfa8Y{ry{bM8m_* zN;r~j00eL^f~fHM=MEeIEQoTOgOGdJ-;P^28;qD3Y7kR7sE-*uL8F!yq1e1HA7j2z zPhR7_mR1c5x{0E@cri*X+8BpI;RN4EU4%SY_{j{3KI7^9=bh<-uif2Zbw^denI;~) zPEj(aOo)5IKTy66c?M1QP~$KyaP=8&2iRl>p)GKAlc&Z6=nN@$*VX3G@^G7vln&b` zx*q(5k+=`m5K$mmNL zHs$qRJJn6(oGKF}PW_hj!m>+T68Ctajcq^w4xIn&Tj{}Xw7V9@*bzf)%Y>LSKzEr~ zn{y(l6NYco0w>#n14b>zN1E`h)t8pNUV*T4cbUhr?|-y46Yj^u8sATeJqHm~#ta~gNZ@Vgo+$y7zUN4NHd*X3&S)C^~H zK)5^QKQq?kHodI=`&PTBhc?%%aV8E92|Nicg!o zm-U|+Etgu3OBYK#+W$JvPwOl$1{SHV4W9e+KFUxi{PS>qEA9v@o$O>!Oc~?3b0zmN zka9sCKWOT;1G)A5*N^n#LQ>z1HNc4iMLHvU$@g%dQ3}1x3F{>w3iQmnqMOvx0kzxl zxOby(%@^x=Y0v9JT-A8=&Y1~WV5rGQCKS=(g$qxe;g`uro@j16!VsViWz@iN3?r$* zbcG6yq1^9A9xlZh6L$lKB_eg=jnw~nY^!q{-dvR@Yt!0wFscwb%4i#+AaS{|=^V;3 z_te$z-4FcaN$&k^hXb-4q!0bjPIaATrZaLF{EHc1h6wX(+}`CqX)uNT3n&9GpNSIG zbXVOpB^yByF=6fS&6QT%Xdbqx8(Wo|ZDh}G8pLjJ;Om*K(MGscr4|vmQRFeU9aeW- zIJWJUcU(BPUAg2=4tKDTo`n&3@wQ!-Nmi|L^9kCw{cT(Y_INO$sKLO3q4^>G|31Lx z*Mi%1t0M-e`xTCFN8`Im!fc zYl4{E-#;&;oqgYnvT;`C5`JHsL9JM2H{quhF3*qY)_7YU3!NTcC%b*hO%??H@OTxC zm62|Ir**cQNX$Ef$-lv1ZsYznM0#vqJ**yQs+u#4@hqlky0ipERu^vV@|h9`f>I1C zZ!S3x8(Y9Vx2@~OOp@j`@=C2{urr3LHRnC-kCR&v9eU@GpfbCbG&ETj-%Q>U~}>S=waPIDN)B{P|?P z#S~Ni@<|fNko7s|10LG`_Eol+1RKMJ%}9nB;-3_E)^~pBp~X2I-X{I<64hZ2>QqbC zltHyA_;-{Mp02bnnOqxBM4qz31K2VHvmktEMS)`YqXvuAkN6s7FpU4*f8f%8WZ!${ zLcINyyGob$r#OFAKW}2s@1&~OT=W8UIL^k;34I2gSSv^Yw+_HL1U?IooqtsfYb832 zE;Bc=?51;{O3Hv5`HBdUO*vpIuQ3E}oXg73ktiQQ3|ur;OY}?^H-KQTCA~&~@lod1 z#A@A#F(}Ec;wSc93Z53mv*9BFt1MABV)!oseHuQ@zUYE*_%3)qXady$C4^U1EIVer z1#5P0wz~f*s#`|Fpu(ur{B)%=8vglB@E+=dWwkYh!4tQq)b&muNrE40W%EQM?VO`E}f? zxdQz280%l&8#{Sf5@2`Ww2--e(2Ug@*^u$B8wqAO&L&VS@V4zVXM{))5V3Hqcl?br zQF})bySid{QRnN;+xr{#OEI>@Y$urbx~66D#&hHPWgYIByA-)~=6HVQxY!PQEbfW5 z5V7|L4g3lIyIXLBT_TJ1@M2X*yWFXv8>mfDW~LXi-4_204WK3c4IxoG6Gz0;A4l*| z=*awfM+#%~W$%U+R5=vVxa(JFl@>r|RYhiMA&_Nj&VRL>ScSfH`0a=zt_)Cs9`Ug9 z&%0Ozj7j^rTtQ18v_HNN)$Kl~N1wkv+QK^7Z-v_JhVAjW2`SU@ENZ<}epZ{2vZ^~SLU#W4 zJ(<$1iB9C~9t~==zVI02t@ZpT`)s+ZZ`j(tzVm6TfTpAQi;LQV#)kKn$Q&OJ=o_Mg zCBToo;Gn5wBIXht@NK(Qd7Z=IKkm}49?8&#kI+3#rFM9D158DB|5QM6I_}EH?#_GD zzrW-5Aj2r<83v_g#0#%IB6##_B$`b7=+GzN(bXwkzsO*A58^I!{!k7 zmxJs&xDB$?`=tM-uWzHZ|1=wk%>U9TN1G2NU=ELy@TA`mhq_uN&HhhP|qQz5!zKZ^DhE~TkH)lyR0df^^?d*kS@?A|8 zwD=;X;hz!kDuV=2ul>G3H6MD(!yfsyWFmS8vlUpwF4*aJksM%lclhO(av-&{y9Sc1vN^tPs^8yJZVWB+)bn|?d> zIq}+5ab+4#bLf-{;;t85eA-w%*B4ul)O~lNqKw>}Q$N~L<4J;kpVStR9uNP4mTqlN z6U^v3O%ZOmOr;l>KCEdm*DMu;>QO%RJS3C7zjJ#~W5}Pyz!0HxHuJ>-jVEyvMLRm}eY2=}R|I@>f(sV(Vx7+UGTtf3 z`he297phvMpuS_a3ET|ww`28pBMp|KfE8iMwOmcaDd|xu(gn#9j#%?Mx9)^Am}>9Q z%XZh7i;LrGgQ$*w8m&DG!IhRzzj>Z`^PMqWkJSkX8;E1v-X?Bk7*KqH@p`^4|E_jJ zxM*_plYoFAp9H3RpJ45cq368i*?agG6DOen{qUu1>RccyMCcqaB;A5GOE>aq;dI7C z8wZW{Y--KcRveTY3jaowHLI^rw1%Tzhfd}oAb(}8QQ7r$%yd)(ESg~lp_^YJy~$=w z-;El=;gVnKj09M!GlcS3vpzAPJ{FNIHTsHx(P`b?EeAV4D0c`MW#2!%W$zsT%Nvox z{{{q}e;JD?;UGXkeK=L#Z|vBW%5JJce^uFS{r6(YHHnk$@V?dbY)Vf!g|MyXErn+;hT{9lS(L{vl z`cI;_d+Q2c`O{?yaWE=sXVem;Y3a+aN32g97ksyp#qK#=olhadz)`n{WnvJ#03oWC zE9lg3{L0Qj!-gPhT$E_VP47gc>Qu&>Qy~bRBtNvYyn|E~rnza523CDr^hW63#D41C z&K0@&@zto_y;&8G#T+NZ--tOdFd{;@9)hMm;H`Y9TTb%`I2EAwJRw!4lO0Y~ROtOS zHSLif`teq_r*3l<$M~yH9>d68A!bEbz;BYG_v$IPoz!pWlsNg#d7`?Oj6jRi?6#SR z0`8>!toiJ*e!UZr*vi27A24Oqa7D3JhfAQ9lXP$OKb7HYp&M3Y`=KTN#x`;v3OmCL}|ru-y_t$ z-%i)XA2+MvJcNph1V~wZbc$;v+8@*oORY^IPLv8>eF|{Mc8Wwh|sG34T|}A zCPc_OH#B$kU$pYT19Ot+JdQxVt@V`!dfZ0_>7l=oGO&M|tIl$}T%Y2vK5RUmCiom* z1S>lVU6v-TAlKu~wy@fRj#q_NF0oGuc`}7Qe^dQg;YRGIbv8r1g8?a+LASX?rgYiC zJsJITMjLGx>7hP1cXV_PWd(-C-EvgqA`SbRA9*}EJ_aK)j|3-!W&n8gY+O2;)HHDn z=)@NuH9*a`D@&~H9AA|figue;&_e3agOJN;(?8cmyv^3s!+H1P>>d^};e`-sQg-7) zG5&C`O~SSlr<^(=zqd3;a*Csx!gmtIru-PR?s3w>vpGxE9;H*Ytz)@T<%noJ=lrE= z?dvC9B5G%D+oFF4pv0M&HphO;Ni$zN-BtffG4O&o0BIcgZ7_tAbA9s;HSofsJW#Ez z_8U>QX+c>z<|if|?I)*Y2Wa=glg&mQni5hP&-AqSdr&ah@LQaO=}N>HH9bh<3dE)z zQa_qpAAA3wzA*Q!+w@d~^4>T-P=_8^iJOz=^e-K*dh^?)TRYVS7XpmE%O`#NLw+uG zshuv%u-CUWoW&N{J{f>U@iM_6^JI0tzIX-Y+Gmq?4e-_z8Hpraj3kGlcE#32VGo*+ zHwMAc^yhZE2r|@RC7}Fv%JTAcKYHU|32MJQ@hVjLvoP$)Q=u2`2~Jh#La zZpF$+;n4@njS#s5=|F(5oF*_;_o%-O9Mj;!>-$ytJD=KmGm>SE_o0*0cF+9H2JV8C zZm;8_0pTwK+w`9hrqCke_l}I*Xih0&(&3@K=yGB6ZV5@VP`JW0(;W5CQ}(1NPu@pc zFVmVb&gWN3|EVPBf~aTc#^GcwQKGxMlIGa2A!Hx{2DIFHBe=AjFPGHNaiTL2QfnF4? zS}4;Tb{5Y=+s#$yU_SQRy_d^c-|0GgM8r__pS&#QUlrD|OUm+aX^s}QyBxJt>b*w! zY+9`!d?yN(QwpmZ&ceEEpZd~bLDFvgt2VpO&KYf*Z#u@>=`jiiOis^foDe+n6C!ca znBbh+0R+oWR50WeNM~gMt=7sfDHC@zWxqRPY+I|0MM3|zIQ!8$Pm;UrgQ$lY_34rq zSHO0QvA(UZP%55jLem~#Ra#a3J3?ggS&k*Pio?{hEyc#n++6=aQ&9~>wW>azGx(HlcKlE*C#n68^S! zXlO!rr)wFIy$0tSXHyGgSe95s&na}Vm0$bbjweDCBU_vfPKO}NH7o}NrvJu6ClB(2 zBmIp)8~|nD2pL2?`l7h!^+KuQeVRkWw=(R=?Bo>W)gG2X;Bd?G{u~F*FlY_HnldEE z7Xf({bW|uderN$v-MDQgY^n#75Z+Up++I?LI;wSiMaMT4hKHnN2nb{WNIECi!B3mF zd+0EriZSfQ+N&`rL&nm?+ynAn%5CDjh1fp7F#IhIjaQ9%B*T@=CAQRKuraAm5dMmJ z;6t0O+ey@We&_Q;?!)kGv8hm!VC{q-#7ltxI(zCR-gb7I7x-moq5tYKJ zv6zGnhN(?=;$Z(gCZl@j<~t6S@8bD>^~`)z8l138(?@3Qmz`I4zjh_h7OMppz*c1T?c+?75#AMkVIwq%(jJE<>=IQAjJW@ zwU+0_N5V_0C));(Xl+@`veX4Ur83r=S+i6wOkOg$8FOi|-zj`9b*&WA03*M&HEH-K zJFhD~?36N0cm22INlDL_SKDmYqYYgi4pA42M(ZtiWZE+z|Nen2K0M8C9#l+T9TkYg zj~pV*C_yGra0r8yYyd;rB{Ew|2~%h*|1f{3=PcW;or+2j;Igz?z4oFUiIv}^&c5~i zAtGS6zlWlc$pC^TsMQ)xIHps%NOtVj2+9D&7twG-hMHHAnuvno(AcqBq|CIk;5|5Q zLX<HOuG5>zLBeO zT=I`wV#mxP?{^JxR|NnAr_YA+U!>K#3L3Mf?3_FtoCXLh5c}uyYr@PF{9giyyVQb@niMs&gLl_>Z6V-ufU8kG+Ia%66haCdSx8^qyDEQj-<(cHR;d_i(%k(J8!1Gr+7I$ z(I_9)Rvy;^3^l8l*A%kv{maX0+k=IWASo6x`d92IR<6Zr;pmBEepvY!u?nrtkm!*l ztG4H&?;s3{H)yk;vqL9%YW!-a_ptJm;CWp3rOlOMXaWun{pAZA!QFQj?SDXxK`RRL zXe!Fc=Ph|gJ=^P(A)AX3f!EUr5t3{V-P(ECG9xVjZrcd}nhp9pV*T8{b@!oDY~J2; ztsIxYDD z1BYdZ)5c`R&uCd1II>(OayG&ou@?1}6ST#lv2>gCFPu9h2(a%KFTJ;CC1hkiz0Qw6 zSbSXof#}{sBZu(03HcA$pvmsn>(<$2x!|H`0WCRW{xY79HH-mY^r!(c-?P(Jp*$7p z1md$yl^sJ~nyx;fJ2o|}(oBD4vEDICfdhOBp~Ex=Td=a!KtlaTN=iebzwC3fvn1&T z*D$I!tv@;ExsC>dAOj1SqN0BNGsBgh8o62YB5;pE^3v+eL|GoeGagmH#+~L7y?IGS zYMm~p{xJuQg&ez|<32y6Wr3a_GhjnQh9d_D;toDW{~Lo>FlYs^Ol5uW+^unT*gV8s zoxR()P;`2=V#m3~H$@o~LyM!y%M<>t4{or(;GPlef7uF0PVzNww{enPZMi)D`j(S+ z_xEIz83G1cwft~wxP{A7(l*L>91Q)Nx`JvO; zLosDR%eZYP012m79Px{|SUta0BnE^%c%Zf3Tmy+QTgLa5S`u~5c=_1KC0u1B?B` zgi+-bDV#}7c^n*J!xJlEYkc)dLC1$7{d90oh0uO8`Dj*2EHtTTKx`m=m;n2JEJ~^$ zUJC?RN*A2Ip-$%pQ-AH0RW{tGT8`SRV)8UDnNSRpv!-g6i{%X8KELZ0>N>iS)|Y-% z97ImqOm=kL?3xgtou-m7v2K7y1#jtSL1SZLj3c#3$cN(7=irYWEyFi4M_htvKv5C- zw;KjaEd3LV%L(=j6bJJ*;8uA%kXLJgV$VyFi`$0J;AVg*klLb=5iyWFfe_)=bVu^e z4F`MOPE3x9O=gfOH&e3k@S$JniU!rA-yl@r2PL-gO{<4d9w zx4cqnTHNTof(oKIGmJbpa8J$s>+W6V@hAdKgip%Zl~P|7B^CF`&6W4Dj4JSjn>%eB zoO%*YaQJd~Xp}&m$TW^LwZxPNSyM^4!)nemvh!&dFU!A{DV{#oRBUJOQO~8~w;Ktx znhk350T^HSAGuJUR!D{^L?N3Qt%85$Oq{U<>q4ep@44`r9eD@ag1cF|u6*G2;GEJB zvWBE&O{zs@f9N|sAoX4$kkFG?+sniox$%I{v%3I9F*;2i^l5p5PS7~^Wtwq1E#_pr{x_E^gQ6U254#iaOC(l5c9OQEz8+k${=3Nw}=FoOO5ehUTSiP#p-2lICa6AL~9hri&|L+C(x?}vZ ze|J;R!%(%Hq}_Abz<&DOmb)woa$EPe}^I*mL) zu>kEh>AtQ%Iy8zkUfcJ3AI( z#0X&#WL~1X&!S(^e0jOZU?Y@q>YnWbPsPH#r1r3qDcy}2!<+y3SgO!`y{FXBGPAxC zNTnAjEdDAUzjOO6r@a+n=Y(|`M)aDTw;i&6dy9RwUVq@?n|~+2SJB#ed(>WCa0uB2 zuaslk_y1_Rrs&GHW*ytMZQEwYwr$&X(y=AXu5!*==aFfOtkrv2-F>4l&lr{X}=QZk2Q;igO-3l4>K)G5(y&Tit#`|iT% zFN3vR%S{)VgyyM5GS`>2IYCQNE)@Ay+j~W-*!XLKArq%iu#xswqDOrt@gqH6P6uCR z;-GS7jmL<};ha<7mG#ZEZ}lQfJ$}&J4^h|DH#S!E7-Mn;HToqm-f#EvwM^IQUP918 z1Tf13a(4Mp5#-0mHKeFvq*&Rk4b0G;Ej|6GrHEGB)%;W2qM#(`G1oUHRJm++D3jXq z!h83SvWMM<5#lc&w=YZUtKu+UYwct+Y<&ZuC;6-T9K=6mdyn*yaJk!h-@fXFO-cu% zX=cjWN>5-G{H6kP<9kyb=5XtH&4~)~I>}^%XZQP;Zy4Q+6#W~{pV(_oC`0C{*cy_AoGm6-P;Pd*Vzt(Lq7#mgHH29woRSg<|7SW zLH``4ZE*N_cID>Hez059MkR0V2VCA!i29jRv_3DCYm=EA<_(A_!gtp!hzWaNEo#QO z1d8}xREOj82C8mayZt`vrjBtpEH%d5_)YC0DJcsqELc{vRf;V9`kNT9x^=%sBI4g+ z0|6CvRVSwrpyW+mwm)%MW4lo#FX(X&4xSNm}M8dYFf(rZ;FL3aS-8SDwpL?N>D*yBC``k ze~P=$fm539{^H6r3@1IPH+wu2OT?%zx>A4!8DdS_>Al+2;KSG8gLfu=UDgU-XJ?;U zF0M9e(p}~?p1eq8?|eMVZqdywasX8K!t4N*g*>{1sXw(94*do?h4n3YT_Kp`xIQn} zYUDf{t}41pZ=fYlmUjzo%*rY|5a}D~^&;qlEKE4AR2k_Jv$|bC*&3xp7HjYU&{)ox zwmaQ-WjlQ*dAlXPeFr|@UmNtp32^kk*9|6P5$H&+35IxQgidS2PMd`DjKR6J(16Bv zwcN!En_@AVymISJF7$rr&36)CDymL;ABQ_+s_{{E$4!y=Q0*G>EeTkdE*zG z_m?0LO&-}ae*f0sPfTQ5%%G|)|4bfV`MypH*WcP$+B!YM4c{RQm#fNM_@{dANMBLj z$vf`<9hZLoHDPk1&CGQv7RjNnyzrYSvYvN~OJ^tC;vzWIPO!78z52e-)XVvXa1uD> z1M<&^hP2jEAGYmMLeDDApU&;*Z(-hCaw#Ru&;jIT_eUY5gUD#PW4DLl1@VA#?XHJ! zc=)Ipi8z6n;X+3*_4pqMZmkgC~f4z9zW)19Y2oS}W7p zDKFax3W9zQB^Y)UlPbFEPqNK;-jA8bSU6d{dk-H;iK1x0Y%=8kl;!_d^y7)S86DH7 zhIM@2R$Jc(<=!RXCan_r1pXujpX()9^*Fo)5$7jiS47}@)jo<;U@ZtStBD%twN|?? zqQH%q$(OpWg{{X=r4+r$=p4B=N8exSpc>;X*D6z33L2o)E;)rjP>Nt#e* zWo7j@htB?m1boZ*JyUtscL-a+Kv4RTWWxz*X(GJIu^TNY-6J!p{~Ef!uLPV^@wi$_ zI*gW4)PU&?@8_8nUU1cwwgG9_H?${WQ?Otowr1D;xOXEqw@1C~y(he#rzzHOG0N<7 znTaZY(iVWk-#fyDleMw;Kwg?S%L11i>rIy-h})*0olvKjOL7lx^Rs37kFNK(NH1M> zCac2t;fsq3WRJ`6Hl&+Umjs?|$ece;VO0PQ+CA{VJ&+O6Le203BWZw*@Cek+`h==*l|s zjY?VrYq)w!z(0I8$fDU6&c19jDBLG8)VO1P zy(!%(YX(R5z(117BO02z&xYQUp@8c)87`F#n65$jE(Pjy5`gOKu!Hn#QR~jTO2Mj; zvqw+YUMuBPcQLg=lMW_s~p zjY7lX=_cQsffP{JEI?gvSnMLE(?+OpbUJq*z(>DWGK{dW9(mBFvZENQvqIpj%*BpA z*>^Z_UY8KLMiED&;Qd0J$#EF`PNR~0 zUMEcdt@iEctD>k;SYB=2H11woSjj9gv)D3l{YZk-Rov5BK^-f%kFm1fSZUCB74h?x z`A&77#k1@BK_v5E0~5+Xe10?WbV1&x^H4%uC~Ozrjp*muet63l84HwdV;mj)X&<;R z@BJ7GAh1k#Ds9E)=!(I(r#?qT5kv0z;>ant8?0K695}S~FKaKn4+pd@L&BPGqKlUa zhR?$|WA_q)u$~H}Z!gf*SXsF&Qq<7g5^HGNtn0331S#Y2j*tC{%7+U|u1zHsb)9!$ z8-ds7TX>R4uOKk~8%&<4gg1*ieRe`udUn0*+r4!@g~!bwz6L)DMo>eW`u zOeHp_#vyF*OqfoB_r3x#qqw9H0DVW%b0rDBT#6z`mVdSL3rOv=X*WnHrHe}tA&E$? z0O?n@6!m>i(eE)moSV{|8f0V&awF=d%aBd6^}P4-4Wp+?KJl0Nd;J0B^0O}{&Bv&r zI{ya+ASB;LIn{Q<7k0$r$z4xdh0c>tfN`sb6Ei$8GluOyv*LaH+{SBM?qDCWgPBoF zP9EJ!GH(f|=NIDH)`>4!y*-7d;9@5|{LLLT!@h=|s?}R@$)$Sls}c*C$pa^_A_TKV zfR%=WZazIV5J!u-n?32)XuOwYFrn=DH1pB7{x01+9HrL<$4)Nj*+#VeWnOtWg{Jp~ zv_323`lRq-qbQLNLA40wxULs9lMJ=NiP?KHK9<$Be}2U1S0NN<7IQ*O$`3A+YOL!5 zRS4BJ7@~5raci8CpRrj}(luGNoB$|p^6%ejTS;uL$7_|xSQP?0FcFh6Sb$FXMl?s! zU&2gR6DT<6dhQYA9G;*12c0mgAW5vUNDdV~aC(XTcd`Wmu6eOGX7p8BWiDSL_if>D z6pvgST@CT#WA@WIpeuBtW!kY_*EJSQT#rH+ZGJ^C7WJgYvuC)B?TvSb+H0bbWxk_a zK_bn}_=VMMFUnYYe`Lpc{q~n6(b}nX`G4F~xX?vj z{l6!;@QMGiGKdj7*WuYkjCCN+H-eIrz{fzJ>bIM8x$P+77QK$OS+@TVkO79~hnQLu zs*nHk7F}t79wkC;$WFNDD0bxFRie1IE9hXbd^S8}%B5z{73OeMdsJ7YWWE(6%vcnF-omRb&`%?VR3Tdp@$j5@sVNEP$v{v(ap zxh-mt+TzN3I}l~r7=UKwTnpzyOV{{TUGdo8_|V=jx48}+y(kLvjqZf&R|M1R3Gpmh z4!Ay4%h*u4x48>E=5qvI`r(ILYC28ZT{9rSwwJx19)nh9B^hRgxW_)WBayl;MvVbe^15 zGdp$*YAzD|lUE2UJ#Cdl@7j3p!)kw)C32%ZU%a6F;)Lk`Q>aSZ)~im+;2(Gde1=+20Zu@VCa435NMh^57^1{lbhT;0m$LuH)j_ZUd$V)29XivYN;f1ab)*mo1{7 z*9x038{(T1Mf2_=1-O~u+N8UJ8eev3EKI7b9q>+t4z6a~*ouE>C6` zb&NbZkz@X0zb#6dP)J*Rk9{LrMCUog7SuN2GbH3M+fZ4ffrS`7K5pD9*PsR+ALN^{ z7YJrfAKz`|oS?|98W!0*<7J~(de)hB%xvAQq-%>@X0EHR<`TSzrWZE(^Mz_NcdAoBHwEB5;xb7Q7x9C-l33>;!FJqA9>9o|Sh} z-dIH_8ETlFK(10MefSvFyrkoLYW|-1h2P ztKiYH37bAEq=bmZA#KPAjL-AWvBDQKksXx_M>Yr;Fjk`E!F)m#H~VmqX=E1&_>)4+ z{-n;O=lVt?9!Cz)a+pj<$ImIc7m2Cm2bV@Ig@1~!wz@P*U{`nejopg#t8GFSj)KVI zXWej#!6bSx0EF`ZR+iOqEBTWr!1;O~UuT){ldMiq>pdlZ7S?UC1nSv!emTrjgZ(fv zpxQ(ME0l?-8%3-FSm{EzS=tcJ%1|!TP}!y5j1erq4~NX7VzX*SaB*s8Oz$D^O{maC zLG?crd$Zbo7xa3$wDWO3;cB&%3_!5*;S#L=2lk?SP@Ny)w=2s`u6mLl*R|#Eo9#W^ zPYM&028&IFAGznxL64*-yv(K^#CY)(JQ(cIx2WB$0sjf8Zrjg&pC#NAIX3kJSI@$D zWe)=4@`NlP-%Qn8U*)!ufi{BATL77tH0sxr5f@Nm**KM#h?sWN8&XNhY{`A$&DO%S z-?-$g$AG!ZKU7fhxCTqI@YWdtM?OeU4|lWof9$gv)5me$6j(1KQ~;t>E*brt1GDRiqz~-~gY;a~HBux--4W$JHfy~@ zL3Sls)#~Tth_|3%4Is>)c6TbNxd!@nJ`B>sR0)e7gU63VNN{nJVrxP~a5j>R`oFXz z8O_(D=`m!5jg0nQeVM3%0*8%_^aujf0&E5c`j*z1Ol2JjYbCfmINsGC9^U~F>2n{;$?&hJ8NeGN zUMSYfok9Lk#E22!yC2cFuW`tFvbSRl56_8ASb!%Mm-i@e1fyTJr%HWmPZ4}fZ4Pef z1HSDMJIR`vn4lY%Tl`wTQ}23q^@9w*oN=N}Rzd@pN)GKe!u++!CNd&2oIABjNc(7?B>KdRUNquuUw%!w{J8Lr*BUl;8dm7B$4n(=0*d+#J4V64nj zPUAL`iq4)M{ZV#?7pnIFO8F$FHu4fG0WJC$Ow|&o3@cFpoRJhZi-IKg@mo$SC;;P-@Ac)^AEnB@#wa-{t z%F1E!4hzryFCkR?Tg@LbStu}3%lcDf<;ZTI`-wk*+8 z+~zpGv4V1i$gbB4I^zHIeN;@uZtvcPY1hVH$U%2bV`jj@EN>v244l1@RI!1~J2^?} zdOH`yOxF?UF_GO%60`6jOg{xWh#Euny;22P1vS+uK3Y6qneAd?vXo?#IDuAP^n?K; zwY0nrlu-&4Icm7UP}5xZuxHo=(71)9|2ksZ)6BufW;==k_Z{N$(KxdZMJSmJZcUd< zX$wqCySy9KA_4uTrFy%e;#Rk?iCkMc^XQ`bX%5lA4!WSq0%>pTH8ufo!J~qjLbt~f zp|??y`rV?s(*r<@XRlYC?^g1*9!^<1?q(dAl;H-1Xvz9aEZ2x3Qo z1`^~(Q~nZ(EzTn;t&xh&V}$I>*MyZtPdpo>^cgQ*j903_ zA}rnmZlwj!65>5Lc_nGW5!4Y{Y&F$uNA7@XPZ4sGqo-!8=0@~A^x2W{biMDsK#rP; zL$Cv~|3kFsnbVNm>^T7h_5#@f_1i(;#Jq*BKakNln8|d5SFnF-J5W<6eBDDjAD;Hh zp7ojzdh0mId2nz2nFE3a!tm_&T{lQ}Nn~i~UaEK!Y<*gZBlCKRLr?jHqh)}w1p<)V zkTn*s~rk6eXT5fUh6Q&=9k^D1INAGEXYeQY;TH%u%Cw3rRZe1=ea(j6Bw z6&YtyQy7+;d}z5r4ARxZMXR3!i$Fm}qr1J{&R16tqppK?_i^2hDdNs8-(+Ev2avvj zqwNb=N{}O2xW5I^h|o)o$&17yBtVH+K838Dd~N}rw%fXW4M{w!^gTy$LakT*optfr zGw1xetbzLpaOw&_1Qi##QpBJM5(r!1bEVXs*4b&5x4*wsX7#@6Ui|#H=GQ28iEV7< z(yc`DRh`6-;71Bve4g23>fN7+k-AUIRiX<=BIza_JA2A)8uv?Dx#mB7^jE)ro4Es+ z1m*Bi>I>F;e85Q<2XM_*4^+HLQfy&)0);e-EeGN+RnGme)^?h4CBO6W9<{fqnN+B* zJg<>Iu+4pMh3qp+oGpVVxcRjzVZo!ZQ)s$vbcAh;Ea3dqG4`KiVV@}hOtYNOGvBsG zo>8Zl;@uycLyU*0f#r{e3+BQ3Jt&{uHvKbWlA9Ui8)&TFynrhm*{^GDGoIx+^s9G* ztm=HP7aO$!yC+>%!~w?d&!xQl!~(vweU4W;FSRVj+n0D`*lvca4Lx6Rupq$&NEv@P zE1DOL@fJ9X>Q5BXY)$^0q-s=yxb${_668DB60Rz$qb?( zoG3uoYW4{#L;?7ct9bT{>>hhk4~hCgr?LrxU(FlwwEYs3A$**kvl67XWZSd?lUbaD|M3sn^ z6n=#WqD!{|R-M1uY%nvX=lV3|7+$L(D4cBG3! z7q%tjKw{IyzQ8E8DaMM`AMBngtCb-4KWppo`HWHy@>DcIg$;naGz{Hp4iSB4hgpld zCjsO<3uDBxrFs_&!~ZFa-2Kna@*6_`GCSQp`TV6wuJkkLutbEQfIFBL5{Q3(rX%67 z8|g&TBzbzxqzfs3q)7-c|MTYK)Z^rq*2ptu9jX(}-m3CVU4+l?f2V3CBR}Ryju4uJ5v~)eWN3yWZNr1+?Rw8)#)Mi zcvvP7k<6g6GLX=4y0PxZFRd!`jf(7=O@h62WU{F6-W|MZZdp}4>~jYcjn-%`kRkX>(l+NNi7 z9L|C_4saj71gN4r+ZDNjx4(@(#cKxCr|)jiQZ;fnJIq4JmAokC9!8lZ@-={fuD@5Cevwy7_9(V@Wr?vVzXVKLG1-d}_Tr%}ng z8savPjU$m`CsT?1CIe_RN=U?!|D^h5l8Izc#FT=mq7%imhq9zdlBjsRAsjV}Mj);l z2KdqMrGXU4cve)&CRwPd>na^}a9I=<5eN33h0v@dH42eM{x;BQx*xulsZtlHRs311 zC^+m$Iv^VjJV95y#nTMO?@03L3lxF!BndIX8WMvpgacwZgq^JsmkuU^iW~+XI&g|C zgcC+XMvz2;5=VlTM8@1l8cOP;ltIy}Uge!iec~Q7W+xp)csnG$rJ|!lGt=7EZN%JmNLESUo1GE%v!UcOnH!hKf}kmZiB+au^I<6)1|1cnqN$?+ zxY=Gq|1gAa{xSs{@vw00LH$L+pp%t=xuXLu5dqGX0B_NT2A>VmxK*S^Gvr2)i3gu_ z0+fs^9@Gd30|*qFk2FLG0@CVGgCvBU1#8T3d`y%T0w~CL@7;kcIJ(DC7%H%ybeez; zSThZh7-*I`QIkL>E%4+mQn>;NTZD*;jR4UCNmCyU==o2wq`okhBr`R z&8~N&`3k4D>rYmI^=2)#=&z4wnt0}%&a;I{gr=d%aoU-%Ww3-H>X092@0l$G1~lrl z>*-#sS)wRZwj@-hBwVmtpn9uFgQi%8HbzgL|3qnW?3@lR^56+hvL_XDLv9CgA?jG!6WSxCYQ3BC-$Sf$%1S z54djeU~AOjQ-l$F)Zu%6frjWq)_^cMJ7H-eOLs#RB?}ep1M5>y#L^JmTU+QBxD9*t z=$WSKLl3>o-VoD5|4|y=q>iOJ=O)gW84-~dgR(i8$HI+{x)mdDKcMq#6UsCPCxu$^Dg=-l{+1pFmp?(FwisF@CrFqrDX2Se5=y)BSo`W~9=+Cyo2hMg zWiAN%q{X5=ZrKZh89knR;EfWGmkUd!Z&-d`cZOm>lvNfAUS>Nuvwz>@^9C(H>w|sn zohi>`C}N2K<_uR}MDWRy@RbdT9v@>x8qyr5T0VbafIgrRo)Jy{%WhU*jSWQY#Nm8TwAu_NW!Rx3+ z2SYBT5^29hj~hXb7ek7HCY8_J7tCU^@}syj)e2uZk<@d6{H~R$VeO_yk*Kxkr zb@QzExm0BH?s}}?GK@ZZg2TTosOAPlf5i_47W_wp{~!VgKs5MfMGFp%Sg;J|^r+Oa zo28VRr1ngt)MS_{wJcpBpgJENHFM3ule&P6DOtkF{>~unClY;NGYJdDii!ytas{Om zPc;7dja?3Hq=rIPxA;6cjBE z`{wWG4)wq5OA$m{V7{C6aG?7AqJRUdR%OU?o@Ba6%)S;17Z*xr2A8P~61N=~DKLql zUYY|wM}hipMoQU7)3_6in}ZJrf30uhBUn1H)!w*kS&fFJ&~kiAR$N~Wq^8g<%tKpvCeMKlUFZC&14_i1@A>$jyjg? zX%&0(KQfWucVb-|iW`dvZL^%mTiP&rk`mr9>WtYT3XECIc~{;$1HeuOVs5HVWw znkZcPr0|%LGrdV~uc(Kh!cf2_Q()Q2pjrjtA!LYNSO>NBabCW;YjQEw3yU)~xc>UO z`e$9)RsNscED<>l0LA=(kUK2_q)0!;ivlD_t(S*pC-I%~Ki$CPgLcOb7T~S%?%ll+ zkE>kY3KAnD-SWZe7X&Kz3)e0DEngw#7f-4tLxsVA2Lc&C`L@$ZD+6?zgr8ic{b-VVu7HwqHF+!!!< z5$aXp+BKotB{*J&CF+BJ_KcJ#n4C%Aa-irTsos);`+_xqWyrCPcG`MT#eX3uM~YA& z*QqCCW86`JF(Z%+A;pLxBa4Y0umpo3p<%y@WAt+c3F3)U;RzFA2~%N(Ga`vmp@b1d zBJG2KN#{_d>n=o7$vFCaaxKlpW%6)497nSU{5JFY@=TD(lNkOy+emY0(A2Es{X9Xv zBA9+FMeyu)rFir-#Db6khs@LXYx<95+)zlS5g2HBMD?%bV!!1gG3#37CmF;;EJIu-=Nzhugk#5dg_o{|TJF%_=$u?4; zwo%0N(FjAPP|H}1=g}Ad1?1-UJkaF#Y_uHi1eXo~zGVcgqpavjdYu7!NqgSq%b@A& zZy(GR%{_o3Q9)6y&4QUv%jCtk-hJ^O!F_P5vjSv0vAW8r^<0l5pAjNw5^6pY2u1$l zu=W=p3oDm14;8n1X%4nIY(78qQSjifGhePY-nEgVWBjaWPi^kb|bGhW``-s4w-h8Z%KoS&Ja}|kH14t=9RnCOLFW!K#E3+6+Q-g$BqN(GBAF7Hv?O{@1;-5$_6x> zZL~V|L=w<;eYZQotv%;Pn}GwhSw_Mst`E83uXw9ZK!M^qHM|hw>0nRKHSdc=3{M5OtOd~?oQt+ZFD#i&pDU-?DB%1esK2 zAqaE{MZ1p*RavcQj>++>t^X^ntmE81{e<}_X z@)HuzALwsizaB;TC!nA_$q`ePgV0h4DyXG1xJkif<&h7uwZxK7+9VdK8D&GeOCo6z z9X6hi8VJ34WhA0CG-`f}pSggwFP*k*pSB>f$orFb@}odR;A1rc@^IkDaU-YE3Cu!J z!hm5;n~q^PSlO*P^t)+4XgUnQpV_tk%c|wGxz<*`juC0EckUtn%1SsW7J>>A=@%_g z{`+TzgnljbjWxENLNA<}7SsPrj@A?pCFpF~X-RX(N#K5P*wBKp(z>Jt=CkjSP7(CqC z>{m^##dud4j!|3J$m8Y&6I^mitY!lnp@Bg$ir*UTirr50-R)@4anHV_OH))CvGnbE zSiic|_8#-(i!^czuxk`%CeB`WXBN!j?KfJ(R&*Dmx`{Nh;X&F=GH{RPAR>#xcYvleWoaZ-;W_O zJPiTt^mLZFp9xH+1cin?;kPMja-6qm38hI8bGR1;P^m4mVTKnJ5hOMVVd?-^i;1KW z(R_#C6d>DJqc+-1D?D@&8LNQ%iQguM7c#-Y7{fu>Uq1-jH3?s~5M#;azemi@uOAN{ zZkCvr73xL{>$t!U%PXGTYubJ8w@|9)$MdUn6_DYB$hA2AtK&y!Wq%Vch*X%rr!-U# zw*GNKF*$AgkAd<#no*LrBkkmDZdt}G9(bcL)0H5Qu4B0vp z;lc|clkW+S5>ug09h;PnVCLUCOJ~^LW1C+CeNF0`>@4o|f&zHPaxrS5NLWuibPO4B zUB@hq79&fz9{R4@8;e`~bx!Ih(jb+u=PvJJa+e*%4XQqCT-Mv5}1ylm#Ep(%eOxTZ_jgAP{8L(@) zjgNV`*&Ob1Ubj{fh8aIrt z2Ym0Z6UX>I{`y@|{=KiNC_AjEEYUU?Wkh(ax4bEJxtGKR2Cl=>GBaj7P0CCQ)zYHY zw2d@Yk46bVIJ&j z-n*+)hhwjA>~^MjlNpjn3>j|s%hOj_>}+CBi82aB*Pief=aX@sQbum0>2v_FrzPL^ z$3RBznef2lJ7Ibp%}-a~LY7ch zrrZ<|EKE9W=I)Ip7e+I3X?H4>j{q4wGy50JE(m#R36SJD=%nrpb@XK9Wf6V9iLTNJ z!0{$UYScxFl!#gB!D-F2>M0bW#$rnfxXP*@C#Ui+d)#j1ho_|lPY3idB7pH)HR%u~ z(QNE>xDj7!aBIIrChL=PuxErl^5H``ct!f5@D(^@0BwqKJUcXlnbXVrF-PfOe zDyLC+NIfYdx^wnZZi`qHFc+_BOE*e_a_WY2I6K|1am)%e)A^m0tHaTI>r`h6z=ECy zW#eSta3Thz#X=zYxkw-s)Udkibg$edu2|H4z4oJw(^0Tu^5%&4TZ&B=6<@LrIyF9& z;>1${HKmvUW{(CJaC(eD*DCG1_XG^6x5p|FVDP|Q#Pb8u_+U6Vi9q_Ohd0$e`FczR*u1e#qdj*ASy2 zac*d~pRW{dF&cJsp#;-s1M|e}k@g>=+7n%)Bernvp(& zxj!>K3BDHEv1`;c8v!X+yQe$fnz-cbPjpev@dj%wjD zw-z-t>0%AWd?zOIY$YXWd_kl-+{Dg(jdeT+p}CR^frR{DppG5BP?9Fij^4viu@LmN zy_G;72I zMrEgA#Uj$?pJ!8nWFCu5I-E>4ksLb|2+&s*ib6$7Byp9+TTL%Td7PJ_(YxtqWPYIAT&c7%~ zi=-oRrr78vqz5Vwu~sj`^6F`hut}0F+IHIfwc~dGSHa{VKNVCQUm_06X`U<9f{vXy zfXwdM4J<~Y)cMZ}4M`+1$8_k47RK?z&E=AqqrO??iqmIPlqX_UGg9rBtC}U_z1__}GTZ$kflF_HwDH?16 zAu%FG$4`j3u-fVTfU{(gVylit!ep}i~kiFEC!ph@=p5kLkFkzMI zg{MmaOs@cUgzK*5(A{cW4uxkC0ifa|9s(y04)n$5)xEp-k!H;j0CSv@>Mz5vAaU#e zw~&eq1o)C(W>l|#hm?r6IgnFL zL)FTi6%P1JoOSQB$_d(`20AuvcJtyg!|!Uj%^Z3WewQT1DcpdYgG@c%o3CirdF-;7 z{hp6H=FSZQzuJ^PRUS|UP`P>D%}*s}2>WbO%Ai|YK{ zUf$cR2JM({h+1g@TDty*SJ7(?lFLVVT@Rb}d8&wF^9!7CT?YePik)}&W+`R>(;VnT zr>mYyTqe80)($z)A@<0}8Azyf{2d0wT>JA6vGj|Hq=ntDq9ug34OxpveTsOCf+fqu zG~1!6O}Xkx2telJ4F25N-}Xv+&Eor+N89gBaO&6%BoGs*yT0o4Z)2v_K4M+glDmdZ zLNGUXV%+n!|0+H~D5;V+vp+WAuuWbKYE{9<$Wda@z}oww{hb9QstXS^hf%+mQKc=i z0RaN=(s67DSLVu?ZAyN*O%4)}g4H?4iD zPIPBqe?HRPFgnP<(|h_5!2`MktC?HSIS2G<_O}f9@zlf!e^oN^jLyd(em3Vf^L%El zs#OKKf&=f%1!kw%BjWmqYd69qi{#Lm|;5_MzI({p}ZFK!{Eor6Yw-^HGeb zx|G02hS>*Ks7A;nLtwdla#v=x%ufA2?#0wGv=6?z_Ism*Vko?`E(=rW{3M(WQSvEi zXi{2vAYLxJ#1>LY}k{ZXq*O3DlUT;qO~O9Q&P6t9i^_h^ua?&EIX zv6X)syD+}pE>cZkEN|BhIPW}$>^1VX3 z=dr;lpWD+}yBL=ACjtoXKO*R1PVutas8y5T`sAEtBD!{Zjz6$lk6Pe}l`QrX(2aN3 z4pcT7sX+)Z^)?{wG$l!{cd$kEb+35{ zJY1maT)%p5{>ad?udySdP@=WsQTZy2eb_2YPm<2&V91-dXgj*?i=PIM{5z+`lit4p zDy<$@wddALJ}sL^B1~I`aIMXTozci?rYgxfpFE_S9e>`e$f0?4I$-HDuE^~BA_0jR6aR+625cXtd{QxK|JE(a*>Clo-MzA|>z)MK zeS^T~8_ahxN+dfnc>Q|!5N@2nF80MqNlmX^q`cdBc2z!BW+ML{h_qc@B=&eL`1|heTEU>06J^ zb}Eo#=*h9@K!dD}{;E^55GqG}GH`trE|$H4=loF1e>neYx_e-E+ET_7v7Nkyg7UUW|;KRQ9s-~ zN`ZuM5n|C^0nn#67}eu4$)5Y}(IUCe`S>&mjIwmfwrl(mkxYkMA4a$ZEG!&xq9OGA zSx8|dq^PjDVydLN*}o;;D4lqIW3C#d^^ZC&WU!;y)TNd9E9jLe5CRh;mb%c-#2t_ie8kIC@0x*BLk@LktfkL$O z4!$YP)7sXgr)xKN`M-~INJ0HI?S2jI>)PGu-dVypcc86hT9r?)7<<(co&TzNiweVh zeQUe1JXDvH4~F-^kpo&5?3jG@?8tgw`&@jf4NyxD9`rMRM2!D?@Z_S?Iitje0buSU zA7%LE^Syn4D-9MQ3~4tyN^!HZUrQZ#xBk8SiUp8lrz+SPWWXcGfJrIQC~B7vt{bBe ze+?*M_WRTqd0nwuv{^Y*^shxYcDY}Fe&Gqy#QuL4fWS>=I$+S1DNy(&JStL!3e({aa-c?HWjZ2@|c9XXg1q=r^fsyH70-&$_W z&6|OO@!+EG^Ffz^>V4*znqlNoaQy+z_-U_i+oa^}9yM67H7ZEgyawb-$6^<&V*`75&sK@faj?Z6TKy&P&ZM-ED z2-^yHPYm&TyF-9!knwx?3LsL`a0BK+1CeAnP7mF+a=ORHK~nza%0EMM-W|E+<<<$r z-G)(*zIIvq$pA;c_aw;eNwfvRr_MP+Hjwm<$=rxpfUzGoeEioyfoi^XJ3!;5mYAb@RqGj?*b1Q%&Bx%TN`HL{;8dh7lx(oefGQE zP*hTul=oxYqQfT(UJ|JKdfQ4@JO6rzLj%3qmtHTfs4UzNr-20R7y>9aMu;d>I0ZZa zTdE&Db35N|+ibI`V(srQ)&nccjq4Mav%oJ%#=KbLDPu{lsTNlrOunpOIhrv2^l;h< zH7bU&gm-f61lYeHO0tvI3O=+O&=zG)v?c_boflzOuxv?oE=xDMZyQB4IhVXmGJ=Ui zRgZ7J0?w`#?X?WB9pvZ^REx<=c2`X%;4V;mk`Nz~%JDfk;VTCUt0!}8;BL_%vJ)(c z+PY3`rzxMK8u&lQ&$Z{>iD%d>yJD`7hrfT$kWt7_t65?fD%2?j&Cd3_epaHy0*+C6 z^JmGRtl9As>QZ$O^v|7F#}D)cBtY0ka_zac1OU0O_RatBB;XSUVkXQ0?*Z@!)5)i7 zG%zv|7Tn;)!{DB)iKl9~wob9{^uTTby~3Bd(a9Dk<>$$fV=1c=*jC;1``N<((R2-b zl}B5&nwo6ewrw|QYO-y6a!uxB8%Un@P@mSD%4Gt)sGqNT!r z{qQn1RZ}tGVORpy-RKqk34~T%;WgLVvuXTmx~((V(_|7pqc#1~uHcd7X3H^pCJbaW zyivb(&=ltWp+gpF7bDP+gxsD{Nt9ITy%r^5bZ_jYl;gjzo}_>T!W`kdNHy`g<1ZZY z_s1ucwk;y3_8s1pI~(w3!8p}clj()e?pmiyCV04cM(l_;){zHBWAv>_k)o!{qIKC&38+3KO} z;erd_WcLv)5lZxSz7+Uxu6%248u!<*%&8??YYk48Fv5YIaV#yjixvu>m-8}&jK;o$ z8~evEM}B0|QiUYOW(5Yq7CcFq!+RGAwUQRIule_KUoR|%*{*KQvVJT2cOR;KHT+A6 zv!m&oMVhM!5~Ue-lZU6B8zHKsxN=m~Z<9&C{-spx#9D_JWc!fP^?c(!3hqeRDM9!> zTcOPU?T#pe0g?0Z3a>wvYn^~mfSV(7AkDrds;L~m8#VqJo6N6(`fYGz(}q@875g;H2`Vt0d~uqY>U5>{Z!X8*7s~n_)_0}zX z(COVta`e}KO-|`Sfg6;l(s7ETg;e7UJBKfP<+=&DH^&%0%CvpE5BEUH439qnKlO?} z(BgEs*ir4EK_dfuuSjjYeH&*cN}fF>>Z;09SvnzXB7N--lHdLY8fdU6TTNkDqu0)g zMXZ1b*GDL|F4rMOCnj8puyn*?PknpI+s11v;`nph$Yh*4A}tzZhT6+k1Sw|@M%Xxk zrFbNRaB}79@2D8s4R$bb;{}Uut;_4})CgYoO1tFd>cgR=zqS%^hHSn|-nY&lGZdDBIO7uLJuyf79#IXOA)0rxZ{adE^D z`O7h$d8^=!5&HHw9x`d6+}PZ9E=*cXwB1D>l>`Qj4=8&5QQjroW|0rHmF4v-H5sAA z(9xvNW|LeBpM_qQ{e!x1c&K zMx5oFL#mj+xPOC^wftWafpjE7BP^VSFb0!IMZ4JMy?fWjqlME#A`mh85NdO_S>v`K zQ*nRnr6GG?sToE}`MPuc)B>AT1+;|Qm-=F58()pQwPsLa1#7V3{*>0E3N{G6(DD4d zjh{36i;pMlr}cc3IC+=-Bd3%M(F)ezz9;V;^lMXN6IQcL8J(34`!Xn-^@_>*bjjO( z*cMIy{E+0&9mm%l#9vJ5YZq4@e8wgPJGI;^e@dvhaB>s2{+hG8uK=Q3s~b)-%*$4X zk8c&Od@`hLz~R8vGhp9iSJx$yD>?XY&lS&6=8$9jvvLxS5rZ07SbD+qZ0p@NK7tQu~ohg%bO-AA&#|)Z^nD zJJ5A5f0t^{6A@RSV)BmZ$4hzI5r60a^Tp2~RAb4s*z+ihHnm4V6%UsnWZ^DlfM|Dqu5WfPR5#qq2@TGNtaYLJYAg@JbSV}oCFYfS% z%ckKqz$P$mavuaZI)4UKv^`=iPxcpG=rFRCmS@vH4LR@v>4@{rRRp}>5V^Ka$>BLb zX}whlAMudUGa-@-!zt+PxUg=edLoI(ZRS1#X2J>sorGQmzC|0%@Ihx5gv$vvIk99Q zoVz7O?f24Yasj=S6>IY{aN=0O#Qnl*kF@z-aA|``veVOAaYQ+>V~RR)fx7|Lp5Qf$ zRX?X+Hya5nm&7G2Bcc#V57Sz?9l-~_Fc#woh|6EGF?x;|W8M&Mz2`ZeM)M=y3=Yxx z=iAwOdTfnkR9v=Q-L!>VU7HO#wEAKp6d#>kX}VVBismv|@5#3d^ae7Wz0DX&WDXX_-*2+{X?Ti0T}s8J zsU+Iw&qzJfCD~N1kOMW35Rv~{y%|r9dg!<_`(fh2&IuUko@|9rKaca%@5;*ld&2|m z6nMAt8jxn6Q--~buL~uV^CaP)*I@?0z9M@CA4;UF5GFRufzvOR<8l%2^X6=wDUq1B z68XRF90q)DB&u-xj2eHTkC^hr5fLRy$7aWem5t30Gmbhn51a%?9|kWiPYymi;%ebM z+~2*m);imcep{Jc&O1VYVz#dBKEIwQ_6RSv&u>+^Zb+BQlQs)mD13Rc;~*6+z1P@tDx;m@iOk2Ul`@ zH918{FZeKUQLTqz6sJjg&N6A^Io6_f^W}Pjk>>e&*)5?_^f4RD0qTPbqpv#_V$p#T z%%4bPXSja-{s<9#+N{=(Afou{`P(As@_;J^f*FmN1rQvNbhUHu6i;4tMfs}*`5tHh zq8f#Ds%Z^{)Sc<&3;@eA*h_t-oMfBpcnx}{PKv?R#e(ZGJiySE|3xNEg|3utxS?IT6m=gQ3MeX_Ug`nDb69+~goe@_Yp2@J z@4|P8QM>0p+}|q(OoI&$1eSccnaqt}|W2!P{t9iYotvb&q9Eg%&)Z$xdhO@%8 z>ksFVZj%p^2lpVJW#DlOU4jI*g0I<`!>jYWP)G zQC;-W&Bs6wq3pr{nJ{ekSc$)Q2J7FVg_jp;ntj|T37^Nxjz_DZ7)SovBRD`>-f{gi)+7#s$`aB#47(Nady zTPov1tLo-T6gO4q+;a6BS-;;)&TQDg)n{9nnSJ7{BC3#4YrD$y#Gv`EqYL5^?zp%f zFWbn43IuguNO3t5VmqhV+GGcO{B@`Fk8#Lurn;iMF3(5X+P5ea}C7vdo`J1DSCp9ha2UMyr6t1GUd@|_wW<~bD1Co{39QX9z{C{A z{w^JyT?H$rQfTlrX?>A9T|%hKw5pv!u?w;Kt3Egait6>zZ{0u%B}AQ^-zXMSp67^* z4C8xL7QNMUzhiU!UCY+_u0H|3o!nhyx`n+uwDuJ{D$iV3Yf1c*Wpex*^ClV&HqIS^ z_iN43qZZlc`vug4_fNPYWY`P_yIz7US&FZ4e48MHyz2#mGxJ+)Y&f{6!(sc_(_f{cc)u*#kAG3Om<0?6w zmEgy#XrW?Yjrnrldi0@4Nmbu$Qob@?yq3(E7ce~VTY&UC>twR5?AEL(gTVC{o^}L6 z{^9Y_@!*-1$Y1i=Q2)@viL z7d$;}g3pA))DGKM)XQfKwg;1#Odxz8AP8A_J>lbj;E=KoiaVnFw|Bpb!{~uD!IH5UQ&O5V`xPwh|FEGJ6drwoz z(8B3pzJnW_${US5oKL-lZ*|$t5Xyq#owN5DI&~i*jt@V0)u_WwB7Ff#%gQ3q)zVrU ze5B39}_gi6srjF{1y)VmT*D(Hex>KjvCVXyh+uw2x#gL7`x!R=P+-xr0ZCGQ8ZEH zaML+IHFE5;K6W7Yz~Exikl~!XbGt%^@&R8cb5|p{+hQp4s9vK6?a+O?ZCe!W{*)rP zFw=QOlpyR8z3z%SaoBhjwQwl~1Q{pRquwu319cnMc0Q>{0 zoZOmR8PmJB0Q?3gD*o$FwPYrC!w*t)XH@1fG=ARP=bZb6YN-3-+>R#^9|Z-(D$nHW zSDD+MzH9=%TJs?R#?2L9aDW-)%FM!k)#+w}qY41`BT^ea8h1rQ_x&5#L&R>5BkH$i z@xcfM;+P7~y>i@K$${FCcpxh5u&NED-gk>S+QsXT%_{z7JKnl0$A^SG1_IDwW0W7s znEEaaFeVEJgxvjUqyGv_-=Y(1o8<%LLtUPxqTU%ML0sVG5APdRruTM12a#Yg$LuX2 z6Sy;PkxJxW=QXOvgLIGo(dvp|`sO36bYerm7FF^SQgY|vYcs?jz3!tK#j<^MwqkJ3 zg+EwkhwYHOnmCsSjYN|O_!YrjPjgn7oIl3ABMuXYM9aR4>)jy~Y7879?y6ToU*}F0 zAl(q^^G^Lh`WdRaausq6`8s~(Bs%vIq)sMgkcFT&J~Hsek~vU9m9e(6`b4wV!WEz2 zQF2`YlBuMp!f97;po>wK#U{TO+K=+kX{JE1CZk(QYh2V$!r{saG{hRC}BAs z+s9@47{>~!^tBNT`*v#v+Cq}{{l5E|go19v3LS4d(ivy?z0G}5LPTu&YJoFk(9DD& z{-oAsJN76go=dkYwKHE%1qtkX&u`?{G%&2WSRduW@pQi0{+S^v&bzQzr_*7=b*r4< z03ag?>5k+k9x*eYp#)Puf58i$Fp?sTaf+5sK(G>Wy-CF5*8q#L3oYM>)N|{Mh`G)A zCsi?`>|`D8rpv}>i)phW(cIVoGP7>EkpzS7+h>P*H?-@In0pLHO@_mbI7>oePvomA9*P-tqHPL)J{bOmVW#~$1d*D^59okyYE&$pq-}-1*w({XV_`NdW zW)*j|@ZqJ^(732Xc#dtYrU+OO33l52#h0+C8}aAGR!v_@uWOMQ3r>_5*m#p3ez?&% zU$i~hsB3|RC>=)LAAkY;VUknI*0jYqGrqPwZyyPy(~$)ax4s>$7|j%&x~HoNr-tDL zGa=$+|BOL&@3f-dNofJ%E``mFVi>Me-x#)*XRBk*wZlZhyxpP@GZr%l@Pek2Qz`&o z0%0mPj&?~z5B-Fvx#(Q$M_9D?-UwmEczBdIsqL{O9~Xp;g*1$_E4p>>8MFC5da|pF z&Q(}zSy{x{rpa69y5rURBf=y4$AjOOR{`$u-^{dp0-xpPU6k=*xw(D%eqD8$L4DF> z0l9=v_QMJY(J9E=Fj=2sNZ@FW*pBz9=H=gsD;%$RL9^VCt#M%lwKVwlHFt(3pCuuO zfWfydLCI#w;Gl^z!OshY=2R5I$qesXMn(CYHmmhN%^<;ZgbxO$K&jv@ofD zXU9VqY7e?7KLyxxg)@(F=`w#u`qd%mK5mYt^VgGn#?Iwsb3O~PETrAZ++LkupQUe4 zZv3h~^{*_kUbKl*xV=pw#bF#Krz;2Ng+4DPB{PpEd~tbc-p%QlNzs6lOwQPJz!0#= zHv9HflxtNG#&JJ~Ocv#_E|cqYqs~ucfS0YaLhCn&xQ~6SCohv|-{he3Cub#EDh%`}5LJwDris zTNlWetgUrk5r9irSX>-JiJ?_88Tz)MfU;QNZ2lon zqnY)3LEs=H(gc`svGnhH*0O>lHksA$1Vk8_0>h!h$!Ip^;_C?Ef7<5s6ojj zceqc6ZwNq%vF`f+~%SOzQPLOA54`_ zfEw6(T8WLf!)YMF+Qv8pGfN^EHAX?(H#U$<#0w7}xPNhxOgG{ssyGe6PiauD&x79T*xR{#Ehpe3WSi>@`n?a77GIv0hZbM9O{d2U~t>8 z;12b6a3pg>j!+DhgloPosqa7 znS5yg4AI1%3(X^Mv#r9&&*LHlpzt3Hd))#m6wL~l2&;&iQdu0QlCec+4)(WHAXCmS zEQrruZ;RS#fMem;5y$y)=#xp4kc<0^x3Dz3!0P^^N|(Z--?vLD4Rx%`sV}fVSs~6{ zs2T{q7YYbS73yhiJ#@fYUJo$A)tC%rh5R6W{dj6JLRi@nAn2Y!^{%sI|2TRA6PTT= z|DzDqO*___e9ng_pXcm`TL|-5Vt2v%yyNVFbd+@P=|uHMfEK@u)>!e!eAiS&M5Tp= z#<>A6&e8gB@XpuhpqL$GS`hg3JmO;kt5jc{b?-2FOW)kKdv5NJrFNAxdTH+zJm>QC1Y~G4)p>2 zIeoBTHHLY(xl7{G4J0C31|C}3j}-azqA>V#}Jvnys+aF(OlQd^roi)0U3bsjG4v22?#W#h8Z zAixCf0N7l>@+DE6`wOVU31_p2&kYGwz_GcFS9do5CuGxtl%kpjRD&ic0c>9{b@(sU zd=YOQ=*p_tfy~jHf)!!O-+$egM2u)#@=E{j1t1f)={64!kf`XM#RJU`i%QLsB>kcNHN5&D4kl)jh0yfseV<9`<~5e65=6HE7@CdwZatB8=J& zRERdP9uK!SPU3GSpFH~`^PN^vCoOP{W>&`_%vANFXwTk{waw;N&$V5LAjVMhMwB~W zOVySi>k&wWX3!Wd>u=o}eKHAFHMh+c(~N%=t0!l@-JWbn#|p z#!2_P2p%3yxGqCp46_p;V5?Opu>w54>2-E!Mh0Zi4IiK&89UDBbcHVwcGrN?_U98~ z+HJHPmEL-L$EmfMBJdD&KK3~fOAJ~=Q9Ki&|Kpp#DQcv}q>n*V7pwBG12y7^D+5B? z>grOx|K8Yau{)lrgyg5mg&Z@|bd{eJ5{A6ke2eF6ac8yiZM_A#$Z!okH5W654P zkpLyQ=}(#@m4lojqP0WhBE8-Xa7U1wj+LuWTBC~&&Lx_ZXBF{j%Y^M)cjbp?H0l4M z{#KN7n)rcCYI08UG1+uLoGw!5c(_iK3_ibl0h8*dfdiP{w+uS8zjY+e2_AsU4FMMz zTIF!-JJ7Kg>WRWD5SU|r<$QpZKc_Ihbu|Y|BO_SjX;;E_!aeP_Z@+Pg*m5;uM!93( zj2ttS$L-Od8d5D21b1vw`( zMZ`a~6F8aFcAtQMb||VX07^_a)~Dh*G`NOAJ7npp>q*8J6#3+ml$Fu4}&KdMg^yo9q0q|6&&=t}7aOJT&<3mG~J^H-`lcL@39kkA$!?CHc(#yP-Ir*VE4 zP4ZE-h(R`^x5P9wV1K3LSu}&?Cy#1@sHsto&)U;N&SCksgHiM~_~~W<^9CW^?W0oS z5ZmK&jx-TbYS`d=(O8%rZK0{ zbeCof-P6y@@#IAYNFO`Riu4<}O*hsfZpG)&l+cvMsi%g*!|xPBi#v;q-X|o1$EgJb z++nH)8IzgIQ2NDxk|YwZj=U4N}@yc#@<9o}7bn%uwxc<^`@A+s5oJHpKZ z^qC@ekXdC_iTf>!@P$yR7Ks_YnaC!X-Y-<>JluM}H{uUMC`}zNZSn{(cwAl~{d|?1>#RVKj?1Bj zK@$%skWwUrMgozJ-M%%4g5ZM^7m*qu2^9yEA~&QmRw{t$r9yrsnkg7sAMND_4fbfx zFJzuk(Bi^Vwb{5A>2%)jv-&A{ensg~8NEBcswy0EvHMAd#XL>}BI#yFyJsTP}4A*M+g39J-4%>ZI z?&|K6NdWguO~Ho%)K^j9>DyhdjvZEHegswbt*pv)`GRbQn?Ey*2!FrnwvHX*vM$ip zh?Py5tLXQm0Y*)&P*hXfdz#+l;_T!^W>XK!Oaz}kICF!4N=1)gvuWh?+fd1-!LQ!A zHlkRn8h1E`7(}~NsPdVZ^;)Bl>-36>;9G`TSz0oOB_CM*#z@k*^0L;+hrDvSks)|; zk-LwF#6=Wf zjRa_{)9rUY3W&s5rdPEyifRelV*Q)6T-&R)PXz9lmK0ilUE*;?_3YGGv{)t=NC9&8 zl{*>$s6{$KP->7whzUh{Qa_VJ#TCOn6tD9XuSuq%@?xjKpS%RHI@xeyO)}tMls2Q8 z+$ZE&s%$N7>ucYg9JrJN!kWBTP{{wqD5cAqI+#)k7I&-j`j5dtE#>Ek$)w<|>dbH_ z18{=%eJob#uaa?X_$=be!=v+t!WI}Xu+Ea1G_5sdQDqDEA1Xi~_}lRMxQV++PkQbd z$h;g5A&b#RTXeaTe&2=rlD-iXQ}L7SMe<^~ee9`2ZX(#Jl|eSo@MGLd#PUAQD$s}` z$fEyuEN*XVKoK<{_Ry6~NE-NWo(H<$e+h0FX#0=CI2LW!k!Wr@2g(aK8M9Fp^L zO7aV@Tcka1u>%aS^2~;+I6L?!Lk13o=s2DsEP$tS{fw>P2<=zq^%YQ+Uo6lIPD;mQ zc5-kCz=@%{$BQX#nX2%JYERo$>nbe23kg`}>-f zM+NoNUdMk?7%M%XI9#YWW+IggcKpV~BK93h%#bNB!CWYg1MM(O;mbZqHypG6S1)k( zv#6n$2FJSwEV#K#YKV|{eSo*RiGpwP=E3+iw3nUhb{G#3OGI*Iz3c~$;I}7wGctRK zwV7c~I{;_daoN%j_@P4O`a-6a{fVIeD5L$M9~+t#2^wM;Z;k^Fm!dY;Wg-_4h^;EA zYP&Ar(549?VtNjp<;twOO3>hfnfMI-J-J3HBUsl!-k!8|-HK8a$cC0I_;_wx&2IC0 z;4itwn6%`HQNn8RL(svcg&30aTG?aPzl5P z{r1vjWpW(?_y|(D|9KwIH*K^9s=^=LhzI`Y6;c7pCyD)UeqHG}0H=z*XDDgw6-M)- zKhpyw#gwel8Me{bIy*c}5EbM@#LB zexb`Dl>9@OGsi(tP)d2WH7BFD-sefh52~Twq`uy#e>AQJhlT)hG83asF|6*3CAkRl zyd?yiB?L>o<-SxNRRTD1A`~g8_~elA_mgz}UC02q1>7*BoC=$Bs5@=9p< zhq58MJ*eQgrb4h7NzuXt0|O6?TAI?YpGO~958(|cm@`y0#`4grDi(VP9z8EW&eD^!JxTQk zb2>HnhJ|s;)eCKYNr3{LJ0&A2VJke}7mJFJ=vmxW#zDHMM@UErz8l6Xj>N()C5{tp zevWv0={4*uP_+TPPk7SPH!mSW!6tTIvk?ZUuR&gMWI(B#^Sun<1Vxf_gvsL@#D3+=vXImn`}9;W`BEJ%=A2|yzTJF zUW*SlXG^Q+z4Z160iNS#!?U@JAMfqxARiwtRnl1;y#3>zrpOVyNuqnqy?{1q^U0p; z7sF-)Q%RN7m(BWE7`-^CSDhKgT36qM^HJ||w5g|k=ySVD08gCqi@q!%mq}t= zHRX&XbS{M#WW3qXr?k^D$a$Ys=kgD{zp?g$I0#D%xJeMVx^5D|_4F<-XCvG4a`ZrI zDhCHU-df}9^Gkbp>ry4@!_j+Up8eZA(c2OCk2ErAbEQd)8!M$fc@5x*7K3%5!}%+) zqa-@FSX@s*o!}Un+-BVZeuMj?6~aY0^SP6!c3oJfx+mwsb()og5+a*{VTLQC{jC>? z{JyFTSh`2JZJ%qBrbT}g-l`jO4*N6mWdA7tAd-$d zmr`aRFxz(Yyv_;=COT_%`KQ(_PdayEQTV(%Xh9jNdMY7|AV>Tf9+MwB0fQ0nnDqYV zngL28);b$=%_YLU+ta$yL;RLb5&!U6FRA`sCm()k6f>A-rw9jc7t3+-sV-6t*k=&^ z+wGH_;~2CUCQDX`HY?Np+TUJOj-m;{_SLlYT8O6YeyCaf8@fBRHu9= zlXV2EO7c4j06QaeW$e_BcC$N|B^UPziOrt;uQ+Fa9H7Vzmx&(xrUG@u;I+ZwyzdKC z3Qi7W20NBpfBm|RLW+q^us=kTM+6effu7Ay0B4^m_ zQd?U;`f$hk|Ijc7h`rn&NyTv~59{$%VU=038rph%v>M~OzFuMlG@lzm5-vJG=FLcF zIf;R=q=KVsI5x8-`d+B}-p&BKSK~eiSa3wfO;Xq4^dd=B{gh1gV<(@gzHxjsUwY|U z-J_%%4Q=V%%zppZO+@kO=7IpMPytM^4#FG^TG|nZ&otUPiP#v)^eZQdXqc|`Y@3UK zq0DzQ(1EKC2_13kr6e<;4|qdXRDdU)CNZa$33q^;oB*kYcdC$(#q4MP?#|jnTfskU zL9w%~6{h}cmyci7R2(~o{MDB$;_2H5z{okw0-)UWQuBlRNTmY2KCIUW%cb|?-)7y*hfvHtY2%X;c#bO zjsgl9nI#Rc$_j#$?*V;vl~=mdEPK+gY7sOPSq$3G<~#6Ace0*k)>DAZ$Hz zKlGif^Lm+RDn`P?#w2HSW=9@IvTI|#wF)bznFd~Tr9)g>ZriBty$A9Qn6Lje7bz;2N?Q6{BcY>uMF4PnMVQveCqqfm zr=3L*A14Zi>^IvKD<}xu7k4ioyy`)shZx=0f427O%wuh2{YpWO$qbL~kzN{kj<8=~ z`=-T4CIX;cOfJe==?1a?{#2F2CB=w5bn2>k)BJ55MYvBSAw@4bPIqs+h?nvM?$*XM|r_ z7w03Bm=dPm!DW-Gr0PE@EmMo%KDS?l;WN_x=2fuU@MH;|ioWmV9DqQIBgy?Stf-L{ zlb*bv?;va%saNY|^&=&14$$5^UKh6vvu1_xgl>JEvoSs<{ z6w4Mh&Ae7AOkJ*$RD7lC7baj2ESF7;&@OJqVXi3X8hS?Pz9Dhnyqz_88X%I;G|}&j)AU#ppE&tFMUi+c=prP zQM||za<-4)0NkFTswSfk=c511j0LCHy6>Z>kj#}?Qx)1qFGR;Y01^>bXRHjnl1%RB81AeI+=m;~ zwIOBiU%nm71HwF&UWnBl^C0O28yh=2`PL%1yoj?iR=bbILxtKYiL9_KMt_`B_8z;| zFA>0CgWxV(EESjAS-XG`=Bww(u7wPjf_+n`M5apUI$IshizHq9VFh$!rss9{dU3b6 zLU;nc8a(R%Z-~${Xr+b!lf=U3{v!&DWe4RNh|U5OLXYp)oI2LL@QD~ zs~*5Y@coMyitGS|j1Q=#UMttXoA+Lgy*}t-0f}AUGV4Vt}PLlanR@SdT z*HXFazIooRc0t}Iy+5{FQ_t4RO!I{UIEe-)qKCzH$RHVn2&zvF{~H(xtCQx49$Ih) zb{S|tXx+{qZV+H0aDiq3%)cOL7K&LtOHhpL_qIOT8JGVa_pEDR+gL@W2iYRaCrWTD zhwv57YZFAEZjcxuU5($AP5$*9+97r++nK3)MF&bUzBpy-Xa+F3=L@6^(6v3`aMv4UbGjm(7F}tm&Qwc z-lZj*m6|3Eo_f29PrUmc<68NZ93g@j2>>^xg@dhk@xfCkjtRogjXq~iz^AvgkmAYj zic@R*j$#DN9SD<+n05o!3&0e8k_QI`dzdMk$lL`;UuKR-a0}**p3tYwq{ppP0B4AH zaH^P?fAa)=({6fb&vis2(ch_@Sq6=9ctR8}6<4bI1%yEXc{qAhYYEP8MC zOqO+H%~u%%mp9X*hCALCq7-mL0otvYu`L`}(x{=H0Hmy?DB6wuWw z%?Zbe7Og*S4LRkdH2#Q^T$6cpI?enUC8>j^&7g3@w?zh$DjSfejeq0hG*}WE+6KKZ z+XDD;szh$e6C;k6JSwS_^DVFAFu}Z}H~8h?0ezGs6A8SMcNeAG)=lBX)l=Ydd~`CL z4RjZrd1rgg&C_T3Pk0-egXAtlCY24t+b^!s7}&+kQ>(^{pTv47Sf0BHXuzyQI0b&xm6Rg8gI3N^9xDI;7LEvgG;ibia;2}VwiR<`|i}&o@km*F=|5o%X zXQQti%|#{-!iD=P>Zsyv#vB*6aaAH2;LrwJ<9<`W%&lBDvpYMEg?Ez|{jY})U};!+ zT>y_WAGP>a8yhWxPViR|AIAmD-W{g$J^3fepVBzNj_0767)d9=6UtM28 zm{>lRTdV!7xSzf~{hCMT=;FC&naQHj%lCBH9jTiP)F3d>JB?%YB#dB%w1%*B{9c1^ zM?d>$>-{+ObU5s0f{TK`UL2n5xwv%5k97o=DQJGV3Zdw-DOc>4bo~hfmf9e?7Z{?O z`j<;%{*@`upuZzpdI|*Omk^jzrGKi@Wy#;aH(6s=t*xz6Of_cmc!J~t?&XNKcDo8j z;FD*@)1~O@O;otabm@fmQZA1GBCWSwt#`D{BD3ehv-Ww=XjyhO4jMTT;Trk66$cdE z+5sNVmQQs@pNUquyqrnZ#K0P5xKmaNpbOk-pVi_#zzGJAqd z_RAqgaoVS{N_ru=Nk;ZH`R)A|>fWAwKWclxZzAa710{1Mv}Q96irSN;mHdSLw14Uo z^t(Pn$n7VwXm42s2JHbbY5;+9$<_&oc5hRhlZYR1yH5gu;XOVCGe*b4tyL;wBTNzH zT_@s~$ltozY7tBksg&8thSEJUO)V`gvf*UGdJ@*JI;J$gdiOOmFYP^Nj);3AAgb7K zqV!(+C{>t!Ti0&xF6U)lYX*!s)Rc7Ykcf!lr4>sRzLZo6EU&CTc>g|>p;QXSPS#)Wo%Mp z*uwEER%&iUhslX+4pVqg4c{#e%dHtHbzk?&OCV|<4gD_F0t9qVY-mJehCu+8d{_Rq zz~|!#*j`=mBjR&xGgDH-RqZkN^J42#)~(a!ba7sXU#bF{jR;u21%-{xx08q-s5sF_nE}4iM3#>Mde7L78@VBfr=m8yuKPJ7{%R8q+-<_2 zII{+b0}aSLX6$MnIiqGmEQd zjSK2mWRTY#{q*bm+afA0ed$s{F4ne-#s9qkX?>3j2sv-NQxy0y>^daB zUj=QmE{!fLA&gmlW_PU9nIda6?F>yS;6d4cSGZoZU84H5Jnzd5o$@<-9 z(J`#BBARWn`!k|no-4O z|4bqQ6yqj_$InqkP$anrdk~VB9Z6gURa|;={+Zk~Q6c8+KH7&VQq9f}#!b)Ho+&c? zICh5*&no5n_|4~quX)tR$(J#u zH+C842HR+7qB$mV)vvy9r6fAV^=G_m` zoK0(Dj`dDMCG=Zv?e=!Rvk%%XpQ%hp!GEW2ViO78c{%>f&X#7g2TeQW^gWZ_V95{y z2DfRM`eu6z#R~5AAf1x7EoVfSb8@35@m!Ks{o?i2E;Bb@AycG^vlG-`?3W>N$fzvz z=i94mZr4$8)zdcTXN22lf6At{dQt;jwi%9cLQ<6X+xwe~y*0bk8j zo;J;H2PY%(rte;UZ{n8kQ6{9?kc-qKTn9MwRH;+?q%9>vkqe z^UUj^$#N;dCBIzjD3aiFg-gbXXlMW@ysI(sJO+=O1p4h#;86@#GA0w}w1qbvT9I!5 zs&a|Gr{gY40V-tcX49?Hn{N#DKQw)1Se#wY?Vy9ZySsaFr?^wBxE3!CgM0Df4h2eE z+^x97P~6?!-Oup6=leew+{uotWUpkij4X0l{Zw+=VI9zE)zr@4ZDvc|E%jPqgQB`P zf_y`U`~5k&C30+ulR*1y7X``Mw_5p4plB-o-n%>L4jV(P(#{7Hb0Fr)NUV}W%s6PT zMLwdA)vQ>}sqS1!QwqD?9O2ZB_KKbWd-Zh&KL{aNgQzHcGq3*^}WUtQeGqXy4E47-2UvijC!BMPKyGi@!m7ry@x z4Bt4Q8N;R!Z4>pp{<$c%Dt=X%# zlK@ac?0nUeRG6~?MnARQ@(dCa(>|2SDKg*8YSqV$!jiEqewO%qv{<>~_f(#z0`b$b zc|>Em8|<$FKr=!8V~biSG?p=`v*z0~dmtRM?S}>L$lK2b9bTTe8H_}stvXIy8SUs$ z{ujf~_?36^#PG__XEBmT2aROL2Nb#AqeC#DXBMz3@?csXKEJ&}GRxFOS9z3n=?a!7 z7xLQ%?+g@E3YM^E@TW@xoN!E)S*dN`l8Wb8bU%B(1Fu<5=c$WS@zNC;9=MlFn6yS?>ZlgjM_?$1p>4g9&qSM3wO2a?VMxC88clg}?kTM#Lz(wmT4`K+ z+}1_2(wkM3bKAP8$B4BeX3C9gfn|i-wX!~6{D8XS)$qw53G+9<=nSlW`9G~P0hiA} z*A%W*jyWls%QsQT=N*j~Ncrtph&gZl=r=4zp`_!hx6>jB6VN=PniBE7fkA&h1z){6 z{$aW@=gmMYc)KYMRFu2y*Kg93mc0zWXZt%-22i;AT~f;fa)eih=oH+*q9 zxqMx>7-e2Ila;WSho^S%I`e?T@Ox&WA7RZ|aj5 zx_E$(5)pg1#@($R+8e5h6?EU!D;p_4c5b7E<=|;}@r$geO@C2Uwe%Ow z>XM0;DbuceuDn}zt;+dNKc1`J&h8Gkhw<%ZoDm>OAZK&5cTCh4!Kep*i9Ti|eaVbU zh2Q2+?sAM5iN_}mpNihiZk7sGPx0;#kc0rql5tx1KTC)(AH#k36c{-)nbtRhp@ZJ+ z3s1f-`{ac}H-3sC3y7o`K^CC5&U;O$c{|!`M`swqD)B2G%lF|Dy)D(GR>)MJ?i(xzQ&qto^wMlLt zQ}yZ>dsNzeAAe58l66Zw8pxsU-EOv7IstFy8Moq4K~m3 zzEX_T7&Y`n#3w71m#}}fYlv+m&(eY<=yv_C8Es%$m|ul*!GZ|$oX;qBhHN1(F8goL zT2Hq-<0zXHIuyg2!T93%7+ zAFMbc!_TENSRHH#eRJjYK%07@1Jzw@H8wowiI@f!L5rv_>YrKf2E6VhIb;j?ISOk> z!{Q)+F!Vk!G7MPIVAr|E_FQrQ^f*Gz3K_*M0%^ZIdrzERPX@g4VcnCZ;#(J_RroyS z3a!32zk3?>x$=nzez}Sh(Zkd0 zO}*>%7v7aomgn7+TB03EGRdMh9>OqAoh*m#OjXO$)`}*Y122Nd8G2td!5sg?y-2UP zkmd!h3bqK7O|g&f*3%GpzqsX)KXWR<=-S8$n{UWu;;ADM@@ik`TQmki_IzWXvQC_5`{@xPv>gMFT^$4w$4leg;TBiOw1$l}5E(fP z7&jIbV5#OBYHI2Jjgbk@M~A&d%&}q&7k6v%#D1#o)~}5+yqX8UkUtOR-iVPmEM$a_ zpg}1m-38o0fcWPx4MGyFD>>hg;K$sn)N&w(Iuuxik6=fIm@3D{%mCIIJ{O@saPDXO zW?rXH>TCzcl2e)#2aGuy>la--F*>YNg+NRffB4tu*T-gSvWG0lL9*DnqWI5Lw@0Xy z011?ggyKTXL?d?WQK(j(t4is>~}Y<~Tf#-EnZlE8@ck9c|Y?ACDJU$K@r^kCo+% zA;b<)!}R^O8cSKnq29O^2^6Plk1$-HV*6oiMP8XNWd^c35quq%Ic$t-7k zEaw$(ovV2BepFPUH{8GEEqTJqIdx-^yB0xLyu$5`{scO)KK*-h01>GS|7ule?Uh%= zb0TUbTHDL$@oCp?)TW_TU`d_gd`EsD3GryHc2b?7cNbd(vu-ep2(F|_0=#6BpUMY6|<-hpHH~`up`Wu)dVG_@&^Yps-zfRN6kV5 zq};uK>Gy3nM0egjKGbD$sa-%pJ2viD_BCXE0sF?1ch<0&BQ)JA87TL0vjXlbqQkxr z`aBHNpS{=A)DU;M`cfZ}L-D0;Q;VBq$@xwm3ziIx1#cp~?GpX;Whl=c(ju^IOK(bg zo4Q@*jooQJNOyq@(N``FWW+%u`mH?XEm`rUy+T7K@$p{PL(Yns({+peAOzs|n5`}#IZE*D@11^}Ix<&MU`hrS z+t^)KuzfTsB*=)K2gTzD&qnRY)`kf1`Nn;P{6GULWLV~fd%(J*Wy0fw+wD=s!yga; zV}YT>w5{Va{o!IHaiFNMDa@{4=$@2h=OF#2YShKa2sUZoz|czVaFSjXONh%vuE z#z;+!0O-Cd>nQtg%gPCLZZKs5tYksLKruIT!QcYYZgS?5-|nQ+md&`0yT%&3@yDQy zub7`w%`j?TR1C0>R(;n5)g=9&Gyh0Zrb#UNo^Wty=CG-t8**$dB|RLx?o*?PH(}qY z%lFOY*m6(fEMGTOL@N}BGF$QBY?Hq$_H*R)b2YO9rWLb{fYD<_sauO*SvVU)lfZ<) zk8Y?HJ?wJG;{)g+6-Q=2)8&fwQQeuJ_WmnCc3Vh{ryO~tOP09({^4=ezzf7L~b$nXpHs+9SbUPyxV5JVqJkxcLvICt$x3f$AZoc zfhk`RTmQhtay%xzn?ACsM2DwKpPYLG%0Qxg1h+@qE5I6v2Dor=@StPs5>dWfsjYNU z>4IQC;ju1IF^bd1X6@bT#VtF;EiFF}`kpqOAlKCRI146*c6218bKa z=mO5G;it8ye~o#(AcT<`6f?ZEdcn_bzJB}3|Ec3WmQeAxj(-UFdpQR=h*)3{yVw$( zPl&{0o}w^%>+XonC-%4J70I(l;8@{2Uv!#^>z=`R$oDGK6^ETUk#)H+`b+<`3;$Kc=f zs&C6PB@Dt6o9ai>(HwFgG- z(MJm|GQ1ihlhrEY_R5~Ky(-}BZrYP(Lrgje+b0)`T8FXv1NW1w66BJx3JQ{Rat}fa z(D7%ZPRo%LUCn2^esmMPR8!D{KKj1fqdc&N_3Huvnfn7zG|)ewFhxs;XuN$!Er01G z-jWSmL;>hCLrcTMNj?|Lg@l0mj1VAtxL@V{P;{wiO~&=!7qjAtL$?iHl_(W00YJ?6 zhwR7ZWdLSAwvt*~dOh#4YzOmWh{PfDRT##vf2l6=qOjO6@$U*PH<`_ArkRq3@cNPu z{O^7z%Qnu1EE%Vq1-wO!$oEO)D;`x#4>IR$8!bqjW(SbN;@fZEeJLNKo# z0#PDBT9OqN3ezK>o*VC0F1F}n$sm#S3L!0r7!WcJ8Y!2jE*38~>?R8Uzy~lLc$INd zt+o;g?cYwmd>?ipO-A-M)PRSbvVMo94Z#R`e`$!#8Z?424*t#9lusPoPMo*{BG{pR zmT?74GQ{78smHuhDEV2o?+G&CU+HG{T-h+?*rOJEb_#^?Bx0&PgYGSbLncl}7& z?TEgZ=sG0RomO@m#G&A%Ey_XSrZ>2^uAK_+Sa;b6Q5%b$UGQu3$S3`Ri`?-^%)vdF z{mqKg70>0{UfHFcCgYtdyX$!XfKtK;k964n0F+!Au=Uw`k#klji{oXN_uTJTKfQ;y z)s+J8E^DRLQqTPB!b7`~Ul0+%t0Eeb!~A5-zTekE{!xEK%4*}JdOvVgm1xdIEqAD= zoW=bg$y=sFg#8J^w=J>Hnar-mx`Anzgc16-DBTFmBG9&mNWumgV(M^5Qz5o%;!vhI zC9nMhE~G44NH+gIUo7N_cvYpn8xiiA-&_|qm+^;2j!$7(x9txo*YJL2H#oXYh;&y6 zll2t}HyS#Ca}cn$m_%>~Ca>+Nq7{7itBPf$$yn?wP0~qrh1=riEr(9S0U1W({2YU4 zLCiKApXZI94xQ1jW5jZnqLxSi%*XAwSF5GfxAjDsio6xS-Qz{wKhBDM!fc;e@;N zGCpB5nn%i&4KCZGTe*(nom6@X(OK)(fGXcenh2Kx<4^zo0xQ|dxdD9|s36-?F#X55 ztY6qkvwu5E;5Hc){5F}g5Uco0@+m|U-B?m@H0qer0_^$DAZ<4~(&2ejA4(!hiC}E` z-M7a?YC^Furx5fkA}5VOnKx?kiBGodSb=tAk#RY09{)ygnmAN8ngcN7IdJ+$QYSXTqLoU$xoT18q z>pGtl-5J{PQIKfFhcOxZ`J#e^nj6mVs`UlKE)jS>4e3S218&_@k{&&<010E3&gzK; zVJFNsCoGt~d+cAcekChXDBLmq^e6aH3Y(trkxR^Ggx0A_cEvya5I=h|anO=m_a6fS zrTxrr%M%QZE16Np7>;lGDb1lN3DCJ``P&Q}Q{h9Pw4N*|_#Z*l=9PsM@fCv}m48cS zSM3etAX_?tdSzuZrh-m;4{RQ+TI;8N+C>FoW*%p$ma#p{t5b?99c+ah@Fn-Js02DY zX~^DMe-Wyk-yo$x*~P^=OGFO5&x_lqT}8QkU9h<)o=I%Ldnw?<7{@c71k*XVZr48A9lex8?I@{Tm>Qb!=`c}RRF@j+;qW}}+(dL+*&y&K@bNKj+M zKmSH(vc4_mes%&JBNPpUIQqu1#JmJS>GY@F)(YwB^Z_=pO%&d@_W*aHuAz0*Hi7(% z(-{A?NSZNCs@M>q=nqi_%Te*K-3u}6n)ZJ?T+Z3a^jElr3y6vFhpmu2_x%z)jZDDu zgDb?=*q}H-Eg>1LrafB6WsKZm8aP`+H#0nC>;o;-P| z8pd9~>t!p&0;fdIvh90k+yWM(27HN4AAxX)5)9q|PSK?QTzBRRZ#lB7HBy*x(Z@T+ zq>PDZ!WfIiuTKu~GV!pg$LQe`dN4!t zJ8;y^$eY+;k-TE{2u*{F#Q3s@oaIQezNphGm!pC{d~T0D=US!4N^R7nFU0v$J&|LO z%F74s^Ff2ig@o8|;zMGj1oWUK*FX|l9})Ygp#!6&SWLohqgL*o3ESR}vy_g^_fP#Q zUHm!k+7Df27@57^>beKx$66>x*ADk2VLwe-Q*YKaB4i%@w zpl}vB&}BK=vDv%xE5<-T;N&bxs5SwFq)UK{Y2s9skXO{C7;_FIB;=5^xUs$!IaHhL z35~ouqDT+h%Lrn2d43LE__Ae8=Cc%jr$FddTLy0b2moA$!>pzp*^ACay1X3ZO4qJH z5&v`Cu7SG6g`?ts>T5l1xk>(?m?%uQI2iqcGxB4U!PKM(bKGK4%b5(lS|`ks1eqPD zD&IkD(QxdrLAmk}_4<4WO^9!eOL}BO0uz}MNXWoo9LUfg1U8IWtmr}59Sf3mkXK~i z@+l<5hg9#_Q&Swj^=j7E0LNSsc7;5xC}IeM6XY2}!;A(Chbuy<=HWAx0&7Y-JEMxs zt08`n|Al|HKWSbP!*EV!f6Vco;$@Efv3SMtDyyhJ0UVJg!9vsVx^hqaT#M{9EM2LO zO1ntfvqFoIUa3_5~K7#LC|6s`hUK*Mav*G4z15gaKNSkLr~#{DMXkBR{cO#(IAED&{Vuk zg9!;+hFV{bv0yvaon8H00LpVaAENn-|}_7*gA`_;}$91 zJ*iqz%n~`yEBzcr)o7o9d!Y@p8ywJcs?B5W;Z8mJ#tdC=l{nA&^=&XiT{({ zSocHAPWCxCj#85Oqx*)QaweeyH-?kL&!ln8*|i5IE6|>KhYz1b`OTFh)(&+MLu;e&bh(Z?l=L3fpoAGET%2~D$O zby1=@HC_!BA$dc~svQEhX1%;yj8Em5W>^!8aRy;UH|+_lQXcww3cLIQ9`>8b^?vgg z)P>KYoO3Wjb`YB1U%Fn;Y;G8fHo}n64JBbYRaZHdjvX`U7z_&zurs*%zrIHF`3o<` zb%DnfOfmW*e-MOlNH;DmX$TA9a#P3Q_~-*V4HvmJv7>b@`_ZzV z_Ihi@9lmeu&x^r=?vRQ576`2|2fhv|qST@YdG4mqu%Su#?7lI=;jEA=0 z&fp7gPY5j?0X4Ctcu5n%)`KC(W^$uz6`-WkCT z;UY(RS?g@&5!F__8lPOsy(bpXbbHIcto=027oJT*)Uco)zT~9L^vQ;x149>E4o&bu zAWm~dMgptL6;84d&{qSA;Op?V0!?6T9mny0gs;_ZIP`Kw-&{UC40D{w!fvimnVcG`X+ z`QsAM|3Yp6XLp;z!YsANG|W~GmJ#r?POQry@ta>U?&PwJ1O}zpUsUlTYDfY=K;HQI z;A>7BkuecV=+(d#fYfd+jY5&QJsnMDmFA9;bJ^I|S%syI6*ToKQ9f-Zcca%tA%T&+ z>X|S6*!T_SWgvnKso`q=J(H6M)~;f+w-LnA0IK{LS?%aeb7E77=t`Ax3lS0|yFC#y z`@&1zNu2QjgU(r`WZJtuJ0<)}sRStuF|tyFU`$DI1gJ5}eTnCHbTq4YJ=gJY*6yj7 z*REHY6Z*woP{9l)=Kk6o<3wA3av+Ky>owY9h59jqM3T z-*2|RG?WQfvMCSM4z=beQc7wOPRud{D8&Ru%dExx%r~TTM`=+A-*rOM*fzrkxa4*v)FKq@zNBhL-!~d-}m^ z!-y`G*DCDSjd5rkMxNN?%1I>Q;dNueR@^6oUS8@hWrp96A4Xw$!=W~k1{1{}^VUn2 z7WMn*d<35PMsFe|0jmr$u7}gv%Dcpplkzur{R$W``rHge+i-NOBO-iBHzU$YXw2c8 zZmJ)F;VEFQ8ALVa6B21Zk2cdAlT6hNa8JaTu2e+!!mO0FAvr{-tYeNIT-c(Pe*-m> z5r8x~ZuHpPV%hQ~l7qk^p?Mo_DArNZ>xTjI)qF%!UcMEaU!h+_GMrAWDPV)doj+Gv z+n1!?a0!1c+SR@}Olk3lS6lN_WF~XVU$Q%Qd$WSsP-c<45rz+0uqUpPr|qJs5wVy8 zyVUjCto!|O<)v9iNqSH(_fX7s6R^ePw)i7-r5|O=kvvP$weVZM8Vg~4=pn^y5=}~i zS;bu?!sfo=Ba(R0qk>IwM)OWfx76S1y!ra<6NcW2r6`+sKtUVP?0SA?I z8@^CehHMsGm>&*fgZg%hh4~RcGt)l=3Wp76heahP0j!sXDJMMuE)(JFbgVwnV?YJ3 zD>U@nl}XpnUbl*bO4jp}7+-upnDzds^V_kO+Uao9A3vXTwF zF$HS+7;`){i(&SW7*k{*Dje>>KMyhkP8<$}!=i@>B^3FXx{jKvGMuk^Fbb8b_?(vM z3=~w-NW={bltenaSt`sZ5iQt8ckMH*b&ZsHa(5L!%_%VE8^~+1c8|`>!6>H=J1euZ z&W(sb9|Hq?NB-aDze|ex&^kTvmT@9s<_LRQpQ0r5)i-EiI^9@G7w9+{W}+X;w>bc# zNRk-w-yd$X8dh|ZxQ{(8Jbqtp6B^NIJgY2aLMv2H(m)jnPoSVI9Ww-b^fu64$&~Q3 zxMl`x%9NF?OX=$zCXDnD6ZPyd`gp)m|8?#e2E`m4_F#-tV9YdVd^wCQW()CZ5*Hs2 z6Ya2!%^3?R#qfw2fmM$3ad!J#UP{_Xd^ArO7nBwLL>x?mn)yv=_FzYDazkBcds_5y z!j&1ul=&)llE!|bj+aj#23!VrZg}JNM|pmLI@qu>Sef_2urDQnYlnPRp|ojGp@&eL zU1@%(mj<3Ee2-Sn!HG+Z?eZ5_fKYrUfQ|tUqeoE?2Xf1e)IxosDRDcv5BjY9oYsjh1gM>s6m&7x^PBMS`eJid^nGF$KPM85H?`QC z8zDx)8He9exME9%gJjLO{NVcFT05|pHhb#Ag8szQq8i%W&@SCjhCl4QCimC0u{4eK z#MYRKw@gy`VUNTt^58ySQ0~;Ll-t%rPiAdQH&Fzap+rq*BQG7TZd2AmCNH2!V-1<5_A=c|2vw_=@Vg> z^q$|wtMFqkaP^Pwg24MXf064p35sD*<6Eg_6UrJMgOa&ZiCZ?JEvQy!(*{#-KzSW! z_~-&8Nji|Wp3i*?QyUI)pRE(AkR+@Gio(m~

    i16B`ikF6i!01rvg@9+|ONa~t& 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

    ^DRU}TWh=zWZ3Y-{BMV)=#4gS%YCIyXL|wL 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 C8RqK% literal 0 HcmV?d00001 diff --git a/riscv-isac/docs/source/_static/theme_overrides.css b/riscv-isac/docs/source/_static/theme_overrides.css new file mode 100644 index 000000000..03c2bc22f --- /dev/null +++ b/riscv-isac/docs/source/_static/theme_overrides.css @@ -0,0 +1,18 @@ +/* override table width restrictions */ + +@media screen and (min-width: 767px) { + + .wy-table-responsive table td { + /* !important prevents the common CSS stylesheets from overriding + this as on RTD they are loaded after this stylesheet */ + white-space: normal !important; + } + + .wy-table-responsive { + overflow: visible !important; + } +} + +.section #basic-2-flip-flop-synchronizer{ + text-align:justify; +} diff --git a/riscv-isac/docs/source/_templates/breadcrumbs.html b/riscv-isac/docs/source/_templates/breadcrumbs.html new file mode 100644 index 000000000..6c6493a1c --- /dev/null +++ b/riscv-isac/docs/source/_templates/breadcrumbs.html @@ -0,0 +1,14 @@ +{% extends "!breadcrumbs.html" %} +{% block breadcrumbs %} + + {# parameterize default name "Docs" in breadcrumb via docs_title in conf.py #} + {% if not docs_title %} + {% set docs_title = "Docs" %} + {% endif %} + +

  • {{ docs_title }} »
  • + {% for doc in parents %} +
  • {{ doc.title }} »
  • + {% endfor %} +
  • {{ title }}
  • +{% endblock %} diff --git a/riscv-isac/docs/source/_templates/layout.html b/riscv-isac/docs/source/_templates/layout.html new file mode 100644 index 000000000..24c127eb4 --- /dev/null +++ b/riscv-isac/docs/source/_templates/layout.html @@ -0,0 +1,14 @@ +{% extends "!layout.html" %} +{% block document %} + {% if is_release %} +
    + The latest development version + of this page may be more current than this released {{ version }} version. +
    + {% endif %} + {{ super() }} +{% endblock %} +{% block menu %} + {% include "versions.html" %} + {{ super() }} +{% endblock %} diff --git a/riscv-isac/docs/source/_templates/versions.html b/riscv-isac/docs/source/_templates/versions.html new file mode 100644 index 000000000..e66fba251 --- /dev/null +++ b/riscv-isac/docs/source/_templates/versions.html @@ -0,0 +1,25 @@ +{# Add rst-badge after rst-versions for small badge style. #} +
    + + RISC-V ISA Coverage + v: {{ current_version }} + + +
    +
    +
    {{ _('Release Versions') }}
    + {% for slug, url in versions %} +
    {{ slug }}
    + {% endfor %} +
    +
    +
    {{ _('Quick Links') }}
    +
    + Project Home +
    +
    + Releases +
    +
    +
    +
    diff --git a/riscv-isac/docs/source/add_instr.rst b/riscv-isac/docs/source/add_instr.rst new file mode 100644 index 000000000..f4781a73e --- /dev/null +++ b/riscv-isac/docs/source/add_instr.rst @@ -0,0 +1,40 @@ +.. _add_instr: + +################################### +Adding Support for new Instructions +################################### + +This section details the steps for adding support for new instructions in the native python plugins +of RISCV-ISAC. + +.. note:: An alternative is to add support for the new instructions using the ``riscv/riscv-opcodes`` repository. Refer :here:`rvopcodes` for further information. + +Update the Parser-Module +======================== + +The first step is to update the parser-module to be able to deduce the relevant fields of the new +instruction and create the required :meth:`~riscv_isac.parsers.instructionObject`. + +As part of this phase, the contributor will first have to add a function(s) which will decode the +instruction hexadecimal encoding and extract the parameters of the :meth:`~riscv_isac.parsers.instructionObject`. +Make sure to follow the same code structure as used by other functions in module. + +Currently the top level function that get's called by the coverage module is the +:meth:`~riscv_isac.parsers.parseInstruction` function. This function based on the `instruction length +encoding` scheme defined by the RISC-V ISA spec identifies the length of the instruction. If the +instruction is compressed then the :meth:`~riscv_isac.parsers.parseCompressedInstruction` function +is called, else the :meth:`~riscv_isac.parsers.parseInstruction` function is called. + +If the new instruction(s) being added belong to the non-compressed opcodes, then the particular +entry in :meth:`~riscv_isac.parsers.OPCODES` needs to be updated to point to the new function(s) +defined earlier. If there are instructions falling into the compressed op-code space then the +functions :meth:`~riscv_isac.parsers.quad0`, :meth:`~riscv_isac.parsers.quad1` or :meth:`~riscv_isac.parsers.quad2` +will need to be updated accordingly. + +Update the Architectural +======================== + +The coverage module maintains its own architectural state : integer register file, program counter, +floating point register file, etc. If the new instruction(s) requires an additional architectural +state, then that needs to be added in :meth:`~riscv_isac.coverage.archStats` and the usage needs to +be updated in :meth:`~riscv_isac.coverage.compute_per_line`. diff --git a/riscv-isac/docs/source/cgf.rst b/riscv-isac/docs/source/cgf.rst new file mode 100644 index 000000000..07d745143 --- /dev/null +++ b/riscv-isac/docs/source/cgf.rst @@ -0,0 +1,770 @@ +.. See LICENSE.incore for details + +.. _cgf: + +================= +CGF Specification +================= + +A cgf file is a file which is written in the *yaml* format. The higher level node type in a cgf file is a dictionary. + +Covergroup +========== +A covergroup is a dictionary based on the following template. These dictionaries constitute the nodes in a cgf file. Each cover group contains the following type of coverpoints: + +* Mnemonics (Used in conjunction with a `base_op` and a condtion `p_op_cond` node to describe a pseudo-instruction) +* Register +* Register Operand Combinations +* Register/Immediate Value Combinations +* Control and Status Registers Value Combinations +* Cross coverage nodes + +Template +-------- + +The template for defining a non pseudo-op covergroup is as follows: + +.. code-block:: yaml + +