diff options
author | Andrew Waterman <andrew@sifive.com> | 2022-10-17 13:51:59 -0700 |
---|---|---|
committer | Andrew Waterman <andrew@sifive.com> | 2022-10-17 13:51:59 -0700 |
commit | 68aeeb5500521ff52c216862f9a653b64191f3ad (patch) | |
tree | 407230ff48f79f177a792451598d9b2b6e3d34a0 /disasm/disasm.cc | |
parent | 191634d2854dfed448fc323195f9b65c305e2d77 (diff) | |
parent | 03be4ae6c7b8e9865083b61427ff9724c7706fcf (diff) | |
download | spike-plic_uart_v1.zip spike-plic_uart_v1.tar.gz spike-plic_uart_v1.tar.bz2 |
Merge branch 'master' into plic_uart_v1plic_uart_v1
Diffstat (limited to 'disasm/disasm.cc')
-rw-r--r-- | disasm/disasm.cc | 120 |
1 files changed, 108 insertions, 12 deletions
diff --git a/disasm/disasm.cc b/disasm/disasm.cc index 52dede6..856a651 100644 --- a/disasm/disasm.cc +++ b/disasm/disasm.cc @@ -7,6 +7,12 @@ #include <cstdarg> #include <sstream> #include <stdlib.h> +// For std::reverse: +#include <algorithm> + +#ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wunused-variable" +#endif // Indicates that the next arg (only) is optional. // If the result of converting the next arg to a string is "" @@ -178,7 +184,7 @@ struct : public arg_t { } rvc_fp_rs2s; struct : public arg_t { - std::string to_string(insn_t insn) const { + std::string to_string(insn_t UNUSED insn) const { return xpr_name[X_SP]; } } rvc_sp; @@ -312,7 +318,7 @@ struct : public arg_t { } vm; struct : public arg_t { - std::string to_string(insn_t insn) const { + std::string to_string(insn_t UNUSED insn) const { return "v0"; } } v0; @@ -356,7 +362,7 @@ struct : public arg_t { } v_vtype; struct : public arg_t { - std::string to_string(insn_t insn) const { + std::string to_string(insn_t UNUSED insn) const { return "x0"; } } x0; @@ -415,6 +421,18 @@ struct : public arg_t { } } p_imm6; +struct : public arg_t { + std::string to_string(insn_t insn) const { + return std::to_string((int)insn.bs()); + } +} bs; + +struct : public arg_t { + std::string to_string(insn_t insn) const { + return std::to_string((int)insn.rcon()); + } +} rcon; + typedef struct { reg_t match; reg_t mask; @@ -658,6 +676,7 @@ void disassembler_t::add_instructions(const isa_parser_t* isa) #define DEFINE_I0TYPE(name, code) DISASM_INSN(name, code, mask_rs1, {&xrd, &imm}) #define DEFINE_I1TYPE(name, code) DISASM_INSN(name, code, mask_imm, {&xrd, &xrs1}) #define DEFINE_I2TYPE(name, code) DISASM_INSN(name, code, mask_rd | mask_imm, {&xrs1}) + #define DEFINE_PREFETCH(code) DISASM_INSN(#code, code, 0, {&store_address}) #define DEFINE_LTYPE(code) DISASM_INSN(#code, code, 0, {&xrd, &bigimm}) #define DEFINE_BTYPE(code) add_btype_insn(this, #code, match_##code, mask_##code); #define DEFINE_B1TYPE(name, code) add_b1type_insn(this, name, match_##code, mask_##code); @@ -679,6 +698,14 @@ void disassembler_t::add_instructions(const isa_parser_t* isa) add_insn(new disasm_insn_t("unimp", match_csrrw|(CSR_CYCLE<<20), 0xffffffff, {})); add_insn(new disasm_insn_t("c.unimp", 0, 0xffff, {})); + // Following are HINTs, so they must precede their corresponding base-ISA + // instructions. We do not condition them on Zicbop/Zihintpause because, + // definitionally, all implementations provide them. + DEFINE_PREFETCH(prefetch_r); + DEFINE_PREFETCH(prefetch_w); + DEFINE_PREFETCH(prefetch_i); + DEFINE_NOARG(pause); + DEFINE_XLOAD(lb) DEFINE_XLOAD(lbu) DEFINE_XLOAD(lh) @@ -866,6 +893,12 @@ void disassembler_t::add_instructions(const isa_parser_t* isa) } } + if (isa->extension_enabled(EXT_ZBC)) { + DEFINE_RTYPE(clmul); + DEFINE_RTYPE(clmulh); + DEFINE_RTYPE(clmulr); + } + if (isa->extension_enabled(EXT_ZBS)) { DEFINE_RTYPE(bclr); DEFINE_RTYPE(binv); @@ -1894,7 +1927,7 @@ void disassembler_t::add_instructions(const isa_parser_t* isa) DEFINE_RTYPE(msubr32); DEFINE_RTYPE(ave); DEFINE_RTYPE(sra_u); - DEFINE_PI5TYPE(srai_u); + DEFINE_PI6TYPE(srai_u); DEFINE_PI3TYPE(insb); DEFINE_RTYPE(maddr32) @@ -2014,14 +2047,72 @@ void disassembler_t::add_instructions(const isa_parser_t* isa) } if (isa->extension_enabled(EXT_ZICBOM)) { - DISASM_INSN("cbo.clean", cbo_clean, 0, {&xrs1}); - DISASM_INSN("cbo.flush", cbo_flush, 0, {&xrs1}); - DISASM_INSN("cbo.inval", cbo_inval, 0, {&xrs1}); + DISASM_INSN("cbo.clean", cbo_clean, 0, {&base_only_address}); + DISASM_INSN("cbo.flush", cbo_flush, 0, {&base_only_address}); + DISASM_INSN("cbo.inval", cbo_inval, 0, {&base_only_address}); } if (isa->extension_enabled(EXT_ZICBOZ)) { - DISASM_INSN("cbo.zero", cbo_zero, 0, {&xrs1}); + DISASM_INSN("cbo.zero", cbo_zero, 0, {&base_only_address}); + } + + if (isa->extension_enabled(EXT_ZKND) || + isa->extension_enabled(EXT_ZKNE)) { + DISASM_INSN("aes64ks1i", aes64ks1i, 0, {&xrd, &xrs1, &rcon}); + DEFINE_RTYPE(aes64ks2); + } + + if (isa->extension_enabled(EXT_ZKND)) { + if(isa->get_max_xlen() == 64) { + DEFINE_RTYPE(aes64ds); + DEFINE_RTYPE(aes64dsm); + DEFINE_R1TYPE(aes64im); + } else if (isa->get_max_xlen() == 32) { + DISASM_INSN("aes32dsi", aes32dsi, 0, {&xrd, &xrs1, &xrs2, &bs}); + DISASM_INSN("aes32dsmi", aes32dsmi, 0, {&xrd, &xrs1, &xrs2, &bs}); + } + } + + if (isa->extension_enabled(EXT_ZKNE)) { + if(isa->get_max_xlen() == 64) { + DEFINE_RTYPE(aes64es); + DEFINE_RTYPE(aes64esm); + } else if (isa->get_max_xlen() == 32) { + DISASM_INSN("aes32esi", aes32esi, 0, {&xrd, &xrs1, &xrs2, &bs}); + DISASM_INSN("aes32esmi", aes32esmi, 0, {&xrd, &xrs1, &xrs2, &bs}); + } + } + + if (isa->extension_enabled(EXT_ZKNH)) { + DEFINE_R1TYPE(sha256sig0); + DEFINE_R1TYPE(sha256sig1); + DEFINE_R1TYPE(sha256sum0); + DEFINE_R1TYPE(sha256sum1); + if(isa->get_max_xlen() == 64) { + DEFINE_R1TYPE(sha512sig0); + DEFINE_R1TYPE(sha512sig1); + DEFINE_R1TYPE(sha512sum0); + DEFINE_R1TYPE(sha512sum1); + } else if (isa->get_max_xlen() == 32) { + DEFINE_RTYPE(sha512sig0h); + DEFINE_RTYPE(sha512sig0l); + DEFINE_RTYPE(sha512sig1h); + DEFINE_RTYPE(sha512sig1l); + DEFINE_RTYPE(sha512sum0r); + DEFINE_RTYPE(sha512sum1r); + } } + + if (isa->extension_enabled(EXT_ZKSED)) { + DISASM_INSN("sm4ed", sm4ed, 0, {&xrd, &xrs1, &xrs2, &bs}); + DISASM_INSN("sm4ks", sm4ks, 0, {&xrd, &xrs1, &xrs2, &bs}); + } + + if (isa->extension_enabled(EXT_ZKSH)) { + DEFINE_R1TYPE(sm3p0); + DEFINE_R1TYPE(sm3p1); + } + } disassembler_t::disassembler_t(const isa_parser_t *isa) @@ -2031,19 +2122,24 @@ disassembler_t::disassembler_t(const isa_parser_t *isa) // next-highest priority: other instructions in same base ISA std::string fallback_isa_string = std::string("rv") + std::to_string(isa->get_max_xlen()) + - "gcv_zfh_zba_zbb_zbc_zbs_zkn_zkr_zks_xbitmanip"; + "gqchv_zfh_zba_zbb_zbc_zbs_zicbom_zicboz_zkn_zkr_zks_svinval_xbitmanip"; isa_parser_t fallback_isa(fallback_isa_string.c_str(), DEFAULT_PRIV); add_instructions(&fallback_isa); // finally: instructions with known opcodes but unknown arguments add_unknown_insns(this); + + // Now, reverse the lists, because we search them back-to-front (so that + // custom instructions later added with add_insn have highest priority). + for (size_t i = 0; i < HASH_SIZE+1; i++) + std::reverse(chain[i].begin(), chain[i].end()); } const disasm_insn_t* disassembler_t::probe_once(insn_t insn, size_t idx) const { - for (size_t j = 0; j < chain[idx].size(); j++) - if(*chain[idx][j] == insn) - return chain[idx][j]; + for (auto it = chain[idx].rbegin(); it != chain[idx].rend(); ++it) + if (*(*it) == insn) + return *it; return NULL; } |