arrfab / rpms / glibc

Forked from rpms/glibc 5 years ago
Clone

Blame SOURCES/glibc-ppc64le-09.patch

147e83
# commit 650ef4bd7976e36831cba22d838b567d3b5f6e8f
147e83
# Author: Alan Modra <amodra@gmail.com>
147e83
# Date:   Sat Aug 17 18:25:51 2013 +0930
147e83
# 
147e83
#     PowerPC floating point little-endian [4 of 15]
147e83
#     http://sourceware.org/ml/libc-alpha/2013-08/msg00084.html
147e83
#     
147e83
#     Another batch of ieee854 macros and union replacement.  These four
147e83
#     files also have bugs fixed with this patch.  The fact that the two
147e83
#     doubles in an IBM long double may have different signs means that
147e83
#     negation and absolute value operations can't just twiddle one sign bit
147e83
#     as you can with ieee864 style extended double.  fmodl, remainderl,
147e83
#     erfl and erfcl all had errors of this type.  erfl also returned +1 for
147e83
#     large magnitude negative input where it should return -1.  The hypotl
147e83
#     error is innocuous since the value adjusted twice is only used as a
147e83
#     flag.  The e_hypotl.c tests for large "a" and small "b" are mutually
147e83
#     exclusive because we've already exited when x/y > 2**120.  That allows
147e83
#     some further small simplifications.
147e83
#     
147e83
#         [BZ #15734], [BZ #15735]
147e83
#         * sysdeps/ieee754/ldbl-128ibm/e_fmodl.c (__ieee754_fmodl): Rewrite
147e83
#         all uses of ieee875 long double macros and unions.  Simplify test
147e83
#         for 0.0L.  Correct |x|<|y| and |x|=|y| test.  Use
147e83
#         ldbl_extract_mantissa value for ix,iy exponents.  Properly
147e83
#         normalize after ldbl_extract_mantissa, and don't add hidden bit
147e83
#         already handled.  Don't treat low word of ieee854 mantissa like
147e83
#         low word of IBM long double and mask off bit when testing for
147e83
#         zero.
147e83
#         * sysdeps/ieee754/ldbl-128ibm/e_hypotl.c (__ieee754_hypotl): Rewrite
147e83
#         all uses of ieee875 long double macros and unions.  Simplify tests
147e83
#         for 0.0L and inf.  Correct double adjustment of k.  Delete dead code
147e83
#         adjusting ha,hb.  Simplify code setting kld.  Delete two600 and
147e83
#         two1022, instead use their values.  Recognise that tests for large
147e83
#         "a" and small "b" are mutually exclusive.  Rename vars.  Comment.
147e83
#         * sysdeps/ieee754/ldbl-128ibm/e_remainderl.c (__ieee754_remainderl):
147e83
#         Rewrite all uses of ieee875 long double macros and unions.  Simplify
147e83
#         test for 0.0L and nan.  Correct negation.
147e83
#         * sysdeps/ieee754/ldbl-128ibm/s_erfl.c (__erfl): Rewrite all uses of
147e83
#         ieee875 long double macros and unions.  Correct output for large
147e83
#         magnitude x.  Correct absolute value calculation.
147e83
#         (__erfcl): Likewise.
147e83
#         * math/libm-test.inc: Add tests for errors discovered in IBM long
147e83
#         double versions of fmodl, remainderl, erfl and erfcl.
147e83
# 
147e83
diff -urN glibc-2.17-c758a686/math/libm-test.inc glibc-2.17-c758a686/math/libm-test.inc
147e83
--- glibc-2.17-c758a686/math/libm-test.inc	2014-05-27 20:02:29.000000000 -0500
147e83
+++ glibc-2.17-c758a686/math/libm-test.inc	2014-05-27 20:09:59.000000000 -0500
147e83
@@ -4040,6 +4040,10 @@
147e83
   TEST_f_f (erf, 2.0L, 0.995322265018952734162069256367252929L);
147e83
   TEST_f_f (erf, 4.125L, 0.999999994576599200434933994687765914L);
147e83
   TEST_f_f (erf, 27.0L, 1.0L);
147e83
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 54
147e83
+  /* The input is not exactly representable as a double.  */
147e83
+  TEST_f_f (erf, -0x1.fffffffffffff8p-2L, -0.5204998778130465132916303345518417673509L);
147e83
+#endif
147e83
 
147e83
   END (erf);
147e83
 }
147e83
@@ -4071,6 +4075,10 @@
147e83
   TEST_f_f (erfc, 0x1.ffa002p+2L, 1.233585992097580296336099501489175967033e-29L);
147e83
   TEST_f_f (erfc, 0x1.ffffc8p+2L, 1.122671365033056305522366683719541099329e-29L);
147e83
 #ifdef TEST_LDOUBLE
147e83
+# if LDBL_MANT_DIG >= 54
147e83
+  /* The input is not exactly representable as a double.  */
147e83
+  TEST_f_f (erfc, -0x1.fffffffffffff8p-2L, 1.52049987781304651329163033455184176735L);
147e83
+# endif
147e83
   /* The result can only be represented in long double.  */
147e83
 # if LDBL_MIN_10_EXP < -319
147e83
   TEST_f_f (erfc, 27.0L, 0.523704892378925568501606768284954709e-318L);
147e83
@@ -5634,6 +5642,13 @@
147e83
 #if defined TEST_LDOUBLE && LDBL_MIN_EXP <= -16381
147e83
   TEST_ff_f (fmod, 0x0.fffffffffffffffep-16382L, 0x1p-16445L, plus_zero);
147e83
 #endif
147e83
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 56
147e83
+  TEST_ff_f (fmod, -0x1.00000000000004p+0L, 0x1.fffffffffffff8p-1L, -0x1p-53L);
147e83
+  TEST_ff_f (fmod, 0x1.fffffffffffffap-1L, 0x1.fffffffffffff8p-1L, 0x1p-56L);
147e83
+  TEST_ff_f (fmod, -0x1.fffffffffffffap-1L, 0x1.fffffffffffff8p-1L, -0x1p-56L);
147e83
+  TEST_ff_f (fmod, 0x1.fffffffffffffap-1L, -0x1.fffffffffffff8p-1L, 0x1p-56L);
147e83
+  TEST_ff_f (fmod, -0x1.fffffffffffffap-1L, -0x1.fffffffffffff8p-1L, -0x1p-56L);
147e83
+#endif
147e83
 
147e83
   END (fmod);
147e83
 }
147e83
@@ -8642,6 +8657,9 @@
147e83
   TEST_ff_f (remainder, -1.625, -1.0, 0.375);
147e83
   TEST_ff_f (remainder, 5.0, 2.0, 1.0);
147e83
   TEST_ff_f (remainder, 3.0, 2.0, -1.0);
147e83
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 56
147e83
+  TEST_ff_f (remainder, -0x1.80000000000002p1L, 2.0, 0x1.fffffffffffff8p-1L);
147e83
+#endif
147e83
 
147e83
   END (remainder);
147e83
 }
147e83
diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_fmodl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_fmodl.c
147e83
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_fmodl.c	2014-05-27 20:02:27.000000000 -0500
147e83
+++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_fmodl.c	2014-05-27 20:04:08.000000000 -0500
147e83
@@ -27,76 +27,83 @@
147e83
 long double
147e83
 __ieee754_fmodl (long double x, long double y)
147e83
 {
147e83
-	int64_t n,hx,hy,hz,ix,iy,sx, i;
147e83
-	u_int64_t lx,ly,lz;
147e83
-	int temp;
147e83
-
147e83
-	GET_LDOUBLE_WORDS64(hx,lx,x);
147e83
-	GET_LDOUBLE_WORDS64(hy,ly,y);
147e83
+	int64_t hx, hy, hz, sx, sy;
147e83
+	uint64_t lx, ly, lz;
147e83
+	int n, ix, iy;
147e83
+	double xhi, xlo, yhi, ylo;
147e83
+
147e83
+	ldbl_unpack (x, &xhi, &xlo;;
147e83
+	EXTRACT_WORDS64 (hx, xhi);
147e83
+	EXTRACT_WORDS64 (lx, xlo);
147e83
+	ldbl_unpack (y, &yhi, &ylo);
147e83
+	EXTRACT_WORDS64 (hy, yhi);
147e83
+	EXTRACT_WORDS64 (ly, ylo);
147e83
 	sx = hx&0x8000000000000000ULL;		/* sign of x */
147e83
-	hx ^=sx;				/* |x| */
147e83
-	hy &= 0x7fffffffffffffffLL;		/* |y| */
147e83
+	hx ^= sx;				/* |x| */
147e83
+	sy = hy&0x8000000000000000ULL;		/* sign of y */
147e83
+	hy ^= sy;				/* |y| */
147e83
 
147e83
     /* purge off exception values */
147e83
-	if(__builtin_expect((hy|(ly&0x7fffffffffffffff))==0 ||
147e83
+	if(__builtin_expect(hy==0 ||
147e83
 			    (hx>=0x7ff0000000000000LL)|| /* y=0,or x not finite */
147e83
 			    (hy>0x7ff0000000000000LL),0))	/* or y is NaN */
147e83
 	    return (x*y)/(x*y);
147e83
-	if(__builtin_expect(hx<=hy,0)) {
147e83
-	    if((hx
147e83
-	    if(lx==ly)
147e83
-		return Zero[(u_int64_t)sx>>63];	/* |x|=|y| return x*0*/
147e83
+	if (__builtin_expect (hx <= hy, 0))
147e83
+	  {
147e83
+	    /* If |x| < |y| return x.  */
147e83
+	    if (hx < hy)
147e83
+	      return x;
147e83
+	    /* At this point the absolute value of the high doubles of
147e83
+	       x and y must be equal.  */
147e83
+	    /* If the low double of y is the same sign as the high
147e83
+	       double of y (ie. the low double increases |y|)...  */
147e83
+	    if (((ly ^ sy) & 0x8000000000000000LL) == 0
147e83
+		/* ... then a different sign low double to high double
147e83
+		   for x or same sign but lower magnitude...  */
147e83
+		&& (int64_t) (lx ^ sx) < (int64_t) (ly ^ sy))
147e83
+	      /* ... means |x| < |y|.  */
147e83
+	      return x;
147e83
+	    /* If the low double of x differs in sign to the high
147e83
+	       double of x (ie. the low double decreases |x|)...  */
147e83
+	    if (((lx ^ sx) & 0x8000000000000000LL) != 0
147e83
+		/* ... then a different sign low double to high double
147e83
+		   for y with lower magnitude (we've already caught
147e83
+		   the same sign for y case above)...  */
147e83
+		&& (int64_t) (lx ^ sx) > (int64_t) (ly ^ sy))
147e83
+	      /* ... means |x| < |y|.  */
147e83
+	      return x;
147e83
+	    /* If |x| == |y| return x*0.  */
147e83
+	    if ((lx ^ sx) == (ly ^ sy))
147e83
+	      return Zero[(uint64_t) sx >> 63];
147e83
 	}
147e83
 
147e83
-    /* determine ix = ilogb(x) */
147e83
-	if(__builtin_expect(hx<0x0010000000000000LL,0)) {	/* subnormal x */
147e83
-	    if(hx==0) {
147e83
-		for (ix = -1043, i=lx; i>0; i<<=1) ix -=1;
147e83
-	    } else {
147e83
-		for (ix = -1022, i=(hx<<11); i>0; i<<=1) ix -=1;
147e83
-	    }
147e83
-	} else ix = (hx>>52)-0x3ff;
147e83
-
147e83
-    /* determine iy = ilogb(y) */
147e83
-	if(__builtin_expect(hy<0x0010000000000000LL,0)) {	/* subnormal y */
147e83
-	    if(hy==0) {
147e83
-		for (iy = -1043, i=ly; i>0; i<<=1) iy -=1;
147e83
-	    } else {
147e83
-		for (iy = -1022, i=(hy<<11); i>0; i<<=1) iy -=1;
147e83
-	    }
147e83
-	} else iy = (hy>>52)-0x3ff;
147e83
-
147e83
     /* Make the IBM extended format 105 bit mantissa look like the ieee854 112
147e83
        bit mantissa so the following operations will give the correct
147e83
        result.  */
147e83
-	ldbl_extract_mantissa(&hx, &lx, &temp, x);
147e83
-	ldbl_extract_mantissa(&hy, &ly, &temp, y);
147e83
+	ldbl_extract_mantissa(&hx, &lx, &ix, x);
147e83
+	ldbl_extract_mantissa(&hy, &ly, &iy, y);
147e83
 
147e83
-    /* set up {hx,lx}, {hy,ly} and align y to x */
147e83
-	if(__builtin_expect(ix >= -1022, 1))
147e83
-	    hx = 0x0001000000000000LL|(0x0000ffffffffffffLL&hx;;
147e83
-	else {		/* subnormal x, shift x to normal */
147e83
-	    n = -1022-ix;
147e83
-	    if(n<=63) {
147e83
-		hx = (hx<<n)|(lx>>(64-n));
147e83
-		lx <<= n;
147e83
-	    } else {
147e83
-		hx = lx<<(n-64);
147e83
-		lx = 0;
147e83
-	    }
147e83
-	}
147e83
-	if(__builtin_expect(iy >= -1022, 1))
147e83
-	    hy = 0x0001000000000000LL|(0x0000ffffffffffffLL&hy);
147e83
-	else {		/* subnormal y, shift y to normal */
147e83
-	    n = -1022-iy;
147e83
-	    if(n<=63) {
147e83
-		hy = (hy<<n)|(ly>>(64-n));
147e83
-		ly <<= n;
147e83
-	    } else {
147e83
-		hy = ly<<(n-64);
147e83
-		ly = 0;
147e83
-	    }
147e83
-	}
147e83
+	if (__builtin_expect (ix == -IEEE754_DOUBLE_BIAS, 0))
147e83
+	  {
147e83
+	    /* subnormal x, shift x to normal.  */
147e83
+	    while ((hx & (1LL << 48)) == 0)
147e83
+	      {
147e83
+		hx = (hx << 1) | (lx >> 63);
147e83
+		lx = lx << 1;
147e83
+		ix -= 1;
147e83
+	      }
147e83
+	  }
147e83
+
147e83
+	if (__builtin_expect (iy == -IEEE754_DOUBLE_BIAS, 0))
147e83
+	  {
147e83
+	    /* subnormal y, shift y to normal.  */
147e83
+	    while ((hy & (1LL << 48)) == 0)
147e83
+	      {
147e83
+		hy = (hy << 1) | (ly >> 63);
147e83
+		ly = ly << 1;
147e83
+		iy -= 1;
147e83
+	      }
147e83
+	  }
147e83
 
147e83
     /* fix point fmod */
147e83
 	n = ix - iy;
147e83
@@ -104,7 +111,7 @@
147e83
 	    hz=hx-hy;lz=lx-ly; if(lx
147e83
 	    if(hz<0){hx = hx+hx+(lx>>63); lx = lx+lx;}
147e83
 	    else {
147e83
-		if((hz|(lz&0x7fffffffffffffff))==0)		/* return sign(x)*0 */
147e83
+		if((hz|lz)==0)		/* return sign(x)*0 */
147e83
 		    return Zero[(u_int64_t)sx>>63];
147e83
 		hx = hz+hz+(lz>>63); lx = lz+lz;
147e83
 	    }
147e83
@@ -113,7 +120,7 @@
147e83
 	if(hz>=0) {hx=hz;lx=lz;}
147e83
 
147e83
     /* convert back to floating value and restore the sign */
147e83
-	if((hx|(lx&0x7fffffffffffffff))==0)			/* return sign(x)*0 */
147e83
+	if((hx|lx)==0)			/* return sign(x)*0 */
147e83
 	    return Zero[(u_int64_t)sx>>63];
147e83
 	while(hx<0x0001000000000000LL) {	/* normalize x */
147e83
 	    hx = hx+hx+(lx>>63); lx = lx+lx;
147e83
diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_hypotl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_hypotl.c
147e83
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_hypotl.c	2014-05-27 20:02:27.000000000 -0500
147e83
+++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_hypotl.c	2014-05-27 20:04:08.000000000 -0500
147e83
@@ -45,76 +45,84 @@
147e83
 #include <math.h>
147e83
 #include <math_private.h>
147e83
 
147e83
-static const long double two600 = 0x1.0p+600L;
147e83
-static const long double two1022 = 0x1.0p+1022L;
147e83
-
147e83
 long double
147e83
 __ieee754_hypotl(long double x, long double y)
147e83
 {
147e83
-	long double a,b,t1,t2,y1,y2,w,kld;
147e83
+	long double a,b,a1,a2,b1,b2,w,kld;
147e83
 	int64_t j,k,ha,hb;
147e83
+	double xhi, yhi, hi, lo;
147e83
 
147e83
-	GET_LDOUBLE_MSW64(ha,x);
147e83
+	xhi = ldbl_high (x);
147e83
+	EXTRACT_WORDS64 (ha, xhi);
147e83
+	yhi = ldbl_high (y);
147e83
+	EXTRACT_WORDS64 (hb, yhi);
147e83
 	ha &= 0x7fffffffffffffffLL;
147e83
-	GET_LDOUBLE_MSW64(hb,y);
147e83
 	hb &= 0x7fffffffffffffffLL;
147e83
 	if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;}
147e83
 	a = fabsl(a);	/* a <- |a| */
147e83
 	b = fabsl(b);	/* b <- |b| */
147e83
-	if((ha-hb)>0x780000000000000LL) {return a+b;} /* x/y > 2**120 */
147e83
+	if((ha-hb)>0x0780000000000000LL) {return a+b;} /* x/y > 2**120 */
147e83
 	k=0;
147e83
 	kld = 1.0L;
147e83
 	if(ha > 0x5f30000000000000LL) {	/* a>2**500 */
147e83
 	   if(ha >= 0x7ff0000000000000LL) {	/* Inf or NaN */
147e83
-	       u_int64_t low;
147e83
 	       w = a+b;			/* for sNaN */
147e83
-	       GET_LDOUBLE_LSW64(low,a);
147e83
-	       if(((ha&0xfffffffffffffLL)|(low&0x7fffffffffffffffLL))==0)
147e83
+	       if(ha == 0x7ff0000000000000LL)
147e83
 		 w = a;
147e83
-	       GET_LDOUBLE_LSW64(low,b);
147e83
-	       if(((hb^0x7ff0000000000000LL)|(low&0x7fffffffffffffffLL))==0)
147e83
+	       if(hb == 0x7ff0000000000000LL)
147e83
 		 w = b;
147e83
 	       return w;
147e83
 	   }
147e83
 	   /* scale a and b by 2**-600 */
147e83
-	   ha -= 0x2580000000000000LL; hb -= 0x2580000000000000LL; k += 600;
147e83
-	   a /= two600;
147e83
-	   b /= two600;
147e83
-	   k += 600;
147e83
-	   kld = two600;
147e83
+	   a *= 0x1p-600L;
147e83
+	   b *= 0x1p-600L;
147e83
+	   k = 600;
147e83
+	   kld = 0x1p+600L;
147e83
 	}
147e83
-	if(hb < 0x23d0000000000000LL) {	/* b < 2**-450 */
147e83
+	else if(hb < 0x23d0000000000000LL) {	/* b < 2**-450 */
147e83
 	    if(hb <= 0x000fffffffffffffLL) {	/* subnormal b or 0 */
147e83
-		u_int64_t low;
147e83
-		GET_LDOUBLE_LSW64(low,b);
147e83
-		if((hb|(low&0x7fffffffffffffffLL))==0) return a;
147e83
-		t1=two1022;	/* t1=2^1022 */
147e83
-		b *= t1;
147e83
-		a *= t1;
147e83
-		k -= 1022;
147e83
-		kld = kld / two1022;
147e83
+		if(hb==0) return a;
147e83
+		a *= 0x1p+1022L;
147e83
+		b *= 0x1p+1022L;
147e83
+		k = -1022;
147e83
+		kld = 0x1p-1022L;
147e83
 	    } else {		/* scale a and b by 2^600 */
147e83
-		ha += 0x2580000000000000LL;	/* a *= 2^600 */
147e83
-		hb += 0x2580000000000000LL;	/* b *= 2^600 */
147e83
-		k -= 600;
147e83
-		a *= two600;
147e83
-		b *= two600;
147e83
-		kld = kld / two600;
147e83
+		a *= 0x1p+600L;
147e83
+		b *= 0x1p+600L;
147e83
+		k = -600;
147e83
+		kld = 0x1p-600L;
147e83
 	    }
147e83
 	}
147e83
     /* medium size a and b */
147e83
 	w = a-b;
147e83
 	if (w>b) {
147e83
-	    SET_LDOUBLE_WORDS64(t1,ha,0);
147e83
-	    t2 = a-t1;
147e83
-	    w  = __ieee754_sqrtl(t1*t1-(b*(-b)-t2*(a+t1)));
147e83
+	    ldbl_unpack (a, &hi, &lo);
147e83
+	    a1 = hi;
147e83
+	    a2 = lo;
147e83
+	    /* a*a + b*b
147e83
+	       = (a1+a2)*a + b*b
147e83
+	       = a1*a + a2*a + b*b
147e83
+	       = a1*(a1+a2) + a2*a + b*b
147e83
+	       = a1*a1 + a1*a2 + a2*a + b*b
147e83
+	       = a1*a1 + a2*(a+a1) + b*b  */
147e83
+	    w  = __ieee754_sqrtl(a1*a1-(b*(-b)-a2*(a+a1)));
147e83
 	} else {
147e83
 	    a  = a+a;
147e83
-	    SET_LDOUBLE_WORDS64(y1,hb,0);
147e83
-	    y2 = b - y1;
147e83
-	    SET_LDOUBLE_WORDS64(t1,ha+0x0010000000000000LL,0);
147e83
-	    t2 = a - t1;
147e83
-	    w  = __ieee754_sqrtl(t1*y1-(w*(-w)-(t1*y2+t2*b)));
147e83
+	    ldbl_unpack (b, &hi, &lo);
147e83
+	    b1 = hi;
147e83
+	    b2 = lo;
147e83
+	    ldbl_unpack (a, &hi, &lo);
147e83
+	    a1 = hi;
147e83
+	    a2 = lo;
147e83
+	    /* a*a + b*b
147e83
+	       = a*a + (a-b)*(a-b) - (a-b)*(a-b) + b*b
147e83
+	       = a*a + w*w  - (a*a - 2*a*b + b*b) + b*b
147e83
+	       = w*w + 2*a*b
147e83
+	       = w*w + (a1+a2)*b
147e83
+	       = w*w + a1*b + a2*b
147e83
+	       = w*w + a1*(b1+b2) + a2*b
147e83
+	       = w*w + a1*b1 + a1*b2 + a2*b  */
147e83
+	    w  = __ieee754_sqrtl(a1*b1-(w*(-w)-(a1*b2+a2*b)));
147e83
 	}
147e83
 	if(k!=0)
147e83
 	    return w*kld;
147e83
diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_remainderl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_remainderl.c
147e83
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_remainderl.c	2014-05-27 20:02:27.000000000 -0500
147e83
+++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_remainderl.c	2014-05-27 20:04:08.000000000 -0500
147e83
@@ -33,18 +33,22 @@
147e83
 	int64_t hx,hp;
147e83
 	u_int64_t sx,lx,lp;
147e83
 	long double p_half;
147e83
+	double xhi, xlo, phi, plo;
147e83
 
147e83
-	GET_LDOUBLE_WORDS64(hx,lx,x);
147e83
-	GET_LDOUBLE_WORDS64(hp,lp,p);
147e83
+	ldbl_unpack (x, &xhi, &xlo;;
147e83
+	EXTRACT_WORDS64 (hx, xhi);
147e83
+	EXTRACT_WORDS64 (lx, xlo);
147e83
+	ldbl_unpack (p, &phi, &plo;;
147e83
+	EXTRACT_WORDS64 (hp, phi);
147e83
+	EXTRACT_WORDS64 (lp, plo);
147e83
 	sx = hx&0x8000000000000000ULL;
147e83
 	hp &= 0x7fffffffffffffffLL;
147e83
 	hx &= 0x7fffffffffffffffLL;
147e83
 
147e83
     /* purge off exception values */
147e83
-	if((hp|(lp&0x7fffffffffffffff))==0) return (x*p)/(x*p);	/* p = 0 */
147e83
+	if(hp==0) return (x*p)/(x*p);	/* p = 0 */
147e83
 	if((hx>=0x7ff0000000000000LL)||			/* x not finite */
147e83
-	  ((hp>=0x7ff0000000000000LL)&&			/* p is NaN */
147e83
-	  (((hp-0x7ff0000000000000LL)|lp)!=0)))
147e83
+	   (hp>0x7ff0000000000000LL))			/* p is NaN */
147e83
 	    return (x*p)/(x*p);
147e83
 
147e83
 
147e83
@@ -64,8 +68,8 @@
147e83
 		if(x>=p_half) x -= p;
147e83
 	    }
147e83
 	}
147e83
-	GET_LDOUBLE_MSW64(hx,x);
147e83
-	SET_LDOUBLE_MSW64(x,hx^sx);
147e83
+	if (sx)
147e83
+	  x = -x;
147e83
 	return x;
147e83
 }
147e83
 strong_alias (__ieee754_remainderl, __remainderl_finite)
147e83
diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_erfl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_erfl.c
147e83
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_erfl.c	2014-05-27 20:02:27.000000000 -0500
147e83
+++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_erfl.c	2014-05-27 20:04:08.000000000 -0500
147e83
@@ -760,16 +760,16 @@
147e83
 __erfl (long double x)
147e83
 {
147e83
   long double a, y, z;
147e83
-  int32_t i, ix, sign;
147e83
-  ieee854_long_double_shape_type u;
147e83
+  int32_t i, ix, hx;
147e83
+  double xhi;
147e83
 
147e83
-  u.value = x;
147e83
-  sign = u.parts32.w0;
147e83
-  ix = sign & 0x7fffffff;
147e83
+  xhi = ldbl_high (x);
147e83
+  GET_HIGH_WORD (hx, xhi);
147e83
+  ix = hx & 0x7fffffff;
147e83
 
147e83
   if (ix >= 0x7ff00000)
147e83
     {				/* erf(nan)=nan */
147e83
-      i = ((sign & 0xfff00000) >> 31) << 1;
147e83
+      i = ((uint32_t) hx >> 31) << 1;
147e83
       return (long double) (1 - i) + one / x;	/* erf(+-inf)=+-1 */
147e83
     }
147e83
 
147e83
@@ -778,7 +778,7 @@
147e83
       if (ix >= 0x4039A0DE)
147e83
 	{
147e83
 	/* __erfcl (x) underflows if x > 25.6283 */
147e83
-	  if (sign)
147e83
+	  if ((hx & 0x80000000) == 0)
147e83
 	    return one-tiny;
147e83
 	  else
147e83
 	    return tiny-one;
147e83
@@ -789,8 +789,9 @@
147e83
 	  return (one - y);
147e83
 	}
147e83
     }
147e83
-  u.parts32.w0 = ix;
147e83
-  a = u.value;
147e83
+  a = x;
147e83
+  if ((hx & 0x80000000) != 0)
147e83
+    a = -a;
147e83
   z = x * x;
147e83
   if (ix < 0x3fec0000)  /* a < 0.875 */
147e83
     {
147e83
@@ -814,7 +815,7 @@
147e83
       y = erf_const + neval (a, TN2, NTN2) / deval (a, TD2, NTD2);
147e83
     }
147e83
 
147e83
-  if (sign & 0x80000000) /* x < 0 */
147e83
+  if (hx & 0x80000000) /* x < 0 */
147e83
     y = -y;
147e83
   return( y );
147e83
 }
147e83
@@ -824,18 +825,18 @@
147e83
 __erfcl (long double x)
147e83
 {
147e83
   long double y, z, p, r;
147e83
-  int32_t i, ix, sign;
147e83
-  ieee854_long_double_shape_type u;
147e83
-
147e83
-  u.value = x;
147e83
-  sign = u.parts32.w0;
147e83
-  ix = sign & 0x7fffffff;
147e83
-  u.parts32.w0 = ix;
147e83
+  int32_t i, ix;
147e83
+  uint32_t hx;
147e83
+  double xhi;
147e83
+
147e83
+  xhi = ldbl_high (x);
147e83
+  GET_HIGH_WORD (hx, xhi);
147e83
+  ix = hx & 0x7fffffff;
147e83
 
147e83
   if (ix >= 0x7ff00000)
147e83
     {				/* erfc(nan)=nan */
147e83
       /* erfc(+-inf)=0,2 */
147e83
-      return (long double) (((u_int32_t) sign >> 31) << 1) + one / x;
147e83
+      return (long double) ((hx >> 31) << 1) + one / x;
147e83
     }
147e83
 
147e83
   if (ix < 0x3fd00000) /* |x| <1/4 */
147e83
@@ -846,7 +847,8 @@
147e83
     }
147e83
   if (ix < 0x3ff40000) /* 1.25 */
147e83
     {
147e83
-      x = u.value;
147e83
+      if ((hx & 0x80000000) != 0)
147e83
+	x = -x;
147e83
       i = 8.0 * x;
147e83
       switch (i)
147e83
 	{
147e83
@@ -891,7 +893,7 @@
147e83
 	  y += C20a;
147e83
 	  break;
147e83
 	}
147e83
-      if (sign & 0x80000000)
147e83
+      if (hx & 0x80000000)
147e83
 	y = 2.0L - y;
147e83
       return y;
147e83
     }
147e83
@@ -899,10 +901,11 @@
147e83
   if (ix < 0x405ac000)
147e83
     {
147e83
       /* x < -9 */
147e83
-      if ((ix >= 0x40220000) && (sign & 0x80000000))
147e83
+      if (hx >= 0xc0220000)
147e83
 	return two - tiny;
147e83
 
147e83
-      x = fabsl (x);
147e83
+      if ((hx & 0x80000000) != 0)
147e83
+	x = -x;
147e83
       z = one / (x * x);
147e83
       i = 8.0 / x;
147e83
       switch (i)
147e83
@@ -933,21 +936,17 @@
147e83
 	  p = neval (z, RNr8, NRNr8) / deval (z, RDr8, NRDr8);
147e83
 	  break;
147e83
 	}
147e83
-      u.value = x;
147e83
-      u.parts32.w3 = 0;
147e83
-      u.parts32.w2 = 0;
147e83
-      u.parts32.w1 &= 0xf8000000;
147e83
-      z = u.value;
147e83
+      z = (float) x;
147e83
       r = __ieee754_expl (-z * z - 0.5625) *
147e83
 	__ieee754_expl ((z - x) * (z + x) + p);
147e83
-      if ((sign & 0x80000000) == 0)
147e83
+      if ((hx & 0x80000000) == 0)
147e83
 	return r / x;
147e83
       else
147e83
 	return two - r / x;
147e83
     }
147e83
   else
147e83
     {
147e83
-      if ((sign & 0x80000000) == 0)
147e83
+      if ((hx & 0x80000000) == 0)
147e83
 	return tiny * tiny;
147e83
       else
147e83
 	return two - tiny;