summaryrefslogtreecommitdiffstats
path: root/Include/internal/pycore_pymath.h
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2021-10-11 21:09:40 (GMT)
committerGitHub <noreply@github.com>2021-10-11 21:09:40 (GMT)
commit7103356455c8b0c2ba3523929327756413337a31 (patch)
tree7fc7286a502fe00cf42bd2f9c6759064f0f6df82 /Include/internal/pycore_pymath.h
parenta9fe1a8e5b4698937e06c2c419da92e6f78f2ee7 (diff)
downloadcpython-7103356455c8b0c2ba3523929327756413337a31.zip
cpython-7103356455c8b0c2ba3523929327756413337a31.tar.gz
cpython-7103356455c8b0c2ba3523929327756413337a31.tar.bz2
bpo-45412: Move _Py_SET_53BIT_PRECISION_START to pycore_pymath.h (GH-28882)
Move the following macros , to pycore_pymath.h (internal C API): * _Py_SET_53BIT_PRECISION_HEADER * _Py_SET_53BIT_PRECISION_START * _Py_SET_53BIT_PRECISION_END PEP 7: add braces to if and "do { ... } while (0)" in these macros. Move also _Py_get_387controlword() and _Py_set_387controlword() definitions to pycore_pymath.h. These functions are no longer exported. pystrtod.c now includes pycore_pymath.h.
Diffstat (limited to 'Include/internal/pycore_pymath.h')
-rw-r--r--Include/internal/pycore_pymath.h91
1 files changed, 91 insertions, 0 deletions
diff --git a/Include/internal/pycore_pymath.h b/Include/internal/pycore_pymath.h
index e4d5778..b1a2004 100644
--- a/Include/internal/pycore_pymath.h
+++ b/Include/internal/pycore_pymath.h
@@ -74,6 +74,97 @@ static inline void _Py_ADJUST_ERANGE2(double x, double y)
#define _Py_InIntegralTypeRange(type, v) \
(_Py_IntegralTypeMin(type) <= v && v <= _Py_IntegralTypeMax(type))
+
+//--- Implementation of the HAVE_PY_SET_53BIT_PRECISION macro -------------
+//--- defined in pyport.h -------------------------------------------------
+//
+// Give appropriate definitions for the following three macros:
+//
+// _Py_SET_53BIT_PRECISION_HEADER : any variable declarations needed to
+// use the two macros below.
+// _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
+
+// Get and set x87 control word for gcc/x86
+#ifdef HAVE_GCC_ASM_FOR_X87
+
+// Functions defined in Python/pymath.c
+extern unsigned short _Py_get_387controlword(void);
+extern void _Py_set_387controlword(unsigned short);
+
+#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 \
+ do { \
+ if (new_387controlword != old_387controlword) { \
+ _Py_set_387controlword(old_387controlword); \
+ } \
+ } while (0)
+#endif
+
+// Get and set x87 control word for VisualStudio/x86.
+// x87 is not supported in 64-bit or ARM.
+#if defined(_MSC_VER) && !defined(_WIN64) && !defined(_M_ARM)
+#define _Py_SET_53BIT_PRECISION_HEADER \
+ unsigned int old_387controlword, new_387controlword, out_387controlword
+ // We use the __control87_2 function to set only the x87 control word.
+ // The SSE control word is unaffected.
+#define _Py_SET_53BIT_PRECISION_START \
+ do { \
+ __control87_2(0, 0, &old_387controlword, NULL); \
+ new_387controlword = \
+ (old_387controlword & ~(_MCW_PC | _MCW_RC)) | (_PC_53 | _RC_NEAR); \
+ if (new_387controlword != old_387controlword) { \
+ __control87_2(new_387controlword, _MCW_PC | _MCW_RC, \
+ &out_387controlword, NULL); \
+ } \
+ } while (0)
+#define _Py_SET_53BIT_PRECISION_END \
+ do { \
+ if (new_387controlword != old_387controlword) { \
+ __control87_2(old_387controlword, _MCW_PC | _MCW_RC, \
+ &out_387controlword, NULL); \
+ } \
+ } while (0)
+#endif
+
+#ifdef HAVE_GCC_ASM_FOR_MC68881
+#define _Py_SET_53BIT_PRECISION_HEADER \
+ unsigned int old_fpcr, new_fpcr
+#define _Py_SET_53BIT_PRECISION_START \
+ do { \
+ __asm__ ("fmove.l %%fpcr,%0" : "=g" (old_fpcr)); \
+ /* Set double precision / round to nearest. */ \
+ new_fpcr = (old_fpcr & ~0xf0) | 0x80; \
+ if (new_fpcr != old_fpcr) { \
+ __asm__ volatile ("fmove.l %0,%%fpcr" : : "g" (new_fpcr));\
+ } \
+ } while (0)
+#define _Py_SET_53BIT_PRECISION_END \
+ do { \
+ if (new_fpcr != old_fpcr) { \
+ __asm__ volatile ("fmove.l %0,%%fpcr" : : "g" (old_fpcr)); \
+ } \
+ } while (0)
+#endif
+
+// Default definitions are empty
+#ifndef _Py_SET_53BIT_PRECISION_HEADER
+# define _Py_SET_53BIT_PRECISION_HEADER
+# define _Py_SET_53BIT_PRECISION_START
+# define _Py_SET_53BIT_PRECISION_END
+#endif
+
+
#ifdef __cplusplus
}
#endif