diff options
Diffstat (limited to 'lib/msun/arm')
-rw-r--r-- | lib/msun/arm/Makefile.inc | 8 | ||||
-rw-r--r-- | lib/msun/arm/Symbol.map | 15 | ||||
-rw-r--r-- | lib/msun/arm/fenv-mangle.h | 51 | ||||
-rw-r--r-- | lib/msun/arm/fenv-softfp.c | 30 | ||||
-rw-r--r-- | lib/msun/arm/fenv-vfp.c | 33 | ||||
-rw-r--r-- | lib/msun/arm/fenv.c | 313 | ||||
-rw-r--r-- | lib/msun/arm/fenv.h | 268 |
7 files changed, 718 insertions, 0 deletions
diff --git a/lib/msun/arm/Makefile.inc b/lib/msun/arm/Makefile.inc new file mode 100644 index 000000000000..6e3ddb351dd3 --- /dev/null +++ b/lib/msun/arm/Makefile.inc @@ -0,0 +1,8 @@ +LDBL_PREC = 53 +SYM_MAPS += ${.CURDIR}/arm/Symbol.map + +.if defined(CPUTYPE) && ${CPUTYPE:M*soft*} != "" +ARCH_SRCS = fenv-softfp.c fenv-vfp.c +.endif + +CFLAGS.fenv-vfp.c= -mfpu=vfp -mfloat-abi=softfp diff --git a/lib/msun/arm/Symbol.map b/lib/msun/arm/Symbol.map new file mode 100644 index 000000000000..2bc6215688bb --- /dev/null +++ b/lib/msun/arm/Symbol.map @@ -0,0 +1,15 @@ +/* + */ +FBSD_1.0 { +}; + +FBSD_1.3 { + fesetexceptflag; + feraiseexcept; + fegetenv; + feholdexcept; + feupdateenv; + feenableexcept; + fedisableexcept; + fegetexcept; +}; diff --git a/lib/msun/arm/fenv-mangle.h b/lib/msun/arm/fenv-mangle.h new file mode 100644 index 000000000000..ad8c022356ab --- /dev/null +++ b/lib/msun/arm/fenv-mangle.h @@ -0,0 +1,51 @@ +/*- + * Copyright (c) 2013 Andrew Turner <andrew@FreeBSD.ORG> + * 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. + */ + +#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) +#define feenableexcept FENV_MANGLE(feenableexcept) +#define fedisableexcept FENV_MANGLE(fedisableexcept) +#define fegetexcept FENV_MANGLE(fegetexcept) + diff --git a/lib/msun/arm/fenv-softfp.c b/lib/msun/arm/fenv-softfp.c new file mode 100644 index 000000000000..89f01815f48e --- /dev/null +++ b/lib/msun/arm/fenv-softfp.c @@ -0,0 +1,30 @@ +/*- + * Copyright (c) 2013 Andrew Turner <andrew@FreeBSD.ORG> + * 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. + */ + +#define FENV_MANGLE(x) __softfp_ ##x +#include "fenv-mangle.h" +#include "fenv.c" + diff --git a/lib/msun/arm/fenv-vfp.c b/lib/msun/arm/fenv-vfp.c new file mode 100644 index 000000000000..c1d888a7fa60 --- /dev/null +++ b/lib/msun/arm/fenv-vfp.c @@ -0,0 +1,33 @@ +/*- + * Copyright (c) 2013 Andrew Turner <andrew@FreeBSD.ORG> + * 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. + */ + +#define FENV_MANGLE(x) __vfp_ ##x +#include "fenv-mangle.h" +#ifndef __ARM_PCS_VFP +#define __ARM_PCS_VFP 1 +#endif +#include "fenv.c" + diff --git a/lib/msun/arm/fenv.c b/lib/msun/arm/fenv.c new file mode 100644 index 000000000000..05b3adb05f81 --- /dev/null +++ b/lib/msun/arm/fenv.c @@ -0,0 +1,313 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG> + * Copyright (c) 2013 Andrew Turner <andrew@FreeBSD.ORG> + * 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. + */ + +#define __fenv_static +#include "fenv.h" + +#include <machine/acle-compat.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) +#define __env_flags(env) ((env) & FE_ALL_EXCEPT) +#define __env_mask(env) (((env) >> _FPUSW_SHIFT) \ + & 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 + +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); +extern inline int feraiseexcept(int __excepts); +extern inline int fetestexcept(int __excepts); +extern inline int fegetround(void); +extern inline int fesetround(int __round); +extern inline int fegetenv(fenv_t *__envp); +extern inline int feholdexcept(fenv_t *__envp); +extern inline int fesetenv(const fenv_t *__envp); +extern inline int feupdateenv(const fenv_t *__envp); +extern inline int feenableexcept(int __mask); +extern inline int fedisableexcept(int __mask); +extern inline int fegetexcept(void); + +#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 __softfp_feenableexcept(int __mask); +int __softfp_fedisableexcept(int __mask); +int __softfp_fegetexcept(void); + +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); +int __vfp_feenableexcept(int __mask); +int __vfp_fedisableexcept(int __mask); +int __vfp_fegetexcept(void); + +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); + __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); +} + +int feenableexcept(int __mask) +{ + int __unmasked; + + __unmasked = 0; + if (_libc_arm_fpu_present) + __unmasked = __vfp_feenableexcept(__mask); + __unmasked |= __softfp_feenableexcept(__mask); + + return (__unmasked); +} + +int fedisableexcept(int __mask) +{ + int __unmasked; + + __unmasked = 0; + if (_libc_arm_fpu_present) + __unmasked = __vfp_fedisableexcept(__mask); + __unmasked |= __softfp_fedisableexcept(__mask); + + return (__unmasked); +} + +int fegetexcept(void) +{ + int __unmasked; + + __unmasked = 0; + if (_libc_arm_fpu_present) + __unmasked = __vfp_fegetexcept(); + __unmasked |= __softfp_fegetexcept(); + + return (__unmasked); +} + +#endif + diff --git a/lib/msun/arm/fenv.h b/lib/msun/arm/fenv.h new file mode 100644 index 000000000000..e8a30fcf496f --- /dev/null +++ b/lib/msun/arm/fenv.h @@ -0,0 +1,268 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG> + * 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. + */ + +#ifndef _FENV_H_ +#define _FENV_H_ + +#include <sys/cdefs.h> +#include <sys/_types.h> + +#ifndef __fenv_static +#define __fenv_static static +#endif + +typedef __uint32_t fenv_t; +typedef __uint32_t fexcept_t; + +/* Exception flags */ +#define FE_INVALID 0x0001 +#define FE_DIVBYZERO 0x0002 +#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 */ +#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 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 +#define FE_UPWARD 0x0002 +#define FE_DOWNWARD 0x0003 +#endif +#define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \ + FE_UPWARD | FE_TOWARDZERO) +__BEGIN_DECLS + +/* Default floating-point environment */ +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 */ +#ifndef __ARM_PCS_VFP +#define _FPUSW_SHIFT 16 +#define _ENABLE_MASK (FE_ALL_EXCEPT << _FPUSW_SHIFT) +#endif + +#ifndef __ARM_PCS_VFP + +int feclearexcept(int __excepts); +int fegetexceptflag(fexcept_t *__flagp, int __excepts); +int fesetexceptflag(const fexcept_t *__flagp, int __excepts); +int feraiseexcept(int __excepts); +int fetestexcept(int __excepts); +int fegetround(void); +int fesetround(int __round); +int fegetenv(fenv_t *__envp); +int feholdexcept(fenv_t *__envp); +int fesetenv(const fenv_t *__envp); +int feupdateenv(const fenv_t *__envp); +#if __BSD_VISIBLE +int feenableexcept(int __mask); +int fedisableexcept(int __mask); +int fegetexcept(void); +#endif + +#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 _FPU_MASK_SHIFT 8 + +__fenv_static inline int +feclearexcept(int __excepts) +{ + fexcept_t __fpsr; + + vmrs_fpscr(__fpsr); + __fpsr &= ~__excepts; + vmsr_fpscr(__fpsr); + return (0); +} + +__fenv_static inline int +fegetexceptflag(fexcept_t *__flagp, int __excepts) +{ + fexcept_t __fpsr; + + vmrs_fpscr(__fpsr); + *__flagp = __fpsr & __excepts; + return (0); +} + +__fenv_static inline int +fesetexceptflag(const fexcept_t *__flagp, int __excepts) +{ + fexcept_t __fpsr; + + vmrs_fpscr(__fpsr); + __fpsr &= ~__excepts; + __fpsr |= *__flagp & __excepts; + vmsr_fpscr(__fpsr); + return (0); +} + +__fenv_static inline int +feraiseexcept(int __excepts) +{ + fexcept_t __ex = __excepts; + + fesetexceptflag(&__ex, __excepts); /* XXX */ + return (0); +} + +__fenv_static inline int +fetestexcept(int __excepts) +{ + fexcept_t __fpsr; + + vmrs_fpscr(__fpsr); + return (__fpsr & __excepts); +} + +__fenv_static inline int +fegetround(void) +{ + fenv_t __fpsr; + + vmrs_fpscr(__fpsr); + return (__fpsr & _ROUND_MASK); +} + +__fenv_static inline int +fesetround(int __round) +{ + fenv_t __fpsr; + + vmrs_fpscr(__fpsr); + __fpsr &= ~(_ROUND_MASK); + __fpsr |= __round; + vmsr_fpscr(__fpsr); + return (0); +} + +__fenv_static inline int +fegetenv(fenv_t *__envp) +{ + + vmrs_fpscr(*__envp); + return (0); +} + +__fenv_static inline int +feholdexcept(fenv_t *__envp) +{ + fenv_t __env; + + vmrs_fpscr(__env); + *__envp = __env; + __env &= ~(FE_ALL_EXCEPT); + vmsr_fpscr(__env); + return (0); +} + +__fenv_static inline int +fesetenv(const fenv_t *__envp) +{ + + vmsr_fpscr(*__envp); + return (0); +} + +__fenv_static inline int +feupdateenv(const fenv_t *__envp) +{ + fexcept_t __fpsr; + + vmrs_fpscr(__fpsr); + vmsr_fpscr(*__envp); + feraiseexcept(__fpsr & FE_ALL_EXCEPT); + return (0); +} + +#if __BSD_VISIBLE + +/* We currently provide no external definitions of the functions below. */ + +__fenv_static inline int +feenableexcept(int __mask) +{ + fenv_t __old_fpsr, __new_fpsr; + + 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); +} + +__fenv_static inline int +fedisableexcept(int __mask) +{ + fenv_t __old_fpsr, __new_fpsr; + + 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); +} + +__fenv_static inline int +fegetexcept(void) +{ + fenv_t __fpsr; + + vmrs_fpscr(__fpsr); + return (__fpsr & FE_ALL_EXCEPT); +} + +#endif /* __BSD_VISIBLE */ + +#endif /* __ARM_PCS_VFP */ + +__END_DECLS + +#endif /* !_FENV_H_ */ |