Browse Source

sparc: add fenv support from glibc

Waldemar Brodkorb 3 weeks ago
parent
commit
f3d4659c79

+ 1 - 0
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

+ 37 - 23
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)

+ 16 - 8
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 */

+ 16 - 0
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)

+ 34 - 0
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;
+}

+ 34 - 0
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;
+}

+ 34 - 0
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;
+}

+ 28 - 0
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;
+}

+ 28 - 0
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;
+}

+ 26 - 0
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;
+}

+ 29 - 0
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;
+}

+ 34 - 0
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;
+}

+ 187 - 0
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 */

+ 45 - 0
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;
+}

+ 31 - 0
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;
+}

+ 38 - 0
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;
+}

+ 36 - 0
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;
+}

+ 40 - 0
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;
+}

+ 33 - 0
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;
+}

+ 75 - 0
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 */

+ 81 - 0
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;
+}

+ 36 - 0
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;
+}

+ 29 - 0
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;
+}

+ 36 - 0
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 */