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.
This commit is contained in:
Victor Stinner 2021-10-11 23:09:40 +02:00 committed by GitHub
parent a9fe1a8e5b
commit 7103356455
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 111 additions and 88 deletions

View file

@ -335,85 +335,24 @@ extern "C" {
*
* #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 */
// HAVE_PY_SET_53BIT_PRECISION macro must be kept in sync with pycore_pymath.h
#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)
// Get and set x87 control word for gcc/x86
# define HAVE_PY_SET_53BIT_PRECISION 1
#endif
/* get and set x87 control word for VisualStudio/x86 */
#if defined(_MSC_VER) && !defined(_WIN64) && !defined(_M_ARM) /* x87 not supported in 64-bit or ARM */
#define HAVE_PY_SET_53BIT_PRECISION 1
#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)
#if defined(_MSC_VER) && !defined(_WIN64) && !defined(_M_ARM)
// Get and set x87 control word for VisualStudio/x86.
// x87 not supported in 64-bit or ARM.
# define HAVE_PY_SET_53BIT_PRECISION 1
#endif
#ifdef HAVE_GCC_ASM_FOR_MC68881
#define HAVE_PY_SET_53BIT_PRECISION 1
#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)
# define HAVE_PY_SET_53BIT_PRECISION 1
#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
@ -430,14 +369,14 @@ extern "C" {
#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
# 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
# define PY_NO_SHORT_FLOAT_REPR
#endif