From 0d0029fc9d7580df48b66e51fa5b7be219420520 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 30 Jul 2023 17:45:36 -0700 Subject: [PATCH] riscv: Add bitmanip ops to disasm. --- Core/MIPS/JitCommon/JitCommon.cpp | 2 +- ext/riscv-disas.cpp | 115 +++++++++++++++++++++++++++++- ext/riscv-disas.h | 43 +++++++++++ 3 files changed, 158 insertions(+), 2 deletions(-) diff --git a/Core/MIPS/JitCommon/JitCommon.cpp b/Core/MIPS/JitCommon/JitCommon.cpp index b6b3df1205..1adfda298a 100644 --- a/Core/MIPS/JitCommon/JitCommon.cpp +++ b/Core/MIPS/JitCommon/JitCommon.cpp @@ -335,7 +335,7 @@ std::vector DisassembleRV64(const u8 *data, int size) { // Force align in case we're somehow unaligned. len = 2 - ((uintptr_t)data & 1); invalid_count += (int)len; - i +=(int) len; + i += (int)len; continue; } diff --git a/ext/riscv-disas.cpp b/ext/riscv-disas.cpp index 282bfa77bb..7eba6b51eb 100644 --- a/ext/riscv-disas.cpp +++ b/ext/riscv-disas.cpp @@ -674,6 +674,49 @@ const rv_opcode_data opcode_data[] = { { "fsflags", rv_codec_i_csr, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, { "fsrmi", rv_codec_i_csr, rv_fmt_rd_zimm, NULL, 0, 0, 0 }, { "fsflagsi", rv_codec_i_csr, rv_fmt_rd_zimm, NULL, 0, 0, 0 }, + { "add.uw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "andn", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "bclr", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "bclri", rv_codec_i_sh7, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 }, + { "bext", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "bexti", rv_codec_i_sh7, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 }, + { "binv", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "binvi", rv_codec_i_sh7, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 }, + { "bset", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "bseti", rv_codec_i_sh7, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 }, + { "clmul", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "clmulh", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "clmulr", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "clz", rv_codec_i, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, + { "clzw", rv_codec_i, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, + { "cpop", rv_codec_i, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, + { "cpopw", rv_codec_i, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, + { "ctz", rv_codec_i, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, + { "ctzw", rv_codec_i, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, + { "max", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "maxu", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "min", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "minu", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "orc.b", rv_codec_i, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, + { "orn", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "rev8", rv_codec_i, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, + { "rol", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "rolw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "ror", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "rori", rv_codec_i_sh7, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 }, + { "roriw", rv_codec_i_sh7, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 }, + { "rorw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "sext.b", rv_codec_i, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, + { "sext.h", rv_codec_i, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, + { "sh1add", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "sh1add.uw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "sh2add", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "sh2add.uw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "sh3add", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "sh3add.uw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "slli.uw", rv_codec_i_sh6, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 }, + { "xnor", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "zext.h", rv_codec_i, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, }; /* CSR names */ @@ -1091,6 +1134,18 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) case 1: switch (((inst >> 27) & 0b11111)) { case 0: op = rv_op_slli; break; + case 5: op = rv_op_bseti; break; + case 9: op = rv_op_bclri; break; + case 12: + switch (((inst >> 20) & 0b11111)) { + case 0: op = rv_op_clz; break; + case 1: op = rv_op_ctz; break; + case 2: op = rv_op_cpop; break; + case 4: op = rv_op_sext_b; break; + case 5: op = rv_op_sext_h; break; + } + break; + case 13: op = rv_op_binvi; break; } break; case 2: op = rv_op_slti; break; @@ -1099,7 +1154,20 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) case 5: switch (((inst >> 27) & 0b11111)) { case 0: op = rv_op_srli; break; + case 5: + switch (((inst >> 20) & 0b1111111)) { + case 7: op = rv_op_orc_b; break; + } + break; case 8: op = rv_op_srai; break; + case 9: op = rv_op_bexti; break; + case 12: op = rv_op_rori; break; + case 13: + switch (((inst >> 20) & 0b1111111)) { + case 24: if (isa == rv32) op = rv_op_rev8; break; + case 56: if (isa == rv64) op = rv_op_rev8; break; + } + break; } break; case 6: op = rv_op_ori; break; @@ -1113,12 +1181,22 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) case 1: switch (((inst >> 25) & 0b1111111)) { case 0: op = rv_op_slliw; break; + case 4: op = rv_op_slli_uw; break; + case 5: op = rv_op_slli_uw; break; + case 48: + switch (((inst >> 20) & 0b11111)) { + case 0: op = rv_op_clzw; break; + case 1: op = rv_op_ctzw; break; + case 2: op = rv_op_cpopw; break; + } + break; } break; case 5: switch (((inst >> 25) & 0b1111111)) { case 0: op = rv_op_srliw; break; case 32: op = rv_op_sraiw; break; + case 48: op = rv_op_roriw; break; } break; } @@ -1207,8 +1285,32 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) case 13: op = rv_op_divu; break; case 14: op = rv_op_rem; break; case 15: op = rv_op_remu; break; + case 36: + switch (((inst >> 20) & 0b11111)) { + case 0: if (isa == rv32) op = rv_op_zext_h; break; + } + break; + case 41: op = rv_op_clmul; break; + case 42: op = rv_op_clmulr; break; + case 43: op = rv_op_clmulh; break; + case 44: op = rv_op_min; break; + case 45: op = rv_op_minu; break; + case 46: op = rv_op_max; break; + case 47: op = rv_op_maxu; break; + case 130: op = rv_op_sh1add; break; + case 132: op = rv_op_sh2add; break; + case 134: op = rv_op_sh3add; break; + case 161: op = rv_op_bset; break; case 256: op = rv_op_sub; break; + case 260: op = rv_op_xnor; break; case 261: op = rv_op_sra; break; + case 262: op = rv_op_orn; break; + case 263: op = rv_op_andn; break; + case 289: op = rv_op_bclr; break; + case 293: op = rv_op_bext; break; + case 385: op = rv_op_rol; break; + case 389: op = rv_op_ror; break; + case 417: op = rv_op_binv; break; } break; case 13: op = rv_op_lui; break; @@ -1222,8 +1324,19 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) case 13: op = rv_op_divuw; break; case 14: op = rv_op_remw; break; case 15: op = rv_op_remuw; break; + case 32: op = rv_op_add_uw; break; + case 36: + switch (((inst >> 20) & 0b11111)) { + case 0: if (isa == rv64) op = rv_op_zext_h; break; + } + break; + case 130: op = rv_op_sh1add_uw; break; + case 132: op = rv_op_sh2add_uw; break; + case 134: op = rv_op_sh3add_uw; break; case 256: op = rv_op_subw; break; case 261: op = rv_op_sraw; break; + case 385: op = rv_op_rolw; break; + case 389: op = rv_op_rorw; break; } break; case 16: @@ -2195,7 +2308,7 @@ static void decode_inst_lift_pseudo(rv_decode *dec) static char *append(char *buf, const char *src, const char *end) { while (buf < end && *src) - *buf++ = *src++; + *buf++ = *src++; return buf; } diff --git a/ext/riscv-disas.h b/ext/riscv-disas.h index ebf5571743..b7fcdfa509 100644 --- a/ext/riscv-disas.h +++ b/ext/riscv-disas.h @@ -524,6 +524,49 @@ typedef enum { rv_op_fsflags, rv_op_fsrmi, rv_op_fsflagsi, + rv_op_add_uw, + rv_op_andn, + rv_op_bclr, + rv_op_bclri, + rv_op_bext, + rv_op_bexti, + rv_op_binv, + rv_op_binvi, + rv_op_bset, + rv_op_bseti, + rv_op_clmul, + rv_op_clmulh, + rv_op_clmulr, + rv_op_clz, + rv_op_clzw, + rv_op_cpop, + rv_op_cpopw, + rv_op_ctz, + rv_op_ctzw, + rv_op_max, + rv_op_maxu, + rv_op_min, + rv_op_minu, + rv_op_orc_b, + rv_op_orn, + rv_op_rev8, + rv_op_rol, + rv_op_rolw, + rv_op_ror, + rv_op_rori, + rv_op_roriw, + rv_op_rorw, + rv_op_sext_b, + rv_op_sext_h, + rv_op_sh1add, + rv_op_sh1add_uw, + rv_op_sh2add, + rv_op_sh2add_uw, + rv_op_sh3add, + rv_op_sh3add_uw, + rv_op_slli_uw, + rv_op_xnor, + rv_op_zext_h, } rv_op; /* structures */