200 lines
7.2 KiB
Diff
200 lines
7.2 KiB
Diff
From fa96a7fd19e17b9c6b4dd01c3c3774fb382dddc6 Mon Sep 17 00:00:00 2001
|
|
From: Ross Burton <ross.burton@intel.com>
|
|
Date: Wed, 5 Sep 2018 11:45:52 +0100
|
|
Subject: [PATCH] Don't do runtime test to get float byte order
|
|
|
|
Python uses AC_RUN_IFELSE to determine the byte order for floats and doubles,
|
|
and falls back onto "I don't know" if it can't run code. This results in
|
|
crippled floating point numbers in Python, and the regression tests fail.
|
|
|
|
Instead of running code, take a macro from autoconf-archive which compiles C
|
|
with a special double in which has an ASCII representation, and then greps the
|
|
binary to identify the format.
|
|
|
|
Upstream-Status: Submitted [https://bugs.python.org/issue34585]
|
|
Signed-off-by: Ross Burton <ross.burton@intel.com>
|
|
---
|
|
configure.ac | 72 +++------------------------
|
|
m4/ax_c_float_words_bigendian.m4 | 83 ++++++++++++++++++++++++++++++++
|
|
2 files changed, 90 insertions(+), 65 deletions(-)
|
|
create mode 100644 m4/ax_c_float_words_bigendian.m4
|
|
|
|
diff --git a/configure.ac b/configure.ac
|
|
index 4a3681f..4ab19a6 100644
|
|
--- a/configure.ac
|
|
+++ b/configure.ac
|
|
@@ -4328,77 +4328,19 @@ fi
|
|
# * Check for various properties of floating point *
|
|
# **************************************************
|
|
|
|
-AC_MSG_CHECKING(whether C doubles are little-endian IEEE 754 binary64)
|
|
-AC_CACHE_VAL(ac_cv_little_endian_double, [
|
|
-AC_RUN_IFELSE([AC_LANG_SOURCE([[
|
|
-#include <string.h>
|
|
-int main() {
|
|
- double x = 9006104071832581.0;
|
|
- if (memcmp(&x, "\x05\x04\x03\x02\x01\xff\x3f\x43", 8) == 0)
|
|
- return 0;
|
|
- else
|
|
- return 1;
|
|
-}
|
|
-]])],
|
|
-[ac_cv_little_endian_double=yes],
|
|
-[ac_cv_little_endian_double=no],
|
|
-[ac_cv_little_endian_double=no])])
|
|
-AC_MSG_RESULT($ac_cv_little_endian_double)
|
|
-if test "$ac_cv_little_endian_double" = yes
|
|
-then
|
|
- AC_DEFINE(DOUBLE_IS_LITTLE_ENDIAN_IEEE754, 1,
|
|
- [Define if C doubles are 64-bit IEEE 754 binary format, stored
|
|
- with the least significant byte first])
|
|
-fi
|
|
-
|
|
-AC_MSG_CHECKING(whether C doubles are big-endian IEEE 754 binary64)
|
|
-AC_CACHE_VAL(ac_cv_big_endian_double, [
|
|
-AC_RUN_IFELSE([AC_LANG_SOURCE([[
|
|
-#include <string.h>
|
|
-int main() {
|
|
- double x = 9006104071832581.0;
|
|
- if (memcmp(&x, "\x43\x3f\xff\x01\x02\x03\x04\x05", 8) == 0)
|
|
- return 0;
|
|
- else
|
|
- return 1;
|
|
-}
|
|
-]])],
|
|
-[ac_cv_big_endian_double=yes],
|
|
-[ac_cv_big_endian_double=no],
|
|
-[ac_cv_big_endian_double=no])])
|
|
-AC_MSG_RESULT($ac_cv_big_endian_double)
|
|
-if test "$ac_cv_big_endian_double" = yes
|
|
+AX_C_FLOAT_WORDS_BIGENDIAN
|
|
+if test "$ax_cv_c_float_words_bigendian" = "yes"
|
|
then
|
|
AC_DEFINE(DOUBLE_IS_BIG_ENDIAN_IEEE754, 1,
|
|
[Define if C doubles are 64-bit IEEE 754 binary format, stored
|
|
with the most significant byte first])
|
|
-fi
|
|
-
|
|
-# Some ARM platforms use a mixed-endian representation for doubles.
|
|
-# While Python doesn't currently have full support for these platforms
|
|
-# (see e.g., issue 1762561), we can at least make sure that float <-> string
|
|
-# conversions work.
|
|
-AC_MSG_CHECKING(whether C doubles are ARM mixed-endian IEEE 754 binary64)
|
|
-AC_CACHE_VAL(ac_cv_mixed_endian_double, [
|
|
-AC_RUN_IFELSE([AC_LANG_SOURCE([[
|
|
-#include <string.h>
|
|
-int main() {
|
|
- double x = 9006104071832581.0;
|
|
- if (memcmp(&x, "\x01\xff\x3f\x43\x05\x04\x03\x02", 8) == 0)
|
|
- return 0;
|
|
- else
|
|
- return 1;
|
|
-}
|
|
-]])],
|
|
-[ac_cv_mixed_endian_double=yes],
|
|
-[ac_cv_mixed_endian_double=no],
|
|
-[ac_cv_mixed_endian_double=no])])
|
|
-AC_MSG_RESULT($ac_cv_mixed_endian_double)
|
|
-if test "$ac_cv_mixed_endian_double" = yes
|
|
+elif test "$ax_cv_c_float_words_bigendian" = "no"
|
|
then
|
|
- AC_DEFINE(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754, 1,
|
|
+ AC_DEFINE(DOUBLE_IS_LITTLE_ENDIAN_IEEE754, 1,
|
|
[Define if C doubles are 64-bit IEEE 754 binary format, stored
|
|
- in ARM mixed-endian order (byte order 45670123)])
|
|
+ with the least significant byte first])
|
|
+else
|
|
+ AC_MSG_ERROR([Cannot identify floating point byte order])
|
|
fi
|
|
|
|
# The short float repr introduced in Python 3.1 requires the
|
|
diff --git a/m4/ax_c_float_words_bigendian.m4 b/m4/ax_c_float_words_bigendian.m4
|
|
new file mode 100644
|
|
index 0000000..216b90d
|
|
--- /dev/null
|
|
+++ b/m4/ax_c_float_words_bigendian.m4
|
|
@@ -0,0 +1,83 @@
|
|
+# ===============================================================================
|
|
+# https://www.gnu.org/software/autoconf-archive/ax_c_float_words_bigendian.html
|
|
+# ===============================================================================
|
|
+#
|
|
+# SYNOPSIS
|
|
+#
|
|
+# AX_C_FLOAT_WORDS_BIGENDIAN([ACTION-IF-TRUE], [ACTION-IF-FALSE], [ACTION-IF-UNKNOWN])
|
|
+#
|
|
+# DESCRIPTION
|
|
+#
|
|
+# Checks the ordering of words within a multi-word float. This check is
|
|
+# necessary because on some systems (e.g. certain ARM systems), the float
|
|
+# word ordering can be different from the byte ordering. In a multi-word
|
|
+# float context, "big-endian" implies that the word containing the sign
|
|
+# bit is found in the memory location with the lowest address. This
|
|
+# implementation was inspired by the AC_C_BIGENDIAN macro in autoconf.
|
|
+#
|
|
+# The endianness is detected by first compiling C code that contains a
|
|
+# special double float value, then grepping the resulting object file for
|
|
+# certain strings of ASCII values. The double is specially crafted to have
|
|
+# a binary representation that corresponds with a simple string. In this
|
|
+# implementation, the string "noonsees" was selected because the
|
|
+# individual word values ("noon" and "sees") are palindromes, thus making
|
|
+# this test byte-order agnostic. If grep finds the string "noonsees" in
|
|
+# the object file, the target platform stores float words in big-endian
|
|
+# order. If grep finds "seesnoon", float words are in little-endian order.
|
|
+# If neither value is found, the user is instructed to specify the
|
|
+# ordering.
|
|
+#
|
|
+# LICENSE
|
|
+#
|
|
+# Copyright (c) 2008 Daniel Amelang <dan@amelang.net>
|
|
+#
|
|
+# Copying and distribution of this file, with or without modification, are
|
|
+# permitted in any medium without royalty provided the copyright notice
|
|
+# and this notice are preserved. This file is offered as-is, without any
|
|
+# warranty.
|
|
+
|
|
+#serial 11
|
|
+
|
|
+AC_DEFUN([AX_C_FLOAT_WORDS_BIGENDIAN],
|
|
+ [AC_CACHE_CHECK(whether float word ordering is bigendian,
|
|
+ ax_cv_c_float_words_bigendian, [
|
|
+
|
|
+ax_cv_c_float_words_bigendian=unknown
|
|
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
|
|
+
|
|
+double d = 90904234967036810337470478905505011476211692735615632014797120844053488865816695273723469097858056257517020191247487429516932130503560650002327564517570778480236724525140520121371739201496540132640109977779420565776568942592.0;
|
|
+
|
|
+]])], [
|
|
+
|
|
+if grep noonsees conftest.$ac_objext >/dev/null ; then
|
|
+ ax_cv_c_float_words_bigendian=yes
|
|
+fi
|
|
+if grep seesnoon conftest.$ac_objext >/dev/null ; then
|
|
+ if test "$ax_cv_c_float_words_bigendian" = unknown; then
|
|
+ ax_cv_c_float_words_bigendian=no
|
|
+ else
|
|
+ ax_cv_c_float_words_bigendian=unknown
|
|
+ fi
|
|
+fi
|
|
+
|
|
+])])
|
|
+
|
|
+case $ax_cv_c_float_words_bigendian in
|
|
+ yes)
|
|
+ m4_default([$1],
|
|
+ [AC_DEFINE([FLOAT_WORDS_BIGENDIAN], 1,
|
|
+ [Define to 1 if your system stores words within floats
|
|
+ with the most significant word first])]) ;;
|
|
+ no)
|
|
+ $2 ;;
|
|
+ *)
|
|
+ m4_default([$3],
|
|
+ [AC_MSG_ERROR([
|
|
+
|
|
+Unknown float word ordering. You need to manually preset
|
|
+ax_cv_c_float_words_bigendian=no (or yes) according to your system.
|
|
+
|
|
+ ])]) ;;
|
|
+esac
|
|
+
|
|
+])# AX_C_FLOAT_WORDS_BIGENDIAN
|