From owner-svn-src-head@FreeBSD.ORG Sun Oct 27 10:44:23 2013 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id 10BBF2B8; Sun, 27 Oct 2013 10:44:23 +0000 (UTC) (envelope-from andrew@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id E1DBA222E; Sun, 27 Oct 2013 10:44:22 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r9RAiMQd021897; Sun, 27 Oct 2013 10:44:22 GMT (envelope-from andrew@svn.freebsd.org) Received: (from andrew@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r9RAiM9p021896; Sun, 27 Oct 2013 10:44:22 GMT (envelope-from andrew@svn.freebsd.org) Message-Id: <201310271044.r9RAiM9p021896@svn.freebsd.org> From: Andrew Turner Date: Sun, 27 Oct 2013 10:44:22 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r257207 - head/lib/msun/arm X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 27 Oct 2013 10:44:23 -0000 Author: andrew Date: Sun Oct 27 10:44:22 2013 New Revision: 257207 URL: http://svnweb.freebsd.org/changeset/base/257207 Log: Update the hard-float version of the fenv functions to use the VFP unit. Any other floating-point unit is unsupported on ARM. Modified: head/lib/msun/arm/fenv.h Modified: head/lib/msun/arm/fenv.h ============================================================================== --- head/lib/msun/arm/fenv.h Sun Oct 27 10:09:53 2013 (r257206) +++ head/lib/msun/arm/fenv.h Sun Oct 27 10:44:22 2013 (r257207) @@ -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,12 @@ 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 +#ifndef __ARM_PCS_VFP +#define _FPUSW_SHIFT 16 #define _ENABLE_MASK (FE_ALL_EXCEPT << _FPUSW_SHIFT) +#endif -#ifndef ARM_HARD_FLOAT +#ifndef __ARM_PCS_VFP int feclearexcept(int __excepts); int fegetexceptflag(fexcept_t *__flagp, int __excepts); @@ -78,19 +93,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_fpscr(__r) __asm __volatile("vmrs %0, fpscr" : "=&r"(__r)) +#define vmsr_fpscr(__r) __asm __volatile("vmsr fpscr, %0" : : "r"(__r)) __fenv_static inline int feclearexcept(int __excepts) { fexcept_t __fpsr; - __rfs(&__fpsr); + vmrs_fpscr(__fpsr); __fpsr &= ~__excepts; - __wfs(__fpsr); + vmsr_fpscr(__fpsr); return (0); } @@ -99,7 +114,7 @@ fegetexceptflag(fexcept_t *__flagp, int { fexcept_t __fpsr; - __rfs(&__fpsr); + vmrs_fpscr(__fpsr); *__flagp = __fpsr & __excepts; return (0); } @@ -109,10 +124,10 @@ fesetexceptflag(const fexcept_t *__flagp { fexcept_t __fpsr; - __rfs(&__fpsr); + vmrs_fpscr(__fpsr); __fpsr &= ~__excepts; __fpsr |= *__flagp & __excepts; - __wfs(__fpsr); + vmsr_fpscr(__fpsr); return (0); } @@ -130,34 +145,36 @@ fetestexcept(int __excepts) { fexcept_t __fpsr; - __rfs(&__fpsr); + vmrs_fpscr(__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_fpscr(__fpsr); + return (__fpsr & _ROUND_MASK); } __fenv_static inline int fesetround(int __round) { + fenv_t __fpsr; - return (-1); + vmrs_fpscr(__fpsr); + __fpsr &= ~(_ROUND_MASK); + __fpsr |= __round; + vmsr_fpscr(__fpsr); + return (0); } __fenv_static inline int fegetenv(fenv_t *__envp) { - __rfs(__envp); + vmrs_fpscr(*__envp); return (0); } @@ -166,10 +183,10 @@ feholdexcept(fenv_t *__envp) { fenv_t __env; - __rfs(&__env); + vmrs_fpscr(__env); *__envp = __env; - __env &= ~(FE_ALL_EXCEPT | _ENABLE_MASK); - __wfs(__env); + __env &= ~(FE_ALL_EXCEPT); + vmsr_fpscr(__env); return (0); } @@ -177,7 +194,7 @@ __fenv_static inline int fesetenv(const fenv_t *__envp) { - __wfs(*__envp); + vmsr_fpscr(*__envp); return (0); } @@ -186,8 +203,8 @@ feupdateenv(const fenv_t *__envp) { fexcept_t __fpsr; - __rfs(&__fpsr); - __wfs(*__envp); + vmrs_fpscr(__fpsr); + vmsr_fpscr(*__envp); feraiseexcept(__fpsr & FE_ALL_EXCEPT); return (0); } @@ -201,10 +218,10 @@ feenableexcept(int __mask) { fenv_t __old_fpsr, __new_fpsr; - __rfs(&__old_fpsr); - __new_fpsr = __old_fpsr | (__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT; - __wfs(__new_fpsr); - return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT); + vmrs_fpscr(__old_fpsr); + __new_fpsr = __old_fpsr | (__mask & FE_ALL_EXCEPT); + vmsr_fpscr(__new_fpsr); + return (__old_fpsr & FE_ALL_EXCEPT); } static inline int @@ -212,10 +229,10 @@ fedisableexcept(int __mask) { fenv_t __old_fpsr, __new_fpsr; - __rfs(&__old_fpsr); - __new_fpsr = __old_fpsr & ~((__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT); - __wfs(__new_fpsr); - return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT); + vmrs_fpscr(__old_fpsr); + __new_fpsr = __old_fpsr & ~(__mask & FE_ALL_EXCEPT); + vmsr_fpscr(__new_fpsr); + return (__old_fpsr & FE_ALL_EXCEPT); } static inline int @@ -223,13 +240,13 @@ fegetexcept(void) { fenv_t __fpsr; - __rfs(&__fpsr); - return ((__fpsr & _ENABLE_MASK) >> _FPUSW_SHIFT); + vmrs_fpscr(__fpsr); + return (__fpsr & FE_ALL_EXCEPT); } #endif /* __BSD_VISIBLE */ -#endif /* ARM_HARD_FLOAT */ +#endif /* __ARM_PCS_VFP */ __END_DECLS