diff options
Diffstat (limited to 'disasm')
-rw-r--r-- | disasm/disasm.cc | 62 | ||||
-rw-r--r-- | disasm/isa_parser.cc | 12 |
2 files changed, 71 insertions, 3 deletions
diff --git a/disasm/disasm.cc b/disasm/disasm.cc index a33cb71..187a1d5 100644 --- a/disasm/disasm.cc +++ b/disasm/disasm.cc @@ -267,6 +267,18 @@ struct : public arg_t { } rvc_sp; struct : public arg_t { + std::string to_string(insn_t UNUSED insn) const { + return xpr_name[X_RA]; + } +} rvc_ra; + +struct : public arg_t { + std::string to_string(insn_t UNUSED insn) const { + return xpr_name[X_T0]; + } +} rvc_t0; + +struct : public arg_t { std::string to_string(insn_t insn) const { return std::to_string((int)insn.rvc_imm()); } @@ -2184,6 +2196,13 @@ void disassembler_t::add_instructions(const isa_parser_t* isa) } if (isa->extension_enabled(EXT_ZIMOP)) { + #define DISASM_MOP_R(name, rs1, rd) \ + add_insn(new disasm_insn_t(#name, match_##name | (rs1 << 15) | (rd << 7), \ + 0xFFFFFFFF, {&xrd, &xrs1})); + + #define DISASM_MOP_RR(name, rs1, rd, rs2) \ + add_insn(new disasm_insn_t(#name, match_##name | (rs1 << 15) | (rd << 7) | (rs2 << 20), \ + 0xFFFFFFFF, {&xrd, &xrs1, &xrs2})); DEFINE_R1TYPE(mop_r_0); DEFINE_R1TYPE(mop_r_1); DEFINE_R1TYPE(mop_r_2); @@ -2212,7 +2231,15 @@ void disassembler_t::add_instructions(const isa_parser_t* isa) DEFINE_R1TYPE(mop_r_25); DEFINE_R1TYPE(mop_r_26); DEFINE_R1TYPE(mop_r_27); - DEFINE_R1TYPE(mop_r_28); + if (!isa->extension_enabled(EXT_ZICFISS)) { + DEFINE_R1TYPE(mop_r_28); + } else { + // Add code points of mop_r_28 not used by Zicfiss + for (unsigned rd_val = 0; rd_val <= 31; ++rd_val) + for (unsigned rs1_val = 0; rs1_val <= 31; ++rs1_val) + if ((rd_val != 0 && rs1_val !=0) || (rd_val == 0 && !(rs1_val == 1 || rs1_val == 5))) + DISASM_MOP_R(mop_r_28, rs1_val, rd_val); + } DEFINE_R1TYPE(mop_r_29); DEFINE_R1TYPE(mop_r_30); DEFINE_R1TYPE(mop_r_31); @@ -2224,12 +2251,24 @@ void disassembler_t::add_instructions(const isa_parser_t* isa) DEFINE_RTYPE(mop_rr_5); DEFINE_RTYPE(mop_rr_6); DEFINE_RTYPE(mop_rr_7); + if (!isa->extension_enabled(EXT_ZICFISS)) { + DEFINE_RTYPE(mop_rr_7); + } else { + // Add code points of mop_rr_7 not used by Zicfiss + for (unsigned rd_val = 0; rd_val <= 31; ++rd_val) + for (unsigned rs1_val = 0; rs1_val <= 31; ++rs1_val) + for (unsigned rs2_val = 0; rs2_val <= 31; ++rs2_val) + if ((rs2_val != 1 && rs2_val != 5) || rd_val != 0 || rs1_val != 0) + DISASM_MOP_RR(mop_rr_7, rs1_val, rd_val, rs2_val); + } } if (isa->extension_enabled(EXT_ZCMOP)) { - DISASM_INSN("c.mop.1", c_mop_1, 0, {}); + if (!isa->extension_enabled(EXT_ZICFISS)) + DISASM_INSN("c.mop.1", c_mop_1, 0, {}); DISASM_INSN("c.mop.3", c_mop_3, 0, {}); - DISASM_INSN("c.mop.5", c_mop_5, 0, {}); + if (!isa->extension_enabled(EXT_ZICFISS)) + DISASM_INSN("c.mop.5", c_mop_5, 0, {}); DISASM_INSN("c.mop.7", c_mop_7, 0, {}); DISASM_INSN("c.mop.9", c_mop_9, 0, {}); DISASM_INSN("c.mop.11", c_mop_11, 0, {}); @@ -2392,6 +2431,23 @@ void disassembler_t::add_instructions(const isa_parser_t* isa) DEFINE_XSTORE_BASE(sw_rl); DEFINE_XSTORE_BASE(sd_rl); } + + if(isa->extension_enabled(EXT_ZICFISS)) { + DISASM_INSN("sspush", sspush_x1, 0, {&xrs2}); + DISASM_INSN("sspush", sspush_x5, 0, {&xrs2}); + DISASM_INSN("sspopchk", sspopchk_x1, 0, {&xrs1}); + DISASM_INSN("sspopchk", sspopchk_x5, 0, {&xrs1}); + DISASM_INSN("ssrdp", ssrdp, 0, {&xrd}); + DEFINE_XAMO(ssamoswap_w); + + if(isa->get_max_xlen() == 64) + DEFINE_XAMO(ssamoswap_d) + + if (isa->extension_enabled(EXT_ZCA)) { + DISASM_INSN("c.sspush", c_sspush_x1, 0, {&rvc_ra}); + DISASM_INSN("c.sspopchk", c_sspopchk_x5, 0, {&rvc_t0}); + } + } } disassembler_t::disassembler_t(const isa_parser_t *isa) diff --git a/disasm/isa_parser.cc b/disasm/isa_parser.cc index 3a99d0a..e0bebec 100644 --- a/disasm/isa_parser.cc +++ b/disasm/isa_parser.cc @@ -308,6 +308,8 @@ isa_parser_t::isa_parser_t(const char* str, const char *priv) extension_table[EXT_SSQOSID] = true; } else if (ext_str == "zicfilp") { extension_table[EXT_ZICFILP] = true; + } else if (ext_str == "zicfiss") { + extension_table[EXT_ZICFISS] = true; } else if (ext_str[0] == 'x') { extension_table['X'] = true; if (ext_str.size() == 1) { @@ -393,6 +395,16 @@ isa_parser_t::isa_parser_t(const char* str, const char *priv) (extension_table[EXT_ZVKG] || extension_table[EXT_ZVKNED] || extension_table[EXT_ZVKSH])) { bad_isa_string(str, "'Zvkg', 'Zvkned', and 'Zvksh' extensions are incompatible with 'Zpn' extension in rv64"); } + + // When SSE is 0, Zicfiss behavior is defined by Zicmop + if (extension_table[EXT_ZICFISS] && !extension_table[EXT_ZIMOP]) { + bad_isa_string(str, "'Zicfiss' extension requires 'Zimop' extension"); + } + + if (extension_table[EXT_ZICFISS] && extension_table[EXT_ZCA] && + !extension_table[EXT_ZCMOP]) { + bad_isa_string(str, "'Zicfiss' extension requires 'Zcmop' extension when `Zca` is supported"); + } #ifdef WORDS_BIGENDIAN // Access to the vector registers as element groups is unimplemented on big-endian setups. if (extension_table[EXT_ZVKG] || extension_table[EXT_ZVKNHA] || extension_table[EXT_ZVKNHB] || |