mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 00:03:54 -06:00
target/riscv: Introduce helper_set_rounding_mode_chkfrm
The new helper always validates the contents of FRM, even
if the new rounding mode is not DYN. This is required by
the vector unit.
Track whether we've validated FRM separately from whether
we've updated fp_status with a given rounding mode, so that
we can elide calls correctly.
This partially reverts d6c4d3f2a6
which attempted the to do
the same thing, but with two calls to gen_set_rm(), which is
both inefficient and tickles an assertion in decode_save_opc.
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1441
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Message-Id: <20230115160657.3169274-2-richard.henderson@linaro.org>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
parent
9d9db41373
commit
3ceeb19a53
4 changed files with 61 additions and 20 deletions
|
@ -2679,13 +2679,9 @@ static bool do_opfv(DisasContext *s, arg_rmr *a,
|
|||
int rm)
|
||||
{
|
||||
if (checkfn(s, a)) {
|
||||
if (rm != RISCV_FRM_DYN) {
|
||||
gen_set_rm(s, RISCV_FRM_DYN);
|
||||
}
|
||||
|
||||
uint32_t data = 0;
|
||||
TCGLabel *over = gen_new_label();
|
||||
gen_set_rm(s, rm);
|
||||
gen_set_rm_chkfrm(s, rm);
|
||||
tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
|
||||
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
|
||||
|
||||
|
@ -2882,17 +2878,13 @@ static bool opffv_widen_check(DisasContext *s, arg_rmr *a)
|
|||
static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
|
||||
{ \
|
||||
if (CHECK(s, a)) { \
|
||||
if (FRM != RISCV_FRM_DYN) { \
|
||||
gen_set_rm(s, RISCV_FRM_DYN); \
|
||||
} \
|
||||
\
|
||||
uint32_t data = 0; \
|
||||
static gen_helper_gvec_3_ptr * const fns[2] = { \
|
||||
gen_helper_##HELPER##_h, \
|
||||
gen_helper_##HELPER##_w, \
|
||||
}; \
|
||||
TCGLabel *over = gen_new_label(); \
|
||||
gen_set_rm(s, FRM); \
|
||||
gen_set_rm_chkfrm(s, FRM); \
|
||||
tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
|
||||
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
|
||||
\
|
||||
|
@ -3005,17 +2997,13 @@ static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
|
|||
static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
|
||||
{ \
|
||||
if (CHECK(s, a)) { \
|
||||
if (FRM != RISCV_FRM_DYN) { \
|
||||
gen_set_rm(s, RISCV_FRM_DYN); \
|
||||
} \
|
||||
\
|
||||
uint32_t data = 0; \
|
||||
static gen_helper_gvec_3_ptr * const fns[2] = { \
|
||||
gen_helper_##HELPER##_h, \
|
||||
gen_helper_##HELPER##_w, \
|
||||
}; \
|
||||
TCGLabel *over = gen_new_label(); \
|
||||
gen_set_rm(s, FRM); \
|
||||
gen_set_rm_chkfrm(s, FRM); \
|
||||
tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
|
||||
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
|
||||
\
|
||||
|
@ -3060,10 +3048,6 @@ static bool opxfv_narrow_check(DisasContext *s, arg_rmr *a)
|
|||
static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
|
||||
{ \
|
||||
if (opxfv_narrow_check(s, a)) { \
|
||||
if (FRM != RISCV_FRM_DYN) { \
|
||||
gen_set_rm(s, RISCV_FRM_DYN); \
|
||||
} \
|
||||
\
|
||||
uint32_t data = 0; \
|
||||
static gen_helper_gvec_3_ptr * const fns[3] = { \
|
||||
gen_helper_##HELPER##_b, \
|
||||
|
@ -3071,7 +3055,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
|
|||
gen_helper_##HELPER##_w, \
|
||||
}; \
|
||||
TCGLabel *over = gen_new_label(); \
|
||||
gen_set_rm(s, FRM); \
|
||||
gen_set_rm_chkfrm(s, FRM); \
|
||||
tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
|
||||
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
|
||||
\
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue