Branch data Line data Source code
1 : : #ifndef Py_INTERNAL_PYMATH_H 2 : : #define Py_INTERNAL_PYMATH_H 3 : : #ifdef __cplusplus 4 : : extern "C" { 5 : : #endif 6 : : 7 : : #ifndef Py_BUILD_CORE 8 : : # error "this header requires Py_BUILD_CORE define" 9 : : #endif 10 : : 11 : : 12 : : /* _Py_ADJUST_ERANGE1(x) 13 : : * _Py_ADJUST_ERANGE2(x, y) 14 : : * Set errno to 0 before calling a libm function, and invoke one of these 15 : : * macros after, passing the function result(s) (_Py_ADJUST_ERANGE2 is useful 16 : : * for functions returning complex results). This makes two kinds of 17 : : * adjustments to errno: (A) If it looks like the platform libm set 18 : : * errno=ERANGE due to underflow, clear errno. (B) If it looks like the 19 : : * platform libm overflowed but didn't set errno, force errno to ERANGE. In 20 : : * effect, we're trying to force a useful implementation of C89 errno 21 : : * behavior. 22 : : * Caution: 23 : : * This isn't reliable. C99 no longer requires libm to set errno under 24 : : * any exceptional condition, but does require +- HUGE_VAL return 25 : : * values on overflow. A 754 box *probably* maps HUGE_VAL to a 26 : : * double infinity, and we're cool if that's so, unless the input 27 : : * was an infinity and an infinity is the expected result. A C89 28 : : * system sets errno to ERANGE, so we check for that too. We're 29 : : * out of luck if a C99 754 box doesn't map HUGE_VAL to +Inf, or 30 : : * if the returned result is a NaN, or if a C89 box returns HUGE_VAL 31 : : * in non-overflow cases. 32 : : */ 33 : 254832 : static inline void _Py_ADJUST_ERANGE1(double x) 34 : : { 35 [ + + ]: 254832 : if (errno == 0) { 36 [ + - - + ]: 254812 : if (x == Py_HUGE_VAL || x == -Py_HUGE_VAL) { 37 : 0 : errno = ERANGE; 38 : : } 39 : : } 40 [ + - + - ]: 20 : else if (errno == ERANGE && x == 0.0) { 41 : 20 : errno = 0; 42 : : } 43 : 254832 : } 44 : : 45 : 250 : static inline void _Py_ADJUST_ERANGE2(double x, double y) 46 : : { 47 [ + + + + : 250 : if (x == Py_HUGE_VAL || x == -Py_HUGE_VAL || + + ] 48 [ - + ]: 225 : y == Py_HUGE_VAL || y == -Py_HUGE_VAL) 49 : : { 50 [ + + ]: 25 : if (errno == 0) { 51 : 6 : errno = ERANGE; 52 : : } 53 : : } 54 [ + + ]: 225 : else if (errno == ERANGE) { 55 : 58 : errno = 0; 56 : : } 57 : 250 : } 58 : : 59 : : // Return the maximum value of integral type *type*. 60 : : #define _Py_IntegralTypeMax(type) \ 61 : : (_Py_IS_TYPE_SIGNED(type) ? (((((type)1 << (sizeof(type)*CHAR_BIT - 2)) - 1) << 1) + 1) : ~(type)0) 62 : : 63 : : // Return the minimum value of integral type *type*. 64 : : #define _Py_IntegralTypeMin(type) \ 65 : : (_Py_IS_TYPE_SIGNED(type) ? -_Py_IntegralTypeMax(type) - 1 : 0) 66 : : 67 : : // Check whether *v* is in the range of integral type *type*. This is most 68 : : // useful if *v* is floating-point, since demoting a floating-point *v* to an 69 : : // integral type that cannot represent *v*'s integral part is undefined 70 : : // behavior. 71 : : #define _Py_InIntegralTypeRange(type, v) \ 72 : : (_Py_IntegralTypeMin(type) <= v && v <= _Py_IntegralTypeMax(type)) 73 : : 74 : : 75 : : //--- HAVE_PY_SET_53BIT_PRECISION macro ------------------------------------ 76 : : // 77 : : // The functions _Py_dg_strtod() and _Py_dg_dtoa() in Python/dtoa.c (which are 78 : : // required to support the short float repr introduced in Python 3.1) require 79 : : // that the floating-point unit that's being used for arithmetic operations on 80 : : // C doubles is set to use 53-bit precision. It also requires that the FPU 81 : : // rounding mode is round-half-to-even, but that's less often an issue. 82 : : // 83 : : // If your FPU isn't already set to 53-bit precision/round-half-to-even, and 84 : : // you want to make use of _Py_dg_strtod() and _Py_dg_dtoa(), then you should: 85 : : // 86 : : // #define HAVE_PY_SET_53BIT_PRECISION 1 87 : : // 88 : : // and also give appropriate definitions for the following three macros: 89 : : // 90 : : // * _Py_SET_53BIT_PRECISION_HEADER: any variable declarations needed to 91 : : // use the two macros below. 92 : : // * _Py_SET_53BIT_PRECISION_START: store original FPU settings, and 93 : : // set FPU to 53-bit precision/round-half-to-even 94 : : // * _Py_SET_53BIT_PRECISION_END: restore original FPU settings 95 : : // 96 : : // The macros are designed to be used within a single C function: see 97 : : // Python/pystrtod.c for an example of their use. 98 : : 99 : : 100 : : // Get and set x87 control word for gcc/x86 101 : : #ifdef HAVE_GCC_ASM_FOR_X87 102 : : #define HAVE_PY_SET_53BIT_PRECISION 1 103 : : 104 : : // Functions defined in Python/pymath.c 105 : : extern unsigned short _Py_get_387controlword(void); 106 : : extern void _Py_set_387controlword(unsigned short); 107 : : 108 : : #define _Py_SET_53BIT_PRECISION_HEADER \ 109 : : unsigned short old_387controlword, new_387controlword 110 : : #define _Py_SET_53BIT_PRECISION_START \ 111 : : do { \ 112 : : old_387controlword = _Py_get_387controlword(); \ 113 : : new_387controlword = (old_387controlword & ~0x0f00) | 0x0200; \ 114 : : if (new_387controlword != old_387controlword) { \ 115 : : _Py_set_387controlword(new_387controlword); \ 116 : : } \ 117 : : } while (0) 118 : : #define _Py_SET_53BIT_PRECISION_END \ 119 : : do { \ 120 : : if (new_387controlword != old_387controlword) { \ 121 : : _Py_set_387controlword(old_387controlword); \ 122 : : } \ 123 : : } while (0) 124 : : #endif 125 : : 126 : : // Get and set x87 control word for VisualStudio/x86. 127 : : // x87 is not supported in 64-bit or ARM. 128 : : #if defined(_MSC_VER) && !defined(_WIN64) && !defined(_M_ARM) 129 : : #define HAVE_PY_SET_53BIT_PRECISION 1 130 : : 131 : : #include <float.h> // __control87_2() 132 : : 133 : : #define _Py_SET_53BIT_PRECISION_HEADER \ 134 : : unsigned int old_387controlword, new_387controlword, out_387controlword 135 : : // We use the __control87_2 function to set only the x87 control word. 136 : : // The SSE control word is unaffected. 137 : : #define _Py_SET_53BIT_PRECISION_START \ 138 : : do { \ 139 : : __control87_2(0, 0, &old_387controlword, NULL); \ 140 : : new_387controlword = \ 141 : : (old_387controlword & ~(_MCW_PC | _MCW_RC)) | (_PC_53 | _RC_NEAR); \ 142 : : if (new_387controlword != old_387controlword) { \ 143 : : __control87_2(new_387controlword, _MCW_PC | _MCW_RC, \ 144 : : &out_387controlword, NULL); \ 145 : : } \ 146 : : } while (0) 147 : : #define _Py_SET_53BIT_PRECISION_END \ 148 : : do { \ 149 : : if (new_387controlword != old_387controlword) { \ 150 : : __control87_2(old_387controlword, _MCW_PC | _MCW_RC, \ 151 : : &out_387controlword, NULL); \ 152 : : } \ 153 : : } while (0) 154 : : #endif 155 : : 156 : : 157 : : // MC68881 158 : : #ifdef HAVE_GCC_ASM_FOR_MC68881 159 : : #define HAVE_PY_SET_53BIT_PRECISION 1 160 : : #define _Py_SET_53BIT_PRECISION_HEADER \ 161 : : unsigned int old_fpcr, new_fpcr 162 : : #define _Py_SET_53BIT_PRECISION_START \ 163 : : do { \ 164 : : __asm__ ("fmove.l %%fpcr,%0" : "=g" (old_fpcr)); \ 165 : : /* Set double precision / round to nearest. */ \ 166 : : new_fpcr = (old_fpcr & ~0xf0) | 0x80; \ 167 : : if (new_fpcr != old_fpcr) { \ 168 : : __asm__ volatile ("fmove.l %0,%%fpcr" : : "g" (new_fpcr));\ 169 : : } \ 170 : : } while (0) 171 : : #define _Py_SET_53BIT_PRECISION_END \ 172 : : do { \ 173 : : if (new_fpcr != old_fpcr) { \ 174 : : __asm__ volatile ("fmove.l %0,%%fpcr" : : "g" (old_fpcr)); \ 175 : : } \ 176 : : } while (0) 177 : : #endif 178 : : 179 : : // Default definitions are empty 180 : : #ifndef _Py_SET_53BIT_PRECISION_HEADER 181 : : # define _Py_SET_53BIT_PRECISION_HEADER 182 : : # define _Py_SET_53BIT_PRECISION_START 183 : : # define _Py_SET_53BIT_PRECISION_END 184 : : #endif 185 : : 186 : : 187 : : //--- _PY_SHORT_FLOAT_REPR macro ------------------------------------------- 188 : : 189 : : // If we can't guarantee 53-bit precision, don't use the code 190 : : // in Python/dtoa.c, but fall back to standard code. This 191 : : // means that repr of a float will be long (17 significant digits). 192 : : // 193 : : // Realistically, there are two things that could go wrong: 194 : : // 195 : : // (1) doubles aren't IEEE 754 doubles, or 196 : : // (2) we're on x86 with the rounding precision set to 64-bits 197 : : // (extended precision), and we don't know how to change 198 : : // the rounding precision. 199 : : #if !defined(DOUBLE_IS_LITTLE_ENDIAN_IEEE754) && \ 200 : : !defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) && \ 201 : : !defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754) 202 : : # define _PY_SHORT_FLOAT_REPR 0 203 : : #endif 204 : : 205 : : // Double rounding is symptomatic of use of extended precision on x86. 206 : : // If we're seeing double rounding, and we don't have any mechanism available 207 : : // for changing the FPU rounding precision, then don't use Python/dtoa.c. 208 : : #if defined(X87_DOUBLE_ROUNDING) && !defined(HAVE_PY_SET_53BIT_PRECISION) 209 : : # define _PY_SHORT_FLOAT_REPR 0 210 : : #endif 211 : : 212 : : #ifndef _PY_SHORT_FLOAT_REPR 213 : : # define _PY_SHORT_FLOAT_REPR 1 214 : : #endif 215 : : 216 : : 217 : : #ifdef __cplusplus 218 : : } 219 : : #endif 220 : : #endif /* !Py_INTERNAL_PYMATH_H */