diff options
author | Paul A. Clarke <pc@us.ibm.com> | 2019-11-21 09:39:48 -0600 |
---|---|---|
committer | Paul A. Clarke <pc@us.ibm.com> | 2019-11-21 09:39:48 -0600 |
commit | 854e91bf6b4221f424ffa13b9ef50f35623b7b74 (patch) | |
tree | 77f05d1ccb4fff9f7fbde5853b6ad847995771e2 /include/math.h | |
parent | fcb04b9aed26a737159ef7be9c5a6ad0994437dc (diff) | |
download | glibc-854e91bf6b4221f424ffa13b9ef50f35623b7b74.tar.gz glibc-854e91bf6b4221f424ffa13b9ef50f35623b7b74.tar.xz glibc-854e91bf6b4221f424ffa13b9ef50f35623b7b74.zip |
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>
Diffstat (limited to 'include/math.h')
-rw-r--r-- | include/math.h | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/include/math.h b/include/math.h index 79ebbae359..a274f2bdfd 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. */ |