From dd949d5c6b5a36bf1e8484239294df02c1c4c321 Mon Sep 17 00:00:00 2001
From: Elliott Sales de Andrade <quantum.analyst@gmail.com>
Date: Mon, 13 Aug 2018 01:51:04 -0400
Subject: [PATCH] BUG: Fix printing of longdouble on ppc64le.

The high and low parts of the IBM double-double always come in the same
order, regardless of the endianness of the system, according to [1].

[1] https://www.ibm.com/support/knowledgecenter/en/ssw_aix_71/com.ibm.aix.genprogc/128bit_long_double_floating-point_datatype.htm
---
 numpy/core/src/multiarray/dragon4.c | 46 +++++++----------------------
 numpy/core/src/multiarray/dragon4.h |  7 ++---
 2 files changed, 14 insertions(+), 39 deletions(-)

diff --git a/numpy/core/src/multiarray/dragon4.c b/numpy/core/src/multiarray/dragon4.c
index 2e599136efc..14dfa71c2d3 100644
--- a/numpy/core/src/multiarray/dragon4.c
+++ b/numpy/core/src/multiarray/dragon4.c
@@ -2846,7 +2846,7 @@ Dragon4_PrintFloat_IEEE_binary128_be(
 #if (defined(HAVE_LDOUBLE_IBM_DOUBLE_DOUBLE_LE) || \
      defined(HAVE_LDOUBLE_IBM_DOUBLE_DOUBLE_BE))
 /*
- * IBM extended precision 128-bit floating-point format, aka IBM double-dobule
+ * IBM extended precision 128-bit floating-point format, aka IBM double-double
  *
  * IBM's double-double type is a pair of IEEE binary64 values, which you add
  * together to get a total value. The exponents are arranged so that the lower
@@ -2883,12 +2883,15 @@ Dragon4_PrintFloat_IEEE_binary128_be(
  */
 static npy_uint32
 Dragon4_PrintFloat_IBM_double_double(
-    Dragon4_Scratch *scratch, FloatVal128 val128, Dragon4_Options *opt)
+    Dragon4_Scratch *scratch, npy_float128 *value, Dragon4_Options *opt)
 {
     char *buffer = scratch->repr;
     npy_uint32 bufferSize = sizeof(scratch->repr);
     BigInt *bigints = scratch->bigints;
 
+    FloatVal128 val128;
+    FloatUnion128 buf128;
+
     npy_uint32 floatExponent1, floatExponent2;
     npy_uint64 floatMantissa1, floatMantissa2;
     npy_uint32 floatSign1, floatSign2;
@@ -2909,6 +2912,12 @@ Dragon4_PrintFloat_IBM_double_double(
         return 0;
     }
 
+    /* The high part always comes before the low part, regardless of the
+     * endianness of the system. */
+    buf128.floatingPoint = *value;
+    val128.hi = buf128.integer.a;
+    val128.lo = buf128.integer.b;
+
     /* deconstruct the floating point values */
     floatMantissa1 = val128.hi & bitmask_u64(52);
     floatExponent1 = (val128.hi >> 52) & bitmask_u32(11);
@@ -3053,39 +3062,6 @@ Dragon4_PrintFloat_IBM_double_double(
                             signbit, mantissaBit, hasUnequalMargins, opt);
 }
 
-#if defined(HAVE_LDOUBLE_IBM_DOUBLE_DOUBLE_LE)
-static npy_uint32
-Dragon4_PrintFloat_IBM_double_double_le(
-    Dragon4_Scratch *scratch, npy_float128 *value, Dragon4_Options *opt)
-{
-    FloatVal128 val128;
-    FloatUnion128 buf128;
-
-    buf128.floatingPoint = *value;
-    val128.lo = buf128.integer.a;
-    val128.hi = buf128.integer.b;
-
-    return Dragon4_PrintFloat_IBM_double_double(scratch, val128, opt);
-}
-#endif /* HAVE_LDOUBLE_IBM_DOUBLE_DOUBLE_LE */
-
-#if defined(HAVE_LDOUBLE_IBM_DOUBLE_DOUBLE_BE)
-static npy_uint32
-Dragon4_PrintFloat_IBM_double_double_be(
-    Dragon4_Scratch *scratch, npy_float128 *value, Dragon4_Options *opt)
-{
-    FloatVal128 val128;
-    FloatUnion128 buf128;
-
-    buf128.floatingPoint = *value;
-    val128.hi = buf128.integer.a;
-    val128.lo = buf128.integer.b;
-
-    return Dragon4_PrintFloat_IBM_double_double(scratch, val128, opt);
-}
-
-#endif /* HAVE_LDOUBLE_IBM_DOUBLE_DOUBLE_BE */
-
 #endif /* HAVE_LDOUBLE_IBM_DOUBLE_DOUBLE_LE | HAVE_LDOUBLE_IBM_DOUBLE_DOUBLE_BE */
 
 #endif /* NPY_FLOAT128 */
diff --git a/numpy/core/src/multiarray/dragon4.h b/numpy/core/src/multiarray/dragon4.h
index 383a0949dd0..2b8b4cef4b8 100644
--- a/numpy/core/src/multiarray/dragon4.h
+++ b/numpy/core/src/multiarray/dragon4.h
@@ -75,10 +75,9 @@
     #define NPY_LONGDOUBLE_BINFMT_NAME Intel_extended128
 #elif defined(HAVE_LDOUBLE_MOTOROLA_EXTENDED_12_BYTES_BE)
     #define NPY_LONGDOUBLE_BINFMT_NAME Motorola_extended96
-#elif defined(HAVE_LDOUBLE_IBM_DOUBLE_DOUBLE_LE)
-    #define NPY_LONGDOUBLE_BINFMT_NAME IBM_double_double_le
-#elif defined(HAVE_LDOUBLE_IBM_DOUBLE_DOUBLE_BE)
-    #define NPY_LONGDOUBLE_BINFMT_NAME IBM_double_double_be
+#elif (defined(HAVE_LDOUBLE_IBM_DOUBLE_DOUBLE_LE) || \
+       defined(HAVE_LDOUBLE_IBM_DOUBLE_DOUBLE_BE))
+    #define NPY_LONGDOUBLE_BINFMT_NAME IBM_double_double
 #else
     #error No long double representation defined
 #endif
