Yes, the problem is that RV32E/64E can access all 32 registers. I agree this solution is not ideal, but limiting the registers does not seem to be straightforward either. There are many direct accesses to `static TCGv cpu_gpr[32]` based on the register numbers decoded from the instructions. As far as I understand, the only way to do this right now is to return `false` from the `trans_` functions.
From: Alistair Francis <[email protected]> Sent: Monday, September 29, 2025 2:29 AM To: Gergely Futo Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected] Subject: Re: [PATCH] target/riscv: check registers for RV32E/RV64E On Fri, Sep 19, 2025 at 11:58 PM Gergely Futo via <[email protected]> wrote: > > RV32E and RV64E reduce the integer register count to 16 general-purpose > registers, (x0-x15), where x0 is a dedicated zero register. So the problem today is that RV32E/64E can access all 32 registers? > > This patch checks the register usage if the `E` extension is active. > > The instructions from the following extensions are covered: > - Base Integer Instruction Set > - "M" for Integer Multiplication and Division > - "A" Extension for Atomic Instructions > - "B" Extension for Bit Manipulation > - "Zce" Extension for Code Size Reduction > - "Zicond" Extension for Integer Conditional Operations Manually checking every single instruction doesn't seem like the right way to do this. Can't we just limit the registers if using E instead of I? Alistair > > Signed-off-by: Gergely Futo <[email protected]> > --- > target/riscv/insn_trans/trans_rva.c.inc | 44 ++++++ > target/riscv/insn_trans/trans_rvb.c.inc | 96 +++++++++++++ > target/riscv/insn_trans/trans_rvi.c.inc | 134 +++++++++++++++++++ > target/riscv/insn_trans/trans_rvm.c.inc | 32 +++++ > target/riscv/insn_trans/trans_rvzce.c.inc | 3 + > target/riscv/insn_trans/trans_rvzicond.c.inc | 2 + > target/riscv/translate.c | 28 ++++ > 7 files changed, 339 insertions(+) > > diff --git a/target/riscv/insn_trans/trans_rva.c.inc > b/target/riscv/insn_trans/trans_rva.c.inc > index 9cf3ae8019..b87534b9aa 100644 > --- a/target/riscv/insn_trans/trans_rva.c.inc > +++ b/target/riscv/insn_trans/trans_rva.c.inc > @@ -99,72 +99,96 @@ static bool gen_sc(DisasContext *ctx, arg_atomic *a, > MemOp mop) > static bool trans_lr_w(DisasContext *ctx, arg_lr_w *a) > { > REQUIRE_A_OR_ZALRSC(ctx); > + CHECK_X_REG_RD_RS1(ctx, a); > + > return gen_lr(ctx, a, (MO_ALIGN | MO_TESL)); > } > > static bool trans_sc_w(DisasContext *ctx, arg_sc_w *a) > { > REQUIRE_A_OR_ZALRSC(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_sc(ctx, a, (MO_ALIGN | MO_TESL)); > } > > static bool trans_amoswap_w(DisasContext *ctx, arg_amoswap_w *a) > { > REQUIRE_A_OR_ZAAMO(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, MO_TESL); > } > > static bool trans_amoadd_w(DisasContext *ctx, arg_amoadd_w *a) > { > REQUIRE_A_OR_ZAAMO(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, MO_TESL); > } > > static bool trans_amoxor_w(DisasContext *ctx, arg_amoxor_w *a) > { > REQUIRE_A_OR_ZAAMO(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, MO_TESL); > } > > static bool trans_amoand_w(DisasContext *ctx, arg_amoand_w *a) > { > REQUIRE_A_OR_ZAAMO(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, MO_TESL); > } > > static bool trans_amoor_w(DisasContext *ctx, arg_amoor_w *a) > { > REQUIRE_A_OR_ZAAMO(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, MO_TESL); > } > > static bool trans_amomin_w(DisasContext *ctx, arg_amomin_w *a) > { > REQUIRE_A_OR_ZAAMO(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, MO_TESL); > } > > static bool trans_amomax_w(DisasContext *ctx, arg_amomax_w *a) > { > REQUIRE_A_OR_ZAAMO(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, MO_TESL); > } > > static bool trans_amominu_w(DisasContext *ctx, arg_amominu_w *a) > { > REQUIRE_A_OR_ZAAMO(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, MO_TESL); > } > > static bool trans_amomaxu_w(DisasContext *ctx, arg_amomaxu_w *a) > { > REQUIRE_A_OR_ZAAMO(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, MO_TESL); > } > > static bool trans_lr_d(DisasContext *ctx, arg_lr_d *a) > { > REQUIRE_64BIT(ctx); > + CHECK_X_REG_RD_RS1(ctx, a); > + > REQUIRE_A_OR_ZALRSC(ctx); > return gen_lr(ctx, a, MO_ALIGN | MO_TEUQ); > } > @@ -172,6 +196,8 @@ static bool trans_lr_d(DisasContext *ctx, arg_lr_d *a) > static bool trans_sc_d(DisasContext *ctx, arg_sc_d *a) > { > REQUIRE_64BIT(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > REQUIRE_A_OR_ZALRSC(ctx); > return gen_sc(ctx, a, (MO_ALIGN | MO_TEUQ)); > } > @@ -180,6 +206,8 @@ static bool trans_amoswap_d(DisasContext *ctx, > arg_amoswap_d *a) > { > REQUIRE_64BIT(ctx); > REQUIRE_A_OR_ZAAMO(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, MO_TEUQ); > } > > @@ -187,6 +215,8 @@ static bool trans_amoadd_d(DisasContext *ctx, > arg_amoadd_d *a) > { > REQUIRE_64BIT(ctx); > REQUIRE_A_OR_ZAAMO(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, MO_TEUQ); > } > > @@ -194,6 +224,8 @@ static bool trans_amoxor_d(DisasContext *ctx, > arg_amoxor_d *a) > { > REQUIRE_64BIT(ctx); > REQUIRE_A_OR_ZAAMO(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, MO_TEUQ); > } > > @@ -201,6 +233,8 @@ static bool trans_amoand_d(DisasContext *ctx, > arg_amoand_d *a) > { > REQUIRE_64BIT(ctx); > REQUIRE_A_OR_ZAAMO(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, MO_TEUQ); > } > > @@ -208,6 +242,8 @@ static bool trans_amoor_d(DisasContext *ctx, arg_amoor_d > *a) > { > REQUIRE_64BIT(ctx); > REQUIRE_A_OR_ZAAMO(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, MO_TEUQ); > } > > @@ -215,6 +251,8 @@ static bool trans_amomin_d(DisasContext *ctx, > arg_amomin_d *a) > { > REQUIRE_64BIT(ctx); > REQUIRE_A_OR_ZAAMO(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, MO_TEUQ); > } > > @@ -222,6 +260,8 @@ static bool trans_amomax_d(DisasContext *ctx, > arg_amomax_d *a) > { > REQUIRE_64BIT(ctx); > REQUIRE_A_OR_ZAAMO(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, MO_TEUQ); > } > > @@ -229,6 +269,8 @@ static bool trans_amominu_d(DisasContext *ctx, > arg_amominu_d *a) > { > REQUIRE_64BIT(ctx); > REQUIRE_A_OR_ZAAMO(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, MO_TEUQ); > } > > @@ -236,5 +278,7 @@ static bool trans_amomaxu_d(DisasContext *ctx, > arg_amomaxu_d *a) > { > REQUIRE_64BIT(ctx); > REQUIRE_A_OR_ZAAMO(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, MO_TEUQ); > } > diff --git a/target/riscv/insn_trans/trans_rvb.c.inc > b/target/riscv/insn_trans/trans_rvb.c.inc > index e4dcc7c991..f8eae605ce 100644 > --- a/target/riscv/insn_trans/trans_rvb.c.inc > +++ b/target/riscv/insn_trans/trans_rvb.c.inc > @@ -69,6 +69,8 @@ static void gen_clzw(TCGv ret, TCGv arg1) > static bool trans_clz(DisasContext *ctx, arg_clz *a) > { > REQUIRE_ZBB(ctx); > + CHECK_X_REG_RD_RS1(ctx, a); > + > return gen_unary_per_ol(ctx, a, EXT_NONE, gen_clz, gen_clzw); > } > > @@ -85,66 +87,88 @@ static void gen_ctzw(TCGv ret, TCGv arg1) > static bool trans_ctz(DisasContext *ctx, arg_ctz *a) > { > REQUIRE_ZBB(ctx); > + CHECK_X_REG_RD_RS1(ctx, a); > + > return gen_unary_per_ol(ctx, a, EXT_ZERO, gen_ctz, gen_ctzw); > } > > static bool trans_cpop(DisasContext *ctx, arg_cpop *a) > { > REQUIRE_ZBB(ctx); > + CHECK_X_REG_RD_RS1(ctx, a); > + > return gen_unary(ctx, a, EXT_ZERO, tcg_gen_ctpop_tl); > } > > static bool trans_andn(DisasContext *ctx, arg_andn *a) > { > REQUIRE_EITHER_EXT(ctx, zbb, zbkb); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_logic(ctx, a, tcg_gen_andc_tl); > } > > static bool trans_orn(DisasContext *ctx, arg_orn *a) > { > REQUIRE_EITHER_EXT(ctx, zbb, zbkb); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_logic(ctx, a, tcg_gen_orc_tl); > } > > static bool trans_xnor(DisasContext *ctx, arg_xnor *a) > { > REQUIRE_EITHER_EXT(ctx, zbb, zbkb); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_logic(ctx, a, tcg_gen_eqv_tl); > } > > static bool trans_min(DisasContext *ctx, arg_min *a) > { > REQUIRE_ZBB(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_arith(ctx, a, EXT_SIGN, tcg_gen_smin_tl, NULL); > } > > static bool trans_max(DisasContext *ctx, arg_max *a) > { > REQUIRE_ZBB(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_arith(ctx, a, EXT_SIGN, tcg_gen_smax_tl, NULL); > } > > static bool trans_minu(DisasContext *ctx, arg_minu *a) > { > REQUIRE_ZBB(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_arith(ctx, a, EXT_SIGN, tcg_gen_umin_tl, NULL); > } > > static bool trans_maxu(DisasContext *ctx, arg_maxu *a) > { > REQUIRE_ZBB(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_arith(ctx, a, EXT_SIGN, tcg_gen_umax_tl, NULL); > } > > static bool trans_sext_b(DisasContext *ctx, arg_sext_b *a) > { > REQUIRE_ZBB(ctx); > + CHECK_X_REG_RD_RS1(ctx, a); > + > return gen_unary(ctx, a, EXT_NONE, tcg_gen_ext8s_tl); > } > > static bool trans_sext_h(DisasContext *ctx, arg_sext_h *a) > { > REQUIRE_ZBB(ctx); > + CHECK_X_REG_RD_RS1(ctx, a); > + > return gen_unary(ctx, a, EXT_NONE, tcg_gen_ext16s_tl); > } > > @@ -165,12 +189,16 @@ static void gen_bset(TCGv ret, TCGv arg1, TCGv shamt) > static bool trans_bset(DisasContext *ctx, arg_bset *a) > { > REQUIRE_ZBS(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_shift(ctx, a, EXT_NONE, gen_bset, NULL); > } > > static bool trans_bseti(DisasContext *ctx, arg_bseti *a) > { > REQUIRE_ZBS(ctx); > + CHECK_X_REG_RD_RS1(ctx, a); > + > return gen_shift_imm_tl(ctx, a, EXT_NONE, gen_bset); > } > > @@ -185,12 +213,16 @@ static void gen_bclr(TCGv ret, TCGv arg1, TCGv shamt) > static bool trans_bclr(DisasContext *ctx, arg_bclr *a) > { > REQUIRE_ZBS(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_shift(ctx, a, EXT_NONE, gen_bclr, NULL); > } > > static bool trans_bclri(DisasContext *ctx, arg_bclri *a) > { > REQUIRE_ZBS(ctx); > + CHECK_X_REG_RD_RS1(ctx, a); > + > return gen_shift_imm_tl(ctx, a, EXT_NONE, gen_bclr); > } > > @@ -205,12 +237,16 @@ static void gen_binv(TCGv ret, TCGv arg1, TCGv shamt) > static bool trans_binv(DisasContext *ctx, arg_binv *a) > { > REQUIRE_ZBS(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_shift(ctx, a, EXT_NONE, gen_binv, NULL); > } > > static bool trans_binvi(DisasContext *ctx, arg_binvi *a) > { > REQUIRE_ZBS(ctx); > + CHECK_X_REG_RD_RS1(ctx, a); > + > return gen_shift_imm_tl(ctx, a, EXT_NONE, gen_binv); > } > > @@ -223,12 +259,16 @@ static void gen_bext(TCGv ret, TCGv arg1, TCGv shamt) > static bool trans_bext(DisasContext *ctx, arg_bext *a) > { > REQUIRE_ZBS(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_shift(ctx, a, EXT_NONE, gen_bext, NULL); > } > > static bool trans_bexti(DisasContext *ctx, arg_bexti *a) > { > REQUIRE_ZBS(ctx); > + CHECK_X_REG_RD_RS1(ctx, a); > + > return gen_shift_imm_tl(ctx, a, EXT_NONE, gen_bext); > } > > @@ -250,6 +290,8 @@ static void gen_rorw(TCGv ret, TCGv arg1, TCGv arg2) > static bool trans_ror(DisasContext *ctx, arg_ror *a) > { > REQUIRE_EITHER_EXT(ctx, zbb, zbkb); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_shift_per_ol(ctx, a, EXT_NONE, tcg_gen_rotr_tl, gen_rorw, >NULL); > } > > @@ -265,6 +307,8 @@ static void gen_roriw(TCGv ret, TCGv arg1, target_long > shamt) > static bool trans_rori(DisasContext *ctx, arg_rori *a) > { > REQUIRE_EITHER_EXT(ctx, zbb, zbkb); > + CHECK_X_REG_RD_RS1(ctx, a); > + > return gen_shift_imm_fn_per_ol(ctx, a, EXT_NONE, > tcg_gen_rotri_tl, gen_roriw, NULL); > } > @@ -287,6 +331,8 @@ static void gen_rolw(TCGv ret, TCGv arg1, TCGv arg2) > static bool trans_rol(DisasContext *ctx, arg_rol *a) > { > REQUIRE_EITHER_EXT(ctx, zbb, zbkb); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_shift_per_ol(ctx, a, EXT_NONE, tcg_gen_rotl_tl, gen_rolw, >NULL); > } > > @@ -299,6 +345,8 @@ static bool trans_rev8_32(DisasContext *ctx, arg_rev8_32 > *a) > { > REQUIRE_32BIT(ctx); > REQUIRE_EITHER_EXT(ctx, zbb, zbkb); > + CHECK_X_REG_RD_RS1(ctx, a); > + > return gen_unary(ctx, a, EXT_NONE, gen_rev8_32); > } > > @@ -306,6 +354,8 @@ static bool trans_rev8_64(DisasContext *ctx, arg_rev8_64 > *a) > { > REQUIRE_64BIT(ctx); > REQUIRE_EITHER_EXT(ctx, zbb, zbkb); > + CHECK_X_REG_RD_RS1(ctx, a); > + > return gen_unary(ctx, a, EXT_NONE, tcg_gen_bswap_tl); > } > > @@ -330,6 +380,8 @@ static void gen_orc_b(TCGv ret, TCGv source1) > static bool trans_orc_b(DisasContext *ctx, arg_orc_b *a) > { > REQUIRE_ZBB(ctx); > + CHECK_X_REG_RD_RS1(ctx, a); > + > return gen_unary(ctx, a, EXT_ZERO, gen_orc_b); > } > > @@ -350,6 +402,7 @@ GEN_SHADD(3) > static bool trans_sh##SHAMT##add(DisasContext *ctx, arg_sh##SHAMT##add *a) \ > { \ > REQUIRE_ZBA(ctx); \ > + CHECK_X_REG_RD_RS1_RS2(ctx, a); \ > return gen_arith(ctx, a, EXT_NONE, gen_sh##SHAMT##add, NULL); \ > } > > @@ -361,6 +414,8 @@ static bool trans_zext_h_32(DisasContext *ctx, > arg_zext_h_32 *a) > { > REQUIRE_32BIT(ctx); > REQUIRE_ZBB(ctx); > + CHECK_X_REG_RD_RS1(ctx, a); > + > return gen_unary(ctx, a, EXT_NONE, tcg_gen_ext16u_tl); > } > > @@ -368,6 +423,8 @@ static bool trans_zext_h_64(DisasContext *ctx, > arg_zext_h_64 *a) > { > REQUIRE_64BIT(ctx); > REQUIRE_ZBB(ctx); > + CHECK_X_REG_RD_RS1(ctx, a); > + > return gen_unary(ctx, a, EXT_NONE, tcg_gen_ext16u_tl); > } > > @@ -375,6 +432,8 @@ static bool trans_clzw(DisasContext *ctx, arg_clzw *a) > { > REQUIRE_64BIT(ctx); > REQUIRE_ZBB(ctx); > + CHECK_X_REG_RD_RS1(ctx, a); > + > return gen_unary(ctx, a, EXT_NONE, gen_clzw); > } > > @@ -382,6 +441,8 @@ static bool trans_ctzw(DisasContext *ctx, arg_ctzw *a) > { > REQUIRE_64BIT(ctx); > REQUIRE_ZBB(ctx); > + CHECK_X_REG_RD_RS1(ctx, a); > + > ctx->ol = MXL_RV32; > return gen_unary(ctx, a, EXT_ZERO, gen_ctzw); > } > @@ -390,6 +451,8 @@ static bool trans_cpopw(DisasContext *ctx, arg_cpopw *a) > { > REQUIRE_64BIT(ctx); > REQUIRE_ZBB(ctx); > + CHECK_X_REG_RD_RS1(ctx, a); > + > ctx->ol = MXL_RV32; > return gen_unary(ctx, a, EXT_ZERO, tcg_gen_ctpop_tl); > } > @@ -398,6 +461,8 @@ static bool trans_rorw(DisasContext *ctx, arg_rorw *a) > { > REQUIRE_64BIT(ctx); > REQUIRE_EITHER_EXT(ctx, zbb, zbkb); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > ctx->ol = MXL_RV32; > return gen_shift(ctx, a, EXT_NONE, gen_rorw, NULL); > } > @@ -406,6 +471,8 @@ static bool trans_roriw(DisasContext *ctx, arg_roriw *a) > { > REQUIRE_64BIT(ctx); > REQUIRE_EITHER_EXT(ctx, zbb, zbkb); > + CHECK_X_REG_RD_RS1(ctx, a); > + > ctx->ol = MXL_RV32; > return gen_shift_imm_fn(ctx, a, EXT_NONE, gen_roriw, NULL); > } > @@ -414,6 +481,8 @@ static bool trans_rolw(DisasContext *ctx, arg_rolw *a) > { > REQUIRE_64BIT(ctx); > REQUIRE_EITHER_EXT(ctx, zbb, zbkb); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > ctx->ol = MXL_RV32; > return gen_shift(ctx, a, EXT_NONE, gen_rolw, NULL); > } > @@ -439,6 +508,7 @@ static bool trans_sh##SHAMT##add_uw(DisasContext *ctx, > \ > { \ > REQUIRE_64BIT(ctx); \ > REQUIRE_ZBA(ctx); \ > + CHECK_X_REG_RD_RS1_RS2(ctx, a); \ > return gen_arith(ctx, a, EXT_NONE, gen_sh##SHAMT##add_uw, NULL); \ > } > > @@ -457,6 +527,8 @@ static bool trans_add_uw(DisasContext *ctx, arg_add_uw *a) > { > REQUIRE_64BIT(ctx); > REQUIRE_ZBA(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_arith(ctx, a, EXT_NONE, gen_add_uw, NULL); > } > > @@ -469,12 +541,16 @@ static bool trans_slli_uw(DisasContext *ctx, > arg_slli_uw *a) > { > REQUIRE_64BIT(ctx); > REQUIRE_ZBA(ctx); > + CHECK_X_REG_RD_RS1(ctx, a); > + > return gen_shift_imm_fn(ctx, a, EXT_NONE, gen_slli_uw, NULL); > } > > static bool trans_clmul(DisasContext *ctx, arg_clmul *a) > { > REQUIRE_EITHER_EXT(ctx, zbc, zbkc); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_arith(ctx, a, EXT_NONE, gen_helper_clmul, NULL); > } > > @@ -487,12 +563,16 @@ static void gen_clmulh(TCGv dst, TCGv src1, TCGv src2) > static bool trans_clmulh(DisasContext *ctx, arg_clmulr *a) > { > REQUIRE_EITHER_EXT(ctx, zbc, zbkc); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_arith(ctx, a, EXT_NONE, gen_clmulh, NULL); > } > > static bool trans_clmulr(DisasContext *ctx, arg_clmulh *a) > { > REQUIRE_ZBC(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_arith(ctx, a, EXT_NONE, gen_helper_clmulr, NULL); > } > > @@ -522,18 +602,24 @@ static void gen_packw(TCGv ret, TCGv src1, TCGv src2) > static bool trans_brev8(DisasContext *ctx, arg_brev8 *a) > { > REQUIRE_ZBKB(ctx); > + CHECK_X_REG_RD_RS1(ctx, a); > + > return gen_unary(ctx, a, EXT_NONE, gen_helper_brev8); > } > > static bool trans_pack(DisasContext *ctx, arg_pack *a) > { > REQUIRE_ZBKB(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_arith(ctx, a, EXT_NONE, gen_pack, NULL); > } > > static bool trans_packh(DisasContext *ctx, arg_packh *a) > { > REQUIRE_ZBKB(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_arith(ctx, a, EXT_NONE, gen_packh, NULL); > } > > @@ -541,6 +627,8 @@ static bool trans_packw(DisasContext *ctx, arg_packw *a) > { > REQUIRE_64BIT(ctx); > REQUIRE_ZBKB(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_arith(ctx, a, EXT_NONE, gen_packw, NULL); > } > > @@ -548,6 +636,8 @@ static bool trans_unzip(DisasContext *ctx, arg_unzip *a) > { > REQUIRE_32BIT(ctx); > REQUIRE_ZBKB(ctx); > + CHECK_X_REG_RD_RS1(ctx, a); > + > return gen_unary(ctx, a, EXT_NONE, gen_helper_unzip); > } > > @@ -555,17 +645,23 @@ static bool trans_zip(DisasContext *ctx, arg_zip *a) > { > REQUIRE_32BIT(ctx); > REQUIRE_ZBKB(ctx); > + CHECK_X_REG_RD_RS1(ctx, a); > + > return gen_unary(ctx, a, EXT_NONE, gen_helper_zip); > } > > static bool trans_xperm4(DisasContext *ctx, arg_xperm4 *a) > { > REQUIRE_ZBKX(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_arith(ctx, a, EXT_NONE, gen_helper_xperm4, NULL); > } > > static bool trans_xperm8(DisasContext *ctx, arg_xperm8 *a) > { > REQUIRE_ZBKX(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_arith(ctx, a, EXT_NONE, gen_helper_xperm8, NULL); > } > diff --git a/target/riscv/insn_trans/trans_rvi.c.inc > b/target/riscv/insn_trans/trans_rvi.c.inc > index b9c7160468..c69a655ad6 100644 > --- a/target/riscv/insn_trans/trans_rvi.c.inc > +++ b/target/riscv/insn_trans/trans_rvi.c.inc > @@ -32,6 +32,8 @@ static bool trans_c64_illegal(DisasContext *ctx, arg_empty > *a) > > static bool trans_lui(DisasContext *ctx, arg_lui *a) > { > + CHECK_X_REG_RD(ctx, a); > + > gen_set_gpri(ctx, a->rd, a->imm); > return true; > } > @@ -81,6 +83,8 @@ static bool trans_lpad(DisasContext *ctx, arg_lpad *a) > > static bool trans_auipc(DisasContext *ctx, arg_auipc *a) > { > + CHECK_X_REG_RD(ctx, a); > + > TCGv target_pc = dest_gpr(ctx, a->rd); > gen_pc_plus_diff(target_pc, ctx, a->imm); > gen_set_gpr(ctx, a->rd, target_pc); > @@ -89,6 +93,8 @@ static bool trans_auipc(DisasContext *ctx, arg_auipc *a) > > static bool trans_jal(DisasContext *ctx, arg_jal *a) > { > + CHECK_X_REG_RD(ctx, a); > + > gen_jal(ctx, a->rd, a->imm); > return true; > } > @@ -140,6 +146,8 @@ static void gen_ctr_jalr(DisasContext *ctx, arg_jalr *a, > TCGv dest) > > static bool trans_jalr(DisasContext *ctx, arg_jalr *a) > { > + CHECK_X_REG_RD_RS1(ctx, a); > + > TCGLabel *misaligned = NULL; > TCGv target_pc = tcg_temp_new(); > TCGv succ_pc = dest_gpr(ctx, a->rd); > @@ -332,31 +340,43 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, > TCGCond cond) > > static bool trans_beq(DisasContext *ctx, arg_beq *a) > { > + CHECK_X_REG_RS1_RS2(ctx, a); > + > return gen_branch(ctx, a, TCG_COND_EQ); > } > > static bool trans_bne(DisasContext *ctx, arg_bne *a) > { > + CHECK_X_REG_RS1_RS2(ctx, a); > + > return gen_branch(ctx, a, TCG_COND_NE); > } > > static bool trans_blt(DisasContext *ctx, arg_blt *a) > { > + CHECK_X_REG_RS1_RS2(ctx, a); > + > return gen_branch(ctx, a, TCG_COND_LT); > } > > static bool trans_bge(DisasContext *ctx, arg_bge *a) > { > + CHECK_X_REG_RS1_RS2(ctx, a); > + > return gen_branch(ctx, a, TCG_COND_GE); > } > > static bool trans_bltu(DisasContext *ctx, arg_bltu *a) > { > + CHECK_X_REG_RS1_RS2(ctx, a); > + > return gen_branch(ctx, a, TCG_COND_LTU); > } > > static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a) > { > + CHECK_X_REG_RS1_RS2(ctx, a); > + > return gen_branch(ctx, a, TCG_COND_GEU); > } > > @@ -421,22 +441,32 @@ static bool gen_load(DisasContext *ctx, arg_lb *a, > MemOp memop) > > static bool trans_lb(DisasContext *ctx, arg_lb *a) > { > + CHECK_X_REG_RD_RS1(ctx, a); > + > return gen_load(ctx, a, MO_SB); > } > > static bool trans_lh(DisasContext *ctx, arg_lh *a) > { > + CHECK_X_REG_RD_RS1(ctx, a); > + > return gen_load(ctx, a, MO_TESW); > } > > static bool trans_lw(DisasContext *ctx, arg_lw *a) > { > + CHECK_X_REG_RD_RS1(ctx, a); > + > return gen_load(ctx, a, MO_TESL); > } > > static bool trans_ld(DisasContext *ctx, arg_ld *a) > { > REQUIRE_64_OR_128BIT(ctx); > + if (get_xl(ctx) == MXL_RV64) { > + CHECK_X_REG_RD_RS1(ctx, a); > + } > + > return gen_load(ctx, a, MO_TESQ); > } > > @@ -448,17 +478,25 @@ static bool trans_lq(DisasContext *ctx, arg_lq *a) > > static bool trans_lbu(DisasContext *ctx, arg_lbu *a) > { > + CHECK_X_REG_RD_RS1(ctx, a); > + > return gen_load(ctx, a, MO_UB); > } > > static bool trans_lhu(DisasContext *ctx, arg_lhu *a) > { > + CHECK_X_REG_RD_RS1(ctx, a); > + > return gen_load(ctx, a, MO_TEUW); > } > > static bool trans_lwu(DisasContext *ctx, arg_lwu *a) > { > REQUIRE_64_OR_128BIT(ctx); > + if (get_xl(ctx) == MXL_RV64) { > + CHECK_X_REG_RD_RS1(ctx, a); > + } > + > return gen_load(ctx, a, MO_TEUL); > } > > @@ -516,22 +554,32 @@ static bool gen_store(DisasContext *ctx, arg_sb *a, > MemOp memop) > > static bool trans_sb(DisasContext *ctx, arg_sb *a) > { > + CHECK_X_REG_RS1_RS2(ctx, a); > + > return gen_store(ctx, a, MO_SB); > } > > static bool trans_sh(DisasContext *ctx, arg_sh *a) > { > + CHECK_X_REG_RS1_RS2(ctx, a); > + > return gen_store(ctx, a, MO_TESW); > } > > static bool trans_sw(DisasContext *ctx, arg_sw *a) > { > + CHECK_X_REG_RS1_RS2(ctx, a); > + > return gen_store(ctx, a, MO_TESL); > } > > static bool trans_sd(DisasContext *ctx, arg_sd *a) > { > REQUIRE_64_OR_128BIT(ctx); > + if (get_xl(ctx) == MXL_RV64) { > + CHECK_X_REG_RS1_RS2(ctx, a); > + } > + > return gen_store(ctx, a, MO_TEUQ); > } > > @@ -572,6 +620,8 @@ static void gen_addi2_i128(TCGv retl, TCGv reth, > > static bool trans_addi(DisasContext *ctx, arg_addi *a) > { > + CHECK_X_REG_RD_RS1(ctx, a); > + > return gen_arith_imm_fn(ctx, a, EXT_NONE, tcg_gen_addi_tl, >gen_addi2_i128); > } > > @@ -599,26 +649,36 @@ static void gen_sltu_i128(TCGv retl, TCGv reth, > > static bool trans_slti(DisasContext *ctx, arg_slti *a) > { > + CHECK_X_REG_RD_RS1(ctx, a); > + > return gen_arith_imm_tl(ctx, a, EXT_SIGN, gen_slt, gen_slt_i128); > } > > static bool trans_sltiu(DisasContext *ctx, arg_sltiu *a) > { > + CHECK_X_REG_RD_RS1(ctx, a); > + > return gen_arith_imm_tl(ctx, a, EXT_SIGN, gen_sltu, gen_sltu_i128); > } > > static bool trans_xori(DisasContext *ctx, arg_xori *a) > { > + CHECK_X_REG_RD_RS1(ctx, a); > + > return gen_logic_imm_fn(ctx, a, tcg_gen_xori_tl); > } > > static bool trans_ori(DisasContext *ctx, arg_ori *a) > { > + CHECK_X_REG_RD_RS1(ctx, a); > + > return gen_logic_imm_fn(ctx, a, tcg_gen_ori_tl); > } > > static bool trans_andi(DisasContext *ctx, arg_andi *a) > { > + CHECK_X_REG_RD_RS1(ctx, a); > + > return gen_logic_imm_fn(ctx, a, tcg_gen_andi_tl); > } > > @@ -637,6 +697,8 @@ static void gen_slli_i128(TCGv retl, TCGv reth, > > static bool trans_slli(DisasContext *ctx, arg_slli *a) > { > + CHECK_X_REG_RD_RS1(ctx, a); > + > return gen_shift_imm_fn(ctx, a, EXT_NONE, tcg_gen_shli_tl, >gen_slli_i128); > } > > @@ -660,6 +722,8 @@ static void gen_srli_i128(TCGv retl, TCGv reth, > > static bool trans_srli(DisasContext *ctx, arg_srli *a) > { > + CHECK_X_REG_RD_RS1(ctx, a); > + > return gen_shift_imm_fn_per_ol(ctx, a, EXT_NONE, > tcg_gen_shri_tl, gen_srliw, >gen_srli_i128); > } > @@ -684,17 +748,23 @@ static void gen_srai_i128(TCGv retl, TCGv reth, > > static bool trans_srai(DisasContext *ctx, arg_srai *a) > { > + CHECK_X_REG_RD_RS1(ctx, a); > + > return gen_shift_imm_fn_per_ol(ctx, a, EXT_NONE, > tcg_gen_sari_tl, gen_sraiw, >gen_srai_i128); > } > > static bool trans_add(DisasContext *ctx, arg_add *a) > { > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_arith(ctx, a, EXT_NONE, tcg_gen_add_tl, tcg_gen_add2_tl); > } > > static bool trans_sub(DisasContext *ctx, arg_sub *a) > { > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_arith(ctx, a, EXT_NONE, tcg_gen_sub_tl, tcg_gen_sub2_tl); > } > > @@ -727,16 +797,22 @@ static void gen_sll_i128(TCGv destl, TCGv desth, > > static bool trans_sll(DisasContext *ctx, arg_sll *a) > { > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_shift(ctx, a, EXT_NONE, tcg_gen_shl_tl, gen_sll_i128); > } > > static bool trans_slt(DisasContext *ctx, arg_slt *a) > { > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_arith(ctx, a, EXT_SIGN, gen_slt, gen_slt_i128); > } > > static bool trans_sltu(DisasContext *ctx, arg_sltu *a) > { > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_arith(ctx, a, EXT_SIGN, gen_sltu, gen_sltu_i128); > } > > @@ -769,6 +845,8 @@ static void gen_srl_i128(TCGv destl, TCGv desth, > > static bool trans_srl(DisasContext *ctx, arg_srl *a) > { > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_shift(ctx, a, EXT_ZERO, tcg_gen_shr_tl, gen_srl_i128); > } > > @@ -802,27 +880,39 @@ static void gen_sra_i128(TCGv destl, TCGv desth, > > static bool trans_sra(DisasContext *ctx, arg_sra *a) > { > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_shift(ctx, a, EXT_SIGN, tcg_gen_sar_tl, gen_sra_i128); > } > > static bool trans_xor(DisasContext *ctx, arg_xor *a) > { > + CHECK_X_REG_RD_RS1(ctx, a); > + > return gen_logic(ctx, a, tcg_gen_xor_tl); > } > > static bool trans_or(DisasContext *ctx, arg_or *a) > { > + CHECK_X_REG_RD_RS1(ctx, a); > + > return gen_logic(ctx, a, tcg_gen_or_tl); > } > > static bool trans_and(DisasContext *ctx, arg_and *a) > { > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_logic(ctx, a, tcg_gen_and_tl); > } > > static bool trans_addiw(DisasContext *ctx, arg_addiw *a) > { > REQUIRE_64_OR_128BIT(ctx); > + if (get_xl(ctx) == MXL_RV64) { > + CHECK_X_REG_RD_RS1(ctx, a); > + } > + > ctx->ol = MXL_RV32; > return gen_arith_imm_fn(ctx, a, EXT_NONE, tcg_gen_addi_tl, NULL); > } > @@ -830,6 +920,10 @@ static bool trans_addiw(DisasContext *ctx, arg_addiw *a) > static bool trans_slliw(DisasContext *ctx, arg_slliw *a) > { > REQUIRE_64_OR_128BIT(ctx); > + if (get_xl(ctx) == MXL_RV64) { > + CHECK_X_REG_RD_RS1(ctx, a); > + } > + > ctx->ol = MXL_RV32; > return gen_shift_imm_fn(ctx, a, EXT_NONE, tcg_gen_shli_tl, NULL); > } > @@ -837,6 +931,10 @@ static bool trans_slliw(DisasContext *ctx, arg_slliw *a) > static bool trans_srliw(DisasContext *ctx, arg_srliw *a) > { > REQUIRE_64_OR_128BIT(ctx); > + if (get_xl(ctx) == MXL_RV64) { > + CHECK_X_REG_RD_RS1(ctx, a); > + } > + > ctx->ol = MXL_RV32; > return gen_shift_imm_fn(ctx, a, EXT_NONE, gen_srliw, NULL); > } > @@ -844,6 +942,10 @@ static bool trans_srliw(DisasContext *ctx, arg_srliw *a) > static bool trans_sraiw(DisasContext *ctx, arg_sraiw *a) > { > REQUIRE_64_OR_128BIT(ctx); > + if (get_xl(ctx) == MXL_RV64) { > + CHECK_X_REG_RD_RS1(ctx, a); > + } > + > ctx->ol = MXL_RV32; > return gen_shift_imm_fn(ctx, a, EXT_NONE, gen_sraiw, NULL); > } > @@ -872,6 +974,10 @@ static bool trans_sraid(DisasContext *ctx, arg_sraid *a) > static bool trans_addw(DisasContext *ctx, arg_addw *a) > { > REQUIRE_64_OR_128BIT(ctx); > + if (get_xl(ctx) == MXL_RV64) { > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + } > + > ctx->ol = MXL_RV32; > return gen_arith(ctx, a, EXT_NONE, tcg_gen_add_tl, NULL); > } > @@ -879,6 +985,10 @@ static bool trans_addw(DisasContext *ctx, arg_addw *a) > static bool trans_subw(DisasContext *ctx, arg_subw *a) > { > REQUIRE_64_OR_128BIT(ctx); > + if (get_xl(ctx) == MXL_RV64) { > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + } > + > ctx->ol = MXL_RV32; > return gen_arith(ctx, a, EXT_NONE, tcg_gen_sub_tl, NULL); > } > @@ -886,6 +996,10 @@ static bool trans_subw(DisasContext *ctx, arg_subw *a) > static bool trans_sllw(DisasContext *ctx, arg_sllw *a) > { > REQUIRE_64_OR_128BIT(ctx); > + if (get_xl(ctx) == MXL_RV64) { > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + } > + > ctx->ol = MXL_RV32; > return gen_shift(ctx, a, EXT_NONE, tcg_gen_shl_tl, NULL); > } > @@ -893,6 +1007,10 @@ static bool trans_sllw(DisasContext *ctx, arg_sllw *a) > static bool trans_srlw(DisasContext *ctx, arg_srlw *a) > { > REQUIRE_64_OR_128BIT(ctx); > + if (get_xl(ctx) == MXL_RV64) { > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + } > + > ctx->ol = MXL_RV32; > return gen_shift(ctx, a, EXT_ZERO, tcg_gen_shr_tl, NULL); > } > @@ -900,6 +1018,10 @@ static bool trans_srlw(DisasContext *ctx, arg_srlw *a) > static bool trans_sraw(DisasContext *ctx, arg_sraw *a) > { > REQUIRE_64_OR_128BIT(ctx); > + if (get_xl(ctx) == MXL_RV64) { > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + } > + > ctx->ol = MXL_RV32; > return gen_shift(ctx, a, EXT_SIGN, tcg_gen_sar_tl, NULL); > } > @@ -1047,6 +1169,8 @@ static bool trans_csrrw(DisasContext *ctx, arg_csrrw *a) > { > RISCVMXL xl = get_xl(ctx); > if (xl < MXL_RV128) { > + CHECK_X_REG_RD_RS1(ctx, a); > + > TCGv src = get_gpr(ctx, a->rs1, EXT_NONE); > > /* > @@ -1087,6 +1211,8 @@ static bool trans_csrrs(DisasContext *ctx, arg_csrrs *a) > * unmodified value back to the csr and will cause side effects. > */ > if (get_xl(ctx) < MXL_RV128) { > + CHECK_X_REG_RD_RS1(ctx, a); > + > if (a->rs1 == 0) { > return do_csrr(ctx, a->rd, a->csr); > } > @@ -1116,6 +1242,8 @@ static bool trans_csrrc(DisasContext *ctx, arg_csrrc *a) > * unmodified value back to the csr and will cause side effects. > */ > if (get_xl(ctx) < MXL_RV128) { > + CHECK_X_REG_RD_RS1(ctx, a); > + > if (a->rs1 == 0) { > return do_csrr(ctx, a->rd, a->csr); > } > @@ -1138,6 +1266,8 @@ static bool trans_csrrwi(DisasContext *ctx, arg_csrrwi > *a) > { > RISCVMXL xl = get_xl(ctx); > if (xl < MXL_RV128) { > + CHECK_X_REG_RD(ctx, a); > + > TCGv src = tcg_constant_tl(a->rs1); > > /* > @@ -1177,6 +1307,8 @@ static bool trans_csrrsi(DisasContext *ctx, arg_csrrsi > *a) > * unmodified value back to the csr and will cause side effects. > */ > if (get_xl(ctx) < MXL_RV128) { > + CHECK_X_REG_RD(ctx, a); > + > if (a->rs1 == 0) { > return do_csrr(ctx, a->rd, a->csr); > } > @@ -1205,6 +1337,8 @@ static bool trans_csrrci(DisasContext *ctx, arg_csrrci > * a) > * unmodified value back to the csr and will cause side effects. > */ > if (get_xl(ctx) < MXL_RV128) { > + CHECK_X_REG_RD(ctx, a); > + > if (a->rs1 == 0) { > return do_csrr(ctx, a->rd, a->csr); > } > diff --git a/target/riscv/insn_trans/trans_rvm.c.inc > b/target/riscv/insn_trans/trans_rvm.c.inc > index 795f0ccf14..e72463a465 100644 > --- a/target/riscv/insn_trans/trans_rvm.c.inc > +++ b/target/riscv/insn_trans/trans_rvm.c.inc > @@ -65,6 +65,8 @@ static void gen_mul_i128(TCGv rl, TCGv rh, > static bool trans_mul(DisasContext *ctx, arg_mul *a) > { > REQUIRE_M_OR_ZMMUL(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_arith(ctx, a, EXT_NONE, tcg_gen_mul_tl, gen_mul_i128); > } > > @@ -103,6 +105,8 @@ static void gen_mulh_w(TCGv ret, TCGv s1, TCGv s2) > static bool trans_mulh(DisasContext *ctx, arg_mulh *a) > { > REQUIRE_M_OR_ZMMUL(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_arith_per_ol(ctx, a, EXT_SIGN, gen_mulh, gen_mulh_w, > gen_mulh_i128); > } > @@ -147,6 +151,8 @@ static void gen_mulhsu_w(TCGv ret, TCGv arg1, TCGv arg2) > static bool trans_mulhsu(DisasContext *ctx, arg_mulhsu *a) > { > REQUIRE_M_OR_ZMMUL(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_arith_per_ol(ctx, a, EXT_NONE, gen_mulhsu, gen_mulhsu_w, > gen_mulhsu_i128); > } > @@ -161,6 +167,8 @@ static void gen_mulhu(TCGv ret, TCGv s1, TCGv s2) > static bool trans_mulhu(DisasContext *ctx, arg_mulhu *a) > { > REQUIRE_M_OR_ZMMUL(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > /* gen_mulh_w works for either sign as input. */ > return gen_arith_per_ol(ctx, a, EXT_ZERO, gen_mulhu, gen_mulh_w, > gen_mulhu_i128); > @@ -206,6 +214,8 @@ static void gen_div(TCGv ret, TCGv source1, TCGv source2) > static bool trans_div(DisasContext *ctx, arg_div *a) > { > REQUIRE_EXT(ctx, RVM); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_arith(ctx, a, EXT_SIGN, gen_div, gen_div_i128); > } > > @@ -238,6 +248,8 @@ static void gen_divu(TCGv ret, TCGv source1, TCGv source2) > static bool trans_divu(DisasContext *ctx, arg_divu *a) > { > REQUIRE_EXT(ctx, RVM); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_arith(ctx, a, EXT_ZERO, gen_divu, gen_divu_i128); > } > > @@ -283,6 +295,8 @@ static void gen_rem(TCGv ret, TCGv source1, TCGv source2) > static bool trans_rem(DisasContext *ctx, arg_rem *a) > { > REQUIRE_EXT(ctx, RVM); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_arith(ctx, a, EXT_SIGN, gen_rem, gen_rem_i128); > } > > @@ -316,6 +330,8 @@ static void gen_remu(TCGv ret, TCGv source1, TCGv source2) > static bool trans_remu(DisasContext *ctx, arg_remu *a) > { > REQUIRE_EXT(ctx, RVM); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + > return gen_arith(ctx, a, EXT_ZERO, gen_remu, gen_remu_i128); > } > > @@ -323,6 +339,10 @@ static bool trans_mulw(DisasContext *ctx, arg_mulw *a) > { > REQUIRE_64_OR_128BIT(ctx); > REQUIRE_M_OR_ZMMUL(ctx); > + if (get_xl(ctx) == MXL_RV64) { > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + } > + > ctx->ol = MXL_RV32; > return gen_arith(ctx, a, EXT_NONE, tcg_gen_mul_tl, NULL); > } > @@ -339,6 +359,10 @@ static bool trans_divuw(DisasContext *ctx, arg_divuw *a) > { > REQUIRE_64_OR_128BIT(ctx); > REQUIRE_EXT(ctx, RVM); > + if (get_xl(ctx) == MXL_RV64) { > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + } > + > ctx->ol = MXL_RV32; > return gen_arith(ctx, a, EXT_ZERO, gen_divu, NULL); > } > @@ -347,6 +371,10 @@ static bool trans_remw(DisasContext *ctx, arg_remw *a) > { > REQUIRE_64_OR_128BIT(ctx); > REQUIRE_EXT(ctx, RVM); > + if (get_xl(ctx) == MXL_RV64) { > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + } > + > ctx->ol = MXL_RV32; > return gen_arith(ctx, a, EXT_SIGN, gen_rem, NULL); > } > @@ -355,6 +383,10 @@ static bool trans_remuw(DisasContext *ctx, arg_remuw *a) > { > REQUIRE_64_OR_128BIT(ctx); > REQUIRE_EXT(ctx, RVM); > + if (get_xl(ctx) == MXL_RV64) { > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > + } > + > ctx->ol = MXL_RV32; > return gen_arith(ctx, a, EXT_ZERO, gen_remu, NULL); > } > diff --git a/target/riscv/insn_trans/trans_rvzce.c.inc > b/target/riscv/insn_trans/trans_rvzce.c.inc > index c77c2b927b..f0e9292632 100644 > --- a/target/riscv/insn_trans/trans_rvzce.c.inc > +++ b/target/riscv/insn_trans/trans_rvzce.c.inc > @@ -270,6 +270,7 @@ static bool trans_cm_popretz(DisasContext *ctx, > arg_cm_popret *a) > static bool trans_cm_mva01s(DisasContext *ctx, arg_cm_mva01s *a) > { > REQUIRE_ZCMP(ctx); > + CHECK_X_REG_RS1_RS2(ctx, a); > > TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); > TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); > @@ -288,6 +289,8 @@ static bool trans_cm_mvsa01(DisasContext *ctx, > arg_cm_mvsa01 *a) > return false; > } > > + CHECK_X_REG_RS1_RS2(ctx, a); > + > TCGv a0 = get_gpr(ctx, xA0, EXT_NONE); > TCGv a1 = get_gpr(ctx, xA1, EXT_NONE); > > diff --git a/target/riscv/insn_trans/trans_rvzicond.c.inc > b/target/riscv/insn_trans/trans_rvzicond.c.inc > index c8e43fa325..abca39f634 100644 > --- a/target/riscv/insn_trans/trans_rvzicond.c.inc > +++ b/target/riscv/insn_trans/trans_rvzicond.c.inc > @@ -43,6 +43,7 @@ static void gen_czero_nez(TCGv dest, TCGv src1, TCGv src2) > static bool trans_czero_eqz(DisasContext *ctx, arg_r *a) > { > REQUIRE_ZICOND(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > > return gen_logic(ctx, a, gen_czero_eqz); > } > @@ -50,6 +51,7 @@ static bool trans_czero_eqz(DisasContext *ctx, arg_r *a) > static bool trans_czero_nez(DisasContext *ctx, arg_r *a) > { > REQUIRE_ZICOND(ctx); > + CHECK_X_REG_RD_RS1_RS2(ctx, a); > > return gen_logic(ctx, a, gen_czero_nez); > } > diff --git a/target/riscv/translate.c b/target/riscv/translate.c > index 9ddef2d6e2..91568abfe6 100644 > --- a/target/riscv/translate.c > +++ b/target/riscv/translate.c > @@ -812,6 +812,34 @@ EX_SH(12) > } \ > } while (0) > > +#define CHECK_X_REG_RD(ctx, arg) do { \ > + if (has_ext(ctx, RVE) && \ > + (arg->rd & 0x10)) { \ > + return false; \ > + } \ > + } while (0) > + > +#define CHECK_X_REG_RD_RS1(ctx, arg) do { \ > + if (has_ext(ctx, RVE) && \ > + ((arg->rd | arg->rs1) & 0x10)) { \ > + return false; \ > + } \ > + } while (0) > + > +#define CHECK_X_REG_RS1_RS2(ctx, arg) do { \ > + if (has_ext(ctx, RVE) && \ > + ((arg->rs1 | arg->rs2) & 0x10)) { \ > + return false; \ > + } \ > + } while (0) > + > +#define CHECK_X_REG_RD_RS1_RS2(ctx, arg) do { \ > + if (has_ext(ctx, RVE) && \ > + ((arg->rd | arg->rs1 | arg->rs2) & 0x10)) { \ > + return false; \ > + } \ > + } while (0) > + > static int ex_rvc_register(DisasContext *ctx, int reg) > { > return 8 + reg; > -- >
smime.p7s
Description: S/MIME Cryptographic Signature
