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