diff options
author | Joseph Myers <joseph@codesourcery.com> | 2014-10-09 01:03:56 +0000 |
---|---|---|
committer | Joseph Myers <joseph@codesourcery.com> | 2014-10-09 01:03:56 +0000 |
commit | 73e28d9c885fdfed91e6d70c4aab7e8e801818e3 (patch) | |
tree | 776c199c63bde4d28a6f38044665709686adde06 /sysdeps/sparc/sparc32 | |
parent | 43059f42dbd6dd3926c33ee0cbc7583f0c3e84b9 (diff) | |
download | glibc-73e28d9c885fdfed91e6d70c4aab7e8e801818e3.tar.gz |
soft-fp: Refactor exception handling for comparisons.
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.
Diffstat (limited to 'sysdeps/sparc/sparc32')
-rw-r--r-- | sysdeps/sparc/sparc32/soft-fp/q_cmp.c | 4 | ||||
-rw-r--r-- | sysdeps/sparc/sparc32/soft-fp/q_cmpe.c | 4 | ||||
-rw-r--r-- | sysdeps/sparc/sparc32/soft-fp/q_feq.c | 4 | ||||
-rw-r--r-- | sysdeps/sparc/sparc32/soft-fp/q_fge.c | 4 | ||||
-rw-r--r-- | sysdeps/sparc/sparc32/soft-fp/q_fgt.c | 4 | ||||
-rw-r--r-- | sysdeps/sparc/sparc32/soft-fp/q_fle.c | 4 | ||||
-rw-r--r-- | sysdeps/sparc/sparc32/soft-fp/q_flt.c | 4 | ||||
-rw-r--r-- | sysdeps/sparc/sparc32/soft-fp/q_fne.c | 4 |
8 files changed, 8 insertions, 24 deletions
diff --git a/sysdeps/sparc/sparc32/soft-fp/q_cmp.c b/sysdeps/sparc/sparc32/soft-fp/q_cmp.c index 837b3dd091..acc1d1d1b1 100644 --- a/sysdeps/sparc/sparc32/soft-fp/q_cmp.c +++ b/sysdeps/sparc/sparc32/soft-fp/q_cmp.c @@ -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; diff --git a/sysdeps/sparc/sparc32/soft-fp/q_cmpe.c b/sysdeps/sparc/sparc32/soft-fp/q_cmpe.c index d4ac7bd67c..a5d46705b3 100644 --- a/sysdeps/sparc/sparc32/soft-fp/q_cmpe.c +++ b/sysdeps/sparc/sparc32/soft-fp/q_cmpe.c @@ -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; diff --git a/sysdeps/sparc/sparc32/soft-fp/q_feq.c b/sysdeps/sparc/sparc32/soft-fp/q_feq.c index 61a8ff1b18..cb7db6dcaa 100644 --- a/sysdeps/sparc/sparc32/soft-fp/q_feq.c +++ b/sysdeps/sparc/sparc32/soft-fp/q_feq.c @@ -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; diff --git a/sysdeps/sparc/sparc32/soft-fp/q_fge.c b/sysdeps/sparc/sparc32/soft-fp/q_fge.c index 7fca34926a..cca1003dfb 100644 --- a/sysdeps/sparc/sparc32/soft-fp/q_fge.c +++ b/sysdeps/sparc/sparc32/soft-fp/q_fge.c @@ -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); diff --git a/sysdeps/sparc/sparc32/soft-fp/q_fgt.c b/sysdeps/sparc/sparc32/soft-fp/q_fgt.c index f5b2acf4c4..00f837d02e 100644 --- a/sysdeps/sparc/sparc32/soft-fp/q_fgt.c +++ b/sysdeps/sparc/sparc32/soft-fp/q_fgt.c @@ -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); diff --git a/sysdeps/sparc/sparc32/soft-fp/q_fle.c b/sysdeps/sparc/sparc32/soft-fp/q_fle.c index c108fb9e3f..b44f4484d8 100644 --- a/sysdeps/sparc/sparc32/soft-fp/q_fle.c +++ b/sysdeps/sparc/sparc32/soft-fp/q_fle.c @@ -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); diff --git a/sysdeps/sparc/sparc32/soft-fp/q_flt.c b/sysdeps/sparc/sparc32/soft-fp/q_flt.c index 56d140e6e9..caa188d72c 100644 --- a/sysdeps/sparc/sparc32/soft-fp/q_flt.c +++ b/sysdeps/sparc/sparc32/soft-fp/q_flt.c @@ -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); diff --git a/sysdeps/sparc/sparc32/soft-fp/q_fne.c b/sysdeps/sparc/sparc32/soft-fp/q_fne.c index 78c2d6f971..e22f6c987a 100644 --- a/sysdeps/sparc/sparc32/soft-fp/q_fne.c +++ b/sysdeps/sparc/sparc32/soft-fp/q_fne.c @@ -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; |