diff options
-rw-r--r-- | ChangeLog | 18 | ||||
-rw-r--r-- | sysdeps/generic/math_private.h | 99 | ||||
-rw-r--r-- | sysdeps/x86_64/fpu/math_private.h | 114 |
3 files changed, 153 insertions, 78 deletions
diff --git a/ChangeLog b/ChangeLog index 43e241526b..2d6d574804 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,23 @@ 2012-03-19 Richard Henderson <rth@twiddle.net> + * sysdeps/generic/math_private.h: Include <fenv.h>. + (default_libc_feholdexcept): New. + (default_libc_feholdexcept_setround): New. + (default_libc_fesetenv, default_libc_feupdateenv): New. + (libc_feholdexcept): Only define if undefined. + (libc_feholdexceptf, libc_feholdexceptl): Likewise. + (libc_feholdexcept_setround, libc_feholdexcept_setroundf): Likewise. + (libc_feholdexcept_setroundl): Likewise. + (libc_feholdexcept_setround_53bit): Likewise. + (libc_fetestexcept, libc_fetestexceptf, libc_fetestexceptl): Likewise. + (libc_fesetenv, libc_fesetenvf, libc_fesetenvl): Likewise. + (libc_feupdateenv, libc_feupdateenvf, libc_feupdateenvl): Likewise. + (libc_feupdateenv_53bit): Likewise. + * sysdeps/x86_64/fpu/math_private.h: Include <fenv.h>. + (libc_feholdexcept): Convert from macro to inline function. + (libc_feholdexcept_setround, libc_fetestexcept): Likewise. + (libc_fesetenv, libc_feupdateenv): Likewise. + * sysdeps/generic/math_private.h (GET_HIGH_WORD): Define only if not previously defined. (GET_LOW_WORD, EXTRACT_WORDS64, INSERT_WORDS): Likewise. diff --git a/sysdeps/generic/math_private.h b/sysdeps/generic/math_private.h index 908e6b7901..ab4b47bfe0 100644 --- a/sysdeps/generic/math_private.h +++ b/sysdeps/generic/math_private.h @@ -19,6 +19,7 @@ #include <endian.h> #include <stdint.h> #include <sys/types.h> +#include <fenv.h> /* The original fdlibm code used statements like: n0 = ((*(int*)&one)>>29)^1; * index of high word * @@ -372,33 +373,89 @@ extern void __docos (double __x, double __dx, double __v[]); know what operations are going to be performed. Therefore we define additional interfaces. By default they refer to the normal interfaces. */ -#define libc_feholdexcept(e) (void) feholdexcept (e) -#define libc_feholdexceptf(e) (void) feholdexcept (e) -#define libc_feholdexceptl(e) (void) feholdexcept (e) -#define libc_feholdexcept_setround(e, r) \ - do { feholdexcept (e); fesetround (r); } while (0) -#define libc_feholdexcept_setroundf(e, r) \ - do { feholdexcept (e); fesetround (r); } while (0) -#define libc_feholdexcept_setroundl(e, r) \ - do { feholdexcept (e); fesetround (r); } while (0) +static __always_inline void +default_libc_feholdexcept (fenv_t *e) +{ + (void) feholdexcept (e); +} + +#ifndef libc_feholdexcept +# define libc_feholdexcept default_libc_feholdexcept +#endif +#ifndef libc_feholdexceptf +# define libc_feholdexceptf default_libc_feholdexcept +#endif +#ifndef libc_feholdexceptl +# define libc_feholdexceptl default_libc_feholdexcept +#endif + +static __always_inline void +default_libc_feholdexcept_setround (fenv_t *e, int r) +{ + feholdexcept (e); + fesetround (r); +} + +#ifndef libc_feholdexcept_setround +# define libc_feholdexcept_setround default_libc_feholdexcept_setround +#endif +#ifndef libc_feholdexcept_setroundf +# define libc_feholdexcept_setroundf default_libc_feholdexcept_setround +#endif +#ifndef libc_feholdexcept_setroundl +# define libc_feholdexcept_setroundl default_libc_feholdexcept_setround +#endif + +#ifndef libc_feholdexcept_setround_53bit +# define libc_feholdexcept_setround_53bit libc_feholdexcept_setround +#endif -#define libc_feholdexcept_setround_53bit(e, r) \ - libc_feholdexcept_setround (e, r) +#ifndef libc_fetestexcept +# define libc_fetestexcept fetestexcept +#endif +#ifndef libc_fetestexceptf +# define libc_fetestexceptf fetestexcept +#endif +#ifndef libc_fetestexceptl +# define libc_fetestexceptl fetestexcept +#endif -#define libc_fetestexcept(e) fetestexcept (e) -#define libc_fetestexceptf(e) fetestexcept (e) -#define libc_fetestexceptl(e) fetestexcept (e) +static __always_inline void +default_libc_fesetenv (fenv_t *e) +{ + (void) fesetenv (e); +} -#define libc_fesetenv(e) (void) fesetenv (e) -#define libc_fesetenvf(e) (void) fesetenv (e) -#define libc_fesetenvl(e) (void) fesetenv (e) +#ifndef libc_fesetenv +# define libc_fesetenv default_libc_fesetenv +#endif +#ifndef libc_fesetenvf +# define libc_fesetenvf default_libc_fesetenv +#endif +#ifndef libc_fesetenvl +# define libc_fesetenvl default_libc_fesetenv +#endif -#define libc_feupdateenv(e) (void) feupdateenv (e) -#define libc_feupdateenvf(e) (void) feupdateenv (e) -#define libc_feupdateenvl(e) (void) feupdateenv (e) +static __always_inline void +default_libc_feupdateenv (fenv_t *e) +{ + (void) feupdateenv (e); +} + +#ifndef libc_feupdateenv +# define libc_feupdateenv default_libc_feupdateenv +#endif +#ifndef libc_feupdateenvf +# define libc_feupdateenvf default_libc_feupdateenv +#endif +#ifndef libc_feupdateenvl +# define libc_feupdateenvl default_libc_feupdateenv +#endif -#define libc_feupdateenv_53bit(e) libc_feupdateenv (e) +#ifndef libc_feupdateenv_53bit +# define libc_feupdateenv_53bit libc_feupdateenv +#endif #define __nan(str) \ (__builtin_constant_p (str) && str[0] == '\0' ? NAN : __nan (str)) diff --git a/sysdeps/x86_64/fpu/math_private.h b/sysdeps/x86_64/fpu/math_private.h index dae9ccca68..8b1fe70d2c 100644 --- a/sysdeps/x86_64/fpu/math_private.h +++ b/sysdeps/x86_64/fpu/math_private.h @@ -1,6 +1,8 @@ #ifndef X86_64_MATH_PRIVATE_H #define X86_64_MATH_PRIVATE_H 1 +#include <fenv.h> + #define math_opt_barrier(x) \ ({ __typeof(x) __x; \ if (sizeof (x) <= sizeof (double)) \ @@ -62,6 +64,61 @@ f = f__; \ } while (0) +/* Specialized variants of the <fenv.h> interfaces which only handle + either the FPU or the SSE unit. */ +static __always_inline void +libc_feholdexcept (fenv_t *e) +{ + unsigned int mxcsr; + asm (STMXCSR " %0" : "=m" (*&mxcsr)); + e->__mxcsr = mxcsr; + mxcsr = (mxcsr | 0x1f80) & ~0x3f; + asm volatile (LDMXCSR " %0" : : "m" (*&mxcsr)); +} +#define libc_feholdexcept libc_feholdexcept +#define libc_feholdexceptf libc_feholdexcept + +static __always_inline void +libc_feholdexcept_setround (fenv_t *e, int r) +{ + unsigned int mxcsr; + asm (STMXCSR " %0" : "=m" (*&mxcsr)); + e->__mxcsr = mxcsr; + mxcsr = ((mxcsr | 0x1f80) & ~0x603f) | (r << 3); + asm volatile (LDMXCSR " %0" : : "m" (*&mxcsr)); +} +#define libc_feholdexcept_setround libc_feholdexcept_setround +#define libc_feholdexcept_setroundf libc_feholdexcept_setround + +static __always_inline int +libc_fetestexcept (int e) +{ + unsigned int mxcsr; + asm volatile (STMXCSR " %0" : "=m" (*&mxcsr)); + return mxcsr & e & FE_ALL_EXCEPT; +} +#define libc_fetestexcept libc_fetestexcept +#define libc_fetestexceptf libc_fetestexcept + +static __always_inline void +libc_fesetenv (fenv_t *e) +{ + asm volatile (LDMXCSR " %0" : : "m" (e->__mxcsr)); +} +#define libc_fesetenv libc_fesetenv +#define libc_fesetenvf libc_fesetenv + +static __always_inline void +libc_feupdateenv (fenv_t *e) +{ + unsigned int mxcsr; + asm volatile (STMXCSR " %0" : "=m" (*&mxcsr)); + asm volatile (LDMXCSR " %0" : : "m" ((e)->__mxcsr)); + __feraiseexcept (mxcsr & FE_ALL_EXCEPT); +} +#define libc_feupdateenv libc_feupdateenv +#define libc_feupdateenvf libc_feupdateenv + #include_next <math_private.h> extern __always_inline double @@ -146,61 +203,4 @@ __floorf (float d) } #endif /* __SSE4_1__ */ - -/* Specialized variants of the <fenv.h> interfaces which only handle - either the FPU or the SSE unit. */ -#undef libc_feholdexcept -#define libc_feholdexcept(e) \ - do { \ - unsigned int mxcsr; \ - asm (STMXCSR " %0" : "=m" (*&mxcsr)); \ - (e)->__mxcsr = mxcsr; \ - mxcsr = (mxcsr | 0x1f80) & ~0x3f; \ - asm volatile (LDMXCSR " %0" : : "m" (*&mxcsr)); \ - } while (0) -#undef libc_feholdexceptf -#define libc_feholdexceptf(e) libc_feholdexcept (e) -// #define libc_feholdexceptl(e) (void) feholdexcept (e) - -#undef libc_feholdexcept_setround -#define libc_feholdexcept_setround(e, r) \ - do { \ - unsigned int mxcsr; \ - asm (STMXCSR " %0" : "=m" (*&mxcsr)); \ - (e)->__mxcsr = mxcsr; \ - mxcsr = ((mxcsr | 0x1f80) & ~0x603f) | ((r) << 3); \ - asm volatile (LDMXCSR " %0" : : "m" (*&mxcsr)); \ - } while (0) -#undef libc_feholdexcept_setroundf -#define libc_feholdexcept_setroundf(e, r) libc_feholdexcept_setround (e, r) -// #define libc_feholdexcept_setroundl(e, r) ... - -#undef libc_fetestexcept -#define libc_fetestexcept(e) \ - ({ unsigned int mxcsr; \ - asm volatile (STMXCSR " %0" : "=m" (*&mxcsr)); \ - mxcsr & (e) & FE_ALL_EXCEPT; }) -#undef libc_fetestexceptf -#define libc_fetestexceptf(e) libc_fetestexcept (e) -// #define libc_fetestexceptl(e) fetestexcept (e) - -#undef libc_fesetenv -#define libc_fesetenv(e) \ - asm volatile (LDMXCSR " %0" : : "m" ((e)->__mxcsr)) -#undef libc_fesetenvf -#define libc_fesetenvf(e) libc_fesetenv (e) -// #define libc_fesetenvl(e) (void) fesetenv (e) - -#undef libc_feupdateenv -#define libc_feupdateenv(e) \ - do { \ - unsigned int mxcsr; \ - asm volatile (STMXCSR " %0" : "=m" (*&mxcsr)); \ - asm volatile (LDMXCSR " %0" : : "m" ((e)->__mxcsr)); \ - __feraiseexcept (mxcsr & FE_ALL_EXCEPT); \ - } while (0) -#undef libc_feupdateenvf -#define libc_feupdateenvf(e) libc_feupdateenv (e) -// #define libc_feupdateenvl(e) (void) feupdateenv (e) - #endif /* X86_64_MATH_PRIVATE_H */ |