diff options
author | Richard Henderson <rth@twiddle.net> | 2012-03-18 15:58:00 -0700 |
---|---|---|
committer | Richard Henderson <rth@twiddle.net> | 2012-03-19 06:51:39 -0700 |
commit | bd37f2ee314147c69a39817d590149cf1181ef47 (patch) | |
tree | 453f01145f7e526a6f5fdd5f3a6c1dde93f59ce8 /sysdeps/x86_64/fpu/math_private.h | |
parent | d0adc9223031b606c3c7781b4ec41462796ab313 (diff) | |
download | glibc-bd37f2ee314147c69a39817d590149cf1181ef47.tar.gz glibc-bd37f2ee314147c69a39817d590149cf1181ef47.tar.xz glibc-bd37f2ee314147c69a39817d590149cf1181ef47.zip |
Optimize private 387 fenv access; share code between i386 and x86_64.
Diffstat (limited to 'sysdeps/x86_64/fpu/math_private.h')
-rw-r--r-- | sysdeps/x86_64/fpu/math_private.h | 120 |
1 files changed, 1 insertions, 119 deletions
diff --git a/sysdeps/x86_64/fpu/math_private.h b/sysdeps/x86_64/fpu/math_private.h index aa208b2e18..67c5f6a324 100644 --- a/sysdeps/x86_64/fpu/math_private.h +++ b/sysdeps/x86_64/fpu/math_private.h @@ -1,33 +1,12 @@ #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)) \ - __asm ("" : "=x" (__x) : "0" (x)); \ - else \ - __asm ("" : "=t" (__x) : "0" (x)); \ - __x; }) -#define math_force_eval(x) \ - do { \ - if (sizeof (x) <= sizeof (double)) \ - __asm __volatile ("" : : "x" (x)); \ - else \ - __asm __volatile ("" : : "f" (x)); \ - } while (0) - /* We can do a few things better on x86-64. */ #if defined __AVX__ || defined SSE2AVX # define MOVD "vmovd" -# define STMXCSR "vstmxcsr" -# define LDMXCSR "vldmxcsr" #else # define MOVD "movd" -# define STMXCSR "stmxcsr" -# define LDMXCSR "ldmxcsr" #endif /* Direct movement of float into integer register. */ @@ -64,104 +43,7 @@ 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 int -libc_feupdateenv_test (fenv_t *e, int ex) -{ - unsigned int mxcsr, old_mxcsr, cur_ex; - asm volatile (STMXCSR " %0" : "=m" (*&mxcsr)); - cur_ex = mxcsr & FE_ALL_EXCEPT; - - /* Merge current exceptions with the old environment. */ - old_mxcsr = e->__mxcsr; - mxcsr = old_mxcsr | cur_ex; - asm volatile (LDMXCSR " %0" : : "m" (*&mxcsr)); - - /* Raise SIGFPE for any new exceptions since the hold. Expect that - the normal environment has all exceptions masked. */ - if (__builtin_expect ((old_mxcsr >> 7) & cur_ex, 0)) - __feraiseexcept (cur_ex); - - /* Test for exceptions raised since the hold. */ - return cur_ex & ex; -} -#define libc_feupdateenv_test libc_feupdateenv_test -#define libc_feupdateenv_testf libc_feupdateenv_test - -static __always_inline void -libc_feupdateenv (fenv_t *e) -{ - libc_feupdateenv_test (e, 0); -} -#define libc_feupdateenv libc_feupdateenv -#define libc_feupdateenvf libc_feupdateenv - -static __always_inline void -libc_feholdsetround (fenv_t *e, int r) -{ - unsigned int mxcsr; - asm (STMXCSR " %0" : "=m" (*&mxcsr)); - e->__mxcsr = mxcsr; - mxcsr = (mxcsr & ~0x6000) | (r << 3); - asm volatile (LDMXCSR " %0" : : "m" (*&mxcsr)); -} -#define libc_feholdsetround libc_feholdsetround -#define libc_feholdsetroundf libc_feholdsetround - -static __always_inline void -libc_feresetround (fenv_t *e) -{ - unsigned int mxcsr; - asm (STMXCSR " %0" : "=m" (*&mxcsr)); - mxcsr = (mxcsr & ~0x6000) | (e->__mxcsr & 0x6000); - asm volatile (LDMXCSR " %0" : : "m" (*&mxcsr)); -} -#define libc_feresetround libc_feresetround -#define libc_feresetroundf libc_feresetround - +#include <sysdeps/i386/fpu/fenv_private.h> #include_next <math_private.h> extern __always_inline double |