Fix compiler warnings produced by clang 19.
[valgrind.git] / tests / arm64_features.c
blob66744cc6d4a1cd2e3807f10fd7c4843055b96757
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #if !defined(__APPLE__) && defined(VGA_arm64)
5 #include <sys/auxv.h>
6 #endif
8 #if defined(VGO_freebsd)
9 #include <elf.h>
10 #include <sys/exec.h>
12 unsigned long getauxval(unsigned long type);
14 unsigned long getauxval(unsigned long type)
16 extern char** environ;
17 char** envp = environ;
18 Elf_Auxinfo *auxp;
19 while(*envp++ != NULL)
21 for (auxp = (Elf_Auxinfo *)envp; auxp->a_type != AT_NULL; auxp++)
23 if (type == auxp->a_type)
25 return (unsigned long)auxp->a_un.a_val;
28 return 0UL;
30 #endif
33 // This file determines arm64 features a processor supports.
34 // Arm processors do not have a x86-like cpuinfo instruction. Instead the
35 // getauxval() syscall is used with capabilities parameters: getauxval(AT_HWCAP)
36 // and getauxval(AT_HWCAP2).
38 // We return:
39 // - 0 if the machine has the asked-for feature.
40 // - 1 if the machine doesn't have the asked-for feature.
41 // - 2 if the asked-for feature isn't recognised (this will always be the case
42 // for any feature if run on a non-arm64 machine).
43 // - 3 if there was a usage error (it also prints an error message).
44 #define FEATURE_PRESENT 0
45 #define FEATURE_NOT_PRESENT 1
46 #define UNRECOGNISED_FEATURE 2
47 #define USAGE_ERROR 3
49 #define False 0
50 #define True 1
51 typedef int Bool;
53 #if defined(VGA_arm64)
55 // The processor's capabilities/features are returned by getauxval() as an
56 // unsigned long with each bit representing a capability/feature.
57 #ifndef HWCAP_FP
58 #define HWCAP_FP (1 << 0)
59 #endif
60 #ifndef HWCAP_ASIMD
61 #define HWCAP_ASIMD (1 << 1)
62 #endif
63 #ifndef HWCAP_EVTSTRM
64 #define HWCAP_EVTSTRM (1 << 2)
65 #endif
66 #ifndef HWCAP_AES
67 #define HWCAP_AES (1 << 3)
68 #endif
69 #ifndef HWCAP_PMULL
70 #define HWCAP_PMULL (1 << 4)
71 #endif
72 #ifndef HWCAP_SHA1
73 #endif
74 #ifndef HWCAP_SHA1
75 #define HWCAP_SHA1 (1 << 5)
76 #endif
77 #ifndef HWCAP_SHA2
78 #define HWCAP_SHA2 (1 << 6)
79 #endif
80 #ifndef HWCAP_CRC32
81 #define HWCAP_CRC32 (1 << 7)
82 #endif
83 #ifndef HWCAP_ATOMICS
84 #define HWCAP_ATOMICS (1 << 8)
85 #endif
86 #ifndef HWCAP_FPHP
87 #define HWCAP_FPHP (1 << 9)
88 #endif
89 #ifndef HWCAP_ASIMDHP
90 #define HWCAP_ASIMDHP (1 << 10)
91 #endif
92 #ifndef HWCAP_CPUID
93 #define HWCAP_CPUID (1 << 11)
94 #endif
95 #ifndef HWCAP_ASIMDRDM
96 #define HWCAP_ASIMDRDM (1 << 12)
97 #endif
98 #ifndef HWCAP_JSCVT
99 #define HWCAP_JSCVT (1 << 13)
100 #endif
101 #ifndef HWCAP_FCMA
102 #define HWCAP_FCMA (1 << 14)
103 #endif
104 #ifndef HWCAP_LRCPC
105 #define HWCAP_LRCPC (1 << 15)
106 #endif
107 #ifndef HWCAP_DCPOP
108 #define HWCAP_DCPOP (1 << 16)
109 #endif
110 #ifndef HWCAP_SHA3
111 #define HWCAP_SHA3 (1 << 17)
112 #endif
113 #ifndef HWCAP_SM3
114 #define HWCAP_SM3 (1 << 18)
115 #endif
116 #ifndef HWCAP_SM4
117 #define HWCAP_SM4 (1 << 19)
118 #endif
119 #ifndef HWCAP_ASIMDDP
120 #define HWCAP_ASIMDDP (1 << 20)
121 #endif
122 #ifndef HWCAP_SHA512
123 #define HWCAP_SHA512 (1 << 21)
124 #endif
125 #ifndef HWCAP_SVE
126 #define HWCAP_SVE (1 << 22)
127 #endif
128 #ifndef HWCAP_ASIMDFHM
129 #define HWCAP_ASIMDFHM (1 << 23)
130 #endif
131 #ifndef HWCAP_DIT
132 #define HWCAP_DIT (1 << 24)
133 #endif
134 #ifndef HWCAP_USCAT
135 #define HWCAP_USCAT (1 << 25)
136 #endif
137 #ifndef HWCAP_ILRCPC
138 #define HWCAP_ILRCPC (1 << 26)
139 #endif
140 #ifndef HWCAP_FLAGM
141 #define HWCAP_FLAGM (1 << 27)
142 #endif
143 #ifndef HWCAP_SSBS
144 #define HWCAP_SSBS (1 << 28)
145 #endif
146 #ifndef HWCAP_SB
147 #define HWCAP_SB (1 << 29)
148 #endif
149 #ifndef HWCAP_PACA
150 #define HWCAP_PACA (1 << 30)
151 #endif
152 #ifndef HWCAP_PACG
153 #define HWCAP_PACG (1UL << 31)
154 #endif
156 #ifndef HWCAP2_DCPODP
157 #define HWCAP2_DCPODP (1 << 0)
158 #endif
159 #ifndef HWCAP2_SVE2
160 #define HWCAP2_SVE2 (1 << 1)
161 #endif
162 #ifndef HWCAP2_SVEAES
163 #define HWCAP2_SVEAES (1 << 2)
164 #endif
165 #ifndef HWCAP2_SVEPMULL
166 #define HWCAP2_SVEPMULL (1 << 3)
167 #endif
168 #ifndef HWCAP2_SVEBITPERM
169 #define HWCAP2_SVEBITPERM (1 << 4)
170 #endif
171 #ifndef HWCAP2_SVESHA3
172 #define HWCAP2_SVESHA3 (1 << 5)
173 #endif
174 #ifndef HWCAP2_SVESM4
175 #define HWCAP2_SVESM4 (1 << 6)
176 #endif
177 #ifndef HWCAP2_FLAGM2
178 #define HWCAP2_FLAGM2 (1 << 7)
179 #endif
180 #ifndef HWCAP2_FRINT
181 #define HWCAP2_FRINT (1 << 8)
182 #endif
184 unsigned long hwcaps[] = {
185 HWCAP_FP, HWCAP_ASIMD, HWCAP_EVTSTRM, HWCAP_AES, HWCAP_PMULL,
186 HWCAP_SHA1, HWCAP_SHA2, HWCAP_CRC32, HWCAP_ATOMICS, HWCAP_FPHP,
187 HWCAP_ASIMDHP,HWCAP_CPUID, HWCAP_ASIMDRDM,HWCAP_JSCVT, HWCAP_FCMA,
188 HWCAP_LRCPC, HWCAP_DCPOP, HWCAP_SHA3, HWCAP_SM3, HWCAP_SM4,
189 HWCAP_ASIMDDP,HWCAP_SHA512, HWCAP_SVE, HWCAP_ASIMDFHM,HWCAP_DIT,
190 HWCAP_USCAT, HWCAP_ILRCPC, HWCAP_FLAGM, HWCAP_SSBS, HWCAP_SB,
191 HWCAP_PACA, HWCAP_PACG, 0ul};
193 unsigned long hwcaps2[] = {
194 HWCAP2_DCPODP, HWCAP2_SVE2, HWCAP2_SVEAES, HWCAP2_SVEPMULL,
195 HWCAP2_SVEBITPERM, HWCAP2_SVESHA3, HWCAP2_SVESM4, HWCAP2_FLAGM2,
196 HWCAP2_FRINT, 0ul};
198 typedef struct
200 char name[16];
201 unsigned long cap_bit;
202 } capability;
204 capability capabilities[] = {
205 {"fp", HWCAP_FP}, {"asimd", HWCAP_ASIMD},
206 {"evtstrm", HWCAP_EVTSTRM}, {"aes", HWCAP_AES},
207 {"pmull", HWCAP_PMULL}, {"sha1", HWCAP_SHA1},
208 {"sha2", HWCAP_SHA2}, {"crc32", HWCAP_CRC32},
209 {"atomics", HWCAP_ATOMICS}, {"fphp", HWCAP_FPHP},
210 {"asimdhp", HWCAP_ASIMDHP}, {"cpuid", HWCAP_CPUID},
211 {"asimdrdm", HWCAP_ASIMDRDM}, {"jscvt", HWCAP_JSCVT},
212 {"fcma", HWCAP_FCMA}, {"lrcpc", HWCAP_LRCPC},
213 {"dcpop", HWCAP_DCPOP}, {"sha3", HWCAP_SHA3},
214 {"sm3", HWCAP_SM3}, {"sm4", HWCAP_SM4},
215 {"asimddp", HWCAP_ASIMDDP}, {"sha512", HWCAP_SHA512},
216 {"sve", HWCAP_SVE}, {"asimdfhm", HWCAP_ASIMDFHM},
217 {"dit", HWCAP_DIT}, {"uscat", HWCAP_USCAT},
218 {"ilrcpc", HWCAP_ILRCPC}, {"flagm", HWCAP_FLAGM},
219 {"ssbs", HWCAP_SSBS}, {"sb", HWCAP_SB},
220 {"paca", HWCAP_PACA}, {"pacg", HWCAP_PACG},
221 {"", 0ul}
224 capability capabilities2[] = {
225 {"dcpodp", HWCAP2_DCPODP}, {"sve2", HWCAP2_SVE2},
226 {"sveaes", HWCAP2_SVEAES}, {"svepmull", HWCAP2_SVEPMULL},
227 {"svebitperm", HWCAP2_SVEBITPERM}, {"svesha3", HWCAP2_SVESHA3},
228 {"svesm4", HWCAP2_SVESM4}, {"flagm2", HWCAP2_FLAGM2},
229 {"frint", HWCAP2_FRINT}, {"", 0ul}
232 typedef struct
234 unsigned long hwcap;
235 unsigned long hwcap2;
236 } hwc;
238 #define CAPABILITIES_SEARCH_LOOP(hwcversion) \
239 for (int i = 0; capabilities ## hwcversion[i].cap_bit; ++i) \
240 if (strcmp(name, capabilities ## hwcversion[i].name) == 0) { \
241 caps->hwcap ## hwcversion = capabilities ## hwcversion[i].cap_bit; \
242 return True; \
245 static Bool get_feature_from_string(const char *name, hwc *caps)
247 caps->hwcap = caps->hwcap2 = 0;
248 CAPABILITIES_SEARCH_LOOP()
249 CAPABILITIES_SEARCH_LOOP(2)
250 return False;
253 static int go(const char* feature_name)
255 hwc hw;
256 unsigned long hwcap = getauxval(AT_HWCAP);
257 unsigned long hwcap2 = getauxval(AT_HWCAP2);
259 if (!get_feature_from_string(feature_name, &hw))
260 return UNRECOGNISED_FEATURE;
262 if ((hw.hwcap & hwcap) || (hw.hwcap2 & hwcap2))
263 return FEATURE_PRESENT;
265 return FEATURE_NOT_PRESENT;
268 #else
270 static Bool go(const char* feature_name)
272 // Feature not recognised (non-arm64 machine!)
273 return UNRECOGNISED_FEATURE;
276 #endif // defined(VGA_arm64)
279 //---------------------------------------------------------------------------
280 // main
281 //---------------------------------------------------------------------------
282 int main(int argc, char **argv)
284 if (argc != 2) {
285 fprintf(stderr, "usage: arm64_features <feature>\n");
286 exit(USAGE_ERROR);
288 return go(argv[1]);