mirror of https://github.com/python/cpython
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:
parent
a9fe1a8e5b
commit
7103356455
|
@ -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
|
||||
|
|
|
@ -78,13 +78,6 @@ PyAPI_FUNC(double) _Py_force_double(double);
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef Py_LIMITED_API
|
||||
#ifdef HAVE_GCC_ASM_FOR_X87
|
||||
PyAPI_FUNC(unsigned short) _Py_get_387controlword(void);
|
||||
PyAPI_FUNC(void) _Py_set_387controlword(unsigned short);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Py_IS_NAN(X)
|
||||
* Return 1 if float or double arg is a NaN, else 0.
|
||||
* Caution:
|
||||
|
@ -95,11 +88,11 @@ PyAPI_FUNC(void) _Py_set_387controlword(unsigned short);
|
|||
* Note: PC/pyconfig.h defines Py_IS_NAN as _isnan
|
||||
*/
|
||||
#ifndef Py_IS_NAN
|
||||
#if defined HAVE_DECL_ISNAN && HAVE_DECL_ISNAN == 1
|
||||
#define Py_IS_NAN(X) isnan(X)
|
||||
#else
|
||||
#define Py_IS_NAN(X) ((X) != (X))
|
||||
#endif
|
||||
# if defined HAVE_DECL_ISNAN && HAVE_DECL_ISNAN == 1
|
||||
# define Py_IS_NAN(X) isnan(X)
|
||||
# else
|
||||
# define Py_IS_NAN(X) ((X) != (X))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Py_IS_INFINITY(X)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -13,10 +13,10 @@ double _Py_force_double(double x)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GCC_ASM_FOR_X87
|
||||
|
||||
/* inline assembly for getting and setting the 387 FPU control word on
|
||||
gcc/x86 */
|
||||
#ifdef HAVE_GCC_ASM_FOR_X87
|
||||
// Inline assembly for getting and setting the 387 FPU control word on
|
||||
// GCC/x86.
|
||||
#ifdef _Py_MEMORY_SANITIZER
|
||||
__attribute__((no_sanitize_memory))
|
||||
#endif
|
||||
|
@ -29,8 +29,7 @@ unsigned short _Py_get_387controlword(void) {
|
|||
void _Py_set_387controlword(unsigned short cw) {
|
||||
__asm__ __volatile__ ("fldcw %0" : : "m" (cw));
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // HAVE_GCC_ASM_FOR_X87
|
||||
|
||||
|
||||
#ifndef HAVE_HYPOT
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <Python.h>
|
||||
#include "pycore_dtoa.h"
|
||||
#include "pycore_pymath.h" // _Py_SET_53BIT_PRECISION_START
|
||||
#include <locale.h>
|
||||
|
||||
/* Case-insensitive string match used for nan and inf detection; t should be
|
||||
|
|
Loading…
Reference in New Issue