aboutsummaryrefslogtreecommitdiff
path: root/riscv
diff options
context:
space:
mode:
Diffstat (limited to 'riscv')
-rw-r--r--riscv/encoding.h267
-rw-r--r--riscv/insns/addiwu.h3
-rw-r--r--riscv/insns/addu_w.h3
-rw-r--r--riscv/insns/addwu.h3
-rw-r--r--riscv/insns/andn.h2
-rw-r--r--riscv/insns/bdep.h9
-rw-r--r--riscv/insns/bdepw.h10
-rw-r--r--riscv/insns/bext.h9
-rw-r--r--riscv/insns/bextw.h10
-rw-r--r--riscv/insns/bmatflip.h11
-rw-r--r--riscv/insns/bmator.h29
-rw-r--r--riscv/insns/bmatxor.h29
-rw-r--r--riscv/insns/clmul.h6
-rw-r--r--riscv/insns/clmulh.h6
-rw-r--r--riscv/insns/clmulhw.h6
-rw-r--r--riscv/insns/clmulr.h6
-rw-r--r--riscv/insns/clmulrw.h6
-rw-r--r--riscv/insns/clmulw.h6
-rw-r--r--riscv/insns/clz.h5
-rw-r--r--riscv/insns/clzw.h6
-rw-r--r--riscv/insns/cmix.h2
-rw-r--r--riscv/insns/cmov.h2
-rw-r--r--riscv/insns/crc32_b.h5
-rw-r--r--riscv/insns/crc32_d.h5
-rw-r--r--riscv/insns/crc32_h.h5
-rw-r--r--riscv/insns/crc32_w.h5
-rw-r--r--riscv/insns/crc32c_b.h5
-rw-r--r--riscv/insns/crc32c_d.h5
-rw-r--r--riscv/insns/crc32c_h.h5
-rw-r--r--riscv/insns/crc32c_w.h5
-rw-r--r--riscv/insns/ctz.h5
-rw-r--r--riscv/insns/ctzw.h6
-rw-r--r--riscv/insns/fsl.h9
-rw-r--r--riscv/insns/fslw.h10
-rw-r--r--riscv/insns/fsr.h9
-rw-r--r--riscv/insns/fsri.h9
-rw-r--r--riscv/insns/fsriw.h10
-rw-r--r--riscv/insns/fsrw.h10
-rw-r--r--riscv/insns/grev.h10
-rw-r--r--riscv/insns/grevi.h11
-rw-r--r--riscv/insns/greviw.h11
-rw-r--r--riscv/insns/grevw.h10
-rw-r--r--riscv/insns/max.h2
-rw-r--r--riscv/insns/maxu.h2
-rw-r--r--riscv/insns/min.h2
-rw-r--r--riscv/insns/minu.h2
-rw-r--r--riscv/insns/orn.h2
-rw-r--r--riscv/insns/pack.h4
-rw-r--r--riscv/insns/packw.h4
-rw-r--r--riscv/insns/pcnt.h5
-rw-r--r--riscv/insns/pcntw.h6
-rw-r--r--riscv/insns/rol.h4
-rw-r--r--riscv/insns/rolw.h5
-rw-r--r--riscv/insns/ror.h4
-rw-r--r--riscv/insns/rori.h5
-rw-r--r--riscv/insns/roriw.h5
-rw-r--r--riscv/insns/rorw.h5
-rw-r--r--riscv/insns/sbclr.h3
-rw-r--r--riscv/insns/sbclri.h3
-rw-r--r--riscv/insns/sbclriw.h3
-rw-r--r--riscv/insns/sbclrw.h3
-rw-r--r--riscv/insns/sbext.h3
-rw-r--r--riscv/insns/sbexti.h3
-rw-r--r--riscv/insns/sbextw.h3
-rw-r--r--riscv/insns/sbinv.h3
-rw-r--r--riscv/insns/sbinvi.h3
-rw-r--r--riscv/insns/sbinviw.h3
-rw-r--r--riscv/insns/sbinvw.h3
-rw-r--r--riscv/insns/sbset.h3
-rw-r--r--riscv/insns/sbseti.h3
-rw-r--r--riscv/insns/sbsetiw.h3
-rw-r--r--riscv/insns/sbsetw.h3
-rw-r--r--riscv/insns/shfl.h9
-rw-r--r--riscv/insns/shfli.h10
-rw-r--r--riscv/insns/shflw.h9
-rw-r--r--riscv/insns/slliu_w.h3
-rw-r--r--riscv/insns/slo.h2
-rw-r--r--riscv/insns/sloi.h3
-rw-r--r--riscv/insns/sloiw.h3
-rw-r--r--riscv/insns/slow.h3
-rw-r--r--riscv/insns/sro.h2
-rw-r--r--riscv/insns/sroi.h3
-rw-r--r--riscv/insns/sroiw.h3
-rw-r--r--riscv/insns/srow.h3
-rw-r--r--riscv/insns/subu_w.h3
-rw-r--r--riscv/insns/subwu.h3
-rw-r--r--riscv/insns/unshfl.h9
-rw-r--r--riscv/insns/unshfli.h10
-rw-r--r--riscv/insns/unshflw.h9
-rw-r--r--riscv/insns/xnor.h2
-rw-r--r--riscv/processor.cc5
-rw-r--r--riscv/riscv.mk.in92
92 files changed, 872 insertions, 2 deletions
diff --git a/riscv/encoding.h b/riscv/encoding.h
index 68801b0..79af160 100644
--- a/riscv/encoding.h
+++ b/riscv/encoding.h
@@ -448,6 +448,184 @@
#define MASK_REMW 0xfe00707f
#define MATCH_REMUW 0x200703b
#define MASK_REMUW 0xfe00707f
+#define MATCH_ANDN 0x40007033
+#define MASK_ANDN 0xfe00707f
+#define MATCH_ORN 0x40006033
+#define MASK_ORN 0xfe00707f
+#define MATCH_XNOR 0x40004033
+#define MASK_XNOR 0xfe00707f
+#define MATCH_GREV 0x40001033
+#define MASK_GREV 0xfe00707f
+#define MATCH_SLO 0x20001033
+#define MASK_SLO 0xfe00707f
+#define MATCH_SRO 0x20005033
+#define MASK_SRO 0xfe00707f
+#define MATCH_ROL 0x60001033
+#define MASK_ROL 0xfe00707f
+#define MATCH_ROR 0x60005033
+#define MASK_ROR 0xfe00707f
+#define MATCH_SBSET 0x28001033
+#define MASK_SBSET 0xfe00707f
+#define MATCH_SBCLR 0x48001033
+#define MASK_SBCLR 0xfe00707f
+#define MATCH_SBINV 0x68001033
+#define MASK_SBINV 0xfe00707f
+#define MATCH_SBEXT 0x48005033
+#define MASK_SBEXT 0xfe00707f
+#define MATCH_GREVI 0x40001013
+#define MASK_GREVI 0xfc00707f
+#define MATCH_SLOI 0x20001013
+#define MASK_SLOI 0xfc00707f
+#define MATCH_SROI 0x20005013
+#define MASK_SROI 0xfc00707f
+#define MATCH_RORI 0x60005013
+#define MASK_RORI 0xfc00707f
+#define MATCH_SBSETI 0x28001013
+#define MASK_SBSETI 0xfc00707f
+#define MATCH_SBCLRI 0x48001013
+#define MASK_SBCLRI 0xfc00707f
+#define MATCH_SBINVI 0x68001013
+#define MASK_SBINVI 0xfc00707f
+#define MATCH_SBEXTI 0x48005013
+#define MASK_SBEXTI 0xfc00707f
+#define MATCH_CMIX 0x6001033
+#define MASK_CMIX 0x600707f
+#define MATCH_CMOV 0x6005033
+#define MASK_CMOV 0x600707f
+#define MATCH_FSL 0x4001033
+#define MASK_FSL 0x600707f
+#define MATCH_FSR 0x4005033
+#define MASK_FSR 0x600707f
+#define MATCH_FSRI 0x4005013
+#define MASK_FSRI 0x400707f
+#define MATCH_CLZ 0x60001013
+#define MASK_CLZ 0xfff0707f
+#define MATCH_CTZ 0x60101013
+#define MASK_CTZ 0xfff0707f
+#define MATCH_PCNT 0x60201013
+#define MASK_PCNT 0xfff0707f
+#define MATCH_CRC32_B 0x61001013
+#define MASK_CRC32_B 0xfff0707f
+#define MATCH_CRC32_H 0x61101013
+#define MASK_CRC32_H 0xfff0707f
+#define MATCH_CRC32_W 0x61201013
+#define MASK_CRC32_W 0xfff0707f
+#define MATCH_CRC32C_B 0x61801013
+#define MASK_CRC32C_B 0xfff0707f
+#define MATCH_CRC32C_H 0x61901013
+#define MASK_CRC32C_H 0xfff0707f
+#define MATCH_CRC32C_W 0x61a01013
+#define MASK_CRC32C_W 0xfff0707f
+#define MATCH_CLMUL 0xa001033
+#define MASK_CLMUL 0xfe00707f
+#define MATCH_CLMULR 0xa002033
+#define MASK_CLMULR 0xfe00707f
+#define MATCH_CLMULH 0xa003033
+#define MASK_CLMULH 0xfe00707f
+#define MATCH_MIN 0xa004033
+#define MASK_MIN 0xfe00707f
+#define MATCH_MAX 0xa005033
+#define MASK_MAX 0xfe00707f
+#define MATCH_MINU 0xa006033
+#define MASK_MINU 0xfe00707f
+#define MATCH_MAXU 0xa007033
+#define MASK_MAXU 0xfe00707f
+#define MATCH_SHFL 0x8001033
+#define MASK_SHFL 0xfe00707f
+#define MATCH_UNSHFL 0x8005033
+#define MASK_UNSHFL 0xfe00707f
+#define MATCH_BDEP 0x8002033
+#define MASK_BDEP 0xfe00707f
+#define MATCH_BEXT 0x8006033
+#define MASK_BEXT 0xfe00707f
+#define MATCH_PACK 0x8004033
+#define MASK_PACK 0xfe00707f
+#define MATCH_SHFLI 0x8001013
+#define MASK_SHFLI 0xfc00707f
+#define MATCH_UNSHFLI 0x8005013
+#define MASK_UNSHFLI 0xfc00707f
+#define MATCH_BMATFLIP 0x60301013
+#define MASK_BMATFLIP 0xfff0707f
+#define MATCH_CRC32_D 0x61301013
+#define MASK_CRC32_D 0xfff0707f
+#define MATCH_CRC32C_D 0x61b01013
+#define MASK_CRC32C_D 0xfff0707f
+#define MATCH_BMATOR 0x8003033
+#define MASK_BMATOR 0xfe00707f
+#define MATCH_BMATXOR 0x8007033
+#define MASK_BMATXOR 0xfe00707f
+#define MATCH_ADDIWU 0x401b
+#define MASK_ADDIWU 0x707f
+#define MATCH_SLLIU_W 0x800101b
+#define MASK_SLLIU_W 0xfc00707f
+#define MATCH_ADDWU 0xa00003b
+#define MASK_ADDWU 0xfe00707f
+#define MATCH_SUBWU 0x4a00003b
+#define MASK_SUBWU 0xfe00707f
+#define MATCH_ADDU_W 0x800003b
+#define MASK_ADDU_W 0xfe00707f
+#define MATCH_SUBU_W 0x4800003b
+#define MASK_SUBU_W 0xfe00707f
+#define MATCH_GREVW 0x4000103b
+#define MASK_GREVW 0xfe00707f
+#define MATCH_SLOW 0x2000103b
+#define MASK_SLOW 0xfe00707f
+#define MATCH_SROW 0x2000503b
+#define MASK_SROW 0xfe00707f
+#define MATCH_ROLW 0x6000103b
+#define MASK_ROLW 0xfe00707f
+#define MATCH_RORW 0x6000503b
+#define MASK_RORW 0xfe00707f
+#define MATCH_SBSETW 0x2800103b
+#define MASK_SBSETW 0xfe00707f
+#define MATCH_SBCLRW 0x4800103b
+#define MASK_SBCLRW 0xfe00707f
+#define MATCH_SBINVW 0x6800103b
+#define MASK_SBINVW 0xfe00707f
+#define MATCH_SBEXTW 0x4800503b
+#define MASK_SBEXTW 0xfe00707f
+#define MATCH_GREVIW 0x4000101b
+#define MASK_GREVIW 0xfe00707f
+#define MATCH_SLOIW 0x2000101b
+#define MASK_SLOIW 0xfe00707f
+#define MATCH_SROIW 0x2000501b
+#define MASK_SROIW 0xfe00707f
+#define MATCH_RORIW 0x6000501b
+#define MASK_RORIW 0xfe00707f
+#define MATCH_SBSETIW 0x2800101b
+#define MASK_SBSETIW 0xfe00707f
+#define MATCH_SBCLRIW 0x4800101b
+#define MASK_SBCLRIW 0xfe00707f
+#define MATCH_SBINVIW 0x6800101b
+#define MASK_SBINVIW 0xfe00707f
+#define MATCH_FSLW 0x400103b
+#define MASK_FSLW 0x600707f
+#define MATCH_FSRW 0x400503b
+#define MASK_FSRW 0x600707f
+#define MATCH_FSRIW 0x400501b
+#define MASK_FSRIW 0x600707f
+#define MATCH_CLZW 0x6000101b
+#define MASK_CLZW 0xfff0707f
+#define MATCH_CTZW 0x6010101b
+#define MASK_CTZW 0xfff0707f
+#define MATCH_PCNTW 0x6020101b
+#define MASK_PCNTW 0xfff0707f
+#define MATCH_CLMULW 0xa00103b
+#define MASK_CLMULW 0xfe00707f
+#define MATCH_CLMULRW 0xa00203b
+#define MASK_CLMULRW 0xfe00707f
+#define MATCH_CLMULHW 0xa00303b
+#define MASK_CLMULHW 0xfe00707f
+#define MATCH_SHFLW 0x800103b
+#define MASK_SHFLW 0xfe00707f
+#define MATCH_UNSHFLW 0x800503b
+#define MASK_UNSHFLW 0xfe00707f
+#define MATCH_BDEPW 0x800203b
+#define MASK_BDEPW 0xfe00707f
+#define MATCH_BEXTW 0x800603b
+#define MASK_BEXTW 0xfe00707f
+#define MATCH_PACKW 0x800403b
+#define MASK_PACKW 0xfe00707f
#define MATCH_AMOADD_W 0x202f
#define MASK_AMOADD_W 0xf800707f
#define MATCH_AMOXOR_W 0x2000202f
@@ -2223,6 +2401,95 @@ DECLARE_INSN(divw, MATCH_DIVW, MASK_DIVW)
DECLARE_INSN(divuw, MATCH_DIVUW, MASK_DIVUW)
DECLARE_INSN(remw, MATCH_REMW, MASK_REMW)
DECLARE_INSN(remuw, MATCH_REMUW, MASK_REMUW)
+DECLARE_INSN(andn, MATCH_ANDN, MASK_ANDN)
+DECLARE_INSN(orn, MATCH_ORN, MASK_ORN)
+DECLARE_INSN(xnor, MATCH_XNOR, MASK_XNOR)
+DECLARE_INSN(grev, MATCH_GREV, MASK_GREV)
+DECLARE_INSN(slo, MATCH_SLO, MASK_SLO)
+DECLARE_INSN(sro, MATCH_SRO, MASK_SRO)
+DECLARE_INSN(rol, MATCH_ROL, MASK_ROL)
+DECLARE_INSN(ror, MATCH_ROR, MASK_ROR)
+DECLARE_INSN(sbset, MATCH_SBSET, MASK_SBSET)
+DECLARE_INSN(sbclr, MATCH_SBCLR, MASK_SBCLR)
+DECLARE_INSN(sbinv, MATCH_SBINV, MASK_SBINV)
+DECLARE_INSN(sbext, MATCH_SBEXT, MASK_SBEXT)
+DECLARE_INSN(grevi, MATCH_GREVI, MASK_GREVI)
+DECLARE_INSN(sloi, MATCH_SLOI, MASK_SLOI)
+DECLARE_INSN(sroi, MATCH_SROI, MASK_SROI)
+DECLARE_INSN(rori, MATCH_RORI, MASK_RORI)
+DECLARE_INSN(sbseti, MATCH_SBSETI, MASK_SBSETI)
+DECLARE_INSN(sbclri, MATCH_SBCLRI, MASK_SBCLRI)
+DECLARE_INSN(sbinvi, MATCH_SBINVI, MASK_SBINVI)
+DECLARE_INSN(sbexti, MATCH_SBEXTI, MASK_SBEXTI)
+DECLARE_INSN(cmix, MATCH_CMIX, MASK_CMIX)
+DECLARE_INSN(cmov, MATCH_CMOV, MASK_CMOV)
+DECLARE_INSN(fsl, MATCH_FSL, MASK_FSL)
+DECLARE_INSN(fsr, MATCH_FSR, MASK_FSR)
+DECLARE_INSN(fsri, MATCH_FSRI, MASK_FSRI)
+DECLARE_INSN(clz, MATCH_CLZ, MASK_CLZ)
+DECLARE_INSN(ctz, MATCH_CTZ, MASK_CTZ)
+DECLARE_INSN(pcnt, MATCH_PCNT, MASK_PCNT)
+DECLARE_INSN(crc32_b, MATCH_CRC32_B, MASK_CRC32_B)
+DECLARE_INSN(crc32_h, MATCH_CRC32_H, MASK_CRC32_H)
+DECLARE_INSN(crc32_w, MATCH_CRC32_W, MASK_CRC32_W)
+DECLARE_INSN(crc32c_b, MATCH_CRC32C_B, MASK_CRC32C_B)
+DECLARE_INSN(crc32c_h, MATCH_CRC32C_H, MASK_CRC32C_H)
+DECLARE_INSN(crc32c_w, MATCH_CRC32C_W, MASK_CRC32C_W)
+DECLARE_INSN(clmul, MATCH_CLMUL, MASK_CLMUL)
+DECLARE_INSN(clmulr, MATCH_CLMULR, MASK_CLMULR)
+DECLARE_INSN(clmulh, MATCH_CLMULH, MASK_CLMULH)
+DECLARE_INSN(min, MATCH_MIN, MASK_MIN)
+DECLARE_INSN(max, MATCH_MAX, MASK_MAX)
+DECLARE_INSN(minu, MATCH_MINU, MASK_MINU)
+DECLARE_INSN(maxu, MATCH_MAXU, MASK_MAXU)
+DECLARE_INSN(shfl, MATCH_SHFL, MASK_SHFL)
+DECLARE_INSN(unshfl, MATCH_UNSHFL, MASK_UNSHFL)
+DECLARE_INSN(bdep, MATCH_BDEP, MASK_BDEP)
+DECLARE_INSN(bext, MATCH_BEXT, MASK_BEXT)
+DECLARE_INSN(pack, MATCH_PACK, MASK_PACK)
+DECLARE_INSN(shfli, MATCH_SHFLI, MASK_SHFLI)
+DECLARE_INSN(unshfli, MATCH_UNSHFLI, MASK_UNSHFLI)
+DECLARE_INSN(bmatflip, MATCH_BMATFLIP, MASK_BMATFLIP)
+DECLARE_INSN(crc32_d, MATCH_CRC32_D, MASK_CRC32_D)
+DECLARE_INSN(crc32c_d, MATCH_CRC32C_D, MASK_CRC32C_D)
+DECLARE_INSN(bmator, MATCH_BMATOR, MASK_BMATOR)
+DECLARE_INSN(bmatxor, MATCH_BMATXOR, MASK_BMATXOR)
+DECLARE_INSN(addiwu, MATCH_ADDIWU, MASK_ADDIWU)
+DECLARE_INSN(slliu_w, MATCH_SLLIU_W, MASK_SLLIU_W)
+DECLARE_INSN(addwu, MATCH_ADDWU, MASK_ADDWU)
+DECLARE_INSN(subwu, MATCH_SUBWU, MASK_SUBWU)
+DECLARE_INSN(addu_w, MATCH_ADDU_W, MASK_ADDU_W)
+DECLARE_INSN(subu_w, MATCH_SUBU_W, MASK_SUBU_W)
+DECLARE_INSN(grevw, MATCH_GREVW, MASK_GREVW)
+DECLARE_INSN(slow, MATCH_SLOW, MASK_SLOW)
+DECLARE_INSN(srow, MATCH_SROW, MASK_SROW)
+DECLARE_INSN(rolw, MATCH_ROLW, MASK_ROLW)
+DECLARE_INSN(rorw, MATCH_RORW, MASK_RORW)
+DECLARE_INSN(sbsetw, MATCH_SBSETW, MASK_SBSETW)
+DECLARE_INSN(sbclrw, MATCH_SBCLRW, MASK_SBCLRW)
+DECLARE_INSN(sbinvw, MATCH_SBINVW, MASK_SBINVW)
+DECLARE_INSN(sbextw, MATCH_SBEXTW, MASK_SBEXTW)
+DECLARE_INSN(greviw, MATCH_GREVIW, MASK_GREVIW)
+DECLARE_INSN(sloiw, MATCH_SLOIW, MASK_SLOIW)
+DECLARE_INSN(sroiw, MATCH_SROIW, MASK_SROIW)
+DECLARE_INSN(roriw, MATCH_RORIW, MASK_RORIW)
+DECLARE_INSN(sbsetiw, MATCH_SBSETIW, MASK_SBSETIW)
+DECLARE_INSN(sbclriw, MATCH_SBCLRIW, MASK_SBCLRIW)
+DECLARE_INSN(sbinviw, MATCH_SBINVIW, MASK_SBINVIW)
+DECLARE_INSN(fslw, MATCH_FSLW, MASK_FSLW)
+DECLARE_INSN(fsrw, MATCH_FSRW, MASK_FSRW)
+DECLARE_INSN(fsriw, MATCH_FSRIW, MASK_FSRIW)
+DECLARE_INSN(clzw, MATCH_CLZW, MASK_CLZW)
+DECLARE_INSN(ctzw, MATCH_CTZW, MASK_CTZW)
+DECLARE_INSN(pcntw, MATCH_PCNTW, MASK_PCNTW)
+DECLARE_INSN(clmulw, MATCH_CLMULW, MASK_CLMULW)
+DECLARE_INSN(clmulrw, MATCH_CLMULRW, MASK_CLMULRW)
+DECLARE_INSN(clmulhw, MATCH_CLMULHW, MASK_CLMULHW)
+DECLARE_INSN(shflw, MATCH_SHFLW, MASK_SHFLW)
+DECLARE_INSN(unshflw, MATCH_UNSHFLW, MASK_UNSHFLW)
+DECLARE_INSN(bdepw, MATCH_BDEPW, MASK_BDEPW)
+DECLARE_INSN(bextw, MATCH_BEXTW, MASK_BEXTW)
+DECLARE_INSN(packw, MATCH_PACKW, MASK_PACKW)
DECLARE_INSN(amoadd_w, MATCH_AMOADD_W, MASK_AMOADD_W)
DECLARE_INSN(amoxor_w, MATCH_AMOXOR_W, MASK_AMOXOR_W)
DECLARE_INSN(amoor_w, MATCH_AMOOR_W, MASK_AMOOR_W)
diff --git a/riscv/insns/addiwu.h b/riscv/insns/addiwu.h
new file mode 100644
index 0000000..5ba1427
--- /dev/null
+++ b/riscv/insns/addiwu.h
@@ -0,0 +1,3 @@
+require_rv64;
+require_extension('B');
+WRITE_RD(zext32(insn.i_imm() + RS1));
diff --git a/riscv/insns/addu_w.h b/riscv/insns/addu_w.h
new file mode 100644
index 0000000..4c34449
--- /dev/null
+++ b/riscv/insns/addu_w.h
@@ -0,0 +1,3 @@
+require_rv64;
+require_extension('B');
+WRITE_RD(sext_xlen(RS1 + zext32(RS2)));
diff --git a/riscv/insns/addwu.h b/riscv/insns/addwu.h
new file mode 100644
index 0000000..cc40683
--- /dev/null
+++ b/riscv/insns/addwu.h
@@ -0,0 +1,3 @@
+require_rv64;
+require_extension('B');
+WRITE_RD(zext32(RS1 + RS2));
diff --git a/riscv/insns/andn.h b/riscv/insns/andn.h
new file mode 100644
index 0000000..4582aac
--- /dev/null
+++ b/riscv/insns/andn.h
@@ -0,0 +1,2 @@
+require_extension('B');
+WRITE_RD(RS1 & ~RS2);
diff --git a/riscv/insns/bdep.h b/riscv/insns/bdep.h
new file mode 100644
index 0000000..059a1cd
--- /dev/null
+++ b/riscv/insns/bdep.h
@@ -0,0 +1,9 @@
+require_extension('B');
+uint64_t c = 0, i = 0, data = zext_xlen(RS1), mask = zext_xlen(RS2);
+while (mask) {
+ uint64_t b = mask & ~((mask | (mask-1)) + 1);
+ c |= (data << (__builtin_ctzl(b) - i)) & b;
+ i += __builtin_popcountl(b);
+ mask -= b;
+}
+WRITE_RD(sext_xlen(c));
diff --git a/riscv/insns/bdepw.h b/riscv/insns/bdepw.h
new file mode 100644
index 0000000..fc2e9c3
--- /dev/null
+++ b/riscv/insns/bdepw.h
@@ -0,0 +1,10 @@
+require_rv64;
+require_extension('B');
+uint64_t c = 0, i = 0, data = zext32(RS1), mask = zext32(RS2);
+while (mask) {
+ uint64_t b = mask & ~((mask | (mask-1)) + 1);
+ c |= (data << (__builtin_ctzl(b) - i)) & b;
+ i += __builtin_popcountl(b);
+ mask -= b;
+}
+WRITE_RD(sext32(c));
diff --git a/riscv/insns/bext.h b/riscv/insns/bext.h
new file mode 100644
index 0000000..50d9bb2
--- /dev/null
+++ b/riscv/insns/bext.h
@@ -0,0 +1,9 @@
+require_extension('B');
+uint64_t c = 0, i = 0, data = zext_xlen(RS1), mask = zext_xlen(RS2);
+while (mask) {
+ uint64_t b = mask & ~((mask | (mask-1)) + 1);
+ c |= (data & b) >> (__builtin_ctzl(b) - i);
+ i += __builtin_popcountl(b);
+ mask -= b;
+}
+WRITE_RD(sext_xlen(c));
diff --git a/riscv/insns/bextw.h b/riscv/insns/bextw.h
new file mode 100644
index 0000000..90f3d45
--- /dev/null
+++ b/riscv/insns/bextw.h
@@ -0,0 +1,10 @@
+require_rv64;
+require_extension('B');
+uint64_t c = 0, i = 0, data = zext32(RS1), mask = zext32(RS2);
+while (mask) {
+ uint64_t b = mask & ~((mask | (mask-1)) + 1);
+ c |= (data & b) >> (__builtin_ctzl(b) - i);
+ i += __builtin_popcountl(b);
+ mask -= b;
+}
+WRITE_RD(sext32(c));
diff --git a/riscv/insns/bmatflip.h b/riscv/insns/bmatflip.h
new file mode 100644
index 0000000..e137f10
--- /dev/null
+++ b/riscv/insns/bmatflip.h
@@ -0,0 +1,11 @@
+require_rv64;
+require_extension('B');
+reg_t x = RS1;
+for (int i = 0; i < 3; i++) {
+ x = (x & 0xFFFF00000000FFFFLL) | ((x & 0x0000FFFF00000000LL) >> 16) | ((x & 0x00000000FFFF0000LL) << 16);
+ x = (x & 0xFF0000FFFF0000FFLL) | ((x & 0x00FF000000FF0000LL) >> 8) | ((x & 0x0000FF000000FF00LL) << 8);
+ x = (x & 0xF00FF00FF00FF00FLL) | ((x & 0x0F000F000F000F00LL) >> 4) | ((x & 0x00F000F000F000F0LL) << 4);
+ x = (x & 0xC3C3C3C3C3C3C3C3LL) | ((x & 0x3030303030303030LL) >> 2) | ((x & 0x0C0C0C0C0C0C0C0CLL) << 2);
+ x = (x & 0x9999999999999999LL) | ((x & 0x4444444444444444LL) >> 1) | ((x & 0x2222222222222222LL) << 1);
+}
+WRITE_RD(sext_xlen(x));
diff --git a/riscv/insns/bmator.h b/riscv/insns/bmator.h
new file mode 100644
index 0000000..2d57228
--- /dev/null
+++ b/riscv/insns/bmator.h
@@ -0,0 +1,29 @@
+require_rv64;
+require_extension('B');
+
+// transpose of rs2
+int64_t rs2t = RS2;
+for (int i = 0; i < 3; i++) {
+ rs2t = (rs2t & 0xFFFF00000000FFFFLL) | ((rs2t & 0x0000FFFF00000000LL) >> 16) | ((rs2t & 0x00000000FFFF0000LL) << 16);
+ rs2t = (rs2t & 0xFF0000FFFF0000FFLL) | ((rs2t & 0x00FF000000FF0000LL) >> 8) | ((rs2t & 0x0000FF000000FF00LL) << 8);
+ rs2t = (rs2t & 0xF00FF00FF00FF00FLL) | ((rs2t & 0x0F000F000F000F00LL) >> 4) | ((rs2t & 0x00F000F000F000F0LL) << 4);
+ rs2t = (rs2t & 0xC3C3C3C3C3C3C3C3LL) | ((rs2t & 0x3030303030303030LL) >> 2) | ((rs2t & 0x0C0C0C0C0C0C0C0CLL) << 2);
+ rs2t = (rs2t & 0x9999999999999999LL) | ((rs2t & 0x4444444444444444LL) >> 1) | ((rs2t & 0x2222222222222222LL) << 1);
+}
+
+int64_t rs1 = RS1;
+uint8_t u[8]; // rows of rs1
+uint8_t v[8]; // cols of rs2
+
+for (int i = 0; i < 8; i++) {
+ u[i] = rs1 >> (i*8);
+ v[i] = rs2t >> (i*8);
+}
+
+uint64_t x = 0;
+for (int i = 0; i < 64; i++) {
+ if ((u[i / 8] & v[i % 8]) != 0)
+ x |= 1LL << i;
+}
+
+WRITE_RD(sext_xlen(x));
diff --git a/riscv/insns/bmatxor.h b/riscv/insns/bmatxor.h
new file mode 100644
index 0000000..06d9db0
--- /dev/null
+++ b/riscv/insns/bmatxor.h
@@ -0,0 +1,29 @@
+require_rv64;
+require_extension('B');
+
+// transpose of rs2
+int64_t rs2t = RS2;
+for (int i = 0; i < 3; i++) {
+ rs2t = (rs2t & 0xFFFF00000000FFFFLL) | ((rs2t & 0x0000FFFF00000000LL) >> 16) | ((rs2t & 0x00000000FFFF0000LL) << 16);
+ rs2t = (rs2t & 0xFF0000FFFF0000FFLL) | ((rs2t & 0x00FF000000FF0000LL) >> 8) | ((rs2t & 0x0000FF000000FF00LL) << 8);
+ rs2t = (rs2t & 0xF00FF00FF00FF00FLL) | ((rs2t & 0x0F000F000F000F00LL) >> 4) | ((rs2t & 0x00F000F000F000F0LL) << 4);
+ rs2t = (rs2t & 0xC3C3C3C3C3C3C3C3LL) | ((rs2t & 0x3030303030303030LL) >> 2) | ((rs2t & 0x0C0C0C0C0C0C0C0CLL) << 2);
+ rs2t = (rs2t & 0x9999999999999999LL) | ((rs2t & 0x4444444444444444LL) >> 1) | ((rs2t & 0x2222222222222222LL) << 1);
+}
+
+int64_t rs1 = RS1;
+uint8_t u[8]; // rows of rs1
+uint8_t v[8]; // cols of rs2
+
+for (int i = 0; i < 8; i++) {
+ u[i] = rs1 >> (i*8);
+ v[i] = rs2t >> (i*8);
+}
+
+uint64_t x = 0;
+for (int i = 0; i < 64; i++) {
+ if (__builtin_popcountl(u[i / 8] & v[i % 8]) & 1)
+ x |= 1LL << i;
+}
+
+WRITE_RD(sext_xlen(x));
diff --git a/riscv/insns/clmul.h b/riscv/insns/clmul.h
new file mode 100644
index 0000000..9601567
--- /dev/null
+++ b/riscv/insns/clmul.h
@@ -0,0 +1,6 @@
+require_extension('B');
+reg_t a = zext_xlen(RS1), b = zext_xlen(RS2), x = 0;
+for (int i = 0; i < xlen; i++)
+ if ((b >> i) & 1)
+ x ^= a << i;
+WRITE_RD(sext_xlen(x));
diff --git a/riscv/insns/clmulh.h b/riscv/insns/clmulh.h
new file mode 100644
index 0000000..68a50e3
--- /dev/null
+++ b/riscv/insns/clmulh.h
@@ -0,0 +1,6 @@
+require_extension('B');
+reg_t a = zext_xlen(RS1), b = zext_xlen(RS2), x = 0;
+for (int i = 1; i < xlen; i++)
+ if ((b >> i) & 1)
+ x ^= a >> (xlen-i);
+WRITE_RD(sext_xlen(x));
diff --git a/riscv/insns/clmulhw.h b/riscv/insns/clmulhw.h
new file mode 100644
index 0000000..75f64ec
--- /dev/null
+++ b/riscv/insns/clmulhw.h
@@ -0,0 +1,6 @@
+require_extension('B');
+reg_t a = zext32(RS1), b = zext32(RS2), x = 0;
+for (int i = 1; i < 32; i++)
+ if ((b >> i) & 1)
+ x ^= a >> (32-i);
+WRITE_RD(sext32(x));
diff --git a/riscv/insns/clmulr.h b/riscv/insns/clmulr.h
new file mode 100644
index 0000000..f07487e
--- /dev/null
+++ b/riscv/insns/clmulr.h
@@ -0,0 +1,6 @@
+require_extension('B');
+reg_t a = zext_xlen(RS1), b = zext_xlen(RS2), x = 0;
+for (int i = 0; i < xlen; i++)
+ if ((b >> i) & 1)
+ x ^= a >> (xlen-i-1);
+WRITE_RD(sext_xlen(x));
diff --git a/riscv/insns/clmulrw.h b/riscv/insns/clmulrw.h
new file mode 100644
index 0000000..6fc9008
--- /dev/null
+++ b/riscv/insns/clmulrw.h
@@ -0,0 +1,6 @@
+require_extension('B');
+reg_t a = zext32(RS1), b = zext32(RS2), x = 0;
+for (int i = 0; i < 32; i++)
+ if ((b >> i) & 1)
+ x ^= a >> (31-i);
+WRITE_RD(sext32(x));
diff --git a/riscv/insns/clmulw.h b/riscv/insns/clmulw.h
new file mode 100644
index 0000000..69d0f43
--- /dev/null
+++ b/riscv/insns/clmulw.h
@@ -0,0 +1,6 @@
+require_extension('B');
+reg_t a = zext32(RS1), b = zext32(RS2), x = 0;
+for (int i = 0; i < 32; i++)
+ if ((b >> i) & 1)
+ x ^= a << i;
+WRITE_RD(sext32(x));
diff --git a/riscv/insns/clz.h b/riscv/insns/clz.h
new file mode 100644
index 0000000..6821b2d
--- /dev/null
+++ b/riscv/insns/clz.h
@@ -0,0 +1,5 @@
+require_extension('B');
+reg_t x = xlen;
+for (int i = 0; i < xlen; i++)
+ if (1 & (RS1 >> (xlen-i-1))) { x = i; break; }
+WRITE_RD(sext_xlen(x));
diff --git a/riscv/insns/clzw.h b/riscv/insns/clzw.h
new file mode 100644
index 0000000..6313554
--- /dev/null
+++ b/riscv/insns/clzw.h
@@ -0,0 +1,6 @@
+require_rv64;
+require_extension('B');
+reg_t x = 32;
+for (int i = 0; i < 32; i++)
+ if (1 & (RS1 >> (31-i))) { x = i; break; }
+WRITE_RD(sext32(x));
diff --git a/riscv/insns/cmix.h b/riscv/insns/cmix.h
new file mode 100644
index 0000000..727f136
--- /dev/null
+++ b/riscv/insns/cmix.h
@@ -0,0 +1,2 @@
+require_extension('B');
+WRITE_RD((RS1 & RS2) | (RS3 & ~RS2));
diff --git a/riscv/insns/cmov.h b/riscv/insns/cmov.h
new file mode 100644
index 0000000..eeae7e2
--- /dev/null
+++ b/riscv/insns/cmov.h
@@ -0,0 +1,2 @@
+require_extension('B');
+WRITE_RD(RS2 ? RS1 : RS3);
diff --git a/riscv/insns/crc32_b.h b/riscv/insns/crc32_b.h
new file mode 100644
index 0000000..8f04e56
--- /dev/null
+++ b/riscv/insns/crc32_b.h
@@ -0,0 +1,5 @@
+require_extension('B');
+reg_t x = RS1;
+for (int i = 0; i < 8; i++)
+ x = (x >> 1) ^ (0xEDB88320 & ~((x&1)-1));
+WRITE_RD(sext_xlen(x));
diff --git a/riscv/insns/crc32_d.h b/riscv/insns/crc32_d.h
new file mode 100644
index 0000000..e4f1583
--- /dev/null
+++ b/riscv/insns/crc32_d.h
@@ -0,0 +1,5 @@
+require_extension('B');
+reg_t x = RS1;
+for (int i = 0; i < 64; i++)
+ x = (x >> 1) ^ (0xEDB88320 & ~((x&1)-1));
+WRITE_RD(sext_xlen(x));
diff --git a/riscv/insns/crc32_h.h b/riscv/insns/crc32_h.h
new file mode 100644
index 0000000..aa4c0b8
--- /dev/null
+++ b/riscv/insns/crc32_h.h
@@ -0,0 +1,5 @@
+require_extension('B');
+reg_t x = RS1;
+for (int i = 0; i < 16; i++)
+ x = (x >> 1) ^ (0xEDB88320 & ~((x&1)-1));
+WRITE_RD(sext_xlen(x));
diff --git a/riscv/insns/crc32_w.h b/riscv/insns/crc32_w.h
new file mode 100644
index 0000000..c8874a1
--- /dev/null
+++ b/riscv/insns/crc32_w.h
@@ -0,0 +1,5 @@
+require_extension('B');
+reg_t x = RS1;
+for (int i = 0; i < 32; i++)
+ x = (x >> 1) ^ (0xEDB88320 & ~((x&1)-1));
+WRITE_RD(sext_xlen(x));
diff --git a/riscv/insns/crc32c_b.h b/riscv/insns/crc32c_b.h
new file mode 100644
index 0000000..89a218a
--- /dev/null
+++ b/riscv/insns/crc32c_b.h
@@ -0,0 +1,5 @@
+require_extension('B');
+reg_t x = RS1;
+for (int i = 0; i < 8; i++)
+ x = (x >> 1) ^ (0x82F63B78 & ~((x&1)-1));
+WRITE_RD(sext_xlen(x));
diff --git a/riscv/insns/crc32c_d.h b/riscv/insns/crc32c_d.h
new file mode 100644
index 0000000..862407c
--- /dev/null
+++ b/riscv/insns/crc32c_d.h
@@ -0,0 +1,5 @@
+require_extension('B');
+reg_t x = RS1;
+for (int i = 0; i < 64; i++)
+ x = (x >> 1) ^ (0x82F63B78 & ~((x&1)-1));
+WRITE_RD(sext_xlen(x));
diff --git a/riscv/insns/crc32c_h.h b/riscv/insns/crc32c_h.h
new file mode 100644
index 0000000..c5956b9
--- /dev/null
+++ b/riscv/insns/crc32c_h.h
@@ -0,0 +1,5 @@
+require_extension('B');
+reg_t x = RS1;
+for (int i = 0; i < 16; i++)
+ x = (x >> 1) ^ (0x82F63B78 & ~((x&1)-1));
+WRITE_RD(sext_xlen(x));
diff --git a/riscv/insns/crc32c_w.h b/riscv/insns/crc32c_w.h
new file mode 100644
index 0000000..137a369
--- /dev/null
+++ b/riscv/insns/crc32c_w.h
@@ -0,0 +1,5 @@
+require_extension('B');
+reg_t x = RS1;
+for (int i = 0; i < 32; i++)
+ x = (x >> 1) ^ (0x82F63B78 & ~((x&1)-1));
+WRITE_RD(sext_xlen(x));
diff --git a/riscv/insns/ctz.h b/riscv/insns/ctz.h
new file mode 100644
index 0000000..889de0f
--- /dev/null
+++ b/riscv/insns/ctz.h
@@ -0,0 +1,5 @@
+require_extension('B');
+reg_t x = xlen;
+for (int i = 0; i < xlen; i++)
+ if (1 & (RS1 >> i)) { x = i; break; }
+WRITE_RD(sext_xlen(x));
diff --git a/riscv/insns/ctzw.h b/riscv/insns/ctzw.h
new file mode 100644
index 0000000..59f58ad
--- /dev/null
+++ b/riscv/insns/ctzw.h
@@ -0,0 +1,6 @@
+require_rv64;
+require_extension('B');
+reg_t x = 32;
+for (int i = 0; i < 32; i++)
+ if (1 & (RS1 >> i)) { x = i; break; }
+WRITE_RD(sext32(x));
diff --git a/riscv/insns/fsl.h b/riscv/insns/fsl.h
new file mode 100644
index 0000000..fdf02ad
--- /dev/null
+++ b/riscv/insns/fsl.h
@@ -0,0 +1,9 @@
+require_extension('B');
+int shamt = RS2 & (2*xlen-1);
+reg_t a = RS1, b = RS3;
+if (shamt >= xlen) {
+ a = RS3, b = RS1;
+ shamt -= xlen;
+}
+int rshamt = -shamt & (xlen-1);
+WRITE_RD(sext_xlen(shamt ? (a << shamt) | (zext_xlen(b) >> rshamt) : a));
diff --git a/riscv/insns/fslw.h b/riscv/insns/fslw.h
new file mode 100644
index 0000000..04ab04f
--- /dev/null
+++ b/riscv/insns/fslw.h
@@ -0,0 +1,10 @@
+require_rv64;
+require_extension('B');
+int shamt = RS2 & 63;
+reg_t a = RS1, b = RS3;
+if (shamt >= 32) {
+ a = RS3, b = RS1;
+ shamt -= 32;
+}
+int rshamt = -shamt & 31;
+WRITE_RD(sext32(shamt ? (a << shamt) | (zext32(b) >> rshamt) : a));
diff --git a/riscv/insns/fsr.h b/riscv/insns/fsr.h
new file mode 100644
index 0000000..18a1e69
--- /dev/null
+++ b/riscv/insns/fsr.h
@@ -0,0 +1,9 @@
+require_extension('B');
+int shamt = RS2 & (2*xlen-1);
+reg_t a = RS1, b = RS3;
+if (shamt >= xlen) {
+ a = RS3, b = RS1;
+ shamt -= xlen;
+}
+int rshamt = -shamt & (xlen-1);
+WRITE_RD(sext_xlen(shamt ? (b << rshamt) | (zext_xlen(a) >> shamt) : a));
diff --git a/riscv/insns/fsri.h b/riscv/insns/fsri.h
new file mode 100644
index 0000000..2d41c82
--- /dev/null
+++ b/riscv/insns/fsri.h
@@ -0,0 +1,9 @@
+require_extension('B');
+int shamt = SHAMT & (2*xlen-1);
+reg_t a = RS1, b = RS3;
+if (shamt >= xlen) {
+ a = RS3, b = RS1;
+ shamt -= xlen;
+}
+int rshamt = -shamt & (xlen-1);
+WRITE_RD(sext_xlen(shamt ? (b << rshamt) | (zext_xlen(a) >> shamt) : a));
diff --git a/riscv/insns/fsriw.h b/riscv/insns/fsriw.h
new file mode 100644
index 0000000..31983c9
--- /dev/null
+++ b/riscv/insns/fsriw.h
@@ -0,0 +1,10 @@
+require_rv64;
+require_extension('B');
+int shamt = SHAMT & 63;
+reg_t a = RS1, b = RS3;
+if (shamt >= 32) {
+ a = RS3, b = RS1;
+ shamt -= 32;
+}
+int rshamt = -shamt & 31;
+WRITE_RD(sext32(shamt ? (b << rshamt) | (zext32(a) >> shamt) : a));
diff --git a/riscv/insns/fsrw.h b/riscv/insns/fsrw.h
new file mode 100644
index 0000000..1511fbe
--- /dev/null
+++ b/riscv/insns/fsrw.h
@@ -0,0 +1,10 @@
+require_rv64;
+require_extension('B');
+int shamt = RS2 & 63;
+reg_t a = RS1, b = RS3;
+if (shamt >= 32) {
+ a = RS3, b = RS1;
+ shamt -= 32;
+}
+int rshamt = -shamt & 31;
+WRITE_RD(sext32(shamt ? (b << rshamt) | (zext32(a) >> shamt) : a));
diff --git a/riscv/insns/grev.h b/riscv/insns/grev.h
new file mode 100644
index 0000000..b13fa5a
--- /dev/null
+++ b/riscv/insns/grev.h
@@ -0,0 +1,10 @@
+require_extension('B');
+reg_t x = RS1;
+int shamt = RS2 & (xlen-1);
+if (shamt & 1) x = ((x & 0x5555555555555555LL) << 1) | ((x & 0xAAAAAAAAAAAAAAAALL) >> 1);
+if (shamt & 2) x = ((x & 0x3333333333333333LL) << 2) | ((x & 0xCCCCCCCCCCCCCCCCLL) >> 2);
+if (shamt & 4) x = ((x & 0x0F0F0F0F0F0F0F0FLL) << 4) | ((x & 0xF0F0F0F0F0F0F0F0LL) >> 4);
+if (shamt & 8) x = ((x & 0x00FF00FF00FF00FFLL) << 8) | ((x & 0xFF00FF00FF00FF00LL) >> 8);
+if (shamt & 16) x = ((x & 0x0000FFFF0000FFFFLL) << 16) | ((x & 0xFFFF0000FFFF0000LL) >> 16);
+if (shamt & 32) x = ((x & 0x00000000FFFFFFFFLL) << 32) | ((x & 0xFFFFFFFF00000000LL) >> 32);
+WRITE_RD(sext_xlen(x));
diff --git a/riscv/insns/grevi.h b/riscv/insns/grevi.h
new file mode 100644
index 0000000..68213c6
--- /dev/null
+++ b/riscv/insns/grevi.h
@@ -0,0 +1,11 @@
+require_extension('B');
+require(SHAMT < xlen);
+reg_t x = RS1;
+int shamt = SHAMT;
+if (shamt & 1) x = ((x & 0x5555555555555555LL) << 1) | ((x & 0xAAAAAAAAAAAAAAAALL) >> 1);
+if (shamt & 2) x = ((x & 0x3333333333333333LL) << 2) | ((x & 0xCCCCCCCCCCCCCCCCLL) >> 2);
+if (shamt & 4) x = ((x & 0x0F0F0F0F0F0F0F0FLL) << 4) | ((x & 0xF0F0F0F0F0F0F0F0LL) >> 4);
+if (shamt & 8) x = ((x & 0x00FF00FF00FF00FFLL) << 8) | ((x & 0xFF00FF00FF00FF00LL) >> 8);
+if (shamt & 16) x = ((x & 0x0000FFFF0000FFFFLL) << 16) | ((x & 0xFFFF0000FFFF0000LL) >> 16);
+if (shamt & 32) x = ((x & 0x00000000FFFFFFFFLL) << 32) | ((x & 0xFFFFFFFF00000000LL) >> 32);
+WRITE_RD(sext_xlen(x));
diff --git a/riscv/insns/greviw.h b/riscv/insns/greviw.h
new file mode 100644
index 0000000..500096d
--- /dev/null
+++ b/riscv/insns/greviw.h
@@ -0,0 +1,11 @@
+require_rv64;
+require_extension('B');
+require(SHAMT < 32);
+reg_t x = RS1;
+int shamt = SHAMT;
+if (shamt & 1) x = ((x & 0x5555555555555555LL) << 1) | ((x & 0xAAAAAAAAAAAAAAAALL) >> 1);
+if (shamt & 2) x = ((x & 0x3333333333333333LL) << 2) | ((x & 0xCCCCCCCCCCCCCCCCLL) >> 2);
+if (shamt & 4) x = ((x & 0x0F0F0F0F0F0F0F0FLL) << 4) | ((x & 0xF0F0F0F0F0F0F0F0LL) >> 4);
+if (shamt & 8) x = ((x & 0x00FF00FF00FF00FFLL) << 8) | ((x & 0xFF00FF00FF00FF00LL) >> 8);
+if (shamt & 16) x = ((x & 0x0000FFFF0000FFFFLL) << 16) | ((x & 0xFFFF0000FFFF0000LL) >> 16);
+WRITE_RD(sext32(x));
diff --git a/riscv/insns/grevw.h b/riscv/insns/grevw.h
new file mode 100644
index 0000000..274dd6f
--- /dev/null
+++ b/riscv/insns/grevw.h
@@ -0,0 +1,10 @@
+require_rv64;
+require_extension('B');
+reg_t x = RS1;
+int shamt = RS2 & 31;
+if (shamt & 1) x = ((x & 0x5555555555555555LL) << 1) | ((x & 0xAAAAAAAAAAAAAAAALL) >> 1);
+if (shamt & 2) x = ((x & 0x3333333333333333LL) << 2) | ((x & 0xCCCCCCCCCCCCCCCCLL) >> 2);
+if (shamt & 4) x = ((x & 0x0F0F0F0F0F0F0F0FLL) << 4) | ((x & 0xF0F0F0F0F0F0F0F0LL) >> 4);
+if (shamt & 8) x = ((x & 0x00FF00FF00FF00FFLL) << 8) | ((x & 0xFF00FF00FF00FF00LL) >> 8);
+if (shamt & 16) x = ((x & 0x0000FFFF0000FFFFLL) << 16) | ((x & 0xFFFF0000FFFF0000LL) >> 16);
+WRITE_RD(sext32(x));
diff --git a/riscv/insns/max.h b/riscv/insns/max.h
new file mode 100644
index 0000000..f57e722
--- /dev/null
+++ b/riscv/insns/max.h
@@ -0,0 +1,2 @@
+require_extension('B');
+WRITE_RD(sext_xlen(sreg_t(RS1) > sreg_t(RS2) ? RS1 : RS2));
diff --git a/riscv/insns/maxu.h b/riscv/insns/maxu.h
new file mode 100644
index 0000000..e1ecdf4
--- /dev/null
+++ b/riscv/insns/maxu.h
@@ -0,0 +1,2 @@
+require_extension('B');
+WRITE_RD(sext_xlen(RS1 > RS2 ? RS1 : RS2));
diff --git a/riscv/insns/min.h b/riscv/insns/min.h
new file mode 100644
index 0000000..1b2fadb
--- /dev/null
+++ b/riscv/insns/min.h
@@ -0,0 +1,2 @@
+require_extension('B');
+WRITE_RD(sext_xlen(sreg_t(RS1) < sreg_t(RS2) ? RS1 : RS2));
diff --git a/riscv/insns/minu.h b/riscv/insns/minu.h
new file mode 100644
index 0000000..fdf315e
--- /dev/null
+++ b/riscv/insns/minu.h
@@ -0,0 +1,2 @@
+require_extension('B');
+WRITE_RD(sext_xlen(RS1 < RS2 ? RS1 : RS2));
diff --git a/riscv/insns/orn.h b/riscv/insns/orn.h
new file mode 100644
index 0000000..670926f
--- /dev/null
+++ b/riscv/insns/orn.h
@@ -0,0 +1,2 @@
+require_extension('B');
+WRITE_RD(RS1 | ~RS2);
diff --git a/riscv/insns/pack.h b/riscv/insns/pack.h
new file mode 100644
index 0000000..841f24d
--- /dev/null
+++ b/riscv/insns/pack.h
@@ -0,0 +1,4 @@
+require_extension('B');
+reg_t lo = zext_xlen(RS1 << (xlen/2)) >> (xlen/2);
+reg_t hi = zext_xlen(RS2 << (xlen/2));
+WRITE_RD(sext_xlen(lo | hi));
diff --git a/riscv/insns/packw.h b/riscv/insns/packw.h
new file mode 100644
index 0000000..3da96bf
--- /dev/null
+++ b/riscv/insns/packw.h
@@ -0,0 +1,4 @@
+require_extension('B');
+reg_t lo = zext32(RS1 << 16) >> 16;
+reg_t hi = zext32(RS2 << 16);
+WRITE_RD(sext32(lo | hi));
diff --git a/riscv/insns/pcnt.h b/riscv/insns/pcnt.h
new file mode 100644
index 0000000..773e2e1
--- /dev/null
+++ b/riscv/insns/pcnt.h
@@ -0,0 +1,5 @@
+require_extension('B');
+reg_t x = 0;
+for (int i = 0; i < xlen; i++)
+ if (1 & (RS1 >> i)) x++;
+WRITE_RD(sext_xlen(x));
diff --git a/riscv/insns/pcntw.h b/riscv/insns/pcntw.h
new file mode 100644
index 0000000..13e9ba0
--- /dev/null
+++ b/riscv/insns/pcntw.h
@@ -0,0 +1,6 @@
+require_rv64;
+require_extension('B');
+reg_t x = 0;
+for (int i = 0; i < 32; i++)
+ if (1 & (RS1 >> i)) x++;
+WRITE_RD(sext32(x));
diff --git a/riscv/insns/rol.h b/riscv/insns/rol.h
new file mode 100644
index 0000000..2b15c93
--- /dev/null
+++ b/riscv/insns/rol.h
@@ -0,0 +1,4 @@
+require_extension('B');
+int shamt = RS2 & (xlen-1);
+int rshamt = -shamt & (xlen-1);
+WRITE_RD(sext_xlen((RS1 << shamt) | (zext_xlen(RS1) >> rshamt)));
diff --git a/riscv/insns/rolw.h b/riscv/insns/rolw.h
new file mode 100644
index 0000000..6d66a50
--- /dev/null
+++ b/riscv/insns/rolw.h
@@ -0,0 +1,5 @@
+require_rv64;
+require_extension('B');
+int shamt = RS2 & 31;
+int rshamt = -shamt & 31;
+WRITE_RD(sext32((RS1 << shamt) | (zext32(RS1) >> rshamt)));
diff --git a/riscv/insns/ror.h b/riscv/insns/ror.h
new file mode 100644
index 0000000..8788a12
--- /dev/null
+++ b/riscv/insns/ror.h
@@ -0,0 +1,4 @@
+require_extension('B');
+int shamt = RS2 & (xlen-1);
+int rshamt = -shamt & (xlen-1);
+WRITE_RD(sext_xlen((RS1 << rshamt) | (zext_xlen(RS1) >> shamt)));
diff --git a/riscv/insns/rori.h b/riscv/insns/rori.h
new file mode 100644
index 0000000..72f1529
--- /dev/null
+++ b/riscv/insns/rori.h
@@ -0,0 +1,5 @@
+require_extension('B');
+require(SHAMT < xlen);
+int shamt = SHAMT & (xlen-1);
+int rshamt = -shamt & (xlen-1);
+WRITE_RD(sext_xlen((RS1 << rshamt) | (zext_xlen(RS1) >> shamt)));
diff --git a/riscv/insns/roriw.h b/riscv/insns/roriw.h
new file mode 100644
index 0000000..d0b8d67
--- /dev/null
+++ b/riscv/insns/roriw.h
@@ -0,0 +1,5 @@
+require_extension('B');
+require(SHAMT < 32);
+int shamt = SHAMT & 31;
+int rshamt = -shamt & 31;
+WRITE_RD(sext32((RS1 << rshamt) | (zext32(RS1) >> shamt)));
diff --git a/riscv/insns/rorw.h b/riscv/insns/rorw.h
new file mode 100644
index 0000000..b42ab73
--- /dev/null
+++ b/riscv/insns/rorw.h
@@ -0,0 +1,5 @@
+require_rv64;
+require_extension('B');
+int shamt = RS2 & 31;
+int rshamt = -shamt & 31;
+WRITE_RD(sext32((RS1 << rshamt) | (zext32(RS1) >> shamt)));
diff --git a/riscv/insns/sbclr.h b/riscv/insns/sbclr.h
new file mode 100644
index 0000000..f0b0e0a
--- /dev/null
+++ b/riscv/insns/sbclr.h
@@ -0,0 +1,3 @@
+require_extension('B');
+int shamt = RS2 & (xlen-1);
+WRITE_RD(sext_xlen(RS1 & ~(1LL << shamt)));
diff --git a/riscv/insns/sbclri.h b/riscv/insns/sbclri.h
new file mode 100644
index 0000000..546dcaa
--- /dev/null
+++ b/riscv/insns/sbclri.h
@@ -0,0 +1,3 @@
+require_extension('B');
+int shamt = SHAMT & (xlen-1);
+WRITE_RD(sext_xlen(RS1 & ~(1LL << shamt)));
diff --git a/riscv/insns/sbclriw.h b/riscv/insns/sbclriw.h
new file mode 100644
index 0000000..3a26fe0
--- /dev/null
+++ b/riscv/insns/sbclriw.h
@@ -0,0 +1,3 @@
+require_extension('B');
+int shamt = SHAMT & 31;
+WRITE_RD(sext32(RS1 & ~(1LL << shamt)));
diff --git a/riscv/insns/sbclrw.h b/riscv/insns/sbclrw.h
new file mode 100644
index 0000000..e089298
--- /dev/null
+++ b/riscv/insns/sbclrw.h
@@ -0,0 +1,3 @@
+require_extension('B');
+int shamt = RS2 & 31;
+WRITE_RD(sext32(RS1 & ~(1LL << shamt)));
diff --git a/riscv/insns/sbext.h b/riscv/insns/sbext.h
new file mode 100644
index 0000000..7149a2a
--- /dev/null
+++ b/riscv/insns/sbext.h
@@ -0,0 +1,3 @@
+require_extension('B');
+int shamt = RS2 & (xlen-1);
+WRITE_RD(sext_xlen(1 & (RS1 >> shamt)));
diff --git a/riscv/insns/sbexti.h b/riscv/insns/sbexti.h
new file mode 100644
index 0000000..c930cfb
--- /dev/null
+++ b/riscv/insns/sbexti.h
@@ -0,0 +1,3 @@
+require_extension('B');
+int shamt = SHAMT & (xlen-1);
+WRITE_RD(sext_xlen(1 & (RS1 >> shamt)));
diff --git a/riscv/insns/sbextw.h b/riscv/insns/sbextw.h
new file mode 100644
index 0000000..1041453
--- /dev/null
+++ b/riscv/insns/sbextw.h
@@ -0,0 +1,3 @@
+require_extension('B');
+int shamt = RS2 & 31;
+WRITE_RD(sext32(1 & (RS1 >> shamt)));
diff --git a/riscv/insns/sbinv.h b/riscv/insns/sbinv.h
new file mode 100644
index 0000000..5892252
--- /dev/null
+++ b/riscv/insns/sbinv.h
@@ -0,0 +1,3 @@
+require_extension('B');
+int shamt = RS2 & (xlen-1);
+WRITE_RD(sext_xlen(RS1 ^ (1LL << shamt)));
diff --git a/riscv/insns/sbinvi.h b/riscv/insns/sbinvi.h
new file mode 100644
index 0000000..f67143c
--- /dev/null
+++ b/riscv/insns/sbinvi.h
@@ -0,0 +1,3 @@
+require_extension('B');
+int shamt = SHAMT & (xlen-1);
+WRITE_RD(sext_xlen(RS1 ^ (1LL << shamt)));
diff --git a/riscv/insns/sbinviw.h b/riscv/insns/sbinviw.h
new file mode 100644
index 0000000..80fef91
--- /dev/null
+++ b/riscv/insns/sbinviw.h
@@ -0,0 +1,3 @@
+require_extension('B');
+int shamt = SHAMT & 31;
+WRITE_RD(sext32(RS1 ^ (1LL << shamt)));
diff --git a/riscv/insns/sbinvw.h b/riscv/insns/sbinvw.h
new file mode 100644
index 0000000..1b9ccfd
--- /dev/null
+++ b/riscv/insns/sbinvw.h
@@ -0,0 +1,3 @@
+require_extension('B');
+int shamt = RS2 & 31;
+WRITE_RD(sext32(RS1 ^ (1LL << shamt)));
diff --git a/riscv/insns/sbset.h b/riscv/insns/sbset.h
new file mode 100644
index 0000000..0e3f0fc
--- /dev/null
+++ b/riscv/insns/sbset.h
@@ -0,0 +1,3 @@
+require_extension('B');
+int shamt = RS2 & (xlen-1);
+WRITE_RD(sext_xlen(RS1 | (1LL << shamt)));
diff --git a/riscv/insns/sbseti.h b/riscv/insns/sbseti.h
new file mode 100644
index 0000000..44aa8bb
--- /dev/null
+++ b/riscv/insns/sbseti.h
@@ -0,0 +1,3 @@
+require_extension('B');
+int shamt = SHAMT & (xlen-1);
+WRITE_RD(sext_xlen(RS1 | (1LL << shamt)));
diff --git a/riscv/insns/sbsetiw.h b/riscv/insns/sbsetiw.h
new file mode 100644
index 0000000..dcfc6b1
--- /dev/null
+++ b/riscv/insns/sbsetiw.h
@@ -0,0 +1,3 @@
+require_extension('B');
+int shamt = SHAMT & 31;
+WRITE_RD(sext32(RS1 | (1LL << shamt)));
diff --git a/riscv/insns/sbsetw.h b/riscv/insns/sbsetw.h
new file mode 100644
index 0000000..c65199a
--- /dev/null
+++ b/riscv/insns/sbsetw.h
@@ -0,0 +1,3 @@
+require_extension('B');
+int shamt = RS2 & 31;
+WRITE_RD(sext32(RS1 | (1LL << shamt)));
diff --git a/riscv/insns/shfl.h b/riscv/insns/shfl.h
new file mode 100644
index 0000000..5d41336
--- /dev/null
+++ b/riscv/insns/shfl.h
@@ -0,0 +1,9 @@
+require_extension('B');
+reg_t x = RS1;
+int shamt = RS2 & (xlen-1);
+if (shamt & 16) x = (x & 0xFFFF00000000FFFFLL) | ((x & 0x0000FFFF00000000LL) >> 16) | ((x & 0x00000000FFFF0000LL) << 16);
+if (shamt & 8) x = (x & 0xFF0000FFFF0000FFLL) | ((x & 0x00FF000000FF0000LL) >> 8) | ((x & 0x0000FF000000FF00LL) << 8);
+if (shamt & 4) x = (x & 0xF00FF00FF00FF00FLL) | ((x & 0x0F000F000F000F00LL) >> 4) | ((x & 0x00F000F000F000F0LL) << 4);
+if (shamt & 2) x = (x & 0xC3C3C3C3C3C3C3C3LL) | ((x & 0x3030303030303030LL) >> 2) | ((x & 0x0C0C0C0C0C0C0C0CLL) << 2);
+if (shamt & 1) x = (x & 0x9999999999999999LL) | ((x & 0x4444444444444444LL) >> 1) | ((x & 0x2222222222222222LL) << 1);
+WRITE_RD(sext_xlen(x));
diff --git a/riscv/insns/shfli.h b/riscv/insns/shfli.h
new file mode 100644
index 0000000..964638e
--- /dev/null
+++ b/riscv/insns/shfli.h
@@ -0,0 +1,10 @@
+require_extension('B');
+require(SHAMT < (xlen/2));
+reg_t x = RS1;
+int shamt = SHAMT & (xlen-1);
+if (shamt & 16) x = (x & 0xFFFF00000000FFFFLL) | ((x & 0x0000FFFF00000000LL) >> 16) | ((x & 0x00000000FFFF0000LL) << 16);
+if (shamt & 8) x = (x & 0xFF0000FFFF0000FFLL) | ((x & 0x00FF000000FF0000LL) >> 8) | ((x & 0x0000FF000000FF00LL) << 8);
+if (shamt & 4) x = (x & 0xF00FF00FF00FF00FLL) | ((x & 0x0F000F000F000F00LL) >> 4) | ((x & 0x00F000F000F000F0LL) << 4);
+if (shamt & 2) x = (x & 0xC3C3C3C3C3C3C3C3LL) | ((x & 0x3030303030303030LL) >> 2) | ((x & 0x0C0C0C0C0C0C0C0CLL) << 2);
+if (shamt & 1) x = (x & 0x9999999999999999LL) | ((x & 0x4444444444444444LL) >> 1) | ((x & 0x2222222222222222LL) << 1);
+WRITE_RD(sext_xlen(x));
diff --git a/riscv/insns/shflw.h b/riscv/insns/shflw.h
new file mode 100644
index 0000000..8239a98
--- /dev/null
+++ b/riscv/insns/shflw.h
@@ -0,0 +1,9 @@
+require_rv64;
+require_extension('B');
+reg_t x = RS1;
+int shamt = RS2 & 15;
+if (shamt & 8) x = (x & 0xFF0000FFFF0000FFLL) | ((x & 0x00FF000000FF0000LL) >> 8) | ((x & 0x0000FF000000FF00LL) << 8);
+if (shamt & 4) x = (x & 0xF00FF00FF00FF00FLL) | ((x & 0x0F000F000F000F00LL) >> 4) | ((x & 0x00F000F000F000F0LL) << 4);
+if (shamt & 2) x = (x & 0xC3C3C3C3C3C3C3C3LL) | ((x & 0x3030303030303030LL) >> 2) | ((x & 0x0C0C0C0C0C0C0C0CLL) << 2);
+if (shamt & 1) x = (x & 0x9999999999999999LL) | ((x & 0x4444444444444444LL) >> 1) | ((x & 0x2222222222222222LL) << 1);
+WRITE_RD(sext32(x));
diff --git a/riscv/insns/slliu_w.h b/riscv/insns/slliu_w.h
new file mode 100644
index 0000000..99ac5f8
--- /dev/null
+++ b/riscv/insns/slliu_w.h
@@ -0,0 +1,3 @@
+require_rv64;
+require_extension('B');
+WRITE_RD(sext_xlen(zext32(RS1) << SHAMT));
diff --git a/riscv/insns/slo.h b/riscv/insns/slo.h
new file mode 100644
index 0000000..0836cf8
--- /dev/null
+++ b/riscv/insns/slo.h
@@ -0,0 +1,2 @@
+require_extension('B');
+WRITE_RD(sext_xlen(~((~RS1) << (RS2 & (xlen-1)))));
diff --git a/riscv/insns/sloi.h b/riscv/insns/sloi.h
new file mode 100644
index 0000000..216cf9c
--- /dev/null
+++ b/riscv/insns/sloi.h
@@ -0,0 +1,3 @@
+require(SHAMT < xlen);
+require_extension('B');
+WRITE_RD(sext_xlen(~((~RS1) << SHAMT)));
diff --git a/riscv/insns/sloiw.h b/riscv/insns/sloiw.h
new file mode 100644
index 0000000..5ec7576
--- /dev/null
+++ b/riscv/insns/sloiw.h
@@ -0,0 +1,3 @@
+require_rv64;
+require_extension('B');
+WRITE_RD(sext32(~((~RS1) << SHAMT)));
diff --git a/riscv/insns/slow.h b/riscv/insns/slow.h
new file mode 100644
index 0000000..2f958c6
--- /dev/null
+++ b/riscv/insns/slow.h
@@ -0,0 +1,3 @@
+require_rv64;
+require_extension('B');
+WRITE_RD(sext32(~((~RS1) << (RS2 & 0x1F))));
diff --git a/riscv/insns/sro.h b/riscv/insns/sro.h
new file mode 100644
index 0000000..632e8dd
--- /dev/null
+++ b/riscv/insns/sro.h
@@ -0,0 +1,2 @@
+require_extension('B');
+WRITE_RD(sext_xlen(~((~zext_xlen(RS1)) >> (RS2 & (xlen-1)))));
diff --git a/riscv/insns/sroi.h b/riscv/insns/sroi.h
new file mode 100644
index 0000000..b9b73bf
--- /dev/null
+++ b/riscv/insns/sroi.h
@@ -0,0 +1,3 @@
+require(SHAMT < xlen);
+require_extension('B');
+WRITE_RD(sext_xlen(~((~zext_xlen(RS1)) >> SHAMT)));
diff --git a/riscv/insns/sroiw.h b/riscv/insns/sroiw.h
new file mode 100644
index 0000000..671af39
--- /dev/null
+++ b/riscv/insns/sroiw.h
@@ -0,0 +1,3 @@
+require_rv64;
+require_extension('B');
+WRITE_RD(sext32(~((~(uint32_t)RS1) >> SHAMT)));
diff --git a/riscv/insns/srow.h b/riscv/insns/srow.h
new file mode 100644
index 0000000..74ba73e
--- /dev/null
+++ b/riscv/insns/srow.h
@@ -0,0 +1,3 @@
+require_rv64;
+require_extension('B');
+WRITE_RD(sext32(~((~(uint32_t)RS1) >> (RS2 & 0x1F))));
diff --git a/riscv/insns/subu_w.h b/riscv/insns/subu_w.h
new file mode 100644
index 0000000..0afeb14
--- /dev/null
+++ b/riscv/insns/subu_w.h
@@ -0,0 +1,3 @@
+require_rv64;
+require_extension('B');
+WRITE_RD(sext_xlen(RS1 - zext32(RS2)));
diff --git a/riscv/insns/subwu.h b/riscv/insns/subwu.h
new file mode 100644
index 0000000..a97f6d7
--- /dev/null
+++ b/riscv/insns/subwu.h
@@ -0,0 +1,3 @@
+require_rv64;
+require_extension('B');
+WRITE_RD(zext32(RS1 - RS2));
diff --git a/riscv/insns/unshfl.h b/riscv/insns/unshfl.h
new file mode 100644
index 0000000..bc50f70
--- /dev/null
+++ b/riscv/insns/unshfl.h
@@ -0,0 +1,9 @@
+require_extension('B');
+reg_t x = RS1;
+int shamt = RS2 & (xlen-1);
+if (shamt & 1) x = (x & 0x9999999999999999LL) | ((x & 0x4444444444444444LL) >> 1) | ((x & 0x2222222222222222LL) << 1);
+if (shamt & 2) x = (x & 0xC3C3C3C3C3C3C3C3LL) | ((x & 0x3030303030303030LL) >> 2) | ((x & 0x0C0C0C0C0C0C0C0CLL) << 2);
+if (shamt & 4) x = (x & 0xF00FF00FF00FF00FLL) | ((x & 0x0F000F000F000F00LL) >> 4) | ((x & 0x00F000F000F000F0LL) << 4);
+if (shamt & 8) x = (x & 0xFF0000FFFF0000FFLL) | ((x & 0x00FF000000FF0000LL) >> 8) | ((x & 0x0000FF000000FF00LL) << 8);
+if (shamt & 16) x = (x & 0xFFFF00000000FFFFLL) | ((x & 0x0000FFFF00000000LL) >> 16) | ((x & 0x00000000FFFF0000LL) << 16);
+WRITE_RD(sext_xlen(x));
diff --git a/riscv/insns/unshfli.h b/riscv/insns/unshfli.h
new file mode 100644
index 0000000..af25d7d
--- /dev/null
+++ b/riscv/insns/unshfli.h
@@ -0,0 +1,10 @@
+require_extension('B');
+require(SHAMT < (xlen/2));
+reg_t x = RS1;
+int shamt = SHAMT & (xlen-1);
+if (shamt & 1) x = (x & 0x9999999999999999LL) | ((x & 0x4444444444444444LL) >> 1) | ((x & 0x2222222222222222LL) << 1);
+if (shamt & 2) x = (x & 0xC3C3C3C3C3C3C3C3LL) | ((x & 0x3030303030303030LL) >> 2) | ((x & 0x0C0C0C0C0C0C0C0CLL) << 2);
+if (shamt & 4) x = (x & 0xF00FF00FF00FF00FLL) | ((x & 0x0F000F000F000F00LL) >> 4) | ((x & 0x00F000F000F000F0LL) << 4);
+if (shamt & 8) x = (x & 0xFF0000FFFF0000FFLL) | ((x & 0x00FF000000FF0000LL) >> 8) | ((x & 0x0000FF000000FF00LL) << 8);
+if (shamt & 16) x = (x & 0xFFFF00000000FFFFLL) | ((x & 0x0000FFFF00000000LL) >> 16) | ((x & 0x00000000FFFF0000LL) << 16);
+WRITE_RD(sext_xlen(x));
diff --git a/riscv/insns/unshflw.h b/riscv/insns/unshflw.h
new file mode 100644
index 0000000..de5ceb5
--- /dev/null
+++ b/riscv/insns/unshflw.h
@@ -0,0 +1,9 @@
+require_rv64;
+require_extension('B');
+reg_t x = RS1;
+int shamt = RS2 & 15;
+if (shamt & 1) x = (x & 0x9999999999999999LL) | ((x & 0x4444444444444444LL) >> 1) | ((x & 0x2222222222222222LL) << 1);
+if (shamt & 2) x = (x & 0xC3C3C3C3C3C3C3C3LL) | ((x & 0x3030303030303030LL) >> 2) | ((x & 0x0C0C0C0C0C0C0C0CLL) << 2);
+if (shamt & 4) x = (x & 0xF00FF00FF00FF00FLL) | ((x & 0x0F000F000F000F00LL) >> 4) | ((x & 0x00F000F000F000F0LL) << 4);
+if (shamt & 8) x = (x & 0xFF0000FFFF0000FFLL) | ((x & 0x00FF000000FF0000LL) >> 8) | ((x & 0x0000FF000000FF00LL) << 8);
+WRITE_RD(sext32(x));
diff --git a/riscv/insns/xnor.h b/riscv/insns/xnor.h
new file mode 100644
index 0000000..b2fe95b
--- /dev/null
+++ b/riscv/insns/xnor.h
@@ -0,0 +1,2 @@
+require_extension('B');
+WRITE_RD(RS1 ^ ~RS2);
diff --git a/riscv/processor.cc b/riscv/processor.cc
index 4e13622..09d9006 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -204,7 +204,7 @@ void processor_t::parse_isa_string(const char* str)
char error_msg[256];
const char* p = lowercase.c_str();
- const char* all_subsets = "imafdqch"
+ const char* all_subsets = "imafdqcbh"
#ifdef __SIZEOF_INT128__
"v"
#endif
@@ -1027,7 +1027,7 @@ void processor_t::set_csr(int which, reg_t val)
if (!(val & (1L << ('F' - 'A'))))
val &= ~(1L << ('D' - 'A'));
- // allow MAFDC bits in MISA to be modified
+ // allow MAFDCB bits in MISA to be modified
reg_t mask = 0;
mask |= 1L << ('M' - 'A');
mask |= 1L << ('A' - 'A');
@@ -1035,6 +1035,7 @@ void processor_t::set_csr(int which, reg_t val)
mask |= 1L << ('D' - 'A');
mask |= 1L << ('C' - 'A');
mask |= 1L << ('H' - 'A');
+ mask |= 1L << ('B' - 'A');
mask &= max_isa;
state.misa = (val & mask) | (state.misa & ~mask);
diff --git a/riscv/riscv.mk.in b/riscv/riscv.mk.in
index 26ccd05..126c23a 100644
--- a/riscv/riscv.mk.in
+++ b/riscv/riscv.mk.in
@@ -333,6 +333,97 @@ riscv_insn_ext_q = \
fsqrt_q \
fsub_q \
+riscv_insn_ext_b = \
+ addiwu \
+ addu_w \
+ addwu \
+ andn \
+ bdep \
+ bdepw \
+ bext \
+ bextw \
+ bmatflip \
+ bmator \
+ bmatxor \
+ clmul \
+ clmulh \
+ clmulhw \
+ clmulr \
+ clmulrw \
+ clmulw \
+ clz \
+ clzw \
+ cmix \
+ cmov \
+ crc32_b \
+ crc32c_b \
+ crc32c_d \
+ crc32c_h \
+ crc32c_w \
+ crc32_d \
+ crc32_h \
+ crc32_w \
+ ctz \
+ ctzw \
+ fsl \
+ fslw \
+ fsr \
+ fsri \
+ fsriw \
+ fsrw \
+ grev \
+ grevi \
+ greviw \
+ grevw \
+ max \
+ maxu \
+ min \
+ minu \
+ orn \
+ pack \
+ packw \
+ pcnt \
+ pcntw \
+ rol \
+ rolw \
+ ror \
+ rori \
+ roriw \
+ rorw \
+ sbclr \
+ sbclri \
+ sbclriw \
+ sbclrw \
+ sbext \
+ sbexti \
+ sbextw \
+ sbinv \
+ sbinvi \
+ sbinviw \
+ sbinvw \
+ sbset \
+ sbseti \
+ sbsetiw \
+ sbsetw \
+ shfl \
+ shfli \
+ shflw \
+ slliu_w \
+ slo \
+ sloi \
+ sloiw \
+ slow \
+ sro \
+ sroi \
+ sroiw \
+ srow \
+ subu_w \
+ subwu \
+ unshfl \
+ unshfli \
+ unshflw \
+ xnor \
+
riscv_insn_ext_v_alu_int = \
vaadd_vv \
vaaddu_vv \
@@ -794,6 +885,7 @@ riscv_insn_list = \
$(riscv_insn_ext_d) \
$(riscv_insn_ext_zfh) \
$(riscv_insn_ext_q) \
+ $(riscv_insn_ext_b) \
$(if $(HAVE_INT128),$(riscv_insn_ext_v),) \
$(riscv_insn_ext_h) \
$(riscv_insn_priv) \