diff options
author | bde <bde@FreeBSD.org> | 2008-01-19 16:37:57 +0000 |
---|---|---|
committer | bde <bde@FreeBSD.org> | 2008-01-19 16:37:57 +0000 |
commit | aaee2ef564bf1c5fc99a37291522877aa33e15cc (patch) | |
tree | 412e3556c1d654fe9288dbb8e43183ac9e01626d | |
parent | 1d78104fa012fbba92798ea6818421e3e000999a (diff) | |
download | FreeBSD-src-aaee2ef564bf1c5fc99a37291522877aa33e15cc.zip FreeBSD-src-aaee2ef564bf1c5fc99a37291522877aa33e15cc.tar.gz |
Use STRICT_ASSIGN() instead of assorted direct volatile hacks to work
around assignments not working for gcc on i386. Now volatile hacks
for rint() and rintf() don't needlessly pessimize so many arches
and the remaining pessimizations (for arm and powerpc) can be avoided
centrally.
This cleans up after s_rint.c 1.3 and 1.13 and s_rintf.c 1.3 and 1.9:
- s_rint.c 1.13 broke 1.3 by only using a volatile cast hack in 1 place
when it was needed in 2 places, and the volatile cast hack stopped
working with gcc-4. These bugs only affected correctness tests on
i386 since i386 normally uses asm rint() and doesn't support the
extra precision mode that would break assignments of doubles.
- s_rintf.c 1.9 improved(?) on 1.3 by using a volatile variable hack
instead of an extra-precision variable hack, but it declared 2
variables as volatile when only 1 variable needed to be volatile.
This only affected speed tests on i386 since i386 uses asm rintf().
-rw-r--r-- | lib/msun/src/s_rint.c | 4 | ||||
-rw-r--r-- | lib/msun/src/s_rintf.c | 10 |
2 files changed, 8 insertions, 6 deletions
diff --git a/lib/msun/src/s_rint.c b/lib/msun/src/s_rint.c index 74a9331..571c17e 100644 --- a/lib/msun/src/s_rint.c +++ b/lib/msun/src/s_rint.c @@ -51,7 +51,7 @@ rint(double x) i0 &= 0xfffe0000; i0 |= ((i1|-i1)>>12)&0x80000; SET_HIGH_WORD(x,i0); - w = TWO52[sx]+x; + STRICT_ASSIGN(double,w,TWO52[sx]+x); t = w-TWO52[sx]; GET_HIGH_WORD(i0,t); SET_HIGH_WORD(t,(i0&0x7fffffff)|(sx<<31)); @@ -84,7 +84,7 @@ rint(double x) if((i1&i)!=0) i1 = (i1&(~i))|((0x40000000)>>(j0-20)); } INSERT_WORDS(x,i0,i1); - *(volatile double *)&w = TWO52[sx]+x; /* clip any extra precision */ + STRICT_ASSIGN(double,w,TWO52[sx]+x); return w-TWO52[sx]; } diff --git a/lib/msun/src/s_rintf.c b/lib/msun/src/s_rintf.c index 32697fb..ce8b786 100644 --- a/lib/msun/src/s_rintf.c +++ b/lib/msun/src/s_rintf.c @@ -17,7 +17,9 @@ static char rcsid[] = "$FreeBSD$"; #endif -#include <sys/types.h> +#include <float.h> +#include <stdint.h> + #include "math.h" #include "math_private.h" @@ -31,20 +33,20 @@ float rintf(float x) { int32_t i0,j0,sx; - volatile float w,t; /* volatile works around gcc bug */ + float w,t; GET_FLOAT_WORD(i0,x); sx = (i0>>31)&1; j0 = ((i0>>23)&0xff)-0x7f; if(j0<23) { if(j0<0) { if((i0&0x7fffffff)==0) return x; - w = TWO23[sx]+x; + STRICT_ASSIGN(float,w,TWO23[sx]+x); t = w-TWO23[sx]; GET_FLOAT_WORD(i0,t); SET_FLOAT_WORD(t,(i0&0x7fffffff)|(sx<<31)); return t; } - w = TWO23[sx]+x; + STRICT_ASSIGN(float,w,TWO23[sx]+x); return w-TWO23[sx]; } if(j0==0x80) return x+x; /* inf or NaN */ |