aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/i386
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2012-11-03 19:48:53 +0000
committerJoseph Myers <joseph@codesourcery.com>2012-11-03 19:48:53 +0000
commit5b5b04d6282df0364424c6f2c0462e5c1a4394b0 (patch)
treebef8cb91fffbf78e56f18479234abb47ce3054b2 /sysdeps/i386
parentfbeafedeea37e0af1984a6511018d159f5ceed6a (diff)
downloadglibc-5b5b04d6282df0364424c6f2c0462e5c1a4394b0.tar
glibc-5b5b04d6282df0364424c6f2c0462e5c1a4394b0.tar.gz
glibc-5b5b04d6282df0364424c6f2c0462e5c1a4394b0.tar.bz2
glibc-5b5b04d6282df0364424c6f2c0462e5c1a4394b0.zip
Make fma use of Dekker and Knuth algorithms use round-to-nearest (bug 14796).
Diffstat (limited to 'sysdeps/i386')
-rw-r--r--sysdeps/i386/fpu/fclrexcpt.c3
-rw-r--r--sysdeps/i386/fpu/fenv_private.h23
2 files changed, 25 insertions, 1 deletions
diff --git a/sysdeps/i386/fpu/fclrexcpt.c b/sysdeps/i386/fpu/fclrexcpt.c
index f24d07f3d1..f28ef6b3fa 100644
--- a/sysdeps/i386/fpu/fclrexcpt.c
+++ b/sysdeps/i386/fpu/fclrexcpt.c
@@ -1,5 +1,5 @@
/* Clear given exceptions in current floating-point environment.
- Copyright (C) 1997,99,2000, 2001, 2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 1997-2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -65,4 +65,5 @@ strong_alias (__feclearexcept, __old_feclearexcept)
compat_symbol (libm, __old_feclearexcept, feclearexcept, GLIBC_2_1);
#endif
+libm_hidden_ver (__feclearexcept, feclearexcept)
versioned_symbol (libm, __feclearexcept, feclearexcept, GLIBC_2_2);
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