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