From 5b5b04d6282df0364424c6f2c0462e5c1a4394b0 Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Sat, 3 Nov 2012 19:48:53 +0000 Subject: Make fma use of Dekker and Knuth algorithms use round-to-nearest (bug 14796). --- sysdeps/i386/fpu/fenv_private.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'sysdeps/i386/fpu/fenv_private.h') 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 @@ -76,6 +76,24 @@ libc_feholdexcept_387 (fenv_t *e) "st(4)", "st(5)", "st(6)", "st(7)"); } +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) { @@ -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 -- cgit v1.2.3-70-g09d2