diff options
Diffstat (limited to 'numpy')
-rw-r--r-- | numpy/core/src/npymath/ieee754.cpp | 244 |
1 files changed, 5 insertions, 239 deletions
diff --git a/numpy/core/src/npymath/ieee754.cpp b/numpy/core/src/npymath/ieee754.cpp index 81573d97a..2244004c0 100644 --- a/numpy/core/src/npymath/ieee754.cpp +++ b/numpy/core/src/npymath/ieee754.cpp @@ -646,245 +646,13 @@ npy_get_floatstatus() return npy_get_floatstatus_barrier(&x); } -/* - * Functions to set the floating point status word. - */ - -#if (defined(__unix__) || defined(unix)) && !defined(USG) -#include <sys/param.h> -#endif - -/* - * Define floating point status functions. We must define - * npy_get_floatstatus_barrier, npy_clear_floatstatus_barrier, - * npy_set_floatstatus_{divbyzero, overflow, underflow, invalid} - * for all supported platforms. - */ - -/* Solaris --------------------------------------------------------*/ -/* --------ignoring SunOS ieee_flags approach, someone else can -** deal with that! */ -#if defined(sun) || defined(__BSD__) || defined(__OpenBSD__) || \ - (defined(__FreeBSD__) && (__FreeBSD_version < 502114)) || \ - defined(__NetBSD__) -#include <ieeefp.h> - -extern "C" int -npy_get_floatstatus_barrier(char *param) -{ - int fpstatus = fpgetsticky(); - /* - * By using a volatile, the compiler cannot reorder this call - */ - if (param != NULL) { - volatile char NPY_UNUSED(c) = *(char *)param; - } - return ((FP_X_DZ & fpstatus) ? NPY_FPE_DIVIDEBYZERO : 0) | - ((FP_X_OFL & fpstatus) ? NPY_FPE_OVERFLOW : 0) | - ((FP_X_UFL & fpstatus) ? NPY_FPE_UNDERFLOW : 0) | - ((FP_X_INV & fpstatus) ? NPY_FPE_INVALID : 0); -} - -extern "C" int -npy_clear_floatstatus_barrier(char *param) -{ - int fpstatus = npy_get_floatstatus_barrier(param); - fpsetsticky(0); - - return fpstatus; -} - -extern "C" void -npy_set_floatstatus_divbyzero(void) -{ - fpsetsticky(FP_X_DZ); -} - -extern "C" void -npy_set_floatstatus_overflow(void) -{ - fpsetsticky(FP_X_OFL); -} - -extern "C" void -npy_set_floatstatus_underflow(void) -{ - fpsetsticky(FP_X_UFL); -} - -extern "C" void -npy_set_floatstatus_invalid(void) -{ - fpsetsticky(FP_X_INV); -} - -#elif defined(_AIX) && !defined(__GNUC__) -#include <cfloat> -#include <fpxcp.h> - -extern "C" int -npy_get_floatstatus_barrier(char *param) -{ - int fpstatus = fp_read_flag(); - /* - * By using a volatile, the compiler cannot reorder this call - */ - if (param != NULL) { - volatile char NPY_UNUSED(c) = *(char *)param; - } - return ((FP_DIV_BY_ZERO & fpstatus) ? NPY_FPE_DIVIDEBYZERO : 0) | - ((FP_OVERFLOW & fpstatus) ? NPY_FPE_OVERFLOW : 0) | - ((FP_UNDERFLOW & fpstatus) ? NPY_FPE_UNDERFLOW : 0) | - ((FP_INVALID & fpstatus) ? NPY_FPE_INVALID : 0); -} - -extern "C" int -npy_clear_floatstatus_barrier(char *param) -{ - int fpstatus = npy_get_floatstatus_barrier(param); - fp_swap_flag(0); - - return fpstatus; -} - -extern "C" void -npy_set_floatstatus_divbyzero(void) -{ - fp_raise_xcp(FP_DIV_BY_ZERO); -} - -extern "C" void -npy_set_floatstatus_overflow(void) -{ - fp_raise_xcp(FP_OVERFLOW); -} - -extern "C" void -npy_set_floatstatus_underflow(void) -{ - fp_raise_xcp(FP_UNDERFLOW); -} - -extern "C" void -npy_set_floatstatus_invalid(void) -{ - fp_raise_xcp(FP_INVALID); -} - -#elif defined(_MSC_VER) || (defined(__osf__) && defined(__alpha)) || \ - defined(__UCLIBC__) || (defined(__arc__) && defined(__GLIBC__)) -/* - * By using a volatile floating point value, - * the compiler is forced to actually do the requested - * operations because of potential concurrency. - * - * We shouldn't write multiple values to a single - * global here, because that would cause - * a race condition. +/* + * General C99 code for floating point error handling. These functions mainly + * exists, because `fenv.h` was not standardized in C89 so they gave better + * portability. This should be unnecessary with C99/C++11 and further + * functionality can be used from `fenv.h` directly. */ -static volatile double _npy_floatstatus_x, - _npy_floatstatus_zero = 0.0, _npy_floatstatus_big = 1e300, - _npy_floatstatus_small = 1e-300, _npy_floatstatus_inf; - -extern "C" void -npy_set_floatstatus_divbyzero(void) -{ - _npy_floatstatus_x = 1.0 / _npy_floatstatus_zero; -} - -extern "C" void -npy_set_floatstatus_overflow(void) -{ - _npy_floatstatus_x = _npy_floatstatus_big * 1e300; -} - -extern "C" void -npy_set_floatstatus_underflow(void) -{ - _npy_floatstatus_x = _npy_floatstatus_small * 1e-300; -} - -extern "C" void -npy_set_floatstatus_invalid(void) -{ - _npy_floatstatus_inf = NPY_INFINITY; - _npy_floatstatus_x = _npy_floatstatus_inf - NPY_INFINITY; -} - -/* MS Windows -----------------------------------------------------*/ -#if defined(_MSC_VER) - -#include <cfloat> - -extern "C" int -npy_get_floatstatus_barrier(char *param) -{ - /* - * By using a volatile, the compiler cannot reorder this call - */ -#if defined(_WIN64) - int fpstatus = _statusfp(); -#else - /* windows enables sse on 32 bit, so check both flags */ - unsigned int fpstatus, fpstatus2; - _statusfp2(&fpstatus, &fpstatus2); - fpstatus |= fpstatus2; -#endif - if (param != NULL) { - volatile char NPY_UNUSED(c) = *(char *)param; - } - return ((SW_ZERODIVIDE & fpstatus) ? NPY_FPE_DIVIDEBYZERO : 0) | - ((SW_OVERFLOW & fpstatus) ? NPY_FPE_OVERFLOW : 0) | - ((SW_UNDERFLOW & fpstatus) ? NPY_FPE_UNDERFLOW : 0) | - ((SW_INVALID & fpstatus) ? NPY_FPE_INVALID : 0); -} - -extern "C" int -npy_clear_floatstatus_barrier(char *param) -{ - int fpstatus = npy_get_floatstatus_barrier(param); - _clearfp(); - - return fpstatus; -} - -/* OSF/Alpha (Tru64) ---------------------------------------------*/ -#elif defined(__osf__) && defined(__alpha) - -#include <machine/fpu.h> - -extern "C" int -npy_get_floatstatus_barrier(char *param) -{ - unsigned long fpstatus = ieee_get_fp_control(); - /* - * By using a volatile, the compiler cannot reorder this call - */ - if (param != NULL) { - volatile char NPY_UNUSED(c) = *(char *)param; - } - return ((IEEE_STATUS_DZE & fpstatus) ? NPY_FPE_DIVIDEBYZERO : 0) | - ((IEEE_STATUS_OVF & fpstatus) ? NPY_FPE_OVERFLOW : 0) | - ((IEEE_STATUS_UNF & fpstatus) ? NPY_FPE_UNDERFLOW : 0) | - ((IEEE_STATUS_INV & fpstatus) ? NPY_FPE_INVALID : 0); -} - -extern "C" int -npy_clear_floatstatus_barrier(char *param) -{ - int fpstatus = npy_get_floatstatus_barrier(param); - /* clear status bits as well as disable exception mode if on */ - ieee_set_fp_control(0); - - return fpstatus; -} - -#endif -/* End of defined(_MSC_VER) || (defined(__osf__) && defined(__alpha)) */ - -#else -/* General GCC code, should work on most platforms */ #include <fenv.h> extern "C" int @@ -940,5 +708,3 @@ npy_set_floatstatus_invalid(void) { feraiseexcept(FE_INVALID); } - -#endif |