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