pycore_pymath.h 8.4 KB

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