hardfloat fused multiply-add might fallback to softfloat mode in some
situation, but it might already changed the value of input operands,
so we must restore those value before fallback.

This bug is catched by running gcc testsuite on RISC-V qemu.

Signed-off-by: Kito Cheng <kito.ch...@gmail.com>
---
 fpu/softfloat.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 4610738..f53f391 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -1596,6 +1596,7 @@ float32_muladd(float32 xa, float32 xb, float32
xc, int flags, float_status *s)
         }
         ur.h = up.h + uc.h;
     } else {
+        union_float32 ux = ua, uy = uc;
         if (flags & float_muladd_negate_product) {
             ua.h = -ua.h;
         }
@@ -1608,6 +1609,8 @@ float32_muladd(float32 xa, float32 xb, float32
xc, int flags, float_status *s)
         if (unlikely(f32_is_inf(ur))) {
             s->float_exception_flags |= float_flag_overflow;
         } else if (unlikely(fabsf(ur.h) <= FLT_MIN)) {
+            ua.h = ux.h;
+            uc.h = uy.h;
             goto soft;
         }
     }
@@ -1662,6 +1665,8 @@ float64_muladd(float64 xa, float64 xb, float64
xc, int flags, float_status *s)
         }
         ur.h = up.h + uc.h;
     } else {
+        union_float64 ux = ua, uy = uc;
+
         if (flags & float_muladd_negate_product) {
             ua.h = -ua.h;
         }
@@ -1674,6 +1679,8 @@ float64_muladd(float64 xa, float64 xb, float64
xc, int flags, float_status *s)
         if (unlikely(f64_is_inf(ur))) {
             s->float_exception_flags |= float_flag_overflow;
         } else if (unlikely(fabs(ur.h) <= FLT_MIN)) {
+            ua.h = ux.h;
+            uc.h = uy.h;
             goto soft;
         }
     }

Reply via email to