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(+)
RV32E and RV64E reduce the integer register count to 16 general-purpose
registers, (x0-x15), where x0 is a dedicated zero register.
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
Signed-off-by: Gergely Futo <gergely.futo@hightec-rt.com>
---
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;
--
On Fri, Sep 19, 2025 at 11:58 PM Gergely Futo via <qemu-devel@nongnu.org> 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 <gergely.futo@hightec-rt.com>
> ---
> 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;
> --
>
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 <alistair23@gmail.com>
Sent: Monday, September 29, 2025 2:29 AM
To: Gergely Futo
Cc: qemu-devel@nongnu.org; qemu-riscv@nongnu.org; zhiwei_liu@linux.alibaba.com; dbarboza@ventanamicro.com; liwei1518@gmail.com; alistair.francis@wdc.com; palmer@dabbelt.com
Subject: Re: [PATCH] target/riscv: check registers for RV32E/RV64E
On Fri, Sep 19, 2025 at 11:58 PM Gergely Futo via <qemu-devel@nongnu.org> 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 <gergely.futo@hightec-rt.com>
> ---
> 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;
> --
>
© 2016 - 2026 Red Hat, Inc.