aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChao Yang <chao.yang@linaro.org>2011-10-10 15:55:46 +0100
committerChao Yang <chao.yang@linaro.org>2011-10-13 15:39:48 +0100
commit33fbe12da508747e5a78c88e2256094f90a63205 (patch)
tree613377dfd7e4f1db6c3354f30fc1ccdfd37e989f
parenta74d3139b5e2046e52a94f6b1510d5e3d15c2bc1 (diff)
downloadfdlibm-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.mk2
-rw-r--r--e_acos.c2
-rw-r--r--e_asin.c2
-rw-r--r--e_atan2.c8
-rw-r--r--e_atanh.c2
-rw-r--r--e_cosh.c6
-rw-r--r--e_exp.c10
-rw-r--r--e_fmod.c8
-rw-r--r--e_hypot.c27
-rw-r--r--e_log.c2
-rw-r--r--e_log10.c2
-rw-r--r--e_pow.c38
-rw-r--r--e_rem_pio2.c4
-rw-r--r--e_remainder.c5
-rw-r--r--e_sinh.c6
-rw-r--r--e_sqrt.c4
-rw-r--r--fdlibm.h23
-rw-r--r--k_cos.c4
-rw-r--r--k_standard.c2
-rw-r--r--k_tan.c8
-rw-r--r--s_cbrt.c18
-rw-r--r--s_ceil.c4
-rw-r--r--s_copysign.c2
-rw-r--r--s_erf.c4
-rw-r--r--s_expm1.c17
-rw-r--r--s_fabs.c5
-rw-r--r--s_floor.c4
-rw-r--r--s_frexp.c2
-rw-r--r--s_log1p.c4
-rw-r--r--s_modf.c33
-rw-r--r--s_nextafter.c8
-rw-r--r--s_rint.c8
-rw-r--r--s_scalbn.c4
33 files changed, 174 insertions, 104 deletions
diff --git a/Android.mk b/Android.mk
index a78604c..5b43196 100644
--- a/Android.mk
+++ b/Android.mk
@@ -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
#
diff --git a/e_acos.c b/e_acos.c
index 1b63553..337c822 100644
--- a/e_acos.c
+++ b/e_acos.c
@@ -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)));
diff --git a/e_asin.c b/e_asin.c
index e7f9970..dc29e7c 100644
--- a/e_asin.c
+++ b/e_asin.c
@@ -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);
diff --git a/e_atan2.c b/e_atan2.c
index 73c43dd..284e262 100644
--- a/e_atan2.c
+++ b/e_atan2.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(-,-) */
diff --git a/e_atanh.c b/e_atanh.c
index 4793e4a..1e05aa1 100644
--- a/e_atanh.c
+++ b/e_atanh.c
@@ -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));
diff --git a/e_cosh.c b/e_cosh.c
index a5c5ae6..2333edc 100644
--- a/e_cosh.c
+++ b/e_cosh.c
@@ -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));
diff --git a/e_exp.c b/e_exp.c
index e7aaa23..4ab872f 100644
--- a/e_exp.c
+++ b/e_exp.c
@@ -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;
}
}
diff --git a/e_fmod.c b/e_fmod.c
index e4b413b..5872944 100644
--- a/e_fmod.c
+++ b/e_fmod.c
@@ -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 */
diff --git a/e_hypot.c b/e_hypot.c
index e88701d..89da17e 100644
--- a/e_hypot.c
+++ b/e_hypot.c
@@ -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;
}
diff --git a/e_log.c b/e_log.c
index 13c14c8..2b9dd94 100644
--- a/e_log.c
+++ b/e_log.c
@@ -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 */
diff --git a/e_log10.c b/e_log10.c
index 1a705f2..5fb0b55 100644
--- a/e_log10.c
+++ b/e_log10.c
@@ -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;
}
diff --git a/e_pow.c b/e_pow.c
index 808d53f..bcaecb0 100644
--- a/e_pow.c
+++ b/e_pow.c
@@ -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;
}
diff --git a/e_sinh.c b/e_sinh.c
index 0a807c7..45bcd27 100644
--- a/e_sinh.c
+++ b/e_sinh.c
@@ -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;
diff --git a/e_sqrt.c b/e_sqrt.c
index 942cbc7..c838318 100644
--- a/e_sqrt.c
+++ b/e_sqrt.c
@@ -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;
}
diff --git a/fdlibm.h b/fdlibm.h
index d58e65f..fe17c29 100644
--- a/fdlibm.h
+++ b/fdlibm.h
@@ -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
diff --git a/k_cos.c b/k_cos.c
index 2e70850..85d46fa 100644
--- a/k_cos.c
+++ b/k_cos.c
@@ -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
diff --git a/k_tan.c b/k_tan.c
index d789a40..cfae8a0 100644
--- a/k_tan.c
+++ b/k_tan.c
@@ -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);
}
diff --git a/s_cbrt.c b/s_cbrt.c
index f8ce933..2cf4797 100644
--- a/s_cbrt.c
+++ b/s_cbrt.c
@@ -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);
}
diff --git a/s_ceil.c b/s_ceil.c
index cddb1d6..ad301a9 100644
--- a/s_ceil.c
+++ b/s_ceil.c
@@ -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;
}
diff --git a/s_erf.c b/s_erf.c
index f4e3856..c8b7e71 100644
--- a/s_erf.c
+++ b/s_erf.c
@@ -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;
diff --git a/s_expm1.c b/s_expm1.c
index f1f01af..24e8757 100644
--- a/s_expm1.c
+++ b/s_expm1.c
@@ -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;
diff --git a/s_fabs.c b/s_fabs.c
index 498b51f..44d9c5f 100644
--- a/s_fabs.c
+++ b/s_fabs.c
@@ -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;
}
diff --git a/s_floor.c b/s_floor.c
index c55e0b7..d9cc0c6 100644
--- a/s_floor.c
+++ b/s_floor.c
@@ -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;
}
diff --git a/s_frexp.c b/s_frexp.c
index 25b40cb..c592975 100644
--- a/s_frexp.c
+++ b/s_frexp.c
@@ -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;
}
diff --git a/s_log1p.c b/s_log1p.c
index 5b92347..7bc377c 100644
--- a/s_log1p.c
+++ b/s_log1p.c
@@ -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;
diff --git a/s_modf.c b/s_modf.c
index 0d7faa4..9c97bce 100644
--- a/s_modf.c
+++ b/s_modf.c
@@ -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;
}
diff --git a/s_rint.c b/s_rint.c
index fbbd0fd..bd80d98 100644
--- a/s_rint.c
+++ b/s_rint.c
@@ -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];
}
diff --git a/s_scalbn.c b/s_scalbn.c
index 0edb815..91a72a4 100644
--- a/s_scalbn.c
+++ b/s_scalbn.c
@@ -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;
}