|
|
|
@ -128,9 +128,9 @@ struct : public arg_t { |
|
|
|
|
|
|
|
struct : public arg_t { |
|
|
|
std::string to_string(insn_t insn) const { |
|
|
|
return xpr_name[insn.rvc_rds()]; |
|
|
|
return xpr_name[insn.rvc_rs2()]; |
|
|
|
} |
|
|
|
} rvc_rds; |
|
|
|
} rvc_rs2; |
|
|
|
|
|
|
|
struct : public arg_t { |
|
|
|
std::string to_string(insn_t insn) const { |
|
|
|
@ -138,12 +138,42 @@ struct : public arg_t { |
|
|
|
} |
|
|
|
} rvc_rs1s; |
|
|
|
|
|
|
|
struct : public arg_t { |
|
|
|
std::string to_string(insn_t insn) const { |
|
|
|
return xpr_name[insn.rvc_rs2s()]; |
|
|
|
} |
|
|
|
} rvc_rs2s; |
|
|
|
|
|
|
|
struct : public arg_t { |
|
|
|
std::string to_string(insn_t insn) const { |
|
|
|
return xpr_name[insn.rvc_rds()]; |
|
|
|
} |
|
|
|
} rvc_rds; |
|
|
|
|
|
|
|
struct : public arg_t { |
|
|
|
std::string to_string(insn_t insn) const { |
|
|
|
return xpr_name[X_SP]; |
|
|
|
} |
|
|
|
} rvc_sp; |
|
|
|
|
|
|
|
struct : public arg_t { |
|
|
|
std::string to_string(insn_t insn) const { |
|
|
|
return std::to_string((int)insn.rvc_imm()); |
|
|
|
} |
|
|
|
} rvc_imm; |
|
|
|
|
|
|
|
struct : public arg_t { |
|
|
|
std::string to_string(insn_t insn) const { |
|
|
|
return std::to_string((int)insn.rvc_addi4spn_imm()); |
|
|
|
} |
|
|
|
} rvc_addi4spn_imm; |
|
|
|
|
|
|
|
struct : public arg_t { |
|
|
|
std::string to_string(insn_t insn) const { |
|
|
|
return std::to_string((int)insn.rvc_addi16sp_imm()); |
|
|
|
} |
|
|
|
} rvc_addi16sp_imm; |
|
|
|
|
|
|
|
struct : public arg_t { |
|
|
|
std::string to_string(insn_t insn) const { |
|
|
|
return std::to_string((int)insn.rvc_lwsp_imm()); |
|
|
|
@ -166,16 +196,28 @@ struct : public arg_t { |
|
|
|
|
|
|
|
struct : public arg_t { |
|
|
|
std::string to_string(insn_t insn) const { |
|
|
|
return std::to_string((int)insn.rvc_lwsp_imm()) + '(' + xpr_name[2] + ')'; |
|
|
|
return std::to_string((int)insn.rvc_lwsp_imm()) + '(' + xpr_name[X_SP] + ')'; |
|
|
|
} |
|
|
|
} rvc_lwsp_address; |
|
|
|
|
|
|
|
struct : public arg_t { |
|
|
|
std::string to_string(insn_t insn) const { |
|
|
|
return std::to_string((int)insn.rvc_ldsp_imm()) + '(' + xpr_name[2] + ')'; |
|
|
|
return std::to_string((int)insn.rvc_ldsp_imm()) + '(' + xpr_name[X_SP] + ')'; |
|
|
|
} |
|
|
|
} rvc_ldsp_address; |
|
|
|
|
|
|
|
struct : public arg_t { |
|
|
|
std::string to_string(insn_t insn) const { |
|
|
|
return std::to_string((int)insn.rvc_swsp_imm()) + '(' + xpr_name[X_SP] + ')'; |
|
|
|
} |
|
|
|
} rvc_swsp_address; |
|
|
|
|
|
|
|
struct : public arg_t { |
|
|
|
std::string to_string(insn_t insn) const { |
|
|
|
return std::to_string((int)insn.rvc_sdsp_imm()) + '(' + xpr_name[X_SP] + ')'; |
|
|
|
} |
|
|
|
} rvc_sdsp_address; |
|
|
|
|
|
|
|
struct : public arg_t { |
|
|
|
std::string to_string(insn_t insn) const { |
|
|
|
return std::to_string((int)insn.rvc_lw_imm()) + '(' + xpr_name[insn.rvc_rs1s()] + ')'; |
|
|
|
@ -220,11 +262,11 @@ disassembler_t::disassembler_t() |
|
|
|
const uint32_t match_rd_ra = 1UL << 7; |
|
|
|
const uint32_t mask_rs1 = 0x1fUL << 15; |
|
|
|
const uint32_t match_rs1_ra = 1UL << 15; |
|
|
|
const uint32_t mask_rvc_rs1 = 0x1fUL << 2; |
|
|
|
const uint32_t match_rvc_rs1_ra = 1UL << 2; |
|
|
|
const uint32_t mask_rs2 = 0x1fUL << 20; |
|
|
|
const uint32_t mask_imm = 0xfffUL << 20; |
|
|
|
const uint32_t match_imm_1 = 1UL << 20; |
|
|
|
const uint32_t mask_rvc_rs2 = 0x1fUL << 2; |
|
|
|
const uint32_t mask_rvc_imm = mask_rvc_rs2 | 0x1000UL; |
|
|
|
|
|
|
|
#define DECLARE_INSN(code, match, mask) \ |
|
|
|
const uint32_t match_##code = match; \ |
|
|
|
@ -456,29 +498,31 @@ disassembler_t::disassembler_t() |
|
|
|
DEFINE_FXTYPE(flt_d); |
|
|
|
DEFINE_FXTYPE(fle_d); |
|
|
|
|
|
|
|
add_insn(new disasm_insn_t("sbreak", match_c_li | 0x1000, 0xffff, {})); |
|
|
|
DISASM_INSN("ebreak", c_add, mask_rd | mask_rvc_rs2, {}); |
|
|
|
add_insn(new disasm_insn_t("ret", match_c_li | match_rd_ra, mask_c_li | mask_rd | mask_rvc_imm, {})); |
|
|
|
DISASM_INSN("jr", c_li, mask_rvc_imm, {&rvc_rs1}); |
|
|
|
DISASM_INSN("jalr", c_lui, mask_rvc_imm, {&rvc_rs1}); |
|
|
|
DISASM_INSN("nop", c_addi, mask_rd | mask_rvc_imm, {}); |
|
|
|
DISASM_INSN("addi", c_addi, mask_rd, {&rvc_sp, &rvc_sp, &rvc_addi16sp_imm}); |
|
|
|
DISASM_INSN("addi", c_addi4spn, 0, {&rvc_rs1s, &rvc_sp, &rvc_addi4spn_imm}); |
|
|
|
DISASM_INSN("li", c_li, 0, {&xrd, &rvc_imm}); |
|
|
|
DISASM_INSN("lui", c_lui, 0, {&xrd, &rvc_uimm}); |
|
|
|
DISASM_INSN("addi", c_addi, 0, {&xrd, &xrd, &rvc_imm}); |
|
|
|
DISASM_INSN("addiw", c_addiw, 0, {&xrd, &xrd, &rvc_imm}); |
|
|
|
DISASM_INSN("slli", c_slli, 0, {&xrd, &rvc_shamt}); |
|
|
|
DISASM_INSN("addi", c_addi4, 0, {&xrd, &xrd, &rvc_lwsp_imm}); |
|
|
|
DISASM_INSN("mv", c_mv, 0, {&xrd, &rvc_rs1}); |
|
|
|
add_insn(new disasm_insn_t("ret", match_c_jalr | match_rvc_rs1_ra, mask_c_jalr | mask_rd | mask_rvc_rs1, {})); |
|
|
|
DISASM_INSN("jr", c_jalr, mask_rd, {&xrd, &rvc_rs1}); |
|
|
|
DISASM_INSN("jalr", c_jalr, mask_rd, {&xrd, &rvc_rs1}); |
|
|
|
DISASM_INSN("add", c_add, 0, {&xrd, &xrd, &rvc_rs1}); |
|
|
|
DISASM_INSN("addw", c_addw, 0, {&xrd, &xrd, &rvc_rs1}); |
|
|
|
DISASM_INSN("lw", c_lwsp, 0, {&xrd, &rvc_lwsp_address}); |
|
|
|
DISASM_INSN("ld", c_ldsp, 0, {&xrd, &rvc_ldsp_address}); |
|
|
|
DISASM_INSN("sw", c_swsp, 0, {&xrd, &rvc_lwsp_address}); |
|
|
|
DISASM_INSN("sd", c_sdsp, 0, {&xrd, &rvc_ldsp_address}); |
|
|
|
DISASM_INSN("lw", c_lw, 0, {&rvc_rds, &rvc_lw_address}); |
|
|
|
DISASM_INSN("ld", c_ld, 0, {&rvc_rds, &rvc_ld_address}); |
|
|
|
DISASM_INSN("sw", c_sw, 0, {&rvc_rds, &rvc_lw_address}); |
|
|
|
DISASM_INSN("sd", c_sd, 0, {&rvc_rds, &rvc_ld_address}); |
|
|
|
DISASM_INSN("beqz", c_beqz, 0, {&rvc_rds, &rvc_branch_target}); |
|
|
|
DISASM_INSN("bnez", c_bnez, 0, {&rvc_rds, &rvc_branch_target}); |
|
|
|
DISASM_INSN("sw", c_swsp, 0, {&rvc_rs2, &rvc_swsp_address}); |
|
|
|
DISASM_INSN("sd", c_sdsp, 0, {&rvc_rs2, &rvc_sdsp_address}); |
|
|
|
DISASM_INSN("lw", c_lw, 0, {&rvc_rs2s, &rvc_lw_address}); |
|
|
|
DISASM_INSN("ld", c_ld, 0, {&rvc_rs2s, &rvc_ld_address}); |
|
|
|
DISASM_INSN("sw", c_sw, 0, {&rvc_rs2s, &rvc_lw_address}); |
|
|
|
DISASM_INSN("sd", c_sd, 0, {&rvc_rs2s, &rvc_ld_address}); |
|
|
|
DISASM_INSN("beqz", c_beqz, 0, {&rvc_rs1s, &rvc_branch_target}); |
|
|
|
DISASM_INSN("bnez", c_bnez, 0, {&rvc_rs1s, &rvc_branch_target}); |
|
|
|
DISASM_INSN("j", c_j, 0, {&rvc_jump_target}); |
|
|
|
|
|
|
|
// provide a default disassembly for all instructions as a fallback
|
|
|
|
|