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;
     }

Reply via email to