From 4bcb0bf4f727666ba875302baf52d60f65bd7cb1 Mon Sep 17 00:00:00 2001
From: Lixing <lixing@loongosn.cn>
Date: Wed, 19 Jul 2023 11:59:19 +0800
Subject: [PATCH] glibc Sync to vec.35 for LoongArch

dl-machine.h: scope used
	      #define PLTREL ElfW(Rela)
dl-tunables.list added
ld.abilist changed
localplt.data changed
---
 elf/dl-reloc.c                                |   13 +-
 elf/elf.h                                     |   85 +-
 scripts/config.guess                          |    3 +
 scripts/config.sub                            |    7 +-
 sysdeps/loongarch/Implies                     |    5 +
 sysdeps/loongarch/Makefile                    |   36 +
 sysdeps/loongarch/Versions                    |    5 +
 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/cpu-tunables.c              |   94 +
 sysdeps/loongarch/dl-get-cpu-features.c       |   25 +
 sysdeps/loongarch/dl-irel.h                   |   51 +
 sysdeps/loongarch/dl-machine.h                |  410 +++
 sysdeps/loongarch/dl-tls.h                    |   49 +
 sysdeps/loongarch/dl-trampoline.S             |   31 +
 sysdeps/loongarch/dl-trampoline.h             |  153 ++
 sysdeps/loongarch/dl-tunables.list            |   25 +
 sysdeps/loongarch/e_sqrtl.c                   |   39 +
 sysdeps/loongarch/elf-init.c                  |    1 +
 sysdeps/loongarch/fenv_private.h              |  328 +++
 sysdeps/loongarch/fpu/e_ilogb.c               |   39 +
 sysdeps/loongarch/fpu/e_ilogbf.c              |   39 +
 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/s_copysign.c            |   30 +
 sysdeps/loongarch/fpu/s_copysignf.c           |   30 +
 sysdeps/loongarch/fpu/s_finite.c              |   30 +
 sysdeps/loongarch/fpu/s_finitef.c             |   30 +
 sysdeps/loongarch/fpu/s_fmax.c                |   30 +
 sysdeps/loongarch/fpu/s_fmaxf.c               |   30 +
 sysdeps/loongarch/fpu/s_fmaxmag.c             |   29 +
 sysdeps/loongarch/fpu/s_fmaxmagf.c            |   29 +
 sysdeps/loongarch/fpu/s_fmin.c                |   30 +
 sysdeps/loongarch/fpu/s_fminf.c               |   30 +
 sysdeps/loongarch/fpu/s_fminmag.c             |   29 +
 sysdeps/loongarch/fpu/s_fminmagf.c            |   29 +
 sysdeps/loongarch/fpu/s_fpclassify.c          |   38 +
 sysdeps/loongarch/fpu/s_fpclassifyf.c         |   38 +
 sysdeps/loongarch/fpu/s_isinf.c               |   30 +
 sysdeps/loongarch/fpu/s_isinff.c              |   30 +
 sysdeps/loongarch/fpu/s_isnan.c               |   31 +
 sysdeps/loongarch/fpu/s_isnanf.c              |   31 +
 sysdeps/loongarch/fpu/s_issignaling.c         |   29 +
 sysdeps/loongarch/fpu/s_issignalingf.c        |   29 +
 sysdeps/loongarch/fpu/s_llrint.c              |   31 +
 sysdeps/loongarch/fpu/s_llrintf.c             |   31 +
 sysdeps/loongarch/fpu/s_logb.c                |   30 +
 sysdeps/loongarch/fpu/s_logbf.c               |   30 +
 sysdeps/loongarch/fpu/s_lrint.c               |   31 +
 sysdeps/loongarch/fpu/s_lrintf.c              |   31 +
 sysdeps/loongarch/fpu/s_rint.c                |   29 +
 sysdeps/loongarch/fpu/s_rintf.c               |   29 +
 sysdeps/loongarch/fpu/s_scalbn.c              |   29 +
 sysdeps/loongarch/fpu/s_scalbnf.c             |   29 +
 sysdeps/loongarch/fpu_control.h               |  128 +
 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/init-arch.h                 |   24 +
 sysdeps/loongarch/jmpbuf-offsets.h            |   23 +
 sysdeps/loongarch/jmpbuf-unwind.h             |   46 +
 sysdeps/loongarch/ldsodefs.h                  |   48 +
 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/memchr.S               |   99 +
 sysdeps/loongarch/lp64/memcmp.S               |  281 +++
 sysdeps/loongarch/lp64/memcpy.S               |  818 ++++++
 sysdeps/loongarch/lp64/memmove.S              |    2 +
 sysdeps/loongarch/lp64/memset.S               |  173 ++
 sysdeps/loongarch/lp64/multiarch/Makefile     |   18 +
 .../lp64/multiarch/ifunc-impl-list.c          |  142 ++
 sysdeps/loongarch/lp64/multiarch/ifunc-lasx.h |   40 +
 sysdeps/loongarch/lp64/multiarch/ifunc-lsx.h  |   37 +
 .../loongarch/lp64/multiarch/ifunc-memchr.h   |   37 +
 .../loongarch/lp64/multiarch/ifunc-memrchr.h  |   37 +
 .../loongarch/lp64/multiarch/ifunc-stpcpy.h   |   34 +
 .../loongarch/lp64/multiarch/memchr-aligned.S |    7 +
 .../loongarch/lp64/multiarch/memchr-lasx.S    |  108 +
 sysdeps/loongarch/lp64/multiarch/memchr-lsx.S |   93 +
 sysdeps/loongarch/lp64/multiarch/memchr.c     |   39 +
 .../loongarch/lp64/multiarch/memcmp-aligned.S |   11 +
 .../loongarch/lp64/multiarch/memcmp-lasx.S    |  199 ++
 sysdeps/loongarch/lp64/multiarch/memcmp-lsx.S |  255 ++
 sysdeps/loongarch/lp64/multiarch/memcmp.c     |   41 +
 .../loongarch/lp64/multiarch/memcpy-aligned.S |   11 +
 .../loongarch/lp64/multiarch/memcpy-lasx.S    |    1 +
 sysdeps/loongarch/lp64/multiarch/memcpy-lsx.S |    1 +
 .../lp64/multiarch/memcpy-unaligned.S         |  259 ++
 sysdeps/loongarch/lp64/multiarch/memcpy.c     |   39 +
 .../lp64/multiarch/memmove-aligned.S          |    1 +
 .../loongarch/lp64/multiarch/memmove-lasx.S   |  279 +++
 .../loongarch/lp64/multiarch/memmove-lsx.S    |  524 ++++
 .../lp64/multiarch/memmove-unaligned.S        |  478 ++++
 sysdeps/loongarch/lp64/multiarch/memmove.c    |   39 +
 .../lp64/multiarch/memrchr-generic.c          |    9 +
 .../loongarch/lp64/multiarch/memrchr-lasx.S   |  114 +
 .../loongarch/lp64/multiarch/memrchr-lsx.S    |   96 +
 sysdeps/loongarch/lp64/multiarch/memrchr.c    |   39 +
 .../loongarch/lp64/multiarch/memset-aligned.S |    9 +
 .../loongarch/lp64/multiarch/memset-lasx.S    |  132 +
 sysdeps/loongarch/lp64/multiarch/memset-lsx.S |  125 +
 .../lp64/multiarch/memset-unaligned.S         |  177 ++
 sysdeps/loongarch/lp64/multiarch/memset.c     |   39 +
 .../lp64/multiarch/rawmemchr-aligned.S        |    7 +
 .../loongarch/lp64/multiarch/rawmemchr-lasx.S |   51 +
 .../loongarch/lp64/multiarch/rawmemchr-lsx.S  |   56 +
 sysdeps/loongarch/lp64/multiarch/rawmemchr.c  |   37 +
 .../loongarch/lp64/multiarch/stpcpy-aligned.S |    8 +
 sysdeps/loongarch/lp64/multiarch/stpcpy-lsx.S |  178 ++
 sysdeps/loongarch/lp64/multiarch/stpcpy.c     |   43 +
 .../loongarch/lp64/multiarch/strchr-aligned.S |   10 +
 .../loongarch/lp64/multiarch/strchr-lasx.S    |   81 +
 sysdeps/loongarch/lp64/multiarch/strchr-lsx.S |   61 +
 .../lp64/multiarch/strchr-unaligned.S         |  132 +
 sysdeps/loongarch/lp64/multiarch/strchr.c     |   39 +
 .../lp64/multiarch/strchrnul-aligned.S        |    8 +
 .../loongarch/lp64/multiarch/strchrnul-lasx.S |    4 +
 .../loongarch/lp64/multiarch/strchrnul-lsx.S  |    3 +
 .../lp64/multiarch/strchrnul-unaligned.S      |  146 ++
 sysdeps/loongarch/lp64/multiarch/strchrnul.c  |   34 +
 .../loongarch/lp64/multiarch/strcmp-aligned.S |    8 +
 sysdeps/loongarch/lp64/multiarch/strcmp-lsx.S |  147 ++
 .../lp64/multiarch/strcmp-unaligned.S         |  191 ++
 sysdeps/loongarch/lp64/multiarch/strcmp.c     |   35 +
 .../loongarch/lp64/multiarch/strcpy-aligned.S |    8 +
 sysdeps/loongarch/lp64/multiarch/strcpy-lsx.S |  174 ++
 .../lp64/multiarch/strcpy-unaligned.S         |  199 ++
 sysdeps/loongarch/lp64/multiarch/strcpy.c     |   36 +
 .../loongarch/lp64/multiarch/strlen-aligned.S |    8 +
 .../loongarch/lp64/multiarch/strlen-lasx.S    |   55 +
 sysdeps/loongarch/lp64/multiarch/strlen-lsx.S |   63 +
 .../lp64/multiarch/strlen-unaligned.S         |  116 +
 sysdeps/loongarch/lp64/multiarch/strlen.c     |   39 +
 .../lp64/multiarch/strncmp-aligned.S          |    8 +
 .../loongarch/lp64/multiarch/strncmp-lsx.S    |  197 ++
 .../lp64/multiarch/strncmp-unaligned.S        |  257 ++
 sysdeps/loongarch/lp64/multiarch/strncmp.c    |   35 +
 .../lp64/multiarch/strnlen-aligned.S          |    8 +
 .../loongarch/lp64/multiarch/strnlen-lasx.S   |   92 +
 .../loongarch/lp64/multiarch/strnlen-lsx.S    |   81 +
 .../lp64/multiarch/strnlen-unaligned.S        |  145 ++
 sysdeps/loongarch/lp64/multiarch/strnlen.c    |   40 +
 .../lp64/multiarch/strrchr-aligned.S          |   12 +
 .../loongarch/lp64/multiarch/strrchr-lasx.S   |  113 +
 .../loongarch/lp64/multiarch/strrchr-lsx.S    |   93 +
 sysdeps/loongarch/lp64/multiarch/strrchr.c    |   39 +
 sysdeps/loongarch/lp64/rawmemchr.S            |  114 +
 sysdeps/loongarch/lp64/s_cosf.S               |  409 +++
 sysdeps/loongarch/lp64/s_sinf.S               |  392 +++
 sysdeps/loongarch/lp64/stpcpy.S               |  180 ++
 sysdeps/loongarch/lp64/strchr.S               |   90 +
 sysdeps/loongarch/lp64/strchrnul.S            |   95 +
 sysdeps/loongarch/lp64/strcmp.S               |  228 ++
 sysdeps/loongarch/lp64/strcpy.S               |  174 ++
 sysdeps/loongarch/lp64/strlen.S               |   86 +
 sysdeps/loongarch/lp64/strncmp.S              |  257 ++
 sysdeps/loongarch/lp64/strnlen.S              |   83 +
 sysdeps/loongarch/lp64/strrchr.S              |  106 +
 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                   |   58 +
 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 +
 .../unix/sysv/linux/loongarch/bits/hwcap.h    |   37 +
 .../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 +
 .../unix/sysv/linux/loongarch/cpu-features.c  |   32 +
 .../unix/sysv/linux/loongarch/cpu-features.h  |   53 +
 .../unix/sysv/linux/loongarch/dl-procinfo.c   |   60 +
 sysdeps/unix/sysv/linux/loongarch/dl-static.c |   84 +
 sysdeps/unix/sysv/linux/loongarch/dl-sysdep.c |   21 +
 .../sysv/linux/loongarch/dl-tunables.list     |   27 +
 .../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 +
 .../unix/sysv/linux/loongarch/libc-start.c    |   28 +
 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 +
 291 files changed, 24100 insertions(+), 8 deletions(-)
 create mode 100644 sysdeps/loongarch/Implies
 create mode 100644 sysdeps/loongarch/Makefile
 create mode 100644 sysdeps/loongarch/Versions
 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/cpu-tunables.c
 create mode 100644 sysdeps/loongarch/dl-get-cpu-features.c
 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/dl-trampoline.h
 create mode 100644 sysdeps/loongarch/dl-tunables.list
 create mode 100644 sysdeps/loongarch/e_sqrtl.c
 create mode 100644 sysdeps/loongarch/elf-init.c
 create mode 100644 sysdeps/loongarch/fenv_private.h
 create mode 100644 sysdeps/loongarch/fpu/e_ilogb.c
 create mode 100644 sysdeps/loongarch/fpu/e_ilogbf.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/s_copysign.c
 create mode 100644 sysdeps/loongarch/fpu/s_copysignf.c
 create mode 100644 sysdeps/loongarch/fpu/s_finite.c
 create mode 100644 sysdeps/loongarch/fpu/s_finitef.c
 create mode 100644 sysdeps/loongarch/fpu/s_fmax.c
 create mode 100644 sysdeps/loongarch/fpu/s_fmaxf.c
 create mode 100644 sysdeps/loongarch/fpu/s_fmaxmag.c
 create mode 100644 sysdeps/loongarch/fpu/s_fmaxmagf.c
 create mode 100644 sysdeps/loongarch/fpu/s_fmin.c
 create mode 100644 sysdeps/loongarch/fpu/s_fminf.c
 create mode 100644 sysdeps/loongarch/fpu/s_fminmag.c
 create mode 100644 sysdeps/loongarch/fpu/s_fminmagf.c
 create mode 100644 sysdeps/loongarch/fpu/s_fpclassify.c
 create mode 100644 sysdeps/loongarch/fpu/s_fpclassifyf.c
 create mode 100644 sysdeps/loongarch/fpu/s_isinf.c
 create mode 100644 sysdeps/loongarch/fpu/s_isinff.c
 create mode 100644 sysdeps/loongarch/fpu/s_isnan.c
 create mode 100644 sysdeps/loongarch/fpu/s_isnanf.c
 create mode 100644 sysdeps/loongarch/fpu/s_issignaling.c
 create mode 100644 sysdeps/loongarch/fpu/s_issignalingf.c
 create mode 100644 sysdeps/loongarch/fpu/s_llrint.c
 create mode 100644 sysdeps/loongarch/fpu/s_llrintf.c
 create mode 100644 sysdeps/loongarch/fpu/s_logb.c
 create mode 100644 sysdeps/loongarch/fpu/s_logbf.c
 create mode 100644 sysdeps/loongarch/fpu/s_lrint.c
 create mode 100644 sysdeps/loongarch/fpu/s_lrintf.c
 create mode 100644 sysdeps/loongarch/fpu/s_rint.c
 create mode 100644 sysdeps/loongarch/fpu/s_rintf.c
 create mode 100644 sysdeps/loongarch/fpu/s_scalbn.c
 create mode 100644 sysdeps/loongarch/fpu/s_scalbnf.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/init-arch.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/memchr.S
 create mode 100644 sysdeps/loongarch/lp64/memcmp.S
 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/multiarch/Makefile
 create mode 100644 sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
 create mode 100644 sysdeps/loongarch/lp64/multiarch/ifunc-lasx.h
 create mode 100644 sysdeps/loongarch/lp64/multiarch/ifunc-lsx.h
 create mode 100644 sysdeps/loongarch/lp64/multiarch/ifunc-memchr.h
 create mode 100644 sysdeps/loongarch/lp64/multiarch/ifunc-memrchr.h
 create mode 100644 sysdeps/loongarch/lp64/multiarch/ifunc-stpcpy.h
 create mode 100644 sysdeps/loongarch/lp64/multiarch/memchr-aligned.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/memchr-lasx.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/memchr-lsx.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/memchr.c
 create mode 100644 sysdeps/loongarch/lp64/multiarch/memcmp-aligned.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/memcmp-lasx.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/memcmp-lsx.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/memcmp.c
 create mode 100644 sysdeps/loongarch/lp64/multiarch/memcpy-aligned.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/memcpy-lasx.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/memcpy-lsx.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/memcpy-unaligned.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/memcpy.c
 create mode 100644 sysdeps/loongarch/lp64/multiarch/memmove-aligned.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/memmove-lasx.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/memmove-lsx.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/memmove-unaligned.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/memmove.c
 create mode 100644 sysdeps/loongarch/lp64/multiarch/memrchr-generic.c
 create mode 100644 sysdeps/loongarch/lp64/multiarch/memrchr-lasx.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/memrchr-lsx.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/memrchr.c
 create mode 100644 sysdeps/loongarch/lp64/multiarch/memset-aligned.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/memset-lasx.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/memset-lsx.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/memset-unaligned.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/memset.c
 create mode 100644 sysdeps/loongarch/lp64/multiarch/rawmemchr-aligned.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/rawmemchr-lasx.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/rawmemchr-lsx.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/rawmemchr.c
 create mode 100644 sysdeps/loongarch/lp64/multiarch/stpcpy-aligned.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/stpcpy-lsx.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/stpcpy.c
 create mode 100644 sysdeps/loongarch/lp64/multiarch/strchr-aligned.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/strchr-lasx.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/strchr-lsx.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/strchr-unaligned.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/strchr.c
 create mode 100644 sysdeps/loongarch/lp64/multiarch/strchrnul-aligned.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/strchrnul-lasx.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/strchrnul-lsx.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/strchrnul-unaligned.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/strchrnul.c
 create mode 100644 sysdeps/loongarch/lp64/multiarch/strcmp-aligned.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/strcmp-lsx.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/strcmp-unaligned.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/strcmp.c
 create mode 100644 sysdeps/loongarch/lp64/multiarch/strcpy-aligned.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/strcpy-lsx.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/strcpy-unaligned.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/strcpy.c
 create mode 100644 sysdeps/loongarch/lp64/multiarch/strlen-aligned.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/strlen-lasx.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/strlen-lsx.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/strlen-unaligned.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/strlen.c
 create mode 100644 sysdeps/loongarch/lp64/multiarch/strncmp-aligned.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/strncmp-lsx.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/strncmp-unaligned.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/strncmp.c
 create mode 100644 sysdeps/loongarch/lp64/multiarch/strnlen-aligned.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/strnlen-lasx.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/strnlen-lsx.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/strnlen-unaligned.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/strnlen.c
 create mode 100644 sysdeps/loongarch/lp64/multiarch/strrchr-aligned.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/strrchr-lasx.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/strrchr-lsx.S
 create mode 100644 sysdeps/loongarch/lp64/multiarch/strrchr.c
 create mode 100644 sysdeps/loongarch/lp64/rawmemchr.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/stpcpy.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/lp64/strrchr.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/hwcap.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/cpu-features.c
 create mode 100644 sysdeps/unix/sysv/linux/loongarch/cpu-features.h
 create mode 100644 sysdeps/unix/sysv/linux/loongarch/dl-procinfo.c
 create mode 100644 sysdeps/unix/sysv/linux/loongarch/dl-static.c
 create mode 100644 sysdeps/unix/sysv/linux/loongarch/dl-sysdep.c
 create mode 100644 sysdeps/unix/sysv/linux/loongarch/dl-tunables.list
 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-start.c
 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/elf/dl-reloc.c b/elf/dl-reloc.c
index 7a84b1fa..47342c76 100644
--- a/elf/dl-reloc.c
+++ b/elf/dl-reloc.c
@@ -235,12 +235,6 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
 	    newp->start = PTR_ALIGN_DOWN (ph->p_vaddr, GLRO(dl_pagesize))
 			  + (caddr_t) l->l_addr;
 
-	    if (__mprotect (newp->start, newp->len, PROT_READ|PROT_WRITE) < 0)
-	      {
-		errstring = N_("cannot make segment writable for relocation");
-	      call_error:
-		_dl_signal_error (errno, l->l_name, NULL, errstring);
-	      }
 
 #if (PF_R | PF_W | PF_X) == 7 && (PROT_READ | PROT_WRITE | PROT_EXEC) == 7
 	    newp->prot = (PF_TO_PROT
@@ -254,6 +248,13 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
 	    if (ph->p_flags & PF_X)
 	      newp->prot |= PROT_EXEC;
 #endif
+	    if (__mprotect (newp->start, newp->len, PROT_READ|PROT_WRITE) < 0)
+	      {
+		errstring = N_("cannot make segment writable for relocation");
+	      call_error:
+		_dl_signal_error (errno, l->l_name, NULL, errstring);
+	      }
+
 	    newp->next = textrels;
 	    textrels = newp;
 	  }
diff --git a/elf/elf.h b/elf/elf.h
index ec09040b..65d1fb46 100644
--- a/elf/elf.h
+++ b/elf/elf.h
@@ -360,8 +360,9 @@ 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
+#define EM_NUM		259
 
 /* Old spellings/synonyms.  */
 
@@ -3932,6 +3933,88 @@ 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.guess b/scripts/config.guess
index 588fe82a..a1d1cb2a 100755
--- a/scripts/config.guess
+++ b/scripts/config.guess
@@ -957,6 +957,9 @@ EOF
     k1om:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
 	exit ;;
+    loongarch32:Linux:*:* | loongarch64:Linux:*:*)
+        echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+        exit ;;
     m32r*:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
 	exit ;;
diff --git a/scripts/config.sub b/scripts/config.sub
index f2632cd8..429ec408 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* |\
@@ -265,6 +265,7 @@ case $basic_machine in
 	| k1om \
 	| le32 | le64 \
 	| lm32 \
+	| loongarch32 | loongarch64 \
 	| m32c | m32r | m32rle | m68000 | m68k | m88k \
 	| maxq | mb | microblaze | microblazeel | mcore | mep | metag \
 	| mips | mipsbe | mipseb | mipsel | mipsle \
@@ -390,6 +391,7 @@ case $basic_machine in
 	| k1om-* \
 	| le32-* | le64-* \
 	| lm32-* \
+	| loongarch32-* | loongarch64-* \
 	| m32c-* | m32r-* | m32rle-* \
 	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
 	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
@@ -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..286cff67
--- /dev/null
+++ b/sysdeps/loongarch/Makefile
@@ -0,0 +1,36 @@
+ifeq ($(subdir),misc)
+sysdep_headers += sys/asm.h
+endif
+
+ifeq ($(subdir),elf)
+  sysdep-dl-routines += dl-get-cpu-features
+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/Versions b/sysdeps/loongarch/Versions
new file mode 100644
index 00000000..33ae2cc0
--- /dev/null
+++ b/sysdeps/loongarch/Versions
@@ -0,0 +1,5 @@
+ld {
+  GLIBC_PRIVATE {
+    _dl_larch_get_cpu_features;
+  }
+}
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/cpu-tunables.c b/sysdeps/loongarch/cpu-tunables.c
new file mode 100644
index 00000000..840c1b8c
--- /dev/null
+++ b/sysdeps/loongarch/cpu-tunables.c
@@ -0,0 +1,94 @@
+/* LoongArch CPU feature tuning.
+   This file is part of the GNU C Library.
+   Copyright (C) 2017-2018 Free Software Foundation, Inc.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#if HAVE_TUNABLES
+# define TUNABLE_NAMESPACE cpu
+# include <stdbool.h>
+# include <stdint.h>
+# include <unistd.h>		/* Get STDOUT_FILENO for _dl_printf.  */
+# include <elf/dl-tunables.h>
+# include <string.h>
+# include <cpu-features.h>
+# include <ldsodefs.h>
+# include <sys/auxv.h>
+
+# define HWCAP_LOONGARCH_IFUNC \
+  (HWCAP_LOONGARCH_UAL | HWCAP_LOONGARCH_LSX | HWCAP_LOONGARCH_LASX)
+
+# define CHECK_GLIBC_IFUNC_CPU_OFF(f, name, len)			\
+  _Static_assert (sizeof (#name) - 1 == len, #name " != " #len);	\
+  if (!memcmp (f, #name, len) &&					\
+      (GLRO (dl_hwcap) & HWCAP_LOONGARCH_##name))			\
+    {									\
+      hwcap |= (HWCAP_LOONGARCH_##name | (~HWCAP_LOONGARCH_IFUNC));	\
+      break;								\
+    }									\
+
+
+attribute_hidden
+void
+TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *valp)
+{
+  const char *p = valp->strval;
+  size_t len;
+  unsigned long hwcap = 0;
+  const char *c;
+
+  do {
+      for (c = p; *c != ','; c++)
+	if (*c == '\0')
+	  break;
+
+      len = c - p;
+
+      switch(len)
+      {
+	default:
+	  _dl_fatal_printf (
+	    "The valid values of glibc.cpu.hwcaps is UAL, LASX, LSX!!\n"
+			    );
+	  break;
+	case 3:
+	  {
+	    CHECK_GLIBC_IFUNC_CPU_OFF (p, LSX, 3);
+	    CHECK_GLIBC_IFUNC_CPU_OFF (p, UAL, 3);
+	    _dl_fatal_printf (
+		"Some features are invalid or not supported on this machine!!\n"
+		"The valid values of glibc.cpu.hwcaps is UAL, LASX, LSX!!\n"
+                       );
+	  }
+	  break;
+	case 4:
+	  {
+	    CHECK_GLIBC_IFUNC_CPU_OFF (p, LASX, 4);
+	    _dl_fatal_printf (
+		"Some features are invalid or not supported on this machine!!\n"
+		"The valid values of glibc.cpu.hwcaps is UAL, LASX, LSX!!\n"
+                       );
+	  }
+	  break;
+      }
+
+      p += len + 1;
+    }
+  while (*c != '\0');
+
+  GLRO (dl_hwcap) &= hwcap;
+}
+
+#endif
diff --git a/sysdeps/loongarch/dl-get-cpu-features.c b/sysdeps/loongarch/dl-get-cpu-features.c
new file mode 100644
index 00000000..ed71abe0
--- /dev/null
+++ b/sysdeps/loongarch/dl-get-cpu-features.c
@@ -0,0 +1,25 @@
+/* Define _dl_larch_get_cpu_features.
+   Copyright (C) 2015-2022 Free Software Foundation, Inc.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+
+#include <ldsodefs.h>
+
+const struct cpu_features *
+_dl_larch_get_cpu_features (void)
+{
+  return &GLRO(dl_larch_cpu_features);
+}
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..2d527241
--- /dev/null
+++ b/sysdeps/loongarch/dl-machine.h
@@ -0,0 +1,410 @@
+/* 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"
+
+#if HAVE_TUNABLES
+#define TUNABLE_NAMESPACE cpu
+#include <elf/dl-tunables.h>
+extern void TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *) attribute_hidden;
+#endif
+
+#include <entry.h>
+#include <elf/elf.h>
+#include <sys/asm.h>
+#include <dl-tls.h>
+#include <cpu-features.c>
+
+
+#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
+#define PLTREL ElfW(Rela)
+
+#define DL_PLATFORM_INIT dl_platform_init ()
+
+static inline void __attribute__ ((unused))
+dl_platform_init (void)
+{
+  if (GLRO(dl_platform) != NULL && *GLRO(dl_platform) == '\0')
+    /* Avoid an empty string which would disturb us.  */
+    GLRO(dl_platform) = NULL;
+
+#ifdef SHARED
+
+#if HAVE_TUNABLES
+  TUNABLE_GET (hwcaps, tunable_val_t *, TUNABLE_CALLBACK (set_hwcaps));
+#endif
+  /* init_cpu_features has been called early from __libc_start_main in
+     static executable.  */
+  init_cpu_features (&GLRO(dl_larch_cpu_features));
+#endif
+}
+
+
+/* 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, struct r_scope_elem *scope[],
+		  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 (map, scope, &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;
+      if (__glibc_likely (!skip_ifunc))
+	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, struct r_scope_elem *scope[],
+		      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, struct r_scope_elem *scope[],
+			   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")));
+      extern void _dl_runtime_resolve_lasx (void) __attribute__ ((visibility ("hidden")));
+      extern void _dl_runtime_resolve_lsx (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;
+
+      if (SUPPORT_LASX)
+	gotplt[0] = (ElfW(Addr)) &_dl_runtime_resolve_lasx;
+      else if (SUPPORT_LSX)
+	gotplt[0] = (ElfW(Addr)) &_dl_runtime_resolve_lsx;
+      else
+	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..5f627a63
--- /dev/null
+++ b/sysdeps/loongarch/dl-trampoline.S
@@ -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/>.  */
+
+#define USE_LASX
+#define _dl_runtime_resolve _dl_runtime_resolve_lasx
+#include "dl-trampoline.h"
+#undef USE_LASX
+#undef _dl_runtime_resolve
+
+#define USE_LSX
+#define _dl_runtime_resolve _dl_runtime_resolve_lsx
+#include "dl-trampoline.h"
+#undef USE_LSX
+#undef _dl_runtime_resolve
+
+#include "dl-trampoline.h"
diff --git a/sysdeps/loongarch/dl-trampoline.h b/sysdeps/loongarch/dl-trampoline.h
new file mode 100644
index 00000000..95639111
--- /dev/null
+++ b/sysdeps/loongarch/dl-trampoline.h
@@ -0,0 +1,153 @@
+/* LoongArch PLT trampoline
+   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 <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 * 256) & ALMASK))
+#endif
+
+ENTRY (_dl_runtime_resolve)
+  # Save arguments to stack.
+
+#ifdef __loongarch64
+	li.d    t3, -FRAME_SIZE
+	add.d	sp, sp, t3
+#elif defined __loongarch32
+	li.w    t3, -FRAME_SIZE
+	add.w	sp, sp, t3
+#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
+#ifdef USE_LASX
+	xvst	$xr0, sp, 10*SZREG + 0*256
+	xvst	$xr1, sp, 10*SZREG + 1*256
+	xvst	$xr2, sp, 10*SZREG + 2*256
+	xvst	$xr3, sp, 10*SZREG + 3*256
+	xvst	$xr4, sp, 10*SZREG + 4*256
+	xvst	$xr5, sp, 10*SZREG + 5*256
+	xvst	$xr6, sp, 10*SZREG + 6*256
+	xvst	$xr7, sp, 10*SZREG + 7*256
+#elif defined USE_LSX
+	vst	$vr0, sp, 10*SZREG + 0*128
+	vst	$vr1, sp, 10*SZREG + 1*128
+	vst	$vr2, sp, 10*SZREG + 2*128
+	vst	$vr3, sp, 10*SZREG + 3*128
+	vst	$vr4, sp, 10*SZREG + 4*128
+	vst	$vr5, sp, 10*SZREG + 5*128
+	vst	$vr6, sp, 10*SZREG + 6*128
+	vst	$vr7, sp, 10*SZREG + 7*128
+#endif
+#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
+#ifdef USE_LASX
+	xvld	$xr0, sp, 10*SZREG + 0*256
+	xvld	$xr1, sp, 10*SZREG + 1*256
+	xvld	$xr2, sp, 10*SZREG + 2*256
+	xvld	$xr3, sp, 10*SZREG + 3*256
+	xvld	$xr4, sp, 10*SZREG + 4*256
+	xvld	$xr5, sp, 10*SZREG + 5*256
+	xvld	$xr6, sp, 10*SZREG + 6*256
+	xvld	$xr7, sp, 10*SZREG + 7*256
+#elif defined USE_LSX
+	vld	$vr0, sp, 10*SZREG + 0*128
+	vld	$vr1, sp, 10*SZREG + 1*128
+	vld	$vr2, sp, 10*SZREG + 2*128
+	vld	$vr3, sp, 10*SZREG + 3*128
+	vld	$vr4, sp, 10*SZREG + 4*128
+	vld	$vr5, sp, 10*SZREG + 5*128
+	vld	$vr6, sp, 10*SZREG + 6*128
+	vld	$vr7, sp, 10*SZREG + 7*128
+#endif
+#endif
+
+#ifdef __loongarch64
+	li.d    t3, FRAME_SIZE
+	add.d	sp, sp, t3
+#elif defined __loongarch32
+	li.w    t3, FRAME_SIZE
+	addi.w	sp, sp, FRAME_SIZE
+#endif
+
+
+  # Invoke the callee.
+	jirl	zero, t1, 0
+END (_dl_runtime_resolve)
diff --git a/sysdeps/loongarch/dl-tunables.list b/sysdeps/loongarch/dl-tunables.list
new file mode 100644
index 00000000..22c43611
--- /dev/null
+++ b/sysdeps/loongarch/dl-tunables.list
@@ -0,0 +1,25 @@
+# LoongArch specific tunables.
+# 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/>.
+
+glibc {
+  cpu {
+    hwcaps {
+      type: STRING
+    }
+  }
+}
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/fenv_private.h b/sysdeps/loongarch/fenv_private.h
new file mode 100644
index 00000000..416377f6
--- /dev/null
+++ b/sysdeps/loongarch/fenv_private.h
@@ -0,0 +1,328 @@
+/* Optimized inline fenv.h functions for libm.  Generic version.
+   Copyright (C) 2011-2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _FENV_PRIVATE_H
+#define _FENV_PRIVATE_H 1
+
+#include <fenv.h>
+#include <get-rounding-mode.h>
+
+/* The standards only specify one variant of the fenv.h interfaces.
+   But at least for some architectures we can be more efficient if we
+   know what operations are going to be performed.  Therefore we
+   define additional interfaces.  By default they refer to the normal
+   interfaces.  */
+
+static __always_inline void
+default_libc_feholdexcept (fenv_t *e)
+{
+  (void) __feholdexcept (e);
+}
+
+#ifndef libc_feholdexcept
+# define libc_feholdexcept  default_libc_feholdexcept
+#endif
+#ifndef libc_feholdexceptf
+# define libc_feholdexceptf default_libc_feholdexcept
+#endif
+#ifndef libc_feholdexceptl
+# define libc_feholdexceptl default_libc_feholdexcept
+#endif
+
+static __always_inline void
+default_libc_fesetround (int r)
+{
+  (void) __fesetround (r);
+}
+
+#ifndef libc_fesetround
+# define libc_fesetround  default_libc_fesetround
+#endif
+#ifndef libc_fesetroundf
+# define libc_fesetroundf default_libc_fesetround
+#endif
+#ifndef libc_fesetroundl
+# define libc_fesetroundl default_libc_fesetround
+#endif
+
+static __always_inline void
+default_libc_feholdexcept_setround (fenv_t *e, int r)
+{
+  __feholdexcept (e);
+  __fesetround (r);
+}
+
+#ifndef libc_feholdexcept_setround
+# define libc_feholdexcept_setround  default_libc_feholdexcept_setround
+#endif
+#ifndef libc_feholdexcept_setroundf
+# define libc_feholdexcept_setroundf default_libc_feholdexcept_setround
+#endif
+#ifndef libc_feholdexcept_setroundl
+# define libc_feholdexcept_setroundl default_libc_feholdexcept_setround
+#endif
+
+#ifndef libc_feholdsetround_53bit
+# define libc_feholdsetround_53bit libc_feholdsetround
+#endif
+
+#ifndef libc_fetestexcept
+# define libc_fetestexcept  fetestexcept
+#endif
+#ifndef libc_fetestexceptf
+# define libc_fetestexceptf fetestexcept
+#endif
+#ifndef libc_fetestexceptl
+# define libc_fetestexceptl fetestexcept
+#endif
+
+static __always_inline void
+default_libc_fesetenv (fenv_t *e)
+{
+  (void) __fesetenv (e);
+}
+
+#ifndef libc_fesetenv
+# define libc_fesetenv  default_libc_fesetenv
+#endif
+#ifndef libc_fesetenvf
+# define libc_fesetenvf default_libc_fesetenv
+#endif
+#ifndef libc_fesetenvl
+# define libc_fesetenvl default_libc_fesetenv
+#endif
+
+static __always_inline void
+default_libc_feupdateenv (fenv_t *e)
+{
+  (void) __feupdateenv (e);
+}
+
+#ifndef libc_feupdateenv
+# define libc_feupdateenv  default_libc_feupdateenv
+#endif
+#ifndef libc_feupdateenvf
+# define libc_feupdateenvf default_libc_feupdateenv
+#endif
+#ifndef libc_feupdateenvl
+# define libc_feupdateenvl default_libc_feupdateenv
+#endif
+
+#ifndef libc_feresetround_53bit
+# define libc_feresetround_53bit libc_feresetround
+#endif
+
+static __always_inline int
+default_libc_feupdateenv_test (fenv_t *e, int ex)
+{
+  int ret = fetestexcept (ex);
+  __feupdateenv (e);
+  return ret;
+}
+
+#ifndef libc_feupdateenv_test
+# define libc_feupdateenv_test  default_libc_feupdateenv_test
+#endif
+#ifndef libc_feupdateenv_testf
+# define libc_feupdateenv_testf default_libc_feupdateenv_test
+#endif
+#ifndef libc_feupdateenv_testl
+# define libc_feupdateenv_testl default_libc_feupdateenv_test
+#endif
+
+/* Save and set the rounding mode.  The use of fenv_t to store the old mode
+   allows a target-specific version of this function to avoid converting the
+   rounding mode from the fpu format.  By default we have no choice but to
+   manipulate the entire env.  */
+
+#ifndef libc_feholdsetround
+# define libc_feholdsetround  libc_feholdexcept_setround
+#endif
+#ifndef libc_feholdsetroundf
+# define libc_feholdsetroundf libc_feholdexcept_setroundf
+#endif
+#ifndef libc_feholdsetroundl
+# define libc_feholdsetroundl libc_feholdexcept_setroundl
+#endif
+
+/* ... and the reverse.  */
+
+#ifndef libc_feresetround
+# define libc_feresetround  libc_feupdateenv
+#endif
+#ifndef libc_feresetroundf
+# define libc_feresetroundf libc_feupdateenvf
+#endif
+#ifndef libc_feresetroundl
+# define libc_feresetroundl libc_feupdateenvl
+#endif
+
+/* ... and a version that also discards exceptions.  */
+
+#ifndef libc_feresetround_noex
+# define libc_feresetround_noex  libc_fesetenv
+#endif
+#ifndef libc_feresetround_noexf
+# define libc_feresetround_noexf libc_fesetenvf
+#endif
+#ifndef libc_feresetround_noexl
+# define libc_feresetround_noexl libc_fesetenvl
+#endif
+
+#ifndef HAVE_RM_CTX
+# define HAVE_RM_CTX 0
+#endif
+
+
+/* Default implementation using standard fenv functions.
+   Avoid unnecessary rounding mode changes by first checking the
+   current rounding mode.  Note the use of __glibc_unlikely is
+   important for performance.  */
+
+static __always_inline void
+default_libc_feholdsetround_ctx (struct rm_ctx *ctx, int round)
+{
+  ctx->updated_status = false;
+
+  /* Update rounding mode only if different.  */
+  if (__glibc_unlikely (round != get_rounding_mode ()))
+    {
+      ctx->updated_status = true;
+      __fegetenv (&ctx->env);
+      __fesetround (round);
+    }
+}
+
+static __always_inline void
+default_libc_feresetround_ctx (struct rm_ctx *ctx)
+{
+  /* Restore the rounding mode if updated.  */
+  if (__glibc_unlikely (ctx->updated_status))
+    __feupdateenv (&ctx->env);
+}
+
+static __always_inline void
+default_libc_feholdsetround_noex_ctx (struct rm_ctx *ctx, int round)
+{
+  /* Save exception flags and rounding mode, and disable exception
+     traps.  */
+  __feholdexcept (&ctx->env);
+
+  /* Update rounding mode only if different.  */
+  if (__glibc_unlikely (round != get_rounding_mode ()))
+    __fesetround (round);
+}
+
+static __always_inline void
+default_libc_feresetround_noex_ctx (struct rm_ctx *ctx)
+{
+  /* Restore exception flags and rounding mode.  */
+  __fesetenv (&ctx->env);
+}
+
+#if HAVE_RM_CTX
+/* Set/Restore Rounding Modes only when necessary.  If defined, these functions
+   set/restore floating point state only if the state needed within the lexical
+   block is different from the current state.  This saves a lot of time when
+   the floating point unit is much slower than the fixed point units.  */
+
+# ifndef libc_feholdsetround_noex_ctx
+#   define libc_feholdsetround_noex_ctx  libc_feholdsetround_ctx
+# endif
+# ifndef libc_feholdsetround_noexf_ctx
+#   define libc_feholdsetround_noexf_ctx libc_feholdsetroundf_ctx
+# endif
+# ifndef libc_feholdsetround_noexl_ctx
+#   define libc_feholdsetround_noexl_ctx libc_feholdsetroundl_ctx
+# endif
+
+# ifndef libc_feresetround_noex_ctx
+#   define libc_feresetround_noex_ctx  libc_fesetenv_ctx
+# endif
+# ifndef libc_feresetround_noexf_ctx
+#   define libc_feresetround_noexf_ctx libc_fesetenvf_ctx
+# endif
+# ifndef libc_feresetround_noexl_ctx
+#   define libc_feresetround_noexl_ctx libc_fesetenvl_ctx
+# endif
+
+#else
+
+# define libc_feholdsetround_ctx      default_libc_feholdsetround_ctx
+# define libc_feresetround_ctx        default_libc_feresetround_ctx
+# define libc_feholdsetround_noex_ctx default_libc_feholdsetround_noex_ctx
+# define libc_feresetround_noex_ctx   default_libc_feresetround_noex_ctx
+
+# define libc_feholdsetroundf_ctx libc_feholdsetround_ctx
+# define libc_feholdsetroundl_ctx libc_feholdsetround_ctx
+# define libc_feresetroundf_ctx   libc_feresetround_ctx
+# define libc_feresetroundl_ctx   libc_feresetround_ctx
+
+# define libc_feholdsetround_noexf_ctx libc_feholdsetround_noex_ctx
+# define libc_feholdsetround_noexl_ctx libc_feholdsetround_noex_ctx
+# define libc_feresetround_noexf_ctx   libc_feresetround_noex_ctx
+# define libc_feresetround_noexl_ctx   libc_feresetround_noex_ctx
+
+#endif
+
+#ifndef libc_feholdsetround_53bit_ctx
+#  define libc_feholdsetround_53bit_ctx libc_feholdsetround_ctx
+#endif
+#ifndef libc_feresetround_53bit_ctx
+#  define libc_feresetround_53bit_ctx libc_feresetround_ctx
+#endif
+
+#define SET_RESTORE_ROUND_GENERIC(RM,ROUNDFUNC,CLEANUPFUNC) \
+  struct rm_ctx ctx __attribute__((cleanup (CLEANUPFUNC ## _ctx))); \
+  ROUNDFUNC ## _ctx (&ctx, (RM))
+
+/* Set the rounding mode within a lexical block.  Restore the rounding mode to
+   the value at the start of the block.  The exception mode must be preserved.
+   Exceptions raised within the block must be set in the exception flags.
+   Non-stop mode may be enabled inside the block.  */
+
+#define SET_RESTORE_ROUND(RM) \
+  SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround, libc_feresetround)
+#define SET_RESTORE_ROUNDF(RM) \
+  SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetroundf, libc_feresetroundf)
+#define SET_RESTORE_ROUNDL(RM) \
+  SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetroundl, libc_feresetroundl)
+
+/* Set the rounding mode within a lexical block.  Restore the rounding mode to
+   the value at the start of the block.  The exception mode must be preserved.
+   Exceptions raised within the block must be discarded, and exception flags
+   are restored to the value at the start of the block.
+   Non-stop mode must be enabled inside the block.  */
+
+#define SET_RESTORE_ROUND_NOEX(RM) \
+  SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround_noex, \
+			     libc_feresetround_noex)
+#define SET_RESTORE_ROUND_NOEXF(RM) \
+  SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround_noexf, \
+			     libc_feresetround_noexf)
+#define SET_RESTORE_ROUND_NOEXL(RM) \
+  SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround_noexl, \
+			     libc_feresetround_noexl)
+
+/* Like SET_RESTORE_ROUND, but also set rounding precision to 53 bits.  */
+#define SET_RESTORE_ROUND_53BIT(RM) \
+  SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround_53bit,	      \
+			     libc_feresetround_53bit)
+
+#endif /* fenv_private.h.  */
+
diff --git a/sysdeps/loongarch/fpu/e_ilogb.c b/sysdeps/loongarch/fpu/e_ilogb.c
new file mode 100644
index 00000000..f9ada692
--- /dev/null
+++ b/sysdeps/loongarch/fpu/e_ilogb.c
@@ -0,0 +1,39 @@
+/* __ieee754_ilogb().  LoongArch version.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#define NO_MATH_REDIRECT
+#include <math.h>
+#include <fpu_control.h>
+
+int
+__ieee754_ilogb (double x)
+{
+  int x_cond;
+  asm volatile ("fclass.d \t%0, %1" : "=f" (x_cond) : "f" (x));
+
+  if (__glibc_unlikely (x_cond & _FCLASS_ZERO))
+      return FP_ILOGB0;
+  else if (__glibc_unlikely (x_cond & ( _FCLASS_NAN | _FCLASS_INF)))
+      return FP_ILOGBNAN;
+  else
+    {
+      asm volatile ("fabs.d \t%0, %1" : "=f" (x) : "f" (x));
+      asm volatile ("flogb.d \t%0, %1" : "=f" (x) : "f" (x));
+      return x;
+    }
+}
diff --git a/sysdeps/loongarch/fpu/e_ilogbf.c b/sysdeps/loongarch/fpu/e_ilogbf.c
new file mode 100644
index 00000000..e1da48ec
--- /dev/null
+++ b/sysdeps/loongarch/fpu/e_ilogbf.c
@@ -0,0 +1,39 @@
+/* __ieee754_ilogbf().  LoongArch version.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#define NO_MATH_REDIRECT
+#include <math.h>
+#include <fpu_control.h>
+
+int
+__ieee754_ilogbf (float x)
+{
+  int x_cond;
+  asm volatile ("fclass.s \t%0, %1" : "=f" (x_cond) : "f" (x));
+
+  if (__glibc_unlikely (x_cond & _FCLASS_ZERO))
+      return FP_ILOGB0;
+  else if (__glibc_unlikely (x_cond & ( _FCLASS_NAN | _FCLASS_INF)))
+      return FP_ILOGBNAN;
+  else
+    {
+      asm volatile ("fabs.s \t%0, %1" : "=f" (x) : "f" (x));
+      asm volatile ("flogb.s \t%0, %1" : "=f" (x) : "f" (x));
+      return x;
+    }
+}
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/s_copysign.c b/sysdeps/loongarch/fpu/s_copysign.c
new file mode 100644
index 00000000..861c4610
--- /dev/null
+++ b/sysdeps/loongarch/fpu/s_copysign.c
@@ -0,0 +1,30 @@
+/* copysign().  LoongArch version.
+   Copyright (C) 2017-2022 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#define NO_MATH_REDIRECT
+#include <math.h>
+#include <libm-alias-double.h>
+
+double
+__copysign (double x, double y)
+{
+  asm ("fcopysign.d %0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
+  return x;
+}
+libm_alias_double (__copysign, copysign)
diff --git a/sysdeps/loongarch/fpu/s_copysignf.c b/sysdeps/loongarch/fpu/s_copysignf.c
new file mode 100644
index 00000000..c680b1fd
--- /dev/null
+++ b/sysdeps/loongarch/fpu/s_copysignf.c
@@ -0,0 +1,30 @@
+/* copysignf().  LoongArch version.
+   Copyright (C) 2017-2022 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#define NO_MATH_REDIRECT
+#include <math.h>
+#include <libm-alias-float.h>
+
+float
+__copysignf (float x, float y)
+{
+  asm ("fcopysign.s %0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
+  return x;
+}
+libm_alias_float (__copysign, copysign)
diff --git a/sysdeps/loongarch/fpu/s_finite.c b/sysdeps/loongarch/fpu/s_finite.c
new file mode 100644
index 00000000..a2e98f0b
--- /dev/null
+++ b/sysdeps/loongarch/fpu/s_finite.c
@@ -0,0 +1,30 @@
+/* finite().  LoongArch version.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <fenv_private.h>
+
+int
+__finite (double x)
+{
+  int x_cond;
+  asm volatile ("fclass.d \t%0, %1" : "=f" (x_cond) : "f" (x));
+  return  x_cond & ~(_FCLASS_INF | _FCLASS_NAN);
+}
+hidden_def (__finite)
+weak_alias (__finite, finite)
diff --git a/sysdeps/loongarch/fpu/s_finitef.c b/sysdeps/loongarch/fpu/s_finitef.c
new file mode 100644
index 00000000..9ffab38a
--- /dev/null
+++ b/sysdeps/loongarch/fpu/s_finitef.c
@@ -0,0 +1,30 @@
+/* finitef().  LoongArch version.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <fenv_private.h>
+
+int
+__finitef (float x)
+{
+  int x_cond;
+  asm volatile ("fclass.s \t%0, %1" : "=f" (x_cond) : "f" (x));
+  return  x_cond & ~(_FCLASS_INF | _FCLASS_NAN);
+}
+hidden_def (__finitef)
+weak_alias (__finitef, finitef)
diff --git a/sysdeps/loongarch/fpu/s_fmax.c b/sysdeps/loongarch/fpu/s_fmax.c
new file mode 100644
index 00000000..fe7265af
--- /dev/null
+++ b/sysdeps/loongarch/fpu/s_fmax.c
@@ -0,0 +1,30 @@
+/* fmax().  LoongArch version.
+   Copyright (C) 2021-2022 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#define NO_MATH_REDIRECT
+#include <math.h>
+#include <libm-alias-double.h>
+
+double
+__fmax (double x, double y)
+{
+  asm volatile("fmax.d\t%0,%1,%2" : "=f" (x) : "f" (x), "f" (y));
+  return x;
+}
+libm_alias_double (__fmax, fmax)
diff --git a/sysdeps/loongarch/fpu/s_fmaxf.c b/sysdeps/loongarch/fpu/s_fmaxf.c
new file mode 100644
index 00000000..3defa7de
--- /dev/null
+++ b/sysdeps/loongarch/fpu/s_fmaxf.c
@@ -0,0 +1,30 @@
+/* fmaxf().  LoongArch version.
+   Copyright (C) 2021-2022 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#define NO_MATH_REDIRECT
+#include <math.h>
+#include <libm-alias-float.h>
+
+float
+__fmaxf (float x, float y)
+{
+  asm volatile("fmax.s\t%0,%1,%2" : "=f" (x) : "f" (x), "f" (y));
+  return x;
+}
+libm_alias_float (__fmax, fmax)
diff --git a/sysdeps/loongarch/fpu/s_fmaxmag.c b/sysdeps/loongarch/fpu/s_fmaxmag.c
new file mode 100644
index 00000000..8570a3ba
--- /dev/null
+++ b/sysdeps/loongarch/fpu/s_fmaxmag.c
@@ -0,0 +1,29 @@
+/* fmaxmag().  LoongArch version.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#define NO_MATH_REDIRECT
+#include <math.h>
+#include <libm-alias-double.h>
+
+double
+__fmaxmag (double x, double y)
+{
+  asm volatile ("fmaxa.d \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
+  return x;
+}
+libm_alias_double (__fmaxmag, fmaxmag)
diff --git a/sysdeps/loongarch/fpu/s_fmaxmagf.c b/sysdeps/loongarch/fpu/s_fmaxmagf.c
new file mode 100644
index 00000000..413e7683
--- /dev/null
+++ b/sysdeps/loongarch/fpu/s_fmaxmagf.c
@@ -0,0 +1,29 @@
+/* fmaxmagf().  LoongArch version.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#define NO_MATH_REDIRECT
+#include <math.h>
+#include <libm-alias-float.h>
+
+float
+__fmaxmagf (float x, float y)
+{
+  asm volatile ("fmaxa.s \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
+  return x;
+}
+libm_alias_float (__fmaxmag, fmaxmag)
diff --git a/sysdeps/loongarch/fpu/s_fmin.c b/sysdeps/loongarch/fpu/s_fmin.c
new file mode 100644
index 00000000..cc9d0cd1
--- /dev/null
+++ b/sysdeps/loongarch/fpu/s_fmin.c
@@ -0,0 +1,30 @@
+/* fmin().  LoongArch version.
+   Copyright (C) 2021-2022 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#define NO_MATH_REDIRECT
+#include <math.h>
+#include <libm-alias-double.h>
+
+double
+__fmin (double x, double y)
+{
+  asm volatile("fmin.d\t%0,%1,%2" : "=f" (x) : "f" (x), "f" (y));
+  return x;
+}
+libm_alias_double (__fmin, fmin)
diff --git a/sysdeps/loongarch/fpu/s_fminf.c b/sysdeps/loongarch/fpu/s_fminf.c
new file mode 100644
index 00000000..40efbd71
--- /dev/null
+++ b/sysdeps/loongarch/fpu/s_fminf.c
@@ -0,0 +1,30 @@
+/* fminf().  LoongArch version.
+   Copyright (C) 2021-2022 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#define NO_MATH_REDIRECT
+#include <math.h>
+#include <libm-alias-float.h>
+
+float
+__fminf (float x, float y)
+{
+  asm volatile("fmin.s\t%0,%1,%2" : "=f" (x) : "f" (x), "f" (y));
+  return x;
+}
+libm_alias_float (__fmin, fmin)
diff --git a/sysdeps/loongarch/fpu/s_fminmag.c b/sysdeps/loongarch/fpu/s_fminmag.c
new file mode 100644
index 00000000..2badf3d3
--- /dev/null
+++ b/sysdeps/loongarch/fpu/s_fminmag.c
@@ -0,0 +1,29 @@
+/* fminmag().  LoongArch version.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#define NO_MATH_REDIRECT
+#include <math.h>
+#include <libm-alias-double.h>
+
+double
+__fminmag (double x, double y)
+{
+  asm volatile ("fmina.d \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
+  return x;
+}
+libm_alias_double (__fminmag, fminmag)
diff --git a/sysdeps/loongarch/fpu/s_fminmagf.c b/sysdeps/loongarch/fpu/s_fminmagf.c
new file mode 100644
index 00000000..4d625312
--- /dev/null
+++ b/sysdeps/loongarch/fpu/s_fminmagf.c
@@ -0,0 +1,29 @@
+/* fminmagf().  LoongArch version.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#define NO_MATH_REDIRECT
+#include <math.h>
+#include <libm-alias-float.h>
+
+float
+__fminmagf (float x, float y)
+{
+  asm volatile ("fmina.s \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
+  return x;
+}
+libm_alias_float (__fminmag, fminmag)
diff --git a/sysdeps/loongarch/fpu/s_fpclassify.c b/sysdeps/loongarch/fpu/s_fpclassify.c
new file mode 100644
index 00000000..3f4d95da
--- /dev/null
+++ b/sysdeps/loongarch/fpu/s_fpclassify.c
@@ -0,0 +1,38 @@
+/* fpclassify().  LoongArch version.
+   Copyright (C) 2017-2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <fenv_private.h>
+
+int
+__fpclassify (double x)
+{
+  int cls;
+  asm volatile ("fclass.d \t%0, %1" : "=f" (cls) : "f" (x));
+
+  if (__glibc_likely (!!(cls & _FCLASS_NORM)))
+    return FP_NORMAL;
+  if (__glibc_likely (!!(cls & _FCLASS_ZERO)))
+    return FP_ZERO;
+  if (__glibc_likely (!!(cls & _FCLASS_SUBNORM)))
+    return FP_SUBNORMAL;
+  if (__glibc_likely (!!(cls & _FCLASS_INF)))
+    return FP_INFINITE;
+  return FP_NAN;
+}
+libm_hidden_def (__fpclassify)
diff --git a/sysdeps/loongarch/fpu/s_fpclassifyf.c b/sysdeps/loongarch/fpu/s_fpclassifyf.c
new file mode 100644
index 00000000..b7c8b253
--- /dev/null
+++ b/sysdeps/loongarch/fpu/s_fpclassifyf.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 2017-2022 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <fenv_private.h>
+
+int
+__fpclassifyf (float x)
+{
+  int cls;
+  asm volatile ("fclass.s \t%0, %1" : "=f" (cls) : "f" (x));
+
+  if (__glibc_likely (!!(cls & _FCLASS_NORM)))
+    return FP_NORMAL;
+  if (__glibc_likely (!!(cls & _FCLASS_ZERO)))
+    return FP_ZERO;
+  if (__glibc_likely (!!(cls & _FCLASS_SUBNORM)))
+    return FP_SUBNORMAL;
+  if (__glibc_likely (!!(cls & _FCLASS_INF)))
+    return FP_INFINITE;
+  return FP_NAN;
+}
+libm_hidden_def (__fpclassifyf)
diff --git a/sysdeps/loongarch/fpu/s_isinf.c b/sysdeps/loongarch/fpu/s_isinf.c
new file mode 100644
index 00000000..c7a67841
--- /dev/null
+++ b/sysdeps/loongarch/fpu/s_isinf.c
@@ -0,0 +1,30 @@
+/* isinf().  LoongArch version.
+   Copyright (C) 2017-2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <fenv_private.h>
+
+int
+__isinf (double x)
+{
+  int x_cond;
+  asm volatile ("fclass.d \t%0, %1" : "=f" (x_cond) : "f" (x));
+  return -((x_cond & _FCLASS_MINF) ? 1 : 0) | ((x_cond & _FCLASS_PINF) ? 1 : 0);
+}
+hidden_def (__isinf)
+weak_alias (__isinf, isinf)
diff --git a/sysdeps/loongarch/fpu/s_isinff.c b/sysdeps/loongarch/fpu/s_isinff.c
new file mode 100644
index 00000000..dcb4e04e
--- /dev/null
+++ b/sysdeps/loongarch/fpu/s_isinff.c
@@ -0,0 +1,30 @@
+/* isinff().  LoongArch version.
+   Copyright (C) 2017-2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <fenv_private.h>
+
+int
+__isinff (float x)
+{
+  int x_cond;
+  asm volatile ("fclass.s \t%0, %1" : "=f" (x_cond) : "f" (x));
+  return -((x_cond & _FCLASS_MINF) ? 1 : 0) | ((x_cond & _FCLASS_PINF) ? 1 : 0);
+}
+hidden_def (__isinff)
+weak_alias (__isinff, isinff)
diff --git a/sysdeps/loongarch/fpu/s_isnan.c b/sysdeps/loongarch/fpu/s_isnan.c
new file mode 100644
index 00000000..62bb2e2f
--- /dev/null
+++ b/sysdeps/loongarch/fpu/s_isnan.c
@@ -0,0 +1,31 @@
+/* isnan().  LoongArch version.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <fenv_private.h>
+
+int
+__isnan (double x)
+{
+  int x_cond;
+  asm volatile ("fclass.d \t%0, %1" : "=f" (x_cond) : "f" (x));
+
+  return (x_cond & _FCLASS_NAN) != 0;
+}
+hidden_def (__isnan)
+weak_alias (__isnan, isnan)
diff --git a/sysdeps/loongarch/fpu/s_isnanf.c b/sysdeps/loongarch/fpu/s_isnanf.c
new file mode 100644
index 00000000..bbdedb84
--- /dev/null
+++ b/sysdeps/loongarch/fpu/s_isnanf.c
@@ -0,0 +1,31 @@
+/* isnanf().  LoongArch version.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <fenv_private.h>
+
+int
+__isnanf (float x)
+{
+  int x_cond;
+  asm volatile ("fclass.s \t%0, %1" : "=f" (x_cond) : "f" (x));
+
+  return (x_cond & _FCLASS_NAN) != 0;
+}
+hidden_def (__isnanf)
+weak_alias (__isnanf, isnanf)
diff --git a/sysdeps/loongarch/fpu/s_issignaling.c b/sysdeps/loongarch/fpu/s_issignaling.c
new file mode 100644
index 00000000..4fe0e2b7
--- /dev/null
+++ b/sysdeps/loongarch/fpu/s_issignaling.c
@@ -0,0 +1,29 @@
+/* issignaling().  LoongArch version.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <fenv_private.h>
+
+int
+__issignaling (double x)
+{
+  int x_cond;
+  asm volatile ("fclass.d \t%0, %1" : "=f" (x_cond) : "f" (x));
+  return (x_cond & _FCLASS_SNAN) != 0;
+}
+libm_hidden_def (__issignaling)
diff --git a/sysdeps/loongarch/fpu/s_issignalingf.c b/sysdeps/loongarch/fpu/s_issignalingf.c
new file mode 100644
index 00000000..d82abb0e
--- /dev/null
+++ b/sysdeps/loongarch/fpu/s_issignalingf.c
@@ -0,0 +1,29 @@
+/* issignalingf().  LoongArch version.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <fenv_private.h>
+
+int
+__issignalingf (float x)
+{
+  int x_cond;
+  asm volatile ("fclass.s \t%0, %1" : "=f" (x_cond) : "f" (x));
+  return (x_cond & _FCLASS_SNAN) != 0;
+}
+libm_hidden_def (__issignalingf)
diff --git a/sysdeps/loongarch/fpu/s_llrint.c b/sysdeps/loongarch/fpu/s_llrint.c
new file mode 100644
index 00000000..4a8e46ec
--- /dev/null
+++ b/sysdeps/loongarch/fpu/s_llrint.c
@@ -0,0 +1,31 @@
+/* llrint().  LoongArch version.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#define NO_MATH_REDIRECT
+#include <math.h>
+#include <libm-alias-double.h>
+
+long long int
+__llrint (double x)
+{
+  long long int result;
+  asm volatile ("ftint.l.d \t%0, %1" : "=f" (x) : "f" (x));
+  asm volatile ("movfr2gr.d \t%0, %1" : "=r" (result) : "f" (x));
+  return result;
+}
+libm_alias_double (__llrint, llrint)
diff --git a/sysdeps/loongarch/fpu/s_llrintf.c b/sysdeps/loongarch/fpu/s_llrintf.c
new file mode 100644
index 00000000..f3a874a0
--- /dev/null
+++ b/sysdeps/loongarch/fpu/s_llrintf.c
@@ -0,0 +1,31 @@
+/* llrintf().  LoongArch version.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#define NO_MATH_REDIRECT
+#include <math.h>
+#include <libm-alias-float.h>
+
+long long int
+__llrintf (float x)
+{
+  long long int result;
+  asm volatile ("ftint.l.s \t%0, %1" : "=f" (x) : "f" (x));
+  asm volatile ("movfr2gr.d \t%0, %1" : "=r" (result) : "f" (x));
+  return result;
+}
+libm_alias_float (__llrint, llrint)
diff --git a/sysdeps/loongarch/fpu/s_logb.c b/sysdeps/loongarch/fpu/s_logb.c
new file mode 100644
index 00000000..31bb3be5
--- /dev/null
+++ b/sysdeps/loongarch/fpu/s_logb.c
@@ -0,0 +1,30 @@
+/* logb().  LoongArch version.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#define NO_MATH_REDIRECT
+#include <math.h>
+#include <libm-alias-double.h>
+
+double
+__logb (double x)
+{
+  asm volatile ("fabs.d \t%0, %1" : "=f" (x) : "f" (x));
+  asm volatile ("flogb.d \t%0, %1" : "=f" (x) : "f" (x));
+  return x;
+}
+libm_alias_double (__logb, logb)
diff --git a/sysdeps/loongarch/fpu/s_logbf.c b/sysdeps/loongarch/fpu/s_logbf.c
new file mode 100644
index 00000000..f5166bca
--- /dev/null
+++ b/sysdeps/loongarch/fpu/s_logbf.c
@@ -0,0 +1,30 @@
+/* logbf().  LoongArch version.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#define NO_MATH_REDIRECT
+#include <math.h>
+#include <libm-alias-float.h>
+
+float
+__logbf (float x)
+{
+  asm volatile ("fabs.s \t%0, %1" : "=f" (x) : "f" (x));
+  asm volatile ("flogb.s \t%0, %1" : "=f" (x) : "f" (x));
+  return x;
+}
+libm_alias_float (__logb, logb)
diff --git a/sysdeps/loongarch/fpu/s_lrint.c b/sysdeps/loongarch/fpu/s_lrint.c
new file mode 100644
index 00000000..db446111
--- /dev/null
+++ b/sysdeps/loongarch/fpu/s_lrint.c
@@ -0,0 +1,31 @@
+/* lrint().  LoongArch version.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#define NO_MATH_REDIRECT
+#include <math.h>
+#include <libm-alias-double.h>
+
+long int
+__lrint (double x)
+{
+  long int result;
+  asm volatile ("ftint.l.d \t%0, %1" : "=f" (x) : "f" (x));
+  asm volatile ("movfr2gr.d \t%0, %1" : "=r" (result) : "f" (x));
+  return result;
+}
+libm_alias_double (__lrint, lrint)
diff --git a/sysdeps/loongarch/fpu/s_lrintf.c b/sysdeps/loongarch/fpu/s_lrintf.c
new file mode 100644
index 00000000..cde60b88
--- /dev/null
+++ b/sysdeps/loongarch/fpu/s_lrintf.c
@@ -0,0 +1,31 @@
+/* lrintf().  LoongArch version.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#define NO_MATH_REDIRECT
+#include <math.h>
+#include <libm-alias-float.h>
+
+long int
+__lrintf (float x)
+{
+  long int result;
+  asm volatile ("ftint.l.s \t%0, %1" : "=f" (x) : "f" (x));
+  asm volatile ("movfr2gr.d \t%0, %1" : "=r" (result) : "f" (x));
+  return result;
+}
+libm_alias_float (__lrint, lrint)
diff --git a/sysdeps/loongarch/fpu/s_rint.c b/sysdeps/loongarch/fpu/s_rint.c
new file mode 100644
index 00000000..429d5d11
--- /dev/null
+++ b/sysdeps/loongarch/fpu/s_rint.c
@@ -0,0 +1,29 @@
+/* rint().  LoongArch version.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#define NO_MATH_REDIRECT
+#include <math.h>
+#include <libm-alias-double.h>
+
+double
+__rint (double x)
+{
+  asm volatile ("frint.d \t%0, %1" : "=f" (x) : "f" (x));
+  return x;
+}
+libm_alias_double (__rint, rint)
diff --git a/sysdeps/loongarch/fpu/s_rintf.c b/sysdeps/loongarch/fpu/s_rintf.c
new file mode 100644
index 00000000..b3faba20
--- /dev/null
+++ b/sysdeps/loongarch/fpu/s_rintf.c
@@ -0,0 +1,29 @@
+/* rintf().  LoongArch version.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#define NO_MATH_REDIRECT
+#include <math.h>
+#include <libm-alias-float.h>
+
+float
+__rintf (float x)
+{
+  asm volatile ("frint.s \t%0, %1" : "=f" (x) : "f" (x));
+  return x;
+}
+libm_alias_float (__rint, rint)
diff --git a/sysdeps/loongarch/fpu/s_scalbn.c b/sysdeps/loongarch/fpu/s_scalbn.c
new file mode 100644
index 00000000..c03e81a3
--- /dev/null
+++ b/sysdeps/loongarch/fpu/s_scalbn.c
@@ -0,0 +1,29 @@
+/* scalbn().  LoongArch version.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#define NO_MATH_REDIRECT
+#include <math.h>
+
+double
+__scalbn (double x, int fn)
+{
+  double tmp;
+  asm volatile ("movgr2fr.d \t%0, %1" : "=f" (tmp) : "r" (fn));
+  asm volatile ("fscaleb.d \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (tmp));
+  return x;
+}
diff --git a/sysdeps/loongarch/fpu/s_scalbnf.c b/sysdeps/loongarch/fpu/s_scalbnf.c
new file mode 100644
index 00000000..15e64280
--- /dev/null
+++ b/sysdeps/loongarch/fpu/s_scalbnf.c
@@ -0,0 +1,29 @@
+/* scalbnf().  LoongArch version.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#define NO_MATH_REDIRECT
+#include <math.h>
+
+float
+__scalbnf (float x, int fn)
+{
+  float tmp;
+  asm volatile ("movgr2fr.w \t%0, %1" : "=f" (tmp) : "r" (fn));
+  asm volatile ("fscaleb.s \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (tmp));
+  return x;
+}
diff --git a/sysdeps/loongarch/fpu_control.h b/sysdeps/loongarch/fpu_control.h
new file mode 100644
index 00000000..8f688592
--- /dev/null
+++ b/sysdeps/loongarch/fpu_control.h
@@ -0,0 +1,128 @@
+/* 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;
+
+# define _FCLASS_SNAN     (1 << 0)
+# define _FCLASS_QNAN     (1 << 1)
+# define _FCLASS_MINF     (1 << 2)
+# define _FCLASS_MNORM    (1 << 3)
+# define _FCLASS_MSUBNORM (1 << 4)
+# define _FCLASS_MZERO    (1 << 5)
+# define _FCLASS_PINF     (1 << 6)
+# define _FCLASS_PNORM    (1 << 7)
+# define _FCLASS_PSUBNORM (1 << 8)
+# define _FCLASS_PZERO    (1 << 9)
+
+# define _FCLASS_ZERO     (_FCLASS_MZERO | _FCLASS_PZERO)
+# define _FCLASS_SUBNORM  (_FCLASS_MSUBNORM | _FCLASS_PSUBNORM)
+# define _FCLASS_NORM     (_FCLASS_MNORM | _FCLASS_PNORM)
+# define _FCLASS_INF      (_FCLASS_MINF | _FCLASS_PINF)
+# define _FCLASS_NAN      (_FCLASS_SNAN | _FCLASS_QNAN)
+
+#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/init-arch.h b/sysdeps/loongarch/init-arch.h
new file mode 100644
index 00000000..7db7b7b3
--- /dev/null
+++ b/sysdeps/loongarch/init-arch.h
@@ -0,0 +1,24 @@
+/* This file is part of the GNU C Library.
+   Copyright (C) 2008-2022 Free Software Foundation, Inc.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <ldsodefs.h>
+#include <ifunc-init.h>
+
+#define INIT_ARCH()                           \
+  uint64_t __attribute__((unused)) prid =     \
+    GLRO(dl_larch_cpu_features).cpucfg_prid;  \
+
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..f3c07709
--- /dev/null
+++ b/sysdeps/loongarch/ldsodefs.h
@@ -0,0 +1,48 @@
+/* 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>
+#include <cpu-features.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..7bbc658f
--- /dev/null
+++ b/sysdeps/loongarch/libc-start.h
@@ -0,0 +1,25 @@
+/* LoongArch definitions for libc main startup.
+   Copyright (C) 2023 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()  apply_irel ()
+# define ARCH_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/memchr.S b/sysdeps/loongarch/lp64/memchr.S
new file mode 100644
index 00000000..ec34b1af
--- /dev/null
+++ b/sysdeps/loongarch/lp64/memchr.S
@@ -0,0 +1,99 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <sys/asm.h>
+#include <sys/regdef.h>
+#endif
+
+#ifndef MEMCHR_NAME
+#define MEMCHR_NAME memchr
+#endif
+
+#ifdef ANDROID_CHANGES
+LEAF(MEMCHR_NAME, 0)
+#else
+LEAF(MEMCHR_NAME)
+#endif
+    .align      6
+    beqz        a2, L(out)
+    andi        t1, a0, 0x7
+    lu12i.w     a3, 0x01010
+    sub.d       a5, a0, t1
+
+    bstrins.d   a1, a1, 15, 8
+    ld.d        t0, a5, 0
+    slli.d      t2, t1, 3
+    ori         a3, a3, 0x101
+
+    bstrins.d   a1, a1, 31, 16
+    li.w        t7, -1
+    li.w        t8, 9
+    bstrins.d   a3, a3, 63, 32
+
+    srl.d       t3, t7, t2
+    bstrins.d   a1, a1, 63, 32
+    sub.d       t4, t8, t1
+    orn         t3, a1, t3
+
+    srl.d       t0, t0, t2
+    slli.d      a4, a3, 7   # 0x8080808080808080
+    sltu        t4, a2, t4
+    xor         t2, t0, t3
+
+    sub.d       a6, t2, a3
+    andn        a7, a4, t2
+    and         t2, a6, a7
+    or          t3, t2, t4
+
+    bnez        t3, L(count_pos)
+    addi.d      a2, a2, -8
+    addi.d      a0, a5, 8
+    add.d       a2, a2, t1
+
+L(loop):
+    ld.d        t0, a0, 0
+    sltui       t4, a2, 9
+    xor         t2, t0, a1
+    sub.d       a6, t2, a3
+
+    andn        a7, a4, t2
+    and         t2, a6, a7
+    or          t3, t2, t4
+    bnez        t3, L(count_pos)
+
+    ld.d        t1, a0, 8
+    addi.d      a0, a0, 16
+    sltui       t4, a2, 17
+    xor         t2, t1, a1
+
+    sub.d       a6, t2, a3
+    andn        a7, a4, t2
+    and         t2, a6, a7
+    addi.d      a2, a2, -16
+
+    or          t3, t2, t4
+    beqz        t3, L(loop)
+    addi.d      a0, a0, -8
+    addi.d      a2, a2, 8
+
+L(count_pos):
+    ctz.d       t0, t2
+    srli.d      t0, t0, 3
+    sltu        t1, t0, a2
+    add.d       a0, a0, t0
+
+    maskeqz     a0, a0, t1
+    jr          ra
+
+L(out):
+    move        a0, zero
+    jr          ra
+END(MEMCHR_NAME)
+
+#ifndef ANDROID_CHANGES
+#ifdef _LIBC
+libc_hidden_builtin_def (MEMCHR_NAME)
+#endif
+#endif
diff --git a/sysdeps/loongarch/lp64/memcmp.S b/sysdeps/loongarch/lp64/memcmp.S
new file mode 100644
index 00000000..9e57a924
--- /dev/null
+++ b/sysdeps/loongarch/lp64/memcmp.S
@@ -0,0 +1,281 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <sys/asm.h>
+#include <sys/regdef.h>
+#endif
+
+#ifndef MEMCMP_NAME
+#define MEMCMP_NAME memcmp
+#endif
+
+LEAF(MEMCMP_NAME)
+    .align      6
+    beqz        a2, L(ret)
+    andi        a4, a1, 0x7
+    andi        a3, a0, 0x7
+    sltu        a5, a4, a3
+
+    xor         t0, a0, a1
+    li.w        t8, 8
+    maskeqz     t0, t0, a5
+    li.w        t7, -1
+
+    xor         a0, a0, t0	// a0 hold smaller one
+    xor         a1, a1, t0	// a1 hold larger one
+    andi        a3, a0, 0x7	// a3 hold small offset
+    andi        a4, a1, 0x7	// a4 hold larger offset
+
+    xor         a0, a0, a3
+    xor         a1, a1, a4
+    ld.d        t2, a0, 0	// t2 = "fedcbaXX"
+    ld.d        t1, a1, 0	// t1 = "54321YYY"
+
+    slli.d      t3, a3, 3
+    slli.d      t4, a4, 3
+    sub.d       a6, t3, t4	// a6 = 0xfffffffffffffff8
+    srl.d       t1, t1, t4	// t1 = "00054321"
+
+    srl.d       t0, t2, t3	// t0 = "00fedcba"
+    srl.d       t5, t7, t4	// t5 = 0x000000FFFFFFFFFF
+    sub.d       t6, t0, t1	// t6 hold diff
+    and         t6, t6, t5	// t6 = "000xxxxx"
+
+    sub.d       t5, t8, a4	// t5 hold margin 8 - 3 = 5
+    bnez        t6, L(first_out)
+    bgeu        t5, a2, L(ret)
+    sub.d       a2, a2, t5
+
+    bnez        a6, L(unaligned)
+    blt         a2, t8, L(al_less_8bytes)
+    andi        t1, a2, 31
+    beq         t1, a2, L(al_less_32bytes)
+
+    sub.d       t2, a2, t1
+    add.d       a4, a0, t2
+    move        a2, t1
+
+L(al_loop):
+    ld.d        t0, a0, 8
+
+    ld.d        t1, a1, 8
+    ld.d        t2, a0, 16
+    ld.d        t3, a1, 16
+    ld.d        t4, a0, 24
+
+    ld.d        t5, a1, 24
+    ld.d        t6, a0, 32
+    ld.d        t7, a1, 32
+    addi.d      a0, a0, 32
+
+    addi.d      a1, a1, 32
+    bne         t0, t1, L(out1)
+    bne         t2, t3, L(out2)
+    bne         t4, t5, L(out3)
+
+    bne         t6, t7, L(out4)
+    bne         a0, a4, L(al_loop)
+
+L(al_less_32bytes):
+    srai.d      a4, a2, 4
+    beqz        a4, L(al_less_16bytes)
+
+    ld.d        t0, a0, 8
+    ld.d        t1, a1, 8
+    ld.d        t2, a0, 16
+    ld.d        t3, a1, 16
+
+    addi.d      a0, a0, 16
+    addi.d      a1, a1, 16
+    addi.d      a2, a2, -16
+    bne         t0, t1, L(out1)
+
+    bne         t2, t3, L(out2)
+
+L(al_less_16bytes):
+    srai.d      a4, a2, 3
+    beqz        a4, L(al_less_8bytes)
+    ld.d        t0, a0, 8
+
+    ld.d        t1, a1, 8
+    addi.d      a0, a0, 8
+    addi.d      a1, a1, 8
+    addi.d      a2, a2, -8
+
+    bne         t0, t1, L(out1)
+
+L(al_less_8bytes):
+    beqz        a2, L(ret)
+    ld.d        t0, a0, 8
+    ld.d        t1, a1, 8
+
+    li.d        t7, -1
+    slli.d      t2, a2, 3
+    sll.d       t2, t7, t2
+    sub.d       t3, t0, t1
+
+    andn        t6, t3, t2
+    bnez        t6, L(count_diff)
+
+L(ret):
+    move        a0, zero
+    jr          ra
+
+L(out4):
+    move        t0, t6
+    move        t1, t7
+    sub.d       t6, t6, t7
+    b           L(count_diff)
+
+L(out3):
+    move        t0, t4
+    move        t1, t5
+    sub.d       t6, t4, t5
+    b           L(count_diff)
+
+L(out2):
+    move        t0, t2
+    move        t1, t3
+L(out1):
+    sub.d       t6, t0, t1
+    b           L(count_diff)
+
+L(first_out):
+    slli.d      t4, a2, 3
+    slt         t3, a2, t5
+    sll.d       t4, t7, t4
+    maskeqz     t4, t4, t3
+
+    andn        t6, t6, t4
+
+L(count_diff):
+    ctz.d       t2, t6
+    bstrins.d   t2, zero, 2, 0
+    srl.d       t0, t0, t2
+
+    srl.d       t1, t1, t2
+    andi        t0, t0, 0xff
+    andi        t1, t1, 0xff
+    sub.d       t2, t0, t1
+
+    sub.d       t3, t1, t0
+    masknez     t2, t2, a5
+    maskeqz     t3, t3, a5
+    or          a0, t2, t3
+
+    jr          ra
+
+L(unaligned):
+    sub.d       a7, zero, a6
+    srl.d       t0, t2, a6
+    blt         a2, t8, L(un_less_8bytes)
+
+    andi        t1, a2, 31
+    beq         t1, a2, L(un_less_32bytes)
+    sub.d       t2, a2, t1
+    add.d       a4, a0, t2
+
+    move        a2, t1
+
+L(un_loop):
+    ld.d        t2, a0, 8
+    ld.d        t1, a1, 8
+    ld.d        t4, a0, 16
+
+    ld.d        t3, a1, 16
+    ld.d        t6, a0, 24
+    ld.d        t5, a1, 24
+    ld.d        t8, a0, 32
+
+    ld.d        t7, a1, 32
+    addi.d      a0, a0, 32
+    addi.d      a1, a1, 32
+    sll.d       a3, t2, a7
+
+    or          t0, a3, t0
+    bne         t0, t1, L(out1)
+    srl.d       t0, t2, a6
+    sll.d       a3, t4, a7
+
+    or          t2, a3, t0
+    bne         t2, t3, L(out2)
+    srl.d       t0, t4, a6
+    sll.d       a3, t6, a7
+
+    or          t4, a3, t0
+    bne         t4, t5, L(out3)
+    srl.d       t0, t6, a6
+    sll.d       a3, t8, a7
+
+    or          t6, t0, a3
+    bne         t6, t7, L(out4)
+    srl.d       t0, t8, a6
+    bne         a0, a4, L(un_loop)
+
+L(un_less_32bytes):
+    srai.d      a4, a2, 4
+    beqz        a4, L(un_less_16bytes)
+    ld.d        t2, a0, 8
+    ld.d        t1, a1, 8
+
+    ld.d        t4, a0, 16
+    ld.d        t3, a1, 16
+    addi.d      a0, a0, 16
+    addi.d      a1, a1, 16
+
+    addi.d      a2, a2, -16
+    sll.d       a3, t2, a7
+    or          t0, a3, t0
+    bne         t0, t1, L(out1)
+
+    srl.d       t0, t2, a6
+    sll.d       a3, t4, a7
+    or          t2, a3, t0
+    bne         t2, t3, L(out2)
+
+    srl.d       t0, t4, a6
+
+L(un_less_16bytes):
+    srai.d      a4, a2, 3
+    beqz        a4, L(un_less_8bytes)
+    ld.d        t2, a0, 8
+
+    ld.d        t1, a1, 8
+    addi.d      a0, a0, 8
+    addi.d      a1, a1, 8
+    addi.d      a2, a2, -8
+
+    sll.d       a3, t2, a7
+    or          t0, a3, t0
+    bne         t0, t1, L(out1)
+    srl.d       t0, t2, a6
+
+L(un_less_8bytes):
+    beqz        a2, L(ret)
+    andi        a7, a7, 63
+    slli.d      a4, a2, 3
+    bgeu        a7, a4, L(last_cmp)
+
+    ld.d        t2, a0, 8
+    sll.d       a3, t2, a7
+    or          t0, a3, t0
+
+L(last_cmp):
+    ld.d        t1, a1, 8
+
+    li.d        t7, -1
+    sll.d       t2, t7, a4
+    sub.d       t3, t0, t1
+    andn        t6, t3, t2
+
+    bnez        t6, L(count_diff)
+    move        a0, zero
+    jr          ra
+
+END(MEMCMP_NAME)
+
+#ifdef _LIBC
+libc_hidden_builtin_def (MEMCMP_NAME)
+#endif
diff --git a/sysdeps/loongarch/lp64/memcpy.S b/sysdeps/loongarch/lp64/memcpy.S
new file mode 100644
index 00000000..1076e678
--- /dev/null
+++ b/sysdeps/loongarch/lp64/memcpy.S
@@ -0,0 +1,818 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <regdef.h>
+#include <sys/asm.h>
+#endif
+
+#ifndef MEMCPY_NAME
+#define MEMCPY_NAME memcpy
+#endif
+
+#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;
+
+#ifdef ANDROID_CHANGES
+LEAF(MEMMOVE_NAME, 0)
+#else
+LEAF(MEMMOVE_NAME)
+#endif
+
+    .align      6
+    sub.d       t0, a0, a1
+    bltu        t0, a2, L(copy_back)
+
+END(MEMMOVE_NAME)
+
+#ifndef ANDROID_CHANGES
+#ifdef _LIBC
+libc_hidden_builtin_def (MEMMOVE_NAME)
+#endif
+#endif
+
+#ifdef ANDROID_CHANGES
+LEAF(MEMCPY_NAME, 0)
+#else
+LEAF(MEMCPY_NAME)
+#endif
+
+    srai.d      a3, a2, 4
+    beqz        a3, L(short_data)  # less than 16 bytes
+
+    move        a4, a0
+    andi        a5, a0, 0x7
+    andi        a6, a1, 0x7
+    li.d        t8, 8
+    beqz        a5, L(check_align)
+
+    # make dest aligned 8 bytes
+    sub.d       t2, t8, a5
+    sub.d       a2, a2, t2
+
+    pcaddi      t1, 20
+    slli.d      t3, t2, 3
+    add.d       a1, a1, t2
+    sub.d       t1, t1, t3
+    add.d       a4, a4, t2
+    jr          t1
+
+L(al7):
+    ld.b        t0, a1, -7
+    st.b        t0, a4, -7
+L(al6):
+    ld.b        t0, a1, -6
+    st.b        t0, a4, -6
+L(al5):
+    ld.b        t0, a1, -5
+    st.b        t0, a4, -5
+L(al4):
+    ld.b        t0, a1, -4
+    st.b        t0, a4, -4
+L(al3):
+    ld.b        t0, a1, -3
+    st.b        t0, a4, -3
+L(al2):
+    ld.b        t0, a1, -2
+    st.b        t0, a4, -2
+L(al1):
+    ld.b        t0, a1, -1
+    st.b        t0, a4, -1
+
+L(check_align):
+    bne         a5, a6, L(unalign)
+
+    srai.d      a3, a2, 4
+    beqz        a3, L(al_less_16bytes)
+
+    andi        a3, a2, 0x3f
+    beq         a3, a2, L(al_less_64bytes)
+
+    sub.d       t0, a2, a3
+    move        a2, a3
+    add.d       a5, a1, t0
+
+L(loop_64bytes):
+    LD_64(a1, 0)
+    addi.d      a1, a1, 64
+    ST_64(a4, 0)
+
+    addi.d      a4, a4, 64
+    bne         a1, a5, L(loop_64bytes)
+
+L(al_less_64bytes):
+    srai.d     a3, a2, 5
+    beqz       a3, L(al_less_32bytes)
+
+    ld.d       t0, a1, 0
+    ld.d       t1, a1, 8
+    ld.d       t2, a1, 16
+    ld.d       t3, a1, 24
+
+    addi.d     a1, a1, 32
+    addi.d     a2, a2, -32
+
+    st.d       t0, a4, 0
+    st.d       t1, a4, 8
+    st.d       t2, a4, 16
+    st.d       t3, a4, 24
+
+    addi.d     a4, a4, 32
+
+L(al_less_32bytes):
+    srai.d     a3, a2, 4
+    beqz       a3, L(al_less_16bytes)
+
+    ld.d       t0, a1, 0
+    ld.d       t1, a1, 8
+    addi.d     a1, a1, 16
+    addi.d     a2, a2, -16
+
+    st.d       t0, a4, 0
+    st.d       t1, a4, 8
+    addi.d     a4, a4, 16
+
+L(al_less_16bytes):
+    srai.d     a3, a2, 3
+    beqz       a3, L(al_less_8bytes)
+
+    ld.d       t0, a1, 0
+    addi.d     a1, a1, 8
+    addi.d     a2, a2, -8
+
+    st.d       t0, a4, 0
+    addi.d     a4, a4, 8
+
+L(al_less_8bytes):
+    srai.d      a3, a2, 2
+    beqz        a3, L(al_less_4bytes)
+
+    ld.w        t0, a1, 0
+    addi.d      a1, a1, 4
+    addi.d      a2, a2, -4
+
+    st.w        t0, a4, 0
+    addi.d      a4, a4, 4
+
+L(al_less_4bytes):
+    srai.d      a3, a2, 1
+    beqz        a3, L(al_less_2bytes)
+
+    ld.h        t0, a1, 0
+    addi.d      a1, a1, 2
+    addi.d      a2, a2, -2
+
+    st.h        t0, a4, 0
+    addi.d      a4, a4, 2
+
+L(al_less_2bytes):
+    beqz        a2, L(al_less_1byte)
+
+    ld.b        t0, a1, 0
+    st.b        t0, a4, 0
+
+L(al_less_1byte):
+    jr          ra
+
+L(unalign):
+    andi        a5, a1, 0x7
+    bstrins.d   a1, zero, 2, 0   # make src 8 bytes aligned
+
+    sub.d       t8, t8, a5  # use t8 to save count of bytes for aligning
+    slli.d      a5, a5, 3
+
+    ld.d        t0, a1, 0
+    addi.d      a1, a1, 8
+
+    slli.d      a6, t8, 3
+    srl.d       a7, t0, a5
+
+    srai.d      a3, a2, 4
+    beqz        a3, L(un_less_16bytes)
+
+    andi        a3, a2, 0x3f
+    beq         a3, a2, L(un_less_64bytes)
+
+    sub.d       t0, a2, a3
+    move        a2, a3
+    add.d       a3, a1, t0
+
+# a5 shift right num
+# a6 shift left num
+# a7 remaining part
+L(un_long_bytes):
+    ld.d        t0, a1, 0
+    ld.d        t1, a1, 8
+    ld.d        t2, a1, 16
+    ld.d        t3, a1, 24
+
+    srl.d       t4, t0, a5
+    sll.d       t0, t0, a6
+
+    srl.d       t5, t1, a5
+    sll.d       t1, t1, a6
+
+    srl.d       t6, t2, a5
+    sll.d       t2, t2, a6
+
+    srl.d       t7, t3, a5
+    sll.d       t3, t3, a6
+
+    or          t0, a7, t0
+    or          t1, t4, t1
+    or          t2, t5, t2
+    or          t3, t6, t3
+
+    ld.d        t4, a1, 32
+    ld.d        t5, a1, 40
+    ld.d        t6, a1, 48
+    ld.d        a7, a1, 56
+
+    st.d        t0, a4, 0
+    st.d        t1, a4, 8
+    st.d        t2, a4, 16
+    st.d        t3, a4, 24
+
+    addi.d      a1, a1, 64
+
+    srl.d       t0, t4, a5
+    sll.d       t4, t4, a6
+
+    srl.d       t1, t5, a5
+    sll.d       t5, t5, a6
+
+    srl.d       t2, t6, a5
+    sll.d       t6, t6, a6
+
+    sll.d       t3, a7, a6
+    srl.d       a7, a7, a5
+
+    or          t4, t7, t4
+    or          t5, t0, t5
+    or          t6, t1, t6
+    or          t3, t2, t3
+
+    st.d        t4, a4, 32
+    st.d        t5, a4, 40
+    st.d        t6, a4, 48
+    st.d        t3, a4, 56
+
+    addi.d      a4, a4, 64
+    bne         a3, a1, L(un_long_bytes)
+
+L(un_less_64bytes):
+    srai.d	a3, a2, 5
+    beqz	a3, L(un_less_32bytes)
+
+    ld.d        t0, a1, 0
+    ld.d        t1, a1, 8
+    ld.d        t2, a1, 16
+    ld.d        t3, a1, 24
+
+    addi.d      a1, a1, 32
+    addi.d      a2, a2, -32
+
+    srl.d       t4, t0, a5
+    sll.d       t0, t0, a6
+
+    srl.d       t5, t1, a5
+    sll.d       t1, t1, a6
+
+    srl.d       t6, t2, a5
+    sll.d       t2, t2, a6
+
+    or          t0, a7, t0
+
+    srl.d       a7, t3, a5
+    sll.d       t3, t3, a6
+
+    or          t1, t4, t1
+    or          t2, t5, t2
+    or          t3, t6, t3
+
+    st.d        t0, a4, 0
+    st.d        t1, a4, 8
+    st.d        t2, a4, 16
+    st.d        t3, a4, 24
+
+    addi.d      a4, a4, 32
+
+L(un_less_32bytes):
+    srai.d      a3, a2, 4
+    beqz        a3, L(un_less_16bytes)
+
+    ld.d        t0, a1, 0
+    ld.d        t1, a1, 8
+
+    addi.d      a1, a1, 16
+    addi.d      a2, a2, -16
+
+    srl.d       t2, t0, a5
+    sll.d       t3, t0, a6
+
+    sll.d       t4, t1, a6
+    or          t3, a7, t3
+    or          t4, t2, t4
+    srl.d       a7, t1, a5
+
+    st.d        t3, a4, 0
+    st.d        t4, a4, 8
+
+    addi.d      a4, a4, 16
+
+L(un_less_16bytes):
+    srai.d      a3, a2, 3
+    beqz        a3, L(un_less_8bytes)
+
+    ld.d        t0, a1, 0
+
+    addi.d      a1, a1, 8
+    addi.d      a2, a2, -8
+
+    sll.d       t1, t0, a6
+    or          t2, a7, t1
+    srl.d       a7, t0, a5
+
+    st.d        t2, a4, 0
+    addi.d      a4, a4, 8
+
+L(un_less_8bytes):
+    beqz        a2, L(un_less_1byte)
+    bge         t8, a2, 1f # no more data in memory, un_less_8bytes data is stored in a7
+
+    # combine data in memory and a7(remaining part)
+    ld.d        t0, a1, 0
+    sll.d       t0, t0, a6
+    or          a7, a7, t0
+
+1:
+    srai.d      a3, a2, 2
+    beqz        a3, L(un_less_4bytes)
+
+    addi.d      a2, a2, -4
+    st.w        a7, a4, 0
+    addi.d      a4, a4, 4
+    srai.d      a7, a7, 32
+
+L(un_less_4bytes):
+    srai.d      a3, a2, 1
+    beqz        a3, L(un_less_2bytes)
+
+    addi.d      a2, a2, -2
+    st.h        a7, a4, 0
+    addi.d      a4, a4, 2
+    srai.d      a7, a7, 16
+
+L(un_less_2bytes):
+    beqz        a2, L(un_less_1byte)
+    st.b        a7, a4, 0
+
+L(un_less_1byte):
+    jr          ra
+
+# Bytes copying for data less than 16 bytes
+L(short_data):
+    pcaddi      t1, 36
+    slli.d      t2, a2, 3
+    add.d       a4, a0, a2
+    sub.d       t1, t1, t2
+    add.d       a1, a1, a2
+    jr          t1
+
+L(short_15_bytes):
+    ld.b       t0, a1, -15
+    st.b       t0, a4, -15
+L(short_14_bytes):
+    ld.b       t0, a1, -14
+    st.b       t0, a4, -14
+L(short_13_bytes):
+    ld.b       t0, a1, -13
+    st.b       t0, a4, -13
+L(short_12_bytes):
+    ld.b       t0, a1, -12
+    st.b       t0, a4, -12
+L(short_11_bytes):
+    ld.b       t0, a1, -11
+    st.b       t0, a4, -11
+L(short_10_bytes):
+    ld.b       t0, a1, -10
+    st.b       t0, a4, -10
+L(short_9_bytes):
+    ld.b       t0, a1, -9
+    st.b       t0, a4, -9
+L(short_8_bytes):
+    ld.b       t0, a1, -8
+    st.b       t0, a4, -8
+L(short_7_bytes):
+    ld.b       t0, a1, -7
+    st.b       t0, a4, -7
+L(short_6_bytes):
+    ld.b       t0, a1, -6
+    st.b       t0, a4, -6
+L(short_5_bytes):
+    ld.b       t0, a1, -5
+    st.b       t0, a4, -5
+L(short_4_bytes):
+    ld.b       t0, a1, -4
+    st.b       t0, a4, -4
+L(short_3_bytes):
+    ld.b       t0, a1, -3
+    st.b       t0, a4, -3
+L(short_2_bytes):
+    ld.b       t0, a1, -2
+    st.b       t0, a4, -2
+L(short_1_bytes):
+    ld.b       t0, a1, -1
+    st.b       t0, a4, -1
+    jr         ra
+
+L(copy_back):
+    srai.d      a3, a2, 4
+    beqz        a3, L(back_short_data)  # less than 16 bytes
+
+    add.d       a4, a0, a2  # store the tail of dest
+    add.d       a1, a1, a2  # store the tail of src
+
+    andi        a5, a4, 0x7
+    andi        a6, a1, 0x7
+    beqz        a5, L(back_check_align)
+
+    # make dest aligned 8 bytes
+    sub.d       a2, a2, a5
+    sub.d       a1, a1, a5
+    sub.d       a4, a4, a5
+
+    pcaddi      t1, 18
+    slli.d      t3, a5, 3
+    sub.d       t1, t1, t3
+    jr          t1
+
+    ld.b        t0, a1, 6
+    st.b        t0, a4, 6
+    ld.b        t0, a1, 5
+    st.b        t0, a4, 5
+    ld.b        t0, a1, 4
+    st.b        t0, a4, 4
+    ld.b        t0, a1, 3
+    st.b        t0, a4, 3
+    ld.b        t0, a1, 2
+    st.b        t0, a4, 2
+    ld.b        t0, a1, 1
+    st.b        t0, a4, 1
+    ld.b        t0, a1, 0
+    st.b        t0, a4, 0
+
+L(back_check_align):
+    bne         a5, a6, L(back_unalign)
+
+    srai.d      a3, a2, 4
+    beqz        a3, L(back_less_16bytes)
+
+    andi        a3, a2, 0x3f
+    beq         a3, a2, L(back_less_64bytes)
+
+    sub.d       t0, a2, a3
+    move        a2, a3
+    sub.d       a5, a1, t0
+
+L(back_loop_64bytes):
+    LD_64(a1, -64)
+    addi.d      a1, a1, -64
+    ST_64(a4, -64)
+
+    addi.d      a4, a4, -64
+    bne         a1, a5, L(back_loop_64bytes)
+
+L(back_less_64bytes):
+    srai.d     a3, a2, 5
+    beqz       a3, L(back_less_32bytes)
+
+    ld.d       t0, a1, -32
+    ld.d       t1, a1, -24
+    ld.d       t2, a1, -16
+    ld.d       t3, a1, -8
+
+    addi.d     a1, a1, -32
+    addi.d     a2, a2, -32
+
+    st.d       t0, a4, -32
+    st.d       t1, a4, -24
+    st.d       t2, a4, -16
+    st.d       t3, a4, -8
+
+    addi.d     a4, a4, -32
+
+L(back_less_32bytes):
+    srai.d     a3, a2, 4
+    beqz       a3, L(back_less_16bytes)
+
+    ld.d       t0, a1, -16
+    ld.d       t1, a1, -8
+
+    addi.d     a2, a2, -16
+    addi.d     a1, a1, -16
+
+    st.d       t0, a4, -16
+    st.d       t1, a4, -8
+    addi.d     a4, a4, -16
+
+L(back_less_16bytes):
+    srai.d      a3, a2, 3
+    beqz        a3, L(back_less_8bytes)
+
+    ld.d        t0, a1, -8
+    addi.d      a2, a2, -8
+    addi.d      a1, a1, -8
+
+    st.d        t0, a4, -8
+    addi.d      a4, a4, -8
+
+L(back_less_8bytes):
+    srai.d      a3, a2, 2
+    beqz        a3, L(back_less_4bytes)
+
+    ld.w        t0, a1, -4
+    addi.d      a2, a2, -4
+    addi.d      a1, a1, -4
+
+    st.w        t0, a4, -4
+    addi.d      a4, a4, -4
+
+L(back_less_4bytes):
+    srai.d      a3, a2, 1
+    beqz        a3, L(back_less_2bytes)
+
+    ld.h        t0, a1, -2
+    addi.d      a2, a2, -2
+    addi.d      a1, a1, -2
+
+    st.h        t0, a4, -2
+    addi.d      a4, a4, -2
+
+L(back_less_2bytes):
+    beqz        a2, L(back_less_1byte)
+
+    ld.b        t0, a1, -1
+    st.b        t0, a4, -1
+
+L(back_less_1byte):
+    jr          ra
+
+L(back_unalign):
+    andi        t8, a1, 0x7
+    bstrins.d   a1, zero, 2, 0   # make src 8 bytes aligned
+
+    sub.d       a6, zero, t8
+
+    ld.d        t0, a1, 0
+    slli.d      a6, a6, 3
+    slli.d      a5, t8, 3
+    sll.d       a7, t0, a6
+
+    srai.d      a3, a2, 4
+    beqz        a3, L(back_un_less_16bytes)
+
+    andi        a3, a2, 0x3f
+    beq         a3, a2, L(back_un_less_64bytes)
+
+    sub.d       t0, a2, a3
+    move        a2, a3
+    sub.d       a3, a1, t0
+
+L(back_un_long_bytes):
+    ld.d        t0, a1, -8
+    ld.d        t1, a1, -16
+    ld.d        t2, a1, -24
+    ld.d        t3, a1, -32
+
+    sll.d       t4, t0, a6
+    srl.d       t0, t0, a5
+
+    sll.d       t5, t1, a6
+    srl.d       t1, t1, a5
+
+    sll.d       t6, t2, a6
+    srl.d       t2, t2, a5
+
+    sll.d       t7, t3, a6
+    srl.d       t3, t3, a5
+
+    or          t0, t0, a7
+    or          t1, t1, t4
+    or          t2, t2, t5
+    or          t3, t3, t6
+
+    ld.d        t4, a1, -40
+    ld.d        t5, a1, -48
+    ld.d        t6, a1, -56
+    ld.d        a7, a1, -64
+    st.d        t0, a4, -8
+    st.d        t1, a4, -16
+    st.d        t2, a4, -24
+    st.d        t3, a4, -32
+
+    addi.d      a1, a1, -64
+
+    sll.d       t0, t4, a6
+    srl.d       t4, t4, a5
+
+    sll.d       t1, t5, a6
+    srl.d       t5, t5, a5
+
+    sll.d       t2, t6, a6
+    srl.d       t6, t6, a5
+
+    srl.d       t3, a7, a5
+    sll.d       a7, a7, a6
+
+    or          t4, t7, t4
+    or          t5, t0, t5
+    or          t6, t1, t6
+    or          t3, t2, t3
+
+    st.d        t4, a4, -40
+    st.d        t5, a4, -48
+    st.d        t6, a4, -56
+    st.d        t3, a4, -64
+
+    addi.d      a4, a4, -64
+    bne         a3, a1, L(back_un_long_bytes)
+
+L(back_un_less_64bytes):
+    srai.d	a3, a2, 5
+    beqz	a3, L(back_un_less_32bytes)
+
+    ld.d        t0, a1, -8
+    ld.d        t1, a1, -16
+    ld.d        t2, a1, -24
+    ld.d        t3, a1, -32
+
+    addi.d      a1, a1, -32
+    addi.d      a2, a2, -32
+
+    sll.d       t4, t0, a6
+    srl.d       t0, t0, a5
+
+    sll.d       t5, t1, a6
+    srl.d       t1, t1, a5
+
+    sll.d       t6, t2, a6
+    srl.d       t2, t2, a5
+
+    or          t0, a7, t0
+
+    sll.d       a7, t3, a6
+    srl.d       t3, t3, a5
+
+    or          t1, t4, t1
+    or          t2, t5, t2
+    or          t3, t6, t3
+
+    st.d        t0, a4, -8
+    st.d        t1, a4, -16
+    st.d        t2, a4, -24
+    st.d        t3, a4, -32
+
+    addi.d      a4, a4, -32
+
+L(back_un_less_32bytes):
+    srai.d      a3, a2, 4
+    beqz        a3, L(back_un_less_16bytes)
+
+    ld.d        t0, a1, -8
+    ld.d        t1, a1, -16
+
+    addi.d      a1, a1, -16
+    addi.d      a2, a2, -16
+
+    sll.d       t2, t0, a6
+    srl.d       t3, t0, a5
+
+    srl.d       t4, t1, a5
+    or          t3, a7, t3
+    or          t4, t2, t4
+    sll.d       a7, t1, a6
+
+    st.d        t3, a4, -8
+    st.d        t4, a4, -16
+
+    addi.d      a4, a4, -16
+
+L(back_un_less_16bytes):
+    srai.d      a3, a2, 3
+    beqz        a3, L(back_un_less_8bytes)
+
+    ld.d        t0, a1, -8
+
+    addi.d      a1, a1, -8
+    addi.d      a2, a2, -8
+
+    srl.d       t1, t0, a5
+    or          t2, a7, t1
+    sll.d       a7, t0, a6
+
+    st.d        t2, a4, -8
+    addi.d      a4, a4, -8
+
+L(back_un_less_8bytes):
+    beqz        a2, L(back_end)
+    bge         t8, a2, 1f # no more data in memory, un_less_8bytes data is stored in a7
+
+    # combine data in memory and a7(remaining part)
+    ld.d        t0, a1, -8
+    srl.d       t0, t0, a5
+    or          a7, a7, t0
+
+1:
+    srai.d      a3, a2, 2
+    beqz        a3, L(back_un_less_4bytes)
+
+    srai.d      t0, a7, 32
+    addi.d      a2, a2, -4
+    st.w        t0, a4, -4
+    addi.d      a4, a4, -4
+    slli.d      a7, a7, 32
+
+L(back_un_less_4bytes):
+    srai.d      a3, a2, 1
+    beqz        a3, L(back_un_less_2bytes)
+    srai.d      t0, a7, 48
+    addi.d      a2, a2, -2
+    st.h        t0, a4, -2
+    addi.d      a4, a4, -2
+    slli.d      a7, a7, 16
+L(back_un_less_2bytes):
+    beqz        a2, L(back_un_less_1byte)
+    srai.d      t0, a7, 56
+    st.b        t0, a4, -1
+L(back_un_less_1byte):
+    jr          ra
+
+L(back_short_data):
+    pcaddi     t1, 34
+    slli.d     t2, a2, 3
+    sub.d      t1, t1, t2
+    jr         t1
+
+    ld.b       t0, a1, 14
+    st.b       t0, a0, 14
+    ld.b       t0, a1, 13
+    st.b       t0, a0, 13
+    ld.b       t0, a1, 12
+    st.b       t0, a0, 12
+    ld.b       t0, a1, 11
+    st.b       t0, a0, 11
+    ld.b       t0, a1, 10
+    st.b       t0, a0, 10
+    ld.b       t0, a1, 9
+    st.b       t0, a0, 9
+    ld.b       t0, a1, 8
+    st.b       t0, a0, 8
+    ld.b       t0, a1, 7
+    st.b       t0, a0, 7
+    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
+L(back_end):
+    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..6d1922c4
--- /dev/null
+++ b/sysdeps/loongarch/lp64/memmove.S
@@ -0,0 +1,2 @@
+/* DONT DELETE THIS FILE, OTHERWIES MEMCPY.C WILL BE COMPILED. */
+/* There are too many common code in memcpy and memmove. See memcpy.S */
diff --git a/sysdeps/loongarch/lp64/memset.S b/sysdeps/loongarch/lp64/memset.S
new file mode 100644
index 00000000..9fe42b24
--- /dev/null
+++ b/sysdeps/loongarch/lp64/memset.S
@@ -0,0 +1,173 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <sys/asm.h>
+#include <sys/regdef.h>
+#endif
+
+#ifndef MEMSET_NAME
+#define MEMSET_NAME memset
+#endif
+
+#define ST_64(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;
+
+#ifdef ANDROID_CHANGES
+LEAF(MEMSET_NAME, 0)
+#else
+LEAF(MEMSET_NAME)
+#endif
+    .align          6
+    move        t0, a0
+    andi        a3, a0, 0x7
+    li.w        t6, 16
+    beqz        a3, L(align)
+    blt         a2, t6, L(short_data)
+
+L(make_align):
+    li.w        t8, 8
+    sub.d       t2, t8, a3
+    pcaddi      t1, 11
+    slli.d      t3, t2, 2
+    sub.d       t1, t1, t3
+    jirl        zero, t1, 0
+
+L(al7):
+    st.b        a1, t0, 6
+L(al6):
+    st.b        a1, t0, 5
+L(al5):
+    st.b        a1, t0, 4
+L(al4):
+    st.b        a1, t0, 3
+L(al3):
+    st.b        a1, t0, 2
+L(al2):
+    st.b        a1, t0, 1
+L(al1):
+    st.b        a1, t0, 0
+L(al0):
+    add.d       t0, t0, t2
+    sub.d       a2, a2, t2
+
+L(align):
+    bstrins.d   a1, a1, 15, 8
+    bstrins.d   a1, a1, 31, 16
+    bstrins.d   a1, a1, 63, 32
+
+    blt         a2, t6, L(less_16bytes)
+
+    andi        a4, a2, 0x3f
+    beq         a4, a2, L(less_64bytes)
+
+    sub.d       t1, a2, a4
+    move        a2, a4
+    add.d       a5, t0, t1
+
+L(loop_64bytes):
+    addi.d      t0, t0, 64
+    st.d        a1, t0, -64
+    st.d        a1, t0, -56
+    st.d        a1, t0, -48
+    st.d        a1, t0, -40
+    st.d        a1, t0, -32
+    st.d        a1, t0, -24
+    st.d        a1, t0, -16
+    st.d        a1, t0, -8
+    bne         t0, a5, L(loop_64bytes)
+
+L(less_64bytes):
+    srai.d      a4, a2, 5
+    beqz        a4, L(less_32bytes)
+    addi.d      a2, a2, -32
+    st.d        a1, t0, 0
+    st.d        a1, t0, 8
+    st.d        a1, t0, 16
+    st.d        a1, t0, 24
+    addi.d      t0, t0, 32
+L(less_32bytes):
+    blt         a2, t6, L(less_16bytes)
+    addi.d      a2, a2, -16
+    st.d        a1, t0, 0
+    st.d        a1, t0, 8
+    addi.d      t0, t0, 16
+L(less_16bytes):
+    srai.d      a4, a2, 3
+    beqz        a4, L(less_8bytes)
+    addi.d      a2, a2, -8
+    st.d        a1, t0, 0
+    addi.d      t0, t0, 8
+L(less_8bytes):
+    beqz        a2, L(less_1byte)
+    srai.d      a4, a2, 2
+    beqz        a4, L(less_4bytes)
+    addi.d      a2, a2, -4
+    st.w        a1, t0, 0
+    addi.d      t0, t0, 4
+L(less_4bytes):
+    srai.d      a3, a2, 1
+    beqz        a3, L(less_2bytes)
+    addi.d      a2, a2, -2
+    st.h        a1, t0, 0
+    addi.d      t0, t0, 2
+L(less_2bytes):
+    beqz        a2, L(less_1byte)
+    st.b        a1, t0, 0
+L(less_1byte):
+    jr          ra
+
+L(short_data):
+    pcaddi      t1, 19
+    slli.d      t3, a2, 2
+    sub.d       t1, t1, t3
+    jirl        zero, t1, 0
+L(short_15):
+    st.b        a1, a0, 14
+
+L(short_14):
+    st.b        a1, a0, 13
+L(short_13):
+    st.b        a1, a0, 12
+L(short_12):
+    st.b        a1, a0, 11
+L(short_11):
+    st.b        a1, a0, 10
+L(short_10):
+    st.b        a1, a0, 9
+L(short_9):
+    st.b        a1, a0, 8
+L(short_8):
+    st.b        a1, a0, 7
+L(short_7):
+    st.b        a1, a0, 6
+L(short_6):
+    st.b        a1, a0, 5
+L(short_5):
+    st.b        a1, a0, 4
+L(short_4):
+    st.b        a1, a0, 3
+L(short_3):
+    st.b        a1, a0, 2
+L(short_2):
+    st.b        a1, a0, 1
+L(short_1):
+    st.b        a1, a0, 0
+L(short_0):
+    jr          ra
+
+END(MEMSET_NAME)
+
+#ifndef ANDROID_CHANGES
+#ifdef _LIBC
+libc_hidden_builtin_def (MEMSET_NAME)
+#endif
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/Makefile b/sysdeps/loongarch/lp64/multiarch/Makefile
new file mode 100644
index 00000000..6bd48f0e
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/Makefile
@@ -0,0 +1,18 @@
+ifeq ($(subdir),string)
+sysdep_routines += memcpy-aligned memcpy-unaligned memcpy-lasx \
+		   memset-aligned memset-unaligned memset-lsx memset-lasx \
+		   memmove-unaligned memmove-lsx memmove-lasx \
+		   memchr-aligned memchr-lsx memchr-lasx \
+		   memrchr-generic memrchr-lsx memrchr-lasx \
+		   memcmp-aligned memcmp-lsx memcmp-lasx \
+		   rawmemchr-aligned rawmemchr-lsx rawmemchr-lasx \
+		   strchr-aligned strchr-unaligned strchr-lsx strchr-lasx \
+		   strrchr-aligned strrchr-lsx strrchr-lasx \
+		   strlen-aligned strlen-unaligned strlen-lsx strlen-lasx \
+		   strnlen-aligned strnlen-unaligned strnlen-lsx strnlen-lasx \
+		   strchrnul-aligned strchrnul-unaligned strchrnul-lsx strchrnul-lasx \
+		   strncmp-aligned strncmp-unaligned strncmp-lsx \
+		   strcpy-aligned strcpy-unaligned strcpy-lsx \
+		   stpcpy-aligned stpcpy-lsx \
+		   strcmp-aligned strcmp-unaligned strcmp-lsx
+endif
diff --git a/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c b/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
new file mode 100644
index 00000000..c2b6bbf7
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c
@@ -0,0 +1,142 @@
+/* Enumerate available IFUNC implementations of a function.  LoongArch64 version.
+   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 <assert.h>
+#include <string.h>
+#include <wchar.h>
+#include <ldsodefs.h>
+#include <ifunc-impl-list.h>
+#include <init-arch.h>
+#include <stdio.h>
+
+/* Maximum number of IFUNC implementations.  */
+#define MAX_IFUNC	4
+
+size_t
+__libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+			size_t max)
+{
+  assert (max >= MAX_IFUNC);
+
+  size_t i = 0;
+
+  IFUNC_IMPL (i, name, memcpy,
+	      IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_lasx)
+	      IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_lsx)
+	      IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_aligned)
+	      IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_unaligned)
+	      )
+
+  IFUNC_IMPL (i, name, memmove,
+	      IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_lasx)
+	      IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_lsx)
+	      IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_aligned)
+	      IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_unaligned)
+	      )
+
+  IFUNC_IMPL (i, name, memset,
+	      IFUNC_IMPL_ADD (array, i, memset, 1, __memset_lasx)
+	      IFUNC_IMPL_ADD (array, i, memset, 1, __memset_lsx)
+	      IFUNC_IMPL_ADD (array, i, memset, 1, __memset_aligned)
+	      IFUNC_IMPL_ADD (array, i, memset, 1, __memset_unaligned)
+	      )
+
+  IFUNC_IMPL (i, name, memchr,
+	      IFUNC_IMPL_ADD (array, i, memchr, 1, __memchr_lasx)
+	      IFUNC_IMPL_ADD (array, i, memchr, 1, __memchr_lsx)
+	      IFUNC_IMPL_ADD (array, i, memchr, 1, __memchr_aligned)
+	      )
+
+  IFUNC_IMPL (i, name, memrchr,
+	      IFUNC_IMPL_ADD (array, i, memrchr, 1, __memrchr_lasx)
+	      IFUNC_IMPL_ADD (array, i, memrchr, 1, __memrchr_lsx)
+	      IFUNC_IMPL_ADD (array, i, memrchr, 1, __memrchr_generic)
+	      )
+
+  IFUNC_IMPL (i, name, memcmp,
+	      IFUNC_IMPL_ADD (array, i, memcmp, 1, __memcmp_lasx)
+	      IFUNC_IMPL_ADD (array, i, memcmp, 1, __memcmp_lsx)
+	      IFUNC_IMPL_ADD (array, i, memcmp, 1, __memcmp_aligned)
+	      )
+
+  IFUNC_IMPL (i, name, rawmemchr,
+	      IFUNC_IMPL_ADD (array, i, rawmemchr, 1, __rawmemchr_lasx)
+	      IFUNC_IMPL_ADD (array, i, rawmemchr, 1, __rawmemchr_lsx)
+	      IFUNC_IMPL_ADD (array, i, rawmemchr, 1, __rawmemchr_aligned)
+	      )
+
+  IFUNC_IMPL (i, name, strchr,
+	      IFUNC_IMPL_ADD (array, i, strchr, 1, __strchr_lasx)
+	      IFUNC_IMPL_ADD (array, i, strchr, 1, __strchr_lsx)
+	      IFUNC_IMPL_ADD (array, i, strchr, 1, __strchr_aligned)
+	      IFUNC_IMPL_ADD (array, i, strchr, 1, __strchr_unaligned)
+	      )
+
+  IFUNC_IMPL (i, name, strrchr,
+	      IFUNC_IMPL_ADD (array, i, strrchr, 1, __strrchr_lasx)
+	      IFUNC_IMPL_ADD (array, i, strrchr, 1, __strrchr_lsx)
+	      IFUNC_IMPL_ADD (array, i, strrchr, 1, __strrchr_aligned)
+	      )
+
+  IFUNC_IMPL (i, name, strlen,
+	      IFUNC_IMPL_ADD (array, i, strlen, 1, __strlen_lasx)
+	      IFUNC_IMPL_ADD (array, i, strlen, 1, __strlen_lsx)
+	      IFUNC_IMPL_ADD (array, i, strlen, 1, __strlen_aligned)
+	      IFUNC_IMPL_ADD (array, i, strlen, 1, __strlen_unaligned)
+	      )
+
+  IFUNC_IMPL (i, name, strnlen,
+	      IFUNC_IMPL_ADD (array, i, strnlen, 1, __strnlen_lasx)
+	      IFUNC_IMPL_ADD (array, i, strnlen, 1, __strnlen_lsx)
+	      IFUNC_IMPL_ADD (array, i, strnlen, 1, __strnlen_aligned)
+	      IFUNC_IMPL_ADD (array, i, strnlen, 1, __strnlen_unaligned)
+	      )
+
+  IFUNC_IMPL (i, name, strchrnul,
+	      IFUNC_IMPL_ADD (array, i, strchrnul, 1, __strchrnul_lasx)
+	      IFUNC_IMPL_ADD (array, i, strchrnul, 1, __strchrnul_lsx)
+	      IFUNC_IMPL_ADD (array, i, strchrnul, 1, __strchrnul_aligned)
+	      IFUNC_IMPL_ADD (array, i, strchrnul, 1, __strchrnul_unaligned)
+	      )
+
+  IFUNC_IMPL (i, name, strncmp,
+	      IFUNC_IMPL_ADD (array, i, strncmp, 1, __strncmp_lsx)
+	      IFUNC_IMPL_ADD (array, i, strncmp, 1, __strncmp_aligned)
+	      IFUNC_IMPL_ADD (array, i, strncmp, 1, __strncmp_unaligned)
+	      )
+
+  IFUNC_IMPL (i, name, strcpy,
+	      IFUNC_IMPL_ADD (array, i, strcpy, 1, __strcpy_lsx)
+	      IFUNC_IMPL_ADD (array, i, strcpy, 1, __strcpy_aligned)
+	      IFUNC_IMPL_ADD (array, i, strcpy, 1, __strcpy_unaligned)
+	      )
+
+  IFUNC_IMPL (i, name, stpcpy,
+	      IFUNC_IMPL_ADD (array, i, stpcpy, 1, __stpcpy_lsx)
+	      IFUNC_IMPL_ADD (array, i, stpcpy, 1, __stpcpy_aligned)
+	      )
+
+  IFUNC_IMPL (i, name, strcmp,
+	      IFUNC_IMPL_ADD (array, i, strcmp, 1, __strcmp_lsx)
+	      IFUNC_IMPL_ADD (array, i, strcmp, 1, __strcmp_aligned)
+	      IFUNC_IMPL_ADD (array, i, strcmp, 1, __strcmp_unaligned)
+	      )
+
+  return i;
+}
+
diff --git a/sysdeps/loongarch/lp64/multiarch/ifunc-lasx.h b/sysdeps/loongarch/lp64/multiarch/ifunc-lasx.h
new file mode 100644
index 00000000..61c00978
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/ifunc-lasx.h
@@ -0,0 +1,40 @@
+/* Common definition for memcpy, and memset implementation.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2017-2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <init-arch.h>
+
+extern __typeof (REDIRECT_NAME) OPTIMIZE (lasx) attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (lsx) attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (aligned) attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (unaligned) attribute_hidden;
+
+static inline void *
+IFUNC_SELECTOR (void)
+{
+  INIT_ARCH();
+
+  if (SUPPORT_LASX)
+    return OPTIMIZE (lasx);
+  else if (SUPPORT_LSX)
+    return OPTIMIZE (lsx);
+  else if (SUPPORT_UAL)
+    return OPTIMIZE (unaligned);
+  else
+    return OPTIMIZE (aligned);
+}
diff --git a/sysdeps/loongarch/lp64/multiarch/ifunc-lsx.h b/sysdeps/loongarch/lp64/multiarch/ifunc-lsx.h
new file mode 100644
index 00000000..771312f6
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/ifunc-lsx.h
@@ -0,0 +1,37 @@
+/* Common definition for strchr implementation.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2017-2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <init-arch.h>
+
+extern __typeof (REDIRECT_NAME) OPTIMIZE (lsx) attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (aligned) attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (unaligned) attribute_hidden;
+
+static inline void *
+IFUNC_SELECTOR (void)
+{
+  INIT_ARCH();
+
+  if (SUPPORT_LSX)
+    return OPTIMIZE (lsx);
+  if (SUPPORT_UAL)
+    return OPTIMIZE (unaligned);
+  else
+    return OPTIMIZE (aligned);
+}
diff --git a/sysdeps/loongarch/lp64/multiarch/ifunc-memchr.h b/sysdeps/loongarch/lp64/multiarch/ifunc-memchr.h
new file mode 100644
index 00000000..5c01e1af
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/ifunc-memchr.h
@@ -0,0 +1,37 @@
+/* Common definition for memchr implementation.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2017-2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <init-arch.h>
+
+extern __typeof (REDIRECT_NAME) OPTIMIZE (lasx) attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (lsx) attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (aligned) attribute_hidden;
+
+static inline void *
+IFUNC_SELECTOR (void)
+{
+  INIT_ARCH();
+
+  if (SUPPORT_LASX)
+    return OPTIMIZE (lasx);
+  else if (SUPPORT_LSX)
+    return OPTIMIZE (lsx);
+  else
+    return OPTIMIZE (aligned);
+}
diff --git a/sysdeps/loongarch/lp64/multiarch/ifunc-memrchr.h b/sysdeps/loongarch/lp64/multiarch/ifunc-memrchr.h
new file mode 100644
index 00000000..d264944c
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/ifunc-memrchr.h
@@ -0,0 +1,37 @@
+/* Common definition for memrchr implementation.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2017-2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <init-arch.h>
+
+extern __typeof (REDIRECT_NAME) OPTIMIZE (lasx) attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (lsx) attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (generic) attribute_hidden;
+
+static inline void *
+IFUNC_SELECTOR (void)
+{
+  INIT_ARCH();
+
+  if (SUPPORT_LASX)
+    return OPTIMIZE (lasx);
+  else if (SUPPORT_LSX)
+    return OPTIMIZE (lsx);
+  else
+    return OPTIMIZE (generic);
+}
diff --git a/sysdeps/loongarch/lp64/multiarch/ifunc-stpcpy.h b/sysdeps/loongarch/lp64/multiarch/ifunc-stpcpy.h
new file mode 100644
index 00000000..9093f08c
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/ifunc-stpcpy.h
@@ -0,0 +1,34 @@
+/* Common definition for memchr implementation.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2017-2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <init-arch.h>
+
+extern __typeof (REDIRECT_NAME) OPTIMIZE (lsx) attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (aligned) attribute_hidden;
+
+static inline void *
+IFUNC_SELECTOR (void)
+{
+  INIT_ARCH();
+
+  if (SUPPORT_LSX)
+    return OPTIMIZE (lsx);
+  else
+    return OPTIMIZE (aligned);
+}
diff --git a/sysdeps/loongarch/lp64/multiarch/memchr-aligned.S b/sysdeps/loongarch/lp64/multiarch/memchr-aligned.S
new file mode 100644
index 00000000..4677c912
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/memchr-aligned.S
@@ -0,0 +1,7 @@
+
+#if IS_IN (libc)
+#define MEMCHR_NAME __memchr_aligned
+#endif
+
+#include "../memchr.S"
+
diff --git a/sysdeps/loongarch/lp64/multiarch/memchr-lasx.S b/sysdeps/loongarch/lp64/multiarch/memchr-lasx.S
new file mode 100644
index 00000000..e63e34ae
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/memchr-lasx.S
@@ -0,0 +1,108 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <sys/asm.h>
+#include <sys/regdef.h>
+#endif
+
+#if IS_IN (libc)
+
+#define MEMCHR	__memchr_lasx
+
+LEAF(MEMCHR)
+    .align          6
+    beqz            a2, L(ret0)
+    add.d           a3, a0, a2
+    andi            t0, a0, 0x3f
+    bstrins.d       a0, zero, 5, 0
+
+    xvld            $xr0, a0, 0
+    xvld            $xr1, a0, 32
+    li.d            t1, -1
+    li.d            t2, 64
+
+    xvreplgr2vr.b   $xr2, a1
+    sll.d           t3, t1, t0
+    sub.d           t2, t2, t0
+    xvseq.b         $xr0, $xr0, $xr2
+
+    xvseq.b         $xr1, $xr1, $xr2
+    xvmsknz.b       $xr0, $xr0
+    xvmsknz.b       $xr1, $xr1
+    xvpickve.w      $xr3, $xr0, 4
+
+
+    xvpickve.w      $xr4, $xr1, 4
+    vilvl.h         $vr0, $vr3, $vr0
+    vilvl.h         $vr1, $vr4, $vr1
+    vilvl.w         $vr0, $vr1, $vr0
+
+    movfr2gr.d      t0, $f0
+    and             t0, t0, t3
+    bgeu            t2, a2, L(end)
+    bnez            t0, L(found)
+
+    addi.d          a4, a3, -1
+    bstrins.d       a4, zero, 5, 0
+L(loop):
+    xvld            $xr0, a0, 64
+    xvld            $xr1, a0, 96
+
+    addi.d          a0, a0, 64
+    xvseq.b         $xr0, $xr0, $xr2
+    xvseq.b         $xr1, $xr1, $xr2
+    beq             a0, a4, L(out)
+
+
+    xvmax.bu        $xr3, $xr0, $xr1
+    xvseteqz.v      $fcc0, $xr3
+    bcnez           $fcc0, L(loop)
+    xvmsknz.b       $xr0, $xr0
+
+    xvmsknz.b       $xr1, $xr1
+    xvpickve.w      $xr3, $xr0, 4
+    xvpickve.w      $xr4, $xr1, 4
+    vilvl.h         $vr0, $vr3, $vr0
+
+    vilvl.h         $vr1, $vr4, $vr1
+    vilvl.w         $vr0, $vr1, $vr0
+    movfr2gr.d      t0, $f0
+L(found):
+    ctz.d           t1, t0
+
+    add.d           a0, a0, t1
+    jr              ra
+L(ret0):
+    move            a0, zero
+    jr              ra
+
+
+L(out):
+    xvmsknz.b       $xr0, $xr0
+    xvmsknz.b       $xr1, $xr1
+    xvpickve.w      $xr3, $xr0, 4
+    xvpickve.w      $xr4, $xr1, 4
+
+    vilvl.h         $vr0, $vr3, $vr0
+    vilvl.h         $vr1, $vr4, $vr1
+    vilvl.w         $vr0, $vr1, $vr0
+    movfr2gr.d      t0, $f0
+
+L(end):
+    sub.d           t2, zero, a3
+    srl.d           t1, t1, t2
+    and             t0, t0, t1
+    ctz.d           t1, t0
+
+    add.d           a0, a0, t1
+    maskeqz         a0, a0, t0
+    jr              ra
+END(MEMCHR)
+
+#ifdef _LIBC
+libc_hidden_builtin_def (MEMCHR)
+#endif
+
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/memchr-lsx.S b/sysdeps/loongarch/lp64/multiarch/memchr-lsx.S
new file mode 100644
index 00000000..441db534
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/memchr-lsx.S
@@ -0,0 +1,93 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <sys/asm.h>
+#include <sys/regdef.h>
+#endif
+
+#if IS_IN (libc)
+
+#define MEMCHR	__memchr_lsx
+
+LEAF(MEMCHR)
+    .align          6
+    beqz            a2, L(ret0)
+    add.d           a3, a0, a2
+    andi            t0, a0, 0x1f
+    bstrins.d       a0, zero, 4, 0
+
+    vld             $vr0, a0, 0
+    vld             $vr1, a0, 16
+    li.d            t1, -1
+    li.d            t2, 32
+
+    vreplgr2vr.b    $vr2, a1
+    sll.d           t3, t1, t0
+    sub.d           t2, t2, t0
+    vseq.b          $vr0, $vr0, $vr2
+
+    vseq.b          $vr1, $vr1, $vr2
+    vmsknz.b        $vr0, $vr0
+    vmsknz.b        $vr1, $vr1
+    vilvl.h         $vr0, $vr1, $vr0
+
+
+    movfr2gr.s      t0, $f0
+    and             t0, t0, t3
+    bgeu            t2, a2, L(end)
+    bnez            t0, L(found)
+
+    addi.d          a4, a3, -1
+    bstrins.d       a4, zero, 4, 0
+L(loop):
+    vld             $vr0, a0, 32
+    vld             $vr1, a0, 48
+
+    addi.d          a0, a0, 32
+    vseq.b          $vr0, $vr0, $vr2
+    vseq.b          $vr1, $vr1, $vr2
+    beq             a0, a4, L(out)
+
+    vmax.bu         $vr3, $vr0, $vr1
+    vseteqz.v       $fcc0, $vr3
+    bcnez           $fcc0, L(loop)
+    vmsknz.b        $vr0, $vr0
+
+
+    vmsknz.b        $vr1, $vr1
+    vilvl.h         $vr0, $vr1, $vr0
+    movfr2gr.s      t0, $f0
+L(found):
+    ctz.w           t0, t0
+
+    add.d           a0, a0, t0
+    jr              ra
+L(ret0):
+    move            a0, zero
+    jr              ra
+
+L(out):
+    vmsknz.b        $vr0, $vr0
+    vmsknz.b        $vr1, $vr1
+    vilvl.h         $vr0, $vr1, $vr0
+    movfr2gr.s      t0, $f0
+
+L(end):
+    sub.d           t2, zero, a3
+    srl.w           t1, t1, t2
+    and             t0, t0, t1
+    ctz.w           t1, t0
+
+
+    add.d           a0, a0, t1
+    maskeqz         a0, a0, t0
+    jr              ra
+END(MEMCHR)
+
+#ifdef _LIBC
+libc_hidden_builtin_def (MEMCHR)
+#endif
+
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/memchr.c b/sysdeps/loongarch/lp64/multiarch/memchr.c
new file mode 100644
index 00000000..18b0e2ef
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/memchr.c
@@ -0,0 +1,39 @@
+/* Multiple versions of memchr.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2017-2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+/* Define multiple versions only for the definition in libc.  */
+#if IS_IN (libc)
+# define memchr __redirect_memchr
+# include <string.h>
+# undef memchr
+
+# define SYMBOL_NAME memchr
+# include "ifunc-memchr.h"
+
+libc_ifunc_redirected (__redirect_memchr, __new_memchr,
+		       IFUNC_SELECTOR ());
+
+# ifdef SHARED
+__hidden_ver1 (__new_memchr, __GI_memchr, __redirect_memchr)
+  __attribute__ ((visibility ("hidden")));
+# endif
+
+# include <shlib-compat.h>
+versioned_symbol (libc, __new_memchr, memchr, GLIBC_2_27);
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/memcmp-aligned.S b/sysdeps/loongarch/lp64/multiarch/memcmp-aligned.S
new file mode 100644
index 00000000..512eabca
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/memcmp-aligned.S
@@ -0,0 +1,11 @@
+
+#if IS_IN (libc)
+
+#define MEMCMP_NAME __memcmp_aligned
+
+#endif
+
+#include "../memcmp.S"
+# undef bcmp
+weak_alias (MEMCMP_NAME, bcmp)
+
diff --git a/sysdeps/loongarch/lp64/multiarch/memcmp-lasx.S b/sysdeps/loongarch/lp64/multiarch/memcmp-lasx.S
new file mode 100644
index 00000000..30e2dbe6
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/memcmp-lasx.S
@@ -0,0 +1,199 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <sys/asm.h>
+#include <sys/regdef.h>
+#endif
+
+#if IS_IN (libc)
+
+#define MEMCMP  __memcmp_lasx
+
+LEAF(MEMCMP)
+    .align          6
+    li.d            t2, 32
+    add.d           a3, a0, a2
+    add.d           a4, a1, a2
+    bgeu            t2, a2, L(less32) # a2 <= 32
+
+    li.d            t1, 160
+    bgeu            a2, t1, L(make_aligned)  # a2 >= 160
+L(loop32):
+    xvld            $xr0, a0, 0
+    xvld            $xr1, a1, 0
+
+    addi.d          a0, a0, 32
+    addi.d          a1, a1, 32
+    addi.d          a2, a2, -32
+    xvseq.b         $xr2, $xr0, $xr1
+
+    xvsetanyeqz.b   $fcc0, $xr2
+    bcnez           $fcc0, L(end)
+L(last_bytes):
+    bltu            t2, a2, L(loop32)
+    xvld            $xr0, a3, -32
+
+
+    xvld            $xr1, a4, -32
+    xvseq.b         $xr2, $xr0, $xr1
+L(end):
+    xvmsknz.b       $xr2, $xr2
+    xvpermi.q       $xr4, $xr0, 1
+
+    xvpickve.w      $xr3, $xr2, 4
+    xvpermi.q       $xr5, $xr1, 1
+    vilvl.h         $vr2, $vr3, $vr2
+    movfr2gr.s      t0, $f2
+
+    cto.w           t0, t0
+    vreplgr2vr.b    $vr2, t0
+    vshuf.b         $vr0, $vr4, $vr0, $vr2
+    vshuf.b         $vr1, $vr5, $vr1, $vr2
+
+    vpickve2gr.bu   t0, $vr0, 0
+    vpickve2gr.bu   t1, $vr1, 0
+    sub.d           a0, t0, t1
+    jr              ra
+
+
+L(less32):
+    srli.d          t0, a2, 4
+    beqz            t0, L(less16)
+    vld             $vr0, a0, 0
+    vld             $vr1, a1, 0
+
+    vld             $vr2, a3, -16
+    vld             $vr3, a4, -16
+L(short_ret):
+    vseq.b          $vr4, $vr0, $vr1
+    vseq.b          $vr5, $vr2, $vr3
+
+    vmsknz.b        $vr4, $vr4
+    vmsknz.b        $vr5, $vr5
+    vilvl.h         $vr4, $vr5, $vr4
+    movfr2gr.s      t0, $f4
+
+    cto.w           t0, t0
+    vreplgr2vr.b    $vr4, t0
+    vshuf.b         $vr0, $vr2, $vr0, $vr4
+    vshuf.b         $vr1, $vr3, $vr1, $vr4
+
+
+    vpickve2gr.bu   t0, $vr0, 0
+    vpickve2gr.bu   t1, $vr1, 0
+    sub.d           a0, t0, t1
+    jr              ra
+
+L(less16):
+    srli.d          t0, a2, 3
+    beqz            t0, L(less8)
+    vldrepl.d       $vr0, a0, 0
+    vldrepl.d       $vr1, a1, 0
+
+    vldrepl.d       $vr2, a3, -8
+    vldrepl.d       $vr3, a4, -8
+    b               L(short_ret)
+L(less8):
+    srli.d          t0, a2, 2
+
+    beqz            t0, L(less4)
+    vldrepl.w       $vr0, a0, 0
+    vldrepl.w       $vr1, a1, 0
+    vldrepl.w       $vr2, a3, -4
+
+
+    vldrepl.w       $vr3, a4, -4
+    b               L(short_ret)
+L(less4):
+    srli.d          t0, a2, 1
+    beqz            t0, L(less2)
+
+    vldrepl.h       $vr0, a0, 0
+    vldrepl.h       $vr1, a1, 0
+    vldrepl.h       $vr2, a3, -2
+    vldrepl.h       $vr3, a4, -2
+
+    b               L(short_ret)
+L(less2):
+    beqz            a2, L(ret0)
+    ld.bu           t0, a0, 0
+    ld.bu           t1, a1, 0
+
+    sub.d           a0, t0, t1
+    jr              ra
+L(ret0):
+    move            a0, zero
+    jr              ra
+
+
+    nop
+    nop
+    nop
+/* make src1 aligned, and adjust scr2 and length. */
+L(make_aligned):
+    xvld            $xr0, a0, 0
+
+    xvld            $xr1, a1, 0
+    xvseq.b         $xr2, $xr0, $xr1
+    xvsetanyeqz.b   $fcc0, $xr2
+    bcnez           $fcc0, L(end)
+
+    andi            t0, a0, 0x1f
+    sub.d           t0, t2, t0
+    sub.d           t1, a2, t0
+    add.d           a0, a0, t0
+
+    add.d           a1, a1, t0
+    andi            a2, t1, 0x3f
+    sub.d           t0, t1, a2
+    add.d           a5, a0, t0
+
+
+L(loop_align):
+    xvld            $xr0, a0, 0
+    xvld            $xr1, a1, 0
+    xvld            $xr2, a0, 32
+    xvld            $xr3, a1, 32
+
+    xvseq.b         $xr0, $xr0, $xr1
+    xvseq.b         $xr1, $xr2, $xr3
+    xvmin.bu        $xr2, $xr1, $xr0
+    xvsetanyeqz.b   $fcc0, $xr2
+
+    bcnez           $fcc0, L(pair_end)
+    addi.d          a0, a0, 64
+    addi.d          a1, a1, 64
+    bne             a0, a5, L(loop_align)
+
+    bnez            a2, L(last_bytes)
+    move            a0, zero
+    jr              ra
+    nop
+
+
+L(pair_end):
+    xvmsknz.b       $xr0, $xr0
+    xvmsknz.b       $xr1, $xr1
+    xvpickve.w      $xr2, $xr0, 4
+    xvpickve.w      $xr3, $xr1, 4
+
+    vilvl.h         $vr0, $vr2, $vr0
+    vilvl.h         $vr1, $vr3, $vr1
+    vilvl.w         $vr0, $vr1, $vr0
+    movfr2gr.d      t0, $f0
+
+    cto.d           t0, t0
+    ldx.bu          t1, a0, t0
+    ldx.bu          t2, a1, t0
+    sub.d           a0, t1, t2
+
+    jr              ra
+END(MEMCMP)
+
+#ifdef _LIBC
+libc_hidden_builtin_def (MEMCMP)
+#endif
+
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/memcmp-lsx.S b/sysdeps/loongarch/lp64/multiarch/memcmp-lsx.S
new file mode 100644
index 00000000..7fd349b6
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/memcmp-lsx.S
@@ -0,0 +1,255 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <sys/asm.h>
+#include <sys/regdef.h>
+#endif
+
+#if IS_IN (libc)
+
+#define MEMCMP  __memcmp_lsx
+
+L(magic_num):
+    .align          6
+    .dword          0x0706050403020100
+    .dword          0x0f0e0d0c0b0a0908
+    nop
+    nop
+ENTRY_NO_ALIGN(MEMCMP)
+    beqz            a2, L(out)
+    pcaddi          t0, -7
+
+    andi            a3, a0, 0xf
+    vld             $vr5, t0, 0
+    andi            a4, a1, 0xf
+    bne             a3, a4, L(unaligned)
+
+    bstrins.d       a0, zero, 3, 0
+    xor             a1, a1, a4
+    vld             $vr0, a0, 0
+    vld             $vr1, a1, 0
+
+
+    li.d            t0, 16
+    vreplgr2vr.b    $vr3, a3
+    sub.d           t1, t0, a3
+    vadd.b          $vr3, $vr3, $vr5
+
+    vshuf.b         $vr0, $vr3, $vr0, $vr3
+    vshuf.b         $vr1, $vr3, $vr1, $vr3
+    vseq.b          $vr4, $vr0, $vr1
+    bgeu            t1, a2, L(al_end)
+
+    vsetanyeqz.b    $fcc0, $vr4
+    bcnez           $fcc0, L(al_found)
+    sub.d           a2, a2, t1
+    andi            t1, a2, 31
+
+    beq             a2, t1, L(al_less_32bytes)
+    sub.d           t2, a2, t1
+    move            a2, t1
+    add.d           a4, a0, t2
+
+
+L(al_loop):
+    vld             $vr0, a0, 16
+    vld             $vr1, a1, 16
+    vld             $vr2, a0, 32
+    vld             $vr3, a1, 32
+
+    addi.d          a0, a0, 32
+    addi.d          a1, a1, 32
+    vseq.b          $vr4, $vr0, $vr1
+    vseq.b          $vr6, $vr2, $vr3
+
+    vand.v          $vr6, $vr4, $vr6
+    vsetanyeqz.b    $fcc0, $vr6
+    bcnez           $fcc0, L(al_pair_end)
+    bne             a0, a4, L(al_loop)
+
+L(al_less_32bytes):
+    bgeu            t0, a2, L(al_less_16bytes)
+    vld             $vr0, a0, 16
+    vld             $vr1, a1, 16
+    vld             $vr2, a0, 32
+
+
+    vld             $vr3, a1, 32
+    addi.d          a2, a2, -16
+    vreplgr2vr.b    $vr6, a2
+    vslt.b          $vr5, $vr5, $vr6
+
+    vseq.b          $vr4, $vr0, $vr1
+    vseq.b          $vr6, $vr2, $vr3
+    vorn.v          $vr6, $vr6, $vr5
+L(al_pair_end):
+    vsetanyeqz.b    $fcc0, $vr4
+
+    bcnez           $fcc0, L(al_found)
+    vnori.b         $vr4, $vr6, 0
+    vfrstpi.b       $vr4, $vr4, 0
+    vshuf.b         $vr0, $vr2, $vr2, $vr4
+
+    vshuf.b         $vr1, $vr3, $vr3, $vr4
+    vpickve2gr.bu   t0, $vr0, 0
+    vpickve2gr.bu   t1, $vr1, 0
+    sub.d           a0, t0, t1
+
+
+    jr              ra
+L(al_less_16bytes):
+    beqz            a2, L(out)
+    vld             $vr0, a0, 16
+    vld             $vr1, a1, 16
+
+    vseq.b          $vr4, $vr0, $vr1
+L(al_end):
+    vreplgr2vr.b    $vr6, a2
+    vslt.b          $vr5, $vr5, $vr6
+    vorn.v          $vr4, $vr4, $vr5
+
+L(al_found):
+    vnori.b         $vr4, $vr4, 0
+    vfrstpi.b       $vr4, $vr4, 0
+    vshuf.b         $vr0, $vr0, $vr0, $vr4
+    vshuf.b         $vr1, $vr1, $vr1, $vr4
+
+    vpickve2gr.bu   t0, $vr0, 0
+    vpickve2gr.bu   t1, $vr1, 0
+    sub.d           a0, t0, t1
+    jr              ra
+
+
+L(unaligned):
+    xor             t2, a0, a1
+    sltu            a5, a3, a4
+    masknez         t2, t2, a5
+    xor             a0, a0, t2      # a0 point to string with smaller offset 2
+
+    xor             a1, a1, t2      # a1 point to string with larger 4
+    andi            a3, a0, 0xf     # a3 = 2
+    andi            a4, a1, 0xf     # a4 = 4
+    bstrins.d       a0, zero, 3, 0
+
+    xor             a1, a1, a4
+    vld             $vr4, a0, 0
+    vld             $vr1, a1, 0
+    li.d            t0, 16
+
+    vreplgr2vr.b    $vr2, a4
+    sub.d           a6, a4, a3  # a6 hold the diff
+    sub.d           t1, t0, a4
+    sub.d           t2, t0, a6
+
+
+    vadd.b          $vr2, $vr2, $vr5 # [4, 5, 6, ...]
+    vreplgr2vr.b    $vr6, t2
+    vadd.b          $vr6, $vr6, $vr5 # [14, 15, 16, ... ]
+    vshuf.b         $vr0, $vr4, $vr4, $vr6  # make data be in the same position
+
+    vshuf.b         $vr1, $vr2, $vr1, $vr2
+    vshuf.b         $vr0, $vr2, $vr0, $vr2
+    vseq.b          $vr7, $vr0, $vr1
+    bgeu            t1, a2, L(un_end)
+
+    vsetanyeqz.b    $fcc0, $vr7
+    bcnez           $fcc0, L(un_found)
+    sub.d           a2, a2, t1
+    andi            t1, a2, 31
+
+    beq             a2, t1, L(un_less_32bytes)
+    sub.d           t2, a2, t1
+    move            a2, t1
+    add.d           a4, a1, t2
+
+
+L(un_loop):
+    vld             $vr2, a0, 16
+    vld             $vr1, a1, 16
+    vld             $vr3, a1, 32
+    addi.d          a1, a1, 32
+
+    addi.d          a0, a0, 32
+    vshuf.b         $vr0, $vr2, $vr4, $vr6
+    vld             $vr4, a0, 0
+    vseq.b          $vr7, $vr0, $vr1
+
+    vshuf.b         $vr2, $vr4, $vr2, $vr6
+    vseq.b          $vr8, $vr2, $vr3
+    vand.v          $vr8, $vr7, $vr8
+    vsetanyeqz.b    $fcc0, $vr8
+
+    bcnez           $fcc0, L(un_pair_end)
+    bne             a1, a4, L(un_loop)
+L(un_less_32bytes):
+    bltu            a2, t0, L(un_less_16bytes)
+    vld             $vr2, a0, 16
+
+
+    vld             $vr1, a1, 16
+    addi.d          a0, a0, 16
+    addi.d          a1, a1, 16
+    addi.d          a2, a2, -16
+
+    vshuf.b         $vr0, $vr2, $vr4, $vr6
+    vor.v           $vr4, $vr2, $vr2
+    vseq.b          $vr7, $vr0, $vr1
+    vsetanyeqz.b    $fcc0, $vr7
+
+    bcnez           $fcc0, L(un_found)
+L(un_less_16bytes):
+    beqz            a2, L(out)
+    vld             $vr1, a1, 16
+    bgeu            a6, a2, 1f
+
+    vld             $vr2, a0, 16
+1:
+    vshuf.b         $vr0, $vr2, $vr4, $vr6
+    vseq.b          $vr7, $vr0, $vr1
+L(un_end):
+    vreplgr2vr.b    $vr3, a2
+
+
+    vslt.b          $vr3, $vr5, $vr3
+    vorn.v          $vr7, $vr7, $vr3
+L(un_found):
+    vnori.b         $vr7, $vr7, 0
+    vfrstpi.b       $vr7, $vr7, 0
+
+    vshuf.b         $vr0, $vr0, $vr0, $vr7
+    vshuf.b         $vr1, $vr1, $vr1, $vr7
+L(calc_result):
+    vpickve2gr.bu   t0, $vr0, 0
+    vpickve2gr.bu   t1, $vr1, 0
+
+    sub.d           t2, t0, t1
+    sub.d           t3, t1, t0
+    masknez         t0, t3, a5
+    maskeqz         t1, t2, a5
+
+    or              a0, t0, t1
+    jr              ra
+L(un_pair_end):
+    vsetanyeqz.b    $fcc0, $vr7
+    bcnez           $fcc0, L(un_found)
+
+
+    vnori.b         $vr7, $vr8, 0
+    vfrstpi.b       $vr7, $vr7, 0
+    vshuf.b         $vr0, $vr2, $vr2, $vr7
+    vshuf.b         $vr1, $vr3, $vr3, $vr7
+
+    b               L(calc_result)
+L(out):
+    move            a0, zero
+    jr              ra
+
+END(MEMCMP)
+
+#ifdef _LIBC
+libc_hidden_builtin_def (MEMCMP)
+#endif
+
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/memcmp.c b/sysdeps/loongarch/lp64/multiarch/memcmp.c
new file mode 100644
index 00000000..a956761e
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/memcmp.c
@@ -0,0 +1,41 @@
+/* Multiple versions of memcmp.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2017-2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+/* Define multiple versions only for the definition in libc.  */
+#if IS_IN (libc)
+# define memcmp __redirect_memcmp
+# include <string.h>
+# undef memcmp
+
+# define SYMBOL_NAME memcmp
+# include "ifunc-memchr.h"
+
+libc_ifunc_redirected (__redirect_memcmp, __new_memcmp,
+		       IFUNC_SELECTOR ());
+# undef bcmp
+weak_alias (__new_memcmp, bcmp)
+
+# ifdef SHARED
+__hidden_ver1 (__new_memcmp, __GI_memcmp, __redirect_memcmp)
+  __attribute__ ((visibility ("hidden")));
+# endif
+
+# include <shlib-compat.h>
+versioned_symbol (libc, __new_memcmp, memcmp, GLIBC_2_27);
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/memcpy-aligned.S b/sysdeps/loongarch/lp64/multiarch/memcpy-aligned.S
new file mode 100644
index 00000000..5ff8b4e6
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/memcpy-aligned.S
@@ -0,0 +1,11 @@
+
+
+#if IS_IN (libc)
+
+#define MEMCPY_NAME __memcpy_aligned
+#define MEMMOVE_NAME __memmove_aligned
+
+#endif
+
+#include "../memcpy.S"
+
diff --git a/sysdeps/loongarch/lp64/multiarch/memcpy-lasx.S b/sysdeps/loongarch/lp64/multiarch/memcpy-lasx.S
new file mode 100644
index 00000000..99d2cc71
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/memcpy-lasx.S
@@ -0,0 +1 @@
+/* memcpy is part of memmove.S */
diff --git a/sysdeps/loongarch/lp64/multiarch/memcpy-lsx.S b/sysdeps/loongarch/lp64/multiarch/memcpy-lsx.S
new file mode 100644
index 00000000..99d2cc71
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/memcpy-lsx.S
@@ -0,0 +1 @@
+/* memcpy is part of memmove.S */
diff --git a/sysdeps/loongarch/lp64/multiarch/memcpy-unaligned.S b/sysdeps/loongarch/lp64/multiarch/memcpy-unaligned.S
new file mode 100644
index 00000000..5e38df0d
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/memcpy-unaligned.S
@@ -0,0 +1,259 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <regdef.h>
+#include <sys/asm.h>
+#endif
+
+#if IS_IN (libc)
+
+#define MEMCPY_NAME __memcpy_unaligned
+
+#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;
+
+#ifdef ANDROID_CHANGES
+LEAF(MEMCPY_NAME, 0)
+#else
+LEAF(MEMCPY_NAME)
+#endif
+
+//1st var: dst ptr: void *a1 $r4 a0
+//2nd var: src ptr: void *a2 $r5 a1
+//3rd var: size_t len $r6 a2
+//t0~t9 registers as temp
+
+	add.d   a4, a1, a2
+	add.d   a3, a0, a2
+	li.w    a6, 16
+	bge     a6, a2, less_16bytes
+	li.w    a6, 128
+	blt     a6, a2, long_bytes
+	li.w    a6, 64
+	blt     a6, a2, more_64bytes
+	li.w    a6, 32
+	blt     a6, a2, more_32bytes
+
+	/* 17...32 */
+	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
+
+more_64bytes:
+	srli.d	t8, a0, 3
+	slli.d	t8, t8, 3
+	addi.d	t8, t8,  0x8
+	sub.d	a7, a0, t8
+	ld.d	t0, a1, 0
+	sub.d	a1, a1, a7
+	st.d	t0, a0, 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, t8, 0
+	st.d	t1, t8, 8
+	st.d	t2, t8, 16
+	st.d	t3, t8, 24
+
+	addi.d	t8,  t8,   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
+
+	jr	ra
+
+more_32bytes:
+	/* 33...64 */
+	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_16bytes:
+	srai.d  a6, a2, 3
+	beqz    a6, less_8bytes
+
+	/* 8...16 */
+	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
+
+	/* 4...7 */
+	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
+
+	/* 2...3 */
+	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
+
+long_bytes:
+	srli.d  t8, a0, 3
+	slli.d  t8, t8, 3
+	beq     a0, t8, start
+
+	ld.d    t0, a1, 0
+	addi.d  t8, t8, 0x8
+	st.d    t0, a0, 0
+	sub.d   a7, a0, t8
+	sub.d   a1, a1, a7
+
+start:
+	addi.d  a5, a3, -0x80
+	blt     a5, t8, align_end_proc
+
+loop_128:
+	LD_64(a1, 0)
+	ST_64(t8, 0)
+	LD_64(a1, 64)
+	addi.d  a1, a1,  0x80
+	ST_64(t8, 64)
+	addi.d  t8, t8,  0x80
+	bge     a5, t8, loop_128
+
+align_end_proc:
+	sub.d   a2, a3, t8
+
+	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, t8, 112
+end_112_120_unalign:
+	ld.d    t0, a1, 104
+	st.d    t0, t8, 104
+end_104_112_unalign:
+	ld.d    t0, a1, 96
+	st.d    t0, t8, 96
+end_96_104_unalign:
+	ld.d    t0, a1, 88
+	st.d    t0, t8, 88
+end_88_96_unalign:
+	ld.d    t0, a1, 80
+	st.d    t0, t8, 80
+end_80_88_unalign:
+	ld.d    t0, a1, 72
+	st.d    t0, t8, 72
+end_72_80_unalign:
+	ld.d    t0, a1, 64
+	st.d    t0, t8, 64
+end_64_72_unalign:
+	ld.d    t0, a1, 56
+	st.d    t0, t8, 56
+end_56_64_unalign:
+	ld.d    t0, a1, 48
+	st.d    t0, t8, 48
+end_48_56_unalign:
+	ld.d    t0, a1, 40
+	st.d    t0, t8, 40
+end_40_48_unalign:
+	ld.d    t0, a1, 32
+	st.d    t0, t8, 32
+end_32_40_unalign:
+	ld.d    t0, a1, 24
+	st.d    t0, t8, 24
+end_24_32_unalign:
+	ld.d    t0, a1, 16
+	st.d    t0, t8, 16
+end_16_24_unalign:
+	ld.d    t0, a1, 8
+	st.d    t0, t8, 8
+end_8_16_unalign:
+	ld.d    t0, a1, 0
+	st.d    t0, t8, 0
+end_0_8_unalign:
+	ld.d    t0, a4, -8
+	st.d    t0, a3, -8
+
+	jr  ra
+
+END(MEMCPY_NAME)
+
+#ifndef ANDROID_CHANGES
+#ifdef _LIBC
+libc_hidden_builtin_def (MEMCPY_NAME)
+#endif
+#endif
+
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/memcpy.c b/sysdeps/loongarch/lp64/multiarch/memcpy.c
new file mode 100644
index 00000000..0ba8254a
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/memcpy.c
@@ -0,0 +1,39 @@
+/* Multiple versions of memcpy.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2017-2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+/* Define multiple versions only for the definition in libc.  */
+#if IS_IN (libc)
+# define memcpy __redirect_memcpy
+# include <string.h>
+# undef memcpy
+
+# define SYMBOL_NAME memcpy
+# include "ifunc-lasx.h"
+
+libc_ifunc_redirected (__redirect_memcpy, __new_memcpy,
+		       IFUNC_SELECTOR ());
+
+# ifdef SHARED
+__hidden_ver1 (__new_memcpy, __GI_memcpy, __redirect_memcpy)
+  __attribute__ ((visibility ("hidden")));
+# endif
+
+# include <shlib-compat.h>
+versioned_symbol (libc, __new_memcpy, memcpy, GLIBC_2_27);
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/memmove-aligned.S b/sysdeps/loongarch/lp64/multiarch/memmove-aligned.S
new file mode 100644
index 00000000..bcd37a0e
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/memmove-aligned.S
@@ -0,0 +1 @@
+/* memmove_aligned is part of memcpy_aligned, see memcpy-aligned.S.  */
diff --git a/sysdeps/loongarch/lp64/multiarch/memmove-lasx.S b/sysdeps/loongarch/lp64/multiarch/memmove-lasx.S
new file mode 100644
index 00000000..9537a35a
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/memmove-lasx.S
@@ -0,0 +1,279 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <regdef.h>
+#include <sys/asm.h>
+#endif
+
+#if IS_IN (libc)
+
+#ifndef MEMCPY_NAME
+#define MEMCPY_NAME __memcpy_lasx
+#endif
+
+#ifndef MEMMOVE_NAME
+#define MEMMOVE_NAME __memmove_lasx
+#endif
+
+LEAF(MEMCPY_NAME)
+    .align          6
+
+    li.d            t0, 32
+    add.d           a3, a0, a2
+    add.d           a4, a1, a2
+    bgeu            t0, a2, L(less_32bytes) # a2 <= 32
+
+    li.d            t1, 64
+    bltu            t1, a2, L(copy_long)    # a2 > 64
+    xvld            $xr0, a1, 0
+    xvld            $xr1, a4, -32
+
+    xvst            $xr0, a0, 0
+    xvst            $xr1, a3, -32
+    jr              ra
+L(less_32bytes):
+    srli.d          t0, a2, 4
+
+    beqz            t0, L(less_16bytes)
+    vld             $vr0, a1, 0
+    vld             $vr1, a4, -16
+    vst             $vr0, a0, 0
+
+
+    vst             $vr1, a3, -16
+    jr              ra
+L(less_16bytes):
+    srli.d          t0, a2, 3
+    beqz            t0, L(less_8bytes)
+
+    ld.d            t0, a1, 0
+    ld.d            t1, a4, -8
+    st.d            t0, a0, 0
+    st.d            t1, a3, -8
+
+    jr              ra
+L(less_8bytes):
+    srli.d          t0, a2, 2
+    beqz            t0, L(less_4bytes)
+    ld.w            t0, a1, 0
+
+    ld.w            t1, a4, -4
+    st.w            t0, a0, 0
+    st.w            t1, a3, -4
+    jr              ra
+
+
+L(less_4bytes):
+    srli.d          t0, a2, 1
+    beqz            t0, L(less_2bytes)
+    ld.h            t0, a1, 0
+    ld.h            t1, a4, -2
+
+    st.h            t0, a0, 0
+    st.h            t1, a3, -2
+    jr              ra
+L(less_2bytes):
+    beqz            a2, L(less_1bytes)
+
+    ld.b            t0, a1, 0
+    st.b            t0, a0, 0
+L(less_1bytes):
+    jr              ra
+END(MEMCPY_NAME)
+
+LEAF(MEMMOVE_NAME)
+    .align          6
+
+    li.d            t0, 32
+    add.d           a3, a0, a2
+    add.d           a4, a1, a2
+    bgeu            t0, a2, L(less_32bytes) # a2 <= 32
+
+    li.d            t1, 64
+    bltu            t1, a2, L(move_long)    # a2 > 64
+    xvld            $xr0, a1, 0
+    xvld            $xr1, a4, -32
+
+    xvst            $xr0, a0, 0
+    xvst            $xr1, a3, -32
+    jr              ra
+L(move_long):
+    sub.d           t2, a0, a1
+
+    bltu            t2, a2, L(copy_back)
+L(copy_long):
+    andi            t2, a0, 0x1f
+    addi.d          a2, a2, -1
+    sub.d           t2, t0, t2
+
+
+    xvld            $xr8, a1, 0
+    xvld            $xr9, a4, -32
+    sub.d           t3, a2, t2
+    add.d           a5, a0, t2
+
+    andi            a2, t3, 0xff
+    add.d           a1, a1, t2
+    beq             a2, t3, L(lt256)
+    sub.d           a6, a4, a2
+
+    addi.d          a6, a6, -1
+L(loop_256):
+    xvld            $xr0, a1, 0
+    xvld            $xr1, a1, 32
+    xvld            $xr2, a1, 64
+
+    xvld            $xr3, a1, 96
+    xvld            $xr4, a1, 128
+    xvld            $xr5, a1, 160
+    xvld            $xr6, a1, 192
+
+
+    xvld            $xr7, a1, 224
+    addi.d          a1, a1, 256
+    xvst            $xr0, a5, 0
+    xvst            $xr1, a5, 32
+
+    xvst            $xr2, a5, 64
+    xvst            $xr3, a5, 96
+    xvst            $xr4, a5, 128
+    xvst            $xr5, a5, 160
+
+    xvst            $xr6, a5, 192
+    xvst            $xr7, a5, 224
+    addi.d          a5, a5, 256
+    bne             a1, a6, L(loop_256)
+
+L(lt256):
+    srli.d          t2, a2, 7
+    beqz            t2, L(lt128)
+    xvld            $xr0, a1, 0
+    xvld            $xr1, a1, 32
+
+
+    xvld            $xr2, a1, 64
+    xvld            $xr3, a1, 96
+    addi.d          a1, a1, 128
+    addi.d          a2, a2, -128
+
+    xvst            $xr0, a5, 0
+    xvst            $xr1, a5, 32
+    xvst            $xr2, a5, 64
+    xvst            $xr3, a5, 96
+
+    addi.d          a5, a5, 128
+L(lt128):
+    bltu            a2, t1, L(lt64)
+    xvld            $xr0, a1, 0
+    xvld            $xr1, a1, 32
+
+    addi.d          a1, a1, 64
+    addi.d          a2, a2, -64
+    xvst            $xr0, a5, 0
+    xvst            $xr1, a5, 32
+
+
+    addi.d          a5, a5, 64
+L(lt64):
+    bltu            a2, t0, L(lt32)
+    xvld            $xr0, a1, 0
+    xvst            $xr0, a5, 0
+
+L(lt32):
+    xvst            $xr8, a0, 0
+    xvst            $xr9, a3, -32
+    jr              ra
+    nop
+
+L(copy_back):
+    addi.d          a3, a3, -1
+    addi.d          a2, a2, -2
+    andi            t2, a3, 0x1f
+    xvld            $xr8, a1, 0
+
+    xvld            $xr9, a4, -32
+    sub.d           t3, a2, t2
+    sub.d           a5, a3, t2
+    sub.d           a4, a4, t2
+
+
+    andi            a2, t3, 0xff
+    beq             a2, t3, L(back_lt256)
+    add.d           a6, a1, a2
+    addi.d          a6, a6, 2
+
+L(back_loop_256):
+    xvld            $xr0, a4, -33
+    xvld            $xr1, a4, -65
+    xvld            $xr2, a4, -97
+    xvld            $xr3, a4, -129
+
+    xvld            $xr4, a4, -161
+    xvld            $xr5, a4, -193
+    xvld            $xr6, a4, -225
+    xvld            $xr7, a4, -257
+
+    addi.d          a4, a4, -256
+    xvst            $xr0, a5, -32
+    xvst            $xr1, a5, -64
+    xvst            $xr2, a5, -96
+
+
+    xvst            $xr3, a5, -128
+    xvst            $xr4, a5, -160
+    xvst            $xr5, a5, -192
+    xvst            $xr6, a5, -224
+
+    xvst            $xr7, a5, -256
+    addi.d          a5, a5, -256
+    bne             a4, a6, L(back_loop_256)
+L(back_lt256):
+    srli.d          t2, a2, 7
+
+    beqz            t2, L(back_lt128)
+    xvld            $xr0, a4, -33
+    xvld            $xr1, a4, -65
+    xvld            $xr2, a4, -97
+
+    xvld            $xr3, a4, -129
+    addi.d          a2, a2, -128
+    addi.d          a4, a4, -128
+    xvst            $xr0, a5, -32
+
+
+    xvst            $xr1, a5, -64
+    xvst            $xr2, a5, -96
+    xvst            $xr3, a5, -128
+    addi.d          a5, a5, -128
+
+L(back_lt128):
+    blt             a2, t1, L(back_lt64)
+    xvld            $xr0, a4, -33
+    xvld            $xr1, a4, -65
+    addi.d          a2, a2, -64
+
+    addi.d          a4, a4, -64
+    xvst            $xr0, a5, -32
+    xvst            $xr1, a5, -64
+    addi.d          a5, a5, -64
+
+L(back_lt64):
+    bltu            a2, t0, L(back_lt32)
+    xvld            $xr0, a4, -33
+    xvst            $xr0, a5, -32
+L(back_lt32):
+    xvst            $xr8, a0, 0
+
+
+    xvst            $xr9, a3, -31
+    jr              ra
+END(MEMMOVE_NAME)
+
+#ifdef _LIBC
+libc_hidden_builtin_def (MEMCPY_NAME)
+libc_hidden_builtin_def (MEMMOVE_NAME)
+#endif
+
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/memmove-lsx.S b/sysdeps/loongarch/lp64/multiarch/memmove-lsx.S
new file mode 100644
index 00000000..26babad4
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/memmove-lsx.S
@@ -0,0 +1,524 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <regdef.h>
+#include <sys/asm.h>
+#endif
+
+#if IS_IN (libc)
+
+#define MEMCPY_NAME __memcpy_lsx
+#define MEMMOVE_NAME __memmove_lsx
+
+LEAF(MEMCPY_NAME)
+    .align          6
+    li.d            t6, 16
+    add.d           a3, a0, a2
+    add.d           a4, a1, a2
+    bgeu            t6, a2, L(less_16bytes) # a2 <= 16
+
+    li.d            t8, 64
+    li.d            t7, 32
+    bltu            t8, a2, L(copy_long)   # a2 > 64
+    bltu            t7, a2, L(more_32bytes) # a2 > 32
+
+    vld             $vr0, a1, 0
+    vld             $vr1, a4, -16
+    vst             $vr0, a0, 0
+    vst             $vr1, a3, -16
+
+    jr              ra
+L(more_32bytes):
+    vld             $vr0, a1, 0
+    vld             $vr1, a1, 16
+    vld             $vr2, a4, -32
+
+
+    vld             $vr3, a4, -16
+    vst             $vr0, a0, 0
+    vst             $vr1, a0, 16
+    vst             $vr2, a3, -32
+
+    vst             $vr3, a3, -16
+    jr              ra
+L(less_16bytes):
+    srli.d          t0, a2, 3
+    beqz            t0, L(less_8bytes)
+
+    vldrepl.d       $vr0, a1, 0
+    vldrepl.d       $vr1, a4, -8
+    vstelm.d        $vr0, a0, 0, 0
+    vstelm.d        $vr1, a3, -8, 0
+
+    jr              ra
+L(less_8bytes):
+    srli.d          t0, a2, 2
+    beqz            t0, L(less_4bytes)
+    vldrepl.w       $vr0, a1, 0
+
+
+    vldrepl.w       $vr1, a4, -4
+    vstelm.w        $vr0, a0, 0, 0
+    vstelm.w        $vr1, a3, -4, 0
+    jr              ra
+
+L(less_4bytes):
+    srli.d          t0, a2, 1
+    beqz            t0, L(less_2bytes)
+    vldrepl.h       $vr0, a1, 0
+    vldrepl.h       $vr1, a4, -2
+
+    vstelm.h        $vr0, a0, 0, 0
+    vstelm.h        $vr1, a3, -2, 0
+    jr              ra
+L(less_2bytes):
+    beqz            a2, L(less_1bytes)
+
+    ld.b            t0, a1, 0
+    st.b            t0, a0, 0
+L(less_1bytes):
+    jr              ra
+    nop
+END(MEMCPY_NAME)
+
+LEAF(MEMMOVE_NAME)
+    li.d            t6, 16
+    add.d           a3, a0, a2
+    add.d           a4, a1, a2
+    bgeu            t6, a2, L(less_16bytes) # a2 <= 16
+
+    li.d            t8, 64
+    li.d            t7, 32
+    bltu            t8, a2, L(move_long)    # a2 > 64
+    bltu            t7, a2, L(more_32bytes) # a2 > 32
+
+    vld             $vr0, a1, 0
+    vld             $vr1, a4, -16
+    vst             $vr0, a0, 0
+    vst             $vr1, a3, -16
+
+    jr              ra
+    nop
+L(move_long):
+    sub.d           t0, a0, a1
+    bltu            t0, a2, L(copy_back)
+
+
+L(copy_long):
+    vld             $vr2, a1, 0
+    andi            t0, a0, 0xf
+    sub.d           t0, t6, t0
+    add.d           a1, a1, t0
+
+    sub.d           a2, a2, t0
+    andi            t1, a1, 0xf
+    bnez            t1, L(unaligned)
+    vld             $vr0, a1, 0
+
+    addi.d          a2, a2, -16
+    vst             $vr2, a0, 0
+    andi            t2, a2, 0x7f
+    add.d           a5, a0, t0
+
+    beq             a2, t2, L(al_less_128)
+    sub.d           t3, a2, t2
+    move            a2, t2
+    add.d           a6, a1, t3
+
+
+L(al_loop):
+    vld             $vr1, a1, 16
+    vld             $vr2, a1, 32
+    vld             $vr3, a1, 48
+    vld             $vr4, a1, 64
+
+    vld             $vr5, a1, 80
+    vld             $vr6, a1, 96
+    vld             $vr7, a1, 112
+    vst             $vr0, a5, 0
+
+    vld             $vr0, a1, 128
+    addi.d          a1, a1, 128
+    vst             $vr1, a5, 16
+    vst             $vr2, a5, 32
+
+    vst             $vr3, a5, 48
+    vst             $vr4, a5, 64
+    vst             $vr5, a5, 80
+    vst             $vr6, a5, 96
+
+
+    vst             $vr7, a5, 112
+    addi.d          a5, a5, 128
+    bne             a1, a6, L(al_loop)
+L(al_less_128):
+    blt             a2, t8, L(al_less_64)
+
+    vld             $vr1, a1, 16
+    vld             $vr2, a1, 32
+    vld             $vr3, a1, 48
+    addi.d          a2, a2, -64
+
+    vst             $vr0, a5, 0
+    vld             $vr0, a1, 64
+    addi.d          a1, a1, 64
+    vst             $vr1, a5, 16
+
+    vst             $vr2, a5, 32
+    vst             $vr3, a5, 48
+    addi.d          a5, a5, 64
+L(al_less_64):
+    blt             a2, t7, L(al_less_32)
+
+
+    vld             $vr1, a1, 16
+    addi.d          a2, a2, -32
+    vst             $vr0, a5, 0
+    vld             $vr0, a1, 32
+
+    addi.d          a1, a1, 32
+    vst             $vr1, a5, 16
+    addi.d          a5, a5, 32
+L(al_less_32):
+    blt             a2, t6, L(al_less_16)
+
+    vst             $vr0, a5, 0
+    vld             $vr0, a1, 16
+    addi.d          a5, a5, 16
+L(al_less_16):
+    vld             $vr1, a4, -16
+
+    vst             $vr0, a5, 0
+    vst             $vr1, a3, -16
+    jr              ra
+    nop
+
+
+L(magic_num):
+    .dword          0x0706050403020100
+    .dword          0x0f0e0d0c0b0a0908
+L(unaligned):
+    pcaddi          t2, -4
+    bstrins.d       a1, zero, 3, 0
+    vld             $vr8, t2, 0
+    vld             $vr0, a1, 0
+
+    vld             $vr1, a1, 16
+    addi.d          a2, a2, -16
+    vst             $vr2, a0, 0
+    add.d           a5, a0, t0
+
+    vreplgr2vr.b    $vr9, t1
+    andi            t2, a2, 0x7f
+    vadd.b          $vr9, $vr9, $vr8
+    addi.d          a1, a1, 32
+
+
+    beq             t2, a2, L(un_less_128)
+    sub.d           t3, a2, t2
+    move            a2, t2
+    add.d           a6, a1, t3
+
+L(un_loop):
+    vld             $vr2, a1, 0
+    vld             $vr3, a1, 16
+    vld             $vr4, a1, 32
+    vld             $vr5, a1, 48
+
+    vld             $vr6, a1, 64
+    vld             $vr7, a1, 80
+    vshuf.b         $vr8, $vr1, $vr0, $vr9
+    vld             $vr0, a1, 96
+
+    vst             $vr8, a5, 0
+    vshuf.b         $vr8, $vr2, $vr1, $vr9
+    vld             $vr1, a1, 112
+    vst             $vr8, a5, 16
+
+
+    addi.d          a1, a1, 128
+    vshuf.b         $vr2, $vr3, $vr2, $vr9
+    vshuf.b         $vr3, $vr4, $vr3, $vr9
+    vst             $vr2, a5, 32
+
+    vshuf.b         $vr4, $vr5, $vr4, $vr9
+    vst             $vr3, a5, 48
+    vshuf.b         $vr5, $vr6, $vr5, $vr9
+    vst             $vr4, a5, 64
+
+    vshuf.b         $vr6, $vr7, $vr6, $vr9
+    vst             $vr5, a5, 80
+    vshuf.b         $vr7, $vr0, $vr7, $vr9
+    vst             $vr6, a5, 96
+
+    vst             $vr7, a5, 112
+    addi.d          a5, a5, 128
+    bne             a1, a6, L(un_loop)
+L(un_less_128):
+    blt             a2, t8, L(un_less_64)
+
+
+    vld             $vr2, a1, 0
+    vld             $vr3, a1, 16
+    vshuf.b         $vr4, $vr1, $vr0, $vr9
+    vld             $vr0, a1, 32
+
+    vst             $vr4, a5, 0
+    addi.d          a2, a2, -64
+    vshuf.b         $vr4, $vr2, $vr1, $vr9
+    vld             $vr1, a1, 48
+
+    addi.d          a1, a1, 64
+    vst             $vr4, a5, 16
+    vshuf.b         $vr2, $vr3, $vr2, $vr9
+    vshuf.b         $vr3, $vr0, $vr3, $vr9
+
+    vst             $vr2, a5, 32
+    vst             $vr3, a5, 48
+    addi.d          a5, a5, 64
+L(un_less_64):
+    blt             a2, t7, L(un_less_32)
+
+
+    vshuf.b         $vr3, $vr1, $vr0, $vr9
+    vld             $vr0, a1, 0
+    vst             $vr3, a5, 0
+    addi.d          a2, a2, -32
+
+    vshuf.b         $vr3, $vr0, $vr1, $vr9
+    vld             $vr1, a1, 16
+    addi.d          a1, a1, 32
+    vst             $vr3, a5, 16
+
+    addi.d          a5, a5, 32
+L(un_less_32):
+    blt             a2, t6, L(un_less_16)
+    vshuf.b         $vr2, $vr1, $vr0, $vr9
+    vor.v           $vr0, $vr1, $vr1
+
+    vld             $vr1, a1, 0
+    vst             $vr2, a5, 0
+    addi.d          a5, a5, 16
+L(un_less_16):
+    vld             $vr2, a4, -16
+
+
+    vshuf.b         $vr0, $vr1, $vr0, $vr9
+    vst             $vr0, a5, 0
+    vst             $vr2, a3, -16
+    jr              ra
+
+L(copy_back):
+    addi.d          t0, a3, -1
+    vld             $vr2, a4, -16
+    andi            t0, t0, 0xf
+    addi.d          t0, t0, 1   # in case a3 is already aligned, load 16bytes and store 16bytes
+
+    sub.d           a4, a4, t0
+    sub.d           a2, a2, t0
+    andi            t1, a4, 0xf
+    bnez            t1, L(back_unaligned)
+
+    vld             $vr0, a4, -16
+    addi.d          a2, a2, -16
+    vst             $vr2, a3, -16
+    andi            t2, a2, 0x7f
+
+
+    sub.d           a3, a3, t0
+    beq             t2, a2, L(back_al_less_128)
+    sub.d           t3, a2, t2
+    move            a2, t2
+
+    sub.d           a6, a4, t3
+L(back_al_loop):
+    vld             $vr1, a4, -32
+    vld             $vr2, a4, -48
+    vld             $vr3, a4, -64
+
+    vld             $vr4, a4, -80
+    vld             $vr5, a4, -96
+    vld             $vr6, a4, -112
+    vld             $vr7, a4, -128
+
+    vst             $vr0, a3, -16
+    vld             $vr0, a4, -144
+    addi.d          a4, a4, -128
+    vst             $vr1, a3, -32
+
+
+    vst             $vr2, a3, -48
+    vst             $vr3, a3, -64
+    vst             $vr4, a3, -80
+    vst             $vr5, a3, -96
+
+    vst             $vr6, a3, -112
+    vst             $vr7, a3, -128
+    addi.d          a3, a3, -128
+    bne             a4, a6, L(back_al_loop)
+
+L(back_al_less_128):
+    blt             a2, t8, L(back_al_less_64)
+    vld             $vr1, a4, -32
+    vld             $vr2, a4, -48
+    vld             $vr3, a4, -64
+
+    addi.d          a2, a2, -64
+    vst             $vr0, a3, -16
+    vld             $vr0, a4, -80
+    addi.d          a4, a4, -64
+
+
+    vst             $vr1, a3, -32
+    vst             $vr2, a3, -48
+    vst             $vr3, a3, -64
+    addi.d          a3, a3, -64
+
+L(back_al_less_64):
+    blt             a2, t7, L(back_al_less_32)
+    vld             $vr1, a4, -32
+    addi.d          a2, a2, -32
+    vst             $vr0, a3, -16
+
+    vld             $vr0, a4, -48
+    vst             $vr1, a3, -32
+    addi.d          a3, a3, -32
+    addi.d          a4, a4, -32
+
+L(back_al_less_32):
+    blt             a2, t6, L(back_al_less_16)
+    vst             $vr0, a3, -16
+    vld             $vr0, a4, -32
+    addi.d          a3, a3, -16
+
+
+L(back_al_less_16):
+    vld             $vr1, a1, 0
+    vst             $vr0, a3, -16
+    vst             $vr1, a0, 0
+    jr              ra
+
+L(magic_num_2):
+    .dword          0x0706050403020100
+    .dword          0x0f0e0d0c0b0a0908
+L(back_unaligned):
+    pcaddi          t2, -4
+    bstrins.d       a4, zero, 3, 0
+    vld             $vr8, t2, 0
+    vld             $vr0, a4, 0
+
+    vld             $vr1, a4, -16
+    addi.d          a2, a2, -16
+    vst             $vr2, a3, -16
+    sub.d           a3, a3, t0
+
+
+    vreplgr2vr.b    $vr9, t1
+    andi            t2, a2, 0x7f
+    vadd.b          $vr9, $vr9, $vr8
+    addi.d          a4, a4, -16
+
+    beq             t2, a2, L(back_un_less_128)
+    sub.d           t3, a2, t2
+    move            a2, t2
+    sub.d           a6, a4, t3
+
+L(back_un_loop):
+    vld             $vr2, a4, -16
+    vld             $vr3, a4, -32
+    vld             $vr4, a4, -48
+
+    vld             $vr5, a4, -64
+    vld             $vr6, a4, -80
+    vld             $vr7, a4, -96
+    vshuf.b         $vr8, $vr0, $vr1, $vr9
+
+
+    vld             $vr0, a4, -112
+    vst             $vr8, a3, -16
+    vshuf.b         $vr8, $vr1, $vr2, $vr9
+    vld             $vr1, a4, -128
+
+    vst             $vr8, a3, -32
+    addi.d          a4, a4, -128
+    vshuf.b         $vr2, $vr2, $vr3, $vr9
+    vshuf.b         $vr3, $vr3, $vr4, $vr9
+
+    vst             $vr2, a3, -48
+    vshuf.b         $vr4, $vr4, $vr5, $vr9
+    vst             $vr3, a3, -64
+    vshuf.b         $vr5, $vr5, $vr6, $vr9
+
+    vst             $vr4, a3, -80
+    vshuf.b         $vr6, $vr6, $vr7, $vr9
+    vst             $vr5, a3, -96
+    vshuf.b         $vr7, $vr7, $vr0, $vr9
+
+
+    vst             $vr6, a3, -112
+    vst             $vr7, a3, -128
+    addi.d          a3, a3, -128
+    bne             a4, a6, L(back_un_loop)
+
+L(back_un_less_128):
+    blt             a2, t8, L(back_un_less_64)
+    vld             $vr2, a4, -16
+    vld             $vr3, a4, -32
+    vshuf.b         $vr4, $vr0, $vr1, $vr9
+
+    vld             $vr0, a4, -48
+    vst             $vr4, a3, -16
+    addi.d          a2, a2, -64
+    vshuf.b         $vr4, $vr1, $vr2, $vr9
+
+    vld             $vr1, a4, -64
+    addi.d          a4, a4, -64
+    vst             $vr4, a3, -32
+    vshuf.b         $vr2, $vr2, $vr3, $vr9
+
+
+    vshuf.b         $vr3, $vr3, $vr0, $vr9
+    vst             $vr2, a3, -48
+    vst             $vr3, a3, -64
+    addi.d          a3, a3, -64
+
+L(back_un_less_64):
+    blt             a2, t7, L(back_un_less_32)
+    vshuf.b         $vr3, $vr0, $vr1, $vr9
+    vld             $vr0, a4, -16
+    vst             $vr3, a3, -16
+
+    addi.d          a2, a2, -32
+    vshuf.b         $vr3, $vr1, $vr0, $vr9
+    vld             $vr1, a4, -32
+    addi.d          a4, a4, -32
+
+    vst             $vr3, a3, -32
+    addi.d          a3, a3, -32
+L(back_un_less_32):
+    blt             a2, t6, L(back_un_less_16)
+    vshuf.b         $vr2, $vr0, $vr1, $vr9
+
+
+    vor.v           $vr0, $vr1, $vr1
+    vld             $vr1, a4, -16
+    vst             $vr2, a3, -16
+    addi.d          a3, a3, -16
+
+L(back_un_less_16):
+    vld             $vr2, a1, 0
+    vshuf.b         $vr0, $vr0, $vr1, $vr9
+    vst             $vr0, a3, -16
+    vst             $vr2, a0, 0
+
+    jr              ra
+END(MEMMOVE_NAME)
+
+#ifdef _LIBC
+libc_hidden_builtin_def (MEMCPY_NAME)
+libc_hidden_builtin_def (MEMMOVE_NAME)
+#endif
+
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/memmove-unaligned.S b/sysdeps/loongarch/lp64/multiarch/memmove-unaligned.S
new file mode 100644
index 00000000..27ed0c9c
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/memmove-unaligned.S
@@ -0,0 +1,478 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <regdef.h>
+#include <sys/asm.h>
+#endif
+
+#if IS_IN (libc)
+
+#define MEMMOVE_NAME __memmove_unaligned
+
+#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
+
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/memmove.c b/sysdeps/loongarch/lp64/multiarch/memmove.c
new file mode 100644
index 00000000..50a5205b
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/memmove.c
@@ -0,0 +1,39 @@
+/* Multiple versions of memcpy.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2017-2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+/* Define multiple versions only for the definition in libc.  */
+#if IS_IN (libc)
+# define memmove __redirect_memmove
+# include <string.h>
+# undef memmove
+
+# define SYMBOL_NAME memmove
+# include "ifunc-lasx.h"
+
+libc_ifunc_redirected (__redirect_memmove, __new_memmove,
+		       IFUNC_SELECTOR ());
+
+# ifdef SHARED
+__hidden_ver1 (__new_memmove, __GI_memmove, __redirect_memmove)
+  __attribute__ ((visibility ("hidden")));
+# endif
+
+# include <shlib-compat.h>
+versioned_symbol (libc, __new_memmove, memmove, GLIBC_2_27);
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/memrchr-generic.c b/sysdeps/loongarch/lp64/multiarch/memrchr-generic.c
new file mode 100644
index 00000000..ee7ab39c
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/memrchr-generic.c
@@ -0,0 +1,9 @@
+
+#if IS_IN (libc)
+
+#define MEMRCHR __memrchr_generic
+
+#endif
+
+#include <string/memrchr.c>
+weak_alias (__memrchr_generic, __memrchr)
diff --git a/sysdeps/loongarch/lp64/multiarch/memrchr-lasx.S b/sysdeps/loongarch/lp64/multiarch/memrchr-lasx.S
new file mode 100644
index 00000000..57e1035f
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/memrchr-lasx.S
@@ -0,0 +1,114 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <sys/asm.h>
+#include <sys/regdef.h>
+#endif
+
+#if IS_IN (libc)
+
+#ifndef MEMRCHR
+#define MEMRCHR	__memrchr_lasx
+#endif
+
+LEAF(MEMRCHR)
+    .align          6
+    beqz            a2, L(ret0)
+    addi.d          a2, a2, -1
+    add.d           a3, a0, a2
+    andi            t1, a3, 0x3f
+
+    bstrins.d       a3, zero, 5, 0
+    addi.d          t1, t1, 1      # len for unaligned address
+    xvld            $xr0, a3, 0
+    xvld            $xr1, a3, 32
+
+    sub.d           t2, zero, t1
+    li.d            t3, -1
+    xvreplgr2vr.b   $xr2, a1
+    andi            t4, a0, 0x3f
+
+    srl.d           t2, t3, t2
+    xvseq.b         $xr0, $xr0, $xr2
+    xvseq.b         $xr1, $xr1, $xr2
+    xvmsknz.b       $xr0, $xr0
+
+
+    xvmsknz.b       $xr1, $xr1
+    xvpickve.w      $xr3, $xr0, 4
+    xvpickve.w      $xr4, $xr1, 4
+    vilvl.h         $vr0, $vr3, $vr0
+
+    vilvl.h         $vr1, $vr4, $vr1
+    vilvl.w         $vr0, $vr1, $vr0
+    movfr2gr.d      t0, $f0
+    and             t0, t0, t2
+
+    bltu            a2, t1, L(end)
+    bnez            t0, L(found)
+    bstrins.d       a0, zero, 5, 0
+L(loop):
+    xvld            $xr0, a3, -64
+
+    xvld            $xr1, a3, -32
+    addi.d          a3, a3, -64
+    xvseq.b         $xr0, $xr0, $xr2
+    xvseq.b         $xr1, $xr1, $xr2
+
+
+    beq             a0, a3, L(out)
+    xvmax.bu        $xr3, $xr0, $xr1
+    xvseteqz.v      $fcc0, $xr3
+    bcnez           $fcc0, L(loop)
+
+    xvmsknz.b       $xr0, $xr0
+    xvmsknz.b       $xr1, $xr1
+    xvpickve.w      $xr3, $xr0, 4
+    xvpickve.w      $xr4, $xr1, 4
+
+    vilvl.h         $vr0, $vr3, $vr0
+    vilvl.h         $vr1, $vr4, $vr1
+    vilvl.w         $vr0, $vr1, $vr0
+    movfr2gr.d      t0, $f0
+
+L(found):
+    addi.d          a0, a3, 63
+    clz.d           t1, t0
+    sub.d           a0, a0, t1
+    jr              ra
+
+
+L(out):
+    xvmsknz.b       $xr0, $xr0
+    xvmsknz.b       $xr1, $xr1
+    xvpickve.w      $xr3, $xr0, 4
+    xvpickve.w      $xr4, $xr1, 4
+
+    vilvl.h         $vr0, $vr3, $vr0
+    vilvl.h         $vr1, $vr4, $vr1
+    vilvl.w         $vr0, $vr1, $vr0
+    movfr2gr.d      t0, $f0
+
+L(end):
+    sll.d           t2, t3, t4
+    and             t0, t0, t2
+    addi.d          a0, a3, 63
+    clz.d           t1, t0
+
+    sub.d           a0, a0, t1
+    maskeqz         a0, a0, t0
+    jr              ra
+L(ret0):
+    move            a0, zero
+
+
+    jr              ra
+END(MEMRCHR)
+
+#ifdef _LIBC
+libc_hidden_builtin_def (MEMRCHR)
+#endif
+
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/memrchr-lsx.S b/sysdeps/loongarch/lp64/multiarch/memrchr-lsx.S
new file mode 100644
index 00000000..eac2059a
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/memrchr-lsx.S
@@ -0,0 +1,96 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <regdef.h>
+#include <sys/asm.h>
+#endif
+
+#if IS_IN (libc)
+
+#define MEMRCHR	__memrchr_lsx
+
+LEAF(MEMRCHR)
+    .align          6
+    beqz            a2, L(ret0)
+    addi.d          a2, a2, -1
+    add.d           a3, a0, a2
+    andi            t1, a3, 0x1f
+
+    bstrins.d       a3, zero, 4, 0
+    addi.d          t1, t1, 1      # len for unaligned address
+    vld             $vr0, a3, 0
+    vld             $vr1, a3, 16
+
+    sub.d           t2, zero, t1
+    li.d            t3, -1
+    vreplgr2vr.b    $vr2, a1
+    andi            t4, a0, 0x1f
+
+    srl.d           t2, t3, t2
+    vseq.b          $vr0, $vr0, $vr2
+    vseq.b          $vr1, $vr1, $vr2
+    vmsknz.b        $vr0, $vr0
+
+
+    vmsknz.b        $vr1, $vr1
+    vilvl.h         $vr0, $vr1, $vr0
+    movfr2gr.s      t0, $f0
+    and             t0, t0, t2
+
+    bltu            a2, t1, L(end)
+    bnez            t0, L(found)
+    bstrins.d       a0, zero, 4, 0
+L(loop):
+    vld             $vr0, a3, -32
+
+    vld             $vr1, a3, -16
+    addi.d          a3, a3, -32
+    vseq.b          $vr0, $vr0, $vr2
+    vseq.b          $vr1, $vr1, $vr2
+
+    beq             a0, a3, L(out)
+    vmax.bu         $vr3, $vr0, $vr1
+    vseteqz.v       $fcc0, $vr3
+    bcnez           $fcc0, L(loop)
+
+
+    vmsknz.b        $vr0, $vr0
+    vmsknz.b        $vr1, $vr1
+    vilvl.h         $vr0, $vr1, $vr0
+    movfr2gr.s      t0, $f0
+
+L(found):
+    addi.d          a0, a3, 31
+    clz.w           t1, t0
+    sub.d           a0, a0, t1
+    jr              ra
+
+L(out):
+    vmsknz.b        $vr0, $vr0
+    vmsknz.b        $vr1, $vr1
+    vilvl.h         $vr0, $vr1, $vr0
+    movfr2gr.s      t0, $f0
+
+L(end):
+    sll.d           t2, t3, t4
+    and             t0, t0, t2
+    addi.d          a0, a3, 31
+    clz.w           t1, t0
+
+
+    sub.d           a0, a0, t1
+    maskeqz         a0, a0, t0
+    jr              ra
+L(ret0):
+    move            a0, zero
+
+    jr              ra
+END(MEMRCHR)
+
+#ifdef _LIBC
+libc_hidden_builtin_def (MEMRCHR)
+#endif
+
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/memrchr.c b/sysdeps/loongarch/lp64/multiarch/memrchr.c
new file mode 100644
index 00000000..675c3115
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/memrchr.c
@@ -0,0 +1,39 @@
+/* Multiple versions of memrchr.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2017-2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+/* Define multiple versions only for the definition in libc.  */
+#if IS_IN (libc)
+# define memrchr __redirect_memrchr
+# include <string.h>
+# undef memrchr
+
+# define SYMBOL_NAME memrchr
+# include "ifunc-memrchr.h"
+
+libc_ifunc_redirected (__redirect_memrchr, __new_memrchr,
+		       IFUNC_SELECTOR ());
+
+# ifdef SHARED
+__hidden_ver1 (__new_memrchr, __GI_memrchr, __redirect_memrchr)
+  __attribute__ ((visibility ("hidden")));
+# endif
+
+# include <shlib-compat.h>
+versioned_symbol (libc, __new_memrchr, memrchr, GLIBC_2_27);
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/memset-aligned.S b/sysdeps/loongarch/lp64/multiarch/memset-aligned.S
new file mode 100644
index 00000000..da2f5ada
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/memset-aligned.S
@@ -0,0 +1,9 @@
+
+#if IS_IN (libc)
+
+#define MEMSET_NAME __memset_aligned
+
+#endif
+
+#include "../memset.S"
+
diff --git a/sysdeps/loongarch/lp64/multiarch/memset-lasx.S b/sysdeps/loongarch/lp64/multiarch/memset-lasx.S
new file mode 100644
index 00000000..1bd2dda9
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/memset-lasx.S
@@ -0,0 +1,132 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <sys/asm.h>
+#include <sys/regdef.h>
+#endif
+
+#if IS_IN (libc)
+
+#define MEMSET	__memset_lasx
+
+LEAF(MEMSET)
+    .align          6
+    li.d            t1, 32
+    move            a3, a0
+    xvreplgr2vr.b   $xr0, a1
+    add.d           a4, a0, a2
+
+    bgeu            t1, a2, L(less_32bytes) # len <= 32
+    li.d            t3, 128
+    li.d            t2, 64
+    blt             t3, a2, L(long_bytes)   # len > 128
+
+L(less_128bytes):
+    bgeu            t2, a2, L(less_64bytes) # len <= 64
+    xvst            $xr0, a3, 0
+    xvst            $xr0, a3, 32
+    xvst            $xr0, a4, -32
+
+    xvst            $xr0, a4, -64
+    jr              ra
+L(less_64bytes):
+    xvst            $xr0, a3, 0
+    xvst            $xr0, a4, -32
+
+
+    jr              ra
+L(less_32bytes):
+    srli.d          t0, a2, 4
+    beqz            t0, L(less_16bytes)
+    vst             $vr0, a3, 0
+
+    vst             $vr0, a4, -16
+    jr              ra
+L(less_16bytes):
+    srli.d          t0, a2, 3
+    beqz            t0, L(less_8bytes)
+
+    vstelm.d        $vr0, a3, 0, 0
+    vstelm.d        $vr0, a4, -8, 0
+    jr              ra
+L(less_8bytes):
+    srli.d          t0, a2, 2
+
+    beqz            t0, L(less_4bytes)
+    vstelm.w        $vr0, a3, 0, 0
+    vstelm.w        $vr0, a4, -4, 0
+    jr              ra
+
+
+L(less_4bytes):
+    srli.d          t0, a2, 1
+    beqz            t0, L(less_2bytes)
+    vstelm.h        $vr0, a3, 0, 0
+    vstelm.h        $vr0, a4, -2, 0
+
+    jr              ra
+L(less_2bytes):
+    beqz            a2, L(less_1bytes)
+    st.b            a1, a3, 0
+L(less_1bytes):
+    jr              ra
+
+L(long_bytes):
+    xvst            $xr0, a3, 0
+    bstrins.d       a3, zero, 4, 0
+    addi.d          a3, a3, 32
+    sub.d           a2, a4, a3
+
+    andi            t0, a2, 0xff
+    beq             t0, a2, L(long_end)
+    move            a2, t0
+    sub.d           t0, a4, t0
+
+
+L(loop_256):
+    xvst            $xr0, a3, 0
+    xvst            $xr0, a3, 32
+    xvst            $xr0, a3, 64
+    xvst            $xr0, a3, 96
+
+    xvst            $xr0, a3, 128
+    xvst            $xr0, a3, 160
+    xvst            $xr0, a3, 192
+    xvst            $xr0, a3, 224
+
+    addi.d          a3, a3, 256
+    bne             a3, t0, L(loop_256)
+L(long_end):
+    bltu            a2, t3, L(end_less_128)
+    addi.d          a2, a2, -128
+
+    xvst            $xr0, a3, 0
+    xvst            $xr0, a3, 32
+    xvst            $xr0, a3, 64
+    xvst            $xr0, a3, 96
+
+
+    addi.d          a3, a3, 128
+L(end_less_128):
+    bltu            a2, t2, L(end_less_64)
+    addi.d          a2, a2, -64
+    xvst            $xr0, a3, 0
+
+    xvst            $xr0, a3, 32
+    addi.d          a3, a3, 64
+L(end_less_64):
+    bltu            a2, t1, L(end_less_32)
+    xvst            $xr0, a3, 0
+
+L(end_less_32):
+    xvst            $xr0, a4, -32
+    jr              ra
+END(MEMSET)
+
+#ifdef _LIBC
+libc_hidden_builtin_def (MEMSET)
+#endif
+
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/memset-lsx.S b/sysdeps/loongarch/lp64/multiarch/memset-lsx.S
new file mode 100644
index 00000000..a3bbadb7
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/memset-lsx.S
@@ -0,0 +1,125 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <regdef.h>
+#include <sys/asm.h>
+#endif
+
+#if IS_IN (libc)
+
+#define MEMSET	__memset_lsx
+
+LEAF(MEMSET)
+    .align          6
+    li.d            t1, 16
+    move            a3, a0
+    vreplgr2vr.b    $vr0, a1
+    add.d           a4, a0, a2
+
+    bgeu            t1, a2, L(less_16bytes) # len <= 16
+    li.d            t3, 64
+    li.d            t2, 32
+    bgeu            a2, t3, L(long_bytes) # len > 64
+
+L(less_64bytes):
+    bgeu            t2, a2, L(less_32bytes) # len <= 32
+    vst             $vr0, a3, 0
+    vst             $vr0, a3, 16
+    vst             $vr0, a4, -32
+
+    vst             $vr0, a4, -16
+    jr              ra
+L(less_32bytes):
+    vst             $vr0, a3, 0
+    vst             $vr0, a4, -16
+
+
+    jr              ra
+L(less_16bytes):
+    srli.d          t0, a2, 3
+    beqz            t0, L(less_8bytes)
+    vstelm.d        $vr0, a3, 0, 0
+
+    vstelm.d        $vr0, a4, -8, 0
+    jr              ra
+L(less_8bytes):
+    srli.d          t0, a2, 2
+    beqz            t0, L(less_4bytes)
+
+    vstelm.w        $vr0, a3, 0, 0
+    vstelm.w        $vr0, a4, -4, 0
+    jr              ra
+L(less_4bytes):
+    srli.d          t0, a2, 1
+
+    beqz            t0, L(less_2bytes)
+    vstelm.h        $vr0, a3, 0, 0
+    vstelm.h        $vr0, a4, -2, 0
+    jr              ra
+
+
+L(less_2bytes):
+    beqz            a2, L(less_1bytes)
+    vstelm.b        $vr0, a3, 0, 0
+L(less_1bytes):
+    jr              ra
+L(long_bytes):
+    vst             $vr0, a3, 0
+
+    bstrins.d       a3, zero, 3, 0
+    addi.d          a3, a3, 16
+    sub.d           a2, a4, a3
+    andi            t0, a2, 0x7f
+
+    beq             t0, a2, L(long_end)
+    move            a2, t0
+    sub.d           t0, a4, t0
+
+L(loop_128):
+    vst             $vr0, a3, 0
+
+    vst             $vr0, a3, 16
+    vst             $vr0, a3, 32
+    vst             $vr0, a3, 48
+    vst             $vr0, a3, 64
+
+
+    vst             $vr0, a3, 80
+    vst             $vr0, a3, 96
+    vst             $vr0, a3, 112
+    addi.d          a3, a3, 128
+
+    bne             a3, t0, L(loop_128)
+L(long_end):
+    bltu            a2, t3, L(end_less_64)
+    addi.d          a2, a2, -64
+    vst             $vr0, a3, 0
+
+    vst             $vr0, a3, 16
+    vst             $vr0, a3, 32
+    vst             $vr0, a3, 48
+    addi.d          a3, a3, 64
+
+L(end_less_64):
+    bltu            a2, t2, L(end_less_32)
+    addi.d          a2, a2, -32
+    vst             $vr0, a3, 0
+    vst             $vr0, a3, 16
+
+    addi.d          a3, a3, 32
+L(end_less_32):
+    bltu            a2, t1, L(end_less_16)
+    vst             $vr0, a3, 0
+
+L(end_less_16):
+    vst             $vr0, a4, -16
+    jr              ra
+END(MEMSET)
+
+#ifdef _LIBC
+libc_hidden_builtin_def (MEMSET)
+#endif
+
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/memset-unaligned.S b/sysdeps/loongarch/lp64/multiarch/memset-unaligned.S
new file mode 100644
index 00000000..16ff2ef7
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/memset-unaligned.S
@@ -0,0 +1,177 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <sys/asm.h>
+#include <sys/regdef.h>
+#endif
+
+#if IS_IN (libc)
+
+#define MEMSET_NAME __memset_unaligned
+
+#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
+
+#ifdef ANDROID_CHANGES
+LEAF(MEMSET_NAME, 0)
+#else
+LEAF(MEMSET_NAME)
+#endif
+
+	.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_NAME)
+
+#ifndef ANDROID_CHANGES
+#ifdef _LIBC
+libc_hidden_builtin_def (MEMSET_NAME)
+#endif
+#endif
+
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/memset.c b/sysdeps/loongarch/lp64/multiarch/memset.c
new file mode 100644
index 00000000..fb316be5
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/memset.c
@@ -0,0 +1,39 @@
+/* Multiple versions of memset.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2017-2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+/* Define multiple versions only for the definition in libc.  */
+#if IS_IN (libc)
+# define memset __redirect_memset
+# include <string.h>
+# undef memset
+
+# define SYMBOL_NAME memset
+# include "ifunc-lasx.h"
+
+libc_ifunc_redirected (__redirect_memset, __new_memset,
+		       IFUNC_SELECTOR ());
+
+# ifdef SHARED
+__hidden_ver1 (__new_memset, __GI_memset, __redirect_memset)
+  __attribute__ ((visibility ("hidden")));
+# endif
+
+# include <shlib-compat.h>
+versioned_symbol (libc, __new_memset, memset, GLIBC_2_27);
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/rawmemchr-aligned.S b/sysdeps/loongarch/lp64/multiarch/rawmemchr-aligned.S
new file mode 100644
index 00000000..0b46b4ca
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/rawmemchr-aligned.S
@@ -0,0 +1,7 @@
+
+#if IS_IN (libc)
+#define RAWMEMCHR_NAME __rawmemchr_aligned
+#endif
+
+#include "../rawmemchr.S"
+
diff --git a/sysdeps/loongarch/lp64/multiarch/rawmemchr-lasx.S b/sysdeps/loongarch/lp64/multiarch/rawmemchr-lasx.S
new file mode 100644
index 00000000..bff92969
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/rawmemchr-lasx.S
@@ -0,0 +1,51 @@
+#include <sysdep.h>
+#include <sys/asm.h>
+
+#if IS_IN (libc)
+
+# define RAWMEMCHR __rawmemchr_lasx
+
+LEAF(RAWMEMCHR)
+    .align          6
+    move            a2, a0
+    bstrins.d       a0, zero, 4, 0
+    xvld            $xr0, a0, 0
+    xvreplgr2vr.b   $xr1, a1
+
+    xvseq.b         $xr0, $xr0, $xr1
+    xvmsknz.b       $xr0, $xr0
+    xvpickve.w      $xr2, $xr0, 4
+    vilvl.h         $vr0, $vr2, $vr0
+
+    movfr2gr.s      t0, $f0
+    sra.w           t0, t0, a2
+    beqz            t0, L(loop)
+    ctz.w           t0, t0
+
+    add.d           a0, a2, t0
+    jr              ra
+    nop
+    nop
+
+L(loop):
+    xvld            $xr0, a0, 32
+    addi.d          a0, a0, 32
+    xvseq.b         $xr0, $xr0, $xr1
+    xvseteqz.v      $fcc0, $xr0
+
+    bcnez           $fcc0, L(loop)
+    xvmsknz.b       $xr0, $xr0
+    xvpickve.w      $xr1, $xr0, 4
+    vilvl.h         $vr0, $vr1, $vr0
+
+    movfr2gr.s      t0, $f0
+    ctz.w           t0, t0
+    add.d           a0, a0, t0
+    jr              ra
+END(RAWMEMCHR)
+
+#ifdef _LIBC
+libc_hidden_builtin_def (RAWMEMCHR)
+#endif
+
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/rawmemchr-lsx.S b/sysdeps/loongarch/lp64/multiarch/rawmemchr-lsx.S
new file mode 100644
index 00000000..11a19c1d
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/rawmemchr-lsx.S
@@ -0,0 +1,56 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <regdef.h>
+#include <sys/asm.h>
+#endif
+
+#if IS_IN (libc)
+
+# define RAWMEMCHR __rawmemchr_lsx
+
+LEAF(RAWMEMCHR)
+    .align          6
+    move            a2, a0
+    bstrins.d       a0, zero, 4, 0
+    vld             $vr0, a0, 0
+    vld             $vr1, a0, 16
+
+    vreplgr2vr.b    $vr2, a1
+    vseq.b          $vr0, $vr0, $vr2
+    vseq.b          $vr1, $vr1, $vr2
+    vmsknz.b        $vr0, $vr0
+
+    vmsknz.b        $vr1, $vr1
+    vilvl.h         $vr0, $vr1, $vr0
+    movfr2gr.s      t0, $f0
+    sra.w           t0, t0, a2
+
+    beqz            t0, L(loop)
+    ctz.w           t0, t0
+    add.d           a0, a2, t0
+    jr              ra
+
+
+L(loop):
+    vld             $vr0, a0, 32
+    addi.d          a0, a0, 16
+    vseq.b          $vr0, $vr0, $vr2
+    vseteqz.v       $fcc0, $vr0
+
+    bcnez           $fcc0, L(loop)
+    addi.d          a0, a0, 16
+    vfrstpi.b       $vr0, $vr0, 0
+    vpickve2gr.bu   t0, $vr0, 0
+
+    add.d           a0, a0, t0
+    jr              ra
+END(RAWMEMCHR)
+
+#ifdef _LIBC
+libc_hidden_builtin_def (RAWMEMCHR)
+#endif
+
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/rawmemchr.c b/sysdeps/loongarch/lp64/multiarch/rawmemchr.c
new file mode 100644
index 00000000..1e514139
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/rawmemchr.c
@@ -0,0 +1,37 @@
+/* Multiple versions of rawmemchr.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2017-2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#if IS_IN (libc)
+# define rawmemchr __redirect_rawmemchr
+# define __rawmemchr __redirect___rawmemchr
+# include <string.h>
+# undef rawmemchr
+# undef __rawmemchr
+
+# define SYMBOL_NAME rawmemchr
+# include "ifunc-memchr.h"
+
+libc_ifunc_redirected (__redirect_rawmemchr, __rawmemchr,
+                       IFUNC_SELECTOR ());
+weak_alias (__rawmemchr, rawmemchr)
+# ifdef SHARED
+__hidden_ver1 (__rawmemchr, __GI___rawmemchr, __redirect___rawmemchr)
+  __attribute__((visibility ("hidden")));
+# endif
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/stpcpy-aligned.S b/sysdeps/loongarch/lp64/multiarch/stpcpy-aligned.S
new file mode 100644
index 00000000..3d134e3f
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/stpcpy-aligned.S
@@ -0,0 +1,8 @@
+
+#if IS_IN (libc)
+
+#define STPCPY_NAME __stpcpy_aligned
+
+#endif
+
+#include "../stpcpy.S"
diff --git a/sysdeps/loongarch/lp64/multiarch/stpcpy-lsx.S b/sysdeps/loongarch/lp64/multiarch/stpcpy-lsx.S
new file mode 100644
index 00000000..bf0eed43
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/stpcpy-lsx.S
@@ -0,0 +1,178 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <regdef.h>
+#include <sys/asm.h>
+#endif
+
+#if IS_IN (libc)
+
+#define STPCPY __stpcpy_lsx
+
+L(magic_num):
+    .align          6
+    .dword          0x0706050403020100
+    .dword          0x0f0e0d0c0b0a0908
+ENTRY_NO_ALIGN(STPCPY)
+    pcaddi          t0, -4
+    andi            a4, a1, 0xf
+    vld             $vr1, t0, 0
+    beqz            a4, L(load_start)
+
+    xor             t0, a1, a4
+    vld             $vr0, t0, 0
+    vreplgr2vr.b    $vr2, a4
+    vadd.b          $vr2, $vr2, $vr1
+
+    vshuf.b         $vr0, $vr2, $vr0, $vr2
+    vsetanyeqz.b    $fcc0, $vr0
+    bcnez           $fcc0, L(end)
+L(load_start):
+    vld             $vr0, a1, 0
+
+
+    li.d            t1, 16
+    andi            a3, a0, 0xf
+    vsetanyeqz.b    $fcc0, $vr0
+    sub.d           t0, t1, a3
+
+    bcnez           $fcc0, L(end)
+    add.d           a1, a1, t0
+    vst             $vr0, a0, 0
+    add.d           a0, a0, t0
+
+    bne             a3, a4, L(unaligned)
+    vld             $vr0, a1, 0
+    vsetanyeqz.b    $fcc0, $vr0
+    bcnez           $fcc0, L(end)
+
+L(loop):
+    vst             $vr0, a0, 0
+    vld             $vr0, a1, 16
+    addi.d          a0, a0, 16
+    addi.d          a1, a1, 16
+
+
+    vsetanyeqz.b    $fcc0, $vr0
+    bceqz           $fcc0, L(loop)
+    vmsknz.b        $vr1, $vr0
+    movfr2gr.s      t0, $f1
+
+    cto.w           t0, t0
+    add.d           a1, a1, t0
+    vld             $vr0, a1, -15
+    add.d           a0, a0, t0
+
+    vst             $vr0, a0, -15
+    jr              ra
+L(end):
+    vseqi.b         $vr1, $vr0, 0
+    vfrstpi.b       $vr1, $vr1, 0
+
+    vpickve2gr.bu   t0, $vr1, 0
+    addi.d          t0, t0, 1
+L(end_16):
+    andi            t1, t0, 16
+    beqz            t1, L(end_8)
+
+
+    vst             $vr0, a0, 0
+    addi.d          a0, a0, 15
+    jr              ra
+L(end_8):
+    andi            t2, t0, 8
+
+    andi            t3, t0, 4
+    andi            t4, t0, 2
+    andi            t5, t0, 1
+    beqz            t2, L(end_4)
+
+    vstelm.d        $vr0, a0, 0, 0
+    addi.d          a0, a0, 8
+    vbsrl.v         $vr0, $vr0, 8
+L(end_4):
+    beqz            t3, L(end_2)
+
+    vstelm.w        $vr0, a0, 0, 0
+    addi.d          a0, a0, 4
+    vbsrl.v         $vr0, $vr0, 4
+L(end_2):
+    beqz            t4, L(end_1)
+
+
+    vstelm.h        $vr0, a0, 0, 0
+    addi.d          a0, a0, 2
+    vbsrl.v         $vr0, $vr0, 2
+L(end_1):
+    beqz            t5, L(out)
+
+    vstelm.b        $vr0, a0, 0, 0
+    addi.d          a0, a0, 1
+L(out):
+    addi.d          a0, a0, -1
+    jr              ra
+
+    nop
+    nop
+L(unaligned):
+    andi           a3, a1, 0xf
+    bstrins.d      a1, zero, 3, 0
+
+    vld            $vr2, a1, 0
+    vreplgr2vr.b   $vr3, a3
+    vslt.b         $vr4, $vr1, $vr3
+    vor.v          $vr0, $vr2, $vr4
+
+
+    vsetanyeqz.b   $fcc0, $vr0
+    bcnez          $fcc0, L(un_first_end)
+    vld            $vr0, a1, 16
+    vadd.b         $vr3, $vr3, $vr1
+
+    addi.d         a1, a1, 16
+    vshuf.b        $vr4, $vr0, $vr2, $vr3
+    vsetanyeqz.b   $fcc0, $vr0
+    bcnez          $fcc0, L(un_end)
+
+L(un_loop):
+    vor.v          $vr2, $vr0, $vr0
+    vld            $vr0, a1, 16
+    vst            $vr4, a0, 0
+    addi.d         a1, a1, 16
+
+    addi.d         a0, a0, 16
+    vshuf.b        $vr4, $vr0, $vr2, $vr3
+    vsetanyeqz.b   $fcc0, $vr0
+    bceqz          $fcc0, L(un_loop)
+
+
+L(un_end):
+    vsetanyeqz.b    $fcc0, $vr4
+    bcnez           $fcc0, 1f
+    vst             $vr4, a0, 0
+1:
+    vmsknz.b        $vr1, $vr0
+
+    movfr2gr.s      t0, $f1
+    cto.w           t0, t0
+    add.d           a1, a1, t0
+    vld             $vr0, a1, -15
+
+    add.d           a0, a0, t0
+    sub.d           a0, a0, a3
+    vst             $vr0, a0, 1
+    addi.d          a0, a0, 16
+
+    jr              ra
+L(un_first_end):
+    addi.d          a0, a0, -16
+    b               1b
+END(STPCPY)
+
+#ifdef _LIBC
+libc_hidden_builtin_def (STPCPY)
+#endif
+
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/stpcpy.c b/sysdeps/loongarch/lp64/multiarch/stpcpy.c
new file mode 100644
index 00000000..531a3ed6
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/stpcpy.c
@@ -0,0 +1,43 @@
+/* Multiple versions of stpcpy.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2017-2023 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+/* Define multiple versions only for the definition in libc.  */
+#if IS_IN (libc)
+# define stpcpy __redirect_stpcpy
+# define __stpcpy __redirect___stpcpy
+# define NO_MEMPCPY_STPCPY_REDIRECT
+# define __NO_STRING_INLINES
+# include <string.h>
+# undef stpcpy
+# undef __stpcpy
+
+# define SYMBOL_NAME stpcpy
+# include "ifunc-stpcpy.h"
+
+libc_ifunc_redirected (__redirect_stpcpy, __stpcpy, IFUNC_SELECTOR ());
+
+weak_alias (__stpcpy, stpcpy)
+# ifdef SHARED
+__hidden_ver1 (__stpcpy, __GI___stpcpy, __redirect___stpcpy)
+  __attribute__ ((visibility ("hidden")));
+__hidden_ver1 (stpcpy, __GI_stpcpy, __redirect_stpcpy)
+  __attribute__ ((visibility ("hidden")));
+# endif
+#endif
+
diff --git a/sysdeps/loongarch/lp64/multiarch/strchr-aligned.S b/sysdeps/loongarch/lp64/multiarch/strchr-aligned.S
new file mode 100644
index 00000000..92365658
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/strchr-aligned.S
@@ -0,0 +1,10 @@
+
+#if IS_IN (libc)
+
+#define STRCHR_NAME __strchr_aligned
+
+#endif
+
+#include "../strchr.S"
+
+weak_alias (STRCHR_NAME, index)
diff --git a/sysdeps/loongarch/lp64/multiarch/strchr-lasx.S b/sysdeps/loongarch/lp64/multiarch/strchr-lasx.S
new file mode 100644
index 00000000..ea7eb9d2
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/strchr-lasx.S
@@ -0,0 +1,81 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <sys/asm.h>
+#include <sys/regdef.h>
+#endif
+
+#if IS_IN (libc)
+
+#ifndef AS_STRCHRNUL
+#define STRCHR	__strchr_lasx
+#endif
+
+LEAF(STRCHR)
+    .align          6
+    andi            t1, a0, 0x1f
+    bstrins.d       a0, zero, 4, 0
+    xvld            $xr0, a0, 0
+    li.d            t2, -1
+
+    xvreplgr2vr.b   $xr1, a1
+    sll.d           t1, t2, t1
+    xvxor.v         $xr2, $xr0, $xr1
+    xvmin.bu        $xr0, $xr0, $xr2
+
+    xvmsknz.b       $xr0, $xr0
+    xvpickve.w      $xr3, $xr0, 4
+    vilvl.h         $vr0, $vr3, $vr0
+    movfr2gr.s      t0, $f0
+
+    orn             t0, t0, t1
+    bne             t0, t2, L(end)
+    addi.d          a0, a0, 32
+    nop
+
+
+L(loop):
+    xvld            $xr0, a0, 0
+    xvxor.v         $xr2, $xr0, $xr1
+    xvmin.bu        $xr0, $xr0, $xr2
+    xvsetanyeqz.b   $fcc0, $xr0
+
+    bcnez           $fcc0, L(loop_end)
+    xvld            $xr0, a0, 32
+    addi.d          a0, a0, 64
+    xvxor.v         $xr2, $xr0, $xr1
+
+    xvmin.bu        $xr0, $xr0, $xr2
+    xvsetanyeqz.b   $fcc0, $xr0
+    bceqz           $fcc0, L(loop)
+    addi.d          a0, a0, -32
+
+L(loop_end):
+    xvmsknz.b       $xr0, $xr0
+    xvpickve.w      $xr1, $xr0, 4
+    vilvl.h         $vr0, $vr1, $vr0
+    movfr2gr.s      t0, $f0
+
+
+L(end):
+    cto.w           t0, t0
+    add.d           a0, a0, t0
+#ifndef AS_STRCHRNUL
+    vreplgr2vr.b    $vr0, t0
+    xvpermi.q       $xr3, $xr2, 1
+
+    vshuf.b         $vr0, $vr3, $vr2, $vr0
+    vpickve2gr.bu   t0, $vr0, 0
+    masknez         a0, a0, t0
+#endif
+    jr              ra
+
+END(STRCHR)
+
+#ifdef _LIBC
+libc_hidden_builtin_def(STRCHR)
+#endif
+
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/strchr-lsx.S b/sysdeps/loongarch/lp64/multiarch/strchr-lsx.S
new file mode 100644
index 00000000..64ead00b
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/strchr-lsx.S
@@ -0,0 +1,61 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <regdef.h>
+#include <sys/asm.h>
+#endif
+
+#if IS_IN (libc)
+
+#ifndef AS_STRCHRNUL
+#define STRCHR	__strchr_lsx
+#endif
+
+LEAF(STRCHR)
+    .align          6
+    andi            t1, a0, 0xf
+    bstrins.d       a0, zero, 3, 0
+    vld             $vr0, a0, 0
+    li.d            t2, -1
+
+    vreplgr2vr.b    $vr1, a1
+    sll.d           t3, t2, t1
+    vxor.v          $vr2, $vr0, $vr1
+    vmin.bu         $vr0, $vr0, $vr2
+
+    vmsknz.b        $vr0, $vr0
+    movfr2gr.s      t0, $f0
+    ext.w.h         t0, t0
+    orn             t0, t0, t3
+
+    beq             t0, t2, L(loop)
+L(found):
+    cto.w           t0, t0
+    add.d           a0, a0, t0
+#ifndef AS_STRCHRNUL
+    vreplve.b       $vr2, $vr2, t0
+    vpickve2gr.bu   t1, $vr2, 0
+    masknez         a0, a0, t1
+#endif
+    jr              ra
+
+
+L(loop):
+    vld             $vr0, a0, 16
+    addi.d          a0, a0, 16
+    vxor.v          $vr2, $vr0, $vr1
+    vmin.bu         $vr0, $vr0, $vr2
+
+    vsetanyeqz.b    $fcc0, $vr0
+    bceqz           $fcc0, L(loop)
+    vmsknz.b        $vr0, $vr0
+    movfr2gr.s      t0, $f0
+
+    b               L(found)
+END(STRCHR)
+
+libc_hidden_builtin_def (STRCHR)
+
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/strchr-unaligned.S b/sysdeps/loongarch/lp64/multiarch/strchr-unaligned.S
new file mode 100644
index 00000000..1d5e56c5
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/strchr-unaligned.S
@@ -0,0 +1,132 @@
+/* Copyright 2016 Loongson Technology Corporation Limited  */
+
+/* Author: songyuekun songyuekun@loongson.cn */
+
+/* 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
+*/
+
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <sys/asm.h>
+#include <sys/regdef.h>
+#endif
+
+
+#if IS_IN (libc)
+
+#define L_ADDIU  addi.d
+#define L_ADDU   add.d
+#define L_SUBU   sub.d
+
+#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
+
+#define STRCHR_NAME __strchr_unaligned
+
+/* char * strchr (const char *s1, int c); */
+LEAF(STRCHR_NAME)
+	.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_NAME)
+
+#ifndef ANDROID_CHANGES
+#ifdef _LIBC
+libc_hidden_builtin_def (STRCHR_NAME)
+#endif
+#endif
+
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/strchr.c b/sysdeps/loongarch/lp64/multiarch/strchr.c
new file mode 100644
index 00000000..c6b069ed
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/strchr.c
@@ -0,0 +1,39 @@
+/* Multiple versions of strchr.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2017-2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+/* Define multiple versions only for the definition in libc.  */
+#if IS_IN (libc)
+# define strchr __redirect_strchr
+# include <string.h>
+# undef strchr
+
+# define SYMBOL_NAME strchr
+# include "ifunc-lasx.h"
+
+libc_ifunc_redirected (__redirect_strchr, __new_strchr,
+		       IFUNC_SELECTOR ());
+weak_alias(__new_strchr, index)
+# ifdef SHARED
+__hidden_ver1 (__new_strchr, __GI_strchr, __redirect_strchr)
+  __attribute__ ((visibility ("hidden")));
+# endif
+
+# include <shlib-compat.h>
+versioned_symbol (libc, __new_strchr, strchr, GLIBC_2_27);
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/strchrnul-aligned.S b/sysdeps/loongarch/lp64/multiarch/strchrnul-aligned.S
new file mode 100644
index 00000000..4fa63ecc
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/strchrnul-aligned.S
@@ -0,0 +1,8 @@
+
+#if IS_IN (libc)
+
+#define STRCHRNUL_NAME __strchrnul_aligned
+
+#endif
+
+#include "../strchrnul.S"
diff --git a/sysdeps/loongarch/lp64/multiarch/strchrnul-lasx.S b/sysdeps/loongarch/lp64/multiarch/strchrnul-lasx.S
new file mode 100644
index 00000000..f8765413
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/strchrnul-lasx.S
@@ -0,0 +1,4 @@
+#define STRCHR __strchrnul_lasx
+#define AS_STRCHRNUL
+#include "strchr-lasx.S"
+
diff --git a/sysdeps/loongarch/lp64/multiarch/strchrnul-lsx.S b/sysdeps/loongarch/lp64/multiarch/strchrnul-lsx.S
new file mode 100644
index 00000000..d363f11f
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/strchrnul-lsx.S
@@ -0,0 +1,3 @@
+#define STRCHR __strchrnul_lsx
+#define AS_STRCHRNUL
+#include "strchr-lsx.S"
diff --git a/sysdeps/loongarch/lp64/multiarch/strchrnul-unaligned.S b/sysdeps/loongarch/lp64/multiarch/strchrnul-unaligned.S
new file mode 100644
index 00000000..6338d005
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/strchrnul-unaligned.S
@@ -0,0 +1,146 @@
+/* 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
+*/
+
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <sys/asm.h>
+#include <sys/regdef.h>
+#endif
+
+#if IS_IN (libc)
+
+#define L_ADDIU  addi.d
+#define L_ADDU   add.d
+#define L_SUBU   sub.d
+
+#define STRCHRNUL_NAME	__strchrnul_unaligned
+
+#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_NAME)
+	.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
+
+	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_NAME)
+
+#ifndef ANDROID_CHANGES
+#ifdef _LIBC
+weak_alias(STRCHRNUL_NAME, strchrnul)
+libc_hidden_builtin_def (STRCHRNUL_NAME)
+#endif
+#endif
+
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/strchrnul.c b/sysdeps/loongarch/lp64/multiarch/strchrnul.c
new file mode 100644
index 00000000..53a7273a
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/strchrnul.c
@@ -0,0 +1,34 @@
+/* Multiple versions of strchrnul.
+   All versions must be listed in ifunc-impl-list.c.
+   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/>.  */
+
+/* Define multiple versions only for the definition in libc.  */
+#if IS_IN (libc)
+# define strchrnul __redirect_strchrnul
+# define __strchrnul __redirect___strchrnul
+# include <string.h>
+# undef __strchrnul
+# undef strchrnul
+
+# define SYMBOL_NAME strchrnul
+# include "ifunc-lasx.h"
+
+libc_ifunc_redirected (__redirect_strchrnul, __strchrnul,
+                       IFUNC_SELECTOR ());
+weak_alias (__strchrnul, strchrnul)
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/strcmp-aligned.S b/sysdeps/loongarch/lp64/multiarch/strcmp-aligned.S
new file mode 100644
index 00000000..f84f52b8
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/strcmp-aligned.S
@@ -0,0 +1,8 @@
+
+#if IS_IN (libc)
+
+#define STRCMP_NAME __strcmp_aligned
+
+#endif
+
+#include "../strcmp.S"
diff --git a/sysdeps/loongarch/lp64/multiarch/strcmp-lsx.S b/sysdeps/loongarch/lp64/multiarch/strcmp-lsx.S
new file mode 100644
index 00000000..226b1d63
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/strcmp-lsx.S
@@ -0,0 +1,147 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <regdef.h>
+#include <sys/asm.h>
+#endif
+
+#if IS_IN (libc)
+
+#define STRCMP	__strcmp_lsx
+
+/* int strcmp (const char *s1, const char *s2); */
+L(magic_num):
+    .align          6
+    .dword          0x0706050403020100
+    .dword          0x0f0e0d0c0b0a0908
+
+ENTRY_NO_ALIGN(STRCMP)
+    pcaddi          t0, -4
+    andi            a2, a0, 0xf
+    vld             $vr2, t0, 0
+    andi            a3, a1, 0xf
+
+    bne             a2, a3, L(unaligned)
+    bstrins.d       a0, zero, 3, 0
+    bstrins.d       a1, zero, 3, 0
+    vld             $vr0, a0, 0
+
+    vld             $vr1, a1, 0
+    vreplgr2vr.b    $vr3, a2
+    vslt.b          $vr2, $vr2, $vr3
+    vseq.b          $vr3, $vr0, $vr1
+
+
+    vmin.bu         $vr3, $vr0, $vr3
+    vor.v           $vr3, $vr3, $vr2
+    vsetanyeqz.b    $fcc0, $vr3
+    bcnez           $fcc0, L(al_out)
+
+L(al_loop):
+    vld             $vr0, a0, 16
+    vld             $vr1, a1, 16
+    addi.d          a0, a0, 16
+    addi.d          a1, a1, 16
+
+    vseq.b          $vr3, $vr0, $vr1
+    vmin.bu         $vr3, $vr0, $vr3
+    vsetanyeqz.b    $fcc0, $vr3
+    bceqz           $fcc0, L(al_loop)
+
+L(al_out):
+    vseqi.b         $vr3, $vr3, 0
+    vfrstpi.b       $vr3, $vr3, 0
+    vshuf.b         $vr0, $vr0, $vr0, $vr3
+    vshuf.b         $vr1, $vr1, $vr1, $vr3
+
+
+    vpickve2gr.bu   t0, $vr0, 0
+    vpickve2gr.bu   t1, $vr1, 0
+    sub.d           a0, t0, t1
+    jr              ra
+
+    nop
+    nop
+    nop
+L(unaligned):
+    slt             a4, a2, a3
+
+    xor             t0, a0, a1
+    maskeqz         t0, t0, a4
+    xor             a0, a0, t0   # a0 hold the larger one
+    xor             a1, a1, t0   # a1 hold the small one
+
+    andi            a2, a0, 0xf
+    andi            a3, a1, 0xf
+    bstrins.d       a0, zero, 3, 0
+    bstrins.d       a1, zero, 3, 0
+
+
+    vld             $vr0, a0, 0
+    vld             $vr3, a1, 0
+    vreplgr2vr.b    $vr4, a2
+    vreplgr2vr.b    $vr5, a3
+
+    vslt.b          $vr7, $vr2, $vr4
+    vsub.b          $vr4, $vr4, $vr5
+    vaddi.bu        $vr6, $vr2, 16
+    vsub.b          $vr6, $vr6, $vr4
+
+    vshuf.b         $vr1, $vr3, $vr3, $vr6
+    vseq.b          $vr4, $vr0, $vr1
+    vmin.bu         $vr4, $vr0, $vr4
+    vor.v           $vr4, $vr4, $vr7
+
+    vsetanyeqz.b    $fcc0, $vr4
+    bcnez           $fcc0, L(un_end)
+    vslt.b          $vr5, $vr2, $vr5
+    vor.v           $vr3, $vr3, $vr5
+
+
+L(un_loop):
+    vld             $vr0, a0, 16
+    vsetanyeqz.b    $fcc0, $vr3
+    bcnez           $fcc0, L(remaining_end)
+    vor.v           $vr1, $vr3, $vr3
+
+    vld             $vr3, a1, 16
+    addi.d          a0, a0, 16
+    addi.d          a1, a1, 16
+    vshuf.b         $vr1, $vr3, $vr1, $vr6
+
+    vseq.b          $vr4, $vr0, $vr1
+    vmin.bu         $vr4, $vr0, $vr4
+    vsetanyeqz.b    $fcc0, $vr4
+    bceqz           $fcc0, L(un_loop)
+
+L(un_end):
+    vseqi.b         $vr4, $vr4, 0
+    vfrstpi.b       $vr4, $vr4, 0
+    vshuf.b         $vr0, $vr0, $vr0, $vr4
+    vshuf.b         $vr1, $vr1, $vr1, $vr4
+
+
+    vpickve2gr.bu   t0, $vr0, 0
+    vpickve2gr.bu   t1, $vr1, 0
+    sub.d           t3, t0, t1
+    sub.d           t4, t1, t0
+
+    masknez         t0, t3, a4
+    maskeqz         t1, t4, a4
+    or              a0, t0, t1
+    jr              ra
+
+L(remaining_end):
+    vshuf.b         $vr1, $vr3, $vr3, $vr6
+    vseq.b          $vr4, $vr0, $vr1
+    vmin.bu         $vr4, $vr4, $vr0
+    b               L(un_end)
+END(STRCMP)
+
+#ifdef _LIBC
+libc_hidden_builtin_def (STRCMP)
+#endif
+
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/strcmp-unaligned.S b/sysdeps/loongarch/lp64/multiarch/strcmp-unaligned.S
new file mode 100644
index 00000000..e29d872f
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/strcmp-unaligned.S
@@ -0,0 +1,191 @@
+/* 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
+*/
+
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <sys/asm.h>
+#include <sys/regdef.h>
+#endif
+
+
+#if IS_IN (libc)
+
+
+#define STRCMP_NAME __strcmp_unaligned
+
+#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_NAME)
+	.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
+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_NAME)
+
+#ifdef _LIBC
+libc_hidden_builtin_def (STRCMP_NAME)
+#endif
+
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/strcmp.c b/sysdeps/loongarch/lp64/multiarch/strcmp.c
new file mode 100644
index 00000000..0b20e6f0
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/strcmp.c
@@ -0,0 +1,35 @@
+/* Multiple versions of strcmp.
+   All versions must be listed in ifunc-impl-list.c.
+   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/>.  */
+
+/* Define multiple versions only for the definition in libc.  */
+#if IS_IN (libc)
+# define strcmp __redirect_strcmp
+# include <string.h>
+# undef strcmp
+
+# define SYMBOL_NAME strcmp
+#include <ifunc-lsx.h>
+
+libc_ifunc_redirected (__redirect_strcmp, strcmp, IFUNC_SELECTOR ());
+
+# ifdef SHARED
+__hidden_ver1 (strcmp, __GI_strcmp, __redirect_strcmp)
+  __attribute__ ((visibility ("hidden")));
+# endif
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/strcpy-aligned.S b/sysdeps/loongarch/lp64/multiarch/strcpy-aligned.S
new file mode 100644
index 00000000..4860398b
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/strcpy-aligned.S
@@ -0,0 +1,8 @@
+
+#if IS_IN (libc)
+
+#define STRCPY __strcpy_aligned
+
+#endif
+
+#include "../strcpy.S"
diff --git a/sysdeps/loongarch/lp64/multiarch/strcpy-lsx.S b/sysdeps/loongarch/lp64/multiarch/strcpy-lsx.S
new file mode 100644
index 00000000..76db561a
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/strcpy-lsx.S
@@ -0,0 +1,174 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <regdef.h>
+#include <sys/asm.h>
+#endif
+
+#if IS_IN (libc)
+
+#define STRCPY __strcpy_lsx
+
+/* int strcpy (const char *s1, const char *s2); */
+
+L(magic_num):
+    .align          6
+    .dword          0x0706050403020100
+    .dword          0x0f0e0d0c0b0a0908
+ENTRY_NO_ALIGN(STRCPY)
+    pcaddi          t0, -4
+    andi            a4, a1, 0xf
+    vld             $vr1, t0, 0
+    move            a2, a0
+
+    beqz            a4, L(load_start)
+    xor             t0, a1, a4
+    vld             $vr0, t0, 0
+    vreplgr2vr.b    $vr2, a4
+
+    vadd.b          $vr2, $vr2, $vr1
+    vshuf.b         $vr0, $vr2, $vr0, $vr2
+    vsetanyeqz.b    $fcc0, $vr0
+    bcnez           $fcc0, L(end)
+
+
+L(load_start):
+    vld             $vr0, a1, 0
+    li.d            t1, 16
+    andi            a3, a2, 0xf
+    vsetanyeqz.b    $fcc0, $vr0
+
+    sub.d           t0, t1, a3
+    bcnez           $fcc0, L(end)
+    add.d           a1, a1, t0
+    vst             $vr0, a2, 0
+
+    andi            a3, a1, 0xf
+    add.d           a2, a2, t0
+    bnez            a3, L(unaligned)
+    vld             $vr0, a1, 0
+
+    vsetanyeqz.b    $fcc0, $vr0
+    bcnez           $fcc0, L(end)
+L(loop):
+    vst             $vr0, a2, 0
+    vld             $vr0, a1, 16
+
+
+    addi.d          a2, a2, 16
+    addi.d          a1, a1, 16
+    vsetanyeqz.b    $fcc0, $vr0
+    bceqz           $fcc0, L(loop)
+
+    vmsknz.b        $vr1, $vr0
+    movfr2gr.s      t0, $f1
+    cto.w           t0, t0
+    add.d           a1, a1, t0
+
+    vld             $vr0, a1, -15
+    add.d           a2, a2, t0
+    vst             $vr0, a2, -15
+    jr              ra
+
+L(end):
+    vmsknz.b        $vr1, $vr0
+    movfr2gr.s      t0, $f1
+    cto.w           t0, t0
+    addi.d          t0, t0, 1
+
+
+L(end_16):
+    andi            t1, t0, 16
+    beqz            t1, L(end_8)
+    vst             $vr0, a2, 0
+    jr              ra
+
+L(end_8):
+    andi            t2, t0, 8
+    andi            t3, t0, 4
+    andi            t4, t0, 2
+    andi            t5, t0, 1
+
+    beqz            t2, L(end_4)
+    vstelm.d        $vr0, a2, 0, 0
+    addi.d          a2, a2, 8
+    vbsrl.v         $vr0, $vr0, 8
+
+L(end_4):
+    beqz            t3, L(end_2)
+    vstelm.w        $vr0, a2, 0, 0
+    addi.d          a2, a2, 4
+    vbsrl.v         $vr0, $vr0, 4
+
+
+L(end_2):
+    beqz            t4, L(end_1)
+    vstelm.h        $vr0, a2, 0, 0
+    addi.d          a2, a2, 2
+    vbsrl.v         $vr0, $vr0, 2
+
+L(end_1):
+    beqz            t5, L(out)
+    vstelm.b        $vr0, a2, 0, 0
+L(out):
+    jr              ra
+L(unaligned):
+    bstrins.d      a1, zero, 3, 0
+
+    vld            $vr2, a1, 0
+    vreplgr2vr.b   $vr3, a3
+    vslt.b         $vr4, $vr1, $vr3
+    vor.v          $vr0, $vr2, $vr4
+
+    vsetanyeqz.b   $fcc0, $vr0
+    bcnez          $fcc0, L(un_first_end)
+    vld            $vr0, a1, 16
+    vadd.b         $vr3, $vr3, $vr1
+
+
+    addi.d         a1, a1, 16
+    vshuf.b        $vr4, $vr0, $vr2, $vr3
+    vsetanyeqz.b   $fcc0, $vr0
+    bcnez          $fcc0, L(un_end)
+
+L(un_loop):
+    vor.v          $vr2, $vr0, $vr0
+    vld            $vr0, a1, 16
+    vst            $vr4, a2, 0
+    addi.d         a1, a1, 16
+
+    addi.d         a2, a2, 16
+    vshuf.b        $vr4, $vr0, $vr2, $vr3
+    vsetanyeqz.b   $fcc0, $vr0
+    bceqz          $fcc0, L(un_loop)
+
+L(un_end):
+    vsetanyeqz.b    $fcc0, $vr4
+    bcnez           $fcc0, 1f
+    vst             $vr4, a2, 0
+1:
+    vmsknz.b        $vr1, $vr0
+
+
+    movfr2gr.s      t0, $f1
+    cto.w           t0, t0
+    add.d           a1, a1, t0
+    vld             $vr0, a1, -15
+
+    add.d           a2, a2, t0
+    sub.d           a2, a2, a3
+    vst             $vr0, a2, 1
+    jr              ra
+
+L(un_first_end):
+    addi.d          a2, a2, -16
+    b               1b
+END(STRCPY)
+
+#ifdef _LIBC
+libc_hidden_builtin_def (STRCPY)
+#endif
+
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/strcpy-unaligned.S b/sysdeps/loongarch/lp64/multiarch/strcpy-unaligned.S
new file mode 100644
index 00000000..449733cb
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/strcpy-unaligned.S
@@ -0,0 +1,199 @@
+/* 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
+*/
+
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <sys/asm.h>
+#include <sys/regdef.h>
+#endif
+
+#if IS_IN (libc)
+
+#define STRCPY __strcpy_unaligned
+
+#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:
+	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
+
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/strcpy.c b/sysdeps/loongarch/lp64/multiarch/strcpy.c
new file mode 100644
index 00000000..48fecf66
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/strcpy.c
@@ -0,0 +1,36 @@
+/* Multiple versions of strcpy.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2017-2023 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+/* Define multiple versions only for the definition in libc.  */
+#if IS_IN (libc)
+# define strcpy __redirect_strcpy
+# include <string.h>
+# undef strcpy
+
+# define SYMBOL_NAME strcpy
+# include "ifunc-lsx.h"
+
+libc_ifunc_redirected (__redirect_strcpy, strcpy, IFUNC_SELECTOR ());
+
+# ifdef SHARED
+__hidden_ver1 (strcpy, __GI_strcpy, __redirect_strcpy)
+  __attribute__ ((visibility ("hidden")));
+# endif
+#endif
+
diff --git a/sysdeps/loongarch/lp64/multiarch/strlen-aligned.S b/sysdeps/loongarch/lp64/multiarch/strlen-aligned.S
new file mode 100644
index 00000000..d31875fd
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/strlen-aligned.S
@@ -0,0 +1,8 @@
+
+#if IS_IN (libc)
+
+#define STRLEN __strlen_aligned
+
+#endif
+
+#include "../strlen.S"
diff --git a/sysdeps/loongarch/lp64/multiarch/strlen-lasx.S b/sysdeps/loongarch/lp64/multiarch/strlen-lasx.S
new file mode 100644
index 00000000..cb276aa0
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/strlen-lasx.S
@@ -0,0 +1,55 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <sys/asm.h>
+#include <sys/regdef.h>
+#endif
+
+#if IS_IN (libc)
+
+#define STRLEN	__strlen_lasx
+
+/* size_t strlen(const char *s1); */
+
+LEAF(STRLEN)
+    .align          6
+    move            a1, a0
+    bstrins.d       a0, zero, 4, 0
+    li.d            t1, -1
+    xvld            $xr0, a0, 0
+
+    xvmsknz.b       $xr0, $xr0
+    xvpickve.w      $xr1, $xr0, 4
+    vilvl.h         $vr0, $vr1, $vr0
+    movfr2gr.s      t0, $f0  # sign extend
+
+    sra.w           t0, t0, a1
+    beq             t0, t1, L(loop)
+    cto.w           a0, t0
+    jr              ra
+
+L(loop):
+    xvld            $xr0, a0, 32
+    addi.d          a0, a0, 32
+    xvsetanyeqz.b   $fcc0, $xr0
+    bceqz           $fcc0, L(loop)
+
+
+    xvmsknz.b       $xr0, $xr0
+    sub.d           a0, a0, a1
+    xvpickve.w      $xr1, $xr0, 4
+    vilvl.h         $vr0, $vr1, $vr0
+
+    movfr2gr.s      t0, $f0
+    cto.w           t0, t0
+    add.d           a0, a0, t0
+    jr              ra
+END(STRLEN)
+
+#ifdef _LIBC
+libc_hidden_builtin_def (STRLEN)
+#endif
+
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/strlen-lsx.S b/sysdeps/loongarch/lp64/multiarch/strlen-lsx.S
new file mode 100644
index 00000000..6edcac8c
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/strlen-lsx.S
@@ -0,0 +1,63 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <regdef.h>
+#include <sys/asm.h>
+#endif
+
+#if IS_IN (libc)
+
+#define STRLEN	__strlen_lsx
+
+/* size_t strlen(const char *s1); */
+
+LEAF(STRLEN)
+    .align          6
+    move            a1, a0
+    bstrins.d       a0, zero, 4, 0
+    vld             $vr0, a0, 0
+    vld             $vr1, a0, 16
+
+    li.d            t1, -1
+    vmsknz.b        $vr0, $vr0
+    vmsknz.b        $vr1, $vr1
+    vilvl.h         $vr0, $vr1, $vr0
+
+    movfr2gr.s      t0, $f0
+    sra.w           t0, t0, a1
+    beq             t0, t1, L(loop)
+    cto.w           a0, t0
+
+    jr              ra
+    nop
+    nop
+    nop
+
+
+L(loop):
+    vld             $vr0, a0, 32
+    vld             $vr1, a0, 48
+    addi.d          a0, a0, 32
+    vmin.bu         $vr2, $vr0, $vr1
+
+    vsetanyeqz.b    $fcc0, $vr2
+    bceqz           $fcc0, L(loop)
+    vmsknz.b        $vr0, $vr0
+    vmsknz.b        $vr1, $vr1
+
+    vilvl.h         $vr0, $vr1, $vr0
+    sub.d           a0, a0, a1
+    movfr2gr.s      t0, $f0
+    cto.w           t0, t0
+
+    add.d           a0, a0, t0
+    jr              ra
+END(STRLEN)
+
+#ifdef _LIBC
+libc_hidden_builtin_def (STRLEN)
+#endif
+
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/strlen-unaligned.S b/sysdeps/loongarch/lp64/multiarch/strlen-unaligned.S
new file mode 100644
index 00000000..e9b7cf67
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/strlen-unaligned.S
@@ -0,0 +1,116 @@
+/* Copyright 2016 Loongson Technology Corporation Limited.  */
+
+/* Author: Songyuekun songyuekun@loongson.cn.  */
+
+/* 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.  */
+
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <sys/asm.h>
+#include <sys/regdef.h>
+#endif
+
+#if IS_IN (libc)
+
+#define L_ADDIU  addi.d
+#define L_ADDU   add.d
+#define L_SUBU   sub.d
+
+#define STRLEN	__strlen_unaligned
+
+/* size_t strlen (const char *s1); */
+
+LEAF(STRLEN)
+	.align		5
+	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
+
+	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
+	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
+
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/strlen.c b/sysdeps/loongarch/lp64/multiarch/strlen.c
new file mode 100644
index 00000000..e8454404
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/strlen.c
@@ -0,0 +1,39 @@
+/* Multiple versions of strlen.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2017-2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+/* Define multiple versions only for the definition in libc.  */
+#if IS_IN (libc)
+# define strlen __redirect_strlen
+# include <string.h>
+# undef strlen
+
+# define SYMBOL_NAME strlen
+# include "ifunc-lasx.h"
+
+libc_ifunc_redirected (__redirect_strlen, __new_strlen,
+		       IFUNC_SELECTOR ());
+
+# ifdef SHARED
+__hidden_ver1 (__new_strlen, __GI_strlen, __redirect_strlen)
+  __attribute__ ((visibility ("hidden")));
+# endif
+
+# include <shlib-compat.h>
+versioned_symbol (libc, __new_strlen, strlen, GLIBC_2_27);
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/strncmp-aligned.S b/sysdeps/loongarch/lp64/multiarch/strncmp-aligned.S
new file mode 100644
index 00000000..f371b19e
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/strncmp-aligned.S
@@ -0,0 +1,8 @@
+
+#if IS_IN (libc)
+
+#define STRNCMP __strncmp_aligned
+
+#endif
+
+#include "../strncmp.S"
diff --git a/sysdeps/loongarch/lp64/multiarch/strncmp-lsx.S b/sysdeps/loongarch/lp64/multiarch/strncmp-lsx.S
new file mode 100644
index 00000000..3399bf77
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/strncmp-lsx.S
@@ -0,0 +1,197 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <regdef.h>
+#include <sys/asm.h>
+#endif
+
+#if IS_IN (libc)
+
+#define STRNCMP	__strncmp_lsx
+
+/* int strncmp (const char *s1, const char *s2); */
+
+L(magic_num):
+    .align          6
+    .dword          0x0706050403020100
+    .dword          0x0f0e0d0c0b0a0908
+ENTRY_NO_ALIGN(STRNCMP)
+    beqz            a2, L(ret0)
+    pcaddi          t0, -5
+    andi            a3, a0, 0xf
+    vld             $vr2, t0, 0
+
+    andi            a4, a1, 0xf
+    li.d            t2, 16
+    bne             a3, a4, L(unaligned)
+    xor             t0, a0, a3
+
+    xor             t1, a1, a4
+    vld             $vr0, t0, 0
+    vld             $vr1, t1, 0
+    vreplgr2vr.b    $vr3, a3
+
+
+    sub.d           t2, t2, a3
+    vadd.b          $vr3, $vr3, $vr2
+    vshuf.b         $vr0, $vr3, $vr0, $vr3
+    vshuf.b         $vr1, $vr3, $vr1, $vr3
+
+    vseq.b          $vr3, $vr0, $vr1
+    vmin.bu         $vr3, $vr0, $vr3
+    bgeu            t2, a2, L(al_early_end)
+    vsetanyeqz.b    $fcc0, $vr3
+
+    bcnez           $fcc0, L(al_end)
+    add.d           a3, a0, a2
+    addi.d          a4, a3, -1
+    bstrins.d       a4, zero, 3, 0
+
+    sub.d           a2, a3, a4
+L(al_loop):
+    vld             $vr0, t0, 16
+    vld             $vr1, t1, 16
+    addi.d          t0, t0, 16
+
+
+    addi.d          t1, t1, 16
+    vseq.b          $vr3, $vr0, $vr1
+    vmin.bu         $vr3, $vr0, $vr3
+    beq             t0, a4, L(al_early_end)
+
+    vsetanyeqz.b    $fcc0, $vr3
+    bceqz           $fcc0, L(al_loop)
+L(al_end):
+    vseqi.b         $vr3, $vr3, 0
+    vfrstpi.b       $vr3, $vr3, 0
+
+    vshuf.b         $vr0, $vr0, $vr0, $vr3
+    vshuf.b         $vr1, $vr1, $vr1, $vr3
+    vpickve2gr.bu   t0, $vr0, 0
+    vpickve2gr.bu   t1, $vr1, 0
+
+    sub.d           a0, t0, t1
+    jr              ra
+L(al_early_end):
+    vreplgr2vr.b    $vr4, a2
+    vslt.b          $vr4, $vr2, $vr4
+
+
+    vorn.v          $vr3, $vr3, $vr4
+    b               L(al_end)
+L(unaligned):
+    slt             a5, a3, a4
+    xor             t0, a0, a1
+
+    maskeqz         t0, t0, a5
+    xor             a0, a0, t0   # a0 hold the larger one
+    xor             a1, a1, t0   # a1 hold the small one
+    andi            a3, a0, 0xf
+
+    andi            a4, a1, 0xf
+    xor             t0, a0, a3
+    xor             t1, a1, a4
+    vld             $vr0, t0, 0
+
+    vld             $vr3, t1, 0
+    sub.d           t2, t2, a3
+    vreplgr2vr.b    $vr4, a3
+    vreplgr2vr.b    $vr5, a4
+
+
+    vaddi.bu        $vr6, $vr2, 16
+    vsub.b          $vr7, $vr4, $vr5
+    vsub.b          $vr6, $vr6, $vr7
+    vadd.b          $vr4, $vr2, $vr4
+
+    vshuf.b         $vr1, $vr3, $vr3, $vr6
+    vshuf.b         $vr0, $vr7, $vr0, $vr4
+    vshuf.b         $vr1, $vr7, $vr1, $vr4
+    vseq.b          $vr4, $vr0, $vr1
+
+    vmin.bu         $vr4, $vr0, $vr4
+    bgeu            t2, a2, L(un_early_end)
+    vsetanyeqz.b    $fcc0, $vr4
+    bcnez           $fcc0, L(un_end)
+
+    add.d           a6, a0, a2
+    vslt.b          $vr5, $vr2, $vr5
+    addi.d          a7, a6, -1
+    vor.v           $vr3, $vr3, $vr5
+
+
+    bstrins.d       a7, zero, 3, 0
+    sub.d           a2, a6, a7
+L(un_loop):
+    vld             $vr0, t0, 16
+    addi.d          t0, t0, 16
+
+    vsetanyeqz.b    $fcc0, $vr3
+    bcnez           $fcc0, L(has_zero)
+    beq             t0, a7, L(end_with_len)
+    vor.v           $vr1, $vr3, $vr3
+
+    vld             $vr3, t1, 16
+    addi.d          t1, t1, 16
+    vshuf.b         $vr1, $vr3, $vr1, $vr6
+    vseq.b          $vr4, $vr0, $vr1
+
+    vmin.bu         $vr4, $vr0, $vr4
+    vsetanyeqz.b    $fcc0, $vr4
+    bceqz           $fcc0, L(un_loop)
+L(un_end):
+    vseqi.b         $vr4, $vr4, 0
+
+
+    vfrstpi.b       $vr4, $vr4, 0
+    vshuf.b         $vr0, $vr0, $vr0, $vr4
+    vshuf.b         $vr1, $vr1, $vr1, $vr4
+    vpickve2gr.bu   t0, $vr0, 0
+
+    vpickve2gr.bu   t1, $vr1, 0
+    sub.d           t2, t0, t1
+    sub.d           t3, t1, t0
+    masknez         t0, t2, a5
+
+    maskeqz         t1, t3, a5
+    or              a0, t0, t1
+    jr              ra
+L(has_zero):
+    vshuf.b         $vr1, $vr3, $vr3, $vr6
+
+    vseq.b          $vr4, $vr0, $vr1
+    vmin.bu         $vr4, $vr0, $vr4
+    bne             t0, a7, L(un_end)
+L(un_early_end):
+    vreplgr2vr.b    $vr5, a2
+
+    vslt.b          $vr5, $vr2, $vr5
+    vorn.v          $vr4, $vr4, $vr5
+    b               L(un_end)
+L(end_with_len):
+    sub.d           a6, a3, a4
+
+    bgeu            a6, a2, 1f
+    vld             $vr4, t1, 16
+1:
+    vshuf.b         $vr1, $vr4, $vr3, $vr6
+    vseq.b          $vr4, $vr0, $vr1
+
+    vmin.bu         $vr4, $vr0, $vr4
+    vreplgr2vr.b    $vr5, a2
+    vslt.b          $vr5, $vr2, $vr5
+    vorn.v          $vr4, $vr4, $vr5
+
+    b               L(un_end)
+L(ret0):
+    move            a0, zero
+    jr              ra
+END(STRNCMP)
+
+#ifdef _LIBC
+libc_hidden_builtin_def (STRNCMP)
+#endif
+
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/strncmp-unaligned.S b/sysdeps/loongarch/lp64/multiarch/strncmp-unaligned.S
new file mode 100644
index 00000000..558df29b
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/strncmp-unaligned.S
@@ -0,0 +1,257 @@
+/* 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
+*/
+
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <sys/asm.h>
+#include <sys/regdef.h>
+#endif
+
+#if IS_IN (libc)
+
+#define STRNCMP	__strncmp_unaligned
+
+#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
+    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
+
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/strncmp.c b/sysdeps/loongarch/lp64/multiarch/strncmp.c
new file mode 100644
index 00000000..80ab8c8c
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/strncmp.c
@@ -0,0 +1,35 @@
+/* Multiple versions of strncmp.
+   All versions must be listed in ifunc-impl-list.c.
+   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/>.  */
+
+/* Define multiple versions only for the definition in libc.  */
+#if IS_IN (libc)
+# define strncmp __redirect_strncmp
+# include <string.h>
+# undef strncmp
+
+# define SYMBOL_NAME strncmp
+# include "ifunc-lsx.h"
+
+libc_ifunc_redirected (__redirect_strncmp, strncmp, IFUNC_SELECTOR ());
+
+# ifdef SHARED
+__hidden_ver1 (strncmp, __GI_strncmp, __redirect_strncmp)
+  __attribute__ ((visibility ("hidden")));
+# endif
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/strnlen-aligned.S b/sysdeps/loongarch/lp64/multiarch/strnlen-aligned.S
new file mode 100644
index 00000000..503442b3
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/strnlen-aligned.S
@@ -0,0 +1,8 @@
+
+#if IS_IN (libc)
+
+#define STRNLEN __strnlen_aligned
+
+#endif
+
+#include "../strnlen.S"
diff --git a/sysdeps/loongarch/lp64/multiarch/strnlen-lasx.S b/sysdeps/loongarch/lp64/multiarch/strnlen-lasx.S
new file mode 100644
index 00000000..8c30f10c
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/strnlen-lasx.S
@@ -0,0 +1,92 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <sys/asm.h>
+#include <sys/regdef.h>
+#endif
+
+#if IS_IN (libc)
+
+#define STRNLEN	__strnlen_lasx
+
+/* size_t strnlen (const char *s1, size_t maxlen); */
+
+LEAF(STRNLEN)
+    .align          6
+    beqz            a1, L(ret0)
+    andi            t1, a0, 0x3f
+    li.d            t3, 65
+    sub.d           a2, a0, t1
+
+    xvld            $xr0, a2, 0
+    xvld            $xr1, a2, 32
+    sub.d           t1, t3, t1
+    move            a3, a0
+
+    sltu            t1, a1, t1
+    xvmsknz.b       $xr0, $xr0
+    xvmsknz.b       $xr1, $xr1
+    xvpickve.w      $xr2, $xr0, 4
+
+    xvpickve.w      $xr3, $xr1, 4
+    vilvl.h         $vr0, $vr2, $vr0
+    vilvl.h         $vr1, $vr3, $vr1
+    vilvl.w         $vr0, $vr1, $vr0
+
+
+    movfr2gr.d      t0, $f0
+    sra.d           t0, t0, a0
+    orn             t1, t1, t0
+    bnez            t1, L(end)
+
+    add.d           a4, a0, a1
+    move            a0, a2
+    addi.d          a4, a4, -1
+    bstrins.d       a4, zero, 5, 0
+
+L(loop):
+    xvld            $xr0, a0, 64
+    xvld            $xr1, a0, 96
+    addi.d          a0, a0, 64
+    beq             a0, a4, L(out)
+
+    xvmin.bu        $xr2, $xr0, $xr1
+    xvsetanyeqz.b   $fcc0, $xr2
+    bceqz           $fcc0, L(loop)
+L(out):
+    xvmsknz.b       $xr0, $xr0
+
+
+    xvmsknz.b       $xr1, $xr1
+    xvpickve.w      $xr2, $xr0, 4
+    xvpickve.w      $xr3, $xr1, 4
+    vilvl.h         $vr0, $vr2, $vr0
+
+    vilvl.h         $vr1, $vr3, $vr1
+    vilvl.w         $vr0, $vr1, $vr0
+    movfr2gr.d      t0, $f0
+L(end):
+    sub.d           a0, a0, a3
+
+    cto.d           t0, t0
+    add.d           a0, a0, t0
+    sltu            t1, a0, a1
+    masknez         t0, a1, t1
+
+    maskeqz         t1, a0, t1
+    or              a0, t0, t1
+    jr              ra
+L(ret0):
+    move            a0, zero
+
+
+    jr              ra
+END(STRNLEN)
+
+#ifdef _LIBC
+libc_hidden_def (STRNLEN)
+#endif
+
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/strnlen-lsx.S b/sysdeps/loongarch/lp64/multiarch/strnlen-lsx.S
new file mode 100644
index 00000000..388c239a
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/strnlen-lsx.S
@@ -0,0 +1,81 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <regdef.h>
+#include <sys/asm.h>
+#endif
+
+#if IS_IN (libc)
+
+#define STRNLEN	__strnlen_lsx
+
+/* size_t strnlen (const char *s1, size_t maxlen); */
+
+LEAF(STRNLEN)
+    .align          6
+    beqz            a1, L(ret0)
+    andi            t1, a0, 0x1f
+    li.d            t3, 33
+    sub.d           a2, a0, t1
+
+    vld             $vr0, a2, 0
+    vld             $vr1, a2, 16
+    sub.d           t1, t3, t1
+    move            a3, a0
+
+    sltu            t1, a1, t1
+    vmsknz.b        $vr0, $vr0
+    vmsknz.b        $vr1, $vr1
+    vilvl.h         $vr0, $vr1, $vr0
+
+    movfr2gr.s      t0, $f0
+    sra.w           t0, t0, a0
+    orn             t1, t1, t0
+    bnez            t1, L(end)
+
+
+    add.d           a4, a0, a1
+    move            a0, a2
+    addi.d          a4, a4, -1
+    bstrins.d       a4, zero, 4, 0
+
+L(loop):
+    vld             $vr0, a0, 32
+    vld             $vr1, a0, 48
+    addi.d          a0, a0, 32
+    beq             a0, a4, L(out)
+
+    vmin.bu         $vr2, $vr0, $vr1
+    vsetanyeqz.b    $fcc0, $vr2
+    bceqz           $fcc0, L(loop)
+L(out):
+    vmsknz.b        $vr0, $vr0
+
+    vmsknz.b        $vr1, $vr1
+    vilvl.h         $vr0, $vr1, $vr0
+    movfr2gr.s      t0, $f0
+L(end):
+    sub.d           a0, a0, a3
+
+
+    cto.w           t0, t0
+    add.d           a0, a0, t0
+    sltu            t1, a0, a1
+    masknez         t0, a1, t1
+
+    maskeqz         t1, a0, t1
+    or              a0, t0, t1
+    jr              ra
+L(ret0):
+    move            a0, zero
+
+    jr              ra
+END(STRNLEN)
+
+#ifdef _LIBC
+libc_hidden_builtin_def (STRNLEN)
+#endif
+
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/strnlen-unaligned.S b/sysdeps/loongarch/lp64/multiarch/strnlen-unaligned.S
new file mode 100644
index 00000000..60eccf00
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/strnlen-unaligned.S
@@ -0,0 +1,145 @@
+/* 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.  */
+
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <sys/asm.h>
+#include <sys/regdef.h>
+#endif
+
+#if IS_IN (libc)
+
+#define L_ADDIU  addi.d
+#define L_ADDU   add.d
+#define L_SUBU   sub.d
+
+#define STRNLEN	__strnlen_unaligned
+
+/* 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
+libc_hidden_builtin_def (STRNLEN)
+#endif
+#endif
+
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/strnlen.c b/sysdeps/loongarch/lp64/multiarch/strnlen.c
new file mode 100644
index 00000000..6fc406d2
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/strnlen.c
@@ -0,0 +1,40 @@
+/* Multiple versions of strnlen.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2017-2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+/* Define multiple versions only for the definition in libc.  */
+#if IS_IN (libc)
+# define strnlen __redirect_strnlen
+# define __strnlen __redirect___strnlen
+# include <string.h>
+# undef __strnlen
+# undef strnlen
+
+# define SYMBOL_NAME strnlen
+# include "ifunc-lasx.h"
+
+libc_ifunc_redirected (__redirect_strnlen, __strnlen, IFUNC_SELECTOR ());
+weak_alias (__strnlen, strnlen);
+# ifdef SHARED
+__hidden_ver1 (__strnlen, __GI___strnlen, __redirect___strnlen)
+  __attribute__((visibility ("hidden")));
+__hidden_ver1 (strnlen, __GI_strnlen, __redirect_strnlen)
+  __attribute__((weak, visibility ("hidden")));
+# endif
+#endif
+
diff --git a/sysdeps/loongarch/lp64/multiarch/strrchr-aligned.S b/sysdeps/loongarch/lp64/multiarch/strrchr-aligned.S
new file mode 100644
index 00000000..a58ddde8
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/strrchr-aligned.S
@@ -0,0 +1,12 @@
+
+#if IS_IN (libc)
+
+#define STRRCHR_NAME __strrchr_aligned
+
+#endif
+
+#include "../strrchr.S"
+
+#undef rindex
+weak_alias(STRRCHR_NAME, rindex)
+
diff --git a/sysdeps/loongarch/lp64/multiarch/strrchr-lasx.S b/sysdeps/loongarch/lp64/multiarch/strrchr-lasx.S
new file mode 100644
index 00000000..6f7a5618
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/strrchr-lasx.S
@@ -0,0 +1,113 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <sys/asm.h>
+#include <sys/regdef.h>
+#endif
+
+#if IS_IN (libc)
+
+#define STRRCHR __strrchr_lasx
+
+LEAF(STRRCHR)
+    .align          6
+    andi            t1, a0, 0x3f
+    bstrins.d       a0, zero, 5, 0
+    xvld            $xr0, a0, 0
+    xvld            $xr1, a0, 32
+
+    li.d            t2, -1
+    xvreplgr2vr.b   $xr4, a1
+    move            a2, zero
+    sll.d           t3, t2, t1
+
+    addi.d          a0, a0, 63
+    xvseq.b         $xr2, $xr0, $xr4
+    xvseq.b         $xr3, $xr1, $xr4
+    xvmsknz.b       $xr0, $xr0
+
+    xvmsknz.b       $xr1, $xr1
+    xvpickve.w      $xr5, $xr0, 4
+    xvpickve.w      $xr6, $xr1, 4
+    vilvl.h         $vr0, $vr5, $vr0
+
+
+    vilvl.h         $vr1, $vr6, $vr1
+    xvmsknz.b       $xr2, $xr2
+    xvmsknz.b       $xr3, $xr3
+    xvpickve.w      $xr5, $xr2, 4
+
+    xvpickve.w      $xr6, $xr3, 4
+    vilvl.h         $vr2, $vr5, $vr2
+    vilvl.h         $vr3, $vr6, $vr3
+    vilvl.w         $vr0, $vr1, $vr0
+
+    vilvl.w         $vr1, $vr3, $vr2
+    movfr2gr.d      t0, $f0
+    movfr2gr.d      t1, $f1
+    orn             t0, t0, t3
+
+    and             t1, t1, t3
+    bne             t0, t2, L(end)
+L(loop):
+    xvld            $xr0, a0, 1
+    xvld            $xr1, a0, 33
+
+
+    clz.d           t0, t1
+    sub.d           t0, a0, t0
+    addi.d          a0, a0, 64
+    maskeqz         t0, t0, t1
+
+    masknez         t1, a2, t1
+    or              a2, t0, t1
+    xvseq.b         $xr2, $xr0, $xr4
+    xvseq.b         $xr3, $xr1, $xr4
+
+    xvmsknz.b       $xr2, $xr2
+    xvmsknz.b       $xr3, $xr3
+    xvpickve.w      $xr5, $xr2, 4
+    xvpickve.w      $xr6, $xr3, 4
+
+    vilvl.h         $vr2, $vr5, $vr2
+    vilvl.h         $vr3, $vr6, $vr3
+    xvmin.bu        $xr5, $xr0, $xr1
+    vilvl.w         $vr2, $vr3, $vr2
+
+
+    xvsetanyeqz.b   $fcc0, $xr5
+    movfr2gr.d      t1, $f2
+    bceqz           $fcc0, L(loop)
+    xvmsknz.b       $xr0, $xr0
+
+    xvmsknz.b       $xr1, $xr1
+    xvpickve.w      $xr5, $xr0, 4
+    xvpickve.w      $xr6, $xr1, 4
+    vilvl.h         $vr0, $vr5, $vr0
+
+    vilvl.h         $vr1, $vr6, $vr1
+    vilvl.w         $vr0, $vr1, $vr0
+    movfr2gr.d      t0, $f0
+L(end):
+    slli.d          t3, t2, 1   # shift one more for the last '\0'
+
+    cto.d           t0, t0
+    sll.d           t3, t3, t0
+    andn            t1, t1, t3
+    clz.d           t0, t1
+
+    sub.d           a0, a0, t0
+    maskeqz         t0, a0, t1
+    masknez         t1, a2, t1
+    or              a0, t0, t1
+
+    jr              ra
+END(STRRCHR)
+
+#ifdef _LIBC
+libc_hidden_builtin_def(STRRCHR)
+#endif
+
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/strrchr-lsx.S b/sysdeps/loongarch/lp64/multiarch/strrchr-lsx.S
new file mode 100644
index 00000000..e9228a2e
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/strrchr-lsx.S
@@ -0,0 +1,93 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <regdef.h>
+#include <sys/asm.h>
+#endif
+
+#if IS_IN (libc)
+
+#define STRRCHR __strrchr_lsx
+
+LEAF(STRRCHR)
+    .align          6
+    andi            t1, a0, 0x1f
+    bstrins.d       a0, zero, 4, 0
+    vld             $vr0, a0, 0
+    vld             $vr1, a0, 16
+
+    vreplgr2vr.b    $vr4, a1
+    li.d            t2, -1
+    move            a2, zero
+    addi.d          a0, a0, 31
+
+    vseq.b          $vr2, $vr0, $vr4
+    vseq.b          $vr3, $vr1, $vr4
+    vmsknz.b        $vr0, $vr0
+    vmsknz.b        $vr1, $vr1
+
+    vmsknz.b        $vr2, $vr2
+    vmsknz.b        $vr3, $vr3
+    vilvl.h         $vr0, $vr1, $vr0
+    vilvl.h         $vr1, $vr3, $vr2
+
+
+    movfr2gr.s      t0, $f0
+    sll.d           t3, t2, t1
+    movfr2gr.s      t1, $f1
+    orn             t0, t0, t3
+
+    and             t1, t1, t3
+    bne             t0, t2, L(end)
+L(loop):
+    vld             $vr0, a0, 1
+    vld             $vr1, a0, 17
+
+    clz.w           t0, t1
+    sub.d           t0, a0, t0
+    addi.d          a0, a0, 32
+    maskeqz         t0, t0, t1
+
+    masknez         t1, a2, t1
+    or              a2, t0, t1
+    vseq.b          $vr2, $vr0, $vr4
+    vseq.b          $vr3, $vr1, $vr4
+
+
+    vmsknz.b        $vr2, $vr2
+    vmsknz.b        $vr3, $vr3
+    vmin.bu         $vr5, $vr0, $vr1
+    vilvl.h         $vr2, $vr3, $vr2
+
+    vsetanyeqz.b    $fcc0, $vr5
+    movfr2gr.s      t1, $f2
+    bceqz           $fcc0, L(loop)
+    vmsknz.b        $vr0, $vr0
+
+    vmsknz.b        $vr1, $vr1
+    vilvl.h         $vr0, $vr1, $vr0
+    movfr2gr.s      t0, $f0
+L(end):
+    slli.d          t3, t2, 1   # shift one more for the last '\0'
+
+    cto.w           t0, t0
+    sll.d           t3, t3, t0
+    andn            t1, t1, t3
+    clz.w           t0, t1
+
+
+    sub.d           a0, a0, t0
+    maskeqz         t0, a0, t1
+    masknez         t1, a2, t1
+    or              a0, t0, t1
+
+    jr              ra
+END(STRRCHR)
+
+#ifdef _LIBC
+libc_hidden_builtin_def(STRRCHR)
+#endif
+
+#endif
diff --git a/sysdeps/loongarch/lp64/multiarch/strrchr.c b/sysdeps/loongarch/lp64/multiarch/strrchr.c
new file mode 100644
index 00000000..32eb6ea6
--- /dev/null
+++ b/sysdeps/loongarch/lp64/multiarch/strrchr.c
@@ -0,0 +1,39 @@
+/* Multiple versions of strrchr.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2017-2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+/* Define multiple versions only for the definition in libc.  */
+#if IS_IN (libc)
+# define strrchr __redirect_strrchr
+# include <string.h>
+# undef strrchr
+
+# define SYMBOL_NAME strrchr
+# include "ifunc-memchr.h"
+
+libc_ifunc_redirected (__redirect_strrchr, __new_strrchr,
+		       IFUNC_SELECTOR ());
+weak_alias(__new_strrchr, rindex)
+# ifdef SHARED
+__hidden_ver1 (__new_strrchr, __GI_strrchr, __redirect_strrchr)
+  __attribute__ ((visibility ("hidden")));
+# endif
+
+# include <shlib-compat.h>
+versioned_symbol (libc, __new_strrchr, strrchr, GLIBC_2_27);
+#endif
diff --git a/sysdeps/loongarch/lp64/rawmemchr.S b/sysdeps/loongarch/lp64/rawmemchr.S
new file mode 100644
index 00000000..94b70f2d
--- /dev/null
+++ b/sysdeps/loongarch/lp64/rawmemchr.S
@@ -0,0 +1,114 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <sys/asm.h>
+#include <sys/regdef.h>
+#endif
+
+#ifndef RAWMEMCHR_NAME
+# define RAWMEMCHR_NAME __rawmemchr
+#endif
+
+
+LEAF(RAWMEMCHR_NAME)
+    .align      6
+    andi        t1, a0, 0x7
+    bstrins.d   a0, zero, 2, 0
+    lu12i.w     a2, 0x01010
+    bstrins.d   a1, a1, 15, 8
+
+    ld.d        t0, a0, 0
+    slli.d      t1, t1, 3
+    ori         a2, a2, 0x101
+    bstrins.d   a1, a1, 31, 16
+
+    li.w        t8, -1
+    bstrins.d   a1, a1, 63, 32
+    bstrins.d   a2, a2, 63, 32
+    sll.d       t2, t8, t1
+
+    sll.d       t3, a1, t1
+    orn         t0, t0, t2
+    slli.d      a3, a2, 7
+    beqz        a1, L(find_zero)
+
+    xor         t0, t0, t3
+    sub.d       t1, t0, a2
+    andn        t2, a3, t0
+    and         t3, t1, t2
+
+    bnez        t3, L(count_pos)
+    addi.d      a0, a0, 8
+
+L(loop):
+    ld.d        t0, a0, 0
+    xor         t0, t0, a1
+
+    sub.d       t1, t0, a2
+    andn        t2, a3, t0
+    and         t3, t1, t2
+    bnez        t3, L(count_pos)
+
+    ld.d        t0, a0, 8
+    addi.d      a0, a0, 16
+    xor         t0, t0, a1
+    sub.d       t1, t0, a2
+
+    andn        t2, a3, t0
+    and         t3, t1, t2
+    beqz        t3, L(loop)
+    addi.d      a0, a0, -8
+L(count_pos):
+    ctz.d       t0, t3
+    srli.d      t0, t0, 3
+    add.d       a0, a0, t0
+    jr          ra
+
+L(loop_7bit):
+    ld.d        t0, a0, 0
+L(find_zero):
+    sub.d       t1, t0, a2
+    and         t2, t1, a3
+    bnez        t2, L(more_check)
+
+    ld.d        t0, a0, 8
+    addi.d      a0, a0, 16
+    sub.d       t1, t0, a2
+    and         t2, t1, a3
+
+    beqz        t2, L(loop_7bit)
+    addi.d      a0, a0, -8
+
+L(more_check):
+    andn        t2, a3, t0
+    and         t3, t1, t2
+    bnez        t3, L(count_pos)
+    addi.d      a0, a0, 8
+
+L(loop_8bit):
+    ld.d        t0, a0, 0
+
+    sub.d       t1, t0, a2
+    andn        t2, a3, t0
+    and         t3, t1, t2
+    bnez        t3, L(count_pos)
+
+    ld.d        t0, a0, 8
+    addi.d      a0, a0, 16
+    sub.d       t1, t0, a2
+
+    andn        t2, a3, t0
+    and         t3, t1, t2
+    beqz        t3, L(loop_8bit)
+
+    addi.d      a0, a0, -8
+    b           L(count_pos)
+
+END(RAWMEMCHR_NAME)
+
+#ifdef _LIBC
+weak_alias (__rawmemchr, rawmemchr)
+libc_hidden_builtin_def (__rawmemchr)
+#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/stpcpy.S b/sysdeps/loongarch/lp64/stpcpy.S
new file mode 100644
index 00000000..9d4b0c8d
--- /dev/null
+++ b/sysdeps/loongarch/lp64/stpcpy.S
@@ -0,0 +1,180 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <sys/asm.h>
+#include <sys/regdef.h>
+#endif
+
+#ifndef STPCPY_NAME
+#define STPCPY_NAME __stpcpy
+#endif
+
+LEAF(STPCPY_NAME)
+    .align      6
+    andi        a3, a0, 0x7
+    beqz        a3, L(dest_align)
+    sub.d       a5, a1, a3
+    addi.d      a5, a5, 8
+
+L(make_dest_align):
+    ld.b        t0, a1, 0
+    addi.d      a1, a1, 1
+    st.b        t0, a0, 0
+    addi.d      a0, a0, 1
+
+    beqz        t0, L(al_out)
+    bne         a1, a5, L(make_dest_align)
+
+L(dest_align):
+    andi        a4, a1, 7
+    bstrins.d   a1, zero, 2, 0
+
+    lu12i.w     t5, 0x1010
+    ld.d        t0, a1, 0
+    ori         t5, t5, 0x101
+    bstrins.d   t5, t5, 63, 32
+
+    slli.d      t6, t5, 0x7
+    bnez        a4, L(unalign)
+    sub.d       t1, t0, t5
+    andn        t2, t6, t0
+
+    and         t3, t1, t2
+    bnez        t3, L(al_end)
+
+L(al_loop):
+    st.d        t0, a0, 0
+    ld.d        t0, a1, 8
+
+    addi.d      a1, a1, 8
+    addi.d      a0, a0, 8
+    sub.d       t1, t0, t5
+    andn        t2, t6, t0
+
+    and         t3, t1, t2
+    beqz        t3, L(al_loop)
+
+L(al_end):
+    ctz.d       t1, t3
+    srli.d      t1, t1, 3
+    addi.d      t1, t1, 1 # add 1, since '\0' needs to be copied to dest
+
+    andi        a3, t1, 8
+    andi        a4, t1, 4
+    andi        a5, t1, 2
+    andi        a6, t1, 1
+
+L(al_end_8):
+    beqz        a3, L(al_end_4)
+    st.d        t0, a0, 0
+    addi.d      a0, a0, 7
+    jr          ra
+L(al_end_4):
+    beqz        a4, L(al_end_2)
+    st.w        t0, a0, 0
+    addi.d      a0, a0, 4
+    srli.d      t0, t0, 32
+L(al_end_2):
+    beqz        a5, L(al_end_1)
+    st.h        t0, a0, 0
+    addi.d      a0, a0, 2
+    srli.d      t0, t0, 16
+L(al_end_1):
+    beqz        a6, L(al_out)
+    st.b        t0, a0, 0
+    addi.d      a0, a0, 1
+L(al_out):
+    addi.d      a0, a0, -1
+    jr          ra
+
+L(unalign):
+    slli.d      a5, a4, 3
+    li.d        t1, -1
+    sub.d       a6, zero, a5
+
+    srl.d       a7, t0, a5
+    sll.d       t7, t1, a6
+
+    or          t0, a7, t7
+    sub.d       t1, t0, t5
+    andn        t2, t6, t0
+    and         t3, t1, t2
+
+    bnez        t3, L(un_end)
+
+    ld.d        t4, a1, 8
+    addi.d      a1, a1, 8
+
+    sub.d       t1, t4, t5
+    andn        t2, t6, t4
+    sll.d       t0, t4, a6
+    and         t3, t1, t2
+
+    or          t0, t0, a7
+    bnez        t3, L(un_end_with_remaining)
+
+L(un_loop):
+    srl.d       a7, t4, a5
+
+    ld.d        t4, a1, 8
+    addi.d      a1, a1, 8
+
+    st.d        t0, a0, 0
+    addi.d      a0, a0, 8
+
+    sub.d       t1, t4, t5
+    andn        t2, t6, t4
+    sll.d       t0, t4, a6
+    and         t3, t1, t2
+
+    or          t0, t0, a7
+    beqz        t3, L(un_loop)
+
+L(un_end_with_remaining):
+    ctz.d       t1, t3
+    srli.d      t1, t1, 3
+    addi.d      t1, t1, 1
+    sub.d       t1, t1, a4
+
+    blt         t1, zero, L(un_end_less_8)
+    st.d        t0, a0, 0
+    addi.d      a0, a0, 8
+    beqz        t1, L(un_out)
+    srl.d       t0, t4, a5  # get the remaining part
+    b           L(un_end_less_8)
+
+L(un_end):
+    ctz.d       t1, t3
+    srli.d      t1, t1, 3
+    addi.d      t1, t1, 1
+
+L(un_end_less_8):
+    andi        a4, t1, 4
+    andi        a5, t1, 2
+    andi        a6, t1, 1
+L(un_end_4):
+    beqz        a4, L(un_end_2)
+    st.w        t0, a0, 0
+    addi.d      a0, a0, 4
+    srli.d      t0, t0, 32
+L(un_end_2):
+    beqz        a5, L(un_end_1)
+    st.h        t0, a0, 0
+    addi.d      a0, a0, 2
+    srli.d      t0, t0, 16
+L(un_end_1):
+    beqz        a6, L(un_out)
+    st.b        t0, a0, 0
+    addi.d      a0, a0, 1
+L(un_out):
+    addi.d      a0, a0, -1
+    jr          ra
+
+END(STPCPY_NAME)
+
+#ifdef _LIBC
+weak_alias (STPCPY_NAME, stpcpy)
+libc_hidden_builtin_def (STPCPY_NAME)
+#endif
diff --git a/sysdeps/loongarch/lp64/strchr.S b/sysdeps/loongarch/lp64/strchr.S
new file mode 100644
index 00000000..63454c17
--- /dev/null
+++ b/sysdeps/loongarch/lp64/strchr.S
@@ -0,0 +1,90 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <sys/asm.h>
+#include <sys/regdef.h>
+#endif
+
+#ifndef STRCHR_NAME
+#define STRCHR_NAME strchr
+#endif
+
+/* char * strchr (const char *s1, int c); */
+
+LEAF(STRCHR_NAME)
+	.align		6
+	slli.d		t1, a0, 3
+	bstrins.d	a0, zero, 2, 0
+	lu12i.w		a2, 0x01010
+	ld.d		t2, a0, 0
+
+	ori		a2, a2, 0x101
+	andi		a1, a1, 0xff
+	bstrins.d	a2, a2, 63, 32
+	li.w		t0, -1
+
+	mul.d           a1, a1, a2 # "cccccccc"
+	sll.d		t0, t0, t1
+	slli.d		a3, a2, 7  # 0x8080808080808080
+	orn             t2, t2, t0
+
+	sll.d           t3, a1, t1
+	xor             t4, t2, t3
+	sub.d           a7, t2, a2
+	andn            a6, a3, t2
+
+
+	sub.d           a5, t4, a2
+	andn            a4, a3, t4
+	and		a6, a7, a6
+	and		a5, a5, a4
+
+	or		t0, a6, a5
+	bnez		t0, L(_mc8_a)
+	addi.d		a0, a0, 8
+L(_aloop):
+	ld.d		t4, a0, 0
+
+	xor		t2, t4, a1
+	sub.d		a7, t4, a2
+	andn		a6, a3, t4
+	sub.d		a5, t2, a2
+
+	andn		a4, a3, t2
+	and		a6, a7, a6
+	and		a5, a5, a4
+	or		a7, a6, a5
+
+
+	bnez		a7, L(_mc8_a)
+	ld.d		t4, a0, 8
+	addi.d		a0, a0, 16
+	xor		t2, t4, a1
+
+	sub.d		a7, t4, a2
+	andn		a6, a3, t4
+	sub.d		a5, t2, a2
+	andn		a4, a3, t2
+
+	and		a6, a7, a6
+	and		a5, a5, a4
+	or		a7, a6, a5
+	beqz		a7, L(_aloop)
+
+	addi.d		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
+	add.d		a0, a0, t0
+	masknez		a0, a0, t1
+
+	jr		ra
+END(STRCHR_NAME)
diff --git a/sysdeps/loongarch/lp64/strchrnul.S b/sysdeps/loongarch/lp64/strchrnul.S
new file mode 100644
index 00000000..c4532e11
--- /dev/null
+++ b/sysdeps/loongarch/lp64/strchrnul.S
@@ -0,0 +1,95 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <sys/asm.h>
+#include <sys/regdef.h>
+#endif
+
+#ifndef STRCHRNUL_NAME
+#define STRCHRNUL_NAME __strchrnul
+#endif
+
+/* char * strchrnul (const char *s1, int c); */
+
+LEAF(STRCHRNUL_NAME)
+	.align		6
+	slli.d		t1, a0, 3
+	bstrins.d	a0, zero, 2, 0
+	lu12i.w		a2, 0x01010
+	ld.d		t2, a0, 0
+
+	ori		a2, a2, 0x101
+	andi		a1, a1, 0xff
+	bstrins.d	a2, a2, 63, 32
+	li.w		t0, -1
+
+	mul.d           a1, a1, a2 # "cccccccc"
+	sll.d		t0, t0, t1
+	slli.d		a3, a2, 7  # 0x8080808080808080
+	orn             t2, t2, t0
+
+	sll.d           t3, a1, t1
+	xor             t4, t2, t3
+	sub.d           a7, t2, a2
+	andn            a6, a3, t2
+
+
+	sub.d           a5, t4, a2
+	andn            a4, a3, t4
+	and		a6, a7, a6
+	and		a5, a5, a4
+
+	or		t0, a6, a5
+	bnez		t0, L(_mc8_a)
+	addi.d		a0, a0, 8
+L(_aloop):
+	ld.d		t4, a0, 0
+
+	xor		t2, t4, a1
+	sub.d		a7, t4, a2
+	andn		a6, a3, t4
+	sub.d		a5, t2, a2
+
+	andn		a4, a3, t2
+	and		a6, a7, a6
+	and		a5, a5, a4
+	or		a7, a6, a5
+
+
+	bnez		a7, L(_mc8_a)
+	ld.d		t4, a0, 8
+	addi.d		a0, a0, 16
+	xor		t2, t4, a1
+
+	sub.d		a7, t4, a2
+	andn		a6, a3, t4
+	sub.d		a5, t2, a2
+	andn		a4, a3, t2
+
+	and		a6, a7, a6
+	and		a5, a5, a4
+	or		a7, a6, a5
+	beqz		a7, L(_aloop)
+
+	addi.d		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
+	masknez		t3, t2, t1
+	maskeqz		t4, t0, t1
+
+	or		t0, t3, t4
+	add.d		a0, a0, t0
+	jr		ra
+END(STRCHRNUL_NAME)
+
+#ifdef _LIBC
+weak_alias(STRCHRNUL_NAME, strchrnul)
+libc_hidden_builtin_def (STRCHRNUL_NAME)
+#endif
diff --git a/sysdeps/loongarch/lp64/strcmp.S b/sysdeps/loongarch/lp64/strcmp.S
new file mode 100644
index 00000000..22c261a3
--- /dev/null
+++ b/sysdeps/loongarch/lp64/strcmp.S
@@ -0,0 +1,228 @@
+/* 2022\06\15  loongarch64 author: chenxiaolong.  */
+
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <sys/asm.h>
+#include <sys/regdef.h>
+#endif
+
+#ifndef STRCMP_NAME
+#define STRCMP_NAME strcmp
+#endif
+
+/* int strcmp (const char *s1, const char *s2); */
+
+/* Parameters and Results */
+#define src1	a0
+#define	src2	a1
+#define result	v0
+LEAF(STRCMP_NAME)
+    .align	6
+    xor         a4, src1, src2
+    lu12i.w     t5, 0x01010
+    lu12i.w     t6, 0x7f7f7
+    andi        a2, src1, 0x7
+
+    ori         t5, t5, 0x101
+    andi        a4, a4, 0x7
+    ori         t6, t6, 0xf7f
+    bstrins.d   t5, t5, 63, 32
+    bstrins.d   t6, t6, 63, 32
+
+    bnez        a4, 3f  // unaligned
+    beqz        a2, 1f  // loop aligned
+
+// mutual aligned
+    bstrins.d   src1, zero, 2, 0
+    bstrins.d   src2, zero, 2, 0
+    slli.d      a4, a2, 0x3
+    ld.d        t0, src1, 0
+
+    sub.d       a4, zero, a4
+    ld.d        t1, src2, 0
+    addi.d      src1, src1, 8
+    addi.d      src2, src2, 8
+
+    nor         a5, zero, zero
+    srl.d       a5, a5, a4
+    or          t0, t0, a5
+
+    or          t1, t1, a5
+    b           2f  //start realigned
+
+// loop aligned
+1:
+    ld.d        t0, src1, 0
+    addi.d      src1, src1, 8
+    ld.d        t1, src2, 0
+    addi.d      src2, src2, 8
+
+// start realigned:
+2:
+    sub.d       t2, t0, t5
+    nor         t3, t0, t6
+    and         t2, t2, t3
+
+    xor         t3, t0, t1
+    or          t2, t2, t3
+    beqz        t2, 1b
+
+    ctz.d       t7, t2
+    bstrins.d   t7, zero, 2, 0
+    srl.d       t0, t0, t7
+    srl.d       t1, t1, t7
+
+    andi        t0, t0, 0xff
+    andi        t1, t1, 0xff
+    sub.d       v0, t0, t1
+    jr          ra
+
+// unaligned
+3:
+    andi        a3, src2, 0x7
+    slt         a5, a2, a3
+    masknez     t8, a2, a5
+    xor         a6, src1, src2
+    maskeqz     a6, a6, t8
+    xor         src1, src1, a6
+    xor         src2, src2, a6
+
+    andi        a2, src1, 0x7
+    beqz        a2, 4f // src1 is aligned
+
+//strcmp_unaligned:
+    andi        a3, src2, 0x7
+    bstrins.d   src1, zero, 2, 0
+    bstrins.d   src2, zero, 2, 0
+    nor         t3, zero, zero
+
+    ld.d        t0, src1, 0
+    ld.d        t1, src2, 0
+    sub.d       a2, a3, a2
+    addi.d      t2, zero, 8
+
+    sub.d       a5, t2, a2
+    sub.d       a6, t2, a3
+    slli.d      a5, a5, 0x3
+    slli.d      a6, a6, 0x3
+
+    srl.d       t4, t3, a6
+    srl.d       a4, t3, a5
+    rotr.d      a7, t0, a5
+
+    addi.d      src2, src2, 8
+    addi.d      src1, src1, 8
+    or          t1, t1, t4
+    or          t0, a7, t4
+
+    sub.d       t2, t0, t5
+    nor         t3, t0, t6
+    and         t2, t2, t3
+    xor         t3, t0, t1
+    or          t2, t2, t3
+    bnez        t2, 7f
+
+    and         a7, a7, a4
+    slli.d      a6, a2, 0x3
+    nor         a4, zero, a4
+    b           5f
+
+// src1 is aligned
+4:
+    andi        a3, src2, 0x7
+    ld.d        t0, src1, 0
+
+    bstrins.d   src2, zero, 2, 0
+    nor         t2, zero, zero
+    ld.d        t1, src2, 0
+
+    addi.d      t3, zero, 0x8
+    sub.d       a5, t3, a3
+    slli.d      a5, a5, 0x3
+    srl.d       a4, t2, a5
+    rotr.d      t4, t0, a5
+
+    addi.d      src2, src2, 8
+    addi.d      src1, src1, 8
+    or          t1, t1, a4
+    or          t0, t4, a4
+
+    sub.d       t2, t0, t5
+    nor         t3, t0, t6
+    and         t2, t2, t3
+    xor         t3, t0, t1
+    or          t2, t2, t3
+
+    bnez        t2, 7f
+
+    and         a7, t4, a4
+    slli.d      a6, a3, 0x3
+    nor         a4, zero, a4
+
+// unaligned loop
+// a7: remaining number
+// a6: shift left number
+// a5: shift right number
+// a4: mask for checking remaining number
+5:
+    or          t0, a7, a4
+    sub.d       t2, t0, t5
+    nor         t3, t0, t6
+    and         t2, t2, t3
+    bnez        t2, 6f
+
+    ld.d        t0, src1, 0
+    addi.d      src1, src1, 8
+    ld.d        t1, src2, 0
+    addi.d      src2, src2, 8
+
+    srl.d       t7, t0, a5
+    sll.d       t0, t0, a6
+    or          t0, a7, t0
+
+    sub.d       t2, t0, t5
+    nor         t3, t0, t6
+    and         t2, t2, t3
+    xor         t3, t0, t1
+    or          t2, t2, t3
+    bnez        t2, 7f
+
+    or          a7, t7, zero
+    b           5b
+
+6:
+    ld.bu       t1, src2, 0
+    andi        t0, a7, 0xff
+    xor         t2, t0, t1
+    srli.d      a7, a7, 0x8
+    masknez     t2, t0, t2
+    addi.d      src2, src2, 1
+    beqz        t2, 8f
+    b           6b
+
+7:
+    ctz.d       t7, t2
+    bstrins.d   t7, zero, 2, 0
+    srl.d       t0, t0, t7
+    srl.d       t1, t1, t7
+
+    andi        t0, t0, 0xff
+    andi        t1, t1, 0xff
+
+8:
+    sub.d       a4, t0, t1
+    sub.d       a5, t1, t0
+    maskeqz     a6, a5, t8
+    masknez     result, a4, t8
+    or          result, result, a6
+    jr	ra
+
+END(STRCMP_NAME)
+
+#ifdef _LIBC
+libc_hidden_builtin_def (STRCMP_NAME)
+#endif
+
diff --git a/sysdeps/loongarch/lp64/strcpy.S b/sysdeps/loongarch/lp64/strcpy.S
new file mode 100644
index 00000000..c6fe74cb
--- /dev/null
+++ b/sysdeps/loongarch/lp64/strcpy.S
@@ -0,0 +1,174 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <sys/asm.h>
+#include <sys/regdef.h>
+#endif
+
+#ifndef STRCPY
+#define STRCPY  strcpy
+#endif
+
+LEAF(STRCPY)
+    .align      6
+    andi        a3, a0, 0x7
+    move        a2, a0
+    beqz        a3, L(dest_align)
+    sub.d       a5, a1, a3
+    addi.d      a5, a5, 8
+
+L(make_dest_align):
+    ld.b        t0, a1, 0
+    addi.d      a1, a1, 1
+    st.b        t0, a2, 0
+    beqz        t0, L(al_out)
+
+    addi.d      a2, a2, 1
+    bne         a1, a5, L(make_dest_align)
+
+L(dest_align):
+    andi        a4, a1, 7
+    bstrins.d   a1, zero, 2, 0
+
+    lu12i.w     t5, 0x1010
+    ld.d        t0, a1, 0
+    ori         t5, t5, 0x101
+    bstrins.d   t5, t5, 63, 32
+
+    slli.d      t6, t5, 0x7
+    bnez        a4, L(unalign)
+    sub.d       t1, t0, t5
+    andn        t2, t6, t0
+
+    and         t3, t1, t2
+    bnez        t3, L(al_end)
+
+L(al_loop):
+    st.d        t0, a2, 0
+    ld.d        t0, a1, 8
+
+    addi.d      a1, a1, 8
+    addi.d      a2, a2, 8
+    sub.d       t1, t0, t5
+    andn        t2, t6, t0
+
+    and         t3, t1, t2
+    beqz        t3, L(al_loop)
+
+L(al_end):
+    ctz.d       t1, t3
+    srli.d      t1, t1, 3
+    addi.d      t1, t1, 1 # add 1, since '\0' needs to be copied to dest
+
+    andi        a3, t1, 8
+    andi        a4, t1, 4
+    andi        a5, t1, 2
+    andi        a6, t1, 1
+
+L(al_end_8):
+    beqz        a3, L(al_end_4)
+    st.d        t0, a2, 0
+    jr          ra
+L(al_end_4):
+    beqz        a4, L(al_end_2)
+    st.w        t0, a2, 0
+    addi.d      a2, a2, 4
+    srli.d      t0, t0, 32
+L(al_end_2):
+    beqz        a5, L(al_end_1)
+    st.h        t0, a2, 0
+    addi.d      a2, a2, 2
+    srli.d      t0, t0, 16
+L(al_end_1):
+    beqz        a6, L(al_out)
+    st.b        t0, a2, 0
+L(al_out):
+    jr          ra
+
+L(unalign):
+    slli.d      a5, a4, 3
+    li.d        t1, -1
+    sub.d       a6, zero, a5
+
+    srl.d       a7, t0, a5
+    sll.d       t7, t1, a6
+
+    or          t0, a7, t7
+    sub.d       t1, t0, t5
+    andn        t2, t6, t0
+    and         t3, t1, t2
+
+    bnez        t3, L(un_end)
+
+    ld.d        t4, a1, 8
+
+    sub.d       t1, t4, t5
+    andn        t2, t6, t4
+    sll.d       t0, t4, a6
+    and         t3, t1, t2
+
+    or          t0, t0, a7
+    bnez        t3, L(un_end_with_remaining)
+
+L(un_loop):
+    srl.d       a7, t4, a5
+
+    ld.d        t4, a1, 16
+    addi.d      a1, a1, 8
+
+    st.d        t0, a2, 0
+    addi.d      a2, a2, 8
+
+    sub.d       t1, t4, t5
+    andn        t2, t6, t4
+    sll.d       t0, t4, a6
+    and         t3, t1, t2
+
+    or          t0, t0, a7
+    beqz        t3, L(un_loop)
+
+L(un_end_with_remaining):
+    ctz.d       t1, t3
+    srli.d      t1, t1, 3
+    addi.d      t1, t1, 1
+    sub.d       t1, t1, a4
+
+    blt         t1, zero, L(un_end_less_8)
+    st.d        t0, a2, 0
+    addi.d      a2, a2, 8
+    beqz        t1, L(un_out)
+    srl.d       t0, t4, a5  # get the remaining part
+    b           L(un_end_less_8)
+
+L(un_end):
+    ctz.d       t1, t3
+    srli.d      t1, t1, 3
+    addi.d      t1, t1, 1
+
+L(un_end_less_8):
+    andi        a4, t1, 4
+    andi        a5, t1, 2
+    andi        a6, t1, 1
+L(un_end_4):
+    beqz        a4, L(un_end_2)
+    st.w        t0, a2, 0
+    addi.d      a2, a2, 4
+    srli.d      t0, t0, 32
+L(un_end_2):
+    beqz        a5, L(un_end_1)
+    st.h        t0, a2, 0
+    addi.d      a2, a2, 2
+    srli.d      t0, t0, 16
+L(un_end_1):
+    beqz        a6, L(un_out)
+    st.b        t0, a2, 0
+L(un_out):
+    jr          ra
+
+END(STRCPY)
+
+#ifdef _LIBC
+libc_hidden_builtin_def (STRCPY)
+#endif
diff --git a/sysdeps/loongarch/lp64/strlen.S b/sysdeps/loongarch/lp64/strlen.S
new file mode 100644
index 00000000..dd5a8da3
--- /dev/null
+++ b/sysdeps/loongarch/lp64/strlen.S
@@ -0,0 +1,86 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <sys/asm.h>
+#include <sys/regdef.h>
+#endif
+
+#ifndef STRLEN
+#define STRLEN	strlen
+#endif
+
+LEAF(STRLEN)
+	.align 6
+	move		a1, a0
+	bstrins.d	a0, zero, 2, 0
+	lu12i.w		a2, 0x01010
+	li.w		t0, -1
+
+	ld.d		t2, a0, 0
+	andi		t1, a1, 0x7
+	ori		a2, a2, 0x101
+	slli.d		t1, t1, 3
+
+	bstrins.d	a2, a2, 63, 32
+	sll.d		t1, t0, t1
+	slli.d		t3, a2, 7
+	nor		a3, zero, t3
+
+	orn		t2, t2, t1
+	sub.d		t0, t2, a2
+	nor		t1, t2, a3
+	and		t0, t0, t1
+
+
+	bnez		t0, L(count_pos)
+	addi.d          a0, a0, 8
+L(loop_16_7bit):
+	ld.d		t2, a0, 0
+	sub.d		t1, t2, a2
+
+	and 		t0, t1, t3
+	bnez		t0, L(more_check)
+	ld.d		t2, a0, 8
+	addi.d      	a0, a0, 16
+
+	sub.d		t1, t2, a2
+	and 		t0, t1, t3
+	beqz        	t0, L(loop_16_7bit)
+	addi.d          a0, a0, -8
+L(more_check):
+	nor		t0, t2, a3
+
+	and		t0, t1, t0
+	bnez		t0, L(count_pos)
+	addi.d          a0, a0, 8
+L(loop_16_8bit):
+	ld.d		t2, a0, 0
+
+	sub.d		t1, t2, a2
+	nor		t0, t2, a3
+	and		t0, t0, t1
+	bnez		t0, L(count_pos)
+
+	ld.d		t2, a0, 8
+	addi.d      	a0, a0, 16
+	sub.d		t1, t2, a2
+	nor		t0, t2, a3
+
+	and		t0, t0, t1
+	beqz		t0, L(loop_16_8bit)
+	addi.d          a0, a0, -8
+L(count_pos):
+	ctz.d		t1, t0
+	sub.d		a0, a0, a1
+
+	srli.d		t1, t1, 3
+	add.d		a0, a0, t1
+	jr		ra
+
+END(STRLEN)
+
+#ifdef _LIBC
+libc_hidden_builtin_def (STRLEN)
+#endif
diff --git a/sysdeps/loongarch/lp64/strncmp.S b/sysdeps/loongarch/lp64/strncmp.S
new file mode 100644
index 00000000..dcb15350
--- /dev/null
+++ b/sysdeps/loongarch/lp64/strncmp.S
@@ -0,0 +1,257 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <sys/asm.h>
+#include <sys/regdef.h>
+#endif
+
+#ifndef STRNCMP
+#define STRNCMP strncmp
+#endif
+
+/* int strncmp (const char *s1, const char *s2); */
+
+LEAF(STRNCMP)
+    .align      6
+    beqz        a2, L(ret0)
+    xor         a4, a0, a1
+    lu12i.w     t5, 0x01010
+    lu12i.w     t6, 0x7f7f7
+
+    andi        a3, a0, 0x7
+    ori         t5, t5, 0x101
+    andi        a4, a4, 0x7
+    ori         t6, t6, 0xf7f
+
+    bstrins.d   t5, t5, 63, 32
+    bstrins.d   t6, t6, 63, 32
+
+    bnez        a4, L(unalign)
+    bnez        a3, L(mutual_align)
+
+L(a_loop):
+    ld.d        t0, a0, 0
+    ld.d        t1, a1, 0
+    addi.d      a0, a0, 8
+    addi.d      a1, a1, 8
+
+
+    sltui       t7, a2, 9
+
+L(start_realign):
+    sub.d       t2, t0, t5
+    nor         t3, t0, t6
+    xor         t4, t0, t1
+
+    and         t2, t2, t3
+    addi.d      a2, a2, -8
+
+    or          t2, t2, t4
+    or          t3, t2, t7
+    beqz        t3, L(a_loop)
+
+L(end):
+    bge         zero, t7, L(out)
+    andi        t4, a2, 7
+    li.d        t3, -1
+    addi.d      t4, t4, -1
+    slli.d      t4, t4, 3
+    sll.d       t3, t3, t4
+    or          t2, t2, t3
+
+
+L(out):
+    ctz.d       t3, t2
+    bstrins.d   t3, zero, 2, 0
+    srl.d       t0, t0, t3
+    srl.d       t1, t1, t3
+
+    andi        t0, t0, 0xff
+    andi        t1, t1, 0xff
+    sub.d       a0, t0, t1
+    jr          ra
+
+L(mutual_align):
+    bstrins.d   a0, zero, 2, 0
+    bstrins.d   a1, zero, 2, 0
+    slli.d      a5, a3, 0x3
+    li.d        t2, -1
+
+    ld.d        t0, a0, 0
+    ld.d        t1, a1, 0
+
+    li.d        t3, 9
+    sll.d       t2, t2, a5
+
+    sub.d       t3, t3, a3
+    addi.d      a0, a0, 8
+
+    sltu        t7, a2, t3
+    addi.d      a1, a1, 8
+
+    add.d       a2, a2, a3
+    orn         t0, t0, t2
+    orn         t1, t1, t2
+    b           L(start_realign)
+
+L(ret0):
+    move        a0, zero
+    jr          ra
+
+L(unalign):
+    li.d        t8, 8
+    blt         a2, t8, L(short_cmp)
+
+    # swap a0 and a1 in case a3 > a4
+    andi        a4, a1, 0x7
+    sltu        t8, a4, a3
+    xor         a6, a0, a1
+    maskeqz     a6, a6, t8
+    xor         a0, a0, a6
+    xor         a1, a1, a6
+
+    andi        a3, a0, 0x7
+    andi        a4, a1, 0x7
+
+    bstrins.d   a0, zero, 2, 0
+    bstrins.d   a1, zero, 2, 0
+
+    li.d        t2, -1
+    li.d        t3, 9
+
+    ld.d        t0, a0, 0
+    ld.d        t1, a1, 0
+
+    sub.d       t3, t3, a4
+    sub.d       a3, a4, a3
+
+    slli.d      t4, a4, 3
+    slli.d      a6, a3, 3
+
+    sub.d       a5, zero, a6
+    sltu        t7, a2, t3
+
+    rotr.d      a7, t0, a5
+    sll.d       t4, t2, t4 # mask for first num
+
+    add.d       a2, a2, a4
+    sll.d       a4, t2, a6 # mask for a7
+
+    orn         t0, a7, t4
+    orn         t1, t1, t4
+
+    sub.d       t2, t0, t5
+    nor         t4, t0, t6
+    and         t2, t2, t4
+
+    xor         t3, t0, t1
+    or          t2, t2, t3
+
+    or          t3, t2, t7
+    bnez        t3, L(un_end)
+
+    andn        a7, a7, a4
+    addi.d      a3, a3, 1
+
+L(un_loop):
+    addi.d      a2, a2, -8
+    # in case remaining part has '\0', no more load instructions should be executed on a0 address
+    or          t0, a7, a4
+    sltu        t7, a2, a3
+
+    sub.d       t2, t0, t5
+    nor         t3, t0, t6
+    and         t2, t2, t3
+
+    or          t3, t2, t7
+    bnez        t3, L(check_remaining)
+
+    ld.d        t7, a0, 8
+    ld.d        t1, a1, 8
+    addi.d      a0, a0, 8
+    addi.d      a1, a1, 8
+
+    sll.d       t4, t7, a6
+    sub.d       t2, t1, t5
+    nor         t3, t1, t6
+
+    or          t0, t4, a7
+    srl.d       a7, t7, a5
+
+    and         t2, t2, t3
+    xor         t3, t0, t1
+
+    sltui       t7, a2, 9
+    or          t2, t2, t3
+
+    or          t3, t2, t7
+    beqz        t3, L(un_loop)
+    b           L(un_end)
+
+L(check_remaining):
+    ld.d        t1, a1, 8
+    xor         t3, t1, a7
+    or          t2, t2, t3
+
+L(un_end):
+    bge         zero, t7, L(un_out)
+    andi        t4, a2, 7
+    li.d        t3, -1
+
+    addi.d      t4, t4, -1
+    slli.d      t4, t4, 3
+    sll.d       t3, t3, t4
+    or          t2, t2, t3
+
+L(un_out):
+    ctz.d       t3, t2
+    bstrins.d   t3, zero, 2, 0
+    srl.d       t0, t0, t3
+    srl.d       t1, t1, t3
+
+    andi        t0, t0, 0xff
+    andi        t1, t1, 0xff
+
+    sub.d       a4, t0, t1
+    sub.d       a5, t1, t0
+
+    maskeqz     a6, a5, t8
+    masknez     a0, a4, t8
+
+    or          a0, a0, a6
+    jr          ra
+
+L(short_cmp):
+    ld.bu       t0, a0, 0
+    ld.bu       t1, a1, 0
+    addi.d      a2, a2, -1
+
+    xor         t2, t0, t1
+    masknez     t2, t0, t2
+    maskeqz     t2, a2, t2
+
+    beqz        t2, L(short_out)
+
+    ld.bu       t0, a0, 1
+    ld.bu       t1, a1, 1
+
+    addi.d      a2, a2, -1
+    addi.d      a0, a0, 2
+
+    addi.d      a1, a1, 2
+    xor         t2, t0, t1
+    masknez     t2, t0, t2
+    maskeqz     t2, a2, t2
+
+    bnez        t2, L(short_cmp)
+
+L(short_out):
+    sub.d       a0, t0, t1
+    jr ra
+
+END(STRNCMP)
+#ifdef _LIBC
+libc_hidden_builtin_def (STRNCMP)
+#endif
diff --git a/sysdeps/loongarch/lp64/strnlen.S b/sysdeps/loongarch/lp64/strnlen.S
new file mode 100644
index 00000000..0517e206
--- /dev/null
+++ b/sysdeps/loongarch/lp64/strnlen.S
@@ -0,0 +1,83 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <sys/asm.h>
+#include <sys/regdef.h>
+#endif
+
+#ifndef STRNLEN
+#define STRNLEN	__strnlen
+#endif
+
+#. before every load, a1(t5) must > 0;
+#. first load with t1 != 0, need to adjust t5;
+#. return the less one of both strlen(s) and a1;
+
+LEAF(STRNLEN)
+	.align 6
+	beqz		a1, L(out)
+	lu12i.w		a2, 0x01010
+	andi		t1, a0, 0x7
+	move		t4, a0
+
+	bstrins.d	a0, zero, 2, 0
+	ori		a2, a2, 0x101
+	li.w		t0, -1
+	ld.d		t2, a0, 0
+
+	slli.d		t3, t1, 3
+	bstrins.d	a2, a2, 63, 32
+	li.w		t5, 8
+	slli.d		a3, a2, 7
+
+	sub.w		t1, t5, t1
+	sll.d		t0, t0, t3
+	nor		a3, zero, a3
+	orn		t2, t2, t0
+
+
+	sub.d		t0, t2, a2
+	nor		t3, t2, a3
+	and		t0, t0, t3
+	bnez		t0, L(count_pos)
+
+	sub.d		t5, a1, t1
+	bgeu		t1, a1, L(out)
+L(loop_8bytes):
+	ld.d		t2, a0, 8
+	addi.d		a0, a0, 8
+
+	sub.d		t0, t2, a2
+	nor 		t1, t2, a3
+	sltui		t6, t5, 9
+	and 		t0, t0, t1
+
+	addi.d		t5, t5, -8
+	or		t7, t0, t6
+	beqz		t7, L(loop_8bytes)
+L(count_pos):
+	ctz.d		t1, t0
+
+
+	sub.d		a0, a0, t4
+	srli.d		t1, t1, 3
+	add.d		a0, t1, a0
+	sltu		t0, a0, a1
+
+	masknez		t1, a1, t0
+	maskeqz		a0, a0, t0
+	or		a0, a0, t1
+	jr		ra
+
+L(out):
+	move		a0, a1
+	jr		ra
+
+END(STRNLEN)
+
+#ifdef _LIBC
+weak_alias (STRNLEN, strnlen)
+libc_hidden_builtin_def (STRNLEN)
+#endif
diff --git a/sysdeps/loongarch/lp64/strrchr.S b/sysdeps/loongarch/lp64/strrchr.S
new file mode 100644
index 00000000..3bf92ecd
--- /dev/null
+++ b/sysdeps/loongarch/lp64/strrchr.S
@@ -0,0 +1,106 @@
+#ifdef _LIBC
+#include <sysdep.h>
+#include <sys/regdef.h>
+#include <sys/asm.h>
+#else
+#include <sys/asm.h>
+#include <sys/regdef.h>
+#endif
+
+#ifndef STRRCHR_NAME
+#define STRRCHR_NAME strrchr
+#endif
+
+LEAF(STRRCHR_NAME)
+	.align 6
+	slli.d		t1, a0, 3
+	bstrins.d	a0, zero, 2, 0
+	lu12i.w		a2, 0x01010
+	ld.d		t2, a0, 0       // t2 = "5ZZ21abc"
+
+	ori		a2, a2, 0x101
+	andi		a1, a1, 0xff	// a1 = "0000000Z"
+	li.d		a5, -1
+	bstrins.d	a2, a2, 63, 32	// a2 = 0x0101010101010101
+
+	sll.d		t1, a5, t1	// t1 = 0xffffffffff000000
+	mul.d		a1, a1, a2	// a1 = "ZZZZZZZZ"
+	orn		t2, t2, t1	// t2 = "5ZZ21YYY"
+	slli.d		a3, a2, 7	// a3 = 0x8080808080808080
+
+	sub.d		a4, t2, a2
+	andn		t0, a3, t2
+	move		t3, zero
+	and		t0, a4, t0
+
+
+	xor		a4, t2, a1
+	move		t5, zero
+	orn		a4, a4, t1
+	bnez		t0, L(found_end)
+
+	sub.d		t1, a4, a2
+	andn		t0, a3, a4
+	and		t1, t1, t0
+
+L(loop_8bytes):
+	masknez		t4, t3, t1
+
+	maskeqz		t3, t2, t1
+	ld.d		t2, a0, 8
+	masknez		t0, t5, t1
+	maskeqz		t5, a0, t1
+
+	or		t3, t3, t4
+	or		t5, t0, t5
+	sub.d		t0, t2, a2
+	andn		t1, a3, t2
+
+
+	xor		a4, t2, a1
+	and		t0, t0, t1	//t0 hold diff pattern for '\0'
+	sub.d		t1, a4, a2
+	andn		t4, a3, a4
+
+	and		t1, t1, t4	//t1 hold diff pattern for 'a1'
+	addi.d		a0, a0, 8
+	beqz		t0, L(loop_8bytes)	//ok, neither \0 nor found
+L(found_end):
+	ctz.d		t1, t0
+
+	xor		t3, t3, a1
+	orn		t1, zero, t1
+	revb.d		t3, t3
+	srl.d		t1, a5, t1  // mask for '\0'
+
+	sub.d		t4, t3, a2
+	orn		a4, a4, t1
+	andn		t3, a3, t3
+	revb.d		t2, a4
+
+	sub.d		t0, t2, a2
+	andn		t1, a3, t2
+	and		t3, t3, t4
+	and		t1, t0, t1
+
+	li.d		t7, 7
+	masknez		t4, t3, t1
+	maskeqz		t3, t1, t1
+	masknez		t5, t5, t1
+
+	or		t3, t3, t4
+	maskeqz		t6, a0, t1
+	ctz.d		t0, t3
+	or		t5, t6, t5
+
+	srli.d		t0, t0, 3
+	sub.d		t0, t7, t0
+	add.d		a0, t5, t0
+	maskeqz		a0, a0, t3
+
+	jr		ra
+END(STRRCHR_NAME)
+
+#ifdef _LIBC
+libc_hidden_builtin_def(STRRCHR_NAME)
+#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..f64bfb2b
--- /dev/null
+++ b/sysdeps/loongarch/sys/asm.h
@@ -0,0 +1,58 @@
+#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;			\
+	.type	symbol, @function;	\
+symbol: \
+	cfi_startproc;			\
+
+# define ENTRY(symbol) LEAF(symbol)
+
+#define	LEAF_NO_ALIGN(symbol)			\
+	.text;				\
+	.globl	symbol;			\
+	.type	symbol, @function;	\
+symbol: \
+	cfi_startproc;
+
+# define ENTRY_NO_ALIGN(symbol) LEAF_NO_ALIGN(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/hwcap.h b/sysdeps/unix/sysv/linux/loongarch/bits/hwcap.h
new file mode 100644
index 00000000..5104b69c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/loongarch/bits/hwcap.h
@@ -0,0 +1,37 @@
+/* Defines for bits in AT_HWCAP.  LoongArch64 Linux version.
+   Copyright (C) 2022 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/>.  */
+
+#if !defined (_SYS_AUXV_H)
+# error "Never include <bits/hwcap.h> directly; use <sys/auxv.h> instead."
+#endif
+
+/* The following must match the kernel's <asm/hwcap.h>.  */
+/* HWCAP flags */
+#define HWCAP_LOONGARCH_CPUCFG          (1 << 0)
+#define HWCAP_LOONGARCH_LAM             (1 << 1)
+#define HWCAP_LOONGARCH_UAL             (1 << 2)
+#define HWCAP_LOONGARCH_FPU             (1 << 3)
+#define HWCAP_LOONGARCH_LSX             (1 << 4)
+#define HWCAP_LOONGARCH_LASX            (1 << 5)
+#define HWCAP_LOONGARCH_CRC32           (1 << 6)
+#define HWCAP_LOONGARCH_COMPLEX         (1 << 7)
+#define HWCAP_LOONGARCH_CRYPTO          (1 << 8)
+#define HWCAP_LOONGARCH_LVZ             (1 << 9)
+#define HWCAP_LOONGARCH_LBT_X86         (1 << 10)
+#define HWCAP_LOONGARCH_LBT_ARM         (1 << 11)
+#define HWCAP_LOONGARCH_LBT_MIPS        (1 << 12)
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/cpu-features.c b/sysdeps/unix/sysv/linux/loongarch/cpu-features.c
new file mode 100644
index 00000000..80870f3c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/loongarch/cpu-features.c
@@ -0,0 +1,32 @@
+/* Initialize CPU feature data.  LoongArch64 version.
+   This file is part of the GNU C Library.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for 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 <cpu-features.h>
+#include <elf/dl-hwcaps.h>
+
+static inline void
+init_cpu_features (struct cpu_features *cpu_features)
+{
+  register uint64_t cpucfg_word = UINT64_MAX;
+
+  __cpucfg(cpucfg_word, 0);
+  cpu_features->cpucfg_prid = cpucfg_word;
+
+  __cpucfg(cpucfg_word, 2);
+  cpu_features->cpucfg_word_idx2 = cpucfg_word;
+}
diff --git a/sysdeps/unix/sysv/linux/loongarch/cpu-features.h b/sysdeps/unix/sysv/linux/loongarch/cpu-features.h
new file mode 100644
index 00000000..b46a8489
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/loongarch/cpu-features.h
@@ -0,0 +1,53 @@
+/* Initialize CPU feature data.  LoongArch64 version.
+   This file is part of the GNU C Library.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for 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 _CPU_FEATURES_LOONGARCH64_H
+#define _CPU_FEATURES_LOONGARCH64_H
+
+#include <stdint.h>
+#include <sys/auxv.h>
+
+#define LA264 0x14a000
+#define LA364 0x14b000
+#define LA464 0x14c011
+
+struct cpu_features
+{
+  uint64_t cpucfg_prid;
+  uint64_t cpucfg_word_idx2;
+};
+
+/* Get a pointer to the CPU features structure.  */
+extern const struct cpu_features *_dl_larch_get_cpu_features (void)
+     __attribute__ ((pure));
+
+#define __cpucfg(ret, index)  \
+  asm volatile ("or	%1, %0, $zero\n"	\
+		"cpucfg %0, %0\n"		\
+		:"=r"(ret)			\
+		:"r"(index));
+
+#define IS_LA264(prid) (prid == LA264)
+#define IS_LA364(prid) (prid == LA364)
+#define IS_LA464(prid) (prid == LA464)
+#define SUPPORT_UAL (GLRO (dl_hwcap) & HWCAP_LOONGARCH_UAL)
+#define SUPPORT_LSX (GLRO (dl_hwcap) & HWCAP_LOONGARCH_LSX)
+#define SUPPORT_LASX (GLRO (dl_hwcap) & HWCAP_LOONGARCH_LASX)
+
+#endif /* _CPU_FEATURES_LOONGARCH64_H  */
+
diff --git a/sysdeps/unix/sysv/linux/loongarch/dl-procinfo.c b/sysdeps/unix/sysv/linux/loongarch/dl-procinfo.c
new file mode 100644
index 00000000..31e92898
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/loongarch/dl-procinfo.c
@@ -0,0 +1,60 @@
+/* Data for LoongArch64 version of processor capability information.
+   Linux version.
+   Copyright (C) 2022 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/>.  */
+
+/* If anything should be added here check whether the size of each string
+   is still ok with the given array size.
+
+   All the #ifdefs in the definitions are quite irritating but
+   necessary if we want to avoid duplicating the information.  There
+   are three different modes:
+
+   - PROCINFO_DECL is defined.  This means we are only interested in
+     declarations.
+
+   - PROCINFO_DECL is not defined:
+
+     + if SHARED is defined the file is included in an array
+       initializer.  The .element = { ... } syntax is needed.
+
+     + if SHARED is not defined a normal array initialization is
+       needed.
+  */
+
+#ifndef PROCINFO_CLASS
+# define PROCINFO_CLASS
+#endif
+
+#if !IS_IN (ldconfig)
+# if !defined PROCINFO_DECL && defined SHARED
+  ._dl_larch_cpu_features
+# else
+PROCINFO_CLASS struct cpu_features _dl_larch_cpu_features
+# endif
+# ifndef PROCINFO_DECL
+= { }
+# endif
+# if !defined SHARED || defined PROCINFO_DECL
+;
+# else
+,
+# endif
+#endif
+
+#undef PROCINFO_DECL
+#undef PROCINFO_CLASS
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/dl-sysdep.c b/sysdeps/unix/sysv/linux/loongarch/dl-sysdep.c
new file mode 100644
index 00000000..1fe72410
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/loongarch/dl-sysdep.c
@@ -0,0 +1,21 @@
+/* Operating system support for run-time dynamic linker.  LoongArch version.
+   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 <config.h>
+#include <sysdeps/loongarch/cpu-tunables.c>
+#include <sysdeps/unix/sysv/linux/dl-sysdep.c>
diff --git a/sysdeps/unix/sysv/linux/loongarch/dl-tunables.list b/sysdeps/unix/sysv/linux/loongarch/dl-tunables.list
new file mode 100644
index 00000000..c8f9793e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/loongarch/dl-tunables.list
@@ -0,0 +1,27 @@
+# Order of tunables in RHEL 8.7.0.
+@order glibc.rtld.nns
+@order glibc.elision.skip_lock_after_retries
+@order glibc.malloc.trim_threshold
+@order glibc.malloc.perturb
+@order glibc.elision.tries
+@order glibc.elision.enable
+@order glibc.malloc.mxfast
+@order glibc.elision.skip_lock_busy
+@order glibc.malloc.top_pad
+@order glibc.cpu.hwcaps
+@order glibc.cpu.hwcap_mask
+@order glibc.malloc.mmap_max
+@order glibc.elision.skip_trylock_internal_abort
+@order glibc.malloc.tcache_unsorted_limit
+@order glibc.elision.skip_lock_internal_abort
+@order glibc.malloc.arena_max
+@order glibc.malloc.mmap_threshold
+@order glibc.malloc.tcache_count
+@order glibc.malloc.arena_test
+@order glibc.rtld.optional_static_tls
+@order glibc.malloc.tcache_max
+@order glibc.malloc.check
+
+# Tunables added in RHEL 8.8.0
+@order glibc.rtld.dynamic_sort
+
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-start.c b/sysdeps/unix/sysv/linux/loongarch/libc-start.c
new file mode 100644
index 00000000..047ad751
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/loongarch/libc-start.c
@@ -0,0 +1,28 @@
+/* Override csu/libc-start.c on LoongArch64.
+   Copyright (C) 2022 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
+# include <ldsodefs.h>
+# include <cpu-features.c>
+
+extern struct cpu_features _dl_larch_cpu_features;
+
+# define ARCH_INIT_CPU_FEATURES() init_cpu_features (&_dl_larch_cpu_features)
+
+#endif
+#include <csu/libc-start.c>
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.39.3

