From 32795978d6bb96689e6daffc6bddc2cacdeede23 Mon Sep 17 00:00:00 2001 From: Zhao Hang Date: Sun, 8 Oct 2023 10:48:45 +0800 Subject: [PATCH 1/4] update to glibc-2.28-225.6 Signed-off-by: Zhao Hang --- ....c-to-suit-kernel-struct-sigcontext-.patch | 34 - dist | 2 +- ...check-alignment-of-PT_LOAD-segment-2.patch | 147 - ...perly-check-stack-alignment-BZ-27901.patch | 325 - glibc-RHEL-2422.patch | 347 + glibc-RHEL-2434.patch | 987 + glibc-RHEL-3035.patch | 157 + ...cific-ALIGN-for-variable-alignment-4.patch | 171 - glibc-Sync-to-lnd-35-for-LoongArch.patch | 26504 ---------------- ...-of-__munmap-to-page-size-BZ-28676-3.patch | 36 - glibc-elf-Fix-tst-align3.patch | 40 - ...ly-align-PT_LOAD-segments-BZ-28676-1.patch | 137 - glibc-gb18030-2022-bug30243.patch | 797 - glibc-rh2234713.patch | 187 + glibc.spec | 51 +- 15 files changed, 1700 insertions(+), 28222 deletions(-) delete mode 100644 Fix-tst-cancel21.c-to-suit-kernel-struct-sigcontext-.patch delete mode 100644 glibc-Add-a-testcase-to-check-alignment-of-PT_LOAD-segment-2.patch delete mode 100644 glibc-Properly-check-stack-alignment-BZ-27901.patch create mode 100644 glibc-RHEL-2422.patch create mode 100644 glibc-RHEL-2434.patch create mode 100644 glibc-RHEL-3035.patch delete mode 100644 glibc-Support-target-specific-ALIGN-for-variable-alignment-4.patch delete mode 100644 glibc-Sync-to-lnd-35-for-LoongArch.patch delete mode 100644 glibc-elf-Align-argument-of-__munmap-to-page-size-BZ-28676-3.patch delete mode 100644 glibc-elf-Fix-tst-align3.patch delete mode 100644 glibc-elf-Properly-align-PT_LOAD-segments-BZ-28676-1.patch delete mode 100644 glibc-gb18030-2022-bug30243.patch create mode 100644 glibc-rh2234713.patch diff --git a/Fix-tst-cancel21.c-to-suit-kernel-struct-sigcontext-.patch b/Fix-tst-cancel21.c-to-suit-kernel-struct-sigcontext-.patch deleted file mode 100644 index 62b5dab..0000000 --- a/Fix-tst-cancel21.c-to-suit-kernel-struct-sigcontext-.patch +++ /dev/null @@ -1,34 +0,0 @@ -From c5de7c407853b807e8d0c764e6325bb1311f39cd Mon Sep 17 00:00:00 2001 -From: Xing Li -Date: Tue, 4 Jul 2023 15:10:03 +0800 -Subject: [PATCH 2/2] Fix tst-cancel21.c to suit kernel struct sigcontext - change. * nptl/tst-cancel21.c - ---- - nptl/tst-cancel21.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/nptl/tst-cancel21.c b/nptl/tst-cancel21.c -index b10fdbc1..a3653f21 100644 ---- a/nptl/tst-cancel21.c -+++ b/nptl/tst-cancel21.c -@@ -217,14 +217,14 @@ static int - do_test (void) - { - stack_t ss; -- ss.ss_sp = malloc (2 * SIGSTKSZ); -+ ss.ss_sp = malloc (4 * SIGSTKSZ); - if (ss.ss_sp == NULL) - { - puts ("failed to allocate alternate stack"); - return 1; - } - ss.ss_flags = 0; -- ss.ss_size = 2 * SIGSTKSZ; -+ ss.ss_size = 4 * SIGSTKSZ; - if (sigaltstack (&ss, NULL) < 0) - { - printf ("sigaltstack failed %m\n"); --- -2.27.0 - diff --git a/dist b/dist index 9c0e36e..5aa45c5 100644 --- a/dist +++ b/dist @@ -1 +1 @@ -an8 +an8_8 diff --git a/glibc-Add-a-testcase-to-check-alignment-of-PT_LOAD-segment-2.patch b/glibc-Add-a-testcase-to-check-alignment-of-PT_LOAD-segment-2.patch deleted file mode 100644 index 73f1a06..0000000 --- a/glibc-Add-a-testcase-to-check-alignment-of-PT_LOAD-segment-2.patch +++ /dev/null @@ -1,147 +0,0 @@ -From 58f93dff514cc0bdf3c72eff590dcf5fe5bf9e00 Mon Sep 17 00:00:00 2001 -From: "H.J. Lu" -Date: Wed, 19 Jul 2023 23:09:09 +0800 -Subject: [PATCH 3/6] Add a testcase to check alignment of PT_LOAD segment [BZ - #28676] - -Backport from master commit: fc2334a - -Signed-off-by: Rongwei Wang ---- - elf/Makefile | 13 ++++++++++++- - elf/tst-align3.c | 38 ++++++++++++++++++++++++++++++++++++++ - elf/tst-alignmod3.c | 32 ++++++++++++++++++++++++++++++++ - 3 files changed, 82 insertions(+), 1 deletion(-) - create mode 100644 elf/tst-align3.c - create mode 100644 elf/tst-alignmod3.c - -diff --git a/elf/Makefile b/elf/Makefile -index 634c3113..442817ca 100644 ---- a/elf/Makefile -+++ b/elf/Makefile -@@ -331,6 +331,7 @@ tests += \ - tst-addr1 \ - tst-align \ - tst-align2 \ -+ tst-align3 \ - tst-audit-tlsdesc \ - tst-audit-tlsdesc-dlopen \ - tst-audit1 \ -@@ -466,7 +467,9 @@ endif - test-srcs = \ - tst-pathopt - # tests-srcs -- -+ifeq (yes,$(have-fpie)) -+tests-pie += tst-align3 -+endif - selinux-enabled := $(shell cat /selinux/enforce 2> /dev/null) - - ifneq ($(selinux-enabled),1) -@@ -647,6 +650,7 @@ modules-names = \ - tst-absolute-zero-lib \ - tst-alignmod \ - tst-alignmod2 \ -+ tst-alignmod3 \ - tst-array2dep \ - tst-array5dep \ - tst-audit-tlsdesc-mod1 \ -@@ -1669,6 +1673,13 @@ CFLAGS-tst-alignmod2.c += $(stack-align-test-flags) - $(objpfx)tst-align: $(libdl) - $(objpfx)tst-align.out: $(objpfx)tst-alignmod.so - $(objpfx)tst-align2: $(objpfx)tst-alignmod2.so -+$(objpfx)tst-align3: $(objpfx)tst-alignmod3.so -+ifeq (yes,$(have-fpie)) -+CFLAGS-tst-align3.c += $(PIE-ccflag) -+endif -+LDFLAGS-tst-align3 += -Wl,-z,max-page-size=0x200000 -+LDFLAGS-tst-alignmod3.so += -Wl,-z,max-page-size=0x200000 -+$(objpfx)tst-alignmod3.so: $(libsupport) - - $(objpfx)unload3: $(libdl) - $(objpfx)unload3.out: $(objpfx)unload3mod1.so $(objpfx)unload3mod2.so \ -diff --git a/elf/tst-align3.c b/elf/tst-align3.c -new file mode 100644 -index 00000000..ac86d623 ---- /dev/null -+++ b/elf/tst-align3.c -@@ -0,0 +1,38 @@ -+/* Check alignment of PT_LOAD segment in a shared library. -+ Copyright (C) 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 -+ -+/* This should cover all possible page sizes we currently support. */ -+#define ALIGN 0x200000 -+ -+int bar __attribute__ ((aligned (ALIGN))) = 1; -+ -+extern int do_load_test (void); -+ -+static int -+do_test (void) -+{ -+ printf ("bar: %p\n", &bar); -+ TEST_VERIFY (is_aligned (&bar, ALIGN) == 0); -+ -+ return do_load_test (); -+} -+ -+#include -diff --git a/elf/tst-alignmod3.c b/elf/tst-alignmod3.c -new file mode 100644 -index 00000000..0d33f237 ---- /dev/null -+++ b/elf/tst-alignmod3.c -@@ -0,0 +1,32 @@ -+/* Check alignment of PT_LOAD segment in a shared library. -+ Copyright (C) 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 -+ -+/* This should cover all possible page sizes we currently support. */ -+#define ALIGN 0x200000 -+ -+int foo __attribute__ ((aligned (ALIGN))) = 1; -+ -+void -+do_load_test (void) -+{ -+ printf ("foo: %p\n", &foo); -+ TEST_VERIFY (is_aligned (&foo, ALIGN) == 0); -+} --- -2.27.0 - diff --git a/glibc-Properly-check-stack-alignment-BZ-27901.patch b/glibc-Properly-check-stack-alignment-BZ-27901.patch deleted file mode 100644 index 20dff99..0000000 --- a/glibc-Properly-check-stack-alignment-BZ-27901.patch +++ /dev/null @@ -1,325 +0,0 @@ -From 6152628751bf13f74c9336263a9c22f29ccd8ffb Mon Sep 17 00:00:00 2001 -From: "H.J. Lu" -Date: Wed, 19 Jul 2023 23:01:53 +0800 -Subject: [PATCH 1/6] Properly check stack alignment [BZ #27901] - -1. Replace - -if ((((uintptr_t) &_d) & (__alignof (double) - 1)) != 0) - -which may be optimized out by compiler, with - -int -__attribute__ ((weak, noclone, noinline)) -is_aligned (void *p, int align) -{ - return (((uintptr_t) p) & (align - 1)) != 0; -} - -2. Add TEST_STACK_ALIGN_INIT to TEST_STACK_ALIGN. -3. Add a common TEST_STACK_ALIGN_INIT to check 16-byte stack alignment -for both i386 and x86-64. -4. Update powerpc to use TEST_STACK_ALIGN_INIT. - -Reviewed-by: Carlos O'Donell -Signed-off-by: Rongwei Wang ---- - sysdeps/generic/tst-stack-align.h | 40 ++++++++++++++++--------- - sysdeps/i386/i686/tst-stack-align.h | 44 --------------------------- - sysdeps/i386/tst-stack-align.h | 41 ------------------------- - sysdeps/powerpc/tst-stack-align.h | 27 +++++------------ - sysdeps/x86/tst-stack-align.h | 28 ++++++++++++++++++ - sysdeps/x86_64/tst-stack-align.h | 46 ----------------------------- - 6 files changed, 61 insertions(+), 165 deletions(-) - delete mode 100644 sysdeps/i386/i686/tst-stack-align.h - delete mode 100644 sysdeps/i386/tst-stack-align.h - create mode 100644 sysdeps/x86/tst-stack-align.h - delete mode 100644 sysdeps/x86_64/tst-stack-align.h - -diff --git a/sysdeps/generic/tst-stack-align.h b/sysdeps/generic/tst-stack-align.h -index e5cb3310..e6050901 100644 ---- a/sysdeps/generic/tst-stack-align.h -+++ b/sysdeps/generic/tst-stack-align.h -@@ -1,4 +1,5 @@ --/* Copyright (C) 2003-2018 Free Software Foundation, Inc. -+/* Check stack alignment. Generic version. -+ Copyright (C) 2003-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 -@@ -18,17 +19,28 @@ - #include - #include - -+int -+__attribute__ ((weak, noclone, noinline)) -+is_aligned (void *p, int align) -+{ -+ return (((uintptr_t) p) & (align - 1)) != 0; -+} -+ -+#ifndef TEST_STACK_ALIGN_INIT -+# define TEST_STACK_ALIGN_INIT() 0 -+#endif -+ - #define TEST_STACK_ALIGN() \ -- ({ \ -- double _d = 12.0; \ -- long double _ld = 15.0; \ -- int _ret = 0; \ -- printf ("double: %g %p %zu\n", _d, &_d, __alignof (double)); \ -- if ((((uintptr_t) &_d) & (__alignof (double) - 1)) != 0) \ -- _ret = 1; \ -- \ -- printf ("ldouble: %Lg %p %zu\n", _ld, &_ld, __alignof (long double)); \ -- if ((((uintptr_t) &_ld) & (__alignof (long double) - 1)) != 0) \ -- _ret = 1; \ -- _ret; \ -- }) -+ ({ \ -+ double _d = 12.0; \ -+ long double _ld = 15.0; \ -+ int _ret = TEST_STACK_ALIGN_INIT (); \ -+ \ -+ printf ("double: %g %p %zu\n", _d, &_d, __alignof (double)); \ -+ _ret += is_aligned (&_d, __alignof (double)); \ -+ \ -+ printf ("ldouble: %Lg %p %zu\n", _ld, &_ld, \ -+ __alignof (long double)); \ -+ _ret += is_aligned (&_ld, __alignof (long double)); \ -+ _ret; \ -+ }) -diff --git a/sysdeps/i386/i686/tst-stack-align.h b/sysdeps/i386/i686/tst-stack-align.h -deleted file mode 100644 -index 975f26ef..00000000 ---- a/sysdeps/i386/i686/tst-stack-align.h -+++ /dev/null -@@ -1,44 +0,0 @@ --/* Copyright (C) 2003-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 --#ifndef __SSE__ --#include_next --#else --#include -- --#define TEST_STACK_ALIGN() \ -- ({ \ -- __m128 _m; \ -- double _d = 12.0; \ -- long double _ld = 15.0; \ -- int _ret = 0; \ -- printf ("__m128: %p %zu\n", &_m, __alignof (__m128)); \ -- if ((((uintptr_t) &_m) & (__alignof (__m128) - 1)) != 0) \ -- _ret = 1; \ -- \ -- printf ("double: %g %p %zu\n", _d, &_d, __alignof (double)); \ -- if ((((uintptr_t) &_d) & (__alignof (double) - 1)) != 0) \ -- _ret = 1; \ -- \ -- printf ("ldouble: %Lg %p %zu\n", _ld, &_ld, __alignof (long double)); \ -- if ((((uintptr_t) &_ld) & (__alignof (long double) - 1)) != 0) \ -- _ret = 1; \ -- _ret; \ -- }) --#endif -diff --git a/sysdeps/i386/tst-stack-align.h b/sysdeps/i386/tst-stack-align.h -deleted file mode 100644 -index 394ff773..00000000 ---- a/sysdeps/i386/tst-stack-align.h -+++ /dev/null -@@ -1,41 +0,0 @@ --/* Copyright (C) 2004-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 -- --typedef struct { int i[4]; } int_al16 __attribute__((aligned (16))); -- --#define TEST_STACK_ALIGN() \ -- ({ \ -- int_al16 _m; \ -- double _d = 12.0; \ -- long double _ld = 15.0; \ -- int _ret = 0; \ -- printf ("int_al16: %p %zu\n", &_m, __alignof (int_al16)); \ -- if ((((uintptr_t) &_m) & (__alignof (int_al16) - 1)) != 0) \ -- _ret = 1; \ -- \ -- printf ("double: %g %p %zu\n", _d, &_d, __alignof (double)); \ -- if ((((uintptr_t) &_d) & (__alignof (double) - 1)) != 0) \ -- _ret = 1; \ -- \ -- printf ("ldouble: %Lg %p %zu\n", _ld, &_ld, __alignof (long double)); \ -- if ((((uintptr_t) &_ld) & (__alignof (long double) - 1)) != 0) \ -- _ret = 1; \ -- _ret; \ -- }) -diff --git a/sysdeps/powerpc/tst-stack-align.h b/sysdeps/powerpc/tst-stack-align.h -index 7fd7013b..d7400b28 100644 ---- a/sysdeps/powerpc/tst-stack-align.h -+++ b/sysdeps/powerpc/tst-stack-align.h -@@ -1,4 +1,5 @@ --/* Copyright (C) 2005-2018 Free Software Foundation, Inc. -+/* Check stack alignment. PowerPC version. -+ Copyright (C) 2005-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 -@@ -15,10 +16,7 @@ - License along with the GNU C Library; if not, see - . */ - --#include --#include -- --#define TEST_STACK_ALIGN() \ -+#define TEST_STACK_ALIGN_INIT() \ - ({ \ - /* Altivec __vector int etc. needs 16byte aligned stack. \ - Instead of using altivec.h here, use aligned attribute instead. */ \ -@@ -27,20 +25,9 @@ - int _i __attribute__((aligned (16))); \ - int _j[3]; \ - } _s = { ._i = 18, ._j[0] = 19, ._j[1] = 20, ._j[2] = 21 }; \ -- double _d = 12.0; \ -- long double _ld = 15.0; \ -- int _ret = 0; \ - printf ("__vector int: { %d, %d, %d, %d } %p %zu\n", _s._i, _s._j[0], \ - _s._j[1], _s._j[2], &_s, __alignof (_s)); \ -- if ((((uintptr_t) &_s) & (__alignof (_s) - 1)) != 0) \ -- _ret = 1; \ -- \ -- printf ("double: %g %p %zu\n", _d, &_d, __alignof (double)); \ -- if ((((uintptr_t) &_d) & (__alignof (double) - 1)) != 0) \ -- _ret = 1; \ -- \ -- printf ("ldouble: %Lg %p %zu\n", _ld, &_ld, __alignof (long double)); \ -- if ((((uintptr_t) &_ld) & (__alignof (long double) - 1)) != 0) \ -- _ret = 1; \ -- _ret; \ -- }) -+ is_aligned (&_s, __alignof (_s)); \ -+ }) -+ -+#include_next -diff --git a/sysdeps/x86/tst-stack-align.h b/sysdeps/x86/tst-stack-align.h -new file mode 100644 -index 00000000..02ecc72d ---- /dev/null -+++ b/sysdeps/x86/tst-stack-align.h -@@ -0,0 +1,28 @@ -+/* Check stack alignment. X86 version. -+ Copyright (C) 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 -+ . */ -+ -+typedef struct { int i[16]; } int_al16 __attribute__((aligned (16))); -+ -+#define TEST_STACK_ALIGN_INIT() \ -+ ({ \ -+ int_al16 _m; \ -+ printf ("int_al16: %p %zu\n", &_m, __alignof (int_al16)); \ -+ is_aligned (&_m, __alignof (int_al16)); \ -+ }) -+ -+#include_next -diff --git a/sysdeps/x86_64/tst-stack-align.h b/sysdeps/x86_64/tst-stack-align.h -deleted file mode 100644 -index b2ef77f6..00000000 ---- a/sysdeps/x86_64/tst-stack-align.h -+++ /dev/null -@@ -1,46 +0,0 @@ --/* Copyright (C) 2003-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 TEST_STACK_ALIGN() \ -- ({ \ -- /* AMD64 ABI mandates 16byte aligned stack. \ -- Unfortunately, current GCC doesn't support __int128 or __float128 \ -- types, so use aligned attribute instead. */ \ -- struct _S \ -- { \ -- int _i __attribute__((aligned (16))); \ -- int _pad[3]; \ -- } _s = { ._i = 18 }; \ -- double _d = 12.0; \ -- long double _ld = 15.0; \ -- int _ret = 0; \ -- printf ("__int128: %d %p %zu\n", _s._i, &_s, __alignof (_s)); \ -- if ((((uintptr_t) &_s) & (__alignof (_s) - 1)) != 0) \ -- _ret = 1; \ -- \ -- printf ("double: %g %p %zu\n", _d, &_d, __alignof (double)); \ -- if ((((uintptr_t) &_d) & (__alignof (double) - 1)) != 0) \ -- _ret = 1; \ -- \ -- printf ("ldouble: %Lg %p %zu\n", _ld, &_ld, __alignof (long double)); \ -- if ((((uintptr_t) &_ld) & (__alignof (long double) - 1)) != 0) \ -- _ret = 1; \ -- _ret; \ -- }) --- -2.27.0 - diff --git a/glibc-RHEL-2422.patch b/glibc-RHEL-2422.patch new file mode 100644 index 0000000..476ea12 --- /dev/null +++ b/glibc-RHEL-2422.patch @@ -0,0 +1,347 @@ +Avoid UAF in getcanonname (CVE-2023-4806) + +When an NSS plugin only implements the _gethostbyname2_r and +_getcanonname_r callbacks, getaddrinfo could use memory that was freed +during tmpbuf resizing, through h_name in a previous query response. + +The backing store for res->at->name when doing a query with +gethostbyname3_r or gethostbyname2_r is tmpbuf, which is reallocated in +gethosts during the query. For AF_INET6 lookup with AI_ALL | +AI_V4MAPPED, gethosts gets called twice, once for a v6 lookup and second +for a v4 lookup. In this case, if the first call reallocates tmpbuf +enough number of times, resulting in a malloc, th->h_name (that +res->at->name refers to) ends up on a heap allocated storage in tmpbuf. +Now if the second call to gethosts also causes the plugin callback to +return NSS_STATUS_TRYAGAIN, tmpbuf will get freed, resulting in a UAF +reference in res->at->name. This then gets dereferenced in the +getcanonname_r plugin call, resulting in the use after free. + +Fix this by copying h_name over and freeing it at the end. This +resolves BZ #30843, which is assigned CVE-2023-4806. This is a minimal +RHEL-8-specific fix. Test case differences from upstream: + +- The test module needs to explicitly link against libnss_files on + RHEL-8; upstream libnss_files is built into libc.so. + +- Test module code was adapted to not use the upstream NSS module + convenience macros. + +This change is adapted from the following commit from upstream: + +commit 973fe93a5675c42798b2161c6f29c01b0e243994 +Author: Siddhesh Poyarekar +Date: Fri Sep 15 13:51:12 2023 -0400 + + getaddrinfo: Fix use after free in getcanonname (CVE-2023-4806) + + When an NSS plugin only implements the _gethostbyname2_r and + _getcanonname_r callbacks, getaddrinfo could use memory that was freed + during tmpbuf resizing, through h_name in a previous query response. + + The backing store for res->at->name when doing a query with + gethostbyname3_r or gethostbyname2_r is tmpbuf, which is reallocated in + gethosts during the query. For AF_INET6 lookup with AI_ALL | + AI_V4MAPPED, gethosts gets called twice, once for a v6 lookup and second + for a v4 lookup. In this case, if the first call reallocates tmpbuf + enough number of times, resulting in a malloc, th->h_name (that + res->at->name refers to) ends up on a heap allocated storage in tmpbuf. + Now if the second call to gethosts also causes the plugin callback to + return NSS_STATUS_TRYAGAIN, tmpbuf will get freed, resulting in a UAF + reference in res->at->name. This then gets dereferenced in the + getcanonname_r plugin call, resulting in the use after free. + + Fix this by copying h_name over and freeing it at the end. This + resolves BZ #30843, which is assigned CVE-2023-4806. + + Signed-off-by: Siddhesh Poyarekar + +diff --git a/nss/Makefile b/nss/Makefile +index cfb255c6e7a3a4de..5829a2539306ddb5 100644 +--- a/nss/Makefile ++++ b/nss/Makefile +@@ -66,7 +66,8 @@ xtests = bug-erange + tests-container = \ + tst-nss-db-endpwent \ + tst-nss-db-endgrent \ +- tst-nss-gai-actions ++ tst-nss-gai-actions \ ++ tst-nss-gai-hv2-canonname + + # Tests which need libdl + ifeq (yes,$(build-shared)) +@@ -132,7 +133,8 @@ routines += $(libnss_files-routines) + static-only-routines += $(libnss_files-routines) + tests-static += tst-nss-static + endif +-extra-test-objs += nss_test1.os nss_test2.os nss_test_errno.os ++extra-test-objs += nss_test1.os nss_test2.os nss_test_errno.os \ ++ nss_test_gai_hv2_canonname.os + + include ../Rules + +@@ -169,12 +171,17 @@ rtld-tests-LDFLAGS += -Wl,--dynamic-list=nss_test.ver + libof-nss_test1 = extramodules + libof-nss_test2 = extramodules + libof-nss_test_errno = extramodules ++libof-nss_test_gai_hv2_canonname = extramodules + $(objpfx)/libnss_test1.so: $(objpfx)nss_test1.os $(link-libc-deps) + $(build-module) + $(objpfx)/libnss_test2.so: $(objpfx)nss_test2.os $(link-libc-deps) + $(build-module) + $(objpfx)/libnss_test_errno.so: $(objpfx)nss_test_errno.os $(link-libc-deps) + $(build-module) ++$(objpfx)/libnss_test_gai_hv2_canonname.so: \ ++ $(objpfx)nss_test_gai_hv2_canonname.os $(link-libc-deps) \ ++ $(objpfx)/libnss_files.so ++ $(build-module) + $(objpfx)nss_test2.os : nss_test1.c + ifdef libnss_test1.so-version + $(objpfx)/libnss_test1.so$(libnss_test1.so-version): $(objpfx)/libnss_test1.so +@@ -187,10 +194,14 @@ endif + $(objpfx)/libnss_test_errno.so$(libnss_files.so-version): \ + $(objpfx)/libnss_test_errno.so + $(make-link) ++$(objpfx)/libnss_test_gai_hv2_canonname.so$(libnss_files.so-version): \ ++ $(objpfx)/libnss_test_gai_hv2_canonname.so ++ $(make-link) + $(patsubst %,$(objpfx)%.out,$(tests)) : \ + $(objpfx)/libnss_test1.so$(libnss_test1.so-version) \ + $(objpfx)/libnss_test2.so$(libnss_test2.so-version) \ +- $(objpfx)/libnss_test_errno.so$(libnss_files.so-version) ++ $(objpfx)/libnss_test_errno.so$(libnss_files.so-version) \ ++ $(objpfx)/libnss_test_gai_hv2_canonname.so$(libnss_files.so-version) + + ifeq (yes,$(have-thread-library)) + $(objpfx)tst-cancel-getpwuid_r: $(shared-thread-library) +diff --git a/nss/nss_test_gai_hv2_canonname.c b/nss/nss_test_gai_hv2_canonname.c +new file mode 100644 +index 0000000000000000..4195d7d24fdd5f6d +--- /dev/null ++++ b/nss/nss_test_gai_hv2_canonname.c +@@ -0,0 +1,64 @@ ++/* NSS service provider that only provides gethostbyname2_r. ++ Copyright The GNU Toolchain Authors. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for 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 "nss/tst-nss-gai-hv2-canonname.h" ++ ++/* Catch misnamed and functions. */ ++#pragma GCC diagnostic error "-Wmissing-prototypes" ++ ++extern enum nss_status _nss_files_gethostbyname2_r (const char *, int, ++ struct hostent *, char *, ++ size_t, int *, int *); ++ ++enum nss_status ++_nss_test_gai_hv2_canonname_gethostbyname2_r (const char *, int, struct hostent ++ *, char *, size_t, int *, int *); ++ ++enum nss_status ++_nss_test_gai_hv2_canonname_getcanonname_r (const char *, char *, size_t, char ++ **, int *, int *); ++ ++enum nss_status ++_nss_test_gai_hv2_canonname_gethostbyname2_r (const char *name, int af, ++ struct hostent *result, ++ char *buffer, size_t buflen, ++ int *errnop, int *herrnop) ++{ ++ return _nss_files_gethostbyname2_r (name, af, result, buffer, buflen, errnop, ++ herrnop); ++} ++ ++enum nss_status ++_nss_test_gai_hv2_canonname_getcanonname_r (const char *name, char *buffer, ++ size_t buflen, char **result, ++ int *errnop, int *h_errnop) ++{ ++ /* We expect QUERYNAME, which is a small enough string that it shouldn't fail ++ the test. */ ++ if (memcmp (QUERYNAME, name, sizeof (QUERYNAME)) ++ || buflen < sizeof (QUERYNAME)) ++ abort (); ++ ++ strncpy (buffer, name, buflen); ++ *result = buffer; ++ return NSS_STATUS_SUCCESS; ++} +diff --git a/nss/tst-nss-gai-hv2-canonname.c b/nss/tst-nss-gai-hv2-canonname.c +new file mode 100644 +index 0000000000000000..d5f10c07d6a90773 +--- /dev/null ++++ b/nss/tst-nss-gai-hv2-canonname.c +@@ -0,0 +1,63 @@ ++/* Test NSS query path for plugins that only implement gethostbyname2 ++ (#30843). ++ Copyright The GNU Toolchain Authors. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for 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 "nss/tst-nss-gai-hv2-canonname.h" ++ ++#define PREPARE do_prepare ++ ++static void do_prepare (int a, char **av) ++{ ++ FILE *hosts = xfopen ("/etc/hosts", "w"); ++ for (unsigned i = 2; i < 255; i++) ++ { ++ fprintf (hosts, "ff01::ff02:ff03:%u:2\ttest.example.com\n", i); ++ fprintf (hosts, "192.168.0.%u\ttest.example.com\n", i); ++ } ++ xfclose (hosts); ++} ++ ++static int ++do_test (void) ++{ ++ __nss_configure_lookup ("hosts", "test_gai_hv2_canonname"); ++ ++ struct addrinfo hints = {}; ++ struct addrinfo *result = NULL; ++ ++ hints.ai_family = AF_INET6; ++ hints.ai_flags = AI_ALL | AI_V4MAPPED | AI_CANONNAME; ++ ++ int ret = getaddrinfo (QUERYNAME, NULL, &hints, &result); ++ ++ if (ret != 0) ++ FAIL_EXIT1 ("getaddrinfo failed: %s\n", gai_strerror (ret)); ++ ++ TEST_COMPARE_STRING (result->ai_canonname, QUERYNAME); ++ ++ freeaddrinfo(result); ++ return 0; ++} ++ ++#include +diff --git a/nss/tst-nss-gai-hv2-canonname.h b/nss/tst-nss-gai-hv2-canonname.h +new file mode 100644 +index 0000000000000000..14f2a9cb0867dff9 +--- /dev/null ++++ b/nss/tst-nss-gai-hv2-canonname.h +@@ -0,0 +1 @@ ++#define QUERYNAME "test.example.com" +diff --git a/nss/tst-nss-gai-hv2-canonname.root/postclean.req b/nss/tst-nss-gai-hv2-canonname.root/postclean.req +new file mode 100644 +index 0000000000000000..e69de29bb2d1d643 +diff --git a/nss/tst-nss-gai-hv2-canonname.root/tst-nss-gai-hv2-canonname.script b/nss/tst-nss-gai-hv2-canonname.root/tst-nss-gai-hv2-canonname.script +new file mode 100644 +index 0000000000000000..31848b4a28524af6 +--- /dev/null ++++ b/nss/tst-nss-gai-hv2-canonname.root/tst-nss-gai-hv2-canonname.script +@@ -0,0 +1,2 @@ ++cp $B/nss/libnss_test_gai_hv2_canonname.so $L/libnss_test_gai_hv2_canonname.so.2 ++su +diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c +index 4fa963644af8b7d5..46046504a6858f2e 100644 +--- a/sysdeps/posix/getaddrinfo.c ++++ b/sysdeps/posix/getaddrinfo.c +@@ -233,7 +233,6 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, + } + array[i].next = array + i + 1; + } +- array[0].name = h->h_name; + array[count - 1].next = NULL; + + *result = array; +@@ -287,6 +286,18 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, + } \ + *pat = addrmem; \ + \ ++ /* Store h_name so that it survives accidental deallocation when \ ++ gethosts is called again and tmpbuf gets reallocated. */ \ ++ if (h_name == NULL && th.h_name != NULL) \ ++ { \ ++ h_name = __strdup (th.h_name); \ ++ if (h_name == NULL) \ ++ { \ ++ __resolv_context_put (res_ctx); \ ++ result = -EAI_SYSTEM; \ ++ goto free_and_return; \ ++ } \ ++ } \ + if (localcanon != NULL && canon == NULL) \ + { \ + canonbuf = __strdup (localcanon); \ +@@ -323,15 +334,15 @@ typedef enum nss_status (*nss_getcanonname_r) + memory allocation failure. The returned string is allocated on the + heap; the caller has to free it. */ + static char * +-getcanonname (service_user *nip, struct gaih_addrtuple *at, const char *name) ++getcanonname (service_user *nip, const char *hname, const char *name) + { + nss_getcanonname_r cfct = __nss_lookup_function (nip, "getcanonname_r"); + char *s = (char *) name; + if (cfct != NULL) + { + char buf[256]; +- if (DL_CALL_FCT (cfct, (at->name ?: name, buf, sizeof (buf), +- &s, &errno, &h_errno)) != NSS_STATUS_SUCCESS) ++ if (DL_CALL_FCT (cfct, (hname ?: name, buf, sizeof (buf), &s, &errno, ++ &h_errno)) != NSS_STATUS_SUCCESS) + /* If the canonical name cannot be determined, use the passed + string. */ + s = (char *) name; +@@ -349,6 +360,7 @@ gaih_inet (const char *name, const struct gaih_service *service, + struct gaih_addrtuple *at = NULL; + bool got_ipv6 = false; + const char *canon = NULL; ++ char *h_name = NULL; + const char *orig_name = name; + + /* Reserve stack memory for the scratch buffer in the getaddrinfo +@@ -919,7 +931,7 @@ gaih_inet (const char *name, const struct gaih_service *service, + if ((req->ai_flags & AI_CANONNAME) != 0 + && canon == NULL) + { +- canonbuf = getcanonname (nip, at, name); ++ canonbuf = getcanonname (nip, h_name, name); + if (canonbuf == NULL) + { + __resolv_context_enable_inet6 +@@ -1169,6 +1181,7 @@ gaih_inet (const char *name, const struct gaih_service *service, + free ((char *) name); + free (addrmem); + free (canonbuf); ++ free (h_name); + + return result; + } diff --git a/glibc-RHEL-2434.patch b/glibc-RHEL-2434.patch new file mode 100644 index 0000000..61f1587 --- /dev/null +++ b/glibc-RHEL-2434.patch @@ -0,0 +1,987 @@ +commit 1c37b8022e8763fedbb3f79c02e05c6acfe5a215 +Author: Siddhesh Poyarekar +Date: Thu Mar 17 11:44:34 2022 +0530 + + Simplify allocations and fix merge and continue actions [BZ #28931] + + Allocations for address tuples is currently a bit confusing because of + the pointer chasing through PAT, making it hard to observe the sequence + in which allocations have been made. Narrow scope of the pointer + chasing through PAT so that it is only used where necessary. + + This also tightens actions behaviour with the hosts database in + getaddrinfo to comply with the manual text. The "continue" action + discards previous results and the "merge" action results in an immedate + lookup failure. Consequently, chaining of allocations across modules is + no longer necessary, thus opening up cleanup opportunities. + + A test has been added that checks some combinations to ensure that they + work correctly. + + Resolves: BZ #28931 + + Signed-off-by: Siddhesh Poyarekar + Reviewed-by: DJ Delorie + +Conflicts: + nss/Makefile + (Missing test cases) + sysdeps/posix/getaddrinfo.c + (RES_USE_INET6 still present in RHEL-8 and NSS module traversal rewrite + not in RHEL-8) + nss/tst-nss-gai-actions.c + (Adapted SUCCESS=merge result to RHEL-8) + +diff --git a/nss/Makefile b/nss/Makefile +index e8a7d9c7b3cefcdf..cfb255c6e7a3a4de 100644 +--- a/nss/Makefile ++++ b/nss/Makefile +@@ -65,7 +65,8 @@ xtests = bug-erange + + tests-container = \ + tst-nss-db-endpwent \ +- tst-nss-db-endgrent ++ tst-nss-db-endgrent \ ++ tst-nss-gai-actions + + # Tests which need libdl + ifeq (yes,$(build-shared)) +diff --git a/nss/tst-nss-gai-actions.c b/nss/tst-nss-gai-actions.c +new file mode 100644 +index 0000000000000000..c35e752896eceb2a +--- /dev/null ++++ b/nss/tst-nss-gai-actions.c +@@ -0,0 +1,156 @@ ++/* Test continue and merge NSS actions for getaddrinfo. ++ Copyright The GNU Toolchain Authors. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for 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 ++#include ++#include ++#include ++#include ++ ++enum ++{ ++ ACTION_MERGE = 0, ++ ACTION_CONTINUE, ++}; ++ ++static const char * ++family_str (int family) ++{ ++ switch (family) ++ { ++ case AF_UNSPEC: ++ return "AF_UNSPEC"; ++ case AF_INET: ++ return "AF_INET"; ++ default: ++ __builtin_unreachable (); ++ } ++} ++ ++static const char * ++action_str (int action) ++{ ++ switch (action) ++ { ++ case ACTION_MERGE: ++ return "merge"; ++ case ACTION_CONTINUE: ++ return "continue"; ++ default: ++ __builtin_unreachable (); ++ } ++} ++ ++static void ++do_one_test (int action, int family, bool canon) ++{ ++ struct addrinfo hints = ++ { ++ .ai_family = family, ++ }; ++ ++ struct addrinfo *ai; ++ ++ if (canon) ++ hints.ai_flags = AI_CANONNAME; ++ ++ printf ("***** Testing \"files [SUCCESS=%s] files\" for family %s, %s\n", ++ action_str (action), family_str (family), ++ canon ? "AI_CANONNAME" : ""); ++ ++ int ret = getaddrinfo ("example.org", "80", &hints, &ai); ++ ++ switch (action) ++ { ++ case ACTION_MERGE: ++ if (ret == 0) ++ { ++ if (hints.ai_flags == 0 && hints.ai_family == AF_INET) ++ { ++ printf ("***** RHEL-8 limitation: " ++ "NSS modules infrastructure incorrectly allows MERGE\n"); ++ return; ++ } ++ ++ char *formatted = support_format_addrinfo (ai, ret); ++ ++ printf ("merge unexpectedly succeeded:\n %s\n", formatted); ++ support_record_failure (); ++ free (formatted); ++ } ++ else ++ return; ++ case ACTION_CONTINUE: ++ { ++ char *formatted = support_format_addrinfo (ai, ret); ++ ++ /* Verify that the result appears exactly once. */ ++ const char *expected = "address: STREAM/TCP 192.0.0.1 80\n" ++ "address: DGRAM/UDP 192.0.0.1 80\n" ++ "address: RAW/IP 192.0.0.1 80\n"; ++ ++ const char *contains = strstr (formatted, expected); ++ const char *contains2 = NULL; ++ ++ if (contains != NULL) ++ contains2 = strstr (contains + strlen (expected), expected); ++ ++ if (contains == NULL || contains2 != NULL) ++ { ++ printf ("continue failed:\n%s\n", formatted); ++ support_record_failure (); ++ } ++ ++ free (formatted); ++ break; ++ } ++ default: ++ __builtin_unreachable (); ++ } ++} ++ ++static void ++do_one_test_set (int action) ++{ ++ char buf[32]; ++ ++ snprintf (buf, sizeof (buf), "files [SUCCESS=%s] files", ++ action_str (action)); ++ __nss_configure_lookup ("hosts", buf); ++ ++ do_one_test (action, AF_UNSPEC, false); ++ do_one_test (action, AF_INET, false); ++ do_one_test (action, AF_INET, true); ++} ++ ++static int ++do_test (void) ++{ ++ do_one_test_set (ACTION_CONTINUE); ++ do_one_test_set (ACTION_MERGE); ++ return 0; ++} ++ ++#include +diff --git a/nss/tst-nss-gai-actions.root/etc/host.conf b/nss/tst-nss-gai-actions.root/etc/host.conf +new file mode 100644 +index 0000000000000000..d1a59f73a90f2993 +--- /dev/null ++++ b/nss/tst-nss-gai-actions.root/etc/host.conf +@@ -0,0 +1 @@ ++multi on +diff --git a/nss/tst-nss-gai-actions.root/etc/hosts b/nss/tst-nss-gai-actions.root/etc/hosts +new file mode 100644 +index 0000000000000000..50ce9774dc2c21d9 +--- /dev/null ++++ b/nss/tst-nss-gai-actions.root/etc/hosts +@@ -0,0 +1,508 @@ ++192.0.0.1 example.org ++192.0.0.2 example.org ++192.0.0.3 example.org ++192.0.0.4 example.org ++192.0.0.5 example.org ++192.0.0.6 example.org ++192.0.0.7 example.org ++192.0.0.8 example.org ++192.0.0.9 example.org ++192.0.0.10 example.org ++192.0.0.11 example.org ++192.0.0.12 example.org ++192.0.0.13 example.org ++192.0.0.14 example.org ++192.0.0.15 example.org ++192.0.0.16 example.org ++192.0.0.17 example.org ++192.0.0.18 example.org ++192.0.0.19 example.org ++192.0.0.20 example.org ++192.0.0.21 example.org ++192.0.0.22 example.org ++192.0.0.23 example.org ++192.0.0.24 example.org ++192.0.0.25 example.org ++192.0.0.26 example.org ++192.0.0.27 example.org ++192.0.0.28 example.org ++192.0.0.29 example.org ++192.0.0.30 example.org ++192.0.0.31 example.org ++192.0.0.32 example.org ++192.0.0.33 example.org ++192.0.0.34 example.org ++192.0.0.35 example.org ++192.0.0.36 example.org ++192.0.0.37 example.org ++192.0.0.38 example.org ++192.0.0.39 example.org ++192.0.0.40 example.org ++192.0.0.41 example.org ++192.0.0.42 example.org ++192.0.0.43 example.org ++192.0.0.44 example.org ++192.0.0.45 example.org ++192.0.0.46 example.org ++192.0.0.47 example.org ++192.0.0.48 example.org ++192.0.0.49 example.org ++192.0.0.50 example.org ++192.0.0.51 example.org ++192.0.0.52 example.org ++192.0.0.53 example.org ++192.0.0.54 example.org ++192.0.0.55 example.org ++192.0.0.56 example.org ++192.0.0.57 example.org ++192.0.0.58 example.org ++192.0.0.59 example.org ++192.0.0.60 example.org ++192.0.0.61 example.org ++192.0.0.62 example.org ++192.0.0.63 example.org ++192.0.0.64 example.org ++192.0.0.65 example.org ++192.0.0.66 example.org ++192.0.0.67 example.org ++192.0.0.68 example.org ++192.0.0.69 example.org ++192.0.0.70 example.org ++192.0.0.71 example.org ++192.0.0.72 example.org ++192.0.0.73 example.org ++192.0.0.74 example.org ++192.0.0.75 example.org ++192.0.0.76 example.org ++192.0.0.77 example.org ++192.0.0.78 example.org ++192.0.0.79 example.org ++192.0.0.80 example.org ++192.0.0.81 example.org ++192.0.0.82 example.org ++192.0.0.83 example.org ++192.0.0.84 example.org ++192.0.0.85 example.org ++192.0.0.86 example.org ++192.0.0.87 example.org ++192.0.0.88 example.org ++192.0.0.89 example.org ++192.0.0.90 example.org ++192.0.0.91 example.org ++192.0.0.92 example.org ++192.0.0.93 example.org ++192.0.0.94 example.org ++192.0.0.95 example.org ++192.0.0.96 example.org ++192.0.0.97 example.org ++192.0.0.98 example.org ++192.0.0.99 example.org ++192.0.0.100 example.org ++192.0.0.101 example.org ++192.0.0.102 example.org ++192.0.0.103 example.org ++192.0.0.104 example.org ++192.0.0.105 example.org ++192.0.0.106 example.org ++192.0.0.107 example.org ++192.0.0.108 example.org ++192.0.0.109 example.org ++192.0.0.110 example.org ++192.0.0.111 example.org ++192.0.0.112 example.org ++192.0.0.113 example.org ++192.0.0.114 example.org ++192.0.0.115 example.org ++192.0.0.116 example.org ++192.0.0.117 example.org ++192.0.0.118 example.org ++192.0.0.119 example.org ++192.0.0.120 example.org ++192.0.0.121 example.org ++192.0.0.122 example.org ++192.0.0.123 example.org ++192.0.0.124 example.org ++192.0.0.125 example.org ++192.0.0.126 example.org ++192.0.0.127 example.org ++192.0.0.128 example.org ++192.0.0.129 example.org ++192.0.0.130 example.org ++192.0.0.131 example.org ++192.0.0.132 example.org ++192.0.0.133 example.org ++192.0.0.134 example.org ++192.0.0.135 example.org ++192.0.0.136 example.org ++192.0.0.137 example.org ++192.0.0.138 example.org ++192.0.0.139 example.org ++192.0.0.140 example.org ++192.0.0.141 example.org ++192.0.0.142 example.org ++192.0.0.143 example.org ++192.0.0.144 example.org ++192.0.0.145 example.org ++192.0.0.146 example.org ++192.0.0.147 example.org ++192.0.0.148 example.org ++192.0.0.149 example.org ++192.0.0.150 example.org ++192.0.0.151 example.org ++192.0.0.152 example.org ++192.0.0.153 example.org ++192.0.0.154 example.org ++192.0.0.155 example.org ++192.0.0.156 example.org ++192.0.0.157 example.org ++192.0.0.158 example.org ++192.0.0.159 example.org ++192.0.0.160 example.org ++192.0.0.161 example.org ++192.0.0.162 example.org ++192.0.0.163 example.org ++192.0.0.164 example.org ++192.0.0.165 example.org ++192.0.0.166 example.org ++192.0.0.167 example.org ++192.0.0.168 example.org ++192.0.0.169 example.org ++192.0.0.170 example.org ++192.0.0.171 example.org ++192.0.0.172 example.org ++192.0.0.173 example.org ++192.0.0.174 example.org ++192.0.0.175 example.org ++192.0.0.176 example.org ++192.0.0.177 example.org ++192.0.0.178 example.org ++192.0.0.179 example.org ++192.0.0.180 example.org ++192.0.0.181 example.org ++192.0.0.182 example.org ++192.0.0.183 example.org ++192.0.0.184 example.org ++192.0.0.185 example.org ++192.0.0.186 example.org ++192.0.0.187 example.org ++192.0.0.188 example.org ++192.0.0.189 example.org ++192.0.0.190 example.org ++192.0.0.191 example.org ++192.0.0.192 example.org ++192.0.0.193 example.org ++192.0.0.194 example.org ++192.0.0.195 example.org ++192.0.0.196 example.org ++192.0.0.197 example.org ++192.0.0.198 example.org ++192.0.0.199 example.org ++192.0.0.200 example.org ++192.0.0.201 example.org ++192.0.0.202 example.org ++192.0.0.203 example.org ++192.0.0.204 example.org ++192.0.0.205 example.org ++192.0.0.206 example.org ++192.0.0.207 example.org ++192.0.0.208 example.org ++192.0.0.209 example.org ++192.0.0.210 example.org ++192.0.0.211 example.org ++192.0.0.212 example.org ++192.0.0.213 example.org ++192.0.0.214 example.org ++192.0.0.215 example.org ++192.0.0.216 example.org ++192.0.0.217 example.org ++192.0.0.218 example.org ++192.0.0.219 example.org ++192.0.0.220 example.org ++192.0.0.221 example.org ++192.0.0.222 example.org ++192.0.0.223 example.org ++192.0.0.224 example.org ++192.0.0.225 example.org ++192.0.0.226 example.org ++192.0.0.227 example.org ++192.0.0.228 example.org ++192.0.0.229 example.org ++192.0.0.230 example.org ++192.0.0.231 example.org ++192.0.0.232 example.org ++192.0.0.233 example.org ++192.0.0.234 example.org ++192.0.0.235 example.org ++192.0.0.236 example.org ++192.0.0.237 example.org ++192.0.0.238 example.org ++192.0.0.239 example.org ++192.0.0.240 example.org ++192.0.0.241 example.org ++192.0.0.242 example.org ++192.0.0.243 example.org ++192.0.0.244 example.org ++192.0.0.245 example.org ++192.0.0.246 example.org ++192.0.0.247 example.org ++192.0.0.248 example.org ++192.0.0.249 example.org ++192.0.0.250 example.org ++192.0.0.251 example.org ++192.0.0.252 example.org ++192.0.0.253 example.org ++192.0.0.254 example.org ++192.0.1.1 example.org ++192.0.1.2 example.org ++192.0.1.3 example.org ++192.0.1.4 example.org ++192.0.1.5 example.org ++192.0.1.6 example.org ++192.0.1.7 example.org ++192.0.1.8 example.org ++192.0.1.9 example.org ++192.0.1.10 example.org ++192.0.1.11 example.org ++192.0.1.12 example.org ++192.0.1.13 example.org ++192.0.1.14 example.org ++192.0.1.15 example.org ++192.0.1.16 example.org ++192.0.1.17 example.org ++192.0.1.18 example.org ++192.0.1.19 example.org ++192.0.1.20 example.org ++192.0.1.21 example.org ++192.0.1.22 example.org ++192.0.1.23 example.org ++192.0.1.24 example.org ++192.0.1.25 example.org ++192.0.1.26 example.org ++192.0.1.27 example.org ++192.0.1.28 example.org ++192.0.1.29 example.org ++192.0.1.30 example.org ++192.0.1.31 example.org ++192.0.1.32 example.org ++192.0.1.33 example.org ++192.0.1.34 example.org ++192.0.1.35 example.org ++192.0.1.36 example.org ++192.0.1.37 example.org ++192.0.1.38 example.org ++192.0.1.39 example.org ++192.0.1.40 example.org ++192.0.1.41 example.org ++192.0.1.42 example.org ++192.0.1.43 example.org ++192.0.1.44 example.org ++192.0.1.45 example.org ++192.0.1.46 example.org ++192.0.1.47 example.org ++192.0.1.48 example.org ++192.0.1.49 example.org ++192.0.1.50 example.org ++192.0.1.51 example.org ++192.0.1.52 example.org ++192.0.1.53 example.org ++192.0.1.54 example.org ++192.0.1.55 example.org ++192.0.1.56 example.org ++192.0.1.57 example.org ++192.0.1.58 example.org ++192.0.1.59 example.org ++192.0.1.60 example.org ++192.0.1.61 example.org ++192.0.1.62 example.org ++192.0.1.63 example.org ++192.0.1.64 example.org ++192.0.1.65 example.org ++192.0.1.66 example.org ++192.0.1.67 example.org ++192.0.1.68 example.org ++192.0.1.69 example.org ++192.0.1.70 example.org ++192.0.1.71 example.org ++192.0.1.72 example.org ++192.0.1.73 example.org ++192.0.1.74 example.org ++192.0.1.75 example.org ++192.0.1.76 example.org ++192.0.1.77 example.org ++192.0.1.78 example.org ++192.0.1.79 example.org ++192.0.1.80 example.org ++192.0.1.81 example.org ++192.0.1.82 example.org ++192.0.1.83 example.org ++192.0.1.84 example.org ++192.0.1.85 example.org ++192.0.1.86 example.org ++192.0.1.87 example.org ++192.0.1.88 example.org ++192.0.1.89 example.org ++192.0.1.90 example.org ++192.0.1.91 example.org ++192.0.1.92 example.org ++192.0.1.93 example.org ++192.0.1.94 example.org ++192.0.1.95 example.org ++192.0.1.96 example.org ++192.0.1.97 example.org ++192.0.1.98 example.org ++192.0.1.99 example.org ++192.0.1.100 example.org ++192.0.1.101 example.org ++192.0.1.102 example.org ++192.0.1.103 example.org ++192.0.1.104 example.org ++192.0.1.105 example.org ++192.0.1.106 example.org ++192.0.1.107 example.org ++192.0.1.108 example.org ++192.0.1.109 example.org ++192.0.1.110 example.org ++192.0.1.111 example.org ++192.0.1.112 example.org ++192.0.1.113 example.org ++192.0.1.114 example.org ++192.0.1.115 example.org ++192.0.1.116 example.org ++192.0.1.117 example.org ++192.0.1.118 example.org ++192.0.1.119 example.org ++192.0.1.120 example.org ++192.0.1.121 example.org ++192.0.1.122 example.org ++192.0.1.123 example.org ++192.0.1.124 example.org ++192.0.1.125 example.org ++192.0.1.126 example.org ++192.0.1.127 example.org ++192.0.1.128 example.org ++192.0.1.129 example.org ++192.0.1.130 example.org ++192.0.1.131 example.org ++192.0.1.132 example.org ++192.0.1.133 example.org ++192.0.1.134 example.org ++192.0.1.135 example.org ++192.0.1.136 example.org ++192.0.1.137 example.org ++192.0.1.138 example.org ++192.0.1.139 example.org ++192.0.1.140 example.org ++192.0.1.141 example.org ++192.0.1.142 example.org ++192.0.1.143 example.org ++192.0.1.144 example.org ++192.0.1.145 example.org ++192.0.1.146 example.org ++192.0.1.147 example.org ++192.0.1.148 example.org ++192.0.1.149 example.org ++192.0.1.150 example.org ++192.0.1.151 example.org ++192.0.1.152 example.org ++192.0.1.153 example.org ++192.0.1.154 example.org ++192.0.1.155 example.org ++192.0.1.156 example.org ++192.0.1.157 example.org ++192.0.1.158 example.org ++192.0.1.159 example.org ++192.0.1.160 example.org ++192.0.1.161 example.org ++192.0.1.162 example.org ++192.0.1.163 example.org ++192.0.1.164 example.org ++192.0.1.165 example.org ++192.0.1.166 example.org ++192.0.1.167 example.org ++192.0.1.168 example.org ++192.0.1.169 example.org ++192.0.1.170 example.org ++192.0.1.171 example.org ++192.0.1.172 example.org ++192.0.1.173 example.org ++192.0.1.174 example.org ++192.0.1.175 example.org ++192.0.1.176 example.org ++192.0.1.177 example.org ++192.0.1.178 example.org ++192.0.1.179 example.org ++192.0.1.180 example.org ++192.0.1.181 example.org ++192.0.1.182 example.org ++192.0.1.183 example.org ++192.0.1.184 example.org ++192.0.1.185 example.org ++192.0.1.186 example.org ++192.0.1.187 example.org ++192.0.1.188 example.org ++192.0.1.189 example.org ++192.0.1.190 example.org ++192.0.1.191 example.org ++192.0.1.192 example.org ++192.0.1.193 example.org ++192.0.1.194 example.org ++192.0.1.195 example.org ++192.0.1.196 example.org ++192.0.1.197 example.org ++192.0.1.198 example.org ++192.0.1.199 example.org ++192.0.1.200 example.org ++192.0.1.201 example.org ++192.0.1.202 example.org ++192.0.1.203 example.org ++192.0.1.204 example.org ++192.0.1.205 example.org ++192.0.1.206 example.org ++192.0.1.207 example.org ++192.0.1.208 example.org ++192.0.1.209 example.org ++192.0.1.210 example.org ++192.0.1.211 example.org ++192.0.1.212 example.org ++192.0.1.213 example.org ++192.0.1.214 example.org ++192.0.1.215 example.org ++192.0.1.216 example.org ++192.0.1.217 example.org ++192.0.1.218 example.org ++192.0.1.219 example.org ++192.0.1.220 example.org ++192.0.1.221 example.org ++192.0.1.222 example.org ++192.0.1.223 example.org ++192.0.1.224 example.org ++192.0.1.225 example.org ++192.0.1.226 example.org ++192.0.1.227 example.org ++192.0.1.228 example.org ++192.0.1.229 example.org ++192.0.1.230 example.org ++192.0.1.231 example.org ++192.0.1.232 example.org ++192.0.1.233 example.org ++192.0.1.234 example.org ++192.0.1.235 example.org ++192.0.1.236 example.org ++192.0.1.237 example.org ++192.0.1.238 example.org ++192.0.1.239 example.org ++192.0.1.240 example.org ++192.0.1.241 example.org ++192.0.1.242 example.org ++192.0.1.243 example.org ++192.0.1.244 example.org ++192.0.1.245 example.org ++192.0.1.246 example.org ++192.0.1.247 example.org ++192.0.1.248 example.org ++192.0.1.249 example.org ++192.0.1.250 example.org ++192.0.1.251 example.org ++192.0.1.252 example.org ++192.0.1.253 example.org ++192.0.1.254 example.org +diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c +index fae3dea81f19dba6..4fa963644af8b7d5 100644 +--- a/sysdeps/posix/getaddrinfo.c ++++ b/sysdeps/posix/getaddrinfo.c +@@ -474,11 +474,6 @@ gaih_inet (const char *name, const struct gaih_service *service, + + if (name != NULL) + { +- at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used); +- at->family = AF_UNSPEC; +- at->scopeid = 0; +- at->next = NULL; +- + if (req->ai_flags & AI_IDN) + { + char *out; +@@ -489,13 +484,21 @@ gaih_inet (const char *name, const struct gaih_service *service, + malloc_name = true; + } + +- if (__inet_aton_exact (name, (struct in_addr *) at->addr) != 0) ++ uint32_t addr[4]; ++ if (__inet_aton_exact (name, (struct in_addr *) addr) != 0) + { ++ at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used); ++ at->scopeid = 0; ++ at->next = NULL; ++ + if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET) +- at->family = AF_INET; ++ { ++ memcpy (at->addr, addr, sizeof (at->addr)); ++ at->family = AF_INET; ++ } + else if (req->ai_family == AF_INET6 && (req->ai_flags & AI_V4MAPPED)) + { +- at->addr[3] = at->addr[0]; ++ at->addr[3] = addr[0]; + at->addr[2] = htonl (0xffff); + at->addr[1] = 0; + at->addr[0] = 0; +@@ -509,49 +512,62 @@ gaih_inet (const char *name, const struct gaih_service *service, + + if (req->ai_flags & AI_CANONNAME) + canon = name; ++ ++ goto process_list; + } +- else if (at->family == AF_UNSPEC) ++ ++ char *scope_delim = strchr (name, SCOPE_DELIMITER); ++ int e; ++ ++ if (scope_delim == NULL) ++ e = inet_pton (AF_INET6, name, addr); ++ else ++ e = __inet_pton_length (AF_INET6, name, scope_delim - name, addr); ++ ++ if (e > 0) + { +- char *scope_delim = strchr (name, SCOPE_DELIMITER); +- int e; +- if (scope_delim == NULL) +- e = inet_pton (AF_INET6, name, at->addr); ++ at = alloca_account (sizeof (struct gaih_addrtuple), ++ alloca_used); ++ at->scopeid = 0; ++ at->next = NULL; ++ ++ if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6) ++ { ++ memcpy (at->addr, addr, sizeof (at->addr)); ++ at->family = AF_INET6; ++ } ++ else if (req->ai_family == AF_INET ++ && IN6_IS_ADDR_V4MAPPED (addr)) ++ { ++ at->addr[0] = addr[3]; ++ at->addr[1] = addr[1]; ++ at->addr[2] = addr[2]; ++ at->addr[3] = addr[3]; ++ at->family = AF_INET; ++ } + else +- e = __inet_pton_length (AF_INET6, name, scope_delim - name, +- at->addr); +- if (e > 0) + { +- if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6) +- at->family = AF_INET6; +- else if (req->ai_family == AF_INET +- && IN6_IS_ADDR_V4MAPPED (at->addr)) +- { +- at->addr[0] = at->addr[3]; +- at->family = AF_INET; +- } +- else +- { +- result = -EAI_ADDRFAMILY; +- goto free_and_return; +- } +- +- if (scope_delim != NULL +- && __inet6_scopeid_pton ((struct in6_addr *) at->addr, +- scope_delim + 1, +- &at->scopeid) != 0) +- { +- result = -EAI_NONAME; +- goto free_and_return; +- } ++ result = -EAI_ADDRFAMILY; ++ goto free_and_return; ++ } + +- if (req->ai_flags & AI_CANONNAME) +- canon = name; ++ if (scope_delim != NULL ++ && __inet6_scopeid_pton ((struct in6_addr *) at->addr, ++ scope_delim + 1, ++ &at->scopeid) != 0) ++ { ++ result = -EAI_NONAME; ++ goto free_and_return; + } ++ ++ if (req->ai_flags & AI_CANONNAME) ++ canon = name; ++ ++ goto process_list; + } + +- if (at->family == AF_UNSPEC && (req->ai_flags & AI_NUMERICHOST) == 0) ++ if ((req->ai_flags & AI_NUMERICHOST) == 0) + { +- struct gaih_addrtuple **pat = &at; + int no_data = 0; + int no_inet6_data = 0; + service_user *nip; +@@ -560,6 +576,7 @@ gaih_inet (const char *name, const struct gaih_service *service, + int no_more; + struct resolv_context *res_ctx = NULL; + bool res_enable_inet6 = false; ++ bool do_merge = false; + + /* If we do not have to look for IPv6 addresses or the canonical + name, use the simple, old functions, which do not support +@@ -596,7 +613,7 @@ gaih_inet (const char *name, const struct gaih_service *service, + result = -EAI_MEMORY; + goto free_and_return; + } +- *pat = addrmem; ++ at = addrmem; + } + else + { +@@ -649,6 +666,8 @@ gaih_inet (const char *name, const struct gaih_service *service, + } + + struct gaih_addrtuple *addrfree = addrmem; ++ struct gaih_addrtuple **pat = &at; ++ + for (int i = 0; i < air->naddrs; ++i) + { + socklen_t size = (air->family[i] == AF_INET +@@ -712,12 +731,6 @@ gaih_inet (const char *name, const struct gaih_service *service, + + free (air); + +- if (at->family == AF_UNSPEC) +- { +- result = -EAI_NONAME; +- goto free_and_return; +- } +- + goto process_list; + } + else if (err == 0) +@@ -756,6 +769,22 @@ gaih_inet (const char *name, const struct gaih_service *service, + + while (!no_more) + { ++ /* Always start afresh; continue should discard previous results ++ and the hosts database does not support merge. */ ++ at = NULL; ++ free (canonbuf); ++ free (addrmem); ++ canon = canonbuf = NULL; ++ addrmem = NULL; ++ got_ipv6 = false; ++ ++ if (do_merge) ++ { ++ __set_h_errno (NETDB_INTERNAL); ++ __set_errno (EBUSY); ++ break; ++ } ++ + no_data = 0; + nss_gethostbyname4_r fct4 = NULL; + +@@ -768,12 +797,14 @@ gaih_inet (const char *name, const struct gaih_service *service, + { + while (1) + { +- status = DL_CALL_FCT (fct4, (name, pat, ++ status = DL_CALL_FCT (fct4, (name, &at, + tmpbuf->data, tmpbuf->length, + &errno, &h_errno, + NULL)); + if (status == NSS_STATUS_SUCCESS) + break; ++ /* gethostbyname4_r may write into AT, so reset it. */ ++ at = NULL; + if (status != NSS_STATUS_TRYAGAIN + || errno != ERANGE || h_errno != NETDB_INTERNAL) + { +@@ -800,7 +831,9 @@ gaih_inet (const char *name, const struct gaih_service *service, + no_data = 1; + + if ((req->ai_flags & AI_CANONNAME) != 0 && canon == NULL) +- canon = (*pat)->name; ++ canon = at->name; ++ ++ struct gaih_addrtuple **pat = &at; + + while (*pat != NULL) + { +@@ -852,6 +885,8 @@ gaih_inet (const char *name, const struct gaih_service *service, + + if (fct != NULL) + { ++ struct gaih_addrtuple **pat = &at; ++ + if (req->ai_family == AF_INET6 + || req->ai_family == AF_UNSPEC) + { +@@ -927,6 +962,10 @@ gaih_inet (const char *name, const struct gaih_service *service, + if (nss_next_action (nip, status) == NSS_ACTION_RETURN) + break; + ++ /* The hosts database does not support MERGE. */ ++ if (nss_next_action (nip, status) == NSS_ACTION_MERGE) ++ do_merge = true; ++ + if (nip->next == NULL) + no_more = -1; + else +@@ -960,7 +999,7 @@ gaih_inet (const char *name, const struct gaih_service *service, + } + + process_list: +- if (at->family == AF_UNSPEC) ++ if (at == NULL) + { + result = -EAI_NONAME; + goto free_and_return; diff --git a/glibc-RHEL-3035.patch b/glibc-RHEL-3035.patch new file mode 100644 index 0000000..c7f9f8f --- /dev/null +++ b/glibc-RHEL-3035.patch @@ -0,0 +1,157 @@ +This patch was developed under embargo and cannot reference an upstream +commit. To find the associated commit please review the upstream git +log for CVE-2023-4911 to identify the relevant commits. + +Author: Siddhesh Poyarekar +Date: Tue Sep 19 18:39:32 2023 -0400 + + tunables: Terminate if end of input is reached (CVE-2023-4911) + + The string parsing routine may end up writing beyond bounds of tunestr + if the input tunable string is malformed, of the form name=name=val. + This gets processed twice, first as name=name=val and next as name=val, + resulting in tunestr being name=name=val:name=val, thus overflowing + tunestr. + + Terminate the parsing loop at the first instance itself so that tunestr + does not overflow. + + This also fixes up tst-env-setuid-tunables to actually handle failures + correct and add new tests to validate the fix for this CVE. + + Signed-off-by: Siddhesh Poyarekar + Reviewed-by: Carlos O'Donell + +Conflicts: + NEWS + (Dropped) + elf/tst-env-setuid-tunables.c + (Trivial conflict at HAVE_TUNABLES) + +diff --git a/elf/dl-tunables.c b/elf/dl-tunables.c +index 3c84809d44381241..2c878e08ea197b29 100644 +--- a/elf/dl-tunables.c ++++ b/elf/dl-tunables.c +@@ -193,11 +193,7 @@ parse_tunables (char *tunestr, char *valstring) + /* If we reach the end of the string before getting a valid name-value + pair, bail out. */ + if (p[len] == '\0') +- { +- if (__libc_enable_secure) +- tunestr[off] = '\0'; +- return; +- } ++ break; + + /* We did not find a valid name-value pair before encountering the + colon. */ +@@ -257,9 +253,16 @@ parse_tunables (char *tunestr, char *valstring) + } + } + +- if (p[len] != '\0') +- p += len + 1; ++ /* We reached the end while processing the tunable string. */ ++ if (p[len] == '\0') ++ break; ++ ++ p += len + 1; + } ++ ++ /* Terminate tunestr before we leave. */ ++ if (__libc_enable_secure) ++ tunestr[off] = '\0'; + } + #endif + +diff --git a/elf/tst-env-setuid-tunables.c b/elf/tst-env-setuid-tunables.c +index 0b9b075c40598c6f..8b0861c4ad853040 100644 +--- a/elf/tst-env-setuid-tunables.c ++++ b/elf/tst-env-setuid-tunables.c +@@ -52,6 +52,8 @@ const char *teststrings[] = + "glibc.malloc.perturb=0x800:not_valid.malloc.check=2:glibc.malloc.mmap_threshold=4096", + "glibc.not_valid.check=2:glibc.malloc.mmap_threshold=4096", + "not_valid.malloc.check=2:glibc.malloc.mmap_threshold=4096", ++ "glibc.malloc.mmap_threshold=glibc.malloc.mmap_threshold=4096", ++ "glibc.malloc.check=2", + "glibc.malloc.garbage=2:glibc.maoc.mmap_threshold=4096:glibc.malloc.check=2", + "glibc.malloc.check=4:glibc.malloc.garbage=2:glibc.maoc.mmap_threshold=4096", + ":glibc.malloc.garbage=2:glibc.malloc.check=1", +@@ -70,6 +72,8 @@ const char *resultstrings[] = + "glibc.malloc.perturb=0x800:glibc.malloc.mmap_threshold=4096", + "glibc.malloc.mmap_threshold=4096", + "glibc.malloc.mmap_threshold=4096", ++ "glibc.malloc.mmap_threshold=glibc.malloc.mmap_threshold=4096", ++ "", + "", + "", + "", +@@ -84,11 +88,18 @@ test_child (int off) + const char *val = getenv ("GLIBC_TUNABLES"); + + #if HAVE_TUNABLES ++ printf (" [%d] GLIBC_TUNABLES is %s\n", off, val); ++ fflush (stdout); + if (val != NULL && strcmp (val, resultstrings[off]) == 0) + return 0; + + if (val != NULL) +- printf ("[%d] Unexpected GLIBC_TUNABLES VALUE %s\n", off, val); ++ printf (" [%d] Unexpected GLIBC_TUNABLES VALUE %s, expected %s\n", ++ off, val, resultstrings[off]); ++ else ++ printf (" [%d] GLIBC_TUNABLES environment variable absent\n", off); ++ ++ fflush (stdout); + + return 1; + #else +@@ -117,21 +128,26 @@ do_test (int argc, char **argv) + if (ret != 0) + exit (1); + +- exit (EXIT_SUCCESS); ++ /* Special return code to make sure that the child executed all the way ++ through. */ ++ exit (42); + } + else + { +- int ret = 0; +- + /* Spawn tests. */ + for (int i = 0; i < array_length (teststrings); i++) + { + char buf[INT_BUFSIZE_BOUND (int)]; + +- printf ("Spawned test for %s (%d)\n", teststrings[i], i); ++ printf ("[%d] Spawned test for %s\n", i, teststrings[i]); + snprintf (buf, sizeof (buf), "%d\n", i); ++ fflush (stdout); + if (setenv ("GLIBC_TUNABLES", teststrings[i], 1) != 0) +- exit (1); ++ { ++ printf (" [%d] Failed to set GLIBC_TUNABLES: %m", i); ++ support_record_failure (); ++ continue; ++ } + + int status = support_capture_subprogram_self_sgid (buf); + +@@ -139,9 +155,14 @@ do_test (int argc, char **argv) + if (WEXITSTATUS (status) == EXIT_UNSUPPORTED) + return EXIT_UNSUPPORTED; + +- ret |= status; ++ if (WEXITSTATUS (status) != 42) ++ { ++ printf (" [%d] child failed with status %d\n", i, ++ WEXITSTATUS (status)); ++ support_record_failure (); ++ } + } +- return ret; ++ return 0; + } + } + diff --git a/glibc-Support-target-specific-ALIGN-for-variable-alignment-4.patch b/glibc-Support-target-specific-ALIGN-for-variable-alignment-4.patch deleted file mode 100644 index d7552e1..0000000 --- a/glibc-Support-target-specific-ALIGN-for-variable-alignment-4.patch +++ /dev/null @@ -1,171 +0,0 @@ -From 2e86602d21fcaa8353c529f2f6768125396da39f Mon Sep 17 00:00:00 2001 -From: "H.J. Lu" -Date: Wed, 19 Jul 2023 23:12:30 +0800 -Subject: [PATCH 5/6] Support target specific ALIGN for variable alignment test - [BZ #28676] - -Add to support target specific ALIGN for variable -alignment test: - -1. Alpha: Use 0x10000. -2. MicroBlaze and Nios II: Use 0x8000. -3. All others: Use 0x200000. - -Backport from master commit: 4435c29 - -Reviewed-by: Adhemerval Zanella -Signed-off-by: Rongwei Wang ---- - elf/tst-align3.c | 4 +--- - elf/tst-alignmod3.c | 4 +--- - sysdeps/alpha/tst-file-align.h | 20 ++++++++++++++++++++ - sysdeps/generic/tst-file-align.h | 20 ++++++++++++++++++++ - sysdeps/microblaze/tst-file-align.h | 20 ++++++++++++++++++++ - sysdeps/nios2/tst-file-align.h | 20 ++++++++++++++++++++ - 6 files changed, 82 insertions(+), 6 deletions(-) - create mode 100644 sysdeps/alpha/tst-file-align.h - create mode 100644 sysdeps/generic/tst-file-align.h - create mode 100644 sysdeps/microblaze/tst-file-align.h - create mode 100644 sysdeps/nios2/tst-file-align.h - -diff --git a/elf/tst-align3.c b/elf/tst-align3.c -index ac86d623..87a8ff81 100644 ---- a/elf/tst-align3.c -+++ b/elf/tst-align3.c -@@ -17,11 +17,9 @@ - . */ - - #include -+#include - #include - --/* This should cover all possible page sizes we currently support. */ --#define ALIGN 0x200000 -- - int bar __attribute__ ((aligned (ALIGN))) = 1; - - extern int do_load_test (void); -diff --git a/elf/tst-alignmod3.c b/elf/tst-alignmod3.c -index 0d33f237..9520c352 100644 ---- a/elf/tst-alignmod3.c -+++ b/elf/tst-alignmod3.c -@@ -17,11 +17,9 @@ - . */ - - #include -+#include - #include - --/* This should cover all possible page sizes we currently support. */ --#define ALIGN 0x200000 -- - int foo __attribute__ ((aligned (ALIGN))) = 1; - - void -diff --git a/sysdeps/alpha/tst-file-align.h b/sysdeps/alpha/tst-file-align.h -new file mode 100644 -index 00000000..8fc3c940 ---- /dev/null -+++ b/sysdeps/alpha/tst-file-align.h -@@ -0,0 +1,20 @@ -+/* Check file alignment. Alpha version. -+ Copyright (C) 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 should cover all possible alignments we currently support. */ -+#define ALIGN 0x10000 -diff --git a/sysdeps/generic/tst-file-align.h b/sysdeps/generic/tst-file-align.h -new file mode 100644 -index 00000000..6ee6783a ---- /dev/null -+++ b/sysdeps/generic/tst-file-align.h -@@ -0,0 +1,20 @@ -+/* Check file alignment. Generic version. -+ Copyright (C) 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 should cover all possible page sizes we currently support. */ -+#define ALIGN 0x200000 -diff --git a/sysdeps/microblaze/tst-file-align.h b/sysdeps/microblaze/tst-file-align.h -new file mode 100644 -index 00000000..43c58b29 ---- /dev/null -+++ b/sysdeps/microblaze/tst-file-align.h -@@ -0,0 +1,20 @@ -+/* Check file alignment. MicroBlaze version. -+ Copyright (C) 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 should cover all possible alignments we currently support. */ -+#define ALIGN 0x8000 -diff --git a/sysdeps/nios2/tst-file-align.h b/sysdeps/nios2/tst-file-align.h -new file mode 100644 -index 00000000..589a2d5a ---- /dev/null -+++ b/sysdeps/nios2/tst-file-align.h -@@ -0,0 +1,20 @@ -+/* Check file alignment. Nios II version. -+ Copyright (C) 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 should cover all possible alignments we currently support. */ -+#define ALIGN 0x8000 --- -2.27.0 - diff --git a/glibc-Sync-to-lnd-35-for-LoongArch.patch b/glibc-Sync-to-lnd-35-for-LoongArch.patch deleted file mode 100644 index 6980fb1..0000000 --- a/glibc-Sync-to-lnd-35-for-LoongArch.patch +++ /dev/null @@ -1,26504 +0,0 @@ -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,27 @@ -+# Order of tunables in RHEL 8.7.0. -+@order glibc.rtld.nns -+@order glibc.elision.skip_lock_after_retries -+@order glibc.malloc.trim_threshold -+@order glibc.malloc.perturb -+@order glibc.elision.tries -+@order glibc.elision.enable -+@order glibc.malloc.mxfast -+@order glibc.elision.skip_lock_busy -+@order glibc.malloc.top_pad -+@order glibc.cpu.hwcaps -+@order glibc.cpu.hwcap_mask -+@order glibc.malloc.mmap_max -+@order glibc.elision.skip_trylock_internal_abort -+@order glibc.malloc.tcache_unsorted_limit -+@order glibc.elision.skip_lock_internal_abort -+@order glibc.malloc.arena_max -+@order glibc.malloc.mmap_threshold -+@order glibc.malloc.tcache_count -+@order glibc.malloc.arena_test -+@order glibc.rtld.optional_static_tls -+@order glibc.malloc.tcache_max -+@order glibc.malloc.check -+ -+# Tunables added in RHEL 8.8.0 -+@order glibc.rtld.dynamic_sort -+ -diff --git a/sysdeps/unix/sysv/linux/loongarch/getcontext.S b/sysdeps/unix/sysv/linux/loongarch/getcontext.S -new file mode 100644 -index 00000000..9c28d958 ---- /dev/null -+++ b/sysdeps/unix/sysv/linux/loongarch/getcontext.S -@@ -0,0 +1,72 @@ -+/* Save current context. -+ Copyright (C) 2009-2018 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library. If not, see -+ . */ -+ -+#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 - diff --git a/glibc-elf-Align-argument-of-__munmap-to-page-size-BZ-28676-3.patch b/glibc-elf-Align-argument-of-__munmap-to-page-size-BZ-28676-3.patch deleted file mode 100644 index 11417e6..0000000 --- a/glibc-elf-Align-argument-of-__munmap-to-page-size-BZ-28676-3.patch +++ /dev/null @@ -1,36 +0,0 @@ -From bf126f79dff0370d1e52ef8193da7fd593c37833 Mon Sep 17 00:00:00 2001 -From: "H.J. Lu" -Date: Wed, 19 Jul 2023 23:10:48 +0800 -Subject: [PATCH 4/6] elf: Align argument of __munmap to page size [BZ #28676] - -On Linux/x86-64, for elf/tst-align3, we now get - -munmap(0x7f88f9401000, 1126424) = 0 - -instead of - -munmap(0x7f1615200018, 544768) = -1 EINVAL (Invalid argument) - -Backport from master commit: fd6062e - -Reviewed-by: Florian Weimer -Signed-off-by: Rongwei Wang ---- - elf/dl-map-segments.h | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/elf/dl-map-segments.h b/elf/dl-map-segments.h -index 61ba04cd..f1f7ad88 100644 ---- a/elf/dl-map-segments.h -+++ b/elf/dl-map-segments.h -@@ -55,6 +55,7 @@ _dl_map_segment (const struct loadcmd *c, ElfW(Addr) mappref, - if (delta) - __munmap ((void *) map_start, delta); - ElfW(Addr) map_end = map_start_aligned + maplength; -+ map_end = ALIGN_UP (map_end, GLRO(dl_pagesize)); - delta = map_start + maplen - map_end; - if (delta) - __munmap ((void *) map_end, delta); --- -2.27.0 - diff --git a/glibc-elf-Fix-tst-align3.patch b/glibc-elf-Fix-tst-align3.patch deleted file mode 100644 index 194d142..0000000 --- a/glibc-elf-Fix-tst-align3.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 8b39d3b4bf2fc49ab31f31cf30aa80104afa3432 Mon Sep 17 00:00:00 2001 -From: Adhemerval Zanella -Date: Wed, 19 Jul 2023 23:14:33 +0800 -Subject: [PATCH 6/6] elf: Fix tst-align3 - -The elf/tst-align3.c declares the function using a wrong prototype. - -Checked on aarch64-linux-gnu. - -Signed-off-by: Rongwei Wang ---- - elf/tst-align3.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/elf/tst-align3.c b/elf/tst-align3.c -index 87a8ff81..731dd59f 100644 ---- a/elf/tst-align3.c -+++ b/elf/tst-align3.c -@@ -22,7 +22,7 @@ - - int bar __attribute__ ((aligned (ALIGN))) = 1; - --extern int do_load_test (void); -+extern void do_load_test (void); - - static int - do_test (void) -@@ -30,7 +30,8 @@ do_test (void) - printf ("bar: %p\n", &bar); - TEST_VERIFY (is_aligned (&bar, ALIGN) == 0); - -- return do_load_test (); -+ do_load_test (); -+ return 0; - } - - #include --- -2.27.0 - diff --git a/glibc-elf-Properly-align-PT_LOAD-segments-BZ-28676-1.patch b/glibc-elf-Properly-align-PT_LOAD-segments-BZ-28676-1.patch deleted file mode 100644 index a1b6c6b..0000000 --- a/glibc-elf-Properly-align-PT_LOAD-segments-BZ-28676-1.patch +++ /dev/null @@ -1,137 +0,0 @@ -From fe5893121176136b0ae3a5f9198536feeb6f64f8 Mon Sep 17 00:00:00 2001 -From: Rongwei Wang -Date: Wed, 19 Jul 2023 23:05:39 +0800 -Subject: [PATCH 2/6] elf: Properly align PT_LOAD segments [BZ #28676] - -When PT_LOAD segment alignment > the page size, allocate enough space to -ensure that the segment can be properly aligned. This change helps code -segments use huge pages become simple and available. - -This fixes [BZ #28676]. - -Backport from master commit: 718fdd8 - -Signed-off-by: Xu Yu -Signed-off-by: Rongwei Wang ---- - elf/dl-load.c | 2 ++ - elf/dl-load.h | 3 ++- - elf/dl-map-segments.h | 50 +++++++++++++++++++++++++++++++++++++++---- - 3 files changed, 50 insertions(+), 5 deletions(-) - -diff --git a/elf/dl-load.c b/elf/dl-load.c -index 0b45e6e3..132e4233 100644 ---- a/elf/dl-load.c -+++ b/elf/dl-load.c -@@ -1,5 +1,6 @@ - /* Map in a shared object's segments from the file. - Copyright (C) 1995-2018 Free Software Foundation, Inc. -+ Copyright The GNU Toolchain Authors. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or -@@ -1076,6 +1077,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, - c->mapend = ALIGN_UP (ph->p_vaddr + ph->p_filesz, GLRO(dl_pagesize)); - c->dataend = ph->p_vaddr + ph->p_filesz; - c->allocend = ph->p_vaddr + ph->p_memsz; -+ c->mapalign = ph->p_align; - c->mapoff = ALIGN_DOWN (ph->p_offset, GLRO(dl_pagesize)); - - /* Determine whether there is a gap between the last segment -diff --git a/elf/dl-load.h b/elf/dl-load.h -index 66ea2e92..d9f648ea 100644 ---- a/elf/dl-load.h -+++ b/elf/dl-load.h -@@ -1,5 +1,6 @@ - /* Map in a shared object's segments from the file. - Copyright (C) 1995-2018 Free Software Foundation, Inc. -+ Copyright The GNU Toolchain Authors. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or -@@ -74,7 +75,7 @@ ELF_PREFERRED_ADDRESS_DATA; - Its details have been expanded out and converted. */ - struct loadcmd - { -- ElfW(Addr) mapstart, mapend, dataend, allocend; -+ ElfW(Addr) mapstart, mapend, dataend, allocend, mapalign; - ElfW(Off) mapoff; - int prot; /* PROT_* bits. */ - }; -diff --git a/elf/dl-map-segments.h b/elf/dl-map-segments.h -index 084076a2..61ba04cd 100644 ---- a/elf/dl-map-segments.h -+++ b/elf/dl-map-segments.h -@@ -1,5 +1,6 @@ - /* Map in a shared object's segments. Generic version. - Copyright (C) 1995-2018 Free Software Foundation, Inc. -+ Copyright The GNU Toolchain Authors. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or -@@ -18,6 +19,50 @@ - - #include - -+/* Map a segment and align it properly. */ -+ -+static __always_inline ElfW(Addr) -+_dl_map_segment (const struct loadcmd *c, ElfW(Addr) mappref, -+ const size_t maplength, int fd) -+{ -+ if (__glibc_likely (c->mapalign <= GLRO(dl_pagesize))) -+ return (ElfW(Addr)) __mmap ((void *) mappref, maplength, c->prot, -+ MAP_COPY|MAP_FILE, fd, c->mapoff); -+ -+ /* If the segment alignment > the page size, allocate enough space to -+ ensure that the segment can be properly aligned. */ -+ ElfW(Addr) maplen = (maplength >= c->mapalign -+ ? (maplength + c->mapalign) -+ : (2 * c->mapalign)); -+ ElfW(Addr) map_start = (ElfW(Addr)) __mmap ((void *) mappref, maplen, -+ PROT_NONE, -+ MAP_ANONYMOUS|MAP_PRIVATE, -+ -1, 0); -+ if (__glibc_unlikely ((void *) map_start == MAP_FAILED)) -+ return map_start; -+ -+ ElfW(Addr) map_start_aligned = ALIGN_UP (map_start, c->mapalign); -+ map_start_aligned = (ElfW(Addr)) __mmap ((void *) map_start_aligned, -+ maplength, c->prot, -+ MAP_COPY|MAP_FILE|MAP_FIXED, -+ fd, c->mapoff); -+ if (__glibc_unlikely ((void *) map_start_aligned == MAP_FAILED)) -+ __munmap ((void *) map_start, maplen); -+ else -+ { -+ /* Unmap the unused regions. */ -+ ElfW(Addr) delta = map_start_aligned - map_start; -+ if (delta) -+ __munmap ((void *) map_start, delta); -+ ElfW(Addr) map_end = map_start_aligned + maplength; -+ delta = map_start + maplen - map_end; -+ if (delta) -+ __munmap ((void *) map_end, delta); -+ } -+ -+ return map_start_aligned; -+} -+ - /* This implementation assumes (as does the corresponding implementation - of _dl_unmap_segments, in dl-unmap-segments.h) that shared objects - are always laid out with all segments contiguous (or with gaps -@@ -53,10 +98,7 @@ _dl_map_segments (struct link_map *l, int fd, - - MAP_BASE_ADDR (l)); - - /* Remember which part of the address space this object uses. */ -- l->l_map_start = (ElfW(Addr)) __mmap ((void *) mappref, maplength, -- c->prot, -- MAP_COPY|MAP_FILE, -- fd, c->mapoff); -+ l->l_map_start = _dl_map_segment (c, mappref, maplength, fd); - if (__glibc_unlikely ((void *) l->l_map_start == MAP_FAILED)) - return DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT; - --- -2.27.0 - diff --git a/glibc-gb18030-2022-bug30243.patch b/glibc-gb18030-2022-bug30243.patch deleted file mode 100644 index 8e87f34..0000000 --- a/glibc-gb18030-2022-bug30243.patch +++ /dev/null @@ -1,797 +0,0 @@ -diff --git a/iconvdata/gb18030.c b/iconvdata/gb18030.c -index 0b03b9bb..ca383dc0 100644 ---- a/iconvdata/gb18030.c -+++ b/iconvdata/gb18030.c -@@ -6020,49 +6020,50 @@ static const uint16_t __twobyte_to_ucs[] = - [0x5dc2] = 0xfa0e, [0x5dc3] = 0xfa0f, [0x5dc4] = 0xfa11, [0x5dc5] = 0xfa13, - [0x5dc6] = 0xfa14, [0x5dc7] = 0xfa18, [0x5dc8] = 0xfa1f, [0x5dc9] = 0xfa20, - [0x5dca] = 0xfa21, [0x5dcb] = 0xfa23, [0x5dcc] = 0xfa24, [0x5dcd] = 0xfa27, -- [0x5dce] = 0xfa28, [0x5dcf] = 0xfa29, [0x5dd0] = 0x2e81, [0x5dd4] = 0x2e84, -- [0x5dd5] = 0x3473, [0x5dd6] = 0x3447, [0x5dd7] = 0x2e88, [0x5dd8] = 0x2e8b, -- [0x5dd9] = 0x9fb4, [0x5dda] = 0x359e, [0x5ddb] = 0x361a, [0x5ddc] = 0x360e, -- [0x5ddd] = 0x2e8c, [0x5dde] = 0x2e97, [0x5ddf] = 0x396e, [0x5de0] = 0x3918, -- [0x5de1] = 0x9fb5, [0x5de2] = 0x39cf, [0x5de3] = 0x39df, [0x5de4] = 0x3a73, -- [0x5de5] = 0x39d0, [0x5de6] = 0x9fb6, [0x5de7] = 0x9fb7, [0x5de8] = 0x3b4e, -- [0x5de9] = 0x3c6e, [0x5dea] = 0x3ce0, [0x5deb] = 0x2ea7, [0x5ded] = 0x9fb8, -+ [0x5dce] = 0xfa28, [0x5dcf] = 0xfa29, [0x5dd0] = 0x2e81, [0x5dd1] = 0xe816, -+ [0x5dd2] = 0xe817, [0x5dd3] = 0xe818, [0x5dd4] = 0x2e84, [0x5dd5] = 0x3473, -+ [0x5dd6] = 0x3447, [0x5dd7] = 0x2e88, [0x5dd8] = 0x2e8b, [0x5dd9] = 0x9fb4, -+ [0x5dda] = 0x359e, [0x5ddb] = 0x361a, [0x5ddc] = 0x360e, [0x5ddd] = 0x2e8c, -+ [0x5dde] = 0x2e97, [0x5ddf] = 0x396e, [0x5de0] = 0x3918, [0x5de1] = 0x9fb5, -+ [0x5de2] = 0x39cf, [0x5de3] = 0x39df, [0x5de4] = 0x3a73, [0x5de5] = 0x39d0, -+ [0x5de6] = 0x9fb6, [0x5de7] = 0x9fb7, [0x5de8] = 0x3b4e, [0x5de9] = 0x3c6e, -+ [0x5dea] = 0x3ce0, [0x5deb] = 0x2ea7, [0x5dec] = 0xe831, [0x5ded] = 0x9fb8, - [0x5dee] = 0x2eaa, [0x5def] = 0x4056, [0x5df0] = 0x415f, [0x5df1] = 0x2eae, - [0x5df2] = 0x4337, [0x5df3] = 0x2eb3, [0x5df4] = 0x2eb6, [0x5df5] = 0x2eb7, -- [0x5df7] = 0x43b1, [0x5df8] = 0x43ac, [0x5df9] = 0x2ebb, [0x5dfa] = 0x43dd, -- [0x5dfb] = 0x44d6, [0x5dfc] = 0x4661, [0x5dfd] = 0x464c, [0x5dfe] = 0x9fb9, -- [0x5e00] = 0x4723, [0x5e01] = 0x4729, [0x5e02] = 0x477c, [0x5e03] = 0x478d, -- [0x5e04] = 0x2eca, [0x5e05] = 0x4947, [0x5e06] = 0x497a, [0x5e07] = 0x497d, -- [0x5e08] = 0x4982, [0x5e09] = 0x4983, [0x5e0a] = 0x4985, [0x5e0b] = 0x4986, -- [0x5e0c] = 0x499f, [0x5e0d] = 0x499b, [0x5e0e] = 0x49b7, [0x5e0f] = 0x49b6, -- [0x5e10] = 0x9fba, [0x5e12] = 0x4ca3, [0x5e13] = 0x4c9f, [0x5e14] = 0x4ca0, -- [0x5e15] = 0x4ca1, [0x5e16] = 0x4c77, [0x5e17] = 0x4ca2, [0x5e18] = 0x4d13, -- [0x5e19] = 0x4d14, [0x5e1a] = 0x4d15, [0x5e1b] = 0x4d16, [0x5e1c] = 0x4d17, -- [0x5e1d] = 0x4d18, [0x5e1e] = 0x4d19, [0x5e1f] = 0x4dae, [0x5e20] = 0x9fbb, -- [0x5e21] = 0xe468, [0x5e22] = 0xe469, [0x5e23] = 0xe46a, [0x5e24] = 0xe46b, -- [0x5e25] = 0xe46c, [0x5e26] = 0xe46d, [0x5e27] = 0xe46e, [0x5e28] = 0xe46f, -- [0x5e29] = 0xe470, [0x5e2a] = 0xe471, [0x5e2b] = 0xe472, [0x5e2c] = 0xe473, -- [0x5e2d] = 0xe474, [0x5e2e] = 0xe475, [0x5e2f] = 0xe476, [0x5e30] = 0xe477, -- [0x5e31] = 0xe478, [0x5e32] = 0xe479, [0x5e33] = 0xe47a, [0x5e34] = 0xe47b, -- [0x5e35] = 0xe47c, [0x5e36] = 0xe47d, [0x5e37] = 0xe47e, [0x5e38] = 0xe47f, -- [0x5e39] = 0xe480, [0x5e3a] = 0xe481, [0x5e3b] = 0xe482, [0x5e3c] = 0xe483, -- [0x5e3d] = 0xe484, [0x5e3e] = 0xe485, [0x5e3f] = 0xe486, [0x5e40] = 0xe487, -- [0x5e41] = 0xe488, [0x5e42] = 0xe489, [0x5e43] = 0xe48a, [0x5e44] = 0xe48b, -- [0x5e45] = 0xe48c, [0x5e46] = 0xe48d, [0x5e47] = 0xe48e, [0x5e48] = 0xe48f, -- [0x5e49] = 0xe490, [0x5e4a] = 0xe491, [0x5e4b] = 0xe492, [0x5e4c] = 0xe493, -- [0x5e4d] = 0xe494, [0x5e4e] = 0xe495, [0x5e4f] = 0xe496, [0x5e50] = 0xe497, -- [0x5e51] = 0xe498, [0x5e52] = 0xe499, [0x5e53] = 0xe49a, [0x5e54] = 0xe49b, -- [0x5e55] = 0xe49c, [0x5e56] = 0xe49d, [0x5e57] = 0xe49e, [0x5e58] = 0xe49f, -- [0x5e59] = 0xe4a0, [0x5e5a] = 0xe4a1, [0x5e5b] = 0xe4a2, [0x5e5c] = 0xe4a3, -- [0x5e5d] = 0xe4a4, [0x5e5e] = 0xe4a5, [0x5e5f] = 0xe4a6, [0x5e60] = 0xe4a7, -- [0x5e61] = 0xe4a8, [0x5e62] = 0xe4a9, [0x5e63] = 0xe4aa, [0x5e64] = 0xe4ab, -- [0x5e65] = 0xe4ac, [0x5e66] = 0xe4ad, [0x5e67] = 0xe4ae, [0x5e68] = 0xe4af, -- [0x5e69] = 0xe4b0, [0x5e6a] = 0xe4b1, [0x5e6b] = 0xe4b2, [0x5e6c] = 0xe4b3, -- [0x5e6d] = 0xe4b4, [0x5e6e] = 0xe4b5, [0x5e6f] = 0xe4b6, [0x5e70] = 0xe4b7, -- [0x5e71] = 0xe4b8, [0x5e72] = 0xe4b9, [0x5e73] = 0xe4ba, [0x5e74] = 0xe4bb, -- [0x5e75] = 0xe4bc, [0x5e76] = 0xe4bd, [0x5e77] = 0xe4be, [0x5e78] = 0xe4bf, -- [0x5e79] = 0xe4c0, [0x5e7a] = 0xe4c1, [0x5e7b] = 0xe4c2, [0x5e7c] = 0xe4c3, -- [0x5e7d] = 0xe4c4, [0x5e7e] = 0xe4c5, -+ [0x5df6] = 0xe83b, [0x5df7] = 0x43b1, [0x5df8] = 0x43ac, [0x5df9] = 0x2ebb, -+ [0x5dfa] = 0x43dd, [0x5dfb] = 0x44d6, [0x5dfc] = 0x4661, [0x5dfd] = 0x464c, -+ [0x5dfe] = 0x9fb9, [0x5e00] = 0x4723, [0x5e01] = 0x4729, [0x5e02] = 0x477c, -+ [0x5e03] = 0x478d, [0x5e04] = 0x2eca, [0x5e05] = 0x4947, [0x5e06] = 0x497a, -+ [0x5e07] = 0x497d, [0x5e08] = 0x4982, [0x5e09] = 0x4983, [0x5e0a] = 0x4985, -+ [0x5e0b] = 0x4986, [0x5e0c] = 0x499f, [0x5e0d] = 0x499b, [0x5e0e] = 0x49b7, -+ [0x5e0f] = 0x49b6, [0x5e10] = 0x9fba, [0x5e11] = 0xe855, [0x5e12] = 0x4ca3, -+ [0x5e13] = 0x4c9f, [0x5e14] = 0x4ca0, [0x5e15] = 0x4ca1, [0x5e16] = 0x4c77, -+ [0x5e17] = 0x4ca2, [0x5e18] = 0x4d13, [0x5e19] = 0x4d14, [0x5e1a] = 0x4d15, -+ [0x5e1b] = 0x4d16, [0x5e1c] = 0x4d17, [0x5e1d] = 0x4d18, [0x5e1e] = 0x4d19, -+ [0x5e1f] = 0x4dae, [0x5e20] = 0x9fbb, [0x5e21] = 0xe468, [0x5e22] = 0xe469, -+ [0x5e23] = 0xe46a, [0x5e24] = 0xe46b, [0x5e25] = 0xe46c, [0x5e26] = 0xe46d, -+ [0x5e27] = 0xe46e, [0x5e28] = 0xe46f, [0x5e29] = 0xe470, [0x5e2a] = 0xe471, -+ [0x5e2b] = 0xe472, [0x5e2c] = 0xe473, [0x5e2d] = 0xe474, [0x5e2e] = 0xe475, -+ [0x5e2f] = 0xe476, [0x5e30] = 0xe477, [0x5e31] = 0xe478, [0x5e32] = 0xe479, -+ [0x5e33] = 0xe47a, [0x5e34] = 0xe47b, [0x5e35] = 0xe47c, [0x5e36] = 0xe47d, -+ [0x5e37] = 0xe47e, [0x5e38] = 0xe47f, [0x5e39] = 0xe480, [0x5e3a] = 0xe481, -+ [0x5e3b] = 0xe482, [0x5e3c] = 0xe483, [0x5e3d] = 0xe484, [0x5e3e] = 0xe485, -+ [0x5e3f] = 0xe486, [0x5e40] = 0xe487, [0x5e41] = 0xe488, [0x5e42] = 0xe489, -+ [0x5e43] = 0xe48a, [0x5e44] = 0xe48b, [0x5e45] = 0xe48c, [0x5e46] = 0xe48d, -+ [0x5e47] = 0xe48e, [0x5e48] = 0xe48f, [0x5e49] = 0xe490, [0x5e4a] = 0xe491, -+ [0x5e4b] = 0xe492, [0x5e4c] = 0xe493, [0x5e4d] = 0xe494, [0x5e4e] = 0xe495, -+ [0x5e4f] = 0xe496, [0x5e50] = 0xe497, [0x5e51] = 0xe498, [0x5e52] = 0xe499, -+ [0x5e53] = 0xe49a, [0x5e54] = 0xe49b, [0x5e55] = 0xe49c, [0x5e56] = 0xe49d, -+ [0x5e57] = 0xe49e, [0x5e58] = 0xe49f, [0x5e59] = 0xe4a0, [0x5e5a] = 0xe4a1, -+ [0x5e5b] = 0xe4a2, [0x5e5c] = 0xe4a3, [0x5e5d] = 0xe4a4, [0x5e5e] = 0xe4a5, -+ [0x5e5f] = 0xe4a6, [0x5e60] = 0xe4a7, [0x5e61] = 0xe4a8, [0x5e62] = 0xe4a9, -+ [0x5e63] = 0xe4aa, [0x5e64] = 0xe4ab, [0x5e65] = 0xe4ac, [0x5e66] = 0xe4ad, -+ [0x5e67] = 0xe4ae, [0x5e68] = 0xe4af, [0x5e69] = 0xe4b0, [0x5e6a] = 0xe4b1, -+ [0x5e6b] = 0xe4b2, [0x5e6c] = 0xe4b3, [0x5e6d] = 0xe4b4, [0x5e6e] = 0xe4b5, -+ [0x5e6f] = 0xe4b6, [0x5e70] = 0xe4b7, [0x5e71] = 0xe4b8, [0x5e72] = 0xe4b9, -+ [0x5e73] = 0xe4ba, [0x5e74] = 0xe4bb, [0x5e75] = 0xe4bc, [0x5e76] = 0xe4bd, -+ [0x5e77] = 0xe4be, [0x5e78] = 0xe4bf, [0x5e79] = 0xe4c0, [0x5e7a] = 0xe4c1, -+ [0x5e7b] = 0xe4c2, [0x5e7c] = 0xe4c3, [0x5e7d] = 0xe4c4, [0x5e7e] = 0xe4c5, - }; - - /* Table for GB18030 -> UCS-4, containing the four-byte characters only, -@@ -8691,7 +8692,9 @@ static const uint16_t __fourbyte_to_ucs[0x99e2 - 6637 - 2110 - 14404 - 4295] = - [0x2838] = 0x9fa6, [0x2839] = 0x9fa7, [0x283a] = 0x9fa8, [0x283b] = 0x9fa9, - [0x283c] = 0x9faa, [0x283d] = 0x9fab, [0x283e] = 0x9fac, [0x283f] = 0x9fad, - [0x2840] = 0x9fae, [0x2841] = 0x9faf, [0x2842] = 0x9fb0, [0x2843] = 0x9fb1, -- [0x2844] = 0x9fb2, [0x2845] = 0x9fb3, [0x284e] = 0xe76c, [0x284f] = 0xe7c8, -+ [0x2844] = 0x9fb2, [0x2845] = 0x9fb3, [0x2846] = 0xe81e, [0x2847] = 0xe826, -+ [0x2848] = 0xe82b, [0x2849] = 0xe82c, [0x284a] = 0xe832, [0x284b] = 0xe843, -+ [0x284c] = 0xe854, [0x284d] = 0xe864, [0x284e] = 0xe76c, [0x284f] = 0xe7c8, - [0x2850] = 0xe7e7, [0x2851] = 0xe7e8, [0x2852] = 0xe7e9, [0x2853] = 0xe7ea, - [0x2854] = 0xe7eb, [0x2855] = 0xe7ec, [0x2856] = 0xe7ed, [0x2857] = 0xe7ee, - [0x2858] = 0xe7ef, [0x2859] = 0xe7f0, [0x285a] = 0xe7f1, [0x285b] = 0xe7f2, -@@ -9019,84 +9022,86 @@ static const uint16_t __fourbyte_to_ucs[0x99e2 - 6637 - 2110 - 14404 - 4295] = - [0x2d60] = 0xfe02, [0x2d61] = 0xfe03, [0x2d62] = 0xfe04, [0x2d63] = 0xfe05, - [0x2d64] = 0xfe06, [0x2d65] = 0xfe07, [0x2d66] = 0xfe08, [0x2d67] = 0xfe09, - [0x2d68] = 0xfe0a, [0x2d69] = 0xfe0b, [0x2d6a] = 0xfe0c, [0x2d6b] = 0xfe0d, -- [0x2d6c] = 0xfe0e, [0x2d6d] = 0xfe0f, [0x2d78] = 0xfe1a, [0x2d79] = 0xfe1b, -- [0x2d7a] = 0xfe1c, [0x2d7b] = 0xfe1d, [0x2d7c] = 0xfe1e, [0x2d7d] = 0xfe1f, -- [0x2d7e] = 0xfe20, [0x2d7f] = 0xfe21, [0x2d80] = 0xfe22, [0x2d81] = 0xfe23, -- [0x2d82] = 0xfe24, [0x2d83] = 0xfe25, [0x2d84] = 0xfe26, [0x2d85] = 0xfe27, -- [0x2d86] = 0xfe28, [0x2d87] = 0xfe29, [0x2d88] = 0xfe2a, [0x2d89] = 0xfe2b, -- [0x2d8a] = 0xfe2c, [0x2d8b] = 0xfe2d, [0x2d8c] = 0xfe2e, [0x2d8d] = 0xfe2f, -- [0x2d8e] = 0xfe32, [0x2d8f] = 0xfe45, [0x2d90] = 0xfe46, [0x2d91] = 0xfe47, -- [0x2d92] = 0xfe48, [0x2d93] = 0xfe53, [0x2d94] = 0xfe58, [0x2d95] = 0xfe67, -- [0x2d96] = 0xfe6c, [0x2d97] = 0xfe6d, [0x2d98] = 0xfe6e, [0x2d99] = 0xfe6f, -- [0x2d9a] = 0xfe70, [0x2d9b] = 0xfe71, [0x2d9c] = 0xfe72, [0x2d9d] = 0xfe73, -- [0x2d9e] = 0xfe74, [0x2d9f] = 0xfe75, [0x2da0] = 0xfe76, [0x2da1] = 0xfe77, -- [0x2da2] = 0xfe78, [0x2da3] = 0xfe79, [0x2da4] = 0xfe7a, [0x2da5] = 0xfe7b, -- [0x2da6] = 0xfe7c, [0x2da7] = 0xfe7d, [0x2da8] = 0xfe7e, [0x2da9] = 0xfe7f, -- [0x2daa] = 0xfe80, [0x2dab] = 0xfe81, [0x2dac] = 0xfe82, [0x2dad] = 0xfe83, -- [0x2dae] = 0xfe84, [0x2daf] = 0xfe85, [0x2db0] = 0xfe86, [0x2db1] = 0xfe87, -- [0x2db2] = 0xfe88, [0x2db3] = 0xfe89, [0x2db4] = 0xfe8a, [0x2db5] = 0xfe8b, -- [0x2db6] = 0xfe8c, [0x2db7] = 0xfe8d, [0x2db8] = 0xfe8e, [0x2db9] = 0xfe8f, -- [0x2dba] = 0xfe90, [0x2dbb] = 0xfe91, [0x2dbc] = 0xfe92, [0x2dbd] = 0xfe93, -- [0x2dbe] = 0xfe94, [0x2dbf] = 0xfe95, [0x2dc0] = 0xfe96, [0x2dc1] = 0xfe97, -- [0x2dc2] = 0xfe98, [0x2dc3] = 0xfe99, [0x2dc4] = 0xfe9a, [0x2dc5] = 0xfe9b, -- [0x2dc6] = 0xfe9c, [0x2dc7] = 0xfe9d, [0x2dc8] = 0xfe9e, [0x2dc9] = 0xfe9f, -- [0x2dca] = 0xfea0, [0x2dcb] = 0xfea1, [0x2dcc] = 0xfea2, [0x2dcd] = 0xfea3, -- [0x2dce] = 0xfea4, [0x2dcf] = 0xfea5, [0x2dd0] = 0xfea6, [0x2dd1] = 0xfea7, -- [0x2dd2] = 0xfea8, [0x2dd3] = 0xfea9, [0x2dd4] = 0xfeaa, [0x2dd5] = 0xfeab, -- [0x2dd6] = 0xfeac, [0x2dd7] = 0xfead, [0x2dd8] = 0xfeae, [0x2dd9] = 0xfeaf, -- [0x2dda] = 0xfeb0, [0x2ddb] = 0xfeb1, [0x2ddc] = 0xfeb2, [0x2ddd] = 0xfeb3, -- [0x2dde] = 0xfeb4, [0x2ddf] = 0xfeb5, [0x2de0] = 0xfeb6, [0x2de1] = 0xfeb7, -- [0x2de2] = 0xfeb8, [0x2de3] = 0xfeb9, [0x2de4] = 0xfeba, [0x2de5] = 0xfebb, -- [0x2de6] = 0xfebc, [0x2de7] = 0xfebd, [0x2de8] = 0xfebe, [0x2de9] = 0xfebf, -- [0x2dea] = 0xfec0, [0x2deb] = 0xfec1, [0x2dec] = 0xfec2, [0x2ded] = 0xfec3, -- [0x2dee] = 0xfec4, [0x2def] = 0xfec5, [0x2df0] = 0xfec6, [0x2df1] = 0xfec7, -- [0x2df2] = 0xfec8, [0x2df3] = 0xfec9, [0x2df4] = 0xfeca, [0x2df5] = 0xfecb, -- [0x2df6] = 0xfecc, [0x2df7] = 0xfecd, [0x2df8] = 0xfece, [0x2df9] = 0xfecf, -- [0x2dfa] = 0xfed0, [0x2dfb] = 0xfed1, [0x2dfc] = 0xfed2, [0x2dfd] = 0xfed3, -- [0x2dfe] = 0xfed4, [0x2dff] = 0xfed5, [0x2e00] = 0xfed6, [0x2e01] = 0xfed7, -- [0x2e02] = 0xfed8, [0x2e03] = 0xfed9, [0x2e04] = 0xfeda, [0x2e05] = 0xfedb, -- [0x2e06] = 0xfedc, [0x2e07] = 0xfedd, [0x2e08] = 0xfede, [0x2e09] = 0xfedf, -- [0x2e0a] = 0xfee0, [0x2e0b] = 0xfee1, [0x2e0c] = 0xfee2, [0x2e0d] = 0xfee3, -- [0x2e0e] = 0xfee4, [0x2e0f] = 0xfee5, [0x2e10] = 0xfee6, [0x2e11] = 0xfee7, -- [0x2e12] = 0xfee8, [0x2e13] = 0xfee9, [0x2e14] = 0xfeea, [0x2e15] = 0xfeeb, -- [0x2e16] = 0xfeec, [0x2e17] = 0xfeed, [0x2e18] = 0xfeee, [0x2e19] = 0xfeef, -- [0x2e1a] = 0xfef0, [0x2e1b] = 0xfef1, [0x2e1c] = 0xfef2, [0x2e1d] = 0xfef3, -- [0x2e1e] = 0xfef4, [0x2e1f] = 0xfef5, [0x2e20] = 0xfef6, [0x2e21] = 0xfef7, -- [0x2e22] = 0xfef8, [0x2e23] = 0xfef9, [0x2e24] = 0xfefa, [0x2e25] = 0xfefb, -- [0x2e26] = 0xfefc, [0x2e27] = 0xfefd, [0x2e28] = 0xfefe, [0x2e29] = 0xfeff, -- [0x2e2a] = 0xff00, [0x2e2b] = 0xff5f, [0x2e2c] = 0xff60, [0x2e2d] = 0xff61, -- [0x2e2e] = 0xff62, [0x2e2f] = 0xff63, [0x2e30] = 0xff64, [0x2e31] = 0xff65, -- [0x2e32] = 0xff66, [0x2e33] = 0xff67, [0x2e34] = 0xff68, [0x2e35] = 0xff69, -- [0x2e36] = 0xff6a, [0x2e37] = 0xff6b, [0x2e38] = 0xff6c, [0x2e39] = 0xff6d, -- [0x2e3a] = 0xff6e, [0x2e3b] = 0xff6f, [0x2e3c] = 0xff70, [0x2e3d] = 0xff71, -- [0x2e3e] = 0xff72, [0x2e3f] = 0xff73, [0x2e40] = 0xff74, [0x2e41] = 0xff75, -- [0x2e42] = 0xff76, [0x2e43] = 0xff77, [0x2e44] = 0xff78, [0x2e45] = 0xff79, -- [0x2e46] = 0xff7a, [0x2e47] = 0xff7b, [0x2e48] = 0xff7c, [0x2e49] = 0xff7d, -- [0x2e4a] = 0xff7e, [0x2e4b] = 0xff7f, [0x2e4c] = 0xff80, [0x2e4d] = 0xff81, -- [0x2e4e] = 0xff82, [0x2e4f] = 0xff83, [0x2e50] = 0xff84, [0x2e51] = 0xff85, -- [0x2e52] = 0xff86, [0x2e53] = 0xff87, [0x2e54] = 0xff88, [0x2e55] = 0xff89, -- [0x2e56] = 0xff8a, [0x2e57] = 0xff8b, [0x2e58] = 0xff8c, [0x2e59] = 0xff8d, -- [0x2e5a] = 0xff8e, [0x2e5b] = 0xff8f, [0x2e5c] = 0xff90, [0x2e5d] = 0xff91, -- [0x2e5e] = 0xff92, [0x2e5f] = 0xff93, [0x2e60] = 0xff94, [0x2e61] = 0xff95, -- [0x2e62] = 0xff96, [0x2e63] = 0xff97, [0x2e64] = 0xff98, [0x2e65] = 0xff99, -- [0x2e66] = 0xff9a, [0x2e67] = 0xff9b, [0x2e68] = 0xff9c, [0x2e69] = 0xff9d, -- [0x2e6a] = 0xff9e, [0x2e6b] = 0xff9f, [0x2e6c] = 0xffa0, [0x2e6d] = 0xffa1, -- [0x2e6e] = 0xffa2, [0x2e6f] = 0xffa3, [0x2e70] = 0xffa4, [0x2e71] = 0xffa5, -- [0x2e72] = 0xffa6, [0x2e73] = 0xffa7, [0x2e74] = 0xffa8, [0x2e75] = 0xffa9, -- [0x2e76] = 0xffaa, [0x2e77] = 0xffab, [0x2e78] = 0xffac, [0x2e79] = 0xffad, -- [0x2e7a] = 0xffae, [0x2e7b] = 0xffaf, [0x2e7c] = 0xffb0, [0x2e7d] = 0xffb1, -- [0x2e7e] = 0xffb2, [0x2e7f] = 0xffb3, [0x2e80] = 0xffb4, [0x2e81] = 0xffb5, -- [0x2e82] = 0xffb6, [0x2e83] = 0xffb7, [0x2e84] = 0xffb8, [0x2e85] = 0xffb9, -- [0x2e86] = 0xffba, [0x2e87] = 0xffbb, [0x2e88] = 0xffbc, [0x2e89] = 0xffbd, -- [0x2e8a] = 0xffbe, [0x2e8b] = 0xffbf, [0x2e8c] = 0xffc0, [0x2e8d] = 0xffc1, -- [0x2e8e] = 0xffc2, [0x2e8f] = 0xffc3, [0x2e90] = 0xffc4, [0x2e91] = 0xffc5, -- [0x2e92] = 0xffc6, [0x2e93] = 0xffc7, [0x2e94] = 0xffc8, [0x2e95] = 0xffc9, -- [0x2e96] = 0xffca, [0x2e97] = 0xffcb, [0x2e98] = 0xffcc, [0x2e99] = 0xffcd, -- [0x2e9a] = 0xffce, [0x2e9b] = 0xffcf, [0x2e9c] = 0xffd0, [0x2e9d] = 0xffd1, -- [0x2e9e] = 0xffd2, [0x2e9f] = 0xffd3, [0x2ea0] = 0xffd4, [0x2ea1] = 0xffd5, -- [0x2ea2] = 0xffd6, [0x2ea3] = 0xffd7, [0x2ea4] = 0xffd8, [0x2ea5] = 0xffd9, -- [0x2ea6] = 0xffda, [0x2ea7] = 0xffdb, [0x2ea8] = 0xffdc, [0x2ea9] = 0xffdd, -- [0x2eaa] = 0xffde, [0x2eab] = 0xffdf, -+ [0x2d6c] = 0xfe0e, [0x2d6d] = 0xfe0f, [0x2d6e] = 0xe78d, [0x2d6f] = 0xe78f, -+ [0x2d70] = 0xe78e, [0x2d71] = 0xe790, [0x2d72] = 0xe791, [0x2d73] = 0xe792, -+ [0x2d74] = 0xe793, [0x2d75] = 0xe794, [0x2d76] = 0xe795, [0x2d77] = 0xe796, -+ [0x2d78] = 0xfe1a, [0x2d79] = 0xfe1b, [0x2d7a] = 0xfe1c, [0x2d7b] = 0xfe1d, -+ [0x2d7c] = 0xfe1e, [0x2d7d] = 0xfe1f, [0x2d7e] = 0xfe20, [0x2d7f] = 0xfe21, -+ [0x2d80] = 0xfe22, [0x2d81] = 0xfe23, [0x2d82] = 0xfe24, [0x2d83] = 0xfe25, -+ [0x2d84] = 0xfe26, [0x2d85] = 0xfe27, [0x2d86] = 0xfe28, [0x2d87] = 0xfe29, -+ [0x2d88] = 0xfe2a, [0x2d89] = 0xfe2b, [0x2d8a] = 0xfe2c, [0x2d8b] = 0xfe2d, -+ [0x2d8c] = 0xfe2e, [0x2d8d] = 0xfe2f, [0x2d8e] = 0xfe32, [0x2d8f] = 0xfe45, -+ [0x2d90] = 0xfe46, [0x2d91] = 0xfe47, [0x2d92] = 0xfe48, [0x2d93] = 0xfe53, -+ [0x2d94] = 0xfe58, [0x2d95] = 0xfe67, [0x2d96] = 0xfe6c, [0x2d97] = 0xfe6d, -+ [0x2d98] = 0xfe6e, [0x2d99] = 0xfe6f, [0x2d9a] = 0xfe70, [0x2d9b] = 0xfe71, -+ [0x2d9c] = 0xfe72, [0x2d9d] = 0xfe73, [0x2d9e] = 0xfe74, [0x2d9f] = 0xfe75, -+ [0x2da0] = 0xfe76, [0x2da1] = 0xfe77, [0x2da2] = 0xfe78, [0x2da3] = 0xfe79, -+ [0x2da4] = 0xfe7a, [0x2da5] = 0xfe7b, [0x2da6] = 0xfe7c, [0x2da7] = 0xfe7d, -+ [0x2da8] = 0xfe7e, [0x2da9] = 0xfe7f, [0x2daa] = 0xfe80, [0x2dab] = 0xfe81, -+ [0x2dac] = 0xfe82, [0x2dad] = 0xfe83, [0x2dae] = 0xfe84, [0x2daf] = 0xfe85, -+ [0x2db0] = 0xfe86, [0x2db1] = 0xfe87, [0x2db2] = 0xfe88, [0x2db3] = 0xfe89, -+ [0x2db4] = 0xfe8a, [0x2db5] = 0xfe8b, [0x2db6] = 0xfe8c, [0x2db7] = 0xfe8d, -+ [0x2db8] = 0xfe8e, [0x2db9] = 0xfe8f, [0x2dba] = 0xfe90, [0x2dbb] = 0xfe91, -+ [0x2dbc] = 0xfe92, [0x2dbd] = 0xfe93, [0x2dbe] = 0xfe94, [0x2dbf] = 0xfe95, -+ [0x2dc0] = 0xfe96, [0x2dc1] = 0xfe97, [0x2dc2] = 0xfe98, [0x2dc3] = 0xfe99, -+ [0x2dc4] = 0xfe9a, [0x2dc5] = 0xfe9b, [0x2dc6] = 0xfe9c, [0x2dc7] = 0xfe9d, -+ [0x2dc8] = 0xfe9e, [0x2dc9] = 0xfe9f, [0x2dca] = 0xfea0, [0x2dcb] = 0xfea1, -+ [0x2dcc] = 0xfea2, [0x2dcd] = 0xfea3, [0x2dce] = 0xfea4, [0x2dcf] = 0xfea5, -+ [0x2dd0] = 0xfea6, [0x2dd1] = 0xfea7, [0x2dd2] = 0xfea8, [0x2dd3] = 0xfea9, -+ [0x2dd4] = 0xfeaa, [0x2dd5] = 0xfeab, [0x2dd6] = 0xfeac, [0x2dd7] = 0xfead, -+ [0x2dd8] = 0xfeae, [0x2dd9] = 0xfeaf, [0x2dda] = 0xfeb0, [0x2ddb] = 0xfeb1, -+ [0x2ddc] = 0xfeb2, [0x2ddd] = 0xfeb3, [0x2dde] = 0xfeb4, [0x2ddf] = 0xfeb5, -+ [0x2de0] = 0xfeb6, [0x2de1] = 0xfeb7, [0x2de2] = 0xfeb8, [0x2de3] = 0xfeb9, -+ [0x2de4] = 0xfeba, [0x2de5] = 0xfebb, [0x2de6] = 0xfebc, [0x2de7] = 0xfebd, -+ [0x2de8] = 0xfebe, [0x2de9] = 0xfebf, [0x2dea] = 0xfec0, [0x2deb] = 0xfec1, -+ [0x2dec] = 0xfec2, [0x2ded] = 0xfec3, [0x2dee] = 0xfec4, [0x2def] = 0xfec5, -+ [0x2df0] = 0xfec6, [0x2df1] = 0xfec7, [0x2df2] = 0xfec8, [0x2df3] = 0xfec9, -+ [0x2df4] = 0xfeca, [0x2df5] = 0xfecb, [0x2df6] = 0xfecc, [0x2df7] = 0xfecd, -+ [0x2df8] = 0xfece, [0x2df9] = 0xfecf, [0x2dfa] = 0xfed0, [0x2dfb] = 0xfed1, -+ [0x2dfc] = 0xfed2, [0x2dfd] = 0xfed3, [0x2dfe] = 0xfed4, [0x2dff] = 0xfed5, -+ [0x2e00] = 0xfed6, [0x2e01] = 0xfed7, [0x2e02] = 0xfed8, [0x2e03] = 0xfed9, -+ [0x2e04] = 0xfeda, [0x2e05] = 0xfedb, [0x2e06] = 0xfedc, [0x2e07] = 0xfedd, -+ [0x2e08] = 0xfede, [0x2e09] = 0xfedf, [0x2e0a] = 0xfee0, [0x2e0b] = 0xfee1, -+ [0x2e0c] = 0xfee2, [0x2e0d] = 0xfee3, [0x2e0e] = 0xfee4, [0x2e0f] = 0xfee5, -+ [0x2e10] = 0xfee6, [0x2e11] = 0xfee7, [0x2e12] = 0xfee8, [0x2e13] = 0xfee9, -+ [0x2e14] = 0xfeea, [0x2e15] = 0xfeeb, [0x2e16] = 0xfeec, [0x2e17] = 0xfeed, -+ [0x2e18] = 0xfeee, [0x2e19] = 0xfeef, [0x2e1a] = 0xfef0, [0x2e1b] = 0xfef1, -+ [0x2e1c] = 0xfef2, [0x2e1d] = 0xfef3, [0x2e1e] = 0xfef4, [0x2e1f] = 0xfef5, -+ [0x2e20] = 0xfef6, [0x2e21] = 0xfef7, [0x2e22] = 0xfef8, [0x2e23] = 0xfef9, -+ [0x2e24] = 0xfefa, [0x2e25] = 0xfefb, [0x2e26] = 0xfefc, [0x2e27] = 0xfefd, -+ [0x2e28] = 0xfefe, [0x2e29] = 0xfeff, [0x2e2a] = 0xff00, [0x2e2b] = 0xff5f, -+ [0x2e2c] = 0xff60, [0x2e2d] = 0xff61, [0x2e2e] = 0xff62, [0x2e2f] = 0xff63, -+ [0x2e30] = 0xff64, [0x2e31] = 0xff65, [0x2e32] = 0xff66, [0x2e33] = 0xff67, -+ [0x2e34] = 0xff68, [0x2e35] = 0xff69, [0x2e36] = 0xff6a, [0x2e37] = 0xff6b, -+ [0x2e38] = 0xff6c, [0x2e39] = 0xff6d, [0x2e3a] = 0xff6e, [0x2e3b] = 0xff6f, -+ [0x2e3c] = 0xff70, [0x2e3d] = 0xff71, [0x2e3e] = 0xff72, [0x2e3f] = 0xff73, -+ [0x2e40] = 0xff74, [0x2e41] = 0xff75, [0x2e42] = 0xff76, [0x2e43] = 0xff77, -+ [0x2e44] = 0xff78, [0x2e45] = 0xff79, [0x2e46] = 0xff7a, [0x2e47] = 0xff7b, -+ [0x2e48] = 0xff7c, [0x2e49] = 0xff7d, [0x2e4a] = 0xff7e, [0x2e4b] = 0xff7f, -+ [0x2e4c] = 0xff80, [0x2e4d] = 0xff81, [0x2e4e] = 0xff82, [0x2e4f] = 0xff83, -+ [0x2e50] = 0xff84, [0x2e51] = 0xff85, [0x2e52] = 0xff86, [0x2e53] = 0xff87, -+ [0x2e54] = 0xff88, [0x2e55] = 0xff89, [0x2e56] = 0xff8a, [0x2e57] = 0xff8b, -+ [0x2e58] = 0xff8c, [0x2e59] = 0xff8d, [0x2e5a] = 0xff8e, [0x2e5b] = 0xff8f, -+ [0x2e5c] = 0xff90, [0x2e5d] = 0xff91, [0x2e5e] = 0xff92, [0x2e5f] = 0xff93, -+ [0x2e60] = 0xff94, [0x2e61] = 0xff95, [0x2e62] = 0xff96, [0x2e63] = 0xff97, -+ [0x2e64] = 0xff98, [0x2e65] = 0xff99, [0x2e66] = 0xff9a, [0x2e67] = 0xff9b, -+ [0x2e68] = 0xff9c, [0x2e69] = 0xff9d, [0x2e6a] = 0xff9e, [0x2e6b] = 0xff9f, -+ [0x2e6c] = 0xffa0, [0x2e6d] = 0xffa1, [0x2e6e] = 0xffa2, [0x2e6f] = 0xffa3, -+ [0x2e70] = 0xffa4, [0x2e71] = 0xffa5, [0x2e72] = 0xffa6, [0x2e73] = 0xffa7, -+ [0x2e74] = 0xffa8, [0x2e75] = 0xffa9, [0x2e76] = 0xffaa, [0x2e77] = 0xffab, -+ [0x2e78] = 0xffac, [0x2e79] = 0xffad, [0x2e7a] = 0xffae, [0x2e7b] = 0xffaf, -+ [0x2e7c] = 0xffb0, [0x2e7d] = 0xffb1, [0x2e7e] = 0xffb2, [0x2e7f] = 0xffb3, -+ [0x2e80] = 0xffb4, [0x2e81] = 0xffb5, [0x2e82] = 0xffb6, [0x2e83] = 0xffb7, -+ [0x2e84] = 0xffb8, [0x2e85] = 0xffb9, [0x2e86] = 0xffba, [0x2e87] = 0xffbb, -+ [0x2e88] = 0xffbc, [0x2e89] = 0xffbd, [0x2e8a] = 0xffbe, [0x2e8b] = 0xffbf, -+ [0x2e8c] = 0xffc0, [0x2e8d] = 0xffc1, [0x2e8e] = 0xffc2, [0x2e8f] = 0xffc3, -+ [0x2e90] = 0xffc4, [0x2e91] = 0xffc5, [0x2e92] = 0xffc6, [0x2e93] = 0xffc7, -+ [0x2e94] = 0xffc8, [0x2e95] = 0xffc9, [0x2e96] = 0xffca, [0x2e97] = 0xffcb, -+ [0x2e98] = 0xffcc, [0x2e99] = 0xffcd, [0x2e9a] = 0xffce, [0x2e9b] = 0xffcf, -+ [0x2e9c] = 0xffd0, [0x2e9d] = 0xffd1, [0x2e9e] = 0xffd2, [0x2e9f] = 0xffd3, -+ [0x2ea0] = 0xffd4, [0x2ea1] = 0xffd5, [0x2ea2] = 0xffd6, [0x2ea3] = 0xffd7, -+ [0x2ea4] = 0xffd8, [0x2ea5] = 0xffd9, [0x2ea6] = 0xffda, [0x2ea7] = 0xffdb, -+ [0x2ea8] = 0xffdc, [0x2ea9] = 0xffdd, [0x2eaa] = 0xffde, [0x2eab] = 0xffdf, - }; - - /* Table for UCS-4 -> GB18030, for the range U+0080..U+9FBB. -@@ -23448,71 +23453,79 @@ static const unsigned char __ucs_to_gb18030_tab2[][2] = - [0x0783] = "\xa5\xfd", [0x0784] = "\xa5\xfe", [0x0785] = "\xa6\xb9", - [0x0786] = "\xa6\xba", [0x0787] = "\xa6\xbb", [0x0788] = "\xa6\xbc", - [0x0789] = "\xa6\xbd", [0x078a] = "\xa6\xbe", [0x078b] = "\xa6\xbf", -- [0x078c] = "\xa6\xc0", [0x0797] = "\xa6\xf6", [0x0798] = "\xa6\xf7", -- [0x0799] = "\xa6\xf8", [0x079a] = "\xa6\xf9", [0x079b] = "\xa6\xfa", -- [0x079c] = "\xa6\xfb", [0x079d] = "\xa6\xfc", [0x079e] = "\xa6\xfd", -- [0x079f] = "\xa6\xfe", [0x07a0] = "\xa7\xc2", [0x07a1] = "\xa7\xc3", -- [0x07a2] = "\xa7\xc4", [0x07a3] = "\xa7\xc5", [0x07a4] = "\xa7\xc6", -- [0x07a5] = "\xa7\xc7", [0x07a6] = "\xa7\xc8", [0x07a7] = "\xa7\xc9", -- [0x07a8] = "\xa7\xca", [0x07a9] = "\xa7\xcb", [0x07aa] = "\xa7\xcc", -- [0x07ab] = "\xa7\xcd", [0x07ac] = "\xa7\xce", [0x07ad] = "\xa7\xcf", -- [0x07ae] = "\xa7\xd0", [0x07af] = "\xa7\xf2", [0x07b0] = "\xa7\xf3", -- [0x07b1] = "\xa7\xf4", [0x07b2] = "\xa7\xf5", [0x07b3] = "\xa7\xf6", -- [0x07b4] = "\xa7\xf7", [0x07b5] = "\xa7\xf8", [0x07b6] = "\xa7\xf9", -- [0x07b7] = "\xa7\xfa", [0x07b8] = "\xa7\xfb", [0x07b9] = "\xa7\xfc", -- [0x07ba] = "\xa7\xfd", [0x07bb] = "\xa7\xfe", [0x07bc] = "\xa8\x96", -- [0x07bd] = "\xa8\x97", [0x07be] = "\xa8\x98", [0x07bf] = "\xa8\x99", -- [0x07c0] = "\xa8\x9a", [0x07c1] = "\xa8\x9b", [0x07c2] = "\xa8\x9c", -- [0x07c3] = "\xa8\x9d", [0x07c4] = "\xa8\x9e", [0x07c5] = "\xa8\x9f", -- [0x07c6] = "\xa8\xa0", [0x07c7] = "\x00\x01", [0x07c8] = "\x65\x9e", -- [0x07c9] = "\xa8\xc1", [0x07ca] = "\xa8\xc2", [0x07cb] = "\xa8\xc3", -- [0x07cc] = "\xa8\xc4", [0x07cd] = "\xa8\xea", [0x07ce] = "\xa8\xeb", -- [0x07cf] = "\xa8\xec", [0x07d0] = "\xa8\xed", [0x07d1] = "\xa8\xee", -- [0x07d2] = "\xa8\xef", [0x07d3] = "\xa8\xf0", [0x07d4] = "\xa8\xf1", -- [0x07d5] = "\xa8\xf2", [0x07d6] = "\xa8\xf3", [0x07d7] = "\xa8\xf4", -- [0x07d8] = "\xa8\xf5", [0x07d9] = "\xa8\xf6", [0x07da] = "\xa8\xf7", -- [0x07db] = "\xa8\xf8", [0x07dc] = "\xa8\xf9", [0x07dd] = "\xa8\xfa", -- [0x07de] = "\xa8\xfb", [0x07df] = "\xa8\xfc", [0x07e0] = "\xa8\xfd", -- [0x07e1] = "\xa8\xfe", [0x07e2] = "\xa9\x58", [0x07e3] = "\xa9\x5b", -- [0x07e4] = "\xa9\x5d", [0x07e5] = "\xa9\x5e", [0x07e6] = "\xa9\x5f", -- [0x07e7] = "\x65\x9f", [0x07e8] = "\x65\xa0", [0x07e9] = "\x65\xa1", -- [0x07ea] = "\x65\xa2", [0x07eb] = "\x65\xa3", [0x07ec] = "\x65\xa4", -- [0x07ed] = "\x65\xa5", [0x07ee] = "\x65\xa6", [0x07ef] = "\x65\xa7", -- [0x07f0] = "\x65\xa8", [0x07f1] = "\x65\xa9", [0x07f2] = "\x65\xaa", -- [0x07f3] = "\x65\xab", [0x07f4] = "\xa9\x97", [0x07f5] = "\xa9\x98", -- [0x07f6] = "\xa9\x99", [0x07f7] = "\xa9\x9a", [0x07f8] = "\xa9\x9b", -- [0x07f9] = "\xa9\x9c", [0x07fa] = "\xa9\x9d", [0x07fb] = "\xa9\x9e", -- [0x07fc] = "\xa9\x9f", [0x07fd] = "\xa9\xa0", [0x07fe] = "\xa9\xa1", -- [0x07ff] = "\xa9\xa2", [0x0800] = "\xa9\xa3", [0x0801] = "\xa9\xf0", -- [0x0802] = "\xa9\xf1", [0x0803] = "\xa9\xf2", [0x0804] = "\xa9\xf3", -- [0x0805] = "\xa9\xf4", [0x0806] = "\xa9\xf5", [0x0807] = "\xa9\xf6", -- [0x0808] = "\xa9\xf7", [0x0809] = "\xa9\xf8", [0x080a] = "\xa9\xf9", -- [0x080b] = "\xa9\xfa", [0x080c] = "\xa9\xfb", [0x080d] = "\xa9\xfc", -- [0x080e] = "\xa9\xfd", [0x080f] = "\xa9\xfe", [0x0810] = "\xd7\xfa", -- [0x0811] = "\xd7\xfb", [0x0812] = "\xd7\xfc", [0x0813] = "\xd7\xfd", -- [0x0814] = "\xd7\xfe", [0x0815] = "\x65\xac", [0x0819] = "\x65\xad", -- [0x081a] = "\x65\xae", [0x081b] = "\x65\xaf", [0x081c] = "\x65\xb0", -- [0x081d] = "\x65\xb1", [0x081f] = "\x65\xb2", [0x0820] = "\x65\xb3", -- [0x0821] = "\x65\xb4", [0x0822] = "\x65\xb5", [0x0823] = "\x65\xb6", -- [0x0824] = "\x65\xb7", [0x0825] = "\x65\xb8", [0x0827] = "\x65\xb9", -+ [0x078c] = "\xa6\xc0", [0x078d] = "\x7b\x84", [0x078e] = "\x7b\x86", -+ [0x078f] = "\x7b\x85", [0x0790] = "\x7b\x87", [0x0791] = "\x7b\x88", -+ [0x0792] = "\x7b\x89", [0x0793] = "\x7b\x8a", [0x0794] = "\x7b\x8b", -+ [0x0795] = "\x7b\x8c", [0x0796] = "\x7b\x8d", [0x0797] = "\xa6\xf6", -+ [0x0798] = "\xa6\xf7", [0x0799] = "\xa6\xf8", [0x079a] = "\xa6\xf9", -+ [0x079b] = "\xa6\xfa", [0x079c] = "\xa6\xfb", [0x079d] = "\xa6\xfc", -+ [0x079e] = "\xa6\xfd", [0x079f] = "\xa6\xfe", [0x07a0] = "\xa7\xc2", -+ [0x07a1] = "\xa7\xc3", [0x07a2] = "\xa7\xc4", [0x07a3] = "\xa7\xc5", -+ [0x07a4] = "\xa7\xc6", [0x07a5] = "\xa7\xc7", [0x07a6] = "\xa7\xc8", -+ [0x07a7] = "\xa7\xc9", [0x07a8] = "\xa7\xca", [0x07a9] = "\xa7\xcb", -+ [0x07aa] = "\xa7\xcc", [0x07ab] = "\xa7\xcd", [0x07ac] = "\xa7\xce", -+ [0x07ad] = "\xa7\xcf", [0x07ae] = "\xa7\xd0", [0x07af] = "\xa7\xf2", -+ [0x07b0] = "\xa7\xf3", [0x07b1] = "\xa7\xf4", [0x07b2] = "\xa7\xf5", -+ [0x07b3] = "\xa7\xf6", [0x07b4] = "\xa7\xf7", [0x07b5] = "\xa7\xf8", -+ [0x07b6] = "\xa7\xf9", [0x07b7] = "\xa7\xfa", [0x07b8] = "\xa7\xfb", -+ [0x07b9] = "\xa7\xfc", [0x07ba] = "\xa7\xfd", [0x07bb] = "\xa7\xfe", -+ [0x07bc] = "\xa8\x96", [0x07bd] = "\xa8\x97", [0x07be] = "\xa8\x98", -+ [0x07bf] = "\xa8\x99", [0x07c0] = "\xa8\x9a", [0x07c1] = "\xa8\x9b", -+ [0x07c2] = "\xa8\x9c", [0x07c3] = "\xa8\x9d", [0x07c4] = "\xa8\x9e", -+ [0x07c5] = "\xa8\x9f", [0x07c6] = "\xa8\xa0", [0x07c7] = "\x00\x01", -+ [0x07c8] = "\x65\x9e", [0x07c9] = "\xa8\xc1", [0x07ca] = "\xa8\xc2", -+ [0x07cb] = "\xa8\xc3", [0x07cc] = "\xa8\xc4", [0x07cd] = "\xa8\xea", -+ [0x07ce] = "\xa8\xeb", [0x07cf] = "\xa8\xec", [0x07d0] = "\xa8\xed", -+ [0x07d1] = "\xa8\xee", [0x07d2] = "\xa8\xef", [0x07d3] = "\xa8\xf0", -+ [0x07d4] = "\xa8\xf1", [0x07d5] = "\xa8\xf2", [0x07d6] = "\xa8\xf3", -+ [0x07d7] = "\xa8\xf4", [0x07d8] = "\xa8\xf5", [0x07d9] = "\xa8\xf6", -+ [0x07da] = "\xa8\xf7", [0x07db] = "\xa8\xf8", [0x07dc] = "\xa8\xf9", -+ [0x07dd] = "\xa8\xfa", [0x07de] = "\xa8\xfb", [0x07df] = "\xa8\xfc", -+ [0x07e0] = "\xa8\xfd", [0x07e1] = "\xa8\xfe", [0x07e2] = "\xa9\x58", -+ [0x07e3] = "\xa9\x5b", [0x07e4] = "\xa9\x5d", [0x07e5] = "\xa9\x5e", -+ [0x07e6] = "\xa9\x5f", [0x07e7] = "\x65\x9f", [0x07e8] = "\x65\xa0", -+ [0x07e9] = "\x65\xa1", [0x07ea] = "\x65\xa2", [0x07eb] = "\x65\xa3", -+ [0x07ec] = "\x65\xa4", [0x07ed] = "\x65\xa5", [0x07ee] = "\x65\xa6", -+ [0x07ef] = "\x65\xa7", [0x07f0] = "\x65\xa8", [0x07f1] = "\x65\xa9", -+ [0x07f2] = "\x65\xaa", [0x07f3] = "\x65\xab", [0x07f4] = "\xa9\x97", -+ [0x07f5] = "\xa9\x98", [0x07f6] = "\xa9\x99", [0x07f7] = "\xa9\x9a", -+ [0x07f8] = "\xa9\x9b", [0x07f9] = "\xa9\x9c", [0x07fa] = "\xa9\x9d", -+ [0x07fb] = "\xa9\x9e", [0x07fc] = "\xa9\x9f", [0x07fd] = "\xa9\xa0", -+ [0x07fe] = "\xa9\xa1", [0x07ff] = "\xa9\xa2", [0x0800] = "\xa9\xa3", -+ [0x0801] = "\xa9\xf0", [0x0802] = "\xa9\xf1", [0x0803] = "\xa9\xf2", -+ [0x0804] = "\xa9\xf3", [0x0805] = "\xa9\xf4", [0x0806] = "\xa9\xf5", -+ [0x0807] = "\xa9\xf6", [0x0808] = "\xa9\xf7", [0x0809] = "\xa9\xf8", -+ [0x080a] = "\xa9\xf9", [0x080b] = "\xa9\xfa", [0x080c] = "\xa9\xfb", -+ [0x080d] = "\xa9\xfc", [0x080e] = "\xa9\xfd", [0x080f] = "\xa9\xfe", -+ [0x0810] = "\xd7\xfa", [0x0811] = "\xd7\xfb", [0x0812] = "\xd7\xfc", -+ [0x0813] = "\xd7\xfd", [0x0814] = "\xd7\xfe", [0x0815] = "\x65\xac", -+ [0x0816] = "\xfe\x51", [0x0817] = "\xfe\x52", [0x0818] = "\xfe\x53", -+ [0x0819] = "\x65\xad", [0x081a] = "\x65\xae", [0x081b] = "\x65\xaf", -+ [0x081c] = "\x65\xb0", [0x081d] = "\x65\xb1", [0x081e] = "\x2d\x51", -+ [0x081f] = "\x65\xb2", [0x0820] = "\x65\xb3", [0x0821] = "\x65\xb4", -+ [0x0822] = "\x65\xb5", [0x0823] = "\x65\xb6", [0x0824] = "\x65\xb7", -+ [0x0825] = "\x65\xb8", [0x0826] = "\x2d\x52", [0x0827] = "\x65\xb9", - [0x0828] = "\x65\xba", [0x0829] = "\x65\xbb", [0x082a] = "\x65\xbc", -- [0x082d] = "\x65\xbd", [0x082e] = "\x65\xbe", [0x082f] = "\x65\xbf", -- [0x0830] = "\x65\xc0", [0x0833] = "\x65\xc1", [0x0834] = "\x65\xc2", -- [0x0835] = "\x65\xc3", [0x0836] = "\x65\xc4", [0x0837] = "\x65\xc5", -- [0x0838] = "\x65\xc6", [0x0839] = "\x65\xc7", [0x083a] = "\x65\xc8", -- [0x083c] = "\x65\xc9", [0x083d] = "\x65\xca", [0x083e] = "\x65\xcb", -- [0x083f] = "\x65\xcc", [0x0840] = "\x65\xcd", [0x0841] = "\x65\xce", -- [0x0842] = "\x65\xcf", [0x0844] = "\x65\xd0", [0x0845] = "\x65\xd1", -+ [0x082b] = "\x2d\x53", [0x082c] = "\x2d\x54", [0x082d] = "\x65\xbd", -+ [0x082e] = "\x65\xbe", [0x082f] = "\x65\xbf", [0x0830] = "\x65\xc0", -+ [0x0831] = "\xfe\x6c", [0x0832] = "\x2d\x55", [0x0833] = "\x65\xc1", -+ [0x0834] = "\x65\xc2", [0x0835] = "\x65\xc3", [0x0836] = "\x65\xc4", -+ [0x0837] = "\x65\xc5", [0x0838] = "\x65\xc6", [0x0839] = "\x65\xc7", -+ [0x083a] = "\x65\xc8", [0x083b] = "\xfe\x76", [0x083c] = "\x65\xc9", -+ [0x083d] = "\x65\xca", [0x083e] = "\x65\xcb", [0x083f] = "\x65\xcc", -+ [0x0840] = "\x65\xcd", [0x0841] = "\x65\xce", [0x0842] = "\x65\xcf", -+ [0x0843] = "\x2d\x56", [0x0844] = "\x65\xd0", [0x0845] = "\x65\xd1", - [0x0846] = "\x65\xd2", [0x0847] = "\x65\xd3", [0x0848] = "\x65\xd4", - [0x0849] = "\x65\xd5", [0x084a] = "\x65\xd6", [0x084b] = "\x65\xd7", - [0x084c] = "\x65\xd8", [0x084d] = "\x65\xd9", [0x084e] = "\x65\xda", - [0x084f] = "\x65\xdb", [0x0850] = "\x65\xdc", [0x0851] = "\x65\xdd", -- [0x0852] = "\x65\xde", [0x0853] = "\x65\xdf", [0x0856] = "\x65\xe0", -- [0x0857] = "\x65\xe1", [0x0858] = "\x65\xe2", [0x0859] = "\x65\xe3", -- [0x085a] = "\x65\xe4", [0x085b] = "\x65\xe5", [0x085c] = "\x65\xe6", -- [0x085d] = "\x65\xe7", [0x085e] = "\x65\xe8", [0x085f] = "\x65\xe9", -- [0x0860] = "\x65\xea", [0x0861] = "\x65\xeb", [0x0862] = "\x65\xec", -- [0x0863] = "\x65\xed", [0x0865] = "\xfd\x9c", [0x0866] = "\x76\xb5", -+ [0x0852] = "\x65\xde", [0x0853] = "\x65\xdf", [0x0854] = "\x2d\x57", -+ [0x0855] = "\xfe\x91", [0x0856] = "\x65\xe0", [0x0857] = "\x65\xe1", -+ [0x0858] = "\x65\xe2", [0x0859] = "\x65\xe3", [0x085a] = "\x65\xe4", -+ [0x085b] = "\x65\xe5", [0x085c] = "\x65\xe6", [0x085d] = "\x65\xe7", -+ [0x085e] = "\x65\xe8", [0x085f] = "\x65\xe9", [0x0860] = "\x65\xea", -+ [0x0861] = "\x65\xeb", [0x0862] = "\x65\xec", [0x0863] = "\x65\xed", -+ [0x0864] = "\x2d\x58", [0x0865] = "\xfd\x9c", [0x0866] = "\x76\xb5", - [0x0867] = "\x76\xb6", [0x0868] = "\x76\xb7", [0x0869] = "\x76\xb8", - [0x086a] = "\x76\xb9", [0x086b] = "\x76\xba", [0x086c] = "\x76\xbb", - [0x086d] = "\x76\xbc", [0x086e] = "\x76\xbd", [0x086f] = "\x76\xbe", -@@ -24222,24 +24235,8 @@ static const unsigned char __ucs_to_gb18030_tab2[][2] = - || (ch = __twobyte_to_ucs[idx], \ - ch == 0 && *inptr != '\0')) \ - { \ -- /* Handle a few special cases. */ \ -- if (idx == 0x5dd1) \ -- ch = 0x20087; \ -- else if (idx == 0x5dd2) \ -- ch = 0x20089; \ -- else if (idx == 0x5dd3) \ -- ch = 0x200cc; \ -- else if (idx == 0x5dec) \ -- ch = 0x215D7; \ -- else if (idx == 0x5df6) \ -- ch = 0x2298F; \ -- else if (idx == 0x5e11) \ -- ch = 0x241FE; \ -- else \ -- { \ -- /* This is an illegal character. */ \ -- STANDARD_FROM_LOOP_ERR_HANDLER (2); \ -- } \ -+ /* This is an illegal character. */ \ -+ STANDARD_FROM_LOOP_ERR_HANDLER (2); \ - } \ - \ - inptr += 2; \ -@@ -24331,17 +24328,35 @@ static const unsigned char __ucs_to_gb18030_tab2[][2] = - len = 4; \ - } \ - else if (ch == 0x20087) \ -- cp = (const unsigned char *) "\xfe\x51"; \ -+ { \ -+ idx = 0x3E2CF; \ -+ len = 4; \ -+ } \ - else if (ch == 0x20089) \ -- cp = (const unsigned char *) "\xfe\x52"; \ -+ { \ -+ idx = 0x3E2D1; \ -+ len = 4; \ -+ } \ - else if (ch == 0x200CC) \ -- cp = (const unsigned char *) "\xfe\x53"; \ -+ { \ -+ idx = 0x3E314; \ -+ len = 4; \ -+ } \ - else if (ch == 0x215d7) \ -- cp = (const unsigned char *) "\xfe\x6c"; \ -+ { \ -+ idx = 0x3F81F; \ -+ len = 4; \ -+ } \ - else if (ch == 0x2298F) \ -- cp = (const unsigned char *) "\xfe\x76"; \ -+ { \ -+ idx = 0x40BD7; \ -+ len = 4; \ -+ } \ - else if (ch == 0x241FE) \ -- cp = (const unsigned char *) "\xfe\x91"; \ -+ { \ -+ idx = 0x42446; \ -+ len = 4; \ -+ } \ - else if (ch >= 0x10000 && ch <= 0x10FFFF) \ - { \ - idx = ch + 0x1E248; \ -diff --git a/iconvdata/tst-table-from.c b/iconvdata/tst-table-from.c -index 9ad1f44e..c881c86b 100644 ---- a/iconvdata/tst-table-from.c -+++ b/iconvdata/tst-table-from.c -@@ -195,10 +195,9 @@ main (int argc, char *argv[]) - exit (1); - } - -- /* When testing UTF-8 or GB18030, stop at 0x10000, otherwise the output -+ /* When testing UTF-8, stop at 0x10000, otherwise the output - file gets too big. */ -- bmp_only = (strcmp (charset, "UTF-8") == 0 -- || strcmp (charset, "GB18030") == 0); -+ bmp_only = (strcmp (charset, "UTF-8") == 0); - search_depth = (strcmp (charset, "UTF-8") == 0 ? 3 : 4); - - { -diff --git a/iconvdata/tst-table-to.c b/iconvdata/tst-table-to.c -index 6f0aa29c..8d097527 100644 ---- a/iconvdata/tst-table-to.c -+++ b/iconvdata/tst-table-to.c -@@ -33,6 +33,7 @@ main (int argc, char *argv[]) - const char *charset; - iconv_t cd; - int bmp_only; -+ int no_tags; - - if (argc != 2) - { -@@ -48,16 +49,19 @@ main (int argc, char *argv[]) - return 1; - } - -- /* When testing UTF-8 or GB18030, stop at 0x10000, otherwise the output -+ /* When testing UTF-8, stop at 0x10000, otherwise the output - file gets too big. */ -- bmp_only = (strcmp (charset, "UTF-8") == 0 -+ bmp_only = (strcmp (charset, "UTF-8") == 0); -+ /* When testing any encoding other than UTF-8 or GB18030, stop at 0xE0000, -+ because the conversion drops Unicode tag characters (range -+ U+E0000..U+E007F). */ -+ no_tags = !(strcmp (charset, "UTF-8") == 0 - || strcmp (charset, "GB18030") == 0); - - { - unsigned int i; - unsigned char buf[10]; -- -- for (i = 0; i < (bmp_only ? 0x10000 : 0x30000); i++) -+ for (i = 0; i < (bmp_only ? 0x10000 : no_tags ? 0xE0000 : 0x110000); i++) - { - unsigned char in[6]; - unsigned int incount = -diff --git a/iconvdata/tst-table.sh b/iconvdata/tst-table.sh -index 04c06136..3c6927ee 100755 ---- a/iconvdata/tst-table.sh -+++ b/iconvdata/tst-table.sh -@@ -38,7 +38,8 @@ set -e - < ../localedata/charmaps/${charmap:-$charset} \ - > ${objpfx}tst-${charset}.charmap.table - # When the charset is GB18030, truncate this table because for this encoding, --# the tst-table-from and tst-table-to programs scan the Unicode BMP only. -+# the charmap contains ranges (.. notation), which the -+# tst-table-charmap.sh script does not grok. - if test ${charset} = GB18030; then - grep '0x....$' < ${objpfx}tst-${charset}.charmap.table \ - > ${objpfx}tst-${charset}.truncated.table -@@ -74,25 +75,42 @@ diff ${objpfx}tst-${charset}.charmap.table ${objpfx}tst-${charset}.inverse.table - - # Check 1: charmap and iconv forward should be identical, except for - # precomposed characters. --if test -f ${precomposed}; then -- cat ${objpfx}tst-${charset}.table ${precomposed} | sort | uniq -u \ -- > ${objpfx}tst-${charset}.tmp.table -- cmp -s ${objpfx}tst-${charset}.charmap.table ${objpfx}tst-${charset}.tmp.table || -+{ if test -f ${precomposed}; then -+ cat ${objpfx}tst-${charset}.table ${precomposed} | sort | uniq -u -+ else -+ cat ${objpfx}tst-${charset}.table -+ fi -+} | { if test ${charset} = GB18030; then grep '0x....$'; else cat; fi; } \ -+ > ${objpfx}tst-${charset}.tmp1.table -+cmp -s ${objpfx}tst-${charset}.charmap.table ${objpfx}tst-${charset}.tmp1.table || - exit 1 --else -- cmp -s ${objpfx}tst-${charset}.charmap.table ${objpfx}tst-${charset}.table || -- exit 1 --fi - - # Check 2: the difference between the charmap and iconv backward. --if test -f ${irreversible}; then -- cat ${objpfx}tst-${charset}.charmap.table ${irreversible} | sort | uniq -u \ -- > ${objpfx}tst-${charset}.tmp.table -- cmp -s ${objpfx}tst-${charset}.tmp.table ${objpfx}tst-${charset}.inverse.table || -- exit 1 --else -- cmp -s ${objpfx}tst-${charset}.charmap.table ${objpfx}tst-${charset}.inverse.table || -+{ if test -f ${irreversible}; then -+ cat ${objpfx}tst-${charset}.charmap.table ${irreversible} | sort | uniq -u -+ else -+ cat ${objpfx}tst-${charset}.charmap.table -+ fi -+} | { if test ${charset} = GB18030; then grep '0x....$'; else cat; fi; } \ -+ > ${objpfx}tst-${charset}.tmp2c.table -+cat ${objpfx}tst-${charset}.inverse.table \ -+ | { if test ${charset} = GB18030; then grep '0x....$'; else cat; fi; } \ -+ > ${objpfx}tst-${charset}.tmp2i.table -+cmp -s ${objpfx}tst-${charset}.tmp2c.table ${objpfx}tst-${charset}.tmp2i.table || - exit 1 -+ -+# Check 3: the difference between iconv forward and iconv backward. This is -+# necessary only for GB18030, because ${objpfx}tst-${charset}.charmap.table -+# is truncated for this encoding (see above). -+if test ${charset} = GB18030; then -+ { if test -f ${irreversible}; then -+ cat ${objpfx}tst-${charset}.table ${irreversible} | sort | uniq -u -+ else -+ cat ${objpfx}tst-${charset}.table -+ fi -+ } > ${objpfx}tst-${charset}.tmp3.table -+ cmp -s ${objpfx}tst-${charset}.tmp3.table ${objpfx}tst-${charset}.inverse.table || -+ exit 1 - fi - - exit 0 -diff --git a/localedata/charmaps/GB18030 b/localedata/charmaps/GB18030 -index ad6728c5..fc3b1d2d 100644 ---- a/localedata/charmaps/GB18030 -+++ b/localedata/charmaps/GB18030 -@@ -57234,32 +57234,16 @@ CHARMAP - /xa6/xbe - /xa6/xbf - /xa6/xc0 --% The newest GB 18030-2005 standard still uses some private use area --% code points. Any implementation which has Unicode 4.1 or newer --% support should not use these PUA code points, and instead should --% map these entries to their equivalent non-PUA code points. There --% are 24 idiograms in GB 18030-2005 which have non-PUA equivalents. --% In glibc we only support roundtrip code points, and so must choose --% between supporting the old PUA code points, or using the newer --% non-PUA code points. We choose to use the non-PUA code points to --% be compatible with ICU's similar choice. In choosing the non-PUA --% code points we can no longer convert the old PUA code points back --% to GB-18030-2005 (technically only fixable if we added support --% for non-roundtrip code points e.g. ICU's "fallback mapping"). --% The recommendation to use the non-PUA code points, where available, --% is based on "CJKV Information Processing" 2nd Ed. by Dr. Ken Lunde. --% --% These 10 PUA mappings use equivalents from to . --% /xa6/xd9 --% /xa6/xda --% /xa6/xdb --% /xa6/xdc --% /xa6/xdd --% /xa6/xde --% /xa6/xdf --% /xa6/xec --% /xa6/xed --% /xa6/xf3 -+ /x84/x31/x82/x36 -+ /x84/x31/x82/x38 -+ /x84/x31/x82/x37 -+ /x84/x31/x82/x39 -+ /x84/x31/x83/x30 -+ /x84/x31/x83/x31 -+ /x84/x31/x83/x32 -+ /x84/x31/x83/x33 -+ /x84/x31/x83/x34 -+ /x84/x31/x83/x35 - /xa6/xf6 - /xa6/xf7 - /xa6/xf8 -@@ -57387,17 +57371,15 @@ CHARMAP - /xd7/xfd - /xd7/xfe - /x83/x36/xc9/x34 --% These 3 PUA mappings use equivalents , and . --% /xfe/x51 --% /xfe/x52 --% /xfe/x53 -+ /xfe/x51 -+ /xfe/x52 -+ /xfe/x53 - /x83/x36/xc9/x35 - /x83/x36/xc9/x36 - /x83/x36/xc9/x37 - /x83/x36/xc9/x38 - /x83/x36/xc9/x39 --% This 1 PUA mapping uses the equivalent . --% /xfe/x59 -+ /x82/x35/x90/x37 - /x83/x36/xca/x30 - /x83/x36/xca/x31 - /x83/x36/xca/x32 -@@ -57405,22 +57387,19 @@ CHARMAP - /x83/x36/xca/x34 - /x83/x36/xca/x35 - /x83/x36/xca/x36 --% This 1 PUA mapping uses the equivalent . --% /xfe/x61 -+ /x82/x35/x90/x38 - /x83/x36/xca/x37 - /x83/x36/xca/x38 - /x83/x36/xca/x39 - /x83/x36/xcb/x30 --% These 2 PUA mappings use the equivalents and . --% /xfe/x66 --% /xfe/x67 -+ /x82/x35/x90/x39 -+ /x82/x35/x91/x30 - /x83/x36/xcb/x31 - /x83/x36/xcb/x32 - /x83/x36/xcb/x33 - /x83/x36/xcb/x34 --% These 2 PUA mappings use the equivalents and . --% /xfe/x6c --% /xfe/x6d -+ /xfe/x6c -+ /x82/x35/x91/x31 - /x83/x36/xcb/x35 - /x83/x36/xcb/x36 - /x83/x36/xcb/x37 -@@ -57429,8 +57408,7 @@ CHARMAP - /x83/x36/xcc/x30 - /x83/x36/xcc/x31 - /x83/x36/xcc/x32 --% This 1 PUA mapping uses the equivalent . --% /xfe/x76 -+ /xfe/x76 - /x83/x36/xcc/x33 - /x83/x36/xcc/x34 - /x83/x36/xcc/x35 -@@ -57438,8 +57416,7 @@ CHARMAP - /x83/x36/xcc/x37 - /x83/x36/xcc/x38 - /x83/x36/xcc/x39 --% This 1 PUA mapping uses the equivalent . --% /xfe/x7e -+ /x82/x35/x91/x32 - /x83/x36/xcd/x30 - /x83/x36/xcd/x31 - /x83/x36/xcd/x32 -@@ -57456,9 +57433,8 @@ CHARMAP - /x83/x36/xce/x33 - /x83/x36/xce/x34 - /x83/x36/xce/x35 --% These 2 PUA mappings use the equivalents and . --% /xfe/x90 --% /xfe/x91 -+ /x82/x35/x91/x33 -+ /xfe/x91 - /x83/x36/xce/x36 - /x83/x36/xce/x37 - /x83/x36/xce/x38 -@@ -57473,8 +57449,7 @@ CHARMAP - /x83/x36/xcf/x37 - /x83/x36/xcf/x38 - /x83/x36/xcf/x39 --% This 1 PUA mapping uses the equivalent . --% /xfe/xa0 -+ /x82/x35/x91/x34 - /x83/x36/xd0/x30 - /x83/x36/xd0/x31 - /x83/x36/xd0/x32 -@@ -70447,19 +70422,14 @@ CHARMAP - .. /x95/x32/x8d/x30 - .. /x95/x32/x8e/x30 - .. /x95/x32/x8f/x30 -- /x95/x32/x90/x30 -- /xfe/x51 -- /x95/x32/x90/x32 -- /xfe/x52 --.. /x95/x32/x90/x34 -+.. /x95/x32/x90/x30 - .. /x95/x32/x91/x30 - .. /x95/x32/x92/x30 - .. /x95/x32/x93/x30 - .. /x95/x32/x94/x30 - .. /x95/x32/x95/x30 - .. /x95/x32/x96/x30 -- /xfe/x53 --.. /x95/x32/x97/x31 -+.. /x95/x32/x97/x30 - .. /x95/x32/x98/x30 - .. /x95/x32/x99/x30 - .. /x95/x32/x9a/x30 -@@ -70998,8 +70968,7 @@ CHARMAP - .. /x95/x36/xb7/x30 - .. /x95/x36/xb8/x30 - .. /x95/x36/xb9/x30 -- /xfe/x6c --.. /x95/x36/xb9/x38 -+.. /x95/x36/xb9/x37 - .. /x95/x36/xba/x30 - .. /x95/x36/xbb/x30 - .. /x95/x36/xbc/x30 -@@ -71505,8 +71474,7 @@ CHARMAP - .. /x96/x30/xb8/x30 - .. /x96/x30/xb9/x30 - .. /x96/x30/xba/x30 -- /xfe/x76 --.. /x96/x30/xba/x36 -+.. /x96/x30/xba/x35 - .. /x96/x30/xbb/x30 - .. /x96/x30/xbc/x30 - .. /x96/x30/xbd/x30 -@@ -72132,8 +72100,7 @@ CHARMAP - .. /x96/x35/xb3/x30 - .. /x96/x35/xb4/x30 - .. /x96/x35/xb5/x30 -- /xfe/x91 --.. /x96/x35/xb6/x31 -+.. /x96/x35/xb6/x30 - .. /x96/x35/xb7/x30 - .. /x96/x35/xb8/x30 - .. /x96/x35/xb9/x30 diff --git a/glibc-rh2234713.patch b/glibc-rh2234713.patch new file mode 100644 index 0000000..999840c --- /dev/null +++ b/glibc-rh2234713.patch @@ -0,0 +1,187 @@ +commit bd77dd7e73e3530203be1c52c8a29d08270cb25d +Author: Florian Weimer +Date: Wed Sep 13 14:10:56 2023 +0200 + + CVE-2023-4527: Stack read overflow with large TCP responses in no-aaaa mode + + Without passing alt_dns_packet_buffer, __res_context_search can only + store 2048 bytes (what fits into dns_packet_buffer). However, + the function returns the total packet size, and the subsequent + DNS parsing code in _nss_dns_gethostbyname4_r reads beyond the end + of the stack-allocated buffer. + + Fixes commit f282cdbe7f436c75864e5640a4 ("resolv: Implement no-aaaa + stub resolver option") and bug 30842. + +Conflicts: + resolv/nss_dns/dns-host.c + (missing dns_packet_buffer cleanup downstream) + +diff --git a/resolv/Makefile b/resolv/Makefile +index ab8ad49b5318ad41..4f4eaf060443c128 100644 +--- a/resolv/Makefile ++++ b/resolv/Makefile +@@ -58,6 +58,7 @@ tests += \ + tst-resolv-edns \ + tst-resolv-network \ + tst-resolv-noaaaa \ ++ tst-resolv-noaaaa-vc \ + tst-resolv-nondecimal \ + tst-resolv-res_init-multi \ + tst-resolv-search \ +@@ -202,6 +203,7 @@ $(objpfx)tst-resolv-res_init-multi: $(objpfx)libresolv.so \ + $(objpfx)tst-resolv-res_init-thread: $(libdl) $(objpfx)libresolv.so \ + $(shared-thread-library) + $(objpfx)tst-resolv-noaaaa: $(objpfx)libresolv.so $(shared-thread-library) ++$(objpfx)tst-resolv-noaaaa-vc: $(objpfx)libresolv.so $(shared-thread-library) + $(objpfx)tst-resolv-nondecimal: $(objpfx)libresolv.so $(shared-thread-library) + $(objpfx)tst-resolv-qtypes: $(objpfx)libresolv.so $(shared-thread-library) + $(objpfx)tst-resolv-rotate: $(objpfx)libresolv.so $(shared-thread-library) +diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c +index ff0a0b6f7f1f4703..f678c7d7caa3a026 100644 +--- a/resolv/nss_dns/dns-host.c ++++ b/resolv/nss_dns/dns-host.c +@@ -392,7 +392,7 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, + else + { + n = __res_context_search (ctx, name, C_IN, T_A, +- host_buffer.buf->buf, 2048, NULL, ++ host_buffer.buf->buf, 2048, &host_buffer.ptr, + NULL, NULL, NULL, NULL); + if (n >= 0) + status = gaih_getanswer_noaaaa (host_buffer.buf, n, +diff --git a/resolv/tst-resolv-noaaaa-vc.c b/resolv/tst-resolv-noaaaa-vc.c +new file mode 100644 +index 0000000000000000..9f5aebd99f2d74a2 +--- /dev/null ++++ b/resolv/tst-resolv-noaaaa-vc.c +@@ -0,0 +1,129 @@ ++/* Test the RES_NOAAAA resolver option with a large response. ++ Copyright (C) 2022-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 ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Used to keep track of the number of queries. */ ++static volatile unsigned int queries; ++ ++/* If true, add a large TXT record at the start of the answer section. */ ++static volatile bool stuff_txt; ++ ++static void ++response (const struct resolv_response_context *ctx, ++ struct resolv_response_builder *b, ++ const char *qname, uint16_t qclass, uint16_t qtype) ++{ ++ /* If not using TCP, just force its use. */ ++ if (!ctx->tcp) ++ { ++ struct resolv_response_flags flags = {.tc = true}; ++ resolv_response_init (b, flags); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ return; ++ } ++ ++ /* The test needs to send four queries, the first three are used to ++ grow the NSS buffer via the ERANGE handshake. */ ++ ++queries; ++ TEST_VERIFY (queries <= 4); ++ ++ /* AAAA queries are supposed to be disabled. */ ++ TEST_COMPARE (qtype, T_A); ++ TEST_COMPARE (qclass, C_IN); ++ TEST_COMPARE_STRING (qname, "example.com"); ++ ++ struct resolv_response_flags flags = {}; ++ resolv_response_init (b, flags); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ ++ resolv_response_section (b, ns_s_an); ++ ++ if (stuff_txt) ++ { ++ resolv_response_open_record (b, qname, qclass, T_TXT, 60); ++ int zero = 0; ++ for (int i = 0; i <= 15000; ++i) ++ resolv_response_add_data (b, &zero, sizeof (zero)); ++ resolv_response_close_record (b); ++ } ++ ++ for (int i = 0; i < 200; ++i) ++ { ++ resolv_response_open_record (b, qname, qclass, qtype, 60); ++ char ipv4[4] = {192, 0, 2, i + 1}; ++ resolv_response_add_data (b, &ipv4, sizeof (ipv4)); ++ resolv_response_close_record (b); ++ } ++} ++ ++static int ++do_test (void) ++{ ++ struct resolv_test *obj = resolv_test_start ++ ((struct resolv_redirect_config) ++ { ++ .response_callback = response ++ }); ++ ++ _res.options |= RES_NOAAAA; ++ ++ for (int do_stuff_txt = 0; do_stuff_txt < 2; ++do_stuff_txt) ++ { ++ queries = 0; ++ stuff_txt = do_stuff_txt; ++ ++ struct addrinfo *ai = NULL; ++ int ret; ++ ret = getaddrinfo ("example.com", "80", ++ &(struct addrinfo) ++ { ++ .ai_family = AF_UNSPEC, ++ .ai_socktype = SOCK_STREAM, ++ }, &ai); ++ ++ char *expected_result; ++ { ++ struct xmemstream mem; ++ xopen_memstream (&mem); ++ for (int i = 0; i < 200; ++i) ++ fprintf (mem.out, "address: STREAM/TCP 192.0.2.%d 80\n", i + 1); ++ xfclose_memstream (&mem); ++ expected_result = mem.buffer; ++ } ++ ++ check_addrinfo ("example.com", ai, ret, expected_result); ++ ++ free (expected_result); ++ freeaddrinfo (ai); ++ } ++ ++ resolv_test_end (obj); ++ return 0; ++} ++ ++#include diff --git a/glibc.spec b/glibc.spec index 2a454bb..f3de45f 100644 --- a/glibc.spec +++ b/glibc.spec @@ -1,7 +1,6 @@ -%global anolis_release .0.4 %define glibcsrcdir glibc-2.28 %define glibcversion 2.28 -%define glibcrelease 225%{anolis_release}%{?dist} +%define glibcrelease 225%{?dist} # Pre-release tarballs are pulled in from git using a command that is # effectively: # @@ -133,7 +132,7 @@ end \ Summary: The GNU libc libraries Name: glibc Version: %{glibcversion} -Release: %{glibcrelease} +Release: %{glibcrelease}.6 # In general, GPLv2+ is used by programs, LGPLv2+ is used for # libraries. @@ -179,7 +178,6 @@ Source12: ChangeLog.old Source13: wrap-find-debuginfo.sh - ###################################################################### # Activate the wrapper script for debuginfo generation, by rewriting # the definition of __debug_install_post. @@ -200,9 +198,6 @@ rpm.define("__find_debuginfo " .. wrapper .. " " .. sysroot .. " " .. original) # - See each individual patch file for origin and upstream status. # - For new patches follow template.patch format. ############################################################################## -# https://sourceware.org/bugzilla/show_bug.cgi?id=30243 -Patch0: glibc-gb18030-2022-bug30243.patch - Patch2: glibc-fedora-nscd.patch Patch3: glibc-rh697421.patch Patch4: glibc-fedora-linux-tcsetattr.patch @@ -1036,16 +1031,11 @@ Patch838: glibc-rh2142937-3.patch Patch839: glibc-rh2144568.patch Patch840: glibc-rh2154914-1.patch Patch841: glibc-rh2154914-2.patch - -Patch842: glibc-Properly-check-stack-alignment-BZ-27901.patch -Patch843: glibc-elf-Properly-align-PT_LOAD-segments-BZ-28676-1.patch -Patch844: glibc-Add-a-testcase-to-check-alignment-of-PT_LOAD-segment-2.patch -Patch845: glibc-elf-Align-argument-of-__munmap-to-page-size-BZ-28676-3.patch -Patch846: glibc-Support-target-specific-ALIGN-for-variable-alignment-4.patch -Patch847: glibc-elf-Fix-tst-align3.patch - -Patch848: glibc-Sync-to-lnd-35-for-LoongArch.patch -Patch849: Fix-tst-cancel21.c-to-suit-kernel-struct-sigcontext-.patch +# (Reverted fixes for rh2237433 were here.) +Patch848: glibc-rh2234713.patch +Patch849: glibc-RHEL-2434.patch +Patch850: glibc-RHEL-2422.patch +Patch851: glibc-RHEL-3035.patch ############################################################################## # Continued list of core "glibc" package information: @@ -1726,11 +1716,6 @@ build() %ifarch %{ix86} --disable-multi-arch \ %endif -%ifarch loongarch64 - --enable-stackguard-randomization \ - --with-selinux \ - --enable-shared \ -%endif %if %{without werror} --disable-werror \ %endif @@ -2881,17 +2866,23 @@ fi %files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared %changelog -* Thu Aug 3 2023 Funda Wang - 2.28-225.0.4 -- Add patch for gb18030-2022 from upstream bug#30243 +* Wed Sep 20 2023 Siddhesh Poyarekar - 2.28-236.6 +- CVE-2023-4911 glibc: buffer overflow in ld.so leading to privilege escalation (RHEL-3035) -* Mon Jul 31 2023 lixing - 2.28-225.0.3 -- Sync loongarch64 code to lnd.35. +* Tue Sep 19 2023 Carlos O'Donell - 2.28-236.5 +- Revert: Always call destructors in reverse constructor order (#2237433) -* Wed Jul 19 2023 Rongwei Wang - 2.28-225.0.2 -- elf: Properly align PT_LOAD segments +* Mon Sep 18 2023 Siddhesh Poyarekar - 2.28-225.4 +- CVE-2023-4806: potential use-after-free in getaddrinfo (RHEL-2422) -* Sat Jul 1 2023 Weisson - 2.28-225.0.1 -- Remove loongarch64. +* Fri Sep 15 2023 Siddhesh Poyarekar - 2.28-225.3 +- CVE-2023-4813: potential use-after-free in gaih_inet (RHEL-2434) + +* Fri Sep 15 2023 Carlos O'Donell - 2.28-225.2 +- CVE-2023-4527: Stack read overflow in getaddrinfo in no-aaaa mode (#2234713) + +* Tue Sep 12 2023 Florian Weimer - 2.28-225.1 +- Always call destructors in reverse constructor order (#2237433) * Fri Jan 20 2023 Florian Weimer - 2.28-225 - Enforce a specififc internal ordering for tunables (#2154914) From 04546a31a32bfd10dd40ea4bfd3e27d6d4027f45 Mon Sep 17 00:00:00 2001 From: Rongwei Wang Date: Wed, 19 Jul 2023 15:33:00 +0800 Subject: [PATCH 2/4] elf: Properly align PT_LOAD segments It introduces four patches about aligning PT_LOAD segments and update to glibc-2.28-225.0.2.el8. Signed-off-by: Rongwei Wang --- ...check-alignment-of-PT_LOAD-segment-2.patch | 147 ++++++++ ...perly-check-stack-alignment-BZ-27901.patch | 325 ++++++++++++++++++ ...cific-ALIGN-for-variable-alignment-4.patch | 171 +++++++++ ...-of-__munmap-to-page-size-BZ-28676-3.patch | 36 ++ glibc-elf-Fix-tst-align3.patch | 40 +++ ...ly-align-PT_LOAD-segments-BZ-28676-1.patch | 137 ++++++++ glibc.spec | 13 +- 7 files changed, 868 insertions(+), 1 deletion(-) create mode 100644 glibc-Add-a-testcase-to-check-alignment-of-PT_LOAD-segment-2.patch create mode 100644 glibc-Properly-check-stack-alignment-BZ-27901.patch create mode 100644 glibc-Support-target-specific-ALIGN-for-variable-alignment-4.patch create mode 100644 glibc-elf-Align-argument-of-__munmap-to-page-size-BZ-28676-3.patch create mode 100644 glibc-elf-Fix-tst-align3.patch create mode 100644 glibc-elf-Properly-align-PT_LOAD-segments-BZ-28676-1.patch diff --git a/glibc-Add-a-testcase-to-check-alignment-of-PT_LOAD-segment-2.patch b/glibc-Add-a-testcase-to-check-alignment-of-PT_LOAD-segment-2.patch new file mode 100644 index 0000000..73f1a06 --- /dev/null +++ b/glibc-Add-a-testcase-to-check-alignment-of-PT_LOAD-segment-2.patch @@ -0,0 +1,147 @@ +From 58f93dff514cc0bdf3c72eff590dcf5fe5bf9e00 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Wed, 19 Jul 2023 23:09:09 +0800 +Subject: [PATCH 3/6] Add a testcase to check alignment of PT_LOAD segment [BZ + #28676] + +Backport from master commit: fc2334a + +Signed-off-by: Rongwei Wang +--- + elf/Makefile | 13 ++++++++++++- + elf/tst-align3.c | 38 ++++++++++++++++++++++++++++++++++++++ + elf/tst-alignmod3.c | 32 ++++++++++++++++++++++++++++++++ + 3 files changed, 82 insertions(+), 1 deletion(-) + create mode 100644 elf/tst-align3.c + create mode 100644 elf/tst-alignmod3.c + +diff --git a/elf/Makefile b/elf/Makefile +index 634c3113..442817ca 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -331,6 +331,7 @@ tests += \ + tst-addr1 \ + tst-align \ + tst-align2 \ ++ tst-align3 \ + tst-audit-tlsdesc \ + tst-audit-tlsdesc-dlopen \ + tst-audit1 \ +@@ -466,7 +467,9 @@ endif + test-srcs = \ + tst-pathopt + # tests-srcs +- ++ifeq (yes,$(have-fpie)) ++tests-pie += tst-align3 ++endif + selinux-enabled := $(shell cat /selinux/enforce 2> /dev/null) + + ifneq ($(selinux-enabled),1) +@@ -647,6 +650,7 @@ modules-names = \ + tst-absolute-zero-lib \ + tst-alignmod \ + tst-alignmod2 \ ++ tst-alignmod3 \ + tst-array2dep \ + tst-array5dep \ + tst-audit-tlsdesc-mod1 \ +@@ -1669,6 +1673,13 @@ CFLAGS-tst-alignmod2.c += $(stack-align-test-flags) + $(objpfx)tst-align: $(libdl) + $(objpfx)tst-align.out: $(objpfx)tst-alignmod.so + $(objpfx)tst-align2: $(objpfx)tst-alignmod2.so ++$(objpfx)tst-align3: $(objpfx)tst-alignmod3.so ++ifeq (yes,$(have-fpie)) ++CFLAGS-tst-align3.c += $(PIE-ccflag) ++endif ++LDFLAGS-tst-align3 += -Wl,-z,max-page-size=0x200000 ++LDFLAGS-tst-alignmod3.so += -Wl,-z,max-page-size=0x200000 ++$(objpfx)tst-alignmod3.so: $(libsupport) + + $(objpfx)unload3: $(libdl) + $(objpfx)unload3.out: $(objpfx)unload3mod1.so $(objpfx)unload3mod2.so \ +diff --git a/elf/tst-align3.c b/elf/tst-align3.c +new file mode 100644 +index 00000000..ac86d623 +--- /dev/null ++++ b/elf/tst-align3.c +@@ -0,0 +1,38 @@ ++/* Check alignment of PT_LOAD segment in a shared library. ++ Copyright (C) 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 ++ ++/* This should cover all possible page sizes we currently support. */ ++#define ALIGN 0x200000 ++ ++int bar __attribute__ ((aligned (ALIGN))) = 1; ++ ++extern int do_load_test (void); ++ ++static int ++do_test (void) ++{ ++ printf ("bar: %p\n", &bar); ++ TEST_VERIFY (is_aligned (&bar, ALIGN) == 0); ++ ++ return do_load_test (); ++} ++ ++#include +diff --git a/elf/tst-alignmod3.c b/elf/tst-alignmod3.c +new file mode 100644 +index 00000000..0d33f237 +--- /dev/null ++++ b/elf/tst-alignmod3.c +@@ -0,0 +1,32 @@ ++/* Check alignment of PT_LOAD segment in a shared library. ++ Copyright (C) 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 ++ ++/* This should cover all possible page sizes we currently support. */ ++#define ALIGN 0x200000 ++ ++int foo __attribute__ ((aligned (ALIGN))) = 1; ++ ++void ++do_load_test (void) ++{ ++ printf ("foo: %p\n", &foo); ++ TEST_VERIFY (is_aligned (&foo, ALIGN) == 0); ++} +-- +2.27.0 + diff --git a/glibc-Properly-check-stack-alignment-BZ-27901.patch b/glibc-Properly-check-stack-alignment-BZ-27901.patch new file mode 100644 index 0000000..20dff99 --- /dev/null +++ b/glibc-Properly-check-stack-alignment-BZ-27901.patch @@ -0,0 +1,325 @@ +From 6152628751bf13f74c9336263a9c22f29ccd8ffb Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Wed, 19 Jul 2023 23:01:53 +0800 +Subject: [PATCH 1/6] Properly check stack alignment [BZ #27901] + +1. Replace + +if ((((uintptr_t) &_d) & (__alignof (double) - 1)) != 0) + +which may be optimized out by compiler, with + +int +__attribute__ ((weak, noclone, noinline)) +is_aligned (void *p, int align) +{ + return (((uintptr_t) p) & (align - 1)) != 0; +} + +2. Add TEST_STACK_ALIGN_INIT to TEST_STACK_ALIGN. +3. Add a common TEST_STACK_ALIGN_INIT to check 16-byte stack alignment +for both i386 and x86-64. +4. Update powerpc to use TEST_STACK_ALIGN_INIT. + +Reviewed-by: Carlos O'Donell +Signed-off-by: Rongwei Wang +--- + sysdeps/generic/tst-stack-align.h | 40 ++++++++++++++++--------- + sysdeps/i386/i686/tst-stack-align.h | 44 --------------------------- + sysdeps/i386/tst-stack-align.h | 41 ------------------------- + sysdeps/powerpc/tst-stack-align.h | 27 +++++------------ + sysdeps/x86/tst-stack-align.h | 28 ++++++++++++++++++ + sysdeps/x86_64/tst-stack-align.h | 46 ----------------------------- + 6 files changed, 61 insertions(+), 165 deletions(-) + delete mode 100644 sysdeps/i386/i686/tst-stack-align.h + delete mode 100644 sysdeps/i386/tst-stack-align.h + create mode 100644 sysdeps/x86/tst-stack-align.h + delete mode 100644 sysdeps/x86_64/tst-stack-align.h + +diff --git a/sysdeps/generic/tst-stack-align.h b/sysdeps/generic/tst-stack-align.h +index e5cb3310..e6050901 100644 +--- a/sysdeps/generic/tst-stack-align.h ++++ b/sysdeps/generic/tst-stack-align.h +@@ -1,4 +1,5 @@ +-/* Copyright (C) 2003-2018 Free Software Foundation, Inc. ++/* Check stack alignment. Generic version. ++ Copyright (C) 2003-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 +@@ -18,17 +19,28 @@ + #include + #include + ++int ++__attribute__ ((weak, noclone, noinline)) ++is_aligned (void *p, int align) ++{ ++ return (((uintptr_t) p) & (align - 1)) != 0; ++} ++ ++#ifndef TEST_STACK_ALIGN_INIT ++# define TEST_STACK_ALIGN_INIT() 0 ++#endif ++ + #define TEST_STACK_ALIGN() \ +- ({ \ +- double _d = 12.0; \ +- long double _ld = 15.0; \ +- int _ret = 0; \ +- printf ("double: %g %p %zu\n", _d, &_d, __alignof (double)); \ +- if ((((uintptr_t) &_d) & (__alignof (double) - 1)) != 0) \ +- _ret = 1; \ +- \ +- printf ("ldouble: %Lg %p %zu\n", _ld, &_ld, __alignof (long double)); \ +- if ((((uintptr_t) &_ld) & (__alignof (long double) - 1)) != 0) \ +- _ret = 1; \ +- _ret; \ +- }) ++ ({ \ ++ double _d = 12.0; \ ++ long double _ld = 15.0; \ ++ int _ret = TEST_STACK_ALIGN_INIT (); \ ++ \ ++ printf ("double: %g %p %zu\n", _d, &_d, __alignof (double)); \ ++ _ret += is_aligned (&_d, __alignof (double)); \ ++ \ ++ printf ("ldouble: %Lg %p %zu\n", _ld, &_ld, \ ++ __alignof (long double)); \ ++ _ret += is_aligned (&_ld, __alignof (long double)); \ ++ _ret; \ ++ }) +diff --git a/sysdeps/i386/i686/tst-stack-align.h b/sysdeps/i386/i686/tst-stack-align.h +deleted file mode 100644 +index 975f26ef..00000000 +--- a/sysdeps/i386/i686/tst-stack-align.h ++++ /dev/null +@@ -1,44 +0,0 @@ +-/* Copyright (C) 2003-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 +-#ifndef __SSE__ +-#include_next +-#else +-#include +- +-#define TEST_STACK_ALIGN() \ +- ({ \ +- __m128 _m; \ +- double _d = 12.0; \ +- long double _ld = 15.0; \ +- int _ret = 0; \ +- printf ("__m128: %p %zu\n", &_m, __alignof (__m128)); \ +- if ((((uintptr_t) &_m) & (__alignof (__m128) - 1)) != 0) \ +- _ret = 1; \ +- \ +- printf ("double: %g %p %zu\n", _d, &_d, __alignof (double)); \ +- if ((((uintptr_t) &_d) & (__alignof (double) - 1)) != 0) \ +- _ret = 1; \ +- \ +- printf ("ldouble: %Lg %p %zu\n", _ld, &_ld, __alignof (long double)); \ +- if ((((uintptr_t) &_ld) & (__alignof (long double) - 1)) != 0) \ +- _ret = 1; \ +- _ret; \ +- }) +-#endif +diff --git a/sysdeps/i386/tst-stack-align.h b/sysdeps/i386/tst-stack-align.h +deleted file mode 100644 +index 394ff773..00000000 +--- a/sysdeps/i386/tst-stack-align.h ++++ /dev/null +@@ -1,41 +0,0 @@ +-/* Copyright (C) 2004-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 +- +-typedef struct { int i[4]; } int_al16 __attribute__((aligned (16))); +- +-#define TEST_STACK_ALIGN() \ +- ({ \ +- int_al16 _m; \ +- double _d = 12.0; \ +- long double _ld = 15.0; \ +- int _ret = 0; \ +- printf ("int_al16: %p %zu\n", &_m, __alignof (int_al16)); \ +- if ((((uintptr_t) &_m) & (__alignof (int_al16) - 1)) != 0) \ +- _ret = 1; \ +- \ +- printf ("double: %g %p %zu\n", _d, &_d, __alignof (double)); \ +- if ((((uintptr_t) &_d) & (__alignof (double) - 1)) != 0) \ +- _ret = 1; \ +- \ +- printf ("ldouble: %Lg %p %zu\n", _ld, &_ld, __alignof (long double)); \ +- if ((((uintptr_t) &_ld) & (__alignof (long double) - 1)) != 0) \ +- _ret = 1; \ +- _ret; \ +- }) +diff --git a/sysdeps/powerpc/tst-stack-align.h b/sysdeps/powerpc/tst-stack-align.h +index 7fd7013b..d7400b28 100644 +--- a/sysdeps/powerpc/tst-stack-align.h ++++ b/sysdeps/powerpc/tst-stack-align.h +@@ -1,4 +1,5 @@ +-/* Copyright (C) 2005-2018 Free Software Foundation, Inc. ++/* Check stack alignment. PowerPC version. ++ Copyright (C) 2005-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 +@@ -15,10 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#include +-#include +- +-#define TEST_STACK_ALIGN() \ ++#define TEST_STACK_ALIGN_INIT() \ + ({ \ + /* Altivec __vector int etc. needs 16byte aligned stack. \ + Instead of using altivec.h here, use aligned attribute instead. */ \ +@@ -27,20 +25,9 @@ + int _i __attribute__((aligned (16))); \ + int _j[3]; \ + } _s = { ._i = 18, ._j[0] = 19, ._j[1] = 20, ._j[2] = 21 }; \ +- double _d = 12.0; \ +- long double _ld = 15.0; \ +- int _ret = 0; \ + printf ("__vector int: { %d, %d, %d, %d } %p %zu\n", _s._i, _s._j[0], \ + _s._j[1], _s._j[2], &_s, __alignof (_s)); \ +- if ((((uintptr_t) &_s) & (__alignof (_s) - 1)) != 0) \ +- _ret = 1; \ +- \ +- printf ("double: %g %p %zu\n", _d, &_d, __alignof (double)); \ +- if ((((uintptr_t) &_d) & (__alignof (double) - 1)) != 0) \ +- _ret = 1; \ +- \ +- printf ("ldouble: %Lg %p %zu\n", _ld, &_ld, __alignof (long double)); \ +- if ((((uintptr_t) &_ld) & (__alignof (long double) - 1)) != 0) \ +- _ret = 1; \ +- _ret; \ +- }) ++ is_aligned (&_s, __alignof (_s)); \ ++ }) ++ ++#include_next +diff --git a/sysdeps/x86/tst-stack-align.h b/sysdeps/x86/tst-stack-align.h +new file mode 100644 +index 00000000..02ecc72d +--- /dev/null ++++ b/sysdeps/x86/tst-stack-align.h +@@ -0,0 +1,28 @@ ++/* Check stack alignment. X86 version. ++ Copyright (C) 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 ++ . */ ++ ++typedef struct { int i[16]; } int_al16 __attribute__((aligned (16))); ++ ++#define TEST_STACK_ALIGN_INIT() \ ++ ({ \ ++ int_al16 _m; \ ++ printf ("int_al16: %p %zu\n", &_m, __alignof (int_al16)); \ ++ is_aligned (&_m, __alignof (int_al16)); \ ++ }) ++ ++#include_next +diff --git a/sysdeps/x86_64/tst-stack-align.h b/sysdeps/x86_64/tst-stack-align.h +deleted file mode 100644 +index b2ef77f6..00000000 +--- a/sysdeps/x86_64/tst-stack-align.h ++++ /dev/null +@@ -1,46 +0,0 @@ +-/* Copyright (C) 2003-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 TEST_STACK_ALIGN() \ +- ({ \ +- /* AMD64 ABI mandates 16byte aligned stack. \ +- Unfortunately, current GCC doesn't support __int128 or __float128 \ +- types, so use aligned attribute instead. */ \ +- struct _S \ +- { \ +- int _i __attribute__((aligned (16))); \ +- int _pad[3]; \ +- } _s = { ._i = 18 }; \ +- double _d = 12.0; \ +- long double _ld = 15.0; \ +- int _ret = 0; \ +- printf ("__int128: %d %p %zu\n", _s._i, &_s, __alignof (_s)); \ +- if ((((uintptr_t) &_s) & (__alignof (_s) - 1)) != 0) \ +- _ret = 1; \ +- \ +- printf ("double: %g %p %zu\n", _d, &_d, __alignof (double)); \ +- if ((((uintptr_t) &_d) & (__alignof (double) - 1)) != 0) \ +- _ret = 1; \ +- \ +- printf ("ldouble: %Lg %p %zu\n", _ld, &_ld, __alignof (long double)); \ +- if ((((uintptr_t) &_ld) & (__alignof (long double) - 1)) != 0) \ +- _ret = 1; \ +- _ret; \ +- }) +-- +2.27.0 + diff --git a/glibc-Support-target-specific-ALIGN-for-variable-alignment-4.patch b/glibc-Support-target-specific-ALIGN-for-variable-alignment-4.patch new file mode 100644 index 0000000..d7552e1 --- /dev/null +++ b/glibc-Support-target-specific-ALIGN-for-variable-alignment-4.patch @@ -0,0 +1,171 @@ +From 2e86602d21fcaa8353c529f2f6768125396da39f Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Wed, 19 Jul 2023 23:12:30 +0800 +Subject: [PATCH 5/6] Support target specific ALIGN for variable alignment test + [BZ #28676] + +Add to support target specific ALIGN for variable +alignment test: + +1. Alpha: Use 0x10000. +2. MicroBlaze and Nios II: Use 0x8000. +3. All others: Use 0x200000. + +Backport from master commit: 4435c29 + +Reviewed-by: Adhemerval Zanella +Signed-off-by: Rongwei Wang +--- + elf/tst-align3.c | 4 +--- + elf/tst-alignmod3.c | 4 +--- + sysdeps/alpha/tst-file-align.h | 20 ++++++++++++++++++++ + sysdeps/generic/tst-file-align.h | 20 ++++++++++++++++++++ + sysdeps/microblaze/tst-file-align.h | 20 ++++++++++++++++++++ + sysdeps/nios2/tst-file-align.h | 20 ++++++++++++++++++++ + 6 files changed, 82 insertions(+), 6 deletions(-) + create mode 100644 sysdeps/alpha/tst-file-align.h + create mode 100644 sysdeps/generic/tst-file-align.h + create mode 100644 sysdeps/microblaze/tst-file-align.h + create mode 100644 sysdeps/nios2/tst-file-align.h + +diff --git a/elf/tst-align3.c b/elf/tst-align3.c +index ac86d623..87a8ff81 100644 +--- a/elf/tst-align3.c ++++ b/elf/tst-align3.c +@@ -17,11 +17,9 @@ + . */ + + #include ++#include + #include + +-/* This should cover all possible page sizes we currently support. */ +-#define ALIGN 0x200000 +- + int bar __attribute__ ((aligned (ALIGN))) = 1; + + extern int do_load_test (void); +diff --git a/elf/tst-alignmod3.c b/elf/tst-alignmod3.c +index 0d33f237..9520c352 100644 +--- a/elf/tst-alignmod3.c ++++ b/elf/tst-alignmod3.c +@@ -17,11 +17,9 @@ + . */ + + #include ++#include + #include + +-/* This should cover all possible page sizes we currently support. */ +-#define ALIGN 0x200000 +- + int foo __attribute__ ((aligned (ALIGN))) = 1; + + void +diff --git a/sysdeps/alpha/tst-file-align.h b/sysdeps/alpha/tst-file-align.h +new file mode 100644 +index 00000000..8fc3c940 +--- /dev/null ++++ b/sysdeps/alpha/tst-file-align.h +@@ -0,0 +1,20 @@ ++/* Check file alignment. Alpha version. ++ Copyright (C) 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 should cover all possible alignments we currently support. */ ++#define ALIGN 0x10000 +diff --git a/sysdeps/generic/tst-file-align.h b/sysdeps/generic/tst-file-align.h +new file mode 100644 +index 00000000..6ee6783a +--- /dev/null ++++ b/sysdeps/generic/tst-file-align.h +@@ -0,0 +1,20 @@ ++/* Check file alignment. Generic version. ++ Copyright (C) 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 should cover all possible page sizes we currently support. */ ++#define ALIGN 0x200000 +diff --git a/sysdeps/microblaze/tst-file-align.h b/sysdeps/microblaze/tst-file-align.h +new file mode 100644 +index 00000000..43c58b29 +--- /dev/null ++++ b/sysdeps/microblaze/tst-file-align.h +@@ -0,0 +1,20 @@ ++/* Check file alignment. MicroBlaze version. ++ Copyright (C) 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 should cover all possible alignments we currently support. */ ++#define ALIGN 0x8000 +diff --git a/sysdeps/nios2/tst-file-align.h b/sysdeps/nios2/tst-file-align.h +new file mode 100644 +index 00000000..589a2d5a +--- /dev/null ++++ b/sysdeps/nios2/tst-file-align.h +@@ -0,0 +1,20 @@ ++/* Check file alignment. Nios II version. ++ Copyright (C) 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 should cover all possible alignments we currently support. */ ++#define ALIGN 0x8000 +-- +2.27.0 + diff --git a/glibc-elf-Align-argument-of-__munmap-to-page-size-BZ-28676-3.patch b/glibc-elf-Align-argument-of-__munmap-to-page-size-BZ-28676-3.patch new file mode 100644 index 0000000..11417e6 --- /dev/null +++ b/glibc-elf-Align-argument-of-__munmap-to-page-size-BZ-28676-3.patch @@ -0,0 +1,36 @@ +From bf126f79dff0370d1e52ef8193da7fd593c37833 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Wed, 19 Jul 2023 23:10:48 +0800 +Subject: [PATCH 4/6] elf: Align argument of __munmap to page size [BZ #28676] + +On Linux/x86-64, for elf/tst-align3, we now get + +munmap(0x7f88f9401000, 1126424) = 0 + +instead of + +munmap(0x7f1615200018, 544768) = -1 EINVAL (Invalid argument) + +Backport from master commit: fd6062e + +Reviewed-by: Florian Weimer +Signed-off-by: Rongwei Wang +--- + elf/dl-map-segments.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/elf/dl-map-segments.h b/elf/dl-map-segments.h +index 61ba04cd..f1f7ad88 100644 +--- a/elf/dl-map-segments.h ++++ b/elf/dl-map-segments.h +@@ -55,6 +55,7 @@ _dl_map_segment (const struct loadcmd *c, ElfW(Addr) mappref, + if (delta) + __munmap ((void *) map_start, delta); + ElfW(Addr) map_end = map_start_aligned + maplength; ++ map_end = ALIGN_UP (map_end, GLRO(dl_pagesize)); + delta = map_start + maplen - map_end; + if (delta) + __munmap ((void *) map_end, delta); +-- +2.27.0 + diff --git a/glibc-elf-Fix-tst-align3.patch b/glibc-elf-Fix-tst-align3.patch new file mode 100644 index 0000000..194d142 --- /dev/null +++ b/glibc-elf-Fix-tst-align3.patch @@ -0,0 +1,40 @@ +From 8b39d3b4bf2fc49ab31f31cf30aa80104afa3432 Mon Sep 17 00:00:00 2001 +From: Adhemerval Zanella +Date: Wed, 19 Jul 2023 23:14:33 +0800 +Subject: [PATCH 6/6] elf: Fix tst-align3 + +The elf/tst-align3.c declares the function using a wrong prototype. + +Checked on aarch64-linux-gnu. + +Signed-off-by: Rongwei Wang +--- + elf/tst-align3.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/elf/tst-align3.c b/elf/tst-align3.c +index 87a8ff81..731dd59f 100644 +--- a/elf/tst-align3.c ++++ b/elf/tst-align3.c +@@ -22,7 +22,7 @@ + + int bar __attribute__ ((aligned (ALIGN))) = 1; + +-extern int do_load_test (void); ++extern void do_load_test (void); + + static int + do_test (void) +@@ -30,7 +30,8 @@ do_test (void) + printf ("bar: %p\n", &bar); + TEST_VERIFY (is_aligned (&bar, ALIGN) == 0); + +- return do_load_test (); ++ do_load_test (); ++ return 0; + } + + #include +-- +2.27.0 + diff --git a/glibc-elf-Properly-align-PT_LOAD-segments-BZ-28676-1.patch b/glibc-elf-Properly-align-PT_LOAD-segments-BZ-28676-1.patch new file mode 100644 index 0000000..a1b6c6b --- /dev/null +++ b/glibc-elf-Properly-align-PT_LOAD-segments-BZ-28676-1.patch @@ -0,0 +1,137 @@ +From fe5893121176136b0ae3a5f9198536feeb6f64f8 Mon Sep 17 00:00:00 2001 +From: Rongwei Wang +Date: Wed, 19 Jul 2023 23:05:39 +0800 +Subject: [PATCH 2/6] elf: Properly align PT_LOAD segments [BZ #28676] + +When PT_LOAD segment alignment > the page size, allocate enough space to +ensure that the segment can be properly aligned. This change helps code +segments use huge pages become simple and available. + +This fixes [BZ #28676]. + +Backport from master commit: 718fdd8 + +Signed-off-by: Xu Yu +Signed-off-by: Rongwei Wang +--- + elf/dl-load.c | 2 ++ + elf/dl-load.h | 3 ++- + elf/dl-map-segments.h | 50 +++++++++++++++++++++++++++++++++++++++---- + 3 files changed, 50 insertions(+), 5 deletions(-) + +diff --git a/elf/dl-load.c b/elf/dl-load.c +index 0b45e6e3..132e4233 100644 +--- a/elf/dl-load.c ++++ b/elf/dl-load.c +@@ -1,5 +1,6 @@ + /* Map in a shared object's segments from the file. + Copyright (C) 1995-2018 Free Software Foundation, Inc. ++ Copyright The GNU Toolchain Authors. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -1076,6 +1077,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, + c->mapend = ALIGN_UP (ph->p_vaddr + ph->p_filesz, GLRO(dl_pagesize)); + c->dataend = ph->p_vaddr + ph->p_filesz; + c->allocend = ph->p_vaddr + ph->p_memsz; ++ c->mapalign = ph->p_align; + c->mapoff = ALIGN_DOWN (ph->p_offset, GLRO(dl_pagesize)); + + /* Determine whether there is a gap between the last segment +diff --git a/elf/dl-load.h b/elf/dl-load.h +index 66ea2e92..d9f648ea 100644 +--- a/elf/dl-load.h ++++ b/elf/dl-load.h +@@ -1,5 +1,6 @@ + /* Map in a shared object's segments from the file. + Copyright (C) 1995-2018 Free Software Foundation, Inc. ++ Copyright The GNU Toolchain Authors. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -74,7 +75,7 @@ ELF_PREFERRED_ADDRESS_DATA; + Its details have been expanded out and converted. */ + struct loadcmd + { +- ElfW(Addr) mapstart, mapend, dataend, allocend; ++ ElfW(Addr) mapstart, mapend, dataend, allocend, mapalign; + ElfW(Off) mapoff; + int prot; /* PROT_* bits. */ + }; +diff --git a/elf/dl-map-segments.h b/elf/dl-map-segments.h +index 084076a2..61ba04cd 100644 +--- a/elf/dl-map-segments.h ++++ b/elf/dl-map-segments.h +@@ -1,5 +1,6 @@ + /* Map in a shared object's segments. Generic version. + Copyright (C) 1995-2018 Free Software Foundation, Inc. ++ Copyright The GNU Toolchain Authors. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -18,6 +19,50 @@ + + #include + ++/* Map a segment and align it properly. */ ++ ++static __always_inline ElfW(Addr) ++_dl_map_segment (const struct loadcmd *c, ElfW(Addr) mappref, ++ const size_t maplength, int fd) ++{ ++ if (__glibc_likely (c->mapalign <= GLRO(dl_pagesize))) ++ return (ElfW(Addr)) __mmap ((void *) mappref, maplength, c->prot, ++ MAP_COPY|MAP_FILE, fd, c->mapoff); ++ ++ /* If the segment alignment > the page size, allocate enough space to ++ ensure that the segment can be properly aligned. */ ++ ElfW(Addr) maplen = (maplength >= c->mapalign ++ ? (maplength + c->mapalign) ++ : (2 * c->mapalign)); ++ ElfW(Addr) map_start = (ElfW(Addr)) __mmap ((void *) mappref, maplen, ++ PROT_NONE, ++ MAP_ANONYMOUS|MAP_PRIVATE, ++ -1, 0); ++ if (__glibc_unlikely ((void *) map_start == MAP_FAILED)) ++ return map_start; ++ ++ ElfW(Addr) map_start_aligned = ALIGN_UP (map_start, c->mapalign); ++ map_start_aligned = (ElfW(Addr)) __mmap ((void *) map_start_aligned, ++ maplength, c->prot, ++ MAP_COPY|MAP_FILE|MAP_FIXED, ++ fd, c->mapoff); ++ if (__glibc_unlikely ((void *) map_start_aligned == MAP_FAILED)) ++ __munmap ((void *) map_start, maplen); ++ else ++ { ++ /* Unmap the unused regions. */ ++ ElfW(Addr) delta = map_start_aligned - map_start; ++ if (delta) ++ __munmap ((void *) map_start, delta); ++ ElfW(Addr) map_end = map_start_aligned + maplength; ++ delta = map_start + maplen - map_end; ++ if (delta) ++ __munmap ((void *) map_end, delta); ++ } ++ ++ return map_start_aligned; ++} ++ + /* This implementation assumes (as does the corresponding implementation + of _dl_unmap_segments, in dl-unmap-segments.h) that shared objects + are always laid out with all segments contiguous (or with gaps +@@ -53,10 +98,7 @@ _dl_map_segments (struct link_map *l, int fd, + - MAP_BASE_ADDR (l)); + + /* Remember which part of the address space this object uses. */ +- l->l_map_start = (ElfW(Addr)) __mmap ((void *) mappref, maplength, +- c->prot, +- MAP_COPY|MAP_FILE, +- fd, c->mapoff); ++ l->l_map_start = _dl_map_segment (c, mappref, maplength, fd); + if (__glibc_unlikely ((void *) l->l_map_start == MAP_FAILED)) + return DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT; + +-- +2.27.0 + diff --git a/glibc.spec b/glibc.spec index f3de45f..9eefa49 100644 --- a/glibc.spec +++ b/glibc.spec @@ -1,6 +1,7 @@ +%global anolis_release .0.4 %define glibcsrcdir glibc-2.28 %define glibcversion 2.28 -%define glibcrelease 225%{?dist} +%define glibcrelease 225%{anolis_release}%{?dist} # Pre-release tarballs are pulled in from git using a command that is # effectively: # @@ -1037,6 +1038,13 @@ Patch849: glibc-RHEL-2434.patch Patch850: glibc-RHEL-2422.patch Patch851: glibc-RHEL-3035.patch +Patch2000: glibc-Properly-check-stack-alignment-BZ-27901.patch +Patch2001: glibc-elf-Properly-align-PT_LOAD-segments-BZ-28676-1.patch +Patch2002: glibc-Add-a-testcase-to-check-alignment-of-PT_LOAD-segment-2.patch +Patch2003: glibc-elf-Align-argument-of-__munmap-to-page-size-BZ-28676-3.patch +Patch2004: glibc-Support-target-specific-ALIGN-for-variable-alignment-4.patch +Patch2005: glibc-elf-Fix-tst-align3.patch + ############################################################################## # Continued list of core "glibc" package information: ############################################################################## @@ -2866,6 +2874,9 @@ fi %files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared %changelog +* Sun Oct 08 2023 Rongwei Wang - 2.28-225.0.4.6 +- elf: Properly align PT_LOAD segments + * Wed Sep 20 2023 Siddhesh Poyarekar - 2.28-236.6 - CVE-2023-4911 glibc: buffer overflow in ld.so leading to privilege escalation (RHEL-3035) From a7344490118fdb577f3da2a0ad96fb6432e97ab1 Mon Sep 17 00:00:00 2001 From: Xing Li Date: Mon, 31 Jul 2023 20:34:12 +0800 Subject: [PATCH 3/4] Add LoongArch support --- ....c-to-suit-kernel-struct-sigcontext-.patch | 34 + glibc-Sync-to-lnd-35-for-LoongArch.patch | 26504 ++++++++++++++++ glibc.spec | 9 + 3 files changed, 26547 insertions(+) create mode 100644 Fix-tst-cancel21.c-to-suit-kernel-struct-sigcontext-.patch create mode 100644 glibc-Sync-to-lnd-35-for-LoongArch.patch diff --git a/Fix-tst-cancel21.c-to-suit-kernel-struct-sigcontext-.patch b/Fix-tst-cancel21.c-to-suit-kernel-struct-sigcontext-.patch new file mode 100644 index 0000000..62b5dab --- /dev/null +++ b/Fix-tst-cancel21.c-to-suit-kernel-struct-sigcontext-.patch @@ -0,0 +1,34 @@ +From c5de7c407853b807e8d0c764e6325bb1311f39cd Mon Sep 17 00:00:00 2001 +From: Xing Li +Date: Tue, 4 Jul 2023 15:10:03 +0800 +Subject: [PATCH 2/2] Fix tst-cancel21.c to suit kernel struct sigcontext + change. * nptl/tst-cancel21.c + +--- + nptl/tst-cancel21.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/nptl/tst-cancel21.c b/nptl/tst-cancel21.c +index b10fdbc1..a3653f21 100644 +--- a/nptl/tst-cancel21.c ++++ b/nptl/tst-cancel21.c +@@ -217,14 +217,14 @@ static int + do_test (void) + { + stack_t ss; +- ss.ss_sp = malloc (2 * SIGSTKSZ); ++ ss.ss_sp = malloc (4 * SIGSTKSZ); + if (ss.ss_sp == NULL) + { + puts ("failed to allocate alternate stack"); + return 1; + } + ss.ss_flags = 0; +- ss.ss_size = 2 * SIGSTKSZ; ++ ss.ss_size = 4 * SIGSTKSZ; + if (sigaltstack (&ss, NULL) < 0) + { + printf ("sigaltstack failed %m\n"); +-- +2.27.0 + diff --git a/glibc-Sync-to-lnd-35-for-LoongArch.patch b/glibc-Sync-to-lnd-35-for-LoongArch.patch new file mode 100644 index 0000000..6980fb1 --- /dev/null +++ b/glibc-Sync-to-lnd-35-for-LoongArch.patch @@ -0,0 +1,26504 @@ +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,27 @@ ++# Order of tunables in RHEL 8.7.0. ++@order glibc.rtld.nns ++@order glibc.elision.skip_lock_after_retries ++@order glibc.malloc.trim_threshold ++@order glibc.malloc.perturb ++@order glibc.elision.tries ++@order glibc.elision.enable ++@order glibc.malloc.mxfast ++@order glibc.elision.skip_lock_busy ++@order glibc.malloc.top_pad ++@order glibc.cpu.hwcaps ++@order glibc.cpu.hwcap_mask ++@order glibc.malloc.mmap_max ++@order glibc.elision.skip_trylock_internal_abort ++@order glibc.malloc.tcache_unsorted_limit ++@order glibc.elision.skip_lock_internal_abort ++@order glibc.malloc.arena_max ++@order glibc.malloc.mmap_threshold ++@order glibc.malloc.tcache_count ++@order glibc.malloc.arena_test ++@order glibc.rtld.optional_static_tls ++@order glibc.malloc.tcache_max ++@order glibc.malloc.check ++ ++# Tunables added in RHEL 8.8.0 ++@order glibc.rtld.dynamic_sort ++ +diff --git a/sysdeps/unix/sysv/linux/loongarch/getcontext.S b/sysdeps/unix/sysv/linux/loongarch/getcontext.S +new file mode 100644 +index 00000000..9c28d958 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/getcontext.S +@@ -0,0 +1,72 @@ ++/* Save current context. ++ Copyright (C) 2009-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++#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 + diff --git a/glibc.spec b/glibc.spec index 9eefa49..67eaab4 100644 --- a/glibc.spec +++ b/glibc.spec @@ -1045,6 +1045,9 @@ Patch2003: glibc-elf-Align-argument-of-__munmap-to-page-size-BZ-28676-3.patch Patch2004: glibc-Support-target-specific-ALIGN-for-variable-alignment-4.patch Patch2005: glibc-elf-Fix-tst-align3.patch +Patch2006: glibc-Sync-to-lnd-35-for-LoongArch.patch +Patch2007: Fix-tst-cancel21.c-to-suit-kernel-struct-sigcontext-.patch + ############################################################################## # Continued list of core "glibc" package information: ############################################################################## @@ -1724,6 +1727,11 @@ build() %ifarch %{ix86} --disable-multi-arch \ %endif +%ifarch loongarch64 + --enable-stackguard-randomization \ + --with-selinux \ + --enable-shared \ +%endif %if %{without werror} --disable-werror \ %endif @@ -2876,6 +2884,7 @@ fi %changelog * Sun Oct 08 2023 Rongwei Wang - 2.28-225.0.4.6 - elf: Properly align PT_LOAD segments +- Sync loongarch64 code to lnd.35. (lixing@loongson.cn) * Wed Sep 20 2023 Siddhesh Poyarekar - 2.28-236.6 - CVE-2023-4911 glibc: buffer overflow in ld.so leading to privilege escalation (RHEL-3035) From 61bbd0d77b0dadd03b6b238361550f218af57712 Mon Sep 17 00:00:00 2001 From: Funda Wang Date: Fri, 4 Aug 2023 14:36:40 +0800 Subject: [PATCH 4/4] Add patch for gb18030-2022 from upstream bug#30243 --- glibc-gb18030-2022-bug30243.patch | 797 ++++++++++++++++++++++++++++++ glibc.spec | 4 + 2 files changed, 801 insertions(+) create mode 100644 glibc-gb18030-2022-bug30243.patch diff --git a/glibc-gb18030-2022-bug30243.patch b/glibc-gb18030-2022-bug30243.patch new file mode 100644 index 0000000..8e87f34 --- /dev/null +++ b/glibc-gb18030-2022-bug30243.patch @@ -0,0 +1,797 @@ +diff --git a/iconvdata/gb18030.c b/iconvdata/gb18030.c +index 0b03b9bb..ca383dc0 100644 +--- a/iconvdata/gb18030.c ++++ b/iconvdata/gb18030.c +@@ -6020,49 +6020,50 @@ static const uint16_t __twobyte_to_ucs[] = + [0x5dc2] = 0xfa0e, [0x5dc3] = 0xfa0f, [0x5dc4] = 0xfa11, [0x5dc5] = 0xfa13, + [0x5dc6] = 0xfa14, [0x5dc7] = 0xfa18, [0x5dc8] = 0xfa1f, [0x5dc9] = 0xfa20, + [0x5dca] = 0xfa21, [0x5dcb] = 0xfa23, [0x5dcc] = 0xfa24, [0x5dcd] = 0xfa27, +- [0x5dce] = 0xfa28, [0x5dcf] = 0xfa29, [0x5dd0] = 0x2e81, [0x5dd4] = 0x2e84, +- [0x5dd5] = 0x3473, [0x5dd6] = 0x3447, [0x5dd7] = 0x2e88, [0x5dd8] = 0x2e8b, +- [0x5dd9] = 0x9fb4, [0x5dda] = 0x359e, [0x5ddb] = 0x361a, [0x5ddc] = 0x360e, +- [0x5ddd] = 0x2e8c, [0x5dde] = 0x2e97, [0x5ddf] = 0x396e, [0x5de0] = 0x3918, +- [0x5de1] = 0x9fb5, [0x5de2] = 0x39cf, [0x5de3] = 0x39df, [0x5de4] = 0x3a73, +- [0x5de5] = 0x39d0, [0x5de6] = 0x9fb6, [0x5de7] = 0x9fb7, [0x5de8] = 0x3b4e, +- [0x5de9] = 0x3c6e, [0x5dea] = 0x3ce0, [0x5deb] = 0x2ea7, [0x5ded] = 0x9fb8, ++ [0x5dce] = 0xfa28, [0x5dcf] = 0xfa29, [0x5dd0] = 0x2e81, [0x5dd1] = 0xe816, ++ [0x5dd2] = 0xe817, [0x5dd3] = 0xe818, [0x5dd4] = 0x2e84, [0x5dd5] = 0x3473, ++ [0x5dd6] = 0x3447, [0x5dd7] = 0x2e88, [0x5dd8] = 0x2e8b, [0x5dd9] = 0x9fb4, ++ [0x5dda] = 0x359e, [0x5ddb] = 0x361a, [0x5ddc] = 0x360e, [0x5ddd] = 0x2e8c, ++ [0x5dde] = 0x2e97, [0x5ddf] = 0x396e, [0x5de0] = 0x3918, [0x5de1] = 0x9fb5, ++ [0x5de2] = 0x39cf, [0x5de3] = 0x39df, [0x5de4] = 0x3a73, [0x5de5] = 0x39d0, ++ [0x5de6] = 0x9fb6, [0x5de7] = 0x9fb7, [0x5de8] = 0x3b4e, [0x5de9] = 0x3c6e, ++ [0x5dea] = 0x3ce0, [0x5deb] = 0x2ea7, [0x5dec] = 0xe831, [0x5ded] = 0x9fb8, + [0x5dee] = 0x2eaa, [0x5def] = 0x4056, [0x5df0] = 0x415f, [0x5df1] = 0x2eae, + [0x5df2] = 0x4337, [0x5df3] = 0x2eb3, [0x5df4] = 0x2eb6, [0x5df5] = 0x2eb7, +- [0x5df7] = 0x43b1, [0x5df8] = 0x43ac, [0x5df9] = 0x2ebb, [0x5dfa] = 0x43dd, +- [0x5dfb] = 0x44d6, [0x5dfc] = 0x4661, [0x5dfd] = 0x464c, [0x5dfe] = 0x9fb9, +- [0x5e00] = 0x4723, [0x5e01] = 0x4729, [0x5e02] = 0x477c, [0x5e03] = 0x478d, +- [0x5e04] = 0x2eca, [0x5e05] = 0x4947, [0x5e06] = 0x497a, [0x5e07] = 0x497d, +- [0x5e08] = 0x4982, [0x5e09] = 0x4983, [0x5e0a] = 0x4985, [0x5e0b] = 0x4986, +- [0x5e0c] = 0x499f, [0x5e0d] = 0x499b, [0x5e0e] = 0x49b7, [0x5e0f] = 0x49b6, +- [0x5e10] = 0x9fba, [0x5e12] = 0x4ca3, [0x5e13] = 0x4c9f, [0x5e14] = 0x4ca0, +- [0x5e15] = 0x4ca1, [0x5e16] = 0x4c77, [0x5e17] = 0x4ca2, [0x5e18] = 0x4d13, +- [0x5e19] = 0x4d14, [0x5e1a] = 0x4d15, [0x5e1b] = 0x4d16, [0x5e1c] = 0x4d17, +- [0x5e1d] = 0x4d18, [0x5e1e] = 0x4d19, [0x5e1f] = 0x4dae, [0x5e20] = 0x9fbb, +- [0x5e21] = 0xe468, [0x5e22] = 0xe469, [0x5e23] = 0xe46a, [0x5e24] = 0xe46b, +- [0x5e25] = 0xe46c, [0x5e26] = 0xe46d, [0x5e27] = 0xe46e, [0x5e28] = 0xe46f, +- [0x5e29] = 0xe470, [0x5e2a] = 0xe471, [0x5e2b] = 0xe472, [0x5e2c] = 0xe473, +- [0x5e2d] = 0xe474, [0x5e2e] = 0xe475, [0x5e2f] = 0xe476, [0x5e30] = 0xe477, +- [0x5e31] = 0xe478, [0x5e32] = 0xe479, [0x5e33] = 0xe47a, [0x5e34] = 0xe47b, +- [0x5e35] = 0xe47c, [0x5e36] = 0xe47d, [0x5e37] = 0xe47e, [0x5e38] = 0xe47f, +- [0x5e39] = 0xe480, [0x5e3a] = 0xe481, [0x5e3b] = 0xe482, [0x5e3c] = 0xe483, +- [0x5e3d] = 0xe484, [0x5e3e] = 0xe485, [0x5e3f] = 0xe486, [0x5e40] = 0xe487, +- [0x5e41] = 0xe488, [0x5e42] = 0xe489, [0x5e43] = 0xe48a, [0x5e44] = 0xe48b, +- [0x5e45] = 0xe48c, [0x5e46] = 0xe48d, [0x5e47] = 0xe48e, [0x5e48] = 0xe48f, +- [0x5e49] = 0xe490, [0x5e4a] = 0xe491, [0x5e4b] = 0xe492, [0x5e4c] = 0xe493, +- [0x5e4d] = 0xe494, [0x5e4e] = 0xe495, [0x5e4f] = 0xe496, [0x5e50] = 0xe497, +- [0x5e51] = 0xe498, [0x5e52] = 0xe499, [0x5e53] = 0xe49a, [0x5e54] = 0xe49b, +- [0x5e55] = 0xe49c, [0x5e56] = 0xe49d, [0x5e57] = 0xe49e, [0x5e58] = 0xe49f, +- [0x5e59] = 0xe4a0, [0x5e5a] = 0xe4a1, [0x5e5b] = 0xe4a2, [0x5e5c] = 0xe4a3, +- [0x5e5d] = 0xe4a4, [0x5e5e] = 0xe4a5, [0x5e5f] = 0xe4a6, [0x5e60] = 0xe4a7, +- [0x5e61] = 0xe4a8, [0x5e62] = 0xe4a9, [0x5e63] = 0xe4aa, [0x5e64] = 0xe4ab, +- [0x5e65] = 0xe4ac, [0x5e66] = 0xe4ad, [0x5e67] = 0xe4ae, [0x5e68] = 0xe4af, +- [0x5e69] = 0xe4b0, [0x5e6a] = 0xe4b1, [0x5e6b] = 0xe4b2, [0x5e6c] = 0xe4b3, +- [0x5e6d] = 0xe4b4, [0x5e6e] = 0xe4b5, [0x5e6f] = 0xe4b6, [0x5e70] = 0xe4b7, +- [0x5e71] = 0xe4b8, [0x5e72] = 0xe4b9, [0x5e73] = 0xe4ba, [0x5e74] = 0xe4bb, +- [0x5e75] = 0xe4bc, [0x5e76] = 0xe4bd, [0x5e77] = 0xe4be, [0x5e78] = 0xe4bf, +- [0x5e79] = 0xe4c0, [0x5e7a] = 0xe4c1, [0x5e7b] = 0xe4c2, [0x5e7c] = 0xe4c3, +- [0x5e7d] = 0xe4c4, [0x5e7e] = 0xe4c5, ++ [0x5df6] = 0xe83b, [0x5df7] = 0x43b1, [0x5df8] = 0x43ac, [0x5df9] = 0x2ebb, ++ [0x5dfa] = 0x43dd, [0x5dfb] = 0x44d6, [0x5dfc] = 0x4661, [0x5dfd] = 0x464c, ++ [0x5dfe] = 0x9fb9, [0x5e00] = 0x4723, [0x5e01] = 0x4729, [0x5e02] = 0x477c, ++ [0x5e03] = 0x478d, [0x5e04] = 0x2eca, [0x5e05] = 0x4947, [0x5e06] = 0x497a, ++ [0x5e07] = 0x497d, [0x5e08] = 0x4982, [0x5e09] = 0x4983, [0x5e0a] = 0x4985, ++ [0x5e0b] = 0x4986, [0x5e0c] = 0x499f, [0x5e0d] = 0x499b, [0x5e0e] = 0x49b7, ++ [0x5e0f] = 0x49b6, [0x5e10] = 0x9fba, [0x5e11] = 0xe855, [0x5e12] = 0x4ca3, ++ [0x5e13] = 0x4c9f, [0x5e14] = 0x4ca0, [0x5e15] = 0x4ca1, [0x5e16] = 0x4c77, ++ [0x5e17] = 0x4ca2, [0x5e18] = 0x4d13, [0x5e19] = 0x4d14, [0x5e1a] = 0x4d15, ++ [0x5e1b] = 0x4d16, [0x5e1c] = 0x4d17, [0x5e1d] = 0x4d18, [0x5e1e] = 0x4d19, ++ [0x5e1f] = 0x4dae, [0x5e20] = 0x9fbb, [0x5e21] = 0xe468, [0x5e22] = 0xe469, ++ [0x5e23] = 0xe46a, [0x5e24] = 0xe46b, [0x5e25] = 0xe46c, [0x5e26] = 0xe46d, ++ [0x5e27] = 0xe46e, [0x5e28] = 0xe46f, [0x5e29] = 0xe470, [0x5e2a] = 0xe471, ++ [0x5e2b] = 0xe472, [0x5e2c] = 0xe473, [0x5e2d] = 0xe474, [0x5e2e] = 0xe475, ++ [0x5e2f] = 0xe476, [0x5e30] = 0xe477, [0x5e31] = 0xe478, [0x5e32] = 0xe479, ++ [0x5e33] = 0xe47a, [0x5e34] = 0xe47b, [0x5e35] = 0xe47c, [0x5e36] = 0xe47d, ++ [0x5e37] = 0xe47e, [0x5e38] = 0xe47f, [0x5e39] = 0xe480, [0x5e3a] = 0xe481, ++ [0x5e3b] = 0xe482, [0x5e3c] = 0xe483, [0x5e3d] = 0xe484, [0x5e3e] = 0xe485, ++ [0x5e3f] = 0xe486, [0x5e40] = 0xe487, [0x5e41] = 0xe488, [0x5e42] = 0xe489, ++ [0x5e43] = 0xe48a, [0x5e44] = 0xe48b, [0x5e45] = 0xe48c, [0x5e46] = 0xe48d, ++ [0x5e47] = 0xe48e, [0x5e48] = 0xe48f, [0x5e49] = 0xe490, [0x5e4a] = 0xe491, ++ [0x5e4b] = 0xe492, [0x5e4c] = 0xe493, [0x5e4d] = 0xe494, [0x5e4e] = 0xe495, ++ [0x5e4f] = 0xe496, [0x5e50] = 0xe497, [0x5e51] = 0xe498, [0x5e52] = 0xe499, ++ [0x5e53] = 0xe49a, [0x5e54] = 0xe49b, [0x5e55] = 0xe49c, [0x5e56] = 0xe49d, ++ [0x5e57] = 0xe49e, [0x5e58] = 0xe49f, [0x5e59] = 0xe4a0, [0x5e5a] = 0xe4a1, ++ [0x5e5b] = 0xe4a2, [0x5e5c] = 0xe4a3, [0x5e5d] = 0xe4a4, [0x5e5e] = 0xe4a5, ++ [0x5e5f] = 0xe4a6, [0x5e60] = 0xe4a7, [0x5e61] = 0xe4a8, [0x5e62] = 0xe4a9, ++ [0x5e63] = 0xe4aa, [0x5e64] = 0xe4ab, [0x5e65] = 0xe4ac, [0x5e66] = 0xe4ad, ++ [0x5e67] = 0xe4ae, [0x5e68] = 0xe4af, [0x5e69] = 0xe4b0, [0x5e6a] = 0xe4b1, ++ [0x5e6b] = 0xe4b2, [0x5e6c] = 0xe4b3, [0x5e6d] = 0xe4b4, [0x5e6e] = 0xe4b5, ++ [0x5e6f] = 0xe4b6, [0x5e70] = 0xe4b7, [0x5e71] = 0xe4b8, [0x5e72] = 0xe4b9, ++ [0x5e73] = 0xe4ba, [0x5e74] = 0xe4bb, [0x5e75] = 0xe4bc, [0x5e76] = 0xe4bd, ++ [0x5e77] = 0xe4be, [0x5e78] = 0xe4bf, [0x5e79] = 0xe4c0, [0x5e7a] = 0xe4c1, ++ [0x5e7b] = 0xe4c2, [0x5e7c] = 0xe4c3, [0x5e7d] = 0xe4c4, [0x5e7e] = 0xe4c5, + }; + + /* Table for GB18030 -> UCS-4, containing the four-byte characters only, +@@ -8691,7 +8692,9 @@ static const uint16_t __fourbyte_to_ucs[0x99e2 - 6637 - 2110 - 14404 - 4295] = + [0x2838] = 0x9fa6, [0x2839] = 0x9fa7, [0x283a] = 0x9fa8, [0x283b] = 0x9fa9, + [0x283c] = 0x9faa, [0x283d] = 0x9fab, [0x283e] = 0x9fac, [0x283f] = 0x9fad, + [0x2840] = 0x9fae, [0x2841] = 0x9faf, [0x2842] = 0x9fb0, [0x2843] = 0x9fb1, +- [0x2844] = 0x9fb2, [0x2845] = 0x9fb3, [0x284e] = 0xe76c, [0x284f] = 0xe7c8, ++ [0x2844] = 0x9fb2, [0x2845] = 0x9fb3, [0x2846] = 0xe81e, [0x2847] = 0xe826, ++ [0x2848] = 0xe82b, [0x2849] = 0xe82c, [0x284a] = 0xe832, [0x284b] = 0xe843, ++ [0x284c] = 0xe854, [0x284d] = 0xe864, [0x284e] = 0xe76c, [0x284f] = 0xe7c8, + [0x2850] = 0xe7e7, [0x2851] = 0xe7e8, [0x2852] = 0xe7e9, [0x2853] = 0xe7ea, + [0x2854] = 0xe7eb, [0x2855] = 0xe7ec, [0x2856] = 0xe7ed, [0x2857] = 0xe7ee, + [0x2858] = 0xe7ef, [0x2859] = 0xe7f0, [0x285a] = 0xe7f1, [0x285b] = 0xe7f2, +@@ -9019,84 +9022,86 @@ static const uint16_t __fourbyte_to_ucs[0x99e2 - 6637 - 2110 - 14404 - 4295] = + [0x2d60] = 0xfe02, [0x2d61] = 0xfe03, [0x2d62] = 0xfe04, [0x2d63] = 0xfe05, + [0x2d64] = 0xfe06, [0x2d65] = 0xfe07, [0x2d66] = 0xfe08, [0x2d67] = 0xfe09, + [0x2d68] = 0xfe0a, [0x2d69] = 0xfe0b, [0x2d6a] = 0xfe0c, [0x2d6b] = 0xfe0d, +- [0x2d6c] = 0xfe0e, [0x2d6d] = 0xfe0f, [0x2d78] = 0xfe1a, [0x2d79] = 0xfe1b, +- [0x2d7a] = 0xfe1c, [0x2d7b] = 0xfe1d, [0x2d7c] = 0xfe1e, [0x2d7d] = 0xfe1f, +- [0x2d7e] = 0xfe20, [0x2d7f] = 0xfe21, [0x2d80] = 0xfe22, [0x2d81] = 0xfe23, +- [0x2d82] = 0xfe24, [0x2d83] = 0xfe25, [0x2d84] = 0xfe26, [0x2d85] = 0xfe27, +- [0x2d86] = 0xfe28, [0x2d87] = 0xfe29, [0x2d88] = 0xfe2a, [0x2d89] = 0xfe2b, +- [0x2d8a] = 0xfe2c, [0x2d8b] = 0xfe2d, [0x2d8c] = 0xfe2e, [0x2d8d] = 0xfe2f, +- [0x2d8e] = 0xfe32, [0x2d8f] = 0xfe45, [0x2d90] = 0xfe46, [0x2d91] = 0xfe47, +- [0x2d92] = 0xfe48, [0x2d93] = 0xfe53, [0x2d94] = 0xfe58, [0x2d95] = 0xfe67, +- [0x2d96] = 0xfe6c, [0x2d97] = 0xfe6d, [0x2d98] = 0xfe6e, [0x2d99] = 0xfe6f, +- [0x2d9a] = 0xfe70, [0x2d9b] = 0xfe71, [0x2d9c] = 0xfe72, [0x2d9d] = 0xfe73, +- [0x2d9e] = 0xfe74, [0x2d9f] = 0xfe75, [0x2da0] = 0xfe76, [0x2da1] = 0xfe77, +- [0x2da2] = 0xfe78, [0x2da3] = 0xfe79, [0x2da4] = 0xfe7a, [0x2da5] = 0xfe7b, +- [0x2da6] = 0xfe7c, [0x2da7] = 0xfe7d, [0x2da8] = 0xfe7e, [0x2da9] = 0xfe7f, +- [0x2daa] = 0xfe80, [0x2dab] = 0xfe81, [0x2dac] = 0xfe82, [0x2dad] = 0xfe83, +- [0x2dae] = 0xfe84, [0x2daf] = 0xfe85, [0x2db0] = 0xfe86, [0x2db1] = 0xfe87, +- [0x2db2] = 0xfe88, [0x2db3] = 0xfe89, [0x2db4] = 0xfe8a, [0x2db5] = 0xfe8b, +- [0x2db6] = 0xfe8c, [0x2db7] = 0xfe8d, [0x2db8] = 0xfe8e, [0x2db9] = 0xfe8f, +- [0x2dba] = 0xfe90, [0x2dbb] = 0xfe91, [0x2dbc] = 0xfe92, [0x2dbd] = 0xfe93, +- [0x2dbe] = 0xfe94, [0x2dbf] = 0xfe95, [0x2dc0] = 0xfe96, [0x2dc1] = 0xfe97, +- [0x2dc2] = 0xfe98, [0x2dc3] = 0xfe99, [0x2dc4] = 0xfe9a, [0x2dc5] = 0xfe9b, +- [0x2dc6] = 0xfe9c, [0x2dc7] = 0xfe9d, [0x2dc8] = 0xfe9e, [0x2dc9] = 0xfe9f, +- [0x2dca] = 0xfea0, [0x2dcb] = 0xfea1, [0x2dcc] = 0xfea2, [0x2dcd] = 0xfea3, +- [0x2dce] = 0xfea4, [0x2dcf] = 0xfea5, [0x2dd0] = 0xfea6, [0x2dd1] = 0xfea7, +- [0x2dd2] = 0xfea8, [0x2dd3] = 0xfea9, [0x2dd4] = 0xfeaa, [0x2dd5] = 0xfeab, +- [0x2dd6] = 0xfeac, [0x2dd7] = 0xfead, [0x2dd8] = 0xfeae, [0x2dd9] = 0xfeaf, +- [0x2dda] = 0xfeb0, [0x2ddb] = 0xfeb1, [0x2ddc] = 0xfeb2, [0x2ddd] = 0xfeb3, +- [0x2dde] = 0xfeb4, [0x2ddf] = 0xfeb5, [0x2de0] = 0xfeb6, [0x2de1] = 0xfeb7, +- [0x2de2] = 0xfeb8, [0x2de3] = 0xfeb9, [0x2de4] = 0xfeba, [0x2de5] = 0xfebb, +- [0x2de6] = 0xfebc, [0x2de7] = 0xfebd, [0x2de8] = 0xfebe, [0x2de9] = 0xfebf, +- [0x2dea] = 0xfec0, [0x2deb] = 0xfec1, [0x2dec] = 0xfec2, [0x2ded] = 0xfec3, +- [0x2dee] = 0xfec4, [0x2def] = 0xfec5, [0x2df0] = 0xfec6, [0x2df1] = 0xfec7, +- [0x2df2] = 0xfec8, [0x2df3] = 0xfec9, [0x2df4] = 0xfeca, [0x2df5] = 0xfecb, +- [0x2df6] = 0xfecc, [0x2df7] = 0xfecd, [0x2df8] = 0xfece, [0x2df9] = 0xfecf, +- [0x2dfa] = 0xfed0, [0x2dfb] = 0xfed1, [0x2dfc] = 0xfed2, [0x2dfd] = 0xfed3, +- [0x2dfe] = 0xfed4, [0x2dff] = 0xfed5, [0x2e00] = 0xfed6, [0x2e01] = 0xfed7, +- [0x2e02] = 0xfed8, [0x2e03] = 0xfed9, [0x2e04] = 0xfeda, [0x2e05] = 0xfedb, +- [0x2e06] = 0xfedc, [0x2e07] = 0xfedd, [0x2e08] = 0xfede, [0x2e09] = 0xfedf, +- [0x2e0a] = 0xfee0, [0x2e0b] = 0xfee1, [0x2e0c] = 0xfee2, [0x2e0d] = 0xfee3, +- [0x2e0e] = 0xfee4, [0x2e0f] = 0xfee5, [0x2e10] = 0xfee6, [0x2e11] = 0xfee7, +- [0x2e12] = 0xfee8, [0x2e13] = 0xfee9, [0x2e14] = 0xfeea, [0x2e15] = 0xfeeb, +- [0x2e16] = 0xfeec, [0x2e17] = 0xfeed, [0x2e18] = 0xfeee, [0x2e19] = 0xfeef, +- [0x2e1a] = 0xfef0, [0x2e1b] = 0xfef1, [0x2e1c] = 0xfef2, [0x2e1d] = 0xfef3, +- [0x2e1e] = 0xfef4, [0x2e1f] = 0xfef5, [0x2e20] = 0xfef6, [0x2e21] = 0xfef7, +- [0x2e22] = 0xfef8, [0x2e23] = 0xfef9, [0x2e24] = 0xfefa, [0x2e25] = 0xfefb, +- [0x2e26] = 0xfefc, [0x2e27] = 0xfefd, [0x2e28] = 0xfefe, [0x2e29] = 0xfeff, +- [0x2e2a] = 0xff00, [0x2e2b] = 0xff5f, [0x2e2c] = 0xff60, [0x2e2d] = 0xff61, +- [0x2e2e] = 0xff62, [0x2e2f] = 0xff63, [0x2e30] = 0xff64, [0x2e31] = 0xff65, +- [0x2e32] = 0xff66, [0x2e33] = 0xff67, [0x2e34] = 0xff68, [0x2e35] = 0xff69, +- [0x2e36] = 0xff6a, [0x2e37] = 0xff6b, [0x2e38] = 0xff6c, [0x2e39] = 0xff6d, +- [0x2e3a] = 0xff6e, [0x2e3b] = 0xff6f, [0x2e3c] = 0xff70, [0x2e3d] = 0xff71, +- [0x2e3e] = 0xff72, [0x2e3f] = 0xff73, [0x2e40] = 0xff74, [0x2e41] = 0xff75, +- [0x2e42] = 0xff76, [0x2e43] = 0xff77, [0x2e44] = 0xff78, [0x2e45] = 0xff79, +- [0x2e46] = 0xff7a, [0x2e47] = 0xff7b, [0x2e48] = 0xff7c, [0x2e49] = 0xff7d, +- [0x2e4a] = 0xff7e, [0x2e4b] = 0xff7f, [0x2e4c] = 0xff80, [0x2e4d] = 0xff81, +- [0x2e4e] = 0xff82, [0x2e4f] = 0xff83, [0x2e50] = 0xff84, [0x2e51] = 0xff85, +- [0x2e52] = 0xff86, [0x2e53] = 0xff87, [0x2e54] = 0xff88, [0x2e55] = 0xff89, +- [0x2e56] = 0xff8a, [0x2e57] = 0xff8b, [0x2e58] = 0xff8c, [0x2e59] = 0xff8d, +- [0x2e5a] = 0xff8e, [0x2e5b] = 0xff8f, [0x2e5c] = 0xff90, [0x2e5d] = 0xff91, +- [0x2e5e] = 0xff92, [0x2e5f] = 0xff93, [0x2e60] = 0xff94, [0x2e61] = 0xff95, +- [0x2e62] = 0xff96, [0x2e63] = 0xff97, [0x2e64] = 0xff98, [0x2e65] = 0xff99, +- [0x2e66] = 0xff9a, [0x2e67] = 0xff9b, [0x2e68] = 0xff9c, [0x2e69] = 0xff9d, +- [0x2e6a] = 0xff9e, [0x2e6b] = 0xff9f, [0x2e6c] = 0xffa0, [0x2e6d] = 0xffa1, +- [0x2e6e] = 0xffa2, [0x2e6f] = 0xffa3, [0x2e70] = 0xffa4, [0x2e71] = 0xffa5, +- [0x2e72] = 0xffa6, [0x2e73] = 0xffa7, [0x2e74] = 0xffa8, [0x2e75] = 0xffa9, +- [0x2e76] = 0xffaa, [0x2e77] = 0xffab, [0x2e78] = 0xffac, [0x2e79] = 0xffad, +- [0x2e7a] = 0xffae, [0x2e7b] = 0xffaf, [0x2e7c] = 0xffb0, [0x2e7d] = 0xffb1, +- [0x2e7e] = 0xffb2, [0x2e7f] = 0xffb3, [0x2e80] = 0xffb4, [0x2e81] = 0xffb5, +- [0x2e82] = 0xffb6, [0x2e83] = 0xffb7, [0x2e84] = 0xffb8, [0x2e85] = 0xffb9, +- [0x2e86] = 0xffba, [0x2e87] = 0xffbb, [0x2e88] = 0xffbc, [0x2e89] = 0xffbd, +- [0x2e8a] = 0xffbe, [0x2e8b] = 0xffbf, [0x2e8c] = 0xffc0, [0x2e8d] = 0xffc1, +- [0x2e8e] = 0xffc2, [0x2e8f] = 0xffc3, [0x2e90] = 0xffc4, [0x2e91] = 0xffc5, +- [0x2e92] = 0xffc6, [0x2e93] = 0xffc7, [0x2e94] = 0xffc8, [0x2e95] = 0xffc9, +- [0x2e96] = 0xffca, [0x2e97] = 0xffcb, [0x2e98] = 0xffcc, [0x2e99] = 0xffcd, +- [0x2e9a] = 0xffce, [0x2e9b] = 0xffcf, [0x2e9c] = 0xffd0, [0x2e9d] = 0xffd1, +- [0x2e9e] = 0xffd2, [0x2e9f] = 0xffd3, [0x2ea0] = 0xffd4, [0x2ea1] = 0xffd5, +- [0x2ea2] = 0xffd6, [0x2ea3] = 0xffd7, [0x2ea4] = 0xffd8, [0x2ea5] = 0xffd9, +- [0x2ea6] = 0xffda, [0x2ea7] = 0xffdb, [0x2ea8] = 0xffdc, [0x2ea9] = 0xffdd, +- [0x2eaa] = 0xffde, [0x2eab] = 0xffdf, ++ [0x2d6c] = 0xfe0e, [0x2d6d] = 0xfe0f, [0x2d6e] = 0xe78d, [0x2d6f] = 0xe78f, ++ [0x2d70] = 0xe78e, [0x2d71] = 0xe790, [0x2d72] = 0xe791, [0x2d73] = 0xe792, ++ [0x2d74] = 0xe793, [0x2d75] = 0xe794, [0x2d76] = 0xe795, [0x2d77] = 0xe796, ++ [0x2d78] = 0xfe1a, [0x2d79] = 0xfe1b, [0x2d7a] = 0xfe1c, [0x2d7b] = 0xfe1d, ++ [0x2d7c] = 0xfe1e, [0x2d7d] = 0xfe1f, [0x2d7e] = 0xfe20, [0x2d7f] = 0xfe21, ++ [0x2d80] = 0xfe22, [0x2d81] = 0xfe23, [0x2d82] = 0xfe24, [0x2d83] = 0xfe25, ++ [0x2d84] = 0xfe26, [0x2d85] = 0xfe27, [0x2d86] = 0xfe28, [0x2d87] = 0xfe29, ++ [0x2d88] = 0xfe2a, [0x2d89] = 0xfe2b, [0x2d8a] = 0xfe2c, [0x2d8b] = 0xfe2d, ++ [0x2d8c] = 0xfe2e, [0x2d8d] = 0xfe2f, [0x2d8e] = 0xfe32, [0x2d8f] = 0xfe45, ++ [0x2d90] = 0xfe46, [0x2d91] = 0xfe47, [0x2d92] = 0xfe48, [0x2d93] = 0xfe53, ++ [0x2d94] = 0xfe58, [0x2d95] = 0xfe67, [0x2d96] = 0xfe6c, [0x2d97] = 0xfe6d, ++ [0x2d98] = 0xfe6e, [0x2d99] = 0xfe6f, [0x2d9a] = 0xfe70, [0x2d9b] = 0xfe71, ++ [0x2d9c] = 0xfe72, [0x2d9d] = 0xfe73, [0x2d9e] = 0xfe74, [0x2d9f] = 0xfe75, ++ [0x2da0] = 0xfe76, [0x2da1] = 0xfe77, [0x2da2] = 0xfe78, [0x2da3] = 0xfe79, ++ [0x2da4] = 0xfe7a, [0x2da5] = 0xfe7b, [0x2da6] = 0xfe7c, [0x2da7] = 0xfe7d, ++ [0x2da8] = 0xfe7e, [0x2da9] = 0xfe7f, [0x2daa] = 0xfe80, [0x2dab] = 0xfe81, ++ [0x2dac] = 0xfe82, [0x2dad] = 0xfe83, [0x2dae] = 0xfe84, [0x2daf] = 0xfe85, ++ [0x2db0] = 0xfe86, [0x2db1] = 0xfe87, [0x2db2] = 0xfe88, [0x2db3] = 0xfe89, ++ [0x2db4] = 0xfe8a, [0x2db5] = 0xfe8b, [0x2db6] = 0xfe8c, [0x2db7] = 0xfe8d, ++ [0x2db8] = 0xfe8e, [0x2db9] = 0xfe8f, [0x2dba] = 0xfe90, [0x2dbb] = 0xfe91, ++ [0x2dbc] = 0xfe92, [0x2dbd] = 0xfe93, [0x2dbe] = 0xfe94, [0x2dbf] = 0xfe95, ++ [0x2dc0] = 0xfe96, [0x2dc1] = 0xfe97, [0x2dc2] = 0xfe98, [0x2dc3] = 0xfe99, ++ [0x2dc4] = 0xfe9a, [0x2dc5] = 0xfe9b, [0x2dc6] = 0xfe9c, [0x2dc7] = 0xfe9d, ++ [0x2dc8] = 0xfe9e, [0x2dc9] = 0xfe9f, [0x2dca] = 0xfea0, [0x2dcb] = 0xfea1, ++ [0x2dcc] = 0xfea2, [0x2dcd] = 0xfea3, [0x2dce] = 0xfea4, [0x2dcf] = 0xfea5, ++ [0x2dd0] = 0xfea6, [0x2dd1] = 0xfea7, [0x2dd2] = 0xfea8, [0x2dd3] = 0xfea9, ++ [0x2dd4] = 0xfeaa, [0x2dd5] = 0xfeab, [0x2dd6] = 0xfeac, [0x2dd7] = 0xfead, ++ [0x2dd8] = 0xfeae, [0x2dd9] = 0xfeaf, [0x2dda] = 0xfeb0, [0x2ddb] = 0xfeb1, ++ [0x2ddc] = 0xfeb2, [0x2ddd] = 0xfeb3, [0x2dde] = 0xfeb4, [0x2ddf] = 0xfeb5, ++ [0x2de0] = 0xfeb6, [0x2de1] = 0xfeb7, [0x2de2] = 0xfeb8, [0x2de3] = 0xfeb9, ++ [0x2de4] = 0xfeba, [0x2de5] = 0xfebb, [0x2de6] = 0xfebc, [0x2de7] = 0xfebd, ++ [0x2de8] = 0xfebe, [0x2de9] = 0xfebf, [0x2dea] = 0xfec0, [0x2deb] = 0xfec1, ++ [0x2dec] = 0xfec2, [0x2ded] = 0xfec3, [0x2dee] = 0xfec4, [0x2def] = 0xfec5, ++ [0x2df0] = 0xfec6, [0x2df1] = 0xfec7, [0x2df2] = 0xfec8, [0x2df3] = 0xfec9, ++ [0x2df4] = 0xfeca, [0x2df5] = 0xfecb, [0x2df6] = 0xfecc, [0x2df7] = 0xfecd, ++ [0x2df8] = 0xfece, [0x2df9] = 0xfecf, [0x2dfa] = 0xfed0, [0x2dfb] = 0xfed1, ++ [0x2dfc] = 0xfed2, [0x2dfd] = 0xfed3, [0x2dfe] = 0xfed4, [0x2dff] = 0xfed5, ++ [0x2e00] = 0xfed6, [0x2e01] = 0xfed7, [0x2e02] = 0xfed8, [0x2e03] = 0xfed9, ++ [0x2e04] = 0xfeda, [0x2e05] = 0xfedb, [0x2e06] = 0xfedc, [0x2e07] = 0xfedd, ++ [0x2e08] = 0xfede, [0x2e09] = 0xfedf, [0x2e0a] = 0xfee0, [0x2e0b] = 0xfee1, ++ [0x2e0c] = 0xfee2, [0x2e0d] = 0xfee3, [0x2e0e] = 0xfee4, [0x2e0f] = 0xfee5, ++ [0x2e10] = 0xfee6, [0x2e11] = 0xfee7, [0x2e12] = 0xfee8, [0x2e13] = 0xfee9, ++ [0x2e14] = 0xfeea, [0x2e15] = 0xfeeb, [0x2e16] = 0xfeec, [0x2e17] = 0xfeed, ++ [0x2e18] = 0xfeee, [0x2e19] = 0xfeef, [0x2e1a] = 0xfef0, [0x2e1b] = 0xfef1, ++ [0x2e1c] = 0xfef2, [0x2e1d] = 0xfef3, [0x2e1e] = 0xfef4, [0x2e1f] = 0xfef5, ++ [0x2e20] = 0xfef6, [0x2e21] = 0xfef7, [0x2e22] = 0xfef8, [0x2e23] = 0xfef9, ++ [0x2e24] = 0xfefa, [0x2e25] = 0xfefb, [0x2e26] = 0xfefc, [0x2e27] = 0xfefd, ++ [0x2e28] = 0xfefe, [0x2e29] = 0xfeff, [0x2e2a] = 0xff00, [0x2e2b] = 0xff5f, ++ [0x2e2c] = 0xff60, [0x2e2d] = 0xff61, [0x2e2e] = 0xff62, [0x2e2f] = 0xff63, ++ [0x2e30] = 0xff64, [0x2e31] = 0xff65, [0x2e32] = 0xff66, [0x2e33] = 0xff67, ++ [0x2e34] = 0xff68, [0x2e35] = 0xff69, [0x2e36] = 0xff6a, [0x2e37] = 0xff6b, ++ [0x2e38] = 0xff6c, [0x2e39] = 0xff6d, [0x2e3a] = 0xff6e, [0x2e3b] = 0xff6f, ++ [0x2e3c] = 0xff70, [0x2e3d] = 0xff71, [0x2e3e] = 0xff72, [0x2e3f] = 0xff73, ++ [0x2e40] = 0xff74, [0x2e41] = 0xff75, [0x2e42] = 0xff76, [0x2e43] = 0xff77, ++ [0x2e44] = 0xff78, [0x2e45] = 0xff79, [0x2e46] = 0xff7a, [0x2e47] = 0xff7b, ++ [0x2e48] = 0xff7c, [0x2e49] = 0xff7d, [0x2e4a] = 0xff7e, [0x2e4b] = 0xff7f, ++ [0x2e4c] = 0xff80, [0x2e4d] = 0xff81, [0x2e4e] = 0xff82, [0x2e4f] = 0xff83, ++ [0x2e50] = 0xff84, [0x2e51] = 0xff85, [0x2e52] = 0xff86, [0x2e53] = 0xff87, ++ [0x2e54] = 0xff88, [0x2e55] = 0xff89, [0x2e56] = 0xff8a, [0x2e57] = 0xff8b, ++ [0x2e58] = 0xff8c, [0x2e59] = 0xff8d, [0x2e5a] = 0xff8e, [0x2e5b] = 0xff8f, ++ [0x2e5c] = 0xff90, [0x2e5d] = 0xff91, [0x2e5e] = 0xff92, [0x2e5f] = 0xff93, ++ [0x2e60] = 0xff94, [0x2e61] = 0xff95, [0x2e62] = 0xff96, [0x2e63] = 0xff97, ++ [0x2e64] = 0xff98, [0x2e65] = 0xff99, [0x2e66] = 0xff9a, [0x2e67] = 0xff9b, ++ [0x2e68] = 0xff9c, [0x2e69] = 0xff9d, [0x2e6a] = 0xff9e, [0x2e6b] = 0xff9f, ++ [0x2e6c] = 0xffa0, [0x2e6d] = 0xffa1, [0x2e6e] = 0xffa2, [0x2e6f] = 0xffa3, ++ [0x2e70] = 0xffa4, [0x2e71] = 0xffa5, [0x2e72] = 0xffa6, [0x2e73] = 0xffa7, ++ [0x2e74] = 0xffa8, [0x2e75] = 0xffa9, [0x2e76] = 0xffaa, [0x2e77] = 0xffab, ++ [0x2e78] = 0xffac, [0x2e79] = 0xffad, [0x2e7a] = 0xffae, [0x2e7b] = 0xffaf, ++ [0x2e7c] = 0xffb0, [0x2e7d] = 0xffb1, [0x2e7e] = 0xffb2, [0x2e7f] = 0xffb3, ++ [0x2e80] = 0xffb4, [0x2e81] = 0xffb5, [0x2e82] = 0xffb6, [0x2e83] = 0xffb7, ++ [0x2e84] = 0xffb8, [0x2e85] = 0xffb9, [0x2e86] = 0xffba, [0x2e87] = 0xffbb, ++ [0x2e88] = 0xffbc, [0x2e89] = 0xffbd, [0x2e8a] = 0xffbe, [0x2e8b] = 0xffbf, ++ [0x2e8c] = 0xffc0, [0x2e8d] = 0xffc1, [0x2e8e] = 0xffc2, [0x2e8f] = 0xffc3, ++ [0x2e90] = 0xffc4, [0x2e91] = 0xffc5, [0x2e92] = 0xffc6, [0x2e93] = 0xffc7, ++ [0x2e94] = 0xffc8, [0x2e95] = 0xffc9, [0x2e96] = 0xffca, [0x2e97] = 0xffcb, ++ [0x2e98] = 0xffcc, [0x2e99] = 0xffcd, [0x2e9a] = 0xffce, [0x2e9b] = 0xffcf, ++ [0x2e9c] = 0xffd0, [0x2e9d] = 0xffd1, [0x2e9e] = 0xffd2, [0x2e9f] = 0xffd3, ++ [0x2ea0] = 0xffd4, [0x2ea1] = 0xffd5, [0x2ea2] = 0xffd6, [0x2ea3] = 0xffd7, ++ [0x2ea4] = 0xffd8, [0x2ea5] = 0xffd9, [0x2ea6] = 0xffda, [0x2ea7] = 0xffdb, ++ [0x2ea8] = 0xffdc, [0x2ea9] = 0xffdd, [0x2eaa] = 0xffde, [0x2eab] = 0xffdf, + }; + + /* Table for UCS-4 -> GB18030, for the range U+0080..U+9FBB. +@@ -23448,71 +23453,79 @@ static const unsigned char __ucs_to_gb18030_tab2[][2] = + [0x0783] = "\xa5\xfd", [0x0784] = "\xa5\xfe", [0x0785] = "\xa6\xb9", + [0x0786] = "\xa6\xba", [0x0787] = "\xa6\xbb", [0x0788] = "\xa6\xbc", + [0x0789] = "\xa6\xbd", [0x078a] = "\xa6\xbe", [0x078b] = "\xa6\xbf", +- [0x078c] = "\xa6\xc0", [0x0797] = "\xa6\xf6", [0x0798] = "\xa6\xf7", +- [0x0799] = "\xa6\xf8", [0x079a] = "\xa6\xf9", [0x079b] = "\xa6\xfa", +- [0x079c] = "\xa6\xfb", [0x079d] = "\xa6\xfc", [0x079e] = "\xa6\xfd", +- [0x079f] = "\xa6\xfe", [0x07a0] = "\xa7\xc2", [0x07a1] = "\xa7\xc3", +- [0x07a2] = "\xa7\xc4", [0x07a3] = "\xa7\xc5", [0x07a4] = "\xa7\xc6", +- [0x07a5] = "\xa7\xc7", [0x07a6] = "\xa7\xc8", [0x07a7] = "\xa7\xc9", +- [0x07a8] = "\xa7\xca", [0x07a9] = "\xa7\xcb", [0x07aa] = "\xa7\xcc", +- [0x07ab] = "\xa7\xcd", [0x07ac] = "\xa7\xce", [0x07ad] = "\xa7\xcf", +- [0x07ae] = "\xa7\xd0", [0x07af] = "\xa7\xf2", [0x07b0] = "\xa7\xf3", +- [0x07b1] = "\xa7\xf4", [0x07b2] = "\xa7\xf5", [0x07b3] = "\xa7\xf6", +- [0x07b4] = "\xa7\xf7", [0x07b5] = "\xa7\xf8", [0x07b6] = "\xa7\xf9", +- [0x07b7] = "\xa7\xfa", [0x07b8] = "\xa7\xfb", [0x07b9] = "\xa7\xfc", +- [0x07ba] = "\xa7\xfd", [0x07bb] = "\xa7\xfe", [0x07bc] = "\xa8\x96", +- [0x07bd] = "\xa8\x97", [0x07be] = "\xa8\x98", [0x07bf] = "\xa8\x99", +- [0x07c0] = "\xa8\x9a", [0x07c1] = "\xa8\x9b", [0x07c2] = "\xa8\x9c", +- [0x07c3] = "\xa8\x9d", [0x07c4] = "\xa8\x9e", [0x07c5] = "\xa8\x9f", +- [0x07c6] = "\xa8\xa0", [0x07c7] = "\x00\x01", [0x07c8] = "\x65\x9e", +- [0x07c9] = "\xa8\xc1", [0x07ca] = "\xa8\xc2", [0x07cb] = "\xa8\xc3", +- [0x07cc] = "\xa8\xc4", [0x07cd] = "\xa8\xea", [0x07ce] = "\xa8\xeb", +- [0x07cf] = "\xa8\xec", [0x07d0] = "\xa8\xed", [0x07d1] = "\xa8\xee", +- [0x07d2] = "\xa8\xef", [0x07d3] = "\xa8\xf0", [0x07d4] = "\xa8\xf1", +- [0x07d5] = "\xa8\xf2", [0x07d6] = "\xa8\xf3", [0x07d7] = "\xa8\xf4", +- [0x07d8] = "\xa8\xf5", [0x07d9] = "\xa8\xf6", [0x07da] = "\xa8\xf7", +- [0x07db] = "\xa8\xf8", [0x07dc] = "\xa8\xf9", [0x07dd] = "\xa8\xfa", +- [0x07de] = "\xa8\xfb", [0x07df] = "\xa8\xfc", [0x07e0] = "\xa8\xfd", +- [0x07e1] = "\xa8\xfe", [0x07e2] = "\xa9\x58", [0x07e3] = "\xa9\x5b", +- [0x07e4] = "\xa9\x5d", [0x07e5] = "\xa9\x5e", [0x07e6] = "\xa9\x5f", +- [0x07e7] = "\x65\x9f", [0x07e8] = "\x65\xa0", [0x07e9] = "\x65\xa1", +- [0x07ea] = "\x65\xa2", [0x07eb] = "\x65\xa3", [0x07ec] = "\x65\xa4", +- [0x07ed] = "\x65\xa5", [0x07ee] = "\x65\xa6", [0x07ef] = "\x65\xa7", +- [0x07f0] = "\x65\xa8", [0x07f1] = "\x65\xa9", [0x07f2] = "\x65\xaa", +- [0x07f3] = "\x65\xab", [0x07f4] = "\xa9\x97", [0x07f5] = "\xa9\x98", +- [0x07f6] = "\xa9\x99", [0x07f7] = "\xa9\x9a", [0x07f8] = "\xa9\x9b", +- [0x07f9] = "\xa9\x9c", [0x07fa] = "\xa9\x9d", [0x07fb] = "\xa9\x9e", +- [0x07fc] = "\xa9\x9f", [0x07fd] = "\xa9\xa0", [0x07fe] = "\xa9\xa1", +- [0x07ff] = "\xa9\xa2", [0x0800] = "\xa9\xa3", [0x0801] = "\xa9\xf0", +- [0x0802] = "\xa9\xf1", [0x0803] = "\xa9\xf2", [0x0804] = "\xa9\xf3", +- [0x0805] = "\xa9\xf4", [0x0806] = "\xa9\xf5", [0x0807] = "\xa9\xf6", +- [0x0808] = "\xa9\xf7", [0x0809] = "\xa9\xf8", [0x080a] = "\xa9\xf9", +- [0x080b] = "\xa9\xfa", [0x080c] = "\xa9\xfb", [0x080d] = "\xa9\xfc", +- [0x080e] = "\xa9\xfd", [0x080f] = "\xa9\xfe", [0x0810] = "\xd7\xfa", +- [0x0811] = "\xd7\xfb", [0x0812] = "\xd7\xfc", [0x0813] = "\xd7\xfd", +- [0x0814] = "\xd7\xfe", [0x0815] = "\x65\xac", [0x0819] = "\x65\xad", +- [0x081a] = "\x65\xae", [0x081b] = "\x65\xaf", [0x081c] = "\x65\xb0", +- [0x081d] = "\x65\xb1", [0x081f] = "\x65\xb2", [0x0820] = "\x65\xb3", +- [0x0821] = "\x65\xb4", [0x0822] = "\x65\xb5", [0x0823] = "\x65\xb6", +- [0x0824] = "\x65\xb7", [0x0825] = "\x65\xb8", [0x0827] = "\x65\xb9", ++ [0x078c] = "\xa6\xc0", [0x078d] = "\x7b\x84", [0x078e] = "\x7b\x86", ++ [0x078f] = "\x7b\x85", [0x0790] = "\x7b\x87", [0x0791] = "\x7b\x88", ++ [0x0792] = "\x7b\x89", [0x0793] = "\x7b\x8a", [0x0794] = "\x7b\x8b", ++ [0x0795] = "\x7b\x8c", [0x0796] = "\x7b\x8d", [0x0797] = "\xa6\xf6", ++ [0x0798] = "\xa6\xf7", [0x0799] = "\xa6\xf8", [0x079a] = "\xa6\xf9", ++ [0x079b] = "\xa6\xfa", [0x079c] = "\xa6\xfb", [0x079d] = "\xa6\xfc", ++ [0x079e] = "\xa6\xfd", [0x079f] = "\xa6\xfe", [0x07a0] = "\xa7\xc2", ++ [0x07a1] = "\xa7\xc3", [0x07a2] = "\xa7\xc4", [0x07a3] = "\xa7\xc5", ++ [0x07a4] = "\xa7\xc6", [0x07a5] = "\xa7\xc7", [0x07a6] = "\xa7\xc8", ++ [0x07a7] = "\xa7\xc9", [0x07a8] = "\xa7\xca", [0x07a9] = "\xa7\xcb", ++ [0x07aa] = "\xa7\xcc", [0x07ab] = "\xa7\xcd", [0x07ac] = "\xa7\xce", ++ [0x07ad] = "\xa7\xcf", [0x07ae] = "\xa7\xd0", [0x07af] = "\xa7\xf2", ++ [0x07b0] = "\xa7\xf3", [0x07b1] = "\xa7\xf4", [0x07b2] = "\xa7\xf5", ++ [0x07b3] = "\xa7\xf6", [0x07b4] = "\xa7\xf7", [0x07b5] = "\xa7\xf8", ++ [0x07b6] = "\xa7\xf9", [0x07b7] = "\xa7\xfa", [0x07b8] = "\xa7\xfb", ++ [0x07b9] = "\xa7\xfc", [0x07ba] = "\xa7\xfd", [0x07bb] = "\xa7\xfe", ++ [0x07bc] = "\xa8\x96", [0x07bd] = "\xa8\x97", [0x07be] = "\xa8\x98", ++ [0x07bf] = "\xa8\x99", [0x07c0] = "\xa8\x9a", [0x07c1] = "\xa8\x9b", ++ [0x07c2] = "\xa8\x9c", [0x07c3] = "\xa8\x9d", [0x07c4] = "\xa8\x9e", ++ [0x07c5] = "\xa8\x9f", [0x07c6] = "\xa8\xa0", [0x07c7] = "\x00\x01", ++ [0x07c8] = "\x65\x9e", [0x07c9] = "\xa8\xc1", [0x07ca] = "\xa8\xc2", ++ [0x07cb] = "\xa8\xc3", [0x07cc] = "\xa8\xc4", [0x07cd] = "\xa8\xea", ++ [0x07ce] = "\xa8\xeb", [0x07cf] = "\xa8\xec", [0x07d0] = "\xa8\xed", ++ [0x07d1] = "\xa8\xee", [0x07d2] = "\xa8\xef", [0x07d3] = "\xa8\xf0", ++ [0x07d4] = "\xa8\xf1", [0x07d5] = "\xa8\xf2", [0x07d6] = "\xa8\xf3", ++ [0x07d7] = "\xa8\xf4", [0x07d8] = "\xa8\xf5", [0x07d9] = "\xa8\xf6", ++ [0x07da] = "\xa8\xf7", [0x07db] = "\xa8\xf8", [0x07dc] = "\xa8\xf9", ++ [0x07dd] = "\xa8\xfa", [0x07de] = "\xa8\xfb", [0x07df] = "\xa8\xfc", ++ [0x07e0] = "\xa8\xfd", [0x07e1] = "\xa8\xfe", [0x07e2] = "\xa9\x58", ++ [0x07e3] = "\xa9\x5b", [0x07e4] = "\xa9\x5d", [0x07e5] = "\xa9\x5e", ++ [0x07e6] = "\xa9\x5f", [0x07e7] = "\x65\x9f", [0x07e8] = "\x65\xa0", ++ [0x07e9] = "\x65\xa1", [0x07ea] = "\x65\xa2", [0x07eb] = "\x65\xa3", ++ [0x07ec] = "\x65\xa4", [0x07ed] = "\x65\xa5", [0x07ee] = "\x65\xa6", ++ [0x07ef] = "\x65\xa7", [0x07f0] = "\x65\xa8", [0x07f1] = "\x65\xa9", ++ [0x07f2] = "\x65\xaa", [0x07f3] = "\x65\xab", [0x07f4] = "\xa9\x97", ++ [0x07f5] = "\xa9\x98", [0x07f6] = "\xa9\x99", [0x07f7] = "\xa9\x9a", ++ [0x07f8] = "\xa9\x9b", [0x07f9] = "\xa9\x9c", [0x07fa] = "\xa9\x9d", ++ [0x07fb] = "\xa9\x9e", [0x07fc] = "\xa9\x9f", [0x07fd] = "\xa9\xa0", ++ [0x07fe] = "\xa9\xa1", [0x07ff] = "\xa9\xa2", [0x0800] = "\xa9\xa3", ++ [0x0801] = "\xa9\xf0", [0x0802] = "\xa9\xf1", [0x0803] = "\xa9\xf2", ++ [0x0804] = "\xa9\xf3", [0x0805] = "\xa9\xf4", [0x0806] = "\xa9\xf5", ++ [0x0807] = "\xa9\xf6", [0x0808] = "\xa9\xf7", [0x0809] = "\xa9\xf8", ++ [0x080a] = "\xa9\xf9", [0x080b] = "\xa9\xfa", [0x080c] = "\xa9\xfb", ++ [0x080d] = "\xa9\xfc", [0x080e] = "\xa9\xfd", [0x080f] = "\xa9\xfe", ++ [0x0810] = "\xd7\xfa", [0x0811] = "\xd7\xfb", [0x0812] = "\xd7\xfc", ++ [0x0813] = "\xd7\xfd", [0x0814] = "\xd7\xfe", [0x0815] = "\x65\xac", ++ [0x0816] = "\xfe\x51", [0x0817] = "\xfe\x52", [0x0818] = "\xfe\x53", ++ [0x0819] = "\x65\xad", [0x081a] = "\x65\xae", [0x081b] = "\x65\xaf", ++ [0x081c] = "\x65\xb0", [0x081d] = "\x65\xb1", [0x081e] = "\x2d\x51", ++ [0x081f] = "\x65\xb2", [0x0820] = "\x65\xb3", [0x0821] = "\x65\xb4", ++ [0x0822] = "\x65\xb5", [0x0823] = "\x65\xb6", [0x0824] = "\x65\xb7", ++ [0x0825] = "\x65\xb8", [0x0826] = "\x2d\x52", [0x0827] = "\x65\xb9", + [0x0828] = "\x65\xba", [0x0829] = "\x65\xbb", [0x082a] = "\x65\xbc", +- [0x082d] = "\x65\xbd", [0x082e] = "\x65\xbe", [0x082f] = "\x65\xbf", +- [0x0830] = "\x65\xc0", [0x0833] = "\x65\xc1", [0x0834] = "\x65\xc2", +- [0x0835] = "\x65\xc3", [0x0836] = "\x65\xc4", [0x0837] = "\x65\xc5", +- [0x0838] = "\x65\xc6", [0x0839] = "\x65\xc7", [0x083a] = "\x65\xc8", +- [0x083c] = "\x65\xc9", [0x083d] = "\x65\xca", [0x083e] = "\x65\xcb", +- [0x083f] = "\x65\xcc", [0x0840] = "\x65\xcd", [0x0841] = "\x65\xce", +- [0x0842] = "\x65\xcf", [0x0844] = "\x65\xd0", [0x0845] = "\x65\xd1", ++ [0x082b] = "\x2d\x53", [0x082c] = "\x2d\x54", [0x082d] = "\x65\xbd", ++ [0x082e] = "\x65\xbe", [0x082f] = "\x65\xbf", [0x0830] = "\x65\xc0", ++ [0x0831] = "\xfe\x6c", [0x0832] = "\x2d\x55", [0x0833] = "\x65\xc1", ++ [0x0834] = "\x65\xc2", [0x0835] = "\x65\xc3", [0x0836] = "\x65\xc4", ++ [0x0837] = "\x65\xc5", [0x0838] = "\x65\xc6", [0x0839] = "\x65\xc7", ++ [0x083a] = "\x65\xc8", [0x083b] = "\xfe\x76", [0x083c] = "\x65\xc9", ++ [0x083d] = "\x65\xca", [0x083e] = "\x65\xcb", [0x083f] = "\x65\xcc", ++ [0x0840] = "\x65\xcd", [0x0841] = "\x65\xce", [0x0842] = "\x65\xcf", ++ [0x0843] = "\x2d\x56", [0x0844] = "\x65\xd0", [0x0845] = "\x65\xd1", + [0x0846] = "\x65\xd2", [0x0847] = "\x65\xd3", [0x0848] = "\x65\xd4", + [0x0849] = "\x65\xd5", [0x084a] = "\x65\xd6", [0x084b] = "\x65\xd7", + [0x084c] = "\x65\xd8", [0x084d] = "\x65\xd9", [0x084e] = "\x65\xda", + [0x084f] = "\x65\xdb", [0x0850] = "\x65\xdc", [0x0851] = "\x65\xdd", +- [0x0852] = "\x65\xde", [0x0853] = "\x65\xdf", [0x0856] = "\x65\xe0", +- [0x0857] = "\x65\xe1", [0x0858] = "\x65\xe2", [0x0859] = "\x65\xe3", +- [0x085a] = "\x65\xe4", [0x085b] = "\x65\xe5", [0x085c] = "\x65\xe6", +- [0x085d] = "\x65\xe7", [0x085e] = "\x65\xe8", [0x085f] = "\x65\xe9", +- [0x0860] = "\x65\xea", [0x0861] = "\x65\xeb", [0x0862] = "\x65\xec", +- [0x0863] = "\x65\xed", [0x0865] = "\xfd\x9c", [0x0866] = "\x76\xb5", ++ [0x0852] = "\x65\xde", [0x0853] = "\x65\xdf", [0x0854] = "\x2d\x57", ++ [0x0855] = "\xfe\x91", [0x0856] = "\x65\xe0", [0x0857] = "\x65\xe1", ++ [0x0858] = "\x65\xe2", [0x0859] = "\x65\xe3", [0x085a] = "\x65\xe4", ++ [0x085b] = "\x65\xe5", [0x085c] = "\x65\xe6", [0x085d] = "\x65\xe7", ++ [0x085e] = "\x65\xe8", [0x085f] = "\x65\xe9", [0x0860] = "\x65\xea", ++ [0x0861] = "\x65\xeb", [0x0862] = "\x65\xec", [0x0863] = "\x65\xed", ++ [0x0864] = "\x2d\x58", [0x0865] = "\xfd\x9c", [0x0866] = "\x76\xb5", + [0x0867] = "\x76\xb6", [0x0868] = "\x76\xb7", [0x0869] = "\x76\xb8", + [0x086a] = "\x76\xb9", [0x086b] = "\x76\xba", [0x086c] = "\x76\xbb", + [0x086d] = "\x76\xbc", [0x086e] = "\x76\xbd", [0x086f] = "\x76\xbe", +@@ -24222,24 +24235,8 @@ static const unsigned char __ucs_to_gb18030_tab2[][2] = + || (ch = __twobyte_to_ucs[idx], \ + ch == 0 && *inptr != '\0')) \ + { \ +- /* Handle a few special cases. */ \ +- if (idx == 0x5dd1) \ +- ch = 0x20087; \ +- else if (idx == 0x5dd2) \ +- ch = 0x20089; \ +- else if (idx == 0x5dd3) \ +- ch = 0x200cc; \ +- else if (idx == 0x5dec) \ +- ch = 0x215D7; \ +- else if (idx == 0x5df6) \ +- ch = 0x2298F; \ +- else if (idx == 0x5e11) \ +- ch = 0x241FE; \ +- else \ +- { \ +- /* This is an illegal character. */ \ +- STANDARD_FROM_LOOP_ERR_HANDLER (2); \ +- } \ ++ /* This is an illegal character. */ \ ++ STANDARD_FROM_LOOP_ERR_HANDLER (2); \ + } \ + \ + inptr += 2; \ +@@ -24331,17 +24328,35 @@ static const unsigned char __ucs_to_gb18030_tab2[][2] = + len = 4; \ + } \ + else if (ch == 0x20087) \ +- cp = (const unsigned char *) "\xfe\x51"; \ ++ { \ ++ idx = 0x3E2CF; \ ++ len = 4; \ ++ } \ + else if (ch == 0x20089) \ +- cp = (const unsigned char *) "\xfe\x52"; \ ++ { \ ++ idx = 0x3E2D1; \ ++ len = 4; \ ++ } \ + else if (ch == 0x200CC) \ +- cp = (const unsigned char *) "\xfe\x53"; \ ++ { \ ++ idx = 0x3E314; \ ++ len = 4; \ ++ } \ + else if (ch == 0x215d7) \ +- cp = (const unsigned char *) "\xfe\x6c"; \ ++ { \ ++ idx = 0x3F81F; \ ++ len = 4; \ ++ } \ + else if (ch == 0x2298F) \ +- cp = (const unsigned char *) "\xfe\x76"; \ ++ { \ ++ idx = 0x40BD7; \ ++ len = 4; \ ++ } \ + else if (ch == 0x241FE) \ +- cp = (const unsigned char *) "\xfe\x91"; \ ++ { \ ++ idx = 0x42446; \ ++ len = 4; \ ++ } \ + else if (ch >= 0x10000 && ch <= 0x10FFFF) \ + { \ + idx = ch + 0x1E248; \ +diff --git a/iconvdata/tst-table-from.c b/iconvdata/tst-table-from.c +index 9ad1f44e..c881c86b 100644 +--- a/iconvdata/tst-table-from.c ++++ b/iconvdata/tst-table-from.c +@@ -195,10 +195,9 @@ main (int argc, char *argv[]) + exit (1); + } + +- /* When testing UTF-8 or GB18030, stop at 0x10000, otherwise the output ++ /* When testing UTF-8, stop at 0x10000, otherwise the output + file gets too big. */ +- bmp_only = (strcmp (charset, "UTF-8") == 0 +- || strcmp (charset, "GB18030") == 0); ++ bmp_only = (strcmp (charset, "UTF-8") == 0); + search_depth = (strcmp (charset, "UTF-8") == 0 ? 3 : 4); + + { +diff --git a/iconvdata/tst-table-to.c b/iconvdata/tst-table-to.c +index 6f0aa29c..8d097527 100644 +--- a/iconvdata/tst-table-to.c ++++ b/iconvdata/tst-table-to.c +@@ -33,6 +33,7 @@ main (int argc, char *argv[]) + const char *charset; + iconv_t cd; + int bmp_only; ++ int no_tags; + + if (argc != 2) + { +@@ -48,16 +49,19 @@ main (int argc, char *argv[]) + return 1; + } + +- /* When testing UTF-8 or GB18030, stop at 0x10000, otherwise the output ++ /* When testing UTF-8, stop at 0x10000, otherwise the output + file gets too big. */ +- bmp_only = (strcmp (charset, "UTF-8") == 0 ++ bmp_only = (strcmp (charset, "UTF-8") == 0); ++ /* When testing any encoding other than UTF-8 or GB18030, stop at 0xE0000, ++ because the conversion drops Unicode tag characters (range ++ U+E0000..U+E007F). */ ++ no_tags = !(strcmp (charset, "UTF-8") == 0 + || strcmp (charset, "GB18030") == 0); + + { + unsigned int i; + unsigned char buf[10]; +- +- for (i = 0; i < (bmp_only ? 0x10000 : 0x30000); i++) ++ for (i = 0; i < (bmp_only ? 0x10000 : no_tags ? 0xE0000 : 0x110000); i++) + { + unsigned char in[6]; + unsigned int incount = +diff --git a/iconvdata/tst-table.sh b/iconvdata/tst-table.sh +index 04c06136..3c6927ee 100755 +--- a/iconvdata/tst-table.sh ++++ b/iconvdata/tst-table.sh +@@ -38,7 +38,8 @@ set -e + < ../localedata/charmaps/${charmap:-$charset} \ + > ${objpfx}tst-${charset}.charmap.table + # When the charset is GB18030, truncate this table because for this encoding, +-# the tst-table-from and tst-table-to programs scan the Unicode BMP only. ++# the charmap contains ranges (.. notation), which the ++# tst-table-charmap.sh script does not grok. + if test ${charset} = GB18030; then + grep '0x....$' < ${objpfx}tst-${charset}.charmap.table \ + > ${objpfx}tst-${charset}.truncated.table +@@ -74,25 +75,42 @@ diff ${objpfx}tst-${charset}.charmap.table ${objpfx}tst-${charset}.inverse.table + + # Check 1: charmap and iconv forward should be identical, except for + # precomposed characters. +-if test -f ${precomposed}; then +- cat ${objpfx}tst-${charset}.table ${precomposed} | sort | uniq -u \ +- > ${objpfx}tst-${charset}.tmp.table +- cmp -s ${objpfx}tst-${charset}.charmap.table ${objpfx}tst-${charset}.tmp.table || ++{ if test -f ${precomposed}; then ++ cat ${objpfx}tst-${charset}.table ${precomposed} | sort | uniq -u ++ else ++ cat ${objpfx}tst-${charset}.table ++ fi ++} | { if test ${charset} = GB18030; then grep '0x....$'; else cat; fi; } \ ++ > ${objpfx}tst-${charset}.tmp1.table ++cmp -s ${objpfx}tst-${charset}.charmap.table ${objpfx}tst-${charset}.tmp1.table || + exit 1 +-else +- cmp -s ${objpfx}tst-${charset}.charmap.table ${objpfx}tst-${charset}.table || +- exit 1 +-fi + + # Check 2: the difference between the charmap and iconv backward. +-if test -f ${irreversible}; then +- cat ${objpfx}tst-${charset}.charmap.table ${irreversible} | sort | uniq -u \ +- > ${objpfx}tst-${charset}.tmp.table +- cmp -s ${objpfx}tst-${charset}.tmp.table ${objpfx}tst-${charset}.inverse.table || +- exit 1 +-else +- cmp -s ${objpfx}tst-${charset}.charmap.table ${objpfx}tst-${charset}.inverse.table || ++{ if test -f ${irreversible}; then ++ cat ${objpfx}tst-${charset}.charmap.table ${irreversible} | sort | uniq -u ++ else ++ cat ${objpfx}tst-${charset}.charmap.table ++ fi ++} | { if test ${charset} = GB18030; then grep '0x....$'; else cat; fi; } \ ++ > ${objpfx}tst-${charset}.tmp2c.table ++cat ${objpfx}tst-${charset}.inverse.table \ ++ | { if test ${charset} = GB18030; then grep '0x....$'; else cat; fi; } \ ++ > ${objpfx}tst-${charset}.tmp2i.table ++cmp -s ${objpfx}tst-${charset}.tmp2c.table ${objpfx}tst-${charset}.tmp2i.table || + exit 1 ++ ++# Check 3: the difference between iconv forward and iconv backward. This is ++# necessary only for GB18030, because ${objpfx}tst-${charset}.charmap.table ++# is truncated for this encoding (see above). ++if test ${charset} = GB18030; then ++ { if test -f ${irreversible}; then ++ cat ${objpfx}tst-${charset}.table ${irreversible} | sort | uniq -u ++ else ++ cat ${objpfx}tst-${charset}.table ++ fi ++ } > ${objpfx}tst-${charset}.tmp3.table ++ cmp -s ${objpfx}tst-${charset}.tmp3.table ${objpfx}tst-${charset}.inverse.table || ++ exit 1 + fi + + exit 0 +diff --git a/localedata/charmaps/GB18030 b/localedata/charmaps/GB18030 +index ad6728c5..fc3b1d2d 100644 +--- a/localedata/charmaps/GB18030 ++++ b/localedata/charmaps/GB18030 +@@ -57234,32 +57234,16 @@ CHARMAP + /xa6/xbe + /xa6/xbf + /xa6/xc0 +-% The newest GB 18030-2005 standard still uses some private use area +-% code points. Any implementation which has Unicode 4.1 or newer +-% support should not use these PUA code points, and instead should +-% map these entries to their equivalent non-PUA code points. There +-% are 24 idiograms in GB 18030-2005 which have non-PUA equivalents. +-% In glibc we only support roundtrip code points, and so must choose +-% between supporting the old PUA code points, or using the newer +-% non-PUA code points. We choose to use the non-PUA code points to +-% be compatible with ICU's similar choice. In choosing the non-PUA +-% code points we can no longer convert the old PUA code points back +-% to GB-18030-2005 (technically only fixable if we added support +-% for non-roundtrip code points e.g. ICU's "fallback mapping"). +-% The recommendation to use the non-PUA code points, where available, +-% is based on "CJKV Information Processing" 2nd Ed. by Dr. Ken Lunde. +-% +-% These 10 PUA mappings use equivalents from to . +-% /xa6/xd9 +-% /xa6/xda +-% /xa6/xdb +-% /xa6/xdc +-% /xa6/xdd +-% /xa6/xde +-% /xa6/xdf +-% /xa6/xec +-% /xa6/xed +-% /xa6/xf3 ++ /x84/x31/x82/x36 ++ /x84/x31/x82/x38 ++ /x84/x31/x82/x37 ++ /x84/x31/x82/x39 ++ /x84/x31/x83/x30 ++ /x84/x31/x83/x31 ++ /x84/x31/x83/x32 ++ /x84/x31/x83/x33 ++ /x84/x31/x83/x34 ++ /x84/x31/x83/x35 + /xa6/xf6 + /xa6/xf7 + /xa6/xf8 +@@ -57387,17 +57371,15 @@ CHARMAP + /xd7/xfd + /xd7/xfe + /x83/x36/xc9/x34 +-% These 3 PUA mappings use equivalents , and . +-% /xfe/x51 +-% /xfe/x52 +-% /xfe/x53 ++ /xfe/x51 ++ /xfe/x52 ++ /xfe/x53 + /x83/x36/xc9/x35 + /x83/x36/xc9/x36 + /x83/x36/xc9/x37 + /x83/x36/xc9/x38 + /x83/x36/xc9/x39 +-% This 1 PUA mapping uses the equivalent . +-% /xfe/x59 ++ /x82/x35/x90/x37 + /x83/x36/xca/x30 + /x83/x36/xca/x31 + /x83/x36/xca/x32 +@@ -57405,22 +57387,19 @@ CHARMAP + /x83/x36/xca/x34 + /x83/x36/xca/x35 + /x83/x36/xca/x36 +-% This 1 PUA mapping uses the equivalent . +-% /xfe/x61 ++ /x82/x35/x90/x38 + /x83/x36/xca/x37 + /x83/x36/xca/x38 + /x83/x36/xca/x39 + /x83/x36/xcb/x30 +-% These 2 PUA mappings use the equivalents and . +-% /xfe/x66 +-% /xfe/x67 ++ /x82/x35/x90/x39 ++ /x82/x35/x91/x30 + /x83/x36/xcb/x31 + /x83/x36/xcb/x32 + /x83/x36/xcb/x33 + /x83/x36/xcb/x34 +-% These 2 PUA mappings use the equivalents and . +-% /xfe/x6c +-% /xfe/x6d ++ /xfe/x6c ++ /x82/x35/x91/x31 + /x83/x36/xcb/x35 + /x83/x36/xcb/x36 + /x83/x36/xcb/x37 +@@ -57429,8 +57408,7 @@ CHARMAP + /x83/x36/xcc/x30 + /x83/x36/xcc/x31 + /x83/x36/xcc/x32 +-% This 1 PUA mapping uses the equivalent . +-% /xfe/x76 ++ /xfe/x76 + /x83/x36/xcc/x33 + /x83/x36/xcc/x34 + /x83/x36/xcc/x35 +@@ -57438,8 +57416,7 @@ CHARMAP + /x83/x36/xcc/x37 + /x83/x36/xcc/x38 + /x83/x36/xcc/x39 +-% This 1 PUA mapping uses the equivalent . +-% /xfe/x7e ++ /x82/x35/x91/x32 + /x83/x36/xcd/x30 + /x83/x36/xcd/x31 + /x83/x36/xcd/x32 +@@ -57456,9 +57433,8 @@ CHARMAP + /x83/x36/xce/x33 + /x83/x36/xce/x34 + /x83/x36/xce/x35 +-% These 2 PUA mappings use the equivalents and . +-% /xfe/x90 +-% /xfe/x91 ++ /x82/x35/x91/x33 ++ /xfe/x91 + /x83/x36/xce/x36 + /x83/x36/xce/x37 + /x83/x36/xce/x38 +@@ -57473,8 +57449,7 @@ CHARMAP + /x83/x36/xcf/x37 + /x83/x36/xcf/x38 + /x83/x36/xcf/x39 +-% This 1 PUA mapping uses the equivalent . +-% /xfe/xa0 ++ /x82/x35/x91/x34 + /x83/x36/xd0/x30 + /x83/x36/xd0/x31 + /x83/x36/xd0/x32 +@@ -70447,19 +70422,14 @@ CHARMAP + .. /x95/x32/x8d/x30 + .. /x95/x32/x8e/x30 + .. /x95/x32/x8f/x30 +- /x95/x32/x90/x30 +- /xfe/x51 +- /x95/x32/x90/x32 +- /xfe/x52 +-.. /x95/x32/x90/x34 ++.. /x95/x32/x90/x30 + .. /x95/x32/x91/x30 + .. /x95/x32/x92/x30 + .. /x95/x32/x93/x30 + .. /x95/x32/x94/x30 + .. /x95/x32/x95/x30 + .. /x95/x32/x96/x30 +- /xfe/x53 +-.. /x95/x32/x97/x31 ++.. /x95/x32/x97/x30 + .. /x95/x32/x98/x30 + .. /x95/x32/x99/x30 + .. /x95/x32/x9a/x30 +@@ -70998,8 +70968,7 @@ CHARMAP + .. /x95/x36/xb7/x30 + .. /x95/x36/xb8/x30 + .. /x95/x36/xb9/x30 +- /xfe/x6c +-.. /x95/x36/xb9/x38 ++.. /x95/x36/xb9/x37 + .. /x95/x36/xba/x30 + .. /x95/x36/xbb/x30 + .. /x95/x36/xbc/x30 +@@ -71505,8 +71474,7 @@ CHARMAP + .. /x96/x30/xb8/x30 + .. /x96/x30/xb9/x30 + .. /x96/x30/xba/x30 +- /xfe/x76 +-.. /x96/x30/xba/x36 ++.. /x96/x30/xba/x35 + .. /x96/x30/xbb/x30 + .. /x96/x30/xbc/x30 + .. /x96/x30/xbd/x30 +@@ -72132,8 +72100,7 @@ CHARMAP + .. /x96/x35/xb3/x30 + .. /x96/x35/xb4/x30 + .. /x96/x35/xb5/x30 +- /xfe/x91 +-.. /x96/x35/xb6/x31 ++.. /x96/x35/xb6/x30 + .. /x96/x35/xb7/x30 + .. /x96/x35/xb8/x30 + .. /x96/x35/xb9/x30 diff --git a/glibc.spec b/glibc.spec index 67eaab4..b2904c6 100644 --- a/glibc.spec +++ b/glibc.spec @@ -199,6 +199,9 @@ rpm.define("__find_debuginfo " .. wrapper .. " " .. sysroot .. " " .. original) # - See each individual patch file for origin and upstream status. # - For new patches follow template.patch format. ############################################################################## +# https://sourceware.org/bugzilla/show_bug.cgi?id=30243 +Patch0: glibc-gb18030-2022-bug30243.patch + Patch2: glibc-fedora-nscd.patch Patch3: glibc-rh697421.patch Patch4: glibc-fedora-linux-tcsetattr.patch @@ -2885,6 +2888,7 @@ fi * Sun Oct 08 2023 Rongwei Wang - 2.28-225.0.4.6 - elf: Properly align PT_LOAD segments - Sync loongarch64 code to lnd.35. (lixing@loongson.cn) +- Add patch for gb18030-2022 from upstream bug#30243 (fundawang@yeah.net) * Wed Sep 20 2023 Siddhesh Poyarekar - 2.28-236.6 - CVE-2023-4911 glibc: buffer overflow in ld.so leading to privilege escalation (RHEL-3035)