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 */