00db10
# commit 4cf69995e26e16005d4e3843ad4d18c75cf21a04
00db10
# Author: Alan Modra <amodra@gmail.com>
00db10
# Date:   Sat Aug 17 18:19:44 2013 +0930
00db10
# 
00db10
#     Fix for [BZ #15680] IBM long double inaccuracy
00db10
#     http://sourceware.org/ml/libc-alpha/2013-06/msg00919.html
00db10
#     
00db10
#     I discovered a number of places where denormals and other corner cases
00db10
#     were being handled wrongly.
00db10
#     
00db10
#     - printf_fphex.c: Testing for the low double exponent being zero is
00db10
#     unnecessary.  If the difference in exponents is less than 53 then the
00db10
#     high double exponent must be nearing the low end of its range, and the
00db10
#     low double exponent hit rock bottom.
00db10
#     
00db10
#     - ldbl2mpn.c: A denormal (ie. exponent of zero) value is treated as
00db10
#     if the exponent was one, so shift mantissa left by one.  Code handling
00db10
#     normalisation of the low double mantissa lacked a test for shift count
00db10
#     greater than bits in type being shifted, and lacked anything to handle
00db10
#     the case where the difference in exponents is less than 53 as in
00db10
#     printf_fphex.c.
00db10
#     
00db10
#     - math_ldbl.h (ldbl_extract_mantissa): Same as above, but worse, with
00db10
#     code testing for exponent > 1 for some reason, probably a typo for >= 1.
00db10
#     
00db10
#     - math_ldbl.h (ldbl_insert_mantissa): Round the high double as per
00db10
#     mpn2ldbl.c (hi is odd or explicit mantissas non-zero) so that the
00db10
#     number we return won't change when applying ldbl_canonicalize().
00db10
#     Add missing overflow checks and normalisation of high mantissa.
00db10
#     Correct misleading comment: "The hidden bit of the lo mantissa is
00db10
#     zero" is not always true as can be seen from the code rounding the hi
00db10
#     mantissa.  Also by inspection, lzcount can never be less than zero so
00db10
#     remove that test.  Lastly, masking bitfields to their widths can be
00db10
#     left to the compiler.
00db10
#     
00db10
#     - mpn2ldbl.c: The overflow checks here on rounding of high double were
00db10
#     just plain wrong.  Incrementing the exponent must be accompanied by a
00db10
#     shift right of the mantissa to keep the value unchanged.  Above notes
00db10
#     for ldbl_insert_mantissa are also relevant.
00db10
#     
00db10
#         [BZ #15680]
00db10
#         * sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c: Comment fix.
00db10
#         * sysdeps/ieee754/ldbl-128ibm/printf_fphex.c
00db10
#         (PRINT_FPHEX_LONG_DOUBLE): Tidy code by moving -53 into ediff
00db10
#         calculation.  Remove unnecessary test for denormal exponent.
00db10
#         * sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c (__mpn_extract_long_double):
00db10
#         Correct handling of denormals.  Avoid undefined shift behaviour.
00db10
#         Correct normalisation of low mantissa when low double is denormal.
00db10
#         * sysdeps/ieee754/ldbl-128ibm/math_ldbl.h
00db10
#         (ldbl_extract_mantissa): Likewise.  Comment.  Use uint64_t* for hi64.
00db10
#         (ldbl_insert_mantissa): Make both hi64 and lo64 parms uint64_t.
00db10
#         Correct normalisation of low mantissa.  Test for overflow of high
00db10
#         mantissa and normalise.
00db10
#         (ldbl_nearbyint): Use more readable constant for two52.
00db10
#         * sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c
00db10
#         (__mpn_construct_long_double): Fix test for overflow of high
00db10
#         mantissa and correct normalisation.  Avoid undefined shift.
00db10
# 
00db10
diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c
00db10
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c	2014-05-27 19:13:56.000000000 -0500
00db10
+++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c	2014-05-27 19:14:45.000000000 -0500
00db10
@@ -243,7 +243,7 @@
00db10
      We split the 113 bits of the mantissa into 5 24bit integers
00db10
      stored in a double array.  */
00db10
   /* Make the IBM extended format 105 bit mantissa look like the ieee854 112
00db10
-     bit mantissa so the next operatation will give the correct result.  */
00db10
+     bit mantissa so the next operation will give the correct result.  */
00db10
   ldbl_extract_mantissa (&ixd, &lxd, &exp, x);
00db10
   exp = exp - 23;
00db10
   /* This is faster than doing this in floating point, because we
00db10
diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c
00db10
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c	2014-05-27 19:13:56.000000000 -0500
00db10
+++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c	2014-05-27 19:14:45.000000000 -0500
00db10
@@ -36,6 +36,7 @@
00db10
   union ibm_extended_long_double u;
00db10
   unsigned long long hi, lo;
00db10
   int ediff;
00db10
+
00db10
   u.ld = value;
00db10
 
00db10
   *is_neg = u.d[0].ieee.negative;
00db10
@@ -43,27 +44,36 @@
00db10
 
00db10
   lo = ((long long) u.d[1].ieee.mantissa0 << 32) | u.d[1].ieee.mantissa1;
00db10
   hi = ((long long) u.d[0].ieee.mantissa0 << 32) | u.d[0].ieee.mantissa1;
00db10
-  /* If the lower double is not a denomal or zero then set the hidden
00db10
+
00db10
+  /* If the lower double is not a denormal or zero then set the hidden
00db10
      53rd bit.  */
00db10
-  if (u.d[1].ieee.exponent > 0)
00db10
-    {
00db10
-      lo |= 1LL << 52;
00db10
+  if (u.d[1].ieee.exponent != 0)
00db10
+    lo |= 1ULL << 52;
00db10
+  else
00db10
+    lo = lo << 1;
00db10
 
00db10
-      /* The lower double is normalized separately from the upper.  We may
00db10
-	 need to adjust the lower manitissa to reflect this.  */
00db10
-      ediff = u.d[0].ieee.exponent - u.d[1].ieee.exponent;
00db10
-      if (ediff > 53)
00db10
-	lo = lo >> (ediff-53);
00db10
+  /* The lower double is normalized separately from the upper.  We may
00db10
+     need to adjust the lower manitissa to reflect this.  */
00db10
+  ediff = u.d[0].ieee.exponent - u.d[1].ieee.exponent - 53;
00db10
+  if (ediff > 0)
00db10
+    {
00db10
+      if (ediff < 64)
00db10
+	lo = lo >> ediff;
00db10
+      else
00db10
+	lo = 0;
00db10
     }
00db10
+  else if (ediff < 0)
00db10
+    lo = lo << -ediff;
00db10
+
00db10
   /* The high double may be rounded and the low double reflects the
00db10
      difference between the long double and the rounded high double
00db10
      value.  This is indicated by a differnce between the signs of the
00db10
      high and low doubles.  */
00db10
-  if ((u.d[0].ieee.negative != u.d[1].ieee.negative)
00db10
-      && ((u.d[1].ieee.exponent != 0) && (lo != 0L)))
00db10
+  if (u.d[0].ieee.negative != u.d[1].ieee.negative
00db10
+      && lo != 0)
00db10
     {
00db10
       lo = (1ULL << 53) - lo;
00db10
-      if (hi == 0LL)
00db10
+      if (hi == 0)
00db10
 	{
00db10
 	  /* we have a borrow from the hidden bit, so shift left 1.  */
00db10
 	  hi = 0x0ffffffffffffeLL | (lo >> 51);
00db10
diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h
00db10
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h	2014-05-27 19:13:56.000000000 -0500
00db10
+++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h	2014-05-27 19:51:13.000000000 -0500
00db10
@@ -13,77 +13,118 @@
00db10
      the number before the decimal point and the second implicit bit
00db10
      as bit 53 of the mantissa.  */
00db10
   uint64_t hi, lo;
00db10
-  int ediff;
00db10
   union ibm_extended_long_double u;
00db10
+
00db10
   u.ld = x;
00db10
   *exp = u.d[0].ieee.exponent - IEEE754_DOUBLE_BIAS;
00db10
 
00db10
   lo = ((uint64_t)u.d[1].ieee.mantissa0 << 32) | u.d[1].ieee.mantissa1;
00db10
   hi = ((uint64_t)u.d[0].ieee.mantissa0 << 32) | u.d[0].ieee.mantissa1;
00db10
-  /* If the lower double is not a denomal or zero then set the hidden
00db10
-     53rd bit.  */
00db10
-  if (u.d[1].ieee.exponent > 0x001)
00db10
-    {
00db10
-      lo |= (1ULL << 52);
00db10
-      lo = lo << 7; /* pre-shift lo to match ieee854.  */
00db10
-      /* The lower double is normalized separately from the upper.  We
00db10
-	 may need to adjust the lower manitissa to reflect this.  */
00db10
-      ediff = u.d[0].ieee.exponent - u.d[1].ieee.exponent;
00db10
-      if (ediff > 53)
00db10
-	lo = lo >> (ediff-53);
00db10
-      hi |= (1ULL << 52);
00db10
-    }
00db10
   
00db10
-  if ((u.d[0].ieee.negative != u.d[1].ieee.negative)
00db10
-      && ((u.d[1].ieee.exponent != 0) && (lo != 0LL)))
00db10
+  if (u.d[0].ieee.exponent != 0)
00db10
     {
00db10
-      hi--;
00db10
-      lo = (1ULL << 60) - lo;
00db10
-      if (hi < (1ULL << 52))
00db10
+      int ediff;
00db10
+
00db10
+      /* If not a denormal or zero then we have an implicit 53rd bit.  */
00db10
+      hi |= (uint64_t) 1 << 52;
00db10
+
00db10
+      if (u.d[1].ieee.exponent != 0)
00db10
+	lo |= (uint64_t) 1 << 52;
00db10
+      else
00db10
+	/* A denormal is to be interpreted as having a biased exponent
00db10
+	   of 1.  */
00db10
+	lo = lo << 1;
00db10
+
00db10
+      /* We are going to shift 4 bits out of hi later, because we only
00db10
+	 want 48 bits in *hi64.  That means we want 60 bits in lo, but
00db10
+	 we currently only have 53.  Shift the value up.  */
00db10
+      lo = lo << 7;
00db10
+
00db10
+      /* The lower double is normalized separately from the upper.
00db10
+	 We may need to adjust the lower mantissa to reflect this.
00db10
+	 The difference between the exponents can be larger than 53
00db10
+	 when the low double is much less than 1ULP of the upper
00db10
+	 (in which case there are significant bits, all 0's or all
00db10
+	 1's, between the two significands).  The difference between
00db10
+	 the exponents can be less than 53 when the upper double
00db10
+	 exponent is nearing its minimum value (in which case the low
00db10
+	 double is denormal ie. has an exponent of zero).  */
00db10
+      ediff = u.d[0].ieee.exponent - u.d[1].ieee.exponent - 53;
00db10
+      if (ediff > 0)
00db10
 	{
00db10
-	  /* we have a borrow from the hidden bit, so shift left 1.  */
00db10
-	  hi = (hi << 1) | (lo >> 59);
00db10
-	  lo = 0xfffffffffffffffLL & (lo << 1);
00db10
-	  *exp = *exp - 1;
00db10
+	  if (ediff < 64)
00db10
+	    lo = lo >> ediff;
00db10
+	  else
00db10
+	    lo = 0;
00db10
+	}
00db10
+      else if (ediff < 0)
00db10
+	lo = lo << -ediff;
00db10
+
00db10
+      if (u.d[0].ieee.negative != u.d[1].ieee.negative
00db10
+	  && lo != 0)
00db10
+	{
00db10
+	  hi--;
00db10
+	  lo = ((uint64_t) 1 << 60) - lo;
00db10
+	  if (hi < (uint64_t) 1 << 52)
00db10
+	    {
00db10
+	      /* We have a borrow from the hidden bit, so shift left 1.  */
00db10
+	      hi = (hi << 1) | (lo >> 59);
00db10
+	      lo = (((uint64_t) 1 << 60) - 1) & (lo << 1);
00db10
+	      *exp = *exp - 1;
00db10
+	    }
00db10
 	}
00db10
     }
00db10
+  else
00db10
+    /* If the larger magnitude double is denormal then the smaller
00db10
+       one must be zero.  */
00db10
+    hi = hi << 1;
00db10
+
00db10
   *lo64 = (hi << 60) | lo;
00db10
   *hi64 = hi >> 4;
00db10
 }
00db10
 
00db10
 static inline long double
00db10
-ldbl_insert_mantissa (int sign, int exp, int64_t hi64, u_int64_t lo64)
00db10
+ldbl_insert_mantissa (int sign, int exp, int64_t hi64, uint64_t lo64)
00db10
 {
00db10
   union ibm_extended_long_double u;
00db10
-  unsigned long hidden2, lzcount;
00db10
-  unsigned long long hi, lo;
00db10
+  int expnt2;
00db10
+  uint64_t hi, lo;
00db10
 
00db10
   u.d[0].ieee.negative = sign;
00db10
   u.d[1].ieee.negative = sign;
00db10
   u.d[0].ieee.exponent = exp + IEEE754_DOUBLE_BIAS;
00db10
-  u.d[1].ieee.exponent = exp-53 + IEEE754_DOUBLE_BIAS;
00db10
+  u.d[1].ieee.exponent = 0;
00db10
+  expnt2 = exp - 53 + IEEE754_DOUBLE_BIAS;
00db10
+ 
00db10
   /* Expect 113 bits (112 bits + hidden) right justified in two longs.
00db10
      The low order 53 bits (52 + hidden) go into the lower double */ 
00db10
-  lo = (lo64 >> 7)& ((1ULL << 53) - 1);
00db10
-  hidden2 = (lo64 >> 59) &  1ULL;
00db10
+  lo = (lo64 >> 7) & (((uint64_t) 1 << 53) - 1);
00db10
   /* The high order 53 bits (52 + hidden) go into the upper double */
00db10
-  hi = (lo64 >> 60) & ((1ULL << 11) - 1);
00db10
-  hi |= (hi64 << 4);
00db10
+  hi = lo64 >> 60;
00db10
+  hi |= hi64 << 4;
00db10
 
00db10
-  if (lo != 0LL)
00db10
+  if (lo != 0)
00db10
     {
00db10
-      /* hidden2 bit of low double controls rounding of the high double.
00db10
-	 If hidden2 is '1' then round up hi and adjust lo (2nd mantissa)
00db10
+      int lzcount;
00db10
+
00db10
+      /* hidden bit of low double controls rounding of the high double.
00db10
+	 If hidden is '1' and either the explicit mantissa is non-zero
00db10
+	 or hi is odd, then round up hi and adjust lo (2nd mantissa)
00db10
 	 plus change the sign of the low double to compensate.  */
00db10
-      if (hidden2)
00db10
+      if ((lo & ((uint64_t) 1 << 52)) != 0
00db10
+	  && ((hi & 1) != 0 || (lo & (((uint64_t) 1 << 52) - 1)) != 0))
00db10
 	{
00db10
 	  hi++;
00db10
+	  if ((hi & ((uint64_t) 1 << 53)) != 0)
00db10
+	    {
00db10
+	      hi = hi >> 1;
00db10
+	      u.d[0].ieee.exponent++;
00db10
+	    }
00db10
 	  u.d[1].ieee.negative = !sign;
00db10
-	  lo = (1ULL << 53) - lo;
00db10
+	  lo = ((uint64_t) 1 << 53) - lo;
00db10
 	}
00db10
-      /* The hidden bit of the lo mantissa is zero so we need to
00db10
-	 normalize the it for the low double.  Shift it left until the
00db10
-	 hidden bit is '1' then adjust the 2nd exponent accordingly.  */ 
00db10
+      /* Normalize the low double.  Shift the mantissa left until
00db10
+	 the hidden bit is '1' and adjust the exponent accordingly.  */
00db10
 
00db10
       if (sizeof (lo) == sizeof (long))
00db10
 	lzcount = __builtin_clzl (lo);
00db10
@@ -91,34 +132,30 @@
00db10
 	lzcount = __builtin_clzl ((long) (lo >> 32));
00db10
       else
00db10
 	lzcount = __builtin_clzl ((long) lo) + 32;
00db10
-      lzcount = lzcount - 11;
00db10
-      if (lzcount > 0)
00db10
+      lzcount = lzcount - (64 - 53);
00db10
+      lo <<= lzcount;
00db10
+      expnt2 -= lzcount;
00db10
+
00db10
+      if (expnt2 >= 1)
00db10
+	/* Not denormal.  */
00db10
+	u.d[1].ieee.exponent = expnt2;
00db10
+      else
00db10
 	{
00db10
-	  int expnt2 = u.d[1].ieee.exponent - lzcount;
00db10
-	  if (expnt2 >= 1)
00db10
-	    {
00db10
-	      /* Not denormal.  Normalize and set low exponent.  */
00db10
-	      lo = lo << lzcount;
00db10
-	      u.d[1].ieee.exponent = expnt2;
00db10
-	    }
00db10
+	  /* Is denormal.  Note that biased exponent of 0 is treated
00db10
+	     as if it was 1, hence the extra shift.  */
00db10
+	  if (expnt2 > -53)
00db10
+	    lo >>= 1 - expnt2;
00db10
 	  else
00db10
-	    {
00db10
-	      /* Is denormal.  */
00db10
-	      lo = lo << (lzcount + expnt2);
00db10
-	      u.d[1].ieee.exponent = 0;
00db10
-	    }
00db10
+	    lo = 0;
00db10
 	}
00db10
     }
00db10
   else
00db10
-    {
00db10
-      u.d[1].ieee.negative = 0;
00db10
-      u.d[1].ieee.exponent = 0;
00db10
-    }
00db10
+    u.d[1].ieee.negative = 0;
00db10
 
00db10
-  u.d[1].ieee.mantissa1 = lo & ((1ULL << 32) - 1);
00db10
-  u.d[1].ieee.mantissa0 = (lo >> 32) & ((1ULL << 20) - 1);
00db10
-  u.d[0].ieee.mantissa1 = hi & ((1ULL << 32) - 1);
00db10
-  u.d[0].ieee.mantissa0 = (hi >> 32) & ((1ULL << 20) - 1);
00db10
+  u.d[1].ieee.mantissa1 = lo;
00db10
+  u.d[1].ieee.mantissa0 = lo >> 32;
00db10
+  u.d[0].ieee.mantissa1 = hi;
00db10
+  u.d[0].ieee.mantissa0 = hi >> 32;
00db10
   return u.ld;
00db10
 }
00db10
   
00db10
@@ -133,6 +170,10 @@
00db10
   return u.ld;
00db10
 }
00db10
 
00db10
+/* To suit our callers we return *hi64 and *lo64 as if they came from
00db10
+   an ieee854 112 bit mantissa, that is, 48 bits in *hi64 (plus one
00db10
+   implicit bit) and 64 bits in *lo64.  */
00db10
+
00db10
 static inline void
00db10
 default_ldbl_unpack (long double l, double *a, double *aa)
00db10
 {
00db10
@@ -162,13 +203,13 @@
00db10
   *aa = xl;
00db10
 }
00db10
 
00db10
-/* Simple inline nearbyint (double) function .
00db10
+/* Simple inline nearbyint (double) function.
00db10
    Only works in the default rounding mode
00db10
    but is useful in long double rounding functions.  */
00db10
 static inline double
00db10
 ldbl_nearbyint (double a)
00db10
 {
00db10
-  double two52 = 0x10000000000000LL;
00db10
+  double two52 = 0x1p52;
00db10
 
00db10
   if (__builtin_expect ((__builtin_fabs (a) < two52), 1))
00db10
     {
00db10
diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c
00db10
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c	2014-05-27 19:13:56.000000000 -0500
00db10
+++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c	2014-05-27 19:14:45.000000000 -0500
00db10
@@ -70,9 +70,9 @@
00db10
       else
00db10
 	lzcount = __builtin_clzl ((long) val) + 32;
00db10
       if (hi)
00db10
-	lzcount = lzcount - 11;
00db10
+	lzcount = lzcount - (64 - 53);
00db10
       else
00db10
-	lzcount = lzcount + 42;
00db10
+	lzcount = lzcount + 53 - (64 - 53);
00db10
 
00db10
       if (lzcount > u.d[0].ieee.exponent)
00db10
 	{
00db10
@@ -98,29 +98,27 @@
00db10
 	}
00db10
     }
00db10
 
00db10
-  if (lo != 0L)
00db10
+  if (lo != 0)
00db10
     {
00db10
-      /* hidden2 bit of low double controls rounding of the high double.
00db10
-	 If hidden2 is '1' and either the explicit mantissa is non-zero
00db10
+      /* hidden bit of low double controls rounding of the high double.
00db10
+	 If hidden is '1' and either the explicit mantissa is non-zero
00db10
 	 or hi is odd, then round up hi and adjust lo (2nd mantissa)
00db10
 	 plus change the sign of the low double to compensate.  */
00db10
       if ((lo & (1LL << 52)) != 0
00db10
-	  && ((hi & 1) != 0 || (lo & ((1LL << 52) - 1))))
00db10
+	  && ((hi & 1) != 0 || (lo & ((1LL << 52) - 1)) != 0))
00db10
 	{
00db10
 	  hi++;
00db10
-	  if ((hi & ((1LL << 52) - 1)) == 0)
00db10
+	  if ((hi & (1LL << 53)) != 0)
00db10
 	    {
00db10
-	      if ((hi & (1LL << 53)) != 0)
00db10
-		hi -= 1LL << 52;
00db10
+	      hi >>= 1;
00db10
 	      u.d[0].ieee.exponent++;
00db10
 	    }
00db10
 	  u.d[1].ieee.negative = !sign;
00db10
 	  lo = (1LL << 53) - lo;
00db10
 	}
00db10
 
00db10
-      /* The hidden bit of the lo mantissa is zero so we need to normalize
00db10
-	 it for the low double.  Shift it left until the hidden bit is '1'
00db10
-	 then adjust the 2nd exponent accordingly.  */
00db10
+      /* Normalize the low double.  Shift the mantissa left until
00db10
+	 the hidden bit is '1' and adjust the exponent accordingly.  */
00db10
 
00db10
       if (sizeof (lo) == sizeof (long))
00db10
 	lzcount = __builtin_clzl (lo);
00db10
@@ -128,24 +126,24 @@
00db10
 	lzcount = __builtin_clzl ((long) (lo >> 32));
00db10
       else
00db10
 	lzcount = __builtin_clzl ((long) lo) + 32;
00db10
-      lzcount = lzcount - 11;
00db10
-      if (lzcount > 0)
00db10
-	{
00db10
-	  lo = lo << lzcount;
00db10
-	  exponent2 = exponent2 - lzcount;
00db10
-	}
00db10
+      lzcount = lzcount - (64 - 53);
00db10
+      lo <<= lzcount;
00db10
+      exponent2 -= lzcount;
00db10
+
00db10
       if (exponent2 > 0)
00db10
 	u.d[1].ieee.exponent = exponent2;
00db10
-      else
00db10
+      else if (exponent2 > -53)
00db10
 	lo >>= 1 - exponent2;
00db10
+      else
00db10
+	lo = 0;
00db10
     }
00db10
   else
00db10
     u.d[1].ieee.negative = 0;
00db10
 
00db10
-  u.d[1].ieee.mantissa1 = lo & 0xffffffffLL;
00db10
-  u.d[1].ieee.mantissa0 = (lo >> 32) & 0xfffff;
00db10
-  u.d[0].ieee.mantissa1 = hi & 0xffffffffLL;
00db10
-  u.d[0].ieee.mantissa0 = (hi >> 32) & ((1LL << (LDBL_MANT_DIG - 86)) - 1);
00db10
+  u.d[1].ieee.mantissa1 = lo;
00db10
+  u.d[1].ieee.mantissa0 = lo >> 32;
00db10
+  u.d[0].ieee.mantissa1 = hi;
00db10
+  u.d[0].ieee.mantissa0 = hi >> 32;
00db10
 
00db10
   return u.ld;
00db10
 }
00db10
diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c
00db10
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c	2014-05-27 19:13:56.000000000 -0500
00db10
+++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c	2014-05-27 19:14:45.000000000 -0500
00db10
@@ -43,15 +43,15 @@
00db10
 	lo <<= 1;							      \
00db10
       /* The lower double is normalized separately from the upper.  We	      \
00db10
 	 may need to adjust the lower manitissa to reflect this.  */	      \
00db10
-      ediff = u.d[0].ieee.exponent - u.d[1].ieee.exponent;		      \
00db10
-      if (ediff > 53 + 63)						      \
00db10
+      ediff = u.d[0].ieee.exponent - u.d[1].ieee.exponent - 53;		      \
00db10
+      if (ediff > 63)							      \
00db10
 	lo = 0;								      \
00db10
-      else if (ediff > 53)						      \
00db10
-	lo = lo >> (ediff - 53);					      \
00db10
-      else if (u.d[1].ieee.exponent == 0 && ediff < 53)			      \
00db10
-	lo = lo << (53 - ediff);					      \
00db10
+      else if (ediff > 0)						      \
00db10
+	lo = lo >> ediff;						      \
00db10
+      else if (ediff < 0)						      \
00db10
+	lo = lo << -ediff;						      \
00db10
       if (u.d[0].ieee.negative != u.d[1].ieee.negative			      \
00db10
-	  && (u.d[1].ieee.exponent != 0 || lo != 0L))			      \
00db10
+	  && lo != 0)							      \
00db10
 	{								      \
00db10
 	  lo = (1ULL << 60) - lo;					      \
00db10
 	  if (hi == 0L)							      \