[Numpy-svn] r6459 - trunk/numpy/core/include/numpy

numpy-svn@scip... numpy-svn@scip...
Mon Feb 23 10:15:31 CST 2009


Author: cdavid
Date: 2009-02-23 10:14:55 -0600 (Mon, 23 Feb 2009)
New Revision: 6459

Added:
   trunk/numpy/core/include/numpy/mingw_amd64_fenv.h
Modified:
   trunk/numpy/core/include/numpy/ufuncobject.h
Log:
Add custom code for FPU error handling on windows x64 with mingw compilers (mingw-w64).

Added: trunk/numpy/core/include/numpy/mingw_amd64_fenv.h
===================================================================
--- trunk/numpy/core/include/numpy/mingw_amd64_fenv.h	2009-02-22 22:36:18 UTC (rev 6458)
+++ trunk/numpy/core/include/numpy/mingw_amd64_fenv.h	2009-02-23 16:14:55 UTC (rev 6459)
@@ -0,0 +1,98 @@
+/*
+ * Those are mostly copies from BSD mlib
+ */
+#include <inttypes.h>
+typedef struct {
+	struct {
+		uint32_t	__control;
+		uint32_t	__status;
+		uint32_t	__tag;
+		char		__other[16];
+	} __x87;
+	uint32_t		__mxcsr;
+} npy_fenv_t;
+
+typedef	uint16_t	npy_fexcept_t;
+
+/* Exception flags */
+#define	NPY_FE_INVALID		0x01
+#define	NPY_FE_DENORMAL		0x02
+#define	NPY_FE_DIVBYZERO	0x04
+#define	NPY_FE_OVERFLOW		0x08
+#define	NPY_FE_UNDERFLOW	0x10
+#define	NPY_FE_INEXACT		0x20
+#define	NPY_FE_ALL_EXCEPT	(NPY_FE_DIVBYZERO | NPY_FE_DENORMAL | \
+				NPY_FE_INEXACT | NPY_FE_INVALID | \
+				NPY_FE_OVERFLOW | NPY_FE_UNDERFLOW)
+
+/* Assembly macros */
+#define	__fldcw(__cw)		__asm __volatile("fldcw %0" : : "m" (__cw))
+#define	__fldenv(__env)		__asm __volatile("fldenv %0" : : "m" (__env))
+#define	__fldenvx(__env)	__asm __volatile("fldenv %0" : : "m" (__env)  \
+				: "st", "st(1)", "st(2)", "st(3)", "st(4)",   \
+				"st(5)", "st(6)", "st(7)")
+#define	__fnclex()		__asm __volatile("fnclex")
+#define	__fnstenv(__env)	__asm __volatile("fnstenv %0" : "=m" (*(__env)))
+#define	__fnstcw(__cw)		__asm __volatile("fnstcw %0" : "=m" (*(__cw)))
+#define	__fnstsw(__sw)		__asm __volatile("fnstsw %0" : "=am" (*(__sw)))
+#define	__fwait()		__asm __volatile("fwait")
+#define	__ldmxcsr(__csr)	__asm __volatile("ldmxcsr %0" : : "m" (__csr))
+#define	__stmxcsr(__csr)	__asm __volatile("stmxcsr %0" : "=m" (*(__csr)))
+
+static __inline int npy_feclearexcept(int __excepts)
+{
+	npy_fenv_t __env;
+
+	if (__excepts == NPY_FE_ALL_EXCEPT) {
+		__fnclex();
+	} else {
+		__fnstenv(&__env.__x87);
+		__env.__x87.__status &= ~__excepts;
+		__fldenv(__env.__x87);
+	}
+	__stmxcsr(&__env.__mxcsr);
+	__env.__mxcsr &= ~__excepts;
+	__ldmxcsr(__env.__mxcsr);
+	return (0);
+}
+
+static __inline int npy_fetestexcept(int __excepts)
+{
+	int __mxcsr, __status;
+
+	__stmxcsr(&__mxcsr);
+	__fnstsw(&__status);
+	return ((__status | __mxcsr) & __excepts);
+}
+
+static __inline int
+npy_fegetexceptflag(npy_fexcept_t *__flagp, int __excepts)
+{
+	int __mxcsr, __status;
+
+	__stmxcsr(&__mxcsr);
+	__fnstsw(&__status);
+	*__flagp = (__mxcsr | __status) & __excepts;
+	return (0);
+}
+
+int npy_feraiseexcept(int excepts)
+{
+	npy_fexcept_t ex = excepts;
+
+	npy_fesetexceptflag(&ex, excepts);
+	__fwait();
+	return (0);
+}
+
+#undef __fldcw
+#undef __fldenv
+#undef __fldenvx
+#undef	__fnclex
+#undef	__fnstenv
+#undef	__fnstcw
+#undef	__fnstsw
+#undef	__fwait
+#undef	__ldmxcsr
+#undef	__stmxcsr
+

Modified: trunk/numpy/core/include/numpy/ufuncobject.h
===================================================================
--- trunk/numpy/core/include/numpy/ufuncobject.h	2009-02-22 22:36:18 UTC (rev 6458)
+++ trunk/numpy/core/include/numpy/ufuncobject.h	2009-02-23 16:14:55 UTC (rev 6459)
@@ -299,6 +299,23 @@
 	(void) fpsetsticky(0);						\
 	}
 
+#elif defined(__MINGW32__) && defined(__amd64__)
+#include "mingw_amd64_fenv.h"
+
+#define UFUNC_CHECK_STATUS(ret) {                                       \
+	int fpstatus = (int) npy_fetestexcept(NPY_FE_DIVBYZERO | 	\
+		NPY_FE_OVERFLOW | NPY_FE_UNDERFLOW | NPY_FE_INVALID);	\
+	ret = ((NPY_FE_DIVBYZERO  & fpstatus) ? UFUNC_FPE_DIVIDEBYZERO : 0) \
+		| ((NPY_FE_OVERFLOW   & fpstatus) ? UFUNC_FPE_OVERFLOW : 0)	\
+		| ((NPY_FE_UNDERFLOW  & fpstatus) ? UFUNC_FPE_UNDERFLOW : 0) \
+		| ((NPY_FE_INVALID    & fpstatus) ? UFUNC_FPE_INVALID : 0);	\
+	(void) npy_feclearexcept(NPY_FE_DIVBYZERO | NPY_FE_OVERFLOW |		\
+			     NPY_FE_UNDERFLOW | NPY_FE_INVALID);		\
+}
+
+#define generate_divbyzero_error() npy_feraiseexcept(NPY_FE_DIVBYZERO)
+#define generate_overflow_error() npy_feraiseexcept(NPY_FE_OVERFLOW)
+
 #elif defined(__GLIBC__) || defined(__APPLE__) || defined(__CYGWIN__) || defined(__MINGW32__) || (defined(__FreeBSD__) && (__FreeBSD_version >= 502114))
 
 #if defined(__GLIBC__) || defined(__APPLE__) || defined(__MINGW32__) || defined(__FreeBSD__)



More information about the Numpy-svn mailing list