diff mbox series

[v2,23/34] target/arm: Use flags for AH negation in sve_ftmad_*

Message ID 20250129013857.135256-24-richard.henderson@linaro.org
State New
Headers show
Series target/arm: FEAT_AFP followups for FEAT_SME2 | expand

Commit Message

Richard Henderson Jan. 29, 2025, 1:38 a.m. UTC
Because the operand is known to be negative, negating the operand
is the same as taking the absolute value.  Defer this to the muladd
operation via flags, so that it happens after NaN detection, which
is correct for FPCR.AH.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/tcg/sve_helper.c | 27 +++++++++++++++++++++------
 1 file changed, 21 insertions(+), 6 deletions(-)
diff mbox series

Patch

diff --git a/target/arm/tcg/sve_helper.c b/target/arm/tcg/sve_helper.c
index a01613f079..c12b2600bd 100644
--- a/target/arm/tcg/sve_helper.c
+++ b/target/arm/tcg/sve_helper.c
@@ -5137,16 +5137,21 @@  void HELPER(sve_ftmad_h)(void *vd, void *vn, void *vm,
     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;
+        int flags = 0;
+
         if (float16_is_neg(mm)) {
-            if (!(fpcr_ah && float16_is_any_nan(mm))) {
+            if (fpcr_ah) {
+                flags = float_muladd_negate_product;
+            } else {
                 mm = float16_abs(mm);
             }
             xx += 8;
         }
-        d[i] = float16_muladd(n[i], mm, coeff[xx], 0, s);
+        d[i] = float16_muladd(n[i], mm, coeff[xx], flags, s);
     }
 }
 
@@ -5163,16 +5168,21 @@  void HELPER(sve_ftmad_s)(void *vd, void *vn, void *vm,
     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;
+        int flags = 0;
+
         if (float32_is_neg(mm)) {
-            if (!(fpcr_ah && float32_is_any_nan(mm))) {
+            if (fpcr_ah) {
+                flags = float_muladd_negate_product;
+            } else {
                 mm = float32_abs(mm);
             }
             xx += 8;
         }
-        d[i] = float32_muladd(n[i], mm, coeff[xx], 0, s);
+        d[i] = float32_muladd(n[i], mm, coeff[xx], flags, s);
     }
 }
 
@@ -5193,16 +5203,21 @@  void HELPER(sve_ftmad_d)(void *vd, void *vn, void *vm,
     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;
+        int flags = 0;
+
         if (float64_is_neg(mm)) {
-            if (!(fpcr_ah && float64_is_any_nan(mm))) {
+            if (fpcr_ah) {
+                flags = float_muladd_negate_product;
+            } else {
                 mm = float64_abs(mm);
             }
             xx += 8;
         }
-        d[i] = float64_muladd(n[i], mm, coeff[xx], 0, s);
+        d[i] = float64_muladd(n[i], mm, coeff[xx], flags, s);
     }
 }