mirror of
https://github.com/python/cpython.git
synced 2025-07-30 06:34:15 +00:00
Issue #7117 (backport py3k float repr) continued:
- add double endianness detection to configure script - add configure-time check to see whether we can use inline assembly to get and set x87 control word in configure script - add functions to get and set x87 control word in Python/pymath.c - add pyport.h logic to determine whether it's safe to use the short float repr or not
This commit is contained in:
parent
5e9f6676ea
commit
1d6e2e1833
8 changed files with 529 additions and 11 deletions
|
@ -17,6 +17,9 @@
|
|||
# undef SIZEOF_VOID_P
|
||||
# undef SIZEOF__BOOL
|
||||
# undef WORDS_BIGENDIAN
|
||||
# undef DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754
|
||||
# undef DOUBLE_IS_BIG_ENDIAN_IEEE754
|
||||
# undef DOUBLE_IS_LITTLE_ENDIAN_IEEE754
|
||||
|
||||
# undef VA_LIST_IS_ARRAY
|
||||
# if defined(__LP64__) && defined(__x86_64__)
|
||||
|
@ -65,6 +68,9 @@
|
|||
|
||||
#ifdef __BIG_ENDIAN__
|
||||
#define WORDS_BIGENDIAN 1
|
||||
#define DOUBLE_IS_BIG_ENDIAN_IEEE754
|
||||
#else
|
||||
#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754
|
||||
#endif /* __BIG_ENDIAN */
|
||||
|
||||
/*
|
||||
|
|
|
@ -92,6 +92,11 @@ PyAPI_FUNC(double) _Py_force_double(double);
|
|||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GCC_ASM_FOR_X87
|
||||
PyAPI_FUNC(unsigned short) _Py_get_387controlword(void);
|
||||
PyAPI_FUNC(void) _Py_set_387controlword(unsigned short);
|
||||
#endif
|
||||
|
||||
/* Py_IS_NAN(X)
|
||||
* Return 1 if float or double arg is a NaN, else 0.
|
||||
* Caution:
|
||||
|
|
|
@ -488,6 +488,80 @@ extern "C" {
|
|||
errno = 0; \
|
||||
} while(0)
|
||||
|
||||
/* The functions _Py_dg_strtod and _Py_dg_dtoa in Python/dtoa.c (which are
|
||||
* required to support the short float repr introduced in Python 3.1) require
|
||||
* that the floating-point unit that's being used for arithmetic operations
|
||||
* on C doubles is set to use 53-bit precision. It also requires that the
|
||||
* FPU rounding mode is round-half-to-even, but that's less often an issue.
|
||||
*
|
||||
* If your FPU isn't already set to 53-bit precision/round-half-to-even, and
|
||||
* you want to make use of _Py_dg_strtod and _Py_dg_dtoa, then you should
|
||||
*
|
||||
* #define HAVE_PY_SET_53BIT_PRECISION 1
|
||||
*
|
||||
* and also give appropriate definitions for the following three macros:
|
||||
*
|
||||
* _PY_SET_53BIT_PRECISION_START : store original FPU settings, and
|
||||
* set FPU to 53-bit precision/round-half-to-even
|
||||
* _PY_SET_53BIT_PRECISION_END : restore original FPU settings
|
||||
* _PY_SET_53BIT_PRECISION_HEADER : any variable declarations needed to
|
||||
* use the two macros above.
|
||||
*
|
||||
* The macros are designed to be used within a single C function: see
|
||||
* Python/pystrtod.c for an example of their use.
|
||||
*/
|
||||
|
||||
/* get and set x87 control word for gcc/x86 */
|
||||
#ifdef HAVE_GCC_ASM_FOR_X87
|
||||
#define HAVE_PY_SET_53BIT_PRECISION 1
|
||||
/* _Py_get/set_387controlword functions are defined in Python/pymath.c */
|
||||
#define _Py_SET_53BIT_PRECISION_HEADER \
|
||||
unsigned short old_387controlword, new_387controlword
|
||||
#define _Py_SET_53BIT_PRECISION_START \
|
||||
do { \
|
||||
old_387controlword = _Py_get_387controlword(); \
|
||||
new_387controlword = (old_387controlword & ~0x0f00) | 0x0200; \
|
||||
if (new_387controlword != old_387controlword) \
|
||||
_Py_set_387controlword(new_387controlword); \
|
||||
} while (0)
|
||||
#define _Py_SET_53BIT_PRECISION_END \
|
||||
if (new_387controlword != old_387controlword) \
|
||||
_Py_set_387controlword(old_387controlword)
|
||||
#endif
|
||||
|
||||
/* default definitions are empty */
|
||||
#ifndef HAVE_PY_SET_53BIT_PRECISION
|
||||
#define _Py_SET_53BIT_PRECISION_HEADER
|
||||
#define _Py_SET_53BIT_PRECISION_START
|
||||
#define _Py_SET_53BIT_PRECISION_END
|
||||
#endif
|
||||
|
||||
/* If we can't guarantee 53-bit precision, don't use the code
|
||||
in Python/dtoa.c, but fall back to standard code. This
|
||||
means that repr of a float will be long (17 sig digits).
|
||||
|
||||
Realistically, there are two things that could go wrong:
|
||||
|
||||
(1) doubles aren't IEEE 754 doubles, or
|
||||
(2) we're on x86 with the rounding precision set to 64-bits
|
||||
(extended precision), and we don't know how to change
|
||||
the rounding precision.
|
||||
*/
|
||||
|
||||
#if !defined(DOUBLE_IS_LITTLE_ENDIAN_IEEE754) && \
|
||||
!defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) && \
|
||||
!defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754)
|
||||
#define PY_NO_SHORT_FLOAT_REPR
|
||||
#endif
|
||||
|
||||
/* double rounding is symptomatic of use of extended precision on x86. If
|
||||
we're seeing double rounding, and we don't have any mechanism available for
|
||||
changing the FPU rounding precision, then don't use Python/dtoa.c. */
|
||||
#if defined(X87_DOUBLE_ROUNDING) && !defined(HAVE_PY_SET_53BIT_PRECISION)
|
||||
#define PY_NO_SHORT_FLOAT_REPR
|
||||
#endif
|
||||
|
||||
|
||||
/* Py_DEPRECATED(version)
|
||||
* Declare a variable, type, or function deprecated.
|
||||
* Usage:
|
||||
|
|
|
@ -749,4 +749,8 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */
|
|||
socket handles greater than FD_SETSIZE */
|
||||
#define Py_SOCKET_FD_CAN_BE_GE_FD_SETSIZE
|
||||
|
||||
/* Define if C doubles are 64-bit IEEE 754 binary format, stored with the
|
||||
least significant byte first */
|
||||
#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 1
|
||||
|
||||
#endif /* !Py_CONFIG_H */
|
||||
|
|
|
@ -13,6 +13,24 @@ double _Py_force_double(double x)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GCC_ASM_FOR_X87
|
||||
|
||||
/* inline assembly for getting and setting the 387 FPU control word on
|
||||
gcc/x86 */
|
||||
|
||||
unsigned short _Py_get_387controlword(void) {
|
||||
unsigned short cw;
|
||||
__asm__ __volatile__ ("fnstcw %0" : "=m" (cw));
|
||||
return cw;
|
||||
}
|
||||
|
||||
void _Py_set_387controlword(unsigned short cw) {
|
||||
__asm__ __volatile__ ("fldcw %0" : : "m" (cw));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_HYPOT
|
||||
double hypot(double x, double y)
|
||||
{
|
||||
|
|
305
configure
vendored
305
configure
vendored
|
@ -1,5 +1,5 @@
|
|||
#! /bin/sh
|
||||
# From configure.in Revision: 74978 .
|
||||
# From configure.in Revision: 75131 .
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.61 for python 2.7.
|
||||
#
|
||||
|
@ -23233,12 +23233,298 @@ echo "${ECHO_T}default LIBC=\"$LIBC\"" >&6; }
|
|||
fi
|
||||
|
||||
|
||||
# ************************************
|
||||
# * Check for mathematical functions *
|
||||
# ************************************
|
||||
# **************************************************
|
||||
# * Check for various properties of floating point *
|
||||
# **************************************************
|
||||
|
||||
LIBS_SAVE=$LIBS
|
||||
LIBS="$LIBS $LIBM"
|
||||
{ echo "$as_me:$LINENO: checking whether C doubles are little-endian IEEE 754 binary64" >&5
|
||||
echo $ECHO_N "checking whether C doubles are little-endian IEEE 754 binary64... $ECHO_C" >&6; }
|
||||
if test "${ac_cv_little_endian_double+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
|
||||
if test "$cross_compiling" = yes; then
|
||||
ac_cv_little_endian_double=no
|
||||
else
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
_ACEOF
|
||||
rm -f conftest$ac_exeext
|
||||
if { (ac_try="$ac_link"
|
||||
case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
(eval "$ac_link") 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } && { ac_try='./conftest$ac_exeext'
|
||||
{ (case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
(eval "$ac_try") 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; }; then
|
||||
ac_cv_little_endian_double=yes
|
||||
else
|
||||
echo "$as_me: program exited with status $ac_status" >&5
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
( exit $ac_status )
|
||||
ac_cv_little_endian_double=no
|
||||
fi
|
||||
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
|
||||
fi
|
||||
|
||||
|
||||
fi
|
||||
|
||||
{ echo "$as_me:$LINENO: result: $ac_cv_little_endian_double" >&5
|
||||
echo "${ECHO_T}$ac_cv_little_endian_double" >&6; }
|
||||
if test "$ac_cv_little_endian_double" = yes
|
||||
then
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
{ echo "$as_me:$LINENO: checking whether C doubles are big-endian IEEE 754 binary64" >&5
|
||||
echo $ECHO_N "checking whether C doubles are big-endian IEEE 754 binary64... $ECHO_C" >&6; }
|
||||
if test "${ac_cv_big_endian_double+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
|
||||
if test "$cross_compiling" = yes; then
|
||||
ac_cv_big_endian_double=no
|
||||
else
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
_ACEOF
|
||||
rm -f conftest$ac_exeext
|
||||
if { (ac_try="$ac_link"
|
||||
case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
(eval "$ac_link") 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } && { ac_try='./conftest$ac_exeext'
|
||||
{ (case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
(eval "$ac_try") 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; }; then
|
||||
ac_cv_big_endian_double=yes
|
||||
else
|
||||
echo "$as_me: program exited with status $ac_status" >&5
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
( exit $ac_status )
|
||||
ac_cv_big_endian_double=no
|
||||
fi
|
||||
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
|
||||
fi
|
||||
|
||||
|
||||
fi
|
||||
|
||||
{ echo "$as_me:$LINENO: result: $ac_cv_big_endian_double" >&5
|
||||
echo "${ECHO_T}$ac_cv_big_endian_double" >&6; }
|
||||
if test "$ac_cv_big_endian_double" = yes
|
||||
then
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define DOUBLE_IS_BIG_ENDIAN_IEEE754 1
|
||||
_ACEOF
|
||||
|
||||
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.
|
||||
{ echo "$as_me:$LINENO: checking whether C doubles are ARM mixed-endian IEEE 754 binary64" >&5
|
||||
echo $ECHO_N "checking whether C doubles are ARM mixed-endian IEEE 754 binary64... $ECHO_C" >&6; }
|
||||
if test "${ac_cv_mixed_endian_double+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
|
||||
if test "$cross_compiling" = yes; then
|
||||
ac_cv_mixed_endian_double=no
|
||||
else
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
_ACEOF
|
||||
rm -f conftest$ac_exeext
|
||||
if { (ac_try="$ac_link"
|
||||
case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
(eval "$ac_link") 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } && { ac_try='./conftest$ac_exeext'
|
||||
{ (case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
(eval "$ac_try") 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; }; then
|
||||
ac_cv_mixed_endian_double=yes
|
||||
else
|
||||
echo "$as_me: program exited with status $ac_status" >&5
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
( exit $ac_status )
|
||||
ac_cv_mixed_endian_double=no
|
||||
fi
|
||||
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
|
||||
fi
|
||||
|
||||
|
||||
fi
|
||||
|
||||
{ echo "$as_me:$LINENO: result: $ac_cv_mixed_endian_double" >&5
|
||||
echo "${ECHO_T}$ac_cv_mixed_endian_double" >&6; }
|
||||
if test "$ac_cv_mixed_endian_double" = yes
|
||||
then
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
# The short float repr introduced in Python 3.1 requires the
|
||||
# correctly-rounded string <-> double conversion functions from
|
||||
# Python/dtoa.c, which in turn require that the FPU uses 53-bit
|
||||
# rounding; this is a problem on x86, where the x87 FPU has a default
|
||||
# rounding precision of 64 bits. For gcc/x86, we try to fix this by
|
||||
# using inline assembler to get and set the x87 FPU control word.
|
||||
if test "$GCC" = yes && test -n "`$CC -dM -E - </dev/null | grep i386`"
|
||||
then
|
||||
# Check that it's okay to use gcc inline assembler to get and set
|
||||
# x87 control word. It should be, but you never know...
|
||||
{ echo "$as_me:$LINENO: checking whether we can use gcc inline assembler to get and set x87 control word" >&5
|
||||
echo $ECHO_N "checking whether we can use gcc inline assembler to get and set x87 control word... $ECHO_C" >&6; }
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
|
||||
unsigned short cw;
|
||||
__asm__ __volatile__ ("fnstcw %0" : "=m" (cw));
|
||||
__asm__ __volatile__ ("fldcw %0" : : "m" (cw));
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext
|
||||
if { (ac_try="$ac_compile"
|
||||
case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
(eval "$ac_compile") 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } && {
|
||||
test -z "$ac_c_werror_flag" ||
|
||||
test ! -s conftest.err
|
||||
} && test -s conftest.$ac_objext; then
|
||||
have_gcc_asm_for_x87=yes
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
have_gcc_asm_for_x87=no
|
||||
fi
|
||||
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
{ echo "$as_me:$LINENO: result: $have_gcc_asm_for_x87" >&5
|
||||
echo "${ECHO_T}$have_gcc_asm_for_x87" >&6; }
|
||||
if test "$have_gcc_asm_for_x87" = yes
|
||||
then
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define HAVE_GCC_ASM_FOR_X87 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
fi
|
||||
|
||||
# Detect whether system arithmetic is subject to x87-style double
|
||||
# rounding issues. The result of this test has little meaning on non
|
||||
|
@ -23327,6 +23613,13 @@ _ACEOF
|
|||
|
||||
fi
|
||||
|
||||
# ************************************
|
||||
# * Check for mathematical functions *
|
||||
# ************************************
|
||||
|
||||
LIBS_SAVE=$LIBS
|
||||
LIBS="$LIBS $LIBM"
|
||||
|
||||
# Multiprocessing check for broken sem_getvalue
|
||||
{ echo "$as_me:$LINENO: checking for broken sem_getvalue" >&5
|
||||
echo $ECHO_N "checking for broken sem_getvalue... $ECHO_C" >&6; }
|
||||
|
|
112
configure.in
112
configure.in
|
@ -3240,12 +3240,107 @@ else AC_MSG_ERROR([proper usage is --with-libc=STRING])
|
|||
fi],
|
||||
[AC_MSG_RESULT(default LIBC="$LIBC")])
|
||||
|
||||
# ************************************
|
||||
# * Check for mathematical functions *
|
||||
# ************************************
|
||||
# **************************************************
|
||||
# * Check for various properties of floating point *
|
||||
# **************************************************
|
||||
|
||||
LIBS_SAVE=$LIBS
|
||||
LIBS="$LIBS $LIBM"
|
||||
AC_MSG_CHECKING(whether C doubles are little-endian IEEE 754 binary64)
|
||||
AC_CACHE_VAL(ac_cv_little_endian_double, [
|
||||
AC_TRY_RUN([
|
||||
#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_TRY_RUN([
|
||||
#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
|
||||
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_TRY_RUN([
|
||||
#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
|
||||
then
|
||||
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)])
|
||||
fi
|
||||
|
||||
# The short float repr introduced in Python 3.1 requires the
|
||||
# correctly-rounded string <-> double conversion functions from
|
||||
# Python/dtoa.c, which in turn require that the FPU uses 53-bit
|
||||
# rounding; this is a problem on x86, where the x87 FPU has a default
|
||||
# rounding precision of 64 bits. For gcc/x86, we try to fix this by
|
||||
# using inline assembler to get and set the x87 FPU control word.
|
||||
if test "$GCC" = yes && test -n "`$CC -dM -E - </dev/null | grep i386`"
|
||||
then
|
||||
# Check that it's okay to use gcc inline assembler to get and set
|
||||
# x87 control word. It should be, but you never know...
|
||||
AC_MSG_CHECKING(whether we can use gcc inline assembler to get and set x87 control word)
|
||||
AC_TRY_COMPILE([], [
|
||||
unsigned short cw;
|
||||
__asm__ __volatile__ ("fnstcw %0" : "=m" (cw));
|
||||
__asm__ __volatile__ ("fldcw %0" : : "m" (cw));
|
||||
],
|
||||
[have_gcc_asm_for_x87=yes], [have_gcc_asm_for_x87=no])
|
||||
AC_MSG_RESULT($have_gcc_asm_for_x87)
|
||||
if test "$have_gcc_asm_for_x87" = yes
|
||||
then
|
||||
AC_DEFINE(HAVE_GCC_ASM_FOR_X87, 1,
|
||||
[Define if we can use gcc inline assembler to get and set x87 control word])
|
||||
fi
|
||||
fi
|
||||
|
||||
# Detect whether system arithmetic is subject to x87-style double
|
||||
# rounding issues. The result of this test has little meaning on non
|
||||
|
@ -3284,6 +3379,13 @@ then
|
|||
[Define if arithmetic is subject to x87-style double rounding issue])
|
||||
fi
|
||||
|
||||
# ************************************
|
||||
# * Check for mathematical functions *
|
||||
# ************************************
|
||||
|
||||
LIBS_SAVE=$LIBS
|
||||
LIBS="$LIBS $LIBM"
|
||||
|
||||
# Multiprocessing check for broken sem_getvalue
|
||||
AC_MSG_CHECKING(for broken sem_getvalue)
|
||||
AC_CACHE_VAL(ac_cv_broken_sem_getvalue,
|
||||
|
|
|
@ -18,6 +18,18 @@
|
|||
/* Define if you have the Mach cthreads package */
|
||||
#undef C_THREADS
|
||||
|
||||
/* Define if C doubles are 64-bit IEEE 754 binary format, stored in ARM
|
||||
mixed-endian order (byte order 45670123) */
|
||||
#undef DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754
|
||||
|
||||
/* Define if C doubles are 64-bit IEEE 754 binary format, stored with the most
|
||||
significant byte first */
|
||||
#undef DOUBLE_IS_BIG_ENDIAN_IEEE754
|
||||
|
||||
/* Define if C doubles are 64-bit IEEE 754 binary format, stored with the
|
||||
least significant byte first */
|
||||
#undef DOUBLE_IS_LITTLE_ENDIAN_IEEE754
|
||||
|
||||
/* Define if --enable-ipv6 is specified */
|
||||
#undef ENABLE_IPV6
|
||||
|
||||
|
@ -240,6 +252,10 @@
|
|||
/* Define to 1 if you have the `gamma' function. */
|
||||
#undef HAVE_GAMMA
|
||||
|
||||
/* Define if we can use gcc inline assembler to get and set x87 control word
|
||||
*/
|
||||
#undef HAVE_GCC_ASM_FOR_X87
|
||||
|
||||
/* Define if you have the getaddrinfo function. */
|
||||
#undef HAVE_GETADDRINFO
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue