diff options
author | Richard Henderson <rth@twiddle.net> | 2012-03-09 12:38:23 -0800 |
---|---|---|
committer | Richard Henderson <rth@twiddle.net> | 2012-03-19 06:47:43 -0700 |
commit | 4851a949b4cd1f280b56a728c784aaa85e51124c (patch) | |
tree | 331199de9e22e6be357e697a035fb255d89f62e3 /sysdeps | |
parent | e79d442ee64ef2426ddd29a1fe1174108e845b69 (diff) | |
download | glibc-4851a949b4cd1f280b56a728c784aaa85e51124c.tar.gz glibc-4851a949b4cd1f280b56a728c784aaa85e51124c.tar.xz glibc-4851a949b4cd1f280b56a728c784aaa85e51124c.zip |
Make inline __isnan, __isinf_ns, __finite generic.
For code generation to stay identical on x86_64, this requires that we define the fp word manipulation macros before including the generic header.
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/generic/math_private.h | 39 | ||||
-rw-r--r-- | sysdeps/ieee754/dbl-64/wordsize-64/math_private.h | 35 | ||||
-rw-r--r-- | sysdeps/ieee754/flt-32/math_private.h | 35 | ||||
-rw-r--r-- | sysdeps/x86_64/fpu/math_private.h | 28 |
4 files changed, 97 insertions, 40 deletions
diff --git a/sysdeps/generic/math_private.h b/sysdeps/generic/math_private.h index be1e4d2314..908e6b7901 100644 --- a/sysdeps/generic/math_private.h +++ b/sysdeps/generic/math_private.h @@ -76,50 +76,59 @@ do { \ /* Get the more significant 32 bit int from a double. */ -#define GET_HIGH_WORD(i,d) \ +#ifndef GET_HIGH_WORD +# define GET_HIGH_WORD(i,d) \ do { \ ieee_double_shape_type gh_u; \ gh_u.value = (d); \ (i) = gh_u.parts.msw; \ } while (0) +#endif /* Get the less significant 32 bit int from a double. */ -#define GET_LOW_WORD(i,d) \ +#ifndef GET_LOW_WORD +# define GET_LOW_WORD(i,d) \ do { \ ieee_double_shape_type gl_u; \ gl_u.value = (d); \ (i) = gl_u.parts.lsw; \ } while (0) +#endif /* Get all in one, efficient on 64-bit machines. */ -#define EXTRACT_WORDS64(i,d) \ +#ifndef EXTRACT_WORDS64 +# define EXTRACT_WORDS64(i,d) \ do { \ ieee_double_shape_type gh_u; \ gh_u.value = (d); \ (i) = gh_u.word; \ } while (0) +#endif /* Set a double from two 32 bit ints. */ - -#define INSERT_WORDS(d,ix0,ix1) \ +#ifndef INSERT_WORDS +# define INSERT_WORDS(d,ix0,ix1) \ do { \ ieee_double_shape_type iw_u; \ iw_u.parts.msw = (ix0); \ iw_u.parts.lsw = (ix1); \ (d) = iw_u.value; \ } while (0) +#endif /* Get all in one, efficient on 64-bit machines. */ -#define INSERT_WORDS64(d,i) \ +#ifndef INSERT_WORDS64 +# define INSERT_WORDS64(d,i) \ do { \ ieee_double_shape_type iw_u; \ iw_u.word = (i); \ (d) = iw_u.value; \ } while (0) +#endif /* Set the more significant 32 bits of a double from an int. */ - +#ifndef SET_HIGH_WORD #define SET_HIGH_WORD(d,v) \ do { \ ieee_double_shape_type sh_u; \ @@ -127,16 +136,18 @@ do { \ sh_u.parts.msw = (v); \ (d) = sh_u.value; \ } while (0) +#endif /* Set the less significant 32 bits of a double from an int. */ - -#define SET_LOW_WORD(d,v) \ +#ifndef SET_LOW_WORD +# define SET_LOW_WORD(d,v) \ do { \ ieee_double_shape_type sl_u; \ sl_u.value = (d); \ sl_u.parts.lsw = (v); \ (d) = sl_u.value; \ } while (0) +#endif /* A union which permits us to convert between a float and a 32 bit int. */ @@ -148,22 +159,24 @@ typedef union } ieee_float_shape_type; /* Get a 32 bit int from a float. */ - -#define GET_FLOAT_WORD(i,d) \ +#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. */ - -#define SET_FLOAT_WORD(d,i) \ +#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 /* Get long double macros from a separate header. */ #include <math_ldbl.h> diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/math_private.h b/sysdeps/ieee754/dbl-64/wordsize-64/math_private.h new file mode 100644 index 0000000000..b66085eb1b --- /dev/null +++ b/sysdeps/ieee754/dbl-64/wordsize-64/math_private.h @@ -0,0 +1,35 @@ +#ifndef _MATH_PRIVATE_H_ + +#include_next <math_private.h> + +#ifndef __isnan +extern __always_inline int +__isnan (double d) +{ + uint64_t di; + EXTRACT_WORDS64 (di, d); + return (di & 0x7fffffffffffffffull) > 0x7ff0000000000000ull; +} +#endif + +#ifndef __isinf_ns +extern __always_inline int +__isinf_ns (double d) +{ + uint64_t di; + EXTRACT_WORDS64 (di, d); + return (di & 0x7fffffffffffffffull) == 0x7ff0000000000000ull; +} +#endif + +#ifndef __finite +extern __always_inline int +__finite (double d) +{ + uint64_t di; + EXTRACT_WORDS64 (di, d); + return (di & 0x7fffffffffffffffull) < 0x7ff0000000000000ull; +} +#endif + +#endif /* _MATH_PRIVATE_H_ */ diff --git a/sysdeps/ieee754/flt-32/math_private.h b/sysdeps/ieee754/flt-32/math_private.h new file mode 100644 index 0000000000..e33db02b4c --- /dev/null +++ b/sysdeps/ieee754/flt-32/math_private.h @@ -0,0 +1,35 @@ +#ifndef _MATH_PRIVATE_H_ + +#include_next <math_private.h> + +#ifndef __isnanf +extern __always_inline int +__isnanf (float d) +{ + u_int32_t di; + GET_FLOAT_WORD (di, d); + return (di & 0x7fffffff) > 0x7f800000; +} +#endif + +#ifndef __isinf_nsf +extern __always_inline int +__isinf_nsf (float d) +{ + u_int32_t di; + GET_FLOAT_WORD (di, d); + return (di & 0x7fffffff) == 0x7f800000; +} +#endif + +#ifndef __finitef +extern __always_inline int +__finitef (float d) +{ + u_int32_t di; + GET_FLOAT_WORD (di, d); + return (di & 0x7fffffff) < 0x7f800000; +} +#endif + +#endif /* _MATH_PRIVATE_H_ */ diff --git a/sysdeps/x86_64/fpu/math_private.h b/sysdeps/x86_64/fpu/math_private.h index c8616f654a..dae9ccca68 100644 --- a/sysdeps/x86_64/fpu/math_private.h +++ b/sysdeps/x86_64/fpu/math_private.h @@ -16,8 +16,6 @@ __asm __volatile ("" : : "f" (x)); \ } while (0) -#include_next <math_private.h> - /* We can do a few things better on x86-64. */ #if defined __AVX__ || defined SSE2AVX @@ -31,7 +29,6 @@ #endif /* Direct movement of float into integer register. */ -#undef EXTRACT_WORDS64 #define EXTRACT_WORDS64(i, d) \ do { \ long int i_; \ @@ -40,7 +37,6 @@ } while (0) /* And the reverse. */ -#undef INSERT_WORDS64 #define INSERT_WORDS64(d, i) \ do { \ long int i_ = i; \ @@ -50,7 +46,6 @@ } while (0) /* Direct movement of float into integer register. */ -#undef GET_FLOAT_WORD #define GET_FLOAT_WORD(i, d) \ do { \ int i_; \ @@ -59,7 +54,6 @@ } while (0) /* And the reverse. */ -#undef SET_FLOAT_WORD #define SET_FLOAT_WORD(f, i) \ do { \ int i_ = i; \ @@ -68,27 +62,7 @@ f = f__; \ } while (0) - -#define __isnan(d) \ - ({ long int __di; EXTRACT_WORDS64 (__di, (double) (d)); \ - (__di & 0x7fffffffffffffffl) > 0x7ff0000000000000l; }) -#define __isnanf(d) \ - ({ int __di; GET_FLOAT_WORD (__di, (float) d); \ - (__di & 0x7fffffff) > 0x7f800000; }) - -#define __isinf_ns(d) \ - ({ long int __di; EXTRACT_WORDS64 (__di, (double) (d)); \ - (__di & 0x7fffffffffffffffl) == 0x7ff0000000000000l; }) -#define __isinf_nsf(d) \ - ({ int __di; GET_FLOAT_WORD (__di, (float) d); \ - (__di & 0x7fffffff) == 0x7f800000; }) - -#define __finite(d) \ - ({ long int __di; EXTRACT_WORDS64 (__di, (double) (d)); \ - (__di & 0x7fffffffffffffffl) < 0x7ff0000000000000l; }) -#define __finitef(d) \ - ({ int __di; GET_FLOAT_WORD (__di, (float) d); \ - (__di & 0x7fffffff) < 0x7f800000; }) +#include_next <math_private.h> extern __always_inline double __ieee754_sqrt (double d) |