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().
This commit is contained in:
Bruce Evans 2008-01-19 16:37:57 +00:00
parent 82bf4517ef
commit 6a876b92fb
2 changed files with 8 additions and 6 deletions

View File

@ -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];
}

View File

@ -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 */