* [PATCH v3 0/5] riscv: set vstart_eq_zero on mark_vs_dirty
@ 2024-02-20 19:26 Daniel Henrique Barboza
2024-02-20 19:26 ` [PATCH v3 1/5] trans_rvv.c.inc: mark_vs_dirty() before stores Daniel Henrique Barboza
` (4 more replies)
0 siblings, 5 replies; 12+ messages in thread
From: Daniel Henrique Barboza @ 2024-02-20 19:26 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, alistair.francis, bmeng, liwei1518, zhiwei_liu,
palmer, richard.henderson, max.chou, Daniel Henrique Barboza
Hi,
In this new version I decided to scrap patch 3 from v2 and added a patch
that Ivan Klokov sent back in December [1]. In that patch Ivan was
already doing things that Richard suggested to be done in patch 3 of v2.
This is done in patch 5.
Patches 1 and 2 were suggestions from Richard that I'm adding as
cleanup. Patch 2 in particular helped to clean up quite a bit of code.
Patch 3 is a fix in GEN_VEXT_VSLIDEUP_VX() that I caught while doing
code inspection to assert that all helpers were setting env->vstart = 0
in the end.
Patch 4 is patch 2 from v2 without any changes.
Patches based on alistair/riscv-to-apply.next.
Changes from v2:
- patches 1 and 3 from v2 were dropped, patch 2 from v2 is now patch 4
- patch 1: new
- dirty vs state before stores
- patch 2: new
- remove redundant conditionals
- patch 3: new
- assign env->vstart = 0 in GEN_VEXT_VSLIDEUP_VX()
- patch 5: taken from [1] with the following changes:
- fixed conflicts with alistair/riscv-to-apply.next
- changed "finalize_rrv_inst" instances to "finalize_rvv_inst" to fix
trans_rvvk.c.inc build
- set_vstart_eq_zero() removed; finalize_rvv_inst() will do a direct
ctx->vstart_eq_zero = true instead;
- finalize_rvv_inst() is removed from the #ifdef block since it's now
relevant to linux-user
- v2 link: https://lore.kernel.org/qemu-riscv/20240216135719.1034289-1-dbarboza@ventanamicro.com/
Daniel Henrique Barboza (4):
trans_rvv.c.inc: mark_vs_dirty() before stores
target/riscv: remove 'over' brconds from vector trans
target/riscv/vector_helper.c: set vstart = 0 in GEN_VEXT_VSLIDEUP_VX()
trans_rvv.c.inc: remove redundant mark_vs_dirty() calls
Ivan Klokov (1):
target/riscv: Clear vstart_qe_zero flag
target/riscv/insn_trans/trans_rvbf16.c.inc | 6 +-
target/riscv/insn_trans/trans_rvv.c.inc | 224 +++++----------------
target/riscv/insn_trans/trans_rvvk.c.inc | 30 +--
target/riscv/translate.c | 6 +
target/riscv/vector_helper.c | 1 +
5 files changed, 70 insertions(+), 197 deletions(-)
--
2.43.2
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v3 1/5] trans_rvv.c.inc: mark_vs_dirty() before stores
2024-02-20 19:26 [PATCH v3 0/5] riscv: set vstart_eq_zero on mark_vs_dirty Daniel Henrique Barboza
@ 2024-02-20 19:26 ` Daniel Henrique Barboza
2024-02-20 20:17 ` Richard Henderson
2024-02-20 19:26 ` [PATCH v3 2/5] target/riscv: remove 'over' brconds from vector trans Daniel Henrique Barboza
` (3 subsequent siblings)
4 siblings, 1 reply; 12+ messages in thread
From: Daniel Henrique Barboza @ 2024-02-20 19:26 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, alistair.francis, bmeng, liwei1518, zhiwei_liu,
palmer, richard.henderson, max.chou, Daniel Henrique Barboza
While discussing a problem with how we're (not) setting vstart_eq_zero
Richard had the following to say w.r.t the conditional mark_vs_dirty()
calls on load/store functions [1]:
"I think it's required to have stores set dirty unconditionally, before
the operation.
Consider a store that traps on the 2nd element, leaving vstart = 2, and
exiting to the main loop via exception. The exception enters the kernel
page fault handler. The kernel may need to fault in the page for the
process, and in the meantime task switch.
If vs dirty is not already set, the kernel won't know to save vector
state on task switch."
Do a mark_vs_dirty() before store operations. Keep the mark_vs_dirty()
call at the end for loads - the function is a no-op if mstatus_vs is
already set to EXT_STATUS_DIRTY so there's no hurt in store functions
calling it twice.
[1] https://lore.kernel.org/qemu-riscv/72c7503b-0f43-44b8-aa82-fbafed2aac0c@linaro.org/
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
target/riscv/insn_trans/trans_rvv.c.inc | 29 +++++++++++++++----------
1 file changed, 17 insertions(+), 12 deletions(-)
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
index 9e101ab434..2065e9064e 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -636,12 +636,13 @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
tcg_gen_addi_ptr(dest, tcg_env, vreg_ofs(s, vd));
tcg_gen_addi_ptr(mask, tcg_env, vreg_ofs(s, 0));
- fn(dest, mask, base, tcg_env, desc);
-
- if (!is_store) {
+ if (is_store) {
mark_vs_dirty(s);
}
+ fn(dest, mask, base, tcg_env, desc);
+
+ mark_vs_dirty(s);
gen_set_label(over);
return true;
}
@@ -797,12 +798,13 @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
tcg_gen_addi_ptr(dest, tcg_env, vreg_ofs(s, vd));
tcg_gen_addi_ptr(mask, tcg_env, vreg_ofs(s, 0));
- fn(dest, mask, base, stride, tcg_env, desc);
-
- if (!is_store) {
+ if (is_store) {
mark_vs_dirty(s);
}
+ fn(dest, mask, base, stride, tcg_env, desc);
+
+ mark_vs_dirty(s);
gen_set_label(over);
return true;
}
@@ -904,12 +906,13 @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
tcg_gen_addi_ptr(index, tcg_env, vreg_ofs(s, vs2));
tcg_gen_addi_ptr(mask, tcg_env, vreg_ofs(s, 0));
- fn(dest, mask, base, index, tcg_env, desc);
-
- if (!is_store) {
+ if (is_store) {
mark_vs_dirty(s);
}
+ fn(dest, mask, base, index, tcg_env, desc);
+
+ mark_vs_dirty(s);
gen_set_label(over);
return true;
}
@@ -1102,11 +1105,13 @@ static bool ldst_whole_trans(uint32_t vd, uint32_t rs1, uint32_t nf,
base = get_gpr(s, rs1, EXT_NONE);
tcg_gen_addi_ptr(dest, tcg_env, vreg_ofs(s, vd));
- fn(dest, base, tcg_env, desc);
-
- if (!is_store) {
+ if (is_store) {
mark_vs_dirty(s);
}
+
+ fn(dest, base, tcg_env, desc);
+
+ mark_vs_dirty(s);
gen_set_label(over);
return true;
--
2.43.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v3 2/5] target/riscv: remove 'over' brconds from vector trans
2024-02-20 19:26 [PATCH v3 0/5] riscv: set vstart_eq_zero on mark_vs_dirty Daniel Henrique Barboza
2024-02-20 19:26 ` [PATCH v3 1/5] trans_rvv.c.inc: mark_vs_dirty() before stores Daniel Henrique Barboza
@ 2024-02-20 19:26 ` Daniel Henrique Barboza
2024-02-20 20:19 ` Richard Henderson
2024-02-20 19:26 ` [PATCH v3 3/5] target/riscv/vector_helper.c: set vstart = 0 in GEN_VEXT_VSLIDEUP_VX() Daniel Henrique Barboza
` (2 subsequent siblings)
4 siblings, 1 reply; 12+ messages in thread
From: Daniel Henrique Barboza @ 2024-02-20 19:26 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, alistair.francis, bmeng, liwei1518, zhiwei_liu,
palmer, richard.henderson, max.chou, Daniel Henrique Barboza
Most of the vector translations has this following pattern at the start:
TCGLabel *over = gen_new_label();
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
And then right at the end:
gen_set_label(over);
return true;
This means that if vstart >= vl we'll not set vstart = 0 at the end of
the insns - this is done inside the helper that is being skipped. The
reason why this pattern hasn't been a bigger problem is because the
conditional vstart >= vl is very rare.
Checking all the helpers in vector_helper.c we see all of them with a
pattern like this:
for (i = env->vstart; i < vl; i++) {
(...)
}
env->vstart = 0;
Thus they can handle vstart >= vl case gracefully, with the benefit of
setting env->vstart = 0 during the process.
Remove all 'over' conditionals and let the helper set env->vstart = 0
every time.
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
target/riscv/insn_trans/trans_rvv.c.inc | 116 -----------------------
target/riscv/insn_trans/trans_rvvk.c.inc | 18 ----
2 files changed, 134 deletions(-)
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
index 2065e9064e..d80f50acdd 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -616,9 +616,6 @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
TCGv base;
TCGv_i32 desc;
- TCGLabel *over = gen_new_label();
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
-
dest = tcg_temp_new_ptr();
mask = tcg_temp_new_ptr();
base = get_gpr(s, rs1, EXT_NONE);
@@ -643,7 +640,6 @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
fn(dest, mask, base, tcg_env, desc);
mark_vs_dirty(s);
- gen_set_label(over);
return true;
}
@@ -785,9 +781,6 @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
TCGv base, stride;
TCGv_i32 desc;
- TCGLabel *over = gen_new_label();
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
-
dest = tcg_temp_new_ptr();
mask = tcg_temp_new_ptr();
base = get_gpr(s, rs1, EXT_NONE);
@@ -805,7 +798,6 @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
fn(dest, mask, base, stride, tcg_env, desc);
mark_vs_dirty(s);
- gen_set_label(over);
return true;
}
@@ -892,9 +884,6 @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
TCGv base;
TCGv_i32 desc;
- TCGLabel *over = gen_new_label();
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
-
dest = tcg_temp_new_ptr();
mask = tcg_temp_new_ptr();
index = tcg_temp_new_ptr();
@@ -913,7 +902,6 @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
fn(dest, mask, base, index, tcg_env, desc);
mark_vs_dirty(s);
- gen_set_label(over);
return true;
}
@@ -1033,9 +1021,6 @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data,
TCGv base;
TCGv_i32 desc;
- TCGLabel *over = gen_new_label();
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
-
dest = tcg_temp_new_ptr();
mask = tcg_temp_new_ptr();
base = get_gpr(s, rs1, EXT_NONE);
@@ -1048,7 +1033,6 @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data,
fn(dest, mask, base, tcg_env, desc);
mark_vs_dirty(s);
- gen_set_label(over);
return true;
}
@@ -1089,10 +1073,6 @@ static bool ldst_whole_trans(uint32_t vd, uint32_t rs1, uint32_t nf,
uint32_t width, gen_helper_ldst_whole *fn,
DisasContext *s, bool is_store)
{
- uint32_t evl = s->cfg_ptr->vlenb * nf / width;
- TCGLabel *over = gen_new_label();
- tcg_gen_brcondi_tl(TCG_COND_GEU, cpu_vstart, evl, over);
-
TCGv_ptr dest;
TCGv base;
TCGv_i32 desc;
@@ -1112,7 +1092,6 @@ static bool ldst_whole_trans(uint32_t vd, uint32_t rs1, uint32_t nf,
fn(dest, base, tcg_env, desc);
mark_vs_dirty(s);
- gen_set_label(over);
return true;
}
@@ -1187,10 +1166,6 @@ static inline bool
do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn *gvec_fn,
gen_helper_gvec_4_ptr *fn)
{
- TCGLabel *over = gen_new_label();
-
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
-
if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
gvec_fn(s->sew, vreg_ofs(s, a->rd),
vreg_ofs(s, a->rs2), vreg_ofs(s, a->rs1),
@@ -1208,7 +1183,6 @@ do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn *gvec_fn,
s->cfg_ptr->vlenb, data, fn);
}
mark_vs_dirty(s);
- gen_set_label(over);
return true;
}
@@ -1240,9 +1214,6 @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
TCGv_i32 desc;
uint32_t data = 0;
- TCGLabel *over = gen_new_label();
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
-
dest = tcg_temp_new_ptr();
mask = tcg_temp_new_ptr();
src2 = tcg_temp_new_ptr();
@@ -1263,7 +1234,6 @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
fn(dest, mask, src1, src2, tcg_env, desc);
mark_vs_dirty(s);
- gen_set_label(over);
return true;
}
@@ -1402,9 +1372,6 @@ static bool opivi_trans(uint32_t vd, uint32_t imm, uint32_t vs2, uint32_t vm,
TCGv_i32 desc;
uint32_t data = 0;
- TCGLabel *over = gen_new_label();
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
-
dest = tcg_temp_new_ptr();
mask = tcg_temp_new_ptr();
src2 = tcg_temp_new_ptr();
@@ -1425,7 +1392,6 @@ static bool opivi_trans(uint32_t vd, uint32_t imm, uint32_t vs2, uint32_t vm,
fn(dest, mask, src1, src2, tcg_env, desc);
mark_vs_dirty(s);
- gen_set_label(over);
return true;
}
@@ -1487,8 +1453,6 @@ static bool do_opivv_widen(DisasContext *s, arg_rmrr *a,
{
if (checkfn(s, a)) {
uint32_t data = 0;
- TCGLabel *over = gen_new_label();
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
data = FIELD_DP32(data, VDATA, VM, a->vm);
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
@@ -1501,7 +1465,6 @@ static bool do_opivv_widen(DisasContext *s, arg_rmrr *a,
s->cfg_ptr->vlenb,
data, fn);
mark_vs_dirty(s);
- gen_set_label(over);
return true;
}
return false;
@@ -1563,8 +1526,6 @@ static bool do_opiwv_widen(DisasContext *s, arg_rmrr *a,
{
if (opiwv_widen_check(s, a)) {
uint32_t data = 0;
- TCGLabel *over = gen_new_label();
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
data = FIELD_DP32(data, VDATA, VM, a->vm);
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
@@ -1576,7 +1537,6 @@ static bool do_opiwv_widen(DisasContext *s, arg_rmrr *a,
tcg_env, s->cfg_ptr->vlenb,
s->cfg_ptr->vlenb, data, fn);
mark_vs_dirty(s);
- gen_set_label(over);
return true;
}
return false;
@@ -1635,8 +1595,6 @@ static bool opivv_trans(uint32_t vd, uint32_t vs1, uint32_t vs2, uint32_t vm,
gen_helper_gvec_4_ptr *fn, DisasContext *s)
{
uint32_t data = 0;
- TCGLabel *over = gen_new_label();
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
data = FIELD_DP32(data, VDATA, VM, vm);
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
@@ -1647,7 +1605,6 @@ static bool opivv_trans(uint32_t vd, uint32_t vs1, uint32_t vs2, uint32_t vm,
vreg_ofs(s, vs2), tcg_env, s->cfg_ptr->vlenb,
s->cfg_ptr->vlenb, data, fn);
mark_vs_dirty(s);
- gen_set_label(over);
return true;
}
@@ -1826,8 +1783,6 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
gen_helper_##NAME##_h, \
gen_helper_##NAME##_w, \
}; \
- TCGLabel *over = gen_new_label(); \
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
\
data = FIELD_DP32(data, VDATA, VM, a->vm); \
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
@@ -1840,7 +1795,6 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
s->cfg_ptr->vlenb, data, \
fns[s->sew]); \
mark_vs_dirty(s); \
- gen_set_label(over); \
return true; \
} \
return false; \
@@ -2037,14 +1991,11 @@ static bool trans_vmv_v_v(DisasContext *s, arg_vmv_v_v *a)
gen_helper_vmv_v_v_b, gen_helper_vmv_v_v_h,
gen_helper_vmv_v_v_w, gen_helper_vmv_v_v_d,
};
- TCGLabel *over = gen_new_label();
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
tcg_gen_gvec_2_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1),
tcg_env, s->cfg_ptr->vlenb,
s->cfg_ptr->vlenb, data,
fns[s->sew]);
- gen_set_label(over);
}
mark_vs_dirty(s);
return true;
@@ -2060,8 +2011,6 @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
/* vmv.v.x has rs2 = 0 and vm = 1 */
vext_check_ss(s, a->rd, 0, 1)) {
TCGv s1;
- TCGLabel *over = gen_new_label();
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
s1 = get_gpr(s, a->rs1, EXT_SIGN);
@@ -2094,7 +2043,6 @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
}
mark_vs_dirty(s);
- gen_set_label(over);
return true;
}
return false;
@@ -2121,8 +2069,6 @@ static bool trans_vmv_v_i(DisasContext *s, arg_vmv_v_i *a)
gen_helper_vmv_v_x_b, gen_helper_vmv_v_x_h,
gen_helper_vmv_v_x_w, gen_helper_vmv_v_x_d,
};
- TCGLabel *over = gen_new_label();
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
s1 = tcg_constant_i64(simm);
dest = tcg_temp_new_ptr();
@@ -2132,7 +2078,6 @@ static bool trans_vmv_v_i(DisasContext *s, arg_vmv_v_i *a)
fns[s->sew](dest, s1, tcg_env, desc);
mark_vs_dirty(s);
- gen_set_label(over);
}
return true;
}
@@ -2267,9 +2212,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
gen_helper_##NAME##_w, \
gen_helper_##NAME##_d, \
}; \
- TCGLabel *over = gen_new_label(); \
gen_set_rm(s, RISCV_FRM_DYN); \
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
\
data = FIELD_DP32(data, VDATA, VM, a->vm); \
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
@@ -2284,7 +2227,6 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
s->cfg_ptr->vlenb, data, \
fns[s->sew - 1]); \
mark_vs_dirty(s); \
- gen_set_label(over); \
return true; \
} \
return false; \
@@ -2302,9 +2244,6 @@ static bool opfvf_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
TCGv_i32 desc;
TCGv_i64 t1;
- TCGLabel *over = gen_new_label();
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
-
dest = tcg_temp_new_ptr();
mask = tcg_temp_new_ptr();
src2 = tcg_temp_new_ptr();
@@ -2322,7 +2261,6 @@ static bool opfvf_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
fn(dest, mask, t1, src2, tcg_env, desc);
mark_vs_dirty(s);
- gen_set_label(over);
return true;
}
@@ -2385,9 +2323,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
static gen_helper_gvec_4_ptr * const fns[2] = { \
gen_helper_##NAME##_h, gen_helper_##NAME##_w, \
}; \
- TCGLabel *over = gen_new_label(); \
gen_set_rm(s, RISCV_FRM_DYN); \
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);\
\
data = FIELD_DP32(data, VDATA, VM, a->vm); \
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
@@ -2400,7 +2336,6 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
s->cfg_ptr->vlenb, data, \
fns[s->sew - 1]); \
mark_vs_dirty(s); \
- gen_set_label(over); \
return true; \
} \
return false; \
@@ -2459,9 +2394,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
static gen_helper_gvec_4_ptr * const fns[2] = { \
gen_helper_##NAME##_h, gen_helper_##NAME##_w, \
}; \
- TCGLabel *over = gen_new_label(); \
gen_set_rm(s, RISCV_FRM_DYN); \
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
\
data = FIELD_DP32(data, VDATA, VM, a->vm); \
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
@@ -2474,7 +2407,6 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
s->cfg_ptr->vlenb, data, \
fns[s->sew - 1]); \
mark_vs_dirty(s); \
- gen_set_label(over); \
return true; \
} \
return false; \
@@ -2576,9 +2508,7 @@ static bool do_opfv(DisasContext *s, arg_rmr *a,
{
if (checkfn(s, a)) {
uint32_t data = 0;
- TCGLabel *over = gen_new_label();
gen_set_rm_chkfrm(s, rm);
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
data = FIELD_DP32(data, VDATA, VM, a->vm);
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
@@ -2589,7 +2519,6 @@ static bool do_opfv(DisasContext *s, arg_rmr *a,
s->cfg_ptr->vlenb,
s->cfg_ptr->vlenb, data, fn);
mark_vs_dirty(s);
- gen_set_label(over);
return true;
}
return false;
@@ -2688,8 +2617,6 @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
gen_helper_vmv_v_x_w,
gen_helper_vmv_v_x_d,
};
- TCGLabel *over = gen_new_label();
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
t1 = tcg_temp_new_i64();
/* NaN-box f[rs1] */
@@ -2703,7 +2630,6 @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
fns[s->sew - 1](dest, t1, tcg_env, desc);
mark_vs_dirty(s);
- gen_set_label(over);
}
return true;
}
@@ -2765,9 +2691,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
gen_helper_##HELPER##_h, \
gen_helper_##HELPER##_w, \
}; \
- TCGLabel *over = gen_new_label(); \
gen_set_rm_chkfrm(s, FRM); \
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
\
data = FIELD_DP32(data, VDATA, VM, a->vm); \
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
@@ -2779,7 +2703,6 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
s->cfg_ptr->vlenb, data, \
fns[s->sew - 1]); \
mark_vs_dirty(s); \
- gen_set_label(over); \
return true; \
} \
return false; \
@@ -2816,9 +2739,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
gen_helper_##NAME##_h, \
gen_helper_##NAME##_w, \
}; \
- TCGLabel *over = gen_new_label(); \
gen_set_rm(s, RISCV_FRM_DYN); \
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
\
data = FIELD_DP32(data, VDATA, VM, a->vm); \
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
@@ -2830,7 +2751,6 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
s->cfg_ptr->vlenb, data, \
fns[s->sew]); \
mark_vs_dirty(s); \
- gen_set_label(over); \
return true; \
} \
return false; \
@@ -2883,9 +2803,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
gen_helper_##HELPER##_h, \
gen_helper_##HELPER##_w, \
}; \
- TCGLabel *over = gen_new_label(); \
gen_set_rm_chkfrm(s, FRM); \
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
\
data = FIELD_DP32(data, VDATA, VM, a->vm); \
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
@@ -2897,7 +2815,6 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
s->cfg_ptr->vlenb, data, \
fns[s->sew - 1]); \
mark_vs_dirty(s); \
- gen_set_label(over); \
return true; \
} \
return false; \
@@ -2932,9 +2849,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
gen_helper_##HELPER##_h, \
gen_helper_##HELPER##_w, \
}; \
- TCGLabel *over = gen_new_label(); \
gen_set_rm_chkfrm(s, FRM); \
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
\
data = FIELD_DP32(data, VDATA, VM, a->vm); \
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
@@ -2946,7 +2861,6 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
s->cfg_ptr->vlenb, data, \
fns[s->sew]); \
mark_vs_dirty(s); \
- gen_set_label(over); \
return true; \
} \
return false; \
@@ -3023,8 +2937,6 @@ static bool trans_##NAME(DisasContext *s, arg_r *a) \
vext_check_isa_ill(s)) { \
uint32_t data = 0; \
gen_helper_gvec_4_ptr *fn = gen_helper_##NAME; \
- TCGLabel *over = gen_new_label(); \
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
\
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
data = \
@@ -3035,7 +2947,6 @@ static bool trans_##NAME(DisasContext *s, arg_r *a) \
s->cfg_ptr->vlenb, \
s->cfg_ptr->vlenb, data, fn); \
mark_vs_dirty(s); \
- gen_set_label(over); \
return true; \
} \
return false; \
@@ -3123,8 +3034,6 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
s->vstart_eq_zero) { \
uint32_t data = 0; \
gen_helper_gvec_3_ptr *fn = gen_helper_##NAME; \
- TCGLabel *over = gen_new_label(); \
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
\
data = FIELD_DP32(data, VDATA, VM, a->vm); \
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
@@ -3137,7 +3046,6 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
s->cfg_ptr->vlenb, \
data, fn); \
mark_vs_dirty(s); \
- gen_set_label(over); \
return true; \
} \
return false; \
@@ -3163,8 +3071,6 @@ static bool trans_viota_m(DisasContext *s, arg_viota_m *a)
require_align(a->rd, s->lmul) &&
s->vstart_eq_zero) {
uint32_t data = 0;
- TCGLabel *over = gen_new_label();
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
data = FIELD_DP32(data, VDATA, VM, a->vm);
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
@@ -3179,7 +3085,6 @@ static bool trans_viota_m(DisasContext *s, arg_viota_m *a)
s->cfg_ptr->vlenb,
s->cfg_ptr->vlenb, data, fns[s->sew]);
mark_vs_dirty(s);
- gen_set_label(over);
return true;
}
return false;
@@ -3193,8 +3098,6 @@ static bool trans_vid_v(DisasContext *s, arg_vid_v *a)
require_align(a->rd, s->lmul) &&
require_vm(a->vm, a->rd)) {
uint32_t data = 0;
- TCGLabel *over = gen_new_label();
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
data = FIELD_DP32(data, VDATA, VM, a->vm);
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
@@ -3209,7 +3112,6 @@ static bool trans_vid_v(DisasContext *s, arg_vid_v *a)
s->cfg_ptr->vlenb,
data, fns[s->sew]);
mark_vs_dirty(s);
- gen_set_label(over);
return true;
}
return false;
@@ -3378,9 +3280,6 @@ static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x *a)
/* This instruction ignores LMUL and vector register groups */
TCGv_i64 t1;
TCGv s1;
- TCGLabel *over = gen_new_label();
-
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
t1 = tcg_temp_new_i64();
@@ -3392,7 +3291,6 @@ static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x *a)
tcg_gen_ext_tl_i64(t1, s1);
vec_element_storei(s, a->rd, 0, t1);
mark_vs_dirty(s);
- gen_set_label(over);
return true;
}
return false;
@@ -3434,10 +3332,6 @@ static bool trans_vfmv_s_f(DisasContext *s, arg_vfmv_s_f *a)
/* The instructions ignore LMUL and vector register group. */
TCGv_i64 t1;
- TCGLabel *over = gen_new_label();
-
- /* if vstart >= vl, skip vector register write back */
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
/* NaN-box f[rs1] */
t1 = tcg_temp_new_i64();
@@ -3445,7 +3339,6 @@ static bool trans_vfmv_s_f(DisasContext *s, arg_vfmv_s_f *a)
vec_element_storei(s, a->rd, 0, t1);
mark_vs_dirty(s);
- gen_set_label(over);
return true;
}
return false;
@@ -3616,8 +3509,6 @@ static bool trans_vcompress_vm(DisasContext *s, arg_r *a)
gen_helper_vcompress_vm_b, gen_helper_vcompress_vm_h,
gen_helper_vcompress_vm_w, gen_helper_vcompress_vm_d,
};
- TCGLabel *over = gen_new_label();
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
data = FIELD_DP32(data, VDATA, VTA, s->vta);
@@ -3627,7 +3518,6 @@ static bool trans_vcompress_vm(DisasContext *s, arg_r *a)
s->cfg_ptr->vlenb, data,
fns[s->sew]);
mark_vs_dirty(s);
- gen_set_label(over);
return true;
}
return false;
@@ -3650,12 +3540,9 @@ static bool trans_##NAME(DisasContext *s, arg_##NAME * a) \
vreg_ofs(s, a->rs2), maxsz, maxsz); \
mark_vs_dirty(s); \
} else { \
- TCGLabel *over = gen_new_label(); \
- tcg_gen_brcondi_tl(TCG_COND_GEU, cpu_vstart, maxsz, over); \
tcg_gen_gvec_2_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2), \
tcg_env, maxsz, maxsz, 0, gen_helper_vmvr_v); \
mark_vs_dirty(s); \
- gen_set_label(over); \
} \
return true; \
} \
@@ -3684,8 +3571,6 @@ static bool int_ext_op(DisasContext *s, arg_rmr *a, uint8_t seq)
{
uint32_t data = 0;
gen_helper_gvec_3_ptr *fn;
- TCGLabel *over = gen_new_label();
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
static gen_helper_gvec_3_ptr * const fns[6][4] = {
{
@@ -3730,7 +3615,6 @@ static bool int_ext_op(DisasContext *s, arg_rmr *a, uint8_t seq)
s->cfg_ptr->vlenb, data, fn);
mark_vs_dirty(s);
- gen_set_label(over);
return true;
}
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
index a5cdd1b67f..6d640e4596 100644
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
@@ -164,8 +164,6 @@ GEN_OPIVX_GVEC_TRANS_CHECK(vandn_vx, andcs, zvkb_vx_check)
gen_helper_##NAME##_w, \
gen_helper_##NAME##_d, \
}; \
- TCGLabel *over = gen_new_label(); \
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
\
data = FIELD_DP32(data, VDATA, VM, a->vm); \
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
@@ -177,7 +175,6 @@ GEN_OPIVX_GVEC_TRANS_CHECK(vandn_vx, andcs, zvkb_vx_check)
s->cfg_ptr->vlenb, s->cfg_ptr->vlenb, \
data, fns[s->sew]); \
mark_vs_dirty(s); \
- gen_set_label(over); \
return true; \
} \
return false; \
@@ -249,14 +246,12 @@ GEN_OPIVI_WIDEN_TRANS(vwsll_vi, IMM_ZX, vwsll_vx, vwsll_vx_check)
TCGv_ptr rd_v, rs2_v; \
TCGv_i32 desc, egs; \
uint32_t data = 0; \
- TCGLabel *over = gen_new_label(); \
\
if (!s->vstart_eq_zero || !s->vl_eq_vlmax) { \
/* save opcode for unwinding in case we throw an exception */ \
decode_save_opc(s); \
egs = tcg_constant_i32(EGS); \
gen_helper_egs_check(egs, tcg_env); \
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
} \
\
data = FIELD_DP32(data, VDATA, VM, a->vm); \
@@ -272,7 +267,6 @@ GEN_OPIVI_WIDEN_TRANS(vwsll_vi, IMM_ZX, vwsll_vx, vwsll_vx_check)
tcg_gen_addi_ptr(rs2_v, tcg_env, vreg_ofs(s, a->rs2)); \
gen_helper_##NAME(rd_v, rs2_v, tcg_env, desc); \
mark_vs_dirty(s); \
- gen_set_label(over); \
return true; \
} \
return false; \
@@ -325,14 +319,12 @@ GEN_V_UNMASKED_TRANS(vaesem_vs, vaes_check_vs, ZVKNED_EGS)
TCGv_ptr rd_v, rs2_v; \
TCGv_i32 uimm_v, desc, egs; \
uint32_t data = 0; \
- TCGLabel *over = gen_new_label(); \
\
if (!s->vstart_eq_zero || !s->vl_eq_vlmax) { \
/* save opcode for unwinding in case we throw an exception */ \
decode_save_opc(s); \
egs = tcg_constant_i32(EGS); \
gen_helper_egs_check(egs, tcg_env); \
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
} \
\
data = FIELD_DP32(data, VDATA, VM, a->vm); \
@@ -350,7 +342,6 @@ GEN_V_UNMASKED_TRANS(vaesem_vs, vaes_check_vs, ZVKNED_EGS)
tcg_gen_addi_ptr(rs2_v, tcg_env, vreg_ofs(s, a->rs2)); \
gen_helper_##NAME(rd_v, rs2_v, uimm_v, tcg_env, desc); \
mark_vs_dirty(s); \
- gen_set_label(over); \
return true; \
} \
return false; \
@@ -394,7 +385,6 @@ GEN_VI_UNMASKED_TRANS(vaeskf2_vi, vaeskf2_check, ZVKNED_EGS)
{ \
if (CHECK(s, a)) { \
uint32_t data = 0; \
- TCGLabel *over = gen_new_label(); \
TCGv_i32 egs; \
\
if (!s->vstart_eq_zero || !s->vl_eq_vlmax) { \
@@ -402,7 +392,6 @@ GEN_VI_UNMASKED_TRANS(vaeskf2_vi, vaeskf2_check, ZVKNED_EGS)
decode_save_opc(s); \
egs = tcg_constant_i32(EGS); \
gen_helper_egs_check(egs, tcg_env); \
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
} \
\
data = FIELD_DP32(data, VDATA, VM, a->vm); \
@@ -417,7 +406,6 @@ GEN_VI_UNMASKED_TRANS(vaeskf2_vi, vaeskf2_check, ZVKNED_EGS)
data, gen_helper_##NAME); \
\
mark_vs_dirty(s); \
- gen_set_label(over); \
return true; \
} \
return false; \
@@ -448,7 +436,6 @@ static bool trans_vsha2cl_vv(DisasContext *s, arg_rmrr *a)
{
if (vsha_check(s, a)) {
uint32_t data = 0;
- TCGLabel *over = gen_new_label();
TCGv_i32 egs;
if (!s->vstart_eq_zero || !s->vl_eq_vlmax) {
@@ -456,7 +443,6 @@ static bool trans_vsha2cl_vv(DisasContext *s, arg_rmrr *a)
decode_save_opc(s);
egs = tcg_constant_i32(ZVKNH_EGS);
gen_helper_egs_check(egs, tcg_env);
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
}
data = FIELD_DP32(data, VDATA, VM, a->vm);
@@ -472,7 +458,6 @@ static bool trans_vsha2cl_vv(DisasContext *s, arg_rmrr *a)
gen_helper_vsha2cl32_vv : gen_helper_vsha2cl64_vv);
mark_vs_dirty(s);
- gen_set_label(over);
return true;
}
return false;
@@ -482,7 +467,6 @@ static bool trans_vsha2ch_vv(DisasContext *s, arg_rmrr *a)
{
if (vsha_check(s, a)) {
uint32_t data = 0;
- TCGLabel *over = gen_new_label();
TCGv_i32 egs;
if (!s->vstart_eq_zero || !s->vl_eq_vlmax) {
@@ -490,7 +474,6 @@ static bool trans_vsha2ch_vv(DisasContext *s, arg_rmrr *a)
decode_save_opc(s);
egs = tcg_constant_i32(ZVKNH_EGS);
gen_helper_egs_check(egs, tcg_env);
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
}
data = FIELD_DP32(data, VDATA, VM, a->vm);
@@ -506,7 +489,6 @@ static bool trans_vsha2ch_vv(DisasContext *s, arg_rmrr *a)
gen_helper_vsha2ch32_vv : gen_helper_vsha2ch64_vv);
mark_vs_dirty(s);
- gen_set_label(over);
return true;
}
return false;
--
2.43.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v3 3/5] target/riscv/vector_helper.c: set vstart = 0 in GEN_VEXT_VSLIDEUP_VX()
2024-02-20 19:26 [PATCH v3 0/5] riscv: set vstart_eq_zero on mark_vs_dirty Daniel Henrique Barboza
2024-02-20 19:26 ` [PATCH v3 1/5] trans_rvv.c.inc: mark_vs_dirty() before stores Daniel Henrique Barboza
2024-02-20 19:26 ` [PATCH v3 2/5] target/riscv: remove 'over' brconds from vector trans Daniel Henrique Barboza
@ 2024-02-20 19:26 ` Daniel Henrique Barboza
2024-02-20 20:20 ` Richard Henderson
2024-02-20 19:26 ` [PATCH v3 4/5] trans_rvv.c.inc: remove redundant mark_vs_dirty() calls Daniel Henrique Barboza
2024-02-20 19:26 ` [PATCH v3 5/5] target/riscv: Clear vstart_qe_zero flag Daniel Henrique Barboza
4 siblings, 1 reply; 12+ messages in thread
From: Daniel Henrique Barboza @ 2024-02-20 19:26 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, alistair.francis, bmeng, liwei1518, zhiwei_liu,
palmer, richard.henderson, max.chou, Daniel Henrique Barboza
The helper isn't setting env->vstart = 0 after its execution, as it is
expected from every vector instruction that completes successfully.
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
target/riscv/vector_helper.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 84cec73eb2..cc7290a1bb 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4782,6 +4782,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \
} \
*((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i - offset)); \
} \
+ env->vstart = 0; \
/* set tail elements to 1s */ \
vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz); \
}
--
2.43.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v3 4/5] trans_rvv.c.inc: remove redundant mark_vs_dirty() calls
2024-02-20 19:26 [PATCH v3 0/5] riscv: set vstart_eq_zero on mark_vs_dirty Daniel Henrique Barboza
` (2 preceding siblings ...)
2024-02-20 19:26 ` [PATCH v3 3/5] target/riscv/vector_helper.c: set vstart = 0 in GEN_VEXT_VSLIDEUP_VX() Daniel Henrique Barboza
@ 2024-02-20 19:26 ` Daniel Henrique Barboza
2024-02-20 20:20 ` Richard Henderson
2024-02-20 19:26 ` [PATCH v3 5/5] target/riscv: Clear vstart_qe_zero flag Daniel Henrique Barboza
4 siblings, 1 reply; 12+ messages in thread
From: Daniel Henrique Barboza @ 2024-02-20 19:26 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, alistair.francis, bmeng, liwei1518, zhiwei_liu,
palmer, richard.henderson, max.chou, Daniel Henrique Barboza
trans_vmv_v_i , trans_vfmv_v_f and the trans_##NAME macro from
GEN_VMV_WHOLE_TRANS() are calling mark_vs_dirty() in both branches of
their 'ifs'. conditionals.
Call it just once in the end like other functions are doing.
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
target/riscv/insn_trans/trans_rvv.c.inc | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
index d80f50acdd..5436d9e3ef 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2058,7 +2058,6 @@ static bool trans_vmv_v_i(DisasContext *s, arg_vmv_v_i *a)
if (s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
tcg_gen_gvec_dup_imm(s->sew, vreg_ofs(s, a->rd),
MAXSZ(s), MAXSZ(s), simm);
- mark_vs_dirty(s);
} else {
TCGv_i32 desc;
TCGv_i64 s1;
@@ -2076,9 +2075,8 @@ static bool trans_vmv_v_i(DisasContext *s, arg_vmv_v_i *a)
s->cfg_ptr->vlenb, data));
tcg_gen_addi_ptr(dest, tcg_env, vreg_ofs(s, a->rd));
fns[s->sew](dest, s1, tcg_env, desc);
-
- mark_vs_dirty(s);
}
+ mark_vs_dirty(s);
return true;
}
return false;
@@ -2605,7 +2603,6 @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
tcg_gen_gvec_dup_i64(s->sew, vreg_ofs(s, a->rd),
MAXSZ(s), MAXSZ(s), t1);
- mark_vs_dirty(s);
} else {
TCGv_ptr dest;
TCGv_i32 desc;
@@ -2628,9 +2625,8 @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
tcg_gen_addi_ptr(dest, tcg_env, vreg_ofs(s, a->rd));
fns[s->sew - 1](dest, t1, tcg_env, desc);
-
- mark_vs_dirty(s);
}
+ mark_vs_dirty(s);
return true;
}
return false;
@@ -3538,12 +3534,11 @@ static bool trans_##NAME(DisasContext *s, arg_##NAME * a) \
if (s->vstart_eq_zero) { \
tcg_gen_gvec_mov(s->sew, vreg_ofs(s, a->rd), \
vreg_ofs(s, a->rs2), maxsz, maxsz); \
- mark_vs_dirty(s); \
} else { \
tcg_gen_gvec_2_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2), \
tcg_env, maxsz, maxsz, 0, gen_helper_vmvr_v); \
- mark_vs_dirty(s); \
} \
+ mark_vs_dirty(s); \
return true; \
} \
return false; \
--
2.43.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v3 5/5] target/riscv: Clear vstart_qe_zero flag
2024-02-20 19:26 [PATCH v3 0/5] riscv: set vstart_eq_zero on mark_vs_dirty Daniel Henrique Barboza
` (3 preceding siblings ...)
2024-02-20 19:26 ` [PATCH v3 4/5] trans_rvv.c.inc: remove redundant mark_vs_dirty() calls Daniel Henrique Barboza
@ 2024-02-20 19:26 ` Daniel Henrique Barboza
2024-02-20 20:22 ` Richard Henderson
4 siblings, 1 reply; 12+ messages in thread
From: Daniel Henrique Barboza @ 2024-02-20 19:26 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, alistair.francis, bmeng, liwei1518, zhiwei_liu,
palmer, richard.henderson, max.chou, Ivan Klokov,
Daniel Henrique Barboza
From: Ivan Klokov <ivan.klokov@syntacore.com>
The vstart_qe_zero flag is set at the beginning of the translation
phase from the env->vstart variable. During the execution phase, some
instructions may change env->vstart, but the flag remains the same as
at the start of the block. With some combinations of instructions this
causes an illegal instruction exception. This patch simultaneously
updates flag and env->vstart and to avoid inconsistency.
Signed-off-by: Ivan Klokov <ivan.klokov@syntacore.com>
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
target/riscv/insn_trans/trans_rvbf16.c.inc | 6 +-
target/riscv/insn_trans/trans_rvv.c.inc | 82 +++++++++++-----------
target/riscv/insn_trans/trans_rvvk.c.inc | 12 ++--
target/riscv/translate.c | 6 ++
4 files changed, 56 insertions(+), 50 deletions(-)
diff --git a/target/riscv/insn_trans/trans_rvbf16.c.inc b/target/riscv/insn_trans/trans_rvbf16.c.inc
index 8ee99df3f3..96e3e73530 100644
--- a/target/riscv/insn_trans/trans_rvbf16.c.inc
+++ b/target/riscv/insn_trans/trans_rvbf16.c.inc
@@ -86,7 +86,7 @@ static bool trans_vfncvtbf16_f_f_w(DisasContext *ctx, arg_vfncvtbf16_f_f_w *a)
ctx->cfg_ptr->vlenb,
ctx->cfg_ptr->vlenb, data,
gen_helper_vfncvtbf16_f_f_w);
- mark_vs_dirty(ctx);
+ finalize_rvv_inst(ctx);
gen_set_label(over);
return true;
}
@@ -115,7 +115,7 @@ static bool trans_vfwcvtbf16_f_f_v(DisasContext *ctx, arg_vfwcvtbf16_f_f_v *a)
ctx->cfg_ptr->vlenb,
ctx->cfg_ptr->vlenb, data,
gen_helper_vfwcvtbf16_f_f_v);
- mark_vs_dirty(ctx);
+ finalize_rvv_inst(ctx);
gen_set_label(over);
return true;
}
@@ -146,7 +146,7 @@ static bool trans_vfwmaccbf16_vv(DisasContext *ctx, arg_vfwmaccbf16_vv *a)
ctx->cfg_ptr->vlenb,
ctx->cfg_ptr->vlenb, data,
gen_helper_vfwmaccbf16_vv);
- mark_vs_dirty(ctx);
+ finalize_rvv_inst(ctx);
gen_set_label(over);
return true;
}
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
index 5436d9e3ef..bf8ec82a70 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -167,7 +167,7 @@ static bool do_vsetvl(DisasContext *s, int rd, int rs1, TCGv s2)
gen_helper_vsetvl(dst, tcg_env, s1, s2);
gen_set_gpr(s, rd, dst);
- mark_vs_dirty(s);
+ finalize_rvv_inst(s);
gen_update_pc(s, s->cur_insn_len);
lookup_and_goto_ptr(s);
@@ -187,7 +187,7 @@ static bool do_vsetivli(DisasContext *s, int rd, TCGv s1, TCGv s2)
gen_helper_vsetvl(dst, tcg_env, s1, s2);
gen_set_gpr(s, rd, dst);
- mark_vs_dirty(s);
+ finalize_rvv_inst(s);
gen_update_pc(s, s->cur_insn_len);
lookup_and_goto_ptr(s);
s->base.is_jmp = DISAS_NORETURN;
@@ -639,7 +639,7 @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
fn(dest, mask, base, tcg_env, desc);
- mark_vs_dirty(s);
+ finalize_rvv_inst(s);
return true;
}
@@ -797,7 +797,7 @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
fn(dest, mask, base, stride, tcg_env, desc);
- mark_vs_dirty(s);
+ finalize_rvv_inst(s);
return true;
}
@@ -901,7 +901,7 @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
fn(dest, mask, base, index, tcg_env, desc);
- mark_vs_dirty(s);
+ finalize_rvv_inst(s);
return true;
}
@@ -1032,7 +1032,7 @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data,
fn(dest, mask, base, tcg_env, desc);
- mark_vs_dirty(s);
+ finalize_rvv_inst(s);
return true;
}
@@ -1091,7 +1091,7 @@ static bool ldst_whole_trans(uint32_t vd, uint32_t rs1, uint32_t nf,
fn(dest, base, tcg_env, desc);
- mark_vs_dirty(s);
+ finalize_rvv_inst(s);
return true;
}
@@ -1182,7 +1182,7 @@ do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn *gvec_fn,
tcg_env, s->cfg_ptr->vlenb,
s->cfg_ptr->vlenb, data, fn);
}
- mark_vs_dirty(s);
+ finalize_rvv_inst(s);
return true;
}
@@ -1233,7 +1233,7 @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
fn(dest, mask, src1, src2, tcg_env, desc);
- mark_vs_dirty(s);
+ finalize_rvv_inst(s);
return true;
}
@@ -1258,7 +1258,7 @@ do_opivx_gvec(DisasContext *s, arg_rmrr *a, GVecGen2sFn *gvec_fn,
gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
src1, MAXSZ(s), MAXSZ(s));
- mark_vs_dirty(s);
+ finalize_rvv_inst(s);
return true;
}
return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s);
@@ -1391,7 +1391,7 @@ static bool opivi_trans(uint32_t vd, uint32_t imm, uint32_t vs2, uint32_t vm,
fn(dest, mask, src1, src2, tcg_env, desc);
- mark_vs_dirty(s);
+ finalize_rvv_inst(s);
return true;
}
@@ -1405,7 +1405,7 @@ do_opivi_gvec(DisasContext *s, arg_rmrr *a, GVecGen2iFn *gvec_fn,
if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
extract_imm(s, a->rs1, imm_mode), MAXSZ(s), MAXSZ(s));
- mark_vs_dirty(s);
+ finalize_rvv_inst(s);
return true;
}
return opivi_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s, imm_mode);
@@ -1464,7 +1464,7 @@ static bool do_opivv_widen(DisasContext *s, arg_rmrr *a,
tcg_env, s->cfg_ptr->vlenb,
s->cfg_ptr->vlenb,
data, fn);
- mark_vs_dirty(s);
+ finalize_rvv_inst(s);
return true;
}
return false;
@@ -1536,7 +1536,7 @@ static bool do_opiwv_widen(DisasContext *s, arg_rmrr *a,
vreg_ofs(s, a->rs2),
tcg_env, s->cfg_ptr->vlenb,
s->cfg_ptr->vlenb, data, fn);
- mark_vs_dirty(s);
+ finalize_rvv_inst(s);
return true;
}
return false;
@@ -1604,7 +1604,7 @@ static bool opivv_trans(uint32_t vd, uint32_t vs1, uint32_t vs2, uint32_t vm,
tcg_gen_gvec_4_ptr(vreg_ofs(s, vd), vreg_ofs(s, 0), vreg_ofs(s, vs1),
vreg_ofs(s, vs2), tcg_env, s->cfg_ptr->vlenb,
s->cfg_ptr->vlenb, data, fn);
- mark_vs_dirty(s);
+ finalize_rvv_inst(s);
return true;
}
@@ -1737,7 +1737,7 @@ do_opivx_gvec_shift(DisasContext *s, arg_rmrr *a, GVecGen2sFn32 *gvec_fn,
gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
src1, MAXSZ(s), MAXSZ(s));
- mark_vs_dirty(s);
+ finalize_rvv_inst(s);
return true;
}
return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s);
@@ -1794,7 +1794,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
s->cfg_ptr->vlenb, \
s->cfg_ptr->vlenb, data, \
fns[s->sew]); \
- mark_vs_dirty(s); \
+ finalize_rvv_inst(s); \
return true; \
} \
return false; \
@@ -1997,7 +1997,7 @@ static bool trans_vmv_v_v(DisasContext *s, arg_vmv_v_v *a)
s->cfg_ptr->vlenb, data,
fns[s->sew]);
}
- mark_vs_dirty(s);
+ finalize_rvv_inst(s);
return true;
}
return false;
@@ -2042,7 +2042,7 @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
fns[s->sew](dest, s1_i64, tcg_env, desc);
}
- mark_vs_dirty(s);
+ finalize_rvv_inst(s);
return true;
}
return false;
@@ -2076,7 +2076,7 @@ static bool trans_vmv_v_i(DisasContext *s, arg_vmv_v_i *a)
tcg_gen_addi_ptr(dest, tcg_env, vreg_ofs(s, a->rd));
fns[s->sew](dest, s1, tcg_env, desc);
}
- mark_vs_dirty(s);
+ finalize_rvv_inst(s);
return true;
}
return false;
@@ -2224,7 +2224,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
s->cfg_ptr->vlenb, \
s->cfg_ptr->vlenb, data, \
fns[s->sew - 1]); \
- mark_vs_dirty(s); \
+ finalize_rvv_inst(s); \
return true; \
} \
return false; \
@@ -2258,7 +2258,7 @@ static bool opfvf_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
fn(dest, mask, t1, src2, tcg_env, desc);
- mark_vs_dirty(s);
+ finalize_rvv_inst(s);
return true;
}
@@ -2333,7 +2333,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
s->cfg_ptr->vlenb, \
s->cfg_ptr->vlenb, data, \
fns[s->sew - 1]); \
- mark_vs_dirty(s); \
+ finalize_rvv_inst(s); \
return true; \
} \
return false; \
@@ -2404,7 +2404,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
s->cfg_ptr->vlenb, \
s->cfg_ptr->vlenb, data, \
fns[s->sew - 1]); \
- mark_vs_dirty(s); \
+ finalize_rvv_inst(s); \
return true; \
} \
return false; \
@@ -2516,7 +2516,7 @@ static bool do_opfv(DisasContext *s, arg_rmr *a,
vreg_ofs(s, a->rs2), tcg_env,
s->cfg_ptr->vlenb,
s->cfg_ptr->vlenb, data, fn);
- mark_vs_dirty(s);
+ finalize_rvv_inst(s);
return true;
}
return false;
@@ -2626,7 +2626,7 @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
fns[s->sew - 1](dest, t1, tcg_env, desc);
}
- mark_vs_dirty(s);
+ finalize_rvv_inst(s);
return true;
}
return false;
@@ -2698,7 +2698,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
s->cfg_ptr->vlenb, \
s->cfg_ptr->vlenb, data, \
fns[s->sew - 1]); \
- mark_vs_dirty(s); \
+ finalize_rvv_inst(s); \
return true; \
} \
return false; \
@@ -2746,7 +2746,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
s->cfg_ptr->vlenb, \
s->cfg_ptr->vlenb, data, \
fns[s->sew]); \
- mark_vs_dirty(s); \
+ finalize_rvv_inst(s); \
return true; \
} \
return false; \
@@ -2810,7 +2810,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
s->cfg_ptr->vlenb, \
s->cfg_ptr->vlenb, data, \
fns[s->sew - 1]); \
- mark_vs_dirty(s); \
+ finalize_rvv_inst(s); \
return true; \
} \
return false; \
@@ -2856,7 +2856,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
s->cfg_ptr->vlenb, \
s->cfg_ptr->vlenb, data, \
fns[s->sew]); \
- mark_vs_dirty(s); \
+ finalize_rvv_inst(s); \
return true; \
} \
return false; \
@@ -2942,7 +2942,7 @@ static bool trans_##NAME(DisasContext *s, arg_r *a) \
vreg_ofs(s, a->rs2), tcg_env, \
s->cfg_ptr->vlenb, \
s->cfg_ptr->vlenb, data, fn); \
- mark_vs_dirty(s); \
+ finalize_rvv_inst(s); \
return true; \
} \
return false; \
@@ -3041,7 +3041,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
tcg_env, s->cfg_ptr->vlenb, \
s->cfg_ptr->vlenb, \
data, fn); \
- mark_vs_dirty(s); \
+ finalize_rvv_inst(s); \
return true; \
} \
return false; \
@@ -3080,7 +3080,7 @@ static bool trans_viota_m(DisasContext *s, arg_viota_m *a)
vreg_ofs(s, a->rs2), tcg_env,
s->cfg_ptr->vlenb,
s->cfg_ptr->vlenb, data, fns[s->sew]);
- mark_vs_dirty(s);
+ finalize_rvv_inst(s);
return true;
}
return false;
@@ -3107,7 +3107,7 @@ static bool trans_vid_v(DisasContext *s, arg_vid_v *a)
tcg_env, s->cfg_ptr->vlenb,
s->cfg_ptr->vlenb,
data, fns[s->sew]);
- mark_vs_dirty(s);
+ finalize_rvv_inst(s);
return true;
}
return false;
@@ -3286,7 +3286,7 @@ static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x *a)
s1 = get_gpr(s, a->rs1, EXT_NONE);
tcg_gen_ext_tl_i64(t1, s1);
vec_element_storei(s, a->rd, 0, t1);
- mark_vs_dirty(s);
+ finalize_rvv_inst(s);
return true;
}
return false;
@@ -3334,7 +3334,7 @@ static bool trans_vfmv_s_f(DisasContext *s, arg_vfmv_s_f *a)
do_nanbox(s, t1, cpu_fpr[a->rs1]);
vec_element_storei(s, a->rd, 0, t1);
- mark_vs_dirty(s);
+ finalize_rvv_inst(s);
return true;
}
return false;
@@ -3440,7 +3440,7 @@ static bool trans_vrgather_vx(DisasContext *s, arg_rmrr *a)
tcg_gen_gvec_dup_i64(s->sew, vreg_ofs(s, a->rd),
MAXSZ(s), MAXSZ(s), dest);
- mark_vs_dirty(s);
+ finalize_rvv_inst(s);
} else {
static gen_helper_opivx * const fns[4] = {
gen_helper_vrgather_vx_b, gen_helper_vrgather_vx_h,
@@ -3468,7 +3468,7 @@ static bool trans_vrgather_vi(DisasContext *s, arg_rmrr *a)
endian_ofs(s, a->rs2, a->rs1),
MAXSZ(s), MAXSZ(s));
}
- mark_vs_dirty(s);
+ finalize_rvv_inst(s);
} else {
static gen_helper_opivx * const fns[4] = {
gen_helper_vrgather_vx_b, gen_helper_vrgather_vx_h,
@@ -3513,7 +3513,7 @@ static bool trans_vcompress_vm(DisasContext *s, arg_r *a)
tcg_env, s->cfg_ptr->vlenb,
s->cfg_ptr->vlenb, data,
fns[s->sew]);
- mark_vs_dirty(s);
+ finalize_rvv_inst(s);
return true;
}
return false;
@@ -3538,7 +3538,7 @@ static bool trans_##NAME(DisasContext *s, arg_##NAME * a) \
tcg_gen_gvec_2_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2), \
tcg_env, maxsz, maxsz, 0, gen_helper_vmvr_v); \
} \
- mark_vs_dirty(s); \
+ finalize_rvv_inst(s); \
return true; \
} \
return false; \
@@ -3609,7 +3609,7 @@ static bool int_ext_op(DisasContext *s, arg_rmr *a, uint8_t seq)
s->cfg_ptr->vlenb,
s->cfg_ptr->vlenb, data, fn);
- mark_vs_dirty(s);
+ finalize_rvv_inst(s);
return true;
}
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
index 6d640e4596..ae1f40174a 100644
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
@@ -174,7 +174,7 @@ GEN_OPIVX_GVEC_TRANS_CHECK(vandn_vx, andcs, zvkb_vx_check)
vreg_ofs(s, a->rs2), tcg_env, \
s->cfg_ptr->vlenb, s->cfg_ptr->vlenb, \
data, fns[s->sew]); \
- mark_vs_dirty(s); \
+ finalize_rvv_inst(s); \
return true; \
} \
return false; \
@@ -266,7 +266,7 @@ GEN_OPIVI_WIDEN_TRANS(vwsll_vi, IMM_ZX, vwsll_vx, vwsll_vx_check)
tcg_gen_addi_ptr(rd_v, tcg_env, vreg_ofs(s, a->rd)); \
tcg_gen_addi_ptr(rs2_v, tcg_env, vreg_ofs(s, a->rs2)); \
gen_helper_##NAME(rd_v, rs2_v, tcg_env, desc); \
- mark_vs_dirty(s); \
+ finalize_rvv_inst(s); \
return true; \
} \
return false; \
@@ -341,7 +341,7 @@ GEN_V_UNMASKED_TRANS(vaesem_vs, vaes_check_vs, ZVKNED_EGS)
tcg_gen_addi_ptr(rd_v, tcg_env, vreg_ofs(s, a->rd)); \
tcg_gen_addi_ptr(rs2_v, tcg_env, vreg_ofs(s, a->rs2)); \
gen_helper_##NAME(rd_v, rs2_v, uimm_v, tcg_env, desc); \
- mark_vs_dirty(s); \
+ finalize_rvv_inst(s); \
return true; \
} \
return false; \
@@ -405,7 +405,7 @@ GEN_VI_UNMASKED_TRANS(vaeskf2_vi, vaeskf2_check, ZVKNED_EGS)
s->cfg_ptr->vlenb, s->cfg_ptr->vlenb, \
data, gen_helper_##NAME); \
\
- mark_vs_dirty(s); \
+ finalize_rvv_inst(s); \
return true; \
} \
return false; \
@@ -457,7 +457,7 @@ static bool trans_vsha2cl_vv(DisasContext *s, arg_rmrr *a)
s->sew == MO_32 ?
gen_helper_vsha2cl32_vv : gen_helper_vsha2cl64_vv);
- mark_vs_dirty(s);
+ finalize_rvv_inst(s);
return true;
}
return false;
@@ -488,7 +488,7 @@ static bool trans_vsha2ch_vv(DisasContext *s, arg_rmrr *a)
s->sew == MO_32 ?
gen_helper_vsha2ch32_vv : gen_helper_vsha2ch64_vv);
- mark_vs_dirty(s);
+ finalize_rvv_inst(s);
return true;
}
return false;
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 177418b2b9..09efc5f93c 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -674,6 +674,12 @@ static void mark_vs_dirty(DisasContext *ctx)
static inline void mark_vs_dirty(DisasContext *ctx) { }
#endif
+static void finalize_rvv_inst(DisasContext *ctx)
+{
+ mark_vs_dirty(ctx);
+ ctx->vstart_eq_zero = true;
+}
+
static void gen_set_rm(DisasContext *ctx, int rm)
{
if (ctx->frm == rm) {
--
2.43.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v3 1/5] trans_rvv.c.inc: mark_vs_dirty() before stores
2024-02-20 19:26 ` [PATCH v3 1/5] trans_rvv.c.inc: mark_vs_dirty() before stores Daniel Henrique Barboza
@ 2024-02-20 20:17 ` Richard Henderson
2024-02-20 21:10 ` Daniel Henrique Barboza
0 siblings, 1 reply; 12+ messages in thread
From: Richard Henderson @ 2024-02-20 20:17 UTC (permalink / raw)
To: Daniel Henrique Barboza, qemu-devel
Cc: qemu-riscv, alistair.francis, bmeng, liwei1518, zhiwei_liu,
palmer, max.chou
On 2/20/24 09:26, Daniel Henrique Barboza wrote:
> While discussing a problem with how we're (not) setting vstart_eq_zero
> Richard had the following to say w.r.t the conditional mark_vs_dirty()
> calls on load/store functions [1]:
>
> "I think it's required to have stores set dirty unconditionally, before
> the operation.
>
> Consider a store that traps on the 2nd element, leaving vstart = 2, and
> exiting to the main loop via exception. The exception enters the kernel
> page fault handler. The kernel may need to fault in the page for the
> process, and in the meantime task switch.
>
> If vs dirty is not already set, the kernel won't know to save vector
> state on task switch."
>
> Do a mark_vs_dirty() before store operations. Keep the mark_vs_dirty()
> call at the end for loads - the function is a no-op if mstatus_vs is
> already set to EXT_STATUS_DIRTY so there's no hurt in store functions
> calling it twice.
>
> [1] https://lore.kernel.org/qemu-riscv/72c7503b-0f43-44b8-aa82-fbafed2aac0c@linaro.org/
>
> Suggested-by: Richard Henderson <richard.henderson@linaro.org>
> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> ---
> target/riscv/insn_trans/trans_rvv.c.inc | 29 +++++++++++++++----------
> 1 file changed, 17 insertions(+), 12 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
> index 9e101ab434..2065e9064e 100644
> --- a/target/riscv/insn_trans/trans_rvv.c.inc
> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
> @@ -636,12 +636,13 @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
> tcg_gen_addi_ptr(dest, tcg_env, vreg_ofs(s, vd));
> tcg_gen_addi_ptr(mask, tcg_env, vreg_ofs(s, 0));
>
> - fn(dest, mask, base, tcg_env, desc);
> -
> - if (!is_store) {
> + if (is_store) {
> mark_vs_dirty(s);
> }
>
> + fn(dest, mask, base, tcg_env, desc);
> +
> + mark_vs_dirty(s);
You misunderstood here, I think.
Both loads and stores need to set dirty early, before any exit via exception path.
I see that I did say only stores in the quoted mail, but I believe that was merely in
reference to stores not setting dirty *at all* beforehand.
r~
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3 2/5] target/riscv: remove 'over' brconds from vector trans
2024-02-20 19:26 ` [PATCH v3 2/5] target/riscv: remove 'over' brconds from vector trans Daniel Henrique Barboza
@ 2024-02-20 20:19 ` Richard Henderson
0 siblings, 0 replies; 12+ messages in thread
From: Richard Henderson @ 2024-02-20 20:19 UTC (permalink / raw)
To: Daniel Henrique Barboza, qemu-devel
Cc: qemu-riscv, alistair.francis, bmeng, liwei1518, zhiwei_liu,
palmer, max.chou
On 2/20/24 09:26, Daniel Henrique Barboza wrote:
> Most of the vector translations has this following pattern at the start:
>
> TCGLabel *over = gen_new_label();
> tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
>
> And then right at the end:
>
> gen_set_label(over);
> return true;
>
> This means that if vstart >= vl we'll not set vstart = 0 at the end of
> the insns - this is done inside the helper that is being skipped. The
> reason why this pattern hasn't been a bigger problem is because the
> conditional vstart >= vl is very rare.
>
> Checking all the helpers in vector_helper.c we see all of them with a
> pattern like this:
>
> for (i = env->vstart; i < vl; i++) {
> (...)
> }
> env->vstart = 0;
>
> Thus they can handle vstart >= vl case gracefully, with the benefit of
> setting env->vstart = 0 during the process.
>
> Remove all 'over' conditionals and let the helper set env->vstart = 0
> every time.
>
> Suggested-by: Richard Henderson<richard.henderson@linaro.org>
> Signed-off-by: Daniel Henrique Barboza<dbarboza@ventanamicro.com>
> ---
> target/riscv/insn_trans/trans_rvv.c.inc | 116 -----------------------
> target/riscv/insn_trans/trans_rvvk.c.inc | 18 ----
> 2 files changed, 134 deletions(-)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3 3/5] target/riscv/vector_helper.c: set vstart = 0 in GEN_VEXT_VSLIDEUP_VX()
2024-02-20 19:26 ` [PATCH v3 3/5] target/riscv/vector_helper.c: set vstart = 0 in GEN_VEXT_VSLIDEUP_VX() Daniel Henrique Barboza
@ 2024-02-20 20:20 ` Richard Henderson
0 siblings, 0 replies; 12+ messages in thread
From: Richard Henderson @ 2024-02-20 20:20 UTC (permalink / raw)
To: Daniel Henrique Barboza, qemu-devel
Cc: qemu-riscv, alistair.francis, bmeng, liwei1518, zhiwei_liu,
palmer, max.chou
On 2/20/24 09:26, Daniel Henrique Barboza wrote:
> The helper isn't setting env->vstart = 0 after its execution, as it is
> expected from every vector instruction that completes successfully.
>
> Signed-off-by: Daniel Henrique Barboza<dbarboza@ventanamicro.com>
> ---
> target/riscv/vector_helper.c | 1 +
> 1 file changed, 1 insertion(+)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3 4/5] trans_rvv.c.inc: remove redundant mark_vs_dirty() calls
2024-02-20 19:26 ` [PATCH v3 4/5] trans_rvv.c.inc: remove redundant mark_vs_dirty() calls Daniel Henrique Barboza
@ 2024-02-20 20:20 ` Richard Henderson
0 siblings, 0 replies; 12+ messages in thread
From: Richard Henderson @ 2024-02-20 20:20 UTC (permalink / raw)
To: Daniel Henrique Barboza, qemu-devel
Cc: qemu-riscv, alistair.francis, bmeng, liwei1518, zhiwei_liu,
palmer, max.chou
On 2/20/24 09:26, Daniel Henrique Barboza wrote:
> trans_vmv_v_i , trans_vfmv_v_f and the trans_##NAME macro from
> GEN_VMV_WHOLE_TRANS() are calling mark_vs_dirty() in both branches of
> their 'ifs'. conditionals.
>
> Call it just once in the end like other functions are doing.
>
> Signed-off-by: Daniel Henrique Barboza<dbarboza@ventanamicro.com>
> ---
> target/riscv/insn_trans/trans_rvv.c.inc | 11 +++--------
> 1 file changed, 3 insertions(+), 8 deletions(-)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3 5/5] target/riscv: Clear vstart_qe_zero flag
2024-02-20 19:26 ` [PATCH v3 5/5] target/riscv: Clear vstart_qe_zero flag Daniel Henrique Barboza
@ 2024-02-20 20:22 ` Richard Henderson
0 siblings, 0 replies; 12+ messages in thread
From: Richard Henderson @ 2024-02-20 20:22 UTC (permalink / raw)
To: Daniel Henrique Barboza, qemu-devel
Cc: qemu-riscv, alistair.francis, bmeng, liwei1518, zhiwei_liu,
palmer, max.chou, Ivan Klokov
On 2/20/24 09:26, Daniel Henrique Barboza wrote:
> From: Ivan Klokov <ivan.klokov@syntacore.com>
>
> The vstart_qe_zero flag is set at the beginning of the translation
> phase from the env->vstart variable. During the execution phase, some
> instructions may change env->vstart, but the flag remains the same as
> at the start of the block. With some combinations of instructions this
> causes an illegal instruction exception. This patch simultaneously
> updates flag and env->vstart and to avoid inconsistency.
It does not update env->vstart. With the commit message fixed,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3 1/5] trans_rvv.c.inc: mark_vs_dirty() before stores
2024-02-20 20:17 ` Richard Henderson
@ 2024-02-20 21:10 ` Daniel Henrique Barboza
0 siblings, 0 replies; 12+ messages in thread
From: Daniel Henrique Barboza @ 2024-02-20 21:10 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
Cc: qemu-riscv, alistair.francis, bmeng, liwei1518, zhiwei_liu,
palmer, max.chou
On 2/20/24 17:17, Richard Henderson wrote:
> On 2/20/24 09:26, Daniel Henrique Barboza wrote:
>> While discussing a problem with how we're (not) setting vstart_eq_zero
>> Richard had the following to say w.r.t the conditional mark_vs_dirty()
>> calls on load/store functions [1]:
>>
>> "I think it's required to have stores set dirty unconditionally, before
>> the operation.
>>
>> Consider a store that traps on the 2nd element, leaving vstart = 2, and
>> exiting to the main loop via exception. The exception enters the kernel
>> page fault handler. The kernel may need to fault in the page for the
>> process, and in the meantime task switch.
>>
>> If vs dirty is not already set, the kernel won't know to save vector
>> state on task switch."
>>
>> Do a mark_vs_dirty() before store operations. Keep the mark_vs_dirty()
>> call at the end for loads - the function is a no-op if mstatus_vs is
>> already set to EXT_STATUS_DIRTY so there's no hurt in store functions
>> calling it twice.
>>
>> [1] https://lore.kernel.org/qemu-riscv/72c7503b-0f43-44b8-aa82-fbafed2aac0c@linaro.org/
>>
>> Suggested-by: Richard Henderson <richard.henderson@linaro.org>
>> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
>> ---
>> target/riscv/insn_trans/trans_rvv.c.inc | 29 +++++++++++++++----------
>> 1 file changed, 17 insertions(+), 12 deletions(-)
>>
>> diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
>> index 9e101ab434..2065e9064e 100644
>> --- a/target/riscv/insn_trans/trans_rvv.c.inc
>> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
>> @@ -636,12 +636,13 @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
>> tcg_gen_addi_ptr(dest, tcg_env, vreg_ofs(s, vd));
>> tcg_gen_addi_ptr(mask, tcg_env, vreg_ofs(s, 0));
>> - fn(dest, mask, base, tcg_env, desc);
>> -
>> - if (!is_store) {
>> + if (is_store) {
>> mark_vs_dirty(s);
>> }
>> + fn(dest, mask, base, tcg_env, desc);
>> +
>> + mark_vs_dirty(s);
>
> You misunderstood here, I think.
> Both loads and stores need to set dirty early, before any exit via exception path.
>
> I see that I did say only stores in the quoted mail, but I believe that was merely in reference to stores not setting dirty *at all* beforehand.
hmmm it made sense when I read your reply to set just for stores because I thought
that loads wouldn't trigger page context switches in the kernel. TBH I got too
caught up by the existing "if (!is_store)" in the code, trying to figure it out
why it was there.
In another read in the spec there's nothing that indicates that stores needs
additional handling, which means that we can treat both equally in this regard.
I'll change it for v4. Thanks,
Daniel
>
>
> r~
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2024-02-20 21:11 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-02-20 19:26 [PATCH v3 0/5] riscv: set vstart_eq_zero on mark_vs_dirty Daniel Henrique Barboza
2024-02-20 19:26 ` [PATCH v3 1/5] trans_rvv.c.inc: mark_vs_dirty() before stores Daniel Henrique Barboza
2024-02-20 20:17 ` Richard Henderson
2024-02-20 21:10 ` Daniel Henrique Barboza
2024-02-20 19:26 ` [PATCH v3 2/5] target/riscv: remove 'over' brconds from vector trans Daniel Henrique Barboza
2024-02-20 20:19 ` Richard Henderson
2024-02-20 19:26 ` [PATCH v3 3/5] target/riscv/vector_helper.c: set vstart = 0 in GEN_VEXT_VSLIDEUP_VX() Daniel Henrique Barboza
2024-02-20 20:20 ` Richard Henderson
2024-02-20 19:26 ` [PATCH v3 4/5] trans_rvv.c.inc: remove redundant mark_vs_dirty() calls Daniel Henrique Barboza
2024-02-20 20:20 ` Richard Henderson
2024-02-20 19:26 ` [PATCH v3 5/5] target/riscv: Clear vstart_qe_zero flag Daniel Henrique Barboza
2024-02-20 20:22 ` Richard Henderson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).