From: Gergely Futo via <qemu-riscv@nongnu.org>
To: "qemu-devel@nongnu.org" <qemu-devel@nongnu.org>
Cc: "qemu-riscv@nongnu.org" <qemu-riscv@nongnu.org>,
"zhiwei_liu@linux.alibaba.com" <zhiwei_liu@linux.alibaba.com>,
"dbarboza@ventanamicro.com" <dbarboza@ventanamicro.com>,
"liwei1518@gmail.com" <liwei1518@gmail.com>,
"alistair.francis@wdc.com" <alistair.francis@wdc.com>,
"palmer@dabbelt.com" <palmer@dabbelt.com>
Subject: [PATCH] target/riscv: check registers for RV32E/RV64E
Date: Fri, 19 Sep 2025 12:07:35 +0000 [thread overview]
Message-ID: <c20e4af47811456eaf5f185cd75fca7f@hightec-rt.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 39026 bytes --]
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;
--
[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4253 bytes --]
WARNING: multiple messages have this Message-ID (diff)
From: Gergely Futo via <qemu-devel@nongnu.org>
To: "qemu-devel@nongnu.org" <qemu-devel@nongnu.org>
Cc: "qemu-riscv@nongnu.org" <qemu-riscv@nongnu.org>,
"zhiwei_liu@linux.alibaba.com" <zhiwei_liu@linux.alibaba.com>,
"dbarboza@ventanamicro.com" <dbarboza@ventanamicro.com>,
"liwei1518@gmail.com" <liwei1518@gmail.com>,
"alistair.francis@wdc.com" <alistair.francis@wdc.com>,
"palmer@dabbelt.com" <palmer@dabbelt.com>
Subject: [PATCH] target/riscv: check registers for RV32E/RV64E
Date: Fri, 19 Sep 2025 12:07:35 +0000 [thread overview]
Message-ID: <c20e4af47811456eaf5f185cd75fca7f@hightec-rt.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 39026 bytes --]
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;
--
[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4253 bytes --]
next reply other threads:[~2025-09-19 13:59 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-19 12:07 Gergely Futo via [this message]
2025-09-19 12:07 ` [PATCH] target/riscv: check registers for RV32E/RV64E Gergely Futo via
2025-09-29 0:29 ` Alistair Francis
2025-09-29 6:52 ` Gergely Futo via
2025-09-29 6:52 ` Gergely Futo via
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=c20e4af47811456eaf5f185cd75fca7f@hightec-rt.com \
--to=qemu-riscv@nongnu.org \
--cc=Gergely.Futo@hightec-rt.com \
--cc=alistair.francis@wdc.com \
--cc=dbarboza@ventanamicro.com \
--cc=liwei1518@gmail.com \
--cc=palmer@dabbelt.com \
--cc=qemu-devel@nongnu.org \
--cc=zhiwei_liu@linux.alibaba.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.