summaryrefslogtreecommitdiff
path: root/packages/glibc/2.17/0037-glibc-ppc64le-15.patch
diff options
context:
space:
mode:
Diffstat (limited to 'packages/glibc/2.17/0037-glibc-ppc64le-15.patch')
-rw-r--r--packages/glibc/2.17/0037-glibc-ppc64le-15.patch119
1 files changed, 119 insertions, 0 deletions
diff --git a/packages/glibc/2.17/0037-glibc-ppc64le-15.patch b/packages/glibc/2.17/0037-glibc-ppc64le-15.patch
new file mode 100644
index 0000000..29b3b54
--- /dev/null
+++ b/packages/glibc/2.17/0037-glibc-ppc64le-15.patch
@@ -0,0 +1,119 @@
+# commit da13146da10360436941e843834c90a9aef5fd7a
+# Author: Alan Modra <amodra@gmail.com>
+# Date: Sat Aug 17 18:30:23 2013 +0930
+#
+# PowerPC floating point little-endian [10 of 15]
+# http://sourceware.org/ml/libc-alpha/2013-07/msg00201.html
+#
+# These two functions oddly test x+1>0 when a double x is >= 0.0, and
+# similarly when x is negative. I don't see the point of that since the
+# test should always be true. I also don't see any need to convert x+1
+# to integer rather than simply using xr+1. Note that the standard
+# allows these functions to return any value when the input is outside
+# the range of long long, but it's not too hard to prevent xr+1
+# overflowing so that's what I've done.
+#
+# (With rounding mode FE_UPWARD, x+1 can be a lot more than what you
+# might naively expect, but perhaps that situation was covered by the
+# x - xrf < 1.0 test.)
+#
+# * sysdeps/powerpc/fpu/s_llround.c (__llround): Rewrite.
+# * sysdeps/powerpc/fpu/s_llroundf.c (__llroundf): Rewrite.
+#
+diff -urN glibc-2.17-c758a686/sysdeps/powerpc/fpu/s_llround.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/s_llround.c
+--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/s_llround.c 2014-05-27 22:38:55.000000000 -0500
++++ glibc-2.17-c758a686/sysdeps/powerpc/fpu/s_llround.c 2014-05-27 22:38:58.000000000 -0500
+@@ -19,29 +19,28 @@
+ #include <math.h>
+ #include <math_ldbl_opt.h>
+
+-/* I think that what this routine is supposed to do is round a value
+- to the nearest integer, with values exactly on the boundary rounded
+- away from zero. */
+-/* This routine relies on (long long)x, when x is out of range of a long long,
+- clipping to MAX_LLONG or MIN_LLONG. */
++/* Round to the nearest integer, with values exactly on a 0.5 boundary
++ rounded away from zero, regardless of the current rounding mode.
++ If (long long)x, when x is out of range of a long long, clips at
++ LLONG_MAX or LLONG_MIN, then this implementation also clips. */
+
+ long long int
+ __llround (double x)
+ {
+- double xrf;
+- long long int xr;
+- xr = (long long int) x;
+- xrf = (double) xr;
++ long long xr = (long long) x;
++ double xrf = (double) xr;
++
+ if (x >= 0.0)
+- if (x - xrf >= 0.5 && x - xrf < 1.0 && x+1 > 0)
+- return x+1;
+- else
+- return x;
++ {
++ if (x - xrf >= 0.5)
++ xr += (long long) ((unsigned long long) xr + 1) > 0;
++ }
+ else
+- if (xrf - x >= 0.5 && xrf - x < 1.0 && x-1 < 0)
+- return x-1;
+- else
+- return x;
++ {
++ if (xrf - x >= 0.5)
++ xr -= (long long) ((unsigned long long) xr - 1) < 0;
++ }
++ return xr;
+ }
+ weak_alias (__llround, llround)
+ #ifdef NO_LONG_DOUBLE
+diff -urN glibc-2.17-c758a686/sysdeps/powerpc/fpu/s_llroundf.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/s_llroundf.c
+--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/s_llroundf.c 2014-05-27 22:38:55.000000000 -0500
++++ glibc-2.17-c758a686/sysdeps/powerpc/fpu/s_llroundf.c 2014-05-27 22:38:58.000000000 -0500
+@@ -18,28 +18,27 @@
+
+ #include <math.h>
+
+-/* I think that what this routine is supposed to do is round a value
+- to the nearest integer, with values exactly on the boundary rounded
+- away from zero. */
+-/* This routine relies on (long long)x, when x is out of range of a long long,
+- clipping to MAX_LLONG or MIN_LLONG. */
++/* Round to the nearest integer, with values exactly on a 0.5 boundary
++ rounded away from zero, regardless of the current rounding mode.
++ If (long long)x, when x is out of range of a long long, clips at
++ LLONG_MAX or LLONG_MIN, then this implementation also clips. */
+
+ long long int
+ __llroundf (float x)
+ {
+- float xrf;
+- long long int xr;
+- xr = (long long int) x;
+- xrf = (float) xr;
++ long long xr = (long long) x;
++ float xrf = (float) xr;
++
+ if (x >= 0.0)
+- if (x - xrf >= 0.5 && x - xrf < 1.0 && x+1 > 0)
+- return x+1;
+- else
+- return x;
++ {
++ if (x - xrf >= 0.5)
++ xr += (long long) ((unsigned long long) xr + 1) > 0;
++ }
+ else
+- if (xrf - x >= 0.5 && xrf - x < 1.0 && x-1 < 0)
+- return x-1;
+- else
+- return x;
++ {
++ if (xrf - x >= 0.5)
++ xr -= (long long) ((unsigned long long) xr - 1) < 0;
++ }
++ return xr;
+ }
+ weak_alias (__llroundf, llroundf)