[PATCH 1/2] arm: Fix fenv support

Sebastian Huber <[email protected]>
Newsgroups gmane.comp.lib.newlib
Message-ID <[email protected]>
From: Eshan dhawan <[email protected]>

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 <[email protected]>
Signed-off-by: Eshan dhawan <[email protected]>
---
 newlib/libc/machine/arm/machine/fenv-mangle.h |  53 ---
 .../libc/machine/arm/machine/fenv-softfloat.h | 187 ----------
 newlib/libc/machine/arm/machine/fenv-vfp.h    | 187 ----------
 newlib/libc/machine/arm/sys/fenv.h            |  66 +---
 newlib/libm/machine/arm/Makefile.am           |   4 +-
 newlib/libm/machine/arm/Makefile.in           |  19 +-
 newlib/libm/machine/arm/fenv-softfp.c         |  32 --
 newlib/libm/machine/arm/fenv-vfp.c            |  32 --
 newlib/libm/machine/arm/fenv.c                | 319 ++++++------------
 9 files changed, 127 insertions(+), 772 deletions(-)
 delete mode 100644 newlib/libc/machine/arm/machine/fenv-mangle.h
 delete mode 100644 newlib/libc/machine/arm/machine/fenv-softfloat.h
 delete mode 100644 newlib/libc/machine/arm/machine/fenv-vfp.h
 delete mode 100644 newlib/libm/machine/arm/fenv-softfp.c
 delete mode 100644 newlib/libm/machine/arm/fenv-vfp.c

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 <[email protected]>
- * 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 <[email protected]>
- * 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 <[email protected]>
- * 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
diff --git a/newlib/libm/machine/arm/Makefile.am b/newlib/libm/machine/arm/Makefile.am
index a64ee59d5..180a37f44 100644
--- a/newlib/libm/machine/arm/Makefile.am
+++ b/newlib/libm/machine/arm/Makefile.am
@@ -32,9 +32,7 @@ LIB_SOURCES = \
 	fesetexceptflag.c \
 	fesetround.c \
 	fetestexcept.c \
-	feupdateenv.c \
-	fenv-vfp.c \
-	fenv-softfp.c 
+	feupdateenv.c
 
 
 noinst_LIBRARIES = lib.a
diff --git a/newlib/libm/machine/arm/Makefile.in b/newlib/libm/machine/arm/Makefile.in
index ecfa684e7..aa23dd4d5 100644
--- a/newlib/libm/machine/arm/Makefile.in
+++ b/newlib/libm/machine/arm/Makefile.in
@@ -83,8 +83,7 @@ am__objects_1 = lib_a-e_sqrt.$(OBJEXT) lib_a-ef_sqrt.$(OBJEXT) \
 	lib_a-fenv.$(OBJEXT) lib_a-feraiseexcept.$(OBJEXT) \
 	lib_a-fesetenv.$(OBJEXT) lib_a-fesetexceptflag.$(OBJEXT) \
 	lib_a-fesetround.$(OBJEXT) lib_a-fetestexcept.$(OBJEXT) \
-	lib_a-feupdateenv.$(OBJEXT) lib_a-fenv-vfp.$(OBJEXT) \
-	lib_a-fenv-softfp.$(OBJEXT)
+	lib_a-feupdateenv.$(OBJEXT)
 am_lib_a_OBJECTS = $(am__objects_1)
 lib_a_OBJECTS = $(am_lib_a_OBJECTS)
 DEFAULT_INCLUDES = -I.@am__isrc@
@@ -237,9 +236,7 @@ LIB_SOURCES = \
 	fesetexceptflag.c \
 	fesetround.c \
 	fetestexcept.c \
-	feupdateenv.c \
-	fenv-vfp.c \
-	fenv-softfp.c 
+	feupdateenv.c
 
 noinst_LIBRARIES = lib.a
 lib_a_SOURCES = $(LIB_SOURCES)
@@ -479,18 +476,6 @@ lib_a-feupdateenv.o: feupdateenv.c
 lib_a-feupdateenv.obj: feupdateenv.c
 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-feupdateenv.obj `if test -f 'feupdateenv.c'; then $(CYGPATH_W) 'feupdateenv.c'; else $(CYGPATH_W) '$(srcdir)/feupdateenv.c'; fi`
 
-lib_a-fenv-vfp.o: fenv-vfp.c
-	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fenv-vfp.o `test -f 'fenv-vfp.c' || echo '$(srcdir)/'`fenv-vfp.c
-
-lib_a-fenv-vfp.obj: fenv-vfp.c
-	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fenv-vfp.obj `if test -f 'fenv-vfp.c'; then $(CYGPATH_W) 'fenv-vfp.c'; else $(CYGPATH_W) '$(srcdir)/fenv-vfp.c'; fi`
-
-lib_a-fenv-softfp.o: fenv-softfp.c
-	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fenv-softfp.o `test -f 'fenv-softfp.c' || echo '$(srcdir)/'`fenv-softfp.c
-
-lib_a-fenv-softfp.obj: fenv-softfp.c
-	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fenv-softfp.obj `if test -f 'fenv-softfp.c'; then $(CYGPATH_W) 'fenv-softfp.c'; else $(CYGPATH_W) '$(srcdir)/fenv-softfp.c'; fi`
-
 ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
 	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
 	unique=`for i in $$list; do \
diff --git a/newlib/libm/machine/arm/fenv-softfp.c b/newlib/libm/machine/arm/fenv-softfp.c
deleted file mode 100644
index a576cc1b2..000000000
--- a/newlib/libm/machine/arm/fenv-softfp.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*-
- * Copyright (c) 2013 Andrew Turner <[email protected]>
- * 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 <machine/fenv-mangle.h>
-#include "fenv.c"
-
diff --git a/newlib/libm/machine/arm/fenv-vfp.c b/newlib/libm/machine/arm/fenv-vfp.c
deleted file mode 100644
index 297e81296..000000000
--- a/newlib/libm/machine/arm/fenv-vfp.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*-
- * Copyright (c) 2013 Andrew Turner <[email protected]>
- * 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 <machine/fenv-mangle.h>
-#include "fenv.c"
-
diff --git a/newlib/libm/machine/arm/fenv.c b/newlib/libm/machine/arm/fenv.c
index 5b61ab81f..0735cd1c5 100644
--- a/newlib/libm/machine/arm/fenv.c
+++ b/newlib/libm/machine/arm/fenv.c
@@ -1,7 +1,7 @@
 /*-
  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
  *
- * Copyright (c) 2004 David Schultz <[email protected]>
+ * Copyright (c) 2004-2005 David Schultz <[email protected]>
  * Copyright (c) 2013 Andrew Turner <[email protected]>
  * All rights reserved.
  *
@@ -29,300 +29,195 @@
  * $FreeBSD$
  */
 
-#define	__fenv_static
 #include <fenv.h>
 
-#include <machine/acle-compat.h>
-
-#if __ARM_ARCH >= 6
-#define FENV_ARMv6
-#endif
-
-/* When SOFTFP_ABI is defined we are using the softfp ABI. */
-#if defined(__VFP_FP__) && !defined(__ARM_PCS_VFP)
-#define SOFTFP_ABI
+#ifndef __SOFTFP__
+#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
+#define	_ROUND_MASK	(FE_TONEAREST | FE_DOWNWARD | \
+			 FE_UPWARD | FE_TOWARDZERO)
 #endif
 
-
-#ifndef FENV_MANGLE
-/*
- * Hopefully the system ID byte is immutable, so it's valid to use
- * this as a default environment.
- */
 fenv_t __fe_dfl_env = { 0 };
 
 const fenv_t *_fe_dfl_env = &__fe_dfl_env;
-#endif
-
-
-/* If this is a non-mangled softfp version special processing is required */
-#if defined(FENV_MANGLE) || !defined(SOFTFP_ABI) || !defined(FENV_ARMv6)
-
-/*
- * 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 <machine/fenv-softfloat.h>
-
-#else /* __ARM_PCS_VFP PRESENT */
-
-#include <machine/fenv-vfp.h>
-
-#endif /* __ARM_PCS_VFP */
-
-#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 */
-
-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)
 {
+#ifndef __SOFTFP__
+	fexcept_t __fpsr;
 
-	if (_libc_arm_fpu_present)
-		__vfp_feclearexcept(excepts);
-	__softfp_feclearexcept(excepts);
-
+	vmrs_fpscr(__fpsr);
+	__fpsr &= ~excepts;
+	vmsr_fpscr(__fpsr);
+#endif
 	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;
+#ifndef __SOFTFP__
+	fexcept_t __fpsr;
 
+	vmrs_fpscr(__fpsr);
+	__fpsr &= ~excepts;
+	__fpsr |= *flagp & excepts;
+	vmsr_fpscr(__fpsr);
+#endif
 	return (0);
 }
 
 int fesetexceptflag(const fexcept_t *flagp, int excepts)
 {
+#ifndef __SOFTFP__
+	fexcept_t __fpsr;
 
-	if (_libc_arm_fpu_present)
-		__vfp_fesetexceptflag(flagp, excepts);
-	__softfp_fesetexceptflag(flagp, excepts);
-
+	vmrs_fpscr(__fpsr);
+	__fpsr &= ~excepts;
+	__fpsr |= *flagp & excepts;
+	vmsr_fpscr(__fpsr);
+#endif
 	return (0);
 }
 
 int feraiseexcept(int excepts)
 {
+#ifndef __SOFTFP__
+	fexcept_t __ex = excepts;
 
-	if (_libc_arm_fpu_present)
-		__vfp_feraiseexcept(excepts);
-	__softfp_feraiseexcept(excepts);
-
+	fesetexceptflag(&__ex, excepts);
+#endif
 	return (0);
 }
 
 int fetestexcept(int excepts)
 {
-	int __got_excepts;
+#ifndef __SOFTFP__
+	fexcept_t __fpsr;
 
-	__got_excepts = 0;
-	if (_libc_arm_fpu_present)
-		__got_excepts = __vfp_fetestexcept(excepts);
-	__got_excepts |= __softfp_fetestexcept(excepts);
-
-	return (__got_excepts);
+	vmrs_fpscr(__fpsr);
+	return (__fpsr & excepts);
+#else
+	return (0);
+#endif
 }
 
 int fegetround(void)
 {
+#ifndef __SOFTFP__
+	fenv_t __fpsr;
 
-	if (_libc_arm_fpu_present)
-		return __softfp_round_from_vfp(__vfp_fegetround());
-	return __softfp_fegetround();
+	vmrs_fpscr(__fpsr);
+	return (__fpsr & _ROUND_MASK);
+#else
+#ifdef FE_TONEAREST
+	return (FE_TONEAREST);
+#else
+	return (0);
+#endif
+#endif
 }
 
 int fesetround(int round)
 {
+#ifndef __SOFTFP__
+	fenv_t __fpsr;
 
-	if (_libc_arm_fpu_present)
-		__vfp_fesetround(__softfp_round_to_vfp(round));
-	__softfp_fesetround(round);
-
+	vmrs_fpscr(__fpsr);
+	__fpsr &= ~(_ROUND_MASK);
+	__fpsr |= round;
+	vmsr_fpscr(__fpsr);
+#endif
 	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;
 
+#ifndef __SOFTFP__
+	vmrs_fpscr(*envp);
+#endif
 	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;
+#ifndef __SOFTFP__
+	fenv_t __env;
 
+	vmrs_fpscr(__env);
+	*envp = __env;
+	__env &= ~(FE_ALL_EXCEPT);
+	vmsr_fpscr(__env);
+#endif
 	return (0);
 }
 
 int fesetenv(const fenv_t *envp)
 {
 
-	if (_libc_arm_fpu_present)
-		__vfp_fesetenv(envp);
-	__softfp_fesetenv(envp);
-
+#ifndef __SOFTFP__
+	vmsr_fpscr(*envp);
+#endif
 	return (0);
 }
 
 int feupdateenv(const fenv_t *envp)
 {
+#ifndef __SOFTFP__
+	fexcept_t __fpsr;
 
-	if (_libc_arm_fpu_present)
-		__vfp_feupdateenv(envp);
-	__softfp_feupdateenv(envp);
-
+	vmrs_fpscr(__fpsr);
+	vmsr_fpscr(*envp);
+	feraiseexcept(__fpsr & FE_ALL_EXCEPT);
+#else
+#if defined(FE_NOMASK_ENV) && FE_ALL_EXCEPT != 0
+	if (envp == FE_NOMASK_ENV)
+		return (1);
+#endif
+#endif
 	return (0);
 }
 
 int feenableexcept(int __mask)
 {
-	int __unmasked;
-
-	__unmasked = 0;
-	if (_libc_arm_fpu_present)
-		__unmasked = __vfp_feenableexcept(__mask);
-	__unmasked |= __softfp_feenableexcept(__mask);
+#ifndef __SOFTFP__
+	fenv_t __old_fpsr, __new_fpsr;
 
-	return (__unmasked);
+	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);
+#else
+	return (0);
+#endif
 }
 
 int fedisableexcept(int __mask)
 {
-	int __unmasked;
+#ifndef __SOFTFP__
+	fenv_t __old_fpsr, __new_fpsr;
 
-	__unmasked = 0;
-	if (_libc_arm_fpu_present)
-		__unmasked = __vfp_fedisableexcept(__mask);
-	__unmasked |= __softfp_fedisableexcept(__mask);
-
-	return (__unmasked);
+	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);
+#else
+	return (0);
+#endif
 }
 
 int fegetexcept(void)
 {
-	int __unmasked;
-
-	__unmasked = 0;
-	if (_libc_arm_fpu_present)
-		__unmasked = __vfp_fegetexcept();
-	__unmasked |= __softfp_fegetexcept();
-
-	return (__unmasked);
-}
+#ifndef __SOFTFP__
+	fenv_t __fpsr;
 
+	vmrs_fpscr(__fpsr);
+	return (__fpsr & FE_ALL_EXCEPT);
+#else
+	return (0);
 #endif
-
+}
-- 
2.26.2
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.