[PATCH v2 27/52] disas/riscv: Handle decompression via decode_inst_lift_pseudo
Richard Henderson <[email protected]>
| Newsgroups | org.nongnu.qemu-riscv,org.nongnu.qemu-devel |
|---|---|
| Message-ID | <[email protected]> |
Introduce a DECOMP macro that expands an rv_comp_data that always succeeds. Reviewed-by: Alistair Francis <[email protected]> Signed-off-by: Richard Henderson <[email protected]> --- v2: Adjust macro to satisfy clang --- disas/riscv.h | 1 - disas/riscv.c | 113 +++++++++++++++++++++++--------------------------- 2 files changed, 51 insertions(+), 63 deletions(-) diff --git a/disas/riscv.h b/disas/riscv.h index 3bbcbf10fb..ea7141d3b5 100644 --- a/disas/riscv.h +++ b/disas/riscv.h @@ -174,7 +174,6 @@ typedef struct { rv_codec codec; const char *format; const rv_comp_data *pseudo; - rv_opcode decomp; } rv_opcode_data; typedef struct { diff --git a/disas/riscv.c b/disas/riscv.c index b8e5b124a5..a359badab5 100644 --- a/disas/riscv.c +++ b/disas/riscv.c @@ -1065,6 +1065,7 @@ static const rvc_constraint rvcc_ret[] = { rvc_rd_eq_x0, rvc_rs1_eq_ra, rvc_end }; static const rvc_constraint rvcc_jr[] = { rvc_rd_eq_x0, rvc_imm_eq_zero, rvc_end }; +static const rvc_constraint rvcc_true[] = { rvc_end }; /* pseudo-instruction metadata */ @@ -1190,6 +1191,9 @@ static const rv_comp_data rvcp_fsgnjx_q[] = { { rv_op_illegal, NULL } }; +/* Convert compressed insns into normal insns via pseudo expansion. */ +#define DECOMP(X) &(const rv_comp_data){ X, rvcc_true } + /* operand extractors */ static uint32_t operand_rd(rv_inst inst) @@ -1815,52 +1819,52 @@ static const rv_opcode_data rvi_opcode_data[] = { { "fcvt.q.lu", rv_codec_r_m, rv_fmt_rm_frd_rs1 }, { "fmv.x.q", rv_codec_r, rv_fmt_rd_frs1 }, { "fmv.q.x", rv_codec_r, rv_fmt_frd_rs1 }, - { "c.addi4spn", rv_codec_ciw_4spn, rv_fmt_rd_rs1_imm, NULL, rv_op_addi }, - { "c.fld", rv_codec_cl_ld, rv_fmt_frd_offset_rs1, NULL, rv_op_fld }, - { "c.lw", rv_codec_cl_lw, rv_fmt_rd_offset_rs1, NULL, rv_op_lw }, - { "c.flw", rv_codec_cl_lw, rv_fmt_frd_offset_rs1, NULL, rv_op_flw }, - { "c.fsd", rv_codec_cs_sd, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsd }, - { "c.sw", rv_codec_cs_sw, rv_fmt_rs2_offset_rs1, NULL, rv_op_sw }, - { "c.fsw", rv_codec_cs_sw, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsw }, + { "c.addi4spn", rv_codec_ciw_4spn, rv_fmt_rd_rs1_imm, DECOMP(rv_op_addi) }, + { "c.fld", rv_codec_cl_ld, rv_fmt_frd_offset_rs1, DECOMP(rv_op_fld) }, + { "c.lw", rv_codec_cl_lw, rv_fmt_rd_offset_rs1, DECOMP(rv_op_lw) }, + { "c.flw", rv_codec_cl_lw, rv_fmt_frd_offset_rs1, DECOMP(rv_op_flw) }, + { "c.fsd", rv_codec_cs_sd, rv_fmt_frs2_offset_rs1, DECOMP(rv_op_fsd) }, + { "c.sw", rv_codec_cs_sw, rv_fmt_rs2_offset_rs1, DECOMP(rv_op_sw) }, + { "c.fsw", rv_codec_cs_sw, rv_fmt_frs2_offset_rs1, DECOMP(rv_op_fsw) }, { }, - { "c.addi", rv_codec_ci, rv_fmt_rd_rs1_imm, NULL, rv_op_addi }, - { "c.jal", rv_codec_cj_jal, rv_fmt_rd_offset, NULL, rv_op_jal }, - { "c.li", rv_codec_ci_li, rv_fmt_rd_rs1_imm, NULL, rv_op_addi }, - { "c.addi16sp", rv_codec_ci_16sp, rv_fmt_rd_rs1_imm, NULL, rv_op_addi }, - { "c.lui", rv_codec_ci_lui, rv_fmt_rd_uimm, NULL, rv_op_lui }, - { "c.srli", rv_codec_cb_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_srli }, - { "c.srai", rv_codec_cb_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_srai }, - { "c.andi", rv_codec_cb_imm, rv_fmt_rd_rs1_imm, NULL, rv_op_andi }, - { "c.sub", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_sub }, - { "c.xor", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_xor }, - { "c.or", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_or }, - { "c.and", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_and }, - { "c.subw", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_subw }, - { "c.addw", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_addw }, - { "c.j", rv_codec_cj, rv_fmt_rd_offset, NULL, rv_op_jal }, - { "c.beqz", rv_codec_cb, rv_fmt_rs1_rs2_offset, NULL, rv_op_beq }, - { "c.bnez", rv_codec_cb, rv_fmt_rs1_rs2_offset, NULL, rv_op_bne }, - { "c.slli", rv_codec_ci_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_slli }, - { "c.fldsp", rv_codec_ci_ldsp, rv_fmt_frd_offset_rs1, NULL, rv_op_fld }, - { "c.lwsp", rv_codec_ci_lwsp, rv_fmt_rd_offset_rs1, NULL, rv_op_lw }, - { "c.flwsp", rv_codec_ci_lwsp, rv_fmt_frd_offset_rs1, NULL, rv_op_flw }, - { "c.jr", rv_codec_cr_jr, rv_fmt_rd_rs1_offset, NULL, rv_op_jalr }, - { "c.mv", rv_codec_cr_mv, rv_fmt_rd_rs1_rs2, NULL, rv_op_addi }, - { "c.ebreak", rv_codec_ci_none, rv_fmt_none, NULL, rv_op_ebreak }, - { "c.jalr", rv_codec_cr_jalr, rv_fmt_rd_rs1_offset, NULL, rv_op_jalr }, - { "c.add", rv_codec_cr, rv_fmt_rd_rs1_rs2, NULL, rv_op_add }, - { "c.fsdsp", rv_codec_css_sdsp, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsd }, - { "c.swsp", rv_codec_css_swsp, rv_fmt_rs2_offset_rs1, NULL, rv_op_sw }, - { "c.fswsp", rv_codec_css_swsp, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsw }, - { "c.ld", rv_codec_cl_ld, rv_fmt_rd_offset_rs1, NULL, rv_op_ld }, - { "c.sd", rv_codec_cs_sd, rv_fmt_rs2_offset_rs1, NULL, rv_op_sd }, - { "c.addiw", rv_codec_ci, rv_fmt_rd_rs1_imm, NULL, rv_op_addiw }, - { "c.ldsp", rv_codec_ci_ldsp, rv_fmt_rd_offset_rs1, NULL, rv_op_ld }, - { "c.sdsp", rv_codec_css_sdsp, rv_fmt_rs2_offset_rs1, NULL, rv_op_sd }, - { "c.lq", rv_codec_cl_lq, rv_fmt_rd_offset_rs1, NULL, rv_op_lq }, - { "c.sq", rv_codec_cs_sq, rv_fmt_rs2_offset_rs1, NULL, rv_op_sq }, - { "c.lqsp", rv_codec_ci_lqsp, rv_fmt_rd_offset_rs1, NULL, rv_op_lq }, - { "c.sqsp", rv_codec_css_sqsp, rv_fmt_rs2_offset_rs1, NULL, rv_op_sq }, + { "c.addi", rv_codec_ci, rv_fmt_rd_rs1_imm, DECOMP(rv_op_addi) }, + { "c.jal", rv_codec_cj_jal, rv_fmt_rd_offset, DECOMP(rv_op_jal) }, + { "c.li", rv_codec_ci_li, rv_fmt_rd_rs1_imm, DECOMP(rv_op_addi) }, + { "c.addi16sp", rv_codec_ci_16sp, rv_fmt_rd_rs1_imm, DECOMP(rv_op_addi) }, + { "c.lui", rv_codec_ci_lui, rv_fmt_rd_uimm, DECOMP(rv_op_lui) }, + { "c.srli", rv_codec_cb_sh6, rv_fmt_rd_rs1_imm, DECOMP(rv_op_srli) }, + { "c.srai", rv_codec_cb_sh6, rv_fmt_rd_rs1_imm, DECOMP(rv_op_srai) }, + { "c.andi", rv_codec_cb_imm, rv_fmt_rd_rs1_imm, DECOMP(rv_op_andi) }, + { "c.sub", rv_codec_cs, rv_fmt_rd_rs1_rs2, DECOMP(rv_op_sub) }, + { "c.xor", rv_codec_cs, rv_fmt_rd_rs1_rs2, DECOMP(rv_op_xor) }, + { "c.or", rv_codec_cs, rv_fmt_rd_rs1_rs2, DECOMP(rv_op_or) }, + { "c.and", rv_codec_cs, rv_fmt_rd_rs1_rs2, DECOMP(rv_op_and) }, + { "c.subw", rv_codec_cs, rv_fmt_rd_rs1_rs2, DECOMP(rv_op_subw) }, + { "c.addw", rv_codec_cs, rv_fmt_rd_rs1_rs2, DECOMP(rv_op_addw) }, + { "c.j", rv_codec_cj, rv_fmt_rd_offset, DECOMP(rv_op_jal) }, + { "c.beqz", rv_codec_cb, rv_fmt_rs1_rs2_offset, DECOMP(rv_op_beq) }, + { "c.bnez", rv_codec_cb, rv_fmt_rs1_rs2_offset, DECOMP(rv_op_bne) }, + { "c.slli", rv_codec_ci_sh6, rv_fmt_rd_rs1_imm, DECOMP(rv_op_slli) }, + { "c.fldsp", rv_codec_ci_ldsp, rv_fmt_frd_offset_rs1, DECOMP(rv_op_fld) }, + { "c.lwsp", rv_codec_ci_lwsp, rv_fmt_rd_offset_rs1, DECOMP(rv_op_lw) }, + { "c.flwsp", rv_codec_ci_lwsp, rv_fmt_frd_offset_rs1, DECOMP(rv_op_flw) }, + { "c.jr", rv_codec_cr_jr, rv_fmt_rd_rs1_offset, DECOMP(rv_op_jalr) }, + { "c.mv", rv_codec_cr_mv, rv_fmt_rd_rs1_rs2, DECOMP(rv_op_addi) }, + { "c.ebreak", rv_codec_ci_none, rv_fmt_none, DECOMP(rv_op_ebreak) }, + { "c.jalr", rv_codec_cr_jalr, rv_fmt_rd_rs1_offset, DECOMP(rv_op_jalr) }, + { "c.add", rv_codec_cr, rv_fmt_rd_rs1_rs2, DECOMP(rv_op_add) }, + { "c.fsdsp", rv_codec_css_sdsp, rv_fmt_frs2_offset_rs1, DECOMP(rv_op_fsd) }, + { "c.swsp", rv_codec_css_swsp, rv_fmt_rs2_offset_rs1, DECOMP(rv_op_sw) }, + { "c.fswsp", rv_codec_css_swsp, rv_fmt_frs2_offset_rs1, DECOMP(rv_op_fsw) }, + { "c.ld", rv_codec_cl_ld, rv_fmt_rd_offset_rs1, DECOMP(rv_op_ld) }, + { "c.sd", rv_codec_cs_sd, rv_fmt_rs2_offset_rs1, DECOMP(rv_op_sd) }, + { "c.addiw", rv_codec_ci, rv_fmt_rd_rs1_imm, DECOMP(rv_op_addiw) }, + { "c.ldsp", rv_codec_ci_ldsp, rv_fmt_rd_offset_rs1, DECOMP(rv_op_ld) }, + { "c.sdsp", rv_codec_css_sdsp, rv_fmt_rs2_offset_rs1, DECOMP(rv_op_sd) }, + { "c.lq", rv_codec_cl_lq, rv_fmt_rd_offset_rs1, DECOMP(rv_op_lq) }, + { "c.sq", rv_codec_cs_sq, rv_fmt_rs2_offset_rs1, DECOMP(rv_op_sq) }, + { "c.lqsp", rv_codec_ci_lqsp, rv_fmt_rd_offset_rs1, DECOMP(rv_op_lq) }, + { "c.sqsp", rv_codec_css_sqsp, rv_fmt_rs2_offset_rs1, DECOMP(rv_op_sq) }, { "nop", rv_codec_i, rv_fmt_none }, { "mv", rv_codec_i, rv_fmt_rd_rs1 }, { "not", rv_codec_i, rv_fmt_rd_rs1 }, @@ -2542,8 +2546,8 @@ static const rv_opcode_data rvi_opcode_data[] = { { "ssrdp", rv_codec_r, rv_fmt_rd }, { "ssamoswap.w", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1 }, { "ssamoswap.d", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1 }, - { "c.sspush", rv_codec_cmop_ss, rv_fmt_rs2, NULL, rv_op_sspush }, - { "c.sspopchk", rv_codec_cmop_ss, rv_fmt_rs1, NULL, rv_op_sspopchk }, + { "c.sspush", rv_codec_cmop_ss, rv_fmt_rs2, DECOMP(rv_op_sspush) }, + { "c.sspopchk", rv_codec_cmop_ss, rv_fmt_rs1, DECOMP(rv_op_sspopchk) }, { "cbo.inval", rv_codec_r, rv_fmt_rs1 }, { "cbo.clean", rv_codec_r, rv_fmt_rs1 }, { "cbo.flush", rv_codec_r, rv_fmt_rs1 }, @@ -5269,20 +5273,6 @@ static const rv_opcode_data *decode_inst_lift_pseudo(rv_decode *dec, return op; } -/* decompress instruction */ - -static const rv_opcode_data *decode_inst_decompress(rv_decode *dec, - const rv_opcode_data *op) -{ - int decomp_op = op->decomp; - - if (decomp_op != rv_op_illegal) { - dec->op = decomp_op; - op = &dec->opcode_data[decomp_op]; - } - return op; -} - /* disassemble instruction */ static GString *disasm_inst(rv_isa isa, uint64_t pc, rv_inst inst, @@ -5333,7 +5323,6 @@ static GString *disasm_inst(rv_isa isa, uint64_t pc, rv_inst inst, op = &dec.opcode_data[dec.op]; decode_inst_operands(&dec, isa, op); - op = decode_inst_decompress(&dec, op); op = decode_inst_lift_pseudo(&dec, op); return format_inst(24, &dec, op); } -- 2.43.0