Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/powerpc/include update the FE0/FE1 MSR bits as need...



details:   https://anonhg.NetBSD.org/src/rev/27b382f24db8
branches:  trunk
changeset: 822041:27b382f24db8
user:      chs <chs%NetBSD.org@localhost>
date:      Mon Feb 27 06:54:42 2017 +0000

description:
update the FE0/FE1 MSR bits as needed when changing the exception mask.

diffstat:

 sys/arch/powerpc/include/fenv.h |  44 ++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 43 insertions(+), 1 deletions(-)

diffs (101 lines):

diff -r 0dee6e4ee952 -r 27b382f24db8 sys/arch/powerpc/include/fenv.h
--- a/sys/arch/powerpc/include/fenv.h   Mon Feb 27 06:54:00 2017 +0000
+++ b/sys/arch/powerpc/include/fenv.h   Mon Feb 27 06:54:42 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fenv.h,v 1.1 2015/12/20 16:23:14 christos Exp $        */
+/*     $NetBSD: fenv.h,v 1.2 2017/02/27 06:54:42 chs Exp $     */
 
 /*-
  * Copyright (c) 2004-2005 David Schultz <das%FreeBSD.ORG@localhost>
@@ -92,9 +92,45 @@
 #ifndef _SOFT_FLOAT
 #define        __mffs(__env)   __asm __volatile("mffs %0" : "=f" (*(__env)))
 #define        __mtfsf(__env)  __asm __volatile("mtfsf 255,%0" : : "f" (__env))
+
+static inline uint32_t
+__mfmsr(void)
+{
+       uint32_t __msr;
+
+       __asm volatile ("mfmsr %0" : "=r"(__msr));
+       return __msr;
+}
+
+static inline void
+__mtmsr(uint32_t __msr)
+{
+
+       __asm volatile ("mtmsr %0" : : "r"(__msr));
+}
+
+#define __MSR_FE_MASK  (0x00000800 | 0x00000100)
+#define __MSR_FE_DIS   (0)
+#define __MSR_FE_PREC  (0x00000800 | 0x00000100)
+
+static inline void
+__updatemsr(uint32_t __reg)
+{
+       uint32_t __msr;
+
+       __msr = __mfmsr() & ~__MSR_FE_MASK;
+       if (__reg != 0) {
+               __msr |= __MSR_FE_PREC;
+       } else {
+               __msr |= __MSR_FE_DIS;
+       }
+       __mtmsr(__msr);
+}
+
 #else
 #define        __mffs(__env)
 #define        __mtfsf(__env)
+#define __updatemsr(__reg)
 #endif
 
 union __fpscr {
@@ -201,11 +237,13 @@
 feholdexcept(fenv_t *__envp)
 {
        union __fpscr __r;
+       uint32_t msr;
 
        __mffs(&__r.__d);
        *__envp = __r.__d;
        __r.__bits.__reg &= ~(FE_ALL_EXCEPT | _ENABLE_MASK);
        __mtfsf(__r.__d);
+       __updatemsr(__r.__bits.__reg);
        return (0);
 }
 
@@ -216,6 +254,7 @@
 
        __r.__bits.__reg = *__envp;
        __mtfsf(__r.__d);
+       __updatemsr(__r.__bits.__reg);
        return (0);
 }
 
@@ -228,6 +267,7 @@
        __r.__bits.__reg &= FE_ALL_EXCEPT;
        __r.__bits.__reg |= *__envp;
        __mtfsf(__r.__d);
+       __updatemsr(__r.__bits.__reg);
        return (0);
 }
 
@@ -245,6 +285,7 @@
        __oldmask = __r.__bits.__reg;
        __r.__bits.__reg |= (__mask & FE_ALL_EXCEPT) >> _FPUSW_SHIFT;
        __mtfsf(__r.__d);
+       __updatemsr(__r.__bits.__reg);
        return ((__oldmask & _ENABLE_MASK) << _FPUSW_SHIFT);
 }
 
@@ -258,6 +299,7 @@
        __oldmask = __r.__bits.__reg;
        __r.__bits.__reg &= ~((__mask & FE_ALL_EXCEPT) >> _FPUSW_SHIFT);
        __mtfsf(__r.__d);
+       __updatemsr(__r.__bits.__reg);
        return ((__oldmask & _ENABLE_MASK) << _FPUSW_SHIFT);
 }
 



Home | Main Index | Thread Index | Old Index