Re: [PATCH 32/56] disas/riscv: Handle decompression via decode_inst_lift_pseudo

Alistair <[email protected]>
Newsgroups org.nongnu.qemu-riscv,org.nongnu.qemu-devel
Message-ID <[email protected]>
On Sun, 2026-08-09 at 15:35 -0700, Richard Henderson wrote:
> Introduce a DECOMP macro that expands an rv_comp_data
> that always succeeds.
> 
> Signed-off-by: Richard Henderson <[email protected]>

Reviewed-by: Alistair Francis <[email protected]>

Alistair

> ---
>  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..129e545c6e 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) (static const rv_comp_data[1]){ { 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);
>  }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.