diff options
| -rw-r--r-- | extra/Configs/Config.in.arch | 1 | ||||
| -rw-r--r-- | libc/sysdeps/linux/sparc/bits/fenv.h | 60 | ||||
| -rw-r--r-- | libc/sysdeps/linux/sparc/fpu_control.h | 24 | ||||
| -rw-r--r-- | libm/sparc/Makefile.arch | 16 | ||||
| -rw-r--r-- | libm/sparc/fclrexcpt.c | 34 | ||||
| -rw-r--r-- | libm/sparc/fedisblxcpt.c | 34 | ||||
| -rw-r--r-- | libm/sparc/feenablxcpt.c | 34 | ||||
| -rw-r--r-- | libm/sparc/fegetenv.c | 28 | ||||
| -rw-r--r-- | libm/sparc/fegetexcept.c | 28 | ||||
| -rw-r--r-- | libm/sparc/fegetmode.c | 26 | ||||
| -rw-r--r-- | libm/sparc/fegetround.c | 29 | ||||
| -rw-r--r-- | libm/sparc/feholdexcpt.c | 34 | ||||
| -rw-r--r-- | libm/sparc/fenv_private.h | 187 | ||||
| -rw-r--r-- | libm/sparc/fesetenv.c | 45 | ||||
| -rw-r--r-- | libm/sparc/fesetexcept.c | 31 | ||||
| -rw-r--r-- | libm/sparc/fesetmode.c | 38 | ||||
| -rw-r--r-- | libm/sparc/fesetround.c | 36 | ||||
| -rw-r--r-- | libm/sparc/feupdateenv.c | 40 | ||||
| -rw-r--r-- | libm/sparc/fgetexcptflg.c | 33 | ||||
| -rw-r--r-- | libm/sparc/fpu_control.h | 75 | ||||
| -rw-r--r-- | libm/sparc/fraiseexcpt.c | 81 | ||||
| -rw-r--r-- | libm/sparc/fsetexcptflg.c | 36 | ||||
| -rw-r--r-- | libm/sparc/ftestexcept.c | 29 | ||||
| -rw-r--r-- | libm/sparc/math-barriers.h | 36 | 
24 files changed, 984 insertions, 31 deletions
| diff --git a/extra/Configs/Config.in.arch b/extra/Configs/Config.in.arch index cacac7e5e..53734d971 100644 --- a/extra/Configs/Config.in.arch +++ b/extra/Configs/Config.in.arch @@ -174,6 +174,7 @@ config UCLIBC_HAS_FENV  		   (TARGET_powerpc && CONFIG_E500) || \  		   TARGET_riscv32 || \  		   TARGET_riscv64 || \ +		   TARGET_sparc || \  		   TARGET_x86_64  	help  	  If you want the uClibc math library to contain the C99 floating diff --git a/libc/sysdeps/linux/sparc/bits/fenv.h b/libc/sysdeps/linux/sparc/bits/fenv.h index 79ab8cefa..83b32cc51 100644 --- a/libc/sysdeps/linux/sparc/bits/fenv.h +++ b/libc/sysdeps/linux/sparc/bits/fenv.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. +/* Copyright (C) 1997-2025 Free Software Foundation, Inc.     The GNU C Library is free software; you can redistribute it and/or     modify it under the terms of the GNU Lesser General Public @@ -12,26 +12,34 @@     You should have received a copy of the GNU Lesser General Public     License along with the GNU C Library; if not, see -   <http://www.gnu.org/licenses/>.  */ +   <https://www.gnu.org/licenses/>.  */  #ifndef _FENV_H  # error "Never use <bits/fenv.h> directly; include <fenv.h> instead."  #endif +#include <bits/wordsize.h> + +  /* Define bits representing the exception.  We use the bit positions     of the appropriate accrued exception bits from the FSR.  */  enum    { -    FE_INVALID = 	(1 << 9), -#define FE_INVALID	FE_INVALID -    FE_OVERFLOW = 	(1 << 8), -#define FE_OVERFLOW	FE_OVERFLOW -    FE_UNDERFLOW = 	(1 << 7), -#define FE_UNDERFLOW	FE_UNDERFLOW -    FE_DIVBYZERO = 	(1 << 6), -#define FE_DIVBYZERO	FE_DIVBYZERO -    FE_INEXACT = 	(1 << 5) -#define FE_INEXACT	FE_INEXACT +    FE_INVALID = +#define FE_INVALID	(1 << 9) +      FE_INVALID, +    FE_OVERFLOW = +#define FE_OVERFLOW	(1 << 8) +      FE_OVERFLOW, +    FE_UNDERFLOW = +#define FE_UNDERFLOW	(1 << 7) +      FE_UNDERFLOW, +    FE_DIVBYZERO = +#define FE_DIVBYZERO	(1 << 6) +      FE_DIVBYZERO, +    FE_INEXACT = +#define FE_INEXACT	(1 << 5) +      FE_INEXACT    };  #define FE_ALL_EXCEPT \ @@ -42,14 +50,18 @@ enum     for the appropriate macros.  */  enum    { -    FE_TONEAREST = 	(0U << 30), -#define FE_TONEAREST	FE_TONEAREST -    FE_TOWARDZERO = 	(1U << 30), -#define FE_TOWARDZERO	FE_TOWARDZERO -    FE_UPWARD = 	(2U << 30), -#define FE_UPWARD	FE_UPWARD -    FE_DOWNWARD = 	(3U << 30) -#define FE_DOWNWARD	FE_DOWNWARD +    FE_TONEAREST = +#define FE_TONEAREST	(0 << 30) +      FE_TONEAREST, +    FE_TOWARDZERO = +#define FE_TOWARDZERO	(1 << 30) +      FE_TOWARDZERO, +    FE_UPWARD = +#define FE_UPWARD	(-0x7fffffff - 1) /* (2 << 30) */ +      FE_UPWARD, +    FE_DOWNWARD = +#define FE_DOWNWARD	(-0x40000000) /* (3 << 30) */ +      FE_DOWNWARD    };  #define __FE_ROUND_MASK	(3U << 30) @@ -70,6 +82,8 @@ typedef unsigned long int fenv_t;  # define FE_NOMASK_ENV	((const fenv_t *) -2)  #endif -/* For internal use only: access the fp state register.  */ -#define __fenv_stfsr(X)   __asm__ ("st %%fsr,%0" : "=m" (X)) -#define __fenv_ldfsr(X)   __asm__ __volatile__ ("ld %0,%%fsr" : : "m" (X)) +/* Type representing floating-point control modes.  */ +typedef unsigned long int femode_t; + +/* Default floating-point control modes.  */ +# define FE_DFL_MODE	((const femode_t *) -1L) diff --git a/libc/sysdeps/linux/sparc/fpu_control.h b/libc/sysdeps/linux/sparc/fpu_control.h index 57f1dbb67..542f9fb1b 100644 --- a/libc/sysdeps/linux/sparc/fpu_control.h +++ b/libc/sysdeps/linux/sparc/fpu_control.h @@ -1,6 +1,5 @@  /* FPU control word bits.  SPARC version. -   Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. -   Contributed by Miguel de Icaza +   Copyright (C) 1997-2025 Free Software Foundation, Inc.     The GNU C Library is free software; you can redistribute it and/or     modify it under the terms of the GNU Lesser General Public @@ -14,13 +13,14 @@     You should have received a copy of the GNU Lesser General Public     License along with the GNU C Library; if not, see -   <http://www.gnu.org/licenses/>.  */ +   <https://www.gnu.org/licenses/>.  */  #ifndef _FPU_CONTROL_H  #define _FPU_CONTROL_H	1  #include <features.h> +#include <bits/wordsize.h>  /* masking of interrupts */  #define _FPU_MASK_IM  0x08000000 @@ -41,7 +41,7 @@  #define _FPU_RC_ZERO    0x40000000  #define _FPU_RC_NEAREST 0x0        /* RECOMMENDED */ -#define _FPU_RESERVED   0x30300000  /* Reserved bits in cw */ +#define _FPU_RESERVED   0x303e0000  /* Reserved bits in cw */  /* Now two recommended cw */ @@ -56,12 +56,20 @@  /* Type of the control word.  */  typedef unsigned long int fpu_control_t; -#define _FPU_GETCW(cw) __asm__ ("st %%fsr,%0" : "=m" (*&cw)) -#define _FPU_SETCW(cw) __asm__ ("ld %0,%%fsr" : : "m" (*&cw)) +#if __WORDSIZE == 64 +# define _FPU_GETCW(cw) __asm__ __volatile__ ("stx %%fsr,%0" : "=m" (*&cw)) +# define _FPU_SETCW(cw) __asm__ __volatile__ ("ldx %0,%%fsr" : : "m" (*&cw)) +#else +# ifdef __leon__ +   /* Prevent stfsr from being placed directly after other fp instruction.  */ +#  define _FPU_GETCW(cw) __asm__ __volatile__ ("nop; st %%fsr,%0" : "=m" (*&cw)) +# else +#  define _FPU_GETCW(cw) __asm__ __volatile__ ("st %%fsr,%0" : "=m" (*&cw)) +# endif +# define _FPU_SETCW(cw) __asm__ __volatile__ ("ld %0,%%fsr" : : "m" (*&cw)) +#endif -#if 0  /* Default control word set at startup.  */  extern fpu_control_t __fpu_control; -#endif  #endif	/* fpu_control.h */ diff --git a/libm/sparc/Makefile.arch b/libm/sparc/Makefile.arch new file mode 100644 index 000000000..bd38690be --- /dev/null +++ b/libm/sparc/Makefile.arch @@ -0,0 +1,16 @@ +# Makefile for uClibc-ng +# Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball. + +ifeq ($(UCLIBC_HAS_FENV),y) +libm_ARCH_SRC:=$(wildcard $(libm_ARCH_DIR)/*.c) +libm_ARCH_OBJ:=$(patsubst $(libm_ARCH_DIR)/%.c,$(libm_ARCH_OUT)/%.o,$(libm_ARCH_SRC)) +endif + +libm_ARCH_OBJS:=$(libm_ARCH_OBJ) + +ifeq ($(DOPIC),y) +libm-a-y+=$(libm_ARCH_OBJS:.o=.os) +else +libm-a-y+=$(libm_ARCH_OBJS) +endif +libm-so-y+=$(libm_ARCH_OBJS:.o=.os) diff --git a/libm/sparc/fclrexcpt.c b/libm/sparc/fclrexcpt.c new file mode 100644 index 000000000..ae344658d --- /dev/null +++ b/libm/sparc/fclrexcpt.c @@ -0,0 +1,34 @@ +/* Clear given exceptions in current floating-point environment. +   Copyright (C) 1997-2025 Free Software Foundation, Inc. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, see +   <https://www.gnu.org/licenses/>.  */ + +#include <fenv.h> +#include "fenv_private.h" + +int +feclearexcept (int excepts) +{ +  fenv_t tmp; + +  __fenv_stfsr (tmp); + +  tmp &= ~(excepts & FE_ALL_EXCEPT); + +  __fenv_ldfsr (tmp); + +  /* Success.  */ +  return 0; +} diff --git a/libm/sparc/fedisblxcpt.c b/libm/sparc/fedisblxcpt.c new file mode 100644 index 000000000..9bc546f2d --- /dev/null +++ b/libm/sparc/fedisblxcpt.c @@ -0,0 +1,34 @@ +/* Disable floating-point exceptions. +   Copyright (C) 2000-2025 Free Software Foundation, Inc. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, see +   <https://www.gnu.org/licenses/>.  */ + +#include <fenv.h> +#include "fenv_private.h" + +int +fedisableexcept (int excepts) +{ +  fenv_t new_exc, old_exc; + +  __fenv_stfsr (new_exc); + +  old_exc = (new_exc >> 18) & FE_ALL_EXCEPT; +  new_exc &= ~(((fenv_t)excepts & FE_ALL_EXCEPT) << 18); + +  __fenv_ldfsr (new_exc); + +  return old_exc; +} diff --git a/libm/sparc/feenablxcpt.c b/libm/sparc/feenablxcpt.c new file mode 100644 index 000000000..ab88e7e42 --- /dev/null +++ b/libm/sparc/feenablxcpt.c @@ -0,0 +1,34 @@ +/* Enable floating-point exceptions. +   Copyright (C) 2000-2025 Free Software Foundation, Inc. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, see +   <https://www.gnu.org/licenses/>.  */ + +#include <fenv.h> +#include "fenv_private.h" + +int +feenableexcept (int excepts) +{ +  fenv_t new_exc, old_exc; + +  __fenv_stfsr (new_exc); + +  old_exc = (new_exc >> 18) & FE_ALL_EXCEPT; +  new_exc |= (((fenv_t)excepts & FE_ALL_EXCEPT) << 18); + +  __fenv_ldfsr (new_exc); + +  return old_exc; +} diff --git a/libm/sparc/fegetenv.c b/libm/sparc/fegetenv.c new file mode 100644 index 000000000..883012932 --- /dev/null +++ b/libm/sparc/fegetenv.c @@ -0,0 +1,28 @@ +/* Store current floating-point environment. +   Copyright (C) 1997-2025 Free Software Foundation, Inc. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, see +   <https://www.gnu.org/licenses/>.  */ + +#include <fenv.h> +#include "fenv_private.h" + +int +fegetenv (fenv_t *envp) +{ +  __fenv_stfsr (*envp); + +  /* Success.  */ +  return 0; +} diff --git a/libm/sparc/fegetexcept.c b/libm/sparc/fegetexcept.c new file mode 100644 index 000000000..53dfdab8c --- /dev/null +++ b/libm/sparc/fegetexcept.c @@ -0,0 +1,28 @@ +/* Get enabled floating-point exceptions. +   Copyright (C) 2000-2025 Free Software Foundation, Inc. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, see +   <https://www.gnu.org/licenses/>.  */ + +#include <fenv.h> +#include "fenv_private.h" + +int +fegetexcept (void) +{ +  fenv_t exc; +  __fenv_stfsr (exc); + +  return (exc >> 18) & FE_ALL_EXCEPT; +} diff --git a/libm/sparc/fegetmode.c b/libm/sparc/fegetmode.c new file mode 100644 index 000000000..0bb9ba111 --- /dev/null +++ b/libm/sparc/fegetmode.c @@ -0,0 +1,26 @@ +/* Store current floating-point control modes.  SPARC version. +   Copyright (C) 2016-2025 Free Software Foundation, Inc. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, see +   <https://www.gnu.org/licenses/>.  */ + +#include <fenv.h> +#include "fenv_private.h" + +int +fegetmode (femode_t *modep) +{ +  __fenv_stfsr (*modep); +  return 0; +} diff --git a/libm/sparc/fegetround.c b/libm/sparc/fegetround.c new file mode 100644 index 000000000..bb53a735e --- /dev/null +++ b/libm/sparc/fegetround.c @@ -0,0 +1,29 @@ +/* Return current rounding direction. +   Copyright (C) 1997-2025 Free Software Foundation, Inc. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, see +   <https://www.gnu.org/licenses/>.  */ + +#include <fenv.h> +#include "fenv_private.h" + +int +fegetround (void) +{ +  fenv_t tmp; + +  __fenv_stfsr (tmp); + +  return tmp & __FE_ROUND_MASK; +} diff --git a/libm/sparc/feholdexcpt.c b/libm/sparc/feholdexcpt.c new file mode 100644 index 000000000..7d712198b --- /dev/null +++ b/libm/sparc/feholdexcpt.c @@ -0,0 +1,34 @@ +/* Store current floating-point environment and clear exceptions. +   Copyright (C) 1997-2025 Free Software Foundation, Inc. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, see +   <https://www.gnu.org/licenses/>.  */ + +#include <fenv.h> +#include "fenv_private.h" + +int +feholdexcept (fenv_t *envp) +{ +  fenv_t tmp; + +  __fenv_stfsr (*envp); + +  /* Set all exceptions to non-stop and clear all exceptions.  */ +  tmp = *envp & ~((0x1f << 23) | FE_ALL_EXCEPT); + +  __fenv_ldfsr (tmp); + +  return 0; +} diff --git a/libm/sparc/fenv_private.h b/libm/sparc/fenv_private.h new file mode 100644 index 000000000..b888d8442 --- /dev/null +++ b/libm/sparc/fenv_private.h @@ -0,0 +1,187 @@ +#ifndef SPARC_FENV_PRIVATE_H +#define SPARC_FENV_PRIVATE_H 1 + +#include <fenv.h> +#include <fpu_control.h> + +/* For internal use only: access the fp state register.  */ +#define __fenv_stfsr(X)   _FPU_GETCW (X) +#define __fenv_ldfsr(X)   _FPU_SETCW (X) + +static __always_inline void +libc_feholdexcept (fenv_t *e) +{ +  fenv_t etmp; +  __fenv_stfsr(etmp); +  *(e) = etmp; +  etmp = etmp & ~((0x1f << 23) | FE_ALL_EXCEPT); +  __fenv_ldfsr(etmp); +} + +static __always_inline void +libc_fesetround (int r) +{ +  fenv_t etmp; +  __fenv_stfsr(etmp); +  etmp = (etmp & ~__FE_ROUND_MASK) | (r); +  __fenv_ldfsr(etmp); +} + +static __always_inline void +libc_feholdexcept_setround (fenv_t *e, int r) +{ +  fenv_t etmp; +  __fenv_stfsr(etmp); +  *(e) = etmp; +  etmp = etmp & ~((0x1f << 23) | FE_ALL_EXCEPT); +  etmp = (etmp & ~__FE_ROUND_MASK) | (r); +  __fenv_ldfsr(etmp); +} + +static __always_inline int +libc_fetestexcept (int e) +{ +  fenv_t etmp; +  __fenv_stfsr(etmp); +  return etmp & (e) & FE_ALL_EXCEPT; +} + +static __always_inline void +libc_fesetenv (fenv_t *e) +{ +  __fenv_ldfsr(*e); +} + +static __always_inline int +libc_feupdateenv_test (fenv_t *e, int ex) +{ +  fenv_t etmp; + +  __fenv_stfsr(etmp); +  etmp &= FE_ALL_EXCEPT; + +  __fenv_ldfsr(*e); + +  feraiseexcept (etmp); + +  return etmp & ex; +} + +static __always_inline void +libc_feupdateenv (fenv_t *e) +{ +  libc_feupdateenv_test (e, 0); +} + +static __always_inline void +libc_feholdsetround (fenv_t *e, int r) +{ +  fenv_t etmp; +  __fenv_stfsr(etmp); +  *(e) = etmp; +  etmp = (etmp & ~__FE_ROUND_MASK) | (r); +  __fenv_ldfsr(etmp); +} + +static __always_inline void +libc_feresetround (fenv_t *e) +{ +  fenv_t etmp; +  __fenv_stfsr(etmp); +  etmp = (etmp & ~__FE_ROUND_MASK) | (*e & __FE_ROUND_MASK); +  __fenv_ldfsr(etmp); +} + +#define libc_feholdexceptf		libc_feholdexcept +#define libc_fesetroundf		libc_fesetround +#define libc_feholdexcept_setroundf	libc_feholdexcept_setround +#define libc_fetestexceptf		libc_fetestexcept +#define libc_fesetenvf			libc_fesetenv +#define libc_feupdateenv_testf		libc_feupdateenv_test +#define libc_feupdateenvf		libc_feupdateenv +#define libc_feholdsetroundf		libc_feholdsetround +#define libc_feresetroundf		libc_feresetround +#define libc_feholdexcept		libc_feholdexcept +#define libc_fesetround			libc_fesetround +#define libc_feholdexcept_setround	libc_feholdexcept_setround +#define libc_fetestexcept		libc_fetestexcept +#define libc_fesetenv			libc_fesetenv +#define libc_feupdateenv_test		libc_feupdateenv_test +#define libc_feupdateenv		libc_feupdateenv +#define libc_feholdsetround		libc_feholdsetround +#define libc_feresetround		libc_feresetround +#define libc_feholdexceptl		libc_feholdexcept +#define libc_fesetroundl		libc_fesetround +#define libc_feholdexcept_setroundl	libc_feholdexcept_setround +#define libc_fetestexceptl		libc_fetestexcept +#define libc_fesetenvl			libc_fesetenv +#define libc_feupdateenv_testl		libc_feupdateenv_test +#define libc_feupdateenvl		libc_feupdateenv +#define libc_feholdsetroundl		libc_feholdsetround +#define libc_feresetroundl		libc_feresetround + +/* We have support for rounding mode context.  */ +#define HAVE_RM_CTX 1 + +static __always_inline void +libc_feholdexcept_setround_sparc_ctx (struct rm_ctx *ctx, int round) +{ +  fenv_t new; + +  __fenv_stfsr(ctx->env); +  new = ctx->env & ~((0x1f << 23) | FE_ALL_EXCEPT); +  new = (new & ~__FE_ROUND_MASK) | round; +  if (unlikely (new != ctx->env)) +    { +      __fenv_ldfsr(new); +      ctx->updated_status = true; +    } +  else +    ctx->updated_status = false; +} + +static __always_inline void +libc_fesetenv_sparc_ctx (struct rm_ctx *ctx) +{ +  libc_fesetenv(&ctx->env); +} + +static __always_inline void +libc_feupdateenv_sparc_ctx (struct rm_ctx *ctx) +{ +  if (unlikely (ctx->updated_status)) +    libc_feupdateenv_test (&ctx->env, 0); +} + +static __always_inline void +libc_feholdsetround_sparc_ctx (struct rm_ctx *ctx, int round) +{ +  fenv_t new; + +  __fenv_stfsr(ctx->env); +  new = (ctx->env & ~__FE_ROUND_MASK) | round; +  if (unlikely (new != ctx->env)) +    { +      __fenv_ldfsr(new); +      ctx->updated_status = true; +    } +  else +    ctx->updated_status = false; +} +#define libc_feholdexcept_setround_ctx   libc_feholdexcept_setround_sparc_ctx +#define libc_feholdexcept_setroundf_ctx  libc_feholdexcept_setround_sparc_ctx +#define libc_feholdexcept_setroundl_ctx  libc_feholdexcept_setround_sparc_ctx +#define libc_fesetenv_ctx                libc_fesetenv_sparc_ctx +#define libc_fesetenvf_ctx               libc_fesetenv_sparc_ctx +#define libc_fesetenvl_ctx               libc_fesetenv_sparc_ctx +#define libc_feupdateenv_ctx             libc_feupdateenv_sparc_ctx +#define libc_feupdateenvf_ctx            libc_feupdateenv_sparc_ctx +#define libc_feupdateenvl_ctx            libc_feupdateenv_sparc_ctx +#define libc_feresetround_ctx            libc_feupdateenv_sparc_ctx +#define libc_feresetroundf_ctx           libc_feupdateenv_sparc_ctx +#define libc_feresetroundl_ctx           libc_feupdateenv_sparc_ctx +#define libc_feholdsetround_ctx          libc_feholdsetround_sparc_ctx +#define libc_feholdsetroundf_ctx         libc_feholdsetround_sparc_ctx +#define libc_feholdsetroundl_ctx         libc_feholdsetround_sparc_ctx + +#endif /* SPARC_FENV_PRIVATE_H */ diff --git a/libm/sparc/fesetenv.c b/libm/sparc/fesetenv.c new file mode 100644 index 000000000..d6f3dc5f5 --- /dev/null +++ b/libm/sparc/fesetenv.c @@ -0,0 +1,45 @@ +/* Install given floating-point environment. +   Copyright (C) 1997-2025 Free Software Foundation, Inc. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, see +   <https://www.gnu.org/licenses/>.  */ + +#include <fenv.h> +#include "fenv_private.h" + +int +fesetenv (const fenv_t *envp) +{ +  fenv_t dummy; + +  /* Put these constants in memory explicitly, so as to cope with a +     -fPIC bug as of gcc 970624.  Making them automatic is quicker +     than loading up the pic register in this instance.  */ + +  if (envp == FE_DFL_ENV) +    { +      dummy = 0; +      envp = &dummy; +    } +  else if (envp == FE_NOMASK_ENV) +    { +      dummy = 0x1f << 23; +      envp = &dummy; +    } + +  __fenv_ldfsr (*envp); + +  /* Success.  */ +  return 0; +} diff --git a/libm/sparc/fesetexcept.c b/libm/sparc/fesetexcept.c new file mode 100644 index 000000000..02210b691 --- /dev/null +++ b/libm/sparc/fesetexcept.c @@ -0,0 +1,31 @@ +/* Set given exception flags.  SPARC version. +   Copyright (C) 2016-2025 Free Software Foundation, Inc. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, see +   <https://www.gnu.org/licenses/>.  */ + +#include <fenv.h> +#include "fenv_private.h" + +int +fesetexcept (int excepts) +{ +  fenv_t tmp; + +  __fenv_stfsr (tmp); +  tmp |= excepts & FE_ALL_EXCEPT; +  __fenv_ldfsr (tmp); + +  return 0; +} diff --git a/libm/sparc/fesetmode.c b/libm/sparc/fesetmode.c new file mode 100644 index 000000000..e72b3d9df --- /dev/null +++ b/libm/sparc/fesetmode.c @@ -0,0 +1,38 @@ +/* Install given floating-point control modes.  SPARC version. +   Copyright (C) 2016-2025 Free Software Foundation, Inc. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, see +   <https://www.gnu.org/licenses/>.  */ + +#include <fenv.h> +#include "fenv_private.h" +#include <fpu_control.h> + +#define FPU_CONTROL_BITS 0xcfc00000UL + +int +fesetmode (const femode_t *modep) +{ +  femode_t fsr; + +  __fenv_stfsr (fsr); +  fsr &= ~FPU_CONTROL_BITS; +  if (modep == FE_DFL_MODE) +    fsr |= _FPU_DEFAULT; +  else +    fsr |= *modep & FPU_CONTROL_BITS; +  __fenv_ldfsr (fsr); + +  return 0; +} diff --git a/libm/sparc/fesetround.c b/libm/sparc/fesetround.c new file mode 100644 index 000000000..ba3a4e50f --- /dev/null +++ b/libm/sparc/fesetround.c @@ -0,0 +1,36 @@ +/* Set current rounding direction. +   Copyright (C) 1997-2025 Free Software Foundation, Inc. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, see +   <https://www.gnu.org/licenses/>.  */ + +#include <fenv.h> +#include "fenv_private.h" + +int +fesetround (int round) +{ +  fenv_t tmp; + +  if ((round & ~__FE_ROUND_MASK) != 0) +    /* ROUND is no valid rounding mode.  */ +    return 1; + +  __fenv_stfsr (tmp); +  tmp &= ~__FE_ROUND_MASK; +  tmp |= round; +  __fenv_ldfsr (tmp); + +  return 0; +} diff --git a/libm/sparc/feupdateenv.c b/libm/sparc/feupdateenv.c new file mode 100644 index 000000000..272536cf3 --- /dev/null +++ b/libm/sparc/feupdateenv.c @@ -0,0 +1,40 @@ +/* Install given floating-point environment and raise exceptions. +   Copyright (C) 1997-2025 Free Software Foundation, Inc. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, see +   <https://www.gnu.org/licenses/>.  */ + +#include <fenv.h> +#include "fenv_private.h" + +int +feupdateenv (const fenv_t *envp) +{ +  fexcept_t tmp; + +  /* Save current exceptions.  */ +  __fenv_stfsr (tmp); +  tmp &= FE_ALL_EXCEPT; + +  /* Install new environment.  */ +  fesetenv (envp); + +  /* Raise the saved exception.  Incidentally for us the implementation +     defined format of the values in objects of type fexcept_t is the +     same as the ones specified using the FE_* constants.  */ +  feraiseexcept ((int) tmp); + +  /* Success.  */ +  return 0; +} diff --git a/libm/sparc/fgetexcptflg.c b/libm/sparc/fgetexcptflg.c new file mode 100644 index 000000000..d8568906e --- /dev/null +++ b/libm/sparc/fgetexcptflg.c @@ -0,0 +1,33 @@ +/* Store current representation for exceptions. +   Copyright (C) 1997-2025 Free Software Foundation, Inc. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, see +   <https://www.gnu.org/licenses/>.  */ + +#include <fenv.h> +#include "fenv_private.h" + +int +fegetexceptflag (fexcept_t *flagp, int excepts) +{ +  fexcept_t tmp; + +  /* Get the current exceptions.  */ +  __fenv_stfsr (tmp); + +  *flagp = tmp & excepts & FE_ALL_EXCEPT; + +  /* Success.  */ +  return 0; +} diff --git a/libm/sparc/fpu_control.h b/libm/sparc/fpu_control.h new file mode 100644 index 000000000..542f9fb1b --- /dev/null +++ b/libm/sparc/fpu_control.h @@ -0,0 +1,75 @@ +/* FPU control word bits.  SPARC version. +   Copyright (C) 1997-2025 Free Software Foundation, Inc. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, see +   <https://www.gnu.org/licenses/>.  */ + +#ifndef _FPU_CONTROL_H +#define _FPU_CONTROL_H	1 + + +#include <features.h> +#include <bits/wordsize.h> + +/* masking of interrupts */ +#define _FPU_MASK_IM  0x08000000 +#define _FPU_MASK_OM  0x04000000 +#define _FPU_MASK_UM  0x02000000 +#define _FPU_MASK_ZM  0x01000000 +#define _FPU_MASK_PM  0x00800000 + +/* precision control */ +#define _FPU_EXTENDED 0x00000000     /* RECOMMENDED */ +#define _FPU_DOUBLE   0x20000000 +#define _FPU_80BIT    0x30000000 +#define _FPU_SINGLE   0x10000000     /* DO NOT USE */ + +/* rounding control / Sparc */ +#define _FPU_RC_DOWN    0xc0000000 +#define _FPU_RC_UP      0x80000000 +#define _FPU_RC_ZERO    0x40000000 +#define _FPU_RC_NEAREST 0x0        /* RECOMMENDED */ + +#define _FPU_RESERVED   0x303e0000  /* Reserved bits in cw */ + + +/* Now two recommended cw */ + +/* Linux and IEEE default: +     - extended precision +     - rounding to nearest +     - no exceptions  */ +#define _FPU_DEFAULT  0x0 +#define _FPU_IEEE     0x0 + +/* Type of the control word.  */ +typedef unsigned long int fpu_control_t; + +#if __WORDSIZE == 64 +# define _FPU_GETCW(cw) __asm__ __volatile__ ("stx %%fsr,%0" : "=m" (*&cw)) +# define _FPU_SETCW(cw) __asm__ __volatile__ ("ldx %0,%%fsr" : : "m" (*&cw)) +#else +# ifdef __leon__ +   /* Prevent stfsr from being placed directly after other fp instruction.  */ +#  define _FPU_GETCW(cw) __asm__ __volatile__ ("nop; st %%fsr,%0" : "=m" (*&cw)) +# else +#  define _FPU_GETCW(cw) __asm__ __volatile__ ("st %%fsr,%0" : "=m" (*&cw)) +# endif +# define _FPU_SETCW(cw) __asm__ __volatile__ ("ld %0,%%fsr" : : "m" (*&cw)) +#endif + +/* Default control word set at startup.  */ +extern fpu_control_t __fpu_control; + +#endif	/* fpu_control.h */ diff --git a/libm/sparc/fraiseexcpt.c b/libm/sparc/fraiseexcpt.c new file mode 100644 index 000000000..72e151fe6 --- /dev/null +++ b/libm/sparc/fraiseexcpt.c @@ -0,0 +1,81 @@ +/* Raise given exceptions. +   Copyright (C) 1997-2025 Free Software Foundation, Inc. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, see +   <https://www.gnu.org/licenses/>.  */ + +#include <fenv.h> +#include <float.h> +#include <math.h> +#include "math-barriers.h" + +int +feraiseexcept (int excepts) +{ +  static const struct { +    double zero, one, max, min, pi; +  } c = { +    0.0, 1.0, DBL_MAX, DBL_MIN, M_PI +  }; +  double d; + +  /* Raise exceptions represented by EXPECTS.  But we must raise only +     one signal at a time.  It is important the if the overflow/underflow +     exception and the inexact exception are given at the same time, +     the overflow/underflow exception follows the inexact exception.  */ + +  /* First: invalid exception.  */ +  if ((FE_INVALID & excepts) != 0) +    { +      /* One example of an invalid operation is 0/0.  */ +      __asm__ ("" : "=e" (d) : "0" (c.zero)); +      d /= c.zero; +      math_force_eval (d); +    } + +  /* Next: division by zero.  */ +  if ((FE_DIVBYZERO & excepts) != 0) +    { +      __asm__ ("" : "=e" (d) : "0" (c.one)); +      d /= c.zero; +      math_force_eval (d); +    } + +  /* Next: overflow.  */ +  if ((FE_OVERFLOW & excepts) != 0) +    { +      __asm__ ("" : "=e" (d) : "0" (c.max)); +      d *= d; +      math_force_eval (d); +    } + +  /* Next: underflow.  */ +  if ((FE_UNDERFLOW & excepts) != 0) +    { +      __asm__ ("" : "=e" (d) : "0" (c.min)); +      d *= d; +      math_force_eval (d); +    } + +  /* Last: inexact.  */ +  if ((FE_INEXACT & excepts) != 0) +    { +      __asm__ ("" : "=e" (d) : "0" (c.one)); +      d /= c.pi; +      math_force_eval (d); +    } + +  /* Success.  */ +  return 0; +} diff --git a/libm/sparc/fsetexcptflg.c b/libm/sparc/fsetexcptflg.c new file mode 100644 index 000000000..4b3b6ae68 --- /dev/null +++ b/libm/sparc/fsetexcptflg.c @@ -0,0 +1,36 @@ +/* Set floating-point environment exception handling. +   Copyright (C) 1997-2025 Free Software Foundation, Inc. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, see +   <https://www.gnu.org/licenses/>.  */ + +#include <fenv.h> +#include "fenv_private.h" +#include <math.h> + +int +fesetexceptflag (const fexcept_t *flagp, int excepts) +{ +  fenv_t tmp; + +  __fenv_stfsr (tmp); + +  tmp &= ~(excepts & FE_ALL_EXCEPT); +  tmp |= *flagp & excepts & FE_ALL_EXCEPT; + +  __fenv_ldfsr (tmp); + +  /* Success.  */ +  return 0; +} diff --git a/libm/sparc/ftestexcept.c b/libm/sparc/ftestexcept.c new file mode 100644 index 000000000..1fe87bb36 --- /dev/null +++ b/libm/sparc/ftestexcept.c @@ -0,0 +1,29 @@ +/* Test exception in current environment. +   Copyright (C) 1997-2025 Free Software Foundation, Inc. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, see +   <https://www.gnu.org/licenses/>.  */ + +#include <fenv.h> +#include "fenv_private.h" + +int +fetestexcept (int excepts) +{ +  fenv_t tmp; + +  __fenv_stfsr (tmp); + +  return tmp & excepts & FE_ALL_EXCEPT; +} diff --git a/libm/sparc/math-barriers.h b/libm/sparc/math-barriers.h new file mode 100644 index 000000000..4b02ff47b --- /dev/null +++ b/libm/sparc/math-barriers.h @@ -0,0 +1,36 @@ +/* Control when floating-point expressions are evaluated.  Generic version. +   Copyright (C) 2007-2025 Free Software Foundation, Inc. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, see +   <https://www.gnu.org/licenses/>.  */ + +#ifndef _MATH_BARRIERS_H +#define _MATH_BARRIERS_H	1 + +/* math_opt_barrier evaluates and returns its floating-point argument +   and ensures that the evaluation of any expression using the result +   of math_opt_barrier is not moved before the call.  math_force_eval +   ensures that its floating-point argument is evaluated for its side +   effects even if its value is apparently unused, and that the +   evaluation of its argument is not moved after the call.  Both these +   macros are used to ensure the correct ordering of floating-point +   expression evaluations with respect to accesses to the +   floating-point environment.  */ + +#define math_opt_barrier(x)					\ +  ({ __typeof (x) __x = (x); __asm ("" : "+m" (__x)); __x; }) +#define math_force_eval(x)						\ +  ({ __typeof (x) __x = (x); __asm __volatile__ ("" : : "m" (__x)); }) + +#endif /* math-barriers.h */ | 
