This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Configure: mixed-endian double-doubles
authorJarkko Hietaniemi <jhi@iki.fi>
Tue, 8 Dec 2015 13:48:40 +0000 (08:48 -0500)
committerJarkko Hietaniemi <jhi@iki.fi>
Mon, 14 Dec 2015 11:38:34 +0000 (06:38 -0500)
The ppc64el is the first seen little-endian double-double (and also
the first little-endian ppc), but it turns out its little-endianness
is mixed: the doubles are still in big-endian order.  Configure was
expecting wrongly a fully byte-reversed double-double.

Therefore extend the long double format detection to cover all the
(double-double) permutations, though the formats of five and eight
are rather unlikely (based on current platforms using double-double).

Configure
config_h.SH
uconfig.h
win32/config_H.gc
win32/config_H.vc

index 1bd49b4..18aa45f 100755 (executable)
--- a/Configure
+++ b/Configure
@@ -6976,17 +6976,35 @@ int main() {
   /* software "double double", the 106 is 53+53.
    * but irix thinks it is 107. */
   if (b[0] == 0x9A && b[7] == 0x3C && b[8] == 0x9A && b[15] == 0xBF) {
-    /* double double 128-bit little-endian,
+    /* double double 128-bit fully little-endian,
+     * little-endian doubles in little-endian order,
      * 9a 99 99 99 99 99 59 3c 9a 99 99 99 99 99 b9 bf */
     printf("5\n");
     exit(0);
   }
   if (b[0] == 0xBF && b[7] == 0x9A && b[8] == 0x3C && b[15] == 0x9A) {
-    /* double double 128-bit big-endian, e.g. PPC/Power and MIPS:
+    /* double double 128-bit fully big-endian,
+     * big-endian doubles in big-endian order,
+     * e.g. PPC/Power and MIPS:
      * bf b9 99 99 99 99 99 9a 3c 59 99 99 99 99 99 9a */
     printf("6\n");
     exit(0);
   }
+  if (b[0] == 0x9A && b[7] == 0xBF && b[8] == 0x9A && b[15] == 0x3C) {
+    /* double double 128-bit mixed endian.
+     * little-endian doubles in big-endian order,
+     * e.g. ppc64el,
+     * 9a 99 99 99 99 99 b9 bf 9a 99 99 99 99 99 59 3c */
+    printf("7\n");
+    exit(0);
+  }
+  if (b[0] == 0x3C && b[7] == 0x9A && b[8] == 0xBF && b[15] == 0x9A) {
+    /* double double 128-bit mixed endian,
+     * big-endian doubles in little-endian order,
+     * 3c 59 99 99 99 99 99 9a bf b9 99 99 99 99 99 9a */
+    printf("8\n");
+    exit(0);
+  }
 #endif
   printf("-1\n"); /* unknown */
   exit(0);
@@ -7007,8 +7025,10 @@ case "$longdblkind" in
 2) echo "You have IEEE 754 128-bit big endian long doubles." >&4 ;;
 3) echo "You have x86 80-bit little endian long doubles." >& 4 ;;
 4) echo "You have x86 80-bit big endian long doubles." >& 4 ;;
-5) echo "You have 128-bit little-endian double-double long doubles." >& 4 ;;
-6) echo "You have 128-bit big-endian double-double long doubles." >& 4 ;;
+5) echo "You have 128-bit fully little-endian double-double long doubles (64-bit LEs in LE)." >& 4 ;;
+6) echo "You have 128-bit fully big-endian double-double long doubles (64-bit BEs in BE)." >& 4 ;;
+7) echo "You have 128-bit mixed double-double long doubles (64-bit LEs in BE)." >& 4 ;;
+8) echo "You have 128-bit mixed double-double long doubles (64-bit BEs in LE)." >& 4 ;;
 *) echo "Cannot figure out your long double." >&4 ;;
 esac
 $rm_try
index aa806cf..01ac23d 100755 (executable)
@@ -1967,8 +1967,10 @@ sed <<!GROK!THIS! >$CONFIG_H -e 's!^#undef\(.*/\)\*!/\*#define\1 \*!' -e 's!^#un
  *     LONG_DOUBLE_IS_IEEE_754_128_BIT_BIG_ENDIAN
  *     LONG_DOUBLE_IS_X86_80_BIT_LITTLE_ENDIAN
  *     LONG_DOUBLE_IS_X86_80_BIT_BIG_ENDIAN
- *     LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LITTLE_ENDIAN
- *     LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BIG_ENDIAN
+ *     LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LE_LE
+ *     LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_BE
+ *     LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LE_BE
+ *     LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_LE
  *     LONG_DOUBLE_IS_UNKNOWN_FORMAT
  *     It is only defined if the system supports long doubles.
  */
@@ -1982,9 +1984,14 @@ sed <<!GROK!THIS! >$CONFIG_H -e 's!^#undef\(.*/\)\*!/\*#define\1 \*!' -e 's!^#un
 #define LONG_DOUBLE_IS_IEEE_754_128_BIT_BIG_ENDIAN     2
 #define LONG_DOUBLE_IS_X86_80_BIT_LITTLE_ENDIAN                3
 #define LONG_DOUBLE_IS_X86_80_BIT_BIG_ENDIAN           4
-#define LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LITTLE_ENDIAN      5
-#define LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BIG_ENDIAN 6
+#define LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LE_LE      5
+#define LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_BE      6
+#define LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LE_BE      7
+#define LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_LE      8
 #define LONG_DOUBLE_IS_UNKNOWN_FORMAT                  -1
+/* Backward compat. */
+#define LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LITTLE_ENDIAN      LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LE_LE
+#define LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BIG_ENDIAN LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_BE
 #endif
 
 /* HAS_LONG_LONG:
index a020e59..af65ca7 100644 (file)
--- a/uconfig.h
+++ b/uconfig.h
  *     LONG_DOUBLE_IS_IEEE_754_128_BIT_BIG_ENDIAN
  *     LONG_DOUBLE_IS_X86_80_BIT_LITTLE_ENDIAN
  *     LONG_DOUBLE_IS_X86_80_BIT_BIG_ENDIAN
- *     LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LITTLE_ENDIAN
- *     LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BIG_ENDIAN
+ *     LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LE_LE
+ *     LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_BE
+ *     LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LE_BE
+ *     LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_LE
  *     LONG_DOUBLE_IS_UNKNOWN_FORMAT
  *     It is only defined if the system supports long doubles.
  */
 #define LONG_DOUBLE_IS_IEEE_754_128_BIT_BIG_ENDIAN     2
 #define LONG_DOUBLE_IS_X86_80_BIT_LITTLE_ENDIAN                3
 #define LONG_DOUBLE_IS_X86_80_BIT_BIG_ENDIAN           4
-#define LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LITTLE_ENDIAN      5
-#define LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BIG_ENDIAN 6
+#define LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LE_LE      5
+#define LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_BE      6
+#define LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LE_BE      7
+#define LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_LE      8
 #define LONG_DOUBLE_IS_UNKNOWN_FORMAT                  -1
+/* Backward compat. */
+#define LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LITTLE_ENDIAN      LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LE_LE
+#define LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BIG_ENDIAN LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_BE
 #endif
 
 /* HAS_LONG_LONG:
 #endif
 
 /* Generated from:
- * 71bc7991dfb75b5d8a1082c2dd90d90d8f912ecfca90533df598d84f2c3d2382 config_h.SH
+ * 1fbdd1f584710d990cbc1b624770986e12ad6e3eac21c9f3851e6a0ad5a7fbce config_h.SH
  * 0ce9d24f6ed83c533882929bc7c0138fe345656c4b7070aad99bb103dbf3790a uconfig.sh
  * ex: set ro: */
index 8480c77..2254974 100644 (file)
  *     LONG_DOUBLE_IS_IEEE_754_128_BIT_BIG_ENDIAN
  *     LONG_DOUBLE_IS_X86_80_BIT_LITTLE_ENDIAN
  *     LONG_DOUBLE_IS_X86_80_BIT_BIG_ENDIAN
- *     LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LITTLE_ENDIAN
- *     LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BIG_ENDIAN
+ *     LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LE_LE
+ *     LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_BE
+ *     LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LE_BE
+ *     LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_LE
  *     LONG_DOUBLE_IS_UNKNOWN_FORMAT
  *     It is only defined if the system supports long doubles.
  */
 #define LONG_DOUBLE_IS_IEEE_754_128_BIT_BIG_ENDIAN     2
 #define LONG_DOUBLE_IS_X86_80_BIT_LITTLE_ENDIAN                3
 #define LONG_DOUBLE_IS_X86_80_BIT_BIG_ENDIAN           4
-#define LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LITTLE_ENDIAN      5
-#define LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BIG_ENDIAN 6
+#define LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LE_LE      5
+#define LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_BE      6
+#define LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LE_BE      7
+#define LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_LE      8
 #define LONG_DOUBLE_IS_UNKNOWN_FORMAT                  -1
 #endif
 
index f1e8517..3d17f63 100644 (file)
  *     LONG_DOUBLE_IS_IEEE_754_128_BIT_BIG_ENDIAN
  *     LONG_DOUBLE_IS_X86_80_BIT_LITTLE_ENDIAN
  *     LONG_DOUBLE_IS_X86_80_BIT_BIG_ENDIAN
- *     LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LITTLE_ENDIAN
- *     LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BIG_ENDIAN
+ *     LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LE_LE
+ *     LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_BE
+ *     LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LE_BE
+ *     LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_LE
  *     LONG_DOUBLE_IS_UNKNOWN_FORMAT
  *     It is only defined if the system supports long doubles.
  */
 #define LONG_DOUBLE_IS_IEEE_754_128_BIT_BIG_ENDIAN     2
 #define LONG_DOUBLE_IS_X86_80_BIT_LITTLE_ENDIAN                3
 #define LONG_DOUBLE_IS_X86_80_BIT_BIG_ENDIAN           4
-#define LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LITTLE_ENDIAN      5
-#define LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BIG_ENDIAN 6
+#define LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LE_LE      5
+#define LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_BE      6
+#define LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LE_BE      7
+#define LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_LE      8
 #define LONG_DOUBLE_IS_UNKNOWN_FORMAT                  -1
 #endif