softfloat: Add float_muladd_suppress_add_product_zero
authorRichard Henderson <richard.henderson@linaro.org>
Sun, 8 Dec 2024 15:13:45 +0000 (09:13 -0600)
committerRichard Henderson <richard.henderson@linaro.org>
Tue, 24 Dec 2024 16:32:15 +0000 (08:32 -0800)
Certain Hexagon instructions suppress changes to the result
when the product of fma() is a true zero.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
fpu/softfloat-parts.c.inc
fpu/softfloat.c
include/fpu/softfloat.h

index 37d046cfe984e5e439ed4b3e1005d8bae2805a4c..ebde42992fcb7f55d20beeaec118efe453b91cc3 100644 (file)
@@ -615,7 +615,9 @@ static FloatPartsN *partsN(muladd_scalbn)(FloatPartsN *a, FloatPartsN *b,
             goto return_normal;
         }
         if (c->cls == float_class_zero) {
-            if (a->sign != c->sign) {
+            if (flags & float_muladd_suppress_add_product_zero) {
+                a->sign = c->sign;
+            } else if (a->sign != c->sign) {
                 goto return_sub_zero;
             }
             goto return_zero;
index 6967fb5c9f761bea77d7e028cabc103c5bd32095..8d75d668172bf482914ddad74b4c7754bf16ee9b 100644 (file)
@@ -2274,6 +2274,9 @@ float32_muladd(float32 xa, float32 xb, float32 xc, int flags, float_status *s)
     if (unlikely(!can_use_fpu(s))) {
         goto soft;
     }
+    if (unlikely(flags & float_muladd_suppress_add_product_zero)) {
+        goto soft;
+    }
 
     float32_input_flush3(&ua.s, &ub.s, &uc.s, s);
     if (unlikely(!f32_is_zon3(ua, ub, uc))) {
index aa69aecfb030b51370a9f97ef090a36092c5602e..09a40b4310636278ee6296e3921975e7b9fbaeef 100644 (file)
@@ -120,11 +120,16 @@ bfloat16 bfloat16_squash_input_denormal(bfloat16 a, float_status *status);
 | Using these differs from negating an input or output before calling
 | the muladd function in that this means that a NaN doesn't have its
 | sign bit inverted before it is propagated.
+|
+| With float_muladd_suppress_add_product_zero, if A or B is zero
+| such that the product is a true zero, then return C without addition.
+| This preserves the sign of C when C is +/- 0.  Used for Hexagon.
 *----------------------------------------------------------------------------*/
 enum {
     float_muladd_negate_c = 1,
     float_muladd_negate_product = 2,
     float_muladd_negate_result = 4,
+    float_muladd_suppress_add_product_zero = 8,
 };
 
 /*----------------------------------------------------------------------------