]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
soft-fp: Refactor exception handling for comparisons.
authorJoseph Myers <joseph@codesourcery.com>
Thu, 9 Oct 2014 01:03:56 +0000 (01:03 +0000)
committerJoseph Myers <joseph@codesourcery.com>
Thu, 9 Oct 2014 01:03:56 +0000 (01:03 +0000)
This patch refactors how soft-fp comparisons handle setting exceptions
for NaN operands, so that exceptions are set through the FP_CMP macros
rather than directly in the C files calling them.

The _FP_CMP* and FP_CMP* macros gain an extra argument to specify when
exceptions should be set, 0 for no exception setting (I'm not sure
this is actually needed - at least it's not needed for IEEE operations
in glibc / libgcc, but might be relevant in some cases for kernel
use), 1 for exceptions only for signaling NaNs and 2 for exceptions
for all NaNs.  This argument is handled through _FP_CMP_CHECK_NAN,
newly called by the _FP_CMP* macros when a NaN is encountered.  Calls
to these macros are updated, which eliminates all the existing
checking and exception setting in soft-fp *.c files in glibc.

Tested for powerpc-nofpu.  (The __unord* functions have no code
changes; the __eq* / __ge* / __le* functions get slightly larger, but
I don't think that's significant.)

* soft-fp/op-common.h (_FP_CMP_CHECK_NAN): New macro.
(_FP_CMP): Add extra argument EX.  Call _FP_CMP_CHECK_NAN.
(_FP_CMP_EQ): Likewise.
(_FP_CMP_UNORD): Likewise.
* soft-fp/double.h (FP_CMP_D): Add extra argument EX.
(FP_CMP_EQ_D): Likewise.
(FP_CMP_UNORD_D): Likewise.
* soft-fp/extended.h (FP_CMP_E): Likewise.
(FP_CMP_EQ_E): Likewise.
(FP_CMP_UNORD_E): Likewise.
* soft-fp/quad.h (FP_CMP_Q): Likewise.
(FP_CMP_EQ_Q): Likewise.
(FP_CMP_UNORD_Q): Likewise.
* soft-fp/single.h (FP_CMP_S): Likewise.
(FP_CMP_EQ_S): Likewise.
(FP_CMP_UNORD_S): Likewise.
* soft-fp/eqdf2.c (__eqdf2): Update call to FP_CMP_EQ_D.
* soft-fp/eqsf2.c (__eqsf2): Update call to FP_CMP_EQ_S.
* soft-fp/eqtf2.c (__eqtf2): Update call to FP_CMP_EQ_Q.
* soft-fp/gedf2.c (__gedf2): Update call to FP_CMP_D.
* soft-fp/gesf2.c (__gesf2): Update call to FP_CMP_S.
* soft-fp/getf2.c (__getf2): Update call to FP_CMP_Q.
* soft-fp/ledf2.c (__ledf2): Update call to FP_CMP_D.
* soft-fp/lesf2.c (__lesf2): Update call to FP_CMP_S.
* soft-fp/letf2.c (__letf2): Update call to FP_CMP_Q.
* soft-fp/unorddf2.c (__unorddf2): Update call to FP_CMP_UNORD_D.
* soft-fp/unordsf2.c (__unordsf2): Update call to FP_CMP_UNORD_S.
* soft-fp/unordtf2.c (__unordtf2): Update call to FP_CMP_UNORD_Q.
* sysdeps/alpha/soft-fp/ots_cmpe.c (internal_compare): Update call
to FP_CMP_Q.
* sysdeps/sparc/sparc32/soft-fp/q_cmp.c (_Q_cmp): Update call to
FP_CMP_Q.
* sysdeps/sparc/sparc32/soft-fp/q_cmpe.c (_Q_cmpe): Likewise.
* sysdeps/sparc/sparc32/soft-fp/q_feq.c (_Q_feq): Update call to
FP_CMP_EQ_Q.
* sysdeps/sparc/sparc32/soft-fp/q_fge.c (_Q_fge): Update call to
FP_CMP_Q.
* sysdeps/sparc/sparc32/soft-fp/q_fgt.c (_Q_fgt): Likewise.
* sysdeps/sparc/sparc32/soft-fp/q_fle.c (_Q_fle): Likewise.
* sysdeps/sparc/sparc32/soft-fp/q_flt.c (_Q_flt): Likewise.
* sysdeps/sparc/sparc32/soft-fp/q_fne.c (_Q_fne): Update call to
FP_CMP_EQ_Q.
* sysdeps/sparc/sparc64/soft-fp/qp_cmp.c (_Qp_cmp): Update call to
FP_CMP_Q.
* sysdeps/sparc/sparc64/soft-fp/qp_cmpe.c (_Qp_cmpe): Likewise.
* sysdeps/sparc/sparc64/soft-fp/qp_feq.c (_Qp_feq): Update call to
FP_CMP_EQ_Q.
* sysdeps/sparc/sparc64/soft-fp/qp_fge.c (_Qp_fge): Update call to
FP_CMP_Q.
* sysdeps/sparc/sparc64/soft-fp/qp_fgt.c (_Qp_fgt): Likewise.
* sysdeps/sparc/sparc64/soft-fp/qp_fle.c (_Qp_fle): Likewise.
* sysdeps/sparc/sparc64/soft-fp/qp_flt.c (_Qp_flt): Likewise.
* sysdeps/sparc/sparc64/soft-fp/qp_fne.c (_Qp_fne): Update call to
FP_CMP_EQ_Q.

35 files changed:
ChangeLog
soft-fp/double.h
soft-fp/eqdf2.c
soft-fp/eqsf2.c
soft-fp/eqtf2.c
soft-fp/extended.h
soft-fp/gedf2.c
soft-fp/gesf2.c
soft-fp/getf2.c
soft-fp/ledf2.c
soft-fp/lesf2.c
soft-fp/letf2.c
soft-fp/op-common.h
soft-fp/quad.h
soft-fp/single.h
soft-fp/unorddf2.c
soft-fp/unordsf2.c
soft-fp/unordtf2.c
sysdeps/alpha/soft-fp/ots_cmpe.c
sysdeps/sparc/sparc32/soft-fp/q_cmp.c
sysdeps/sparc/sparc32/soft-fp/q_cmpe.c
sysdeps/sparc/sparc32/soft-fp/q_feq.c
sysdeps/sparc/sparc32/soft-fp/q_fge.c
sysdeps/sparc/sparc32/soft-fp/q_fgt.c
sysdeps/sparc/sparc32/soft-fp/q_fle.c
sysdeps/sparc/sparc32/soft-fp/q_flt.c
sysdeps/sparc/sparc32/soft-fp/q_fne.c
sysdeps/sparc/sparc64/soft-fp/qp_cmp.c
sysdeps/sparc/sparc64/soft-fp/qp_cmpe.c
sysdeps/sparc/sparc64/soft-fp/qp_feq.c
sysdeps/sparc/sparc64/soft-fp/qp_fge.c
sysdeps/sparc/sparc64/soft-fp/qp_fgt.c
sysdeps/sparc/sparc64/soft-fp/qp_fle.c
sysdeps/sparc/sparc64/soft-fp/qp_flt.c
sysdeps/sparc/sparc64/soft-fp/qp_fne.c

index 703934d098af6ddbdb2654f7a92f787b2548dd28..f95e3ed79ab72bec880cf4ca585ddb164c6e34f6 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,60 @@
 2014-10-09  Joseph Myers  <joseph@codesourcery.com>
 
+       * soft-fp/op-common.h (_FP_CMP_CHECK_NAN): New macro.
+       (_FP_CMP): Add extra argument EX.  Call _FP_CMP_CHECK_NAN.
+       (_FP_CMP_EQ): Likewise.
+       (_FP_CMP_UNORD): Likewise.
+       * soft-fp/double.h (FP_CMP_D): Add extra argument EX.
+       (FP_CMP_EQ_D): Likewise.
+       (FP_CMP_UNORD_D): Likewise.
+       * soft-fp/extended.h (FP_CMP_E): Likewise.
+       (FP_CMP_EQ_E): Likewise.
+       (FP_CMP_UNORD_E): Likewise.
+       * soft-fp/quad.h (FP_CMP_Q): Likewise.
+       (FP_CMP_EQ_Q): Likewise.
+       (FP_CMP_UNORD_Q): Likewise.
+       * soft-fp/single.h (FP_CMP_S): Likewise.
+       (FP_CMP_EQ_S): Likewise.
+       (FP_CMP_UNORD_S): Likewise.
+       * soft-fp/eqdf2.c (__eqdf2): Update call to FP_CMP_EQ_D.
+       * soft-fp/eqsf2.c (__eqsf2): Update call to FP_CMP_EQ_S.
+       * soft-fp/eqtf2.c (__eqtf2): Update call to FP_CMP_EQ_Q.
+       * soft-fp/gedf2.c (__gedf2): Update call to FP_CMP_D.
+       * soft-fp/gesf2.c (__gesf2): Update call to FP_CMP_S.
+       * soft-fp/getf2.c (__getf2): Update call to FP_CMP_Q.
+       * soft-fp/ledf2.c (__ledf2): Update call to FP_CMP_D.
+       * soft-fp/lesf2.c (__lesf2): Update call to FP_CMP_S.
+       * soft-fp/letf2.c (__letf2): Update call to FP_CMP_Q.
+       * soft-fp/unorddf2.c (__unorddf2): Update call to FP_CMP_UNORD_D.
+       * soft-fp/unordsf2.c (__unordsf2): Update call to FP_CMP_UNORD_S.
+       * soft-fp/unordtf2.c (__unordtf2): Update call to FP_CMP_UNORD_Q.
+       * sysdeps/alpha/soft-fp/ots_cmpe.c (internal_compare): Update call
+       to FP_CMP_Q.
+       * sysdeps/sparc/sparc32/soft-fp/q_cmp.c (_Q_cmp): Update call to
+       FP_CMP_Q.
+       * sysdeps/sparc/sparc32/soft-fp/q_cmpe.c (_Q_cmpe): Likewise.
+       * sysdeps/sparc/sparc32/soft-fp/q_feq.c (_Q_feq): Update call to
+       FP_CMP_EQ_Q.
+       * sysdeps/sparc/sparc32/soft-fp/q_fge.c (_Q_fge): Update call to
+       FP_CMP_Q.
+       * sysdeps/sparc/sparc32/soft-fp/q_fgt.c (_Q_fgt): Likewise.
+       * sysdeps/sparc/sparc32/soft-fp/q_fle.c (_Q_fle): Likewise.
+       * sysdeps/sparc/sparc32/soft-fp/q_flt.c (_Q_flt): Likewise.
+       * sysdeps/sparc/sparc32/soft-fp/q_fne.c (_Q_fne): Update call to
+       FP_CMP_EQ_Q.
+       * sysdeps/sparc/sparc64/soft-fp/qp_cmp.c (_Qp_cmp): Update call to
+       FP_CMP_Q.
+       * sysdeps/sparc/sparc64/soft-fp/qp_cmpe.c (_Qp_cmpe): Likewise.
+       * sysdeps/sparc/sparc64/soft-fp/qp_feq.c (_Qp_feq): Update call to
+       FP_CMP_EQ_Q.
+       * sysdeps/sparc/sparc64/soft-fp/qp_fge.c (_Qp_fge): Update call to
+       FP_CMP_Q.
+       * sysdeps/sparc/sparc64/soft-fp/qp_fgt.c (_Qp_fgt): Likewise.
+       * sysdeps/sparc/sparc64/soft-fp/qp_fle.c (_Qp_fle): Likewise.
+       * sysdeps/sparc/sparc64/soft-fp/qp_flt.c (_Qp_flt): Likewise.
+       * sysdeps/sparc/sparc64/soft-fp/qp_fne.c (_Qp_fne): Update call to
+       FP_CMP_EQ_Q.
+
        * soft-fp/op-common.h (FP_EXTEND): When a subnormal input produces
        a subnormal result, set the underflow exception if trapping on
        underflow is enabled.
index 77829940445c8f26694b3c63983fb97d6bf4dd8b..1e6283e65540a33b9f69949dd3adaf179a604f7c 100644 (file)
@@ -177,9 +177,9 @@ union _FP_UNION_D
 # define _FP_SQRT_MEAT_D(R, S, T, X, Q)        _FP_SQRT_MEAT_2 (R, S, T, X, Q)
 # define FP_FMA_D(R, X, Y, Z)          _FP_FMA (D, 2, 4, R, X, Y, Z)
 
-# define FP_CMP_D(r, X, Y, un)         _FP_CMP (D, 2, r, X, Y, un)
-# define FP_CMP_EQ_D(r, X, Y)          _FP_CMP_EQ (D, 2, r, X, Y)
-# define FP_CMP_UNORD_D(r, X, Y)       _FP_CMP_UNORD (D, 2, r, X, Y)
+# define FP_CMP_D(r, X, Y, un, ex)     _FP_CMP (D, 2, r, X, Y, un, ex)
+# define FP_CMP_EQ_D(r, X, Y, ex)      _FP_CMP_EQ (D, 2, r, X, Y, ex)
+# define FP_CMP_UNORD_D(r, X, Y, ex)   _FP_CMP_UNORD (D, 2, r, X, Y, ex)
 
 # define FP_TO_INT_D(r, X, rsz, rsg)   _FP_TO_INT (D, 2, r, X, rsz, rsg)
 # define FP_FROM_INT_D(X, r, rs, rt)   _FP_FROM_INT (D, 2, X, r, rs, rt)
@@ -299,9 +299,9 @@ union _FP_UNION_D
 /* The implementation of _FP_MUL_D and _FP_DIV_D should be chosen by
    the target machine.  */
 
-# define FP_CMP_D(r, X, Y, un)         _FP_CMP (D, 1, r, X, Y, un)
-# define FP_CMP_EQ_D(r, X, Y)          _FP_CMP_EQ (D, 1, r, X, Y)
-# define FP_CMP_UNORD_D(r, X, Y)       _FP_CMP_UNORD (D, 1, r, X, Y)
+# define FP_CMP_D(r, X, Y, un, ex)     _FP_CMP (D, 1, r, X, Y, un, ex)
+# define FP_CMP_EQ_D(r, X, Y, ex)      _FP_CMP_EQ (D, 1, r, X, Y, ex)
+# define FP_CMP_UNORD_D(r, X, Y, ex)   _FP_CMP_UNORD (D, 1, r, X, Y, ex)
 
 # define FP_TO_INT_D(r, X, rsz, rsg)   _FP_TO_INT (D, 1, r, X, rsz, rsg)
 # define FP_FROM_INT_D(X, r, rs, rt)   _FP_FROM_INT (D, 1, X, r, rs, rt)
index 006b1ef83a3bb23c0734c4b8e39188942d55e292..e8ce12d0aa036418f41f1b950845640b03eba3a0 100644 (file)
@@ -42,9 +42,7 @@ __eqdf2 (DFtype a, DFtype b)
   FP_INIT_EXCEPTIONS;
   FP_UNPACK_RAW_D (A, a);
   FP_UNPACK_RAW_D (B, b);
-  FP_CMP_EQ_D (r, A, B);
-  if (r && (FP_ISSIGNAN_D (A) || FP_ISSIGNAN_D (B)))
-    FP_SET_EXCEPTION (FP_EX_INVALID);
+  FP_CMP_EQ_D (r, A, B, 1);
   FP_HANDLE_EXCEPTIONS;
 
   return r;
index 437ef99a2f441e7e7ea3ce3bb4b321c07c87b12f..2ee837d8478327f1fa5bb961fad6cfa3219749d5 100644 (file)
@@ -42,9 +42,7 @@ __eqsf2 (SFtype a, SFtype b)
   FP_INIT_EXCEPTIONS;
   FP_UNPACK_RAW_S (A, a);
   FP_UNPACK_RAW_S (B, b);
-  FP_CMP_EQ_S (r, A, B);
-  if (r && (FP_ISSIGNAN_S (A) || FP_ISSIGNAN_S (B)))
-    FP_SET_EXCEPTION (FP_EX_INVALID);
+  FP_CMP_EQ_S (r, A, B, 1);
   FP_HANDLE_EXCEPTIONS;
 
   return r;
index ffc558ced2cd1bef9516e6885b285a8261a7e929..17b9d40a0562a4b4dd9d3ac9fced4d084862c68e 100644 (file)
@@ -42,9 +42,7 @@ __eqtf2 (TFtype a, TFtype b)
   FP_INIT_EXCEPTIONS;
   FP_UNPACK_RAW_Q (A, a);
   FP_UNPACK_RAW_Q (B, b);
-  FP_CMP_EQ_Q (r, A, B);
-  if (r && (FP_ISSIGNAN_Q (A) || FP_ISSIGNAN_Q (B)))
-    FP_SET_EXCEPTION (FP_EX_INVALID);
+  FP_CMP_EQ_Q (r, A, B, 1);
   FP_HANDLE_EXCEPTIONS;
 
   return r;
index 989b056974224ff2df01c5190b296a2bd570915d..0dd6a87083ea81498c58f9803433339e04fe31e2 100644 (file)
@@ -287,9 +287,9 @@ union _FP_UNION_E
     }                                                  \
   while (0)
 
-# define FP_CMP_E(r, X, Y, un)         _FP_CMP (E, 4, r, X, Y, un)
-# define FP_CMP_EQ_E(r, X, Y)          _FP_CMP_EQ (E, 4, r, X, Y)
-# define FP_CMP_UNORD_E(r, X, Y)       _FP_CMP_UNORD (E, 4, r, X, Y)
+# define FP_CMP_E(r, X, Y, un, ex)     _FP_CMP (E, 4, r, X, Y, un, ex)
+# define FP_CMP_EQ_E(r, X, Y, ex)      _FP_CMP_EQ (E, 4, r, X, Y, ex)
+# define FP_CMP_UNORD_E(r, X, Y, ex)   _FP_CMP_UNORD (E, 4, r, X, Y, ex)
 
 # define FP_TO_INT_E(r, X, rsz, rsg)   _FP_TO_INT (E, 4, r, X, rsz, rsg)
 # define FP_FROM_INT_E(X, r, rs, rt)   _FP_FROM_INT (E, 4, X, r, rs, rt)
@@ -489,9 +489,9 @@ union _FP_UNION_E
     }                                                  \
   while (0)
 
-# define FP_CMP_E(r, X, Y, un)         _FP_CMP (E, 2, r, X, Y, un)
-# define FP_CMP_EQ_E(r, X, Y)          _FP_CMP_EQ (E, 2, r, X, Y)
-# define FP_CMP_UNORD_E(r, X, Y)       _FP_CMP_UNORD (E, 2, r, X, Y)
+# define FP_CMP_E(r, X, Y, un, ex)     _FP_CMP (E, 2, r, X, Y, un, ex)
+# define FP_CMP_EQ_E(r, X, Y, ex)      _FP_CMP_EQ (E, 2, r, X, Y, ex)
+# define FP_CMP_UNORD_E(r, X, Y, ex)   _FP_CMP_UNORD (E, 2, r, X, Y, ex)
 
 # define FP_TO_INT_E(r, X, rsz, rsg)   _FP_TO_INT (E, 2, r, X, rsz, rsg)
 # define FP_FROM_INT_E(X, r, rs, rt)   _FP_FROM_INT (E, 2, X, r, rs, rt)
index 4ff97561bac70d263a954acf60ba924628de4ca8..a8cc94941f99e16be53afb7f3c9385794b327f28 100644 (file)
@@ -42,9 +42,7 @@ __gedf2 (DFtype a, DFtype b)
   FP_INIT_EXCEPTIONS;
   FP_UNPACK_RAW_D (A, a);
   FP_UNPACK_RAW_D (B, b);
-  FP_CMP_D (r, A, B, -2);
-  if (r == -2)
-    FP_SET_EXCEPTION (FP_EX_INVALID);
+  FP_CMP_D (r, A, B, -2, 2);
   FP_HANDLE_EXCEPTIONS;
 
   return r;
index f3c5d2d71062025bca0e61fe3606b4c91df77f5b..aa84b2614d8db682d7010f480201d507cd7a4082 100644 (file)
@@ -42,9 +42,7 @@ __gesf2 (SFtype a, SFtype b)
   FP_INIT_EXCEPTIONS;
   FP_UNPACK_RAW_S (A, a);
   FP_UNPACK_RAW_S (B, b);
-  FP_CMP_S (r, A, B, -2);
-  if (r == -2)
-    FP_SET_EXCEPTION (FP_EX_INVALID);
+  FP_CMP_S (r, A, B, -2, 2);
   FP_HANDLE_EXCEPTIONS;
 
   return r;
index fb82b795ca9470435a899babd60032f23c824c1c..c852228ddcabc8f770d0a9801bdcef5a860b5af9 100644 (file)
@@ -42,9 +42,7 @@ __getf2 (TFtype a, TFtype b)
   FP_INIT_EXCEPTIONS;
   FP_UNPACK_RAW_Q (A, a);
   FP_UNPACK_RAW_Q (B, b);
-  FP_CMP_Q (r, A, B, -2);
-  if (r == -2)
-    FP_SET_EXCEPTION (FP_EX_INVALID);
+  FP_CMP_Q (r, A, B, -2, 2);
   FP_HANDLE_EXCEPTIONS;
 
   return r;
index 8b15d32b740a504000191148afd59ae2f9e3a701..fb5bbb29de97efb02c769d2293e9fcf2d5354733 100644 (file)
@@ -42,9 +42,7 @@ __ledf2 (DFtype a, DFtype b)
   FP_INIT_EXCEPTIONS;
   FP_UNPACK_RAW_D (A, a);
   FP_UNPACK_RAW_D (B, b);
-  FP_CMP_D (r, A, B, 2);
-  if (r == 2)
-    FP_SET_EXCEPTION (FP_EX_INVALID);
+  FP_CMP_D (r, A, B, 2, 2);
   FP_HANDLE_EXCEPTIONS;
 
   return r;
index e86ac3f08e5f0e55a28bcb0a587302202935d2de..1b672042a2cf1aa4546d0ac9b5f0a6bdc50280d4 100644 (file)
@@ -42,9 +42,7 @@ __lesf2 (SFtype a, SFtype b)
   FP_INIT_EXCEPTIONS;
   FP_UNPACK_RAW_S (A, a);
   FP_UNPACK_RAW_S (B, b);
-  FP_CMP_S (r, A, B, 2);
-  if (r == 2)
-    FP_SET_EXCEPTION (FP_EX_INVALID);
+  FP_CMP_S (r, A, B, 2, 2);
   FP_HANDLE_EXCEPTIONS;
 
   return r;
index 94b7d786d66bf92ad9d2bee0d67f23dc1ddded7a..1293519d21bb61a34135d556c26c93b7bbd28bf9 100644 (file)
@@ -42,9 +42,7 @@ __letf2 (TFtype a, TFtype b)
   FP_INIT_EXCEPTIONS;
   FP_UNPACK_RAW_Q (A, a);
   FP_UNPACK_RAW_Q (B, b);
-  FP_CMP_Q (r, A, B, 2);
-  if (r == 2)
-    FP_SET_EXCEPTION (FP_EX_INVALID);
+  FP_CMP_Q (r, A, B, 2, 2);
   FP_HANDLE_EXCEPTIONS;
 
   return r;
index e3212ecfd54db906c64540b9153be102a02afd55..e62558e4b4a146debc6d49ca63c4466a3c3fc08b 100644 (file)
   while (0)
 
 
+/* Helper for comparisons.  EX is 0 not to raise exceptions, 1 to
+   raise exceptions for signaling NaN operands, 2 to raise exceptions
+   for all NaN operands.  */
+
+#define _FP_CMP_CHECK_NAN(fs, wc, X, Y, ex)            \
+  do                                                   \
+    {                                                  \
+      if (ex)                                          \
+       {                                               \
+         if ((ex) == 2                                 \
+             || _FP_ISSIGNAN (fs, wc, X)               \
+             || _FP_ISSIGNAN (fs, wc, Y))              \
+           FP_SET_EXCEPTION (FP_EX_INVALID);           \
+       }                                               \
+    }                                                  \
+  while (0)
+
 /* Main differential comparison routine.  The inputs should be raw not
-   cooked.  The return is -1,0,1 for normal values, 2 otherwise.  */
+   cooked.  The return is -1, 0, 1 for normal values, UN
+   otherwise.  */
 
-#define _FP_CMP(fs, wc, ret, X, Y, un)                                 \
+#define _FP_CMP(fs, wc, ret, X, Y, un, ex)                             \
   do                                                                   \
     {                                                                  \
       /* NANs are unordered.  */                                       \
          || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (Y)))    \
        {                                                               \
          ret = un;                                                     \
+         _FP_CMP_CHECK_NAN (fs, wc, X, Y, ex);                         \
        }                                                               \
       else                                                             \
        {                                                               \
 
 /* Simplification for strict equality.  */
 
-#define _FP_CMP_EQ(fs, wc, ret, X, Y)                                  \
+#define _FP_CMP_EQ(fs, wc, ret, X, Y, ex)                              \
   do                                                                   \
     {                                                                  \
       /* NANs are unordered.  */                                       \
          || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (Y)))    \
        {                                                               \
          ret = 1;                                                      \
+         _FP_CMP_CHECK_NAN (fs, wc, X, Y, ex);                         \
        }                                                               \
       else                                                             \
        {                                                               \
 
 /* Version to test unordered.  */
 
-#define _FP_CMP_UNORD(fs, wc, ret, X, Y)                               \
+#define _FP_CMP_UNORD(fs, wc, ret, X, Y, ex)                           \
   do                                                                   \
     {                                                                  \
       ret = ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (X))    \
             || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (Y))); \
+      if (ret)                                                         \
+       _FP_CMP_CHECK_NAN (fs, wc, X, Y, ex);                           \
     }                                                                  \
   while (0)
 
index 16e362f1c69c3a4b7b7182d95256b5aa40d1e0c8..c2e4133722007247871f7348913334c22e30be27 100644 (file)
@@ -182,9 +182,9 @@ union _FP_UNION_Q
 # define _FP_SQRT_MEAT_Q(R, S, T, X, Q)        _FP_SQRT_MEAT_4 (R, S, T, X, Q)
 # define FP_FMA_Q(R, X, Y, Z)          _FP_FMA (Q, 4, 8, R, X, Y, Z)
 
-# define FP_CMP_Q(r, X, Y, un)         _FP_CMP (Q, 4, r, X, Y, un)
-# define FP_CMP_EQ_Q(r, X, Y)          _FP_CMP_EQ (Q, 4, r, X, Y)
-# define FP_CMP_UNORD_Q(r, X, Y)       _FP_CMP_UNORD (Q, 4, r, X, Y)
+# define FP_CMP_Q(r, X, Y, un, ex)     _FP_CMP (Q, 4, r, X, Y, un, ex)
+# define FP_CMP_EQ_Q(r, X, Y, ex)      _FP_CMP_EQ (Q, 4, r, X, Y, ex)
+# define FP_CMP_UNORD_Q(r, X, Y, ex)   _FP_CMP_UNORD (Q, 4, r, X, Y, ex)
 
 # define FP_TO_INT_Q(r, X, rsz, rsg)   _FP_TO_INT (Q, 4, r, X, rsz, rsg)
 # define FP_FROM_INT_Q(X, r, rs, rt)   _FP_FROM_INT (Q, 4, X, r, rs, rt)
@@ -306,9 +306,9 @@ union _FP_UNION_Q
 # define _FP_SQRT_MEAT_Q(R, S, T, X, Q)        _FP_SQRT_MEAT_2 (R, S, T, X, Q)
 # define FP_FMA_Q(R, X, Y, Z)          _FP_FMA (Q, 2, 4, R, X, Y, Z)
 
-# define FP_CMP_Q(r, X, Y, un)         _FP_CMP (Q, 2, r, X, Y, un)
-# define FP_CMP_EQ_Q(r, X, Y)          _FP_CMP_EQ (Q, 2, r, X, Y)
-# define FP_CMP_UNORD_Q(r, X, Y)       _FP_CMP_UNORD (Q, 2, r, X, Y)
+# define FP_CMP_Q(r, X, Y, un, ex)     _FP_CMP (Q, 2, r, X, Y, un, ex)
+# define FP_CMP_EQ_Q(r, X, Y, ex)      _FP_CMP_EQ (Q, 2, r, X, Y, ex)
+# define FP_CMP_UNORD_Q(r, X, Y, ex)   _FP_CMP_UNORD (Q, 2, r, X, Y, ex)
 
 # define FP_TO_INT_Q(r, X, rsz, rsg)   _FP_TO_INT (Q, 2, r, X, rsz, rsg)
 # define FP_FROM_INT_Q(X, r, rs, rt)   _FP_FROM_INT (Q, 2, X, r, rs, rt)
index 19fd6476ee9e58e7aebeaaaf4a952ed9b5f56b35..efa829466245af65c21609f95b281cec4255bfa2 100644 (file)
@@ -175,9 +175,9 @@ union _FP_UNION_S
 # define FP_FMA_S(R, X, Y, Z)  _FP_FMA (S, 1, 1, R, X, Y, Z)
 #endif
 
-#define FP_CMP_S(r, X, Y, un)  _FP_CMP (S, 1, r, X, Y, un)
-#define FP_CMP_EQ_S(r, X, Y)   _FP_CMP_EQ (S, 1, r, X, Y)
-#define FP_CMP_UNORD_S(r, X, Y)        _FP_CMP_UNORD (S, 1, r, X, Y)
+#define FP_CMP_S(r, X, Y, un, ex)      _FP_CMP (S, 1, r, X, Y, un, ex)
+#define FP_CMP_EQ_S(r, X, Y, ex)       _FP_CMP_EQ (S, 1, r, X, Y, ex)
+#define FP_CMP_UNORD_S(r, X, Y, ex)    _FP_CMP_UNORD (S, 1, r, X, Y, ex)
 
 #define FP_TO_INT_S(r, X, rsz, rsg)    _FP_TO_INT (S, 1, r, X, rsz, rsg)
 #define FP_FROM_INT_S(X, r, rs, rt)    _FP_FROM_INT (S, 1, X, r, rs, rt)
index ceacb9e91d4b78862b3fe83d1be4258f49e735a6..e09a1ece650a898d1a8ce6cc62af785584bb4a38 100644 (file)
@@ -41,9 +41,7 @@ __unorddf2 (DFtype a, DFtype b)
   FP_INIT_EXCEPTIONS;
   FP_UNPACK_RAW_D (A, a);
   FP_UNPACK_RAW_D (B, b);
-  FP_CMP_UNORD_D (r, A, B);
-  if (r && (FP_ISSIGNAN_D (A) || FP_ISSIGNAN_D (B)))
-    FP_SET_EXCEPTION (FP_EX_INVALID);
+  FP_CMP_UNORD_D (r, A, B, 1);
   FP_HANDLE_EXCEPTIONS;
 
   return r;
index 057f2c43a7938455c43b49ce10dc715fec7243a7..4d6be98a753ff105622f96300a06620d10c44d7e 100644 (file)
@@ -41,9 +41,7 @@ __unordsf2 (SFtype a, SFtype b)
   FP_INIT_EXCEPTIONS;
   FP_UNPACK_RAW_S (A, a);
   FP_UNPACK_RAW_S (B, b);
-  FP_CMP_UNORD_S (r, A, B);
-  if (r && (FP_ISSIGNAN_S (A) || FP_ISSIGNAN_S (B)))
-    FP_SET_EXCEPTION (FP_EX_INVALID);
+  FP_CMP_UNORD_S (r, A, B, 1);
   FP_HANDLE_EXCEPTIONS;
 
   return r;
index 433a84fd5eb2d60dde412497e0e8c8768205ba77..79d34211cf281a1dfd007b8269a7869fad46c902 100644 (file)
@@ -41,9 +41,7 @@ __unordtf2 (TFtype a, TFtype b)
   FP_INIT_EXCEPTIONS;
   FP_UNPACK_RAW_Q (A, a);
   FP_UNPACK_RAW_Q (B, b);
-  FP_CMP_UNORD_Q (r, A, B);
-  if (r && (FP_ISSIGNAN_Q (A) || FP_ISSIGNAN_Q (B)))
-    FP_SET_EXCEPTION (FP_EX_INVALID);
+  FP_CMP_UNORD_Q (r, A, B, 1);
   FP_HANDLE_EXCEPTIONS;
 
   return r;
index adeda848f4b949ca7bbb88ceda2d7b121041b5ba..41586eee263494ee431d0066cdbbc3b7dd222f6e 100644 (file)
@@ -29,14 +29,9 @@ internal_compare (long al, long ah, long bl, long bh)
 
   FP_UNPACK_RAW_Q(A, a);
   FP_UNPACK_RAW_Q(B, b);
-  FP_CMP_Q (r, A, B, 2);
+  FP_CMP_Q (r, A, B, 2, 2);
 
-  /* Relative comparisons signal invalid operation if either operand is NaN. */
-  if (r == 2)
-    {
-      FP_SET_EXCEPTION(FP_EX_INVALID);
-      FP_HANDLE_EXCEPTIONS;
-    }
+  FP_HANDLE_EXCEPTIONS;
 
   return r;
 }
index 837b3dd0912ffcca5df195a345dda1f04da032ed..acc1d1d1b12440abbe63a8936fced836ba424d29 100644 (file)
@@ -30,10 +30,8 @@ int _Q_cmp(const long double a, const long double b)
 
   FP_UNPACK_RAW_Q(A, a);
   FP_UNPACK_RAW_Q(B, b);
-  FP_CMP_Q(r, B, A, 3);
+  FP_CMP_Q(r, B, A, 3, 1);
   if (r == -1) r = 2;
-  if (r == 3 && (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B)))
-    FP_SET_EXCEPTION(FP_EX_INVALID);
   FP_HANDLE_EXCEPTIONS;
 
   return r;
index d4ac7bd67c37fb1c642ae0a575ac8459a8206e99..a5d46705b30f2fedee7314ec92ad595b51d83237 100644 (file)
@@ -31,10 +31,8 @@ int _Q_cmpe(const long double a, const long double b)
 
   FP_UNPACK_RAW_Q(A, a);
   FP_UNPACK_RAW_Q(B, b);
-  FP_CMP_Q(r, B, A, 3);
+  FP_CMP_Q(r, B, A, 3, 2);
   if (r == -1) r = 2;
-  if (r == 3)
-    FP_SET_EXCEPTION(FP_EX_INVALID);
   FP_HANDLE_EXCEPTIONS;
 
   return r;
index 61a8ff1b188378e4baf6e9d8cb34340bb5b36ca9..cb7db6dcaa5f9fca77d31df1839d304268343d4c 100644 (file)
@@ -30,9 +30,7 @@ int _Q_feq(const long double a, const long double b)
 
   FP_UNPACK_RAW_Q(A, a);
   FP_UNPACK_RAW_Q(B, b);
-  FP_CMP_EQ_Q(r, A, B);
-  if (r && (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B)))
-    FP_SET_EXCEPTION(FP_EX_INVALID);
+  FP_CMP_EQ_Q(r, A, B, 1);
   FP_HANDLE_EXCEPTIONS;
 
   return !r;
index 7fca34926a7675ccb909a6aacff348f779e2d604..cca1003dfb66d73d31c6bf1636df31b3028064d9 100644 (file)
@@ -30,9 +30,7 @@ int _Q_fge(const long double a, const long double b)
 
   FP_UNPACK_RAW_Q(A, a);
   FP_UNPACK_RAW_Q(B, b);
-  FP_CMP_Q(r, B, A, 3);
-  if (r == 3)
-    FP_SET_EXCEPTION(FP_EX_INVALID);
+  FP_CMP_Q(r, B, A, 3, 2);
   FP_HANDLE_EXCEPTIONS;
 
   return (r <= 0);
index f5b2acf4c4aa0d80045a95dc9f7af750a73eb82c..00f837d02e9ba46620426f9a17fa02651f32c310 100644 (file)
@@ -30,9 +30,7 @@ int _Q_fgt(const long double a, const long double b)
 
   FP_UNPACK_RAW_Q(A, a);
   FP_UNPACK_RAW_Q(B, b);
-  FP_CMP_Q(r, B, A, 3);
-  if (r == 3)
-    FP_SET_EXCEPTION(FP_EX_INVALID);
+  FP_CMP_Q(r, B, A, 3, 2);
   FP_HANDLE_EXCEPTIONS;
 
   return (r == -1);
index c108fb9e3f9cc5be03bd059c9e77ad09766cc88b..b44f4484d8e2d9f1da7ef4ea194aa88818921eb1 100644 (file)
@@ -30,9 +30,7 @@ int _Q_fle(const long double a, const long double b)
 
   FP_UNPACK_RAW_Q(A, a);
   FP_UNPACK_RAW_Q(B, b);
-  FP_CMP_Q(r, B, A, -2);
-  if (r == -2)
-    FP_SET_EXCEPTION(FP_EX_INVALID);
+  FP_CMP_Q(r, B, A, -2, 2);
   FP_HANDLE_EXCEPTIONS;
 
   return (r >= 0);
index 56d140e6e9e70f659e520729d8831c74ea372197..caa188d72c64b1b7348489fc6ff3c70ab42ced65 100644 (file)
@@ -30,9 +30,7 @@ int _Q_flt(const long double a, const long double b)
 
   FP_UNPACK_RAW_Q(A, a);
   FP_UNPACK_RAW_Q(B, b);
-  FP_CMP_Q(r, B, A, 3);
-  if (r == 3)
-    FP_SET_EXCEPTION(FP_EX_INVALID);
+  FP_CMP_Q(r, B, A, 3, 2);
   FP_HANDLE_EXCEPTIONS;
 
   return (r == 1);
index 78c2d6f971bee05c8a29a375e1002e6258829e04..e22f6c987a33a920a2bfb44f0973d8bdb690e7ee 100644 (file)
@@ -30,9 +30,7 @@ int _Q_fne(const long double a, const long double b)
 
   FP_UNPACK_RAW_Q(A, a);
   FP_UNPACK_RAW_Q(B, b);
-  FP_CMP_EQ_Q(r, A, B);
-  if (r && (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B)))
-    FP_SET_EXCEPTION(FP_EX_INVALID);
+  FP_CMP_EQ_Q(r, A, B, 1);
   FP_HANDLE_EXCEPTIONS;
 
   return r;
index 1929a082c2b54a1835964a0336aefdee3943fec5..dadb36909d9142162fe98e8af7ec4189c1913f39 100644 (file)
@@ -31,10 +31,8 @@ int _Qp_cmp(const long double *a, const long double *b)
   FP_INIT_ROUNDMODE;
   FP_UNPACK_RAW_QP(A, a);
   FP_UNPACK_RAW_QP(B, b);
-  FP_CMP_Q(r, B, A, 3);
+  FP_CMP_Q(r, B, A, 3, 1);
   if (r == -1) r = 2;
-  if (r == 3 && (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B)))
-    FP_SET_EXCEPTION(FP_EX_INVALID);
   QP_HANDLE_EXCEPTIONS(
        __asm (
 "      ldd [%0], %%f52\n"
index ee25b5e8b132dc2087cb6b1aa6ee29f80b5d5d47..c56d623947658def1afe4d47582dd68e1386f06e 100644 (file)
@@ -32,10 +32,8 @@ int _Qp_cmpe(const long double *a, const long double *b)
   FP_INIT_ROUNDMODE;
   FP_UNPACK_RAW_QP(A, a);
   FP_UNPACK_RAW_QP(B, b);
-  FP_CMP_Q(r, B, A, 3);
+  FP_CMP_Q(r, B, A, 3, 2);
   if (r == -1) r = 2;
-  if (r == 3)
-    FP_SET_EXCEPTION(FP_EX_INVALID);
   QP_HANDLE_EXCEPTIONS(
        __asm (
 "      ldd [%0], %%f52\n"
index 36eef5aa8a42c1b2995c34c68c18cc63410765da..67b6b877f0bce2500ec07c063e4c51689c214cb2 100644 (file)
@@ -31,9 +31,7 @@ int _Qp_feq(const long double *a, const long double *b)
   FP_INIT_ROUNDMODE;
   FP_UNPACK_RAW_QP(A, a);
   FP_UNPACK_RAW_QP(B, b);
-  FP_CMP_EQ_Q(r, A, B);
-  if (r && (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B)))
-    FP_SET_EXCEPTION(FP_EX_INVALID);
+  FP_CMP_EQ_Q(r, A, B, 1);
 
   QP_HANDLE_EXCEPTIONS(
        __asm (
index 3f0c16b416953478331056e94617aa0cc0122d10..690a741d1b26896baeb250dc6da4280562e12f0b 100644 (file)
@@ -31,9 +31,7 @@ int _Qp_fge(const long double *a, const long double *b)
   FP_INIT_ROUNDMODE;
   FP_UNPACK_RAW_QP(A, a);
   FP_UNPACK_RAW_QP(B, b);
-  FP_CMP_Q(r, B, A, 3);
-  if (r == 3)
-    FP_SET_EXCEPTION(FP_EX_INVALID);
+  FP_CMP_Q(r, B, A, 3, 2);
 
   QP_HANDLE_EXCEPTIONS(
        __asm (
index 2b915be37d9a4e460e4e68c57433d2304ca4a2f9..423bd5a9224ce226afb73c1ae3ce148c453b8806 100644 (file)
@@ -31,9 +31,7 @@ int _Qp_fgt(const long double *a, const long double *b)
   FP_INIT_ROUNDMODE;
   FP_UNPACK_RAW_QP(A, a);
   FP_UNPACK_RAW_QP(B, b);
-  FP_CMP_Q(r, B, A, 3);
-  if (r == 3)
-    FP_SET_EXCEPTION(FP_EX_INVALID);
+  FP_CMP_Q(r, B, A, 3, 2);
 
   QP_HANDLE_EXCEPTIONS(
        __asm (
index 74f80f41318c897236c0a443f7f7bd4394044f49..f9151524f98bfab68b6ef1e3aebe663c7edb039d 100644 (file)
@@ -31,9 +31,7 @@ int _Qp_fle(const long double *a, const long double *b)
   FP_INIT_ROUNDMODE;
   FP_UNPACK_RAW_QP(A, a);
   FP_UNPACK_RAW_QP(B, b);
-  FP_CMP_Q(r, B, A, -2);
-  if (r == -2)
-    FP_SET_EXCEPTION(FP_EX_INVALID);
+  FP_CMP_Q(r, B, A, -2, 2);
 
   QP_HANDLE_EXCEPTIONS(
        __asm (
index a4c8e05a0acd3c69e19c3b17dca4145618bca838..c03cd72516e6d1d6a3e9c3ba1b0db3b5dcf632b3 100644 (file)
@@ -31,9 +31,7 @@ int _Qp_flt(const long double *a, const long double *b)
   FP_INIT_ROUNDMODE;
   FP_UNPACK_RAW_QP(A, a);
   FP_UNPACK_RAW_QP(B, b);
-  FP_CMP_Q(r, B, A, 3);
-  if (r == 3)
-    FP_SET_EXCEPTION(FP_EX_INVALID);
+  FP_CMP_Q(r, B, A, 3, 2);
 
   QP_HANDLE_EXCEPTIONS(
        __asm (
index 828c394f292eb4fe7e2d239a78b77cb74efc3c77..948077c425071966d6a9dc83f2dd632b42736ce6 100644 (file)
@@ -31,9 +31,7 @@ int _Qp_fne(const long double *a, const long double *b)
   FP_INIT_ROUNDMODE;
   FP_UNPACK_RAW_QP(A, a);
   FP_UNPACK_RAW_QP(B, b);
-  FP_CMP_EQ_Q(r, A, B);
-  if (r && (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B)))
-    FP_SET_EXCEPTION(FP_EX_INVALID);
+  FP_CMP_EQ_Q(r, A, B, 1);
 
   QP_HANDLE_EXCEPTIONS(
        __asm (