diff options
author | Joseph Myers <joseph@codesourcery.com> | 2012-11-03 19:48:53 +0000 |
---|---|---|
committer | Joseph Myers <joseph@codesourcery.com> | 2012-11-03 19:48:53 +0000 |
commit | 5b5b04d6282df0364424c6f2c0462e5c1a4394b0 (patch) | |
tree | bef8cb91fffbf78e56f18479234abb47ce3054b2 /sysdeps/i386/fpu/fenv_private.h | |
parent | fbeafedeea37e0af1984a6511018d159f5ceed6a (diff) | |
download | glibc-5b5b04d6282df0364424c6f2c0462e5c1a4394b0.tar.gz glibc-5b5b04d6282df0364424c6f2c0462e5c1a4394b0.tar.xz glibc-5b5b04d6282df0364424c6f2c0462e5c1a4394b0.zip |
Make fma use of Dekker and Knuth algorithms use round-to-nearest (bug 14796).
Diffstat (limited to 'sysdeps/i386/fpu/fenv_private.h')
-rw-r--r-- | sysdeps/i386/fpu/fenv_private.h | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/sysdeps/i386/fpu/fenv_private.h b/sysdeps/i386/fpu/fenv_private.h index f33f57c39c..03f4c97a9c 100644 --- a/sysdeps/i386/fpu/fenv_private.h +++ b/sysdeps/i386/fpu/fenv_private.h @@ -77,6 +77,24 @@ libc_feholdexcept_387 (fenv_t *e) } static __always_inline void +libc_fesetround_sse (int r) +{ + unsigned int mxcsr; + asm (STMXCSR " %0" : "=m" (*&mxcsr)); + mxcsr = (mxcsr & ~0x6000) | (r << 3); + asm volatile (LDMXCSR " %0" : : "m" (*&mxcsr)); +} + +static __always_inline void +libc_fesetround_387 (int r) +{ + fpu_control_t cw; + _FPU_GETCW (cw); + cw = (cw & ~0xc00) | r; + _FPU_SETCW (cw); +} + +static __always_inline void libc_feholdexcept_setround_sse (fenv_t *e, int r) { unsigned int mxcsr; @@ -247,6 +265,7 @@ libc_feresetround_387 (fenv_t *e) #ifdef __SSE_MATH__ # define libc_feholdexceptf libc_feholdexcept_sse +# define libc_fesetroundf libc_fesetround_sse # define libc_feholdexcept_setroundf libc_feholdexcept_setround_sse # define libc_fetestexceptf libc_fetestexcept_sse # define libc_fesetenvf libc_fesetenv_sse @@ -256,6 +275,7 @@ libc_feresetround_387 (fenv_t *e) # define libc_feresetroundf libc_feresetround_sse #else # define libc_feholdexceptf libc_feholdexcept_387 +# define libc_fesetroundf libc_fesetround_387 # define libc_feholdexcept_setroundf libc_feholdexcept_setround_387 # define libc_fetestexceptf libc_fetestexcept_387 # define libc_fesetenvf libc_fesetenv_387 @@ -267,6 +287,7 @@ libc_feresetround_387 (fenv_t *e) #ifdef __SSE2_MATH__ # define libc_feholdexcept libc_feholdexcept_sse +# define libc_fesetround libc_fesetround_sse # define libc_feholdexcept_setround libc_feholdexcept_setround_sse # define libc_fetestexcept libc_fetestexcept_sse # define libc_fesetenv libc_fesetenv_sse @@ -276,6 +297,7 @@ libc_feresetround_387 (fenv_t *e) # define libc_feresetround libc_feresetround_sse #else # define libc_feholdexcept libc_feholdexcept_387 +# define libc_fesetround libc_fesetround_387 # define libc_feholdexcept_setround libc_feholdexcept_setround_387 # define libc_fetestexcept libc_fetestexcept_387 # define libc_fesetenv libc_fesetenv_387 @@ -286,6 +308,7 @@ libc_feresetround_387 (fenv_t *e) #endif /* __SSE2_MATH__ */ #define libc_feholdexceptl libc_feholdexcept_387 +#define libc_fesetroundl libc_fesetround_387 #define libc_feholdexcept_setroundl libc_feholdexcept_setround_387 #define libc_fetestexceptl libc_fetestexcept_387 #define libc_fesetenvl libc_fesetenv_387 |