Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/mips/include making this use mips assembly is a goo...



details:   https://anonhg.NetBSD.org/src/rev/26b981cb3566
branches:  trunk
changeset: 350540:26b981cb3566
user:      christos <christos%NetBSD.org@localhost>
date:      Fri Jan 13 19:10:14 2017 +0000

description:
making this use mips assembly is a good start!

diffstat:

 sys/arch/mips/include/fenv.h |  75 ++++++++++++++++++++++++-------------------
 1 files changed, 41 insertions(+), 34 deletions(-)

diffs (147 lines):

diff -r 11079ddb7f09 -r 26b981cb3566 sys/arch/mips/include/fenv.h
--- a/sys/arch/mips/include/fenv.h      Fri Jan 13 18:18:20 2017 +0000
+++ b/sys/arch/mips/include/fenv.h      Fri Jan 13 19:10:14 2017 +0000
@@ -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 <das%FreeBSD.ORG@localhost>
@@ -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 @@
 #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 @@
 __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;
 
-       return (-1);
+       if (__round & ~_ROUND_MASK)
+               return 1;
+       __rfs(&__fpsr);
+       __fpsr &= ~_ROUND_MASK;
+       __fpsr |= __round;
+       __wfs(&__fpsr);
+
+       return 0;
 }
 
 __fenv_static inline int
@@ -188,25 +191,29 @@
 /* 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 @@
        fenv_t __fpsr;
 
        __rfs(&__fpsr);
-       return ((__fpsr & _ENABLE_MASK) >> _FPUSW_SHIFT);
+       return ((__fpsr & _ENABLE_MASK) >> _ENABLE_SHIFT);
 }
 
 #endif /* _NETBSD_SOURCE || _GNU_SOURCE */



Home | Main Index | Thread Index | Old Index