]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Make MIPS soft-fp preserve NaN payloads for NAN2008.
authorJoseph Myers <joseph@codesourcery.com>
Wed, 4 Jan 2017 17:15:39 +0000 (17:15 +0000)
committerJoseph Myers <joseph@codesourcery.com>
Wed, 4 Jan 2017 17:15:39 +0000 (17:15 +0000)
This corresponds to a patch applied to libgcc.  In glibc it doesn't
actually affect much (only fma, I think).

The MIPS sfp-machine.h files have an _FP_CHOOSENAN implementation
which emulates hardware semantics of not preserving signaling NaN
payloads for an operation with two NaN arguments (although that
doesn't suffice to avoid sNaN payload preservation in any case with
just one NaN argument).

However, those are only hardware semantics in the legacy NaN case; in
the NAN2008 case, the architecture documentation says hardware
preserves payloads in such cases.  Furthermore, this implementation
assumes legacy NaN semantics, so in the NAN2008 case the
implementation actually has the effect of preserving sNaN payloads but
not preserving qNaN payloads, when both should be preserved.

This patch fixes the code just to copy from the first argument.

Tested for mips64 soft-float.

* sysdeps/mips/mips32/sfp-machine.h (_FP_CHOOSENAN): Always
preserve NaN payload if [__mips_nan2008].
* sysdeps/mips/mips64/sfp-machine.h (_FP_CHOOSENAN): Likewise.

ChangeLog
sysdeps/mips/mips32/sfp-machine.h
sysdeps/mips/mips64/sfp-machine.h

index 32dee3fcb3d4ca651facc3b114831a7629e40653..0278dff4cc9dcef1801abc4c49f922fcc1012af9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2017-01-04  Joseph Myers  <joseph@codesourcery.com>
 
+       * sysdeps/mips/mips32/sfp-machine.h (_FP_CHOOSENAN): Always
+       preserve NaN payload if [__mips_nan2008].
+       * sysdeps/mips/mips64/sfp-machine.h (_FP_CHOOSENAN): Likewise.
+
        [BZ #21022]
        * sysdeps/microblaze/backtrace.c (get_frame_size): Make static.
 
index 4e23aa8b2622df0019eea113302be3d883aea53a..5215655029d07836f8a22f89a74ac8299fa4ec7e 100644 (file)
 # define _FP_QNANNEGATEDP 1
 #endif
 
+#ifdef __mips_nan2008
+/* NaN payloads should be preserved for NAN2008.  */
+# define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)    \
+  do                                           \
+    {                                          \
+      R##_s = X##_s;                           \
+      _FP_FRAC_COPY_##wc (R, X);               \
+      R##_c = FP_CLS_NAN;                      \
+    }                                          \
+  while (0)
+#else
 /* From my experiments it seems X is chosen unless one of the
    NaNs is sNaN,  in which case the result is NANSIGN/NANFRAC.  */
-#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)                     \
+# define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)                    \
   do {                                                         \
     if ((_FP_FRAC_HIGH_RAW_##fs(X) |                           \
         _FP_FRAC_HIGH_RAW_##fs(Y)) & _FP_QNANBIT_##fs)         \
@@ -58,6 +69,7 @@
       }                                                                \
     R##_c = FP_CLS_NAN;                                                \
   } while (0)
+#endif
 
 #define FP_EX_INVALID           (1 << 4)
 #define FP_EX_DIVZERO           (1 << 3)
index 708afc783e97dd3da55559d324ba7ca15999642b..35cc4ddeb1d0259c2c2b371229c70cc34c764898 100644 (file)
 # define _FP_QNANNEGATEDP 1
 #endif
 
+#ifdef __mips_nan2008
+/* NaN payloads should be preserved for NAN2008.  */
+# define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)    \
+  do                                           \
+    {                                          \
+      R##_s = X##_s;                           \
+      _FP_FRAC_COPY_##wc (R, X);               \
+      R##_c = FP_CLS_NAN;                      \
+    }                                          \
+  while (0)
+#else
 /* From my experiments it seems X is chosen unless one of the
    NaNs is sNaN,  in which case the result is NANSIGN/NANFRAC.  */
-#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)                     \
+# define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)                    \
   do {                                                         \
     if ((_FP_FRAC_HIGH_RAW_##fs(X) |                           \
         _FP_FRAC_HIGH_RAW_##fs(Y)) & _FP_QNANBIT_##fs)         \
@@ -61,6 +72,7 @@
       }                                                                \
     R##_c = FP_CLS_NAN;                                                \
   } while (0)
+#endif
 
 #define _FP_DECL_EX            fpu_control_t _fcw