From owner-svn-src-projects@FreeBSD.ORG Sun Sep 8 15:39:25 2013 Return-Path: Delivered-To: svn-src-projects@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 CD09DF75; Sun, 8 Sep 2013 15:39:25 +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 AC2612397; Sun, 8 Sep 2013 15:39:25 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r88FdPoV064519; Sun, 8 Sep 2013 15:39:25 GMT (envelope-from andrew@svn.freebsd.org) Received: (from andrew@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r88FdPw6064517; Sun, 8 Sep 2013 15:39:25 GMT (envelope-from andrew@svn.freebsd.org) Message-Id: <201309081539.r88FdPw6064517@svn.freebsd.org> From: Andrew Turner Date: Sun, 8 Sep 2013 15:39:25 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r255389 - projects/arm_eabi_vfp/lib/msun/arm X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 08 Sep 2013 15:39:26 -0000 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); }