From c7e1f55389c37091b7ac8b74a55719704a470d5a Mon Sep 17 00:00:00 2001 From: wanghongliang Date: Thu, 23 Jun 2022 11:50:12 +0800 Subject: [PATCH] glibc LoongArch Port. Signed-off-by: wanghongliang --- glibc-LoongArch-Port.patch | 16504 +++++++++++++++++++++++++++++++++++ glibc.spec | 2 + 2 files changed, 16506 insertions(+) create mode 100644 glibc-LoongArch-Port.patch diff --git a/glibc-LoongArch-Port.patch b/glibc-LoongArch-Port.patch new file mode 100644 index 0000000..ca00cdd --- /dev/null +++ b/glibc-LoongArch-Port.patch @@ -0,0 +1,16504 @@ +From b8f82ee8df870058d80a7a51bea14465235f06d5 Mon Sep 17 00:00:00 2001 +From: wanghongliang +Date: Thu, 23 Jun 2022 10:29:34 +0800 +Subject: [PATCH] glibc LoongArch Port. + +add LoongArch architecture support. + +Signed-off-by: wanghongliang +--- + README | 1 + + elf/elf.h | 84 + + scripts/config.sub | 7 +- + sysdeps/loongarch/Implies | 5 + + sysdeps/loongarch/Makefile | 32 + + sysdeps/loongarch/__longjmp.S | 50 + + sysdeps/loongarch/abort-instr.h | 2 + + sysdeps/loongarch/at_quick_exit.c | 1 + + sysdeps/loongarch/atexit.c | 1 + + sysdeps/loongarch/bits/endian.h | 9 + + sysdeps/loongarch/bits/fenv.h | 93 + + sysdeps/loongarch/bits/link.h | 56 + + sysdeps/loongarch/bits/setjmp.h | 39 + + sysdeps/loongarch/bits/wordsize.h | 22 + + sysdeps/loongarch/bsd-_setjmp.c | 1 + + sysdeps/loongarch/bsd-setjmp.c | 1 + + sysdeps/loongarch/configure | 4 + + sysdeps/loongarch/configure.ac | 6 + + sysdeps/loongarch/dl-irel.h | 51 + + sysdeps/loongarch/dl-machine.h | 366 +++ + sysdeps/loongarch/dl-tls.h | 49 + + sysdeps/loongarch/dl-trampoline.S | 108 + + sysdeps/loongarch/e_sqrtl.c | 39 + + sysdeps/loongarch/elf-init.c | 1 + + sysdeps/loongarch/fpu/e_sqrt.c | 29 + + sysdeps/loongarch/fpu/e_sqrtf.c | 28 + + sysdeps/loongarch/fpu/fclrexcpt.c | 47 + + sysdeps/loongarch/fpu/fedisblxcpt.c | 40 + + sysdeps/loongarch/fpu/feenablxcpt.c | 40 + + sysdeps/loongarch/fpu/fegetenv.c | 33 + + sysdeps/loongarch/fpu/fegetexcept.c | 33 + + sysdeps/loongarch/fpu/fegetmode.c | 27 + + sysdeps/loongarch/fpu/fegetround.c | 35 + + sysdeps/loongarch/fpu/feholdexcpt.c | 41 + + sysdeps/loongarch/fpu/fenv_libc.h | 31 + + sysdeps/loongarch/fpu/fesetenv.c | 44 + + sysdeps/loongarch/fpu/fesetexcept.c | 32 + + sysdeps/loongarch/fpu/fesetmode.c | 38 + + sysdeps/loongarch/fpu/fesetround.c | 46 + + sysdeps/loongarch/fpu/feupdateenv.c | 45 + + sysdeps/loongarch/fpu/fgetexcptflg.c | 39 + + sysdeps/loongarch/fpu/fraiseexcpt.c | 84 + + sysdeps/loongarch/fpu/fsetexcptflg.c | 42 + + sysdeps/loongarch/fpu/ftestexcept.c | 33 + + sysdeps/loongarch/fpu_control.h | 111 + + sysdeps/loongarch/fstat.c | 1 + + sysdeps/loongarch/fstat64.c | 1 + + sysdeps/loongarch/fstatat.c | 1 + + sysdeps/loongarch/fstatat64.c | 1 + + sysdeps/loongarch/gccframe.h | 21 + + sysdeps/loongarch/hp-timing.h | 40 + + sysdeps/loongarch/jmpbuf-offsets.h | 23 + + sysdeps/loongarch/jmpbuf-unwind.h | 46 + + sysdeps/loongarch/ldsodefs.h | 47 + + sysdeps/loongarch/libc-start.h | 25 + + sysdeps/loongarch/libc-tls.c | 32 + + sysdeps/loongarch/linkmap.h | 4 + + sysdeps/loongarch/lp64/Implies-after | 1 + + sysdeps/loongarch/lp64/libm-test-ulps | 2206 +++++++++++++++++ + sysdeps/loongarch/lp64/libm-test-ulps-name | 1 + + sysdeps/loongarch/lp64/memcpy.S | 402 +++ + sysdeps/loongarch/lp64/memmove.S | 476 ++++ + sysdeps/loongarch/lp64/memset.S | 175 ++ + sysdeps/loongarch/lp64/s_cosf.S | 409 +++ + sysdeps/loongarch/lp64/s_sinf.S | 392 +++ + sysdeps/loongarch/lp64/strchr.S | 140 ++ + sysdeps/loongarch/lp64/strchrnul.S | 156 ++ + sysdeps/loongarch/lp64/strcmp.S | 197 ++ + sysdeps/loongarch/lp64/strcpy.S | 210 ++ + sysdeps/loongarch/lp64/strlen.S | 135 + + sysdeps/loongarch/lp64/strncmp.S | 269 ++ + sysdeps/loongarch/lp64/strnlen.S | 155 ++ + sysdeps/loongarch/lstat.c | 1 + + sysdeps/loongarch/lstat64.c | 1 + + sysdeps/loongarch/machine-gmon.h | 37 + + sysdeps/loongarch/math_private.h | 245 ++ + sysdeps/loongarch/memusage.h | 21 + + sysdeps/loongarch/mknod.c | 1 + + sysdeps/loongarch/mknodat.c | 1 + + sysdeps/loongarch/nptl/Makefile | 26 + + .../loongarch/nptl/bits/pthreadtypes-arch.h | 68 + + sysdeps/loongarch/nptl/bits/semaphore.h | 33 + + sysdeps/loongarch/nptl/libc-lowlevellock.c | 8 + + sysdeps/loongarch/nptl/nptl-sysdep.S | 2 + + sysdeps/loongarch/nptl/pthread-offsets.h | 23 + + sysdeps/loongarch/nptl/pthreaddef.h | 32 + + sysdeps/loongarch/nptl/tcb-offsets.sym | 6 + + sysdeps/loongarch/nptl/tls.h | 147 ++ + sysdeps/loongarch/preconfigure | 9 + + sysdeps/loongarch/pthread_atfork.c | 1 + + sysdeps/loongarch/setjmp.S | 62 + + sysdeps/loongarch/sfp-machine.h | 79 + + sysdeps/loongarch/sotruss-lib.c | 51 + + sysdeps/loongarch/stack_chk_fail_local.c | 1 + + sysdeps/loongarch/stackinfo.h | 33 + + sysdeps/loongarch/start.S | 51 + + sysdeps/loongarch/stat.c | 1 + + sysdeps/loongarch/stat64.c | 1 + + sysdeps/loongarch/sys/asm.h | 49 + + sysdeps/loongarch/sys/regdef.h | 83 + + sysdeps/loongarch/tininess.h | 1 + + sysdeps/loongarch/tls-macros.h | 46 + + sysdeps/loongarch/tst-audit.h | 23 + + sysdeps/loongarch/warning-nop.c | 1 + + sysdeps/unix/sysv/linux/loongarch/Implies | 1 + + sysdeps/unix/sysv/linux/loongarch/Makefile | 17 + + sysdeps/unix/sysv/linux/loongarch/Versions | 44 + + .../sysv/linux/loongarch/atomic-machine.h | 188 ++ + .../unix/sysv/linux/loongarch/bits/fcntl.h | 62 + + .../sysv/linux/loongarch/bits/local_lim.h | 99 + + sysdeps/unix/sysv/linux/loongarch/bits/mman.h | 41 + + sysdeps/unix/sysv/linux/loongarch/bits/shm.h | 112 + + .../sysv/linux/loongarch/bits/sigcontext.h | 47 + + .../unix/sysv/linux/loongarch/bits/signum.h | 58 + + sysdeps/unix/sysv/linux/loongarch/clone.S | 98 + + sysdeps/unix/sysv/linux/loongarch/configure | 199 ++ + .../unix/sysv/linux/loongarch/configure.ac | 27 + + sysdeps/unix/sysv/linux/loongarch/dl-static.c | 84 + + .../unix/sysv/linux/loongarch/getcontext.S | 72 + + sysdeps/unix/sysv/linux/loongarch/getpid.c | 54 + + .../unix/sysv/linux/loongarch/gettimeofday.c | 58 + + sysdeps/unix/sysv/linux/loongarch/getuid.c | 60 + + .../unix/sysv/linux/loongarch/init-first.c | 57 + + sysdeps/unix/sysv/linux/loongarch/ipc_priv.h | 21 + + .../sysv/linux/loongarch/kernel-features.h | 24 + + .../unix/sysv/linux/loongarch/ldd-rewrite.sed | 1 + + sysdeps/unix/sysv/linux/loongarch/ldsodefs.h | 32 + + sysdeps/unix/sysv/linux/loongarch/libc-vdso.h | 37 + + .../unix/sysv/linux/loongarch/localplt.data | 13 + + .../unix/sysv/linux/loongarch/lp64/Implies | 3 + + .../sysv/linux/loongarch/lp64/c++-types.data | 67 + + .../linux/loongarch/lp64/jmp_buf-macros.h | 41 + + .../unix/sysv/linux/loongarch/lp64/ld.abilist | 5 + + .../loongarch/lp64/libBrokenLocale.abilist | 1 + + .../sysv/linux/loongarch/lp64/libanl.abilist | 4 + + .../sysv/linux/loongarch/lp64/libc.abilist | 2101 ++++++++++++++++ + .../linux/loongarch/lp64/libcrypt.abilist | 7 + + .../sysv/linux/loongarch/lp64/libdl.abilist | 9 + + .../sysv/linux/loongarch/lp64/libm.abilist | 1021 ++++++++ + .../sysv/linux/loongarch/lp64/libnsl.abilist | 120 + + .../linux/loongarch/lp64/libpthread.abilist | 264 ++ + .../linux/loongarch/lp64/libresolv.abilist | 79 + + .../sysv/linux/loongarch/lp64/librt.abilist | 35 + + .../linux/loongarch/lp64/libthread_db.abilist | 40 + + .../sysv/linux/loongarch/lp64/libutil.abilist | 6 + + .../unix/sysv/linux/loongarch/makecontext.c | 78 + + .../sysv/linux/loongarch/profil-counter.h | 31 + + sysdeps/unix/sysv/linux/loongarch/pt-vfork.S | 1 + + .../unix/sysv/linux/loongarch/register-dump.h | 63 + + .../unix/sysv/linux/loongarch/setcontext.S | 111 + + .../unix/sysv/linux/loongarch/shlib-versions | 2 + + .../sysv/linux/loongarch/sigcontextinfo.h | 22 + + .../unix/sysv/linux/loongarch/swapcontext.S | 120 + + .../unix/sysv/linux/loongarch/sys/procfs.h | 122 + + .../unix/sysv/linux/loongarch/sys/ucontext.h | 81 + + sysdeps/unix/sysv/linux/loongarch/sys/user.h | 31 + + sysdeps/unix/sysv/linux/loongarch/syscall.c | 36 + + sysdeps/unix/sysv/linux/loongarch/sysdep.S | 52 + + sysdeps/unix/sysv/linux/loongarch/sysdep.h | 333 +++ + .../sysv/linux/loongarch/ucontext-macros.h | 44 + + .../unix/sysv/linux/loongarch/ucontext_i.sym | 33 + + sysdeps/unix/sysv/linux/loongarch/vfork.S | 49 + + 162 files changed, 15153 insertions(+), 1 deletion(-) + create mode 100644 sysdeps/loongarch/Implies + create mode 100644 sysdeps/loongarch/Makefile + create mode 100644 sysdeps/loongarch/__longjmp.S + create mode 100644 sysdeps/loongarch/abort-instr.h + create mode 100644 sysdeps/loongarch/at_quick_exit.c + create mode 100644 sysdeps/loongarch/atexit.c + create mode 100644 sysdeps/loongarch/bits/endian.h + create mode 100644 sysdeps/loongarch/bits/fenv.h + create mode 100644 sysdeps/loongarch/bits/link.h + create mode 100644 sysdeps/loongarch/bits/setjmp.h + create mode 100644 sysdeps/loongarch/bits/wordsize.h + create mode 100644 sysdeps/loongarch/bsd-_setjmp.c + create mode 100644 sysdeps/loongarch/bsd-setjmp.c + create mode 100755 sysdeps/loongarch/configure + create mode 100644 sysdeps/loongarch/configure.ac + create mode 100644 sysdeps/loongarch/dl-irel.h + create mode 100644 sysdeps/loongarch/dl-machine.h + create mode 100644 sysdeps/loongarch/dl-tls.h + create mode 100644 sysdeps/loongarch/dl-trampoline.S + create mode 100644 sysdeps/loongarch/e_sqrtl.c + create mode 100644 sysdeps/loongarch/elf-init.c + create mode 100644 sysdeps/loongarch/fpu/e_sqrt.c + create mode 100644 sysdeps/loongarch/fpu/e_sqrtf.c + create mode 100644 sysdeps/loongarch/fpu/fclrexcpt.c + create mode 100644 sysdeps/loongarch/fpu/fedisblxcpt.c + create mode 100644 sysdeps/loongarch/fpu/feenablxcpt.c + create mode 100644 sysdeps/loongarch/fpu/fegetenv.c + create mode 100644 sysdeps/loongarch/fpu/fegetexcept.c + create mode 100644 sysdeps/loongarch/fpu/fegetmode.c + create mode 100644 sysdeps/loongarch/fpu/fegetround.c + create mode 100644 sysdeps/loongarch/fpu/feholdexcpt.c + create mode 100644 sysdeps/loongarch/fpu/fenv_libc.h + create mode 100644 sysdeps/loongarch/fpu/fesetenv.c + create mode 100644 sysdeps/loongarch/fpu/fesetexcept.c + create mode 100644 sysdeps/loongarch/fpu/fesetmode.c + create mode 100644 sysdeps/loongarch/fpu/fesetround.c + create mode 100644 sysdeps/loongarch/fpu/feupdateenv.c + create mode 100644 sysdeps/loongarch/fpu/fgetexcptflg.c + create mode 100644 sysdeps/loongarch/fpu/fraiseexcpt.c + create mode 100644 sysdeps/loongarch/fpu/fsetexcptflg.c + create mode 100644 sysdeps/loongarch/fpu/ftestexcept.c + create mode 100644 sysdeps/loongarch/fpu_control.h + create mode 100644 sysdeps/loongarch/fstat.c + create mode 100644 sysdeps/loongarch/fstat64.c + create mode 100644 sysdeps/loongarch/fstatat.c + create mode 100644 sysdeps/loongarch/fstatat64.c + create mode 100644 sysdeps/loongarch/gccframe.h + create mode 100644 sysdeps/loongarch/hp-timing.h + create mode 100644 sysdeps/loongarch/jmpbuf-offsets.h + create mode 100644 sysdeps/loongarch/jmpbuf-unwind.h + create mode 100644 sysdeps/loongarch/ldsodefs.h + create mode 100644 sysdeps/loongarch/libc-start.h + create mode 100644 sysdeps/loongarch/libc-tls.c + create mode 100644 sysdeps/loongarch/linkmap.h + create mode 100644 sysdeps/loongarch/lp64/Implies-after + create mode 100644 sysdeps/loongarch/lp64/libm-test-ulps + create mode 100644 sysdeps/loongarch/lp64/libm-test-ulps-name + create mode 100644 sysdeps/loongarch/lp64/memcpy.S + create mode 100644 sysdeps/loongarch/lp64/memmove.S + create mode 100644 sysdeps/loongarch/lp64/memset.S + create mode 100644 sysdeps/loongarch/lp64/s_cosf.S + create mode 100644 sysdeps/loongarch/lp64/s_sinf.S + create mode 100644 sysdeps/loongarch/lp64/strchr.S + create mode 100644 sysdeps/loongarch/lp64/strchrnul.S + create mode 100644 sysdeps/loongarch/lp64/strcmp.S + create mode 100644 sysdeps/loongarch/lp64/strcpy.S + create mode 100644 sysdeps/loongarch/lp64/strlen.S + create mode 100644 sysdeps/loongarch/lp64/strncmp.S + create mode 100644 sysdeps/loongarch/lp64/strnlen.S + create mode 100644 sysdeps/loongarch/lstat.c + create mode 100644 sysdeps/loongarch/lstat64.c + create mode 100644 sysdeps/loongarch/machine-gmon.h + create mode 100644 sysdeps/loongarch/math_private.h + create mode 100644 sysdeps/loongarch/memusage.h + create mode 100644 sysdeps/loongarch/mknod.c + create mode 100644 sysdeps/loongarch/mknodat.c + create mode 100644 sysdeps/loongarch/nptl/Makefile + create mode 100644 sysdeps/loongarch/nptl/bits/pthreadtypes-arch.h + create mode 100644 sysdeps/loongarch/nptl/bits/semaphore.h + create mode 100644 sysdeps/loongarch/nptl/libc-lowlevellock.c + create mode 100644 sysdeps/loongarch/nptl/nptl-sysdep.S + create mode 100644 sysdeps/loongarch/nptl/pthread-offsets.h + create mode 100644 sysdeps/loongarch/nptl/pthreaddef.h + create mode 100644 sysdeps/loongarch/nptl/tcb-offsets.sym + create mode 100644 sysdeps/loongarch/nptl/tls.h + create mode 100644 sysdeps/loongarch/preconfigure + create mode 100644 sysdeps/loongarch/pthread_atfork.c + create mode 100644 sysdeps/loongarch/setjmp.S + create mode 100644 sysdeps/loongarch/sfp-machine.h + create mode 100644 sysdeps/loongarch/sotruss-lib.c + create mode 100644 sysdeps/loongarch/stack_chk_fail_local.c + create mode 100644 sysdeps/loongarch/stackinfo.h + create mode 100644 sysdeps/loongarch/start.S + create mode 100644 sysdeps/loongarch/stat.c + create mode 100644 sysdeps/loongarch/stat64.c + create mode 100644 sysdeps/loongarch/sys/asm.h + create mode 100644 sysdeps/loongarch/sys/regdef.h + create mode 100644 sysdeps/loongarch/tininess.h + create mode 100644 sysdeps/loongarch/tls-macros.h + create mode 100644 sysdeps/loongarch/tst-audit.h + create mode 100644 sysdeps/loongarch/warning-nop.c + create mode 100644 sysdeps/unix/sysv/linux/loongarch/Implies + create mode 100644 sysdeps/unix/sysv/linux/loongarch/Makefile + create mode 100644 sysdeps/unix/sysv/linux/loongarch/Versions + create mode 100644 sysdeps/unix/sysv/linux/loongarch/atomic-machine.h + create mode 100644 sysdeps/unix/sysv/linux/loongarch/bits/fcntl.h + create mode 100644 sysdeps/unix/sysv/linux/loongarch/bits/local_lim.h + create mode 100644 sysdeps/unix/sysv/linux/loongarch/bits/mman.h + create mode 100644 sysdeps/unix/sysv/linux/loongarch/bits/shm.h + create mode 100644 sysdeps/unix/sysv/linux/loongarch/bits/sigcontext.h + create mode 100644 sysdeps/unix/sysv/linux/loongarch/bits/signum.h + create mode 100644 sysdeps/unix/sysv/linux/loongarch/clone.S + create mode 100644 sysdeps/unix/sysv/linux/loongarch/configure + create mode 100644 sysdeps/unix/sysv/linux/loongarch/configure.ac + create mode 100644 sysdeps/unix/sysv/linux/loongarch/dl-static.c + create mode 100644 sysdeps/unix/sysv/linux/loongarch/getcontext.S + create mode 100644 sysdeps/unix/sysv/linux/loongarch/getpid.c + create mode 100644 sysdeps/unix/sysv/linux/loongarch/gettimeofday.c + create mode 100644 sysdeps/unix/sysv/linux/loongarch/getuid.c + create mode 100644 sysdeps/unix/sysv/linux/loongarch/init-first.c + create mode 100644 sysdeps/unix/sysv/linux/loongarch/ipc_priv.h + create mode 100644 sysdeps/unix/sysv/linux/loongarch/kernel-features.h + create mode 100644 sysdeps/unix/sysv/linux/loongarch/ldd-rewrite.sed + create mode 100644 sysdeps/unix/sysv/linux/loongarch/ldsodefs.h + create mode 100644 sysdeps/unix/sysv/linux/loongarch/libc-vdso.h + create mode 100644 sysdeps/unix/sysv/linux/loongarch/localplt.data + create mode 100644 sysdeps/unix/sysv/linux/loongarch/lp64/Implies + create mode 100644 sysdeps/unix/sysv/linux/loongarch/lp64/c++-types.data + create mode 100644 sysdeps/unix/sysv/linux/loongarch/lp64/jmp_buf-macros.h + create mode 100644 sysdeps/unix/sysv/linux/loongarch/lp64/ld.abilist + create mode 100644 sysdeps/unix/sysv/linux/loongarch/lp64/libBrokenLocale.abilist + create mode 100644 sysdeps/unix/sysv/linux/loongarch/lp64/libanl.abilist + create mode 100644 sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist + create mode 100644 sysdeps/unix/sysv/linux/loongarch/lp64/libcrypt.abilist + create mode 100644 sysdeps/unix/sysv/linux/loongarch/lp64/libdl.abilist + create mode 100644 sysdeps/unix/sysv/linux/loongarch/lp64/libm.abilist + create mode 100644 sysdeps/unix/sysv/linux/loongarch/lp64/libnsl.abilist + create mode 100644 sysdeps/unix/sysv/linux/loongarch/lp64/libpthread.abilist + create mode 100644 sysdeps/unix/sysv/linux/loongarch/lp64/libresolv.abilist + create mode 100644 sysdeps/unix/sysv/linux/loongarch/lp64/librt.abilist + create mode 100644 sysdeps/unix/sysv/linux/loongarch/lp64/libthread_db.abilist + create mode 100644 sysdeps/unix/sysv/linux/loongarch/lp64/libutil.abilist + create mode 100644 sysdeps/unix/sysv/linux/loongarch/makecontext.c + create mode 100644 sysdeps/unix/sysv/linux/loongarch/profil-counter.h + create mode 100644 sysdeps/unix/sysv/linux/loongarch/pt-vfork.S + create mode 100644 sysdeps/unix/sysv/linux/loongarch/register-dump.h + create mode 100644 sysdeps/unix/sysv/linux/loongarch/setcontext.S + create mode 100644 sysdeps/unix/sysv/linux/loongarch/shlib-versions + create mode 100644 sysdeps/unix/sysv/linux/loongarch/sigcontextinfo.h + create mode 100644 sysdeps/unix/sysv/linux/loongarch/swapcontext.S + create mode 100644 sysdeps/unix/sysv/linux/loongarch/sys/procfs.h + create mode 100644 sysdeps/unix/sysv/linux/loongarch/sys/ucontext.h + create mode 100644 sysdeps/unix/sysv/linux/loongarch/sys/user.h + create mode 100644 sysdeps/unix/sysv/linux/loongarch/syscall.c + create mode 100644 sysdeps/unix/sysv/linux/loongarch/sysdep.S + create mode 100644 sysdeps/unix/sysv/linux/loongarch/sysdep.h + create mode 100644 sysdeps/unix/sysv/linux/loongarch/ucontext-macros.h + create mode 100644 sysdeps/unix/sysv/linux/loongarch/ucontext_i.sym + create mode 100644 sysdeps/unix/sysv/linux/loongarch/vfork.S + +diff --git a/README b/README +index 27a9fd47..1b5e147d 100644 +--- a/README ++++ b/README +@@ -41,6 +41,7 @@ The GNU C Library supports these configurations for using Linux kernels: + sh[34]-*-linux-gnu + sparc*-*-linux-gnu + sparc64*-*-linux-gnu ++ loongarch64-*-linux-gnu + + If you are interested in doing a port, please contact the glibc + maintainers; see http://www.gnu.org/software/libc/ for more +diff --git a/elf/elf.h b/elf/elf.h +index d6506ea1..0dc58b6d 100644 +--- a/elf/elf.h ++++ b/elf/elf.h +@@ -360,6 +360,7 @@ typedef struct + #define EM_RISCV 243 /* RISC-V */ + + #define EM_BPF 247 /* Linux BPF -- in-kernel virtual machine */ ++#define EM_LOONGARCH 258 /* Loongson Loongarch */ + + #define EM_NUM 248 + +@@ -3935,6 +3936,89 @@ enum + #define R_NDS32_TLS_TPOFF 102 + #define R_NDS32_TLS_DESC 119 + ++/* LoongISA ELF Flags */ ++#define EF_LARCH_ABI 0x0003 ++#define EF_LARCH_ABI_LP64 0x0003 ++#define EF_LARCH_ABI_LPX32 0x0002 ++#define EF_LARCH_ABI_LP32 0x0001 ++ ++/* Loongarch specific dynamic relocations. */ ++#define R_LARCH_NONE 0 ++#define R_LARCH_32 1 ++#define R_LARCH_64 2 ++#define R_LARCH_RELATIVE 3 ++#define R_LARCH_COPY 4 ++#define R_LARCH_JUMP_SLOT 5 ++#define R_LARCH_TLS_DTPMOD32 6 ++#define R_LARCH_TLS_DTPMOD64 7 ++#define R_LARCH_TLS_DTPREL32 8 ++#define R_LARCH_TLS_DTPREL64 9 ++#define R_LARCH_TLS_TPREL32 10 ++#define R_LARCH_TLS_TPREL64 11 ++#define R_LARCH_IRELATIVE 12 ++ ++/* Reserved for future relocs that the dynamic linker must understand. */ ++ ++/* used by the static linker for relocating .text */ ++#define R_LARCH_MARK_LA 20 ++#define R_LARCH_MARK_PCREL 21 ++ ++/* 这个重定位类型将symbol距离重定位位置的pc相对位置偏移量压栈。 ++ 它against symbol,因为如果是个常数,虽然在no-pic的情况下可以得到结果,但因为 ++ 重定位位置相对这个常数的偏移量一定很大,八成填不进去;而在pic的情况下, ++ 偏移量无法在静态连接时确定。因此我们约定这个重定位不可能against constant */ ++#define R_LARCH_SOP_PUSH_PCREL 22 ++ ++/* 这个重定位against a symbol or a constant。它将symbol的运行时绝对地址 ++ 或常数压栈,因此在pic的情况下会报错。另外我不太清楚常数和ABS段的关系。 */ ++#define R_LARCH_SOP_PUSH_ABSOLUTE 23 ++#define R_LARCH_SOP_PUSH_DUP 24 ++#define R_LARCH_SOP_PUSH_GPREL 25 ++#define R_LARCH_SOP_PUSH_TLS_TPREL 26 ++#define R_LARCH_SOP_PUSH_TLS_GOT 27 ++#define R_LARCH_SOP_PUSH_TLS_GD 28 ++#define R_LARCH_SOP_PUSH_PLT_PCREL 29 ++ ++#define R_LARCH_SOP_ASSERT 30 ++#define R_LARCH_SOP_NOT 31 ++#define R_LARCH_SOP_SUB 32 ++#define R_LARCH_SOP_SL 33 ++#define R_LARCH_SOP_SR 34 ++#define R_LARCH_SOP_ADD 35 ++#define R_LARCH_SOP_AND 36 ++#define R_LARCH_SOP_IF_ELSE 37 ++#define R_LARCH_SOP_POP_32_S_10_5 38 ++#define R_LARCH_SOP_POP_32_U_10_12 39 ++#define R_LARCH_SOP_POP_32_S_10_12 40 ++#define R_LARCH_SOP_POP_32_S_10_16 41 ++#define R_LARCH_SOP_POP_32_S_10_16_S2 42 ++#define R_LARCH_SOP_POP_32_S_5_20 43 ++#define R_LARCH_SOP_POP_32_S_0_5_10_16_S2 44 ++#define R_LARCH_SOP_POP_32_S_0_10_10_16_S2 45 ++#define R_LARCH_SOP_POP_32_U 46 ++ ++/* used by the static linker for relocating non .text */ ++/* 这几个重定位类型是为了照顾到 ".dword sym1 - sym2" 这种求差的写法。 ++ 这些重定位类型处理的是连接时地址,一般情况下它们是成对出现的。 ++ 在直接求负数".dword - sym1"的情况下,R_LARCH_SUBxx会单独出现。但注意, ++ 那个位置填进去的是连接时地址。 */ ++#define R_LARCH_ADD8 47 ++#define R_LARCH_ADD16 48 ++#define R_LARCH_ADD24 49 ++#define R_LARCH_ADD32 50 ++#define R_LARCH_ADD64 51 ++#define R_LARCH_SUB8 52 ++#define R_LARCH_SUB16 53 ++#define R_LARCH_SUB24 54 ++#define R_LARCH_SUB32 55 ++#define R_LARCH_SUB64 56 ++ ++ /* I don't know what it is. Existing in almost all other arch */ ++#define R_LARCH_GNU_VTINHERIT 57 ++#define R_LARCH_GNU_VTENTRY 58 ++ ++ ++ + __END_DECLS + + #endif /* elf.h */ +diff --git a/scripts/config.sub b/scripts/config.sub +index f2632cd8..34e9313f 100755 +--- a/scripts/config.sub ++++ b/scripts/config.sub +@@ -142,7 +142,7 @@ case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; +- -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ ++ -dec* | -mips* | -loongarch* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ +@@ -288,6 +288,7 @@ case $basic_machine in + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ ++ | loongarch | loongarch64 \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ +@@ -415,6 +416,7 @@ case $basic_machine in + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipsr5900-* | mipsr5900el-* \ + | mipstx39-* | mipstx39el-* \ ++ | loongarch-* | loongarch64-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ +@@ -1339,6 +1341,9 @@ case $basic_machine in + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; ++ loongarch) ++ basic_machine=loongarch-loongson ++ ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; +diff --git a/sysdeps/loongarch/Implies b/sysdeps/loongarch/Implies +new file mode 100644 +index 00000000..c88325b8 +--- /dev/null ++++ b/sysdeps/loongarch/Implies +@@ -0,0 +1,5 @@ ++init_array ++ ++ieee754/ldbl-128 ++ieee754/dbl-64 ++ieee754/flt-32 +diff --git a/sysdeps/loongarch/Makefile b/sysdeps/loongarch/Makefile +new file mode 100644 +index 00000000..d5801b3c +--- /dev/null ++++ b/sysdeps/loongarch/Makefile +@@ -0,0 +1,32 @@ ++ifeq ($(subdir),misc) ++sysdep_headers += sys/asm.h ++endif ++ ++# LoongArch's assembler also needs to know about PIC as it changes the definition ++# of some assembler macros. ++ASFLAGS-.os += $(pic-ccflag) ++CFLAGS-elf-init.oS += -mcmodel=large ++CFLAGS-atexit.oS += -mcmodel=large ++CFLAGS-at_quick_exit.oS += -mcmodel=large ++CFLAGS-stat.oS += -mcmodel=large ++CFLAGS-fstat.oS += -mcmodel=large ++CFLAGS-lstat.oS += -mcmodel=large ++CFLAGS-stat64.oS += -mcmodel=large ++CFLAGS-fstat64.oS += -mcmodel=large ++CFLAGS-lstat64.oS += -mcmodel=large ++CFLAGS-fstatat.oS += -mcmodel=large ++CFLAGS-fstatat64.oS += -mcmodel=large ++CFLAGS-mknod.oS += -mcmodel=large ++CFLAGS-mknodat.oS += -mcmodel=large ++CFLAGS-pthread_atfork.oS += -mcmodel=large ++CFLAGS-warning-nop.oS += -mcmodel=large ++CFLAGS-stack_chk_fail_local.oS += -mcmodel=large ++ ++abi-variants := lp32 lp64 ++ ++ifeq (,$(filter $(default-abi),$(abi-variants))) ++$(error Unknown ABI $(default-abi), must be one of $(abi-variants)) ++endif ++ ++abi-lp64-condition := defined _ABILP64 ++abi-lp32-condition := defined _ABILP32 +diff --git a/sysdeps/loongarch/__longjmp.S b/sysdeps/loongarch/__longjmp.S +new file mode 100644 +index 00000000..68f67639 +--- /dev/null ++++ b/sysdeps/loongarch/__longjmp.S +@@ -0,0 +1,50 @@ ++/* Copyright (C) 2020-2021 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 ++ . */ ++ ++#include ++#include ++ ++ENTRY (__longjmp) ++ REG_L ra, a0, 0*SZREG ++ REG_L sp, a0, 1*SZREG ++ REG_L x, a0, 2*SZREG ++ REG_L fp, a0, 3*SZREG ++ REG_L s0, a0, 4*SZREG ++ REG_L s1, a0, 5*SZREG ++ REG_L s2, a0, 6*SZREG ++ REG_L s3, a0, 7*SZREG ++ REG_L s4, a0, 8*SZREG ++ REG_L s5, a0, 9*SZREG ++ REG_L s6, a0, 10*SZREG ++ REG_L s7, a0, 11*SZREG ++ REG_L s8, a0, 12*SZREG ++ ++ FREG_L $f24, a0, 13*SZREG + 0*SZFREG ++ FREG_L $f25, a0, 13*SZREG + 1*SZFREG ++ FREG_L $f26, a0, 13*SZREG + 2*SZFREG ++ FREG_L $f27, a0, 13*SZREG + 3*SZFREG ++ FREG_L $f28, a0, 13*SZREG + 4*SZFREG ++ FREG_L $f29, a0, 13*SZREG + 5*SZFREG ++ FREG_L $f30, a0, 13*SZREG + 6*SZFREG ++ FREG_L $f31, a0, 13*SZREG + 7*SZFREG ++ ++ sltui a0,a1,1 ++ add.d a0, a0, a1 # a0 = (a1 == 0) ? 1 : a1 ++ jirl zero,ra,0 ++ ++END (__longjmp) +diff --git a/sysdeps/loongarch/abort-instr.h b/sysdeps/loongarch/abort-instr.h +new file mode 100644 +index 00000000..46d3ad08 +--- /dev/null ++++ b/sysdeps/loongarch/abort-instr.h +@@ -0,0 +1,2 @@ ++/* An instruction which should crash any program is a breakpoint. */ ++#define ABORT_INSTRUCTION asm ("break 0") +diff --git a/sysdeps/loongarch/at_quick_exit.c b/sysdeps/loongarch/at_quick_exit.c +new file mode 100644 +index 00000000..8d4b44a7 +--- /dev/null ++++ b/sysdeps/loongarch/at_quick_exit.c +@@ -0,0 +1 @@ ++#include +diff --git a/sysdeps/loongarch/atexit.c b/sysdeps/loongarch/atexit.c +new file mode 100644 +index 00000000..fc055a48 +--- /dev/null ++++ b/sysdeps/loongarch/atexit.c +@@ -0,0 +1 @@ ++#include +diff --git a/sysdeps/loongarch/bits/endian.h b/sysdeps/loongarch/bits/endian.h +new file mode 100644 +index 00000000..dc9a3f2e +--- /dev/null ++++ b/sysdeps/loongarch/bits/endian.h +@@ -0,0 +1,9 @@ ++/* The MIPS architecture has selectable endianness. ++ It exists in both little and big endian flavours and we ++ want to be able to share the installed header files between ++ both, so we define __BYTE_ORDER based on GCC's predefines. */ ++ ++#ifndef _ENDIAN_H ++# error "Never use directly; include instead." ++#endif ++# define __BYTE_ORDER __LITTLE_ENDIAN +diff --git a/sysdeps/loongarch/bits/fenv.h b/sysdeps/loongarch/bits/fenv.h +new file mode 100644 +index 00000000..42767412 +--- /dev/null ++++ b/sysdeps/loongarch/bits/fenv.h +@@ -0,0 +1,93 @@ ++/* Copyright (C) 1998-2018 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 ++ . */ ++ ++#ifndef _FENV_H ++# error "Never use directly; include instead." ++#endif ++ ++ ++/* Define bits representing the exception. We use the bit positions ++ of the appropriate bits in the FPU control word. */ ++enum ++ { ++ FE_INEXACT = ++#define FE_INEXACT 0x010000 ++ FE_INEXACT, ++ FE_UNDERFLOW = ++#define FE_UNDERFLOW 0x020000 ++ FE_UNDERFLOW, ++ FE_OVERFLOW = ++#define FE_OVERFLOW 0x040000 ++ FE_OVERFLOW, ++ FE_DIVBYZERO = ++#define FE_DIVBYZERO 0x080000 ++ FE_DIVBYZERO, ++ FE_INVALID = ++#define FE_INVALID 0x100000 ++ FE_INVALID, ++ }; ++ ++#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 ++ use again the bit positions in the FPU control word as the values ++ for the appropriate macros. */ ++enum ++ { ++ FE_TONEAREST = ++#define FE_TONEAREST 0x000 ++ FE_TONEAREST, ++ FE_TOWARDZERO = ++#define FE_TOWARDZERO 0x100 ++ FE_TOWARDZERO, ++ FE_UPWARD = ++#define FE_UPWARD 0x200 ++ FE_UPWARD, ++ FE_DOWNWARD = ++#define FE_DOWNWARD 0x300 ++ FE_DOWNWARD ++ }; ++ ++ ++/* Type representing exception flags. */ ++typedef unsigned int fexcept_t; ++ ++ ++/* Type representing floating-point environment. This function corresponds ++ to the layout of the block written by the `fstenv'. */ ++typedef struct ++ { ++ unsigned int __fp_control_register; ++ } ++fenv_t; ++ ++/* If the default argument is used we use this value. */ ++#define FE_DFL_ENV ((const fenv_t *) -1) ++ ++#ifdef __USE_GNU ++/* Floating-point environment where none of the exception is masked. */ ++# define FE_NOMASK_ENV ((const fenv_t *) -257) ++#endif ++ ++#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/sysdeps/loongarch/bits/link.h b/sysdeps/loongarch/bits/link.h +new file mode 100644 +index 00000000..554dfdc0 +--- /dev/null ++++ b/sysdeps/loongarch/bits/link.h +@@ -0,0 +1,56 @@ ++/* Copyright (C) 2020-2021 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 ++ . */ ++ ++#ifndef _LINK_H ++# error "Never include directly; use instead." ++#endif ++ ++typedef struct La_loongarch_regs ++{ ++ unsigned long int lr_reg[8]; /* a0 - a7 */ ++ double lr_fpreg[8]; /* fa0 - fa7 */ ++ unsigned long int lr_ra; ++ unsigned long int lr_sp; ++} La_loongarch_regs; ++ ++/* Return values for calls from PLT on LoongArch. */ ++typedef struct La_loongarch_retval ++{ ++ unsigned long int lrv_a0; ++ unsigned long int lrv_a1; ++ double lrv_fa0; ++ double lrv_fa1; ++} La_loongarch_retval; ++ ++__BEGIN_DECLS ++ ++extern ElfW(Addr) la_loongarch_gnu_pltenter (ElfW(Sym) *__sym, unsigned int __ndx, ++ uintptr_t *__refcook, ++ uintptr_t *__defcook, ++ La_loongarch_regs *__regs, ++ unsigned int *__flags, ++ const char *__symname, ++ long int *__framesizep); ++extern unsigned int la_loongarch_gnu_pltexit (ElfW(Sym) *__sym, unsigned int __ndx, ++ uintptr_t *__refcook, ++ uintptr_t *__defcook, ++ const La_loongarch_regs *__inregs, ++ La_loongarch_retval *__outregs, ++ const char *__symname); ++ ++__END_DECLS +diff --git a/sysdeps/loongarch/bits/setjmp.h b/sysdeps/loongarch/bits/setjmp.h +new file mode 100644 +index 00000000..cc9b6bfd +--- /dev/null ++++ b/sysdeps/loongarch/bits/setjmp.h +@@ -0,0 +1,39 @@ ++/* Copyright (C) 2020-2021 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 ++ . */ ++ ++#ifndef _LOONGARCH_BITS_SETJMP_H ++#define _LOONGARCH_BITS_SETJMP_H ++ ++typedef struct __jmp_buf_internal_tag ++ { ++ /* Program counter. */ ++ long int __pc; ++ /* Stack pointer. */ ++ long int __sp; ++ /* Reserved */ ++ long int __x; ++ /* Frame pointer. */ ++ long int __fp; ++ /* Callee-saved registers. */ ++ long int __regs[9]; ++ ++ /* Callee-saved floating point registers. */ ++ double __fpregs[8]; ++ } __jmp_buf[1]; ++ ++#endif /* _LOONGARCH_BITS_SETJMP_H */ +diff --git a/sysdeps/loongarch/bits/wordsize.h b/sysdeps/loongarch/bits/wordsize.h +new file mode 100644 +index 00000000..8dbaa00d +--- /dev/null ++++ b/sysdeps/loongarch/bits/wordsize.h +@@ -0,0 +1,22 @@ ++/* Copyright (C) 1999-2018 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 ++ . */ ++ ++#define __loongarch_xlen 64 ++ ++#define __WORDSIZE __loongarch_xlen ++#define __WORDSIZE_TIME64_COMPAT32 0 ++ +diff --git a/sysdeps/loongarch/bsd-_setjmp.c b/sysdeps/loongarch/bsd-_setjmp.c +new file mode 100644 +index 00000000..0d413101 +--- /dev/null ++++ b/sysdeps/loongarch/bsd-_setjmp.c +@@ -0,0 +1 @@ ++/* _setjmp is implemented in setjmp.S */ +diff --git a/sysdeps/loongarch/bsd-setjmp.c b/sysdeps/loongarch/bsd-setjmp.c +new file mode 100644 +index 00000000..ee7c5e34 +--- /dev/null ++++ b/sysdeps/loongarch/bsd-setjmp.c +@@ -0,0 +1 @@ ++/* setjmp is implemented in setjmp.S */ +diff --git a/sysdeps/loongarch/configure b/sysdeps/loongarch/configure +new file mode 100755 +index 00000000..1e5abf81 +--- /dev/null ++++ b/sysdeps/loongarch/configure +@@ -0,0 +1,4 @@ ++# This file is generated from configure.ac by Autoconf. DO NOT EDIT! ++ # Local configure fragment for sysdeps/loongarch/elf. ++ ++#AC_DEFINE(PI_STATIC_AND_HIDDEN) +diff --git a/sysdeps/loongarch/configure.ac b/sysdeps/loongarch/configure.ac +new file mode 100644 +index 00000000..67b46ce0 +--- /dev/null ++++ b/sysdeps/loongarch/configure.ac +@@ -0,0 +1,6 @@ ++GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. ++# Local configure fragment for sysdeps/loongarch/elf. ++ ++dnl It is always possible to access static and hidden symbols in an ++dnl position independent way. ++#AC_DEFINE(PI_STATIC_AND_HIDDEN) +diff --git a/sysdeps/loongarch/dl-irel.h b/sysdeps/loongarch/dl-irel.h +new file mode 100644 +index 00000000..4216fec2 +--- /dev/null ++++ b/sysdeps/loongarch/dl-irel.h +@@ -0,0 +1,51 @@ ++/* Machine-dependent ELF indirect relocation inline functions. ++ x86-64 version. ++ Copyright (C) 2009-2018 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 ++ . */ ++ ++#ifndef _DL_IREL_H ++#define _DL_IREL_H ++ ++#include ++#include ++ ++#define ELF_MACHINE_IRELA 1 ++ ++static inline ElfW(Addr) ++__attribute ((always_inline)) ++elf_ifunc_invoke (ElfW(Addr) addr) ++{ ++ return ((ElfW(Addr) (*) (void)) (addr)) (); ++} ++ ++static inline void ++__attribute ((always_inline)) ++elf_irela (const ElfW(Rela) *reloc) ++{ ++ ElfW(Addr) *const reloc_addr = (void *) reloc->r_offset; ++ const unsigned long int r_type = ELFW(R_TYPE) (reloc->r_info); ++ ++ if (__glibc_likely (r_type == R_LARCH_IRELATIVE)) ++ { ++ ElfW(Addr) value = elf_ifunc_invoke(reloc->r_addend); ++ *reloc_addr = value; ++ } ++ else ++ __libc_fatal ("Unexpected reloc type in static binary.\n"); ++} ++ ++#endif /* dl-irel.h */ +diff --git a/sysdeps/loongarch/dl-machine.h b/sysdeps/loongarch/dl-machine.h +new file mode 100644 +index 00000000..2a5e3767 +--- /dev/null ++++ b/sysdeps/loongarch/dl-machine.h +@@ -0,0 +1,366 @@ ++/* Copyright (C) 2020-2021 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 ++ . */ ++ ++#ifndef dl_machine_h ++#define dl_machine_h ++ ++#define ELF_MACHINE_NAME "LoongArch" ++ ++#include ++#include ++#include ++#include ++ ++#ifndef _RTLD_PROLOGUE ++# define _RTLD_PROLOGUE(entry) \ ++ ".globl\t" __STRING (entry) "\n\t" \ ++ ".type\t" __STRING (entry) ", @function\n\t" \ ++ CFI_STARTPROC "\n" \ ++ __STRING (entry) ":\n" ++#endif ++ ++#ifndef _RTLD_EPILOGUE ++# define _RTLD_EPILOGUE(entry) \ ++ CFI_ENDPROC "\n\t" \ ++ ".size\t" __STRING (entry) ", . - " __STRING (entry) "\n" ++#endif ++ ++#define ELF_MACHINE_JMP_SLOT R_LARCH_JUMP_SLOT ++#define ELF_MACHINE_IRELATIVE R_LARCH_IRELATIVE ++ ++#define elf_machine_type_class(type) \ ++ ((ELF_RTYPE_CLASS_PLT * ((type) == ELF_MACHINE_JMP_SLOT \ ++ || (__WORDSIZE == 32 && (type) == R_LARCH_TLS_DTPREL32) \ ++ || (__WORDSIZE == 32 && (type) == R_LARCH_TLS_DTPMOD32) \ ++ || (__WORDSIZE == 32 && (type) == R_LARCH_TLS_TPREL32) \ ++ || (__WORDSIZE == 64 && (type) == R_LARCH_TLS_DTPREL64) \ ++ || (__WORDSIZE == 64 && (type) == R_LARCH_TLS_DTPMOD64) \ ++ || (__WORDSIZE == 64 && (type) == R_LARCH_TLS_TPREL64))) \ ++ | (ELF_RTYPE_CLASS_COPY * ((type) == R_LARCH_COPY))) ++ ++#define ELF_MACHINE_NO_REL 1 ++#define ELF_MACHINE_NO_RELA 0 ++ ++/* Return nonzero iff ELF header is compatible with the running host. */ ++static inline int __attribute_used__ ++elf_machine_matches_host (const ElfW(Ehdr) *ehdr) ++{ ++ /* We can only run LoongArch binaries. */ ++ if (ehdr->e_machine != EM_LOONGARCH) ++ return 0; ++ ++#ifdef _ABILP64 ++ if ((ehdr->e_flags & EF_LARCH_ABI) != EF_LARCH_ABI_LP64) ++#elif defined _ABILPX32 ++ if ((ehdr->e_flags & EF_LARCH_ABI) != EF_LARCH_ABI_LPX32) ++#elif defined _ABILP32 ++ if ((ehdr->e_flags & EF_LARCH_ABI) != EF_LARCH_ABI_LP32) ++#else ++# error "Unknown ABI" ++#endif ++ return 0; ++ ++ return 1; ++} ++ ++/* Runtime address of .got */ ++#define _GLOBAL_OFFSET_TABLE_ ({ \ ++ ElfW(Addr) *r; \ ++ asm ("la.pcrel %0, _GLOBAL_OFFSET_TABLE_":"=r" (r)); \ ++ r; \ ++}) ++ ++/* Return the link-time address of _DYNAMIC. */ ++static inline ElfW(Addr) ++elf_machine_dynamic (void) ++{ ++ return _GLOBAL_OFFSET_TABLE_[0]; ++} ++ ++#define STRINGXP(X) __STRING (X) ++#define STRINGXV(X) STRINGV_ (X) ++#define STRINGV_(...) # __VA_ARGS__ ++ ++/* Return the run-time load address of the shared object. */ ++static inline ElfW(Addr) ++elf_machine_load_address (void) ++{ ++ ElfW(Addr) got_linktime_addr; ++ asm ( ++ "la.got %0, _GLOBAL_OFFSET_TABLE_" ++ /* Link-time address in GOT entry before runtime relocation */ ++ : "=r" (got_linktime_addr) ++ ); ++ return (ElfW(Addr))_GLOBAL_OFFSET_TABLE_ - got_linktime_addr; ++} ++ ++/* Initial entry point code for the dynamic linker. ++ The C function `_dl_start' is the real entry point; ++ its return value is the user program's entry point. */ ++ ++#define RTLD_START asm (\ ++ ".text\n\ ++ " _RTLD_PROLOGUE (ENTRY_POINT) "\ ++ .cfi_label .Ldummy\n\ ++ " CFI_UNDEFINED (1) "\n\ ++ or $a0, $sp, $zero\n\ ++ bl _dl_start\n\ ++ # Stash user entry point in s0.\n\ ++ or $s0, $v0, $zero\n\ ++ # See if we were run as a command with the executable file\n\ ++ # name as an extra leading argument.\n\ ++ la $a0, _dl_skip_args\n\ ++ ld.w $a0, $a0, 0\n\ ++ # Load the original argument count.\n\ ++ ld.d $a1, $sp, 0\n\ ++ # Subtract _dl_skip_args from it.\n\ ++ sub.d $a1, $a1, $a0\n\ ++ # Adjust the stack pointer to skip _dl_skip_args words.\n\ ++ slli.d $a0, $a0, 3\n\ ++ add.d $sp, $sp, $a0\n\ ++ # Save back the modified argument count.\n\ ++ st.d $a1, $sp, 0\n\ ++ # Call _dl_init (struct link_map *main_map, int argc, char **argv, char **env) \n\ ++ la $a0, _rtld_local\n\ ++ ld.d $a0, $a0, 0\n\ ++ addi.d $a2, $sp, 8\n\ ++ slli.d $a3, $a1, 3\n\ ++ add.d $a3, $a3, $a2\n\ ++ addi.d $a3, $a3, 8\n\ ++ # Adjust $sp for 16-aligned\n\ ++ srli.d $t0, $sp, 4\n\ ++ slli.d $t0, $t0, 4\n\ ++ ori $t1, $sp, 0\n\ ++ addi.d $sp, $t0, -32\n\ ++ st.d $t1, $sp, 24\n\ ++ # Call the function to run the initializers.\n\ ++ bl _dl_init\n\ ++ # Pass our finalizer function to _start.\n\ ++ ld.d $sp, $sp, 24\n\ ++ la $a0, _dl_fini\n\ ++ # Jump to the user entry point.\n\ ++ jirl $zero, $s0, 0\n\ ++ " _RTLD_EPILOGUE (ENTRY_POINT) "\ ++ .previous" \ ++); ++ ++/* Names of the architecture-specific auditing callback functions. */ ++#define ARCH_LA_PLTENTER loongarch_gnu_pltenter ++#define ARCH_LA_PLTEXIT loongarch_gnu_pltexit ++ ++/* Bias .got.plt entry by the offset requested by the PLT header. */ ++#define elf_machine_plt_value(map, reloc, value) (value) ++ ++static inline ElfW(Addr) ++elf_machine_fixup_plt (struct link_map *map, lookup_t t, ++ const ElfW(Sym) *refsym, const ElfW(Sym) *sym, ++ const ElfW(Rela) *reloc, ++ ElfW(Addr) *reloc_addr, ElfW(Addr) value) ++{ ++ return *reloc_addr = value; ++} ++ ++#endif /* !dl_machine_h */ ++ ++#ifdef RESOLVE_MAP ++ ++/* Perform a relocation described by R_INFO at the location pointed to ++ by RELOC_ADDR. SYM is the relocation symbol specified by R_INFO and ++ MAP is the object containing the reloc. */ ++ ++auto inline void ++__attribute__ ((always_inline)) ++elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, ++ const ElfW(Sym) *sym, const struct r_found_version *version, ++ void *const reloc_addr, int skip_ifunc) ++{ ++ ElfW(Addr) r_info = reloc->r_info; ++ const unsigned long int r_type = ELFW (R_TYPE) (r_info); ++ ElfW(Addr) *addr_field = (ElfW(Addr) *) reloc_addr; ++ const ElfW(Sym) *const __attribute__ ((unused)) refsym = sym; ++ struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); ++ ElfW(Addr) value = 0; ++ if (sym_map != NULL) ++ value = SYMBOL_ADDRESS (sym_map, sym, true) + reloc->r_addend; ++ ++ if (sym != NULL ++ && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0) ++ && __builtin_expect (sym->st_shndx != SHN_UNDEF, 1) ++ && __builtin_expect (!skip_ifunc, 1)) ++ value = ((ElfW(Addr) (*) (int)) value) (GLRO(dl_hwcap)); ++ ++ switch (r_type) ++ { ++#ifndef RTLD_BOOTSTRAP ++ case __WORDSIZE == 64 ? R_LARCH_TLS_DTPMOD64 : R_LARCH_TLS_DTPMOD32: ++ if (sym_map) ++ *addr_field = sym_map->l_tls_modid; ++ break; ++ ++ case __WORDSIZE == 64 ? R_LARCH_TLS_DTPREL64 : R_LARCH_TLS_DTPREL32: ++ if (sym != NULL) ++ *addr_field = TLS_DTPREL_VALUE (sym) + reloc->r_addend; ++ break; ++ ++ case __WORDSIZE == 64 ? R_LARCH_TLS_TPREL64 : R_LARCH_TLS_TPREL32: ++ if (sym != NULL) ++ { ++ CHECK_STATIC_TLS (map, sym_map); ++ *addr_field = TLS_TPREL_VALUE (sym_map, sym) + reloc->r_addend; ++ } ++ break; ++ ++ case R_LARCH_COPY: ++ { ++ if (__glibc_unlikely (sym == NULL)) ++ /* This can happen in trace mode if an object could not be ++ found. */ ++ break; ++ ++ /* Handle TLS copy relocations. */ ++ if (__glibc_unlikely (ELFW (ST_TYPE) (sym->st_info) == STT_TLS)) ++ { ++ /* There's nothing to do if the symbol is in .tbss. */ ++ if (__glibc_likely (sym->st_value >= sym_map->l_tls_initimage_size)) ++ break; ++ value += (ElfW(Addr)) sym_map->l_tls_initimage - sym_map->l_addr; ++ } ++ ++ size_t size = sym->st_size; ++ if (__glibc_unlikely (sym->st_size != refsym->st_size)) ++ { ++ const char *strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]); ++ if (sym->st_size > refsym->st_size) ++ size = refsym->st_size; ++ if (sym->st_size > refsym->st_size || GLRO(dl_verbose)) ++ _dl_error_printf ("\ ++ %s: Symbol `%s' has different size in shared object, consider re-linking\n", ++ rtld_progname ?: "", ++ strtab + refsym->st_name); ++ } ++ ++ memcpy (reloc_addr, (void *)value, size); ++ break; ++ } ++#endif ++ ++#if !defined RTLD_BOOTSTRAP || !defined HAVE_Z_COMBRELOC ++ case R_LARCH_RELATIVE: ++ { ++# if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC ++ /* This is defined in rtld.c, but nowhere in the static libc.a; ++ make the reference weak so static programs can still link. ++ This declaration cannot be done when compiling rtld.c ++ (i.e. #ifdef RTLD_BOOTSTRAP) because rtld.c contains the ++ common defn for _dl_rtld_map, which is incompatible with a ++ weak decl in the same file. */ ++# ifndef SHARED ++ weak_extern (GL(dl_rtld_map)); ++# endif ++ if (map != &GL(dl_rtld_map)) /* Already done in rtld itself. */ ++# endif ++ *addr_field = map->l_addr + reloc->r_addend; ++ break; ++ } ++#endif ++ ++ case R_LARCH_JUMP_SLOT: ++ case __WORDSIZE == 64 ? R_LARCH_64 : R_LARCH_32: ++ *addr_field = value; ++ break; ++ ++ case R_LARCH_IRELATIVE: ++ value = map->l_addr + reloc->r_addend; ++ value = ((ElfW(Addr) (*) (void)) value) (); ++ *addr_field = value; ++ break; ++ ++ case R_LARCH_NONE: ++ break; ++ ++ default: ++ _dl_reloc_bad_type (map, r_type, 0); ++ break; ++ } ++} ++ ++auto inline void ++__attribute__ ((always_inline)) ++elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc, ++ void *const reloc_addr) ++{ ++ *(ElfW(Addr) *) reloc_addr = l_addr + reloc->r_addend; ++} ++ ++auto inline void ++__attribute__ ((always_inline)) ++elf_machine_lazy_rel (struct link_map *map, ElfW(Addr) l_addr, ++ const ElfW(Rela) *reloc, int skip_ifunc) ++{ ++ ElfW(Addr) *const reloc_addr = (void *) (l_addr + reloc->r_offset); ++ const unsigned int r_type = ELFW (R_TYPE) (reloc->r_info); ++ ++ /* Check for unexpected PLT reloc type. */ ++ if (__glibc_likely (r_type == R_LARCH_JUMP_SLOT)) ++ { ++ if (__glibc_unlikely (map->l_mach.plt == 0)) ++ { ++ if (l_addr) ++ *reloc_addr += l_addr; ++ } ++ else ++ *reloc_addr = map->l_mach.plt; ++ } ++ else if (__glibc_unlikely (r_type == R_LARCH_IRELATIVE)) ++ { ++ ElfW(Addr) *value = (void *) (l_addr + reloc->r_addend); ++ if (__glibc_likely (!skip_ifunc)) ++ value = (ElfW(Addr) *)((ElfW(Addr) (*) (void)) value) (); ++ *reloc_addr = (ElfW(Addr))value; ++ } ++ else ++ _dl_reloc_bad_type (map, r_type, 1); ++} ++ ++/* Set up the loaded object described by L so its stub function ++ will jump to the on-demand fixup code __dl_runtime_resolve. */ ++ ++auto inline int ++__attribute__ ((always_inline)) ++elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) ++{ ++#ifndef RTLD_BOOTSTRAP ++ /* If using PLTs, fill in the first two entries of .got.plt. */ ++ if (l->l_info[DT_JMPREL]) ++ { ++ extern void _dl_runtime_resolve (void) __attribute__ ((visibility ("hidden"))); ++ ElfW(Addr) *gotplt = (ElfW(Addr) *) D_PTR (l, l_info[DT_PLTGOT]); ++ /* If a library is prelinked but we have to relocate anyway, ++ we have to be able to undo the prelinking of .got.plt. ++ The prelinker saved the address of .plt for us here. */ ++ if (gotplt[1]) ++ l->l_mach.plt = gotplt[1] + l->l_addr; ++ gotplt[0] = (ElfW(Addr)) &_dl_runtime_resolve; ++ gotplt[1] = (ElfW(Addr)) l; ++ } ++#endif ++ ++ return lazy; ++} ++ ++#endif /* RESOLVE_MAP */ +diff --git a/sysdeps/loongarch/dl-tls.h b/sysdeps/loongarch/dl-tls.h +new file mode 100644 +index 00000000..70110c50 +--- /dev/null ++++ b/sysdeps/loongarch/dl-tls.h +@@ -0,0 +1,49 @@ ++/* Copyright (C) 2020-2021 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 ++ . */ ++ ++ ++/* Type used for the representation of TLS information in the GOT. */ ++typedef struct ++{ ++ unsigned long int ti_module; ++ unsigned long int ti_offset; ++} tls_index; ++ ++/* The thread pointer points to the first static TLS block. */ ++#define TLS_TP_OFFSET 0 ++ ++/* Dynamic thread vector pointers point 0x800 past the start of each ++ TLS block. */ ++//#define TLS_DTV_OFFSET 0x800 ++#define TLS_DTV_OFFSET 0 ++ ++/* Compute the value for a GOTTPREL reloc. */ ++#define TLS_TPREL_VALUE(sym_map, sym) \ ++ ((sym_map)->l_tls_offset + (sym)->st_value - TLS_TP_OFFSET) ++ ++/* Compute the value for a DTPREL reloc. */ ++#define TLS_DTPREL_VALUE(sym) \ ++ ((sym)->st_value - TLS_DTV_OFFSET) ++ ++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/sysdeps/loongarch/dl-trampoline.S b/sysdeps/loongarch/dl-trampoline.S +new file mode 100644 +index 00000000..1f4689e0 +--- /dev/null ++++ b/sysdeps/loongarch/dl-trampoline.S +@@ -0,0 +1,108 @@ ++/* Copyright (C) 2020-2021 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 ++ . */ ++ ++#include ++#include ++ ++/* Assembler veneer called from the PLT header code for lazy loading. ++ The PLT header passes its own args in t0-t2. */ ++ ++#ifdef __loongarch_soft_float ++# define FRAME_SIZE (-((-10 * SZREG) & ALMASK)) ++#else ++# define FRAME_SIZE (-((-10 * SZREG - 8 * SZFREG) & ALMASK)) ++#endif ++ ++ENTRY (_dl_runtime_resolve) ++ # Save arguments to stack. ++ ++#ifdef __loongarch64 ++ addi.d sp, sp, -FRAME_SIZE ++#elif defined __loongarch32 ++ addi.w sp, sp, -FRAME_SIZE ++#endif ++ ++ REG_S ra, sp, 9*SZREG ++ REG_S a0, sp, 1*SZREG ++ REG_S a1, sp, 2*SZREG ++ REG_S a2, sp, 3*SZREG ++ REG_S a3, sp, 4*SZREG ++ REG_S a4, sp, 5*SZREG ++ REG_S a5, sp, 6*SZREG ++ REG_S a6, sp, 7*SZREG ++ REG_S a7, sp, 8*SZREG ++ ++#ifndef __loongarch_soft_float ++ FREG_S fa0, sp, 10*SZREG + 0*SZFREG ++ FREG_S fa1, sp, 10*SZREG + 1*SZFREG ++ FREG_S fa2, sp, 10*SZREG + 2*SZFREG ++ FREG_S fa3, sp, 10*SZREG + 3*SZFREG ++ FREG_S fa4, sp, 10*SZREG + 4*SZFREG ++ FREG_S fa5, sp, 10*SZREG + 5*SZFREG ++ FREG_S fa6, sp, 10*SZREG + 6*SZFREG ++ FREG_S fa7, sp, 10*SZREG + 7*SZFREG ++#endif ++ ++ # Update .got.plt and obtain runtime address of callee. ++#ifdef __loongarch64 ++ slli.d a1, t1, 1 ++ or a0, t0, zero ++ add.d a1, a1, t1 ++ la a2, _dl_fixup ++ jirl ra, a2, 0 ++ or t1, v0, zero ++#elif defined __loongarch32 ++ slli.w a1, t1, 1 ++ or a0, t0, zero ++ add.w a1, a1, t1 ++ la a2, _dl_fixup ++ jirl ra, a2, 0 ++ or t1, v0, zero ++#endif ++ ++ # Restore arguments from stack. ++ REG_L ra, sp, 9*SZREG ++ REG_L a0, sp, 1*SZREG ++ REG_L a1, sp, 2*SZREG ++ REG_L a2, sp, 3*SZREG ++ REG_L a3, sp, 4*SZREG ++ REG_L a4, sp, 5*SZREG ++ REG_L a5, sp, 6*SZREG ++ REG_L a6, sp, 7*SZREG ++ REG_L a7, sp, 8*SZREG ++ ++#ifndef __loongarch_soft_float ++ FREG_L fa0, sp, 10*SZREG + 0*SZFREG ++ FREG_L fa1, sp, 10*SZREG + 1*SZFREG ++ FREG_L fa2, sp, 10*SZREG + 2*SZFREG ++ FREG_L fa3, sp, 10*SZREG + 3*SZFREG ++ FREG_L fa4, sp, 10*SZREG + 4*SZFREG ++ FREG_L fa5, sp, 10*SZREG + 5*SZFREG ++ FREG_L fa6, sp, 10*SZREG + 6*SZFREG ++ FREG_L fa7, sp, 10*SZREG + 7*SZFREG ++#endif ++ ++#ifdef __loongarch64 ++ addi.d sp, sp, FRAME_SIZE ++#elif defined __loongarch32 ++ addi.w sp, sp, FRAME_SIZE ++#endif ++ ++ # Invoke the callee. ++ jirl zero, t1, 0 ++END (_dl_runtime_resolve) +diff --git a/sysdeps/loongarch/e_sqrtl.c b/sysdeps/loongarch/e_sqrtl.c +new file mode 100644 +index 00000000..65ae7ad8 +--- /dev/null ++++ b/sysdeps/loongarch/e_sqrtl.c +@@ -0,0 +1,39 @@ ++/* long double square root in software floating-point emulation. ++ Copyright (C) 1997-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson (rth@cygnus.com) and ++ Jakub Jelinek (jj@ultra.linux.cz). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++#include ++#include ++#include ++ ++long double ++__ieee754_sqrtl (const long double a) ++{ ++ FP_DECL_EX; ++ FP_DECL_Q(A); FP_DECL_Q(C); ++ long double c; ++ ++ FP_INIT_ROUNDMODE; ++ FP_UNPACK_Q(A, a); ++ FP_SQRT_Q(C, A); ++ FP_PACK_Q(c, C); ++ FP_HANDLE_EXCEPTIONS; ++ return c; ++} ++strong_alias (__ieee754_sqrtl, __sqrtl_finite) +diff --git a/sysdeps/loongarch/elf-init.c b/sysdeps/loongarch/elf-init.c +new file mode 100644 +index 00000000..5f261a9d +--- /dev/null ++++ b/sysdeps/loongarch/elf-init.c +@@ -0,0 +1 @@ ++#include +diff --git a/sysdeps/loongarch/fpu/e_sqrt.c b/sysdeps/loongarch/fpu/e_sqrt.c +new file mode 100644 +index 00000000..dac8696a +--- /dev/null ++++ b/sysdeps/loongarch/fpu/e_sqrt.c +@@ -0,0 +1,29 @@ ++/* Copyright (C) 2002-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Hartvig Ekner , 2002. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++ ++ ++double ++__ieee754_sqrt (double x) ++{ ++ double z; ++ __asm__ ("fsqrt.d %0,%1" : "=f" (z) : "f" (x)); ++ return z; ++} ++strong_alias (__ieee754_sqrt, __sqrt_finite) ++ +diff --git a/sysdeps/loongarch/fpu/e_sqrtf.c b/sysdeps/loongarch/fpu/e_sqrtf.c +new file mode 100644 +index 00000000..706c0494 +--- /dev/null ++++ b/sysdeps/loongarch/fpu/e_sqrtf.c +@@ -0,0 +1,28 @@ ++/* Copyright (C) 2002-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Hartvig Ekner , 2002. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++ ++ ++float ++__ieee754_sqrtf (float x) ++{ ++ float z; ++ __asm__ ("fsqrt.s %0,%1" : "=f" (z) : "f" (x)); ++ return z; ++} ++strong_alias (__ieee754_sqrtf, __sqrtf_finite) +diff --git a/sysdeps/loongarch/fpu/fclrexcpt.c b/sysdeps/loongarch/fpu/fclrexcpt.c +new file mode 100644 +index 00000000..51310d93 +--- /dev/null ++++ b/sysdeps/loongarch/fpu/fclrexcpt.c +@@ -0,0 +1,47 @@ ++/* Clear given exceptions in current floating-point environment. ++ Copyright (C) 1998-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Andreas Jaeger , 1998. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++#include ++#include ++#include ++ ++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; ++} ++libm_hidden_def (feclearexcept) +diff --git a/sysdeps/loongarch/fpu/fedisblxcpt.c b/sysdeps/loongarch/fpu/fedisblxcpt.c +new file mode 100644 +index 00000000..004b0ecb +--- /dev/null ++++ b/sysdeps/loongarch/fpu/fedisblxcpt.c +@@ -0,0 +1,40 @@ ++/* Disable floating-point exceptions. ++ Copyright (C) 2000-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Andreas Jaeger , 2000. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++#include ++#include ++#include ++ ++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/sysdeps/loongarch/fpu/feenablxcpt.c b/sysdeps/loongarch/fpu/feenablxcpt.c +new file mode 100644 +index 00000000..b8f56625 +--- /dev/null ++++ b/sysdeps/loongarch/fpu/feenablxcpt.c +@@ -0,0 +1,40 @@ ++/* Enable floating-point exceptions. ++ Copyright (C) 2000-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Andreas Jaeger , 2000. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++#include ++#include ++#include ++ ++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/sysdeps/loongarch/fpu/fegetenv.c b/sysdeps/loongarch/fpu/fegetenv.c +new file mode 100644 +index 00000000..8e8fa2c5 +--- /dev/null ++++ b/sysdeps/loongarch/fpu/fegetenv.c +@@ -0,0 +1,33 @@ ++/* Store current floating-point environment. ++ Copyright (C) 1998-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Andreas Jaeger , 1998. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++#include ++#include ++ ++int ++__fegetenv (fenv_t *envp) ++{ ++ _FPU_GETCW (*envp); ++ ++ /* Success. */ ++ return 0; ++} ++libm_hidden_def (__fegetenv) ++weak_alias (__fegetenv, fegetenv) ++libm_hidden_weak (fegetenv) +diff --git a/sysdeps/loongarch/fpu/fegetexcept.c b/sysdeps/loongarch/fpu/fegetexcept.c +new file mode 100644 +index 00000000..2c0a1208 +--- /dev/null ++++ b/sysdeps/loongarch/fpu/fegetexcept.c +@@ -0,0 +1,33 @@ ++/* Get enabled floating-point exceptions. ++ Copyright (C) 2000-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Andreas Jaeger , 2000. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++#include ++#include ++#include ++ ++int ++fegetexcept (void) ++{ ++ unsigned int exc; ++ ++ /* Get the current control word. */ ++ _FPU_GETCW (exc); ++ ++ return (exc & ENABLE_MASK) << ENABLE_SHIFT; ++} +diff --git a/sysdeps/loongarch/fpu/fegetmode.c b/sysdeps/loongarch/fpu/fegetmode.c +new file mode 100644 +index 00000000..e0a5180f +--- /dev/null ++++ b/sysdeps/loongarch/fpu/fegetmode.c +@@ -0,0 +1,27 @@ ++/* Store current floating-point control modes. MIPS version. ++ Copyright (C) 2016-2018 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 ++ . */ ++ ++#include ++#include ++ ++int ++fegetmode (femode_t *modep) ++{ ++ _FPU_GETCW (*modep); ++ return 0; ++} +diff --git a/sysdeps/loongarch/fpu/fegetround.c b/sysdeps/loongarch/fpu/fegetround.c +new file mode 100644 +index 00000000..a7ac444a +--- /dev/null ++++ b/sysdeps/loongarch/fpu/fegetround.c +@@ -0,0 +1,35 @@ ++/* Return current rounding direction. ++ Copyright (C) 1998-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Andreas Jaeger , 1998. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++#include ++#include ++ ++int ++__fegetround (void) ++{ ++ int cw; ++ ++ /* Get control word. */ ++ _FPU_GETCW (cw); ++ ++ return cw & _FPU_RC_MASK; ++} ++libm_hidden_def (__fegetround) ++weak_alias (__fegetround, fegetround) ++libm_hidden_weak (fegetround) +diff --git a/sysdeps/loongarch/fpu/feholdexcpt.c b/sysdeps/loongarch/fpu/feholdexcpt.c +new file mode 100644 +index 00000000..eb9d4764 +--- /dev/null ++++ b/sysdeps/loongarch/fpu/feholdexcpt.c +@@ -0,0 +1,41 @@ ++/* Store current floating-point environment and clear exceptions. ++ Copyright (C) 2000-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Andreas Jaeger , 2000. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++#include ++#include ++ ++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; ++} ++ ++libm_hidden_def (__feholdexcept) ++weak_alias (__feholdexcept, feholdexcept) ++libm_hidden_weak (feholdexcept) +diff --git a/sysdeps/loongarch/fpu/fenv_libc.h b/sysdeps/loongarch/fpu/fenv_libc.h +new file mode 100644 +index 00000000..f5dd1678 +--- /dev/null ++++ b/sysdeps/loongarch/fpu/fenv_libc.h +@@ -0,0 +1,31 @@ ++/* Copyright (C) 2000-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Andreas Jaeger . ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++#ifndef _FENV_LIBC_H ++#define _FENV_LIBC_H 1 ++ ++/* Mask for enabling exceptions and for the CAUSE bits. */ ++#define ENABLE_MASK 0x0000001FU ++#define CAUSE_MASK 0x1F000000U ++ ++/* Shift for FE_* flags to get up to the ENABLE bits and the CAUSE bits. */ ++#define ENABLE_SHIFT 16 ++#define CAUSE_SHIFT 8 ++ ++ ++#endif /* _FENV_LIBC_H */ +diff --git a/sysdeps/loongarch/fpu/fesetenv.c b/sysdeps/loongarch/fpu/fesetenv.c +new file mode 100644 +index 00000000..8dee8782 +--- /dev/null ++++ b/sysdeps/loongarch/fpu/fesetenv.c +@@ -0,0 +1,44 @@ ++/* Install given floating-point environment. ++ Copyright (C) 1998-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Andreas Jaeger , 1998. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++#include ++#include ++ ++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; ++} ++ ++libm_hidden_def (__fesetenv) ++weak_alias (__fesetenv, fesetenv) ++libm_hidden_weak (fesetenv) +diff --git a/sysdeps/loongarch/fpu/fesetexcept.c b/sysdeps/loongarch/fpu/fesetexcept.c +new file mode 100644 +index 00000000..d14febca +--- /dev/null ++++ b/sysdeps/loongarch/fpu/fesetexcept.c +@@ -0,0 +1,32 @@ ++/* Set given exception flags. MIPS version. ++ Copyright (C) 2016-2018 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 ++ . */ ++ ++#include ++#include ++ ++int ++fesetexcept (int excepts) ++{ ++ fpu_control_t temp; ++ ++ _FPU_GETCW (temp); ++ temp |= excepts & FE_ALL_EXCEPT; ++ _FPU_SETCW (temp); ++ ++ return 0; ++} +diff --git a/sysdeps/loongarch/fpu/fesetmode.c b/sysdeps/loongarch/fpu/fesetmode.c +new file mode 100644 +index 00000000..8cc5d0b1 +--- /dev/null ++++ b/sysdeps/loongarch/fpu/fesetmode.c +@@ -0,0 +1,38 @@ ++/* Install given floating-point control modes. MIPS version. ++ Copyright (C) 2016-2018 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 ++ . */ ++ ++#include ++#include ++ ++#define FCSR_STATUS 0x1f1f0000 ++ ++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/sysdeps/loongarch/fpu/fesetround.c b/sysdeps/loongarch/fpu/fesetround.c +new file mode 100644 +index 00000000..31fdeab3 +--- /dev/null ++++ b/sysdeps/loongarch/fpu/fesetround.c +@@ -0,0 +1,46 @@ ++/* Set current rounding direction. ++ Copyright (C) 1998-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Andreas Jaeger , 1998. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++#include ++#include ++ ++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; ++} ++ ++libm_hidden_def (__fesetround) ++weak_alias (__fesetround, fesetround) ++libm_hidden_weak (fesetround) +diff --git a/sysdeps/loongarch/fpu/feupdateenv.c b/sysdeps/loongarch/fpu/feupdateenv.c +new file mode 100644 +index 00000000..669bfc3c +--- /dev/null ++++ b/sysdeps/loongarch/fpu/feupdateenv.c +@@ -0,0 +1,45 @@ ++/* Install given floating-point environment and raise exceptions. ++ Copyright (C) 1998-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Andreas Jaeger , 1998. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++#include ++#include ++ ++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 safed exception. Incidently 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; ++} ++libm_hidden_def (__feupdateenv) ++weak_alias (__feupdateenv, feupdateenv) ++libm_hidden_weak (feupdateenv) +diff --git a/sysdeps/loongarch/fpu/fgetexcptflg.c b/sysdeps/loongarch/fpu/fgetexcptflg.c +new file mode 100644 +index 00000000..1e594e14 +--- /dev/null ++++ b/sysdeps/loongarch/fpu/fgetexcptflg.c +@@ -0,0 +1,39 @@ ++/* Store current representation for exceptions. ++ Copyright (C) 1998-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Andreas Jaeger , 1998. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++#include ++#include ++ ++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/sysdeps/loongarch/fpu/fraiseexcpt.c b/sysdeps/loongarch/fpu/fraiseexcpt.c +new file mode 100644 +index 00000000..2eec053a +--- /dev/null ++++ b/sysdeps/loongarch/fpu/fraiseexcpt.c +@@ -0,0 +1,84 @@ ++/* Raise given exceptions. ++ Copyright (C) 2000-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Andreas Jaeger , 2000. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++#include ++#include ++#include ++ ++int ++__feraiseexcept (int excepts) ++{ ++ ++ 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.*/ ++ ++ /* First: invalid exception. */ ++ if (FE_INVALID & excepts) ++ __asm__ __volatile__ ( ++ "fdiv.s $f0,%0,%0\n\t" ++ : ++ : "f" (fp_zero) ++ :"$f0"); ++ ++ /* Next: division by zero. */ ++ if (FE_DIVBYZERO & excepts) ++ __asm__ __volatile__ ( ++ "fdiv.s $f0,%0,%1\n\t" ++ : ++ : "f" (fp_one), "f" (fp_zero) ++ :"$f0"); ++ ++ /* Next: overflow. */ ++ if (FE_OVERFLOW & excepts) ++ /* There's no way to raise overflow without also raising inexact. */ ++ __asm__ __volatile__ ( ++ "fadd.s $f0,%0,%1\n\t" ++ : ++ : "f" (fp_max), "f" (fp_1e32) ++ : "$f0"); ++ ++ /* Next: underflow. */ ++ if (FE_UNDERFLOW & excepts) ++ __asm__ __volatile__ ( ++ "fdiv.s $f0,%0,%1\n\t" ++ : ++ : "f" (fp_min), "f" (fp_three) ++ : "$f0"); ++ ++ /* Last: inexact. */ ++ if (FE_INEXACT & excepts) ++ __asm__ __volatile__ ( ++ "fdiv.s $f0, %0, %1\n\t" ++ : ++ : "f" (fp_two), "f" (fp_three) ++ : "$f0"); ++ ++ /* Success. */ ++ return 0; ++} ++ ++libm_hidden_def (__feraiseexcept) ++weak_alias (__feraiseexcept, feraiseexcept) ++libm_hidden_weak (feraiseexcept) +diff --git a/sysdeps/loongarch/fpu/fsetexcptflg.c b/sysdeps/loongarch/fpu/fsetexcptflg.c +new file mode 100644 +index 00000000..dc447a77 +--- /dev/null ++++ b/sysdeps/loongarch/fpu/fsetexcptflg.c +@@ -0,0 +1,42 @@ ++/* Set floating-point environment exception handling. ++ Copyright (C) 1998-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Hartvig Ekner , 2002. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++#include ++#include ++ ++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/sysdeps/loongarch/fpu/ftestexcept.c b/sysdeps/loongarch/fpu/ftestexcept.c +new file mode 100644 +index 00000000..fa645b26 +--- /dev/null ++++ b/sysdeps/loongarch/fpu/ftestexcept.c +@@ -0,0 +1,33 @@ ++/* Test exception in current environment. ++ Copyright (C) 1998-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Andreas Jaeger , 1998. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++#include ++#include ++ ++int ++fetestexcept (int excepts) ++{ ++ int cw; ++ ++ /* Get current control word. */ ++ _FPU_GETCW (cw); ++ ++ return cw & excepts & FE_ALL_EXCEPT; ++} ++libm_hidden_def (fetestexcept) +diff --git a/sysdeps/loongarch/fpu_control.h b/sysdeps/loongarch/fpu_control.h +new file mode 100644 +index 00000000..92474b25 +--- /dev/null ++++ b/sysdeps/loongarch/fpu_control.h +@@ -0,0 +1,111 @@ ++/* FPU control word bits. Mips version. ++ Copyright (C) 1996-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Olaf Flebbe and Ralf Baechle. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++#ifndef _FPU_CONTROL_H ++#define _FPU_CONTROL_H ++ ++/* MIPS FPU floating point control register bits. ++ * ++ * 31-25 -> floating point conditions code bits 7-1. These bits are only ++ * available in MIPS IV. ++ * 24 -> flush denormalized results to zero instead of ++ * causing unimplemented operation exception. This bit is only ++ * available for MIPS III and newer. ++ * 23 -> Condition bit ++ * 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 ++ * 28 -> cause bit for invalid exception ++ * 27 -> cause bit for division by zero exception ++ * 26 -> cause bit for overflow exception ++ * 25 -> cause bit for underflow exception ++ * 24 -> cause bit for inexact exception ++ * 4 -> enable exception for invalid exception ++ * 3 -> enable exception for division by zero exception ++ * 2 -> enable exception for overflow exception ++ * 1 -> enable exception for underflow exception ++ * 0 -> enable exception for inexact exception ++ * 20 -> flag invalid exception ++ * 19 -> flag division by zero exception ++ * 18 -> flag overflow exception ++ * 17 -> flag underflow exception ++ * 16 -> flag inexact exception ++ * 9-8 -> rounding control ++ * ++ * ++ * 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) ++ */ ++ ++#include ++ ++#ifdef __loongarch_soft_float ++ ++#define _FPU_RESERVED 0xffffffff ++#define _FPU_DEFAULT 0x00000000 ++typedef unsigned int fpu_control_t; ++#define _FPU_GETCW(cw) (cw) = 0 ++#define _FPU_SETCW(cw) (void) (cw) ++extern fpu_control_t __fpu_control; ++ ++#else /* __loongarch_soft_float */ ++ ++/* Masks for interrupts. */ ++#define _FPU_MASK_V 0x10 /* Invalid operation */ ++#define _FPU_MASK_Z 0x08 /* Division by zero */ ++#define _FPU_MASK_O 0x04 /* Overflow */ ++#define _FPU_MASK_U 0x02 /* Underflow */ ++#define _FPU_MASK_I 0x01 /* Inexact operation */ ++ ++/* Flush denormalized numbers to zero. */ ++#define _FPU_FLUSH_TZ 0x1000000 ++ ++/* Rounding control. */ ++#define _FPU_RC_NEAREST 0x000 /* RECOMMENDED */ ++#define _FPU_RC_ZERO 0x100 ++#define _FPU_RC_UP 0x200 ++#define _FPU_RC_DOWN 0x300 ++/* Mask for rounding control. */ ++#define _FPU_RC_MASK 0x300 ++ ++#define _FPU_RESERVED 0x0 ++ ++#define _FPU_DEFAULT 0x0 ++#define _FPU_IEEE 0x1F ++ ++/* Type of the control word. */ ++typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__SI__))); ++ ++/* Macros for accessing the hardware control word. */ ++extern fpu_control_t __mips_fpu_getcw (void) __THROW; ++extern void __mips_fpu_setcw (fpu_control_t) __THROW; ++#define _FPU_GETCW(cw) __asm__ volatile ("movfcsr2gr %0,$r0" : "=r" (cw)) ++#define _FPU_SETCW(cw) __asm__ volatile ("movgr2fcsr $r0,%0" : : "r" (cw)) ++ ++/* Default control word set at startup. */ ++extern fpu_control_t __fpu_control; ++ ++#endif /* __loongarch_soft_float */ ++ ++#endif /* fpu_control.h */ +diff --git a/sysdeps/loongarch/fstat.c b/sysdeps/loongarch/fstat.c +new file mode 100644 +index 00000000..c4504eeb +--- /dev/null ++++ b/sysdeps/loongarch/fstat.c +@@ -0,0 +1 @@ ++#include +diff --git a/sysdeps/loongarch/fstat64.c b/sysdeps/loongarch/fstat64.c +new file mode 100644 +index 00000000..143ca2b0 +--- /dev/null ++++ b/sysdeps/loongarch/fstat64.c +@@ -0,0 +1 @@ ++#include +diff --git a/sysdeps/loongarch/fstatat.c b/sysdeps/loongarch/fstatat.c +new file mode 100644 +index 00000000..0b0a3342 +--- /dev/null ++++ b/sysdeps/loongarch/fstatat.c +@@ -0,0 +1 @@ ++#include +diff --git a/sysdeps/loongarch/fstatat64.c b/sysdeps/loongarch/fstatat64.c +new file mode 100644 +index 00000000..e82b9274 +--- /dev/null ++++ b/sysdeps/loongarch/fstatat64.c +@@ -0,0 +1 @@ ++#include +diff --git a/sysdeps/loongarch/gccframe.h b/sysdeps/loongarch/gccframe.h +new file mode 100644 +index 00000000..5c799c64 +--- /dev/null ++++ b/sysdeps/loongarch/gccframe.h +@@ -0,0 +1,21 @@ ++/* Copyright (C) 2020-2021 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 ++ . */ ++ ++#define FIRST_PSEUDO_REGISTER 74 ++ ++#include +diff --git a/sysdeps/loongarch/hp-timing.h b/sysdeps/loongarch/hp-timing.h +new file mode 100644 +index 00000000..2d006540 +--- /dev/null ++++ b/sysdeps/loongarch/hp-timing.h +@@ -0,0 +1,40 @@ ++/* High precision, low overhead timing functions. x86-64 version. ++ Copyright (C) 2002-2018 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 ++ . */ ++ ++#ifndef _HP_TIMING_H ++#define _HP_TIMING_H 1 ++ ++/* We always assume having the timestamp register. */ ++#define HP_TIMING_AVAIL (1) ++#define HP_SMALL_TIMING_AVAIL (1) ++ ++/* We indeed have inlined functions. */ ++#define HP_TIMING_INLINE (1) ++ ++/* We use 64bit values for the times. */ ++typedef unsigned long long int hp_timing_t; ++ ++/* Read the cp0 count, this maybe inaccurate. */ ++#define HP_TIMING_NOW(Var) \ ++ ({ unsigned long long int _count; \ ++ asm volatile ("rdtime.d\t%0,$r0" : "=r" (_count)); \ ++ (Var) = _count; }) ++ ++#include ++ ++#endif /* hp-timing.h */ +diff --git a/sysdeps/loongarch/jmpbuf-offsets.h b/sysdeps/loongarch/jmpbuf-offsets.h +new file mode 100644 +index 00000000..bc4c1523 +--- /dev/null ++++ b/sysdeps/loongarch/jmpbuf-offsets.h +@@ -0,0 +1,23 @@ ++/* Copyright (C) 2020-2021 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 ++ . */ ++ ++#include ++ ++/* Helper for generic ____longjmp_chk(). */ ++#define JB_FRAME_ADDRESS(buf) \ ++ ((void *) _jmpbuf_sp (buf)) +diff --git a/sysdeps/loongarch/jmpbuf-unwind.h b/sysdeps/loongarch/jmpbuf-unwind.h +new file mode 100644 +index 00000000..c866d910 +--- /dev/null ++++ b/sysdeps/loongarch/jmpbuf-unwind.h +@@ -0,0 +1,46 @@ ++/* Copyright (C) 2020-2021 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 ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++/* Test if longjmp to JMPBUF would unwind the frame ++ containing a local variable at ADDRESS. */ ++#define _JMPBUF_UNWINDS(jmpbuf, address, demangle) \ ++ ((void *) (address) < (void *) demangle ((jmpbuf)[0].__sp)) ++ ++#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \ ++ _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj) ++ ++static inline uintptr_t __attribute__ ((unused)) ++_jmpbuf_sp (__jmp_buf regs) ++{ ++ uintptr_t sp = regs[0].__sp; ++#ifdef PTR_DEMANGLE ++ PTR_DEMANGLE (sp); ++#endif ++ return sp; ++} ++ ++#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \ ++ ((uintptr_t) (_address) - (_adj) < _jmpbuf_sp (_jmpbuf) - (_adj)) ++ ++/* We use the normal longjmp for unwinding. */ ++#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val) +diff --git a/sysdeps/loongarch/ldsodefs.h b/sysdeps/loongarch/ldsodefs.h +new file mode 100644 +index 00000000..60b6db58 +--- /dev/null ++++ b/sysdeps/loongarch/ldsodefs.h +@@ -0,0 +1,47 @@ ++/* Run-time dynamic linker data structures for loaded ELF shared objects. ++ Copyright (C) 2011-2018 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 ++ . */ ++ ++#ifndef _LOONGARCH_LDSODEFS_H ++#define _LOONGARCH_LDSODEFS_H 1 ++ ++#include ++ ++struct La_loongarch_regs; ++struct La_loongarch_retval; ++ ++#define ARCH_PLTENTER_MEMBERS \ ++ ElfW(Addr) (*loongarch_gnu_pltenter) (ElfW(Sym) *, unsigned int, \ ++ uintptr_t *, uintptr_t *, \ ++ const struct La_loongarch_regs *, \ ++ unsigned int *, const char *name, \ ++ long int *framesizep); ++ ++#define ARCH_PLTEXIT_MEMBERS \ ++ unsigned int (*loongarch_gnu_pltexit) (ElfW(Sym) *, unsigned int, \ ++ uintptr_t *, uintptr_t *, \ ++ const struct La_loongarch_regs *, \ ++ struct La_loongarch_retval *, \ ++ const char *); ++ ++/* The LoongArch ABI specifies that the dynamic section has to be read-only. */ ++ ++#define DL_RO_DYN_SECTION 1 ++ ++#include_next ++ ++#endif +diff --git a/sysdeps/loongarch/libc-start.h b/sysdeps/loongarch/libc-start.h +new file mode 100644 +index 00000000..d35ed85f +--- /dev/null ++++ b/sysdeps/loongarch/libc-start.h +@@ -0,0 +1,25 @@ ++ /* X86 definitions for libc main startup. ++ Copyright (C) 2018 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 ++ . */ ++ ++#ifndef SHARED ++# define ARCH_SETUP_IREL() ++# define ARCH_APPLY_IREL() apply_irel () ++# ifndef ARCH_SETUP_TLS ++# define ARCH_SETUP_TLS() __libc_setup_tls () ++# endif ++#endif /* !SHARED */ +diff --git a/sysdeps/loongarch/libc-tls.c b/sysdeps/loongarch/libc-tls.c +new file mode 100644 +index 00000000..0b0590d1 +--- /dev/null ++++ b/sysdeps/loongarch/libc-tls.c +@@ -0,0 +1,32 @@ ++/* Copyright (C) 2020-2021 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 ++ . */ ++ ++#include ++#include ++ ++/* On LoongArch, linker optimizations are not required, so __tls_get_addr ++ can be called even in statically linked binaries. In this case module ++ must be always 1 and PT_TLS segment exist in the binary, otherwise it ++ would not link. */ ++ ++void * ++__tls_get_addr (tls_index *ti) ++{ ++ dtv_t *dtv = THREAD_DTV (); ++ return (char *) dtv[1].pointer.val + GET_ADDR_OFFSET; ++} +diff --git a/sysdeps/loongarch/linkmap.h b/sysdeps/loongarch/linkmap.h +new file mode 100644 +index 00000000..ac170bb3 +--- /dev/null ++++ b/sysdeps/loongarch/linkmap.h +@@ -0,0 +1,4 @@ ++struct link_map_machine ++ { ++ ElfW(Addr) plt; /* Address of .plt. */ ++ }; +diff --git a/sysdeps/loongarch/lp64/Implies-after b/sysdeps/loongarch/lp64/Implies-after +new file mode 100644 +index 00000000..a8cae95f +--- /dev/null ++++ b/sysdeps/loongarch/lp64/Implies-after +@@ -0,0 +1 @@ ++wordsize-64 +diff --git a/sysdeps/loongarch/lp64/libm-test-ulps b/sysdeps/loongarch/lp64/libm-test-ulps +new file mode 100644 +index 00000000..61be2df6 +--- /dev/null ++++ b/sysdeps/loongarch/lp64/libm-test-ulps +@@ -0,0 +1,2206 @@ ++# Begin of automatic generation ++ ++# Maximal error of functions: ++Function: "acos": ++float: 1 ++ifloat: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "acos_downward": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "acos_towardzero": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "acos_upward": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "acosh": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: "acosh_downward": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 3 ++ldouble: 3 ++ ++Function: "acosh_towardzero": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: "acosh_upward": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: "asin": ++float: 1 ++ifloat: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "asin_downward": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 2 ++ldouble: 2 ++ ++Function: "asin_towardzero": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "asin_upward": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 2 ++ldouble: 2 ++ ++Function: "asinh": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 3 ++ldouble: 3 ++ ++Function: "asinh_downward": ++double: 3 ++float: 3 ++idouble: 3 ++ifloat: 3 ++ildouble: 4 ++ldouble: 4 ++ ++Function: "asinh_towardzero": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: "asinh_upward": ++double: 3 ++float: 3 ++idouble: 3 ++ifloat: 3 ++ildouble: 4 ++ldouble: 4 ++ ++Function: "atan": ++float: 1 ++ifloat: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "atan2": ++float: 1 ++ifloat: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "atan2_downward": ++double: 1 ++float: 2 ++idouble: 1 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: "atan2_towardzero": ++double: 1 ++float: 2 ++idouble: 1 ++ifloat: 2 ++ildouble: 3 ++ldouble: 3 ++ ++Function: "atan2_upward": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 2 ++ldouble: 2 ++ ++Function: "atan_downward": ++double: 1 ++float: 2 ++idouble: 1 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: "atan_towardzero": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "atan_upward": ++double: 1 ++float: 2 ++idouble: 1 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: "atanh": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 3 ++ldouble: 3 ++ ++Function: "atanh_downward": ++double: 3 ++float: 3 ++idouble: 3 ++ifloat: 3 ++ildouble: 4 ++ldouble: 4 ++ ++Function: "atanh_towardzero": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: "atanh_upward": ++double: 3 ++float: 3 ++idouble: 3 ++ifloat: 3 ++ildouble: 4 ++ldouble: 4 ++ ++Function: "cabs": ++double: 1 ++idouble: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "cabs_downward": ++double: 1 ++idouble: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "cabs_towardzero": ++double: 1 ++idouble: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "cabs_upward": ++double: 1 ++idouble: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: Real part of "cacos": ++double: 1 ++float: 2 ++idouble: 1 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Imaginary part of "cacos": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Real part of "cacos_downward": ++double: 3 ++float: 2 ++idouble: 3 ++ifloat: 2 ++ildouble: 3 ++ldouble: 3 ++ ++Function: Imaginary part of "cacos_downward": ++double: 5 ++float: 3 ++idouble: 5 ++ifloat: 3 ++ildouble: 6 ++ldouble: 6 ++ ++Function: Real part of "cacos_towardzero": ++double: 3 ++float: 2 ++idouble: 3 ++ifloat: 2 ++ildouble: 3 ++ldouble: 3 ++ ++Function: Imaginary part of "cacos_towardzero": ++double: 4 ++float: 2 ++idouble: 4 ++ifloat: 2 ++ildouble: 5 ++ldouble: 5 ++ ++Function: Real part of "cacos_upward": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 3 ++ldouble: 3 ++ ++Function: Imaginary part of "cacos_upward": ++double: 5 ++float: 5 ++idouble: 5 ++ifloat: 5 ++ildouble: 7 ++ldouble: 7 ++ ++Function: Real part of "cacosh": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Imaginary part of "cacosh": ++double: 1 ++float: 2 ++idouble: 1 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Real part of "cacosh_downward": ++double: 4 ++float: 2 ++idouble: 4 ++ifloat: 2 ++ildouble: 5 ++ldouble: 5 ++ ++Function: Imaginary part of "cacosh_downward": ++double: 3 ++float: 3 ++idouble: 3 ++ifloat: 3 ++ildouble: 4 ++ldouble: 4 ++ ++Function: Real part of "cacosh_towardzero": ++double: 4 ++float: 2 ++idouble: 4 ++ifloat: 2 ++ildouble: 5 ++ldouble: 5 ++ ++Function: Imaginary part of "cacosh_towardzero": ++double: 3 ++float: 2 ++idouble: 3 ++ifloat: 2 ++ildouble: 3 ++ldouble: 3 ++ ++Function: Real part of "cacosh_upward": ++double: 4 ++float: 3 ++idouble: 4 ++ifloat: 3 ++ildouble: 6 ++ldouble: 6 ++ ++Function: Imaginary part of "cacosh_upward": ++double: 3 ++float: 2 ++idouble: 3 ++ifloat: 2 ++ildouble: 4 ++ldouble: 4 ++ ++Function: "carg": ++float: 1 ++ifloat: 1 ++ildouble: 2 ++ldouble: 2 ++ ++Function: "carg_downward": ++double: 1 ++float: 2 ++idouble: 1 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: "carg_towardzero": ++double: 1 ++float: 2 ++idouble: 1 ++ifloat: 2 ++ildouble: 3 ++ldouble: 3 ++ ++Function: "carg_upward": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Real part of "casin": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Imaginary part of "casin": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Real part of "casin_downward": ++double: 3 ++float: 2 ++idouble: 3 ++ifloat: 2 ++ildouble: 3 ++ldouble: 3 ++ ++Function: Imaginary part of "casin_downward": ++double: 5 ++float: 3 ++idouble: 5 ++ifloat: 3 ++ildouble: 6 ++ldouble: 6 ++ ++Function: Real part of "casin_towardzero": ++double: 3 ++float: 1 ++idouble: 3 ++ifloat: 1 ++ildouble: 3 ++ldouble: 3 ++ ++Function: Imaginary part of "casin_towardzero": ++double: 4 ++float: 2 ++idouble: 4 ++ifloat: 2 ++ildouble: 5 ++ldouble: 5 ++ ++Function: Real part of "casin_upward": ++double: 3 ++float: 2 ++idouble: 3 ++ifloat: 2 ++ildouble: 3 ++ldouble: 3 ++ ++Function: Imaginary part of "casin_upward": ++double: 5 ++float: 5 ++idouble: 5 ++ifloat: 5 ++ildouble: 7 ++ldouble: 7 ++ ++Function: Real part of "casinh": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Imaginary part of "casinh": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Real part of "casinh_downward": ++double: 5 ++float: 3 ++idouble: 5 ++ifloat: 3 ++ildouble: 6 ++ldouble: 6 ++ ++Function: Imaginary part of "casinh_downward": ++double: 3 ++float: 2 ++idouble: 3 ++ifloat: 2 ++ildouble: 3 ++ldouble: 3 ++ ++Function: Real part of "casinh_towardzero": ++double: 4 ++float: 2 ++idouble: 4 ++ifloat: 2 ++ildouble: 5 ++ldouble: 5 ++ ++Function: Imaginary part of "casinh_towardzero": ++double: 3 ++float: 1 ++idouble: 3 ++ifloat: 1 ++ildouble: 3 ++ldouble: 3 ++ ++Function: Real part of "casinh_upward": ++double: 5 ++float: 5 ++idouble: 5 ++ifloat: 5 ++ildouble: 7 ++ldouble: 7 ++ ++Function: Imaginary part of "casinh_upward": ++double: 3 ++float: 2 ++idouble: 3 ++ifloat: 2 ++ildouble: 3 ++ldouble: 3 ++ ++Function: Real part of "catan": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: Imaginary part of "catan": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: Real part of "catan_downward": ++double: 1 ++float: 2 ++idouble: 1 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Imaginary part of "catan_downward": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Real part of "catan_towardzero": ++double: 1 ++float: 2 ++idouble: 1 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Imaginary part of "catan_towardzero": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Real part of "catan_upward": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Imaginary part of "catan_upward": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 3 ++ldouble: 3 ++ ++Function: Real part of "catanh": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: Imaginary part of "catanh": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: Real part of "catanh_downward": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Imaginary part of "catanh_downward": ++double: 1 ++float: 2 ++idouble: 1 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Real part of "catanh_towardzero": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Imaginary part of "catanh_towardzero": ++double: 1 ++float: 2 ++idouble: 1 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Real part of "catanh_upward": ++double: 4 ++float: 4 ++idouble: 4 ++ifloat: 4 ++ildouble: 4 ++ldouble: 4 ++ ++Function: Imaginary part of "catanh_upward": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 2 ++ldouble: 2 ++ ++Function: "cbrt": ++double: 3 ++float: 1 ++idouble: 3 ++ifloat: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "cbrt_downward": ++double: 4 ++float: 1 ++idouble: 4 ++ifloat: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "cbrt_towardzero": ++double: 3 ++float: 1 ++idouble: 3 ++ifloat: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "cbrt_upward": ++double: 5 ++float: 1 ++idouble: 5 ++ifloat: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: Real part of "ccos": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: Imaginary part of "ccos": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: Real part of "ccos_downward": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Imaginary part of "ccos_downward": ++double: 2 ++float: 3 ++idouble: 2 ++ifloat: 3 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Real part of "ccos_towardzero": ++double: 1 ++float: 2 ++idouble: 1 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Imaginary part of "ccos_towardzero": ++double: 2 ++float: 3 ++idouble: 2 ++ifloat: 3 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Real part of "ccos_upward": ++double: 1 ++float: 2 ++idouble: 1 ++ifloat: 2 ++ildouble: 3 ++ldouble: 3 ++ ++Function: Imaginary part of "ccos_upward": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Real part of "ccosh": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: Imaginary part of "ccosh": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: Real part of "ccosh_downward": ++double: 1 ++float: 2 ++idouble: 1 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Imaginary part of "ccosh_downward": ++double: 2 ++float: 3 ++idouble: 2 ++ifloat: 3 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Real part of "ccosh_towardzero": ++double: 1 ++float: 3 ++idouble: 1 ++ifloat: 3 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Imaginary part of "ccosh_towardzero": ++double: 2 ++float: 3 ++idouble: 2 ++ifloat: 3 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Real part of "ccosh_upward": ++double: 1 ++float: 2 ++idouble: 1 ++ifloat: 2 ++ildouble: 3 ++ldouble: 3 ++ ++Function: Imaginary part of "ccosh_upward": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Real part of "cexp": ++double: 2 ++float: 1 ++idouble: 2 ++ifloat: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: Imaginary part of "cexp": ++double: 1 ++float: 2 ++idouble: 1 ++ifloat: 2 ++ildouble: 1 ++ldouble: 1 ++ ++Function: Real part of "cexp_downward": ++double: 1 ++float: 2 ++idouble: 1 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Imaginary part of "cexp_downward": ++double: 1 ++float: 3 ++idouble: 1 ++ifloat: 3 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Real part of "cexp_towardzero": ++double: 1 ++float: 2 ++idouble: 1 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Imaginary part of "cexp_towardzero": ++double: 1 ++float: 3 ++idouble: 1 ++ifloat: 3 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Real part of "cexp_upward": ++double: 1 ++float: 2 ++idouble: 1 ++ifloat: 2 ++ildouble: 3 ++ldouble: 3 ++ ++Function: Imaginary part of "cexp_upward": ++double: 1 ++float: 2 ++idouble: 1 ++ifloat: 2 ++ildouble: 3 ++ldouble: 3 ++ ++Function: Real part of "clog": ++double: 3 ++float: 3 ++idouble: 3 ++ifloat: 3 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Imaginary part of "clog": ++float: 1 ++ifloat: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: Real part of "clog10": ++double: 3 ++float: 4 ++idouble: 3 ++ifloat: 4 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Imaginary part of "clog10": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Real part of "clog10_downward": ++double: 5 ++float: 5 ++idouble: 5 ++ifloat: 5 ++ildouble: 3 ++ldouble: 3 ++ ++Function: Imaginary part of "clog10_downward": ++double: 2 ++float: 4 ++idouble: 2 ++ifloat: 4 ++ildouble: 3 ++ldouble: 3 ++ ++Function: Real part of "clog10_towardzero": ++double: 5 ++float: 5 ++idouble: 5 ++ifloat: 5 ++ildouble: 4 ++ldouble: 4 ++ ++Function: Imaginary part of "clog10_towardzero": ++double: 2 ++float: 4 ++idouble: 2 ++ifloat: 4 ++ildouble: 3 ++ldouble: 3 ++ ++Function: Real part of "clog10_upward": ++double: 6 ++float: 5 ++idouble: 6 ++ifloat: 5 ++ildouble: 4 ++ldouble: 4 ++ ++Function: Imaginary part of "clog10_upward": ++double: 2 ++float: 4 ++idouble: 2 ++ifloat: 4 ++ildouble: 3 ++ldouble: 3 ++ ++Function: Real part of "clog_downward": ++double: 4 ++float: 3 ++idouble: 4 ++ifloat: 3 ++ildouble: 3 ++ldouble: 3 ++ ++Function: Imaginary part of "clog_downward": ++double: 1 ++float: 2 ++idouble: 1 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Real part of "clog_towardzero": ++double: 4 ++float: 4 ++idouble: 4 ++ifloat: 4 ++ildouble: 3 ++ldouble: 3 ++ ++Function: Imaginary part of "clog_towardzero": ++double: 1 ++float: 3 ++idouble: 1 ++ifloat: 3 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Real part of "clog_upward": ++double: 4 ++float: 3 ++idouble: 4 ++ifloat: 3 ++ildouble: 4 ++ldouble: 4 ++ ++Function: Imaginary part of "clog_upward": ++double: 1 ++float: 2 ++idouble: 1 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: "cos": ++double: 1 ++idouble: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "cos_downward": ++double: 1 ++idouble: 1 ++ildouble: 3 ++ldouble: 3 ++ ++Function: "cos_towardzero": ++double: 1 ++idouble: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "cos_upward": ++double: 1 ++idouble: 1 ++ildouble: 2 ++ldouble: 2 ++ ++Function: "cosh": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "cosh_downward": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 1 ++ldouble: 2 ++ ++Function: "cosh_towardzero": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 1 ++ldouble: 2 ++ ++Function: "cosh_upward": ++double: 1 ++float: 2 ++idouble: 1 ++ifloat: 2 ++ildouble: 1 ++ldouble: 3 ++ ++Function: Real part of "cpow": ++double: 2 ++float: 5 ++idouble: 2 ++ifloat: 5 ++ildouble: 4 ++ldouble: 4 ++ ++Function: Imaginary part of "cpow": ++float: 2 ++ifloat: 2 ++ildouble: 1 ++ldouble: 1 ++ ++Function: Real part of "cpow_downward": ++double: 4 ++float: 8 ++idouble: 4 ++ifloat: 8 ++ildouble: 6 ++ldouble: 6 ++ ++Function: Imaginary part of "cpow_downward": ++double: 1 ++float: 2 ++idouble: 1 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Real part of "cpow_towardzero": ++double: 4 ++float: 8 ++idouble: 4 ++ifloat: 8 ++ildouble: 6 ++ldouble: 6 ++ ++Function: Imaginary part of "cpow_towardzero": ++double: 1 ++float: 2 ++idouble: 1 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Real part of "cpow_upward": ++double: 4 ++float: 1 ++idouble: 4 ++ifloat: 1 ++ildouble: 3 ++ldouble: 3 ++ ++Function: Imaginary part of "cpow_upward": ++double: 1 ++float: 2 ++idouble: 1 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Real part of "csin": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: Imaginary part of "csin": ++ildouble: 1 ++ldouble: 1 ++ ++Function: Real part of "csin_downward": ++double: 2 ++float: 3 ++idouble: 2 ++ifloat: 3 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Imaginary part of "csin_downward": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Real part of "csin_towardzero": ++double: 2 ++float: 3 ++idouble: 2 ++ifloat: 3 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Imaginary part of "csin_towardzero": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Real part of "csin_upward": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Imaginary part of "csin_upward": ++double: 1 ++float: 2 ++idouble: 1 ++ifloat: 2 ++ildouble: 3 ++ldouble: 3 ++ ++Function: Real part of "csinh": ++float: 1 ++ifloat: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: Imaginary part of "csinh": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: Real part of "csinh_downward": ++double: 2 ++float: 1 ++idouble: 2 ++ifloat: 1 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Imaginary part of "csinh_downward": ++double: 2 ++float: 3 ++idouble: 2 ++ifloat: 3 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Real part of "csinh_towardzero": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Imaginary part of "csinh_towardzero": ++double: 2 ++float: 3 ++idouble: 2 ++ifloat: 3 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Real part of "csinh_upward": ++double: 1 ++float: 2 ++idouble: 1 ++ifloat: 2 ++ildouble: 3 ++ldouble: 3 ++ ++Function: Imaginary part of "csinh_upward": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Real part of "csqrt": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Imaginary part of "csqrt": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: Real part of "csqrt_downward": ++double: 5 ++float: 4 ++idouble: 5 ++ifloat: 4 ++ildouble: 4 ++ldouble: 4 ++ ++Function: Imaginary part of "csqrt_downward": ++double: 4 ++float: 3 ++idouble: 4 ++ifloat: 3 ++ildouble: 3 ++ldouble: 3 ++ ++Function: Real part of "csqrt_towardzero": ++double: 4 ++float: 3 ++idouble: 4 ++ifloat: 3 ++ildouble: 3 ++ldouble: 3 ++ ++Function: Imaginary part of "csqrt_towardzero": ++double: 4 ++float: 3 ++idouble: 4 ++ifloat: 3 ++ildouble: 3 ++ldouble: 3 ++ ++Function: Real part of "csqrt_upward": ++double: 5 ++float: 4 ++idouble: 5 ++ifloat: 4 ++ildouble: 4 ++ldouble: 4 ++ ++Function: Imaginary part of "csqrt_upward": ++double: 3 ++float: 3 ++idouble: 3 ++ifloat: 3 ++ildouble: 3 ++ldouble: 3 ++ ++Function: Real part of "ctan": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 3 ++ldouble: 3 ++ ++Function: Imaginary part of "ctan": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 3 ++ldouble: 3 ++ ++Function: Real part of "ctan_downward": ++double: 6 ++float: 5 ++idouble: 6 ++ifloat: 5 ++ildouble: 4 ++ldouble: 4 ++ ++Function: Imaginary part of "ctan_downward": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 5 ++ldouble: 5 ++ ++Function: Real part of "ctan_towardzero": ++double: 5 ++float: 2 ++idouble: 5 ++ifloat: 2 ++ildouble: 4 ++ldouble: 4 ++ ++Function: Imaginary part of "ctan_towardzero": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 5 ++ldouble: 5 ++ ++Function: Real part of "ctan_upward": ++double: 2 ++float: 4 ++idouble: 2 ++ifloat: 4 ++ildouble: 5 ++ldouble: 5 ++ ++Function: Imaginary part of "ctan_upward": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 5 ++ldouble: 5 ++ ++Function: Real part of "ctanh": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 3 ++ldouble: 3 ++ ++Function: Imaginary part of "ctanh": ++double: 2 ++float: 1 ++idouble: 2 ++ifloat: 1 ++ildouble: 3 ++ldouble: 3 ++ ++Function: Real part of "ctanh_downward": ++double: 4 ++float: 2 ++idouble: 4 ++ifloat: 2 ++ildouble: 5 ++ldouble: 5 ++ ++Function: Imaginary part of "ctanh_downward": ++double: 6 ++float: 5 ++idouble: 6 ++ifloat: 5 ++ildouble: 4 ++ldouble: 4 ++ ++Function: Real part of "ctanh_towardzero": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 5 ++ldouble: 5 ++ ++Function: Imaginary part of "ctanh_towardzero": ++double: 5 ++float: 2 ++idouble: 5 ++ifloat: 2 ++ildouble: 3 ++ldouble: 3 ++ ++Function: Real part of "ctanh_upward": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 5 ++ldouble: 5 ++ ++Function: Imaginary part of "ctanh_upward": ++double: 2 ++float: 3 ++idouble: 2 ++ifloat: 3 ++ildouble: 5 ++ldouble: 5 ++ ++Function: "erf": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "erf_downward": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 2 ++ldouble: 2 ++ ++Function: "erf_towardzero": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "erf_upward": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 2 ++ldouble: 2 ++ ++Function: "erfc": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: "erfc_downward": ++double: 3 ++float: 4 ++idouble: 3 ++ifloat: 4 ++ildouble: 5 ++ldouble: 5 ++ ++Function: "erfc_towardzero": ++double: 3 ++float: 3 ++idouble: 3 ++ifloat: 3 ++ildouble: 4 ++ldouble: 4 ++ ++Function: "erfc_upward": ++double: 3 ++float: 4 ++idouble: 3 ++ifloat: 4 ++ildouble: 5 ++ldouble: 5 ++ ++Function: "exp": ++ildouble: 1 ++ldouble: 1 ++ ++Function: "exp10": ++double: 2 ++idouble: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: "exp10_downward": ++double: 2 ++float: 1 ++idouble: 2 ++ifloat: 1 ++ildouble: 3 ++ldouble: 3 ++ ++Function: "exp10_towardzero": ++double: 2 ++float: 1 ++idouble: 2 ++ifloat: 1 ++ildouble: 3 ++ldouble: 3 ++ ++Function: "exp10_upward": ++double: 2 ++float: 1 ++idouble: 2 ++ifloat: 1 ++ildouble: 3 ++ldouble: 3 ++ ++Function: "exp2": ++double: 1 ++idouble: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "exp2_downward": ++double: 1 ++idouble: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "exp2_towardzero": ++double: 1 ++idouble: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "exp2_upward": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 2 ++ldouble: 2 ++ ++Function: "exp_downward": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ ++Function: "exp_towardzero": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ ++Function: "exp_upward": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ ++Function: "expm1": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "expm1_downward": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 2 ++ldouble: 2 ++ ++Function: "expm1_towardzero": ++double: 1 ++float: 2 ++idouble: 1 ++ifloat: 2 ++ildouble: 4 ++ldouble: 4 ++ ++Function: "expm1_upward": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 3 ++ldouble: 3 ++ ++Function: "gamma": ++double: 3 ++float: 3 ++idouble: 3 ++ifloat: 3 ++ildouble: 5 ++ldouble: 5 ++ ++Function: "gamma_downward": ++double: 4 ++float: 4 ++idouble: 4 ++ifloat: 4 ++ildouble: 8 ++ldouble: 8 ++ ++Function: "gamma_towardzero": ++double: 4 ++float: 3 ++idouble: 4 ++ifloat: 3 ++ildouble: 5 ++ldouble: 5 ++ ++Function: "gamma_upward": ++double: 4 ++float: 5 ++idouble: 4 ++ifloat: 5 ++ildouble: 8 ++ldouble: 8 ++ ++Function: "hypot": ++double: 1 ++idouble: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "hypot_downward": ++double: 1 ++idouble: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "hypot_towardzero": ++double: 1 ++idouble: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "hypot_upward": ++double: 1 ++idouble: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "j0": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: "j0_downward": ++double: 2 ++float: 4 ++idouble: 2 ++ifloat: 4 ++ildouble: 4 ++ldouble: 4 ++ ++Function: "j0_towardzero": ++double: 2 ++float: 1 ++idouble: 2 ++ifloat: 1 ++ildouble: 2 ++ldouble: 2 ++ ++Function: "j0_upward": ++double: 3 ++float: 2 ++idouble: 3 ++ifloat: 2 ++ildouble: 5 ++ldouble: 5 ++ ++Function: "j1": ++double: 1 ++float: 2 ++idouble: 1 ++ifloat: 2 ++ildouble: 4 ++ldouble: 4 ++ ++Function: "j1_downward": ++double: 3 ++float: 2 ++idouble: 3 ++ifloat: 2 ++ildouble: 4 ++ldouble: 4 ++ ++Function: "j1_towardzero": ++double: 3 ++float: 2 ++idouble: 3 ++ifloat: 2 ++ildouble: 4 ++ldouble: 4 ++ ++Function: "j1_upward": ++double: 3 ++float: 4 ++idouble: 3 ++ifloat: 4 ++ildouble: 3 ++ldouble: 3 ++ ++Function: "jn": ++double: 4 ++float: 4 ++idouble: 4 ++ifloat: 4 ++ildouble: 7 ++ldouble: 7 ++ ++Function: "jn_downward": ++double: 4 ++float: 5 ++idouble: 4 ++ifloat: 5 ++ildouble: 8 ++ldouble: 8 ++ ++Function: "jn_towardzero": ++double: 4 ++float: 5 ++idouble: 4 ++ifloat: 5 ++ildouble: 8 ++ldouble: 8 ++ ++Function: "jn_upward": ++double: 5 ++float: 4 ++idouble: 5 ++ifloat: 4 ++ildouble: 7 ++ldouble: 7 ++ ++Function: "lgamma": ++double: 3 ++float: 3 ++idouble: 3 ++ifloat: 3 ++ildouble: 5 ++ldouble: 5 ++ ++Function: "lgamma_downward": ++double: 4 ++float: 4 ++idouble: 4 ++ifloat: 4 ++ildouble: 8 ++ldouble: 8 ++ ++Function: "lgamma_towardzero": ++double: 4 ++float: 3 ++idouble: 4 ++ifloat: 3 ++ildouble: 5 ++ldouble: 5 ++ ++Function: "lgamma_upward": ++double: 4 ++float: 5 ++idouble: 4 ++ifloat: 5 ++ildouble: 8 ++ldouble: 8 ++ ++Function: "log": ++ildouble: 1 ++ldouble: 1 ++ ++Function: "log10": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "log10_downward": ++double: 2 ++float: 3 ++idouble: 2 ++ifloat: 3 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "log10_towardzero": ++double: 2 ++float: 1 ++idouble: 2 ++ifloat: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "log10_upward": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "log1p": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 2 ++ldouble: 2 ++ ++Function: "log1p_downward": ++double: 1 ++float: 2 ++idouble: 1 ++ifloat: 2 ++ildouble: 3 ++ldouble: 3 ++ ++Function: "log1p_towardzero": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 3 ++ldouble: 3 ++ ++Function: "log1p_upward": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: "log2": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 2 ++ldouble: 2 ++ ++Function: "log2_downward": ++double: 3 ++idouble: 3 ++ildouble: 3 ++ldouble: 3 ++ ++Function: "log2_towardzero": ++double: 2 ++idouble: 2 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "log2_upward": ++double: 3 ++idouble: 3 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "log_downward": ++ildouble: 1 ++ldouble: 1 ++ ++Function: "log_towardzero": ++ildouble: 2 ++ldouble: 2 ++ ++Function: "log_upward": ++double: 1 ++idouble: 1 ++ildouble: 2 ++ldouble: 2 ++ ++Function: "pow": ++double: 1 ++idouble: 1 ++ildouble: 2 ++ldouble: 2 ++ ++Function: "pow_downward": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 2 ++ldouble: 2 ++ ++Function: "pow_towardzero": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 2 ++ldouble: 2 ++ ++Function: "pow_upward": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 2 ++ldouble: 2 ++ ++Function: "sin": ++double: 1 ++idouble: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "sin_downward": ++double: 1 ++idouble: 1 ++ildouble: 3 ++ldouble: 3 ++ ++Function: "sin_towardzero": ++double: 1 ++idouble: 1 ++ildouble: 2 ++ldouble: 2 ++ ++Function: "sin_upward": ++double: 1 ++idouble: 1 ++ildouble: 3 ++ldouble: 3 ++ ++Function: "sincos": ++double: 1 ++idouble: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "sincos_downward": ++double: 1 ++idouble: 1 ++ildouble: 3 ++ldouble: 3 ++ ++Function: "sincos_towardzero": ++double: 1 ++idouble: 1 ++ildouble: 2 ++ldouble: 2 ++ ++Function: "sincos_upward": ++double: 1 ++idouble: 1 ++ildouble: 3 ++ldouble: 3 ++ ++Function: "sinh": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: "sinh_downward": ++double: 3 ++float: 3 ++idouble: 3 ++ifloat: 3 ++ildouble: 3 ++ldouble: 3 ++ ++Function: "sinh_towardzero": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 3 ++ldouble: 3 ++ ++Function: "sinh_upward": ++double: 3 ++float: 3 ++idouble: 3 ++ifloat: 3 ++ildouble: 4 ++ldouble: 4 ++ ++Function: "tan": ++float: 1 ++ifloat: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "tan_downward": ++double: 1 ++float: 2 ++idouble: 1 ++ifloat: 2 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "tan_towardzero": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "tan_upward": ++double: 1 ++float: 1 ++idouble: 1 ++ifloat: 1 ++ildouble: 1 ++ldouble: 1 ++ ++Function: "tanh": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: "tanh_downward": ++double: 3 ++float: 3 ++idouble: 3 ++ifloat: 3 ++ildouble: 4 ++ldouble: 4 ++ ++Function: "tanh_towardzero": ++double: 2 ++float: 2 ++idouble: 2 ++ifloat: 2 ++ildouble: 3 ++ldouble: 3 ++ ++Function: "tanh_upward": ++double: 3 ++float: 3 ++idouble: 3 ++ifloat: 3 ++ildouble: 3 ++ldouble: 3 ++ ++Function: "tgamma": ++double: 5 ++float: 4 ++idouble: 5 ++ifloat: 4 ++ildouble: 4 ++ldouble: 4 ++ ++Function: "tgamma_downward": ++double: 5 ++float: 5 ++idouble: 5 ++ifloat: 5 ++ildouble: 5 ++ldouble: 5 ++ ++Function: "tgamma_towardzero": ++double: 5 ++float: 4 ++idouble: 5 ++ifloat: 4 ++ildouble: 5 ++ldouble: 5 ++ ++Function: "tgamma_upward": ++double: 4 ++float: 4 ++idouble: 4 ++ifloat: 4 ++ildouble: 4 ++ldouble: 4 ++ ++Function: "y0": ++double: 2 ++float: 1 ++idouble: 2 ++ifloat: 1 ++ildouble: 3 ++ldouble: 3 ++ ++Function: "y0_downward": ++double: 3 ++float: 4 ++idouble: 3 ++ifloat: 4 ++ildouble: 4 ++ldouble: 4 ++ ++Function: "y0_towardzero": ++double: 3 ++float: 3 ++idouble: 3 ++ifloat: 3 ++ildouble: 3 ++ldouble: 3 ++ ++Function: "y0_upward": ++double: 2 ++float: 5 ++idouble: 2 ++ifloat: 5 ++ildouble: 3 ++ldouble: 3 ++ ++Function: "y1": ++double: 3 ++float: 2 ++idouble: 3 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: "y1_downward": ++double: 3 ++float: 2 ++idouble: 3 ++ifloat: 2 ++ildouble: 4 ++ldouble: 4 ++ ++Function: "y1_towardzero": ++double: 3 ++float: 2 ++idouble: 3 ++ifloat: 2 ++ildouble: 2 ++ldouble: 2 ++ ++Function: "y1_upward": ++double: 5 ++float: 2 ++idouble: 5 ++ifloat: 2 ++ildouble: 5 ++ldouble: 5 ++ ++Function: "yn": ++double: 3 ++float: 3 ++idouble: 3 ++ifloat: 3 ++ildouble: 5 ++ldouble: 5 ++ ++Function: "yn_downward": ++double: 3 ++float: 4 ++idouble: 3 ++ifloat: 4 ++ildouble: 5 ++ldouble: 5 ++ ++Function: "yn_towardzero": ++double: 3 ++float: 3 ++idouble: 3 ++ifloat: 3 ++ildouble: 5 ++ldouble: 5 ++ ++Function: "yn_upward": ++double: 4 ++float: 5 ++idouble: 4 ++ifloat: 5 ++ildouble: 5 ++ldouble: 5 ++ ++# end of automatic generation +diff --git a/sysdeps/loongarch/lp64/libm-test-ulps-name b/sysdeps/loongarch/lp64/libm-test-ulps-name +new file mode 100644 +index 00000000..ce02281e +--- /dev/null ++++ b/sysdeps/loongarch/lp64/libm-test-ulps-name +@@ -0,0 +1 @@ ++LoongArch 64-bit +diff --git a/sysdeps/loongarch/lp64/memcpy.S b/sysdeps/loongarch/lp64/memcpy.S +new file mode 100644 +index 00000000..2dc7a779 +--- /dev/null ++++ b/sysdeps/loongarch/lp64/memcpy.S +@@ -0,0 +1,402 @@ ++#ifdef _LIBC ++#include ++#include ++#include ++#else ++#include ++#include ++#endif ++ ++/* Allow the routine to be named something else if desired. */ ++#ifndef MEMCPY_NAME ++#define MEMCPY_NAME memcpy ++#endif ++ ++#define LD_64(reg, n) \ ++ ld.d t0, reg, n; \ ++ ld.d t1, reg, n+8; \ ++ ld.d t2, reg, n+16; \ ++ ld.d t3, reg, n+24; \ ++ ld.d t4, reg, n+32; \ ++ ld.d t5, reg, n+40; \ ++ ld.d t6, reg, n+48; \ ++ ld.d t7, reg, n+56; ++ ++ ++#define ST_64(reg, n) \ ++ st.d t0, reg, n; \ ++ st.d t1, reg, n+8; \ ++ st.d t2, reg, n+16; \ ++ st.d t3, reg, n+24; \ ++ st.d t4, reg, n+32; \ ++ st.d t5, reg, n+40; \ ++ st.d t6, reg, n+48; \ ++ st.d t7, reg, n+56; ++ ++#define LDST_1024 \ ++ LD_64(a1, 0); \ ++ ST_64(a0, 0); \ ++ LD_64(a1, 64); \ ++ ST_64(a0, 64); \ ++ LD_64(a1, 128); \ ++ ST_64(a0, 128); \ ++ LD_64(a1, 192); \ ++ ST_64(a0, 192); \ ++ LD_64(a1, 256); \ ++ ST_64(a0, 256); \ ++ LD_64(a1, 320); \ ++ ST_64(a0, 320); \ ++ LD_64(a1, 384); \ ++ ST_64(a0, 384); \ ++ LD_64(a1, 448); \ ++ ST_64(a0, 448); \ ++ LD_64(a1, 512); \ ++ ST_64(a0, 512); \ ++ LD_64(a1, 576); \ ++ ST_64(a0, 576); \ ++ LD_64(a1, 640); \ ++ ST_64(a0, 640); \ ++ LD_64(a1, 704); \ ++ ST_64(a0, 704); \ ++ LD_64(a1, 768); \ ++ ST_64(a0, 768); \ ++ LD_64(a1, 832); \ ++ ST_64(a0, 832); \ ++ LD_64(a1, 896); \ ++ ST_64(a0, 896); \ ++ LD_64(a1, 960); \ ++ ST_64(a0, 960); ++ ++#ifdef ANDROID_CHANGES ++LEAF(MEMCPY_NAME, 0) ++#else ++LEAF(MEMCPY_NAME) ++#endif ++ ++//1st var: dest ptr: void *str1 $r4 ++//2nd var: src ptr: void *str2 $r5 ++//3rd var: size_t num ++//t0~t9 registers as temp ++ ++ add.d a4, a1, a2 ++ add.d a3, a0, a2 ++ move t8, a0 ++ move a5, a1 ++ srai.d a6, a2, 4 #num/16 ++ beqz a6, less_16bytes #num<16 ++ slti a6, a2, 137 ++ beqz a6, more_137bytes #num>137 ++ srai.d a6, a2, 6 ++ beqz a6, less_64bytes #num<64 ++ ++ srli.d a0, a0, 3 ++ slli.d a0, a0, 3 ++ addi.d a0, a0, 0x8 ++ sub.d a7, t8, a0 ++ ld.d t0, a1, 0 ++ sub.d a1, a1, a7 ++ st.d t0, t8, 0 ++ ++ add.d a7, a7, a2 ++ addi.d a7, a7, -0x20 ++loop_32: ++ ld.d t0, a1, 0 ++ ld.d t1, a1, 8 ++ ld.d t2, a1, 16 ++ ld.d t3, a1, 24 ++ st.d t0, a0, 0 ++ st.d t1, a0, 8 ++ st.d t2, a0, 16 ++ st.d t3, a0, 24 ++ ++ addi.d a0, a0, 0x20 ++ addi.d a1, a1, 0x20 ++ addi.d a7, a7, -0x20 ++ blt zero, a7, loop_32 ++ ++ ld.d t4, a4, -32 ++ ld.d t5, a4, -24 ++ ld.d t6, a4, -16 ++ ld.d t7, a4, -8 ++ st.d t4, a3, -32 ++ st.d t5, a3, -24 ++ st.d t6, a3, -16 ++ st.d t7, a3, -8 ++ ++ move v0, t8 ++ jr ra ++ ++less_64bytes: ++ srai.d a6, a2, 5 ++ beqz a6, less_32bytes ++ ++ ld.d t0, a1, 0 ++ ld.d t1, a1, 8 ++ ld.d t2, a1, 16 ++ ld.d t3, a1, 24 ++ ld.d t4, a4, -32 ++ ld.d t5, a4, -24 ++ ld.d t6, a4, -16 ++ ld.d t7, a4, -8 ++ st.d t0, a0, 0 ++ st.d t1, a0, 8 ++ st.d t2, a0, 16 ++ st.d t3, a0, 24 ++ st.d t4, a3, -32 ++ st.d t5, a3, -24 ++ st.d t6, a3, -16 ++ st.d t7, a3, -8 ++ ++ jr ra ++ ++less_32bytes: ++ ld.d t0, a1, 0 ++ ld.d t1, a1, 8 ++ ld.d t2, a4, -16 ++ ld.d t3, a4, -8 ++ st.d t0, a0, 0 ++ st.d t1, a0, 8 ++ st.d t2, a3, -16 ++ st.d t3, a3, -8 ++ ++ jr ra ++ ++less_16bytes: ++ srai.d a6, a2, 3 #num/8 ++ beqz a6, less_8bytes ++ ++ ld.d t0, a1, 0 ++ ld.d t1, a4, -8 ++ st.d t0, a0, 0 ++ st.d t1, a3, -8 ++ ++ jr ra ++ ++less_8bytes: ++ srai.d a6, a2, 2 ++ beqz a6, less_4bytes ++ ++ ld.w t0, a1, 0 ++ ld.w t1, a4, -4 ++ st.w t0, a0, 0 ++ st.w t1, a3, -4 ++ ++ jr ra ++ ++less_4bytes: ++ srai.d a6, a2, 1 ++ beqz a6, less_2bytes ++ ++ ld.h t0, a1, 0 ++ ld.h t1, a4, -2 ++ st.h t0, a0, 0 ++ st.h t1, a3, -2 ++ ++ jr ra ++ ++less_2bytes: ++ beqz a2, less_1bytes ++ ++ ld.b t0, a1, 0 ++ st.b t0, a0, 0 ++ ++ jr ra ++ ++less_1bytes: ++ jr ra ++ ++more_137bytes: ++ li.w a6, 64 ++ andi t1, a0, 7 ++ srli.d a0, a0, 3 ++ andi t2, a2, 7 ++ slli.d a0, a0, 3 ++ add.d t1, t1, t2 ++ beqz t1, all_align ++ beq a0, t8, start_over ++ addi.d a0, a0, 0x8 ++ sub.d a7, t8, a0 ++ sub.d a1, a1, a7 ++ add.d a2, a7, a2 ++ ++start_unalign_proc: ++ ld.d t0, a5, 0 ++ slli.d t0, t0, 8 ++ pcaddi t1, 18 ++ slli.d t2, a7, 3 ++ add.d t1, t1, t2 ++ jirl zero, t1, 0 ++ ++start_7_unalign: ++ srli.d t0, t0, 8 ++ st.b t0, a0, -7 ++start_6_unalign: ++ srli.d t0, t0, 8 ++ st.b t0, a0, -6 ++start_5_unalign: ++ srli.d t0, t0, 8 ++ st.b t0, a0, -5 ++start_4_unalign: ++ srli.d t0, t0, 8 ++ st.b t0, a0, -4 ++start_3_unalign: ++ srli.d t0, t0, 8 ++ st.b t0, a0, -3 ++start_2_unalign: ++ srli.d t0, t0, 8 ++ st.b t0, a0, -2 ++start_1_unalign: ++ srli.d t0, t0, 8 ++ st.b t0, a0, -1 ++start_over: ++ ++ addi.d a2, a2, -0x80 ++ blt a2, zero, end_unalign_proc ++ ++loop_less: ++ LD_64(a1, 0) ++ ST_64(a0, 0) ++ LD_64(a1, 64) ++ ST_64(a0, 64) ++ ++ addi.d a0, a0, 0x80 ++ addi.d a1, a1, 0x80 ++ addi.d a2, a2, -0x80 ++ bge a2, zero, loop_less ++ ++end_unalign_proc: ++ addi.d a2, a2, 0x80 ++ ++ pcaddi t1, 34 ++ andi t2, a2, 0x78 ++ sub.d t1, t1, t2 ++ jirl zero, t1, 0 ++ ++end_120_128_unalign: ++ ld.d t0, a1, 112 ++ st.d t0, a0, 112 ++end_112_120_unalign: ++ ld.d t0, a1, 104 ++ st.d t0, a0, 104 ++end_104_112_unalign: ++ ld.d t0, a1, 96 ++ st.d t0, a0, 96 ++end_96_104_unalign: ++ ld.d t0, a1, 88 ++ st.d t0, a0, 88 ++end_88_96_unalign: ++ ld.d t0, a1, 80 ++ st.d t0, a0, 80 ++end_80_88_unalign: ++ ld.d t0, a1, 72 ++ st.d t0, a0, 72 ++end_72_80_unalign: ++ ld.d t0, a1, 64 ++ st.d t0, a0, 64 ++end_64_72_unalign: ++ ld.d t0, a1, 56 ++ st.d t0, a0, 56 ++end_56_64_unalign: ++ ld.d t0, a1, 48 ++ st.d t0, a0, 48 ++end_48_56_unalign: ++ ld.d t0, a1, 40 ++ st.d t0, a0, 40 ++end_40_48_unalign: ++ ld.d t0, a1, 32 ++ st.d t0, a0, 32 ++end_32_40_unalign: ++ ld.d t0, a1, 24 ++ st.d t0, a0, 24 ++end_24_32_unalign: ++ ld.d t0, a1, 16 ++ st.d t0, a0, 16 ++end_16_24_unalign: ++ ld.d t0, a1, 8 ++ st.d t0, a0, 8 ++end_8_16_unalign: ++ ld.d t0, a1, 0 ++ st.d t0, a0, 0 ++end_0_8_unalign: ++ ++ mod.d t0, a3, a6 ++ srli.d t1, t0, 3 ++ slti t0, t0, 1 ++ add.d t0, t0, t1 ++ blt zero, t0, end_8_without_cross_cache_line ++ ++ andi a2, a2, 0x7 ++ pcaddi t1, 18 ++ slli.d a2, a2, 3 ++ sub.d t1, t1, a2 ++ jirl zero, t1, 0 ++ ++end_7_unalign: ++ ld.b t0, a4, -7 ++ st.b t0, a3, -7 ++end_6_unalign: ++ ld.b t0, a4, -6 ++ st.b t0, a3, -6 ++end_5_unalign: ++ ld.b t0, a4, -5 ++ st.b t0, a3, -5 ++end_4_unalign: ++ ld.b t0, a4, -4 ++ st.b t0, a3, -4 ++end_3_unalign: ++ ld.b t0, a4, -3 ++ st.b t0, a3, -3 ++end_2_unalign: ++ ld.b t0, a4, -2 ++ st.b t0, a3, -2 ++end_1_unalign: ++ ld.b t0, a4, -1 ++ st.b t0, a3, -1 ++end: ++ ++ move v0, t8 ++ jr ra ++ ++all_align: ++ addi.d a2, a2, -0x20 ++ ++align_loop_less: ++ ld.d t0, a1, 0 ++ ld.d t1, a1, 8 ++ ld.d t2, a1, 16 ++ ld.d t3, a1, 24 ++ st.d t0, a0, 0 ++ st.d t1, a0, 8 ++ st.d t2, a0, 16 ++ st.d t3, a0, 24 ++ ++ addi.d a0, a0, 0x20 ++ addi.d a1, a1, 0x20 ++ addi.d a2, a2, -0x20 ++ blt zero, a2, align_loop_less ++ ++ ld.d t4, a4, -32 ++ ld.d t5, a4, -24 ++ ld.d t6, a4, -16 ++ ld.d t7, a4, -8 ++ st.d t4, a3, -32 ++ st.d t5, a3, -24 ++ st.d t6, a3, -16 ++ st.d t7, a3, -8 ++ ++ move v0, t8 ++ jr ra ++ ++end_8_without_cross_cache_line: ++ ld.d t0, a4, -8 ++ st.d t0, a3, -8 ++ ++ move v0, t8 ++ jr ra ++ ++END(MEMCPY_NAME) ++#ifndef ANDROID_CHANGES ++#ifdef _LIBC ++libc_hidden_builtin_def (MEMCPY_NAME) ++#endif ++#endif +diff --git a/sysdeps/loongarch/lp64/memmove.S b/sysdeps/loongarch/lp64/memmove.S +new file mode 100644 +index 00000000..f87d036b +--- /dev/null ++++ b/sysdeps/loongarch/lp64/memmove.S +@@ -0,0 +1,476 @@ ++#ifdef _LIBC ++#include ++#include ++#include ++#else ++#include ++#include ++#endif ++ ++/* Allow the routine to be named something else if desired. */ ++#ifndef MEMMOVE_NAME ++#define MEMMOVE_NAME memmove ++#endif ++ ++#define LD_64(reg, n) \ ++ ld.d t0, reg, n; \ ++ ld.d t1, reg, n+8; \ ++ ld.d t2, reg, n+16; \ ++ ld.d t3, reg, n+24; \ ++ ld.d t4, reg, n+32; \ ++ ld.d t5, reg, n+40; \ ++ ld.d t6, reg, n+48; \ ++ ld.d t7, reg, n+56; ++ ++ ++#define ST_64(reg, n) \ ++ st.d t0, reg, n; \ ++ st.d t1, reg, n+8; \ ++ st.d t2, reg, n+16; \ ++ st.d t3, reg, n+24; \ ++ st.d t4, reg, n+32; \ ++ st.d t5, reg, n+40; \ ++ st.d t6, reg, n+48; \ ++ st.d t7, reg, n+56; ++ ++#define LDST_1024 \ ++ LD_64(a1, 0); \ ++ ST_64(a0, 0); \ ++ LD_64(a1, 64); \ ++ ST_64(a0, 64); \ ++ LD_64(a1, 128); \ ++ ST_64(a0, 128); \ ++ LD_64(a1, 192); \ ++ ST_64(a0, 192); \ ++ LD_64(a1, 256); \ ++ ST_64(a0, 256); \ ++ LD_64(a1, 320); \ ++ ST_64(a0, 320); \ ++ LD_64(a1, 384); \ ++ ST_64(a0, 384); \ ++ LD_64(a1, 448); \ ++ ST_64(a0, 448); \ ++ LD_64(a1, 512); \ ++ ST_64(a0, 512); \ ++ LD_64(a1, 576); \ ++ ST_64(a0, 576); \ ++ LD_64(a1, 640); \ ++ ST_64(a0, 640); \ ++ LD_64(a1, 704); \ ++ ST_64(a0, 704); \ ++ LD_64(a1, 768); \ ++ ST_64(a0, 768); \ ++ LD_64(a1, 832); \ ++ ST_64(a0, 832); \ ++ LD_64(a1, 896); \ ++ ST_64(a0, 896); \ ++ LD_64(a1, 960); \ ++ ST_64(a0, 960); ++ ++#define LDST_1024_BACK \ ++ LD_64(a4, -64); \ ++ ST_64(a3, -64); \ ++ LD_64(a4, -128); \ ++ ST_64(a3, -128); \ ++ LD_64(a4, -192); \ ++ ST_64(a3, -192); \ ++ LD_64(a4, -256); \ ++ ST_64(a3, -256); \ ++ LD_64(a4, -320); \ ++ ST_64(a3, -320); \ ++ LD_64(a4, -384); \ ++ ST_64(a3, -384); \ ++ LD_64(a4, -448); \ ++ ST_64(a3, -448); \ ++ LD_64(a4, -512); \ ++ ST_64(a3, -512); \ ++ LD_64(a4, -576); \ ++ ST_64(a3, -576); \ ++ LD_64(a4, -640); \ ++ ST_64(a3, -640); \ ++ LD_64(a4, -704); \ ++ ST_64(a3, -704); \ ++ LD_64(a4, -768); \ ++ ST_64(a3, -768); \ ++ LD_64(a4, -832); \ ++ ST_64(a3, -832); \ ++ LD_64(a4, -896); \ ++ ST_64(a3, -896); \ ++ LD_64(a4, -960); \ ++ ST_64(a3, -960); \ ++ LD_64(a4, -1024); \ ++ ST_64(a3, -1024); ++ ++#ifdef ANDROID_CHANGES ++LEAF(MEMMOVE_NAME, 0) ++#else ++LEAF(MEMMOVE_NAME) ++#endif ++ ++//1st var: dest ptr: void *str1 $r4 a0 ++//2nd var: src ptr: void *str2 $r5 a1 ++//3rd var: size_t num ++//t0~t9 registers as temp ++ ++ add.d a4, a1, a2 ++ add.d a3, a0, a2 ++ beq a1, a0, less_1bytes ++ move t8, a0 ++ srai.d a6, a2, 4 #num/16 ++ beqz a6, less_16bytes #num<16 ++ srai.d a6, a2, 6 #num/64 ++ bnez a6, more_64bytes #num>64 ++ srai.d a6, a2, 5 ++ beqz a6, less_32bytes #num<32 ++ ++ ld.d t0, a1, 0 #32 ++#include ++#include ++#else ++#include ++#include ++#endif ++ ++#ifdef LOONGSON_TEST ++#define MEMSET _memset ++#else ++#define MEMSET memset ++#endif ++ ++#define ST_128(n) \ ++ st.d a1, a0, n; \ ++ st.d a1, a0, n+8 ; \ ++ st.d a1, a0, n+16 ; \ ++ st.d a1, a0, n+24 ; \ ++ st.d a1, a0, n+32 ; \ ++ st.d a1, a0, n+40 ; \ ++ st.d a1, a0, n+48 ; \ ++ st.d a1, a0, n+56 ; \ ++ st.d a1, a0, n+64 ; \ ++ st.d a1, a0, n+72 ; \ ++ st.d a1, a0, n+80 ; \ ++ st.d a1, a0, n+88 ; \ ++ st.d a1, a0, n+96 ; \ ++ st.d a1, a0, n+104; \ ++ st.d a1, a0, n+112; \ ++ st.d a1, a0, n+120; \ ++ ++//1st var: void *str $4 a0 ++//2nd var: int val $5 a1 ++//3rd var: size_t num $6 a2 ++ ++LEAF(MEMSET) ++ ++memset: ++ .align 6 ++ ++ bstrins.d a1, a1, 15, 8 ++ add.d t7, a0, a2 ++ bstrins.d a1, a1, 31, 16 ++ move t0, a0 ++ bstrins.d a1, a1, 63, 32 ++ srai.d t8, a2, 4 #num/16 ++ beqz t8, less_16bytes #num<16 ++ srai.d t8, a2, 6 #num/64 ++ bnez t8, more_64bytes #num>64 ++ srai.d t8, a2, 5 #num/32 ++ beqz t8, less_32bytes #num<32 ++ st.d a1, a0, 0 #32 ++#include ++#include ++ ++/* Short algorithm description: ++ * ++ * 1) if |x|==0: sin(x)=x, ++ * cos(x)=1. ++ * 2) if |x|<2^-27: sin(x)=x-x*DP_SMALL, raising underflow only when needed, ++ * cos(x)=1-|x|. ++ * 3) if |x|<2^-5 : sin(x)=x+x*x^2*DP_SIN2_0+x^5*DP_SIN2_1, ++ * cos(x)=1+1*x^2*DP_COS2_0+x^5*DP_COS2_1 ++ * 4) if |x|< Pi/4: sin(x)=x+x*x^2*(S0+x^2*(S1+x^2*(S2+x^2*(S3+x^2*S4)))), ++ * cos(x)=1+1*x^2*(C0+x^2*(C1+x^2*(C2+x^2*(C3+x^2*C4)))). ++ * 5) if |x| < 9*Pi/4: ++ * 5.1) Range reduction: ++ * k=trunc(|x|/(Pi/4)), j=(k+1)&0x0e, n=k+1, t=|x|-j*Pi/4. ++ * 5.2) Reconstruction: ++ * sign_sin = sign(x) * (-1.0)^(( n >>2)&1) ++ * sign_cos = (-1.0)^(((n+2)>>2)&1) ++ * poly_sin = ((((S4*t^2 + S3)*t^2 + S2)*t^2 + S1)*t^2 + S0)*t^2*t+t ++ * poly_cos = ((((C4*t^2 + C3)*t^2 + C2)*t^2 + C1)*t^2 + C0)*t^2*s+s ++ * if(n&2 != 0) { ++ * using cos(t) and sin(t) polynomials for |t|= 2^23, very large args: ++ * 7.1) Range reduction: ++ * k=trunc(|x|/(Pi/4)), j=(k+1)&0xfffffffe, n=k+1, t=|x|-j*Pi/4. ++ * 7.2) Reconstruction same as (5.2). ++ * 8) if x is Inf, return x-x, and set errno=EDOM. ++ * 9) if x is NaN, return x-x. ++ * ++ * Special cases: ++ * sin/cos(+-0) = +-0/1 not raising inexact/underflow, ++ * sin/cos(subnormal) raises inexact/underflow, ++ * sin/cos(min_normalized) raises inexact/underflow, ++ * sin/cos(normalized) raises inexact, ++ * sin/cos(Inf) = NaN, raises invalid, sets errno to EDOM, ++ * sin/cos(NaN) = NaN. ++ */ ++ ++#define COSF __cosf ++ ++#define LOADFD(rd, rs, label) \ ++ la.local rs, label;\ ++ fld.d rd, rs, 0 ++ ++#define LOADFS(rd, rs, label) \ ++ la.local rs, label;\ ++ fld.s rd, rs, 0 ++ ++#define FTOL(rd, rs, tmp) \ ++ ftintrz.l.d tmp, rs;\ ++ movfr2gr.d rd, tmp ++ ++#define FTOW(rd, rs, tmp) \ ++ ftintrz.w.d tmp, rs;\ ++ movfr2gr.s rd, tmp ++ ++#define WTOF(rd, rs, tmp) \ ++ movgr2fr.w tmp, rs;\ ++ ffint.d.w rd, tmp ++ ++#define LTOF(rd, rs, tmp) \ ++ movgr2fr.d tmp, rs;\ ++ ffint.d.l rd, tmp ++ ++LEAF(COSF) ++ .align 2 ++ .align 3 ++ /* fa0 is SP x; fa1 is DP x */ ++ movfr2gr.s t0, fa0 /* Bits of x */ ++ fcvt.d.s fa1, fa0 /* DP x */ ++ li.w t1, 0x7fffffff ++ and t0, t0, t1 /* |x| */ ++ li.w t1, 0x3f490fdb /* const Pi/4 */ ++ bltu t0, t1, L(arg_less_pio4) /* |x| < Pi/4 branch */ ++ li.w t1, 0x40e231d6 /* 9*Pi/4 */ ++ la.local t4, L(DP_) /*DP_ base addr*/ ++ bgeu t0, t1, L(greater_or_equal_9pio4) /* |x| >= 9*Pi/4 branch */ ++/* L(median_args): */ ++ /* Here if Pi/4<=|x|<9*Pi/4 */ ++ fabs.d fa0, fa1 /* DP |x| */ ++ fld.d fa1, t4, 56 /* 4/Pi */ ++ fmul.d fa1, fa1, fa0 /* DP |x|/(Pi/4) */ ++ FTOW( t0, fa1, fa1 ) /* k=trunc(|x|/(Pi/4)) */ ++ la.local t1, L(PIO2J) /* base addr of PIO2J table */ ++ addi.w t0, t0, 1 /* k+1 */ ++ bstrpick.d t2, t0, 3, 1 /* j=n/2 */ ++ alsl.d t1, t2, t1, 3 ++ fld.d fa1, t1, 0 /* j*Pi/2 */ ++ addi.w t0, t0, 2 /* n = k+3 */ ++ fsub.d fa0, fa0, fa1 /* t = |x| - j * Pi/2 */ ++/* Input: t0=n fa0=t*/ ++L(reduced): ++ /* Here if cos(x) calculated using cos(t) polynomial for |t|>2)&1) ++ * result = s * (1.0+t^2*(C0+t^2*(C1+t^2*(C2+t^2*(C3+t^2*C4))))) ++ ++ * Here if cos(x) calculated using sin(t) polynomial for |t|>2)&1) ++ * result = s * t * (1.0+t^2*(S0+t^2*(S1+t^2*(S2+t^2*(S3+t^2*S4))))) ++ */ ++ /* TODO: what is the best order ??? */ ++ /* load-to-use latency, hardware module usage, integer pipeline & float pipeline */ ++ /* cancel branch */ ++ slli.w t0, t0, 1 /* (n << 1) */ ++ andi t1, t0, 4 /* (n << 1) & 4 */ ++ alsl.d t2, t1, t4, 4 /* adjust to DP_C or DP_S */ ++ fld.d fa3, t2, 32 /* C4 */ ++ andi t0, t0, 8 /* =====> (n << 1) & 8 */ ++ fmul.d fa1, fa0, fa0 /* y=x^2 */ ++ fld.d fa4, t2, 16 /* C2 */ ++ fmul.d fa2, fa1, fa1 /* z=x^4 */ ++ fld.d fa5, t2, 24 /* C3 */ ++ la.local t3, L(DP_ONES) /* =====> DP_ONES */ ++ fld.d fa6, t2, 8 /* C1 */ ++ fmadd.d fa4, fa2, fa3, fa4 /* cx = C2+z*C4 */ ++ fld.d fa3, t2, 0 /* C0 */ ++ fmadd.d fa5, fa2, fa5, fa6 /* cy = C1+z*C3 */ ++ fld.d fa6, t3, 0 /* one */ ++ fmadd.d fa4, fa2, fa4, fa3 /* cx = C0+z*cx */ ++ add.d t0, t0, t3 /* =====> addr */ ++ fmadd.d fa4, fa1, fa5, fa4 /* cx = cx+y*cy */ ++ fld.d fa2, t0, 0 /* sign */ ++ fmadd.d fa4, fa4, fa1, fa6 /* 1.0+y*cx */ ++ fmul.d fa1, fa2, fa4 /* sign * cx */ ++ bnez t1, L_return ++ fmul.d fa1, fa1, fa0 /* t*s, where s = sign(x) * (-1.0)^((n>>2)&1) */ ++L_return: ++ fcvt.s.d fa0, fa1 /* SP result */ ++ jr ra ++ ++L(greater_or_equal_9pio4): ++ /* Here if |x|>=9*Pi/4 */ ++ li.w t1, 0x7f800000 /* x is Inf or NaN? */ ++ bgeu t0, t1, L(inf_or_nan) /* |x| >= Inf branch */ ++ /* Here if finite |x|>=9*Pi/4 */ ++ li.w t1, 0x4b000000 /* 2^23 */ ++ bgeu t0, t1, L(greater_or_equal_2p23) /* |x| >= 2^23 branch */ ++ /* Here if 9*Pi/4<=|x|<2^23 */ ++ fabs.d fa0, fa1 /* DP |x| */ ++ fld.d fa1, t4, 56 ++ fmul.d fa1, fa1, fa0 /* |x|/(Pi/4) */ ++ FTOW( t0, fa1, fa1 ) /* k=trunc(|x|/(Pi/4)) */ ++ addi.w t0, t0, 1 /* k+1 */ ++ srli.w t1, t0, 1 /* x=n/2 */ ++ WTOF( fa1, t1, fa1 ) /* DP x */ ++ fld.d fa2, t4, 104 /* -PIO2HI = high part of -Pi/2 */ ++ fld.d fa3, t4, 112 /* -PIO2LO = low part of -Pi/2 */ ++ fmadd.d fa0, fa2, fa1, fa0 /* |x| - x*PIO2HI */ ++ addi.w t0, t0, 2 /* n = k+3 */ ++ fmadd.d fa0, fa3, fa1, fa0 /* |x| - x*PIO2HI - x*PIO2LO */ ++ b L(reduced) ++ ++L(greater_or_equal_2p23): ++ /* Here if finite |x|>=2^23 */ ++ fabs.s fa5, fa0 /* SP |x| */ ++ /* bitpos = (ix>>23) - BIAS_32; */ ++ srli.w t0, t0, 23 /*TODO???srai.w eb = biased exponent of x */ ++ /* bitpos = eb - 0x7f + 59, where 0x7f is exponent bias */ ++ addi.w t0, t0, -124 /* t0 = bitpos */ ++ /* t3= j = bitpos/28 */ ++ /* x/28 = (x * ((0x100000000 / 28) + 1)) >> 32 */ ++ li.w t1, 0x924924a ++ mulh.wu t0, t1, t0 ++ fcvt.d.s fa5, fa5 /* Convert to double */ ++ /* TODO: what is the best order ??? */ ++ la.local t1, L(invpio4_table) /* t2 */ ++ alsl.d t1, t0, t1, 3 ++ fld.d fa0, t1, 0 /* invpio4_table[j] */ ++ fld.d fa1, t1, 8 /* invpio4_table[j+1] */ ++ fmul.d fa0, fa0, fa5 /* a = invpio4_table[j]*|x| */ ++ fld.d fa2, t1, 16 /* invpio4_table[j+2] */ ++ fmul.d fa1, fa1, fa5 /* b = invpio4_table[j+1]*|x| */ ++ fld.d fa3, t1, 24 /* invpio4_table[j+3] */ ++ fmul.d fa2, fa2, fa5 /* c = invpio4_table[j+2]*|x| */ ++ fmul.d fa3, fa3, fa5 /* d = invpio4_table[j+3]*|x| */ ++/*TODO: overflow check*/ ++ FTOL( t0, fa0, fa4 ) /*uint64_t l = a; TODO: change the order*/ ++ li.w t1, -8 /* 0xfffffffffffffff8 */ ++ and t0, t0, t1 /* l &= ~0x7; */ ++ LTOF( fa4, t0, fa4 ) /* DP l*/ ++ fsub.d fa0, fa0, fa4 /* a -= l; */ ++ fadd.d fa4, fa0, fa1 /* fa4 double e = a + b; */ ++/*TODO: overflow check*/ ++ FTOL( t0, fa4, fa4 ) /*uint64_t l = e;*/ ++ andi t2, t0, 1 /* l & 1 TODO: change the order*/ ++ LOADFD( fa5, t1, L(DP_ONES) ) /* fa5 = 1.0 */ ++ LTOF( fa4, t0, fa4 ) /* fa4 DP l*/ ++/* critical!!!! the order */ ++ fsub.d fa0, fa0, fa4 ++ fld.d fa4, t4, 120 /* PI_4 */ ++ beqz t2, L_even_integer ++/*L_odd_integer:*/ ++ fsub.d fa0, fa0, fa5 ++ fadd.d fa0, fa0, fa1 ++ fadd.d fa2, fa2, fa3 ++ fadd.d fa0, fa0, fa2 ++ addi.d t0, t0, 3 ++ fmul.d fa0, fa0, fa4 ++ b L(reduced) ++L_even_integer: ++ fadd.d fa0, fa0, fa1 ++ fadd.d fa2, fa2, fa3 ++ fadd.d fa0, fa0, fa2 ++ fcmp.sle.d $fcc0, fa0, fa5 ++ addi.d t0, t0, 3 ++ bcnez $fcc0, L_leq_one ++/*L_gt_one:*/ ++ fld.d fa2, t1, 16 /* 2.0 */ ++ addi.d t0, t0, 1 ++ fsub.d fa0, fa0, fa2 ++L_leq_one: ++ fmul.d fa0, fa0, fa4 ++ b L(reduced) ++ ++L(arg_less_pio4): ++ /* Here if |x| ++#include ++#include ++ ++/* Short algorithm description: ++ * ++ * 1) if |x|==0: sin(x)=x, ++ * cos(x)=1. ++ * 2) if |x|<2^-27: sin(x)=x-x*DP_SMALL, raising underflow only when needed, ++ * cos(x)=1-|x|. ++ * 3) if |x|<2^-5 : sin(x)=x+x*x^2*DP_SIN2_0+x^5*DP_SIN2_1, ++ * cos(x)=1+1*x^2*DP_COS2_0+x^5*DP_COS2_1 ++ * 4) if |x|< Pi/4: sin(x)=x+x*x^2*(S0+x^2*(S1+x^2*(S2+x^2*(S3+x^2*S4)))), ++ * cos(x)=1+1*x^2*(C0+x^2*(C1+x^2*(C2+x^2*(C3+x^2*C4)))). ++ * 5) if |x| < 9*Pi/4: ++ * 5.1) Range reduction: ++ * k=trunc(|x|/(Pi/4)), j=(k+1)&0x0e, n=k+1, t=|x|-j*Pi/4. ++ * 5.2) Reconstruction: ++ * sign_sin = sign(x) * (-1.0)^(( n >>2)&1) ++ * sign_cos = (-1.0)^(((n+2)>>2)&1) ++ * poly_sin = ((((S4*t^2 + S3)*t^2 + S2)*t^2 + S1)*t^2 + S0)*t^2*t+t ++ * poly_cos = ((((C4*t^2 + C3)*t^2 + C2)*t^2 + C1)*t^2 + C0)*t^2*s+s ++ * if(n&2 != 0) { ++ * using cos(t) and sin(t) polynomials for |t|= 2^23, very large args: ++ * 7.1) Range reduction: ++ * k=trunc(|x|/(Pi/4)), j=(k+1)&0xfffffffe, n=k+1, t=|x|-j*Pi/4. ++ * 7.2) Reconstruction same as (5.2). ++ * 8) if x is Inf, return x-x, and set errno=EDOM. ++ * 9) if x is NaN, return x-x. ++ * ++ * Special cases: ++ * sin/cos(+-0) = +-0/1 not raising inexact/underflow, ++ * sin/cos(subnormal) raises inexact/underflow, ++ * sin/cos(min_normalized) raises inexact/underflow, ++ * sin/cos(normalized) raises inexact, ++ * sin/cos(Inf) = NaN, raises invalid, sets errno to EDOM, ++ * sin/cos(NaN) = NaN. ++ */ ++ ++#define SINF __sinf ++ ++#define LOADFD(rd, rs, label) \ ++ la.local rs, label;\ ++ fld.d rd, rs, 0 ++ ++#define LOADFS(rd, rs, label) \ ++ la.local rs, label;\ ++ fld.s rd, rs, 0 ++ ++#define FTOL(rd, rs, tmp) \ ++ ftintrz.l.d tmp, rs;\ ++ movfr2gr.d rd, tmp ++ ++#define FTOW(rd, rs, tmp) \ ++ ftintrz.w.d tmp, rs;\ ++ movfr2gr.s rd, tmp ++ ++#define WTOF(rd, rs, tmp) \ ++ movgr2fr.w tmp, rs;\ ++ ffint.d.w rd, tmp ++ ++#define LTOF(rd, rs, tmp) \ ++ movgr2fr.d tmp, rs;\ ++ ffint.d.l rd, tmp ++ ++LEAF(SINF) ++ .align 2 ++ .align 3 ++ /* fa0 is SP x; fa1 is DP x */ ++ movfr2gr.s t2, fa0 /* Bits of x */ ++ fcvt.d.s fa1, fa0 /* DP x */ ++ li.w t1, 0x7fffffff ++ and t0, t2, t1 /* |x| */ ++ li.w t1, 0x3f490fdb /* const Pi/4 */ ++ bltu t0, t1, L(arg_less_pio4) /* |x| < Pi/4 branch */ ++ li.w t1, 0x40e231d6 /* 9*Pi/4 */ ++ la.local t4, L(DP_) /*DP_ base addr*/ ++ bstrpick.d t5, t2, 31, 31 /* sign of x */ ++ slli.w t5, t5, 3 ++ bgeu t0, t1, L(greater_or_equal_9pio4) /* |x| >= 9*Pi/4 branch */ ++/* L(median_args): */ ++ /* Here if Pi/4<=|x|<9*Pi/4 */ ++ fabs.d fa0, fa1 /* DP |x| */ ++ fld.d fa1, t4, 56 /* 4/Pi */ ++ fmul.d fa1, fa1, fa0 /* DP |x|/(Pi/4) */ ++ FTOW( t0, fa1, fa1 ) /* k=trunc(|x|/(Pi/4)) */ ++ la.local t1, L(PIO2J) /* base addr of PIO2J table */ ++ addi.w t0, t0, 1 /* k+1 */ ++ bstrpick.d t2, t0, 3, 1 /* j=n/2 */ ++ alsl.d t1, t2, t1, 3 ++ fld.d fa1, t1, 0 /* j*Pi/2 */ ++ fsub.d fa0, fa0, fa1 /* t = |x| - j * Pi/2 */ ++/* Input: t0=n fa0=t*/ ++/* Input: t0=n fa0=t, t5=sign(x) */ ++L(reduced): ++ /* Here if cos(x) calculated using cos(t) polynomial for |t|>2)&1) ++ * result = s * (1.0+t^2*(C0+t^2*(C1+t^2*(C2+t^2*(C3+t^2*C4))))) ++ ++ * Here if cos(x) calculated using sin(t) polynomial for |t|>2)&1) ++ * result = s * t * (1.0+t^2*(S0+t^2*(S1+t^2*(S2+t^2*(S3+t^2*S4))))) ++ */ ++ /* TODO: what is the best order ??? */ ++ /* load-to-use latency, hardware module usage, integer pipeline & float pipeline */ ++ /* cancel branch */ ++ slli.w t0, t0, 1 /* (n << 1) */ ++ andi t1, t0, 4 /* (n << 1) & 4 */ ++ alsl.d t2, t1, t4, 4 /* adjust to DP_C or DP_S */ ++ fld.d fa3, t2, 32 /* C4 */ ++ andi t0, t0, 8 /* =====> (n << 1) & 8 */ ++ fmul.d fa1, fa0, fa0 /* y=x^2 */ ++ xor t0, t0, t5 /* (-1.0)^((n>>2)&1) XOR sign(x) */ ++ fld.d fa4, t2, 16 /* C2 */ ++ fmul.d fa2, fa1, fa1 /* z=x^4 */ ++ fld.d fa5, t2, 24 /* C3 */ ++ la.local t3, L(DP_ONES) /* =====> DP_ONES */ ++ fld.d fa6, t2, 8 /* C1 */ ++ fmadd.d fa4, fa2, fa3, fa4 /* cx = C2+z*C4 */ ++ fld.d fa3, t2, 0 /* C0 */ ++ fmadd.d fa5, fa2, fa5, fa6 /* cy = C1+z*C3 */ ++ fld.d fa6, t3, 0 /* 1.0 */ ++ fmadd.d fa4, fa2, fa4, fa3 /* cx = C0+z*cx */ ++ add.d t0, t0, t3 /* =====> addr */ ++ fmadd.d fa4, fa1, fa5, fa4 /* cx = cx+y*cy */ ++ fld.d fa2, t0, 0 /* sign */ ++ fmadd.d fa4, fa4, fa1, fa6 /* 1.0+y*cx */ ++ fmul.d fa1, fa2, fa4 /* sign * cx */ ++ bnez t1, L_return ++ fmul.d fa1, fa1, fa0 /* t*s, where s = sign(x) * (-1.0)^((n>>2)&1) */ ++L_return: ++ fcvt.s.d fa0, fa1 /* SP result */ ++ jr ra ++ ++L(greater_or_equal_9pio4): ++ /* Here if |x|>=9*Pi/4 */ ++ li.w t1, 0x7f800000 /* x is Inf or NaN? */ ++ bgeu t0, t1, L(inf_or_nan) /* |x| >= Inf branch */ ++ /* Here if finite |x|>=9*Pi/4 */ ++ li.w t1, 0x4b000000 /* 2^23 */ ++ bgeu t0, t1, L(greater_or_equal_2p23) /* |x| >= 2^23 branch */ ++ /* Here if 9*Pi/4<=|x|<2^23 */ ++ fabs.d fa0, fa1 /* DP |x| */ ++ fld.d fa1, t4, 56 ++ fmul.d fa1, fa1, fa0 /* |x|/(Pi/4) */ ++ FTOW( t0, fa1, fa1 ) /* k=trunc(|x|/(Pi/4)) */ ++ addi.w t0, t0, 1 /* k+1 */ ++ srli.w t1, t0, 1 /* x=n/2 */ ++ WTOF( fa1, t1, fa1 ) /* DP x */ ++ fld.d fa2, t4, 104 /* -PIO2HI = high part of -Pi/2 */ ++ fld.d fa3, t4, 112 /* -PIO2LO = low part of -Pi/2 */ ++ fmadd.d fa0, fa2, fa1, fa0 /* |x| - x*PIO2HI */ ++ fmadd.d fa0, fa3, fa1, fa0 /* |x| - x*PIO2HI - x*PIO2LO */ ++ b L(reduced) ++ ++L(greater_or_equal_2p23): ++ /* Here if finite |x|>=2^23 */ ++ fabs.s fa5, fa0 /* SP |x| */ ++ /* bitpos = (ix>>23) - BIAS_32; */ ++ srli.w t0, t0, 23 /*TODO???srai.w eb = biased exponent of x */ ++ /* bitpos = eb - 0x7f + 59, where 0x7f is exponent bias */ ++ addi.w t0, t0, -124 /* t0 = bitpos */ ++ /* t3= j = bitpos/28 */ ++ /* x/28 = (x * ((0x100000000 / 28) + 1)) >> 32 */ ++ li.w t1, 0x924924a ++ mulh.wu t0, t1, t0 ++ fcvt.d.s fa5, fa5 /* Convert to double */ ++ /* TODO: what is the best order ??? */ ++ la.local t1, L(invpio4_table) /* t2 */ ++ alsl.d t1, t0, t1, 3 ++ fld.d fa0, t1, 0 /* invpio4_table[j] */ ++ fld.d fa1, t1, 8 /* invpio4_table[j+1] */ ++ fmul.d fa0, fa0, fa5 /* a = invpio4_table[j]*|x| */ ++ fld.d fa2, t1, 16 /* invpio4_table[j+2] */ ++ fmul.d fa1, fa1, fa5 /* b = invpio4_table[j+1]*|x| */ ++ fld.d fa3, t1, 24 /* invpio4_table[j+3] */ ++ fmul.d fa2, fa2, fa5 /* c = invpio4_table[j+2]*|x| */ ++ fmul.d fa3, fa3, fa5 /* d = invpio4_table[j+3]*|x| */ ++/*TODO: overflow check*/ ++ FTOL( t0, fa0, fa4 ) /*uint64_t l = a; TODO: change the order*/ ++ li.w t1, -8 /* 0xfffffffffffffff8 */ ++ and t0, t0, t1 /* l &= ~0x7; */ ++ LTOF( fa4, t0, fa4 ) /* DP l*/ ++ fsub.d fa0, fa0, fa4 /* a -= l; */ ++ fadd.d fa4, fa0, fa1 /* fa4 double e = a + b; */ ++/*TODO: overflow check*/ ++ FTOL( t0, fa4, fa4 ) /*uint64_t l = e;*/ ++ andi t2, t0, 1 /* l & 1 TODO: change the order*/ ++ LOADFD( fa5, t1, L(DP_ONES) ) /* fa5 = 1.0 */ ++ LTOF( fa4, t0, fa4 ) /* fa4 DP l*/ ++/* critical!!!! the order */ ++ fsub.d fa0, fa0, fa4 ++ fld.d fa4, t4, 120 /* PI_4 */ ++ beqz t2, L_even_integer ++/*L_odd_integer:*/ ++ fsub.d fa0, fa0, fa5 ++ fadd.d fa0, fa0, fa1 ++ fadd.d fa2, fa2, fa3 ++ fadd.d fa0, fa0, fa2 ++ addi.d t0, t0, 1 ++ fmul.d fa0, fa0, fa4 ++ b L(reduced) ++L_even_integer: ++ fadd.d fa0, fa0, fa1 ++ fadd.d fa2, fa2, fa3 ++ fadd.d fa0, fa0, fa2 ++ fcmp.sle.d $fcc0, fa0, fa5 ++ addi.d t0, t0, 1 ++ bcnez $fcc0, L_leq_one ++/*L_gt_one:*/ ++ fld.d fa2, t1, 16 /* 2.0 */ ++ addi.d t0, t0, 1 ++ fsub.d fa0, fa0, fa2 ++L_leq_one: ++ fmul.d fa0, fa0, fa4 ++ b L(reduced) ++ ++L(arg_less_pio4): ++ /* Here if |x| ++#include ++ ++ ++ ++ ++ ++#define L_ADDIU addi.d ++#define L_ADDU add.d ++#define L_SUBU sub.d ++ ++#define STRCHR strchr ++#define MOVN(rd,rs,rt) \ ++ maskeqz t6, rs, rt;\ ++ masknez rd, rd, rt;\ ++ or rd, rd, t6 ++ ++#define MOVN2(rd,rt) \ ++ masknez rd, rd, rt;\ ++ or rd, rd, rt ++ ++ ++/* char * strchr (const char *s1, int c); */ ++ ++LEAF(STRCHR) ++ .align 6 ++ ++ li.w t4, 0x7 ++ lu12i.w a2, 0x01010 ++ bstrins.d a1, a1, 15, 8 ++ andi t0, a0, 0x7 ++ ++ ori a2, a2, 0x101 ++ andn t4, a0, t4 ++ slli.w t1, t0, 3 ++ ++ ld.d t4, t4, 0 ++ ++ ++ nor t8, zero, zero ++ bstrins.d a1, a1, 31, 16 ++ srl.d t4, t4, t1 ++ ++ bstrins.d a1, a1, 63, 32 ++ bstrins.d a2, a2, 63, 32 ++ srl.d a7, t8, t1 ++ ++ li.w t1, 8 ++ nor t8, a7, zero ++ slli.d a3, a2, 7 ++ or t5, t8, t4 ++ and t3, a7, a1 ++ ++ sub.w t1, t1, t0 ++ nor a3, a3, zero ++ xor t2, t5, t3 ++ sub.d a7, t5, a2 ++ nor a6, t5, a3 ++ ++ sub.d a5, t2, a2 ++ nor a4, t2, a3 ++ ++ and a6, a7, a6 ++ and a5, a5, a4 ++ or a7, a6, a5 ++ bnez a7, L(_mc8_a) ++ ++ L_ADDU a0, a0, t1 ++L(_aloop): ++ ld.d t4, a0, 0 ++ ++ xor t2, t4, a1 ++ sub.d a7, t4, a2 ++ nor a6, t4, a3 ++ sub.d a5, t2, a2 ++ ++ nor a4, t2, a3 ++ and a6, a7, a6 ++ and a5, a5, a4 ++ or a7, a6, a5 ++ bnez a7, L(_mc8_a) ++ ++ ld.d t4, a0, 8 ++ L_ADDIU a0, a0, 16 ++ xor t2, t4, a1 ++ sub.d a7, t4, a2 ++ nor a6, t4, a3 ++ sub.d a5, t2, a2 ++ ++ nor a4, t2, a3 ++ and a6, a7, a6 ++ and a5, a5, a4 ++ or a7, a6, a5 ++ beqz a7, L(_aloop) ++ ++ L_ADDIU a0, a0, -8 ++L(_mc8_a): ++ ++ ctz.d t0, a5 ++ ctz.d t2, a6 ++ ++ srli.w t0, t0, 3 ++ srli.w t2, t2, 3 ++ sltu t1, t2, t0 ++ L_ADDU v0, a0, t0 ++ masknez v0, v0, t1 ++ jr ra ++END(STRCHR) ++ ++#ifndef ANDROID_CHANGES ++#ifdef _LIBC ++libc_hidden_builtin_def (strchr) ++weak_alias (strchr, index) ++#endif ++#endif +diff --git a/sysdeps/loongarch/lp64/strchrnul.S b/sysdeps/loongarch/lp64/strchrnul.S +new file mode 100644 +index 00000000..a57a5065 +--- /dev/null ++++ b/sysdeps/loongarch/lp64/strchrnul.S +@@ -0,0 +1,156 @@ ++/* Copyright 2016 Loongson Technology Corporation Limited */ ++ ++/* Author: Songyuekun songyuekun@loongson.cn */ ++ ++/* ++ * ISA: MIPS64R2 ++ * ABI: N64 ++ */ ++ ++/* basic algorithm : ++ ++ +. use ld.d and mask for the first 8 bytes or less; ++ ++ +. build a1 with 8c with dins; ++ ++ +. use xor from a1 and v0 to check if is found; ++ ++ +. if (v0 - 0x0101010101010101) & (~(v0 | 0x7f7f7f7f7f7f7f7f)!= 0, v0 has ++ one byte is \0, else has no \0 ++ ++*/ ++ ++ ++ ++ ++#include ++#include ++ ++ ++ ++ ++ ++#define L_ADDIU addi.d ++#define L_ADDU add.d ++#define L_SUBU sub.d ++ ++#define STRCHRNUL __strchrnul ++ ++#define MOVN(rd,rs,rt) \ ++ maskeqz t6, rs, rt;\ ++ masknez rd, rd, rt;\ ++ or rd, rd, t6 ++ ++#define MOVZ(rd,rs,rt) \ ++ masknez t6, rs, rt;\ ++ maskeqz rd, rd, rt;\ ++ or rd, rd, t6 ++ ++ ++#define MOVN2(rd,rt) \ ++ masknez rd, rd, rt;\ ++ or rd, rd, rt ++ ++ ++/* char * strchrnul (const char *s1, int c); */ ++ ++LEAF(STRCHRNUL) ++ .align 6 ++ ++ li.w t4, 0x7 ++ lu12i.w a2, 0x01010 ++ bstrins.d a1, a1, 15, 8 ++ andi t0, a0, 0x7 ++ ++ ori a2, a2, 0x101 ++ andn t4, a0, t4 ++ slli.w t1, t0, 3 ++/* ++ ldr t4, 0(a0) ++*/ ++ ld.d t4, t4, 0 ++ ++ ++ nor t8, zero, zero ++ bstrins.d a1, a1, 31, 16 ++ srl.d t4, t4, t1 ++ ++ preld 0, a0, 32 ++ bstrins.d a1, a1, 63, 32 ++ bstrins.d a2, a2, 63, 32 ++ srl.d a7, t8, t1 ++ ++ nor t8, a7, zero ++ slli.d a3, a2, 7 ++ or t5, t8, t4 ++ and t3, a7, a1 ++ ++ nor a3, a3, zero ++ xor t2, t5, t3 ++ sub.d a7, t5, a2 ++ nor a6, t5, a3 ++ ++ li.w t1, 8 ++ sub.d a5, t2, a2 ++ nor a4, t2, a3 ++ ++ and a6, a7, a6 ++ and a5, a5, a4 ++ or a7, a6, a5 ++ bnez a7, L(_mc8_a) ++ ++ ++ sub.w t1, t1, t0 ++ L_ADDU a0, a0, t1 ++L(_aloop): ++ ld.d t4, a0, 0 ++ ++ xor t2, t4, a1 ++ sub.d a7, t4, a2 ++ nor a6, t4, a3 ++ sub.d a5, t2, a2 ++ ++ nor a4, t2, a3 ++ and a6, a7, a6 ++ and a5, a5, a4 ++ ++ or a7, a6, a5 ++ bnez a7, L(_mc8_a) ++ ++ ld.d t4, a0, 8 ++ L_ADDIU a0, a0, 16 ++ ++ xor t2, t4, a1 ++ sub.d a7, t4, a2 ++ nor a6, t4, a3 ++ sub.d a5, t2, a2 ++ ++ nor a4, t2, a3 ++ and a6, a7, a6 ++ and a5, a5, a4 ++ ++ or a7, a6, a5 ++ beqz a7, L(_aloop) ++ ++ L_ADDIU a0, a0, -8 ++L(_mc8_a): ++ ++ ctz.d t0, a5 ++ ctz.d t2, a6 ++ ++ srli.w t0, t0, 3 ++ srli.w t2, t2, 3 ++ slt t1, t0, t2 ++ ++ MOVZ(t0,t2,t1) ++ ++ L_ADDU v0, a0, t0 ++ jr ra ++END(STRCHRNUL) ++ ++#ifndef ANDROID_CHANGES ++#ifdef _LIBC ++weak_alias(__strchrnul, strchrnul) ++libc_hidden_builtin_def (__strchrnul) ++#endif ++#endif +diff --git a/sysdeps/loongarch/lp64/strcmp.S b/sysdeps/loongarch/lp64/strcmp.S +new file mode 100644 +index 00000000..11474bf2 +--- /dev/null ++++ b/sysdeps/loongarch/lp64/strcmp.S +@@ -0,0 +1,197 @@ ++/* Copyright 2016 Loongson Technology Corporation Limited */ ++ ++/* Author: songyuekun songyuekun@loongson.cn */ ++ ++/* ++ * ISA: MIPS64R2 ++ * ABI: N64 ++ */ ++ ++/* basic algorithm : ++ ++ +. let t0, t1 point to a0, a1, if a0 has smaller low 3 bit of a0 and a1, ++ set a4 to 1 and let t0 point to the larger of lower 3bit of a0 and a1 ++ ++ +. if low 3 bit of a0 equal low 3 bit of a0, use a ldr one time and more ld other times; ++ ++ +. if not, load partial t2 and t3, check if t2 has \0; ++ ++ +. then use use ld for t0, ldr for t1, ++ ++ +. if partial 8 byte from t1 has \0, compare partial 8 byte from t1 with 8 ++ byte from t0 with a mask in a7 ++ ++ +. if not, ldl other part of t1, compare 8 byte from t1 with 8 byte from t0 ++ ++ +. if (v0 - 0x0101010101010101) & (~v0) & 0x8080808080808080 != 0, v0 has ++ one byte is \0, else has no \0 ++ ++ +. for partial 8 byte from ldr t3, 0(a0), preload t3 with 0xffffffffffffffff ++ ++ ++*/ ++#include ++#include ++ ++ ++#define STRCMP strcmp ++ ++#define REP8_01 0x0101010101010101 ++#define REP8_7f 0x7f7f7f7f7f7f7f7f ++#define REP8_80 0x8080808080808080 ++ ++/* Parameters and Results */ ++#define src1 a0 ++#define src2 a1 ++#define result v0 ++// Note: v0 = a0 in N64 ABI ++ ++ ++/* Internal variable */ ++#define data1 t0 ++#define data2 t1 ++#define has_nul t2 ++#define diff t3 ++#define syndrome t4 ++#define zeroones t5 ++#define sevenf t6 ++#define pos t7 ++#define exchange t8 ++#define tmp1 a4 ++#define tmp2 a5 ++#define tmp3 a6 ++#define src1_off a2 ++#define src2_off a3 ++#define tmp4 a7 ++ ++/* rd <- if rc then ra else rb ++ will destroy tmp3 ++*/ ++#define CONDITIONSEL(rd,rc,ra,rb)\ ++ masknez tmp3, rb, rc;\ ++ maskeqz rd, ra, rc;\ ++ or rd, rd, tmp3 ++ ++ ++ ++/* int strcmp (const char *s1, const char *s2); */ ++ ++LEAF(STRCMP) ++ .align 4 ++ ++ xor tmp1, src1, src2 ++ lu12i.w zeroones, 0x01010 ++ lu12i.w sevenf, 0x7f7f7 ++ andi src1_off, src1, 0x7 ++ ori zeroones, zeroones, 0x101 ++ ori sevenf, sevenf, 0xf7f ++ andi tmp1, tmp1, 0x7 ++ bstrins.d zeroones, zeroones, 63, 32 ++ bstrins.d sevenf, sevenf, 63, 32 ++ bnez tmp1, strcmp_misaligned8 ++ bnez src1_off, strcmp_mutual_align ++strcmp_loop_aligned: ++ ld.d data1, src1, 0 ++ addi.d src1, src1, 8 ++ ld.d data2, src2, 0 ++ addi.d src2, src2, 8 ++strcmp_start_realigned: ++ sub.d tmp1, data1, zeroones ++ or tmp2, data1, sevenf ++ xor diff, data1, data2 ++ andn has_nul, tmp1, tmp2 ++ or syndrome, diff, has_nul ++ beqz syndrome, strcmp_loop_aligned ++ ++strcmp_end: ++ ctz.d pos, syndrome ++ bstrins.d pos, zero, 2, 0 ++ srl.d data1, data1, pos ++ srl.d data2, data2, pos ++ andi data1, data1, 0xff ++ andi data2, data2, 0xff ++ sub.d result, data1, data2 ++ jr ra ++strcmp_mutual_align: ++ bstrins.d src1, zero, 2, 0 ++ bstrins.d src2, zero, 2, 0 ++ slli.d tmp1, src1_off, 0x3 ++ ld.d data1, src1, 0 ++ sub.d tmp1, zero, tmp1 ++ ld.d data2, src2, 0 ++ addi.d src1, src1, 8 ++ addi.d src2, src2, 8 ++ nor tmp2, zero, zero ++ srl.d tmp2, tmp2, tmp1 ++ or data1, data1, tmp2 ++ or data2, data2, tmp2 ++ b strcmp_start_realigned ++ ++strcmp_misaligned8: ++ ++/* check ++ if ((src1 != 0) && ((src2 == 0 ) || (src1 < src2))) ++ then exchange(src1,src2) ++ ++*/ ++ andi src2_off, src2, 0x7 ++ slt tmp2, src1_off, src2_off ++ CONDITIONSEL(tmp2,src2_off,tmp2,tmp1) ++ maskeqz exchange, tmp2, src1_off ++ xor tmp3, src1, src2 ++ maskeqz tmp3, tmp3, exchange ++ xor src1, src1, tmp3 ++ xor src2, src2, tmp3 ++ ++ andi src1_off, src1, 0x7 ++ beqz src1_off, strcmp_loop_misaligned ++strcmp_do_misaligned: ++ ld.bu data1, src1, 0 ++ ld.bu data2, src2, 0 ++ xor tmp3, data1, data2 ++ addi.d src1, src1, 1 ++ masknez tmp3, data1, tmp3 ++ addi.d src2, src2, 1 ++ beqz tmp3, strcmp_done ++ andi src1_off, src1, 0x7 ++ bnez src1_off, strcmp_do_misaligned ++ ++strcmp_loop_misaligned: ++ andi tmp1, src2, 0xff8 ++ xori tmp1, tmp1, 0xff8 ++ beqz tmp1, strcmp_do_misaligned ++ ld.d data1, src1, 0 ++ ld.d data2, src2, 0 ++ addi.d src1, src1, 8 ++ addi.d src2, src2, 8 ++ ++ sub.d tmp1, data1, zeroones ++ or tmp2, data1, sevenf ++ xor diff, data1, data2 ++ andn has_nul, tmp1, tmp2 ++ or syndrome, diff, has_nul ++ beqz syndrome, strcmp_loop_misaligned ++// b strcmp_end ++strcmp_misalign_end: ++ ctz.d pos, syndrome ++ bstrins.d pos, zero, 2, 0 ++ srl.d data1, data1, pos ++ srl.d data2, data2, pos ++ andi data1, data1, 0xff ++ andi data2, data2, 0xff ++ sub.d tmp1, data1, data2 ++ sub.d tmp2, data2, data1 ++ CONDITIONSEL(result,exchange,tmp2,tmp1) ++ jr ra ++ ++strcmp_done: ++ sub.d tmp1, data1, data2 ++ sub.d tmp2, data2, data1 ++ CONDITIONSEL(result,exchange,tmp2,tmp1) ++ jr ra ++END(STRCMP) ++#ifndef ANDROID_CHANGES ++#ifdef _LIBC ++libc_hidden_builtin_def (strcmp) ++#endif ++#endif +diff --git a/sysdeps/loongarch/lp64/strcpy.S b/sysdeps/loongarch/lp64/strcpy.S +new file mode 100644 +index 00000000..ce39e5a1 +--- /dev/null ++++ b/sysdeps/loongarch/lp64/strcpy.S +@@ -0,0 +1,210 @@ ++/* Copyright 2016 Loongson Technology Corporation Limited */ ++ ++/* Author: Huang Pei huangpei@loongson.cn */ ++ ++/* ++ * ISA: MIPS64R2 ++ * ABI: N64 ++ */ ++ ++/* basic algorithm : ++ ++ +. if src aligned. just do the copy loop. if not, do the cross page check and copy one double word. ++ ++ Then move src to aligned. ++ ++ +. if (v0 - 0x0101010101010101) & (~v0) & 0x8080808080808080 != 0, v0 has ++ one byte is \0, else has no \0 ++ ++ ++*/ ++ ++ ++#include ++#include ++ ++ ++#define STRCPY strcpy ++ ++ ++#define REP8_01 0x0101010101010101 ++#define REP8_7f 0x7f7f7f7f7f7f7f7f ++#define REP8_80 0x8080808080808080 ++ ++/* Parameters and Results */ ++#define dest a0 ++#define src a1 ++#define result v0 ++// Note: v0 = a0 in N64 ABI ++ ++ ++/* Internal variable */ ++#define data t0 ++#define data1 t1 ++#define has_nul t2 ++#define diff t3 ++#define syndrome t4 ++#define zeroones t5 ++#define sevenf t6 ++#define pos t7 ++#define dest_backup t8 ++#define tmp1 a4 ++#define tmp2 a5 ++#define tmp3 a6 ++#define dest_off a2 ++#define src_off a3 ++#define tmp4 a7 ++ ++/* rd <- if rc then ra else rb ++ will destroy tmp3 ++*/ ++#define CONDITIONSEL(rd,rc,ra,rb)\ ++ masknez tmp3, rb, rc;\ ++ maskeqz rd, ra, rc;\ ++ or rd, rd, tmp3 ++ ++ ++ ++/* int strcpy (const char *s1, const char *s2); */ ++ ++LEAF(STRCPY) ++ .align 4 ++ ++ move dest_backup, dest ++ lu12i.w zeroones, 0x01010 ++ lu12i.w sevenf, 0x7f7f7 ++ ori zeroones, zeroones, 0x101 ++ ori sevenf, sevenf, 0xf7f ++ bstrins.d zeroones, zeroones, 63, 32 ++ bstrins.d sevenf, sevenf, 63, 32 ++ andi src_off, src, 0x7 ++ beqz src_off, strcpy_loop_aligned_1 ++ b strcpy_mutual_align ++strcpy_loop_aligned: ++ st.d data, dest, 0 ++ addi.d dest, dest, 8 ++strcpy_loop_aligned_1: ++ ld.d data, src, 0 ++ addi.d src, src, 8 ++strcpy_start_realigned: ++ sub.d tmp1, data, zeroones ++ or tmp2, data, sevenf ++ andn has_nul, tmp1, tmp2 ++ beqz has_nul, strcpy_loop_aligned ++ ++strcpy_end: ++ ++/* ++8 4 2 1 ++*/ ++ ctz.d pos, has_nul ++ srli.d pos, pos, 3 ++ addi.d pos, pos, 1 ++/* ++ Do 8/4/2/1 strcpy based on pos value. ++ pos value is the number of bytes to be copied ++ the bytes include the final \0 so the max length is 8 and the min length is 1 ++*/ ++ ++strcpy_end_8: ++ andi tmp1, pos, 0x8 ++ beqz tmp1, strcpy_end_4 ++ st.d data, dest, 0 ++ move dest, dest_backup ++ jr ra ++strcpy_end_4: ++ andi tmp1, pos, 0x4 ++ beqz tmp1, strcpy_end_2 ++ st.w data, dest, 0 ++ srli.d data, data, 32 ++ addi.d dest, dest, 4 ++strcpy_end_2: ++ andi tmp1, pos, 0x2 ++ beqz tmp1, strcpy_end_1 ++ st.h data, dest, 0 ++ srli.d data, data, 16 ++ addi.d dest, dest, 2 ++strcpy_end_1: ++ andi tmp1, pos, 0x1 ++ beqz tmp1, strcpy_end_ret ++ st.b data, dest, 0 ++strcpy_end_ret: ++ move result, dest_backup ++ jr ra ++ ++ ++strcpy_mutual_align: ++/* ++ Check if around src page bound. ++ if not go to page cross ok. ++ if it is, do further check. ++ use tmp2 to accelerate. ++*/ ++ ++ li.w tmp2, 0xff8 ++ andi tmp1, src, 0xff8 ++ beq tmp1, tmp2, strcpy_page_cross ++ ++strcpy_page_cross_ok: ++/* ++ Load a misaligned double word and check if has \0 ++ If no, do a misaligned double word paste. ++ If yes, calculate the number of avaliable bytes, ++ then jump to 4/2/1 end. ++*/ ++ ld.d data, src, 0 ++ sub.d tmp1, data, zeroones ++ or tmp2, data, sevenf ++ andn has_nul, tmp1, tmp2 ++ bnez has_nul, strcpy_end ++strcpy_mutual_align_finish: ++/* ++ Before jump back to align loop, make dest/src aligned. ++ This will cause a duplicated paste for several bytes between the first double word and the second double word, ++ but should not bring a problem. ++*/ ++ li.w tmp1, 8 ++ st.d data, dest, 0 ++ sub.d tmp1, tmp1, src_off ++ add.d src, src, tmp1 ++ add.d dest, dest, tmp1 ++ ++ b strcpy_loop_aligned_1 ++ ++strcpy_page_cross: ++/* ++ ld.d from aligned address(src & ~0x7). ++ check if high bytes have \0. ++ it not, go back to page cross ok, ++ since the string is supposed to cross the page bound in such situation. ++ if it is, do a srl for data to make it seems like a direct double word from src, ++ then go to 4/2/1 strcpy end. ++ ++ tmp4 is 0xffff...ffff mask ++ tmp2 demonstrate the bytes to be masked ++ tmp2 = src_off << 3 ++ data = data >> (src_off * 8) | -1 << (64 - src_off * 8) ++ and ++ -1 << (64 - src_off * 8) -> ~(-1 >> (src_off * 8)) ++ ++*/ ++ li.w tmp1, 0x7 ++ andn tmp3, src, tmp1 ++ ld.d data, tmp3, 0 ++ li.w tmp4, -1 ++ slli.d tmp2, src_off, 3 ++ srl.d tmp4, tmp4, tmp2 ++ srl.d data, data, tmp2 ++ nor tmp4, tmp4, zero ++ or data, data, tmp4 ++ sub.d tmp1, data, zeroones ++ or tmp2, data, sevenf ++ andn has_nul, tmp1, tmp2 ++ beqz has_nul, strcpy_page_cross_ok ++ b strcpy_end ++END(STRCPY) ++#ifndef ANDROID_CHANGES ++#ifdef _LIBC ++libc_hidden_builtin_def (strcpy) ++#endif ++#endif +diff --git a/sysdeps/loongarch/lp64/strlen.S b/sysdeps/loongarch/lp64/strlen.S +new file mode 100644 +index 00000000..a34d8b69 +--- /dev/null ++++ b/sysdeps/loongarch/lp64/strlen.S +@@ -0,0 +1,135 @@ ++/* Copyright 2016 Loongson Technology Corporation Limited */ ++ ++/* Author: Songyuekun songyuekun@loongson.cn */ ++ ++/* ++ * ISA: MIPS64R2 ++ * ABI: N64 ++ */ ++/* ++algorithm: ++ ++ #. use ld/ldr to access word/partial word in the string ++ ++ #. use (x - 0x0101010101010101) & (~(x | 0x7f7f7f7f7f7f7f7f) != 0 to ++ judge if x has zero byte ++ ++ #. use dctz((x - 0x0101010101010101) & (~(x | 0x7f7f7f7f7f7f7f7f) >> 3 ++ to get the index of first rightmost zero byte in dword x; ++ ++ #. use dctz(x) = 64 - dclz(~x & (x-1)); ++ ++ #. use pointer to the last non zero byte minus pointer to the start ++ of the string to get the length of string ++ ++*/ ++ ++ ++#include ++#include ++ ++ ++ ++#define L_ADDIU addi.d ++#define L_ADDU add.d ++#define L_SUBU sub.d ++ ++#define STRLEN strlen ++#define L(x) x ++ ++ ++/* size_t strlen (const char *s1); */ ++ ++ .text; ++ .globl strlen; ++ .align 5; ++ cfi_startproc ; ++ .type strlen, @function; ++strlen: ++ ++ //LEAF(strlen) ++ #preld 0, a0, 0 ++ ++ nor t4, zero, zero ++ lu12i.w a2, 0x01010 ++ andi t5, a0, 0x7 ++ ++ li.w t7, 0x7 ++ slli.d t6, t5, 0x3 ++ andn t7, a0, t7 ++ ld.d a1, t7, 0 ++ sub.d t7, zero, t6 ++ sll.d t4, t4, t7 ++ maskeqz t4, t4, t6 ++ srl.d a1, a1, t6 ++ or a1, a1, t4 ++ ++ ++ ori a2, a2, 0x101 ++ nor t1, a1, zero ++ li.w a4, 8 ++ ++ #preld 0, a0, 32 ++ bstrins.d a2, a2, 63, 32 ++ sub.d a5, a4, t5 ++ move t5, a0 ++ ++ sub.d t0, a1, a2 ++ slli.d t4, a2, 7 ++ nor a3, zero, t4 ++ nor t1, a1, a3 ++ ++ and t0, t0, t1 ++ #preld 0, a0, 64 ++ bnez t0, strlen_count1 /* instead of use bnel with daddu a0, a0, a5 in branch slot */ ++ L_ADDU a0, a0, a5 ++strlen_loop: ++ ld.d a1, a0, 0 ++ sub.d t0, a1, a2 ++ and t1, t0, t4 ++ bnez t1, strlen_count_pre ++ ld.d a1, a0, 8 ++ sub.d t0, a1, a2 ++ and t1, t0, t4 ++ L_ADDIU a0, a0, 16 ++ beqz t1, strlen_loop ++strlen_count: ++ addi.d a0, a0, -8 ++strlen_count_pre: ++ nor t1, a1, a3 ++ and t0, t0, t1 ++ beqz t0, strlen_noascii_start ++strlen_count1: ++ ctz.d t1, t0 ++ L_SUBU v0, a0, t5 ++ srli.w t1, t1, 3 ++ L_ADDU v0, v0, t1 ++ jr ra ++strlen_noascii_start: ++ addi.d a0, a0, 8 ++strlen_loop_noascii: ++ ld.d a1, a0, 0 ++ sub.d t0, a1, a2 ++ nor t1, a1, a3 ++ and t0, t0, t1 ++ bnez t0, strlen_count1 ++ ld.d a1, a0, 8 ++ sub.d t0, a1, a2 ++ nor t1, a1, a3 ++ and t0, t0, t1 ++ L_ADDIU a0, a0, 16 ++ beqz t0, strlen_loop_noascii ++ addi.d a0, a0, -8 ++ ctz.d t1, t0 ++ L_SUBU v0, a0, t5 ++ srli.w t1, t1, 3 ++ L_ADDU v0, v0, t1 ++ jr ra ++END(STRLEN) ++ ++#ifndef ANDROID_CHANGES ++#ifdef _LIBC ++libc_hidden_builtin_def (strlen) ++#endif ++#endif ++ +diff --git a/sysdeps/loongarch/lp64/strncmp.S b/sysdeps/loongarch/lp64/strncmp.S +new file mode 100644 +index 00000000..29cc7b02 +--- /dev/null ++++ b/sysdeps/loongarch/lp64/strncmp.S +@@ -0,0 +1,269 @@ ++/* Copyright 2016 Loongson Technology Corporation Limited */ ++ ++/* Author: songyuekun songyuekun@loongson.cn */ ++ ++/* ++ * ISA: MIPS64R2 ++ * ABI: N64 ++ */ ++ ++/* basic algorithm : ++ ++ +. let t0, t1 point to a0, a1, if a0 has smaller low 3 bit of a0 and a1, ++ set a4 to 1 and let t0 point to the larger of lower 3bit of a0 and a1 ++ ++ +. if low 3 bit of a0 equal low 3 bit of a0, use a ldr one time and more ld other times; ++ ++ +. if not, load partial t2 and t3, check if t2 has \0; ++ ++ +. then use use ld for t0, ldr for t1, ++ ++ +. if partial 8 byte from t1 has \0, compare partial 8 byte from t1 with 8 ++ byte from t0 with a mask in a7 ++ ++ +. if not, ldl other part of t1, compare 8 byte from t1 with 8 byte from t0 ++ ++ +. if (v0 - 0x0101010101010101) & (~v0) & 0x8080808080808080 != 0, v0 has ++ one byte is \0, else has no \0 ++ ++ +. for partial 8 byte from ldr t3, 0(a0), preload t3 with 0xffffffffffffffff ++ ++ ++*/ ++#include ++#include ++ ++ ++#define STRNCMP strncmp ++ ++#define REP8_01 0x0101010101010101 ++#define REP8_7f 0x7f7f7f7f7f7f7f7f ++#define REP8_80 0x8080808080808080 ++ ++/* Parameters and Results */ ++#define src1 a0 ++#define src2 a1 ++#define limit a2 ++#define result v0 ++// Note: v0 = a0 in N64 ABI ++ ++ ++/* Internal variable */ ++#define data1 t0 ++#define data2 t1 ++#define has_nul t2 ++#define diff t3 ++#define syndrome t4 ++#define zeroones t5 ++#define sevenf t6 ++#define pos t7 ++#define exchange t8 ++#define tmp1 a5 ++#define tmp2 a6 ++#define tmp3 a7 ++#define src1_off a3 ++#define limit_wd a4 ++ ++ ++/* int strncmp (const char *s1, const char *s2); */ ++ ++LEAF(STRNCMP) ++ .align 4 ++ beqz limit, strncmp_ret0 ++ ++ xor tmp1, src1, src2 ++ lu12i.w zeroones, 0x01010 ++ lu12i.w sevenf, 0x7f7f7 ++ andi src1_off, src1, 0x7 ++ ori zeroones, zeroones, 0x101 ++ andi tmp1, tmp1, 0x7 ++ ori sevenf, sevenf, 0xf7f ++ bstrins.d zeroones, zeroones, 63, 32 ++ bstrins.d sevenf, sevenf, 63, 32 ++ bnez tmp1, strncmp_misaligned8 ++ bnez src1_off, strncmp_mutual_align ++ /* */ ++ addi.d limit_wd, limit, -1 ++ srli.d limit_wd, limit_wd, 3 ++ ++strncmp_loop_aligned: ++ ld.d data1, src1, 0 ++ addi.d src1, src1, 8 ++ ld.d data2, src2, 0 ++ addi.d src2, src2, 8 ++strncmp_start_realigned: ++ addi.d limit_wd, limit_wd, -1 ++ sub.d tmp1, data1, zeroones ++ or tmp2, data1, sevenf ++ xor diff, data1, data2 ++ andn has_nul, tmp1, tmp2 ++ srli.d tmp1, limit_wd, 63 ++ or syndrome, diff, has_nul ++ or tmp2, syndrome, tmp1 ++ beqz tmp2, strncmp_loop_aligned ++ ++ /* if not reach limit */ ++ bge limit_wd, zero, strncmp_not_limit ++ /* if reach limit */ ++ andi limit, limit, 0x7 ++ li.w tmp1, 0x8 ++ sub.d limit, tmp1, limit ++ slli.d limit, limit, 0x3 ++ li.d tmp1, -1 ++ srl.d tmp1, tmp1, limit ++ and data1, data1, tmp1 ++ and data2, data2, tmp1 ++ orn syndrome, syndrome, tmp1 ++ ++ ++strncmp_not_limit: ++ ctz.d pos, syndrome ++ bstrins.d pos, zero, 2, 0 ++ srl.d data1, data1, pos ++ srl.d data2, data2, pos ++ andi data1, data1, 0xff ++ andi data2, data2, 0xff ++ sub.d result, data1, data2 ++ jr ra ++ ++ ++ ++strncmp_mutual_align: ++ bstrins.d src1, zero, 2, 0 ++ bstrins.d src2, zero, 2, 0 ++ slli.d tmp1, src1_off, 0x3 ++ ld.d data1, src1, 0 ++ ld.d data2, src2, 0 ++ addi.d src2, src2, 8 ++ addi.d src1, src1, 8 ++ ++ addi.d limit_wd, limit, -1 ++ andi tmp3, limit_wd, 0x7 ++ srli.d limit_wd, limit_wd, 3 ++ add.d limit, limit, src1_off ++ add.d tmp3, tmp3, src1_off ++ srli.d tmp3, tmp3, 3 ++ add.d limit_wd, limit_wd, tmp3 ++ ++ sub.d tmp1, zero, tmp1 ++ nor tmp2, zero, zero ++ srl.d tmp2, tmp2, tmp1 ++ or data1, data1, tmp2 ++ or data2, data2, tmp2 ++ b strncmp_start_realigned ++ ++strncmp_misaligned8: ++ ++ li.w tmp1, 0x10 ++ bge limit, tmp1, strncmp_try_words ++strncmp_byte_loop: ++ ld.bu data1, src1, 0 ++ ld.bu data2, src2, 0 ++ addi.d limit, limit, -1 ++ xor tmp1, data1, data2 ++ masknez tmp1, data1, tmp1 ++ maskeqz tmp1, limit, tmp1 ++ beqz tmp1, strncmp_done ++ ++ ld.bu data1, src1, 1 ++ ld.bu data2, src2, 1 ++ addi.d src1, src1, 2 ++ addi.d src2, src2, 2 ++ addi.d limit, limit, -1 ++ xor tmp1, data1, data2 ++ masknez tmp1, data1, tmp1 ++ maskeqz tmp1, limit, tmp1 ++ bnez tmp1, strncmp_byte_loop ++ ++ ++strncmp_done: ++ sub.d result, data1, data2 ++ jr ra ++ ++strncmp_try_words: ++ srli.d limit_wd, limit, 3 ++ beqz src1_off, strncmp_do_misaligned ++ ++ sub.d src1_off, zero, src1_off ++ andi src1_off, src1_off, 0x7 ++ sub.d limit, limit, src1_off ++ srli.d limit_wd, limit, 0x3 ++ ++ ++strncmp_page_end_loop: ++ ld.bu data1, src1, 0 ++ ld.bu data2, src2, 0 ++ addi.d src1, src1, 1 ++ addi.d src2, src2, 1 ++ xor tmp1, data1, data2 ++ masknez tmp1, data1, tmp1 ++ beqz tmp1, strncmp_done ++ andi tmp1, src1, 0x7 ++ bnez tmp1, strncmp_page_end_loop ++strncmp_do_misaligned: ++ li.w src1_off, 0x8 ++ addi.d limit_wd, limit_wd, -1 ++ blt limit_wd, zero, strncmp_done_loop ++ ++strncmp_loop_misaligned: ++ andi tmp2, src2, 0xff8 ++ xori tmp2, tmp2, 0xff8 ++ beqz tmp2, strncmp_page_end_loop ++ ++ ld.d data1, src1, 0 ++ ld.d data2, src2, 0 ++ addi.d src1, src1, 8 ++ addi.d src2, src2, 8 ++ sub.d tmp1, data1, zeroones ++ or tmp2, data1, sevenf ++ xor diff, data1, data2 ++ andn has_nul, tmp1, tmp2 ++ or syndrome, diff, has_nul ++ bnez syndrome, strncmp_not_limit ++ addi.d limit_wd, limit_wd, -1 ++ #blt zero, limit_wd, strncmp_loop_misaligned ++ bge limit_wd, zero, strncmp_loop_misaligned ++ ++strncmp_done_loop: ++ andi limit, limit, 0x7 ++ beqz limit, strncmp_not_limit ++ /* Read the last double word */ ++ /* check if the final part is about to exceed the page */ ++ andi tmp1, src2, 0x7 ++ andi tmp2, src2, 0xff8 ++ add.d tmp1, tmp1, limit ++ xori tmp2, tmp2, 0xff8 ++ andi tmp1, tmp1, 0x8 ++ masknez tmp1, tmp1, tmp2 ++ bnez tmp1, strncmp_byte_loop ++ addi.d src1, src1, -8 ++ addi.d src2, src2, -8 ++ ldx.d data1, src1, limit ++ ldx.d data2, src2, limit ++ sub.d tmp1, data1, zeroones ++ or tmp2, data1, sevenf ++ xor diff, data1, data2 ++ andn has_nul, tmp1, tmp2 ++ or syndrome, diff, has_nul ++ bnez syndrome, strncmp_not_limit ++ ++strncmp_ret0: ++ move result, zero ++ jr ra ++/* check ++ if ((src1 != 0) && ((src2 == 0 ) || (src1 < src2))) ++ then exchange(src1,src2) ++ ++*/ ++ ++ ++ ++ ++ ++ ++END(STRNCMP) ++#ifndef ANDROID_CHANGES ++#ifdef _LIBC ++libc_hidden_builtin_def (strncmp) ++#endif ++#endif +diff --git a/sysdeps/loongarch/lp64/strnlen.S b/sysdeps/loongarch/lp64/strnlen.S +new file mode 100644 +index 00000000..3a204686 +--- /dev/null ++++ b/sysdeps/loongarch/lp64/strnlen.S +@@ -0,0 +1,155 @@ ++/* Copyright 2016 Loongson Technology Corporation Limited */ ++ ++/* Author: Songyuekun songyuekun@loongson.cn */ ++ ++/* ++ * ISA: MIPS64R2 ++ * ABI: N64 ++ */ ++/* ++algorithm: ++ ++ #. use ld/ldr to access word/partial word in the string ++ ++ #. use (x - 0x0101010101010101) & (~(x | 0x7f7f7f7f7f7f7f7f) != 0 to ++ judge if x has zero byte ++ ++ #. use dctz((x - 0x0101010101010101) & (~(x | 0x7f7f7f7f7f7f7f7f) >> 3 ++ to get the index of first rightmost zero byte in dword x; ++ ++ #. use dctz(x) = 64 - dclz(~x & (x-1)); ++ ++ #. use pointer to the last non zero byte minus pointer to the start ++ of the string to get the length of string ++ ++*/ ++ ++#include ++#include ++ ++ ++ ++#define L_ADDIU addi.d ++#define L_ADDU add.d ++#define L_SUBU sub.d ++ ++#define STRNLEN __strnlen ++#define L(x) x ++/* rd <- if rc then ra else rb ++ will destroy t6 ++*/ ++ ++#define CONDITIONSEL(rd,ra,rb,rc)\ ++ masknez a5, rb, rc;\ ++ maskeqz rd, ra, rc;\ ++ or rd, rd, a5 ++ ++ ++/* Parameters and Results */ ++#define srcin a0 ++#define limit a1 ++#define len v0 ++ ++ ++/* Internal variable */ ++#define data1 t0 ++#define data2 t1 ++#define has_nul1 t2 ++#define has_nul2 t3 ++#define src t4 ++#define zeroones t5 ++#define sevenf t6 ++#define data2a t7 ++#define tmp6 t7 ++#define pos t8 ++#define tmp1 a2 ++#define tmp2 a3 ++#define tmp3 a4 ++#define tmp4 a5 ++#define tmp5 a6 ++#define limit_wd a7 ++ ++ ++ ++/* size_t strnlen (const char *s1,size_t maxlen); */ ++ ++LEAF(STRNLEN) ++ ++ .align 4 ++ beqz limit, L(_hit_limit) ++ lu12i.w zeroones, 0x01010 ++ lu12i.w sevenf, 0x7f7f7 ++ ori zeroones, zeroones, 0x101 ++ ori sevenf, sevenf, 0xf7f ++ bstrins.d zeroones, zeroones, 63, 32 ++ bstrins.d sevenf, sevenf, 63, 32 ++ andi tmp1, srcin, 15 ++ sub.d src, srcin, tmp1 ++ bnez tmp1, L(misaligned) ++ addi.d limit_wd, limit, -1 ++ srli.d limit_wd, limit_wd, 4 ++L(_loop): ++ ld.d data1, src, 0 ++ ld.d data2, src, 8 ++ addi.d src, src, 16 ++L(_realigned): ++ sub.d tmp1, data1, zeroones ++ or tmp2, data1, sevenf ++ sub.d tmp3, data2, zeroones ++ or tmp4, data2, sevenf ++ andn has_nul1, tmp1, tmp2 ++ andn has_nul2, tmp3, tmp4 ++ addi.d limit_wd, limit_wd, -1 ++ srli.d tmp1, limit_wd, 63 ++ or tmp2, has_nul1, has_nul2 ++ or tmp3, tmp1, tmp2 ++ beqz tmp3, L(_loop) ++ beqz tmp2, L(_hit_limit) ++ sub.d len, src, srcin ++ beqz has_nul1, L(_nul_in_data2) ++ move has_nul2, has_nul1 ++ addi.d len, len, -8 ++L(_nul_in_data2): ++ ctz.d pos, has_nul2 ++ srli.d pos, pos, 3 ++ addi.d len, len, -8 ++ add.d len, len, pos ++ sltu tmp1, len, limit ++ CONDITIONSEL(len,len,limit,tmp1) ++ jr ra ++ ++ ++L(misaligned): ++ addi.d limit_wd, limit, -1 ++ sub.d tmp4, zero, tmp1 ++ andi tmp3, limit_wd, 15 ++ srli.d limit_wd, limit_wd, 4 ++ li.d tmp5, -1 ++ ld.d data1, src, 0 ++ ld.d data2, src, 8 ++ addi.d src, src, 16 ++ slli.d tmp4, tmp4, 3 ++ add.d tmp3, tmp3, tmp1 ++ srl.d tmp2, tmp5, tmp4 ++ srli.d tmp3, tmp3, 4 ++ add.d limit_wd, limit_wd, tmp3 ++ or data1, data1, tmp2 ++ or data2a, data2, tmp2 ++ li.w tmp3, 9 ++ sltu tmp1, tmp1, tmp3 ++ CONDITIONSEL(data1,data1,tmp5,tmp1) ++ CONDITIONSEL(data2,data2,data2a,tmp1) ++ b L(_realigned) ++ ++ ++L(_hit_limit): ++ move len, limit ++ jr ra ++END(STRNLEN) ++#ifndef ANDROID_CHANGES ++#ifdef _LIBC ++weak_alias (__strnlen, strnlen) ++libc_hidden_def (strnlen) ++libc_hidden_def (__strnlen) ++#endif ++#endif +diff --git a/sysdeps/loongarch/lstat.c b/sysdeps/loongarch/lstat.c +new file mode 100644 +index 00000000..f47a56af +--- /dev/null ++++ b/sysdeps/loongarch/lstat.c +@@ -0,0 +1 @@ ++#include +diff --git a/sysdeps/loongarch/lstat64.c b/sysdeps/loongarch/lstat64.c +new file mode 100644 +index 00000000..d6811656 +--- /dev/null ++++ b/sysdeps/loongarch/lstat64.c +@@ -0,0 +1 @@ ++#include +diff --git a/sysdeps/loongarch/machine-gmon.h b/sysdeps/loongarch/machine-gmon.h +new file mode 100644 +index 00000000..0b49082d +--- /dev/null ++++ b/sysdeps/loongarch/machine-gmon.h +@@ -0,0 +1,37 @@ ++/* Copyright (C) 2020-2021 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 ++ . */ ++ ++/* Accept 'frompc' address as argument from the function that calls ++ _mcount for profiling. Use __builtin_return_address (0) ++ for the 'selfpc' address. */ ++ ++#include ++ ++static void mcount_internal (unsigned long int frompc, ++ unsigned long int selfpc); ++ ++#define _MCOUNT_DECL(frompc, selfpc) \ ++static inline void mcount_internal (unsigned long int frompc, \ ++unsigned long int selfpc) ++ ++#define MCOUNT \ ++void _mcount (void *frompc) \ ++{ \ ++ mcount_internal ((unsigned long int) frompc, \ ++ (unsigned long int) RETURN_ADDRESS (0)); \ ++} +diff --git a/sysdeps/loongarch/math_private.h b/sysdeps/loongarch/math_private.h +new file mode 100644 +index 00000000..140eef07 +--- /dev/null ++++ b/sysdeps/loongarch/math_private.h +@@ -0,0 +1,245 @@ ++/* Internal math stuff. LOONGARCH version. ++ Copyright (C) 2013-2018 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 ++ . */ ++ ++#ifndef LOONGARCH_MATH_PRIVATE_H ++#define LOONGARCH_MATH_PRIVATE_H 1 ++ ++/* Inline functions to speed up the math library implementation. The ++ default versions of these routines are in generic/math_private.h ++ and call fesetround, feholdexcept, etc. These routines use inlined ++ code instead. */ ++ ++#ifdef __loongarch_hard_float ++ ++# include ++# include ++# include ++ ++# 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_loongarch (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_loongarch ++# define libc_feholdexceptf libc_feholdexcept_loongarch ++# define libc_feholdexceptl libc_feholdexcept_loongarch ++ ++static __always_inline void ++libc_fesetround_loongarch (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_loongarch ++# define libc_fesetroundf libc_fesetround_loongarch ++# define libc_fesetroundl libc_fesetround_loongarch ++ ++static __always_inline void ++libc_feholdexcept_setround_loongarch (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_loongarch ++# define libc_feholdexcept_setroundf libc_feholdexcept_setround_loongarch ++# define libc_feholdexcept_setroundl libc_feholdexcept_setround_loongarch ++ ++# define libc_feholdsetround libc_feholdexcept_setround_loongarch ++# define libc_feholdsetroundf libc_feholdexcept_setround_loongarch ++# define libc_feholdsetroundl libc_feholdexcept_setround_loongarch ++ ++static __always_inline void ++libc_fesetenv_loongarch (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_loongarch ++# define libc_fesetenvf libc_fesetenv_loongarch ++# define libc_fesetenvl libc_fesetenv_loongarch ++ ++static __always_inline int ++libc_feupdateenv_test_loongarch (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_loongarch ++# define libc_feupdateenv_testf libc_feupdateenv_test_loongarch ++# define libc_feupdateenv_testl libc_feupdateenv_test_loongarch ++ ++static __always_inline void ++libc_feupdateenv_loongarch (fenv_t *envp) ++{ ++ libc_feupdateenv_test_loongarch (envp, 0); ++} ++# define libc_feupdateenv libc_feupdateenv_loongarch ++# define libc_feupdateenvf libc_feupdateenv_loongarch ++# define libc_feupdateenvl libc_feupdateenv_loongarch ++ ++# define libc_feresetround libc_feupdateenv_loongarch ++# define libc_feresetroundf libc_feupdateenv_loongarch ++# define libc_feresetroundl libc_feupdateenv_loongarch ++ ++static __always_inline int ++libc_fetestexcept_loongarch (int excepts) ++{ ++ int cw; ++ ++ /* Get current control word. */ ++ _FPU_GETCW (cw); ++ ++ return cw & excepts & FE_ALL_EXCEPT; ++} ++# define libc_fetestexcept libc_fetestexcept_loongarch ++# define libc_fetestexceptf libc_fetestexcept_loongarch ++# define libc_fetestexceptl libc_fetestexcept_loongarch ++ ++/* Enable support for rounding mode context. */ ++# define HAVE_RM_CTX 1 ++ ++static __always_inline void ++libc_feholdexcept_setround_loongarch_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_loongarch_ctx ++# define libc_feholdexcept_setroundf_ctx libc_feholdexcept_setround_loongarch_ctx ++# define libc_feholdexcept_setroundl_ctx libc_feholdexcept_setround_loongarch_ctx ++ ++static __always_inline void ++libc_fesetenv_loongarch_ctx (struct rm_ctx *ctx) ++{ ++ libc_fesetenv_loongarch (&ctx->env); ++} ++# define libc_fesetenv_ctx libc_fesetenv_loongarch_ctx ++# define libc_fesetenvf_ctx libc_fesetenv_loongarch_ctx ++# define libc_fesetenvl_ctx libc_fesetenv_loongarch_ctx ++ ++static __always_inline void ++libc_feupdateenv_loongarch_ctx (struct rm_ctx *ctx) ++{ ++ if (__glibc_unlikely (ctx->updated_status)) ++ libc_feupdateenv_test_loongarch (&ctx->env, 0); ++} ++# define libc_feupdateenv_ctx libc_feupdateenv_loongarch_ctx ++# define libc_feupdateenvf_ctx libc_feupdateenv_loongarch_ctx ++# define libc_feupdateenvl_ctx libc_feupdateenv_loongarch_ctx ++# define libc_feresetround_ctx libc_feupdateenv_loongarch_ctx ++# define libc_feresetroundf_ctx libc_feupdateenv_loongarch_ctx ++# define libc_feresetroundl_ctx libc_feupdateenv_loongarch_ctx ++ ++static __always_inline void ++libc_feholdsetround_loongarch_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_loongarch_ctx ++# define libc_feholdsetroundf_ctx libc_feholdsetround_loongarch_ctx ++# define libc_feholdsetroundl_ctx libc_feholdsetround_loongarch_ctx ++ ++#endif ++ ++#include_next ++ ++#endif +diff --git a/sysdeps/loongarch/memusage.h b/sysdeps/loongarch/memusage.h +new file mode 100644 +index 00000000..bdf99f8a +--- /dev/null ++++ b/sysdeps/loongarch/memusage.h +@@ -0,0 +1,21 @@ ++/* Copyright (C) 2020-2021 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 ++ . */ ++ ++#define GETSP() ({ register uintptr_t stack_ptr asm ("$sp"); stack_ptr; }) ++ ++#include +diff --git a/sysdeps/loongarch/mknod.c b/sysdeps/loongarch/mknod.c +new file mode 100644 +index 00000000..1ed3681f +--- /dev/null ++++ b/sysdeps/loongarch/mknod.c +@@ -0,0 +1 @@ ++#include +diff --git a/sysdeps/loongarch/mknodat.c b/sysdeps/loongarch/mknodat.c +new file mode 100644 +index 00000000..82bc6ee6 +--- /dev/null ++++ b/sysdeps/loongarch/mknodat.c +@@ -0,0 +1 @@ ++#include +diff --git a/sysdeps/loongarch/nptl/Makefile b/sysdeps/loongarch/nptl/Makefile +new file mode 100644 +index 00000000..a1d5768a +--- /dev/null ++++ b/sysdeps/loongarch/nptl/Makefile +@@ -0,0 +1,26 @@ ++# Makefile for sysdeps/loongarch/nptl. ++# Copyright (C) 2005-2018 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 ++# . ++ ++ifeq ($(subdir),csu) ++gen-as-const-headers += tcb-offsets.sym ++endif ++ ++ifeq ($(subdir),nptl) ++libpthread-sysdep_routines += nptl-sysdep ++libpthread-shared-only-routines += nptl-sysdep ++endif +diff --git a/sysdeps/loongarch/nptl/bits/pthreadtypes-arch.h b/sysdeps/loongarch/nptl/bits/pthreadtypes-arch.h +new file mode 100644 +index 00000000..5a761355 +--- /dev/null ++++ b/sysdeps/loongarch/nptl/bits/pthreadtypes-arch.h +@@ -0,0 +1,68 @@ ++/* Copyright (C) 2020-2021 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 ++ . */ ++ ++#ifndef _BITS_PTHREADTYPES_ARCH_H ++#define _BITS_PTHREADTYPES_ARCH_H 1 ++ ++#include ++ ++#if __loongarch_xlen == 64 ++# define __SIZEOF_PTHREAD_ATTR_T 56 ++# define __SIZEOF_PTHREAD_MUTEX_T 40 ++# define __SIZEOF_PTHREAD_MUTEXATTR_T 4 ++# define __SIZEOF_PTHREAD_COND_T 48 ++# define __SIZEOF_PTHREAD_CONDATTR_T 4 ++# define __SIZEOF_PTHREAD_RWLOCK_T 56 ++# define __SIZEOF_PTHREAD_RWLOCKATTR_T 8 ++# define __SIZEOF_PTHREAD_BARRIER_T 32 ++# define __SIZEOF_PTHREAD_BARRIERATTR_T 4 ++#else ++# error "rv32i-based systems are not supported" ++#endif ++ ++#define __PTHREAD_COMPAT_PADDING_MID ++#define __PTHREAD_COMPAT_PADDING_END ++#define __PTHREAD_MUTEX_LOCK_ELISION 0 ++#define __PTHREAD_MUTEX_USE_UNION 0 ++#define __PTHREAD_MUTEX_NUSERS_AFTER_KIND 0 ++ ++#define __LOCK_ALIGNMENT ++#define __ONCE_ALIGNMENT ++ ++/* There is a lot of padding in this structure. While it's not strictly ++ necessary on LoongArch, we're going to leave it in to be on the safe side in ++ case it's needed in the future. Most other architectures have the padding, ++ so this gives us the same extensibility as everyone else has. */ ++struct __pthread_rwlock_arch_t ++{ ++ unsigned int __readers; ++ unsigned int __writers; ++ unsigned int __wrphase_futex; ++ unsigned int __writers_futex; ++ unsigned int __pad3; ++ unsigned int __pad4; ++ int __cur_writer; ++ int __shared; ++ unsigned long int __pad1; ++ unsigned long int __pad2; ++ unsigned int __flags; ++}; ++ ++#define __PTHREAD_RWLOCK_ELISION_EXTRA 0 ++ ++#endif /* bits/pthreadtypes.h */ +diff --git a/sysdeps/loongarch/nptl/bits/semaphore.h b/sysdeps/loongarch/nptl/bits/semaphore.h +new file mode 100644 +index 00000000..a9ddefb2 +--- /dev/null ++++ b/sysdeps/loongarch/nptl/bits/semaphore.h +@@ -0,0 +1,33 @@ ++/* Copyright (C) 2020-2021 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 ++ . */ ++ ++#ifndef _SEMAPHORE_H ++# error "Never use directly; include instead." ++#endif ++ ++#define __SIZEOF_SEM_T (4 * __SIZEOF_POINTER__) ++ ++/* Value returned if `sem_open' failed. */ ++#define SEM_FAILED ((sem_t *) 0) ++ ++ ++typedef union ++{ ++ char __size[__SIZEOF_SEM_T]; ++ long int __align; ++} sem_t; +diff --git a/sysdeps/loongarch/nptl/libc-lowlevellock.c b/sysdeps/loongarch/nptl/libc-lowlevellock.c +new file mode 100644 +index 00000000..9523fb46 +--- /dev/null ++++ b/sysdeps/loongarch/nptl/libc-lowlevellock.c +@@ -0,0 +1,8 @@ ++/* This kludge works around a libpthread static linking problem: ++ https://sourceware.org/bugzilla/show_bug.cgi?id=15648. */ ++ ++#ifndef SHARED ++# define __lll_lock_wait_private weak_function __lll_lock_wait_private ++#endif ++ ++#include +diff --git a/sysdeps/loongarch/nptl/nptl-sysdep.S b/sysdeps/loongarch/nptl/nptl-sysdep.S +new file mode 100644 +index 00000000..3f5c2a36 +--- /dev/null ++++ b/sysdeps/loongarch/nptl/nptl-sysdep.S +@@ -0,0 +1,2 @@ ++/* Pull in __syscall_error. */ ++#include +diff --git a/sysdeps/loongarch/nptl/pthread-offsets.h b/sysdeps/loongarch/nptl/pthread-offsets.h +new file mode 100644 +index 00000000..04130879 +--- /dev/null ++++ b/sysdeps/loongarch/nptl/pthread-offsets.h +@@ -0,0 +1,23 @@ ++/* Copyright (C) 2020-2021 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 ++ . */ ++ ++#define __PTHREAD_MUTEX_NUSERS_OFFSET 12 ++#define __PTHREAD_MUTEX_KIND_OFFSET 16 ++#define __PTHREAD_MUTEX_SPINS_OFFSET 20 ++#define __PTHREAD_MUTEX_ELISION_OFFSET 22 ++#define __PTHREAD_MUTEX_LIST_OFFSET 24 +diff --git a/sysdeps/loongarch/nptl/pthreaddef.h b/sysdeps/loongarch/nptl/pthreaddef.h +new file mode 100644 +index 00000000..87c407bc +--- /dev/null ++++ b/sysdeps/loongarch/nptl/pthreaddef.h +@@ -0,0 +1,32 @@ ++/* Copyright (C) 2020-2021 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 ++ . */ ++ ++/* Default stack size. */ ++#define ARCH_STACK_DEFAULT_SIZE (2 * 1024 * 1024) ++ ++/* Required stack pointer alignment at beginning. */ ++#define STACK_ALIGN 16 ++ ++/* Minimal stack size after allocating thread descriptor and guard size. */ ++#define MINIMAL_REST_STACK 2048 ++ ++/* Alignment requirement for TCB. */ ++#define TCB_ALIGNMENT 16 ++ ++/* Location of current stack frame. */ ++#define CURRENT_STACK_FRAME __builtin_frame_address (0) +diff --git a/sysdeps/loongarch/nptl/tcb-offsets.sym b/sysdeps/loongarch/nptl/tcb-offsets.sym +new file mode 100644 +index 00000000..ab4981f2 +--- /dev/null ++++ b/sysdeps/loongarch/nptl/tcb-offsets.sym +@@ -0,0 +1,6 @@ ++#include ++#include ++ ++#define thread_offsetof(mem) (long)(offsetof (struct pthread, mem) - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE) ++ ++MULTIPLE_THREADS_OFFSET thread_offsetof (header.multiple_threads) +diff --git a/sysdeps/loongarch/nptl/tls.h b/sysdeps/loongarch/nptl/tls.h +new file mode 100644 +index 00000000..8d2d4ca2 +--- /dev/null ++++ b/sysdeps/loongarch/nptl/tls.h +@@ -0,0 +1,147 @@ ++/* Copyright (C) 2020-2021 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 ++ . */ ++ ++#ifndef _LOONGARCH_TLS_H ++#define _LOONGARCH_TLS_H 1 ++ ++#include ++ ++#ifndef __ASSEMBLER__ ++# include ++# include ++# include ++# include ++ ++register void *__thread_self asm ("$tp"); /* FIXME */ ++# define READ_THREAD_POINTER() ({ __thread_self; }) ++ ++/* Get system call information. */ ++# include ++ ++/* The TP points to the start of the thread blocks. */ ++# define TLS_DTV_AT_TP 1 ++# define TLS_TCB_AT_TP 0 ++ ++/* Get the thread descriptor definition. */ ++# include ++ ++typedef struct ++{ ++ dtv_t *dtv; ++ void *private; ++} tcbhead_t; ++ ++/* This is the size of the initial TCB. Because our TCB is before the thread ++ pointer, we don't need this. */ ++# define TLS_INIT_TCB_SIZE 0 ++ ++/* Alignment requirements for the initial TCB. */ ++# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread) ++ ++/* This is the size of the TCB. Because our TCB is before the thread ++ pointer, we don't need this. */ ++# define TLS_TCB_SIZE 0 ++ ++/* Alignment requirements for the TCB. */ ++# define TLS_TCB_ALIGN __alignof__ (struct pthread) ++ ++/* This is the size we need before TCB - actually, it includes the TCB. */ ++# define TLS_PRE_TCB_SIZE \ ++ (sizeof (struct pthread) \ ++ + ((sizeof (tcbhead_t) + TLS_TCB_ALIGN - 1) & ~(TLS_TCB_ALIGN - 1))) ++ ++/* The thread pointer tp points to the end of the TCB. ++ The pthread_descr structure is immediately in front of the TCB. */ ++# define TLS_TCB_OFFSET 0 ++ ++/* Install the dtv pointer. The pointer passed is to the element with ++ index -1 which contain the length. */ ++# define INSTALL_DTV(tcbp, dtvp) \ ++ (((tcbhead_t *) (tcbp))[-1].dtv = (dtvp) + 1) ++ ++/* Install new dtv for current thread. */ ++# define INSTALL_NEW_DTV(dtv) \ ++ (THREAD_DTV() = (dtv)) ++ ++/* Return dtv of given thread descriptor. */ ++# define GET_DTV(tcbp) \ ++ (((tcbhead_t *) (tcbp))[-1].dtv) ++ ++/* Code to initially initialize the thread pointer. */ ++# define TLS_INIT_TP(tcbp) \ ++ ({ __thread_self = (char*)tcbp + TLS_TCB_OFFSET; NULL; }) ++ ++/* Return the address of the dtv for the current thread. */ ++# define THREAD_DTV() \ ++ (((tcbhead_t *) (READ_THREAD_POINTER () - TLS_TCB_OFFSET))[-1].dtv) ++ ++/* Return the thread descriptor for the current thread. */ ++# define THREAD_SELF \ ++ ((struct pthread *) (READ_THREAD_POINTER () \ ++ - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE)) ++ ++/* Value passed to 'clone' for initialization of the thread register. */ ++# define TLS_DEFINE_INIT_TP(tp, pd) \ ++ void *tp = (void *) (pd) + TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE ++ ++/* Informs libthread_db that the thread pointer is register 2, which is used ++ * to know how to do THREAD_SELF. */ ++# define DB_THREAD_SELF \ ++ REGISTER (64, 64, 2 * 8, - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE) ++ ++/* Access to data in the thread descriptor is easy. */ ++# define THREAD_GETMEM(descr, member) \ ++ descr->member ++# define THREAD_GETMEM_NC(descr, member, idx) \ ++ descr->member[idx] ++# define THREAD_SETMEM(descr, member, value) \ ++ descr->member = (value) ++# define THREAD_SETMEM_NC(descr, member, idx, value) \ ++ descr->member[idx] = (value) ++ ++/* l_tls_offset == 0 is perfectly valid, so we have to use some different ++ value to mean unset l_tls_offset. */ ++# define NO_TLS_OFFSET -1 ++ ++/* Get and set the global scope generation counter in struct pthread. */ ++# define THREAD_GSCOPE_IN_TCB 1 ++# define THREAD_GSCOPE_FLAG_UNUSED 0 ++# define THREAD_GSCOPE_FLAG_USED 1 ++# define THREAD_GSCOPE_FLAG_WAIT 2 ++# define THREAD_GSCOPE_RESET_FLAG() \ ++ do \ ++ { int __res \ ++ = atomic_exchange_rel (&THREAD_SELF->header.gscope_flag, \ ++ THREAD_GSCOPE_FLAG_UNUSED); \ ++ if (__res == THREAD_GSCOPE_FLAG_WAIT) \ ++ lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1, LLL_PRIVATE); \ ++ } \ ++ while (0) ++# define THREAD_GSCOPE_SET_FLAG() \ ++ do \ ++ { \ ++ THREAD_SELF->header.gscope_flag = THREAD_GSCOPE_FLAG_USED; \ ++ atomic_write_barrier (); \ ++ } \ ++ while (0) ++# define THREAD_GSCOPE_WAIT() \ ++ GL(dl_wait_lookup_done) () ++ ++#endif /* __ASSEMBLER__ */ ++ ++#endif /* tls.h */ +diff --git a/sysdeps/loongarch/preconfigure b/sysdeps/loongarch/preconfigure +new file mode 100644 +index 00000000..26ffe884 +--- /dev/null ++++ b/sysdeps/loongarch/preconfigure +@@ -0,0 +1,9 @@ ++case "$machine" in ++loongarch*) ++ base_machine=loongarch ++ machine=loongarch/lp64 ++ ;; ++esac ++ ++#TODO: this file is useless now. ++#Maybe we can make use of it to get arch info from GCC to set env +diff --git a/sysdeps/loongarch/pthread_atfork.c b/sysdeps/loongarch/pthread_atfork.c +new file mode 100644 +index 00000000..0f01d805 +--- /dev/null ++++ b/sysdeps/loongarch/pthread_atfork.c +@@ -0,0 +1 @@ ++#include +diff --git a/sysdeps/loongarch/setjmp.S b/sysdeps/loongarch/setjmp.S +new file mode 100644 +index 00000000..da09a93c +--- /dev/null ++++ b/sysdeps/loongarch/setjmp.S +@@ -0,0 +1,62 @@ ++/* Copyright (C) 2020-2021 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 ++ . */ ++ ++#include ++#include ++ ++ENTRY (_setjmp) ++ li.w a1,0 ++ b __sigsetjmp ++END (_setjmp) ++ENTRY (setjmp) ++ li.w a1,1 ++END (setjmp) ++ENTRY (__sigsetjmp) ++ REG_S ra, a0, 0*SZREG ++ REG_S sp, a0, 1*SZREG ++ REG_S x, a0, 2*SZREG ++ REG_S fp, a0, 3*SZREG ++ REG_S s0, a0, 4*SZREG ++ REG_S s1, a0, 5*SZREG ++ REG_S s2, a0, 6*SZREG ++ REG_S s3, a0, 7*SZREG ++ REG_S s4, a0, 8*SZREG ++ REG_S s5, a0, 9*SZREG ++ REG_S s6, a0, 10*SZREG ++ REG_S s7, a0, 11*SZREG ++ REG_S s8, a0, 12*SZREG ++ ++ FREG_S $f24, a0, 13*SZREG + 0*SZFREG ++ FREG_S $f25, a0, 13*SZREG + 1*SZFREG ++ FREG_S $f26, a0, 13*SZREG + 2*SZFREG ++ FREG_S $f27, a0, 13*SZREG + 3*SZFREG ++ FREG_S $f28, a0, 13*SZREG + 4*SZFREG ++ FREG_S $f29, a0, 13*SZREG + 5*SZFREG ++ FREG_S $f30, a0, 13*SZREG + 6*SZFREG ++ FREG_S $f31, a0, 13*SZREG + 7*SZFREG ++ ++#if !IS_IN (libc) && IS_IN(rtld) ++ li.w v0, 0 ++ jirl zero,ra,0 ++#else ++ b __sigjmp_save ++#endif ++END (__sigsetjmp) ++ ++hidden_def (__sigsetjmp) ++weak_alias (_setjmp, __GI__setjmp) +diff --git a/sysdeps/loongarch/sfp-machine.h b/sysdeps/loongarch/sfp-machine.h +new file mode 100644 +index 00000000..b5c79bc0 +--- /dev/null ++++ b/sysdeps/loongarch/sfp-machine.h +@@ -0,0 +1,79 @@ ++#include ++#include ++ ++#define _FP_W_TYPE_SIZE 64 ++#define _FP_W_TYPE unsigned long long ++#define _FP_WS_TYPE signed long long ++#define _FP_I_TYPE long long ++ ++#define _FP_MUL_MEAT_S(R,X,Y) \ ++ _FP_MUL_MEAT_1_imm(_FP_WFRACBITS_S,R,X,Y) ++#define _FP_MUL_MEAT_D(R,X,Y) \ ++ _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm) ++#define _FP_MUL_MEAT_Q(R,X,Y) \ ++ _FP_MUL_MEAT_2_wide_3mul(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm) ++ ++#define _FP_MUL_MEAT_DW_S(R,X,Y) \ ++ _FP_MUL_MEAT_DW_1_imm(_FP_WFRACBITS_S,R,X,Y) ++#define _FP_MUL_MEAT_DW_D(R,X,Y) \ ++ _FP_MUL_MEAT_DW_1_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm) ++#define _FP_MUL_MEAT_DW_Q(R,X,Y) \ ++ _FP_MUL_MEAT_DW_2_wide_3mul(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm) ++ ++#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_imm(S,R,X,Y,_FP_DIV_HELP_imm) ++#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_1_udiv_norm(D,R,X,Y) ++#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_2_udiv(Q,R,X,Y) ++ ++# define _FP_NANFRAC_S _FP_QNANBIT_S ++# define _FP_NANFRAC_D _FP_QNANBIT_D ++# define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0 ++ ++#define _FP_NANSIGN_S 0 ++#define _FP_NANSIGN_D 0 ++#define _FP_NANSIGN_Q 0 ++ ++#define _FP_KEEPNANFRACP 1 ++#define _FP_QNANNEGATEDP 0 ++ ++/* NaN payloads should be preserved for NAN2008. */ ++# define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \ ++ do \ ++ { \ ++ R##_s = X##_s; \ ++ _FP_FRAC_COPY_##wc (R, X); \ ++ R##_c = FP_CLS_NAN; \ ++ } \ ++ while (0) ++ ++#define _FP_DECL_EX fpu_control_t _fcw ++ ++#define FP_ROUNDMODE (_fcw & 0x300) ++ ++#define FP_RND_NEAREST FE_TONEAREST ++#define FP_RND_ZERO FE_TOWARDZERO ++#define FP_RND_PINF FE_UPWARD ++#define FP_RND_MINF FE_DOWNWARD ++ ++#define FP_EX_INVALID FE_INVALID ++#define FP_EX_OVERFLOW FE_OVERFLOW ++#define FP_EX_UNDERFLOW FE_UNDERFLOW ++#define FP_EX_DIVZERO FE_DIVBYZERO ++#define FP_EX_INEXACT FE_INEXACT ++ ++#define _FP_TININESS_AFTER_ROUNDING 1 ++ ++#ifdef __loongarch_hard_float ++#define FP_INIT_ROUNDMODE \ ++do { \ ++ _FPU_GETCW (_fcw); \ ++} while (0) ++ ++#define FP_HANDLE_EXCEPTIONS \ ++do { \ ++ if (__builtin_expect (_fex, 0)) \ ++ _FPU_SETCW (_fcw | _fex | (_fex << 8)); \ ++} while (0) ++#define FP_TRAPPING_EXCEPTIONS ((_fcw << 16) & 0x1f0000) ++#else ++#define FP_INIT_ROUNDMODE _fcw = FP_RND_NEAREST ++#endif +diff --git a/sysdeps/loongarch/sotruss-lib.c b/sysdeps/loongarch/sotruss-lib.c +new file mode 100644 +index 00000000..124db440 +--- /dev/null ++++ b/sysdeps/loongarch/sotruss-lib.c +@@ -0,0 +1,51 @@ ++/* Copyright (C) 2020-2021 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 ++ . */ ++ ++#define HAVE_ARCH_PLTENTER ++#define HAVE_ARCH_PLTEXIT ++ ++#include ++ ++ElfW(Addr) ++la_loongarch_gnu_pltenter (ElfW(Sym) *sym __attribute__ ((unused)), ++ unsigned int ndx __attribute__ ((unused)), ++ uintptr_t *refcook, uintptr_t *defcook, ++ La_loongarch_regs *regs, unsigned int *flags, ++ const char *symname, long int *framesizep) ++{ ++ print_enter (refcook, defcook, symname, ++ regs->lr_reg[0], regs->lr_reg[1], regs->lr_reg[2], ++ *flags); ++ ++ /* No need to copy anything, we will not need the parameters in any case. */ ++ *framesizep = 0; ++ ++ return sym->st_value; ++} ++ ++unsigned int ++la_loongarch_gnu_pltexit (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook, ++ uintptr_t *defcook, ++ const struct La_loongarch_regs *inregs, ++ struct La_loongarch_retval *outregs, ++ const char *symname) ++{ ++ print_exit (refcook, defcook, symname, outregs->lrv_a0); ++ ++ return 0; ++} +diff --git a/sysdeps/loongarch/stack_chk_fail_local.c b/sysdeps/loongarch/stack_chk_fail_local.c +new file mode 100644 +index 00000000..305871fb +--- /dev/null ++++ b/sysdeps/loongarch/stack_chk_fail_local.c +@@ -0,0 +1 @@ ++#include +diff --git a/sysdeps/loongarch/stackinfo.h b/sysdeps/loongarch/stackinfo.h +new file mode 100644 +index 00000000..5f5e6ad1 +--- /dev/null ++++ b/sysdeps/loongarch/stackinfo.h +@@ -0,0 +1,33 @@ ++/* Copyright (C) 2020-2021 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 ++ . */ ++ ++/* This file contains a bit of information about the stack allocation ++ of the processor. */ ++ ++#ifndef _STACKINFO_H ++#define _STACKINFO_H 1 ++ ++#include ++ ++/* On LoongArch the stack grows down. */ ++#define _STACK_GROWS_DOWN 1 ++ ++/* Default to a non-executable stack. */ ++#define DEFAULT_STACK_PERMS (PF_R | PF_W) ++ ++#endif /* stackinfo.h */ +diff --git a/sysdeps/loongarch/start.S b/sysdeps/loongarch/start.S +new file mode 100644 +index 00000000..cf0a14b5 +--- /dev/null ++++ b/sysdeps/loongarch/start.S +@@ -0,0 +1,51 @@ ++#define __ASSEMBLY__ 1 ++#include ++#include ++ ++/* The entry point's job is to call __libc_start_main. Per the ABI, ++ a0 contains the address of a function to be passed to atexit. ++ __libc_start_main wants this in a5. */ ++ ++/* ++int ++__libc_start_main (int (*main) (int, char **, char **), ++ int argc, ++ char **argv, ++ __typeof (main) init, ++ void (*fini) (void), ++ void (*rtld_fini) (void), ++ void *stack_end); ++*/ ++ ++ENTRY (ENTRY_POINT) ++ /* Terminate call stack by noting ra is undefined. Use a dummy ++ .cfi_label to force starting the FDE. */ ++ .cfi_label .Ldummy ++ cfi_undefined (1) ++ or a5, a0, zero /* rtld_fini */ ++ ++ /* 这个main必须要走GOT表拿到。因为main不一定是local的。 ++ 比如googletest就把main定义在动态库里了。 */ ++ la.got a0, t0, main ++#ifdef __loongarch64 ++ ld.d a1, sp, 0 ++ addi.d a2, sp, SZREG ++#elif defined __loongarch32 ++ ld.w a1, sp, 0 ++ addi.w a2, sp, SZREG ++#endif ++ /* Adjust $sp for 16-aligned */ ++ srli.d sp, sp, 4 ++ slli.d sp, sp, 4 ++ ++ la.got a3, t0, __libc_csu_init ++ la.got a4, t0, __libc_csu_fini ++ or a6, sp, zero /* stack_end. */ ++ ++ la.got ra, t0, __libc_start_main ++ jirl ra, ra, 0 ++ ++ la.got ra, t0, abort ++ jirl ra, ra, 0 ++END (ENTRY_POINT) ++ +diff --git a/sysdeps/loongarch/stat.c b/sysdeps/loongarch/stat.c +new file mode 100644 +index 00000000..36461b87 +--- /dev/null ++++ b/sysdeps/loongarch/stat.c +@@ -0,0 +1 @@ ++#include +diff --git a/sysdeps/loongarch/stat64.c b/sysdeps/loongarch/stat64.c +new file mode 100644 +index 00000000..0897282e +--- /dev/null ++++ b/sysdeps/loongarch/stat64.c +@@ -0,0 +1 @@ ++#include +diff --git a/sysdeps/loongarch/sys/asm.h b/sysdeps/loongarch/sys/asm.h +new file mode 100644 +index 00000000..7f3769bd +--- /dev/null ++++ b/sysdeps/loongarch/sys/asm.h +@@ -0,0 +1,49 @@ ++#ifndef _SYS_ASM_H ++#define _SYS_ASM_H ++ ++#include ++#include ++ ++/* Macros to handle different pointer/register sizes for 32/64-bit code. */ ++#ifdef __loongarch64 ++# define PTRLOG 3 ++# define SZREG 8 ++# define SZFREG 8 ++# define REG_L ld.d ++# define REG_S st.d ++# define FREG_L fld.d ++# define FREG_S fst.d ++#elif defined __loongarch32 ++# define PTRLOG 2 ++# define SZREG 4 ++# define SZFREG 4 ++# define REG_L ld.w ++# define REG_S st.w ++# define FREG_L fld.w ++# define FREG_S fst.w ++#else ++# error __loongarch_xlen must equal 32 or 64 ++#endif ++ ++ ++/* Declare leaf routine. */ ++#define LEAF(symbol) \ ++ .text; \ ++ .globl symbol; \ ++ .align 3; \ ++ cfi_startproc ; \ ++ .type symbol, @function; \ ++symbol: ++ ++# define ENTRY(symbol) LEAF(symbol) ++ ++/* Mark end of function. */ ++#undef END ++#define END(function) \ ++ cfi_endproc ; \ ++ .size function,.-function; ++ ++/* Stack alignment. */ ++#define ALMASK ~15 ++ ++#endif /* sys/asm.h */ +diff --git a/sysdeps/loongarch/sys/regdef.h b/sysdeps/loongarch/sys/regdef.h +new file mode 100644 +index 00000000..769784b8 +--- /dev/null ++++ b/sysdeps/loongarch/sys/regdef.h +@@ -0,0 +1,83 @@ ++#ifndef _SYS_REGDEF_H ++#define _SYS_REGDEF_H ++ ++#if _LOONGARCH_SIM == _ABILP64 ++# define zero $r0 ++# define ra $r1 ++# define tp $r2 ++# define sp $r3 ++# define a0 $r4 ++# define a1 $r5 ++# define a2 $r6 ++# define a3 $r7 ++# define a4 $r8 ++# define a5 $r9 ++# define a6 $r10 ++# define a7 $r11 ++# define v0 $r4 ++# define v1 $r5 ++# define t0 $r12 ++# define t1 $r13 ++# define t2 $r14 ++# define t3 $r15 ++# define t4 $r16 ++# define t5 $r17 ++# define t6 $r18 ++# define t7 $r19 ++# define t8 $r20 ++# define x $r21 ++# define fp $r22 ++# define s0 $r23 ++# define s1 $r24 ++# define s2 $r25 ++# define s3 $r26 ++# define s4 $r27 ++# define s5 $r28 ++# define s6 $r29 ++# define s7 $r30 ++# define s8 $r31 ++ ++# define fa0 $f0 ++# define fa1 $f1 ++# define fa2 $f2 ++# define fa3 $f3 ++# define fa4 $f4 ++# define fa5 $f5 ++# define fa6 $f6 ++# define fa7 $f7 ++# define fv0 $f0 ++# define fv1 $f1 ++# define ft0 $f8 ++# define ft1 $f9 ++# define ft2 $f10 ++# define ft3 $f11 ++# define ft4 $f12 ++# define ft5 $f13 ++# define ft6 $f14 ++# define ft7 $f15 ++# define ft8 $f16 ++# define ft9 $f17 ++# define ft10 $f18 ++# define ft11 $f19 ++# define ft12 $f20 ++# define ft13 $f21 ++# define ft14 $f22 ++# define ft15 $f23 ++# define fs0 $f24 ++# define fs1 $f25 ++# define fs2 $f26 ++# define fs3 $f27 ++# define fs4 $f28 ++# define fs5 $f29 ++# define fs6 $f30 ++# define fs7 $f31 ++ ++#elif _LOONGARCH_SIM == _ABILPX32 ++# error ABILPX32 ++#elif _LOONGARCH_SIM == _ABILP32 ++# error ABILP32 ++#else ++# error noABI ++#endif ++ ++#endif /* _SYS_REGDEF_H */ +diff --git a/sysdeps/loongarch/tininess.h b/sysdeps/loongarch/tininess.h +new file mode 100644 +index 00000000..1db37790 +--- /dev/null ++++ b/sysdeps/loongarch/tininess.h +@@ -0,0 +1 @@ ++#define TININESS_AFTER_ROUNDING 1 +diff --git a/sysdeps/loongarch/tls-macros.h b/sysdeps/loongarch/tls-macros.h +new file mode 100644 +index 00000000..f0ad55ac +--- /dev/null ++++ b/sysdeps/loongarch/tls-macros.h +@@ -0,0 +1,46 @@ ++/* Macros to support TLS testing in times of missing compiler support. ++ Copyright (C) 2017-2018 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 ++ . */ ++ ++ ++#include ++#include ++#include ++#include "dl-tls.h" ++ ++#define TLS_GD(x) \ ++ ({ void *__result; \ ++ asm ("la.tls.gd %0, " #x "\n\t" \ ++ : "=r" (__result)); \ ++ __tls_get_addr (__result); }) ++ ++#define TLS_LD(x) TLS_GD(x) ++ ++#define TLS_IE(x) \ ++ ({ void *__result; \ ++ asm ("la.tls.ie %0, " #x "\n\t" \ ++ "add.d %0, %0, $tp\n\t" \ ++ : "=r" (__result)); \ ++ __result; }) ++ ++#define TLS_LE(x) \ ++ ({ void *__result; \ ++ asm ("la.tls.le %0, " #x "\n\t" \ ++ "add.d %0, %0, $tp\n\t" \ ++ : "=r" (__result)); \ ++ __result; }) +diff --git a/sysdeps/loongarch/tst-audit.h b/sysdeps/loongarch/tst-audit.h +new file mode 100644 +index 00000000..d8d260eb +--- /dev/null ++++ b/sysdeps/loongarch/tst-audit.h +@@ -0,0 +1,23 @@ ++/* Copyright (C) 2020-2021 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 ++ . */ ++ ++#define pltenter la_loongarch_gnu_pltenter ++#define pltexit la_loongarch_gnu_pltexit ++#define La_regs La_loongarch_regs ++#define La_retval La_loongarch_retval ++#define int_retval lrv_a0 +diff --git a/sysdeps/loongarch/warning-nop.c b/sysdeps/loongarch/warning-nop.c +new file mode 100644 +index 00000000..b76aae79 +--- /dev/null ++++ b/sysdeps/loongarch/warning-nop.c +@@ -0,0 +1 @@ ++#include +diff --git a/sysdeps/unix/sysv/linux/loongarch/Implies b/sysdeps/unix/sysv/linux/loongarch/Implies +new file mode 100644 +index 00000000..e52b1ac3 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/Implies +@@ -0,0 +1 @@ ++loongarch/nptl +diff --git a/sysdeps/unix/sysv/linux/loongarch/Makefile b/sysdeps/unix/sysv/linux/loongarch/Makefile +new file mode 100644 +index 00000000..6f049aa9 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/Makefile +@@ -0,0 +1,17 @@ ++ifeq ($(subdir),elf) ++sysdep_routines += dl-vdso ++ifeq ($(build-shared),yes) ++# This is needed for DSO loading from static binaries. ++sysdep-dl-routines += dl-static ++endif ++endif ++ ++#ifeq ($(subdir),misc) ++#sysdep_headers += sys/cachectl.h ++#sysdep_routines += flush-icache ++#endif ++ ++ifeq ($(subdir),stdlib) ++gen-as-const-headers += ucontext_i.sym ++endif ++ +diff --git a/sysdeps/unix/sysv/linux/loongarch/Versions b/sysdeps/unix/sysv/linux/loongarch/Versions +new file mode 100644 +index 00000000..453f276a +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/Versions +@@ -0,0 +1,44 @@ ++ld { ++ GLIBC_PRIVATE { ++ # used for loading by static libraries ++ _dl_var_init; ++ } ++} ++libc { ++ # The comment lines with "#errlist-compat" are magic; see errlist-compat.awk. ++ # When you get an error from errlist-compat.awk, you need to add a new ++ # version here. Don't do this blindly, since this means changing the ABI ++ # for all GNU/Linux configurations. ++ ++ GLIBC_2.0 { ++ #errlist-compat 123 ++ _sys_errlist; sys_errlist; _sys_nerr; sys_nerr; ++ ++ # Exception handling support functions from libgcc ++ __register_frame; __register_frame_table; __deregister_frame; ++ __frame_state_for; __register_frame_info_table; ++ ++ # Needed by gcc: ++ _flush_cache; ++ ++ # c* ++ cachectl; cacheflush; ++ ++ # s* ++ sysmips; ++ } ++ GLIBC_2.2 { ++ #errlist-compat 1134 ++ _sys_errlist; sys_errlist; _sys_nerr; sys_nerr; ++ ++ # _* ++ _test_and_set; ++ } ++ GLIBC_2.11 { ++ fallocate64; ++ } ++ GLIBC_PRIVATE { ++ # nptl/pthread_cond_timedwait.c uses INTERNAL_VSYSCALL(clock_gettime). ++ __vdso_clock_gettime; ++ } ++} +diff --git a/sysdeps/unix/sysv/linux/loongarch/atomic-machine.h b/sysdeps/unix/sysv/linux/loongarch/atomic-machine.h +new file mode 100644 +index 00000000..ac1948ea +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/atomic-machine.h +@@ -0,0 +1,188 @@ ++/* Copyright (C) 2020-2021 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 ++ . */ ++ ++#ifndef _LINUX_LOONGARCH_BITS_ATOMIC_H ++#define _LINUX_LOONGARCH_BITS_ATOMIC_H 1 ++ ++#include ++ ++typedef int32_t atomic32_t; ++typedef uint32_t uatomic32_t; ++ ++typedef int64_t atomic64_t; ++typedef uint64_t uatomic64_t; ++ ++typedef intptr_t atomicptr_t; ++typedef uintptr_t uatomicptr_t; ++typedef intmax_t atomic_max_t; ++typedef uintmax_t uatomic_max_t; ++ ++#define atomic_full_barrier() __sync_synchronize () ++ ++# define __HAVE_64B_ATOMICS (__loongarch_xlen >= 64) ++# define USE_ATOMIC_COMPILER_BUILTINS 1 ++# define ATOMIC_EXCHANGE_USES_CAS 0 ++ ++/* Compare and exchange. ++ For all "bool" routines, we return FALSE if exchange succesful. */ ++ ++# define __arch_compare_and_exchange_bool_8_int(mem, newval, oldval, model) \ ++ ({ \ ++ typeof (*mem) __oldval = (oldval); \ ++ !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \ ++ model, __ATOMIC_RELAXED); \ ++ }) ++ ++# define __arch_compare_and_exchange_bool_16_int(mem, newval, oldval, model) \ ++ ({ \ ++ typeof (*mem) __oldval = (oldval); \ ++ !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \ ++ model, __ATOMIC_RELAXED); \ ++ }) ++ ++# define __arch_compare_and_exchange_bool_32_int(mem, newval, oldval, model) \ ++ ({ \ ++ typeof (*mem) __oldval = (oldval); \ ++ !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \ ++ model, __ATOMIC_RELAXED); \ ++ }) ++ ++# define __arch_compare_and_exchange_bool_64_int(mem, newval, oldval, model) \ ++ ({ \ ++ typeof (*mem) __oldval = (oldval); \ ++ !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \ ++ model, __ATOMIC_RELAXED); \ ++ }) ++ ++# define __arch_compare_and_exchange_val_8_int(mem, newval, oldval, model) \ ++ ({ \ ++ typeof (*mem) __oldval = (oldval); \ ++ __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \ ++ model, __ATOMIC_RELAXED); \ ++ __oldval; \ ++ }) ++ ++# define __arch_compare_and_exchange_val_16_int(mem, newval, oldval, model) \ ++ ({ \ ++ typeof (*mem) __oldval = (oldval); \ ++ __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \ ++ model, __ATOMIC_RELAXED); \ ++ __oldval; \ ++ }) ++ ++# define __arch_compare_and_exchange_val_32_int(mem, newval, oldval, model) \ ++ ({ \ ++ typeof (*mem) __oldval = (oldval); \ ++ __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \ ++ model, __ATOMIC_RELAXED); \ ++ __oldval; \ ++ }) ++ ++# define __arch_compare_and_exchange_val_64_int(mem, newval, oldval, model) \ ++ ({ \ ++ typeof (*mem) __oldval = (oldval); \ ++ __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \ ++ model, __ATOMIC_RELAXED); \ ++ __oldval; \ ++ }) ++ ++/* Atomic compare and exchange. */ ++ ++# define atomic_compare_and_exchange_bool_acq(mem, new, old) \ ++ __atomic_bool_bysize (__arch_compare_and_exchange_bool, int, \ ++ mem, new, old, __ATOMIC_ACQUIRE) ++ ++# define atomic_compare_and_exchange_val_acq(mem, new, old) \ ++ __atomic_val_bysize (__arch_compare_and_exchange_val, int, \ ++ mem, new, old, __ATOMIC_ACQUIRE) ++ ++# define atomic_compare_and_exchange_val_rel(mem, new, old) \ ++ __atomic_val_bysize (__arch_compare_and_exchange_val, int, \ ++ mem, new, old, __ATOMIC_RELEASE) ++ ++/* Atomic exchange (without compare). */ ++ ++# define __arch_exchange_8_int(mem, newval, model) \ ++ __atomic_exchange_n (mem, newval, model) ++ ++# define __arch_exchange_16_int(mem, newval, model) \ ++ __atomic_exchange_n (mem, newval, model) ++ ++# define __arch_exchange_32_int(mem, newval, model) \ ++ __atomic_exchange_n (mem, newval, model) ++ ++# define __arch_exchange_64_int(mem, newval, model) \ ++ __atomic_exchange_n (mem, newval, model) ++ ++# define atomic_exchange_acq(mem, value) \ ++ __atomic_val_bysize (__arch_exchange, int, mem, value, __ATOMIC_ACQUIRE) ++ ++# define atomic_exchange_rel(mem, value) \ ++ __atomic_val_bysize (__arch_exchange, int, mem, value, __ATOMIC_RELEASE) ++ ++/* Atomically add value and return the previous (unincremented) value. */ ++ ++# define __arch_exchange_and_add_8_int(mem, value, model) \ ++ __atomic_fetch_add (mem, value, model) ++ ++# define __arch_exchange_and_add_16_int(mem, value, model) \ ++ __atomic_fetch_add (mem, value, model) ++ ++# define __arch_exchange_and_add_32_int(mem, value, model) \ ++ __atomic_fetch_add (mem, value, model) ++ ++# define __arch_exchange_and_add_64_int(mem, value, model) \ ++ __atomic_fetch_add (mem, value, model) ++ ++# define atomic_exchange_and_add_acq(mem, value) \ ++ __atomic_val_bysize (__arch_exchange_and_add, int, mem, value, \ ++ __ATOMIC_ACQUIRE) ++ ++# define atomic_exchange_and_add_rel(mem, value) \ ++ __atomic_val_bysize (__arch_exchange_and_add, int, mem, value, \ ++ __ATOMIC_RELEASE) ++ ++/* Miscellaneous. */ ++ ++# define asm_amo(which, mem, value) ({ \ ++ __atomic_check_size (mem); \ ++ typeof (*mem) __tmp; \ ++ if (sizeof (__tmp) == 4) \ ++ asm volatile (which ".w""\t%0, %z2, %1" \ ++ : "=&r" (__tmp), "+ZB" (* (mem)) \ ++ : "rJ" (value)); \ ++ else if (sizeof (__tmp) == 8) \ ++ asm volatile (which ".d""\t%0, %z2, %1" \ ++ : "=&r" (__tmp), "+ZB" (* (mem)) \ ++ : "rJ" (value)); \ ++ else \ ++ abort (); \ ++ __tmp; }) ++ ++# define atomic_max(mem, value) asm_amo ("ammax_db", mem, value) ++# define atomic_min(mem, value) asm_amo ("ammin_db", mem, value) ++ ++# define atomic_bit_test_set(mem, bit) \ ++ ({ typeof (*mem) __mask = (typeof (*mem))1 << (bit); \ ++ asm_amo("amor_db", mem, __mask) & __mask; }) ++ ++# define catomic_exchange_and_add(mem, value) \ ++ atomic_exchange_and_add (mem, value) ++# define catomic_max(mem, value) atomic_max (mem, value) ++ ++#endif /* bits/atomic.h */ +diff --git a/sysdeps/unix/sysv/linux/loongarch/bits/fcntl.h b/sysdeps/unix/sysv/linux/loongarch/bits/fcntl.h +new file mode 100644 +index 00000000..5ee2e976 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/bits/fcntl.h +@@ -0,0 +1,62 @@ ++/* O_*, F_*, FD_* bit values for the generic Linux ABI. ++ Copyright (C) 2011-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Chris Metcalf , 2011. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++#ifndef _FCNTL_H ++# error "Never use directly; include instead." ++#endif ++ ++#include ++ ++/* In 64-bit ISA files are always with 64bit off_t and F_*LK64 are the same as ++ non-64-bit versions. It will need to be revised for 128-bit. */ ++#if __WORDSIZE == 64 ++# define __O_LARGEFILE 0 ++ ++# define F_GETLK64 5 /* Get record locking info. */ ++# define F_SETLK64 6 /* Set record locking info (non-blocking). */ ++# define F_SETLKW64 7 /* Set record locking info (blocking). */ ++#endif ++ ++struct flock ++ { ++ short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */ ++ short int l_whence; /* Where `l_start' is relative to (like `lseek'). */ ++#ifndef __USE_FILE_OFFSET64 ++ __off_t l_start; /* Offset where the lock begins. */ ++ __off_t l_len; /* Size of the locked area; zero means until EOF. */ ++#else ++ __off64_t l_start; /* Offset where the lock begins. */ ++ __off64_t l_len; /* Size of the locked area; zero means until EOF. */ ++#endif ++ __pid_t l_pid; /* Process holding the lock. */ ++ }; ++ ++#ifdef __USE_LARGEFILE64 ++struct flock64 ++ { ++ short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */ ++ short int l_whence; /* Where `l_start' is relative to (like `lseek'). */ ++ __off64_t l_start; /* Offset where the lock begins. */ ++ __off64_t l_len; /* Size of the locked area; zero means until EOF. */ ++ __pid_t l_pid; /* Process holding the lock. */ ++ }; ++#endif ++ ++/* Include generic Linux declarations. */ ++#include +diff --git a/sysdeps/unix/sysv/linux/loongarch/bits/local_lim.h b/sysdeps/unix/sysv/linux/loongarch/bits/local_lim.h +new file mode 100644 +index 00000000..a8cd6df8 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/bits/local_lim.h +@@ -0,0 +1,99 @@ ++/* Minimum guaranteed maximum values for system limits. Linux version. ++ Copyright (C) 1993-2018 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; see the file COPYING.LIB. If ++ not, see . */ ++ ++/* The kernel header pollutes the namespace with the NR_OPEN symbol ++ and defines LINK_MAX although filesystems have different maxima. A ++ similar thing is true for OPEN_MAX: the limit can be changed at ++ runtime and therefore the macro must not be defined. Remove this ++ after including the header if necessary. */ ++#ifndef NR_OPEN ++# define __undef_NR_OPEN ++#endif ++#ifndef LINK_MAX ++# define __undef_LINK_MAX ++#endif ++#ifndef OPEN_MAX ++# define __undef_OPEN_MAX ++#endif ++#ifndef ARG_MAX ++# define __undef_ARG_MAX ++#endif ++ ++/* The kernel sources contain a file with all the needed information. */ ++#include ++ ++/* Have to remove NR_OPEN? */ ++#ifdef __undef_NR_OPEN ++# undef NR_OPEN ++# undef __undef_NR_OPEN ++#endif ++/* Have to remove LINK_MAX? */ ++#ifdef __undef_LINK_MAX ++# undef LINK_MAX ++# undef __undef_LINK_MAX ++#endif ++/* Have to remove OPEN_MAX? */ ++#ifdef __undef_OPEN_MAX ++# undef OPEN_MAX ++# undef __undef_OPEN_MAX ++#endif ++/* Have to remove ARG_MAX? */ ++#ifdef __undef_ARG_MAX ++# undef ARG_MAX ++# undef __undef_ARG_MAX ++#endif ++ ++/* The number of data keys per process. */ ++#define _POSIX_THREAD_KEYS_MAX 128 ++/* This is the value this implementation supports. */ ++#define PTHREAD_KEYS_MAX 1024 ++ ++/* Controlling the iterations of destructors for thread-specific data. */ ++#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 ++/* Number of iterations this implementation does. */ ++#define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS ++ ++/* The number of threads per process. */ ++#define _POSIX_THREAD_THREADS_MAX 64 ++/* We have no predefined limit on the number of threads. */ ++#undef PTHREAD_THREADS_MAX ++ ++/* Maximum amount by which a process can descrease its asynchronous I/O ++ priority level. */ ++#define AIO_PRIO_DELTA_MAX 20 ++ ++/* Minimum size for a thread. At least two pages with 64k pages. */ ++#define PTHREAD_STACK_MIN 131072 ++ ++/* Maximum number of timer expiration overruns. */ ++#define DELAYTIMER_MAX 2147483647 ++ ++/* Maximum tty name length. */ ++#define TTY_NAME_MAX 32 ++ ++/* Maximum login name length. This is arbitrary. */ ++#define LOGIN_NAME_MAX 256 ++ ++/* Maximum host name length. */ ++#define HOST_NAME_MAX 64 ++ ++/* Maximum message queue priority level. */ ++#define MQ_PRIO_MAX 32768 ++ ++/* Maximum value the semaphore can have. */ ++#define SEM_VALUE_MAX (2147483647) +diff --git a/sysdeps/unix/sysv/linux/loongarch/bits/mman.h b/sysdeps/unix/sysv/linux/loongarch/bits/mman.h +new file mode 100644 +index 00000000..5a16f8ac +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/bits/mman.h +@@ -0,0 +1,41 @@ ++/* Definitions for POSIX memory map interface. Linux/MIPS version. ++ Copyright (C) 1997-2018 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 ++ . */ ++ ++ ++#ifndef _SYS_MMAN_H ++# error "Never use directly; include instead." ++#endif ++ ++#ifdef __USE_MISC ++# define MAP_GROWSDOWN 0x00100 /* Stack-like segment. */ ++# define MAP_DENYWRITE 0x00800 /* ETXTBSY. */ ++# define MAP_EXECUTABLE 0x01000 /* Mark it as an executable. */ ++# define MAP_LOCKED 0x02000 /* Lock the mapping. */ ++# define MAP_NORESERVE 0x04000 /* Don't check for reservations. */ ++# define MAP_POPULATE 0x08000 /* Populate (prefault) pagetables. */ ++# define MAP_NONBLOCK 0x10000 /* Do not block on IO. */ ++# define MAP_STACK 0x20000 /* Allocation is for a stack. */ ++# define MAP_HUGETLB 0x40000 /* Create huge page mapping. */ ++# define MAP_SYNC 0x80000 /* Perform synchronous page ++ faults for the mapping. */ ++# define MAP_FIXED_NOREPLACE 0x100000 /* MAP_FIXED but do not unmap ++ underlying mapping. */ ++#endif ++ ++/* Include generic Linux declarations. */ ++#include +diff --git a/sysdeps/unix/sysv/linux/loongarch/bits/shm.h b/sysdeps/unix/sysv/linux/loongarch/bits/shm.h +new file mode 100644 +index 00000000..9e23092d +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/bits/shm.h +@@ -0,0 +1,112 @@ ++/* Copyright (C) 2011-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Chris Metcalf , 2011. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++#ifndef _SYS_SHM_H ++# error "Never include directly; use instead." ++#endif ++ ++#include ++#include ++ ++/* Permission flag for shmget. */ ++#define SHM_R 0400 /* or S_IRUGO from */ ++#define SHM_W 0200 /* or S_IWUGO from */ ++ ++/* 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 */ ++#define SHM_EXEC 0100000 /* execution access */ ++ ++/* 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 shared memory segment. */ ++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() */ ++#if __WORDSIZE == 32 ++ unsigned long int __glibc_reserved1; ++#endif ++ __time_t shm_dtime; /* time of last shmdt() */ ++#if __WORDSIZE == 32 ++ unsigned long int __glibc_reserved2; ++#endif ++ __time_t shm_ctime; /* time of last change by shmctl() */ ++#if __WORDSIZE == 32 ++ unsigned long int __glibc_reserved3; ++#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 __glibc_reserved4; ++ unsigned long int __glibc_reserved5; ++ }; ++ ++#ifdef __USE_MISC ++ ++/* ipcs ctl commands */ ++# define SHM_STAT 13 ++# define SHM_INFO 14 ++# define SHM_STAT_ANY 15 ++ ++/* 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 __glibc_reserved1; ++ unsigned long int __glibc_reserved2; ++ unsigned long int __glibc_reserved3; ++ unsigned long int __glibc_reserved4; ++ }; ++ ++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/sysdeps/unix/sysv/linux/loongarch/bits/sigcontext.h b/sysdeps/unix/sysv/linux/loongarch/bits/sigcontext.h +new file mode 100644 +index 00000000..0f925b4c +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/bits/sigcontext.h +@@ -0,0 +1,47 @@ ++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 1996, 1997, 1999 by Ralf Baechle ++ * Copyright (C) 1999 Silicon Graphics, Inc. ++ */ ++#ifndef _BITS_SIGCONTEXT_H ++#define _BITS_SIGCONTEXT_H ++ ++/* ++ * Keep this struct definition in sync with the sigcontext fragment ++ * in arch/mips/kernel/asm-offsets.c ++ * ++ * Warning: this structure illdefined with sc_badvaddr being just an unsigned ++ * int so it was changed to unsigned long in 2.6.0-test1. This may break ++ * binary compatibility - no prisoners. ++ * DSP ASE in 2.6.12-rc4. Turn sc_mdhi and sc_mdlo into an array of four ++ * entries, add sc_dsp and sc_reserved for padding. No prisoners. ++ */ ++ ++#define FPU_REG_WIDTH 256 ++#define FPU_ALIGN __attribute__((aligned(32))) ++ ++struct sigcontext { ++ unsigned long long sc_pc; ++ unsigned long long sc_regs[32]; ++ unsigned int sc_flags; ++ ++ unsigned int sc_fcsr; ++ unsigned int sc_vcsr; ++ unsigned long long sc_fcc; ++ ++ unsigned long long sc_scr[4]; ++ ++ union { ++ unsigned int val32[FPU_REG_WIDTH / 32]; ++ unsigned long long val64[FPU_REG_WIDTH / 64]; ++ } sc_fpregs[32] FPU_ALIGN; ++ unsigned char sc_reserved[4096] __attribute__((__aligned__(16))); ++ ++}; ++ ++ ++#endif /* _BITS_SIGCONTEXT_H */ +diff --git a/sysdeps/unix/sysv/linux/loongarch/bits/signum.h b/sysdeps/unix/sysv/linux/loongarch/bits/signum.h +new file mode 100644 +index 00000000..3cad0b19 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/bits/signum.h +@@ -0,0 +1,58 @@ ++/* Signal number definitions. Linux version. ++ Copyright (C) 1995-2018 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 ++ . */ ++ ++#ifndef _BITS_SIGNUM_H ++#define _BITS_SIGNUM_H 1 ++ ++#ifndef _SIGNAL_H ++#error "Never include directly; use instead." ++#endif ++ ++#include ++ ++/* Adjustments and additions to the signal number constants for ++ most Linux systems. */ ++ ++#define SIGSTKFLT 16 /* Stack fault (obsolete). */ ++#define SIGPWR 30 /* Power failure imminent. */ ++ ++#undef SIGBUS ++#define SIGBUS 7 ++#undef SIGUSR1 ++#define SIGUSR1 10 ++#undef SIGUSR2 ++#define SIGUSR2 12 ++#undef SIGCHLD ++#define SIGCHLD 17 ++#undef SIGCONT ++#define SIGCONT 18 ++#undef SIGSTOP ++#define SIGSTOP 19 ++#undef SIGTSTP ++#define SIGTSTP 20 ++#undef SIGURG ++#define SIGURG 23 ++#undef SIGPOLL ++#define SIGPOLL 29 ++#undef SIGSYS ++#define SIGSYS 31 ++ ++#undef __SIGRTMAX ++#define __SIGRTMAX 127 ++ ++#endif /* included. */ +diff --git a/sysdeps/unix/sysv/linux/loongarch/clone.S b/sysdeps/unix/sysv/linux/loongarch/clone.S +new file mode 100644 +index 00000000..f0fc566e +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/clone.S +@@ -0,0 +1,98 @@ ++/* Copyright (C) 2020-2021 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 ++ . */ ++ ++/* clone() is even more special than fork() as it mucks with stacks ++ and invokes a function in the right context after its all over. */ ++ ++#include ++#include ++#define _ERRNO_H 1 ++#include ++#include ++#include "tcb-offsets.h" ++ ++/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg, ++ void *parent_tidptr, void *tls, void *child_tidptr) */ ++ ++ENTRY (__clone) ++ ++ /* Align stack to 16 or 8 bytes per the ABI. */ ++#if _LOONGARCH_SIM == _ABILP64 ++ addi.d t0, zero, -16 ++#elif _LOONGARCH_SIM == _ABILP32 ++ addi.w t0, zero, -8 ++#endif ++ and a1, a1, t0 ++ ++ /* Sanity check arguments. */ ++ beqz a0, L (invalid) /* No NULL function pointers. */ ++ beqz a1, L (invalid) /* No NULL stack pointers. */ ++ ++ addi.d a1, a1, -16 /* Reserve argument save space. */ ++ st.d a0, a1, 0 /* Save function pointer. */ ++ st.d a3, a1, SZREG /* Save argument pointer. */ ++ ++ /* The syscall expects the args to be in different slots. */ ++ or a0, a2, zero ++ or a2, a4, zero ++ or a3, a6, zero ++ or a4, a5, zero ++ ++ /* Do the system call. */ ++ li.d a7,__NR_clone ++ syscall 0 ++ ++ blt a0, zero ,L (error) ++ beqz a0,L (thread_start) ++ ++ /* Successful return from the parent. */ ++ ret ++ ++L (invalid): ++ li.d a0, -EINVAL ++ /* Something bad happened -- no child created. */ ++L (error): ++ b __syscall_error ++ END (__clone) ++ ++/* Load up the arguments to the function. Put this block of code in ++ its own function so that we can terminate the stack trace with our ++ debug info. */ ++ ++ENTRY (__thread_start) ++L (thread_start): ++ /* Terminate call stack by noting ra is undefined. Use a dummy ++ .cfi_label to force starting the FDE. */ ++ .cfi_label .Ldummy ++ cfi_undefined (1) ++ ++ /* Restore the arg for user's function. */ ++ ld.d a1, sp, 0 /* Function pointer. */ ++ ld.d a0, sp, SZREG /* Argument pointer. */ ++ ++ /* Call the user's function. */ ++ jirl ra, a1, 0 ++ ++ /* Call exit with the function's return value. */ ++ li.d a7, __NR_exit ++ syscall 0 ++ ++ END (__thread_start) ++ ++libc_hidden_def (__clone) ++weak_alias (__clone, clone) +diff --git a/sysdeps/unix/sysv/linux/loongarch/configure b/sysdeps/unix/sysv/linux/loongarch/configure +new file mode 100644 +index 00000000..a402323a +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/configure +@@ -0,0 +1,199 @@ ++# This file is generated from configure.ac by Autoconf. DO NOT EDIT! ++ # Local configure fragment for sysdeps/unix/sysv/linux/loongarch. ++ ++arch_minimum_kernel=4.15.0 ++ ++libc_cv_loongarch_int_abi=no ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 ++$as_echo_n "checking for grep that handles long lines and -e... " >&6; } ++if ${ac_cv_path_GREP+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -z "$GREP"; then ++ ac_path_GREP_found=false ++ # Loop through the user's path and test for each of PROGNAME-LIST ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_prog in grep ggrep; do ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" ++ as_fn_executable_p "$ac_path_GREP" || continue ++# Check for GNU ac_path_GREP and select it if it is found. ++ # Check for GNU $ac_path_GREP ++case `"$ac_path_GREP" --version 2>&1` in ++*GNU*) ++ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; ++*) ++ ac_count=0 ++ $as_echo_n 0123456789 >"conftest.in" ++ while : ++ do ++ cat "conftest.in" "conftest.in" >"conftest.tmp" ++ mv "conftest.tmp" "conftest.in" ++ cp "conftest.in" "conftest.nl" ++ $as_echo 'GREP' >> "conftest.nl" ++ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break ++ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ++ as_fn_arith $ac_count + 1 && ac_count=$as_val ++ if test $ac_count -gt ${ac_path_GREP_max-0}; then ++ # Best one so far, save it but keep looking for a better one ++ ac_cv_path_GREP="$ac_path_GREP" ++ ac_path_GREP_max=$ac_count ++ fi ++ # 10*(2^10) chars as input seems more than enough ++ test $ac_count -gt 10 && break ++ done ++ rm -f conftest.in conftest.tmp conftest.nl conftest.out;; ++esac ++ ++ $ac_path_GREP_found && break 3 ++ done ++ done ++ done ++IFS=$as_save_IFS ++ if test -z "$ac_cv_path_GREP"; then ++ as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 ++ fi ++else ++ ac_cv_path_GREP=$GREP ++fi ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 ++$as_echo "$ac_cv_path_GREP" >&6; } ++ GREP="$ac_cv_path_GREP" ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 ++$as_echo_n "checking for egrep... " >&6; } ++if ${ac_cv_path_EGREP+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 ++ then ac_cv_path_EGREP="$GREP -E" ++ else ++ if test -z "$EGREP"; then ++ ac_path_EGREP_found=false ++ # Loop through the user's path and test for each of PROGNAME-LIST ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_prog in egrep; do ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" ++ as_fn_executable_p "$ac_path_EGREP" || continue ++# Check for GNU ac_path_EGREP and select it if it is found. ++ # Check for GNU $ac_path_EGREP ++case `"$ac_path_EGREP" --version 2>&1` in ++*GNU*) ++ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; ++*) ++ ac_count=0 ++ $as_echo_n 0123456789 >"conftest.in" ++ while : ++ do ++ cat "conftest.in" "conftest.in" >"conftest.tmp" ++ mv "conftest.tmp" "conftest.in" ++ cp "conftest.in" "conftest.nl" ++ $as_echo 'EGREP' >> "conftest.nl" ++ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break ++ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ++ as_fn_arith $ac_count + 1 && ac_count=$as_val ++ if test $ac_count -gt ${ac_path_EGREP_max-0}; then ++ # Best one so far, save it but keep looking for a better one ++ ac_cv_path_EGREP="$ac_path_EGREP" ++ ac_path_EGREP_max=$ac_count ++ fi ++ # 10*(2^10) chars as input seems more than enough ++ test $ac_count -gt 10 && break ++ done ++ rm -f conftest.in conftest.tmp conftest.nl conftest.out;; ++esac ++ ++ $ac_path_EGREP_found && break 3 ++ done ++ done ++ done ++IFS=$as_save_IFS ++ if test -z "$ac_cv_path_EGREP"; then ++ as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 ++ fi ++else ++ ac_cv_path_EGREP=$EGREP ++fi ++ ++ fi ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 ++$as_echo "$ac_cv_path_EGREP" >&6; } ++ EGREP="$ac_cv_path_EGREP" ++ ++ ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++__SIZEOF_INT__ __SIZEOF_LONG__ __SIZEOF_POINTER__ ++ ++_ACEOF ++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | ++ $EGREP "4 4 4" >/dev/null 2>&1; then : ++ libc_cv_loongarch_int_abi=lp32 ++fi ++rm -f conftest* ++ ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++__SIZEOF_INT__ __SIZEOF_LONG__ __SIZEOF_POINTER__ ++ ++_ACEOF ++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | ++ $EGREP "4 8 8" >/dev/null 2>&1; then : ++ libc_cv_loongarch_int_abi=lp64 ++fi ++rm -f conftest* ++ ++if test $libc_cv_loongarch_int_abi = no; then ++ as_fn_error $? "Unable to determine integer ABI" "$LINENO" 5 ++fi ++ ++config_vars="$config_vars ++default-abi = $libc_cv_loongarch_int_abi" ++ ++case $libc_cv_loongarch_int_abi in ++lp32) ++ test -n "$libc_cv_slibdir" || ++case "$prefix" in ++/usr | /usr/) ++ libc_cv_slibdir='/lib32' ++ libc_cv_rtlddir='/lib32' ++ if test "$libdir" = '${exec_prefix}/lib'; then ++ libdir='${exec_prefix}/lib32'; ++ # Locale data can be shared between 32-bit and 64-bit libraries. ++ libc_cv_complocaledir='${exec_prefix}/lib/locale' ++ fi ++ ;; ++esac ++ ;; ++lp64) ++ test -n "$libc_cv_slibdir" || ++case "$prefix" in ++/usr | /usr/) ++ libc_cv_slibdir='/lib64' ++ libc_cv_rtlddir='/lib64' ++ if test "$libdir" = '${exec_prefix}/lib'; then ++ libdir='${exec_prefix}/lib64'; ++ # Locale data can be shared between 32-bit and 64-bit libraries. ++ libc_cv_complocaledir='${exec_prefix}/lib/locale' ++ fi ++ ;; ++esac ++ ;; ++esac ++ ++ldd_rewrite_script=sysdeps/unix/sysv/linux/loongarch/ldd-rewrite.sed +diff --git a/sysdeps/unix/sysv/linux/loongarch/configure.ac b/sysdeps/unix/sysv/linux/loongarch/configure.ac +new file mode 100644 +index 00000000..fef4f4d2 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/configure.ac +@@ -0,0 +1,27 @@ ++sinclude(./aclocal.m4)dnl Autoconf lossage ++GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. ++# Local configure fragment for sysdeps/unix/sysv/linux/loongarch. ++ ++arch_minimum_kernel=4.15.0 ++ ++libc_cv_loongarch_int_abi=no ++AC_EGREP_CPP(4 4 4, [__SIZEOF_INT__ __SIZEOF_LONG__ __SIZEOF_POINTER__ ++ ], libc_cv_loongarch_int_abi=lp32) ++AC_EGREP_CPP(4 8 8, [__SIZEOF_INT__ __SIZEOF_LONG__ __SIZEOF_POINTER__ ++ ], libc_cv_loongarch_int_abi=lp64) ++if test $libc_cv_loongarch_int_abi = no; then ++ AC_MSG_ERROR([Unable to determine integer ABI]) ++fi ++ ++LIBC_CONFIG_VAR([default-abi], [$libc_cv_loongarch_int_abi]) ++ ++case $libc_cv_loongarch_int_abi in ++lp32) ++ LIBC_SLIBDIR_RTLDDIR([lib32], [lib32]) ++ ;; ++lp64) ++ LIBC_SLIBDIR_RTLDDIR([lib64], [lib]) ++ ;; ++esac ++ ++ldd_rewrite_script=sysdeps/unix/sysv/linux/loongarch/ldd-rewrite.sed +diff --git a/sysdeps/unix/sysv/linux/loongarch/dl-static.c b/sysdeps/unix/sysv/linux/loongarch/dl-static.c +new file mode 100644 +index 00000000..12b030f0 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/dl-static.c +@@ -0,0 +1,84 @@ ++/* Copyright (C) 2020-2021 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 ++ . */ ++ ++#include ++ ++#ifdef SHARED ++ ++void ++_dl_var_init (void *array[]) ++{ ++ /* It has to match "variables" below. */ ++ enum ++ { ++ DL_PAGESIZE = 0 ++ }; ++ ++ GLRO(dl_pagesize) = *((size_t *) array[DL_PAGESIZE]); ++} ++ ++#else ++ ++static void *variables[] = ++{ ++ &GLRO(dl_pagesize) ++}; ++ ++static void ++_dl_unprotect_relro (struct link_map *l) ++{ ++ ElfW(Addr) start = ((l->l_addr + l->l_relro_addr) ++ & ~(GLRO(dl_pagesize) - 1)); ++ ElfW(Addr) end = ((l->l_addr + l->l_relro_addr + l->l_relro_size) ++ & ~(GLRO(dl_pagesize) - 1)); ++ ++ if (start != end) ++ __mprotect ((void *) start, end - start, PROT_READ | PROT_WRITE); ++} ++ ++void ++_dl_static_init (struct link_map *l) ++{ ++ struct link_map *rtld_map = l; ++ struct r_scope_elem **scope; ++ const ElfW(Sym) *ref = NULL; ++ lookup_t loadbase; ++ void (*f) (void *[]); ++ size_t i; ++ ++ loadbase = _dl_lookup_symbol_x ("_dl_var_init", l, &ref, l->l_local_scope, ++ NULL, 0, 1, NULL); ++ ++ for (scope = l->l_local_scope; *scope != NULL; scope++) ++ for (i = 0; i < (*scope)->r_nlist; i++) ++ if ((*scope)->r_list[i] == loadbase) ++ { ++ rtld_map = (*scope)->r_list[i]; ++ break; ++ } ++ ++ if (ref != NULL) ++ { ++ f = (void (*) (void *[])) DL_SYMBOL_ADDRESS (loadbase, ref); ++ _dl_unprotect_relro (rtld_map); ++ f (variables); ++ _dl_protect_relro (rtld_map); ++ } ++} ++ ++#endif +diff --git a/sysdeps/unix/sysv/linux/loongarch/getcontext.S b/sysdeps/unix/sysv/linux/loongarch/getcontext.S +new file mode 100644 +index 00000000..9c28d958 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/getcontext.S +@@ -0,0 +1,72 @@ ++/* Save current context. ++ Copyright (C) 2009-2018 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 ++ . */ ++ ++#include "ucontext-macros.h" ++ ++/* int getcontext (ucontext_t *ucp) */ ++ ++ .text ++LEAF (__getcontext) ++ SAVE_INT_REG (ra, 1, a0) ++ SAVE_INT_REG (sp, 3, a0) ++ SAVE_INT_REG (zero, 4, a0) /* return 0 by overwriting a0. */ ++ SAVE_INT_REG (x, 21, a0) ++ SAVE_INT_REG (fp, 22, a0) ++ SAVE_INT_REG (s0, 23, a0) ++ SAVE_INT_REG (s1, 24, a0) ++ SAVE_INT_REG (s2, 25, a0) ++ SAVE_INT_REG (s3, 26, a0) ++ SAVE_INT_REG (s4, 27, a0) ++ SAVE_INT_REG (s5, 28, a0) ++ SAVE_INT_REG (s6, 29, a0) ++ SAVE_INT_REG (s7, 30, a0) ++ SAVE_INT_REG (s8, 31, a0) ++ st.d ra, a0, MCONTEXT_PC ++ ++#ifndef __loongarch_soft_float ++ movfcsr2gr a1, $r0 ++ ++ SAVE_FP_REG (fs0, 24, a0) ++ SAVE_FP_REG (fs1, 25, a0) ++ SAVE_FP_REG (fs2, 26, a0) ++ SAVE_FP_REG (fs3, 27, a0) ++ SAVE_FP_REG (fs4, 28, a0) ++ SAVE_FP_REG (fs5, 29, a0) ++ SAVE_FP_REG (fs6, 30, a0) ++ SAVE_FP_REG (fs7, 31, a0) ++ ++ st.w a1, a0, MCONTEXT_FCSR ++#endif /* __loongarch_soft_float */ ++ ++/* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */ ++ li.d a3, _NSIG8 ++ addi.d a2, a0, UCONTEXT_SIGMASK ++ ori a1, zero,0 ++ li.d a0, SIG_BLOCK ++ ++ li.d a7, SYS_ify (rt_sigprocmask) ++ syscall 0 ++ blt a0, zero, 99f ++ ++ jirl $r0, $r1, 0 ++ ++99: b __syscall_error ++ ++PSEUDO_END (__getcontext) ++ ++weak_alias (__getcontext, getcontext) +diff --git a/sysdeps/unix/sysv/linux/loongarch/getpid.c b/sysdeps/unix/sysv/linux/loongarch/getpid.c +new file mode 100644 +index 00000000..5b4edb2b +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/getpid.c +@@ -0,0 +1,54 @@ ++/* getpid - get the pid. Linux/Loongarch version. ++ Copyright (C) 2015-2018 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 ++ . */ ++ ++#include ++ ++#ifdef SHARED ++# include ++# include ++ ++static pid_t ++__getpid_syscall (void) ++{ ++ return INLINE_SYSCALL (getpid, 0); ++} ++ ++# ifndef __getpid_type ++# define __getpid_type __getpid ++# endif ++ ++# undef INIT_ARCH ++# define INIT_ARCH() PREPARE_VERSION_KNOWN (linux26, LINUX_2_6) ++libc_ifunc_hidden (__getpid_type, __getpid, (_dl_vdso_vsym ("__vdso_getpid", &linux26) ?: &__getpid_syscall)) ++libc_hidden_def (__getpid) ++ ++#else ++ ++# include ++# include ++ ++pid_t ++__getpid (void) ++{ ++ return INLINE_SYSCALL (getpid, 0); ++} ++libc_hidden_def (__getpid); ++ ++#endif ++weak_alias (__getpid, getpid) ++libc_hidden_weak (getpid) +diff --git a/sysdeps/unix/sysv/linux/loongarch/gettimeofday.c b/sysdeps/unix/sysv/linux/loongarch/gettimeofday.c +new file mode 100644 +index 00000000..902b1a5d +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/gettimeofday.c +@@ -0,0 +1,58 @@ ++/* gettimeofday - get the time. Linux/LoongArch version. ++ Copyright (C) 2015-2018 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 ++ . */ ++ ++#include ++ ++#ifdef SHARED ++ ++# include ++# include ++ ++static int ++__gettimeofday_syscall (struct timeval *tv, struct timezone *tz) ++{ ++ return INLINE_SYSCALL (gettimeofday, 2, tv, tz); ++} ++ ++# ifndef __gettimeofday_type ++# define __gettimeofday_type __gettimeofday ++# endif ++ ++# undef INIT_ARCH ++# define INIT_ARCH() PREPARE_VERSION_KNOWN (linux26, LINUX_2_6) ++/* If the vDSO is not available we fall back to syscall. */ ++libc_ifunc_hidden (__gettimeofday_type, __gettimeofday, ++ (_dl_vdso_vsym ("__vdso_gettimeofday", &linux26) ++ ?: &__gettimeofday_syscall)) ++libc_hidden_def (__gettimeofday) ++ ++#else ++ ++# include ++# include ++ ++int ++__gettimeofday (struct timeval *tv, struct timezone *tz) ++{ ++ return INLINE_SYSCALL (gettimeofday, 2, tv, tz); ++} ++libc_hidden_def (__gettimeofday) ++ ++#endif ++weak_alias (__gettimeofday, gettimeofday) ++libc_hidden_weak (gettimeofday) +diff --git a/sysdeps/unix/sysv/linux/loongarch/getuid.c b/sysdeps/unix/sysv/linux/loongarch/getuid.c +new file mode 100644 +index 00000000..4b3f95eb +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/getuid.c +@@ -0,0 +1,60 @@ ++/* getuid - get the uid. Linux/Loongarch version. ++ Copyright (C) 2015-2018 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 ++ . */ ++ ++#include ++ ++#ifdef SHARED ++ ++# include ++# include ++ ++libc_hidden_proto (getuid) ++ ++extern __uid_t __getuid (void); ++libc_hidden_proto (__getuid) ++ ++static uid_t ++__getuid_syscall(void) ++{ ++ return INLINE_SYSCALL (getuid, 0); ++} ++ ++# ifndef __getuid_type ++# define __getuid_type __getuid ++# endif ++ ++# undef INIT_ARCH ++# define INIT_ARCH() PREPARE_VERSION_KNOWN (linux26, LINUX_2_6) ++libc_ifunc_hidden (__getuid_type, __getuid, (_dl_vdso_vsym ("__vdso_getuid", &linux26) ?: &__getuid_syscall)) ++libc_hidden_def (__getuid) ++ ++#else ++ ++# include ++# include ++ ++uid_t ++__getuid(void) ++{ ++ return INLINE_SYSCALL (getuid, 0); ++} ++libc_hidden_def (__getuid) ++ ++#endif ++weak_alias (__getuid, getuid) ++libc_hidden_weak (getuid) +diff --git a/sysdeps/unix/sysv/linux/loongarch/init-first.c b/sysdeps/unix/sysv/linux/loongarch/init-first.c +new file mode 100644 +index 00000000..5185a831 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/init-first.c +@@ -0,0 +1,57 @@ ++/* Copyright (C) 2020-2021 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 ++ . */ ++ ++#ifdef SHARED ++# include ++# include ++ ++long int (*VDSO_SYMBOL (getcpu)) (unsigned int *, unsigned int *, void *) ++ attribute_hidden; ++long int (*VDSO_SYMBOL (gettimeofday)) (struct timeval *, void *) ++ attribute_hidden; ++long int (*VDSO_SYMBOL (clock_gettime)) (clockid_t, struct timespec *) ++ attribute_hidden; ++long int (*VDSO_SYMBOL (clock_getres)) (clockid_t, struct timespec *) ++ attribute_hidden; ++ ++static inline void ++_libc_vdso_platform_setup (void) ++{ ++ PREPARE_VERSION_KNOWN (linux_version, LINUX_2_6); ++ ++ void *p = _dl_vdso_vsym ("__vdso_getcpu", &linux_version); ++ PTR_MANGLE (p); ++ VDSO_SYMBOL (getcpu) = p; ++ ++ p = _dl_vdso_vsym ("__vdso_gettimeofday", &linux_version); ++ PTR_MANGLE (p); ++ VDSO_SYMBOL (gettimeofday) = p; ++ ++ p = _dl_vdso_vsym ("__vdso_clock_gettime", &linux_version); ++ PTR_MANGLE (p); ++ VDSO_SYMBOL (clock_gettime) = p; ++ ++ p = _dl_vdso_vsym ("__vdso_clock_getres", &linux_version); ++ PTR_MANGLE (p); ++ VDSO_SYMBOL (clock_getres) = p; ++} ++ ++# define VDSO_SETUP _libc_vdso_platform_setup ++#endif ++ ++#include +diff --git a/sysdeps/unix/sysv/linux/loongarch/ipc_priv.h b/sysdeps/unix/sysv/linux/loongarch/ipc_priv.h +new file mode 100644 +index 00000000..51583429 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/ipc_priv.h +@@ -0,0 +1,21 @@ ++/* Old SysV permission definition for Linux. LoongArch version. ++ Copyright (C) 2020 Loongson Technology, 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 ++ . */ ++ ++#include /* For __key_t */ ++ ++#define __IPC_64 0x0 +diff --git a/sysdeps/unix/sysv/linux/loongarch/kernel-features.h b/sysdeps/unix/sysv/linux/loongarch/kernel-features.h +new file mode 100644 +index 00000000..c87c7967 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/kernel-features.h +@@ -0,0 +1,24 @@ ++/* Copyright (C) 2020-2021 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 ++ . */ ++ ++#include_next ++ ++/* No support for PI mutexes or robust futexes before 4.20. */ ++#if __LINUX_KERNEL_VERSION < 0x041400 ++# undef __ASSUME_SET_ROBUST_LIST ++#endif +diff --git a/sysdeps/unix/sysv/linux/loongarch/ldd-rewrite.sed b/sysdeps/unix/sysv/linux/loongarch/ldd-rewrite.sed +new file mode 100644 +index 00000000..131c5f14 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/ldd-rewrite.sed +@@ -0,0 +1 @@ ++s_^\(RTLDLIST=\)\(.*lib/\)\(ld-linux\)-\(loongarch64\)-\(lp64\)\(d*\)\(\.so\.[0-9.]*\)_\1"\2\3-\4-\5\7 \2\3-\4-\5d\7"_ +diff --git a/sysdeps/unix/sysv/linux/loongarch/ldsodefs.h b/sysdeps/unix/sysv/linux/loongarch/ldsodefs.h +new file mode 100644 +index 00000000..c0fc7046 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/ldsodefs.h +@@ -0,0 +1,32 @@ ++/* Copyright (C) 2020-2021 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 ++ . */ ++ ++#ifndef _LDSODEFS_H ++ ++/* Get the real definitions. */ ++#include_next ++ ++/* Now define our stuff. */ ++ ++/* We need special support to initialize DSO loaded for statically linked ++ binaries. */ ++extern void _dl_static_init (struct link_map *map); ++#undef DL_STATIC_INIT ++#define DL_STATIC_INIT(map) _dl_static_init (map) ++ ++#endif /* ldsodefs.h */ +diff --git a/sysdeps/unix/sysv/linux/loongarch/libc-vdso.h b/sysdeps/unix/sysv/linux/loongarch/libc-vdso.h +new file mode 100644 +index 00000000..658c27a5 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/libc-vdso.h +@@ -0,0 +1,37 @@ ++/* Copyright (C) 2020-2021 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 ++ . */ ++ ++#ifndef _LIBC_VDSO_H ++#define _LIBC_VDSO_H ++ ++#ifdef SHARED ++ ++# include ++ ++extern long int (*VDSO_SYMBOL (getcpu)) (unsigned int *, unsigned int *, void *) ++ attribute_hidden; ++extern long int (*VDSO_SYMBOL (gettimeofday)) (struct timeval *, void *) ++ attribute_hidden; ++extern long int (*VDSO_SYMBOL (clock_gettime)) (clockid_t, struct timespec *) ++ attribute_hidden; ++extern long int (*VDSO_SYMBOL (clock_getres)) (clockid_t, struct timespec *) ++ attribute_hidden; ++ ++#endif ++ ++#endif /* _LIBC_VDSO_H */ +diff --git a/sysdeps/unix/sysv/linux/loongarch/localplt.data b/sysdeps/unix/sysv/linux/loongarch/localplt.data +new file mode 100644 +index 00000000..0ed8650b +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/localplt.data +@@ -0,0 +1,13 @@ ++# See scripts/check-localplt.awk for how this file is processed. ++# PLT use is required for the malloc family and for matherr because ++# users can define their own functions and have library internals call them. ++libc.so: calloc ++libc.so: free ++libc.so: malloc ++libc.so: memalign ++libc.so: realloc ++# The TLS-enabled version of these functions is interposed from libc.so. ++ld.so: _dl_signal_error ++ld.so: _dl_catch_error ++ld.so: _dl_signal_exception ++ld.so: _dl_catch_exception +diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/Implies b/sysdeps/unix/sysv/linux/loongarch/lp64/Implies +new file mode 100644 +index 00000000..117c2b8e +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/lp64/Implies +@@ -0,0 +1,3 @@ ++unix/sysv/linux/loongarch ++unix/sysv/linux/generic ++unix/sysv/linux/wordsize-64 +diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/c++-types.data b/sysdeps/unix/sysv/linux/loongarch/lp64/c++-types.data +new file mode 100644 +index 00000000..ac925ccb +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/lp64/c++-types.data +@@ -0,0 +1,67 @@ ++blkcnt64_t:l ++blkcnt_t:l ++blksize_t:i ++caddr_t:Pc ++clockid_t:i ++clock_t:l ++daddr_t:i ++dev_t:m ++fd_mask:l ++fsblkcnt64_t:m ++fsblkcnt_t:m ++fsfilcnt64_t:m ++fsfilcnt_t:m ++fsid_t:8__fsid_t ++gid_t:j ++id_t:j ++ino64_t:m ++ino_t:m ++int16_t:s ++int32_t:i ++int64_t:l ++int8_t:a ++intptr_t:l ++key_t:i ++loff_t:l ++mode_t:j ++nlink_t:j ++off64_t:l ++off_t:l ++pid_t:i ++pthread_attr_t:14pthread_attr_t ++pthread_barrier_t:17pthread_barrier_t ++pthread_barrierattr_t:21pthread_barrierattr_t ++pthread_cond_t:14pthread_cond_t ++pthread_condattr_t:18pthread_condattr_t ++pthread_key_t:j ++pthread_mutex_t:15pthread_mutex_t ++pthread_mutexattr_t:19pthread_mutexattr_t ++pthread_once_t:i ++pthread_rwlock_t:16pthread_rwlock_t ++pthread_rwlockattr_t:20pthread_rwlockattr_t ++pthread_spinlock_t:i ++pthread_t:m ++quad_t:l ++register_t:l ++rlim64_t:m ++rlim_t:m ++sigset_t:10__sigset_t ++size_t:m ++socklen_t:j ++ssize_t:l ++suseconds_t:l ++time_t:l ++u_char:h ++uid_t:j ++uint:j ++u_int:j ++u_int16_t:t ++u_int32_t:j ++u_int64_t:m ++u_int8_t:h ++ulong:m ++u_long:m ++u_quad_t:m ++useconds_t:j ++ushort:t ++u_short:t +diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/jmp_buf-macros.h b/sysdeps/unix/sysv/linux/loongarch/lp64/jmp_buf-macros.h +new file mode 100644 +index 00000000..e1c96e67 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/lp64/jmp_buf-macros.h +@@ -0,0 +1,41 @@ ++/* Copyright (C) 2020-2021 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 ++ . */ ++ ++/* Produced by this program: ++ ++ #include ++ #include ++ #include ++ #include ++ ++ int main (int argc, char **argv) ++ { ++ printf ("#define JMP_BUF_SIZE %d\n", sizeof (jmp_buf)); ++ printf ("#define JMP_BUF_ALIGN %d\n", __alignof__ (jmp_buf)); ++ printf ("#define SIGJMP_BUF_SIZE %d\n", sizeof (sigjmp_buf)); ++ printf ("#define SIGJMP_BUF_ALIGN %d\n", __alignof__ (sigjmp_buf)); ++ printf ("#define MASK_WAS_SAVED_OFFSET %d\n", offsetof (struct __jmp_buf_tag, __mask_was_saved)); ++ printf ("#define SAVED_MASK_OFFSET %d\n", offsetof (struct __jmp_buf_tag, __saved_mask)); ++ } */ ++ ++# define JMP_BUF_SIZE 304 ++# define JMP_BUF_ALIGN 8 ++# define SIGJMP_BUF_SIZE 304 ++# define SIGJMP_BUF_ALIGN 8 ++# define MASK_WAS_SAVED_OFFSET 168 ++# define SAVED_MASK_OFFSET 176 +diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/ld.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/ld.abilist +new file mode 100644 +index 00000000..845f356c +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/lp64/ld.abilist +@@ -0,0 +1,5 @@ ++GLIBC_2.27 __libc_stack_end D 0x8 ++GLIBC_2.27 __stack_chk_guard D 0x8 ++GLIBC_2.27 __tls_get_addr F ++GLIBC_2.27 _dl_mcount F ++GLIBC_2.27 _r_debug D 0x28 +diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libBrokenLocale.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libBrokenLocale.abilist +new file mode 100644 +index 00000000..18968d3c +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libBrokenLocale.abilist +@@ -0,0 +1 @@ ++GLIBC_2.27 __ctype_get_mb_cur_max F +diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libanl.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libanl.abilist +new file mode 100644 +index 00000000..711fc87c +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libanl.abilist +@@ -0,0 +1,4 @@ ++GLIBC_2.27 gai_cancel F ++GLIBC_2.27 gai_error F ++GLIBC_2.27 gai_suspend F ++GLIBC_2.27 getaddrinfo_a F +diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist +new file mode 100644 +index 00000000..4d8733f2 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist +@@ -0,0 +1,2101 @@ ++GLIBC_2.27 _Exit F ++GLIBC_2.27 _IO_2_1_stderr_ D 0xe0 ++GLIBC_2.27 _IO_2_1_stdin_ D 0xe0 ++GLIBC_2.27 _IO_2_1_stdout_ D 0xe0 ++GLIBC_2.27 _IO_adjust_column F ++GLIBC_2.27 _IO_adjust_wcolumn F ++GLIBC_2.27 _IO_default_doallocate F ++GLIBC_2.27 _IO_default_finish F ++GLIBC_2.27 _IO_default_pbackfail F ++GLIBC_2.27 _IO_default_uflow F ++GLIBC_2.27 _IO_default_xsgetn F ++GLIBC_2.27 _IO_default_xsputn F ++GLIBC_2.27 _IO_do_write F ++GLIBC_2.27 _IO_doallocbuf F ++GLIBC_2.27 _IO_fclose F ++GLIBC_2.27 _IO_fdopen F ++GLIBC_2.27 _IO_feof F ++GLIBC_2.27 _IO_ferror F ++GLIBC_2.27 _IO_fflush F ++GLIBC_2.27 _IO_fgetpos F ++GLIBC_2.27 _IO_fgetpos64 F ++GLIBC_2.27 _IO_fgets F ++GLIBC_2.27 _IO_file_attach F ++GLIBC_2.27 _IO_file_close F ++GLIBC_2.27 _IO_file_close_it F ++GLIBC_2.27 _IO_file_doallocate F ++GLIBC_2.27 _IO_file_finish F ++GLIBC_2.27 _IO_file_fopen F ++GLIBC_2.27 _IO_file_init F ++GLIBC_2.27 _IO_file_jumps D 0xa8 ++GLIBC_2.27 _IO_file_open F ++GLIBC_2.27 _IO_file_overflow F ++GLIBC_2.27 _IO_file_read F ++GLIBC_2.27 _IO_file_seek F ++GLIBC_2.27 _IO_file_seekoff F ++GLIBC_2.27 _IO_file_setbuf F ++GLIBC_2.27 _IO_file_stat F ++GLIBC_2.27 _IO_file_sync F ++GLIBC_2.27 _IO_file_underflow F ++GLIBC_2.27 _IO_file_write F ++GLIBC_2.27 _IO_file_xsputn F ++GLIBC_2.27 _IO_flockfile F ++GLIBC_2.27 _IO_flush_all F ++GLIBC_2.27 _IO_flush_all_linebuffered F ++GLIBC_2.27 _IO_fopen F ++GLIBC_2.27 _IO_fprintf F ++GLIBC_2.27 _IO_fputs F ++GLIBC_2.27 _IO_fread F ++GLIBC_2.27 _IO_free_backup_area F ++GLIBC_2.27 _IO_free_wbackup_area F ++GLIBC_2.27 _IO_fsetpos F ++GLIBC_2.27 _IO_fsetpos64 F ++GLIBC_2.27 _IO_ftell F ++GLIBC_2.27 _IO_ftrylockfile F ++GLIBC_2.27 _IO_funlockfile F ++GLIBC_2.27 _IO_fwrite F ++GLIBC_2.27 _IO_getc F ++GLIBC_2.27 _IO_getline F ++GLIBC_2.27 _IO_getline_info F ++GLIBC_2.27 _IO_gets F ++GLIBC_2.27 _IO_init F ++GLIBC_2.27 _IO_init_marker F ++GLIBC_2.27 _IO_init_wmarker F ++GLIBC_2.27 _IO_iter_begin F ++GLIBC_2.27 _IO_iter_end F ++GLIBC_2.27 _IO_iter_file F ++GLIBC_2.27 _IO_iter_next F ++GLIBC_2.27 _IO_least_wmarker F ++GLIBC_2.27 _IO_link_in F ++GLIBC_2.27 _IO_list_all D 0x8 ++GLIBC_2.27 _IO_list_lock F ++GLIBC_2.27 _IO_list_resetlock F ++GLIBC_2.27 _IO_list_unlock F ++GLIBC_2.27 _IO_marker_delta F ++GLIBC_2.27 _IO_marker_difference F ++GLIBC_2.27 _IO_padn F ++GLIBC_2.27 _IO_peekc_locked F ++GLIBC_2.27 _IO_popen F ++GLIBC_2.27 _IO_printf F ++GLIBC_2.27 _IO_proc_close F ++GLIBC_2.27 _IO_proc_open F ++GLIBC_2.27 _IO_putc F ++GLIBC_2.27 _IO_puts F ++GLIBC_2.27 _IO_remove_marker F ++GLIBC_2.27 _IO_seekmark F ++GLIBC_2.27 _IO_seekoff F ++GLIBC_2.27 _IO_seekpos F ++GLIBC_2.27 _IO_seekwmark F ++GLIBC_2.27 _IO_setb F ++GLIBC_2.27 _IO_setbuffer F ++GLIBC_2.27 _IO_setvbuf F ++GLIBC_2.27 _IO_sgetn F ++GLIBC_2.27 _IO_sprintf F ++GLIBC_2.27 _IO_sputbackc F ++GLIBC_2.27 _IO_sputbackwc F ++GLIBC_2.27 _IO_sscanf F ++GLIBC_2.27 _IO_str_init_readonly F ++GLIBC_2.27 _IO_str_init_static F ++GLIBC_2.27 _IO_str_overflow F ++GLIBC_2.27 _IO_str_pbackfail F ++GLIBC_2.27 _IO_str_seekoff F ++GLIBC_2.27 _IO_str_underflow F ++GLIBC_2.27 _IO_sungetc F ++GLIBC_2.27 _IO_sungetwc F ++GLIBC_2.27 _IO_switch_to_get_mode F ++GLIBC_2.27 _IO_switch_to_main_wget_area F ++GLIBC_2.27 _IO_switch_to_wbackup_area F ++GLIBC_2.27 _IO_switch_to_wget_mode F ++GLIBC_2.27 _IO_un_link F ++GLIBC_2.27 _IO_ungetc F ++GLIBC_2.27 _IO_unsave_markers F ++GLIBC_2.27 _IO_unsave_wmarkers F ++GLIBC_2.27 _IO_vfprintf F ++GLIBC_2.27 _IO_vfscanf F ++GLIBC_2.27 _IO_vsprintf F ++GLIBC_2.27 _IO_wdefault_doallocate F ++GLIBC_2.27 _IO_wdefault_finish F ++GLIBC_2.27 _IO_wdefault_pbackfail F ++GLIBC_2.27 _IO_wdefault_uflow F ++GLIBC_2.27 _IO_wdefault_xsgetn F ++GLIBC_2.27 _IO_wdefault_xsputn F ++GLIBC_2.27 _IO_wdo_write F ++GLIBC_2.27 _IO_wdoallocbuf F ++GLIBC_2.27 _IO_wfile_jumps D 0xa8 ++GLIBC_2.27 _IO_wfile_overflow F ++GLIBC_2.27 _IO_wfile_seekoff F ++GLIBC_2.27 _IO_wfile_sync F ++GLIBC_2.27 _IO_wfile_underflow F ++GLIBC_2.27 _IO_wfile_xsputn F ++GLIBC_2.27 _IO_wmarker_delta F ++GLIBC_2.27 _IO_wsetb F ++GLIBC_2.27 ___brk_addr D 0x8 ++GLIBC_2.27 __adjtimex F ++GLIBC_2.27 __after_morecore_hook D 0x8 ++GLIBC_2.27 __argz_count F ++GLIBC_2.27 __argz_next F ++GLIBC_2.27 __argz_stringify F ++GLIBC_2.27 __asprintf F ++GLIBC_2.27 __asprintf_chk F ++GLIBC_2.27 __assert F ++GLIBC_2.27 __assert_fail F ++GLIBC_2.27 __assert_perror_fail F ++GLIBC_2.27 __backtrace F ++GLIBC_2.27 __backtrace_symbols F ++GLIBC_2.27 __backtrace_symbols_fd F ++GLIBC_2.27 __bsd_getpgrp F ++GLIBC_2.27 __bzero F ++GLIBC_2.27 __check_rhosts_file D 0x4 ++GLIBC_2.27 __chk_fail F ++GLIBC_2.27 __clone F ++GLIBC_2.27 __close F ++GLIBC_2.27 __cmsg_nxthdr F ++GLIBC_2.27 __confstr_chk F ++GLIBC_2.27 __connect F ++GLIBC_2.27 __ctype_b_loc F ++GLIBC_2.27 __ctype_get_mb_cur_max F ++GLIBC_2.27 __ctype_tolower_loc F ++GLIBC_2.27 __ctype_toupper_loc F ++GLIBC_2.27 __curbrk D 0x8 ++GLIBC_2.27 __cxa_at_quick_exit F ++GLIBC_2.27 __cxa_atexit F ++GLIBC_2.27 __cxa_finalize F ++GLIBC_2.27 __cxa_thread_atexit_impl F ++GLIBC_2.27 __cyg_profile_func_enter F ++GLIBC_2.27 __cyg_profile_func_exit F ++GLIBC_2.27 __daylight D 0x4 ++GLIBC_2.27 __dcgettext F ++GLIBC_2.27 __default_morecore F ++GLIBC_2.27 __dgettext F ++GLIBC_2.27 __dprintf_chk F ++GLIBC_2.27 __dup2 F ++GLIBC_2.27 __duplocale F ++GLIBC_2.27 __endmntent F ++GLIBC_2.27 __environ D 0x8 ++GLIBC_2.27 __errno_location F ++GLIBC_2.27 __explicit_bzero_chk F ++GLIBC_2.27 __fbufsize F ++GLIBC_2.27 __fcntl F ++GLIBC_2.27 __fdelt_chk F ++GLIBC_2.27 __fdelt_warn F ++GLIBC_2.27 __ffs F ++GLIBC_2.27 __fgets_chk F ++GLIBC_2.27 __fgets_unlocked_chk F ++GLIBC_2.27 __fgetws_chk F ++GLIBC_2.27 __fgetws_unlocked_chk F ++GLIBC_2.27 __finite F ++GLIBC_2.27 __finitef F ++GLIBC_2.27 __finitel F ++GLIBC_2.27 __flbf F ++GLIBC_2.27 __fork F ++GLIBC_2.27 __fpending F ++GLIBC_2.27 __fprintf_chk F ++GLIBC_2.27 __fpu_control D 0x4 ++GLIBC_2.27 __fpurge F ++GLIBC_2.27 __fread_chk F ++GLIBC_2.27 __fread_unlocked_chk F ++GLIBC_2.27 __freadable F ++GLIBC_2.27 __freading F ++GLIBC_2.27 __free_hook D 0x8 ++GLIBC_2.27 __freelocale F ++GLIBC_2.27 __fsetlocking F ++GLIBC_2.27 __fwprintf_chk F ++GLIBC_2.27 __fwritable F ++GLIBC_2.27 __fwriting F ++GLIBC_2.27 __fxstat F ++GLIBC_2.27 __fxstat64 F ++GLIBC_2.27 __fxstatat F ++GLIBC_2.27 __fxstatat64 F ++GLIBC_2.27 __getauxval F ++GLIBC_2.27 __getcwd_chk F ++GLIBC_2.27 __getdelim F ++GLIBC_2.27 __getdomainname_chk F ++GLIBC_2.27 __getgroups_chk F ++GLIBC_2.27 __gethostname_chk F ++GLIBC_2.27 __getlogin_r_chk F ++GLIBC_2.27 __getmntent_r F ++GLIBC_2.27 __getpagesize F ++GLIBC_2.27 __getpgid F ++GLIBC_2.27 __getpid F ++GLIBC_2.27 __gets_chk F ++GLIBC_2.27 __gettimeofday F ++GLIBC_2.27 __getwd_chk F ++GLIBC_2.27 __gmtime_r F ++GLIBC_2.27 __h_errno_location F ++GLIBC_2.27 __isalnum_l F ++GLIBC_2.27 __isalpha_l F ++GLIBC_2.27 __isascii_l F ++GLIBC_2.27 __isblank_l F ++GLIBC_2.27 __iscntrl_l F ++GLIBC_2.27 __isctype F ++GLIBC_2.27 __isdigit_l F ++GLIBC_2.27 __isgraph_l F ++GLIBC_2.27 __isinf F ++GLIBC_2.27 __isinff F ++GLIBC_2.27 __isinfl F ++GLIBC_2.27 __islower_l F ++GLIBC_2.27 __isnan F ++GLIBC_2.27 __isnanf F ++GLIBC_2.27 __isnanl F ++GLIBC_2.27 __isoc99_fscanf F ++GLIBC_2.27 __isoc99_fwscanf F ++GLIBC_2.27 __isoc99_scanf F ++GLIBC_2.27 __isoc99_sscanf F ++GLIBC_2.27 __isoc99_swscanf F ++GLIBC_2.27 __isoc99_vfscanf F ++GLIBC_2.27 __isoc99_vfwscanf F ++GLIBC_2.27 __isoc99_vscanf F ++GLIBC_2.27 __isoc99_vsscanf F ++GLIBC_2.27 __isoc99_vswscanf F ++GLIBC_2.27 __isoc99_vwscanf F ++GLIBC_2.27 __isoc99_wscanf F ++GLIBC_2.27 __isprint_l F ++GLIBC_2.27 __ispunct_l F ++GLIBC_2.27 __isspace_l F ++GLIBC_2.27 __isupper_l F ++GLIBC_2.27 __iswalnum_l F ++GLIBC_2.27 __iswalpha_l F ++GLIBC_2.27 __iswblank_l F ++GLIBC_2.27 __iswcntrl_l F ++GLIBC_2.27 __iswctype F ++GLIBC_2.27 __iswctype_l F ++GLIBC_2.27 __iswdigit_l F ++GLIBC_2.27 __iswgraph_l F ++GLIBC_2.27 __iswlower_l F ++GLIBC_2.27 __iswprint_l F ++GLIBC_2.27 __iswpunct_l F ++GLIBC_2.27 __iswspace_l F ++GLIBC_2.27 __iswupper_l F ++GLIBC_2.27 __iswxdigit_l F ++GLIBC_2.27 __isxdigit_l F ++GLIBC_2.27 __ivaliduser F ++GLIBC_2.27 __key_decryptsession_pk_LOCAL D 0x8 ++GLIBC_2.27 __key_encryptsession_pk_LOCAL D 0x8 ++GLIBC_2.27 __key_gendes_LOCAL D 0x8 ++GLIBC_2.27 __libc_allocate_rtsig F ++GLIBC_2.27 __libc_calloc F ++GLIBC_2.27 __libc_current_sigrtmax F ++GLIBC_2.27 __libc_current_sigrtmin F ++GLIBC_2.27 __libc_free F ++GLIBC_2.27 __libc_freeres F ++GLIBC_2.27 __libc_init_first F ++GLIBC_2.27 __libc_mallinfo F ++GLIBC_2.27 __libc_malloc F ++GLIBC_2.27 __libc_mallopt F ++GLIBC_2.27 __libc_memalign F ++GLIBC_2.27 __libc_pvalloc F ++GLIBC_2.27 __libc_realloc F ++GLIBC_2.27 __libc_sa_len F ++GLIBC_2.27 __libc_start_main F ++GLIBC_2.27 __libc_valloc F ++GLIBC_2.27 __longjmp_chk F ++GLIBC_2.27 __lseek F ++GLIBC_2.27 __lxstat F ++GLIBC_2.27 __lxstat64 F ++GLIBC_2.27 __malloc_hook D 0x8 ++GLIBC_2.27 __mbrlen F ++GLIBC_2.27 __mbrtowc F ++GLIBC_2.27 __mbsnrtowcs_chk F ++GLIBC_2.27 __mbsrtowcs_chk F ++GLIBC_2.27 __mbstowcs_chk F ++GLIBC_2.27 __memalign_hook D 0x8 ++GLIBC_2.27 __memcpy_chk F ++GLIBC_2.27 __memmove_chk F ++GLIBC_2.27 __mempcpy F ++GLIBC_2.27 __mempcpy_chk F ++GLIBC_2.27 __memset_chk F ++GLIBC_2.27 __monstartup F ++GLIBC_2.27 __morecore D 0x8 ++GLIBC_2.27 __nanosleep F ++GLIBC_2.27 __newlocale F ++GLIBC_2.27 __nl_langinfo_l F ++GLIBC_2.27 __nss_configure_lookup F ++GLIBC_2.27 __nss_database_lookup F ++GLIBC_2.27 __nss_hostname_digits_dots F ++GLIBC_2.27 __nss_next F ++GLIBC_2.27 __obstack_printf_chk F ++GLIBC_2.27 __obstack_vprintf_chk F ++GLIBC_2.27 __open F ++GLIBC_2.27 __open64 F ++GLIBC_2.27 __open64_2 F ++GLIBC_2.27 __open_2 F ++GLIBC_2.27 __openat64_2 F ++GLIBC_2.27 __openat_2 F ++GLIBC_2.27 __overflow F ++GLIBC_2.27 __pipe F ++GLIBC_2.27 __poll F ++GLIBC_2.27 __poll_chk F ++GLIBC_2.27 __posix_getopt F ++GLIBC_2.27 __ppoll_chk F ++GLIBC_2.27 __pread64 F ++GLIBC_2.27 __pread64_chk F ++GLIBC_2.27 __pread_chk F ++GLIBC_2.27 __printf_chk F ++GLIBC_2.27 __printf_fp F ++GLIBC_2.27 __profile_frequency F ++GLIBC_2.27 __progname D 0x8 ++GLIBC_2.27 __progname_full D 0x8 ++GLIBC_2.27 __ptsname_r_chk F ++GLIBC_2.27 __pwrite64 F ++GLIBC_2.27 __rawmemchr F ++GLIBC_2.27 __rcmd_errstr D 0x8 ++GLIBC_2.27 __read F ++GLIBC_2.27 __read_chk F ++GLIBC_2.27 __readlink_chk F ++GLIBC_2.27 __readlinkat_chk F ++GLIBC_2.27 __realloc_hook D 0x8 ++GLIBC_2.27 __realpath_chk F ++GLIBC_2.27 __recv_chk F ++GLIBC_2.27 __recvfrom_chk F ++GLIBC_2.27 __register_atfork F ++GLIBC_2.27 __res_init F ++GLIBC_2.27 __res_nclose F ++GLIBC_2.27 __res_ninit F ++GLIBC_2.27 __res_randomid F ++GLIBC_2.27 __res_state F ++GLIBC_2.27 __rpc_thread_createerr F ++GLIBC_2.27 __rpc_thread_svc_fdset F ++GLIBC_2.27 __rpc_thread_svc_max_pollfd F ++GLIBC_2.27 __rpc_thread_svc_pollfd F ++GLIBC_2.27 __sbrk F ++GLIBC_2.27 __sched_cpualloc F ++GLIBC_2.27 __sched_cpucount F ++GLIBC_2.27 __sched_cpufree F ++GLIBC_2.27 __sched_get_priority_max F ++GLIBC_2.27 __sched_get_priority_min F ++GLIBC_2.27 __sched_getparam F ++GLIBC_2.27 __sched_getscheduler F ++GLIBC_2.27 __sched_setscheduler F ++GLIBC_2.27 __sched_yield F ++GLIBC_2.27 __select F ++GLIBC_2.27 __send F ++GLIBC_2.27 __setmntent F ++GLIBC_2.27 __setpgid F ++GLIBC_2.27 __sigaction F ++GLIBC_2.27 __signbit F ++GLIBC_2.27 __signbitf F ++GLIBC_2.27 __signbitl F ++GLIBC_2.27 __sigpause F ++GLIBC_2.27 __sigsetjmp F ++GLIBC_2.27 __sigsuspend F ++GLIBC_2.27 __snprintf_chk F ++GLIBC_2.27 __sprintf_chk F ++GLIBC_2.27 __stack_chk_fail F ++GLIBC_2.27 __statfs F ++GLIBC_2.27 __stpcpy F ++GLIBC_2.27 __stpcpy_chk F ++GLIBC_2.27 __stpncpy F ++GLIBC_2.27 __stpncpy_chk F ++GLIBC_2.27 __strcasecmp F ++GLIBC_2.27 __strcasecmp_l F ++GLIBC_2.27 __strcasestr F ++GLIBC_2.27 __strcat_chk F ++GLIBC_2.27 __strcoll_l F ++GLIBC_2.27 __strcpy_chk F ++GLIBC_2.27 __strdup F ++GLIBC_2.27 __strerror_r F ++GLIBC_2.27 __strfmon_l F ++GLIBC_2.27 __strftime_l F ++GLIBC_2.27 __strncasecmp_l F ++GLIBC_2.27 __strncat_chk F ++GLIBC_2.27 __strncpy_chk F ++GLIBC_2.27 __strndup F ++GLIBC_2.27 __strsep_g F ++GLIBC_2.27 __strtod_internal F ++GLIBC_2.27 __strtod_l F ++GLIBC_2.27 __strtof_internal F ++GLIBC_2.27 __strtof_l F ++GLIBC_2.27 __strtok_r F ++GLIBC_2.27 __strtol_internal F ++GLIBC_2.27 __strtol_l F ++GLIBC_2.27 __strtold_internal F ++GLIBC_2.27 __strtold_l F ++GLIBC_2.27 __strtoll_internal F ++GLIBC_2.27 __strtoll_l F ++GLIBC_2.27 __strtoul_internal F ++GLIBC_2.27 __strtoul_l F ++GLIBC_2.27 __strtoull_internal F ++GLIBC_2.27 __strtoull_l F ++GLIBC_2.27 __strverscmp F ++GLIBC_2.27 __strxfrm_l F ++GLIBC_2.27 __swprintf_chk F ++GLIBC_2.27 __sysconf F ++GLIBC_2.27 __syslog_chk F ++GLIBC_2.27 __sysv_signal F ++GLIBC_2.27 __timezone D 0x8 ++GLIBC_2.27 __toascii_l F ++GLIBC_2.27 __tolower_l F ++GLIBC_2.27 __toupper_l F ++GLIBC_2.27 __towctrans F ++GLIBC_2.27 __towctrans_l F ++GLIBC_2.27 __towlower_l F ++GLIBC_2.27 __towupper_l F ++GLIBC_2.27 __ttyname_r_chk F ++GLIBC_2.27 __tzname D 0x10 ++GLIBC_2.27 __uflow F ++GLIBC_2.27 __underflow F ++GLIBC_2.27 __uselocale F ++GLIBC_2.27 __vasprintf_chk F ++GLIBC_2.27 __vdprintf_chk F ++GLIBC_2.27 __vfork F ++GLIBC_2.27 __vfprintf_chk F ++GLIBC_2.27 __vfscanf F ++GLIBC_2.27 __vfwprintf_chk F ++GLIBC_2.27 __vprintf_chk F ++GLIBC_2.27 __vsnprintf F ++GLIBC_2.27 __vsnprintf_chk F ++GLIBC_2.27 __vsprintf_chk F ++GLIBC_2.27 __vsscanf F ++GLIBC_2.27 __vswprintf_chk F ++GLIBC_2.27 __vsyslog_chk F ++GLIBC_2.27 __vwprintf_chk F ++GLIBC_2.27 __wait F ++GLIBC_2.27 __waitpid F ++GLIBC_2.27 __wcpcpy_chk F ++GLIBC_2.27 __wcpncpy_chk F ++GLIBC_2.27 __wcrtomb_chk F ++GLIBC_2.27 __wcscasecmp_l F ++GLIBC_2.27 __wcscat_chk F ++GLIBC_2.27 __wcscoll_l F ++GLIBC_2.27 __wcscpy_chk F ++GLIBC_2.27 __wcsftime_l F ++GLIBC_2.27 __wcsncasecmp_l F ++GLIBC_2.27 __wcsncat_chk F ++GLIBC_2.27 __wcsncpy_chk F ++GLIBC_2.27 __wcsnrtombs_chk F ++GLIBC_2.27 __wcsrtombs_chk F ++GLIBC_2.27 __wcstod_internal F ++GLIBC_2.27 __wcstod_l F ++GLIBC_2.27 __wcstof_internal F ++GLIBC_2.27 __wcstof_l F ++GLIBC_2.27 __wcstol_internal F ++GLIBC_2.27 __wcstol_l F ++GLIBC_2.27 __wcstold_internal F ++GLIBC_2.27 __wcstold_l F ++GLIBC_2.27 __wcstoll_internal F ++GLIBC_2.27 __wcstoll_l F ++GLIBC_2.27 __wcstombs_chk F ++GLIBC_2.27 __wcstoul_internal F ++GLIBC_2.27 __wcstoul_l F ++GLIBC_2.27 __wcstoull_internal F ++GLIBC_2.27 __wcstoull_l F ++GLIBC_2.27 __wcsxfrm_l F ++GLIBC_2.27 __wctomb_chk F ++GLIBC_2.27 __wctrans_l F ++GLIBC_2.27 __wctype_l F ++GLIBC_2.27 __wmemcpy_chk F ++GLIBC_2.27 __wmemmove_chk F ++GLIBC_2.27 __wmempcpy_chk F ++GLIBC_2.27 __wmemset_chk F ++GLIBC_2.27 __woverflow F ++GLIBC_2.27 __wprintf_chk F ++GLIBC_2.27 __write F ++GLIBC_2.27 __wuflow F ++GLIBC_2.27 __wunderflow F ++GLIBC_2.27 __xmknod F ++GLIBC_2.27 __xmknodat F ++GLIBC_2.27 __xpg_basename F ++GLIBC_2.27 __xpg_sigpause F ++GLIBC_2.27 __xpg_strerror_r F ++GLIBC_2.27 __xstat F ++GLIBC_2.27 __xstat64 F ++GLIBC_2.27 _authenticate F ++GLIBC_2.27 _dl_mcount_wrapper F ++GLIBC_2.27 _dl_mcount_wrapper_check F ++GLIBC_2.27 _environ D 0x8 ++GLIBC_2.27 _exit F ++GLIBC_2.27 _flushlbf F ++GLIBC_2.27 _libc_intl_domainname D 0x5 ++GLIBC_2.27 _longjmp F ++GLIBC_2.27 _mcleanup F ++GLIBC_2.27 _mcount F ++GLIBC_2.27 _nl_default_dirname D 0x12 ++GLIBC_2.27 _nl_domain_bindings D 0x8 ++GLIBC_2.27 _nl_msg_cat_cntr D 0x4 ++GLIBC_2.27 _null_auth D 0x18 ++GLIBC_2.27 _obstack_allocated_p F ++GLIBC_2.27 _obstack_begin F ++GLIBC_2.27 _obstack_begin_1 F ++GLIBC_2.27 _obstack_free F ++GLIBC_2.27 _obstack_memory_used F ++GLIBC_2.27 _obstack_newchunk F ++GLIBC_2.27 _res D 0x238 ++GLIBC_2.27 _res_hconf D 0x48 ++GLIBC_2.27 _rpc_dtablesize F ++GLIBC_2.27 _seterr_reply F ++GLIBC_2.27 _setjmp F ++GLIBC_2.27 _sys_errlist D 0x2370 ++GLIBC_2.27 _sys_nerr D 0x4 ++GLIBC_2.27 _sys_siglist D 0x400 ++GLIBC_2.27 _tolower F ++GLIBC_2.27 _toupper F ++GLIBC_2.27 a64l F ++GLIBC_2.27 abort F ++GLIBC_2.27 abs F ++GLIBC_2.27 accept F ++GLIBC_2.27 accept4 F ++GLIBC_2.27 access F ++GLIBC_2.27 acct F ++GLIBC_2.27 addmntent F ++GLIBC_2.27 addseverity F ++GLIBC_2.27 adjtime F ++GLIBC_2.27 adjtimex F ++GLIBC_2.27 alarm F ++GLIBC_2.27 aligned_alloc F ++GLIBC_2.27 alphasort F ++GLIBC_2.27 alphasort64 F ++GLIBC_2.27 argp_err_exit_status D 0x4 ++GLIBC_2.27 argp_error F ++GLIBC_2.27 argp_failure F ++GLIBC_2.27 argp_help F ++GLIBC_2.27 argp_parse F ++GLIBC_2.27 argp_program_bug_address D 0x8 ++GLIBC_2.27 argp_program_version D 0x8 ++GLIBC_2.27 argp_program_version_hook D 0x8 ++GLIBC_2.27 argp_state_help F ++GLIBC_2.27 argp_usage F ++GLIBC_2.27 argz_add F ++GLIBC_2.27 argz_add_sep F ++GLIBC_2.27 argz_append F ++GLIBC_2.27 argz_count F ++GLIBC_2.27 argz_create F ++GLIBC_2.27 argz_create_sep F ++GLIBC_2.27 argz_delete F ++GLIBC_2.27 argz_extract F ++GLIBC_2.27 argz_insert F ++GLIBC_2.27 argz_next F ++GLIBC_2.27 argz_replace F ++GLIBC_2.27 argz_stringify F ++GLIBC_2.27 asctime F ++GLIBC_2.27 asctime_r F ++GLIBC_2.27 asprintf F ++GLIBC_2.27 atof F ++GLIBC_2.27 atoi F ++GLIBC_2.27 atol F ++GLIBC_2.27 atoll F ++GLIBC_2.27 authdes_create F ++GLIBC_2.27 authdes_getucred F ++GLIBC_2.27 authdes_pk_create F ++GLIBC_2.27 authnone_create F ++GLIBC_2.27 authunix_create F ++GLIBC_2.27 authunix_create_default F ++GLIBC_2.27 backtrace F ++GLIBC_2.27 backtrace_symbols F ++GLIBC_2.27 backtrace_symbols_fd F ++GLIBC_2.27 basename F ++GLIBC_2.27 bcmp F ++GLIBC_2.27 bcopy F ++GLIBC_2.27 bind F ++GLIBC_2.27 bind_textdomain_codeset F ++GLIBC_2.27 bindresvport F ++GLIBC_2.27 bindtextdomain F ++GLIBC_2.27 brk F ++GLIBC_2.27 bsd_signal F ++GLIBC_2.27 bsearch F ++GLIBC_2.27 btowc F ++GLIBC_2.27 bzero F ++GLIBC_2.27 c16rtomb F ++GLIBC_2.27 c32rtomb F ++GLIBC_2.27 calloc F ++GLIBC_2.27 callrpc F ++GLIBC_2.27 canonicalize_file_name F ++GLIBC_2.27 capget F ++GLIBC_2.27 capset F ++GLIBC_2.27 catclose F ++GLIBC_2.27 catgets F ++GLIBC_2.27 catopen F ++GLIBC_2.27 cbc_crypt F ++GLIBC_2.27 cfgetispeed F ++GLIBC_2.27 cfgetospeed F ++GLIBC_2.27 cfmakeraw F ++GLIBC_2.27 cfsetispeed F ++GLIBC_2.27 cfsetospeed F ++GLIBC_2.27 cfsetspeed F ++GLIBC_2.27 chdir F ++GLIBC_2.27 chflags F ++GLIBC_2.27 chmod F ++GLIBC_2.27 chown F ++GLIBC_2.27 chroot F ++GLIBC_2.27 clearenv F ++GLIBC_2.27 clearerr F ++GLIBC_2.27 clearerr_unlocked F ++GLIBC_2.27 clnt_broadcast F ++GLIBC_2.27 clnt_create F ++GLIBC_2.27 clnt_pcreateerror F ++GLIBC_2.27 clnt_perrno F ++GLIBC_2.27 clnt_perror F ++GLIBC_2.27 clnt_spcreateerror F ++GLIBC_2.27 clnt_sperrno F ++GLIBC_2.27 clnt_sperror F ++GLIBC_2.27 clntraw_create F ++GLIBC_2.27 clnttcp_create F ++GLIBC_2.27 clntudp_bufcreate F ++GLIBC_2.27 clntudp_create F ++GLIBC_2.27 clntunix_create F ++GLIBC_2.27 clock F ++GLIBC_2.27 clock_adjtime F ++GLIBC_2.27 clock_getcpuclockid F ++GLIBC_2.27 clock_getres F ++GLIBC_2.27 clock_gettime F ++GLIBC_2.27 clock_nanosleep F ++GLIBC_2.27 clock_settime F ++GLIBC_2.27 clone F ++GLIBC_2.27 close F ++GLIBC_2.27 closedir F ++GLIBC_2.27 closelog F ++GLIBC_2.27 confstr F ++GLIBC_2.27 connect F ++GLIBC_2.27 copy_file_range F ++GLIBC_2.27 copysign F ++GLIBC_2.27 copysignf F ++GLIBC_2.27 copysignl F ++GLIBC_2.27 creat F ++GLIBC_2.27 creat64 F ++GLIBC_2.27 ctermid F ++GLIBC_2.27 ctime F ++GLIBC_2.27 ctime_r F ++GLIBC_2.27 cuserid F ++GLIBC_2.27 daemon F ++GLIBC_2.27 daylight D 0x4 ++GLIBC_2.27 dcgettext F ++GLIBC_2.27 dcngettext F ++GLIBC_2.27 delete_module F ++GLIBC_2.27 des_setparity F ++GLIBC_2.27 dgettext F ++GLIBC_2.27 difftime F ++GLIBC_2.27 dirfd F ++GLIBC_2.27 dirname F ++GLIBC_2.27 div F ++GLIBC_2.27 dl_iterate_phdr F ++GLIBC_2.27 dngettext F ++GLIBC_2.27 dprintf F ++GLIBC_2.27 drand48 F ++GLIBC_2.27 drand48_r F ++GLIBC_2.27 dup F ++GLIBC_2.27 dup2 F ++GLIBC_2.27 dup3 F ++GLIBC_2.27 duplocale F ++GLIBC_2.27 dysize F ++GLIBC_2.27 eaccess F ++GLIBC_2.27 ecb_crypt F ++GLIBC_2.27 ecvt F ++GLIBC_2.27 ecvt_r F ++GLIBC_2.27 endaliasent F ++GLIBC_2.27 endfsent F ++GLIBC_2.27 endgrent F ++GLIBC_2.27 endhostent F ++GLIBC_2.27 endmntent F ++GLIBC_2.27 endnetent F ++GLIBC_2.27 endnetgrent F ++GLIBC_2.27 endprotoent F ++GLIBC_2.27 endpwent F ++GLIBC_2.27 endrpcent F ++GLIBC_2.27 endservent F ++GLIBC_2.27 endsgent F ++GLIBC_2.27 endspent F ++GLIBC_2.27 endttyent F ++GLIBC_2.27 endusershell F ++GLIBC_2.27 endutent F ++GLIBC_2.27 endutxent F ++GLIBC_2.27 environ D 0x8 ++GLIBC_2.27 envz_add F ++GLIBC_2.27 envz_entry F ++GLIBC_2.27 envz_get F ++GLIBC_2.27 envz_merge F ++GLIBC_2.27 envz_remove F ++GLIBC_2.27 envz_strip F ++GLIBC_2.27 epoll_create F ++GLIBC_2.27 epoll_create1 F ++GLIBC_2.27 epoll_ctl F ++GLIBC_2.27 epoll_pwait F ++GLIBC_2.27 epoll_wait F ++GLIBC_2.27 erand48 F ++GLIBC_2.27 erand48_r F ++GLIBC_2.27 err F ++GLIBC_2.27 error F ++GLIBC_2.27 error_at_line F ++GLIBC_2.27 error_message_count D 0x4 ++GLIBC_2.27 error_one_per_line D 0x4 ++GLIBC_2.27 error_print_progname D 0x8 ++GLIBC_2.27 errx F ++GLIBC_2.27 ether_aton F ++GLIBC_2.27 ether_aton_r F ++GLIBC_2.27 ether_hostton F ++GLIBC_2.27 ether_line F ++GLIBC_2.27 ether_ntoa F ++GLIBC_2.27 ether_ntoa_r F ++GLIBC_2.27 ether_ntohost F ++GLIBC_2.27 euidaccess F ++GLIBC_2.27 eventfd F ++GLIBC_2.27 eventfd_read F ++GLIBC_2.27 eventfd_write F ++GLIBC_2.27 execl F ++GLIBC_2.27 execle F ++GLIBC_2.27 execlp F ++GLIBC_2.27 execv F ++GLIBC_2.27 execve F ++GLIBC_2.27 execvp F ++GLIBC_2.27 execvpe F ++GLIBC_2.27 exit F ++GLIBC_2.27 explicit_bzero F ++GLIBC_2.27 faccessat F ++GLIBC_2.27 fallocate F ++GLIBC_2.27 fallocate64 F ++GLIBC_2.27 fanotify_init F ++GLIBC_2.27 fanotify_mark F ++GLIBC_2.27 fattach F ++GLIBC_2.27 fchdir F ++GLIBC_2.27 fchflags F ++GLIBC_2.27 fchmod F ++GLIBC_2.27 fchmodat F ++GLIBC_2.27 fchown F ++GLIBC_2.27 fchownat F ++GLIBC_2.27 fclose F ++GLIBC_2.27 fcloseall F ++GLIBC_2.27 fcntl F ++GLIBC_2.27 fcvt F ++GLIBC_2.27 fcvt_r F ++GLIBC_2.27 fdatasync F ++GLIBC_2.27 fdetach F ++GLIBC_2.27 fdopen F ++GLIBC_2.27 fdopendir F ++GLIBC_2.27 feof F ++GLIBC_2.27 feof_unlocked F ++GLIBC_2.27 ferror F ++GLIBC_2.27 ferror_unlocked F ++GLIBC_2.27 fexecve F ++GLIBC_2.27 fflush F ++GLIBC_2.27 fflush_unlocked F ++GLIBC_2.27 ffs F ++GLIBC_2.27 ffsl F ++GLIBC_2.27 ffsll F ++GLIBC_2.27 fgetc F ++GLIBC_2.27 fgetc_unlocked F ++GLIBC_2.27 fgetgrent F ++GLIBC_2.27 fgetgrent_r F ++GLIBC_2.27 fgetpos F ++GLIBC_2.27 fgetpos64 F ++GLIBC_2.27 fgetpwent F ++GLIBC_2.27 fgetpwent_r F ++GLIBC_2.27 fgets F ++GLIBC_2.27 fgets_unlocked F ++GLIBC_2.27 fgetsgent F ++GLIBC_2.27 fgetsgent_r F ++GLIBC_2.27 fgetspent F ++GLIBC_2.27 fgetspent_r F ++GLIBC_2.27 fgetwc F ++GLIBC_2.27 fgetwc_unlocked F ++GLIBC_2.27 fgetws F ++GLIBC_2.27 fgetws_unlocked F ++GLIBC_2.27 fgetxattr F ++GLIBC_2.27 fileno F ++GLIBC_2.27 fileno_unlocked F ++GLIBC_2.27 finite F ++GLIBC_2.27 finitef F ++GLIBC_2.27 finitel F ++GLIBC_2.27 flistxattr F ++GLIBC_2.27 flock F ++GLIBC_2.27 flockfile F ++GLIBC_2.27 fmemopen F ++GLIBC_2.27 fmtmsg F ++GLIBC_2.27 fnmatch F ++GLIBC_2.27 fopen F ++GLIBC_2.27 fopen64 F ++GLIBC_2.27 fopencookie F ++GLIBC_2.27 fork F ++GLIBC_2.27 fpathconf F ++GLIBC_2.27 fprintf F ++GLIBC_2.27 fputc F ++GLIBC_2.27 fputc_unlocked F ++GLIBC_2.27 fputs F ++GLIBC_2.27 fputs_unlocked F ++GLIBC_2.27 fputwc F ++GLIBC_2.27 fputwc_unlocked F ++GLIBC_2.27 fputws F ++GLIBC_2.27 fputws_unlocked F ++GLIBC_2.27 fread F ++GLIBC_2.27 fread_unlocked F ++GLIBC_2.27 free F ++GLIBC_2.27 freeaddrinfo F ++GLIBC_2.27 freeifaddrs F ++GLIBC_2.27 freelocale F ++GLIBC_2.27 fremovexattr F ++GLIBC_2.27 freopen F ++GLIBC_2.27 freopen64 F ++GLIBC_2.27 frexp F ++GLIBC_2.27 frexpf F ++GLIBC_2.27 frexpl F ++GLIBC_2.27 fscanf F ++GLIBC_2.27 fseek F ++GLIBC_2.27 fseeko F ++GLIBC_2.27 fseeko64 F ++GLIBC_2.27 fsetpos F ++GLIBC_2.27 fsetpos64 F ++GLIBC_2.27 fsetxattr F ++GLIBC_2.27 fstatfs F ++GLIBC_2.27 fstatfs64 F ++GLIBC_2.27 fstatvfs F ++GLIBC_2.27 fstatvfs64 F ++GLIBC_2.27 fsync F ++GLIBC_2.27 ftell F ++GLIBC_2.27 ftello F ++GLIBC_2.27 ftello64 F ++GLIBC_2.27 ftime F ++GLIBC_2.27 ftok F ++GLIBC_2.27 ftruncate F ++GLIBC_2.27 ftruncate64 F ++GLIBC_2.27 ftrylockfile F ++GLIBC_2.27 fts64_children F ++GLIBC_2.27 fts64_close F ++GLIBC_2.27 fts64_open F ++GLIBC_2.27 fts64_read F ++GLIBC_2.27 fts64_set F ++GLIBC_2.27 fts_children F ++GLIBC_2.27 fts_close F ++GLIBC_2.27 fts_open F ++GLIBC_2.27 fts_read F ++GLIBC_2.27 fts_set F ++GLIBC_2.27 ftw F ++GLIBC_2.27 ftw64 F ++GLIBC_2.27 funlockfile F ++GLIBC_2.27 futimens F ++GLIBC_2.27 futimes F ++GLIBC_2.27 futimesat F ++GLIBC_2.27 fwide F ++GLIBC_2.27 fwprintf F ++GLIBC_2.27 fwrite F ++GLIBC_2.27 fwrite_unlocked F ++GLIBC_2.27 fwscanf F ++GLIBC_2.27 gai_strerror F ++GLIBC_2.27 gcvt F ++GLIBC_2.27 get_avphys_pages F ++GLIBC_2.27 get_current_dir_name F ++GLIBC_2.27 get_myaddress F ++GLIBC_2.27 get_nprocs F ++GLIBC_2.27 get_nprocs_conf F ++GLIBC_2.27 get_phys_pages F ++GLIBC_2.27 getaddrinfo F ++GLIBC_2.27 getaliasbyname F ++GLIBC_2.27 getaliasbyname_r F ++GLIBC_2.27 getaliasent F ++GLIBC_2.27 getaliasent_r F ++GLIBC_2.27 getauxval F ++GLIBC_2.27 getc F ++GLIBC_2.27 getc_unlocked F ++GLIBC_2.27 getchar F ++GLIBC_2.27 getchar_unlocked F ++GLIBC_2.27 getcontext F ++GLIBC_2.27 getcwd F ++GLIBC_2.27 getdate F ++GLIBC_2.27 getdate_err D 0x4 ++GLIBC_2.27 getdate_r F ++GLIBC_2.27 getdelim F ++GLIBC_2.27 getdirentries F ++GLIBC_2.27 getdirentries64 F ++GLIBC_2.27 getdomainname F ++GLIBC_2.27 getdtablesize F ++GLIBC_2.27 getegid F ++GLIBC_2.27 getentropy F ++GLIBC_2.27 getenv F ++GLIBC_2.27 geteuid F ++GLIBC_2.27 getfsent F ++GLIBC_2.27 getfsfile F ++GLIBC_2.27 getfsspec F ++GLIBC_2.27 getgid F ++GLIBC_2.27 getgrent F ++GLIBC_2.27 getgrent_r F ++GLIBC_2.27 getgrgid F ++GLIBC_2.27 getgrgid_r F ++GLIBC_2.27 getgrnam F ++GLIBC_2.27 getgrnam_r F ++GLIBC_2.27 getgrouplist F ++GLIBC_2.27 getgroups F ++GLIBC_2.27 gethostbyaddr F ++GLIBC_2.27 gethostbyaddr_r F ++GLIBC_2.27 gethostbyname F ++GLIBC_2.27 gethostbyname2 F ++GLIBC_2.27 gethostbyname2_r F ++GLIBC_2.27 gethostbyname_r F ++GLIBC_2.27 gethostent F ++GLIBC_2.27 gethostent_r F ++GLIBC_2.27 gethostid F ++GLIBC_2.27 gethostname F ++GLIBC_2.27 getifaddrs F ++GLIBC_2.27 getipv4sourcefilter F ++GLIBC_2.27 getitimer F ++GLIBC_2.27 getline F ++GLIBC_2.27 getloadavg F ++GLIBC_2.27 getlogin F ++GLIBC_2.27 getlogin_r F ++GLIBC_2.27 getmntent F ++GLIBC_2.27 getmntent_r F ++GLIBC_2.27 getmsg F ++GLIBC_2.27 getnameinfo F ++GLIBC_2.27 getnetbyaddr F ++GLIBC_2.27 getnetbyaddr_r F ++GLIBC_2.27 getnetbyname F ++GLIBC_2.27 getnetbyname_r F ++GLIBC_2.27 getnetent F ++GLIBC_2.27 getnetent_r F ++GLIBC_2.27 getnetgrent F ++GLIBC_2.27 getnetgrent_r F ++GLIBC_2.27 getnetname F ++GLIBC_2.27 getopt F ++GLIBC_2.27 getopt_long F ++GLIBC_2.27 getopt_long_only F ++GLIBC_2.27 getpagesize F ++GLIBC_2.27 getpass F ++GLIBC_2.27 getpeername F ++GLIBC_2.27 getpgid F ++GLIBC_2.27 getpgrp F ++GLIBC_2.27 getpid F ++GLIBC_2.27 getpmsg F ++GLIBC_2.27 getppid F ++GLIBC_2.27 getpriority F ++GLIBC_2.27 getprotobyname F ++GLIBC_2.27 getprotobyname_r F ++GLIBC_2.27 getprotobynumber F ++GLIBC_2.27 getprotobynumber_r F ++GLIBC_2.27 getprotoent F ++GLIBC_2.27 getprotoent_r F ++GLIBC_2.27 getpt F ++GLIBC_2.27 getpublickey F ++GLIBC_2.27 getpw F ++GLIBC_2.27 getpwent F ++GLIBC_2.27 getpwent_r F ++GLIBC_2.27 getpwnam F ++GLIBC_2.27 getpwnam_r F ++GLIBC_2.27 getpwuid F ++GLIBC_2.27 getpwuid_r F ++GLIBC_2.27 getrandom F ++GLIBC_2.27 getresgid F ++GLIBC_2.27 getresuid F ++GLIBC_2.27 getrlimit F ++GLIBC_2.27 getrlimit64 F ++GLIBC_2.27 getrpcbyname F ++GLIBC_2.27 getrpcbyname_r F ++GLIBC_2.27 getrpcbynumber F ++GLIBC_2.27 getrpcbynumber_r F ++GLIBC_2.27 getrpcent F ++GLIBC_2.27 getrpcent_r F ++GLIBC_2.27 getrpcport F ++GLIBC_2.27 getrusage F ++GLIBC_2.27 gets F ++GLIBC_2.27 getsecretkey F ++GLIBC_2.27 getservbyname F ++GLIBC_2.27 getservbyname_r F ++GLIBC_2.27 getservbyport F ++GLIBC_2.27 getservbyport_r F ++GLIBC_2.27 getservent F ++GLIBC_2.27 getservent_r F ++GLIBC_2.27 getsgent F ++GLIBC_2.27 getsgent_r F ++GLIBC_2.27 getsgnam F ++GLIBC_2.27 getsgnam_r F ++GLIBC_2.27 getsid F ++GLIBC_2.27 getsockname F ++GLIBC_2.27 getsockopt F ++GLIBC_2.27 getsourcefilter F ++GLIBC_2.27 getspent F ++GLIBC_2.27 getspent_r F ++GLIBC_2.27 getspnam F ++GLIBC_2.27 getspnam_r F ++GLIBC_2.27 getsubopt F ++GLIBC_2.27 gettext F ++GLIBC_2.27 gettimeofday F ++GLIBC_2.27 getttyent F ++GLIBC_2.27 getttynam F ++GLIBC_2.27 getuid F ++GLIBC_2.27 getusershell F ++GLIBC_2.27 getutent F ++GLIBC_2.27 getutent_r F ++GLIBC_2.27 getutid F ++GLIBC_2.27 getutid_r F ++GLIBC_2.27 getutline F ++GLIBC_2.27 getutline_r F ++GLIBC_2.27 getutmp F ++GLIBC_2.27 getutmpx F ++GLIBC_2.27 getutxent F ++GLIBC_2.27 getutxid F ++GLIBC_2.27 getutxline F ++GLIBC_2.27 getw F ++GLIBC_2.27 getwc F ++GLIBC_2.27 getwc_unlocked F ++GLIBC_2.27 getwchar F ++GLIBC_2.27 getwchar_unlocked F ++GLIBC_2.27 getwd F ++GLIBC_2.27 getxattr F ++GLIBC_2.27 glob F ++GLIBC_2.27 glob64 F ++GLIBC_2.27 glob_pattern_p F ++GLIBC_2.27 globfree F ++GLIBC_2.27 globfree64 F ++GLIBC_2.27 gmtime F ++GLIBC_2.27 gmtime_r F ++GLIBC_2.27 gnu_dev_major F ++GLIBC_2.27 gnu_dev_makedev F ++GLIBC_2.27 gnu_dev_minor F ++GLIBC_2.27 gnu_get_libc_release F ++GLIBC_2.27 gnu_get_libc_version F ++GLIBC_2.27 grantpt F ++GLIBC_2.27 group_member F ++GLIBC_2.27 gsignal F ++GLIBC_2.27 gtty F ++GLIBC_2.27 h_errlist D 0x28 ++GLIBC_2.27 h_nerr D 0x4 ++GLIBC_2.27 hasmntopt F ++GLIBC_2.27 hcreate F ++GLIBC_2.27 hcreate_r F ++GLIBC_2.27 hdestroy F ++GLIBC_2.27 hdestroy_r F ++GLIBC_2.27 herror F ++GLIBC_2.27 host2netname F ++GLIBC_2.27 hsearch F ++GLIBC_2.27 hsearch_r F ++GLIBC_2.27 hstrerror F ++GLIBC_2.27 htonl F ++GLIBC_2.27 htons F ++GLIBC_2.27 iconv F ++GLIBC_2.27 iconv_close F ++GLIBC_2.27 iconv_open F ++GLIBC_2.27 if_freenameindex F ++GLIBC_2.27 if_indextoname F ++GLIBC_2.27 if_nameindex F ++GLIBC_2.27 if_nametoindex F ++GLIBC_2.27 imaxabs F ++GLIBC_2.27 imaxdiv F ++GLIBC_2.27 in6addr_any D 0x10 ++GLIBC_2.27 in6addr_loopback D 0x10 ++GLIBC_2.27 index F ++GLIBC_2.27 inet6_opt_append F ++GLIBC_2.27 inet6_opt_find F ++GLIBC_2.27 inet6_opt_finish F ++GLIBC_2.27 inet6_opt_get_val F ++GLIBC_2.27 inet6_opt_init F ++GLIBC_2.27 inet6_opt_next F ++GLIBC_2.27 inet6_opt_set_val F ++GLIBC_2.27 inet6_option_alloc F ++GLIBC_2.27 inet6_option_append F ++GLIBC_2.27 inet6_option_find F ++GLIBC_2.27 inet6_option_init F ++GLIBC_2.27 inet6_option_next F ++GLIBC_2.27 inet6_option_space F ++GLIBC_2.27 inet6_rth_add F ++GLIBC_2.27 inet6_rth_getaddr F ++GLIBC_2.27 inet6_rth_init F ++GLIBC_2.27 inet6_rth_reverse F ++GLIBC_2.27 inet6_rth_segments F ++GLIBC_2.27 inet6_rth_space F ++GLIBC_2.27 inet_addr F ++GLIBC_2.27 inet_aton F ++GLIBC_2.27 inet_lnaof F ++GLIBC_2.27 inet_makeaddr F ++GLIBC_2.27 inet_netof F ++GLIBC_2.27 inet_network F ++GLIBC_2.27 inet_nsap_addr F ++GLIBC_2.27 inet_nsap_ntoa F ++GLIBC_2.27 inet_ntoa F ++GLIBC_2.27 inet_ntop F ++GLIBC_2.27 inet_pton F ++GLIBC_2.27 init_module F ++GLIBC_2.27 initgroups F ++GLIBC_2.27 initstate F ++GLIBC_2.27 initstate_r F ++GLIBC_2.27 innetgr F ++GLIBC_2.27 inotify_add_watch F ++GLIBC_2.27 inotify_init F ++GLIBC_2.27 inotify_init1 F ++GLIBC_2.27 inotify_rm_watch F ++GLIBC_2.27 insque F ++GLIBC_2.27 ioctl F ++GLIBC_2.27 iruserok F ++GLIBC_2.27 iruserok_af F ++GLIBC_2.27 isalnum F ++GLIBC_2.27 isalnum_l F ++GLIBC_2.27 isalpha F ++GLIBC_2.27 isalpha_l F ++GLIBC_2.27 isascii F ++GLIBC_2.27 isastream F ++GLIBC_2.27 isatty F ++GLIBC_2.27 isblank F ++GLIBC_2.27 isblank_l F ++GLIBC_2.27 iscntrl F ++GLIBC_2.27 iscntrl_l F ++GLIBC_2.27 isctype F ++GLIBC_2.27 isdigit F ++GLIBC_2.27 isdigit_l F ++GLIBC_2.27 isfdtype F ++GLIBC_2.27 isgraph F ++GLIBC_2.27 isgraph_l F ++GLIBC_2.27 isinf F ++GLIBC_2.27 isinff F ++GLIBC_2.27 isinfl F ++GLIBC_2.27 islower F ++GLIBC_2.27 islower_l F ++GLIBC_2.27 isnan F ++GLIBC_2.27 isnanf F ++GLIBC_2.27 isnanl F ++GLIBC_2.27 isprint F ++GLIBC_2.27 isprint_l F ++GLIBC_2.27 ispunct F ++GLIBC_2.27 ispunct_l F ++GLIBC_2.27 isspace F ++GLIBC_2.27 isspace_l F ++GLIBC_2.27 isupper F ++GLIBC_2.27 isupper_l F ++GLIBC_2.27 iswalnum F ++GLIBC_2.27 iswalnum_l F ++GLIBC_2.27 iswalpha F ++GLIBC_2.27 iswalpha_l F ++GLIBC_2.27 iswblank F ++GLIBC_2.27 iswblank_l F ++GLIBC_2.27 iswcntrl F ++GLIBC_2.27 iswcntrl_l F ++GLIBC_2.27 iswctype F ++GLIBC_2.27 iswctype_l F ++GLIBC_2.27 iswdigit F ++GLIBC_2.27 iswdigit_l F ++GLIBC_2.27 iswgraph F ++GLIBC_2.27 iswgraph_l F ++GLIBC_2.27 iswlower F ++GLIBC_2.27 iswlower_l F ++GLIBC_2.27 iswprint F ++GLIBC_2.27 iswprint_l F ++GLIBC_2.27 iswpunct F ++GLIBC_2.27 iswpunct_l F ++GLIBC_2.27 iswspace F ++GLIBC_2.27 iswspace_l F ++GLIBC_2.27 iswupper F ++GLIBC_2.27 iswupper_l F ++GLIBC_2.27 iswxdigit F ++GLIBC_2.27 iswxdigit_l F ++GLIBC_2.27 isxdigit F ++GLIBC_2.27 isxdigit_l F ++GLIBC_2.27 jrand48 F ++GLIBC_2.27 jrand48_r F ++GLIBC_2.27 key_decryptsession F ++GLIBC_2.27 key_decryptsession_pk F ++GLIBC_2.27 key_encryptsession F ++GLIBC_2.27 key_encryptsession_pk F ++GLIBC_2.27 key_gendes F ++GLIBC_2.27 key_get_conv F ++GLIBC_2.27 key_secretkey_is_set F ++GLIBC_2.27 key_setnet F ++GLIBC_2.27 key_setsecret F ++GLIBC_2.27 kill F ++GLIBC_2.27 killpg F ++GLIBC_2.27 klogctl F ++GLIBC_2.27 l64a F ++GLIBC_2.27 labs F ++GLIBC_2.27 lchmod F ++GLIBC_2.27 lchown F ++GLIBC_2.27 lckpwdf F ++GLIBC_2.27 lcong48 F ++GLIBC_2.27 lcong48_r F ++GLIBC_2.27 ldexp F ++GLIBC_2.27 ldexpf F ++GLIBC_2.27 ldexpl F ++GLIBC_2.27 ldiv F ++GLIBC_2.27 lfind F ++GLIBC_2.27 lgetxattr F ++GLIBC_2.27 link F ++GLIBC_2.27 linkat F ++GLIBC_2.27 listen F ++GLIBC_2.27 listxattr F ++GLIBC_2.27 llabs F ++GLIBC_2.27 lldiv F ++GLIBC_2.27 llistxattr F ++GLIBC_2.27 llseek F ++GLIBC_2.27 localeconv F ++GLIBC_2.27 localtime F ++GLIBC_2.27 localtime_r F ++GLIBC_2.27 lockf F ++GLIBC_2.27 lockf64 F ++GLIBC_2.27 longjmp F ++GLIBC_2.27 lrand48 F ++GLIBC_2.27 lrand48_r F ++GLIBC_2.27 lremovexattr F ++GLIBC_2.27 lsearch F ++GLIBC_2.27 lseek F ++GLIBC_2.27 lseek64 F ++GLIBC_2.27 lsetxattr F ++GLIBC_2.27 lutimes F ++GLIBC_2.27 madvise F ++GLIBC_2.27 makecontext F ++GLIBC_2.27 mallinfo F ++GLIBC_2.27 malloc F ++GLIBC_2.27 malloc_info F ++GLIBC_2.27 malloc_stats F ++GLIBC_2.27 malloc_trim F ++GLIBC_2.27 malloc_usable_size F ++GLIBC_2.27 mallopt F ++GLIBC_2.27 mallwatch D 0x8 ++GLIBC_2.27 mblen F ++GLIBC_2.27 mbrlen F ++GLIBC_2.27 mbrtoc16 F ++GLIBC_2.27 mbrtoc32 F ++GLIBC_2.27 mbrtowc F ++GLIBC_2.27 mbsinit F ++GLIBC_2.27 mbsnrtowcs F ++GLIBC_2.27 mbsrtowcs F ++GLIBC_2.27 mbstowcs F ++GLIBC_2.27 mbtowc F ++GLIBC_2.27 mcheck F ++GLIBC_2.27 mcheck_check_all F ++GLIBC_2.27 mcheck_pedantic F ++GLIBC_2.27 memalign F ++GLIBC_2.27 memccpy F ++GLIBC_2.27 memchr F ++GLIBC_2.27 memcmp F ++GLIBC_2.27 memcpy F ++GLIBC_2.27 memfd_create F ++GLIBC_2.27 memfrob F ++GLIBC_2.27 memmem F ++GLIBC_2.27 memmove F ++GLIBC_2.27 mempcpy F ++GLIBC_2.27 memrchr F ++GLIBC_2.27 memset F ++GLIBC_2.27 mincore F ++GLIBC_2.27 mkdir F ++GLIBC_2.27 mkdirat F ++GLIBC_2.27 mkdtemp F ++GLIBC_2.27 mkfifo F ++GLIBC_2.27 mkfifoat F ++GLIBC_2.27 mkostemp F ++GLIBC_2.27 mkostemp64 F ++GLIBC_2.27 mkostemps F ++GLIBC_2.27 mkostemps64 F ++GLIBC_2.27 mkstemp F ++GLIBC_2.27 mkstemp64 F ++GLIBC_2.27 mkstemps F ++GLIBC_2.27 mkstemps64 F ++GLIBC_2.27 mktemp F ++GLIBC_2.27 mktime F ++GLIBC_2.27 mlock F ++GLIBC_2.27 mlock2 F ++GLIBC_2.27 mlockall F ++GLIBC_2.27 mmap F ++GLIBC_2.27 mmap64 F ++GLIBC_2.27 modf F ++GLIBC_2.27 modff F ++GLIBC_2.27 modfl F ++GLIBC_2.27 moncontrol F ++GLIBC_2.27 monstartup F ++GLIBC_2.27 mount F ++GLIBC_2.27 mprobe F ++GLIBC_2.27 mprotect F ++GLIBC_2.27 mrand48 F ++GLIBC_2.27 mrand48_r F ++GLIBC_2.27 mremap F ++GLIBC_2.27 msgctl F ++GLIBC_2.27 msgget F ++GLIBC_2.27 msgrcv F ++GLIBC_2.27 msgsnd F ++GLIBC_2.27 msync F ++GLIBC_2.27 mtrace F ++GLIBC_2.27 munlock F ++GLIBC_2.27 munlockall F ++GLIBC_2.27 munmap F ++GLIBC_2.27 muntrace F ++GLIBC_2.27 name_to_handle_at F ++GLIBC_2.27 nanosleep F ++GLIBC_2.27 netname2host F ++GLIBC_2.27 netname2user F ++GLIBC_2.27 newlocale F ++GLIBC_2.27 nfsservctl F ++GLIBC_2.27 nftw F ++GLIBC_2.27 nftw64 F ++GLIBC_2.27 ngettext F ++GLIBC_2.27 nice F ++GLIBC_2.27 nl_langinfo F ++GLIBC_2.27 nl_langinfo_l F ++GLIBC_2.27 nrand48 F ++GLIBC_2.27 nrand48_r F ++GLIBC_2.27 ntohl F ++GLIBC_2.27 ntohs F ++GLIBC_2.27 ntp_adjtime F ++GLIBC_2.27 ntp_gettime F ++GLIBC_2.27 ntp_gettimex F ++GLIBC_2.27 obstack_alloc_failed_handler D 0x8 ++GLIBC_2.27 obstack_exit_failure D 0x4 ++GLIBC_2.27 obstack_free F ++GLIBC_2.27 obstack_printf F ++GLIBC_2.27 obstack_vprintf F ++GLIBC_2.27 on_exit F ++GLIBC_2.27 open F ++GLIBC_2.27 open64 F ++GLIBC_2.27 open_by_handle_at F ++GLIBC_2.27 open_memstream F ++GLIBC_2.27 open_wmemstream F ++GLIBC_2.27 openat F ++GLIBC_2.27 openat64 F ++GLIBC_2.27 opendir F ++GLIBC_2.27 openlog F ++GLIBC_2.27 optarg D 0x8 ++GLIBC_2.27 opterr D 0x4 ++GLIBC_2.27 optind D 0x4 ++GLIBC_2.27 optopt D 0x4 ++GLIBC_2.27 parse_printf_format F ++GLIBC_2.27 passwd2des F ++GLIBC_2.27 pathconf F ++GLIBC_2.27 pause F ++GLIBC_2.27 pclose F ++GLIBC_2.27 perror F ++GLIBC_2.27 personality F ++GLIBC_2.27 pipe F ++GLIBC_2.27 pipe2 F ++GLIBC_2.27 pivot_root F ++GLIBC_2.27 pkey_alloc F ++GLIBC_2.27 pkey_free F ++GLIBC_2.27 pkey_get F ++GLIBC_2.27 pkey_mprotect F ++GLIBC_2.27 pkey_set F ++GLIBC_2.27 pmap_getmaps F ++GLIBC_2.27 pmap_getport F ++GLIBC_2.27 pmap_rmtcall F ++GLIBC_2.27 pmap_set F ++GLIBC_2.27 pmap_unset F ++GLIBC_2.27 poll F ++GLIBC_2.27 popen F ++GLIBC_2.27 posix_fadvise F ++GLIBC_2.27 posix_fadvise64 F ++GLIBC_2.27 posix_fallocate F ++GLIBC_2.27 posix_fallocate64 F ++GLIBC_2.27 posix_madvise F ++GLIBC_2.27 posix_memalign F ++GLIBC_2.27 posix_openpt F ++GLIBC_2.27 posix_spawn F ++GLIBC_2.27 posix_spawn_file_actions_addclose F ++GLIBC_2.27 posix_spawn_file_actions_adddup2 F ++GLIBC_2.27 posix_spawn_file_actions_addopen F ++GLIBC_2.27 posix_spawn_file_actions_destroy F ++GLIBC_2.27 posix_spawn_file_actions_init F ++GLIBC_2.27 posix_spawnattr_destroy F ++GLIBC_2.27 posix_spawnattr_getflags F ++GLIBC_2.27 posix_spawnattr_getpgroup F ++GLIBC_2.27 posix_spawnattr_getschedparam F ++GLIBC_2.27 posix_spawnattr_getschedpolicy F ++GLIBC_2.27 posix_spawnattr_getsigdefault F ++GLIBC_2.27 posix_spawnattr_getsigmask F ++GLIBC_2.27 posix_spawnattr_init F ++GLIBC_2.27 posix_spawnattr_setflags F ++GLIBC_2.27 posix_spawnattr_setpgroup F ++GLIBC_2.27 posix_spawnattr_setschedparam F ++GLIBC_2.27 posix_spawnattr_setschedpolicy F ++GLIBC_2.27 posix_spawnattr_setsigdefault F ++GLIBC_2.27 posix_spawnattr_setsigmask F ++GLIBC_2.27 posix_spawnp F ++GLIBC_2.27 ppoll F ++GLIBC_2.27 prctl F ++GLIBC_2.27 pread F ++GLIBC_2.27 pread64 F ++GLIBC_2.27 preadv F ++GLIBC_2.27 preadv2 F ++GLIBC_2.27 preadv64 F ++GLIBC_2.27 preadv64v2 F ++GLIBC_2.27 printf F ++GLIBC_2.27 printf_size F ++GLIBC_2.27 printf_size_info F ++GLIBC_2.27 prlimit F ++GLIBC_2.27 prlimit64 F ++GLIBC_2.27 process_vm_readv F ++GLIBC_2.27 process_vm_writev F ++GLIBC_2.27 profil F ++GLIBC_2.27 program_invocation_name D 0x8 ++GLIBC_2.27 program_invocation_short_name D 0x8 ++GLIBC_2.27 pselect F ++GLIBC_2.27 psiginfo F ++GLIBC_2.27 psignal F ++GLIBC_2.27 pthread_attr_destroy F ++GLIBC_2.27 pthread_attr_getdetachstate F ++GLIBC_2.27 pthread_attr_getinheritsched F ++GLIBC_2.27 pthread_attr_getschedparam F ++GLIBC_2.27 pthread_attr_getschedpolicy F ++GLIBC_2.27 pthread_attr_getscope F ++GLIBC_2.27 pthread_attr_init F ++GLIBC_2.27 pthread_attr_setdetachstate F ++GLIBC_2.27 pthread_attr_setinheritsched F ++GLIBC_2.27 pthread_attr_setschedparam F ++GLIBC_2.27 pthread_attr_setschedpolicy F ++GLIBC_2.27 pthread_attr_setscope F ++GLIBC_2.27 pthread_cond_broadcast F ++GLIBC_2.27 pthread_cond_destroy F ++GLIBC_2.27 pthread_cond_init F ++GLIBC_2.27 pthread_cond_signal F ++GLIBC_2.27 pthread_cond_timedwait F ++GLIBC_2.27 pthread_cond_wait F ++GLIBC_2.27 pthread_condattr_destroy F ++GLIBC_2.27 pthread_condattr_init F ++GLIBC_2.27 pthread_equal F ++GLIBC_2.27 pthread_exit F ++GLIBC_2.27 pthread_getschedparam F ++GLIBC_2.27 pthread_mutex_destroy F ++GLIBC_2.27 pthread_mutex_init F ++GLIBC_2.27 pthread_mutex_lock F ++GLIBC_2.27 pthread_mutex_unlock F ++GLIBC_2.27 pthread_self F ++GLIBC_2.27 pthread_setcancelstate F ++GLIBC_2.27 pthread_setcanceltype F ++GLIBC_2.27 pthread_setschedparam F ++GLIBC_2.27 ptrace F ++GLIBC_2.27 ptsname F ++GLIBC_2.27 ptsname_r F ++GLIBC_2.27 putc F ++GLIBC_2.27 putc_unlocked F ++GLIBC_2.27 putchar F ++GLIBC_2.27 putchar_unlocked F ++GLIBC_2.27 putenv F ++GLIBC_2.27 putgrent F ++GLIBC_2.27 putmsg F ++GLIBC_2.27 putpmsg F ++GLIBC_2.27 putpwent F ++GLIBC_2.27 puts F ++GLIBC_2.27 putsgent F ++GLIBC_2.27 putspent F ++GLIBC_2.27 pututline F ++GLIBC_2.27 pututxline F ++GLIBC_2.27 putw F ++GLIBC_2.27 putwc F ++GLIBC_2.27 putwc_unlocked F ++GLIBC_2.27 putwchar F ++GLIBC_2.27 putwchar_unlocked F ++GLIBC_2.27 pvalloc F ++GLIBC_2.27 pwrite F ++GLIBC_2.27 pwrite64 F ++GLIBC_2.27 pwritev F ++GLIBC_2.27 pwritev2 F ++GLIBC_2.27 pwritev64 F ++GLIBC_2.27 pwritev64v2 F ++GLIBC_2.27 qecvt F ++GLIBC_2.27 qecvt_r F ++GLIBC_2.27 qfcvt F ++GLIBC_2.27 qfcvt_r F ++GLIBC_2.27 qgcvt F ++GLIBC_2.27 qsort F ++GLIBC_2.27 qsort_r F ++GLIBC_2.27 quick_exit F ++GLIBC_2.27 quotactl F ++GLIBC_2.27 raise F ++GLIBC_2.27 rand F ++GLIBC_2.27 rand_r F ++GLIBC_2.27 random F ++GLIBC_2.27 random_r F ++GLIBC_2.27 rawmemchr F ++GLIBC_2.27 rcmd F ++GLIBC_2.27 rcmd_af F ++GLIBC_2.27 re_comp F ++GLIBC_2.27 re_compile_fastmap F ++GLIBC_2.27 re_compile_pattern F ++GLIBC_2.27 re_exec F ++GLIBC_2.27 re_match F ++GLIBC_2.27 re_match_2 F ++GLIBC_2.27 re_search F ++GLIBC_2.27 re_search_2 F ++GLIBC_2.27 re_set_registers F ++GLIBC_2.27 re_set_syntax F ++GLIBC_2.27 re_syntax_options D 0x8 ++GLIBC_2.27 read F ++GLIBC_2.27 readahead F ++GLIBC_2.27 readdir F ++GLIBC_2.27 readdir64 F ++GLIBC_2.27 readdir64_r F ++GLIBC_2.27 readdir_r F ++GLIBC_2.27 readlink F ++GLIBC_2.27 readlinkat F ++GLIBC_2.27 readv F ++GLIBC_2.27 realloc F ++GLIBC_2.27 reallocarray F ++GLIBC_2.27 realpath F ++GLIBC_2.27 reboot F ++GLIBC_2.27 recv F ++GLIBC_2.27 recvfrom F ++GLIBC_2.27 recvmmsg F ++GLIBC_2.27 recvmsg F ++GLIBC_2.27 regcomp F ++GLIBC_2.27 regerror F ++GLIBC_2.27 regexec F ++GLIBC_2.27 regfree F ++GLIBC_2.27 register_printf_function F ++GLIBC_2.27 register_printf_modifier F ++GLIBC_2.27 register_printf_specifier F ++GLIBC_2.27 register_printf_type F ++GLIBC_2.27 registerrpc F ++GLIBC_2.27 remap_file_pages F ++GLIBC_2.27 remove F ++GLIBC_2.27 removexattr F ++GLIBC_2.27 remque F ++GLIBC_2.27 rename F ++GLIBC_2.27 renameat F ++GLIBC_2.27 revoke F ++GLIBC_2.27 rewind F ++GLIBC_2.27 rewinddir F ++GLIBC_2.27 rexec F ++GLIBC_2.27 rexec_af F ++GLIBC_2.27 rexecoptions D 0x4 ++GLIBC_2.27 rindex F ++GLIBC_2.27 rmdir F ++GLIBC_2.27 rpc_createerr D 0x20 ++GLIBC_2.27 rpmatch F ++GLIBC_2.27 rresvport F ++GLIBC_2.27 rresvport_af F ++GLIBC_2.27 rtime F ++GLIBC_2.27 ruserok F ++GLIBC_2.27 ruserok_af F ++GLIBC_2.27 ruserpass F ++GLIBC_2.27 sbrk F ++GLIBC_2.27 scalbn F ++GLIBC_2.27 scalbnf F ++GLIBC_2.27 scalbnl F ++GLIBC_2.27 scandir F ++GLIBC_2.27 scandir64 F ++GLIBC_2.27 scandirat F ++GLIBC_2.27 scandirat64 F ++GLIBC_2.27 scanf F ++GLIBC_2.27 sched_get_priority_max F ++GLIBC_2.27 sched_get_priority_min F ++GLIBC_2.27 sched_getaffinity F ++GLIBC_2.27 sched_getcpu F ++GLIBC_2.27 sched_getparam F ++GLIBC_2.27 sched_getscheduler F ++GLIBC_2.27 sched_rr_get_interval F ++GLIBC_2.27 sched_setaffinity F ++GLIBC_2.27 sched_setparam F ++GLIBC_2.27 sched_setscheduler F ++GLIBC_2.27 sched_yield F ++GLIBC_2.27 secure_getenv F ++GLIBC_2.27 seed48 F ++GLIBC_2.27 seed48_r F ++GLIBC_2.27 seekdir F ++GLIBC_2.27 select F ++GLIBC_2.27 semctl F ++GLIBC_2.27 semget F ++GLIBC_2.27 semop F ++GLIBC_2.27 semtimedop F ++GLIBC_2.27 send F ++GLIBC_2.27 sendfile F ++GLIBC_2.27 sendfile64 F ++GLIBC_2.27 sendmmsg F ++GLIBC_2.27 sendmsg F ++GLIBC_2.27 sendto F ++GLIBC_2.27 setaliasent F ++GLIBC_2.27 setbuf F ++GLIBC_2.27 setbuffer F ++GLIBC_2.27 setcontext F ++GLIBC_2.27 setdomainname F ++GLIBC_2.27 setegid F ++GLIBC_2.27 setenv F ++GLIBC_2.27 seteuid F ++GLIBC_2.27 setfsent F ++GLIBC_2.27 setfsgid F ++GLIBC_2.27 setfsuid F ++GLIBC_2.27 setgid F ++GLIBC_2.27 setgrent F ++GLIBC_2.27 setgroups F ++GLIBC_2.27 sethostent F ++GLIBC_2.27 sethostid F ++GLIBC_2.27 sethostname F ++GLIBC_2.27 setipv4sourcefilter F ++GLIBC_2.27 setitimer F ++GLIBC_2.27 setjmp F ++GLIBC_2.27 setlinebuf F ++GLIBC_2.27 setlocale F ++GLIBC_2.27 setlogin F ++GLIBC_2.27 setlogmask F ++GLIBC_2.27 setmntent F ++GLIBC_2.27 setnetent F ++GLIBC_2.27 setnetgrent F ++GLIBC_2.27 setns F ++GLIBC_2.27 setpgid F ++GLIBC_2.27 setpgrp F ++GLIBC_2.27 setpriority F ++GLIBC_2.27 setprotoent F ++GLIBC_2.27 setpwent F ++GLIBC_2.27 setregid F ++GLIBC_2.27 setresgid F ++GLIBC_2.27 setresuid F ++GLIBC_2.27 setreuid F ++GLIBC_2.27 setrlimit F ++GLIBC_2.27 setrlimit64 F ++GLIBC_2.27 setrpcent F ++GLIBC_2.27 setservent F ++GLIBC_2.27 setsgent F ++GLIBC_2.27 setsid F ++GLIBC_2.27 setsockopt F ++GLIBC_2.27 setsourcefilter F ++GLIBC_2.27 setspent F ++GLIBC_2.27 setstate F ++GLIBC_2.27 setstate_r F ++GLIBC_2.27 settimeofday F ++GLIBC_2.27 setttyent F ++GLIBC_2.27 setuid F ++GLIBC_2.27 setusershell F ++GLIBC_2.27 setutent F ++GLIBC_2.27 setutxent F ++GLIBC_2.27 setvbuf F ++GLIBC_2.27 setxattr F ++GLIBC_2.27 sgetsgent F ++GLIBC_2.27 sgetsgent_r F ++GLIBC_2.27 sgetspent F ++GLIBC_2.27 sgetspent_r F ++GLIBC_2.27 shmat F ++GLIBC_2.27 shmctl F ++GLIBC_2.27 shmdt F ++GLIBC_2.27 shmget F ++GLIBC_2.27 shutdown F ++GLIBC_2.27 sigaction F ++GLIBC_2.27 sigaddset F ++GLIBC_2.27 sigaltstack F ++GLIBC_2.27 sigandset F ++GLIBC_2.27 sigblock F ++GLIBC_2.27 sigdelset F ++GLIBC_2.27 sigemptyset F ++GLIBC_2.27 sigfillset F ++GLIBC_2.27 siggetmask F ++GLIBC_2.27 sighold F ++GLIBC_2.27 sigignore F ++GLIBC_2.27 siginterrupt F ++GLIBC_2.27 sigisemptyset F ++GLIBC_2.27 sigismember F ++GLIBC_2.27 siglongjmp F ++GLIBC_2.27 signal F ++GLIBC_2.27 signalfd F ++GLIBC_2.27 sigorset F ++GLIBC_2.27 sigpause F ++GLIBC_2.27 sigpending F ++GLIBC_2.27 sigprocmask F ++GLIBC_2.27 sigqueue F ++GLIBC_2.27 sigrelse F ++GLIBC_2.27 sigreturn F ++GLIBC_2.27 sigset F ++GLIBC_2.27 sigsetmask F ++GLIBC_2.27 sigstack F ++GLIBC_2.27 sigsuspend F ++GLIBC_2.27 sigtimedwait F ++GLIBC_2.27 sigwait F ++GLIBC_2.27 sigwaitinfo F ++GLIBC_2.27 sleep F ++GLIBC_2.27 snprintf F ++GLIBC_2.27 sockatmark F ++GLIBC_2.27 socket F ++GLIBC_2.27 socketpair F ++GLIBC_2.27 splice F ++GLIBC_2.27 sprintf F ++GLIBC_2.27 sprofil F ++GLIBC_2.27 srand F ++GLIBC_2.27 srand48 F ++GLIBC_2.27 srand48_r F ++GLIBC_2.27 srandom F ++GLIBC_2.27 srandom_r F ++GLIBC_2.27 sscanf F ++GLIBC_2.27 ssignal F ++GLIBC_2.27 sstk F ++GLIBC_2.27 statfs F ++GLIBC_2.27 statfs64 F ++GLIBC_2.27 statvfs F ++GLIBC_2.27 statvfs64 F ++GLIBC_2.27 stderr D 0x8 ++GLIBC_2.27 stdin D 0x8 ++GLIBC_2.27 stdout D 0x8 ++GLIBC_2.27 stime F ++GLIBC_2.27 stpcpy F ++GLIBC_2.27 stpncpy F ++GLIBC_2.27 strcasecmp F ++GLIBC_2.27 strcasecmp_l F ++GLIBC_2.27 strcasestr F ++GLIBC_2.27 strcat F ++GLIBC_2.27 strchr F ++GLIBC_2.27 strchrnul F ++GLIBC_2.27 strcmp F ++GLIBC_2.27 strcoll F ++GLIBC_2.27 strcoll_l F ++GLIBC_2.27 strcpy F ++GLIBC_2.27 strcspn F ++GLIBC_2.27 strdup F ++GLIBC_2.27 strerror F ++GLIBC_2.27 strerror_l F ++GLIBC_2.27 strerror_r F ++GLIBC_2.27 strfmon F ++GLIBC_2.27 strfmon_l F ++GLIBC_2.27 strfromd F ++GLIBC_2.27 strfromf F ++GLIBC_2.27 strfromf128 F ++GLIBC_2.27 strfromf32 F ++GLIBC_2.27 strfromf32x F ++GLIBC_2.27 strfromf64 F ++GLIBC_2.27 strfromf64x F ++GLIBC_2.27 strfroml F ++GLIBC_2.27 strfry F ++GLIBC_2.27 strftime F ++GLIBC_2.27 strftime_l F ++GLIBC_2.27 strlen F ++GLIBC_2.27 strncasecmp F ++GLIBC_2.27 strncasecmp_l F ++GLIBC_2.27 strncat F ++GLIBC_2.27 strncmp F ++GLIBC_2.27 strncpy F ++GLIBC_2.27 strndup F ++GLIBC_2.27 strnlen F ++GLIBC_2.27 strpbrk F ++GLIBC_2.27 strptime F ++GLIBC_2.27 strptime_l F ++GLIBC_2.27 strrchr F ++GLIBC_2.27 strsep F ++GLIBC_2.27 strsignal F ++GLIBC_2.27 strspn F ++GLIBC_2.27 strstr F ++GLIBC_2.27 strtod F ++GLIBC_2.27 strtod_l F ++GLIBC_2.27 strtof F ++GLIBC_2.27 strtof128 F ++GLIBC_2.27 strtof128_l F ++GLIBC_2.27 strtof32 F ++GLIBC_2.27 strtof32_l F ++GLIBC_2.27 strtof32x F ++GLIBC_2.27 strtof32x_l F ++GLIBC_2.27 strtof64 F ++GLIBC_2.27 strtof64_l F ++GLIBC_2.27 strtof64x F ++GLIBC_2.27 strtof64x_l F ++GLIBC_2.27 strtof_l F ++GLIBC_2.27 strtoimax F ++GLIBC_2.27 strtok F ++GLIBC_2.27 strtok_r F ++GLIBC_2.27 strtol F ++GLIBC_2.27 strtol_l F ++GLIBC_2.27 strtold F ++GLIBC_2.27 strtold_l F ++GLIBC_2.27 strtoll F ++GLIBC_2.27 strtoll_l F ++GLIBC_2.27 strtoq F ++GLIBC_2.27 strtoul F ++GLIBC_2.27 strtoul_l F ++GLIBC_2.27 strtoull F ++GLIBC_2.27 strtoull_l F ++GLIBC_2.27 strtoumax F ++GLIBC_2.27 strtouq F ++GLIBC_2.27 strverscmp F ++GLIBC_2.27 strxfrm F ++GLIBC_2.27 strxfrm_l F ++GLIBC_2.27 stty F ++GLIBC_2.27 svc_exit F ++GLIBC_2.27 svc_fdset D 0x80 ++GLIBC_2.27 svc_getreq F ++GLIBC_2.27 svc_getreq_common F ++GLIBC_2.27 svc_getreq_poll F ++GLIBC_2.27 svc_getreqset F ++GLIBC_2.27 svc_max_pollfd D 0x4 ++GLIBC_2.27 svc_pollfd D 0x8 ++GLIBC_2.27 svc_register F ++GLIBC_2.27 svc_run F ++GLIBC_2.27 svc_sendreply F ++GLIBC_2.27 svc_unregister F ++GLIBC_2.27 svcauthdes_stats D 0x18 ++GLIBC_2.27 svcerr_auth F ++GLIBC_2.27 svcerr_decode F ++GLIBC_2.27 svcerr_noproc F ++GLIBC_2.27 svcerr_noprog F ++GLIBC_2.27 svcerr_progvers F ++GLIBC_2.27 svcerr_systemerr F ++GLIBC_2.27 svcerr_weakauth F ++GLIBC_2.27 svcfd_create F ++GLIBC_2.27 svcraw_create F ++GLIBC_2.27 svctcp_create F ++GLIBC_2.27 svcudp_bufcreate F ++GLIBC_2.27 svcudp_create F ++GLIBC_2.27 svcudp_enablecache F ++GLIBC_2.27 svcunix_create F ++GLIBC_2.27 svcunixfd_create F ++GLIBC_2.27 swab F ++GLIBC_2.27 swapcontext F ++GLIBC_2.27 swapoff F ++GLIBC_2.27 swapon F ++GLIBC_2.27 swprintf F ++GLIBC_2.27 swscanf F ++GLIBC_2.27 symlink F ++GLIBC_2.27 symlinkat F ++GLIBC_2.27 sync F ++GLIBC_2.27 sync_file_range F ++GLIBC_2.27 syncfs F ++GLIBC_2.27 sys_errlist D 0x2370 ++GLIBC_2.27 sys_nerr D 0x4 ++GLIBC_2.27 sys_sigabbrev D 0x400 ++GLIBC_2.27 sys_siglist D 0x400 ++GLIBC_2.27 syscall F ++GLIBC_2.27 sysconf F ++GLIBC_2.27 sysctl F ++GLIBC_2.27 sysinfo F ++GLIBC_2.27 syslog F ++GLIBC_2.27 system F ++GLIBC_2.27 sysv_signal F ++GLIBC_2.27 tcdrain F ++GLIBC_2.27 tcflow F ++GLIBC_2.27 tcflush F ++GLIBC_2.27 tcgetattr F ++GLIBC_2.27 tcgetpgrp F ++GLIBC_2.27 tcgetsid F ++GLIBC_2.27 tcsendbreak F ++GLIBC_2.27 tcsetattr F ++GLIBC_2.27 tcsetpgrp F ++GLIBC_2.27 tdelete F ++GLIBC_2.27 tdestroy F ++GLIBC_2.27 tee F ++GLIBC_2.27 telldir F ++GLIBC_2.27 tempnam F ++GLIBC_2.27 textdomain F ++GLIBC_2.27 tfind F ++GLIBC_2.27 time F ++GLIBC_2.27 timegm F ++GLIBC_2.27 timelocal F ++GLIBC_2.27 timerfd_create F ++GLIBC_2.27 timerfd_gettime F ++GLIBC_2.27 timerfd_settime F ++GLIBC_2.27 times F ++GLIBC_2.27 timespec_get F ++GLIBC_2.27 timezone D 0x8 ++GLIBC_2.27 tmpfile F ++GLIBC_2.27 tmpfile64 F ++GLIBC_2.27 tmpnam F ++GLIBC_2.27 tmpnam_r F ++GLIBC_2.27 toascii F ++GLIBC_2.27 tolower F ++GLIBC_2.27 tolower_l F ++GLIBC_2.27 toupper F ++GLIBC_2.27 toupper_l F ++GLIBC_2.27 towctrans F ++GLIBC_2.27 towctrans_l F ++GLIBC_2.27 towlower F ++GLIBC_2.27 towlower_l F ++GLIBC_2.27 towupper F ++GLIBC_2.27 towupper_l F ++GLIBC_2.27 tr_break F ++GLIBC_2.27 truncate F ++GLIBC_2.27 truncate64 F ++GLIBC_2.27 tsearch F ++GLIBC_2.27 ttyname F ++GLIBC_2.27 ttyname_r F ++GLIBC_2.27 ttyslot F ++GLIBC_2.27 twalk F ++GLIBC_2.27 tzname D 0x10 ++GLIBC_2.27 tzset F ++GLIBC_2.27 ualarm F ++GLIBC_2.27 ulckpwdf F ++GLIBC_2.27 ulimit F ++GLIBC_2.27 umask F ++GLIBC_2.27 umount F ++GLIBC_2.27 umount2 F ++GLIBC_2.27 uname F ++GLIBC_2.27 ungetc F ++GLIBC_2.27 ungetwc F ++GLIBC_2.27 unlink F ++GLIBC_2.27 unlinkat F ++GLIBC_2.27 unlockpt F ++GLIBC_2.27 unsetenv F ++GLIBC_2.27 unshare F ++GLIBC_2.27 updwtmp F ++GLIBC_2.27 updwtmpx F ++GLIBC_2.27 uselocale F ++GLIBC_2.27 user2netname F ++GLIBC_2.27 usleep F ++GLIBC_2.27 ustat F ++GLIBC_2.27 utime F ++GLIBC_2.27 utimensat F ++GLIBC_2.27 utimes F ++GLIBC_2.27 utmpname F ++GLIBC_2.27 utmpxname F ++GLIBC_2.27 valloc F ++GLIBC_2.27 vasprintf F ++GLIBC_2.27 vdprintf F ++GLIBC_2.27 verr F ++GLIBC_2.27 verrx F ++GLIBC_2.27 versionsort F ++GLIBC_2.27 versionsort64 F ++GLIBC_2.27 vfork F ++GLIBC_2.27 vfprintf F ++GLIBC_2.27 vfscanf F ++GLIBC_2.27 vfwprintf F ++GLIBC_2.27 vfwscanf F ++GLIBC_2.27 vhangup F ++GLIBC_2.27 vlimit F ++GLIBC_2.27 vmsplice F ++GLIBC_2.27 vprintf F ++GLIBC_2.27 vscanf F ++GLIBC_2.27 vsnprintf F ++GLIBC_2.27 vsprintf F ++GLIBC_2.27 vsscanf F ++GLIBC_2.27 vswprintf F ++GLIBC_2.27 vswscanf F ++GLIBC_2.27 vsyslog F ++GLIBC_2.27 vtimes F ++GLIBC_2.27 vwarn F ++GLIBC_2.27 vwarnx F ++GLIBC_2.27 vwprintf F ++GLIBC_2.27 vwscanf F ++GLIBC_2.27 wait F ++GLIBC_2.27 wait3 F ++GLIBC_2.27 wait4 F ++GLIBC_2.27 waitid F ++GLIBC_2.27 waitpid F ++GLIBC_2.27 warn F ++GLIBC_2.27 warnx F ++GLIBC_2.27 wcpcpy F ++GLIBC_2.27 wcpncpy F ++GLIBC_2.27 wcrtomb F ++GLIBC_2.27 wcscasecmp F ++GLIBC_2.27 wcscasecmp_l F ++GLIBC_2.27 wcscat F ++GLIBC_2.27 wcschr F ++GLIBC_2.27 wcschrnul F ++GLIBC_2.27 wcscmp F ++GLIBC_2.27 wcscoll F ++GLIBC_2.27 wcscoll_l F ++GLIBC_2.27 wcscpy F ++GLIBC_2.27 wcscspn F ++GLIBC_2.27 wcsdup F ++GLIBC_2.27 wcsftime F ++GLIBC_2.27 wcsftime_l F ++GLIBC_2.27 wcslen F ++GLIBC_2.27 wcsncasecmp F ++GLIBC_2.27 wcsncasecmp_l F ++GLIBC_2.27 wcsncat F ++GLIBC_2.27 wcsncmp F ++GLIBC_2.27 wcsncpy F ++GLIBC_2.27 wcsnlen F ++GLIBC_2.27 wcsnrtombs F ++GLIBC_2.27 wcspbrk F ++GLIBC_2.27 wcsrchr F ++GLIBC_2.27 wcsrtombs F ++GLIBC_2.27 wcsspn F ++GLIBC_2.27 wcsstr F ++GLIBC_2.27 wcstod F ++GLIBC_2.27 wcstod_l F ++GLIBC_2.27 wcstof F ++GLIBC_2.27 wcstof128 F ++GLIBC_2.27 wcstof128_l F ++GLIBC_2.27 wcstof32 F ++GLIBC_2.27 wcstof32_l F ++GLIBC_2.27 wcstof32x F ++GLIBC_2.27 wcstof32x_l F ++GLIBC_2.27 wcstof64 F ++GLIBC_2.27 wcstof64_l F ++GLIBC_2.27 wcstof64x F ++GLIBC_2.27 wcstof64x_l F ++GLIBC_2.27 wcstof_l F ++GLIBC_2.27 wcstoimax F ++GLIBC_2.27 wcstok F ++GLIBC_2.27 wcstol F ++GLIBC_2.27 wcstol_l F ++GLIBC_2.27 wcstold F ++GLIBC_2.27 wcstold_l F ++GLIBC_2.27 wcstoll F ++GLIBC_2.27 wcstoll_l F ++GLIBC_2.27 wcstombs F ++GLIBC_2.27 wcstoq F ++GLIBC_2.27 wcstoul F ++GLIBC_2.27 wcstoul_l F ++GLIBC_2.27 wcstoull F ++GLIBC_2.27 wcstoull_l F ++GLIBC_2.27 wcstoumax F ++GLIBC_2.27 wcstouq F ++GLIBC_2.27 wcswcs F ++GLIBC_2.27 wcswidth F ++GLIBC_2.27 wcsxfrm F ++GLIBC_2.27 wcsxfrm_l F ++GLIBC_2.27 wctob F ++GLIBC_2.27 wctomb F ++GLIBC_2.27 wctrans F ++GLIBC_2.27 wctrans_l F ++GLIBC_2.27 wctype F ++GLIBC_2.27 wctype_l F ++GLIBC_2.27 wcwidth F ++GLIBC_2.27 wmemchr F ++GLIBC_2.27 wmemcmp F ++GLIBC_2.27 wmemcpy F ++GLIBC_2.27 wmemmove F ++GLIBC_2.27 wmempcpy F ++GLIBC_2.27 wmemset F ++GLIBC_2.27 wordexp F ++GLIBC_2.27 wordfree F ++GLIBC_2.27 wprintf F ++GLIBC_2.27 write F ++GLIBC_2.27 writev F ++GLIBC_2.27 wscanf F ++GLIBC_2.27 xdecrypt F ++GLIBC_2.27 xdr_accepted_reply F ++GLIBC_2.27 xdr_array F ++GLIBC_2.27 xdr_authdes_cred F ++GLIBC_2.27 xdr_authdes_verf F ++GLIBC_2.27 xdr_authunix_parms F ++GLIBC_2.27 xdr_bool F ++GLIBC_2.27 xdr_bytes F ++GLIBC_2.27 xdr_callhdr F ++GLIBC_2.27 xdr_callmsg F ++GLIBC_2.27 xdr_char F ++GLIBC_2.27 xdr_cryptkeyarg F ++GLIBC_2.27 xdr_cryptkeyarg2 F ++GLIBC_2.27 xdr_cryptkeyres F ++GLIBC_2.27 xdr_des_block F ++GLIBC_2.27 xdr_double F ++GLIBC_2.27 xdr_enum F ++GLIBC_2.27 xdr_float F ++GLIBC_2.27 xdr_free F ++GLIBC_2.27 xdr_getcredres F ++GLIBC_2.27 xdr_hyper F ++GLIBC_2.27 xdr_int F ++GLIBC_2.27 xdr_int16_t F ++GLIBC_2.27 xdr_int32_t F ++GLIBC_2.27 xdr_int64_t F ++GLIBC_2.27 xdr_int8_t F ++GLIBC_2.27 xdr_key_netstarg F ++GLIBC_2.27 xdr_key_netstres F ++GLIBC_2.27 xdr_keybuf F ++GLIBC_2.27 xdr_keystatus F ++GLIBC_2.27 xdr_long F ++GLIBC_2.27 xdr_longlong_t F ++GLIBC_2.27 xdr_netnamestr F ++GLIBC_2.27 xdr_netobj F ++GLIBC_2.27 xdr_opaque F ++GLIBC_2.27 xdr_opaque_auth F ++GLIBC_2.27 xdr_pmap F ++GLIBC_2.27 xdr_pmaplist F ++GLIBC_2.27 xdr_pointer F ++GLIBC_2.27 xdr_quad_t F ++GLIBC_2.27 xdr_reference F ++GLIBC_2.27 xdr_rejected_reply F ++GLIBC_2.27 xdr_replymsg F ++GLIBC_2.27 xdr_rmtcall_args F ++GLIBC_2.27 xdr_rmtcallres F ++GLIBC_2.27 xdr_short F ++GLIBC_2.27 xdr_sizeof F ++GLIBC_2.27 xdr_string F ++GLIBC_2.27 xdr_u_char F ++GLIBC_2.27 xdr_u_hyper F ++GLIBC_2.27 xdr_u_int F ++GLIBC_2.27 xdr_u_long F ++GLIBC_2.27 xdr_u_longlong_t F ++GLIBC_2.27 xdr_u_quad_t F ++GLIBC_2.27 xdr_u_short F ++GLIBC_2.27 xdr_uint16_t F ++GLIBC_2.27 xdr_uint32_t F ++GLIBC_2.27 xdr_uint64_t F ++GLIBC_2.27 xdr_uint8_t F ++GLIBC_2.27 xdr_union F ++GLIBC_2.27 xdr_unixcred F ++GLIBC_2.27 xdr_vector F ++GLIBC_2.27 xdr_void F ++GLIBC_2.27 xdr_wrapstring F ++GLIBC_2.27 xdrmem_create F ++GLIBC_2.27 xdrrec_create F ++GLIBC_2.27 xdrrec_endofrecord F ++GLIBC_2.27 xdrrec_eof F ++GLIBC_2.27 xdrrec_skiprecord F ++GLIBC_2.27 xdrstdio_create F ++GLIBC_2.27 xencrypt F ++GLIBC_2.27 xprt_register F ++GLIBC_2.27 xprt_unregister F ++GLIBC_2.28 fcntl64 F ++GLIBC_2.28 renameat2 F ++GLIBC_2.28 statx F ++GLIBC_2.28 thrd_current F ++GLIBC_2.28 thrd_equal F ++GLIBC_2.28 thrd_sleep F ++GLIBC_2.28 thrd_yield F +diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libcrypt.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libcrypt.abilist +new file mode 100644 +index 00000000..9484dca7 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libcrypt.abilist +@@ -0,0 +1,7 @@ ++GLIBC_2.27 crypt F ++GLIBC_2.27 crypt_r F ++GLIBC_2.27 encrypt F ++GLIBC_2.27 encrypt_r F ++GLIBC_2.27 fcrypt F ++GLIBC_2.27 setkey F ++GLIBC_2.27 setkey_r F +diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libdl.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libdl.abilist +new file mode 100644 +index 00000000..16adcae5 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libdl.abilist +@@ -0,0 +1,9 @@ ++GLIBC_2.27 dladdr F ++GLIBC_2.27 dladdr1 F ++GLIBC_2.27 dlclose F ++GLIBC_2.27 dlerror F ++GLIBC_2.27 dlinfo F ++GLIBC_2.27 dlmopen F ++GLIBC_2.27 dlopen F ++GLIBC_2.27 dlsym F ++GLIBC_2.27 dlvsym F +diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libm.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libm.abilist +new file mode 100644 +index 00000000..361fce20 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libm.abilist +@@ -0,0 +1,1021 @@ ++GLIBC_2.27 __acos_finite F ++GLIBC_2.27 __acosf_finite F ++GLIBC_2.27 __acosh_finite F ++GLIBC_2.27 __acoshf_finite F ++GLIBC_2.27 __acoshl_finite F ++GLIBC_2.27 __acosl_finite F ++GLIBC_2.27 __asin_finite F ++GLIBC_2.27 __asinf_finite F ++GLIBC_2.27 __asinl_finite F ++GLIBC_2.27 __atan2_finite F ++GLIBC_2.27 __atan2f_finite F ++GLIBC_2.27 __atan2l_finite F ++GLIBC_2.27 __atanh_finite F ++GLIBC_2.27 __atanhf_finite F ++GLIBC_2.27 __atanhl_finite F ++GLIBC_2.27 __clog10 F ++GLIBC_2.27 __clog10f F ++GLIBC_2.27 __clog10l F ++GLIBC_2.27 __cosh_finite F ++GLIBC_2.27 __coshf_finite F ++GLIBC_2.27 __coshl_finite F ++GLIBC_2.27 __exp10_finite F ++GLIBC_2.27 __exp10f_finite F ++GLIBC_2.27 __exp10l_finite F ++GLIBC_2.27 __exp2_finite F ++GLIBC_2.27 __exp2f_finite F ++GLIBC_2.27 __exp2l_finite F ++GLIBC_2.27 __exp_finite F ++GLIBC_2.27 __expf_finite F ++GLIBC_2.27 __expl_finite F ++GLIBC_2.27 __finite F ++GLIBC_2.27 __finitef F ++GLIBC_2.27 __finitel F ++GLIBC_2.27 __fmod_finite F ++GLIBC_2.27 __fmodf_finite F ++GLIBC_2.27 __fmodl_finite F ++GLIBC_2.27 __fpclassify F ++GLIBC_2.27 __fpclassifyf F ++GLIBC_2.27 __fpclassifyl F ++GLIBC_2.27 __gamma_r_finite F ++GLIBC_2.27 __gammaf_r_finite F ++GLIBC_2.27 __gammal_r_finite F ++GLIBC_2.27 __hypot_finite F ++GLIBC_2.27 __hypotf_finite F ++GLIBC_2.27 __hypotl_finite F ++GLIBC_2.27 __iseqsig F ++GLIBC_2.27 __iseqsigf F ++GLIBC_2.27 __iseqsigl F ++GLIBC_2.27 __issignaling F ++GLIBC_2.27 __issignalingf F ++GLIBC_2.27 __issignalingl F ++GLIBC_2.27 __j0_finite F ++GLIBC_2.27 __j0f_finite F ++GLIBC_2.27 __j0l_finite F ++GLIBC_2.27 __j1_finite F ++GLIBC_2.27 __j1f_finite F ++GLIBC_2.27 __j1l_finite F ++GLIBC_2.27 __jn_finite F ++GLIBC_2.27 __jnf_finite F ++GLIBC_2.27 __jnl_finite F ++GLIBC_2.27 __lgamma_r_finite F ++GLIBC_2.27 __lgammaf_r_finite F ++GLIBC_2.27 __lgammal_r_finite F ++GLIBC_2.27 __log10_finite F ++GLIBC_2.27 __log10f_finite F ++GLIBC_2.27 __log10l_finite F ++GLIBC_2.27 __log2_finite F ++GLIBC_2.27 __log2f_finite F ++GLIBC_2.27 __log2l_finite F ++GLIBC_2.27 __log_finite F ++GLIBC_2.27 __logf_finite F ++GLIBC_2.27 __logl_finite F ++GLIBC_2.27 __pow_finite F ++GLIBC_2.27 __powf_finite F ++GLIBC_2.27 __powl_finite F ++GLIBC_2.27 __remainder_finite F ++GLIBC_2.27 __remainderf_finite F ++GLIBC_2.27 __remainderl_finite F ++GLIBC_2.27 __scalb_finite F ++GLIBC_2.27 __scalbf_finite F ++GLIBC_2.27 __scalbl_finite F ++GLIBC_2.27 __signbit F ++GLIBC_2.27 __signbitf F ++GLIBC_2.27 __signbitl F ++GLIBC_2.27 __signgam D 0x4 ++GLIBC_2.27 __sinh_finite F ++GLIBC_2.27 __sinhf_finite F ++GLIBC_2.27 __sinhl_finite F ++GLIBC_2.27 __sqrt_finite F ++GLIBC_2.27 __sqrtf_finite F ++GLIBC_2.27 __sqrtl_finite F ++GLIBC_2.27 __y0_finite F ++GLIBC_2.27 __y0f_finite F ++GLIBC_2.27 __y0l_finite F ++GLIBC_2.27 __y1_finite F ++GLIBC_2.27 __y1f_finite F ++GLIBC_2.27 __y1l_finite F ++GLIBC_2.27 __yn_finite F ++GLIBC_2.27 __ynf_finite F ++GLIBC_2.27 __ynl_finite F ++GLIBC_2.27 acos F ++GLIBC_2.27 acosf F ++GLIBC_2.27 acosf128 F ++GLIBC_2.27 acosf32 F ++GLIBC_2.27 acosf32x F ++GLIBC_2.27 acosf64 F ++GLIBC_2.27 acosf64x F ++GLIBC_2.27 acosh F ++GLIBC_2.27 acoshf F ++GLIBC_2.27 acoshf128 F ++GLIBC_2.27 acoshf32 F ++GLIBC_2.27 acoshf32x F ++GLIBC_2.27 acoshf64 F ++GLIBC_2.27 acoshf64x F ++GLIBC_2.27 acoshl F ++GLIBC_2.27 acosl F ++GLIBC_2.27 asin F ++GLIBC_2.27 asinf F ++GLIBC_2.27 asinf128 F ++GLIBC_2.27 asinf32 F ++GLIBC_2.27 asinf32x F ++GLIBC_2.27 asinf64 F ++GLIBC_2.27 asinf64x F ++GLIBC_2.27 asinh F ++GLIBC_2.27 asinhf F ++GLIBC_2.27 asinhf128 F ++GLIBC_2.27 asinhf32 F ++GLIBC_2.27 asinhf32x F ++GLIBC_2.27 asinhf64 F ++GLIBC_2.27 asinhf64x F ++GLIBC_2.27 asinhl F ++GLIBC_2.27 asinl F ++GLIBC_2.27 atan F ++GLIBC_2.27 atan2 F ++GLIBC_2.27 atan2f F ++GLIBC_2.27 atan2f128 F ++GLIBC_2.27 atan2f32 F ++GLIBC_2.27 atan2f32x F ++GLIBC_2.27 atan2f64 F ++GLIBC_2.27 atan2f64x F ++GLIBC_2.27 atan2l F ++GLIBC_2.27 atanf F ++GLIBC_2.27 atanf128 F ++GLIBC_2.27 atanf32 F ++GLIBC_2.27 atanf32x F ++GLIBC_2.27 atanf64 F ++GLIBC_2.27 atanf64x F ++GLIBC_2.27 atanh F ++GLIBC_2.27 atanhf F ++GLIBC_2.27 atanhf128 F ++GLIBC_2.27 atanhf32 F ++GLIBC_2.27 atanhf32x F ++GLIBC_2.27 atanhf64 F ++GLIBC_2.27 atanhf64x F ++GLIBC_2.27 atanhl F ++GLIBC_2.27 atanl F ++GLIBC_2.27 cabs F ++GLIBC_2.27 cabsf F ++GLIBC_2.27 cabsf128 F ++GLIBC_2.27 cabsf32 F ++GLIBC_2.27 cabsf32x F ++GLIBC_2.27 cabsf64 F ++GLIBC_2.27 cabsf64x F ++GLIBC_2.27 cabsl F ++GLIBC_2.27 cacos F ++GLIBC_2.27 cacosf F ++GLIBC_2.27 cacosf128 F ++GLIBC_2.27 cacosf32 F ++GLIBC_2.27 cacosf32x F ++GLIBC_2.27 cacosf64 F ++GLIBC_2.27 cacosf64x F ++GLIBC_2.27 cacosh F ++GLIBC_2.27 cacoshf F ++GLIBC_2.27 cacoshf128 F ++GLIBC_2.27 cacoshf32 F ++GLIBC_2.27 cacoshf32x F ++GLIBC_2.27 cacoshf64 F ++GLIBC_2.27 cacoshf64x F ++GLIBC_2.27 cacoshl F ++GLIBC_2.27 cacosl F ++GLIBC_2.27 canonicalize F ++GLIBC_2.27 canonicalizef F ++GLIBC_2.27 canonicalizef128 F ++GLIBC_2.27 canonicalizef32 F ++GLIBC_2.27 canonicalizef32x F ++GLIBC_2.27 canonicalizef64 F ++GLIBC_2.27 canonicalizef64x F ++GLIBC_2.27 canonicalizel F ++GLIBC_2.27 carg F ++GLIBC_2.27 cargf F ++GLIBC_2.27 cargf128 F ++GLIBC_2.27 cargf32 F ++GLIBC_2.27 cargf32x F ++GLIBC_2.27 cargf64 F ++GLIBC_2.27 cargf64x F ++GLIBC_2.27 cargl F ++GLIBC_2.27 casin F ++GLIBC_2.27 casinf F ++GLIBC_2.27 casinf128 F ++GLIBC_2.27 casinf32 F ++GLIBC_2.27 casinf32x F ++GLIBC_2.27 casinf64 F ++GLIBC_2.27 casinf64x F ++GLIBC_2.27 casinh F ++GLIBC_2.27 casinhf F ++GLIBC_2.27 casinhf128 F ++GLIBC_2.27 casinhf32 F ++GLIBC_2.27 casinhf32x F ++GLIBC_2.27 casinhf64 F ++GLIBC_2.27 casinhf64x F ++GLIBC_2.27 casinhl F ++GLIBC_2.27 casinl F ++GLIBC_2.27 catan F ++GLIBC_2.27 catanf F ++GLIBC_2.27 catanf128 F ++GLIBC_2.27 catanf32 F ++GLIBC_2.27 catanf32x F ++GLIBC_2.27 catanf64 F ++GLIBC_2.27 catanf64x F ++GLIBC_2.27 catanh F ++GLIBC_2.27 catanhf F ++GLIBC_2.27 catanhf128 F ++GLIBC_2.27 catanhf32 F ++GLIBC_2.27 catanhf32x F ++GLIBC_2.27 catanhf64 F ++GLIBC_2.27 catanhf64x F ++GLIBC_2.27 catanhl F ++GLIBC_2.27 catanl F ++GLIBC_2.27 cbrt F ++GLIBC_2.27 cbrtf F ++GLIBC_2.27 cbrtf128 F ++GLIBC_2.27 cbrtf32 F ++GLIBC_2.27 cbrtf32x F ++GLIBC_2.27 cbrtf64 F ++GLIBC_2.27 cbrtf64x F ++GLIBC_2.27 cbrtl F ++GLIBC_2.27 ccos F ++GLIBC_2.27 ccosf F ++GLIBC_2.27 ccosf128 F ++GLIBC_2.27 ccosf32 F ++GLIBC_2.27 ccosf32x F ++GLIBC_2.27 ccosf64 F ++GLIBC_2.27 ccosf64x F ++GLIBC_2.27 ccosh F ++GLIBC_2.27 ccoshf F ++GLIBC_2.27 ccoshf128 F ++GLIBC_2.27 ccoshf32 F ++GLIBC_2.27 ccoshf32x F ++GLIBC_2.27 ccoshf64 F ++GLIBC_2.27 ccoshf64x F ++GLIBC_2.27 ccoshl F ++GLIBC_2.27 ccosl F ++GLIBC_2.27 ceil F ++GLIBC_2.27 ceilf F ++GLIBC_2.27 ceilf128 F ++GLIBC_2.27 ceilf32 F ++GLIBC_2.27 ceilf32x F ++GLIBC_2.27 ceilf64 F ++GLIBC_2.27 ceilf64x F ++GLIBC_2.27 ceill F ++GLIBC_2.27 cexp F ++GLIBC_2.27 cexpf F ++GLIBC_2.27 cexpf128 F ++GLIBC_2.27 cexpf32 F ++GLIBC_2.27 cexpf32x F ++GLIBC_2.27 cexpf64 F ++GLIBC_2.27 cexpf64x F ++GLIBC_2.27 cexpl F ++GLIBC_2.27 cimag F ++GLIBC_2.27 cimagf F ++GLIBC_2.27 cimagf128 F ++GLIBC_2.27 cimagf32 F ++GLIBC_2.27 cimagf32x F ++GLIBC_2.27 cimagf64 F ++GLIBC_2.27 cimagf64x F ++GLIBC_2.27 cimagl F ++GLIBC_2.27 clog F ++GLIBC_2.27 clog10 F ++GLIBC_2.27 clog10f F ++GLIBC_2.27 clog10f128 F ++GLIBC_2.27 clog10f32 F ++GLIBC_2.27 clog10f32x F ++GLIBC_2.27 clog10f64 F ++GLIBC_2.27 clog10f64x F ++GLIBC_2.27 clog10l F ++GLIBC_2.27 clogf F ++GLIBC_2.27 clogf128 F ++GLIBC_2.27 clogf32 F ++GLIBC_2.27 clogf32x F ++GLIBC_2.27 clogf64 F ++GLIBC_2.27 clogf64x F ++GLIBC_2.27 clogl F ++GLIBC_2.27 conj F ++GLIBC_2.27 conjf F ++GLIBC_2.27 conjf128 F ++GLIBC_2.27 conjf32 F ++GLIBC_2.27 conjf32x F ++GLIBC_2.27 conjf64 F ++GLIBC_2.27 conjf64x F ++GLIBC_2.27 conjl F ++GLIBC_2.27 copysign F ++GLIBC_2.27 copysignf F ++GLIBC_2.27 copysignf128 F ++GLIBC_2.27 copysignf32 F ++GLIBC_2.27 copysignf32x F ++GLIBC_2.27 copysignf64 F ++GLIBC_2.27 copysignf64x F ++GLIBC_2.27 copysignl F ++GLIBC_2.27 cos F ++GLIBC_2.27 cosf F ++GLIBC_2.27 cosf128 F ++GLIBC_2.27 cosf32 F ++GLIBC_2.27 cosf32x F ++GLIBC_2.27 cosf64 F ++GLIBC_2.27 cosf64x F ++GLIBC_2.27 cosh F ++GLIBC_2.27 coshf F ++GLIBC_2.27 coshf128 F ++GLIBC_2.27 coshf32 F ++GLIBC_2.27 coshf32x F ++GLIBC_2.27 coshf64 F ++GLIBC_2.27 coshf64x F ++GLIBC_2.27 coshl F ++GLIBC_2.27 cosl F ++GLIBC_2.27 cpow F ++GLIBC_2.27 cpowf F ++GLIBC_2.27 cpowf128 F ++GLIBC_2.27 cpowf32 F ++GLIBC_2.27 cpowf32x F ++GLIBC_2.27 cpowf64 F ++GLIBC_2.27 cpowf64x F ++GLIBC_2.27 cpowl F ++GLIBC_2.27 cproj F ++GLIBC_2.27 cprojf F ++GLIBC_2.27 cprojf128 F ++GLIBC_2.27 cprojf32 F ++GLIBC_2.27 cprojf32x F ++GLIBC_2.27 cprojf64 F ++GLIBC_2.27 cprojf64x F ++GLIBC_2.27 cprojl F ++GLIBC_2.27 creal F ++GLIBC_2.27 crealf F ++GLIBC_2.27 crealf128 F ++GLIBC_2.27 crealf32 F ++GLIBC_2.27 crealf32x F ++GLIBC_2.27 crealf64 F ++GLIBC_2.27 crealf64x F ++GLIBC_2.27 creall F ++GLIBC_2.27 csin F ++GLIBC_2.27 csinf F ++GLIBC_2.27 csinf128 F ++GLIBC_2.27 csinf32 F ++GLIBC_2.27 csinf32x F ++GLIBC_2.27 csinf64 F ++GLIBC_2.27 csinf64x F ++GLIBC_2.27 csinh F ++GLIBC_2.27 csinhf F ++GLIBC_2.27 csinhf128 F ++GLIBC_2.27 csinhf32 F ++GLIBC_2.27 csinhf32x F ++GLIBC_2.27 csinhf64 F ++GLIBC_2.27 csinhf64x F ++GLIBC_2.27 csinhl F ++GLIBC_2.27 csinl F ++GLIBC_2.27 csqrt F ++GLIBC_2.27 csqrtf F ++GLIBC_2.27 csqrtf128 F ++GLIBC_2.27 csqrtf32 F ++GLIBC_2.27 csqrtf32x F ++GLIBC_2.27 csqrtf64 F ++GLIBC_2.27 csqrtf64x F ++GLIBC_2.27 csqrtl F ++GLIBC_2.27 ctan F ++GLIBC_2.27 ctanf F ++GLIBC_2.27 ctanf128 F ++GLIBC_2.27 ctanf32 F ++GLIBC_2.27 ctanf32x F ++GLIBC_2.27 ctanf64 F ++GLIBC_2.27 ctanf64x F ++GLIBC_2.27 ctanh F ++GLIBC_2.27 ctanhf F ++GLIBC_2.27 ctanhf128 F ++GLIBC_2.27 ctanhf32 F ++GLIBC_2.27 ctanhf32x F ++GLIBC_2.27 ctanhf64 F ++GLIBC_2.27 ctanhf64x F ++GLIBC_2.27 ctanhl F ++GLIBC_2.27 ctanl F ++GLIBC_2.27 drem F ++GLIBC_2.27 dremf F ++GLIBC_2.27 dreml F ++GLIBC_2.27 erf F ++GLIBC_2.27 erfc F ++GLIBC_2.27 erfcf F ++GLIBC_2.27 erfcf128 F ++GLIBC_2.27 erfcf32 F ++GLIBC_2.27 erfcf32x F ++GLIBC_2.27 erfcf64 F ++GLIBC_2.27 erfcf64x F ++GLIBC_2.27 erfcl F ++GLIBC_2.27 erff F ++GLIBC_2.27 erff128 F ++GLIBC_2.27 erff32 F ++GLIBC_2.27 erff32x F ++GLIBC_2.27 erff64 F ++GLIBC_2.27 erff64x F ++GLIBC_2.27 erfl F ++GLIBC_2.27 exp F ++GLIBC_2.27 exp10 F ++GLIBC_2.27 exp10f F ++GLIBC_2.27 exp10f128 F ++GLIBC_2.27 exp10f32 F ++GLIBC_2.27 exp10f32x F ++GLIBC_2.27 exp10f64 F ++GLIBC_2.27 exp10f64x F ++GLIBC_2.27 exp10l F ++GLIBC_2.27 exp2 F ++GLIBC_2.27 exp2f F ++GLIBC_2.27 exp2f128 F ++GLIBC_2.27 exp2f32 F ++GLIBC_2.27 exp2f32x F ++GLIBC_2.27 exp2f64 F ++GLIBC_2.27 exp2f64x F ++GLIBC_2.27 exp2l F ++GLIBC_2.27 expf F ++GLIBC_2.27 expf128 F ++GLIBC_2.27 expf32 F ++GLIBC_2.27 expf32x F ++GLIBC_2.27 expf64 F ++GLIBC_2.27 expf64x F ++GLIBC_2.27 expl F ++GLIBC_2.27 expm1 F ++GLIBC_2.27 expm1f F ++GLIBC_2.27 expm1f128 F ++GLIBC_2.27 expm1f32 F ++GLIBC_2.27 expm1f32x F ++GLIBC_2.27 expm1f64 F ++GLIBC_2.27 expm1f64x F ++GLIBC_2.27 expm1l F ++GLIBC_2.27 fabs F ++GLIBC_2.27 fabsf F ++GLIBC_2.27 fabsf128 F ++GLIBC_2.27 fabsf32 F ++GLIBC_2.27 fabsf32x F ++GLIBC_2.27 fabsf64 F ++GLIBC_2.27 fabsf64x F ++GLIBC_2.27 fabsl F ++GLIBC_2.27 fdim F ++GLIBC_2.27 fdimf F ++GLIBC_2.27 fdimf128 F ++GLIBC_2.27 fdimf32 F ++GLIBC_2.27 fdimf32x F ++GLIBC_2.27 fdimf64 F ++GLIBC_2.27 fdimf64x F ++GLIBC_2.27 fdiml F ++GLIBC_2.27 feclearexcept F ++GLIBC_2.27 fedisableexcept F ++GLIBC_2.27 feenableexcept F ++GLIBC_2.27 fegetenv F ++GLIBC_2.27 fegetexcept F ++GLIBC_2.27 fegetexceptflag F ++GLIBC_2.27 fegetmode F ++GLIBC_2.27 fegetround F ++GLIBC_2.27 feholdexcept F ++GLIBC_2.27 feraiseexcept F ++GLIBC_2.27 fesetenv F ++GLIBC_2.27 fesetexcept F ++GLIBC_2.27 fesetexceptflag F ++GLIBC_2.27 fesetmode F ++GLIBC_2.27 fesetround F ++GLIBC_2.27 fetestexcept F ++GLIBC_2.27 fetestexceptflag F ++GLIBC_2.27 feupdateenv F ++GLIBC_2.27 finite F ++GLIBC_2.27 finitef F ++GLIBC_2.27 finitel F ++GLIBC_2.27 floor F ++GLIBC_2.27 floorf F ++GLIBC_2.27 floorf128 F ++GLIBC_2.27 floorf32 F ++GLIBC_2.27 floorf32x F ++GLIBC_2.27 floorf64 F ++GLIBC_2.27 floorf64x F ++GLIBC_2.27 floorl F ++GLIBC_2.27 fma F ++GLIBC_2.27 fmaf F ++GLIBC_2.27 fmaf128 F ++GLIBC_2.27 fmaf32 F ++GLIBC_2.27 fmaf32x F ++GLIBC_2.27 fmaf64 F ++GLIBC_2.27 fmaf64x F ++GLIBC_2.27 fmal F ++GLIBC_2.27 fmax F ++GLIBC_2.27 fmaxf F ++GLIBC_2.27 fmaxf128 F ++GLIBC_2.27 fmaxf32 F ++GLIBC_2.27 fmaxf32x F ++GLIBC_2.27 fmaxf64 F ++GLIBC_2.27 fmaxf64x F ++GLIBC_2.27 fmaxl F ++GLIBC_2.27 fmaxmag F ++GLIBC_2.27 fmaxmagf F ++GLIBC_2.27 fmaxmagf128 F ++GLIBC_2.27 fmaxmagf32 F ++GLIBC_2.27 fmaxmagf32x F ++GLIBC_2.27 fmaxmagf64 F ++GLIBC_2.27 fmaxmagf64x F ++GLIBC_2.27 fmaxmagl F ++GLIBC_2.27 fmin F ++GLIBC_2.27 fminf F ++GLIBC_2.27 fminf128 F ++GLIBC_2.27 fminf32 F ++GLIBC_2.27 fminf32x F ++GLIBC_2.27 fminf64 F ++GLIBC_2.27 fminf64x F ++GLIBC_2.27 fminl F ++GLIBC_2.27 fminmag F ++GLIBC_2.27 fminmagf F ++GLIBC_2.27 fminmagf128 F ++GLIBC_2.27 fminmagf32 F ++GLIBC_2.27 fminmagf32x F ++GLIBC_2.27 fminmagf64 F ++GLIBC_2.27 fminmagf64x F ++GLIBC_2.27 fminmagl F ++GLIBC_2.27 fmod F ++GLIBC_2.27 fmodf F ++GLIBC_2.27 fmodf128 F ++GLIBC_2.27 fmodf32 F ++GLIBC_2.27 fmodf32x F ++GLIBC_2.27 fmodf64 F ++GLIBC_2.27 fmodf64x F ++GLIBC_2.27 fmodl F ++GLIBC_2.27 frexp F ++GLIBC_2.27 frexpf F ++GLIBC_2.27 frexpf128 F ++GLIBC_2.27 frexpf32 F ++GLIBC_2.27 frexpf32x F ++GLIBC_2.27 frexpf64 F ++GLIBC_2.27 frexpf64x F ++GLIBC_2.27 frexpl F ++GLIBC_2.27 fromfp F ++GLIBC_2.27 fromfpf F ++GLIBC_2.27 fromfpf128 F ++GLIBC_2.27 fromfpf32 F ++GLIBC_2.27 fromfpf32x F ++GLIBC_2.27 fromfpf64 F ++GLIBC_2.27 fromfpf64x F ++GLIBC_2.27 fromfpl F ++GLIBC_2.27 fromfpx F ++GLIBC_2.27 fromfpxf F ++GLIBC_2.27 fromfpxf128 F ++GLIBC_2.27 fromfpxf32 F ++GLIBC_2.27 fromfpxf32x F ++GLIBC_2.27 fromfpxf64 F ++GLIBC_2.27 fromfpxf64x F ++GLIBC_2.27 fromfpxl F ++GLIBC_2.27 gamma F ++GLIBC_2.27 gammaf F ++GLIBC_2.27 gammal F ++GLIBC_2.27 getpayload F ++GLIBC_2.27 getpayloadf F ++GLIBC_2.27 getpayloadf128 F ++GLIBC_2.27 getpayloadf32 F ++GLIBC_2.27 getpayloadf32x F ++GLIBC_2.27 getpayloadf64 F ++GLIBC_2.27 getpayloadf64x F ++GLIBC_2.27 getpayloadl F ++GLIBC_2.27 hypot F ++GLIBC_2.27 hypotf F ++GLIBC_2.27 hypotf128 F ++GLIBC_2.27 hypotf32 F ++GLIBC_2.27 hypotf32x F ++GLIBC_2.27 hypotf64 F ++GLIBC_2.27 hypotf64x F ++GLIBC_2.27 hypotl F ++GLIBC_2.27 ilogb F ++GLIBC_2.27 ilogbf F ++GLIBC_2.27 ilogbf128 F ++GLIBC_2.27 ilogbf32 F ++GLIBC_2.27 ilogbf32x F ++GLIBC_2.27 ilogbf64 F ++GLIBC_2.27 ilogbf64x F ++GLIBC_2.27 ilogbl F ++GLIBC_2.27 j0 F ++GLIBC_2.27 j0f F ++GLIBC_2.27 j0f128 F ++GLIBC_2.27 j0f32 F ++GLIBC_2.27 j0f32x F ++GLIBC_2.27 j0f64 F ++GLIBC_2.27 j0f64x F ++GLIBC_2.27 j0l F ++GLIBC_2.27 j1 F ++GLIBC_2.27 j1f F ++GLIBC_2.27 j1f128 F ++GLIBC_2.27 j1f32 F ++GLIBC_2.27 j1f32x F ++GLIBC_2.27 j1f64 F ++GLIBC_2.27 j1f64x F ++GLIBC_2.27 j1l F ++GLIBC_2.27 jn F ++GLIBC_2.27 jnf F ++GLIBC_2.27 jnf128 F ++GLIBC_2.27 jnf32 F ++GLIBC_2.27 jnf32x F ++GLIBC_2.27 jnf64 F ++GLIBC_2.27 jnf64x F ++GLIBC_2.27 jnl F ++GLIBC_2.27 ldexp F ++GLIBC_2.27 ldexpf F ++GLIBC_2.27 ldexpf128 F ++GLIBC_2.27 ldexpf32 F ++GLIBC_2.27 ldexpf32x F ++GLIBC_2.27 ldexpf64 F ++GLIBC_2.27 ldexpf64x F ++GLIBC_2.27 ldexpl F ++GLIBC_2.27 lgamma F ++GLIBC_2.27 lgamma_r F ++GLIBC_2.27 lgammaf F ++GLIBC_2.27 lgammaf128 F ++GLIBC_2.27 lgammaf128_r F ++GLIBC_2.27 lgammaf32 F ++GLIBC_2.27 lgammaf32_r F ++GLIBC_2.27 lgammaf32x F ++GLIBC_2.27 lgammaf32x_r F ++GLIBC_2.27 lgammaf64 F ++GLIBC_2.27 lgammaf64_r F ++GLIBC_2.27 lgammaf64x F ++GLIBC_2.27 lgammaf64x_r F ++GLIBC_2.27 lgammaf_r F ++GLIBC_2.27 lgammal F ++GLIBC_2.27 lgammal_r F ++GLIBC_2.27 llogb F ++GLIBC_2.27 llogbf F ++GLIBC_2.27 llogbf128 F ++GLIBC_2.27 llogbf32 F ++GLIBC_2.27 llogbf32x F ++GLIBC_2.27 llogbf64 F ++GLIBC_2.27 llogbf64x F ++GLIBC_2.27 llogbl F ++GLIBC_2.27 llrint F ++GLIBC_2.27 llrintf F ++GLIBC_2.27 llrintf128 F ++GLIBC_2.27 llrintf32 F ++GLIBC_2.27 llrintf32x F ++GLIBC_2.27 llrintf64 F ++GLIBC_2.27 llrintf64x F ++GLIBC_2.27 llrintl F ++GLIBC_2.27 llround F ++GLIBC_2.27 llroundf F ++GLIBC_2.27 llroundf128 F ++GLIBC_2.27 llroundf32 F ++GLIBC_2.27 llroundf32x F ++GLIBC_2.27 llroundf64 F ++GLIBC_2.27 llroundf64x F ++GLIBC_2.27 llroundl F ++GLIBC_2.27 log F ++GLIBC_2.27 log10 F ++GLIBC_2.27 log10f F ++GLIBC_2.27 log10f128 F ++GLIBC_2.27 log10f32 F ++GLIBC_2.27 log10f32x F ++GLIBC_2.27 log10f64 F ++GLIBC_2.27 log10f64x F ++GLIBC_2.27 log10l F ++GLIBC_2.27 log1p F ++GLIBC_2.27 log1pf F ++GLIBC_2.27 log1pf128 F ++GLIBC_2.27 log1pf32 F ++GLIBC_2.27 log1pf32x F ++GLIBC_2.27 log1pf64 F ++GLIBC_2.27 log1pf64x F ++GLIBC_2.27 log1pl F ++GLIBC_2.27 log2 F ++GLIBC_2.27 log2f F ++GLIBC_2.27 log2f128 F ++GLIBC_2.27 log2f32 F ++GLIBC_2.27 log2f32x F ++GLIBC_2.27 log2f64 F ++GLIBC_2.27 log2f64x F ++GLIBC_2.27 log2l F ++GLIBC_2.27 logb F ++GLIBC_2.27 logbf F ++GLIBC_2.27 logbf128 F ++GLIBC_2.27 logbf32 F ++GLIBC_2.27 logbf32x F ++GLIBC_2.27 logbf64 F ++GLIBC_2.27 logbf64x F ++GLIBC_2.27 logbl F ++GLIBC_2.27 logf F ++GLIBC_2.27 logf128 F ++GLIBC_2.27 logf32 F ++GLIBC_2.27 logf32x F ++GLIBC_2.27 logf64 F ++GLIBC_2.27 logf64x F ++GLIBC_2.27 logl F ++GLIBC_2.27 lrint F ++GLIBC_2.27 lrintf F ++GLIBC_2.27 lrintf128 F ++GLIBC_2.27 lrintf32 F ++GLIBC_2.27 lrintf32x F ++GLIBC_2.27 lrintf64 F ++GLIBC_2.27 lrintf64x F ++GLIBC_2.27 lrintl F ++GLIBC_2.27 lround F ++GLIBC_2.27 lroundf F ++GLIBC_2.27 lroundf128 F ++GLIBC_2.27 lroundf32 F ++GLIBC_2.27 lroundf32x F ++GLIBC_2.27 lroundf64 F ++GLIBC_2.27 lroundf64x F ++GLIBC_2.27 lroundl F ++GLIBC_2.27 modf F ++GLIBC_2.27 modff F ++GLIBC_2.27 modff128 F ++GLIBC_2.27 modff32 F ++GLIBC_2.27 modff32x F ++GLIBC_2.27 modff64 F ++GLIBC_2.27 modff64x F ++GLIBC_2.27 modfl F ++GLIBC_2.27 nan F ++GLIBC_2.27 nanf F ++GLIBC_2.27 nanf128 F ++GLIBC_2.27 nanf32 F ++GLIBC_2.27 nanf32x F ++GLIBC_2.27 nanf64 F ++GLIBC_2.27 nanf64x F ++GLIBC_2.27 nanl F ++GLIBC_2.27 nearbyint F ++GLIBC_2.27 nearbyintf F ++GLIBC_2.27 nearbyintf128 F ++GLIBC_2.27 nearbyintf32 F ++GLIBC_2.27 nearbyintf32x F ++GLIBC_2.27 nearbyintf64 F ++GLIBC_2.27 nearbyintf64x F ++GLIBC_2.27 nearbyintl F ++GLIBC_2.27 nextafter F ++GLIBC_2.27 nextafterf F ++GLIBC_2.27 nextafterf128 F ++GLIBC_2.27 nextafterf32 F ++GLIBC_2.27 nextafterf32x F ++GLIBC_2.27 nextafterf64 F ++GLIBC_2.27 nextafterf64x F ++GLIBC_2.27 nextafterl F ++GLIBC_2.27 nextdown F ++GLIBC_2.27 nextdownf F ++GLIBC_2.27 nextdownf128 F ++GLIBC_2.27 nextdownf32 F ++GLIBC_2.27 nextdownf32x F ++GLIBC_2.27 nextdownf64 F ++GLIBC_2.27 nextdownf64x F ++GLIBC_2.27 nextdownl F ++GLIBC_2.27 nexttoward F ++GLIBC_2.27 nexttowardf F ++GLIBC_2.27 nexttowardl F ++GLIBC_2.27 nextup F ++GLIBC_2.27 nextupf F ++GLIBC_2.27 nextupf128 F ++GLIBC_2.27 nextupf32 F ++GLIBC_2.27 nextupf32x F ++GLIBC_2.27 nextupf64 F ++GLIBC_2.27 nextupf64x F ++GLIBC_2.27 nextupl F ++GLIBC_2.27 pow F ++GLIBC_2.27 powf F ++GLIBC_2.27 powf128 F ++GLIBC_2.27 powf32 F ++GLIBC_2.27 powf32x F ++GLIBC_2.27 powf64 F ++GLIBC_2.27 powf64x F ++GLIBC_2.27 powl F ++GLIBC_2.27 remainder F ++GLIBC_2.27 remainderf F ++GLIBC_2.27 remainderf128 F ++GLIBC_2.27 remainderf32 F ++GLIBC_2.27 remainderf32x F ++GLIBC_2.27 remainderf64 F ++GLIBC_2.27 remainderf64x F ++GLIBC_2.27 remainderl F ++GLIBC_2.27 remquo F ++GLIBC_2.27 remquof F ++GLIBC_2.27 remquof128 F ++GLIBC_2.27 remquof32 F ++GLIBC_2.27 remquof32x F ++GLIBC_2.27 remquof64 F ++GLIBC_2.27 remquof64x F ++GLIBC_2.27 remquol F ++GLIBC_2.27 rint F ++GLIBC_2.27 rintf F ++GLIBC_2.27 rintf128 F ++GLIBC_2.27 rintf32 F ++GLIBC_2.27 rintf32x F ++GLIBC_2.27 rintf64 F ++GLIBC_2.27 rintf64x F ++GLIBC_2.27 rintl F ++GLIBC_2.27 round F ++GLIBC_2.27 roundeven F ++GLIBC_2.27 roundevenf F ++GLIBC_2.27 roundevenf128 F ++GLIBC_2.27 roundevenf32 F ++GLIBC_2.27 roundevenf32x F ++GLIBC_2.27 roundevenf64 F ++GLIBC_2.27 roundevenf64x F ++GLIBC_2.27 roundevenl F ++GLIBC_2.27 roundf F ++GLIBC_2.27 roundf128 F ++GLIBC_2.27 roundf32 F ++GLIBC_2.27 roundf32x F ++GLIBC_2.27 roundf64 F ++GLIBC_2.27 roundf64x F ++GLIBC_2.27 roundl F ++GLIBC_2.27 scalb F ++GLIBC_2.27 scalbf F ++GLIBC_2.27 scalbl F ++GLIBC_2.27 scalbln F ++GLIBC_2.27 scalblnf F ++GLIBC_2.27 scalblnf128 F ++GLIBC_2.27 scalblnf32 F ++GLIBC_2.27 scalblnf32x F ++GLIBC_2.27 scalblnf64 F ++GLIBC_2.27 scalblnf64x F ++GLIBC_2.27 scalblnl F ++GLIBC_2.27 scalbn F ++GLIBC_2.27 scalbnf F ++GLIBC_2.27 scalbnf128 F ++GLIBC_2.27 scalbnf32 F ++GLIBC_2.27 scalbnf32x F ++GLIBC_2.27 scalbnf64 F ++GLIBC_2.27 scalbnf64x F ++GLIBC_2.27 scalbnl F ++GLIBC_2.27 setpayload F ++GLIBC_2.27 setpayloadf F ++GLIBC_2.27 setpayloadf128 F ++GLIBC_2.27 setpayloadf32 F ++GLIBC_2.27 setpayloadf32x F ++GLIBC_2.27 setpayloadf64 F ++GLIBC_2.27 setpayloadf64x F ++GLIBC_2.27 setpayloadl F ++GLIBC_2.27 setpayloadsig F ++GLIBC_2.27 setpayloadsigf F ++GLIBC_2.27 setpayloadsigf128 F ++GLIBC_2.27 setpayloadsigf32 F ++GLIBC_2.27 setpayloadsigf32x F ++GLIBC_2.27 setpayloadsigf64 F ++GLIBC_2.27 setpayloadsigf64x F ++GLIBC_2.27 setpayloadsigl F ++GLIBC_2.27 signgam D 0x4 ++GLIBC_2.27 significand F ++GLIBC_2.27 significandf F ++GLIBC_2.27 significandl F ++GLIBC_2.27 sin F ++GLIBC_2.27 sincos F ++GLIBC_2.27 sincosf F ++GLIBC_2.27 sincosf128 F ++GLIBC_2.27 sincosf32 F ++GLIBC_2.27 sincosf32x F ++GLIBC_2.27 sincosf64 F ++GLIBC_2.27 sincosf64x F ++GLIBC_2.27 sincosl F ++GLIBC_2.27 sinf F ++GLIBC_2.27 sinf128 F ++GLIBC_2.27 sinf32 F ++GLIBC_2.27 sinf32x F ++GLIBC_2.27 sinf64 F ++GLIBC_2.27 sinf64x F ++GLIBC_2.27 sinh F ++GLIBC_2.27 sinhf F ++GLIBC_2.27 sinhf128 F ++GLIBC_2.27 sinhf32 F ++GLIBC_2.27 sinhf32x F ++GLIBC_2.27 sinhf64 F ++GLIBC_2.27 sinhf64x F ++GLIBC_2.27 sinhl F ++GLIBC_2.27 sinl F ++GLIBC_2.27 sqrt F ++GLIBC_2.27 sqrtf F ++GLIBC_2.27 sqrtf128 F ++GLIBC_2.27 sqrtf32 F ++GLIBC_2.27 sqrtf32x F ++GLIBC_2.27 sqrtf64 F ++GLIBC_2.27 sqrtf64x F ++GLIBC_2.27 sqrtl F ++GLIBC_2.27 tan F ++GLIBC_2.27 tanf F ++GLIBC_2.27 tanf128 F ++GLIBC_2.27 tanf32 F ++GLIBC_2.27 tanf32x F ++GLIBC_2.27 tanf64 F ++GLIBC_2.27 tanf64x F ++GLIBC_2.27 tanh F ++GLIBC_2.27 tanhf F ++GLIBC_2.27 tanhf128 F ++GLIBC_2.27 tanhf32 F ++GLIBC_2.27 tanhf32x F ++GLIBC_2.27 tanhf64 F ++GLIBC_2.27 tanhf64x F ++GLIBC_2.27 tanhl F ++GLIBC_2.27 tanl F ++GLIBC_2.27 tgamma F ++GLIBC_2.27 tgammaf F ++GLIBC_2.27 tgammaf128 F ++GLIBC_2.27 tgammaf32 F ++GLIBC_2.27 tgammaf32x F ++GLIBC_2.27 tgammaf64 F ++GLIBC_2.27 tgammaf64x F ++GLIBC_2.27 tgammal F ++GLIBC_2.27 totalorder F ++GLIBC_2.27 totalorderf F ++GLIBC_2.27 totalorderf128 F ++GLIBC_2.27 totalorderf32 F ++GLIBC_2.27 totalorderf32x F ++GLIBC_2.27 totalorderf64 F ++GLIBC_2.27 totalorderf64x F ++GLIBC_2.27 totalorderl F ++GLIBC_2.27 totalordermag F ++GLIBC_2.27 totalordermagf F ++GLIBC_2.27 totalordermagf128 F ++GLIBC_2.27 totalordermagf32 F ++GLIBC_2.27 totalordermagf32x F ++GLIBC_2.27 totalordermagf64 F ++GLIBC_2.27 totalordermagf64x F ++GLIBC_2.27 totalordermagl F ++GLIBC_2.27 trunc F ++GLIBC_2.27 truncf F ++GLIBC_2.27 truncf128 F ++GLIBC_2.27 truncf32 F ++GLIBC_2.27 truncf32x F ++GLIBC_2.27 truncf64 F ++GLIBC_2.27 truncf64x F ++GLIBC_2.27 truncl F ++GLIBC_2.27 ufromfp F ++GLIBC_2.27 ufromfpf F ++GLIBC_2.27 ufromfpf128 F ++GLIBC_2.27 ufromfpf32 F ++GLIBC_2.27 ufromfpf32x F ++GLIBC_2.27 ufromfpf64 F ++GLIBC_2.27 ufromfpf64x F ++GLIBC_2.27 ufromfpl F ++GLIBC_2.27 ufromfpx F ++GLIBC_2.27 ufromfpxf F ++GLIBC_2.27 ufromfpxf128 F ++GLIBC_2.27 ufromfpxf32 F ++GLIBC_2.27 ufromfpxf32x F ++GLIBC_2.27 ufromfpxf64 F ++GLIBC_2.27 ufromfpxf64x F ++GLIBC_2.27 ufromfpxl F ++GLIBC_2.27 y0 F ++GLIBC_2.27 y0f F ++GLIBC_2.27 y0f128 F ++GLIBC_2.27 y0f32 F ++GLIBC_2.27 y0f32x F ++GLIBC_2.27 y0f64 F ++GLIBC_2.27 y0f64x F ++GLIBC_2.27 y0l F ++GLIBC_2.27 y1 F ++GLIBC_2.27 y1f F ++GLIBC_2.27 y1f128 F ++GLIBC_2.27 y1f32 F ++GLIBC_2.27 y1f32x F ++GLIBC_2.27 y1f64 F ++GLIBC_2.27 y1f64x F ++GLIBC_2.27 y1l F ++GLIBC_2.27 yn F ++GLIBC_2.27 ynf F ++GLIBC_2.27 ynf128 F ++GLIBC_2.27 ynf32 F ++GLIBC_2.27 ynf32x F ++GLIBC_2.27 ynf64 F ++GLIBC_2.27 ynf64x F ++GLIBC_2.27 ynl F ++GLIBC_2.28 daddl F ++GLIBC_2.28 ddivl F ++GLIBC_2.28 dmull F ++GLIBC_2.28 dsubl F ++GLIBC_2.28 f32addf128 F ++GLIBC_2.28 f32addf32x F ++GLIBC_2.28 f32addf64 F ++GLIBC_2.28 f32addf64x F ++GLIBC_2.28 f32divf128 F ++GLIBC_2.28 f32divf32x F ++GLIBC_2.28 f32divf64 F ++GLIBC_2.28 f32divf64x F ++GLIBC_2.28 f32mulf128 F ++GLIBC_2.28 f32mulf32x F ++GLIBC_2.28 f32mulf64 F ++GLIBC_2.28 f32mulf64x F ++GLIBC_2.28 f32subf128 F ++GLIBC_2.28 f32subf32x F ++GLIBC_2.28 f32subf64 F ++GLIBC_2.28 f32subf64x F ++GLIBC_2.28 f32xaddf128 F ++GLIBC_2.28 f32xaddf64 F ++GLIBC_2.28 f32xaddf64x F ++GLIBC_2.28 f32xdivf128 F ++GLIBC_2.28 f32xdivf64 F ++GLIBC_2.28 f32xdivf64x F ++GLIBC_2.28 f32xmulf128 F ++GLIBC_2.28 f32xmulf64 F ++GLIBC_2.28 f32xmulf64x F ++GLIBC_2.28 f32xsubf128 F ++GLIBC_2.28 f32xsubf64 F ++GLIBC_2.28 f32xsubf64x F ++GLIBC_2.28 f64addf128 F ++GLIBC_2.28 f64addf64x F ++GLIBC_2.28 f64divf128 F ++GLIBC_2.28 f64divf64x F ++GLIBC_2.28 f64mulf128 F ++GLIBC_2.28 f64mulf64x F ++GLIBC_2.28 f64subf128 F ++GLIBC_2.28 f64subf64x F ++GLIBC_2.28 f64xaddf128 F ++GLIBC_2.28 f64xdivf128 F ++GLIBC_2.28 f64xmulf128 F ++GLIBC_2.28 f64xsubf128 F ++GLIBC_2.28 fadd F ++GLIBC_2.28 faddl F ++GLIBC_2.28 fdiv F ++GLIBC_2.28 fdivl F ++GLIBC_2.28 fmul F ++GLIBC_2.28 fmull F ++GLIBC_2.28 fsub F ++GLIBC_2.28 fsubl F +diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libnsl.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libnsl.abilist +new file mode 100644 +index 00000000..0767472d +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libnsl.abilist +@@ -0,0 +1,120 @@ ++GLIBC_2.27 __free_fdresult F ++GLIBC_2.27 __nis_default_access F ++GLIBC_2.27 __nis_default_group F ++GLIBC_2.27 __nis_default_owner F ++GLIBC_2.27 __nis_default_ttl F ++GLIBC_2.27 __nis_finddirectory F ++GLIBC_2.27 __nisbind_connect F ++GLIBC_2.27 __nisbind_create F ++GLIBC_2.27 __nisbind_destroy F ++GLIBC_2.27 __nisbind_next F ++GLIBC_2.27 __yp_check F ++GLIBC_2.27 nis_add F ++GLIBC_2.27 nis_add_entry F ++GLIBC_2.27 nis_addmember F ++GLIBC_2.27 nis_checkpoint F ++GLIBC_2.27 nis_clone_directory F ++GLIBC_2.27 nis_clone_object F ++GLIBC_2.27 nis_clone_result F ++GLIBC_2.27 nis_creategroup F ++GLIBC_2.27 nis_destroy_object F ++GLIBC_2.27 nis_destroygroup F ++GLIBC_2.27 nis_dir_cmp F ++GLIBC_2.27 nis_domain_of F ++GLIBC_2.27 nis_domain_of_r F ++GLIBC_2.27 nis_first_entry F ++GLIBC_2.27 nis_free_directory F ++GLIBC_2.27 nis_free_object F ++GLIBC_2.27 nis_free_request F ++GLIBC_2.27 nis_freenames F ++GLIBC_2.27 nis_freeresult F ++GLIBC_2.27 nis_freeservlist F ++GLIBC_2.27 nis_freetags F ++GLIBC_2.27 nis_getnames F ++GLIBC_2.27 nis_getservlist F ++GLIBC_2.27 nis_ismember F ++GLIBC_2.27 nis_leaf_of F ++GLIBC_2.27 nis_leaf_of_r F ++GLIBC_2.27 nis_lerror F ++GLIBC_2.27 nis_list F ++GLIBC_2.27 nis_local_directory F ++GLIBC_2.27 nis_local_group F ++GLIBC_2.27 nis_local_host F ++GLIBC_2.27 nis_local_principal F ++GLIBC_2.27 nis_lookup F ++GLIBC_2.27 nis_mkdir F ++GLIBC_2.27 nis_modify F ++GLIBC_2.27 nis_modify_entry F ++GLIBC_2.27 nis_name_of F ++GLIBC_2.27 nis_name_of_r F ++GLIBC_2.27 nis_next_entry F ++GLIBC_2.27 nis_perror F ++GLIBC_2.27 nis_ping F ++GLIBC_2.27 nis_print_directory F ++GLIBC_2.27 nis_print_entry F ++GLIBC_2.27 nis_print_group F ++GLIBC_2.27 nis_print_group_entry F ++GLIBC_2.27 nis_print_link F ++GLIBC_2.27 nis_print_object F ++GLIBC_2.27 nis_print_result F ++GLIBC_2.27 nis_print_rights F ++GLIBC_2.27 nis_print_table F ++GLIBC_2.27 nis_read_obj F ++GLIBC_2.27 nis_remove F ++GLIBC_2.27 nis_remove_entry F ++GLIBC_2.27 nis_removemember F ++GLIBC_2.27 nis_rmdir F ++GLIBC_2.27 nis_servstate F ++GLIBC_2.27 nis_sperrno F ++GLIBC_2.27 nis_sperror F ++GLIBC_2.27 nis_sperror_r F ++GLIBC_2.27 nis_stats F ++GLIBC_2.27 nis_verifygroup F ++GLIBC_2.27 nis_write_obj F ++GLIBC_2.27 readColdStartFile F ++GLIBC_2.27 writeColdStartFile F ++GLIBC_2.27 xdr_cback_data F ++GLIBC_2.27 xdr_domainname F ++GLIBC_2.27 xdr_keydat F ++GLIBC_2.27 xdr_mapname F ++GLIBC_2.27 xdr_obj_p F ++GLIBC_2.27 xdr_peername F ++GLIBC_2.27 xdr_valdat F ++GLIBC_2.27 xdr_yp_buf F ++GLIBC_2.27 xdr_ypall F ++GLIBC_2.27 xdr_ypbind_binding F ++GLIBC_2.27 xdr_ypbind_resp F ++GLIBC_2.27 xdr_ypbind_resptype F ++GLIBC_2.27 xdr_ypbind_setdom F ++GLIBC_2.27 xdr_ypdelete_args F ++GLIBC_2.27 xdr_ypmap_parms F ++GLIBC_2.27 xdr_ypmaplist F ++GLIBC_2.27 xdr_yppush_status F ++GLIBC_2.27 xdr_yppushresp_xfr F ++GLIBC_2.27 xdr_ypreq_key F ++GLIBC_2.27 xdr_ypreq_nokey F ++GLIBC_2.27 xdr_ypreq_xfr F ++GLIBC_2.27 xdr_ypresp_all F ++GLIBC_2.27 xdr_ypresp_key_val F ++GLIBC_2.27 xdr_ypresp_maplist F ++GLIBC_2.27 xdr_ypresp_master F ++GLIBC_2.27 xdr_ypresp_order F ++GLIBC_2.27 xdr_ypresp_val F ++GLIBC_2.27 xdr_ypresp_xfr F ++GLIBC_2.27 xdr_ypstat F ++GLIBC_2.27 xdr_ypupdate_args F ++GLIBC_2.27 xdr_ypxfrstat F ++GLIBC_2.27 yp_all F ++GLIBC_2.27 yp_bind F ++GLIBC_2.27 yp_first F ++GLIBC_2.27 yp_get_default_domain F ++GLIBC_2.27 yp_maplist F ++GLIBC_2.27 yp_master F ++GLIBC_2.27 yp_match F ++GLIBC_2.27 yp_next F ++GLIBC_2.27 yp_order F ++GLIBC_2.27 yp_unbind F ++GLIBC_2.27 yp_update F ++GLIBC_2.27 ypbinderr_string F ++GLIBC_2.27 yperr_string F ++GLIBC_2.27 ypprot_err F +diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libpthread.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libpthread.abilist +new file mode 100644 +index 00000000..f60b22ef +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libpthread.abilist +@@ -0,0 +1,264 @@ ++GLIBC_2.0 _IO_flockfile F ++GLIBC_2.0 _IO_ftrylockfile F ++GLIBC_2.0 _IO_funlockfile F ++GLIBC_2.0 __close F ++GLIBC_2.0 __connect F ++GLIBC_2.0 __errno_location F ++GLIBC_2.0 __fcntl F ++GLIBC_2.0 __fork F ++GLIBC_2.0 __h_errno_location F ++GLIBC_2.0 __lseek F ++GLIBC_2.0 __open F ++GLIBC_2.0 __pthread_getspecific F ++GLIBC_2.0 __pthread_key_create F ++GLIBC_2.0 __pthread_mutex_destroy F ++GLIBC_2.0 __pthread_mutex_init F ++GLIBC_2.0 __pthread_mutex_lock F ++GLIBC_2.0 __pthread_mutex_trylock F ++GLIBC_2.0 __pthread_mutex_unlock F ++GLIBC_2.0 __pthread_mutexattr_destroy F ++GLIBC_2.0 __pthread_mutexattr_init F ++GLIBC_2.0 __pthread_mutexattr_settype F ++GLIBC_2.0 __pthread_once F ++GLIBC_2.0 __pthread_setspecific F ++GLIBC_2.0 __read F ++GLIBC_2.0 __send F ++GLIBC_2.0 __sigaction F ++GLIBC_2.0 __wait F ++GLIBC_2.0 __write F ++GLIBC_2.0 _pthread_cleanup_pop F ++GLIBC_2.0 _pthread_cleanup_pop_restore F ++GLIBC_2.0 _pthread_cleanup_push F ++GLIBC_2.0 _pthread_cleanup_push_defer F ++GLIBC_2.0 accept F ++GLIBC_2.0 close F ++GLIBC_2.0 connect F ++GLIBC_2.0 fcntl F ++GLIBC_2.0 flockfile F ++GLIBC_2.0 fork F ++GLIBC_2.0 fsync F ++GLIBC_2.0 ftrylockfile F ++GLIBC_2.0 funlockfile F ++GLIBC_2.0 longjmp F ++GLIBC_2.0 lseek F ++GLIBC_2.0 msync F ++GLIBC_2.0 nanosleep F ++GLIBC_2.0 open F ++GLIBC_2.0 pause F ++GLIBC_2.0 pthread_atfork F ++GLIBC_2.0 pthread_attr_destroy F ++GLIBC_2.0 pthread_attr_getdetachstate F ++GLIBC_2.0 pthread_attr_getinheritsched F ++GLIBC_2.0 pthread_attr_getschedparam F ++GLIBC_2.0 pthread_attr_getschedpolicy F ++GLIBC_2.0 pthread_attr_getscope F ++GLIBC_2.0 pthread_attr_init F ++GLIBC_2.0 pthread_attr_setdetachstate F ++GLIBC_2.0 pthread_attr_setinheritsched F ++GLIBC_2.0 pthread_attr_setschedparam F ++GLIBC_2.0 pthread_attr_setschedpolicy F ++GLIBC_2.0 pthread_attr_setscope F ++GLIBC_2.0 pthread_cancel F ++GLIBC_2.0 pthread_cond_broadcast F ++GLIBC_2.0 pthread_cond_destroy F ++GLIBC_2.0 pthread_cond_init F ++GLIBC_2.0 pthread_cond_signal F ++GLIBC_2.0 pthread_cond_timedwait F ++GLIBC_2.0 pthread_cond_wait F ++GLIBC_2.0 pthread_condattr_destroy F ++GLIBC_2.0 pthread_condattr_init F ++GLIBC_2.0 pthread_create F ++GLIBC_2.0 pthread_detach F ++GLIBC_2.0 pthread_equal F ++GLIBC_2.0 pthread_exit F ++GLIBC_2.0 pthread_getschedparam F ++GLIBC_2.0 pthread_getspecific F ++GLIBC_2.0 pthread_join F ++GLIBC_2.0 pthread_key_create F ++GLIBC_2.0 pthread_key_delete F ++GLIBC_2.0 pthread_kill F ++GLIBC_2.0 pthread_kill_other_threads_np F ++GLIBC_2.0 pthread_mutex_destroy F ++GLIBC_2.0 pthread_mutex_init F ++GLIBC_2.0 pthread_mutex_lock F ++GLIBC_2.0 pthread_mutex_trylock F ++GLIBC_2.0 pthread_mutex_unlock F ++GLIBC_2.0 pthread_mutexattr_destroy F ++GLIBC_2.0 pthread_mutexattr_getkind_np F ++GLIBC_2.0 pthread_mutexattr_init F ++GLIBC_2.0 pthread_mutexattr_setkind_np F ++GLIBC_2.0 pthread_once F ++GLIBC_2.0 pthread_self F ++GLIBC_2.0 pthread_setcancelstate F ++GLIBC_2.0 pthread_setcanceltype F ++GLIBC_2.0 pthread_setschedparam F ++GLIBC_2.0 pthread_setspecific F ++GLIBC_2.0 pthread_sigmask F ++GLIBC_2.0 pthread_testcancel F ++GLIBC_2.0 raise F ++GLIBC_2.0 read F ++GLIBC_2.0 recv F ++GLIBC_2.0 recvfrom F ++GLIBC_2.0 recvmsg F ++GLIBC_2.0 sem_destroy F ++GLIBC_2.0 sem_getvalue F ++GLIBC_2.0 sem_init F ++GLIBC_2.0 sem_post F ++GLIBC_2.0 sem_trywait F ++GLIBC_2.0 sem_wait F ++GLIBC_2.0 send F ++GLIBC_2.0 sendmsg F ++GLIBC_2.0 sendto F ++GLIBC_2.0 sigaction F ++GLIBC_2.0 siglongjmp F ++GLIBC_2.0 sigwait F ++GLIBC_2.0 system F ++GLIBC_2.0 tcdrain F ++GLIBC_2.0 wait F ++GLIBC_2.0 waitpid F ++GLIBC_2.0 write F ++GLIBC_2.11 pthread_sigqueue F ++GLIBC_2.12 pthread_getname_np F ++GLIBC_2.12 pthread_mutex_consistent F ++GLIBC_2.12 pthread_mutexattr_getrobust F ++GLIBC_2.12 pthread_mutexattr_setrobust F ++GLIBC_2.12 pthread_setname_np F ++GLIBC_2.18 pthread_getattr_default_np F ++GLIBC_2.18 pthread_setattr_default_np F ++GLIBC_2.2 __libc_allocate_rtsig F ++GLIBC_2.2 __libc_current_sigrtmax F ++GLIBC_2.2 __libc_current_sigrtmin F ++GLIBC_2.2 __open64 F ++GLIBC_2.2 __pread64 F ++GLIBC_2.2 __pthread_rwlock_destroy F ++GLIBC_2.2 __pthread_rwlock_init F ++GLIBC_2.2 __pthread_rwlock_rdlock F ++GLIBC_2.2 __pthread_rwlock_tryrdlock F ++GLIBC_2.2 __pthread_rwlock_trywrlock F ++GLIBC_2.2 __pthread_rwlock_unlock F ++GLIBC_2.2 __pthread_rwlock_wrlock F ++GLIBC_2.2 __pwrite64 F ++GLIBC_2.2 __res_state F ++GLIBC_2.2 lseek64 F ++GLIBC_2.2 open64 F ++GLIBC_2.2 pread F ++GLIBC_2.2 pread64 F ++GLIBC_2.2 pthread_attr_getguardsize F ++GLIBC_2.2 pthread_attr_getstack F ++GLIBC_2.2 pthread_attr_getstackaddr F ++GLIBC_2.2 pthread_attr_getstacksize F ++GLIBC_2.2 pthread_attr_init F ++GLIBC_2.2 pthread_attr_setguardsize F ++GLIBC_2.2 pthread_attr_setstack F ++GLIBC_2.2 pthread_attr_setstackaddr F ++GLIBC_2.2 pthread_attr_setstacksize F ++GLIBC_2.2 pthread_barrier_destroy F ++GLIBC_2.2 pthread_barrier_init F ++GLIBC_2.2 pthread_barrier_wait F ++GLIBC_2.2 pthread_barrierattr_destroy F ++GLIBC_2.2 pthread_barrierattr_init F ++GLIBC_2.2 pthread_barrierattr_setpshared F ++GLIBC_2.2 pthread_condattr_getpshared F ++GLIBC_2.2 pthread_condattr_setpshared F ++GLIBC_2.2 pthread_create F ++GLIBC_2.2 pthread_getconcurrency F ++GLIBC_2.2 pthread_getcpuclockid F ++GLIBC_2.2 pthread_mutex_timedlock F ++GLIBC_2.2 pthread_mutexattr_getpshared F ++GLIBC_2.2 pthread_mutexattr_gettype F ++GLIBC_2.2 pthread_mutexattr_setpshared F ++GLIBC_2.2 pthread_mutexattr_settype F ++GLIBC_2.2 pthread_rwlock_destroy F ++GLIBC_2.2 pthread_rwlock_init F ++GLIBC_2.2 pthread_rwlock_rdlock F ++GLIBC_2.2 pthread_rwlock_timedrdlock F ++GLIBC_2.2 pthread_rwlock_timedwrlock F ++GLIBC_2.2 pthread_rwlock_tryrdlock F ++GLIBC_2.2 pthread_rwlock_trywrlock F ++GLIBC_2.2 pthread_rwlock_unlock F ++GLIBC_2.2 pthread_rwlock_wrlock F ++GLIBC_2.2 pthread_rwlockattr_destroy F ++GLIBC_2.2 pthread_rwlockattr_getkind_np F ++GLIBC_2.2 pthread_rwlockattr_getpshared F ++GLIBC_2.2 pthread_rwlockattr_init F ++GLIBC_2.2 pthread_rwlockattr_setkind_np F ++GLIBC_2.2 pthread_rwlockattr_setpshared F ++GLIBC_2.2 pthread_setconcurrency F ++GLIBC_2.2 pthread_spin_destroy F ++GLIBC_2.2 pthread_spin_init F ++GLIBC_2.2 pthread_spin_lock F ++GLIBC_2.2 pthread_spin_trylock F ++GLIBC_2.2 pthread_spin_unlock F ++GLIBC_2.2 pthread_yield F ++GLIBC_2.2 pwrite F ++GLIBC_2.2 pwrite64 F ++GLIBC_2.2 sem_close F ++GLIBC_2.2 sem_destroy F ++GLIBC_2.2 sem_getvalue F ++GLIBC_2.2 sem_init F ++GLIBC_2.2 sem_open F ++GLIBC_2.2 sem_post F ++GLIBC_2.2 sem_timedwait F ++GLIBC_2.2 sem_trywait F ++GLIBC_2.2 sem_unlink F ++GLIBC_2.2 sem_wait F ++GLIBC_2.2.3 pthread_getattr_np F ++GLIBC_2.2.6 __nanosleep F ++GLIBC_2.28 call_once F ++GLIBC_2.28 cnd_broadcast F ++GLIBC_2.28 cnd_destroy F ++GLIBC_2.28 cnd_init F ++GLIBC_2.28 cnd_signal F ++GLIBC_2.28 cnd_timedwait F ++GLIBC_2.28 cnd_wait F ++GLIBC_2.28 mtx_destroy F ++GLIBC_2.28 mtx_init F ++GLIBC_2.28 mtx_lock F ++GLIBC_2.28 mtx_timedlock F ++GLIBC_2.28 mtx_trylock F ++GLIBC_2.28 mtx_unlock F ++GLIBC_2.28 thrd_create F ++GLIBC_2.28 thrd_detach F ++GLIBC_2.28 thrd_exit F ++GLIBC_2.28 thrd_join F ++GLIBC_2.28 tss_create F ++GLIBC_2.28 tss_delete F ++GLIBC_2.28 tss_get F ++GLIBC_2.28 tss_set F ++GLIBC_2.3.2 pthread_cond_broadcast F ++GLIBC_2.3.2 pthread_cond_destroy F ++GLIBC_2.3.2 pthread_cond_init F ++GLIBC_2.3.2 pthread_cond_signal F ++GLIBC_2.3.2 pthread_cond_timedwait F ++GLIBC_2.3.2 pthread_cond_wait F ++GLIBC_2.3.3 __pthread_cleanup_routine F ++GLIBC_2.3.3 __pthread_register_cancel F ++GLIBC_2.3.3 __pthread_register_cancel_defer F ++GLIBC_2.3.3 __pthread_unregister_cancel F ++GLIBC_2.3.3 __pthread_unregister_cancel_restore F ++GLIBC_2.3.3 __pthread_unwind_next F ++GLIBC_2.3.3 pthread_attr_getaffinity_np F ++GLIBC_2.3.3 pthread_attr_setaffinity_np F ++GLIBC_2.3.3 pthread_attr_setstack F ++GLIBC_2.3.3 pthread_attr_setstacksize F ++GLIBC_2.3.3 pthread_barrierattr_getpshared F ++GLIBC_2.3.3 pthread_condattr_getclock F ++GLIBC_2.3.3 pthread_condattr_setclock F ++GLIBC_2.3.3 pthread_getaffinity_np F ++GLIBC_2.3.3 pthread_setaffinity_np F ++GLIBC_2.3.3 pthread_timedjoin_np F ++GLIBC_2.3.3 pthread_tryjoin_np F ++GLIBC_2.3.4 pthread_attr_getaffinity_np F ++GLIBC_2.3.4 pthread_attr_setaffinity_np F ++GLIBC_2.3.4 pthread_getaffinity_np F ++GLIBC_2.3.4 pthread_setaffinity_np F ++GLIBC_2.3.4 pthread_setschedprio F ++GLIBC_2.4 pthread_mutex_consistent_np F ++GLIBC_2.4 pthread_mutex_getprioceiling F ++GLIBC_2.4 pthread_mutex_setprioceiling F ++GLIBC_2.4 pthread_mutexattr_getprioceiling F ++GLIBC_2.4 pthread_mutexattr_getprotocol F ++GLIBC_2.4 pthread_mutexattr_getrobust_np F ++GLIBC_2.4 pthread_mutexattr_setprioceiling F ++GLIBC_2.4 pthread_mutexattr_setprotocol F ++GLIBC_2.4 pthread_mutexattr_setrobust_np F +diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libresolv.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libresolv.abilist +new file mode 100644 +index 00000000..eb9c1cb7 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libresolv.abilist +@@ -0,0 +1,79 @@ ++GLIBC_2.27 __b64_ntop F ++GLIBC_2.27 __b64_pton F ++GLIBC_2.27 __dn_comp F ++GLIBC_2.27 __dn_count_labels F ++GLIBC_2.27 __dn_expand F ++GLIBC_2.27 __dn_skipname F ++GLIBC_2.27 __fp_nquery F ++GLIBC_2.27 __fp_query F ++GLIBC_2.27 __fp_resstat F ++GLIBC_2.27 __hostalias F ++GLIBC_2.27 __loc_aton F ++GLIBC_2.27 __loc_ntoa F ++GLIBC_2.27 __p_cdname F ++GLIBC_2.27 __p_cdnname F ++GLIBC_2.27 __p_class F ++GLIBC_2.27 __p_class_syms D 0xa8 ++GLIBC_2.27 __p_fqname F ++GLIBC_2.27 __p_fqnname F ++GLIBC_2.27 __p_option F ++GLIBC_2.27 __p_query F ++GLIBC_2.27 __p_rcode F ++GLIBC_2.27 __p_time F ++GLIBC_2.27 __p_type F ++GLIBC_2.27 __p_type_syms D 0x450 ++GLIBC_2.27 __putlong F ++GLIBC_2.27 __putshort F ++GLIBC_2.27 __res_close F ++GLIBC_2.27 __res_dnok F ++GLIBC_2.27 __res_hnok F ++GLIBC_2.27 __res_hostalias F ++GLIBC_2.27 __res_isourserver F ++GLIBC_2.27 __res_mailok F ++GLIBC_2.27 __res_mkquery F ++GLIBC_2.27 __res_nameinquery F ++GLIBC_2.27 __res_nmkquery F ++GLIBC_2.27 __res_nquery F ++GLIBC_2.27 __res_nquerydomain F ++GLIBC_2.27 __res_nsearch F ++GLIBC_2.27 __res_nsend F ++GLIBC_2.27 __res_ownok F ++GLIBC_2.27 __res_queriesmatch F ++GLIBC_2.27 __res_query F ++GLIBC_2.27 __res_querydomain F ++GLIBC_2.27 __res_search F ++GLIBC_2.27 __res_send F ++GLIBC_2.27 __sym_ntop F ++GLIBC_2.27 __sym_ntos F ++GLIBC_2.27 __sym_ston F ++GLIBC_2.27 _getlong F ++GLIBC_2.27 _getshort F ++GLIBC_2.27 inet_net_ntop F ++GLIBC_2.27 inet_net_pton F ++GLIBC_2.27 inet_neta F ++GLIBC_2.27 ns_datetosecs F ++GLIBC_2.27 ns_format_ttl F ++GLIBC_2.27 ns_get16 F ++GLIBC_2.27 ns_get32 F ++GLIBC_2.27 ns_initparse F ++GLIBC_2.27 ns_makecanon F ++GLIBC_2.27 ns_msg_getflag F ++GLIBC_2.27 ns_name_compress F ++GLIBC_2.27 ns_name_ntol F ++GLIBC_2.27 ns_name_ntop F ++GLIBC_2.27 ns_name_pack F ++GLIBC_2.27 ns_name_pton F ++GLIBC_2.27 ns_name_rollback F ++GLIBC_2.27 ns_name_skip F ++GLIBC_2.27 ns_name_uncompress F ++GLIBC_2.27 ns_name_unpack F ++GLIBC_2.27 ns_parse_ttl F ++GLIBC_2.27 ns_parserr F ++GLIBC_2.27 ns_put16 F ++GLIBC_2.27 ns_put32 F ++GLIBC_2.27 ns_samedomain F ++GLIBC_2.27 ns_samename F ++GLIBC_2.27 ns_skiprr F ++GLIBC_2.27 ns_sprintrr F ++GLIBC_2.27 ns_sprintrrf F ++GLIBC_2.27 ns_subdomain F +diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/librt.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/librt.abilist +new file mode 100644 +index 00000000..bfd262ec +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/lp64/librt.abilist +@@ -0,0 +1,35 @@ ++GLIBC_2.27 __mq_open_2 F ++GLIBC_2.27 aio_cancel F ++GLIBC_2.27 aio_cancel64 F ++GLIBC_2.27 aio_error F ++GLIBC_2.27 aio_error64 F ++GLIBC_2.27 aio_fsync F ++GLIBC_2.27 aio_fsync64 F ++GLIBC_2.27 aio_init F ++GLIBC_2.27 aio_read F ++GLIBC_2.27 aio_read64 F ++GLIBC_2.27 aio_return F ++GLIBC_2.27 aio_return64 F ++GLIBC_2.27 aio_suspend F ++GLIBC_2.27 aio_suspend64 F ++GLIBC_2.27 aio_write F ++GLIBC_2.27 aio_write64 F ++GLIBC_2.27 lio_listio F ++GLIBC_2.27 lio_listio64 F ++GLIBC_2.27 mq_close F ++GLIBC_2.27 mq_getattr F ++GLIBC_2.27 mq_notify F ++GLIBC_2.27 mq_open F ++GLIBC_2.27 mq_receive F ++GLIBC_2.27 mq_send F ++GLIBC_2.27 mq_setattr F ++GLIBC_2.27 mq_timedreceive F ++GLIBC_2.27 mq_timedsend F ++GLIBC_2.27 mq_unlink F ++GLIBC_2.27 shm_open F ++GLIBC_2.27 shm_unlink F ++GLIBC_2.27 timer_create F ++GLIBC_2.27 timer_delete F ++GLIBC_2.27 timer_getoverrun F ++GLIBC_2.27 timer_gettime F ++GLIBC_2.27 timer_settime F +diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libthread_db.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libthread_db.abilist +new file mode 100644 +index 00000000..4122e563 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libthread_db.abilist +@@ -0,0 +1,40 @@ ++GLIBC_2.27 td_init F ++GLIBC_2.27 td_log F ++GLIBC_2.27 td_symbol_list F ++GLIBC_2.27 td_ta_clear_event F ++GLIBC_2.27 td_ta_delete F ++GLIBC_2.27 td_ta_enable_stats F ++GLIBC_2.27 td_ta_event_addr F ++GLIBC_2.27 td_ta_event_getmsg F ++GLIBC_2.27 td_ta_get_nthreads F ++GLIBC_2.27 td_ta_get_ph F ++GLIBC_2.27 td_ta_get_stats F ++GLIBC_2.27 td_ta_map_id2thr F ++GLIBC_2.27 td_ta_map_lwp2thr F ++GLIBC_2.27 td_ta_new F ++GLIBC_2.27 td_ta_reset_stats F ++GLIBC_2.27 td_ta_set_event F ++GLIBC_2.27 td_ta_setconcurrency F ++GLIBC_2.27 td_ta_thr_iter F ++GLIBC_2.27 td_ta_tsd_iter F ++GLIBC_2.27 td_thr_clear_event F ++GLIBC_2.27 td_thr_dbresume F ++GLIBC_2.27 td_thr_dbsuspend F ++GLIBC_2.27 td_thr_event_enable F ++GLIBC_2.27 td_thr_event_getmsg F ++GLIBC_2.27 td_thr_get_info F ++GLIBC_2.27 td_thr_getfpregs F ++GLIBC_2.27 td_thr_getgregs F ++GLIBC_2.27 td_thr_getxregs F ++GLIBC_2.27 td_thr_getxregsize F ++GLIBC_2.27 td_thr_set_event F ++GLIBC_2.27 td_thr_setfpregs F ++GLIBC_2.27 td_thr_setgregs F ++GLIBC_2.27 td_thr_setprio F ++GLIBC_2.27 td_thr_setsigpending F ++GLIBC_2.27 td_thr_setxregs F ++GLIBC_2.27 td_thr_sigsetmask F ++GLIBC_2.27 td_thr_tls_get_addr F ++GLIBC_2.27 td_thr_tlsbase F ++GLIBC_2.27 td_thr_tsd F ++GLIBC_2.27 td_thr_validate F +diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libutil.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libutil.abilist +new file mode 100644 +index 00000000..cbfec8d4 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libutil.abilist +@@ -0,0 +1,6 @@ ++GLIBC_2.27 forkpty F ++GLIBC_2.27 login F ++GLIBC_2.27 login_tty F ++GLIBC_2.27 logout F ++GLIBC_2.27 logwtmp F ++GLIBC_2.27 openpty F +diff --git a/sysdeps/unix/sysv/linux/loongarch/makecontext.c b/sysdeps/unix/sysv/linux/loongarch/makecontext.c +new file mode 100644 +index 00000000..55d509ab +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/makecontext.c +@@ -0,0 +1,78 @@ ++/* Copyright (C) 2020-2021 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 ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++void ++__makecontext (ucontext_t *ucp, void (*func) (void), int argc, ++ long int a0, long int a1, long int a2, long int a3, long int a4, ++ ...) ++{ ++ extern void __start_context (void) attribute_hidden; ++ long int i, sp; ++ ++ _Static_assert (LARCH_REG_NARGS == 8, "__makecontext assumes 8 argument registers"); ++ ++ /* Set up the stack. */ ++ sp = ((long int) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size) & ALMASK; ++ ++ /* Set up the register context. ++ ra = s0 = 0, terminating the stack for backtracing purposes. ++ s1 = the function we must call. ++ s2 = the subsequent context to run. */ ++ ucp->uc_mcontext.__gregs[LARCH_REG_RA] = 0; ++ ucp->uc_mcontext.__gregs[LARCH_REG_S0] = 0; ++ ucp->uc_mcontext.__gregs[LARCH_REG_S1] = (long int) func; ++ ucp->uc_mcontext.__gregs[LARCH_REG_S2] = (long int) ucp->uc_link; ++ ucp->uc_mcontext.__gregs[LARCH_REG_SP] = sp; ++ ucp->uc_mcontext.__pc = (long int) &__start_context; ++ ++ /* Put args in a0-a7, then put any remaining args on the stack. */ ++ ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 0] = a0; ++ ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 1] = a1; ++ ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 2] = a2; ++ ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 3] = a3; ++ ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 4] = a4; ++ ++ if (__glibc_unlikely (argc > 5)) ++ { ++ va_list vl; ++ va_start (vl, a4); ++ ++ long reg_args = argc < LARCH_REG_NARGS ? argc : LARCH_REG_NARGS; ++ for (i = 5; i < reg_args; i++) ++ ucp->uc_mcontext.__gregs[LARCH_REG_A0 + i] = va_arg (vl, long); ++ ++ long int stack_args = argc - reg_args; ++ if (stack_args > 0) ++ { ++ sp = (sp - stack_args * sizeof (long int)) & ALMASK; ++ ucp->uc_mcontext.__gregs[LARCH_REG_SP] = sp; ++ for (i = 0; i < stack_args; i++) ++ ((long int *) sp)[i] = va_arg (vl, long int); ++ } ++ ++ va_end (vl); ++ } ++} ++ ++weak_alias (__makecontext, makecontext) +diff --git a/sysdeps/unix/sysv/linux/loongarch/profil-counter.h b/sysdeps/unix/sysv/linux/loongarch/profil-counter.h +new file mode 100644 +index 00000000..6a3cc201 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/profil-counter.h +@@ -0,0 +1,31 @@ ++/* Copyright (C) 2020-2021 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 ++ . */ ++ ++#include ++#include ++ ++static void ++__profil_counter (int signo, const SIGCONTEXT scp) ++{ ++ profil_count ((void *) GET_PC (scp)); ++ ++ /* This is a hack to prevent the compiler from implementing the ++ above function call as a sibcall. The sibcall would overwrite ++ the signal context. */ ++ asm volatile (""); ++} +diff --git a/sysdeps/unix/sysv/linux/loongarch/pt-vfork.S b/sysdeps/unix/sysv/linux/loongarch/pt-vfork.S +new file mode 100644 +index 00000000..1cc89317 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/pt-vfork.S +@@ -0,0 +1 @@ ++/* Not needed. */ +diff --git a/sysdeps/unix/sysv/linux/loongarch/register-dump.h b/sysdeps/unix/sysv/linux/loongarch/register-dump.h +new file mode 100644 +index 00000000..5e45d5c7 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/register-dump.h +@@ -0,0 +1,63 @@ ++/* Dump registers. ++ Copyright (C) 2000-2018 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 ++ . */ ++ ++#include ++#include ++#include <_itoa.h> ++ ++static void ++hexvalue (unsigned long int value, char *buf, size_t len) ++{ ++ char *cp = _itoa_word (value, buf + len, 16, 0); ++ while (cp > buf) ++ *--cp = '0'; ++} ++ ++#define REGDUMP_NREGS 32 ++#define REGDUMP_PER_LINE (80 / (__WORDSIZE / 4 + 4)) ++ ++static void ++register_dump (int fd, ucontext_t *ctx) ++{ ++ int i; ++ char regvalue[__WORDSIZE / 4 + 1]; ++ char str[82 * ((REGDUMP_NREGS + REGDUMP_PER_LINE - 1) / REGDUMP_PER_LINE)]; ++ ++ static const char names[REGDUMP_NREGS][4] = { ++ "pc", "ra", "tp", "sp", "a0", "a1", "a2", "a3", ++ "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3", ++ "t4", "t5", "t6", "t7", "t8", "x" , "fp", "s0", ++ "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8" ++ }; ++ ++ str[0] = 0; ++ for (i = 0; i < REGDUMP_NREGS; i++) ++ { ++ strcat (str, names[i]); ++ strcat (str, " "); ++ hexvalue (ctx->uc_mcontext.__gregs[i], regvalue, __WORDSIZE / 4); ++ strcat (str, regvalue); ++ ++ if ((i + 1) % REGDUMP_PER_LINE == 0) ++ strcat (str, "\n"); ++ } ++ ++ write (fd, str, strlen (str)); ++} ++ ++#define REGISTER_DUMP register_dump (fd, ctx) +diff --git a/sysdeps/unix/sysv/linux/loongarch/setcontext.S b/sysdeps/unix/sysv/linux/loongarch/setcontext.S +new file mode 100644 +index 00000000..c96ec43c +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/setcontext.S +@@ -0,0 +1,111 @@ ++/* Set current context. ++ Copyright (C) 2009-2018 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 ++ . */ ++#include "sys/regdef.h" ++#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) ++ ++ addi.d sp, sp, -16 ++ st.d a0, sp, 0 /* Save ucp to stack. */ ++/* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, NULL, _NSIG8) */ ++ li.d a3, _NSIG8 ++ li.d a2, 0 ++ addi.d a1, a0, UCONTEXT_SIGMASK ++ li.d a0, SIG_SETMASK ++ ++ li.d a7, SYS_ify (rt_sigprocmask) ++ syscall 0 ++ ++ blt a0, $r0, 99f ++ ++ ld.d t0, sp, 0 /* Load ucp to t0. */ ++ cfi_def_cfa (12, 0) ++ ++#ifndef __loongarch_soft_float ++ ld.w t1, t0, MCONTEXT_FCSR ++ ++ RESTORE_FP_REG (fs0, 24, t0) ++ RESTORE_FP_REG (fs1, 25, t0) ++ RESTORE_FP_REG (fs2, 26, t0) ++ RESTORE_FP_REG (fs3, 27, t0) ++ RESTORE_FP_REG (fs4, 28, t0) ++ RESTORE_FP_REG (fs5, 29, t0) ++ RESTORE_FP_REG (fs6, 30, t0) ++ RESTORE_FP_REG (fs7, 31, t0) ++ ++ movgr2fcsr $r0, t1 ++#endif /* __loongarch_soft_float */ ++ ++ /* Note the contents of argument registers will be random ++ unless makecontext() has been called. */ ++ RESTORE_INT_REG (ra, 1, t0) ++ RESTORE_INT_REG (sp, 3, t0) ++ RESTORE_INT_REG (a0, 4, t0) ++ RESTORE_INT_REG (a1, 5, t0) ++ RESTORE_INT_REG (a2, 6, t0) ++ RESTORE_INT_REG (a3, 7, t0) ++ RESTORE_INT_REG (a4, 8, t0) ++ RESTORE_INT_REG (a5, 9, t0) ++ RESTORE_INT_REG (a6, 10, t0) ++ RESTORE_INT_REG (a7, 11, t0) ++ RESTORE_INT_REG (x, 21, t0) ++ RESTORE_INT_REG (fp, 22, t0) ++ RESTORE_INT_REG (s0, 23, t0) ++ RESTORE_INT_REG (s1, 24, t0) ++ RESTORE_INT_REG (s2, 25, t0) ++ RESTORE_INT_REG (s3, 26, t0) ++ RESTORE_INT_REG (s4, 27, t0) ++ RESTORE_INT_REG (s5, 28, t0) ++ RESTORE_INT_REG (s6, 29, t0) ++ RESTORE_INT_REG (s7, 30, t0) ++ RESTORE_INT_REG (s8, 31, t0) ++ ld.d t1, t0, MCONTEXT_PC ++ jirl $r0,t1,0 ++ ++99: ++ addi.d sp, sp, 16 ++ b __syscall_error ++ ++PSEUDO_END (__setcontext) ++weak_alias (__setcontext, setcontext) ++ ++LEAF (__start_context) ++ ++ /* Terminate call stack by noting ra == 0. Happily, s0 == 0 here. */ ++ cfi_register (1, 23) ++ ++ /* Call the function passed to makecontext. */ ++ jirl $r1,s1,0 ++ ++ /* Invoke subsequent context if present, else exit(0). */ ++ ori a0, s2, 0 ++ beqz s2, 1f ++ bl __setcontext ++1: b exit ++ ++PSEUDO_END (__start_context) +diff --git a/sysdeps/unix/sysv/linux/loongarch/shlib-versions b/sysdeps/unix/sysv/linux/loongarch/shlib-versions +new file mode 100644 +index 00000000..2a67fe71 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/shlib-versions +@@ -0,0 +1,2 @@ ++DEFAULT GLIBC_2.27 ++libpthread=0 GLIBC_2.0 GLIBC_2.2 +diff --git a/sysdeps/unix/sysv/linux/loongarch/sigcontextinfo.h b/sysdeps/unix/sysv/linux/loongarch/sigcontextinfo.h +new file mode 100644 +index 00000000..2a864795 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/sigcontextinfo.h +@@ -0,0 +1,22 @@ ++/* Copyright (C) 2020-2021 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 ++ . */ ++ ++#include ++ ++#define SIGCONTEXT siginfo_t *_si, ucontext_t * ++#define GET_PC(ctx) ((void *) ctx->uc_mcontext.__pc) +diff --git a/sysdeps/unix/sysv/linux/loongarch/swapcontext.S b/sysdeps/unix/sysv/linux/loongarch/swapcontext.S +new file mode 100644 +index 00000000..d839dd87 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/swapcontext.S +@@ -0,0 +1,120 @@ ++/* Save and set current context. ++ Copyright (C) 2009-2018 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 ++ . */ ++ ++#include "ucontext-macros.h" ++ ++/* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */ ++ ++LEAF (__swapcontext) ++ ori a2, sp, 0 /* Save sp to a2. */ ++ addi.d sp, sp, -16 ++ st.d a1, sp, 0 ++ ori t0, a1, 0 ++ ++ SAVE_INT_REG (ra, 1, a0) ++ SAVE_INT_REG (a2, 3, a0) /* Store sp .*/ ++ SAVE_INT_REG (zero, 4, a0) /* return 0 by overwriting a0. */ ++ SAVE_INT_REG (x, 21, a0) ++ SAVE_INT_REG (fp, 22, a0) ++ SAVE_INT_REG (s0, 23, a0) ++ SAVE_INT_REG (s1, 24, a0) ++ SAVE_INT_REG (s2, 25, a0) ++ SAVE_INT_REG (s3, 26, a0) ++ SAVE_INT_REG (s4, 27, a0) ++ SAVE_INT_REG (s5, 28, a0) ++ SAVE_INT_REG (s6, 29, a0) ++ SAVE_INT_REG (s7, 30, a0) ++ SAVE_INT_REG (s8, 31, a0) ++ st.d ra, a0, MCONTEXT_PC ++#ifndef __loongarch_soft_float ++ movfcsr2gr a1, $r0 ++ ++ SAVE_FP_REG (fs0, 24, a0) ++ SAVE_FP_REG (fs1, 25, a0) ++ SAVE_FP_REG (fs2, 26, a0) ++ SAVE_FP_REG (fs3, 27, a0) ++ SAVE_FP_REG (fs4, 28, a0) ++ SAVE_FP_REG (fs5, 29, a0) ++ SAVE_FP_REG (fs6, 30, a0) ++ SAVE_FP_REG (fs7, 31, a0) ++ ++ st.w a1, a0, MCONTEXT_FCSR ++#endif /* __loongarch_soft_float */ ++ ++/* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, &oucp->uc_sigmask, _NSIG8) */ ++ li.d a3, _NSIG8 ++ addi.d a2, a0, UCONTEXT_SIGMASK ++ addi.d a1, t0, UCONTEXT_SIGMASK ++ li.d a0, SIG_SETMASK ++ ++ li.d a7, SYS_ify (rt_sigprocmask) ++ syscall 0 ++ ++ blt a0, zero, 99f ++ ++#ifndef __loongarch_soft_float ++ ld.d t0, sp, 0 /* Load a1 to t0. */ ++ ld.w t1, t0, MCONTEXT_FCSR ++ ++ RESTORE_FP_REG (fs0, 24, t0) ++ RESTORE_FP_REG (fs1, 25, t0) ++ RESTORE_FP_REG (fs2, 26, t0) ++ RESTORE_FP_REG (fs3, 27, t0) ++ RESTORE_FP_REG (fs4, 28, t0) ++ RESTORE_FP_REG (fs5, 29, t0) ++ RESTORE_FP_REG (fs6, 30, t0) ++ RESTORE_FP_REG (fs7, 31, t0) ++ ++ movgr2fcsr $r0, t1 ++#endif /* __loongarch_soft_float */ ++ ++ /* Note the contents of argument registers will be random ++ unless makecontext() has been called. */ ++ RESTORE_INT_REG (ra, 1, t0) ++ RESTORE_INT_REG (sp, 3, t0) ++ RESTORE_INT_REG (a0, 4, t0) ++ RESTORE_INT_REG (a1, 5, t0) ++ RESTORE_INT_REG (a2, 6, t0) ++ RESTORE_INT_REG (a3, 7, t0) ++ RESTORE_INT_REG (a4, 8, t0) ++ RESTORE_INT_REG (a5, 9, t0) ++ RESTORE_INT_REG (a6, 10, t0) ++ RESTORE_INT_REG (a7, 11, t0) ++ RESTORE_INT_REG (x, 21, t0) ++ RESTORE_INT_REG (fp, 22, t0) ++ RESTORE_INT_REG (s0, 23, t0) ++ RESTORE_INT_REG (s1, 24, t0) ++ RESTORE_INT_REG (s2, 25, t0) ++ RESTORE_INT_REG (s3, 26, t0) ++ RESTORE_INT_REG (s4, 27, t0) ++ RESTORE_INT_REG (s5, 28, t0) ++ RESTORE_INT_REG (s6, 29, t0) ++ RESTORE_INT_REG (s7, 30, t0) ++ RESTORE_INT_REG (s8, 31, t0) ++ ld.d t1, t0, MCONTEXT_PC ++ ++ jirl $r0, t1, 0 ++ ++ ++99: ++ addi.d sp, sp, 16 ++ b __syscall_error ++ ++PSEUDO_END (__swapcontext) ++ ++weak_alias (__swapcontext, swapcontext) +diff --git a/sysdeps/unix/sysv/linux/loongarch/sys/procfs.h b/sysdeps/unix/sysv/linux/loongarch/sys/procfs.h +new file mode 100644 +index 00000000..9ae06b40 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/sys/procfs.h +@@ -0,0 +1,122 @@ ++/* Copyright (C) 2020-2021 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 ++ . */ ++ ++#ifndef _SYS_PROCFS_H ++#define _SYS_PROCFS_H 1 ++ ++/* This is somehow modelled after the file of the same name on SysVr4 ++ systems. It provides a definition of the core file format for ELF ++ used on Linux. */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++__BEGIN_DECLS ++ ++/* Type for a general-purpose register. */ ++typedef uint64_t elf_greg_t; ++ ++/* And the whole bunch of them. We could have used `struct ++ pt_regs' directly in the typedef, but tradition says that ++ the register set is an array, which does have some peculiar ++ semantics, so leave it that way. */ ++#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t)) ++typedef elf_greg_t elf_gregset_t[ELF_NGREG]; ++ ++#define ELF_NFPREG 34 /* 32 FPRs + 8-byte byte-vec for fcc + 4-byte FCR */ ++typedef union { double d; float f; } elf_fpreg_t; ++typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; ++ ++typedef union { double d[2]; float f[4]; } __attribute__((__aligned__ (16))) elf_lsxregset_t[32]; ++typedef union { double d[4]; float f[8]; } __attribute__((__aligned__ (32))) elf_lasxregset_t[32]; ++ ++struct elf_siginfo ++ { ++ int si_signo; /* Signal number. */ ++ int si_code; /* Extra code. */ ++ int si_errno; /* Errno. */ ++ }; ++ ++/* Definitions to generate Intel SVR4-like core files. These mostly ++ have the same names as the SVR4 types with "elf_" tacked on the ++ front to prevent clashes with linux definitions, and the typedef ++ forms have been avoided. This is mostly like the SVR4 structure, ++ but more Linuxy, with things that Linux does not support and which ++ gdb doesn't really use excluded. Fields present but not used are ++ marked with "XXX". */ ++struct elf_prstatus ++ { ++ struct elf_siginfo pr_info; /* Info associated with signal. */ ++ short int pr_cursig; /* Current signal. */ ++ unsigned long int pr_sigpend; /* Set of pending signals. */ ++ unsigned long int pr_sighold; /* Set of held signals. */ ++ __pid_t pr_pid; ++ __pid_t pr_ppid; ++ __pid_t pr_pgrp; ++ __pid_t pr_sid; ++ struct timeval pr_utime; /* User time. */ ++ struct timeval pr_stime; /* System time. */ ++ struct timeval pr_cutime; /* Cumulative user time. */ ++ struct timeval pr_cstime; /* Cumulative system time. */ ++ elf_gregset_t pr_reg; /* GP registers. */ ++ int pr_fpvalid; /* True if math copro being used. */ ++ }; ++ ++ ++#define ELF_PRARGSZ (80) /* Number of chars for args */ ++ ++struct elf_prpsinfo ++ { ++ char pr_state; /* Numeric process state. */ ++ char pr_sname; /* Char for pr_state. */ ++ char pr_zomb; /* Zombie. */ ++ char pr_nice; /* Nice val. */ ++ unsigned long int pr_flag; /* Flags. */ ++ unsigned int pr_uid; ++ unsigned int pr_gid; ++ int pr_pid, pr_ppid, pr_pgrp, pr_sid; ++ /* Lots missing */ ++ char pr_fname[16]; /* Filename of executable. */ ++ char pr_psargs[ELF_PRARGSZ]; /* Initial part of arg list. */ ++ }; ++ ++/* The rest of this file provides the types for emulation of the ++ Solaris interfaces that should be implemented by ++ users of libthread_db. */ ++ ++/* Addresses. */ ++typedef void *psaddr_t; ++ ++/* Register sets. Linux has different names. */ ++typedef elf_gregset_t prgregset_t; ++typedef elf_fpregset_t prfpregset_t; ++ ++/* We don't have any differences between processes and threads, ++ therefore habe only ine PID type. */ ++typedef __pid_t lwpid_t; ++ ++/* Process status and info. In the end we do provide typedefs for them. */ ++typedef struct elf_prstatus prstatus_t; ++typedef struct elf_prpsinfo prpsinfo_t; ++ ++__END_DECLS ++ ++#endif /* sys/procfs.h */ +diff --git a/sysdeps/unix/sysv/linux/loongarch/sys/ucontext.h b/sysdeps/unix/sysv/linux/loongarch/sys/ucontext.h +new file mode 100644 +index 00000000..e52a46c9 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/sys/ucontext.h +@@ -0,0 +1,81 @@ ++/* Copyright (C) 2020-2021 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 ++ . */ ++ ++/* Don't rely on this, the interface is currently messed up and may need to ++ be broken to be fixed. */ ++#ifndef _SYS_UCONTEXT_H ++#define _SYS_UCONTEXT_H 1 ++ ++#include ++ ++#include ++#include ++ ++typedef unsigned long int __loongarch_mc_gp_state[32]; ++ ++#ifdef __USE_MISC ++# define LARCH_NGREG 32 ++ ++# define LARCH_REG_RA 1 ++# define LARCH_REG_SP 3 ++# define LARCH_REG_S0 23 ++# define LARCH_REG_S1 24 ++# define LARCH_REG_A0 4 ++# define LARCH_REG_S2 25 ++# define LARCH_REG_NARGS 8 ++ ++typedef unsigned long int greg_t; ++ ++/* Container for all general registers. */ ++typedef __loongarch_mc_gp_state gregset_t; ++ ++/* Container for floating-point state. */ ++typedef union __loongarch_mc_fp_state fpregset_t; ++#endif ++ ++ ++ ++union __loongarch_mc_fp_state { ++ unsigned int __val32[256 / 32]; ++ unsigned long long __val64[256 / 64]; ++}; ++ ++typedef struct mcontext_t { ++ unsigned long long __pc; ++ unsigned long long __gregs[32]; ++ unsigned int __flags; ++ ++ unsigned int __fcsr; ++ unsigned int __vcsr; ++ unsigned long long __fcc; ++ union __loongarch_mc_fp_state __fpregs[32] __attribute__((__aligned__ (32))); ++ ++ unsigned int __reserved; ++} mcontext_t; ++ ++/* Userlevel context. */ ++typedef struct ucontext_t ++ { ++ unsigned long int __uc_flags; ++ struct ucontext_t *uc_link; ++ stack_t uc_stack; ++ mcontext_t uc_mcontext; ++ sigset_t uc_sigmask; ++ } ucontext_t; ++ ++#endif /* sys/ucontext.h */ +diff --git a/sysdeps/unix/sysv/linux/loongarch/sys/user.h b/sysdeps/unix/sysv/linux/loongarch/sys/user.h +new file mode 100644 +index 00000000..f9108350 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/sys/user.h +@@ -0,0 +1,31 @@ ++/* Copyright (C) 2001-2018 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 ++ . */ ++ ++#ifndef _SYS_USER_H ++#define _SYS_USER_H 1 ++ ++#include ++ ++struct user_regs_struct ++{ ++ uint64_t gpr[32]; ++ uint64_t pc; ++ uint64_t badvaddr; ++ uint64_t reserved[11]; ++}; ++ ++#endif /* _SYS_USER_H */ +diff --git a/sysdeps/unix/sysv/linux/loongarch/syscall.c b/sysdeps/unix/sysv/linux/loongarch/syscall.c +new file mode 100644 +index 00000000..b06a528e +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/syscall.c +@@ -0,0 +1,36 @@ ++/* Copyright (C) 2020-2021 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 ++ . */ ++ ++#include ++ ++long int ++syscall (long int syscall_number, long int arg1, long int arg2, long int arg3, ++ long int arg4, long int arg5, long int arg6, long int arg7) ++{ ++ long int ret; ++ INTERNAL_SYSCALL_DECL (err); ++ ++ ret = INTERNAL_SYSCALL_NCS (syscall_number, err, 7, arg1, arg2, arg3, arg4, ++ arg5, arg6, arg7); ++ ++ if (INTERNAL_SYSCALL_ERROR_P (ret, err)) ++ return __syscall_error (ret); ++ ++ return ret; ++} ++ +diff --git a/sysdeps/unix/sysv/linux/loongarch/sysdep.S b/sysdeps/unix/sysv/linux/loongarch/sysdep.S +new file mode 100644 +index 00000000..a8094283 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/sysdep.S +@@ -0,0 +1,52 @@ ++/* syscall error handlers ++ Copyright (C) 2011-2018 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 ++ . */ ++ ++#include ++ ++#if IS_IN (libc) ++# define errno __libc_errno ++#endif ++ ++ENTRY (__syscall_error) ++ /* Fall through to __syscall_set_errno. */ ++END (__syscall_error) ++ ++/* Non-standard calling convention: argument in a0, return address in t0, ++ and clobber only t1. */ ++ENTRY (__syscall_set_errno) ++ /* We got here because a0 < 0, but only codes in the range [-4095, -1] ++ represent errors. Otherwise, just return the result normally. */ ++ ++ li.d t1, -4096 ++ bgeu t1, a0, L (out) ++ sub.w a0, zero, a0 ++ ++#if RTLD_PRIVATE_ERRNO ++ la t1, rtld_errno ++#elif defined(__PIC__) ++ la.tls.ie t1, errno ++ add.d t1, tp, t1 ++#else ++ la.tls.le t1, errno ++ add.d t1, tp, t1 ++#endif ++ st.w a0, t1, 0 ++ li.d a0, -1 ++L (out): ++ ret ++END (__syscall_set_errno) +diff --git a/sysdeps/unix/sysv/linux/loongarch/sysdep.h b/sysdeps/unix/sysv/linux/loongarch/sysdep.h +new file mode 100644 +index 00000000..f50946d4 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/sysdep.h +@@ -0,0 +1,333 @@ ++#ifndef _LINUX_LOONGARCH_SYSDEP_H ++#define _LINUX_LOONGARCH_SYSDEP_H 1 ++ ++#include ++#include ++ ++#ifdef __ASSEMBLER__ ++ ++# include ++# define ret jirl zero, ra, 0 ++# define L(label) .L ## label ++ ++/* Performs a system call, handling errors by setting errno. Linux indicates ++ errors by setting a0 to a value between -1 and -4095. */ ++# undef PSEUDO ++# define PSEUDO(name, syscall_name, args) \ ++ ENTRY (name); \ ++ li.d a7, SYS_ify (syscall_name); \ ++ syscall 0; \ ++ li.d a7, -4096; \ ++ bltu a7, a0, .Lsyscall_error ## name; ++ ++# undef PSEUDO_END ++# define PSEUDO_END(sym) \ ++ SYSCALL_ERROR_HANDLER (sym); \ ++ ret; \ ++ END (sym); ++ ++# if !IS_IN (libc) ++# if RTLD_PRIVATE_ERRNO ++ ++# define SYSCALL_ERROR_HANDLER(name) \ ++.Lsyscall_error ## name: \ ++ la t0, rtld_errno; \ ++ sub.w a0, zero, a0; \ ++ st.w a0, t0, 0; \ ++ li.d a0, -1; ++ ++# else ++ ++# define SYSCALL_ERROR_HANDLER(name) \ ++.Lsyscall_error ## name: \ ++ la.tls.ie t0, errno; \ ++ add.d t0, tp, t0; \ ++ sub.w a0, zero, a0; \ ++ st.w a0, t0, 0; \ ++ li.d a0, -1; ++ ++# endif ++# else ++ ++# define SYSCALL_ERROR_HANDLER(name) \ ++.Lsyscall_error ## name: \ ++ b __syscall_error; ++ ++# endif ++ ++/* Performs a system call, not setting errno. */ ++# undef PSEUDO_NEORRNO ++# define PSEUDO_NOERRNO(name, syscall_name, args) \ ++ ENTRY (name); \ ++ li.d a7, SYS_ify (syscall_name); \ ++ syscall 0; ++ ++# undef PSEUDO_END_NOERRNO ++# define PSEUDO_END_NOERRNO(name) \ ++ END (name); ++ ++# undef ret_NOERRNO ++# define ret_NOERRNO ret ++ ++/* Perfroms a system call, returning the error code. */ ++# undef PSEUDO_ERRVAL ++# define PSEUDO_ERRVAL(name, syscall_name, args) \ ++ PSEUDO_NOERRNO (name, syscall_name, args); \ ++ slli.d a0, a0, 32; \ ++ srai.d a0, a0, 32; /* sign_ext */ \ ++ sub.d a0, zero, a0; ++ ++# undef PSEUDO_END_ERRVAL ++# define PSEUDO_END_ERRVAL(name) \ ++ END (name); ++ ++# undef ret_ERRVAL ++# define ret_ERRVAL ret ++ ++#endif /* __ASSEMBLER__ */ ++ ++/* In order to get __set_errno() definition in INLINE_SYSCALL. */ ++#ifndef __ASSEMBLER__ ++# include ++#endif ++ ++#include ++ ++#undef SYS_ify ++#define SYS_ify(syscall_name) __NR_##syscall_name ++ ++#ifndef __ASSEMBLER__ ++ ++/* List of system calls which are supported as vsyscalls. */ ++# define HAVE_CLOCK_GETRES_VSYSCALL 1 ++# define HAVE_CLOCK_GETTIME_VSYSCALL 1 ++# define HAVE_GETTIMEOFDAY_VSYSCALL 1 ++# define HAVE_GETCPU_VSYSCALL 1 ++ ++/* Define a macro which expands into the inline wrapper code for a system ++ call. */ ++# undef INLINE_SYSCALL ++# define INLINE_SYSCALL(name, nr, args...) \ ++ ({ INTERNAL_SYSCALL_DECL (err); \ ++ long int __sys_result = INTERNAL_SYSCALL (name, err, nr, args); \ ++ if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (__sys_result, ))) \ ++ { \ ++ __set_errno (INTERNAL_SYSCALL_ERRNO (__sys_result, )); \ ++ __sys_result = (unsigned long) -1; \ ++ } \ ++ __sys_result; }) ++ ++ ++# define INTERNAL_SYSCALL_DECL(err) do { } while (0) ++ ++# define INTERNAL_SYSCALL_ERROR_P(val, err) \ ++ ((unsigned long int) (val) > -4096UL) ++ ++# define INTERNAL_SYSCALL_ERRNO(val, err) (-(val)) ++ ++# define INTERNAL_SYSCALL(name, err, nr, args...) \ ++ internal_syscall##nr (SYS_ify (name), err, args) ++ ++# define INTERNAL_SYSCALL_NCS(number, err, nr, args...) \ ++ internal_syscall##nr (number, err, args) ++ ++# define internal_syscall0(number, err, dummy...) \ ++({ \ ++ long int _sys_result; \ ++ \ ++ { \ ++ register long int __a7 asm ("$a7") = number; \ ++ register long int __a0 asm ("$a0"); \ ++ __asm__ volatile ( \ ++ "syscall 0\n\t" \ ++ : "=r" (__a0) \ ++ : "r" (__a7) \ ++ : __SYSCALL_CLOBBERS); \ ++ _sys_result = __a0; \ ++ } \ ++ _sys_result; \ ++}) ++ ++# define internal_syscall1(number, err, arg0) \ ++({ \ ++ long int _sys_result; \ ++ \ ++ { \ ++ long int _arg0 = (long int) (arg0); \ ++ register long int __a7 asm ("$a7") = number; \ ++ register long int __a0 asm ("$a0") = _arg0; \ ++ __asm__ volatile ( \ ++ "syscall 0\n\t" \ ++ : "+r" (__a0) \ ++ : "r" (__a7) \ ++ : __SYSCALL_CLOBBERS); \ ++ _sys_result = __a0; \ ++ } \ ++ _sys_result; \ ++}) ++ ++# define internal_syscall2(number, err, arg0, arg1) \ ++({ \ ++ long int _sys_result; \ ++ \ ++ { \ ++ long int _arg0 = (long int) (arg0); \ ++ long int _arg1 = (long int) (arg1); \ ++ register long int __a7 asm ("$a7") = number; \ ++ register long int __a0 asm ("$a0") = _arg0; \ ++ register long int __a1 asm ("$a1") = _arg1; \ ++ __asm__ volatile ( \ ++ "syscall 0\n\t" \ ++ : "+r" (__a0) \ ++ : "r" (__a7), "r" (__a1) \ ++ : __SYSCALL_CLOBBERS); \ ++ _sys_result = __a0; \ ++ } \ ++ _sys_result; \ ++}) ++ ++# define internal_syscall3(number, err, arg0, arg1, arg2) \ ++({ \ ++ long int _sys_result; \ ++ \ ++ { \ ++ long int _arg0 = (long int) (arg0); \ ++ long int _arg1 = (long int) (arg1); \ ++ long int _arg2 = (long int) (arg2); \ ++ register long int __a7 asm ("$a7") = number; \ ++ register long int __a0 asm ("$a0") = _arg0; \ ++ register long int __a1 asm ("$a1") = _arg1; \ ++ register long int __a2 asm ("$a2") = _arg2; \ ++ __asm__ volatile ( \ ++ "syscall 0\n\t" \ ++ : "+r" (__a0) \ ++ : "r" (__a7), "r" (__a1), "r" (__a2) \ ++ : __SYSCALL_CLOBBERS); \ ++ _sys_result = __a0; \ ++ } \ ++ _sys_result; \ ++}) ++ ++# define internal_syscall4(number, err, arg0, arg1, arg2, arg3) \ ++({ \ ++ long int _sys_result; \ ++ \ ++ { \ ++ long int _arg0 = (long int) (arg0); \ ++ long int _arg1 = (long int) (arg1); \ ++ long int _arg2 = (long int) (arg2); \ ++ long int _arg3 = (long int) (arg3); \ ++ register long int __a7 asm ("$a7") = number; \ ++ register long int __a0 asm ("$a0") = _arg0; \ ++ register long int __a1 asm ("$a1") = _arg1; \ ++ register long int __a2 asm ("$a2") = _arg2; \ ++ register long int __a3 asm ("$a3") = _arg3; \ ++ __asm__ volatile ( \ ++ "syscall 0\n\t" \ ++ : "+r" (__a0) \ ++ : "r" (__a7), "r" (__a1), "r" (__a2), "r" (__a3) \ ++ : __SYSCALL_CLOBBERS); \ ++ _sys_result = __a0; \ ++ } \ ++ _sys_result; \ ++}) ++ ++# define internal_syscall5(number, err, arg0, arg1, arg2, arg3, arg4) \ ++({ \ ++ long int _sys_result; \ ++ \ ++ { \ ++ long int _arg0 = (long int) (arg0); \ ++ long int _arg1 = (long int) (arg1); \ ++ long int _arg2 = (long int) (arg2); \ ++ long int _arg3 = (long int) (arg3); \ ++ long int _arg4 = (long int) (arg4); \ ++ register long int __a7 asm ("$a7") = number; \ ++ register long int __a0 asm ("$a0") = _arg0; \ ++ register long int __a1 asm ("$a1") = _arg1; \ ++ register long int __a2 asm ("$a2") = _arg2; \ ++ register long int __a3 asm ("$a3") = _arg3; \ ++ register long int __a4 asm ("$a4") = _arg4; \ ++ __asm__ volatile ( \ ++ "syscall 0\n\t" \ ++ : "+r" (__a0) \ ++ : "r" (__a7), "r"(__a1), "r"(__a2), "r"(__a3), "r" (__a4) \ ++ : __SYSCALL_CLOBBERS); \ ++ _sys_result = __a0; \ ++ } \ ++ _sys_result; \ ++}) ++ ++# define internal_syscall6(number, err, arg0, arg1, arg2, arg3, arg4, arg5) \ ++({ \ ++ long int _sys_result; \ ++ \ ++ { \ ++ long int _arg0 = (long int) (arg0); \ ++ long int _arg1 = (long int) (arg1); \ ++ long int _arg2 = (long int) (arg2); \ ++ long int _arg3 = (long int) (arg3); \ ++ long int _arg4 = (long int) (arg4); \ ++ long int _arg5 = (long int) (arg5); \ ++ register long int __a7 asm ("$a7") = number; \ ++ register long int __a0 asm ("$a0") = _arg0; \ ++ register long int __a1 asm ("$a1") = _arg1; \ ++ register long int __a2 asm ("$a2") = _arg2; \ ++ register long int __a3 asm ("$a3") = _arg3; \ ++ register long int __a4 asm ("$a4") = _arg4; \ ++ register long int __a5 asm ("$a5") = _arg5; \ ++ __asm__ volatile ( \ ++ "syscall 0\n\t" \ ++ : "+r" (__a0) \ ++ : "r" (__a7), "r" (__a1), "r" (__a2), "r" (__a3), \ ++ "r" (__a4), "r" (__a5) \ ++ : __SYSCALL_CLOBBERS); \ ++ _sys_result = __a0; \ ++ } \ ++ _sys_result; \ ++}) ++ ++# define internal_syscall7(number, err, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ ++({ \ ++ long int _sys_result; \ ++ \ ++ { \ ++ long int _arg0 = (long int) (arg0); \ ++ long int _arg1 = (long int) (arg1); \ ++ long int _arg2 = (long int) (arg2); \ ++ long int _arg3 = (long int) (arg3); \ ++ long int _arg4 = (long int) (arg4); \ ++ long int _arg5 = (long int) (arg5); \ ++ long int _arg6 = (long int) (arg6); \ ++ register long int __a7 asm ("$a7") = number; \ ++ register long int __a0 asm ("$a0") = _arg0; \ ++ register long int __a1 asm ("$a1") = _arg1; \ ++ register long int __a2 asm ("$a2") = _arg2; \ ++ register long int __a3 asm ("$a3") = _arg3; \ ++ register long int __a4 asm ("$a4") = _arg4; \ ++ register long int __a5 asm ("$a5") = _arg5; \ ++ register long int __a6 asm ("$a6") = _arg6; \ ++ __asm__ volatile ( \ ++ "syscall 0\n\t" \ ++ : "+r" (__a0) \ ++ : "r" (__a7), "r" (__a1), "r" (__a2), "r" (__a3), \ ++ "r" (__a4), "r" (__a5), "r" (__a6) \ ++ : __SYSCALL_CLOBBERS); \ ++ _sys_result = __a0; \ ++ } \ ++ _sys_result; \ ++}) ++ ++# define __SYSCALL_CLOBBERS \ ++ "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7", "$t8",\ ++ "memory" ++ ++extern long int __syscall_error (long int neg_errno); ++ ++#endif /* ! __ASSEMBLER__ */ ++ ++/* Pointer mangling is not supported. */ ++#define PTR_MANGLE(var) (void) (var) ++#define PTR_DEMANGLE(var) (void) (var) ++ ++#endif /* linux/loongarch/sysdep.h */ +diff --git a/sysdeps/unix/sysv/linux/loongarch/ucontext-macros.h b/sysdeps/unix/sysv/linux/loongarch/ucontext-macros.h +new file mode 100644 +index 00000000..abd22247 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/ucontext-macros.h +@@ -0,0 +1,44 @@ ++/* Macros for ucontext routines. ++ Copyright (C) 2017-2018 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 ++ . */ ++ ++#ifndef _LINUX_LOONGARCH_UCONTEXT_MACROS_H ++#define _LINUX_LOONGARCH_UCONTEXT_MACROS_H ++ ++#include ++#include ++ ++#include "ucontext_i.h" ++ ++#define SAVE_FP_REG(name, num, base) \ ++ FREG_S name, base, ((num) * SZFREG + MCONTEXT_FPREGS) ++ ++#define RESTORE_FP_REG(name, num, base) \ ++ FREG_L name, base, ((num) * SZFREG + MCONTEXT_FPREGS) ++ ++#define SAVE_INT_REG(name, num, base) \ ++ REG_S name, base, ((num) * SZREG + MCONTEXT_GREGS) ++ ++#define RESTORE_INT_REG(name, num, base) \ ++ REG_L name, base, ((num) * SZREG + MCONTEXT_GREGS) ++ ++#define SAVE_REG(name, offset, base) \ ++ REG_S name, base, (offset) ++ ++#define RESTORE_REG(name, offset, base) \ ++ REG_L name, base, (offset) ++#endif /* _LINUX_LOONGARCH_UCONTEXT_MACROS_H */ +diff --git a/sysdeps/unix/sysv/linux/loongarch/ucontext_i.sym b/sysdeps/unix/sysv/linux/loongarch/ucontext_i.sym +new file mode 100644 +index 00000000..d7f612fe +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/ucontext_i.sym +@@ -0,0 +1,33 @@ ++#include ++#include ++#include ++#include ++ ++-- Constants used by the rt_sigprocmask call. ++ ++SIG_BLOCK ++SIG_SETMASK ++ ++_NSIG8 (_NSIG / 8) ++ ++-- Offsets of the fields in the ucontext_t structure. ++#define ucontext(member) offsetof (ucontext_t, member) ++#define stack(member) ucontext (uc_stack.member) ++#define mcontext(member) ucontext (uc_mcontext.member) ++ ++UCONTEXT_FLAGS ucontext (__uc_flags) ++UCONTEXT_LINK ucontext (uc_link) ++UCONTEXT_STACK ucontext (uc_stack) ++UCONTEXT_MCONTEXT ucontext (uc_mcontext) ++UCONTEXT_SIGMASK ucontext (uc_sigmask) ++ ++STACK_SP stack (ss_sp) ++STACK_SIZE stack (ss_size) ++STACK_FLAGS stack (ss_flags) ++ ++MCONTEXT_PC mcontext (__pc) ++MCONTEXT_FCSR mcontext (__fcsr) ++MCONTEXT_GREGS mcontext (__gregs) ++MCONTEXT_FPREGS mcontext (__fpregs) ++ ++UCONTEXT_SIZE sizeof (ucontext_t) +diff --git a/sysdeps/unix/sysv/linux/loongarch/vfork.S b/sysdeps/unix/sysv/linux/loongarch/vfork.S +new file mode 100644 +index 00000000..83cf141f +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/vfork.S +@@ -0,0 +1,49 @@ ++/* Copyright (C) 1999-2018 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 ++ . */ ++ ++#include ++#define _ERRNO_H 1 ++#include ++ ++/* 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) ++ ++ ++ li.d a0, 0x4111 /* CLONE_VM | CLONE_VFORK | SIGCHLD */ ++ add.d a1, zero, sp ++ ++ /* Do the system call. */ ++ li.d a7, __NR_clone ++ syscall 0 ++ ++ blt a0, zero ,L (error) ++ ++ ret ++ ++L (error): ++ b __syscall_error ++ END (__vfork) ++ ++libc_hidden_def (__vfork) ++ ++weak_alias (__vfork, vfork) ++strong_alias (__vfork, __libc_vfork) +-- +2.20.1 + diff --git a/glibc.spec b/glibc.spec index 6f2eda9..557485a 100644 --- a/glibc.spec +++ b/glibc.spec @@ -976,6 +976,7 @@ Patch1002: glibc-Add-a-testcase-to-check-alignment-of-PT_LOAD-segment-2.patch Patch1003: glibc-elf-Align-argument-of-__munmap-to-page-size-BZ-28676-3.patch Patch1004: glibc-Support-target-specific-ALIGN-for-variable-alignment-4.patch Patch1005: glibc-elf-Fix-tst-align3.patch +Patch1006: glibc-LoongArch-Port.patch ############################################################################## # Continued list of core "glibc" package information: @@ -2808,6 +2809,7 @@ fi %changelog * Wed Dec 28 2022 Rongwei Wang - 2.28-211.0.1 - elf: Properly align PT_LOAD segments +- arch: LoongArch Port * Thu Aug 25 2022 Florian Weimer - 2.28-211 - Preserve GLRO (dl_naudit) internal ABI (#2119304)