anolis-glibc/glibc-LoongArch-Port.patch
wanghongliang c7e1f55389 glibc LoongArch Port.
Signed-off-by: wanghongliang <wanghongliang@loongson.cn>
2022-12-28 10:04:48 +08:00

16504 lines
444 KiB
Diff
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

From b8f82ee8df870058d80a7a51bea14465235f06d5 Mon Sep 17 00:00:00 2001
From: wanghongliang <wanghongliang@loongson.cn>
Date: Thu, 23 Jun 2022 10:29:34 +0800
Subject: [PATCH] glibc LoongArch Port.
add LoongArch architecture support.
Signed-off-by: wanghongliang <wanghongliang@loongson.cn>
---
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
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#include <sys/asm.h>
+
+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 <stdlib/at_quick_exit.c>
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 <stdlib/atexit.c>
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 <bits/endian.h> directly; include <endian.h> 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
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _FENV_H
+# error "Never use <bits/fenv.h> directly; include <fenv.h> instead."
+#endif
+
+
+/* Define bits representing the exception. We use the bit positions
+ of the appropriate bits in the 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
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _LINK_H
+# error "Never include <bits/link.h> directly; use <link.h> 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
+ <http://www.gnu.org/licenses/>. */
+
+#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
+ <http://www.gnu.org/licenses/>. */
+
+#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
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _DL_IREL_H
+#define _DL_IREL_H
+
+#include <stdio.h>
+#include <unistd.h>
+
+#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
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef dl_machine_h
+#define dl_machine_h
+
+#define ELF_MACHINE_NAME "LoongArch"
+
+#include <entry.h>
+#include <elf/elf.h>
+#include <sys/asm.h>
+#include <dl-tls.h>
+
+#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 ?: "<program name unknown>",
+ 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
+ <http://www.gnu.org/licenses/>. */
+
+
+/* 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
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#include <sys/asm.h>
+
+/* 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
+ <http://www.gnu.org/licenses/>. */
+
+#include <stdlib.h>
+#include <soft-fp/soft-fp.h>
+#include <soft-fp/quad.h>
+
+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 <sysdeps/init_array/elf-init.c>
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 <hartvige@mips.com>, 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
+ <http://www.gnu.org/licenses/>. */
+
+
+
+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 <hartvige@mips.com>, 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
+ <http://www.gnu.org/licenses/>. */
+
+
+
+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 <aj@suse.de>, 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
+ <http://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include <fenv_libc.h>
+#include <fpu_control.h>
+
+int
+feclearexcept (int excepts)
+{
+ int cw;
+
+ /* Mask out unsupported bits/exceptions. */
+ excepts &= FE_ALL_EXCEPT;
+
+ /* Read the complete control word. */
+ _FPU_GETCW (cw);
+
+ /* Clear exception flag bits and cause bits. If the cause bit is not
+ cleared, the next CTC instruction (just below) will re-generate the
+ exception. */
+
+ cw &= ~(excepts | (excepts << CAUSE_SHIFT));
+
+ /* Put the new data in effect. */
+ _FPU_SETCW (cw);
+
+ /* Success. */
+ return 0;
+}
+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 <aj@suse.de>, 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
+ <http://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include <fenv_libc.h>
+#include <fpu_control.h>
+
+int
+fedisableexcept (int excepts)
+{
+ unsigned int new_exc, old_exc;
+
+ /* Get the current control word. */
+ _FPU_GETCW (new_exc);
+
+ old_exc = (new_exc & ENABLE_MASK) << ENABLE_SHIFT;
+
+ excepts &= FE_ALL_EXCEPT;
+
+ new_exc &= ~(excepts >> ENABLE_SHIFT);
+ _FPU_SETCW (new_exc);
+
+ return old_exc;
+}
diff --git a/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 <aj@suse.de>, 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
+ <http://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include <fenv_libc.h>
+#include <fpu_control.h>
+
+int
+feenableexcept (int excepts)
+{
+ unsigned int new_exc, old_exc;
+
+ /* Get the current control word. */
+ _FPU_GETCW (new_exc);
+
+ old_exc = (new_exc & ENABLE_MASK) << ENABLE_SHIFT;
+
+ excepts &= FE_ALL_EXCEPT;
+
+ new_exc |= excepts >> ENABLE_SHIFT;
+ _FPU_SETCW (new_exc);
+
+ return old_exc;
+}
diff --git a/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 <aj@suse.de>, 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
+ <http://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+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 <aj@suse.de>, 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
+ <http://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include <fenv_libc.h>
+#include <fpu_control.h>
+
+int
+fegetexcept (void)
+{
+ unsigned int exc;
+
+ /* Get the current control word. */
+ _FPU_GETCW (exc);
+
+ return (exc & ENABLE_MASK) << ENABLE_SHIFT;
+}
diff --git a/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
+ <http://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+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 <aj@arthur.rhein-neckar.de>, 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
+ <http://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+int
+__fegetround (void)
+{
+ int cw;
+
+ /* Get control word. */
+ _FPU_GETCW (cw);
+
+ return cw & _FPU_RC_MASK;
+}
+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 <aj@suse.de>, 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
+ <http://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+int
+__feholdexcept (fenv_t *envp)
+{
+ fpu_control_t cw;
+
+ /* Save the current state. */
+ _FPU_GETCW (cw);
+ envp->__fp_control_register = cw;
+
+ /* Clear all exception enable bits and flags. */
+ cw &= ~(_FPU_MASK_V|_FPU_MASK_Z|_FPU_MASK_O|_FPU_MASK_U|_FPU_MASK_I|FE_ALL_EXCEPT);
+ _FPU_SETCW (cw);
+
+ return 0;
+}
+
+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 <aj@suse.de>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _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 <aj@suse.de>, 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
+ <http://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+int
+__fesetenv (const fenv_t *envp)
+{
+ fpu_control_t cw;
+
+ /* Read first current state to flush fpu pipeline. */
+ _FPU_GETCW (cw);
+
+ if (envp == FE_DFL_ENV)
+ _FPU_SETCW (_FPU_DEFAULT);
+ else if (envp == FE_NOMASK_ENV)
+ _FPU_SETCW (_FPU_IEEE);
+ else
+ _FPU_SETCW (envp->__fp_control_register);
+
+ /* Success. */
+ return 0;
+}
+
+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
+ <http://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+int
+fesetexcept (int excepts)
+{
+ fpu_control_t temp;
+
+ _FPU_GETCW (temp);
+ temp |= excepts & FE_ALL_EXCEPT;
+ _FPU_SETCW (temp);
+
+ return 0;
+}
diff --git a/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
+ <http://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+#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 <aj@arthur.rhein-neckar.de>, 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
+ <http://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+int
+__fesetround (int round)
+{
+ fpu_control_t cw;
+
+ if ((round & ~_FPU_RC_MASK) != 0)
+ /* ROUND is no valid rounding mode. */
+ return 1;
+
+ /* Get current state. */
+ _FPU_GETCW (cw);
+
+ /* Set rounding bits. */
+ cw &= ~_FPU_RC_MASK;
+ cw |= round;
+ /* Set new state. */
+ _FPU_SETCW (cw);
+
+ return 0;
+}
+
+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 <aj@suse.de>, 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
+ <http://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+int
+__feupdateenv (const fenv_t *envp)
+{
+ int temp;
+
+ /* Save current exceptions. */
+ _FPU_GETCW (temp);
+ temp &= FE_ALL_EXCEPT;
+
+ /* Install new environment. */
+ __fesetenv (envp);
+
+ /* Raise the 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 <aj@suse.de>, 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
+ <http://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+int
+fegetexceptflag (fexcept_t *flagp, int excepts)
+{
+ fpu_control_t temp;
+
+ /* Get the current exceptions. */
+ _FPU_GETCW (temp);
+
+ /* We only save the relevant bits here. In particular, care has to be
+ taken with the CAUSE bits, as an inadvertent restore later on could
+ generate unexpected exceptions. */
+
+ *flagp = temp & excepts & FE_ALL_EXCEPT;
+
+ /* Success. */
+ return 0;
+}
diff --git a/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 <aj@suse.de>, 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
+ <http://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include <fpu_control.h>
+#include <float.h>
+
+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 <hartvige@mips.com>, 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
+ <http://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+int
+fesetexceptflag (const fexcept_t *flagp, int excepts)
+{
+ fpu_control_t temp;
+
+ /* Get the current exceptions. */
+ _FPU_GETCW (temp);
+
+ /* Make sure the flags we want restored are legal. */
+ excepts &= FE_ALL_EXCEPT;
+
+ /* Now clear the bits called for, and copy them in from flagp. Note that
+ we ignore all non-flag bits from *flagp, so they don't matter. */
+ temp = (temp & ~excepts) | (*flagp & excepts);
+
+ _FPU_SETCW (temp);
+
+ /* Success. */
+ return 0;
+}
diff --git a/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 <aj@arthur.rhein-neckar.de>, 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
+ <http://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+int
+fetestexcept (int excepts)
+{
+ int cw;
+
+ /* Get current control word. */
+ _FPU_GETCW (cw);
+
+ return cw & excepts & FE_ALL_EXCEPT;
+}
+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
+ <http://www.gnu.org/licenses/>. */
+
+#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 <features.h>
+
+#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 <io/fstat.c>
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 <io/fstat64.c>
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 <io/fstatat.c>
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 <io/fstatat64.c>
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
+ <http://www.gnu.org/licenses/>. */
+
+#define FIRST_PSEUDO_REGISTER 74
+
+#include <sysdeps/generic/gccframe.h>
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
+ <http://www.gnu.org/licenses/>. */
+
+#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 <hp-timing-common.h>
+
+#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
+ <http://www.gnu.org/licenses/>. */
+
+#include <jmpbuf-unwind.h>
+
+/* 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
+ <http://www.gnu.org/licenses/>. */
+
+#include <setjmp.h>
+#include <stdint.h>
+#include <unwind.h>
+#include <sysdep.h>
+
+/* 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
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _LOONGARCH_LDSODEFS_H
+#define _LOONGARCH_LDSODEFS_H 1
+
+#include <elf.h>
+
+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 <ldsodefs.h>
+
+#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
+ <http://www.gnu.org/licenses/>. */
+
+#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
+ <http://www.gnu.org/licenses/>. */
+
+#include <csu/libc-tls.c>
+#include <dl-tls.h>
+
+/* 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 <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <regdef.h>
+#include <sys/asm.h>
+#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 <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <regdef.h>
+#include <sys/asm.h>
+#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<num<64
+ 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_64bytes:
+ sub.d a7, a0, a1
+ bltu a7, a2, copy_backward
+
+copy_forward:
+ srli.d a0, a0, 3
+ slli.d a0, a0, 3
+ beq a0, t8, all_align
+ addi.d a0, a0, 0x8
+ sub.d a7, t8, a0
+ sub.d a1, a1, a7
+ add.d a2, a7, a2
+
+start_unalign_proc:
+ pcaddi t1, 18
+ slli.d a6, a7, 3
+ add.d t1, t1, a6
+ jirl zero, t1, 0
+
+start_7_unalign:
+ ld.b t0, a1, -7
+ st.b t0, a0, -7
+start_6_unalign:
+ ld.b t0, a1, -6
+ st.b t0, a0, -6
+start_5_unalign:
+ ld.b t0, a1, -5
+ st.b t0, a0, -5
+start_4_unalign:
+ ld.b t0, a1, -4
+ st.b t0, a0, -4
+start_3_unalign:
+ ld.b t0, a1, -3
+ st.b t0, a0, -3
+start_2_unalign:
+ ld.b t0, a1, -2
+ st.b t0, a0, -2
+start_1_unalign:
+ ld.b t0, a1, -1
+ 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, 36
+ andi t2, a2, 0x78
+ add.d a1, a1, t2
+ add.d a0, a0, t2
+ sub.d t1, t1, t2
+ jirl zero, t1, 0
+
+end_120_128_unalign:
+ ld.d t0, a1, -120
+ st.d t0, a0, -120
+end_112_120_unalign:
+ ld.d t0, a1, -112
+ st.d t0, a0, -112
+end_104_112_unalign:
+ ld.d t0, a1, -104
+ st.d t0, a0, -104
+end_96_104_unalign:
+ ld.d t0, a1, -96
+ st.d t0, a0, -96
+end_88_96_unalign:
+ ld.d t0, a1, -88
+ st.d t0, a0, -88
+end_80_88_unalign:
+ ld.d t0, a1, -80
+ st.d t0, a0, -80
+end_72_80_unalign:
+ ld.d t0, a1, -72
+ st.d t0, a0, -72
+end_64_72_unalign:
+ ld.d t0, a1, -64
+ st.d t0, a0, -64
+end_56_64_unalign:
+ ld.d t0, a1, -56
+ st.d t0, a0, -56
+end_48_56_unalign:
+ ld.d t0, a1, -48
+ st.d t0, a0, -48
+end_40_48_unalign:
+ ld.d t0, a1, -40
+ st.d t0, a0, -40
+end_32_40_unalign:
+ ld.d t0, a1, -32
+ st.d t0, a0, -32
+end_24_32_unalign:
+ ld.d t0, a1, -24
+ st.d t0, a0, -24
+end_16_24_unalign:
+ ld.d t0, a1, -16
+ st.d t0, a0, -16
+end_8_16_unalign:
+ ld.d t0, a1, -8
+ st.d t0, a0, -8
+end_0_8_unalign:
+
+ 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 a1, a1, 0x8
+ addi.d a0, a0, 0x8
+ ld.d t0, a1, -8
+ st.d t0, a0, -8
+ addi.d a2, a2, -8
+ b start_over
+
+all_align_back:
+ addi.d a4, a4, -0x8
+ addi.d a3, a3, -0x8
+ ld.d t0, a4, 0
+ st.d t0, a3, 0
+ addi.d a2, a2, -8
+ b start_over_back
+
+copy_backward:
+ move a5, a3
+ srli.d a3, a3, 3
+ slli.d a3, a3, 3
+ beq a3, a5, all_align_back
+ sub.d a7, a3, a5
+ add.d a4, a4, a7
+ add.d a2, a7, a2
+
+ pcaddi t1, 18
+ slli.d a6, a7, 3
+ add.d t1, t1, a6
+ jirl zero, t1, 0
+
+ ld.b t0, a4, 6
+ st.b t0, a3, 6
+ ld.b t0, a4, 5
+ st.b t0, a3, 5
+ ld.b t0, a4, 4
+ st.b t0, a3, 4
+ ld.b t0, a4, 3
+ st.b t0, a3, 3
+ ld.b t0, a4, 2
+ st.b t0, a3, 2
+ ld.b t0, a4, 1
+ st.b t0, a3, 1
+ ld.b t0, a4, 0
+ st.b t0, a3, 0
+start_over_back:
+
+ addi.d a2, a2, -0x80
+ blt a2, zero, end_unalign_proc_back
+
+loop_less_back:
+ LD_64(a4, -64)
+ ST_64(a3, -64)
+ LD_64(a4, -128)
+ ST_64(a3, -128)
+
+ addi.d a4, a4, -0x80
+ addi.d a3, a3, -0x80
+ addi.d a2, a2, -0x80
+ bge a2, zero, loop_less_back
+
+end_unalign_proc_back:
+ addi.d a2, a2, 0x80
+
+ pcaddi t1, 36
+ andi t2, a2, 0x78
+ sub.d a4, a4, t2
+ sub.d a3, a3, t2
+ sub.d t1, t1, t2
+ jirl zero, t1, 0
+
+ ld.d t0, a4, 112
+ st.d t0, a3, 112
+ ld.d t0, a4, 104
+ st.d t0, a3, 104
+ ld.d t0, a4, 96
+ st.d t0, a3, 96
+ ld.d t0, a4, 88
+ st.d t0, a3, 88
+ ld.d t0, a4, 80
+ st.d t0, a3, 80
+ ld.d t0, a4, 72
+ st.d t0, a3, 72
+ ld.d t0, a4, 64
+ st.d t0, a3, 64
+ ld.d t0, a4, 56
+ st.d t0, a3, 56
+ ld.d t0, a4, 48
+ st.d t0, a3, 48
+ ld.d t0, a4, 40
+ st.d t0, a3, 40
+ ld.d t0, a4, 32
+ st.d t0, a3, 32
+ ld.d t0, a4, 24
+ st.d t0, a3, 24
+ ld.d t0, a4, 16
+ st.d t0, a3, 16
+ ld.d t0, a4, 8
+ st.d t0, a3, 8
+ ld.d t0, a4, 0
+ st.d t0, a3, 0
+
+ andi a2, a2, 0x7
+ pcaddi t1, 18
+ slli.d a2, a2, 3
+ sub.d t1, t1, a2
+ jirl zero, t1, 0
+
+ ld.b t0, a1, 6
+ st.b t0, a0, 6
+ ld.b t0, a1, 5
+ st.b t0, a0, 5
+ ld.b t0, a1, 4
+ st.b t0, a0, 4
+ ld.b t0, a1, 3
+ st.b t0, a0, 3
+ ld.b t0, a1, 2
+ st.b t0, a0, 2
+ ld.b t0, a1, 1
+ st.b t0, a0, 1
+ ld.b t0, a1, 0
+ st.b t0, a0, 0
+
+ move v0, t8
+ jr ra
+
+END(MEMMOVE_NAME)
+#ifndef ANDROID_CHANGES
+#ifdef _LIBC
+libc_hidden_builtin_def (MEMMOVE_NAME)
+#endif
+#endif
diff --git a/sysdeps/loongarch/lp64/memset.S b/sysdeps/loongarch/lp64/memset.S
new file mode 100644
index 00000000..8bc152ee
--- /dev/null
+++ b/sysdeps/loongarch/lp64/memset.S
@@ -0,0 +1,175 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <sys/asm.h>
+#include <sys/regdef.h>
+#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<num<64
+ st.d a1, a0, 8
+ st.d a1, a0, 16
+ st.d a1, a0, 24
+ st.d a1, t7, -32
+ st.d a1, t7, -24
+ st.d a1, t7, -16
+ st.d a1, t7, -8
+
+ jr ra
+
+less_32bytes:
+ st.d a1, a0, 0
+ st.d a1, a0, 8
+ st.d a1, t7, -16
+ st.d a1, t7, -8
+
+ jr ra
+
+less_16bytes:
+ srai.d t8, a2, 3 #num/8
+ beqz t8, less_8bytes
+ st.d a1, a0, 0
+ st.d a1, t7, -8
+
+ jr ra
+
+less_8bytes:
+ srai.d t8, a2, 2
+ beqz t8, less_4bytes
+ st.w a1, a0, 0
+ st.w a1, t7, -4
+
+ jr ra
+
+less_4bytes:
+ srai.d t8, a2, 1
+ beqz t8, less_2bytes
+ st.h a1, a0, 0
+ st.h a1, t7, -2
+
+ jr ra
+
+less_2bytes:
+ beqz a2, less_1bytes
+ st.b a1, a0, 0
+
+ jr ra
+
+less_1bytes:
+ jr ra
+
+more_64bytes:
+ srli.d a0, a0, 3
+ slli.d a0, a0, 3
+ addi.d a0, a0, 0x8
+ st.d a1, t0, 0
+ sub.d t2, t0, a0
+ add.d a2, t2, a2
+
+ addi.d a2, a2, -0x80
+ blt a2, zero, end_unalign_proc
+
+loop_less:
+ ST_128(0)
+ addi.d a0, a0, 0x80
+ addi.d a2, a2, -0x80
+ bge a2, zero, loop_less
+
+end_unalign_proc:
+ addi.d a2, a2, 0x80
+
+ pcaddi t1, 20
+ andi t5, a2, 0x78
+ srli.d t5, t5, 1
+ sub.d t1, t1, t5
+ jirl zero, t1, 0
+
+end_120_128_unalign:
+ st.d a1, a0, 112
+end_112_120_unalign:
+ st.d a1, a0, 104
+end_104_112_unalign:
+ st.d a1, a0, 96
+end_96_104_unalign:
+ st.d a1, a0, 88
+end_88_96_unalign:
+ st.d a1, a0, 80
+end_80_88_unalign:
+ st.d a1, a0, 72
+end_72_80_unalign:
+ st.d a1, a0, 64
+end_64_72_unalign:
+ st.d a1, a0, 56
+end_56_64_unalign:
+ st.d a1, a0, 48
+end_48_56_unalign:
+ st.d a1, a0, 40
+end_40_48_unalign:
+ st.d a1, a0, 32
+end_32_40_unalign:
+ st.d a1, a0, 24
+end_24_32_unalign:
+ st.d a1, a0, 16
+end_16_24_unalign:
+ st.d a1, a0, 8
+end_8_16_unalign:
+ st.d a1, a0, 0
+end_0_8_unalign:
+
+ st.d a1, t7, -8
+
+ move v0, t0
+ jr ra
+
+END(MEMSET)
+
+#ifndef ANDROID_CHANGES
+#ifdef _LIBC
+libc_hidden_builtin_def (memset)
+#endif
+#endif
diff --git a/sysdeps/loongarch/lp64/s_cosf.S b/sysdeps/loongarch/lp64/s_cosf.S
new file mode 100644
index 00000000..5bfabefb
--- /dev/null
+++ b/sysdeps/loongarch/lp64/s_cosf.S
@@ -0,0 +1,409 @@
+#include <sysdep.h>
+#include <sys/asm.h>
+#include <libm-alias-float.h>
+
+/* 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|<Pi/4, results are
+ * cos(x) = poly_sin * sign_cos
+ * sin(x) = poly_cos * sign_sin
+ * } else {
+ * sin(x) = poly_sin * sign_sin
+ * cos(x) = poly_cos * sign_cos
+ * }
+ * 6) if |x| < 2^23, large args:
+ * 6.1) Range reduction:
+ * k=trunc(|x|/(Pi/4)), j=(k+1)&0xfffffffe, n=k+1, t=|x|-j*Pi/4
+ * 6.2) Reconstruction same as (5.2).
+ * 7) if |x| >= 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|<Pi/4:
+ * y = t*t; z = y*y;
+ * s = sign(x) * (-1.0)^((n>>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|<Pi/4:
+ * y = t*t; z = y*y;
+ * s = sign(x) * (-1.0)^((n>>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|<Pi/4 */
+ li.w t1, 0x3d000000 /* const 2^-5 */
+ blt t0, t1, L(less_2pn5) /* |x| < 2^-5 branch */
+ /* Here if 2^-5<=|x|<Pi/4 */
+ /*
+ * Chebyshev polynomial of the form:
+ * 1.0+x^2*(C0+x^2*(C1+x^2*(C2+x^2*(C3+x^2*C4)))).
+ */
+ la.local t0, L(DP_) /*DP_ base addr*/
+ fld.d fa3, t0, 96 /* C4 */
+ fmul.d fa1, fa1, fa1 /* y=x^2 */
+ fld.d fa4, t0, 80 /* C2 */
+ fmul.d fa2, fa1, fa1 /* z=x^4 */
+ fld.d fa5, t0, 88 /* C3 */
+ fld.d fa6, t0, 72 /* C1 */
+ fmadd.d fa0, fa2, fa3, fa4 /* cx = C2+z*C4 */
+ fld.d fa3, t0, 64 /* C0 */
+ fmadd.d fa5, fa2, fa5, fa6 /* cy = C1+z*C3 */
+ la.local t0, L(DP_ONES)
+ fmadd.d fa0, fa0, fa2, fa3 /* cx = C0+z*cx */
+ fld.d fa2, t0, 0 /* 1.0 */
+ fmadd.d fa0, fa1, fa5, fa0 /* cx = cx+y*cy */
+ fmadd.d fa0, fa0, fa1, fa2 /* 1.0+y*cx */
+ /*
+ fld.d fa6, t0, 96
+ fld.d fa5, t0, 88
+ fld.d fa4, t0, 80
+ fmul.d fa1, fa1, fa1
+ fld.d fa3, t0, 72
+ fld.d fa2, t0, 64
+ la.local t0, L(DP_ONES)
+ fld.d fa6, t0, 0
+ fmadd.d fa0, fa1, fa5, fa0
+ fmadd.d fa0, fa1, fa4, fa0
+ fmadd.d fa0, fa1, fa3, fa0
+ fmadd.d fa0, fa1, fa2, fa0
+ fmadd.d fa0, fa1, fa5, fa4
+ */
+ fcvt.s.d fa0, fa0
+ jr ra
+
+L(less_2pn5):
+ /* Here if |x|<2^-5 */
+ li.w t1, 0x32000000 /* 2^-27? */
+ blt t0, t1, L(less_2pn27)
+ /* Here if 2^-27<=|x|<2^-5 */
+ fmul.d fa0, fa1, fa1 /* theta2=x^2 */
+ la.local t0, L(DP_)
+ fld.d fa2, t0, 48 /* DP_COS2_1 */
+ fmul.d fa1, fa1, fa0 /* x*theta2 */
+ fld.d fa3, t0, 40 /* DP_COS2_0 */
+ la.local t0, L(DP_ONES)
+ fld.d fa4, t0, 0 /* 1.0 */
+ fmadd.d fa1, fa1, fa2, fa3 /* DP_COS2_0+x^2*DP_COS2_1 */
+ fmadd.d fa0, fa0, fa1, fa4 /* cx = 1.0 + theta2 * cx */
+ fcvt.s.d fa0, fa0
+ jr ra
+
+L(less_2pn27):
+ /* Here if |x|<2^-27 */
+ fabs.s fa0, fa0
+ LOADFS( fa1, t0, L(SP_ONE) ) /* 1.0 */
+ fsub.s fa0, fa1, fa0 /* 1.0 - abstheta */
+ /* No need to convert */
+ jr ra
+
+L(inf_or_nan):
+ /* Here if |x| is Inf or NAN */
+ bne t0, t1, L_skip_errno_setting /* in case of x is NaN */
+ la.tls.ie t0, errno
+ li.w t1, 0x21
+ stx.w t1, t0, tp
+L_skip_errno_setting:
+ /* Here if |x| is Inf or NAN. Continued. */
+ fsub.s fa0, fa0, fa0 /* Result is NaN */
+ jr ra
+END(COSF)
+
+ .section .rodata
+ .align 3
+ .type L(PIO2J), @object
+ .size L(PIO2J), 48
+L(PIO2J): /* Table of j*Pi/2, for j=0,1,..,5 */
+ .word 0x00000000
+ .word 0x00000000
+ .word 0x54442d18
+ .word 0x3ff921fb
+ .word 0x54442d18
+ .word 0x400921fb
+ .word 0x7f3321d2
+ .word 0x4012d97c
+ .word 0x54442d18
+ .word 0x401921fb
+ .word 0x2955385e
+ .word 0x401f6a7a
+
+ .align 3
+ .type L(invpio4_table), @object
+ .size L(invpio4_table), 64
+L(invpio4_table): /* 4/Pi broken into sum of positive DP values */
+ .word 0x00000000
+ .word 0x00000000
+ .word 0x6c000000
+ .word 0x3ff45f30
+ .word 0x2a000000
+ .word 0x3e3c9c88
+ .word 0xa8000000
+ .word 0x3c54fe13
+ .word 0xd0000000
+ .word 0x3aaf47d4
+ .word 0x6c000000
+ .word 0x38fbb81b
+ .word 0xe0000000
+ .word 0x3714acc9
+ .word 0x7c000000
+ .word 0x3560e410
+
+/* Coefficients of polynomial
+ for sin(x)~=x+x^3*DP_SIN2_0+x^5*DP_SIN2_1, |x|<2^-5. */
+/* Coefficients of polynomial
+ for sin(t)~=t+t^3*(S0+t^2*(S1+t^2*(S2+t^2*(S3+t^2*S4)))), |t|<Pi/4.
+ for cos(t)~=1.0+t^2*(C0+t^2*(C1+t^2*(C2+t^2*(C3+t^2*C4)))), |t|<Pi/4.
+*/
+ .align 3
+ .type L(DP_), @object
+ .size L(DP_), 128
+L(DP_):
+ .word 0x55551cd9
+ .word 0xbfc55555 /*S0*/
+ .word 0x10c2688b
+ .word 0x3f811111 /*S1*/
+ .word 0x8b4bd1f9
+ .word 0xbf2a019f /*S2*/
+ .word 0x64e6b5b4
+ .word 0x3ec71d72 /*S3*/
+ .word 0x1674b58a
+ .word 0xbe5a947e /*S4*/
+ .word 0xff5cc6fd
+ .word 0xbfdfffff /*CC0 +40*/
+ .word 0xb178dac5
+ .word 0x3fa55514 /*CC1 +48*/
+ .word 0x6dc9c883
+ .word 0x3ff45f30 /* inv_PI_4 */
+ .word 0xfffe98ae
+ .word 0xbfdfffff /*C0*/
+ .word 0x545c50c7
+ .word 0x3fa55555 /*C1*/
+ .word 0x348b6874
+ .word 0xbf56c16b /*C2*/
+ .word 0x9ac43cc0
+ .word 0x3efa00eb /*C3*/
+ .word 0xdd8844d7
+ .word 0xbe923c97 /*C4*/
+ .word 0x54400000
+ .word 0xbff921fb /* PI_2_hi */
+ .word 0x1a626332
+ .word 0xbdd0b461 /* PI_2_lo */
+ .word 0x54442d18
+ .word 0x3fe921fb /* PI_4 */
+
+ .align 3
+ .type L(DP_ONES), @object
+ .size L(DP_ONES), 24
+L(DP_ONES):
+ .word 0x00000000
+ .word 0x3ff00000 /* +1.0 */
+ .word 0x00000000
+ .word 0xbff00000 /* -1.0 */
+ .word 0x00000000
+ .word 0x40000000 /* +2.0 */
+
+ .align 2
+L(SP_INVPIO4):
+ .word 0x3fa2f983 /* 4/Pi */
+
+ .align 2
+L(SP_ONE):
+ .word 0x3f800000 /* 1.0 */
+
+libm_alias_float (__cos, cos)
diff --git a/sysdeps/loongarch/lp64/s_sinf.S b/sysdeps/loongarch/lp64/s_sinf.S
new file mode 100644
index 00000000..91c9db9e
--- /dev/null
+++ b/sysdeps/loongarch/lp64/s_sinf.S
@@ -0,0 +1,392 @@
+#include <sysdep.h>
+#include <sys/asm.h>
+#include <libm-alias-float.h>
+
+/* 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|<Pi/4, results are
+ * cos(x) = poly_sin * sign_cos
+ * sin(x) = poly_cos * sign_sin
+ * } else {
+ * sin(x) = poly_sin * sign_sin
+ * cos(x) = poly_cos * sign_cos
+ * }
+ * 6) if |x| < 2^23, large args:
+ * 6.1) Range reduction:
+ * k=trunc(|x|/(Pi/4)), j=(k+1)&0xfffffffe, n=k+1, t=|x|-j*Pi/4
+ * 6.2) Reconstruction same as (5.2).
+ * 7) if |x| >= 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|<Pi/4:
+ * y = t*t; z = y*y;
+ * s = sign(x) * (-1.0)^((n>>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|<Pi/4:
+ * y = t*t; z = y*y;
+ * s = sign(x) * (-1.0)^((n>>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|<Pi/4 */
+ li.w t1, 0x3d000000 /* const 2^-5 */
+ blt t0, t1, L(less_2pn5) /* |x| < 2^-5 branch */
+ /* Here if 2^-5<=|x|<Pi/4 */
+ /*
+ * Chebyshev polynomial of the form:
+ * 1.0+x^2*(C0+x^2*(C1+x^2*(C2+x^2*(C3+x^2*C4)))).
+ */
+ la.local t0, L(DP_) /*DP_ base addr*/
+ fld.d fa3, t0, 32 /* S4 */
+ fmul.d fa0, fa1, fa1 /* y=x^2 */
+ fld.d fa4, t0, 16 /* S2 */
+ fmul.d fa2, fa0, fa0 /* z=x^4 */
+ fld.d fa5, t0, 24 /* S3 */
+ fmul.d fa7, fa0, fa1 /* w=x^3 */
+ fld.d fa6, t0, 8 /* S1 */
+ fmadd.d fa4, fa2, fa3, fa4 /* sx = S2+z*S4 */
+ fld.d fa3, t0, 0 /* S0 */
+ fmadd.d fa5, fa5, fa2, fa6 /* sy = S1+z*S3 */
+ fmadd.d fa4, fa4, fa2, fa3 /* sx = S0+z*sx */
+ fmadd.d fa4, fa0, fa5, fa4 /* sx = sx+y*sy */
+ fmadd.d fa0, fa4, fa7, fa1 /* sx = x +w*sx */
+ fcvt.s.d fa0, fa0
+ jr ra
+
+L(less_2pn5):
+ /* Here if |x|<2^-5 */
+ li.w t1, 0x32000000 /* 2^-27? */
+ blt t0, t1, L(less_2pn27)
+ /* Here if 2^-27<=|x|<2^-5 */
+ fmul.d fa0, fa1, fa1 /* theta2=x^2 */
+ la.local t0, L(DP_)
+ fld.d fa2, t0, 48 /* SS_1 */
+ fmul.d fa4, fa1, fa0 /* theta3=x^3 */
+ fld.d fa3, t0, 40 /* SS_0 */
+ fmadd.d fa0, fa0, fa2, fa3 /* sx = SS_0+theta2*SS_1 */
+ fmadd.d fa0, fa0, fa4, fa1 /* sx = theta + theta3 * sx */
+ fcvt.s.d fa0, fa0
+ jr ra
+
+L(less_2pn27):
+ /* Here if |x|<2^-27 */
+ beqz t0, L(eq_zero)
+ la.local t0, L(DP_ONES)
+ fld.d fa2, t0, 24
+ /*fmul.d fa2, fa2, fa1
+ *fsub.d fa0, fa1, fa2*/
+ fnmsub.d fa0, fa1, fa2, fa1
+ fcvt.s.d fa0, fa0
+L(eq_zero):
+ jr ra
+
+L(inf_or_nan):
+ /* Here if |x| is Inf or NAN */
+ bne t0, t1, L_skip_errno_setting /* in case of x is NaN */
+ la.tls.ie t0, errno
+ li.w t1, 0x21
+ stx.w t1, t0, tp
+L_skip_errno_setting:
+ /* Here if |x| is Inf or NAN. Continued. */
+ fsub.s fa0, fa0, fa0 /* Result is NaN */
+ jr ra
+END(SINF)
+
+ .section .rodata
+ .align 3
+ .type L(PIO2J), @object
+ .size L(PIO2J), 48
+L(PIO2J): /* Table of j*Pi/2, for j=0,1,..,5 */
+ .word 0x00000000
+ .word 0x00000000
+ .word 0x54442d18
+ .word 0x3ff921fb
+ .word 0x54442d18
+ .word 0x400921fb
+ .word 0x7f3321d2
+ .word 0x4012d97c
+ .word 0x54442d18
+ .word 0x401921fb
+ .word 0x2955385e
+ .word 0x401f6a7a
+
+ .align 3
+ .type L(invpio4_table), @object
+ .size L(invpio4_table), 64
+L(invpio4_table): /* 4/Pi broken into sum of positive DP values */
+ .word 0x00000000
+ .word 0x00000000
+ .word 0x6c000000
+ .word 0x3ff45f30
+ .word 0x2a000000
+ .word 0x3e3c9c88
+ .word 0xa8000000
+ .word 0x3c54fe13
+ .word 0xd0000000
+ .word 0x3aaf47d4
+ .word 0x6c000000
+ .word 0x38fbb81b
+ .word 0xe0000000
+ .word 0x3714acc9
+ .word 0x7c000000
+ .word 0x3560e410
+
+/* Coefficients of polynomial
+ for sin(x)~=x+x^3*DP_SIN2_0+x^5*DP_SIN2_1, |x|<2^-5. */
+/* Coefficients of polynomial
+ for sin(t)~=t+t^3*(S0+t^2*(S1+t^2*(S2+t^2*(S3+t^2*S4)))), |t|<Pi/4.
+ for cos(t)~=1.0+t^2*(C0+t^2*(C1+t^2*(C2+t^2*(C3+t^2*C4)))), |t|<Pi/4.
+*/
+ .align 3
+ .type L(DP_), @object
+ .size L(DP_), 128
+L(DP_):
+ .word 0x55551cd9
+ .word 0xbfc55555 /*S0*/
+ .word 0x10c2688b
+ .word 0x3f811111 /*S1*/
+ .word 0x8b4bd1f9
+ .word 0xbf2a019f /*S2*/
+ .word 0x64e6b5b4
+ .word 0x3ec71d72 /*S3*/
+ .word 0x1674b58a
+ .word 0xbe5a947e /*S4*/
+ .word 0x5543d49d
+ .word 0xbfc55555 /*SS0 +40*/
+ .word 0x75cec8c5
+ .word 0x3f8110f4 /*SS1 +48*/
+ .word 0x6dc9c883
+ .word 0x3ff45f30 /* inv_PI_4 */
+ .word 0xfffe98ae
+ .word 0xbfdfffff /*C0*/
+ .word 0x545c50c7
+ .word 0x3fa55555 /*C1*/
+ .word 0x348b6874
+ .word 0xbf56c16b /*C2*/
+ .word 0x9ac43cc0
+ .word 0x3efa00eb /*C3*/
+ .word 0xdd8844d7
+ .word 0xbe923c97 /*C4*/
+ .word 0x54400000
+ .word 0xbff921fb /* PI_2_hi */
+ .word 0x1a626332
+ .word 0xbdd0b461 /* PI_2_lo */
+ .word 0x54442d18
+ .word 0x3fe921fb /* PI_4 */
+
+ .align 3
+ .type L(DP_ONES), @object
+ .size L(DP_ONES), 32
+L(DP_ONES):
+ .word 0x00000000
+ .word 0x3ff00000 /* +1.0 */
+ .word 0x00000000
+ .word 0xbff00000 /* -1.0 */
+ .word 0x00000000
+ .word 0x40000000 /* +2.0 */
+ .word 0x00000000
+ .word 0x3cd00000 /* 2^(-50) */
+
+
+libm_alias_float (__sin, sin)
diff --git a/sysdeps/loongarch/lp64/strchr.S b/sysdeps/loongarch/lp64/strchr.S
new file mode 100644
index 00000000..872101db
--- /dev/null
+++ b/sysdeps/loongarch/lp64/strchr.S
@@ -0,0 +1,140 @@
+/* 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 <sysdep.h>
+#include <sys/asm.h>
+
+
+
+
+
+#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 <sysdep.h>
+#include <sys/asm.h>
+
+
+
+
+
+#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 <sys/asm.h>
+#include <sys/regdef.h>
+
+
+#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 <sys/asm.h>
+#include <sys/regdef.h>
+
+
+#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 <sysdep.h>
+#include <sys/asm.h>
+
+
+
+#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 <sys/asm.h>
+#include <sys/regdef.h>
+
+
+#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 <sys/asm.h>
+#include <sys/regdef.h>
+
+
+
+#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 <io/lstat.c>
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 <io/lstat64.c>
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
+ <http://www.gnu.org/licenses/>. */
+
+/* Accept 'frompc' address as argument from the function that calls
+ _mcount for profiling. Use __builtin_return_address (0)
+ for the 'selfpc' address. */
+
+#include <sysdep.h>
+
+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
+ <http://www.gnu.org/licenses/>. */
+
+#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 <fenv.h>
+# include <fenv_libc.h>
+# include <fpu_control.h>
+
+# define _FPU_MASK_ALL (_FPU_MASK_V | _FPU_MASK_Z | _FPU_MASK_O \
+ |_FPU_MASK_U | _FPU_MASK_I | FE_ALL_EXCEPT)
+
+static __always_inline void
+libc_feholdexcept_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 <math_private.h>
+
+#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
+ <http://www.gnu.org/licenses/>. */
+
+#define GETSP() ({ register uintptr_t stack_ptr asm ("$sp"); stack_ptr; })
+
+#include <sysdeps/generic/memusage.h>
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 <io/mknod.c>
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 <io/mknodat.c>
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
+# <http://www.gnu.org/licenses/>.
+
+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
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _BITS_PTHREADTYPES_ARCH_H
+#define _BITS_PTHREADTYPES_ARCH_H 1
+
+#include <endian.h>
+
+#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
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _SEMAPHORE_H
+# error "Never use <bits/semaphore.h> directly; include <semaphore.h> 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 <lowlevellock.c>
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 <sysdep.S>
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
+ <http://www.gnu.org/licenses/>. */
+
+#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
+ <http://www.gnu.org/licenses/>. */
+
+/* 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 <sysdep.h>
+#include <tls.h>
+
+#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
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _LOONGARCH_TLS_H
+#define _LOONGARCH_TLS_H 1
+
+#include <dl-sysdep.h>
+
+#ifndef __ASSEMBLER__
+# include <stdbool.h>
+# include <stddef.h>
+# include <stdint.h>
+# include <dl-dtv.h>
+
+register void *__thread_self asm ("$tp"); /* FIXME */
+# define READ_THREAD_POINTER() ({ __thread_self; })
+
+/* Get system call information. */
+# include <sysdep.h>
+
+/* 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 <nptl/descr.h>
+
+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 <nptl/pthread_atfork.c>
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
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#include <sys/asm.h>
+
+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 <fenv.h>
+#include <fpu_control.h>
+
+#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
+ <http://www.gnu.org/licenses/>. */
+
+#define HAVE_ARCH_PLTENTER
+#define HAVE_ARCH_PLTEXIT
+
+#include <elf/sotruss-lib.c>
+
+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 <debug/stack_chk_fail_local.c>
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
+ <http://www.gnu.org/licenses/>. */
+
+/* This file contains a bit of information about the stack allocation
+ of the processor. */
+
+#ifndef _STACKINFO_H
+#define _STACKINFO_H 1
+
+#include <elf.h>
+
+/* 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 <entry.h>
+#include <sys/asm.h>
+
+/* 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 <io/stat.c>
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 <io/stat64.c>
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 <sys/regdef.h>
+#include <sysdeps/generic/sysdep.h>
+
+/* 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
+ <http://www.gnu.org/licenses/>. */
+
+
+#include <sys/cdefs.h>
+#include <sys/asm.h>
+#include <sysdep.h>
+#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
+ <http://www.gnu.org/licenses/>. */
+
+#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 <debug/warning-nop.c>
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
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _LINUX_LOONGARCH_BITS_ATOMIC_H
+#define _LINUX_LOONGARCH_BITS_ATOMIC_H 1
+
+#include <stdint.h>
+
+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 <cmetcalf@tilera.com>, 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
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _FCNTL_H
+# error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead."
+#endif
+
+#include <bits/wordsize.h>
+
+/* 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 <bits/fcntl-linux.h>
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 <http://www.gnu.org/licenses/>. */
+
+/* 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 <linux/limits.h>
+
+/* 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
+ <http://www.gnu.org/licenses/>. */
+
+
+#ifndef _SYS_MMAN_H
+# error "Never use <bits/mman.h> directly; include <sys/mman.h> 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 <bits/mman-linux.h>
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 <cmetcalf@tilera.com>, 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
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _SYS_SHM_H
+# error "Never include <bits/shm.h> directly; use <sys/shm.h> instead."
+#endif
+
+#include <bits/types.h>
+#include <bits/wordsize.h>
+
+/* Permission flag for shmget. */
+#define SHM_R 0400 /* or S_IRUGO from <linux/stat.h> */
+#define SHM_W 0200 /* or S_IWUGO from <linux/stat.h> */
+
+/* Flags for `shmat'. */
+#define SHM_RDONLY 010000 /* attach read-only else read-write */
+#define SHM_RND 020000 /* round attach address to SHMLBA */
+#define SHM_REMAP 040000 /* take-over region on attach */
+#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
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _BITS_SIGNUM_H
+#define _BITS_SIGNUM_H 1
+
+#ifndef _SIGNAL_H
+#error "Never include <bits/signum.h> directly; use <signal.h> instead."
+#endif
+
+#include <bits/signum-generic.h>
+
+/* 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 /* <signal.h> 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
+ <http://www.gnu.org/licenses/>. */
+
+/* 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 <sys/asm.h>
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+#include <tls.h>
+#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
+ <http://www.gnu.org/licenses/>. */
+
+#include <ldsodefs.h>
+
+#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
+ <http://www.gnu.org/licenses/>. */
+
+#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
+ <http://www.gnu.org/licenses/>. */
+
+#include <unistd.h>
+
+#ifdef SHARED
+# include <dl-vdso.h>
+# include <errno.h>
+
+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 <sysdep.h>
+# include <errno.h>
+
+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
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/time.h>
+
+#ifdef SHARED
+
+# include <dl-vdso.h>
+# include <errno.h>
+
+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 <sysdep.h>
+# include <errno.h>
+
+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
+ <http://www.gnu.org/licenses/>. */
+
+#include <unistd.h>
+
+#ifdef SHARED
+
+# include <dl-vdso.h>
+# include <errno.h>
+
+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 <sysdep.h>
+# include <errno.h>
+
+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
+ <http://www.gnu.org/licenses/>. */
+
+#ifdef SHARED
+# include <dl-vdso.h>
+# include <libc-vdso.h>
+
+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 <csu/init-first.c>
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
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/ipc.h> /* 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
+ <http://www.gnu.org/licenses/>. */
+
+#include_next <kernel-features.h>
+
+/* 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
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _LDSODEFS_H
+
+/* Get the real definitions. */
+#include_next <ldsodefs.h>
+
+/* 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
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _LIBC_VDSO_H
+#define _LIBC_VDSO_H
+
+#ifdef SHARED
+
+# include <sysdep-vdso.h>
+
+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
+ <http://www.gnu.org/licenses/>. */
+
+/* Produced by this program:
+
+ #include <stdio.h>
+ #include <unistd.h>
+ #include <setjmp.h>
+ #include <stddef.h>
+
+ 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
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#include <sys/asm.h>
+#include <sys/ucontext.h>
+#include <stdarg.h>
+#include <assert.h>
+
+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
+ <http://www.gnu.org/licenses/>. */
+
+#include <signal.h>
+#include <sigcontextinfo.h>
+
+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
+ <http://www.gnu.org/licenses/>. */
+
+#include <unistd.h>
+#include <string.h>
+#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
+ <http://www.gnu.org/licenses/>. */
+#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
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/ucontext.h>
+
+#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
+ <http://www.gnu.org/licenses/>. */
+
+#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
+ <http://www.gnu.org/licenses/>. */
+
+#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 <features.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/user.h>
+#include <sys/ucontext.h>
+
+__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 <proc_service.h> 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
+ <http://www.gnu.org/licenses/>. */
+
+/* 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 <features.h>
+
+#include <bits/types/sigset_t.h>
+#include <bits/types/stack_t.h>
+
+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
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _SYS_USER_H
+#define _SYS_USER_H 1
+
+#include <stdint.h>
+
+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
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+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
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+#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 <sysdeps/unix/sysv/linux/generic/sysdep.h>
+#include <tls.h>
+
+#ifdef __ASSEMBLER__
+
+# include <sys/asm.h>
+# 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 <errno.h>
+#endif
+
+#include <sysdeps/unix/sysdep.h>
+
+#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
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _LINUX_LOONGARCH_UCONTEXT_MACROS_H
+#define _LINUX_LOONGARCH_UCONTEXT_MACROS_H
+
+#include <sysdep.h>
+#include <sys/asm.h>
+
+#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 <inttypes.h>
+#include <signal.h>
+#include <stddef.h>
+#include <sys/ucontext.h>
+
+-- 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
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+
+/* Clone the calling process, but without copying the whole address space.
+ The calling process is suspended until the new process exits or is
+ replaced by a call to `execve'. Return -1 for errors, 0 to the new process,
+ and the process ID of the new process to the old process. */
+
+ENTRY (__vfork)
+
+
+ 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