diff --git a/disasm/disasm.cc b/disasm/disasm.cc index 150250ee..30ce6515 100644 --- a/disasm/disasm.cc +++ b/disasm/disasm.cc @@ -542,6 +542,19 @@ disassembler_t::disassembler_t(int xlen) DEFINE_RTYPE(remw); DEFINE_RTYPE(remuw); + DEFINE_RTYPE(sh1add); + DEFINE_RTYPE(sh2add); + DEFINE_RTYPE(sh3add); + DEFINE_RTYPE(sh1addu_w); + DEFINE_RTYPE(sh2addu_w); + DEFINE_RTYPE(sh3addu_w); + DEFINE_RTYPE(addwu); + DEFINE_RTYPE(subwu); + DEFINE_ITYPE(addiwu); + DEFINE_RTYPE(ror); + DEFINE_RTYPE(rol); + DEFINE_ITYPE_SHIFT(rori); + DEFINE_NOARG(ecall); DEFINE_NOARG(ebreak); DEFINE_NOARG(uret); diff --git a/riscv/encoding.h b/riscv/encoding.h index 68801b07..fb1536ed 100644 --- a/riscv/encoding.h +++ b/riscv/encoding.h @@ -448,6 +448,218 @@ #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_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_SBCLR 0x48001033 +#define MASK_SBCLR 0xfe00707f +#define MATCH_SBSET 0x28001033 +#define MASK_SBSET 0xfe00707f +#define MATCH_SBINV 0x68001033 +#define MASK_SBINV 0xfe00707f +#define MATCH_SBEXT 0x48005033 +#define MASK_SBEXT 0xfe00707f +#define MATCH_GORC 0x28005033 +#define MASK_GORC 0xfe00707f +#define MATCH_GREV 0x68005033 +#define MASK_GREV 0xfe00707f +#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_SBCLRI 0x48001013 +#define MASK_SBCLRI 0xfc00707f +#define MATCH_SBSETI 0x28001013 +#define MASK_SBSETI 0xfc00707f +#define MATCH_SBINVI 0x68001013 +#define MASK_SBINVI 0xfc00707f +#define MATCH_SBEXTI 0x48005013 +#define MASK_SBEXTI 0xfc00707f +#define MATCH_GORCI 0x28005013 +#define MASK_GORCI 0xfc00707f +#define MATCH_GREVI 0x68005013 +#define MASK_GREVI 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_SEXT_B 0x60401013 +#define MASK_SEXT_B 0xfff0707f +#define MATCH_SEXT_H 0x60501013 +#define MASK_SEXT_H 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_SH1ADD 0x20002033 +#define MASK_SH1ADD 0xfe00707f +#define MATCH_SH2ADD 0x20004033 +#define MASK_SH2ADD 0xfe00707f +#define MATCH_SH3ADD 0x20006033 +#define MASK_SH3ADD 0xfe00707f +#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_MINU 0xa005033 +#define MASK_MINU 0xfe00707f +#define MATCH_MAX 0xa006033 +#define MASK_MAX 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_BEXT 0x8006033 +#define MASK_BEXT 0xfe00707f +#define MATCH_BDEP 0x48006033 +#define MASK_BDEP 0xfe00707f +#define MATCH_PACK 0x8004033 +#define MASK_PACK 0xfe00707f +#define MATCH_PACKU 0x48004033 +#define MASK_PACKU 0xfe00707f +#define MATCH_PACKH 0x8007033 +#define MASK_PACKH 0xfe00707f +#define MATCH_BFP 0x48007033 +#define MASK_BFP 0xfe00707f +#define MATCH_SHFLI 0x8001013 +#define MASK_SHFLI 0xfe00707f +#define MATCH_UNSHFLI 0x8005013 +#define MASK_UNSHFLI 0xfe00707f +#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 0x48003033 +#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_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_SBCLRW 0x4800103b +#define MASK_SBCLRW 0xfe00707f +#define MATCH_SBSETW 0x2800103b +#define MASK_SBSETW 0xfe00707f +#define MATCH_SBINVW 0x6800103b +#define MASK_SBINVW 0xfe00707f +#define MATCH_SBEXTW 0x4800503b +#define MASK_SBEXTW 0xfe00707f +#define MATCH_GORCW 0x2800503b +#define MASK_GORCW 0xfe00707f +#define MATCH_GREVW 0x6800503b +#define MASK_GREVW 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_SBCLRIW 0x4800101b +#define MASK_SBCLRIW 0xfe00707f +#define MATCH_SBSETIW 0x2800101b +#define MASK_SBSETIW 0xfe00707f +#define MATCH_SBINVIW 0x6800101b +#define MASK_SBINVIW 0xfe00707f +#define MATCH_GORCIW 0x2800501b +#define MASK_GORCIW 0xfe00707f +#define MATCH_GREVIW 0x6800501b +#define MASK_GREVIW 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_SH1ADDU_W 0x2000203b +#define MASK_SH1ADDU_W 0xfe00707f +#define MATCH_SH2ADDU_W 0x2000403b +#define MASK_SH2ADDU_W 0xfe00707f +#define MATCH_SH3ADDU_W 0x2000603b +#define MASK_SH3ADDU_W 0xfe00707f +#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_BEXTW 0x800603b +#define MASK_BEXTW 0xfe00707f +#define MATCH_BDEPW 0x4800603b +#define MASK_BDEPW 0xfe00707f +#define MATCH_PACKW 0x800403b +#define MASK_PACKW 0xfe00707f +#define MATCH_PACKUW 0x4800403b +#define MASK_PACKUW 0xfe00707f +#define MATCH_BFPW 0x4800703b +#define MASK_BFPW 0xfe00707f #define MATCH_AMOADD_W 0x202f #define MASK_AMOADD_W 0xf800707f #define MATCH_AMOXOR_W 0x2000202f @@ -2223,6 +2435,112 @@ 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(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(sbclr, MATCH_SBCLR, MASK_SBCLR) +DECLARE_INSN(sbset, MATCH_SBSET, MASK_SBSET) +DECLARE_INSN(sbinv, MATCH_SBINV, MASK_SBINV) +DECLARE_INSN(sbext, MATCH_SBEXT, MASK_SBEXT) +DECLARE_INSN(gorc, MATCH_GORC, MASK_GORC) +DECLARE_INSN(grev, MATCH_GREV, MASK_GREV) +DECLARE_INSN(sloi, MATCH_SLOI, MASK_SLOI) +DECLARE_INSN(sroi, MATCH_SROI, MASK_SROI) +DECLARE_INSN(rori, MATCH_RORI, MASK_RORI) +DECLARE_INSN(sbclri, MATCH_SBCLRI, MASK_SBCLRI) +DECLARE_INSN(sbseti, MATCH_SBSETI, MASK_SBSETI) +DECLARE_INSN(sbinvi, MATCH_SBINVI, MASK_SBINVI) +DECLARE_INSN(sbexti, MATCH_SBEXTI, MASK_SBEXTI) +DECLARE_INSN(gorci, MATCH_GORCI, MASK_GORCI) +DECLARE_INSN(grevi, MATCH_GREVI, MASK_GREVI) +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(sext_b, MATCH_SEXT_B, MASK_SEXT_B) +DECLARE_INSN(sext_h, MATCH_SEXT_H, MASK_SEXT_H) +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(sh1add, MATCH_SH1ADD, MASK_SH1ADD) +DECLARE_INSN(sh2add, MATCH_SH2ADD, MASK_SH2ADD) +DECLARE_INSN(sh3add, MATCH_SH3ADD, MASK_SH3ADD) +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(bext, MATCH_BEXT, MASK_BEXT) +DECLARE_INSN(bdep, MATCH_BDEP, MASK_BDEP) +DECLARE_INSN(pack, MATCH_PACK, MASK_PACK) +DECLARE_INSN(packu, MATCH_PACKU, MASK_PACKU) +DECLARE_INSN(packh, MATCH_PACKH, MASK_PACKH) +DECLARE_INSN(bfp, MATCH_BFP, MASK_BFP) +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(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(sbclrw, MATCH_SBCLRW, MASK_SBCLRW) +DECLARE_INSN(sbsetw, MATCH_SBSETW, MASK_SBSETW) +DECLARE_INSN(sbinvw, MATCH_SBINVW, MASK_SBINVW) +DECLARE_INSN(sbextw, MATCH_SBEXTW, MASK_SBEXTW) +DECLARE_INSN(gorcw, MATCH_GORCW, MASK_GORCW) +DECLARE_INSN(grevw, MATCH_GREVW, MASK_GREVW) +DECLARE_INSN(sloiw, MATCH_SLOIW, MASK_SLOIW) +DECLARE_INSN(sroiw, MATCH_SROIW, MASK_SROIW) +DECLARE_INSN(roriw, MATCH_RORIW, MASK_RORIW) +DECLARE_INSN(sbclriw, MATCH_SBCLRIW, MASK_SBCLRIW) +DECLARE_INSN(sbsetiw, MATCH_SBSETIW, MASK_SBSETIW) +DECLARE_INSN(sbinviw, MATCH_SBINVIW, MASK_SBINVIW) +DECLARE_INSN(gorciw, MATCH_GORCIW, MASK_GORCIW) +DECLARE_INSN(greviw, MATCH_GREVIW, MASK_GREVIW) +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(sh1addu_w, MATCH_SH1ADDU_W, MASK_SH1ADDU_W) +DECLARE_INSN(sh2addu_w, MATCH_SH2ADDU_W, MASK_SH2ADDU_W) +DECLARE_INSN(sh3addu_w, MATCH_SH3ADDU_W, MASK_SH3ADDU_W) +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(bextw, MATCH_BEXTW, MASK_BEXTW) +DECLARE_INSN(bdepw, MATCH_BDEPW, MASK_BDEPW) +DECLARE_INSN(packw, MATCH_PACKW, MASK_PACKW) +DECLARE_INSN(packuw, MATCH_PACKUW, MASK_PACKUW) +DECLARE_INSN(bfpw, MATCH_BFPW, MASK_BFPW) 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 00000000..5ba14275 --- /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 00000000..4b4d9c66 --- /dev/null +++ b/riscv/insns/addu_w.h @@ -0,0 +1,3 @@ +require_rv64; +require_extension('B'); +WRITE_RD(sext_xlen(zext32(RS1) + RS2)); diff --git a/riscv/insns/addwu.h b/riscv/insns/addwu.h new file mode 100644 index 00000000..cc406835 --- /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 00000000..4582aac1 --- /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 00000000..059a1cd1 --- /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 00000000..fc2e9c3b --- /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 00000000..50d9bb28 --- /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 00000000..90f3d451 --- /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/bfp.h b/riscv/insns/bfp.h new file mode 100644 index 00000000..96e6cfc6 --- /dev/null +++ b/riscv/insns/bfp.h @@ -0,0 +1,10 @@ +require_extension('B'); +reg_t cfg = RS2 >> (xlen/2); +if ((cfg >> 30) == 2) + cfg = cfg >> 16; +int len = (cfg >> 8) & (xlen/2-1); +int off = cfg & (xlen-1); +len = len ? len : xlen/2; +reg_t mask = ~(~reg_t(0) << len) << off; +reg_t data = RS2 << off; +WRITE_RD(sext_xlen((data & mask) | (RS1 & ~mask))); diff --git a/riscv/insns/bfpw.h b/riscv/insns/bfpw.h new file mode 100644 index 00000000..2a19ac11 --- /dev/null +++ b/riscv/insns/bfpw.h @@ -0,0 +1,8 @@ +require_extension('B'); +reg_t cfg = RS2 >> 16; +int len = (cfg >> 8) & 15; +int off = cfg & 31; +len = len ? len : 16; +reg_t mask = ~(~reg_t(0) << len) << off; +reg_t data = RS2 << off; +WRITE_RD(sext32((data & mask) | (RS1 & ~mask))); diff --git a/riscv/insns/bmatflip.h b/riscv/insns/bmatflip.h new file mode 100644 index 00000000..e137f10b --- /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 00000000..2d57228b --- /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 00000000..06d9db0a --- /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 00000000..96015674 --- /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 00000000..68a50e33 --- /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 00000000..75f64ec2 --- /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 00000000..f07487e1 --- /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 00000000..6fc90087 --- /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 00000000..69d0f437 --- /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 00000000..6821b2da --- /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 00000000..63135541 --- /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 00000000..727f136c --- /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 00000000..eeae7e26 --- /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 00000000..b000e646 --- /dev/null +++ b/riscv/insns/crc32_b.h @@ -0,0 +1,5 @@ +require_extension('B'); +reg_t x = zext_xlen(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 00000000..c96d253b --- /dev/null +++ b/riscv/insns/crc32_d.h @@ -0,0 +1,5 @@ +require_extension('B'); +reg_t x = zext_xlen(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 00000000..91bb253a --- /dev/null +++ b/riscv/insns/crc32_h.h @@ -0,0 +1,5 @@ +require_extension('B'); +reg_t x = zext_xlen(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 00000000..2ad4a30e --- /dev/null +++ b/riscv/insns/crc32_w.h @@ -0,0 +1,5 @@ +require_extension('B'); +reg_t x = zext_xlen(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 00000000..077b3700 --- /dev/null +++ b/riscv/insns/crc32c_b.h @@ -0,0 +1,5 @@ +require_extension('B'); +reg_t x = zext_xlen(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 00000000..78a54a67 --- /dev/null +++ b/riscv/insns/crc32c_d.h @@ -0,0 +1,5 @@ +require_extension('B'); +reg_t x = zext_xlen(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 00000000..62718b5d --- /dev/null +++ b/riscv/insns/crc32c_h.h @@ -0,0 +1,5 @@ +require_extension('B'); +reg_t x = zext_xlen(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 00000000..754d7bb3 --- /dev/null +++ b/riscv/insns/crc32c_w.h @@ -0,0 +1,5 @@ +require_extension('B'); +reg_t x = zext_xlen(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 00000000..889de0f1 --- /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 00000000..59f58ad1 --- /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 00000000..fdf02ad1 --- /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 00000000..04ab04f4 --- /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 00000000..18a1e69a --- /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 00000000..2d41c82a --- /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 00000000..31983c9a --- /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 00000000..1511fbed --- /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/gorc.h b/riscv/insns/gorc.h new file mode 100644 index 00000000..097ba9b0 --- /dev/null +++ b/riscv/insns/gorc.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/gorci.h b/riscv/insns/gorci.h new file mode 100644 index 00000000..c42142ff --- /dev/null +++ b/riscv/insns/gorci.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/gorciw.h b/riscv/insns/gorciw.h new file mode 100644 index 00000000..27bc7539 --- /dev/null +++ b/riscv/insns/gorciw.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/gorcw.h b/riscv/insns/gorcw.h new file mode 100644 index 00000000..88642fb9 --- /dev/null +++ b/riscv/insns/gorcw.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/grev.h b/riscv/insns/grev.h new file mode 100644 index 00000000..b13fa5a3 --- /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 00000000..68213c6a --- /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 00000000..500096d2 --- /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 00000000..274dd6fd --- /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 00000000..f57e7222 --- /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 00000000..e1ecdf4e --- /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 00000000..1b2fadbd --- /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 00000000..fdf315e8 --- /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 00000000..670926f7 --- /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 00000000..841f24da --- /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/packh.h b/riscv/insns/packh.h new file mode 100644 index 00000000..34a95c82 --- /dev/null +++ b/riscv/insns/packh.h @@ -0,0 +1,4 @@ +require_extension('B'); +reg_t lo = zext_xlen(RS1 << (xlen-8)) >> (xlen-8); +reg_t hi = zext_xlen(RS2 << (xlen-8)) >> (xlen-16); +WRITE_RD(sext_xlen(lo | hi)); diff --git a/riscv/insns/packu.h b/riscv/insns/packu.h new file mode 100644 index 00000000..25cc9c21 --- /dev/null +++ b/riscv/insns/packu.h @@ -0,0 +1,4 @@ +require_extension('B'); +reg_t lo = zext_xlen(RS1) >> (xlen/2); +reg_t hi = zext_xlen(RS2) >> (xlen/2) << (xlen/2); +WRITE_RD(sext_xlen(lo | hi)); diff --git a/riscv/insns/packuw.h b/riscv/insns/packuw.h new file mode 100644 index 00000000..b4a2f50f --- /dev/null +++ b/riscv/insns/packuw.h @@ -0,0 +1,4 @@ +require_extension('B'); +reg_t lo = zext32(RS1) >> 16; +reg_t hi = zext32(RS2) >> 16 << 16; +WRITE_RD(sext32(lo | hi)); diff --git a/riscv/insns/packw.h b/riscv/insns/packw.h new file mode 100644 index 00000000..3da96bf4 --- /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 00000000..773e2e1d --- /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 00000000..13e9ba0f --- /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 00000000..2b15c932 --- /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 00000000..6d66a50c --- /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 00000000..8788a120 --- /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 00000000..72f1529b --- /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 00000000..d0b8d677 --- /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 00000000..b42ab738 --- /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 00000000..f0b0e0ad --- /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 00000000..546dcaa9 --- /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 00000000..3a26fe01 --- /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 00000000..e0892983 --- /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 00000000..7149a2a9 --- /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 00000000..c930cfb4 --- /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 00000000..10414538 --- /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 00000000..58922526 --- /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 00000000..f67143c4 --- /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 00000000..80fef91a --- /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 00000000..1b9ccfd8 --- /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 00000000..0e3f0fce --- /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 00000000..44aa8bba --- /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 00000000..dcfc6b1e --- /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 00000000..c65199ad --- /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/sext_b.h b/riscv/insns/sext_b.h new file mode 100644 index 00000000..566e6f82 --- /dev/null +++ b/riscv/insns/sext_b.h @@ -0,0 +1,2 @@ +require_extension('B'); +WRITE_RD((sreg_t)(int8_t)(RS1)); diff --git a/riscv/insns/sext_h.h b/riscv/insns/sext_h.h new file mode 100644 index 00000000..bd1fde2e --- /dev/null +++ b/riscv/insns/sext_h.h @@ -0,0 +1,2 @@ +require_extension('B'); +WRITE_RD((sreg_t)(int16_t)(RS1)); diff --git a/riscv/insns/sh1add.h b/riscv/insns/sh1add.h new file mode 100644 index 00000000..f2805ab4 --- /dev/null +++ b/riscv/insns/sh1add.h @@ -0,0 +1,2 @@ +require_extension('B'); +WRITE_RD(sext_xlen((RS1 << 1) + RS2)); diff --git a/riscv/insns/sh1addu_w.h b/riscv/insns/sh1addu_w.h new file mode 100644 index 00000000..74569589 --- /dev/null +++ b/riscv/insns/sh1addu_w.h @@ -0,0 +1,3 @@ +require_rv64; +require_extension('B'); +WRITE_RD(sext_xlen((zext32(RS1) << 1) + RS2)); diff --git a/riscv/insns/sh2add.h b/riscv/insns/sh2add.h new file mode 100644 index 00000000..ff68d371 --- /dev/null +++ b/riscv/insns/sh2add.h @@ -0,0 +1,2 @@ +require_extension('B'); +WRITE_RD(sext_xlen((RS1 << 2) + RS2)); diff --git a/riscv/insns/sh2addu_w.h b/riscv/insns/sh2addu_w.h new file mode 100644 index 00000000..9948980b --- /dev/null +++ b/riscv/insns/sh2addu_w.h @@ -0,0 +1,3 @@ +require_rv64; +require_extension('B'); +WRITE_RD(sext_xlen((zext32(RS1) << 2) + RS2)); diff --git a/riscv/insns/sh3add.h b/riscv/insns/sh3add.h new file mode 100644 index 00000000..631a0ce2 --- /dev/null +++ b/riscv/insns/sh3add.h @@ -0,0 +1,2 @@ +require_extension('B'); +WRITE_RD(sext_xlen((RS1 << 3) + RS2)); diff --git a/riscv/insns/sh3addu_w.h b/riscv/insns/sh3addu_w.h new file mode 100644 index 00000000..e41a65da --- /dev/null +++ b/riscv/insns/sh3addu_w.h @@ -0,0 +1,3 @@ +require_rv64; +require_extension('B'); +WRITE_RD(sext_xlen((zext32(RS1) << 3) + RS2)); diff --git a/riscv/insns/shfl.h b/riscv/insns/shfl.h new file mode 100644 index 00000000..0bd87d3d --- /dev/null +++ b/riscv/insns/shfl.h @@ -0,0 +1,9 @@ +require_extension('B'); +reg_t x = RS1; +int shamt = RS2 & ((xlen-1) >> 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 00000000..59fbcff4 --- /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) >> 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 00000000..8239a985 --- /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 00000000..99ac5f8b --- /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 00000000..0836cf86 --- /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 00000000..216cf9cf --- /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 00000000..5ec7576a --- /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 00000000..2f958c68 --- /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 00000000..841a9606 --- /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 00000000..46eb8408 --- /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 00000000..671af39c --- /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 00000000..74ba73e5 --- /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/subwu.h b/riscv/insns/subwu.h new file mode 100644 index 00000000..a97f6d79 --- /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 00000000..b14bc29a --- /dev/null +++ b/riscv/insns/unshfl.h @@ -0,0 +1,9 @@ +require_extension('B'); +reg_t x = RS1; +int shamt = RS2 & ((xlen-1) >> 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 00000000..fbe83643 --- /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) >> 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 00000000..de5ceb53 --- /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 00000000..b2fe95b8 --- /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 c56819a0..564f1b30 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 26ccd055..9afbc145 100644 --- a/riscv/riscv.mk.in +++ b/riscv/riscv.mk.in @@ -333,6 +333,113 @@ riscv_insn_ext_q = \ fsqrt_q \ fsub_q \ +riscv_insn_ext_b = \ + addiwu \ + addu_w \ + addwu \ + andn \ + bdep \ + bdepw \ + bext \ + bextw \ + bfp \ + bfpw \ + bmatflip \ + bmator \ + bmatxor \ + sh1add \ + sh1addu_w \ + sh2add \ + sh2addu_w \ + sh3add \ + sh3addu_w \ + 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 \ + gorc \ + gorci \ + gorciw \ + gorcw \ + grev \ + grevi \ + greviw \ + grevw \ + max \ + maxu \ + min \ + minu \ + orn \ + pack \ + packh \ + packu \ + packuw \ + packw \ + pcnt \ + pcntw \ + rol \ + rolw \ + ror \ + rori \ + roriw \ + rorw \ + sbclr \ + sbclri \ + sbclriw \ + sbclrw \ + sbext \ + sbexti \ + sbextw \ + sbinv \ + sbinvi \ + sbinviw \ + sbinvw \ + sbset \ + sbseti \ + sbsetiw \ + sbsetw \ + sext_b \ + sext_h \ + shfl \ + shfli \ + shflw \ + slliu_w \ + slo \ + sloi \ + sloiw \ + slow \ + sro \ + sroi \ + sroiw \ + srow \ + subwu \ + unshfl \ + unshfli \ + unshflw \ + xnor \ + riscv_insn_ext_v_alu_int = \ vaadd_vv \ vaaddu_vv \ @@ -794,6 +901,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) \