Date: Sun, 8 Sep 2013 15:39:25 +0000 (UTC) From: Andrew Turner <andrew@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r255389 - projects/arm_eabi_vfp/lib/msun/arm Message-ID: <201309081539.r88FdPw6064517@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: andrew Date: Sun Sep 8 15:39:24 2013 New Revision: 255389 URL: http://svnweb.freebsd.org/changeset/base/255389 Log: Update the floating-point control functions for ARM hard-float. Modified: projects/arm_eabi_vfp/lib/msun/arm/fenv.c projects/arm_eabi_vfp/lib/msun/arm/fenv.h Modified: projects/arm_eabi_vfp/lib/msun/arm/fenv.c ============================================================================== --- projects/arm_eabi_vfp/lib/msun/arm/fenv.c Sun Sep 8 11:35:56 2013 (r255388) +++ projects/arm_eabi_vfp/lib/msun/arm/fenv.c Sun Sep 8 15:39:24 2013 (r255389) @@ -34,6 +34,7 @@ * the hardware's FPSR. The hardware this file was written for doesn't * have rounding control bits, so we stick those in the system ID byte. */ +#ifndef __ARM_PCS_VFP #define __set_env(env, flags, mask, rnd) env = ((flags) \ | (mask)<<_FPUSW_SHIFT \ | (rnd) << 24) @@ -42,6 +43,7 @@ & FE_ALL_EXCEPT) #define __env_round(env) (((env) >> 24) & _ROUND_MASK) #include "fenv-softfloat.h" +#endif #ifdef __GNUC_GNU_INLINE__ #error "This file must be compiled with C99 'inline' semantics" Modified: projects/arm_eabi_vfp/lib/msun/arm/fenv.h ============================================================================== --- projects/arm_eabi_vfp/lib/msun/arm/fenv.h Sun Sep 8 11:35:56 2013 (r255388) +++ projects/arm_eabi_vfp/lib/msun/arm/fenv.h Sun Sep 8 15:39:24 2013 (r255389) @@ -44,14 +44,27 @@ typedef __uint32_t fexcept_t; #define FE_OVERFLOW 0x0004 #define FE_UNDERFLOW 0x0008 #define FE_INEXACT 0x0010 +#ifdef __ARM_PCS_VFP +#define FE_DENORMAL 0x0080 +#define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | \ + FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW | FE_DENORMAL) +#else #define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | \ FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW) +#endif /* Rounding modes */ +#ifdef __ARM_PCS_VFP +#define FE_TONEAREST 0x00000000 +#define FE_UPWARD 0x00400000 +#define FE_DOWNWARD 0x00800000 +#define FE_TOWARDZERO 0x00c00000 +#else #define FE_TONEAREST 0x0000 #define FE_TOWARDZERO 0x0001 #define FE_UPWARD 0x0002 #define FE_DOWNWARD 0x0003 +#endif #define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \ FE_UPWARD | FE_TOWARDZERO) __BEGIN_DECLS @@ -61,10 +74,14 @@ 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 */ +#ifdef __ARM_PCS_VFP +#define _FPUSW_SHIFT 8 +#else #define _FPUSW_SHIFT 16 +#endif #define _ENABLE_MASK (FE_ALL_EXCEPT << _FPUSW_SHIFT) -#ifndef ARM_HARD_FLOAT +#ifndef __ARM_PCS_VFP int feclearexcept(int __excepts); int fegetexceptflag(fexcept_t *__flagp, int __excepts); @@ -78,19 +95,19 @@ int feholdexcept(fenv_t *__envp); int fesetenv(const fenv_t *__envp); int feupdateenv(const fenv_t *__envp); -#else /* ARM_HARD_FLOAT */ +#else /* __ARM_PCS_VFP */ -#define __rfs(__fpsr) __asm __volatile("rfs %0" : "=r" (*(__fpsr))) -#define __wfs(__fpsr) __asm __volatile("wfs %0" : : "r" (__fpsr)) +#define vmrs_fpsr(__r) __asm __volatile("vmrs %0, fpscr" : "=&r"(__r)) +#define vmsr_fpsr(__r) __asm __volatile("vmsr fpscr, %0" : : "r"(__r)) __fenv_static inline int feclearexcept(int __excepts) { fexcept_t __fpsr; - __rfs(&__fpsr); + vmrs_fpsr(__fpsr); __fpsr &= ~__excepts; - __wfs(__fpsr); + vmsr_fpsr(__fpsr); return (0); } @@ -99,7 +116,7 @@ fegetexceptflag(fexcept_t *__flagp, int { fexcept_t __fpsr; - __rfs(&__fpsr); + vmrs_fpsr(__fpsr); *__flagp = __fpsr & __excepts; return (0); } @@ -109,10 +126,10 @@ fesetexceptflag(const fexcept_t *__flagp { fexcept_t __fpsr; - __rfs(&__fpsr); + vmrs_fpsr(__fpsr); __fpsr &= ~__excepts; __fpsr |= *__flagp & __excepts; - __wfs(__fpsr); + vmsr_fpsr(__fpsr); return (0); } @@ -130,34 +147,36 @@ fetestexcept(int __excepts) { fexcept_t __fpsr; - __rfs(&__fpsr); + vmrs_fpsr(__fpsr); return (__fpsr & __excepts); } __fenv_static inline int fegetround(void) { + fenv_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); + vmrs_fpsr(__fpsr); + return (__fpsr & _ROUND_MASK); } __fenv_static inline int fesetround(int __round) { + fenv_t __fpsr; - return (-1); + vmrs_fpsr(__fpsr); + __fpsr &= ~(_ROUND_MASK); + __fpsr |= __round; + vmsr_fpsr(__fpsr); + return (0); } __fenv_static inline int fegetenv(fenv_t *__envp) { - __rfs(__envp); + vmrs_fpsr(*__envp); return (0); } @@ -166,10 +185,10 @@ feholdexcept(fenv_t *__envp) { fenv_t __env; - __rfs(&__env); + vmrs_fpsr(__env); *__envp = __env; __env &= ~(FE_ALL_EXCEPT | _ENABLE_MASK); - __wfs(__env); + vmsr_fpsr(__env); return (0); } @@ -177,7 +196,7 @@ __fenv_static inline int fesetenv(const fenv_t *__envp) { - __wfs(*__envp); + vmsr_fpsr(*__envp); return (0); } @@ -186,8 +205,8 @@ feupdateenv(const fenv_t *__envp) { fexcept_t __fpsr; - __rfs(&__fpsr); - __wfs(*__envp); + vmrs_fpsr(__fpsr); + vmsr_fpsr(*__envp); feraiseexcept(__fpsr & FE_ALL_EXCEPT); return (0); } @@ -201,9 +220,9 @@ feenableexcept(int __mask) { fenv_t __old_fpsr, __new_fpsr; - __rfs(&__old_fpsr); + vmrs_fpsr(__old_fpsr); __new_fpsr = __old_fpsr | (__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT; - __wfs(__new_fpsr); + vmsr_fpsr(__new_fpsr); return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT); } @@ -212,9 +231,9 @@ fedisableexcept(int __mask) { fenv_t __old_fpsr, __new_fpsr; - __rfs(&__old_fpsr); + vmrs_fpsr(__old_fpsr); __new_fpsr = __old_fpsr & ~((__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT); - __wfs(__new_fpsr); + vmsr_fpsr(__new_fpsr); return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT); } @@ -223,7 +242,7 @@ fegetexcept(void) { fenv_t __fpsr; - __rfs(&__fpsr); + vmrs_fpsr(__fpsr); return ((__fpsr & _ENABLE_MASK) >> _FPUSW_SHIFT); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201309081539.r88FdPw6064517>