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