diff options
author | Richard Henderson <rth@twiddle.net> | 2012-03-10 08:53:05 -0800 |
---|---|---|
committer | Richard Henderson <rth@twiddle.net> | 2012-03-19 06:50:41 -0700 |
commit | 0fe0f1f86f82f9e08ca4d4b85111de03f4c2f876 (patch) | |
tree | b7daee8ebf19cc6f493921a1862408ef166b6b14 /sysdeps/x86_64/fpu/math_private.h | |
parent | eb92c487b35e26aa1e08815c4480d0bc5cc9f370 (diff) | |
download | glibc-0fe0f1f86f82f9e08ca4d4b85111de03f4c2f876.tar.gz glibc-0fe0f1f86f82f9e08ca4d4b85111de03f4c2f876.tar.xz glibc-0fe0f1f86f82f9e08ca4d4b85111de03f4c2f876.zip |
Create and use libc_feupdateenv_test.
We can reduce the number of STMXCSR, and often we can avoid the call to __feraiseexcept.
Diffstat (limited to 'sysdeps/x86_64/fpu/math_private.h')
-rw-r--r-- | sysdeps/x86_64/fpu/math_private.h | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/sysdeps/x86_64/fpu/math_private.h b/sysdeps/x86_64/fpu/math_private.h index 3289afc58b..aa208b2e18 100644 --- a/sysdeps/x86_64/fpu/math_private.h +++ b/sysdeps/x86_64/fpu/math_private.h @@ -108,13 +108,33 @@ libc_fesetenv (fenv_t *e) #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) { - unsigned int mxcsr; - asm volatile (STMXCSR " %0" : "=m" (*&mxcsr)); - asm volatile (LDMXCSR " %0" : : "m" ((e)->__mxcsr)); - __feraiseexcept (mxcsr & FE_ALL_EXCEPT); + libc_feupdateenv_test (e, 0); } #define libc_feupdateenv libc_feupdateenv #define libc_feupdateenvf libc_feupdateenv |