summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Rules.mak14
-rw-r--r--extra/Configs/Config.in8
-rw-r--r--extra/Configs/Config.in.arch13
-rw-r--r--extra/Configs/Config.nds321
-rw-r--r--extra/config/lxdialog/check-lxdialog.sh2
-rw-r--r--extra/scripts/unifdef.c12
-rw-r--r--include/atomic.h18
-rw-r--r--include/elf.h6
-rw-r--r--include/features.h12
-rw-r--r--include/fenv.h10
-rw-r--r--include/internal/time64_helpers.h5
-rw-r--r--include/libintl.h3
-rw-r--r--include/net/ppp_defs.h2
-rw-r--r--include/netdb.h2
-rw-r--r--include/pty.h6
-rw-r--r--include/spawn.h1
-rw-r--r--include/stdint.h8
-rw-r--r--include/stdio.h5
-rw-r--r--include/stdlib.h6
-rw-r--r--include/sys/cdefs.h14
-rw-r--r--include/sys/mount.h25
-rw-r--r--include/sys/uio.h19
-rw-r--r--include/ucontext.h4
-rw-r--r--include/unistd.h13
-rw-r--r--ldso/include/dl-auxvt.h9
-rw-r--r--ldso/include/dl-syscall.h6
-rwxr-xr-xldso/include/ldso.h3
-rw-r--r--ldso/ldso/Makefile.in5
-rw-r--r--ldso/ldso/aarch64/dl-sysdep.h25
-rw-r--r--ldso/ldso/arm/dl-sysdep.h69
-rw-r--r--ldso/ldso/dl-elf.c2
-rw-r--r--ldso/ldso/dl-startup.c6
-rwxr-xr-xldso/ldso/dl-vdso.c12
-rw-r--r--ldso/ldso/i386/dl-sysdep.h27
-rwxr-xr-xldso/ldso/ldso.c2
-rw-r--r--ldso/ldso/m68k/elfinterp.c4
-rw-r--r--ldso/ldso/riscv32/dl-sysdep.h22
-rw-r--r--ldso/ldso/x86_64/dl-sysdep.h45
-rw-r--r--ldso/ldso/xtensa/dl-inlines.h1
-rw-r--r--ldso/ldso/xtensa/dl-startup.h91
-rw-r--r--ldso/ldso/xtensa/dl-sysdep.h66
-rw-r--r--ldso/ldso/xtensa/dl-tlsdesc.S10
-rw-r--r--ldso/ldso/xtensa/elfinterp.c114
-rw-r--r--ldso/libdl/libdl.c4
-rw-r--r--libc/inet/resolv.c4
-rwxr-xr-xlibc/misc/auxvt/getauxval.c30
-rw-r--r--libc/misc/elf/dl-support.c19
-rw-r--r--libc/misc/internals/__uClibc_main.c24
-rw-r--r--libc/misc/internals/reloc_static_pie.c4
-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/misc/wchar/wchar.c2
-rw-r--r--libc/stdio/_fpmaxtostr.c4
-rw-r--r--libc/stdio/_scanf.c2
-rw-r--r--libc/stdlib/_strtod.c10
-rw-r--r--libc/stdlib/malloc-standard/malloc.c10
-rw-r--r--libc/stdlib/malloc/memalign.c6
-rw-r--r--libc/stdlib/stdlib.c2
-rw-r--r--libc/string/generic/strnlen.c6
-rw-r--r--libc/string/x86_64/strcat.S2
-rw-r--r--libc/string/x86_64/strcspn.S2
-rw-r--r--libc/string/x86_64/strlen.S2
-rw-r--r--libc/string/x86_64/strspn.S2
-rw-r--r--libc/sysdeps/linux/aarch64/bits/fcntl.h3
-rw-r--r--libc/sysdeps/linux/aarch64/bits/fenv.h78
-rw-r--r--libc/sysdeps/linux/aarch64/bits/shm.h87
-rw-r--r--libc/sysdeps/linux/aarch64/crt1.S4
-rw-r--r--libc/sysdeps/linux/aarch64/fpu_control.h102
-rw-r--r--libc/sysdeps/linux/aarch64/sys/ucontext.h4
-rw-r--r--libc/sysdeps/linux/alpha/bits/fcntl.h2
-rw-r--r--libc/sysdeps/linux/alpha/bits/stat.h2
-rwxr-xr-xlibc/sysdeps/linux/arc/bits/fcntl.h3
-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/__longjmp.S8
-rw-r--r--libc/sysdeps/linux/arm/bits/fcntl.h2
-rw-r--r--libc/sysdeps/linux/arm/bits/fenv.h107
-rw-r--r--libc/sysdeps/linux/arm/bits/shm.h6
-rw-r--r--libc/sysdeps/linux/arm/crt1.S15
-rw-r--r--libc/sysdeps/linux/arm/fpu_control.h192
-rw-r--r--libc/sysdeps/linux/arm/setjmp.S8
-rw-r--r--libc/sysdeps/linux/avr32/bits/fcntl.h3
-rw-r--r--libc/sysdeps/linux/bfin/bits/fcntl.h2
-rw-r--r--libc/sysdeps/linux/c6x/bits/fcntl.h3
-rw-r--r--libc/sysdeps/linux/common-generic/bits/kernel_stat.h2
-rw-r--r--libc/sysdeps/linux/common/Makefile.in4
-rw-r--r--libc/sysdeps/linux/common/bits/fcntl-linux.h34
-rw-r--r--libc/sysdeps/linux/common/bits/mman-shared.h2
-rw-r--r--libc/sysdeps/linux/common/bits/msq.h14
-rw-r--r--libc/sysdeps/linux/common/bits/nan.h4
-rw-r--r--libc/sysdeps/linux/common/bits/sem.h8
-rw-r--r--libc/sysdeps/linux/common/bits/stat.h4
-rw-r--r--libc/sysdeps/linux/common/clock_adjtime.c2
-rw-r--r--libc/sysdeps/linux/common/fstat64.c3
-rw-r--r--libc/sysdeps/linux/common/fstatat64.c3
-rw-r--r--libc/sysdeps/linux/common/getentropy.c46
-rw-r--r--libc/sysdeps/linux/common/getrandom.c3
-rw-r--r--libc/sysdeps/linux/common/lseek.c2
-rw-r--r--libc/sysdeps/linux/common/memfd_create.c13
-rw-r--r--libc/sysdeps/linux/common/not-cancel.h2
-rw-r--r--libc/sysdeps/linux/common/process_vm_readv.c32
-rw-r--r--libc/sysdeps/linux/common/process_vm_writev.c32
-rw-r--r--libc/sysdeps/linux/common/sys/epoll.h14
-rw-r--r--libc/sysdeps/linux/common/sys/random.h22
-rw-r--r--libc/sysdeps/linux/common/utime.c4
-rw-r--r--libc/sysdeps/linux/common/utimensat.c3
-rw-r--r--libc/sysdeps/linux/common/utimes.c4
-rw-r--r--libc/sysdeps/linux/cris/bits/fcntl.h2
-rw-r--r--libc/sysdeps/linux/csky/bits/fcntl.h2
-rw-r--r--libc/sysdeps/linux/csky/bits/fenv.h123
-rw-r--r--libc/sysdeps/linux/csky/bits/uClibc_arch_features.h3
-rw-r--r--libc/sysdeps/linux/csky/fpu_control.h147
-rw-r--r--libc/sysdeps/linux/frv/bits/fcntl.h2
-rw-r--r--libc/sysdeps/linux/frv/bits/stat.h4
-rw-r--r--libc/sysdeps/linux/h8300/bits/fcntl.h2
-rw-r--r--libc/sysdeps/linux/hppa/bits/fcntl.h2
-rw-r--r--libc/sysdeps/linux/i386/bits/fcntl.h2
-rw-r--r--libc/sysdeps/linux/ia64/bits/fcntl.h2
-rw-r--r--libc/sysdeps/linux/ia64/bits/stat.h4
-rw-r--r--libc/sysdeps/linux/kvx/bits/fcntl.h3
-rw-r--r--libc/sysdeps/linux/kvx/bits/shm.h87
-rw-r--r--libc/sysdeps/linux/lm32/bits/fcntl.h2
-rw-r--r--libc/sysdeps/linux/m68k/bits/fcntl.h2
-rw-r--r--libc/sysdeps/linux/m68k/bits/fenv.h98
-rw-r--r--libc/sysdeps/linux/m68k/bits/shm.h108
-rw-r--r--libc/sysdeps/linux/m68k/bits/stat.h4
-rw-r--r--libc/sysdeps/linux/m68k/bsd-_setjmp.S4
-rw-r--r--libc/sysdeps/linux/m68k/bsd-setjmp.S4
-rw-r--r--libc/sysdeps/linux/m68k/clone.S12
-rw-r--r--libc/sysdeps/linux/m68k/fpu_control.h77
-rw-r--r--libc/sysdeps/linux/m68k/setjmp.S4
-rw-r--r--libc/sysdeps/linux/metag/bits/fcntl.h2
-rw-r--r--libc/sysdeps/linux/microblaze/bits/fcntl.h2
-rw-r--r--libc/sysdeps/linux/mips/bits/fcntl.h2
-rw-r--r--libc/sysdeps/linux/mips/bits/fenv.h82
-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/stat.h8
-rw-r--r--libc/sysdeps/linux/mips/bits/syscalls.h36
-rw-r--r--libc/sysdeps/linux/mips/fpu_control.h68
-rw-r--r--libc/sysdeps/linux/nds32/Makefile.arch2
-rw-r--r--libc/sysdeps/linux/nds32/bits/fcntl.h2
-rw-r--r--libc/sysdeps/linux/nds32/bits/kernel_types.h22
-rw-r--r--libc/sysdeps/linux/nds32/bits/stat.h4
-rw-r--r--libc/sysdeps/linux/nds32/bits/syscalls.h3
-rw-r--r--libc/sysdeps/linux/nds32/jmpbuf-unwind.h2
-rw-r--r--libc/sysdeps/linux/nds32/sys/ucontext.h6
-rw-r--r--libc/sysdeps/linux/nds32/vfork.S129
-rw-r--r--libc/sysdeps/linux/nios2/bits/fcntl.h2
-rw-r--r--libc/sysdeps/linux/or1k/bits/fcntl.h3
-rw-r--r--libc/sysdeps/linux/or1k/bits/fenv.h84
-rw-r--r--libc/sysdeps/linux/or1k/fpu_control.h88
-rw-r--r--libc/sysdeps/linux/powerpc/bits/fcntl.h2
-rw-r--r--libc/sysdeps/linux/powerpc/bits/stat.h4
-rw-r--r--libc/sysdeps/linux/riscv32/bits/fcntl.h3
-rw-r--r--libc/sysdeps/linux/riscv32/bits/fenv.h2
-rw-r--r--libc/sysdeps/linux/riscv32/bits/shm.h6
-rw-r--r--libc/sysdeps/linux/riscv32/getcontext.S74
-rw-r--r--libc/sysdeps/linux/riscv32/setcontext.S112
-rw-r--r--libc/sysdeps/linux/riscv32/swapcontext.S122
-rw-r--r--libc/sysdeps/linux/riscv32/sys/ucontext.h4
-rw-r--r--libc/sysdeps/linux/riscv64/bits/fcntl.h3
-rw-r--r--libc/sysdeps/linux/riscv64/bits/fenv.h2
-rw-r--r--libc/sysdeps/linux/riscv64/bits/shm.h7
-rw-r--r--libc/sysdeps/linux/riscv64/getcontext.S74
-rw-r--r--libc/sysdeps/linux/riscv64/setcontext.S112
-rw-r--r--libc/sysdeps/linux/riscv64/swapcontext.S122
-rw-r--r--libc/sysdeps/linux/riscv64/sys/ucontext.h4
-rw-r--r--libc/sysdeps/linux/sh/bits/fcntl.h2
-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/fcntl.h2
-rw-r--r--libc/sysdeps/linux/sparc/bits/fenv.h60
-rw-r--r--libc/sysdeps/linux/sparc/bits/stat.h4
-rw-r--r--libc/sysdeps/linux/sparc/fpu_control.h24
-rw-r--r--libc/sysdeps/linux/sparc64/bits/fcntl.h2
-rw-r--r--libc/sysdeps/linux/sparc64/bits/stat.h4
-rw-r--r--libc/sysdeps/linux/tile/bits/fcntl.h3
-rw-r--r--libc/sysdeps/linux/tile/sys/ucontext.h4
-rw-r--r--libc/sysdeps/linux/x86_64/bits/fcntl.h2
-rw-r--r--libc/sysdeps/linux/x86_64/bits/stat.h4
-rw-r--r--libc/sysdeps/linux/x86_64/crt1.S6
-rw-r--r--libc/sysdeps/linux/xtensa/__start_context.S6
-rw-r--r--libc/sysdeps/linux/xtensa/bits/elf-fdpic.h117
-rw-r--r--libc/sysdeps/linux/xtensa/bits/fcntl.h2
-rw-r--r--libc/sysdeps/linux/xtensa/bits/stat.h4
-rw-r--r--libc/sysdeps/linux/xtensa/bits/xtensa-config.h20
-rw-r--r--libc/sysdeps/linux/xtensa/clone.S6
-rw-r--r--libc/sysdeps/linux/xtensa/crt1.S81
-rw-r--r--libc/sysdeps/linux/xtensa/crti.S10
-rw-r--r--libc/sysdeps/linux/xtensa/crtn.S6
-rw-r--r--libc/sysdeps/linux/xtensa/crtreloc.c105
-rw-r--r--libc/sysdeps/linux/xtensa/getcontext.S1
-rw-r--r--libc/sysdeps/linux/xtensa/makecontext.c5
-rw-r--r--libc/sysdeps/linux/xtensa/setcontext.S1
-rw-r--r--libc/sysdeps/linux/xtensa/setjmp.S3
-rw-r--r--libc/sysdeps/linux/xtensa/swapcontext.S1
-rw-r--r--libc/sysdeps/linux/xtensa/sysdep.h48
-rw-r--r--libiconv/iconv.c12
-rw-r--r--libiconv/include/jis0208.h170
-rw-r--r--libm/aarch64/Makefile.arch16
-rw-r--r--libm/aarch64/fclrexcpt.c35
-rw-r--r--libm/aarch64/fedisblxcpt.c34
-rw-r--r--libm/aarch64/feenablxcpt.c45
-rw-r--r--libm/aarch64/fegetenv.c30
-rw-r--r--libm/aarch64/fegetexcept.c26
-rw-r--r--libm/aarch64/fegetmode.c26
-rw-r--r--libm/aarch64/fegetround.c35
-rw-r--r--libm/aarch64/feholdexcpt.c25
-rw-r--r--libm/aarch64/fenv_private.h300
-rw-r--r--libm/aarch64/fesetenv.c73
-rw-r--r--libm/aarch64/fesetexcept.c33
-rw-r--r--libm/aarch64/fesetmode.c33
-rw-r--r--libm/aarch64/fesetround.c29
-rw-r--r--libm/aarch64/feupdateenv.c84
-rw-r--r--libm/aarch64/fgetexcptflg.c25
-rw-r--r--libm/aarch64/fraiseexcpt.c89
-rw-r--r--libm/aarch64/fsetexcptflg.c39
-rw-r--r--libm/aarch64/ftestexcept.c24
-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/arm/Makefile.arch16
-rw-r--r--libm/arm/arm-features.h58
-rw-r--r--libm/arm/fclrexcpt.c41
-rw-r--r--libm/arm/fedisblxcpt.c41
-rw-r--r--libm/arm/feenablxcpt.c49
-rw-r--r--libm/arm/fegetenv.c35
-rw-r--r--libm/arm/fegetexcept.c35
-rw-r--r--libm/arm/fegetmode.c28
-rw-r--r--libm/arm/fegetround.c42
-rw-r--r--libm/arm/feholdexcpt.c31
-rw-r--r--libm/arm/fenv_private.h248
-rw-r--r--libm/arm/fesetenv.c62
-rw-r--r--libm/arm/fesetexcept.c37
-rw-r--r--libm/arm/fesetmode.c44
-rw-r--r--libm/arm/fesetround.c35
-rw-r--r--libm/arm/feupdateenv.c73
-rw-r--r--libm/arm/fgetexcptflg.c31
-rw-r--r--libm/arm/fraiseexcpt.c103
-rw-r--r--libm/arm/fsetexcptflg.c44
-rw-r--r--libm/arm/ftestexcept.c30
-rw-r--r--libm/cexp.c6
-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/e_exp.c2
-rw-r--r--libm/float_wrappers.c2
-rw-r--r--libm/m68k/Makefile.arch16
-rw-r--r--libm/m68k/fclrexcpt.c39
-rw-r--r--libm/m68k/fedisblxcpt.c36
-rw-r--r--libm/m68k/feenablxcpt.c36
-rw-r--r--libm/m68k/fegetenv.c33
-rw-r--r--libm/m68k/fegetexcept.c29
-rw-r--r--libm/m68k/fegetmode.c26
-rw-r--r--libm/m68k/fegetround.c28
-rw-r--r--libm/m68k/feholdexcpt.c42
-rw-r--r--libm/m68k/fesetenv.c63
-rw-r--r--libm/m68k/fesetexcept.c30
-rw-r--r--libm/m68k/fesetmode.c31
-rw-r--r--libm/m68k/fesetround.c35
-rw-r--r--libm/m68k/feupdateenv.c39
-rw-r--r--libm/m68k/fgetexcptflg.c32
-rw-r--r--libm/m68k/fraiseexcpt.c106
-rw-r--r--libm/m68k/fsetexcptflg.c38
-rw-r--r--libm/m68k/ftestexcept.c29
-rw-r--r--libm/mips/Makefile.arch16
-rw-r--r--libm/mips/fclrexcpt.c44
-rw-r--r--libm/mips/fedisblxcpt.c38
-rw-r--r--libm/mips/feenablxcpt.c38
-rw-r--r--libm/mips/fegetenv.c28
-rw-r--r--libm/mips/fegetexcept.c31
-rw-r--r--libm/mips/fegetmode.c26
-rw-r--r--libm/mips/fegetround.c30
-rw-r--r--libm/mips/feholdexcpt.c35
-rw-r--r--libm/mips/fenv_libc.h29
-rw-r--r--libm/mips/fenv_private.h238
-rw-r--r--libm/mips/fesetenv.c38
-rw-r--r--libm/mips/fesetexcept.c31
-rw-r--r--libm/mips/fesetmode.c37
-rw-r--r--libm/mips/fesetround.c40
-rw-r--r--libm/mips/feupdateenv.c40
-rw-r--r--libm/mips/fgetexcptflg.c37
-rw-r--r--libm/mips/fraiseexcpt.c42
-rw-r--r--libm/mips/fsetexcptflg.c40
-rw-r--r--libm/mips/ftestexcept.c30
-rw-r--r--libm/nan.c4
-rw-r--r--libm/or1k/Makefile.arch16
-rw-r--r--libm/or1k/fclrexcpt.c42
-rw-r--r--libm/or1k/fegetenv.c28
-rw-r--r--libm/or1k/fegetmode.c28
-rw-r--r--libm/or1k/fegetround.c25
-rw-r--r--libm/or1k/feholdexcpt.c29
-rw-r--r--libm/or1k/fenv_private.h196
-rw-r--r--libm/or1k/fesetenv.c28
-rw-r--r--libm/or1k/fesetexcept.c34
-rw-r--r--libm/or1k/fesetmode.c38
-rw-r--r--libm/or1k/fesetround.c35
-rw-r--r--libm/or1k/feupdateenv.c29
-rw-r--r--libm/or1k/fgetexcptflg.c28
-rw-r--r--libm/or1k/fraiseexcpt.c63
-rw-r--r--libm/or1k/fsetexcptflg.c42
-rw-r--r--libm/or1k/ftestexcept.c25
-rw-r--r--libm/or1k/get-rounding-mode.h36
-rw-r--r--libm/riscv32/Makefile.arch16
-rw-r--r--libm/riscv32/fclrexcpt.c26
-rw-r--r--libm/riscv32/fegetenv.c28
-rw-r--r--libm/riscv32/fegetmode.c26
-rw-r--r--libm/riscv32/fegetround.c25
-rw-r--r--libm/riscv32/feholdexcpt.c26
-rw-r--r--libm/riscv32/fenv_private.h156
-rw-r--r--libm/riscv32/fesetenv.c26
-rw-r--r--libm/riscv32/fesetexcept.c25
-rw-r--r--libm/riscv32/fesetmode.c30
-rw-r--r--libm/riscv32/fesetround.c35
-rw-r--r--libm/riscv32/feupdateenv.c26
-rw-r--r--libm/riscv32/fgetexcptflg.c29
-rw-r--r--libm/riscv32/fraiseexcpt.c26
-rw-r--r--libm/riscv32/fsetexcptflg.c29
-rw-r--r--libm/riscv32/ftestexcept.c25
-rw-r--r--libm/riscv32/get-rounding-mode.h32
-rw-r--r--libm/riscv64/Makefile.arch16
-rw-r--r--libm/riscv64/fclrexcpt.c26
-rw-r--r--libm/riscv64/fegetenv.c28
-rw-r--r--libm/riscv64/fegetmode.c26
-rw-r--r--libm/riscv64/fegetround.c25
-rw-r--r--libm/riscv64/feholdexcpt.c26
-rw-r--r--libm/riscv64/fenv_private.h156
-rw-r--r--libm/riscv64/fesetenv.c26
-rw-r--r--libm/riscv64/fesetexcept.c25
-rw-r--r--libm/riscv64/fesetmode.c30
-rw-r--r--libm/riscv64/fesetround.c35
-rw-r--r--libm/riscv64/feupdateenv.c26
-rw-r--r--libm/riscv64/fgetexcptflg.c29
-rw-r--r--libm/riscv64/fraiseexcpt.c26
-rw-r--r--libm/riscv64/fsetexcptflg.c29
-rw-r--r--libm/riscv64/ftestexcept.c25
-rw-r--r--libm/riscv64/get-rounding-mode.h32
-rw-r--r--libm/s_expm1.c2
-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--libm/w_cabs.c2
-rw-r--r--libpthread/linuxthreads/Makefile.in2
-rw-r--r--libpthread/linuxthreads/sysdeps/pthread/not-cancel.h2
-rw-r--r--libpthread/nptl/allocatestack.c5
-rw-r--r--libpthread/nptl/sysdeps/arc/dl-tls.h3
-rw-r--r--libpthread/nptl/sysdeps/arm/dl-tls.h3
-rw-r--r--libpthread/nptl/sysdeps/csky/dl-tls.h2
-rw-r--r--libpthread/nptl/sysdeps/generic/dl-tls.c2
-rw-r--r--libpthread/nptl/sysdeps/i386/dl-tls.h3
-rw-r--r--libpthread/nptl/sysdeps/metag/dl-tls.h3
-rw-r--r--libpthread/nptl/sysdeps/microblaze/dl-tls.h3
-rw-r--r--libpthread/nptl/sysdeps/mips/dl-tls.h3
-rw-r--r--libpthread/nptl/sysdeps/nds32/dl-tls.h2
-rw-r--r--libpthread/nptl/sysdeps/or1k/dl-tls.h3
-rw-r--r--libpthread/nptl/sysdeps/powerpc/dl-tls.h3
-rw-r--r--libpthread/nptl/sysdeps/riscv32/dl-tls.h3
-rw-r--r--libpthread/nptl/sysdeps/riscv64/dl-tls.h3
-rw-r--r--libpthread/nptl/sysdeps/sh/dl-tls.h3
-rw-r--r--libpthread/nptl/sysdeps/sparc/dl-tls.h3
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/m68k/bits/pthreadtypes.h18
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/not-cancel.h2
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/xtensa/Makefile.arch2
-rw-r--r--libpthread/nptl/sysdeps/x86_64/dl-tls.h3
-rw-r--r--libpthread/nptl/sysdeps/xtensa/dl-tls.h36
-rw-r--r--libutil/forkpty.c3
-rw-r--r--libutil/openpty.c80
438 files changed, 12309 insertions, 1707 deletions
diff --git a/Rules.mak b/Rules.mak
index 5be74b86e..5f6d526e7 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 := 48
+SUBLEVEL := 54
EXTRAVERSION :=
VERSION := $(MAJOR_VERSION).$(MINOR_VERSION).$(SUBLEVEL)
ABI_VERSION := $(MAJOR_VERSION)
@@ -520,6 +520,10 @@ ifeq ($(TARGET_ARCH),c6x)
CPU_LDFLAGS-y += $(CPU_CFLAGS)
endif
+ifeq ($(TARGET_ARCH),xtensa)
+ CPU_CFLAGS-$(UCLIBC_FORMAT_FDPIC_ELF) += -mfdpic
+endif
+
$(eval $(call check-gcc-var,$(PIEFLAG_NAME)))
PIEFLAG := $(CFLAG_$(PIEFLAG_NAME))
ifeq ($(PIEFLAG),)
@@ -664,6 +668,12 @@ endif
ifeq ($(TARGET_ARCH),i386)
CFLAGS += -fno-omit-frame-pointer
endif
+ifeq ($(TARGET_ARCH),bfin)
+CFLAGS += -Wno-implicit-function-declaration
+endif
+ifeq ($(TARGET_ARCH),frv)
+CFLAGS += -Wno-implicit-function-declaration
+endif
ifneq ($(strip $(UCLIBC_EXTRA_LDFLAGS)),"")
LDFLAGS += $(call qstrip,$(UCLIBC_EXTRA_LDFLAGS))
endif
diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in
index b814449b4..454b6ddb8 100644
--- a/extra/Configs/Config.in
+++ b/extra/Configs/Config.in
@@ -545,7 +545,7 @@ config LDSO_LD_LIBRARY_PATH
If unsure, simply say Y here.
config UCLIBC_CTOR_DTOR
- bool
+ bool "Support global constructors and destructors"
default y
help
If you wish to build uClibc with support for global constructor
@@ -615,7 +615,7 @@ config UCLIBC_HAS_THREADS_NATIVE
!TARGET_h8300 && \
!TARGET_hppa && \
!TARGET_ia64 && \
- (ARCH_USE_MMU || TARGET_arm)
+ (ARCH_USE_MMU || TARGET_arm || TARGET_xtensa)
help
If you want to compile uClibc with NPTL support, then answer Y.
@@ -1028,6 +1028,7 @@ config UCLIBC_USE_TIME64
bool "Use *time64 syscalls instead of 32bit ones (if possible)"
depends on TARGET_arc || \
TARGET_arm || \
+ TARGET_csky || \
TARGET_i386 || \
TARGET_m68k || \
TARGET_microblaze || \
@@ -1039,8 +1040,7 @@ config UCLIBC_USE_TIME64
TARGET_sh || \
TARGET_xtensa
# TODO: add support for other architectures
- default y if TARGET_riscv32
- default n
+ default y
help
Replace 32bit syscalls to their 64/time64 analog if possible.
diff --git a/extra/Configs/Config.in.arch b/extra/Configs/Config.in.arch
index 1ae5134b9..24c0db157 100644
--- a/extra/Configs/Config.in.arch
+++ b/extra/Configs/Config.in.arch
@@ -20,7 +20,7 @@ config UCLIBC_FORMAT_ELF
select HAVE_LDSO
config UCLIBC_FORMAT_FDPIC_ELF
bool "FDPIC ELF"
- depends on !ARCH_USE_MMU && (TARGET_bfin || TARGET_frv || TARGET_arm)
+ depends on !ARCH_USE_MMU && (TARGET_bfin || TARGET_frv || TARGET_arm || TARGET_xtensa)
select DOPIC
config UCLIBC_FORMAT_DSBT_ELF
bool "DBST ELF"
@@ -164,9 +164,20 @@ config UCLIBC_HAS_FENV
bool "Enable C99 Floating-point environment"
depends on UCLIBC_HAS_FLOATS
depends on TARGET_i386 || \
+ TARGET_aarch64 || \
+ TARGET_arc || \
+ TARGET_arm || \
+ TARGET_csky || \
+ TARGET_m68k || \
TARGET_metag || \
+ TARGET_mips || \
TARGET_nds32 || \
+ TARGET_or1k || \
(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.nds32 b/extra/Configs/Config.nds32
index 8bac9e679..2ed6a32b7 100644
--- a/extra/Configs/Config.nds32
+++ b/extra/Configs/Config.nds32
@@ -11,6 +11,7 @@ config FORCE_OPTIONS_FOR_ARCH
bool
default y
select ARCH_ANY_ENDIAN
+ select ARCH_HAS_DEPRECATED_SYSCALLS
select ARCH_HAS_MMU
select ARCH_HAS_UCONTEXT
diff --git a/extra/config/lxdialog/check-lxdialog.sh b/extra/config/lxdialog/check-lxdialog.sh
index 9d2a4c585..66bfcb549 100644
--- a/extra/config/lxdialog/check-lxdialog.sh
+++ b/extra/config/lxdialog/check-lxdialog.sh
@@ -43,7 +43,7 @@ trap "rm -f $tmp" 0 1 2 3 15
check() {
$cc -x c - -o $tmp 2>/dev/null <<'EOF'
#include CURSES_LOC
-main() {}
+int main() {}
EOF
if [ $? != 0 ]; then
echo " *** Unable to find the ncurses libraries or the" 1>&2
diff --git a/extra/scripts/unifdef.c b/extra/scripts/unifdef.c
index 0f059205f..cfe34377a 100644
--- a/extra/scripts/unifdef.c
+++ b/extra/scripts/unifdef.c
@@ -201,7 +201,7 @@ static int depth; /* current #if nesting */
static int delcount; /* count of deleted lines */
static unsigned blankcount; /* count of blank lines */
static unsigned blankmax; /* maximum recent blankcount */
-static bool constexpr; /* constant #if expression */
+static bool const_expr; /* constant #if expression */
static bool zerosyms; /* to format symdepth output */
static bool firstsym; /* ditto */
@@ -951,7 +951,7 @@ static long prec(const struct ops *ops)
/*
* Function for evaluating the innermost parts of expressions,
* viz. !expr (expr) number defined(symbol) symbol
- * We reset the constexpr flag in the last two cases.
+ * We reset the const_expr flag in the last two cases.
*/
static Linetype
eval_unary(const struct ops *ops, long *valp, const char **cpp)
@@ -1011,7 +1011,7 @@ eval_unary(const struct ops *ops, long *valp, const char **cpp)
*valp = (value[sym] != NULL);
lt = *valp ? LT_TRUE : LT_FALSE;
}
- constexpr = false;
+ const_expr = false;
} else if (!endsym(*cp)) {
debug("eval%d symbol", prec(ops));
sym = findsym(&cp);
@@ -1028,7 +1028,7 @@ eval_unary(const struct ops *ops, long *valp, const char **cpp)
lt = *valp ? LT_TRUE : LT_FALSE;
cp = skipargs(cp);
}
- constexpr = false;
+ const_expr = false;
} else {
debug("eval%d bad expr", prec(ops));
return (LT_ERROR);
@@ -1088,10 +1088,10 @@ ifeval(const char **cpp)
long val = 0;
debug("eval %s", *cpp);
- constexpr = killconsts ? false : true;
+ const_expr = killconsts ? false : true;
ret = eval_table(eval_ops, &val, cpp);
debug("eval = %d", val);
- return (constexpr ? LT_IF : ret == LT_ERROR ? LT_IF : ret);
+ return (const_expr ? LT_IF : ret == LT_ERROR ? LT_IF : ret);
}
/*
diff --git a/include/atomic.h b/include/atomic.h
index 267aff5d5..3adcfbc5f 100644
--- a/include/atomic.h
+++ b/include/atomic.h
@@ -54,15 +54,15 @@
and following args. */
#define __atomic_val_bysize(pre, post, mem, ...) \
({ \
- __typeof (*mem) __atg1_result; \
+ __typeof ((__typeof (*(mem))) *(mem)) __atg1_result; \
if (sizeof (*mem) == 1) \
- __atg1_result = pre##_8_##post (mem, __VA_ARGS__); \
+ __atg1_result = (__typeof ((__typeof (*(mem))) *(mem))) pre##_8_##post (mem, __VA_ARGS__); \
else if (sizeof (*mem) == 2) \
- __atg1_result = pre##_16_##post (mem, __VA_ARGS__); \
+ __atg1_result = (__typeof ((__typeof (*(mem))) *(mem))) pre##_16_##post (mem, __VA_ARGS__); \
else if (sizeof (*mem) == 4) \
- __atg1_result = pre##_32_##post (mem, __VA_ARGS__); \
+ __atg1_result = (__typeof ((__typeof (*(mem))) *(mem))) pre##_32_##post (mem, __VA_ARGS__); \
else if (sizeof (*mem) == 8) \
- __atg1_result = pre##_64_##post (mem, __VA_ARGS__); \
+ __atg1_result = (__typeof ((__typeof (*(mem))) *(mem))) pre##_64_##post (mem, __VA_ARGS__); \
else \
abort (); \
__atg1_result; \
@@ -71,13 +71,13 @@
({ \
int __atg2_result; \
if (sizeof (*mem) == 1) \
- __atg2_result = pre##_8_##post (mem, __VA_ARGS__); \
+ __atg2_result = (int) pre##_8_##post (mem, __VA_ARGS__); \
else if (sizeof (*mem) == 2) \
- __atg2_result = pre##_16_##post (mem, __VA_ARGS__); \
+ __atg2_result = (int) pre##_16_##post (mem, __VA_ARGS__); \
else if (sizeof (*mem) == 4) \
- __atg2_result = pre##_32_##post (mem, __VA_ARGS__); \
+ __atg2_result = (int) pre##_32_##post (mem, __VA_ARGS__); \
else if (sizeof (*mem) == 8) \
- __atg2_result = pre##_64_##post (mem, __VA_ARGS__); \
+ __atg2_result = (int) pre##_64_##post (mem, __VA_ARGS__); \
else \
abort (); \
__atg2_result; \
diff --git a/include/elf.h b/include/elf.h
index c2efa9978..1e7c89615 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -3588,8 +3588,12 @@ typedef Elf32_Addr Elf32_Conflict;
#define R_XTENSA_TLSDESC_FN 50
#define R_XTENSA_TLSDESC_ARG 51
#define R_XTENSA_TLS_TPOFF 53
+#define R_XTENSA_SYM32 63
+#define R_XTENSA_FUNCDESC 68
+#define R_XTENSA_FUNCDESC_VALUE 69
+#define R_XTENSA_TLSDESC 72
/* Keep this the last entry. */
-#define R_XTENSA_NUM 54
+#define R_XTENSA_NUM 77
/* C6X specific relocs */
#define R_C6000_NONE 0
diff --git a/include/features.h b/include/features.h
index b5d4e79f2..1a4efb9db 100644
--- a/include/features.h
+++ b/include/features.h
@@ -140,6 +140,18 @@
# define __GNUC_PREREQ(maj, min) 0
#endif
+/* Convenience macro to test the version of clang.
+ Use like this:
+ #if __CLANG_PREREQ(3,2)
+ ... code requiring clang 3.2 or later ...
+ #endif */
+#if defined __clang__
+# define __CLANG_PREREQ(maj, min) \
+ ((__clang_major__ << 16) + __clang_minor__ >= ((maj) << 16) + (min))
+#else
+# define __CLANG_PREREQ(maj, min) 0
+#endif
+
/* Whether to use feature set F. */
#define __GLIBC_USE(F) __GLIBC_USE_ ## F
diff --git a/include/fenv.h b/include/fenv.h
index 9ba384756..4b532c573 100644
--- a/include/fenv.h
+++ b/include/fenv.h
@@ -23,6 +23,7 @@
#define _FENV_H 1
#include <features.h>
+#include <stdbool.h>
/* Get the architecture dependend definitions. The following definitions
are expected to be done:
@@ -130,6 +131,15 @@ extern int fedisableexcept (int __excepts) __THROW;
extern int fegetexcept (void) __THROW;
#endif
+/* Rounding mode context. This allows functions to set/restore rounding mode
+ only when the desired rounding mode is different from the current rounding
+ mode. */
+struct rm_ctx
+{
+ fenv_t env;
+ bool updated_status;
+};
+
__END_DECLS
#endif /* fenv.h */
diff --git a/include/internal/time64_helpers.h b/include/internal/time64_helpers.h
index 2284aacd9..e2ed0f3bb 100644
--- a/include/internal/time64_helpers.h
+++ b/include/internal/time64_helpers.h
@@ -1,10 +1,15 @@
#ifndef _TIME64_HELPERS_H
#define _TIME64_HELPERS_H
+#include <linux/version.h>
#include <bits/types.h>
#include <time.h>
#include <stddef.h>
+#if defined(__UCLIBC_USE_TIME64__) && __TARGET_ARCH_BITS__ == 32 && LINUX_VERSION_CODE < KERNEL_VERSION(5,1,0)
+#error 64bit time on 32bit targets is not supported on Linux < 5.1.0
+#endif
+
struct __ts64_struct {
__S64_TYPE tv_sec;
__S64_TYPE tv_nsec;
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/net/ppp_defs.h b/include/net/ppp_defs.h
index f8924c4f2..904d1933c 100644
--- a/include/net/ppp_defs.h
+++ b/include/net/ppp_defs.h
@@ -4,7 +4,7 @@
#define __need_time_t
#include <time.h>
-#include <asm/types.h>
+#include <sys/types.h>
#include <linux/ppp_defs.h>
#endif /* net/ppp_defs.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/include/spawn.h b/include/spawn.h
index 3de375b41..cf01639c1 100644
--- a/include/spawn.h
+++ b/include/spawn.h
@@ -103,6 +103,7 @@ int posix_spawnattr_init (posix_spawnattr_t *__attr)
static inline
int posix_spawnattr_destroy (posix_spawnattr_t *__attr)
{
+ (void)__attr;
return 0;
}
diff --git a/include/stdint.h b/include/stdint.h
index 749f73697..5fedfb574 100644
--- a/include/stdint.h
+++ b/include/stdint.h
@@ -144,11 +144,19 @@ typedef unsigned long long int uintmax_t;
# if __WORDSIZE == 64
+# ifndef __INT64_C
# define __INT64_C(c) c ## L
+# endif
+# ifndef __UINT64_C
# define __UINT64_C(c) c ## UL
+# endif
# else
+# ifndef __INT64_C
# define __INT64_C(c) c ## LL
+# endif
+# ifndef __UINT64_C
# define __UINT64_C(c) c ## ULL
+# endif
# endif
/* Limits of integral types. */
diff --git a/include/stdio.h b/include/stdio.h
index 0915da909..a48fa9b78 100644
--- a/include/stdio.h
+++ b/include/stdio.h
@@ -110,7 +110,10 @@ typedef __STDIO_fpos64_t fpos64_t;
#define SEEK_SET 0 /* Seek from beginning of file. */
#define SEEK_CUR 1 /* Seek from current position. */
#define SEEK_END 2 /* Seek from end of file. */
-
+#ifdef __USE_GNU
+# define SEEK_DATA 3 /* Seek to next data. */
+# define SEEK_HOLE 4 /* Seek to next hole. */
+#endif
#if defined __USE_SVID || defined __USE_XOPEN
/* Default path prefix for `mkstemp'. */
diff --git a/include/stdlib.h b/include/stdlib.h
index 8b1375184..448c5e336 100644
--- a/include/stdlib.h
+++ b/include/stdlib.h
@@ -606,7 +606,7 @@ libc_hidden_proto(unsetenv)
#ifdef __UCLIBC_DYNAMIC_ATEXIT__
# define __UCLIBC_MAX_ATEXIT INT_MAX
#else
-# define __UCLIBC_MAX_ATEXIT 20
+# define __UCLIBC_MAX_ATEXIT 32
#endif
@@ -986,9 +986,13 @@ extern int getpt (void);
extern int getloadavg (double __loadavg[], int __nelem)
__THROW __nonnull ((1));
+/* reallocarray() only provided by the malloc-standard implementation */
+#if defined(__MALLOC_STANDARD__)
extern void *reallocarray (void *__ptr, size_t __m, size_t __n);
#endif
+#endif
+
#ifdef _LIBC
extern int __drand48_iterate (unsigned short int xsubi[3], struct drand48_data *buffer) attribute_hidden;
diff --git a/include/sys/cdefs.h b/include/sys/cdefs.h
index 5c4daebcd..656548c52 100644
--- a/include/sys/cdefs.h
+++ b/include/sys/cdefs.h
@@ -58,9 +58,15 @@
# define __NTH(fct) __attribute__ ((__nothrow__ __LEAF)) fct
# else
# if defined __cplusplus && __GNUC_PREREQ (2,8)
-# define __THROW throw ()
-# define __THROWNL throw ()
-# define __NTH(fct) __LEAF_ATTR fct throw ()
+/* Dynamic exception specification is deprecated since C++11, so
+ we only use it when compiling for an earlier standard. */
+# if __cplusplus < 201103UL
+# define __THROW throw ()
+# else
+# define __THROW noexcept
+# endif
+# define __THROWNL __THROW
+# define __NTH(fct) __LEAF_ATTR fct __THROW
# else
# define __THROW
# define __THROWNL
@@ -314,7 +320,7 @@
inline semantics, unless -fgnu89-inline is used.
For -std=gnu99, forcing gnu_inline attribute does not change behavior,
but may silence spurious warnings (such as in GCC 4.2). */
-#if !defined __cplusplus || __GNUC_PREREQ (4,3)
+#if !defined __cplusplus || __GNUC_PREREQ (4,3) || __CLANG_PREREQ(8,0)
# if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__ || defined __cplusplus
# define __extern_inline extern __inline __attribute__ ((__gnu_inline__))
# if __GNUC_PREREQ (4,3)
diff --git a/include/sys/mount.h b/include/sys/mount.h
index c0e7b84f8..f9edbeba3 100644
--- a/include/sys/mount.h
+++ b/include/sys/mount.h
@@ -32,54 +32,79 @@
supported */
enum
{
+#undef MS_RDONLY
MS_RDONLY = 1, /* Mount read-only. */
#define MS_RDONLY MS_RDONLY
+#undef MS_NOSUID
MS_NOSUID = 2, /* Ignore suid and sgid bits. */
#define MS_NOSUID MS_NOSUID
+#undef MS_NODEV
MS_NODEV = 4, /* Disallow access to device special files. */
#define MS_NODEV MS_NODEV
+#undef MS_NOEXEC
MS_NOEXEC = 8, /* Disallow program execution. */
#define MS_NOEXEC MS_NOEXEC
+#undef MS_SYNCHRONOUS
MS_SYNCHRONOUS = 16, /* Writes are synced at once. */
#define MS_SYNCHRONOUS MS_SYNCHRONOUS
+#undef MS_REMOUNT
MS_REMOUNT = 32, /* Alter flags of a mounted FS. */
#define MS_REMOUNT MS_REMOUNT
+#undef MS_MANDLOCK
MS_MANDLOCK = 64, /* Allow mandatory locks on an FS. */
#define MS_MANDLOCK MS_MANDLOCK
+#undef MS_DIRSYNC
MS_DIRSYNC = 128, /* Directory modifications are synchronous. */
#define MS_DIRSYNC MS_DIRSYNC
+#undef MS_NOATIME
MS_NOATIME = 1024, /* Do not update access times. */
#define MS_NOATIME MS_NOATIME
+#undef MS_NODIRATIME
MS_NODIRATIME = 2048, /* Do not update directory access times. */
#define MS_NODIRATIME MS_NODIRATIME
+#undef MS_BIND
MS_BIND = 4096, /* Bind directory at different place. */
#define MS_BIND MS_BIND
+#undef MS_MOVE
MS_MOVE = 8192,
#define MS_MOVE MS_MOVE
+#undef MS_REC
MS_REC = 16384,
#define MS_REC MS_REC
+#undef MS_SILENT
MS_SILENT = 32768,
#define MS_SILENT MS_SILENT
+#undef MS_POSIXACL
MS_POSIXACL = 1 << 16, /* VFS does not apply the umask. */
#define MS_POSIXACL MS_POSIXACL
+#undef MS_UNBINDABLE
MS_UNBINDABLE = 1 << 17, /* Change to unbindable. */
#define MS_UNBINDABLE MS_UNBINDABLE
+#undef MS_PRIVATE
MS_PRIVATE = 1 << 18, /* Change to private. */
#define MS_PRIVATE MS_PRIVATE
+#undef MS_SLAVE
MS_SLAVE = 1 << 19, /* Change to slave. */
#define MS_SLAVE MS_SLAVE
+#undef MS_SHARED
MS_SHARED = 1 << 20, /* Change to shared. */
#define MS_SHARED MS_SHARED
+#undef MS_RELATIME
MS_RELATIME = 1 << 21, /* Update atime relative to mtime/ctime. */
#define MS_RELATIME MS_RELATIME
+#undef MS_KERNMOUNT
MS_KERNMOUNT = 1 << 22, /* This is a kern_mount call. */
#define MS_KERNMOUNT MS_KERNMOUNT
+#undef MS_I_VERSION
MS_I_VERSION = 1 << 23, /* Update inode I_version field. */
#define MS_I_VERSION MS_I_VERSION
+#undef MS_STRICTATIME
MS_STRICTATIME = 1 << 24, /* Always perform atime updates. */
#define MS_STRICTATIME MS_STRICTATIME
+#undef MS_ACTIVE
MS_ACTIVE = 1 << 30,
#define MS_ACTIVE MS_ACTIVE
+#undef MS_NOUSER
MS_NOUSER = 1 << 31
#define MS_NOUSER MS_NOUSER
};
diff --git a/include/sys/uio.h b/include/sys/uio.h
index 330426fec..9e9708c0c 100644
--- a/include/sys/uio.h
+++ b/include/sys/uio.h
@@ -74,6 +74,25 @@ extern ssize_t pwritev (int __fd, const struct iovec *__iovec, int __count,
__off64_t __offset) __wur;
#endif /* Use misc. */
+#ifdef __USE_GNU
+/* Read from another process' address space. */
+extern ssize_t process_vm_readv (pid_t __pid, const struct iovec *__lvec,
+ unsigned long int __liovcnt,
+ const struct iovec *__rvec,
+ unsigned long int __riovcnt,
+ unsigned long int __flags)
+ __THROW;
+
+/* Write to another process' address space. */
+extern ssize_t process_vm_writev (pid_t __pid, const struct iovec *__lvec,
+ unsigned long int __liovcnt,
+ const struct iovec *__rvec,
+ unsigned long int __riovcnt,
+ unsigned long int __flags)
+ __THROW;
+
+#endif
+
__END_DECLS
#endif /* sys/uio.h */
diff --git a/include/ucontext.h b/include/ucontext.h
index 4ce114ef1..76b4f375e 100644
--- a/include/ucontext.h
+++ b/include/ucontext.h
@@ -23,11 +23,11 @@
#include <features.h>
-#ifdef __UCLIBC_HAS_CONTEXT_FUNCS__
-
/* Get machine dependent definition of data structures. */
#include <sys/ucontext.h>
+#ifdef __UCLIBC_HAS_CONTEXT_FUNCS__
+
__BEGIN_DECLS
/* Get user context and store it in variable pointed to by UCP. */
diff --git a/include/unistd.h b/include/unistd.h
index 36cd5fcb5..e45266f14 100644
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -316,6 +316,10 @@ libc_hidden_proto(faccessat)
# define SEEK_SET 0 /* Seek from beginning of file. */
# define SEEK_CUR 1 /* Seek from current position. */
# define SEEK_END 2 /* Seek from end of file. */
+# ifdef __USE_GNU
+# define SEEK_DATA 3 /* Seek to next data. */
+# define SEEK_HOLE 4 /* Seek to next hole. */
+# endif
#endif
#if defined __USE_BSD && !defined L_SET
@@ -1246,6 +1250,15 @@ extern void swab (const void *__restrict __from, void *__restrict __to,
extern char *ctermid (char *__s) __THROW;
#endif
+/* OpenBSD-compatible access to random bytes.
+ May be a cancellation point here, unlike in glibc/musl. */
+#ifdef _DEFAULT_SOURCE
+# ifndef __getentropy_defined
+extern int getentropy(void *__buf, size_t __len) __nonnull ((1)) __wur;
+# define __getentropy_defined
+# endif
+#endif
+
__END_DECLS
diff --git a/ldso/include/dl-auxvt.h b/ldso/include/dl-auxvt.h
new file mode 100644
index 000000000..29eda6eb3
--- /dev/null
+++ b/ldso/include/dl-auxvt.h
@@ -0,0 +1,9 @@
+#ifndef _DL_AUXVT_H
+#define _DL_AUXVT_H
+
+#define AUX_MAX_AT_ID 40
+extern ElfW(auxv_t) _dl_auxvt[AUX_MAX_AT_ID]; /* Cache frequently accessed auxiliary vector entries */
+extern ElfW(auxv_t) *_dl_auxv_start; /* Start of the auxiliary vector */
+
+#endif /* _DL_AUXVT_H */
+
diff --git a/ldso/include/dl-syscall.h b/ldso/include/dl-syscall.h
index 4f41034ad..c143b8d45 100644
--- a/ldso/include/dl-syscall.h
+++ b/ldso/include/dl-syscall.h
@@ -17,6 +17,8 @@ extern int _dl_errno;
#define __set_errno(X) {(_dl_errno) = (X);}
#endif
+#include <linux/version.h>
+
/* Pull in the arch specific syscall implementation */
#include <dl-syscalls.h>
/* For MAP_ANONYMOUS -- differs between platforms */
@@ -139,7 +141,7 @@ static __always_inline int _dl_stat(const char *file_name,
{
return _dl_newfstatat(AT_FDCWD, file_name, buf, 0);
}
-#elif defined __NR_stat && (!defined(__UCLIBC_USE_TIME64__) || defined(__sparc__))
+#elif defined __NR_stat && (!defined(__UCLIBC_USE_TIME64__) || defined(__sparc__) || (LINUX_VERSION_CODE <= KERNEL_VERSION(5,1,0)))
# define __NR__dl_stat __NR_stat
static __always_inline _syscall2(int, _dl_stat, const char *, file_name,
struct stat *, buf)
@@ -166,7 +168,7 @@ static __always_inline int _dl_stat(const char *file_name,
#if defined __NR_fstat64 && !defined __NR_fstat && (!defined(__UCLIBC_USE_TIME64__) || defined(__sparc__))
# define __NR__dl_fstat __NR_fstat64
static __always_inline _syscall2(int, _dl_fstat, int, fd, struct stat *, buf)
-#elif defined __NR_fstat
+#elif defined __NR_fstat && !defined __UCLIBC_USE_TIME64__ || defined(__sparc__)
# define __NR__dl_fstat __NR_fstat
static __always_inline _syscall2(int, _dl_fstat, int, fd, struct stat *, buf)
#elif defined __NR_statx && defined __UCLIBC_HAVE_STATX__
diff --git a/ldso/include/ldso.h b/ldso/include/ldso.h
index a397cce61..061d8a536 100755
--- a/ldso/include/ldso.h
+++ b/ldso/include/ldso.h
@@ -191,8 +191,7 @@ extern void *_dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE loa
#endif
-#define AUX_MAX_AT_ID 40
-extern ElfW(auxv_t) _dl_auxvt[AUX_MAX_AT_ID];
+#include <dl-auxvt.h>
void load_vdso(void *sys_info_ehdr, char **envp );
diff --git a/ldso/ldso/Makefile.in b/ldso/ldso/Makefile.in
index 6e8a0c388..0f8ed140d 100644
--- a/ldso/ldso/Makefile.in
+++ b/ldso/ldso/Makefile.in
@@ -19,6 +19,11 @@ ifeq ($(TARGET_ARCH),arm)
CFLAGS-rtld += -fno-unwind-tables -fno-asynchronous-unwind-tables
endif
+ifeq ($(TARGET_ARCH),bfin)
+# for gcc 10.5.0 and above we need to use -ffreestanding
+CFLAGS-rtld += -ffreestanding
+endif
+
CFLAGS-rtld += -I$(top_srcdir)ldso/ldso/$(TARGET_ARCH) -I$(top_srcdir)ldso/include -I$(top_srcdir)ldso/ldso
CFLAGS-rtld += -DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" -DUCLIBC_LDSO=\"$(UCLIBC_LDSO)\"
diff --git a/ldso/ldso/aarch64/dl-sysdep.h b/ldso/ldso/aarch64/dl-sysdep.h
index 6d9d2c1fb..3466920d9 100644
--- a/ldso/ldso/aarch64/dl-sysdep.h
+++ b/ldso/ldso/aarch64/dl-sysdep.h
@@ -54,28 +54,21 @@ unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
|| (type) == R_AARCH64_TLSDESC) * ELF_RTYPE_CLASS_PLT) \
| (((type) == R_AARCH64_COPY) * ELF_RTYPE_CLASS_COPY))
-/* Return the link-time address of _DYNAMIC. Conveniently, this is the
- first element of the GOT. */
-extern const ElfW(Addr) _GLOBAL_OFFSET_TABLE_[] attribute_hidden;
-static __always_inline ElfW(Addr) __attribute__ ((unused))
-elf_machine_dynamic (void)
-{
- return _GLOBAL_OFFSET_TABLE_[0];
-}
-
/* Return the run-time load address of the shared object. */
static __always_inline ElfW(Addr) __attribute__ ((unused))
elf_machine_load_address (void)
{
- /* To figure out the load address we use the definition that for any symbol:
- dynamic_addr(symbol) = static_addr(symbol) + load_addr
-
- _DYNAMIC sysmbol is used here as its link-time address stored in
- the special unrelocated first GOT entry. */
+ extern const ElfW(Ehdr) __ehdr_start attribute_hidden;
+ return (ElfW(Addr)) &__ehdr_start;
+}
- extern ElfW(Dyn) _DYNAMIC[] attribute_hidden;
- return (ElfW(Addr)) &_DYNAMIC - elf_machine_dynamic ();
+/* Return the link-time address of _DYNAMIC. */
+static __always_inline ElfW(Addr) __attribute__ ((unused))
+elf_machine_dynamic (void)
+{
+ extern ElfW(Dyn) _DYNAMIC[] attribute_hidden;
+ return (ElfW(Addr)) _DYNAMIC - elf_machine_load_address ();
}
static __always_inline void
diff --git a/ldso/ldso/arm/dl-sysdep.h b/ldso/ldso/arm/dl-sysdep.h
index 0f783e1c4..93e36b694 100644
--- a/ldso/ldso/arm/dl-sysdep.h
+++ b/ldso/ldso/arm/dl-sysdep.h
@@ -96,43 +96,6 @@ unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
| (((type) == R_ARM_COPY) * ELF_RTYPE_CLASS_COPY))
#endif /* __FDPIC__ */
-/* Return the link-time address of _DYNAMIC. Conveniently, this is the
- first element of the GOT. We used to use the PIC register to do this
- without a constant pool reference, but GCC 4.2 will use a pseudo-register
- for the PIC base, so it may not be in r10. */
-static __always_inline Elf32_Addr __attribute__ ((unused))
-elf_machine_dynamic (void)
-{
- Elf32_Addr dynamic;
-#if !defined __thumb__
- __asm__ ("ldr %0, 2f\n"
- "1: ldr %0, [pc, %0]\n"
- "b 3f\n"
- "2: .word _GLOBAL_OFFSET_TABLE_ - (1b+8)\n"
- "3:" : "=r" (dynamic));
-#else
- int tmp;
- __asm__ (".align 2\n"
- "bx pc\n"
- "nop\n"
- ".arm\n"
- "ldr %0, 2f\n"
- "1: ldr %0, [pc, %0]\n"
- "b 3f\n"
- "2: .word _GLOBAL_OFFSET_TABLE_ - (1b+8)\n"
- "3:"
- ".align 2\n"
- "orr %1, pc, #1\n"
- "bx %1\n"
- ".force_thumb\n"
- : "=r" (dynamic), "=&r" (tmp));
-#endif
-
- return dynamic;
-}
-
-extern char __dl_start[] __asm__("_dl_start");
-
#ifdef __FDPIC__
/* We must force strings used early in the bootstrap into the data
segment. */
@@ -148,28 +111,16 @@ extern char __dl_start[] __asm__("_dl_start");
static __always_inline Elf32_Addr __attribute__ ((unused))
elf_machine_load_address (void)
{
-#if defined(__FDPIC__)
- return 0;
-#else
- Elf32_Addr got_addr = (Elf32_Addr) &__dl_start;
- Elf32_Addr pcrel_addr;
-#if defined __OPTIMIZE__ && !defined __thumb__
- __asm__ ("adr %0, _dl_start" : "=r" (pcrel_addr));
-#else
- /* A simple adr does not work in Thumb mode because the offset is
- negative, and for debug builds may be too large. */
- int tmp;
- __asm__ ("adr %1, 1f\n\t"
- "ldr %0, [%1]\n\t"
- "add %0, %0, %1\n\t"
- "b 2f\n\t"
- ".align 2\n\t"
- "1: .word _dl_start - 1b\n\t"
- "2:"
- : "=r" (pcrel_addr), "=r" (tmp));
-#endif
- return pcrel_addr - got_addr;
-#endif
+ extern const Elf32_Ehdr __ehdr_start attribute_hidden;
+ return (Elf32_Addr) &__ehdr_start;
+}
+
+/* Return the link-time address of _DYNAMIC. */
+static __always_inline Elf32_Addr __attribute__ ((unused))
+elf_machine_dynamic (void)
+{
+ extern Elf32_Dyn _DYNAMIC[] attribute_hidden;
+ return (Elf32_Addr) _DYNAMIC - elf_machine_load_address ();
}
static __always_inline void
diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c
index 4f50d62b7..6656acb0f 100644
--- a/ldso/ldso/dl-elf.c
+++ b/ldso/ldso/dl-elf.c
@@ -1028,7 +1028,7 @@ int _dl_fixup(struct dyn_elf *rpnt, struct r_scope_elem *scope, int now_flag)
return goof;
}
-#if !defined(__FDPIC__) && !defined(__DSBT__)
+#if !defined(__FDPIC__) && !defined(__FRV_FDPIC__) && !defined(__DSBT__)
/* Process DT_RELR relative relocations */
DL_RELOCATE_RELR(tpnt);
#endif
diff --git a/ldso/ldso/dl-startup.c b/ldso/ldso/dl-startup.c
index e7000bd87..ec6b72a39 100644
--- a/ldso/ldso/dl-startup.c
+++ b/ldso/ldso/dl-startup.c
@@ -100,6 +100,7 @@ extern ElfW(Addr) _begin[] attribute_hidden;
ElfW(auxv_t) _dl_auxvt[AUX_MAX_AT_ID];
+ElfW(auxv_t) *_dl_auxv_start;
#ifdef LDSO_NEED_DPNT
ElfW(Dyn) *_dl_saved_dpnt = 0;
@@ -131,6 +132,7 @@ DL_START(unsigned long args)
struct elf_resolve tpnt_tmp;
struct elf_resolve *tpnt = &tpnt_tmp;
ElfW(auxv_t) _dl_auxvt_tmp[AUX_MAX_AT_ID];
+ ElfW(auxv_t) *_dl_auxv_start_tmp;
ElfW(Dyn) *dpnt;
uint32_t *p32;
@@ -166,6 +168,7 @@ DL_START(unsigned long args)
/* The junk on the stack immediately following the environment is
* the Auxiliary Vector Table. Read out the elements of the auxvt,
* sort and store them in auxvt for later use. */
+ _dl_auxv_start_tmp = (ElfW(auxv_t) *)aux_dat;
while (*aux_dat) {
ElfW(auxv_t) *auxv_entry = (ElfW(auxv_t) *) aux_dat;
@@ -264,7 +267,7 @@ DL_START(unsigned long args)
that once we are done, we have considerably more flexibility. */
SEND_EARLY_STDERR_DEBUG("About to do library loader relocations\n");
-#if !defined(__FDPIC__) && !defined(__DSBT__)
+#if !defined(__FDPIC__) && !defined(__FRV_FDPIC__) && !defined(__DSBT__)
/* Process DT_RELR relative relocations */
DL_RELOCATE_RELR(tpnt);
#endif
@@ -367,6 +370,7 @@ DL_START(unsigned long args)
* now the globals work. so copy the aux vector
*/
_dl_memcpy( _dl_auxvt, _dl_auxvt_tmp, sizeof( ElfW(auxv_t) ) * AUX_MAX_AT_ID );
+ _dl_auxv_start = _dl_auxv_start_tmp;
_dl_elf_main = (int (*)(int, char **, char **))
_dl_get_ready_to_run(tpnt, load_addr, envp, argv
diff --git a/ldso/ldso/dl-vdso.c b/ldso/ldso/dl-vdso.c
index 196cbbb3b..01309011d 100755
--- a/ldso/ldso/dl-vdso.c
+++ b/ldso/ldso/dl-vdso.c
@@ -28,14 +28,14 @@
#ifndef __VDSO_SUPPORT__
- void load_vdso(void *sys_info_ehdr, char **envp ){
+void load_vdso( void *sys_info_ehdr attribute_unused,
+ char **envp attribute_unused ){
#ifdef __SUPPORT_LD_DEBUG__
- if ( _dl_debug_vdso != 0 ){
- _dl_dprintf(2,"_dl_vdso support not enabled\n" );
- }
-
-#endif
+ if ( _dl_debug_vdso != 0 ){
+ _dl_dprintf(2,"_dl_vdso support not enabled\n" );
}
+#endif
+}
#else
void *_dl__vdso_gettimeofday = 0;
diff --git a/ldso/ldso/i386/dl-sysdep.h b/ldso/ldso/i386/dl-sysdep.h
index b95328df4..8fc80a145 100644
--- a/ldso/ldso/i386/dl-sysdep.h
+++ b/ldso/ldso/i386/dl-sysdep.h
@@ -35,28 +35,21 @@ extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_ent
|| (type) == R_386_TLS_TPOFF) * ELF_RTYPE_CLASS_PLT) \
| (((type) == R_386_COPY) * ELF_RTYPE_CLASS_COPY))
-/* Return the link-time address of _DYNAMIC. Conveniently, this is the
- first element of the GOT, a special entry that is never relocated. */
-extern const Elf32_Addr _GLOBAL_OFFSET_TABLE_[] attribute_hidden;
-static __always_inline Elf32_Addr __attribute__ ((unused, const))
-elf_machine_dynamic (void)
-{
- /* This produces a GOTOFF reloc that resolves to zero at link time, so in
- fact just loads from the GOT register directly. By doing it without
- an asm we can let the compiler choose any register. */
- return _GLOBAL_OFFSET_TABLE_[0];
-}
-
-extern Elf32_Dyn bygotoff[] __asm__ ("_DYNAMIC") attribute_hidden;
/* Return the run-time load address of the shared object. */
static __always_inline Elf32_Addr attribute_unused
elf_machine_load_address (void)
{
- /* Compute the difference between the runtime address of _DYNAMIC as seen
- by a GOTOFF reference, and the link-time address found in the special
- unrelocated first GOT entry. */
- return (Elf32_Addr) &bygotoff - elf_machine_dynamic ();
+ extern const Elf32_Ehdr __ehdr_start attribute_hidden;
+ return (Elf32_Addr) &__ehdr_start;
+}
+
+/* Return the link-time address of _DYNAMIC. */
+static __always_inline Elf32_Addr __attribute__ ((unused, const))
+elf_machine_dynamic (void)
+{
+ extern Elf32_Dyn _DYNAMIC[] attribute_hidden;
+ return (Elf32_Addr) _DYNAMIC - elf_machine_load_address ();
}
static __always_inline void
diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c
index 435bd43bc..e866d6418 100755
--- a/ldso/ldso/ldso.c
+++ b/ldso/ldso/ldso.c
@@ -682,7 +682,7 @@ of this helper program; chances are you did not intend to run this program.\n\
*/
/* Now cover the application program. */
if (app_tpnt->dynamic_info[DT_TEXTREL]) {
- int j;
+ unsigned int j;
ElfW(Phdr) *ppnt_outer = ppnt;
_dl_debug_early("calling mprotect on the application program\n");
ppnt = (ElfW(Phdr) *) _dl_auxvt[AT_PHDR].a_un.a_val;
diff --git a/ldso/ldso/m68k/elfinterp.c b/ldso/ldso/m68k/elfinterp.c
index 25ea23067..e7fa117da 100644
--- a/ldso/ldso/m68k/elfinterp.c
+++ b/ldso/ldso/m68k/elfinterp.c
@@ -193,7 +193,7 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope,
#endif
#if defined (__SUPPORT_LD_DEBUG__)
- old_val = *reloc_addr;
+ old_val = reloc_addr ? *reloc_addr : 0;
#endif
switch (reloc_type) {
@@ -292,7 +292,7 @@ _dl_do_lazy_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope,
reloc_type = ELF_R_TYPE(rpnt->r_info);
#if defined (__SUPPORT_LD_DEBUG__)
- old_val = *reloc_addr;
+ old_val = reloc_addr ? *reloc_addr : 0;
#endif
switch (reloc_type) {
diff --git a/ldso/ldso/riscv32/dl-sysdep.h b/ldso/ldso/riscv32/dl-sysdep.h
index e0a59fddd..02296b148 100644
--- a/ldso/ldso/riscv32/dl-sysdep.h
+++ b/ldso/ldso/riscv32/dl-sysdep.h
@@ -59,22 +59,20 @@ unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
| (ELF_RTYPE_CLASS_COPY * ((type) == R_RISCV_COPY)))
-/* Return the link-time address of _DYNAMIC. */
-static inline ElfW(Addr)
-elf_machine_dynamic (void)
-{
- extern ElfW(Addr) _GLOBAL_OFFSET_TABLE_ __attribute__ ((visibility ("hidden")));
- return _GLOBAL_OFFSET_TABLE_;
-}
-
-
/* Return the run-time load address of the shared object. */
static __always_inline ElfW(Addr) __attribute__ ((unused))
elf_machine_load_address (void)
{
- ElfW(Addr) load_addr;
- __asm__ ("lla %0, _DYNAMIC" : "=r" (load_addr));
- return load_addr - elf_machine_dynamic ();
+ extern const ElfW(Ehdr) __ehdr_start attribute_hidden;
+ return (ElfW(Addr)) &__ehdr_start;
+}
+
+/* Return the link-time address of _DYNAMIC. */
+static inline ElfW(Addr)
+elf_machine_dynamic (void)
+{
+ extern ElfW(Dyn) _DYNAMIC[] attribute_hidden;
+ return (ElfW(Addr)) _DYNAMIC - elf_machine_load_address ();
}
static __always_inline void
diff --git a/ldso/ldso/x86_64/dl-sysdep.h b/ldso/ldso/x86_64/dl-sysdep.h
index ccf9a8851..58447a951 100644
--- a/ldso/ldso/x86_64/dl-sysdep.h
+++ b/ldso/ldso/x86_64/dl-sysdep.h
@@ -52,48 +52,21 @@ extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_ent
* ELF_RTYPE_CLASS_PLT) \
| (((type) == R_X86_64_COPY) * ELF_RTYPE_CLASS_COPY))
-/* Return the link-time address of _DYNAMIC. Conveniently, this is the
- first element of the GOT. This must be inlined in a function which
- uses global data. */
-static __always_inline Elf64_Addr __attribute__ ((unused))
-elf_machine_dynamic (void)
-{
- Elf64_Addr addr;
-
- /* This works because we have our GOT address available in the small PIC
- model. */
- addr = (Elf64_Addr) &_DYNAMIC;
-
- return addr;
-}
-
/* Return the run-time load address of the shared object. */
static __always_inline Elf64_Addr __attribute__ ((unused))
elf_machine_load_address (void)
{
- register Elf64_Addr addr, tmp;
-
- /* The easy way is just the same as on x86:
- leaq _dl_start, %0
- leaq _dl_start(%%rip), %1
- subq %0, %1
- but this does not work with binutils since we then have
- a R_X86_64_32S relocation in a shared lib.
-
- Instead we store the address of _dl_start in the data section
- and compare it with the current value that we can get via
- an RIP relative addressing mode. */
-
- __asm__ ("movq 1f(%%rip), %1\n"
- "0:\tleaq _dl_start(%%rip), %0\n\t"
- "subq %1, %0\n\t"
- ".section\t.data\n"
- "1:\t.quad _dl_start\n\t"
- ".previous\n\t"
- : "=r" (addr), "=r" (tmp) : : "cc");
+ extern const Elf64_Ehdr __ehdr_start attribute_hidden;
+ return (Elf64_Addr) &__ehdr_start;
+}
- return addr;
+/* Return the link-time address of _DYNAMIC. */
+static __always_inline Elf64_Addr __attribute__ ((unused))
+elf_machine_dynamic (void)
+{
+ extern Elf64_Dyn _DYNAMIC[] attribute_hidden;
+ return (Elf64_Addr) _DYNAMIC - elf_machine_load_address ();
}
static __always_inline void
diff --git a/ldso/ldso/xtensa/dl-inlines.h b/ldso/ldso/xtensa/dl-inlines.h
new file mode 100644
index 000000000..8fdf6eb48
--- /dev/null
+++ b/ldso/ldso/xtensa/dl-inlines.h
@@ -0,0 +1 @@
+#include "../fdpic/dl-inlines.h"
diff --git a/ldso/ldso/xtensa/dl-startup.h b/ldso/ldso/xtensa/dl-startup.h
index c9350c0f2..2a453752a 100644
--- a/ldso/ldso/xtensa/dl-startup.h
+++ b/ldso/ldso/xtensa/dl-startup.h
@@ -7,6 +7,68 @@
* Parts taken from glibc/sysdeps/xtensa/dl-machine.h.
*/
+#if defined(__FDPIC__)
+__asm__ (
+ " .text\n"
+ " .align 4\n"
+ " .literal_position\n"
+ " .global _start\n"
+ " .type _start, @function\n"
+ " .hidden _start\n"
+ "_start:\n"
+ " .begin no-transform\n"
+ " _call0 1f\n"
+ "2:\n"
+ " .end no-transform\n"
+ " .align 4\n"
+ "1:\n"
+#if defined(__XTENSA_CALL0_ABI__)
+ " movi a15, 2b\n"
+ " sub a15, a0, a15\n"
+
+ /* Save FDPIC pointers in callee-saved registers */
+ " mov a12, a4\n"
+ " mov a13, a5\n"
+ " mov a14, a6\n"
+
+ /* Call __self_reloc */
+ " mov a2, a5\n"
+ " movi a3, __ROFIXUP_LIST__\n"
+ " add a3, a3, a15\n"
+ " movi a4, __ROFIXUP_END__\n"
+ " add a4, a4, a15\n"
+ " movi a0, __self_reloc\n"
+ " add a0, a0, a15\n"
+ " callx0 a0\n"
+
+ /* call _dl_start */
+ " mov a3, a12\n"
+ " mov a4, a13\n"
+ " mov a5, a14\n"
+ " mov a7, sp\n"
+ " addi sp, sp, -16\n"
+ " mov a6, sp\n"
+ " mov a11, a2\n"
+ /* a13, interpreter map is no longer needed, save interpreter GOT there */
+ " mov a13, a2\n"
+ " movi a0, _dl_start\n"
+ " add a0, a0, a15\n"
+ " callx0 a0\n"
+
+ /* call main */
+ " l32i a0, sp, 0\n"
+ " l32i a11, sp, 4\n"
+ " addi sp, sp, 16\n"
+ " mov a4, a12\n"
+ " movi a5, _dl_fini@GOTOFFFUNCDESC\n"
+ " add a5, a5, a13\n"
+ " mov a6, a14\n"
+ " jx a0\n"
+#else
+#error Unsupported Xtensa ABI
+#endif
+ );
+#else /* __FDPIC__ */
#ifndef L_rcrt1
__asm__ (
" .text\n"
@@ -83,6 +145,7 @@ __asm__ (
" bnez a6, 3b\n"
" j .Lfixup_stack_ret");
#endif
+#endif /* __FDPIC__ */
/* Get a pointer to the argv value. */
#define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long *) ARGS) + 1)
@@ -90,7 +153,7 @@ __asm__ (
/* Function calls are not safe until the GOT relocations have been done. */
#define NO_FUNCS_BEFORE_BOOTSTRAP
-#if defined(__ARCH_USE_MMU__)
+#if defined(__ARCH_USE_MMU__) && !defined(__FDPIC__)
#define PERFORM_BOOTSTRAP_GOT(tpnt) \
do { \
xtensa_got_location *got_loc; \
@@ -128,3 +191,29 @@ do { \
} \
} while (0)
#endif
+
+#ifdef __FDPIC__
+#undef DL_START
+#define DL_START(X) \
+static void __attribute__ ((used)) \
+_dl_start (Elf32_Addr dl_boot_got_pointer, \
+ struct elf32_fdpic_loadmap *dl_boot_progmap, \
+ struct elf32_fdpic_loadmap *dl_boot_ldsomap, \
+ Elf32_Dyn *dl_boot_ldso_dyn_pointer, \
+ struct funcdesc_value *dl_main_funcdesc, \
+ X)
+
+/*
+ * Transfer control to the user's application, once the dynamic loader
+ * is done. We return the address of the function's entry point to
+ * _dl_boot, see boot1_arch.h.
+ */
+#define START() do { \
+ struct elf_resolve *exec_mod = _dl_loaded_modules; \
+ dl_main_funcdesc->entry_point = _dl_elf_main; \
+ while (exec_mod->libtype != elf_executable) \
+ exec_mod = exec_mod->next; \
+ dl_main_funcdesc->got_value = exec_mod->loadaddr.got_value; \
+ return; \
+} while (0)
+#endif /* __FDPIC__ */
diff --git a/ldso/ldso/xtensa/dl-sysdep.h b/ldso/ldso/xtensa/dl-sysdep.h
index 6b908989a..5aa3e177f 100644
--- a/ldso/ldso/xtensa/dl-sysdep.h
+++ b/ldso/ldso/xtensa/dl-sysdep.h
@@ -26,6 +26,7 @@
in l_info array. */
#define DT_XTENSA(x) (DT_XTENSA_##x - DT_LOPROC + DT_NUM + OS_NUM)
+#ifndef __FDPIC__
typedef struct xtensa_got_location_struct {
Elf32_Off offset;
Elf32_Word length;
@@ -86,6 +87,7 @@ typedef struct xtensa_got_location_struct {
else if (dpnt->d_tag == DT_XTENSA_GOT_LOC_SZ) \
dynamic[DT_XTENSA (GOT_LOC_SZ)] = dpnt->d_un.d_val; \
} while (0)
+#endif
/* Here we define the magic numbers that this dynamic loader should accept. */
#define MAGIC1 EM_XTENSA
@@ -115,10 +117,41 @@ elf_machine_dynamic (void)
return (Elf32_Addr) &_DYNAMIC;
}
+#ifdef __FDPIC__
+
+#define DL_CHECK_LIB_TYPE(epnt, piclib, _dl_progname, libname) \
+do \
+{ \
+ (piclib) = 2; \
+} \
+while (0)
+
+/* We must force strings used early in the bootstrap into the data
+ segment. */
+#undef SEND_EARLY_STDERR
+#define SEND_EARLY_STDERR(S) \
+ do { /* FIXME: implement */; } while (0)
+
+#undef INIT_GOT
+#include "../fdpic/dl-sysdep.h"
+#undef INIT_GOT
+#define INIT_GOT(GOT_BASE,MODULE) \
+{ \
+ (MODULE)->loadaddr.got_value = (GOT_BASE); \
+ GOT_BASE[0] = ((unsigned long *)&_dl_linux_resolve)[0]; \
+ GOT_BASE[1] = ((unsigned long *)&_dl_linux_resolve)[1]; \
+ GOT_BASE[2] = (unsigned long) MODULE; \
+}
+
+#endif /* __FDPIC__ */
+
/* Return the run-time load address of the shared object. */
static __always_inline Elf32_Addr
elf_machine_load_address (void)
{
+#ifdef __FDPIC__
+ return 0;
+#else
Elf32_Addr addr, tmp;
/* At this point, the runtime linker is being bootstrapped and the GOT
@@ -135,17 +168,48 @@ elf_machine_load_address (void)
: "=a" (addr), "=a" (tmp));
return addr - 3;
+#endif
}
+#ifdef __FDPIC__
+
+/* Need bootstrap relocations */
+#define ARCH_NEEDS_BOOTSTRAP_RELOCS
+
+#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \
+ switch (ELF_R_TYPE((RELP)->r_info)){ \
+ case R_XTENSA_SYM32: \
+ *(REL) = (SYMBOL) + (RELP)->r_addend; \
+ break; \
+ case R_XTENSA_RELATIVE: \
+ case R_XTENSA_NONE: \
+ default: \
+ break; \
+ }
+
static __always_inline void
-elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr,
+elf_machine_relative (DL_LOADADDR_TYPE load_off, const Elf32_Addr rel_addr,
Elf32_Word relative_count)
{
Elf32_Rela *rpnt = (Elf32_Rela *) rel_addr;
while (relative_count--)
{
+ Elf32_Addr *const reloc_addr = (Elf32_Addr *) DL_RELOC_ADDR(load_off, rpnt->r_offset);
+ *reloc_addr = DL_RELOC_ADDR(load_off, *reloc_addr);
+ rpnt++;
+ }
+}
+#else
+static __always_inline void
+elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr,
+ Elf32_Word relative_count)
+{
+ Elf32_Rela *rpnt = (Elf32_Rela *) rel_addr;
+ while (relative_count--)
+ {
Elf32_Addr *const reloc_addr = (Elf32_Addr *) (load_off + rpnt->r_offset);
*reloc_addr += load_off + rpnt->r_addend;
rpnt++;
}
}
+#endif
diff --git a/ldso/ldso/xtensa/dl-tlsdesc.S b/ldso/ldso/xtensa/dl-tlsdesc.S
index 426f2180b..1a8eacff2 100644
--- a/ldso/ldso/xtensa/dl-tlsdesc.S
+++ b/ldso/ldso/xtensa/dl-tlsdesc.S
@@ -24,6 +24,9 @@
.text
HIDDEN_ENTRY (_dl_tlsdesc_return)
+#ifdef __FDPIC__
+ l32i a2, a2, 4
+#endif
rur.threadptr a3
add a2, a2, a3
abi_ret
@@ -53,7 +56,9 @@ END (_dl_tlsdesc_return)
*/
HIDDEN_ENTRY (_dl_tlsdesc_dynamic)
-
+#ifdef __FDPIC__
+ l32i a2, a2, 4
+#endif
/* dtv_t *dtv = (dtv_t *)THREAD_DTV(); */
rur.threadptr a3
l32i a4, a3, 0
@@ -86,7 +91,8 @@ HIDDEN_ENTRY (_dl_tlsdesc_dynamic)
#elif defined(__XTENSA_CALL0_ABI__)
addi a1, a1, -16
s32i a0, a1, 0
- movi a0, __tls_get_addr
+ movi a0, JUMPTARGET(__tls_get_addr)
+ FDPIC_LOAD_JUMPTARGET(a0, a11, a0)
callx0 a0
l32i a0, a1, 0
addi a1, a1, 16
diff --git a/ldso/ldso/xtensa/elfinterp.c b/ldso/ldso/xtensa/elfinterp.c
index e38a02666..d97f23435 100644
--- a/ldso/ldso/xtensa/elfinterp.c
+++ b/ldso/ldso/xtensa/elfinterp.c
@@ -36,6 +36,13 @@
#include "tlsdeschtab.h"
#endif
+#ifdef __FDPIC__
+unsigned long
+_dl_linux_resolver (struct elf_resolve *tpnt, int reloc_entry)
+{
+ return 0;
+}
+#else
unsigned long
_dl_linux_resolver (struct elf_resolve *tpnt, int reloc_entry)
{
@@ -83,7 +90,7 @@ _dl_linux_resolver (struct elf_resolve *tpnt, int reloc_entry)
return (unsigned long) new_addr;
}
-
+#endif
static int
_dl_parse (struct elf_resolve *tpnt, struct r_scope_elem *scope,
@@ -145,8 +152,8 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope,
int reloc_type;
int symtab_index;
char *symname;
-#if defined USE_TLS && USE_TLS
- struct elf_resolve *tls_tpnt = NULL;
+#if defined USE_TLS && USE_TLS || defined (__FDPIC__)
+ struct elf_resolve *def_mod = NULL;
#endif
struct symbol_ref sym_ref;
ElfW(Addr) *reloc_addr;
@@ -155,7 +162,7 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope,
ElfW(Addr) old_val;
#endif
- reloc_addr = (ElfW(Addr) *) (tpnt->loadaddr + rpnt->r_offset);
+ reloc_addr = (ElfW(Addr) *) DL_RELOC_ADDR(tpnt->loadaddr, rpnt->r_offset);
reloc_type = ELF_R_TYPE (rpnt->r_info);
symtab_index = ELF_R_SYM (rpnt->r_info);
sym_ref.sym = &symtab[symtab_index];
@@ -164,9 +171,17 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope,
symname = strtab + sym_ref.sym->st_name;
if (symtab_index) {
- symbol_addr = (ElfW(Addr))
- _dl_find_hash (symname, scope, tpnt,
- elf_machine_type_class (reloc_type), &sym_ref);
+ if (ELF_ST_BIND (sym_ref.sym->st_info) == STB_LOCAL) {
+ symbol_addr = (ElfW(Addr))
+ DL_RELOC_ADDR(tpnt->loadaddr,
+ symtab[symtab_index].st_value);
+ sym_ref.tpnt = tpnt;
+ } else {
+ symbol_addr = (ElfW(Addr))
+ _dl_find_hash (symname, scope, tpnt,
+ elf_machine_type_class (reloc_type),
+ &sym_ref);
+ }
/*
* We want to allow undefined references to weak symbols - this might
@@ -182,13 +197,13 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope,
_dl_debug_lookup (symname, tpnt, &symtab[symtab_index],
&sym_ref, elf_machine_type_class(reloc_type));
}
-#if defined USE_TLS && USE_TLS
- tls_tpnt = sym_ref.tpnt;
+#if defined USE_TLS && USE_TLS || defined (__FDPIC__)
+ def_mod = sym_ref.tpnt;
#endif
} else {
symbol_addr =symtab[symtab_index].st_value;
-#if defined USE_TLS && USE_TLS
- tls_tpnt = tpnt;
+#if defined USE_TLS && USE_TLS || defined (__FDPIC__)
+ def_mod = tpnt;
#endif
}
@@ -202,6 +217,7 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope,
case R_XTENSA_GLOB_DAT:
case R_XTENSA_JMP_SLOT:
+ case R_XTENSA_SYM32:
*reloc_addr = symbol_addr + rpnt->r_addend;
break;
@@ -219,19 +235,63 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope,
break;
case R_XTENSA_RELATIVE:
- *reloc_addr += tpnt->loadaddr + rpnt->r_addend;
+ *reloc_addr += DL_RELOC_ADDR(tpnt->loadaddr, rpnt->r_addend);
break;
+#ifdef __FDPIC__
+ case R_XTENSA_FUNCDESC_VALUE:
+ {
+ struct funcdesc_value *dst = (struct funcdesc_value *) reloc_addr;
+
+ dst->entry_point = (void *) (symbol_addr + rpnt->r_addend);
+ dst->got_value = def_mod->loadaddr.got_value;
+ }
+ break;
+ case R_XTENSA_FUNCDESC:
+ if (symbol_addr)
+ *reloc_addr = (unsigned long)
+ _dl_funcdesc_for((void *) (symbol_addr + rpnt->r_addend),
+ sym_ref.tpnt->loadaddr.got_value);
+ else
+ /* Relocation against an undefined weak symbol:
+ set funcdesc to zero. */
+ *reloc_addr = 0;
+ break;
+ case R_XTENSA_TLS_TPOFF:
+ CHECK_STATIC_TLS((struct link_map *) def_mod);
+ *reloc_addr = symbol_addr + rpnt->r_addend + def_mod->l_tls_offset;
+ break;
+ case R_XTENSA_TLSDESC:
+ {
+ struct tlsdesc *td = (struct tlsdesc *) reloc_addr;
+#ifndef SHARED
+ CHECK_STATIC_TLS((struct link_map *) def_mod);
+#else
+ if (!TRY_STATIC_TLS ((struct link_map *) def_mod))
+ {
+ td->entry = _dl_tlsdesc_dynamic;
+ td->argument = _dl_make_tlsdesc_dynamic((struct link_map *) def_mod,
+ symbol_addr + rpnt->r_addend);
+ }
+ else
+#endif
+ {
+ td->entry = _dl_tlsdesc_return;
+ td->argument = (void *) (symbol_addr + rpnt->r_addend + def_mod->l_tls_offset);
+ }
+ }
+ break;
+#else
#if defined USE_TLS && USE_TLS
case R_XTENSA_TLS_TPOFF:
- CHECK_STATIC_TLS((struct link_map *) tls_tpnt);
- *reloc_addr = symbol_addr + tls_tpnt->l_tls_offset + rpnt->r_addend;
+ CHECK_STATIC_TLS((struct link_map *) def_mod);
+ *reloc_addr = symbol_addr + rpnt->r_addend + def_mod->l_tls_offset;
break;
case R_XTENSA_TLSDESC_FN:
#ifndef SHARED
- CHECK_STATIC_TLS((struct link_map *) tls_tpnt);
+ CHECK_STATIC_TLS((struct link_map *) def_mod);
#else
- if (!TRY_STATIC_TLS ((struct link_map *) tls_tpnt))
+ if (!TRY_STATIC_TLS ((struct link_map *) def_mod))
*reloc_addr = (ElfW(Addr)) _dl_tlsdesc_dynamic;
else
#endif
@@ -239,25 +299,25 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope,
break;
case R_XTENSA_TLSDESC_ARG:
#ifndef SHARED
- CHECK_STATIC_TLS((struct link_map *) tls_tpnt);
+ CHECK_STATIC_TLS((struct link_map *) def_mod);
#else
- if (!TRY_STATIC_TLS ((struct link_map *) tls_tpnt))
+ if (!TRY_STATIC_TLS ((struct link_map *) def_mod))
*reloc_addr = (ElfW(Addr))
- _dl_make_tlsdesc_dynamic((struct link_map *) tls_tpnt,
+ _dl_make_tlsdesc_dynamic((struct link_map *) def_mod,
symbol_addr + rpnt->r_addend);
else
#endif
*reloc_addr = symbol_addr + rpnt->r_addend +
- tls_tpnt->l_tls_offset;
+ def_mod->l_tls_offset;
break;
#endif
-
+#endif
default:
return -1; /* Calls _dl_exit(1). */
}
#if defined (__SUPPORT_LD_DEBUG__)
if (_dl_debug_reloc && _dl_debug_detail)
- _dl_dprintf (_dl_debug_file, "\tpatched: %x ==> %x @ %x\n",
+ _dl_dprintf (_dl_debug_file, "\tpatched: %x ==> %x @ %p\n",
old_val, *reloc_addr, reloc_addr);
#endif
@@ -275,7 +335,7 @@ _dl_do_lazy_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope,
ElfW(Addr) old_val;
#endif
- reloc_addr = (ElfW(Addr) *) (tpnt->loadaddr + rpnt->r_offset);
+ reloc_addr = (ElfW(Addr) *) DL_RELOC_ADDR(tpnt->loadaddr, rpnt->r_offset);
reloc_type = ELF_R_TYPE (rpnt->r_info);
#if defined (__SUPPORT_LD_DEBUG__)
@@ -286,7 +346,7 @@ _dl_do_lazy_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope,
case R_XTENSA_JMP_SLOT:
/* Perform a RELATIVE reloc on the GOT entry that transfers
to the stub function. */
- *reloc_addr += tpnt->loadaddr;
+ *reloc_addr = DL_RELOC_ADDR(tpnt->loadaddr, *reloc_addr);
break;
case R_XTENSA_NONE:
break;
@@ -296,7 +356,7 @@ _dl_do_lazy_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope,
#if defined (__SUPPORT_LD_DEBUG__)
if (_dl_debug_reloc && _dl_debug_detail)
- _dl_dprintf (_dl_debug_file, "\tpatched: %x ==> %x @ %x\n",
+ _dl_dprintf (_dl_debug_file, "\tpatched: %x ==> %x @ %p\n",
old_val, *reloc_addr, reloc_addr);
#endif
return 0;
@@ -320,3 +380,7 @@ _dl_parse_relocation_information (struct dyn_elf *rpnt,
return _dl_parse (rpnt->dyn, scope, rel_addr, rel_size,
_dl_do_reloc);
}
+
+#ifndef IS_IN_libdl
+# include "../../libc/sysdeps/linux/xtensa/crtreloc.c"
+#endif
diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c
index 37c4a876e..6e50cb087 100644
--- a/ldso/libdl/libdl.c
+++ b/ldso/libdl/libdl.c
@@ -972,11 +972,11 @@ static int do_dlclose(void *vhandle, int need_fini)
end = (end + ADDR_ALIGN) & PAGE_ALIGN;
start = start & ~ADDR_ALIGN;
if (end > start) {
- _dl_if_debug_print("unmapping: %s at %p with length: '%p' until %p\n", tpnt->libname, tpnt->mapaddr, end - start, tpnt->mapaddr + (end - start));
+ _dl_if_debug_print("unmapping: %s at %p with length: '%p' until %p\n", tpnt->libname, (void *)tpnt->mapaddr, (void *)(end - start), (void *)(tpnt->mapaddr + (end - start)));
DL_LIB_UNMAP (tpnt, end - start);
}
else {
- _dl_if_debug_print("NOT unmapping: %s at %p. start<end ('%p'<'%p')", tpnt->libname, tpnt->mapaddr, start, end);
+ _dl_if_debug_print("NOT unmapping: %s at %p. start<end ('%p'<'%p')", tpnt->libname, (void *)tpnt->mapaddr, (void *)start, (void *)end);
}
/* Free elements in RTLD_LOCAL scope list */
for (runp = tpnt->rtld_local; runp; runp = tmp) {
diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c
index d7a659a8c..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;
@@ -2699,7 +2699,7 @@ int gethostent_r(struct hostent *result_buf, char *buf, size_t buflen,
hostp = __open_etc_hosts();
if (hostp == NULL) {
*result = NULL;
- ret = TRY_AGAIN;
+ *h_errnop = ret = TRY_AGAIN;
goto DONE;
}
}
diff --git a/libc/misc/auxvt/getauxval.c b/libc/misc/auxvt/getauxval.c
index 2bdffaf2c..7610b7e5c 100755
--- a/libc/misc/auxvt/getauxval.c
+++ b/libc/misc/auxvt/getauxval.c
@@ -17,32 +17,28 @@
* <http://www.gnu.org/licenses/>.
*/
-#include "errno.h"
-#include "ldso.h"
-#include "sys/auxv.h"
+#include <errno.h>
+#include <ldso.h>
+#include <sys/auxv.h>
-
-/*
- *
- * aarch64 gcc 11 uses __getauxval() in init_have_lse_atomics()
- *
- */
unsigned long int __getauxval (unsigned long int __type)
{
- if ( __type >= AUX_MAX_AT_ID ){
+ // Requested value part of cached subset of auxiliary vector?
+ if (__type < AUX_MAX_AT_ID) {
+ if (_dl_auxvt[__type].a_type == __type)
+ return _dl_auxvt[__type].a_un.a_val;
+
__set_errno (ENOENT);
return 0;
}
- if ( _dl_auxvt[__type].a_type == __type){
- return _dl_auxvt[__type].a_un.a_val;
- }
+ // Otherwise we have to iterate the auxiliary vector.
+ for (ElfW(auxv_t) *entry = _dl_auxv_start; entry->a_type != AT_NULL; entry++)
+ if (entry->a_type == __type)
+ return entry->a_un.a_val;
__set_errno (ENOENT);
return 0;
}
-unsigned long int getauxval (unsigned long int __type){
- return __getauxval( __type );
-}
-
+weak_alias(__getauxval, getauxval)
diff --git a/libc/misc/elf/dl-support.c b/libc/misc/elf/dl-support.c
index 87cd1bb72..09cbefc18 100644
--- a/libc/misc/elf/dl-support.c
+++ b/libc/misc/elf/dl-support.c
@@ -12,6 +12,7 @@
*/
#include <link.h>
+#include <ldso.h>
#include <elf.h>
#if defined(USE_TLS) && USE_TLS
#include <assert.h>
@@ -31,17 +32,29 @@ ElfW(Phdr) *_dl_phdr;
size_t _dl_phnum;
size_t _dl_pagesize;
+ElfW(auxv_t) _dl_auxvt[AUX_MAX_AT_ID];
+ElfW(auxv_t) *_dl_auxv_start;
+
void internal_function _dl_aux_init (ElfW(auxv_t) *av);
void internal_function _dl_aux_init (ElfW(auxv_t) *av)
{
+ _dl_auxv_start = av;
+
+ memset(_dl_auxvt, 0x00, sizeof(_dl_auxvt));
+ for (; av->a_type != AT_NULL; av++)
+ {
+ if (av->a_type < AUX_MAX_AT_ID)
+ _dl_auxvt[av->a_type] = *av;
+ }
+
/* Get the program headers base address from the aux vect */
- _dl_phdr = (ElfW(Phdr) *) av[AT_PHDR].a_un.a_val;
+ _dl_phdr = (ElfW(Phdr) *) _dl_auxvt[AT_PHDR].a_un.a_val;
/* Get the number of program headers from the aux vect */
- _dl_phnum = (size_t) av[AT_PHNUM].a_un.a_val;
+ _dl_phnum = (size_t) _dl_auxvt[AT_PHNUM].a_un.a_val;
/* Get the pagesize from the aux vect */
- _dl_pagesize = (av[AT_PAGESZ].a_un.a_val) ? (size_t) av[AT_PAGESZ].a_un.a_val : PAGE_SIZE;
+ _dl_pagesize = (_dl_auxvt[AT_PAGESZ].a_un.a_val) ? (size_t) _dl_auxvt[AT_PAGESZ].a_un.a_val : PAGE_SIZE;
}
#if defined(USE_TLS) && USE_TLS
diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c
index 64a9c8214..60695b6ed 100644
--- a/libc/misc/internals/__uClibc_main.c
+++ b/libc/misc/internals/__uClibc_main.c
@@ -43,7 +43,7 @@
/* Are we in a secure process environment or are we dealing
* with setuid stuff? If we are dynamically linked, then we
* already have _dl_secure, otherwise we need to re-examine
- * auxvt[] below.
+ * _dl_auxvt[] below.
*/
int _pe_secure = 0;
libc_hidden_data_def(_pe_secure)
@@ -84,6 +84,8 @@ static void fdpic_init_array_jump(void *addr)
#ifndef SHARED
void *__libc_stack_end = NULL;
+#include "dl-auxvt.h"
+
# ifdef __UCLIBC_HAS_SSP__
# include <dl-osinfo.h>
static uintptr_t stack_chk_guard;
@@ -373,7 +375,6 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc,
{
#ifndef SHARED
unsigned long *aux_dat;
- ElfW(auxv_t) auxvt[AT_EGID + 1];
#endif
#ifdef __UCLIBC_HAS_THREADS_NATIVE__
@@ -399,23 +400,14 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc,
#ifndef SHARED
/* Pull stuff from the ELF header when possible */
- memset(auxvt, 0x00, sizeof(auxvt));
aux_dat = (unsigned long*)__environ;
while (*aux_dat) {
aux_dat++;
}
aux_dat++;
- while (*aux_dat) {
- ElfW(auxv_t) *auxv_entry = (ElfW(auxv_t) *) aux_dat;
- if (auxv_entry->a_type <= AT_EGID) {
- memcpy(&(auxvt[auxv_entry->a_type]), auxv_entry, sizeof(ElfW(auxv_t)));
- }
- aux_dat += 2;
- }
/* Get the program headers (_dl_phdr) from the aux vector
It will be used into __libc_setup_tls. */
-
- _dl_aux_init (auxvt);
+ _dl_aux_init ((ElfW(auxv_t) *)aux_dat);
#endif
/* We need to initialize uClibc. If we are dynamically linked this
@@ -431,10 +423,10 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc,
#ifndef SHARED
/* Prevent starting SUID binaries where the stdin. stdout, and
* stderr file descriptors are not already opened. */
- if ((auxvt[AT_UID].a_un.a_val == (size_t)-1 && __check_suid()) ||
- (auxvt[AT_UID].a_un.a_val != (size_t)-1 &&
- (auxvt[AT_UID].a_un.a_val != auxvt[AT_EUID].a_un.a_val ||
- auxvt[AT_GID].a_un.a_val != auxvt[AT_EGID].a_un.a_val)))
+ if ((_dl_auxvt[AT_UID].a_un.a_val == (size_t)-1 && __check_suid()) ||
+ (_dl_auxvt[AT_UID].a_un.a_val != (size_t)-1 &&
+ (_dl_auxvt[AT_UID].a_un.a_val != _dl_auxvt[AT_EUID].a_un.a_val ||
+ _dl_auxvt[AT_GID].a_un.a_val != _dl_auxvt[AT_EGID].a_un.a_val)))
#else
if (_dl_secure)
#endif
diff --git a/libc/misc/internals/reloc_static_pie.c b/libc/misc/internals/reloc_static_pie.c
index 81af7d666..3bbdef18e 100644
--- a/libc/misc/internals/reloc_static_pie.c
+++ b/libc/misc/internals/reloc_static_pie.c
@@ -21,7 +21,7 @@
#include <dl-elf.h>
#include <ldso.h>
-#if defined(__mips__) || defined(__xtensa__)
+#if defined(__m68k__) || defined(__mips__) || defined(__xtensa__)
#include <dl-startup.h>
#endif
@@ -107,6 +107,8 @@ reloc_static_pie(ElfW(Addr) load_addr)
PERFORM_BOOTSTRAP_RELOC(rpnt, reloc_addr, symbol_addr, load_addr, sym);
}
}
+#else
+ (void)rel_size;
#endif
}
_dl_load_base = load_addr;
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/misc/wchar/wchar.c b/libc/misc/wchar/wchar.c
index 2714d47d7..782b67f93 100644
--- a/libc/misc/wchar/wchar.c
+++ b/libc/misc/wchar/wchar.c
@@ -1298,7 +1298,7 @@ iconv_t weak_function iconv_open(const char *tocode, const char *fromcode)
int weak_function iconv_close(iconv_t cd)
{
- free(cd);
+ free((void *) cd);
return 0;
}
diff --git a/libc/stdio/_fpmaxtostr.c b/libc/stdio/_fpmaxtostr.c
index b06b25aa0..1f268fdaa 100644
--- a/libc/stdio/_fpmaxtostr.c
+++ b/libc/stdio/_fpmaxtostr.c
@@ -318,8 +318,8 @@ ssize_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info,
#else /* __UCLIBC_HAS_HEXADECIMAL_FLOATS__ */
-#define lower_bnd 1e8
-#define upper_bnd 1e9
+#define lower_bnd (__fpmax_t)1e8
+#define upper_bnd (__fpmax_t)1e9
#define power_table exp10_table
#define dpb DIGITS_PER_BLOCK
#define base 10
diff --git a/libc/stdio/_scanf.c b/libc/stdio/_scanf.c
index 3f3000d6f..cb72d14ac 100644
--- a/libc/stdio/_scanf.c
+++ b/libc/stdio/_scanf.c
@@ -1715,7 +1715,7 @@ int attribute_hidden __psfs_do_numeric(psfs_t *psfs, struct scan_cookie *sc)
#define MAX_DIGITS 65 /* Allow one leading 0. */
unsigned char buf[MAX_DIGITS+2+ 100];
unsigned char usflag, base;
- unsigned char nonzero = 0;
+ unsigned char nonzero __attribute__((unused)) = 0;
unsigned char seendigit = 0;
#ifndef __UCLIBC_HAS_FLOATS__
diff --git a/libc/stdlib/_strtod.c b/libc/stdlib/_strtod.c
index c4c79e511..483551e64 100644
--- a/libc/stdlib/_strtod.c
+++ b/libc/stdlib/_strtod.c
@@ -256,7 +256,7 @@ __fpmax_t attribute_hidden __XL_NPP(__strtofpmax)(const Wchar *str, Wchar **endp
}
#endif
- number = 0.;
+ number = (__fpmax_t)0;
#ifdef _STRTOD_NEED_NUM_DIGITS
num_digits = -1;
#endif
@@ -339,7 +339,7 @@ __fpmax_t attribute_hidden __XL_NPP(__strtofpmax)(const Wchar *str, Wchar **endp
while ((pos[j] | 0x20) == nan_inf_str[i+1+j]) {
++j;
if (!nan_inf_str[i+1+j]) {
- number = i / 0.;
+ number = i / (__fpmax_t)0.;
if (negative) { /* Correct for sign. */
number = -number;
}
@@ -414,7 +414,7 @@ __fpmax_t attribute_hidden __XL_NPP(__strtofpmax)(const Wchar *str, Wchar **endp
}
#ifdef _STRTOD_ZERO_CHECK
- if (number == 0.) {
+ if (number == (__fpmax_t)0.) {
goto DONE;
}
#endif
@@ -515,7 +515,7 @@ float __XL_NPP(strtof)(const Wchar *str, Wchar **endptr __LOCALE_PARAM )
x = __XL_NPP(__strtofpmax)(str, endptr, 0 __LOCALE_ARG );
y = (float) x;
- __fp_range_check(y, x);
+ __fp_range_check((__fpmax_t)y, x);
return y;
#endif
@@ -549,7 +549,7 @@ double __XL_NPP(strtod)(const Wchar *__restrict str,
x = __XL_NPP(__strtofpmax)(str, endptr, 0 __LOCALE_ARG );
y = (double) x;
- __fp_range_check(y, x);
+ __fp_range_check((__fpmax_t)y, x);
return y;
#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/stdlib/malloc/memalign.c b/libc/stdlib/malloc/memalign.c
index 665f20cfb..54f6dbc6c 100644
--- a/libc/stdlib/malloc/memalign.c
+++ b/libc/stdlib/malloc/memalign.c
@@ -11,6 +11,7 @@
* Written by Miles Bader <miles@gnu.org>
*/
+#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
@@ -38,6 +39,11 @@ memalign (size_t alignment, size_t size)
unsigned long tot_addr, tot_end_addr, addr, end_addr;
struct heap_free_area **heap = &__malloc_heap;
+ if (unlikely(size > PTRDIFF_MAX)) {
+ __set_errno(ENOMEM);
+ return NULL;
+ }
+
/* Make SIZE something we like. */
size = HEAP_ADJUST_SIZE (size);
diff --git a/libc/stdlib/stdlib.c b/libc/stdlib/stdlib.c
index f5936630c..c45dd53a5 100644
--- a/libc/stdlib/stdlib.c
+++ b/libc/stdlib/stdlib.c
@@ -822,6 +822,7 @@ libc_hidden_def(_stdlib_mb_cur_max)
#endif
+#if defined(L_mblen) || defined(L_mbtowc) || defined(L_wctomb)
#ifdef __UCLIBC_HAS_LOCALE__
/*
* The following function return 1 if the encoding is stateful, 0 if stateless.
@@ -844,6 +845,7 @@ static __always_inline int is_stateful(unsigned char encoding)
#else
#define is_stateful(encoding) 0
#endif
+#endif
/**********************************************************************/
#ifdef L_mblen
diff --git a/libc/string/generic/strnlen.c b/libc/string/generic/strnlen.c
index 4d4cde84f..82d4122ec 100644
--- a/libc/string/generic/strnlen.c
+++ b/libc/string/generic/strnlen.c
@@ -29,15 +29,17 @@
'\0' terminator is found in that many characters, return MAXLEN. */
size_t strnlen (const char *str, size_t maxlen)
{
- const char *char_ptr, *end_ptr = str + maxlen;
+ const char *char_ptr, *end_ptr;
const unsigned long int *longword_ptr;
unsigned long int longword, himagic, lomagic;
if (maxlen == 0)
return 0;
- if (__builtin_expect (end_ptr < str, 0))
+ if (__builtin_expect ((uintptr_t)str + maxlen < (uintptr_t)str, 0))
end_ptr = (const char *) ~0UL;
+ else
+ end_ptr = str + maxlen;
/* Handle the first few characters by reading one character at a time.
Do this until CHAR_PTR is aligned on a longword boundary. */
diff --git a/libc/string/x86_64/strcat.S b/libc/string/x86_64/strcat.S
index 55e09e5f1..209e19062 100644
--- a/libc/string/x86_64/strcat.S
+++ b/libc/string/x86_64/strcat.S
@@ -106,7 +106,7 @@ ENTRY (BP_SYM (strcat))
/* Align, it is a jump target. */
/* Next 3 insns are 8 bytes total, make sure we decode them in one go */
- .p2align 3,,8
+ .p2align 3,,7
3:
subq $8,%rax /* correct pointer increment. */
diff --git a/libc/string/x86_64/strcspn.S b/libc/string/x86_64/strcspn.S
index 7a06c8867..5ef565db7 100644
--- a/libc/string/x86_64/strcspn.S
+++ b/libc/string/x86_64/strcspn.S
@@ -94,7 +94,7 @@ L(1): leaq -4(%rdx), %rax /* prepare loop */
/* but it will also align entire function to 16 bytes, */
/* potentially creating largish padding at link time. */
/* We are aligning to 8 bytes instead: */
- .p2align 3,,8
+ .p2align 3,,7
L(3): addq $4, %rax /* adjust pointer for full loop round */
diff --git a/libc/string/x86_64/strlen.S b/libc/string/x86_64/strlen.S
index 9e84326c2..2fe2f58b2 100644
--- a/libc/string/x86_64/strlen.S
+++ b/libc/string/x86_64/strlen.S
@@ -102,7 +102,7 @@ ENTRY (strlen)
/* Align, it is a jump target. */
/* Next 3 insns are 8 bytes total, make sure we decode them in one go */
- .p2align 3,,8
+ .p2align 3,,7
3:
subq $8,%rax /* correct pointer increment. */
diff --git a/libc/string/x86_64/strspn.S b/libc/string/x86_64/strspn.S
index 366377649..8dc42656b 100644
--- a/libc/string/x86_64/strspn.S
+++ b/libc/string/x86_64/strspn.S
@@ -89,7 +89,7 @@ L(1): leaq -4(%rdx), %rax /* prepare loop */
/* but it will also align entire function to 16 bytes, */
/* potentially creating largish padding at link time. */
/* We are aligning to 8 bytes instead: */
- .p2align 3,,8
+ .p2align 3,,7
L(3):
addq $4, %rax /* adjust pointer for full loop round */
diff --git a/libc/sysdeps/linux/aarch64/bits/fcntl.h b/libc/sysdeps/linux/aarch64/bits/fcntl.h
index dbe929351..024344eec 100644
--- a/libc/sysdeps/linux/aarch64/bits/fcntl.h
+++ b/libc/sysdeps/linux/aarch64/bits/fcntl.h
@@ -289,3 +289,6 @@ extern int fallocate64 (int __fd, int __mode, __off64_t __offset,
#endif /* use GNU */
__END_DECLS
+
+/* Include generic Linux declarations. */
+#include <bits/fcntl-linux.h>
diff --git a/libc/sysdeps/linux/aarch64/bits/fenv.h b/libc/sysdeps/linux/aarch64/bits/fenv.h
new file mode 100644
index 000000000..4febd2177
--- /dev/null
+++ b/libc/sysdeps/linux/aarch64/bits/fenv.h
@@ -0,0 +1,78 @@
+/* Copyright (C) 2004-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 exceptions in the FPSR status word. */
+enum
+ {
+ FE_INVALID =
+#define FE_INVALID 1
+ FE_INVALID,
+ FE_DIVBYZERO =
+#define FE_DIVBYZERO 2
+ FE_DIVBYZERO,
+ FE_OVERFLOW =
+#define FE_OVERFLOW 4
+ FE_OVERFLOW,
+ FE_UNDERFLOW =
+#define FE_UNDERFLOW 8
+ FE_UNDERFLOW,
+ FE_INEXACT =
+#define FE_INEXACT 16
+ FE_INEXACT,
+ };
+
+/* Amount to shift by to convert an exception bit in FPSR to a an
+ exception bit mask in FPCR. */
+#define FE_EXCEPT_SHIFT 8
+
+/* All supported exceptions. */
+#define FE_ALL_EXCEPT \
+ (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT)
+
+/* Define bits representing rounding modes in the FPCR Rmode field. */
+#define FE_TONEAREST 0x000000
+#define FE_UPWARD 0x400000
+#define FE_DOWNWARD 0x800000
+#define FE_TOWARDZERO 0xc00000
+
+/* Type representing exception flags. */
+typedef unsigned int fexcept_t;
+
+/* Type representing floating-point environment. */
+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 *) -1l)
+
+#ifdef __USE_GNU
+/* Floating-point environment where none of the exceptions are masked. */
+# 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/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/aarch64/crt1.S b/libc/sysdeps/linux/aarch64/crt1.S
index e9f946894..965d3265d 100644
--- a/libc/sysdeps/linux/aarch64/crt1.S
+++ b/libc/sysdeps/linux/aarch64/crt1.S
@@ -52,8 +52,8 @@ _start:
/* Save off the atexit pointer */
mov x19, x0
- /* Calculate load address... idk how this works, but it does */
- adrp x0, _start
+ /* "Calculate" load address. The link address of __ehdr_start is 0. */
+ adrp x0, __ehdr_start
/* Do relocations */
bl reloc_static_pie
diff --git a/libc/sysdeps/linux/aarch64/fpu_control.h b/libc/sysdeps/linux/aarch64/fpu_control.h
new file mode 100644
index 000000000..c3e7f6629
--- /dev/null
+++ b/libc/sysdeps/linux/aarch64/fpu_control.h
@@ -0,0 +1,102 @@
+/* Copyright (C) 1996-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 _AARCH64_FPU_CONTROL_H
+#define _AARCH64_FPU_CONTROL_H
+
+#include <features.h>
+
+/* Macros for accessing the FPCR and FPSR. */
+
+#if __GNUC_PREREQ (6,0)
+# define _FPU_GETCW(fpcr) (fpcr = __builtin_aarch64_get_fpcr ())
+# define _FPU_SETCW(fpcr) __builtin_aarch64_set_fpcr (fpcr)
+# define _FPU_GETFPSR(fpsr) (fpsr = __builtin_aarch64_get_fpsr ())
+# define _FPU_SETFPSR(fpsr) __builtin_aarch64_set_fpsr (fpsr)
+#else
+# define _FPU_GETCW(fpcr) \
+ ({ \
+ __uint64_t __fpcr; \
+ __asm__ __volatile__ ("mrs %0, fpcr" : "=r" (__fpcr)); \
+ fpcr = __fpcr; \
+ })
+
+# define _FPU_SETCW(fpcr) \
+ ({ \
+ __uint64_t __fpcr = fpcr; \
+ __asm__ __volatile__ ("msr fpcr, %0" : : "r" (__fpcr)); \
+ })
+
+# define _FPU_GETFPSR(fpsr) \
+ ({ \
+ __uint64_t __fpsr; \
+ __asm__ __volatile__ ("mrs %0, fpsr" : "=r" (__fpsr)); \
+ fpsr = __fpsr; \
+ })
+
+# define _FPU_SETFPSR(fpsr) \
+ ({ \
+ __uint64_t __fpsr = fpsr; \
+ __asm__ __volatile__ ("msr fpsr, %0" : : "r" (__fpsr)); \
+ })
+#endif
+
+/* Reserved bits should be preserved when modifying register
+ contents. These two masks indicate which bits in each of FPCR and
+ FPSR should not be changed. */
+
+#define _FPU_RESERVED 0xfe0fe0f8
+#define _FPU_FPSR_RESERVED 0x0fffffe0
+
+#define _FPU_DEFAULT 0x00000000
+#define _FPU_FPSR_DEFAULT 0x00000000
+
+/* Layout of FPCR and FPSR:
+
+ | | | | | | | |
+ 0 0 0 0 1 1 1 0 0 0 0 0 1 0 0 0 1 1 1 0 0 0 0 0 1 1 1 0 0 0 0 0
+ s s s s s s s s s s s
+ c c c c c c c c c c c c
+ N Z C V Q A D F R R S S S L L L I U U I U O D I I U U I U O D I
+ C H N Z M M T T B E E E D N N X F F Z O D N N X F F Z O
+ P O O R R Z N N N E K K E E E E E C K K C C C C C
+ D D I I P
+ E E D D
+ E E
+ */
+
+#define _FPU_FPCR_RM_MASK 0xc00000
+
+#define _FPU_FPCR_MASK_IXE 0x1000
+#define _FPU_FPCR_MASK_UFE 0x0800
+#define _FPU_FPCR_MASK_OFE 0x0400
+#define _FPU_FPCR_MASK_DZE 0x0200
+#define _FPU_FPCR_MASK_IOE 0x0100
+
+#define _FPU_FPCR_IEEE \
+ (_FPU_DEFAULT | _FPU_FPCR_MASK_IXE \
+ | _FPU_FPCR_MASK_UFE | _FPU_FPCR_MASK_OFE \
+ | _FPU_FPCR_MASK_DZE | _FPU_FPCR_MASK_IOE)
+
+#define _FPU_FPSR_IEEE 0
+
+typedef unsigned int fpu_control_t;
+typedef unsigned int fpu_fpsr_t;
+
+/* Default control word set at startup. */
+extern fpu_control_t __fpu_control;
+
+#endif
diff --git a/libc/sysdeps/linux/aarch64/sys/ucontext.h b/libc/sysdeps/linux/aarch64/sys/ucontext.h
index 5f75cbbf3..1a27f918b 100644
--- a/libc/sysdeps/linux/aarch64/sys/ucontext.h
+++ b/libc/sysdeps/linux/aarch64/sys/ucontext.h
@@ -45,10 +45,10 @@ typedef elf_fpregset_t fpregset_t;
typedef struct sigcontext mcontext_t;
/* Userlevel context. */
-typedef struct ucontext_t
+typedef struct ucontext
{
unsigned long uc_flags;
- struct ucontext_t *uc_link;
+ struct ucontext *uc_link;
stack_t uc_stack;
__sigset_t uc_sigmask;
unsigned char __reserved[128];
diff --git a/libc/sysdeps/linux/alpha/bits/fcntl.h b/libc/sysdeps/linux/alpha/bits/fcntl.h
index 11e68214e..7d06c76b7 100644
--- a/libc/sysdeps/linux/alpha/bits/fcntl.h
+++ b/libc/sysdeps/linux/alpha/bits/fcntl.h
@@ -236,3 +236,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len,
#endif
__END_DECLS
+/* Include generic Linux declarations. */
+#include <bits/fcntl-linux.h>
diff --git a/libc/sysdeps/linux/alpha/bits/stat.h b/libc/sysdeps/linux/alpha/bits/stat.h
index 88bc6617d..f2dca250d 100644
--- a/libc/sysdeps/linux/alpha/bits/stat.h
+++ b/libc/sysdeps/linux/alpha/bits/stat.h
@@ -40,7 +40,7 @@
Use neat tidy anonymous unions and structures when possible. */
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
# if __GNUC_PREREQ(3,3)
# define __ST_TIME(X) \
__extension__ union { \
diff --git a/libc/sysdeps/linux/arc/bits/fcntl.h b/libc/sysdeps/linux/arc/bits/fcntl.h
index beb32e41e..b02849691 100755
--- a/libc/sysdeps/linux/arc/bits/fcntl.h
+++ b/libc/sysdeps/linux/arc/bits/fcntl.h
@@ -230,3 +230,6 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len,
#endif
__END_DECLS
+
+/* Include generic Linux declarations. */
+#include <bits/fcntl-linux.h>
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/__longjmp.S b/libc/sysdeps/linux/arm/__longjmp.S
index 58ae8ab58..a5ffe84e9 100644
--- a/libc/sysdeps/linux/arm/__longjmp.S
+++ b/libc/sysdeps/linux/arm/__longjmp.S
@@ -64,6 +64,13 @@ __longjmp:
#if defined __UCLIBC_HAS_FLOATS__ && ! defined __UCLIBC_HAS_SOFT_FLOAT__
#ifdef __VFP_FP__
+# if __ARM_ARCH >= 8
+ /* Restore the VFP registers. */
+ fldmiax ip!, {d8-d15}
+ /* Restore the floating-point status register. */
+ ldr r1, [ip], #4
+ fmxr fpscr, r1
+# else
/* Restore the VFP registers. */
/* Following instruction is fldmiax ip!, {d8-d15}. */
ldc p11, cr8, [r12], #68
@@ -71,6 +78,7 @@ __longjmp:
ldr r1, [ip], #4
/* Following instruction is fmxr fpscr, r1. */
mcr p10, 7, r1, cr1, cr0, 0
+# endif
# elif defined __MAVERICK__
cfldrd mvd4, [ip], #8 ; nop
cfldrd mvd5, [ip], #8 ; nop
diff --git a/libc/sysdeps/linux/arm/bits/fcntl.h b/libc/sysdeps/linux/arm/bits/fcntl.h
index 823660648..52dee4287 100644
--- a/libc/sysdeps/linux/arm/bits/fcntl.h
+++ b/libc/sysdeps/linux/arm/bits/fcntl.h
@@ -244,3 +244,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len,
#endif
__END_DECLS
+/* Include generic Linux declarations. */
+#include <bits/fcntl-linux.h>
diff --git a/libc/sysdeps/linux/arm/bits/fenv.h b/libc/sysdeps/linux/arm/bits/fenv.h
index 106bf36c2..ab60b9e70 100644
--- a/libc/sysdeps/linux/arm/bits/fenv.h
+++ b/libc/sysdeps/linux/arm/bits/fenv.h
@@ -1,5 +1,4 @@
-/* Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
+/* Copyright (C) 2004-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,87 +11,77 @@
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/>. */
+ 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
-#ifdef __MAVERICK__
-
/* Define bits representing exceptions in the FPU status word. */
enum
{
- FE_INVALID = 1,
-#define FE_INVALID FE_INVALID
- FE_OVERFLOW = 4,
-#define FE_OVERFLOW FE_OVERFLOW
- FE_UNDERFLOW = 8,
-#define FE_UNDERFLOW FE_UNDERFLOW
- FE_INEXACT = 16,
-#define FE_INEXACT FE_INEXACT
+ FE_INVALID =
+#define FE_INVALID 1
+ FE_INVALID,
+ FE_DIVBYZERO =
+#define FE_DIVBYZERO 2
+ FE_DIVBYZERO,
+ FE_OVERFLOW =
+#define FE_OVERFLOW 4
+ FE_OVERFLOW,
+ FE_UNDERFLOW =
+#define FE_UNDERFLOW 8
+ FE_UNDERFLOW,
+ FE_INEXACT =
+#define FE_INEXACT 16
+ FE_INEXACT,
};
/* Amount to shift by to convert an exception to a mask bit. */
-#define FE_EXCEPT_SHIFT 5
+#define FE_EXCEPT_SHIFT 8
/* All supported exceptions. */
-#define FE_ALL_EXCEPT \
- (FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT)
-
-/* IEEE rounding modes. */
-enum
- {
- FE_TONEAREST = 0,
-#define FE_TONEAREST FE_TONEAREST
- FE_TOWARDZERO = 0x400,
-#define FE_TOWARDZERO FE_TOWARDZERO
- FE_DOWNWARD = 0x800,
-#define FE_DOWNWARD FE_DOWNWARD
- FE_UPWARD = 0xc00,
-#define FE_UPWARD FE_UPWARD
- };
-
-#define FE_ROUND_MASK (FE_UPWARD)
-
-#else /* !__MAVERICK__ */
+#define FE_ALL_EXCEPT \
+ (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT)
-/* Define bits representing exceptions in the FPU status word. */
+/* VFP supports all of the four defined rounding modes. */
enum
{
- FE_INVALID = 1,
-#define FE_INVALID FE_INVALID
- FE_DIVBYZERO = 2,
-#define FE_DIVBYZERO FE_DIVBYZERO
- FE_OVERFLOW = 4,
-#define FE_OVERFLOW FE_OVERFLOW
- FE_UNDERFLOW = 8,
-#define FE_UNDERFLOW FE_UNDERFLOW
- };
-
-/* Amount to shift by to convert an exception to a mask bit. */
-#define FE_EXCEPT_SHIFT 16
-
-/* All supported exceptions. */
-#define FE_ALL_EXCEPT \
- (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW)
-
-/* The ARM FPU basically only supports round-to-nearest. Other rounding
- modes exist, but you have to encode them in the actual instruction. */
+ FE_TONEAREST =
#define FE_TONEAREST 0
-
-#endif /* __MAVERICK__ */
+ FE_TONEAREST,
+ FE_UPWARD =
+#define FE_UPWARD 0x400000
+ FE_UPWARD,
+ FE_DOWNWARD =
+#define FE_DOWNWARD 0x800000
+ FE_DOWNWARD,
+ FE_TOWARDZERO =
+#define FE_TOWARDZERO 0xc00000
+ FE_TOWARDZERO
+ };
/* Type representing exception flags. */
-typedef unsigned long int fexcept_t;
+typedef unsigned int fexcept_t;
/* Type representing floating-point environment. */
typedef struct
{
- unsigned long int __cw;
+ unsigned int __cw;
}
fenv_t;
/* If the default argument is used we use this value. */
-#define FE_DFL_ENV ((fenv_t *) -1l)
+#define FE_DFL_ENV ((const fenv_t *) -1l)
+
+#ifdef __USE_GNU
+/* Floating-point environment where none of the exceptions are masked. */
+# 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/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/arm/crt1.S b/libc/sysdeps/linux/arm/crt1.S
index 799f11080..040ddfd27 100644
--- a/libc/sysdeps/linux/arm/crt1.S
+++ b/libc/sysdeps/linux/arm/crt1.S
@@ -248,13 +248,9 @@ _start:
#if defined(__ARCH_USE_MMU__) || defined(__UCLIBC_FORMAT_ELF__)
#ifdef L_rcrt1
/* We don't need to save a1 since no dynamic linker should have run */
- ldr a1, .L_GOT /* Get value at .L_GOT + 0 (offset to GOT)*/
- adr a2, .L_GOT /* Get address of .L_GOT */
- ldr a3, .L_GOT+16 /* Get value of _start(GOT) stored in .L_GOT */
- adr a4, _start /* Get address of _start after relocation (changes to pc - ~30 or so) */
- add a1, a1, a2 /* Calculate where the GOT is */
- ldr a2, [a1, a3] /* GOT + _start(GOT) = offset of _start from begin of file */
- sub a1, a4, a2 /* Current addr of _start - offset from beginning of file = load addr */
+ adr a1, .L__ehdr_start_off /* Get address of .L__ehdr_start_off */
+ ldr a2, .L__ehdr_start_off /* Offset from .L__ehdr_start_off to __ehdr_start */
+ add a1, a1, a2 /* Address of __ehdr_start = load addr */
bl reloc_static_pie
mov a1, #0 /* Clean up a1 so that a random address won't get called at the end of program */
@@ -325,9 +321,10 @@ _start:
.word _fini(GOT)
.word _init(GOT)
.word main(GOT)
-#ifdef L_rcrt1
- .word _start(GOT)
#endif
+#ifdef L_rcrt1
+.L__ehdr_start_off:
+ .word __ehdr_start - .L__ehdr_start_off
#endif
#endif
diff --git a/libc/sysdeps/linux/arm/fpu_control.h b/libc/sysdeps/linux/arm/fpu_control.h
index 1b9b09df6..05ac6a03c 100644
--- a/libc/sysdeps/linux/arm/fpu_control.h
+++ b/libc/sysdeps/linux/arm/fpu_control.h
@@ -1,6 +1,5 @@
-/* FPU control word definitions. ARM version.
- Copyright (C) 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
+/* FPU control word definitions. ARM VFP version.
+ Copyright (C) 2004-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,13 +12,22 @@
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/>. */
+ License along with the GNU C Library. If not, see
+ <https://www.gnu.org/licenses/>. */
#ifndef _FPU_CONTROL_H
#define _FPU_CONTROL_H
-#ifdef __VFP_FP__
+#if !(defined(_LIBC) && !defined(_LIBC_TEST)) && defined(__SOFTFP__)
+
+#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
/* masking of interrupts */
#define _FPU_MASK_IM 0x00000100 /* invalid operation */
@@ -28,175 +36,39 @@
#define _FPU_MASK_UM 0x00000800 /* underflow */
#define _FPU_MASK_PM 0x00001000 /* inexact */
+#define _FPU_MASK_NZCV 0xf0000000 /* NZCV flags */
+#define _FPU_MASK_RM 0x00c00000 /* rounding mode */
+#define _FPU_MASK_EXCEPT 0x00001f1f /* all exception flags */
+
/* Some bits in the FPSCR are not yet defined. They must be preserved when
modifying the contents. */
-#define _FPU_RESERVED 0x0e08e0e0
+#define _FPU_RESERVED 0x00086060
#define _FPU_DEFAULT 0x00000000
-/* Default + exceptions enabled. */
+
+/* Default + exceptions enabled. */
#define _FPU_IEEE (_FPU_DEFAULT | 0x00001f00)
/* Type of the control word. */
typedef unsigned int fpu_control_t;
/* Macros for accessing the hardware control word. */
+#ifdef __SOFTFP__
/* This is fmrx %0, fpscr. */
-#define _FPU_GETCW(cw) \
+# define _FPU_GETCW(cw) \
__asm__ __volatile__ ("mrc p10, 7, %0, cr1, cr0, 0" : "=r" (cw))
/* This is fmxr fpscr, %0. */
-#define _FPU_SETCW(cw) \
+# define _FPU_SETCW(cw) \
__asm__ __volatile__ ("mcr p10, 7, %0, cr1, cr0, 0" : : "r" (cw))
+#else
+# define _FPU_GETCW(cw) \
+ __asm__ __volatile__ ("vmrs %0, fpscr" : "=r" (cw))
+# define _FPU_SETCW(cw) \
+ __asm__ __volatile__ ("vmsr fpscr, %0" : : "r" (cw))
+#endif
-#elif defined __MAVERICK__
-
-/* DSPSC register: (from EP9312 User's Guide)
- *
- * bits 31..29 - DAID
- * bits 28..26 - HVID
- * bits 25..24 - RSVD
- * bit 23 - ISAT
- * bit 22 - UI
- * bit 21 - INT
- * bit 20 - AEXC
- * bits 19..18 - SAT
- * bits 17..16 - FCC
- * bit 15 - V
- * bit 14 - FWDEN
- * bit 13 - Invalid
- * bit 12 - Denorm
- * bits 11..10 - RM
- * bits 9..5 - IXE, UFE, OFE, RSVD, IOE
- * bits 4..0 - IX, UF, OF, RSVD, IO
- */
-
-/* masking of interrupts */
-#define _FPU_MASK_IM (1 << 5) /* invalid operation */
-#define _FPU_MASK_ZM 0 /* divide by zero */
-#define _FPU_MASK_OM (1 << 7) /* overflow */
-#define _FPU_MASK_UM (1 << 8) /* underflow */
-#define _FPU_MASK_PM (1 << 9) /* inexact */
-#define _FPU_MASK_DM 0 /* denormalized operation */
-
-#define _FPU_RESERVED 0xfffff000 /* These bits are reserved. */
-
-#define _FPU_DEFAULT 0x00b00000 /* Default value. */
-#define _FPU_IEEE 0x00b003a0 /* Default + exceptions enabled. */
-
-/* Type of the control word. */
-typedef unsigned int fpu_control_t;
-
-/* Macros for accessing the hardware control word. */
-#define _FPU_GETCW(cw) ({ \
- register int __t1, __t2; \
- \
- __asm__ __volatile__ ( \
- "cfmvr64l %1, mvdx0\n\t" \
- "cfmvr64h %2, mvdx0\n\t" \
- "cfmv32sc mvdx0, dspsc\n\t" \
- "cfmvr64l %0, mvdx0\n\t" \
- "cfmv64lr mvdx0, %1\n\t" \
- "cfmv64hr mvdx0, %2" \
- : "=r" (cw), "=r" (__t1), "=r" (__t2) \
- ); \
-})
-
-#define _FPU_SETCW(cw) ({ \
- register int __t0, __t1, __t2; \
- \
- __asm__ __volatile__ ( \
- "cfmvr64l %1, mvdx0\n\t" \
- "cfmvr64h %2, mvdx0\n\t" \
- "cfmv64lr mvdx0, %0\n\t" \
- "cfmvsc32 dspsc, mvdx0\n\t" \
- "cfmv64lr mvdx0, %1\n\t" \
- "cfmv64hr mvdx0, %2" \
- : "=r" (__t0), "=r" (__t1), "=r" (__t2) \
- : "0" (cw) \
- ); \
-})
-
-#else /* !__MAVERICK__ */
-
-/* We have a slight terminology confusion here. On the ARM, the register
- * we're interested in is actually the FPU status word - the FPU control
- * word is something different (which is implementation-defined and only
- * accessible from supervisor mode.)
- *
- * The FPSR looks like this:
- *
- * 31-24 23-16 15-8 7-0
- * | system ID | trap enable | system control | exception flags |
- *
- * We ignore the system ID bits; for interest's sake they are:
- *
- * 0000 "old" FPE
- * 1000 FPPC hardware
- * 0001 FPE 400
- * 1001 FPA hardware
- *
- * The trap enable and exception flags are both structured like this:
- *
- * 7 - 5 4 3 2 1 0
- * | reserved | INX | UFL | OFL | DVZ | IVO |
- *
- * where a `1' bit in the enable byte means that the trap can occur, and
- * a `1' bit in the flags byte means the exception has occurred.
- *
- * The exceptions are:
- *
- * IVO - invalid operation
- * DVZ - divide by zero
- * OFL - overflow
- * UFL - underflow
- * INX - inexact (do not use; implementations differ)
- *
- * The system control byte looks like this:
- *
- * 7-5 4 3 2 1 0
- * | reserved | AC | EP | SO | NE | ND |
- *
- * where the bits mean
- *
- * ND - no denormalised numbers (force them all to zero)
- * NE - enable NaN exceptions
- * SO - synchronous operation
- * EP - use expanded packed-decimal format
- * AC - use alternate definition for C flag on compare operations
- */
-
-/* masking of interrupts */
-#define _FPU_MASK_IM 0x00010000 /* invalid operation */
-#define _FPU_MASK_ZM 0x00020000 /* divide by zero */
-#define _FPU_MASK_OM 0x00040000 /* overflow */
-#define _FPU_MASK_UM 0x00080000 /* underflow */
-#define _FPU_MASK_PM 0x00100000 /* inexact */
-#define _FPU_MASK_DM 0x00000000 /* denormalized operation */
-
-/* The system id bytes cannot be changed.
- Only the bottom 5 bits in the trap enable byte can be changed.
- Only the bottom 5 bits in the system control byte can be changed.
- Only the bottom 5 bits in the exception flags are used.
- The exception flags are set by the fpu, but can be zeroed by the user. */
-#define _FPU_RESERVED 0xffe0e0e0 /* These bits are reserved. */
-
-/* The fdlibm code requires strict IEEE double precision arithmetic,
- no interrupts for exceptions, rounding to nearest. Changing the
- rounding mode will break long double I/O. Turn on the AC bit,
- the compiler generates code that assumes it is on. */
-#define _FPU_DEFAULT 0x00001000 /* Default value. */
-#define _FPU_IEEE 0x001f1000 /* Default + exceptions enabled. */
-
-/* Type of the control word. */
-typedef unsigned int fpu_control_t;
-
-/* Macros for accessing the hardware control word. */
-#define _FPU_GETCW(cw) __asm__ ("rfs %0" : "=r" (cw))
-#define _FPU_SETCW(cw) __asm__ ("wfs %0" : : "r" (cw))
-
-#endif /* __MAVERICK__ */
-
-#if 0
/* Default control word set at startup. */
extern fpu_control_t __fpu_control;
-#endif
+
+#endif /* __SOFTFP__ */
#endif /* _FPU_CONTROL_H */
diff --git a/libc/sysdeps/linux/arm/setjmp.S b/libc/sysdeps/linux/arm/setjmp.S
index f7a74cc5a..d5bc9ba65 100644
--- a/libc/sysdeps/linux/arm/setjmp.S
+++ b/libc/sysdeps/linux/arm/setjmp.S
@@ -54,6 +54,13 @@ __sigsetjmp:
#endif
#if defined __UCLIBC_HAS_FLOATS__ && ! defined __UCLIBC_HAS_SOFT_FLOAT__
# ifdef __VFP_FP__
+# if __ARM_ARCH >= 8
+ /* Store the VFP registers. */
+ fstmiax ip!, {d8-d15}
+ /* Store the floating-point status register. */
+ fmrx r2, fpscr
+ str r2, [ip], #4
+# else
/* Store the VFP registers. */
/* Following instruction is fstmiax ip!, {d8-d15}. */
stc p11, cr8, [r12], #68
@@ -61,6 +68,7 @@ __sigsetjmp:
/* Following instruction is fmrx r2, fpscr. */
mrc p10, 7, r2, cr1, cr0, 0
str r2, [ip], #4
+# endif
# elif defined __MAVERICK__
cfstrd mvd4, [ip], #8 ; nop
cfstrd mvd5, [ip], #8 ; nop
diff --git a/libc/sysdeps/linux/avr32/bits/fcntl.h b/libc/sysdeps/linux/avr32/bits/fcntl.h
index ec0a3b55d..9e41550be 100644
--- a/libc/sysdeps/linux/avr32/bits/fcntl.h
+++ b/libc/sysdeps/linux/avr32/bits/fcntl.h
@@ -218,3 +218,6 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len,
__END_DECLS
#endif
+
+/* Include generic Linux declarations. */
+#include <bits/fcntl-linux.h>
diff --git a/libc/sysdeps/linux/bfin/bits/fcntl.h b/libc/sysdeps/linux/bfin/bits/fcntl.h
index 0909ae6c4..67d2c5245 100644
--- a/libc/sysdeps/linux/bfin/bits/fcntl.h
+++ b/libc/sysdeps/linux/bfin/bits/fcntl.h
@@ -244,3 +244,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len,
#endif
__END_DECLS
+/* Include generic Linux declarations. */
+#include <bits/fcntl-linux.h>
diff --git a/libc/sysdeps/linux/c6x/bits/fcntl.h b/libc/sysdeps/linux/c6x/bits/fcntl.h
index 14aea565e..00f3b34e0 100644
--- a/libc/sysdeps/linux/c6x/bits/fcntl.h
+++ b/libc/sysdeps/linux/c6x/bits/fcntl.h
@@ -237,3 +237,6 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len,
#endif
__END_DECLS
+
+/* Include generic Linux declarations. */
+#include <bits/fcntl-linux.h>
diff --git a/libc/sysdeps/linux/common-generic/bits/kernel_stat.h b/libc/sysdeps/linux/common-generic/bits/kernel_stat.h
index 7a97bb4d7..e874a4a9f 100644
--- a/libc/sysdeps/linux/common-generic/bits/kernel_stat.h
+++ b/libc/sysdeps/linux/common-generic/bits/kernel_stat.h
@@ -18,7 +18,7 @@
* However that requires more #ifndef in relevant wrappers,
* further uglifying them
*/
-#define kernel_stat64 stat
+#define kernel_stat64 stat64
#endif /* _BITS_STAT_STRUCT_H */
diff --git a/libc/sysdeps/linux/common/Makefile.in b/libc/sysdeps/linux/common/Makefile.in
index 848bc1e4a..4a4317432 100644
--- a/libc/sysdeps/linux/common/Makefile.in
+++ b/libc/sysdeps/linux/common/Makefile.in
@@ -27,9 +27,11 @@ CSRC-$(UCLIBC_LINUX_SPECIFIC) += \
eventfd_write.c \
fanotify.c \
getrandom.c \
+ getentropy.c \
inotify.c \
ioperm.c \
iopl.c \
+ memfd_create.c \
modify_ldt.c \
module.c \
name_to_handle_at.c \
@@ -39,6 +41,8 @@ CSRC-$(UCLIBC_LINUX_SPECIFIC) += \
ppoll.c \
prctl.c \
prlimit.c \
+ process_vm_readv.c \
+ process_vm_writev.c \
readahead.c \
reboot.c \
remap_file_pages.c \
diff --git a/libc/sysdeps/linux/common/bits/fcntl-linux.h b/libc/sysdeps/linux/common/bits/fcntl-linux.h
new file mode 100644
index 000000000..d0236fd8b
--- /dev/null
+++ b/libc/sysdeps/linux/common/bits/fcntl-linux.h
@@ -0,0 +1,34 @@
+/* O_*, F_*, FD_* bit values for Linux.
+ Copyright (C) 2001-2024 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 _FCNTL_H
+# error "Never use <bits/fcntl-linux.h> directly; include <fcntl.h> instead."
+#endif
+
+#ifdef __USE_GNU
+/* Types of seals. */
+# define F_SEAL_SEAL 0x0001 /* Prevent further seals from being set. */
+# define F_SEAL_SHRINK 0x0002 /* Prevent file from shrinking. */
+# define F_SEAL_GROW 0x0004 /* Prevent file from growing. */
+# define F_SEAL_WRITE 0x0008 /* Prevent writes. */
+# define F_SEAL_FUTURE_WRITE 0x0010 /* Prevent future writes while
+ mapped. */
+# define F_SEAL_EXEC 0x0020 /* Prevent chmod modifying exec bits. */
+
+# define F_ADD_SEALS 1033 /* Add seals to file. */
+# define F_GET_SEALS 1034 /* Get seals for file. */
+#endif
diff --git a/libc/sysdeps/linux/common/bits/mman-shared.h b/libc/sysdeps/linux/common/bits/mman-shared.h
index 98c9e1d3c..c40ae2d1e 100644
--- a/libc/sysdeps/linux/common/bits/mman-shared.h
+++ b/libc/sysdeps/linux/common/bits/mman-shared.h
@@ -40,11 +40,9 @@
__BEGIN_DECLS
-#if 0
/* Create a new memory file descriptor. NAME is a name for debugging.
FLAGS is a combination of the MFD_* constants. */
int memfd_create (const char *__name, unsigned int __flags) __THROW;
-#endif
/* Lock pages from ADDR (inclusive) to ADDR + LENGTH (exclusive) into
memory. FLAGS is a combination of the MLOCK_* flags above. */
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/nan.h b/libc/sysdeps/linux/common/bits/nan.h
index 00cb405f1..46cfb613f 100644
--- a/libc/sysdeps/linux/common/bits/nan.h
+++ b/libc/sysdeps/linux/common/bits/nan.h
@@ -25,7 +25,9 @@
#if __GNUC_PREREQ(3,3)
-# define NAN (__builtin_nanf (""))
+# ifndef NAN
+# define NAN (__builtin_nanf (""))
+# endif
#elif defined __GNUC__
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/stat.h b/libc/sysdeps/linux/common/bits/stat.h
index 07c09f50a..fc76cc3e7 100644
--- a/libc/sysdeps/linux/common/bits/stat.h
+++ b/libc/sysdeps/linux/common/bits/stat.h
@@ -61,7 +61,7 @@ struct stat
#else
__blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
#endif
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
@@ -107,7 +107,7 @@ struct stat64
__blksize_t st_blksize; /* Optimal block size for I/O. */
__blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
diff --git a/libc/sysdeps/linux/common/clock_adjtime.c b/libc/sysdeps/linux/common/clock_adjtime.c
index 53f64e9d5..ada256ccd 100644
--- a/libc/sysdeps/linux/common/clock_adjtime.c
+++ b/libc/sysdeps/linux/common/clock_adjtime.c
@@ -15,5 +15,5 @@ _syscall2_64(int, clock_adjtime, clockid_t, clock_id, struct timex*, ntx)
#elif defined(__NR_clock_adjtime)
_syscall2(int, clock_adjtime, clockid_t, clock_id, struct timex*, ntx)
#else
-#error "clock_adjtime syscall is not defined!"
+#warning "clock_adjtime syscall is not defined!"
#endif
diff --git a/libc/sysdeps/linux/common/fstat64.c b/libc/sysdeps/linux/common/fstat64.c
index 359c22af6..121b21fc8 100644
--- a/libc/sysdeps/linux/common/fstat64.c
+++ b/libc/sysdeps/linux/common/fstat64.c
@@ -8,8 +8,9 @@
#include <_lfs_64.h>
#include <sys/syscall.h>
+#include <linux/version.h>
-#if defined(__NR_fstat64) && !defined(__UCLIBC_USE_TIME64__)
+#if defined(__NR_fstat64) && (!defined(__UCLIBC_USE_TIME64__) || LINUX_VERSION_CODE <= KERNEL_VERSION(5,1,0))
# include <unistd.h>
# include <sys/stat.h>
# include "xstatconv.h"
diff --git a/libc/sysdeps/linux/common/fstatat64.c b/libc/sysdeps/linux/common/fstatat64.c
index 16dbf9215..739e84081 100644
--- a/libc/sysdeps/linux/common/fstatat64.c
+++ b/libc/sysdeps/linux/common/fstatat64.c
@@ -9,6 +9,7 @@
#include <_lfs_64.h>
#include <bits/wordsize.h>
#include <sys/syscall.h>
+#include <linux/version.h>
#if defined __mips__
# include <sgidefs.h>
@@ -23,7 +24,7 @@
# define __NR_fstatat64 __NR_newfstatat
#endif
-#if defined(__NR_fstatat64) && !defined(__UCLIBC_USE_TIME64__)
+#if defined(__NR_fstatat64) && (!defined(__UCLIBC_USE_TIME64__) || LINUX_VERSION_CODE <= KERNEL_VERSION(5,1,0))
# include <sys/stat.h>
# include "xstatconv.h"
int fstatat64(int fd, const char *file, struct stat64 *buf, int flag)
diff --git a/libc/sysdeps/linux/common/getentropy.c b/libc/sysdeps/linux/common/getentropy.c
new file mode 100644
index 000000000..d255310b6
--- /dev/null
+++ b/libc/sysdeps/linux/common/getentropy.c
@@ -0,0 +1,46 @@
+/*
+ * getentropy() by wrapping getrandom(), for µClibc-ng
+ *
+ * © 2025 mirabilos Ⓕ CC0 or MirBSD or GNU LGPLv2
+ *
+ * Note: may be a thread cancellation point, unlike the
+ * implementations in glibc and musl libc. Should this
+ * ever become a concern, it will need patching.
+ */
+
+#define _DEFAULT_SOURCE
+#include <errno.h>
+#include <unistd.h>
+#include <sys/random.h>
+#include <sys/syscall.h>
+
+#ifdef __NR_getrandom
+int
+getentropy(void *__buf, size_t __len)
+{
+ ssize_t n;
+
+ if (__len > 256U) {
+ errno = EIO;
+ return (-1);
+ }
+
+ again:
+ if ((n = getrandom(__buf, __len, 0)) == -1)
+ switch (errno) {
+ case EAGAIN: /* should not happen but better safe than sorry */
+ case EINTR:
+ goto again;
+ default:
+ errno = EIO;
+ /* FALLTHROUGH */
+ case EFAULT:
+ case ENOSYS:
+ return (-1);
+ }
+ if ((size_t)n != __len)
+ /* also shouldn’t happen (safety net) */
+ goto again;
+ return (0);
+}
+#endif
diff --git a/libc/sysdeps/linux/common/getrandom.c b/libc/sysdeps/linux/common/getrandom.c
index bb9841463..1db1663b9 100644
--- a/libc/sysdeps/linux/common/getrandom.c
+++ b/libc/sysdeps/linux/common/getrandom.c
@@ -8,6 +8,7 @@
#include <sys/syscall.h>
#include <sys/random.h>
+
#ifdef __NR_getrandom
-_syscall3(int, getrandom, void *, buf, size_t, buflen, unsigned int, flags)
+_syscall3(ssize_t, getrandom, void *, buf, size_t, buflen, unsigned int, flags)
#endif
diff --git a/libc/sysdeps/linux/common/lseek.c b/libc/sysdeps/linux/common/lseek.c
index 80d69318a..0fc99efae 100644
--- a/libc/sysdeps/linux/common/lseek.c
+++ b/libc/sysdeps/linux/common/lseek.c
@@ -40,6 +40,8 @@ off_t __NC(lseek)(int fd, off_t offset attribute_unused, int whence)
case SEEK_SET:
case SEEK_CUR:
case SEEK_END:
+ case SEEK_DATA:
+ case SEEK_HOLE:
break;
default:
__set_errno(EINVAL);
diff --git a/libc/sysdeps/linux/common/memfd_create.c b/libc/sysdeps/linux/common/memfd_create.c
new file mode 100644
index 000000000..7165f3278
--- /dev/null
+++ b/libc/sysdeps/linux/common/memfd_create.c
@@ -0,0 +1,13 @@
+/*
+ * memfd_create() for uClibc-ng
+ *
+ * Copyright (C) 2024 Waldemar Brodkorb <wbx@uclibc-ng.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <sys/syscall.h>
+#include <sys/mman.h>
+#if defined(__NR_memfd_create)
+_syscall2(int, memfd_create, const char *, name, unsigned int, flags)
+#endif
diff --git a/libc/sysdeps/linux/common/not-cancel.h b/libc/sysdeps/linux/common/not-cancel.h
index e4fb1d7fe..426edcc46 100644
--- a/libc/sysdeps/linux/common/not-cancel.h
+++ b/libc/sysdeps/linux/common/not-cancel.h
@@ -19,6 +19,7 @@
#include <sys/types.h>
#include <sysdep.h>
+#include <time.h>
#ifdef NOT_IN_libc
@@ -114,6 +115,7 @@ extern __typeof(pause) __pause_nocancel;
# define nanosleep_not_cancel(requested_time, remaining) \
INLINE_SYSCALL (nanosleep, 2, requested_time, remaining)
#else
+extern int __nanosleep_nocancel (const struct timespec *requested_time, struct timespec *remaining);
# define nanosleep_not_cancel(requested_time, remaining) \
__nanosleep_nocancel (requested_time, remaining)
#endif
diff --git a/libc/sysdeps/linux/common/process_vm_readv.c b/libc/sysdeps/linux/common/process_vm_readv.c
new file mode 100644
index 000000000..b69c1c97a
--- /dev/null
+++ b/libc/sysdeps/linux/common/process_vm_readv.c
@@ -0,0 +1,32 @@
+/* process_vm_readv - Linux specific syscall.
+ Copyright (C) 2020-2024 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 <sys/uio.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+#ifdef __NR_process_vm_readv
+ssize_t
+process_vm_readv (pid_t pid, const struct iovec *local_iov,
+ unsigned long int liovcnt,
+ const struct iovec *remote_iov,
+ unsigned long int riovcnt, unsigned long int flags)
+{
+ return INLINE_SYSCALL (process_vm_readv, 6, pid, local_iov,
+ liovcnt, remote_iov, riovcnt, flags);
+}
+#endif
diff --git a/libc/sysdeps/linux/common/process_vm_writev.c b/libc/sysdeps/linux/common/process_vm_writev.c
new file mode 100644
index 000000000..e22817a8d
--- /dev/null
+++ b/libc/sysdeps/linux/common/process_vm_writev.c
@@ -0,0 +1,32 @@
+/* process_vm_writev - Linux specific syscall.
+ Copyright (C) 2020-2024 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 <sys/uio.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+#ifdef __NR_process_vm_writev
+ssize_t
+process_vm_writev (pid_t pid, const struct iovec *local_iov,
+ unsigned long int liovcnt,
+ const struct iovec *remote_iov,
+ unsigned long int riovcnt, unsigned long int flags)
+{
+ return INLINE_SYSCALL (process_vm_writev, 6, pid, local_iov,
+ liovcnt, remote_iov, riovcnt, flags);
+}
+#endif
diff --git a/libc/sysdeps/linux/common/sys/epoll.h b/libc/sysdeps/linux/common/sys/epoll.h
index 5551bed0d..5138d77a9 100644
--- a/libc/sysdeps/linux/common/sys/epoll.h
+++ b/libc/sysdeps/linux/common/sys/epoll.h
@@ -19,6 +19,7 @@
#define _SYS_EPOLL_H 1
#include <stdint.h>
+#include <sys/ioctl.h>
#include <sys/types.h>
/* Get __sigset_t. */
@@ -87,6 +88,19 @@ struct epoll_event
epoll_data_t data; /* User data variable */
} __EPOLL_PACKED;
+struct epoll_params
+{
+ uint32_t busy_poll_usecs;
+ uint16_t busy_poll_budget;
+ uint8_t prefer_busy_poll;
+
+ /* pad the struct to a multiple of 64bits */
+ uint8_t __pad;
+};
+
+#define EPOLL_IOC_TYPE 0x8A
+#define EPIOCSPARAMS _IOW(EPOLL_IOC_TYPE, 0x01, struct epoll_params)
+#define EPIOCGPARAMS _IOR(EPOLL_IOC_TYPE, 0x02, struct epoll_params)
__BEGIN_DECLS
diff --git a/libc/sysdeps/linux/common/sys/random.h b/libc/sysdeps/linux/common/sys/random.h
index 3d12744ad..c3d9cf575 100644
--- a/libc/sysdeps/linux/common/sys/random.h
+++ b/libc/sysdeps/linux/common/sys/random.h
@@ -4,12 +4,20 @@
#ifndef _SYS_RANDOM_H
#define _SYS_RANDOM_H 1
+
#include <features.h>
#include <stddef.h>
__BEGIN_DECLS
-#if defined __UCLIBC_LINUX_SPECIFIC__ && defined __USE_GNU
+#include <bits/types.h>
+
+#ifndef __ssize_t_defined
+typedef __ssize_t ssize_t;
+# define __ssize_t_defined
+#endif
+
+#if defined __UCLIBC_LINUX_SPECIFIC__
# if 0 /*def __ASSUME_GETRANDOM_SYSCALL */
# include <linux/random.h>
# else
@@ -20,13 +28,21 @@ __BEGIN_DECLS
*
* GRND_NONBLOCK Don't block and return EAGAIN instead
* GRND_RANDOM Use the /dev/random pool instead of /dev/urandom
+ * GRND_INSECURE Write random data that may not be cryptographically secure.
*/
# define GRND_NONBLOCK 0x0001
# define GRND_RANDOM 0x0002
+# define GRND_INSECURE 0x0004
# endif
-/* FIXME: aren't there a couple of __restrict and const missing ? */
-extern int getrandom(void *__buf, size_t count, unsigned int flags)
+extern ssize_t getrandom(void *__buf, size_t count, unsigned int flags)
__nonnull ((1)) __wur;
+
+/* OpenBSD-compatible access to random bytes.
+ May be a cancellation point here, unlike in glibc/musl. */
+# ifndef __getentropy_defined
+extern int getentropy(void *__buf, size_t __len) __nonnull ((1)) __wur;
+# define __getentropy_defined
+# endif
#endif
__END_DECLS
diff --git a/libc/sysdeps/linux/common/utime.c b/libc/sysdeps/linux/common/utime.c
index e4ac0b269..c716388e8 100644
--- a/libc/sysdeps/linux/common/utime.c
+++ b/libc/sysdeps/linux/common/utime.c
@@ -9,7 +9,7 @@
#include <sys/syscall.h>
#include <utime.h>
-#if defined __NR_utimensat && !defined __NR_utime
+#if (defined(__NR_utimensat) || defined(__NR_utimensat_time64)) && !defined __NR_utime
# include <fcntl.h>
# include <stddef.h>
@@ -51,7 +51,7 @@ int utime(const char *file, const struct utimbuf *times)
}
#endif
-#if (defined __NR_utimensat && !defined __NR_utime) || \
+#if ((defined(__NR_utimensat) || defined(__NR_utimensat_time64)) && !defined __NR_utime) || \
defined __NR_utime || defined __NR_utimes
libc_hidden_def(utime)
#endif
diff --git a/libc/sysdeps/linux/common/utimensat.c b/libc/sysdeps/linux/common/utimensat.c
index fa6f90e55..5816c7890 100644
--- a/libc/sysdeps/linux/common/utimensat.c
+++ b/libc/sysdeps/linux/common/utimensat.c
@@ -8,6 +8,7 @@
#include <sys/syscall.h>
#include <sys/stat.h>
+#include <stdint.h>
#if defined(__UCLIBC_USE_TIME64__)
#include "internal/time64_helpers.h"
@@ -28,7 +29,7 @@ int utimensat(int fd, const char *path, const struct timespec times[2], int flag
}
};
- return INLINE_SYSCALL(utimensat_time64, 4, fd, path, times ? &__times64 : 0, flags);
+ return INLINE_SYSCALL(utimensat_time64, 4, fd, path, times ? (uintptr_t) &__times64 : 0, flags);
}
#else
_syscall4(int, utimensat, int, fd, const char *, path, const struct timespec *, times, int, flags)
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/cris/bits/fcntl.h b/libc/sysdeps/linux/cris/bits/fcntl.h
index e9bc90ea9..e1d4ee1a6 100644
--- a/libc/sysdeps/linux/cris/bits/fcntl.h
+++ b/libc/sysdeps/linux/cris/bits/fcntl.h
@@ -245,3 +245,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len,
#endif
__END_DECLS
+/* Include generic Linux declarations. */
+#include <bits/fcntl-linux.h>
diff --git a/libc/sysdeps/linux/csky/bits/fcntl.h b/libc/sysdeps/linux/csky/bits/fcntl.h
index b36f41569..25f4491ba 100644
--- a/libc/sysdeps/linux/csky/bits/fcntl.h
+++ b/libc/sysdeps/linux/csky/bits/fcntl.h
@@ -232,3 +232,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len,
#endif
__END_DECLS
+/* Include generic Linux declarations. */
+#include <bits/fcntl-linux.h>
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/bits/uClibc_arch_features.h b/libc/sysdeps/linux/csky/bits/uClibc_arch_features.h
index 3f5dab80c..1b866cb90 100644
--- a/libc/sysdeps/linux/csky/bits/uClibc_arch_features.h
+++ b/libc/sysdeps/linux/csky/bits/uClibc_arch_features.h
@@ -17,9 +17,6 @@
/* can your target use syscall6() for mmap ? */
#undef __UCLIBC_MMAP_HAS_6_ARGS__
-/* does your target use statx */
-#define __UCLIBC_HAVE_STATX__
-
#ifdef __CSKYABIV2__
#undef __UCLIBC_SYSCALL_ALIGN_64BIT__
#else
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/frv/bits/fcntl.h b/libc/sysdeps/linux/frv/bits/fcntl.h
index 02c8ac310..81a1bcd99 100644
--- a/libc/sysdeps/linux/frv/bits/fcntl.h
+++ b/libc/sysdeps/linux/frv/bits/fcntl.h
@@ -226,3 +226,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len,
#endif
__END_DECLS
+/* Include generic Linux declarations. */
+#include <bits/fcntl-linux.h>
diff --git a/libc/sysdeps/linux/frv/bits/stat.h b/libc/sysdeps/linux/frv/bits/stat.h
index 381d207f2..18321c080 100644
--- a/libc/sysdeps/linux/frv/bits/stat.h
+++ b/libc/sysdeps/linux/frv/bits/stat.h
@@ -70,7 +70,7 @@ struct stat
__blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
#endif
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
@@ -117,7 +117,7 @@ struct stat64
__blksize_t st_blksize; /* Optimal block size for I/O. */
__blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
diff --git a/libc/sysdeps/linux/h8300/bits/fcntl.h b/libc/sysdeps/linux/h8300/bits/fcntl.h
index 2062f7cda..7cbe04e15 100644
--- a/libc/sysdeps/linux/h8300/bits/fcntl.h
+++ b/libc/sysdeps/linux/h8300/bits/fcntl.h
@@ -244,3 +244,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len,
#endif
__END_DECLS
+/* Include generic Linux declarations. */
+#include <bits/fcntl-linux.h>
diff --git a/libc/sysdeps/linux/hppa/bits/fcntl.h b/libc/sysdeps/linux/hppa/bits/fcntl.h
index 4ce76ce5f..bcd6618b2 100644
--- a/libc/sysdeps/linux/hppa/bits/fcntl.h
+++ b/libc/sysdeps/linux/hppa/bits/fcntl.h
@@ -234,3 +234,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len,
#endif
__END_DECLS
+/* Include generic Linux declarations. */
+#include <bits/fcntl-linux.h>
diff --git a/libc/sysdeps/linux/i386/bits/fcntl.h b/libc/sysdeps/linux/i386/bits/fcntl.h
index f3c08bbe5..5caf66114 100644
--- a/libc/sysdeps/linux/i386/bits/fcntl.h
+++ b/libc/sysdeps/linux/i386/bits/fcntl.h
@@ -245,3 +245,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len,
#endif
__END_DECLS
+/* Include generic Linux declarations. */
+#include <bits/fcntl-linux.h>
diff --git a/libc/sysdeps/linux/ia64/bits/fcntl.h b/libc/sysdeps/linux/ia64/bits/fcntl.h
index a20f44ff7..53263c3d3 100644
--- a/libc/sysdeps/linux/ia64/bits/fcntl.h
+++ b/libc/sysdeps/linux/ia64/bits/fcntl.h
@@ -238,3 +238,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len,
#endif
__END_DECLS
+/* Include generic Linux declarations. */
+#include <bits/fcntl-linux.h>
diff --git a/libc/sysdeps/linux/ia64/bits/stat.h b/libc/sysdeps/linux/ia64/bits/stat.h
index 6723166e7..2b70b8cf8 100644
--- a/libc/sysdeps/linux/ia64/bits/stat.h
+++ b/libc/sysdeps/linux/ia64/bits/stat.h
@@ -38,7 +38,7 @@ struct stat
int pad0;
__dev_t st_rdev; /* Device number, if device. */
__off_t st_size; /* Size of file, in bytes. */
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
@@ -77,7 +77,7 @@ struct stat64
int pad0;
__dev_t st_rdev; /* Device number, if device. */
__off_t st_size; /* Size of file, in bytes. */
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
diff --git a/libc/sysdeps/linux/kvx/bits/fcntl.h b/libc/sysdeps/linux/kvx/bits/fcntl.h
index ea0c59d09..79cd3f14e 100644
--- a/libc/sysdeps/linux/kvx/bits/fcntl.h
+++ b/libc/sysdeps/linux/kvx/bits/fcntl.h
@@ -227,3 +227,6 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len,
#endif
__END_DECLS
+
+/* Include generic Linux declarations. */
+#include <bits/fcntl-linux.h>
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/lm32/bits/fcntl.h b/libc/sysdeps/linux/lm32/bits/fcntl.h
index 0bfea6e7a..049c7fd83 100644
--- a/libc/sysdeps/linux/lm32/bits/fcntl.h
+++ b/libc/sysdeps/linux/lm32/bits/fcntl.h
@@ -244,3 +244,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len,
#endif
__END_DECLS
+/* Include generic Linux declarations. */
+#include <bits/fcntl-linux.h>
diff --git a/libc/sysdeps/linux/m68k/bits/fcntl.h b/libc/sysdeps/linux/m68k/bits/fcntl.h
index 5a56c8781..92c0964d9 100644
--- a/libc/sysdeps/linux/m68k/bits/fcntl.h
+++ b/libc/sysdeps/linux/m68k/bits/fcntl.h
@@ -244,3 +244,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len,
#endif
__END_DECLS
+/* Include generic Linux declarations. */
+#include <bits/fcntl-linux.h>
diff --git a/libc/sysdeps/linux/m68k/bits/fenv.h b/libc/sysdeps/linux/m68k/bits/fenv.h
index b07f0ab51..37c5fe829 100644
--- a/libc/sysdeps/linux/m68k/bits/fenv.h
+++ b/libc/sysdeps/linux/m68k/bits/fenv.h
@@ -1,5 +1,4 @@
-/* Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
+/* 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,31 +11,38 @@
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/>. */
+ 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
+#if defined __HAVE_68881__ || defined __HAVE_FPU__ || defined __mcffpu__
+
/* Define bits representing the exception. We use the bit positions of
the appropriate bits in the FPSR Accrued Exception Byte. */
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_INEXACT =
+# define FE_INEXACT (1 << 3)
+ FE_INEXACT,
+ FE_DIVBYZERO =
+# define FE_DIVBYZERO (1 << 4)
+ FE_DIVBYZERO,
+ FE_UNDERFLOW =
+# define FE_UNDERFLOW (1 << 5)
+ FE_UNDERFLOW,
+ FE_OVERFLOW =
+# define FE_OVERFLOW (1 << 6)
+ FE_OVERFLOW,
+ FE_INVALID =
+# define FE_INVALID (1 << 7)
+ FE_INVALID
};
-#define FE_ALL_EXCEPT \
+# define FE_ALL_EXCEPT \
(FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID)
/* The m68k FPU supports all of the four defined rounding modes. We use
@@ -44,21 +50,45 @@ enum
appropriate macros. */
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_TONEAREST =
+# define FE_TONEAREST 0
+ FE_TONEAREST,
+ FE_TOWARDZERO =
+# define FE_TOWARDZERO (1 << 4)
+ FE_TOWARDZERO,
+ FE_DOWNWARD =
+# define FE_DOWNWARD (2 << 4)
+ FE_DOWNWARD,
+ FE_UPWARD =
+# define FE_UPWARD (3 << 4)
+ FE_UPWARD
};
+#else
+
+/* In the soft-float case, only rounding to nearest is supported, with
+ no exceptions. */
+
+# define FE_ALL_EXCEPT 0
+
+enum
+ {
+ __FE_UNDEFINED = -1,
+
+ FE_TONEAREST =
+# define FE_TONEAREST 0
+ FE_TONEAREST
+ };
+
+#endif
+
/* Type representing exception flags. */
typedef unsigned int fexcept_t;
+#if defined __HAVE_68881__ || defined __HAVE_FPU__ || defined __mcffpu__
+
/* Type representing floating-point environment. This structure
corresponds to the layout of the block written by `fmovem'. */
typedef struct
@@ -69,10 +99,30 @@ typedef struct
}
fenv_t;
+#else
+
+/* Keep ABI compatibility with the type used in the generic
+ bits/fenv.h, formerly used for no-FPU ColdFire. */
+typedef struct
+ {
+ fexcept_t __excepts;
+ }
+fenv_t;
+
+#endif
+
/* If the default argument is used we use this value. */
#define FE_DFL_ENV ((const fenv_t *) -1)
-#ifdef __USE_GNU
+#if defined __USE_GNU && (defined __HAVE_68881__ \
+ || defined __HAVE_FPU__ \
+ || defined __mcffpu__)
/* Floating-point environment where none of the exceptions are masked. */
# 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/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/m68k/bits/stat.h b/libc/sysdeps/linux/m68k/bits/stat.h
index 7b9c3d144..70da1b384 100644
--- a/libc/sysdeps/linux/m68k/bits/stat.h
+++ b/libc/sysdeps/linux/m68k/bits/stat.h
@@ -60,7 +60,7 @@ struct stat
#else
__blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
#endif
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
@@ -106,7 +106,7 @@ struct stat64
__blksize_t st_blksize; /* Optimal block size for I/O. */
__blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
diff --git a/libc/sysdeps/linux/m68k/bsd-_setjmp.S b/libc/sysdeps/linux/m68k/bsd-_setjmp.S
index c963cccf5..eaabce8ed 100644
--- a/libc/sysdeps/linux/m68k/bsd-_setjmp.S
+++ b/libc/sysdeps/linux/m68k/bsd-_setjmp.S
@@ -13,7 +13,9 @@ _setjmp:
moveal %sp@(4), %a0
movel %sp@(0), %a0@(JB_PC)
moveml %d2-%d7/%a2-%a7, %a0@(JB_REGS)
-#if defined __HAVE_68881__ || defined __UCLIBC_HAS_FPU__
+#if defined(__mcffpu__) && defined(__UCLIBC_HAS_FPU__)
+ fmovemd %fp2-%fp7, %a0@(JB_FPREGS)
+#elif defined(__HAVE_68881__)
fmovemx %fp2-%fp7, %a0@(JB_FPREGS)
#endif
clrl %d0
diff --git a/libc/sysdeps/linux/m68k/bsd-setjmp.S b/libc/sysdeps/linux/m68k/bsd-setjmp.S
index 9daf27713..7d76d192b 100644
--- a/libc/sysdeps/linux/m68k/bsd-setjmp.S
+++ b/libc/sysdeps/linux/m68k/bsd-setjmp.S
@@ -14,7 +14,9 @@ setjmp:
moveal %sp@(4), %a0
movel %sp@(0), %a0@(JB_PC)
moveml %d2-%d7/%a2-%a7, %a0@(JB_REGS)
-#if defined __HAVE_68881__ || defined __UCLIBC_HAS_FPU__
+#if defined(__mcffpu__) && defined(__UCLIBC_HAS_FPU__)
+ fmovemd %fp2-%fp7, %a0@(JB_FPREGS)
+#elif defined(__HAVE_68881__)
fmovemx %fp2-%fp7, %a0@(JB_FPREGS)
#endif
clrl %d0
diff --git a/libc/sysdeps/linux/m68k/clone.S b/libc/sysdeps/linux/m68k/clone.S
index 24071235b..a83d90a98 100644
--- a/libc/sysdeps/linux/m68k/clone.S
+++ b/libc/sysdeps/linux/m68k/clone.S
@@ -35,12 +35,14 @@
__clone:
/* Sanity check arguments. */
- movel #-EINVAL, %d0
- movel 4(%sp), %a0 /* no NULL function pointers */
- tstl %a0
+ movel #-EINVAL, %d0
+ movel 4(%sp), %d1 /* no NULL function pointers */
+ movel %d1, %a0
+ tstl %d1
beq.w __syscall_error_trampoline
- movel 8(%sp), %a1 /* no NULL stack pointers */
- tstl %a1
+ movel 8(%sp), %d1 /* no NULL stack pointers */
+ movel %d1, %a1
+ tstl %d1
beq.w __syscall_error_trampoline
/* Allocate space and copy the argument onto the new stack. */
diff --git a/libc/sysdeps/linux/m68k/fpu_control.h b/libc/sysdeps/linux/m68k/fpu_control.h
index 35ad95e6d..c3a9c6326 100644
--- a/libc/sysdeps/linux/m68k/fpu_control.h
+++ b/libc/sysdeps/linux/m68k/fpu_control.h
@@ -1,6 +1,5 @@
/* 68k FPU control word definitions.
- Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
+ Copyright (C) 1996-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,8 +12,8 @@
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/>. */
+ License along with the GNU C Library. If not, see
+ <https://www.gnu.org/licenses/>. */
#ifndef _FPU_CONTROL_H
#define _FPU_CONTROL_H
@@ -29,9 +28,9 @@
* 12 -> enable trap for OVFL exception
* 11 -> enable trap for UNFL exception
* 10 -> enable trap for DZ exception
- * 9 -> enable trap for INEX2 exception
- * 8 -> enable trap for INEX1 exception
- * 7-6 -> Precision Control
+ * 9 -> enable trap for INEX2 exception (INEX on Coldfire)
+ * 8 -> enable trap for INEX1 exception (IDE on Coldfire)
+ * 7-6 -> Precision Control (only bit 6 is used on Coldfire)
* 5-4 -> Rounding Control
* 3-0 -> zero (read as 0, write as 0)
*
@@ -53,50 +52,66 @@
#include <features.h>
+#if defined (__mcoldfire__) && !defined (__mcffpu__)
+
+# define _FPU_RESERVED 0xffffffff
+# define _FPU_DEFAULT 0x00000000
+# define _FPU_GETCW(cw) ((cw) = 0)
+# define _FPU_SETCW(cw) ((void) (cw))
+
+#else
+
/* masking of interrupts */
-#define _FPU_MASK_BSUN 0x8000
-#define _FPU_MASK_SNAN 0x4000
-#define _FPU_MASK_OPERR 0x2000
-#define _FPU_MASK_OVFL 0x1000
-#define _FPU_MASK_UNFL 0x0800
-#define _FPU_MASK_DZ 0x0400
-#define _FPU_MASK_INEX1 0x0200
-#define _FPU_MASK_INEX2 0x0100
+# define _FPU_MASK_BSUN 0x8000
+# define _FPU_MASK_SNAN 0x4000
+# define _FPU_MASK_OPERR 0x2000
+# define _FPU_MASK_OVFL 0x1000
+# define _FPU_MASK_UNFL 0x0800
+# define _FPU_MASK_DZ 0x0400
+# define _FPU_MASK_INEX1 0x0200
+# define _FPU_MASK_INEX2 0x0100
/* precision control */
-#define _FPU_EXTENDED 0x00 /* RECOMMENDED */
-#define _FPU_DOUBLE 0x80
-#define _FPU_SINGLE 0x40 /* DO NOT USE */
+# ifdef __mcoldfire__
+# define _FPU_DOUBLE 0x00
+# else
+# define _FPU_EXTENDED 0x00 /* RECOMMENDED */
+# define _FPU_DOUBLE 0x80
+# endif
+# define _FPU_SINGLE 0x40 /* DO NOT USE */
/* rounding control */
-#define _FPU_RC_NEAREST 0x00 /* RECOMMENDED */
-#define _FPU_RC_ZERO 0x10
-#define _FPU_RC_DOWN 0x20
-#define _FPU_RC_UP 0x30
+# define _FPU_RC_NEAREST 0x00 /* RECOMMENDED */
+# define _FPU_RC_ZERO 0x10
+# define _FPU_RC_DOWN 0x20
+# define _FPU_RC_UP 0x30
-#define _FPU_RESERVED 0xFFFF000F /* Reserved bits in fpucr */
+# ifdef __mcoldfire__
+# define _FPU_RESERVED 0xFFFF800F
+# else
+# define _FPU_RESERVED 0xFFFF000F /* Reserved bits in fpucr */
+# endif
/* Now two recommended fpucr */
/* The fdlibm code requires no interrupts for exceptions. Don't
change the rounding mode, it would break long double I/O! */
-#define _FPU_DEFAULT 0x00000000
+# define _FPU_DEFAULT 0x00000000
/* IEEE: same as above, but exceptions. We must make it non-zero so
that __setfpucw works. This bit will be ignored. */
-#define _FPU_IEEE 0x00000001
+# define _FPU_IEEE 0x00000001
+
+/* Macros for accessing the hardware control word. */
+# define _FPU_GETCW(cw) __asm__ ("fmove%.l %!, %0" : "=dm" (cw))
+# define _FPU_SETCW(cw) __asm__ volatile ("fmove%.l %0, %!" : : "dm" (cw))
+#endif
/* Type of the control word. */
typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__SI__)));
-/* Macros for accessing the hardware control word. */
-#define _FPU_GETCW(cw) __asm__ ("fmove%.l %!, %0" : "=dm" (cw))
-#define _FPU_SETCW(cw) __asm__ __volatile__ ("fmove%.l %0, %!" : : "dm" (cw))
-
-#if 0
/* Default control word set at startup. */
extern fpu_control_t __fpu_control;
-#endif
#endif /* _M68K_FPU_CONTROL_H */
diff --git a/libc/sysdeps/linux/m68k/setjmp.S b/libc/sysdeps/linux/m68k/setjmp.S
index 5f05b8591..d10163ec6 100644
--- a/libc/sysdeps/linux/m68k/setjmp.S
+++ b/libc/sysdeps/linux/m68k/setjmp.S
@@ -14,7 +14,9 @@ __sigsetjmp:
moveal %sp@(4), %a0
movel %sp@(0), %a0@(JB_PC)
moveml %d2-%d7/%a2-%a7, %a0@(JB_REGS)
-#if defined __HAVE_68881__ || defined __UCLIBC_HAS_FPU__
+#if defined(__mcffpu__) && defined (__UCLIBC_HAS_FPU__)
+ fmovemd %fp2-%fp7, %a0@(JB_FPREGS)
+#elif defined(__HAVE_68881__)
fmovemx %fp2-%fp7, %a0@(JB_FPREGS)
#endif
clrl %d0
diff --git a/libc/sysdeps/linux/metag/bits/fcntl.h b/libc/sysdeps/linux/metag/bits/fcntl.h
index bdd697348..471938b7d 100644
--- a/libc/sysdeps/linux/metag/bits/fcntl.h
+++ b/libc/sysdeps/linux/metag/bits/fcntl.h
@@ -244,3 +244,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len,
#endif
__END_DECLS
+/* Include generic Linux declarations. */
+#include <bits/fcntl-linux.h>
diff --git a/libc/sysdeps/linux/microblaze/bits/fcntl.h b/libc/sysdeps/linux/microblaze/bits/fcntl.h
index 110927d95..8c9c2ceef 100644
--- a/libc/sysdeps/linux/microblaze/bits/fcntl.h
+++ b/libc/sysdeps/linux/microblaze/bits/fcntl.h
@@ -244,3 +244,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len,
#endif
__END_DECLS
+/* Include generic Linux declarations. */
+#include <bits/fcntl-linux.h>
diff --git a/libc/sysdeps/linux/mips/bits/fcntl.h b/libc/sysdeps/linux/mips/bits/fcntl.h
index 33251c74d..a98b8c2e5 100644
--- a/libc/sysdeps/linux/mips/bits/fcntl.h
+++ b/libc/sysdeps/linux/mips/bits/fcntl.h
@@ -268,3 +268,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len,
#endif
__END_DECLS
+/* Include generic Linux declarations. */
+#include <bits/fcntl-linux.h>
diff --git a/libc/sysdeps/linux/mips/bits/fenv.h b/libc/sysdeps/linux/mips/bits/fenv.h
index 944101f75..25ae4d9ca 100644
--- a/libc/sysdeps/linux/mips/bits/fenv.h
+++ b/libc/sysdeps/linux/mips/bits/fenv.h
@@ -1,5 +1,4 @@
-/* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
+/* 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
@@ -12,31 +11,38 @@
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/>. */
+ 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
+#ifdef __mips_hard_float
+
/* Define bits representing the exception. We use the bit positions
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 \
+# define FE_ALL_EXCEPT \
(FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID)
/* The MIPS FPU supports all of the four defined rounding modes. We
@@ -44,16 +50,38 @@ enum
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_TONEAREST =
+# define FE_TONEAREST 0x0
+ FE_TONEAREST,
+ FE_TOWARDZERO =
+# define FE_TOWARDZERO 0x1
+ FE_TOWARDZERO,
+ FE_UPWARD =
+# define FE_UPWARD 0x2
+ FE_UPWARD,
+ FE_DOWNWARD =
+# define FE_DOWNWARD 0x3
+ FE_DOWNWARD
};
+#else
+
+/* In the soft-float case, only rounding to nearest is supported, with
+ no exceptions. */
+
+enum
+ {
+ __FE_UNDEFINED = -1,
+
+ FE_TONEAREST =
+# define FE_TONEAREST 0x0
+ FE_TONEAREST
+ };
+
+# define FE_ALL_EXCEPT 0
+
+#endif
+
/* Type representing exception flags. */
typedef unsigned short int fexcept_t;
@@ -70,7 +98,13 @@ fenv_t;
/* If the default argument is used we use this value. */
#define FE_DFL_ENV ((const fenv_t *) -1)
-#ifdef __USE_GNU
+#if defined __USE_GNU && defined __mips_hard_float
/* Floating-point environment where none of the exception is masked. */
# 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/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/stat.h b/libc/sysdeps/linux/mips/bits/stat.h
index 539fa33d2..81d2e4687 100644
--- a/libc/sysdeps/linux/mips/bits/stat.h
+++ b/libc/sysdeps/linux/mips/bits/stat.h
@@ -60,7 +60,7 @@ struct stat
long int st_pad2[2];
__off64_t st_size; /* Size of file, in bytes. */
#endif
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
@@ -103,7 +103,7 @@ struct stat {
unsigned int st_rdev; /* Device number, if device. */
int st_pad2[3];
__off_t st_size; /* Size of file, in bytes. */
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
@@ -145,7 +145,7 @@ struct stat64
__dev_t st_rdev; /* Device number, if device. */
long int st_pad2[2];
__off64_t st_size; /* Size of file, in bytes. */
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
@@ -184,7 +184,7 @@ struct stat64 {
unsigned int st_rdev; /* Device number, if device. */
int st_pad2[3];
__off_t st_size; /* Size of file, in bytes. */
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
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/mips/fpu_control.h b/libc/sysdeps/linux/mips/fpu_control.h
index f855af506..6aa05e4cf 100644
--- a/libc/sysdeps/linux/mips/fpu_control.h
+++ b/libc/sysdeps/linux/mips/fpu_control.h
@@ -1,7 +1,5 @@
/* FPU control word bits. Mips version.
- Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contributed by Olaf Flebbe and Ralf Baechle.
+ Copyright (C) 1996-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,8 +12,8 @@
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/>. */
+ License along with the GNU C Library. If not, see
+ <https://www.gnu.org/licenses/>. */
#ifndef _FPU_CONTROL_H
#define _FPU_CONTROL_H
@@ -28,7 +26,10 @@
* causing unimplemented operation exception. This bit is only
* available for MIPS III and newer.
* 23 -> Condition bit
- * 22-18 -> reserved (read as 0, write with 0)
+ * 22-21 -> reserved for architecture implementers
+ * 20 -> reserved (read as 0, write with 0)
+ * 19 -> IEEE 754-2008 non-arithmetic ABS.fmt and NEG.fmt enable
+ * 18 -> IEEE 754-2008 recommended NaN encoding enable
* 17 -> cause bit for unimplemented operation
* 16 -> cause bit for invalid exception
* 15 -> cause bit for division by zero exception
@@ -57,43 +58,74 @@
#include <features.h>
-/* masking of interrupts */
+#ifdef __mips_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)
+extern fpu_control_t __fpu_control;
+
+#else /* __mips_soft_float */
+
+/* Masks for interrupts. */
#define _FPU_MASK_V 0x0800 /* Invalid operation */
#define _FPU_MASK_Z 0x0400 /* Division by zero */
#define _FPU_MASK_O 0x0200 /* Overflow */
#define _FPU_MASK_U 0x0100 /* Underflow */
#define _FPU_MASK_I 0x0080 /* Inexact operation */
-/* flush denormalized numbers to zero */
+/* Flush denormalized numbers to zero. */
#define _FPU_FLUSH_TZ 0x1000000
-/* rounding control */
+/* IEEE 754-2008 compliance control. */
+#define _FPU_ABS2008 0x80000
+#define _FPU_NAN2008 0x40000
+
+/* Rounding control. */
#define _FPU_RC_NEAREST 0x0 /* RECOMMENDED */
#define _FPU_RC_ZERO 0x1
#define _FPU_RC_UP 0x2
#define _FPU_RC_DOWN 0x3
+/* Mask for rounding control. */
+#define _FPU_RC_MASK 0x3
-#define _FPU_RESERVED 0xfe3c0000 /* Reserved bits in cw */
+#define _FPU_RESERVED 0xfe8c0000 /* Reserved bits in cw, incl ABS/NAN2008. */
/* The fdlibm code requires strict IEEE double precision arithmetic,
and no interrupts for exceptions, rounding to nearest. */
+#ifdef __mips_nan2008
+# define _FPU_DEFAULT 0x000C0000
+#else
+# define _FPU_DEFAULT 0x00000000
+#endif
-#define _FPU_DEFAULT 0x00000000
-
-/* IEEE: same as above, but exceptions */
-#define _FPU_IEEE 0x00000F80
+/* IEEE: same as above, but exceptions. */
+#ifdef __mips_nan2008
+# define _FPU_IEEE 0x000C0F80
+#else
+# define _FPU_IEEE 0x00000F80
+#endif
/* Type of the control word. */
typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__SI__)));
/* Macros for accessing the hardware control word. */
-#define _FPU_GETCW(cw) __asm__ ("cfc1 %0,$31" : "=r" (cw))
-#define _FPU_SETCW(cw) __asm__ ("ctc1 %0,$31" : : "r" (cw))
+extern fpu_control_t __mips_fpu_getcw (void) __THROW;
+extern void __mips_fpu_setcw (fpu_control_t) __THROW;
+#ifdef __mips16
+# define _FPU_GETCW(cw) do { (cw) = __mips_fpu_getcw (); } while (0)
+# define _FPU_SETCW(cw) __mips_fpu_setcw (cw)
+#else
+# define _FPU_GETCW(cw) __asm__ volatile ("cfc1 %0,$31" : "=r" (cw))
+# define _FPU_SETCW(cw) __asm__ volatile ("ctc1 %0,$31" : : "r" (cw))
+#endif
-#if 0
/* Default control word set at startup. */
extern fpu_control_t __fpu_control;
-#endif
+
+#endif /* __mips_soft_float */
#endif /* fpu_control.h */
diff --git a/libc/sysdeps/linux/nds32/Makefile.arch b/libc/sysdeps/linux/nds32/Makefile.arch
index c7627b847..caf163844 100644
--- a/libc/sysdeps/linux/nds32/Makefile.arch
+++ b/libc/sysdeps/linux/nds32/Makefile.arch
@@ -2,6 +2,6 @@
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
CSRC-y := brk.c prctl.c mremap.c
-SSRC-y := setjmp.S __longjmp.S bsd-setjmp.S bsd-_setjmp.S clone.S sysdep.S
+SSRC-y := setjmp.S __longjmp.S bsd-setjmp.S bsd-_setjmp.S clone.S vfork.S sysdep.S
CSRC-$(UCLIBC_HAS_CONTEXT_FUNCS) += makecontext.c swapcontext.c
SSRC-$(UCLIBC_HAS_CONTEXT_FUNCS) += getcontext.S setcontext.S
diff --git a/libc/sysdeps/linux/nds32/bits/fcntl.h b/libc/sysdeps/linux/nds32/bits/fcntl.h
index 2e6a95ec8..cfce8ab27 100644
--- a/libc/sysdeps/linux/nds32/bits/fcntl.h
+++ b/libc/sysdeps/linux/nds32/bits/fcntl.h
@@ -249,3 +249,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len,
#endif
__END_DECLS
+/* Include generic Linux declarations. */
+#include <bits/fcntl-linux.h>
diff --git a/libc/sysdeps/linux/nds32/bits/kernel_types.h b/libc/sysdeps/linux/nds32/bits/kernel_types.h
index 6b142d2e5..1b6ae4d1b 100644
--- a/libc/sysdeps/linux/nds32/bits/kernel_types.h
+++ b/libc/sysdeps/linux/nds32/bits/kernel_types.h
@@ -14,13 +14,13 @@
typedef unsigned short __kernel_dev_t;
typedef unsigned long __kernel_ino_t;
-typedef unsigned int __kernel_mode_t;
+typedef unsigned short __kernel_mode_t;
typedef unsigned short __kernel_nlink_t;
typedef long __kernel_off_t;
typedef int __kernel_pid_t;
-typedef int __kernel_ipc_pid_t;
-typedef unsigned int __kernel_uid_t;
-typedef unsigned int __kernel_gid_t;
+typedef unsigned short __kernel_ipc_pid_t;
+typedef unsigned short __kernel_uid_t;
+typedef unsigned short __kernel_gid_t;
typedef unsigned int __kernel_size_t;
typedef int __kernel_ssize_t;
typedef int __kernel_ptrdiff_t;
@@ -34,11 +34,19 @@ typedef unsigned short __kernel_gid16_t;
typedef unsigned int __kernel_uid32_t;
typedef unsigned int __kernel_gid32_t;
-typedef __kernel_uid_t __kernel_old_uid_t;
-typedef __kernel_gid_t __kernel_old_gid_t;
-typedef unsigned int __kernel_old_dev_t;
+typedef unsigned short __kernel_old_uid_t;
+typedef unsigned short __kernel_old_gid_t;
+typedef __kernel_dev_t __kernel_old_dev_t;
typedef long __kernel_long_t;
typedef unsigned long __kernel_ulong_t;
__extension__ typedef long long __kernel_loff_t;
+typedef struct {
+#ifdef __USE_ALL
+ int val[2];
+#else
+ int __val[2];
+#endif
+} __kernel_fsid_t;
+
#endif /* __ARCH_NDS32_POSIX_TYPES_H */
diff --git a/libc/sysdeps/linux/nds32/bits/stat.h b/libc/sysdeps/linux/nds32/bits/stat.h
index c4e09e0f2..5272751f4 100644
--- a/libc/sysdeps/linux/nds32/bits/stat.h
+++ b/libc/sysdeps/linux/nds32/bits/stat.h
@@ -64,7 +64,7 @@ struct stat
#else
__blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
#endif
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
@@ -110,7 +110,7 @@ struct stat64
__blksize_t st_blksize; /* Optimal block size for I/O. */
__blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
diff --git a/libc/sysdeps/linux/nds32/bits/syscalls.h b/libc/sysdeps/linux/nds32/bits/syscalls.h
index 50e30db7d..a5cdda18a 100644
--- a/libc/sysdeps/linux/nds32/bits/syscalls.h
+++ b/libc/sysdeps/linux/nds32/bits/syscalls.h
@@ -37,7 +37,8 @@
#define Y(x) X(x)
#define LIB_SYSCALL __NR_syscall
-#define __issue_syscall(syscall_name) "syscall 0x0;\n"
+#define __issue_syscall(syscall_name) \
+" syscall " Y(syscall_name) "; \n"
#undef INTERNAL_SYSCALL_ERROR_P
#define INTERNAL_SYSCALL_ERROR_P(val, err) ((unsigned int) (val) >= 0xfffff001u)
diff --git a/libc/sysdeps/linux/nds32/jmpbuf-unwind.h b/libc/sysdeps/linux/nds32/jmpbuf-unwind.h
index 8499e99b4..5b85f4d23 100644
--- a/libc/sysdeps/linux/nds32/jmpbuf-unwind.h
+++ b/libc/sysdeps/linux/nds32/jmpbuf-unwind.h
@@ -20,7 +20,7 @@
static inline uintptr_t __attribute__ ((unused))
_jmpbuf_sp (__jmp_buf regs)
{
- uintptr_t sp = &(regs)[0].__regs[__JMP_BUF_SP];
+ uintptr_t sp = (uintptr_t) &(regs)[0].__regs[__JMP_BUF_SP];
return sp;
}
diff --git a/libc/sysdeps/linux/nds32/sys/ucontext.h b/libc/sysdeps/linux/nds32/sys/ucontext.h
index ea86a3ad0..0d7422aab 100644
--- a/libc/sysdeps/linux/nds32/sys/ucontext.h
+++ b/libc/sysdeps/linux/nds32/sys/ucontext.h
@@ -36,10 +36,10 @@ typedef struct sigcontext mcontext_t;
/* Userlevel context. */
-typedef struct ucontext_t
+typedef struct ucontext
{
- unsigned long int __uc_flags;
- struct ucontext_t *uc_link;
+ unsigned long int uc_flags;
+ struct ucontext *uc_link;
stack_t uc_stack;
mcontext_t uc_mcontext;
__sigset_t uc_sigmask;
diff --git a/libc/sysdeps/linux/nds32/vfork.S b/libc/sysdeps/linux/nds32/vfork.S
new file mode 100644
index 000000000..ab32135fc
--- /dev/null
+++ b/libc/sysdeps/linux/nds32/vfork.S
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2016-2017 Andes Technology, Inc.
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/* Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
+ Contributed by Philip Blundell <philb@gnu.org>.
+
+ 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+
+/* Clone the calling process, but without copying the whole address space.
+ The calling process is suspended until the new process exits or is
+ replaced by a call to `execve'. Return -1 for errors, 0 to the new process,
+ and the process ID of the new process to the old process. */
+
+ENTRY (__vfork)
+#ifdef PIC
+.pic
+#endif
+
+#ifdef __NR_vfork
+ syscall __NR_vfork
+ bltz $r0, 2f
+1:
+ ret
+2:
+ sltsi $r1, $r0, -4096
+ bnez $r1, 1b;
+
+# ifdef __ASSUME_VFORK_SYSCALL
+# ifdef PIC
+ pushm $gp, $lp
+ cfi_adjust_cfa_offset(8)
+ cfi_rel_offset(gp, 0)
+ cfi_rel_offset(lp, 4)
+ mfusr $r15, $PC
+ sethi $gp, hi20(_GLOBAL_OFFSET_TABLE_+4)
+ ori $gp, $gp, lo12(_GLOBAL_OFFSET_TABLE_+8)
+ add $gp, $gp, $r15
+
+ ! r15=C_SYMBOL_NAME(__syscall_error)@PLT
+ sethi $r15, hi20(C_SYMBOL_NAME(__syscall_error)@PLT)
+ ori $r15, $r15, lo12(C_SYMBOL_NAME(__syscall_error)@PLT)
+ add $r15, $r15, $gp
+
+ ! jump to SYSCALL_ERROR
+ jral $r15
+ popm $gp, $lp
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(lp)
+ cfi_restore(gp)
+ ret
+# else
+ j C_SYMBOL_NAME(__syscall_error)
+# endif
+# else
+ /* Check if vfork syscall is known at all. */
+ li $r1, -ENOSYS
+ beq $r0, $r1, 1f
+
+# ifdef PIC
+3:
+ pushm $gp, $lp
+ cfi_adjust_cfa_offset(8)
+ cfi_rel_offset(gp, 0)
+ cfi_rel_offset(lp, 4)
+ mfusr $r15, $PC
+ sethi $gp, hi20(_GLOBAL_OFFSET_TABLE_+4)
+ ori $gp, $gp, lo12(_GLOBAL_OFFSET_TABLE_+8)
+ add $gp, $gp, $r15
+
+ ! r15=C_SYMBOL_NAME(__syscall_error)@PLT
+ sethi $r15, hi20(C_SYMBOL_NAME(__syscall_error)@PLT)
+ ori $r15, $r15, lo12(C_SYMBOL_NAME(__syscall_error)@PLT)
+ add $r15, $r15, $gp
+
+ ! jump to SYSCALL_ERROR
+ jral $r15
+ popm $gp, $lp
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(lp)
+ cfi_restore(gp)
+ ret
+# else
+ j C_SYMBOL_NAME(__syscall_error)
+# endif
+1:
+# endif
+#endif
+
+#ifndef __ASSUME_VFORK_SYSCALL
+ /* If we don't have vfork, fork is close enough. */
+ syscall __NR_fork
+ bgez $r0, 1f
+ sltsi $r1, $r0, -4096
+ bnez $r1, 1f
+
+# ifdef PIC
+ b 3b
+# else
+ j C_SYMBOL_NAME(__syscall_error)
+# endif
+1:
+ ret
+
+#elif !defined __NR_vfork
+# error "__NR_vfork not available and __ASSUME_VFORK_SYSCALL defined"
+#endif
+
+PSEUDO_END (__vfork)
+weak_alias (__vfork, vfork)
+libc_hidden_def (vfork)
diff --git a/libc/sysdeps/linux/nios2/bits/fcntl.h b/libc/sysdeps/linux/nios2/bits/fcntl.h
index 200a35443..0c11c3aba 100644
--- a/libc/sysdeps/linux/nios2/bits/fcntl.h
+++ b/libc/sysdeps/linux/nios2/bits/fcntl.h
@@ -244,3 +244,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len,
#endif
__END_DECLS
+/* Include generic Linux declarations. */
+#include <bits/fcntl-linux.h>
diff --git a/libc/sysdeps/linux/or1k/bits/fcntl.h b/libc/sysdeps/linux/or1k/bits/fcntl.h
index c9599ef3a..78eed9d5f 100644
--- a/libc/sysdeps/linux/or1k/bits/fcntl.h
+++ b/libc/sysdeps/linux/or1k/bits/fcntl.h
@@ -244,3 +244,6 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len,
#endif
__END_DECLS
+
+/* Include generic Linux declarations. */
+#include <bits/fcntl-linux.h>
diff --git a/libc/sysdeps/linux/or1k/bits/fenv.h b/libc/sysdeps/linux/or1k/bits/fenv.h
new file mode 100644
index 000000000..4701946ff
--- /dev/null
+++ b/libc/sysdeps/linux/or1k/bits/fenv.h
@@ -0,0 +1,84 @@
+/* Floating point environment, OpenRISC version.
+ Copyright (C) 2022-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
+
+#ifdef __or1k_hard_float__
+/* Define bits representing exceptions in the FPCSR status word. */
+enum
+ {
+ FE_OVERFLOW =
+#define FE_OVERFLOW (1 << 3)
+ FE_OVERFLOW,
+ FE_UNDERFLOW =
+#define FE_UNDERFLOW (1 << 4)
+ FE_UNDERFLOW,
+ FE_INEXACT =
+#define FE_INEXACT (1 << 8)
+ FE_INEXACT,
+ FE_INVALID =
+#define FE_INVALID (1 << 9)
+ FE_INVALID,
+ FE_DIVBYZERO =
+#define FE_DIVBYZERO (1 << 11)
+ FE_DIVBYZERO,
+ };
+
+/* All supported exceptions. */
+#define FE_ALL_EXCEPT \
+ (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT)
+
+/* Define bits representing rounding modes in the FPCSR Rmode field. */
+#define FE_TONEAREST (0x0 << 1)
+#define FE_TOWARDZERO (0x1 << 1)
+#define FE_UPWARD (0x2 << 1)
+#define FE_DOWNWARD (0x3 << 1)
+
+#else
+
+/* In the soft-float case only rounding to nearest is supported, with
+ no exceptions. */
+
+enum
+ {
+ __FE_UNDEFINED = -1,
+
+ FE_TONEAREST =
+# define FE_TONEAREST 0x0
+ FE_TONEAREST
+ };
+
+# define FE_ALL_EXCEPT 0
+
+#endif /* __or1k_hard_float__ */
+
+/* Type representing exception flags. */
+typedef unsigned int fexcept_t;
+
+/* Type representing floating-point environment. */
+typedef unsigned int fenv_t;
+
+/* If the default argument is used we use this value. */
+#define FE_DFL_ENV ((const fenv_t *) -1l)
+
+/* 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/or1k/fpu_control.h b/libc/sysdeps/linux/or1k/fpu_control.h
new file mode 100644
index 000000000..9abde4f42
--- /dev/null
+++ b/libc/sysdeps/linux/or1k/fpu_control.h
@@ -0,0 +1,88 @@
+/* FPU control word bits. OpenRISC version.
+ Copyright (C) 2024-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
+
+#ifndef __or1k_hard_float__
+
+# define _FPU_RESERVED 0xffffffff
+# define _FPU_DEFAULT 0x00000000
+# define _FPU_GETCW(cw) (cw) = 0
+# define _FPU_SETCW(cw) (void) (cw)
+
+#else /* __or1k_hard_float__ */
+
+/* Layout of FPCSR:
+
+ The bits of the FPCSR are defined as follows, this should help
+ explain how the masks below have come to be.
+
+ +-----------+----------------------------+-----+----+
+ | 32 - 12 | 11 10 9 8 7 6 5 4 3 | 2-1 | 0 |
+ +-----------+----------------------------+-----+----+
+ | Reserved | DZ IN IV IX Z QN SN UN OV | RM | EE |
+ +-----------+----------------------------+-----+----+
+
+ Exception flags:
+
+ DZ - divide by zero flag.
+ IN - infinite flag.
+ IV - invalid flag.
+ IX - inexact flag.
+ Z - zero flag.
+ QN - qnan flag.
+ SN - snan flag.
+ UN - underflow flag.
+ OV - overflow flag.
+
+ Rounding modes:
+
+ The FPCSR bits 2-1 labeled above as RM specify the rounding mode.
+
+ 00 - round to nearest
+ 01 - round to zero
+ 10 - round to positive infinity
+ 11 - round to negative infinity
+
+ Enabling exceptions:
+
+ EE - set to enable FPU exceptions.
+
+ */
+
+# define _FPU_RESERVED 0xfffff000
+/* Default: rounding to nearest with exceptions disabled. */
+# define _FPU_DEFAULT 0
+/* IEEE: Same as above with exceptions enabled. */
+# define _FPU_IEEE (_FPU_DEFAULT | 1)
+
+# define _FPU_FPCSR_RM_MASK (0x3 << 1)
+
+/* Macros for accessing the hardware control word. */
+# define _FPU_GETCW(cw) __asm__ volatile ("l.mfspr %0,r0,20" : "=r" (cw))
+# define _FPU_SETCW(cw) __asm__ volatile ("l.mtspr r0,%0,20" : : "r" (cw))
+
+#endif /* __or1k_hard_float__ */
+
+/* Type of the control word. */
+typedef unsigned int fpu_control_t;
+
+/* Default control word set at startup. */
+extern fpu_control_t __fpu_control;
+
+#endif /* fpu_control.h */
diff --git a/libc/sysdeps/linux/powerpc/bits/fcntl.h b/libc/sysdeps/linux/powerpc/bits/fcntl.h
index ef1beeca0..54e4894ec 100644
--- a/libc/sysdeps/linux/powerpc/bits/fcntl.h
+++ b/libc/sysdeps/linux/powerpc/bits/fcntl.h
@@ -245,3 +245,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len,
#endif
__END_DECLS
+/* Include generic Linux declarations. */
+#include <bits/fcntl-linux.h>
diff --git a/libc/sysdeps/linux/powerpc/bits/stat.h b/libc/sysdeps/linux/powerpc/bits/stat.h
index 7494586b5..ce2ebf896 100644
--- a/libc/sysdeps/linux/powerpc/bits/stat.h
+++ b/libc/sysdeps/linux/powerpc/bits/stat.h
@@ -59,7 +59,7 @@ struct stat
# else
__blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
# endif
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
@@ -99,7 +99,7 @@ struct stat64
__off64_t st_size; /* Size of file, in bytes. */
__blksize_t st_blksize; /* Optimal block size for I/O. */
__blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
diff --git a/libc/sysdeps/linux/riscv32/bits/fcntl.h b/libc/sysdeps/linux/riscv32/bits/fcntl.h
index a9d7c84e0..fdfb1805d 100644
--- a/libc/sysdeps/linux/riscv32/bits/fcntl.h
+++ b/libc/sysdeps/linux/riscv32/bits/fcntl.h
@@ -229,3 +229,6 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len,
#endif
__END_DECLS
+
+/* Include generic Linux declarations. */
+#include <bits/fcntl-linux.h>
diff --git a/libc/sysdeps/linux/riscv32/bits/fenv.h b/libc/sysdeps/linux/riscv32/bits/fenv.h
index a3f8031af..a6b828a76 100644
--- a/libc/sysdeps/linux/riscv32/bits/fenv.h
+++ b/libc/sysdeps/linux/riscv32/bits/fenv.h
@@ -64,10 +64,8 @@ typedef unsigned int fenv_t;
/* If the default argument is used we use this value. */
#define FE_DFL_ENV ((__const fenv_t *) -1)
-#if __GLIBC_USE (IEC_60559_BFP_EXT)
/* Type representing floating-point control modes. */
typedef unsigned int femode_t;
/* Default floating-point control modes. */
# define FE_DFL_MODE ((const femode_t *) -1L)
-#endif
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/riscv32/getcontext.S b/libc/sysdeps/linux/riscv32/getcontext.S
deleted file mode 100644
index 0b9e7c2d3..000000000
--- a/libc/sysdeps/linux/riscv32/getcontext.S
+++ /dev/null
@@ -1,74 +0,0 @@
-/* Save current context.
- Copyright (C) 2009-2018 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
- <http://www.gnu.org/licenses/>. */
-
-#include "ucontext-macros.h"
-
-/* int getcontext (ucontext_t *ucp) */
-
- .text
-LEAF (getcontext)
- SAVE_INT_REG (ra, 0, a0)
- SAVE_INT_REG (ra, 1, a0)
- SAVE_INT_REG (sp, 2, a0)
- SAVE_INT_REG (s0, 8, a0)
- SAVE_INT_REG (s1, 9, a0)
- SAVE_INT_REG (x0, 10, a0) /* return 0 by overwriting a0. */
- SAVE_INT_REG (s2, 18, a0)
- SAVE_INT_REG (s3, 19, a0)
- SAVE_INT_REG (s4, 20, a0)
- SAVE_INT_REG (s5, 21, a0)
- SAVE_INT_REG (s6, 22, a0)
- SAVE_INT_REG (s7, 23, a0)
- SAVE_INT_REG (s8, 24, a0)
- SAVE_INT_REG (s9, 25, a0)
- SAVE_INT_REG (s10, 26, a0)
- SAVE_INT_REG (s11, 27, a0)
-
-#ifndef __riscv_float_abi_soft
- frsr a1
-
- SAVE_FP_REG (fs0, 8, a0)
- SAVE_FP_REG (fs1, 9, a0)
- SAVE_FP_REG (fs2, 18, a0)
- SAVE_FP_REG (fs3, 19, a0)
- SAVE_FP_REG (fs4, 20, a0)
- SAVE_FP_REG (fs5, 21, a0)
- SAVE_FP_REG (fs6, 22, a0)
- SAVE_FP_REG (fs7, 23, a0)
- SAVE_FP_REG (fs8, 24, a0)
- SAVE_FP_REG (fs9, 25, a0)
- SAVE_FP_REG (fs10, 26, a0)
- SAVE_FP_REG (fs11, 27, a0)
-
- sw a1, MCONTEXT_FSR(a0)
-#endif /* __riscv_float_abi_soft */
-
-/* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */
- li a3, _NSIG8
- add a2, a0, UCONTEXT_SIGMASK
- mv a1, zero
- li a0, SIG_BLOCK
-
- li a7, SYS_ify (rt_sigprocmask)
- scall
- bltz a0, 99f
-
- ret
-
-99: j __syscall_error
-
-PSEUDO_END (getcontext)
diff --git a/libc/sysdeps/linux/riscv32/setcontext.S b/libc/sysdeps/linux/riscv32/setcontext.S
deleted file mode 100644
index 15cc17bd8..000000000
--- a/libc/sysdeps/linux/riscv32/setcontext.S
+++ /dev/null
@@ -1,112 +0,0 @@
-/* Set current context.
- Copyright (C) 2009-2018 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
- <http://www.gnu.org/licenses/>. */
-
-#include "ucontext-macros.h"
-
-/* int __setcontext (const ucontext_t *ucp)
-
- Restores the machine context in UCP and thereby resumes execution
- in that context.
-
- This implementation is intended to be used for *synchronous* context
- switches only. Therefore, it does not have to restore anything
- other than the PRESERVED state. */
-
- .text
-LEAF (setcontext)
-
- mv t0, a0 /* Save ucp into t0. */
-
-/* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, NULL, _NSIG8) */
- li a3, _NSIG8
- mv a2, zero
- add a1, a0, UCONTEXT_SIGMASK
- li a0, SIG_SETMASK
-
- li a7, SYS_ify (rt_sigprocmask)
- scall
-
- bltz a0, 99f
-
- cfi_def_cfa (t0, 0)
-
-#ifndef __riscv_float_abi_soft
- lw t1, MCONTEXT_FSR(t0)
-
- RESTORE_FP_REG_CFI (fs0, 8, t0)
- RESTORE_FP_REG_CFI (fs1, 9, t0)
- RESTORE_FP_REG_CFI (fs2, 18, t0)
- RESTORE_FP_REG_CFI (fs3, 19, t0)
- RESTORE_FP_REG_CFI (fs4, 20, t0)
- RESTORE_FP_REG_CFI (fs5, 21, t0)
- RESTORE_FP_REG_CFI (fs6, 22, t0)
- RESTORE_FP_REG_CFI (fs7, 23, t0)
- RESTORE_FP_REG_CFI (fs8, 24, t0)
- RESTORE_FP_REG_CFI (fs9, 25, t0)
- RESTORE_FP_REG_CFI (fs10, 26, t0)
- RESTORE_FP_REG_CFI (fs11, 27, t0)
-
- fssr t1
-#endif /* __riscv_float_abi_soft */
-
- /* Note the contents of argument registers will be random
- unless makecontext() has been called. */
- RESTORE_INT_REG (t1, 0, t0)
- RESTORE_INT_REG_CFI (ra, 1, t0)
- RESTORE_INT_REG (sp, 2, t0)
- RESTORE_INT_REG_CFI (s0, 8, t0)
- RESTORE_INT_REG_CFI (s1, 9, t0)
- RESTORE_INT_REG (a0, 10, t0)
- RESTORE_INT_REG (a1, 11, t0)
- RESTORE_INT_REG (a2, 12, t0)
- RESTORE_INT_REG (a3, 13, t0)
- RESTORE_INT_REG (a4, 14, t0)
- RESTORE_INT_REG (a5, 15, t0)
- RESTORE_INT_REG (a6, 16, t0)
- RESTORE_INT_REG (a7, 17, t0)
- RESTORE_INT_REG_CFI (s2, 18, t0)
- RESTORE_INT_REG_CFI (s3, 19, t0)
- RESTORE_INT_REG_CFI (s4, 20, t0)
- RESTORE_INT_REG_CFI (s5, 21, t0)
- RESTORE_INT_REG_CFI (s6, 22, t0)
- RESTORE_INT_REG_CFI (s7, 23, t0)
- RESTORE_INT_REG_CFI (s8, 24, t0)
- RESTORE_INT_REG_CFI (s9, 25, t0)
- RESTORE_INT_REG_CFI (s10, 26, t0)
- RESTORE_INT_REG_CFI (s11, 27, t0)
-
- jr t1
-
-99: j __syscall_error
-
-PSEUDO_END (setcontext)
-
-LEAF (start_context)
-
- /* Terminate call stack by noting ra == 0. Happily, s0 == 0 here. */
- cfi_register (ra, s0)
-
- /* Call the function passed to makecontext. */
- jalr s1
-
- /* Invoke subsequent context if present, else exit(0). */
- mv a0, s2
- beqz s2, 1f
- jal setcontext
-1: j exit
-
-PSEUDO_END (start_context)
diff --git a/libc/sysdeps/linux/riscv32/swapcontext.S b/libc/sysdeps/linux/riscv32/swapcontext.S
deleted file mode 100644
index f5e12b2db..000000000
--- a/libc/sysdeps/linux/riscv32/swapcontext.S
+++ /dev/null
@@ -1,122 +0,0 @@
-/* Save and set current context.
- Copyright (C) 2009-2018 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
- <http://www.gnu.org/licenses/>. */
-
-#include "ucontext-macros.h"
-
-/* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */
-
-LEAF (swapcontext)
- mv t0, a1 /* Save ucp into t0. */
-
- SAVE_INT_REG (ra, 0, a0)
- SAVE_INT_REG (ra, 1, a0)
- SAVE_INT_REG (sp, 2, a0)
- SAVE_INT_REG (s0, 8, a0)
- SAVE_INT_REG (s1, 9, a0)
- SAVE_INT_REG (x0, 10, a0) /* return 0 by overwriting a0. */
- SAVE_INT_REG (s2, 18, a0)
- SAVE_INT_REG (s3, 19, a0)
- SAVE_INT_REG (s4, 20, a0)
- SAVE_INT_REG (s5, 21, a0)
- SAVE_INT_REG (s6, 22, a0)
- SAVE_INT_REG (s7, 23, a0)
- SAVE_INT_REG (s8, 24, a0)
- SAVE_INT_REG (s9, 25, a0)
- SAVE_INT_REG (s10, 26, a0)
- SAVE_INT_REG (s11, 27, a0)
-
-#ifndef __riscv_float_abi_soft
- frsr a1
-
- SAVE_FP_REG (fs0, 8, a0)
- SAVE_FP_REG (fs1, 9, a0)
- SAVE_FP_REG (fs2, 18, a0)
- SAVE_FP_REG (fs3, 19, a0)
- SAVE_FP_REG (fs4, 20, a0)
- SAVE_FP_REG (fs5, 21, a0)
- SAVE_FP_REG (fs6, 22, a0)
- SAVE_FP_REG (fs7, 23, a0)
- SAVE_FP_REG (fs8, 24, a0)
- SAVE_FP_REG (fs9, 25, a0)
- SAVE_FP_REG (fs10, 26, a0)
- SAVE_FP_REG (fs11, 27, a0)
-
- sw a1, MCONTEXT_FSR(a0)
-#endif /* __riscv_float_abi_soft */
-
-/* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, &oucp->uc_sigmask, _NSIG8) */
- li a3, _NSIG8
- add a2, a0, UCONTEXT_SIGMASK
- add a1, t0, UCONTEXT_SIGMASK
- li a0, SIG_SETMASK
-
- li a7, SYS_ify (rt_sigprocmask)
- scall
-
- bltz a0, 99f
-
-#ifndef __riscv_float_abi_soft
- lw t1, MCONTEXT_FSR(t0)
-
- RESTORE_FP_REG (fs0, 8, t0)
- RESTORE_FP_REG (fs1, 9, t0)
- RESTORE_FP_REG (fs2, 18, t0)
- RESTORE_FP_REG (fs3, 19, t0)
- RESTORE_FP_REG (fs4, 20, t0)
- RESTORE_FP_REG (fs5, 21, t0)
- RESTORE_FP_REG (fs6, 22, t0)
- RESTORE_FP_REG (fs7, 23, t0)
- RESTORE_FP_REG (fs8, 24, t0)
- RESTORE_FP_REG (fs9, 25, t0)
- RESTORE_FP_REG (fs10, 26, t0)
- RESTORE_FP_REG (fs11, 27, t0)
-
- fssr t1
-#endif /* __riscv_float_abi_soft */
-
- /* Note the contents of argument registers will be random
- unless makecontext() has been called. */
- RESTORE_INT_REG (t1, 0, t0)
- RESTORE_INT_REG (ra, 1, t0)
- RESTORE_INT_REG (sp, 2, t0)
- RESTORE_INT_REG (s0, 8, t0)
- RESTORE_INT_REG (s1, 9, t0)
- RESTORE_INT_REG (a0, 10, t0)
- RESTORE_INT_REG (a1, 11, t0)
- RESTORE_INT_REG (a2, 12, t0)
- RESTORE_INT_REG (a3, 13, t0)
- RESTORE_INT_REG (a4, 14, t0)
- RESTORE_INT_REG (a5, 15, t0)
- RESTORE_INT_REG (a6, 16, t0)
- RESTORE_INT_REG (a7, 17, t0)
- RESTORE_INT_REG (s2, 18, t0)
- RESTORE_INT_REG (s3, 19, t0)
- RESTORE_INT_REG (s4, 20, t0)
- RESTORE_INT_REG (s5, 21, t0)
- RESTORE_INT_REG (s6, 22, t0)
- RESTORE_INT_REG (s7, 23, t0)
- RESTORE_INT_REG (s8, 24, t0)
- RESTORE_INT_REG (s9, 25, t0)
- RESTORE_INT_REG (s10, 26, t0)
- RESTORE_INT_REG (s11, 27, t0)
-
- jr t1
-
-
-99: j __syscall_error
-
-PSEUDO_END (swapcontext)
diff --git a/libc/sysdeps/linux/riscv32/sys/ucontext.h b/libc/sysdeps/linux/riscv32/sys/ucontext.h
index 2893ff359..308ccb8c2 100644
--- a/libc/sysdeps/linux/riscv32/sys/ucontext.h
+++ b/libc/sysdeps/linux/riscv32/sys/ucontext.h
@@ -83,10 +83,10 @@ typedef struct mcontext_t
} mcontext_t;
/* Userlevel context. */
-typedef struct ucontext_t
+typedef struct ucontext
{
unsigned long int __uc_flags;
- struct ucontext_t *uc_link;
+ struct ucontext *uc_link;
stack_t uc_stack;
sigset_t uc_sigmask;
/* There's some padding here to allow sigset_t to be expanded in the
diff --git a/libc/sysdeps/linux/riscv64/bits/fcntl.h b/libc/sysdeps/linux/riscv64/bits/fcntl.h
index a9d7c84e0..fdfb1805d 100644
--- a/libc/sysdeps/linux/riscv64/bits/fcntl.h
+++ b/libc/sysdeps/linux/riscv64/bits/fcntl.h
@@ -229,3 +229,6 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len,
#endif
__END_DECLS
+
+/* Include generic Linux declarations. */
+#include <bits/fcntl-linux.h>
diff --git a/libc/sysdeps/linux/riscv64/bits/fenv.h b/libc/sysdeps/linux/riscv64/bits/fenv.h
index a3f8031af..a6b828a76 100644
--- a/libc/sysdeps/linux/riscv64/bits/fenv.h
+++ b/libc/sysdeps/linux/riscv64/bits/fenv.h
@@ -64,10 +64,8 @@ typedef unsigned int fenv_t;
/* If the default argument is used we use this value. */
#define FE_DFL_ENV ((__const fenv_t *) -1)
-#if __GLIBC_USE (IEC_60559_BFP_EXT)
/* Type representing floating-point control modes. */
typedef unsigned int femode_t;
/* Default floating-point control modes. */
# define FE_DFL_MODE ((const femode_t *) -1L)
-#endif
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/riscv64/getcontext.S b/libc/sysdeps/linux/riscv64/getcontext.S
deleted file mode 100644
index 0b9e7c2d3..000000000
--- a/libc/sysdeps/linux/riscv64/getcontext.S
+++ /dev/null
@@ -1,74 +0,0 @@
-/* Save current context.
- Copyright (C) 2009-2018 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
- <http://www.gnu.org/licenses/>. */
-
-#include "ucontext-macros.h"
-
-/* int getcontext (ucontext_t *ucp) */
-
- .text
-LEAF (getcontext)
- SAVE_INT_REG (ra, 0, a0)
- SAVE_INT_REG (ra, 1, a0)
- SAVE_INT_REG (sp, 2, a0)
- SAVE_INT_REG (s0, 8, a0)
- SAVE_INT_REG (s1, 9, a0)
- SAVE_INT_REG (x0, 10, a0) /* return 0 by overwriting a0. */
- SAVE_INT_REG (s2, 18, a0)
- SAVE_INT_REG (s3, 19, a0)
- SAVE_INT_REG (s4, 20, a0)
- SAVE_INT_REG (s5, 21, a0)
- SAVE_INT_REG (s6, 22, a0)
- SAVE_INT_REG (s7, 23, a0)
- SAVE_INT_REG (s8, 24, a0)
- SAVE_INT_REG (s9, 25, a0)
- SAVE_INT_REG (s10, 26, a0)
- SAVE_INT_REG (s11, 27, a0)
-
-#ifndef __riscv_float_abi_soft
- frsr a1
-
- SAVE_FP_REG (fs0, 8, a0)
- SAVE_FP_REG (fs1, 9, a0)
- SAVE_FP_REG (fs2, 18, a0)
- SAVE_FP_REG (fs3, 19, a0)
- SAVE_FP_REG (fs4, 20, a0)
- SAVE_FP_REG (fs5, 21, a0)
- SAVE_FP_REG (fs6, 22, a0)
- SAVE_FP_REG (fs7, 23, a0)
- SAVE_FP_REG (fs8, 24, a0)
- SAVE_FP_REG (fs9, 25, a0)
- SAVE_FP_REG (fs10, 26, a0)
- SAVE_FP_REG (fs11, 27, a0)
-
- sw a1, MCONTEXT_FSR(a0)
-#endif /* __riscv_float_abi_soft */
-
-/* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */
- li a3, _NSIG8
- add a2, a0, UCONTEXT_SIGMASK
- mv a1, zero
- li a0, SIG_BLOCK
-
- li a7, SYS_ify (rt_sigprocmask)
- scall
- bltz a0, 99f
-
- ret
-
-99: j __syscall_error
-
-PSEUDO_END (getcontext)
diff --git a/libc/sysdeps/linux/riscv64/setcontext.S b/libc/sysdeps/linux/riscv64/setcontext.S
deleted file mode 100644
index 15cc17bd8..000000000
--- a/libc/sysdeps/linux/riscv64/setcontext.S
+++ /dev/null
@@ -1,112 +0,0 @@
-/* Set current context.
- Copyright (C) 2009-2018 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
- <http://www.gnu.org/licenses/>. */
-
-#include "ucontext-macros.h"
-
-/* int __setcontext (const ucontext_t *ucp)
-
- Restores the machine context in UCP and thereby resumes execution
- in that context.
-
- This implementation is intended to be used for *synchronous* context
- switches only. Therefore, it does not have to restore anything
- other than the PRESERVED state. */
-
- .text
-LEAF (setcontext)
-
- mv t0, a0 /* Save ucp into t0. */
-
-/* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, NULL, _NSIG8) */
- li a3, _NSIG8
- mv a2, zero
- add a1, a0, UCONTEXT_SIGMASK
- li a0, SIG_SETMASK
-
- li a7, SYS_ify (rt_sigprocmask)
- scall
-
- bltz a0, 99f
-
- cfi_def_cfa (t0, 0)
-
-#ifndef __riscv_float_abi_soft
- lw t1, MCONTEXT_FSR(t0)
-
- RESTORE_FP_REG_CFI (fs0, 8, t0)
- RESTORE_FP_REG_CFI (fs1, 9, t0)
- RESTORE_FP_REG_CFI (fs2, 18, t0)
- RESTORE_FP_REG_CFI (fs3, 19, t0)
- RESTORE_FP_REG_CFI (fs4, 20, t0)
- RESTORE_FP_REG_CFI (fs5, 21, t0)
- RESTORE_FP_REG_CFI (fs6, 22, t0)
- RESTORE_FP_REG_CFI (fs7, 23, t0)
- RESTORE_FP_REG_CFI (fs8, 24, t0)
- RESTORE_FP_REG_CFI (fs9, 25, t0)
- RESTORE_FP_REG_CFI (fs10, 26, t0)
- RESTORE_FP_REG_CFI (fs11, 27, t0)
-
- fssr t1
-#endif /* __riscv_float_abi_soft */
-
- /* Note the contents of argument registers will be random
- unless makecontext() has been called. */
- RESTORE_INT_REG (t1, 0, t0)
- RESTORE_INT_REG_CFI (ra, 1, t0)
- RESTORE_INT_REG (sp, 2, t0)
- RESTORE_INT_REG_CFI (s0, 8, t0)
- RESTORE_INT_REG_CFI (s1, 9, t0)
- RESTORE_INT_REG (a0, 10, t0)
- RESTORE_INT_REG (a1, 11, t0)
- RESTORE_INT_REG (a2, 12, t0)
- RESTORE_INT_REG (a3, 13, t0)
- RESTORE_INT_REG (a4, 14, t0)
- RESTORE_INT_REG (a5, 15, t0)
- RESTORE_INT_REG (a6, 16, t0)
- RESTORE_INT_REG (a7, 17, t0)
- RESTORE_INT_REG_CFI (s2, 18, t0)
- RESTORE_INT_REG_CFI (s3, 19, t0)
- RESTORE_INT_REG_CFI (s4, 20, t0)
- RESTORE_INT_REG_CFI (s5, 21, t0)
- RESTORE_INT_REG_CFI (s6, 22, t0)
- RESTORE_INT_REG_CFI (s7, 23, t0)
- RESTORE_INT_REG_CFI (s8, 24, t0)
- RESTORE_INT_REG_CFI (s9, 25, t0)
- RESTORE_INT_REG_CFI (s10, 26, t0)
- RESTORE_INT_REG_CFI (s11, 27, t0)
-
- jr t1
-
-99: j __syscall_error
-
-PSEUDO_END (setcontext)
-
-LEAF (start_context)
-
- /* Terminate call stack by noting ra == 0. Happily, s0 == 0 here. */
- cfi_register (ra, s0)
-
- /* Call the function passed to makecontext. */
- jalr s1
-
- /* Invoke subsequent context if present, else exit(0). */
- mv a0, s2
- beqz s2, 1f
- jal setcontext
-1: j exit
-
-PSEUDO_END (start_context)
diff --git a/libc/sysdeps/linux/riscv64/swapcontext.S b/libc/sysdeps/linux/riscv64/swapcontext.S
deleted file mode 100644
index f5e12b2db..000000000
--- a/libc/sysdeps/linux/riscv64/swapcontext.S
+++ /dev/null
@@ -1,122 +0,0 @@
-/* Save and set current context.
- Copyright (C) 2009-2018 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
- <http://www.gnu.org/licenses/>. */
-
-#include "ucontext-macros.h"
-
-/* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */
-
-LEAF (swapcontext)
- mv t0, a1 /* Save ucp into t0. */
-
- SAVE_INT_REG (ra, 0, a0)
- SAVE_INT_REG (ra, 1, a0)
- SAVE_INT_REG (sp, 2, a0)
- SAVE_INT_REG (s0, 8, a0)
- SAVE_INT_REG (s1, 9, a0)
- SAVE_INT_REG (x0, 10, a0) /* return 0 by overwriting a0. */
- SAVE_INT_REG (s2, 18, a0)
- SAVE_INT_REG (s3, 19, a0)
- SAVE_INT_REG (s4, 20, a0)
- SAVE_INT_REG (s5, 21, a0)
- SAVE_INT_REG (s6, 22, a0)
- SAVE_INT_REG (s7, 23, a0)
- SAVE_INT_REG (s8, 24, a0)
- SAVE_INT_REG (s9, 25, a0)
- SAVE_INT_REG (s10, 26, a0)
- SAVE_INT_REG (s11, 27, a0)
-
-#ifndef __riscv_float_abi_soft
- frsr a1
-
- SAVE_FP_REG (fs0, 8, a0)
- SAVE_FP_REG (fs1, 9, a0)
- SAVE_FP_REG (fs2, 18, a0)
- SAVE_FP_REG (fs3, 19, a0)
- SAVE_FP_REG (fs4, 20, a0)
- SAVE_FP_REG (fs5, 21, a0)
- SAVE_FP_REG (fs6, 22, a0)
- SAVE_FP_REG (fs7, 23, a0)
- SAVE_FP_REG (fs8, 24, a0)
- SAVE_FP_REG (fs9, 25, a0)
- SAVE_FP_REG (fs10, 26, a0)
- SAVE_FP_REG (fs11, 27, a0)
-
- sw a1, MCONTEXT_FSR(a0)
-#endif /* __riscv_float_abi_soft */
-
-/* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, &oucp->uc_sigmask, _NSIG8) */
- li a3, _NSIG8
- add a2, a0, UCONTEXT_SIGMASK
- add a1, t0, UCONTEXT_SIGMASK
- li a0, SIG_SETMASK
-
- li a7, SYS_ify (rt_sigprocmask)
- scall
-
- bltz a0, 99f
-
-#ifndef __riscv_float_abi_soft
- lw t1, MCONTEXT_FSR(t0)
-
- RESTORE_FP_REG (fs0, 8, t0)
- RESTORE_FP_REG (fs1, 9, t0)
- RESTORE_FP_REG (fs2, 18, t0)
- RESTORE_FP_REG (fs3, 19, t0)
- RESTORE_FP_REG (fs4, 20, t0)
- RESTORE_FP_REG (fs5, 21, t0)
- RESTORE_FP_REG (fs6, 22, t0)
- RESTORE_FP_REG (fs7, 23, t0)
- RESTORE_FP_REG (fs8, 24, t0)
- RESTORE_FP_REG (fs9, 25, t0)
- RESTORE_FP_REG (fs10, 26, t0)
- RESTORE_FP_REG (fs11, 27, t0)
-
- fssr t1
-#endif /* __riscv_float_abi_soft */
-
- /* Note the contents of argument registers will be random
- unless makecontext() has been called. */
- RESTORE_INT_REG (t1, 0, t0)
- RESTORE_INT_REG (ra, 1, t0)
- RESTORE_INT_REG (sp, 2, t0)
- RESTORE_INT_REG (s0, 8, t0)
- RESTORE_INT_REG (s1, 9, t0)
- RESTORE_INT_REG (a0, 10, t0)
- RESTORE_INT_REG (a1, 11, t0)
- RESTORE_INT_REG (a2, 12, t0)
- RESTORE_INT_REG (a3, 13, t0)
- RESTORE_INT_REG (a4, 14, t0)
- RESTORE_INT_REG (a5, 15, t0)
- RESTORE_INT_REG (a6, 16, t0)
- RESTORE_INT_REG (a7, 17, t0)
- RESTORE_INT_REG (s2, 18, t0)
- RESTORE_INT_REG (s3, 19, t0)
- RESTORE_INT_REG (s4, 20, t0)
- RESTORE_INT_REG (s5, 21, t0)
- RESTORE_INT_REG (s6, 22, t0)
- RESTORE_INT_REG (s7, 23, t0)
- RESTORE_INT_REG (s8, 24, t0)
- RESTORE_INT_REG (s9, 25, t0)
- RESTORE_INT_REG (s10, 26, t0)
- RESTORE_INT_REG (s11, 27, t0)
-
- jr t1
-
-
-99: j __syscall_error
-
-PSEUDO_END (swapcontext)
diff --git a/libc/sysdeps/linux/riscv64/sys/ucontext.h b/libc/sysdeps/linux/riscv64/sys/ucontext.h
index 2893ff359..308ccb8c2 100644
--- a/libc/sysdeps/linux/riscv64/sys/ucontext.h
+++ b/libc/sysdeps/linux/riscv64/sys/ucontext.h
@@ -83,10 +83,10 @@ typedef struct mcontext_t
} mcontext_t;
/* Userlevel context. */
-typedef struct ucontext_t
+typedef struct ucontext
{
unsigned long int __uc_flags;
- struct ucontext_t *uc_link;
+ struct ucontext *uc_link;
stack_t uc_stack;
sigset_t uc_sigmask;
/* There's some padding here to allow sigset_t to be expanded in the
diff --git a/libc/sysdeps/linux/sh/bits/fcntl.h b/libc/sysdeps/linux/sh/bits/fcntl.h
index 0d687f04f..4ae682425 100644
--- a/libc/sysdeps/linux/sh/bits/fcntl.h
+++ b/libc/sysdeps/linux/sh/bits/fcntl.h
@@ -245,3 +245,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len,
#endif
__END_DECLS
+/* Include generic Linux declarations. */
+#include <bits/fcntl-linux.h>
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/fcntl.h b/libc/sysdeps/linux/sparc/bits/fcntl.h
index 935495937..35224cdb3 100644
--- a/libc/sysdeps/linux/sparc/bits/fcntl.h
+++ b/libc/sysdeps/linux/sparc/bits/fcntl.h
@@ -252,3 +252,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len,
#endif
__END_DECLS
+/* Include generic Linux declarations. */
+#include <bits/fcntl-linux.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/bits/stat.h b/libc/sysdeps/linux/sparc/bits/stat.h
index b88885fe2..0fbef8b3f 100644
--- a/libc/sysdeps/linux/sparc/bits/stat.h
+++ b/libc/sysdeps/linux/sparc/bits/stat.h
@@ -53,7 +53,7 @@ struct stat
#else
__blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
#endif
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
@@ -93,7 +93,7 @@ struct stat64
__blksize_t st_blksize; /* Optimal block size for I/O. */
__blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
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/libc/sysdeps/linux/sparc64/bits/fcntl.h b/libc/sysdeps/linux/sparc64/bits/fcntl.h
index 395c95baf..00e91a671 100644
--- a/libc/sysdeps/linux/sparc64/bits/fcntl.h
+++ b/libc/sysdeps/linux/sparc64/bits/fcntl.h
@@ -248,3 +248,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len,
#endif
__END_DECLS
+/* Include generic Linux declarations. */
+#include <bits/fcntl-linux.h>
diff --git a/libc/sysdeps/linux/sparc64/bits/stat.h b/libc/sysdeps/linux/sparc64/bits/stat.h
index 8516b159c..62b48b745 100644
--- a/libc/sysdeps/linux/sparc64/bits/stat.h
+++ b/libc/sysdeps/linux/sparc64/bits/stat.h
@@ -58,7 +58,7 @@ struct stat
#else
__blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
#endif
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
@@ -101,7 +101,7 @@ struct stat64
__blksize_t st_blksize; /* Optimal block size for I/O. */
__blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
diff --git a/libc/sysdeps/linux/tile/bits/fcntl.h b/libc/sysdeps/linux/tile/bits/fcntl.h
index 818da5c4a..28fda899d 100644
--- a/libc/sysdeps/linux/tile/bits/fcntl.h
+++ b/libc/sysdeps/linux/tile/bits/fcntl.h
@@ -229,3 +229,6 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len,
#endif
__END_DECLS
+
+/* Include generic Linux declarations. */
+#include <bits/fcntl-linux.h>
diff --git a/libc/sysdeps/linux/tile/sys/ucontext.h b/libc/sysdeps/linux/tile/sys/ucontext.h
index ed2c27b58..068da8c4a 100644
--- a/libc/sysdeps/linux/tile/sys/ucontext.h
+++ b/libc/sysdeps/linux/tile/sys/ucontext.h
@@ -82,10 +82,10 @@ typedef struct
} mcontext_t;
/* Userlevel context. */
-typedef struct ucontext_t
+typedef struct ucontext
{
unsigned long int __ctx(uc_flags);
- struct ucontext_t *uc_link;
+ struct ucontext *uc_link;
stack_t uc_stack;
mcontext_t uc_mcontext;
sigset_t uc_sigmask;
diff --git a/libc/sysdeps/linux/x86_64/bits/fcntl.h b/libc/sysdeps/linux/x86_64/bits/fcntl.h
index 3547a2046..821b2e3cc 100644
--- a/libc/sysdeps/linux/x86_64/bits/fcntl.h
+++ b/libc/sysdeps/linux/x86_64/bits/fcntl.h
@@ -259,3 +259,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len,
#endif
__END_DECLS
+/* Include generic Linux declarations. */
+#include <bits/fcntl-linux.h>
diff --git a/libc/sysdeps/linux/x86_64/bits/stat.h b/libc/sysdeps/linux/x86_64/bits/stat.h
index a7412c8f9..a8c75feaa 100644
--- a/libc/sysdeps/linux/x86_64/bits/stat.h
+++ b/libc/sysdeps/linux/x86_64/bits/stat.h
@@ -77,7 +77,7 @@ struct stat
#else
__blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
#endif
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
@@ -138,7 +138,7 @@ struct stat64
#endif
__blksize_t st_blksize; /* Optimal block size for I/O. */
__blkcnt64_t st_blocks; /* Nr. 512-byte blocks allocated. */
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
diff --git a/libc/sysdeps/linux/x86_64/crt1.S b/libc/sysdeps/linux/x86_64/crt1.S
index 701cbf2f6..151aeffeb 100644
--- a/libc/sysdeps/linux/x86_64/crt1.S
+++ b/libc/sysdeps/linux/x86_64/crt1.S
@@ -83,11 +83,7 @@ _start:
#ifdef L_rcrt1
pushq %rdi /* save rdi (but should be 0...) */
pushq %rdx /* store rdx (rtld_fini) */
- xorq %rcx, %rcx /* ensure rcx is 0 */
- addq _start@GOTPCREL(%rip), %rcx /* get offset of _start from beginning of file */
- movq _start@GOTPCREL(%rip), %rax /* get run time address of _start */
- subq %rcx, %rax /* calculate run time load offset */
- movq %rax, %rdi /* load offset -> param 1 */
+ lea __ehdr_start(%rip), %rdi /* "Calculate" load address... */
call reloc_static_pie /* relocate dynamic addrs */
xorq %rax, %rax /* cleanup */
popq %rdx
diff --git a/libc/sysdeps/linux/xtensa/__start_context.S b/libc/sysdeps/linux/xtensa/__start_context.S
index a30d7b618..e6ce93347 100644
--- a/libc/sysdeps/linux/xtensa/__start_context.S
+++ b/libc/sysdeps/linux/xtensa/__start_context.S
@@ -22,9 +22,10 @@
* There's no entry instruction, makecontext sets up ucontext_t as if
* getcontext was called above and is about to return here.
* Registers on entry to this function:
- * a12: func to call
+ * a12: func to call (function descriptor in case of FDPIC)
* a13: ucp->uc_link, next context to activate if func returns
* a14: func argc
+ * a15: current GOT pointer (in case of FDPIC)
*/
.literal_position
@@ -46,14 +47,17 @@ ENTRY_PREFIX(__start_context)
addi a1, a1, 16
/* func arguments 6..argc - 1 are now at the top of the stack */
1:
+ FDPIC_LOAD_FUNCDESC (a12, a12)
callx0 a12
beqz a13, 1f
mov a2, a13
movi a4, JUMPTARGET (setcontext)
+ FDPIC_LOAD_JUMPTARGET (a4, a15, a4)
callx0 a4
1:
movi a4, JUMPTARGET (_exit)
movi a2, 0
+ FDPIC_LOAD_JUMPTARGET (a4, a15, a4)
callx0 a4
ill
END(__start_context)
diff --git a/libc/sysdeps/linux/xtensa/bits/elf-fdpic.h b/libc/sysdeps/linux/xtensa/bits/elf-fdpic.h
new file mode 100644
index 000000000..19bb247b8
--- /dev/null
+++ b/libc/sysdeps/linux/xtensa/bits/elf-fdpic.h
@@ -0,0 +1,117 @@
+/* Copyright 2003, 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.
+
+In addition to the permissions in the GNU Lesser General Public
+License, the Free Software Foundation gives you unlimited
+permission to link the compiled version of this file with other
+programs, and to distribute those programs without any restriction
+coming from the use of this file. (The GNU Lesser General Public
+License restrictions do apply in other respects; for example, they
+cover modification of the file, and distribution when not linked
+into another program.)
+
+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
+Library 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; see the file COPYING.LIB. If
+not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef _BITS_ELF_FDPIC_H
+#define _BITS_ELF_FDPIC_H
+
+/* These data structures are described in the FDPIC ABI extension.
+ The kernel passes a process a memory map, such that for every LOAD
+ segment there is an elf32_fdpic_loadseg entry. A pointer to an
+ elf32_fdpic_loadmap is passed in r7 at start-up, and a pointer to
+ an additional such map is passed in r8 for the interpreter, when
+ there is one. */
+
+#include <elf.h>
+
+/* This data structure represents a PT_LOAD segment. */
+struct elf32_fdpic_loadseg
+{
+ /* Core address to which the segment is mapped. */
+ Elf32_Addr addr;
+ /* VMA recorded in the program header. */
+ Elf32_Addr p_vaddr;
+ /* Size of this segment in memory. */
+ Elf32_Word p_memsz;
+};
+
+struct elf32_fdpic_loadmap {
+ /* Protocol version number, must be zero. */
+ Elf32_Half version;
+ /* Number of segments in this map. */
+ Elf32_Half nsegs;
+ /* The actual memory map. */
+ struct elf32_fdpic_loadseg segs[/*nsegs*/];
+};
+
+struct elf32_fdpic_loadaddr {
+ struct elf32_fdpic_loadmap *map;
+ void *got_value;
+};
+
+/* Map a pointer's VMA to its corresponding address according to the
+ load map. */
+static __always_inline void *
+__reloc_pointer (void *p,
+ const struct elf32_fdpic_loadmap *map)
+{
+ int c;
+
+#if 0
+ if (map->version != 0)
+ /* Crash. */
+ ((void(*)())0)();
+#endif
+
+ /* No special provision is made for NULL. We don't want NULL
+ addresses to go through relocation, so they shouldn't be in
+ .rofixup sections, and, if they're present in dynamic
+ relocations, they shall be mapped to the NULL address without
+ undergoing relocations. */
+
+ for (c = 0;
+ /* Take advantage of the fact that the loadmap is ordered by
+ virtual addresses. In general there will only be 2 entries,
+ so it's not profitable to do a binary search. */
+ c < map->nsegs && p >= (void*)map->segs[c].p_vaddr;
+ c++)
+ {
+ /* This should be computed as part of the pointer comparison
+ above, but we want to use the carry in the comparison, so we
+ can't convert it to an integer type beforehand. */
+ unsigned long offset = (char*)p - (char*)map->segs[c].p_vaddr;
+ /* We only check for one-past-the-end for the last segment,
+ assumed to be the data segment, because other cases are
+ ambiguous in the absence of padding between segments, and
+ rofixup already serves as padding between text and data.
+ Unfortunately, unless we special-case the last segment, we
+ fail to relocate the _end symbol. */
+ if (offset < map->segs[c].p_memsz
+ || (offset == map->segs[c].p_memsz && c + 1 == map->nsegs))
+ return (char*)map->segs[c].addr + offset;
+ }
+
+ /* We might want to crash instead. */
+ return (void*)-1;
+}
+
+# define __RELOC_POINTER(ptr, loadaddr) \
+ (__reloc_pointer ((void*)(ptr), \
+ (loadaddr).map))
+
+void*
+__self_reloc (const struct elf32_fdpic_loadmap *map, void ***p, void ***e);
+
+#endif /* _BITS_ELF_FDPIC_H */
diff --git a/libc/sysdeps/linux/xtensa/bits/fcntl.h b/libc/sysdeps/linux/xtensa/bits/fcntl.h
index 5af9d2124..9bc5fa893 100644
--- a/libc/sysdeps/linux/xtensa/bits/fcntl.h
+++ b/libc/sysdeps/linux/xtensa/bits/fcntl.h
@@ -245,3 +245,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len,
#endif
__END_DECLS
+/* Include generic Linux declarations. */
+#include <bits/fcntl-linux.h>
diff --git a/libc/sysdeps/linux/xtensa/bits/stat.h b/libc/sysdeps/linux/xtensa/bits/stat.h
index 045a017fd..43af825ec 100644
--- a/libc/sysdeps/linux/xtensa/bits/stat.h
+++ b/libc/sysdeps/linux/xtensa/bits/stat.h
@@ -54,7 +54,7 @@ struct stat
unsigned long __pad2;
__blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
#endif
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
@@ -94,7 +94,7 @@ struct stat64
unsigned long __pad2;
__blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
diff --git a/libc/sysdeps/linux/xtensa/bits/xtensa-config.h b/libc/sysdeps/linux/xtensa/bits/xtensa-config.h
index b99928b1e..bfcd571d2 100644
--- a/libc/sysdeps/linux/xtensa/bits/xtensa-config.h
+++ b/libc/sysdeps/linux/xtensa/bits/xtensa-config.h
@@ -32,21 +32,41 @@
macros. */
#undef XCHAL_HAVE_NSA
+#ifdef __XCHAL_HAVE_NSA
+#define XCHAL_HAVE_NSA __XCHAL_HAVE_NSA
+#else
#define XCHAL_HAVE_NSA 1
+#endif
#undef XCHAL_HAVE_LOOPS
+#ifdef __XCHAL_HAVE_LOOPS
+#define XCHAL_HAVE_LOOPS __XCHAL_HAVE_LOOPS
+#else
#define XCHAL_HAVE_LOOPS 1
+#endif
/* Assume the maximum number of AR registers. This currently only affects
the __window_spill function, and it is always safe to flush extra. */
#undef XCHAL_NUM_AREGS
+#ifdef __XCHAL_NUM_AREGS
+#define XCHAL_NUM_AREGS __XCHAL_NUM_AREGS
+#else
#define XCHAL_NUM_AREGS 64
+#endif
#undef XCHAL_HAVE_S32C1I
+#ifdef __XCHAL_HAVE_S32C1I
+#define XCHAL_HAVE_S32C1I __XCHAL_HAVE_S32C1I
+#else
#define XCHAL_HAVE_S32C1I 1
+#endif
#undef XCHAL_HAVE_EXCLUSIVE
+#ifdef __XCHAL_HAVE_EXCLUSIVE
+#define XCHAL_HAVE_EXCLUSIVE __XCHAL_HAVE_EXCLUSIVE
+#else
#define XCHAL_HAVE_EXCLUSIVE 0
+#endif
#endif /* !XTENSA_CONFIG_H */
diff --git a/libc/sysdeps/linux/xtensa/clone.S b/libc/sysdeps/linux/xtensa/clone.S
index ebfdcc1f6..a11044cd0 100644
--- a/libc/sysdeps/linux/xtensa/clone.S
+++ b/libc/sysdeps/linux/xtensa/clone.S
@@ -81,11 +81,17 @@ ENTRY (__clone)
callx4 a2
#elif defined(__XTENSA_CALL0_ABI__)
mov a2, a9 /* load up the 'arg' parameter */
+#ifdef __FDPIC__
+ mov a12, a11
+ l32i a11, a7, 4
+ l32i a7, a7, 0
+#endif
callx0 a7 /* call the user's function */
/* Call _exit. Note that any return parameter from the user's
function in a2 is seen as inputs to _exit. */
movi a0, JUMPTARGET(_exit)
+ FDPIC_LOAD_JUMPTARGET(a0, a12, a0)
callx0 a0
#else
#error Unsupported Xtensa ABI
diff --git a/libc/sysdeps/linux/xtensa/crt1.S b/libc/sysdeps/linux/xtensa/crt1.S
index 3fa14ae58..a12f82dd6 100644
--- a/libc/sysdeps/linux/xtensa/crt1.S
+++ b/libc/sysdeps/linux/xtensa/crt1.S
@@ -35,6 +35,86 @@
#include <features.h>
+#if defined(__FDPIC__)
+
+/* This is the canonical entry point, usually the first thing in the text
+ segment. When the entry point runs, most register values are unspecified,
+ except for:
+
+ a6 Address of .dynamic section
+ a5 Interpreter map
+ a4 Executable map
+
+ a2 Contains a function pointer to be registered with `atexit'.
+ This is how the dynamic linker arranges to have DT_FINI
+ functions called for shared libraries that have been loaded
+ before this code runs.
+
+ a1 The stack (i.e., a1+16) contains the arguments and environment:
+ a1+0 argc
+ a1+4 argv[0]
+ ...
+ a1+(4*argc) NULL
+ a1+(4*(argc+1)) envp[0]
+ ...
+ NULL
+ */
+ .text
+ .align 4
+ .literal_position
+ .global _start
+ .type _start, @function
+_start:
+#if defined(__XTENSA_CALL0_ABI__)
+
+ .begin no-transform
+ call0 1f
+2:
+ .end no-transform
+ .align 4
+ .literal_position
+1:
+ movi a15, 2b
+ sub a15, a0, a15
+
+ mov a12, a4
+ mov a13, a5
+ mov a14, a6
+ mov a2, a4
+ movi a3, __ROFIXUP_LIST__
+ add a3, a3, a15
+ movi a4, __ROFIXUP_END__
+ add a4, a4, a15
+ movi a0, __self_reloc
+ add a0, a0, a15
+ callx0 a0
+
+ mov a11, a2
+ movi a2, main@GOTOFFFUNCDESC
+ add a2, a2, a11
+ l32i a3, sp, 0 /* argc */
+ addi a4, sp, 4 /* argv */
+ /* a5 is either 0 when static or set by the RTLD to the rtld_fini */
+ mov a7, a13
+ /* unused stack_end argument is what used to be argc */
+ movi a5, _init@GOTOFFFUNCDESC
+ add a5, a5, a11
+ movi a6, _fini@GOTOFFFUNCDESC
+ add a6, a6, a11
+
+ movi a0, __uClibc_main@GOTOFFFUNCDESC
+ add a0, a0, a11
+ l32i a11, a0, 4
+ l32i a0, a0, 0
+ callx0 a0
+ ill
+
+#else
+#error Unsupported Xtensa ABI
+#endif
+
+#else /* defined(__FDPIC__) */
+
#ifndef __UCLIBC_CTOR_DTOR__
.weak _init
.weak _fini
@@ -173,3 +253,4 @@ __data_start:
.long 0
.weak data_start
data_start = __data_start
+#endif /* defined(__FDPIC__) */
diff --git a/libc/sysdeps/linux/xtensa/crti.S b/libc/sysdeps/linux/xtensa/crti.S
index ba804eb45..2923ff09d 100644
--- a/libc/sysdeps/linux/xtensa/crti.S
+++ b/libc/sysdeps/linux/xtensa/crti.S
@@ -3,6 +3,7 @@
.section .init
.align 4
.global _init
+ .hidden _init
.type _init, @function
_init:
#if defined(__XTENSA_WINDOWED_ABI__)
@@ -10,6 +11,10 @@ _init:
#elif defined(__XTENSA_CALL0_ABI__)
addi sp, sp, -16
s32i a0, sp, 0
+#ifdef __FDPIC__
+ s32i a12, sp, 4
+ mov a12, a11
+#endif
#else
#error Unsupported Xtensa ABI
#endif
@@ -17,6 +22,7 @@ _init:
.section .fini
.align 4
.global _fini
+ .hidden _fini
.type _fini, @function
_fini:
#if defined(__XTENSA_WINDOWED_ABI__)
@@ -24,6 +30,10 @@ _fini:
#elif defined(__XTENSA_CALL0_ABI__)
addi sp, sp, -16
s32i a0, sp, 0
+#ifdef __FDPIC__
+ s32i a12, sp, 4
+ mov a12, a11
+#endif
#else
#error Unsupported Xtensa ABI
#endif
diff --git a/libc/sysdeps/linux/xtensa/crtn.S b/libc/sysdeps/linux/xtensa/crtn.S
index a3598da1a..6f797e8bd 100644
--- a/libc/sysdeps/linux/xtensa/crtn.S
+++ b/libc/sysdeps/linux/xtensa/crtn.S
@@ -4,6 +4,9 @@
#if defined(__XTENSA_WINDOWED_ABI__)
retw
#elif defined(__XTENSA_CALL0_ABI__)
+#ifdef __FDPIC__
+ l32i a12, sp, 4
+#endif
l32i a0, sp, 0
addi sp, sp, 16
ret
@@ -15,6 +18,9 @@
#if defined(__XTENSA_WINDOWED_ABI__)
retw
#elif defined(__XTENSA_CALL0_ABI__)
+#ifdef __FDPIC__
+ l32i a12, sp, 4
+#endif
l32i a0, sp, 0
addi sp, sp, 16
ret
diff --git a/libc/sysdeps/linux/xtensa/crtreloc.c b/libc/sysdeps/linux/xtensa/crtreloc.c
new file mode 100644
index 000000000..697ef91ab
--- /dev/null
+++ b/libc/sysdeps/linux/xtensa/crtreloc.c
@@ -0,0 +1,105 @@
+/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ written by Alexandre Oliva <aoliva@redhat.com>
+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.
+
+In addition to the permissions in the GNU Lesser General Public
+License, the Free Software Foundation gives you unlimited
+permission to link the compiled version of this file with other
+programs, and to distribute those programs without any restriction
+coming from the use of this file. (The GNU Lesser General Public
+License restrictions do apply in other respects; for example, they
+cover modification of the file, and distribution when not linked
+into another program.)
+
+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
+Library 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; see the file COPYING.LIB. If
+not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef __FDPIC__
+
+#include <sys/types.h>
+#include <link.h>
+
+/* This file is to be compiled into crt object files, to enable
+ executables to easily self-relocate. */
+
+/* Compute the runtime address of pointer in the range [p,e), and then
+ map the pointer pointed by it. */
+static __always_inline void ***
+reloc_range_indirect (void ***p, void ***e,
+ const struct elf32_fdpic_loadmap *map)
+{
+ while (p < e)
+ {
+ if (*p != (void **)-1)
+ {
+ void *ptr = __reloc_pointer (*p, map);
+
+ if (ptr != (void *)-1)
+ {
+ unsigned long off = ((unsigned long)ptr & 3) * 8;
+ unsigned long *pa = (unsigned long *)((unsigned long)ptr & -4);
+ unsigned long v2;
+ void *pt;
+
+ if (off)
+ {
+ unsigned long v0, v1;
+#ifdef __XTENSA_EB__
+ v0 = pa[1]; v1 = pa[0];
+ v2 = (v1 >> (32 - off)) | (v0 << off);
+#else /* __XTENSA_EL__ */
+ v0 = pa[0]; v1 = pa[1];
+ v2 = (v0 << (32 - off)) | (v1 >> off);
+#endif
+ pt = (void *)((v1 << (32 - off)) | (v0 >> off));
+ }
+ else
+ pt = *(void**)ptr;
+ pt = __reloc_pointer (pt, map);
+ if (off)
+ {
+ unsigned long v = (unsigned long)pt;
+#ifdef __XTENSA_EB__
+ pa[0] = (v2 << (32 - off)) | (v >> off);
+ pa[1] = (v << (32 - off)) | (v2 >> off);
+#else /* __XTENSA_EL__ */
+ pa[0] = (v2 >> (32 - off)) | (v << off);
+ pa[1] = (v >> (32 - off)) | (v2 << off);
+#endif
+ }
+ else
+ *(void**)ptr = pt;
+ }
+ }
+ p++;
+ }
+ return p;
+}
+
+/* Call __reloc_range_indirect for the given range except for the last
+ entry, whose contents are only relocated. It's expected to hold
+ the GOT value. */
+attribute_hidden void*
+__self_reloc (const struct elf32_fdpic_loadmap *map,
+ void ***p, void ***e)
+{
+ p = reloc_range_indirect (p, e-1, map);
+
+ if (p >= e)
+ return (void*)-1;
+
+ return __reloc_pointer (*p, map);
+}
+
+#endif /* __FDPIC__ */
diff --git a/libc/sysdeps/linux/xtensa/getcontext.S b/libc/sysdeps/linux/xtensa/getcontext.S
index 7588a91b3..4cc644552 100644
--- a/libc/sysdeps/linux/xtensa/getcontext.S
+++ b/libc/sysdeps/linux/xtensa/getcontext.S
@@ -33,6 +33,7 @@ ENTRY(__getcontext)
addi a4, a2, UCONTEXT_SIGMASK
movi a2, SIG_BLOCK
movi a5, JUMPTARGET (sigprocmask)
+ FDPIC_LOAD_JUMPTARGET (a5, a11, a5)
jx a5
END(__getcontext)
#elif defined(__XTENSA_WINDOWED_ABI__)
diff --git a/libc/sysdeps/linux/xtensa/makecontext.c b/libc/sysdeps/linux/xtensa/makecontext.c
index da26a0130..0a8f7116f 100644
--- a/libc/sysdeps/linux/xtensa/makecontext.c
+++ b/libc/sysdeps/linux/xtensa/makecontext.c
@@ -73,7 +73,12 @@ __makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
sp -= 4 * (argc + 2);
sp &= -16;
+#ifdef __FDPIC__
+ ucp->uc_mcontext.sc_pc = ((unsigned long *) __start_context)[0];
+ ucp->uc_mcontext.sc_a[15] = ((unsigned long *) __start_context)[1];
+#else
ucp->uc_mcontext.sc_pc = (unsigned long) __start_context;
+#endif
ucp->uc_mcontext.sc_a[1] = sp;
ucp->uc_mcontext.sc_a[12] = (unsigned long) func;
ucp->uc_mcontext.sc_a[13] = (unsigned long) ucp->uc_link;
diff --git a/libc/sysdeps/linux/xtensa/setcontext.S b/libc/sysdeps/linux/xtensa/setcontext.S
index 4df7cc049..72915ef8d 100644
--- a/libc/sysdeps/linux/xtensa/setcontext.S
+++ b/libc/sysdeps/linux/xtensa/setcontext.S
@@ -28,6 +28,7 @@ ENTRY(__setcontext)
movi a4, 0
movi a2, SIG_SETMASK
movi a5, JUMPTARGET (sigprocmask)
+ FDPIC_LOAD_JUMPTARGET (a5, a11, a5)
callx0 a5
bnez a2, .Lerror
diff --git a/libc/sysdeps/linux/xtensa/setjmp.S b/libc/sysdeps/linux/xtensa/setjmp.S
index b8152fdd8..d629c11a8 100644
--- a/libc/sysdeps/linux/xtensa/setjmp.S
+++ b/libc/sysdeps/linux/xtensa/setjmp.S
@@ -155,7 +155,8 @@ ENTRY (__sigsetjmp)
s32i a14, a2, 16
s32i a15, a2, 20
mov a12, a2
- movi a0, __sigjmp_save
+ movi a0, JUMPTARGET(__sigjmp_save)
+ FDPIC_LOAD_JUMPTARGET(a0, a11, a0)
callx0 a0
l32i a0, a12, 0
l32i a12, a12, 8
diff --git a/libc/sysdeps/linux/xtensa/swapcontext.S b/libc/sysdeps/linux/xtensa/swapcontext.S
index a215edc6d..40b38e98c 100644
--- a/libc/sysdeps/linux/xtensa/swapcontext.S
+++ b/libc/sysdeps/linux/xtensa/swapcontext.S
@@ -36,6 +36,7 @@ ENTRY(__swapcontext)
addi a4, a2, UCONTEXT_SIGMASK
movi a2, SIG_SETMASK
movi a5, JUMPTARGET (sigprocmask)
+ FDPIC_LOAD_JUMPTARGET (a5, a11, a5)
callx0 a5
bnez a2, .Lerror
diff --git a/libc/sysdeps/linux/xtensa/sysdep.h b/libc/sysdeps/linux/xtensa/sysdep.h
index 80b3f30fc..d05741027 100644
--- a/libc/sysdeps/linux/xtensa/sysdep.h
+++ b/libc/sysdeps/linux/xtensa/sysdep.h
@@ -75,13 +75,27 @@
#define LITERAL_POSITION .literal_position
#undef JUMPTARGET
-#ifdef __PIC__
+#if defined(__FDPIC__)
+#define JUMPTARGET(name) name##@GOTOFFFUNCDESC
+#define FDPIC_LOAD_FUNCDESC(call_target, funcdesc) \
+ l32i a11, funcdesc, 4; \
+ l32i call_target, funcdesc, 0
+
+#define FDPIC_LOAD_JUMPTARGET(call_target, got_base, jumptarget)\
+ add call_target, got_base, jumptarget; \
+ FDPIC_LOAD_FUNCDESC(call_target, call_target)
+
+#elif defined(__PIC__)
/* The "@PLT" suffix is currently a no-op for non-shared linking, but
it doesn't hurt to use it conditionally for PIC code in case that
changes someday. */
#define JUMPTARGET(name) name##@PLT
+#define FDPIC_LOAD_FUNCDESC(call_target, funcdesc)
+#define FDPIC_LOAD_JUMPTARGET(call_target, got_base, jumptarget)
#else
#define JUMPTARGET(name) name
+#define FDPIC_LOAD_FUNCDESC(call_target, funcdesc)
+#define FDPIC_LOAD_JUMPTARGET(call_target, got_base, jumptarget)
#endif
#ifndef FRAMESIZE
@@ -153,6 +167,21 @@
#if defined _LIBC_REENTRANT
# if defined USE___THREAD
+#ifdef __FDPIC__
+# define SYSCALL_ERROR_ERRNO errno
+# define SYSCALL_ERROR_HANDLER \
+0: rur a4, THREADPTR; \
+ movi a3, SYSCALL_ERROR_ERRNO@GOTTPOFF; \
+ .reloc ., R_XTENSA_TLS_TPOFF_PTR, SYSCALL_ERROR_ERRNO; \
+ add a3, a3, a11; \
+ .reloc ., R_XTENSA_TLS_TPOFF_LOAD, SYSCALL_ERROR_ERRNO; \
+ l32i a3, a3, 0; \
+ neg a2, a2; \
+ add a4, a4, a3; \
+ s32i a2, a4, 0; \
+ movi a2, -1; \
+ j .Lpseudo_end;
+#else
# define SYSCALL_ERROR_ERRNO errno
# define SYSCALL_ERROR_HANDLER \
0: rur a4, THREADPTR; \
@@ -162,13 +191,14 @@
s32i a2, a4, 0; \
movi a2, -1; \
j .Lpseudo_end;
+#endif
# else /* !USE___THREAD */
#if defined(__XTENSA_WINDOWED_ABI__)
# define SYSCALL_ERROR_HANDLER \
0: neg a2, a2; \
mov a6, a2; \
- movi a4, __errno_location@PLT; \
+ movi a4, JUMPTARGET(__errno_location); \
callx4 a4; \
s32i a2, a6, 0; \
movi a2, -1; \
@@ -179,7 +209,8 @@
addi a1, a1, -16; \
s32i a0, a1, 0; \
s32i a2, a1, 4; \
- movi a0, __errno_location@PLT; \
+ movi a0, JUMPTARGET(__errno_location); \
+ FDPIC_LOAD_JUMPTARGET(a0, a11, a0); \
callx0 a0; \
l32i a0, a1, 0; \
l32i a3, a1, 4; \
@@ -193,12 +224,23 @@
# endif /* !USE___THREAD */
#else /* !_LIBC_REENTRANT */
+#ifdef __FDPIC__
+#define SYSCALL_ERROR_HANDLER \
+0: movi a4, errno@GOT; \
+ add a4, a4, a11; \
+ l32i a4, a4, 0; \
+ neg a2, a2; \
+ s32i a2, a4, 0; \
+ movi a2, -1; \
+ j .Lpseudo_end;
+#else
#define SYSCALL_ERROR_HANDLER \
0: movi a4, errno; \
neg a2, a2; \
s32i a2, a4, 0; \
movi a2, -1; \
j .Lpseudo_end;
+#endif /* __FDPIC__ */
#endif /* _LIBC_REENTRANT */
#endif /* __ASSEMBLER__ */
diff --git a/libiconv/iconv.c b/libiconv/iconv.c
index 0462f6e10..095932fd6 100644
--- a/libiconv/iconv.c
+++ b/libiconv/iconv.c
@@ -199,7 +199,7 @@ static void put_16(unsigned char *s, unsigned c, int e)
static unsigned get_32(const unsigned char *s, int e)
{
e &= 3;
- return s[e]+0U<<24 | s[e^1]<<16 | s[e^2]<<8 | s[e^3];
+ return (s[e]+0U)<<24 | s[e^1]<<16 | s[e^2]<<8 | s[e^3];
}
static void put_32(unsigned char *s, unsigned c, int e)
@@ -242,7 +242,7 @@ static inline int utf8enc_wchar(char *outb, wchar_t c)
}
}
-static inline int utf8seq_is_overlong(char *s, int n)
+static inline int utf8seq_is_overlong(unsigned char *s, int n)
{
switch (n)
{
@@ -268,12 +268,12 @@ static inline int utf8seq_is_overlong(char *s, int n)
return 0;
}
-static inline int utf8seq_is_surrogate(char *s, int n)
+static inline int utf8seq_is_surrogate(unsigned char *s, int n)
{
return ((n == 3) && (*s == 0xED) && (*(s+1) >= 0xA0) && (*(s+1) <= 0xBF));
}
-static inline int utf8seq_is_illegal(char *s, int n)
+static inline int utf8seq_is_illegal(unsigned char *s, int n)
{
return ((n == 3) && (*s == 0xEF) && (*(s+1) == 0xBF) &&
(*(s+2) >= 0xBE) && (*(s+2) <= 0xBF));
@@ -331,7 +331,7 @@ static unsigned legacy_map(const unsigned char *map, unsigned c)
{
if (c < 4*map[-1]) return c;
unsigned x = c - 4*map[-1];
- x = map[x*5/4]>>2*x%8 | map[x*5/4+1]<<8-2*x%8 & 1023;
+ x = map[x*5/4]>>(2*x%8) | (map[x*5/4+1]<<(8-2*x%8) & 1023);
return x < 256 ? x : legacy_chars[x-256];
}
@@ -384,7 +384,7 @@ size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restri
if (c < 128) break;
else {
wchar_t wc;
- l = utf8dec_wchar(&wc, *in, *inb);
+ l = utf8dec_wchar(&wc, (unsigned char*)(*in), *inb);
c = wc;
}
if (!l) l++;
diff --git a/libiconv/include/jis0208.h b/libiconv/include/jis0208.h
index de9c5f26a..12183ed3e 100644
--- a/libiconv/include/jis0208.h
+++ b/libiconv/include/jis0208.h
@@ -1,80 +1,80 @@
-12288,12289,12290,65292,65294,12539,65306,65307,65311,65281,12443,12444,180,
+{12288,12289,12290,65292,65294,12539,65306,65307,65311,65281,12443,12444,180,
65344,168,65342,65507,65343,12541,12542,12445,12446,12291,20189,12293,12294,
12295,12540,8213,8208,65295,92,12316,8214,65372,8230,8229,8216,8217,8220,8221,
65288,65289,12308,12309,65339,65341,65371,65373,12296,12297,12298,12299,12300,
12301,12302,12303,12304,12305,65291,8722,177,215,247,65309,8800,65308,65310,
8806,8807,8734,8756,9794,9792,176,8242,8243,8451,65509,65284,162,163,65285,
-65283,65286,65290,65312,167,9734,9733,9675,9679,9678,9671,9670,9633,9632,9651,
+65283,65286,65290,65312,167,9734,9733,9675,9679,9678,9671},{9670,9633,9632,9651,
9650,9661,9660,8251,12306,8594,8592,8593,8595,12307,0,0,0,0,0,0,0,0,0,0,0,
8712,8715,8838,8839,8834,8835,8746,8745,0,0,0,0,0,0,0,0,8743,8744,172,8658,
8660,8704,8707,0,0,0,0,0,0,0,0,0,0,0,8736,8869,8978,8706,8711,8801,8786,8810,
8811,8730,8765,8733,8757,8747,8748,0,0,0,0,0,0,0,8491,8240,9839,9837,9834,
-8224,8225,182,0,0,0,0,9711,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65296,65297,65298,
+8224,8225,182,0,0,0,0,9711},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65296,65297,65298,
65299,65300,65301,65302,65303,65304,65305,0,0,0,0,0,0,0,65313,65314,65315,
65316,65317,65318,65319,65320,65321,65322,65323,65324,65325,65326,65327,65328,
65329,65330,65331,65332,65333,65334,65335,65336,65337,65338,0,0,0,0,0,0,65345,
65346,65347,
65348,65349,65350,65351,65352,65353,65354,65355,65356,65357,65358,65359,65360,
-65361,65362,65363,65364,65365,65366,65367,65368,65369,65370,0,0,0,0,12353,
+65361,65362,65363,65364,65365,65366,65367,65368,65369,65370,0,0,0,0},{12353,
12354,12355,12356,12357,12358,12359,12360,12361,12362,12363,12364,12365,12366,
12367,12368,12369,12370,12371,12372,12373,12374,12375,12376,12377,12378,12379,
12380,12381,12382,12383,12384,12385,12386,12387,12388,12389,12390,12391,12392,
12393,12394,12395,12396,12397,12398,12399,12400,12401,12402,12403,12404,12405,
12406,12407,12408,12409,12410,12411,12412,12413,12414,12415,12416,12417,12418,
12419,12420,12421,12422,12423,12424,12425,12426,12427,12428,12429,12430,12431,
-12432,12433,12434,12435,0,0,0,0,0,0,0,0,0,0,0,12449,12450,12451,12452,12453,
+12432,12433,12434,12435,0,0,0,0,0,0,0,0,0,0,0},{12449,12450,12451,12452,12453,
12454,12455,12456,12457,12458,12459,12460,12461,12462,12463,12464,12465,12466,
12467,12468,12469,12470,12471,12472,12473,12474,12475,12476,12477,12478,12479,
12480,12481,12482,12483,12484,12485,12486,12487,12488,12489,12490,12491,12492,
12493,12494,12495,12496,12497,12498,12499,12500,12501,12502,12503,12504,12505,
12506,12507,12508,12509,12510,12511,12512,12513,12514,12515,12516,12517,12518,
12519,12520,12521,12522,12523,12524,12525,12526,12527,12528,12529,12530,12531,
-12532,12533,12534,0,0,0,0,0,0,0,0,913,914,915,916,917,918,919,920,921,922,923,
+12532,12533,12534,0,0,0,0,0,0,0,0},{913,914,915,916,917,918,919,920,921,922,923,
924,925,926,927,928,929,931,932,933,934,935,936,937,0,0,0,0,0,0,0,0,945,946,
947,948,949,950,951,952,953,
954,955,956,957,958,959,960,961,963,964,965,966,967,968,969,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1040,1041,1042,1043,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{1040,1041,1042,1043,
1044,1045,1025,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,
1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,1072,1073,1074,1075,1076,1077,1105,1078,1079,1080,1081,
1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,
-1097,1098,1099,1100,1101,1102,1103,0,0,0,0,0,0,0,0,0,0,0,0,0,9472,9474,9484,
+1097,1098,1099,1100,1101,1102,1103,0,0,0,0,0,0,0,0,0,0,0,0,0},{9472,9474,9484,
9488,9496,9492,9500,9516,9508,9524,9532,9473,9475,9487,9491,9499,9495,9507,
9523,9515,9531,9547,9504,9519,9512,9527,9535,9501,9520,9509,9528,9538,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,20124,21782,23043,38463,21696,24859,25384,23030,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0},{20124,21782,23043,38463,21696,24859,25384,23030,
36898,33909,33564,31312,24746,25569,28197,26093,33894,33446,39925,26771,22311,
26017,25201,23451,22992,34427,39156,32098,32190,39822,25110,31903,34999,23433,
24245,25353,26263,26696,38343,38797,26447,20197,20234,20301,20381,20553,22258,
22839,22996,23041,23561,24799,24847,24944,26131,26885,28858,30031,30064,31227,
32173,32239,32963,33806,34915,35586,36949,36986,21307,20117,20133,22495,32946,
37057,30959,19968,22769,28322,36920,31282,33576,33419,39983,20801,21360,21693,
-21729,22240,23035,24341,39154,28139,32996,34093,38498,38512,38560,38907,21515,
+21729,22240,23035,24341,39154,28139,32996,34093},{38498,38512,38560,38907,21515,
21491,23431,28879,32701,36802,38632,21359,40284,31418,19985,30867,33276,28198,
22040,21764,27421,34074,39995,23013,21417,28006,29916,38287,22082,20113,36939,
38642,33615,39180,21473,21942,23344,24433,26144,26355,26628,27704,27891,27945,
29787,30408,31310,38964,33521,34907,35424,37613,28082,30123,30410,39365,24742,
35585,36234,38322,27022,21421,20870,22290,22576,22852,23476,24310,24616,25513,
25588,27839,28436,28814,28948,29017,29141,29503,32257,33398,33489,34199,36960,
-37467,40219,22633,26044,27738,29989,20985,22830,22885,24448,24540,25276,26106,
+37467,40219,22633,26044,27738,29989,20985,22830,22885,24448,24540},{25276,26106,
27178,27431,27572,29579,32705,35158,40236,40206,40644,23713,27798,33659,20740,
23627,25014,33222,26742,29281,20057,20474,21368,24681,28201,31311,38899,19979,
21270,20206,20309,20285,20385,20339,21152,21487,22025,22799,23233,23478,23521,
@@ -82,21 +82,21 @@
33499,33540,33655,33775,33747,34662,35506,22057,36008,36838,36942,38686,34442,
20420,23784,25105,29273,30011,33253,33469,34558,36032,38597,39187,39381,20171,
20250,35299,22238,22602,22730,24315,24555,24618,24724,24674,25040,25106,25296,
-25913,39745,26214,26800,28023,28784,30028,30342,32117,33445,34809,38283,38542,
+25913},{39745,26214,26800,28023,28784,30028,30342,32117,33445,34809,38283,38542,
35997,20977,21182,22806,21683,23475,23830,24936,27010,28079,30861,33995,34903,
35442,37799,39608,28012,39336,34521,22435,26623,34510,37390,21123,22151,21508,
24275,25313,25785,26684,26680,27579,29554,30906,31339,35226,35282,36203,36611,
37101,38307,38548,38761,23398,23731,27005,38989,38990,25499,31520,27179,27263,
26806,39949,28511,21106,21917,24688,25324,27963,28167,28369,33883,35088,36676,
19988,39993,21494,26907,27194,38788,26666,20828,31427,33970,37340,37772,22107,
-40232,26658,33541,33841,31909,21000,33477,29926,20094,
+40232,26658,33541,33841},{31909,21000,33477,29926,20094,
20355,20896,23506,21002,21208,21223,24059,21914,22570,23014,23436,23448,23515,
24178,24185,24739,24863,24931,25022,25563,25954,26577,26707,26874,27454,27475,
27735,28450,28567,28485,29872,29976,30435,30475,31487,31649,31777,32233,32566,
32752,32925,33382,33694,35251,35532,36011,36996,37969,38291,38289,38306,38501,
38867,39208,33304,20024,21547,23736,24012,29609,30284,30524,23721,32747,36107,
38593,38929,38996,39000,20225,20238,21361,21916,22120,22522,22855,23305,23492,
-23696,24076,24190,24524,25582,26426,26071,26082,26399,26827,26820,27231,24112,
+23696,24076,24190,24524,25582,26426,26071,26082,26399,26827,26820},{27231,24112,
27589,27671,27773,30079,31048,23395,31232,32000,24509,35215,35352,36020,36215,
36556,36637,39138,39438,39740,20096,20605,20736,22931,23452,25135,25216,25836,
27450,29344,30097,31047,32681,34811,35516,35696,25516,33738,38816,21513,21507,
@@ -104,21 +104,21 @@
20037,20167,20241,21450,21560,23470,24339,24613,25937,26429,27714,27762,27875,
28792,29699,31350,31406,31496,32026,31998,32102,26087,29275,21435,23621,24040,
25298,25312,25369,28192,34394,35377,36317,37624,28417,31142,39770,20136,20139,
-20140,20379,20384,20689,20807,31478,20849,20982,21332,21281,21375,21483,21932,
+20140},{20379,20384,20689,20807,31478,20849,20982,21332,21281,21375,21483,21932,
22659,23777,24375,24394,24623,24656,24685,25375,25945,27211,27841,29378,29421,
30703,33016,33029,33288,34126,37111,37857,38911,39255,39514,20208,20957,23597,
26241,26989,23616,26354,26997,29577,26704,31873,20677,21220,22343,24062,37670,
26020,27427,27453,29748,31105,31165,31563,32202,33465,33740,34943,35167,35641,
36817,37329,21535,37504,20061,20534,21477,21306,29399,
29590,30697,33510,36527,39366,39368,39378,20855,24858,34398,21936,31354,20598,
-23507,36935,38533,20018,27355,37351,23633,23624,25496,31391,27795,38772,36705,
+23507,36935,38533,20018,27355,37351,23633,23624},{25496,31391,27795,38772,36705,
31402,29066,38536,31874,26647,32368,26705,37740,21234,21531,34219,35347,32676,
36557,37089,21350,34952,31041,20418,20670,21009,20804,21843,22317,29674,22411,
22865,24418,24452,24693,24950,24935,25001,25522,25658,25964,26223,26690,28179,
30054,31293,31995,32076,32153,32331,32619,33550,33610,34509,35336,35427,35686,
36605,38938,40335,33464,36814,39912,21127,25119,25731,28608,38553,26689,20625,
27424,27770,28500,31348,32080,34880,35363,26376,20214,20537,20518,20581,20860,
-21048,21091,21927,22287,22533,23244,24314,25010,25080,25331,25458,26908,27177,
+21048,21091,21927,22287,22533,23244,24314,25010,25080,25331,25458},{26908,27177,
29309,29356,29486,30740,30831,32121,30476,32937,35211,35609,36066,36562,36963,
37749,38522,38997,39443,40568,20803,21407,21427,24187,24358,28187,28304,29572,
29694,32067,33335,35328,35578,38480,20046,20491,21476,21628,22266,22993,23396,
@@ -126,21 +126,21 @@
34382,35463,36328,37431,38599,39015,40723,20116,20114,20237,21320,21577,21566,
23087,24460,24481,24735,26791,27278,29786,30849,35486,35492,35703,37264,20062,
39881,20132,20348,20399,20505,20502,20809,20844,21151,21177,21246,21402,21475,
-21521,21518,21897,22353,22434,22909,23380,23389,23439,24037,24039,24055,24184,
+21521},{21518,21897,22353,22434,22909,23380,23389,23439,24037,24039,24055,24184,
24195,24218,24247,24344,24658,24908,25239,25304,25511,25915,26114,26179,26356,
26477,26657,26775,27083,27743,27946,28009,28207,28317,30002,30343,30828,31295,
31968,32005,32024,32094,32177,32789,32771,32943,32945,
33108,33167,33322,33618,34892,34913,35611,36002,36092,37066,37237,37489,30783,
37628,38308,38477,38917,39321,39640,40251,21083,21163,21495,21512,22741,25335,
28640,35946,36703,40633,20811,21051,21578,22269,31296,37239,40288,40658,29508,
-28425,33136,29969,24573,24794,39592,29403,36796,27492,38915,20170,22256,22372,
+28425,33136,29969,24573,24794,39592,29403,36796},{27492,38915,20170,22256,22372,
22718,23130,24680,25031,26127,26118,26681,26801,28151,30165,32058,33390,39746,
20123,20304,21449,21766,23919,24038,24046,26619,27801,29811,30722,35408,37782,
35039,22352,24231,25387,20661,20652,20877,26368,21705,22622,22971,23472,24425,
25165,25505,26685,27507,28168,28797,37319,29312,30741,30758,31085,25998,32048,
33756,35009,36617,38555,21092,22312,26448,32618,36001,20916,22338,38442,22586,
27018,32948,21682,23822,22524,30869,40442,20316,21066,21643,25662,26152,26388,
-26613,31364,31574,32034,37679,26716,39853,31545,21273,20874,21047,23519,25334,
+26613,31364,31574,32034,37679,26716,39853,31545,21273,20874,21047},{23519,25334,
25774,25830,26413,27578,34217,38609,30352,39894,25420,37638,39851,30399,26194,
19977,20632,21442,23665,24808,25746,25955,26719,29158,29642,29987,31639,32386,
34453,35715,36059,37240,39184,26028,26283,27531,20181,20180,20282,20351,21050,
@@ -148,21 +148,21 @@
24605,25351,25903,23388,26031,26045,26088,26525,27490,27515,27663,29509,31049,
31169,31992,32025,32043,32930,33026,33267,35222,35422,35433,35430,35468,35566,
36039,36060,38604,39164,27503,20107,20284,20365,20816,23383,23546,24904,25345,
-26178,27425,28363,27835,29246,29885,30164,30913,31034,32780,32819,33258,33940,
+26178},{27425,28363,27835,29246,29885,30164,30913,31034,32780,32819,33258,33940,
36766,27728,40575,24335,35672,40235,31482,36600,23437,
38635,19971,21489,22519,22833,23241,23460,24713,28287,28422,30142,36074,23455,
34048,31712,20594,26612,33437,23649,34122,32286,33294,20889,23556,25448,36198,
26012,29038,31038,32023,32773,35613,36554,36974,34503,37034,20511,21242,23610,
26451,28796,29237,37196,37320,37675,33509,23490,24369,24825,20027,21462,23432,
25163,26417,27530,29417,29664,31278,33131,36259,37202,39318,20754,21463,21610,
-23551,25480,27193,32172,38656,22234,21454,21608,23447,23601,24030,20462,24833,
+23551,25480,27193,32172,38656,22234,21454,21608},{23447,23601,24030,20462,24833,
25342,27954,31168,31179,32066,32333,32722,33261,33311,33936,34886,35186,35728,
36468,36655,36913,37195,37228,38598,37276,20160,20303,20805,21313,24467,25102,
26580,27713,28171,29539,32294,37325,37507,21460,22809,23487,28113,31069,32302,
31899,22654,29087,20986,34899,36848,20426,23803,26149,30636,31459,33308,39423,
20934,24490,26092,26991,27529,28147,28310,28516,30462,32020,24033,36981,37255,
38918,20966,21021,25152,26257,26329,28186,24246,32210,32626,26360,34223,34295,
-35576,21161,21465,22899,24207,24464,24661,37604,38500,20663,20767,21213,21280,
+35576,21161,21465,22899,24207,24464,24661,37604,38500,20663,20767},{21213,21280,
21319,21484,21736,21830,21809,22039,22888,22974,23100,23477,23558,23567,23569,
23578,24196,24202,24288,24432,25215,25220,25307,25484,25463,26119,26124,26157,
26230,26494,26786,27167,27189,27836,28040,28169,28248,28988,28966,29031,30151,
@@ -170,21 +170,21 @@
34909,35059,35359,35388,35412,35443,35937,36062,37284,37478,37758,37912,38556,
38808,19978,19976,19998,20055,20887,21104,22478,22580,22732,23330,24120,24773,
25854,26465,26454,27972,29366,30067,31331,33976,35698,
-37304,37664,22065,22516,39166,25325,26893,27542,29165,32340,32887,33394,35302,
+37304,37664,22065,22516,39166},{25325,26893,27542,29165,32340,32887,33394,35302,
39135,34645,36785,23611,20280,20449,20405,21767,23072,23517,23529,24515,24910,
25391,26032,26187,26862,27035,28024,28145,30003,30137,30495,31070,31206,32051,
33251,33455,34218,35242,35386,36523,36763,36914,37341,38663,20154,20161,20995,
22645,22764,23563,29978,23613,33102,35338,36805,38499,38765,31525,35535,38920,
37218,22259,21416,36887,21561,22402,24101,25512,27700,28810,30561,31883,32736,
34928,36930,37204,37648,37656,38543,29790,39620,23815,23913,25968,26530,36264,
-38619,25454,26441,26905,33733,38935,38592,35070,28548,25722,23544,19990,28716,
+38619,25454,26441,26905,33733,38935,38592,35070},{28548,25722,23544,19990,28716,
30045,26159,20932,21046,21218,22995,24449,24615,25104,25919,25972,26143,26228,
26866,26646,27491,28165,29298,29983,30427,31934,32854,22768,35069,35199,35488,
35475,35531,36893,37266,38738,38745,25993,31246,33030,38587,24109,24796,25114,
26021,26132,26512,30707,31309,31821,32318,33034,36012,36196,36321,36447,30889,
20999,25305,25509,25666,25240,35373,31363,31680,35500,38634,32118,33292,34633,
20185,20808,21315,21344,23459,23554,23574,24029,25126,25159,25776,26643,26676,
-27849,27973,27927,26579,28508,29006,29053,26059,31359,31661,32218,32330,32680,
+27849,27973,27927,26579,28508,29006,29053,26059,31359,31661,32218},{32330,32680,
33146,33307,33337,34214,35438,36046,36341,36984,36983,37549,37521,38275,39854,
21069,21892,28472,28982,20840,31109,32341,33203,31950,22092,22609,23720,25514,
26366,26365,26970,29401,30095,30094,30990,31062,31199,31895,32032,32068,34311,
@@ -192,21 +192,21 @@
23435,23652,21277,24803,24819,25436,25475,25407,25531,
25805,26089,26361,24035,27085,27133,28437,29157,20105,30185,30456,31379,31967,
32207,32156,32865,33609,33624,33900,33980,34299,35013,36208,36865,36973,37783,
-38684,39442,20687,22679,24974,33235,34101,36104,36896,20419,20596,21063,21363,
+38684,39442,20687,22679,24974},{33235,34101,36104,36896,20419,20596,21063,21363,
24687,25417,26463,28204,36275,36895,20439,23646,36042,26063,32154,21330,34966,
20854,25539,23384,23403,23562,25613,26449,36956,20182,22810,22826,27760,35409,
21822,22549,22949,24816,25171,26561,33333,26965,38464,39364,39464,20307,22534,
23550,32784,23729,24111,24453,24608,24907,25140,26367,27888,28382,32974,33151,
33492,34955,36024,36864,36910,38538,40667,39899,20195,21488,22823,31532,37261,
38988,40441,28381,28711,21331,21828,23429,25176,25246,25299,27810,28655,29730,
-35351,37944,28609,35582,33592,20967,34552,21482,21481,20294,36948,36784,22890,
+35351,37944,28609,35582,33592,20967,34552,21482},{21481,20294,36948,36784,22890,
33073,24061,31466,36799,26842,35895,29432,40008,27197,35504,20025,21336,22022,
22374,25285,25506,26086,27470,28129,28251,28845,30701,31471,31658,32187,32829,
32966,34507,35477,37723,22243,22727,24382,26029,26262,27264,27573,30007,35527,
20516,30693,22320,24347,24677,26234,27744,30196,31258,32622,33268,34584,36933,
39347,31689,30044,31481,31569,33988,36880,31209,31378,33590,23265,30528,20013,
20210,23449,24544,25277,26172,26609,27880,34411,34935,35387,37198,37619,39376,
-27159,28710,29482,33511,33879,36015,19969,20806,20939,21899,23541,24086,24115,
+27159,28710,29482,33511,33879,36015,19969,20806,20939,21899,23541},{24086,24115,
24193,24340,24373,24427,24500,25074,25361,26274,26397,28526,29266,30010,30522,
32884,33081,33144,34678,35519,35548,36229,36339,37530,38263,38914,40165,21189,
25431,30452,26389,27784,29645,36035,37806,38515,27941,
@@ -214,21 +214,21 @@
26584,36795,34086,32180,37716,26943,28528,22378,22775,23340,32044,29226,21514,
37347,40372,20141,20302,20572,20597,21059,35998,21576,22564,23450,24093,24213,
24237,24311,24351,24716,25269,25402,25552,26799,27712,30855,31118,31243,32224,
-33351,35330,35558,36420,36883,37048,37165,37336,40718,27877,25688,25826,25973,
+33351,35330,35558,36420,36883},{37048,37165,37336,40718,27877,25688,25826,25973,
28404,30340,31515,36969,37841,28346,21746,24505,25764,36685,36845,37444,20856,
22635,22825,23637,24215,28155,32399,29980,36028,36578,39003,28857,20253,27583,
28593,30000,38651,20814,21520,22581,22615,22956,23648,24466,26007,26460,28193,
30331,33759,36077,36884,37117,37709,30757,30778,21162,24230,22303,22900,24594,
20498,20826,20908,20941,20992,21776,22612,22616,22871,23445,23798,23947,24764,
25237,25645,26481,26691,26812,26847,30423,28120,28271,28059,28783,29128,24403,
-30168,31095,31561,31572,31570,31958,32113,21040,33891,34153,34276,35342,35588,
+30168,31095,31561,31572,31570,31958,32113,21040},{33891,34153,34276,35342,35588,
35910,36367,36867,36879,37913,38518,38957,39472,38360,20685,21205,21516,22530,
23566,24999,25758,27934,30643,31461,33012,33796,36947,37509,23776,40199,21311,
24471,24499,28060,29305,30563,31167,31716,27602,29420,35501,26627,27233,20984,
31361,26932,23626,40182,33515,23493,37193,28702,22136,23663,24775,25958,27788,
35930,36929,38931,21585,26311,37389,22856,37027,20869,20045,20970,34201,35598,
28760,25466,37707,26978,39348,32260,30071,21335,26976,36575,38627,27741,20108,
-23612,24336,36841,21250,36049,32905,34425,24319,26085,20083,20837,22914,23615,
+23612,24336,36841,21250,36049,32905,34425,24319,26085,20083,20837},{22914,23615,
38894,20219,22922,24525,35469,28641,31152,31074,23527,
33905,29483,29105,24180,24565,25467,25754,29123,31896,20035,24316,20043,22492,
22178,24745,28611,32013,33021,33075,33215,36786,35223,34468,24052,25226,25773,
@@ -236,14 +236,14 @@
25490,25943,26479,30403,29260,32972,32954,36649,37197,20493,22521,23186,26757,
26995,29028,29437,36023,22770,36064,38506,36889,34687,31204,30695,33833,20271,
21093,21338,25293,26575,27850,30333,31636,31893,33334,34180,36843,26333,28448,
-29190,32283,33707,39361,40614,20989,31665,30834,31672,32903,31560,27368,24161,
+29190,32283,33707,39361,40614},{20989,31665,30834,31672,32903,31560,27368,24161,
32908,30033,30048,20843,37474,28300,30330,37271,39658,20240,32624,25244,31567,
38309,40169,22138,22617,34532,38588,20276,21028,21322,21453,21467,24070,25644,
26001,26495,27710,27726,29256,29359,29677,30036,32321,33324,34281,36009,31684,
37318,29033,38930,39151,25405,26217,30058,30436,30928,34115,34542,21290,21329,
21542,22915,24199,24444,24754,25161,25209,25259,26000,27604,27852,30130,30382,
30865,31192,32203,32631,32933,34987,35513,36027,36991,38750,39131,27147,31800,
-20633,23614,24494,26503,27608,29749,30473,32654,40763,26570,31255,21305,30091,
+20633,23614,24494,26503,27608,29749,30473,32654},{40763,26570,31255,21305,30091,
39661,24422,33181,33777,32920,24380,24517,30050,31558,36924,26727,23019,23195,
32016,30334,35628,20469,24426,27161,27703,28418,29922,31080,34920,35413,35961,
24287,25551,30149,31186,33495,37672,37618,33948,34541,39981,21697,24428,25996,
@@ -251,21 +251,21 @@
20904,24067,24220,24598,25206,25975,26023,26222,28014,29238,31526,33104,33178,
33433,35676,36000,36070,36212,38428,38468,20398,25771,
27494,33310,33889,34154,37096,23553,26963,39080,33914,34135,20239,21103,24489,
-24133,26381,31119,33145,35079,35206,28149,24343,25173,27832,20175,29289,39826,
+24133,26381},{31119,33145,35079,35206,28149,24343,25173,27832,20175,29289,39826,
20998,21563,22132,22707,24996,25198,28954,22894,31881,31966,32027,38640,25991,
32862,19993,20341,20853,22592,24163,24179,24330,26564,20006,34109,38281,38491,
31859,38913,20731,22721,30294,30887,21029,30629,34065,31622,20559,22793,29255,
31687,32232,36794,36820,36941,20415,21193,23081,24321,38829,20445,33303,37610,
22275,25429,27497,29995,35036,36628,31298,21215,22675,24917,25098,26286,27597,
31807,33769,20515,20472,21253,21574,22577,22857,23453,23792,23791,23849,24214,
-25265,25447,25918,26041,26379,27861,27873,28921,30770,32299,32990,33459,33804,
+25265,25447,25918,26041,26379},{27861,27873,28921,30770,32299,32990,33459,33804,
34028,34562,35090,35370,35914,37030,37586,39165,40179,40300,20047,20129,20621,
21078,22346,22952,24125,24536,24537,25151,26292,26395,26576,26834,20882,32033,
32938,33192,35584,35980,36031,37502,38450,21536,38956,21271,20693,21340,22696,
25778,26420,29287,30566,31302,37350,21187,27809,27526,22528,24140,22868,26412,
32763,20961,30406,25705,30952,39764,40635,22475,22969,26151,26522,27598,21737,
27097,24149,33180,26517,39850,26622,40018,26717,20134,20451,21448,25273,26411,
-27819,36804,20397,32365,40639,19975,24930,28288,28459,34067,21619,26410,39749,
+27819,36804,20397,32365,40639,19975,24930,28288},{28459,34067,21619,26410,39749,
24051,31637,23724,23494,34588,28234,34001,31252,33032,22937,31885,27665,30496,
21209,22818,28961,29279,30683,38695,40289,26891,23167,23064,20901,21517,21629,
26126,30431,36855,37528,40180,23018,29277,28357,20813,26825,32191,32236,38754,
@@ -273,26 +273,26 @@
32178,32791,33945,20786,26408,40665,30446,26466,21247,39173,23588,25147,31870,
36016,21839,24758,32011,38272,21249,20063,20918,22812,29242,32822,37326,24357,
30690,21380,24441,32004,34220,35379,36493,38742,26611,34222,37971,24841,24840,
-27833,30290,35565,36664,21807,20305,20778,21191,21451,23461,24189,24736,24962,
+27833,30290},{35565,36664,21807,20305,20778,21191,21451,23461,24189,24736,24962,
25558,26377,26586,28263,28044,29494,29495,30001,31056,35029,35480,36938,37009,
37109,38596,34701,22805,20104,20313,19982,35465,36671,38928,20653,24188,22934,
23481,24248,25562,25594,25793,26332,26954,27096,27915,28342,29076,29992,31407,
32650,32768,33865,33993,35201,35617,36362,36965,38525,39178,24958,25233,27442,
27779,28020,32716,32764,28096,32645,34746,35064,26469,33713,38972,38647,27931,
32097,33853,37226,20081,21365,23888,27396,28651,34253,34349,35239,21033,21519,
-23653,26446,26792,29702,29827,30178,35023,35041,37324,38626,38520,24459,29575,
+23653,26446,26792,29702,29827},{30178,35023,35041,37324,38626,38520,24459,29575,
31435,33870,25504,30053,21129,27969,28316,29705,30041,30827,31890,38534,31452,
40845,20406,24942,26053,34396,20102,20142,20698,20001,20940,23534,26009,26753,
28092,29471,30274,30637,31260,31975,33391,35538,36988,37327,38517,38936,21147,
32209,20523,21400,26519,28107,29136,29747,33256,36650,38563,40023,40607,29792,
22593,28057,32047,39006,20196,20278,20363,20919,21169,23994,24604,29618,31036,
33491,37428,38583,38646,38666,40599,40802,26278,27508,21015,21155,28872,35010,
-24265,24651,24976,28451,29001,31806,32244,32879,34030,36899,37676,21570,39791,
+24265,24651,24976,28451,29001,31806,32244,32879},{34030,36899,37676,21570,39791,
27347,28809,36034,36335,38706,21172,23105,24266,24324,26391,27004,27028,28010,
28431,29282,29436,31725,32769,32894,34635,37070,20845,
40595,31108,32907,37682,35542,20525,21644,35441,27498,36036,33031,24785,26528,
40434,20121,20120,39952,35435,34241,34152,26880,28286,30871,33109,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{
24332,19984,19989,20010,20017,20022,20028,20031,20034,20054,20056,20098,20101,
35947,20106,33298,24333,20110,20126,20127,20128,20130,20144,20147,20150,20174,
20173,20164,20166,20162,20183,20190,20205,20191,20215,20233,20314,20272,20315,
@@ -300,14 +300,14 @@
20374,20760,20436,20447,20430,20440,20443,20433,20442,20432,20452,20453,20506,
20520,20500,20522,20517,20485,20252,20470,20513,20521,20524,20478,20463,20497,
20486,20547,20551,26371,20565,20560,20552,20570,20566,20588,20600,20608,20634,
-20613,20660,20658,20681,20682,20659,20674,20694,20702,20709,20717,20707,20718,
+20613,20660,20658},{20681,20682,20659,20674,20694,20702,20709,20717,20707,20718,
20729,20725,20745,20737,20738,20758,20757,20756,20762,20769,20794,20791,20796,
20795,20799,20800,20818,20812,20820,20834,31480,20841,20842,20846,20864,20866,
22232,20876,20873,20879,20881,20883,20885,20886,20900,20902,20898,20905,20906,
20907,20915,20913,20914,20912,20917,20925,20933,20937,20955,20960,34389,20969,
20973,20976,20981,20990,20996,21003,21012,21006,21031,21034,21038,21043,21049,
21071,21060,21067,21068,21086,21076,21098,21108,21097,21107,21119,21117,21133,
-21140,21138,21105,21128,21137,36776,36775,
+21140,21138,21105,21128,21137,36776},{36775,
21164,21165,21180,21173,21185,21197,21207,21214,21219,21222,39149,21216,21235,
21237,21240,21241,21254,21256,30008,21261,21264,21263,21269,21274,21283,21295,
21297,21299,21304,21312,21318,21317,19991,21321,21325,20950,21342,21353,21358,
@@ -315,21 +315,21 @@
38617,21471,26364,29166,21486,21480,21485,21498,21505,21565,21568,21548,21549,
21564,21550,21558,21545,21533,21582,21647,21621,21646,21599,21617,21623,21616,
21650,21627,21632,21622,21636,21648,21638,21703,21666,21688,21669,21676,21700,
-21704,21672,21675,21698,21668,21694,21692,21720,21733,21734,21775,21780,21757,
+21704,21672},{21675,21698,21668,21694,21692,21720,21733,21734,21775,21780,21757,
21742,21741,21754,21730,21817,21824,21859,21836,21806,21852,21829,21846,21847,
21816,21811,21853,21913,21888,21679,21898,21919,21883,21886,21912,21918,21934,
21884,21891,21929,21895,21928,21978,21957,21983,21956,21980,21988,21972,22036,
22007,22038,22014,22013,22043,22009,22094,22096,29151,22068,22070,22066,22072,
22123,22116,22063,22124,22122,22150,22144,22154,22176,22164,22159,22181,22190,
22198,22196,22210,22204,22209,22211,22208,22216,22222,22225,22227,22231,22254,
-22265,22272,22271,22276,22281,22280,22283,22285,22291,22296,22294,21959,22300,
+22265,22272,22271,22276,22281},{22280,22283,22285,22291,22296,22294,21959,22300,
22310,22327,22328,22350,22331,22336,22351,22377,22464,22408,22369,22399,22409,
22419,22432,22451,22436,22442,22448,22467,22470,22484,22482,22483,22538,22486,
22499,22539,22553,22557,22642,22561,22626,22603,22640,27584,22610,22589,22649,
22661,22713,22687,22699,22714,22750,22715,22712,22702,22725,22739,22737,22743,
22745,22744,22757,22748,22756,22751,22767,22778,22777,
22779,22780,22781,22786,22794,22800,22811,26790,22821,22828,22829,22834,22840,
-22846,31442,22869,22864,22862,22874,22872,22882,22880,22887,22892,22889,22904,
+22846,31442,22869,22864,22862,22874,22872,22882,22880,22887,22892,22889},{22904,
22913,22941,20318,20395,22947,22962,22982,23016,23004,22925,23001,23002,23077,
23071,23057,23068,23049,23066,23104,23148,23113,23093,23094,23138,23146,23194,
23228,23230,23243,23234,23229,23267,23255,23270,23273,23254,23290,23291,23308,
@@ -337,21 +337,21 @@
23387,23397,23401,23408,23411,23413,23416,25992,23418,23424,23427,23462,23480,
23491,23495,23497,23508,23504,23524,23526,23522,23518,23525,23531,23536,23542,
23539,23557,23559,23560,23565,23571,23584,23586,23592,23608,23609,23617,23622,
-23630,23635,23632,23631,23409,23660,23662,20066,23670,23673,23692,23697,23700,
+23630,23635},{23632,23631,23409,23660,23662,20066,23670,23673,23692,23697,23700,
22939,23723,23739,23734,23740,23735,23749,23742,23751,23769,23785,23805,23802,
23789,23948,23786,23819,23829,23831,23900,23839,23835,23825,23828,23842,23834,
23833,23832,23884,23890,23886,23883,23916,23923,23926,23943,23940,23938,23970,
23965,23980,23982,23997,23952,23991,23996,24009,24013,24019,24018,24022,24027,
24043,24050,24053,24075,24090,24089,24081,24091,24118,24119,24132,24131,24128,
24142,24151,24148,24159,24162,24164,24135,24181,24182,24186,40636,24191,24224,
-24257,24258,24264,24272,24271,24278,24291,24285,24282,24283,24290,24289,24296,
+24257,24258,24264,24272,24271},{24278,24291,24285,24282,24283,24290,24289,24296,
24297,24300,24305,24307,24304,24308,24312,24318,24323,24329,24413,24412,24331,
24337,24342,24361,24365,24376,24385,24392,24396,24398,24367,24401,24406,24407,
24409,24417,24429,24435,24439,24451,24450,24447,24458,
24456,24465,24455,24478,24473,24472,24480,24488,24493,24508,24534,24571,24548,
24568,24561,24541,24755,24575,24609,24672,24601,24592,24617,24590,24625,24603,
24597,24619,24614,24591,24634,24666,24641,24682,24695,24671,24650,24646,24653,
-24675,24643,24676,24642,24684,24683,24665,24705,24717,24807,24707,24730,24708,
+24675,24643,24676,24642,24684,24683,24665,24705,24717,24807,24707,24730},{24708,
24731,24726,24727,24722,24743,24715,24801,24760,24800,24787,24756,24560,24765,
24774,24757,24792,24909,24853,24838,24822,24823,24832,24820,24826,24835,24865,
24827,24817,24845,24846,24903,24894,24872,24871,24906,24895,24892,24876,24884,
@@ -359,21 +359,21 @@
24927,24925,24915,24949,24985,24982,24967,25004,24980,24986,24970,24977,25003,
25006,25036,25034,25033,25079,25032,25027,25030,25018,25035,32633,25037,25062,
25059,25078,25082,25076,25087,25085,25084,25086,25088,25096,25097,25101,25100,
-25108,25115,25118,25121,25130,25134,25136,25138,25139,25153,25166,25182,25187,
+25108,25115},{25118,25121,25130,25134,25136,25138,25139,25153,25166,25182,25187,
25179,25184,25192,25212,25218,25225,25214,25234,25235,25238,25300,25219,25236,
25303,25297,25275,25295,25343,25286,25812,25288,25308,25292,25290,25282,25287,
25243,25289,25356,25326,25329,25383,25346,25352,25327,25333,25424,25406,25421,
25628,25423,25494,25486,25472,25515,25462,25507,25487,25481,25503,25525,25451,
25449,25534,25577,25536,25542,25571,25545,25554,25590,25540,25622,25652,25606,
25619,25638,25654,25885,25623,25640,25615,25703,25711,25718,25678,25898,25749,
-25747,25765,25769,25736,25788,25818,25810,25797,25799,25787,25816,25794,25841,
+25747,25765,25769,25736,25788},{25818,25810,25797,25799,25787,25816,25794,25841,
25831,33289,25824,25825,25260,25827,25839,25900,25846,
25844,25842,25850,25856,25853,25880,25884,25861,25892,25891,25899,25908,25909,
25911,25910,25912,30027,25928,25942,25941,25933,25944,25950,25949,25970,25976,
25986,25987,35722,26011,26015,26027,26039,26051,26054,26049,26052,26060,26066,
26075,26073,26080,26081,26097,26482,26122,26115,26107,26483,26165,26166,26164,
26140,26191,26180,26185,26177,26206,26205,26212,26215,26216,26207,26210,26224,
-26243,26248,26254,26249,26244,26264,26269,26305,26297,26313,26302,26300,26308,
+26243,26248,26254,26249,26244,26264,26269,26305,26297,26313,26302,26300},{26308,
26296,26326,26330,26336,26175,26342,26345,26352,26357,26359,26383,26390,26398,
26406,26407,38712,26414,26431,26422,26433,26424,26423,26438,26462,26464,26457,
26467,26468,26505,26480,26537,26492,26474,26508,26507,26534,26529,26501,26551,
@@ -381,21 +381,21 @@
26566,26599,27292,26654,26694,26665,26688,26701,26674,26702,26803,26667,26713,
26723,26743,26751,26783,26767,26797,26772,26781,26779,26755,27310,26809,26740,
26805,26784,26810,26895,26765,26750,26881,26826,26888,26840,26914,26918,26849,
-26892,26829,26836,26855,26837,26934,26898,26884,26839,26851,26917,26873,26848,
+26892,26829},{26836,26855,26837,26934,26898,26884,26839,26851,26917,26873,26848,
26863,26920,26922,26906,26915,26913,26822,27001,26999,26972,27000,26987,26964,
27006,26990,26937,26996,26941,26969,26928,26977,26974,26973,27009,26986,27058,
27054,27088,27071,27073,27091,27070,27086,23528,27082,27101,27067,27075,27047,
27182,27025,27040,27036,27029,27060,27102,27112,27138,27163,27135,27402,27129,
27122,27111,27141,27057,27166,27117,27156,27115,27146,27154,27329,27171,27155,
27204,27148,27250,27190,27256,27207,27234,27225,27238,
-27208,27192,27170,27280,27277,27296,27268,27298,27299,27287,34327,27323,27331,
+27208,27192,27170,27280,27277,27296,27268,27298,27299},{27287,34327,27323,27331,
27330,27320,27315,27308,27358,27345,27359,27306,27354,27370,27387,27397,34326,
27386,27410,27414,39729,27423,27448,27447,30428,27449,39150,27463,27459,27465,
27472,27481,27476,27483,27487,27489,27512,27513,27519,27520,27524,27523,27533,
27544,27541,27550,27556,27562,27563,27567,27570,27569,27571,27575,27580,27590,
27595,27603,27615,27628,27627,27635,27631,40638,27656,27667,27668,27675,27684,
27683,27742,27733,27746,27754,27778,27789,27802,27777,27803,27774,27752,27763,
-27794,27792,27844,27889,27859,27837,27863,27845,27869,27822,27825,27838,27834,
+27794,27792,27844,27889,27859,27837,27863,27845,27869,27822,27825,27838},{27834,
27867,27887,27865,27882,27935,34893,27958,27947,27965,27960,27929,27957,27955,
27922,27916,28003,28051,28004,27994,28025,27993,28046,28053,28644,28037,28153,
28181,28170,28085,28103,28134,28088,28102,28140,28126,28108,28136,28114,28101,
@@ -403,21 +403,21 @@
28195,28267,28203,28278,28237,28191,28227,28218,28238,28196,28415,28189,28216,
28290,28330,28312,28361,28343,28371,28349,28335,28356,28338,28372,28373,28303,
28325,28354,28319,28481,28433,28748,28396,28408,28414,28479,28402,28465,28399,
-28466,28364,28478,28435,28407,28550,28538,28536,28545,28544,28527,28507,28659,
+28466,28364},{28478,28435,28407,28550,28538,28536,28545,28544,28527,28507,28659,
28525,28546,28540,28504,28558,28561,28610,28518,28595,28579,28577,28580,28601,
28614,28586,28639,28629,28652,28628,28632,28657,28654,28635,28681,28683,28666,
28689,28673,28687,28670,28699,28698,28532,28701,28696,28703,28720,28734,28722,
28753,28771,28825,28818,28847,28913,28844,28856,28851,
28846,28895,28875,28893,28889,28937,28925,28956,28953,29029,29013,29064,29030,
29026,29004,29014,29036,29071,29179,29060,29077,29096,29100,29143,29113,29118,
-29138,29129,29140,29134,29152,29164,29159,29173,29180,29177,29183,29197,29200,
+29138,29129,29140,29134,29152,29164,29159,29173,29180},{29177,29183,29197,29200,
29211,29224,29229,29228,29232,29234,29243,29244,29247,29248,29254,29259,29272,
29300,29310,29314,29313,29319,29330,29334,29346,29351,29369,29362,29379,29382,
29380,29390,29394,29410,29408,29409,29433,29431,20495,29463,29450,29468,29462,
29469,29492,29487,29481,29477,29502,29518,29519,40664,29527,29546,29544,29552,
29560,29557,29563,29562,29640,29619,29646,29627,29632,29669,29678,29662,29858,
29701,29807,29733,29688,29746,29754,29781,29759,29791,29785,29761,29788,29801,
-29808,29795,29802,29814,29822,29835,29854,29863,29898,29903,29908,29681,29920,
+29808,29795,29802,29814,29822,29835,29854,29863,29898,29903,29908,29681},{29920,
29923,29927,29929,29934,29938,29936,29937,29944,29943,29956,29955,29957,29964,
29966,29965,29973,29971,29982,29990,29996,30012,30020,30029,30026,30025,30043,
30022,30042,30057,30052,30055,30059,30061,30072,30070,30086,30087,30068,30090,
@@ -425,21 +425,21 @@
30140,30129,30157,30154,30162,30169,30179,30174,30206,30207,30204,30209,30192,
30202,30194,30195,30219,30221,30217,30239,30247,30240,30241,30242,30244,30260,
30256,30267,30279,30280,30278,30300,30296,30305,30306,30312,30313,30314,30311,
-30316,30320,30322,30326,30328,30332,30336,30339,30344,30347,30350,30358,30355,
+30316,30320},{30322,30326,30328,30332,30336,30339,30344,30347,30350,30358,30355,
30361,30362,30384,30388,30392,30393,30394,30402,30413,30422,30418,30430,30433,
30437,30439,30442,34351,30459,30472,30471,30468,30505,
30500,30494,30501,30502,30491,30519,30520,30535,30554,30568,30571,30555,30565,
30591,30590,30585,30606,30603,30609,30624,30622,30640,30646,30649,30655,30652,
30653,30651,30663,30669,30679,30682,30684,30691,30702,30716,30732,30738,31014,
30752,31018,30789,30862,30836,30854,30844,30874,30860,30883,30901,30890,30895,
-30929,30918,30923,30932,30910,30908,30917,30922,30956,30951,30938,30973,30964,
+30929,30918,30923,30932,30910,30908,30917,30922,30956},{30951,30938,30973,30964,
30983,30994,30993,31001,31020,31019,31040,31072,31063,31071,31066,31061,31059,
31098,31103,31114,31133,31143,40779,31146,31150,31155,31161,31162,31177,31189,
31207,31212,31201,31203,31240,31245,31256,31257,31264,31263,31104,31281,31291,
31294,31287,31299,31319,31305,31329,31330,31337,40861,31344,31353,31357,31368,
31383,31381,31384,31382,31401,31432,31408,31414,31429,31428,31423,36995,31431,
31434,31437,31439,31445,31443,31449,31450,31453,31457,31458,31462,31469,31472,
-31490,31503,31498,31494,31539,31512,31513,31518,31541,31528,31542,31568,31610,
+31490,31503,31498,31494,31539,31512,31513,31518,31541,31528,31542,31568},{31610,
31492,31565,31499,31564,31557,31605,31589,31604,31591,31600,31601,31596,31598,
31645,31640,31647,31629,31644,31642,31627,31634,31631,31581,31641,31691,31681,
31692,31695,31668,31686,31709,31721,31761,31764,31718,31717,31840,31744,31751,
@@ -447,21 +447,21 @@
31820,31811,31828,31823,31808,31824,31832,31839,31844,31830,31845,31852,31861,
31875,31888,31908,31917,31906,31915,31905,31912,31923,31922,31921,31918,31929,
31933,31936,31941,31938,31960,31954,31964,31970,39739,31983,31986,31988,31990,
-31994,32006,32002,32028,32021,32010,32069,32075,32046,
+31994,32006},{32002,32028,32021,32010,32069,32075,32046,
32050,32063,32053,32070,32115,32086,32078,32114,32104,32110,32079,32099,32147,
32137,32091,32143,32125,32155,32186,32174,32163,32181,32199,32189,32171,32317,
32162,32175,32220,32184,32159,32176,32216,32221,32228,32222,32251,32242,32225,
32261,32266,32291,32289,32274,32305,32287,32265,32267,32290,32326,32358,32315,
32309,32313,32323,32311,32306,32314,32359,32349,32342,32350,32345,32346,32377,
32362,32361,32380,32379,32387,32213,32381,36782,32383,32392,32393,32396,32402,
-32400,32403,32404,32406,32398,32411,32412,32568,32570,32581,32588,32589,32590,
+32400,32403,32404,32406,32398,32411,32412,32568,32570},{32581,32588,32589,32590,
32592,32593,32597,32596,32600,32607,32608,32616,32617,32615,32632,32642,32646,
32643,32648,32647,32652,32660,32670,32669,32666,32675,32687,32690,32697,32686,
32694,32696,35697,32709,32710,32714,32725,32724,32737,32742,32745,32755,32761,
39132,32774,32772,32779,32786,32792,32793,32796,32801,32808,32831,32827,32842,
32838,32850,32856,32858,32863,32866,32872,32883,32882,32880,32886,32889,32893,
32895,32900,32902,32901,32923,32915,32922,32941,20880,32940,32987,32997,32985,
-32989,32964,32986,32982,33033,33007,33009,33051,33065,33059,33071,33099,38539,
+32989,32964,32986,32982,33033,33007,33009,33051,33065,33059,33071,33099},{38539,
33094,33086,33107,33105,33020,33137,33134,33125,33126,33140,33155,33160,33162,
33152,33154,33184,33173,33188,33187,33119,33171,33193,33200,33205,33214,33208,
33213,33216,33218,33210,33225,33229,33233,33241,33240,33224,33242,33247,33248,
@@ -469,21 +469,21 @@
33323,33336,33331,33344,33369,33368,33373,33370,33375,33380,33378,33384,33386,
33387,33326,33393,33399,33400,33406,33421,33426,33451,
33439,33467,33452,33505,33507,33503,33490,33524,33523,33530,33683,33539,33531,
-33529,33502,33542,33500,33545,33497,33589,33588,33558,33586,33585,33600,33593,
+33529,33502,33542,33500,33545,33497},{33589,33588,33558,33586,33585,33600,33593,
33616,33605,33583,33579,33559,33560,33669,33690,33706,33695,33698,33686,33571,
33678,33671,33674,33660,33717,33651,33653,33696,33673,33704,33780,33811,33771,
33742,33789,33795,33752,33803,33729,33783,33799,33760,33778,33805,33826,33824,
33725,33848,34054,33787,33901,33834,33852,34138,33924,33911,33899,33965,33902,
33922,33897,33862,33836,33903,33913,33845,33994,33890,33977,33983,33951,34009,
33997,33979,34010,34000,33985,33990,34006,33953,34081,34047,34036,34071,34072,
-34092,34079,34069,34068,34044,34112,34147,34136,34120,34113,34306,34123,34133,
+34092,34079,34069,34068,34044,34112,34147,34136,34120},{34113,34306,34123,34133,
34176,34212,34184,34193,34186,34216,34157,34196,34203,34282,34183,34204,34167,
34174,34192,34249,34234,34255,34233,34256,34261,34269,34277,34268,34297,34314,
34323,34315,34302,34298,34310,34338,34330,34352,34367,34381,20053,34388,34399,
34407,34417,34451,34467,34473,34474,34443,34444,34486,34479,34500,34502,34480,
34505,34851,34475,34516,34526,34537,34540,34527,34523,34543,34578,34566,34568,
34560,34563,34555,34577,34569,34573,34553,34570,34612,34623,34615,34619,34597,
-34601,34586,34656,34655,34680,34636,34638,34676,34647,34664,34670,34649,34643,
+34601,34586,34656,34655,34680,34636,34638,34676,34647,34664,34670,34649},{34643,
34659,34666,34821,34722,34719,34690,34735,34763,34749,34752,34768,38614,34731,
34756,34739,34759,34758,34747,34799,34802,34784,34831,34829,34814,34806,34807,
34830,34770,34833,34838,34837,34850,34849,34865,34870,34873,34855,34875,34884,
@@ -491,21 +491,21 @@
34933,34941,34997,34930,34946,34967,34962,34990,34969,34978,34957,34980,34992,
35007,34993,35011,35012,35028,35032,35033,35037,35065,35074,35068,35060,35048,
35058,35076,35084,35082,35091,35139,35102,35109,35114,35115,35137,35140,35131,
-35126,35128,35148,35101,35168,35166,35174,35172,35181,35178,35183,35188,35191,
+35126,35128,35148,35101,35168,35166},{35174,35172,35181,35178,35183,35188,35191,
35198,35203,35208,35210,35219,35224,35233,35241,35238,35244,35247,35250,35258,
35261,35263,35264,35290,35292,35293,35303,35316,35320,35331,35350,35344,35340,
35355,35357,35365,35382,35393,35419,35410,35398,35400,35452,35437,35436,35426,
35461,35458,35460,35496,35489,35473,35493,35494,35482,35491,35524,35533,35522,
35546,35563,35571,35559,35556,35569,35604,35552,35554,35575,35550,35547,35596,
35591,35610,35553,35606,35600,35607,35616,35635,38827,35622,35627,35646,35624,
-35649,35660,35663,35662,35657,35670,35675,35674,35691,35679,35692,35695,35700,
+35649,35660,35663,35662,35657,35670,35675,35674,35691},{35679,35692,35695,35700,
35709,35712,35724,35726,35730,35731,35734,35737,35738,35898,35905,35903,35912,
35916,35918,35920,35925,35938,35948,35960,35962,35970,35977,35973,35978,35981,
35982,35988,35964,35992,25117,36013,36010,36029,36018,36019,36014,36022,36040,
36033,36068,36067,36058,36093,36090,36091,36100,36101,36106,36103,36111,36109,
36112,40782,36115,36045,36116,36118,36199,36205,36209,36211,36225,36249,36290,
36286,36282,36303,36314,36310,36300,36315,36299,36330,36331,36319,36323,36348,
-36360,36361,36351,36381,36382,36368,36383,36418,36405,36400,36404,36426,36423,
+36360,36361,36351,36381,36382,36368,36383,36418,36405,36400,36404,36426},{36423,
36425,36428,36432,36424,36441,36452,36448,36394,36451,36437,36470,36466,36476,
36481,36487,36485,36484,36491,36490,36499,36497,36500,
36505,36522,36513,36524,36528,36550,36529,36542,36549,36552,36555,36571,36579,
@@ -513,14 +513,14 @@
36620,36646,36659,36667,36665,36677,36674,36670,36684,36681,36678,36686,36695,
36700,36706,36707,36708,36764,36767,36771,36781,36783,36791,36826,36837,36834,
36842,36847,36999,36852,36869,36857,36858,36881,36885,36897,36877,36894,36886,
-36875,36903,36918,36917,36921,36856,36943,36944,36945,36946,36878,36937,36926,
+36875,36903,36918,36917,36921,36856},{36943,36944,36945,36946,36878,36937,36926,
36950,36952,36958,36968,36975,36982,38568,36978,36994,36989,36993,36992,37002,
37001,37007,37032,37039,37041,37045,37090,37092,25160,37083,37122,37138,37145,
37170,37168,37194,37206,37208,37219,37221,37225,37235,37234,37259,37257,37250,
37282,37291,37295,37290,37301,37300,37306,37312,37313,37321,37323,37328,37334,
37343,37345,37339,37372,37365,37366,37406,37375,37396,37420,37397,37393,37470,
37463,37445,37449,37476,37448,37525,37439,37451,37456,37532,37526,37523,37531,
-37466,37583,37561,37559,37609,37647,37626,37700,37678,37657,37666,37658,37667,
+37466,37583,37561,37559,37609,37647,37626,37700,37678},{37657,37666,37658,37667,
37690,37685,37691,37724,37728,37756,37742,37718,37808,37804,37805,37780,37817,
37846,37847,37864,37861,37848,37827,37853,37840,37832,37860,37914,37908,37907,
37891,37895,37904,37942,37931,37941,37921,37946,37953,37970,37956,37979,37984,
@@ -528,21 +528,21 @@
38274,38279,38282,38292,38294,38296,38297,38304,38312,38311,38317,38332,38331,
38329,38334,38346,28662,38339,38349,38348,38357,38356,38358,38364,38369,38373,
38370,38433,38440,38446,38447,38466,38476,38479,38475,
-38519,38492,38494,38493,38495,38502,38514,38508,38541,38552,38549,38551,38570,
+38519,38492,38494},{38493,38495,38502,38514,38508,38541,38552,38549,38551,38570,
38567,38577,38578,38576,38580,38582,38584,38585,38606,38603,38601,38605,35149,
38620,38669,38613,38649,38660,38662,38664,38675,38670,38673,38671,38678,38681,
38692,38698,38704,38713,38717,38718,38724,38726,38728,38722,38729,38748,38752,
38756,38758,38760,21202,38763,38769,38777,38789,38780,38785,38778,38790,38795,
38799,38800,38812,38824,38822,38819,38835,38836,38851,38854,38856,38859,38876,
38893,40783,38898,31455,38902,38901,38927,38924,38968,38948,38945,38967,38973,
-38982,38991,38987,39019,39023,39024,39025,39028,39027,39082,39087,39089,39094,
+38982,38991,38987,39019,39023,39024},{39025,39028,39027,39082,39087,39089,39094,
39108,39107,39110,39145,39147,39171,39177,39186,39188,39192,39201,39197,39198,
39204,39200,39212,39214,39229,39230,39234,39241,39237,39248,39243,39249,39250,
39244,39253,39319,39320,39333,39341,39342,39356,39391,39387,39389,39384,39377,
39405,39406,39409,39410,39419,39416,39425,39439,39429,39394,39449,39467,39479,
39493,39490,39488,39491,39486,39509,39501,39515,39511,39519,39522,39525,39524,
39529,39531,39530,39597,39600,39612,39616,39631,39633,39635,39636,39646,39647,
-39650,39651,39654,39663,39659,39662,39668,39665,39671,39675,39686,39704,39706,
+39650,39651,39654,39663,39659,39662,39668,39665,39671},{39675,39686,39704,39706,
39711,39714,39715,39717,39719,39720,39721,39722,39726,39727,39730,39748,39747,
39759,39757,39758,39761,39768,39796,39827,39811,39825,39830,39831,39839,39840,
39848,39860,39872,39882,39865,39878,39887,39889,39890,39907,39906,39908,39892,
@@ -550,14 +550,14 @@
39946,39940,39982,39963,39973,39972,39969,39984,40007,
39986,40006,39998,40026,40032,40039,40054,40056,40167,40172,40176,40201,40200,
40171,40195,40198,40234,40230,40367,40227,40223,40260,40213,40210,40257,40255,
-40254,40262,40264,40285,40286,40292,40273,40272,40281,40306,40329,40327,40363,
+40254,40262,40264},{40285,40286,40292,40273,40272,40281,40306,40329,40327,40363,
40303,40314,40346,40356,40361,40370,40388,40385,40379,40376,40378,40390,40399,
40386,40409,40403,40440,40422,40429,40431,40445,40474,40475,40478,40565,40569,
40573,40577,40584,40587,40588,40594,40597,40593,40605,40613,40617,40632,40618,
40621,38753,40652,40654,40655,40656,40660,40668,40670,40669,40672,40677,40680,
40687,40692,40694,40695,40697,40699,40700,40701,40711,40712,30391,40725,40737,
40748,40766,40778,40786,40788,40803,40799,40800,40801,40806,40807,40812,40810,
-40823,40818,40822,40853,40860,40864,22575,27079,36953,29796,20956,29081,0,0,0,
+40823,40818,40822,40853,40860,40864},{22575,27079,36953,29796,20956,29081,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,
+0,0,0,0,0,0,0}
diff --git a/libm/aarch64/Makefile.arch b/libm/aarch64/Makefile.arch
new file mode 100644
index 000000000..bd38690be
--- /dev/null
+++ b/libm/aarch64/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/aarch64/fclrexcpt.c b/libm/aarch64/fclrexcpt.c
new file mode 100644
index 000000000..3dbd9a8bb
--- /dev/null
+++ b/libm/aarch64/fclrexcpt.c
@@ -0,0 +1,35 @@
+/* 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
+feclearexcept (int excepts)
+{
+ fpu_fpsr_t fpsr;
+ fpu_fpsr_t fpsr_new;
+
+ excepts &= FE_ALL_EXCEPT;
+
+ _FPU_GETFPSR (fpsr);
+ fpsr_new = fpsr & ~excepts;
+
+ if (fpsr != fpsr_new)
+ _FPU_SETFPSR (fpsr_new);
+
+ return 0;
+}
diff --git a/libm/aarch64/fedisblxcpt.c b/libm/aarch64/fedisblxcpt.c
new file mode 100644
index 000000000..a36873690
--- /dev/null
+++ b/libm/aarch64/fedisblxcpt.c
@@ -0,0 +1,34 @@
+/* Copyright (C) 2001-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 fpcr;
+ fpu_control_t fpcr_new;
+
+ _FPU_GETCW (fpcr);
+ excepts &= FE_ALL_EXCEPT;
+ fpcr_new = fpcr & ~(excepts << FE_EXCEPT_SHIFT);
+
+ if (fpcr != fpcr_new)
+ _FPU_SETCW (fpcr_new);
+
+ return (fpcr >> FE_EXCEPT_SHIFT) & FE_ALL_EXCEPT;
+}
diff --git a/libm/aarch64/feenablxcpt.c b/libm/aarch64/feenablxcpt.c
new file mode 100644
index 000000000..b5aa3bdc6
--- /dev/null
+++ b/libm/aarch64/feenablxcpt.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 2001-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 fpcr;
+ fpu_control_t fpcr_new;
+ fpu_control_t updated_fpcr;
+
+ _FPU_GETCW (fpcr);
+ excepts &= FE_ALL_EXCEPT;
+ fpcr_new = fpcr | (excepts << FE_EXCEPT_SHIFT);
+
+ if (fpcr != fpcr_new)
+ {
+ _FPU_SETCW (fpcr_new);
+
+ /* Trapping exceptions are optional in AArch64; the relevant enable
+ bits in FPCR are RES0 hence the absence of support can be detected
+ by reading back the FPCR and comparing with the required value. */
+ _FPU_GETCW (updated_fpcr);
+
+ if (fpcr_new & ~updated_fpcr)
+ return -1;
+ }
+
+ return (fpcr >> FE_EXCEPT_SHIFT) & FE_ALL_EXCEPT;
+}
diff --git a/libm/aarch64/fegetenv.c b/libm/aarch64/fegetenv.c
new file mode 100644
index 000000000..a85575eb8
--- /dev/null
+++ b/libm/aarch64/fegetenv.c
@@ -0,0 +1,30 @@
+/* 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 fpcr;
+ fpu_fpsr_t fpsr;
+ _FPU_GETCW (fpcr);
+ _FPU_GETFPSR (fpsr);
+ envp->__fpcr = fpcr;
+ envp->__fpsr = fpsr;
+ return 0;
+}
diff --git a/libm/aarch64/fegetexcept.c b/libm/aarch64/fegetexcept.c
new file mode 100644
index 000000000..a9eac299c
--- /dev/null
+++ b/libm/aarch64/fegetexcept.c
@@ -0,0 +1,26 @@
+/* Copyright (C) 2001-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 fpcr;
+ _FPU_GETCW (fpcr);
+ return (fpcr >> FE_EXCEPT_SHIFT) & FE_ALL_EXCEPT;
+}
diff --git a/libm/aarch64/fegetmode.c b/libm/aarch64/fegetmode.c
new file mode 100644
index 000000000..8393e6d05
--- /dev/null
+++ b/libm/aarch64/fegetmode.c
@@ -0,0 +1,26 @@
+/* Store current floating-point control modes. AArch64 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/aarch64/fegetround.c b/libm/aarch64/fegetround.c
new file mode 100644
index 000000000..1f34c6918
--- /dev/null
+++ b/libm/aarch64/fegetround.c
@@ -0,0 +1,35 @@
+/* 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>
+
+/* Return the floating-point rounding mode. */
+
+static inline int
+get_rounding_mode (void)
+{
+ fpu_control_t fpcr;
+
+ _FPU_GETCW (fpcr);
+ return fpcr & _FPU_FPCR_RM_MASK;
+}
+
+int
+fegetround (void)
+{
+ return get_rounding_mode ();
+}
diff --git a/libm/aarch64/feholdexcpt.c b/libm/aarch64/feholdexcpt.c
new file mode 100644
index 000000000..09c8cd38b
--- /dev/null
+++ b/libm/aarch64/feholdexcpt.c
@@ -0,0 +1,25 @@
+/* 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)
+{
+ libc_feholdexcept_aarch64 (envp);
+ return 0;
+}
diff --git a/libm/aarch64/fenv_private.h b/libm/aarch64/fenv_private.h
new file mode 100644
index 000000000..5afb790ea
--- /dev/null
+++ b/libm/aarch64/fenv_private.h
@@ -0,0 +1,300 @@
+/* Private floating point rounding and exceptions handling. AArch64 version.
+ Copyright (C) 2014-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 AARCH64_FENV_PRIVATE_H
+#define AARCH64_FENV_PRIVATE_H 1
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+static __always_inline void
+libc_feholdexcept_aarch64 (fenv_t *envp)
+{
+ fpu_control_t fpcr;
+ fpu_control_t new_fpcr;
+ fpu_fpsr_t fpsr;
+ fpu_fpsr_t new_fpsr;
+
+ _FPU_GETCW (fpcr);
+ _FPU_GETFPSR (fpsr);
+ envp->__fpcr = fpcr;
+ envp->__fpsr = fpsr;
+
+ /* Clear exception flags and set all exceptions to non-stop. */
+ new_fpcr = fpcr & ~(FE_ALL_EXCEPT << FE_EXCEPT_SHIFT);
+ new_fpsr = fpsr & ~FE_ALL_EXCEPT;
+
+ if (unlikely (new_fpcr != fpcr))
+ _FPU_SETCW (new_fpcr);
+
+ if (new_fpsr != fpsr)
+ _FPU_SETFPSR (new_fpsr);
+}
+
+#define libc_feholdexcept libc_feholdexcept_aarch64
+#define libc_feholdexceptf libc_feholdexcept_aarch64
+#define libc_feholdexceptl libc_feholdexcept_aarch64
+
+static __always_inline void
+libc_fesetround_aarch64 (int round)
+{
+ fpu_control_t fpcr;
+
+ _FPU_GETCW (fpcr);
+
+ /* Check whether rounding modes are different. */
+ round = (fpcr ^ round) & _FPU_FPCR_RM_MASK;
+
+ /* Set new rounding mode if different. */
+ if (unlikely (round != 0))
+ _FPU_SETCW (fpcr ^ round);
+}
+
+#define libc_fesetround libc_fesetround_aarch64
+#define libc_fesetroundf libc_fesetround_aarch64
+#define libc_fesetroundl libc_fesetround_aarch64
+
+static __always_inline void
+libc_feholdexcept_setround_aarch64 (fenv_t *envp, int round)
+{
+ fpu_control_t fpcr;
+ fpu_control_t new_fpcr;
+ fpu_fpsr_t fpsr;
+ fpu_fpsr_t new_fpsr;
+
+ _FPU_GETCW (fpcr);
+ _FPU_GETFPSR (fpsr);
+ envp->__fpcr = fpcr;
+ envp->__fpsr = fpsr;
+
+ /* Clear exception flags, set all exceptions to non-stop,
+ and set new rounding mode. */
+ new_fpcr = fpcr & ~((FE_ALL_EXCEPT << FE_EXCEPT_SHIFT) | _FPU_FPCR_RM_MASK);
+ new_fpcr |= round;
+ new_fpsr = fpsr & ~FE_ALL_EXCEPT;
+
+ if (unlikely (new_fpcr != fpcr))
+ _FPU_SETCW (new_fpcr);
+
+ if (new_fpsr != fpsr)
+ _FPU_SETFPSR (new_fpsr);
+}
+
+#define libc_feholdexcept_setround libc_feholdexcept_setround_aarch64
+#define libc_feholdexcept_setroundf libc_feholdexcept_setround_aarch64
+#define libc_feholdexcept_setroundl libc_feholdexcept_setround_aarch64
+
+static __always_inline int
+libc_fetestexcept_aarch64 (int ex)
+{
+ fpu_fpsr_t fpsr;
+
+ _FPU_GETFPSR (fpsr);
+ return fpsr & ex & FE_ALL_EXCEPT;
+}
+
+#define libc_fetestexcept libc_fetestexcept_aarch64
+#define libc_fetestexceptf libc_fetestexcept_aarch64
+#define libc_fetestexceptl libc_fetestexcept_aarch64
+
+static __always_inline void
+libc_fesetenv_aarch64 (const fenv_t *envp)
+{
+ fpu_control_t fpcr;
+ fpu_control_t new_fpcr;
+
+ _FPU_GETCW (fpcr);
+ new_fpcr = envp->__fpcr;
+
+ if (unlikely (fpcr != new_fpcr))
+ _FPU_SETCW (new_fpcr);
+
+ _FPU_SETFPSR (envp->__fpsr);
+}
+
+#define libc_fesetenv libc_fesetenv_aarch64
+#define libc_fesetenvf libc_fesetenv_aarch64
+#define libc_fesetenvl libc_fesetenv_aarch64
+#define libc_feresetround_noex libc_fesetenv_aarch64
+#define libc_feresetround_noexf libc_fesetenv_aarch64
+#define libc_feresetround_noexl libc_fesetenv_aarch64
+
+static __always_inline int
+libc_feupdateenv_test_aarch64 (const fenv_t *envp, int ex)
+{
+ fpu_control_t fpcr;
+ fpu_control_t new_fpcr;
+ fpu_fpsr_t fpsr;
+ fpu_fpsr_t new_fpsr;
+ int excepts;
+
+ _FPU_GETCW (fpcr);
+ _FPU_GETFPSR (fpsr);
+
+ /* Merge current exception flags with the saved fenv. */
+ excepts = fpsr & FE_ALL_EXCEPT;
+ new_fpcr = envp->__fpcr;
+ new_fpsr = envp->__fpsr | excepts;
+
+ if (unlikely (fpcr != new_fpcr))
+ _FPU_SETCW (new_fpcr);
+
+ if (fpsr != new_fpsr)
+ _FPU_SETFPSR (new_fpsr);
+
+ /* Raise the exceptions if enabled in the new FP state. */
+ if (unlikely (excepts & (new_fpcr >> FE_EXCEPT_SHIFT)))
+ feraiseexcept (excepts);
+
+ return excepts & ex;
+}
+
+#define libc_feupdateenv_test libc_feupdateenv_test_aarch64
+#define libc_feupdateenv_testf libc_feupdateenv_test_aarch64
+#define libc_feupdateenv_testl libc_feupdateenv_test_aarch64
+
+static __always_inline void
+libc_feupdateenv_aarch64 (const fenv_t *envp)
+{
+ libc_feupdateenv_test_aarch64 (envp, 0);
+}
+
+#define libc_feupdateenv libc_feupdateenv_aarch64
+#define libc_feupdateenvf libc_feupdateenv_aarch64
+#define libc_feupdateenvl libc_feupdateenv_aarch64
+
+static __always_inline void
+libc_feholdsetround_aarch64 (fenv_t *envp, int round)
+{
+ fpu_control_t fpcr;
+ fpu_fpsr_t fpsr;
+
+ _FPU_GETCW (fpcr);
+ _FPU_GETFPSR (fpsr);
+ envp->__fpcr = fpcr;
+ envp->__fpsr = fpsr;
+
+ /* Check whether rounding modes are different. */
+ round = (fpcr ^ round) & _FPU_FPCR_RM_MASK;
+
+ /* Set new rounding mode if different. */
+ if (unlikely (round != 0))
+ _FPU_SETCW (fpcr ^ round);
+}
+
+#define libc_feholdsetround libc_feholdsetround_aarch64
+#define libc_feholdsetroundf libc_feholdsetround_aarch64
+#define libc_feholdsetroundl libc_feholdsetround_aarch64
+
+static __always_inline void
+libc_feresetround_aarch64 (fenv_t *envp)
+{
+ fpu_control_t fpcr;
+ int round;
+
+ _FPU_GETCW (fpcr);
+
+ /* Check whether rounding modes are different. */
+ round = (envp->__fpcr ^ fpcr) & _FPU_FPCR_RM_MASK;
+
+ /* Restore the rounding mode if it was changed. */
+ if (unlikely (round != 0))
+ _FPU_SETCW (fpcr ^ round);
+}
+
+#define libc_feresetround libc_feresetround_aarch64
+#define libc_feresetroundf libc_feresetround_aarch64
+#define libc_feresetroundl libc_feresetround_aarch64
+
+/* We have support for rounding mode context. */
+#define HAVE_RM_CTX 1
+
+static __always_inline void
+libc_feholdsetround_aarch64_ctx (struct rm_ctx *ctx, int r)
+{
+ fpu_control_t fpcr;
+ int round;
+
+ _FPU_GETCW (fpcr);
+ ctx->env.__fpcr = fpcr;
+
+ /* Check whether rounding modes are different. */
+ round = (fpcr ^ r) & _FPU_FPCR_RM_MASK;
+ ctx->updated_status = round != 0;
+
+ /* Set the rounding mode if changed. */
+ if (unlikely (round != 0))
+ _FPU_SETCW (fpcr ^ round);
+}
+
+#define libc_feholdsetround_ctx libc_feholdsetround_aarch64_ctx
+#define libc_feholdsetroundf_ctx libc_feholdsetround_aarch64_ctx
+#define libc_feholdsetroundl_ctx libc_feholdsetround_aarch64_ctx
+
+static __always_inline void
+libc_feresetround_aarch64_ctx (struct rm_ctx *ctx)
+{
+ /* Restore the rounding mode if updated. */
+ if (unlikely (ctx->updated_status))
+ _FPU_SETCW (ctx->env.__fpcr);
+}
+
+#define libc_feresetround_ctx libc_feresetround_aarch64_ctx
+#define libc_feresetroundf_ctx libc_feresetround_aarch64_ctx
+#define libc_feresetroundl_ctx libc_feresetround_aarch64_ctx
+
+static __always_inline void
+libc_feholdsetround_noex_aarch64_ctx (struct rm_ctx *ctx, int r)
+{
+ fpu_control_t fpcr;
+ fpu_fpsr_t fpsr;
+ int round;
+
+ _FPU_GETCW (fpcr);
+ _FPU_GETFPSR (fpsr);
+ ctx->env.__fpcr = fpcr;
+ ctx->env.__fpsr = fpsr;
+
+ /* Check whether rounding modes are different. */
+ round = (fpcr ^ r) & _FPU_FPCR_RM_MASK;
+ ctx->updated_status = round != 0;
+
+ /* Set the rounding mode if changed. */
+ if (unlikely (round != 0))
+ _FPU_SETCW (fpcr ^ round);
+}
+
+#define libc_feholdsetround_noex_ctx libc_feholdsetround_noex_aarch64_ctx
+#define libc_feholdsetround_noexf_ctx libc_feholdsetround_noex_aarch64_ctx
+#define libc_feholdsetround_noexl_ctx libc_feholdsetround_noex_aarch64_ctx
+
+static __always_inline void
+libc_feresetround_noex_aarch64_ctx (struct rm_ctx *ctx)
+{
+ /* Restore the rounding mode if updated. */
+ if (unlikely (ctx->updated_status))
+ _FPU_SETCW (ctx->env.__fpcr);
+
+ /* Write new FPSR to restore exception flags. */
+ _FPU_SETFPSR (ctx->env.__fpsr);
+}
+
+#define libc_feresetround_noex_ctx libc_feresetround_noex_aarch64_ctx
+#define libc_feresetround_noexf_ctx libc_feresetround_noex_aarch64_ctx
+#define libc_feresetround_noexl_ctx libc_feresetround_noex_aarch64_ctx
+
+#endif
diff --git a/libm/aarch64/fesetenv.c b/libm/aarch64/fesetenv.c
new file mode 100644
index 000000000..eb7a08da0
--- /dev/null
+++ b/libm/aarch64/fesetenv.c
@@ -0,0 +1,73 @@
+/* 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
+fesetenv (const fenv_t *envp)
+{
+ fpu_control_t fpcr;
+ fpu_control_t fpcr_new;
+ fpu_control_t updated_fpcr;
+ fpu_fpsr_t fpsr;
+ fpu_fpsr_t fpsr_new;
+
+ _FPU_GETCW (fpcr);
+
+ if ((envp != FE_DFL_ENV) && (envp != FE_NOMASK_ENV))
+ {
+ /* The new FPCR/FPSR are valid, so don't merge the reserved flags. */
+ fpcr_new = envp->__fpcr;
+
+ if (fpcr != fpcr_new)
+ _FPU_SETCW (fpcr_new);
+
+ _FPU_SETFPSR (envp->__fpsr);
+ return 0;
+ }
+
+ _FPU_GETFPSR (fpsr);
+ fpcr_new = fpcr & _FPU_RESERVED;
+ fpsr_new = fpsr & _FPU_FPSR_RESERVED;
+
+ if (envp == FE_DFL_ENV)
+ {
+ fpcr_new |= _FPU_DEFAULT;
+ fpsr_new |= _FPU_FPSR_DEFAULT;
+ }
+ else
+ {
+ fpcr_new |= _FPU_FPCR_IEEE;
+ fpsr_new |= _FPU_FPSR_IEEE;
+ }
+
+ _FPU_SETFPSR (fpsr_new);
+
+ if (fpcr != fpcr_new)
+ {
+ _FPU_SETCW (fpcr_new);
+
+ /* Trapping exceptions are optional in AArch64; the relevant enable
+ bits in FPCR are RES0 hence the absence of support can be detected
+ by reading back the FPCR and comparing with the required value. */
+ _FPU_GETCW (updated_fpcr);
+
+ return fpcr_new & ~updated_fpcr;
+ }
+
+ return 0;
+}
diff --git a/libm/aarch64/fesetexcept.c b/libm/aarch64/fesetexcept.c
new file mode 100644
index 000000000..14a0b4232
--- /dev/null
+++ b/libm/aarch64/fesetexcept.c
@@ -0,0 +1,33 @@
+/* Set given exception flags. AArch64 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_fpsr_t fpsr;
+ fpu_fpsr_t fpsr_new;
+
+ _FPU_GETFPSR (fpsr);
+ fpsr_new = fpsr | (excepts & FE_ALL_EXCEPT);
+ if (fpsr != fpsr_new)
+ _FPU_SETFPSR (fpsr_new);
+
+ return 0;
+}
diff --git a/libm/aarch64/fesetmode.c b/libm/aarch64/fesetmode.c
new file mode 100644
index 000000000..34e7c9316
--- /dev/null
+++ b/libm/aarch64/fesetmode.c
@@ -0,0 +1,33 @@
+/* Install given floating-point control modes. AArch64 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
+fesetmode (const femode_t *modep)
+{
+ fpu_control_t fpcr, fpcr_new;
+ _FPU_GETCW (fpcr);
+ if (modep == FE_DFL_MODE)
+ fpcr_new = (fpcr & _FPU_RESERVED) | _FPU_DEFAULT;
+ else
+ fpcr_new = *modep;
+ if (fpcr != fpcr_new)
+ _FPU_SETCW (fpcr_new);
+ return 0;
+}
diff --git a/libm/aarch64/fesetround.c b/libm/aarch64/fesetround.c
new file mode 100644
index 000000000..63a558258
--- /dev/null
+++ b/libm/aarch64/fesetround.c
@@ -0,0 +1,29 @@
+/* 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 <fpu_control.h>
+
+int
+fesetround (int round)
+{
+ if (round & ~_FPU_FPCR_RM_MASK)
+ return 1;
+
+ libc_fesetround_aarch64 (round);
+ return 0;
+}
diff --git a/libm/aarch64/feupdateenv.c b/libm/aarch64/feupdateenv.c
new file mode 100644
index 000000000..2b4e62ecc
--- /dev/null
+++ b/libm/aarch64/feupdateenv.c
@@ -0,0 +1,84 @@
+/* Copyright (C) 2009-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 fpcr;
+ fpu_control_t fpcr_new;
+ fpu_control_t updated_fpcr;
+ fpu_fpsr_t fpsr;
+ fpu_fpsr_t fpsr_new;
+ int excepts;
+
+ _FPU_GETCW (fpcr);
+ _FPU_GETFPSR (fpsr);
+ excepts = fpsr & FE_ALL_EXCEPT;
+
+ if ((envp != FE_DFL_ENV) && (envp != FE_NOMASK_ENV))
+ {
+ fpcr_new = envp->__fpcr;
+ fpsr_new = envp->__fpsr | excepts;
+
+ if (fpcr != fpcr_new)
+ _FPU_SETCW (fpcr_new);
+
+ if (fpsr != fpsr_new)
+ _FPU_SETFPSR (fpsr_new);
+
+ if (excepts & (fpcr_new >> FE_EXCEPT_SHIFT))
+ return feraiseexcept (excepts);
+
+ return 0;
+ }
+
+ fpcr_new = fpcr & _FPU_RESERVED;
+ fpsr_new = fpsr & (_FPU_FPSR_RESERVED | FE_ALL_EXCEPT);
+
+ if (envp == FE_DFL_ENV)
+ {
+ fpcr_new |= _FPU_DEFAULT;
+ fpsr_new |= _FPU_FPSR_DEFAULT;
+ }
+ else
+ {
+ fpcr_new |= _FPU_FPCR_IEEE;
+ fpsr_new |= _FPU_FPSR_IEEE;
+ }
+
+ _FPU_SETFPSR (fpsr_new);
+
+ if (fpcr != fpcr_new)
+ {
+ _FPU_SETCW (fpcr_new);
+
+ /* Trapping exceptions are optional in AArch64; the relevant enable
+ bits in FPCR are RES0 hence the absence of support can be detected
+ by reading back the FPCR and comparing with the required value. */
+ _FPU_GETCW (updated_fpcr);
+
+ if (fpcr_new & ~updated_fpcr)
+ return 1;
+ }
+
+ if (excepts & (fpcr_new >> FE_EXCEPT_SHIFT))
+ return feraiseexcept (excepts);
+
+ return 0;
+}
diff --git a/libm/aarch64/fgetexcptflg.c b/libm/aarch64/fgetexcptflg.c
new file mode 100644
index 000000000..2c8920989
--- /dev/null
+++ b/libm/aarch64/fgetexcptflg.c
@@ -0,0 +1,25 @@
+/* Copyright (C) 2001-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)
+{
+ *flagp = libc_fetestexcept_aarch64 (excepts);
+ return 0;
+}
diff --git a/libm/aarch64/fraiseexcpt.c b/libm/aarch64/fraiseexcpt.c
new file mode 100644
index 000000000..6a016d046
--- /dev/null
+++ b/libm/aarch64/fraiseexcpt.c
@@ -0,0 +1,89 @@
+/* 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>
+#include <float.h>
+#include <stdint.h>
+
+int
+feraiseexcept (int excepts)
+{
+ uint64_t fpsr;
+ const float fp_zero = 0.0;
+ const float fp_one = 1.0;
+ const float fp_max = FLT_MAX;
+ const float fp_min = FLT_MIN;
+ const float fp_1e32 = 1.0e32f;
+ const float fp_two = 2.0;
+ const float fp_three = 3.0;
+
+ /* Raise exceptions represented by EXCEPTS. But we must raise only
+ one signal at a time. It is important that if the OVERFLOW or
+ UNDERFLOW exception and the inexact exception are given at the
+ same time, the OVERFLOW or UNDERFLOW exception precedes the
+ INEXACT exception.
+
+ After each exception we read from the FPSR, to force the
+ exception to be raised immediately. */
+
+ if (FE_INVALID & excepts)
+ __asm__ __volatile__ (
+ "ldr s0, %1\n\t"
+ "fdiv s0, s0, s0\n\t"
+ "mrs %0, fpsr" : "=r" (fpsr)
+ : "m" (fp_zero)
+ : "d0");
+
+ if (FE_DIVBYZERO & excepts)
+ __asm__ __volatile__ (
+ "ldr s0, %1\n\t"
+ "ldr s1, %2\n\t"
+ "fdiv s0, s0, s1\n\t"
+ "mrs %0, fpsr" : "=r" (fpsr)
+ : "m" (fp_one), "m" (fp_zero)
+ : "d0", "d1");
+
+ if (FE_OVERFLOW & excepts)
+ /* There's no way to raise overflow without also raising inexact. */
+ __asm__ __volatile__ (
+ "ldr s0, %1\n\t"
+ "ldr s1, %2\n\t"
+ "fadd s0, s0, s1\n\t"
+ "mrs %0, fpsr" : "=r" (fpsr)
+ : "m" (fp_max), "m" (fp_1e32)
+ : "d0", "d1");
+
+ if (FE_UNDERFLOW & excepts)
+ __asm__ __volatile__ (
+ "ldr s0, %1\n\t"
+ "ldr s1, %2\n\t"
+ "fdiv s0, s0, s1\n\t"
+ "mrs %0, fpsr" : "=r" (fpsr)
+ : "m" (fp_min), "m" (fp_three)
+ : "d0", "d1");
+
+ if (FE_INEXACT & excepts)
+ __asm__ __volatile__ (
+ "ldr s0, %1\n\t"
+ "ldr s1, %2\n\t"
+ "fdiv s0, s0, s1\n\t"
+ "mrs %0, fpsr" : "=r" (fpsr)
+ : "m" (fp_two), "m" (fp_three)
+ : "d0", "d1");
+
+ return 0;
+}
diff --git a/libm/aarch64/fsetexcptflg.c b/libm/aarch64/fsetexcptflg.c
new file mode 100644
index 000000000..a78623d14
--- /dev/null
+++ b/libm/aarch64/fsetexcptflg.c
@@ -0,0 +1,39 @@
+/* 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
+fesetexceptflag (const fexcept_t *flagp, int excepts)
+{
+ fpu_fpsr_t fpsr;
+ fpu_fpsr_t fpsr_new;
+
+ /* Get the current environment. */
+ _FPU_GETFPSR (fpsr);
+ excepts &= FE_ALL_EXCEPT;
+
+ /* Set the desired exception mask. */
+ fpsr_new = fpsr & ~excepts;
+ fpsr_new |= *flagp & excepts;
+
+ /* Save state back to the FPU. */
+ if (fpsr != fpsr_new)
+ _FPU_SETFPSR (fpsr_new);
+
+ return 0;
+}
diff --git a/libm/aarch64/ftestexcept.c b/libm/aarch64/ftestexcept.c
new file mode 100644
index 000000000..eecb93406
--- /dev/null
+++ b/libm/aarch64/ftestexcept.c
@@ -0,0 +1,24 @@
+/* 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)
+{
+ return libc_fetestexcept_aarch64 (excepts);
+}
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/arm/Makefile.arch b/libm/arm/Makefile.arch
new file mode 100644
index 000000000..bd38690be
--- /dev/null
+++ b/libm/arm/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/arm/arm-features.h b/libm/arm/arm-features.h
new file mode 100644
index 000000000..8f9fd7362
--- /dev/null
+++ b/libm/arm/arm-features.h
@@ -0,0 +1,58 @@
+/* Macros to test for CPU features on ARM. Generic ARM version.
+ 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/>. */
+
+#ifndef _ARM_ARM_FEATURES_H
+#define _ARM_ARM_FEATURES_H 1
+
+/* An OS-specific arm-features.h file should define ARM_HAVE_VFP to
+ an appropriate expression for testing at runtime whether the VFP
+ hardware is present. We'll then redefine it to a constant if we
+ know at compile time that we can assume VFP. */
+
+#ifndef __SOFTFP__
+/* The compiler is generating VFP instructions, so we're already
+ assuming the hardware exists. */
+# undef ARM_HAVE_VFP
+# define ARM_HAVE_VFP 1
+#endif
+
+/* An OS-specific arm-features.h file may define ARM_ASSUME_NO_IWMMXT
+ to indicate at compile time that iWMMXt hardware is never present
+ at runtime (or that we never care about its state) and so need not
+ be checked for. */
+
+/* A more-specific arm-features.h file may define ARM_ALWAYS_BX to indicate
+ that instructions using pc as a destination register must never be used,
+ so a "bx" (or "blx") instruction is always required. */
+
+/* The log2 of the minimum alignment required for an address that
+ is the target of a computed branch (i.e. a "bx" instruction).
+ A more-specific arm-features.h file may define this to set a more
+ stringent requirement.
+
+ Using this only makes sense for code in ARM mode (where instructions
+ always have a fixed size of four bytes), or for Thumb-mode code that is
+ specifically aligning all the related branch targets to match (since
+ Thumb instructions might be either two or four bytes). */
+#ifndef ARM_BX_ALIGN_LOG2
+# define ARM_BX_ALIGN_LOG2 2
+#endif
+
+/* An OS-specific arm-features.h file may define ARM_NO_INDEX_REGISTER to
+ indicate that the two-register addressing modes must never be used. */
+
+#endif /* arm-features.h */
diff --git a/libm/arm/fclrexcpt.c b/libm/arm/fclrexcpt.c
new file mode 100644
index 000000000..81de94271
--- /dev/null
+++ b/libm/arm/fclrexcpt.c
@@ -0,0 +1,41 @@
+/* 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 <fpu_control.h>
+#include "arm-features.h"
+
+
+int
+feclearexcept (int excepts)
+{
+ fpu_control_t fpscr, new_fpscr;
+
+ /* Fail if a VFP unit isn't present unless nothing needs to be done. */
+ if (!ARM_HAVE_VFP)
+ return (excepts != 0);
+
+ _FPU_GETCW (fpscr);
+ excepts &= FE_ALL_EXCEPT;
+ new_fpscr = fpscr & ~excepts;
+
+ /* Write new exception flags if changed. */
+ if (new_fpscr != fpscr)
+ _FPU_SETCW (new_fpscr);
+
+ return 0;
+}
diff --git a/libm/arm/fedisblxcpt.c b/libm/arm/fedisblxcpt.c
new file mode 100644
index 000000000..c507e80b4
--- /dev/null
+++ b/libm/arm/fedisblxcpt.c
@@ -0,0 +1,41 @@
+/* Disable floating-point exceptions.
+ Copyright (C) 2001-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 "arm-features.h"
+
+
+int
+fedisableexcept (int excepts)
+{
+ fpu_control_t fpscr, new_fpscr;
+
+ /* Fail if a VFP unit isn't present. */
+ if (!ARM_HAVE_VFP)
+ return -1;
+
+ _FPU_GETCW (fpscr);
+ excepts &= FE_ALL_EXCEPT;
+ new_fpscr = fpscr & ~(excepts << FE_EXCEPT_SHIFT);
+
+ /* Write new exceptions if changed. */
+ if (new_fpscr != fpscr)
+ _FPU_SETCW (new_fpscr);
+
+ return (fpscr >> FE_EXCEPT_SHIFT) & FE_ALL_EXCEPT;
+}
diff --git a/libm/arm/feenablxcpt.c b/libm/arm/feenablxcpt.c
new file mode 100644
index 000000000..41e8eb912
--- /dev/null
+++ b/libm/arm/feenablxcpt.c
@@ -0,0 +1,49 @@
+/* Enable floating-point exceptions.
+ Copyright (C) 2001-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 "arm-features.h"
+
+
+int
+feenableexcept (int excepts)
+{
+ fpu_control_t fpscr, new_fpscr, updated_fpscr;
+
+ /* Fail if a VFP unit isn't present. */
+ if (!ARM_HAVE_VFP)
+ return -1;
+
+ _FPU_GETCW (fpscr);
+ excepts &= FE_ALL_EXCEPT;
+ new_fpscr = fpscr | (excepts << FE_EXCEPT_SHIFT);
+
+ if (new_fpscr != fpscr)
+ {
+ _FPU_SETCW (new_fpscr);
+
+ /* Not all VFP architectures support trapping exceptions, so
+ test whether the relevant bits were set and fail if not. */
+ _FPU_GETCW (updated_fpscr);
+
+ if (new_fpscr & ~updated_fpscr)
+ return -1;
+ }
+
+ return (fpscr >> FE_EXCEPT_SHIFT) & FE_ALL_EXCEPT;
+}
diff --git a/libm/arm/fegetenv.c b/libm/arm/fegetenv.c
new file mode 100644
index 000000000..a9f63f5c9
--- /dev/null
+++ b/libm/arm/fegetenv.c
@@ -0,0 +1,35 @@
+/* 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>
+#include "arm-features.h"
+
+
+int
+fegetenv (fenv_t *envp)
+{
+ fpu_control_t fpscr;
+
+ /* Fail if a VFP unit isn't present. */
+ if (!ARM_HAVE_VFP)
+ return 1;
+
+ _FPU_GETCW (fpscr);
+ envp->__cw = fpscr;
+ return 0;
+}
diff --git a/libm/arm/fegetexcept.c b/libm/arm/fegetexcept.c
new file mode 100644
index 000000000..5dd8e144b
--- /dev/null
+++ b/libm/arm/fegetexcept.c
@@ -0,0 +1,35 @@
+/* Get floating-point exceptions.
+ Copyright (C) 2001-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 "arm-features.h"
+
+
+int
+fegetexcept (void)
+{
+ fpu_control_t fpscr;
+
+ /* Return with all exceptions disabled if a VFP unit isn't present. */
+ if (!ARM_HAVE_VFP)
+ return 0;
+
+ _FPU_GETCW (fpscr);
+
+ return (fpscr >> FE_EXCEPT_SHIFT) & FE_ALL_EXCEPT;
+}
diff --git a/libm/arm/fegetmode.c b/libm/arm/fegetmode.c
new file mode 100644
index 000000000..bf2597353
--- /dev/null
+++ b/libm/arm/fegetmode.c
@@ -0,0 +1,28 @@
+/* Store current floating-point control modes. ARM 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>
+#include "arm-features.h"
+
+int
+fegetmode (femode_t *modep)
+{
+ if (ARM_HAVE_VFP)
+ _FPU_GETCW (*modep);
+ return 0;
+}
diff --git a/libm/arm/fegetround.c b/libm/arm/fegetround.c
new file mode 100644
index 000000000..2f9320491
--- /dev/null
+++ b/libm/arm/fegetround.c
@@ -0,0 +1,42 @@
+/* Return current rounding direction.
+ Copyright (C) 2004-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 "arm-features.h"
+#include <fenv.h>
+#include <fpu_control.h>
+
+/* Return the floating-point rounding mode. */
+
+static inline int
+get_rounding_mode (void)
+{
+ fpu_control_t fpscr;
+
+ /* FE_TONEAREST is the only supported rounding mode
+ if a VFP unit isn't present. */
+ if (!ARM_HAVE_VFP)
+ return FE_TONEAREST;
+
+ _FPU_GETCW (fpscr);
+ return fpscr & _FPU_MASK_RM;
+}
+
+int
+fegetround (void)
+{
+ return get_rounding_mode ();
+}
diff --git a/libm/arm/feholdexcpt.c b/libm/arm/feholdexcpt.c
new file mode 100644
index 000000000..3608931db
--- /dev/null
+++ b/libm/arm/feholdexcpt.c
@@ -0,0 +1,31 @@
+/* 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_private.h"
+#include "arm-features.h"
+
+
+int
+feholdexcept (fenv_t *envp)
+{
+ /* Fail if a VFP unit isn't present. */
+ if (!ARM_HAVE_VFP)
+ return 1;
+
+ libc_feholdexcept_vfp (envp);
+ return 0;
+}
diff --git a/libm/arm/fenv_private.h b/libm/arm/fenv_private.h
new file mode 100644
index 000000000..566bf443c
--- /dev/null
+++ b/libm/arm/fenv_private.h
@@ -0,0 +1,248 @@
+/* Private floating point rounding and exceptions handling. ARM VFP version.
+ Copyright (C) 2014-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 ARM_FENV_PRIVATE_H
+#define ARM_FENV_PRIVATE_H 1
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+static __always_inline void
+libc_feholdexcept_vfp (fenv_t *envp)
+{
+ fpu_control_t fpscr;
+
+ _FPU_GETCW (fpscr);
+ envp->__cw = fpscr;
+
+ /* Clear exception flags and set all exceptions to non-stop. */
+ fpscr &= ~_FPU_MASK_EXCEPT;
+ _FPU_SETCW (fpscr);
+}
+
+static __always_inline void
+libc_fesetround_vfp (int round)
+{
+ fpu_control_t fpscr;
+
+ _FPU_GETCW (fpscr);
+
+ /* Set new rounding mode if different. */
+ if (unlikely ((fpscr & _FPU_MASK_RM) != round))
+ _FPU_SETCW ((fpscr & ~_FPU_MASK_RM) | round);
+}
+
+static __always_inline void
+libc_feholdexcept_setround_vfp (fenv_t *envp, int round)
+{
+ fpu_control_t fpscr;
+
+ _FPU_GETCW (fpscr);
+ envp->__cw = fpscr;
+
+ /* Clear exception flags, set all exceptions to non-stop,
+ and set new rounding mode. */
+ fpscr &= ~(_FPU_MASK_EXCEPT | _FPU_MASK_RM);
+ _FPU_SETCW (fpscr | round);
+}
+
+static __always_inline void
+libc_feholdsetround_vfp (fenv_t *envp, int round)
+{
+ fpu_control_t fpscr;
+
+ _FPU_GETCW (fpscr);
+ envp->__cw = fpscr;
+
+ /* Set new rounding mode if different. */
+ if (unlikely ((fpscr & _FPU_MASK_RM) != round))
+ _FPU_SETCW ((fpscr & ~_FPU_MASK_RM) | round);
+}
+
+static __always_inline void
+libc_feresetround_vfp (fenv_t *envp)
+{
+ fpu_control_t fpscr, round;
+
+ _FPU_GETCW (fpscr);
+
+ /* Check whether rounding modes are different. */
+ round = (envp->__cw ^ fpscr) & _FPU_MASK_RM;
+
+ /* Restore the rounding mode if it was changed. */
+ if (unlikely (round != 0))
+ _FPU_SETCW (fpscr ^ round);
+}
+
+static __always_inline int
+libc_fetestexcept_vfp (int ex)
+{
+ fpu_control_t fpscr;
+
+ _FPU_GETCW (fpscr);
+ return fpscr & ex & FE_ALL_EXCEPT;
+}
+
+static __always_inline void
+libc_fesetenv_vfp (const fenv_t *envp)
+{
+ fpu_control_t fpscr, new_fpscr;
+
+ _FPU_GETCW (fpscr);
+ new_fpscr = envp->__cw;
+
+ /* Write new FPSCR if different (ignoring NZCV flags). */
+ if (unlikely (((fpscr ^ new_fpscr) & ~_FPU_MASK_NZCV) != 0))
+ _FPU_SETCW (new_fpscr);
+}
+
+static __always_inline int
+libc_feupdateenv_test_vfp (const fenv_t *envp, int ex)
+{
+ fpu_control_t fpscr, new_fpscr;
+ int excepts;
+
+ _FPU_GETCW (fpscr);
+
+ /* Merge current exception flags with the saved fenv. */
+ excepts = fpscr & FE_ALL_EXCEPT;
+ new_fpscr = envp->__cw | excepts;
+
+ /* Write new FPSCR if different (ignoring NZCV flags). */
+ if (unlikely (((fpscr ^ new_fpscr) & ~_FPU_MASK_NZCV) != 0))
+ _FPU_SETCW (new_fpscr);
+
+ /* Raise the exceptions if enabled in the new FP state. */
+ if (unlikely (excepts & (new_fpscr >> FE_EXCEPT_SHIFT)))
+ 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 fpscr, round;
+
+ _FPU_GETCW (fpscr);
+ ctx->updated_status = false;
+ ctx->env.__cw = fpscr;
+
+ /* Check whether rounding modes are different. */
+ round = (fpscr ^ r) & _FPU_MASK_RM;
+
+ /* Set the rounding mode if changed. */
+ if (unlikely (round != 0))
+ {
+ ctx->updated_status = true;
+ _FPU_SETCW (fpscr ^ 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 fpscr;
+
+ _FPU_GETCW (fpscr);
+ fpscr = (fpscr & ~_FPU_MASK_RM) | (ctx->env.__cw & _FPU_MASK_RM);
+ _FPU_SETCW (fpscr);
+ }
+}
+
+static __always_inline void
+libc_fesetenv_vfp_ctx (struct rm_ctx *ctx)
+{
+ fpu_control_t fpscr, new_fpscr;
+
+ _FPU_GETCW (fpscr);
+ new_fpscr = ctx->env.__cw;
+
+ /* Write new FPSCR if different (ignoring NZCV flags). */
+ if (unlikely (((fpscr ^ new_fpscr) & ~_FPU_MASK_NZCV) != 0))
+ _FPU_SETCW (new_fpscr);
+}
+
+#ifndef __SOFTFP__
+
+# 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
+
+#endif /* ARM_FENV_PRIVATE_H */
diff --git a/libm/arm/fesetenv.c b/libm/arm/fesetenv.c
new file mode 100644
index 000000000..4675dbe88
--- /dev/null
+++ b/libm/arm/fesetenv.c
@@ -0,0 +1,62 @@
+/* Install given floating-point environment.
+ Copyright (C) 2004-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 "arm-features.h"
+
+
+int
+fesetenv (const fenv_t *envp)
+{
+ fpu_control_t fpscr, new_fpscr, updated_fpscr;
+
+ /* Fail if a VFP unit isn't present. */
+ if (!ARM_HAVE_VFP)
+ return 1;
+
+ _FPU_GETCW (fpscr);
+
+ if ((envp != FE_DFL_ENV) && (envp != FE_NOMASK_ENV))
+ {
+ /* The new FPSCR is valid, so don't merge the reserved flags. */
+ new_fpscr = envp->__cw;
+
+ /* Write new FPSCR if different (ignoring NZCV flags). */
+ if (((fpscr ^ new_fpscr) & ~_FPU_MASK_NZCV) != 0)
+ _FPU_SETCW (new_fpscr);
+
+ return 0;
+ }
+
+ /* Preserve the reserved FPSCR flags. */
+ new_fpscr = fpscr & _FPU_RESERVED;
+ new_fpscr |= (envp == FE_DFL_ENV) ? _FPU_DEFAULT : _FPU_IEEE;
+
+ if (((new_fpscr ^ fpscr) & ~_FPU_MASK_NZCV) != 0)
+ {
+ _FPU_SETCW (new_fpscr);
+
+ /* Not all VFP architectures support trapping exceptions, so
+ test whether the relevant bits were set and fail if not. */
+ _FPU_GETCW (updated_fpscr);
+
+ return new_fpscr & ~updated_fpscr;
+ }
+
+ return 0;
+}
diff --git a/libm/arm/fesetexcept.c b/libm/arm/fesetexcept.c
new file mode 100644
index 000000000..03338c783
--- /dev/null
+++ b/libm/arm/fesetexcept.c
@@ -0,0 +1,37 @@
+/* Set given exception flags. ARM 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>
+#include "arm-features.h"
+
+int
+fesetexcept (int excepts)
+{
+ fpu_control_t fpscr, new_fpscr;
+
+ /* Fail if a VFP unit isn't present unless nothing needs to be done. */
+ if (!ARM_HAVE_VFP)
+ return (excepts != 0);
+
+ _FPU_GETCW (fpscr);
+ new_fpscr = fpscr | (excepts & FE_ALL_EXCEPT);
+ if (new_fpscr != fpscr)
+ _FPU_SETCW (new_fpscr);
+
+ return 0;
+}
diff --git a/libm/arm/fesetmode.c b/libm/arm/fesetmode.c
new file mode 100644
index 000000000..7919022b0
--- /dev/null
+++ b/libm/arm/fesetmode.c
@@ -0,0 +1,44 @@
+/* Install given floating-point control modes. ARM 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>
+#include "arm-features.h"
+
+/* NZCV flags, QC bit, IDC bit and bits for IEEE exception status. */
+#define FPU_STATUS_BITS 0xf800009f
+
+int
+fesetmode (const femode_t *modep)
+{
+ fpu_control_t fpscr, new_fpscr;
+
+ if (!ARM_HAVE_VFP)
+ /* Nothing to do. */
+ return 0;
+
+ _FPU_GETCW (fpscr);
+ if (modep == FE_DFL_MODE)
+ new_fpscr = (fpscr & (_FPU_RESERVED | FPU_STATUS_BITS)) | _FPU_DEFAULT;
+ else
+ new_fpscr = (fpscr & FPU_STATUS_BITS) | (*modep & ~FPU_STATUS_BITS);
+
+ if (((new_fpscr ^ fpscr) & ~_FPU_MASK_NZCV) != 0)
+ _FPU_SETCW (new_fpscr);
+
+ return 0;
+}
diff --git a/libm/arm/fesetround.c b/libm/arm/fesetround.c
new file mode 100644
index 000000000..1cb6b366c
--- /dev/null
+++ b/libm/arm/fesetround.c
@@ -0,0 +1,35 @@
+/* Set current rounding direction.
+ Copyright (C) 2004-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_private.h"
+#include "arm-features.h"
+
+
+int
+fesetround (int round)
+{
+ /* FE_TONEAREST is the only supported rounding mode
+ if a VFP unit isn't present. */
+ if (!ARM_HAVE_VFP)
+ return (round == FE_TONEAREST) ? 0 : 1;
+
+ if (round & ~_FPU_MASK_RM)
+ return 1;
+
+ libc_fesetround_vfp (round);
+ return 0;
+}
diff --git a/libm/arm/feupdateenv.c b/libm/arm/feupdateenv.c
new file mode 100644
index 000000000..a246b865b
--- /dev/null
+++ b/libm/arm/feupdateenv.c
@@ -0,0 +1,73 @@
+/* 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 <fpu_control.h>
+#include "arm-features.h"
+
+
+int
+feupdateenv (const fenv_t *envp)
+{
+ fpu_control_t fpscr, new_fpscr, updated_fpscr;
+ int excepts;
+
+ /* Fail if a VFP unit isn't present. */
+ if (!ARM_HAVE_VFP)
+ return 1;
+
+ _FPU_GETCW (fpscr);
+ excepts = fpscr & FE_ALL_EXCEPT;
+
+ if ((envp != FE_DFL_ENV) && (envp != FE_NOMASK_ENV))
+ {
+ /* Merge current exception flags with the saved fenv. */
+ new_fpscr = envp->__cw | excepts;
+
+ /* Write new FPSCR if different (ignoring NZCV flags). */
+ if (((fpscr ^ new_fpscr) & ~_FPU_MASK_NZCV) != 0)
+ _FPU_SETCW (new_fpscr);
+
+ /* Raise the exceptions if enabled in the new FP state. */
+ if (excepts & (new_fpscr >> FE_EXCEPT_SHIFT))
+ return feraiseexcept (excepts);
+
+ return 0;
+ }
+
+ /* Preserve the reserved FPSCR flags. */
+ new_fpscr = fpscr & (_FPU_RESERVED | FE_ALL_EXCEPT);
+ new_fpscr |= (envp == FE_DFL_ENV) ? _FPU_DEFAULT : _FPU_IEEE;
+
+ if (((new_fpscr ^ fpscr) & ~_FPU_MASK_NZCV) != 0)
+ {
+ _FPU_SETCW (new_fpscr);
+
+ /* Not all VFP architectures support trapping exceptions, so
+ test whether the relevant bits were set and fail if not. */
+ _FPU_GETCW (updated_fpscr);
+
+ if (new_fpscr & ~updated_fpscr)
+ return 1;
+ }
+
+ /* Raise the exceptions if enabled in the new FP state. */
+ if (excepts & (new_fpscr >> FE_EXCEPT_SHIFT))
+ return feraiseexcept (excepts);
+
+ return 0;
+}
diff --git a/libm/arm/fgetexcptflg.c b/libm/arm/fgetexcptflg.c
new file mode 100644
index 000000000..2ef835fd4
--- /dev/null
+++ b/libm/arm/fgetexcptflg.c
@@ -0,0 +1,31 @@
+/* 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_private.h"
+#include "arm-features.h"
+
+
+int
+fegetexceptflag (fexcept_t *flagp, int excepts)
+{
+ /* Fail if a VFP unit isn't present. */
+ if (!ARM_HAVE_VFP)
+ return 1;
+
+ *flagp = libc_fetestexcept_vfp (excepts);
+ return 0;
+}
diff --git a/libm/arm/fraiseexcpt.c b/libm/arm/fraiseexcpt.c
new file mode 100644
index 000000000..91a5d6308
--- /dev/null
+++ b/libm/arm/fraiseexcpt.c
@@ -0,0 +1,103 @@
+/* Raise given exceptions.
+ Copyright (C) 2004-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 <fpu_control.h>
+#include <fenv.h>
+#include <float.h>
+#include "arm-features.h"
+
+
+int
+feraiseexcept (int excepts)
+{
+ /* Fail if a VFP unit isn't present unless nothing needs to be done. */
+ if (!ARM_HAVE_VFP)
+ return (excepts != 0);
+ else
+ {
+ fpu_control_t fpscr;
+ const float fp_zero = 0.0, fp_one = 1.0, fp_max = FLT_MAX,
+ fp_min = FLT_MIN, fp_1e32 = 1.0e32f, fp_two = 2.0,
+ fp_three = 3.0;
+
+ /* Raise exceptions represented by EXPECTS. But we must raise only
+ one signal at a time. It is important that if the overflow/underflow
+ exception and the inexact exception are given at the same time,
+ the overflow/underflow exception follows the inexact exception. After
+ each exception we read from the fpscr, to force the exception to be
+ raised immediately. */
+
+ /* There are additional complications because this file may be compiled
+ without VFP support enabled, and we also can't assume that the
+ assembler has VFP instructions enabled. To get around this we use the
+ generic coprocessor mnemonics and avoid asking GCC to put float values
+ in VFP registers. */
+
+ /* First: invalid exception. */
+ if (FE_INVALID & excepts)
+ __asm__ __volatile__ (
+ "ldc p10, cr0, %1\n\t" /* flds s0, %1 */
+ "cdp p10, 8, cr0, cr0, cr0, 0\n\t" /* fdivs s0, s0, s0 */
+ "mrc p10, 7, %0, cr1, cr0, 0" : "=r" (fpscr) /* fmrx %0, fpscr */
+ : "m" (fp_zero)
+ : "s0");
+
+ /* Next: division by zero. */
+ if (FE_DIVBYZERO & excepts)
+ __asm__ __volatile__ (
+ "ldc p10, cr0, %1\n\t" /* flds s0, %1 */
+ "ldcl p10, cr0, %2\n\t" /* flds s1, %2 */
+ "cdp p10, 8, cr0, cr0, cr0, 1\n\t" /* fdivs s0, s0, s1 */
+ "mrc p10, 7, %0, cr1, cr0, 0" : "=r" (fpscr) /* fmrx %0, fpscr */
+ : "m" (fp_one), "m" (fp_zero)
+ : "s0", "s1");
+
+ /* Next: overflow. */
+ if (FE_OVERFLOW & excepts)
+ /* There's no way to raise overflow without also raising inexact. */
+ __asm__ __volatile__ (
+ "ldc p10, cr0, %1\n\t" /* flds s0, %1 */
+ "ldcl p10, cr0, %2\n\t" /* flds s1, %2 */
+ "cdp p10, 3, cr0, cr0, cr0, 1\n\t" /* fadds s0, s0, s1 */
+ "mrc p10, 7, %0, cr1, cr0, 0" : "=r" (fpscr) /* fmrx %0, fpscr */
+ : "m" (fp_max), "m" (fp_1e32)
+ : "s0", "s1");
+
+ /* Next: underflow. */
+ if (FE_UNDERFLOW & excepts)
+ __asm__ __volatile__ (
+ "ldc p10, cr0, %1\n\t" /* flds s0, %1 */
+ "ldcl p10, cr0, %2\n\t" /* flds s1, %2 */
+ "cdp p10, 8, cr0, cr0, cr0, 1\n\t" /* fdivs s0, s0, s1 */
+ "mrc p10, 7, %0, cr1, cr0, 0" : "=r" (fpscr) /* fmrx %0, fpscr */
+ : "m" (fp_min), "m" (fp_three)
+ : "s0", "s1");
+
+ /* Last: inexact. */
+ if (FE_INEXACT & excepts)
+ __asm__ __volatile__ (
+ "ldc p10, cr0, %1\n\t" /* flds s0, %1 */
+ "ldcl p10, cr0, %2\n\t" /* flds s1, %2 */
+ "cdp p10, 8, cr0, cr0, cr0, 1\n\t" /* fdivs s0, s0, s1 */
+ "mrc p10, 7, %0, cr1, cr0, 0" : "=r" (fpscr) /* fmrx %0, fpscr */
+ : "m" (fp_two), "m" (fp_three)
+ : "s0", "s1");
+
+ /* Success. */
+ return 0;
+ }
+}
diff --git a/libm/arm/fsetexcptflg.c b/libm/arm/fsetexcptflg.c
new file mode 100644
index 000000000..343b33af9
--- /dev/null
+++ b/libm/arm/fsetexcptflg.c
@@ -0,0 +1,44 @@
+/* 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 <fpu_control.h>
+#include "arm-features.h"
+
+
+int
+fesetexceptflag (const fexcept_t *flagp, int excepts)
+{
+ fpu_control_t fpscr, new_fpscr;
+
+ /* Fail if a VFP unit isn't present unless nothing needs to be done. */
+ if (!ARM_HAVE_VFP)
+ return (excepts != 0);
+
+ _FPU_GETCW (fpscr);
+ excepts &= FE_ALL_EXCEPT;
+
+ /* Set the desired exception mask. */
+ new_fpscr = fpscr & ~excepts;
+ new_fpscr |= *flagp & excepts;
+
+ /* Write new exception flags if changed. */
+ if (new_fpscr != fpscr)
+ _FPU_SETCW (new_fpscr);
+
+ return 0;
+}
diff --git a/libm/arm/ftestexcept.c b/libm/arm/ftestexcept.c
new file mode 100644
index 000000000..8b836d97d
--- /dev/null
+++ b/libm/arm/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_private.h"
+#include "arm-features.h"
+
+
+int
+fetestexcept (int excepts)
+{
+ /* Return no exception flags if a VFP unit isn't present. */
+ if (!ARM_HAVE_VFP)
+ return 0;
+
+ return libc_fetestexcept_vfp (excepts);
+}
diff --git a/libm/cexp.c b/libm/cexp.c
index 87512b7c5..a08d12d4e 100644
--- a/libm/cexp.c
+++ b/libm/cexp.c
@@ -38,10 +38,10 @@ libm_hidden_proto(cexpf)
__complex__ float cexpf(__complex__ float z)
{
__complex__ float ret;
- double r_exponent = exp(__real__ z);
+ double r_exponent = exp((double)__real__ z);
- __real__ ret = r_exponent * cosf(__imag__ z);
- __imag__ ret = r_exponent * sinf(__imag__ z);
+ __real__ ret = r_exponent * (double) cosf(__imag__ z);
+ __imag__ ret = r_exponent * (double) sinf(__imag__ z);
return ret;
}
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/e_exp.c b/libm/e_exp.c
index ffa556120..f694f67d1 100644
--- a/libm/e_exp.c
+++ b/libm/e_exp.c
@@ -126,7 +126,7 @@ double __ieee754_exp(double x) /* default IEEE double exp */
if(hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */
hi = x-ln2HI[xsb]; lo=ln2LO[xsb]; k = 1-xsb-xsb;
} else {
- k = invln2*x+halF[xsb];
+ k = (int32_t)(invln2*x+halF[xsb]);
t = k;
hi = x - t*ln2HI[0]; /* t*ln2HI is exact here */
lo = t*ln2LO[0];
diff --git a/libm/float_wrappers.c b/libm/float_wrappers.c
index 948f6bc14..35887dde2 100644
--- a/libm/float_wrappers.c
+++ b/libm/float_wrappers.c
@@ -230,7 +230,7 @@ long_WRAPPER1(lround)
float modff (float x, float *iptr)
{
double y, result;
- result = modf( x, &y );
+ result = modf( (double)x, &y );
*iptr = (float)y;
return (float) result;
}
diff --git a/libm/m68k/Makefile.arch b/libm/m68k/Makefile.arch
new file mode 100644
index 000000000..bd38690be
--- /dev/null
+++ b/libm/m68k/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/m68k/fclrexcpt.c b/libm/m68k/fclrexcpt.c
new file mode 100644
index 000000000..904ba5a19
--- /dev/null
+++ b/libm/m68k/fclrexcpt.c
@@ -0,0 +1,39 @@
+/* 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>
+
+int
+feclearexcept (int excepts)
+{
+ fexcept_t fpsr;
+
+ /* Mask out unsupported bits/exceptions. */
+ excepts &= FE_ALL_EXCEPT;
+
+ /* Fetch the fpu status register. */
+ __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (fpsr));
+
+ /* Clear the relevant bits. */
+ fpsr &= ~excepts;
+
+ /* Put the new data in effect. */
+ __asm__ __volatile__ ("fmove%.l %0,%/fpsr" : : "dm" (fpsr));
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/m68k/fedisblxcpt.c b/libm/m68k/fedisblxcpt.c
new file mode 100644
index 000000000..c2c593e38
--- /dev/null
+++ b/libm/m68k/fedisblxcpt.c
@@ -0,0 +1,36 @@
+/* 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>
+
+int
+fedisableexcept (int excepts)
+{
+ unsigned int old_exc, new_exc;
+
+ /* Get the current control register contents. */
+ __asm__ ("fmove%.l %!,%0" : "=dm" (new_exc));
+
+ old_exc = (new_exc >> 6) & FE_ALL_EXCEPT;
+
+ excepts &= FE_ALL_EXCEPT;
+
+ new_exc &= ~(excepts << 6);
+ __asm__ ("fmove%.l %0,%!" : : "dm" (new_exc));
+
+ return old_exc;
+}
diff --git a/libm/m68k/feenablxcpt.c b/libm/m68k/feenablxcpt.c
new file mode 100644
index 000000000..9c01dc28b
--- /dev/null
+++ b/libm/m68k/feenablxcpt.c
@@ -0,0 +1,36 @@
+/* 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>
+
+int
+feenableexcept (int excepts)
+{
+ unsigned int new_exc, old_exc;
+
+ /* Get the current control register contents. */
+ __asm__ ("fmove%.l %!,%0" : "=dm" (new_exc));
+
+ old_exc = (new_exc >> 6) & FE_ALL_EXCEPT;
+
+ excepts &= FE_ALL_EXCEPT;
+
+ new_exc |= excepts << 6;
+ __asm__ ("fmove%.l %0,%!" : : "dm" (new_exc));
+
+ return old_exc;
+}
diff --git a/libm/m68k/fegetenv.c b/libm/m68k/fegetenv.c
new file mode 100644
index 000000000..2cd0a7c88
--- /dev/null
+++ b/libm/m68k/fegetenv.c
@@ -0,0 +1,33 @@
+/* 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>
+
+int
+fegetenv (fenv_t *envp)
+{
+#ifdef __mcoldfire__
+ __asm__ ("fmove%.l %/fpcr,%0" : "=dm" (envp->__control_register));
+ __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (envp->__status_register));
+ __asm__ ("fmove%.l %/fpiar,%0" : "=dm" (envp->__instruction_address));
+#else
+ __asm__ ("fmovem%.l %/fpcr/%/fpsr/%/fpiar,%0" : "=m" (*envp));
+#endif
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/m68k/fegetexcept.c b/libm/m68k/fegetexcept.c
new file mode 100644
index 000000000..1be3f8bf5
--- /dev/null
+++ b/libm/m68k/fegetexcept.c
@@ -0,0 +1,29 @@
+/* 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>
+
+int
+fegetexcept (void)
+{
+ unsigned int exc;
+
+ /* Get the current control register contents. */
+ __asm__ ("fmove%.l %!,%0" : "=dm" (exc));
+
+ return (exc >> 6) & FE_ALL_EXCEPT;
+}
diff --git a/libm/m68k/fegetmode.c b/libm/m68k/fegetmode.c
new file mode 100644
index 000000000..19f49922a
--- /dev/null
+++ b/libm/m68k/fegetmode.c
@@ -0,0 +1,26 @@
+/* Store current floating-point control modes. M68K 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/m68k/fegetround.c b/libm/m68k/fegetround.c
new file mode 100644
index 000000000..02f6c4c41
--- /dev/null
+++ b/libm/m68k/fegetround.c
@@ -0,0 +1,28 @@
+/* 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>
+
+int
+fegetround (void)
+{
+ int fpcr;
+
+ __asm__ ("fmove%.l %!,%0" : "=dm" (fpcr));
+
+ return fpcr & FE_UPWARD;
+}
diff --git a/libm/m68k/feholdexcpt.c b/libm/m68k/feholdexcpt.c
new file mode 100644
index 000000000..c0891969a
--- /dev/null
+++ b/libm/m68k/feholdexcpt.c
@@ -0,0 +1,42 @@
+/* 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>
+
+int
+feholdexcept (fenv_t *envp)
+{
+ fexcept_t fpcr, fpsr;
+
+ /* Store the environment. */
+#ifdef __mcoldfire__
+ __asm__ ("fmove%.l %/fpcr,%0" : "=dm" (envp->__control_register));
+ __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (envp->__status_register));
+ __asm__ ("fmove%.l %/fpiar,%0" : "=dm" (envp->__instruction_address));
+#else
+ __asm__ ("fmovem%.l %/fpcr/%/fpsr/%/fpiar,%0" : "=m" (*envp));
+#endif
+
+ /* Now clear all exceptions. */
+ fpsr = envp->__status_register & ~FE_ALL_EXCEPT;
+ __asm__ __volatile__ ("fmove%.l %0,%/fpsr" : : "dm" (fpsr));
+ /* And set all exceptions to non-stop. */
+ fpcr = envp->__control_register & ~(FE_ALL_EXCEPT << 6);
+ __asm__ __volatile__ ("fmove%.l %0,%!" : : "dm" (fpcr));
+
+ return 0;
+}
diff --git a/libm/m68k/fesetenv.c b/libm/m68k/fesetenv.c
new file mode 100644
index 000000000..873eb9abe
--- /dev/null
+++ b/libm/m68k/fesetenv.c
@@ -0,0 +1,63 @@
+/* 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>
+
+int
+fesetenv (const fenv_t *envp)
+{
+ fenv_t temp;
+
+ /* Install the environment specified by ENVP. But there are a few
+ values which we do not want to come from the saved environment.
+ Therefore, we get the current environment and replace the values
+ we want to use from the environment specified by the parameter. */
+#ifdef __mcoldfire__
+ __asm__ ("fmove%.l %/fpcr,%0" : "=dm" (temp.__control_register));
+ __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (temp.__status_register));
+ __asm__ ("fmove%.l %/fpiar,%0" : "=dm" (temp.__instruction_address));
+#else
+ __asm__ ("fmovem%.l %/fpcr/%/fpsr/%/fpiar,%0" : "=m" (*&temp));
+#endif
+
+ temp.__status_register &= ~FE_ALL_EXCEPT;
+ temp.__control_register &= ~((FE_ALL_EXCEPT << 6) | FE_UPWARD);
+ if (envp == FE_DFL_ENV)
+ ;
+ else if (envp == FE_NOMASK_ENV)
+ temp.__control_register |= FE_ALL_EXCEPT << 6;
+ else
+ {
+ temp.__control_register |= (envp->__control_register
+ & ((FE_ALL_EXCEPT << 6) | FE_UPWARD));
+ temp.__status_register |= envp->__status_register & FE_ALL_EXCEPT;
+ }
+
+#ifdef __mcoldfire__
+ __asm__ __volatile__ ("fmove%.l %0,%/fpiar"
+ :: "dm" (temp.__instruction_address));
+ __asm__ __volatile__ ("fmove%.l %0,%/fpcr"
+ :: "dm" (temp.__control_register));
+ __asm__ __volatile__ ("fmove%.l %0,%/fpsr"
+ :: "dm" (temp.__status_register));
+#else
+ __asm__ __volatile__ ("fmovem%.l %0,%/fpcr/%/fpsr/%/fpiar" : : "m" (*&temp));
+#endif
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/m68k/fesetexcept.c b/libm/m68k/fesetexcept.c
new file mode 100644
index 000000000..6ae4a55ea
--- /dev/null
+++ b/libm/m68k/fesetexcept.c
@@ -0,0 +1,30 @@
+/* Set given exception flags. M68K 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>
+
+int
+fesetexcept (int excepts)
+{
+ fexcept_t fpsr;
+
+ __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (fpsr));
+ fpsr |= excepts & FE_ALL_EXCEPT;
+ __asm__ __volatile__ ("fmove%.l %0,%/fpsr" : : "dm" (fpsr));
+
+ return 0;
+}
diff --git a/libm/m68k/fesetmode.c b/libm/m68k/fesetmode.c
new file mode 100644
index 000000000..a7e93d616
--- /dev/null
+++ b/libm/m68k/fesetmode.c
@@ -0,0 +1,31 @@
+/* Install given floating-point control modes. M68K 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
+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/m68k/fesetround.c b/libm/m68k/fesetround.c
new file mode 100644
index 000000000..a8abc4e6e
--- /dev/null
+++ b/libm/m68k/fesetround.c
@@ -0,0 +1,35 @@
+/* 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>
+
+int
+fesetround (int round)
+{
+ fexcept_t fpcr;
+
+ if (round & ~FE_UPWARD)
+ /* ROUND is no valid rounding mode. */
+ return 1;
+
+ __asm__ ("fmove%.l %!,%0" : "=dm" (fpcr));
+ fpcr &= ~FE_UPWARD;
+ fpcr |= round;
+ __asm__ __volatile__ ("fmove%.l %0,%!" : : "dm" (fpcr));
+
+ return 0;
+}
diff --git a/libm/m68k/feupdateenv.c b/libm/m68k/feupdateenv.c
new file mode 100644
index 000000000..29dcc712e
--- /dev/null
+++ b/libm/m68k/feupdateenv.c
@@ -0,0 +1,39 @@
+/* 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>
+
+int
+feupdateenv (const fenv_t *envp)
+{
+ fexcept_t fpsr;
+
+ /* Save current exceptions. */
+ __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (fpsr));
+ fpsr &= 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) fpsr);
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/m68k/fgetexcptflg.c b/libm/m68k/fgetexcptflg.c
new file mode 100644
index 000000000..7a564555b
--- /dev/null
+++ b/libm/m68k/fgetexcptflg.c
@@ -0,0 +1,32 @@
+/* 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>
+
+int
+fegetexceptflag (fexcept_t *flagp, int excepts)
+{
+ fexcept_t fpsr;
+
+ /* Get the current exceptions. */
+ __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (fpsr));
+
+ *flagp = fpsr & excepts & FE_ALL_EXCEPT;
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/m68k/fraiseexcpt.c b/libm/m68k/fraiseexcpt.c
new file mode 100644
index 000000000..4599c08f7
--- /dev/null
+++ b/libm/m68k/fraiseexcpt.c
@@ -0,0 +1,106 @@
+/* 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>
+
+int
+feraiseexcept (int excepts)
+{
+#if defined(__mcffpu__)
+
+ /* The Coldfire FPU allows an exception to be raised by asserting
+ the associated EXC bit and then executing an arbitrary arithmetic
+ instruction. fmove.l is classified as an arithmetic instruction
+ and suffices for this purpose.
+
+ We therefore raise an exception by setting both the EXC and AEXC
+ bit associated with the exception (the former being 6 bits to the
+ left of the latter) and then loading the longword at (%sp) into an
+ FP register. */
+
+ inline void
+ raise_one_exception (int mask)
+ {
+ if (excepts & mask)
+ {
+ int fpsr;
+ double unused;
+
+ __asm__ volatile ("fmove%.l %/fpsr,%0" : "=d" (fpsr));
+ fpsr |= (mask << 6) | mask;
+ __asm__ volatile ("fmove%.l %0,%/fpsr" :: "d" (fpsr));
+ __asm__ volatile ("fmove%.l (%%sp),%0" : "=f" (unused));
+ }
+ }
+
+ raise_one_exception (FE_INVALID);
+ raise_one_exception (FE_DIVBYZERO);
+ raise_one_exception (FE_OVERFLOW);
+ raise_one_exception (FE_UNDERFLOW);
+ raise_one_exception (FE_INEXACT);
+
+#else
+ /* 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. */
+
+ /* First: invalid exception. */
+ if (excepts & FE_INVALID)
+ {
+ /* One example of an invalid operation is 0 * Infinity. */
+ double d = HUGE_VAL;
+ __asm__ __volatile__ ("fmul%.s %#0r0,%0; fnop" : "=f" (d) : "0" (d));
+ }
+
+ /* Next: division by zero. */
+ if (excepts & FE_DIVBYZERO)
+ {
+ double d = 1.0;
+ __asm__ __volatile__ ("fdiv%.s %#0r0,%0; fnop" : "=f" (d) : "0" (d));
+ }
+
+ /* Next: overflow. */
+ if (excepts & FE_OVERFLOW)
+ {
+ long double d = LDBL_MAX;
+
+ __asm__ __volatile__ ("fmul%.x %0,%0; fnop" : "=f" (d) : "0" (d));
+ }
+
+ /* Next: underflow. */
+ if (excepts & FE_UNDERFLOW)
+ {
+ long double d = -LDBL_MAX;
+
+ __asm__ __volatile__ ("fetox%.x %0; fnop" : "=f" (d) : "0" (d));
+ }
+
+ /* Last: inexact. */
+ if (excepts & FE_INEXACT)
+ {
+ long double d = 1.0;
+ __asm__ __volatile__ ("fdiv%.s %#0r3,%0; fnop" : "=f" (d) : "0" (d));
+ }
+
+#endif
+ /* Success. */
+ return 0;
+}
diff --git a/libm/m68k/fsetexcptflg.c b/libm/m68k/fsetexcptflg.c
new file mode 100644
index 000000000..18fc1811f
--- /dev/null
+++ b/libm/m68k/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>
+
+int
+fesetexceptflag (const fexcept_t *flagp, int excepts)
+{
+ fexcept_t fpsr;
+
+ /* Get the current status register. */
+ __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (fpsr));
+
+ /* Install the new exception bits in the Accrued Exception Byte. */
+ fpsr &= ~(excepts & FE_ALL_EXCEPT);
+ fpsr |= *flagp & excepts & FE_ALL_EXCEPT;
+
+ /* Store the new status register. */
+ __asm__ __volatile__ ("fmove%.l %0,%/fpsr" : : "dm" (fpsr));
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/m68k/ftestexcept.c b/libm/m68k/ftestexcept.c
new file mode 100644
index 000000000..1ece1a48d
--- /dev/null
+++ b/libm/m68k/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>
+
+int
+fetestexcept (int excepts)
+{
+ fexcept_t fpsr;
+
+ /* Get current exceptions. */
+ __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (fpsr));
+
+ return fpsr & excepts & FE_ALL_EXCEPT;
+}
diff --git a/libm/mips/Makefile.arch b/libm/mips/Makefile.arch
new file mode 100644
index 000000000..bd38690be
--- /dev/null
+++ b/libm/mips/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/mips/fclrexcpt.c b/libm/mips/fclrexcpt.c
new file mode 100644
index 000000000..04d48d712
--- /dev/null
+++ b/libm/mips/fclrexcpt.c
@@ -0,0 +1,44 @@
+/* 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 "fenv_libc.h"
+#include <fpu_control.h>
+
+int
+feclearexcept (int excepts)
+{
+ int cw;
+
+ /* Mask out unsupported bits/exceptions. */
+ excepts &= FE_ALL_EXCEPT;
+
+ /* Read the complete control word. */
+ _FPU_GETCW (cw);
+
+ /* Clear exception flag bits and cause bits. If the cause bit is not
+ cleared, the next CTC instruction (just below) will re-generate the
+ exception. */
+
+ cw &= ~(excepts | (excepts << CAUSE_SHIFT));
+
+ /* Put the new data in effect. */
+ _FPU_SETCW (cw);
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/mips/fedisblxcpt.c b/libm/mips/fedisblxcpt.c
new file mode 100644
index 000000000..85cd6c518
--- /dev/null
+++ b/libm/mips/fedisblxcpt.c
@@ -0,0 +1,38 @@
+/* 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_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;
+
+ excepts &= FE_ALL_EXCEPT;
+
+ new_exc &= ~(excepts << ENABLE_SHIFT);
+ _FPU_SETCW (new_exc);
+
+ return old_exc;
+}
diff --git a/libm/mips/feenablxcpt.c b/libm/mips/feenablxcpt.c
new file mode 100644
index 000000000..9d919a8ba
--- /dev/null
+++ b/libm/mips/feenablxcpt.c
@@ -0,0 +1,38 @@
+/* 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_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/mips/fegetenv.c b/libm/mips/fegetenv.c
new file mode 100644
index 000000000..94f3444ac
--- /dev/null
+++ b/libm/mips/fegetenv.c
@@ -0,0 +1,28 @@
+/* Store 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
+fegetenv (fenv_t *envp)
+{
+ _FPU_GETCW (*envp);
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/mips/fegetexcept.c b/libm/mips/fegetexcept.c
new file mode 100644
index 000000000..4c7c89fa6
--- /dev/null
+++ b/libm/mips/fegetexcept.c
@@ -0,0 +1,31 @@
+/* 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_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/mips/fegetmode.c b/libm/mips/fegetmode.c
new file mode 100644
index 000000000..136b8d3fb
--- /dev/null
+++ b/libm/mips/fegetmode.c
@@ -0,0 +1,26 @@
+/* Store current floating-point control modes. MIPS 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/mips/fegetround.c b/libm/mips/fegetround.c
new file mode 100644
index 000000000..4d8f3744d
--- /dev/null
+++ b/libm/mips/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)
+{
+ int cw;
+
+ /* Get control word. */
+ _FPU_GETCW (cw);
+
+ return cw & _FPU_RC_MASK;
+}
diff --git a/libm/mips/feholdexcpt.c b/libm/mips/feholdexcpt.c
new file mode 100644
index 000000000..b1e35ae5a
--- /dev/null
+++ b/libm/mips/feholdexcpt.c
@@ -0,0 +1,35 @@
+/* Store current floating-point environment and clear 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 <fpu_control.h>
+
+int
+feholdexcept (fenv_t *envp)
+{
+ fpu_control_t cw;
+
+ /* Save the current state. */
+ _FPU_GETCW (cw);
+ envp->__fp_control_register = cw;
+
+ /* Clear all exception enable bits and flags. */
+ cw &= ~(_FPU_MASK_V|_FPU_MASK_Z|_FPU_MASK_O|_FPU_MASK_U|_FPU_MASK_I|FE_ALL_EXCEPT);
+ _FPU_SETCW (cw);
+
+ return 0;
+}
diff --git a/libm/mips/fenv_libc.h b/libm/mips/fenv_libc.h
new file mode 100644
index 000000000..642a7b127
--- /dev/null
+++ b/libm/mips/fenv_libc.h
@@ -0,0 +1,29 @@
+/* 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/>. */
+
+#ifndef _FENV_LIBC_H
+#define _FENV_LIBC_H 1
+
+/* Mask for enabling exceptions and for the CAUSE bits. */
+#define ENABLE_MASK 0x00F80U
+#define CAUSE_MASK 0x1F000U
+
+/* Shift for FE_* flags to get up to the ENABLE bits and the CAUSE bits. */
+#define ENABLE_SHIFT 5
+#define CAUSE_SHIFT 10
+
+
+#endif /* _FENV_LIBC_H */
diff --git a/libm/mips/fenv_private.h b/libm/mips/fenv_private.h
new file mode 100644
index 000000000..bc9be3b62
--- /dev/null
+++ b/libm/mips/fenv_private.h
@@ -0,0 +1,238 @@
+/* Internal math stuff. MIPS version.
+ 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/>. */
+
+#ifndef MIPS_FENV_PRIVATE_H
+#define MIPS_FENV_PRIVATE_H 1
+
+/* Inline functions to speed up the math library implementation. The
+ default versions of these routines are in generic/fenv_private.h
+ and call fesetround, feholdexcept, etc. These routines use inlined
+ code instead. */
+
+#include <fenv.h>
+#include "fenv_libc.h"
+#include <fpu_control.h>
+
+#define _FPU_MASK_ALL (_FPU_MASK_V | _FPU_MASK_Z | _FPU_MASK_O \
+ |_FPU_MASK_U | _FPU_MASK_I | FE_ALL_EXCEPT)
+
+static __always_inline void
+libc_feholdexcept_mips (fenv_t *envp)
+{
+ fpu_control_t cw;
+
+ /* Save the current state. */
+ _FPU_GETCW (cw);
+ envp->__fp_control_register = cw;
+
+ /* Clear all exception enable bits and flags. */
+ cw &= ~(_FPU_MASK_ALL);
+ _FPU_SETCW (cw);
+}
+#define libc_feholdexcept libc_feholdexcept_mips
+#define libc_feholdexceptf libc_feholdexcept_mips
+#define libc_feholdexceptl libc_feholdexcept_mips
+
+static __always_inline void
+libc_fesetround_mips (int round)
+{
+ fpu_control_t cw;
+
+ /* Get current state. */
+ _FPU_GETCW (cw);
+
+ /* Set rounding bits. */
+ cw &= ~_FPU_RC_MASK;
+ cw |= round;
+
+ /* Set new state. */
+ _FPU_SETCW (cw);
+}
+#define libc_fesetround libc_fesetround_mips
+#define libc_fesetroundf libc_fesetround_mips
+#define libc_fesetroundl libc_fesetround_mips
+
+static __always_inline void
+libc_feholdexcept_setround_mips (fenv_t *envp, int round)
+{
+ fpu_control_t cw;
+
+ /* Save the current state. */
+ _FPU_GETCW (cw);
+ envp->__fp_control_register = cw;
+
+ /* Clear all exception enable bits and flags. */
+ cw &= ~(_FPU_MASK_ALL);
+
+ /* Set rounding bits. */
+ cw &= ~_FPU_RC_MASK;
+ cw |= round;
+
+ /* Set new state. */
+ _FPU_SETCW (cw);
+}
+#define libc_feholdexcept_setround libc_feholdexcept_setround_mips
+#define libc_feholdexcept_setroundf libc_feholdexcept_setround_mips
+#define libc_feholdexcept_setroundl libc_feholdexcept_setround_mips
+
+#define libc_feholdsetround libc_feholdexcept_setround_mips
+#define libc_feholdsetroundf libc_feholdexcept_setround_mips
+#define libc_feholdsetroundl libc_feholdexcept_setround_mips
+
+static __always_inline void
+libc_fesetenv_mips (fenv_t *envp)
+{
+ fpu_control_t cw __attribute__ ((unused));
+
+ /* Read current state to flush fpu pipeline. */
+ _FPU_GETCW (cw);
+
+ _FPU_SETCW (envp->__fp_control_register);
+}
+#define libc_fesetenv libc_fesetenv_mips
+#define libc_fesetenvf libc_fesetenv_mips
+#define libc_fesetenvl libc_fesetenv_mips
+
+static __always_inline int
+libc_feupdateenv_test_mips (fenv_t *envp, int excepts)
+{
+ /* int ret = fetestexcept (excepts); feupdateenv (envp); return ret; */
+ int cw, temp;
+
+ /* Get current control word. */
+ _FPU_GETCW (cw);
+
+ /* Set flag bits (which are accumulative), and *also* set the
+ cause bits. The setting of the cause bits is what actually causes
+ the hardware to generate the exception, if the corresponding enable
+ bit is set as well. */
+ temp = cw & FE_ALL_EXCEPT;
+ temp |= envp->__fp_control_register | (temp << CAUSE_SHIFT);
+
+ /* Set new state. */
+ _FPU_SETCW (temp);
+
+ return cw & excepts & FE_ALL_EXCEPT;
+}
+#define libc_feupdateenv_test libc_feupdateenv_test_mips
+#define libc_feupdateenv_testf libc_feupdateenv_test_mips
+#define libc_feupdateenv_testl libc_feupdateenv_test_mips
+
+static __always_inline void
+libc_feupdateenv_mips (fenv_t *envp)
+{
+ libc_feupdateenv_test_mips (envp, 0);
+}
+#define libc_feupdateenv libc_feupdateenv_mips
+#define libc_feupdateenvf libc_feupdateenv_mips
+#define libc_feupdateenvl libc_feupdateenv_mips
+
+#define libc_feresetround libc_feupdateenv_mips
+#define libc_feresetroundf libc_feupdateenv_mips
+#define libc_feresetroundl libc_feupdateenv_mips
+
+static __always_inline int
+libc_fetestexcept_mips (int excepts)
+{
+ int cw;
+
+ /* Get current control word. */
+ _FPU_GETCW (cw);
+
+ return cw & excepts & FE_ALL_EXCEPT;
+}
+#define libc_fetestexcept libc_fetestexcept_mips
+#define libc_fetestexceptf libc_fetestexcept_mips
+#define libc_fetestexceptl libc_fetestexcept_mips
+
+/* Enable support for rounding mode context. */
+#define HAVE_RM_CTX 1
+
+static __always_inline void
+libc_feholdexcept_setround_mips_ctx (struct rm_ctx *ctx, int round)
+{
+ fpu_control_t old, new;
+
+ /* Save the current state. */
+ _FPU_GETCW (old);
+ ctx->env.__fp_control_register = old;
+
+ /* Clear all exception enable bits and flags. */
+ new = old & ~(_FPU_MASK_ALL);
+
+ /* Set rounding bits. */
+ new = (new & ~_FPU_RC_MASK) | round;
+
+ if (__glibc_unlikely (new != old))
+ {
+ _FPU_SETCW (new);
+ ctx->updated_status = true;
+ }
+ else
+ ctx->updated_status = false;
+}
+#define libc_feholdexcept_setround_ctx libc_feholdexcept_setround_mips_ctx
+#define libc_feholdexcept_setroundf_ctx libc_feholdexcept_setround_mips_ctx
+#define libc_feholdexcept_setroundl_ctx libc_feholdexcept_setround_mips_ctx
+
+static __always_inline void
+libc_fesetenv_mips_ctx (struct rm_ctx *ctx)
+{
+ libc_fesetenv_mips (&ctx->env);
+}
+#define libc_fesetenv_ctx libc_fesetenv_mips_ctx
+#define libc_fesetenvf_ctx libc_fesetenv_mips_ctx
+#define libc_fesetenvl_ctx libc_fesetenv_mips_ctx
+
+static __always_inline void
+libc_feupdateenv_mips_ctx (struct rm_ctx *ctx)
+{
+ if (__glibc_unlikely (ctx->updated_status))
+ libc_feupdateenv_test_mips (&ctx->env, 0);
+}
+#define libc_feupdateenv_ctx libc_feupdateenv_mips_ctx
+#define libc_feupdateenvf_ctx libc_feupdateenv_mips_ctx
+#define libc_feupdateenvl_ctx libc_feupdateenv_mips_ctx
+#define libc_feresetround_ctx libc_feupdateenv_mips_ctx
+#define libc_feresetroundf_ctx libc_feupdateenv_mips_ctx
+#define libc_feresetroundl_ctx libc_feupdateenv_mips_ctx
+
+static __always_inline void
+libc_feholdsetround_mips_ctx (struct rm_ctx *ctx, int round)
+{
+ fpu_control_t old, new;
+
+ /* Save the current state. */
+ _FPU_GETCW (old);
+ ctx->env.__fp_control_register = old;
+
+ /* Set rounding bits. */
+ new = (old & ~_FPU_RC_MASK) | round;
+
+ if (__glibc_unlikely (new != old))
+ {
+ _FPU_SETCW (new);
+ ctx->updated_status = true;
+ }
+ else
+ ctx->updated_status = false;
+}
+#define libc_feholdsetround_ctx libc_feholdsetround_mips_ctx
+#define libc_feholdsetroundf_ctx libc_feholdsetround_mips_ctx
+#define libc_feholdsetroundl_ctx libc_feholdsetround_mips_ctx
+
+#endif
diff --git a/libm/mips/fesetenv.c b/libm/mips/fesetenv.c
new file mode 100644
index 000000000..03b5b91a6
--- /dev/null
+++ b/libm/mips/fesetenv.c
@@ -0,0 +1,38 @@
+/* Install given 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
+fesetenv (const fenv_t *envp)
+{
+ fpu_control_t cw;
+
+ /* Read first current state to flush fpu pipeline. */
+ _FPU_GETCW (cw);
+
+ if (envp == FE_DFL_ENV)
+ _FPU_SETCW (_FPU_DEFAULT);
+ else if (envp == FE_NOMASK_ENV)
+ _FPU_SETCW (_FPU_IEEE);
+ else
+ _FPU_SETCW (envp->__fp_control_register);
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/mips/fesetexcept.c b/libm/mips/fesetexcept.c
new file mode 100644
index 000000000..1c9a0de3b
--- /dev/null
+++ b/libm/mips/fesetexcept.c
@@ -0,0 +1,31 @@
+/* Set given exception flags. MIPS 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/mips/fesetmode.c b/libm/mips/fesetmode.c
new file mode 100644
index 000000000..cb4ffdc06
--- /dev/null
+++ b/libm/mips/fesetmode.c
@@ -0,0 +1,37 @@
+/* Install given floating-point control modes. MIPS 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 FCSR_STATUS 0xfe83f07c
+
+int
+fesetmode (const femode_t *modep)
+{
+ fpu_control_t cw;
+
+ _FPU_GETCW (cw);
+ cw &= FCSR_STATUS;
+ if (modep == FE_DFL_MODE)
+ cw |= _FPU_DEFAULT;
+ else
+ cw |= *modep & ~FCSR_STATUS;
+ _FPU_SETCW (cw);
+
+ return 0;
+}
diff --git a/libm/mips/fesetround.c b/libm/mips/fesetround.c
new file mode 100644
index 000000000..532092710
--- /dev/null
+++ b/libm/mips/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 & ~_FPU_RC_MASK) != 0)
+ /* ROUND is no valid rounding mode. */
+ return 1;
+
+ /* Get current state. */
+ _FPU_GETCW (cw);
+
+ /* Set rounding bits. */
+ cw &= ~_FPU_RC_MASK;
+ cw |= round;
+ /* Set new state. */
+ _FPU_SETCW (cw);
+
+ return 0;
+}
diff --git a/libm/mips/feupdateenv.c b/libm/mips/feupdateenv.c
new file mode 100644
index 000000000..d90604db3
--- /dev/null
+++ b/libm/mips/feupdateenv.c
@@ -0,0 +1,40 @@
+/* Install given floating-point environment and raise exceptions.
+ 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
+feupdateenv (const fenv_t *envp)
+{
+ int temp;
+
+ /* Save current exceptions. */
+ _FPU_GETCW (temp);
+ temp &= 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/mips/fgetexcptflg.c b/libm/mips/fgetexcptflg.c
new file mode 100644
index 000000000..b03eca55e
--- /dev/null
+++ b/libm/mips/fgetexcptflg.c
@@ -0,0 +1,37 @@
+/* Store current representation for exceptions.
+ 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
+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/mips/fraiseexcpt.c b/libm/mips/fraiseexcpt.c
new file mode 100644
index 000000000..6327b1104
--- /dev/null
+++ b/libm/mips/fraiseexcpt.c
@@ -0,0 +1,42 @@
+/* Raise given 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_libc.h"
+#include <fpu_control.h>
+
+int
+feraiseexcept (int excepts)
+{
+ fpu_control_t cw;
+
+ /* Get current state. */
+ _FPU_GETCW (cw);
+
+ /* Set flag bits (which are accumulative), and *also* set the
+ cause bits. The setting of the cause bits is what actually causes
+ the hardware to generate the exception, if the corresponding enable
+ bit is set as well. */
+
+ excepts &= FE_ALL_EXCEPT;
+ cw |= excepts | (excepts << CAUSE_SHIFT);
+
+ /* Set new state. */
+ _FPU_SETCW (cw);
+
+ return 0;
+}
diff --git a/libm/mips/fsetexcptflg.c b/libm/mips/fsetexcptflg.c
new file mode 100644
index 000000000..d98a300e2
--- /dev/null
+++ b/libm/mips/fsetexcptflg.c
@@ -0,0 +1,40 @@
+/* Set floating-point environment exception handling.
+ 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
+fesetexceptflag (const fexcept_t *flagp, int excepts)
+{
+ fpu_control_t temp;
+
+ /* Get the current exceptions. */
+ _FPU_GETCW (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 & ~excepts) | (*flagp & excepts);
+
+ _FPU_SETCW (temp);
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/mips/ftestexcept.c b/libm/mips/ftestexcept.c
new file mode 100644
index 000000000..8fdca7560
--- /dev/null
+++ b/libm/mips/ftestexcept.c
@@ -0,0 +1,30 @@
+/* Test exception in current 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
+fetestexcept (int excepts)
+{
+ int cw;
+
+ /* Get current control word. */
+ _FPU_GETCW (cw);
+
+ return cw & excepts & FE_ALL_EXCEPT;
+}
diff --git a/libm/nan.c b/libm/nan.c
index 454734b6f..9c2cd6e90 100644
--- a/libm/nan.c
+++ b/libm/nan.c
@@ -28,7 +28,7 @@ double nan (const char *tagp)
sprintf (buf, "NAN(%s)", tagp);
return strtod (buf, NULL);
}
- return NAN;
+ return (double)NAN;
}
libm_hidden_def(nan)
@@ -53,7 +53,7 @@ long double nanl (const char *tagp)
sprintf (buf, "NAN(%s)", tagp);
return strtold (buf, NULL);
}
- return NAN;
+ return (long double)NAN;
}
libm_hidden_def(nanl)
#endif
diff --git a/libm/or1k/Makefile.arch b/libm/or1k/Makefile.arch
new file mode 100644
index 000000000..bd38690be
--- /dev/null
+++ b/libm/or1k/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/or1k/fclrexcpt.c b/libm/or1k/fclrexcpt.c
new file mode 100644
index 000000000..ecb327d72
--- /dev/null
+++ b/libm/or1k/fclrexcpt.c
@@ -0,0 +1,42 @@
+/* Clear given exceptions in current floating-point environment.
+ OpenRISC version.
+ Copyright (C) 2024-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;
+ fpu_control_t cw_new;
+
+ /* Mask out unsupported bits/exceptions. */
+ excepts &= FE_ALL_EXCEPT;
+
+ /* Read the complete control word. */
+ _FPU_GETCW (cw);
+
+ cw_new = cw & ~excepts;
+
+ /* Put the new data in effect. */
+ if (cw != cw_new)
+ _FPU_SETCW (cw_new);
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/or1k/fegetenv.c b/libm/or1k/fegetenv.c
new file mode 100644
index 000000000..7769d456f
--- /dev/null
+++ b/libm/or1k/fegetenv.c
@@ -0,0 +1,28 @@
+/* Store current floating-point environment.
+ Copyright (C) 2024-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_GETCW (*envp);
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/or1k/fegetmode.c b/libm/or1k/fegetmode.c
new file mode 100644
index 000000000..40a789329
--- /dev/null
+++ b/libm/or1k/fegetmode.c
@@ -0,0 +1,28 @@
+/* Store current floating-point control modes. OpenRISC version.
+ Copyright (C) 2024-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);
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/or1k/fegetround.c b/libm/or1k/fegetround.c
new file mode 100644
index 000000000..0965de2f9
--- /dev/null
+++ b/libm/or1k/fegetround.c
@@ -0,0 +1,25 @@
+/* Return current rounding direction. OpenRISC version.
+ Copyright (C) 2024-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 "get-rounding-mode.h"
+
+int
+fegetround (void)
+{
+ return get_rounding_mode ();
+}
diff --git a/libm/or1k/feholdexcpt.c b/libm/or1k/feholdexcpt.c
new file mode 100644
index 000000000..cff06f3d0
--- /dev/null
+++ b/libm/or1k/feholdexcpt.c
@@ -0,0 +1,29 @@
+/* Store current floating-point environment and clear exceptions.
+ OpenRISC version.
+ Copyright (C) 2024-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)
+{
+ libc_feholdexcept_or1k (envp);
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/or1k/fenv_private.h b/libm/or1k/fenv_private.h
new file mode 100644
index 000000000..ede7d243a
--- /dev/null
+++ b/libm/or1k/fenv_private.h
@@ -0,0 +1,196 @@
+/* Private floating point rounding and exceptions handling. OpenRISC version.
+ Copyright (C) 2024-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 OR1K_FENV_PRIVATE_H
+#define OR1K_FENV_PRIVATE_H 1
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+static __always_inline void
+libc_feholdexcept_or1k (fenv_t *envp)
+{
+ fpu_control_t cw;
+ fpu_control_t cw_new;
+
+ /* Get and store the environment. */
+ _FPU_GETCW (cw);
+ *envp = cw;
+
+ /* Clear the exception status flags. */
+ cw_new = cw & ~FE_ALL_EXCEPT;
+
+ if (cw != cw_new)
+ _FPU_SETCW (cw_new);
+}
+
+#define libc_feholdexcept libc_feholdexcept_or1k
+#define libc_feholdexceptf libc_feholdexcept_or1k
+#define libc_feholdexceptl libc_feholdexcept_or1k
+
+static __always_inline void
+libc_fesetround_or1k (int round)
+{
+ fpu_control_t cw;
+ fpu_control_t cw_new;
+
+ _FPU_GETCW (cw);
+ cw_new = cw & ~_FPU_FPCSR_RM_MASK;
+ cw_new |= round;
+ if (cw != cw_new)
+ _FPU_SETCW (cw_new);
+}
+
+#define libc_fesetround libc_fesetround_or1k
+#define libc_fesetroundf libc_fesetround_or1k
+#define libc_fesetroundl libc_fesetround_or1k
+
+static __always_inline void
+libc_feholdexcept_setround_or1k (fenv_t *envp, int round)
+{
+ fpu_control_t cw;
+ fpu_control_t cw_new;
+
+ /* Get and store the environment. */
+ _FPU_GETCW (cw);
+ *envp = cw;
+
+ /* Clear the status flags and rounding mode. */
+ cw_new = cw & ~(FE_ALL_EXCEPT | _FPU_FPCSR_RM_MASK);
+
+ /* Set rounding mode. */
+ cw_new |= round;
+
+ if (cw != cw_new)
+ _FPU_SETCW (cw_new);
+}
+
+#define libc_feholdexcept_setround libc_feholdexcept_setround_or1k
+#define libc_feholdexcept_setroundf libc_feholdexcept_setround_or1k
+#define libc_feholdexcept_setroundl libc_feholdexcept_setround_or1k
+
+static __always_inline int
+libc_fetestexcept_or1k (int ex)
+{
+ fpu_control_t cw;
+
+ /* Get current control word. */
+ _FPU_GETCW (cw);
+
+ /* Check if any of the queried exception flags are set. */
+ return cw & ex & FE_ALL_EXCEPT;
+}
+
+#define libc_fetestexcept libc_fetestexcept_or1k
+#define libc_fetestexceptf libc_fetestexcept_or1k
+#define libc_fetestexceptl libc_fetestexcept_or1k
+
+static __always_inline void
+libc_fesetenv_or1k (const fenv_t *envp)
+{
+ if (envp == FE_DFL_ENV)
+ _FPU_SETCW (_FPU_DEFAULT);
+ else
+ _FPU_SETCW (*envp);
+}
+
+#define libc_fesetenv libc_fesetenv_or1k
+#define libc_fesetenvf libc_fesetenv_or1k
+#define libc_fesetenvl libc_fesetenv_or1k
+#define libc_feresetround_noex libc_fesetenv_or1k
+#define libc_feresetround_noexf libc_fesetenv_or1k
+#define libc_feresetround_noexl libc_fesetenv_or1k
+
+static __always_inline int
+libc_feupdateenv_test_or1k (const fenv_t *envp, int ex)
+{
+ fpu_control_t cw;
+ fpu_control_t cw_new;
+ int excepts;
+
+ /* Get current control word. */
+ _FPU_GETCW (cw);
+
+ /* Merge current exception flags with the passed fenv. */
+ excepts = cw & FE_ALL_EXCEPT;
+ cw_new = (envp == FE_DFL_ENV ? _FPU_DEFAULT : *envp) | excepts;
+
+ if (unlikely (cw != cw_new))
+ _FPU_SETCW (cw_new);
+
+ /* Raise the exceptions if enabled in the new FP state. */
+ if (unlikely (excepts))
+ feraiseexcept (excepts);
+
+ return excepts & ex;
+}
+
+#define libc_feupdateenv_test libc_feupdateenv_test_or1k
+#define libc_feupdateenv_testf libc_feupdateenv_test_or1k
+#define libc_feupdateenv_testl libc_feupdateenv_test_or1k
+
+static __always_inline void
+libc_feupdateenv_or1k (const fenv_t *envp)
+{
+ libc_feupdateenv_test_or1k (envp, 0);
+}
+
+#define libc_feupdateenv libc_feupdateenv_or1k
+#define libc_feupdateenvf libc_feupdateenv_or1k
+#define libc_feupdateenvl libc_feupdateenv_or1k
+
+static __always_inline void
+libc_feholdsetround_or1k (fenv_t *envp, int round)
+{
+ fpu_control_t cw;
+
+ _FPU_GETCW (cw);
+ *envp = cw;
+
+ /* Check whether rounding modes are different. */
+ round = (cw ^ round) & _FPU_FPCSR_RM_MASK;
+
+ /* Set new rounding mode if different. */
+ if (unlikely (round != 0))
+ _FPU_SETCW (cw ^ round);
+}
+
+#define libc_feholdsetround libc_feholdsetround_or1k
+#define libc_feholdsetroundf libc_feholdsetround_or1k
+#define libc_feholdsetroundl libc_feholdsetround_or1k
+
+static __always_inline void
+libc_feresetround_or1k (fenv_t *envp)
+{
+ fpu_control_t cw;
+ int round;
+
+ _FPU_GETCW (cw);
+
+ /* Check whether rounding modes are different. */
+ round = (*envp ^ cw) & _FPU_FPCSR_RM_MASK;
+
+ /* Restore the rounding mode if it was changed. */
+ if (unlikely (round != 0))
+ _FPU_SETCW (cw ^ round);
+}
+
+#define libc_feresetround libc_feresetround_or1k
+#define libc_feresetroundf libc_feresetround_or1k
+#define libc_feresetroundl libc_feresetround_or1k
+
+#endif
diff --git a/libm/or1k/fesetenv.c b/libm/or1k/fesetenv.c
new file mode 100644
index 000000000..a9c8448f4
--- /dev/null
+++ b/libm/or1k/fesetenv.c
@@ -0,0 +1,28 @@
+/* Install given floating-point environment. OpenRISC version.
+ Copyright (C) 2024-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)
+{
+ libc_fesetenv_or1k (envp);
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/or1k/fesetexcept.c b/libm/or1k/fesetexcept.c
new file mode 100644
index 000000000..abc5624c3
--- /dev/null
+++ b/libm/or1k/fesetexcept.c
@@ -0,0 +1,34 @@
+/* Set given exception flags. OpenRISC version.
+ Copyright (C) 2024-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 cw;
+ fpu_control_t cw_new;
+
+ _FPU_GETCW (cw);
+ cw_new = cw | (excepts & FE_ALL_EXCEPT);
+ if (cw != cw_new)
+ _FPU_SETCW (cw_new);
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/or1k/fesetmode.c b/libm/or1k/fesetmode.c
new file mode 100644
index 000000000..74490621b
--- /dev/null
+++ b/libm/or1k/fesetmode.c
@@ -0,0 +1,38 @@
+/* Install given floating-point control modes. OpenRISC version.
+ Copyright (C) 2024-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)
+{
+ fpu_control_t cw;
+ fpu_control_t cw_new;
+
+ _FPU_GETCW (cw);
+ cw_new = cw & ~_FPU_FPCSR_RM_MASK;
+ if (modep == FE_DFL_MODE)
+ cw_new |= (_FPU_DEFAULT & _FPU_FPCSR_RM_MASK);
+ else
+ cw_new |= (*modep & _FPU_FPCSR_RM_MASK);
+ if (cw != cw_new)
+ _FPU_SETCW (cw_new);
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/or1k/fesetround.c b/libm/or1k/fesetround.c
new file mode 100644
index 000000000..37c2db4ab
--- /dev/null
+++ b/libm/or1k/fesetround.c
@@ -0,0 +1,35 @@
+/* Set current rounding direction. OpenRISC version.
+ Copyright (C) 2024-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)
+{
+ switch (round)
+ {
+ case FE_TONEAREST:
+ case FE_TOWARDZERO:
+ case FE_DOWNWARD:
+ case FE_UPWARD:
+ libc_fesetround_or1k (round);
+ return 0;
+ default:
+ return round; /* A nonzero value. */
+ }
+}
diff --git a/libm/or1k/feupdateenv.c b/libm/or1k/feupdateenv.c
new file mode 100644
index 000000000..b0f42744f
--- /dev/null
+++ b/libm/or1k/feupdateenv.c
@@ -0,0 +1,29 @@
+/* Install given floating-point environment and raise exceptions.
+ OpenRISC version.
+ Copyright (C) 2024-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)
+{
+ libc_feupdateenv_or1k (envp);
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/or1k/fgetexcptflg.c b/libm/or1k/fgetexcptflg.c
new file mode 100644
index 000000000..2a725a4c7
--- /dev/null
+++ b/libm/or1k/fgetexcptflg.c
@@ -0,0 +1,28 @@
+/* Store current state of exceptions. OpenRISC version.
+ Copyright (C) 2024-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)
+{
+ *flagp = libc_fetestexcept_or1k (excepts);
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/or1k/fraiseexcpt.c b/libm/or1k/fraiseexcpt.c
new file mode 100644
index 000000000..31ceb830d
--- /dev/null
+++ b/libm/or1k/fraiseexcpt.c
@@ -0,0 +1,63 @@
+/* Raise given exceptions. OpenRISC version.
+ Copyright (C) 2024-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)
+{
+ if (excepts == 0)
+ return 0;
+
+ /* Raise exceptions represented by EXPECTS. */
+
+ if (excepts & FE_INEXACT)
+ {
+ float d = 1.0, x = 3.0;
+ __asm__ volatile ("lf.div.s %0, %0, %1" : "+r" (d) : "r" (x));
+ }
+
+ if (excepts & FE_UNDERFLOW)
+ {
+ float d = FLT_MIN;
+ __asm__ volatile ("lf.mul.s %0, %0, %0" : "+r" (d));
+ }
+
+ if (excepts & FE_OVERFLOW)
+ {
+ float d = FLT_MAX;
+ __asm__ volatile ("lf.mul.s %0, %0, %0" : "+r" (d) : "r" (d));
+ }
+
+ if (excepts & FE_DIVBYZERO)
+ {
+ float d = 1.0, x = 0.0;
+ __asm__ volatile ("lf.div.s %0, %0, %1" : "+r" (d) : "r" (x));
+ }
+
+ if (excepts & FE_INVALID)
+ {
+ float d = HUGE_VAL, x = 0.0;
+ __asm__ volatile ("lf.mul.s %0, %1, %0" : "+r" (d) : "r" (x));
+ }
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/or1k/fsetexcptflg.c b/libm/or1k/fsetexcptflg.c
new file mode 100644
index 000000000..01c6e8635
--- /dev/null
+++ b/libm/or1k/fsetexcptflg.c
@@ -0,0 +1,42 @@
+/* Set floating-point environment exception handling.
+ Copyright (C) 2024-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)
+{
+ fpu_control_t cw;
+ fpu_control_t cw_new;
+
+ /* Get the current exceptions. */
+ _FPU_GETCW (cw);
+
+ /* Make sure the flags we want restored are legal. */
+ excepts &= FE_ALL_EXCEPT;
+
+ /* Now set selected bits from flagp. Note that we ignore all non-flag
+ bits from *flagp, so they don't matter. */
+ cw_new = (cw & ~excepts) | (*flagp & excepts);
+
+ if (cw != cw_new)
+ _FPU_SETCW (cw_new);
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/or1k/ftestexcept.c b/libm/or1k/ftestexcept.c
new file mode 100644
index 000000000..02ddf12c8
--- /dev/null
+++ b/libm/or1k/ftestexcept.c
@@ -0,0 +1,25 @@
+/* Test exception in current environment. OpenRISC version.
+ Copyright (C) 2024-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)
+{
+ return libc_fetestexcept_or1k (excepts);
+}
diff --git a/libm/or1k/get-rounding-mode.h b/libm/or1k/get-rounding-mode.h
new file mode 100644
index 000000000..f65c4ecc0
--- /dev/null
+++ b/libm/or1k/get-rounding-mode.h
@@ -0,0 +1,36 @@
+/* Determine floating-point rounding mode within libc. OpenRISC version.
+
+ Copyright (C) 2024-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 _OR1K_GET_ROUNDING_MODE_H
+#define _OR1K_GET_ROUNDING_MODE_H 1
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+/* Return the floating-point rounding mode. */
+
+static inline int
+get_rounding_mode (void)
+{
+ fpu_control_t cw;
+
+ _FPU_GETCW (cw);
+ return cw & _FPU_FPCSR_RM_MASK;
+}
+
+#endif /* get-rounding-mode.h */
diff --git a/libm/riscv32/Makefile.arch b/libm/riscv32/Makefile.arch
new file mode 100644
index 000000000..bd38690be
--- /dev/null
+++ b/libm/riscv32/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/riscv32/fclrexcpt.c b/libm/riscv32/fclrexcpt.c
new file mode 100644
index 000000000..849a910fc
--- /dev/null
+++ b/libm/riscv32/fclrexcpt.c
@@ -0,0 +1,26 @@
+/* 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)
+{
+ __asm__ volatile ("csrc fflags, %0" : : "r" (excepts));
+ return 0;
+}
diff --git a/libm/riscv32/fegetenv.c b/libm/riscv32/fegetenv.c
new file mode 100644
index 000000000..94f3444ac
--- /dev/null
+++ b/libm/riscv32/fegetenv.c
@@ -0,0 +1,28 @@
+/* Store 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
+fegetenv (fenv_t *envp)
+{
+ _FPU_GETCW (*envp);
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/riscv32/fegetmode.c b/libm/riscv32/fegetmode.c
new file mode 100644
index 000000000..4b0ff270c
--- /dev/null
+++ b/libm/riscv32/fegetmode.c
@@ -0,0 +1,26 @@
+/* Store current floating-point control modes. RISC-V version.
+ Copyright (C) 2017-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/riscv32/fegetround.c b/libm/riscv32/fegetround.c
new file mode 100644
index 000000000..abd13fc7f
--- /dev/null
+++ b/libm/riscv32/fegetround.c
@@ -0,0 +1,25 @@
+/* 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 "fenv_private.h"
+
+int
+fegetround (void)
+{
+ return riscv_getround ();
+}
diff --git a/libm/riscv32/feholdexcpt.c b/libm/riscv32/feholdexcpt.c
new file mode 100644
index 000000000..5d95a08fe
--- /dev/null
+++ b/libm/riscv32/feholdexcpt.c
@@ -0,0 +1,26 @@
+/* Store current floating-point environment and clear 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
+feholdexcept (fenv_t *envp)
+{
+ libc_feholdexcept_riscv (envp);
+ return 0;
+}
diff --git a/libm/riscv32/fenv_private.h b/libm/riscv32/fenv_private.h
new file mode 100644
index 000000000..9eed4b614
--- /dev/null
+++ b/libm/riscv32/fenv_private.h
@@ -0,0 +1,156 @@
+/* Private floating point rounding and exceptions handling. RISC-V version.
+ Copyright (C) 2014-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 RISCV_FENV_PRIVATE_H
+#define RISCV_FENV_PRIVATE_H 1
+
+#include <fenv.h>
+#include <fpu_control.h>
+#include "get-rounding-mode.h"
+
+static __always_inline int
+riscv_getround (void)
+{
+ return get_rounding_mode ();
+}
+
+static __always_inline void
+riscv_setround (int rm)
+{
+ __asm__ volatile ("fsrm %z0" : : "rJ" (rm));
+}
+
+static __always_inline int
+riscv_getflags (void)
+{
+ int flags;
+ __asm__ volatile ("frflags %0" : "=r" (flags));
+ return flags;
+}
+
+static __always_inline void
+riscv_setflags (int flags)
+{
+ __asm__ volatile ("fsflags %z0" : : "rJ" (flags));
+}
+
+static __always_inline void
+libc_feholdexcept_riscv (fenv_t *envp)
+{
+ __asm__ volatile ("csrrc %0, fcsr, %1" : "=r" (*envp) : "i" (FE_ALL_EXCEPT));
+}
+
+#define libc_feholdexcept libc_feholdexcept_riscv
+#define libc_feholdexceptf libc_feholdexcept_riscv
+#define libc_feholdexceptl libc_feholdexcept_riscv
+
+static __always_inline void
+libc_fesetround_riscv (int round)
+{
+ riscv_setround (round);
+}
+
+#define libc_fesetround libc_fesetround_riscv
+#define libc_fesetroundf libc_fesetround_riscv
+#define libc_fesetroundl libc_fesetround_riscv
+
+static __always_inline void
+libc_feholdexcept_setround_riscv (fenv_t *envp, int round)
+{
+ libc_feholdexcept_riscv (envp);
+ libc_fesetround_riscv (round);
+}
+
+#define libc_feholdexcept_setround libc_feholdexcept_setround_riscv
+#define libc_feholdexcept_setroundf libc_feholdexcept_setround_riscv
+#define libc_feholdexcept_setroundl libc_feholdexcept_setround_riscv
+
+static __always_inline int
+libc_fetestexcept_riscv (int ex)
+{
+ return riscv_getflags () & ex;
+}
+
+#define libc_fetestexcept libc_fetestexcept_riscv
+#define libc_fetestexceptf libc_fetestexcept_riscv
+#define libc_fetestexceptl libc_fetestexcept_riscv
+
+static __always_inline void
+libc_fesetenv_riscv (const fenv_t *envp)
+{
+ long int env = (envp != FE_DFL_ENV ? *envp : 0);
+ _FPU_SETCW (env);
+}
+
+#define libc_fesetenv libc_fesetenv_riscv
+#define libc_fesetenvf libc_fesetenv_riscv
+#define libc_fesetenvl libc_fesetenv_riscv
+#define libc_feresetround_noex libc_fesetenv_riscv
+#define libc_feresetround_noexf libc_fesetenv_riscv
+#define libc_feresetround_noexl libc_fesetenv_riscv
+
+static __always_inline int
+libc_feupdateenv_test_riscv (const fenv_t *envp, int ex)
+{
+ fenv_t env = *envp;
+ int flags = riscv_getflags ();
+ __asm__ volatile ("csrw fcsr, %z0" : : "rJ" (env | flags));
+ return flags & ex;
+}
+
+#define libc_feupdateenv_test libc_feupdateenv_test_riscv
+#define libc_feupdateenv_testf libc_feupdateenv_test_riscv
+#define libc_feupdateenv_testl libc_feupdateenv_test_riscv
+
+static __always_inline void
+libc_feupdateenv_riscv (const fenv_t *envp)
+{
+ long int env = (envp != FE_DFL_ENV ? *envp : 0);
+ _FPU_SETCW (env | riscv_getflags ());
+}
+
+#define libc_feupdateenv libc_feupdateenv_riscv
+#define libc_feupdateenvf libc_feupdateenv_riscv
+#define libc_feupdateenvl libc_feupdateenv_riscv
+
+static __always_inline void
+libc_feholdsetround_riscv (fenv_t *envp, int round)
+{
+ /* Note this implementation makes an improperly-formatted fenv_t and
+ so should only be used in conjunction with libc_feresetround. */
+ int old_round;
+ __asm__ volatile ("csrrw %0, frm, %z1" : "=r" (old_round) : "rJ" (round));
+ *envp = old_round;
+}
+
+#define libc_feholdsetround libc_feholdsetround_riscv
+#define libc_feholdsetroundf libc_feholdsetround_riscv
+#define libc_feholdsetroundl libc_feholdsetround_riscv
+
+static __always_inline void
+libc_feresetround_riscv (fenv_t *envp)
+{
+ /* Note this implementation takes an improperly-formatted fenv_t and
+ so should only be used in conjunction with libc_feholdsetround. */
+ riscv_setround (*envp);
+}
+
+#define libc_feresetround libc_feresetround_riscv
+#define libc_feresetroundf libc_feresetround_riscv
+#define libc_feresetroundl libc_feresetround_riscv
+
+#endif
diff --git a/libm/riscv32/fesetenv.c b/libm/riscv32/fesetenv.c
new file mode 100644
index 000000000..8b7427c18
--- /dev/null
+++ b/libm/riscv32/fesetenv.c
@@ -0,0 +1,26 @@
+/* Install given 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 "fenv_private.h"
+
+int
+fesetenv (const fenv_t *envp)
+{
+ libc_fesetenv_riscv (envp);
+ return 0;
+}
diff --git a/libm/riscv32/fesetexcept.c b/libm/riscv32/fesetexcept.c
new file mode 100644
index 000000000..9c931a1b7
--- /dev/null
+++ b/libm/riscv32/fesetexcept.c
@@ -0,0 +1,25 @@
+/* Set given exception flags. RISC-V version.
+ Copyright (C) 2017-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>
+
+int
+fesetexcept (int excepts)
+{
+ __asm__ volatile ("csrs fflags, %0" : : "r" (excepts));
+ return 0;
+}
diff --git a/libm/riscv32/fesetmode.c b/libm/riscv32/fesetmode.c
new file mode 100644
index 000000000..aaaf4480b
--- /dev/null
+++ b/libm/riscv32/fesetmode.c
@@ -0,0 +1,30 @@
+/* Install given floating-point control modes. RISC-V version.
+ Copyright (C) 2017-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)
+{
+ __asm__ volatile ("csrc fcsr, %0" : : "r" (~FE_ALL_EXCEPT));
+
+ if (modep != FE_DFL_MODE)
+ __asm__ volatile ("csrs fcsr, %0" : : "r" (*modep & ~FE_ALL_EXCEPT));
+
+ return 0;
+}
diff --git a/libm/riscv32/fesetround.c b/libm/riscv32/fesetround.c
new file mode 100644
index 000000000..a791751d1
--- /dev/null
+++ b/libm/riscv32/fesetround.c
@@ -0,0 +1,35 @@
+/* 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 "fenv_private.h"
+
+int
+fesetround (int round)
+{
+ switch (round)
+ {
+ case FE_TONEAREST:
+ case FE_TOWARDZERO:
+ case FE_DOWNWARD:
+ case FE_UPWARD:
+ riscv_setround (round);
+ return 0;
+ default:
+ return round; /* A nonzero value. */
+ }
+}
diff --git a/libm/riscv32/feupdateenv.c b/libm/riscv32/feupdateenv.c
new file mode 100644
index 000000000..ea62bd1aa
--- /dev/null
+++ b/libm/riscv32/feupdateenv.c
@@ -0,0 +1,26 @@
+/* Install given floating-point environment and raise exceptions.
+ 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 "fenv_private.h"
+
+int
+feupdateenv (const fenv_t *envp)
+{
+ libc_feupdateenv_riscv (envp);
+ return 0;
+}
diff --git a/libm/riscv32/fgetexcptflg.c b/libm/riscv32/fgetexcptflg.c
new file mode 100644
index 000000000..ecf513bed
--- /dev/null
+++ b/libm/riscv32/fgetexcptflg.c
@@ -0,0 +1,29 @@
+/* Store current representation for exceptions.
+ 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 "fenv_private.h"
+
+int
+fegetexceptflag (fexcept_t *flagp, int excepts)
+{
+ /* Get the current exceptions. */
+ *flagp = riscv_getflags () & excepts;
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/riscv32/fraiseexcpt.c b/libm/riscv32/fraiseexcpt.c
new file mode 100644
index 000000000..f89f983d7
--- /dev/null
+++ b/libm/riscv32/fraiseexcpt.c
@@ -0,0 +1,26 @@
+/* Raise given 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 <fpu_control.h>
+
+int
+feraiseexcept (int excepts)
+{
+ __asm__ volatile ("csrs fflags, %0" : : "r" (excepts));
+ return 0;
+}
diff --git a/libm/riscv32/fsetexcptflg.c b/libm/riscv32/fsetexcptflg.c
new file mode 100644
index 000000000..f295c18ab
--- /dev/null
+++ b/libm/riscv32/fsetexcptflg.c
@@ -0,0 +1,29 @@
+/* Set floating-point environment exception handling.
+ 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
+fesetexceptflag (const fexcept_t *flagp, int excepts)
+{
+ fexcept_t flags = *flagp;
+ __asm__ volatile ("csrc fflags, %0" : : "r" (excepts));
+ __asm__ volatile ("csrs fflags, %0" : : "r" (flags & excepts));
+
+ return 0;
+}
diff --git a/libm/riscv32/ftestexcept.c b/libm/riscv32/ftestexcept.c
new file mode 100644
index 000000000..ed3a3e5e0
--- /dev/null
+++ b/libm/riscv32/ftestexcept.c
@@ -0,0 +1,25 @@
+/* Test exception in current 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 "fenv_private.h"
+
+int
+fetestexcept (int excepts)
+{
+ return libc_fetestexcept_riscv (excepts);
+}
diff --git a/libm/riscv32/get-rounding-mode.h b/libm/riscv32/get-rounding-mode.h
new file mode 100644
index 000000000..7ab691ac8
--- /dev/null
+++ b/libm/riscv32/get-rounding-mode.h
@@ -0,0 +1,32 @@
+/* Determine floating-point rounding mode within libc. RISC-V version.
+ Copyright (C) 2015-2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _RISCV_GET_ROUNDING_MODE_H
+#define _RISCV_GET_ROUNDING_MODE_H
+
+/* Return the floating-point rounding mode. */
+
+static inline int
+get_rounding_mode (void)
+{
+ int rm;
+ __asm__ volatile ("frrm %0" : "=r" (rm));
+ return rm;
+}
+
+#endif /* get-rounding-mode.h */
diff --git a/libm/riscv64/Makefile.arch b/libm/riscv64/Makefile.arch
new file mode 100644
index 000000000..bd38690be
--- /dev/null
+++ b/libm/riscv64/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/riscv64/fclrexcpt.c b/libm/riscv64/fclrexcpt.c
new file mode 100644
index 000000000..849a910fc
--- /dev/null
+++ b/libm/riscv64/fclrexcpt.c
@@ -0,0 +1,26 @@
+/* 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)
+{
+ __asm__ volatile ("csrc fflags, %0" : : "r" (excepts));
+ return 0;
+}
diff --git a/libm/riscv64/fegetenv.c b/libm/riscv64/fegetenv.c
new file mode 100644
index 000000000..94f3444ac
--- /dev/null
+++ b/libm/riscv64/fegetenv.c
@@ -0,0 +1,28 @@
+/* Store 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
+fegetenv (fenv_t *envp)
+{
+ _FPU_GETCW (*envp);
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/riscv64/fegetmode.c b/libm/riscv64/fegetmode.c
new file mode 100644
index 000000000..4b0ff270c
--- /dev/null
+++ b/libm/riscv64/fegetmode.c
@@ -0,0 +1,26 @@
+/* Store current floating-point control modes. RISC-V version.
+ Copyright (C) 2017-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/riscv64/fegetround.c b/libm/riscv64/fegetround.c
new file mode 100644
index 000000000..abd13fc7f
--- /dev/null
+++ b/libm/riscv64/fegetround.c
@@ -0,0 +1,25 @@
+/* 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 "fenv_private.h"
+
+int
+fegetround (void)
+{
+ return riscv_getround ();
+}
diff --git a/libm/riscv64/feholdexcpt.c b/libm/riscv64/feholdexcpt.c
new file mode 100644
index 000000000..5d95a08fe
--- /dev/null
+++ b/libm/riscv64/feholdexcpt.c
@@ -0,0 +1,26 @@
+/* Store current floating-point environment and clear 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
+feholdexcept (fenv_t *envp)
+{
+ libc_feholdexcept_riscv (envp);
+ return 0;
+}
diff --git a/libm/riscv64/fenv_private.h b/libm/riscv64/fenv_private.h
new file mode 100644
index 000000000..9eed4b614
--- /dev/null
+++ b/libm/riscv64/fenv_private.h
@@ -0,0 +1,156 @@
+/* Private floating point rounding and exceptions handling. RISC-V version.
+ Copyright (C) 2014-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 RISCV_FENV_PRIVATE_H
+#define RISCV_FENV_PRIVATE_H 1
+
+#include <fenv.h>
+#include <fpu_control.h>
+#include "get-rounding-mode.h"
+
+static __always_inline int
+riscv_getround (void)
+{
+ return get_rounding_mode ();
+}
+
+static __always_inline void
+riscv_setround (int rm)
+{
+ __asm__ volatile ("fsrm %z0" : : "rJ" (rm));
+}
+
+static __always_inline int
+riscv_getflags (void)
+{
+ int flags;
+ __asm__ volatile ("frflags %0" : "=r" (flags));
+ return flags;
+}
+
+static __always_inline void
+riscv_setflags (int flags)
+{
+ __asm__ volatile ("fsflags %z0" : : "rJ" (flags));
+}
+
+static __always_inline void
+libc_feholdexcept_riscv (fenv_t *envp)
+{
+ __asm__ volatile ("csrrc %0, fcsr, %1" : "=r" (*envp) : "i" (FE_ALL_EXCEPT));
+}
+
+#define libc_feholdexcept libc_feholdexcept_riscv
+#define libc_feholdexceptf libc_feholdexcept_riscv
+#define libc_feholdexceptl libc_feholdexcept_riscv
+
+static __always_inline void
+libc_fesetround_riscv (int round)
+{
+ riscv_setround (round);
+}
+
+#define libc_fesetround libc_fesetround_riscv
+#define libc_fesetroundf libc_fesetround_riscv
+#define libc_fesetroundl libc_fesetround_riscv
+
+static __always_inline void
+libc_feholdexcept_setround_riscv (fenv_t *envp, int round)
+{
+ libc_feholdexcept_riscv (envp);
+ libc_fesetround_riscv (round);
+}
+
+#define libc_feholdexcept_setround libc_feholdexcept_setround_riscv
+#define libc_feholdexcept_setroundf libc_feholdexcept_setround_riscv
+#define libc_feholdexcept_setroundl libc_feholdexcept_setround_riscv
+
+static __always_inline int
+libc_fetestexcept_riscv (int ex)
+{
+ return riscv_getflags () & ex;
+}
+
+#define libc_fetestexcept libc_fetestexcept_riscv
+#define libc_fetestexceptf libc_fetestexcept_riscv
+#define libc_fetestexceptl libc_fetestexcept_riscv
+
+static __always_inline void
+libc_fesetenv_riscv (const fenv_t *envp)
+{
+ long int env = (envp != FE_DFL_ENV ? *envp : 0);
+ _FPU_SETCW (env);
+}
+
+#define libc_fesetenv libc_fesetenv_riscv
+#define libc_fesetenvf libc_fesetenv_riscv
+#define libc_fesetenvl libc_fesetenv_riscv
+#define libc_feresetround_noex libc_fesetenv_riscv
+#define libc_feresetround_noexf libc_fesetenv_riscv
+#define libc_feresetround_noexl libc_fesetenv_riscv
+
+static __always_inline int
+libc_feupdateenv_test_riscv (const fenv_t *envp, int ex)
+{
+ fenv_t env = *envp;
+ int flags = riscv_getflags ();
+ __asm__ volatile ("csrw fcsr, %z0" : : "rJ" (env | flags));
+ return flags & ex;
+}
+
+#define libc_feupdateenv_test libc_feupdateenv_test_riscv
+#define libc_feupdateenv_testf libc_feupdateenv_test_riscv
+#define libc_feupdateenv_testl libc_feupdateenv_test_riscv
+
+static __always_inline void
+libc_feupdateenv_riscv (const fenv_t *envp)
+{
+ long int env = (envp != FE_DFL_ENV ? *envp : 0);
+ _FPU_SETCW (env | riscv_getflags ());
+}
+
+#define libc_feupdateenv libc_feupdateenv_riscv
+#define libc_feupdateenvf libc_feupdateenv_riscv
+#define libc_feupdateenvl libc_feupdateenv_riscv
+
+static __always_inline void
+libc_feholdsetround_riscv (fenv_t *envp, int round)
+{
+ /* Note this implementation makes an improperly-formatted fenv_t and
+ so should only be used in conjunction with libc_feresetround. */
+ int old_round;
+ __asm__ volatile ("csrrw %0, frm, %z1" : "=r" (old_round) : "rJ" (round));
+ *envp = old_round;
+}
+
+#define libc_feholdsetround libc_feholdsetround_riscv
+#define libc_feholdsetroundf libc_feholdsetround_riscv
+#define libc_feholdsetroundl libc_feholdsetround_riscv
+
+static __always_inline void
+libc_feresetround_riscv (fenv_t *envp)
+{
+ /* Note this implementation takes an improperly-formatted fenv_t and
+ so should only be used in conjunction with libc_feholdsetround. */
+ riscv_setround (*envp);
+}
+
+#define libc_feresetround libc_feresetround_riscv
+#define libc_feresetroundf libc_feresetround_riscv
+#define libc_feresetroundl libc_feresetround_riscv
+
+#endif
diff --git a/libm/riscv64/fesetenv.c b/libm/riscv64/fesetenv.c
new file mode 100644
index 000000000..8b7427c18
--- /dev/null
+++ b/libm/riscv64/fesetenv.c
@@ -0,0 +1,26 @@
+/* Install given 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 "fenv_private.h"
+
+int
+fesetenv (const fenv_t *envp)
+{
+ libc_fesetenv_riscv (envp);
+ return 0;
+}
diff --git a/libm/riscv64/fesetexcept.c b/libm/riscv64/fesetexcept.c
new file mode 100644
index 000000000..9c931a1b7
--- /dev/null
+++ b/libm/riscv64/fesetexcept.c
@@ -0,0 +1,25 @@
+/* Set given exception flags. RISC-V version.
+ Copyright (C) 2017-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>
+
+int
+fesetexcept (int excepts)
+{
+ __asm__ volatile ("csrs fflags, %0" : : "r" (excepts));
+ return 0;
+}
diff --git a/libm/riscv64/fesetmode.c b/libm/riscv64/fesetmode.c
new file mode 100644
index 000000000..aaaf4480b
--- /dev/null
+++ b/libm/riscv64/fesetmode.c
@@ -0,0 +1,30 @@
+/* Install given floating-point control modes. RISC-V version.
+ Copyright (C) 2017-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)
+{
+ __asm__ volatile ("csrc fcsr, %0" : : "r" (~FE_ALL_EXCEPT));
+
+ if (modep != FE_DFL_MODE)
+ __asm__ volatile ("csrs fcsr, %0" : : "r" (*modep & ~FE_ALL_EXCEPT));
+
+ return 0;
+}
diff --git a/libm/riscv64/fesetround.c b/libm/riscv64/fesetround.c
new file mode 100644
index 000000000..a791751d1
--- /dev/null
+++ b/libm/riscv64/fesetround.c
@@ -0,0 +1,35 @@
+/* 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 "fenv_private.h"
+
+int
+fesetround (int round)
+{
+ switch (round)
+ {
+ case FE_TONEAREST:
+ case FE_TOWARDZERO:
+ case FE_DOWNWARD:
+ case FE_UPWARD:
+ riscv_setround (round);
+ return 0;
+ default:
+ return round; /* A nonzero value. */
+ }
+}
diff --git a/libm/riscv64/feupdateenv.c b/libm/riscv64/feupdateenv.c
new file mode 100644
index 000000000..ea62bd1aa
--- /dev/null
+++ b/libm/riscv64/feupdateenv.c
@@ -0,0 +1,26 @@
+/* Install given floating-point environment and raise exceptions.
+ 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 "fenv_private.h"
+
+int
+feupdateenv (const fenv_t *envp)
+{
+ libc_feupdateenv_riscv (envp);
+ return 0;
+}
diff --git a/libm/riscv64/fgetexcptflg.c b/libm/riscv64/fgetexcptflg.c
new file mode 100644
index 000000000..ecf513bed
--- /dev/null
+++ b/libm/riscv64/fgetexcptflg.c
@@ -0,0 +1,29 @@
+/* Store current representation for exceptions.
+ 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 "fenv_private.h"
+
+int
+fegetexceptflag (fexcept_t *flagp, int excepts)
+{
+ /* Get the current exceptions. */
+ *flagp = riscv_getflags () & excepts;
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/riscv64/fraiseexcpt.c b/libm/riscv64/fraiseexcpt.c
new file mode 100644
index 000000000..f89f983d7
--- /dev/null
+++ b/libm/riscv64/fraiseexcpt.c
@@ -0,0 +1,26 @@
+/* Raise given 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 <fpu_control.h>
+
+int
+feraiseexcept (int excepts)
+{
+ __asm__ volatile ("csrs fflags, %0" : : "r" (excepts));
+ return 0;
+}
diff --git a/libm/riscv64/fsetexcptflg.c b/libm/riscv64/fsetexcptflg.c
new file mode 100644
index 000000000..f295c18ab
--- /dev/null
+++ b/libm/riscv64/fsetexcptflg.c
@@ -0,0 +1,29 @@
+/* Set floating-point environment exception handling.
+ 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
+fesetexceptflag (const fexcept_t *flagp, int excepts)
+{
+ fexcept_t flags = *flagp;
+ __asm__ volatile ("csrc fflags, %0" : : "r" (excepts));
+ __asm__ volatile ("csrs fflags, %0" : : "r" (flags & excepts));
+
+ return 0;
+}
diff --git a/libm/riscv64/ftestexcept.c b/libm/riscv64/ftestexcept.c
new file mode 100644
index 000000000..ed3a3e5e0
--- /dev/null
+++ b/libm/riscv64/ftestexcept.c
@@ -0,0 +1,25 @@
+/* Test exception in current 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 "fenv_private.h"
+
+int
+fetestexcept (int excepts)
+{
+ return libc_fetestexcept_riscv (excepts);
+}
diff --git a/libm/riscv64/get-rounding-mode.h b/libm/riscv64/get-rounding-mode.h
new file mode 100644
index 000000000..7ab691ac8
--- /dev/null
+++ b/libm/riscv64/get-rounding-mode.h
@@ -0,0 +1,32 @@
+/* Determine floating-point rounding mode within libc. RISC-V version.
+ Copyright (C) 2015-2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _RISCV_GET_ROUNDING_MODE_H
+#define _RISCV_GET_ROUNDING_MODE_H
+
+/* Return the floating-point rounding mode. */
+
+static inline int
+get_rounding_mode (void)
+{
+ int rm;
+ __asm__ volatile ("frrm %0" : "=r" (rm));
+ return rm;
+}
+
+#endif /* get-rounding-mode.h */
diff --git a/libm/s_expm1.c b/libm/s_expm1.c
index 8e51ae748..85defefa4 100644
--- a/libm/s_expm1.c
+++ b/libm/s_expm1.c
@@ -159,7 +159,7 @@ double expm1(double x)
else
{hi = x + ln2_hi; lo = -ln2_lo; k = -1;}
} else {
- k = invln2*x+((xsb==0)?0.5:-0.5);
+ k = (int32_t)(invln2*x+((xsb==0)?0.5:-0.5));
t = k;
hi = x - t*ln2_hi; /* t*ln2_hi is exact here */
lo = t*ln2_lo;
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/libm/w_cabs.c b/libm/w_cabs.c
index b2592484c..546b6affa 100644
--- a/libm/w_cabs.c
+++ b/libm/w_cabs.c
@@ -17,7 +17,7 @@ libm_hidden_def(cabs)
libm_hidden_proto(cabsf)
float cabsf(float _Complex z)
{
- return (float) hypot(__real__ z, __imag__ z);
+ return (float) hypot((double)__real__ z, (double)__imag__ z);
}
libm_hidden_def(cabsf)
diff --git a/libpthread/linuxthreads/Makefile.in b/libpthread/linuxthreads/Makefile.in
index ffdd5d4eb..cc2a5f285 100644
--- a/libpthread/linuxthreads/Makefile.in
+++ b/libpthread/linuxthreads/Makefile.in
@@ -16,6 +16,8 @@ libpthread_OUT := $(top_builddir)libpthread/linuxthreads
-include $(libpthread_DIR)/sysdeps/$(TARGET_ARCH)/Makefile.arch
+CFLAGS-signals.c = -fexceptions -fasynchronous-unwind-tables
+
libpthread_SRC := \
attr.c cancel.c condvar.c errno.c events.c join.c lockfile.c manager.c \
mutex.c pt-machine.c ptfork.c pthread.c ptlongjmp.c \
diff --git a/libpthread/linuxthreads/sysdeps/pthread/not-cancel.h b/libpthread/linuxthreads/sysdeps/pthread/not-cancel.h
index bbdb0739c..6d7c4d70a 100644
--- a/libpthread/linuxthreads/sysdeps/pthread/not-cancel.h
+++ b/libpthread/linuxthreads/sysdeps/pthread/not-cancel.h
@@ -19,6 +19,7 @@
#include <sys/types.h>
#include <sysdep.h>
+#include <time.h>
/* Uncancelable open. */
#if defined __NR_openat && !defined __NR_open
@@ -104,6 +105,7 @@ extern int __openat64_nocancel (int fd, const char *fname, int oflag,
# define nanosleep_not_cancel(requested_time, remaining) \
INLINE_SYSCALL (nanosleep, 2, requested_time, remaining)
#else
+extern int __nanosleep_nocancel (const struct timespec *requested_time, struct timespec *remaining);
# define nanosleep_not_cancel(requested_time, remaining) \
__nanosleep_nocancel (requested_time, remaining)
#endif
diff --git a/libpthread/nptl/allocatestack.c b/libpthread/nptl/allocatestack.c
index 7ef884543..941ef22f0 100644
--- a/libpthread/nptl/allocatestack.c
+++ b/libpthread/nptl/allocatestack.c
@@ -24,6 +24,7 @@
#include <unistd.h>
#include <sys/mman.h>
#include <sys/param.h>
+#include <dl-tls.h>
#include <tls.h>
#include <lowlevellock.h>
#include <link.h>
@@ -241,6 +242,10 @@ get_cached_stack (size_t *sizep, void **memp)
/* Clear the DTV. */
dtv_t *dtv = GET_DTV (TLS_TPADJ (result));
+ for (size_t cnt = 0; cnt < dtv[-1].counter; ++cnt)
+ if (! dtv[1 + cnt].pointer.is_static
+ && dtv[1 + cnt].pointer.val != TLS_DTV_UNALLOCATED)
+ free (dtv[1 + cnt].pointer.val);
memset (dtv, '\0', (dtv[-1].counter + 1) * sizeof (dtv_t));
/* Re-initialize the TLS. */
diff --git a/libpthread/nptl/sysdeps/arc/dl-tls.h b/libpthread/nptl/sysdeps/arc/dl-tls.h
index 34e54e4d3..e81c0c187 100644
--- a/libpthread/nptl/sysdeps/arc/dl-tls.h
+++ b/libpthread/nptl/sysdeps/arc/dl-tls.h
@@ -26,3 +26,6 @@ typedef struct
extern void *__tls_get_addr (tls_index *ti);
+
+/* Value used for dtv entries for which the allocation is delayed. */
+#define TLS_DTV_UNALLOCATED ((void *) -1l)
diff --git a/libpthread/nptl/sysdeps/arm/dl-tls.h b/libpthread/nptl/sysdeps/arm/dl-tls.h
index a728455e4..a79ea7160 100644
--- a/libpthread/nptl/sysdeps/arm/dl-tls.h
+++ b/libpthread/nptl/sysdeps/arm/dl-tls.h
@@ -26,3 +26,6 @@ typedef struct
extern void *__tls_get_addr (tls_index *ti);
+
+/* Value used for dtv entries for which the allocation is delayed. */
+#define TLS_DTV_UNALLOCATED ((void *) -1l)
diff --git a/libpthread/nptl/sysdeps/csky/dl-tls.h b/libpthread/nptl/sysdeps/csky/dl-tls.h
index ebf1a7dc3..7171d47ea 100644
--- a/libpthread/nptl/sysdeps/csky/dl-tls.h
+++ b/libpthread/nptl/sysdeps/csky/dl-tls.h
@@ -14,3 +14,5 @@ typedef struct
extern void *__tls_get_addr (tls_index *ti);
+/* Value used for dtv entries for which the allocation is delayed. */
+#define TLS_DTV_UNALLOCATED ((void *) -1l)
diff --git a/libpthread/nptl/sysdeps/generic/dl-tls.c b/libpthread/nptl/sysdeps/generic/dl-tls.c
index 7d25e4706..7b7991be8 100644
--- a/libpthread/nptl/sysdeps/generic/dl-tls.c
+++ b/libpthread/nptl/sysdeps/generic/dl-tls.c
@@ -45,8 +45,6 @@
to allow dynamic loading of modules defining IE-model TLS data. */
# define TLS_STATIC_SURPLUS 64 + DL_NNS * 100
-/* Value used for dtv entries for which the allocation is delayed. */
-# define TLS_DTV_UNALLOCATED ((void *) -1l)
#ifndef SHARED
extern dtv_t static_dtv;
diff --git a/libpthread/nptl/sysdeps/i386/dl-tls.h b/libpthread/nptl/sysdeps/i386/dl-tls.h
index 32495c1e0..004082407 100644
--- a/libpthread/nptl/sysdeps/i386/dl-tls.h
+++ b/libpthread/nptl/sysdeps/i386/dl-tls.h
@@ -59,3 +59,6 @@ strong_alias (___tls_get_addr, ___tls_get_addr_internal)
# endif
#endif
+
+/* Value used for dtv entries for which the allocation is delayed. */
+#define TLS_DTV_UNALLOCATED ((void *) -1l)
diff --git a/libpthread/nptl/sysdeps/metag/dl-tls.h b/libpthread/nptl/sysdeps/metag/dl-tls.h
index 81632e057..811d6254f 100644
--- a/libpthread/nptl/sysdeps/metag/dl-tls.h
+++ b/libpthread/nptl/sysdeps/metag/dl-tls.h
@@ -26,3 +26,6 @@ typedef struct
extern void *__tls_get_addr (tls_index *ti);
+
+/* Value used for dtv entries for which the allocation is delayed. */
+#define TLS_DTV_UNALLOCATED ((void *) -1l)
diff --git a/libpthread/nptl/sysdeps/microblaze/dl-tls.h b/libpthread/nptl/sysdeps/microblaze/dl-tls.h
index 5613e21e2..ded8714bd 100644
--- a/libpthread/nptl/sysdeps/microblaze/dl-tls.h
+++ b/libpthread/nptl/sysdeps/microblaze/dl-tls.h
@@ -24,3 +24,6 @@ typedef struct
} tls_index;
extern void *__tls_get_addr (tls_index *ti);
+
+/* Value used for dtv entries for which the allocation is delayed. */
+#define TLS_DTV_UNALLOCATED ((void *) -1l)
diff --git a/libpthread/nptl/sysdeps/mips/dl-tls.h b/libpthread/nptl/sysdeps/mips/dl-tls.h
index e26aa388b..63ec2bc00 100644
--- a/libpthread/nptl/sysdeps/mips/dl-tls.h
+++ b/libpthread/nptl/sysdeps/mips/dl-tls.h
@@ -43,3 +43,6 @@ extern void *__tls_get_addr (tls_index *ti);
# define GET_ADDR_OFFSET (ti->ti_offset + TLS_DTV_OFFSET)
# define __TLS_GET_ADDR(__ti) (__tls_get_addr (__ti) - TLS_DTV_OFFSET)
+
+/* Value used for dtv entries for which the allocation is delayed. */
+#define TLS_DTV_UNALLOCATED ((void *) -1l)
diff --git a/libpthread/nptl/sysdeps/nds32/dl-tls.h b/libpthread/nptl/sysdeps/nds32/dl-tls.h
index 3b11e7f42..f0107cacb 100644
--- a/libpthread/nptl/sysdeps/nds32/dl-tls.h
+++ b/libpthread/nptl/sysdeps/nds32/dl-tls.h
@@ -50,7 +50,7 @@ struct tlsdesc_dynamic_arg
extern void *__tls_get_addr (tls_index *ti);
extern ptrdiff_t attribute_hidden
- _dl_tlsdesc_return(struct tlsdesc_dynamic_arg *);
+ _dl_tlsdesc_return(struct tlsdesc *);
extern void *_dl_make_tlsdesc_dynamic (struct link_map *map, size_t ti_offset);
extern ptrdiff_t attribute_hidden
diff --git a/libpthread/nptl/sysdeps/or1k/dl-tls.h b/libpthread/nptl/sysdeps/or1k/dl-tls.h
index 5613e21e2..ded8714bd 100644
--- a/libpthread/nptl/sysdeps/or1k/dl-tls.h
+++ b/libpthread/nptl/sysdeps/or1k/dl-tls.h
@@ -24,3 +24,6 @@ typedef struct
} tls_index;
extern void *__tls_get_addr (tls_index *ti);
+
+/* Value used for dtv entries for which the allocation is delayed. */
+#define TLS_DTV_UNALLOCATED ((void *) -1l)
diff --git a/libpthread/nptl/sysdeps/powerpc/dl-tls.h b/libpthread/nptl/sysdeps/powerpc/dl-tls.h
index c322ade60..ae50098c7 100644
--- a/libpthread/nptl/sysdeps/powerpc/dl-tls.h
+++ b/libpthread/nptl/sysdeps/powerpc/dl-tls.h
@@ -46,3 +46,6 @@ extern void *__tls_get_addr (tls_index *ti);
# define GET_ADDR_OFFSET (ti->ti_offset + TLS_DTV_OFFSET)
# define __TLS_GET_ADDR(__ti) (__tls_get_addr (__ti) - TLS_DTV_OFFSET)
#endif
+
+/* Value used for dtv entries for which the allocation is delayed. */
+#define TLS_DTV_UNALLOCATED ((void *) -1l)
diff --git a/libpthread/nptl/sysdeps/riscv32/dl-tls.h b/libpthread/nptl/sysdeps/riscv32/dl-tls.h
index 31991be0d..4124b7c78 100644
--- a/libpthread/nptl/sysdeps/riscv32/dl-tls.h
+++ b/libpthread/nptl/sysdeps/riscv32/dl-tls.h
@@ -32,3 +32,6 @@ extern void *__tls_get_addr (tls_index *ti);
#define GET_ADDR_OFFSET (ti->ti_offset + TLS_DTV_OFFSET)
#define __TLS_GET_ADDR(__ti) (__tls_get_addr (__ti) - TLS_DTV_OFFSET)
+
+/* Value used for dtv entries for which the allocation is delayed. */
+#define TLS_DTV_UNALLOCATED ((void *) -1l)
diff --git a/libpthread/nptl/sysdeps/riscv64/dl-tls.h b/libpthread/nptl/sysdeps/riscv64/dl-tls.h
index 31991be0d..4124b7c78 100644
--- a/libpthread/nptl/sysdeps/riscv64/dl-tls.h
+++ b/libpthread/nptl/sysdeps/riscv64/dl-tls.h
@@ -32,3 +32,6 @@ extern void *__tls_get_addr (tls_index *ti);
#define GET_ADDR_OFFSET (ti->ti_offset + TLS_DTV_OFFSET)
#define __TLS_GET_ADDR(__ti) (__tls_get_addr (__ti) - TLS_DTV_OFFSET)
+
+/* Value used for dtv entries for which the allocation is delayed. */
+#define TLS_DTV_UNALLOCATED ((void *) -1l)
diff --git a/libpthread/nptl/sysdeps/sh/dl-tls.h b/libpthread/nptl/sysdeps/sh/dl-tls.h
index f5f90beaf..e0d13eec4 100644
--- a/libpthread/nptl/sysdeps/sh/dl-tls.h
+++ b/libpthread/nptl/sysdeps/sh/dl-tls.h
@@ -26,3 +26,6 @@ typedef struct
extern void *__tls_get_addr (tls_index *ti);
+
+/* Value used for dtv entries for which the allocation is delayed. */
+#define TLS_DTV_UNALLOCATED ((void *) -1l)
diff --git a/libpthread/nptl/sysdeps/sparc/dl-tls.h b/libpthread/nptl/sysdeps/sparc/dl-tls.h
index 7d9e8f0f7..aac9d5b30 100644
--- a/libpthread/nptl/sysdeps/sparc/dl-tls.h
+++ b/libpthread/nptl/sysdeps/sparc/dl-tls.h
@@ -26,3 +26,6 @@ typedef struct
extern void *__tls_get_addr (tls_index *ti);
+
+/* Value used for dtv entries for which the allocation is delayed. */
+#define TLS_DTV_UNALLOCATED ((void *) -1l)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/m68k/bits/pthreadtypes.h b/libpthread/nptl/sysdeps/unix/sysv/linux/m68k/bits/pthreadtypes.h
index 2a90a0b90..d2f22caee 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/m68k/bits/pthreadtypes.h
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/m68k/bits/pthreadtypes.h
@@ -39,7 +39,7 @@ typedef unsigned long int pthread_t;
typedef union
{
char __size[__SIZEOF_PTHREAD_ATTR_T];
- long int __align;
+ long int __align __attribute__((__aligned__(4)));
} pthread_attr_t;
@@ -69,13 +69,13 @@ typedef union
};
} __data;
char __size[__SIZEOF_PTHREAD_MUTEX_T];
- long int __align;
+ long int __align __attribute__((__aligned__(4)));
} pthread_mutex_t;
typedef union
{
char __size[__SIZEOF_PTHREAD_MUTEXATTR_T];
- long int __align;
+ long int __align __attribute__((__aligned__(4)));
} pthread_mutexattr_t;
@@ -95,13 +95,13 @@ typedef union
unsigned int __broadcast_seq;
} __data;
char __size[__SIZEOF_PTHREAD_COND_T];
- __extension__ long long int __align;
+ __extension__ long long int __align __attribute__((__aligned__(8)));
} pthread_cond_t;
typedef union
{
char __size[__SIZEOF_PTHREAD_CONDATTR_T];
- long int __align;
+ long int __align __attribute__((__aligned__(4)));
} pthread_condattr_t;
@@ -144,13 +144,13 @@ typedef union
int __writer;
} __data;
char __size[__SIZEOF_PTHREAD_RWLOCK_T];
- long int __align;
+ long int __align __attribute__((__aligned__(4)));
} pthread_rwlock_t;
typedef union
{
char __size[__SIZEOF_PTHREAD_RWLOCKATTR_T];
- long int __align;
+ long int __align __attribute__((__aligned__(4)));
} pthread_rwlockattr_t;
#endif
@@ -165,13 +165,13 @@ typedef volatile int pthread_spinlock_t;
typedef union
{
char __size[__SIZEOF_PTHREAD_BARRIER_T];
- long int __align;
+ long int __align __attribute__((__aligned__(4)));
} pthread_barrier_t;
typedef union
{
char __size[__SIZEOF_PTHREAD_BARRIERATTR_T];
- int __align;
+ int __align __attribute__((__aligned__(4)));
} pthread_barrierattr_t;
#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/not-cancel.h b/libpthread/nptl/sysdeps/unix/sysv/linux/not-cancel.h
index bbdb0739c..6d7c4d70a 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/not-cancel.h
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/not-cancel.h
@@ -19,6 +19,7 @@
#include <sys/types.h>
#include <sysdep.h>
+#include <time.h>
/* Uncancelable open. */
#if defined __NR_openat && !defined __NR_open
@@ -104,6 +105,7 @@ extern int __openat64_nocancel (int fd, const char *fname, int oflag,
# define nanosleep_not_cancel(requested_time, remaining) \
INLINE_SYSCALL (nanosleep, 2, requested_time, remaining)
#else
+extern int __nanosleep_nocancel (const struct timespec *requested_time, struct timespec *remaining);
# define nanosleep_not_cancel(requested_time, remaining) \
__nanosleep_nocancel (requested_time, remaining)
#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/xtensa/Makefile.arch b/libpthread/nptl/sysdeps/unix/sysv/linux/xtensa/Makefile.arch
index 6f1734871..a3719a3fb 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/xtensa/Makefile.arch
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/xtensa/Makefile.arch
@@ -9,3 +9,5 @@ CFLAGS-OMIT-fork.c = -DNOT_IN_libc -DIS_IN_libpthread
ASFLAGS-syscall.S = -D_LIBC_REENTRANT
ASFLAGS-mmap.S = -D_LIBC_REENTRANT
+
+ASFLAGS += -DUSE___THREAD
diff --git a/libpthread/nptl/sysdeps/x86_64/dl-tls.h b/libpthread/nptl/sysdeps/x86_64/dl-tls.h
index d6c338cda..5cac55f33 100644
--- a/libpthread/nptl/sysdeps/x86_64/dl-tls.h
+++ b/libpthread/nptl/sysdeps/x86_64/dl-tls.h
@@ -26,3 +26,6 @@ typedef struct
extern void *__tls_get_addr (tls_index *ti);
+
+/* Value used for dtv entries for which the allocation is delayed. */
+#define TLS_DTV_UNALLOCATED ((void *) -1l)
diff --git a/libpthread/nptl/sysdeps/xtensa/dl-tls.h b/libpthread/nptl/sysdeps/xtensa/dl-tls.h
index adc02d74a..dfc91753e 100644
--- a/libpthread/nptl/sysdeps/xtensa/dl-tls.h
+++ b/libpthread/nptl/sysdeps/xtensa/dl-tls.h
@@ -28,6 +28,29 @@ typedef struct
extern void *__tls_get_addr (tls_index *ti);
+/* Type used as the argument in a TLS descriptor for a symbol that
+ needs dynamic TLS offsets. */
+struct tlsdesc_dynamic_arg
+{
+ tls_index tlsinfo;
+ size_t gen_count;
+};
+
+#ifdef __FDPIC__
+/* Type used to represent a TLS descriptor. */
+struct tlsdesc
+{
+ ptrdiff_t (*entry)(struct tlsdesc *);
+ void *argument;
+};
+
+extern ptrdiff_t attribute_hidden
+ _dl_tlsdesc_return(struct tlsdesc *);
+
+extern void *_dl_make_tlsdesc_dynamic (struct link_map *map, size_t ti_offset);
+extern ptrdiff_t attribute_hidden
+ _dl_tlsdesc_dynamic(struct tlsdesc *);
+#else
/* Type used to represent a TLS descriptor. */
struct tlsdesc
{
@@ -39,19 +62,14 @@ struct tlsdesc
ptrdiff_t (*entry)(struct tlsdesc *);
};
-/* Type used as the argument in a TLS descriptor for a symbol that
- needs dynamic TLS offsets. */
-struct tlsdesc_dynamic_arg
-{
- tls_index tlsinfo;
- size_t gen_count;
-};
-
extern ptrdiff_t attribute_hidden
_dl_tlsdesc_return(struct tlsdesc_dynamic_arg *);
extern void *_dl_make_tlsdesc_dynamic (struct link_map *map, size_t ti_offset);
extern ptrdiff_t attribute_hidden
_dl_tlsdesc_dynamic(struct tlsdesc_dynamic_arg *);
-
#endif
+#endif
+
+/* Value used for dtv entries for which the allocation is delayed. */
+#define TLS_DTV_UNALLOCATED ((void *) -1l)
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: