Skip to content

Commit b3b12c4

Browse files
committed
Don't do runtime test to get float byte order
1 parent cb5778f commit b3b12c4

File tree

3 files changed

+99
-63
lines changed

3 files changed

+99
-63
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Check for floating-point byte order in configure.ac using compilation tests
2+
instead of executing code, so that these checks work in cross-compiled
3+
builds.

configure.ac

Lines changed: 13 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -4206,74 +4206,24 @@ fi
42064206
# * Check for various properties of floating point *
42074207
# **************************************************
42084208

4209-
AC_MSG_CHECKING(whether C doubles are little-endian IEEE 754 binary64)
4210-
AC_CACHE_VAL(ac_cv_little_endian_double, [
4211-
AC_RUN_IFELSE([AC_LANG_SOURCE([[
4212-
#include <string.h>
4213-
int main() {
4214-
double x = 9006104071832581.0;
4215-
if (memcmp(&x, "\x05\x04\x03\x02\x01\xff\x3f\x43", 8) == 0)
4216-
return 0;
4217-
else
4218-
return 1;
4219-
}
4220-
]])],
4221-
[ac_cv_little_endian_double=yes],
4222-
[ac_cv_little_endian_double=no],
4223-
[ac_cv_little_endian_double=no])])
4224-
AC_MSG_RESULT($ac_cv_little_endian_double)
4225-
if test "$ac_cv_little_endian_double" = yes
4226-
then
4227-
AC_DEFINE(DOUBLE_IS_LITTLE_ENDIAN_IEEE754, 1,
4228-
[Define if C doubles are 64-bit IEEE 754 binary format, stored
4229-
with the least significant byte first])
4230-
fi
4231-
4232-
AC_MSG_CHECKING(whether C doubles are big-endian IEEE 754 binary64)
4233-
AC_CACHE_VAL(ac_cv_big_endian_double, [
4234-
AC_RUN_IFELSE([AC_LANG_SOURCE([[
4235-
#include <string.h>
4236-
int main() {
4237-
double x = 9006104071832581.0;
4238-
if (memcmp(&x, "\x43\x3f\xff\x01\x02\x03\x04\x05", 8) == 0)
4239-
return 0;
4240-
else
4241-
return 1;
4242-
}
4243-
]])],
4244-
[ac_cv_big_endian_double=yes],
4245-
[ac_cv_big_endian_double=no],
4246-
[ac_cv_big_endian_double=no])])
4247-
AC_MSG_RESULT($ac_cv_big_endian_double)
4248-
if test "$ac_cv_big_endian_double" = yes
4209+
AX_C_FLOAT_WORDS_BIGENDIAN
4210+
if test "$ax_cv_c_float_words_bigendian" = "yes"
42494211
then
42504212
AC_DEFINE(DOUBLE_IS_BIG_ENDIAN_IEEE754, 1,
42514213
[Define if C doubles are 64-bit IEEE 754 binary format, stored
42524214
with the most significant byte first])
4253-
fi
4254-
4255-
# Some ARM platforms use a mixed-endian representation for doubles.
4256-
# While Python doesn't currently have full support for these platforms
4257-
# (see e.g., issue 1762561), we can at least make sure that float <-> string
4258-
# conversions work.
4259-
AC_MSG_CHECKING(whether C doubles are ARM mixed-endian IEEE 754 binary64)
4260-
AC_CACHE_VAL(ac_cv_mixed_endian_double, [
4261-
AC_RUN_IFELSE([AC_LANG_SOURCE([[
4262-
#include <string.h>
4263-
int main() {
4264-
double x = 9006104071832581.0;
4265-
if (memcmp(&x, "\x01\xff\x3f\x43\x05\x04\x03\x02", 8) == 0)
4266-
return 0;
4267-
else
4268-
return 1;
4269-
}
4270-
]])],
4271-
[ac_cv_mixed_endian_double=yes],
4272-
[ac_cv_mixed_endian_double=no],
4273-
[ac_cv_mixed_endian_double=no])])
4274-
AC_MSG_RESULT($ac_cv_mixed_endian_double)
4275-
if test "$ac_cv_mixed_endian_double" = yes
4215+
elif test "$ax_cv_c_float_words_bigendian" = "no"
42764216
then
4217+
AC_DEFINE(DOUBLE_IS_LITTLE_ENDIAN_IEEE754, 1,
4218+
[Define if C doubles are 64-bit IEEE 754 binary format, stored
4219+
with the least significant byte first])
4220+
else
4221+
# Some ARM platforms use a mixed-endian representation for doubles.
4222+
# While Python doesn't currently have full support for these platforms
4223+
# (see e.g., issue 1762561), we can at least make sure that float <-> string
4224+
# conversions work.
4225+
# FLOAT_WORDS_BIGENDIAN doesnt actually detect this case, but if it's not big
4226+
# or little, then it must be this?
42774227
AC_DEFINE(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754, 1,
42784228
[Define if C doubles are 64-bit IEEE 754 binary format, stored
42794229
in ARM mixed-endian order (byte order 45670123)])

m4/ax_c_float_words_bigendian.m4

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# ===============================================================================
2+
# https://www.gnu.org/software/autoconf-archive/ax_c_float_words_bigendian.html
3+
# ===============================================================================
4+
#
5+
# SYNOPSIS
6+
#
7+
# AX_C_FLOAT_WORDS_BIGENDIAN([ACTION-IF-TRUE], [ACTION-IF-FALSE], [ACTION-IF-UNKNOWN])
8+
#
9+
# DESCRIPTION
10+
#
11+
# Checks the ordering of words within a multi-word float. This check is
12+
# necessary because on some systems (e.g. certain ARM systems), the float
13+
# word ordering can be different from the byte ordering. In a multi-word
14+
# float context, "big-endian" implies that the word containing the sign
15+
# bit is found in the memory location with the lowest address. This
16+
# implementation was inspired by the AC_C_BIGENDIAN macro in autoconf.
17+
#
18+
# The endianness is detected by first compiling C code that contains a
19+
# special double float value, then grepping the resulting object file for
20+
# certain strings of ASCII values. The double is specially crafted to have
21+
# a binary representation that corresponds with a simple string. In this
22+
# implementation, the string "noonsees" was selected because the
23+
# individual word values ("noon" and "sees") are palindromes, thus making
24+
# this test byte-order agnostic. If grep finds the string "noonsees" in
25+
# the object file, the target platform stores float words in big-endian
26+
# order. If grep finds "seesnoon", float words are in little-endian order.
27+
# If neither value is found, the user is instructed to specify the
28+
# ordering.
29+
#
30+
# LICENSE
31+
#
32+
# Copyright (c) 2008 Daniel Amelang <[email protected]>
33+
#
34+
# Copying and distribution of this file, with or without modification, are
35+
# permitted in any medium without royalty provided the copyright notice
36+
# and this notice are preserved. This file is offered as-is, without any
37+
# warranty.
38+
39+
#serial 11
40+
41+
AC_DEFUN([AX_C_FLOAT_WORDS_BIGENDIAN],
42+
[AC_CACHE_CHECK(whether float word ordering is bigendian,
43+
ax_cv_c_float_words_bigendian, [
44+
45+
ax_cv_c_float_words_bigendian=unknown
46+
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
47+
48+
double d = 90904234967036810337470478905505011476211692735615632014797120844053488865816695273723469097858056257517020191247487429516932130503560650002327564517570778480236724525140520121371739201496540132640109977779420565776568942592.0;
49+
50+
]])], [
51+
52+
if grep noonsees conftest.$ac_objext >/dev/null ; then
53+
ax_cv_c_float_words_bigendian=yes
54+
fi
55+
if grep seesnoon conftest.$ac_objext >/dev/null ; then
56+
if test "$ax_cv_c_float_words_bigendian" = unknown; then
57+
ax_cv_c_float_words_bigendian=no
58+
else
59+
ax_cv_c_float_words_bigendian=unknown
60+
fi
61+
fi
62+
63+
])])
64+
65+
case $ax_cv_c_float_words_bigendian in
66+
yes)
67+
m4_default([$1],
68+
[AC_DEFINE([FLOAT_WORDS_BIGENDIAN], 1,
69+
[Define to 1 if your system stores words within floats
70+
with the most significant word first])]) ;;
71+
no)
72+
$2 ;;
73+
*)
74+
m4_default([$3],
75+
[AC_MSG_ERROR([
76+
77+
Unknown float word ordering. You need to manually preset
78+
ax_cv_c_float_words_bigendian=no (or yes) according to your system.
79+
80+
])]) ;;
81+
esac
82+
83+
])# AX_C_FLOAT_WORDS_BIGENDIAN

0 commit comments

Comments
 (0)