On 2026-01-28 14:26, Sebastien Michelland wrote:
>
> >> GEN_LDST_WHOLE_TRANS checks for require_rvv but it's always true, even with
> >> e.g. -cpu=rv32,v=false.
> >> --- a/target/riscv/insn_trans/trans_rvv.c.inc
> >> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
> >> @@ -1235,6 +1235,7 @@ static bool ldst_whole_trans(uint32_t vd, uint32_t
> >> rs1,
> >> uint32_t nf,
> >> static bool trans_##NAME(DisasContext *s, arg_##NAME * a)
> >> \
> >> {
> >> \
> >> if (require_rvv(s) &&
> >> \
> >> + vext_check_isa_ill(s) &&
> >> \
> >> QEMU_IS_ALIGNED(a->rd, ARG_NF)) {
> >> \
> >> return ldst_whole_trans(a->rd, a->rs1, ARG_NF,
> >> ctzl(sizeof(ETYPE)), \
> > > gen_helper_##NAME, s, IS_LOAD);
> > > \
>
Hi Sebastien,
Thank you for this patch and for identifying this bug.
But I think that the proposed fix of adding vext_check_isa_ill to whole
register load/store instructions will violate the RISC-V vector specification.
There is an existing comment in trans_rvv.c.inc:
/*
* load and store whole register instructions ignore vtype and vl setting.
* Thus, we don't need to check vill bit. (Section 7.9)
*/
The RISC-V unpriviledge specification (31.3.4.4. Vector Type Illegal (vill))
states that whole register load/store instructions do not depend on vtype:
"If the vill bit is set, then any attempt to execute a vector instruction
that depends upon vtype will raise an illegal-instruction exception.
NOTE: vset{i}vl{i} and whole register loads and stores do not depend
upon vtype."
- https://github.com/riscv/riscv-isa-manual
This means whole register instructions (vl*r.v, vs*r.v) should not check
the vill bit.
The Spike reference implementation confirms this interpretation. Whole
register instructions use require_vector_novtype which does not check vill,
while regular vector instructions use require_vector which does:
// riscv/v_ext_macros.h - used by vl*r.v, vs*r.v
#define VI_ST_WHOLE \
require_vector_novtype(true); \
...
// riscv/decode_macros.h
#define require_vector_novtype(is_log) \
do { \
require_vector_vs; // Only checks VS status
...
} while (0); // NO vill check!
#define require_vector(alu) \
do { \
require_vector_vs;
require(!P.VU.vill); // Checks vill
...
} while (0);
- https://github.com/riscv-software-src/riscv-isa-sim
With this patch, whole register load/store instructions would incorrectly
raise illegal instruction exceptions when vill=1, even though the V extension
is enabled.
I would recommend that we should fix this bug at riscv_get_tb_cpu_state by
checking the CPU configuration in CONFIG_USER_ONLY block (user mode) to
ensures require_rvv returns false when the vector is disabled.
Thanks,
rnax