]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/loongarch/cpu-tunables.c
LoongArch: Add glibc.cpu.hwcap support.
[thirdparty/glibc.git] / sysdeps / loongarch / cpu-tunables.c
1 /* LoongArch CPU feature tuning.
2 This file is part of the GNU C Library.
3 Copyright (C) 2024 Free Software Foundation, Inc.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
18
19 #include <stdbool.h>
20 #include <stdint.h>
21 #include <unistd.h> /* Get STDOUT_FILENO for _dl_printf. */
22 #include <elf/dl-tunables.h>
23 #include <string.h>
24 #include <cpu-features.h>
25 #include <ldsodefs.h>
26 #include <sys/auxv.h>
27 #include <dl-tunables-parse.h>
28 #include <dl-symbol-redir-ifunc.h>
29
30 #define CHECK_GLIBC_IFUNC_CPU(f, name, len) \
31 _Static_assert (sizeof (#name) - 1 == len, #name " != " #len); \
32 if (tunable_str_comma_strcmp_cte (&f, #name)) \
33 { \
34 if (f.disable) \
35 GLRO(dl_larch_cpu_features).hwcap &= (~HWCAP_LOONGARCH_##name); \
36 else \
37 GLRO(dl_larch_cpu_features).hwcap |= HWCAP_LOONGARCH_##name; \
38 break; \
39 }
40
41 attribute_hidden void
42 TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *valp)
43 {
44 /* The current IFUNC selection is based on microbenchmarks in glibc.
45 It should give the best performance for most workloads. But other
46 choices may have better performance for a particular workload or on
47 the hardware which wasn't available when the selection was made.
48 The environment variable:
49
50 GLIBC_TUNABLES=glibc.cpu.hwcaps=-xxx,yyy,-zzz,....
51
52 can be used to enable CPU/ARCH feature yyy, disable CPU/ARCH feature
53 yyy and zzz, where the feature name is case-sensitive and has to
54 match the ones in cpu-features.h. It can be used by glibc developers
55 to tune for a new processor or override the IFUNC selection to
56 improve performance for a particular workload.
57
58 NOTE: the IFUNC selection may change over time. Please check all
59 multiarch implementations when experimenting. */
60
61 struct tunable_str_comma_state_t ts;
62 tunable_str_comma_init (&ts, valp);
63
64 struct tunable_str_comma_t n;
65 while (tunable_str_comma_next (&ts, &n))
66 {
67 switch (n.len)
68 {
69 default:
70 break;
71 case 3:
72 {
73 CHECK_GLIBC_IFUNC_CPU (n, LSX, 3);
74 CHECK_GLIBC_IFUNC_CPU (n, UAL, 3);
75 }
76 break;
77 case 4:
78 {
79 CHECK_GLIBC_IFUNC_CPU (n, LASX, 4);
80 }
81 break;
82 }
83 }
84
85 /* Ensure that the user has not enabled any unsupported features. */
86 GLRO(dl_larch_cpu_features).hwcap &= GLRO(dl_hwcap);
87 }