The Zcmp pseudocode marks cm.mva01s/cm.mvsa01 as reserved on RV32E when either compressed saved-register selector is above s1, but the translators only checked REQUIRE_ZCMP. Since %r1s/%r2s map the selectors to register numbers (x8/x9 for s0/s1, x18..x23 for s2..s7), add a gate that returns false when RVE is enabled and either operand exceeds x9, so the high-sreg forms raise an illegal-instruction exception while the s0/s1 forms and all RV32I forms keep retiring.
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4110 Signed-off-by: wangyang <[email protected]> --- 1 file changed, 6 insertions(+), 0 deletions(-) diff --git a/target/riscv/tcg/insn_trans/trans_rvzce.c.inc b/target/riscv/tcg/insn_trans/trans_rvzce.c.inc index 71b4ca5473c..fef522d3932 100644 --- a/target/riscv/tcg/insn_trans/trans_rvzce.c.inc +++ b/target/riscv/tcg/insn_trans/trans_rvzce.c.inc @@ -273,6 +273,10 @@ static bool trans_cm_mva01s(DisasContext *ctx, arg_cm_mva01s *a) { REQUIRE_ZCMP(ctx); + if (has_ext(ctx, RVE) && (a->rs1 > 9 || a->rs2 > 9)) { + return false; + } + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); @@ -286,6 +290,10 @@ static bool trans_cm_mvsa01(DisasContext *ctx, arg_cm_mvsa01 *a) { REQUIRE_ZCMP(ctx); + if (has_ext(ctx, RVE) && (a->rs1 > 9 || a->rs2 > 9)) { + return false; + } + if (a->rs1 == a->rs2) { return false; }
