Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:06:46

0001 #ifndef Py_INTERNAL_PYMATH_H
0002 #define Py_INTERNAL_PYMATH_H
0003 #ifdef __cplusplus
0004 extern "C" {
0005 #endif
0006 
0007 #ifndef Py_BUILD_CORE
0008 #  error "this header requires Py_BUILD_CORE define"
0009 #endif
0010 
0011 
0012 /* _Py_ADJUST_ERANGE1(x)
0013  * _Py_ADJUST_ERANGE2(x, y)
0014  * Set errno to 0 before calling a libm function, and invoke one of these
0015  * macros after, passing the function result(s) (_Py_ADJUST_ERANGE2 is useful
0016  * for functions returning complex results).  This makes two kinds of
0017  * adjustments to errno:  (A) If it looks like the platform libm set
0018  * errno=ERANGE due to underflow, clear errno. (B) If it looks like the
0019  * platform libm overflowed but didn't set errno, force errno to ERANGE.  In
0020  * effect, we're trying to force a useful implementation of C89 errno
0021  * behavior.
0022  * Caution:
0023  *    This isn't reliable.  C99 no longer requires libm to set errno under
0024  *        any exceptional condition, but does require +- HUGE_VAL return
0025  *        values on overflow.  A 754 box *probably* maps HUGE_VAL to a
0026  *        double infinity, and we're cool if that's so, unless the input
0027  *        was an infinity and an infinity is the expected result.  A C89
0028  *        system sets errno to ERANGE, so we check for that too.  We're
0029  *        out of luck if a C99 754 box doesn't map HUGE_VAL to +Inf, or
0030  *        if the returned result is a NaN, or if a C89 box returns HUGE_VAL
0031  *        in non-overflow cases.
0032  */
0033 static inline void _Py_ADJUST_ERANGE1(double x)
0034 {
0035     if (errno == 0) {
0036         if (x == Py_HUGE_VAL || x == -Py_HUGE_VAL) {
0037             errno = ERANGE;
0038         }
0039     }
0040     else if (errno == ERANGE && x == 0.0) {
0041         errno = 0;
0042     }
0043 }
0044 
0045 static inline void _Py_ADJUST_ERANGE2(double x, double y)
0046 {
0047     if (x == Py_HUGE_VAL || x == -Py_HUGE_VAL ||
0048         y == Py_HUGE_VAL || y == -Py_HUGE_VAL)
0049     {
0050         if (errno == 0) {
0051             errno = ERANGE;
0052         }
0053     }
0054     else if (errno == ERANGE) {
0055         errno = 0;
0056     }
0057 }
0058 
0059 
0060 //--- HAVE_PY_SET_53BIT_PRECISION macro ------------------------------------
0061 //
0062 // The functions _Py_dg_strtod() and _Py_dg_dtoa() in Python/dtoa.c (which are
0063 // required to support the short float repr introduced in Python 3.1) require
0064 // that the floating-point unit that's being used for arithmetic operations on
0065 // C doubles is set to use 53-bit precision.  It also requires that the FPU
0066 // rounding mode is round-half-to-even, but that's less often an issue.
0067 //
0068 // If your FPU isn't already set to 53-bit precision/round-half-to-even, and
0069 // you want to make use of _Py_dg_strtod() and _Py_dg_dtoa(), then you should:
0070 //
0071 //     #define HAVE_PY_SET_53BIT_PRECISION 1
0072 //
0073 // and also give appropriate definitions for the following three macros:
0074 //
0075 // * _Py_SET_53BIT_PRECISION_HEADER: any variable declarations needed to
0076 //   use the two macros below.
0077 // * _Py_SET_53BIT_PRECISION_START: store original FPU settings, and
0078 //   set FPU to 53-bit precision/round-half-to-even
0079 // * _Py_SET_53BIT_PRECISION_END: restore original FPU settings
0080 //
0081 // The macros are designed to be used within a single C function: see
0082 // Python/pystrtod.c for an example of their use.
0083 
0084 
0085 // Get and set x87 control word for gcc/x86
0086 #ifdef HAVE_GCC_ASM_FOR_X87
0087 #define HAVE_PY_SET_53BIT_PRECISION 1
0088 
0089 // Functions defined in Python/pymath.c
0090 extern unsigned short _Py_get_387controlword(void);
0091 extern void _Py_set_387controlword(unsigned short);
0092 
0093 #define _Py_SET_53BIT_PRECISION_HEADER                                  \
0094     unsigned short old_387controlword, new_387controlword
0095 #define _Py_SET_53BIT_PRECISION_START                                   \
0096     do {                                                                \
0097         old_387controlword = _Py_get_387controlword();                  \
0098         new_387controlword = (old_387controlword & ~0x0f00) | 0x0200;   \
0099         if (new_387controlword != old_387controlword) {                 \
0100             _Py_set_387controlword(new_387controlword);                 \
0101         }                                                               \
0102     } while (0)
0103 #define _Py_SET_53BIT_PRECISION_END                                     \
0104     do {                                                                \
0105         if (new_387controlword != old_387controlword) {                 \
0106             _Py_set_387controlword(old_387controlword);                 \
0107         }                                                               \
0108     } while (0)
0109 #endif
0110 
0111 // Get and set x87 control word for VisualStudio/x86.
0112 // x87 is not supported in 64-bit or ARM.
0113 #if defined(_MSC_VER) && !defined(_WIN64) && !defined(_M_ARM)
0114 #define HAVE_PY_SET_53BIT_PRECISION 1
0115 
0116 #include <float.h>                // __control87_2()
0117 
0118 #define _Py_SET_53BIT_PRECISION_HEADER \
0119     unsigned int old_387controlword, new_387controlword, out_387controlword
0120     // We use the __control87_2 function to set only the x87 control word.
0121     // The SSE control word is unaffected.
0122 #define _Py_SET_53BIT_PRECISION_START                                   \
0123     do {                                                                \
0124         __control87_2(0, 0, &old_387controlword, NULL);                 \
0125         new_387controlword =                                            \
0126           (old_387controlword & ~(_MCW_PC | _MCW_RC)) | (_PC_53 | _RC_NEAR); \
0127         if (new_387controlword != old_387controlword) {                 \
0128             __control87_2(new_387controlword, _MCW_PC | _MCW_RC,        \
0129                           &out_387controlword, NULL);                   \
0130         }                                                               \
0131     } while (0)
0132 #define _Py_SET_53BIT_PRECISION_END                                     \
0133     do {                                                                \
0134         if (new_387controlword != old_387controlword) {                 \
0135             __control87_2(old_387controlword, _MCW_PC | _MCW_RC,        \
0136                           &out_387controlword, NULL);                   \
0137         }                                                               \
0138     } while (0)
0139 #endif
0140 
0141 
0142 // MC68881
0143 #ifdef HAVE_GCC_ASM_FOR_MC68881
0144 #define HAVE_PY_SET_53BIT_PRECISION 1
0145 #define _Py_SET_53BIT_PRECISION_HEADER \
0146     unsigned int old_fpcr, new_fpcr
0147 #define _Py_SET_53BIT_PRECISION_START                                   \
0148     do {                                                                \
0149         __asm__ ("fmove.l %%fpcr,%0" : "=g" (old_fpcr));                \
0150         /* Set double precision / round to nearest.  */                 \
0151         new_fpcr = (old_fpcr & ~0xf0) | 0x80;                           \
0152         if (new_fpcr != old_fpcr) {                                     \
0153               __asm__ volatile ("fmove.l %0,%%fpcr" : : "g" (new_fpcr));\
0154         }                                                               \
0155     } while (0)
0156 #define _Py_SET_53BIT_PRECISION_END                                     \
0157     do {                                                                \
0158         if (new_fpcr != old_fpcr) {                                     \
0159             __asm__ volatile ("fmove.l %0,%%fpcr" : : "g" (old_fpcr));  \
0160         }                                                               \
0161     } while (0)
0162 #endif
0163 
0164 // Default definitions are empty
0165 #ifndef _Py_SET_53BIT_PRECISION_HEADER
0166 #  define _Py_SET_53BIT_PRECISION_HEADER
0167 #  define _Py_SET_53BIT_PRECISION_START
0168 #  define _Py_SET_53BIT_PRECISION_END
0169 #endif
0170 
0171 
0172 //--- _PY_SHORT_FLOAT_REPR macro -------------------------------------------
0173 
0174 // If we can't guarantee 53-bit precision, don't use the code
0175 // in Python/dtoa.c, but fall back to standard code.  This
0176 // means that repr of a float will be long (17 significant digits).
0177 //
0178 // Realistically, there are two things that could go wrong:
0179 //
0180 // (1) doubles aren't IEEE 754 doubles, or
0181 // (2) we're on x86 with the rounding precision set to 64-bits
0182 //     (extended precision), and we don't know how to change
0183 //     the rounding precision.
0184 #if !defined(DOUBLE_IS_LITTLE_ENDIAN_IEEE754) && \
0185     !defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) && \
0186     !defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754)
0187 #  define _PY_SHORT_FLOAT_REPR 0
0188 #endif
0189 
0190 // Double rounding is symptomatic of use of extended precision on x86.
0191 // If we're seeing double rounding, and we don't have any mechanism available
0192 // for changing the FPU rounding precision, then don't use Python/dtoa.c.
0193 #if defined(X87_DOUBLE_ROUNDING) && !defined(HAVE_PY_SET_53BIT_PRECISION)
0194 #  define _PY_SHORT_FLOAT_REPR 0
0195 #endif
0196 
0197 #ifndef _PY_SHORT_FLOAT_REPR
0198 #  define _PY_SHORT_FLOAT_REPR 1
0199 #endif
0200 
0201 
0202 #ifdef __cplusplus
0203 }
0204 #endif
0205 #endif /* !Py_INTERNAL_PYMATH_H */