summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makerules2
-rw-r--r--Rules.mak8
-rw-r--r--extra/Configs/Config.in.arch4
-rw-r--r--extra/Configs/Config.kvx1
-rw-r--r--include/libintl.h3
-rw-r--r--include/netdb.h2
-rw-r--r--include/pty.h6
-rw-r--r--ldso/ldso/aarch64/elfinterp.c4
-rw-r--r--libc/inet/resolv.c2
-rw-r--r--libc/misc/sysvipc/ipc.h9
-rw-r--r--libc/misc/sysvipc/msgq.c21
-rw-r--r--libc/misc/sysvipc/sem.c11
-rw-r--r--libc/misc/sysvipc/shm.c19
-rw-r--r--libc/stdlib/malloc-standard/malloc.c10
-rw-r--r--libc/sysdeps/linux/aarch64/bits/shm.h87
-rw-r--r--libc/sysdeps/linux/arc/bits/fenv.h75
-rw-r--r--libc/sysdeps/linux/arc/fpu_control.h104
-rw-r--r--libc/sysdeps/linux/arm/bits/shm.h6
-rw-r--r--libc/sysdeps/linux/common/Makefile.in1
-rw-r--r--libc/sysdeps/linux/common/bits/msq.h14
-rw-r--r--libc/sysdeps/linux/common/bits/sem.h8
-rw-r--r--libc/sysdeps/linux/common/bits/typesizes.h10
-rw-r--r--libc/sysdeps/linux/common/getentropy.c1
-rw-r--r--libc/sysdeps/linux/common/utimes.c4
-rw-r--r--libc/sysdeps/linux/csky/bits/fenv.h123
-rw-r--r--libc/sysdeps/linux/csky/fpu_control.h147
-rw-r--r--libc/sysdeps/linux/kvx/Makefile.arch2
-rw-r--r--libc/sysdeps/linux/kvx/bits/shm.h87
-rw-r--r--libc/sysdeps/linux/kvx/getcontext.S81
-rw-r--r--libc/sysdeps/linux/kvx/makecontext.c53
-rw-r--r--libc/sysdeps/linux/kvx/setcontext.S106
-rw-r--r--libc/sysdeps/linux/kvx/swapcontext.S63
-rw-r--r--libc/sysdeps/linux/kvx/sys/ucontext.h4
-rw-r--r--libc/sysdeps/linux/kvx/ucontext_i.sym28
-rw-r--r--libc/sysdeps/linux/m68k/bits/shm.h108
-rw-r--r--libc/sysdeps/linux/mips/bits/msq.h94
-rw-r--r--libc/sysdeps/linux/mips/bits/sem.h11
-rw-r--r--libc/sysdeps/linux/mips/bits/shm.h28
-rw-r--r--libc/sysdeps/linux/mips/bits/syscalls.h36
-rw-r--r--libc/sysdeps/linux/riscv32/bits/shm.h6
-rw-r--r--libc/sysdeps/linux/riscv64/bits/shm.h7
-rw-r--r--libc/sysdeps/linux/sh/bits/fenv.h60
-rw-r--r--libc/sysdeps/linux/sh/fpu_control.h30
-rw-r--r--libc/sysdeps/linux/sparc/bits/fenv.h60
-rw-r--r--libc/sysdeps/linux/sparc/fpu_control.h24
-rw-r--r--libm/arc/Makefile.arch16
-rw-r--r--libm/arc/fclrexcpt.c34
-rw-r--r--libm/arc/fegetenv.c33
-rw-r--r--libm/arc/fegetmode.c30
-rw-r--r--libm/arc/fegetround.c28
-rw-r--r--libm/arc/feholdexcpt.c39
-rw-r--r--libm/arc/fenv_private.h326
-rw-r--r--libm/arc/fesetenv.c44
-rw-r--r--libm/arc/fesetexcept.c31
-rw-r--r--libm/arc/fesetmode.c39
-rw-r--r--libm/arc/fesetround.c36
-rw-r--r--libm/arc/feupdateenv.c47
-rw-r--r--libm/arc/fgetexcptflg.c30
-rw-r--r--libm/arc/fraiseexcpt.c35
-rw-r--r--libm/arc/fsetexcptflg.c37
-rw-r--r--libm/arc/ftestexcept.c31
-rw-r--r--libm/arc/get-rounding-mode.h37
-rw-r--r--libm/csky/Makefile.arch16
-rw-r--r--libm/csky/fclrexcpt.c40
-rw-r--r--libm/csky/fedisblxcpt.c40
-rw-r--r--libm/csky/feenablxcpt.c39
-rw-r--r--libm/csky/fegetenv.c33
-rw-r--r--libm/csky/fegetexcept.c31
-rw-r--r--libm/csky/fegetmode.c27
-rw-r--r--libm/csky/fegetround.c30
-rw-r--r--libm/csky/feholdexcpt.c30
-rw-r--r--libm/csky/fenv_libc.h29
-rw-r--r--libm/csky/fenv_private.h277
-rw-r--r--libm/csky/fesetenv.c55
-rw-r--r--libm/csky/fesetexcept.c32
-rw-r--r--libm/csky/fesetmode.c32
-rw-r--r--libm/csky/fesetround.c28
-rw-r--r--libm/csky/feupdateenv.c42
-rw-r--r--libm/csky/fgetexcptflg.c31
-rw-r--r--libm/csky/fraiseexcpt.c122
-rw-r--r--libm/csky/fsetexcptflg.c42
-rw-r--r--libm/csky/ftestexcept.c28
-rw-r--r--libm/sh/sh4/Makefile.arch2
-rw-r--r--libm/sh/sh4/fclrexcpt.c39
-rw-r--r--libm/sh/sh4/fedisblxcpt.c37
-rw-r--r--libm/sh/sh4/feenablxcpt.c36
-rw-r--r--libm/sh/sh4/fegetenv.c30
-rw-r--r--libm/sh/sh4/fegetexcept.c30
-rw-r--r--libm/sh/sh4/fegetmode.c26
-rw-r--r--libm/sh/sh4/fegetround.c30
-rw-r--r--libm/sh/sh4/feholdexcpt.c37
-rw-r--r--libm/sh/sh4/fesetenv.c28
-rw-r--r--libm/sh/sh4/fesetexcept.c31
-rw-r--r--libm/sh/sh4/fesetmode.c37
-rw-r--r--libm/sh/sh4/fesetround.c40
-rw-r--r--libm/sh/sh4/feupdateenv.c36
-rw-r--r--libm/sh/sh4/fgetexcptflg.c37
-rw-r--r--libm/sh/sh4/fraiseexcpt.c70
-rw-r--r--libm/sh/sh4/fsetexcptflg.c38
-rw-r--r--libm/sh/sh4/ftestexcept.c30
-rw-r--r--libm/sparc/Makefile.arch16
-rw-r--r--libm/sparc/fclrexcpt.c34
-rw-r--r--libm/sparc/fedisblxcpt.c34
-rw-r--r--libm/sparc/feenablxcpt.c34
-rw-r--r--libm/sparc/fegetenv.c28
-rw-r--r--libm/sparc/fegetexcept.c28
-rw-r--r--libm/sparc/fegetmode.c26
-rw-r--r--libm/sparc/fegetround.c29
-rw-r--r--libm/sparc/feholdexcpt.c34
-rw-r--r--libm/sparc/fenv_private.h187
-rw-r--r--libm/sparc/fesetenv.c45
-rw-r--r--libm/sparc/fesetexcept.c31
-rw-r--r--libm/sparc/fesetmode.c38
-rw-r--r--libm/sparc/fesetround.c36
-rw-r--r--libm/sparc/feupdateenv.c40
-rw-r--r--libm/sparc/fgetexcptflg.c33
-rw-r--r--libm/sparc/fpu_control.h75
-rw-r--r--libm/sparc/fraiseexcpt.c81
-rw-r--r--libm/sparc/fsetexcptflg.c36
-rw-r--r--libm/sparc/ftestexcept.c29
-rw-r--r--libm/sparc/math-barriers.h36
-rw-r--r--libpthread/nptl/pthread_key_create.c1
-rw-r--r--libpthread/nptl/sysdeps/nds32/dl-tls.h2
-rw-r--r--libutil/forkpty.c3
-rw-r--r--libutil/openpty.c80
125 files changed, 4780 insertions, 297 deletions
diff --git a/Makerules b/Makerules
index 96f2a71ec..38c26891b 100644
--- a/Makerules
+++ b/Makerules
@@ -86,7 +86,7 @@ SHELL_SET_X := set +x
define rel_srcdir
$(shell $(CONFIG_SHELL) $(top_srcdir)/extra/scripts/relative_path.sh $(@D) .)
endef
-ifneq ($(findstring s,$(MAKEFLAGS)),)
+ifneq (,$(filter -s,$(wordlist 1,$(words $(MAKEFLAGS)),$(MAKEFLAGS))))
export MAKE_IS_SILENT := y
SECHO := -@false
DISP := sil
diff --git a/Rules.mak b/Rules.mak
index 1aa1be93a..695913b2a 100644
--- a/Rules.mak
+++ b/Rules.mak
@@ -1,7 +1,7 @@
# Rules.mak for uClibc-ng
#
# Copyright (C) 2000-2008 Erik Andersen <andersen@uclibc.org>
-# Copyright (C) 2015-2024 Waldemar Brodkorb <wbx@uclibc-ng.org>
+# Copyright (C) 2015-2025 Waldemar Brodkorb <wbx@uclibc-ng.org>
#
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
#
@@ -128,7 +128,7 @@ export RUNTIME_PREFIX DEVEL_PREFIX KERNEL_HEADERS MULTILIB_DIR
# Now config hard core
MAJOR_VERSION := 1
MINOR_VERSION := 0
-SUBLEVEL := 52
+SUBLEVEL := 55
EXTRAVERSION :=
VERSION := $(MAJOR_VERSION).$(MINOR_VERSION).$(SUBLEVEL)
ABI_VERSION := $(MAJOR_VERSION)
@@ -312,10 +312,6 @@ endif
endif
endif
-ifeq ($(TARGET_ARCH),aarch64)
-CPU_CFLAGS-y += -ftls-model=initial-exec
-endif
-
$(eval $(call check-gcc-var,-std=gnu99))
CPU_CFLAGS-y += $(CFLAG_-std=gnu99)
diff --git a/extra/Configs/Config.in.arch b/extra/Configs/Config.in.arch
index cacac7e5e..24c0db157 100644
--- a/extra/Configs/Config.in.arch
+++ b/extra/Configs/Config.in.arch
@@ -165,7 +165,9 @@ config UCLIBC_HAS_FENV
depends on UCLIBC_HAS_FLOATS
depends on TARGET_i386 || \
TARGET_aarch64 || \
+ TARGET_arc || \
TARGET_arm || \
+ TARGET_csky || \
TARGET_m68k || \
TARGET_metag || \
TARGET_mips || \
@@ -174,6 +176,8 @@ config UCLIBC_HAS_FENV
(TARGET_powerpc && CONFIG_E500) || \
TARGET_riscv32 || \
TARGET_riscv64 || \
+ (TARGET_sh && (CONFIG_SH4 || CONFIG_SH4A)) || \
+ TARGET_sparc || \
TARGET_x86_64
help
If you want the uClibc math library to contain the C99 floating
diff --git a/extra/Configs/Config.kvx b/extra/Configs/Config.kvx
index 04df53c38..4d8152ab9 100644
--- a/extra/Configs/Config.kvx
+++ b/extra/Configs/Config.kvx
@@ -30,6 +30,7 @@ config FORCE_OPTIONS_FOR_ARCH
default y
select ARCH_LITTLE_ENDIAN
select ARCH_HAS_MMU
+ select ARCH_HAS_UCONTEXT
select UCLIBC_HAS_FPU
select UCLIBC_HAS_FENV
select UCLIBC_HAS_WCHAR
diff --git a/include/libintl.h b/include/libintl.h
index b7123a963..6d8b9f342 100644
--- a/include/libintl.h
+++ b/include/libintl.h
@@ -50,9 +50,6 @@ char *bindtextdomain(const char *domainname, const char *dirname);
#endif
-#include <stdio.h>
-#define gettext_printf(args...) printf(args)
-
/* to supply LC_MESSAGES and other stuff GNU expects to be exported when
including libintl.h */
#include <locale.h>
diff --git a/include/netdb.h b/include/netdb.h
index a85797956..26c999e59 100644
--- a/include/netdb.h
+++ b/include/netdb.h
@@ -689,7 +689,7 @@ extern const char *gai_strerror (int __ecode) __THROW;
extern int getnameinfo (const struct sockaddr *__restrict __sa,
socklen_t __salen, char *__restrict __host,
socklen_t __hostlen, char *__restrict __serv,
- socklen_t __servlen, unsigned int __flags);
+ socklen_t __servlen, int __flags);
libc_hidden_proto(getnameinfo)
#endif /* POSIX */
diff --git a/include/pty.h b/include/pty.h
index f23a260ae..609ac2459 100644
--- a/include/pty.h
+++ b/include/pty.h
@@ -31,13 +31,15 @@ __BEGIN_DECLS
attributes according to TERMP and WINP and return handles for both
ends in AMASTER and ASLAVE. */
extern int openpty (int *__amaster, int *__aslave, char *__name,
- struct termios *__termp, struct winsize *__winp) __THROW;
+ const struct termios *__termp,
+ const struct winsize *__winp) __THROW;
libutil_hidden_proto(openpty)
/* Create child process and establish the slave pseudo terminal as the
child's controlling terminal. */
extern int forkpty (int *__amaster, char *__name,
- struct termios *__termp, struct winsize *__winp) __THROW;
+ const struct termios *__termp,
+ const struct winsize *__winp) __THROW;
__END_DECLS
diff --git a/ldso/ldso/aarch64/elfinterp.c b/ldso/ldso/aarch64/elfinterp.c
index 9365569cc..d8530ecd1 100644
--- a/ldso/ldso/aarch64/elfinterp.c
+++ b/ldso/ldso/aarch64/elfinterp.c
@@ -227,13 +227,13 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope,
#else
if (!TRY_STATIC_TLS ((struct link_map *) tls_tpnt))
{
- td->arg = _dl_make_tlsdesc_dynamic((struct link_map *) tls_tpnt, symbol_addr);
+ td->arg = _dl_make_tlsdesc_dynamic((struct link_map *) tls_tpnt, symbol_addr + rpnt->r_addend);
td->entry = _dl_tlsdesc_dynamic;
}
else
#endif
{
- td->arg = (void*)(symbol_addr + tls_tpnt->l_tls_offset);
+ td->arg = (void*)(symbol_addr + tls_tpnt->l_tls_offset + rpnt->r_addend);
td->entry = _dl_tlsdesc_return;
}
}
diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c
index 130a9a505..44685e6b8 100644
--- a/libc/inet/resolv.c
+++ b/libc/inet/resolv.c
@@ -1892,7 +1892,7 @@ int getnameinfo(const struct sockaddr *sa,
socklen_t hostlen,
char *serv,
socklen_t servlen,
- unsigned flags)
+ int flags)
{
int serrno = errno;
bool ok = 0;
diff --git a/libc/misc/sysvipc/ipc.h b/libc/misc/sysvipc/ipc.h
index b342dc1cf..58a690ee3 100644
--- a/libc/misc/sysvipc/ipc.h
+++ b/libc/misc/sysvipc/ipc.h
@@ -1,12 +1,19 @@
#ifndef IPC_H
#define IPC_H
#include <syscall.h>
+#include <bits/kernel-features.h>
#include <bits/wordsize.h>
#ifndef __ARCH_HAS_DEPRECATED_SYSCALLS__
# define __IPC_64 0x0
+#elif defined __mips__ || defined __m68k__
+# if __LINUX_KERNEL_VERSION < 0x050100
+# define __IPC_64 0x100
+# else
+# define __IPC_64 0x0
+# endif
#else
-# if __WORDSIZE == 32 || defined __alpha__ || defined __mips__
+# if __WORDSIZE == 32 || defined __alpha__
# define __IPC_64 0x100
# else
# define __IPC_64 0x0
diff --git a/libc/misc/sysvipc/msgq.c b/libc/misc/sysvipc/msgq.c
index 185cd268b..2d8bcae99 100644
--- a/libc/misc/sysvipc/msgq.c
+++ b/libc/misc/sysvipc/msgq.c
@@ -1,5 +1,6 @@
#include <errno.h>
#include <sys/msg.h>
+#include <stddef.h>
#include "ipc.h"
#ifdef __UCLIBC_HAS_THREADS_NATIVE__
#include "sysdep-cancel.h"
@@ -7,6 +8,12 @@
#define SINGLE_THREAD_P 1
#endif
+#if defined(__UCLIBC_USE_TIME64__)
+union msqun {
+ struct msqid_ds* buff;
+ void *__pad;
+};
+#endif
#ifdef L_msgctl
@@ -18,9 +25,19 @@ static __inline__ _syscall3(int, __libc_msgctl, int, msqid, int, cmd, struct msq
int msgctl(int msqid, int cmd, struct msqid_ds *buf)
{
#ifdef __NR_msgctl
- return __libc_msgctl(msqid, cmd | __IPC_64, buf);
+ int __ret = __libc_msgctl(msqid, cmd | __IPC_64, buf);
+#if (__WORDSIZE == 32) && defined(__UCLIBC_USE_TIME64__) && (defined(__mips) || defined(__riscv))
+ union msqun arg = {.buff = buf};
+ // When cmd is IPC_RMID, buf should be NULL.
+ if (arg.__pad != NULL) {
+ arg.buff->msg_stime = (__time_t)arg.buff->msg_stime_internal_1 | (__time_t)(arg.buff->msg_stime_internal_2) << 32;
+ arg.buff->msg_rtime = (__time_t)arg.buff->msg_rtime_internal_1 | (__time_t)(arg.buff->msg_rtime_internal_2) << 32;
+ arg.buff->msg_ctime = (__time_t)arg.buff->msg_ctime_internal_1 | (__time_t)(arg.buff->msg_ctime_internal_2) << 32;
+ }
+#endif
+ return __ret;
#else
- return __syscall_ipc(IPCOP_msgctl, msqid, cmd | __IPC_64, 0, buf, 0);
+ return __syscall_ipc(IPCOP_msgctl, msqid, cmd | __IPC_64, 0, buf, 0);
#endif
}
#endif
diff --git a/libc/misc/sysvipc/sem.c b/libc/misc/sysvipc/sem.c
index 07076eff7..66f86f53c 100644
--- a/libc/misc/sysvipc/sem.c
+++ b/libc/misc/sysvipc/sem.c
@@ -57,9 +57,14 @@ int semctl(int semid, int semnum, int cmd, ...)
va_end (ap);
#ifdef __NR_semctl
int __ret = __semctl(semid, semnum, cmd | __IPC_64, arg.__pad);
-#if defined(__UCLIBC_USE_TIME64__)
- arg.buf->sem_otime = (__time_t)arg.buf->__sem_otime_internal_1 | (__time_t)(arg.buf->__sem_otime_internal_2) << 32;
- arg.buf->sem_ctime = (__time_t)arg.buf->__sem_ctime_internal_1 | (__time_t)(arg.buf->__sem_ctime_internal_2) << 32;
+#if (__WORDSIZE == 32) && defined(__UCLIBC_USE_TIME64__)
+ // Only when cmd is IPC_STAT and IPC_SET, semun points to struct semid_ds.
+ // At this point, arg.__pad should not be NULL, but a check is added just
+ // to be safe.
+ if ((cmd & (IPC_STAT | IPC_SET)) && (arg.__pad != NULL)) {
+ arg.buf->sem_otime = (__time_t)arg.buf->__sem_otime_internal_1 | (__time_t)(arg.buf->__sem_otime_internal_2) << 32;
+ arg.buf->sem_ctime = (__time_t)arg.buf->__sem_ctime_internal_1 | (__time_t)(arg.buf->__sem_ctime_internal_2) << 32;
+ }
#endif
return __ret;
#else
diff --git a/libc/misc/sysvipc/shm.c b/libc/misc/sysvipc/shm.c
index cd46ff0dd..b3366b301 100644
--- a/libc/misc/sysvipc/shm.c
+++ b/libc/misc/sysvipc/shm.c
@@ -25,6 +25,13 @@
#include <syscall.h>
#include "ipc.h"
+#if defined(__UCLIBC_USE_TIME64__)
+union shmun {
+ struct shmid_ds* buff;
+ void *__pad;
+};
+#endif
+
#ifdef L_shmat
/* Attach the shared memory segment associated with SHMID to the data
segment of the calling process. SHMADDR and SHMFLG determine how
@@ -59,7 +66,17 @@ static __always_inline _syscall3(int, __syscall_shmctl, int, shmid, int, cmd, st
int shmctl(int shmid, int cmd, struct shmid_ds *buf)
{
#ifdef __NR_shmctl
- return __syscall_shmctl(shmid, cmd | __IPC_64, buf);
+ int __ret = __syscall_shmctl(shmid, cmd | __IPC_64, buf);
+#if (__WORDSIZE == 32) && defined(__mips) && defined(__UCLIBC_USE_TIME64__)
+ union shmun arg = {.buff = buf};
+ // When cmd is IPC_RMID, buf should be NULL.
+ if (arg.__pad != NULL) {
+ arg.buff->shm_atime = (__time_t)arg.buff->shm_atime_internal_1 | (__time_t)(arg.buff->shm_atime_internal_2) << 32;
+ arg.buff->shm_dtime = (__time_t)arg.buff->shm_dtime_internal_1 | (__time_t)(arg.buff->shm_dtime_internal_2) << 32;
+ arg.buff->shm_ctime = (__time_t)arg.buff->shm_ctime_internal_1 | (__time_t)(arg.buff->shm_ctime_internal_2) << 32;
+ }
+#endif
+ return __ret;
#else
return __syscall_ipc(IPCOP_shmctl, shmid, cmd | __IPC_64, 0, buf, 0);
#endif
diff --git a/libc/stdlib/malloc-standard/malloc.c b/libc/stdlib/malloc-standard/malloc.c
index cecea87ec..e51bc6610 100644
--- a/libc/stdlib/malloc-standard/malloc.c
+++ b/libc/stdlib/malloc-standard/malloc.c
@@ -29,7 +29,7 @@ __UCLIBC_MUTEX_INIT(__malloc_lock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
struct malloc_state __malloc_state; /* never directly referenced */
/* forward declaration */
-static int __malloc_largebin_index(unsigned int sz);
+static int __malloc_largebin_index(unsigned long sz);
#ifdef __UCLIBC_MALLOC_DEBUGGING__
@@ -755,10 +755,10 @@ static void* __malloc_alloc(size_t nb, mstate av)
Compute index for size. We expect this to be inlined when
compiled with optimization, else not, which works out well.
*/
-static int __malloc_largebin_index(unsigned int sz)
+static int __malloc_largebin_index(unsigned long sz)
{
- unsigned int x = sz >> SMALLBIN_WIDTH;
- unsigned int m; /* bit position of highest set bit of m */
+ unsigned long x = sz >> SMALLBIN_WIDTH;
+ unsigned long m; /* bit position of highest set bit of m */
if (x >= 0x10000) return NBINS-1;
@@ -776,7 +776,7 @@ static int __malloc_largebin_index(unsigned int sz)
S. Warren Jr's book "Hacker's Delight".
*/
- unsigned int n = ((x - 0x100) >> 16) & 8;
+ unsigned long n = ((x - 0x100) >> 16) & 8;
x <<= n;
m = ((x - 0x1000) >> 16) & 4;
n += m;
diff --git a/libc/sysdeps/linux/aarch64/bits/shm.h b/libc/sysdeps/linux/aarch64/bits/shm.h
new file mode 100644
index 000000000..bfb603499
--- /dev/null
+++ b/libc/sysdeps/linux/aarch64/bits/shm.h
@@ -0,0 +1,87 @@
+/*
+ * Licensed under the LGPL v2.1 or later, see the file COPYING.LIB
+ * in this tarball.
+ */
+
+#ifndef _SYS_SHM_H
+# error "Never include <bits/shm.h> directly; use <sys/shm.h> instead."
+#endif
+
+#include <bits/types.h>
+
+/* Permission flag for shmget. */
+#define SHM_R 0400 /* or S_IRUGO from <linux/stat.h> */
+#define SHM_W 0200 /* or S_IWUGO from <linux/stat.h> */
+
+/* Flags for `shmat'. */
+#define SHM_RDONLY 010000 /* attach read-only else read-write */
+#define SHM_RND 020000 /* round attach address to SHMLBA */
+#define SHM_REMAP 040000 /* take-over region on attach */
+
+/* Commands for `shmctl'. */
+#define SHM_LOCK 11 /* lock segment (root only) */
+#define SHM_UNLOCK 12 /* unlock segment (root only) */
+
+__BEGIN_DECLS
+
+/* Segment low boundary address multiple. */
+#define SHMLBA (__getpagesize () << 2)
+extern int __getpagesize (void) __THROW __attribute__ ((__const__));
+
+
+/* Type to count number of attaches. */
+typedef unsigned long int shmatt_t;
+
+/* Data structure describing a set of semaphores. */
+struct shmid_ds
+ {
+ struct ipc_perm shm_perm; /* operation permission struct */
+ size_t shm_segsz; /* size of segment in bytes */
+ __time_t shm_atime; /* time of last shmat() */
+ __time_t shm_dtime; /* time of last shmdt() */
+ __time_t shm_ctime; /* time of last change by shmctl() */
+ __pid_t shm_cpid; /* pid of creator */
+ __pid_t shm_lpid; /* pid of last shmop */
+ shmatt_t shm_nattch; /* number of current attaches */
+ unsigned long int __uclibc_unused1;
+ unsigned long int __uclibc_unused2;
+ };
+
+#ifdef __USE_MISC
+
+/* ipcs ctl commands */
+# define SHM_STAT 13
+# define SHM_INFO 14
+
+/* shm_mode upper byte flags */
+# define SHM_DEST 01000 /* segment will be destroyed on last detach */
+# define SHM_LOCKED 02000 /* segment will not be swapped */
+# define SHM_HUGETLB 04000 /* segment is mapped via hugetlb */
+# define SHM_NORESERVE 010000 /* don't check for reservations */
+
+struct shminfo
+ {
+ unsigned long int shmmax;
+ unsigned long int shmmin;
+ unsigned long int shmmni;
+ unsigned long int shmseg;
+ unsigned long int shmall;
+ unsigned long int __uclibc_unused1;
+ unsigned long int __uclibc_unused2;
+ unsigned long int __uclibc_unused3;
+ unsigned long int __uclibc_unused4;
+ };
+
+struct shm_info
+ {
+ int used_ids;
+ unsigned long int shm_tot; /* total allocated shm */
+ unsigned long int shm_rss; /* total resident shm */
+ unsigned long int shm_swp; /* total swapped shm */
+ unsigned long int swap_attempts;
+ unsigned long int swap_successes;
+ };
+
+#endif /* __USE_MISC */
+
+__END_DECLS
diff --git a/libc/sysdeps/linux/arc/bits/fenv.h b/libc/sysdeps/linux/arc/bits/fenv.h
new file mode 100644
index 000000000..c5c76cb93
--- /dev/null
+++ b/libc/sysdeps/linux/arc/bits/fenv.h
@@ -0,0 +1,75 @@
+/* Floating point environment. ARC version.
+ Copyright (C) 2020-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 _FENV_H
+# error "Never use <bits/fenv.h> directly; include <fenv.h> instead."
+#endif
+
+enum
+ {
+ FE_INVALID =
+# define FE_INVALID (0x01)
+ FE_INVALID,
+ FE_DIVBYZERO =
+# define FE_DIVBYZERO (0x02)
+ FE_DIVBYZERO,
+ FE_OVERFLOW =
+# define FE_OVERFLOW (0x04)
+ FE_OVERFLOW,
+ FE_UNDERFLOW =
+# define FE_UNDERFLOW (0x08)
+ FE_UNDERFLOW,
+ FE_INEXACT =
+# define FE_INEXACT (0x10)
+ FE_INEXACT
+ };
+
+# define FE_ALL_EXCEPT \
+ (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT)
+
+enum
+ {
+ FE_TOWARDZERO =
+# define FE_TOWARDZERO (0x0)
+ FE_TOWARDZERO,
+ FE_TONEAREST =
+# define FE_TONEAREST (0x1) /* default */
+ FE_TONEAREST,
+ FE_UPWARD =
+# define FE_UPWARD (0x2)
+ FE_UPWARD,
+ FE_DOWNWARD =
+# define FE_DOWNWARD (0x3)
+ FE_DOWNWARD
+ };
+
+typedef unsigned int fexcept_t;
+
+typedef struct
+{
+ unsigned int __fpcr;
+ unsigned int __fpsr;
+} fenv_t;
+
+/* If the default argument is used we use this value. */
+#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)
diff --git a/libc/sysdeps/linux/arc/fpu_control.h b/libc/sysdeps/linux/arc/fpu_control.h
new file mode 100644
index 000000000..e833de3aa
--- /dev/null
+++ b/libc/sysdeps/linux/arc/fpu_control.h
@@ -0,0 +1,104 @@
+/* FPU control word bits. ARC version.
+ Copyright (C) 2020-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
+
+/* ARC FPU control register bits.
+
+ [ 0] -> IVE: Enable invalid operation exception.
+ if 0, soft exception: status register IV flag set.
+ if 1, hardware exception trap (not supported in Linux yet).
+ [ 1] -> DZE: Enable division by zero exception.
+ if 0, soft exception: status register IV flag set.
+ if 1, hardware exception: (not supported in Linux yet).
+ [9:8] -> RM: Rounding Mode:
+ 00 - Rounding toward zero.
+ 01 - Rounding to nearest (default).
+ 10 - Rounding (up) toward plus infinity.
+ 11 - Rounding (down)toward minus infinity.
+
+ ARC FPU status register bits.
+
+ [ 0] -> IV: flag invalid operation.
+ [ 1] -> DZ: flag division by zero.
+ [ 2] -> OV: flag Overflow operation.
+ [ 3] -> UV: flag Underflow operation.
+ [ 4] -> IX: flag Inexact operation.
+ [31] -> FWE: Flag Write Enable.
+ If 1, above flags writable explicitly (clearing),
+ else IoW and only writable indirectly via bits [12:7]. */
+
+#include <features.h>
+
+#if !defined(__ARC_FPU_SP__) && !defined(__ARC_FPU_DP__)
+
+# 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)
+# define _FPU_GETS(cw) (cw) = 0
+# define _FPU_SETS(cw) (void) (cw)
+extern fpu_control_t __fpu_control;
+
+#else
+
+#define _FPU_RESERVED 0
+
+/* The fdlibm code requires strict IEEE double precision arithmetic,
+ and no interrupts for exceptions, rounding to nearest.
+ So only RM set to b'01. */
+# define _FPU_DEFAULT 0x00000100
+
+/* Actually default needs to have FWE bit as 1 but that is already
+ ingrained into _FPU_SETS macro below. */
+#define _FPU_FPSR_DEFAULT 0x00000000
+
+#define __FPU_RND_SHIFT 8
+#define __FPU_RND_MASK 0x3
+
+/* Type of the control word. */
+typedef unsigned int fpu_control_t;
+
+/* Macros for accessing the hardware control word. */
+# define _FPU_GETCW(cw) __asm__ volatile ("lr %0, [0x300]" : "=r" (cw))
+# define _FPU_SETCW(cw) __asm__ volatile ("sr %0, [0x300]" : : "r" (cw))
+
+/* Macros for accessing the hardware status word.
+ Writing to FPU_STATUS requires a "control" bit FWE to be able to set the
+ exception flags directly (as opposed to side-effects of FP instructions).
+ That is done in the macro here to keeps callers agnostic of this detail.
+ And given FWE is write-only and RAZ, no need to "clear" it in _FPU_GETS
+ macro. */
+# define _FPU_GETS(cw) \
+ __asm__ volatile ("lr %0, [0x301] \r\n" \
+ : "=r" (cw))
+
+# define _FPU_SETS(cw) \
+ do { \
+ unsigned int __fwe = 0x80000000 | (cw); \
+ __asm__ volatile ("sr %0, [0x301] \r\n" \
+ : : "r" (__fwe)); \
+ } while (0)
+
+/* Default control word set at startup. */
+extern fpu_control_t __fpu_control;
+
+#endif
+
+#endif /* fpu_control.h */
diff --git a/libc/sysdeps/linux/arm/bits/shm.h b/libc/sysdeps/linux/arm/bits/shm.h
index 86245faff..aa1a72e54 100644
--- a/libc/sysdeps/linux/arm/bits/shm.h
+++ b/libc/sysdeps/linux/arm/bits/shm.h
@@ -49,12 +49,18 @@ struct shmid_ds
{
struct ipc_perm shm_perm; /* operation permission struct */
size_t shm_segsz; /* size of segment in bytes */
+#if defined(__UCLIBC_USE_TIME64__)
+ __time_t shm_atime;
+ __time_t shm_dtime;
+ __time_t shm_ctime;
+#else
__time_t shm_atime; /* time of last shmat() */
unsigned long int __uclibc_unused1;
__time_t shm_dtime; /* time of last shmdt() */
unsigned long int __uclibc_unused2;
__time_t shm_ctime; /* time of last change by shmctl() */
unsigned long int __uclibc_unused3;
+#endif
__pid_t shm_cpid; /* pid of creator */
__pid_t shm_lpid; /* pid of last shmop */
shmatt_t shm_nattch; /* number of current attaches */
diff --git a/libc/sysdeps/linux/common/Makefile.in b/libc/sysdeps/linux/common/Makefile.in
index e0b280c33..4a4317432 100644
--- a/libc/sysdeps/linux/common/Makefile.in
+++ b/libc/sysdeps/linux/common/Makefile.in
@@ -27,6 +27,7 @@ CSRC-$(UCLIBC_LINUX_SPECIFIC) += \
eventfd_write.c \
fanotify.c \
getrandom.c \
+ getentropy.c \
inotify.c \
ioperm.c \
iopl.c \
diff --git a/libc/sysdeps/linux/common/bits/msq.h b/libc/sysdeps/linux/common/bits/msq.h
index b594cfff2..0cb734263 100644
--- a/libc/sysdeps/linux/common/bits/msq.h
+++ b/libc/sysdeps/linux/common/bits/msq.h
@@ -37,17 +37,31 @@ typedef unsigned long int msglen_t;
struct msqid_ds
{
struct ipc_perm msg_perm; /* structure describing operation permission */
+#if (__WORDSIZE == 32 && defined(__riscv) && defined(__UCLIBC_USE_TIME64__))
+ unsigned long int msg_stime_internal_1;
+ unsigned long int msg_stime_internal_2;
+ unsigned long int msg_rtime_internal_1;
+ unsigned long int msg_rtime_internal_2;
+ unsigned long int msg_ctime_internal_1;
+ unsigned long int msg_ctime_internal_2;
+#else
__time_t msg_stime; /* time of last msgsnd command */
unsigned long int __uclibc_unused1;
__time_t msg_rtime; /* time of last msgrcv command */
unsigned long int __uclibc_unused2;
__time_t msg_ctime; /* time of last change */
unsigned long int __uclibc_unused3;
+#endif
unsigned long int __msg_cbytes; /* current number of bytes on queue */
msgqnum_t msg_qnum; /* number of messages currently on queue */
msglen_t msg_qbytes; /* max number of bytes allowed on queue */
__pid_t msg_lspid; /* pid of last msgsnd() */
__pid_t msg_lrpid; /* pid of last msgrcv() */
+#if (__WORDSIZE == 32 && defined(__riscv) && defined(__UCLIBC_USE_TIME64__))
+ __time_t msg_stime; /* time of last msgsnd command */
+ __time_t msg_rtime; /* time of last msgrcv command */
+ __time_t msg_ctime; /* time of last change */
+#endif
unsigned long int __uclibc_unused4;
unsigned long int __uclibc_unused5;
};
diff --git a/libc/sysdeps/linux/common/bits/sem.h b/libc/sysdeps/linux/common/bits/sem.h
index 24a130981..d855494ee 100644
--- a/libc/sysdeps/linux/common/bits/sem.h
+++ b/libc/sysdeps/linux/common/bits/sem.h
@@ -45,8 +45,8 @@ struct semid_ds
#else
__time_t sem_otime; /* last semop() time */
#endif
-#if (__WORDSIZE == 32 && !defined(__ARC64_ARCH32__) && !defined(__arc__) && !defined(__arm__) && !defined(__or1k__) && !defined(__xtensa__)) || \
- ((defined(__ARC64_ARCH32__) || defined(__arc__) || defined(__arm__) || defined(__or1k__) || defined(__xtensa__)) && !defined(__UCLIBC_USE_TIME64__))
+#if (__WORDSIZE == 32 && !defined(__ARC64_ARCH32__) && !defined(__arc__) && !defined(__arm__) && !defined(__or1k__) && !defined(__xtensa__) && !defined(__riscv)) || \
+ ((defined(__ARC64_ARCH32__) || defined(__arc__) || defined(__arm__) || defined(__or1k__) || defined(__xtensa__) || defined(__riscv)) && !defined(__UCLIBC_USE_TIME64__))
unsigned long int __uclibc_unused1;
#endif
#if defined(__UCLIBC_USE_TIME64__)
@@ -55,8 +55,8 @@ struct semid_ds
#else
__time_t sem_ctime; /* last time changed by semctl() */
#endif
-#if (__WORDSIZE == 32 && !defined(__ARC64_ARCH32__) && !defined(__arc__) && !defined(__arm__) && !defined(__or1k__) && !defined(__xtensa__)) || \
- ((defined(__ARC64_ARCH32__) || defined(__arc__) || defined(__arm__) || defined(__or1k__) || defined(__xtensa__)) && !defined(__UCLIBC_USE_TIME64__))
+#if (__WORDSIZE == 32 && !defined(__ARC64_ARCH32__) && !defined(__arc__) && !defined(__arm__) && !defined(__or1k__) && !defined(__xtensa__) && !defined(__riscv)) || \
+ ((defined(__ARC64_ARCH32__) || defined(__arc__) || defined(__arm__) || defined(__or1k__) || defined(__xtensa__) || defined(__riscv)) && !defined(__UCLIBC_USE_TIME64__))
unsigned long int __uclibc_unused2;
#endif
unsigned long int sem_nsems; /* number of semaphores in set */
diff --git a/libc/sysdeps/linux/common/bits/typesizes.h b/libc/sysdeps/linux/common/bits/typesizes.h
index dcb2c3b0a..074758701 100644
--- a/libc/sysdeps/linux/common/bits/typesizes.h
+++ b/libc/sysdeps/linux/common/bits/typesizes.h
@@ -73,5 +73,15 @@
/* Number of descriptors that can fit in an `fd_set'. */
#define __FD_SETSIZE 1024
+#if __WORDSIZE == 64
+/* Tell the code that off_t and off64_t are actually the same type
+ for all ABI purposes, even if possibly expressed as different base types
+ for C type-checking purposes. */
+# define __OFF_T_MATCHES_OFF64_T 1
+
+/* Same for ino_t and ino64_t. */
+# define __INO_T_MATCHES_INO64_T 1
+
+#endif
#endif /* bits/typesizes.h */
diff --git a/libc/sysdeps/linux/common/getentropy.c b/libc/sysdeps/linux/common/getentropy.c
index 55bd48a12..d255310b6 100644
--- a/libc/sysdeps/linux/common/getentropy.c
+++ b/libc/sysdeps/linux/common/getentropy.c
@@ -12,6 +12,7 @@
#include <errno.h>
#include <unistd.h>
#include <sys/random.h>
+#include <sys/syscall.h>
#ifdef __NR_getrandom
int
diff --git a/libc/sysdeps/linux/common/utimes.c b/libc/sysdeps/linux/common/utimes.c
index a28594dfd..c471a9b89 100644
--- a/libc/sysdeps/linux/common/utimes.c
+++ b/libc/sysdeps/linux/common/utimes.c
@@ -9,7 +9,7 @@
#include <sys/syscall.h>
#include <sys/time.h>
-#if (defined (__NR_utimensat) || defined(__NR_utimensat_time64)) && !defined __NR_utimes
+#if (defined (__NR_utimensat) || defined(__NR_utimensat_time64)) && (!defined __NR_utimes || defined(__UCLIBC_USE_TIME64__))
# include <fcntl.h>
# include <stddef.h>
int utimes(const char *file, const struct timeval tvp[2])
@@ -50,6 +50,6 @@ int utimes(const char *file, const struct timeval tvp[2])
}
#endif
-#if defined __NR_utimensat || defined __NR_utimensat_time64 || defined __NR_utimes || defined __NR_utime
+#if (((defined __NR_utimensat || defined __NR_utimensat_time64) && (!defined __NR_utimes || defined __UCLIBC_USE_TIME64__))) || defined __NR_utimes || defined __NR_utime
libc_hidden_def(utimes)
#endif
diff --git a/libc/sysdeps/linux/csky/bits/fenv.h b/libc/sysdeps/linux/csky/bits/fenv.h
index 3359e1f8e..1428f385a 100644
--- a/libc/sysdeps/linux/csky/bits/fenv.h
+++ b/libc/sysdeps/linux/csky/bits/fenv.h
@@ -1,65 +1,108 @@
-/*
- * Copyright (C) 2017 Hangzhou C-SKY Microsystems co.,ltd.
- *
- * Licensed under the LGPL v2.1 or later, see the file COPYING.LIB
- * in this tarball.
- */
+/* Floating point environment. C-SKY version.
+ Copyright (C) 2018-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 _FENV_H
# error "Never use <bits/fenv.h> directly; include <fenv.h> instead."
#endif
-/* Define bits representing the exception. We use the bit positions of
- the appropriate bits in the FPSR Accrued Exception Byte. */
+#ifdef __csky_hard_float__
+/* Define bits representing the exception. We use the bit positions
+ of the appropriate bits in the FPU control word. */
enum
{
- FE_INEXACT = 1 << 3,
-#define FE_INEXACT FE_INEXACT
- FE_DIVBYZERO = 1 << 4,
-#define FE_DIVBYZERO FE_DIVBYZERO
- FE_UNDERFLOW = 1 << 5,
-#define FE_UNDERFLOW FE_UNDERFLOW
- FE_OVERFLOW = 1 << 6,
-#define FE_OVERFLOW FE_OVERFLOW
- FE_INVALID = 1 << 7
-#define FE_INVALID FE_INVALID
+ FE_INVALID =
+#define FE_INVALID 0x01
+ FE_INVALID,
+ FE_DIVBYZERO =
+#define FE_DIVBYZERO 0x02
+ FE_DIVBYZERO,
+ FE_OVERFLOW =
+#define FE_OVERFLOW 0x04
+ FE_OVERFLOW,
+ FE_UNDERFLOW =
+#define FE_UNDERFLOW 0x08
+ FE_UNDERFLOW,
+ FE_INEXACT =
+#define FE_INEXACT 0x10
+ FE_INEXACT,
+ __FE_DENORMAL = 0x20
};
#define FE_ALL_EXCEPT \
(FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID)
-/* The csky FPU supports all of the four defined rounding modes. We use
- the bit positions in the FPCR Mode Control Byte as the values for the
- appropriate macros. */
+/* The C-SKY 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. */
+enum
+ {
+ FE_TONEAREST =
+#define FE_TONEAREST (0x0 << 24)
+ FE_TONEAREST,
+ FE_TOWARDZERO =
+#define FE_TOWARDZERO (0x1 << 24)
+ FE_TOWARDZERO,
+ FE_UPWARD =
+#define FE_UPWARD (0x2 << 24)
+ FE_UPWARD,
+ FE_DOWNWARD =
+#define FE_DOWNWARD (0x3 << 24)
+ FE_DOWNWARD,
+ __FE_ROUND_MASK = (0x3 << 24)
+ };
+
+#else
+
+/* In the soft-float case, only rounding to nearest is supported, with
+ no exceptions. */
+
enum
{
- FE_TONEAREST = 0,
-#define FE_TONEAREST FE_TONEAREST
- FE_TOWARDZERO = 1 << 4,
-#define FE_TOWARDZERO FE_TOWARDZERO
- FE_DOWNWARD = 2 << 4,
-#define FE_DOWNWARD FE_DOWNWARD
- FE_UPWARD = 3 << 4
-#define FE_UPWARD FE_UPWARD
+ __FE_UNDEFINED = -1,
+
+ FE_TONEAREST =
+# define FE_TONEAREST 0x0
+ FE_TONEAREST
};
+# define FE_ALL_EXCEPT 0
+
+#endif
+
/* Type representing exception flags. */
typedef unsigned int fexcept_t;
-/* Type representing floating-point environment. This structure
- corresponds to the layout of the block written by `fmovem'. */
+/* Type representing floating-point environment. */
typedef struct
- {
- unsigned int __control_register;
- unsigned int __status_register;
- unsigned int __instruction_address;
- }
-fenv_t;
+{
+ unsigned int __fpcr;
+ unsigned int __fpsr;
+} fenv_t;
/* If the default argument is used we use this value. */
-#define FE_DFL_ENV ((__const fenv_t *) -1)
+#define FE_DFL_ENV ((const fenv_t *) -1)
-#ifdef __USE_GNU
+#if defined __USE_GNU && defined __csky_hard_float__
/* Floating-point environment where none of the exceptions are masked. */
-# define FE_NOMASK_ENV ((__const fenv_t *) -2)
+# define FE_NOMASK_ENV ((const fenv_t *) -2)
#endif
+
+/* Type representing floating-point control modes. */
+typedef unsigned int femode_t;
+
+/* Default floating-point control modes. */
+# define FE_DFL_MODE ((const femode_t *) -1L)
diff --git a/libc/sysdeps/linux/csky/fpu_control.h b/libc/sysdeps/linux/csky/fpu_control.h
new file mode 100644
index 000000000..a2d615554
--- /dev/null
+++ b/libc/sysdeps/linux/csky/fpu_control.h
@@ -0,0 +1,147 @@
+/* FPU control word bits. C-SKY version.
+ Copyright (C) 2018-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
+
+/* C-SKY FPU floating point control register bits.
+
+ 31-28 -> Reserved (read as 0, write with 0).
+ 27 -> 0: Flush denormalized results to zero.
+ 1: Flush denormalized results to signed minimal normal number.
+ 26 -> Reserved (read as 0, write with 0).
+ 25-24 -> Rounding control.
+ 23-6 -> Reserved (read as 0, write with 0).
+ 5 -> Enable exception for input denormalized exception.
+ 4 -> Enable exception for inexact exception.
+ 3 -> Enable exception for underflow exception.
+ 2 -> Enable exception for overflow exception.
+ 1 -> Enable exception for division by zero exception.
+ 0 -> Enable exception for invalid operation exception.
+
+ Rounding Control:
+ 00 - Rounding to nearest (RN).
+ 01 - Rounding toward zero (RZ).
+ 10 - Rounding (up) toward plus infinity (RP).
+ 11 - Rounding (down)toward minus infinity (RM).
+
+ C-SKY FPU floating point exception status register bits.
+
+ 15 -> Accumulate bit for any exception.
+ 14 -> Reserved (read as 0, write with 0).
+ 13 -> Cause bit for input denormalized exception.
+ 12 -> Cause bit for inexact exception.
+ 11 -> Cause bit for underflow exception.
+ 10 -> Cause bit for overflow exception.
+ 9 -> Cause bit for division by zero exception.
+ 8 -> Cause bit for invalid operation exception.
+ 7 -> Flag bit for any exception.
+ 6 -> Reserved (read as 0, write with 0).
+ 5 -> Flag exception for input denormalized exception.
+ 4 -> Flag exception for inexact exception.
+ 3 -> Flag exception for underflow exception.
+ 2 -> Flag exception for overflow exception.
+ 1 -> Flag exception for division by zero exception.
+ 0 -> Flag exception for invalid operation exception. */
+
+#include <features.h>
+
+#ifdef __csky_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)
+# define _FPU_GETFPSR(cw) (cw) = 0
+# define _FPU_SETFPSR(cw) (void) (cw)
+extern fpu_control_t __fpu_control;
+
+#else /* __csky_soft_float__ */
+
+/* Masking of interrupts. */
+# define _FPU_MASK_IDE (1 << 5) /* Input denormalized exception. */
+# define _FPU_MASK_IXE (1 << 4) /* Inexact exception. */
+# define _FPU_MASK_UFE (1 << 3) /* Underflow exception. */
+# define _FPU_MASK_OFE (1 << 2) /* Overflow exception. */
+# define _FPU_MASK_DZE (1 << 1) /* Division by zero exception. */
+# define _FPU_MASK_IOE (1 << 0) /* Invalid operation exception. */
+
+# define _FPU_MASK_FEA (1 << 15) /* Case for any exception. */
+# define _FPU_MASK_FEC (1 << 7) /* Flag for any exception. */
+
+/* Flush denormalized numbers to zero. */
+# define _FPU_FLUSH_TZ 0x8000000
+
+/* Rounding control. */
+# define _FPU_RC_NEAREST (0x0 << 24) /* RECOMMENDED. */
+# define _FPU_RC_ZERO (0x1 << 24)
+# define _FPU_RC_UP (0x2 << 24)
+# define _FPU_RC_DOWN (0x3 << 24)
+
+# define _FPU_RESERVED 0xf460ffc0 /* Reserved bits in cw. */
+# define _FPU_FPSR_RESERVED 0xffff4040
+
+/* The fdlibm code requires strict IEEE double precision arithmetic,
+ and no interrupts for exceptions, rounding to nearest. */
+
+# define _FPU_DEFAULT 0x00000000
+# define _FPU_FPSR_DEFAULT 0x00000000
+
+/* IEEE: same as above, but exceptions. */
+# define _FPU_FPCR_IEEE 0x0000001F
+# define _FPU_FPSR_IEEE 0x00000000
+
+/* Type of the control word. */
+typedef unsigned int fpu_control_t;
+
+/* Macros for accessing the hardware control word. */
+# if (__CSKY__ == 2)
+# define _FPU_GETCW(cw) __asm__ volatile ("mfcr %0, cr<1, 2>" : "=a" (cw))
+# define _FPU_SETCW(cw) __asm__ volatile ("mtcr %0, cr<1, 2>" : : "a" (cw))
+# define _FPU_GETFPSR(cw) __asm__ volatile ("mfcr %0, cr<2, 2>" : "=a" (cw))
+# define _FPU_SETFPSR(cw) __asm__ volatile ("mtcr %0, cr<2, 2>" : : "a" (cw))
+# else
+# define _FPU_GETCW(cw) __asm__ volatile ("1: cprcr %0, cpcr2 \n" \
+ " btsti %0, 31 \n" \
+ " bt 1b \n" \
+ " cprcr %0, cpcr1\n" : "=b" (cw))
+
+# define _FPU_SETCW(cw) __asm__ volatile ("1: cprcr r7, cpcr2 \n" \
+ " btsti r7, 31 \n" \
+ " bt 1b \n" \
+ " cpwcr %0, cpcr1 \n" \
+ : : "b" (cw) : "r7")
+
+# define _FPU_GETFPSR(cw) __asm__ volatile ("1: cprcr %0, cpcr2 \n" \
+ " btsti %0, 31 \n" \
+ " bt 1b \n" \
+ " cprcr %0, cpcr4\n" : "=b" (cw))
+
+# define _FPU_SETFPSR(cw) __asm__ volatile ("1: cprcr r7, cpcr2 \n" \
+ " btsti r7, 31 \n" \
+ " bt 1b \n" \
+ " cpwcr %0, cpcr4 \n" \
+ : : "b" (cw) : "r7")
+# endif /* __CSKY__ != 2 */
+
+/* Default control word set at startup. */
+extern fpu_control_t __fpu_control;
+
+#endif /* !__csky_soft_float__ */
+
+#endif /* fpu_control.h */
diff --git a/libc/sysdeps/linux/kvx/Makefile.arch b/libc/sysdeps/linux/kvx/Makefile.arch
index 3ad290915..18f2118f6 100644
--- a/libc/sysdeps/linux/kvx/Makefile.arch
+++ b/libc/sysdeps/linux/kvx/Makefile.arch
@@ -8,3 +8,5 @@
CSRC-y := __syscall_error.c
CSRC-$(UCLIBC_LINUX_SPECIFIC) += cachectl.c
SSRC-y := setjmp.S bsd-setjmp.S bsd-_setjmp.S __longjmp.S clone.S vfork.S
+CSRC-$(UCLIBC_HAS_CONTEXT_FUNCS) += makecontext.c
+SSRC-$(UCLIBC_HAS_CONTEXT_FUNCS) += getcontext.S setcontext.S swapcontext.S
diff --git a/libc/sysdeps/linux/kvx/bits/shm.h b/libc/sysdeps/linux/kvx/bits/shm.h
new file mode 100644
index 000000000..bfb603499
--- /dev/null
+++ b/libc/sysdeps/linux/kvx/bits/shm.h
@@ -0,0 +1,87 @@
+/*
+ * Licensed under the LGPL v2.1 or later, see the file COPYING.LIB
+ * in this tarball.
+ */
+
+#ifndef _SYS_SHM_H
+# error "Never include <bits/shm.h> directly; use <sys/shm.h> instead."
+#endif
+
+#include <bits/types.h>
+
+/* Permission flag for shmget. */
+#define SHM_R 0400 /* or S_IRUGO from <linux/stat.h> */
+#define SHM_W 0200 /* or S_IWUGO from <linux/stat.h> */
+
+/* Flags for `shmat'. */
+#define SHM_RDONLY 010000 /* attach read-only else read-write */
+#define SHM_RND 020000 /* round attach address to SHMLBA */
+#define SHM_REMAP 040000 /* take-over region on attach */
+
+/* Commands for `shmctl'. */
+#define SHM_LOCK 11 /* lock segment (root only) */
+#define SHM_UNLOCK 12 /* unlock segment (root only) */
+
+__BEGIN_DECLS
+
+/* Segment low boundary address multiple. */
+#define SHMLBA (__getpagesize () << 2)
+extern int __getpagesize (void) __THROW __attribute__ ((__const__));
+
+
+/* Type to count number of attaches. */
+typedef unsigned long int shmatt_t;
+
+/* Data structure describing a set of semaphores. */
+struct shmid_ds
+ {
+ struct ipc_perm shm_perm; /* operation permission struct */
+ size_t shm_segsz; /* size of segment in bytes */
+ __time_t shm_atime; /* time of last shmat() */
+ __time_t shm_dtime; /* time of last shmdt() */
+ __time_t shm_ctime; /* time of last change by shmctl() */
+ __pid_t shm_cpid; /* pid of creator */
+ __pid_t shm_lpid; /* pid of last shmop */
+ shmatt_t shm_nattch; /* number of current attaches */
+ unsigned long int __uclibc_unused1;
+ unsigned long int __uclibc_unused2;
+ };
+
+#ifdef __USE_MISC
+
+/* ipcs ctl commands */
+# define SHM_STAT 13
+# define SHM_INFO 14
+
+/* shm_mode upper byte flags */
+# define SHM_DEST 01000 /* segment will be destroyed on last detach */
+# define SHM_LOCKED 02000 /* segment will not be swapped */
+# define SHM_HUGETLB 04000 /* segment is mapped via hugetlb */
+# define SHM_NORESERVE 010000 /* don't check for reservations */
+
+struct shminfo
+ {
+ unsigned long int shmmax;
+ unsigned long int shmmin;
+ unsigned long int shmmni;
+ unsigned long int shmseg;
+ unsigned long int shmall;
+ unsigned long int __uclibc_unused1;
+ unsigned long int __uclibc_unused2;
+ unsigned long int __uclibc_unused3;
+ unsigned long int __uclibc_unused4;
+ };
+
+struct shm_info
+ {
+ int used_ids;
+ unsigned long int shm_tot; /* total allocated shm */
+ unsigned long int shm_rss; /* total resident shm */
+ unsigned long int shm_swp; /* total swapped shm */
+ unsigned long int swap_attempts;
+ unsigned long int swap_successes;
+ };
+
+#endif /* __USE_MISC */
+
+__END_DECLS
diff --git a/libc/sysdeps/linux/kvx/getcontext.S b/libc/sysdeps/linux/kvx/getcontext.S
new file mode 100644
index 000000000..9440f67ce
--- /dev/null
+++ b/libc/sysdeps/linux/kvx/getcontext.S
@@ -0,0 +1,81 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive for
+ * more details.
+ *
+ * Copyright (C) 2025 Kalray Inc.
+ * Author(s): Julian Vetter <jvetter@kalrayinc.com>
+ */
+
+#include <sysdep.h>
+
+#include "ucontext_i.h"
+
+ .text
+
+/*
+ * int getcontext (ucontext_t *ucp)
+ */
+ENTRY(__getcontext)
+ /* Save callee saved registers ($r14, $r18 - $r31)
+ * and some special registers */
+
+ /* Save the entire occtuple, although we only need $sp and $r14 */
+ so MCONTEXT_Q12[$r0] = $r12r13r14r15
+ get $r4 = $lc
+ ;;
+ /* Don't need to save veneer registers $r16 and $r17 */
+ sq (MCONTEXT_Q16 + 16)[$r0] = $r18r19
+ get $r5 = $le
+ ;;
+ so MCONTEXT_Q20[$r0] = $r20r21r22r23
+ get $r6 = $ls
+ ;;
+ so MCONTEXT_Q24[$r0] = $r24r25r26r27
+ get $r7 = $ra
+ ;;
+ so MCONTEXT_Q28[$r0] = $r28r29r30r31
+ get $r8 = $cs
+ ;;
+ so MCONTEXT_LC_LE_LS_RA[$r0] = $r4r5r6r7
+ /* Save ucp and $ra in callee saved registers because below we need to
+ * do a call to sigprocmask and afterwards we need to restore $ra. */
+ copyd $r20 = $r0
+ copyd $r21 = $r7
+ ;;
+ sd MCONTEXT_CS_SPC[$r0] = $r8
+
+ /* Prepare call to sigprocmask */
+ make $r0 = SIG_BLOCK
+ make $r1 = 0
+ ;;
+ /* $r20 points to the ucontext */
+ addd $r2 = $r20, UCONTEXT_SIGMASK
+ /* Already set the return value for when this is called in the context
+ * of swapcontext. Because when this context returns it should look
+ * like as if swapcontext returned with 0. */
+ sd MCONTEXT_Q0[$r20] = $r1
+ ;;
+ /* sigprocmask(SIG_BLOCK, NULL, &(ucontext->uc_sigmask)) */
+ call sigprocmask
+ ;;
+ /* Restore $ra to point to the caller of this function. So,
+ * __getcontext will return with -1 (set by __syscall_error) and an
+ * appropriate errno */
+ set $ra = $r21
+ ;;
+ /* Check return value of sigprocmask */
+ cb.deqz $r0 ? 1f
+ ;;
+ goto __syscall_error
+ ;;
+1:
+ /* Restore used callee saved registers */
+ lq $r20r21 = MCONTEXT_Q20[$r20]
+ ;;
+ /* Set return value */
+ make $r0 = 0
+ ret
+ ;;
+END(__getcontext)
+weak_alias(__getcontext, getcontext)
diff --git a/libc/sysdeps/linux/kvx/makecontext.c b/libc/sysdeps/linux/kvx/makecontext.c
new file mode 100644
index 000000000..a52eded9f
--- /dev/null
+++ b/libc/sysdeps/linux/kvx/makecontext.c
@@ -0,0 +1,53 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive for
+ * more details.
+ *
+ * Copyright (C) 2025 Kalray Inc.
+ * Author(s): Julian Vetter <jvetter@kalrayinc.com>
+ */
+
+#include <stdarg.h>
+#include <ucontext.h>
+
+
+/* Number of arguments that go in registers. */
+#define NREG_ARGS 12
+
+/* Take a context previously prepared via getcontext() and set to
+ call func() with the given int only args. */
+void
+__makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
+{
+ extern void __startcontext (void);
+ unsigned long *funcstack;
+ va_list vl;
+ unsigned long *regptr;
+ unsigned int reg;
+
+ /* Start at the top of stack. */
+ funcstack = (unsigned long *) (ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size);
+ funcstack -= argc < NREG_ARGS ? 0 : argc - NREG_ARGS;
+ funcstack = (unsigned long *) (((uintptr_t) funcstack & -32L));
+
+ ucp->uc_mcontext.sc_regs.r12 = (unsigned long) funcstack;
+ /* Use $r20 and $r21 to pass some infos to __startcontext */
+ ucp->uc_mcontext.sc_regs.r20 = (unsigned long) ucp->uc_link;
+ ucp->uc_mcontext.sc_regs.r21 = (unsigned long) func;
+ ucp->uc_mcontext.sc_regs.ra = (unsigned long) __startcontext;
+
+ va_start (vl, argc);
+
+ /* The first twelve arguments go into registers. */
+ regptr = &(ucp->uc_mcontext.sc_regs.r0);
+
+ for (reg = 0; (reg < argc) && (reg < NREG_ARGS); reg++)
+ *regptr++ = va_arg (vl, unsigned long);
+
+ /* And the remainder on the stack. */
+ for (; reg < argc; reg++)
+ *funcstack++ = va_arg (vl, unsigned long);
+
+ va_end (vl);
+}
+weak_alias (__makecontext, makecontext)
diff --git a/libc/sysdeps/linux/kvx/setcontext.S b/libc/sysdeps/linux/kvx/setcontext.S
new file mode 100644
index 000000000..7b91d21d9
--- /dev/null
+++ b/libc/sysdeps/linux/kvx/setcontext.S
@@ -0,0 +1,106 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive for
+ * more details.
+ *
+ * Copyright (C) 2025 Kalray Inc.
+ * Author(s): Julian Vetter <jvetter@kalrayinc.com>
+ */
+
+#include <sysdep.h>
+
+#include "ucontext_i.h"
+
+ .text
+
+/*
+ * int setcontext (const ucontext_t *ucp)
+ */
+ENTRY(__setcontext)
+ get $r16 = $ra
+ addd $r12 = $r12, -32
+ ;;
+ /* Save ucp pointer and $ra on the stack because we can't trash
+ * any callee saved registers in case __setcontext returns */
+ sd 16[$r12] = $r16
+ ;;
+ sd 24[$r12] = $r0
+ ;;
+ /* Bring back the signal status. */
+ make $r0 = SIG_SETMASK
+ addd $r1 = $r0, UCONTEXT_SIGMASK
+ make $r2 = 0
+ ;;
+ /* sigprocmask(SIG_SETMASK, &(ucontext->uc_sigmask), NULL) */
+ call sigprocmask
+ ;;
+ /* Check return value of sigprocmask */
+ cb.deqz $r0 ? 1f
+ /* Normally __setcontext does not return. But in case of an error it
+ * returns with -1 and an appropriate errno */
+ ld $r16 = 16[$r12]
+ ;;
+ set $ra = $r16
+ addd $r12 = $r12, 32
+ ;;
+ goto __syscall_error
+ ;;
+1:
+ /* Get back the ucp pointer */
+ ld $r16 = 24[$r12]
+ /* Reset the stack pointer (we can trash $ra here, because we will
+ * never return to after __setcontext from this point onwards) */
+ addd $r12 = $r12, 32
+ ;;
+ /* Restore callee saved registers */
+ lq $r18r19 = (MCONTEXT_Q16 + 16)[$r16]
+ ;;
+ /* Setup $r20, $r21 for the __startcontext to work */
+ lo $r20r21r22r23 = MCONTEXT_Q20[$r16]
+ ;;
+ lo $r24r25r26r27 = MCONTEXT_Q24[$r16]
+ ;;
+ lo $r28r29r30r31 = MCONTEXT_Q28[$r16]
+ ;;
+ /* Restore special registers */
+ lo $r40r41r42r43 = MCONTEXT_LC_LE_LS_RA[$r16]
+ ;;
+ /* Now load argument registers */
+ lo $r0r1r2r3 = MCONTEXT_Q0[$r16]
+ set $lc = $r40
+ ;;
+ lo $r4r5r6r7 = MCONTEXT_Q4[$r16]
+ set $le = $r41
+ ;;
+ lo $r8r9r10r11 = MCONTEXT_Q8[$r16]
+ set $ls = $r42
+ ;;
+ /* Restore $sp */
+ ld $r12 = MCONTEXT_Q12[$r16]
+ /* Restore $ra which points to the $ra set by __getcontext or
+ * to__startcontext if __makecontext was called in between */
+ set $ra = $r43
+ ;;
+ ld $r40 = MCONTEXT_CS_SPC[$r16]
+ ;;
+ ld $r14 = (MCONTEXT_Q12 + 16)[$r16]
+ set $cs = $r40
+ ;;
+ ret
+ ;;
+END(setcontext)
+weak_alias(__setcontext, setcontext)
+
+ENTRY(__startcontext)
+ icall $r21
+ ;;
+ copyd $r0 = $r20
+ /* Check if the new context is 0 if so just call _exit */
+ cb.deqz $r20 ? 1f
+ ;;
+ goto __setcontext
+ ;;
+ /* This should never be reached otherwise kill the thread */
+1: goto _exit
+ ;;
+END(__startcontext)
diff --git a/libc/sysdeps/linux/kvx/swapcontext.S b/libc/sysdeps/linux/kvx/swapcontext.S
new file mode 100644
index 000000000..1abb6a8a8
--- /dev/null
+++ b/libc/sysdeps/linux/kvx/swapcontext.S
@@ -0,0 +1,63 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive for
+ * more details.
+ *
+ * Copyright (C) 2025 Kalray Inc.
+ * Author(s): Julian Vetter <jvetter@kalrayinc.com>
+ */
+
+#include <sysdep.h>
+
+#include "ucontext_i.h"
+
+ .text
+
+/* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */
+
+ENTRY(swapcontext)
+ /* Make space on the stack to save all caller saved registers */
+ get $r16 = $ra
+ addd $r12 = $r12, -32
+ ;;
+
+ /* Save $ra on the stack */
+ sd (24)[$r12] = $r16
+ ;;
+ /* Save the arguments of swapcontext on the stack */
+ sq (8)[$r12] = $r0r1
+ ;;
+ call __getcontext
+ ;;
+
+ /* Save the return value of __getcontext in $r17 */
+ copyd $r17 = $r0
+
+ /* Restore $ra */
+ ld $r16 = (24)[$r12]
+ ;;
+ /* Restore arguments */
+ lq $r0r1 = (8)[$r12]
+ /* Readjust the stack pointer */
+ addd $r12 = $r12, 32
+ /* Also restore $ra */
+ set $ra = $r16
+ ;;
+
+ /* Exit if getcontext() failed */
+ cb.deqz $r17 ? 1f
+ ;;
+
+ /* Set the return value set by __syscall_error in __getcontext */
+ copyd $r0 = $r17
+ ret
+ ;;
+1:
+ /* Store the $sp and $ra in the context to be saved */
+ sd (MCONTEXT_Q12)[$r0] = $r12
+ ;;
+ sd (MCONTEXT_LC_LE_LS_RA + 24)[$r0] = $r16
+ copyd $r0 = $r1
+ goto __setcontext
+ ;;
+END(swapcontext)
diff --git a/libc/sysdeps/linux/kvx/sys/ucontext.h b/libc/sysdeps/linux/kvx/sys/ucontext.h
index a97b83cad..6a30a09e2 100644
--- a/libc/sysdeps/linux/kvx/sys/ucontext.h
+++ b/libc/sysdeps/linux/kvx/sys/ucontext.h
@@ -17,11 +17,13 @@
/* Type for general register. */
typedef unsigned long greg_t;
+typedef struct sigcontext mcontext_t;
+
typedef struct ucontext {
unsigned long uc_flags;
struct ucontext *uc_link;
stack_t uc_stack;
- struct sigcontext uc_mcontext;
+ mcontext_t uc_mcontext;
sigset_t uc_sigmask; /* mask last for extensibility */
} ucontext_t;
diff --git a/libc/sysdeps/linux/kvx/ucontext_i.sym b/libc/sysdeps/linux/kvx/ucontext_i.sym
new file mode 100644
index 000000000..d2b565332
--- /dev/null
+++ b/libc/sysdeps/linux/kvx/ucontext_i.sym
@@ -0,0 +1,28 @@
+#include <inttypes.h>
+#include <signal.h>
+#include <stddef.h>
+#include <sys/ucontext.h>
+
+SIG_BLOCK
+SIG_SETMASK
+
+-- Offsets of the fields in the ucontext_t structure.
+#define ucontext(member) offsetof (ucontext_t, member)
+#define mcontext(member) ucontext (uc_mcontext.member)
+
+UCONTEXT_FLAGS ucontext (uc_flags)
+UCONTEXT_LINK ucontext (uc_link)
+UCONTEXT_STACK ucontext (uc_stack)
+UCONTEXT_MCONTEXT ucontext (uc_mcontext)
+UCONTEXT_SIGMASK ucontext (uc_sigmask)
+
+MCONTEXT_Q0 mcontext (sc_regs.r0)
+MCONTEXT_Q4 mcontext (sc_regs.r4)
+MCONTEXT_Q8 mcontext (sc_regs.r8)
+MCONTEXT_Q12 mcontext (sc_regs.r12)
+MCONTEXT_Q16 mcontext (sc_regs.r16)
+MCONTEXT_Q20 mcontext (sc_regs.r20)
+MCONTEXT_Q24 mcontext (sc_regs.r24)
+MCONTEXT_Q28 mcontext (sc_regs.r28)
+MCONTEXT_LC_LE_LS_RA mcontext (sc_regs.lc)
+MCONTEXT_CS_SPC mcontext (sc_regs.cs)
diff --git a/libc/sysdeps/linux/m68k/bits/shm.h b/libc/sysdeps/linux/m68k/bits/shm.h
new file mode 100644
index 000000000..aa1a72e54
--- /dev/null
+++ b/libc/sysdeps/linux/m68k/bits/shm.h
@@ -0,0 +1,108 @@
+/* Copyright (C) 1995,1996,1997,2000,2002,2004 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
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _SYS_SHM_H
+# error "Never include <bits/shm.h> directly; use <sys/shm.h> instead."
+#endif
+
+#include <bits/types.h>
+
+/* Permission flag for shmget. */
+#define SHM_R 0400 /* or S_IRUGO from <linux/stat.h> */
+#define SHM_W 0200 /* or S_IWUGO from <linux/stat.h> */
+
+/* Flags for `shmat'. */
+#define SHM_RDONLY 010000 /* attach read-only else read-write */
+#define SHM_RND 020000 /* round attach address to SHMLBA */
+#define SHM_REMAP 040000 /* take-over region on attach */
+
+/* Commands for `shmctl'. */
+#define SHM_LOCK 11 /* lock segment (root only) */
+#define SHM_UNLOCK 12 /* unlock segment (root only) */
+
+__BEGIN_DECLS
+
+/* Segment low boundary address multiple. */
+#define SHMLBA (__getpagesize () << 2)
+extern int __getpagesize (void) __THROW __attribute__ ((__const__));
+
+
+/* Type to count number of attaches. */
+typedef unsigned long int shmatt_t;
+
+/* Data structure describing a set of semaphores. */
+struct shmid_ds
+ {
+ struct ipc_perm shm_perm; /* operation permission struct */
+ size_t shm_segsz; /* size of segment in bytes */
+#if defined(__UCLIBC_USE_TIME64__)
+ __time_t shm_atime;
+ __time_t shm_dtime;
+ __time_t shm_ctime;
+#else
+ __time_t shm_atime; /* time of last shmat() */
+ unsigned long int __uclibc_unused1;
+ __time_t shm_dtime; /* time of last shmdt() */
+ unsigned long int __uclibc_unused2;
+ __time_t shm_ctime; /* time of last change by shmctl() */
+ unsigned long int __uclibc_unused3;
+#endif
+ __pid_t shm_cpid; /* pid of creator */
+ __pid_t shm_lpid; /* pid of last shmop */
+ shmatt_t shm_nattch; /* number of current attaches */
+ unsigned long int __uclibc_unused4;
+ unsigned long int __uclibc_unused5;
+ };
+
+#ifdef __USE_MISC
+
+/* ipcs ctl commands */
+# define SHM_STAT 13
+# define SHM_INFO 14
+
+/* shm_mode upper byte flags */
+# define SHM_DEST 01000 /* segment will be destroyed on last detach */
+# define SHM_LOCKED 02000 /* segment will not be swapped */
+# define SHM_HUGETLB 04000 /* segment is mapped via hugetlb */
+# define SHM_NORESERVE 010000 /* don't check for reservations */
+
+struct shminfo
+ {
+ unsigned long int shmmax;
+ unsigned long int shmmin;
+ unsigned long int shmmni;
+ unsigned long int shmseg;
+ unsigned long int shmall;
+ unsigned long int __uclibc_unused1;
+ unsigned long int __uclibc_unused2;
+ unsigned long int __uclibc_unused3;
+ unsigned long int __uclibc_unused4;
+ };
+
+struct shm_info
+ {
+ int used_ids;
+ unsigned long int shm_tot; /* total allocated shm */
+ unsigned long int shm_rss; /* total resident shm */
+ unsigned long int shm_swp; /* total swapped shm */
+ unsigned long int swap_attempts;
+ unsigned long int swap_successes;
+ };
+
+#endif /* __USE_MISC */
+
+__END_DECLS
diff --git a/libc/sysdeps/linux/mips/bits/msq.h b/libc/sysdeps/linux/mips/bits/msq.h
index bcf1073e8..141b1ff9f 100644
--- a/libc/sysdeps/linux/mips/bits/msq.h
+++ b/libc/sysdeps/linux/mips/bits/msq.h
@@ -35,30 +35,58 @@ typedef unsigned long int msglen_t;
/* Structure of record for one message inside the kernel.
The type `struct msg' is opaque. */
+#if (__WORDSIZE == 32) && defined(__MIPSEL__)
struct msqid_ds
{
struct ipc_perm msg_perm; /* structure describing operation permission */
-#if (__WORDSIZE == 32) && !defined(__MIPSEL__)
- unsigned long __unused1;
-#endif
- __time_t msg_stime; /* time of last msgsnd command */
-#if (__WORDSIZE == 32) && defined(__MIPSEL__)
- unsigned long __unused1;
-#endif
-#if (__WORDSIZE == 32) && !defined(__MIPSEL__)
- unsigned long __unused2;
-#endif
- __time_t msg_rtime; /* time of last msgrcv command */
-#if (__WORDSIZE == 32) && defined(__MIPSEL__)
- unsigned long __unused2;
-#endif
-#if (__WORDSIZE == 32) && !defined(__MIPSEL__)
- unsigned long __unused3;
-#endif
- __time_t msg_ctime; /* time of last change */
-#if (__WORDSIZE == 32) && defined(__MIPSEL__)
- unsigned long __unused3;
-#endif
+# if defined(__UCLIBC_USE_TIME64__)
+ unsigned long msg_stime_internal_1; /* time of last msgsnd command */
+ unsigned long msg_stime_internal_2;
+ unsigned long msg_rtime_internal_1; /* time of last msgrcv command */
+ unsigned long msg_rtime_internal_2;
+ unsigned long msg_ctime_internal_1; /* time of last change */
+ unsigned long msg_ctime_internal_2;
+# else
+ __time_t msg_stime;
+ unsigned long int __uclibc_unused1;
+ __time_t msg_rtime;
+ unsigned long int __uclibc_unused2;
+ __time_t msg_ctime;
+ unsigned long int __uclibc_unused3;
+# endif
+ unsigned long int __msg_cbytes; /* current number of bytes on queue */
+ msgqnum_t msg_qnum; /* number of messages currently on queue */
+ msglen_t msg_qbytes; /* max number of bytes allowed on queue */
+ __pid_t msg_lspid; /* pid of last msgsnd() */
+ __pid_t msg_lrpid; /* pid of last msgrcv() */
+ unsigned long int __uclibc_unused4;
+ unsigned long int __uclibc_unused5;
+# if defined(__UCLIBC_USE_TIME64__)
+ __time_t msg_stime;
+ __time_t msg_rtime;
+ __time_t msg_ctime;
+# endif
+};
+
+#elif (__WORDSIZE == 32) && defined(__MIPSEB__)
+struct msqid_ds
+{
+ struct ipc_perm msg_perm; /* structure describing operation permission */
+# if defined(__UCLIBC_USE_TIME64__)
+ unsigned long msg_stime_internal_2; /* time of last msgsnd command */
+ unsigned long msg_stime_internal_1;
+ unsigned long msg_rtime_internal_2; /* time of last msgrcv command */
+ unsigned long msg_rtime_internal_1;
+ unsigned long msg_ctime_internal_2; /* time of last change */
+ unsigned long msg_ctime_internal_1;
+# else
+ unsigned long int __uclibc_unused1;
+ __time_t msg_stime;
+ unsigned long int __uclibc_unused2;
+ __time_t msg_rtime;
+ unsigned long int __uclibc_unused3;
+ __time_t msg_ctime;
+# endif
unsigned long int __msg_cbytes; /* current number of bytes on queue */
msgqnum_t msg_qnum; /* number of messages currently on queue */
msglen_t msg_qbytes; /* max number of bytes allowed on queue */
@@ -66,8 +94,32 @@ struct msqid_ds
__pid_t msg_lrpid; /* pid of last msgrcv() */
unsigned long int __uclibc_unused4;
unsigned long int __uclibc_unused5;
+# if defined(__UCLIBC_USE_TIME64__)
+ __time_t msg_stime;
+ __time_t msg_rtime;
+ __time_t msg_ctime;
+# endif
+};
+
+#else
+
+struct msqid_ds
+{
+ struct ipc_perm msg_perm; /* structure describing operation permission */
+ __time_t msg_stime; /* time of last msgsnd command */
+ __time_t msg_rtime; /* time of last msgrcv command */
+ __time_t msg_ctime; /* time of last change */
+ unsigned long int __msg_cbytes; /* current number of bytes on queue */
+ msgqnum_t msg_qnum; /* number of messages currently on queue */
+ msglen_t msg_qbytes; /* max number of bytes allowed on queue */
+ __pid_t msg_lspid; /* pid of last msgsnd() */
+ __pid_t msg_lrpid; /* pid of last msgrcv() */
+ unsigned long int __uclibc_unused4;
+ unsigned long int __uclibc_unused5;
};
+#endif
+
#ifdef __USE_MISC
# define msg_cbytes __msg_cbytes
diff --git a/libc/sysdeps/linux/mips/bits/sem.h b/libc/sysdeps/linux/mips/bits/sem.h
index 35eaa05c3..230d04868 100644
--- a/libc/sysdeps/linux/mips/bits/sem.h
+++ b/libc/sysdeps/linux/mips/bits/sem.h
@@ -38,22 +38,23 @@
struct semid_ds
{
struct ipc_perm sem_perm; /* operation permission struct */
-#if defined(__UCLIBC_USE_TIME64__)
+#if (__WORDSIZE == 32) && defined(__UCLIBC_USE_TIME64__)
unsigned long int __sem_otime_internal_1; /* last semop() time */
- unsigned long int __sem_otime_internal_2;
unsigned long int __sem_ctime_internal_1; /* last time changed by semctl() */
- unsigned long int __sem_ctime_internal_2;
#else
__time_t sem_otime; /* last semop() time */
__time_t sem_ctime; /* last time changed by semctl() */
#endif
unsigned long int sem_nsems; /* number of semaphores in set */
-#if defined(__UCLIBC_USE_TIME64__)
+#if (__WORDSIZE == 32) && defined(__UCLIBC_USE_TIME64__)
+ unsigned long int __sem_otime_internal_2;
+ unsigned long int __sem_ctime_internal_2;
__time_t sem_otime;
__time_t sem_ctime;
-#endif
+#else
unsigned long int __uclibc_unused1;
unsigned long int __uclibc_unused2;
+#endif
};
/* The user should define a union like the following to use it for arguments
diff --git a/libc/sysdeps/linux/mips/bits/shm.h b/libc/sysdeps/linux/mips/bits/shm.h
index bb87ba13d..1855a50b2 100644
--- a/libc/sysdeps/linux/mips/bits/shm.h
+++ b/libc/sysdeps/linux/mips/bits/shm.h
@@ -46,14 +46,32 @@ struct shmid_ds
{
struct ipc_perm shm_perm; /* operation permission struct */
size_t shm_segsz; /* size of segment in bytes */
- __time_t shm_atime; /* time of last shmat() */
- __time_t shm_dtime; /* time of last shmdt() */
- __time_t shm_ctime; /* time of last change by shmctl() */
+#if (__WORDSIZE == 32) && defined(__UCLIBC_USE_TIME64__)
+ unsigned long int shm_atime_internal_1; /* time of last shmat() */
+ unsigned long int shm_dtime_internal_1; /* time of last shmdt() */
+ unsigned long int shm_ctime_internal_1; /* time of last change by shmctl() */
+#else
+ __time_t shm_atime;
+ __time_t shm_dtime;
+ __time_t shm_ctime;
+#endif
__pid_t shm_cpid; /* pid of creator */
__pid_t shm_lpid; /* pid of last shmop */
shmatt_t shm_nattch; /* number of current attaches */
- unsigned long int __uclibc_unused1;
- unsigned long int __uclibc_unused2;
+#if (__WORDSIZE == 32) && defined(__UCLIBC_USE_TIME64__)
+ unsigned short int shm_atime_internal_2; /* time of last shmat() */
+ unsigned short int shm_dtime_internal_2; /* time of last shmdt() */
+ unsigned short int shm_ctime_internal_2; /* time of last change by shmctl() */
+ unsigned short int __uclibc_unused1;
+ __time_t shm_atime;
+ __time_t shm_dtime;
+ __time_t shm_ctime;
+#else
+ unsigned short int __uclibc_unused1;
+ unsigned short int __uclibc_unused2;
+ unsigned short int __uclibc_unused3;
+ unsigned short int __uclibc_unused4;
+#endif
};
#ifdef __USE_MISC
diff --git a/libc/sysdeps/linux/mips/bits/syscalls.h b/libc/sysdeps/linux/mips/bits/syscalls.h
index 13728ac55..64b42ffb1 100644
--- a/libc/sysdeps/linux/mips/bits/syscalls.h
+++ b/libc/sysdeps/linux/mips/bits/syscalls.h
@@ -184,7 +184,7 @@
({ \
long _sys_result; \
\
- FORCE_FRAME_POINTER; \
+ int* array = FORCE_FRAME_POINTER; \
{ \
register long __v0 __asm__("$2") ncs_init; \
register long __a0 __asm__("$4") = (long) arg1; \
@@ -193,15 +193,16 @@
register long __a3 __asm__("$7") = (long) arg4; \
__asm__ __volatile__ ( \
".set\tnoreorder\n\t" \
- "subu\t$29, 32\n\t" \
+ "subu\t$29, 32\n\t" \
"sw\t%6, 16($29)\n\t" \
cs_init \
"syscall\n\t" \
- "addiu\t$29, 32\n\t" \
- ".set\treorder" \
+ "addiu\t$29, 32\n\t" \
+ "addiu\t%7, %7, 0\n\t" \
+ ".set\treorder" \
: "=r" (__v0), "+r" (__a3) \
: input, "r" (__a0), "r" (__a1), "r" (__a2), \
- "r" ((long)arg5) \
+ "r" ((long)arg5), "r" (array) \
: __SYSCALL_CLOBBERS); \
err = __a3; \
_sys_result = __v0; \
@@ -213,7 +214,7 @@
({ \
long _sys_result; \
\
- FORCE_FRAME_POINTER; \
+ int* array = FORCE_FRAME_POINTER; \
{ \
register long __v0 __asm__("$2") ncs_init; \
register long __a0 __asm__("$4") = (long) arg1; \
@@ -221,17 +222,18 @@
register long __a2 __asm__("$6") = (long) arg3; \
register long __a3 __asm__("$7") = (long) arg4; \
__asm__ __volatile__ ( \
- ".set\tnoreorder\n\t" \
- "subu\t$29, 32\n\t" \
+ ".set\tnoreorder\n\t" \
+ "subu\t$29, 32\n\t" \
"sw\t%6, 16($29)\n\t" \
"sw\t%7, 20($29)\n\t" \
cs_init \
"syscall\n\t" \
- "addiu\t$29, 32\n\t" \
- ".set\treorder" \
+ "addiu\t$29, 32\n\t" \
+ "addiu\t%8, %8, 0\n\t" \
+ ".set\treorder" \
: "=r" (__v0), "+r" (__a3) \
: input, "r" (__a0), "r" (__a1), "r" (__a2), \
- "r" ((long)arg5), "r" ((long)arg6) \
+ "r" ((long)arg5), "r" ((long)arg6), "r" (array) \
: __SYSCALL_CLOBBERS); \
err = __a3; \
_sys_result = __v0; \
@@ -243,7 +245,7 @@
({ \
long _sys_result; \
\
- FORCE_FRAME_POINTER; \
+ int* array = FORCE_FRAME_POINTER; \
{ \
register long __v0 __asm__("$2") ncs_init; \
register long __a0 __asm__("$4") = (long) arg1; \
@@ -252,17 +254,19 @@
register long __a3 __asm__("$7") = (long) arg4; \
__asm__ __volatile__ ( \
".set\tnoreorder\n\t" \
- "subu\t$29, 32\n\t" \
+ "subu\t$29, 32\n\t" \
"sw\t%6, 16($29)\n\t" \
"sw\t%7, 20($29)\n\t" \
"sw\t%8, 24($29)\n\t" \
cs_init \
"syscall\n\t" \
- "addiu\t$29, 32\n\t" \
- ".set\treorder" \
+ "addiu\t$29, 32\n\t" \
+ "addiu\t%9, %9, 0\n\t" \
+ ".set\treorder" \
: "=r" (__v0), "+r" (__a3) \
: input, "r" (__a0), "r" (__a1), "r" (__a2), \
- "r" ((long)arg5), "r" ((long)arg6), "r" ((long)arg7) \
+ "r" ((long)arg5), "r" ((long)arg6), "r" ((long)arg7), \
+ "r" (array) \
: __SYSCALL_CLOBBERS); \
err = __a3; \
_sys_result = __v0; \
diff --git a/libc/sysdeps/linux/riscv32/bits/shm.h b/libc/sysdeps/linux/riscv32/bits/shm.h
index 8a11c7050..9190c562b 100644
--- a/libc/sysdeps/linux/riscv32/bits/shm.h
+++ b/libc/sysdeps/linux/riscv32/bits/shm.h
@@ -37,12 +37,18 @@ struct shmid_ds
{
struct ipc_perm shm_perm; /* operation permission struct */
size_t shm_segsz; /* size of segment in bytes */
+#if defined(__UCLIBC_USE_TIME64__)
+ __time_t shm_atime;
+ __time_t shm_dtime;
+ __time_t shm_ctime;
+#else
__time_t shm_atime; /* time of last shmat() */
unsigned long int __uclibc_unused1;
__time_t shm_dtime; /* time of last shmdt() */
unsigned long int __uclibc_unused2;
__time_t shm_ctime; /* time of last change by shmctl() */
unsigned long int __uclibc_unused3;
+#endif
__pid_t shm_cpid; /* pid of creator */
__pid_t shm_lpid; /* pid of last shmop */
shmatt_t shm_nattch; /* number of current attaches */
diff --git a/libc/sysdeps/linux/riscv64/bits/shm.h b/libc/sysdeps/linux/riscv64/bits/shm.h
index 8a11c7050..bfb603499 100644
--- a/libc/sysdeps/linux/riscv64/bits/shm.h
+++ b/libc/sysdeps/linux/riscv64/bits/shm.h
@@ -38,16 +38,13 @@ struct shmid_ds
struct ipc_perm shm_perm; /* operation permission struct */
size_t shm_segsz; /* size of segment in bytes */
__time_t shm_atime; /* time of last shmat() */
- unsigned long int __uclibc_unused1;
__time_t shm_dtime; /* time of last shmdt() */
- unsigned long int __uclibc_unused2;
__time_t shm_ctime; /* time of last change by shmctl() */
- unsigned long int __uclibc_unused3;
__pid_t shm_cpid; /* pid of creator */
__pid_t shm_lpid; /* pid of last shmop */
shmatt_t shm_nattch; /* number of current attaches */
- unsigned long int __uclibc_unused4;
- unsigned long int __uclibc_unused5;
+ unsigned long int __uclibc_unused1;
+ unsigned long int __uclibc_unused2;
};
#ifdef __USE_MISC
diff --git a/libc/sysdeps/linux/sh/bits/fenv.h b/libc/sysdeps/linux/sh/bits/fenv.h
index 38c303ff2..349e7ddde 100644
--- a/libc/sysdeps/linux/sh/bits/fenv.h
+++ b/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)
diff --git a/libc/sysdeps/linux/sh/fpu_control.h b/libc/sysdeps/linux/sh/fpu_control.h
index 8143041fe..d5f401f91 100644
--- a/libc/sysdeps/linux/sh/fpu_control.h
+++ b/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 */
diff --git a/libc/sysdeps/linux/sparc/bits/fenv.h b/libc/sysdeps/linux/sparc/bits/fenv.h
index 79ab8cefa..83b32cc51 100644
--- a/libc/sysdeps/linux/sparc/bits/fenv.h
+++ b/libc/sysdeps/linux/sparc/bits/fenv.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+/* Copyright (C) 1997-2025 Free Software Foundation, Inc.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -12,26 +12,34 @@
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
- <http://www.gnu.org/licenses/>. */
+ <https://www.gnu.org/licenses/>. */
#ifndef _FENV_H
# error "Never use <bits/fenv.h> directly; include <fenv.h> instead."
#endif
+#include <bits/wordsize.h>
+
+
/* Define bits representing the exception. We use the bit positions
of the appropriate accrued exception bits from the FSR. */
enum
{
- FE_INVALID = (1 << 9),
-#define FE_INVALID FE_INVALID
- FE_OVERFLOW = (1 << 8),
-#define FE_OVERFLOW FE_OVERFLOW
- FE_UNDERFLOW = (1 << 7),
-#define FE_UNDERFLOW FE_UNDERFLOW
- FE_DIVBYZERO = (1 << 6),
-#define FE_DIVBYZERO FE_DIVBYZERO
- FE_INEXACT = (1 << 5)
-#define FE_INEXACT FE_INEXACT
+ FE_INVALID =
+#define FE_INVALID (1 << 9)
+ FE_INVALID,
+ FE_OVERFLOW =
+#define FE_OVERFLOW (1 << 8)
+ FE_OVERFLOW,
+ FE_UNDERFLOW =
+#define FE_UNDERFLOW (1 << 7)
+ FE_UNDERFLOW,
+ FE_DIVBYZERO =
+#define FE_DIVBYZERO (1 << 6)
+ FE_DIVBYZERO,
+ FE_INEXACT =
+#define FE_INEXACT (1 << 5)
+ FE_INEXACT
};
#define FE_ALL_EXCEPT \
@@ -42,14 +50,18 @@ enum
for the appropriate macros. */
enum
{
- FE_TONEAREST = (0U << 30),
-#define FE_TONEAREST FE_TONEAREST
- FE_TOWARDZERO = (1U << 30),
-#define FE_TOWARDZERO FE_TOWARDZERO
- FE_UPWARD = (2U << 30),
-#define FE_UPWARD FE_UPWARD
- FE_DOWNWARD = (3U << 30)
-#define FE_DOWNWARD FE_DOWNWARD
+ FE_TONEAREST =
+#define FE_TONEAREST (0 << 30)
+ FE_TONEAREST,
+ FE_TOWARDZERO =
+#define FE_TOWARDZERO (1 << 30)
+ FE_TOWARDZERO,
+ FE_UPWARD =
+#define FE_UPWARD (-0x7fffffff - 1) /* (2 << 30) */
+ FE_UPWARD,
+ FE_DOWNWARD =
+#define FE_DOWNWARD (-0x40000000) /* (3 << 30) */
+ FE_DOWNWARD
};
#define __FE_ROUND_MASK (3U << 30)
@@ -70,6 +82,8 @@ typedef unsigned long int fenv_t;
# define FE_NOMASK_ENV ((const fenv_t *) -2)
#endif
-/* For internal use only: access the fp state register. */
-#define __fenv_stfsr(X) __asm__ ("st %%fsr,%0" : "=m" (X))
-#define __fenv_ldfsr(X) __asm__ __volatile__ ("ld %0,%%fsr" : : "m" (X))
+/* Type representing floating-point control modes. */
+typedef unsigned long int femode_t;
+
+/* Default floating-point control modes. */
+# define FE_DFL_MODE ((const femode_t *) -1L)
diff --git a/libc/sysdeps/linux/sparc/fpu_control.h b/libc/sysdeps/linux/sparc/fpu_control.h
index 57f1dbb67..542f9fb1b 100644
--- a/libc/sysdeps/linux/sparc/fpu_control.h
+++ b/libc/sysdeps/linux/sparc/fpu_control.h
@@ -1,6 +1,5 @@
/* FPU control word bits. SPARC version.
- Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
- Contributed by Miguel de Icaza
+ Copyright (C) 1997-2025 Free Software Foundation, Inc.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -14,13 +13,14 @@
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
- <http://www.gnu.org/licenses/>. */
+ <https://www.gnu.org/licenses/>. */
#ifndef _FPU_CONTROL_H
#define _FPU_CONTROL_H 1
#include <features.h>
+#include <bits/wordsize.h>
/* masking of interrupts */
#define _FPU_MASK_IM 0x08000000
@@ -41,7 +41,7 @@
#define _FPU_RC_ZERO 0x40000000
#define _FPU_RC_NEAREST 0x0 /* RECOMMENDED */
-#define _FPU_RESERVED 0x30300000 /* Reserved bits in cw */
+#define _FPU_RESERVED 0x303e0000 /* Reserved bits in cw */
/* Now two recommended cw */
@@ -56,12 +56,20 @@
/* Type of the control word. */
typedef unsigned long int fpu_control_t;
-#define _FPU_GETCW(cw) __asm__ ("st %%fsr,%0" : "=m" (*&cw))
-#define _FPU_SETCW(cw) __asm__ ("ld %0,%%fsr" : : "m" (*&cw))
+#if __WORDSIZE == 64
+# define _FPU_GETCW(cw) __asm__ __volatile__ ("stx %%fsr,%0" : "=m" (*&cw))
+# define _FPU_SETCW(cw) __asm__ __volatile__ ("ldx %0,%%fsr" : : "m" (*&cw))
+#else
+# ifdef __leon__
+ /* Prevent stfsr from being placed directly after other fp instruction. */
+# define _FPU_GETCW(cw) __asm__ __volatile__ ("nop; st %%fsr,%0" : "=m" (*&cw))
+# else
+# define _FPU_GETCW(cw) __asm__ __volatile__ ("st %%fsr,%0" : "=m" (*&cw))
+# endif
+# define _FPU_SETCW(cw) __asm__ __volatile__ ("ld %0,%%fsr" : : "m" (*&cw))
+#endif
-#if 0
/* Default control word set at startup. */
extern fpu_control_t __fpu_control;
-#endif
#endif /* fpu_control.h */
diff --git a/libm/arc/Makefile.arch b/libm/arc/Makefile.arch
new file mode 100644
index 000000000..bd38690be
--- /dev/null
+++ b/libm/arc/Makefile.arch
@@ -0,0 +1,16 @@
+# Makefile for uClibc-ng
+# Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
+
+ifeq ($(UCLIBC_HAS_FENV),y)
+libm_ARCH_SRC:=$(wildcard $(libm_ARCH_DIR)/*.c)
+libm_ARCH_OBJ:=$(patsubst $(libm_ARCH_DIR)/%.c,$(libm_ARCH_OUT)/%.o,$(libm_ARCH_SRC))
+endif
+
+libm_ARCH_OBJS:=$(libm_ARCH_OBJ)
+
+ifeq ($(DOPIC),y)
+libm-a-y+=$(libm_ARCH_OBJS:.o=.os)
+else
+libm-a-y+=$(libm_ARCH_OBJS)
+endif
+libm-so-y+=$(libm_ARCH_OBJS:.o=.os)
diff --git a/libm/arc/fclrexcpt.c b/libm/arc/fclrexcpt.c
new file mode 100644
index 000000000..76631657d
--- /dev/null
+++ b/libm/arc/fclrexcpt.c
@@ -0,0 +1,34 @@
+/* Clear given exceptions in current floating-point environment.
+ Copyright (C) 2020-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)
+{
+ unsigned int fpsr;
+
+ _FPU_GETS (fpsr);
+
+ /* Clear the relevant bits, FWE is preserved. */
+ fpsr &= ~excepts;
+
+ _FPU_SETS (fpsr);
+
+ return 0;
+}
diff --git a/libm/arc/fegetenv.c b/libm/arc/fegetenv.c
new file mode 100644
index 000000000..ad332c3e5
--- /dev/null
+++ b/libm/arc/fegetenv.c
@@ -0,0 +1,33 @@
+/* Store current floating-point environment.
+ Copyright (C) 2020-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)
+{
+ unsigned int fpcr;
+ unsigned int fpsr;
+
+ _FPU_GETCW (fpcr);
+ _FPU_GETS (fpsr);
+ envp->__fpcr = fpcr;
+ envp->__fpsr = fpsr;
+
+ return 0;
+}
diff --git a/libm/arc/fegetmode.c b/libm/arc/fegetmode.c
new file mode 100644
index 000000000..e6aebbc87
--- /dev/null
+++ b/libm/arc/fegetmode.c
@@ -0,0 +1,30 @@
+/* Store current floating-point control modes.
+ Copyright (C) 2020-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)
+{
+ unsigned int fpcr;
+
+ _FPU_GETCW (fpcr);
+ *modep = fpcr;
+
+ return 0;
+}
diff --git a/libm/arc/fegetround.c b/libm/arc/fegetround.c
new file mode 100644
index 000000000..4dc476a7c
--- /dev/null
+++ b/libm/arc/fegetround.c
@@ -0,0 +1,28 @@
+/* Return current rounding direction.
+ Copyright (C) 2020-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)
+{
+ unsigned int fpcr;
+ _FPU_GETCW (fpcr);
+
+ return (fpcr >> __FPU_RND_SHIFT) & __FPU_RND_MASK;
+}
diff --git a/libm/arc/feholdexcpt.c b/libm/arc/feholdexcpt.c
new file mode 100644
index 000000000..8febc7508
--- /dev/null
+++ b/libm/arc/feholdexcpt.c
@@ -0,0 +1,39 @@
+/* Store current floating-point environment and clear exceptions.
+ Copyright (C) 2020-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)
+{
+ unsigned int fpcr;
+ unsigned int fpsr;
+
+ _FPU_GETCW (fpcr);
+ _FPU_GETS (fpsr);
+
+ envp->__fpcr = fpcr;
+ envp->__fpsr = fpsr;
+
+ fpsr &= ~FE_ALL_EXCEPT;
+
+ _FPU_SETCW (fpcr);
+ _FPU_SETS (fpsr);
+
+ return 0;
+}
diff --git a/libm/arc/fenv_private.h b/libm/arc/fenv_private.h
new file mode 100644
index 000000000..5f74c5e13
--- /dev/null
+++ b/libm/arc/fenv_private.h
@@ -0,0 +1,326 @@
+/* Optimized inline fenv.h functions for libm. Generic version.
+ Copyright (C) 2011-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 _FENV_PRIVATE_H
+#define _FENV_PRIVATE_H 1
+
+#include <fenv.h>
+#include "get-rounding-mode.h"
+
+/* The standards only specify one variant of the fenv.h interfaces.
+ But at least for some architectures we can be more efficient if we
+ know what operations are going to be performed. Therefore we
+ define additional interfaces. By default they refer to the normal
+ interfaces. */
+
+static __always_inline void
+default_libc_feholdexcept (fenv_t *e)
+{
+ (void) feholdexcept (e);
+}
+
+#ifndef libc_feholdexcept
+# define libc_feholdexcept default_libc_feholdexcept
+#endif
+#ifndef libc_feholdexceptf
+# define libc_feholdexceptf default_libc_feholdexcept
+#endif
+#ifndef libc_feholdexceptl
+# define libc_feholdexceptl default_libc_feholdexcept
+#endif
+
+static __always_inline void
+default_libc_fesetround (int r)
+{
+ (void) fesetround (r);
+}
+
+#ifndef libc_fesetround
+# define libc_fesetround default_libc_fesetround
+#endif
+#ifndef libc_fesetroundf
+# define libc_fesetroundf default_libc_fesetround
+#endif
+#ifndef libc_fesetroundl
+# define libc_fesetroundl default_libc_fesetround
+#endif
+
+static __always_inline void
+default_libc_feholdexcept_setround (fenv_t *e, int r)
+{
+ feholdexcept (e);
+ fesetround (r);
+}
+
+#ifndef libc_feholdexcept_setround
+# define libc_feholdexcept_setround default_libc_feholdexcept_setround
+#endif
+#ifndef libc_feholdexcept_setroundf
+# define libc_feholdexcept_setroundf default_libc_feholdexcept_setround
+#endif
+#ifndef libc_feholdexcept_setroundl
+# define libc_feholdexcept_setroundl default_libc_feholdexcept_setround
+#endif
+
+#ifndef libc_feholdsetround_53bit
+# define libc_feholdsetround_53bit libc_feholdsetround
+#endif
+
+#ifndef libc_fetestexcept
+# define libc_fetestexcept fetestexcept
+#endif
+#ifndef libc_fetestexceptf
+# define libc_fetestexceptf fetestexcept
+#endif
+#ifndef libc_fetestexceptl
+# define libc_fetestexceptl fetestexcept
+#endif
+
+static __always_inline void
+default_libc_fesetenv (fenv_t *e)
+{
+ (void) fesetenv (e);
+}
+
+#ifndef libc_fesetenv
+# define libc_fesetenv default_libc_fesetenv
+#endif
+#ifndef libc_fesetenvf
+# define libc_fesetenvf default_libc_fesetenv
+#endif
+#ifndef libc_fesetenvl
+# define libc_fesetenvl default_libc_fesetenv
+#endif
+
+static __always_inline void
+default_libc_feupdateenv (fenv_t *e)
+{
+ (void) feupdateenv (e);
+}
+
+#ifndef libc_feupdateenv
+# define libc_feupdateenv default_libc_feupdateenv
+#endif
+#ifndef libc_feupdateenvf
+# define libc_feupdateenvf default_libc_feupdateenv
+#endif
+#ifndef libc_feupdateenvl
+# define libc_feupdateenvl default_libc_feupdateenv
+#endif
+
+#ifndef libc_feresetround_53bit
+# define libc_feresetround_53bit libc_feresetround
+#endif
+
+static __always_inline int
+default_libc_feupdateenv_test (fenv_t *e, int ex)
+{
+ int ret = fetestexcept (ex);
+ feupdateenv (e);
+ return ret;
+}
+
+#ifndef libc_feupdateenv_test
+# define libc_feupdateenv_test default_libc_feupdateenv_test
+#endif
+#ifndef libc_feupdateenv_testf
+# define libc_feupdateenv_testf default_libc_feupdateenv_test
+#endif
+#ifndef libc_feupdateenv_testl
+# define libc_feupdateenv_testl default_libc_feupdateenv_test
+#endif
+
+/* Save and set the rounding mode. The use of fenv_t to store the old mode
+ allows a target-specific version of this function to avoid converting the
+ rounding mode from the fpu format. By default we have no choice but to
+ manipulate the entire env. */
+
+#ifndef libc_feholdsetround
+# define libc_feholdsetround libc_feholdexcept_setround
+#endif
+#ifndef libc_feholdsetroundf
+# define libc_feholdsetroundf libc_feholdexcept_setroundf
+#endif
+#ifndef libc_feholdsetroundl
+# define libc_feholdsetroundl libc_feholdexcept_setroundl
+#endif
+
+/* ... and the reverse. */
+
+#ifndef libc_feresetround
+# define libc_feresetround libc_feupdateenv
+#endif
+#ifndef libc_feresetroundf
+# define libc_feresetroundf libc_feupdateenvf
+#endif
+#ifndef libc_feresetroundl
+# define libc_feresetroundl libc_feupdateenvl
+#endif
+
+/* ... and a version that also discards exceptions. */
+
+#ifndef libc_feresetround_noex
+# define libc_feresetround_noex libc_fesetenv
+#endif
+#ifndef libc_feresetround_noexf
+# define libc_feresetround_noexf libc_fesetenvf
+#endif
+#ifndef libc_feresetround_noexl
+# define libc_feresetround_noexl libc_fesetenvl
+#endif
+
+#ifndef HAVE_RM_CTX
+# define HAVE_RM_CTX 0
+#endif
+
+
+/* Default implementation using standard fenv functions.
+ Avoid unnecessary rounding mode changes by first checking the
+ current rounding mode. Note the use of unlikely is
+ important for performance. */
+
+static __always_inline void
+default_libc_feholdsetround_ctx (struct rm_ctx *ctx, int round)
+{
+ ctx->updated_status = false;
+
+ /* Update rounding mode only if different. */
+ if (unlikely (round != get_rounding_mode ()))
+ {
+ ctx->updated_status = true;
+ fegetenv (&ctx->env);
+ fesetround (round);
+ }
+}
+
+static __always_inline void
+default_libc_feresetround_ctx (struct rm_ctx *ctx)
+{
+ /* Restore the rounding mode if updated. */
+ if (unlikely (ctx->updated_status))
+ feupdateenv (&ctx->env);
+}
+
+static __always_inline void
+default_libc_feholdsetround_noex_ctx (struct rm_ctx *ctx, int round)
+{
+ /* Save exception flags and rounding mode, and disable exception
+ traps. */
+ feholdexcept (&ctx->env);
+
+ /* Update rounding mode only if different. */
+ if (unlikely (round != get_rounding_mode ()))
+ fesetround (round);
+}
+
+static __always_inline void
+default_libc_feresetround_noex_ctx (struct rm_ctx *ctx)
+{
+ /* Restore exception flags and rounding mode. */
+ fesetenv (&ctx->env);
+}
+
+#if HAVE_RM_CTX
+/* Set/Restore Rounding Modes only when necessary. If defined, these functions
+ set/restore floating point state only if the state needed within the lexical
+ block is different from the current state. This saves a lot of time when
+ the floating point unit is much slower than the fixed point units. */
+
+# ifndef libc_feholdsetround_noex_ctx
+# define libc_feholdsetround_noex_ctx libc_feholdsetround_ctx
+# endif
+# ifndef libc_feholdsetround_noexf_ctx
+# define libc_feholdsetround_noexf_ctx libc_feholdsetroundf_ctx
+# endif
+# ifndef libc_feholdsetround_noexl_ctx
+# define libc_feholdsetround_noexl_ctx libc_feholdsetroundl_ctx
+# endif
+
+# ifndef libc_feresetround_noex_ctx
+# define libc_feresetround_noex_ctx libc_fesetenv_ctx
+# endif
+# ifndef libc_feresetround_noexf_ctx
+# define libc_feresetround_noexf_ctx libc_fesetenvf_ctx
+# endif
+# ifndef libc_feresetround_noexl_ctx
+# define libc_feresetround_noexl_ctx libc_fesetenvl_ctx
+# endif
+
+#else
+
+# define libc_feholdsetround_ctx default_libc_feholdsetround_ctx
+# define libc_feresetround_ctx default_libc_feresetround_ctx
+# define libc_feholdsetround_noex_ctx default_libc_feholdsetround_noex_ctx
+# define libc_feresetround_noex_ctx default_libc_feresetround_noex_ctx
+
+# define libc_feholdsetroundf_ctx libc_feholdsetround_ctx
+# define libc_feholdsetroundl_ctx libc_feholdsetround_ctx
+# define libc_feresetroundf_ctx libc_feresetround_ctx
+# define libc_feresetroundl_ctx libc_feresetround_ctx
+
+# define libc_feholdsetround_noexf_ctx libc_feholdsetround_noex_ctx
+# define libc_feholdsetround_noexl_ctx libc_feholdsetround_noex_ctx
+# define libc_feresetround_noexf_ctx libc_feresetround_noex_ctx
+# define libc_feresetround_noexl_ctx libc_feresetround_noex_ctx
+
+#endif
+
+#ifndef libc_feholdsetround_53bit_ctx
+# define libc_feholdsetround_53bit_ctx libc_feholdsetround_ctx
+#endif
+#ifndef libc_feresetround_53bit_ctx
+# define libc_feresetround_53bit_ctx libc_feresetround_ctx
+#endif
+
+#define SET_RESTORE_ROUND_GENERIC(RM,ROUNDFUNC,CLEANUPFUNC) \
+ struct rm_ctx ctx __attribute__((cleanup (CLEANUPFUNC ## _ctx))); \
+ ROUNDFUNC ## _ctx (&ctx, (RM))
+
+/* Set the rounding mode within a lexical block. Restore the rounding mode to
+ the value at the start of the block. The exception mode must be preserved.
+ Exceptions raised within the block must be set in the exception flags.
+ Non-stop mode may be enabled inside the block. */
+
+#define SET_RESTORE_ROUND(RM) \
+ SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround, libc_feresetround)
+#define SET_RESTORE_ROUNDF(RM) \
+ SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetroundf, libc_feresetroundf)
+#define SET_RESTORE_ROUNDL(RM) \
+ SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetroundl, libc_feresetroundl)
+
+/* Set the rounding mode within a lexical block. Restore the rounding mode to
+ the value at the start of the block. The exception mode must be preserved.
+ Exceptions raised within the block must be discarded, and exception flags
+ are restored to the value at the start of the block.
+ Non-stop mode must be enabled inside the block. */
+
+#define SET_RESTORE_ROUND_NOEX(RM) \
+ SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround_noex, \
+ libc_feresetround_noex)
+#define SET_RESTORE_ROUND_NOEXF(RM) \
+ SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround_noexf, \
+ libc_feresetround_noexf)
+#define SET_RESTORE_ROUND_NOEXL(RM) \
+ SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround_noexl, \
+ libc_feresetround_noexl)
+
+/* Like SET_RESTORE_ROUND, but also set rounding precision to 53 bits. */
+#define SET_RESTORE_ROUND_53BIT(RM) \
+ SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround_53bit, \
+ libc_feresetround_53bit)
+
+#endif /* fenv_private.h. */
diff --git a/libm/arc/fesetenv.c b/libm/arc/fesetenv.c
new file mode 100644
index 000000000..59ec3b722
--- /dev/null
+++ b/libm/arc/fesetenv.c
@@ -0,0 +1,44 @@
+/* Install given floating-point environment (does not raise exceptions).
+ Copyright (C) 2020-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
+fesetenv (const fenv_t *envp)
+{
+ unsigned int fpcr;
+ unsigned int fpsr;
+
+ if (envp == FE_DFL_ENV)
+ {
+ fpcr = _FPU_DEFAULT;
+ fpsr = _FPU_FPSR_DEFAULT;
+ }
+ else
+ {
+ /* No need to mask out reserved bits as they are IoW. */
+ fpcr = envp->__fpcr;
+ fpsr = envp->__fpsr;
+ }
+
+ _FPU_SETCW (fpcr);
+ _FPU_SETS (fpsr);
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/arc/fesetexcept.c b/libm/arc/fesetexcept.c
new file mode 100644
index 000000000..3756a2e09
--- /dev/null
+++ b/libm/arc/fesetexcept.c
@@ -0,0 +1,31 @@
+/* Set given exception flags.
+ Copyright (C) 2020-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)
+{
+ unsigned int fpsr;
+
+ _FPU_GETS (fpsr);
+ fpsr |= excepts;
+ _FPU_SETS (fpsr);
+
+ return 0;
+}
diff --git a/libm/arc/fesetmode.c b/libm/arc/fesetmode.c
new file mode 100644
index 000000000..1fc2bdf12
--- /dev/null
+++ b/libm/arc/fesetmode.c
@@ -0,0 +1,39 @@
+/* Install given floating-point control modes.
+ Copyright (C) 2020-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
+fesetmode (const femode_t *modep)
+{
+ unsigned int fpcr;
+
+ if (modep == FE_DFL_MODE)
+ {
+ fpcr = _FPU_DEFAULT;
+ }
+ else
+ {
+ /* No need to mask out reserved bits as they are IoW. */
+ fpcr = *modep;
+ }
+
+ _FPU_SETCW (fpcr);
+
+ return 0;
+}
diff --git a/libm/arc/fesetround.c b/libm/arc/fesetround.c
new file mode 100644
index 000000000..e156e9cf5
--- /dev/null
+++ b/libm/arc/fesetround.c
@@ -0,0 +1,36 @@
+/* Set current rounding direction.
+ Copyright (C) 2020-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)
+{
+ unsigned int fpcr;
+
+ _FPU_GETCW (fpcr);
+
+ if (((fpcr >> __FPU_RND_SHIFT) & __FPU_RND_MASK) != round)
+ {
+ fpcr &= ~(__FPU_RND_MASK << __FPU_RND_SHIFT);
+ fpcr |= (round & __FPU_RND_MASK) << __FPU_RND_SHIFT;
+ _FPU_SETCW (fpcr);
+ }
+
+ return 0;
+}
diff --git a/libm/arc/feupdateenv.c b/libm/arc/feupdateenv.c
new file mode 100644
index 000000000..6a59b2bfe
--- /dev/null
+++ b/libm/arc/feupdateenv.c
@@ -0,0 +1,47 @@
+/* Install given floating-point environment and raise exceptions,
+ without clearing currently raised exceptions.
+ Copyright (C) 2020-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)
+{
+ unsigned int fpcr;
+ unsigned int fpsr;
+
+ _FPU_GETS (fpsr);
+
+ if (envp == FE_DFL_ENV)
+ {
+ fpcr = _FPU_DEFAULT;
+ }
+ else
+ {
+ fpcr = envp->__fpcr;
+
+ /* currently raised exceptions need to be preserved. */
+ fpsr |= envp->__fpsr;
+ }
+
+ _FPU_SETCW (fpcr);
+ _FPU_SETS (fpsr);
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/arc/fgetexcptflg.c b/libm/arc/fgetexcptflg.c
new file mode 100644
index 000000000..03f97f99f
--- /dev/null
+++ b/libm/arc/fgetexcptflg.c
@@ -0,0 +1,30 @@
+/* Store current representation for exceptions, ARC version.
+ Copyright (C) 2020-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)
+{
+ unsigned int fpsr;
+
+ _FPU_GETS (fpsr);
+ *flagp = fpsr & excepts;
+
+ return 0;
+}
diff --git a/libm/arc/fraiseexcpt.c b/libm/arc/fraiseexcpt.c
new file mode 100644
index 000000000..2ff5e0269
--- /dev/null
+++ b/libm/arc/fraiseexcpt.c
@@ -0,0 +1,35 @@
+/* Raise given exceptions.
+ Copyright (C) 2020-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>
+#include <float.h>
+#include <math.h>
+
+int
+feraiseexcept (int excepts)
+{
+ unsigned int fpsr;
+
+ /* currently raised exceptions are not cleared. */
+ _FPU_GETS (fpsr);
+ fpsr |= excepts;
+
+ _FPU_SETS (fpsr);
+
+ return 0;
+}
diff --git a/libm/arc/fsetexcptflg.c b/libm/arc/fsetexcptflg.c
new file mode 100644
index 000000000..97ff20fff
--- /dev/null
+++ b/libm/arc/fsetexcptflg.c
@@ -0,0 +1,37 @@
+/* Set floating-point environment exception handling, ARC version.
+ Copyright (C) 2020-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
+fesetexceptflag (const fexcept_t *flagp, int excepts)
+{
+ unsigned int fpsr;
+
+ _FPU_GETS (fpsr);
+
+ /* Clear the bits first. */
+ fpsr &= ~excepts;
+
+ /* Now set those bits, copying them over from @flagp. */
+ fpsr |= *flagp & excepts;
+
+ _FPU_SETS (fpsr);
+
+ return 0;
+}
diff --git a/libm/arc/ftestexcept.c b/libm/arc/ftestexcept.c
new file mode 100644
index 000000000..ccc557e5e
--- /dev/null
+++ b/libm/arc/ftestexcept.c
@@ -0,0 +1,31 @@
+/* Test exception in current environment.
+ Copyright (C) 2020-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>
+#include "fenv_private.h"
+#include <stdio.h>
+
+int
+fetestexcept (int excepts)
+{
+ unsigned int fpsr;
+
+ _FPU_GETS (fpsr);
+
+ return fpsr & excepts;
+}
diff --git a/libm/arc/get-rounding-mode.h b/libm/arc/get-rounding-mode.h
new file mode 100644
index 000000000..d1bf3475d
--- /dev/null
+++ b/libm/arc/get-rounding-mode.h
@@ -0,0 +1,37 @@
+/* Determine floating-point rounding mode within libc. ARC version.
+ Copyright (C) 2020-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 _ARC_GET_ROUNDING_MODE_H
+#define _ARC_GET_ROUNDING_MODE_H 1
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+static inline int
+get_rounding_mode (void)
+{
+#if defined(__ARC_FPU_SP__) || defined(__ARC_FPU_DP__)
+ unsigned int fpcr;
+ _FPU_GETCW (fpcr);
+
+ return (fpcr >> __FPU_RND_SHIFT) & __FPU_RND_MASK;
+#else
+ return FE_TONEAREST;
+#endif
+}
+
+#endif /* get-rounding-mode.h */
diff --git a/libm/csky/Makefile.arch b/libm/csky/Makefile.arch
new file mode 100644
index 000000000..bd38690be
--- /dev/null
+++ b/libm/csky/Makefile.arch
@@ -0,0 +1,16 @@
+# Makefile for uClibc-ng
+# Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
+
+ifeq ($(UCLIBC_HAS_FENV),y)
+libm_ARCH_SRC:=$(wildcard $(libm_ARCH_DIR)/*.c)
+libm_ARCH_OBJ:=$(patsubst $(libm_ARCH_DIR)/%.c,$(libm_ARCH_OUT)/%.o,$(libm_ARCH_SRC))
+endif
+
+libm_ARCH_OBJS:=$(libm_ARCH_OBJ)
+
+ifeq ($(DOPIC),y)
+libm-a-y+=$(libm_ARCH_OBJS:.o=.os)
+else
+libm-a-y+=$(libm_ARCH_OBJS)
+endif
+libm-so-y+=$(libm_ARCH_OBJS:.o=.os)
diff --git a/libm/csky/fclrexcpt.c b/libm/csky/fclrexcpt.c
new file mode 100644
index 000000000..8f8acef16
--- /dev/null
+++ b/libm/csky/fclrexcpt.c
@@ -0,0 +1,40 @@
+/* Clear given exceptions in current floating-point environment.
+ Copyright (C) 2018-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_libc.h"
+#include <fpu_control.h>
+
+int
+feclearexcept (int excepts)
+{
+ int fpsr;
+
+ /* Mask out unsupported bits/exceptions. */
+ excepts &= FE_ALL_EXCEPT;
+
+ /* Read the complete control word. */
+ _FPU_GETFPSR (fpsr);
+
+ /* Clear the relevant bits. */
+ fpsr &= ~(excepts | (excepts << CAUSE_SHIFT));
+
+ /* Put the new data in effect. */
+ _FPU_SETFPSR (fpsr);
+
+ return 0;
+}
diff --git a/libm/csky/fedisblxcpt.c b/libm/csky/fedisblxcpt.c
new file mode 100644
index 000000000..e518968ab
--- /dev/null
+++ b/libm/csky/fedisblxcpt.c
@@ -0,0 +1,40 @@
+/* Disable floating-point exceptions.
+ Copyright (C) 2018-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_libc.h"
+#include <fpu_control.h>
+
+int
+fedisableexcept (int excepts)
+{
+ unsigned int new_exc, old_exc;
+
+ /* Get the current control word. */
+ _FPU_GETCW (new_exc);
+
+ old_exc = (new_exc & ENABLE_MASK) >> ENABLE_SHIFT;
+
+ /* Get the except disable mask. */
+ excepts &= FE_ALL_EXCEPT;
+ new_exc &= ~(excepts << ENABLE_SHIFT);
+
+ /* Put the new data in effect. */
+ _FPU_SETCW (new_exc);
+
+ return old_exc;
+}
diff --git a/libm/csky/feenablxcpt.c b/libm/csky/feenablxcpt.c
new file mode 100644
index 000000000..90c495080
--- /dev/null
+++ b/libm/csky/feenablxcpt.c
@@ -0,0 +1,39 @@
+/* Enable floating-point exceptions.
+ Copyright (C) 2018-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_libc.h"
+#include <fpu_control.h>
+
+int
+feenableexcept (int excepts)
+{
+ unsigned int new_exc, old_exc;
+
+ /* Get the current control word. */
+ _FPU_GETCW (new_exc);
+
+ old_exc = (new_exc & ENABLE_MASK) >> ENABLE_SHIFT;
+
+ excepts &= FE_ALL_EXCEPT;
+
+ new_exc |= excepts << ENABLE_SHIFT;
+
+ _FPU_SETCW (new_exc);
+
+ return old_exc;
+}
diff --git a/libm/csky/fegetenv.c b/libm/csky/fegetenv.c
new file mode 100644
index 000000000..d98982fc1
--- /dev/null
+++ b/libm/csky/fegetenv.c
@@ -0,0 +1,33 @@
+/* Store current floating-point environment.
+ Copyright (C) 2018-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)
+{
+ unsigned int fpcr;
+ unsigned int fpsr;
+
+ _FPU_GETCW (fpcr);
+ _FPU_GETFPSR (fpsr);
+ envp->__fpcr = fpcr;
+ envp->__fpsr = fpsr;
+
+ return 0;
+}
diff --git a/libm/csky/fegetexcept.c b/libm/csky/fegetexcept.c
new file mode 100644
index 000000000..339f35923
--- /dev/null
+++ b/libm/csky/fegetexcept.c
@@ -0,0 +1,31 @@
+/* Get enabled floating-point exceptions.
+ Copyright (C) 2018-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_libc.h"
+#include <fpu_control.h>
+
+int
+fegetexcept (void)
+{
+ unsigned int exc;
+
+ /* Get the current control word. */
+ _FPU_GETCW (exc);
+
+ return (exc & ENABLE_MASK) >> ENABLE_SHIFT;
+}
diff --git a/libm/csky/fegetmode.c b/libm/csky/fegetmode.c
new file mode 100644
index 000000000..09d8282dd
--- /dev/null
+++ b/libm/csky/fegetmode.c
@@ -0,0 +1,27 @@
+/* Store current floating-point control modes.
+ Copyright (C) 2018-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;
+}
diff --git a/libm/csky/fegetround.c b/libm/csky/fegetround.c
new file mode 100644
index 000000000..e68775af3
--- /dev/null
+++ b/libm/csky/fegetround.c
@@ -0,0 +1,30 @@
+/* Return current rounding direction.
+ Copyright (C) 2018-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)
+{
+ unsigned int cw;
+
+ /* Get control word. */
+ _FPU_GETCW (cw);
+
+ return cw & __FE_ROUND_MASK;
+}
diff --git a/libm/csky/feholdexcpt.c b/libm/csky/feholdexcpt.c
new file mode 100644
index 000000000..456af5eb1
--- /dev/null
+++ b/libm/csky/feholdexcpt.c
@@ -0,0 +1,30 @@
+/* Store current floating-point environment and clear exceptions.
+ Copyright (C) 2018-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>
+#include "fenv_libc.h"
+#include "fenv_private.h"
+
+#include <stdio.h>
+
+int
+feholdexcept (fenv_t *envp)
+{
+ libc_feholdexcept_vfp (envp);
+ return 0;
+}
diff --git a/libm/csky/fenv_libc.h b/libm/csky/fenv_libc.h
new file mode 100644
index 000000000..44e89812d
--- /dev/null
+++ b/libm/csky/fenv_libc.h
@@ -0,0 +1,29 @@
+/* fpu registers environment. C-SKY version.
+ Copyright (C) 2018-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 _FENV_LIBC_H
+#define _FENV_LIBC_H 1
+
+/* Mask for enabling exceptions and for the CAUSE bits. */
+#define ENABLE_MASK 0x0003FU
+#define CAUSE_MASK 0x3F000U
+
+/* Shift for FE_* flags to get up to the ENABLE bits and the CAUSE bits. */
+#define ENABLE_SHIFT 0
+#define CAUSE_SHIFT 8
+
+#endif /* fenv_libc.h */
diff --git a/libm/csky/fenv_private.h b/libm/csky/fenv_private.h
new file mode 100644
index 000000000..f0f48a88a
--- /dev/null
+++ b/libm/csky/fenv_private.h
@@ -0,0 +1,277 @@
+/* Private floating point rounding and exceptions handling. C-SKY version.
+ Copyright (C) 2018-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 CSKY_FENV_PRIVATE_H
+#define CSKY_FENV_PRIVATE_H 1
+
+#include <fenv.h>
+#include <fpu_control.h>
+#include "fenv_libc.h"
+
+static __always_inline void
+libc_feholdexcept_vfp (fenv_t *envp)
+{
+ fpu_control_t fpsr, fpcr;
+
+ _FPU_GETCW (fpcr);
+ envp->__fpcr = fpcr;
+
+ _FPU_GETFPSR (fpsr);
+ envp->__fpsr = fpsr;
+
+ /* Now set all exceptions to non-stop. */
+ fpcr &= ~FE_ALL_EXCEPT;
+
+ /* And clear all exception flags. */
+ fpsr &= ~(FE_ALL_EXCEPT << CAUSE_SHIFT);
+
+ _FPU_SETFPSR (fpsr);
+
+ _FPU_SETCW (fpcr);
+}
+
+static __always_inline void
+libc_fesetround_vfp (int round)
+{
+ fpu_control_t fpcr;
+
+ _FPU_GETCW (fpcr);
+
+ /* Set new rounding mode if different. */
+ if (unlikely ((fpcr & FE_DOWNWARD) != round))
+ _FPU_SETCW ((fpcr & ~FE_DOWNWARD) | round);
+}
+
+static __always_inline void
+libc_feholdexcept_setround_vfp (fenv_t *envp, int round)
+{
+ fpu_control_t fpsr, fpcr;
+
+ _FPU_GETCW (fpcr);
+ envp->__fpcr = fpcr;
+
+ _FPU_GETFPSR (fpsr);
+ envp->__fpsr = fpsr;
+
+ /* Clear exception flags, set all exceptions to non-stop,
+ and set new rounding mode. */
+ fpsr &= ~(FE_ALL_EXCEPT << CAUSE_SHIFT);
+ _FPU_SETFPSR (fpsr);
+
+ fpcr &= ~(FE_ALL_EXCEPT | FE_DOWNWARD);
+ _FPU_SETCW (fpcr | round);
+}
+
+static __always_inline void
+libc_feholdsetround_vfp (fenv_t *envp, int round)
+{
+ fpu_control_t fpcr;
+
+ _FPU_GETCW (fpcr);
+ envp->__fpcr = fpcr;
+
+ /* Set new rounding mode if different. */
+ if (unlikely ((fpcr & FE_DOWNWARD) != round))
+ _FPU_SETCW ((fpcr & ~FE_DOWNWARD) | round);
+}
+
+static __always_inline void
+libc_feresetround_vfp (fenv_t *envp)
+{
+ fpu_control_t fpcr, round;
+
+ _FPU_GETCW (fpcr);
+
+ /* Check whether rounding modes are different. */
+ round = (envp->__fpcr ^ fpcr) & FE_DOWNWARD;
+
+ /* Restore the rounding mode if it was changed. */
+ if (unlikely (round != 0))
+ _FPU_SETCW (fpcr ^ round);
+}
+
+static __always_inline int
+libc_fetestexcept_vfp (int ex)
+{
+ fpu_control_t fpsr;
+
+ _FPU_GETFPSR (fpsr);
+ fpsr = fpsr >> CAUSE_SHIFT;
+ return fpsr & ex & FE_ALL_EXCEPT;
+}
+
+static __always_inline void
+libc_fesetenv_vfp (const fenv_t *envp)
+{
+ fpu_control_t fpcr, fpsr, new_fpcr, new_fpsr;
+
+ _FPU_GETCW (fpcr);
+ _FPU_GETFPSR (fpsr);
+
+ new_fpcr = envp->__fpcr;
+ new_fpsr = envp->__fpsr;
+
+ if (unlikely (fpsr ^ new_fpsr) != 0)
+ _FPU_SETFPSR (new_fpsr);
+
+ if (unlikely (fpcr ^ new_fpcr) != 0)
+ _FPU_SETCW (new_fpcr);
+}
+
+static __always_inline int
+libc_feupdateenv_test_vfp (const fenv_t *envp, int ex)
+{
+ fpu_control_t fpcr, fpsr, new_fpcr, new_fpsr, excepts;
+
+ _FPU_GETCW (fpcr);
+ _FPU_GETFPSR (fpsr);
+
+ /* Merge current exception flags with the saved fenv. */
+ excepts = (fpsr >> CAUSE_SHIFT) & FE_ALL_EXCEPT;
+ new_fpcr = envp->__fpcr;
+ new_fpsr = envp->__fpsr | (excepts << CAUSE_SHIFT);
+
+ /* Write FCR and FESR if different. */
+ if (unlikely (fpsr ^ new_fpsr) != 0)
+ _FPU_SETFPSR (new_fpsr);
+
+ if (unlikely (fpcr ^ new_fpcr) != 0)
+ _FPU_SETCW (new_fpcr);
+
+ /* Raise the exceptions if enabled in the new FP state. */
+ if (unlikely (excepts & new_fpcr))
+ feraiseexcept (excepts);
+
+ return excepts & ex;
+}
+
+static __always_inline void
+libc_feupdateenv_vfp (const fenv_t *envp)
+{
+ libc_feupdateenv_test_vfp (envp, 0);
+}
+
+static __always_inline void
+libc_feholdsetround_vfp_ctx (struct rm_ctx *ctx, int r)
+{
+ fpu_control_t fpcr, fpsr, round;
+
+ _FPU_GETCW (fpcr);
+ _FPU_GETFPSR (fpsr);
+ ctx->updated_status = false;
+ ctx->env.__fpcr = fpcr;
+ ctx->env.__fpsr = fpsr;
+
+ /* Check whether rounding modes are different. */
+ round = (fpcr ^ r) & FE_DOWNWARD;
+
+ /* Set the rounding mode if changed. */
+ if (unlikely (round != 0))
+ {
+ ctx->updated_status = true;
+ _FPU_SETCW (fpcr ^ round);
+ }
+}
+
+static __always_inline void
+libc_feresetround_vfp_ctx (struct rm_ctx *ctx)
+{
+ /* Restore the rounding mode if updated. */
+ if (unlikely (ctx->updated_status))
+ {
+ fpu_control_t fpcr;
+
+ _FPU_GETCW (fpcr);
+ fpcr = (fpcr & ~FE_DOWNWARD) | (ctx->env.__fpcr & FE_DOWNWARD);
+ _FPU_SETCW (fpcr);
+ }
+}
+
+static __always_inline void
+libc_fesetenv_vfp_ctx (struct rm_ctx *ctx)
+{
+ fpu_control_t fpcr, fpsr, new_fpcr, new_fpsr;
+
+ _FPU_GETCW (fpcr);
+ _FPU_GETFPSR (fpsr);
+
+ new_fpcr = ctx->env.__fpcr;
+ new_fpsr = ctx->env.__fpsr;
+
+ if (unlikely (fpsr ^ new_fpsr) != 0)
+ _FPU_SETFPSR (new_fpsr);
+
+ if (unlikely (fpcr ^ new_fpcr) != 0)
+ _FPU_SETCW (new_fpcr);
+}
+
+#define libc_feholdexcept libc_feholdexcept_vfp
+#define libc_feholdexceptf libc_feholdexcept_vfp
+#define libc_feholdexceptl libc_feholdexcept_vfp
+
+#define libc_fesetround libc_fesetround_vfp
+#define libc_fesetroundf libc_fesetround_vfp
+#define libc_fesetroundl libc_fesetround_vfp
+
+#define libc_feresetround libc_feresetround_vfp
+#define libc_feresetroundf libc_feresetround_vfp
+#define libc_feresetroundl libc_feresetround_vfp
+
+#define libc_feresetround_noex libc_fesetenv_vfp
+#define libc_feresetround_noexf libc_fesetenv_vfp
+#define libc_feresetround_noexl libc_fesetenv_vfp
+
+#define libc_feholdexcept_setround libc_feholdexcept_setround_vfp
+#define libc_feholdexcept_setroundf libc_feholdexcept_setround_vfp
+#define libc_feholdexcept_setroundl libc_feholdexcept_setround_vfp
+
+#define libc_feholdsetround libc_feholdsetround_vfp
+#define libc_feholdsetroundf libc_feholdsetround_vfp
+#define libc_feholdsetroundl libc_feholdsetround_vfp
+
+#define libc_fetestexcept libc_fetestexcept_vfp
+#define libc_fetestexceptf libc_fetestexcept_vfp
+#define libc_fetestexceptl libc_fetestexcept_vfp
+
+#define libc_fesetenv libc_fesetenv_vfp
+#define libc_fesetenvf libc_fesetenv_vfp
+#define libc_fesetenvl libc_fesetenv_vfp
+
+#define libc_feupdateenv libc_feupdateenv_vfp
+#define libc_feupdateenvf libc_feupdateenv_vfp
+#define libc_feupdateenvl libc_feupdateenv_vfp
+
+#define libc_feupdateenv_test libc_feupdateenv_test_vfp
+#define libc_feupdateenv_testf libc_feupdateenv_test_vfp
+#define libc_feupdateenv_testl libc_feupdateenv_test_vfp
+
+/* We have support for rounding mode context. */
+#define HAVE_RM_CTX 1
+
+#define libc_feholdsetround_ctx libc_feholdsetround_vfp_ctx
+#define libc_feresetround_ctx libc_feresetround_vfp_ctx
+#define libc_feresetround_noex_ctx libc_fesetenv_vfp_ctx
+
+#define libc_feholdsetroundf_ctx libc_feholdsetround_vfp_ctx
+#define libc_feresetroundf_ctx libc_feresetround_vfp_ctx
+#define libc_feresetround_noexf_ctx libc_fesetenv_vfp_ctx
+
+#define libc_feholdsetroundl_ctx libc_feholdsetround_vfp_ctx
+#define libc_feresetroundl_ctx libc_feresetround_vfp_ctx
+#define libc_feresetround_noexl_ctx libc_fesetenv_vfp_ctx
+
+#endif /* CSKY_FENV_PRIVATE_H */
diff --git a/libm/csky/fesetenv.c b/libm/csky/fesetenv.c
new file mode 100644
index 000000000..96b961598
--- /dev/null
+++ b/libm/csky/fesetenv.c
@@ -0,0 +1,55 @@
+/* Install given floating-point environment.
+ Copyright (C) 2018-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
+fesetenv (const fenv_t *envp)
+{
+ unsigned int fpcr;
+ unsigned int fpsr;
+
+ _FPU_GETCW (fpcr);
+ _FPU_GETFPSR (fpsr);
+
+ fpcr &= _FPU_RESERVED;
+ fpsr &= _FPU_FPSR_RESERVED;
+
+ if (envp == FE_DFL_ENV)
+ {
+ fpcr |= _FPU_DEFAULT;
+ fpsr |= _FPU_FPSR_DEFAULT;
+ }
+ else if (envp == FE_NOMASK_ENV)
+ {
+ fpcr |= _FPU_FPCR_IEEE;
+ fpsr |= _FPU_FPSR_IEEE;
+ }
+ else
+ {
+ fpcr |= envp->__fpcr & ~_FPU_RESERVED;
+ fpsr |= envp->__fpsr & ~_FPU_FPSR_RESERVED;
+ }
+
+ _FPU_SETFPSR (fpsr);
+
+ _FPU_SETCW (fpcr);
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/csky/fesetexcept.c b/libm/csky/fesetexcept.c
new file mode 100644
index 000000000..940322197
--- /dev/null
+++ b/libm/csky/fesetexcept.c
@@ -0,0 +1,32 @@
+/* Set given exception flags.
+ Copyright (C) 2018-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>
+#include "fenv_libc.h"
+
+int
+fesetexcept (int excepts)
+{
+ fpu_control_t fpsr, new_fpsr;
+ _FPU_GETFPSR (fpsr);
+ new_fpsr = fpsr | ((excepts & FE_ALL_EXCEPT) << CAUSE_SHIFT);
+ if (new_fpsr != fpsr)
+ _FPU_SETFPSR (new_fpsr);
+
+ return 0;
+}
diff --git a/libm/csky/fesetmode.c b/libm/csky/fesetmode.c
new file mode 100644
index 000000000..eddd2d401
--- /dev/null
+++ b/libm/csky/fesetmode.c
@@ -0,0 +1,32 @@
+/* Install given floating-point control modes.
+ Copyright (C) 2018-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
+fesetmode (const femode_t *modep)
+{
+ femode_t mode;
+ if (modep == FE_DFL_MODE)
+ mode = _FPU_DEFAULT;
+ else
+ mode = *modep;
+ _FPU_SETCW (mode);
+
+ return 0;
+}
diff --git a/libm/csky/fesetround.c b/libm/csky/fesetround.c
new file mode 100644
index 000000000..15a4b7c7e
--- /dev/null
+++ b/libm/csky/fesetround.c
@@ -0,0 +1,28 @@
+/* Set current rounding direction.
+ Copyright (C) 2018-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>
+#include "fenv_private.h"
+
+#include <stdio.h>
+int
+fesetround (int round)
+{
+ libc_fesetround_vfp (round);
+ return 0;
+}
diff --git a/libm/csky/feupdateenv.c b/libm/csky/feupdateenv.c
new file mode 100644
index 000000000..91e627ad2
--- /dev/null
+++ b/libm/csky/feupdateenv.c
@@ -0,0 +1,42 @@
+/* Install given floating-point environment and raise exceptions.
+ Copyright (C) 2018-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>
+#include "fenv_libc.h"
+#include "fenv_private.h"
+#include <stdio.h>
+
+int
+feupdateenv (const fenv_t *envp)
+{
+ int temp;
+
+ /* Save current exceptions. */
+ _FPU_GETFPSR (temp);
+ temp = (temp >> CAUSE_SHIFT) & 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);
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/csky/fgetexcptflg.c b/libm/csky/fgetexcptflg.c
new file mode 100644
index 000000000..c400a2c1f
--- /dev/null
+++ b/libm/csky/fgetexcptflg.c
@@ -0,0 +1,31 @@
+/* Store current representation for exceptions.
+ Copyright (C) 2018-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>
+#include "fenv_libc.h"
+#include "fenv_private.h"
+#include <stdio.h>
+
+int
+fegetexceptflag (fexcept_t *flagp, int excepts)
+{
+ *flagp = libc_fetestexcept_vfp (excepts);
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/csky/fraiseexcpt.c b/libm/csky/fraiseexcpt.c
new file mode 100644
index 000000000..31cd32f2c
--- /dev/null
+++ b/libm/csky/fraiseexcpt.c
@@ -0,0 +1,122 @@
+/* Raise given exceptions.
+ Copyright (C) 2018-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_libc.h"
+#include <fpu_control.h>
+#include <float.h>
+#include <math.h>
+
+int
+feraiseexcept (int excepts)
+{
+ /* Raise exceptions represented by EXCEPTS. But we must raise only one
+ signal at a time. It is important that if the overflow/underflow
+ exception and the divide by zero exception are given at the same
+ time, the overflow/underflow exception follows the divide by zero
+ exception. */
+
+# ifndef __csky_fpuv1__
+ /* First: invalid exception. */
+ if (FE_INVALID & excepts)
+ {
+ /* One example of a invalid operation is 0 * Infinity. */
+ float x = HUGE_VALF, y = 0.0f;
+ __asm__ __volatile__ ("fmuls %0, %0, %1" : "+v" (x) : "v" (y));
+ }
+
+ /* Next: division by zero. */
+ if (FE_DIVBYZERO & excepts)
+ {
+ float x = 1.0f, y = 0.0f;
+ __asm__ __volatile__ ("fdivs %0, %0, %1" : "+v" (x) : "v" (y));
+ }
+
+ /* Next: overflow. */
+ if (FE_OVERFLOW & excepts)
+ {
+ float x = FLT_MAX;
+ __asm__ __volatile__ ("fmuls %0, %0, %0" : "+v" (x));
+ }
+ /* Next: underflow. */
+ if (FE_UNDERFLOW & excepts)
+ {
+ float x = -FLT_MIN;
+
+ __asm__ __volatile__ ("fmuls %0, %0, %0" : "+v" (x));
+ }
+
+ /* Last: inexact. */
+ if (FE_INEXACT & excepts)
+ {
+ float x = 1.0f, y = 3.0f;
+ __asm__ __volatile__ ("fdivs %0, %0, %1" : "+v" (x) : "v" (y));
+ }
+
+ if (__FE_DENORMAL & excepts)
+ {
+ double x = 4.9406564584124654e-324;
+ __asm__ __volatile__ ("fstod %0, %0" : "+v" (x));
+ }
+# else
+ int tmp = 0;
+ /* First: invalid exception. */
+ if (FE_INVALID & excepts)
+ {
+ /* One example of a invalid operation is 0 * Infinity. */
+ float x = HUGE_VALF, y = 0.0f;
+ __asm__ __volatile__ ("fmuls %0, %0, %2, %1"
+ : "+f" (x), "+r"(tmp) : "f" (y));
+ }
+
+ /* Next: division by zero. */
+ if (FE_DIVBYZERO & excepts)
+ {
+ float x = 1.0f, y = 0.0f;
+ __asm__ __volatile__ ("fdivs %0, %0, %2, %1"
+ : "+f" (x), "+r"(tmp) : "f" (y));
+ }
+
+ /* Next: overflow. */
+ if (FE_OVERFLOW & excepts)
+ {
+ float x = FLT_MAX, y = FLT_MAX;
+ __asm__ __volatile__ ("fmuls %0, %0, %2, %1"
+ : "+f" (x), "+r"(tmp) : "f" (y));
+ }
+
+ /* Next: underflow. */
+ if (FE_UNDERFLOW & excepts)
+ {
+ float x = -FLT_MIN, y = -FLT_MIN;
+
+ __asm__ __volatile__ ("fmuls %0, %0, %2, %1"
+ : "+f" (x), "+r"(tmp) : "f" (y));
+ }
+
+ /* Last: inexact. */
+ if (FE_INEXACT & excepts)
+ {
+ float x = 1.0f, y = 3.0f;
+ __asm__ __volatile__ ("fdivs %0, %0, %2, %1"
+ : "+f" (x), "+r"(tmp) : "f" (y));
+ }
+# endif /* __csky_fpuv2__ */
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/csky/fsetexcptflg.c b/libm/csky/fsetexcptflg.c
new file mode 100644
index 000000000..b6281d5c2
--- /dev/null
+++ b/libm/csky/fsetexcptflg.c
@@ -0,0 +1,42 @@
+/* Set floating-point environment exception handling.
+ Copyright (C) 2018-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>
+#include "fenv_libc.h"
+
+int
+fesetexceptflag (const fexcept_t *flagp, int excepts)
+{
+ fpu_control_t temp;
+
+ /* Get the current exceptions. */
+ _FPU_GETFPSR (temp);
+
+ /* 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. */
+ temp = ((temp >> CAUSE_SHIFT) & ~excepts) | (*flagp & excepts);
+ temp = temp << CAUSE_SHIFT;
+
+ _FPU_SETFPSR (temp);
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/csky/ftestexcept.c b/libm/csky/ftestexcept.c
new file mode 100644
index 000000000..6e3217eb1
--- /dev/null
+++ b/libm/csky/ftestexcept.c
@@ -0,0 +1,28 @@
+/* Test exception in current environment.
+ Copyright (C) 2018-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>
+#include "fenv_libc.h"
+#include "fenv_private.h"
+#include <stdio.h>
+
+int
+fetestexcept (int excepts)
+{
+ return libc_fetestexcept_vfp (excepts);
+}
diff --git a/libm/sh/sh4/Makefile.arch b/libm/sh/sh4/Makefile.arch
index e38e99c15..69996edda 100644
--- a/libm/sh/sh4/Makefile.arch
+++ b/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
diff --git a/libm/sh/sh4/fclrexcpt.c b/libm/sh/sh4/fclrexcpt.c
new file mode 100644
index 000000000..286b4f36a
--- /dev/null
+++ b/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;
+}
diff --git a/libm/sh/sh4/fedisblxcpt.c b/libm/sh/sh4/fedisblxcpt.c
new file mode 100644
index 000000000..69f9ff2c4
--- /dev/null
+++ b/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;
+}
diff --git a/libm/sh/sh4/feenablxcpt.c b/libm/sh/sh4/feenablxcpt.c
new file mode 100644
index 000000000..bf2b01f0b
--- /dev/null
+++ b/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;
+}
diff --git a/libm/sh/sh4/fegetenv.c b/libm/sh/sh4/fegetenv.c
new file mode 100644
index 000000000..d76964f8b
--- /dev/null
+++ b/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;
+}
diff --git a/libm/sh/sh4/fegetexcept.c b/libm/sh/sh4/fegetexcept.c
new file mode 100644
index 000000000..85f783520
--- /dev/null
+++ b/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;
+}
diff --git a/libm/sh/sh4/fegetmode.c b/libm/sh/sh4/fegetmode.c
new file mode 100644
index 000000000..16deb5183
--- /dev/null
+++ b/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;
+}
diff --git a/libm/sh/sh4/fegetround.c b/libm/sh/sh4/fegetround.c
new file mode 100644
index 000000000..b7c26eb6f
--- /dev/null
+++ b/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;
+}
diff --git a/libm/sh/sh4/feholdexcpt.c b/libm/sh/sh4/feholdexcpt.c
index 70b51e8dd..fc462b403 100644
--- a/libm/sh/sh4/feholdexcpt.c
+++ b/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;
}
diff --git a/libm/sh/sh4/fesetenv.c b/libm/sh/sh4/fesetenv.c
index c5cfc1d51..6a9a68090 100644
--- a/libm/sh/sh4/fesetenv.c
+++ b/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;
diff --git a/libm/sh/sh4/fesetexcept.c b/libm/sh/sh4/fesetexcept.c
new file mode 100644
index 000000000..eceb0bb4f
--- /dev/null
+++ b/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;
+}
diff --git a/libm/sh/sh4/fesetmode.c b/libm/sh/sh4/fesetmode.c
new file mode 100644
index 000000000..073da0984
--- /dev/null
+++ b/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;
+}
diff --git a/libm/sh/sh4/fesetround.c b/libm/sh/sh4/fesetround.c
new file mode 100644
index 000000000..144eca86f
--- /dev/null
+++ b/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;
+}
diff --git a/libm/sh/sh4/feupdateenv.c b/libm/sh/sh4/feupdateenv.c
new file mode 100644
index 000000000..cb7e95259
--- /dev/null
+++ b/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;
+}
diff --git a/libm/sh/sh4/fgetexcptflg.c b/libm/sh/sh4/fgetexcptflg.c
new file mode 100644
index 000000000..308b5ad44
--- /dev/null
+++ b/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;
+}
diff --git a/libm/sh/sh4/fraiseexcpt.c b/libm/sh/sh4/fraiseexcpt.c
new file mode 100644
index 000000000..1ed495b7a
--- /dev/null
+++ b/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;
+}
diff --git a/libm/sh/sh4/fsetexcptflg.c b/libm/sh/sh4/fsetexcptflg.c
new file mode 100644
index 000000000..8fcb94973
--- /dev/null
+++ b/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;
+}
diff --git a/libm/sh/sh4/ftestexcept.c b/libm/sh/sh4/ftestexcept.c
new file mode 100644
index 000000000..edc523426
--- /dev/null
+++ b/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;
+}
diff --git a/libm/sparc/Makefile.arch b/libm/sparc/Makefile.arch
new file mode 100644
index 000000000..bd38690be
--- /dev/null
+++ b/libm/sparc/Makefile.arch
@@ -0,0 +1,16 @@
+# Makefile for uClibc-ng
+# Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
+
+ifeq ($(UCLIBC_HAS_FENV),y)
+libm_ARCH_SRC:=$(wildcard $(libm_ARCH_DIR)/*.c)
+libm_ARCH_OBJ:=$(patsubst $(libm_ARCH_DIR)/%.c,$(libm_ARCH_OUT)/%.o,$(libm_ARCH_SRC))
+endif
+
+libm_ARCH_OBJS:=$(libm_ARCH_OBJ)
+
+ifeq ($(DOPIC),y)
+libm-a-y+=$(libm_ARCH_OBJS:.o=.os)
+else
+libm-a-y+=$(libm_ARCH_OBJS)
+endif
+libm-so-y+=$(libm_ARCH_OBJS:.o=.os)
diff --git a/libm/sparc/fclrexcpt.c b/libm/sparc/fclrexcpt.c
new file mode 100644
index 000000000..ae344658d
--- /dev/null
+++ b/libm/sparc/fclrexcpt.c
@@ -0,0 +1,34 @@
+/* Clear given exceptions in current floating-point environment.
+ Copyright (C) 1997-2025 Free Software Foundation, Inc.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include "fenv_private.h"
+
+int
+feclearexcept (int excepts)
+{
+ fenv_t tmp;
+
+ __fenv_stfsr (tmp);
+
+ tmp &= ~(excepts & FE_ALL_EXCEPT);
+
+ __fenv_ldfsr (tmp);
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/sparc/fedisblxcpt.c b/libm/sparc/fedisblxcpt.c
new file mode 100644
index 000000000..9bc546f2d
--- /dev/null
+++ b/libm/sparc/fedisblxcpt.c
@@ -0,0 +1,34 @@
+/* Disable floating-point exceptions.
+ Copyright (C) 2000-2025 Free Software Foundation, Inc.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include "fenv_private.h"
+
+int
+fedisableexcept (int excepts)
+{
+ fenv_t new_exc, old_exc;
+
+ __fenv_stfsr (new_exc);
+
+ old_exc = (new_exc >> 18) & FE_ALL_EXCEPT;
+ new_exc &= ~(((fenv_t)excepts & FE_ALL_EXCEPT) << 18);
+
+ __fenv_ldfsr (new_exc);
+
+ return old_exc;
+}
diff --git a/libm/sparc/feenablxcpt.c b/libm/sparc/feenablxcpt.c
new file mode 100644
index 000000000..ab88e7e42
--- /dev/null
+++ b/libm/sparc/feenablxcpt.c
@@ -0,0 +1,34 @@
+/* Enable floating-point exceptions.
+ Copyright (C) 2000-2025 Free Software Foundation, Inc.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include "fenv_private.h"
+
+int
+feenableexcept (int excepts)
+{
+ fenv_t new_exc, old_exc;
+
+ __fenv_stfsr (new_exc);
+
+ old_exc = (new_exc >> 18) & FE_ALL_EXCEPT;
+ new_exc |= (((fenv_t)excepts & FE_ALL_EXCEPT) << 18);
+
+ __fenv_ldfsr (new_exc);
+
+ return old_exc;
+}
diff --git a/libm/sparc/fegetenv.c b/libm/sparc/fegetenv.c
new file mode 100644
index 000000000..883012932
--- /dev/null
+++ b/libm/sparc/fegetenv.c
@@ -0,0 +1,28 @@
+/* Store current floating-point environment.
+ Copyright (C) 1997-2025 Free Software Foundation, Inc.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include "fenv_private.h"
+
+int
+fegetenv (fenv_t *envp)
+{
+ __fenv_stfsr (*envp);
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/sparc/fegetexcept.c b/libm/sparc/fegetexcept.c
new file mode 100644
index 000000000..53dfdab8c
--- /dev/null
+++ b/libm/sparc/fegetexcept.c
@@ -0,0 +1,28 @@
+/* Get enabled floating-point exceptions.
+ Copyright (C) 2000-2025 Free Software Foundation, Inc.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include "fenv_private.h"
+
+int
+fegetexcept (void)
+{
+ fenv_t exc;
+ __fenv_stfsr (exc);
+
+ return (exc >> 18) & FE_ALL_EXCEPT;
+}
diff --git a/libm/sparc/fegetmode.c b/libm/sparc/fegetmode.c
new file mode 100644
index 000000000..0bb9ba111
--- /dev/null
+++ b/libm/sparc/fegetmode.c
@@ -0,0 +1,26 @@
+/* Store current floating-point control modes. SPARC version.
+ Copyright (C) 2016-2025 Free Software Foundation, Inc.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include "fenv_private.h"
+
+int
+fegetmode (femode_t *modep)
+{
+ __fenv_stfsr (*modep);
+ return 0;
+}
diff --git a/libm/sparc/fegetround.c b/libm/sparc/fegetround.c
new file mode 100644
index 000000000..bb53a735e
--- /dev/null
+++ b/libm/sparc/fegetround.c
@@ -0,0 +1,29 @@
+/* Return current rounding direction.
+ Copyright (C) 1997-2025 Free Software Foundation, Inc.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include "fenv_private.h"
+
+int
+fegetround (void)
+{
+ fenv_t tmp;
+
+ __fenv_stfsr (tmp);
+
+ return tmp & __FE_ROUND_MASK;
+}
diff --git a/libm/sparc/feholdexcpt.c b/libm/sparc/feholdexcpt.c
new file mode 100644
index 000000000..7d712198b
--- /dev/null
+++ b/libm/sparc/feholdexcpt.c
@@ -0,0 +1,34 @@
+/* Store current floating-point environment and clear exceptions.
+ Copyright (C) 1997-2025 Free Software Foundation, Inc.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include "fenv_private.h"
+
+int
+feholdexcept (fenv_t *envp)
+{
+ fenv_t tmp;
+
+ __fenv_stfsr (*envp);
+
+ /* Set all exceptions to non-stop and clear all exceptions. */
+ tmp = *envp & ~((0x1f << 23) | FE_ALL_EXCEPT);
+
+ __fenv_ldfsr (tmp);
+
+ return 0;
+}
diff --git a/libm/sparc/fenv_private.h b/libm/sparc/fenv_private.h
new file mode 100644
index 000000000..b888d8442
--- /dev/null
+++ b/libm/sparc/fenv_private.h
@@ -0,0 +1,187 @@
+#ifndef SPARC_FENV_PRIVATE_H
+#define SPARC_FENV_PRIVATE_H 1
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+/* For internal use only: access the fp state register. */
+#define __fenv_stfsr(X) _FPU_GETCW (X)
+#define __fenv_ldfsr(X) _FPU_SETCW (X)
+
+static __always_inline void
+libc_feholdexcept (fenv_t *e)
+{
+ fenv_t etmp;
+ __fenv_stfsr(etmp);
+ *(e) = etmp;
+ etmp = etmp & ~((0x1f << 23) | FE_ALL_EXCEPT);
+ __fenv_ldfsr(etmp);
+}
+
+static __always_inline void
+libc_fesetround (int r)
+{
+ fenv_t etmp;
+ __fenv_stfsr(etmp);
+ etmp = (etmp & ~__FE_ROUND_MASK) | (r);
+ __fenv_ldfsr(etmp);
+}
+
+static __always_inline void
+libc_feholdexcept_setround (fenv_t *e, int r)
+{
+ fenv_t etmp;
+ __fenv_stfsr(etmp);
+ *(e) = etmp;
+ etmp = etmp & ~((0x1f << 23) | FE_ALL_EXCEPT);
+ etmp = (etmp & ~__FE_ROUND_MASK) | (r);
+ __fenv_ldfsr(etmp);
+}
+
+static __always_inline int
+libc_fetestexcept (int e)
+{
+ fenv_t etmp;
+ __fenv_stfsr(etmp);
+ return etmp & (e) & FE_ALL_EXCEPT;
+}
+
+static __always_inline void
+libc_fesetenv (fenv_t *e)
+{
+ __fenv_ldfsr(*e);
+}
+
+static __always_inline int
+libc_feupdateenv_test (fenv_t *e, int ex)
+{
+ fenv_t etmp;
+
+ __fenv_stfsr(etmp);
+ etmp &= FE_ALL_EXCEPT;
+
+ __fenv_ldfsr(*e);
+
+ feraiseexcept (etmp);
+
+ return etmp & ex;
+}
+
+static __always_inline void
+libc_feupdateenv (fenv_t *e)
+{
+ libc_feupdateenv_test (e, 0);
+}
+
+static __always_inline void
+libc_feholdsetround (fenv_t *e, int r)
+{
+ fenv_t etmp;
+ __fenv_stfsr(etmp);
+ *(e) = etmp;
+ etmp = (etmp & ~__FE_ROUND_MASK) | (r);
+ __fenv_ldfsr(etmp);
+}
+
+static __always_inline void
+libc_feresetround (fenv_t *e)
+{
+ fenv_t etmp;
+ __fenv_stfsr(etmp);
+ etmp = (etmp & ~__FE_ROUND_MASK) | (*e & __FE_ROUND_MASK);
+ __fenv_ldfsr(etmp);
+}
+
+#define libc_feholdexceptf libc_feholdexcept
+#define libc_fesetroundf libc_fesetround
+#define libc_feholdexcept_setroundf libc_feholdexcept_setround
+#define libc_fetestexceptf libc_fetestexcept
+#define libc_fesetenvf libc_fesetenv
+#define libc_feupdateenv_testf libc_feupdateenv_test
+#define libc_feupdateenvf libc_feupdateenv
+#define libc_feholdsetroundf libc_feholdsetround
+#define libc_feresetroundf libc_feresetround
+#define libc_feholdexcept libc_feholdexcept
+#define libc_fesetround libc_fesetround
+#define libc_feholdexcept_setround libc_feholdexcept_setround
+#define libc_fetestexcept libc_fetestexcept
+#define libc_fesetenv libc_fesetenv
+#define libc_feupdateenv_test libc_feupdateenv_test
+#define libc_feupdateenv libc_feupdateenv
+#define libc_feholdsetround libc_feholdsetround
+#define libc_feresetround libc_feresetround
+#define libc_feholdexceptl libc_feholdexcept
+#define libc_fesetroundl libc_fesetround
+#define libc_feholdexcept_setroundl libc_feholdexcept_setround
+#define libc_fetestexceptl libc_fetestexcept
+#define libc_fesetenvl libc_fesetenv
+#define libc_feupdateenv_testl libc_feupdateenv_test
+#define libc_feupdateenvl libc_feupdateenv
+#define libc_feholdsetroundl libc_feholdsetround
+#define libc_feresetroundl libc_feresetround
+
+/* We have support for rounding mode context. */
+#define HAVE_RM_CTX 1
+
+static __always_inline void
+libc_feholdexcept_setround_sparc_ctx (struct rm_ctx *ctx, int round)
+{
+ fenv_t new;
+
+ __fenv_stfsr(ctx->env);
+ new = ctx->env & ~((0x1f << 23) | FE_ALL_EXCEPT);
+ new = (new & ~__FE_ROUND_MASK) | round;
+ if (unlikely (new != ctx->env))
+ {
+ __fenv_ldfsr(new);
+ ctx->updated_status = true;
+ }
+ else
+ ctx->updated_status = false;
+}
+
+static __always_inline void
+libc_fesetenv_sparc_ctx (struct rm_ctx *ctx)
+{
+ libc_fesetenv(&ctx->env);
+}
+
+static __always_inline void
+libc_feupdateenv_sparc_ctx (struct rm_ctx *ctx)
+{
+ if (unlikely (ctx->updated_status))
+ libc_feupdateenv_test (&ctx->env, 0);
+}
+
+static __always_inline void
+libc_feholdsetround_sparc_ctx (struct rm_ctx *ctx, int round)
+{
+ fenv_t new;
+
+ __fenv_stfsr(ctx->env);
+ new = (ctx->env & ~__FE_ROUND_MASK) | round;
+ if (unlikely (new != ctx->env))
+ {
+ __fenv_ldfsr(new);
+ ctx->updated_status = true;
+ }
+ else
+ ctx->updated_status = false;
+}
+#define libc_feholdexcept_setround_ctx libc_feholdexcept_setround_sparc_ctx
+#define libc_feholdexcept_setroundf_ctx libc_feholdexcept_setround_sparc_ctx
+#define libc_feholdexcept_setroundl_ctx libc_feholdexcept_setround_sparc_ctx
+#define libc_fesetenv_ctx libc_fesetenv_sparc_ctx
+#define libc_fesetenvf_ctx libc_fesetenv_sparc_ctx
+#define libc_fesetenvl_ctx libc_fesetenv_sparc_ctx
+#define libc_feupdateenv_ctx libc_feupdateenv_sparc_ctx
+#define libc_feupdateenvf_ctx libc_feupdateenv_sparc_ctx
+#define libc_feupdateenvl_ctx libc_feupdateenv_sparc_ctx
+#define libc_feresetround_ctx libc_feupdateenv_sparc_ctx
+#define libc_feresetroundf_ctx libc_feupdateenv_sparc_ctx
+#define libc_feresetroundl_ctx libc_feupdateenv_sparc_ctx
+#define libc_feholdsetround_ctx libc_feholdsetround_sparc_ctx
+#define libc_feholdsetroundf_ctx libc_feholdsetround_sparc_ctx
+#define libc_feholdsetroundl_ctx libc_feholdsetround_sparc_ctx
+
+#endif /* SPARC_FENV_PRIVATE_H */
diff --git a/libm/sparc/fesetenv.c b/libm/sparc/fesetenv.c
new file mode 100644
index 000000000..d6f3dc5f5
--- /dev/null
+++ b/libm/sparc/fesetenv.c
@@ -0,0 +1,45 @@
+/* Install given floating-point environment.
+ Copyright (C) 1997-2025 Free Software Foundation, Inc.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include "fenv_private.h"
+
+int
+fesetenv (const fenv_t *envp)
+{
+ fenv_t dummy;
+
+ /* Put these constants in memory explicitly, so as to cope with a
+ -fPIC bug as of gcc 970624. Making them automatic is quicker
+ than loading up the pic register in this instance. */
+
+ if (envp == FE_DFL_ENV)
+ {
+ dummy = 0;
+ envp = &dummy;
+ }
+ else if (envp == FE_NOMASK_ENV)
+ {
+ dummy = 0x1f << 23;
+ envp = &dummy;
+ }
+
+ __fenv_ldfsr (*envp);
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/sparc/fesetexcept.c b/libm/sparc/fesetexcept.c
new file mode 100644
index 000000000..02210b691
--- /dev/null
+++ b/libm/sparc/fesetexcept.c
@@ -0,0 +1,31 @@
+/* Set given exception flags. SPARC version.
+ Copyright (C) 2016-2025 Free Software Foundation, Inc.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include "fenv_private.h"
+
+int
+fesetexcept (int excepts)
+{
+ fenv_t tmp;
+
+ __fenv_stfsr (tmp);
+ tmp |= excepts & FE_ALL_EXCEPT;
+ __fenv_ldfsr (tmp);
+
+ return 0;
+}
diff --git a/libm/sparc/fesetmode.c b/libm/sparc/fesetmode.c
new file mode 100644
index 000000000..e72b3d9df
--- /dev/null
+++ b/libm/sparc/fesetmode.c
@@ -0,0 +1,38 @@
+/* Install given floating-point control modes. SPARC version.
+ Copyright (C) 2016-2025 Free Software Foundation, Inc.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include "fenv_private.h"
+#include <fpu_control.h>
+
+#define FPU_CONTROL_BITS 0xcfc00000UL
+
+int
+fesetmode (const femode_t *modep)
+{
+ femode_t fsr;
+
+ __fenv_stfsr (fsr);
+ fsr &= ~FPU_CONTROL_BITS;
+ if (modep == FE_DFL_MODE)
+ fsr |= _FPU_DEFAULT;
+ else
+ fsr |= *modep & FPU_CONTROL_BITS;
+ __fenv_ldfsr (fsr);
+
+ return 0;
+}
diff --git a/libm/sparc/fesetround.c b/libm/sparc/fesetround.c
new file mode 100644
index 000000000..ba3a4e50f
--- /dev/null
+++ b/libm/sparc/fesetround.c
@@ -0,0 +1,36 @@
+/* Set current rounding direction.
+ Copyright (C) 1997-2025 Free Software Foundation, Inc.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include "fenv_private.h"
+
+int
+fesetround (int round)
+{
+ fenv_t tmp;
+
+ if ((round & ~__FE_ROUND_MASK) != 0)
+ /* ROUND is no valid rounding mode. */
+ return 1;
+
+ __fenv_stfsr (tmp);
+ tmp &= ~__FE_ROUND_MASK;
+ tmp |= round;
+ __fenv_ldfsr (tmp);
+
+ return 0;
+}
diff --git a/libm/sparc/feupdateenv.c b/libm/sparc/feupdateenv.c
new file mode 100644
index 000000000..272536cf3
--- /dev/null
+++ b/libm/sparc/feupdateenv.c
@@ -0,0 +1,40 @@
+/* Install given floating-point environment and raise exceptions.
+ Copyright (C) 1997-2025 Free Software Foundation, Inc.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include "fenv_private.h"
+
+int
+feupdateenv (const fenv_t *envp)
+{
+ fexcept_t tmp;
+
+ /* Save current exceptions. */
+ __fenv_stfsr (tmp);
+ tmp &= FE_ALL_EXCEPT;
+
+ /* Install new environment. */
+ fesetenv (envp);
+
+ /* Raise the saved exception. Incidentally for us the implementation
+ defined format of the values in objects of type fexcept_t is the
+ same as the ones specified using the FE_* constants. */
+ feraiseexcept ((int) tmp);
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/sparc/fgetexcptflg.c b/libm/sparc/fgetexcptflg.c
new file mode 100644
index 000000000..d8568906e
--- /dev/null
+++ b/libm/sparc/fgetexcptflg.c
@@ -0,0 +1,33 @@
+/* Store current representation for exceptions.
+ Copyright (C) 1997-2025 Free Software Foundation, Inc.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include "fenv_private.h"
+
+int
+fegetexceptflag (fexcept_t *flagp, int excepts)
+{
+ fexcept_t tmp;
+
+ /* Get the current exceptions. */
+ __fenv_stfsr (tmp);
+
+ *flagp = tmp & excepts & FE_ALL_EXCEPT;
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/sparc/fpu_control.h b/libm/sparc/fpu_control.h
new file mode 100644
index 000000000..542f9fb1b
--- /dev/null
+++ b/libm/sparc/fpu_control.h
@@ -0,0 +1,75 @@
+/* FPU control word bits. SPARC version.
+ Copyright (C) 1997-2025 Free Software Foundation, Inc.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _FPU_CONTROL_H
+#define _FPU_CONTROL_H 1
+
+
+#include <features.h>
+#include <bits/wordsize.h>
+
+/* masking of interrupts */
+#define _FPU_MASK_IM 0x08000000
+#define _FPU_MASK_OM 0x04000000
+#define _FPU_MASK_UM 0x02000000
+#define _FPU_MASK_ZM 0x01000000
+#define _FPU_MASK_PM 0x00800000
+
+/* precision control */
+#define _FPU_EXTENDED 0x00000000 /* RECOMMENDED */
+#define _FPU_DOUBLE 0x20000000
+#define _FPU_80BIT 0x30000000
+#define _FPU_SINGLE 0x10000000 /* DO NOT USE */
+
+/* rounding control / Sparc */
+#define _FPU_RC_DOWN 0xc0000000
+#define _FPU_RC_UP 0x80000000
+#define _FPU_RC_ZERO 0x40000000
+#define _FPU_RC_NEAREST 0x0 /* RECOMMENDED */
+
+#define _FPU_RESERVED 0x303e0000 /* Reserved bits in cw */
+
+
+/* Now two recommended cw */
+
+/* Linux and IEEE default:
+ - extended precision
+ - rounding to nearest
+ - no exceptions */
+#define _FPU_DEFAULT 0x0
+#define _FPU_IEEE 0x0
+
+/* Type of the control word. */
+typedef unsigned long int fpu_control_t;
+
+#if __WORDSIZE == 64
+# define _FPU_GETCW(cw) __asm__ __volatile__ ("stx %%fsr,%0" : "=m" (*&cw))
+# define _FPU_SETCW(cw) __asm__ __volatile__ ("ldx %0,%%fsr" : : "m" (*&cw))
+#else
+# ifdef __leon__
+ /* Prevent stfsr from being placed directly after other fp instruction. */
+# define _FPU_GETCW(cw) __asm__ __volatile__ ("nop; st %%fsr,%0" : "=m" (*&cw))
+# else
+# define _FPU_GETCW(cw) __asm__ __volatile__ ("st %%fsr,%0" : "=m" (*&cw))
+# endif
+# define _FPU_SETCW(cw) __asm__ __volatile__ ("ld %0,%%fsr" : : "m" (*&cw))
+#endif
+
+/* Default control word set at startup. */
+extern fpu_control_t __fpu_control;
+
+#endif /* fpu_control.h */
diff --git a/libm/sparc/fraiseexcpt.c b/libm/sparc/fraiseexcpt.c
new file mode 100644
index 000000000..72e151fe6
--- /dev/null
+++ b/libm/sparc/fraiseexcpt.c
@@ -0,0 +1,81 @@
+/* Raise given exceptions.
+ Copyright (C) 1997-2025 Free Software Foundation, Inc.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include <float.h>
+#include <math.h>
+#include "math-barriers.h"
+
+int
+feraiseexcept (int excepts)
+{
+ static const struct {
+ double zero, one, max, min, pi;
+ } c = {
+ 0.0, 1.0, DBL_MAX, DBL_MIN, M_PI
+ };
+ double d;
+
+ /* Raise exceptions represented by EXPECTS. But we must raise only
+ one signal at a time. It is important the if the overflow/underflow
+ exception and the inexact exception are given at the same time,
+ the overflow/underflow exception follows the inexact exception. */
+
+ /* First: invalid exception. */
+ if ((FE_INVALID & excepts) != 0)
+ {
+ /* One example of an invalid operation is 0/0. */
+ __asm__ ("" : "=e" (d) : "0" (c.zero));
+ d /= c.zero;
+ math_force_eval (d);
+ }
+
+ /* Next: division by zero. */
+ if ((FE_DIVBYZERO & excepts) != 0)
+ {
+ __asm__ ("" : "=e" (d) : "0" (c.one));
+ d /= c.zero;
+ math_force_eval (d);
+ }
+
+ /* Next: overflow. */
+ if ((FE_OVERFLOW & excepts) != 0)
+ {
+ __asm__ ("" : "=e" (d) : "0" (c.max));
+ d *= d;
+ math_force_eval (d);
+ }
+
+ /* Next: underflow. */
+ if ((FE_UNDERFLOW & excepts) != 0)
+ {
+ __asm__ ("" : "=e" (d) : "0" (c.min));
+ d *= d;
+ math_force_eval (d);
+ }
+
+ /* Last: inexact. */
+ if ((FE_INEXACT & excepts) != 0)
+ {
+ __asm__ ("" : "=e" (d) : "0" (c.one));
+ d /= c.pi;
+ math_force_eval (d);
+ }
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/sparc/fsetexcptflg.c b/libm/sparc/fsetexcptflg.c
new file mode 100644
index 000000000..4b3b6ae68
--- /dev/null
+++ b/libm/sparc/fsetexcptflg.c
@@ -0,0 +1,36 @@
+/* Set floating-point environment exception handling.
+ Copyright (C) 1997-2025 Free Software Foundation, Inc.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include "fenv_private.h"
+#include <math.h>
+
+int
+fesetexceptflag (const fexcept_t *flagp, int excepts)
+{
+ fenv_t tmp;
+
+ __fenv_stfsr (tmp);
+
+ tmp &= ~(excepts & FE_ALL_EXCEPT);
+ tmp |= *flagp & excepts & FE_ALL_EXCEPT;
+
+ __fenv_ldfsr (tmp);
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/sparc/ftestexcept.c b/libm/sparc/ftestexcept.c
new file mode 100644
index 000000000..1fe87bb36
--- /dev/null
+++ b/libm/sparc/ftestexcept.c
@@ -0,0 +1,29 @@
+/* Test exception in current environment.
+ Copyright (C) 1997-2025 Free Software Foundation, Inc.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include "fenv_private.h"
+
+int
+fetestexcept (int excepts)
+{
+ fenv_t tmp;
+
+ __fenv_stfsr (tmp);
+
+ return tmp & excepts & FE_ALL_EXCEPT;
+}
diff --git a/libm/sparc/math-barriers.h b/libm/sparc/math-barriers.h
new file mode 100644
index 000000000..4b02ff47b
--- /dev/null
+++ b/libm/sparc/math-barriers.h
@@ -0,0 +1,36 @@
+/* Control when floating-point expressions are evaluated. Generic version.
+ Copyright (C) 2007-2025 Free Software Foundation, Inc.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _MATH_BARRIERS_H
+#define _MATH_BARRIERS_H 1
+
+/* math_opt_barrier evaluates and returns its floating-point argument
+ and ensures that the evaluation of any expression using the result
+ of math_opt_barrier is not moved before the call. math_force_eval
+ ensures that its floating-point argument is evaluated for its side
+ effects even if its value is apparently unused, and that the
+ evaluation of its argument is not moved after the call. Both these
+ macros are used to ensure the correct ordering of floating-point
+ expression evaluations with respect to accesses to the
+ floating-point environment. */
+
+#define math_opt_barrier(x) \
+ ({ __typeof (x) __x = (x); __asm ("" : "+m" (__x)); __x; })
+#define math_force_eval(x) \
+ ({ __typeof (x) __x = (x); __asm __volatile__ ("" : : "m" (__x)); })
+
+#endif /* math-barriers.h */
diff --git a/libpthread/nptl/pthread_key_create.c b/libpthread/nptl/pthread_key_create.c
index 6e11bbeae..87999764e 100644
--- a/libpthread/nptl/pthread_key_create.c
+++ b/libpthread/nptl/pthread_key_create.c
@@ -22,7 +22,6 @@
int
-attribute_protected
__pthread_key_create (
pthread_key_t *key,
void (*destr) (void *))
diff --git a/libpthread/nptl/sysdeps/nds32/dl-tls.h b/libpthread/nptl/sysdeps/nds32/dl-tls.h
index f0107cacb..11101fdd2 100644
--- a/libpthread/nptl/sysdeps/nds32/dl-tls.h
+++ b/libpthread/nptl/sysdeps/nds32/dl-tls.h
@@ -56,4 +56,6 @@ extern void *_dl_make_tlsdesc_dynamic (struct link_map *map, size_t ti_offset);
extern ptrdiff_t attribute_hidden
_dl_tlsdesc_dynamic(struct tlsdesc *);
+#define TLS_DTV_UNALLOCATED ((void *) -1l)
+
#endif //_NDS32_DL_TLS_H
diff --git a/libutil/forkpty.c b/libutil/forkpty.c
index 24643330c..7e42d1a33 100644
--- a/libutil/forkpty.c
+++ b/libutil/forkpty.c
@@ -23,7 +23,8 @@
#include <pty.h>
int
-forkpty (int *amaster, char *name, struct termios *termp, struct winsize *winp)
+forkpty (int *amaster, char *name, const struct termios *termp,
+ const struct winsize *winp)
{
int master, slave, pid;
diff --git a/libutil/openpty.c b/libutil/openpty.c
index 848dc8d38..74d86506b 100644
--- a/libutil/openpty.c
+++ b/libutil/openpty.c
@@ -26,82 +26,18 @@
#include <unistd.h>
#include <sys/types.h>
-/* BCS: the following function is, IMO, overkill */
-#if 0
-/* Return the result of ptsname_r in the buffer pointed to by PTS,
- which should be of length BUF_LEN. If it is too long to fit in
- this buffer, a sufficiently long buffer is allocated using malloc,
- and returned in PTS. 0 is returned upon success, -1 otherwise. */
-static int
-pts_name (int fd, char **pts, size_t buf_len)
-{
- int rv;
- char *buf = *pts;
-
- for (;;)
- {
- char *new_buf;
-
- if (buf_len)
- {
- rv = ptsname_r (fd, buf, buf_len);
-
- if (rv != 0 || memchr (buf, '\0', buf_len))
- /* We either got an error, or we succeeded and the
- returned name fit in the buffer. */
- break;
-
- /* Try again with a longer buffer. */
- buf_len += buf_len; /* Double it */
- }
- else
- /* No initial buffer; start out by mallocing one. */
- buf_len = 128; /* First time guess. */
-
- if (buf != *pts)
- /* We've already malloced another buffer at least once. */
- new_buf = realloc (buf, buf_len);
- else
- new_buf = malloc (buf_len);
- if (! new_buf)
- {
- rv = -1;
- __set_errno (ENOMEM);
- break;
- }
- buf = new_buf;
- }
-
- if (rv == 0)
- *pts = buf; /* Return buffer to the user. */
- else if (buf != *pts)
- free (buf); /* Free what we malloced when returning an error. */
-
- return rv;
-}
-#endif
-
/* Create pseudo tty master slave pair and set terminal attributes
according to TERMP and WINP. Return handles for both ends in
AMASTER and ASLAVE, and return the name of the slave end in NAME. */
int
-openpty (int *amaster, int *aslave, char *name, struct termios *termp,
- struct winsize *winp)
+openpty (int *amaster, int *aslave, char *name, const struct termios *termp,
+ const struct winsize *winp)
{
-#if 0
-#ifdef PATH_MAX
- char _buf[PATH_MAX];
-#else
- char _buf[512];
-#endif
- char *buf = _buf;
-#else
#ifdef PATH_MAX
char buf[PATH_MAX];
#else
char buf[512];
#endif
-#endif
int master, slave;
master = posix_openpt (O_RDWR);
@@ -114,20 +50,12 @@ openpty (int *amaster, int *aslave, char *name, struct termios *termp,
if (unlockpt (master))
goto fail;
-#if 0
- if (pts_name (master, &buf, sizeof (_buf)))
-#else
if (ptsname_r (master, buf, sizeof buf))
-#endif
goto fail;
slave = open (buf, O_RDWR | O_NOCTTY);
if (slave == -1)
{
-#if 0
- if (buf != _buf)
- free (buf);
-#endif
goto fail;
}
@@ -142,10 +70,6 @@ openpty (int *amaster, int *aslave, char *name, struct termios *termp,
if (name != NULL)
strcpy (name, buf);
-#if 0
- if (buf != _buf)
- free (buf);
-#endif
return 0;
fail: