target/arm: Use FPST_FPCR_AH for BFMLAL*, BFMLSL* insns

When FPCR.AH is 1, use FPST_FPCR_AH for:
 * AdvSIMD BFMLALB, BFMLALT
 * SVE BFMLALB, BFMLALT, BFMLSLB, BFMLSLT

so that they get the required behaviour changes.

We do this by making gen_gvec_op4_fpst() take an ARMFPStatusFlavour
rather than a bool is_fp16; existing callsites now select
FPST_FPCR_F16_A64 vs FPST_FPCR_A64 themselves rather than passing in
the boolean.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Peter Maydell 2025-02-01 16:39:17 +00:00
parent b6295046e6
commit 8a5a2b943e
2 changed files with 17 additions and 9 deletions

View File

@ -754,10 +754,11 @@ static void gen_gvec_op4_env(DisasContext *s, bool is_q, int rd, int rn,
* an out-of-line helper. * an out-of-line helper.
*/ */
static void gen_gvec_op4_fpst(DisasContext *s, bool is_q, int rd, int rn, static void gen_gvec_op4_fpst(DisasContext *s, bool is_q, int rd, int rn,
int rm, int ra, bool is_fp16, int data, int rm, int ra, ARMFPStatusFlavour fpsttype,
int data,
gen_helper_gvec_4_ptr *fn) gen_helper_gvec_4_ptr *fn)
{ {
TCGv_ptr fpst = fpstatus_ptr(is_fp16 ? FPST_A64_F16 : FPST_A64); TCGv_ptr fpst = fpstatus_ptr(fpsttype);
tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, rd), tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, rd),
vec_full_reg_offset(s, rn), vec_full_reg_offset(s, rn),
vec_full_reg_offset(s, rm), vec_full_reg_offset(s, rm),
@ -5826,7 +5827,8 @@ static bool trans_BFMLAL_v(DisasContext *s, arg_qrrr_e *a)
} }
if (fp_access_check(s)) { if (fp_access_check(s)) {
/* Q bit selects BFMLALB vs BFMLALT. */ /* Q bit selects BFMLALB vs BFMLALT. */
gen_gvec_op4_fpst(s, true, a->rd, a->rn, a->rm, a->rd, false, a->q, gen_gvec_op4_fpst(s, true, a->rd, a->rn, a->rm, a->rd,
s->fpcr_ah ? FPST_AH : FPST_A64, a->q,
gen_helper_gvec_bfmlal); gen_helper_gvec_bfmlal);
} }
return true; return true;
@ -5859,7 +5861,8 @@ static bool trans_FCMLA_v(DisasContext *s, arg_FCMLA_v *a)
} }
gen_gvec_op4_fpst(s, a->q, a->rd, a->rn, a->rm, a->rd, gen_gvec_op4_fpst(s, a->q, a->rd, a->rn, a->rm, a->rd,
a->esz == MO_16, a->rot, fn[a->esz]); a->esz == MO_16 ? FPST_A64_F16 : FPST_A64,
a->rot, fn[a->esz]);
return true; return true;
} }
@ -6439,7 +6442,8 @@ static bool do_fmla_vector_idx(DisasContext *s, arg_qrrx_e *a, bool neg)
} }
gen_gvec_op4_fpst(s, a->q, a->rd, a->rn, a->rm, a->rd, gen_gvec_op4_fpst(s, a->q, a->rd, a->rn, a->rm, a->rd,
esz == MO_16, (a->idx << 1) | neg, esz == MO_16 ? FPST_A64_F16 : FPST_A64,
(a->idx << 1) | neg,
fns[esz - 1]); fns[esz - 1]);
return true; return true;
} }
@ -6574,7 +6578,8 @@ static bool trans_BFMLAL_vi(DisasContext *s, arg_qrrx_e *a)
} }
if (fp_access_check(s)) { if (fp_access_check(s)) {
/* Q bit selects BFMLALB vs BFMLALT. */ /* Q bit selects BFMLALB vs BFMLALT. */
gen_gvec_op4_fpst(s, true, a->rd, a->rn, a->rm, a->rd, 0, gen_gvec_op4_fpst(s, true, a->rd, a->rn, a->rm, a->rd,
s->fpcr_ah ? FPST_AH : FPST_A64,
(a->idx << 1) | a->q, (a->idx << 1) | a->q,
gen_helper_gvec_bfmlal_idx); gen_helper_gvec_bfmlal_idx);
} }
@ -6603,7 +6608,8 @@ static bool trans_FCMLA_vi(DisasContext *s, arg_FCMLA_vi *a)
} }
if (fp_access_check(s)) { if (fp_access_check(s)) {
gen_gvec_op4_fpst(s, a->q, a->rd, a->rn, a->rm, a->rd, gen_gvec_op4_fpst(s, a->q, a->rd, a->rn, a->rm, a->rd,
a->esz == MO_16, (a->idx << 2) | a->rot, fn); a->esz == MO_16 ? FPST_A64_F16 : FPST_A64,
(a->idx << 2) | a->rot, fn);
} }
return true; return true;
} }

View File

@ -7117,7 +7117,8 @@ TRANS_FEAT_NONSTREAMING(BFMMLA, aa64_sve_bf16, gen_gvec_env_arg_zzzz,
static bool do_BFMLAL_zzzw(DisasContext *s, arg_rrrr_esz *a, bool sel) static bool do_BFMLAL_zzzw(DisasContext *s, arg_rrrr_esz *a, bool sel)
{ {
return gen_gvec_fpst_zzzz(s, gen_helper_gvec_bfmlal, return gen_gvec_fpst_zzzz(s, gen_helper_gvec_bfmlal,
a->rd, a->rn, a->rm, a->ra, sel, FPST_A64); a->rd, a->rn, a->rm, a->ra, sel,
s->fpcr_ah ? FPST_AH : FPST_A64);
} }
TRANS_FEAT(BFMLALB_zzzw, aa64_sve_bf16, do_BFMLAL_zzzw, a, false) TRANS_FEAT(BFMLALB_zzzw, aa64_sve_bf16, do_BFMLAL_zzzw, a, false)
@ -7127,7 +7128,8 @@ static bool do_BFMLAL_zzxw(DisasContext *s, arg_rrxr_esz *a, bool sel)
{ {
return gen_gvec_fpst_zzzz(s, gen_helper_gvec_bfmlal_idx, return gen_gvec_fpst_zzzz(s, gen_helper_gvec_bfmlal_idx,
a->rd, a->rn, a->rm, a->ra, a->rd, a->rn, a->rm, a->ra,
(a->index << 1) | sel, FPST_A64); (a->index << 1) | sel,
s->fpcr_ah ? FPST_AH : FPST_A64);
} }
TRANS_FEAT(BFMLALB_zzxw, aa64_sve_bf16, do_BFMLAL_zzxw, a, false) TRANS_FEAT(BFMLALB_zzxw, aa64_sve_bf16, do_BFMLAL_zzxw, a, false)