On Tue, 2026-08-11 at 09:14 +0800, wangyang wrote:
> 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]>

Reviewed-by: Alistair Francis <[email protected]>

Alistair

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