diff options
author | Chao Yang <chao.yang@linaro.org> | 2011-10-10 15:55:46 +0100 |
---|---|---|
committer | Chao Yang <chao.yang@linaro.org> | 2011-10-13 15:39:48 +0100 |
commit | 33fbe12da508747e5a78c88e2256094f90a63205 (patch) | |
tree | 613377dfd7e4f1db6c3354f30fc1ccdfd37e989f | |
parent | a74d3139b5e2046e52a94f6b1510d5e3d15c2bc1 (diff) | |
download | fdlibm-33fbe12da508747e5a78c88e2256094f90a63205.tar.gz |
fdlibm: fix strict aliasing violations
This patch fixes strict aliasing violations and removes -fno-strict-aliasing
compiler flag in Android.mk
Change-Id: I9411e2000eadf9e357e611f386ba66e584152b15
-rw-r--r-- | Android.mk | 2 | ||||
-rw-r--r-- | e_acos.c | 2 | ||||
-rw-r--r-- | e_asin.c | 2 | ||||
-rw-r--r-- | e_atan2.c | 8 | ||||
-rw-r--r-- | e_atanh.c | 2 | ||||
-rw-r--r-- | e_cosh.c | 6 | ||||
-rw-r--r-- | e_exp.c | 10 | ||||
-rw-r--r-- | e_fmod.c | 8 | ||||
-rw-r--r-- | e_hypot.c | 27 | ||||
-rw-r--r-- | e_log.c | 2 | ||||
-rw-r--r-- | e_log10.c | 2 | ||||
-rw-r--r-- | e_pow.c | 38 | ||||
-rw-r--r-- | e_rem_pio2.c | 4 | ||||
-rw-r--r-- | e_remainder.c | 5 | ||||
-rw-r--r-- | e_sinh.c | 6 | ||||
-rw-r--r-- | e_sqrt.c | 4 | ||||
-rw-r--r-- | fdlibm.h | 23 | ||||
-rw-r--r-- | k_cos.c | 4 | ||||
-rw-r--r-- | k_standard.c | 2 | ||||
-rw-r--r-- | k_tan.c | 8 | ||||
-rw-r--r-- | s_cbrt.c | 18 | ||||
-rw-r--r-- | s_ceil.c | 4 | ||||
-rw-r--r-- | s_copysign.c | 2 | ||||
-rw-r--r-- | s_erf.c | 4 | ||||
-rw-r--r-- | s_expm1.c | 17 | ||||
-rw-r--r-- | s_fabs.c | 5 | ||||
-rw-r--r-- | s_floor.c | 4 | ||||
-rw-r--r-- | s_frexp.c | 2 | ||||
-rw-r--r-- | s_log1p.c | 4 | ||||
-rw-r--r-- | s_modf.c | 33 | ||||
-rw-r--r-- | s_nextafter.c | 8 | ||||
-rw-r--r-- | s_rint.c | 8 | ||||
-rw-r--r-- | s_scalbn.c | 4 |
33 files changed, 174 insertions, 104 deletions
@@ -43,7 +43,7 @@ src_files := \ # This is necessary to guarantee that the FDLIBM functions are in # "IEEE spirit", i.e. to guarantee that the IEEE 754 core functions # are used. -cflags := "-D_LIB_VERSION_TYPE=\"const enum _IEEE_\"" -fno-strict-aliasing +cflags := "-D_LIB_VERSION_TYPE=\"const enum _IEEE_\"" -Werror=strict-aliasing # @@ -94,7 +94,7 @@ qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */ z = (one-x)*0.5; s = ieee_sqrt(z); df = s; - __LO(df) = 0; + __TOLO(df, 0); c = (z-df*df)/(s+df); p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); @@ -103,7 +103,7 @@ qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */ t = pio2_hi-(2.0*(s+s*w)-pio2_lo); } else { w = s; - __LO(w) = 0; + __TOLO(w, 0); c = (t-w*w)/(s+w); r = p/q; p = 2.0*s*r-(pio2_lo-2.0*c); @@ -114,8 +114,14 @@ pi_lo = 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */ else z=ieee_atan(ieee_fabs(y/x)); /* safe to do y/x */ switch (m) { case 0: return z ; /* ieee_atan(+,+) */ - case 1: __HI(z) ^= 0x80000000; + case 1: + { + double_ints di; /* di created to remove strict-aliasing warning */ + di.d = z; + di.i.hi ^= 0x80000000; + z = di.d; return z ; /* ieee_atan(-,+) */ + } case 2: return pi-(z-pi_lo);/* ieee_atan(+,-) */ default: /* case 3 */ return (z-pi_lo)-pi;/* ieee_atan(-,-) */ @@ -58,7 +58,7 @@ static double zero = 0.0; if(ix==0x3ff00000) return x/zero; if(ix<0x3e300000&&(huge+x)>zero) return x; /* x<2**-28 */ - __HI(x) = ix; /* x <- |x| */ + __TOHI(x, ix); /* x <- |x| */ if(ix<0x3fe00000) { /* x < 0.5 */ t = x+x; t = 0.5*ieee_log1p(t+t*x/(one-x)); @@ -36,8 +36,10 @@ #ifdef __STDC__ static const double one = 1.0, half=0.5, huge = 1.0e300; + union {unsigned* dst_p; const double* src_p;}u_cast, u_castx; #else static double one = 1.0, half=0.5, huge = 1.0e300; + union {unsigned* dst_p; double* src_p;}u_cast, u_castx; #endif #ifdef __STDC__ @@ -76,7 +78,9 @@ static double one = 1.0, half=0.5, huge = 1.0e300; if (ix < 0x40862E42) return half*__ieee754_exp(ieee_fabs(x)); /* |x| in [log(maxdouble), overflowthresold] */ - lx = *( (((*(unsigned*)&one)>>29)) + (unsigned*)&x); + u_cast.src_p = &one; + u_castx.src_p = &x; + lx = *(((*u_cast.dst_p)>>29) + u_castx.dst_p); if (ix<0x408633CE || (ix==0x408633ce)&&(lx<=(unsigned)0x8fb9f87d)) { w = __ieee754_exp(half*ieee_fabs(x)); @@ -147,10 +147,16 @@ P5 = 4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */ if(k==0) return one-((x*c)/(c-2.0)-x); else y = one-((lo-(x*c)/(2.0-c))-hi); if(k >= -1021) { - __HI(y) += (k<<20); /* add k to y's exponent */ + double_ints di; + di.d = y; + di.i.hi += (k<<20); /* add k to y's exponent */ + y = di.d; return y; } else { - __HI(y) += ((k+1000)<<20);/* add k to y's exponent */ + double_ints di; + di.d = y; + di.i.hi += ((k+1000)<<20);/* add k to y's exponent */ + y = di.d; return y*twom1000; } } @@ -120,8 +120,8 @@ static double one = 1.0, Zero[] = {0.0, -0.0,}; } if(iy>= -1022) { /* normalize output */ hx = ((hx-0x00100000)|((iy+1023)<<20)); - __HI(x) = hx|sx; - __LO(x) = lx; + __TOHI(x, hx|sx); + __TOLO(x, lx); } else { /* subnormal output */ n = -1022 - iy; if(n<=20) { @@ -132,8 +132,8 @@ static double one = 1.0, Zero[] = {0.0, -0.0,}; } else { lx = hx>>(n-32); hx = sx; } - __HI(x) = hx|sx; - __LO(x) = lx; + __TOHI(x, hx|sx); + __TOLO(x, lx); x *= one; /* create necessary signal */ } return x; /* exact output */ @@ -58,8 +58,8 @@ ha = __HI(x)&0x7fffffff; /* high word of x */ hb = __HI(y)&0x7fffffff; /* high word of y */ if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;} - __HI(a) = ha; /* a <- |a| */ - __HI(b) = hb; /* b <- |b| */ + __TOHI(a, ha); /* a <- |a| */ + __TOHI(b, hb); /* b <- |b| */ if((ha-hb)>0x3c00000) {return a+b;} /* x/y > 2**60 */ k=0; if(ha > 0x5f300000) { /* a>2**500 */ @@ -71,14 +71,14 @@ } /* scale a and b by 2**-600 */ ha -= 0x25800000; hb -= 0x25800000; k += 600; - __HI(a) = ha; - __HI(b) = hb; + __TOHI(a, ha); + __TOHI(b, hb); } if(hb < 0x20b00000) { /* b < 2**-500 */ if(hb <= 0x000fffff) { /* subnormal b or 0 */ if((hb|(__LO(b)))==0) return a; t1=0; - __HI(t1) = 0x7fd00000; /* t1=2^1022 */ + __TOHI(t1, 0x7fd00000); /* t1=2^1022 */ b *= t1; a *= t1; k -= 1022; @@ -86,30 +86,31 @@ ha += 0x25800000; /* a *= 2^600 */ hb += 0x25800000; /* b *= 2^600 */ k -= 600; - __HI(a) = ha; - __HI(b) = hb; + __TOHI(a, ha); + __TOHI(b, hb); } } /* medium size a and b */ w = a-b; if (w>b) { t1 = 0; - __HI(t1) = ha; + __TOHI(t1, ha); t2 = a-t1; w = ieee_sqrt(t1*t1-(b*(-b)-t2*(a+t1))); } else { a = a+a; y1 = 0; - __HI(y1) = hb; + __TOHI(y1, hb); y2 = b - y1; t1 = 0; - __HI(t1) = ha+0x00100000; + __TOHI(t1, ha+0x00100000); t2 = a - t1; w = ieee_sqrt(t1*y1-(w*(-w)-(t1*y2+t2*b))); } if(k!=0) { - t1 = 1.0; - __HI(t1) += (k<<20); - return t1*w; + double_ints di; + di.d = 1.0; + di.i.hi += (k<<20); + return di.d*w; } else return w; } @@ -108,7 +108,7 @@ static double zero = 0.0; k += (hx>>20)-1023; hx &= 0x000fffff; i = (hx+0x95f64)&0x100000; - __HI(x) = hx|(i^0x3ff00000); /* normalize x or x/2 */ + __TOHI(x, hx|(i^0x3ff00000)); /* normalize x or x/2 */ k += (i>>20); f = x-1.0; if((0x000fffff&(2+hx))<3) { /* |f| < 2**-20 */ @@ -85,7 +85,7 @@ static double zero = 0.0; i = ((unsigned)k&0x80000000)>>31; hx = (hx&0x000fffff)|((0x3ff-i)<<20); y = (double)(k+i); - __HI(x) = hx; + __TOHI(x, hx); z = y*log10_2lo + ivln10*__ieee754_log(x); return z+y*log10_2hi; } @@ -109,8 +109,17 @@ ivln2_l = 1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/ int i0,i1,i,j,k,yisint,n; int hx,hy,ix,iy; unsigned lx,ly; + union { +#ifdef __STDC__ + const double* one_p; +#else + double* one_p; +#endif + int* dst_p; + }u_cast; - i0 = ((*(int*)&one)>>29)^1; i1=1-i0; + u_cast.one_p = &one; + i0 = ((*u_cast.dst_p)>>29)^1; i1=1-i0; hx = __HI(x); lx = __LO(x); hy = __HI(y); ly = __LO(y); ix = hx&0x7fffffff; iy = hy&0x7fffffff; @@ -203,7 +212,7 @@ ivln2_l = 1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/ u = ivln2_h*t; /* ivln2_h has 21 sig. bits */ v = t*ivln2_l-w*ivln2; t1 = u+v; - __LO(t1) = 0; + __TOLO(t1, 0); t2 = v-(t1-u); } else { double ss,s2,s_h,s_l,t_h,t_l; @@ -218,17 +227,17 @@ ivln2_l = 1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/ if(j<=0x3988E) k=0; /* |x|<ieee_sqrt(3/2) */ else if(j<0xBB67A) k=1; /* |x|<ieee_sqrt(3) */ else {k=0;n+=1;ix -= 0x00100000;} - __HI(ax) = ix; + __TOHI(ax, ix); /* compute ss = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */ u = ax-bp[k]; /* bp[0]=1.0, bp[1]=1.5 */ v = one/(ax+bp[k]); ss = u*v; s_h = ss; - __LO(s_h) = 0; + __TOLO(s_h, 0); /* t_h=ax+bp[k] High */ t_h = zero; - __HI(t_h)=((ix>>1)|0x20000000)+0x00080000+(k<<18); + __TOHI(t_h, ((ix>>1)|0x20000000)+0x00080000+(k<<18)); t_l = ax - (t_h-bp[k]); s_l = v*((u-s_h*t_h)-s_h*t_l); /* compute ieee_log(ax) */ @@ -237,27 +246,27 @@ ivln2_l = 1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/ r += s_l*(s_h+ss); s2 = s_h*s_h; t_h = 3.0+s2+r; - __LO(t_h) = 0; + __TOLO(t_h, 0); t_l = r-((t_h-3.0)-s2); /* u+v = ss*(1+...) */ u = s_h*t_h; v = s_l*t_h+t_l*ss; /* 2/(3log2)*(ss+...) */ p_h = u+v; - __LO(p_h) = 0; + __TOLO(p_h, 0); p_l = v-(p_h-u); z_h = cp_h*p_h; /* cp_h+cp_l = 2/(3*log2) */ z_l = cp_l*p_h+p_l*cp+dp_l[k]; /* log2(ax) = (ss+..)*2/(3*log2) = n + dp_h + z_h + z_l */ t = (double)n; t1 = (((z_h+z_l)+dp_h[k])+t); - __LO(t1) = 0; + __TOLO(t1, 0); t2 = z_l-(((t1-t)-dp_h[k])-z_h); } /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */ y1 = y; - __LO(y1) = 0; + __TOLO(y1, 0); p_l = (y-y1)*t1+y*t2; p_h = y1*t1; z = p_l+p_h; @@ -286,13 +295,13 @@ ivln2_l = 1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/ n = j+(0x00100000>>(k+1)); k = ((n&0x7fffffff)>>20)-0x3ff; /* new k for n */ t = zero; - __HI(t) = (n&~(0x000fffff>>k)); + __TOHI(t, (n&~(0x000fffff>>k))); n = ((n&0x000fffff)|0x00100000)>>(20-k); if(j<0) n = -n; p_h -= t; } t = p_l+p_h; - __LO(t) = 0; + __TOLO(t, 0); u = t*lg2_h; v = (p_l-(t-p_h))*lg2+t*lg2_l; z = u+v; @@ -304,6 +313,11 @@ ivln2_l = 1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/ j = __HI(z); j += (n<<20); if((j>>20)<=0) z = ieee_scalbn(z,n); /* subnormal output */ - else __HI(z) += (n<<20); + else { + double_ints di; + di.d = z; + di.i.hi += (n<<20); + z = di.d; + } return s*z; } diff --git a/e_rem_pio2.c b/e_rem_pio2.c index 42f14f8..cdf02bc 100644 --- a/e_rem_pio2.c +++ b/e_rem_pio2.c @@ -159,9 +159,9 @@ pio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */ y[0]=y[1]=x-x; return 0; } /* set z = ieee_scalbn(|x|,ilogb(x)-23) */ - __LO(z) = __LO(x); + __TOLO(z, __LO(x)); e0 = (ix>>20)-1046; /* e0 = ieee_ilogb(z)-23; */ - __HI(z) = ix - (e0<<20); + __TOHI(z, ix - (e0<<20)); for(i=0;i<2;i++) { tx[i] = (double)((int)(z)); z = (z-tx[i])*two24; diff --git a/e_remainder.c b/e_remainder.c index 6de2135..9f78866 100644 --- a/e_remainder.c +++ b/e_remainder.c @@ -39,6 +39,7 @@ static double zero = 0.0; int hx,hp; unsigned sx,lx,lp; double p_half; + double_ints di; hx = __HI(x); /* high word of x */ lx = __LO(x); /* low word of x */ @@ -72,6 +73,8 @@ static double zero = 0.0; if(x>=p_half) x -= p; } } - __HI(x) ^= sx; + di.d = x; + di.i.hi ^= sx; + x = di.d; return x; } @@ -33,8 +33,10 @@ #ifdef __STDC__ static const double one = 1.0, shuge = 1.0e307; + union {const double* src_p; unsigned* dst_p;}u_cast, u_castx; #else static double one = 1.0, shuge = 1.0e307; + union {double* src_p; unsigned* dst_p;}u_cast, u_castx; #endif #ifdef __STDC__ @@ -70,7 +72,9 @@ static double one = 1.0, shuge = 1.0e307; if (ix < 0x40862E42) return h*__ieee754_exp(ieee_fabs(x)); /* |x| in [log(maxdouble), overflowthresold] */ - lx = *( (((*(unsigned*)&one)>>29)) + (unsigned*)&x); + u_cast.src_p = &one; + u_castx.src_p = &x; + lx = *( ((*u_cast.dst_p)>>29) + u_castx.dst_p); if (ix<0x408633CE || (ix==0x408633ce)&&(lx<=(unsigned)0x8fb9f87d)) { w = __ieee754_exp(0.5*ieee_fabs(x)); t = h*w; @@ -186,8 +186,8 @@ static double one = 1.0, tiny=1.0e-300; ix1 = q1>>1; if ((q&1)==1) ix1 |= sign; ix0 += (m <<20); - __HI(z) = ix0; - __LO(z) = ix1; + __TOHI(z, ix0); + __TOLO(z, ix1); return z; } @@ -24,17 +24,24 @@ extern "C" { #endif #endif +typedef union { #ifdef __LITTLE_ENDIAN -#define __HI(x) *(1+(int*)&x) -#define __LO(x) *(int*)&x -#define __HIp(x) *(1+(int*)x) -#define __LOp(x) *(int*)x + struct { int lo, hi; } i; #else -#define __HI(x) *(int*)&x -#define __LO(x) *(1+(int*)&x) -#define __HIp(x) *(int*)x -#define __LOp(x) *(1+(int*)x) + struct { int hi, lo; } i; #endif + double d; +}double_ints; + +#define __HI(x) ((double_ints)(x)).i.hi +#define __LO(x) ((double_ints)(x)).i.lo +#define __HIp(x) ((double_ints)*(x)).i.hi +#define __LOp(x) ((double_ints)*(x)).i.lo + +#define __TOHI(x, y) do{double_ints di; di.d = (x); di.i.hi = (y); (x) = di.d;}while(0) +#define __TOLO(x, y) do{double_ints di; di.d = (x); di.i.lo = (y); (x) = di.d;}while(0) +#define __TOHIp(x, y) do{double_ints di; di.d = *(x); di.i.hi = (y); *(x) = di.d;}while(0) +#define __TOLOp(x, y) do{double_ints di; di.d = *(x); di.i.lo = (y); *(x) = di.d;}while(0) #ifndef __P #define __FDLIBM_P_DEFINED @@ -82,8 +82,8 @@ C6 = -1.13596475577881948265e-11; /* 0xBDA8FAE9, 0xBE8838D4 */ if(ix > 0x3fe90000) { /* x > 0.78125 */ qx = 0.28125; } else { - __HI(qx) = ix-0x00200000; /* x/4 */ - __LO(qx) = 0; + __TOHI(qx, ix-0x00200000); /* x/4 */ + __TOLO(qx, 0); } hz = 0.5*z-qx; a = one-qx; diff --git a/k_standard.c b/k_standard.c index fb13464..f3c97e2 100644 --- a/k_standard.c +++ b/k_standard.c @@ -86,7 +86,7 @@ static double zero = 0.0; /* used as const */ #define HUGE_VAL inf double inf = 0.0; - __HI(inf) = 0x7ff00000; /* set inf to infinite */ + __TOHI(inf, 0x7ff00000); /* set inf to infinite */ #endif #ifdef _USE_WRITE @@ -88,10 +88,10 @@ __kernel_tan(double x, double y, int iy) { double a, t; z = w = x + y; - __LO(z) = 0; + __TOLO(z, 0); v = y - (z - x); t = a = -one / w; - __LO(t) = 0; + __TOLO(t, 0); s = one + t * z; return t + a * (s + t * v); } @@ -138,10 +138,10 @@ __kernel_tan(double x, double y, int iy) { /* compute -1.0 / (x+r) accurately */ double a, t; z = w; - __LO(z) = 0; + __TOLO(z, 0); v = r - (z - x); /* z+v = r+x */ t = a = -1.0 / w; /* a = -1.0/w */ - __LO(t) = 0; + __TOLO(t, 0); s = 1.0 + t * z; return t + a * (s + t * v); } @@ -46,6 +46,7 @@ G = 3.57142857142857150787e-01; /* 5/14 = 0x3FD6DB6D, 0xB6DB6DB7 */ int hx; double r,s,t=0.0,w; unsigned sign; + double_ints di; hx = __HI(x); /* high word of x */ @@ -55,14 +56,14 @@ G = 3.57142857142857150787e-01; /* 5/14 = 0x3FD6DB6D, 0xB6DB6DB7 */ if((hx|__LO(x))==0) return(x); /* ieee_cbrt(0) is itself */ - __HI(x) = hx; /* x <- |x| */ + __TOHI(x, hx); /* x <- |x| */ /* rough cbrt to 5 bits */ if(hx<0x00100000) /* subnormal number */ - {__HI(t)=0x43500000; /* set t= 2**54 */ - t*=x; __HI(t)=__HI(t)/3+B2; + {__TOHI(t, 0x43500000); /* set t= 2**54 */ + t*=x; __TOHI(t, (__HI(t)/3+B2)); } else - __HI(t)=hx/3+B1; + __TOHI(t, (hx/3+B1)); /* new cbrt to 23 bits, may be implemented in single precision */ @@ -71,7 +72,10 @@ G = 3.57142857142857150787e-01; /* 5/14 = 0x3FD6DB6D, 0xB6DB6DB7 */ t*=G+F/(s+E+D/s); /* chopped to 20 bits and make it larger than ieee_cbrt(x) */ - __LO(t)=0; __HI(t)+=0x00000001; + __TOLO(t, 0); + di.d = t; + di.i.hi +=0x00000001; + t = di.d; /* one step newton iteration to 53 bits with error less than 0.667 ulps */ @@ -82,6 +86,8 @@ G = 3.57142857142857150787e-01; /* 5/14 = 0x3FD6DB6D, 0xB6DB6DB7 */ t=t+t*r; /* retore the sign bit */ - __HI(t) |= sign; + di.d = t; + di.i.hi |= sign; + t = di.d; return(t); } @@ -72,7 +72,7 @@ static double huge = 1.0e300; i1 &= (~i); } } - __HI(x) = i0; - __LO(x) = i1; + __TOHI(x, i0); + __TOLO(x, i1); return x; } diff --git a/s_copysign.c b/s_copysign.c index c61698c..75c0c2d 100644 --- a/s_copysign.c +++ b/s_copysign.c @@ -26,6 +26,6 @@ double x,y; #endif { - __HI(x) = (__HI(x)&0x7fffffff)|(__HI(y)&0x80000000); + __TOHI(x, ((__HI(x)&0x7fffffff)|(__HI(y)&0x80000000))); return x; } @@ -238,7 +238,7 @@ sb7 = -2.24409524465858183362e+01; /* 0xC03670E2, 0x42712D62 */ sb5+s*(sb6+s*sb7)))))); } z = x; - __LO(z) = 0; + __TOLO(z, 0); r = __ieee754_exp(-z*z-0.5625)*__ieee754_exp((z-x)*(z+x)+R/S); if(hx>=0) return one-r/x; else return r/x-one; } @@ -300,7 +300,7 @@ sb7 = -2.24409524465858183362e+01; /* 0xC03670E2, 0x42712D62 */ sb5+s*(sb6+s*sb7)))))); } z = x; - __LO(z) = 0; + __TOLO(z, 0); r = __ieee754_exp(-z*z-0.5625)* __ieee754_exp((z-x)*(z+x)+R/S); if(hx>0) return r/x; else return two-r/x; @@ -136,6 +136,7 @@ Q5 = -2.01099218183624371326e-07; /* BE8AFDB7 6E09C32D */ double y,hi,lo,c,t,e,hxs,hfx,r1; int k,xsb; unsigned hx; + double_ints di; hx = __HI(x); /* high word of x */ xsb = hx&0x80000000; /* sign bit of x */ @@ -197,19 +198,25 @@ Q5 = -2.01099218183624371326e-07; /* BE8AFDB7 6E09C32D */ else return one+2.0*(x-e); if (k <= -2 || k>56) { /* suffice to return ieee_exp(x)-1 */ y = one-(e-x); - __HI(y) += (k<<20); /* add k to y's exponent */ + di.d = y; + di.i.hi += (k<<20); /* add k to y's exponent */ + y = di.d; return y-one; } t = one; if(k<20) { - __HI(t) = 0x3ff00000 - (0x200000>>k); /* t=1-2^-k */ + __TOHI(t, 0x3ff00000 - (0x200000>>k)); /* t=1-2^-k */ y = t-(e-x); - __HI(y) += (k<<20); /* add k to y's exponent */ + di.d = y; + di.i.hi += (k<<20); /* add k to y's exponent */ + y = di.d; } else { - __HI(t) = ((0x3ff-k)<<20); /* 2^-k */ + __TOHI(t, ((0x3ff-k)<<20)); /* 2^-k */ y = x-(e+t); y += one; - __HI(y) += (k<<20); /* add k to y's exponent */ + di.d = y; + di.i.hi += (k<<20); /* add k to y's exponent */ + y = di.d; } } return y; @@ -24,6 +24,9 @@ double x; #endif { - __HI(x) &= 0x7fffffff; + double_ints di; + di.d = x; + di.i.hi &= 0x7fffffff; + x = di.d; return x; } @@ -73,7 +73,7 @@ static double huge = 1.0e300; i1 &= (~i); } } - __HI(x) = i0; - __LO(x) = i1; + __TOHI(x, i0); + __TOLO(x, i1); return x; } @@ -51,6 +51,6 @@ two54 = 1.80143985094819840000e+16; /* 0x43500000, 0x00000000 */ } *eptr += (ix>>20)-1022; hx = (hx&0x800fffff)|0x3fe00000; - __HI(x) = hx; + __TOHI(x, hx); return x; } @@ -141,10 +141,10 @@ static double zero = 0.0; } hu &= 0x000fffff; if(hu<0x6a09e) { - __HI(u) = hu|0x3ff00000; /* normalize u */ + __TOHI(u, hu|0x3ff00000); /* normalize u */ } else { k += 1; - __HI(u) = hu|0x3fe00000; /* normalize u/2 */ + __TOHI(u, hu|0x3fe00000); /* normalize u/2 */ hu = (0x00100000-hu)>>2; } f = u-1.0; @@ -43,37 +43,46 @@ static double one = 1.0; j0 = ((i0>>20)&0x7ff)-0x3ff; /* exponent of x */ if(j0<20) { /* integer part in high x */ if(j0<0) { /* |x|<1 */ - __HIp(iptr) = i0&0x80000000; - __LOp(iptr) = 0; /* *iptr = +-0 */ + __TOHIp(iptr, i0&0x80000000); + __TOLOp(iptr, 0); /* *iptr = +-0 */ return x; } else { i = (0x000fffff)>>j0; if(((i0&i)|i1)==0) { /* x is integral */ + double_ints di; *iptr = x; - __HI(x) &= 0x80000000; - __LO(x) = 0; /* return +-0 */ + di.d = x; + di.i.hi &= 0x80000000; + di.i.lo = 0; /* return +-0 */ + x = di.d; return x; } else { - __HIp(iptr) = i0&(~i); - __LOp(iptr) = 0; + __TOHIp(iptr, i0&(~i)); + __TOLOp(iptr, 0); return x - *iptr; } } } else if (j0>51) { /* no fraction part */ + double_ints di; *iptr = x*one; - __HI(x) &= 0x80000000; - __LO(x) = 0; /* return +-0 */ + di.d = x; + di.i.hi &= 0x80000000; + di.i.lo = 0; /* return +-0 */ + x = di.d; return x; } else { /* fraction part in low x */ i = ((unsigned)(0xffffffff))>>(j0-20); if((i1&i)==0) { /* x is integral */ + double_ints di; *iptr = x; - __HI(x) &= 0x80000000; - __LO(x) = 0; /* return +-0 */ + di.d = x; + di.i.hi &= 0x80000000; + di.i.lo = 0; /* return +-0 */ + x = di.d; return x; } else { - __HIp(iptr) = i0; - __LOp(iptr) = i1&(~i); + __TOHIp(iptr, i0); + __TOLOp(iptr, i1&(~i)); return x - *iptr; } } diff --git a/s_nextafter.c b/s_nextafter.c index 0e6db32..fa4a35c 100644 --- a/s_nextafter.c +++ b/s_nextafter.c @@ -42,8 +42,8 @@ return x+y; if(x==y) return x; /* x=y, return x */ if((ix|lx)==0) { /* x == 0 */ - __HI(x) = hy&0x80000000; /* return +-minsubnormal */ - __LO(x) = 1; + __TOHI(x, hy&0x80000000); /* return +-minsubnormal */ + __TOLO(x, 1); y = x*x; if(y==x) return y; else return x; /* raise underflow flag */ } @@ -69,10 +69,10 @@ if(hy<0x00100000) { /* underflow */ y = x*x; if(y!=x) { /* raise underflow flag */ - __HI(y) = hx; __LO(y) = lx; + __TOHI(y, hx); __TOLO(y, lx); return y; } } - __HI(x) = hx; __LO(x) = lx; + __TOHI(x, hx); __TOLO(x, lx); return x; } @@ -53,11 +53,11 @@ TWO52[2]={ i1 |= (i0&0x0fffff); i0 &= 0xfffe0000; i0 |= ((i1|-i1)>>12)&0x80000; - __HI(x)=i0; + __TOHI(x, i0); w = TWO52[sx]+x; t = w-TWO52[sx]; i0 = __HI(t); - __HI(t) = (i0&0x7fffffff)|(sx<<31); + __TOHI(t, (i0&0x7fffffff)|(sx<<31)); return t; } else { i = (0x000fffff)>>j0; @@ -77,8 +77,8 @@ TWO52[2]={ i>>=1; if((i1&i)!=0) i1 = (i1&(~i))|((0x40000000)>>(j0-20)); } - __HI(x) = i0; - __LO(x) = i1; + __TOHI(x, i0); + __TOLO(x, i1); w = TWO52[sx]+x; return w-TWO52[sx]; } @@ -52,12 +52,12 @@ tiny = 1.0e-300; k = k+n; if (k > 0x7fe) return huge*ieee_copysign(huge,x); /* overflow */ if (k > 0) /* normal result */ - {__HI(x) = (hx&0x800fffff)|(k<<20); return x;} + {__TOHI(x, (hx&0x800fffff)|(k<<20)); return x;} if (k <= -54) if (n > 50000) /* in case integer overflow in n+k */ return huge*ieee_copysign(huge,x); /*overflow*/ else return tiny*ieee_copysign(tiny,x); /*underflow*/ k += 54; /* subnormal result */ - __HI(x) = (hx&0x800fffff)|(k<<20); + __TOHI(x, (hx&0x800fffff)|(k<<20)); return x*twom54; } |