blob: 3721e7c2aa3a84ab4a50a01cc5d08f31b17a4640 [file] [log] [blame]
Brad Bishop19323692019-04-05 15:28:33 -04001From fa96a7fd19e17b9c6b4dd01c3c3774fb382dddc6 Mon Sep 17 00:00:00 2001
2From: Ross Burton <ross.burton@intel.com>
3Date: Wed, 5 Sep 2018 11:45:52 +0100
4Subject: [PATCH] Don't do runtime test to get float byte order
5
6Python uses AC_RUN_IFELSE to determine the byte order for floats and doubles,
7and falls back onto "I don't know" if it can't run code. This results in
8crippled floating point numbers in Python, and the regression tests fail.
9
10Instead of running code, take a macro from autoconf-archive which compiles C
11with a special double in which has an ASCII representation, and then greps the
12binary to identify the format.
13
14Upstream-Status: Submitted [https://bugs.python.org/issue34585]
15Signed-off-by: Ross Burton <ross.burton@intel.com>
16---
17 configure.ac | 72 +++------------------------
18 m4/ax_c_float_words_bigendian.m4 | 83 ++++++++++++++++++++++++++++++++
19 2 files changed, 90 insertions(+), 65 deletions(-)
20 create mode 100644 m4/ax_c_float_words_bigendian.m4
21
22diff --git a/configure.ac b/configure.ac
23index 4a3681f..4ab19a6 100644
24--- a/configure.ac
25+++ b/configure.ac
26@@ -4328,77 +4328,19 @@ fi
27 # * Check for various properties of floating point *
28 # **************************************************
29
30-AC_MSG_CHECKING(whether C doubles are little-endian IEEE 754 binary64)
31-AC_CACHE_VAL(ac_cv_little_endian_double, [
32-AC_RUN_IFELSE([AC_LANG_SOURCE([[
33-#include <string.h>
34-int main() {
35- double x = 9006104071832581.0;
36- if (memcmp(&x, "\x05\x04\x03\x02\x01\xff\x3f\x43", 8) == 0)
37- return 0;
38- else
39- return 1;
40-}
41-]])],
42-[ac_cv_little_endian_double=yes],
43-[ac_cv_little_endian_double=no],
44-[ac_cv_little_endian_double=no])])
45-AC_MSG_RESULT($ac_cv_little_endian_double)
46-if test "$ac_cv_little_endian_double" = yes
47-then
48- AC_DEFINE(DOUBLE_IS_LITTLE_ENDIAN_IEEE754, 1,
49- [Define if C doubles are 64-bit IEEE 754 binary format, stored
50- with the least significant byte first])
51-fi
52-
53-AC_MSG_CHECKING(whether C doubles are big-endian IEEE 754 binary64)
54-AC_CACHE_VAL(ac_cv_big_endian_double, [
55-AC_RUN_IFELSE([AC_LANG_SOURCE([[
56-#include <string.h>
57-int main() {
58- double x = 9006104071832581.0;
59- if (memcmp(&x, "\x43\x3f\xff\x01\x02\x03\x04\x05", 8) == 0)
60- return 0;
61- else
62- return 1;
63-}
64-]])],
65-[ac_cv_big_endian_double=yes],
66-[ac_cv_big_endian_double=no],
67-[ac_cv_big_endian_double=no])])
68-AC_MSG_RESULT($ac_cv_big_endian_double)
69-if test "$ac_cv_big_endian_double" = yes
70+AX_C_FLOAT_WORDS_BIGENDIAN
71+if test "$ax_cv_c_float_words_bigendian" = "yes"
72 then
73 AC_DEFINE(DOUBLE_IS_BIG_ENDIAN_IEEE754, 1,
74 [Define if C doubles are 64-bit IEEE 754 binary format, stored
75 with the most significant byte first])
76-fi
77-
78-# Some ARM platforms use a mixed-endian representation for doubles.
79-# While Python doesn't currently have full support for these platforms
80-# (see e.g., issue 1762561), we can at least make sure that float <-> string
81-# conversions work.
82-AC_MSG_CHECKING(whether C doubles are ARM mixed-endian IEEE 754 binary64)
83-AC_CACHE_VAL(ac_cv_mixed_endian_double, [
84-AC_RUN_IFELSE([AC_LANG_SOURCE([[
85-#include <string.h>
86-int main() {
87- double x = 9006104071832581.0;
88- if (memcmp(&x, "\x01\xff\x3f\x43\x05\x04\x03\x02", 8) == 0)
89- return 0;
90- else
91- return 1;
92-}
93-]])],
94-[ac_cv_mixed_endian_double=yes],
95-[ac_cv_mixed_endian_double=no],
96-[ac_cv_mixed_endian_double=no])])
97-AC_MSG_RESULT($ac_cv_mixed_endian_double)
98-if test "$ac_cv_mixed_endian_double" = yes
99+elif test "$ax_cv_c_float_words_bigendian" = "no"
100 then
101- AC_DEFINE(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754, 1,
102+ AC_DEFINE(DOUBLE_IS_LITTLE_ENDIAN_IEEE754, 1,
103 [Define if C doubles are 64-bit IEEE 754 binary format, stored
104- in ARM mixed-endian order (byte order 45670123)])
105+ with the least significant byte first])
106+else
107+ AC_MSG_ERROR([Cannot identify floating point byte order])
108 fi
109
110 # The short float repr introduced in Python 3.1 requires the
111diff --git a/m4/ax_c_float_words_bigendian.m4 b/m4/ax_c_float_words_bigendian.m4
112new file mode 100644
113index 0000000..216b90d
114--- /dev/null
115+++ b/m4/ax_c_float_words_bigendian.m4
116@@ -0,0 +1,83 @@
117+# ===============================================================================
118+# https://www.gnu.org/software/autoconf-archive/ax_c_float_words_bigendian.html
119+# ===============================================================================
120+#
121+# SYNOPSIS
122+#
123+# AX_C_FLOAT_WORDS_BIGENDIAN([ACTION-IF-TRUE], [ACTION-IF-FALSE], [ACTION-IF-UNKNOWN])
124+#
125+# DESCRIPTION
126+#
127+# Checks the ordering of words within a multi-word float. This check is
128+# necessary because on some systems (e.g. certain ARM systems), the float
129+# word ordering can be different from the byte ordering. In a multi-word
130+# float context, "big-endian" implies that the word containing the sign
131+# bit is found in the memory location with the lowest address. This
132+# implementation was inspired by the AC_C_BIGENDIAN macro in autoconf.
133+#
134+# The endianness is detected by first compiling C code that contains a
135+# special double float value, then grepping the resulting object file for
136+# certain strings of ASCII values. The double is specially crafted to have
137+# a binary representation that corresponds with a simple string. In this
138+# implementation, the string "noonsees" was selected because the
139+# individual word values ("noon" and "sees") are palindromes, thus making
140+# this test byte-order agnostic. If grep finds the string "noonsees" in
141+# the object file, the target platform stores float words in big-endian
142+# order. If grep finds "seesnoon", float words are in little-endian order.
143+# If neither value is found, the user is instructed to specify the
144+# ordering.
145+#
146+# LICENSE
147+#
148+# Copyright (c) 2008 Daniel Amelang <dan@amelang.net>
149+#
150+# Copying and distribution of this file, with or without modification, are
151+# permitted in any medium without royalty provided the copyright notice
152+# and this notice are preserved. This file is offered as-is, without any
153+# warranty.
154+
155+#serial 11
156+
157+AC_DEFUN([AX_C_FLOAT_WORDS_BIGENDIAN],
158+ [AC_CACHE_CHECK(whether float word ordering is bigendian,
159+ ax_cv_c_float_words_bigendian, [
160+
161+ax_cv_c_float_words_bigendian=unknown
162+AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
163+
164+double d = 90904234967036810337470478905505011476211692735615632014797120844053488865816695273723469097858056257517020191247487429516932130503560650002327564517570778480236724525140520121371739201496540132640109977779420565776568942592.0;
165+
166+]])], [
167+
168+if grep noonsees conftest.$ac_objext >/dev/null ; then
169+ ax_cv_c_float_words_bigendian=yes
170+fi
171+if grep seesnoon conftest.$ac_objext >/dev/null ; then
172+ if test "$ax_cv_c_float_words_bigendian" = unknown; then
173+ ax_cv_c_float_words_bigendian=no
174+ else
175+ ax_cv_c_float_words_bigendian=unknown
176+ fi
177+fi
178+
179+])])
180+
181+case $ax_cv_c_float_words_bigendian in
182+ yes)
183+ m4_default([$1],
184+ [AC_DEFINE([FLOAT_WORDS_BIGENDIAN], 1,
185+ [Define to 1 if your system stores words within floats
186+ with the most significant word first])]) ;;
187+ no)
188+ $2 ;;
189+ *)
190+ m4_default([$3],
191+ [AC_MSG_ERROR([
192+
193+Unknown float word ordering. You need to manually preset
194+ax_cv_c_float_words_bigendian=no (or yes) according to your system.
195+
196+ ])]) ;;
197+esac
198+
199+])# AX_C_FLOAT_WORDS_BIGENDIAN