summaryrefslogtreecommitdiffstats
path: root/poky/meta/recipes-devtools/python/python/float-endian.patch
blob: 8a5c90aec407748b87df2b1c8b214eab061e0edb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
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: Backport
Signed-off-by: Ross Burton <ross.burton@intel.com>

From 253f47b28120c42cfe53a4e2f5ed0ab0ed469deb Mon Sep 17 00:00:00 2001
From: Ross Burton <ross@burtonini.com>
Date: Wed, 19 Sep 2018 07:25:48 +0100
Subject: [PATCH] closes bpo-34585: Don't do runtime test to get float byte
 order. (GH-9085)

Currently configure.ac uses AC_RUN_IFELSE to determine the byte order of doubles, but this silently fails under cross compilation and Python doesn't do floats properly.

Instead, steal a macro from autoconf-archive which compiles code using magic doubles (which encode to ASCII) and grep for the representation in the binary.

RFC because this doesn't yet handle the weird ancient ARMv4 OABI 'mixed-endian' encoding properly. This encoding is ancient and I don't believe the union of "Python 3.8 users" and "OABI users" has anything in. Should the support for this just be dropped too? Alternatively, someone will need to find an OABI toolchain to verify the encoding of the magic double.

Signed-off-by: Ross Burton <ross.burton@intel.com>
---
 .../Build/2018-09-18-16-28-31.bpo-34585.CGMu0h.rst |  3 +
 configure.ac                                       | 76 ++++----------------
 m4/ax_c_float_words_bigendian.m4                   | 83 ++++++++++++++++++++++
 3 files changed, 99 insertions(+), 63 deletions(-)
 create mode 100644 Misc/NEWS.d/next/Build/2018-09-18-16-28-31.bpo-34585.CGMu0h.rst
 create mode 100644 m4/ax_c_float_words_bigendian.m4

diff --git a/configure.ac b/configure.ac
index 913d5469d0..7672735396 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3835,74 +3835,24 @@ 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_LITTLE_ENDIAN_IEEE754, 1,
+  [Define if C doubles are 64-bit IEEE 754 binary format, stored
+   with the least significant byte first])
+else
+  # 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.
+  # FLOAT_WORDS_BIGENDIAN doesnt actually detect this case, but if it's not big
+  # or little, then it must be this?
   AC_DEFINE(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754, 1,
   [Define if C doubles are 64-bit IEEE 754 binary format, stored
    in ARM mixed-endian order (byte order 45670123)])
diff --git a/m4/ax_c_float_words_bigendian.m4 b/m4/ax_c_float_words_bigendian.m4
new file mode 100644
index 0000000000..216b90d803
--- /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
-- 
2.11.0

OpenPOWER on IntegriCloud