From 4bcb0bf4f727666ba875302baf52d60f65bd7cb1 Mon Sep 17 00:00:00 2001 From: Lixing 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 + . */ + +#include +#include + +ENTRY (__longjmp) + REG_L ra, a0, 0*SZREG + REG_L sp, a0, 1*SZREG + REG_L x, a0, 2*SZREG + REG_L fp, a0, 3*SZREG + REG_L s0, a0, 4*SZREG + REG_L s1, a0, 5*SZREG + REG_L s2, a0, 6*SZREG + REG_L s3, a0, 7*SZREG + REG_L s4, a0, 8*SZREG + REG_L s5, a0, 9*SZREG + REG_L s6, a0, 10*SZREG + REG_L s7, a0, 11*SZREG + REG_L s8, a0, 12*SZREG + + FREG_L $f24, a0, 13*SZREG + 0*SZFREG + FREG_L $f25, a0, 13*SZREG + 1*SZFREG + FREG_L $f26, a0, 13*SZREG + 2*SZFREG + FREG_L $f27, a0, 13*SZREG + 3*SZFREG + FREG_L $f28, a0, 13*SZREG + 4*SZFREG + FREG_L $f29, a0, 13*SZREG + 5*SZFREG + FREG_L $f30, a0, 13*SZREG + 6*SZFREG + FREG_L $f31, a0, 13*SZREG + 7*SZFREG + + sltui a0,a1,1 + add.d a0, a0, a1 # a0 = (a1 == 0) ? 1 : a1 + jirl zero,ra,0 + +END (__longjmp) diff --git a/sysdeps/loongarch/abort-instr.h b/sysdeps/loongarch/abort-instr.h new file mode 100644 index 00000000..46d3ad08 --- /dev/null +++ b/sysdeps/loongarch/abort-instr.h @@ -0,0 +1,2 @@ +/* An instruction which should crash any program is a breakpoint. */ +#define ABORT_INSTRUCTION asm ("break 0") diff --git a/sysdeps/loongarch/at_quick_exit.c b/sysdeps/loongarch/at_quick_exit.c new file mode 100644 index 00000000..8d4b44a7 --- /dev/null +++ b/sysdeps/loongarch/at_quick_exit.c @@ -0,0 +1 @@ +#include diff --git a/sysdeps/loongarch/atexit.c b/sysdeps/loongarch/atexit.c new file mode 100644 index 00000000..fc055a48 --- /dev/null +++ b/sysdeps/loongarch/atexit.c @@ -0,0 +1 @@ +#include diff --git a/sysdeps/loongarch/bits/endian.h b/sysdeps/loongarch/bits/endian.h new file mode 100644 index 00000000..dc9a3f2e --- /dev/null +++ b/sysdeps/loongarch/bits/endian.h @@ -0,0 +1,9 @@ +/* The MIPS architecture has selectable endianness. + It exists in both little and big endian flavours and we + want to be able to share the installed header files between + both, so we define __BYTE_ORDER based on GCC's predefines. */ + +#ifndef _ENDIAN_H +# error "Never use directly; include instead." +#endif +# define __BYTE_ORDER __LITTLE_ENDIAN diff --git a/sysdeps/loongarch/bits/fenv.h b/sysdeps/loongarch/bits/fenv.h new file mode 100644 index 00000000..42767412 --- /dev/null +++ b/sysdeps/loongarch/bits/fenv.h @@ -0,0 +1,93 @@ +/* Copyright (C) 1998-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#ifndef _FENV_H +# error "Never use directly; include instead." +#endif + + +/* Define bits representing the exception. We use the bit positions + of the appropriate bits in the FPU control word. */ +enum + { + FE_INEXACT = +#define FE_INEXACT 0x010000 + FE_INEXACT, + FE_UNDERFLOW = +#define FE_UNDERFLOW 0x020000 + FE_UNDERFLOW, + FE_OVERFLOW = +#define FE_OVERFLOW 0x040000 + FE_OVERFLOW, + FE_DIVBYZERO = +#define FE_DIVBYZERO 0x080000 + FE_DIVBYZERO, + FE_INVALID = +#define FE_INVALID 0x100000 + FE_INVALID, + }; + +#define FE_ALL_EXCEPT \ + (FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID) + +/* The MIPS FPU supports all of the four defined rounding modes. We + use again the bit positions in the FPU control word as the values + for the appropriate macros. */ +enum + { + FE_TONEAREST = +#define FE_TONEAREST 0x000 + FE_TONEAREST, + FE_TOWARDZERO = +#define FE_TOWARDZERO 0x100 + FE_TOWARDZERO, + FE_UPWARD = +#define FE_UPWARD 0x200 + FE_UPWARD, + FE_DOWNWARD = +#define FE_DOWNWARD 0x300 + FE_DOWNWARD + }; + + +/* Type representing exception flags. */ +typedef unsigned int fexcept_t; + + +/* Type representing floating-point environment. This function corresponds + to the layout of the block written by the `fstenv'. */ +typedef struct + { + unsigned int __fp_control_register; + } +fenv_t; + +/* If the default argument is used we use this value. */ +#define FE_DFL_ENV ((const fenv_t *) -1) + +#ifdef __USE_GNU +/* Floating-point environment where none of the exception is masked. */ +# define FE_NOMASK_ENV ((const fenv_t *) -257) +#endif + +#if __GLIBC_USE (IEC_60559_BFP_EXT) +/* Type representing floating-point control modes. */ +typedef unsigned int femode_t; + +/* Default floating-point control modes. */ +# define FE_DFL_MODE ((const femode_t *) -1L) +#endif diff --git a/sysdeps/loongarch/bits/link.h b/sysdeps/loongarch/bits/link.h new file mode 100644 index 00000000..554dfdc0 --- /dev/null +++ b/sysdeps/loongarch/bits/link.h @@ -0,0 +1,56 @@ +/* Copyright (C) 2020-2021 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#ifndef _LINK_H +# error "Never include directly; use instead." +#endif + +typedef struct La_loongarch_regs +{ + unsigned long int lr_reg[8]; /* a0 - a7 */ + double lr_fpreg[8]; /* fa0 - fa7 */ + unsigned long int lr_ra; + unsigned long int lr_sp; +} La_loongarch_regs; + +/* Return values for calls from PLT on LoongArch. */ +typedef struct La_loongarch_retval +{ + unsigned long int lrv_a0; + unsigned long int lrv_a1; + double lrv_fa0; + double lrv_fa1; +} La_loongarch_retval; + +__BEGIN_DECLS + +extern ElfW(Addr) la_loongarch_gnu_pltenter (ElfW(Sym) *__sym, unsigned int __ndx, + uintptr_t *__refcook, + uintptr_t *__defcook, + La_loongarch_regs *__regs, + unsigned int *__flags, + const char *__symname, + long int *__framesizep); +extern unsigned int la_loongarch_gnu_pltexit (ElfW(Sym) *__sym, unsigned int __ndx, + uintptr_t *__refcook, + uintptr_t *__defcook, + const La_loongarch_regs *__inregs, + La_loongarch_retval *__outregs, + const char *__symname); + +__END_DECLS diff --git a/sysdeps/loongarch/bits/setjmp.h b/sysdeps/loongarch/bits/setjmp.h new file mode 100644 index 00000000..cc9b6bfd --- /dev/null +++ b/sysdeps/loongarch/bits/setjmp.h @@ -0,0 +1,39 @@ +/* Copyright (C) 2020-2021 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#ifndef _LOONGARCH_BITS_SETJMP_H +#define _LOONGARCH_BITS_SETJMP_H + +typedef struct __jmp_buf_internal_tag + { + /* Program counter. */ + long int __pc; + /* Stack pointer. */ + long int __sp; + /* Reserved */ + long int __x; + /* Frame pointer. */ + long int __fp; + /* Callee-saved registers. */ + long int __regs[9]; + + /* Callee-saved floating point registers. */ + double __fpregs[8]; + } __jmp_buf[1]; + +#endif /* _LOONGARCH_BITS_SETJMP_H */ diff --git a/sysdeps/loongarch/bits/wordsize.h b/sysdeps/loongarch/bits/wordsize.h new file mode 100644 index 00000000..8dbaa00d --- /dev/null +++ b/sysdeps/loongarch/bits/wordsize.h @@ -0,0 +1,22 @@ +/* Copyright (C) 1999-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#define __loongarch_xlen 64 + +#define __WORDSIZE __loongarch_xlen +#define __WORDSIZE_TIME64_COMPAT32 0 + diff --git a/sysdeps/loongarch/bsd-_setjmp.c b/sysdeps/loongarch/bsd-_setjmp.c new file mode 100644 index 00000000..0d413101 --- /dev/null +++ b/sysdeps/loongarch/bsd-_setjmp.c @@ -0,0 +1 @@ +/* _setjmp is implemented in setjmp.S */ diff --git a/sysdeps/loongarch/bsd-setjmp.c b/sysdeps/loongarch/bsd-setjmp.c new file mode 100644 index 00000000..ee7c5e34 --- /dev/null +++ b/sysdeps/loongarch/bsd-setjmp.c @@ -0,0 +1 @@ +/* setjmp is implemented in setjmp.S */ diff --git a/sysdeps/loongarch/configure b/sysdeps/loongarch/configure new file mode 100755 index 00000000..1e5abf81 --- /dev/null +++ b/sysdeps/loongarch/configure @@ -0,0 +1,4 @@ +# This file is generated from configure.ac by Autoconf. DO NOT EDIT! + # Local configure fragment for sysdeps/loongarch/elf. + +#AC_DEFINE(PI_STATIC_AND_HIDDEN) diff --git a/sysdeps/loongarch/configure.ac b/sysdeps/loongarch/configure.ac new file mode 100644 index 00000000..67b46ce0 --- /dev/null +++ b/sysdeps/loongarch/configure.ac @@ -0,0 +1,6 @@ +GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. +# Local configure fragment for sysdeps/loongarch/elf. + +dnl It is always possible to access static and hidden symbols in an +dnl position independent way. +#AC_DEFINE(PI_STATIC_AND_HIDDEN) diff --git a/sysdeps/loongarch/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 + . */ + +#if HAVE_TUNABLES +# define TUNABLE_NAMESPACE cpu +# include +# include +# include /* Get STDOUT_FILENO for _dl_printf. */ +# include +# include +# include +# include +# include + +# 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 + . */ + + +#include + +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 + . */ + +#ifndef _DL_IREL_H +#define _DL_IREL_H + +#include +#include + +#define ELF_MACHINE_IRELA 1 + +static inline ElfW(Addr) +__attribute ((always_inline)) +elf_ifunc_invoke (ElfW(Addr) addr) +{ + return ((ElfW(Addr) (*) (void)) (addr)) (); +} + +static inline void +__attribute ((always_inline)) +elf_irela (const ElfW(Rela) *reloc) +{ + ElfW(Addr) *const reloc_addr = (void *) reloc->r_offset; + const unsigned long int r_type = ELFW(R_TYPE) (reloc->r_info); + + if (__glibc_likely (r_type == R_LARCH_IRELATIVE)) + { + ElfW(Addr) value = elf_ifunc_invoke(reloc->r_addend); + *reloc_addr = value; + } + else + __libc_fatal ("Unexpected reloc type in static binary.\n"); +} + +#endif /* dl-irel.h */ diff --git a/sysdeps/loongarch/dl-machine.h b/sysdeps/loongarch/dl-machine.h new file mode 100644 index 00000000..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 + . */ + +#ifndef dl_machine_h +#define dl_machine_h + +#define ELF_MACHINE_NAME "LoongArch" + +#if HAVE_TUNABLES +#define TUNABLE_NAMESPACE cpu +#include +extern void TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *) attribute_hidden; +#endif + +#include +#include +#include +#include +#include + + +#ifndef _RTLD_PROLOGUE +# define _RTLD_PROLOGUE(entry) \ + ".globl\t" __STRING (entry) "\n\t" \ + ".type\t" __STRING (entry) ", @function\n\t" \ + CFI_STARTPROC "\n" \ + __STRING (entry) ":\n" +#endif + +#ifndef _RTLD_EPILOGUE +# define _RTLD_EPILOGUE(entry) \ + CFI_ENDPROC "\n\t" \ + ".size\t" __STRING (entry) ", . - " __STRING (entry) "\n" +#endif + +#define ELF_MACHINE_JMP_SLOT R_LARCH_JUMP_SLOT +#define ELF_MACHINE_IRELATIVE R_LARCH_IRELATIVE + +#define elf_machine_type_class(type) \ + ((ELF_RTYPE_CLASS_PLT * ((type) == ELF_MACHINE_JMP_SLOT \ + || (__WORDSIZE == 32 && (type) == R_LARCH_TLS_DTPREL32) \ + || (__WORDSIZE == 32 && (type) == R_LARCH_TLS_DTPMOD32) \ + || (__WORDSIZE == 32 && (type) == R_LARCH_TLS_TPREL32) \ + || (__WORDSIZE == 64 && (type) == R_LARCH_TLS_DTPREL64) \ + || (__WORDSIZE == 64 && (type) == R_LARCH_TLS_DTPMOD64) \ + || (__WORDSIZE == 64 && (type) == R_LARCH_TLS_TPREL64))) \ + | (ELF_RTYPE_CLASS_COPY * ((type) == R_LARCH_COPY))) + +#define ELF_MACHINE_NO_REL 1 +#define ELF_MACHINE_NO_RELA 0 +#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 ?: "", + 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 + . */ + + +/* 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 + . */ + +#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 + . */ + +#include +#include + +/* Assembler veneer called from the PLT header code for lazy loading. + The PLT header passes its own args in t0-t2. */ + +#ifdef __loongarch_soft_float +# define FRAME_SIZE (-((-10 * SZREG) & ALMASK)) +#else +# define FRAME_SIZE (-((-10 * SZREG - 8 * 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 +# . + +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 + . */ + +#include +#include +#include + +long double +__ieee754_sqrtl (const long double a) +{ + FP_DECL_EX; + FP_DECL_Q(A); FP_DECL_Q(C); + long double c; + + FP_INIT_ROUNDMODE; + FP_UNPACK_Q(A, a); + FP_SQRT_Q(C, A); + FP_PACK_Q(c, C); + FP_HANDLE_EXCEPTIONS; + return c; +} +strong_alias (__ieee754_sqrtl, __sqrtl_finite) diff --git a/sysdeps/loongarch/elf-init.c b/sysdeps/loongarch/elf-init.c new file mode 100644 index 00000000..5f261a9d --- /dev/null +++ b/sysdeps/loongarch/elf-init.c @@ -0,0 +1 @@ +#include diff --git a/sysdeps/loongarch/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 + . */ + +#ifndef _FENV_PRIVATE_H +#define _FENV_PRIVATE_H 1 + +#include +#include + +/* 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 + . */ + +#define NO_MATH_REDIRECT +#include +#include + +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 + . */ + +#define NO_MATH_REDIRECT +#include +#include + +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 , 2002. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + + + +double +__ieee754_sqrt (double x) +{ + double z; + __asm__ ("fsqrt.d %0,%1" : "=f" (z) : "f" (x)); + return z; +} +strong_alias (__ieee754_sqrt, __sqrt_finite) + diff --git a/sysdeps/loongarch/fpu/e_sqrtf.c b/sysdeps/loongarch/fpu/e_sqrtf.c new file mode 100644 index 00000000..706c0494 --- /dev/null +++ b/sysdeps/loongarch/fpu/e_sqrtf.c @@ -0,0 +1,28 @@ +/* Copyright (C) 2002-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Hartvig Ekner , 2002. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + + + +float +__ieee754_sqrtf (float x) +{ + float z; + __asm__ ("fsqrt.s %0,%1" : "=f" (z) : "f" (x)); + return z; +} +strong_alias (__ieee754_sqrtf, __sqrtf_finite) diff --git a/sysdeps/loongarch/fpu/fclrexcpt.c b/sysdeps/loongarch/fpu/fclrexcpt.c new file mode 100644 index 00000000..51310d93 --- /dev/null +++ b/sysdeps/loongarch/fpu/fclrexcpt.c @@ -0,0 +1,47 @@ +/* Clear given exceptions in current floating-point environment. + Copyright (C) 1998-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger , 1998. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include +#include +#include + +int +feclearexcept (int excepts) +{ + int cw; + + /* Mask out unsupported bits/exceptions. */ + excepts &= FE_ALL_EXCEPT; + + /* Read the complete control word. */ + _FPU_GETCW (cw); + + /* Clear exception flag bits and cause bits. If the cause bit is not + cleared, the next CTC instruction (just below) will re-generate the + exception. */ + + cw &= ~(excepts | (excepts << CAUSE_SHIFT)); + + /* Put the new data in effect. */ + _FPU_SETCW (cw); + + /* Success. */ + return 0; +} +libm_hidden_def (feclearexcept) diff --git a/sysdeps/loongarch/fpu/fedisblxcpt.c b/sysdeps/loongarch/fpu/fedisblxcpt.c new file mode 100644 index 00000000..004b0ecb --- /dev/null +++ b/sysdeps/loongarch/fpu/fedisblxcpt.c @@ -0,0 +1,40 @@ +/* Disable floating-point exceptions. + Copyright (C) 2000-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger , 2000. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include +#include +#include + +int +fedisableexcept (int excepts) +{ + unsigned int new_exc, old_exc; + + /* Get the current control word. */ + _FPU_GETCW (new_exc); + + old_exc = (new_exc & ENABLE_MASK) << ENABLE_SHIFT; + + excepts &= FE_ALL_EXCEPT; + + new_exc &= ~(excepts >> ENABLE_SHIFT); + _FPU_SETCW (new_exc); + + return old_exc; +} diff --git a/sysdeps/loongarch/fpu/feenablxcpt.c b/sysdeps/loongarch/fpu/feenablxcpt.c new file mode 100644 index 00000000..b8f56625 --- /dev/null +++ b/sysdeps/loongarch/fpu/feenablxcpt.c @@ -0,0 +1,40 @@ +/* Enable floating-point exceptions. + Copyright (C) 2000-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger , 2000. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include +#include +#include + +int +feenableexcept (int excepts) +{ + unsigned int new_exc, old_exc; + + /* Get the current control word. */ + _FPU_GETCW (new_exc); + + old_exc = (new_exc & ENABLE_MASK) << ENABLE_SHIFT; + + excepts &= FE_ALL_EXCEPT; + + new_exc |= excepts >> ENABLE_SHIFT; + _FPU_SETCW (new_exc); + + return old_exc; +} diff --git a/sysdeps/loongarch/fpu/fegetenv.c b/sysdeps/loongarch/fpu/fegetenv.c new file mode 100644 index 00000000..8e8fa2c5 --- /dev/null +++ b/sysdeps/loongarch/fpu/fegetenv.c @@ -0,0 +1,33 @@ +/* Store current floating-point environment. + Copyright (C) 1998-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger , 1998. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include +#include + +int +__fegetenv (fenv_t *envp) +{ + _FPU_GETCW (*envp); + + /* Success. */ + return 0; +} +libm_hidden_def (__fegetenv) +weak_alias (__fegetenv, fegetenv) +libm_hidden_weak (fegetenv) diff --git a/sysdeps/loongarch/fpu/fegetexcept.c b/sysdeps/loongarch/fpu/fegetexcept.c new file mode 100644 index 00000000..2c0a1208 --- /dev/null +++ b/sysdeps/loongarch/fpu/fegetexcept.c @@ -0,0 +1,33 @@ +/* Get enabled floating-point exceptions. + Copyright (C) 2000-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger , 2000. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include +#include +#include + +int +fegetexcept (void) +{ + unsigned int exc; + + /* Get the current control word. */ + _FPU_GETCW (exc); + + return (exc & ENABLE_MASK) << ENABLE_SHIFT; +} diff --git a/sysdeps/loongarch/fpu/fegetmode.c b/sysdeps/loongarch/fpu/fegetmode.c new file mode 100644 index 00000000..e0a5180f --- /dev/null +++ b/sysdeps/loongarch/fpu/fegetmode.c @@ -0,0 +1,27 @@ +/* Store current floating-point control modes. MIPS version. + Copyright (C) 2016-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include + +int +fegetmode (femode_t *modep) +{ + _FPU_GETCW (*modep); + return 0; +} diff --git a/sysdeps/loongarch/fpu/fegetround.c b/sysdeps/loongarch/fpu/fegetround.c new file mode 100644 index 00000000..a7ac444a --- /dev/null +++ b/sysdeps/loongarch/fpu/fegetround.c @@ -0,0 +1,35 @@ +/* Return current rounding direction. + Copyright (C) 1998-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger , 1998. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include +#include + +int +__fegetround (void) +{ + int cw; + + /* Get control word. */ + _FPU_GETCW (cw); + + return cw & _FPU_RC_MASK; +} +libm_hidden_def (__fegetround) +weak_alias (__fegetround, fegetround) +libm_hidden_weak (fegetround) diff --git a/sysdeps/loongarch/fpu/feholdexcpt.c b/sysdeps/loongarch/fpu/feholdexcpt.c new file mode 100644 index 00000000..eb9d4764 --- /dev/null +++ b/sysdeps/loongarch/fpu/feholdexcpt.c @@ -0,0 +1,41 @@ +/* Store current floating-point environment and clear exceptions. + Copyright (C) 2000-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger , 2000. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include +#include + +int +__feholdexcept (fenv_t *envp) +{ + fpu_control_t cw; + + /* Save the current state. */ + _FPU_GETCW (cw); + envp->__fp_control_register = cw; + + /* Clear all exception enable bits and flags. */ + cw &= ~(_FPU_MASK_V|_FPU_MASK_Z|_FPU_MASK_O|_FPU_MASK_U|_FPU_MASK_I|FE_ALL_EXCEPT); + _FPU_SETCW (cw); + + return 0; +} + +libm_hidden_def (__feholdexcept) +weak_alias (__feholdexcept, feholdexcept) +libm_hidden_weak (feholdexcept) diff --git a/sysdeps/loongarch/fpu/fenv_libc.h b/sysdeps/loongarch/fpu/fenv_libc.h new file mode 100644 index 00000000..f5dd1678 --- /dev/null +++ b/sysdeps/loongarch/fpu/fenv_libc.h @@ -0,0 +1,31 @@ +/* Copyright (C) 2000-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger . + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#ifndef _FENV_LIBC_H +#define _FENV_LIBC_H 1 + +/* Mask for enabling exceptions and for the CAUSE bits. */ +#define ENABLE_MASK 0x0000001FU +#define CAUSE_MASK 0x1F000000U + +/* Shift for FE_* flags to get up to the ENABLE bits and the CAUSE bits. */ +#define ENABLE_SHIFT 16 +#define CAUSE_SHIFT 8 + + +#endif /* _FENV_LIBC_H */ diff --git a/sysdeps/loongarch/fpu/fesetenv.c b/sysdeps/loongarch/fpu/fesetenv.c new file mode 100644 index 00000000..8dee8782 --- /dev/null +++ b/sysdeps/loongarch/fpu/fesetenv.c @@ -0,0 +1,44 @@ +/* Install given floating-point environment. + Copyright (C) 1998-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger , 1998. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include +#include + +int +__fesetenv (const fenv_t *envp) +{ + fpu_control_t cw; + + /* Read first current state to flush fpu pipeline. */ + _FPU_GETCW (cw); + + if (envp == FE_DFL_ENV) + _FPU_SETCW (_FPU_DEFAULT); + else if (envp == FE_NOMASK_ENV) + _FPU_SETCW (_FPU_IEEE); + else + _FPU_SETCW (envp->__fp_control_register); + + /* Success. */ + return 0; +} + +libm_hidden_def (__fesetenv) +weak_alias (__fesetenv, fesetenv) +libm_hidden_weak (fesetenv) diff --git a/sysdeps/loongarch/fpu/fesetexcept.c b/sysdeps/loongarch/fpu/fesetexcept.c new file mode 100644 index 00000000..d14febca --- /dev/null +++ b/sysdeps/loongarch/fpu/fesetexcept.c @@ -0,0 +1,32 @@ +/* Set given exception flags. MIPS version. + Copyright (C) 2016-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include + +int +fesetexcept (int excepts) +{ + fpu_control_t temp; + + _FPU_GETCW (temp); + temp |= excepts & FE_ALL_EXCEPT; + _FPU_SETCW (temp); + + return 0; +} diff --git a/sysdeps/loongarch/fpu/fesetmode.c b/sysdeps/loongarch/fpu/fesetmode.c new file mode 100644 index 00000000..8cc5d0b1 --- /dev/null +++ b/sysdeps/loongarch/fpu/fesetmode.c @@ -0,0 +1,38 @@ +/* Install given floating-point control modes. MIPS version. + Copyright (C) 2016-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include + +#define FCSR_STATUS 0x1f1f0000 + +int +fesetmode (const femode_t *modep) +{ + fpu_control_t cw; + + _FPU_GETCW (cw); + cw &= FCSR_STATUS; + if (modep == FE_DFL_MODE) + cw |= _FPU_DEFAULT; + else + cw |= *modep & ~FCSR_STATUS; + _FPU_SETCW (cw); + + return 0; +} diff --git a/sysdeps/loongarch/fpu/fesetround.c b/sysdeps/loongarch/fpu/fesetround.c new file mode 100644 index 00000000..31fdeab3 --- /dev/null +++ b/sysdeps/loongarch/fpu/fesetround.c @@ -0,0 +1,46 @@ +/* Set current rounding direction. + Copyright (C) 1998-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger , 1998. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include +#include + +int +__fesetround (int round) +{ + fpu_control_t cw; + + if ((round & ~_FPU_RC_MASK) != 0) + /* ROUND is no valid rounding mode. */ + return 1; + + /* Get current state. */ + _FPU_GETCW (cw); + + /* Set rounding bits. */ + cw &= ~_FPU_RC_MASK; + cw |= round; + /* Set new state. */ + _FPU_SETCW (cw); + + return 0; +} + +libm_hidden_def (__fesetround) +weak_alias (__fesetround, fesetround) +libm_hidden_weak (fesetround) diff --git a/sysdeps/loongarch/fpu/feupdateenv.c b/sysdeps/loongarch/fpu/feupdateenv.c new file mode 100644 index 00000000..669bfc3c --- /dev/null +++ b/sysdeps/loongarch/fpu/feupdateenv.c @@ -0,0 +1,45 @@ +/* Install given floating-point environment and raise exceptions. + Copyright (C) 1998-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger , 1998. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include +#include + +int +__feupdateenv (const fenv_t *envp) +{ + int temp; + + /* Save current exceptions. */ + _FPU_GETCW (temp); + temp &= FE_ALL_EXCEPT; + + /* Install new environment. */ + __fesetenv (envp); + + /* Raise the safed exception. Incidently for us the implementation + defined format of the values in objects of type fexcept_t is the + same as the ones specified using the FE_* constants. */ + __feraiseexcept (temp); + + /* Success. */ + return 0; +} +libm_hidden_def (__feupdateenv) +weak_alias (__feupdateenv, feupdateenv) +libm_hidden_weak (feupdateenv) diff --git a/sysdeps/loongarch/fpu/fgetexcptflg.c b/sysdeps/loongarch/fpu/fgetexcptflg.c new file mode 100644 index 00000000..1e594e14 --- /dev/null +++ b/sysdeps/loongarch/fpu/fgetexcptflg.c @@ -0,0 +1,39 @@ +/* Store current representation for exceptions. + Copyright (C) 1998-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger , 1998. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include +#include + +int +fegetexceptflag (fexcept_t *flagp, int excepts) +{ + fpu_control_t temp; + + /* Get the current exceptions. */ + _FPU_GETCW (temp); + + /* We only save the relevant bits here. In particular, care has to be + taken with the CAUSE bits, as an inadvertent restore later on could + generate unexpected exceptions. */ + + *flagp = temp & excepts & FE_ALL_EXCEPT; + + /* Success. */ + return 0; +} diff --git a/sysdeps/loongarch/fpu/fraiseexcpt.c b/sysdeps/loongarch/fpu/fraiseexcpt.c new file mode 100644 index 00000000..2eec053a --- /dev/null +++ b/sysdeps/loongarch/fpu/fraiseexcpt.c @@ -0,0 +1,84 @@ +/* Raise given exceptions. + Copyright (C) 2000-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger , 2000. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include +#include +#include + +int +__feraiseexcept (int excepts) +{ + + const float fp_zero = 0.0, fp_one = 1.0, fp_max = FLT_MAX, + fp_min = FLT_MIN, fp_1e32 = 1.0e32f, fp_two = 2.0, + fp_three = 3.0; + + /* Raise exceptions represented by EXPECTS. But we must raise only + one signal at a time. It is important that if the overflow/underflow + exception and the inexact exception are given at the same time, + the overflow/underflow exception follows the inexact exception.*/ + + /* First: invalid exception. */ + if (FE_INVALID & excepts) + __asm__ __volatile__ ( + "fdiv.s $f0,%0,%0\n\t" + : + : "f" (fp_zero) + :"$f0"); + + /* Next: division by zero. */ + if (FE_DIVBYZERO & excepts) + __asm__ __volatile__ ( + "fdiv.s $f0,%0,%1\n\t" + : + : "f" (fp_one), "f" (fp_zero) + :"$f0"); + + /* Next: overflow. */ + if (FE_OVERFLOW & excepts) + /* There's no way to raise overflow without also raising inexact. */ + __asm__ __volatile__ ( + "fadd.s $f0,%0,%1\n\t" + : + : "f" (fp_max), "f" (fp_1e32) + : "$f0"); + + /* Next: underflow. */ + if (FE_UNDERFLOW & excepts) + __asm__ __volatile__ ( + "fdiv.s $f0,%0,%1\n\t" + : + : "f" (fp_min), "f" (fp_three) + : "$f0"); + + /* Last: inexact. */ + if (FE_INEXACT & excepts) + __asm__ __volatile__ ( + "fdiv.s $f0, %0, %1\n\t" + : + : "f" (fp_two), "f" (fp_three) + : "$f0"); + + /* Success. */ + return 0; +} + +libm_hidden_def (__feraiseexcept) +weak_alias (__feraiseexcept, feraiseexcept) +libm_hidden_weak (feraiseexcept) diff --git a/sysdeps/loongarch/fpu/fsetexcptflg.c b/sysdeps/loongarch/fpu/fsetexcptflg.c new file mode 100644 index 00000000..dc447a77 --- /dev/null +++ b/sysdeps/loongarch/fpu/fsetexcptflg.c @@ -0,0 +1,42 @@ +/* Set floating-point environment exception handling. + Copyright (C) 1998-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Hartvig Ekner , 2002. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include +#include + +int +fesetexceptflag (const fexcept_t *flagp, int excepts) +{ + fpu_control_t temp; + + /* Get the current exceptions. */ + _FPU_GETCW (temp); + + /* Make sure the flags we want restored are legal. */ + excepts &= FE_ALL_EXCEPT; + + /* Now clear the bits called for, and copy them in from flagp. Note that + we ignore all non-flag bits from *flagp, so they don't matter. */ + temp = (temp & ~excepts) | (*flagp & excepts); + + _FPU_SETCW (temp); + + /* Success. */ + return 0; +} diff --git a/sysdeps/loongarch/fpu/ftestexcept.c b/sysdeps/loongarch/fpu/ftestexcept.c new file mode 100644 index 00000000..fa645b26 --- /dev/null +++ b/sysdeps/loongarch/fpu/ftestexcept.c @@ -0,0 +1,33 @@ +/* Test exception in current environment. + Copyright (C) 1998-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger , 1998. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include +#include + +int +fetestexcept (int excepts) +{ + int cw; + + /* Get current control word. */ + _FPU_GETCW (cw); + + return cw & excepts & FE_ALL_EXCEPT; +} +libm_hidden_def (fetestexcept) diff --git a/sysdeps/loongarch/fpu/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 + . */ + +#define NO_MATH_REDIRECT +#include +#include + +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 + . */ + +#define NO_MATH_REDIRECT +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#define NO_MATH_REDIRECT +#include +#include + +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 + . */ + +#define NO_MATH_REDIRECT +#include +#include + +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 + . */ + +#define NO_MATH_REDIRECT +#include +#include + +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 + . */ + +#define NO_MATH_REDIRECT +#include +#include + +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 + . */ + +#define NO_MATH_REDIRECT +#include +#include + +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 + . */ + +#define NO_MATH_REDIRECT +#include +#include + +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 + . */ + +#define NO_MATH_REDIRECT +#include +#include + +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 + . */ + +#define NO_MATH_REDIRECT +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#define NO_MATH_REDIRECT +#include +#include + +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 + . */ + +#define NO_MATH_REDIRECT +#include +#include + +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 + . */ + +#define NO_MATH_REDIRECT +#include +#include + +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 + . */ + +#define NO_MATH_REDIRECT +#include +#include + +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 + . */ + +#define NO_MATH_REDIRECT +#include +#include + +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 + . */ + +#define NO_MATH_REDIRECT +#include +#include + +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 + . */ + +#define NO_MATH_REDIRECT +#include +#include + +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 + . */ + +#define NO_MATH_REDIRECT +#include +#include + +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 + . */ + +#define NO_MATH_REDIRECT +#include + +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 + . */ + +#define NO_MATH_REDIRECT +#include + +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 + . */ + +#ifndef _FPU_CONTROL_H +#define _FPU_CONTROL_H + +/* MIPS FPU floating point control register bits. + * + * 31-25 -> floating point conditions code bits 7-1. These bits are only + * available in MIPS IV. + * 24 -> flush denormalized results to zero instead of + * causing unimplemented operation exception. This bit is only + * available for MIPS III and newer. + * 23 -> Condition bit + * 22-21 -> reserved for architecture implementers + * 20 -> reserved (read as 0, write with 0) + * 19 -> IEEE 754-2008 non-arithmetic ABS.fmt and NEG.fmt enable + * 18 -> IEEE 754-2008 recommended NaN encoding enable + * 17 -> cause bit for unimplemented operation + * 28 -> cause bit for invalid exception + * 27 -> cause bit for division by zero exception + * 26 -> cause bit for overflow exception + * 25 -> cause bit for underflow exception + * 24 -> cause bit for inexact exception + * 4 -> enable exception for invalid exception + * 3 -> enable exception for division by zero exception + * 2 -> enable exception for overflow exception + * 1 -> enable exception for underflow exception + * 0 -> enable exception for inexact exception + * 20 -> flag invalid exception + * 19 -> flag division by zero exception + * 18 -> flag overflow exception + * 17 -> flag underflow exception + * 16 -> flag inexact exception + * 9-8 -> rounding control + * + * + * Rounding Control: + * 00 - rounding to nearest (RN) + * 01 - rounding toward zero (RZ) + * 10 - rounding (up) toward plus infinity (RP) + * 11 - rounding (down)toward minus infinity (RM) + */ + +#include + +#ifdef __loongarch_soft_float + +#define _FPU_RESERVED 0xffffffff +#define _FPU_DEFAULT 0x00000000 +typedef unsigned int fpu_control_t; +#define _FPU_GETCW(cw) (cw) = 0 +#define _FPU_SETCW(cw) (void) (cw) +extern fpu_control_t __fpu_control; + +#else /* __loongarch_soft_float */ + +/* Masks for interrupts. */ +#define _FPU_MASK_V 0x10 /* Invalid operation */ +#define _FPU_MASK_Z 0x08 /* Division by zero */ +#define _FPU_MASK_O 0x04 /* Overflow */ +#define _FPU_MASK_U 0x02 /* Underflow */ +#define _FPU_MASK_I 0x01 /* Inexact operation */ + +/* Flush denormalized numbers to zero. */ +#define _FPU_FLUSH_TZ 0x1000000 + +/* Rounding control. */ +#define _FPU_RC_NEAREST 0x000 /* RECOMMENDED */ +#define _FPU_RC_ZERO 0x100 +#define _FPU_RC_UP 0x200 +#define _FPU_RC_DOWN 0x300 +/* Mask for rounding control. */ +#define _FPU_RC_MASK 0x300 + +#define _FPU_RESERVED 0x0 + +#define _FPU_DEFAULT 0x0 +#define _FPU_IEEE 0x1F + +/* Type of the control word. */ +typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__SI__))); + +/* Macros for accessing the hardware control word. */ +extern fpu_control_t __mips_fpu_getcw (void) __THROW; +extern void __mips_fpu_setcw (fpu_control_t) __THROW; +#define _FPU_GETCW(cw) __asm__ volatile ("movfcsr2gr %0,$r0" : "=r" (cw)) +#define _FPU_SETCW(cw) __asm__ volatile ("movgr2fcsr $r0,%0" : : "r" (cw)) + +/* Default control word set at startup. */ +extern fpu_control_t __fpu_control; + +# 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 diff --git a/sysdeps/loongarch/fstat64.c b/sysdeps/loongarch/fstat64.c new file mode 100644 index 00000000..143ca2b0 --- /dev/null +++ b/sysdeps/loongarch/fstat64.c @@ -0,0 +1 @@ +#include diff --git a/sysdeps/loongarch/fstatat.c b/sysdeps/loongarch/fstatat.c new file mode 100644 index 00000000..0b0a3342 --- /dev/null +++ b/sysdeps/loongarch/fstatat.c @@ -0,0 +1 @@ +#include diff --git a/sysdeps/loongarch/fstatat64.c b/sysdeps/loongarch/fstatat64.c new file mode 100644 index 00000000..e82b9274 --- /dev/null +++ b/sysdeps/loongarch/fstatat64.c @@ -0,0 +1 @@ +#include diff --git a/sysdeps/loongarch/gccframe.h b/sysdeps/loongarch/gccframe.h new file mode 100644 index 00000000..5c799c64 --- /dev/null +++ b/sysdeps/loongarch/gccframe.h @@ -0,0 +1,21 @@ +/* Copyright (C) 2020-2021 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#define FIRST_PSEUDO_REGISTER 74 + +#include diff --git a/sysdeps/loongarch/hp-timing.h b/sysdeps/loongarch/hp-timing.h new file mode 100644 index 00000000..2d006540 --- /dev/null +++ b/sysdeps/loongarch/hp-timing.h @@ -0,0 +1,40 @@ +/* High precision, low overhead timing functions. x86-64 version. + Copyright (C) 2002-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _HP_TIMING_H +#define _HP_TIMING_H 1 + +/* We always assume having the timestamp register. */ +#define HP_TIMING_AVAIL (1) +#define HP_SMALL_TIMING_AVAIL (1) + +/* We indeed have inlined functions. */ +#define HP_TIMING_INLINE (1) + +/* We use 64bit values for the times. */ +typedef unsigned long long int hp_timing_t; + +/* Read the cp0 count, this maybe inaccurate. */ +#define HP_TIMING_NOW(Var) \ + ({ unsigned long long int _count; \ + asm volatile ("rdtime.d\t%0,$r0" : "=r" (_count)); \ + (Var) = _count; }) + +#include + +#endif /* hp-timing.h */ diff --git a/sysdeps/loongarch/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 + . */ + +#include +#include + +#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 + . */ + +#include + +/* Helper for generic ____longjmp_chk(). */ +#define JB_FRAME_ADDRESS(buf) \ + ((void *) _jmpbuf_sp (buf)) diff --git a/sysdeps/loongarch/jmpbuf-unwind.h b/sysdeps/loongarch/jmpbuf-unwind.h new file mode 100644 index 00000000..c866d910 --- /dev/null +++ b/sysdeps/loongarch/jmpbuf-unwind.h @@ -0,0 +1,46 @@ +/* Copyright (C) 2020-2021 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include +#include +#include +#include + +/* Test if longjmp to JMPBUF would unwind the frame + containing a local variable at ADDRESS. */ +#define _JMPBUF_UNWINDS(jmpbuf, address, demangle) \ + ((void *) (address) < (void *) demangle ((jmpbuf)[0].__sp)) + +#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \ + _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj) + +static inline uintptr_t __attribute__ ((unused)) +_jmpbuf_sp (__jmp_buf regs) +{ + uintptr_t sp = regs[0].__sp; +#ifdef PTR_DEMANGLE + PTR_DEMANGLE (sp); +#endif + return sp; +} + +#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \ + ((uintptr_t) (_address) - (_adj) < _jmpbuf_sp (_jmpbuf) - (_adj)) + +/* We use the normal longjmp for unwinding. */ +#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val) diff --git a/sysdeps/loongarch/ldsodefs.h b/sysdeps/loongarch/ldsodefs.h new file mode 100644 index 00000000..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 + . */ + +#ifndef _LOONGARCH_LDSODEFS_H +#define _LOONGARCH_LDSODEFS_H 1 + +#include +#include + +struct La_loongarch_regs; +struct La_loongarch_retval; + +#define ARCH_PLTENTER_MEMBERS \ + ElfW(Addr) (*loongarch_gnu_pltenter) (ElfW(Sym) *, unsigned int, \ + uintptr_t *, uintptr_t *, \ + const struct La_loongarch_regs *, \ + unsigned int *, const char *name, \ + long int *framesizep); + +#define ARCH_PLTEXIT_MEMBERS \ + unsigned int (*loongarch_gnu_pltexit) (ElfW(Sym) *, unsigned int, \ + uintptr_t *, uintptr_t *, \ + const struct La_loongarch_regs *, \ + struct La_loongarch_retval *, \ + const char *); + +/* The LoongArch ABI specifies that the dynamic section has to be read-only. */ + +#define DL_RO_DYN_SECTION 1 + +#include_next + +#endif diff --git a/sysdeps/loongarch/libc-start.h b/sysdeps/loongarch/libc-start.h new file mode 100644 index 00000000..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 + . */ + +#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 + . */ + +#include +#include + +/* On LoongArch, linker optimizations are not required, so __tls_get_addr + can be called even in statically linked binaries. In this case module + must be always 1 and PT_TLS segment exist in the binary, otherwise it + would not link. */ + +void * +__tls_get_addr (tls_index *ti) +{ + dtv_t *dtv = THREAD_DTV (); + return (char *) dtv[1].pointer.val + GET_ADDR_OFFSET; +} diff --git a/sysdeps/loongarch/linkmap.h b/sysdeps/loongarch/linkmap.h new file mode 100644 index 00000000..ac170bb3 --- /dev/null +++ b/sysdeps/loongarch/linkmap.h @@ -0,0 +1,4 @@ +struct link_map_machine + { + ElfW(Addr) plt; /* Address of .plt. */ + }; diff --git a/sysdeps/loongarch/lp64/Implies-after b/sysdeps/loongarch/lp64/Implies-after new file mode 100644 index 00000000..a8cae95f --- /dev/null +++ b/sysdeps/loongarch/lp64/Implies-after @@ -0,0 +1 @@ +wordsize-64 diff --git a/sysdeps/loongarch/lp64/libm-test-ulps b/sysdeps/loongarch/lp64/libm-test-ulps new file mode 100644 index 00000000..61be2df6 --- /dev/null +++ b/sysdeps/loongarch/lp64/libm-test-ulps @@ -0,0 +1,2206 @@ +# Begin of automatic generation + +# Maximal error of functions: +Function: "acos": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "acos_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "acos_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "acos_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "acosh": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "acosh_downward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: "acosh_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "acosh_upward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "asin": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "asin_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "asin_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "asin_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "asinh": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: "asinh_downward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 4 +ldouble: 4 + +Function: "asinh_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "asinh_upward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 4 +ldouble: 4 + +Function: "atan": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "atan2": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "atan2_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "atan2_towardzero": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: "atan2_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "atan_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "atan_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "atan_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "atanh": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: "atanh_downward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 4 +ldouble: 4 + +Function: "atanh_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "atanh_upward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 4 +ldouble: 4 + +Function: "cabs": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 + +Function: "cabs_downward": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 + +Function: "cabs_towardzero": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 + +Function: "cabs_upward": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 + +Function: Real part of "cacos": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "cacos": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "cacos_downward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "cacos_downward": +double: 5 +float: 3 +idouble: 5 +ifloat: 3 +ildouble: 6 +ldouble: 6 + +Function: Real part of "cacos_towardzero": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "cacos_towardzero": +double: 4 +float: 2 +idouble: 4 +ifloat: 2 +ildouble: 5 +ldouble: 5 + +Function: Real part of "cacos_upward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "cacos_upward": +double: 5 +float: 5 +idouble: 5 +ifloat: 5 +ildouble: 7 +ldouble: 7 + +Function: Real part of "cacosh": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "cacosh": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "cacosh_downward": +double: 4 +float: 2 +idouble: 4 +ifloat: 2 +ildouble: 5 +ldouble: 5 + +Function: Imaginary part of "cacosh_downward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 4 +ldouble: 4 + +Function: Real part of "cacosh_towardzero": +double: 4 +float: 2 +idouble: 4 +ifloat: 2 +ildouble: 5 +ldouble: 5 + +Function: Imaginary part of "cacosh_towardzero": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Real part of "cacosh_upward": +double: 4 +float: 3 +idouble: 4 +ifloat: 3 +ildouble: 6 +ldouble: 6 + +Function: Imaginary part of "cacosh_upward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 4 +ldouble: 4 + +Function: "carg": +float: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "carg_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "carg_towardzero": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: "carg_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: Real part of "casin": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "casin": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "casin_downward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "casin_downward": +double: 5 +float: 3 +idouble: 5 +ifloat: 3 +ildouble: 6 +ldouble: 6 + +Function: Real part of "casin_towardzero": +double: 3 +float: 1 +idouble: 3 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "casin_towardzero": +double: 4 +float: 2 +idouble: 4 +ifloat: 2 +ildouble: 5 +ldouble: 5 + +Function: Real part of "casin_upward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "casin_upward": +double: 5 +float: 5 +idouble: 5 +ifloat: 5 +ildouble: 7 +ldouble: 7 + +Function: Real part of "casinh": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "casinh": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: Real part of "casinh_downward": +double: 5 +float: 3 +idouble: 5 +ifloat: 3 +ildouble: 6 +ldouble: 6 + +Function: Imaginary part of "casinh_downward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Real part of "casinh_towardzero": +double: 4 +float: 2 +idouble: 4 +ifloat: 2 +ildouble: 5 +ldouble: 5 + +Function: Imaginary part of "casinh_towardzero": +double: 3 +float: 1 +idouble: 3 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: Real part of "casinh_upward": +double: 5 +float: 5 +idouble: 5 +ifloat: 5 +ildouble: 7 +ldouble: 7 + +Function: Imaginary part of "casinh_upward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Real part of "catan": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "catan": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Real part of "catan_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "catan_downward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "catan_towardzero": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "catan_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "catan_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "catan_upward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Real part of "catanh": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "catanh": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Real part of "catanh_downward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "catanh_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "catanh_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "catanh_towardzero": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "catanh_upward": +double: 4 +float: 4 +idouble: 4 +ifloat: 4 +ildouble: 4 +ldouble: 4 + +Function: Imaginary part of "catanh_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "cbrt": +double: 3 +float: 1 +idouble: 3 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "cbrt_downward": +double: 4 +float: 1 +idouble: 4 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "cbrt_towardzero": +double: 3 +float: 1 +idouble: 3 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "cbrt_upward": +double: 5 +float: 1 +idouble: 5 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Real part of "ccos": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "ccos": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Real part of "ccos_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "ccos_downward": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 2 +ldouble: 2 + +Function: Real part of "ccos_towardzero": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "ccos_towardzero": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 2 +ldouble: 2 + +Function: Real part of "ccos_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "ccos_upward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "ccosh": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "ccosh": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Real part of "ccosh_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "ccosh_downward": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 2 +ldouble: 2 + +Function: Real part of "ccosh_towardzero": +double: 1 +float: 3 +idouble: 1 +ifloat: 3 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "ccosh_towardzero": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 2 +ldouble: 2 + +Function: Real part of "ccosh_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "ccosh_upward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "cexp": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "cexp": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 1 +ldouble: 1 + +Function: Real part of "cexp_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "cexp_downward": +double: 1 +float: 3 +idouble: 1 +ifloat: 3 +ildouble: 2 +ldouble: 2 + +Function: Real part of "cexp_towardzero": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "cexp_towardzero": +double: 1 +float: 3 +idouble: 1 +ifloat: 3 +ildouble: 2 +ldouble: 2 + +Function: Real part of "cexp_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "cexp_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Real part of "clog": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "clog": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Real part of "clog10": +double: 3 +float: 4 +idouble: 3 +ifloat: 4 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "clog10": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "clog10_downward": +double: 5 +float: 5 +idouble: 5 +ifloat: 5 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "clog10_downward": +double: 2 +float: 4 +idouble: 2 +ifloat: 4 +ildouble: 3 +ldouble: 3 + +Function: Real part of "clog10_towardzero": +double: 5 +float: 5 +idouble: 5 +ifloat: 5 +ildouble: 4 +ldouble: 4 + +Function: Imaginary part of "clog10_towardzero": +double: 2 +float: 4 +idouble: 2 +ifloat: 4 +ildouble: 3 +ldouble: 3 + +Function: Real part of "clog10_upward": +double: 6 +float: 5 +idouble: 6 +ifloat: 5 +ildouble: 4 +ldouble: 4 + +Function: Imaginary part of "clog10_upward": +double: 2 +float: 4 +idouble: 2 +ifloat: 4 +ildouble: 3 +ldouble: 3 + +Function: Real part of "clog_downward": +double: 4 +float: 3 +idouble: 4 +ifloat: 3 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "clog_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "clog_towardzero": +double: 4 +float: 4 +idouble: 4 +ifloat: 4 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "clog_towardzero": +double: 1 +float: 3 +idouble: 1 +ifloat: 3 +ildouble: 2 +ldouble: 2 + +Function: Real part of "clog_upward": +double: 4 +float: 3 +idouble: 4 +ifloat: 3 +ildouble: 4 +ldouble: 4 + +Function: Imaginary part of "clog_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "cos": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 + +Function: "cos_downward": +double: 1 +idouble: 1 +ildouble: 3 +ldouble: 3 + +Function: "cos_towardzero": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 + +Function: "cos_upward": +double: 1 +idouble: 1 +ildouble: 2 +ldouble: 2 + +Function: "cosh": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "cosh_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 2 + +Function: "cosh_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 2 + +Function: "cosh_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 1 +ldouble: 3 + +Function: Real part of "cpow": +double: 2 +float: 5 +idouble: 2 +ifloat: 5 +ildouble: 4 +ldouble: 4 + +Function: Imaginary part of "cpow": +float: 2 +ifloat: 2 +ildouble: 1 +ldouble: 1 + +Function: Real part of "cpow_downward": +double: 4 +float: 8 +idouble: 4 +ifloat: 8 +ildouble: 6 +ldouble: 6 + +Function: Imaginary part of "cpow_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "cpow_towardzero": +double: 4 +float: 8 +idouble: 4 +ifloat: 8 +ildouble: 6 +ldouble: 6 + +Function: Imaginary part of "cpow_towardzero": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "cpow_upward": +double: 4 +float: 1 +idouble: 4 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "cpow_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "csin": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "csin": +ildouble: 1 +ldouble: 1 + +Function: Real part of "csin_downward": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "csin_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: Real part of "csin_towardzero": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "csin_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: Real part of "csin_upward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "csin_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Real part of "csinh": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "csinh": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Real part of "csinh_downward": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "csinh_downward": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 2 +ldouble: 2 + +Function: Real part of "csinh_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "csinh_towardzero": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 2 +ldouble: 2 + +Function: Real part of "csinh_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "csinh_upward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "csqrt": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "csqrt": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "csqrt_downward": +double: 5 +float: 4 +idouble: 5 +ifloat: 4 +ildouble: 4 +ldouble: 4 + +Function: Imaginary part of "csqrt_downward": +double: 4 +float: 3 +idouble: 4 +ifloat: 3 +ildouble: 3 +ldouble: 3 + +Function: Real part of "csqrt_towardzero": +double: 4 +float: 3 +idouble: 4 +ifloat: 3 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "csqrt_towardzero": +double: 4 +float: 3 +idouble: 4 +ifloat: 3 +ildouble: 3 +ldouble: 3 + +Function: Real part of "csqrt_upward": +double: 5 +float: 4 +idouble: 5 +ifloat: 4 +ildouble: 4 +ldouble: 4 + +Function: Imaginary part of "csqrt_upward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 3 +ldouble: 3 + +Function: Real part of "ctan": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "ctan": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Real part of "ctan_downward": +double: 6 +float: 5 +idouble: 6 +ifloat: 5 +ildouble: 4 +ldouble: 4 + +Function: Imaginary part of "ctan_downward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 5 +ldouble: 5 + +Function: Real part of "ctan_towardzero": +double: 5 +float: 2 +idouble: 5 +ifloat: 2 +ildouble: 4 +ldouble: 4 + +Function: Imaginary part of "ctan_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 5 +ldouble: 5 + +Function: Real part of "ctan_upward": +double: 2 +float: 4 +idouble: 2 +ifloat: 4 +ildouble: 5 +ldouble: 5 + +Function: Imaginary part of "ctan_upward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 5 +ldouble: 5 + +Function: Real part of "ctanh": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "ctanh": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: Real part of "ctanh_downward": +double: 4 +float: 2 +idouble: 4 +ifloat: 2 +ildouble: 5 +ldouble: 5 + +Function: Imaginary part of "ctanh_downward": +double: 6 +float: 5 +idouble: 6 +ifloat: 5 +ildouble: 4 +ldouble: 4 + +Function: Real part of "ctanh_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 5 +ldouble: 5 + +Function: Imaginary part of "ctanh_towardzero": +double: 5 +float: 2 +idouble: 5 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Real part of "ctanh_upward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 5 +ldouble: 5 + +Function: Imaginary part of "ctanh_upward": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 5 +ldouble: 5 + +Function: "erf": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "erf_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "erf_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "erf_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "erfc": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "erfc_downward": +double: 3 +float: 4 +idouble: 3 +ifloat: 4 +ildouble: 5 +ldouble: 5 + +Function: "erfc_towardzero": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 4 +ldouble: 4 + +Function: "erfc_upward": +double: 3 +float: 4 +idouble: 3 +ifloat: 4 +ildouble: 5 +ldouble: 5 + +Function: "exp": +ildouble: 1 +ldouble: 1 + +Function: "exp10": +double: 2 +idouble: 2 +ildouble: 2 +ldouble: 2 + +Function: "exp10_downward": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: "exp10_towardzero": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: "exp10_upward": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: "exp2": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 + +Function: "exp2_downward": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 + +Function: "exp2_towardzero": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 + +Function: "exp2_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "exp_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: "exp_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: "exp_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: "expm1": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "expm1_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "expm1_towardzero": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 4 +ldouble: 4 + +Function: "expm1_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: "gamma": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 5 +ldouble: 5 + +Function: "gamma_downward": +double: 4 +float: 4 +idouble: 4 +ifloat: 4 +ildouble: 8 +ldouble: 8 + +Function: "gamma_towardzero": +double: 4 +float: 3 +idouble: 4 +ifloat: 3 +ildouble: 5 +ldouble: 5 + +Function: "gamma_upward": +double: 4 +float: 5 +idouble: 4 +ifloat: 5 +ildouble: 8 +ldouble: 8 + +Function: "hypot": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 + +Function: "hypot_downward": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 + +Function: "hypot_towardzero": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 + +Function: "hypot_upward": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 + +Function: "j0": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "j0_downward": +double: 2 +float: 4 +idouble: 2 +ifloat: 4 +ildouble: 4 +ldouble: 4 + +Function: "j0_towardzero": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "j0_upward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 5 +ldouble: 5 + +Function: "j1": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 4 +ldouble: 4 + +Function: "j1_downward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 4 +ldouble: 4 + +Function: "j1_towardzero": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 4 +ldouble: 4 + +Function: "j1_upward": +double: 3 +float: 4 +idouble: 3 +ifloat: 4 +ildouble: 3 +ldouble: 3 + +Function: "jn": +double: 4 +float: 4 +idouble: 4 +ifloat: 4 +ildouble: 7 +ldouble: 7 + +Function: "jn_downward": +double: 4 +float: 5 +idouble: 4 +ifloat: 5 +ildouble: 8 +ldouble: 8 + +Function: "jn_towardzero": +double: 4 +float: 5 +idouble: 4 +ifloat: 5 +ildouble: 8 +ldouble: 8 + +Function: "jn_upward": +double: 5 +float: 4 +idouble: 5 +ifloat: 4 +ildouble: 7 +ldouble: 7 + +Function: "lgamma": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 5 +ldouble: 5 + +Function: "lgamma_downward": +double: 4 +float: 4 +idouble: 4 +ifloat: 4 +ildouble: 8 +ldouble: 8 + +Function: "lgamma_towardzero": +double: 4 +float: 3 +idouble: 4 +ifloat: 3 +ildouble: 5 +ldouble: 5 + +Function: "lgamma_upward": +double: 4 +float: 5 +idouble: 4 +ifloat: 5 +ildouble: 8 +ldouble: 8 + +Function: "log": +ildouble: 1 +ldouble: 1 + +Function: "log10": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 1 +ldouble: 1 + +Function: "log10_downward": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 1 +ldouble: 1 + +Function: "log10_towardzero": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "log10_upward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 1 +ldouble: 1 + +Function: "log1p": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "log1p_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: "log1p_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: "log1p_upward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "log2": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "log2_downward": +double: 3 +idouble: 3 +ildouble: 3 +ldouble: 3 + +Function: "log2_towardzero": +double: 2 +idouble: 2 +ildouble: 1 +ldouble: 1 + +Function: "log2_upward": +double: 3 +idouble: 3 +ildouble: 1 +ldouble: 1 + +Function: "log_downward": +ildouble: 1 +ldouble: 1 + +Function: "log_towardzero": +ildouble: 2 +ldouble: 2 + +Function: "log_upward": +double: 1 +idouble: 1 +ildouble: 2 +ldouble: 2 + +Function: "pow": +double: 1 +idouble: 1 +ildouble: 2 +ldouble: 2 + +Function: "pow_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "pow_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "pow_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "sin": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 + +Function: "sin_downward": +double: 1 +idouble: 1 +ildouble: 3 +ldouble: 3 + +Function: "sin_towardzero": +double: 1 +idouble: 1 +ildouble: 2 +ldouble: 2 + +Function: "sin_upward": +double: 1 +idouble: 1 +ildouble: 3 +ldouble: 3 + +Function: "sincos": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 + +Function: "sincos_downward": +double: 1 +idouble: 1 +ildouble: 3 +ldouble: 3 + +Function: "sincos_towardzero": +double: 1 +idouble: 1 +ildouble: 2 +ldouble: 2 + +Function: "sincos_upward": +double: 1 +idouble: 1 +ildouble: 3 +ldouble: 3 + +Function: "sinh": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "sinh_downward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 3 +ldouble: 3 + +Function: "sinh_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: "sinh_upward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 4 +ldouble: 4 + +Function: "tan": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "tan_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 1 +ldouble: 1 + +Function: "tan_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "tan_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "tanh": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "tanh_downward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 4 +ldouble: 4 + +Function: "tanh_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: "tanh_upward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 3 +ldouble: 3 + +Function: "tgamma": +double: 5 +float: 4 +idouble: 5 +ifloat: 4 +ildouble: 4 +ldouble: 4 + +Function: "tgamma_downward": +double: 5 +float: 5 +idouble: 5 +ifloat: 5 +ildouble: 5 +ldouble: 5 + +Function: "tgamma_towardzero": +double: 5 +float: 4 +idouble: 5 +ifloat: 4 +ildouble: 5 +ldouble: 5 + +Function: "tgamma_upward": +double: 4 +float: 4 +idouble: 4 +ifloat: 4 +ildouble: 4 +ldouble: 4 + +Function: "y0": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: "y0_downward": +double: 3 +float: 4 +idouble: 3 +ifloat: 4 +ildouble: 4 +ldouble: 4 + +Function: "y0_towardzero": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 3 +ldouble: 3 + +Function: "y0_upward": +double: 2 +float: 5 +idouble: 2 +ifloat: 5 +ildouble: 3 +ldouble: 3 + +Function: "y1": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "y1_downward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 4 +ldouble: 4 + +Function: "y1_towardzero": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "y1_upward": +double: 5 +float: 2 +idouble: 5 +ifloat: 2 +ildouble: 5 +ldouble: 5 + +Function: "yn": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 5 +ldouble: 5 + +Function: "yn_downward": +double: 3 +float: 4 +idouble: 3 +ifloat: 4 +ildouble: 5 +ldouble: 5 + +Function: "yn_towardzero": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 5 +ldouble: 5 + +Function: "yn_upward": +double: 4 +float: 5 +idouble: 4 +ifloat: 5 +ildouble: 5 +ldouble: 5 + +# end of automatic generation diff --git a/sysdeps/loongarch/lp64/libm-test-ulps-name b/sysdeps/loongarch/lp64/libm-test-ulps-name new file mode 100644 index 00000000..ce02281e --- /dev/null +++ b/sysdeps/loongarch/lp64/libm-test-ulps-name @@ -0,0 +1 @@ +LoongArch 64-bit diff --git a/sysdeps/loongarch/lp64/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 +#include +#include +#else +#include +#include +#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 +#include +#include +#else +#include +#include +#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 +#include +#include +#else +#include +#include +#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 +#include +#include +#else +#include +#include +#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 + . */ + +#include +#include +#include +#include +#include +#include +#include + +/* 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 + . */ + +#include + +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 + . */ + +#include + +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 + . */ + +#include + +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 + . */ + +#include + +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 + . */ + +#include + +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 +#include +#include +#else +#include +#include +#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 +#include +#include +#else +#include +#include +#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 + . */ + +/* Define multiple versions only for the definition in libc. */ +#if IS_IN (libc) +# define memchr __redirect_memchr +# include +# 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 +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 +#include +#include +#else +#include +#include +#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 +#include +#include +#else +#include +#include +#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 + . */ + +/* Define multiple versions only for the definition in libc. */ +#if IS_IN (libc) +# define memcmp __redirect_memcmp +# include +# 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 +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 +#include +#include +#else +#include +#include +#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 + . */ + +/* Define multiple versions only for the definition in libc. */ +#if IS_IN (libc) +# define memcpy __redirect_memcpy +# include +# 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 +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 +#include +#include +#else +#include +#include +#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 +#include +#include +#else +#include +#include +#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 +#include +#include +#else +#include +#include +#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. */ + +/* Define multiple versions only for the definition in libc. */ +#if IS_IN (libc) +# define memmove __redirect_memmove +# include +# 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 +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 +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 +#include +#include +#else +#include +#include +#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 +#include +#include +#else +#include +#include +#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 + . */ + +/* Define multiple versions only for the definition in libc. */ +#if IS_IN (libc) +# define memrchr __redirect_memrchr +# include +# 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 +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 +#include +#include +#else +#include +#include +#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 +#include +#include +#else +#include +#include +#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 +#include +#include +#else +#include +#include +#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. */ + +/* Define multiple versions only for the definition in libc. */ +#if IS_IN (libc) +# define memset __redirect_memset +# include +# 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 +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 +#include + +#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 +#include +#include +#else +#include +#include +#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 + . */ + +#if IS_IN (libc) +# define rawmemchr __redirect_rawmemchr +# define __rawmemchr __redirect___rawmemchr +# include +# 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 +#include +#include +#else +#include +#include +#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 + . */ + +/* 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 +# 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 +#include +#include +#else +#include +#include +#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 +#include +#include +#else +#include +#include +#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 +#include +#include +#else +#include +#include +#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 + . */ + +/* Define multiple versions only for the definition in libc. */ +#if IS_IN (libc) +# define strchr __redirect_strchr +# include +# 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 +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 +#include +#include +#else +#include +#include +#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 + . */ + +/* Define multiple versions only for the definition in libc. */ +#if IS_IN (libc) +# define strchrnul __redirect_strchrnul +# define __strchrnul __redirect___strchrnul +# include +# 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 +#include +#include +#else +#include +#include +#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 +#include +#include +#else +#include +#include +#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 + . */ + +/* Define multiple versions only for the definition in libc. */ +#if IS_IN (libc) +# define strcmp __redirect_strcmp +# include +# undef strcmp + +# define SYMBOL_NAME strcmp +#include + +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 +#include +#include +#else +#include +#include +#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 +#include +#include +#else +#include +#include +#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 + . */ + +/* Define multiple versions only for the definition in libc. */ +#if IS_IN (libc) +# define strcpy __redirect_strcpy +# include +# 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 +#include +#include +#else +#include +#include +#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 +#include +#include +#else +#include +#include +#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 +#include +#include +#else +#include +#include +#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 + . */ + +/* Define multiple versions only for the definition in libc. */ +#if IS_IN (libc) +# define strlen __redirect_strlen +# include +# 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 +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 +#include +#include +#else +#include +#include +#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 +#include +#include +#else +#include +#include +#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 + . */ + +/* Define multiple versions only for the definition in libc. */ +#if IS_IN (libc) +# define strncmp __redirect_strncmp +# include +# 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 +#include +#include +#else +#include +#include +#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 +#include +#include +#else +#include +#include +#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 +#include +#include +#else +#include +#include +#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 + . */ + +/* Define multiple versions only for the definition in libc. */ +#if IS_IN (libc) +# define strnlen __redirect_strnlen +# define __strnlen __redirect___strnlen +# include +# 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 +#include +#include +#else +#include +#include +#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 +#include +#include +#else +#include +#include +#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 + . */ + +/* Define multiple versions only for the definition in libc. */ +#if IS_IN (libc) +# define strrchr __redirect_strrchr +# include +# 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 +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 +#include +#include +#else +#include +#include +#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 +#include +#include + +/* Short algorithm description: + * + * 1) if |x|==0: sin(x)=x, + * cos(x)=1. + * 2) if |x|<2^-27: sin(x)=x-x*DP_SMALL, raising underflow only when needed, + * cos(x)=1-|x|. + * 3) if |x|<2^-5 : sin(x)=x+x*x^2*DP_SIN2_0+x^5*DP_SIN2_1, + * cos(x)=1+1*x^2*DP_COS2_0+x^5*DP_COS2_1 + * 4) if |x|< Pi/4: sin(x)=x+x*x^2*(S0+x^2*(S1+x^2*(S2+x^2*(S3+x^2*S4)))), + * cos(x)=1+1*x^2*(C0+x^2*(C1+x^2*(C2+x^2*(C3+x^2*C4)))). + * 5) if |x| < 9*Pi/4: + * 5.1) Range reduction: + * k=trunc(|x|/(Pi/4)), j=(k+1)&0x0e, n=k+1, t=|x|-j*Pi/4. + * 5.2) Reconstruction: + * sign_sin = sign(x) * (-1.0)^(( n >>2)&1) + * sign_cos = (-1.0)^(((n+2)>>2)&1) + * poly_sin = ((((S4*t^2 + S3)*t^2 + S2)*t^2 + S1)*t^2 + S0)*t^2*t+t + * poly_cos = ((((C4*t^2 + C3)*t^2 + C2)*t^2 + C1)*t^2 + C0)*t^2*s+s + * if(n&2 != 0) { + * using cos(t) and sin(t) polynomials for |t|= 2^23, very large args: + * 7.1) Range reduction: + * k=trunc(|x|/(Pi/4)), j=(k+1)&0xfffffffe, n=k+1, t=|x|-j*Pi/4. + * 7.2) Reconstruction same as (5.2). + * 8) if x is Inf, return x-x, and set errno=EDOM. + * 9) if x is NaN, return x-x. + * + * Special cases: + * sin/cos(+-0) = +-0/1 not raising inexact/underflow, + * sin/cos(subnormal) raises inexact/underflow, + * sin/cos(min_normalized) raises inexact/underflow, + * sin/cos(normalized) raises inexact, + * sin/cos(Inf) = NaN, raises invalid, sets errno to EDOM, + * sin/cos(NaN) = NaN. + */ + +#define COSF __cosf + +#define LOADFD(rd, rs, label) \ + la.local rs, label;\ + fld.d rd, rs, 0 + +#define LOADFS(rd, rs, label) \ + la.local rs, label;\ + fld.s rd, rs, 0 + +#define FTOL(rd, rs, tmp) \ + ftintrz.l.d tmp, rs;\ + movfr2gr.d rd, tmp + +#define FTOW(rd, rs, tmp) \ + ftintrz.w.d tmp, rs;\ + movfr2gr.s rd, tmp + +#define WTOF(rd, rs, tmp) \ + movgr2fr.w tmp, rs;\ + ffint.d.w rd, tmp + +#define LTOF(rd, rs, tmp) \ + movgr2fr.d tmp, rs;\ + ffint.d.l rd, tmp + +LEAF(COSF) + .align 2 + .align 3 + /* fa0 is SP x; fa1 is DP x */ + movfr2gr.s t0, fa0 /* Bits of x */ + fcvt.d.s fa1, fa0 /* DP x */ + li.w t1, 0x7fffffff + and t0, t0, t1 /* |x| */ + li.w t1, 0x3f490fdb /* const Pi/4 */ + bltu t0, t1, L(arg_less_pio4) /* |x| < Pi/4 branch */ + li.w t1, 0x40e231d6 /* 9*Pi/4 */ + la.local t4, L(DP_) /*DP_ base addr*/ + bgeu t0, t1, L(greater_or_equal_9pio4) /* |x| >= 9*Pi/4 branch */ +/* L(median_args): */ + /* Here if Pi/4<=|x|<9*Pi/4 */ + fabs.d fa0, fa1 /* DP |x| */ + fld.d fa1, t4, 56 /* 4/Pi */ + fmul.d fa1, fa1, fa0 /* DP |x|/(Pi/4) */ + FTOW( t0, fa1, fa1 ) /* k=trunc(|x|/(Pi/4)) */ + la.local t1, L(PIO2J) /* base addr of PIO2J table */ + addi.w t0, t0, 1 /* k+1 */ + bstrpick.d t2, t0, 3, 1 /* j=n/2 */ + alsl.d t1, t2, t1, 3 + fld.d fa1, t1, 0 /* j*Pi/2 */ + addi.w t0, t0, 2 /* n = k+3 */ + fsub.d fa0, fa0, fa1 /* t = |x| - j * Pi/2 */ +/* Input: t0=n fa0=t*/ +L(reduced): + /* Here if cos(x) calculated using cos(t) polynomial for |t|>2)&1) + * result = s * (1.0+t^2*(C0+t^2*(C1+t^2*(C2+t^2*(C3+t^2*C4))))) + + * Here if cos(x) calculated using sin(t) polynomial for |t|>2)&1) + * result = s * t * (1.0+t^2*(S0+t^2*(S1+t^2*(S2+t^2*(S3+t^2*S4))))) + */ + /* TODO: what is the best order ??? */ + /* load-to-use latency, hardware module usage, integer pipeline & float pipeline */ + /* cancel branch */ + slli.w t0, t0, 1 /* (n << 1) */ + andi t1, t0, 4 /* (n << 1) & 4 */ + alsl.d t2, t1, t4, 4 /* adjust to DP_C or DP_S */ + fld.d fa3, t2, 32 /* C4 */ + andi t0, t0, 8 /* =====> (n << 1) & 8 */ + fmul.d fa1, fa0, fa0 /* y=x^2 */ + fld.d fa4, t2, 16 /* C2 */ + fmul.d fa2, fa1, fa1 /* z=x^4 */ + fld.d fa5, t2, 24 /* C3 */ + la.local t3, L(DP_ONES) /* =====> DP_ONES */ + fld.d fa6, t2, 8 /* C1 */ + fmadd.d fa4, fa2, fa3, fa4 /* cx = C2+z*C4 */ + fld.d fa3, t2, 0 /* C0 */ + fmadd.d fa5, fa2, fa5, fa6 /* cy = C1+z*C3 */ + fld.d fa6, t3, 0 /* one */ + fmadd.d fa4, fa2, fa4, fa3 /* cx = C0+z*cx */ + add.d t0, t0, t3 /* =====> addr */ + fmadd.d fa4, fa1, fa5, fa4 /* cx = cx+y*cy */ + fld.d fa2, t0, 0 /* sign */ + fmadd.d fa4, fa4, fa1, fa6 /* 1.0+y*cx */ + fmul.d fa1, fa2, fa4 /* sign * cx */ + bnez t1, L_return + fmul.d fa1, fa1, fa0 /* t*s, where s = sign(x) * (-1.0)^((n>>2)&1) */ +L_return: + fcvt.s.d fa0, fa1 /* SP result */ + jr ra + +L(greater_or_equal_9pio4): + /* Here if |x|>=9*Pi/4 */ + li.w t1, 0x7f800000 /* x is Inf or NaN? */ + bgeu t0, t1, L(inf_or_nan) /* |x| >= Inf branch */ + /* Here if finite |x|>=9*Pi/4 */ + li.w t1, 0x4b000000 /* 2^23 */ + bgeu t0, t1, L(greater_or_equal_2p23) /* |x| >= 2^23 branch */ + /* Here if 9*Pi/4<=|x|<2^23 */ + fabs.d fa0, fa1 /* DP |x| */ + fld.d fa1, t4, 56 + fmul.d fa1, fa1, fa0 /* |x|/(Pi/4) */ + FTOW( t0, fa1, fa1 ) /* k=trunc(|x|/(Pi/4)) */ + addi.w t0, t0, 1 /* k+1 */ + srli.w t1, t0, 1 /* x=n/2 */ + WTOF( fa1, t1, fa1 ) /* DP x */ + fld.d fa2, t4, 104 /* -PIO2HI = high part of -Pi/2 */ + fld.d fa3, t4, 112 /* -PIO2LO = low part of -Pi/2 */ + fmadd.d fa0, fa2, fa1, fa0 /* |x| - x*PIO2HI */ + addi.w t0, t0, 2 /* n = k+3 */ + fmadd.d fa0, fa3, fa1, fa0 /* |x| - x*PIO2HI - x*PIO2LO */ + b L(reduced) + +L(greater_or_equal_2p23): + /* Here if finite |x|>=2^23 */ + fabs.s fa5, fa0 /* SP |x| */ + /* bitpos = (ix>>23) - BIAS_32; */ + srli.w t0, t0, 23 /*TODO???srai.w eb = biased exponent of x */ + /* bitpos = eb - 0x7f + 59, where 0x7f is exponent bias */ + addi.w t0, t0, -124 /* t0 = bitpos */ + /* t3= j = bitpos/28 */ + /* x/28 = (x * ((0x100000000 / 28) + 1)) >> 32 */ + li.w t1, 0x924924a + mulh.wu t0, t1, t0 + fcvt.d.s fa5, fa5 /* Convert to double */ + /* TODO: what is the best order ??? */ + la.local t1, L(invpio4_table) /* t2 */ + alsl.d t1, t0, t1, 3 + fld.d fa0, t1, 0 /* invpio4_table[j] */ + fld.d fa1, t1, 8 /* invpio4_table[j+1] */ + fmul.d fa0, fa0, fa5 /* a = invpio4_table[j]*|x| */ + fld.d fa2, t1, 16 /* invpio4_table[j+2] */ + fmul.d fa1, fa1, fa5 /* b = invpio4_table[j+1]*|x| */ + fld.d fa3, t1, 24 /* invpio4_table[j+3] */ + fmul.d fa2, fa2, fa5 /* c = invpio4_table[j+2]*|x| */ + fmul.d fa3, fa3, fa5 /* d = invpio4_table[j+3]*|x| */ +/*TODO: overflow check*/ + FTOL( t0, fa0, fa4 ) /*uint64_t l = a; TODO: change the order*/ + li.w t1, -8 /* 0xfffffffffffffff8 */ + and t0, t0, t1 /* l &= ~0x7; */ + LTOF( fa4, t0, fa4 ) /* DP l*/ + fsub.d fa0, fa0, fa4 /* a -= l; */ + fadd.d fa4, fa0, fa1 /* fa4 double e = a + b; */ +/*TODO: overflow check*/ + FTOL( t0, fa4, fa4 ) /*uint64_t l = e;*/ + andi t2, t0, 1 /* l & 1 TODO: change the order*/ + LOADFD( fa5, t1, L(DP_ONES) ) /* fa5 = 1.0 */ + LTOF( fa4, t0, fa4 ) /* fa4 DP l*/ +/* critical!!!! the order */ + fsub.d fa0, fa0, fa4 + fld.d fa4, t4, 120 /* PI_4 */ + beqz t2, L_even_integer +/*L_odd_integer:*/ + fsub.d fa0, fa0, fa5 + fadd.d fa0, fa0, fa1 + fadd.d fa2, fa2, fa3 + fadd.d fa0, fa0, fa2 + addi.d t0, t0, 3 + fmul.d fa0, fa0, fa4 + b L(reduced) +L_even_integer: + fadd.d fa0, fa0, fa1 + fadd.d fa2, fa2, fa3 + fadd.d fa0, fa0, fa2 + fcmp.sle.d $fcc0, fa0, fa5 + addi.d t0, t0, 3 + bcnez $fcc0, L_leq_one +/*L_gt_one:*/ + fld.d fa2, t1, 16 /* 2.0 */ + addi.d t0, t0, 1 + fsub.d fa0, fa0, fa2 +L_leq_one: + fmul.d fa0, fa0, fa4 + b L(reduced) + +L(arg_less_pio4): + /* Here if |x| +#include +#include + +/* Short algorithm description: + * + * 1) if |x|==0: sin(x)=x, + * cos(x)=1. + * 2) if |x|<2^-27: sin(x)=x-x*DP_SMALL, raising underflow only when needed, + * cos(x)=1-|x|. + * 3) if |x|<2^-5 : sin(x)=x+x*x^2*DP_SIN2_0+x^5*DP_SIN2_1, + * cos(x)=1+1*x^2*DP_COS2_0+x^5*DP_COS2_1 + * 4) if |x|< Pi/4: sin(x)=x+x*x^2*(S0+x^2*(S1+x^2*(S2+x^2*(S3+x^2*S4)))), + * cos(x)=1+1*x^2*(C0+x^2*(C1+x^2*(C2+x^2*(C3+x^2*C4)))). + * 5) if |x| < 9*Pi/4: + * 5.1) Range reduction: + * k=trunc(|x|/(Pi/4)), j=(k+1)&0x0e, n=k+1, t=|x|-j*Pi/4. + * 5.2) Reconstruction: + * sign_sin = sign(x) * (-1.0)^(( n >>2)&1) + * sign_cos = (-1.0)^(((n+2)>>2)&1) + * poly_sin = ((((S4*t^2 + S3)*t^2 + S2)*t^2 + S1)*t^2 + S0)*t^2*t+t + * poly_cos = ((((C4*t^2 + C3)*t^2 + C2)*t^2 + C1)*t^2 + C0)*t^2*s+s + * if(n&2 != 0) { + * using cos(t) and sin(t) polynomials for |t|= 2^23, very large args: + * 7.1) Range reduction: + * k=trunc(|x|/(Pi/4)), j=(k+1)&0xfffffffe, n=k+1, t=|x|-j*Pi/4. + * 7.2) Reconstruction same as (5.2). + * 8) if x is Inf, return x-x, and set errno=EDOM. + * 9) if x is NaN, return x-x. + * + * Special cases: + * sin/cos(+-0) = +-0/1 not raising inexact/underflow, + * sin/cos(subnormal) raises inexact/underflow, + * sin/cos(min_normalized) raises inexact/underflow, + * sin/cos(normalized) raises inexact, + * sin/cos(Inf) = NaN, raises invalid, sets errno to EDOM, + * sin/cos(NaN) = NaN. + */ + +#define SINF __sinf + +#define LOADFD(rd, rs, label) \ + la.local rs, label;\ + fld.d rd, rs, 0 + +#define LOADFS(rd, rs, label) \ + la.local rs, label;\ + fld.s rd, rs, 0 + +#define FTOL(rd, rs, tmp) \ + ftintrz.l.d tmp, rs;\ + movfr2gr.d rd, tmp + +#define FTOW(rd, rs, tmp) \ + ftintrz.w.d tmp, rs;\ + movfr2gr.s rd, tmp + +#define WTOF(rd, rs, tmp) \ + movgr2fr.w tmp, rs;\ + ffint.d.w rd, tmp + +#define LTOF(rd, rs, tmp) \ + movgr2fr.d tmp, rs;\ + ffint.d.l rd, tmp + +LEAF(SINF) + .align 2 + .align 3 + /* fa0 is SP x; fa1 is DP x */ + movfr2gr.s t2, fa0 /* Bits of x */ + fcvt.d.s fa1, fa0 /* DP x */ + li.w t1, 0x7fffffff + and t0, t2, t1 /* |x| */ + li.w t1, 0x3f490fdb /* const Pi/4 */ + bltu t0, t1, L(arg_less_pio4) /* |x| < Pi/4 branch */ + li.w t1, 0x40e231d6 /* 9*Pi/4 */ + la.local t4, L(DP_) /*DP_ base addr*/ + bstrpick.d t5, t2, 31, 31 /* sign of x */ + slli.w t5, t5, 3 + bgeu t0, t1, L(greater_or_equal_9pio4) /* |x| >= 9*Pi/4 branch */ +/* L(median_args): */ + /* Here if Pi/4<=|x|<9*Pi/4 */ + fabs.d fa0, fa1 /* DP |x| */ + fld.d fa1, t4, 56 /* 4/Pi */ + fmul.d fa1, fa1, fa0 /* DP |x|/(Pi/4) */ + FTOW( t0, fa1, fa1 ) /* k=trunc(|x|/(Pi/4)) */ + la.local t1, L(PIO2J) /* base addr of PIO2J table */ + addi.w t0, t0, 1 /* k+1 */ + bstrpick.d t2, t0, 3, 1 /* j=n/2 */ + alsl.d t1, t2, t1, 3 + fld.d fa1, t1, 0 /* j*Pi/2 */ + fsub.d fa0, fa0, fa1 /* t = |x| - j * Pi/2 */ +/* Input: t0=n fa0=t*/ +/* Input: t0=n fa0=t, t5=sign(x) */ +L(reduced): + /* Here if cos(x) calculated using cos(t) polynomial for |t|>2)&1) + * result = s * (1.0+t^2*(C0+t^2*(C1+t^2*(C2+t^2*(C3+t^2*C4))))) + + * Here if cos(x) calculated using sin(t) polynomial for |t|>2)&1) + * result = s * t * (1.0+t^2*(S0+t^2*(S1+t^2*(S2+t^2*(S3+t^2*S4))))) + */ + /* TODO: what is the best order ??? */ + /* load-to-use latency, hardware module usage, integer pipeline & float pipeline */ + /* cancel branch */ + slli.w t0, t0, 1 /* (n << 1) */ + andi t1, t0, 4 /* (n << 1) & 4 */ + alsl.d t2, t1, t4, 4 /* adjust to DP_C or DP_S */ + fld.d fa3, t2, 32 /* C4 */ + andi t0, t0, 8 /* =====> (n << 1) & 8 */ + fmul.d fa1, fa0, fa0 /* y=x^2 */ + xor t0, t0, t5 /* (-1.0)^((n>>2)&1) XOR sign(x) */ + fld.d fa4, t2, 16 /* C2 */ + fmul.d fa2, fa1, fa1 /* z=x^4 */ + fld.d fa5, t2, 24 /* C3 */ + la.local t3, L(DP_ONES) /* =====> DP_ONES */ + fld.d fa6, t2, 8 /* C1 */ + fmadd.d fa4, fa2, fa3, fa4 /* cx = C2+z*C4 */ + fld.d fa3, t2, 0 /* C0 */ + fmadd.d fa5, fa2, fa5, fa6 /* cy = C1+z*C3 */ + fld.d fa6, t3, 0 /* 1.0 */ + fmadd.d fa4, fa2, fa4, fa3 /* cx = C0+z*cx */ + add.d t0, t0, t3 /* =====> addr */ + fmadd.d fa4, fa1, fa5, fa4 /* cx = cx+y*cy */ + fld.d fa2, t0, 0 /* sign */ + fmadd.d fa4, fa4, fa1, fa6 /* 1.0+y*cx */ + fmul.d fa1, fa2, fa4 /* sign * cx */ + bnez t1, L_return + fmul.d fa1, fa1, fa0 /* t*s, where s = sign(x) * (-1.0)^((n>>2)&1) */ +L_return: + fcvt.s.d fa0, fa1 /* SP result */ + jr ra + +L(greater_or_equal_9pio4): + /* Here if |x|>=9*Pi/4 */ + li.w t1, 0x7f800000 /* x is Inf or NaN? */ + bgeu t0, t1, L(inf_or_nan) /* |x| >= Inf branch */ + /* Here if finite |x|>=9*Pi/4 */ + li.w t1, 0x4b000000 /* 2^23 */ + bgeu t0, t1, L(greater_or_equal_2p23) /* |x| >= 2^23 branch */ + /* Here if 9*Pi/4<=|x|<2^23 */ + fabs.d fa0, fa1 /* DP |x| */ + fld.d fa1, t4, 56 + fmul.d fa1, fa1, fa0 /* |x|/(Pi/4) */ + FTOW( t0, fa1, fa1 ) /* k=trunc(|x|/(Pi/4)) */ + addi.w t0, t0, 1 /* k+1 */ + srli.w t1, t0, 1 /* x=n/2 */ + WTOF( fa1, t1, fa1 ) /* DP x */ + fld.d fa2, t4, 104 /* -PIO2HI = high part of -Pi/2 */ + fld.d fa3, t4, 112 /* -PIO2LO = low part of -Pi/2 */ + fmadd.d fa0, fa2, fa1, fa0 /* |x| - x*PIO2HI */ + fmadd.d fa0, fa3, fa1, fa0 /* |x| - x*PIO2HI - x*PIO2LO */ + b L(reduced) + +L(greater_or_equal_2p23): + /* Here if finite |x|>=2^23 */ + fabs.s fa5, fa0 /* SP |x| */ + /* bitpos = (ix>>23) - BIAS_32; */ + srli.w t0, t0, 23 /*TODO???srai.w eb = biased exponent of x */ + /* bitpos = eb - 0x7f + 59, where 0x7f is exponent bias */ + addi.w t0, t0, -124 /* t0 = bitpos */ + /* t3= j = bitpos/28 */ + /* x/28 = (x * ((0x100000000 / 28) + 1)) >> 32 */ + li.w t1, 0x924924a + mulh.wu t0, t1, t0 + fcvt.d.s fa5, fa5 /* Convert to double */ + /* TODO: what is the best order ??? */ + la.local t1, L(invpio4_table) /* t2 */ + alsl.d t1, t0, t1, 3 + fld.d fa0, t1, 0 /* invpio4_table[j] */ + fld.d fa1, t1, 8 /* invpio4_table[j+1] */ + fmul.d fa0, fa0, fa5 /* a = invpio4_table[j]*|x| */ + fld.d fa2, t1, 16 /* invpio4_table[j+2] */ + fmul.d fa1, fa1, fa5 /* b = invpio4_table[j+1]*|x| */ + fld.d fa3, t1, 24 /* invpio4_table[j+3] */ + fmul.d fa2, fa2, fa5 /* c = invpio4_table[j+2]*|x| */ + fmul.d fa3, fa3, fa5 /* d = invpio4_table[j+3]*|x| */ +/*TODO: overflow check*/ + FTOL( t0, fa0, fa4 ) /*uint64_t l = a; TODO: change the order*/ + li.w t1, -8 /* 0xfffffffffffffff8 */ + and t0, t0, t1 /* l &= ~0x7; */ + LTOF( fa4, t0, fa4 ) /* DP l*/ + fsub.d fa0, fa0, fa4 /* a -= l; */ + fadd.d fa4, fa0, fa1 /* fa4 double e = a + b; */ +/*TODO: overflow check*/ + FTOL( t0, fa4, fa4 ) /*uint64_t l = e;*/ + andi t2, t0, 1 /* l & 1 TODO: change the order*/ + LOADFD( fa5, t1, L(DP_ONES) ) /* fa5 = 1.0 */ + LTOF( fa4, t0, fa4 ) /* fa4 DP l*/ +/* critical!!!! the order */ + fsub.d fa0, fa0, fa4 + fld.d fa4, t4, 120 /* PI_4 */ + beqz t2, L_even_integer +/*L_odd_integer:*/ + fsub.d fa0, fa0, fa5 + fadd.d fa0, fa0, fa1 + fadd.d fa2, fa2, fa3 + fadd.d fa0, fa0, fa2 + addi.d t0, t0, 1 + fmul.d fa0, fa0, fa4 + b L(reduced) +L_even_integer: + fadd.d fa0, fa0, fa1 + fadd.d fa2, fa2, fa3 + fadd.d fa0, fa0, fa2 + fcmp.sle.d $fcc0, fa0, fa5 + addi.d t0, t0, 1 + bcnez $fcc0, L_leq_one +/*L_gt_one:*/ + fld.d fa2, t1, 16 /* 2.0 */ + addi.d t0, t0, 1 + fsub.d fa0, fa0, fa2 +L_leq_one: + fmul.d fa0, fa0, fa4 + b L(reduced) + +L(arg_less_pio4): + /* Here if |x| +#include +#include +#else +#include +#include +#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 +#include +#include +#else +#include +#include +#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 +#include +#include +#else +#include +#include +#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 +#include +#include +#else +#include +#include +#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 +#include +#include +#else +#include +#include +#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 +#include +#include +#else +#include +#include +#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 +#include +#include +#else +#include +#include +#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 +#include +#include +#else +#include +#include +#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 +#include +#include +#else +#include +#include +#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 diff --git a/sysdeps/loongarch/lstat64.c b/sysdeps/loongarch/lstat64.c new file mode 100644 index 00000000..d6811656 --- /dev/null +++ b/sysdeps/loongarch/lstat64.c @@ -0,0 +1 @@ +#include diff --git a/sysdeps/loongarch/machine-gmon.h b/sysdeps/loongarch/machine-gmon.h new file mode 100644 index 00000000..0b49082d --- /dev/null +++ b/sysdeps/loongarch/machine-gmon.h @@ -0,0 +1,37 @@ +/* Copyright (C) 2020-2021 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +/* Accept 'frompc' address as argument from the function that calls + _mcount for profiling. Use __builtin_return_address (0) + for the 'selfpc' address. */ + +#include + +static void mcount_internal (unsigned long int frompc, + unsigned long int selfpc); + +#define _MCOUNT_DECL(frompc, selfpc) \ +static inline void mcount_internal (unsigned long int frompc, \ +unsigned long int selfpc) + +#define MCOUNT \ +void _mcount (void *frompc) \ +{ \ + mcount_internal ((unsigned long int) frompc, \ + (unsigned long int) RETURN_ADDRESS (0)); \ +} diff --git a/sysdeps/loongarch/math_private.h b/sysdeps/loongarch/math_private.h new file mode 100644 index 00000000..140eef07 --- /dev/null +++ b/sysdeps/loongarch/math_private.h @@ -0,0 +1,245 @@ +/* Internal math stuff. LOONGARCH version. + Copyright (C) 2013-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef LOONGARCH_MATH_PRIVATE_H +#define LOONGARCH_MATH_PRIVATE_H 1 + +/* Inline functions to speed up the math library implementation. The + default versions of these routines are in generic/math_private.h + and call fesetround, feholdexcept, etc. These routines use inlined + code instead. */ + +#ifdef __loongarch_hard_float + +# include +# include +# include + +# define _FPU_MASK_ALL (_FPU_MASK_V | _FPU_MASK_Z | _FPU_MASK_O \ + |_FPU_MASK_U | _FPU_MASK_I | FE_ALL_EXCEPT) + +static __always_inline void +libc_feholdexcept_loongarch (fenv_t *envp) +{ + fpu_control_t cw; + + /* Save the current state. */ + _FPU_GETCW (cw); + envp->__fp_control_register = cw; + + /* Clear all exception enable bits and flags. */ + cw &= ~(_FPU_MASK_ALL); + _FPU_SETCW (cw); +} +# define libc_feholdexcept libc_feholdexcept_loongarch +# define libc_feholdexceptf libc_feholdexcept_loongarch +# define libc_feholdexceptl libc_feholdexcept_loongarch + +static __always_inline void +libc_fesetround_loongarch (int round) +{ + fpu_control_t cw; + + /* Get current state. */ + _FPU_GETCW (cw); + + /* Set rounding bits. */ + cw &= ~_FPU_RC_MASK; + cw |= round; + + /* Set new state. */ + _FPU_SETCW (cw); +} +# define libc_fesetround libc_fesetround_loongarch +# define libc_fesetroundf libc_fesetround_loongarch +# define libc_fesetroundl libc_fesetround_loongarch + +static __always_inline void +libc_feholdexcept_setround_loongarch (fenv_t *envp, int round) +{ + fpu_control_t cw; + + /* Save the current state. */ + _FPU_GETCW (cw); + envp->__fp_control_register = cw; + + /* Clear all exception enable bits and flags. */ + cw &= ~(_FPU_MASK_ALL); + + /* Set rounding bits. */ + cw &= ~_FPU_RC_MASK; + cw |= round; + + /* Set new state. */ + _FPU_SETCW (cw); +} +# define libc_feholdexcept_setround libc_feholdexcept_setround_loongarch +# define libc_feholdexcept_setroundf libc_feholdexcept_setround_loongarch +# define libc_feholdexcept_setroundl libc_feholdexcept_setround_loongarch + +# define libc_feholdsetround libc_feholdexcept_setround_loongarch +# define libc_feholdsetroundf libc_feholdexcept_setround_loongarch +# define libc_feholdsetroundl libc_feholdexcept_setround_loongarch + +static __always_inline void +libc_fesetenv_loongarch (fenv_t *envp) +{ + fpu_control_t cw __attribute__ ((unused)); + + /* Read current state to flush fpu pipeline. */ + _FPU_GETCW (cw); + + _FPU_SETCW (envp->__fp_control_register); +} +# define libc_fesetenv libc_fesetenv_loongarch +# define libc_fesetenvf libc_fesetenv_loongarch +# define libc_fesetenvl libc_fesetenv_loongarch + +static __always_inline int +libc_feupdateenv_test_loongarch (fenv_t *envp, int excepts) +{ + /* int ret = fetestexcept (excepts); feupdateenv (envp); return ret; */ + int cw, temp; + + /* Get current control word. */ + _FPU_GETCW (cw); + + /* Set flag bits (which are accumulative), and *also* set the + cause bits. The setting of the cause bits is what actually causes + the hardware to generate the exception, if the corresponding enable + bit is set as well. */ + temp = cw & FE_ALL_EXCEPT; + temp |= envp->__fp_control_register | (temp << CAUSE_SHIFT); + + /* Set new state. */ + _FPU_SETCW (temp); + + return cw & excepts & FE_ALL_EXCEPT; +} +# define libc_feupdateenv_test libc_feupdateenv_test_loongarch +# define libc_feupdateenv_testf libc_feupdateenv_test_loongarch +# define libc_feupdateenv_testl libc_feupdateenv_test_loongarch + +static __always_inline void +libc_feupdateenv_loongarch (fenv_t *envp) +{ + libc_feupdateenv_test_loongarch (envp, 0); +} +# define libc_feupdateenv libc_feupdateenv_loongarch +# define libc_feupdateenvf libc_feupdateenv_loongarch +# define libc_feupdateenvl libc_feupdateenv_loongarch + +# define libc_feresetround libc_feupdateenv_loongarch +# define libc_feresetroundf libc_feupdateenv_loongarch +# define libc_feresetroundl libc_feupdateenv_loongarch + +static __always_inline int +libc_fetestexcept_loongarch (int excepts) +{ + int cw; + + /* Get current control word. */ + _FPU_GETCW (cw); + + return cw & excepts & FE_ALL_EXCEPT; +} +# define libc_fetestexcept libc_fetestexcept_loongarch +# define libc_fetestexceptf libc_fetestexcept_loongarch +# define libc_fetestexceptl libc_fetestexcept_loongarch + +/* Enable support for rounding mode context. */ +# define HAVE_RM_CTX 1 + +static __always_inline void +libc_feholdexcept_setround_loongarch_ctx (struct rm_ctx *ctx, int round) +{ + fpu_control_t old, new; + + /* Save the current state. */ + _FPU_GETCW (old); + ctx->env.__fp_control_register = old; + + /* Clear all exception enable bits and flags. */ + new = old & ~(_FPU_MASK_ALL); + + /* Set rounding bits. */ + new = (new & ~_FPU_RC_MASK) | round; + + if (__glibc_unlikely (new != old)) + { + _FPU_SETCW (new); + ctx->updated_status = true; + } + else + ctx->updated_status = false; +} +# define libc_feholdexcept_setround_ctx libc_feholdexcept_setround_loongarch_ctx +# define libc_feholdexcept_setroundf_ctx libc_feholdexcept_setround_loongarch_ctx +# define libc_feholdexcept_setroundl_ctx libc_feholdexcept_setround_loongarch_ctx + +static __always_inline void +libc_fesetenv_loongarch_ctx (struct rm_ctx *ctx) +{ + libc_fesetenv_loongarch (&ctx->env); +} +# define libc_fesetenv_ctx libc_fesetenv_loongarch_ctx +# define libc_fesetenvf_ctx libc_fesetenv_loongarch_ctx +# define libc_fesetenvl_ctx libc_fesetenv_loongarch_ctx + +static __always_inline void +libc_feupdateenv_loongarch_ctx (struct rm_ctx *ctx) +{ + if (__glibc_unlikely (ctx->updated_status)) + libc_feupdateenv_test_loongarch (&ctx->env, 0); +} +# define libc_feupdateenv_ctx libc_feupdateenv_loongarch_ctx +# define libc_feupdateenvf_ctx libc_feupdateenv_loongarch_ctx +# define libc_feupdateenvl_ctx libc_feupdateenv_loongarch_ctx +# define libc_feresetround_ctx libc_feupdateenv_loongarch_ctx +# define libc_feresetroundf_ctx libc_feupdateenv_loongarch_ctx +# define libc_feresetroundl_ctx libc_feupdateenv_loongarch_ctx + +static __always_inline void +libc_feholdsetround_loongarch_ctx (struct rm_ctx *ctx, int round) +{ + fpu_control_t old, new; + + /* Save the current state. */ + _FPU_GETCW (old); + ctx->env.__fp_control_register = old; + + /* Set rounding bits. */ + new = (old & ~_FPU_RC_MASK) | round; + + if (__glibc_unlikely (new != old)) + { + _FPU_SETCW (new); + ctx->updated_status = true; + } + else + ctx->updated_status = false; +} +# define libc_feholdsetround_ctx libc_feholdsetround_loongarch_ctx +# define libc_feholdsetroundf_ctx libc_feholdsetround_loongarch_ctx +# define libc_feholdsetroundl_ctx libc_feholdsetround_loongarch_ctx + +#endif + +#include_next + +#endif diff --git a/sysdeps/loongarch/memusage.h b/sysdeps/loongarch/memusage.h new file mode 100644 index 00000000..bdf99f8a --- /dev/null +++ b/sysdeps/loongarch/memusage.h @@ -0,0 +1,21 @@ +/* Copyright (C) 2020-2021 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#define GETSP() ({ register uintptr_t stack_ptr asm ("$sp"); stack_ptr; }) + +#include diff --git a/sysdeps/loongarch/mknod.c b/sysdeps/loongarch/mknod.c new file mode 100644 index 00000000..1ed3681f --- /dev/null +++ b/sysdeps/loongarch/mknod.c @@ -0,0 +1 @@ +#include diff --git a/sysdeps/loongarch/mknodat.c b/sysdeps/loongarch/mknodat.c new file mode 100644 index 00000000..82bc6ee6 --- /dev/null +++ b/sysdeps/loongarch/mknodat.c @@ -0,0 +1 @@ +#include diff --git a/sysdeps/loongarch/nptl/Makefile b/sysdeps/loongarch/nptl/Makefile new file mode 100644 index 00000000..a1d5768a --- /dev/null +++ b/sysdeps/loongarch/nptl/Makefile @@ -0,0 +1,26 @@ +# Makefile for sysdeps/loongarch/nptl. +# Copyright (C) 2005-2018 Free Software Foundation, Inc. +# This file is part of the GNU C Library. +# +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with the GNU C Library; if not, see +# . + +ifeq ($(subdir),csu) +gen-as-const-headers += tcb-offsets.sym +endif + +ifeq ($(subdir),nptl) +libpthread-sysdep_routines += nptl-sysdep +libpthread-shared-only-routines += nptl-sysdep +endif diff --git a/sysdeps/loongarch/nptl/bits/pthreadtypes-arch.h b/sysdeps/loongarch/nptl/bits/pthreadtypes-arch.h new file mode 100644 index 00000000..5a761355 --- /dev/null +++ b/sysdeps/loongarch/nptl/bits/pthreadtypes-arch.h @@ -0,0 +1,68 @@ +/* Copyright (C) 2020-2021 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#ifndef _BITS_PTHREADTYPES_ARCH_H +#define _BITS_PTHREADTYPES_ARCH_H 1 + +#include + +#if __loongarch_xlen == 64 +# define __SIZEOF_PTHREAD_ATTR_T 56 +# define __SIZEOF_PTHREAD_MUTEX_T 40 +# define __SIZEOF_PTHREAD_MUTEXATTR_T 4 +# define __SIZEOF_PTHREAD_COND_T 48 +# define __SIZEOF_PTHREAD_CONDATTR_T 4 +# define __SIZEOF_PTHREAD_RWLOCK_T 56 +# define __SIZEOF_PTHREAD_RWLOCKATTR_T 8 +# define __SIZEOF_PTHREAD_BARRIER_T 32 +# define __SIZEOF_PTHREAD_BARRIERATTR_T 4 +#else +# error "rv32i-based systems are not supported" +#endif + +#define __PTHREAD_COMPAT_PADDING_MID +#define __PTHREAD_COMPAT_PADDING_END +#define __PTHREAD_MUTEX_LOCK_ELISION 0 +#define __PTHREAD_MUTEX_USE_UNION 0 +#define __PTHREAD_MUTEX_NUSERS_AFTER_KIND 0 + +#define __LOCK_ALIGNMENT +#define __ONCE_ALIGNMENT + +/* There is a lot of padding in this structure. While it's not strictly + necessary on LoongArch, we're going to leave it in to be on the safe side in + case it's needed in the future. Most other architectures have the padding, + so this gives us the same extensibility as everyone else has. */ +struct __pthread_rwlock_arch_t +{ + unsigned int __readers; + unsigned int __writers; + unsigned int __wrphase_futex; + unsigned int __writers_futex; + unsigned int __pad3; + unsigned int __pad4; + int __cur_writer; + int __shared; + unsigned long int __pad1; + unsigned long int __pad2; + unsigned int __flags; +}; + +#define __PTHREAD_RWLOCK_ELISION_EXTRA 0 + +#endif /* bits/pthreadtypes.h */ diff --git a/sysdeps/loongarch/nptl/bits/semaphore.h b/sysdeps/loongarch/nptl/bits/semaphore.h new file mode 100644 index 00000000..a9ddefb2 --- /dev/null +++ b/sysdeps/loongarch/nptl/bits/semaphore.h @@ -0,0 +1,33 @@ +/* Copyright (C) 2020-2021 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#ifndef _SEMAPHORE_H +# error "Never use directly; include instead." +#endif + +#define __SIZEOF_SEM_T (4 * __SIZEOF_POINTER__) + +/* Value returned if `sem_open' failed. */ +#define SEM_FAILED ((sem_t *) 0) + + +typedef union +{ + char __size[__SIZEOF_SEM_T]; + long int __align; +} sem_t; diff --git a/sysdeps/loongarch/nptl/libc-lowlevellock.c b/sysdeps/loongarch/nptl/libc-lowlevellock.c new file mode 100644 index 00000000..9523fb46 --- /dev/null +++ b/sysdeps/loongarch/nptl/libc-lowlevellock.c @@ -0,0 +1,8 @@ +/* This kludge works around a libpthread static linking problem: + https://sourceware.org/bugzilla/show_bug.cgi?id=15648. */ + +#ifndef SHARED +# define __lll_lock_wait_private weak_function __lll_lock_wait_private +#endif + +#include diff --git a/sysdeps/loongarch/nptl/nptl-sysdep.S b/sysdeps/loongarch/nptl/nptl-sysdep.S new file mode 100644 index 00000000..3f5c2a36 --- /dev/null +++ b/sysdeps/loongarch/nptl/nptl-sysdep.S @@ -0,0 +1,2 @@ +/* Pull in __syscall_error. */ +#include diff --git a/sysdeps/loongarch/nptl/pthread-offsets.h b/sysdeps/loongarch/nptl/pthread-offsets.h new file mode 100644 index 00000000..04130879 --- /dev/null +++ b/sysdeps/loongarch/nptl/pthread-offsets.h @@ -0,0 +1,23 @@ +/* Copyright (C) 2020-2021 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#define __PTHREAD_MUTEX_NUSERS_OFFSET 12 +#define __PTHREAD_MUTEX_KIND_OFFSET 16 +#define __PTHREAD_MUTEX_SPINS_OFFSET 20 +#define __PTHREAD_MUTEX_ELISION_OFFSET 22 +#define __PTHREAD_MUTEX_LIST_OFFSET 24 diff --git a/sysdeps/loongarch/nptl/pthreaddef.h b/sysdeps/loongarch/nptl/pthreaddef.h new file mode 100644 index 00000000..87c407bc --- /dev/null +++ b/sysdeps/loongarch/nptl/pthreaddef.h @@ -0,0 +1,32 @@ +/* Copyright (C) 2020-2021 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +/* Default stack size. */ +#define ARCH_STACK_DEFAULT_SIZE (2 * 1024 * 1024) + +/* Required stack pointer alignment at beginning. */ +#define STACK_ALIGN 16 + +/* Minimal stack size after allocating thread descriptor and guard size. */ +#define MINIMAL_REST_STACK 2048 + +/* Alignment requirement for TCB. */ +#define TCB_ALIGNMENT 16 + +/* Location of current stack frame. */ +#define CURRENT_STACK_FRAME __builtin_frame_address (0) diff --git a/sysdeps/loongarch/nptl/tcb-offsets.sym b/sysdeps/loongarch/nptl/tcb-offsets.sym new file mode 100644 index 00000000..ab4981f2 --- /dev/null +++ b/sysdeps/loongarch/nptl/tcb-offsets.sym @@ -0,0 +1,6 @@ +#include +#include + +#define thread_offsetof(mem) (long)(offsetof (struct pthread, mem) - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE) + +MULTIPLE_THREADS_OFFSET thread_offsetof (header.multiple_threads) diff --git a/sysdeps/loongarch/nptl/tls.h b/sysdeps/loongarch/nptl/tls.h new file mode 100644 index 00000000..8d2d4ca2 --- /dev/null +++ b/sysdeps/loongarch/nptl/tls.h @@ -0,0 +1,147 @@ +/* Copyright (C) 2020-2021 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#ifndef _LOONGARCH_TLS_H +#define _LOONGARCH_TLS_H 1 + +#include + +#ifndef __ASSEMBLER__ +# include +# include +# include +# include + +register void *__thread_self asm ("$tp"); /* FIXME */ +# define READ_THREAD_POINTER() ({ __thread_self; }) + +/* Get system call information. */ +# include + +/* The TP points to the start of the thread blocks. */ +# define TLS_DTV_AT_TP 1 +# define TLS_TCB_AT_TP 0 + +/* Get the thread descriptor definition. */ +# include + +typedef struct +{ + dtv_t *dtv; + void *private; +} tcbhead_t; + +/* This is the size of the initial TCB. Because our TCB is before the thread + pointer, we don't need this. */ +# define TLS_INIT_TCB_SIZE 0 + +/* Alignment requirements for the initial TCB. */ +# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread) + +/* This is the size of the TCB. Because our TCB is before the thread + pointer, we don't need this. */ +# define TLS_TCB_SIZE 0 + +/* Alignment requirements for the TCB. */ +# define TLS_TCB_ALIGN __alignof__ (struct pthread) + +/* This is the size we need before TCB - actually, it includes the TCB. */ +# define TLS_PRE_TCB_SIZE \ + (sizeof (struct pthread) \ + + ((sizeof (tcbhead_t) + TLS_TCB_ALIGN - 1) & ~(TLS_TCB_ALIGN - 1))) + +/* The thread pointer tp points to the end of the TCB. + The pthread_descr structure is immediately in front of the TCB. */ +# define TLS_TCB_OFFSET 0 + +/* Install the dtv pointer. The pointer passed is to the element with + index -1 which contain the length. */ +# define INSTALL_DTV(tcbp, dtvp) \ + (((tcbhead_t *) (tcbp))[-1].dtv = (dtvp) + 1) + +/* Install new dtv for current thread. */ +# define INSTALL_NEW_DTV(dtv) \ + (THREAD_DTV() = (dtv)) + +/* Return dtv of given thread descriptor. */ +# define GET_DTV(tcbp) \ + (((tcbhead_t *) (tcbp))[-1].dtv) + +/* Code to initially initialize the thread pointer. */ +# define TLS_INIT_TP(tcbp) \ + ({ __thread_self = (char*)tcbp + TLS_TCB_OFFSET; NULL; }) + +/* Return the address of the dtv for the current thread. */ +# define THREAD_DTV() \ + (((tcbhead_t *) (READ_THREAD_POINTER () - TLS_TCB_OFFSET))[-1].dtv) + +/* Return the thread descriptor for the current thread. */ +# define THREAD_SELF \ + ((struct pthread *) (READ_THREAD_POINTER () \ + - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE)) + +/* Value passed to 'clone' for initialization of the thread register. */ +# define TLS_DEFINE_INIT_TP(tp, pd) \ + void *tp = (void *) (pd) + TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE + +/* Informs libthread_db that the thread pointer is register 2, which is used + * to know how to do THREAD_SELF. */ +# define DB_THREAD_SELF \ + REGISTER (64, 64, 2 * 8, - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE) + +/* Access to data in the thread descriptor is easy. */ +# define THREAD_GETMEM(descr, member) \ + descr->member +# define THREAD_GETMEM_NC(descr, member, idx) \ + descr->member[idx] +# define THREAD_SETMEM(descr, member, value) \ + descr->member = (value) +# define THREAD_SETMEM_NC(descr, member, idx, value) \ + descr->member[idx] = (value) + +/* l_tls_offset == 0 is perfectly valid, so we have to use some different + value to mean unset l_tls_offset. */ +# define NO_TLS_OFFSET -1 + +/* Get and set the global scope generation counter in struct pthread. */ +# define THREAD_GSCOPE_IN_TCB 1 +# define THREAD_GSCOPE_FLAG_UNUSED 0 +# define THREAD_GSCOPE_FLAG_USED 1 +# define THREAD_GSCOPE_FLAG_WAIT 2 +# define THREAD_GSCOPE_RESET_FLAG() \ + do \ + { int __res \ + = atomic_exchange_rel (&THREAD_SELF->header.gscope_flag, \ + THREAD_GSCOPE_FLAG_UNUSED); \ + if (__res == THREAD_GSCOPE_FLAG_WAIT) \ + lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1, LLL_PRIVATE); \ + } \ + while (0) +# define THREAD_GSCOPE_SET_FLAG() \ + do \ + { \ + THREAD_SELF->header.gscope_flag = THREAD_GSCOPE_FLAG_USED; \ + atomic_write_barrier (); \ + } \ + while (0) +# define THREAD_GSCOPE_WAIT() \ + GL(dl_wait_lookup_done) () + +#endif /* __ASSEMBLER__ */ + +#endif /* tls.h */ diff --git a/sysdeps/loongarch/preconfigure b/sysdeps/loongarch/preconfigure new file mode 100644 index 00000000..26ffe884 --- /dev/null +++ b/sysdeps/loongarch/preconfigure @@ -0,0 +1,9 @@ +case "$machine" in +loongarch*) + base_machine=loongarch + machine=loongarch/lp64 + ;; +esac + +#TODO: this file is useless now. +#Maybe we can make use of it to get arch info from GCC to set env diff --git a/sysdeps/loongarch/pthread_atfork.c b/sysdeps/loongarch/pthread_atfork.c new file mode 100644 index 00000000..0f01d805 --- /dev/null +++ b/sysdeps/loongarch/pthread_atfork.c @@ -0,0 +1 @@ +#include diff --git a/sysdeps/loongarch/setjmp.S b/sysdeps/loongarch/setjmp.S new file mode 100644 index 00000000..da09a93c --- /dev/null +++ b/sysdeps/loongarch/setjmp.S @@ -0,0 +1,62 @@ +/* Copyright (C) 2020-2021 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include +#include + +ENTRY (_setjmp) + li.w a1,0 + b __sigsetjmp +END (_setjmp) +ENTRY (setjmp) + li.w a1,1 +END (setjmp) +ENTRY (__sigsetjmp) + REG_S ra, a0, 0*SZREG + REG_S sp, a0, 1*SZREG + REG_S x, a0, 2*SZREG + REG_S fp, a0, 3*SZREG + REG_S s0, a0, 4*SZREG + REG_S s1, a0, 5*SZREG + REG_S s2, a0, 6*SZREG + REG_S s3, a0, 7*SZREG + REG_S s4, a0, 8*SZREG + REG_S s5, a0, 9*SZREG + REG_S s6, a0, 10*SZREG + REG_S s7, a0, 11*SZREG + REG_S s8, a0, 12*SZREG + + FREG_S $f24, a0, 13*SZREG + 0*SZFREG + FREG_S $f25, a0, 13*SZREG + 1*SZFREG + FREG_S $f26, a0, 13*SZREG + 2*SZFREG + FREG_S $f27, a0, 13*SZREG + 3*SZFREG + FREG_S $f28, a0, 13*SZREG + 4*SZFREG + FREG_S $f29, a0, 13*SZREG + 5*SZFREG + FREG_S $f30, a0, 13*SZREG + 6*SZFREG + FREG_S $f31, a0, 13*SZREG + 7*SZFREG + +#if !IS_IN (libc) && IS_IN(rtld) + li.w v0, 0 + jirl zero,ra,0 +#else + b __sigjmp_save +#endif +END (__sigsetjmp) + +hidden_def (__sigsetjmp) +weak_alias (_setjmp, __GI__setjmp) diff --git a/sysdeps/loongarch/sfp-machine.h b/sysdeps/loongarch/sfp-machine.h new file mode 100644 index 00000000..b5c79bc0 --- /dev/null +++ b/sysdeps/loongarch/sfp-machine.h @@ -0,0 +1,79 @@ +#include +#include + +#define _FP_W_TYPE_SIZE 64 +#define _FP_W_TYPE unsigned long long +#define _FP_WS_TYPE signed long long +#define _FP_I_TYPE long long + +#define _FP_MUL_MEAT_S(R,X,Y) \ + _FP_MUL_MEAT_1_imm(_FP_WFRACBITS_S,R,X,Y) +#define _FP_MUL_MEAT_D(R,X,Y) \ + _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm) +#define _FP_MUL_MEAT_Q(R,X,Y) \ + _FP_MUL_MEAT_2_wide_3mul(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm) + +#define _FP_MUL_MEAT_DW_S(R,X,Y) \ + _FP_MUL_MEAT_DW_1_imm(_FP_WFRACBITS_S,R,X,Y) +#define _FP_MUL_MEAT_DW_D(R,X,Y) \ + _FP_MUL_MEAT_DW_1_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm) +#define _FP_MUL_MEAT_DW_Q(R,X,Y) \ + _FP_MUL_MEAT_DW_2_wide_3mul(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm) + +#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_imm(S,R,X,Y,_FP_DIV_HELP_imm) +#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_1_udiv_norm(D,R,X,Y) +#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_2_udiv(Q,R,X,Y) + +# define _FP_NANFRAC_S _FP_QNANBIT_S +# define _FP_NANFRAC_D _FP_QNANBIT_D +# define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0 + +#define _FP_NANSIGN_S 0 +#define _FP_NANSIGN_D 0 +#define _FP_NANSIGN_Q 0 + +#define _FP_KEEPNANFRACP 1 +#define _FP_QNANNEGATEDP 0 + +/* NaN payloads should be preserved for NAN2008. */ +# define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \ + do \ + { \ + R##_s = X##_s; \ + _FP_FRAC_COPY_##wc (R, X); \ + R##_c = FP_CLS_NAN; \ + } \ + while (0) + +#define _FP_DECL_EX fpu_control_t _fcw + +#define FP_ROUNDMODE (_fcw & 0x300) + +#define FP_RND_NEAREST FE_TONEAREST +#define FP_RND_ZERO FE_TOWARDZERO +#define FP_RND_PINF FE_UPWARD +#define FP_RND_MINF FE_DOWNWARD + +#define FP_EX_INVALID FE_INVALID +#define FP_EX_OVERFLOW FE_OVERFLOW +#define FP_EX_UNDERFLOW FE_UNDERFLOW +#define FP_EX_DIVZERO FE_DIVBYZERO +#define FP_EX_INEXACT FE_INEXACT + +#define _FP_TININESS_AFTER_ROUNDING 1 + +#ifdef __loongarch_hard_float +#define FP_INIT_ROUNDMODE \ +do { \ + _FPU_GETCW (_fcw); \ +} while (0) + +#define FP_HANDLE_EXCEPTIONS \ +do { \ + if (__builtin_expect (_fex, 0)) \ + _FPU_SETCW (_fcw | _fex | (_fex << 8)); \ +} while (0) +#define FP_TRAPPING_EXCEPTIONS ((_fcw << 16) & 0x1f0000) +#else +#define FP_INIT_ROUNDMODE _fcw = FP_RND_NEAREST +#endif diff --git a/sysdeps/loongarch/sotruss-lib.c b/sysdeps/loongarch/sotruss-lib.c new file mode 100644 index 00000000..124db440 --- /dev/null +++ b/sysdeps/loongarch/sotruss-lib.c @@ -0,0 +1,51 @@ +/* Copyright (C) 2020-2021 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#define HAVE_ARCH_PLTENTER +#define HAVE_ARCH_PLTEXIT + +#include + +ElfW(Addr) +la_loongarch_gnu_pltenter (ElfW(Sym) *sym __attribute__ ((unused)), + unsigned int ndx __attribute__ ((unused)), + uintptr_t *refcook, uintptr_t *defcook, + La_loongarch_regs *regs, unsigned int *flags, + const char *symname, long int *framesizep) +{ + print_enter (refcook, defcook, symname, + regs->lr_reg[0], regs->lr_reg[1], regs->lr_reg[2], + *flags); + + /* No need to copy anything, we will not need the parameters in any case. */ + *framesizep = 0; + + return sym->st_value; +} + +unsigned int +la_loongarch_gnu_pltexit (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, + const struct La_loongarch_regs *inregs, + struct La_loongarch_retval *outregs, + const char *symname) +{ + print_exit (refcook, defcook, symname, outregs->lrv_a0); + + return 0; +} diff --git a/sysdeps/loongarch/stack_chk_fail_local.c b/sysdeps/loongarch/stack_chk_fail_local.c new file mode 100644 index 00000000..305871fb --- /dev/null +++ b/sysdeps/loongarch/stack_chk_fail_local.c @@ -0,0 +1 @@ +#include diff --git a/sysdeps/loongarch/stackinfo.h b/sysdeps/loongarch/stackinfo.h new file mode 100644 index 00000000..5f5e6ad1 --- /dev/null +++ b/sysdeps/loongarch/stackinfo.h @@ -0,0 +1,33 @@ +/* Copyright (C) 2020-2021 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +/* This file contains a bit of information about the stack allocation + of the processor. */ + +#ifndef _STACKINFO_H +#define _STACKINFO_H 1 + +#include + +/* On LoongArch the stack grows down. */ +#define _STACK_GROWS_DOWN 1 + +/* Default to a non-executable stack. */ +#define DEFAULT_STACK_PERMS (PF_R | PF_W) + +#endif /* stackinfo.h */ diff --git a/sysdeps/loongarch/start.S b/sysdeps/loongarch/start.S new file mode 100644 index 00000000..cf0a14b5 --- /dev/null +++ b/sysdeps/loongarch/start.S @@ -0,0 +1,51 @@ +#define __ASSEMBLY__ 1 +#include +#include + +/* The entry point's job is to call __libc_start_main. Per the ABI, + a0 contains the address of a function to be passed to atexit. + __libc_start_main wants this in a5. */ + +/* +int +__libc_start_main (int (*main) (int, char **, char **), + int argc, + char **argv, + __typeof (main) init, + void (*fini) (void), + void (*rtld_fini) (void), + void *stack_end); +*/ + +ENTRY (ENTRY_POINT) + /* Terminate call stack by noting ra is undefined. Use a dummy + .cfi_label to force starting the FDE. */ + .cfi_label .Ldummy + cfi_undefined (1) + or a5, a0, zero /* rtld_fini */ + + /* 这个main必须要走GOT表拿到。因为main不一定是local的。 + 比如googletest就把main定义在动态库里了。 */ + la.got a0, t0, main +#ifdef __loongarch64 + ld.d a1, sp, 0 + addi.d a2, sp, SZREG +#elif defined __loongarch32 + ld.w a1, sp, 0 + addi.w a2, sp, SZREG +#endif + /* Adjust $sp for 16-aligned */ + srli.d sp, sp, 4 + slli.d sp, sp, 4 + + la.got a3, t0, __libc_csu_init + la.got a4, t0, __libc_csu_fini + or a6, sp, zero /* stack_end. */ + + la.got ra, t0, __libc_start_main + jirl ra, ra, 0 + + la.got ra, t0, abort + jirl ra, ra, 0 +END (ENTRY_POINT) + diff --git a/sysdeps/loongarch/stat.c b/sysdeps/loongarch/stat.c new file mode 100644 index 00000000..36461b87 --- /dev/null +++ b/sysdeps/loongarch/stat.c @@ -0,0 +1 @@ +#include diff --git a/sysdeps/loongarch/stat64.c b/sysdeps/loongarch/stat64.c new file mode 100644 index 00000000..0897282e --- /dev/null +++ b/sysdeps/loongarch/stat64.c @@ -0,0 +1 @@ +#include diff --git a/sysdeps/loongarch/sys/asm.h b/sysdeps/loongarch/sys/asm.h new file mode 100644 index 00000000..f64bfb2b --- /dev/null +++ b/sysdeps/loongarch/sys/asm.h @@ -0,0 +1,58 @@ +#ifndef _SYS_ASM_H +#define _SYS_ASM_H + +#include +#include + +/* Macros to handle different pointer/register sizes for 32/64-bit code. */ +#ifdef __loongarch64 +# define PTRLOG 3 +# define SZREG 8 +# define SZFREG 8 +# define REG_L ld.d +# define REG_S st.d +# define FREG_L fld.d +# define FREG_S fst.d +#elif defined __loongarch32 +# define PTRLOG 2 +# define SZREG 4 +# define SZFREG 4 +# define REG_L ld.w +# define REG_S st.w +# define FREG_L fld.w +# define FREG_S fst.w +#else +# error __loongarch_xlen must equal 32 or 64 +#endif + + +/* Declare leaf routine. */ +#define LEAF(symbol) \ + .text; \ + .globl symbol; \ + .align 3; \ + .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 + . */ + + +#include +#include +#include +#include "dl-tls.h" + +#define TLS_GD(x) \ + ({ void *__result; \ + asm ("la.tls.gd %0, " #x "\n\t" \ + : "=r" (__result)); \ + __tls_get_addr (__result); }) + +#define TLS_LD(x) TLS_GD(x) + +#define TLS_IE(x) \ + ({ void *__result; \ + asm ("la.tls.ie %0, " #x "\n\t" \ + "add.d %0, %0, $tp\n\t" \ + : "=r" (__result)); \ + __result; }) + +#define TLS_LE(x) \ + ({ void *__result; \ + asm ("la.tls.le %0, " #x "\n\t" \ + "add.d %0, %0, $tp\n\t" \ + : "=r" (__result)); \ + __result; }) diff --git a/sysdeps/loongarch/tst-audit.h b/sysdeps/loongarch/tst-audit.h new file mode 100644 index 00000000..d8d260eb --- /dev/null +++ b/sysdeps/loongarch/tst-audit.h @@ -0,0 +1,23 @@ +/* Copyright (C) 2020-2021 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#define pltenter la_loongarch_gnu_pltenter +#define pltexit la_loongarch_gnu_pltexit +#define La_regs La_loongarch_regs +#define La_retval La_loongarch_retval +#define int_retval lrv_a0 diff --git a/sysdeps/loongarch/warning-nop.c b/sysdeps/loongarch/warning-nop.c new file mode 100644 index 00000000..b76aae79 --- /dev/null +++ b/sysdeps/loongarch/warning-nop.c @@ -0,0 +1 @@ +#include diff --git a/sysdeps/unix/sysv/linux/loongarch/Implies b/sysdeps/unix/sysv/linux/loongarch/Implies new file mode 100644 index 00000000..e52b1ac3 --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/Implies @@ -0,0 +1 @@ +loongarch/nptl diff --git a/sysdeps/unix/sysv/linux/loongarch/Makefile b/sysdeps/unix/sysv/linux/loongarch/Makefile new file mode 100644 index 00000000..6f049aa9 --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/Makefile @@ -0,0 +1,17 @@ +ifeq ($(subdir),elf) +sysdep_routines += dl-vdso +ifeq ($(build-shared),yes) +# This is needed for DSO loading from static binaries. +sysdep-dl-routines += dl-static +endif +endif + +#ifeq ($(subdir),misc) +#sysdep_headers += sys/cachectl.h +#sysdep_routines += flush-icache +#endif + +ifeq ($(subdir),stdlib) +gen-as-const-headers += ucontext_i.sym +endif + diff --git a/sysdeps/unix/sysv/linux/loongarch/Versions b/sysdeps/unix/sysv/linux/loongarch/Versions new file mode 100644 index 00000000..453f276a --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/Versions @@ -0,0 +1,44 @@ +ld { + GLIBC_PRIVATE { + # used for loading by static libraries + _dl_var_init; + } +} +libc { + # The comment lines with "#errlist-compat" are magic; see errlist-compat.awk. + # When you get an error from errlist-compat.awk, you need to add a new + # version here. Don't do this blindly, since this means changing the ABI + # for all GNU/Linux configurations. + + GLIBC_2.0 { + #errlist-compat 123 + _sys_errlist; sys_errlist; _sys_nerr; sys_nerr; + + # Exception handling support functions from libgcc + __register_frame; __register_frame_table; __deregister_frame; + __frame_state_for; __register_frame_info_table; + + # Needed by gcc: + _flush_cache; + + # c* + cachectl; cacheflush; + + # s* + sysmips; + } + GLIBC_2.2 { + #errlist-compat 1134 + _sys_errlist; sys_errlist; _sys_nerr; sys_nerr; + + # _* + _test_and_set; + } + GLIBC_2.11 { + fallocate64; + } + GLIBC_PRIVATE { + # nptl/pthread_cond_timedwait.c uses INTERNAL_VSYSCALL(clock_gettime). + __vdso_clock_gettime; + } +} diff --git a/sysdeps/unix/sysv/linux/loongarch/atomic-machine.h b/sysdeps/unix/sysv/linux/loongarch/atomic-machine.h new file mode 100644 index 00000000..ac1948ea --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/atomic-machine.h @@ -0,0 +1,188 @@ +/* Copyright (C) 2020-2021 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#ifndef _LINUX_LOONGARCH_BITS_ATOMIC_H +#define _LINUX_LOONGARCH_BITS_ATOMIC_H 1 + +#include + +typedef int32_t atomic32_t; +typedef uint32_t uatomic32_t; + +typedef int64_t atomic64_t; +typedef uint64_t uatomic64_t; + +typedef intptr_t atomicptr_t; +typedef uintptr_t uatomicptr_t; +typedef intmax_t atomic_max_t; +typedef uintmax_t uatomic_max_t; + +#define atomic_full_barrier() __sync_synchronize () + +# define __HAVE_64B_ATOMICS (__loongarch_xlen >= 64) +# define USE_ATOMIC_COMPILER_BUILTINS 1 +# define ATOMIC_EXCHANGE_USES_CAS 0 + +/* Compare and exchange. + For all "bool" routines, we return FALSE if exchange succesful. */ + +# define __arch_compare_and_exchange_bool_8_int(mem, newval, oldval, model) \ + ({ \ + typeof (*mem) __oldval = (oldval); \ + !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \ + model, __ATOMIC_RELAXED); \ + }) + +# define __arch_compare_and_exchange_bool_16_int(mem, newval, oldval, model) \ + ({ \ + typeof (*mem) __oldval = (oldval); \ + !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \ + model, __ATOMIC_RELAXED); \ + }) + +# define __arch_compare_and_exchange_bool_32_int(mem, newval, oldval, model) \ + ({ \ + typeof (*mem) __oldval = (oldval); \ + !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \ + model, __ATOMIC_RELAXED); \ + }) + +# define __arch_compare_and_exchange_bool_64_int(mem, newval, oldval, model) \ + ({ \ + typeof (*mem) __oldval = (oldval); \ + !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \ + model, __ATOMIC_RELAXED); \ + }) + +# define __arch_compare_and_exchange_val_8_int(mem, newval, oldval, model) \ + ({ \ + typeof (*mem) __oldval = (oldval); \ + __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \ + model, __ATOMIC_RELAXED); \ + __oldval; \ + }) + +# define __arch_compare_and_exchange_val_16_int(mem, newval, oldval, model) \ + ({ \ + typeof (*mem) __oldval = (oldval); \ + __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \ + model, __ATOMIC_RELAXED); \ + __oldval; \ + }) + +# define __arch_compare_and_exchange_val_32_int(mem, newval, oldval, model) \ + ({ \ + typeof (*mem) __oldval = (oldval); \ + __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \ + model, __ATOMIC_RELAXED); \ + __oldval; \ + }) + +# define __arch_compare_and_exchange_val_64_int(mem, newval, oldval, model) \ + ({ \ + typeof (*mem) __oldval = (oldval); \ + __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \ + model, __ATOMIC_RELAXED); \ + __oldval; \ + }) + +/* Atomic compare and exchange. */ + +# define atomic_compare_and_exchange_bool_acq(mem, new, old) \ + __atomic_bool_bysize (__arch_compare_and_exchange_bool, int, \ + mem, new, old, __ATOMIC_ACQUIRE) + +# define atomic_compare_and_exchange_val_acq(mem, new, old) \ + __atomic_val_bysize (__arch_compare_and_exchange_val, int, \ + mem, new, old, __ATOMIC_ACQUIRE) + +# define atomic_compare_and_exchange_val_rel(mem, new, old) \ + __atomic_val_bysize (__arch_compare_and_exchange_val, int, \ + mem, new, old, __ATOMIC_RELEASE) + +/* Atomic exchange (without compare). */ + +# define __arch_exchange_8_int(mem, newval, model) \ + __atomic_exchange_n (mem, newval, model) + +# define __arch_exchange_16_int(mem, newval, model) \ + __atomic_exchange_n (mem, newval, model) + +# define __arch_exchange_32_int(mem, newval, model) \ + __atomic_exchange_n (mem, newval, model) + +# define __arch_exchange_64_int(mem, newval, model) \ + __atomic_exchange_n (mem, newval, model) + +# define atomic_exchange_acq(mem, value) \ + __atomic_val_bysize (__arch_exchange, int, mem, value, __ATOMIC_ACQUIRE) + +# define atomic_exchange_rel(mem, value) \ + __atomic_val_bysize (__arch_exchange, int, mem, value, __ATOMIC_RELEASE) + +/* Atomically add value and return the previous (unincremented) value. */ + +# define __arch_exchange_and_add_8_int(mem, value, model) \ + __atomic_fetch_add (mem, value, model) + +# define __arch_exchange_and_add_16_int(mem, value, model) \ + __atomic_fetch_add (mem, value, model) + +# define __arch_exchange_and_add_32_int(mem, value, model) \ + __atomic_fetch_add (mem, value, model) + +# define __arch_exchange_and_add_64_int(mem, value, model) \ + __atomic_fetch_add (mem, value, model) + +# define atomic_exchange_and_add_acq(mem, value) \ + __atomic_val_bysize (__arch_exchange_and_add, int, mem, value, \ + __ATOMIC_ACQUIRE) + +# define atomic_exchange_and_add_rel(mem, value) \ + __atomic_val_bysize (__arch_exchange_and_add, int, mem, value, \ + __ATOMIC_RELEASE) + +/* Miscellaneous. */ + +# define asm_amo(which, mem, value) ({ \ + __atomic_check_size (mem); \ + typeof (*mem) __tmp; \ + if (sizeof (__tmp) == 4) \ + asm volatile (which ".w""\t%0, %z2, %1" \ + : "=&r" (__tmp), "+ZB" (* (mem)) \ + : "rJ" (value)); \ + else if (sizeof (__tmp) == 8) \ + asm volatile (which ".d""\t%0, %z2, %1" \ + : "=&r" (__tmp), "+ZB" (* (mem)) \ + : "rJ" (value)); \ + else \ + abort (); \ + __tmp; }) + +# define atomic_max(mem, value) asm_amo ("ammax_db", mem, value) +# define atomic_min(mem, value) asm_amo ("ammin_db", mem, value) + +# define atomic_bit_test_set(mem, bit) \ + ({ typeof (*mem) __mask = (typeof (*mem))1 << (bit); \ + asm_amo("amor_db", mem, __mask) & __mask; }) + +# define catomic_exchange_and_add(mem, value) \ + atomic_exchange_and_add (mem, value) +# define catomic_max(mem, value) atomic_max (mem, value) + +#endif /* bits/atomic.h */ diff --git a/sysdeps/unix/sysv/linux/loongarch/bits/fcntl.h b/sysdeps/unix/sysv/linux/loongarch/bits/fcntl.h new file mode 100644 index 00000000..5ee2e976 --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/bits/fcntl.h @@ -0,0 +1,62 @@ +/* O_*, F_*, FD_* bit values for the generic Linux ABI. + Copyright (C) 2011-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Chris Metcalf , 2011. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#ifndef _FCNTL_H +# error "Never use directly; include instead." +#endif + +#include + +/* In 64-bit ISA files are always with 64bit off_t and F_*LK64 are the same as + non-64-bit versions. It will need to be revised for 128-bit. */ +#if __WORDSIZE == 64 +# define __O_LARGEFILE 0 + +# define F_GETLK64 5 /* Get record locking info. */ +# define F_SETLK64 6 /* Set record locking info (non-blocking). */ +# define F_SETLKW64 7 /* Set record locking info (blocking). */ +#endif + +struct flock + { + short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */ + short int l_whence; /* Where `l_start' is relative to (like `lseek'). */ +#ifndef __USE_FILE_OFFSET64 + __off_t l_start; /* Offset where the lock begins. */ + __off_t l_len; /* Size of the locked area; zero means until EOF. */ +#else + __off64_t l_start; /* Offset where the lock begins. */ + __off64_t l_len; /* Size of the locked area; zero means until EOF. */ +#endif + __pid_t l_pid; /* Process holding the lock. */ + }; + +#ifdef __USE_LARGEFILE64 +struct flock64 + { + short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */ + short int l_whence; /* Where `l_start' is relative to (like `lseek'). */ + __off64_t l_start; /* Offset where the lock begins. */ + __off64_t l_len; /* Size of the locked area; zero means until EOF. */ + __pid_t l_pid; /* Process holding the lock. */ + }; +#endif + +/* Include generic Linux declarations. */ +#include diff --git a/sysdeps/unix/sysv/linux/loongarch/bits/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 + . */ + +#if !defined (_SYS_AUXV_H) +# error "Never include directly; use instead." +#endif + +/* The following must match the kernel's . */ +/* 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 . */ + +/* The kernel header pollutes the namespace with the NR_OPEN symbol + and defines LINK_MAX although filesystems have different maxima. A + similar thing is true for OPEN_MAX: the limit can be changed at + runtime and therefore the macro must not be defined. Remove this + after including the header if necessary. */ +#ifndef NR_OPEN +# define __undef_NR_OPEN +#endif +#ifndef LINK_MAX +# define __undef_LINK_MAX +#endif +#ifndef OPEN_MAX +# define __undef_OPEN_MAX +#endif +#ifndef ARG_MAX +# define __undef_ARG_MAX +#endif + +/* The kernel sources contain a file with all the needed information. */ +#include + +/* Have to remove NR_OPEN? */ +#ifdef __undef_NR_OPEN +# undef NR_OPEN +# undef __undef_NR_OPEN +#endif +/* Have to remove LINK_MAX? */ +#ifdef __undef_LINK_MAX +# undef LINK_MAX +# undef __undef_LINK_MAX +#endif +/* Have to remove OPEN_MAX? */ +#ifdef __undef_OPEN_MAX +# undef OPEN_MAX +# undef __undef_OPEN_MAX +#endif +/* Have to remove ARG_MAX? */ +#ifdef __undef_ARG_MAX +# undef ARG_MAX +# undef __undef_ARG_MAX +#endif + +/* The number of data keys per process. */ +#define _POSIX_THREAD_KEYS_MAX 128 +/* This is the value this implementation supports. */ +#define PTHREAD_KEYS_MAX 1024 + +/* Controlling the iterations of destructors for thread-specific data. */ +#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 +/* Number of iterations this implementation does. */ +#define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS + +/* The number of threads per process. */ +#define _POSIX_THREAD_THREADS_MAX 64 +/* We have no predefined limit on the number of threads. */ +#undef PTHREAD_THREADS_MAX + +/* Maximum amount by which a process can descrease its asynchronous I/O + priority level. */ +#define AIO_PRIO_DELTA_MAX 20 + +/* Minimum size for a thread. At least two pages with 64k pages. */ +#define PTHREAD_STACK_MIN 131072 + +/* Maximum number of timer expiration overruns. */ +#define DELAYTIMER_MAX 2147483647 + +/* Maximum tty name length. */ +#define TTY_NAME_MAX 32 + +/* Maximum login name length. This is arbitrary. */ +#define LOGIN_NAME_MAX 256 + +/* Maximum host name length. */ +#define HOST_NAME_MAX 64 + +/* Maximum message queue priority level. */ +#define MQ_PRIO_MAX 32768 + +/* Maximum value the semaphore can have. */ +#define SEM_VALUE_MAX (2147483647) diff --git a/sysdeps/unix/sysv/linux/loongarch/bits/mman.h b/sysdeps/unix/sysv/linux/loongarch/bits/mman.h new file mode 100644 index 00000000..5a16f8ac --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/bits/mman.h @@ -0,0 +1,41 @@ +/* Definitions for POSIX memory map interface. Linux/MIPS version. + Copyright (C) 1997-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + + +#ifndef _SYS_MMAN_H +# error "Never use directly; include instead." +#endif + +#ifdef __USE_MISC +# define MAP_GROWSDOWN 0x00100 /* Stack-like segment. */ +# define MAP_DENYWRITE 0x00800 /* ETXTBSY. */ +# define MAP_EXECUTABLE 0x01000 /* Mark it as an executable. */ +# define MAP_LOCKED 0x02000 /* Lock the mapping. */ +# define MAP_NORESERVE 0x04000 /* Don't check for reservations. */ +# define MAP_POPULATE 0x08000 /* Populate (prefault) pagetables. */ +# define MAP_NONBLOCK 0x10000 /* Do not block on IO. */ +# define MAP_STACK 0x20000 /* Allocation is for a stack. */ +# define MAP_HUGETLB 0x40000 /* Create huge page mapping. */ +# define MAP_SYNC 0x80000 /* Perform synchronous page + faults for the mapping. */ +# define MAP_FIXED_NOREPLACE 0x100000 /* MAP_FIXED but do not unmap + underlying mapping. */ +#endif + +/* Include generic Linux declarations. */ +#include diff --git a/sysdeps/unix/sysv/linux/loongarch/bits/shm.h b/sysdeps/unix/sysv/linux/loongarch/bits/shm.h new file mode 100644 index 00000000..9e23092d --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/bits/shm.h @@ -0,0 +1,112 @@ +/* Copyright (C) 2011-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Chris Metcalf , 2011. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#ifndef _SYS_SHM_H +# error "Never include directly; use instead." +#endif + +#include +#include + +/* Permission flag for shmget. */ +#define SHM_R 0400 /* or S_IRUGO from */ +#define SHM_W 0200 /* or S_IWUGO from */ + +/* Flags for `shmat'. */ +#define SHM_RDONLY 010000 /* attach read-only else read-write */ +#define SHM_RND 020000 /* round attach address to SHMLBA */ +#define SHM_REMAP 040000 /* take-over region on attach */ +#define SHM_EXEC 0100000 /* execution access */ + +/* Commands for `shmctl'. */ +#define SHM_LOCK 11 /* lock segment (root only) */ +#define SHM_UNLOCK 12 /* unlock segment (root only) */ + +__BEGIN_DECLS + +/* Segment low boundary address multiple. */ +#define SHMLBA (__getpagesize () << 2) +extern int __getpagesize (void) __THROW __attribute__ ((__const__)); + + +/* Type to count number of attaches. */ +typedef unsigned long int shmatt_t; + +/* Data structure describing a shared memory segment. */ +struct shmid_ds + { + struct ipc_perm shm_perm; /* operation permission struct */ + size_t shm_segsz; /* size of segment in bytes */ + __time_t shm_atime; /* time of last shmat() */ +#if __WORDSIZE == 32 + unsigned long int __glibc_reserved1; +#endif + __time_t shm_dtime; /* time of last shmdt() */ +#if __WORDSIZE == 32 + unsigned long int __glibc_reserved2; +#endif + __time_t shm_ctime; /* time of last change by shmctl() */ +#if __WORDSIZE == 32 + unsigned long int __glibc_reserved3; +#endif + __pid_t shm_cpid; /* pid of creator */ + __pid_t shm_lpid; /* pid of last shmop */ + shmatt_t shm_nattch; /* number of current attaches */ + unsigned long int __glibc_reserved4; + unsigned long int __glibc_reserved5; + }; + +#ifdef __USE_MISC + +/* ipcs ctl commands */ +# define SHM_STAT 13 +# define SHM_INFO 14 +# define SHM_STAT_ANY 15 + +/* shm_mode upper byte flags */ +# define SHM_DEST 01000 /* segment will be destroyed on last detach */ +# define SHM_LOCKED 02000 /* segment will not be swapped */ +# define SHM_HUGETLB 04000 /* segment is mapped via hugetlb */ +# define SHM_NORESERVE 010000 /* don't check for reservations */ + +struct shminfo + { + unsigned long int shmmax; + unsigned long int shmmin; + unsigned long int shmmni; + unsigned long int shmseg; + unsigned long int shmall; + unsigned long int __glibc_reserved1; + unsigned long int __glibc_reserved2; + unsigned long int __glibc_reserved3; + unsigned long int __glibc_reserved4; + }; + +struct shm_info + { + int used_ids; + unsigned long int shm_tot; /* total allocated shm */ + unsigned long int shm_rss; /* total resident shm */ + unsigned long int shm_swp; /* total swapped shm */ + unsigned long int swap_attempts; + unsigned long int swap_successes; + }; + +#endif /* __USE_MISC */ + +__END_DECLS diff --git a/sysdeps/unix/sysv/linux/loongarch/bits/sigcontext.h b/sysdeps/unix/sysv/linux/loongarch/bits/sigcontext.h new file mode 100644 index 00000000..0f925b4c --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/bits/sigcontext.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1996, 1997, 1999 by Ralf Baechle + * Copyright (C) 1999 Silicon Graphics, Inc. + */ +#ifndef _BITS_SIGCONTEXT_H +#define _BITS_SIGCONTEXT_H + +/* + * Keep this struct definition in sync with the sigcontext fragment + * in arch/mips/kernel/asm-offsets.c + * + * Warning: this structure illdefined with sc_badvaddr being just an unsigned + * int so it was changed to unsigned long in 2.6.0-test1. This may break + * binary compatibility - no prisoners. + * DSP ASE in 2.6.12-rc4. Turn sc_mdhi and sc_mdlo into an array of four + * entries, add sc_dsp and sc_reserved for padding. No prisoners. + */ + +#define FPU_REG_WIDTH 256 +#define FPU_ALIGN __attribute__((aligned(32))) + +struct sigcontext { + unsigned long long sc_pc; + unsigned long long sc_regs[32]; + unsigned int sc_flags; + + unsigned int sc_fcsr; + unsigned int sc_vcsr; + unsigned long long sc_fcc; + + unsigned long long sc_scr[4]; + + union { + unsigned int val32[FPU_REG_WIDTH / 32]; + unsigned long long val64[FPU_REG_WIDTH / 64]; + } sc_fpregs[32] FPU_ALIGN; + unsigned char sc_reserved[4096] __attribute__((__aligned__(16))); + +}; + + +#endif /* _BITS_SIGCONTEXT_H */ diff --git a/sysdeps/unix/sysv/linux/loongarch/bits/signum.h b/sysdeps/unix/sysv/linux/loongarch/bits/signum.h new file mode 100644 index 00000000..3cad0b19 --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/bits/signum.h @@ -0,0 +1,58 @@ +/* Signal number definitions. Linux version. + Copyright (C) 1995-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _BITS_SIGNUM_H +#define _BITS_SIGNUM_H 1 + +#ifndef _SIGNAL_H +#error "Never include directly; use instead." +#endif + +#include + +/* Adjustments and additions to the signal number constants for + most Linux systems. */ + +#define SIGSTKFLT 16 /* Stack fault (obsolete). */ +#define SIGPWR 30 /* Power failure imminent. */ + +#undef SIGBUS +#define SIGBUS 7 +#undef SIGUSR1 +#define SIGUSR1 10 +#undef SIGUSR2 +#define SIGUSR2 12 +#undef SIGCHLD +#define SIGCHLD 17 +#undef SIGCONT +#define SIGCONT 18 +#undef SIGSTOP +#define SIGSTOP 19 +#undef SIGTSTP +#define SIGTSTP 20 +#undef SIGURG +#define SIGURG 23 +#undef SIGPOLL +#define SIGPOLL 29 +#undef SIGSYS +#define SIGSYS 31 + +#undef __SIGRTMAX +#define __SIGRTMAX 127 + +#endif /* included. */ diff --git a/sysdeps/unix/sysv/linux/loongarch/clone.S b/sysdeps/unix/sysv/linux/loongarch/clone.S new file mode 100644 index 00000000..f0fc566e --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/clone.S @@ -0,0 +1,98 @@ +/* Copyright (C) 2020-2021 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +/* clone() is even more special than fork() as it mucks with stacks + and invokes a function in the right context after its all over. */ + +#include +#include +#define _ERRNO_H 1 +#include +#include +#include "tcb-offsets.h" + +/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg, + void *parent_tidptr, void *tls, void *child_tidptr) */ + +ENTRY (__clone) + + /* Align stack to 16 or 8 bytes per the ABI. */ +#if _LOONGARCH_SIM == _ABILP64 + addi.d t0, zero, -16 +#elif _LOONGARCH_SIM == _ABILP32 + addi.w t0, zero, -8 +#endif + and a1, a1, t0 + + /* Sanity check arguments. */ + beqz a0, L (invalid) /* No NULL function pointers. */ + beqz a1, L (invalid) /* No NULL stack pointers. */ + + addi.d a1, a1, -16 /* Reserve argument save space. */ + st.d a0, a1, 0 /* Save function pointer. */ + st.d a3, a1, SZREG /* Save argument pointer. */ + + /* The syscall expects the args to be in different slots. */ + or a0, a2, zero + or a2, a4, zero + or a3, a6, zero + or a4, a5, zero + + /* Do the system call. */ + li.d a7,__NR_clone + syscall 0 + + blt a0, zero ,L (error) + beqz a0,L (thread_start) + + /* Successful return from the parent. */ + ret + +L (invalid): + li.d a0, -EINVAL + /* Something bad happened -- no child created. */ +L (error): + b __syscall_error + END (__clone) + +/* Load up the arguments to the function. Put this block of code in + its own function so that we can terminate the stack trace with our + debug info. */ + +ENTRY (__thread_start) +L (thread_start): + /* Terminate call stack by noting ra is undefined. Use a dummy + .cfi_label to force starting the FDE. */ + .cfi_label .Ldummy + cfi_undefined (1) + + /* Restore the arg for user's function. */ + ld.d a1, sp, 0 /* Function pointer. */ + ld.d a0, sp, SZREG /* Argument pointer. */ + + /* Call the user's function. */ + jirl ra, a1, 0 + + /* Call exit with the function's return value. */ + li.d a7, __NR_exit + syscall 0 + + END (__thread_start) + +libc_hidden_def (__clone) +weak_alias (__clone, clone) diff --git a/sysdeps/unix/sysv/linux/loongarch/configure b/sysdeps/unix/sysv/linux/loongarch/configure new file mode 100644 index 00000000..a402323a --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/configure @@ -0,0 +1,199 @@ +# This file is generated from configure.ac by Autoconf. DO NOT EDIT! + # Local configure fragment for sysdeps/unix/sysv/linux/loongarch. + +arch_minimum_kernel=4.15.0 + +libc_cv_loongarch_int_abi=no + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +__SIZEOF_INT__ __SIZEOF_LONG__ __SIZEOF_POINTER__ + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "4 4 4" >/dev/null 2>&1; then : + libc_cv_loongarch_int_abi=lp32 +fi +rm -f conftest* + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +__SIZEOF_INT__ __SIZEOF_LONG__ __SIZEOF_POINTER__ + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "4 8 8" >/dev/null 2>&1; then : + libc_cv_loongarch_int_abi=lp64 +fi +rm -f conftest* + +if test $libc_cv_loongarch_int_abi = no; then + as_fn_error $? "Unable to determine integer ABI" "$LINENO" 5 +fi + +config_vars="$config_vars +default-abi = $libc_cv_loongarch_int_abi" + +case $libc_cv_loongarch_int_abi in +lp32) + test -n "$libc_cv_slibdir" || +case "$prefix" in +/usr | /usr/) + libc_cv_slibdir='/lib32' + libc_cv_rtlddir='/lib32' + if test "$libdir" = '${exec_prefix}/lib'; then + libdir='${exec_prefix}/lib32'; + # Locale data can be shared between 32-bit and 64-bit libraries. + libc_cv_complocaledir='${exec_prefix}/lib/locale' + fi + ;; +esac + ;; +lp64) + test -n "$libc_cv_slibdir" || +case "$prefix" in +/usr | /usr/) + libc_cv_slibdir='/lib64' + libc_cv_rtlddir='/lib64' + if test "$libdir" = '${exec_prefix}/lib'; then + libdir='${exec_prefix}/lib64'; + # Locale data can be shared between 32-bit and 64-bit libraries. + libc_cv_complocaledir='${exec_prefix}/lib/locale' + fi + ;; +esac + ;; +esac + +ldd_rewrite_script=sysdeps/unix/sysv/linux/loongarch/ldd-rewrite.sed diff --git a/sysdeps/unix/sysv/linux/loongarch/configure.ac b/sysdeps/unix/sysv/linux/loongarch/configure.ac new file mode 100644 index 00000000..fef4f4d2 --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/configure.ac @@ -0,0 +1,27 @@ +sinclude(./aclocal.m4)dnl Autoconf lossage +GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. +# Local configure fragment for sysdeps/unix/sysv/linux/loongarch. + +arch_minimum_kernel=4.15.0 + +libc_cv_loongarch_int_abi=no +AC_EGREP_CPP(4 4 4, [__SIZEOF_INT__ __SIZEOF_LONG__ __SIZEOF_POINTER__ + ], libc_cv_loongarch_int_abi=lp32) +AC_EGREP_CPP(4 8 8, [__SIZEOF_INT__ __SIZEOF_LONG__ __SIZEOF_POINTER__ + ], libc_cv_loongarch_int_abi=lp64) +if test $libc_cv_loongarch_int_abi = no; then + AC_MSG_ERROR([Unable to determine integer ABI]) +fi + +LIBC_CONFIG_VAR([default-abi], [$libc_cv_loongarch_int_abi]) + +case $libc_cv_loongarch_int_abi in +lp32) + LIBC_SLIBDIR_RTLDDIR([lib32], [lib32]) + ;; +lp64) + LIBC_SLIBDIR_RTLDDIR([lib64], [lib]) + ;; +esac + +ldd_rewrite_script=sysdeps/unix/sysv/linux/loongarch/ldd-rewrite.sed diff --git a/sysdeps/unix/sysv/linux/loongarch/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 + . */ + +#include +#include + +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 + . */ + +#ifndef _CPU_FEATURES_LOONGARCH64_H +#define _CPU_FEATURES_LOONGARCH64_H + +#include +#include + +#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 + . */ + +/* 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 + . */ + +#include + +#ifdef SHARED + +void +_dl_var_init (void *array[]) +{ + /* It has to match "variables" below. */ + enum + { + DL_PAGESIZE = 0 + }; + + GLRO(dl_pagesize) = *((size_t *) array[DL_PAGESIZE]); +} + +#else + +static void *variables[] = +{ + &GLRO(dl_pagesize) +}; + +static void +_dl_unprotect_relro (struct link_map *l) +{ + ElfW(Addr) start = ((l->l_addr + l->l_relro_addr) + & ~(GLRO(dl_pagesize) - 1)); + ElfW(Addr) end = ((l->l_addr + l->l_relro_addr + l->l_relro_size) + & ~(GLRO(dl_pagesize) - 1)); + + if (start != end) + __mprotect ((void *) start, end - start, PROT_READ | PROT_WRITE); +} + +void +_dl_static_init (struct link_map *l) +{ + struct link_map *rtld_map = l; + struct r_scope_elem **scope; + const ElfW(Sym) *ref = NULL; + lookup_t loadbase; + void (*f) (void *[]); + size_t i; + + loadbase = _dl_lookup_symbol_x ("_dl_var_init", l, &ref, l->l_local_scope, + NULL, 0, 1, NULL); + + for (scope = l->l_local_scope; *scope != NULL; scope++) + for (i = 0; i < (*scope)->r_nlist; i++) + if ((*scope)->r_list[i] == loadbase) + { + rtld_map = (*scope)->r_list[i]; + break; + } + + if (ref != NULL) + { + f = (void (*) (void *[])) DL_SYMBOL_ADDRESS (loadbase, ref); + _dl_unprotect_relro (rtld_map); + f (variables); + _dl_protect_relro (rtld_map); + } +} + +#endif diff --git a/sysdeps/unix/sysv/linux/loongarch/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 + . */ + +#include +#include +#include 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,29 @@ +# 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 + +@order glibc.gmon.minarcs +@order glibc.gmon.maxarcs diff --git a/sysdeps/unix/sysv/linux/loongarch/getcontext.S b/sysdeps/unix/sysv/linux/loongarch/getcontext.S new file mode 100644 index 00000000..9c28d958 --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/getcontext.S @@ -0,0 +1,72 @@ +/* Save current context. + Copyright (C) 2009-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include "ucontext-macros.h" + +/* int getcontext (ucontext_t *ucp) */ + + .text +LEAF (__getcontext) + SAVE_INT_REG (ra, 1, a0) + SAVE_INT_REG (sp, 3, a0) + SAVE_INT_REG (zero, 4, a0) /* return 0 by overwriting a0. */ + SAVE_INT_REG (x, 21, a0) + SAVE_INT_REG (fp, 22, a0) + SAVE_INT_REG (s0, 23, a0) + SAVE_INT_REG (s1, 24, a0) + SAVE_INT_REG (s2, 25, a0) + SAVE_INT_REG (s3, 26, a0) + SAVE_INT_REG (s4, 27, a0) + SAVE_INT_REG (s5, 28, a0) + SAVE_INT_REG (s6, 29, a0) + SAVE_INT_REG (s7, 30, a0) + SAVE_INT_REG (s8, 31, a0) + st.d ra, a0, MCONTEXT_PC + +#ifndef __loongarch_soft_float + movfcsr2gr a1, $r0 + + SAVE_FP_REG (fs0, 24, a0) + SAVE_FP_REG (fs1, 25, a0) + SAVE_FP_REG (fs2, 26, a0) + SAVE_FP_REG (fs3, 27, a0) + SAVE_FP_REG (fs4, 28, a0) + SAVE_FP_REG (fs5, 29, a0) + SAVE_FP_REG (fs6, 30, a0) + SAVE_FP_REG (fs7, 31, a0) + + st.w a1, a0, MCONTEXT_FCSR +#endif /* __loongarch_soft_float */ + +/* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */ + li.d a3, _NSIG8 + addi.d a2, a0, UCONTEXT_SIGMASK + ori a1, zero,0 + li.d a0, SIG_BLOCK + + li.d a7, SYS_ify (rt_sigprocmask) + syscall 0 + blt a0, zero, 99f + + jirl $r0, $r1, 0 + +99: b __syscall_error + +PSEUDO_END (__getcontext) + +weak_alias (__getcontext, getcontext) diff --git a/sysdeps/unix/sysv/linux/loongarch/getpid.c b/sysdeps/unix/sysv/linux/loongarch/getpid.c new file mode 100644 index 00000000..5b4edb2b --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/getpid.c @@ -0,0 +1,54 @@ +/* getpid - get the pid. Linux/Loongarch version. + Copyright (C) 2015-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include + +#ifdef SHARED +# include +# include + +static pid_t +__getpid_syscall (void) +{ + return INLINE_SYSCALL (getpid, 0); +} + +# ifndef __getpid_type +# define __getpid_type __getpid +# endif + +# undef INIT_ARCH +# define INIT_ARCH() PREPARE_VERSION_KNOWN (linux26, LINUX_2_6) +libc_ifunc_hidden (__getpid_type, __getpid, (_dl_vdso_vsym ("__vdso_getpid", &linux26) ?: &__getpid_syscall)) +libc_hidden_def (__getpid) + +#else + +# include +# include + +pid_t +__getpid (void) +{ + return INLINE_SYSCALL (getpid, 0); +} +libc_hidden_def (__getpid); + +#endif +weak_alias (__getpid, getpid) +libc_hidden_weak (getpid) diff --git a/sysdeps/unix/sysv/linux/loongarch/gettimeofday.c b/sysdeps/unix/sysv/linux/loongarch/gettimeofday.c new file mode 100644 index 00000000..902b1a5d --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/gettimeofday.c @@ -0,0 +1,58 @@ +/* gettimeofday - get the time. Linux/LoongArch version. + Copyright (C) 2015-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include + +#ifdef SHARED + +# include +# include + +static int +__gettimeofday_syscall (struct timeval *tv, struct timezone *tz) +{ + return INLINE_SYSCALL (gettimeofday, 2, tv, tz); +} + +# ifndef __gettimeofday_type +# define __gettimeofday_type __gettimeofday +# endif + +# undef INIT_ARCH +# define INIT_ARCH() PREPARE_VERSION_KNOWN (linux26, LINUX_2_6) +/* If the vDSO is not available we fall back to syscall. */ +libc_ifunc_hidden (__gettimeofday_type, __gettimeofday, + (_dl_vdso_vsym ("__vdso_gettimeofday", &linux26) + ?: &__gettimeofday_syscall)) +libc_hidden_def (__gettimeofday) + +#else + +# include +# include + +int +__gettimeofday (struct timeval *tv, struct timezone *tz) +{ + return INLINE_SYSCALL (gettimeofday, 2, tv, tz); +} +libc_hidden_def (__gettimeofday) + +#endif +weak_alias (__gettimeofday, gettimeofday) +libc_hidden_weak (gettimeofday) diff --git a/sysdeps/unix/sysv/linux/loongarch/getuid.c b/sysdeps/unix/sysv/linux/loongarch/getuid.c new file mode 100644 index 00000000..4b3f95eb --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/getuid.c @@ -0,0 +1,60 @@ +/* getuid - get the uid. Linux/Loongarch version. + Copyright (C) 2015-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include + +#ifdef SHARED + +# include +# include + +libc_hidden_proto (getuid) + +extern __uid_t __getuid (void); +libc_hidden_proto (__getuid) + +static uid_t +__getuid_syscall(void) +{ + return INLINE_SYSCALL (getuid, 0); +} + +# ifndef __getuid_type +# define __getuid_type __getuid +# endif + +# undef INIT_ARCH +# define INIT_ARCH() PREPARE_VERSION_KNOWN (linux26, LINUX_2_6) +libc_ifunc_hidden (__getuid_type, __getuid, (_dl_vdso_vsym ("__vdso_getuid", &linux26) ?: &__getuid_syscall)) +libc_hidden_def (__getuid) + +#else + +# include +# include + +uid_t +__getuid(void) +{ + return INLINE_SYSCALL (getuid, 0); +} +libc_hidden_def (__getuid) + +#endif +weak_alias (__getuid, getuid) +libc_hidden_weak (getuid) diff --git a/sysdeps/unix/sysv/linux/loongarch/init-first.c b/sysdeps/unix/sysv/linux/loongarch/init-first.c new file mode 100644 index 00000000..5185a831 --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/init-first.c @@ -0,0 +1,57 @@ +/* Copyright (C) 2020-2021 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifdef SHARED +# include +# include + +long int (*VDSO_SYMBOL (getcpu)) (unsigned int *, unsigned int *, void *) + attribute_hidden; +long int (*VDSO_SYMBOL (gettimeofday)) (struct timeval *, void *) + attribute_hidden; +long int (*VDSO_SYMBOL (clock_gettime)) (clockid_t, struct timespec *) + attribute_hidden; +long int (*VDSO_SYMBOL (clock_getres)) (clockid_t, struct timespec *) + attribute_hidden; + +static inline void +_libc_vdso_platform_setup (void) +{ + PREPARE_VERSION_KNOWN (linux_version, LINUX_2_6); + + void *p = _dl_vdso_vsym ("__vdso_getcpu", &linux_version); + PTR_MANGLE (p); + VDSO_SYMBOL (getcpu) = p; + + p = _dl_vdso_vsym ("__vdso_gettimeofday", &linux_version); + PTR_MANGLE (p); + VDSO_SYMBOL (gettimeofday) = p; + + p = _dl_vdso_vsym ("__vdso_clock_gettime", &linux_version); + PTR_MANGLE (p); + VDSO_SYMBOL (clock_gettime) = p; + + p = _dl_vdso_vsym ("__vdso_clock_getres", &linux_version); + PTR_MANGLE (p); + VDSO_SYMBOL (clock_getres) = p; +} + +# define VDSO_SETUP _libc_vdso_platform_setup +#endif + +#include diff --git a/sysdeps/unix/sysv/linux/loongarch/ipc_priv.h b/sysdeps/unix/sysv/linux/loongarch/ipc_priv.h new file mode 100644 index 00000000..51583429 --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/ipc_priv.h @@ -0,0 +1,21 @@ +/* Old SysV permission definition for Linux. LoongArch version. + Copyright (C) 2020 Loongson Technology, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include /* For __key_t */ + +#define __IPC_64 0x0 diff --git a/sysdeps/unix/sysv/linux/loongarch/kernel-features.h b/sysdeps/unix/sysv/linux/loongarch/kernel-features.h new file mode 100644 index 00000000..c87c7967 --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/kernel-features.h @@ -0,0 +1,24 @@ +/* Copyright (C) 2020-2021 Free Software Foundation, Inc. + * + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include_next + +/* No support for PI mutexes or robust futexes before 4.20. */ +#if __LINUX_KERNEL_VERSION < 0x041400 +# undef __ASSUME_SET_ROBUST_LIST +#endif diff --git a/sysdeps/unix/sysv/linux/loongarch/ldd-rewrite.sed b/sysdeps/unix/sysv/linux/loongarch/ldd-rewrite.sed new file mode 100644 index 00000000..131c5f14 --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/ldd-rewrite.sed @@ -0,0 +1 @@ +s_^\(RTLDLIST=\)\(.*lib/\)\(ld-linux\)-\(loongarch64\)-\(lp64\)\(d*\)\(\.so\.[0-9.]*\)_\1"\2\3-\4-\5\7 \2\3-\4-\5d\7"_ diff --git a/sysdeps/unix/sysv/linux/loongarch/ldsodefs.h b/sysdeps/unix/sysv/linux/loongarch/ldsodefs.h new file mode 100644 index 00000000..c0fc7046 --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/ldsodefs.h @@ -0,0 +1,32 @@ +/* Copyright (C) 2020-2021 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#ifndef _LDSODEFS_H + +/* Get the real definitions. */ +#include_next + +/* Now define our stuff. */ + +/* We need special support to initialize DSO loaded for statically linked + binaries. */ +extern void _dl_static_init (struct link_map *map); +#undef DL_STATIC_INIT +#define DL_STATIC_INIT(map) _dl_static_init (map) + +#endif /* ldsodefs.h */ diff --git a/sysdeps/unix/sysv/linux/loongarch/libc-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 + . */ + +#ifndef SHARED +# include +# include + +extern struct cpu_features _dl_larch_cpu_features; + +# define ARCH_INIT_CPU_FEATURES() init_cpu_features (&_dl_larch_cpu_features) + +#endif +#include diff --git a/sysdeps/unix/sysv/linux/loongarch/libc-vdso.h b/sysdeps/unix/sysv/linux/loongarch/libc-vdso.h new file mode 100644 index 00000000..658c27a5 --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/libc-vdso.h @@ -0,0 +1,37 @@ +/* Copyright (C) 2020-2021 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#ifndef _LIBC_VDSO_H +#define _LIBC_VDSO_H + +#ifdef SHARED + +# include + +extern long int (*VDSO_SYMBOL (getcpu)) (unsigned int *, unsigned int *, void *) + attribute_hidden; +extern long int (*VDSO_SYMBOL (gettimeofday)) (struct timeval *, void *) + attribute_hidden; +extern long int (*VDSO_SYMBOL (clock_gettime)) (clockid_t, struct timespec *) + attribute_hidden; +extern long int (*VDSO_SYMBOL (clock_getres)) (clockid_t, struct timespec *) + attribute_hidden; + +#endif + +#endif /* _LIBC_VDSO_H */ diff --git a/sysdeps/unix/sysv/linux/loongarch/localplt.data b/sysdeps/unix/sysv/linux/loongarch/localplt.data new file mode 100644 index 00000000..0ed8650b --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/localplt.data @@ -0,0 +1,13 @@ +# See scripts/check-localplt.awk for how this file is processed. +# PLT use is required for the malloc family and for matherr because +# users can define their own functions and have library internals call them. +libc.so: calloc +libc.so: free +libc.so: malloc +libc.so: memalign +libc.so: realloc +# The TLS-enabled version of these functions is interposed from libc.so. +ld.so: _dl_signal_error +ld.so: _dl_catch_error +ld.so: _dl_signal_exception +ld.so: _dl_catch_exception diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/Implies b/sysdeps/unix/sysv/linux/loongarch/lp64/Implies new file mode 100644 index 00000000..117c2b8e --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/lp64/Implies @@ -0,0 +1,3 @@ +unix/sysv/linux/loongarch +unix/sysv/linux/generic +unix/sysv/linux/wordsize-64 diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/c++-types.data b/sysdeps/unix/sysv/linux/loongarch/lp64/c++-types.data new file mode 100644 index 00000000..ac925ccb --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/lp64/c++-types.data @@ -0,0 +1,67 @@ +blkcnt64_t:l +blkcnt_t:l +blksize_t:i +caddr_t:Pc +clockid_t:i +clock_t:l +daddr_t:i +dev_t:m +fd_mask:l +fsblkcnt64_t:m +fsblkcnt_t:m +fsfilcnt64_t:m +fsfilcnt_t:m +fsid_t:8__fsid_t +gid_t:j +id_t:j +ino64_t:m +ino_t:m +int16_t:s +int32_t:i +int64_t:l +int8_t:a +intptr_t:l +key_t:i +loff_t:l +mode_t:j +nlink_t:j +off64_t:l +off_t:l +pid_t:i +pthread_attr_t:14pthread_attr_t +pthread_barrier_t:17pthread_barrier_t +pthread_barrierattr_t:21pthread_barrierattr_t +pthread_cond_t:14pthread_cond_t +pthread_condattr_t:18pthread_condattr_t +pthread_key_t:j +pthread_mutex_t:15pthread_mutex_t +pthread_mutexattr_t:19pthread_mutexattr_t +pthread_once_t:i +pthread_rwlock_t:16pthread_rwlock_t +pthread_rwlockattr_t:20pthread_rwlockattr_t +pthread_spinlock_t:i +pthread_t:m +quad_t:l +register_t:l +rlim64_t:m +rlim_t:m +sigset_t:10__sigset_t +size_t:m +socklen_t:j +ssize_t:l +suseconds_t:l +time_t:l +u_char:h +uid_t:j +uint:j +u_int:j +u_int16_t:t +u_int32_t:j +u_int64_t:m +u_int8_t:h +ulong:m +u_long:m +u_quad_t:m +useconds_t:j +ushort:t +u_short:t diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/jmp_buf-macros.h b/sysdeps/unix/sysv/linux/loongarch/lp64/jmp_buf-macros.h new file mode 100644 index 00000000..e1c96e67 --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/lp64/jmp_buf-macros.h @@ -0,0 +1,41 @@ +/* Copyright (C) 2020-2021 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +/* Produced by this program: + + #include + #include + #include + #include + + int main (int argc, char **argv) + { + printf ("#define JMP_BUF_SIZE %d\n", sizeof (jmp_buf)); + printf ("#define JMP_BUF_ALIGN %d\n", __alignof__ (jmp_buf)); + printf ("#define SIGJMP_BUF_SIZE %d\n", sizeof (sigjmp_buf)); + printf ("#define SIGJMP_BUF_ALIGN %d\n", __alignof__ (sigjmp_buf)); + printf ("#define MASK_WAS_SAVED_OFFSET %d\n", offsetof (struct __jmp_buf_tag, __mask_was_saved)); + printf ("#define SAVED_MASK_OFFSET %d\n", offsetof (struct __jmp_buf_tag, __saved_mask)); + } */ + +# define JMP_BUF_SIZE 304 +# define JMP_BUF_ALIGN 8 +# define SIGJMP_BUF_SIZE 304 +# define SIGJMP_BUF_ALIGN 8 +# define MASK_WAS_SAVED_OFFSET 168 +# define SAVED_MASK_OFFSET 176 diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/ld.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/ld.abilist new file mode 100644 index 00000000..845f356c --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/lp64/ld.abilist @@ -0,0 +1,5 @@ +GLIBC_2.27 __libc_stack_end D 0x8 +GLIBC_2.27 __stack_chk_guard D 0x8 +GLIBC_2.27 __tls_get_addr F +GLIBC_2.27 _dl_mcount F +GLIBC_2.27 _r_debug D 0x28 diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libBrokenLocale.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libBrokenLocale.abilist new file mode 100644 index 00000000..18968d3c --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libBrokenLocale.abilist @@ -0,0 +1 @@ +GLIBC_2.27 __ctype_get_mb_cur_max F diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libanl.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libanl.abilist new file mode 100644 index 00000000..711fc87c --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libanl.abilist @@ -0,0 +1,4 @@ +GLIBC_2.27 gai_cancel F +GLIBC_2.27 gai_error F +GLIBC_2.27 gai_suspend F +GLIBC_2.27 getaddrinfo_a F diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist new file mode 100644 index 00000000..4d8733f2 --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist @@ -0,0 +1,2101 @@ +GLIBC_2.27 _Exit F +GLIBC_2.27 _IO_2_1_stderr_ D 0xe0 +GLIBC_2.27 _IO_2_1_stdin_ D 0xe0 +GLIBC_2.27 _IO_2_1_stdout_ D 0xe0 +GLIBC_2.27 _IO_adjust_column F +GLIBC_2.27 _IO_adjust_wcolumn F +GLIBC_2.27 _IO_default_doallocate F +GLIBC_2.27 _IO_default_finish F +GLIBC_2.27 _IO_default_pbackfail F +GLIBC_2.27 _IO_default_uflow F +GLIBC_2.27 _IO_default_xsgetn F +GLIBC_2.27 _IO_default_xsputn F +GLIBC_2.27 _IO_do_write F +GLIBC_2.27 _IO_doallocbuf F +GLIBC_2.27 _IO_fclose F +GLIBC_2.27 _IO_fdopen F +GLIBC_2.27 _IO_feof F +GLIBC_2.27 _IO_ferror F +GLIBC_2.27 _IO_fflush F +GLIBC_2.27 _IO_fgetpos F +GLIBC_2.27 _IO_fgetpos64 F +GLIBC_2.27 _IO_fgets F +GLIBC_2.27 _IO_file_attach F +GLIBC_2.27 _IO_file_close F +GLIBC_2.27 _IO_file_close_it F +GLIBC_2.27 _IO_file_doallocate F +GLIBC_2.27 _IO_file_finish F +GLIBC_2.27 _IO_file_fopen F +GLIBC_2.27 _IO_file_init F +GLIBC_2.27 _IO_file_jumps D 0xa8 +GLIBC_2.27 _IO_file_open F +GLIBC_2.27 _IO_file_overflow F +GLIBC_2.27 _IO_file_read F +GLIBC_2.27 _IO_file_seek F +GLIBC_2.27 _IO_file_seekoff F +GLIBC_2.27 _IO_file_setbuf F +GLIBC_2.27 _IO_file_stat F +GLIBC_2.27 _IO_file_sync F +GLIBC_2.27 _IO_file_underflow F +GLIBC_2.27 _IO_file_write F +GLIBC_2.27 _IO_file_xsputn F +GLIBC_2.27 _IO_flockfile F +GLIBC_2.27 _IO_flush_all F +GLIBC_2.27 _IO_flush_all_linebuffered F +GLIBC_2.27 _IO_fopen F +GLIBC_2.27 _IO_fprintf F +GLIBC_2.27 _IO_fputs F +GLIBC_2.27 _IO_fread F +GLIBC_2.27 _IO_free_backup_area F +GLIBC_2.27 _IO_free_wbackup_area F +GLIBC_2.27 _IO_fsetpos F +GLIBC_2.27 _IO_fsetpos64 F +GLIBC_2.27 _IO_ftell F +GLIBC_2.27 _IO_ftrylockfile F +GLIBC_2.27 _IO_funlockfile F +GLIBC_2.27 _IO_fwrite F +GLIBC_2.27 _IO_getc F +GLIBC_2.27 _IO_getline F +GLIBC_2.27 _IO_getline_info F +GLIBC_2.27 _IO_gets F +GLIBC_2.27 _IO_init F +GLIBC_2.27 _IO_init_marker F +GLIBC_2.27 _IO_init_wmarker F +GLIBC_2.27 _IO_iter_begin F +GLIBC_2.27 _IO_iter_end F +GLIBC_2.27 _IO_iter_file F +GLIBC_2.27 _IO_iter_next F +GLIBC_2.27 _IO_least_wmarker F +GLIBC_2.27 _IO_link_in F +GLIBC_2.27 _IO_list_all D 0x8 +GLIBC_2.27 _IO_list_lock F +GLIBC_2.27 _IO_list_resetlock F +GLIBC_2.27 _IO_list_unlock F +GLIBC_2.27 _IO_marker_delta F +GLIBC_2.27 _IO_marker_difference F +GLIBC_2.27 _IO_padn F +GLIBC_2.27 _IO_peekc_locked F +GLIBC_2.27 _IO_popen F +GLIBC_2.27 _IO_printf F +GLIBC_2.27 _IO_proc_close F +GLIBC_2.27 _IO_proc_open F +GLIBC_2.27 _IO_putc F +GLIBC_2.27 _IO_puts F +GLIBC_2.27 _IO_remove_marker F +GLIBC_2.27 _IO_seekmark F +GLIBC_2.27 _IO_seekoff F +GLIBC_2.27 _IO_seekpos F +GLIBC_2.27 _IO_seekwmark F +GLIBC_2.27 _IO_setb F +GLIBC_2.27 _IO_setbuffer F +GLIBC_2.27 _IO_setvbuf F +GLIBC_2.27 _IO_sgetn F +GLIBC_2.27 _IO_sprintf F +GLIBC_2.27 _IO_sputbackc F +GLIBC_2.27 _IO_sputbackwc F +GLIBC_2.27 _IO_sscanf F +GLIBC_2.27 _IO_str_init_readonly F +GLIBC_2.27 _IO_str_init_static F +GLIBC_2.27 _IO_str_overflow F +GLIBC_2.27 _IO_str_pbackfail F +GLIBC_2.27 _IO_str_seekoff F +GLIBC_2.27 _IO_str_underflow F +GLIBC_2.27 _IO_sungetc F +GLIBC_2.27 _IO_sungetwc F +GLIBC_2.27 _IO_switch_to_get_mode F +GLIBC_2.27 _IO_switch_to_main_wget_area F +GLIBC_2.27 _IO_switch_to_wbackup_area F +GLIBC_2.27 _IO_switch_to_wget_mode F +GLIBC_2.27 _IO_un_link F +GLIBC_2.27 _IO_ungetc F +GLIBC_2.27 _IO_unsave_markers F +GLIBC_2.27 _IO_unsave_wmarkers F +GLIBC_2.27 _IO_vfprintf F +GLIBC_2.27 _IO_vfscanf F +GLIBC_2.27 _IO_vsprintf F +GLIBC_2.27 _IO_wdefault_doallocate F +GLIBC_2.27 _IO_wdefault_finish F +GLIBC_2.27 _IO_wdefault_pbackfail F +GLIBC_2.27 _IO_wdefault_uflow F +GLIBC_2.27 _IO_wdefault_xsgetn F +GLIBC_2.27 _IO_wdefault_xsputn F +GLIBC_2.27 _IO_wdo_write F +GLIBC_2.27 _IO_wdoallocbuf F +GLIBC_2.27 _IO_wfile_jumps D 0xa8 +GLIBC_2.27 _IO_wfile_overflow F +GLIBC_2.27 _IO_wfile_seekoff F +GLIBC_2.27 _IO_wfile_sync F +GLIBC_2.27 _IO_wfile_underflow F +GLIBC_2.27 _IO_wfile_xsputn F +GLIBC_2.27 _IO_wmarker_delta F +GLIBC_2.27 _IO_wsetb F +GLIBC_2.27 ___brk_addr D 0x8 +GLIBC_2.27 __adjtimex F +GLIBC_2.27 __after_morecore_hook D 0x8 +GLIBC_2.27 __argz_count F +GLIBC_2.27 __argz_next F +GLIBC_2.27 __argz_stringify F +GLIBC_2.27 __asprintf F +GLIBC_2.27 __asprintf_chk F +GLIBC_2.27 __assert F +GLIBC_2.27 __assert_fail F +GLIBC_2.27 __assert_perror_fail F +GLIBC_2.27 __backtrace F +GLIBC_2.27 __backtrace_symbols F +GLIBC_2.27 __backtrace_symbols_fd F +GLIBC_2.27 __bsd_getpgrp F +GLIBC_2.27 __bzero F +GLIBC_2.27 __check_rhosts_file D 0x4 +GLIBC_2.27 __chk_fail F +GLIBC_2.27 __clone F +GLIBC_2.27 __close F +GLIBC_2.27 __cmsg_nxthdr F +GLIBC_2.27 __confstr_chk F +GLIBC_2.27 __connect F +GLIBC_2.27 __ctype_b_loc F +GLIBC_2.27 __ctype_get_mb_cur_max F +GLIBC_2.27 __ctype_tolower_loc F +GLIBC_2.27 __ctype_toupper_loc F +GLIBC_2.27 __curbrk D 0x8 +GLIBC_2.27 __cxa_at_quick_exit F +GLIBC_2.27 __cxa_atexit F +GLIBC_2.27 __cxa_finalize F +GLIBC_2.27 __cxa_thread_atexit_impl F +GLIBC_2.27 __cyg_profile_func_enter F +GLIBC_2.27 __cyg_profile_func_exit F +GLIBC_2.27 __daylight D 0x4 +GLIBC_2.27 __dcgettext F +GLIBC_2.27 __default_morecore F +GLIBC_2.27 __dgettext F +GLIBC_2.27 __dprintf_chk F +GLIBC_2.27 __dup2 F +GLIBC_2.27 __duplocale F +GLIBC_2.27 __endmntent F +GLIBC_2.27 __environ D 0x8 +GLIBC_2.27 __errno_location F +GLIBC_2.27 __explicit_bzero_chk F +GLIBC_2.27 __fbufsize F +GLIBC_2.27 __fcntl F +GLIBC_2.27 __fdelt_chk F +GLIBC_2.27 __fdelt_warn F +GLIBC_2.27 __ffs F +GLIBC_2.27 __fgets_chk F +GLIBC_2.27 __fgets_unlocked_chk F +GLIBC_2.27 __fgetws_chk F +GLIBC_2.27 __fgetws_unlocked_chk F +GLIBC_2.27 __finite F +GLIBC_2.27 __finitef F +GLIBC_2.27 __finitel F +GLIBC_2.27 __flbf F +GLIBC_2.27 __fork F +GLIBC_2.27 __fpending F +GLIBC_2.27 __fprintf_chk F +GLIBC_2.27 __fpu_control D 0x4 +GLIBC_2.27 __fpurge F +GLIBC_2.27 __fread_chk F +GLIBC_2.27 __fread_unlocked_chk F +GLIBC_2.27 __freadable F +GLIBC_2.27 __freading F +GLIBC_2.27 __free_hook D 0x8 +GLIBC_2.27 __freelocale F +GLIBC_2.27 __fsetlocking F +GLIBC_2.27 __fwprintf_chk F +GLIBC_2.27 __fwritable F +GLIBC_2.27 __fwriting F +GLIBC_2.27 __fxstat F +GLIBC_2.27 __fxstat64 F +GLIBC_2.27 __fxstatat F +GLIBC_2.27 __fxstatat64 F +GLIBC_2.27 __getauxval F +GLIBC_2.27 __getcwd_chk F +GLIBC_2.27 __getdelim F +GLIBC_2.27 __getdomainname_chk F +GLIBC_2.27 __getgroups_chk F +GLIBC_2.27 __gethostname_chk F +GLIBC_2.27 __getlogin_r_chk F +GLIBC_2.27 __getmntent_r F +GLIBC_2.27 __getpagesize F +GLIBC_2.27 __getpgid F +GLIBC_2.27 __getpid F +GLIBC_2.27 __gets_chk F +GLIBC_2.27 __gettimeofday F +GLIBC_2.27 __getwd_chk F +GLIBC_2.27 __gmtime_r F +GLIBC_2.27 __h_errno_location F +GLIBC_2.27 __isalnum_l F +GLIBC_2.27 __isalpha_l F +GLIBC_2.27 __isascii_l F +GLIBC_2.27 __isblank_l F +GLIBC_2.27 __iscntrl_l F +GLIBC_2.27 __isctype F +GLIBC_2.27 __isdigit_l F +GLIBC_2.27 __isgraph_l F +GLIBC_2.27 __isinf F +GLIBC_2.27 __isinff F +GLIBC_2.27 __isinfl F +GLIBC_2.27 __islower_l F +GLIBC_2.27 __isnan F +GLIBC_2.27 __isnanf F +GLIBC_2.27 __isnanl F +GLIBC_2.27 __isoc99_fscanf F +GLIBC_2.27 __isoc99_fwscanf F +GLIBC_2.27 __isoc99_scanf F +GLIBC_2.27 __isoc99_sscanf F +GLIBC_2.27 __isoc99_swscanf F +GLIBC_2.27 __isoc99_vfscanf F +GLIBC_2.27 __isoc99_vfwscanf F +GLIBC_2.27 __isoc99_vscanf F +GLIBC_2.27 __isoc99_vsscanf F +GLIBC_2.27 __isoc99_vswscanf F +GLIBC_2.27 __isoc99_vwscanf F +GLIBC_2.27 __isoc99_wscanf F +GLIBC_2.27 __isprint_l F +GLIBC_2.27 __ispunct_l F +GLIBC_2.27 __isspace_l F +GLIBC_2.27 __isupper_l F +GLIBC_2.27 __iswalnum_l F +GLIBC_2.27 __iswalpha_l F +GLIBC_2.27 __iswblank_l F +GLIBC_2.27 __iswcntrl_l F +GLIBC_2.27 __iswctype F +GLIBC_2.27 __iswctype_l F +GLIBC_2.27 __iswdigit_l F +GLIBC_2.27 __iswgraph_l F +GLIBC_2.27 __iswlower_l F +GLIBC_2.27 __iswprint_l F +GLIBC_2.27 __iswpunct_l F +GLIBC_2.27 __iswspace_l F +GLIBC_2.27 __iswupper_l F +GLIBC_2.27 __iswxdigit_l F +GLIBC_2.27 __isxdigit_l F +GLIBC_2.27 __ivaliduser F +GLIBC_2.27 __key_decryptsession_pk_LOCAL D 0x8 +GLIBC_2.27 __key_encryptsession_pk_LOCAL D 0x8 +GLIBC_2.27 __key_gendes_LOCAL D 0x8 +GLIBC_2.27 __libc_allocate_rtsig F +GLIBC_2.27 __libc_calloc F +GLIBC_2.27 __libc_current_sigrtmax F +GLIBC_2.27 __libc_current_sigrtmin F +GLIBC_2.27 __libc_free F +GLIBC_2.27 __libc_freeres F +GLIBC_2.27 __libc_init_first F +GLIBC_2.27 __libc_mallinfo F +GLIBC_2.27 __libc_malloc F +GLIBC_2.27 __libc_mallopt F +GLIBC_2.27 __libc_memalign F +GLIBC_2.27 __libc_pvalloc F +GLIBC_2.27 __libc_realloc F +GLIBC_2.27 __libc_sa_len F +GLIBC_2.27 __libc_start_main F +GLIBC_2.27 __libc_valloc F +GLIBC_2.27 __longjmp_chk F +GLIBC_2.27 __lseek F +GLIBC_2.27 __lxstat F +GLIBC_2.27 __lxstat64 F +GLIBC_2.27 __malloc_hook D 0x8 +GLIBC_2.27 __mbrlen F +GLIBC_2.27 __mbrtowc F +GLIBC_2.27 __mbsnrtowcs_chk F +GLIBC_2.27 __mbsrtowcs_chk F +GLIBC_2.27 __mbstowcs_chk F +GLIBC_2.27 __memalign_hook D 0x8 +GLIBC_2.27 __memcpy_chk F +GLIBC_2.27 __memmove_chk F +GLIBC_2.27 __mempcpy F +GLIBC_2.27 __mempcpy_chk F +GLIBC_2.27 __memset_chk F +GLIBC_2.27 __monstartup F +GLIBC_2.27 __morecore D 0x8 +GLIBC_2.27 __nanosleep F +GLIBC_2.27 __newlocale F +GLIBC_2.27 __nl_langinfo_l F +GLIBC_2.27 __nss_configure_lookup F +GLIBC_2.27 __nss_database_lookup F +GLIBC_2.27 __nss_hostname_digits_dots F +GLIBC_2.27 __nss_next F +GLIBC_2.27 __obstack_printf_chk F +GLIBC_2.27 __obstack_vprintf_chk F +GLIBC_2.27 __open F +GLIBC_2.27 __open64 F +GLIBC_2.27 __open64_2 F +GLIBC_2.27 __open_2 F +GLIBC_2.27 __openat64_2 F +GLIBC_2.27 __openat_2 F +GLIBC_2.27 __overflow F +GLIBC_2.27 __pipe F +GLIBC_2.27 __poll F +GLIBC_2.27 __poll_chk F +GLIBC_2.27 __posix_getopt F +GLIBC_2.27 __ppoll_chk F +GLIBC_2.27 __pread64 F +GLIBC_2.27 __pread64_chk F +GLIBC_2.27 __pread_chk F +GLIBC_2.27 __printf_chk F +GLIBC_2.27 __printf_fp F +GLIBC_2.27 __profile_frequency F +GLIBC_2.27 __progname D 0x8 +GLIBC_2.27 __progname_full D 0x8 +GLIBC_2.27 __ptsname_r_chk F +GLIBC_2.27 __pwrite64 F +GLIBC_2.27 __rawmemchr F +GLIBC_2.27 __rcmd_errstr D 0x8 +GLIBC_2.27 __read F +GLIBC_2.27 __read_chk F +GLIBC_2.27 __readlink_chk F +GLIBC_2.27 __readlinkat_chk F +GLIBC_2.27 __realloc_hook D 0x8 +GLIBC_2.27 __realpath_chk F +GLIBC_2.27 __recv_chk F +GLIBC_2.27 __recvfrom_chk F +GLIBC_2.27 __register_atfork F +GLIBC_2.27 __res_init F +GLIBC_2.27 __res_nclose F +GLIBC_2.27 __res_ninit F +GLIBC_2.27 __res_randomid F +GLIBC_2.27 __res_state F +GLIBC_2.27 __rpc_thread_createerr F +GLIBC_2.27 __rpc_thread_svc_fdset F +GLIBC_2.27 __rpc_thread_svc_max_pollfd F +GLIBC_2.27 __rpc_thread_svc_pollfd F +GLIBC_2.27 __sbrk F +GLIBC_2.27 __sched_cpualloc F +GLIBC_2.27 __sched_cpucount F +GLIBC_2.27 __sched_cpufree F +GLIBC_2.27 __sched_get_priority_max F +GLIBC_2.27 __sched_get_priority_min F +GLIBC_2.27 __sched_getparam F +GLIBC_2.27 __sched_getscheduler F +GLIBC_2.27 __sched_setscheduler F +GLIBC_2.27 __sched_yield F +GLIBC_2.27 __select F +GLIBC_2.27 __send F +GLIBC_2.27 __setmntent F +GLIBC_2.27 __setpgid F +GLIBC_2.27 __sigaction F +GLIBC_2.27 __signbit F +GLIBC_2.27 __signbitf F +GLIBC_2.27 __signbitl F +GLIBC_2.27 __sigpause F +GLIBC_2.27 __sigsetjmp F +GLIBC_2.27 __sigsuspend F +GLIBC_2.27 __snprintf_chk F +GLIBC_2.27 __sprintf_chk F +GLIBC_2.27 __stack_chk_fail F +GLIBC_2.27 __statfs F +GLIBC_2.27 __stpcpy F +GLIBC_2.27 __stpcpy_chk F +GLIBC_2.27 __stpncpy F +GLIBC_2.27 __stpncpy_chk F +GLIBC_2.27 __strcasecmp F +GLIBC_2.27 __strcasecmp_l F +GLIBC_2.27 __strcasestr F +GLIBC_2.27 __strcat_chk F +GLIBC_2.27 __strcoll_l F +GLIBC_2.27 __strcpy_chk F +GLIBC_2.27 __strdup F +GLIBC_2.27 __strerror_r F +GLIBC_2.27 __strfmon_l F +GLIBC_2.27 __strftime_l F +GLIBC_2.27 __strncasecmp_l F +GLIBC_2.27 __strncat_chk F +GLIBC_2.27 __strncpy_chk F +GLIBC_2.27 __strndup F +GLIBC_2.27 __strsep_g F +GLIBC_2.27 __strtod_internal F +GLIBC_2.27 __strtod_l F +GLIBC_2.27 __strtof_internal F +GLIBC_2.27 __strtof_l F +GLIBC_2.27 __strtok_r F +GLIBC_2.27 __strtol_internal F +GLIBC_2.27 __strtol_l F +GLIBC_2.27 __strtold_internal F +GLIBC_2.27 __strtold_l F +GLIBC_2.27 __strtoll_internal F +GLIBC_2.27 __strtoll_l F +GLIBC_2.27 __strtoul_internal F +GLIBC_2.27 __strtoul_l F +GLIBC_2.27 __strtoull_internal F +GLIBC_2.27 __strtoull_l F +GLIBC_2.27 __strverscmp F +GLIBC_2.27 __strxfrm_l F +GLIBC_2.27 __swprintf_chk F +GLIBC_2.27 __sysconf F +GLIBC_2.27 __syslog_chk F +GLIBC_2.27 __sysv_signal F +GLIBC_2.27 __timezone D 0x8 +GLIBC_2.27 __toascii_l F +GLIBC_2.27 __tolower_l F +GLIBC_2.27 __toupper_l F +GLIBC_2.27 __towctrans F +GLIBC_2.27 __towctrans_l F +GLIBC_2.27 __towlower_l F +GLIBC_2.27 __towupper_l F +GLIBC_2.27 __ttyname_r_chk F +GLIBC_2.27 __tzname D 0x10 +GLIBC_2.27 __uflow F +GLIBC_2.27 __underflow F +GLIBC_2.27 __uselocale F +GLIBC_2.27 __vasprintf_chk F +GLIBC_2.27 __vdprintf_chk F +GLIBC_2.27 __vfork F +GLIBC_2.27 __vfprintf_chk F +GLIBC_2.27 __vfscanf F +GLIBC_2.27 __vfwprintf_chk F +GLIBC_2.27 __vprintf_chk F +GLIBC_2.27 __vsnprintf F +GLIBC_2.27 __vsnprintf_chk F +GLIBC_2.27 __vsprintf_chk F +GLIBC_2.27 __vsscanf F +GLIBC_2.27 __vswprintf_chk F +GLIBC_2.27 __vsyslog_chk F +GLIBC_2.27 __vwprintf_chk F +GLIBC_2.27 __wait F +GLIBC_2.27 __waitpid F +GLIBC_2.27 __wcpcpy_chk F +GLIBC_2.27 __wcpncpy_chk F +GLIBC_2.27 __wcrtomb_chk F +GLIBC_2.27 __wcscasecmp_l F +GLIBC_2.27 __wcscat_chk F +GLIBC_2.27 __wcscoll_l F +GLIBC_2.27 __wcscpy_chk F +GLIBC_2.27 __wcsftime_l F +GLIBC_2.27 __wcsncasecmp_l F +GLIBC_2.27 __wcsncat_chk F +GLIBC_2.27 __wcsncpy_chk F +GLIBC_2.27 __wcsnrtombs_chk F +GLIBC_2.27 __wcsrtombs_chk F +GLIBC_2.27 __wcstod_internal F +GLIBC_2.27 __wcstod_l F +GLIBC_2.27 __wcstof_internal F +GLIBC_2.27 __wcstof_l F +GLIBC_2.27 __wcstol_internal F +GLIBC_2.27 __wcstol_l F +GLIBC_2.27 __wcstold_internal F +GLIBC_2.27 __wcstold_l F +GLIBC_2.27 __wcstoll_internal F +GLIBC_2.27 __wcstoll_l F +GLIBC_2.27 __wcstombs_chk F +GLIBC_2.27 __wcstoul_internal F +GLIBC_2.27 __wcstoul_l F +GLIBC_2.27 __wcstoull_internal F +GLIBC_2.27 __wcstoull_l F +GLIBC_2.27 __wcsxfrm_l F +GLIBC_2.27 __wctomb_chk F +GLIBC_2.27 __wctrans_l F +GLIBC_2.27 __wctype_l F +GLIBC_2.27 __wmemcpy_chk F +GLIBC_2.27 __wmemmove_chk F +GLIBC_2.27 __wmempcpy_chk F +GLIBC_2.27 __wmemset_chk F +GLIBC_2.27 __woverflow F +GLIBC_2.27 __wprintf_chk F +GLIBC_2.27 __write F +GLIBC_2.27 __wuflow F +GLIBC_2.27 __wunderflow F +GLIBC_2.27 __xmknod F +GLIBC_2.27 __xmknodat F +GLIBC_2.27 __xpg_basename F +GLIBC_2.27 __xpg_sigpause F +GLIBC_2.27 __xpg_strerror_r F +GLIBC_2.27 __xstat F +GLIBC_2.27 __xstat64 F +GLIBC_2.27 _authenticate F +GLIBC_2.27 _dl_mcount_wrapper F +GLIBC_2.27 _dl_mcount_wrapper_check F +GLIBC_2.27 _environ D 0x8 +GLIBC_2.27 _exit F +GLIBC_2.27 _flushlbf F +GLIBC_2.27 _libc_intl_domainname D 0x5 +GLIBC_2.27 _longjmp F +GLIBC_2.27 _mcleanup F +GLIBC_2.27 _mcount F +GLIBC_2.27 _nl_default_dirname D 0x12 +GLIBC_2.27 _nl_domain_bindings D 0x8 +GLIBC_2.27 _nl_msg_cat_cntr D 0x4 +GLIBC_2.27 _null_auth D 0x18 +GLIBC_2.27 _obstack_allocated_p F +GLIBC_2.27 _obstack_begin F +GLIBC_2.27 _obstack_begin_1 F +GLIBC_2.27 _obstack_free F +GLIBC_2.27 _obstack_memory_used F +GLIBC_2.27 _obstack_newchunk F +GLIBC_2.27 _res D 0x238 +GLIBC_2.27 _res_hconf D 0x48 +GLIBC_2.27 _rpc_dtablesize F +GLIBC_2.27 _seterr_reply F +GLIBC_2.27 _setjmp F +GLIBC_2.27 _sys_errlist D 0x2370 +GLIBC_2.27 _sys_nerr D 0x4 +GLIBC_2.27 _sys_siglist D 0x400 +GLIBC_2.27 _tolower F +GLIBC_2.27 _toupper F +GLIBC_2.27 a64l F +GLIBC_2.27 abort F +GLIBC_2.27 abs F +GLIBC_2.27 accept F +GLIBC_2.27 accept4 F +GLIBC_2.27 access F +GLIBC_2.27 acct F +GLIBC_2.27 addmntent F +GLIBC_2.27 addseverity F +GLIBC_2.27 adjtime F +GLIBC_2.27 adjtimex F +GLIBC_2.27 alarm F +GLIBC_2.27 aligned_alloc F +GLIBC_2.27 alphasort F +GLIBC_2.27 alphasort64 F +GLIBC_2.27 argp_err_exit_status D 0x4 +GLIBC_2.27 argp_error F +GLIBC_2.27 argp_failure F +GLIBC_2.27 argp_help F +GLIBC_2.27 argp_parse F +GLIBC_2.27 argp_program_bug_address D 0x8 +GLIBC_2.27 argp_program_version D 0x8 +GLIBC_2.27 argp_program_version_hook D 0x8 +GLIBC_2.27 argp_state_help F +GLIBC_2.27 argp_usage F +GLIBC_2.27 argz_add F +GLIBC_2.27 argz_add_sep F +GLIBC_2.27 argz_append F +GLIBC_2.27 argz_count F +GLIBC_2.27 argz_create F +GLIBC_2.27 argz_create_sep F +GLIBC_2.27 argz_delete F +GLIBC_2.27 argz_extract F +GLIBC_2.27 argz_insert F +GLIBC_2.27 argz_next F +GLIBC_2.27 argz_replace F +GLIBC_2.27 argz_stringify F +GLIBC_2.27 asctime F +GLIBC_2.27 asctime_r F +GLIBC_2.27 asprintf F +GLIBC_2.27 atof F +GLIBC_2.27 atoi F +GLIBC_2.27 atol F +GLIBC_2.27 atoll F +GLIBC_2.27 authdes_create F +GLIBC_2.27 authdes_getucred F +GLIBC_2.27 authdes_pk_create F +GLIBC_2.27 authnone_create F +GLIBC_2.27 authunix_create F +GLIBC_2.27 authunix_create_default F +GLIBC_2.27 backtrace F +GLIBC_2.27 backtrace_symbols F +GLIBC_2.27 backtrace_symbols_fd F +GLIBC_2.27 basename F +GLIBC_2.27 bcmp F +GLIBC_2.27 bcopy F +GLIBC_2.27 bind F +GLIBC_2.27 bind_textdomain_codeset F +GLIBC_2.27 bindresvport F +GLIBC_2.27 bindtextdomain F +GLIBC_2.27 brk F +GLIBC_2.27 bsd_signal F +GLIBC_2.27 bsearch F +GLIBC_2.27 btowc F +GLIBC_2.27 bzero F +GLIBC_2.27 c16rtomb F +GLIBC_2.27 c32rtomb F +GLIBC_2.27 calloc F +GLIBC_2.27 callrpc F +GLIBC_2.27 canonicalize_file_name F +GLIBC_2.27 capget F +GLIBC_2.27 capset F +GLIBC_2.27 catclose F +GLIBC_2.27 catgets F +GLIBC_2.27 catopen F +GLIBC_2.27 cbc_crypt F +GLIBC_2.27 cfgetispeed F +GLIBC_2.27 cfgetospeed F +GLIBC_2.27 cfmakeraw F +GLIBC_2.27 cfsetispeed F +GLIBC_2.27 cfsetospeed F +GLIBC_2.27 cfsetspeed F +GLIBC_2.27 chdir F +GLIBC_2.27 chflags F +GLIBC_2.27 chmod F +GLIBC_2.27 chown F +GLIBC_2.27 chroot F +GLIBC_2.27 clearenv F +GLIBC_2.27 clearerr F +GLIBC_2.27 clearerr_unlocked F +GLIBC_2.27 clnt_broadcast F +GLIBC_2.27 clnt_create F +GLIBC_2.27 clnt_pcreateerror F +GLIBC_2.27 clnt_perrno F +GLIBC_2.27 clnt_perror F +GLIBC_2.27 clnt_spcreateerror F +GLIBC_2.27 clnt_sperrno F +GLIBC_2.27 clnt_sperror F +GLIBC_2.27 clntraw_create F +GLIBC_2.27 clnttcp_create F +GLIBC_2.27 clntudp_bufcreate F +GLIBC_2.27 clntudp_create F +GLIBC_2.27 clntunix_create F +GLIBC_2.27 clock F +GLIBC_2.27 clock_adjtime F +GLIBC_2.27 clock_getcpuclockid F +GLIBC_2.27 clock_getres F +GLIBC_2.27 clock_gettime F +GLIBC_2.27 clock_nanosleep F +GLIBC_2.27 clock_settime F +GLIBC_2.27 clone F +GLIBC_2.27 close F +GLIBC_2.27 closedir F +GLIBC_2.27 closelog F +GLIBC_2.27 confstr F +GLIBC_2.27 connect F +GLIBC_2.27 copy_file_range F +GLIBC_2.27 copysign F +GLIBC_2.27 copysignf F +GLIBC_2.27 copysignl F +GLIBC_2.27 creat F +GLIBC_2.27 creat64 F +GLIBC_2.27 ctermid F +GLIBC_2.27 ctime F +GLIBC_2.27 ctime_r F +GLIBC_2.27 cuserid F +GLIBC_2.27 daemon F +GLIBC_2.27 daylight D 0x4 +GLIBC_2.27 dcgettext F +GLIBC_2.27 dcngettext F +GLIBC_2.27 delete_module F +GLIBC_2.27 des_setparity F +GLIBC_2.27 dgettext F +GLIBC_2.27 difftime F +GLIBC_2.27 dirfd F +GLIBC_2.27 dirname F +GLIBC_2.27 div F +GLIBC_2.27 dl_iterate_phdr F +GLIBC_2.27 dngettext F +GLIBC_2.27 dprintf F +GLIBC_2.27 drand48 F +GLIBC_2.27 drand48_r F +GLIBC_2.27 dup F +GLIBC_2.27 dup2 F +GLIBC_2.27 dup3 F +GLIBC_2.27 duplocale F +GLIBC_2.27 dysize F +GLIBC_2.27 eaccess F +GLIBC_2.27 ecb_crypt F +GLIBC_2.27 ecvt F +GLIBC_2.27 ecvt_r F +GLIBC_2.27 endaliasent F +GLIBC_2.27 endfsent F +GLIBC_2.27 endgrent F +GLIBC_2.27 endhostent F +GLIBC_2.27 endmntent F +GLIBC_2.27 endnetent F +GLIBC_2.27 endnetgrent F +GLIBC_2.27 endprotoent F +GLIBC_2.27 endpwent F +GLIBC_2.27 endrpcent F +GLIBC_2.27 endservent F +GLIBC_2.27 endsgent F +GLIBC_2.27 endspent F +GLIBC_2.27 endttyent F +GLIBC_2.27 endusershell F +GLIBC_2.27 endutent F +GLIBC_2.27 endutxent F +GLIBC_2.27 environ D 0x8 +GLIBC_2.27 envz_add F +GLIBC_2.27 envz_entry F +GLIBC_2.27 envz_get F +GLIBC_2.27 envz_merge F +GLIBC_2.27 envz_remove F +GLIBC_2.27 envz_strip F +GLIBC_2.27 epoll_create F +GLIBC_2.27 epoll_create1 F +GLIBC_2.27 epoll_ctl F +GLIBC_2.27 epoll_pwait F +GLIBC_2.27 epoll_wait F +GLIBC_2.27 erand48 F +GLIBC_2.27 erand48_r F +GLIBC_2.27 err F +GLIBC_2.27 error F +GLIBC_2.27 error_at_line F +GLIBC_2.27 error_message_count D 0x4 +GLIBC_2.27 error_one_per_line D 0x4 +GLIBC_2.27 error_print_progname D 0x8 +GLIBC_2.27 errx F +GLIBC_2.27 ether_aton F +GLIBC_2.27 ether_aton_r F +GLIBC_2.27 ether_hostton F +GLIBC_2.27 ether_line F +GLIBC_2.27 ether_ntoa F +GLIBC_2.27 ether_ntoa_r F +GLIBC_2.27 ether_ntohost F +GLIBC_2.27 euidaccess F +GLIBC_2.27 eventfd F +GLIBC_2.27 eventfd_read F +GLIBC_2.27 eventfd_write F +GLIBC_2.27 execl F +GLIBC_2.27 execle F +GLIBC_2.27 execlp F +GLIBC_2.27 execv F +GLIBC_2.27 execve F +GLIBC_2.27 execvp F +GLIBC_2.27 execvpe F +GLIBC_2.27 exit F +GLIBC_2.27 explicit_bzero F +GLIBC_2.27 faccessat F +GLIBC_2.27 fallocate F +GLIBC_2.27 fallocate64 F +GLIBC_2.27 fanotify_init F +GLIBC_2.27 fanotify_mark F +GLIBC_2.27 fattach F +GLIBC_2.27 fchdir F +GLIBC_2.27 fchflags F +GLIBC_2.27 fchmod F +GLIBC_2.27 fchmodat F +GLIBC_2.27 fchown F +GLIBC_2.27 fchownat F +GLIBC_2.27 fclose F +GLIBC_2.27 fcloseall F +GLIBC_2.27 fcntl F +GLIBC_2.27 fcvt F +GLIBC_2.27 fcvt_r F +GLIBC_2.27 fdatasync F +GLIBC_2.27 fdetach F +GLIBC_2.27 fdopen F +GLIBC_2.27 fdopendir F +GLIBC_2.27 feof F +GLIBC_2.27 feof_unlocked F +GLIBC_2.27 ferror F +GLIBC_2.27 ferror_unlocked F +GLIBC_2.27 fexecve F +GLIBC_2.27 fflush F +GLIBC_2.27 fflush_unlocked F +GLIBC_2.27 ffs F +GLIBC_2.27 ffsl F +GLIBC_2.27 ffsll F +GLIBC_2.27 fgetc F +GLIBC_2.27 fgetc_unlocked F +GLIBC_2.27 fgetgrent F +GLIBC_2.27 fgetgrent_r F +GLIBC_2.27 fgetpos F +GLIBC_2.27 fgetpos64 F +GLIBC_2.27 fgetpwent F +GLIBC_2.27 fgetpwent_r F +GLIBC_2.27 fgets F +GLIBC_2.27 fgets_unlocked F +GLIBC_2.27 fgetsgent F +GLIBC_2.27 fgetsgent_r F +GLIBC_2.27 fgetspent F +GLIBC_2.27 fgetspent_r F +GLIBC_2.27 fgetwc F +GLIBC_2.27 fgetwc_unlocked F +GLIBC_2.27 fgetws F +GLIBC_2.27 fgetws_unlocked F +GLIBC_2.27 fgetxattr F +GLIBC_2.27 fileno F +GLIBC_2.27 fileno_unlocked F +GLIBC_2.27 finite F +GLIBC_2.27 finitef F +GLIBC_2.27 finitel F +GLIBC_2.27 flistxattr F +GLIBC_2.27 flock F +GLIBC_2.27 flockfile F +GLIBC_2.27 fmemopen F +GLIBC_2.27 fmtmsg F +GLIBC_2.27 fnmatch F +GLIBC_2.27 fopen F +GLIBC_2.27 fopen64 F +GLIBC_2.27 fopencookie F +GLIBC_2.27 fork F +GLIBC_2.27 fpathconf F +GLIBC_2.27 fprintf F +GLIBC_2.27 fputc F +GLIBC_2.27 fputc_unlocked F +GLIBC_2.27 fputs F +GLIBC_2.27 fputs_unlocked F +GLIBC_2.27 fputwc F +GLIBC_2.27 fputwc_unlocked F +GLIBC_2.27 fputws F +GLIBC_2.27 fputws_unlocked F +GLIBC_2.27 fread F +GLIBC_2.27 fread_unlocked F +GLIBC_2.27 free F +GLIBC_2.27 freeaddrinfo F +GLIBC_2.27 freeifaddrs F +GLIBC_2.27 freelocale F +GLIBC_2.27 fremovexattr F +GLIBC_2.27 freopen F +GLIBC_2.27 freopen64 F +GLIBC_2.27 frexp F +GLIBC_2.27 frexpf F +GLIBC_2.27 frexpl F +GLIBC_2.27 fscanf F +GLIBC_2.27 fseek F +GLIBC_2.27 fseeko F +GLIBC_2.27 fseeko64 F +GLIBC_2.27 fsetpos F +GLIBC_2.27 fsetpos64 F +GLIBC_2.27 fsetxattr F +GLIBC_2.27 fstatfs F +GLIBC_2.27 fstatfs64 F +GLIBC_2.27 fstatvfs F +GLIBC_2.27 fstatvfs64 F +GLIBC_2.27 fsync F +GLIBC_2.27 ftell F +GLIBC_2.27 ftello F +GLIBC_2.27 ftello64 F +GLIBC_2.27 ftime F +GLIBC_2.27 ftok F +GLIBC_2.27 ftruncate F +GLIBC_2.27 ftruncate64 F +GLIBC_2.27 ftrylockfile F +GLIBC_2.27 fts64_children F +GLIBC_2.27 fts64_close F +GLIBC_2.27 fts64_open F +GLIBC_2.27 fts64_read F +GLIBC_2.27 fts64_set F +GLIBC_2.27 fts_children F +GLIBC_2.27 fts_close F +GLIBC_2.27 fts_open F +GLIBC_2.27 fts_read F +GLIBC_2.27 fts_set F +GLIBC_2.27 ftw F +GLIBC_2.27 ftw64 F +GLIBC_2.27 funlockfile F +GLIBC_2.27 futimens F +GLIBC_2.27 futimes F +GLIBC_2.27 futimesat F +GLIBC_2.27 fwide F +GLIBC_2.27 fwprintf F +GLIBC_2.27 fwrite F +GLIBC_2.27 fwrite_unlocked F +GLIBC_2.27 fwscanf F +GLIBC_2.27 gai_strerror F +GLIBC_2.27 gcvt F +GLIBC_2.27 get_avphys_pages F +GLIBC_2.27 get_current_dir_name F +GLIBC_2.27 get_myaddress F +GLIBC_2.27 get_nprocs F +GLIBC_2.27 get_nprocs_conf F +GLIBC_2.27 get_phys_pages F +GLIBC_2.27 getaddrinfo F +GLIBC_2.27 getaliasbyname F +GLIBC_2.27 getaliasbyname_r F +GLIBC_2.27 getaliasent F +GLIBC_2.27 getaliasent_r F +GLIBC_2.27 getauxval F +GLIBC_2.27 getc F +GLIBC_2.27 getc_unlocked F +GLIBC_2.27 getchar F +GLIBC_2.27 getchar_unlocked F +GLIBC_2.27 getcontext F +GLIBC_2.27 getcwd F +GLIBC_2.27 getdate F +GLIBC_2.27 getdate_err D 0x4 +GLIBC_2.27 getdate_r F +GLIBC_2.27 getdelim F +GLIBC_2.27 getdirentries F +GLIBC_2.27 getdirentries64 F +GLIBC_2.27 getdomainname F +GLIBC_2.27 getdtablesize F +GLIBC_2.27 getegid F +GLIBC_2.27 getentropy F +GLIBC_2.27 getenv F +GLIBC_2.27 geteuid F +GLIBC_2.27 getfsent F +GLIBC_2.27 getfsfile F +GLIBC_2.27 getfsspec F +GLIBC_2.27 getgid F +GLIBC_2.27 getgrent F +GLIBC_2.27 getgrent_r F +GLIBC_2.27 getgrgid F +GLIBC_2.27 getgrgid_r F +GLIBC_2.27 getgrnam F +GLIBC_2.27 getgrnam_r F +GLIBC_2.27 getgrouplist F +GLIBC_2.27 getgroups F +GLIBC_2.27 gethostbyaddr F +GLIBC_2.27 gethostbyaddr_r F +GLIBC_2.27 gethostbyname F +GLIBC_2.27 gethostbyname2 F +GLIBC_2.27 gethostbyname2_r F +GLIBC_2.27 gethostbyname_r F +GLIBC_2.27 gethostent F +GLIBC_2.27 gethostent_r F +GLIBC_2.27 gethostid F +GLIBC_2.27 gethostname F +GLIBC_2.27 getifaddrs F +GLIBC_2.27 getipv4sourcefilter F +GLIBC_2.27 getitimer F +GLIBC_2.27 getline F +GLIBC_2.27 getloadavg F +GLIBC_2.27 getlogin F +GLIBC_2.27 getlogin_r F +GLIBC_2.27 getmntent F +GLIBC_2.27 getmntent_r F +GLIBC_2.27 getmsg F +GLIBC_2.27 getnameinfo F +GLIBC_2.27 getnetbyaddr F +GLIBC_2.27 getnetbyaddr_r F +GLIBC_2.27 getnetbyname F +GLIBC_2.27 getnetbyname_r F +GLIBC_2.27 getnetent F +GLIBC_2.27 getnetent_r F +GLIBC_2.27 getnetgrent F +GLIBC_2.27 getnetgrent_r F +GLIBC_2.27 getnetname F +GLIBC_2.27 getopt F +GLIBC_2.27 getopt_long F +GLIBC_2.27 getopt_long_only F +GLIBC_2.27 getpagesize F +GLIBC_2.27 getpass F +GLIBC_2.27 getpeername F +GLIBC_2.27 getpgid F +GLIBC_2.27 getpgrp F +GLIBC_2.27 getpid F +GLIBC_2.27 getpmsg F +GLIBC_2.27 getppid F +GLIBC_2.27 getpriority F +GLIBC_2.27 getprotobyname F +GLIBC_2.27 getprotobyname_r F +GLIBC_2.27 getprotobynumber F +GLIBC_2.27 getprotobynumber_r F +GLIBC_2.27 getprotoent F +GLIBC_2.27 getprotoent_r F +GLIBC_2.27 getpt F +GLIBC_2.27 getpublickey F +GLIBC_2.27 getpw F +GLIBC_2.27 getpwent F +GLIBC_2.27 getpwent_r F +GLIBC_2.27 getpwnam F +GLIBC_2.27 getpwnam_r F +GLIBC_2.27 getpwuid F +GLIBC_2.27 getpwuid_r F +GLIBC_2.27 getrandom F +GLIBC_2.27 getresgid F +GLIBC_2.27 getresuid F +GLIBC_2.27 getrlimit F +GLIBC_2.27 getrlimit64 F +GLIBC_2.27 getrpcbyname F +GLIBC_2.27 getrpcbyname_r F +GLIBC_2.27 getrpcbynumber F +GLIBC_2.27 getrpcbynumber_r F +GLIBC_2.27 getrpcent F +GLIBC_2.27 getrpcent_r F +GLIBC_2.27 getrpcport F +GLIBC_2.27 getrusage F +GLIBC_2.27 gets F +GLIBC_2.27 getsecretkey F +GLIBC_2.27 getservbyname F +GLIBC_2.27 getservbyname_r F +GLIBC_2.27 getservbyport F +GLIBC_2.27 getservbyport_r F +GLIBC_2.27 getservent F +GLIBC_2.27 getservent_r F +GLIBC_2.27 getsgent F +GLIBC_2.27 getsgent_r F +GLIBC_2.27 getsgnam F +GLIBC_2.27 getsgnam_r F +GLIBC_2.27 getsid F +GLIBC_2.27 getsockname F +GLIBC_2.27 getsockopt F +GLIBC_2.27 getsourcefilter F +GLIBC_2.27 getspent F +GLIBC_2.27 getspent_r F +GLIBC_2.27 getspnam F +GLIBC_2.27 getspnam_r F +GLIBC_2.27 getsubopt F +GLIBC_2.27 gettext F +GLIBC_2.27 gettimeofday F +GLIBC_2.27 getttyent F +GLIBC_2.27 getttynam F +GLIBC_2.27 getuid F +GLIBC_2.27 getusershell F +GLIBC_2.27 getutent F +GLIBC_2.27 getutent_r F +GLIBC_2.27 getutid F +GLIBC_2.27 getutid_r F +GLIBC_2.27 getutline F +GLIBC_2.27 getutline_r F +GLIBC_2.27 getutmp F +GLIBC_2.27 getutmpx F +GLIBC_2.27 getutxent F +GLIBC_2.27 getutxid F +GLIBC_2.27 getutxline F +GLIBC_2.27 getw F +GLIBC_2.27 getwc F +GLIBC_2.27 getwc_unlocked F +GLIBC_2.27 getwchar F +GLIBC_2.27 getwchar_unlocked F +GLIBC_2.27 getwd F +GLIBC_2.27 getxattr F +GLIBC_2.27 glob F +GLIBC_2.27 glob64 F +GLIBC_2.27 glob_pattern_p F +GLIBC_2.27 globfree F +GLIBC_2.27 globfree64 F +GLIBC_2.27 gmtime F +GLIBC_2.27 gmtime_r F +GLIBC_2.27 gnu_dev_major F +GLIBC_2.27 gnu_dev_makedev F +GLIBC_2.27 gnu_dev_minor F +GLIBC_2.27 gnu_get_libc_release F +GLIBC_2.27 gnu_get_libc_version F +GLIBC_2.27 grantpt F +GLIBC_2.27 group_member F +GLIBC_2.27 gsignal F +GLIBC_2.27 gtty F +GLIBC_2.27 h_errlist D 0x28 +GLIBC_2.27 h_nerr D 0x4 +GLIBC_2.27 hasmntopt F +GLIBC_2.27 hcreate F +GLIBC_2.27 hcreate_r F +GLIBC_2.27 hdestroy F +GLIBC_2.27 hdestroy_r F +GLIBC_2.27 herror F +GLIBC_2.27 host2netname F +GLIBC_2.27 hsearch F +GLIBC_2.27 hsearch_r F +GLIBC_2.27 hstrerror F +GLIBC_2.27 htonl F +GLIBC_2.27 htons F +GLIBC_2.27 iconv F +GLIBC_2.27 iconv_close F +GLIBC_2.27 iconv_open F +GLIBC_2.27 if_freenameindex F +GLIBC_2.27 if_indextoname F +GLIBC_2.27 if_nameindex F +GLIBC_2.27 if_nametoindex F +GLIBC_2.27 imaxabs F +GLIBC_2.27 imaxdiv F +GLIBC_2.27 in6addr_any D 0x10 +GLIBC_2.27 in6addr_loopback D 0x10 +GLIBC_2.27 index F +GLIBC_2.27 inet6_opt_append F +GLIBC_2.27 inet6_opt_find F +GLIBC_2.27 inet6_opt_finish F +GLIBC_2.27 inet6_opt_get_val F +GLIBC_2.27 inet6_opt_init F +GLIBC_2.27 inet6_opt_next F +GLIBC_2.27 inet6_opt_set_val F +GLIBC_2.27 inet6_option_alloc F +GLIBC_2.27 inet6_option_append F +GLIBC_2.27 inet6_option_find F +GLIBC_2.27 inet6_option_init F +GLIBC_2.27 inet6_option_next F +GLIBC_2.27 inet6_option_space F +GLIBC_2.27 inet6_rth_add F +GLIBC_2.27 inet6_rth_getaddr F +GLIBC_2.27 inet6_rth_init F +GLIBC_2.27 inet6_rth_reverse F +GLIBC_2.27 inet6_rth_segments F +GLIBC_2.27 inet6_rth_space F +GLIBC_2.27 inet_addr F +GLIBC_2.27 inet_aton F +GLIBC_2.27 inet_lnaof F +GLIBC_2.27 inet_makeaddr F +GLIBC_2.27 inet_netof F +GLIBC_2.27 inet_network F +GLIBC_2.27 inet_nsap_addr F +GLIBC_2.27 inet_nsap_ntoa F +GLIBC_2.27 inet_ntoa F +GLIBC_2.27 inet_ntop F +GLIBC_2.27 inet_pton F +GLIBC_2.27 init_module F +GLIBC_2.27 initgroups F +GLIBC_2.27 initstate F +GLIBC_2.27 initstate_r F +GLIBC_2.27 innetgr F +GLIBC_2.27 inotify_add_watch F +GLIBC_2.27 inotify_init F +GLIBC_2.27 inotify_init1 F +GLIBC_2.27 inotify_rm_watch F +GLIBC_2.27 insque F +GLIBC_2.27 ioctl F +GLIBC_2.27 iruserok F +GLIBC_2.27 iruserok_af F +GLIBC_2.27 isalnum F +GLIBC_2.27 isalnum_l F +GLIBC_2.27 isalpha F +GLIBC_2.27 isalpha_l F +GLIBC_2.27 isascii F +GLIBC_2.27 isastream F +GLIBC_2.27 isatty F +GLIBC_2.27 isblank F +GLIBC_2.27 isblank_l F +GLIBC_2.27 iscntrl F +GLIBC_2.27 iscntrl_l F +GLIBC_2.27 isctype F +GLIBC_2.27 isdigit F +GLIBC_2.27 isdigit_l F +GLIBC_2.27 isfdtype F +GLIBC_2.27 isgraph F +GLIBC_2.27 isgraph_l F +GLIBC_2.27 isinf F +GLIBC_2.27 isinff F +GLIBC_2.27 isinfl F +GLIBC_2.27 islower F +GLIBC_2.27 islower_l F +GLIBC_2.27 isnan F +GLIBC_2.27 isnanf F +GLIBC_2.27 isnanl F +GLIBC_2.27 isprint F +GLIBC_2.27 isprint_l F +GLIBC_2.27 ispunct F +GLIBC_2.27 ispunct_l F +GLIBC_2.27 isspace F +GLIBC_2.27 isspace_l F +GLIBC_2.27 isupper F +GLIBC_2.27 isupper_l F +GLIBC_2.27 iswalnum F +GLIBC_2.27 iswalnum_l F +GLIBC_2.27 iswalpha F +GLIBC_2.27 iswalpha_l F +GLIBC_2.27 iswblank F +GLIBC_2.27 iswblank_l F +GLIBC_2.27 iswcntrl F +GLIBC_2.27 iswcntrl_l F +GLIBC_2.27 iswctype F +GLIBC_2.27 iswctype_l F +GLIBC_2.27 iswdigit F +GLIBC_2.27 iswdigit_l F +GLIBC_2.27 iswgraph F +GLIBC_2.27 iswgraph_l F +GLIBC_2.27 iswlower F +GLIBC_2.27 iswlower_l F +GLIBC_2.27 iswprint F +GLIBC_2.27 iswprint_l F +GLIBC_2.27 iswpunct F +GLIBC_2.27 iswpunct_l F +GLIBC_2.27 iswspace F +GLIBC_2.27 iswspace_l F +GLIBC_2.27 iswupper F +GLIBC_2.27 iswupper_l F +GLIBC_2.27 iswxdigit F +GLIBC_2.27 iswxdigit_l F +GLIBC_2.27 isxdigit F +GLIBC_2.27 isxdigit_l F +GLIBC_2.27 jrand48 F +GLIBC_2.27 jrand48_r F +GLIBC_2.27 key_decryptsession F +GLIBC_2.27 key_decryptsession_pk F +GLIBC_2.27 key_encryptsession F +GLIBC_2.27 key_encryptsession_pk F +GLIBC_2.27 key_gendes F +GLIBC_2.27 key_get_conv F +GLIBC_2.27 key_secretkey_is_set F +GLIBC_2.27 key_setnet F +GLIBC_2.27 key_setsecret F +GLIBC_2.27 kill F +GLIBC_2.27 killpg F +GLIBC_2.27 klogctl F +GLIBC_2.27 l64a F +GLIBC_2.27 labs F +GLIBC_2.27 lchmod F +GLIBC_2.27 lchown F +GLIBC_2.27 lckpwdf F +GLIBC_2.27 lcong48 F +GLIBC_2.27 lcong48_r F +GLIBC_2.27 ldexp F +GLIBC_2.27 ldexpf F +GLIBC_2.27 ldexpl F +GLIBC_2.27 ldiv F +GLIBC_2.27 lfind F +GLIBC_2.27 lgetxattr F +GLIBC_2.27 link F +GLIBC_2.27 linkat F +GLIBC_2.27 listen F +GLIBC_2.27 listxattr F +GLIBC_2.27 llabs F +GLIBC_2.27 lldiv F +GLIBC_2.27 llistxattr F +GLIBC_2.27 llseek F +GLIBC_2.27 localeconv F +GLIBC_2.27 localtime F +GLIBC_2.27 localtime_r F +GLIBC_2.27 lockf F +GLIBC_2.27 lockf64 F +GLIBC_2.27 longjmp F +GLIBC_2.27 lrand48 F +GLIBC_2.27 lrand48_r F +GLIBC_2.27 lremovexattr F +GLIBC_2.27 lsearch F +GLIBC_2.27 lseek F +GLIBC_2.27 lseek64 F +GLIBC_2.27 lsetxattr F +GLIBC_2.27 lutimes F +GLIBC_2.27 madvise F +GLIBC_2.27 makecontext F +GLIBC_2.27 mallinfo F +GLIBC_2.27 malloc F +GLIBC_2.27 malloc_info F +GLIBC_2.27 malloc_stats F +GLIBC_2.27 malloc_trim F +GLIBC_2.27 malloc_usable_size F +GLIBC_2.27 mallopt F +GLIBC_2.27 mallwatch D 0x8 +GLIBC_2.27 mblen F +GLIBC_2.27 mbrlen F +GLIBC_2.27 mbrtoc16 F +GLIBC_2.27 mbrtoc32 F +GLIBC_2.27 mbrtowc F +GLIBC_2.27 mbsinit F +GLIBC_2.27 mbsnrtowcs F +GLIBC_2.27 mbsrtowcs F +GLIBC_2.27 mbstowcs F +GLIBC_2.27 mbtowc F +GLIBC_2.27 mcheck F +GLIBC_2.27 mcheck_check_all F +GLIBC_2.27 mcheck_pedantic F +GLIBC_2.27 memalign F +GLIBC_2.27 memccpy F +GLIBC_2.27 memchr F +GLIBC_2.27 memcmp F +GLIBC_2.27 memcpy F +GLIBC_2.27 memfd_create F +GLIBC_2.27 memfrob F +GLIBC_2.27 memmem F +GLIBC_2.27 memmove F +GLIBC_2.27 mempcpy F +GLIBC_2.27 memrchr F +GLIBC_2.27 memset F +GLIBC_2.27 mincore F +GLIBC_2.27 mkdir F +GLIBC_2.27 mkdirat F +GLIBC_2.27 mkdtemp F +GLIBC_2.27 mkfifo F +GLIBC_2.27 mkfifoat F +GLIBC_2.27 mkostemp F +GLIBC_2.27 mkostemp64 F +GLIBC_2.27 mkostemps F +GLIBC_2.27 mkostemps64 F +GLIBC_2.27 mkstemp F +GLIBC_2.27 mkstemp64 F +GLIBC_2.27 mkstemps F +GLIBC_2.27 mkstemps64 F +GLIBC_2.27 mktemp F +GLIBC_2.27 mktime F +GLIBC_2.27 mlock F +GLIBC_2.27 mlock2 F +GLIBC_2.27 mlockall F +GLIBC_2.27 mmap F +GLIBC_2.27 mmap64 F +GLIBC_2.27 modf F +GLIBC_2.27 modff F +GLIBC_2.27 modfl F +GLIBC_2.27 moncontrol F +GLIBC_2.27 monstartup F +GLIBC_2.27 mount F +GLIBC_2.27 mprobe F +GLIBC_2.27 mprotect F +GLIBC_2.27 mrand48 F +GLIBC_2.27 mrand48_r F +GLIBC_2.27 mremap F +GLIBC_2.27 msgctl F +GLIBC_2.27 msgget F +GLIBC_2.27 msgrcv F +GLIBC_2.27 msgsnd F +GLIBC_2.27 msync F +GLIBC_2.27 mtrace F +GLIBC_2.27 munlock F +GLIBC_2.27 munlockall F +GLIBC_2.27 munmap F +GLIBC_2.27 muntrace F +GLIBC_2.27 name_to_handle_at F +GLIBC_2.27 nanosleep F +GLIBC_2.27 netname2host F +GLIBC_2.27 netname2user F +GLIBC_2.27 newlocale F +GLIBC_2.27 nfsservctl F +GLIBC_2.27 nftw F +GLIBC_2.27 nftw64 F +GLIBC_2.27 ngettext F +GLIBC_2.27 nice F +GLIBC_2.27 nl_langinfo F +GLIBC_2.27 nl_langinfo_l F +GLIBC_2.27 nrand48 F +GLIBC_2.27 nrand48_r F +GLIBC_2.27 ntohl F +GLIBC_2.27 ntohs F +GLIBC_2.27 ntp_adjtime F +GLIBC_2.27 ntp_gettime F +GLIBC_2.27 ntp_gettimex F +GLIBC_2.27 obstack_alloc_failed_handler D 0x8 +GLIBC_2.27 obstack_exit_failure D 0x4 +GLIBC_2.27 obstack_free F +GLIBC_2.27 obstack_printf F +GLIBC_2.27 obstack_vprintf F +GLIBC_2.27 on_exit F +GLIBC_2.27 open F +GLIBC_2.27 open64 F +GLIBC_2.27 open_by_handle_at F +GLIBC_2.27 open_memstream F +GLIBC_2.27 open_wmemstream F +GLIBC_2.27 openat F +GLIBC_2.27 openat64 F +GLIBC_2.27 opendir F +GLIBC_2.27 openlog F +GLIBC_2.27 optarg D 0x8 +GLIBC_2.27 opterr D 0x4 +GLIBC_2.27 optind D 0x4 +GLIBC_2.27 optopt D 0x4 +GLIBC_2.27 parse_printf_format F +GLIBC_2.27 passwd2des F +GLIBC_2.27 pathconf F +GLIBC_2.27 pause F +GLIBC_2.27 pclose F +GLIBC_2.27 perror F +GLIBC_2.27 personality F +GLIBC_2.27 pipe F +GLIBC_2.27 pipe2 F +GLIBC_2.27 pivot_root F +GLIBC_2.27 pkey_alloc F +GLIBC_2.27 pkey_free F +GLIBC_2.27 pkey_get F +GLIBC_2.27 pkey_mprotect F +GLIBC_2.27 pkey_set F +GLIBC_2.27 pmap_getmaps F +GLIBC_2.27 pmap_getport F +GLIBC_2.27 pmap_rmtcall F +GLIBC_2.27 pmap_set F +GLIBC_2.27 pmap_unset F +GLIBC_2.27 poll F +GLIBC_2.27 popen F +GLIBC_2.27 posix_fadvise F +GLIBC_2.27 posix_fadvise64 F +GLIBC_2.27 posix_fallocate F +GLIBC_2.27 posix_fallocate64 F +GLIBC_2.27 posix_madvise F +GLIBC_2.27 posix_memalign F +GLIBC_2.27 posix_openpt F +GLIBC_2.27 posix_spawn F +GLIBC_2.27 posix_spawn_file_actions_addclose F +GLIBC_2.27 posix_spawn_file_actions_adddup2 F +GLIBC_2.27 posix_spawn_file_actions_addopen F +GLIBC_2.27 posix_spawn_file_actions_destroy F +GLIBC_2.27 posix_spawn_file_actions_init F +GLIBC_2.27 posix_spawnattr_destroy F +GLIBC_2.27 posix_spawnattr_getflags F +GLIBC_2.27 posix_spawnattr_getpgroup F +GLIBC_2.27 posix_spawnattr_getschedparam F +GLIBC_2.27 posix_spawnattr_getschedpolicy F +GLIBC_2.27 posix_spawnattr_getsigdefault F +GLIBC_2.27 posix_spawnattr_getsigmask F +GLIBC_2.27 posix_spawnattr_init F +GLIBC_2.27 posix_spawnattr_setflags F +GLIBC_2.27 posix_spawnattr_setpgroup F +GLIBC_2.27 posix_spawnattr_setschedparam F +GLIBC_2.27 posix_spawnattr_setschedpolicy F +GLIBC_2.27 posix_spawnattr_setsigdefault F +GLIBC_2.27 posix_spawnattr_setsigmask F +GLIBC_2.27 posix_spawnp F +GLIBC_2.27 ppoll F +GLIBC_2.27 prctl F +GLIBC_2.27 pread F +GLIBC_2.27 pread64 F +GLIBC_2.27 preadv F +GLIBC_2.27 preadv2 F +GLIBC_2.27 preadv64 F +GLIBC_2.27 preadv64v2 F +GLIBC_2.27 printf F +GLIBC_2.27 printf_size F +GLIBC_2.27 printf_size_info F +GLIBC_2.27 prlimit F +GLIBC_2.27 prlimit64 F +GLIBC_2.27 process_vm_readv F +GLIBC_2.27 process_vm_writev F +GLIBC_2.27 profil F +GLIBC_2.27 program_invocation_name D 0x8 +GLIBC_2.27 program_invocation_short_name D 0x8 +GLIBC_2.27 pselect F +GLIBC_2.27 psiginfo F +GLIBC_2.27 psignal F +GLIBC_2.27 pthread_attr_destroy F +GLIBC_2.27 pthread_attr_getdetachstate F +GLIBC_2.27 pthread_attr_getinheritsched F +GLIBC_2.27 pthread_attr_getschedparam F +GLIBC_2.27 pthread_attr_getschedpolicy F +GLIBC_2.27 pthread_attr_getscope F +GLIBC_2.27 pthread_attr_init F +GLIBC_2.27 pthread_attr_setdetachstate F +GLIBC_2.27 pthread_attr_setinheritsched F +GLIBC_2.27 pthread_attr_setschedparam F +GLIBC_2.27 pthread_attr_setschedpolicy F +GLIBC_2.27 pthread_attr_setscope F +GLIBC_2.27 pthread_cond_broadcast F +GLIBC_2.27 pthread_cond_destroy F +GLIBC_2.27 pthread_cond_init F +GLIBC_2.27 pthread_cond_signal F +GLIBC_2.27 pthread_cond_timedwait F +GLIBC_2.27 pthread_cond_wait F +GLIBC_2.27 pthread_condattr_destroy F +GLIBC_2.27 pthread_condattr_init F +GLIBC_2.27 pthread_equal F +GLIBC_2.27 pthread_exit F +GLIBC_2.27 pthread_getschedparam F +GLIBC_2.27 pthread_mutex_destroy F +GLIBC_2.27 pthread_mutex_init F +GLIBC_2.27 pthread_mutex_lock F +GLIBC_2.27 pthread_mutex_unlock F +GLIBC_2.27 pthread_self F +GLIBC_2.27 pthread_setcancelstate F +GLIBC_2.27 pthread_setcanceltype F +GLIBC_2.27 pthread_setschedparam F +GLIBC_2.27 ptrace F +GLIBC_2.27 ptsname F +GLIBC_2.27 ptsname_r F +GLIBC_2.27 putc F +GLIBC_2.27 putc_unlocked F +GLIBC_2.27 putchar F +GLIBC_2.27 putchar_unlocked F +GLIBC_2.27 putenv F +GLIBC_2.27 putgrent F +GLIBC_2.27 putmsg F +GLIBC_2.27 putpmsg F +GLIBC_2.27 putpwent F +GLIBC_2.27 puts F +GLIBC_2.27 putsgent F +GLIBC_2.27 putspent F +GLIBC_2.27 pututline F +GLIBC_2.27 pututxline F +GLIBC_2.27 putw F +GLIBC_2.27 putwc F +GLIBC_2.27 putwc_unlocked F +GLIBC_2.27 putwchar F +GLIBC_2.27 putwchar_unlocked F +GLIBC_2.27 pvalloc F +GLIBC_2.27 pwrite F +GLIBC_2.27 pwrite64 F +GLIBC_2.27 pwritev F +GLIBC_2.27 pwritev2 F +GLIBC_2.27 pwritev64 F +GLIBC_2.27 pwritev64v2 F +GLIBC_2.27 qecvt F +GLIBC_2.27 qecvt_r F +GLIBC_2.27 qfcvt F +GLIBC_2.27 qfcvt_r F +GLIBC_2.27 qgcvt F +GLIBC_2.27 qsort F +GLIBC_2.27 qsort_r F +GLIBC_2.27 quick_exit F +GLIBC_2.27 quotactl F +GLIBC_2.27 raise F +GLIBC_2.27 rand F +GLIBC_2.27 rand_r F +GLIBC_2.27 random F +GLIBC_2.27 random_r F +GLIBC_2.27 rawmemchr F +GLIBC_2.27 rcmd F +GLIBC_2.27 rcmd_af F +GLIBC_2.27 re_comp F +GLIBC_2.27 re_compile_fastmap F +GLIBC_2.27 re_compile_pattern F +GLIBC_2.27 re_exec F +GLIBC_2.27 re_match F +GLIBC_2.27 re_match_2 F +GLIBC_2.27 re_search F +GLIBC_2.27 re_search_2 F +GLIBC_2.27 re_set_registers F +GLIBC_2.27 re_set_syntax F +GLIBC_2.27 re_syntax_options D 0x8 +GLIBC_2.27 read F +GLIBC_2.27 readahead F +GLIBC_2.27 readdir F +GLIBC_2.27 readdir64 F +GLIBC_2.27 readdir64_r F +GLIBC_2.27 readdir_r F +GLIBC_2.27 readlink F +GLIBC_2.27 readlinkat F +GLIBC_2.27 readv F +GLIBC_2.27 realloc F +GLIBC_2.27 reallocarray F +GLIBC_2.27 realpath F +GLIBC_2.27 reboot F +GLIBC_2.27 recv F +GLIBC_2.27 recvfrom F +GLIBC_2.27 recvmmsg F +GLIBC_2.27 recvmsg F +GLIBC_2.27 regcomp F +GLIBC_2.27 regerror F +GLIBC_2.27 regexec F +GLIBC_2.27 regfree F +GLIBC_2.27 register_printf_function F +GLIBC_2.27 register_printf_modifier F +GLIBC_2.27 register_printf_specifier F +GLIBC_2.27 register_printf_type F +GLIBC_2.27 registerrpc F +GLIBC_2.27 remap_file_pages F +GLIBC_2.27 remove F +GLIBC_2.27 removexattr F +GLIBC_2.27 remque F +GLIBC_2.27 rename F +GLIBC_2.27 renameat F +GLIBC_2.27 revoke F +GLIBC_2.27 rewind F +GLIBC_2.27 rewinddir F +GLIBC_2.27 rexec F +GLIBC_2.27 rexec_af F +GLIBC_2.27 rexecoptions D 0x4 +GLIBC_2.27 rindex F +GLIBC_2.27 rmdir F +GLIBC_2.27 rpc_createerr D 0x20 +GLIBC_2.27 rpmatch F +GLIBC_2.27 rresvport F +GLIBC_2.27 rresvport_af F +GLIBC_2.27 rtime F +GLIBC_2.27 ruserok F +GLIBC_2.27 ruserok_af F +GLIBC_2.27 ruserpass F +GLIBC_2.27 sbrk F +GLIBC_2.27 scalbn F +GLIBC_2.27 scalbnf F +GLIBC_2.27 scalbnl F +GLIBC_2.27 scandir F +GLIBC_2.27 scandir64 F +GLIBC_2.27 scandirat F +GLIBC_2.27 scandirat64 F +GLIBC_2.27 scanf F +GLIBC_2.27 sched_get_priority_max F +GLIBC_2.27 sched_get_priority_min F +GLIBC_2.27 sched_getaffinity F +GLIBC_2.27 sched_getcpu F +GLIBC_2.27 sched_getparam F +GLIBC_2.27 sched_getscheduler F +GLIBC_2.27 sched_rr_get_interval F +GLIBC_2.27 sched_setaffinity F +GLIBC_2.27 sched_setparam F +GLIBC_2.27 sched_setscheduler F +GLIBC_2.27 sched_yield F +GLIBC_2.27 secure_getenv F +GLIBC_2.27 seed48 F +GLIBC_2.27 seed48_r F +GLIBC_2.27 seekdir F +GLIBC_2.27 select F +GLIBC_2.27 semctl F +GLIBC_2.27 semget F +GLIBC_2.27 semop F +GLIBC_2.27 semtimedop F +GLIBC_2.27 send F +GLIBC_2.27 sendfile F +GLIBC_2.27 sendfile64 F +GLIBC_2.27 sendmmsg F +GLIBC_2.27 sendmsg F +GLIBC_2.27 sendto F +GLIBC_2.27 setaliasent F +GLIBC_2.27 setbuf F +GLIBC_2.27 setbuffer F +GLIBC_2.27 setcontext F +GLIBC_2.27 setdomainname F +GLIBC_2.27 setegid F +GLIBC_2.27 setenv F +GLIBC_2.27 seteuid F +GLIBC_2.27 setfsent F +GLIBC_2.27 setfsgid F +GLIBC_2.27 setfsuid F +GLIBC_2.27 setgid F +GLIBC_2.27 setgrent F +GLIBC_2.27 setgroups F +GLIBC_2.27 sethostent F +GLIBC_2.27 sethostid F +GLIBC_2.27 sethostname F +GLIBC_2.27 setipv4sourcefilter F +GLIBC_2.27 setitimer F +GLIBC_2.27 setjmp F +GLIBC_2.27 setlinebuf F +GLIBC_2.27 setlocale F +GLIBC_2.27 setlogin F +GLIBC_2.27 setlogmask F +GLIBC_2.27 setmntent F +GLIBC_2.27 setnetent F +GLIBC_2.27 setnetgrent F +GLIBC_2.27 setns F +GLIBC_2.27 setpgid F +GLIBC_2.27 setpgrp F +GLIBC_2.27 setpriority F +GLIBC_2.27 setprotoent F +GLIBC_2.27 setpwent F +GLIBC_2.27 setregid F +GLIBC_2.27 setresgid F +GLIBC_2.27 setresuid F +GLIBC_2.27 setreuid F +GLIBC_2.27 setrlimit F +GLIBC_2.27 setrlimit64 F +GLIBC_2.27 setrpcent F +GLIBC_2.27 setservent F +GLIBC_2.27 setsgent F +GLIBC_2.27 setsid F +GLIBC_2.27 setsockopt F +GLIBC_2.27 setsourcefilter F +GLIBC_2.27 setspent F +GLIBC_2.27 setstate F +GLIBC_2.27 setstate_r F +GLIBC_2.27 settimeofday F +GLIBC_2.27 setttyent F +GLIBC_2.27 setuid F +GLIBC_2.27 setusershell F +GLIBC_2.27 setutent F +GLIBC_2.27 setutxent F +GLIBC_2.27 setvbuf F +GLIBC_2.27 setxattr F +GLIBC_2.27 sgetsgent F +GLIBC_2.27 sgetsgent_r F +GLIBC_2.27 sgetspent F +GLIBC_2.27 sgetspent_r F +GLIBC_2.27 shmat F +GLIBC_2.27 shmctl F +GLIBC_2.27 shmdt F +GLIBC_2.27 shmget F +GLIBC_2.27 shutdown F +GLIBC_2.27 sigaction F +GLIBC_2.27 sigaddset F +GLIBC_2.27 sigaltstack F +GLIBC_2.27 sigandset F +GLIBC_2.27 sigblock F +GLIBC_2.27 sigdelset F +GLIBC_2.27 sigemptyset F +GLIBC_2.27 sigfillset F +GLIBC_2.27 siggetmask F +GLIBC_2.27 sighold F +GLIBC_2.27 sigignore F +GLIBC_2.27 siginterrupt F +GLIBC_2.27 sigisemptyset F +GLIBC_2.27 sigismember F +GLIBC_2.27 siglongjmp F +GLIBC_2.27 signal F +GLIBC_2.27 signalfd F +GLIBC_2.27 sigorset F +GLIBC_2.27 sigpause F +GLIBC_2.27 sigpending F +GLIBC_2.27 sigprocmask F +GLIBC_2.27 sigqueue F +GLIBC_2.27 sigrelse F +GLIBC_2.27 sigreturn F +GLIBC_2.27 sigset F +GLIBC_2.27 sigsetmask F +GLIBC_2.27 sigstack F +GLIBC_2.27 sigsuspend F +GLIBC_2.27 sigtimedwait F +GLIBC_2.27 sigwait F +GLIBC_2.27 sigwaitinfo F +GLIBC_2.27 sleep F +GLIBC_2.27 snprintf F +GLIBC_2.27 sockatmark F +GLIBC_2.27 socket F +GLIBC_2.27 socketpair F +GLIBC_2.27 splice F +GLIBC_2.27 sprintf F +GLIBC_2.27 sprofil F +GLIBC_2.27 srand F +GLIBC_2.27 srand48 F +GLIBC_2.27 srand48_r F +GLIBC_2.27 srandom F +GLIBC_2.27 srandom_r F +GLIBC_2.27 sscanf F +GLIBC_2.27 ssignal F +GLIBC_2.27 sstk F +GLIBC_2.27 statfs F +GLIBC_2.27 statfs64 F +GLIBC_2.27 statvfs F +GLIBC_2.27 statvfs64 F +GLIBC_2.27 stderr D 0x8 +GLIBC_2.27 stdin D 0x8 +GLIBC_2.27 stdout D 0x8 +GLIBC_2.27 stime F +GLIBC_2.27 stpcpy F +GLIBC_2.27 stpncpy F +GLIBC_2.27 strcasecmp F +GLIBC_2.27 strcasecmp_l F +GLIBC_2.27 strcasestr F +GLIBC_2.27 strcat F +GLIBC_2.27 strchr F +GLIBC_2.27 strchrnul F +GLIBC_2.27 strcmp F +GLIBC_2.27 strcoll F +GLIBC_2.27 strcoll_l F +GLIBC_2.27 strcpy F +GLIBC_2.27 strcspn F +GLIBC_2.27 strdup F +GLIBC_2.27 strerror F +GLIBC_2.27 strerror_l F +GLIBC_2.27 strerror_r F +GLIBC_2.27 strfmon F +GLIBC_2.27 strfmon_l F +GLIBC_2.27 strfromd F +GLIBC_2.27 strfromf F +GLIBC_2.27 strfromf128 F +GLIBC_2.27 strfromf32 F +GLIBC_2.27 strfromf32x F +GLIBC_2.27 strfromf64 F +GLIBC_2.27 strfromf64x F +GLIBC_2.27 strfroml F +GLIBC_2.27 strfry F +GLIBC_2.27 strftime F +GLIBC_2.27 strftime_l F +GLIBC_2.27 strlen F +GLIBC_2.27 strncasecmp F +GLIBC_2.27 strncasecmp_l F +GLIBC_2.27 strncat F +GLIBC_2.27 strncmp F +GLIBC_2.27 strncpy F +GLIBC_2.27 strndup F +GLIBC_2.27 strnlen F +GLIBC_2.27 strpbrk F +GLIBC_2.27 strptime F +GLIBC_2.27 strptime_l F +GLIBC_2.27 strrchr F +GLIBC_2.27 strsep F +GLIBC_2.27 strsignal F +GLIBC_2.27 strspn F +GLIBC_2.27 strstr F +GLIBC_2.27 strtod F +GLIBC_2.27 strtod_l F +GLIBC_2.27 strtof F +GLIBC_2.27 strtof128 F +GLIBC_2.27 strtof128_l F +GLIBC_2.27 strtof32 F +GLIBC_2.27 strtof32_l F +GLIBC_2.27 strtof32x F +GLIBC_2.27 strtof32x_l F +GLIBC_2.27 strtof64 F +GLIBC_2.27 strtof64_l F +GLIBC_2.27 strtof64x F +GLIBC_2.27 strtof64x_l F +GLIBC_2.27 strtof_l F +GLIBC_2.27 strtoimax F +GLIBC_2.27 strtok F +GLIBC_2.27 strtok_r F +GLIBC_2.27 strtol F +GLIBC_2.27 strtol_l F +GLIBC_2.27 strtold F +GLIBC_2.27 strtold_l F +GLIBC_2.27 strtoll F +GLIBC_2.27 strtoll_l F +GLIBC_2.27 strtoq F +GLIBC_2.27 strtoul F +GLIBC_2.27 strtoul_l F +GLIBC_2.27 strtoull F +GLIBC_2.27 strtoull_l F +GLIBC_2.27 strtoumax F +GLIBC_2.27 strtouq F +GLIBC_2.27 strverscmp F +GLIBC_2.27 strxfrm F +GLIBC_2.27 strxfrm_l F +GLIBC_2.27 stty F +GLIBC_2.27 svc_exit F +GLIBC_2.27 svc_fdset D 0x80 +GLIBC_2.27 svc_getreq F +GLIBC_2.27 svc_getreq_common F +GLIBC_2.27 svc_getreq_poll F +GLIBC_2.27 svc_getreqset F +GLIBC_2.27 svc_max_pollfd D 0x4 +GLIBC_2.27 svc_pollfd D 0x8 +GLIBC_2.27 svc_register F +GLIBC_2.27 svc_run F +GLIBC_2.27 svc_sendreply F +GLIBC_2.27 svc_unregister F +GLIBC_2.27 svcauthdes_stats D 0x18 +GLIBC_2.27 svcerr_auth F +GLIBC_2.27 svcerr_decode F +GLIBC_2.27 svcerr_noproc F +GLIBC_2.27 svcerr_noprog F +GLIBC_2.27 svcerr_progvers F +GLIBC_2.27 svcerr_systemerr F +GLIBC_2.27 svcerr_weakauth F +GLIBC_2.27 svcfd_create F +GLIBC_2.27 svcraw_create F +GLIBC_2.27 svctcp_create F +GLIBC_2.27 svcudp_bufcreate F +GLIBC_2.27 svcudp_create F +GLIBC_2.27 svcudp_enablecache F +GLIBC_2.27 svcunix_create F +GLIBC_2.27 svcunixfd_create F +GLIBC_2.27 swab F +GLIBC_2.27 swapcontext F +GLIBC_2.27 swapoff F +GLIBC_2.27 swapon F +GLIBC_2.27 swprintf F +GLIBC_2.27 swscanf F +GLIBC_2.27 symlink F +GLIBC_2.27 symlinkat F +GLIBC_2.27 sync F +GLIBC_2.27 sync_file_range F +GLIBC_2.27 syncfs F +GLIBC_2.27 sys_errlist D 0x2370 +GLIBC_2.27 sys_nerr D 0x4 +GLIBC_2.27 sys_sigabbrev D 0x400 +GLIBC_2.27 sys_siglist D 0x400 +GLIBC_2.27 syscall F +GLIBC_2.27 sysconf F +GLIBC_2.27 sysctl F +GLIBC_2.27 sysinfo F +GLIBC_2.27 syslog F +GLIBC_2.27 system F +GLIBC_2.27 sysv_signal F +GLIBC_2.27 tcdrain F +GLIBC_2.27 tcflow F +GLIBC_2.27 tcflush F +GLIBC_2.27 tcgetattr F +GLIBC_2.27 tcgetpgrp F +GLIBC_2.27 tcgetsid F +GLIBC_2.27 tcsendbreak F +GLIBC_2.27 tcsetattr F +GLIBC_2.27 tcsetpgrp F +GLIBC_2.27 tdelete F +GLIBC_2.27 tdestroy F +GLIBC_2.27 tee F +GLIBC_2.27 telldir F +GLIBC_2.27 tempnam F +GLIBC_2.27 textdomain F +GLIBC_2.27 tfind F +GLIBC_2.27 time F +GLIBC_2.27 timegm F +GLIBC_2.27 timelocal F +GLIBC_2.27 timerfd_create F +GLIBC_2.27 timerfd_gettime F +GLIBC_2.27 timerfd_settime F +GLIBC_2.27 times F +GLIBC_2.27 timespec_get F +GLIBC_2.27 timezone D 0x8 +GLIBC_2.27 tmpfile F +GLIBC_2.27 tmpfile64 F +GLIBC_2.27 tmpnam F +GLIBC_2.27 tmpnam_r F +GLIBC_2.27 toascii F +GLIBC_2.27 tolower F +GLIBC_2.27 tolower_l F +GLIBC_2.27 toupper F +GLIBC_2.27 toupper_l F +GLIBC_2.27 towctrans F +GLIBC_2.27 towctrans_l F +GLIBC_2.27 towlower F +GLIBC_2.27 towlower_l F +GLIBC_2.27 towupper F +GLIBC_2.27 towupper_l F +GLIBC_2.27 tr_break F +GLIBC_2.27 truncate F +GLIBC_2.27 truncate64 F +GLIBC_2.27 tsearch F +GLIBC_2.27 ttyname F +GLIBC_2.27 ttyname_r F +GLIBC_2.27 ttyslot F +GLIBC_2.27 twalk F +GLIBC_2.27 tzname D 0x10 +GLIBC_2.27 tzset F +GLIBC_2.27 ualarm F +GLIBC_2.27 ulckpwdf F +GLIBC_2.27 ulimit F +GLIBC_2.27 umask F +GLIBC_2.27 umount F +GLIBC_2.27 umount2 F +GLIBC_2.27 uname F +GLIBC_2.27 ungetc F +GLIBC_2.27 ungetwc F +GLIBC_2.27 unlink F +GLIBC_2.27 unlinkat F +GLIBC_2.27 unlockpt F +GLIBC_2.27 unsetenv F +GLIBC_2.27 unshare F +GLIBC_2.27 updwtmp F +GLIBC_2.27 updwtmpx F +GLIBC_2.27 uselocale F +GLIBC_2.27 user2netname F +GLIBC_2.27 usleep F +GLIBC_2.27 ustat F +GLIBC_2.27 utime F +GLIBC_2.27 utimensat F +GLIBC_2.27 utimes F +GLIBC_2.27 utmpname F +GLIBC_2.27 utmpxname F +GLIBC_2.27 valloc F +GLIBC_2.27 vasprintf F +GLIBC_2.27 vdprintf F +GLIBC_2.27 verr F +GLIBC_2.27 verrx F +GLIBC_2.27 versionsort F +GLIBC_2.27 versionsort64 F +GLIBC_2.27 vfork F +GLIBC_2.27 vfprintf F +GLIBC_2.27 vfscanf F +GLIBC_2.27 vfwprintf F +GLIBC_2.27 vfwscanf F +GLIBC_2.27 vhangup F +GLIBC_2.27 vlimit F +GLIBC_2.27 vmsplice F +GLIBC_2.27 vprintf F +GLIBC_2.27 vscanf F +GLIBC_2.27 vsnprintf F +GLIBC_2.27 vsprintf F +GLIBC_2.27 vsscanf F +GLIBC_2.27 vswprintf F +GLIBC_2.27 vswscanf F +GLIBC_2.27 vsyslog F +GLIBC_2.27 vtimes F +GLIBC_2.27 vwarn F +GLIBC_2.27 vwarnx F +GLIBC_2.27 vwprintf F +GLIBC_2.27 vwscanf F +GLIBC_2.27 wait F +GLIBC_2.27 wait3 F +GLIBC_2.27 wait4 F +GLIBC_2.27 waitid F +GLIBC_2.27 waitpid F +GLIBC_2.27 warn F +GLIBC_2.27 warnx F +GLIBC_2.27 wcpcpy F +GLIBC_2.27 wcpncpy F +GLIBC_2.27 wcrtomb F +GLIBC_2.27 wcscasecmp F +GLIBC_2.27 wcscasecmp_l F +GLIBC_2.27 wcscat F +GLIBC_2.27 wcschr F +GLIBC_2.27 wcschrnul F +GLIBC_2.27 wcscmp F +GLIBC_2.27 wcscoll F +GLIBC_2.27 wcscoll_l F +GLIBC_2.27 wcscpy F +GLIBC_2.27 wcscspn F +GLIBC_2.27 wcsdup F +GLIBC_2.27 wcsftime F +GLIBC_2.27 wcsftime_l F +GLIBC_2.27 wcslen F +GLIBC_2.27 wcsncasecmp F +GLIBC_2.27 wcsncasecmp_l F +GLIBC_2.27 wcsncat F +GLIBC_2.27 wcsncmp F +GLIBC_2.27 wcsncpy F +GLIBC_2.27 wcsnlen F +GLIBC_2.27 wcsnrtombs F +GLIBC_2.27 wcspbrk F +GLIBC_2.27 wcsrchr F +GLIBC_2.27 wcsrtombs F +GLIBC_2.27 wcsspn F +GLIBC_2.27 wcsstr F +GLIBC_2.27 wcstod F +GLIBC_2.27 wcstod_l F +GLIBC_2.27 wcstof F +GLIBC_2.27 wcstof128 F +GLIBC_2.27 wcstof128_l F +GLIBC_2.27 wcstof32 F +GLIBC_2.27 wcstof32_l F +GLIBC_2.27 wcstof32x F +GLIBC_2.27 wcstof32x_l F +GLIBC_2.27 wcstof64 F +GLIBC_2.27 wcstof64_l F +GLIBC_2.27 wcstof64x F +GLIBC_2.27 wcstof64x_l F +GLIBC_2.27 wcstof_l F +GLIBC_2.27 wcstoimax F +GLIBC_2.27 wcstok F +GLIBC_2.27 wcstol F +GLIBC_2.27 wcstol_l F +GLIBC_2.27 wcstold F +GLIBC_2.27 wcstold_l F +GLIBC_2.27 wcstoll F +GLIBC_2.27 wcstoll_l F +GLIBC_2.27 wcstombs F +GLIBC_2.27 wcstoq F +GLIBC_2.27 wcstoul F +GLIBC_2.27 wcstoul_l F +GLIBC_2.27 wcstoull F +GLIBC_2.27 wcstoull_l F +GLIBC_2.27 wcstoumax F +GLIBC_2.27 wcstouq F +GLIBC_2.27 wcswcs F +GLIBC_2.27 wcswidth F +GLIBC_2.27 wcsxfrm F +GLIBC_2.27 wcsxfrm_l F +GLIBC_2.27 wctob F +GLIBC_2.27 wctomb F +GLIBC_2.27 wctrans F +GLIBC_2.27 wctrans_l F +GLIBC_2.27 wctype F +GLIBC_2.27 wctype_l F +GLIBC_2.27 wcwidth F +GLIBC_2.27 wmemchr F +GLIBC_2.27 wmemcmp F +GLIBC_2.27 wmemcpy F +GLIBC_2.27 wmemmove F +GLIBC_2.27 wmempcpy F +GLIBC_2.27 wmemset F +GLIBC_2.27 wordexp F +GLIBC_2.27 wordfree F +GLIBC_2.27 wprintf F +GLIBC_2.27 write F +GLIBC_2.27 writev F +GLIBC_2.27 wscanf F +GLIBC_2.27 xdecrypt F +GLIBC_2.27 xdr_accepted_reply F +GLIBC_2.27 xdr_array F +GLIBC_2.27 xdr_authdes_cred F +GLIBC_2.27 xdr_authdes_verf F +GLIBC_2.27 xdr_authunix_parms F +GLIBC_2.27 xdr_bool F +GLIBC_2.27 xdr_bytes F +GLIBC_2.27 xdr_callhdr F +GLIBC_2.27 xdr_callmsg F +GLIBC_2.27 xdr_char F +GLIBC_2.27 xdr_cryptkeyarg F +GLIBC_2.27 xdr_cryptkeyarg2 F +GLIBC_2.27 xdr_cryptkeyres F +GLIBC_2.27 xdr_des_block F +GLIBC_2.27 xdr_double F +GLIBC_2.27 xdr_enum F +GLIBC_2.27 xdr_float F +GLIBC_2.27 xdr_free F +GLIBC_2.27 xdr_getcredres F +GLIBC_2.27 xdr_hyper F +GLIBC_2.27 xdr_int F +GLIBC_2.27 xdr_int16_t F +GLIBC_2.27 xdr_int32_t F +GLIBC_2.27 xdr_int64_t F +GLIBC_2.27 xdr_int8_t F +GLIBC_2.27 xdr_key_netstarg F +GLIBC_2.27 xdr_key_netstres F +GLIBC_2.27 xdr_keybuf F +GLIBC_2.27 xdr_keystatus F +GLIBC_2.27 xdr_long F +GLIBC_2.27 xdr_longlong_t F +GLIBC_2.27 xdr_netnamestr F +GLIBC_2.27 xdr_netobj F +GLIBC_2.27 xdr_opaque F +GLIBC_2.27 xdr_opaque_auth F +GLIBC_2.27 xdr_pmap F +GLIBC_2.27 xdr_pmaplist F +GLIBC_2.27 xdr_pointer F +GLIBC_2.27 xdr_quad_t F +GLIBC_2.27 xdr_reference F +GLIBC_2.27 xdr_rejected_reply F +GLIBC_2.27 xdr_replymsg F +GLIBC_2.27 xdr_rmtcall_args F +GLIBC_2.27 xdr_rmtcallres F +GLIBC_2.27 xdr_short F +GLIBC_2.27 xdr_sizeof F +GLIBC_2.27 xdr_string F +GLIBC_2.27 xdr_u_char F +GLIBC_2.27 xdr_u_hyper F +GLIBC_2.27 xdr_u_int F +GLIBC_2.27 xdr_u_long F +GLIBC_2.27 xdr_u_longlong_t F +GLIBC_2.27 xdr_u_quad_t F +GLIBC_2.27 xdr_u_short F +GLIBC_2.27 xdr_uint16_t F +GLIBC_2.27 xdr_uint32_t F +GLIBC_2.27 xdr_uint64_t F +GLIBC_2.27 xdr_uint8_t F +GLIBC_2.27 xdr_union F +GLIBC_2.27 xdr_unixcred F +GLIBC_2.27 xdr_vector F +GLIBC_2.27 xdr_void F +GLIBC_2.27 xdr_wrapstring F +GLIBC_2.27 xdrmem_create F +GLIBC_2.27 xdrrec_create F +GLIBC_2.27 xdrrec_endofrecord F +GLIBC_2.27 xdrrec_eof F +GLIBC_2.27 xdrrec_skiprecord F +GLIBC_2.27 xdrstdio_create F +GLIBC_2.27 xencrypt F +GLIBC_2.27 xprt_register F +GLIBC_2.27 xprt_unregister F +GLIBC_2.28 fcntl64 F +GLIBC_2.28 renameat2 F +GLIBC_2.28 statx F +GLIBC_2.28 thrd_current F +GLIBC_2.28 thrd_equal F +GLIBC_2.28 thrd_sleep F +GLIBC_2.28 thrd_yield F diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libcrypt.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libcrypt.abilist new file mode 100644 index 00000000..9484dca7 --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libcrypt.abilist @@ -0,0 +1,7 @@ +GLIBC_2.27 crypt F +GLIBC_2.27 crypt_r F +GLIBC_2.27 encrypt F +GLIBC_2.27 encrypt_r F +GLIBC_2.27 fcrypt F +GLIBC_2.27 setkey F +GLIBC_2.27 setkey_r F diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libdl.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libdl.abilist new file mode 100644 index 00000000..16adcae5 --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libdl.abilist @@ -0,0 +1,9 @@ +GLIBC_2.27 dladdr F +GLIBC_2.27 dladdr1 F +GLIBC_2.27 dlclose F +GLIBC_2.27 dlerror F +GLIBC_2.27 dlinfo F +GLIBC_2.27 dlmopen F +GLIBC_2.27 dlopen F +GLIBC_2.27 dlsym F +GLIBC_2.27 dlvsym F diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libm.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libm.abilist new file mode 100644 index 00000000..361fce20 --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libm.abilist @@ -0,0 +1,1021 @@ +GLIBC_2.27 __acos_finite F +GLIBC_2.27 __acosf_finite F +GLIBC_2.27 __acosh_finite F +GLIBC_2.27 __acoshf_finite F +GLIBC_2.27 __acoshl_finite F +GLIBC_2.27 __acosl_finite F +GLIBC_2.27 __asin_finite F +GLIBC_2.27 __asinf_finite F +GLIBC_2.27 __asinl_finite F +GLIBC_2.27 __atan2_finite F +GLIBC_2.27 __atan2f_finite F +GLIBC_2.27 __atan2l_finite F +GLIBC_2.27 __atanh_finite F +GLIBC_2.27 __atanhf_finite F +GLIBC_2.27 __atanhl_finite F +GLIBC_2.27 __clog10 F +GLIBC_2.27 __clog10f F +GLIBC_2.27 __clog10l F +GLIBC_2.27 __cosh_finite F +GLIBC_2.27 __coshf_finite F +GLIBC_2.27 __coshl_finite F +GLIBC_2.27 __exp10_finite F +GLIBC_2.27 __exp10f_finite F +GLIBC_2.27 __exp10l_finite F +GLIBC_2.27 __exp2_finite F +GLIBC_2.27 __exp2f_finite F +GLIBC_2.27 __exp2l_finite F +GLIBC_2.27 __exp_finite F +GLIBC_2.27 __expf_finite F +GLIBC_2.27 __expl_finite F +GLIBC_2.27 __finite F +GLIBC_2.27 __finitef F +GLIBC_2.27 __finitel F +GLIBC_2.27 __fmod_finite F +GLIBC_2.27 __fmodf_finite F +GLIBC_2.27 __fmodl_finite F +GLIBC_2.27 __fpclassify F +GLIBC_2.27 __fpclassifyf F +GLIBC_2.27 __fpclassifyl F +GLIBC_2.27 __gamma_r_finite F +GLIBC_2.27 __gammaf_r_finite F +GLIBC_2.27 __gammal_r_finite F +GLIBC_2.27 __hypot_finite F +GLIBC_2.27 __hypotf_finite F +GLIBC_2.27 __hypotl_finite F +GLIBC_2.27 __iseqsig F +GLIBC_2.27 __iseqsigf F +GLIBC_2.27 __iseqsigl F +GLIBC_2.27 __issignaling F +GLIBC_2.27 __issignalingf F +GLIBC_2.27 __issignalingl F +GLIBC_2.27 __j0_finite F +GLIBC_2.27 __j0f_finite F +GLIBC_2.27 __j0l_finite F +GLIBC_2.27 __j1_finite F +GLIBC_2.27 __j1f_finite F +GLIBC_2.27 __j1l_finite F +GLIBC_2.27 __jn_finite F +GLIBC_2.27 __jnf_finite F +GLIBC_2.27 __jnl_finite F +GLIBC_2.27 __lgamma_r_finite F +GLIBC_2.27 __lgammaf_r_finite F +GLIBC_2.27 __lgammal_r_finite F +GLIBC_2.27 __log10_finite F +GLIBC_2.27 __log10f_finite F +GLIBC_2.27 __log10l_finite F +GLIBC_2.27 __log2_finite F +GLIBC_2.27 __log2f_finite F +GLIBC_2.27 __log2l_finite F +GLIBC_2.27 __log_finite F +GLIBC_2.27 __logf_finite F +GLIBC_2.27 __logl_finite F +GLIBC_2.27 __pow_finite F +GLIBC_2.27 __powf_finite F +GLIBC_2.27 __powl_finite F +GLIBC_2.27 __remainder_finite F +GLIBC_2.27 __remainderf_finite F +GLIBC_2.27 __remainderl_finite F +GLIBC_2.27 __scalb_finite F +GLIBC_2.27 __scalbf_finite F +GLIBC_2.27 __scalbl_finite F +GLIBC_2.27 __signbit F +GLIBC_2.27 __signbitf F +GLIBC_2.27 __signbitl F +GLIBC_2.27 __signgam D 0x4 +GLIBC_2.27 __sinh_finite F +GLIBC_2.27 __sinhf_finite F +GLIBC_2.27 __sinhl_finite F +GLIBC_2.27 __sqrt_finite F +GLIBC_2.27 __sqrtf_finite F +GLIBC_2.27 __sqrtl_finite F +GLIBC_2.27 __y0_finite F +GLIBC_2.27 __y0f_finite F +GLIBC_2.27 __y0l_finite F +GLIBC_2.27 __y1_finite F +GLIBC_2.27 __y1f_finite F +GLIBC_2.27 __y1l_finite F +GLIBC_2.27 __yn_finite F +GLIBC_2.27 __ynf_finite F +GLIBC_2.27 __ynl_finite F +GLIBC_2.27 acos F +GLIBC_2.27 acosf F +GLIBC_2.27 acosf128 F +GLIBC_2.27 acosf32 F +GLIBC_2.27 acosf32x F +GLIBC_2.27 acosf64 F +GLIBC_2.27 acosf64x F +GLIBC_2.27 acosh F +GLIBC_2.27 acoshf F +GLIBC_2.27 acoshf128 F +GLIBC_2.27 acoshf32 F +GLIBC_2.27 acoshf32x F +GLIBC_2.27 acoshf64 F +GLIBC_2.27 acoshf64x F +GLIBC_2.27 acoshl F +GLIBC_2.27 acosl F +GLIBC_2.27 asin F +GLIBC_2.27 asinf F +GLIBC_2.27 asinf128 F +GLIBC_2.27 asinf32 F +GLIBC_2.27 asinf32x F +GLIBC_2.27 asinf64 F +GLIBC_2.27 asinf64x F +GLIBC_2.27 asinh F +GLIBC_2.27 asinhf F +GLIBC_2.27 asinhf128 F +GLIBC_2.27 asinhf32 F +GLIBC_2.27 asinhf32x F +GLIBC_2.27 asinhf64 F +GLIBC_2.27 asinhf64x F +GLIBC_2.27 asinhl F +GLIBC_2.27 asinl F +GLIBC_2.27 atan F +GLIBC_2.27 atan2 F +GLIBC_2.27 atan2f F +GLIBC_2.27 atan2f128 F +GLIBC_2.27 atan2f32 F +GLIBC_2.27 atan2f32x F +GLIBC_2.27 atan2f64 F +GLIBC_2.27 atan2f64x F +GLIBC_2.27 atan2l F +GLIBC_2.27 atanf F +GLIBC_2.27 atanf128 F +GLIBC_2.27 atanf32 F +GLIBC_2.27 atanf32x F +GLIBC_2.27 atanf64 F +GLIBC_2.27 atanf64x F +GLIBC_2.27 atanh F +GLIBC_2.27 atanhf F +GLIBC_2.27 atanhf128 F +GLIBC_2.27 atanhf32 F +GLIBC_2.27 atanhf32x F +GLIBC_2.27 atanhf64 F +GLIBC_2.27 atanhf64x F +GLIBC_2.27 atanhl F +GLIBC_2.27 atanl F +GLIBC_2.27 cabs F +GLIBC_2.27 cabsf F +GLIBC_2.27 cabsf128 F +GLIBC_2.27 cabsf32 F +GLIBC_2.27 cabsf32x F +GLIBC_2.27 cabsf64 F +GLIBC_2.27 cabsf64x F +GLIBC_2.27 cabsl F +GLIBC_2.27 cacos F +GLIBC_2.27 cacosf F +GLIBC_2.27 cacosf128 F +GLIBC_2.27 cacosf32 F +GLIBC_2.27 cacosf32x F +GLIBC_2.27 cacosf64 F +GLIBC_2.27 cacosf64x F +GLIBC_2.27 cacosh F +GLIBC_2.27 cacoshf F +GLIBC_2.27 cacoshf128 F +GLIBC_2.27 cacoshf32 F +GLIBC_2.27 cacoshf32x F +GLIBC_2.27 cacoshf64 F +GLIBC_2.27 cacoshf64x F +GLIBC_2.27 cacoshl F +GLIBC_2.27 cacosl F +GLIBC_2.27 canonicalize F +GLIBC_2.27 canonicalizef F +GLIBC_2.27 canonicalizef128 F +GLIBC_2.27 canonicalizef32 F +GLIBC_2.27 canonicalizef32x F +GLIBC_2.27 canonicalizef64 F +GLIBC_2.27 canonicalizef64x F +GLIBC_2.27 canonicalizel F +GLIBC_2.27 carg F +GLIBC_2.27 cargf F +GLIBC_2.27 cargf128 F +GLIBC_2.27 cargf32 F +GLIBC_2.27 cargf32x F +GLIBC_2.27 cargf64 F +GLIBC_2.27 cargf64x F +GLIBC_2.27 cargl F +GLIBC_2.27 casin F +GLIBC_2.27 casinf F +GLIBC_2.27 casinf128 F +GLIBC_2.27 casinf32 F +GLIBC_2.27 casinf32x F +GLIBC_2.27 casinf64 F +GLIBC_2.27 casinf64x F +GLIBC_2.27 casinh F +GLIBC_2.27 casinhf F +GLIBC_2.27 casinhf128 F +GLIBC_2.27 casinhf32 F +GLIBC_2.27 casinhf32x F +GLIBC_2.27 casinhf64 F +GLIBC_2.27 casinhf64x F +GLIBC_2.27 casinhl F +GLIBC_2.27 casinl F +GLIBC_2.27 catan F +GLIBC_2.27 catanf F +GLIBC_2.27 catanf128 F +GLIBC_2.27 catanf32 F +GLIBC_2.27 catanf32x F +GLIBC_2.27 catanf64 F +GLIBC_2.27 catanf64x F +GLIBC_2.27 catanh F +GLIBC_2.27 catanhf F +GLIBC_2.27 catanhf128 F +GLIBC_2.27 catanhf32 F +GLIBC_2.27 catanhf32x F +GLIBC_2.27 catanhf64 F +GLIBC_2.27 catanhf64x F +GLIBC_2.27 catanhl F +GLIBC_2.27 catanl F +GLIBC_2.27 cbrt F +GLIBC_2.27 cbrtf F +GLIBC_2.27 cbrtf128 F +GLIBC_2.27 cbrtf32 F +GLIBC_2.27 cbrtf32x F +GLIBC_2.27 cbrtf64 F +GLIBC_2.27 cbrtf64x F +GLIBC_2.27 cbrtl F +GLIBC_2.27 ccos F +GLIBC_2.27 ccosf F +GLIBC_2.27 ccosf128 F +GLIBC_2.27 ccosf32 F +GLIBC_2.27 ccosf32x F +GLIBC_2.27 ccosf64 F +GLIBC_2.27 ccosf64x F +GLIBC_2.27 ccosh F +GLIBC_2.27 ccoshf F +GLIBC_2.27 ccoshf128 F +GLIBC_2.27 ccoshf32 F +GLIBC_2.27 ccoshf32x F +GLIBC_2.27 ccoshf64 F +GLIBC_2.27 ccoshf64x F +GLIBC_2.27 ccoshl F +GLIBC_2.27 ccosl F +GLIBC_2.27 ceil F +GLIBC_2.27 ceilf F +GLIBC_2.27 ceilf128 F +GLIBC_2.27 ceilf32 F +GLIBC_2.27 ceilf32x F +GLIBC_2.27 ceilf64 F +GLIBC_2.27 ceilf64x F +GLIBC_2.27 ceill F +GLIBC_2.27 cexp F +GLIBC_2.27 cexpf F +GLIBC_2.27 cexpf128 F +GLIBC_2.27 cexpf32 F +GLIBC_2.27 cexpf32x F +GLIBC_2.27 cexpf64 F +GLIBC_2.27 cexpf64x F +GLIBC_2.27 cexpl F +GLIBC_2.27 cimag F +GLIBC_2.27 cimagf F +GLIBC_2.27 cimagf128 F +GLIBC_2.27 cimagf32 F +GLIBC_2.27 cimagf32x F +GLIBC_2.27 cimagf64 F +GLIBC_2.27 cimagf64x F +GLIBC_2.27 cimagl F +GLIBC_2.27 clog F +GLIBC_2.27 clog10 F +GLIBC_2.27 clog10f F +GLIBC_2.27 clog10f128 F +GLIBC_2.27 clog10f32 F +GLIBC_2.27 clog10f32x F +GLIBC_2.27 clog10f64 F +GLIBC_2.27 clog10f64x F +GLIBC_2.27 clog10l F +GLIBC_2.27 clogf F +GLIBC_2.27 clogf128 F +GLIBC_2.27 clogf32 F +GLIBC_2.27 clogf32x F +GLIBC_2.27 clogf64 F +GLIBC_2.27 clogf64x F +GLIBC_2.27 clogl F +GLIBC_2.27 conj F +GLIBC_2.27 conjf F +GLIBC_2.27 conjf128 F +GLIBC_2.27 conjf32 F +GLIBC_2.27 conjf32x F +GLIBC_2.27 conjf64 F +GLIBC_2.27 conjf64x F +GLIBC_2.27 conjl F +GLIBC_2.27 copysign F +GLIBC_2.27 copysignf F +GLIBC_2.27 copysignf128 F +GLIBC_2.27 copysignf32 F +GLIBC_2.27 copysignf32x F +GLIBC_2.27 copysignf64 F +GLIBC_2.27 copysignf64x F +GLIBC_2.27 copysignl F +GLIBC_2.27 cos F +GLIBC_2.27 cosf F +GLIBC_2.27 cosf128 F +GLIBC_2.27 cosf32 F +GLIBC_2.27 cosf32x F +GLIBC_2.27 cosf64 F +GLIBC_2.27 cosf64x F +GLIBC_2.27 cosh F +GLIBC_2.27 coshf F +GLIBC_2.27 coshf128 F +GLIBC_2.27 coshf32 F +GLIBC_2.27 coshf32x F +GLIBC_2.27 coshf64 F +GLIBC_2.27 coshf64x F +GLIBC_2.27 coshl F +GLIBC_2.27 cosl F +GLIBC_2.27 cpow F +GLIBC_2.27 cpowf F +GLIBC_2.27 cpowf128 F +GLIBC_2.27 cpowf32 F +GLIBC_2.27 cpowf32x F +GLIBC_2.27 cpowf64 F +GLIBC_2.27 cpowf64x F +GLIBC_2.27 cpowl F +GLIBC_2.27 cproj F +GLIBC_2.27 cprojf F +GLIBC_2.27 cprojf128 F +GLIBC_2.27 cprojf32 F +GLIBC_2.27 cprojf32x F +GLIBC_2.27 cprojf64 F +GLIBC_2.27 cprojf64x F +GLIBC_2.27 cprojl F +GLIBC_2.27 creal F +GLIBC_2.27 crealf F +GLIBC_2.27 crealf128 F +GLIBC_2.27 crealf32 F +GLIBC_2.27 crealf32x F +GLIBC_2.27 crealf64 F +GLIBC_2.27 crealf64x F +GLIBC_2.27 creall F +GLIBC_2.27 csin F +GLIBC_2.27 csinf F +GLIBC_2.27 csinf128 F +GLIBC_2.27 csinf32 F +GLIBC_2.27 csinf32x F +GLIBC_2.27 csinf64 F +GLIBC_2.27 csinf64x F +GLIBC_2.27 csinh F +GLIBC_2.27 csinhf F +GLIBC_2.27 csinhf128 F +GLIBC_2.27 csinhf32 F +GLIBC_2.27 csinhf32x F +GLIBC_2.27 csinhf64 F +GLIBC_2.27 csinhf64x F +GLIBC_2.27 csinhl F +GLIBC_2.27 csinl F +GLIBC_2.27 csqrt F +GLIBC_2.27 csqrtf F +GLIBC_2.27 csqrtf128 F +GLIBC_2.27 csqrtf32 F +GLIBC_2.27 csqrtf32x F +GLIBC_2.27 csqrtf64 F +GLIBC_2.27 csqrtf64x F +GLIBC_2.27 csqrtl F +GLIBC_2.27 ctan F +GLIBC_2.27 ctanf F +GLIBC_2.27 ctanf128 F +GLIBC_2.27 ctanf32 F +GLIBC_2.27 ctanf32x F +GLIBC_2.27 ctanf64 F +GLIBC_2.27 ctanf64x F +GLIBC_2.27 ctanh F +GLIBC_2.27 ctanhf F +GLIBC_2.27 ctanhf128 F +GLIBC_2.27 ctanhf32 F +GLIBC_2.27 ctanhf32x F +GLIBC_2.27 ctanhf64 F +GLIBC_2.27 ctanhf64x F +GLIBC_2.27 ctanhl F +GLIBC_2.27 ctanl F +GLIBC_2.27 drem F +GLIBC_2.27 dremf F +GLIBC_2.27 dreml F +GLIBC_2.27 erf F +GLIBC_2.27 erfc F +GLIBC_2.27 erfcf F +GLIBC_2.27 erfcf128 F +GLIBC_2.27 erfcf32 F +GLIBC_2.27 erfcf32x F +GLIBC_2.27 erfcf64 F +GLIBC_2.27 erfcf64x F +GLIBC_2.27 erfcl F +GLIBC_2.27 erff F +GLIBC_2.27 erff128 F +GLIBC_2.27 erff32 F +GLIBC_2.27 erff32x F +GLIBC_2.27 erff64 F +GLIBC_2.27 erff64x F +GLIBC_2.27 erfl F +GLIBC_2.27 exp F +GLIBC_2.27 exp10 F +GLIBC_2.27 exp10f F +GLIBC_2.27 exp10f128 F +GLIBC_2.27 exp10f32 F +GLIBC_2.27 exp10f32x F +GLIBC_2.27 exp10f64 F +GLIBC_2.27 exp10f64x F +GLIBC_2.27 exp10l F +GLIBC_2.27 exp2 F +GLIBC_2.27 exp2f F +GLIBC_2.27 exp2f128 F +GLIBC_2.27 exp2f32 F +GLIBC_2.27 exp2f32x F +GLIBC_2.27 exp2f64 F +GLIBC_2.27 exp2f64x F +GLIBC_2.27 exp2l F +GLIBC_2.27 expf F +GLIBC_2.27 expf128 F +GLIBC_2.27 expf32 F +GLIBC_2.27 expf32x F +GLIBC_2.27 expf64 F +GLIBC_2.27 expf64x F +GLIBC_2.27 expl F +GLIBC_2.27 expm1 F +GLIBC_2.27 expm1f F +GLIBC_2.27 expm1f128 F +GLIBC_2.27 expm1f32 F +GLIBC_2.27 expm1f32x F +GLIBC_2.27 expm1f64 F +GLIBC_2.27 expm1f64x F +GLIBC_2.27 expm1l F +GLIBC_2.27 fabs F +GLIBC_2.27 fabsf F +GLIBC_2.27 fabsf128 F +GLIBC_2.27 fabsf32 F +GLIBC_2.27 fabsf32x F +GLIBC_2.27 fabsf64 F +GLIBC_2.27 fabsf64x F +GLIBC_2.27 fabsl F +GLIBC_2.27 fdim F +GLIBC_2.27 fdimf F +GLIBC_2.27 fdimf128 F +GLIBC_2.27 fdimf32 F +GLIBC_2.27 fdimf32x F +GLIBC_2.27 fdimf64 F +GLIBC_2.27 fdimf64x F +GLIBC_2.27 fdiml F +GLIBC_2.27 feclearexcept F +GLIBC_2.27 fedisableexcept F +GLIBC_2.27 feenableexcept F +GLIBC_2.27 fegetenv F +GLIBC_2.27 fegetexcept F +GLIBC_2.27 fegetexceptflag F +GLIBC_2.27 fegetmode F +GLIBC_2.27 fegetround F +GLIBC_2.27 feholdexcept F +GLIBC_2.27 feraiseexcept F +GLIBC_2.27 fesetenv F +GLIBC_2.27 fesetexcept F +GLIBC_2.27 fesetexceptflag F +GLIBC_2.27 fesetmode F +GLIBC_2.27 fesetround F +GLIBC_2.27 fetestexcept F +GLIBC_2.27 fetestexceptflag F +GLIBC_2.27 feupdateenv F +GLIBC_2.27 finite F +GLIBC_2.27 finitef F +GLIBC_2.27 finitel F +GLIBC_2.27 floor F +GLIBC_2.27 floorf F +GLIBC_2.27 floorf128 F +GLIBC_2.27 floorf32 F +GLIBC_2.27 floorf32x F +GLIBC_2.27 floorf64 F +GLIBC_2.27 floorf64x F +GLIBC_2.27 floorl F +GLIBC_2.27 fma F +GLIBC_2.27 fmaf F +GLIBC_2.27 fmaf128 F +GLIBC_2.27 fmaf32 F +GLIBC_2.27 fmaf32x F +GLIBC_2.27 fmaf64 F +GLIBC_2.27 fmaf64x F +GLIBC_2.27 fmal F +GLIBC_2.27 fmax F +GLIBC_2.27 fmaxf F +GLIBC_2.27 fmaxf128 F +GLIBC_2.27 fmaxf32 F +GLIBC_2.27 fmaxf32x F +GLIBC_2.27 fmaxf64 F +GLIBC_2.27 fmaxf64x F +GLIBC_2.27 fmaxl F +GLIBC_2.27 fmaxmag F +GLIBC_2.27 fmaxmagf F +GLIBC_2.27 fmaxmagf128 F +GLIBC_2.27 fmaxmagf32 F +GLIBC_2.27 fmaxmagf32x F +GLIBC_2.27 fmaxmagf64 F +GLIBC_2.27 fmaxmagf64x F +GLIBC_2.27 fmaxmagl F +GLIBC_2.27 fmin F +GLIBC_2.27 fminf F +GLIBC_2.27 fminf128 F +GLIBC_2.27 fminf32 F +GLIBC_2.27 fminf32x F +GLIBC_2.27 fminf64 F +GLIBC_2.27 fminf64x F +GLIBC_2.27 fminl F +GLIBC_2.27 fminmag F +GLIBC_2.27 fminmagf F +GLIBC_2.27 fminmagf128 F +GLIBC_2.27 fminmagf32 F +GLIBC_2.27 fminmagf32x F +GLIBC_2.27 fminmagf64 F +GLIBC_2.27 fminmagf64x F +GLIBC_2.27 fminmagl F +GLIBC_2.27 fmod F +GLIBC_2.27 fmodf F +GLIBC_2.27 fmodf128 F +GLIBC_2.27 fmodf32 F +GLIBC_2.27 fmodf32x F +GLIBC_2.27 fmodf64 F +GLIBC_2.27 fmodf64x F +GLIBC_2.27 fmodl F +GLIBC_2.27 frexp F +GLIBC_2.27 frexpf F +GLIBC_2.27 frexpf128 F +GLIBC_2.27 frexpf32 F +GLIBC_2.27 frexpf32x F +GLIBC_2.27 frexpf64 F +GLIBC_2.27 frexpf64x F +GLIBC_2.27 frexpl F +GLIBC_2.27 fromfp F +GLIBC_2.27 fromfpf F +GLIBC_2.27 fromfpf128 F +GLIBC_2.27 fromfpf32 F +GLIBC_2.27 fromfpf32x F +GLIBC_2.27 fromfpf64 F +GLIBC_2.27 fromfpf64x F +GLIBC_2.27 fromfpl F +GLIBC_2.27 fromfpx F +GLIBC_2.27 fromfpxf F +GLIBC_2.27 fromfpxf128 F +GLIBC_2.27 fromfpxf32 F +GLIBC_2.27 fromfpxf32x F +GLIBC_2.27 fromfpxf64 F +GLIBC_2.27 fromfpxf64x F +GLIBC_2.27 fromfpxl F +GLIBC_2.27 gamma F +GLIBC_2.27 gammaf F +GLIBC_2.27 gammal F +GLIBC_2.27 getpayload F +GLIBC_2.27 getpayloadf F +GLIBC_2.27 getpayloadf128 F +GLIBC_2.27 getpayloadf32 F +GLIBC_2.27 getpayloadf32x F +GLIBC_2.27 getpayloadf64 F +GLIBC_2.27 getpayloadf64x F +GLIBC_2.27 getpayloadl F +GLIBC_2.27 hypot F +GLIBC_2.27 hypotf F +GLIBC_2.27 hypotf128 F +GLIBC_2.27 hypotf32 F +GLIBC_2.27 hypotf32x F +GLIBC_2.27 hypotf64 F +GLIBC_2.27 hypotf64x F +GLIBC_2.27 hypotl F +GLIBC_2.27 ilogb F +GLIBC_2.27 ilogbf F +GLIBC_2.27 ilogbf128 F +GLIBC_2.27 ilogbf32 F +GLIBC_2.27 ilogbf32x F +GLIBC_2.27 ilogbf64 F +GLIBC_2.27 ilogbf64x F +GLIBC_2.27 ilogbl F +GLIBC_2.27 j0 F +GLIBC_2.27 j0f F +GLIBC_2.27 j0f128 F +GLIBC_2.27 j0f32 F +GLIBC_2.27 j0f32x F +GLIBC_2.27 j0f64 F +GLIBC_2.27 j0f64x F +GLIBC_2.27 j0l F +GLIBC_2.27 j1 F +GLIBC_2.27 j1f F +GLIBC_2.27 j1f128 F +GLIBC_2.27 j1f32 F +GLIBC_2.27 j1f32x F +GLIBC_2.27 j1f64 F +GLIBC_2.27 j1f64x F +GLIBC_2.27 j1l F +GLIBC_2.27 jn F +GLIBC_2.27 jnf F +GLIBC_2.27 jnf128 F +GLIBC_2.27 jnf32 F +GLIBC_2.27 jnf32x F +GLIBC_2.27 jnf64 F +GLIBC_2.27 jnf64x F +GLIBC_2.27 jnl F +GLIBC_2.27 ldexp F +GLIBC_2.27 ldexpf F +GLIBC_2.27 ldexpf128 F +GLIBC_2.27 ldexpf32 F +GLIBC_2.27 ldexpf32x F +GLIBC_2.27 ldexpf64 F +GLIBC_2.27 ldexpf64x F +GLIBC_2.27 ldexpl F +GLIBC_2.27 lgamma F +GLIBC_2.27 lgamma_r F +GLIBC_2.27 lgammaf F +GLIBC_2.27 lgammaf128 F +GLIBC_2.27 lgammaf128_r F +GLIBC_2.27 lgammaf32 F +GLIBC_2.27 lgammaf32_r F +GLIBC_2.27 lgammaf32x F +GLIBC_2.27 lgammaf32x_r F +GLIBC_2.27 lgammaf64 F +GLIBC_2.27 lgammaf64_r F +GLIBC_2.27 lgammaf64x F +GLIBC_2.27 lgammaf64x_r F +GLIBC_2.27 lgammaf_r F +GLIBC_2.27 lgammal F +GLIBC_2.27 lgammal_r F +GLIBC_2.27 llogb F +GLIBC_2.27 llogbf F +GLIBC_2.27 llogbf128 F +GLIBC_2.27 llogbf32 F +GLIBC_2.27 llogbf32x F +GLIBC_2.27 llogbf64 F +GLIBC_2.27 llogbf64x F +GLIBC_2.27 llogbl F +GLIBC_2.27 llrint F +GLIBC_2.27 llrintf F +GLIBC_2.27 llrintf128 F +GLIBC_2.27 llrintf32 F +GLIBC_2.27 llrintf32x F +GLIBC_2.27 llrintf64 F +GLIBC_2.27 llrintf64x F +GLIBC_2.27 llrintl F +GLIBC_2.27 llround F +GLIBC_2.27 llroundf F +GLIBC_2.27 llroundf128 F +GLIBC_2.27 llroundf32 F +GLIBC_2.27 llroundf32x F +GLIBC_2.27 llroundf64 F +GLIBC_2.27 llroundf64x F +GLIBC_2.27 llroundl F +GLIBC_2.27 log F +GLIBC_2.27 log10 F +GLIBC_2.27 log10f F +GLIBC_2.27 log10f128 F +GLIBC_2.27 log10f32 F +GLIBC_2.27 log10f32x F +GLIBC_2.27 log10f64 F +GLIBC_2.27 log10f64x F +GLIBC_2.27 log10l F +GLIBC_2.27 log1p F +GLIBC_2.27 log1pf F +GLIBC_2.27 log1pf128 F +GLIBC_2.27 log1pf32 F +GLIBC_2.27 log1pf32x F +GLIBC_2.27 log1pf64 F +GLIBC_2.27 log1pf64x F +GLIBC_2.27 log1pl F +GLIBC_2.27 log2 F +GLIBC_2.27 log2f F +GLIBC_2.27 log2f128 F +GLIBC_2.27 log2f32 F +GLIBC_2.27 log2f32x F +GLIBC_2.27 log2f64 F +GLIBC_2.27 log2f64x F +GLIBC_2.27 log2l F +GLIBC_2.27 logb F +GLIBC_2.27 logbf F +GLIBC_2.27 logbf128 F +GLIBC_2.27 logbf32 F +GLIBC_2.27 logbf32x F +GLIBC_2.27 logbf64 F +GLIBC_2.27 logbf64x F +GLIBC_2.27 logbl F +GLIBC_2.27 logf F +GLIBC_2.27 logf128 F +GLIBC_2.27 logf32 F +GLIBC_2.27 logf32x F +GLIBC_2.27 logf64 F +GLIBC_2.27 logf64x F +GLIBC_2.27 logl F +GLIBC_2.27 lrint F +GLIBC_2.27 lrintf F +GLIBC_2.27 lrintf128 F +GLIBC_2.27 lrintf32 F +GLIBC_2.27 lrintf32x F +GLIBC_2.27 lrintf64 F +GLIBC_2.27 lrintf64x F +GLIBC_2.27 lrintl F +GLIBC_2.27 lround F +GLIBC_2.27 lroundf F +GLIBC_2.27 lroundf128 F +GLIBC_2.27 lroundf32 F +GLIBC_2.27 lroundf32x F +GLIBC_2.27 lroundf64 F +GLIBC_2.27 lroundf64x F +GLIBC_2.27 lroundl F +GLIBC_2.27 modf F +GLIBC_2.27 modff F +GLIBC_2.27 modff128 F +GLIBC_2.27 modff32 F +GLIBC_2.27 modff32x F +GLIBC_2.27 modff64 F +GLIBC_2.27 modff64x F +GLIBC_2.27 modfl F +GLIBC_2.27 nan F +GLIBC_2.27 nanf F +GLIBC_2.27 nanf128 F +GLIBC_2.27 nanf32 F +GLIBC_2.27 nanf32x F +GLIBC_2.27 nanf64 F +GLIBC_2.27 nanf64x F +GLIBC_2.27 nanl F +GLIBC_2.27 nearbyint F +GLIBC_2.27 nearbyintf F +GLIBC_2.27 nearbyintf128 F +GLIBC_2.27 nearbyintf32 F +GLIBC_2.27 nearbyintf32x F +GLIBC_2.27 nearbyintf64 F +GLIBC_2.27 nearbyintf64x F +GLIBC_2.27 nearbyintl F +GLIBC_2.27 nextafter F +GLIBC_2.27 nextafterf F +GLIBC_2.27 nextafterf128 F +GLIBC_2.27 nextafterf32 F +GLIBC_2.27 nextafterf32x F +GLIBC_2.27 nextafterf64 F +GLIBC_2.27 nextafterf64x F +GLIBC_2.27 nextafterl F +GLIBC_2.27 nextdown F +GLIBC_2.27 nextdownf F +GLIBC_2.27 nextdownf128 F +GLIBC_2.27 nextdownf32 F +GLIBC_2.27 nextdownf32x F +GLIBC_2.27 nextdownf64 F +GLIBC_2.27 nextdownf64x F +GLIBC_2.27 nextdownl F +GLIBC_2.27 nexttoward F +GLIBC_2.27 nexttowardf F +GLIBC_2.27 nexttowardl F +GLIBC_2.27 nextup F +GLIBC_2.27 nextupf F +GLIBC_2.27 nextupf128 F +GLIBC_2.27 nextupf32 F +GLIBC_2.27 nextupf32x F +GLIBC_2.27 nextupf64 F +GLIBC_2.27 nextupf64x F +GLIBC_2.27 nextupl F +GLIBC_2.27 pow F +GLIBC_2.27 powf F +GLIBC_2.27 powf128 F +GLIBC_2.27 powf32 F +GLIBC_2.27 powf32x F +GLIBC_2.27 powf64 F +GLIBC_2.27 powf64x F +GLIBC_2.27 powl F +GLIBC_2.27 remainder F +GLIBC_2.27 remainderf F +GLIBC_2.27 remainderf128 F +GLIBC_2.27 remainderf32 F +GLIBC_2.27 remainderf32x F +GLIBC_2.27 remainderf64 F +GLIBC_2.27 remainderf64x F +GLIBC_2.27 remainderl F +GLIBC_2.27 remquo F +GLIBC_2.27 remquof F +GLIBC_2.27 remquof128 F +GLIBC_2.27 remquof32 F +GLIBC_2.27 remquof32x F +GLIBC_2.27 remquof64 F +GLIBC_2.27 remquof64x F +GLIBC_2.27 remquol F +GLIBC_2.27 rint F +GLIBC_2.27 rintf F +GLIBC_2.27 rintf128 F +GLIBC_2.27 rintf32 F +GLIBC_2.27 rintf32x F +GLIBC_2.27 rintf64 F +GLIBC_2.27 rintf64x F +GLIBC_2.27 rintl F +GLIBC_2.27 round F +GLIBC_2.27 roundeven F +GLIBC_2.27 roundevenf F +GLIBC_2.27 roundevenf128 F +GLIBC_2.27 roundevenf32 F +GLIBC_2.27 roundevenf32x F +GLIBC_2.27 roundevenf64 F +GLIBC_2.27 roundevenf64x F +GLIBC_2.27 roundevenl F +GLIBC_2.27 roundf F +GLIBC_2.27 roundf128 F +GLIBC_2.27 roundf32 F +GLIBC_2.27 roundf32x F +GLIBC_2.27 roundf64 F +GLIBC_2.27 roundf64x F +GLIBC_2.27 roundl F +GLIBC_2.27 scalb F +GLIBC_2.27 scalbf F +GLIBC_2.27 scalbl F +GLIBC_2.27 scalbln F +GLIBC_2.27 scalblnf F +GLIBC_2.27 scalblnf128 F +GLIBC_2.27 scalblnf32 F +GLIBC_2.27 scalblnf32x F +GLIBC_2.27 scalblnf64 F +GLIBC_2.27 scalblnf64x F +GLIBC_2.27 scalblnl F +GLIBC_2.27 scalbn F +GLIBC_2.27 scalbnf F +GLIBC_2.27 scalbnf128 F +GLIBC_2.27 scalbnf32 F +GLIBC_2.27 scalbnf32x F +GLIBC_2.27 scalbnf64 F +GLIBC_2.27 scalbnf64x F +GLIBC_2.27 scalbnl F +GLIBC_2.27 setpayload F +GLIBC_2.27 setpayloadf F +GLIBC_2.27 setpayloadf128 F +GLIBC_2.27 setpayloadf32 F +GLIBC_2.27 setpayloadf32x F +GLIBC_2.27 setpayloadf64 F +GLIBC_2.27 setpayloadf64x F +GLIBC_2.27 setpayloadl F +GLIBC_2.27 setpayloadsig F +GLIBC_2.27 setpayloadsigf F +GLIBC_2.27 setpayloadsigf128 F +GLIBC_2.27 setpayloadsigf32 F +GLIBC_2.27 setpayloadsigf32x F +GLIBC_2.27 setpayloadsigf64 F +GLIBC_2.27 setpayloadsigf64x F +GLIBC_2.27 setpayloadsigl F +GLIBC_2.27 signgam D 0x4 +GLIBC_2.27 significand F +GLIBC_2.27 significandf F +GLIBC_2.27 significandl F +GLIBC_2.27 sin F +GLIBC_2.27 sincos F +GLIBC_2.27 sincosf F +GLIBC_2.27 sincosf128 F +GLIBC_2.27 sincosf32 F +GLIBC_2.27 sincosf32x F +GLIBC_2.27 sincosf64 F +GLIBC_2.27 sincosf64x F +GLIBC_2.27 sincosl F +GLIBC_2.27 sinf F +GLIBC_2.27 sinf128 F +GLIBC_2.27 sinf32 F +GLIBC_2.27 sinf32x F +GLIBC_2.27 sinf64 F +GLIBC_2.27 sinf64x F +GLIBC_2.27 sinh F +GLIBC_2.27 sinhf F +GLIBC_2.27 sinhf128 F +GLIBC_2.27 sinhf32 F +GLIBC_2.27 sinhf32x F +GLIBC_2.27 sinhf64 F +GLIBC_2.27 sinhf64x F +GLIBC_2.27 sinhl F +GLIBC_2.27 sinl F +GLIBC_2.27 sqrt F +GLIBC_2.27 sqrtf F +GLIBC_2.27 sqrtf128 F +GLIBC_2.27 sqrtf32 F +GLIBC_2.27 sqrtf32x F +GLIBC_2.27 sqrtf64 F +GLIBC_2.27 sqrtf64x F +GLIBC_2.27 sqrtl F +GLIBC_2.27 tan F +GLIBC_2.27 tanf F +GLIBC_2.27 tanf128 F +GLIBC_2.27 tanf32 F +GLIBC_2.27 tanf32x F +GLIBC_2.27 tanf64 F +GLIBC_2.27 tanf64x F +GLIBC_2.27 tanh F +GLIBC_2.27 tanhf F +GLIBC_2.27 tanhf128 F +GLIBC_2.27 tanhf32 F +GLIBC_2.27 tanhf32x F +GLIBC_2.27 tanhf64 F +GLIBC_2.27 tanhf64x F +GLIBC_2.27 tanhl F +GLIBC_2.27 tanl F +GLIBC_2.27 tgamma F +GLIBC_2.27 tgammaf F +GLIBC_2.27 tgammaf128 F +GLIBC_2.27 tgammaf32 F +GLIBC_2.27 tgammaf32x F +GLIBC_2.27 tgammaf64 F +GLIBC_2.27 tgammaf64x F +GLIBC_2.27 tgammal F +GLIBC_2.27 totalorder F +GLIBC_2.27 totalorderf F +GLIBC_2.27 totalorderf128 F +GLIBC_2.27 totalorderf32 F +GLIBC_2.27 totalorderf32x F +GLIBC_2.27 totalorderf64 F +GLIBC_2.27 totalorderf64x F +GLIBC_2.27 totalorderl F +GLIBC_2.27 totalordermag F +GLIBC_2.27 totalordermagf F +GLIBC_2.27 totalordermagf128 F +GLIBC_2.27 totalordermagf32 F +GLIBC_2.27 totalordermagf32x F +GLIBC_2.27 totalordermagf64 F +GLIBC_2.27 totalordermagf64x F +GLIBC_2.27 totalordermagl F +GLIBC_2.27 trunc F +GLIBC_2.27 truncf F +GLIBC_2.27 truncf128 F +GLIBC_2.27 truncf32 F +GLIBC_2.27 truncf32x F +GLIBC_2.27 truncf64 F +GLIBC_2.27 truncf64x F +GLIBC_2.27 truncl F +GLIBC_2.27 ufromfp F +GLIBC_2.27 ufromfpf F +GLIBC_2.27 ufromfpf128 F +GLIBC_2.27 ufromfpf32 F +GLIBC_2.27 ufromfpf32x F +GLIBC_2.27 ufromfpf64 F +GLIBC_2.27 ufromfpf64x F +GLIBC_2.27 ufromfpl F +GLIBC_2.27 ufromfpx F +GLIBC_2.27 ufromfpxf F +GLIBC_2.27 ufromfpxf128 F +GLIBC_2.27 ufromfpxf32 F +GLIBC_2.27 ufromfpxf32x F +GLIBC_2.27 ufromfpxf64 F +GLIBC_2.27 ufromfpxf64x F +GLIBC_2.27 ufromfpxl F +GLIBC_2.27 y0 F +GLIBC_2.27 y0f F +GLIBC_2.27 y0f128 F +GLIBC_2.27 y0f32 F +GLIBC_2.27 y0f32x F +GLIBC_2.27 y0f64 F +GLIBC_2.27 y0f64x F +GLIBC_2.27 y0l F +GLIBC_2.27 y1 F +GLIBC_2.27 y1f F +GLIBC_2.27 y1f128 F +GLIBC_2.27 y1f32 F +GLIBC_2.27 y1f32x F +GLIBC_2.27 y1f64 F +GLIBC_2.27 y1f64x F +GLIBC_2.27 y1l F +GLIBC_2.27 yn F +GLIBC_2.27 ynf F +GLIBC_2.27 ynf128 F +GLIBC_2.27 ynf32 F +GLIBC_2.27 ynf32x F +GLIBC_2.27 ynf64 F +GLIBC_2.27 ynf64x F +GLIBC_2.27 ynl F +GLIBC_2.28 daddl F +GLIBC_2.28 ddivl F +GLIBC_2.28 dmull F +GLIBC_2.28 dsubl F +GLIBC_2.28 f32addf128 F +GLIBC_2.28 f32addf32x F +GLIBC_2.28 f32addf64 F +GLIBC_2.28 f32addf64x F +GLIBC_2.28 f32divf128 F +GLIBC_2.28 f32divf32x F +GLIBC_2.28 f32divf64 F +GLIBC_2.28 f32divf64x F +GLIBC_2.28 f32mulf128 F +GLIBC_2.28 f32mulf32x F +GLIBC_2.28 f32mulf64 F +GLIBC_2.28 f32mulf64x F +GLIBC_2.28 f32subf128 F +GLIBC_2.28 f32subf32x F +GLIBC_2.28 f32subf64 F +GLIBC_2.28 f32subf64x F +GLIBC_2.28 f32xaddf128 F +GLIBC_2.28 f32xaddf64 F +GLIBC_2.28 f32xaddf64x F +GLIBC_2.28 f32xdivf128 F +GLIBC_2.28 f32xdivf64 F +GLIBC_2.28 f32xdivf64x F +GLIBC_2.28 f32xmulf128 F +GLIBC_2.28 f32xmulf64 F +GLIBC_2.28 f32xmulf64x F +GLIBC_2.28 f32xsubf128 F +GLIBC_2.28 f32xsubf64 F +GLIBC_2.28 f32xsubf64x F +GLIBC_2.28 f64addf128 F +GLIBC_2.28 f64addf64x F +GLIBC_2.28 f64divf128 F +GLIBC_2.28 f64divf64x F +GLIBC_2.28 f64mulf128 F +GLIBC_2.28 f64mulf64x F +GLIBC_2.28 f64subf128 F +GLIBC_2.28 f64subf64x F +GLIBC_2.28 f64xaddf128 F +GLIBC_2.28 f64xdivf128 F +GLIBC_2.28 f64xmulf128 F +GLIBC_2.28 f64xsubf128 F +GLIBC_2.28 fadd F +GLIBC_2.28 faddl F +GLIBC_2.28 fdiv F +GLIBC_2.28 fdivl F +GLIBC_2.28 fmul F +GLIBC_2.28 fmull F +GLIBC_2.28 fsub F +GLIBC_2.28 fsubl F diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libnsl.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libnsl.abilist new file mode 100644 index 00000000..0767472d --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libnsl.abilist @@ -0,0 +1,120 @@ +GLIBC_2.27 __free_fdresult F +GLIBC_2.27 __nis_default_access F +GLIBC_2.27 __nis_default_group F +GLIBC_2.27 __nis_default_owner F +GLIBC_2.27 __nis_default_ttl F +GLIBC_2.27 __nis_finddirectory F +GLIBC_2.27 __nisbind_connect F +GLIBC_2.27 __nisbind_create F +GLIBC_2.27 __nisbind_destroy F +GLIBC_2.27 __nisbind_next F +GLIBC_2.27 __yp_check F +GLIBC_2.27 nis_add F +GLIBC_2.27 nis_add_entry F +GLIBC_2.27 nis_addmember F +GLIBC_2.27 nis_checkpoint F +GLIBC_2.27 nis_clone_directory F +GLIBC_2.27 nis_clone_object F +GLIBC_2.27 nis_clone_result F +GLIBC_2.27 nis_creategroup F +GLIBC_2.27 nis_destroy_object F +GLIBC_2.27 nis_destroygroup F +GLIBC_2.27 nis_dir_cmp F +GLIBC_2.27 nis_domain_of F +GLIBC_2.27 nis_domain_of_r F +GLIBC_2.27 nis_first_entry F +GLIBC_2.27 nis_free_directory F +GLIBC_2.27 nis_free_object F +GLIBC_2.27 nis_free_request F +GLIBC_2.27 nis_freenames F +GLIBC_2.27 nis_freeresult F +GLIBC_2.27 nis_freeservlist F +GLIBC_2.27 nis_freetags F +GLIBC_2.27 nis_getnames F +GLIBC_2.27 nis_getservlist F +GLIBC_2.27 nis_ismember F +GLIBC_2.27 nis_leaf_of F +GLIBC_2.27 nis_leaf_of_r F +GLIBC_2.27 nis_lerror F +GLIBC_2.27 nis_list F +GLIBC_2.27 nis_local_directory F +GLIBC_2.27 nis_local_group F +GLIBC_2.27 nis_local_host F +GLIBC_2.27 nis_local_principal F +GLIBC_2.27 nis_lookup F +GLIBC_2.27 nis_mkdir F +GLIBC_2.27 nis_modify F +GLIBC_2.27 nis_modify_entry F +GLIBC_2.27 nis_name_of F +GLIBC_2.27 nis_name_of_r F +GLIBC_2.27 nis_next_entry F +GLIBC_2.27 nis_perror F +GLIBC_2.27 nis_ping F +GLIBC_2.27 nis_print_directory F +GLIBC_2.27 nis_print_entry F +GLIBC_2.27 nis_print_group F +GLIBC_2.27 nis_print_group_entry F +GLIBC_2.27 nis_print_link F +GLIBC_2.27 nis_print_object F +GLIBC_2.27 nis_print_result F +GLIBC_2.27 nis_print_rights F +GLIBC_2.27 nis_print_table F +GLIBC_2.27 nis_read_obj F +GLIBC_2.27 nis_remove F +GLIBC_2.27 nis_remove_entry F +GLIBC_2.27 nis_removemember F +GLIBC_2.27 nis_rmdir F +GLIBC_2.27 nis_servstate F +GLIBC_2.27 nis_sperrno F +GLIBC_2.27 nis_sperror F +GLIBC_2.27 nis_sperror_r F +GLIBC_2.27 nis_stats F +GLIBC_2.27 nis_verifygroup F +GLIBC_2.27 nis_write_obj F +GLIBC_2.27 readColdStartFile F +GLIBC_2.27 writeColdStartFile F +GLIBC_2.27 xdr_cback_data F +GLIBC_2.27 xdr_domainname F +GLIBC_2.27 xdr_keydat F +GLIBC_2.27 xdr_mapname F +GLIBC_2.27 xdr_obj_p F +GLIBC_2.27 xdr_peername F +GLIBC_2.27 xdr_valdat F +GLIBC_2.27 xdr_yp_buf F +GLIBC_2.27 xdr_ypall F +GLIBC_2.27 xdr_ypbind_binding F +GLIBC_2.27 xdr_ypbind_resp F +GLIBC_2.27 xdr_ypbind_resptype F +GLIBC_2.27 xdr_ypbind_setdom F +GLIBC_2.27 xdr_ypdelete_args F +GLIBC_2.27 xdr_ypmap_parms F +GLIBC_2.27 xdr_ypmaplist F +GLIBC_2.27 xdr_yppush_status F +GLIBC_2.27 xdr_yppushresp_xfr F +GLIBC_2.27 xdr_ypreq_key F +GLIBC_2.27 xdr_ypreq_nokey F +GLIBC_2.27 xdr_ypreq_xfr F +GLIBC_2.27 xdr_ypresp_all F +GLIBC_2.27 xdr_ypresp_key_val F +GLIBC_2.27 xdr_ypresp_maplist F +GLIBC_2.27 xdr_ypresp_master F +GLIBC_2.27 xdr_ypresp_order F +GLIBC_2.27 xdr_ypresp_val F +GLIBC_2.27 xdr_ypresp_xfr F +GLIBC_2.27 xdr_ypstat F +GLIBC_2.27 xdr_ypupdate_args F +GLIBC_2.27 xdr_ypxfrstat F +GLIBC_2.27 yp_all F +GLIBC_2.27 yp_bind F +GLIBC_2.27 yp_first F +GLIBC_2.27 yp_get_default_domain F +GLIBC_2.27 yp_maplist F +GLIBC_2.27 yp_master F +GLIBC_2.27 yp_match F +GLIBC_2.27 yp_next F +GLIBC_2.27 yp_order F +GLIBC_2.27 yp_unbind F +GLIBC_2.27 yp_update F +GLIBC_2.27 ypbinderr_string F +GLIBC_2.27 yperr_string F +GLIBC_2.27 ypprot_err F diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libpthread.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libpthread.abilist new file mode 100644 index 00000000..f60b22ef --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libpthread.abilist @@ -0,0 +1,264 @@ +GLIBC_2.0 _IO_flockfile F +GLIBC_2.0 _IO_ftrylockfile F +GLIBC_2.0 _IO_funlockfile F +GLIBC_2.0 __close F +GLIBC_2.0 __connect F +GLIBC_2.0 __errno_location F +GLIBC_2.0 __fcntl F +GLIBC_2.0 __fork F +GLIBC_2.0 __h_errno_location F +GLIBC_2.0 __lseek F +GLIBC_2.0 __open F +GLIBC_2.0 __pthread_getspecific F +GLIBC_2.0 __pthread_key_create F +GLIBC_2.0 __pthread_mutex_destroy F +GLIBC_2.0 __pthread_mutex_init F +GLIBC_2.0 __pthread_mutex_lock F +GLIBC_2.0 __pthread_mutex_trylock F +GLIBC_2.0 __pthread_mutex_unlock F +GLIBC_2.0 __pthread_mutexattr_destroy F +GLIBC_2.0 __pthread_mutexattr_init F +GLIBC_2.0 __pthread_mutexattr_settype F +GLIBC_2.0 __pthread_once F +GLIBC_2.0 __pthread_setspecific F +GLIBC_2.0 __read F +GLIBC_2.0 __send F +GLIBC_2.0 __sigaction F +GLIBC_2.0 __wait F +GLIBC_2.0 __write F +GLIBC_2.0 _pthread_cleanup_pop F +GLIBC_2.0 _pthread_cleanup_pop_restore F +GLIBC_2.0 _pthread_cleanup_push F +GLIBC_2.0 _pthread_cleanup_push_defer F +GLIBC_2.0 accept F +GLIBC_2.0 close F +GLIBC_2.0 connect F +GLIBC_2.0 fcntl F +GLIBC_2.0 flockfile F +GLIBC_2.0 fork F +GLIBC_2.0 fsync F +GLIBC_2.0 ftrylockfile F +GLIBC_2.0 funlockfile F +GLIBC_2.0 longjmp F +GLIBC_2.0 lseek F +GLIBC_2.0 msync F +GLIBC_2.0 nanosleep F +GLIBC_2.0 open F +GLIBC_2.0 pause F +GLIBC_2.0 pthread_atfork F +GLIBC_2.0 pthread_attr_destroy F +GLIBC_2.0 pthread_attr_getdetachstate F +GLIBC_2.0 pthread_attr_getinheritsched F +GLIBC_2.0 pthread_attr_getschedparam F +GLIBC_2.0 pthread_attr_getschedpolicy F +GLIBC_2.0 pthread_attr_getscope F +GLIBC_2.0 pthread_attr_init F +GLIBC_2.0 pthread_attr_setdetachstate F +GLIBC_2.0 pthread_attr_setinheritsched F +GLIBC_2.0 pthread_attr_setschedparam F +GLIBC_2.0 pthread_attr_setschedpolicy F +GLIBC_2.0 pthread_attr_setscope F +GLIBC_2.0 pthread_cancel F +GLIBC_2.0 pthread_cond_broadcast F +GLIBC_2.0 pthread_cond_destroy F +GLIBC_2.0 pthread_cond_init F +GLIBC_2.0 pthread_cond_signal F +GLIBC_2.0 pthread_cond_timedwait F +GLIBC_2.0 pthread_cond_wait F +GLIBC_2.0 pthread_condattr_destroy F +GLIBC_2.0 pthread_condattr_init F +GLIBC_2.0 pthread_create F +GLIBC_2.0 pthread_detach F +GLIBC_2.0 pthread_equal F +GLIBC_2.0 pthread_exit F +GLIBC_2.0 pthread_getschedparam F +GLIBC_2.0 pthread_getspecific F +GLIBC_2.0 pthread_join F +GLIBC_2.0 pthread_key_create F +GLIBC_2.0 pthread_key_delete F +GLIBC_2.0 pthread_kill F +GLIBC_2.0 pthread_kill_other_threads_np F +GLIBC_2.0 pthread_mutex_destroy F +GLIBC_2.0 pthread_mutex_init F +GLIBC_2.0 pthread_mutex_lock F +GLIBC_2.0 pthread_mutex_trylock F +GLIBC_2.0 pthread_mutex_unlock F +GLIBC_2.0 pthread_mutexattr_destroy F +GLIBC_2.0 pthread_mutexattr_getkind_np F +GLIBC_2.0 pthread_mutexattr_init F +GLIBC_2.0 pthread_mutexattr_setkind_np F +GLIBC_2.0 pthread_once F +GLIBC_2.0 pthread_self F +GLIBC_2.0 pthread_setcancelstate F +GLIBC_2.0 pthread_setcanceltype F +GLIBC_2.0 pthread_setschedparam F +GLIBC_2.0 pthread_setspecific F +GLIBC_2.0 pthread_sigmask F +GLIBC_2.0 pthread_testcancel F +GLIBC_2.0 raise F +GLIBC_2.0 read F +GLIBC_2.0 recv F +GLIBC_2.0 recvfrom F +GLIBC_2.0 recvmsg F +GLIBC_2.0 sem_destroy F +GLIBC_2.0 sem_getvalue F +GLIBC_2.0 sem_init F +GLIBC_2.0 sem_post F +GLIBC_2.0 sem_trywait F +GLIBC_2.0 sem_wait F +GLIBC_2.0 send F +GLIBC_2.0 sendmsg F +GLIBC_2.0 sendto F +GLIBC_2.0 sigaction F +GLIBC_2.0 siglongjmp F +GLIBC_2.0 sigwait F +GLIBC_2.0 system F +GLIBC_2.0 tcdrain F +GLIBC_2.0 wait F +GLIBC_2.0 waitpid F +GLIBC_2.0 write F +GLIBC_2.11 pthread_sigqueue F +GLIBC_2.12 pthread_getname_np F +GLIBC_2.12 pthread_mutex_consistent F +GLIBC_2.12 pthread_mutexattr_getrobust F +GLIBC_2.12 pthread_mutexattr_setrobust F +GLIBC_2.12 pthread_setname_np F +GLIBC_2.18 pthread_getattr_default_np F +GLIBC_2.18 pthread_setattr_default_np F +GLIBC_2.2 __libc_allocate_rtsig F +GLIBC_2.2 __libc_current_sigrtmax F +GLIBC_2.2 __libc_current_sigrtmin F +GLIBC_2.2 __open64 F +GLIBC_2.2 __pread64 F +GLIBC_2.2 __pthread_rwlock_destroy F +GLIBC_2.2 __pthread_rwlock_init F +GLIBC_2.2 __pthread_rwlock_rdlock F +GLIBC_2.2 __pthread_rwlock_tryrdlock F +GLIBC_2.2 __pthread_rwlock_trywrlock F +GLIBC_2.2 __pthread_rwlock_unlock F +GLIBC_2.2 __pthread_rwlock_wrlock F +GLIBC_2.2 __pwrite64 F +GLIBC_2.2 __res_state F +GLIBC_2.2 lseek64 F +GLIBC_2.2 open64 F +GLIBC_2.2 pread F +GLIBC_2.2 pread64 F +GLIBC_2.2 pthread_attr_getguardsize F +GLIBC_2.2 pthread_attr_getstack F +GLIBC_2.2 pthread_attr_getstackaddr F +GLIBC_2.2 pthread_attr_getstacksize F +GLIBC_2.2 pthread_attr_init F +GLIBC_2.2 pthread_attr_setguardsize F +GLIBC_2.2 pthread_attr_setstack F +GLIBC_2.2 pthread_attr_setstackaddr F +GLIBC_2.2 pthread_attr_setstacksize F +GLIBC_2.2 pthread_barrier_destroy F +GLIBC_2.2 pthread_barrier_init F +GLIBC_2.2 pthread_barrier_wait F +GLIBC_2.2 pthread_barrierattr_destroy F +GLIBC_2.2 pthread_barrierattr_init F +GLIBC_2.2 pthread_barrierattr_setpshared F +GLIBC_2.2 pthread_condattr_getpshared F +GLIBC_2.2 pthread_condattr_setpshared F +GLIBC_2.2 pthread_create F +GLIBC_2.2 pthread_getconcurrency F +GLIBC_2.2 pthread_getcpuclockid F +GLIBC_2.2 pthread_mutex_timedlock F +GLIBC_2.2 pthread_mutexattr_getpshared F +GLIBC_2.2 pthread_mutexattr_gettype F +GLIBC_2.2 pthread_mutexattr_setpshared F +GLIBC_2.2 pthread_mutexattr_settype F +GLIBC_2.2 pthread_rwlock_destroy F +GLIBC_2.2 pthread_rwlock_init F +GLIBC_2.2 pthread_rwlock_rdlock F +GLIBC_2.2 pthread_rwlock_timedrdlock F +GLIBC_2.2 pthread_rwlock_timedwrlock F +GLIBC_2.2 pthread_rwlock_tryrdlock F +GLIBC_2.2 pthread_rwlock_trywrlock F +GLIBC_2.2 pthread_rwlock_unlock F +GLIBC_2.2 pthread_rwlock_wrlock F +GLIBC_2.2 pthread_rwlockattr_destroy F +GLIBC_2.2 pthread_rwlockattr_getkind_np F +GLIBC_2.2 pthread_rwlockattr_getpshared F +GLIBC_2.2 pthread_rwlockattr_init F +GLIBC_2.2 pthread_rwlockattr_setkind_np F +GLIBC_2.2 pthread_rwlockattr_setpshared F +GLIBC_2.2 pthread_setconcurrency F +GLIBC_2.2 pthread_spin_destroy F +GLIBC_2.2 pthread_spin_init F +GLIBC_2.2 pthread_spin_lock F +GLIBC_2.2 pthread_spin_trylock F +GLIBC_2.2 pthread_spin_unlock F +GLIBC_2.2 pthread_yield F +GLIBC_2.2 pwrite F +GLIBC_2.2 pwrite64 F +GLIBC_2.2 sem_close F +GLIBC_2.2 sem_destroy F +GLIBC_2.2 sem_getvalue F +GLIBC_2.2 sem_init F +GLIBC_2.2 sem_open F +GLIBC_2.2 sem_post F +GLIBC_2.2 sem_timedwait F +GLIBC_2.2 sem_trywait F +GLIBC_2.2 sem_unlink F +GLIBC_2.2 sem_wait F +GLIBC_2.2.3 pthread_getattr_np F +GLIBC_2.2.6 __nanosleep F +GLIBC_2.28 call_once F +GLIBC_2.28 cnd_broadcast F +GLIBC_2.28 cnd_destroy F +GLIBC_2.28 cnd_init F +GLIBC_2.28 cnd_signal F +GLIBC_2.28 cnd_timedwait F +GLIBC_2.28 cnd_wait F +GLIBC_2.28 mtx_destroy F +GLIBC_2.28 mtx_init F +GLIBC_2.28 mtx_lock F +GLIBC_2.28 mtx_timedlock F +GLIBC_2.28 mtx_trylock F +GLIBC_2.28 mtx_unlock F +GLIBC_2.28 thrd_create F +GLIBC_2.28 thrd_detach F +GLIBC_2.28 thrd_exit F +GLIBC_2.28 thrd_join F +GLIBC_2.28 tss_create F +GLIBC_2.28 tss_delete F +GLIBC_2.28 tss_get F +GLIBC_2.28 tss_set F +GLIBC_2.3.2 pthread_cond_broadcast F +GLIBC_2.3.2 pthread_cond_destroy F +GLIBC_2.3.2 pthread_cond_init F +GLIBC_2.3.2 pthread_cond_signal F +GLIBC_2.3.2 pthread_cond_timedwait F +GLIBC_2.3.2 pthread_cond_wait F +GLIBC_2.3.3 __pthread_cleanup_routine F +GLIBC_2.3.3 __pthread_register_cancel F +GLIBC_2.3.3 __pthread_register_cancel_defer F +GLIBC_2.3.3 __pthread_unregister_cancel F +GLIBC_2.3.3 __pthread_unregister_cancel_restore F +GLIBC_2.3.3 __pthread_unwind_next F +GLIBC_2.3.3 pthread_attr_getaffinity_np F +GLIBC_2.3.3 pthread_attr_setaffinity_np F +GLIBC_2.3.3 pthread_attr_setstack F +GLIBC_2.3.3 pthread_attr_setstacksize F +GLIBC_2.3.3 pthread_barrierattr_getpshared F +GLIBC_2.3.3 pthread_condattr_getclock F +GLIBC_2.3.3 pthread_condattr_setclock F +GLIBC_2.3.3 pthread_getaffinity_np F +GLIBC_2.3.3 pthread_setaffinity_np F +GLIBC_2.3.3 pthread_timedjoin_np F +GLIBC_2.3.3 pthread_tryjoin_np F +GLIBC_2.3.4 pthread_attr_getaffinity_np F +GLIBC_2.3.4 pthread_attr_setaffinity_np F +GLIBC_2.3.4 pthread_getaffinity_np F +GLIBC_2.3.4 pthread_setaffinity_np F +GLIBC_2.3.4 pthread_setschedprio F +GLIBC_2.4 pthread_mutex_consistent_np F +GLIBC_2.4 pthread_mutex_getprioceiling F +GLIBC_2.4 pthread_mutex_setprioceiling F +GLIBC_2.4 pthread_mutexattr_getprioceiling F +GLIBC_2.4 pthread_mutexattr_getprotocol F +GLIBC_2.4 pthread_mutexattr_getrobust_np F +GLIBC_2.4 pthread_mutexattr_setprioceiling F +GLIBC_2.4 pthread_mutexattr_setprotocol F +GLIBC_2.4 pthread_mutexattr_setrobust_np F diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libresolv.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libresolv.abilist new file mode 100644 index 00000000..eb9c1cb7 --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libresolv.abilist @@ -0,0 +1,79 @@ +GLIBC_2.27 __b64_ntop F +GLIBC_2.27 __b64_pton F +GLIBC_2.27 __dn_comp F +GLIBC_2.27 __dn_count_labels F +GLIBC_2.27 __dn_expand F +GLIBC_2.27 __dn_skipname F +GLIBC_2.27 __fp_nquery F +GLIBC_2.27 __fp_query F +GLIBC_2.27 __fp_resstat F +GLIBC_2.27 __hostalias F +GLIBC_2.27 __loc_aton F +GLIBC_2.27 __loc_ntoa F +GLIBC_2.27 __p_cdname F +GLIBC_2.27 __p_cdnname F +GLIBC_2.27 __p_class F +GLIBC_2.27 __p_class_syms D 0xa8 +GLIBC_2.27 __p_fqname F +GLIBC_2.27 __p_fqnname F +GLIBC_2.27 __p_option F +GLIBC_2.27 __p_query F +GLIBC_2.27 __p_rcode F +GLIBC_2.27 __p_time F +GLIBC_2.27 __p_type F +GLIBC_2.27 __p_type_syms D 0x450 +GLIBC_2.27 __putlong F +GLIBC_2.27 __putshort F +GLIBC_2.27 __res_close F +GLIBC_2.27 __res_dnok F +GLIBC_2.27 __res_hnok F +GLIBC_2.27 __res_hostalias F +GLIBC_2.27 __res_isourserver F +GLIBC_2.27 __res_mailok F +GLIBC_2.27 __res_mkquery F +GLIBC_2.27 __res_nameinquery F +GLIBC_2.27 __res_nmkquery F +GLIBC_2.27 __res_nquery F +GLIBC_2.27 __res_nquerydomain F +GLIBC_2.27 __res_nsearch F +GLIBC_2.27 __res_nsend F +GLIBC_2.27 __res_ownok F +GLIBC_2.27 __res_queriesmatch F +GLIBC_2.27 __res_query F +GLIBC_2.27 __res_querydomain F +GLIBC_2.27 __res_search F +GLIBC_2.27 __res_send F +GLIBC_2.27 __sym_ntop F +GLIBC_2.27 __sym_ntos F +GLIBC_2.27 __sym_ston F +GLIBC_2.27 _getlong F +GLIBC_2.27 _getshort F +GLIBC_2.27 inet_net_ntop F +GLIBC_2.27 inet_net_pton F +GLIBC_2.27 inet_neta F +GLIBC_2.27 ns_datetosecs F +GLIBC_2.27 ns_format_ttl F +GLIBC_2.27 ns_get16 F +GLIBC_2.27 ns_get32 F +GLIBC_2.27 ns_initparse F +GLIBC_2.27 ns_makecanon F +GLIBC_2.27 ns_msg_getflag F +GLIBC_2.27 ns_name_compress F +GLIBC_2.27 ns_name_ntol F +GLIBC_2.27 ns_name_ntop F +GLIBC_2.27 ns_name_pack F +GLIBC_2.27 ns_name_pton F +GLIBC_2.27 ns_name_rollback F +GLIBC_2.27 ns_name_skip F +GLIBC_2.27 ns_name_uncompress F +GLIBC_2.27 ns_name_unpack F +GLIBC_2.27 ns_parse_ttl F +GLIBC_2.27 ns_parserr F +GLIBC_2.27 ns_put16 F +GLIBC_2.27 ns_put32 F +GLIBC_2.27 ns_samedomain F +GLIBC_2.27 ns_samename F +GLIBC_2.27 ns_skiprr F +GLIBC_2.27 ns_sprintrr F +GLIBC_2.27 ns_sprintrrf F +GLIBC_2.27 ns_subdomain F diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/librt.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/librt.abilist new file mode 100644 index 00000000..bfd262ec --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/lp64/librt.abilist @@ -0,0 +1,35 @@ +GLIBC_2.27 __mq_open_2 F +GLIBC_2.27 aio_cancel F +GLIBC_2.27 aio_cancel64 F +GLIBC_2.27 aio_error F +GLIBC_2.27 aio_error64 F +GLIBC_2.27 aio_fsync F +GLIBC_2.27 aio_fsync64 F +GLIBC_2.27 aio_init F +GLIBC_2.27 aio_read F +GLIBC_2.27 aio_read64 F +GLIBC_2.27 aio_return F +GLIBC_2.27 aio_return64 F +GLIBC_2.27 aio_suspend F +GLIBC_2.27 aio_suspend64 F +GLIBC_2.27 aio_write F +GLIBC_2.27 aio_write64 F +GLIBC_2.27 lio_listio F +GLIBC_2.27 lio_listio64 F +GLIBC_2.27 mq_close F +GLIBC_2.27 mq_getattr F +GLIBC_2.27 mq_notify F +GLIBC_2.27 mq_open F +GLIBC_2.27 mq_receive F +GLIBC_2.27 mq_send F +GLIBC_2.27 mq_setattr F +GLIBC_2.27 mq_timedreceive F +GLIBC_2.27 mq_timedsend F +GLIBC_2.27 mq_unlink F +GLIBC_2.27 shm_open F +GLIBC_2.27 shm_unlink F +GLIBC_2.27 timer_create F +GLIBC_2.27 timer_delete F +GLIBC_2.27 timer_getoverrun F +GLIBC_2.27 timer_gettime F +GLIBC_2.27 timer_settime F diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libthread_db.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libthread_db.abilist new file mode 100644 index 00000000..4122e563 --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libthread_db.abilist @@ -0,0 +1,40 @@ +GLIBC_2.27 td_init F +GLIBC_2.27 td_log F +GLIBC_2.27 td_symbol_list F +GLIBC_2.27 td_ta_clear_event F +GLIBC_2.27 td_ta_delete F +GLIBC_2.27 td_ta_enable_stats F +GLIBC_2.27 td_ta_event_addr F +GLIBC_2.27 td_ta_event_getmsg F +GLIBC_2.27 td_ta_get_nthreads F +GLIBC_2.27 td_ta_get_ph F +GLIBC_2.27 td_ta_get_stats F +GLIBC_2.27 td_ta_map_id2thr F +GLIBC_2.27 td_ta_map_lwp2thr F +GLIBC_2.27 td_ta_new F +GLIBC_2.27 td_ta_reset_stats F +GLIBC_2.27 td_ta_set_event F +GLIBC_2.27 td_ta_setconcurrency F +GLIBC_2.27 td_ta_thr_iter F +GLIBC_2.27 td_ta_tsd_iter F +GLIBC_2.27 td_thr_clear_event F +GLIBC_2.27 td_thr_dbresume F +GLIBC_2.27 td_thr_dbsuspend F +GLIBC_2.27 td_thr_event_enable F +GLIBC_2.27 td_thr_event_getmsg F +GLIBC_2.27 td_thr_get_info F +GLIBC_2.27 td_thr_getfpregs F +GLIBC_2.27 td_thr_getgregs F +GLIBC_2.27 td_thr_getxregs F +GLIBC_2.27 td_thr_getxregsize F +GLIBC_2.27 td_thr_set_event F +GLIBC_2.27 td_thr_setfpregs F +GLIBC_2.27 td_thr_setgregs F +GLIBC_2.27 td_thr_setprio F +GLIBC_2.27 td_thr_setsigpending F +GLIBC_2.27 td_thr_setxregs F +GLIBC_2.27 td_thr_sigsetmask F +GLIBC_2.27 td_thr_tls_get_addr F +GLIBC_2.27 td_thr_tlsbase F +GLIBC_2.27 td_thr_tsd F +GLIBC_2.27 td_thr_validate F diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libutil.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libutil.abilist new file mode 100644 index 00000000..cbfec8d4 --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libutil.abilist @@ -0,0 +1,6 @@ +GLIBC_2.27 forkpty F +GLIBC_2.27 login F +GLIBC_2.27 login_tty F +GLIBC_2.27 logout F +GLIBC_2.27 logwtmp F +GLIBC_2.27 openpty F diff --git a/sysdeps/unix/sysv/linux/loongarch/makecontext.c b/sysdeps/unix/sysv/linux/loongarch/makecontext.c new file mode 100644 index 00000000..55d509ab --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/makecontext.c @@ -0,0 +1,78 @@ +/* Copyright (C) 2020-2021 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include +#include +#include +#include +#include + +void +__makecontext (ucontext_t *ucp, void (*func) (void), int argc, + long int a0, long int a1, long int a2, long int a3, long int a4, + ...) +{ + extern void __start_context (void) attribute_hidden; + long int i, sp; + + _Static_assert (LARCH_REG_NARGS == 8, "__makecontext assumes 8 argument registers"); + + /* Set up the stack. */ + sp = ((long int) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size) & ALMASK; + + /* Set up the register context. + ra = s0 = 0, terminating the stack for backtracing purposes. + s1 = the function we must call. + s2 = the subsequent context to run. */ + ucp->uc_mcontext.__gregs[LARCH_REG_RA] = 0; + ucp->uc_mcontext.__gregs[LARCH_REG_S0] = 0; + ucp->uc_mcontext.__gregs[LARCH_REG_S1] = (long int) func; + ucp->uc_mcontext.__gregs[LARCH_REG_S2] = (long int) ucp->uc_link; + ucp->uc_mcontext.__gregs[LARCH_REG_SP] = sp; + ucp->uc_mcontext.__pc = (long int) &__start_context; + + /* Put args in a0-a7, then put any remaining args on the stack. */ + ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 0] = a0; + ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 1] = a1; + ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 2] = a2; + ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 3] = a3; + ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 4] = a4; + + if (__glibc_unlikely (argc > 5)) + { + va_list vl; + va_start (vl, a4); + + long reg_args = argc < LARCH_REG_NARGS ? argc : LARCH_REG_NARGS; + for (i = 5; i < reg_args; i++) + ucp->uc_mcontext.__gregs[LARCH_REG_A0 + i] = va_arg (vl, long); + + long int stack_args = argc - reg_args; + if (stack_args > 0) + { + sp = (sp - stack_args * sizeof (long int)) & ALMASK; + ucp->uc_mcontext.__gregs[LARCH_REG_SP] = sp; + for (i = 0; i < stack_args; i++) + ((long int *) sp)[i] = va_arg (vl, long int); + } + + va_end (vl); + } +} + +weak_alias (__makecontext, makecontext) diff --git a/sysdeps/unix/sysv/linux/loongarch/profil-counter.h b/sysdeps/unix/sysv/linux/loongarch/profil-counter.h new file mode 100644 index 00000000..6a3cc201 --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/profil-counter.h @@ -0,0 +1,31 @@ +/* Copyright (C) 2020-2021 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include + +static void +__profil_counter (int signo, const SIGCONTEXT scp) +{ + profil_count ((void *) GET_PC (scp)); + + /* This is a hack to prevent the compiler from implementing the + above function call as a sibcall. The sibcall would overwrite + the signal context. */ + asm volatile (""); +} diff --git a/sysdeps/unix/sysv/linux/loongarch/pt-vfork.S b/sysdeps/unix/sysv/linux/loongarch/pt-vfork.S new file mode 100644 index 00000000..1cc89317 --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/pt-vfork.S @@ -0,0 +1 @@ +/* Not needed. */ diff --git a/sysdeps/unix/sysv/linux/loongarch/register-dump.h b/sysdeps/unix/sysv/linux/loongarch/register-dump.h new file mode 100644 index 00000000..5e45d5c7 --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/register-dump.h @@ -0,0 +1,63 @@ +/* Dump registers. + Copyright (C) 2000-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include +#include +#include <_itoa.h> + +static void +hexvalue (unsigned long int value, char *buf, size_t len) +{ + char *cp = _itoa_word (value, buf + len, 16, 0); + while (cp > buf) + *--cp = '0'; +} + +#define REGDUMP_NREGS 32 +#define REGDUMP_PER_LINE (80 / (__WORDSIZE / 4 + 4)) + +static void +register_dump (int fd, ucontext_t *ctx) +{ + int i; + char regvalue[__WORDSIZE / 4 + 1]; + char str[82 * ((REGDUMP_NREGS + REGDUMP_PER_LINE - 1) / REGDUMP_PER_LINE)]; + + static const char names[REGDUMP_NREGS][4] = { + "pc", "ra", "tp", "sp", "a0", "a1", "a2", "a3", + "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3", + "t4", "t5", "t6", "t7", "t8", "x" , "fp", "s0", + "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8" + }; + + str[0] = 0; + for (i = 0; i < REGDUMP_NREGS; i++) + { + strcat (str, names[i]); + strcat (str, " "); + hexvalue (ctx->uc_mcontext.__gregs[i], regvalue, __WORDSIZE / 4); + strcat (str, regvalue); + + if ((i + 1) % REGDUMP_PER_LINE == 0) + strcat (str, "\n"); + } + + write (fd, str, strlen (str)); +} + +#define REGISTER_DUMP register_dump (fd, ctx) diff --git a/sysdeps/unix/sysv/linux/loongarch/setcontext.S b/sysdeps/unix/sysv/linux/loongarch/setcontext.S new file mode 100644 index 00000000..c96ec43c --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/setcontext.S @@ -0,0 +1,111 @@ +/* Set current context. + Copyright (C) 2009-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ +#include "sys/regdef.h" +#include "ucontext-macros.h" + +/* int __setcontext (const ucontext_t *ucp) + + Restores the machine context in UCP and thereby resumes execution + in that context. + + This implementation is intended to be used for *synchronous* context + switches only. Therefore, it does not have to restore anything + other than the PRESERVED state. */ + + .text +LEAF (__setcontext) + + addi.d sp, sp, -16 + st.d a0, sp, 0 /* Save ucp to stack. */ +/* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, NULL, _NSIG8) */ + li.d a3, _NSIG8 + li.d a2, 0 + addi.d a1, a0, UCONTEXT_SIGMASK + li.d a0, SIG_SETMASK + + li.d a7, SYS_ify (rt_sigprocmask) + syscall 0 + + blt a0, $r0, 99f + + ld.d t0, sp, 0 /* Load ucp to t0. */ + cfi_def_cfa (12, 0) + +#ifndef __loongarch_soft_float + ld.w t1, t0, MCONTEXT_FCSR + + RESTORE_FP_REG (fs0, 24, t0) + RESTORE_FP_REG (fs1, 25, t0) + RESTORE_FP_REG (fs2, 26, t0) + RESTORE_FP_REG (fs3, 27, t0) + RESTORE_FP_REG (fs4, 28, t0) + RESTORE_FP_REG (fs5, 29, t0) + RESTORE_FP_REG (fs6, 30, t0) + RESTORE_FP_REG (fs7, 31, t0) + + movgr2fcsr $r0, t1 +#endif /* __loongarch_soft_float */ + + /* Note the contents of argument registers will be random + unless makecontext() has been called. */ + RESTORE_INT_REG (ra, 1, t0) + RESTORE_INT_REG (sp, 3, t0) + RESTORE_INT_REG (a0, 4, t0) + RESTORE_INT_REG (a1, 5, t0) + RESTORE_INT_REG (a2, 6, t0) + RESTORE_INT_REG (a3, 7, t0) + RESTORE_INT_REG (a4, 8, t0) + RESTORE_INT_REG (a5, 9, t0) + RESTORE_INT_REG (a6, 10, t0) + RESTORE_INT_REG (a7, 11, t0) + RESTORE_INT_REG (x, 21, t0) + RESTORE_INT_REG (fp, 22, t0) + RESTORE_INT_REG (s0, 23, t0) + RESTORE_INT_REG (s1, 24, t0) + RESTORE_INT_REG (s2, 25, t0) + RESTORE_INT_REG (s3, 26, t0) + RESTORE_INT_REG (s4, 27, t0) + RESTORE_INT_REG (s5, 28, t0) + RESTORE_INT_REG (s6, 29, t0) + RESTORE_INT_REG (s7, 30, t0) + RESTORE_INT_REG (s8, 31, t0) + ld.d t1, t0, MCONTEXT_PC + jirl $r0,t1,0 + +99: + addi.d sp, sp, 16 + b __syscall_error + +PSEUDO_END (__setcontext) +weak_alias (__setcontext, setcontext) + +LEAF (__start_context) + + /* Terminate call stack by noting ra == 0. Happily, s0 == 0 here. */ + cfi_register (1, 23) + + /* Call the function passed to makecontext. */ + jirl $r1,s1,0 + + /* Invoke subsequent context if present, else exit(0). */ + ori a0, s2, 0 + beqz s2, 1f + bl __setcontext +1: b exit + +PSEUDO_END (__start_context) diff --git a/sysdeps/unix/sysv/linux/loongarch/shlib-versions b/sysdeps/unix/sysv/linux/loongarch/shlib-versions new file mode 100644 index 00000000..2a67fe71 --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/shlib-versions @@ -0,0 +1,2 @@ +DEFAULT GLIBC_2.27 +libpthread=0 GLIBC_2.0 GLIBC_2.2 diff --git a/sysdeps/unix/sysv/linux/loongarch/sigcontextinfo.h b/sysdeps/unix/sysv/linux/loongarch/sigcontextinfo.h new file mode 100644 index 00000000..2a864795 --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/sigcontextinfo.h @@ -0,0 +1,22 @@ +/* Copyright (C) 2020-2021 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include + +#define SIGCONTEXT siginfo_t *_si, ucontext_t * +#define GET_PC(ctx) ((void *) ctx->uc_mcontext.__pc) diff --git a/sysdeps/unix/sysv/linux/loongarch/swapcontext.S b/sysdeps/unix/sysv/linux/loongarch/swapcontext.S new file mode 100644 index 00000000..d839dd87 --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/swapcontext.S @@ -0,0 +1,120 @@ +/* Save and set current context. + Copyright (C) 2009-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include "ucontext-macros.h" + +/* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */ + +LEAF (__swapcontext) + ori a2, sp, 0 /* Save sp to a2. */ + addi.d sp, sp, -16 + st.d a1, sp, 0 + ori t0, a1, 0 + + SAVE_INT_REG (ra, 1, a0) + SAVE_INT_REG (a2, 3, a0) /* Store sp .*/ + SAVE_INT_REG (zero, 4, a0) /* return 0 by overwriting a0. */ + SAVE_INT_REG (x, 21, a0) + SAVE_INT_REG (fp, 22, a0) + SAVE_INT_REG (s0, 23, a0) + SAVE_INT_REG (s1, 24, a0) + SAVE_INT_REG (s2, 25, a0) + SAVE_INT_REG (s3, 26, a0) + SAVE_INT_REG (s4, 27, a0) + SAVE_INT_REG (s5, 28, a0) + SAVE_INT_REG (s6, 29, a0) + SAVE_INT_REG (s7, 30, a0) + SAVE_INT_REG (s8, 31, a0) + st.d ra, a0, MCONTEXT_PC +#ifndef __loongarch_soft_float + movfcsr2gr a1, $r0 + + SAVE_FP_REG (fs0, 24, a0) + SAVE_FP_REG (fs1, 25, a0) + SAVE_FP_REG (fs2, 26, a0) + SAVE_FP_REG (fs3, 27, a0) + SAVE_FP_REG (fs4, 28, a0) + SAVE_FP_REG (fs5, 29, a0) + SAVE_FP_REG (fs6, 30, a0) + SAVE_FP_REG (fs7, 31, a0) + + st.w a1, a0, MCONTEXT_FCSR +#endif /* __loongarch_soft_float */ + +/* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, &oucp->uc_sigmask, _NSIG8) */ + li.d a3, _NSIG8 + addi.d a2, a0, UCONTEXT_SIGMASK + addi.d a1, t0, UCONTEXT_SIGMASK + li.d a0, SIG_SETMASK + + li.d a7, SYS_ify (rt_sigprocmask) + syscall 0 + + blt a0, zero, 99f + +#ifndef __loongarch_soft_float + ld.d t0, sp, 0 /* Load a1 to t0. */ + ld.w t1, t0, MCONTEXT_FCSR + + RESTORE_FP_REG (fs0, 24, t0) + RESTORE_FP_REG (fs1, 25, t0) + RESTORE_FP_REG (fs2, 26, t0) + RESTORE_FP_REG (fs3, 27, t0) + RESTORE_FP_REG (fs4, 28, t0) + RESTORE_FP_REG (fs5, 29, t0) + RESTORE_FP_REG (fs6, 30, t0) + RESTORE_FP_REG (fs7, 31, t0) + + movgr2fcsr $r0, t1 +#endif /* __loongarch_soft_float */ + + /* Note the contents of argument registers will be random + unless makecontext() has been called. */ + RESTORE_INT_REG (ra, 1, t0) + RESTORE_INT_REG (sp, 3, t0) + RESTORE_INT_REG (a0, 4, t0) + RESTORE_INT_REG (a1, 5, t0) + RESTORE_INT_REG (a2, 6, t0) + RESTORE_INT_REG (a3, 7, t0) + RESTORE_INT_REG (a4, 8, t0) + RESTORE_INT_REG (a5, 9, t0) + RESTORE_INT_REG (a6, 10, t0) + RESTORE_INT_REG (a7, 11, t0) + RESTORE_INT_REG (x, 21, t0) + RESTORE_INT_REG (fp, 22, t0) + RESTORE_INT_REG (s0, 23, t0) + RESTORE_INT_REG (s1, 24, t0) + RESTORE_INT_REG (s2, 25, t0) + RESTORE_INT_REG (s3, 26, t0) + RESTORE_INT_REG (s4, 27, t0) + RESTORE_INT_REG (s5, 28, t0) + RESTORE_INT_REG (s6, 29, t0) + RESTORE_INT_REG (s7, 30, t0) + RESTORE_INT_REG (s8, 31, t0) + ld.d t1, t0, MCONTEXT_PC + + jirl $r0, t1, 0 + + +99: + addi.d sp, sp, 16 + b __syscall_error + +PSEUDO_END (__swapcontext) + +weak_alias (__swapcontext, swapcontext) diff --git a/sysdeps/unix/sysv/linux/loongarch/sys/procfs.h b/sysdeps/unix/sysv/linux/loongarch/sys/procfs.h new file mode 100644 index 00000000..9ae06b40 --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/sys/procfs.h @@ -0,0 +1,122 @@ +/* Copyright (C) 2020-2021 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#ifndef _SYS_PROCFS_H +#define _SYS_PROCFS_H 1 + +/* This is somehow modelled after the file of the same name on SysVr4 + systems. It provides a definition of the core file format for ELF + used on Linux. */ + +#include +#include +#include +#include +#include + +__BEGIN_DECLS + +/* Type for a general-purpose register. */ +typedef uint64_t elf_greg_t; + +/* And the whole bunch of them. We could have used `struct + pt_regs' directly in the typedef, but tradition says that + the register set is an array, which does have some peculiar + semantics, so leave it that way. */ +#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t)) +typedef elf_greg_t elf_gregset_t[ELF_NGREG]; + +#define ELF_NFPREG 34 /* 32 FPRs + 8-byte byte-vec for fcc + 4-byte FCR */ +typedef union { double d; float f; } elf_fpreg_t; +typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; + +typedef union { double d[2]; float f[4]; } __attribute__((__aligned__ (16))) elf_lsxregset_t[32]; +typedef union { double d[4]; float f[8]; } __attribute__((__aligned__ (32))) elf_lasxregset_t[32]; + +struct elf_siginfo + { + int si_signo; /* Signal number. */ + int si_code; /* Extra code. */ + int si_errno; /* Errno. */ + }; + +/* Definitions to generate Intel SVR4-like core files. These mostly + have the same names as the SVR4 types with "elf_" tacked on the + front to prevent clashes with linux definitions, and the typedef + forms have been avoided. This is mostly like the SVR4 structure, + but more Linuxy, with things that Linux does not support and which + gdb doesn't really use excluded. Fields present but not used are + marked with "XXX". */ +struct elf_prstatus + { + struct elf_siginfo pr_info; /* Info associated with signal. */ + short int pr_cursig; /* Current signal. */ + unsigned long int pr_sigpend; /* Set of pending signals. */ + unsigned long int pr_sighold; /* Set of held signals. */ + __pid_t pr_pid; + __pid_t pr_ppid; + __pid_t pr_pgrp; + __pid_t pr_sid; + struct timeval pr_utime; /* User time. */ + struct timeval pr_stime; /* System time. */ + struct timeval pr_cutime; /* Cumulative user time. */ + struct timeval pr_cstime; /* Cumulative system time. */ + elf_gregset_t pr_reg; /* GP registers. */ + int pr_fpvalid; /* True if math copro being used. */ + }; + + +#define ELF_PRARGSZ (80) /* Number of chars for args */ + +struct elf_prpsinfo + { + char pr_state; /* Numeric process state. */ + char pr_sname; /* Char for pr_state. */ + char pr_zomb; /* Zombie. */ + char pr_nice; /* Nice val. */ + unsigned long int pr_flag; /* Flags. */ + unsigned int pr_uid; + unsigned int pr_gid; + int pr_pid, pr_ppid, pr_pgrp, pr_sid; + /* Lots missing */ + char pr_fname[16]; /* Filename of executable. */ + char pr_psargs[ELF_PRARGSZ]; /* Initial part of arg list. */ + }; + +/* The rest of this file provides the types for emulation of the + Solaris interfaces that should be implemented by + users of libthread_db. */ + +/* Addresses. */ +typedef void *psaddr_t; + +/* Register sets. Linux has different names. */ +typedef elf_gregset_t prgregset_t; +typedef elf_fpregset_t prfpregset_t; + +/* We don't have any differences between processes and threads, + therefore habe only ine PID type. */ +typedef __pid_t lwpid_t; + +/* Process status and info. In the end we do provide typedefs for them. */ +typedef struct elf_prstatus prstatus_t; +typedef struct elf_prpsinfo prpsinfo_t; + +__END_DECLS + +#endif /* sys/procfs.h */ diff --git a/sysdeps/unix/sysv/linux/loongarch/sys/ucontext.h b/sysdeps/unix/sysv/linux/loongarch/sys/ucontext.h new file mode 100644 index 00000000..e52a46c9 --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/sys/ucontext.h @@ -0,0 +1,81 @@ +/* Copyright (C) 2020-2021 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +/* Don't rely on this, the interface is currently messed up and may need to + be broken to be fixed. */ +#ifndef _SYS_UCONTEXT_H +#define _SYS_UCONTEXT_H 1 + +#include + +#include +#include + +typedef unsigned long int __loongarch_mc_gp_state[32]; + +#ifdef __USE_MISC +# define LARCH_NGREG 32 + +# define LARCH_REG_RA 1 +# define LARCH_REG_SP 3 +# define LARCH_REG_S0 23 +# define LARCH_REG_S1 24 +# define LARCH_REG_A0 4 +# define LARCH_REG_S2 25 +# define LARCH_REG_NARGS 8 + +typedef unsigned long int greg_t; + +/* Container for all general registers. */ +typedef __loongarch_mc_gp_state gregset_t; + +/* Container for floating-point state. */ +typedef union __loongarch_mc_fp_state fpregset_t; +#endif + + + +union __loongarch_mc_fp_state { + unsigned int __val32[256 / 32]; + unsigned long long __val64[256 / 64]; +}; + +typedef struct mcontext_t { + unsigned long long __pc; + unsigned long long __gregs[32]; + unsigned int __flags; + + unsigned int __fcsr; + unsigned int __vcsr; + unsigned long long __fcc; + union __loongarch_mc_fp_state __fpregs[32] __attribute__((__aligned__ (32))); + + unsigned int __reserved; +} mcontext_t; + +/* Userlevel context. */ +typedef struct ucontext_t + { + unsigned long int __uc_flags; + struct ucontext_t *uc_link; + stack_t uc_stack; + mcontext_t uc_mcontext; + sigset_t uc_sigmask; + } ucontext_t; + +#endif /* sys/ucontext.h */ diff --git a/sysdeps/unix/sysv/linux/loongarch/sys/user.h b/sysdeps/unix/sysv/linux/loongarch/sys/user.h new file mode 100644 index 00000000..f9108350 --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/sys/user.h @@ -0,0 +1,31 @@ +/* Copyright (C) 2001-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _SYS_USER_H +#define _SYS_USER_H 1 + +#include + +struct user_regs_struct +{ + uint64_t gpr[32]; + uint64_t pc; + uint64_t badvaddr; + uint64_t reserved[11]; +}; + +#endif /* _SYS_USER_H */ diff --git a/sysdeps/unix/sysv/linux/loongarch/syscall.c b/sysdeps/unix/sysv/linux/loongarch/syscall.c new file mode 100644 index 00000000..b06a528e --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/syscall.c @@ -0,0 +1,36 @@ +/* Copyright (C) 2020-2021 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include + +long int +syscall (long int syscall_number, long int arg1, long int arg2, long int arg3, + long int arg4, long int arg5, long int arg6, long int arg7) +{ + long int ret; + INTERNAL_SYSCALL_DECL (err); + + ret = INTERNAL_SYSCALL_NCS (syscall_number, err, 7, arg1, arg2, arg3, arg4, + arg5, arg6, arg7); + + if (INTERNAL_SYSCALL_ERROR_P (ret, err)) + return __syscall_error (ret); + + return ret; +} + diff --git a/sysdeps/unix/sysv/linux/loongarch/sysdep.S b/sysdeps/unix/sysv/linux/loongarch/sysdep.S new file mode 100644 index 00000000..a8094283 --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/sysdep.S @@ -0,0 +1,52 @@ +/* syscall error handlers + Copyright (C) 2011-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include + +#if IS_IN (libc) +# define errno __libc_errno +#endif + +ENTRY (__syscall_error) + /* Fall through to __syscall_set_errno. */ +END (__syscall_error) + +/* Non-standard calling convention: argument in a0, return address in t0, + and clobber only t1. */ +ENTRY (__syscall_set_errno) + /* We got here because a0 < 0, but only codes in the range [-4095, -1] + represent errors. Otherwise, just return the result normally. */ + + li.d t1, -4096 + bgeu t1, a0, L (out) + sub.w a0, zero, a0 + +#if RTLD_PRIVATE_ERRNO + la t1, rtld_errno +#elif defined(__PIC__) + la.tls.ie t1, errno + add.d t1, tp, t1 +#else + la.tls.le t1, errno + add.d t1, tp, t1 +#endif + st.w a0, t1, 0 + li.d a0, -1 +L (out): + ret +END (__syscall_set_errno) diff --git a/sysdeps/unix/sysv/linux/loongarch/sysdep.h b/sysdeps/unix/sysv/linux/loongarch/sysdep.h new file mode 100644 index 00000000..f50946d4 --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/sysdep.h @@ -0,0 +1,333 @@ +#ifndef _LINUX_LOONGARCH_SYSDEP_H +#define _LINUX_LOONGARCH_SYSDEP_H 1 + +#include +#include + +#ifdef __ASSEMBLER__ + +# include +# define ret jirl zero, ra, 0 +# define L(label) .L ## label + +/* Performs a system call, handling errors by setting errno. Linux indicates + errors by setting a0 to a value between -1 and -4095. */ +# undef PSEUDO +# define PSEUDO(name, syscall_name, args) \ + ENTRY (name); \ + li.d a7, SYS_ify (syscall_name); \ + syscall 0; \ + li.d a7, -4096; \ + bltu a7, a0, .Lsyscall_error ## name; + +# undef PSEUDO_END +# define PSEUDO_END(sym) \ + SYSCALL_ERROR_HANDLER (sym); \ + ret; \ + END (sym); + +# if !IS_IN (libc) +# if RTLD_PRIVATE_ERRNO + +# define SYSCALL_ERROR_HANDLER(name) \ +.Lsyscall_error ## name: \ + la t0, rtld_errno; \ + sub.w a0, zero, a0; \ + st.w a0, t0, 0; \ + li.d a0, -1; + +# else + +# define SYSCALL_ERROR_HANDLER(name) \ +.Lsyscall_error ## name: \ + la.tls.ie t0, errno; \ + add.d t0, tp, t0; \ + sub.w a0, zero, a0; \ + st.w a0, t0, 0; \ + li.d a0, -1; + +# endif +# else + +# define SYSCALL_ERROR_HANDLER(name) \ +.Lsyscall_error ## name: \ + b __syscall_error; + +# endif + +/* Performs a system call, not setting errno. */ +# undef PSEUDO_NEORRNO +# define PSEUDO_NOERRNO(name, syscall_name, args) \ + ENTRY (name); \ + li.d a7, SYS_ify (syscall_name); \ + syscall 0; + +# undef PSEUDO_END_NOERRNO +# define PSEUDO_END_NOERRNO(name) \ + END (name); + +# undef ret_NOERRNO +# define ret_NOERRNO ret + +/* Perfroms a system call, returning the error code. */ +# undef PSEUDO_ERRVAL +# define PSEUDO_ERRVAL(name, syscall_name, args) \ + PSEUDO_NOERRNO (name, syscall_name, args); \ + slli.d a0, a0, 32; \ + srai.d a0, a0, 32; /* sign_ext */ \ + sub.d a0, zero, a0; + +# undef PSEUDO_END_ERRVAL +# define PSEUDO_END_ERRVAL(name) \ + END (name); + +# undef ret_ERRVAL +# define ret_ERRVAL ret + +#endif /* __ASSEMBLER__ */ + +/* In order to get __set_errno() definition in INLINE_SYSCALL. */ +#ifndef __ASSEMBLER__ +# include +#endif + +#include + +#undef SYS_ify +#define SYS_ify(syscall_name) __NR_##syscall_name + +#ifndef __ASSEMBLER__ + +/* List of system calls which are supported as vsyscalls. */ +# define HAVE_CLOCK_GETRES_VSYSCALL 1 +# define HAVE_CLOCK_GETTIME_VSYSCALL 1 +# define HAVE_GETTIMEOFDAY_VSYSCALL 1 +# define HAVE_GETCPU_VSYSCALL 1 + +/* Define a macro which expands into the inline wrapper code for a system + call. */ +# undef INLINE_SYSCALL +# define INLINE_SYSCALL(name, nr, args...) \ + ({ INTERNAL_SYSCALL_DECL (err); \ + long int __sys_result = INTERNAL_SYSCALL (name, err, nr, args); \ + if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (__sys_result, ))) \ + { \ + __set_errno (INTERNAL_SYSCALL_ERRNO (__sys_result, )); \ + __sys_result = (unsigned long) -1; \ + } \ + __sys_result; }) + + +# define INTERNAL_SYSCALL_DECL(err) do { } while (0) + +# define INTERNAL_SYSCALL_ERROR_P(val, err) \ + ((unsigned long int) (val) > -4096UL) + +# define INTERNAL_SYSCALL_ERRNO(val, err) (-(val)) + +# define INTERNAL_SYSCALL(name, err, nr, args...) \ + internal_syscall##nr (SYS_ify (name), err, args) + +# define INTERNAL_SYSCALL_NCS(number, err, nr, args...) \ + internal_syscall##nr (number, err, args) + +# define internal_syscall0(number, err, dummy...) \ +({ \ + long int _sys_result; \ + \ + { \ + register long int __a7 asm ("$a7") = number; \ + register long int __a0 asm ("$a0"); \ + __asm__ volatile ( \ + "syscall 0\n\t" \ + : "=r" (__a0) \ + : "r" (__a7) \ + : __SYSCALL_CLOBBERS); \ + _sys_result = __a0; \ + } \ + _sys_result; \ +}) + +# define internal_syscall1(number, err, arg0) \ +({ \ + long int _sys_result; \ + \ + { \ + long int _arg0 = (long int) (arg0); \ + register long int __a7 asm ("$a7") = number; \ + register long int __a0 asm ("$a0") = _arg0; \ + __asm__ volatile ( \ + "syscall 0\n\t" \ + : "+r" (__a0) \ + : "r" (__a7) \ + : __SYSCALL_CLOBBERS); \ + _sys_result = __a0; \ + } \ + _sys_result; \ +}) + +# define internal_syscall2(number, err, arg0, arg1) \ +({ \ + long int _sys_result; \ + \ + { \ + long int _arg0 = (long int) (arg0); \ + long int _arg1 = (long int) (arg1); \ + register long int __a7 asm ("$a7") = number; \ + register long int __a0 asm ("$a0") = _arg0; \ + register long int __a1 asm ("$a1") = _arg1; \ + __asm__ volatile ( \ + "syscall 0\n\t" \ + : "+r" (__a0) \ + : "r" (__a7), "r" (__a1) \ + : __SYSCALL_CLOBBERS); \ + _sys_result = __a0; \ + } \ + _sys_result; \ +}) + +# define internal_syscall3(number, err, arg0, arg1, arg2) \ +({ \ + long int _sys_result; \ + \ + { \ + long int _arg0 = (long int) (arg0); \ + long int _arg1 = (long int) (arg1); \ + long int _arg2 = (long int) (arg2); \ + register long int __a7 asm ("$a7") = number; \ + register long int __a0 asm ("$a0") = _arg0; \ + register long int __a1 asm ("$a1") = _arg1; \ + register long int __a2 asm ("$a2") = _arg2; \ + __asm__ volatile ( \ + "syscall 0\n\t" \ + : "+r" (__a0) \ + : "r" (__a7), "r" (__a1), "r" (__a2) \ + : __SYSCALL_CLOBBERS); \ + _sys_result = __a0; \ + } \ + _sys_result; \ +}) + +# define internal_syscall4(number, err, arg0, arg1, arg2, arg3) \ +({ \ + long int _sys_result; \ + \ + { \ + long int _arg0 = (long int) (arg0); \ + long int _arg1 = (long int) (arg1); \ + long int _arg2 = (long int) (arg2); \ + long int _arg3 = (long int) (arg3); \ + register long int __a7 asm ("$a7") = number; \ + register long int __a0 asm ("$a0") = _arg0; \ + register long int __a1 asm ("$a1") = _arg1; \ + register long int __a2 asm ("$a2") = _arg2; \ + register long int __a3 asm ("$a3") = _arg3; \ + __asm__ volatile ( \ + "syscall 0\n\t" \ + : "+r" (__a0) \ + : "r" (__a7), "r" (__a1), "r" (__a2), "r" (__a3) \ + : __SYSCALL_CLOBBERS); \ + _sys_result = __a0; \ + } \ + _sys_result; \ +}) + +# define internal_syscall5(number, err, arg0, arg1, arg2, arg3, arg4) \ +({ \ + long int _sys_result; \ + \ + { \ + long int _arg0 = (long int) (arg0); \ + long int _arg1 = (long int) (arg1); \ + long int _arg2 = (long int) (arg2); \ + long int _arg3 = (long int) (arg3); \ + long int _arg4 = (long int) (arg4); \ + register long int __a7 asm ("$a7") = number; \ + register long int __a0 asm ("$a0") = _arg0; \ + register long int __a1 asm ("$a1") = _arg1; \ + register long int __a2 asm ("$a2") = _arg2; \ + register long int __a3 asm ("$a3") = _arg3; \ + register long int __a4 asm ("$a4") = _arg4; \ + __asm__ volatile ( \ + "syscall 0\n\t" \ + : "+r" (__a0) \ + : "r" (__a7), "r"(__a1), "r"(__a2), "r"(__a3), "r" (__a4) \ + : __SYSCALL_CLOBBERS); \ + _sys_result = __a0; \ + } \ + _sys_result; \ +}) + +# define internal_syscall6(number, err, arg0, arg1, arg2, arg3, arg4, arg5) \ +({ \ + long int _sys_result; \ + \ + { \ + long int _arg0 = (long int) (arg0); \ + long int _arg1 = (long int) (arg1); \ + long int _arg2 = (long int) (arg2); \ + long int _arg3 = (long int) (arg3); \ + long int _arg4 = (long int) (arg4); \ + long int _arg5 = (long int) (arg5); \ + register long int __a7 asm ("$a7") = number; \ + register long int __a0 asm ("$a0") = _arg0; \ + register long int __a1 asm ("$a1") = _arg1; \ + register long int __a2 asm ("$a2") = _arg2; \ + register long int __a3 asm ("$a3") = _arg3; \ + register long int __a4 asm ("$a4") = _arg4; \ + register long int __a5 asm ("$a5") = _arg5; \ + __asm__ volatile ( \ + "syscall 0\n\t" \ + : "+r" (__a0) \ + : "r" (__a7), "r" (__a1), "r" (__a2), "r" (__a3), \ + "r" (__a4), "r" (__a5) \ + : __SYSCALL_CLOBBERS); \ + _sys_result = __a0; \ + } \ + _sys_result; \ +}) + +# define internal_syscall7(number, err, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ +({ \ + long int _sys_result; \ + \ + { \ + long int _arg0 = (long int) (arg0); \ + long int _arg1 = (long int) (arg1); \ + long int _arg2 = (long int) (arg2); \ + long int _arg3 = (long int) (arg3); \ + long int _arg4 = (long int) (arg4); \ + long int _arg5 = (long int) (arg5); \ + long int _arg6 = (long int) (arg6); \ + register long int __a7 asm ("$a7") = number; \ + register long int __a0 asm ("$a0") = _arg0; \ + register long int __a1 asm ("$a1") = _arg1; \ + register long int __a2 asm ("$a2") = _arg2; \ + register long int __a3 asm ("$a3") = _arg3; \ + register long int __a4 asm ("$a4") = _arg4; \ + register long int __a5 asm ("$a5") = _arg5; \ + register long int __a6 asm ("$a6") = _arg6; \ + __asm__ volatile ( \ + "syscall 0\n\t" \ + : "+r" (__a0) \ + : "r" (__a7), "r" (__a1), "r" (__a2), "r" (__a3), \ + "r" (__a4), "r" (__a5), "r" (__a6) \ + : __SYSCALL_CLOBBERS); \ + _sys_result = __a0; \ + } \ + _sys_result; \ +}) + +# define __SYSCALL_CLOBBERS \ + "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7", "$t8",\ + "memory" + +extern long int __syscall_error (long int neg_errno); + +#endif /* ! __ASSEMBLER__ */ + +/* Pointer mangling is not supported. */ +#define PTR_MANGLE(var) (void) (var) +#define PTR_DEMANGLE(var) (void) (var) + +#endif /* linux/loongarch/sysdep.h */ diff --git a/sysdeps/unix/sysv/linux/loongarch/ucontext-macros.h b/sysdeps/unix/sysv/linux/loongarch/ucontext-macros.h new file mode 100644 index 00000000..abd22247 --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/ucontext-macros.h @@ -0,0 +1,44 @@ +/* Macros for ucontext routines. + Copyright (C) 2017-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#ifndef _LINUX_LOONGARCH_UCONTEXT_MACROS_H +#define _LINUX_LOONGARCH_UCONTEXT_MACROS_H + +#include +#include + +#include "ucontext_i.h" + +#define SAVE_FP_REG(name, num, base) \ + FREG_S name, base, ((num) * SZFREG + MCONTEXT_FPREGS) + +#define RESTORE_FP_REG(name, num, base) \ + FREG_L name, base, ((num) * SZFREG + MCONTEXT_FPREGS) + +#define SAVE_INT_REG(name, num, base) \ + REG_S name, base, ((num) * SZREG + MCONTEXT_GREGS) + +#define RESTORE_INT_REG(name, num, base) \ + REG_L name, base, ((num) * SZREG + MCONTEXT_GREGS) + +#define SAVE_REG(name, offset, base) \ + REG_S name, base, (offset) + +#define RESTORE_REG(name, offset, base) \ + REG_L name, base, (offset) +#endif /* _LINUX_LOONGARCH_UCONTEXT_MACROS_H */ diff --git a/sysdeps/unix/sysv/linux/loongarch/ucontext_i.sym b/sysdeps/unix/sysv/linux/loongarch/ucontext_i.sym new file mode 100644 index 00000000..d7f612fe --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/ucontext_i.sym @@ -0,0 +1,33 @@ +#include +#include +#include +#include + +-- Constants used by the rt_sigprocmask call. + +SIG_BLOCK +SIG_SETMASK + +_NSIG8 (_NSIG / 8) + +-- Offsets of the fields in the ucontext_t structure. +#define ucontext(member) offsetof (ucontext_t, member) +#define stack(member) ucontext (uc_stack.member) +#define mcontext(member) ucontext (uc_mcontext.member) + +UCONTEXT_FLAGS ucontext (__uc_flags) +UCONTEXT_LINK ucontext (uc_link) +UCONTEXT_STACK ucontext (uc_stack) +UCONTEXT_MCONTEXT ucontext (uc_mcontext) +UCONTEXT_SIGMASK ucontext (uc_sigmask) + +STACK_SP stack (ss_sp) +STACK_SIZE stack (ss_size) +STACK_FLAGS stack (ss_flags) + +MCONTEXT_PC mcontext (__pc) +MCONTEXT_FCSR mcontext (__fcsr) +MCONTEXT_GREGS mcontext (__gregs) +MCONTEXT_FPREGS mcontext (__fpregs) + +UCONTEXT_SIZE sizeof (ucontext_t) diff --git a/sysdeps/unix/sysv/linux/loongarch/vfork.S b/sysdeps/unix/sysv/linux/loongarch/vfork.S new file mode 100644 index 00000000..83cf141f --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/vfork.S @@ -0,0 +1,49 @@ +/* Copyright (C) 1999-2018 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#define _ERRNO_H 1 +#include + +/* Clone the calling process, but without copying the whole address space. + The calling process is suspended until the new process exits or is + replaced by a call to `execve'. Return -1 for errors, 0 to the new process, + and the process ID of the new process to the old process. */ + +ENTRY (__vfork) + + + li.d a0, 0x4111 /* CLONE_VM | CLONE_VFORK | SIGCHLD */ + add.d a1, zero, sp + + /* Do the system call. */ + li.d a7, __NR_clone + syscall 0 + + blt a0, zero ,L (error) + + ret + +L (error): + b __syscall_error + END (__vfork) + +libc_hidden_def (__vfork) + +weak_alias (__vfork, vfork) +strong_alias (__vfork, __libc_vfork) -- 2.39.3