| 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 |