Get rid of strict aliasing rule violations from libm (#3069)

JerryScript-DCO-1.0-Signed-off-by: Csaba Osztrogonác oszi@inf.u-szeged.hu
This commit is contained in:
Csaba Osztrogonác
2019-10-01 14:37:18 +02:00
committed by Robert Fancsik
parent f7391a94ae
commit 3763ac8371
16 changed files with 246 additions and 197 deletions
+71 -69
View File
@@ -120,8 +120,9 @@ static const double dp_l[] =
double
pow (double x, double y)
{
double z, ax, z_h, z_l, p_h, p_l;
double y1, t1, t2, r, s, t, u, v, w;
double_accessor t1, ax, p_h, y1, t, z;
double z_h, z_l, p_l;
double t2, r, s, u, v, w;
int i, j, k, yisint, n;
int hx, hy, ix, iy;
unsigned lx, ly;
@@ -227,29 +228,29 @@ pow (double x, double y)
}
}
ax = fabs (x);
ax.dbl = fabs (x);
/* special value of x */
if (lx == 0)
{
if (ix == 0x7ff00000 || ix == 0 || ix == 0x3ff00000)
{
z = ax; /* x is +-0,+-inf,+-1 */
z.dbl = ax.dbl; /* x is +-0,+-inf,+-1 */
if (hy < 0)
{
z = one / z; /* z = (1 / |x|) */
z.dbl = one / z.dbl; /* z = (1 / |x|) */
}
if (hx < 0)
{
if (((ix - 0x3ff00000) | yisint) == 0)
{
z = (z - z) / (z - z); /* (-1)**non-int is NaN */
z.dbl = NAN; /* (-1)**non-int is NaN */
}
else if (yisint == 1)
{
z = -z; /* (x<0)**odd = -(|x|**odd) */
z.dbl = -z.dbl; /* (x<0)**odd = -(|x|**odd) */
}
}
return z;
return z.dbl;
}
}
@@ -292,25 +293,26 @@ pow (double x, double y)
}
/* now |1 - x| is tiny <= 2**-20, suffice to compute
log(x) by x - x^2 / 2 + x^3 / 3 - x^4 / 4 */
t = ax - one; /* t has 20 trailing zeros */
w = (t * t) * (0.5 - t * (0.3333333333333333333333 - t * 0.25));
u = ivln2_h * t; /* ivln2_h has 21 sig. bits */
v = t * ivln2_l - w * ivln2;
t1 = u + v;
__LO (t1) = 0;
t2 = v - (t1 - u);
t.dbl = ax.dbl - one; /* t has 20 trailing zeros */
w = (t.dbl * t.dbl) * (0.5 - t.dbl * (0.3333333333333333333333 - t.dbl * 0.25));
u = ivln2_h * t.dbl; /* ivln2_h has 21 sig. bits */
v = t.dbl * ivln2_l - w * ivln2;
t1.dbl = u + v;
t1.as_int.lo = 0;
t2 = v - (t1.dbl - u);
}
else
{
double ss, s2, s_h, s_l, t_h, t_l;
double_accessor s_h, t_h;
double ss, s2, s_l, t_l;
n = 0;
/* take care subnormal number */
if (ix < 0x00100000)
{
ax *= two53;
ax.dbl *= two53;
n -= 53;
ix = __HI (ax);
ix = ax.as_int.hi;
}
n += ((ix) >> 20) - 0x3ff;
j = ix & 0x000fffff;
@@ -330,51 +332,51 @@ pow (double x, double y)
n += 1;
ix -= 0x00100000;
}
__HI (ax) = ix;
ax.as_int.hi = 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]);
u = ax.dbl - bp[k]; /* bp[0] = 1.0, bp[1] = 1.5 */
v = one / (ax.dbl + bp[k]);
ss = u * v;
s_h = ss;
__LO (s_h) = 0;
s_h.dbl = ss;
s_h.as_int.lo = 0;
/* t_h = ax + bp[k] High */
t_h = zero;
__HI (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);
t_h.dbl = zero;
t_h.as_int.hi = ((ix >> 1) | 0x20000000) + 0x00080000 + (k << 18);
t_l = ax.dbl - (t_h.dbl - bp[k]);
s_l = v * ((u - s_h.dbl * t_h.dbl) - s_h.dbl * t_l);
/* compute log(ax) */
s2 = ss * ss;
r = s2 * s2 * (L1 + s2 * (L2 + s2 * (L3 + s2 * (L4 + s2 * (L5 + s2 * L6)))));
r += s_l * (s_h + ss);
s2 = s_h * s_h;
t_h = 3.0 + s2 + r;
__LO (t_h) = 0;
t_l = r - ((t_h - 3.0) - s2);
r += s_l * (s_h.dbl + ss);
s2 = s_h.dbl * s_h.dbl;
t_h.dbl = 3.0 + s2 + r;
t_h.as_int.lo = 0;
t_l = r - ((t_h.dbl - 3.0) - s2);
/* u + v = ss * (1 + ...) */
u = s_h * t_h;
v = s_l * t_h + t_l * ss;
u = s_h.dbl * t_h.dbl;
v = s_l * t_h.dbl + t_l * ss;
/* 2 / (3 * log2) * (ss + ...) */
p_h = u + v;
__LO (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];
p_h.dbl = u + v;
p_h.as_int.lo = 0;
p_l = v - (p_h.dbl - u);
z_h = cp_h * p_h.dbl; /* cp_h + cp_l = 2 / (3 * log2) */
z_l = cp_l * p_h.dbl + 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;
t2 = z_l - (((t1 - t) - dp_h[k]) - z_h);
t.dbl = (double) n;
t1.dbl = (((z_h + z_l) + dp_h[k]) + t.dbl);
t1.as_int.lo = 0;
t2 = z_l - (((t1.dbl - t.dbl) - dp_h[k]) - z_h);
}
/* split up y into y1 + y2 and compute (y1 + y2) * (t1 + t2) */
y1 = y;
__LO (y1) = 0;
p_l = (y - y1) * t1 + y * t2;
p_h = y1 * t1;
z = p_l + p_h;
j = __HI (z);
i = __LO (z);
y1.dbl = y;
y1.as_int.lo = 0;
p_l = (y - y1.dbl) * t1.dbl + y * t2;
p_h.dbl = y1.dbl * t1.dbl;
z.dbl = p_l + p_h.dbl;
j = z.as_int.hi;
i = z.as_int.lo;
if (j >= 0x40900000) /* z >= 1024 */
{
if (((j - 0x40900000) | i) != 0) /* if z > 1024 */
@@ -383,7 +385,7 @@ pow (double x, double y)
}
else
{
if (p_l + ovt > z - p_h)
if (p_l + ovt > z.dbl - p_h.dbl)
{
return s * huge * huge; /* overflow */
}
@@ -397,7 +399,7 @@ pow (double x, double y)
}
else
{
if (p_l <= z - p_h)
if (p_l <= z.dbl - p_h.dbl)
{
return s * tiny * tiny; /* underflow */
}
@@ -413,36 +415,36 @@ pow (double x, double y)
{
n = j + (0x00100000 >> (k + 1));
k = ((n & 0x7fffffff) >> 20) - 0x3ff; /* new k for n */
t = zero;
__HI (t) = (n & ~(0x000fffff >> k));
t.dbl = zero;
t.as_int.hi = (n & ~(0x000fffff >> k));
n = ((n & 0x000fffff) | 0x00100000) >> (20 - k);
if (j < 0)
{
n = -n;
}
p_h -= t;
p_h.dbl -= t.dbl;
}
t = p_l + p_h;
__LO (t) = 0;
u = t * lg2_h;
v = (p_l - (t - p_h)) * lg2 + t * lg2_l;
z = u + v;
w = v - (z - u);
t = z * z;
t1 = z - t * (P1 + t * (P2 + t * (P3 + t * (P4 + t * P5))));
r = (z * t1) / (t1 - two) - (w + z * w);
z = one - (r - z);
j = __HI (z);
t.dbl = p_l + p_h.dbl;
t.as_int.lo = 0;
u = t.dbl * lg2_h;
v = (p_l - (t.dbl - p_h.dbl)) * lg2 + t.dbl * lg2_l;
z.dbl = u + v;
w = v - (z.dbl - u);
t.dbl = z.dbl * z.dbl;
t1.dbl = z.dbl - t.dbl * (P1 + t.dbl * (P2 + t.dbl * (P3 + t.dbl * (P4 + t.dbl * P5))));
r = (z.dbl * t1.dbl) / (t1.dbl - two) - (w + z.dbl * w);
z.dbl = one - (r - z.dbl);
j = z.as_int.hi;
j += (n << 20);
if ((j >> 20) <= 0) /* subnormal output */
{
z = scalbn (z, n);
z.dbl = scalbn (z.dbl, n);
}
else
{
__HI (z) += (n << 20);
z.as_int.hi += (n << 20);
}
return s * z;
return s * z.dbl;
} /* pow */
#undef zero