target/riscv: Add a property to set vill bit on reserved usage of vsetvli instruction

Usage of vsetvli instruction is reserved if VLMAX is changed when vsetvli rs1
and rd arguments are x0.

In this case, if the new property is true, only the vill bit will be set.

See https://github.com/riscv/riscv-isa-manual/blob/main/src/v-st-ext.adoc#avl-encoding
According to the spec, the above use cases are reserved, and
"Implementations may set vill in either case."

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2422
Signed-off-by: Vasilis Liaskovitis <vliaskovitis@suse.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-ID: <20250618213542.22873-1-vliaskovitis@suse.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
Vasilis Liaskovitis 2025-06-18 23:35:42 +02:00 committed by Alistair Francis
parent a1f44e0c59
commit 5625817e8b
5 changed files with 16 additions and 4 deletions

View file

@ -2632,6 +2632,7 @@ static const Property riscv_cpu_properties[] = {
DEFINE_PROP_BOOL("rvv_ta_all_1s", RISCVCPU, cfg.rvv_ta_all_1s, false), DEFINE_PROP_BOOL("rvv_ta_all_1s", RISCVCPU, cfg.rvv_ta_all_1s, false),
DEFINE_PROP_BOOL("rvv_ma_all_1s", RISCVCPU, cfg.rvv_ma_all_1s, false), DEFINE_PROP_BOOL("rvv_ma_all_1s", RISCVCPU, cfg.rvv_ma_all_1s, false),
DEFINE_PROP_BOOL("rvv_vl_half_avl", RISCVCPU, cfg.rvv_vl_half_avl, false), DEFINE_PROP_BOOL("rvv_vl_half_avl", RISCVCPU, cfg.rvv_vl_half_avl, false),
DEFINE_PROP_BOOL("rvv_vsetvl_x0_vill", RISCVCPU, cfg.rvv_vsetvl_x0_vill, false),
/* /*
* write_misa() is marked as experimental for now so mark * write_misa() is marked as experimental for now so mark

View file

@ -114,6 +114,7 @@ BOOL_FIELD(ext_supm)
BOOL_FIELD(rvv_ta_all_1s) BOOL_FIELD(rvv_ta_all_1s)
BOOL_FIELD(rvv_ma_all_1s) BOOL_FIELD(rvv_ma_all_1s)
BOOL_FIELD(rvv_vl_half_avl) BOOL_FIELD(rvv_vl_half_avl)
BOOL_FIELD(rvv_vsetvl_x0_vill)
/* Named features */ /* Named features */
BOOL_FIELD(ext_svade) BOOL_FIELD(ext_svade)
BOOL_FIELD(ext_zic64b) BOOL_FIELD(ext_zic64b)

View file

@ -159,7 +159,7 @@ DEF_HELPER_FLAGS_3(hyp_hsv_d, TCG_CALL_NO_WG, void, env, tl, tl)
#endif #endif
/* Vector functions */ /* Vector functions */
DEF_HELPER_3(vsetvl, tl, env, tl, tl) DEF_HELPER_4(vsetvl, tl, env, tl, tl, tl)
DEF_HELPER_5(vle8_v, void, ptr, ptr, tl, env, i32) DEF_HELPER_5(vle8_v, void, ptr, ptr, tl, env, i32)
DEF_HELPER_5(vle16_v, void, ptr, ptr, tl, env, i32) DEF_HELPER_5(vle16_v, void, ptr, ptr, tl, env, i32)
DEF_HELPER_5(vle32_v, void, ptr, ptr, tl, env, i32) DEF_HELPER_5(vle32_v, void, ptr, ptr, tl, env, i32)

View file

@ -202,7 +202,7 @@ static bool do_vsetvl(DisasContext *s, int rd, int rs1, TCGv s2)
s1 = get_gpr(s, rs1, EXT_ZERO); s1 = get_gpr(s, rs1, EXT_ZERO);
} }
gen_helper_vsetvl(dst, tcg_env, s1, s2); gen_helper_vsetvl(dst, tcg_env, s1, s2, tcg_constant_tl((int) (rd == 0 && rs1 == 0)));
gen_set_gpr(s, rd, dst); gen_set_gpr(s, rd, dst);
finalize_rvv_inst(s); finalize_rvv_inst(s);
@ -222,7 +222,7 @@ static bool do_vsetivli(DisasContext *s, int rd, TCGv s1, TCGv s2)
dst = dest_gpr(s, rd); dst = dest_gpr(s, rd);
gen_helper_vsetvl(dst, tcg_env, s1, s2); gen_helper_vsetvl(dst, tcg_env, s1, s2, tcg_constant_tl(0));
gen_set_gpr(s, rd, dst); gen_set_gpr(s, rd, dst);
finalize_rvv_inst(s); finalize_rvv_inst(s);
gen_update_pc(s, s->cur_insn_len); gen_update_pc(s, s->cur_insn_len);

View file

@ -35,7 +35,7 @@
#include <math.h> #include <math.h>
target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1, target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
target_ulong s2) target_ulong s2, target_ulong x0)
{ {
int vlmax, vl; int vlmax, vl;
RISCVCPU *cpu = env_archcpu(env); RISCVCPU *cpu = env_archcpu(env);
@ -83,6 +83,16 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
} else { } else {
vl = vlmax; vl = vlmax;
} }
if (cpu->cfg.rvv_vsetvl_x0_vill && x0 && (env->vl != vl)) {
/* only set vill bit. */
env->vill = 1;
env->vtype = 0;
env->vl = 0;
env->vstart = 0;
return 0;
}
env->vl = vl; env->vl = vl;
env->vtype = s2; env->vtype = s2;
env->vstart = 0; env->vstart = 0;