From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pl1-x636.google.com (mail-pl1-x636.google.com [IPv6:2607:f8b0:4864:20::636]) by sourceware.org (Postfix) with ESMTPS id 66414385840D for ; Tue, 23 Apr 2024 20:10:09 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 66414385840D Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 66414385840D Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::636 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1713903013; cv=none; b=eq4oXW0PXvbsAzXkGfi+HD77JwE2KcN2ZUYc4Z42Qfgyz4v+hgx5rp77RR1F+I9JPU6nL0kClPo3PSxW6UCbid+PJwdLq0RMYn+XCOR/jH19jDCy1k9vrlOhCOcbnntsBXLihdWUztDE6TcVcURYaMKA4axj2dWShn6FSVvLHPQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1713903013; c=relaxed/simple; bh=uAjK+/WYj4KiAL0omXhLGNc90VFkchPXSb5dkLfO6tg=; h=DKIM-Signature:Message-ID:Date:MIME-Version:Subject:To:From; b=N+CfS/Sij91GhA7JGXZBEo3lOF2FLIQIIdpgPfOj0xol/2rTV3JLVFyo+FHm9Q/tJJKTB9w9bkUgHervP1iNvxsada1GoP0e9I6Rx08d6u3GFcFH0lKQ/eJqUm/cVTugLwh4nQqUhzu07HOVfRMLOoXhen5Pf0wB1Exrq6tMtO0= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pl1-x636.google.com with SMTP id d9443c01a7336-1e411e339b8so47019135ad.3 for ; Tue, 23 Apr 2024 13:10:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1713903008; x=1714507808; darn=sourceware.org; h=content-transfer-encoding:in-reply-to:organization:from :content-language:references:cc:to:subject:user-agent:mime-version :date:message-id:from:to:cc:subject:date:message-id:reply-to; bh=62TLdEBDk8ZF2AAQNGMUiLLt+XhdWhKLcO17y05ib0g=; b=gOVUAVS487G6qLZJzSiCTZnsO/W5H4pyGz34kTrUNs0HsRZbVusSd6Z4g+tsGSey10 3O/nACjdozOrVGGLUtFKEtmWbIKfsUDEmMUUNiuS8U8qLqnKFONPhWODxKZCA8KVKHwf XNHFmMi3Gfq8wFLiJ4sBemMKEJn+YwKpTAHfWuyf8NtimPVurlW6MI4l407wu9/VAZCC AWdj2ArRrjv6ytfUbtNfFLTbiBQYhEi0Wm8jkz14ZQLPiBo4Gs+Lk2SR1rOcvhb8Fcc2 Inoig36Lchc9zaGleGKIaoAFdNgZ25teAvKK6ctSUSJvdAFmI27db++ZWRpABVtGpDof 0k2A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1713903008; x=1714507808; h=content-transfer-encoding:in-reply-to:organization:from :content-language:references:cc:to:subject:user-agent:mime-version :date:message-id:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=62TLdEBDk8ZF2AAQNGMUiLLt+XhdWhKLcO17y05ib0g=; b=WYakoc7nStv7ebn2cPhdgaRG4TuAi1qRYesFa3vZ+9WjErndj0PNqJBKS0Wt6dGk1V mQRZ/KSpfmy2edKnPGbwTrKm2iaT/aptybIeIfMFDKOFmm79PldmWfgQbi+ov99VP6Tk KHhg/iVYSkgz3slq5rQ744KJ7KDWbnuqJCR1q9Sgu5FdXwBRLLyg6rRywMlc6V0l1iXb Ccf2u7v745FDaUttWEr9SMQK/AOfqr9olTB6MU11FDia8GKFEF+MM7LqU55c3JlgEwQE J8Ag8S5A1Ir/+6teLbglAFONnWtl6k3ngqioZWb+qz49/sl381WgVyQ3pyo64lh1GwH+ ci5g== X-Forwarded-Encrypted: i=1; AJvYcCWLvQhFfuw4ZkHvu5swVrbURL9MWoq7Bb61E98WYljUXrJkT2Cy/UWrB34ANVl1lepUhKblp7p1QEHG5UApBxW5RiCj2rBNvDq/ X-Gm-Message-State: AOJu0Yz9sOcBr0czq3qKE8Uww3B7zZlXSE4V01EX3RJkovQ9w8o1ri1R Xa3Afbjz4c3lLNfOmmjLmw9EUxexd5xbN/rYtFOeFHGakvlJGaCcO3qpYeqO0ojYutw9OJYLYJh 3 X-Google-Smtp-Source: AGHT+IEOgHMQ2kasBDot3hq93wfm9A9YWOfACnmi823Xp9EyH5Rs72naDnUq5Aje8RZ7jg4Gksc7EA== X-Received: by 2002:a17:902:ced1:b0:1e2:718c:61e with SMTP id d17-20020a170902ced100b001e2718c061emr610999plg.27.1713903008137; Tue, 23 Apr 2024 13:10:08 -0700 (PDT) Received: from ?IPV6:2804:1b3:a7c1:6157:e8dc:fc2f:3a83:26ff? ([2804:1b3:a7c1:6157:e8dc:fc2f:3a83:26ff]) by smtp.gmail.com with ESMTPSA id j12-20020a170903024c00b001db66f3748fsm10451880plh.182.2024.04.23.13.10.06 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 23 Apr 2024 13:10:07 -0700 (PDT) Message-ID: Date: Tue, 23 Apr 2024 17:10:04 -0300 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH] LoongArch: Add glibc.cpu.hwcap support. To: caiyinyu , libc-alpha@sourceware.org Cc: xry111@xry111.site References: <20240423124851.382241-1-caiyinyu@loongson.cn> Content-Language: en-US From: Adhemerval Zanella Netto Organization: Linaro In-Reply-To: <20240423124851.382241-1-caiyinyu@loongson.cn> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-12.8 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_SHORT,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On 23/04/24 09:48, caiyinyu wrote: > The current IFUNC selection is always using the most recent > features which are available via AT_HWCAP. But in > some scenarios it is useful to adjust this selection. > > The environment variable: > > GLIBC_TUNABLES=glibc.cpu.hwcaps=-xxx,yyy,zzz,.... > > can be used to enable HWCAP feature yyy, disable HWCAP feature xxx, > where the feature name is case-sensitive and has to match the ones > used in sysdeps/loongarch/cpu-tunables.c. The patch looks good, just two minor style issues below. > --- > manual/tunables.texi | 5 +- > sysdeps/loongarch/Makefile | 12 ++ > sysdeps/loongarch/cpu-tunables.c | 87 +++++++++++ > sysdeps/loongarch/dl-get-cpu-features.c | 25 ++++ > sysdeps/loongarch/dl-machine.h | 29 +++- > sysdeps/loongarch/dl-tunables.list | 25 ++++ > .../lp64/multiarch/dl-symbol-redir-ifunc.h | 3 + > sysdeps/loongarch/tst-hwcap-tunables.c | 136 ++++++++++++++++++ > .../unix/sysv/linux/loongarch/cpu-features.c | 30 ++++ > .../unix/sysv/linux/loongarch/cpu-features.h | 17 ++- > .../unix/sysv/linux/loongarch/dl-procinfo.c | 60 ++++++++ > sysdeps/unix/sysv/linux/loongarch/dl-sysdep.c | 21 +++ > .../unix/sysv/linux/loongarch/libc-start.c | 34 +++++ > 13 files changed, 475 insertions(+), 9 deletions(-) > create mode 100644 sysdeps/loongarch/cpu-tunables.c > create mode 100644 sysdeps/loongarch/dl-get-cpu-features.c > create mode 100644 sysdeps/loongarch/dl-tunables.list > create mode 100644 sysdeps/loongarch/tst-hwcap-tunables.c > create mode 100644 sysdeps/unix/sysv/linux/loongarch/cpu-features.c > create mode 100644 sysdeps/unix/sysv/linux/loongarch/dl-procinfo.c > create mode 100644 sysdeps/unix/sysv/linux/loongarch/dl-sysdep.c > create mode 100644 sysdeps/unix/sysv/linux/loongarch/libc-start.c > > diff --git a/manual/tunables.texi b/manual/tunables.texi > index 4a7d04dc0d..baaf751721 100644 > --- a/manual/tunables.texi > +++ b/manual/tunables.texi > @@ -525,7 +525,10 @@ a CPU arch-level like @code{z13} instead of single HWCAP and STFLE features. > On powerpc, the supported HWCAP and HWCAP2 features can be found in > @code{sysdeps/powerpc/dl-procinfo.c}. > > -This tunable is specific to i386, x86-64, s390x and powerpc. > +On loongarch, the supported HWCAP features can be found in > +@code{sysdeps/loongarch/cpu-tunables.c}. > + > +This tunable is specific to i386, x86-64, s390x, powerpc and loongarch. > @end deftp > > @deftp Tunable glibc.cpu.cached_memopt Ok. As a side note, from a recent BZ report [1] I think maybe we should start to proper document the supported HWCAP for ifunc selection instead of reference a source file. [1] https://sourceware.org/bugzilla/show_bug.cgi?id=31675 > diff --git a/sysdeps/loongarch/Makefile b/sysdeps/loongarch/Makefile > index 43d2f583cd..965daae571 100644 > --- a/sysdeps/loongarch/Makefile > +++ b/sysdeps/loongarch/Makefile > @@ -1,11 +1,23 @@ > ifeq ($(subdir),misc) > sysdep_headers += sys/asm.h > + > +tests += \ > + tst-hwcap-tunables \ > + # tests > + > +tst-hwcap-tunables-ARGS = -- $(host-test-program-cmd) > endif > > ifeq ($(subdir),elf) > gen-as-const-headers += dl-link.sym > endif > > +ifeq ($(subdir),elf) > +sysdep-dl-routines += \ > + dl-get-cpu-features \ > + # sysdep-dl-routines > +endif > + > # LoongArch's assembler also needs to know about PIC as it changes the > # definition of some assembler macros. > ASFLAGS-.os += $(pic-ccflag) Minor nit, other files use a double space instead of tab for each new entry. > diff --git a/sysdeps/loongarch/cpu-tunables.c b/sysdeps/loongarch/cpu-tunables.c > new file mode 100644 > index 0000000000..e274e993c1 > --- /dev/null > +++ b/sysdeps/loongarch/cpu-tunables.c > @@ -0,0 +1,87 @@ > +/* LoongArch CPU feature tuning. > + This file is part of the GNU C Library. > + Copyright (C) 2024 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 > +#include /* Get STDOUT_FILENO for _dl_printf. */ > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#define CHECK_GLIBC_IFUNC_CPU(f, name, len) \ > + _Static_assert (sizeof (#name) - 1 == len, #name " != " #len); \ > + if (tunable_str_comma_strcmp_cte (&f, #name)) \ > + { \ > + if (f.disable) \ > + GLRO(dl_larch_cpu_features).hwcap &= (~HWCAP_LOONGARCH_##name); \ > + else \ > + GLRO(dl_larch_cpu_features).hwcap |= HWCAP_LOONGARCH_##name; \ > + break; \ > + } > + > +attribute_hidden void > +TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *valp) > +{ > + /* The current IFUNC selection is based on microbenchmarks in glibc. > + It should give the best performance for most workloads. But other > + choices may have better performance for a particular workload or on > + the hardware which wasn't available when the selection was made. > + The environment variable: > + > + GLIBC_TUNABLES=glibc.cpu.hwcaps=-xxx,yyy,-zzz,.... > + > + can be used to enable CPU/ARCH feature yyy, disable CPU/ARCH feature > + yyy and zzz, where the feature name is case-sensitive and has to > + match the ones in cpu-features.h. It can be used by glibc developers > + to tune for a new processor or override the IFUNC selection to > + improve performance for a particular workload. > + > + NOTE: the IFUNC selection may change over time. Please check all > + multiarch implementations when experimenting. */ > + > + struct tunable_str_comma_state_t ts; > + tunable_str_comma_init (&ts, valp); > + > + struct tunable_str_comma_t n; > + while (tunable_str_comma_next (&ts, &n)) > + { > + switch (n.len) > + { > + default: > + break; > + case 3: > + { > + CHECK_GLIBC_IFUNC_CPU (n, LSX, 3); > + CHECK_GLIBC_IFUNC_CPU (n, UAL, 3); > + } > + break; > + case 4: > + { > + CHECK_GLIBC_IFUNC_CPU (n, LASX, 4); > + } > + break; > + } > + } > + > + /* Ensure that the user has not enabled any unsupported features. */ > + GLRO(dl_larch_cpu_features).hwcap &= GLRO(dl_hwcap); > +} Ok. > diff --git a/sysdeps/loongarch/dl-get-cpu-features.c b/sysdeps/loongarch/dl-get-cpu-features.c > new file mode 100644 > index 0000000000..3dcecefbcd > --- /dev/null > +++ b/sysdeps/loongarch/dl-get-cpu-features.c > @@ -0,0 +1,25 @@ > +/* Define _dl_larch_get_cpu_features. > + Copyright (C) 2024 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); > +} Ok. > diff --git a/sysdeps/loongarch/dl-machine.h b/sysdeps/loongarch/dl-machine.h > index ab81b82d95..6baf0e600a 100644 > --- a/sysdeps/loongarch/dl-machine.h > +++ b/sysdeps/loongarch/dl-machine.h > @@ -29,6 +29,8 @@ > #include > #include > > +#include > + > #ifndef _RTLD_PROLOGUE > # define _RTLD_PROLOGUE(entry) \ > ".globl\t" __STRING (entry) "\n\t" \ > @@ -53,6 +55,23 @@ > #define ELF_MACHINE_NO_REL 1 > #define ELF_MACHINE_NO_RELA 0 > > +#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 > + /* 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 > elf_machine_matches_host (const ElfW (Ehdr) *ehdr) > @@ -290,10 +309,10 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], > #ifdef SHARED > if (profile != 0) > { > -# if !defined __loongarch_soft_float > - if (SUPPORT_LASX) > +#if !defined __loongarch_soft_float > + if (RTLD_SUPPORT_LASX) > gotplt[0] = (ElfW(Addr)) &_dl_runtime_profile_lasx; > - else if (SUPPORT_LSX) > + else if (RTLD_SUPPORT_LSX) > gotplt[0] = (ElfW(Addr)) &_dl_runtime_profile_lsx; > else > # endif > @@ -312,9 +331,9 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], > indicated by the offset on the stack, and then jump to > the resolved address. */ > #if !defined __loongarch_soft_float > - if (SUPPORT_LASX) > + if (RTLD_SUPPORT_LASX) > gotplt[0] = (ElfW(Addr)) &_dl_runtime_resolve_lasx; > - else if (SUPPORT_LSX) > + else if (RTLD_SUPPORT_LSX) > gotplt[0] = (ElfW(Addr)) &_dl_runtime_resolve_lsx; > else > #endif Ok, lazy resolvers should not depend of the glibc.cpu.hwcap value. > diff --git a/sysdeps/loongarch/dl-tunables.list b/sysdeps/loongarch/dl-tunables.list > new file mode 100644 > index 0000000000..00869a9fad > --- /dev/null > +++ b/sysdeps/loongarch/dl-tunables.list > @@ -0,0 +1,25 @@ > +# LoongArch specific tunables. > +# Copyright (C) 2024 Free Software Foundation, Inc. > +# This file is part of the GNU C Library. > + > +# The GNU C Library is free software; you can redistribute it and/or > +# modify it under the terms of the GNU Lesser General Public > +# License as published by the Free Software Foundation; either > +# version 2.1 of the License, or (at your option) any later version. > + > +# The GNU C Library is distributed in the hope that it will be useful, > +# but WITHOUT ANY WARRANTY; without even the implied warranty of > +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > +# Lesser General Public License for 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 > + } > + } > +} Ok. > diff --git a/sysdeps/loongarch/lp64/multiarch/dl-symbol-redir-ifunc.h b/sysdeps/loongarch/lp64/multiarch/dl-symbol-redir-ifunc.h > index cb640d77b7..a73390b12f 100644 > --- a/sysdeps/loongarch/lp64/multiarch/dl-symbol-redir-ifunc.h > +++ b/sysdeps/loongarch/lp64/multiarch/dl-symbol-redir-ifunc.h > @@ -19,6 +19,9 @@ > #ifndef _DL_IFUNC_GENERIC_H > #define _DL_IFUNC_GENERIC_H > > +#ifndef SHARED > asm ("memset = __memset_aligned"); > +asm ("memcmp = __memcmp_aligned"); > +#endif > > #endif Ok. > diff --git a/sysdeps/loongarch/tst-hwcap-tunables.c b/sysdeps/loongarch/tst-hwcap-tunables.c > new file mode 100644 > index 0000000000..e6856ad042 > --- /dev/null > +++ b/sysdeps/loongarch/tst-hwcap-tunables.c > @@ -0,0 +1,136 @@ > +/* Tests for powerpc GLIBC_TUNABLES=glibc.cpu.hwcaps filter. > + Copyright (C) 2024 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for 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 > +#include > + > +/* Nonzero if the program gets called via `exec'. */ > +#define CMDLINE_OPTIONS \ > + { "restart", no_argument, &restart, 1 }, \ > + { "enable", no_argument, &enable, 1 }, > +static int restart; > +static int enable; > + > +/* Hold the four initial argument used to respawn the process, plus the extra > + '--direct', '--restart', and the function to check. */ > +static char *spargs[9]; > +static int fc; > + > +/* Called on process re-execution. */ > +_Noreturn static void > +handle_restart (int argc, char *argv[]) > +{ > + TEST_VERIFY_EXIT (argc == 1); > + const char *funcname = argv[0]; > + > + struct libc_ifunc_impl impls[32]; > + int cnt = __libc_ifunc_impl_list ("memcpy", impls, array_length (impls)); > + if (cnt == 0) > + _exit (EXIT_SUCCESS); > + TEST_VERIFY_EXIT (cnt >= 1); > + for (int i = 0; i < cnt; i++) > + { > + if (strcmp (impls[i].name, funcname) == 0) > + { > + if (enable && impls[i].usable != true) > + FAIL_EXIT1 ("FAIL: %s ifunc selection is not enabled.\n", funcname); > + else if (!enable && impls[i].usable != false) > + FAIL_EXIT1 ("FAIL: %s ifunc selection is not disabled.\n", funcname); > + break; > + } > + } > + > + _exit (EXIT_SUCCESS); > +} > + > +static void > +run_test (const char *filter, const char *funcname, int disable) > +{ > + if (disable) > + printf ("info: checking filter %s (expect %s ifunc " > + "selection to be disabled)\n", filter, funcname); > + else > + { > + printf ("info: checking filter %s (expect %s ifunc " > + "selection to be enabled)\n", filter, funcname); > + spargs[fc++] = (char *) "--enable"; > + } > + > + char *tunable = xasprintf ("GLIBC_TUNABLES=glibc.cpu.hwcaps=%s", filter); > + char *const newenvs[] = { (char*) tunable, NULL }; > + spargs[fc] = (char *) funcname; > + > + pid_t pid; > + TEST_COMPARE (posix_spawn (&pid, spargs[0], NULL, NULL, spargs, newenvs), 0); > + int status; > + TEST_COMPARE (xwaitpid (pid, &status, 0), pid); > + TEST_VERIFY (WIFEXITED (status)); > + TEST_VERIFY (!WIFSIGNALED (status)); > + TEST_COMPARE (WEXITSTATUS (status), 0); > + > + if (!disable) > + fc--; > + free (tunable); > +} > + > +static int > +do_test (int argc, char *argv[]) > +{ > + if (restart) > + handle_restart (argc - 1, &argv[1]); > + > + TEST_VERIFY_EXIT (argc == 2 || argc == 5); > + > + int i; > + for (i = 0; i < argc - 1; i++) > + spargs[i] = argv[i + 1]; > + spargs[i++] = (char *) "--direct"; > + spargs[i++] = (char *) "--restart"; > + fc = i++; > + spargs[i] = NULL; > + > + unsigned long int hwcap = getauxval (AT_HWCAP); > + > + if (hwcap & HWCAP_LOONGARCH_LASX) > + run_test ("-LASX", "__memcpy_lasx", 1); > + if (hwcap & HWCAP_LOONGARCH_LSX) > + run_test ("-LSX", "__memcpy_lsx", 1); > + if (hwcap & HWCAP_LOONGARCH_UAL) > + run_test ("-UAL", "__memcpy_unaligned", 1); > + > + /* __memcpy_aligned is the default ifunc selection and will be > + * always enabled. */ > + run_test ("-LASX,-LSX,-UAL", "__memcpy_aligned", 0); > + run_test ("-LASX,-LSX", "__memcpy_aligned", 0); > + run_test ("-LASX", "__memcpy_aligned", 0); > + > + return 0; > +} > + > +#define TEST_FUNCTION_ARGV do_test > +#include Ok. > 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 0000000000..9c526516d8 > --- /dev/null > +++ b/sysdeps/unix/sysv/linux/loongarch/cpu-features.c > @@ -0,0 +1,30 @@ > +/* Initialize CPU feature data. LoongArch64 version. > + This file is part of the GNU C Library. > + Copyright (C) 2024 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 > +#include > +extern void TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *) attribute_hidden; > + > +static inline void > +init_cpu_features (struct cpu_features *cpu_features) > +{ > + GLRO(dl_larch_cpu_features).hwcap = GLRO(dl_hwcap); > + TUNABLE_GET (glibc, cpu, hwcaps, tunable_val_t *, > + TUNABLE_CALLBACK (set_hwcaps)); > +} Minor nit, the indentation should use double space. > diff --git a/sysdeps/unix/sysv/linux/loongarch/cpu-features.h b/sysdeps/unix/sysv/linux/loongarch/cpu-features.h > index 4e863c7469..eec51956a9 100644 > --- a/sysdeps/unix/sysv/linux/loongarch/cpu-features.h > +++ b/sysdeps/unix/sysv/linux/loongarch/cpu-features.h > @@ -19,12 +19,23 @@ > #ifndef _CPU_FEATURES_LOONGARCH64_H > #define _CPU_FEATURES_LOONGARCH64_H > > +#include > #include > > -#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) > +struct cpu_features > +{ > + uint64_t hwcap; > +}; > > +/* Get a pointer to the CPU features structure. */ > +extern const struct cpu_features * > +_dl_larch_get_cpu_features (void) __attribute__ ((pure)); > + > +#define SUPPORT_UAL (GLRO (dl_larch_cpu_features).hwcap & HWCAP_LOONGARCH_UAL) > +#define SUPPORT_LSX (GLRO (dl_larch_cpu_features).hwcap & HWCAP_LOONGARCH_LSX) > +#define SUPPORT_LASX (GLRO (dl_larch_cpu_features).hwcap & HWCAP_LOONGARCH_LASX) > +#define RTLD_SUPPORT_LSX (GLRO (dl_hwcap) & HWCAP_LOONGARCH_LSX) > +#define RTLD_SUPPORT_LASX (GLRO (dl_hwcap) & HWCAP_LOONGARCH_LASX) > #define INIT_ARCH() > > #endif /* _CPU_FEATURES_LOONGARCH64_H */ Ok. > 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 0000000000..5e056a1923 > --- /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) 2024 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for 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 Ok. > 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 0000000000..30b84f1911 > --- /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) 2024 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for 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 Ok. > 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 0000000000..e545f7f1d7 > --- /dev/null > +++ b/sysdeps/unix/sysv/linux/loongarch/libc-start.c > @@ -0,0 +1,34 @@ > +/* Override csu/libc-start.c on LoongArch64. > + Copyright (C) 2024 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for 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 > + > +/* Mark symbols hidden in static PIE for early self relocation to work. */ > +#if BUILD_PIE_DEFAULT > +# pragma GCC visibility push (hidden) > +#endif > + > +#include > +#include > + > +extern struct cpu_features _dl_larch_cpu_features; > + > +#define ARCH_INIT_CPU_FEATURES() init_cpu_features (&_dl_larch_cpu_features) > + > +#endif > +#include OK.