aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2024-12-08 09:13:45 -0600
committerRichard Henderson <richard.henderson@linaro.org>2024-12-24 08:32:15 -0800
commit82f898f3b660fb11e601ee5ea1cab4b2fdafacc8 (patch)
tree30a43e4d0e4514ebeeadaeaf46e268b2fe2941dc
parent72330260cdb42015ae72096bae37e6fdaf361737 (diff)
downloadqemu-82f898f3b660fb11e601ee5ea1cab4b2fdafacc8.zip
qemu-82f898f3b660fb11e601ee5ea1cab4b2fdafacc8.tar.gz
qemu-82f898f3b660fb11e601ee5ea1cab4b2fdafacc8.tar.bz2
softfloat: Add float_muladd_suppress_add_product_zero
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>
-rw-r--r--fpu/softfloat-parts.c.inc4
-rw-r--r--fpu/softfloat.c3
-rw-r--r--include/fpu/softfloat.h5
3 files changed, 11 insertions, 1 deletions
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index 37d046c..ebde429 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -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;
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 6967fb5..8d75d66 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -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))) {
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index aa69aec..09a40b4 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -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,
};
/*----------------------------------------------------------------------------