[PATCH 6/7] target/riscv: rvv: accept v1.0-legal overlap in widening accumulate instructions

"wangyang" <[email protected]>
Newsgroups org.nongnu.qemu-riscv,org.nongnu.qemu-devel
Message-ID <[email protected]>
Commit 1f090a22 ("target/riscv: rvv: Apply vext_check_input_eew to vector
narrow/widen instructions") added vext_check_input_eew() calls that treat
the destination register group of widening multiply-accumulate
instructions (vwmacc*.vv/.vx, vfwmacc*.vv/.vf, vfwmaccbf16) as an input
read with EEW=2*SEW, and reject any overlap with the SEW-wide sources.

That implements the "same vector register read with two different EEWs is
reserved" rule added in the V-extension 1.1 draft.  The ratified V-1.0
specification (Section 5.2) instead allows a widening destination group
to overlap a source when the source is the highest-numbered part of the
destination group.  For example, with SEW=8/LMUL=1, vwmaccu.vv v2, v1, v3
(destination group {v2,v3}, source vs2=v3) is legal under V-1.0 but
raises an illegal-instruction exception in QEMU.

QEMU only supports vext_spec=v1.0, so legal V-1.0 programs must run.  The
genuinely reserved overlap cases are already rejected by
require_noover()/require_align() in vext_check_dss()/vext_check_ds(), so
dropping the extra input-EEW checks only un-rejects encodings that V-1.0
explicitly allows.  Real V-1.0 hardware (SpacemiT X60, Linux 6.6.63)
executes these encodings.

Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4153
Signed-off-by: wangyang <[email protected]>
---
 target/riscv/tcg/insn_trans/trans_rvbf16.c.inc |  9 ++-------
 target/riscv/tcg/insn_trans/trans_rvv.c.inc    | 14 ++++----------
 2 files changed, 6 insertions(+), 17 deletions(-)

diff --git a/target/riscv/tcg/insn_trans/trans_rvbf16.c.inc b/target/riscv/tcg/insn_trans/trans_rvbf16.c.inc
index 066dc364c5b..0a9cd1ec315 100644
--- a/target/riscv/tcg/insn_trans/trans_rvbf16.c.inc
+++ b/target/riscv/tcg/insn_trans/trans_rvbf16.c.inc
@@ -119,11 +119,8 @@ static bool trans_vfwmaccbf16_vv(DisasContext *ctx, arg_vfwmaccbf16_vv *a)
     REQUIRE_FPU;
     REQUIRE_ZVFBFWMA(ctx);
 
-    uint8_t sew = ctx->sew;
     if (require_rvv(ctx) && vext_check_isa_ill(ctx) && (ctx->sew == MO_16) &&
-        vext_check_dss(ctx, a->rd, a->rs1, a->rs2, a->vm) &&
-        vext_check_input_eew(ctx, a->rd, sew + 1, a->rs1, sew, a->vm) &&
-        vext_check_input_eew(ctx, a->rd, sew + 1, a->rs2, sew, a->vm)) {
+        vext_check_dss(ctx, a->rd, a->rs1, a->rs2, a->vm)) {
         uint32_t data = 0;
 
         gen_set_rm_chkfrm(ctx, RISCV_FRM_DYN);
@@ -149,10 +146,8 @@ static bool trans_vfwmaccbf16_vf(DisasContext *ctx, arg_vfwmaccbf16_vf *a)
     REQUIRE_FPU;
     REQUIRE_ZVFBFWMA(ctx);
 
-    uint8_t sew = ctx->sew;
     if (require_rvv(ctx) && (ctx->sew == MO_16) && vext_check_isa_ill(ctx) &&
-        vext_check_ds(ctx, a->rd, a->rs2, a->vm) &&
-        vext_check_input_eew(ctx, a->rd, sew + 1, a->rs2, sew, a->vm)) {
+        vext_check_ds(ctx, a->rd, a->rs2, a->vm)) {
         uint32_t data = 0;
 
         gen_set_rm(ctx, RISCV_FRM_DYN);
diff --git a/target/riscv/tcg/insn_trans/trans_rvv.c.inc b/target/riscv/tcg/insn_trans/trans_rvv.c.inc
index 9b9a751e58e..fa1ee80bc59 100644
--- a/target/riscv/tcg/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/tcg/insn_trans/trans_rvv.c.inc
@@ -1598,9 +1598,7 @@ static bool opivv_overwrite_widen_check(DisasContext *s, arg_rmrr *a)
 {
     return require_rvv(s) &&
            vext_check_isa_ill(s) &&
-           vext_check_dss(s, a->rd, a->rs1, a->rs2, a->vm) &&
-           vext_check_input_eew(s, a->rd, s->sew + 1, a->rs1, s->sew, a->vm) &&
-           vext_check_input_eew(s, a->rd, s->sew + 1, a->rs2, s->sew, a->vm);
+           vext_check_dss(s, a->rd, a->rs1, a->rs2, a->vm);
 }
 
 static bool do_opivv_widen(DisasContext *s, arg_rmrr *a,
@@ -1654,8 +1652,7 @@ static bool opivx_overwrite_widen_check(DisasContext *s, arg_rmrr *a)
 {
     return require_rvv(s) &&
            vext_check_isa_ill(s) &&
-           vext_check_ds(s, a->rd, a->rs2, a->vm) &&
-           vext_check_input_eew(s, a->rd, s->sew + 1, a->rs2, s->sew, a->vm);
+           vext_check_ds(s, a->rd, a->rs2, a->vm);
 }
 
 #define GEN_OPIVX_WIDEN_TRANS(NAME, CHECK) \
@@ -2554,9 +2551,7 @@ static bool opfvv_widen_check(DisasContext *s, arg_rmrr *a,
 static bool opfvv_overwrite_widen_check(DisasContext *s, arg_rmrr *a,
                                         int8_t valid_bfa_vsew)
 {
-    return opfvv_widen_check(s, a, valid_bfa_vsew) &&
-           vext_check_input_eew(s, a->rd, s->sew + 1, a->rs1, s->sew, a->vm) &&
-           vext_check_input_eew(s, a->rd, s->sew + 1, a->rs2, s->sew, a->vm);
+    return opfvv_widen_check(s, a, valid_bfa_vsew);
 }
 
 /* OPFVV with WIDEN */
@@ -2631,8 +2626,7 @@ static bool opfvf_widen_check(DisasContext *s, arg_rmrr *a,
 static bool opfvf_overwrite_widen_check(DisasContext *s, arg_rmrr *a,
                                         int8_t valid_bfa_vsew)
 {
-    return opfvf_widen_check(s, a, valid_bfa_vsew) &&
-           vext_check_input_eew(s, a->rd, s->sew + 1, a->rs2, s->sew, a->vm);
+    return opfvf_widen_check(s, a, valid_bfa_vsew);
 }
 
 /* OPFVF with WIDEN */
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.