aboutsummaryrefslogtreecommitdiff
path: root/riscv/insns
diff options
context:
space:
mode:
authorChunPing Chung <cpchung@pllab.cs.nthu.edu.tw>2021-05-11 14:15:45 +0800
committerGitHub <noreply@github.com>2021-05-10 23:15:45 -0700
commit0981d396bca516a2b17db4cf744b8463b210c4cc (patch)
tree8a10e57b5fc3696ef2acf6c9ba7a31ed9f8d371b /riscv/insns
parent71acc77173587155e4f2e62e3372abab889803aa (diff)
downloadriscv-isa-sim-0981d396bca516a2b17db4cf744b8463b210c4cc.zip
riscv-isa-sim-0981d396bca516a2b17db4cf744b8463b210c4cc.tar.gz
riscv-isa-sim-0981d396bca516a2b17db4cf744b8463b210c4cc.tar.bz2
Support RISC-V p-ext-proposal v0.9.2 (#637)
* rvp: add 8/16 bits add/sub simd instructions * rvp: add 8/16 bits shift simd instructions * rvp: add 8/16 bits compare simd instructions * rvp: add 8/16 bits multiply simd instructions * rvp: add 8/16 bits misc simd instructions * rvp: add 8 bits unpacking simd instructions * rvp: update suppported extention and add restriction * rvp: update encoding.h and riscv.mk.in * rvp: disasm: add simd instruction support * rvp: update readme for p-ext simd instructions * rvp: fix rvp support version * rvp: update encoding.h generated from riscv-opcode p-ext branch * rvp: rename some macro argument * rvp: add pk[bb,bt,tt,tb][16,32] instructions * rvp: add kadd32, [su]maqa[_su] instructions * rvp: fix missing initial value of pd * rvp: add msw 32x32 multiply & add instructions * rvp: change to use extract64 * rvp: add msw 32x16 multiply & add instructions * rvp: fix some style * rvp: change reduction marcro definition * rvp: add signed 16x32 add/subtract instructions * rvp: use stdint to replace hardcode max/minimum * rvp: refactor some p-ext macro code * rvp: add partial simd miscellaneous instructions * rvp: add signed 16 x 64 add/subtract Instructions * rvp: add 64-bit add & sub instructions * rvp: add 32-bit mul with 64-bit add/sub instructions * rvp: add 16-bit mul with 64-bit add/sub instructions * rvp: disasm: add 64 bit profile instruction support * rvp: add Q15 saturation instructions * rvp: fix kmar64/kmsr64 saturation behavior * rvp: add 32-bit computation instructions * rvp: add rdov/clrov and fix khm16 behavior of setting OV flag * rvp: add non simd miscellaneous instructions * rvp: add Q31 saturation instructions * rvp: disasm: add non-simd instruction support * rvp: add 32 bits add/sub simd instructions * rvp: fix left shift saturation bug * rvp: add 32 bits shift simd instructions * rvp: add rv64 only Q15 simd instructions * rvp: add rv64 only 32-bit multiply instructions * rvp: add rv64 only 32-bit miscellaneous instructions * rvp: add rv64 only 32-bit mul & add instructions * rvp: add rv64 only 32-bit parallel mul & add instructions * rvp: add rv64 only non-simd 32-bit shift instructions * rvp: disasm: remove redundant tab * rvp: disasm: add rv64 only instructions support * rvp: change ov csr to ucode to match v0.5.2 spec * rvp: update readme for p-ext 0.5.2 * rvp: update to p-ext v0.9.1 * rvp: update to p-ext v0.9.2 * rvp: update readme for p-ext 0.9.2 * rvp: fix macro for PKxx16 & PKxx32 commands. * rvp: fix missing for in PKxxdd macro * Sign-extension for p-ext insns * * Fixed uclipNN insns while sh >> 64 is an UB. * Added missing OV * Added missing sext_xlen * Remove unused macroses * Sign extension for RD_PAIR macro * rvp: remove lost tab Co-authored-by: Mark Fedorov <mark.fedorov@cloudbear.ru>
Diffstat (limited to 'riscv/insns')
-rw-r--r--riscv/insns/add16.h3
-rw-r--r--riscv/insns/add32.h4
-rw-r--r--riscv/insns/add64.h3
-rw-r--r--riscv/insns/add8.h3
-rw-r--r--riscv/insns/ave.h5
-rw-r--r--riscv/insns/bitrev.h12
-rw-r--r--riscv/insns/bitrevi.h12
-rw-r--r--riscv/insns/bpick.h6
-rw-r--r--riscv/insns/clo16.h11
-rw-r--r--riscv/insns/clo32.h12
-rw-r--r--riscv/insns/clo8.h10
-rw-r--r--riscv/insns/clrs16.h12
-rw-r--r--riscv/insns/clrs32.h13
-rw-r--r--riscv/insns/clrs8.h11
-rw-r--r--riscv/insns/clz16.h10
-rw-r--r--riscv/insns/clz32.h11
-rw-r--r--riscv/insns/clz8.h9
-rw-r--r--riscv/insns/cmpeq16.h3
-rw-r--r--riscv/insns/cmpeq8.h3
-rw-r--r--riscv/insns/cras16.h5
-rw-r--r--riscv/insns/cras32.h6
-rw-r--r--riscv/insns/crsa16.h5
-rw-r--r--riscv/insns/crsa32.h6
-rw-r--r--riscv/insns/insb.h3
-rw-r--r--riscv/insns/kabs16.h9
-rw-r--r--riscv/insns/kabs32.h9
-rw-r--r--riscv/insns/kabs8.h9
-rw-r--r--riscv/insns/kabsw.h9
-rw-r--r--riscv/insns/kadd16.h5
-rw-r--r--riscv/insns/kadd32.h6
-rw-r--r--riscv/insns/kadd64.h5
-rw-r--r--riscv/insns/kadd8.h5
-rw-r--r--riscv/insns/kaddh.h4
-rw-r--r--riscv/insns/kaddw.h4
-rw-r--r--riscv/insns/kcras16.h9
-rw-r--r--riscv/insns/kcras32.h10
-rw-r--r--riscv/insns/kcrsa16.h9
-rw-r--r--riscv/insns/kcrsa32.h10
-rw-r--r--riscv/insns/kdmabb.h16
-rw-r--r--riscv/insns/kdmabb16.h17
-rw-r--r--riscv/insns/kdmabt.h16
-rw-r--r--riscv/insns/kdmabt16.h17
-rw-r--r--riscv/insns/kdmatt.h16
-rw-r--r--riscv/insns/kdmatt16.h17
-rw-r--r--riscv/insns/kdmbb.h12
-rw-r--r--riscv/insns/kdmbb16.h12
-rw-r--r--riscv/insns/kdmbt.h12
-rw-r--r--riscv/insns/kdmbt16.h12
-rw-r--r--riscv/insns/kdmtt.h12
-rw-r--r--riscv/insns/kdmtt16.h12
-rw-r--r--riscv/insns/khm16.h8
-rw-r--r--riscv/insns/khm8.h8
-rw-r--r--riscv/insns/khmbb.h12
-rw-r--r--riscv/insns/khmbb16.h13
-rw-r--r--riscv/insns/khmbt.h12
-rw-r--r--riscv/insns/khmbt16.h13
-rw-r--r--riscv/insns/khmtt.h12
-rw-r--r--riscv/insns/khmtt16.h13
-rw-r--r--riscv/insns/khmx16.h8
-rw-r--r--riscv/insns/khmx8.h8
-rw-r--r--riscv/insns/kmabb.h6
-rw-r--r--riscv/insns/kmabb32.h7
-rw-r--r--riscv/insns/kmabt.h6
-rw-r--r--riscv/insns/kmabt32.h7
-rw-r--r--riscv/insns/kmada.h3
-rw-r--r--riscv/insns/kmadrs.h6
-rw-r--r--riscv/insns/kmadrs32.h9
-rw-r--r--riscv/insns/kmads.h6
-rw-r--r--riscv/insns/kmads32.h9
-rw-r--r--riscv/insns/kmar64.h15
-rw-r--r--riscv/insns/kmatt.h6
-rw-r--r--riscv/insns/kmatt32.h7
-rw-r--r--riscv/insns/kmaxda.h3
-rw-r--r--riscv/insns/kmaxda32.h9
-rw-r--r--riscv/insns/kmaxds.h6
-rw-r--r--riscv/insns/kmaxds32.h9
-rw-r--r--riscv/insns/kmda.h3
-rw-r--r--riscv/insns/kmda32.h9
-rw-r--r--riscv/insns/kmmac.h6
-rw-r--r--riscv/insns/kmmac_u.h7
-rw-r--r--riscv/insns/kmmawb.h6
-rw-r--r--riscv/insns/kmmawb2.h14
-rw-r--r--riscv/insns/kmmawb2_u.h14
-rw-r--r--riscv/insns/kmmawb_u.h7
-rw-r--r--riscv/insns/kmmawt.h6
-rw-r--r--riscv/insns/kmmawt2.h14
-rw-r--r--riscv/insns/kmmawt2_u.h14
-rw-r--r--riscv/insns/kmmawt_u.h7
-rw-r--r--riscv/insns/kmmsb.h6
-rw-r--r--riscv/insns/kmmsb_u.h7
-rw-r--r--riscv/insns/kmmwb2.h9
-rw-r--r--riscv/insns/kmmwb2_u.h9
-rw-r--r--riscv/insns/kmmwt2.h9
-rw-r--r--riscv/insns/kmmwt2_u.h9
-rw-r--r--riscv/insns/kmsda.h3
-rw-r--r--riscv/insns/kmsda32.h9
-rw-r--r--riscv/insns/kmsr64.h25
-rw-r--r--riscv/insns/kmsxda.h3
-rw-r--r--riscv/insns/kmsxda32.h9
-rw-r--r--riscv/insns/kmxda.h3
-rw-r--r--riscv/insns/kmxda32.h9
-rw-r--r--riscv/insns/ksll16.h5
-rw-r--r--riscv/insns/ksll32.h6
-rw-r--r--riscv/insns/ksll8.h5
-rw-r--r--riscv/insns/kslli16.h5
-rw-r--r--riscv/insns/kslli32.h6
-rw-r--r--riscv/insns/kslli8.h5
-rw-r--r--riscv/insns/kslliw.h7
-rw-r--r--riscv/insns/ksllw.h7
-rw-r--r--riscv/insns/kslra16.h11
-rw-r--r--riscv/insns/kslra16_u.h14
-rw-r--r--riscv/insns/kslra32.h12
-rw-r--r--riscv/insns/kslra32_u.h15
-rw-r--r--riscv/insns/kslra8.h11
-rw-r--r--riscv/insns/kslra8_u.h14
-rw-r--r--riscv/insns/kslraw.h13
-rw-r--r--riscv/insns/kslraw_u.h13
-rw-r--r--riscv/insns/kstas16.h9
-rw-r--r--riscv/insns/kstas32.h10
-rw-r--r--riscv/insns/kstsa16.h9
-rw-r--r--riscv/insns/kstsa32.h10
-rw-r--r--riscv/insns/ksub16.h5
-rw-r--r--riscv/insns/ksub32.h6
-rw-r--r--riscv/insns/ksub64.h5
-rw-r--r--riscv/insns/ksub8.h5
-rw-r--r--riscv/insns/ksubh.h4
-rw-r--r--riscv/insns/ksubw.h4
-rw-r--r--riscv/insns/kwmmul.h9
-rw-r--r--riscv/insns/kwmmul_u.h9
-rw-r--r--riscv/insns/maddr32.h5
-rw-r--r--riscv/insns/maxw.h4
-rw-r--r--riscv/insns/minw.h4
-rw-r--r--riscv/insns/msubr32.h5
-rw-r--r--riscv/insns/mulr64.h3
-rw-r--r--riscv/insns/mulsr64.h3
-rw-r--r--riscv/insns/pbsad.h3
-rw-r--r--riscv/insns/pbsada.h3
-rw-r--r--riscv/insns/pkbb16.h1
-rw-r--r--riscv/insns/pkbb32.h2
-rw-r--r--riscv/insns/pkbt16.h1
-rw-r--r--riscv/insns/pkbt32.h2
-rw-r--r--riscv/insns/pktb16.h1
-rw-r--r--riscv/insns/pktb32.h2
-rw-r--r--riscv/insns/pktt16.h1
-rw-r--r--riscv/insns/pktt32.h2
-rw-r--r--riscv/insns/radd16.h3
-rw-r--r--riscv/insns/radd32.h4
-rw-r--r--riscv/insns/radd64.h8
-rw-r--r--riscv/insns/radd8.h3
-rw-r--r--riscv/insns/raddw.h4
-rw-r--r--riscv/insns/rcras16.h5
-rw-r--r--riscv/insns/rcras32.h6
-rw-r--r--riscv/insns/rcrsa16.h5
-rw-r--r--riscv/insns/rcrsa32.h6
-rw-r--r--riscv/insns/rstas16.h5
-rw-r--r--riscv/insns/rstas32.h6
-rw-r--r--riscv/insns/rstsa16.h5
-rw-r--r--riscv/insns/rstsa32.h6
-rw-r--r--riscv/insns/rsub16.h3
-rw-r--r--riscv/insns/rsub32.h4
-rw-r--r--riscv/insns/rsub64.h8
-rw-r--r--riscv/insns/rsub8.h3
-rw-r--r--riscv/insns/rsubw.h4
-rw-r--r--riscv/insns/sclip16.h13
-rw-r--r--riscv/insns/sclip32.h13
-rw-r--r--riscv/insns/sclip8.h13
-rw-r--r--riscv/insns/scmple16.h3
-rw-r--r--riscv/insns/scmple8.h3
-rw-r--r--riscv/insns/scmplt16.h3
-rw-r--r--riscv/insns/scmplt8.h3
-rw-r--r--riscv/insns/sll16.h3
-rw-r--r--riscv/insns/sll32.h4
-rw-r--r--riscv/insns/sll8.h3
-rw-r--r--riscv/insns/slli16.h3
-rw-r--r--riscv/insns/slli32.h4
-rw-r--r--riscv/insns/slli8.h3
-rw-r--r--riscv/insns/smal.h10
-rw-r--r--riscv/insns/smalbb.h3
-rw-r--r--riscv/insns/smalbt.h3
-rw-r--r--riscv/insns/smalda.h3
-rw-r--r--riscv/insns/smaldrs.h7
-rw-r--r--riscv/insns/smalds.h7
-rw-r--r--riscv/insns/smaltt.h3
-rw-r--r--riscv/insns/smalxda.h4
-rw-r--r--riscv/insns/smalxds.h4
-rw-r--r--riscv/insns/smaqa.h3
-rw-r--r--riscv/insns/smaqa_su.h3
-rw-r--r--riscv/insns/smar64.h3
-rw-r--r--riscv/insns/smax16.h3
-rw-r--r--riscv/insns/smax32.h3
-rw-r--r--riscv/insns/smax8.h3
-rw-r--r--riscv/insns/smbb16.h3
-rw-r--r--riscv/insns/smbt16.h3
-rw-r--r--riscv/insns/smbt32.h3
-rw-r--r--riscv/insns/smdrs.h6
-rw-r--r--riscv/insns/smdrs32.h7
-rw-r--r--riscv/insns/smds.h6
-rw-r--r--riscv/insns/smds32.h7
-rw-r--r--riscv/insns/smin16.h3
-rw-r--r--riscv/insns/smin32.h3
-rw-r--r--riscv/insns/smin8.h3
-rw-r--r--riscv/insns/smmul.h4
-rw-r--r--riscv/insns/smmul_u.h4
-rw-r--r--riscv/insns/smmwb.h4
-rw-r--r--riscv/insns/smmwb_u.h4
-rw-r--r--riscv/insns/smmwt.h4
-rw-r--r--riscv/insns/smmwt_u.h4
-rw-r--r--riscv/insns/smslda.h3
-rw-r--r--riscv/insns/smslxda.h4
-rw-r--r--riscv/insns/smsr64.h3
-rw-r--r--riscv/insns/smtt16.h3
-rw-r--r--riscv/insns/smtt32.h3
-rw-r--r--riscv/insns/smul16.h3
-rw-r--r--riscv/insns/smul8.h3
-rw-r--r--riscv/insns/smulx16.h3
-rw-r--r--riscv/insns/smulx8.h3
-rw-r--r--riscv/insns/smxds.h6
-rw-r--r--riscv/insns/smxds32.h7
-rw-r--r--riscv/insns/sra16.h3
-rw-r--r--riscv/insns/sra16_u.h6
-rw-r--r--riscv/insns/sra32.h4
-rw-r--r--riscv/insns/sra32_u.h7
-rw-r--r--riscv/insns/sra8.h3
-rw-r--r--riscv/insns/sra8_u.h6
-rw-r--r--riscv/insns/sra_u.h9
-rw-r--r--riscv/insns/srai16.h3
-rw-r--r--riscv/insns/srai16_u.h6
-rw-r--r--riscv/insns/srai32.h4
-rw-r--r--riscv/insns/srai32_u.h7
-rw-r--r--riscv/insns/srai8.h3
-rw-r--r--riscv/insns/srai8_u.h6
-rw-r--r--riscv/insns/srai_u.h9
-rw-r--r--riscv/insns/sraiw_u.h9
-rw-r--r--riscv/insns/srl16.h3
-rw-r--r--riscv/insns/srl16_u.h7
-rw-r--r--riscv/insns/srl32.h4
-rw-r--r--riscv/insns/srl32_u.h8
-rw-r--r--riscv/insns/srl8.h3
-rw-r--r--riscv/insns/srl8_u.h7
-rw-r--r--riscv/insns/srli16.h3
-rw-r--r--riscv/insns/srli16_u.h7
-rw-r--r--riscv/insns/srli32.h4
-rw-r--r--riscv/insns/srli32_u.h8
-rw-r--r--riscv/insns/srli8.h3
-rw-r--r--riscv/insns/srli8_u.h7
-rw-r--r--riscv/insns/stas16.h5
-rw-r--r--riscv/insns/stas32.h6
-rw-r--r--riscv/insns/stsa16.h5
-rw-r--r--riscv/insns/stsa32.h6
-rw-r--r--riscv/insns/sub16.h3
-rw-r--r--riscv/insns/sub32.h4
-rw-r--r--riscv/insns/sub64.h3
-rw-r--r--riscv/insns/sub8.h3
-rw-r--r--riscv/insns/sunpkd810.h1
-rw-r--r--riscv/insns/sunpkd820.h1
-rw-r--r--riscv/insns/sunpkd830.h1
-rw-r--r--riscv/insns/sunpkd831.h1
-rw-r--r--riscv/insns/sunpkd832.h1
-rw-r--r--riscv/insns/swap16.h4
-rw-r--r--riscv/insns/swap8.h4
-rw-r--r--riscv/insns/uclip16.h12
-rw-r--r--riscv/insns/uclip32.h12
-rw-r--r--riscv/insns/uclip8.h12
-rw-r--r--riscv/insns/ucmple16.h3
-rw-r--r--riscv/insns/ucmple8.h3
-rw-r--r--riscv/insns/ucmplt16.h3
-rw-r--r--riscv/insns/ucmplt8.h3
-rw-r--r--riscv/insns/ukadd16.h5
-rw-r--r--riscv/insns/ukadd32.h6
-rw-r--r--riscv/insns/ukadd64.h5
-rw-r--r--riscv/insns/ukadd8.h5
-rw-r--r--riscv/insns/ukaddh.h4
-rw-r--r--riscv/insns/ukaddw.h4
-rw-r--r--riscv/insns/ukcras16.h9
-rw-r--r--riscv/insns/ukcras32.h10
-rw-r--r--riscv/insns/ukcrsa16.h9
-rw-r--r--riscv/insns/ukcrsa32.h10
-rw-r--r--riscv/insns/ukmar64.h5
-rw-r--r--riscv/insns/ukmsr64.h5
-rw-r--r--riscv/insns/ukstas16.h9
-rw-r--r--riscv/insns/ukstas32.h10
-rw-r--r--riscv/insns/ukstsa16.h9
-rw-r--r--riscv/insns/ukstsa32.h10
-rw-r--r--riscv/insns/uksub16.h5
-rw-r--r--riscv/insns/uksub32.h6
-rw-r--r--riscv/insns/uksub64.h5
-rw-r--r--riscv/insns/uksub8.h5
-rw-r--r--riscv/insns/uksubh.h4
-rw-r--r--riscv/insns/uksubw.h4
-rw-r--r--riscv/insns/umaqa.h3
-rw-r--r--riscv/insns/umar64.h3
-rw-r--r--riscv/insns/umax16.h3
-rw-r--r--riscv/insns/umax32.h3
-rw-r--r--riscv/insns/umax8.h3
-rw-r--r--riscv/insns/umin16.h3
-rw-r--r--riscv/insns/umin32.h3
-rw-r--r--riscv/insns/umin8.h3
-rw-r--r--riscv/insns/umsr64.h3
-rw-r--r--riscv/insns/umul16.h3
-rw-r--r--riscv/insns/umul8.h3
-rw-r--r--riscv/insns/umulx16.h3
-rw-r--r--riscv/insns/umulx8.h3
-rw-r--r--riscv/insns/uradd16.h3
-rw-r--r--riscv/insns/uradd32.h4
-rw-r--r--riscv/insns/uradd64.h9
-rw-r--r--riscv/insns/uradd8.h3
-rw-r--r--riscv/insns/uraddw.h4
-rw-r--r--riscv/insns/urcras16.h5
-rw-r--r--riscv/insns/urcras32.h6
-rw-r--r--riscv/insns/urcrsa16.h5
-rw-r--r--riscv/insns/urcrsa32.h6
-rw-r--r--riscv/insns/urstas16.h5
-rw-r--r--riscv/insns/urstas32.h6
-rw-r--r--riscv/insns/urstsa16.h5
-rw-r--r--riscv/insns/urstsa32.h6
-rw-r--r--riscv/insns/ursub16.h3
-rw-r--r--riscv/insns/ursub32.h4
-rw-r--r--riscv/insns/ursub64.h9
-rw-r--r--riscv/insns/ursub8.h3
-rw-r--r--riscv/insns/ursubw.h4
-rw-r--r--riscv/insns/wext.h4
-rw-r--r--riscv/insns/wexti.h4
-rw-r--r--riscv/insns/zunpkd810.h1
-rw-r--r--riscv/insns/zunpkd820.h1
-rw-r--r--riscv/insns/zunpkd830.h1
-rw-r--r--riscv/insns/zunpkd831.h1
-rw-r--r--riscv/insns/zunpkd832.h1
327 files changed, 2027 insertions, 0 deletions
diff --git a/riscv/insns/add16.h b/riscv/insns/add16.h
new file mode 100644
index 0000000..53b6be8
--- /dev/null
+++ b/riscv/insns/add16.h
@@ -0,0 +1,3 @@
+P_LOOP(16, {
+ pd = ps1 + ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/add32.h b/riscv/insns/add32.h
new file mode 100644
index 0000000..7fe7c96
--- /dev/null
+++ b/riscv/insns/add32.h
@@ -0,0 +1,4 @@
+require_rv64;
+P_LOOP(32, {
+ pd = ps1 + ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/add64.h b/riscv/insns/add64.h
new file mode 100644
index 0000000..eb076b2
--- /dev/null
+++ b/riscv/insns/add64.h
@@ -0,0 +1,3 @@
+P_64_PROFILE({
+ rd = rs1 + rs2;
+}) \ No newline at end of file
diff --git a/riscv/insns/add8.h b/riscv/insns/add8.h
new file mode 100644
index 0000000..e5e1cb0
--- /dev/null
+++ b/riscv/insns/add8.h
@@ -0,0 +1,3 @@
+P_LOOP(8, {
+ pd = ps1 + ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/ave.h b/riscv/insns/ave.h
new file mode 100644
index 0000000..15bf863
--- /dev/null
+++ b/riscv/insns/ave.h
@@ -0,0 +1,5 @@
+require_extension('P');
+sreg_t rs1 = RS1;
+sreg_t rs2 = RS2;
+sreg_t carry = (rs1 & 1) | (rs2 & 1);
+WRITE_RD(sext_xlen((rs1 >> 1) + (rs2 >> 1) + carry)); \ No newline at end of file
diff --git a/riscv/insns/bitrev.h b/riscv/insns/bitrev.h
new file mode 100644
index 0000000..939f5a4
--- /dev/null
+++ b/riscv/insns/bitrev.h
@@ -0,0 +1,12 @@
+require_extension('P');
+reg_t msb = get_field(RS2, make_mask64(0, xlen == 32 ? 5 : 6));
+reg_t n = get_field(RS1, make_mask64(0, msb + 1));
+reg_t rev = 0;
+
+for (size_t i = 0; i <= msb; i++) {
+ rev <<= 1;
+ rev |= n & 1;
+ n >>= 1;
+}
+
+WRITE_RD(sext_xlen(rev)); \ No newline at end of file
diff --git a/riscv/insns/bitrevi.h b/riscv/insns/bitrevi.h
new file mode 100644
index 0000000..5350e6b
--- /dev/null
+++ b/riscv/insns/bitrevi.h
@@ -0,0 +1,12 @@
+require_extension('P');
+reg_t msb = xlen == 32 ? insn.p_imm5() : insn.p_imm6();
+reg_t n = get_field(RS1, make_mask64(0, msb + 1));
+reg_t rev = 0;
+
+for (size_t i = 0; i <= msb; i++) {
+ rev <<= 1;
+ rev |= n & 1;
+ n >>= 1;
+}
+
+WRITE_RD(sext_xlen(rev)); \ No newline at end of file
diff --git a/riscv/insns/bpick.h b/riscv/insns/bpick.h
new file mode 100644
index 0000000..fc83086
--- /dev/null
+++ b/riscv/insns/bpick.h
@@ -0,0 +1,6 @@
+require_extension('P');
+reg_t rc = RS3;
+reg_t rs1 = RS1;
+reg_t rs2 = RS2;
+
+WRITE_RD(sext_xlen((rs1 & rc) | (rs2 & ~rc))); \ No newline at end of file
diff --git a/riscv/insns/clo16.h b/riscv/insns/clo16.h
new file mode 100644
index 0000000..cc714ac
--- /dev/null
+++ b/riscv/insns/clo16.h
@@ -0,0 +1,11 @@
+P_ONE_LOOP(16, {
+ pd = 0;
+ ps1 = ~ps1;
+ if (!ps1) pd = 16;
+ else {
+ if ((ps1 & 0xFF00) == 0) { pd += 8; ps1 <<= 8; }
+ if ((ps1 & 0xF000) == 0) { pd += 4; ps1 <<= 4; }
+ if ((ps1 & 0xC000) == 0) { pd += 2; ps1 <<= 2; }
+ if ((ps1 & 0x8000) == 0) { pd += 1; }
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/clo32.h b/riscv/insns/clo32.h
new file mode 100644
index 0000000..2f81a25
--- /dev/null
+++ b/riscv/insns/clo32.h
@@ -0,0 +1,12 @@
+P_ONE_LOOP(32, {
+ pd = 0;
+ ps1 = ~ps1;
+ if (!ps1) pd = 32;
+ else {
+ if ((ps1 & 0xFFFF0000) == 0) { pd += 16; ps1 <<= 16; }
+ if ((ps1 & 0xFF000000) == 0) { pd += 8; ps1 <<= 8; }
+ if ((ps1 & 0xF0000000) == 0) { pd += 4; ps1 <<= 4; }
+ if ((ps1 & 0xC0000000) == 0) { pd += 2; ps1 <<= 2; }
+ if ((ps1 & 0x80000000) == 0) { pd += 1; }
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/clo8.h b/riscv/insns/clo8.h
new file mode 100644
index 0000000..1009b39
--- /dev/null
+++ b/riscv/insns/clo8.h
@@ -0,0 +1,10 @@
+P_ONE_LOOP(8, {
+ pd = 0;
+ ps1 = ~ps1;
+ if (!ps1) pd = 8;
+ else {
+ if ((ps1 & 0xF0) == 0) { pd += 4; ps1 <<= 4; }
+ if ((ps1 & 0xC0) == 0) { pd += 2; ps1 <<= 2; }
+ if ((ps1 & 0x80) == 0) { pd += 1; }
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/clrs16.h b/riscv/insns/clrs16.h
new file mode 100644
index 0000000..c9362a6
--- /dev/null
+++ b/riscv/insns/clrs16.h
@@ -0,0 +1,12 @@
+P_ONE_LOOP(16, {
+ pd = 0;
+ if (ps1 < 0) ps1 = ~ps1;
+ if (!ps1) pd = 16;
+ else {
+ if ((ps1 & 0xFF00) == 0) { pd += 8; ps1 <<= 8; }
+ if ((ps1 & 0xF000) == 0) { pd += 4; ps1 <<= 4; }
+ if ((ps1 & 0xC000) == 0) { pd += 2; ps1 <<= 2; }
+ if ((ps1 & 0x8000) == 0) { pd += 1; }
+ }
+ pd -= 1;
+}) \ No newline at end of file
diff --git a/riscv/insns/clrs32.h b/riscv/insns/clrs32.h
new file mode 100644
index 0000000..55fc4f3
--- /dev/null
+++ b/riscv/insns/clrs32.h
@@ -0,0 +1,13 @@
+P_ONE_LOOP(32, {
+ pd = 0;
+ if (ps1 < 0) ps1 = ~ps1;
+ if (!ps1) pd = 32;
+ else {
+ if ((ps1 & 0xFFFF0000) == 0) { pd += 16; ps1 <<= 16; }
+ if ((ps1 & 0xFF000000) == 0) { pd += 8; ps1 <<= 8; }
+ if ((ps1 & 0xF0000000) == 0) { pd += 4; ps1 <<= 4; }
+ if ((ps1 & 0xC0000000) == 0) { pd += 2; ps1 <<= 2; }
+ if ((ps1 & 0x80000000) == 0) { pd += 1; }
+ }
+ pd -= 1;
+}) \ No newline at end of file
diff --git a/riscv/insns/clrs8.h b/riscv/insns/clrs8.h
new file mode 100644
index 0000000..071982c
--- /dev/null
+++ b/riscv/insns/clrs8.h
@@ -0,0 +1,11 @@
+P_ONE_LOOP(8, {
+ pd = 0;
+ if (ps1 < 0) ps1 = ~ps1;
+ if (!ps1) pd = 8;
+ else {
+ if ((ps1 & 0xF0) == 0) { pd += 4; ps1 <<= 4; }
+ if ((ps1 & 0xC0) == 0) { pd += 2; ps1 <<= 2; }
+ if ((ps1 & 0x80) == 0) { pd += 1; }
+ }
+ pd -= 1;
+}) \ No newline at end of file
diff --git a/riscv/insns/clz16.h b/riscv/insns/clz16.h
new file mode 100644
index 0000000..e4e5601
--- /dev/null
+++ b/riscv/insns/clz16.h
@@ -0,0 +1,10 @@
+P_ONE_LOOP(16, {
+ pd = 0;
+ if (ps1 == 0) pd = 16;
+ else {
+ if ((ps1 & 0xFF00) == 0) { pd += 8; ps1 <<= 8; }
+ if ((ps1 & 0xF000) == 0) { pd += 4; ps1 <<= 4; }
+ if ((ps1 & 0xC000) == 0) { pd += 2; ps1 <<= 2; }
+ if ((ps1 & 0x8000) == 0) { pd += 1; }
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/clz32.h b/riscv/insns/clz32.h
new file mode 100644
index 0000000..0c36cd2
--- /dev/null
+++ b/riscv/insns/clz32.h
@@ -0,0 +1,11 @@
+P_ONE_LOOP(32, {
+ pd = 0;
+ if (ps1 == 0) pd = 32;
+ else {
+ if ((ps1 & 0xFFFF0000) == 0) { pd += 16; ps1 <<= 16; }
+ if ((ps1 & 0xFF000000) == 0) { pd += 8; ps1 <<= 8; }
+ if ((ps1 & 0xF0000000) == 0) { pd += 4; ps1 <<= 4; }
+ if ((ps1 & 0xC0000000) == 0) { pd += 2; ps1 <<= 2; }
+ if ((ps1 & 0x80000000) == 0) { pd += 1; }
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/clz8.h b/riscv/insns/clz8.h
new file mode 100644
index 0000000..4e56b24
--- /dev/null
+++ b/riscv/insns/clz8.h
@@ -0,0 +1,9 @@
+P_ONE_LOOP(8, {
+ pd = 0;
+ if (ps1 == 0) pd = 8;
+ else {
+ if ((ps1 & 0xF0) == 0) { pd += 4; ps1 <<= 4; }
+ if ((ps1 & 0xC0) == 0) { pd += 2; ps1 <<= 2; }
+ if ((ps1 & 0x80) == 0) { pd += 1; }
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/cmpeq16.h b/riscv/insns/cmpeq16.h
new file mode 100644
index 0000000..75c0c98
--- /dev/null
+++ b/riscv/insns/cmpeq16.h
@@ -0,0 +1,3 @@
+P_LOOP(16, {
+ pd = (ps1 == ps2) ? -1 : 0;
+}) \ No newline at end of file
diff --git a/riscv/insns/cmpeq8.h b/riscv/insns/cmpeq8.h
new file mode 100644
index 0000000..f282a55
--- /dev/null
+++ b/riscv/insns/cmpeq8.h
@@ -0,0 +1,3 @@
+P_LOOP(8, {
+ pd = (ps1 == ps2) ? -1 : 0;
+}) \ No newline at end of file
diff --git a/riscv/insns/cras16.h b/riscv/insns/cras16.h
new file mode 100644
index 0000000..4392edf
--- /dev/null
+++ b/riscv/insns/cras16.h
@@ -0,0 +1,5 @@
+P_CROSS_LOOP(16, {
+ pd = ps1 + ps2;
+}, {
+ pd = ps1 - ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/cras32.h b/riscv/insns/cras32.h
new file mode 100644
index 0000000..0604809
--- /dev/null
+++ b/riscv/insns/cras32.h
@@ -0,0 +1,6 @@
+require_rv64;
+P_CROSS_LOOP(32, {
+ pd = ps1 + ps2;
+}, {
+ pd = ps1 - ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/crsa16.h b/riscv/insns/crsa16.h
new file mode 100644
index 0000000..7ae0ca8
--- /dev/null
+++ b/riscv/insns/crsa16.h
@@ -0,0 +1,5 @@
+P_CROSS_LOOP(16, {
+ pd = ps1 - ps2;
+}, {
+ pd = ps1 + ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/crsa32.h b/riscv/insns/crsa32.h
new file mode 100644
index 0000000..6d423a8
--- /dev/null
+++ b/riscv/insns/crsa32.h
@@ -0,0 +1,6 @@
+require_rv64;
+P_CROSS_LOOP(32, {
+ pd = (int64_t)ps1 - ps2;
+}, {
+ pd = (int64_t)ps1 + ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/insb.h b/riscv/insns/insb.h
new file mode 100644
index 0000000..199a8c6
--- /dev/null
+++ b/riscv/insns/insb.h
@@ -0,0 +1,3 @@
+require_extension('P');
+reg_t bpos = (xlen == 32) ? insn.p_imm2() : insn.p_imm3();
+WRITE_RD(sext_xlen(set_field(RD, make_mask64(bpos * 8, 8), P_B(RS1, 0)))); \ No newline at end of file
diff --git a/riscv/insns/kabs16.h b/riscv/insns/kabs16.h
new file mode 100644
index 0000000..f2b9472
--- /dev/null
+++ b/riscv/insns/kabs16.h
@@ -0,0 +1,9 @@
+P_ONE_LOOP(16, {
+ pd = ps1;
+ if (ps1 == INT16_MIN) {
+ pd = INT16_MAX;
+ P_SET_OV(1);
+ } else if (ps1 < 0) {
+ pd = - ps1;
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/kabs32.h b/riscv/insns/kabs32.h
new file mode 100644
index 0000000..796d827
--- /dev/null
+++ b/riscv/insns/kabs32.h
@@ -0,0 +1,9 @@
+P_ONE_LOOP(32, {
+ pd = ps1;
+ if (ps1 == INT32_MIN) {
+ pd = INT32_MAX;
+ P_SET_OV(1);
+ } else if (ps1 < 0) {
+ pd = - ps1;
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/kabs8.h b/riscv/insns/kabs8.h
new file mode 100644
index 0000000..51ee04d
--- /dev/null
+++ b/riscv/insns/kabs8.h
@@ -0,0 +1,9 @@
+P_ONE_LOOP(8, {
+ pd = ps1;
+ if (ps1 == INT8_MIN) {
+ pd = INT8_MAX;
+ P_SET_OV(1);
+ } else if (ps1 < 0) {
+ pd = - ps1;
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/kabsw.h b/riscv/insns/kabsw.h
new file mode 100644
index 0000000..677d51e
--- /dev/null
+++ b/riscv/insns/kabsw.h
@@ -0,0 +1,9 @@
+require_extension('P');
+int32_t rs1 = P_W(RS1, 0);
+
+if (rs1 == INT32_MIN) {
+ rs1 = INT32_MAX;
+ P_SET_OV(1);
+}
+
+WRITE_RD(sext_xlen(rs1 >= 0 ? rs1 : -rs1)); \ No newline at end of file
diff --git a/riscv/insns/kadd16.h b/riscv/insns/kadd16.h
new file mode 100644
index 0000000..b557e9a
--- /dev/null
+++ b/riscv/insns/kadd16.h
@@ -0,0 +1,5 @@
+P_LOOP(16, {
+ bool sat = false;
+ pd = (sat_add<int16_t, uint16_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/kadd32.h b/riscv/insns/kadd32.h
new file mode 100644
index 0000000..462e106
--- /dev/null
+++ b/riscv/insns/kadd32.h
@@ -0,0 +1,6 @@
+require_rv64;
+P_LOOP(32, {
+ bool sat = false;
+ pd = (sat_add<int32_t, uint32_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/kadd64.h b/riscv/insns/kadd64.h
new file mode 100644
index 0000000..e99b960
--- /dev/null
+++ b/riscv/insns/kadd64.h
@@ -0,0 +1,5 @@
+P_64_PROFILE({
+ bool sat = false;
+ rd = (sat_add<int64_t, uint64_t>(rs1, rs2, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/kadd8.h b/riscv/insns/kadd8.h
new file mode 100644
index 0000000..e004a02
--- /dev/null
+++ b/riscv/insns/kadd8.h
@@ -0,0 +1,5 @@
+P_LOOP(8, {
+ bool sat = false;
+ pd = (sat_add<int8_t, uint8_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/kaddh.h b/riscv/insns/kaddh.h
new file mode 100644
index 0000000..e81219b
--- /dev/null
+++ b/riscv/insns/kaddh.h
@@ -0,0 +1,4 @@
+require_extension('P');
+sreg_t res = (sreg_t)P_SW(RS1, 0) + (sreg_t)P_SW(RS2, 0);
+P_SAT(res, 16);
+WRITE_RD(sext_xlen((int16_t)res)); \ No newline at end of file
diff --git a/riscv/insns/kaddw.h b/riscv/insns/kaddw.h
new file mode 100644
index 0000000..9b84c09
--- /dev/null
+++ b/riscv/insns/kaddw.h
@@ -0,0 +1,4 @@
+require_extension('P');
+sreg_t res = (sreg_t)P_SW(RS1, 0) + (sreg_t)P_SW(RS2, 0);
+P_SAT(res, 32);
+WRITE_RD(sext32(res)); \ No newline at end of file
diff --git a/riscv/insns/kcras16.h b/riscv/insns/kcras16.h
new file mode 100644
index 0000000..81bba89
--- /dev/null
+++ b/riscv/insns/kcras16.h
@@ -0,0 +1,9 @@
+P_CROSS_ULOOP(16, {
+ bool sat = false;
+ pd = (sat_add<int16_t, uint16_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}, {
+ bool sat = false;
+ pd = (sat_sub<int16_t, uint16_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/kcras32.h b/riscv/insns/kcras32.h
new file mode 100644
index 0000000..92e8245
--- /dev/null
+++ b/riscv/insns/kcras32.h
@@ -0,0 +1,10 @@
+require_rv64;
+P_CROSS_ULOOP(32, {
+ bool sat = false;
+ pd = (sat_add<int32_t, uint32_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}, {
+ bool sat = false;
+ pd = (sat_sub<int32_t, uint32_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/kcrsa16.h b/riscv/insns/kcrsa16.h
new file mode 100644
index 0000000..32c80d2
--- /dev/null
+++ b/riscv/insns/kcrsa16.h
@@ -0,0 +1,9 @@
+P_CROSS_ULOOP(16, {
+ bool sat = false;
+ pd = (sat_sub<int16_t, uint16_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}, {
+ bool sat = false;
+ pd = (sat_add<int16_t, uint16_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/kcrsa32.h b/riscv/insns/kcrsa32.h
new file mode 100644
index 0000000..a23c56a
--- /dev/null
+++ b/riscv/insns/kcrsa32.h
@@ -0,0 +1,10 @@
+require_rv64;
+P_CROSS_ULOOP(32, {
+ bool sat = false;
+ pd = (sat_sub<int32_t, uint32_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}, {
+ bool sat = false;
+ pd = (sat_add<int32_t, uint32_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/kdmabb.h b/riscv/insns/kdmabb.h
new file mode 100644
index 0000000..920cfdb
--- /dev/null
+++ b/riscv/insns/kdmabb.h
@@ -0,0 +1,16 @@
+require_extension('P');
+sreg_t res;
+sreg_t aop = P_SH(RS1, 0);
+sreg_t bop = P_SH(RS2, 0);
+
+if ((INT16_MIN != aop) | (INT16_MIN != bop)) {
+ res = aop * bop;
+ res <<= 1;
+} else {
+ res = INT32_MAX;
+ P_SET_OV(1);
+}
+
+res += sext32(RD);
+P_SAT(res, 32);
+WRITE_RD(sext32(res)); \ No newline at end of file
diff --git a/riscv/insns/kdmabb16.h b/riscv/insns/kdmabb16.h
new file mode 100644
index 0000000..eed5efa
--- /dev/null
+++ b/riscv/insns/kdmabb16.h
@@ -0,0 +1,17 @@
+require_rv64;
+P_LOOP(32, {
+ int32_t aop = P_SH(ps1, 0);
+ int32_t bop = P_SH(ps2, 0);
+ int32_t mres;
+ bool sat;
+
+ if ((INT16_MIN != aop) | (INT16_MIN != bop)) {
+ mres = aop * bop;
+ mres <<= 1;
+ } else {
+ mres = INT32_MAX;
+ P_SET_OV(1);
+ }
+ pd = (sat_add<int32_t, uint32_t>(pd, mres, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/kdmabt.h b/riscv/insns/kdmabt.h
new file mode 100644
index 0000000..5281900
--- /dev/null
+++ b/riscv/insns/kdmabt.h
@@ -0,0 +1,16 @@
+require_extension('P');
+sreg_t res;
+sreg_t aop = P_SH(RS1, 0);
+sreg_t bop = P_SH(RS2, 1);
+
+if ((INT16_MIN != aop) | (INT16_MIN != bop)) {
+ res = aop * bop;
+ res <<= 1;
+} else {
+ res = INT32_MAX;
+ P_SET_OV(1);
+}
+
+res += sext32(RD);
+P_SAT(res, 32);
+WRITE_RD(sext32(res)); \ No newline at end of file
diff --git a/riscv/insns/kdmabt16.h b/riscv/insns/kdmabt16.h
new file mode 100644
index 0000000..8190186
--- /dev/null
+++ b/riscv/insns/kdmabt16.h
@@ -0,0 +1,17 @@
+require_rv64;
+P_LOOP(32, {
+ int32_t aop = P_SH(ps1, 0);
+ int32_t bop = P_SH(ps2, 1);
+ int32_t mres;
+ bool sat;
+
+ if ((INT16_MIN != aop) | (INT16_MIN != bop)) {
+ mres = aop * bop;
+ mres <<= 1;
+ } else {
+ mres = INT32_MAX;
+ P_SET_OV(1);
+ }
+ pd = (sat_add<int32_t, uint32_t>(pd, mres, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/kdmatt.h b/riscv/insns/kdmatt.h
new file mode 100644
index 0000000..2885e3a
--- /dev/null
+++ b/riscv/insns/kdmatt.h
@@ -0,0 +1,16 @@
+require_extension('P');
+sreg_t res;
+sreg_t aop = P_SH(RS1, 1);
+sreg_t bop = P_SH(RS2, 1);
+
+if ((INT16_MIN != aop) | (INT16_MIN != bop)) {
+ res = aop * bop;
+ res <<= 1;
+} else {
+ res = INT32_MAX;
+ P_SET_OV(1);
+}
+
+res += sext32(RD);
+P_SAT(res, 32);
+WRITE_RD(sext32(res)); \ No newline at end of file
diff --git a/riscv/insns/kdmatt16.h b/riscv/insns/kdmatt16.h
new file mode 100644
index 0000000..22e8a00
--- /dev/null
+++ b/riscv/insns/kdmatt16.h
@@ -0,0 +1,17 @@
+require_rv64;
+P_LOOP(32, {
+ int32_t aop = P_SH(ps1, 1);
+ int32_t bop = P_SH(ps2, 1);
+ int32_t mres;
+ bool sat;
+
+ if ((INT16_MIN != aop) | (INT16_MIN != bop)) {
+ mres = aop * bop;
+ mres <<= 1;
+ } else {
+ mres = INT32_MAX;
+ P_SET_OV(1);
+ }
+ pd = (sat_add<int32_t, uint32_t>(pd, mres, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/kdmbb.h b/riscv/insns/kdmbb.h
new file mode 100644
index 0000000..af25355
--- /dev/null
+++ b/riscv/insns/kdmbb.h
@@ -0,0 +1,12 @@
+require_extension('P');
+sreg_t res;
+sreg_t aop = P_SH(RS1, 0);
+sreg_t bop = P_SH(RS2, 0);
+if ((INT16_MIN != aop) | (INT16_MIN != bop)) {
+ res = aop * bop;
+ res <<= 1;
+} else {
+ res = INT32_MAX;
+ P_SET_OV(1);
+}
+WRITE_RD(sext32(res)); \ No newline at end of file
diff --git a/riscv/insns/kdmbb16.h b/riscv/insns/kdmbb16.h
new file mode 100644
index 0000000..1353c00
--- /dev/null
+++ b/riscv/insns/kdmbb16.h
@@ -0,0 +1,12 @@
+require_rv64;
+P_LOOP(32, {
+ int32_t aop = P_SH(ps1, 0);
+ int32_t bop = P_SH(ps2, 0);
+ if ((INT16_MIN != aop) | (INT16_MIN != bop)) {
+ pd = aop * bop;
+ pd <<= 1;
+ } else {
+ pd = INT32_MAX;
+ P_SET_OV(1);
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/kdmbt.h b/riscv/insns/kdmbt.h
new file mode 100644
index 0000000..32017ed
--- /dev/null
+++ b/riscv/insns/kdmbt.h
@@ -0,0 +1,12 @@
+require_extension('P');
+sreg_t res;
+sreg_t aop = P_SH(RS1, 0);
+sreg_t bop = P_SH(RS2, 1);
+if ((INT16_MIN != aop) | (INT16_MIN != bop)) {
+ res = aop * bop;
+ res <<= 1;
+} else {
+ res = INT32_MAX;
+ P_SET_OV(1);
+}
+WRITE_RD(sext32(res)); \ No newline at end of file
diff --git a/riscv/insns/kdmbt16.h b/riscv/insns/kdmbt16.h
new file mode 100644
index 0000000..d934330
--- /dev/null
+++ b/riscv/insns/kdmbt16.h
@@ -0,0 +1,12 @@
+require_rv64;
+P_LOOP(32, {
+ int32_t aop = P_SH(ps1, 0);
+ int32_t bop = P_SH(ps2, 1);
+ if ((INT16_MIN != aop) | (INT16_MIN != bop)) {
+ pd = aop * bop;
+ pd <<= 1;
+ } else {
+ pd = INT32_MAX;
+ P_SET_OV(1);
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/kdmtt.h b/riscv/insns/kdmtt.h
new file mode 100644
index 0000000..3851280
--- /dev/null
+++ b/riscv/insns/kdmtt.h
@@ -0,0 +1,12 @@
+require_extension('P');
+sreg_t res;
+sreg_t aop = P_SH(RS1, 1);
+sreg_t bop = P_SH(RS2, 1);
+if ((INT16_MIN != aop) | (INT16_MIN != bop)) {
+ res = aop * bop;
+ res <<= 1;
+} else {
+ res = INT32_MAX;
+ P_SET_OV(1);
+}
+WRITE_RD(sext32(res)); \ No newline at end of file
diff --git a/riscv/insns/kdmtt16.h b/riscv/insns/kdmtt16.h
new file mode 100644
index 0000000..0aed777
--- /dev/null
+++ b/riscv/insns/kdmtt16.h
@@ -0,0 +1,12 @@
+require_rv64;
+P_LOOP(32, {
+ int32_t aop = P_SH(ps1, 1);
+ int32_t bop = P_SH(ps2, 1);
+ if ((INT16_MIN != aop) | (INT16_MIN != bop)) {
+ pd = aop * bop;
+ pd <<= 1;
+ } else {
+ pd = INT32_MAX;
+ P_SET_OV(1);
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/khm16.h b/riscv/insns/khm16.h
new file mode 100644
index 0000000..4414345
--- /dev/null
+++ b/riscv/insns/khm16.h
@@ -0,0 +1,8 @@
+P_LOOP(16, {
+ if ((ps1 != INT16_MIN) | (ps2 != INT16_MIN)) {
+ pd = (ps1 * ps2) >> 15;
+ } else {
+ pd = INT16_MAX;
+ P_SET_OV(1);
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/khm8.h b/riscv/insns/khm8.h
new file mode 100644
index 0000000..aeef15c
--- /dev/null
+++ b/riscv/insns/khm8.h
@@ -0,0 +1,8 @@
+P_LOOP(8, {
+ if ((ps1 != INT8_MIN) | (ps2 != INT8_MIN)) {
+ pd = (ps1 * ps2) >> 7;
+ } else {
+ pd = INT8_MAX;
+ P_SET_OV(1);
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/khmbb.h b/riscv/insns/khmbb.h
new file mode 100644
index 0000000..6a59aa7
--- /dev/null
+++ b/riscv/insns/khmbb.h
@@ -0,0 +1,12 @@
+require_extension('P');
+sreg_t res;
+sreg_t aop = P_SH(RS1, 0);
+sreg_t bop = P_SH(RS2, 0);
+if ((INT16_MIN != aop) | (INT16_MIN != bop)) {
+ res = aop * bop;
+ res >>= 15;
+} else {
+ res = INT16_MAX;
+ P_SET_OV(1);
+}
+WRITE_RD(sext_xlen((int16_t)res)); \ No newline at end of file
diff --git a/riscv/insns/khmbb16.h b/riscv/insns/khmbb16.h
new file mode 100644
index 0000000..42a1d1b
--- /dev/null
+++ b/riscv/insns/khmbb16.h
@@ -0,0 +1,13 @@
+require_rv64;
+P_LOOP(32, {
+ int32_t aop = P_SH(ps1, 0);
+ int32_t bop = P_SH(ps2, 0);
+ if ((INT16_MIN != aop) | (INT16_MIN != bop)) {
+ pd = aop * bop;
+ pd >>= 15;
+ } else {
+ pd = INT16_MAX;
+ P_SET_OV(1);
+ }
+ pd = (int16_t)pd;
+}) \ No newline at end of file
diff --git a/riscv/insns/khmbt.h b/riscv/insns/khmbt.h
new file mode 100644
index 0000000..cdbd00f
--- /dev/null
+++ b/riscv/insns/khmbt.h
@@ -0,0 +1,12 @@
+require_extension('P');
+sreg_t res;
+sreg_t aop = P_SH(RS1, 0);
+sreg_t bop = P_SH(RS2, 1);
+if ((INT16_MIN != aop) | (INT16_MIN != bop)) {
+ res = aop * bop;
+ res >>= 15;
+} else {
+ res = INT16_MAX;
+ P_SET_OV(1);
+}
+WRITE_RD(sext_xlen((int16_t)res)); \ No newline at end of file
diff --git a/riscv/insns/khmbt16.h b/riscv/insns/khmbt16.h
new file mode 100644
index 0000000..f187902
--- /dev/null
+++ b/riscv/insns/khmbt16.h
@@ -0,0 +1,13 @@
+require_rv64;
+P_LOOP(32, {
+ int32_t aop = P_SH(ps1, 0);
+ int32_t bop = P_SH(ps2, 1);
+ if ((INT16_MIN != aop) | (INT16_MIN != bop)) {
+ pd = aop * bop;
+ pd >>= 15;
+ } else {
+ pd = INT16_MAX;
+ P_SET_OV(1);
+ }
+ pd = (int16_t)pd;
+}) \ No newline at end of file
diff --git a/riscv/insns/khmtt.h b/riscv/insns/khmtt.h
new file mode 100644
index 0000000..efcd479
--- /dev/null
+++ b/riscv/insns/khmtt.h
@@ -0,0 +1,12 @@
+require_extension('P');
+sreg_t res;
+sreg_t aop = P_SH(RS1, 1);
+sreg_t bop = P_SH(RS2, 1);
+if ((INT16_MIN != aop) | (INT16_MIN != bop)) {
+ res = aop * bop;
+ res >>= 15;
+} else {
+ res = INT16_MAX;
+ P_SET_OV(1);
+}
+WRITE_RD(sext_xlen((int16_t)res)); \ No newline at end of file
diff --git a/riscv/insns/khmtt16.h b/riscv/insns/khmtt16.h
new file mode 100644
index 0000000..7b70220
--- /dev/null
+++ b/riscv/insns/khmtt16.h
@@ -0,0 +1,13 @@
+require_rv64;
+P_LOOP(32, {
+ int32_t aop = P_SH(ps1, 1);
+ int32_t bop = P_SH(ps2, 1);
+ if ((INT16_MIN != aop) | (INT16_MIN != bop)) {
+ pd = aop * bop;
+ pd >>= 15;
+ } else {
+ pd = INT16_MAX;
+ P_SET_OV(1);
+ }
+ pd = (int16_t)pd;
+}) \ No newline at end of file
diff --git a/riscv/insns/khmx16.h b/riscv/insns/khmx16.h
new file mode 100644
index 0000000..dd5ddf1
--- /dev/null
+++ b/riscv/insns/khmx16.h
@@ -0,0 +1,8 @@
+P_CROSS_LOOP(16, {
+ if ((ps1 != INT16_MIN) | (ps2 != INT16_MIN)) {
+ pd = (ps1 * ps2) >> 15;
+ } else {
+ pd = INT16_MAX;
+ P_SET_OV(1);
+ }
+},) \ No newline at end of file
diff --git a/riscv/insns/khmx8.h b/riscv/insns/khmx8.h
new file mode 100644
index 0000000..41770e8
--- /dev/null
+++ b/riscv/insns/khmx8.h
@@ -0,0 +1,8 @@
+P_CROSS_LOOP(8, {
+ if ((ps1 != INT8_MIN) | (ps2 != INT8_MIN)) {
+ pd = (ps1 * ps2) >> 7;
+ } else {
+ pd = INT8_MAX;
+ P_SET_OV(1);
+ }
+},) \ No newline at end of file
diff --git a/riscv/insns/kmabb.h b/riscv/insns/kmabb.h
new file mode 100644
index 0000000..18b01fb
--- /dev/null
+++ b/riscv/insns/kmabb.h
@@ -0,0 +1,6 @@
+P_LOOP(32, {
+ int32_t mres = P_SH(ps1, 0) * P_SH(ps2, 0);
+ bool sat = false;
+ pd = (sat_add<int32_t, uint32_t>(pd, mres, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/kmabb32.h b/riscv/insns/kmabb32.h
new file mode 100644
index 0000000..0c417af
--- /dev/null
+++ b/riscv/insns/kmabb32.h
@@ -0,0 +1,7 @@
+require_rv64;
+require_extension('P');
+
+bool sat = false;
+sreg_t mres = (sreg_t)P_SW(RS1, 0) * P_SW(RS2, 0);
+WRITE_RD((sat_add<int64_t, uint64_t>(RD, mres, sat)));
+P_SET_OV(sat); \ No newline at end of file
diff --git a/riscv/insns/kmabt.h b/riscv/insns/kmabt.h
new file mode 100644
index 0000000..eeab423
--- /dev/null
+++ b/riscv/insns/kmabt.h
@@ -0,0 +1,6 @@
+P_LOOP(32, {
+ int32_t mres = P_SH(ps1, 0) * P_SH(ps2, 1);
+ bool sat = false;
+ pd = (sat_add<int32_t, uint32_t>(pd, mres, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/kmabt32.h b/riscv/insns/kmabt32.h
new file mode 100644
index 0000000..42701f4
--- /dev/null
+++ b/riscv/insns/kmabt32.h
@@ -0,0 +1,7 @@
+require_rv64;
+require_extension('P');
+
+bool sat = false;
+sreg_t mres = (sreg_t)P_SW(RS1, 0) * P_SW(RS2, 1);
+WRITE_RD((sat_add<int64_t, uint64_t>(RD, mres, sat)));
+P_SET_OV(sat); \ No newline at end of file
diff --git a/riscv/insns/kmada.h b/riscv/insns/kmada.h
new file mode 100644
index 0000000..2fb8fd4
--- /dev/null
+++ b/riscv/insns/kmada.h
@@ -0,0 +1,3 @@
+P_REDUCTION_LOOP(32, 16, true, true, {
+ pd_res += ps1 * ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/kmadrs.h b/riscv/insns/kmadrs.h
new file mode 100644
index 0000000..8b5a888
--- /dev/null
+++ b/riscv/insns/kmadrs.h
@@ -0,0 +1,6 @@
+P_REDUCTION_LOOP(32, 16, true, true, {
+ if (j & 1)
+ pd_res -= ps1 * ps2;
+ else
+ pd_res += ps1 * ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/kmadrs32.h b/riscv/insns/kmadrs32.h
new file mode 100644
index 0000000..f502b0e
--- /dev/null
+++ b/riscv/insns/kmadrs32.h
@@ -0,0 +1,9 @@
+require_rv64;
+require_extension('P');
+
+bool sat;
+sreg_t mres0 = (sreg_t)P_SW(RS1, 0) * P_SW(RS2, 0);
+sreg_t mres1 = (sreg_t)P_SW(RS1, 1) * P_SW(RS2, 1);
+
+WRITE_RD((sat_add<sreg_t, reg_t>(RD, mres0, -mres1, sat)));
+P_SET_OV(sat); \ No newline at end of file
diff --git a/riscv/insns/kmads.h b/riscv/insns/kmads.h
new file mode 100644
index 0000000..f1d9948
--- /dev/null
+++ b/riscv/insns/kmads.h
@@ -0,0 +1,6 @@
+P_REDUCTION_LOOP(32, 16, true, true, {
+ if (j & 1)
+ pd_res += ps1 * ps2;
+ else
+ pd_res -= ps1 * ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/kmads32.h b/riscv/insns/kmads32.h
new file mode 100644
index 0000000..79ad4a6
--- /dev/null
+++ b/riscv/insns/kmads32.h
@@ -0,0 +1,9 @@
+require_rv64;
+require_extension('P');
+
+bool sat;
+sreg_t mres0 = (sreg_t)P_SW(RS1, 0) * P_SW(RS2, 0);
+sreg_t mres1 = (sreg_t)P_SW(RS1, 1) * P_SW(RS2, 1);
+
+WRITE_RD((sat_add<sreg_t, reg_t>(RD, -mres0, mres1, sat)));
+P_SET_OV(sat); \ No newline at end of file
diff --git a/riscv/insns/kmar64.h b/riscv/insns/kmar64.h
new file mode 100644
index 0000000..eb6275c
--- /dev/null
+++ b/riscv/insns/kmar64.h
@@ -0,0 +1,15 @@
+P_64_PROFILE_BASE()
+P_64_PROFILE_PARAM(true, false)
+
+bool sat = false;
+sreg_t mres0 = (sreg_t)P_SW(rs1, 0) * P_SW(rs2, 0);
+sreg_t mres1 = (sreg_t)P_SW(rs1, 1) * P_SW(rs2, 1);
+sreg_t res;
+
+if (xlen == 32) {
+ rd = (sat_add<int64_t, uint64_t>(rd, mres0, sat));
+} else {
+ rd = (sat_add<int64_t, uint64_t>(rd, mres0, mres1, sat));
+}
+P_SET_OV(sat);
+P_64_PROFILE_END() \ No newline at end of file
diff --git a/riscv/insns/kmatt.h b/riscv/insns/kmatt.h
new file mode 100644
index 0000000..e2611c6
--- /dev/null
+++ b/riscv/insns/kmatt.h
@@ -0,0 +1,6 @@
+P_LOOP(32, {
+ int32_t mres = P_SH(ps1, 1) * P_SH(ps2, 1);
+ bool sat = false;
+ pd = (sat_add<int32_t, uint32_t>(pd, mres, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/kmatt32.h b/riscv/insns/kmatt32.h
new file mode 100644
index 0000000..e0e1a90
--- /dev/null
+++ b/riscv/insns/kmatt32.h
@@ -0,0 +1,7 @@
+require_rv64;
+require_extension('P');
+
+bool sat = false;
+sreg_t mres = (sreg_t)P_SW(RS1, 1) * P_SW(RS2, 1);
+WRITE_RD((sat_add<int64_t, uint64_t>(RD, mres, sat)));
+P_SET_OV(sat); \ No newline at end of file
diff --git a/riscv/insns/kmaxda.h b/riscv/insns/kmaxda.h
new file mode 100644
index 0000000..7aaca96
--- /dev/null
+++ b/riscv/insns/kmaxda.h
@@ -0,0 +1,3 @@
+P_REDUCTION_CROSS_LOOP(32, 16, true, true, {
+ pd_res += ps1 * ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/kmaxda32.h b/riscv/insns/kmaxda32.h
new file mode 100644
index 0000000..0fb0c70
--- /dev/null
+++ b/riscv/insns/kmaxda32.h
@@ -0,0 +1,9 @@
+require_rv64;
+require_extension('P');
+
+bool sat;
+sreg_t mres0 = (sreg_t)P_SW(RS1, 0) * P_SW(RS2, 1);
+sreg_t mres1 = (sreg_t)P_SW(RS1, 1) * P_SW(RS2, 0);
+
+WRITE_RD((sat_add<sreg_t, reg_t>(RD, mres0, mres1, sat)));
+P_SET_OV(sat); \ No newline at end of file
diff --git a/riscv/insns/kmaxds.h b/riscv/insns/kmaxds.h
new file mode 100644
index 0000000..d6f36f8
--- /dev/null
+++ b/riscv/insns/kmaxds.h
@@ -0,0 +1,6 @@
+P_REDUCTION_CROSS_LOOP(32, 16, true, true, {
+ if (j & 1)
+ pd_res += ps1 * ps2;
+ else
+ pd_res -= ps1 * ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/kmaxds32.h b/riscv/insns/kmaxds32.h
new file mode 100644
index 0000000..1fd93d3
--- /dev/null
+++ b/riscv/insns/kmaxds32.h
@@ -0,0 +1,9 @@
+require_rv64;
+require_extension('P');
+
+bool sat;
+sreg_t mres0 = (sreg_t)P_SW(RS1, 0) * P_SW(RS2, 1);
+sreg_t mres1 = (sreg_t)P_SW(RS1, 1) * P_SW(RS2, 0);
+
+WRITE_RD((sat_add<sreg_t, reg_t>(RD, -mres0, mres1, sat)));
+P_SET_OV(sat); \ No newline at end of file
diff --git a/riscv/insns/kmda.h b/riscv/insns/kmda.h
new file mode 100644
index 0000000..ceba4ac
--- /dev/null
+++ b/riscv/insns/kmda.h
@@ -0,0 +1,3 @@
+P_REDUCTION_LOOP(32, 16, false, true, {
+ pd_res += ps1 * ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/kmda32.h b/riscv/insns/kmda32.h
new file mode 100644
index 0000000..6233284
--- /dev/null
+++ b/riscv/insns/kmda32.h
@@ -0,0 +1,9 @@
+require_rv64;
+require_extension('P');
+
+bool sat;
+sreg_t mres0 = (sreg_t)P_SW(RS1, 0) * P_SW(RS2, 0);
+sreg_t mres1 = (sreg_t)P_SW(RS1, 1) * P_SW(RS2, 1);
+
+WRITE_RD((sat_add<sreg_t, reg_t>(mres0, mres1, sat)));
+P_SET_OV(sat); \ No newline at end of file
diff --git a/riscv/insns/kmmac.h b/riscv/insns/kmmac.h
new file mode 100644
index 0000000..124771a
--- /dev/null
+++ b/riscv/insns/kmmac.h
@@ -0,0 +1,6 @@
+P_LOOP(32, {
+ int64_t mres = (int64_t) ps1 * (int64_t) ps2;
+ bool sat = false;
+ pd = (sat_add<int32_t, uint32_t>(pd, (mres >> 32), sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/kmmac_u.h b/riscv/insns/kmmac_u.h
new file mode 100644
index 0000000..9a0c580
--- /dev/null
+++ b/riscv/insns/kmmac_u.h
@@ -0,0 +1,7 @@
+P_LOOP(32, {
+ int64_t mres = (int64_t) ps1 * (int64_t) ps2;
+ int32_t round = (((mres >> 31) + 1) >> 1);
+ bool sat = false;
+ pd = (sat_add<int32_t, uint32_t>(pd, round, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/kmmawb.h b/riscv/insns/kmmawb.h
new file mode 100644
index 0000000..28eb0a8
--- /dev/null
+++ b/riscv/insns/kmmawb.h
@@ -0,0 +1,6 @@
+P_LOOP(32, {
+ int64_t mres = (int64_t)ps1 * P_SH(ps2, 0);
+ bool sat = false;
+ pd = (sat_add<int32_t, uint32_t>(pd, (mres >> 16), sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/kmmawb2.h b/riscv/insns/kmmawb2.h
new file mode 100644
index 0000000..e82bfda
--- /dev/null
+++ b/riscv/insns/kmmawb2.h
@@ -0,0 +1,14 @@
+P_LOOP(32, {
+ int64_t addop = 0;
+ int64_t mres = 0;
+ bool sat = false;
+ if((INT32_MIN != ps1) | (INT16_MIN != P_SH(ps2, 0))) {
+ mres = ((int64_t) ps1 * P_SH(ps2, 0)) << 1;
+ addop = mres >> 16;
+ } else {
+ addop = INT32_MAX;
+ P_SET_OV(1);
+ }
+ pd = (sat_add<int32_t, uint32_t>(pd, addop, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/kmmawb2_u.h b/riscv/insns/kmmawb2_u.h
new file mode 100644
index 0000000..fb4b075
--- /dev/null
+++ b/riscv/insns/kmmawb2_u.h
@@ -0,0 +1,14 @@
+P_LOOP(32, {
+ int64_t addop = 0;
+ int64_t mres = 0;
+ bool sat = false;
+ if((INT32_MIN != ps1) | (INT16_MIN != P_SH(ps2, 0))) {
+ mres = ((int64_t) ps1 * P_SH(ps2, 0)) << 1;
+ addop = ((mres >> 15) + 1) >> 1;
+ } else {
+ addop = INT32_MAX;
+ P_SET_OV(1);
+ }
+ pd = (sat_add<int32_t, uint32_t>(pd, addop, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/kmmawb_u.h b/riscv/insns/kmmawb_u.h
new file mode 100644
index 0000000..4c51b74
--- /dev/null
+++ b/riscv/insns/kmmawb_u.h
@@ -0,0 +1,7 @@
+P_LOOP(32, {
+ int64_t mres = (int64_t)ps1 * P_SH(ps2, 0);
+ int32_t round = (((mres >> 15) + 1) >> 1);
+ bool sat = false;
+ pd = (sat_add<int32_t, uint32_t>(pd, round, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/kmmawt.h b/riscv/insns/kmmawt.h
new file mode 100644
index 0000000..444546f
--- /dev/null
+++ b/riscv/insns/kmmawt.h
@@ -0,0 +1,6 @@
+P_LOOP(32, {
+ int64_t mres = (int64_t)ps1 * P_SH(ps2, 1);
+ bool sat = false;
+ pd = (sat_add<int32_t, uint32_t>(pd, (mres >> 16), sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/kmmawt2.h b/riscv/insns/kmmawt2.h
new file mode 100644
index 0000000..c92d8c7
--- /dev/null
+++ b/riscv/insns/kmmawt2.h
@@ -0,0 +1,14 @@
+P_LOOP(32, {
+ int64_t addop = 0;
+ int64_t mres = 0;
+ bool sat = false;
+ if((INT32_MIN != ps1) | (INT16_MIN != P_SH(ps2, 1))) {
+ mres = ((int64_t) ps1 * P_SH(ps2, 1)) << 1;
+ addop = mres >> 16;
+ } else {
+ addop = INT32_MAX;
+ P_SET_OV(1);
+ }
+ pd = (sat_add<int32_t, uint32_t>(pd, addop, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/kmmawt2_u.h b/riscv/insns/kmmawt2_u.h
new file mode 100644
index 0000000..46dca79
--- /dev/null
+++ b/riscv/insns/kmmawt2_u.h
@@ -0,0 +1,14 @@
+P_LOOP(32, {
+ int64_t addop = 0;
+ int64_t mres = 0;
+ bool sat = false;
+ if((INT32_MIN != ps1) | (INT16_MIN != P_SH(ps2, 1))) {
+ mres = ((int64_t) ps1 * P_SH(ps2, 1)) << 1;
+ addop = ((mres >> 15) + 1) >> 1;
+ } else {
+ addop = INT32_MAX;
+ P_SET_OV(1);
+ }
+ pd = (sat_add<int32_t, uint32_t>(pd, addop, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/kmmawt_u.h b/riscv/insns/kmmawt_u.h
new file mode 100644
index 0000000..fe1dff0
--- /dev/null
+++ b/riscv/insns/kmmawt_u.h
@@ -0,0 +1,7 @@
+P_LOOP(32, {
+ int64_t mres = (int64_t)ps1 * P_SH(ps2, 1);
+ int32_t round = (((mres >> 15) + 1) >> 1);
+ bool sat = false;
+ pd = (sat_add<int32_t, uint32_t>(pd, round, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/kmmsb.h b/riscv/insns/kmmsb.h
new file mode 100644
index 0000000..f1b4c8b
--- /dev/null
+++ b/riscv/insns/kmmsb.h
@@ -0,0 +1,6 @@
+P_LOOP(32, {
+ int64_t mres = (int64_t) ps1 * (int64_t) ps2;
+ bool sat = false;
+ pd = (sat_sub<int32_t, uint32_t>(pd, (mres >> 32), sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/kmmsb_u.h b/riscv/insns/kmmsb_u.h
new file mode 100644
index 0000000..864c66c
--- /dev/null
+++ b/riscv/insns/kmmsb_u.h
@@ -0,0 +1,7 @@
+P_LOOP(32, {
+ int64_t mres = (int64_t) ps1 * (int64_t) ps2;
+ int32_t round = (((mres >> 31) + 1) >> 1);
+ bool sat = false;
+ pd = (sat_sub<int32_t, uint32_t>(pd, round, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/kmmwb2.h b/riscv/insns/kmmwb2.h
new file mode 100644
index 0000000..8574aa5
--- /dev/null
+++ b/riscv/insns/kmmwb2.h
@@ -0,0 +1,9 @@
+P_LOOP(32, {
+ if((INT32_MIN != ps1) | (INT16_MIN != P_SH(ps2, 0))) {
+ int64_t mres = ((int64_t) ps1 * P_SH(ps2, 0)) << 1;
+ pd = mres >> 16;
+ } else {
+ pd = INT32_MAX;
+ P_SET_OV(1);
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/kmmwb2_u.h b/riscv/insns/kmmwb2_u.h
new file mode 100644
index 0000000..4216ad1
--- /dev/null
+++ b/riscv/insns/kmmwb2_u.h
@@ -0,0 +1,9 @@
+P_LOOP(32, {
+ if((INT32_MIN != ps1) | (INT16_MIN != P_SH(ps2, 0))) {
+ int64_t mres = ((int64_t) ps1 * P_SH(ps2, 0)) << 1;
+ pd = ((mres >> 15) + 1) >> 1;
+ } else {
+ pd = INT32_MAX;
+ P_SET_OV(1);
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/kmmwt2.h b/riscv/insns/kmmwt2.h
new file mode 100644
index 0000000..62b47cd
--- /dev/null
+++ b/riscv/insns/kmmwt2.h
@@ -0,0 +1,9 @@
+P_LOOP(32, {
+ if((INT32_MIN != ps1) | (INT16_MIN != P_SH(ps2, 1))) {
+ int64_t mres = ((int64_t) ps1 * P_SH(ps2, 1)) << 1;
+ pd = mres >> 16;
+ } else {
+ pd = INT32_MAX;
+ P_SET_OV(1);
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/kmmwt2_u.h b/riscv/insns/kmmwt2_u.h
new file mode 100644
index 0000000..d76d890
--- /dev/null
+++ b/riscv/insns/kmmwt2_u.h
@@ -0,0 +1,9 @@
+P_LOOP(32, {
+ if((INT32_MIN != ps1) | (INT16_MIN != P_SH(ps2, 1))) {
+ int64_t mres = ((int64_t) ps1 * P_SH(ps2, 1)) << 1;
+ pd = ((mres >> 15) + 1) >> 1;
+ } else {
+ pd = INT32_MAX;
+ P_SET_OV(1);
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/kmsda.h b/riscv/insns/kmsda.h
new file mode 100644
index 0000000..4992ac3
--- /dev/null
+++ b/riscv/insns/kmsda.h
@@ -0,0 +1,3 @@
+P_REDUCTION_LOOP(32, 16, true, true, {
+ pd_res -= ps1 * ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/kmsda32.h b/riscv/insns/kmsda32.h
new file mode 100644
index 0000000..1a3a13b
--- /dev/null
+++ b/riscv/insns/kmsda32.h
@@ -0,0 +1,9 @@
+require_rv64;
+require_extension('P');
+
+bool sat;
+sreg_t mres0 = (sreg_t)P_SW(RS1, 0) * P_SW(RS2, 0);
+sreg_t mres1 = (sreg_t)P_SW(RS1, 1) * P_SW(RS2, 1);
+
+WRITE_RD((sat_add<sreg_t, reg_t>(RD, -mres0, -mres1, sat)));
+P_SET_OV(sat); \ No newline at end of file
diff --git a/riscv/insns/kmsr64.h b/riscv/insns/kmsr64.h
new file mode 100644
index 0000000..bdc405e
--- /dev/null
+++ b/riscv/insns/kmsr64.h
@@ -0,0 +1,25 @@
+P_64_PROFILE_BASE()
+P_64_PROFILE_PARAM(true, false)
+
+bool sat = false;
+sreg_t mres0 = -(sreg_t)P_SW(rs1, 0) * P_SW(rs2, 0);
+sreg_t mres1 = -(sreg_t)P_SW(rs1, 1) * P_SW(rs2, 1);
+sreg_t res;
+
+if (xlen == 32) {
+ rd = (sat_add<int64_t, uint64_t>(rd, mres0, sat));
+} else {
+ if ((rd ^ mres0) < 0) {
+ res = rd + mres0;
+ rd = (sat_add<int64_t, uint64_t>(res, mres1, sat));
+ } else if ((rd ^ mres1) < 0) {
+ res = rd + mres1;
+ rd = (sat_add<int64_t, uint64_t>(res, mres0, sat));
+ } else {
+ rd = (sat_add<int64_t, uint64_t>(rd, mres0, sat));
+ P_SET_OV(sat);
+ rd = (sat_add<int64_t, uint64_t>(rd, mres1, sat));
+ }
+}
+P_SET_OV(sat);
+P_64_PROFILE_END() \ No newline at end of file
diff --git a/riscv/insns/kmsxda.h b/riscv/insns/kmsxda.h
new file mode 100644
index 0000000..34b2b1d
--- /dev/null
+++ b/riscv/insns/kmsxda.h
@@ -0,0 +1,3 @@
+P_REDUCTION_CROSS_LOOP(32, 16, true, true, {
+ pd_res -= ps1 * ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/kmsxda32.h b/riscv/insns/kmsxda32.h
new file mode 100644
index 0000000..8bea0c2
--- /dev/null
+++ b/riscv/insns/kmsxda32.h
@@ -0,0 +1,9 @@
+require_rv64;
+require_extension('P');
+
+bool sat;
+sreg_t mres0 = (sreg_t)P_SW(RS1, 0) * P_SW(RS2, 1);
+sreg_t mres1 = (sreg_t)P_SW(RS1, 1) * P_SW(RS2, 0);
+
+WRITE_RD((sat_add<sreg_t, reg_t>(RD, -mres0, -mres1, sat)));
+P_SET_OV(sat); \ No newline at end of file
diff --git a/riscv/insns/kmxda.h b/riscv/insns/kmxda.h
new file mode 100644
index 0000000..0f6fb03
--- /dev/null
+++ b/riscv/insns/kmxda.h
@@ -0,0 +1,3 @@
+P_REDUCTION_CROSS_LOOP(32, 16, false, true, {
+ pd_res += ps1 * ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/kmxda32.h b/riscv/insns/kmxda32.h
new file mode 100644
index 0000000..d33cdf1
--- /dev/null
+++ b/riscv/insns/kmxda32.h
@@ -0,0 +1,9 @@
+require_rv64;
+require_extension('P');
+
+bool sat;
+sreg_t mres0 = (sreg_t)P_SW(RS1, 0) * P_SW(RS2, 1);
+sreg_t mres1 = (sreg_t)P_SW(RS1, 1) * P_SW(RS2, 0);
+
+WRITE_RD((sat_add<sreg_t, reg_t>(mres0, mres1, sat)));
+P_SET_OV(sat); \ No newline at end of file
diff --git a/riscv/insns/ksll16.h b/riscv/insns/ksll16.h
new file mode 100644
index 0000000..405967a
--- /dev/null
+++ b/riscv/insns/ksll16.h
@@ -0,0 +1,5 @@
+P_X_LOOP(16, 4, {
+ auto res = (sreg_t)ps1 << sa;
+ P_SAT(res, 16);
+ pd = res;
+}) \ No newline at end of file
diff --git a/riscv/insns/ksll32.h b/riscv/insns/ksll32.h
new file mode 100644
index 0000000..4533119
--- /dev/null
+++ b/riscv/insns/ksll32.h
@@ -0,0 +1,6 @@
+require_rv64;
+P_X_LOOP(32, 5, {
+ auto res = (sreg_t)ps1 << sa;
+ P_SAT(res, 32);
+ pd = res;
+}) \ No newline at end of file
diff --git a/riscv/insns/ksll8.h b/riscv/insns/ksll8.h
new file mode 100644
index 0000000..482ceb7
--- /dev/null
+++ b/riscv/insns/ksll8.h
@@ -0,0 +1,5 @@
+P_X_LOOP(8, 3, {
+ auto res = (sreg_t)ps1 << sa;
+ P_SAT(res, 8);
+ pd = res;
+}) \ No newline at end of file
diff --git a/riscv/insns/kslli16.h b/riscv/insns/kslli16.h
new file mode 100644
index 0000000..dd8c1de
--- /dev/null
+++ b/riscv/insns/kslli16.h
@@ -0,0 +1,5 @@
+P_I_LOOP(16, 4, {
+ auto res = (sreg_t)ps1 << imm4u;
+ P_SAT(res, 16);
+ pd = res;
+}) \ No newline at end of file
diff --git a/riscv/insns/kslli32.h b/riscv/insns/kslli32.h
new file mode 100644
index 0000000..4c034bd
--- /dev/null
+++ b/riscv/insns/kslli32.h
@@ -0,0 +1,6 @@
+require_rv64;
+P_I_LOOP(32, 5, {
+ auto res = (sreg_t)ps1 << imm5u;
+ P_SAT(res, 32);
+ pd = res;
+}) \ No newline at end of file
diff --git a/riscv/insns/kslli8.h b/riscv/insns/kslli8.h
new file mode 100644
index 0000000..cc8b08d
--- /dev/null
+++ b/riscv/insns/kslli8.h
@@ -0,0 +1,5 @@
+P_I_LOOP(8, 3, {
+ auto res = (sreg_t)ps1 << imm3u;
+ P_SAT(res, 8);
+ pd = res;
+}) \ No newline at end of file
diff --git a/riscv/insns/kslliw.h b/riscv/insns/kslliw.h
new file mode 100644
index 0000000..9c1d877
--- /dev/null
+++ b/riscv/insns/kslliw.h
@@ -0,0 +1,7 @@
+require_extension('P');
+sreg_t rs1 = sext32(RS1);
+sreg_t sa = insn.p_imm5();
+sreg_t res = rs1 << sa;
+
+P_SAT(res, 32);
+WRITE_RD(sext32(res)); \ No newline at end of file
diff --git a/riscv/insns/ksllw.h b/riscv/insns/ksllw.h
new file mode 100644
index 0000000..b95a6f2
--- /dev/null
+++ b/riscv/insns/ksllw.h
@@ -0,0 +1,7 @@
+require_extension('P');
+sreg_t rs1 = sext32(RS1);
+sreg_t sa = get_field(RS2, make_mask64(0, 5));
+sreg_t res = rs1 << sa;
+
+P_SAT(res, 32);
+WRITE_RD(sext32(res)); \ No newline at end of file
diff --git a/riscv/insns/kslra16.h b/riscv/insns/kslra16.h
new file mode 100644
index 0000000..93ccec3
--- /dev/null
+++ b/riscv/insns/kslra16.h
@@ -0,0 +1,11 @@
+P_X_LOOP(16, 5, {
+ if (ssa < 0) {
+ sa = -ssa;
+ sa = (sa == 16) ? 15 : sa;
+ pd = ps1 >> sa;
+ } else {
+ auto res = (sreg_t)ps1 << ssa;
+ P_SAT(res, 16);
+ pd = res;
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/kslra16_u.h b/riscv/insns/kslra16_u.h
new file mode 100644
index 0000000..ac6b2ff
--- /dev/null
+++ b/riscv/insns/kslra16_u.h
@@ -0,0 +1,14 @@
+P_X_LOOP(16, 5, {
+ if (ssa < 0) {
+ sa = -ssa;
+ sa = (sa == 16) ? 15 : sa;
+ if(sa != 0)
+ pd = ((ps1 >> (sa - 1)) + 1) >> 1;
+ else
+ pd = ps1;
+ } else {
+ auto res = (sreg_t)ps1 << ssa;
+ P_SAT(res, 16);
+ pd = res;
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/kslra32.h b/riscv/insns/kslra32.h
new file mode 100644
index 0000000..34ffbe4
--- /dev/null
+++ b/riscv/insns/kslra32.h
@@ -0,0 +1,12 @@
+require_rv64;
+P_X_LOOP(32, 6, {
+ if (ssa < 0) {
+ sa = -ssa;
+ sa = (sa == 32) ? 31 : sa;
+ pd = ps1 >> sa;
+ } else {
+ auto res = (sreg_t)ps1 << ssa;
+ P_SAT(res, 32);
+ pd = res;
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/kslra32_u.h b/riscv/insns/kslra32_u.h
new file mode 100644
index 0000000..8fe632d
--- /dev/null
+++ b/riscv/insns/kslra32_u.h
@@ -0,0 +1,15 @@
+require_rv64;
+P_X_LOOP(32, 6, {
+ if (ssa < 0) {
+ sa = -ssa;
+ sa = (sa == 32) ? 31 : sa;
+ if(sa != 0)
+ pd = ((ps1 >> (sa - 1)) + 1) >> 1;
+ else
+ pd = ps1;
+ } else {
+ auto res = (sreg_t)ps1 << ssa;
+ P_SAT(res, 32);
+ pd = res;
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/kslra8.h b/riscv/insns/kslra8.h
new file mode 100644
index 0000000..8ed631d
--- /dev/null
+++ b/riscv/insns/kslra8.h
@@ -0,0 +1,11 @@
+P_X_LOOP(8, 4, {
+ if (ssa < 0) {
+ sa = -ssa;
+ sa = (sa == 8) ? 7 : sa;
+ pd = ps1 >> sa;
+ } else {
+ auto res = (sreg_t)ps1 << ssa;
+ P_SAT(res, 8);
+ pd = res;
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/kslra8_u.h b/riscv/insns/kslra8_u.h
new file mode 100644
index 0000000..9139775
--- /dev/null
+++ b/riscv/insns/kslra8_u.h
@@ -0,0 +1,14 @@
+P_X_LOOP(8, 4, {
+ if (ssa < 0) {
+ sa = -ssa;
+ sa = (sa == 8) ? 7 : sa;
+ if(sa != 0)
+ pd = ((ps1 >> (sa - 1)) + 1) >> 1;
+ else
+ pd = ps1;
+ } else {
+ auto res = (sreg_t)ps1 << ssa;
+ P_SAT(res, 8);
+ pd = res;
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/kslraw.h b/riscv/insns/kslraw.h
new file mode 100644
index 0000000..36e1ea9
--- /dev/null
+++ b/riscv/insns/kslraw.h
@@ -0,0 +1,13 @@
+require_extension('P');
+sreg_t rs1 = sext32(RS1);
+sreg_t sa = int64_t(RS2) << (64 - 6) >> (64 - 6);
+
+if (sa < 0) {
+ sa = -sa;
+ sa = (sa == 32) ? 31 : sa;
+ WRITE_RD(sext32(rs1 >> sa));
+} else {
+ auto res = rs1 << sa;
+ P_SAT(res, 32);
+ WRITE_RD(sext32(res));
+} \ No newline at end of file
diff --git a/riscv/insns/kslraw_u.h b/riscv/insns/kslraw_u.h
new file mode 100644
index 0000000..3ff723d
--- /dev/null
+++ b/riscv/insns/kslraw_u.h
@@ -0,0 +1,13 @@
+require_extension('P');
+sreg_t rs1 = sext32(RS1);
+sreg_t sa = int64_t(RS2) << (64 - 6) >> (64 - 6);
+
+if (sa < 0) {
+ sa = -sa;
+ sa = (sa == 32) ? 31 : sa;
+ WRITE_RD(sext32(((rs1 >> (sa - 1)) + 1)) >> 1);
+} else {
+ auto res = rs1 << sa;
+ P_SAT(res, 32);
+ WRITE_RD(sext32(res));
+} \ No newline at end of file
diff --git a/riscv/insns/kstas16.h b/riscv/insns/kstas16.h
new file mode 100644
index 0000000..50d3a46
--- /dev/null
+++ b/riscv/insns/kstas16.h
@@ -0,0 +1,9 @@
+P_STRAIGHT_ULOOP(16, {
+ bool sat = false;
+ pd = (sat_add<int16_t, uint16_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}, {
+ bool sat = false;
+ pd = (sat_sub<int16_t, uint16_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/kstas32.h b/riscv/insns/kstas32.h
new file mode 100644
index 0000000..aea3c46
--- /dev/null
+++ b/riscv/insns/kstas32.h
@@ -0,0 +1,10 @@
+require_rv64;
+P_STRAIGHT_ULOOP(32, {
+ bool sat = false;
+ pd = (sat_add<int32_t, uint32_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}, {
+ bool sat = false;
+ pd = (sat_sub<int32_t, uint32_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/kstsa16.h b/riscv/insns/kstsa16.h
new file mode 100644
index 0000000..76b1f22
--- /dev/null
+++ b/riscv/insns/kstsa16.h
@@ -0,0 +1,9 @@
+P_STRAIGHT_ULOOP(16, {
+ bool sat = false;
+ pd = (sat_sub<int16_t, uint16_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}, {
+ bool sat = false;
+ pd = (sat_add<int16_t, uint16_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/kstsa32.h b/riscv/insns/kstsa32.h
new file mode 100644
index 0000000..d2ac99b
--- /dev/null
+++ b/riscv/insns/kstsa32.h
@@ -0,0 +1,10 @@
+require_rv64;
+P_STRAIGHT_ULOOP(32, {
+ bool sat = false;
+ pd = (sat_sub<int32_t, uint32_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}, {
+ bool sat = false;
+ pd = (sat_add<int32_t, uint32_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/ksub16.h b/riscv/insns/ksub16.h
new file mode 100644
index 0000000..9994359
--- /dev/null
+++ b/riscv/insns/ksub16.h
@@ -0,0 +1,5 @@
+P_LOOP(16, {
+ bool sat = false;
+ pd = (sat_sub<int16_t, uint16_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/ksub32.h b/riscv/insns/ksub32.h
new file mode 100644
index 0000000..3e51440
--- /dev/null
+++ b/riscv/insns/ksub32.h
@@ -0,0 +1,6 @@
+require_rv64;
+P_LOOP(32, {
+ bool sat = false;
+ pd = (sat_sub<int32_t, uint32_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/ksub64.h b/riscv/insns/ksub64.h
new file mode 100644
index 0000000..c94c28e
--- /dev/null
+++ b/riscv/insns/ksub64.h
@@ -0,0 +1,5 @@
+P_64_PROFILE({
+ bool sat = false;
+ rd = (sat_sub<int64_t, uint64_t>(rs1, rs2, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/ksub8.h b/riscv/insns/ksub8.h
new file mode 100644
index 0000000..90a0c58
--- /dev/null
+++ b/riscv/insns/ksub8.h
@@ -0,0 +1,5 @@
+P_LOOP(8, {
+ bool sat = false;
+ pd = (sat_sub<int8_t, uint8_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/ksubh.h b/riscv/insns/ksubh.h
new file mode 100644
index 0000000..9c21a94
--- /dev/null
+++ b/riscv/insns/ksubh.h
@@ -0,0 +1,4 @@
+require_extension('P');
+sreg_t res = (sreg_t)P_SW(RS1, 0) - (sreg_t)P_SW(RS2, 0);
+P_SAT(res, 16);
+WRITE_RD(sext_xlen((int16_t)res)); \ No newline at end of file
diff --git a/riscv/insns/ksubw.h b/riscv/insns/ksubw.h
new file mode 100644
index 0000000..0542ba1
--- /dev/null
+++ b/riscv/insns/ksubw.h
@@ -0,0 +1,4 @@
+require_extension('P');
+sreg_t res = (sreg_t)P_SW(RS1, 0) - (sreg_t)P_SW(RS2, 0);
+P_SAT(res, 32);
+WRITE_RD(sext32(res)); \ No newline at end of file
diff --git a/riscv/insns/kwmmul.h b/riscv/insns/kwmmul.h
new file mode 100644
index 0000000..0332769
--- /dev/null
+++ b/riscv/insns/kwmmul.h
@@ -0,0 +1,9 @@
+P_LOOP(32, {
+ if((INT32_MIN != ps1) | (INT32_MIN != ps2)) {
+ int64_t mres = ((int64_t) ps1 * (int64_t) ps2) << 1;
+ pd = mres >> 32;
+ } else {
+ pd = INT32_MAX;
+ P_SET_OV(1);
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/kwmmul_u.h b/riscv/insns/kwmmul_u.h
new file mode 100644
index 0000000..73ba2c7
--- /dev/null
+++ b/riscv/insns/kwmmul_u.h
@@ -0,0 +1,9 @@
+P_LOOP(32, {
+ if((INT32_MIN != ps1) | (INT32_MIN != ps2)) {
+ int64_t mres = ((int64_t) ps1 * (int64_t) ps2) << 1;
+ pd = ((mres >> 31) + 1) >> 1;
+ } else {
+ pd = INT32_MAX;
+ P_SET_OV(1);
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/maddr32.h b/riscv/insns/maddr32.h
new file mode 100644
index 0000000..47cadd3
--- /dev/null
+++ b/riscv/insns/maddr32.h
@@ -0,0 +1,5 @@
+require_extension('P');
+reg_t mres = (reg_t)P_W(RS1, 0) * P_W(RS2, 0);
+reg_t rd = P_W(RD, 0);
+rd += mres;
+WRITE_RD(sext_xlen((int32_t)rd)); \ No newline at end of file
diff --git a/riscv/insns/maxw.h b/riscv/insns/maxw.h
new file mode 100644
index 0000000..7fc9404
--- /dev/null
+++ b/riscv/insns/maxw.h
@@ -0,0 +1,4 @@
+require_extension('P');
+int32_t rs1w = P_W(RS1, 0);
+int32_t rs2w = P_W(RS2, 0);
+WRITE_RD(sext_xlen(rs1w >= rs2w ? rs1w : rs2w)); \ No newline at end of file
diff --git a/riscv/insns/minw.h b/riscv/insns/minw.h
new file mode 100644
index 0000000..1c00c63
--- /dev/null
+++ b/riscv/insns/minw.h
@@ -0,0 +1,4 @@
+require_extension('P');
+int32_t rs1w = P_W(RS1, 0);
+int32_t rs2w = P_W(RS2, 0);
+WRITE_RD(sext_xlen(rs1w >= rs2w ? rs2w : rs1w)); \ No newline at end of file
diff --git a/riscv/insns/msubr32.h b/riscv/insns/msubr32.h
new file mode 100644
index 0000000..14dabb8
--- /dev/null
+++ b/riscv/insns/msubr32.h
@@ -0,0 +1,5 @@
+require_extension('P');
+reg_t mres = (reg_t)P_W(RS1, 0) * P_W(RS2, 0);
+reg_t rd = P_W(RD, 0);
+rd -= mres;
+WRITE_RD(sext_xlen((int32_t)rd)); \ No newline at end of file
diff --git a/riscv/insns/mulr64.h b/riscv/insns/mulr64.h
new file mode 100644
index 0000000..d2f807a
--- /dev/null
+++ b/riscv/insns/mulr64.h
@@ -0,0 +1,3 @@
+require_extension('P');
+reg_t rd = (reg_t)P_W(RS1, 0) * P_W(RS2, 0);
+P_64_PROFILE_END(); \ No newline at end of file
diff --git a/riscv/insns/mulsr64.h b/riscv/insns/mulsr64.h
new file mode 100644
index 0000000..2cc0e17
--- /dev/null
+++ b/riscv/insns/mulsr64.h
@@ -0,0 +1,3 @@
+require_extension('P');
+sreg_t rd = (sreg_t)P_SW(RS1, 0) * P_SW(RS2, 0);
+P_64_PROFILE_END(); \ No newline at end of file
diff --git a/riscv/insns/pbsad.h b/riscv/insns/pbsad.h
new file mode 100644
index 0000000..71f5aeb
--- /dev/null
+++ b/riscv/insns/pbsad.h
@@ -0,0 +1,3 @@
+P_REDUCTION_ULOOP(64, 8, false, false, {
+ pd_res += (ps1 > ps2 ? ps1 - ps2 : ps2 - ps1);
+}) \ No newline at end of file
diff --git a/riscv/insns/pbsada.h b/riscv/insns/pbsada.h
new file mode 100644
index 0000000..a8e1f46
--- /dev/null
+++ b/riscv/insns/pbsada.h
@@ -0,0 +1,3 @@
+P_REDUCTION_ULOOP(64, 8, true, false, {
+ pd_res += (ps1 > ps2 ? ps1 - ps2 : ps2 - ps1);
+}) \ No newline at end of file
diff --git a/riscv/insns/pkbb16.h b/riscv/insns/pkbb16.h
new file mode 100644
index 0000000..06283cf
--- /dev/null
+++ b/riscv/insns/pkbb16.h
@@ -0,0 +1 @@
+P_PK(16, 0, 0); \ No newline at end of file
diff --git a/riscv/insns/pkbb32.h b/riscv/insns/pkbb32.h
new file mode 100644
index 0000000..2b7ab37
--- /dev/null
+++ b/riscv/insns/pkbb32.h
@@ -0,0 +1,2 @@
+require_rv64;
+P_PK(32, 0, 0); \ No newline at end of file
diff --git a/riscv/insns/pkbt16.h b/riscv/insns/pkbt16.h
new file mode 100644
index 0000000..8247388
--- /dev/null
+++ b/riscv/insns/pkbt16.h
@@ -0,0 +1 @@
+P_PK(16, 0, 1); \ No newline at end of file
diff --git a/riscv/insns/pkbt32.h b/riscv/insns/pkbt32.h
new file mode 100644
index 0000000..426dcdc
--- /dev/null
+++ b/riscv/insns/pkbt32.h
@@ -0,0 +1,2 @@
+require_rv64;
+P_PK(32, 0, 1); \ No newline at end of file
diff --git a/riscv/insns/pktb16.h b/riscv/insns/pktb16.h
new file mode 100644
index 0000000..2925eae
--- /dev/null
+++ b/riscv/insns/pktb16.h
@@ -0,0 +1 @@
+P_PK(16, 1, 0); \ No newline at end of file
diff --git a/riscv/insns/pktb32.h b/riscv/insns/pktb32.h
new file mode 100644
index 0000000..ff98609
--- /dev/null
+++ b/riscv/insns/pktb32.h
@@ -0,0 +1,2 @@
+require_rv64;
+P_PK(32, 1, 0); \ No newline at end of file
diff --git a/riscv/insns/pktt16.h b/riscv/insns/pktt16.h
new file mode 100644
index 0000000..11cca59
--- /dev/null
+++ b/riscv/insns/pktt16.h
@@ -0,0 +1 @@
+P_PK(16, 1, 1); \ No newline at end of file
diff --git a/riscv/insns/pktt32.h b/riscv/insns/pktt32.h
new file mode 100644
index 0000000..49d86ee
--- /dev/null
+++ b/riscv/insns/pktt32.h
@@ -0,0 +1,2 @@
+require_rv64;
+P_PK(32, 1, 1); \ No newline at end of file
diff --git a/riscv/insns/radd16.h b/riscv/insns/radd16.h
new file mode 100644
index 0000000..4195516
--- /dev/null
+++ b/riscv/insns/radd16.h
@@ -0,0 +1,3 @@
+P_LOOP(16, {
+ pd = (ps1 + ps2) >> 1;
+}) \ No newline at end of file
diff --git a/riscv/insns/radd32.h b/riscv/insns/radd32.h
new file mode 100644
index 0000000..ec908e5
--- /dev/null
+++ b/riscv/insns/radd32.h
@@ -0,0 +1,4 @@
+require_rv64;
+P_LOOP(32, {
+ pd = ((int64_t)ps1 + ps2) >> 1;
+}) \ No newline at end of file
diff --git a/riscv/insns/radd64.h b/riscv/insns/radd64.h
new file mode 100644
index 0000000..91c6c24
--- /dev/null
+++ b/riscv/insns/radd64.h
@@ -0,0 +1,8 @@
+P_64_PROFILE({
+ rd = (rs1 + rs2) >> 1;
+ if (rs1 > 0 && rs2 > 0) {
+ rd &= ~((reg_t)1 << 63);
+ } else if (rs1 < 0 && rs2 < 0) {
+ rd |= ((reg_t)1 << 63);
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/radd8.h b/riscv/insns/radd8.h
new file mode 100644
index 0000000..5ac638b
--- /dev/null
+++ b/riscv/insns/radd8.h
@@ -0,0 +1,3 @@
+P_LOOP(8, {
+ pd = (ps1 + ps2) >> 1;
+}) \ No newline at end of file
diff --git a/riscv/insns/raddw.h b/riscv/insns/raddw.h
new file mode 100644
index 0000000..983f33e
--- /dev/null
+++ b/riscv/insns/raddw.h
@@ -0,0 +1,4 @@
+require_extension('P');
+sreg_t res = (sreg_t)P_SW(RS1, 0) + (sreg_t)P_SW(RS2, 0);
+res >>= 1;
+WRITE_RD(sext_xlen(res)); \ No newline at end of file
diff --git a/riscv/insns/rcras16.h b/riscv/insns/rcras16.h
new file mode 100644
index 0000000..6d91eb8
--- /dev/null
+++ b/riscv/insns/rcras16.h
@@ -0,0 +1,5 @@
+P_CROSS_LOOP(16, {
+ pd = (ps1 + ps2) >> 1;
+}, {
+ pd = (ps1 - ps2) >> 1;
+}) \ No newline at end of file
diff --git a/riscv/insns/rcras32.h b/riscv/insns/rcras32.h
new file mode 100644
index 0000000..e9329cc
--- /dev/null
+++ b/riscv/insns/rcras32.h
@@ -0,0 +1,6 @@
+require_rv64;
+P_CROSS_LOOP(32, {
+ pd = ((int64_t)ps1 + ps2) >> 1;
+}, {
+ pd = ((int64_t)ps1 - ps2) >> 1;
+}) \ No newline at end of file
diff --git a/riscv/insns/rcrsa16.h b/riscv/insns/rcrsa16.h
new file mode 100644
index 0000000..a3a74f0
--- /dev/null
+++ b/riscv/insns/rcrsa16.h
@@ -0,0 +1,5 @@
+P_CROSS_LOOP(16, {
+ pd = (ps1 - ps2) >> 1;
+}, {
+ pd = (ps1 + ps2) >> 1;
+}) \ No newline at end of file
diff --git a/riscv/insns/rcrsa32.h b/riscv/insns/rcrsa32.h
new file mode 100644
index 0000000..76cddbc
--- /dev/null
+++ b/riscv/insns/rcrsa32.h
@@ -0,0 +1,6 @@
+require_rv64;
+P_CROSS_LOOP(32, {
+ pd = ((uint64_t)ps1 - ps2) >> 1;
+}, {
+ pd = ((uint64_t)ps1 + ps2) >> 1;
+}) \ No newline at end of file
diff --git a/riscv/insns/rstas16.h b/riscv/insns/rstas16.h
new file mode 100644
index 0000000..cf38442
--- /dev/null
+++ b/riscv/insns/rstas16.h
@@ -0,0 +1,5 @@
+P_STRAIGHT_LOOP(16, {
+ pd = (ps1 + ps2) >> 1;
+}, {
+ pd = (ps1 - ps2) >> 1;
+}) \ No newline at end of file
diff --git a/riscv/insns/rstas32.h b/riscv/insns/rstas32.h
new file mode 100644
index 0000000..f23603f
--- /dev/null
+++ b/riscv/insns/rstas32.h
@@ -0,0 +1,6 @@
+require_rv64;
+P_STRAIGHT_LOOP(32, {
+ pd = ((int64_t)ps1 + ps2) >> 1;
+}, {
+ pd = ((int64_t)ps1 - ps2) >> 1;
+}) \ No newline at end of file
diff --git a/riscv/insns/rstsa16.h b/riscv/insns/rstsa16.h
new file mode 100644
index 0000000..8c0476e
--- /dev/null
+++ b/riscv/insns/rstsa16.h
@@ -0,0 +1,5 @@
+P_STRAIGHT_LOOP(16, {
+ pd = (ps1 - ps2) >> 1;
+}, {
+ pd = (ps1 + ps2) >> 1;
+}) \ No newline at end of file
diff --git a/riscv/insns/rstsa32.h b/riscv/insns/rstsa32.h
new file mode 100644
index 0000000..ee74dab
--- /dev/null
+++ b/riscv/insns/rstsa32.h
@@ -0,0 +1,6 @@
+require_rv64;
+P_STRAIGHT_LOOP(32, {
+ pd = ((int64_t)ps1 - ps2) >> 1;
+}, {
+ pd = ((int64_t)ps1 + ps2) >> 1;
+}) \ No newline at end of file
diff --git a/riscv/insns/rsub16.h b/riscv/insns/rsub16.h
new file mode 100644
index 0000000..27e420d
--- /dev/null
+++ b/riscv/insns/rsub16.h
@@ -0,0 +1,3 @@
+P_LOOP(16, {
+ pd = (ps1 - ps2) >> 1;
+}) \ No newline at end of file
diff --git a/riscv/insns/rsub32.h b/riscv/insns/rsub32.h
new file mode 100644
index 0000000..aaf7862
--- /dev/null
+++ b/riscv/insns/rsub32.h
@@ -0,0 +1,4 @@
+require_rv64;
+P_LOOP(32, {
+ pd = ((int64_t)ps1 - ps2) >> 1;
+}) \ No newline at end of file
diff --git a/riscv/insns/rsub64.h b/riscv/insns/rsub64.h
new file mode 100644
index 0000000..a42e9c1
--- /dev/null
+++ b/riscv/insns/rsub64.h
@@ -0,0 +1,8 @@
+P_64_PROFILE({
+ rd = (rs1 - rs2) >> 1;
+ if (rs1 > 0 && rs2 < 0) {
+ rd &= ~((reg_t)1 << 63);
+ } else if(rs1 < 0 && rs2 > 0) {
+ rd |= ((reg_t)1 << 63);
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/rsub8.h b/riscv/insns/rsub8.h
new file mode 100644
index 0000000..a3bfeb7
--- /dev/null
+++ b/riscv/insns/rsub8.h
@@ -0,0 +1,3 @@
+P_LOOP(8, {
+ pd = (ps1 - ps2) >> 1;
+}) \ No newline at end of file
diff --git a/riscv/insns/rsubw.h b/riscv/insns/rsubw.h
new file mode 100644
index 0000000..89083ad
--- /dev/null
+++ b/riscv/insns/rsubw.h
@@ -0,0 +1,4 @@
+require_extension('P');
+sreg_t res = (sreg_t)P_SW(RS1, 0) - (sreg_t)P_SW(RS2, 0);
+res >>= 1;
+WRITE_RD(sext_xlen(res)); \ No newline at end of file
diff --git a/riscv/insns/sclip16.h b/riscv/insns/sclip16.h
new file mode 100644
index 0000000..6d0e60c
--- /dev/null
+++ b/riscv/insns/sclip16.h
@@ -0,0 +1,13 @@
+P_I_LOOP(16, 4, {
+ int64_t int_max = INT64_MAX >> (64 - (imm4u + 1));
+ int64_t int_min = INT64_MIN >> (64 - (imm4u + 1));
+ pd = ps1;
+
+ if (ps1 > int_max) {
+ pd = int_max;
+ P_SET_OV(1);
+ } else if (ps1 < int_min) {
+ pd = int_min;
+ P_SET_OV(1);
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/sclip32.h b/riscv/insns/sclip32.h
new file mode 100644
index 0000000..0d7793b
--- /dev/null
+++ b/riscv/insns/sclip32.h
@@ -0,0 +1,13 @@
+P_I_LOOP(32, 5, {
+ int64_t int_max = INT64_MAX >> (64 - (imm5u + 1));
+ int64_t int_min = INT64_MIN >> (64 - (imm5u + 1));
+ pd = ps1;
+
+ if (ps1 > int_max) {
+ pd = int_max;
+ P_SET_OV(1);
+ } else if (ps1 < int_min) {
+ pd = int_min;
+ P_SET_OV(1);
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/sclip8.h b/riscv/insns/sclip8.h
new file mode 100644
index 0000000..f95770f
--- /dev/null
+++ b/riscv/insns/sclip8.h
@@ -0,0 +1,13 @@
+P_I_LOOP(8, 3, {
+ int64_t int_max = INT64_MAX >> (64 - (imm3u + 1));
+ int64_t int_min = INT64_MIN >> (64 - (imm3u + 1));
+ pd = ps1;
+
+ if (ps1 > int_max) {
+ pd = int_max;
+ P_SET_OV(1);
+ } else if (ps1 < int_min) {
+ pd = int_min;
+ P_SET_OV(1);
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/scmple16.h b/riscv/insns/scmple16.h
new file mode 100644
index 0000000..6ee2e15
--- /dev/null
+++ b/riscv/insns/scmple16.h
@@ -0,0 +1,3 @@
+P_LOOP(16, {
+ pd = (ps1 <= ps2) ? -1 : 0;
+}) \ No newline at end of file
diff --git a/riscv/insns/scmple8.h b/riscv/insns/scmple8.h
new file mode 100644
index 0000000..1540cb1
--- /dev/null
+++ b/riscv/insns/scmple8.h
@@ -0,0 +1,3 @@
+P_LOOP(8, {
+ pd = (ps1 <= ps2) ? -1 : 0;
+}) \ No newline at end of file
diff --git a/riscv/insns/scmplt16.h b/riscv/insns/scmplt16.h
new file mode 100644
index 0000000..ad34ae0
--- /dev/null
+++ b/riscv/insns/scmplt16.h
@@ -0,0 +1,3 @@
+P_LOOP(16, {
+ pd = (ps1 < ps2) ? -1 : 0;
+}) \ No newline at end of file
diff --git a/riscv/insns/scmplt8.h b/riscv/insns/scmplt8.h
new file mode 100644
index 0000000..df17dff
--- /dev/null
+++ b/riscv/insns/scmplt8.h
@@ -0,0 +1,3 @@
+P_LOOP(8, {
+ pd = (ps1 < ps2) ? -1 : 0;
+}) \ No newline at end of file
diff --git a/riscv/insns/sll16.h b/riscv/insns/sll16.h
new file mode 100644
index 0000000..66b81eb
--- /dev/null
+++ b/riscv/insns/sll16.h
@@ -0,0 +1,3 @@
+P_X_ULOOP(16, 4, {
+ pd = ps1 << sa;
+}) \ No newline at end of file
diff --git a/riscv/insns/sll32.h b/riscv/insns/sll32.h
new file mode 100644
index 0000000..b19be32
--- /dev/null
+++ b/riscv/insns/sll32.h
@@ -0,0 +1,4 @@
+require_rv64;
+P_X_ULOOP(32, 5, {
+ pd = ps1 << sa;
+}) \ No newline at end of file
diff --git a/riscv/insns/sll8.h b/riscv/insns/sll8.h
new file mode 100644
index 0000000..7a36b3c
--- /dev/null
+++ b/riscv/insns/sll8.h
@@ -0,0 +1,3 @@
+P_X_ULOOP(8, 3, {
+ pd = ps1 << sa;
+}) \ No newline at end of file
diff --git a/riscv/insns/slli16.h b/riscv/insns/slli16.h
new file mode 100644
index 0000000..64827d7
--- /dev/null
+++ b/riscv/insns/slli16.h
@@ -0,0 +1,3 @@
+P_I_ULOOP(16, 4, {
+ pd = ps1 << imm4u;
+}) \ No newline at end of file
diff --git a/riscv/insns/slli32.h b/riscv/insns/slli32.h
new file mode 100644
index 0000000..5278586
--- /dev/null
+++ b/riscv/insns/slli32.h
@@ -0,0 +1,4 @@
+require_rv64;
+P_I_ULOOP(32, 5, {
+ pd = ps1 << imm5u;
+}) \ No newline at end of file
diff --git a/riscv/insns/slli8.h b/riscv/insns/slli8.h
new file mode 100644
index 0000000..4e3935c
--- /dev/null
+++ b/riscv/insns/slli8.h
@@ -0,0 +1,3 @@
+P_I_ULOOP(8, 3, {
+ pd = ps1 << imm3u;
+}) \ No newline at end of file
diff --git a/riscv/insns/smal.h b/riscv/insns/smal.h
new file mode 100644
index 0000000..121e4dc
--- /dev/null
+++ b/riscv/insns/smal.h
@@ -0,0 +1,10 @@
+sreg_t res = 0;
+if (xlen == 32) {
+ res = RS1_PAIR;
+ res += sext_xlen(P_SH(RS2, 0) * P_SH(RS2, 1));
+ WRITE_RD_PAIR(res);
+} else {
+ res = sext_xlen(P_SH(RS2, 0) * P_SH(RS2, 1)) +
+ sext_xlen(P_SH(RS2, 2) * P_SH(RS2, 3)) + RS1;
+ WRITE_RD(res);
+} \ No newline at end of file
diff --git a/riscv/insns/smalbb.h b/riscv/insns/smalbb.h
new file mode 100644
index 0000000..4178c2b
--- /dev/null
+++ b/riscv/insns/smalbb.h
@@ -0,0 +1,3 @@
+P_64_PROFILE_REDUCTION(32, {
+ rd += (sreg_t)P_SH(ps1, 0) * (sreg_t)P_SH(ps2, 0);
+}) \ No newline at end of file
diff --git a/riscv/insns/smalbt.h b/riscv/insns/smalbt.h
new file mode 100644
index 0000000..dab9f7a
--- /dev/null
+++ b/riscv/insns/smalbt.h
@@ -0,0 +1,3 @@
+P_64_PROFILE_REDUCTION(32, {
+ rd += (sreg_t)P_SH(ps1, 0) * (sreg_t)P_SH(ps2, 1);
+}) \ No newline at end of file
diff --git a/riscv/insns/smalda.h b/riscv/insns/smalda.h
new file mode 100644
index 0000000..95b16b1
--- /dev/null
+++ b/riscv/insns/smalda.h
@@ -0,0 +1,3 @@
+P_64_PROFILE_REDUCTION(16, {
+ rd += ps1 * ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/smaldrs.h b/riscv/insns/smaldrs.h
new file mode 100644
index 0000000..8ce8c9b
--- /dev/null
+++ b/riscv/insns/smaldrs.h
@@ -0,0 +1,7 @@
+P_64_PROFILE_REDUCTION(16, {
+ if (i & 1) {
+ rd -= ps1 * ps2;
+ } else {
+ rd += ps1 * ps2;
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/smalds.h b/riscv/insns/smalds.h
new file mode 100644
index 0000000..352fa1f
--- /dev/null
+++ b/riscv/insns/smalds.h
@@ -0,0 +1,7 @@
+P_64_PROFILE_REDUCTION(16, {
+ if (i & 1) {
+ rd += ps1 * ps2;
+ } else {
+ rd -= ps1 * ps2;
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/smaltt.h b/riscv/insns/smaltt.h
new file mode 100644
index 0000000..72d5133
--- /dev/null
+++ b/riscv/insns/smaltt.h
@@ -0,0 +1,3 @@
+P_64_PROFILE_REDUCTION(32, {
+ rd += P_SH(ps1, 1) * P_SH(ps2, 1);
+}) \ No newline at end of file
diff --git a/riscv/insns/smalxda.h b/riscv/insns/smalxda.h
new file mode 100644
index 0000000..b5fa1d0
--- /dev/null
+++ b/riscv/insns/smalxda.h
@@ -0,0 +1,4 @@
+P_64_PROFILE_REDUCTION(32, {
+ rd += (sreg_t)P_SH(ps1, 0) * (sreg_t)P_SH(ps2, 1);
+ rd += (sreg_t)P_SH(ps1, 1) * (sreg_t)P_SH(ps2, 0);
+}) \ No newline at end of file
diff --git a/riscv/insns/smalxds.h b/riscv/insns/smalxds.h
new file mode 100644
index 0000000..3f3c6bd
--- /dev/null
+++ b/riscv/insns/smalxds.h
@@ -0,0 +1,4 @@
+P_64_PROFILE_REDUCTION(32, {
+ rd += (sreg_t)P_SH(ps1, 1) * (sreg_t)P_SH(ps2, 0);
+ rd -= (sreg_t)P_SH(ps1, 0) * (sreg_t)P_SH(ps2, 1);
+}) \ No newline at end of file
diff --git a/riscv/insns/smaqa.h b/riscv/insns/smaqa.h
new file mode 100644
index 0000000..33c9df0
--- /dev/null
+++ b/riscv/insns/smaqa.h
@@ -0,0 +1,3 @@
+P_REDUCTION_LOOP(32, 8, true, false, {
+ pd_res += ps1 * ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/smaqa_su.h b/riscv/insns/smaqa_su.h
new file mode 100644
index 0000000..7af3386
--- /dev/null
+++ b/riscv/insns/smaqa_su.h
@@ -0,0 +1,3 @@
+P_REDUCTION_SULOOP(32, 8, true, false, {
+ pd_res += ps1 * ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/smar64.h b/riscv/insns/smar64.h
new file mode 100644
index 0000000..bc87d4f
--- /dev/null
+++ b/riscv/insns/smar64.h
@@ -0,0 +1,3 @@
+P_64_PROFILE_REDUCTION(32, {
+ rd += ps1 * ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/smax16.h b/riscv/insns/smax16.h
new file mode 100644
index 0000000..eac4eb4
--- /dev/null
+++ b/riscv/insns/smax16.h
@@ -0,0 +1,3 @@
+P_LOOP(16, {
+ pd = (ps1 > ps2) ? ps1 : ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/smax32.h b/riscv/insns/smax32.h
new file mode 100644
index 0000000..b0b0075
--- /dev/null
+++ b/riscv/insns/smax32.h
@@ -0,0 +1,3 @@
+P_LOOP(32, {
+ pd = (ps1 > ps2) ? ps1 : ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/smax8.h b/riscv/insns/smax8.h
new file mode 100644
index 0000000..86303c7
--- /dev/null
+++ b/riscv/insns/smax8.h
@@ -0,0 +1,3 @@
+P_LOOP(8, {
+ pd = (ps1 > ps2) ? ps1 : ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/smbb16.h b/riscv/insns/smbb16.h
new file mode 100644
index 0000000..d7e82b4
--- /dev/null
+++ b/riscv/insns/smbb16.h
@@ -0,0 +1,3 @@
+P_LOOP(32, {
+ pd = P_SH(ps1, 0) * P_SH(ps2, 0);
+}) \ No newline at end of file
diff --git a/riscv/insns/smbt16.h b/riscv/insns/smbt16.h
new file mode 100644
index 0000000..55e90c6
--- /dev/null
+++ b/riscv/insns/smbt16.h
@@ -0,0 +1,3 @@
+P_LOOP(32, {
+ pd = P_SH(ps1, 0) * P_SH(ps2, 1);
+}) \ No newline at end of file
diff --git a/riscv/insns/smbt32.h b/riscv/insns/smbt32.h
new file mode 100644
index 0000000..1d16755
--- /dev/null
+++ b/riscv/insns/smbt32.h
@@ -0,0 +1,3 @@
+require_rv64;
+require_extension('P');
+WRITE_RD((sreg_t)P_SW(RS1, 0) * P_SW(RS2, 1)); \ No newline at end of file
diff --git a/riscv/insns/smdrs.h b/riscv/insns/smdrs.h
new file mode 100644
index 0000000..2837a0c
--- /dev/null
+++ b/riscv/insns/smdrs.h
@@ -0,0 +1,6 @@
+P_REDUCTION_LOOP(32, 16, false, false, {
+ if (j & 1)
+ pd_res -= ps1 * ps2;
+ else
+ pd_res += ps1 * ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/smdrs32.h b/riscv/insns/smdrs32.h
new file mode 100644
index 0000000..53ac516
--- /dev/null
+++ b/riscv/insns/smdrs32.h
@@ -0,0 +1,7 @@
+require_rv64;
+require_extension('P');
+
+sreg_t mres0 = (sreg_t)P_SW(RS1, 0) * P_SW(RS2, 0);
+sreg_t mres1 = (sreg_t)P_SW(RS1, 1) * P_SW(RS2, 1);
+
+WRITE_RD(mres0 - mres1); \ No newline at end of file
diff --git a/riscv/insns/smds.h b/riscv/insns/smds.h
new file mode 100644
index 0000000..214ac34
--- /dev/null
+++ b/riscv/insns/smds.h
@@ -0,0 +1,6 @@
+P_REDUCTION_LOOP(32, 16, false, false, {
+ if (j & 1)
+ pd_res += ps1 * ps2;
+ else
+ pd_res -= ps1 * ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/smds32.h b/riscv/insns/smds32.h
new file mode 100644
index 0000000..97440a5
--- /dev/null
+++ b/riscv/insns/smds32.h
@@ -0,0 +1,7 @@
+require_rv64;
+require_extension('P');
+
+sreg_t mres0 = (sreg_t)P_SW(RS1, 0) * P_SW(RS2, 0);
+sreg_t mres1 = (sreg_t)P_SW(RS1, 1) * P_SW(RS2, 1);
+
+WRITE_RD(mres1 - mres0); \ No newline at end of file
diff --git a/riscv/insns/smin16.h b/riscv/insns/smin16.h
new file mode 100644
index 0000000..921cccb
--- /dev/null
+++ b/riscv/insns/smin16.h
@@ -0,0 +1,3 @@
+P_LOOP(16, {
+ pd = (ps1 < ps2) ? ps1 : ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/smin32.h b/riscv/insns/smin32.h
new file mode 100644
index 0000000..c1d0cfa
--- /dev/null
+++ b/riscv/insns/smin32.h
@@ -0,0 +1,3 @@
+P_LOOP(32, {
+ pd = (ps1 < ps2) ? ps1 : ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/smin8.h b/riscv/insns/smin8.h
new file mode 100644
index 0000000..04bd43a
--- /dev/null
+++ b/riscv/insns/smin8.h
@@ -0,0 +1,3 @@
+P_LOOP(8, {
+ pd = (ps1 < ps2) ? ps1 : ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/smmul.h b/riscv/insns/smmul.h
new file mode 100644
index 0000000..c305648
--- /dev/null
+++ b/riscv/insns/smmul.h
@@ -0,0 +1,4 @@
+P_LOOP(32, {
+ int64_t mres = (int64_t) ps1 * (int64_t) ps2;
+ pd = mres >> 32;
+}) \ No newline at end of file
diff --git a/riscv/insns/smmul_u.h b/riscv/insns/smmul_u.h
new file mode 100644
index 0000000..a41ceb7
--- /dev/null
+++ b/riscv/insns/smmul_u.h
@@ -0,0 +1,4 @@
+P_LOOP(32, {
+ int64_t mres = (int64_t) ps1 * (int64_t) ps2;
+ pd = ((mres >> 31) + 1) >> 1;
+}) \ No newline at end of file
diff --git a/riscv/insns/smmwb.h b/riscv/insns/smmwb.h
new file mode 100644
index 0000000..5e798f2
--- /dev/null
+++ b/riscv/insns/smmwb.h
@@ -0,0 +1,4 @@
+P_LOOP(32, {
+ int64_t mres = (int64_t) ps1 * (int16_t) P_H(ps2, 0);
+ pd = mres >> 16;
+}) \ No newline at end of file
diff --git a/riscv/insns/smmwb_u.h b/riscv/insns/smmwb_u.h
new file mode 100644
index 0000000..9ea1e49
--- /dev/null
+++ b/riscv/insns/smmwb_u.h
@@ -0,0 +1,4 @@
+P_LOOP(32, {
+ int64_t mres = (int64_t) ps1 * (int16_t) P_H(ps2, 0);
+ pd = ((mres >> 15) + 1) >> 1;
+}) \ No newline at end of file
diff --git a/riscv/insns/smmwt.h b/riscv/insns/smmwt.h
new file mode 100644
index 0000000..0f88ce1
--- /dev/null
+++ b/riscv/insns/smmwt.h
@@ -0,0 +1,4 @@
+P_LOOP(32, {
+ int64_t mres = (int64_t) ps1 * (int16_t) P_H(ps2, 1);
+ pd = mres >> 16;
+}) \ No newline at end of file
diff --git a/riscv/insns/smmwt_u.h b/riscv/insns/smmwt_u.h
new file mode 100644
index 0000000..97e6d64
--- /dev/null
+++ b/riscv/insns/smmwt_u.h
@@ -0,0 +1,4 @@
+P_LOOP(32, {
+ int64_t mres = (int64_t) ps1 * (int16_t) P_H(ps2, 1);
+ pd = ((mres >> 15) + 1) >> 1;
+}) \ No newline at end of file
diff --git a/riscv/insns/smslda.h b/riscv/insns/smslda.h
new file mode 100644
index 0000000..eba5727
--- /dev/null
+++ b/riscv/insns/smslda.h
@@ -0,0 +1,3 @@
+P_64_PROFILE_REDUCTION(16, {
+ rd -= ps1 * ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/smslxda.h b/riscv/insns/smslxda.h
new file mode 100644
index 0000000..5e2c43d
--- /dev/null
+++ b/riscv/insns/smslxda.h
@@ -0,0 +1,4 @@
+P_64_PROFILE_REDUCTION(32, {
+ rd -= (sreg_t)P_SH(ps1, 1) * (sreg_t)P_SH(ps2, 0);
+ rd -= (sreg_t)P_SH(ps1, 0) * (sreg_t)P_SH(ps2, 1);
+}) \ No newline at end of file
diff --git a/riscv/insns/smsr64.h b/riscv/insns/smsr64.h
new file mode 100644
index 0000000..cc44fc5
--- /dev/null
+++ b/riscv/insns/smsr64.h
@@ -0,0 +1,3 @@
+P_64_PROFILE_REDUCTION(32, {
+ rd -= ps1 * ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/smtt16.h b/riscv/insns/smtt16.h
new file mode 100644
index 0000000..bbc5039
--- /dev/null
+++ b/riscv/insns/smtt16.h
@@ -0,0 +1,3 @@
+P_LOOP(32, {
+ pd = P_SH(ps1, 1) * P_SH(ps2, 1);
+}) \ No newline at end of file
diff --git a/riscv/insns/smtt32.h b/riscv/insns/smtt32.h
new file mode 100644
index 0000000..beb45d8
--- /dev/null
+++ b/riscv/insns/smtt32.h
@@ -0,0 +1,3 @@
+require_rv64;
+require_extension('P');
+WRITE_RD((sreg_t)P_SW(RS1, 1) * P_SW(RS2, 1)); \ No newline at end of file
diff --git a/riscv/insns/smul16.h b/riscv/insns/smul16.h
new file mode 100644
index 0000000..4ec914b
--- /dev/null
+++ b/riscv/insns/smul16.h
@@ -0,0 +1,3 @@
+P_MUL_LOOP(16, {
+ pd = ps1 * ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/smul8.h b/riscv/insns/smul8.h
new file mode 100644
index 0000000..ee01391
--- /dev/null
+++ b/riscv/insns/smul8.h
@@ -0,0 +1,3 @@
+P_MUL_LOOP(8, {
+ pd = ps1 * ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/smulx16.h b/riscv/insns/smulx16.h
new file mode 100644
index 0000000..623cb06
--- /dev/null
+++ b/riscv/insns/smulx16.h
@@ -0,0 +1,3 @@
+P_MUL_CROSS_LOOP(16, {
+ pd = ps1 * ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/smulx8.h b/riscv/insns/smulx8.h
new file mode 100644
index 0000000..d11614d
--- /dev/null
+++ b/riscv/insns/smulx8.h
@@ -0,0 +1,3 @@
+P_MUL_CROSS_LOOP(8, {
+ pd = ps1 * ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/smxds.h b/riscv/insns/smxds.h
new file mode 100644
index 0000000..49b720b
--- /dev/null
+++ b/riscv/insns/smxds.h
@@ -0,0 +1,6 @@
+P_REDUCTION_CROSS_LOOP(32, 16, false, false, {
+ if (j & 1)
+ pd_res += ps1 * ps2;
+ else
+ pd_res -= ps1 * ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/smxds32.h b/riscv/insns/smxds32.h
new file mode 100644
index 0000000..25b1666
--- /dev/null
+++ b/riscv/insns/smxds32.h
@@ -0,0 +1,7 @@
+require_rv64;
+require_extension('P');
+
+sreg_t mres0 = (sreg_t)P_SW(RS1, 0) * P_SW(RS2, 1);
+sreg_t mres1 = (sreg_t)P_SW(RS1, 1) * P_SW(RS2, 0);
+
+WRITE_RD(mres1 - mres0); \ No newline at end of file
diff --git a/riscv/insns/sra16.h b/riscv/insns/sra16.h
new file mode 100644
index 0000000..bdc9c5f
--- /dev/null
+++ b/riscv/insns/sra16.h
@@ -0,0 +1,3 @@
+P_X_LOOP(16, 4, {
+ pd = ps1 >> sa;
+}) \ No newline at end of file
diff --git a/riscv/insns/sra16_u.h b/riscv/insns/sra16_u.h
new file mode 100644
index 0000000..44ebbc3
--- /dev/null
+++ b/riscv/insns/sra16_u.h
@@ -0,0 +1,6 @@
+P_X_LOOP(16, 4, {
+ if(sa > 0)
+ pd = ((ps1 >> (sa - 1)) + 1) >> 1;
+ else
+ pd = ps1;
+}) \ No newline at end of file
diff --git a/riscv/insns/sra32.h b/riscv/insns/sra32.h
new file mode 100644
index 0000000..53a8c07
--- /dev/null
+++ b/riscv/insns/sra32.h
@@ -0,0 +1,4 @@
+require_rv64;
+P_X_LOOP(32, 5, {
+ pd = ps1 >> sa;
+}) \ No newline at end of file
diff --git a/riscv/insns/sra32_u.h b/riscv/insns/sra32_u.h
new file mode 100644
index 0000000..c0ce87f
--- /dev/null
+++ b/riscv/insns/sra32_u.h
@@ -0,0 +1,7 @@
+require_rv64;
+P_X_LOOP(32, 5, {
+ if(sa > 0)
+ pd = ((ps1 >> (sa - 1)) + 1) >> 1;
+ else
+ pd = ps1;
+}) \ No newline at end of file
diff --git a/riscv/insns/sra8.h b/riscv/insns/sra8.h
new file mode 100644
index 0000000..c92e497
--- /dev/null
+++ b/riscv/insns/sra8.h
@@ -0,0 +1,3 @@
+P_X_LOOP(8, 3, {
+ pd = ps1 >> sa;
+}) \ No newline at end of file
diff --git a/riscv/insns/sra8_u.h b/riscv/insns/sra8_u.h
new file mode 100644
index 0000000..e53736a
--- /dev/null
+++ b/riscv/insns/sra8_u.h
@@ -0,0 +1,6 @@
+P_X_LOOP(8, 3, {
+ if(sa > 0)
+ pd = ((ps1 >> (sa - 1)) + 1) >> 1;
+ else
+ pd = ps1;
+}) \ No newline at end of file
diff --git a/riscv/insns/sra_u.h b/riscv/insns/sra_u.h
new file mode 100644
index 0000000..8efb031
--- /dev/null
+++ b/riscv/insns/sra_u.h
@@ -0,0 +1,9 @@
+require_extension('P');
+sreg_t rs1 = sext_xlen(RS1);
+reg_t sa = get_field(RS2, make_mask64(0, xlen == 32 ? 5 : 6));
+
+if (sa > 0) {
+ WRITE_RD(sext_xlen(((rs1 >> (sa - 1)) + 1) >> 1));
+} else {
+ WRITE_RD(sext_xlen(rs1));
+} \ No newline at end of file
diff --git a/riscv/insns/srai16.h b/riscv/insns/srai16.h
new file mode 100644
index 0000000..57fbdc3
--- /dev/null
+++ b/riscv/insns/srai16.h
@@ -0,0 +1,3 @@
+P_I_LOOP(16, 4, {
+ pd = ps1 >> imm4u;
+}) \ No newline at end of file
diff --git a/riscv/insns/srai16_u.h b/riscv/insns/srai16_u.h
new file mode 100644
index 0000000..b34bb00
--- /dev/null
+++ b/riscv/insns/srai16_u.h
@@ -0,0 +1,6 @@
+P_I_LOOP(16, 4, {
+ if (imm4u > 0)
+ pd = ((ps1 >> (imm4u - 1)) + 1) >> 1;
+ else
+ pd = ps1;
+}) \ No newline at end of file
diff --git a/riscv/insns/srai32.h b/riscv/insns/srai32.h
new file mode 100644
index 0000000..85172cf
--- /dev/null
+++ b/riscv/insns/srai32.h
@@ -0,0 +1,4 @@
+require_rv64;
+P_I_LOOP(32, 5, {
+ pd = ps1 >> imm5u;
+}) \ No newline at end of file
diff --git a/riscv/insns/srai32_u.h b/riscv/insns/srai32_u.h
new file mode 100644
index 0000000..5c7b06c
--- /dev/null
+++ b/riscv/insns/srai32_u.h
@@ -0,0 +1,7 @@
+require_rv64;
+P_I_LOOP(32, 5, {
+ if (imm5u > 0)
+ pd = ((ps1 >> (imm5u - 1)) + 1) >> 1;
+ else
+ pd = ps1;
+}) \ No newline at end of file
diff --git a/riscv/insns/srai8.h b/riscv/insns/srai8.h
new file mode 100644
index 0000000..d6f003d
--- /dev/null
+++ b/riscv/insns/srai8.h
@@ -0,0 +1,3 @@
+P_I_LOOP(8, 3, {
+ pd = ps1 >> imm3u;
+}) \ No newline at end of file
diff --git a/riscv/insns/srai8_u.h b/riscv/insns/srai8_u.h
new file mode 100644
index 0000000..c2970ed
--- /dev/null
+++ b/riscv/insns/srai8_u.h
@@ -0,0 +1,6 @@
+P_I_LOOP(8, 3, {
+ if (imm3u > 0)
+ pd = ((ps1 >> (imm3u - 1)) + 1) >> 1;
+ else
+ pd = ps1;
+}) \ No newline at end of file
diff --git a/riscv/insns/srai_u.h b/riscv/insns/srai_u.h
new file mode 100644
index 0000000..0655c6c
--- /dev/null
+++ b/riscv/insns/srai_u.h
@@ -0,0 +1,9 @@
+require_extension('P');
+sreg_t rs1 = sext_xlen(RS1);
+reg_t sa = xlen == 32 ? insn.p_imm5() : insn.p_imm6();
+
+if (sa > 0) {
+ WRITE_RD(sext_xlen(((rs1 >> (sa - 1)) + 1) >> 1));
+} else {
+ WRITE_RD(sext_xlen(rs1));
+} \ No newline at end of file
diff --git a/riscv/insns/sraiw_u.h b/riscv/insns/sraiw_u.h
new file mode 100644
index 0000000..dd26707
--- /dev/null
+++ b/riscv/insns/sraiw_u.h
@@ -0,0 +1,9 @@
+require_rv64;
+require_extension('P');
+
+reg_t sa = insn.p_imm5();
+if (sa != 0) {
+ WRITE_RD(sext32(((P_SW(RS1, 0) >> (sa - 1)) + 1) >> 1));
+} else {
+ WRITE_RD(sext32(P_SW(RS1, 0)));
+} \ No newline at end of file
diff --git a/riscv/insns/srl16.h b/riscv/insns/srl16.h
new file mode 100644
index 0000000..dede8e3
--- /dev/null
+++ b/riscv/insns/srl16.h
@@ -0,0 +1,3 @@
+P_X_ULOOP(16, 4, {
+ pd = ps1 >> sa;
+}) \ No newline at end of file
diff --git a/riscv/insns/srl16_u.h b/riscv/insns/srl16_u.h
new file mode 100644
index 0000000..f7b0571
--- /dev/null
+++ b/riscv/insns/srl16_u.h
@@ -0,0 +1,7 @@
+P_X_ULOOP(16, 4, {
+ if (sa > 0) {
+ pd = ((ps1 >> (sa - 1)) + 1) >> 1;
+ } else {
+ pd = ps1;
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/srl32.h b/riscv/insns/srl32.h
new file mode 100644
index 0000000..c50522f
--- /dev/null
+++ b/riscv/insns/srl32.h
@@ -0,0 +1,4 @@
+require_rv64;
+P_X_ULOOP(32, 5, {
+ pd = ps1 >> sa;
+}) \ No newline at end of file
diff --git a/riscv/insns/srl32_u.h b/riscv/insns/srl32_u.h
new file mode 100644
index 0000000..3c770d5
--- /dev/null
+++ b/riscv/insns/srl32_u.h
@@ -0,0 +1,8 @@
+require_rv64;
+P_X_ULOOP(32, 5, {
+ if (sa > 0) {
+ pd = ((ps1 >> (sa - 1)) + 1) >> 1;
+ } else {
+ pd = ps1;
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/srl8.h b/riscv/insns/srl8.h
new file mode 100644
index 0000000..f5891fa
--- /dev/null
+++ b/riscv/insns/srl8.h
@@ -0,0 +1,3 @@
+P_X_ULOOP(8, 3, {
+ pd = ps1 >> sa;
+}) \ No newline at end of file
diff --git a/riscv/insns/srl8_u.h b/riscv/insns/srl8_u.h
new file mode 100644
index 0000000..956d260
--- /dev/null
+++ b/riscv/insns/srl8_u.h
@@ -0,0 +1,7 @@
+P_X_ULOOP(8, 3, {
+ if (sa > 0) {
+ pd = ((ps1 >> (sa - 1)) + 1) >> 1;
+ } else {
+ pd = ps1;
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/srli16.h b/riscv/insns/srli16.h
new file mode 100644
index 0000000..0ad3cb4
--- /dev/null
+++ b/riscv/insns/srli16.h
@@ -0,0 +1,3 @@
+P_I_ULOOP(16, 4, {
+ pd = ps1 >> imm4u;
+}) \ No newline at end of file
diff --git a/riscv/insns/srli16_u.h b/riscv/insns/srli16_u.h
new file mode 100644
index 0000000..4eb9248
--- /dev/null
+++ b/riscv/insns/srli16_u.h
@@ -0,0 +1,7 @@
+P_I_ULOOP(16, 4, {
+ if (imm4u > 0) {
+ pd = ((ps1 >> (imm4u - 1)) + 1) >> 1;
+ } else {
+ pd = ps1;
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/srli32.h b/riscv/insns/srli32.h
new file mode 100644
index 0000000..f5d229c
--- /dev/null
+++ b/riscv/insns/srli32.h
@@ -0,0 +1,4 @@
+require_rv64;
+P_I_ULOOP(32, 5, {
+ pd = ps1 >> imm5u;
+}) \ No newline at end of file
diff --git a/riscv/insns/srli32_u.h b/riscv/insns/srli32_u.h
new file mode 100644
index 0000000..8aa9c1b
--- /dev/null
+++ b/riscv/insns/srli32_u.h
@@ -0,0 +1,8 @@
+require_rv64;
+P_I_ULOOP(32, 5, {
+ if (imm5u > 0) {
+ pd = ((ps1 >> (imm5u - 1)) + 1) >> 1;
+ } else {
+ pd = ps1;
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/srli8.h b/riscv/insns/srli8.h
new file mode 100644
index 0000000..bf64250
--- /dev/null
+++ b/riscv/insns/srli8.h
@@ -0,0 +1,3 @@
+P_I_ULOOP(8, 3, {
+ pd = ps1 >> imm3u;
+}) \ No newline at end of file
diff --git a/riscv/insns/srli8_u.h b/riscv/insns/srli8_u.h
new file mode 100644
index 0000000..1154177
--- /dev/null
+++ b/riscv/insns/srli8_u.h
@@ -0,0 +1,7 @@
+P_I_ULOOP(8, 3, {
+ if (imm3u > 0) {
+ pd = ((ps1 >> (imm3u - 1)) + 1) >> 1;
+ } else {
+ pd = ps1;
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/stas16.h b/riscv/insns/stas16.h
new file mode 100644
index 0000000..7cea5ae
--- /dev/null
+++ b/riscv/insns/stas16.h
@@ -0,0 +1,5 @@
+P_STRAIGHT_LOOP(16, {
+ pd = ps1 + ps2;
+}, {
+ pd = ps1 - ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/stas32.h b/riscv/insns/stas32.h
new file mode 100644
index 0000000..fad20f0
--- /dev/null
+++ b/riscv/insns/stas32.h
@@ -0,0 +1,6 @@
+require_rv64;
+P_STRAIGHT_LOOP(32, {
+ pd = ps1 + ps2;
+}, {
+ pd = ps1 - ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/stsa16.h b/riscv/insns/stsa16.h
new file mode 100644
index 0000000..9ca05ab
--- /dev/null
+++ b/riscv/insns/stsa16.h
@@ -0,0 +1,5 @@
+P_STRAIGHT_LOOP(16, {
+ pd = ps1 - ps2;
+}, {
+ pd = ps1 + ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/stsa32.h b/riscv/insns/stsa32.h
new file mode 100644
index 0000000..b6be39a
--- /dev/null
+++ b/riscv/insns/stsa32.h
@@ -0,0 +1,6 @@
+require_rv64;
+P_STRAIGHT_LOOP(32, {
+ pd = ps1 - ps2;
+}, {
+ pd = ps1 + ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/sub16.h b/riscv/insns/sub16.h
new file mode 100644
index 0000000..1bcca23
--- /dev/null
+++ b/riscv/insns/sub16.h
@@ -0,0 +1,3 @@
+P_LOOP(16, {
+ pd = ps1 - ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/sub32.h b/riscv/insns/sub32.h
new file mode 100644
index 0000000..06e645c
--- /dev/null
+++ b/riscv/insns/sub32.h
@@ -0,0 +1,4 @@
+require_rv64;
+P_LOOP(32, {
+ pd = ps1 - ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/sub64.h b/riscv/insns/sub64.h
new file mode 100644
index 0000000..0b747fe
--- /dev/null
+++ b/riscv/insns/sub64.h
@@ -0,0 +1,3 @@
+P_64_PROFILE({
+ rd = rs1 - rs2;
+}) \ No newline at end of file
diff --git a/riscv/insns/sub8.h b/riscv/insns/sub8.h
new file mode 100644
index 0000000..8cdca73
--- /dev/null
+++ b/riscv/insns/sub8.h
@@ -0,0 +1,3 @@
+P_LOOP(8, {
+ pd = ps1 - ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/sunpkd810.h b/riscv/insns/sunpkd810.h
new file mode 100644
index 0000000..b93a981
--- /dev/null
+++ b/riscv/insns/sunpkd810.h
@@ -0,0 +1 @@
+P_SUNPKD8(1, 0) \ No newline at end of file
diff --git a/riscv/insns/sunpkd820.h b/riscv/insns/sunpkd820.h
new file mode 100644
index 0000000..5ded8f6
--- /dev/null
+++ b/riscv/insns/sunpkd820.h
@@ -0,0 +1 @@
+P_SUNPKD8(2, 0) \ No newline at end of file
diff --git a/riscv/insns/sunpkd830.h b/riscv/insns/sunpkd830.h
new file mode 100644
index 0000000..84688c4
--- /dev/null
+++ b/riscv/insns/sunpkd830.h
@@ -0,0 +1 @@
+P_SUNPKD8(3, 0) \ No newline at end of file
diff --git a/riscv/insns/sunpkd831.h b/riscv/insns/sunpkd831.h
new file mode 100644
index 0000000..bf19ef0
--- /dev/null
+++ b/riscv/insns/sunpkd831.h
@@ -0,0 +1 @@
+P_SUNPKD8(3, 1) \ No newline at end of file
diff --git a/riscv/insns/sunpkd832.h b/riscv/insns/sunpkd832.h
new file mode 100644
index 0000000..ae2ce0d
--- /dev/null
+++ b/riscv/insns/sunpkd832.h
@@ -0,0 +1 @@
+P_SUNPKD8(3, 2) \ No newline at end of file
diff --git a/riscv/insns/swap16.h b/riscv/insns/swap16.h
new file mode 100644
index 0000000..2b9f13d
--- /dev/null
+++ b/riscv/insns/swap16.h
@@ -0,0 +1,4 @@
+P_ONE_LOOP_BASE(16)
+auto pd = P_FIELD(rs1, (i ^ 1), 16);
+WRITE_PD();
+P_LOOP_END() \ No newline at end of file
diff --git a/riscv/insns/swap8.h b/riscv/insns/swap8.h
new file mode 100644
index 0000000..d57304d
--- /dev/null
+++ b/riscv/insns/swap8.h
@@ -0,0 +1,4 @@
+P_ONE_LOOP_BASE(8)
+auto pd = P_FIELD(rs1, (i ^ 1), 8);
+WRITE_PD();
+P_LOOP_END() \ No newline at end of file
diff --git a/riscv/insns/uclip16.h b/riscv/insns/uclip16.h
new file mode 100644
index 0000000..faf57ca
--- /dev/null
+++ b/riscv/insns/uclip16.h
@@ -0,0 +1,12 @@
+P_I_LOOP(16, 4, {
+ int64_t uint_max = imm4u ? UINT64_MAX >> (64 - imm4u) : 0;
+ pd = ps1;
+
+ if (ps1 > uint_max) {
+ pd = uint_max;
+ P_SET_OV(1);
+ } else if (ps1 < 0) {
+ pd = 0;
+ P_SET_OV(1);
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/uclip32.h b/riscv/insns/uclip32.h
new file mode 100644
index 0000000..f5d89ad
--- /dev/null
+++ b/riscv/insns/uclip32.h
@@ -0,0 +1,12 @@
+P_I_LOOP(32, 5, {
+ int64_t uint_max = imm5u ? UINT64_MAX >> (64 - imm5u) : 0;
+ pd = ps1;
+
+ if (ps1 > uint_max) {
+ pd = uint_max;
+ P_SET_OV(1);
+ } else if (ps1 < 0) {
+ pd = 0;
+ P_SET_OV(1);
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/uclip8.h b/riscv/insns/uclip8.h
new file mode 100644
index 0000000..e2978a6
--- /dev/null
+++ b/riscv/insns/uclip8.h
@@ -0,0 +1,12 @@
+P_I_LOOP(8, 3, {
+ int64_t uint_max = imm3u ? UINT64_MAX >> (64 - imm3u) : 0;
+ pd = ps1;
+
+ if (ps1 > uint_max) {
+ pd = uint_max;
+ P_SET_OV(1);
+ } else if (ps1 < 0) {
+ pd = 0;
+ P_SET_OV(1);
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/ucmple16.h b/riscv/insns/ucmple16.h
new file mode 100644
index 0000000..b3ba04d
--- /dev/null
+++ b/riscv/insns/ucmple16.h
@@ -0,0 +1,3 @@
+P_ULOOP(16, {
+ pd = (ps1 <= ps2) ? -1 : 0;
+}) \ No newline at end of file
diff --git a/riscv/insns/ucmple8.h b/riscv/insns/ucmple8.h
new file mode 100644
index 0000000..78f12b8
--- /dev/null
+++ b/riscv/insns/ucmple8.h
@@ -0,0 +1,3 @@
+P_ULOOP(8, {
+ pd = (ps1 <= ps2) ? -1 : 0;
+}) \ No newline at end of file
diff --git a/riscv/insns/ucmplt16.h b/riscv/insns/ucmplt16.h
new file mode 100644
index 0000000..fca78a8
--- /dev/null
+++ b/riscv/insns/ucmplt16.h
@@ -0,0 +1,3 @@
+P_ULOOP(16, {
+ pd = (ps1 < ps2) ? -1 : 0;
+}) \ No newline at end of file
diff --git a/riscv/insns/ucmplt8.h b/riscv/insns/ucmplt8.h
new file mode 100644
index 0000000..0ebdf50
--- /dev/null
+++ b/riscv/insns/ucmplt8.h
@@ -0,0 +1,3 @@
+P_ULOOP(8, {
+ pd = (ps1 < ps2) ? -1 : 0;
+}) \ No newline at end of file
diff --git a/riscv/insns/ukadd16.h b/riscv/insns/ukadd16.h
new file mode 100644
index 0000000..57c661a
--- /dev/null
+++ b/riscv/insns/ukadd16.h
@@ -0,0 +1,5 @@
+P_ULOOP(16, {
+ bool sat = false;
+ pd = (sat_addu<uint16_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/ukadd32.h b/riscv/insns/ukadd32.h
new file mode 100644
index 0000000..7613e59
--- /dev/null
+++ b/riscv/insns/ukadd32.h
@@ -0,0 +1,6 @@
+require_rv64;
+P_ULOOP(32, {
+ bool sat = false;
+ pd = (sat_addu<uint32_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/ukadd64.h b/riscv/insns/ukadd64.h
new file mode 100644
index 0000000..047e276
--- /dev/null
+++ b/riscv/insns/ukadd64.h
@@ -0,0 +1,5 @@
+P_64_UPROFILE({
+ bool sat = false;
+ rd = (sat_addu<uint64_t>(rs1, rs2, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/ukadd8.h b/riscv/insns/ukadd8.h
new file mode 100644
index 0000000..68708e2
--- /dev/null
+++ b/riscv/insns/ukadd8.h
@@ -0,0 +1,5 @@
+P_ULOOP(8, {
+ bool sat = false;
+ pd = (sat_addu<uint8_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/ukaddh.h b/riscv/insns/ukaddh.h
new file mode 100644
index 0000000..4eed73f
--- /dev/null
+++ b/riscv/insns/ukaddh.h
@@ -0,0 +1,4 @@
+require_extension('P');
+sreg_t res = (sreg_t)P_W(RS1, 0) + (sreg_t)P_W(RS2, 0);
+P_SATU(res, 16);
+WRITE_RD(sext_xlen((int16_t)res)); \ No newline at end of file
diff --git a/riscv/insns/ukaddw.h b/riscv/insns/ukaddw.h
new file mode 100644
index 0000000..61c109f
--- /dev/null
+++ b/riscv/insns/ukaddw.h
@@ -0,0 +1,4 @@
+require_extension('P');
+sreg_t res = (sreg_t)P_W(RS1, 0) + (sreg_t)P_W(RS2, 0);
+P_SATU(res, 32);
+WRITE_RD(sext32(res)); \ No newline at end of file
diff --git a/riscv/insns/ukcras16.h b/riscv/insns/ukcras16.h
new file mode 100644
index 0000000..90ef8f8
--- /dev/null
+++ b/riscv/insns/ukcras16.h
@@ -0,0 +1,9 @@
+P_CROSS_ULOOP(16, {
+ bool sat = false;
+ pd = (sat_addu<uint16_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}, {
+ bool sat = false;
+ pd = (sat_subu<uint16_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+})
diff --git a/riscv/insns/ukcras32.h b/riscv/insns/ukcras32.h
new file mode 100644
index 0000000..9478778
--- /dev/null
+++ b/riscv/insns/ukcras32.h
@@ -0,0 +1,10 @@
+require_rv64;
+P_CROSS_ULOOP(32, {
+ bool sat = false;
+ pd = (sat_addu<uint32_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}, {
+ bool sat = false;
+ pd = (sat_subu<uint32_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+})
diff --git a/riscv/insns/ukcrsa16.h b/riscv/insns/ukcrsa16.h
new file mode 100644
index 0000000..91c505d
--- /dev/null
+++ b/riscv/insns/ukcrsa16.h
@@ -0,0 +1,9 @@
+P_CROSS_ULOOP(16, {
+ bool sat = false;
+ pd = (sat_subu<uint16_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}, {
+ bool sat = false;
+ pd = (sat_addu<uint16_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/ukcrsa32.h b/riscv/insns/ukcrsa32.h
new file mode 100644
index 0000000..fd6a455
--- /dev/null
+++ b/riscv/insns/ukcrsa32.h
@@ -0,0 +1,10 @@
+require_rv64;
+P_CROSS_ULOOP(32, {
+ bool sat = false;
+ pd = (sat_subu<uint32_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}, {
+ bool sat = false;
+ pd = (sat_addu<uint32_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/ukmar64.h b/riscv/insns/ukmar64.h
new file mode 100644
index 0000000..e12be5d
--- /dev/null
+++ b/riscv/insns/ukmar64.h
@@ -0,0 +1,5 @@
+P_64_UPROFILE_REDUCTION(32, {
+ bool sat = false;
+ rd = (sat_addu<uint64_t>(rd, ps1 * ps2, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/ukmsr64.h b/riscv/insns/ukmsr64.h
new file mode 100644
index 0000000..d2e0ac3
--- /dev/null
+++ b/riscv/insns/ukmsr64.h
@@ -0,0 +1,5 @@
+P_64_UPROFILE_REDUCTION(32, {
+ bool sat = false;
+ rd = (sat_subu<uint64_t>(rd, ps1 * ps2, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/ukstas16.h b/riscv/insns/ukstas16.h
new file mode 100644
index 0000000..110b247
--- /dev/null
+++ b/riscv/insns/ukstas16.h
@@ -0,0 +1,9 @@
+P_STRAIGHT_ULOOP(16, {
+ bool sat = false;
+ pd = (sat_addu<uint16_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}, {
+ bool sat = false;
+ pd = (sat_subu<uint16_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/ukstas32.h b/riscv/insns/ukstas32.h
new file mode 100644
index 0000000..62a39eb
--- /dev/null
+++ b/riscv/insns/ukstas32.h
@@ -0,0 +1,10 @@
+require_rv64;
+P_STRAIGHT_ULOOP(32, {
+ bool sat = false;
+ pd = (sat_addu<uint32_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}, {
+ bool sat = false;
+ pd = (sat_subu<uint32_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/ukstsa16.h b/riscv/insns/ukstsa16.h
new file mode 100644
index 0000000..47a2fc1
--- /dev/null
+++ b/riscv/insns/ukstsa16.h
@@ -0,0 +1,9 @@
+P_STRAIGHT_ULOOP(16, {
+ bool sat = false;
+ pd = (sat_subu<uint16_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}, {
+ bool sat = false;
+ pd = (sat_addu<uint16_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/ukstsa32.h b/riscv/insns/ukstsa32.h
new file mode 100644
index 0000000..52a078f
--- /dev/null
+++ b/riscv/insns/ukstsa32.h
@@ -0,0 +1,10 @@
+require_rv64;
+P_STRAIGHT_ULOOP(32, {
+ bool sat = false;
+ pd = (sat_subu<uint32_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}, {
+ bool sat = false;
+ pd = (sat_addu<uint32_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/uksub16.h b/riscv/insns/uksub16.h
new file mode 100644
index 0000000..b330622
--- /dev/null
+++ b/riscv/insns/uksub16.h
@@ -0,0 +1,5 @@
+P_ULOOP(16, {
+ bool sat = false;
+ pd = (sat_subu<uint16_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/uksub32.h b/riscv/insns/uksub32.h
new file mode 100644
index 0000000..da1fd20
--- /dev/null
+++ b/riscv/insns/uksub32.h
@@ -0,0 +1,6 @@
+require_rv64;
+P_ULOOP(32, {
+ bool sat = false;
+ pd = (sat_subu<uint32_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/uksub64.h b/riscv/insns/uksub64.h
new file mode 100644
index 0000000..7a0deb1
--- /dev/null
+++ b/riscv/insns/uksub64.h
@@ -0,0 +1,5 @@
+P_64_UPROFILE({
+ bool sat = false;
+ rd = (sat_subu<uint64_t>(rs1, rs2, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/uksub8.h b/riscv/insns/uksub8.h
new file mode 100644
index 0000000..3d47608
--- /dev/null
+++ b/riscv/insns/uksub8.h
@@ -0,0 +1,5 @@
+P_ULOOP(8, {
+ bool sat = false;
+ pd = (sat_subu<uint8_t>(ps1, ps2, sat));
+ P_SET_OV(sat);
+}) \ No newline at end of file
diff --git a/riscv/insns/uksubh.h b/riscv/insns/uksubh.h
new file mode 100644
index 0000000..be9ec45
--- /dev/null
+++ b/riscv/insns/uksubh.h
@@ -0,0 +1,4 @@
+require_extension('P');
+sreg_t res = (sreg_t)P_W(RS1, 0) - (sreg_t)P_W(RS2, 0);
+P_SATU(res, 16);
+WRITE_RD(sext_xlen((int16_t)res)); \ No newline at end of file
diff --git a/riscv/insns/uksubw.h b/riscv/insns/uksubw.h
new file mode 100644
index 0000000..8a088cd
--- /dev/null
+++ b/riscv/insns/uksubw.h
@@ -0,0 +1,4 @@
+require_extension('P');
+sreg_t res = (sreg_t)P_W(RS1, 0) - (sreg_t)P_W(RS2, 0);
+P_SATU(res, 32);
+WRITE_RD(sext32(res)); \ No newline at end of file
diff --git a/riscv/insns/umaqa.h b/riscv/insns/umaqa.h
new file mode 100644
index 0000000..69cd048
--- /dev/null
+++ b/riscv/insns/umaqa.h
@@ -0,0 +1,3 @@
+P_REDUCTION_ULOOP(32, 8, true, false, {
+ pd_res += ps1 * ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/umar64.h b/riscv/insns/umar64.h
new file mode 100644
index 0000000..a131104
--- /dev/null
+++ b/riscv/insns/umar64.h
@@ -0,0 +1,3 @@
+P_64_UPROFILE_REDUCTION(32, {
+ rd += ps1 * ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/umax16.h b/riscv/insns/umax16.h
new file mode 100644
index 0000000..8cc897b
--- /dev/null
+++ b/riscv/insns/umax16.h
@@ -0,0 +1,3 @@
+P_ULOOP(16, {
+ pd = (ps1 > ps2) ? ps1 : ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/umax32.h b/riscv/insns/umax32.h
new file mode 100644
index 0000000..77a57f5
--- /dev/null
+++ b/riscv/insns/umax32.h
@@ -0,0 +1,3 @@
+P_ULOOP(32, {
+ pd = (ps1 > ps2) ? ps1 : ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/umax8.h b/riscv/insns/umax8.h
new file mode 100644
index 0000000..22a89f0
--- /dev/null
+++ b/riscv/insns/umax8.h
@@ -0,0 +1,3 @@
+P_ULOOP(8, {
+ pd = (ps1 > ps2) ? ps1 : ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/umin16.h b/riscv/insns/umin16.h
new file mode 100644
index 0000000..8e7b6a4
--- /dev/null
+++ b/riscv/insns/umin16.h
@@ -0,0 +1,3 @@
+P_ULOOP(16, {
+ pd = (ps1 < ps2) ? ps1 : ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/umin32.h b/riscv/insns/umin32.h
new file mode 100644
index 0000000..6b5a6dc
--- /dev/null
+++ b/riscv/insns/umin32.h
@@ -0,0 +1,3 @@
+P_ULOOP(32, {
+ pd = (ps1 < ps2) ? ps1 : ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/umin8.h b/riscv/insns/umin8.h
new file mode 100644
index 0000000..9194fd7
--- /dev/null
+++ b/riscv/insns/umin8.h
@@ -0,0 +1,3 @@
+P_ULOOP(8, {
+ pd = (ps1 < ps2) ? ps1 : ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/umsr64.h b/riscv/insns/umsr64.h
new file mode 100644
index 0000000..1b28267
--- /dev/null
+++ b/riscv/insns/umsr64.h
@@ -0,0 +1,3 @@
+P_64_UPROFILE_REDUCTION(32, {
+ rd -= ps1 * ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/umul16.h b/riscv/insns/umul16.h
new file mode 100644
index 0000000..1f5891d
--- /dev/null
+++ b/riscv/insns/umul16.h
@@ -0,0 +1,3 @@
+P_MUL_ULOOP(16, {
+ pd = ps1 * ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/umul8.h b/riscv/insns/umul8.h
new file mode 100644
index 0000000..d96ab73
--- /dev/null
+++ b/riscv/insns/umul8.h
@@ -0,0 +1,3 @@
+P_MUL_ULOOP(8, {
+ pd = ps1 * ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/umulx16.h b/riscv/insns/umulx16.h
new file mode 100644
index 0000000..e3dd5a3
--- /dev/null
+++ b/riscv/insns/umulx16.h
@@ -0,0 +1,3 @@
+P_MUL_CROSS_ULOOP(16, {
+ pd = ps1 * ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/umulx8.h b/riscv/insns/umulx8.h
new file mode 100644
index 0000000..48062da
--- /dev/null
+++ b/riscv/insns/umulx8.h
@@ -0,0 +1,3 @@
+P_MUL_CROSS_ULOOP(8, {
+ pd = ps1 * ps2;
+}) \ No newline at end of file
diff --git a/riscv/insns/uradd16.h b/riscv/insns/uradd16.h
new file mode 100644
index 0000000..2349568
--- /dev/null
+++ b/riscv/insns/uradd16.h
@@ -0,0 +1,3 @@
+P_ULOOP(16, {
+ pd = (ps1 + ps2) >> 1;
+}) \ No newline at end of file
diff --git a/riscv/insns/uradd32.h b/riscv/insns/uradd32.h
new file mode 100644
index 0000000..9b17e7c
--- /dev/null
+++ b/riscv/insns/uradd32.h
@@ -0,0 +1,4 @@
+require_rv64;
+P_ULOOP(32, {
+ pd = ((uint64_t)ps1 + ps2) >> 1;
+}) \ No newline at end of file
diff --git a/riscv/insns/uradd64.h b/riscv/insns/uradd64.h
new file mode 100644
index 0000000..3005c98
--- /dev/null
+++ b/riscv/insns/uradd64.h
@@ -0,0 +1,9 @@
+P_64_UPROFILE({
+ rd = rs1 + rs2;
+ if (rd < rs1) {
+ rd >>= 1;
+ rd |= ((reg_t)1 << 63);
+ } else {
+ rd >>= 1;
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/uradd8.h b/riscv/insns/uradd8.h
new file mode 100644
index 0000000..277d2d3
--- /dev/null
+++ b/riscv/insns/uradd8.h
@@ -0,0 +1,3 @@
+P_ULOOP(8, {
+ pd = (ps1 + ps2) >> 1;
+}) \ No newline at end of file
diff --git a/riscv/insns/uraddw.h b/riscv/insns/uraddw.h
new file mode 100644
index 0000000..97c5710
--- /dev/null
+++ b/riscv/insns/uraddw.h
@@ -0,0 +1,4 @@
+require_extension('P');
+reg_t res = (reg_t)P_W(RS1, 0) + (reg_t)P_W(RS2, 0);
+res >>= 1;
+WRITE_RD(sext_xlen((int32_t)res)); \ No newline at end of file
diff --git a/riscv/insns/urcras16.h b/riscv/insns/urcras16.h
new file mode 100644
index 0000000..592920d
--- /dev/null
+++ b/riscv/insns/urcras16.h
@@ -0,0 +1,5 @@
+P_CROSS_ULOOP(16, {
+ pd = (ps1 + ps2) >> 1;
+}, {
+ pd = (ps1 - ps2) >> 1;
+}) \ No newline at end of file
diff --git a/riscv/insns/urcras32.h b/riscv/insns/urcras32.h
new file mode 100644
index 0000000..0e5a201
--- /dev/null
+++ b/riscv/insns/urcras32.h
@@ -0,0 +1,6 @@
+require_rv64;
+P_CROSS_ULOOP(32, {
+ pd = ((uint64_t)ps1 + ps2) >> 1;
+}, {
+ pd = ((uint64_t)ps1 - ps2) >> 1;
+}) \ No newline at end of file
diff --git a/riscv/insns/urcrsa16.h b/riscv/insns/urcrsa16.h
new file mode 100644
index 0000000..65fe17b
--- /dev/null
+++ b/riscv/insns/urcrsa16.h
@@ -0,0 +1,5 @@
+P_CROSS_ULOOP(16, {
+ pd = (ps1 - ps2) >> 1;
+}, {
+ pd = (ps1 + ps2) >> 1;
+}) \ No newline at end of file
diff --git a/riscv/insns/urcrsa32.h b/riscv/insns/urcrsa32.h
new file mode 100644
index 0000000..fda986f
--- /dev/null
+++ b/riscv/insns/urcrsa32.h
@@ -0,0 +1,6 @@
+require_rv64;
+P_CROSS_ULOOP(32, {
+ pd = ((uint64_t)ps1 - ps2) >> 1;
+}, {
+ pd = ((uint64_t)ps1 + ps2) >> 1;
+}) \ No newline at end of file
diff --git a/riscv/insns/urstas16.h b/riscv/insns/urstas16.h
new file mode 100644
index 0000000..9aa4697
--- /dev/null
+++ b/riscv/insns/urstas16.h
@@ -0,0 +1,5 @@
+P_STRAIGHT_ULOOP(16, {
+ pd = (ps1 + ps2) >> 1;
+}, {
+ pd = (ps1 - ps2) >> 1;
+}) \ No newline at end of file
diff --git a/riscv/insns/urstas32.h b/riscv/insns/urstas32.h
new file mode 100644
index 0000000..c79d3ce
--- /dev/null
+++ b/riscv/insns/urstas32.h
@@ -0,0 +1,6 @@
+require_rv64;
+P_STRAIGHT_ULOOP(32, {
+ pd = ((uint64_t)ps1 + ps2) >> 1;
+}, {
+ pd = ((uint64_t)ps1 - ps2) >> 1;
+}) \ No newline at end of file
diff --git a/riscv/insns/urstsa16.h b/riscv/insns/urstsa16.h
new file mode 100644
index 0000000..3aec9c9
--- /dev/null
+++ b/riscv/insns/urstsa16.h
@@ -0,0 +1,5 @@
+P_STRAIGHT_ULOOP(16, {
+ pd = (ps1 - ps2) >> 1;
+}, {
+ pd = (ps1 + ps2) >> 1;
+}) \ No newline at end of file
diff --git a/riscv/insns/urstsa32.h b/riscv/insns/urstsa32.h
new file mode 100644
index 0000000..577fba1
--- /dev/null
+++ b/riscv/insns/urstsa32.h
@@ -0,0 +1,6 @@
+require_rv64;
+P_STRAIGHT_ULOOP(32, {
+ pd = ((uint64_t)ps1 - ps2) >> 1;
+}, {
+ pd = ((uint64_t)ps1 + ps2) >> 1;
+}) \ No newline at end of file
diff --git a/riscv/insns/ursub16.h b/riscv/insns/ursub16.h
new file mode 100644
index 0000000..153d8ec
--- /dev/null
+++ b/riscv/insns/ursub16.h
@@ -0,0 +1,3 @@
+P_ULOOP(16, {
+ pd = (ps1 - ps2) >> 1;
+}) \ No newline at end of file
diff --git a/riscv/insns/ursub32.h b/riscv/insns/ursub32.h
new file mode 100644
index 0000000..d43e065
--- /dev/null
+++ b/riscv/insns/ursub32.h
@@ -0,0 +1,4 @@
+require_rv64;
+P_ULOOP(32, {
+ pd = ((uint64_t)ps1 - ps2) >> 1;
+}) \ No newline at end of file
diff --git a/riscv/insns/ursub64.h b/riscv/insns/ursub64.h
new file mode 100644
index 0000000..6354e3e
--- /dev/null
+++ b/riscv/insns/ursub64.h
@@ -0,0 +1,9 @@
+P_64_UPROFILE({
+ rd = rs1 - rs2;
+ if (rd > rs1) {
+ rd >>= 1;
+ rd |= ((reg_t)1 << 63);
+ } else {
+ rd >>= 1;
+ }
+}) \ No newline at end of file
diff --git a/riscv/insns/ursub8.h b/riscv/insns/ursub8.h
new file mode 100644
index 0000000..74dea5d
--- /dev/null
+++ b/riscv/insns/ursub8.h
@@ -0,0 +1,3 @@
+P_ULOOP(8, {
+ pd = (ps1 - ps2) >> 1;
+}) \ No newline at end of file
diff --git a/riscv/insns/ursubw.h b/riscv/insns/ursubw.h
new file mode 100644
index 0000000..2b27955
--- /dev/null
+++ b/riscv/insns/ursubw.h
@@ -0,0 +1,4 @@
+require_extension('P');
+reg_t res = (reg_t)P_W(RS1, 0) - (reg_t)P_W(RS2, 0);
+res >>= 1;
+WRITE_RD(sext_xlen((int32_t)res)); \ No newline at end of file
diff --git a/riscv/insns/wext.h b/riscv/insns/wext.h
new file mode 100644
index 0000000..b849011
--- /dev/null
+++ b/riscv/insns/wext.h
@@ -0,0 +1,4 @@
+require_extension('P');
+reg_t rs1 = (xlen == 32) ? RS1_PAIR : RS1;
+reg_t lsb = get_field(RS2, make_mask64(0, 5));
+WRITE_RD(sext32(get_field(rs1, make_mask64(lsb, 32)))); \ No newline at end of file
diff --git a/riscv/insns/wexti.h b/riscv/insns/wexti.h
new file mode 100644
index 0000000..752b173
--- /dev/null
+++ b/riscv/insns/wexti.h
@@ -0,0 +1,4 @@
+require_extension('P');
+reg_t rs1 = (xlen == 32) ? RS1_PAIR : RS1;
+reg_t lsb = insn.p_imm5();
+WRITE_RD(sext32(get_field(rs1, make_mask64(lsb, 32)))); \ No newline at end of file
diff --git a/riscv/insns/zunpkd810.h b/riscv/insns/zunpkd810.h
new file mode 100644
index 0000000..d5cf460
--- /dev/null
+++ b/riscv/insns/zunpkd810.h
@@ -0,0 +1 @@
+P_ZUNPKD8(1, 0) \ No newline at end of file
diff --git a/riscv/insns/zunpkd820.h b/riscv/insns/zunpkd820.h
new file mode 100644
index 0000000..149d1de
--- /dev/null
+++ b/riscv/insns/zunpkd820.h
@@ -0,0 +1 @@
+P_ZUNPKD8(2, 0) \ No newline at end of file
diff --git a/riscv/insns/zunpkd830.h b/riscv/insns/zunpkd830.h
new file mode 100644
index 0000000..aa1f554
--- /dev/null
+++ b/riscv/insns/zunpkd830.h
@@ -0,0 +1 @@
+P_ZUNPKD8(3, 0) \ No newline at end of file
diff --git a/riscv/insns/zunpkd831.h b/riscv/insns/zunpkd831.h
new file mode 100644
index 0000000..494e2f1
--- /dev/null
+++ b/riscv/insns/zunpkd831.h
@@ -0,0 +1 @@
+P_ZUNPKD8(3, 1) \ No newline at end of file
diff --git a/riscv/insns/zunpkd832.h b/riscv/insns/zunpkd832.h
new file mode 100644
index 0000000..42b01ea
--- /dev/null
+++ b/riscv/insns/zunpkd832.h
@@ -0,0 +1 @@
+P_ZUNPKD8(3, 2) \ No newline at end of file