@@ -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;
}
@@ -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);
}
@@ -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); \
} \
} \
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.maydell@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(-)