Browse Source

sh: add fenv support from glibc

Waldemar Brodkorb 2 weeks ago
parent
commit
d339ad89cb

+ 1 - 0
extra/Configs/Config.in.arch

@@ -175,6 +175,7 @@ config UCLIBC_HAS_FENV
 		   (TARGET_powerpc && CONFIG_E500) || \
 		   TARGET_riscv32 || \
 		   TARGET_riscv64 || \
+		   (TARGET_sh && (CONFIG_SH4 || CONFIG_SH4A)) || \
 		   TARGET_sparc || \
 		   TARGET_x86_64
 	help

+ 35 - 25
libc/sysdeps/linux/sh/bits/fenv.h

@@ -1,5 +1,4 @@
-/* Copyright (C) 1999, 2000 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
+/* Copyright (C) 1999-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
@@ -13,7 +12,7 @@
 
    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."
@@ -24,34 +23,39 @@
    of the appropriate bits in the FPU control word.  */
 enum
   {
-    FE_INEXACT = 0x04,
-#define FE_INEXACT	FE_INEXACT
-    FE_UNDERFLOW = 0x08,
-#define FE_UNDERFLOW	FE_UNDERFLOW
-    FE_OVERFLOW = 0x10,
-#define FE_OVERFLOW	FE_OVERFLOW
-    FE_DIVBYZERO = 0x20,
-#define FE_DIVBYZERO	FE_DIVBYZERO
-    FE_INVALID = 0x40,
-#define FE_INVALID	FE_INVALID
+    FE_INEXACT =
+#define FE_INEXACT	0x04
+      FE_INEXACT,
+    FE_UNDERFLOW =
+#define FE_UNDERFLOW	0x08
+      FE_UNDERFLOW,
+    FE_OVERFLOW =
+#define FE_OVERFLOW	0x10
+      FE_OVERFLOW,
+    FE_DIVBYZERO =
+#define FE_DIVBYZERO	0x20
+      FE_DIVBYZERO,
+    FE_INVALID =
+#define FE_INVALID	0x40
+      FE_INVALID,
   };
 
 #define FE_ALL_EXCEPT \
 	(FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID)
 
-/* The SH FPU supports all of the four defined rounding modes.  We
-   use again the bit positions in the FPU control word as the values
-   for the appropriate macros.  */
+/* The SH FPU supports two of the four defined rounding modes: round to nearest
+   and round to zero.  We use again the bit positions in the FPU control word
+   as the values for the appropriate macros.  */
 enum
   {
-    FE_TONEAREST = 0x0,
-#define FE_TONEAREST	FE_TONEAREST
-    FE_TOWARDZERO = 0x1,
-#define FE_TOWARDZERO	FE_TOWARDZERO
-    FE_UPWARD = 0x2,
-#define FE_UPWARD	FE_UPWARD
-    FE_DOWNWARD = 0x3
-#define FE_DOWNWARD	FE_DOWNWARD
+    __FE_UNDEFINED = -1,
+
+    FE_TONEAREST =
+#define FE_TONEAREST	0x0
+      FE_TONEAREST,
+    FE_TOWARDZERO =
+#define FE_TOWARDZERO	0x1
+      FE_TOWARDZERO,
   };
 
 
@@ -68,4 +72,10 @@ typedef struct
 fenv_t;
 
 /* If the default argument is used we use this value.  */
-#define FE_DFL_ENV	((fenv_t *) -1)
+#define FE_DFL_ENV	((const fenv_t *) -1)
+
+/* Type representing floating-point control modes.  */
+typedef unsigned int femode_t;
+
+/* Default floating-point control modes.  */
+# define FE_DFL_MODE	((const femode_t *) -1L)

+ 21 - 9
libc/sysdeps/linux/sh/fpu_control.h

@@ -1,6 +1,5 @@
 /* FPU control word definitions.  SH version.
-   Copyright (C) 1999, 2000, 2009 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
+   Copyright (C) 1999-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,14 +13,23 @@
 
    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
 
-#ifndef __SH4__
-#error This file is only correct for sh4
-#endif
+#if !defined(__SH_FPU_ANY__)
+
+#define _FPU_RESERVED 0xffffffff
+#define _FPU_DEFAULT  0x00000000
+typedef unsigned int fpu_control_t;
+#define _FPU_GETCW(cw) (cw) = 0
+#define _FPU_SETCW(cw) (void) (cw)
+extern fpu_control_t __fpu_control;
+
+#else
+
+#include <features.h>
 
 /* masking of interrupts */
 #define _FPU_MASK_VM	0x0800	/* Invalid operation */
@@ -48,16 +56,20 @@ typedef unsigned int fpu_control_t;
 #define _FPU_GETCW(cw) __asm__ ("sts fpscr,%0" : "=r" (cw))
 
 #if defined __GNUC__
-/* GCC provides this function */
+__BEGIN_DECLS
+
+/* GCC provides this function.  */
 extern void __set_fpscr (unsigned long);
 #define _FPU_SETCW(cw) __set_fpscr ((cw))
 #else
 #define _FPU_SETCW(cw) __asm__ ("lds %0,fpscr" : : "r" (cw))
 #endif
 
-#if 0
 /* Default control word set at startup.	 */
 extern fpu_control_t __fpu_control;
-#endif
+
+__END_DECLS
+
+#endif /* __SH_FPU_ANY__ */
 
 #endif /* _FPU_CONTROL_H */

+ 1 - 1
libm/sh/sh4/Makefile.arch

@@ -8,7 +8,7 @@
 
 ifeq ($(UCLIBC_HAS_FENV),y)
 libm_ARCH_CSRC:=$(wildcard $(libm_SUBARCH_DIR)/*.c)
-libm_ARCH_COBJ:=$(patsubst $(libm_SUBARCH_DIR)/%.c,$(libm_SUBARCH_OUT)/%.o,$(libm_ARCH_SRC))
+libm_ARCH_COBJ:=$(patsubst $(libm_SUBARCH_DIR)/%.c,$(libm_SUBARCH_OUT)/%.o,$(libm_ARCH_CSRC))
 libm_ARCH_SSRC:=$(wildcard $(libm_SUBARCH_DIR)/*.S)
 libm_ARCH_SOBJ:=$(patsubst $(libm_SUBARCH_DIR)/%.S,$(libm_SUBARCH_OUT)/%.o,$(libm_ARCH_SSRC))
 endif

+ 39 - 0
libm/sh/sh4/fclrexcpt.c

@@ -0,0 +1,39 @@
+/* Clear given exceptions in current floating-point environment.
+   Copyright (C) 1998-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 <fpu_control.h>
+
+int
+feclearexcept (int excepts)
+{
+  fpu_control_t cw;
+
+  /* Mask out unsupported bits/exceptions.  */
+  excepts &= FE_ALL_EXCEPT;
+
+  /* Read the complete control word.  */
+  _FPU_GETCW (cw);
+
+  /* Clear exception bits.  */
+  cw &= ~excepts;
+
+  /* Put the new data in effect.  */
+  _FPU_SETCW (cw);
+
+  return 0;
+}

+ 37 - 0
libm/sh/sh4/fedisblxcpt.c

@@ -0,0 +1,37 @@
+/* Disable floating-point exceptions.
+   Copyright (C) 2012-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 <fpu_control.h>
+
+int
+fedisableexcept (int excepts)
+{
+  fpu_control_t temp, old_exc;
+
+  /* Get the current control register contents.  */
+  _FPU_GETCW (temp);
+
+  old_exc = (temp >> 5) & FE_ALL_EXCEPT;
+
+  excepts &= FE_ALL_EXCEPT;
+
+  temp &= ~(excepts << 5);
+  _FPU_SETCW (temp);
+
+  return old_exc;
+}

+ 36 - 0
libm/sh/sh4/feenablxcpt.c

@@ -0,0 +1,36 @@
+/* Enable floating-point exceptions.
+   Copyright (C) 2012-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 <fpu_control.h>
+
+int
+feenableexcept (int excepts)
+{
+  fpu_control_t temp, old_flag;
+
+  /* Get current exceptions.  */
+  _FPU_GETCW (temp);
+
+  old_flag = (temp >> 5) & FE_ALL_EXCEPT;
+  excepts &= FE_ALL_EXCEPT;
+
+  temp |= excepts << 5;
+  _FPU_SETCW (temp);
+
+  return old_flag;
+}

+ 30 - 0
libm/sh/sh4/fegetenv.c

@@ -0,0 +1,30 @@
+/* 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 <fpu_control.h>
+
+int
+fegetenv (fenv_t *envp)
+{
+  fpu_control_t temp;
+  _FPU_GETCW (temp);
+
+  envp->__fpscr = temp;
+
+  return 0;
+}

+ 30 - 0
libm/sh/sh4/fegetexcept.c

@@ -0,0 +1,30 @@
+/* Get enabled floating-point exceptions.
+   Copyright (C) 2012-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 <fpu_control.h>
+
+int
+fegetexcept (void)
+{
+  fpu_control_t temp;
+
+  /* Get current exceptions.  */
+  _FPU_GETCW (temp);
+
+  return (temp >> 5) & FE_ALL_EXCEPT;
+}

+ 26 - 0
libm/sh/sh4/fegetmode.c

@@ -0,0 +1,26 @@
+/* Store current floating-point control modes.  SH4 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 <fpu_control.h>
+
+int
+fegetmode (femode_t *modep)
+{
+  _FPU_GETCW (*modep);
+  return 0;
+}

+ 30 - 0
libm/sh/sh4/fegetround.c

@@ -0,0 +1,30 @@
+/* Return current rounding direction.
+   Copyright (C) 1998-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 <fpu_control.h>
+
+int
+fegetround (void)
+{
+  fpu_control_t cw;
+
+  /* Get control word.  */
+  _FPU_GETCW (cw);
+
+  return cw & 0x1;
+}

+ 24 - 13
libm/sh/sh4/feholdexcpt.c

@@ -1,13 +1,19 @@
-/*
- *
- * Copyright (c) 2007  STMicroelectronics Ltd
- * Filippo Arcidiacono (filippo.arcidiacono@st.com)
- *
- * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
- *
- * Taken from glibc 2.6
- *
- */
+/* 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 <fpu_control.h>
@@ -15,15 +21,20 @@
 int
 feholdexcept (fenv_t *envp)
 {
-  unsigned long int temp;
+  fpu_control_t temp;
 
   /* Store the environment.  */
   _FPU_GETCW (temp);
   envp->__fpscr = temp;
 
-  /* Now set all exceptions to non-stop.  */
+  /* Clear the status flags.  */
   temp &= ~FE_ALL_EXCEPT;
+
+  /* Now set all exceptions to non-stop.  */
+  temp &= ~(FE_ALL_EXCEPT << 5);
+
   _FPU_SETCW (temp);
 
-  return 1;
+  /* Success.  */
+  return 0;
 }

+ 17 - 11
libm/sh/sh4/fesetenv.c

@@ -1,13 +1,19 @@
-/*
- *
- * Copyright (c) 2007  STMicroelectronics Ltd
- * Filippo Arcidiacono (filippo.arcidiacono@st.com)
- *
- * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
- *
- * Taken from glibc 2.6
- *
- */
+/* 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 <fpu_control.h>
@@ -19,7 +25,7 @@ fesetenv (const fenv_t *envp)
       _FPU_SETCW (_FPU_DEFAULT);
   else
     {
-      unsigned long int temp = envp->__fpscr;
+      fpu_control_t temp = envp->__fpscr;
       _FPU_SETCW (temp);
     }
   return 0;

+ 31 - 0
libm/sh/sh4/fesetexcept.c

@@ -0,0 +1,31 @@
+/* Set given exception flags.  SH4 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 <fpu_control.h>
+
+int
+fesetexcept (int excepts)
+{
+  fpu_control_t temp;
+
+  _FPU_GETCW (temp);
+  temp |= (excepts & FE_ALL_EXCEPT);
+  _FPU_SETCW (temp);
+
+  return 0;
+}

+ 37 - 0
libm/sh/sh4/fesetmode.c

@@ -0,0 +1,37 @@
+/* Install given floating-point control modes.  SH4 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 <fpu_control.h>
+
+#define FPU_STATUS 0x3f07c
+
+int
+fesetmode (const femode_t *modep)
+{
+  fpu_control_t fpscr;
+
+  _FPU_GETCW (fpscr);
+  fpscr &= FPU_STATUS;
+  if (modep == FE_DFL_MODE)
+    fpscr |= _FPU_DEFAULT;
+  else
+    fpscr |= *modep & ~FPU_STATUS;
+  _FPU_SETCW (fpscr);
+
+  return 0;
+}

+ 40 - 0
libm/sh/sh4/fesetround.c

@@ -0,0 +1,40 @@
+/* Set current rounding direction.
+   Copyright (C) 1998-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 <fpu_control.h>
+
+int
+fesetround (int round)
+{
+  fpu_control_t cw;
+
+  if ((round & ~0x1) != 0)
+    /* ROUND is no valid rounding mode.  */
+    return 1;
+
+  /* Get current state.  */
+  _FPU_GETCW (cw);
+
+  /* Set rounding bits.  */
+  cw &= ~0x1;
+  cw |= round;
+  /* Set new state.  */
+  _FPU_SETCW (cw);
+
+  return 0;
+}

+ 36 - 0
libm/sh/sh4/feupdateenv.c

@@ -0,0 +1,36 @@
+/* Install given floating-point environment and raise exceptions.
+   Copyright (C) 2012-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 <fpu_control.h>
+
+int
+feupdateenv (const fenv_t *envp)
+{
+  fpu_control_t temp;
+
+  _FPU_GETCW (temp);
+  temp = (temp & FE_ALL_EXCEPT);
+
+  /* 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. */
+  fesetenv (envp);
+  feraiseexcept ((int) temp);
+
+  return 0;
+}

+ 37 - 0
libm/sh/sh4/fgetexcptflg.c

@@ -0,0 +1,37 @@
+/* Store current representation for exceptions.
+   Copyright (C) 2013-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 <fpu_control.h>
+
+int
+fegetexceptflag (fexcept_t *flagp, int excepts)
+{
+  fpu_control_t temp;
+
+  /* Get the current exceptions.  */
+  _FPU_GETCW (temp);
+
+  /* We only save the relevant bits here. In particular, care has to be
+     taken with the CAUSE bits, as an inadvertent restore later on could
+     generate unexpected exceptions.  */
+
+  *flagp = temp & excepts & FE_ALL_EXCEPT;
+
+  /* Success.  */
+  return 0;
+}

+ 70 - 0
libm/sh/sh4/fraiseexcpt.c

@@ -0,0 +1,70 @@
+/* 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 <fpu_control.h>
+#include <math.h>
+
+int
+feraiseexcept (int excepts)
+{
+  if (excepts == 0)
+    return 0;
+
+  /* Raise exceptions represented by EXPECTS.  */
+
+  if (excepts & FE_INEXACT)
+  {
+    double d = 1.0, x = 3.0;
+    __asm__ __volatile__ ("fdiv %1, %0" : "+d" (d) : "d" (x));
+  }
+
+  if (excepts & FE_UNDERFLOW)
+  {
+    long double d = LDBL_MIN, x = 10;
+    __asm__ __volatile__ ("fdiv %1, %0" : "+d" (d) : "d" (x));
+  }
+
+  if (excepts & FE_OVERFLOW)
+  {
+    long double d = LDBL_MAX;
+    __asm__ __volatile__ ("fmul %0, %0" : "+d" (d) : "d" (d));
+  }
+
+  if (excepts & FE_DIVBYZERO)
+  {
+    double d = 1.0, x = 0.0;
+    __asm__ __volatile__ ("fdiv %1, %0" : "+d" (d) : "d" (x));
+  }
+
+  if (excepts & FE_INVALID)
+  {
+    double d = HUGE_VAL, x = 0.0;
+    __asm__ __volatile__ ("fmul %1, %0" : "+d" (d) : "d" (x));
+  }
+
+  {
+    /* Restore flag fields.  */
+    fpu_control_t cw;
+    _FPU_GETCW (cw);
+    cw |= (excepts & FE_ALL_EXCEPT);
+    _FPU_SETCW (cw);
+  }
+
+  return 0;
+}

+ 38 - 0
libm/sh/sh4/fsetexcptflg.c

@@ -0,0 +1,38 @@
+/* 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 <math.h>
+#include <fpu_control.h>
+
+int
+fesetexceptflag (const fexcept_t *flagp, int excepts)
+{
+  fpu_control_t temp;
+
+  /* Get the current environment.  */
+  _FPU_GETCW (temp);
+
+  /* Set the desired exception mask.  */
+  temp &= ~(excepts & FE_ALL_EXCEPT);
+  temp |= (*flagp & excepts & FE_ALL_EXCEPT);
+
+  /* Save state back to the FPU.  */
+  _FPU_SETCW (temp);
+
+  return 0;
+}

+ 30 - 0
libm/sh/sh4/ftestexcept.c

@@ -0,0 +1,30 @@
+/* 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 <fpu_control.h>
+
+int
+fetestexcept (int excepts)
+{
+  fpu_control_t temp;
+
+  /* Get current exceptions.  */
+  _FPU_GETCW (temp);
+
+  return temp & excepts & FE_ALL_EXCEPT;
+}