Re: [PATCH 21/56] disas/riscv: Handle c.{srli,srai} imm during decode
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: > Zero shift immediate to c.srli and c.srai are not illegal, > but are reserved as HINTs. Go ahead and disassemble as > shifts rather than falling back to invalid. > > On the other hand, shift immediate >= 32 with RV32 is > reserved for custom extensions, and we need to reject those > early so that the extension disassemblers get a look in. > > Signed-off-by: Richard Henderson <[email protected]> Reviewed-by: Alistair Francis <[email protected]> Alistair > --- > disas/riscv.c | 14 ++++++++++---- > 1 file changed, 10 insertions(+), 4 deletions(-) > > diff --git a/disas/riscv.c b/disas/riscv.c > index d6fbb3bca6..a8fbefb9bd 100644 > --- a/disas/riscv.c > +++ b/disas/riscv.c > @@ -1906,9 +1906,9 @@ static const rv_opcode_data rvi_opcode_data[] = > { > { "c.lui", rv_codec_ci_lui, rv_fmt_rd_uimm, NULL, rv_op_lui, > rv_op_lui, > rv_op_lui }, > { "c.srli", rv_codec_cb_sh6, rv_fmt_rd_rs1_imm, NULL, > rv_op_srli, > - rv_op_srli, rv_op_srli, rvcd_imm_nz }, > + rv_op_srli, rv_op_srli }, > { "c.srai", rv_codec_cb_sh6, rv_fmt_rd_rs1_imm, NULL, > rv_op_srai, > - rv_op_srai, rv_op_srai, rvcd_imm_nz }, > + rv_op_srai, rv_op_srai }, > { "c.andi", rv_codec_cb_imm, rv_fmt_rd_rs1_imm, NULL, > rv_op_andi, > rv_op_andi, rv_op_andi }, > { "c.sub", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_sub, > rv_op_sub, > @@ -3042,10 +3042,16 @@ static void decode_inst_opcode(rv_decode > *dec, rv_isa isa) > case 4: > switch ((inst >> 10) & 0b11) { > case 0: > - op = rv_op_c_srli; > + /* For rv32, shamt[5]=1 is designated for custom > extensions. */ > + if (isa != rv32 || (inst & 0x1000) == 0) { > + op = rv_op_c_srli; /* or unspecified HINT */ > + } > break; > case 1: > - op = rv_op_c_srai; > + /* For rv32, shamt[5]=1 is designated for custom > extensions. */ > + if (isa != rv32 || (inst & 0x1000) == 0) { > + op = rv_op_c_srai; /* or unspecified HINT */ > + } > break; > case 2: op = rv_op_c_andi; break; > case 3: