diff options
author | Andreas Jaeger <aj@suse.de> | 2012-03-14 17:20:10 +0100 |
---|---|---|
committer | Andreas Jaeger <aj@suse.de> | 2012-03-14 17:20:10 +0100 |
commit | c4814b6b3a2b4f264a461a27667a139387968ee1 (patch) | |
tree | e2e5aed10a4ab7861c357f3a88abf8ffbd22451b | |
parent | 1e2405c8fa877d7cb3c06626c94356faaa7bd1e0 (diff) | |
download | glibc-c4814b6b3a2b4f264a461a27667a139387968ee1.zip glibc-c4814b6b3a2b4f264a461a27667a139387968ee1.tar.gz glibc-c4814b6b3a2b4f264a461a27667a139387968ee1.tar.bz2 |
Implement and use libc_feholdexcept_setround_53bit and libc_feupdateenv_53bit
so that double arithmetic in s_sin is done in 53 bit (without extend i386 double precision)
-rw-r--r-- | sysdeps/generic/math_private.h | 5 | ||||
-rw-r--r-- | sysdeps/i386/fpu/math_private.h | 29 | ||||
-rw-r--r-- | sysdeps/ieee754/dbl-64/s_sin.c | 10 |
3 files changed, 39 insertions, 5 deletions
diff --git a/sysdeps/generic/math_private.h b/sysdeps/generic/math_private.h index 777762d..be1e4d2 100644 --- a/sysdeps/generic/math_private.h +++ b/sysdeps/generic/math_private.h @@ -370,6 +370,9 @@ extern void __docos (double __x, double __dx, double __v[]); #define libc_feholdexcept_setroundl(e, r) \ do { feholdexcept (e); fesetround (r); } while (0) +#define libc_feholdexcept_setround_53bit(e, r) \ + libc_feholdexcept_setround (e, r) + #define libc_fetestexcept(e) fetestexcept (e) #define libc_fetestexceptf(e) fetestexcept (e) #define libc_fetestexceptl(e) fetestexcept (e) @@ -382,6 +385,8 @@ extern void __docos (double __x, double __dx, double __v[]); #define libc_feupdateenvf(e) (void) feupdateenv (e) #define libc_feupdateenvl(e) (void) feupdateenv (e) +#define libc_feupdateenv_53bit(e) libc_feupdateenv (e) + #define __nan(str) \ (__builtin_constant_p (str) && str[0] == '\0' ? NAN : __nan (str)) #define __nanf(str) \ diff --git a/sysdeps/i386/fpu/math_private.h b/sysdeps/i386/fpu/math_private.h index 5253998..d96996f 100644 --- a/sysdeps/i386/fpu/math_private.h +++ b/sysdeps/i386/fpu/math_private.h @@ -16,4 +16,33 @@ do \ while (0) #include_next <math_private.h> + +# include <fpu_control.h> + +# undef libc_feholdexcept_setround_53bit +# define libc_feholdexcept_setround_53bit(e, r) \ + do \ + { \ + fpu_control_t cw; \ + libc_feholdexcept_setround (e, r); \ + _FPU_GETCW (cw); \ + cw &= ~(fpu_control_t) _FPU_EXTENDED; \ + cw |= _FPU_DOUBLE; \ + _FPU_SETCW (cw); \ + } \ + while (0) + +# undef libc_feupdateenv_53bit +# define libc_feupdateenv_53bit(e) \ + do \ + { \ + fpu_control_t cw; \ + libc_feupdateenv (e); \ + _FPU_GETCW (cw); \ + cw &= ~(fpu_control_t) _FPU_EXTENDED; \ + cw |= _FPU_EXTENDED; \ + _FPU_SETCW (cw); \ + } \ + while (0) + #endif diff --git a/sysdeps/ieee754/dbl-64/s_sin.c b/sysdeps/ieee754/dbl-64/s_sin.c index e3e3a2a..4b4b675 100644 --- a/sysdeps/ieee754/dbl-64/s_sin.c +++ b/sysdeps/ieee754/dbl-64/s_sin.c @@ -1,7 +1,7 @@ /* * IBM Accurate Mathematical Library * written by International Business Machines Corp. - * Copyright (C) 2001, 2009, 2011 Free Software Foundation + * Copyright (C) 2001-2012 Free Software Foundation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -111,7 +111,7 @@ __sin(double x){ fenv_t env; double retval = 0; - libc_feholdexcept_setround (&env, FE_TONEAREST); + libc_feholdexcept_setround_53bit (&env, FE_TONEAREST); u.x = x; m = u.i[HIGH_HALF]; @@ -365,7 +365,7 @@ __sin(double x){ } ret: - libc_feupdateenv (&env); + libc_feupdateenv_53bit (&env); return retval; } @@ -386,7 +386,7 @@ __cos(double x) fenv_t env; double retval = 0; - libc_feholdexcept_setround (&env, FE_TONEAREST); + libc_feholdexcept_setround_53bit (&env, FE_TONEAREST); u.x = x; m = u.i[HIGH_HALF]; @@ -635,7 +635,7 @@ __cos(double x) } ret: - libc_feupdateenv (&env); + libc_feupdateenv_53bit (&env); return retval; } |