Module Name:    src
Committed By:   christos
Date:           Fri Jan 13 19:10:14 UTC 2017

Modified Files:
        src/sys/arch/mips/include: fenv.h

Log Message:
making this use mips assembly is a good start!


To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/mips/include/fenv.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/mips/include/fenv.h
diff -u src/sys/arch/mips/include/fenv.h:1.1 src/sys/arch/mips/include/fenv.h:1.2
--- src/sys/arch/mips/include/fenv.h:1.1	Mon Dec 21 12:02:33 2015
+++ src/sys/arch/mips/include/fenv.h	Fri Jan 13 14:10:14 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: fenv.h,v 1.1 2015/12/21 17:02:33 christos Exp $	*/
+/*	$NetBSD: fenv.h,v 1.2 2017/01/13 19:10:14 christos Exp $	*/
 
 /*-
  * Copyright (c) 2004-2005 David Schultz <d...@freebsd.org>
@@ -37,15 +37,16 @@
 #define	__fenv_static	static
 #endif
 
-typedef	uint32_t	fenv_t;
-typedef	uint32_t	fexcept_t;
+typedef	uint32_t 	fpu_control_t __attribute__((__mode__(__SI__)));
+typedef	fpu_control_t	fenv_t;
+typedef	fpu_control_t	fexcept_t;
 
 /* Exception flags */
-#define	FE_INVALID	0x0001
-#define	FE_DIVBYZERO	0x0002
-#define	FE_OVERFLOW	0x0004
+#define	FE_INEXACT	0x0004
 #define	FE_UNDERFLOW	0x0008
-#define	FE_INEXACT	0x0010
+#define	FE_OVERFLOW	0x0010
+#define	FE_DIVBYZERO	0x0020
+#define	FE_INVALID	0x0040
 #define	FE_ALL_EXCEPT	(FE_DIVBYZERO | FE_INEXACT | \
 			 FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
 
@@ -63,26 +64,23 @@ extern const fenv_t	__fe_dfl_env;
 #define	FE_DFL_ENV	(&__fe_dfl_env)
 
 /* We need to be able to map status flag positions to mask flag positions */
-#define _FPUSW_SHIFT	16
-#define	_ENABLE_MASK	(FE_ALL_EXCEPT << _FPUSW_SHIFT)
+#define	_ENABLE_MASK	(FE_ALL_EXCEPT << _ENABLE_SHIFT)
+#define _ENABLE_SHIFT    5
 
-#ifdef	ARM_HARD_FLOAT
-#define	__rfs(__fpsr)	__asm __volatile("rfs %0" : "=r" (*(__fpsr)))
-#define	__wfs(__fpsr)	__asm __volatile("wfs %0" : : "r" (__fpsr))
-#else
-#define __rfs(__fpsr)
-#define __wfs(__fpsr)
-#endif
+
+#define	__rfs(__fpsr)	__asm __volatile("cfc1 %0,$31" : "=r" ((*__fpsr)))
+#define	__wfs(__fpsr)	__asm __volatile("ctc1 %0,$31" : : "r" (__fpsr))
 
 __fenv_static inline int
 feclearexcept(int __excepts)
 {
 	fexcept_t __fpsr;
 
+	__excepts &= FE_ALL_EXCEPT;
 	__rfs(&__fpsr);
-	__fpsr &= ~__excepts;
+	__fpsr &= ~(__excepts | (__excepts << _ENABLE_SHIFT));
 	__wfs(__fpsr);
-	return (0);
+	return 0;
 }
 
 __fenv_static inline int
@@ -128,20 +126,25 @@ fetestexcept(int __excepts)
 __fenv_static inline int
 fegetround(void)
 {
+	fexcept_t __fpsr;
 
-	/*
-	 * Apparently, the rounding mode is specified as part of the
-	 * instruction format on ARM, so the dynamic rounding mode is
-	 * indeterminate.  Some FPUs may differ.
-	 */
-	return (-1);
+	__rfs(&__fpsr);
+	return __fpsr & _ROUND_MASK;
 }
 
 __fenv_static inline int
 fesetround(int __round)
 {
+	fexcept_t __fpsr;
+
+	if (__round & ~_ROUND_MASK)
+		return 1;
+	__rfs(&__fpsr);
+	__fpsr &= ~_ROUND_MASK;
+	__fpsr |= __round;
+	__wfs(&__fpsr);
 
-	return (-1);
+	return 0;
 }
 
 __fenv_static inline int
@@ -188,25 +191,29 @@ feupdateenv(const fenv_t *__envp)
 /* We currently provide no external definitions of the functions below. */
 
 static inline int
-feenableexcept(int __mask)
+feenableexcept(int __excepts)
 {
 	fenv_t __old_fpsr, __new_fpsr;
 
-	__rfs(&__old_fpsr);
-	__new_fpsr = __old_fpsr | (__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT;
+	__rfs(&__new_fpsr);
+	__old_fpsr = (__new_fpsr & _ENABLE_MASK) >> _ENABLE_SHIFT;
+	__excepts &= FE_ALL_EXCEPT;
+	__new_fpsr |= __excepts << _ENABLE_SHIFT;
 	__wfs(__new_fpsr);
-	return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT);
+	return __old_fpsr;
 }
 
 static inline int
-fedisableexcept(int __mask)
+fedisableexcept(int __excepts)
 {
 	fenv_t __old_fpsr, __new_fpsr;
 
-	__rfs(&__old_fpsr);
-	__new_fpsr = __old_fpsr & ~((__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT);
+	__rfs(&__new_fpsr);
+	__old_fpsr = (__new_fpsr & _ENABLE_MASK) >> _ENABLE_SHIFT;
+	__excepts &= FE_ALL_EXCEPT;
+	__new_fpsr &= ~(__excepts << _ENABLE_SHIFT);
 	__wfs(__new_fpsr);
-	return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT);
+	return __old_fpsr;
 }
 
 static inline int
@@ -215,7 +222,7 @@ fegetexcept(void)
 	fenv_t __fpsr;
 
 	__rfs(&__fpsr);
-	return ((__fpsr & _ENABLE_MASK) >> _FPUSW_SHIFT);
+	return ((__fpsr & _ENABLE_MASK) >> _ENABLE_SHIFT);
 }
 
 #endif /* _NETBSD_SOURCE || _GNU_SOURCE */

Reply via email to