Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 15 May 2014 15:02:49 +0000 (UTC)
From:      Ian Lepore <ian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r266133 - in stable/10/lib/msun: arm src
Message-ID:  <201405151502.s4FF2nIB038769@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ian
Date: Thu May 15 15:02:48 2014
New Revision: 266133
URL: http://svnweb.freebsd.org/changeset/base/266133

Log:
  MFC r257207, r261161, r261163:
  
    Update the hard-float version of the fenv functions to use the VFP unit.
    Any other floating-point unit is unsupported on ARM.
  
    Use __fenv_static for all static inline functions.
  
    Correctly shift the mask when masking/unmasking exceptions.

Modified:
  stable/10/lib/msun/arm/fenv.h
  stable/10/lib/msun/src/fenv-softfloat.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/lib/msun/arm/fenv.h
==============================================================================
--- stable/10/lib/msun/arm/fenv.h	Thu May 15 14:48:25 2014	(r266132)
+++ stable/10/lib/msun/arm/fenv.h	Thu May 15 15:02:48 2014	(r266133)
@@ -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,21 @@ 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	vmrs_fpscr(__r)	__asm __volatile("vmrs %0, fpscr" : "=&r"(__r))
+#define	vmsr_fpscr(__r)	__asm __volatile("vmsr fpscr, %0" : : "r"(__r))
 
-#define	__rfs(__fpsr)	__asm __volatile("rfs %0" : "=r" (*(__fpsr)))
-#define	__wfs(__fpsr)	__asm __volatile("wfs %0" : : "r" (__fpsr))
+#define _FPU_MASK_SHIFT	8
 
 __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 +116,7 @@ fegetexceptflag(fexcept_t *__flagp, int 
 {
 	fexcept_t __fpsr;
 
-	__rfs(&__fpsr);
+	vmrs_fpscr(__fpsr);
 	*__flagp = __fpsr & __excepts;
 	return (0);
 }
@@ -109,10 +126,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 +147,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 +185,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 +196,7 @@ __fenv_static inline int
 fesetenv(const fenv_t *__envp)
 {
 
-	__wfs(*__envp);
+	vmsr_fpscr(*__envp);
 	return (0);
 }
 
@@ -186,8 +205,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);
 }
@@ -196,40 +215,42 @@ feupdateenv(const fenv_t *__envp)
 
 /* We currently provide no external definitions of the functions below. */
 
-static inline int
+__fenv_static inline int
 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) << _FPU_MASK_SHIFT);
+	vmsr_fpscr(__new_fpsr);
+	return ((__old_fpsr >> _FPU_MASK_SHIFT) & FE_ALL_EXCEPT);
 }
 
-static inline int
+__fenv_static inline int
 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) << _FPU_MASK_SHIFT);
+	vmsr_fpscr(__new_fpsr);
+	return ((__old_fpsr >> _FPU_MASK_SHIFT) & FE_ALL_EXCEPT);
 }
 
-static inline int
+__fenv_static inline int
 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
 

Modified: stable/10/lib/msun/src/fenv-softfloat.h
==============================================================================
--- stable/10/lib/msun/src/fenv-softfloat.h	Thu May 15 14:48:25 2014	(r266132)
+++ stable/10/lib/msun/src/fenv-softfloat.h	Thu May 15 15:02:48 2014	(r266133)
@@ -156,7 +156,7 @@ feupdateenv(const fenv_t *__envp)
 
 /* We currently provide no external definitions of the functions below. */
 
-static inline int
+__fenv_static inline int
 feenableexcept(int __mask)
 {
 	int __omask = __softfloat_float_exception_mask;
@@ -165,7 +165,7 @@ feenableexcept(int __mask)
 	return (__omask);
 }
 
-static inline int
+__fenv_static inline int
 fedisableexcept(int __mask)
 {
 	int __omask = __softfloat_float_exception_mask;
@@ -174,7 +174,7 @@ fedisableexcept(int __mask)
 	return (__omask);
 }
 
-static inline int
+__fenv_static inline int
 fegetexcept(void)
 {
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201405151502.s4FF2nIB038769>