[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 67/76] target/arm: Handle FPCR.AH in SVE FTMAD
From: |
Peter Maydell |
Subject: |
[PATCH 67/76] target/arm: Handle FPCR.AH in SVE FTMAD |
Date: |
Fri, 24 Jan 2025 16:28:27 +0000 |
The negation step in the SVE FTMAD insn mustn't negate a NaN when
FPCR.AH is set. Pass FPCR.AH to the helper via the SIMD data field
and use that to determine whether to do the negation.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/tcg/sve_helper.c | 21 +++++++++++++++------
target/arm/tcg/translate-sve.c | 3 ++-
2 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/target/arm/tcg/sve_helper.c b/target/arm/tcg/sve_helper.c
index a39a3ed0cf9..3f38e078291 100644
--- a/target/arm/tcg/sve_helper.c
+++ b/target/arm/tcg/sve_helper.c
@@ -5143,13 +5143,16 @@ void HELPER(sve_ftmad_h)(void *vd, void *vn, void *vm,
0x3c00, 0xb800, 0x293a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
};
intptr_t i, opr_sz = simd_oprsz(desc) / sizeof(float16);
- intptr_t x = simd_data(desc);
+ intptr_t x = extract32(desc, SIMD_DATA_SHIFT, 3);
+ bool fpcr_ah = extract32(desc, SIMD_DATA_SHIFT + 3, 1);
float16 *d = vd, *n = vn, *m = vm;
for (i = 0; i < opr_sz; i++) {
float16 mm = m[i];
intptr_t xx = x;
if (float16_is_neg(mm)) {
- mm = float16_abs(mm);
+ if (!(fpcr_ah && float16_is_any_nan(mm))) {
+ mm = float16_abs(mm);
+ }
xx += 8;
}
d[i] = float16_muladd(n[i], mm, coeff[xx], 0, s);
@@ -5166,13 +5169,16 @@ void HELPER(sve_ftmad_s)(void *vd, void *vn, void *vm,
0x37cd37cc, 0x00000000, 0x00000000, 0x00000000,
};
intptr_t i, opr_sz = simd_oprsz(desc) / sizeof(float32);
- intptr_t x = simd_data(desc);
+ intptr_t x = extract32(desc, SIMD_DATA_SHIFT, 3);
+ bool fpcr_ah = extract32(desc, SIMD_DATA_SHIFT + 3, 1);
float32 *d = vd, *n = vn, *m = vm;
for (i = 0; i < opr_sz; i++) {
float32 mm = m[i];
intptr_t xx = x;
if (float32_is_neg(mm)) {
- mm = float32_abs(mm);
+ if (!(fpcr_ah && float32_is_any_nan(mm))) {
+ mm = float32_abs(mm);
+ }
xx += 8;
}
d[i] = float32_muladd(n[i], mm, coeff[xx], 0, s);
@@ -5193,13 +5199,16 @@ void HELPER(sve_ftmad_d)(void *vd, void *vn, void *vm,
0x3e21ee96d2641b13ull, 0xbda8f76380fbb401ull,
};
intptr_t i, opr_sz = simd_oprsz(desc) / sizeof(float64);
- intptr_t x = simd_data(desc);
+ intptr_t x = extract32(desc, SIMD_DATA_SHIFT, 3);
+ bool fpcr_ah = extract32(desc, SIMD_DATA_SHIFT + 3, 1);
float64 *d = vd, *n = vn, *m = vm;
for (i = 0; i < opr_sz; i++) {
float64 mm = m[i];
intptr_t xx = x;
if (float64_is_neg(mm)) {
- mm = float64_abs(mm);
+ if (!(fpcr_ah && float64_is_any_nan(mm))) {
+ mm = float64_abs(mm);
+ }
xx += 8;
}
d[i] = float64_muladd(n[i], mm, coeff[xx], 0, s);
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
index 2d70b0faad2..26bdda8f96e 100644
--- a/target/arm/tcg/translate-sve.c
+++ b/target/arm/tcg/translate-sve.c
@@ -3682,7 +3682,8 @@ static gen_helper_gvec_3_ptr * const ftmad_fns[4] = {
gen_helper_sve_ftmad_s, gen_helper_sve_ftmad_d,
};
TRANS_FEAT_NONSTREAMING(FTMAD, aa64_sve, gen_gvec_fpst_zzz,
- ftmad_fns[a->esz], a->rd, a->rn, a->rm, a->imm,
+ ftmad_fns[a->esz], a->rd, a->rn, a->rm,
+ a->imm | (s->fpcr_ah << 3),
a->esz == MO_16 ? FPST_FPCR_F16_A64 : FPST_FPCR_A64)
/*
--
2.34.1
- [PATCH 50/76] target/arm: Implement FPCR.AH semantics for SVE FMIN/FMAX immediate, (continued)
- [PATCH 50/76] target/arm: Implement FPCR.AH semantics for SVE FMIN/FMAX immediate, Peter Maydell, 2025/01/24
- [PATCH 55/76] target/arm: Handle FPCR.AH in SVE FNEG, Peter Maydell, 2025/01/24
- [PATCH 11/76] target/arm: Use FPST_FPCR_A64 in A64 decoder, Peter Maydell, 2025/01/24
- [PATCH 26/76] target/arm: Use FPST_FPCR_F16_A64 for halfprec-to-other conversions, Peter Maydell, 2025/01/24
- [PATCH 46/76] target/arm: Implement FPCR.AH semantics for vector FMIN/FMAX, Peter Maydell, 2025/01/24
- [PATCH 67/76] target/arm: Handle FPCR.AH in SVE FTMAD,
Peter Maydell <=
- [PATCH 70/76] target/arm: Implement increased precision FRECPE, Peter Maydell, 2025/01/24
- [PATCH 66/76] target/arm: Handle FPCR.AH in SVE FTSSEL, Peter Maydell, 2025/01/24
- [PATCH 34/76] target/arm: Use FPST_FPCR_AH for BFCVT* insns, Peter Maydell, 2025/01/24
- [PATCH 37/76] target/arm: Define and use new write_fp_*reg_merging() functions, Peter Maydell, 2025/01/24
- [PATCH 62/76] target/arm: Handle FPCR.AH in FRECPS and FRSQRTS vector insns, Peter Maydell, 2025/01/24