summaryrefslogtreecommitdiffstats
path: root/Include
diff options
context:
space:
mode:
authorMark Dickinson <dickinsm@gmail.com>2009-10-24 13:28:38 (GMT)
committerMark Dickinson <dickinsm@gmail.com>2009-10-24 13:28:38 (GMT)
commit1d6e2e1833864238b903325b37d05fef9b794393 (patch)
tree9ec5c642e19d7aacf9be92a08d28b9434f99b4f6 /Include
parent5e9f6676eaf911c9218549ea5f1e022f1ea95e32 (diff)
downloadcpython-1d6e2e1833864238b903325b37d05fef9b794393.zip
cpython-1d6e2e1833864238b903325b37d05fef9b794393.tar.gz
cpython-1d6e2e1833864238b903325b37d05fef9b794393.tar.bz2
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
Diffstat (limited to 'Include')
-rw-r--r--Include/pymacconfig.h6
-rw-r--r--Include/pymath.h5
-rw-r--r--Include/pyport.h74
3 files changed, 85 insertions, 0 deletions
diff --git a/Include/pymacconfig.h b/Include/pymacconfig.h
index b2cc0b7..3a3428c 100644
--- a/Include/pymacconfig.h
+++ b/Include/pymacconfig.h
@@ -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 */
/*
diff --git a/Include/pymath.h b/Include/pymath.h
index 7623efa..dc2c427 100644
--- a/Include/pymath.h
+++ b/Include/pymath.h
@@ -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:
diff --git a/Include/pyport.h b/Include/pyport.h
index da83196..62d4524 100644
--- a/Include/pyport.h
+++ b/Include/pyport.h
@@ -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: