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 */
_Py_ADJUST_ERANGE1(double x)33 static inline void _Py_ADJUST_ERANGE1(double x)
34 {
35 if (errno == 0) {
36 if (x == Py_HUGE_VAL || x == -Py_HUGE_VAL) {
37 errno = ERANGE;
38 }
39 }
40 else if (errno == ERANGE && x == 0.0) {
41 errno = 0;
42 }
43 }
44
_Py_ADJUST_ERANGE2(double x, double y)45 static inline void _Py_ADJUST_ERANGE2(double x, double y)
46 {
47 if (x == Py_HUGE_VAL || x == -Py_HUGE_VAL ||
48 y == Py_HUGE_VAL || y == -Py_HUGE_VAL)
49 {
50 if (errno == 0) {
51 errno = ERANGE;
52 }
53 }
54 else if (errno == ERANGE) {
55 errno = 0;
56 }
57 }
58
59 // Return whether integral type *type* is signed or not.
60 #define _Py_IntegralTypeSigned(type) \
61 ((type)(-1) < 0)
62
63 // Return the maximum value of integral type *type*.
64 #define _Py_IntegralTypeMax(type) \
65 ((_Py_IntegralTypeSigned(type)) ? (((((type)1 << (sizeof(type)*CHAR_BIT - 2)) - 1) << 1) + 1) : ~(type)0)
66
67 // Return the minimum value of integral type *type*.
68 #define _Py_IntegralTypeMin(type) \
69 ((_Py_IntegralTypeSigned(type)) ? -_Py_IntegralTypeMax(type) - 1 : 0)
70
71 // Check whether *v* is in the range of integral type *type*. This is most
72 // useful if *v* is floating-point, since demoting a floating-point *v* to an
73 // integral type that cannot represent *v*'s integral part is undefined
74 // behavior.
75 #define _Py_InIntegralTypeRange(type, v) \
76 (_Py_IntegralTypeMin(type) <= v && v <= _Py_IntegralTypeMax(type))
77
78
79 //--- HAVE_PY_SET_53BIT_PRECISION macro ------------------------------------
80 //
81 // The functions _Py_dg_strtod() and _Py_dg_dtoa() in Python/dtoa.c (which are
82 // required to support the short float repr introduced in Python 3.1) require
83 // that the floating-point unit that's being used for arithmetic operations on
84 // C doubles is set to use 53-bit precision. It also requires that the FPU
85 // rounding mode is round-half-to-even, but that's less often an issue.
86 //
87 // If your FPU isn't already set to 53-bit precision/round-half-to-even, and
88 // you want to make use of _Py_dg_strtod() and _Py_dg_dtoa(), then you should:
89 //
90 // #define HAVE_PY_SET_53BIT_PRECISION 1
91 //
92 // and also give appropriate definitions for the following three macros:
93 //
94 // * _Py_SET_53BIT_PRECISION_HEADER: any variable declarations needed to
95 // use the two macros below.
96 // * _Py_SET_53BIT_PRECISION_START: store original FPU settings, and
97 // set FPU to 53-bit precision/round-half-to-even
98 // * _Py_SET_53BIT_PRECISION_END: restore original FPU settings
99 //
100 // The macros are designed to be used within a single C function: see
101 // Python/pystrtod.c for an example of their use.
102
103
104 // Get and set x87 control word for gcc/x86
105 #ifdef HAVE_GCC_ASM_FOR_X87
106 #define HAVE_PY_SET_53BIT_PRECISION 1
107
108 // Functions defined in Python/pymath.c
109 extern unsigned short _Py_get_387controlword(void);
110 extern void _Py_set_387controlword(unsigned short);
111
112 #define _Py_SET_53BIT_PRECISION_HEADER \
113 unsigned short old_387controlword, new_387controlword
114 #define _Py_SET_53BIT_PRECISION_START \
115 do { \
116 old_387controlword = _Py_get_387controlword(); \
117 new_387controlword = (old_387controlword & ~0x0f00) | 0x0200; \
118 if (new_387controlword != old_387controlword) { \
119 _Py_set_387controlword(new_387controlword); \
120 } \
121 } while (0)
122 #define _Py_SET_53BIT_PRECISION_END \
123 do { \
124 if (new_387controlword != old_387controlword) { \
125 _Py_set_387controlword(old_387controlword); \
126 } \
127 } while (0)
128 #endif
129
130 // Get and set x87 control word for VisualStudio/x86.
131 // x87 is not supported in 64-bit or ARM.
132 #if defined(_MSC_VER) && !defined(_WIN64) && !defined(_M_ARM)
133 #define HAVE_PY_SET_53BIT_PRECISION 1
134
135 #include <float.h> // __control87_2()
136
137 #define _Py_SET_53BIT_PRECISION_HEADER \
138 unsigned int old_387controlword, new_387controlword, out_387controlword
139 // We use the __control87_2 function to set only the x87 control word.
140 // The SSE control word is unaffected.
141 #define _Py_SET_53BIT_PRECISION_START \
142 do { \
143 __control87_2(0, 0, &old_387controlword, NULL); \
144 new_387controlword = \
145 (old_387controlword & ~(_MCW_PC | _MCW_RC)) | (_PC_53 | _RC_NEAR); \
146 if (new_387controlword != old_387controlword) { \
147 __control87_2(new_387controlword, _MCW_PC | _MCW_RC, \
148 &out_387controlword, NULL); \
149 } \
150 } while (0)
151 #define _Py_SET_53BIT_PRECISION_END \
152 do { \
153 if (new_387controlword != old_387controlword) { \
154 __control87_2(old_387controlword, _MCW_PC | _MCW_RC, \
155 &out_387controlword, NULL); \
156 } \
157 } while (0)
158 #endif
159
160
161 // MC68881
162 #ifdef HAVE_GCC_ASM_FOR_MC68881
163 #define HAVE_PY_SET_53BIT_PRECISION 1
164 #define _Py_SET_53BIT_PRECISION_HEADER \
165 unsigned int old_fpcr, new_fpcr
166 #define _Py_SET_53BIT_PRECISION_START \
167 do { \
168 __asm__ ("fmove.l %%fpcr,%0" : "=g" (old_fpcr)); \
169 /* Set double precision / round to nearest. */ \
170 new_fpcr = (old_fpcr & ~0xf0) | 0x80; \
171 if (new_fpcr != old_fpcr) { \
172 __asm__ volatile ("fmove.l %0,%%fpcr" : : "g" (new_fpcr));\
173 } \
174 } while (0)
175 #define _Py_SET_53BIT_PRECISION_END \
176 do { \
177 if (new_fpcr != old_fpcr) { \
178 __asm__ volatile ("fmove.l %0,%%fpcr" : : "g" (old_fpcr)); \
179 } \
180 } while (0)
181 #endif
182
183 // Default definitions are empty
184 #ifndef _Py_SET_53BIT_PRECISION_HEADER
185 # define _Py_SET_53BIT_PRECISION_HEADER
186 # define _Py_SET_53BIT_PRECISION_START
187 # define _Py_SET_53BIT_PRECISION_END
188 #endif
189
190
191 //--- _PY_SHORT_FLOAT_REPR macro -------------------------------------------
192
193 // If we can't guarantee 53-bit precision, don't use the code
194 // in Python/dtoa.c, but fall back to standard code. This
195 // means that repr of a float will be long (17 significant digits).
196 //
197 // Realistically, there are two things that could go wrong:
198 //
199 // (1) doubles aren't IEEE 754 doubles, or
200 // (2) we're on x86 with the rounding precision set to 64-bits
201 // (extended precision), and we don't know how to change
202 // the rounding precision.
203 #if !defined(DOUBLE_IS_LITTLE_ENDIAN_IEEE754) && \
204 !defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) && \
205 !defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754)
206 # define _PY_SHORT_FLOAT_REPR 0
207 #endif
208
209 // Double rounding is symptomatic of use of extended precision on x86.
210 // If we're seeing double rounding, and we don't have any mechanism available
211 // for changing the FPU rounding precision, then don't use Python/dtoa.c.
212 #if defined(X87_DOUBLE_ROUNDING) && !defined(HAVE_PY_SET_53BIT_PRECISION)
213 # define _PY_SHORT_FLOAT_REPR 0
214 #endif
215
216 #ifndef _PY_SHORT_FLOAT_REPR
217 # define _PY_SHORT_FLOAT_REPR 1
218 #endif
219
220
221 #ifdef __cplusplus
222 }
223 #endif
224 #endif /* !Py_INTERNAL_PYMATH_H */
225