diff options
author | Eshan dhawan <eshandhawan51@gmail.com> | 2020-07-18 22:52:53 +0300 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2020-07-29 07:58:17 +0300 |
commit | b7a6e02dc6a5289bfa489c0e7b6539abd281e2c6 (patch) | |
tree | 349aea06970fed386d034a47cffb5e38b44d2f3f /newlib/libc/machine | |
parent | 7b1416c3abe890c8058001d6bb795802f80270af (diff) |
arm: Fix fenv support
The previous fenv support for ARM used the soft-float implementation of
FreeBSD. Newlib uses the one from libgcc by default. They are not
compatible. Having an GCC incompatible soft-float fenv support in
Newlib makes no sense. A long-term solution could be to provide a
libgcc compatible soft-float support. This likely requires changes in
the GCC configuration. For now, provide a stub implementation for
soft-float multilibs similar to RISC-V.
Move implementation to one file and delete now unused files. Hide
implementation details. Remove function parameter names from header
file to avoid name conflicts.
Provide VFP support if __SOFTFP__ is not defined like glibc.
Reviewed-by: Sebastian Huber <sebastian.huber@embedded-brains.de>
Signed-off-by: Eshan dhawan <eshandhawan51@gmail.com>
Diffstat (limited to 'newlib/libc/machine')
-rw-r--r-- | newlib/libc/machine/arm/machine/fenv-mangle.h | 53 | ||||
-rw-r--r-- | newlib/libc/machine/arm/machine/fenv-softfloat.h | 187 | ||||
-rw-r--r-- | newlib/libc/machine/arm/machine/fenv-vfp.h | 187 | ||||
-rw-r--r-- | newlib/libc/machine/arm/sys/fenv.h | 66 |
4 files changed, 17 insertions, 476 deletions
diff --git a/newlib/libc/machine/arm/machine/fenv-mangle.h b/newlib/libc/machine/arm/machine/fenv-mangle.h deleted file mode 100644 index 476f7b20c..000000000 --- a/newlib/libc/machine/arm/machine/fenv-mangle.h +++ /dev/null @@ -1,53 +0,0 @@ -/*- - * 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. - * - * $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) -#define feenableexcept FENV_MANGLE(feenableexcept) -#define fedisableexcept FENV_MANGLE(fedisableexcept) -#define fegetexcept FENV_MANGLE(fegetexcept) - diff --git a/newlib/libc/machine/arm/machine/fenv-softfloat.h b/newlib/libc/machine/arm/machine/fenv-softfloat.h deleted file mode 100644 index 5d33e18d0..000000000 --- a/newlib/libc/machine/arm/machine/fenv-softfloat.h +++ /dev/null @@ -1,187 +0,0 @@ - /*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2004-2011 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. - * - * $FreeBSD$ - */ - -#ifndef _SYS_FENV_H_ -#error "This file is meant to be included only by <sys/fenv.h>." -#endif -/* the file can be added from architecture specific fenv.h file found in - *libc/sys/arch/sys * - * - * This file implements the functionality of <fenv.h> on platforms that - * lack an FPU and use softfloat in libc for floating point. To use it, - * you must write an <fenv.h> that provides the following: - * - * - a typedef for fenv_t, which may be an integer or struct type - * - a typedef for fexcept_t (XXX This file assumes fexcept_t is a - * simple integer type containing the exception mask.) - * - definitions of FE_* constants for the five exceptions and four - * rounding modes in IEEE 754, as described in fenv(3) - * - a definition, and the corresponding external symbol, for FE_DFL_ENV - * - a macro __set_env(env, flags, mask, rnd), which sets the given fenv_t - * from the exception flags, mask, and rounding mode - * - macros __env_flags(env), __env_mask(env), and __env_round(env), which - * extract fields from an fenv_t - * - a definition of __fenv_static - * - * If the architecture supports an optional FPU, it's recommended that you - * define fenv_t and fexcept_t to match the hardware ABI. Otherwise, it - * doesn't matter how you define them. - */ -#include <errno.h> - -int __softfloat_float_exception_flags; -int __softfloat_float_exception_mask; -int __softfloat_float_rounding_mode; - - -__fenv_static inline int -feclearexcept(int excepts) -{ - - __softfloat_float_exception_flags &= ~excepts; - return (0); -} - -__fenv_static inline int -fegetexceptflag(fexcept_t *flagp, int excepts) -{ - - *flagp = __softfloat_float_exception_flags & excepts; - return (0); -} - -__fenv_static inline int -fesetexceptflag(const fexcept_t *flagp, int excepts) -{ - - __softfloat_float_exception_flags &= ~excepts; - __softfloat_float_exception_flags |= *flagp & excepts; - return (0); -} - -__fenv_static inline int -feraiseexcept(int excepts) -{ - - return (excepts ? -ENOTSUP : 0); -} - -__fenv_static inline int -fetestexcept(int excepts) -{ - - return (__softfloat_float_exception_flags & excepts); -} - -__fenv_static inline int -fegetround(void) -{ - - return (__softfloat_float_rounding_mode); -} - -__fenv_static inline int -fesetround(int round) -{ - - __softfloat_float_rounding_mode = round; - return (0); -} - -__fenv_static inline int -fegetenv(fenv_t *envp) -{ - - __set_env(*envp, __softfloat_float_exception_flags, - __softfloat_float_exception_mask, __softfloat_float_rounding_mode); - return (0); -} - -__fenv_static inline int -feholdexcept(fenv_t *envp) -{ - fenv_t __env; - - fegetenv(envp); - __softfloat_float_exception_flags = 0; - __softfloat_float_exception_mask = 0; - return (0); -} - -__fenv_static inline int -fesetenv(const fenv_t *envp) -{ - - __softfloat_float_exception_flags = __env_flags(*envp); - __softfloat_float_exception_mask = __env_mask(*envp); - __softfloat_float_rounding_mode = __env_round(*envp); - return (0); -} - -__fenv_static inline int -feupdateenv(const fenv_t *envp) -{ - int __oflags = __softfloat_float_exception_flags; - - fesetenv(envp); - feraiseexcept(__oflags); - return (0); -} - -#if __BSD_VISIBLE - -/* We currently provide no external definitions of the functions below. */ - -__fenv_static inline int -feenableexcept(int __mask) -{ - int __omask = __softfloat_float_exception_mask; - - __softfloat_float_exception_mask |= __mask; - return (__omask); -} - -__fenv_static inline int -fedisableexcept(int __mask) -{ - int __omask = __softfloat_float_exception_mask; - - __softfloat_float_exception_mask &= ~__mask; - return (__omask); -} - -__fenv_static inline int -fegetexcept(void) -{ - - return (__softfloat_float_exception_mask); -} - -#endif /* __BSD_VISIBLE */ diff --git a/newlib/libc/machine/arm/machine/fenv-vfp.h b/newlib/libc/machine/arm/machine/fenv-vfp.h deleted file mode 100644 index 25d71f3ab..000000000 --- a/newlib/libc/machine/arm/machine/fenv-vfp.h +++ /dev/null @@ -1,187 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * 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. - * - * $FreeBSD$ - */ - - - -#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 */ - diff --git a/newlib/libc/machine/arm/sys/fenv.h b/newlib/libc/machine/arm/sys/fenv.h index 740995a1a..70bd57be4 100644 --- a/newlib/libc/machine/arm/sys/fenv.h +++ b/newlib/libc/machine/arm/sys/fenv.h @@ -38,10 +38,6 @@ extern "C" { #endif -#ifndef __fenv_static -#define __fenv_static static -#endif - typedef int fenv_t; typedef int fexcept_t; @@ -51,7 +47,7 @@ typedef int fexcept_t; #define FE_OVERFLOW 0x0004 #define FE_UNDERFLOW 0x0008 #define FE_INEXACT 0x0010 -#ifdef __ARM_PCS_VFP +#ifndef __SOFTFP__ #define FE_DENORMAL 0x0080 #define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | \ FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW | FE_DENORMAL) @@ -60,61 +56,33 @@ typedef int fexcept_t; 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) - +#define FE_TONEAREST 0x00000000 +#define FE_UPWARD 0x00400000 +#define FE_DOWNWARD 0x00800000 +#define FE_TOWARDZERO 0x00c00000 /* 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 - - - -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 feclearexcept(int); +int fegetexceptflag(fexcept_t *, int); +int fesetexceptflag(const fexcept_t *, int); +int feraiseexcept(int); +int fetestexcept(int); 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); +int fesetround(int); +int fegetenv(fenv_t *); +int feholdexcept(fenv_t *); +int fesetenv(const fenv_t *); +int feupdateenv(const fenv_t *); #if __BSD_VISIBLE -int feenableexcept(int __mask); -int fedisableexcept(int __mask); +int feenableexcept(int); +int fedisableexcept(int); int fegetexcept(void); #endif /* __BSD_VISIBLE */ - - #ifdef __cplusplus } #endif |