Index: lib/msun/arm/Makefile.inc =================================================================== --- lib/msun/arm/Makefile.inc (revision 260550) +++ lib/msun/arm/Makefile.inc (working copy) @@ -2,3 +2,8 @@ LDBL_PREC = 53 SYM_MAPS += ${.CURDIR}/arm/Symbol.map + +.if ${TARGET_ARCH} == "armv6" +ARCH_SRCS = fenv-softfp.c fenv-vfp.c +.endif + Index: lib/msun/arm/fenv-mangle.h =================================================================== --- lib/msun/arm/fenv-mangle.h (revision 0) +++ lib/msun/arm/fenv-mangle.h (working copy) @@ -0,0 +1,50 @@ +/*- + * Copyright (c) 2013 Andrew Turner + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifdef _FENV_MANGLE_H_ +#error Only include fenv-mangle.h once +#endif + +#define _FENV_MANGLE_H_ + +#ifndef FENV_MANGLE +#error FENV_MANGLE is undefined +#endif + +#define feclearexcept FENV_MANGLE(feclearexcept) +#define fegetexceptflag FENV_MANGLE(fegetexceptflag) +#define fesetexceptflag FENV_MANGLE(fesetexceptflag) +#define feraiseexcept FENV_MANGLE(feraiseexcept) +#define fetestexcept FENV_MANGLE(fetestexcept) +#define fegetround FENV_MANGLE(fegetround) +#define fesetround FENV_MANGLE(fesetround) +#define fegetenv FENV_MANGLE(fegetenv) +#define feholdexcept FENV_MANGLE(feholdexcept) +#define fesetenv FENV_MANGLE(fesetenv) +#define feupdateenv FENV_MANGLE(feupdateenv) + Index: lib/msun/arm/fenv-softfp.c =================================================================== --- lib/msun/arm/fenv-softfp.c (revision 0) +++ lib/msun/arm/fenv-softfp.c (working copy) @@ -0,0 +1,32 @@ +/*- + * Copyright (c) 2013 Andrew Turner + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#define FENV_MANGLE(x) __softfp_ ##x +#include "fenv-mangle.h" +#include "fenv.c" + Index: lib/msun/arm/fenv-vfp.c =================================================================== --- lib/msun/arm/fenv-vfp.c (revision 0) +++ lib/msun/arm/fenv-vfp.c (working copy) @@ -0,0 +1,33 @@ +/*- + * Copyright (c) 2013 Andrew Turner + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#define FENV_MANGLE(x) __vfp_ ##x +#include "fenv-mangle.h" +#define __ARM_PCS_VFP +#include "fenv.c" + Index: lib/msun/arm/fenv.c =================================================================== --- lib/msun/arm/fenv.c (revision 260550) +++ lib/msun/arm/fenv.c (working copy) @@ -1,5 +1,6 @@ /*- * Copyright (c) 2004 David Schultz + * Copyright (c) 2013 Andrew Turner * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,11 +30,30 @@ #define __fenv_static #include "fenv.h" +/* When SOFTFP_ABI is defined we are using the softfp ABI. */ +#if defined(__VFP_FP__) && !defined(__ARM_PCS_VFP) +#define SOFTFP_ABI +#endif + + +#ifndef FENV_MANGLE /* + * Hopefully the system ID byte is immutable, so it's valid to use + * this as a default environment. + */ +const fenv_t __fe_dfl_env = 0; +#endif + + +/* If this is a non-mangled softfp version special processing is required */ +#if defined(FENV_MANGLE) || !defined(SOFTFP_ABI) + +/* * The following macros map between the softfloat emulator's flags and * 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,17 +62,12 @@ & 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" #endif -/* - * Hopefully the system ID byte is immutable, so it's valid to use - * this as a default environment. - */ -const fenv_t __fe_dfl_env = 0; - extern inline int feclearexcept(int __excepts); extern inline int fegetexceptflag(fexcept_t *__flagp, int __excepts); extern inline int fesetexceptflag(const fexcept_t *__flagp, int __excepts); @@ -64,3 +79,189 @@ extern inline int feholdexcept(fenv_t *__envp); extern inline int fesetenv(const fenv_t *__envp); extern inline int feupdateenv(const fenv_t *__envp); + +#else /* !FENV_MANGLE && SOFTFP_ABI */ +/* Set by libc when the VFP unit is enabled */ +extern int _libc_arm_fpu_present; + +int __softfp_feclearexcept(int __excepts); +int __softfp_fegetexceptflag(fexcept_t *__flagp, int __excepts); +int __softfp_fesetexceptflag(const fexcept_t *__flagp, int __excepts); +int __softfp_feraiseexcept(int __excepts); +int __softfp_fetestexcept(int __excepts); +int __softfp_fegetround(void); +int __softfp_fesetround(int __round); +int __softfp_fegetenv(fenv_t *__envp); +int __softfp_feholdexcept(fenv_t *__envp); +int __softfp_fesetenv(const fenv_t *__envp); +int __softfp_feupdateenv(const fenv_t *__envp); + +int __vfp_feclearexcept(int __excepts); +int __vfp_fegetexceptflag(fexcept_t *__flagp, int __excepts); +int __vfp_fesetexceptflag(const fexcept_t *__flagp, int __excepts); +int __vfp_feraiseexcept(int __excepts); +int __vfp_fetestexcept(int __excepts); +int __vfp_fegetround(void); +int __vfp_fesetround(int __round); +int __vfp_fegetenv(fenv_t *__envp); +int __vfp_feholdexcept(fenv_t *__envp); +int __vfp_fesetenv(const fenv_t *__envp); +int __vfp_feupdateenv(const fenv_t *__envp); + +static int +__softfp_round_to_vfp(int round) +{ + + switch (round) { + case FE_TONEAREST: + default: + return VFP_FE_TONEAREST; + case FE_TOWARDZERO: + return VFP_FE_TOWARDZERO; + case FE_UPWARD: + return VFP_FE_UPWARD; + case FE_DOWNWARD: + return VFP_FE_DOWNWARD; + } +} + +static int +__softfp_round_from_vfp(int round) +{ + + switch (round) { + case VFP_FE_TONEAREST: + default: + return FE_TONEAREST; + case VFP_FE_TOWARDZERO: + return FE_TOWARDZERO; + case VFP_FE_UPWARD: + return FE_UPWARD; + case VFP_FE_DOWNWARD: + return FE_DOWNWARD; + } +} + +int feclearexcept(int __excepts) +{ + + if (_libc_arm_fpu_present) + __vfp_feclearexcept(__excepts); + __softfp_feclearexcept(__excepts); + + return (0); +} + +int fegetexceptflag(fexcept_t *__flagp, int __excepts) +{ + fexcept_t __vfp_flagp; + + __vfp_flagp = 0; + if (_libc_arm_fpu_present) + __vfp_fegetexceptflag(&__vfp_flagp, __excepts); + __softfp_fegetexceptflag(__flagp, __excepts); + + *__flagp |= __vfp_flagp; + + return (0); +} + +int fesetexceptflag(const fexcept_t *__flagp, int __excepts) +{ + + if (_libc_arm_fpu_present) + __vfp_fesetexceptflag(__flagp, __excepts); + __softfp_fesetexceptflag(__flagp, __excepts); + + return (0); +} + +int feraiseexcept(int __excepts) +{ + + if (_libc_arm_fpu_present) + __vfp_feraiseexcept(__excepts); + __softfp_feraiseexcept(__excepts); + + return (0); +} + +int fetestexcept(int __excepts) +{ + int __got_excepts; + + __got_excepts = 0; + if (_libc_arm_fpu_present) + __got_excepts = __vfp_fetestexcept(__excepts); + + if (__got_excepts == 0) + __got_excepts = __softfp_fetestexcept(__excepts); + + return (__got_excepts); +} + +int fegetround(void) +{ + + if (_libc_arm_fpu_present) + return __softfp_round_from_vfp(__vfp_fegetround()); + return __softfp_fegetround(); +} + +int fesetround(int __round) +{ + + if (_libc_arm_fpu_present) + __vfp_fesetround(__softfp_round_to_vfp(__round)); + __softfp_fesetround(__round); + + return (0); +} + +int fegetenv(fenv_t *__envp) +{ + fenv_t __vfp_envp; + + __vfp_envp = 0; + if (_libc_arm_fpu_present) + __vfp_fegetenv(&__vfp_envp); + __softfp_fegetenv(__envp); + *__envp |= __vfp_envp; + + return (0); +} + +int feholdexcept(fenv_t *__envp) +{ + fenv_t __vfp_envp; + + __vfp_envp = 0; + if (_libc_arm_fpu_present) + __vfp_feholdexcept(&__vfp_envp); + __softfp_feholdexcept(__envp); + *__envp |= __vfp_envp; + + return (0); +} + +int fesetenv(const fenv_t *__envp) +{ + + if (_libc_arm_fpu_present) + __vfp_fesetenv(__envp); + __softfp_fesetenv(__envp); + + return (0); +} + +int feupdateenv(const fenv_t *__envp) +{ + + if (_libc_arm_fpu_present) + __vfp_feupdateenv(__envp); + __softfp_feupdateenv(__envp); + + return (0); +} +#endif + Index: lib/msun/arm/fenv.h =================================================================== --- lib/msun/arm/fenv.h (revision 260550) +++ lib/msun/arm/fenv.h (working copy) @@ -54,11 +54,16 @@ #endif /* Rounding modes */ +#define VFP_FE_TONEAREST 0x00000000 +#define VFP_FE_UPWARD 0x00400000 +#define VFP_FE_DOWNWARD 0x00800000 +#define VFP_FE_TOWARDZERO 0x00c00000 + #ifdef __ARM_PCS_VFP -#define FE_TONEAREST 0x00000000 -#define FE_UPWARD 0x00400000 -#define FE_DOWNWARD 0x00800000 -#define FE_TOWARDZERO 0x00c00000 +#define FE_TONEAREST VFP_FE_TONEAREST +#define FE_UPWARD VFP_FE_UPWARD +#define FE_DOWNWARD VFP_FE_DOWNWARD +#define FE_TOWARDZERO VFP_FE_TOWARDZERO #else #define FE_TONEAREST 0x0000 #define FE_TOWARDZERO 0x0001 Index: lib/libc/arm/Symbol.map =================================================================== --- lib/libc/arm/Symbol.map (revision 260550) +++ lib/libc/arm/Symbol.map (working copy) @@ -76,4 +76,6 @@ __fixunsdfsi; __extendsfdf2; __truncdfsf2; + + _libc_arm_fpu_present; };