Handle the FPCR.AH "don't negate the sign of a NaN" semantics in FMLS (indexed), by passing through FPCR.AH in the SIMD data word, for the helper to use to determine whether to negate.
Signed-off-by: Peter Maydell <peter.mayd...@linaro.org> --- target/arm/tcg/translate-a64.c | 2 +- target/arm/tcg/translate-sve.c | 2 +- target/arm/tcg/vec_helper.c | 9 +++++++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c index 3fe8e041093..c688275106f 100644 --- a/target/arm/tcg/translate-a64.c +++ b/target/arm/tcg/translate-a64.c @@ -6751,7 +6751,7 @@ 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, esz == MO_16 ? FPST_FPCR_F16_A64 : FPST_FPCR_A64, - (a->idx << 1) | neg, + (s->fpcr_ah << 5) | (a->idx << 1) | neg, fns[esz - 1]); return true; } diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c index eef3623fd3a..a7033fe93ab 100644 --- a/target/arm/tcg/translate-sve.c +++ b/target/arm/tcg/translate-sve.c @@ -3533,7 +3533,7 @@ static bool do_FMLA_zzxz(DisasContext *s, arg_rrxr_esz *a, bool sub) gen_helper_gvec_fmla_idx_d, }; return gen_gvec_fpst_zzzz(s, fns[a->esz], a->rd, a->rn, a->rm, a->ra, - (a->index << 1) | sub, + (s->fpcr_ah << 5) | (a->index << 1) | sub, a->esz == MO_16 ? FPST_FPCR_F16_A64 : FPST_FPCR_A64); } diff --git a/target/arm/tcg/vec_helper.c b/target/arm/tcg/vec_helper.c index bf6f6a97636..5e9663382a9 100644 --- a/target/arm/tcg/vec_helper.c +++ b/target/arm/tcg/vec_helper.c @@ -1708,13 +1708,18 @@ void HELPER(NAME)(void *vd, void *vn, void *vm, void *va, \ intptr_t i, j, oprsz = simd_oprsz(desc); \ intptr_t segment = MIN(16, oprsz) / sizeof(TYPE); \ TYPE op1_neg = extract32(desc, SIMD_DATA_SHIFT, 1); \ - intptr_t idx = desc >> (SIMD_DATA_SHIFT + 1); \ + intptr_t idx = extract32(desc, SIMD_DATA_SHIFT + 1, 3); \ + bool fpcr_ah = extract32(desc, SIMD_DATA_SHIFT + 5, 1); \ TYPE *d = vd, *n = vn, *m = vm, *a = va; \ op1_neg <<= (8 * sizeof(TYPE) - 1); \ for (i = 0; i < oprsz / sizeof(TYPE); i += segment) { \ TYPE mm = m[H(i + idx)]; \ for (j = 0; j < segment; j++) { \ - d[i + j] = TYPE##_muladd(n[i + j] ^ op1_neg, \ + TYPE nval = n[i + j]; \ + if (!(fpcr_ah && TYPE ## _is_any_nan(nval))) { \ + nval ^= op1_neg; \ + } \ + d[i + j] = TYPE##_muladd(nval, \ mm, a[i + j], 0, stat); \ } \ } \ -- 2.34.1