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); }