diff options
author | Victor Stinner <vstinner@python.org> | 2021-10-11 21:09:40 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-11 21:09:40 (GMT) |
commit | 7103356455c8b0c2ba3523929327756413337a31 (patch) | |
tree | 7fc7286a502fe00cf42bd2f9c6759064f0f6df82 /Include/internal/pycore_pymath.h | |
parent | a9fe1a8e5b4698937e06c2c419da92e6f78f2ee7 (diff) | |
download | cpython-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.h | 91 |
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 |