aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul A. Clarke <pc@us.ibm.com>2019-11-21 09:39:48 -0600
committerPaul A. Clarke <pc@us.ibm.com>2019-11-21 09:39:48 -0600
commit854e91bf6b4221f424ffa13b9ef50f35623b7b74 (patch)
tree77f05d1ccb4fff9f7fbde5853b6ad847995771e2
parentfcb04b9aed26a737159ef7be9c5a6ad0994437dc (diff)
downloadglibc-854e91bf6b4221f424ffa13b9ef50f35623b7b74.zip
glibc-854e91bf6b4221f424ffa13b9ef50f35623b7b74.tar.gz
glibc-854e91bf6b4221f424ffa13b9ef50f35623b7b74.tar.bz2
Enable inlining issignalingf within glibc
issignalingf is a very small function used in some areas where better performance (and smaller code) might be helpful. Create inline implementation for issignalingf. Reviewed-by: Joseph Myers <joseph@codesourcery.com>
-rw-r--r--include/math.h53
-rw-r--r--sysdeps/generic/math_private.h29
2 files changed, 53 insertions, 29 deletions
diff --git a/include/math.h b/include/math.h
index 79ebbae..a274f2b 100644
--- a/include/math.h
+++ b/include/math.h
@@ -54,6 +54,59 @@ libm_hidden_proto (__expf128)
libm_hidden_proto (__expm1f128)
# endif
+#include <stdint.h>
+#include <nan-high-order-bit.h>
+
+/* A union which permits us to convert between a float and a 32 bit
+ int. */
+
+typedef union
+{
+ float value;
+ uint32_t word;
+} ieee_float_shape_type;
+
+/* Get a 32 bit int from a float. */
+#ifndef GET_FLOAT_WORD
+# define GET_FLOAT_WORD(i,d) \
+do { \
+ ieee_float_shape_type gf_u; \
+ gf_u.value = (d); \
+ (i) = gf_u.word; \
+} while (0)
+#endif
+
+/* Set a float from a 32 bit int. */
+#ifndef SET_FLOAT_WORD
+# define SET_FLOAT_WORD(d,i) \
+do { \
+ ieee_float_shape_type sf_u; \
+ sf_u.word = (i); \
+ (d) = sf_u.value; \
+} while (0)
+#endif
+
+extern inline int
+__issignalingf (float x)
+{
+ uint32_t xi;
+ GET_FLOAT_WORD (xi, x);
+#if HIGH_ORDER_BIT_IS_SET_FOR_SNAN
+ /* We only have to care about the high-order bit of x's significand, because
+ having it set (sNaN) already makes the significand different from that
+ used to designate infinity. */
+ return (xi & 0x7fc00000) == 0x7fc00000;
+#else
+ /* To keep the following comparison simple, toggle the quiet/signaling bit,
+ so that it is set for sNaNs. This is inverse to IEEE 754-2008 (as well as
+ common practice for IEEE 754-1985). */
+ xi ^= 0x00400000;
+ /* We have to compare for greater (instead of greater or equal), because x's
+ significand being all-zero designates infinity not NaN. */
+ return (xi & 0x7fffffff) > 0x7fc00000;
+#endif
+}
+
# if __HAVE_DISTINCT_FLOAT128
/* __builtin_isinf_sign is broken in GCC < 7 for float128. */
diff --git a/sysdeps/generic/math_private.h b/sysdeps/generic/math_private.h
index d91b929..9296324 100644
--- a/sysdeps/generic/math_private.h
+++ b/sysdeps/generic/math_private.h
@@ -153,35 +153,6 @@ do { \
} while (0)
#endif
-/* A union which permits us to convert between a float and a 32 bit
- int. */
-
-typedef union
-{
- float value;
- uint32_t word;
-} ieee_float_shape_type;
-
-/* Get a 32 bit int from a float. */
-#ifndef GET_FLOAT_WORD
-# define GET_FLOAT_WORD(i,d) \
-do { \
- ieee_float_shape_type gf_u; \
- gf_u.value = (d); \
- (i) = gf_u.word; \
-} while (0)
-#endif
-
-/* Set a float from a 32 bit int. */
-#ifndef SET_FLOAT_WORD
-# define SET_FLOAT_WORD(d,i) \
-do { \
- ieee_float_shape_type sf_u; \
- sf_u.word = (i); \
- (d) = sf_u.value; \
-} while (0)
-#endif
-
/* We need to guarantee an expansion of name when building
ldbl-128 files as another type (e.g _Float128). */
#define mathx_hidden_def(name) hidden_def(name)