在 2024/3/28 上午1:10, Joseph Myers 写道:
> On Wed, 27 Mar 2024, caiyinyu wrote:
>
>> Yes, this patch does make sense in both libc and libm and it can be proved by
>> the following glibc tests:
> Please explain more how it works.
>
>> All the functions Implemented in this patch are exported from libm.so the same
>> as powerpc nofpu.
> I'm talking about functions such as __adddf3 (which would need to be
> exported from libc, not libm, to provide exceptions / rounding modes
> support for software floating point). I don't see them in any Versions
> file for LoongArch.
>
> Furthermore, this patch isn't changing sfp-machine.h for LoongArch, which
> uses fpu_control.h to get rounding mode / exceptions state, and it isn't
> changing how fpu_control.h uses constant 0 for that state in the
> soft-float case. So I don't see how it would produce *working* exceptions
> / rounding modes support for software floating-point arithmetic.
I revised and submitted the version 2 patch:
The main corrections in the version 2 patch are:
1. Correcting the nofpu libc files: sim-full.c sfp-machine.h soft-supp.h.
2. Updating/modifying the fpu/nofpu libc
Versions/libc.abilist/localplt.data files.
v1: https://sourceware.org/pipermail/libc-alpha/2024-March/155597.html
v2: https://sourceware.org/pipermail/libc-alpha/2024-March/155707.html
LoongArch soft float support was added in version 2.37, but the fe*
functions
were not completely added. I want to backport this patch if possible
(it requires some modifications) to the 2.37/38/39/master branch, so the
version of
the relevant symbols in Versions is GLIBC_2.37.
Here is the difference between v1 and v2 :
1.
diff --git a/sysdeps/loongarch/nofpu/sim-full.c
b/sysdeps/loongarch/nofpu/sim-full.c
index a2bbb9f880..b10e5b2f4d 100644
--- a/sysdeps/loongarch/nofpu/sim-full.c
+++ b/sysdeps/loongarch/nofpu/sim-full.c
@@ -16,8 +16,22 @@
License along with the GNU C Library. If not, see
<https://www.gnu.org/licenses/>. */
+#include "soft-fp.h"
#include "soft-supp.h"
+#include <signal.h>
/* By default, no exceptions should trap. */
__thread int __sim_cw_thread;
libc_hidden_tls_def (__sim_cw_thread);
+
+void
+__simulate_exceptions (int excepts)
+{
+ int enable;
+ __sim_cw_thread |= excepts;
+
+ enable = __sim_cw_thread & _FPU_ENABLE_MASK;
+ if (excepts & __sim_cw_thread & (enable << ENABLE_SHIFT))
+ raise (SIGFPE);
+}
+libc_hidden_def (__simulate_exceptions)
diff --git a/sysdeps/loongarch/nofpu/soft-supp.h
b/sysdeps/loongarch/nofpu/soft-supp.h
index 37d83399e8..8d3ba09764 100644
--- a/sysdeps/loongarch/nofpu/soft-supp.h
+++ b/sysdeps/loongarch/nofpu/soft-supp.h
@@ -18,3 +18,5 @@
extern __thread int __sim_cw_thread attribute_tls_model_ie;
libc_hidden_tls_proto (__sim_cw_thread, tls_model ("initial-exec"));
+
+extern void __simulate_exceptions (int excepts);
diff --git a/sysdeps/loongarch/sfp-machine.h
b/sysdeps/loongarch/sfp-machine.h
index cbf66500db..eda6c66423 100644
--- a/sysdeps/loongarch/sfp-machine.h
+++ b/sysdeps/loongarch/sfp-machine.h
@@ -64,10 +64,6 @@
} \
while (0)
-#define _FP_DECL_EX fpu_control_t _fcw
-
-#define FP_ROUNDMODE (_fcw & 0x300)
-
#define FP_RND_NEAREST FE_TONEAREST
#define FP_RND_ZERO FE_TOWARDZERO
#define FP_RND_PINF FE_UPWARD
@@ -82,6 +78,8 @@
#define _FP_TININESS_AFTER_ROUNDING 1
#ifdef __loongarch_hard_float
+#define _FP_DECL_EX fpu_control_t _fcw
+#define FP_ROUNDMODE (_fcw & 0x300)
#define FP_INIT_ROUNDMODE \
do \
{ \
@@ -98,5 +96,12 @@
while (0)
#define FP_TRAPPING_EXCEPTIONS ((_fcw << 16) & 0x1f0000)
#else
-#define FP_INIT_ROUNDMODE _fcw = FP_RND_NEAREST
+#define FP_HANDLE_EXCEPTIONS __simulate_exceptions (_fex)
+#define FP_ROUNDMODE (__sim_cw_thread & _FPU_RC_MASK)
+#define FP_TRAPPING_EXCEPTIONS (__sim_cw_thread & _FPU_ENABLE_MASK)
+
+extern __thread int __sim_cw_thread attribute_tls_model_ie;
+libc_hidden_tls_proto (__sim_cw_thread, tls_model ("initial-exec"));
+extern void __simulate_exceptions (int excepts);
+libc_hidden_proto (__simulate_exceptions)
#endif
2. libc.abilist is too long so not listed here.
diff --git a/sysdeps/loongarch/nofpu/Versions
b/sysdeps/loongarch/nofpu/Versions
index 6d7f6aae6c..73b6a71bbd 100644
--- a/sysdeps/loongarch/nofpu/Versions
+++ b/sysdeps/loongarch/nofpu/Versions
@@ -1,5 +1,13 @@
libc {
+ GLIBC_2.37 {
+ __adddf3; __addsf3; __divdf3; __divsf3; __eqdf2; __eqsf2;
+ __extendsfdf2; __fixdfsi; __fixsfsi;
+ __fixunsdfsi; __fixunssfsi;
+ __floatsidf; __floatsisf;
+ __gedf2; __gesf2; __ledf2; __lesf2; __muldf3; __mulsf3;
+ __negdf2; __negsf2; __subdf3; __subsf3; __truncdfsf2;
+ }
GLIBC_PRIVATE {
- __sim_cw_thread;
+ __sim_cw_thread; __simulate_exceptions;
}
}
diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/fpu/localplt.data
b/sysdeps/unix/sysv/linux/loongarch/lp64/fpu/localplt.data
new file mode 100644
index 0000000000..547b1c1b7f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/loongarch/lp64/fpu/localplt.data
@@ -0,0 +1,7 @@
+# See scripts/check-localplt.awk for how this file is processed.
+# PLT use is required for the malloc family and for matherr because
+# users can define their own functions and have library internals call
them.
+libc.so: calloc
+libc.so: free
+libc.so: malloc
+libc.so: realloc
diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/nofpu/Implies
b/sysdeps/unix/sysv/linux/loongarch/lp64/nofpu/Implies
new file mode 100644
index 0000000000..1090fb545a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/loongarch/lp64/nofpu/Implies
@@ -0,0 +1 @@
+loongarch/nofpu
diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/nofpu/localplt.data
b/sysdeps/unix/sysv/linux/loongarch/lp64/nofpu/localplt.data
new file mode 100644
index 0000000000..d40826c783
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/loongarch/lp64/nofpu/localplt.data
@@ -0,0 +1,23 @@
+# See scripts/check-localplt.awk for how this file is processed.
+# PLT use is required for the malloc family and for matherr because
+# users can define their own functions and have library internals call
them.
+libc.so: calloc
+libc.so: free
+libc.so: malloc
+libc.so: realloc
+libc.so: __fixsfsi
+libc.so: __divsf3
+libc.so: __adddf3
+libc.so: __eqdf2
+libc.so: __gedf2
+libc.so: __floatsisf
+libc.so: __eqsf2
+libc.so: __subsf3
+libc.so: __mulsf3
+libc.so: __muldf3
+libc.so: __subdf3
+libc.so: __divdf3
+libc.so: __ledf2
+libc.so: __floatsidf
+libc.so: __extendsfdf2
+libc.so: __addsf3
>
@@ -17,7 +17,6 @@
<https://www.gnu.org/licenses/>. */
#include <fenv.h>
-#include <fenv_libc.h>
#include <fpu_control.h>
int
@@ -17,7 +17,6 @@
<https://www.gnu.org/licenses/>. */
#include <fenv.h>
-#include <fenv_libc.h>
#include <fpu_control.h>
int
@@ -28,7 +27,7 @@ fedisableexcept (int excepts)
/* Get the current control word. */
_FPU_GETCW (new_exc);
- old_exc = (new_exc & ENABLE_MASK) << ENABLE_SHIFT;
+ old_exc = (new_exc & _FPU_ENABLE_MASK) << ENABLE_SHIFT;
excepts &= FE_ALL_EXCEPT;
@@ -17,7 +17,6 @@
<https://www.gnu.org/licenses/>. */
#include <fenv.h>
-#include <fenv_libc.h>
#include <fpu_control.h>
int
@@ -28,7 +27,7 @@ feenableexcept (int excepts)
/* Get the current control word. */
_FPU_GETCW (new_exc);
- old_exc = (new_exc & ENABLE_MASK) << ENABLE_SHIFT;
+ old_exc = (new_exc & _FPU_ENABLE_MASK) << ENABLE_SHIFT;
excepts &= FE_ALL_EXCEPT;
@@ -17,7 +17,6 @@
<https://www.gnu.org/licenses/>. */
#include <fenv.h>
-#include <fenv_libc.h>
#include <fpu_control.h>
int
@@ -28,5 +27,5 @@ fegetexcept (void)
/* Get the current control word. */
_FPU_GETCW (exc);
- return (exc & ENABLE_MASK) << ENABLE_SHIFT;
+ return (exc & _FPU_ENABLE_MASK) << ENABLE_SHIFT;
}
@@ -51,10 +51,25 @@
#include <features.h>
+#define _FPU_DEFAULT 0x0
+#define _FPU_IEEE 0x1F
+/* Mask for rounding control/enable/cause fields. */
+#define _FPU_RC_MASK 0x300
+#define _FPU_ENABLE_MASK 0x0000001f
+#define _FPU_CAUSE_MASK 0x1f000000
+/* Shift for FE_* flags to get up to the ENABLE bits and the CAUSE bits. */
+#define ENABLE_SHIFT 16
+#define CAUSE_SHIFT 8
+/* Masks for interrupts. */
+#define _FPU_MASK_V 0x10 /* Invalid operation */
+#define _FPU_MASK_Z 0x08 /* Division by zero */
+#define _FPU_MASK_O 0x04 /* Overflow */
+#define _FPU_MASK_U 0x02 /* Underflow */
+#define _FPU_MASK_I 0x01 /* Inexact operation */
+
#ifdef __loongarch_soft_float
#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)
@@ -62,13 +77,6 @@ extern fpu_control_t __fpu_control;
#else /* __loongarch_soft_float */
-/* Masks for interrupts. */
-#define _FPU_MASK_V 0x10 /* Invalid operation */
-#define _FPU_MASK_Z 0x08 /* Division by zero */
-#define _FPU_MASK_O 0x04 /* Overflow */
-#define _FPU_MASK_U 0x02 /* Underflow */
-#define _FPU_MASK_I 0x01 /* Inexact operation */
-
/* Flush denormalized numbers to zero. */
#define _FPU_FLUSH_TZ 0x1000000
@@ -77,14 +85,9 @@ extern fpu_control_t __fpu_control;
#define _FPU_RC_ZERO 0x100
#define _FPU_RC_UP 0x200
#define _FPU_RC_DOWN 0x300
-/* Mask for rounding control. */
-#define _FPU_RC_MASK 0x300
#define _FPU_RESERVED 0x0
-#define _FPU_DEFAULT 0x0
-#define _FPU_IEEE 0x1F
-
/* Type of the control word. */
typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__SI__)));
@@ -27,7 +27,6 @@
#ifdef __loongarch_hard_float
#include <fenv.h>
-#include <fenv_libc.h>
#include <fpu_control.h>
#define _FPU_MASK_ALL \
new file mode 100644
@@ -0,0 +1,10 @@
+# Makefile fragment for LoongArch with no FPU.
+
+ifeq ($(subdir),soft-fp)
+sysdep_routines += $(gcc-single-routines) $(gcc-double-routines) \
+ sim-full
+endif
+
+ifeq ($(subdir),math)
+CPPFLAGS += -I../soft-fp/
+endif
new file mode 100644
@@ -0,0 +1 @@
+soft-fp
new file mode 100644
@@ -0,0 +1,5 @@
+libc {
+ GLIBC_PRIVATE {
+ __sim_cw_thread;
+ }
+}
new file mode 100644
@@ -0,0 +1,37 @@
+/* Clear floating-point exceptions (soft-float edition).
+ Copyright (C) 2024 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ 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 "soft-fp.h"
+#include "soft-supp.h"
+
+int
+feclearexcept (int excepts)
+{
+ /* Mask out unsupported bits/exceptions. */
+ excepts &= FE_ALL_EXCEPT;
+
+ /* Clear exception flag bits and cause bits. If the cause bit is not
+ cleared, the next CTC instruction (just below) will re-generate the
+ exception. */
+
+ __sim_cw_thread &= ~(excepts | (excepts << CAUSE_SHIFT));
+
+ return 0;
+}
+
+libm_hidden_weak (feclearexcept)
similarity index 62%
rename from sysdeps/loongarch/fpu/fenv_libc.h
rename to sysdeps/loongarch/nofpu/fedisblxcpt.c
@@ -1,5 +1,5 @@
-/* Internal libc stuff for floating point environment routines.
- Copyright (C) 2022-2024 Free Software Foundation, Inc.
+/* Disable exceptions (soft-float edition).
+ Copyright (C) 2024 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -16,15 +16,17 @@
License along with the GNU C Library. If not, see
<https://www.gnu.org/licenses/>. */
-#ifndef _FENV_LIBC_H
-#define _FENV_LIBC_H 1
+#include "soft-fp.h"
+#include "soft-supp.h"
-/* Mask for enabling exceptions and for the CAUSE bits. */
-#define ENABLE_MASK 0x0000001FU
-#define CAUSE_MASK 0x1F000000U
+int
+fedisableexcept (int excepts)
+{
+ unsigned int old_exc = (__sim_cw_thread & _FPU_ENABLE_MASK) << ENABLE_SHIFT;
-/* Shift for FE_* flags to get up to the ENABLE bits and the CAUSE bits. */
-#define ENABLE_SHIFT 16
-#define CAUSE_SHIFT 8
+ excepts &= FE_ALL_EXCEPT;
-#endif /* _FENV_LIBC_H */
+ __sim_cw_thread &= ~(excepts >> ENABLE_SHIFT);
+
+ return old_exc;
+}
new file mode 100644
@@ -0,0 +1,32 @@
+/* Enable exceptions (soft-float edition).
+ Copyright (C) 2024 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ 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 "soft-fp.h"
+#include "soft-supp.h"
+
+int
+feenableexcept (int excepts)
+{
+ int old_exc = (__sim_cw_thread & _FPU_ENABLE_MASK) << ENABLE_SHIFT;
+
+ excepts &= FE_ALL_EXCEPT;
+
+ __sim_cw_thread |= excepts >> ENABLE_SHIFT;
+
+ return old_exc;
+}
new file mode 100644
@@ -0,0 +1,32 @@
+/* Store current floating-point environment (soft-float edition).
+ Copyright (C) 2024 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ 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 "soft-fp.h"
+#include "soft-supp.h"
+
+int
+__fegetenv (fenv_t *envp)
+{
+
+ envp->__fp_control_register = __sim_cw_thread;
+
+ return 0;
+}
+
+libm_hidden_def (__fegetenv) weak_alias (__fegetenv, fegetenv)
+libm_hidden_weak (fegetenv)
new file mode 100644
@@ -0,0 +1,26 @@
+/* Get floating-point exceptions (soft-float edition).
+ Copyright (C) 2024 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ 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 "soft-fp.h"
+#include "soft-supp.h"
+
+int
+fegetexcept (void)
+{
+ return (__sim_cw_thread & _FPU_ENABLE_MASK) << ENABLE_SHIFT;
+}
new file mode 100644
@@ -0,0 +1,27 @@
+/* Store current floating-point control modes (soft-float edition).
+ Copyright (C) 2024 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ 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 "soft-fp.h"
+#include "soft-supp.h"
+
+int
+fegetmode (femode_t *modep)
+{
+ *modep = __sim_cw_thread;
+ return 0;
+}
new file mode 100644
@@ -0,0 +1,29 @@
+/* Return current rounding mode (soft-float edition).
+ Copyright (C) 2024 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ 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 "soft-fp.h"
+#include "soft-supp.h"
+
+int
+__fegetround (void)
+{
+ return __sim_cw_thread & _FPU_RC_MASK;
+}
+
+libm_hidden_def (__fegetround) weak_alias (__fegetround, fegetround)
+libm_hidden_weak (fegetround)
new file mode 100644
@@ -0,0 +1,37 @@
+/* Store current floating-point environment and clear exceptions
+ (soft-float edition).
+ Copyright (C) 2024 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ 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 "soft-fp.h"
+#include "soft-supp.h"
+
+int
+__feholdexcept (fenv_t *envp)
+{
+
+ envp->__fp_control_register = __sim_cw_thread;
+
+ /* Clear all exception enable bits and flags. */
+ __sim_cw_thread &= ~(_FPU_MASK_V | _FPU_MASK_Z | _FPU_MASK_O | _FPU_MASK_U
+ | _FPU_MASK_I | FE_ALL_EXCEPT);
+
+ return 0;
+}
+
+libm_hidden_def (__feholdexcept) weak_alias (__feholdexcept, feholdexcept)
+libm_hidden_weak (feholdexcept)
new file mode 100644
@@ -0,0 +1,37 @@
+/* Set floating point environment (soft-float edition).
+ Copyright (C) 2024 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ 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 "soft-fp.h"
+#include "soft-supp.h"
+
+int
+__fesetenv (const fenv_t *envp)
+{
+
+ if (envp == FE_DFL_ENV)
+ __sim_cw_thread = _FPU_DEFAULT;
+ else if (envp == FE_NOMASK_ENV)
+ __sim_cw_thread = _FPU_IEEE;
+ else
+ __sim_cw_thread = envp->__fp_control_register;
+
+ return 0;
+}
+
+libm_hidden_def (__fesetenv) weak_alias (__fesetenv, fesetenv)
+libm_hidden_weak (fesetenv)
new file mode 100644
@@ -0,0 +1,27 @@
+/* Set given exception flags (soft-float edition).
+ Copyright (C) 2024 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ 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 "soft-fp.h"
+#include "soft-supp.h"
+
+int
+fesetexcept (int excepts)
+{
+ __sim_cw_thread |= excepts & FE_ALL_EXCEPT;
+ return 0;
+}
new file mode 100644
@@ -0,0 +1,34 @@
+/* Install given floating-point control modes (soft-float edition).
+ Copyright (C) 2024 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ 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 "soft-fp.h"
+#include "soft-supp.h"
+
+#define FCSR_STATUS 0x1f1f0000
+
+int
+fesetmode (const femode_t *modep)
+{
+ __sim_cw_thread &= FCSR_STATUS;
+ if (modep == FE_DFL_MODE)
+ __sim_cw_thread |= _FPU_DEFAULT;
+ else
+ __sim_cw_thread |= *modep & ~FCSR_STATUS;
+
+ return 0;
+}
new file mode 100644
@@ -0,0 +1,36 @@
+/* Set rounding mode (soft-float edition).
+ Copyright (C) 2024 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ 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 "soft-fp.h"
+#include "soft-supp.h"
+
+int
+__fesetround (int round)
+{
+ if ((round & ~_FPU_RC_MASK) != 0)
+ /* ROUND is no valid rounding mode. */
+ return 1;
+
+ /* Set rounding bits. */
+ __sim_cw_thread &= ~_FPU_RC_MASK;
+ __sim_cw_thread |= round;
+
+ return 0;
+}
+libm_hidden_def (__fesetround) weak_alias (__fesetround, fesetround)
+libm_hidden_weak (fesetround)
new file mode 100644
@@ -0,0 +1,43 @@
+/* Install given floating-point environment and raise exceptions
+ (soft-float edition).
+ Copyright (C) 2024 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ 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 "soft-fp.h"
+#include "soft-supp.h"
+#include <signal.h>
+
+int
+__feupdateenv (const fenv_t *envp)
+{
+ int temp;
+
+ temp = __sim_cw_thread & 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 (temp);
+
+ return 0;
+}
+
+libm_hidden_def (__feupdateenv) weak_alias (__feupdateenv, feupdateenv)
+libm_hidden_weak (feupdateenv)
new file mode 100644
@@ -0,0 +1,28 @@
+/* Store current representation for exceptions (soft-float edition).
+ Copyright (C) 2024 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ 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 "soft-fp.h"
+#include "soft-supp.h"
+
+int
+fegetexceptflag (fexcept_t *flagp, int excepts)
+{
+ *flagp = (fexcept_t) __sim_cw_thread & excepts & FE_ALL_EXCEPT;
+
+ return 0;
+}
new file mode 100644
@@ -0,0 +1,42 @@
+/* Raise given exceptions (soft-float edition).
+ Copyright (C) 2024 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ 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 "soft-fp.h"
+#include "soft-supp.h"
+#include <signal.h>
+
+int
+__feraiseexcept (int excepts)
+{
+ int enable;
+ /* Set flag bits (which are accumulative), and *also* set the
+ cause bits. The setting of the cause bits is what actually causes
+ the hardware to generate the exception, if the corresponding enable
+ bit is set as well. */
+
+ excepts &= FE_ALL_EXCEPT;
+ __sim_cw_thread |= excepts | (excepts << CAUSE_SHIFT);
+ enable = __sim_cw_thread & _FPU_ENABLE_MASK;
+ if (excepts & __sim_cw_thread & (enable << ENABLE_SHIFT))
+ raise (SIGFPE);
+
+ return 0;
+}
+
+libm_hidden_def (__feraiseexcept) weak_alias (__feraiseexcept, feraiseexcept)
+libm_hidden_weak (feraiseexcept)
new file mode 100644
@@ -0,0 +1,35 @@
+/* Set floating-point environment exception handling (soft-float edition).
+ Copyright (C) 2024 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ 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 "soft-fp.h"
+#include "soft-supp.h"
+
+int
+fesetexceptflag (const fexcept_t *flagp, int excepts)
+{
+ /* Make sure the flags we want restored are legal. */
+ excepts &= FE_ALL_EXCEPT;
+
+ /* Now clear the bits called for, and copy them in from flagp. Note that
+ we ignore all non-flag bits from *flagp, so they don't matter. */
+ __sim_cw_thread = (__sim_cw_thread & ~excepts) | (*flagp & excepts);
+
+
+ /* Success. */
+ return 0;
+}
new file mode 100644
@@ -0,0 +1,27 @@
+/* Test floating-point exceptions (soft-float edition).
+ Copyright (C) 2024 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ 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 "soft-fp.h"
+#include "soft-supp.h"
+
+int
+fetestexcept (int excepts)
+{
+ return __sim_cw_thread & excepts & FE_ALL_EXCEPT;
+}
+libm_hidden_def (fetestexcept)
new file mode 100644
@@ -0,0 +1,34 @@
+/* Determine floating-point rounding mode within libc (soft-float edition).
+ Copyright (C) 2024 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ 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 _LOONGARCH_NOFPU_GET_ROUNDING_MODE_H
+#define _LOONGARCH_NOFPU_GET_ROUNDING_MODE_H 1
+
+#include <fenv.h>
+#include <fpu_control.h>
+#include "soft-supp.h"
+
+/* Return the floating-point rounding mode. */
+
+static inline int
+get_rounding_mode (void)
+{
+ return __sim_cw_thread & _FPU_RC_MASK;
+}
+
+#endif /* get-rounding-mode.h */
new file mode 100644
@@ -0,0 +1,23 @@
+/* Software floating-point exception handling emulation.
+ Copyright (C) 2024 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ 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 "soft-supp.h"
+
+/* By default, no exceptions should trap. */
+__thread int __sim_cw_thread;
+libc_hidden_tls_def (__sim_cw_thread);
new file mode 100644
@@ -0,0 +1,20 @@
+/* Internal support stuff for complete soft float.
+ Copyright (C) 2024 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ 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/>. */
+
+extern __thread int __sim_cw_thread attribute_tls_model_ie;
+libc_hidden_tls_proto (__sim_cw_thread, tls_model ("initial-exec"));