Module Name:    src
Committed By:   chs
Date:           Mon Feb 27 06:54:43 UTC 2017

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

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


To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/powerpc/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/powerpc/include/fenv.h
diff -u src/sys/arch/powerpc/include/fenv.h:1.1 src/sys/arch/powerpc/include/fenv.h:1.2
--- src/sys/arch/powerpc/include/fenv.h:1.1	Sun Dec 20 16:23:14 2015
+++ src/sys/arch/powerpc/include/fenv.h	Mon Feb 27 06:54:42 2017
@@ -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 <d...@freebsd.org>
@@ -92,9 +92,45 @@ extern const fenv_t	__fe_dfl_env;
 #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 @@ __fenv_static inline int
 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 @@ fesetenv(const fenv_t *__envp)
 
 	__r.__bits.__reg = *__envp;
 	__mtfsf(__r.__d);
+	__updatemsr(__r.__bits.__reg);
 	return (0);
 }
 
@@ -228,6 +267,7 @@ feupdateenv(const fenv_t *__envp)
 	__r.__bits.__reg &= FE_ALL_EXCEPT;
 	__r.__bits.__reg |= *__envp;
 	__mtfsf(__r.__d);
+	__updatemsr(__r.__bits.__reg);
 	return (0);
 }
 
@@ -245,6 +285,7 @@ feenableexcept(int __mask)
 	__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 @@ fedisableexcept(int __mask)
 	__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);
 }
 

Reply via email to