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