mirror of
https://github.com/python/cpython.git
synced 2025-07-30 22:54:16 +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_VOID_P
|
||||||
# undef SIZEOF__BOOL
|
# undef SIZEOF__BOOL
|
||||||
# undef WORDS_BIGENDIAN
|
# 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
|
# undef VA_LIST_IS_ARRAY
|
||||||
# if defined(__LP64__) && defined(__x86_64__)
|
# if defined(__LP64__) && defined(__x86_64__)
|
||||||
|
@ -65,6 +68,9 @@
|
||||||
|
|
||||||
#ifdef __BIG_ENDIAN__
|
#ifdef __BIG_ENDIAN__
|
||||||
#define WORDS_BIGENDIAN 1
|
#define WORDS_BIGENDIAN 1
|
||||||
|
#define DOUBLE_IS_BIG_ENDIAN_IEEE754
|
||||||
|
#else
|
||||||
|
#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754
|
||||||
#endif /* __BIG_ENDIAN */
|
#endif /* __BIG_ENDIAN */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -92,6 +92,11 @@ PyAPI_FUNC(double) _Py_force_double(double);
|
||||||
# endif
|
# endif
|
||||||
#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)
|
/* Py_IS_NAN(X)
|
||||||
* Return 1 if float or double arg is a NaN, else 0.
|
* Return 1 if float or double arg is a NaN, else 0.
|
||||||
* Caution:
|
* Caution:
|
||||||
|
|
|
@ -488,6 +488,80 @@ extern "C" {
|
||||||
errno = 0; \
|
errno = 0; \
|
||||||
} while(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)
|
/* Py_DEPRECATED(version)
|
||||||
* Declare a variable, type, or function deprecated.
|
* Declare a variable, type, or function deprecated.
|
||||||
* Usage:
|
* 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 */
|
socket handles greater than FD_SETSIZE */
|
||||||
#define Py_SOCKET_FD_CAN_BE_GE_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 */
|
#endif /* !Py_CONFIG_H */
|
||||||
|
|
|
@ -13,6 +13,24 @@ double _Py_force_double(double x)
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
#ifndef HAVE_HYPOT
|
||||||
double hypot(double x, double y)
|
double hypot(double x, double y)
|
||||||
{
|
{
|
||||||
|
|
305
configure
vendored
305
configure
vendored
|
@ -1,5 +1,5 @@
|
||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# From configure.in Revision: 74978 .
|
# From configure.in Revision: 75131 .
|
||||||
# Guess values for system-dependent variables and create Makefiles.
|
# Guess values for system-dependent variables and create Makefiles.
|
||||||
# Generated by GNU Autoconf 2.61 for python 2.7.
|
# Generated by GNU Autoconf 2.61 for python 2.7.
|
||||||
#
|
#
|
||||||
|
@ -23233,12 +23233,298 @@ echo "${ECHO_T}default LIBC=\"$LIBC\"" >&6; }
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
# ************************************
|
# **************************************************
|
||||||
# * Check for mathematical functions *
|
# * Check for various properties of floating point *
|
||||||
# ************************************
|
# **************************************************
|
||||||
|
|
||||||
LIBS_SAVE=$LIBS
|
{ echo "$as_me:$LINENO: checking whether C doubles are little-endian IEEE 754 binary64" >&5
|
||||||
LIBS="$LIBS $LIBM"
|
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
|
# Detect whether system arithmetic is subject to x87-style double
|
||||||
# rounding issues. The result of this test has little meaning on non
|
# rounding issues. The result of this test has little meaning on non
|
||||||
|
@ -23327,6 +23613,13 @@ _ACEOF
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# ************************************
|
||||||
|
# * Check for mathematical functions *
|
||||||
|
# ************************************
|
||||||
|
|
||||||
|
LIBS_SAVE=$LIBS
|
||||||
|
LIBS="$LIBS $LIBM"
|
||||||
|
|
||||||
# Multiprocessing check for broken sem_getvalue
|
# Multiprocessing check for broken sem_getvalue
|
||||||
{ echo "$as_me:$LINENO: checking for broken sem_getvalue" >&5
|
{ echo "$as_me:$LINENO: checking for broken sem_getvalue" >&5
|
||||||
echo $ECHO_N "checking for broken sem_getvalue... $ECHO_C" >&6; }
|
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],
|
fi],
|
||||||
[AC_MSG_RESULT(default LIBC="$LIBC")])
|
[AC_MSG_RESULT(default LIBC="$LIBC")])
|
||||||
|
|
||||||
# ************************************
|
# **************************************************
|
||||||
# * Check for mathematical functions *
|
# * Check for various properties of floating point *
|
||||||
# ************************************
|
# **************************************************
|
||||||
|
|
||||||
LIBS_SAVE=$LIBS
|
AC_MSG_CHECKING(whether C doubles are little-endian IEEE 754 binary64)
|
||||||
LIBS="$LIBS $LIBM"
|
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
|
# Detect whether system arithmetic is subject to x87-style double
|
||||||
# rounding issues. The result of this test has little meaning on non
|
# 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])
|
[Define if arithmetic is subject to x87-style double rounding issue])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# ************************************
|
||||||
|
# * Check for mathematical functions *
|
||||||
|
# ************************************
|
||||||
|
|
||||||
|
LIBS_SAVE=$LIBS
|
||||||
|
LIBS="$LIBS $LIBM"
|
||||||
|
|
||||||
# Multiprocessing check for broken sem_getvalue
|
# Multiprocessing check for broken sem_getvalue
|
||||||
AC_MSG_CHECKING(for broken sem_getvalue)
|
AC_MSG_CHECKING(for broken sem_getvalue)
|
||||||
AC_CACHE_VAL(ac_cv_broken_sem_getvalue,
|
AC_CACHE_VAL(ac_cv_broken_sem_getvalue,
|
||||||
|
|
|
@ -18,6 +18,18 @@
|
||||||
/* Define if you have the Mach cthreads package */
|
/* Define if you have the Mach cthreads package */
|
||||||
#undef C_THREADS
|
#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 */
|
/* Define if --enable-ipv6 is specified */
|
||||||
#undef ENABLE_IPV6
|
#undef ENABLE_IPV6
|
||||||
|
|
||||||
|
@ -240,6 +252,10 @@
|
||||||
/* Define to 1 if you have the `gamma' function. */
|
/* Define to 1 if you have the `gamma' function. */
|
||||||
#undef HAVE_GAMMA
|
#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. */
|
/* Define if you have the getaddrinfo function. */
|
||||||
#undef HAVE_GETADDRINFO
|
#undef HAVE_GETADDRINFO
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue