When R##_f0 is assembled the _o240 chunk is shifted right by
(wfracbits - 1) - 96 bits, 19 for the quad format, and those bits are
discarded without being folded into the sticky bit _y240, which is
computed only from _s240, _r240, _q240 and _p240.  A product whose only
inexactness lies in the discarded bits is therefore reported as exact.

Fold the discarded bits into _y240.  This is the same change as the
glibc fix for BZ #34640; libgcc's soft-fp is a copy of glibc's.  In
glibc the macro is used for sparc64's _Qp_mul, where the fix takes
math/test-float64x-float128-mul from 65 errors to none.  No libgcc
target uses it today, so this keeps the two copies in sync.

libgcc/ChangeLog:

        * soft-fp/op-2.h (_FP_MUL_MEAT_2_120_240_double): Fold the bits of
        the _o240 chunk shifted out of R_f0 into the sticky bit _y240.

Signed-off-by: Stian Halseth <[email protected]>
---
 libgcc/soft-fp/op-2.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/libgcc/soft-fp/op-2.h b/libgcc/soft-fp/op-2.h
index 412b972..6415f66 100644
--- a/libgcc/soft-fp/op-2.h
+++ b/libgcc/soft-fp/op-2.h
@@ -515,6 +515,10 @@
       _v240 = _m240.i;                                                 \
       _w240 = _n240.i;                                                 \
       _x240 = _o240.i;                                                 \
+      /* The low bits of the _o240 chunk are shifted out when R##_f0   \
+        is assembled; fold them into the sticky bit.  */               \
+      if ((_x240 & ((((UDItype) 1) << ((wfracbits) - 97)) - 1)) != 0)  \
+       _y240 = 1;                                                      \
       R##_f1 = ((_t240 << (128 - (wfracbits - 1)))                     \
                | ((_u240 & 0xffffff) >> ((wfracbits - 1) - 104)));     \
       R##_f0 = (((_u240 & 0xffffff) << (168 - (wfracbits - 1)))                
\
-- 
2.43.0

Reply via email to