1 #pragma once
2 #ifndef CPUINFO_H
3 #define CPUINFO_H
4 
5 #ifndef __cplusplus
6 	#include <stdbool.h>
7 #endif
8 
9 #ifdef __APPLE__
10 	#include <TargetConditionals.h>
11 #endif
12 
13 #include <stdint.h>
14 
15 /* Identify architecture and define corresponding macro */
16 
17 #if defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) || defined(_M_IX86)
18 	#define CPUINFO_ARCH_X86 1
19 #endif
20 
21 #if defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64)
22 	#define CPUINFO_ARCH_X86_64 1
23 #endif
24 
25 #if defined(__arm__) || defined(_M_ARM)
26 	#define CPUINFO_ARCH_ARM 1
27 #endif
28 
29 #if defined(__aarch64__) || defined(_M_ARM64)
30 	#define CPUINFO_ARCH_ARM64 1
31 #endif
32 
33 #if defined(__PPC64__) || defined(__powerpc64__) || defined(_ARCH_PPC64)
34 	#define CPUINFO_ARCH_PPC64 1
35 #endif
36 
37 #if defined(__asmjs__)
38 	#define CPUINFO_ARCH_ASMJS 1
39 #endif
40 
41 #if defined(__wasm__)
42 	#if defined(__wasm_simd128__)
43 		#define CPUINFO_ARCH_WASMSIMD 1
44 	#else
45 		#define CPUINFO_ARCH_WASM 1
46 	#endif
47 #endif
48 
49 /* Define other architecture-specific macros as 0 */
50 
51 #ifndef CPUINFO_ARCH_X86
52 	#define CPUINFO_ARCH_X86 0
53 #endif
54 
55 #ifndef CPUINFO_ARCH_X86_64
56 	#define CPUINFO_ARCH_X86_64 0
57 #endif
58 
59 #ifndef CPUINFO_ARCH_ARM
60 	#define CPUINFO_ARCH_ARM 0
61 #endif
62 
63 #ifndef CPUINFO_ARCH_ARM64
64 	#define CPUINFO_ARCH_ARM64 0
65 #endif
66 
67 #ifndef CPUINFO_ARCH_PPC64
68 	#define CPUINFO_ARCH_PPC64 0
69 #endif
70 
71 #ifndef CPUINFO_ARCH_ASMJS
72 	#define CPUINFO_ARCH_ASMJS 0
73 #endif
74 
75 #ifndef CPUINFO_ARCH_WASM
76 	#define CPUINFO_ARCH_WASM 0
77 #endif
78 
79 #ifndef CPUINFO_ARCH_WASMSIMD
80 	#define CPUINFO_ARCH_WASMSIMD 0
81 #endif
82 
83 #if CPUINFO_ARCH_X86 && defined(_MSC_VER)
84 	#define CPUINFO_ABI __cdecl
85 #elif CPUINFO_ARCH_X86 && defined(__GNUC__)
86 	#define CPUINFO_ABI __attribute__((__cdecl__))
87 #else
88 	#define CPUINFO_ABI
89 #endif
90 
91 #define CPUINFO_CACHE_UNIFIED          0x00000001
92 #define CPUINFO_CACHE_INCLUSIVE        0x00000002
93 #define CPUINFO_CACHE_COMPLEX_INDEXING 0x00000004
94 
95 struct cpuinfo_cache {
96 	/** Cache size in bytes */
97 	uint32_t size;
98 	/** Number of ways of associativity */
99 	uint32_t associativity;
100 	/** Number of sets */
101 	uint32_t sets;
102 	/** Number of partitions */
103 	uint32_t partitions;
104 	/** Line size in bytes */
105 	uint32_t line_size;
106 	/**
107 	 * Binary characteristics of the cache (unified cache, inclusive cache, cache with complex indexing).
108 	 *
109 	 * @see CPUINFO_CACHE_UNIFIED, CPUINFO_CACHE_INCLUSIVE, CPUINFO_CACHE_COMPLEX_INDEXING
110 	 */
111 	uint32_t flags;
112 	/** Index of the first logical processor that shares this cache */
113 	uint32_t processor_start;
114 	/** Number of logical processors that share this cache */
115 	uint32_t processor_count;
116 };
117 
118 struct cpuinfo_trace_cache {
119 	uint32_t uops;
120 	uint32_t associativity;
121 };
122 
123 #define CPUINFO_PAGE_SIZE_4KB  0x1000
124 #define CPUINFO_PAGE_SIZE_1MB  0x100000
125 #define CPUINFO_PAGE_SIZE_2MB  0x200000
126 #define CPUINFO_PAGE_SIZE_4MB  0x400000
127 #define CPUINFO_PAGE_SIZE_16MB 0x1000000
128 #define CPUINFO_PAGE_SIZE_1GB  0x40000000
129 
130 struct cpuinfo_tlb {
131 	uint32_t entries;
132 	uint32_t associativity;
133 	uint64_t pages;
134 };
135 
136 /** Vendor of processor core design */
137 enum cpuinfo_vendor {
138 	/** Processor vendor is not known to the library, or the library failed to get vendor information from the OS. */
139 	cpuinfo_vendor_unknown = 0,
140 
141 	/* Active vendors of modern CPUs */
142 
143 	/**
144 	 * Intel Corporation. Vendor of x86, x86-64, IA64, and ARM processor microarchitectures.
145 	 *
146 	 * Sold its ARM design subsidiary in 2006. The last ARM processor design was released in 2004.
147 	 */
148 	cpuinfo_vendor_intel    = 1,
149 	/** Advanced Micro Devices, Inc. Vendor of x86 and x86-64 processor microarchitectures. */
150 	cpuinfo_vendor_amd      = 2,
151 	/** ARM Holdings plc. Vendor of ARM and ARM64 processor microarchitectures. */
152 	cpuinfo_vendor_arm      = 3,
153 	/** Qualcomm Incorporated. Vendor of ARM and ARM64 processor microarchitectures. */
154 	cpuinfo_vendor_qualcomm = 4,
155 	/** Apple Inc. Vendor of ARM and ARM64 processor microarchitectures. */
156 	cpuinfo_vendor_apple    = 5,
157 	/** Samsung Electronics Co., Ltd. Vendir if ARM64 processor microarchitectures. */
158 	cpuinfo_vendor_samsung  = 6,
159 	/** Nvidia Corporation. Vendor of ARM64-compatible processor microarchitectures. */
160 	cpuinfo_vendor_nvidia   = 7,
161 	/** MIPS Technologies, Inc. Vendor of MIPS processor microarchitectures. */
162 	cpuinfo_vendor_mips     = 8,
163 	/** International Business Machines Corporation. Vendor of PowerPC processor microarchitectures. */
164 	cpuinfo_vendor_ibm      = 9,
165 	/** Ingenic Semiconductor. Vendor of MIPS processor microarchitectures. */
166 	cpuinfo_vendor_ingenic  = 10,
167 	/**
168 	 * VIA Technologies, Inc. Vendor of x86 and x86-64 processor microarchitectures.
169 	 *
170 	 * Processors are designed by Centaur Technology, a subsidiary of VIA Technologies.
171 	 */
172 	cpuinfo_vendor_via      = 11,
173 	/** Cavium, Inc. Vendor of ARM64 processor microarchitectures. */
174 	cpuinfo_vendor_cavium   = 12,
175 	/** Broadcom, Inc. Vendor of ARM processor microarchitectures. */
176 	cpuinfo_vendor_broadcom = 13,
177 	/** Applied Micro Circuits Corporation (APM). Vendor of ARM64 processor microarchitectures. */
178 	cpuinfo_vendor_apm      = 14,
179 	/**
180 	 * Huawei Technologies Co., Ltd. Vendor of ARM64 processor microarchitectures.
181 	 *
182 	 * Processors are designed by HiSilicon, a subsidiary of Huawei.
183 	 */
184 	cpuinfo_vendor_huawei   = 15,
185 	/**
186 	 * Hygon (Chengdu Haiguang Integrated Circuit Design Co., Ltd), Vendor of x86-64 processor microarchitectures.
187 	 *
188 	 * Processors are variants of AMD cores.
189 	 */
190 	cpuinfo_vendor_hygon    = 16,
191 
192 	/* Active vendors of embedded CPUs */
193 
194 	/** Texas Instruments Inc. Vendor of ARM processor microarchitectures. */
195 	cpuinfo_vendor_texas_instruments = 30,
196 	/** Marvell Technology Group Ltd. Vendor of ARM processor microarchitectures. */
197 	cpuinfo_vendor_marvell           = 31,
198 	/** RDC Semiconductor Co., Ltd. Vendor of x86 processor microarchitectures. */
199 	cpuinfo_vendor_rdc               = 32,
200 	/** DM&P Electronics Inc. Vendor of x86 processor microarchitectures. */
201 	cpuinfo_vendor_dmp               = 33,
202 	/** Motorola, Inc. Vendor of PowerPC and ARM processor microarchitectures. */
203 	cpuinfo_vendor_motorola          = 34,
204 
205 	/* Defunct CPU vendors */
206 
207 	/**
208 	 * Transmeta Corporation. Vendor of x86 processor microarchitectures.
209 	 *
210 	 * Now defunct. The last processor design was released in 2004.
211 	 * Transmeta processors implemented VLIW ISA and used binary translation to execute x86 code.
212 	 */
213 	cpuinfo_vendor_transmeta = 50,
214 	/**
215 	 * Cyrix Corporation. Vendor of x86 processor microarchitectures.
216 	 *
217 	 * Now defunct. The last processor design was released in 1996.
218 	 */
219 	cpuinfo_vendor_cyrix     = 51,
220 	/**
221 	 * Rise Technology. Vendor of x86 processor microarchitectures.
222 	 *
223 	 * Now defunct. The last processor design was released in 1999.
224 	 */
225 	cpuinfo_vendor_rise      = 52,
226 	/**
227 	 * National Semiconductor. Vendor of x86 processor microarchitectures.
228 	 *
229 	 * Sold its x86 design subsidiary in 1999. The last processor design was released in 1998.
230 	 */
231 	cpuinfo_vendor_nsc       = 53,
232 	/**
233 	 * Silicon Integrated Systems. Vendor of x86 processor microarchitectures.
234 	 *
235 	 * Sold its x86 design subsidiary in 2001. The last processor design was released in 2001.
236 	 */
237 	cpuinfo_vendor_sis       = 54,
238 	/**
239 	 * NexGen. Vendor of x86 processor microarchitectures.
240 	 *
241 	 * Now defunct. The last processor design was released in 1994.
242 	 * NexGen designed the first x86 microarchitecture which decomposed x86 instructions into simple microoperations.
243 	 */
244 	cpuinfo_vendor_nexgen    = 55,
245 	/**
246 	 * United Microelectronics Corporation. Vendor of x86 processor microarchitectures.
247 	 *
248 	 * Ceased x86 in the early 1990s. The last processor design was released in 1991.
249 	 * Designed U5C and U5D processors. Both are 486 level.
250 	 */
251 	cpuinfo_vendor_umc       = 56,
252 	/**
253 	 * Digital Equipment Corporation. Vendor of ARM processor microarchitecture.
254 	 *
255 	 * Sold its ARM designs in 1997. The last processor design was released in 1997.
256 	 */
257 	cpuinfo_vendor_dec       = 57,
258 };
259 
260 /**
261  * Processor microarchitecture
262  *
263  * Processors with different microarchitectures often have different instruction performance characteristics,
264  * and may have dramatically different pipeline organization.
265  */
266 enum cpuinfo_uarch {
267 	/** Microarchitecture is unknown, or the library failed to get information about the microarchitecture from OS */
268 	cpuinfo_uarch_unknown = 0,
269 
270 	/** Pentium and Pentium MMX microarchitecture. */
271 	cpuinfo_uarch_p5    = 0x00100100,
272 	/** Intel Quark microarchitecture. */
273 	cpuinfo_uarch_quark = 0x00100101,
274 
275 	/** Pentium Pro, Pentium II, and Pentium III. */
276 	cpuinfo_uarch_p6           = 0x00100200,
277 	/** Pentium M. */
278 	cpuinfo_uarch_dothan       = 0x00100201,
279 	/** Intel Core microarchitecture. */
280 	cpuinfo_uarch_yonah        = 0x00100202,
281 	/** Intel Core 2 microarchitecture on 65 nm process. */
282 	cpuinfo_uarch_conroe       = 0x00100203,
283 	/** Intel Core 2 microarchitecture on 45 nm process. */
284 	cpuinfo_uarch_penryn       = 0x00100204,
285 	/** Intel Nehalem and Westmere microarchitectures (Core i3/i5/i7 1st gen). */
286 	cpuinfo_uarch_nehalem      = 0x00100205,
287 	/** Intel Sandy Bridge microarchitecture (Core i3/i5/i7 2nd gen). */
288 	cpuinfo_uarch_sandy_bridge = 0x00100206,
289 	/** Intel Ivy Bridge microarchitecture (Core i3/i5/i7 3rd gen). */
290 	cpuinfo_uarch_ivy_bridge   = 0x00100207,
291 	/** Intel Haswell microarchitecture (Core i3/i5/i7 4th gen). */
292 	cpuinfo_uarch_haswell      = 0x00100208,
293 	/** Intel Broadwell microarchitecture. */
294 	cpuinfo_uarch_broadwell    = 0x00100209,
295 	/** Intel Sky Lake microarchitecture (14 nm, including Kaby/Coffee/Whiskey/Amber/Comet/Cascade/Cooper Lake). */
296 	cpuinfo_uarch_sky_lake     = 0x0010020A,
297 	/** DEPRECATED (Intel Kaby Lake microarchitecture). */
298 	cpuinfo_uarch_kaby_lake    = 0x0010020A,
299 	/** Intel Palm Cove microarchitecture (10 nm, Cannon Lake). */
300 	cpuinfo_uarch_palm_cove    = 0x0010020B,
301 	/** Intel Sunny Cove microarchitecture (10 nm, Ice Lake). */
302 	cpuinfo_uarch_sunny_cove   = 0x0010020C,
303 
304 	/** Pentium 4 with Willamette, Northwood, or Foster cores. */
305 	cpuinfo_uarch_willamette = 0x00100300,
306 	/** Pentium 4 with Prescott and later cores. */
307 	cpuinfo_uarch_prescott   = 0x00100301,
308 
309 	/** Intel Atom on 45 nm process. */
310 	cpuinfo_uarch_bonnell       = 0x00100400,
311 	/** Intel Atom on 32 nm process. */
312 	cpuinfo_uarch_saltwell      = 0x00100401,
313 	/** Intel Silvermont microarchitecture (22 nm out-of-order Atom). */
314 	cpuinfo_uarch_silvermont    = 0x00100402,
315 	/** Intel Airmont microarchitecture (14 nm out-of-order Atom). */
316 	cpuinfo_uarch_airmont       = 0x00100403,
317 	/** Intel Goldmont microarchitecture (Denverton, Apollo Lake). */
318 	cpuinfo_uarch_goldmont      = 0x00100404,
319 	/** Intel Goldmont Plus microarchitecture (Gemini Lake). */
320 	cpuinfo_uarch_goldmont_plus = 0x00100405,
321 
322 	/** Intel Knights Ferry HPC boards. */
323 	cpuinfo_uarch_knights_ferry   = 0x00100500,
324 	/** Intel Knights Corner HPC boards (aka Xeon Phi). */
325 	cpuinfo_uarch_knights_corner  = 0x00100501,
326 	/** Intel Knights Landing microarchitecture (second-gen MIC). */
327 	cpuinfo_uarch_knights_landing = 0x00100502,
328 	/** Intel Knights Hill microarchitecture (third-gen MIC). */
329 	cpuinfo_uarch_knights_hill    = 0x00100503,
330 	/** Intel Knights Mill Xeon Phi. */
331 	cpuinfo_uarch_knights_mill    = 0x00100504,
332 
333 	/** Intel/Marvell XScale series. */
334 	cpuinfo_uarch_xscale = 0x00100600,
335 
336 	/** AMD K5. */
337 	cpuinfo_uarch_k5        = 0x00200100,
338 	/** AMD K6 and alike. */
339 	cpuinfo_uarch_k6        = 0x00200101,
340 	/** AMD Athlon and Duron. */
341 	cpuinfo_uarch_k7        = 0x00200102,
342 	/** AMD Athlon 64, Opteron 64. */
343 	cpuinfo_uarch_k8        = 0x00200103,
344 	/** AMD Family 10h (Barcelona, Istambul, Magny-Cours). */
345 	cpuinfo_uarch_k10       = 0x00200104,
346 	/**
347 	 * AMD Bulldozer microarchitecture
348 	 * Zambezi FX-series CPUs, Zurich, Valencia and Interlagos Opteron CPUs.
349 	 */
350 	cpuinfo_uarch_bulldozer = 0x00200105,
351 	/**
352 	 * AMD Piledriver microarchitecture
353 	 * Vishera FX-series CPUs, Trinity and Richland APUs, Delhi, Seoul, Abu Dhabi Opteron CPUs.
354 	 */
355 	cpuinfo_uarch_piledriver  = 0x00200106,
356 	/** AMD Steamroller microarchitecture (Kaveri APUs). */
357 	cpuinfo_uarch_steamroller = 0x00200107,
358 	/** AMD Excavator microarchitecture (Carizzo APUs). */
359 	cpuinfo_uarch_excavator   = 0x00200108,
360 	/** AMD Zen microarchitecture (12/14 nm Ryzen and EPYC CPUs). */
361 	cpuinfo_uarch_zen         = 0x00200109,
362 	/** AMD Zen 2 microarchitecture (7 nm Ryzen and EPYC CPUs). */
363 	cpuinfo_uarch_zen2        = 0x0020010A,
364 	/** AMD Zen 3 microarchitecture. */
365 	cpuinfo_uarch_zen3        = 0x0020010B,
366 
367 	/** NSC Geode and AMD Geode GX and LX. */
368 	cpuinfo_uarch_geode  = 0x00200200,
369 	/** AMD Bobcat mobile microarchitecture. */
370 	cpuinfo_uarch_bobcat = 0x00200201,
371 	/** AMD Jaguar mobile microarchitecture. */
372 	cpuinfo_uarch_jaguar = 0x00200202,
373 	/** AMD Puma mobile microarchitecture. */
374 	cpuinfo_uarch_puma   = 0x00200203,
375 
376 	/** ARM7 series. */
377 	cpuinfo_uarch_arm7  = 0x00300100,
378 	/** ARM9 series. */
379 	cpuinfo_uarch_arm9  = 0x00300101,
380 	/** ARM 1136, ARM 1156, ARM 1176, or ARM 11MPCore. */
381 	cpuinfo_uarch_arm11 = 0x00300102,
382 
383 	/** ARM Cortex-A5. */
384 	cpuinfo_uarch_cortex_a5  = 0x00300205,
385 	/** ARM Cortex-A7. */
386 	cpuinfo_uarch_cortex_a7  = 0x00300207,
387 	/** ARM Cortex-A8. */
388 	cpuinfo_uarch_cortex_a8  = 0x00300208,
389 	/** ARM Cortex-A9. */
390 	cpuinfo_uarch_cortex_a9  = 0x00300209,
391 	/** ARM Cortex-A12. */
392 	cpuinfo_uarch_cortex_a12 = 0x00300212,
393 	/** ARM Cortex-A15. */
394 	cpuinfo_uarch_cortex_a15 = 0x00300215,
395 	/** ARM Cortex-A17. */
396 	cpuinfo_uarch_cortex_a17 = 0x00300217,
397 
398 	/** ARM Cortex-A32. */
399 	cpuinfo_uarch_cortex_a32   = 0x00300332,
400 	/** ARM Cortex-A35. */
401 	cpuinfo_uarch_cortex_a35   = 0x00300335,
402 	/** ARM Cortex-A53. */
403 	cpuinfo_uarch_cortex_a53   = 0x00300353,
404 	/** ARM Cortex-A55 revision 0 (restricted dual-issue capabilities compared to revision 1+). */
405 	cpuinfo_uarch_cortex_a55r0 = 0x00300354,
406 	/** ARM Cortex-A55. */
407 	cpuinfo_uarch_cortex_a55   = 0x00300355,
408 	/** ARM Cortex-A57. */
409 	cpuinfo_uarch_cortex_a57   = 0x00300357,
410 	/** ARM Cortex-A65. */
411 	cpuinfo_uarch_cortex_a65   = 0x00300365,
412 	/** ARM Cortex-A72. */
413 	cpuinfo_uarch_cortex_a72   = 0x00300372,
414 	/** ARM Cortex-A73. */
415 	cpuinfo_uarch_cortex_a73   = 0x00300373,
416 	/** ARM Cortex-A75. */
417 	cpuinfo_uarch_cortex_a75   = 0x00300375,
418 	/** ARM Cortex-A76. */
419 	cpuinfo_uarch_cortex_a76   = 0x00300376,
420 	/** ARM Cortex-A77. */
421 	cpuinfo_uarch_cortex_a77   = 0x00300377,
422 	/** ARM Cortex-A78. */
423 	cpuinfo_uarch_cortex_a78   = 0x00300378,
424 
425 	/** ARM Neoverse N1. */
426 	cpuinfo_uarch_neoverse_n1  = 0x00300400,
427 	/** ARM Neoverse E1. */
428 	cpuinfo_uarch_neoverse_e1  = 0x00300401,
429 
430 	/** ARM Cortex-X1. */
431 	cpuinfo_uarch_cortex_x1    = 0x00300500,
432 
433 	/** Qualcomm Scorpion. */
434 	cpuinfo_uarch_scorpion = 0x00400100,
435 	/** Qualcomm Krait. */
436 	cpuinfo_uarch_krait    = 0x00400101,
437 	/** Qualcomm Kryo. */
438 	cpuinfo_uarch_kryo     = 0x00400102,
439 	/** Qualcomm Falkor. */
440 	cpuinfo_uarch_falkor   = 0x00400103,
441 	/** Qualcomm Saphira. */
442 	cpuinfo_uarch_saphira  = 0x00400104,
443 
444 	/** Nvidia Denver. */
445 	cpuinfo_uarch_denver   = 0x00500100,
446 	/** Nvidia Denver 2. */
447 	cpuinfo_uarch_denver2  = 0x00500101,
448 	/** Nvidia Carmel. */
449 	cpuinfo_uarch_carmel   = 0x00500102,
450 
451 	/** Samsung Exynos M1 (Exynos 8890 big cores). */
452 	cpuinfo_uarch_exynos_m1 = 0x00600100,
453 	/** Samsung Exynos M2 (Exynos 8895 big cores). */
454 	cpuinfo_uarch_exynos_m2 = 0x00600101,
455 	/** Samsung Exynos M3 (Exynos 9810 big cores). */
456 	cpuinfo_uarch_exynos_m3  = 0x00600102,
457 	/** Samsung Exynos M4 (Exynos 9820 big cores). */
458 	cpuinfo_uarch_exynos_m4  = 0x00600103,
459 	/** Samsung Exynos M5 (Exynos 9830 big cores). */
460 	cpuinfo_uarch_exynos_m5  = 0x00600104,
461 
462 	/* Deprecated synonym for Cortex-A76 */
463 	cpuinfo_uarch_cortex_a76ae = 0x00300376,
464 	/* Deprecated names for Exynos. */
465 	cpuinfo_uarch_mongoose_m1 = 0x00600100,
466 	cpuinfo_uarch_mongoose_m2 = 0x00600101,
467 	cpuinfo_uarch_meerkat_m3  = 0x00600102,
468 	cpuinfo_uarch_meerkat_m4  = 0x00600103,
469 
470 	/** Apple A6 and A6X processors. */
471 	cpuinfo_uarch_swift     = 0x00700100,
472 	/** Apple A7 processor. */
473 	cpuinfo_uarch_cyclone   = 0x00700101,
474 	/** Apple A8 and A8X processor. */
475 	cpuinfo_uarch_typhoon   = 0x00700102,
476 	/** Apple A9 and A9X processor. */
477 	cpuinfo_uarch_twister   = 0x00700103,
478 	/** Apple A10 and A10X processor. */
479 	cpuinfo_uarch_hurricane = 0x00700104,
480 	/** Apple A11 processor (big cores). */
481 	cpuinfo_uarch_monsoon   = 0x00700105,
482 	/** Apple A11 processor (little cores). */
483 	cpuinfo_uarch_mistral   = 0x00700106,
484 	/** Apple A12 processor (big cores). */
485 	cpuinfo_uarch_vortex    = 0x00700107,
486 	/** Apple A12 processor (little cores). */
487 	cpuinfo_uarch_tempest   = 0x00700108,
488 	/** Apple A13 processor (big cores). */
489 	cpuinfo_uarch_lightning = 0x00700109,
490 	/** Apple A13 processor (little cores). */
491 	cpuinfo_uarch_thunder   = 0x0070010A,
492 	/** Apple M1 processor (big cores). */
493 	cpuinfo_uarch_firestorm = 0x0070010B,
494 	/** Apple M1 processor (little cores). */
495 	cpuinfo_uarch_icestorm  = 0x0070010C,
496 
497 	/** Cavium ThunderX. */
498 	cpuinfo_uarch_thunderx = 0x00800100,
499 	/** Cavium ThunderX2 (originally Broadcom Vulkan). */
500 	cpuinfo_uarch_thunderx2 = 0x00800200,
501 
502 	/** Marvell PJ4. */
503 	cpuinfo_uarch_pj4 = 0x00900100,
504 
505 	/** Broadcom Brahma B15. */
506 	cpuinfo_uarch_brahma_b15 = 0x00A00100,
507 	/** Broadcom Brahma B53. */
508 	cpuinfo_uarch_brahma_b53 = 0x00A00101,
509 
510 	/** Applied Micro X-Gene. */
511 	cpuinfo_uarch_xgene = 0x00B00100,
512 
513 	/* Hygon Dhyana (a modification of AMD Zen for Chinese market). */
514 	cpuinfo_uarch_dhyana = 0x01000100,
515 
516 	/** HiSilicon TaiShan v110 (Huawei Kunpeng 920 series processors). */
517 	cpuinfo_uarch_taishan_v110 = 0x00C00100,
518 };
519 
520 struct cpuinfo_processor {
521 	/** SMT (hyperthread) ID within a core */
522 	uint32_t smt_id;
523 	/** Core containing this logical processor */
524 	const struct cpuinfo_core* core;
525 	/** Cluster of cores containing this logical processor */
526 	const struct cpuinfo_cluster* cluster;
527 	/** Physical package containing this logical processor */
528 	const struct cpuinfo_package* package;
529 #if defined(__linux__)
530 	/**
531 	 * Linux-specific ID for the logical processor:
532 	 * - Linux kernel exposes information about this logical processor in /sys/devices/system/cpu/cpu<linux_id>/
533 	 * - Bit <linux_id> in the cpu_set_t identifies this logical processor
534 	 */
535 	int linux_id;
536 #endif
537 #if defined(_WIN32) || defined(__CYGWIN__)
538 	/** Windows-specific ID for the group containing the logical processor. */
539 	uint16_t windows_group_id;
540 	/**
541 	 * Windows-specific ID of the logical processor within its group:
542 	 * - Bit <windows_processor_id> in the KAFFINITY mask identifies this logical processor within its group.
543 	 */
544 	uint16_t windows_processor_id;
545 #endif
546 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
547 	/** APIC ID (unique x86-specific ID of the logical processor) */
548 	uint32_t apic_id;
549 #endif
550 	struct {
551 		/** Level 1 instruction cache */
552 		const struct cpuinfo_cache* l1i;
553 		/** Level 1 data cache */
554 		const struct cpuinfo_cache* l1d;
555 		/** Level 2 unified or data cache */
556 		const struct cpuinfo_cache* l2;
557 		/** Level 3 unified or data cache */
558 		const struct cpuinfo_cache* l3;
559 		/** Level 4 unified or data cache */
560 		const struct cpuinfo_cache* l4;
561 	} cache;
562 };
563 
564 struct cpuinfo_core {
565 	/** Index of the first logical processor on this core. */
566 	uint32_t processor_start;
567 	/** Number of logical processors on this core */
568 	uint32_t processor_count;
569 	/** Core ID within a package */
570 	uint32_t core_id;
571 	/** Cluster containing this core */
572 	const struct cpuinfo_cluster* cluster;
573 	/** Physical package containing this core. */
574 	const struct cpuinfo_package* package;
575 	/** Vendor of the CPU microarchitecture for this core */
576 	enum cpuinfo_vendor vendor;
577 	/** CPU microarchitecture for this core */
578 	enum cpuinfo_uarch uarch;
579 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
580 	/** Value of CPUID leaf 1 EAX register for this core */
581 	uint32_t cpuid;
582 #elif CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
583 	/** Value of Main ID Register (MIDR) for this core */
584 	uint32_t midr;
585 #endif
586 	/** Clock rate (non-Turbo) of the core, in Hz */
587 	uint64_t frequency;
588 };
589 
590 struct cpuinfo_cluster {
591 	/** Index of the first logical processor in the cluster */
592 	uint32_t processor_start;
593 	/** Number of logical processors in the cluster */
594 	uint32_t processor_count;
595 	/** Index of the first core in the cluster */
596 	uint32_t core_start;
597 	/** Number of cores on the cluster */
598 	uint32_t core_count;
599 	/** Cluster ID within a package */
600 	uint32_t cluster_id;
601 	/** Physical package containing the cluster */
602 	const struct cpuinfo_package* package;
603 	/** CPU microarchitecture vendor of the cores in the cluster */
604 	enum cpuinfo_vendor vendor;
605 	/** CPU microarchitecture of the cores in the cluster */
606 	enum cpuinfo_uarch uarch;
607 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
608 	/** Value of CPUID leaf 1 EAX register of the cores in the cluster */
609 	uint32_t cpuid;
610 #elif CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
611 	/** Value of Main ID Register (MIDR) of the cores in the cluster */
612 	uint32_t midr;
613 #endif
614 	/** Clock rate (non-Turbo) of the cores in the cluster, in Hz */
615 	uint64_t frequency;
616 };
617 
618 #define CPUINFO_PACKAGE_NAME_MAX 48
619 
620 struct cpuinfo_package {
621 	/** SoC or processor chip model name */
622 	char name[CPUINFO_PACKAGE_NAME_MAX];
623 	/** Index of the first logical processor on this physical package */
624 	uint32_t processor_start;
625 	/** Number of logical processors on this physical package */
626 	uint32_t processor_count;
627 	/** Index of the first core on this physical package */
628 	uint32_t core_start;
629 	/** Number of cores on this physical package */
630 	uint32_t core_count;
631 	/** Index of the first cluster of cores on this physical package */
632 	uint32_t cluster_start;
633 	/** Number of clusters of cores on this physical package */
634 	uint32_t cluster_count;
635 };
636 
637 struct cpuinfo_uarch_info {
638 	/** Type of CPU microarchitecture */
639 	enum cpuinfo_uarch uarch;
640 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
641 	/** Value of CPUID leaf 1 EAX register for the microarchitecture */
642 	uint32_t cpuid;
643 #elif CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
644 	/** Value of Main ID Register (MIDR) for the microarchitecture */
645 	uint32_t midr;
646 #endif
647 	/** Number of logical processors with the microarchitecture */
648 	uint32_t processor_count;
649 	/** Number of cores with the microarchitecture */
650 	uint32_t core_count;
651 };
652 
653 #ifdef __cplusplus
654 extern "C" {
655 #endif
656 
657 bool CPUINFO_ABI cpuinfo_initialize(void);
658 
659 void CPUINFO_ABI cpuinfo_deinitialize(void);
660 
661 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
662 	/* This structure is not a part of stable API. Use cpuinfo_has_x86_* functions instead. */
663 	struct cpuinfo_x86_isa {
664 		#if CPUINFO_ARCH_X86
665 			bool rdtsc;
666 		#endif
667 		bool rdtscp;
668 		bool rdpid;
669 		bool sysenter;
670 		#if CPUINFO_ARCH_X86
671 			bool syscall;
672 		#endif
673 		bool msr;
674 		bool clzero;
675 		bool clflush;
676 		bool clflushopt;
677 		bool mwait;
678 		bool mwaitx;
679 		#if CPUINFO_ARCH_X86
680 			bool emmx;
681 		#endif
682 		bool fxsave;
683 		bool xsave;
684 		#if CPUINFO_ARCH_X86
685 			bool fpu;
686 			bool mmx;
687 			bool mmx_plus;
688 		#endif
689 		bool three_d_now;
690 		bool three_d_now_plus;
691 		#if CPUINFO_ARCH_X86
692 			bool three_d_now_geode;
693 		#endif
694 		bool prefetch;
695 		bool prefetchw;
696 		bool prefetchwt1;
697 		#if CPUINFO_ARCH_X86
698 			bool daz;
699 			bool sse;
700 			bool sse2;
701 		#endif
702 		bool sse3;
703 		bool ssse3;
704 		bool sse4_1;
705 		bool sse4_2;
706 		bool sse4a;
707 		bool misaligned_sse;
708 		bool avx;
709 		bool fma3;
710 		bool fma4;
711 		bool xop;
712 		bool f16c;
713 		bool avx2;
714 		bool avx512f;
715 		bool avx512pf;
716 		bool avx512er;
717 		bool avx512cd;
718 		bool avx512dq;
719 		bool avx512bw;
720 		bool avx512vl;
721 		bool avx512ifma;
722 		bool avx512vbmi;
723 		bool avx512vbmi2;
724 		bool avx512bitalg;
725 		bool avx512vpopcntdq;
726 		bool avx512vnni;
727 		bool avx512bf16;
728 		bool avx512vp2intersect;
729 		bool avx512_4vnniw;
730 		bool avx512_4fmaps;
731 		bool hle;
732 		bool rtm;
733 		bool xtest;
734 		bool mpx;
735 		#if CPUINFO_ARCH_X86
736 			bool cmov;
737 			bool cmpxchg8b;
738 		#endif
739 		bool cmpxchg16b;
740 		bool clwb;
741 		bool movbe;
742 		#if CPUINFO_ARCH_X86_64
743 			bool lahf_sahf;
744 		#endif
745 		bool fs_gs_base;
746 		bool lzcnt;
747 		bool popcnt;
748 		bool tbm;
749 		bool bmi;
750 		bool bmi2;
751 		bool adx;
752 		bool aes;
753 		bool vaes;
754 		bool pclmulqdq;
755 		bool vpclmulqdq;
756 		bool gfni;
757 		bool rdrand;
758 		bool rdseed;
759 		bool sha;
760 		bool rng;
761 		bool ace;
762 		bool ace2;
763 		bool phe;
764 		bool pmm;
765 		bool lwp;
766 	};
767 
768 	extern struct cpuinfo_x86_isa cpuinfo_isa;
769 #endif
770 
cpuinfo_has_x86_rdtsc(void)771 static inline bool cpuinfo_has_x86_rdtsc(void) {
772 	#if CPUINFO_ARCH_X86_64
773 		return true;
774 	#elif CPUINFO_ARCH_X86
775 		#if defined(__ANDROID__)
776 			return true;
777 		#else
778 			return cpuinfo_isa.rdtsc;
779 		#endif
780 	#else
781 		return false;
782 	#endif
783 }
784 
cpuinfo_has_x86_rdtscp(void)785 static inline bool cpuinfo_has_x86_rdtscp(void) {
786 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
787 		return cpuinfo_isa.rdtscp;
788 	#else
789 		return false;
790 	#endif
791 }
792 
cpuinfo_has_x86_rdpid(void)793 static inline bool cpuinfo_has_x86_rdpid(void) {
794 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
795 		return cpuinfo_isa.rdpid;
796 	#else
797 		return false;
798 	#endif
799 }
800 
cpuinfo_has_x86_clzero(void)801 static inline bool cpuinfo_has_x86_clzero(void) {
802 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
803 		return cpuinfo_isa.clzero;
804 	#else
805 		return false;
806 	#endif
807 }
808 
cpuinfo_has_x86_mwait(void)809 static inline bool cpuinfo_has_x86_mwait(void) {
810 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
811 		return cpuinfo_isa.mwait;
812 	#else
813 		return false;
814 	#endif
815 }
816 
cpuinfo_has_x86_mwaitx(void)817 static inline bool cpuinfo_has_x86_mwaitx(void) {
818 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
819 		return cpuinfo_isa.mwaitx;
820 	#else
821 		return false;
822 	#endif
823 }
824 
cpuinfo_has_x86_fxsave(void)825 static inline bool cpuinfo_has_x86_fxsave(void) {
826 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
827 		return cpuinfo_isa.fxsave;
828 	#else
829 		return false;
830 	#endif
831 }
832 
cpuinfo_has_x86_xsave(void)833 static inline bool cpuinfo_has_x86_xsave(void) {
834 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
835 		return cpuinfo_isa.xsave;
836 	#else
837 		return false;
838 	#endif
839 }
840 
cpuinfo_has_x86_fpu(void)841 static inline bool cpuinfo_has_x86_fpu(void) {
842 	#if CPUINFO_ARCH_X86_64
843 		return true;
844 	#elif CPUINFO_ARCH_X86
845 		#if defined(__ANDROID__)
846 			return true;
847 		#else
848 			return cpuinfo_isa.fpu;
849 		#endif
850 	#else
851 		return false;
852 	#endif
853 }
854 
cpuinfo_has_x86_mmx(void)855 static inline bool cpuinfo_has_x86_mmx(void) {
856 	#if CPUINFO_ARCH_X86_64
857 		return true;
858 	#elif CPUINFO_ARCH_X86
859 		#if defined(__ANDROID__)
860 			return true;
861 		#else
862 			return cpuinfo_isa.mmx;
863 		#endif
864 	#else
865 		return false;
866 	#endif
867 }
868 
cpuinfo_has_x86_mmx_plus(void)869 static inline bool cpuinfo_has_x86_mmx_plus(void) {
870 	#if CPUINFO_ARCH_X86_64
871 		return true;
872 	#elif CPUINFO_ARCH_X86
873 		#if defined(__ANDROID__)
874 			return true;
875 		#else
876 			return cpuinfo_isa.mmx_plus;
877 		#endif
878 	#else
879 		return false;
880 	#endif
881 }
882 
cpuinfo_has_x86_3dnow(void)883 static inline bool cpuinfo_has_x86_3dnow(void) {
884 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
885 		return cpuinfo_isa.three_d_now;
886 	#else
887 		return false;
888 	#endif
889 }
890 
cpuinfo_has_x86_3dnow_plus(void)891 static inline bool cpuinfo_has_x86_3dnow_plus(void) {
892 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
893 		return cpuinfo_isa.three_d_now_plus;
894 	#else
895 		return false;
896 	#endif
897 }
898 
cpuinfo_has_x86_3dnow_geode(void)899 static inline bool cpuinfo_has_x86_3dnow_geode(void) {
900 	#if CPUINFO_ARCH_X86_64
901 		return false;
902 	#elif CPUINFO_ARCH_X86
903 		#if defined(__ANDROID__)
904 			return false;
905 		#else
906 			return cpuinfo_isa.three_d_now_geode;
907 		#endif
908 	#else
909 		return false;
910 	#endif
911 }
912 
cpuinfo_has_x86_prefetch(void)913 static inline bool cpuinfo_has_x86_prefetch(void) {
914 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
915 		return cpuinfo_isa.prefetch;
916 	#else
917 		return false;
918 	#endif
919 }
920 
cpuinfo_has_x86_prefetchw(void)921 static inline bool cpuinfo_has_x86_prefetchw(void) {
922 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
923 		return cpuinfo_isa.prefetchw;
924 	#else
925 		return false;
926 	#endif
927 }
928 
cpuinfo_has_x86_prefetchwt1(void)929 static inline bool cpuinfo_has_x86_prefetchwt1(void) {
930 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
931 		return cpuinfo_isa.prefetchwt1;
932 	#else
933 		return false;
934 	#endif
935 }
936 
cpuinfo_has_x86_daz(void)937 static inline bool cpuinfo_has_x86_daz(void) {
938 	#if CPUINFO_ARCH_X86_64
939 		return true;
940 	#elif CPUINFO_ARCH_X86
941 		#if defined(__ANDROID__)
942 			return true;
943 		#else
944 			return cpuinfo_isa.daz;
945 		#endif
946 	#else
947 		return false;
948 	#endif
949 }
950 
cpuinfo_has_x86_sse(void)951 static inline bool cpuinfo_has_x86_sse(void) {
952 	#if CPUINFO_ARCH_X86_64
953 		return true;
954 	#elif CPUINFO_ARCH_X86
955 		#if defined(__ANDROID__)
956 			return true;
957 		#else
958 			return cpuinfo_isa.sse;
959 		#endif
960 	#else
961 		return false;
962 	#endif
963 }
964 
cpuinfo_has_x86_sse2(void)965 static inline bool cpuinfo_has_x86_sse2(void) {
966 	#if CPUINFO_ARCH_X86_64
967 		return true;
968 	#elif CPUINFO_ARCH_X86
969 		#if defined(__ANDROID__)
970 			return true;
971 		#else
972 			return cpuinfo_isa.sse2;
973 		#endif
974 	#else
975 		return false;
976 	#endif
977 }
978 
cpuinfo_has_x86_sse3(void)979 static inline bool cpuinfo_has_x86_sse3(void) {
980 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
981 		#if defined(__ANDROID__)
982 			return true;
983 		#else
984 			return cpuinfo_isa.sse3;
985 		#endif
986 	#else
987 		return false;
988 	#endif
989 }
990 
cpuinfo_has_x86_ssse3(void)991 static inline bool cpuinfo_has_x86_ssse3(void) {
992 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
993 		#if defined(__ANDROID__)
994 			return true;
995 		#else
996 			return cpuinfo_isa.ssse3;
997 		#endif
998 	#else
999 		return false;
1000 	#endif
1001 }
1002 
cpuinfo_has_x86_sse4_1(void)1003 static inline bool cpuinfo_has_x86_sse4_1(void) {
1004 	#if CPUINFO_ARCH_X86_64
1005 		#if defined(__ANDROID__)
1006 			return true;
1007 		#else
1008 			return cpuinfo_isa.sse4_1;
1009 		#endif
1010 	#elif CPUINFO_ARCH_X86
1011 		return cpuinfo_isa.sse4_1;
1012 	#else
1013 		return false;
1014 	#endif
1015 }
1016 
cpuinfo_has_x86_sse4_2(void)1017 static inline bool cpuinfo_has_x86_sse4_2(void) {
1018 	#if CPUINFO_ARCH_X86_64
1019 		#if defined(__ANDROID__)
1020 			return true;
1021 		#else
1022 			return cpuinfo_isa.sse4_2;
1023 		#endif
1024 	#elif CPUINFO_ARCH_X86
1025 		return cpuinfo_isa.sse4_2;
1026 	#else
1027 		return false;
1028 	#endif
1029 }
1030 
cpuinfo_has_x86_sse4a(void)1031 static inline bool cpuinfo_has_x86_sse4a(void) {
1032 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1033 		return cpuinfo_isa.sse4a;
1034 	#else
1035 		return false;
1036 	#endif
1037 }
1038 
cpuinfo_has_x86_misaligned_sse(void)1039 static inline bool cpuinfo_has_x86_misaligned_sse(void) {
1040 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1041 		return cpuinfo_isa.misaligned_sse;
1042 	#else
1043 		return false;
1044 	#endif
1045 }
1046 
cpuinfo_has_x86_avx(void)1047 static inline bool cpuinfo_has_x86_avx(void) {
1048 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1049 		return cpuinfo_isa.avx;
1050 	#else
1051 		return false;
1052 	#endif
1053 }
1054 
cpuinfo_has_x86_fma3(void)1055 static inline bool cpuinfo_has_x86_fma3(void) {
1056 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1057 		return cpuinfo_isa.fma3;
1058 	#else
1059 		return false;
1060 	#endif
1061 }
1062 
cpuinfo_has_x86_fma4(void)1063 static inline bool cpuinfo_has_x86_fma4(void) {
1064 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1065 		return cpuinfo_isa.fma4;
1066 	#else
1067 		return false;
1068 	#endif
1069 }
1070 
cpuinfo_has_x86_xop(void)1071 static inline bool cpuinfo_has_x86_xop(void) {
1072 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1073 		return cpuinfo_isa.xop;
1074 	#else
1075 		return false;
1076 	#endif
1077 }
1078 
cpuinfo_has_x86_f16c(void)1079 static inline bool cpuinfo_has_x86_f16c(void) {
1080 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1081 		return cpuinfo_isa.f16c;
1082 	#else
1083 		return false;
1084 	#endif
1085 }
1086 
cpuinfo_has_x86_avx2(void)1087 static inline bool cpuinfo_has_x86_avx2(void) {
1088 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1089 		return cpuinfo_isa.avx2;
1090 	#else
1091 		return false;
1092 	#endif
1093 }
1094 
cpuinfo_has_x86_avx512f(void)1095 static inline bool cpuinfo_has_x86_avx512f(void) {
1096 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1097 		return cpuinfo_isa.avx512f;
1098 	#else
1099 		return false;
1100 	#endif
1101 }
1102 
cpuinfo_has_x86_avx512pf(void)1103 static inline bool cpuinfo_has_x86_avx512pf(void) {
1104 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1105 		return cpuinfo_isa.avx512pf;
1106 	#else
1107 		return false;
1108 	#endif
1109 }
1110 
cpuinfo_has_x86_avx512er(void)1111 static inline bool cpuinfo_has_x86_avx512er(void) {
1112 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1113 		return cpuinfo_isa.avx512er;
1114 	#else
1115 		return false;
1116 	#endif
1117 }
1118 
cpuinfo_has_x86_avx512cd(void)1119 static inline bool cpuinfo_has_x86_avx512cd(void) {
1120 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1121 		return cpuinfo_isa.avx512cd;
1122 	#else
1123 		return false;
1124 	#endif
1125 }
1126 
cpuinfo_has_x86_avx512dq(void)1127 static inline bool cpuinfo_has_x86_avx512dq(void) {
1128 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1129 		return cpuinfo_isa.avx512dq;
1130 	#else
1131 		return false;
1132 	#endif
1133 }
1134 
cpuinfo_has_x86_avx512bw(void)1135 static inline bool cpuinfo_has_x86_avx512bw(void) {
1136 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1137 		return cpuinfo_isa.avx512bw;
1138 	#else
1139 		return false;
1140 	#endif
1141 }
1142 
cpuinfo_has_x86_avx512vl(void)1143 static inline bool cpuinfo_has_x86_avx512vl(void) {
1144 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1145 		return cpuinfo_isa.avx512vl;
1146 	#else
1147 		return false;
1148 	#endif
1149 }
1150 
cpuinfo_has_x86_avx512ifma(void)1151 static inline bool cpuinfo_has_x86_avx512ifma(void) {
1152 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1153 		return cpuinfo_isa.avx512ifma;
1154 	#else
1155 		return false;
1156 	#endif
1157 }
1158 
cpuinfo_has_x86_avx512vbmi(void)1159 static inline bool cpuinfo_has_x86_avx512vbmi(void) {
1160 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1161 		return cpuinfo_isa.avx512vbmi;
1162 	#else
1163 		return false;
1164 	#endif
1165 }
1166 
cpuinfo_has_x86_avx512vbmi2(void)1167 static inline bool cpuinfo_has_x86_avx512vbmi2(void) {
1168 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1169 		return cpuinfo_isa.avx512vbmi2;
1170 	#else
1171 		return false;
1172 	#endif
1173 }
1174 
cpuinfo_has_x86_avx512bitalg(void)1175 static inline bool cpuinfo_has_x86_avx512bitalg(void) {
1176 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1177 		return cpuinfo_isa.avx512bitalg;
1178 	#else
1179 		return false;
1180 	#endif
1181 }
1182 
cpuinfo_has_x86_avx512vpopcntdq(void)1183 static inline bool cpuinfo_has_x86_avx512vpopcntdq(void) {
1184 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1185 		return cpuinfo_isa.avx512vpopcntdq;
1186 	#else
1187 		return false;
1188 	#endif
1189 }
1190 
cpuinfo_has_x86_avx512vnni(void)1191 static inline bool cpuinfo_has_x86_avx512vnni(void) {
1192 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1193 		return cpuinfo_isa.avx512vnni;
1194 	#else
1195 		return false;
1196 	#endif
1197 }
1198 
cpuinfo_has_x86_avx512bf16(void)1199 static inline bool cpuinfo_has_x86_avx512bf16(void) {
1200 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1201 		return cpuinfo_isa.avx512bf16;
1202 	#else
1203 		return false;
1204 	#endif
1205 }
1206 
cpuinfo_has_x86_avx512vp2intersect(void)1207 static inline bool cpuinfo_has_x86_avx512vp2intersect(void) {
1208 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1209 		return cpuinfo_isa.avx512vp2intersect;
1210 	#else
1211 		return false;
1212 	#endif
1213 }
1214 
cpuinfo_has_x86_avx512_4vnniw(void)1215 static inline bool cpuinfo_has_x86_avx512_4vnniw(void) {
1216 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1217 		return cpuinfo_isa.avx512_4vnniw;
1218 	#else
1219 		return false;
1220 	#endif
1221 }
1222 
cpuinfo_has_x86_avx512_4fmaps(void)1223 static inline bool cpuinfo_has_x86_avx512_4fmaps(void) {
1224 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1225 		return cpuinfo_isa.avx512_4fmaps;
1226 	#else
1227 		return false;
1228 	#endif
1229 }
1230 
cpuinfo_has_x86_hle(void)1231 static inline bool cpuinfo_has_x86_hle(void) {
1232 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1233 		return cpuinfo_isa.hle;
1234 	#else
1235 		return false;
1236 	#endif
1237 }
1238 
cpuinfo_has_x86_rtm(void)1239 static inline bool cpuinfo_has_x86_rtm(void) {
1240 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1241 		return cpuinfo_isa.rtm;
1242 	#else
1243 		return false;
1244 	#endif
1245 }
1246 
cpuinfo_has_x86_xtest(void)1247 static inline bool cpuinfo_has_x86_xtest(void) {
1248 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1249 		return cpuinfo_isa.xtest;
1250 	#else
1251 		return false;
1252 	#endif
1253 }
1254 
cpuinfo_has_x86_mpx(void)1255 static inline bool cpuinfo_has_x86_mpx(void) {
1256 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1257 		return cpuinfo_isa.mpx;
1258 	#else
1259 		return false;
1260 	#endif
1261 }
1262 
cpuinfo_has_x86_cmov(void)1263 static inline bool cpuinfo_has_x86_cmov(void) {
1264 	#if CPUINFO_ARCH_X86_64
1265 		return true;
1266 	#elif CPUINFO_ARCH_X86
1267 		return cpuinfo_isa.cmov;
1268 	#else
1269 		return false;
1270 	#endif
1271 }
1272 
cpuinfo_has_x86_cmpxchg8b(void)1273 static inline bool cpuinfo_has_x86_cmpxchg8b(void) {
1274 	#if CPUINFO_ARCH_X86_64
1275 		return true;
1276 	#elif CPUINFO_ARCH_X86
1277 		return cpuinfo_isa.cmpxchg8b;
1278 	#else
1279 		return false;
1280 	#endif
1281 }
1282 
cpuinfo_has_x86_cmpxchg16b(void)1283 static inline bool cpuinfo_has_x86_cmpxchg16b(void) {
1284 	#if CPUINFO_ARCH_X86_64
1285 		return cpuinfo_isa.cmpxchg16b;
1286 	#else
1287 		return false;
1288 	#endif
1289 }
1290 
cpuinfo_has_x86_clwb(void)1291 static inline bool cpuinfo_has_x86_clwb(void) {
1292 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1293 		return cpuinfo_isa.clwb;
1294 	#else
1295 		return false;
1296 	#endif
1297 }
1298 
cpuinfo_has_x86_movbe(void)1299 static inline bool cpuinfo_has_x86_movbe(void) {
1300 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1301 		return cpuinfo_isa.movbe;
1302 	#else
1303 		return false;
1304 	#endif
1305 }
1306 
cpuinfo_has_x86_lahf_sahf(void)1307 static inline bool cpuinfo_has_x86_lahf_sahf(void) {
1308 	#if CPUINFO_ARCH_X86
1309 		return true;
1310 	#elif CPUINFO_ARCH_X86_64
1311 		return cpuinfo_isa.lahf_sahf;
1312 	#else
1313 		return false;
1314 	#endif
1315 }
1316 
cpuinfo_has_x86_lzcnt(void)1317 static inline bool cpuinfo_has_x86_lzcnt(void) {
1318 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1319 		return cpuinfo_isa.lzcnt;
1320 	#else
1321 		return false;
1322 	#endif
1323 }
1324 
cpuinfo_has_x86_popcnt(void)1325 static inline bool cpuinfo_has_x86_popcnt(void) {
1326 	#if CPUINFO_ARCH_X86_64
1327 		#if defined(__ANDROID__)
1328 			return true;
1329 		#else
1330 			return cpuinfo_isa.popcnt;
1331 		#endif
1332 	#elif CPUINFO_ARCH_X86
1333 		return cpuinfo_isa.popcnt;
1334 	#else
1335 		return false;
1336 	#endif
1337 }
1338 
cpuinfo_has_x86_tbm(void)1339 static inline bool cpuinfo_has_x86_tbm(void) {
1340 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1341 		return cpuinfo_isa.tbm;
1342 	#else
1343 		return false;
1344 	#endif
1345 }
1346 
cpuinfo_has_x86_bmi(void)1347 static inline bool cpuinfo_has_x86_bmi(void) {
1348 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1349 		return cpuinfo_isa.bmi;
1350 	#else
1351 		return false;
1352 	#endif
1353 }
1354 
cpuinfo_has_x86_bmi2(void)1355 static inline bool cpuinfo_has_x86_bmi2(void) {
1356 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1357 		return cpuinfo_isa.bmi2;
1358 	#else
1359 		return false;
1360 	#endif
1361 }
1362 
cpuinfo_has_x86_adx(void)1363 static inline bool cpuinfo_has_x86_adx(void) {
1364 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1365 		return cpuinfo_isa.adx;
1366 	#else
1367 		return false;
1368 	#endif
1369 }
1370 
cpuinfo_has_x86_aes(void)1371 static inline bool cpuinfo_has_x86_aes(void) {
1372 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1373 		return cpuinfo_isa.aes;
1374 	#else
1375 		return false;
1376 	#endif
1377 }
1378 
cpuinfo_has_x86_vaes(void)1379 static inline bool cpuinfo_has_x86_vaes(void) {
1380 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1381 		return cpuinfo_isa.vaes;
1382 	#else
1383 		return false;
1384 	#endif
1385 }
1386 
cpuinfo_has_x86_pclmulqdq(void)1387 static inline bool cpuinfo_has_x86_pclmulqdq(void) {
1388 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1389 		return cpuinfo_isa.pclmulqdq;
1390 	#else
1391 		return false;
1392 	#endif
1393 }
1394 
cpuinfo_has_x86_vpclmulqdq(void)1395 static inline bool cpuinfo_has_x86_vpclmulqdq(void) {
1396 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1397 		return cpuinfo_isa.vpclmulqdq;
1398 	#else
1399 		return false;
1400 	#endif
1401 }
1402 
cpuinfo_has_x86_gfni(void)1403 static inline bool cpuinfo_has_x86_gfni(void) {
1404 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1405 		return cpuinfo_isa.gfni;
1406 	#else
1407 		return false;
1408 	#endif
1409 }
1410 
cpuinfo_has_x86_rdrand(void)1411 static inline bool cpuinfo_has_x86_rdrand(void) {
1412 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1413 		return cpuinfo_isa.rdrand;
1414 	#else
1415 		return false;
1416 	#endif
1417 }
1418 
cpuinfo_has_x86_rdseed(void)1419 static inline bool cpuinfo_has_x86_rdseed(void) {
1420 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1421 		return cpuinfo_isa.rdseed;
1422 	#else
1423 		return false;
1424 	#endif
1425 }
1426 
cpuinfo_has_x86_sha(void)1427 static inline bool cpuinfo_has_x86_sha(void) {
1428 	#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1429 		return cpuinfo_isa.sha;
1430 	#else
1431 		return false;
1432 	#endif
1433 }
1434 
1435 #if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
1436 	/* This structure is not a part of stable API. Use cpuinfo_has_arm_* functions instead. */
1437 	struct cpuinfo_arm_isa {
1438 		#if CPUINFO_ARCH_ARM
1439 			bool thumb;
1440 			bool thumb2;
1441 			bool thumbee;
1442 			bool jazelle;
1443 			bool armv5e;
1444 			bool armv6;
1445 			bool armv6k;
1446 			bool armv7;
1447 			bool armv7mp;
1448 			bool armv8;
1449 			bool idiv;
1450 
1451 			bool vfpv2;
1452 			bool vfpv3;
1453 			bool d32;
1454 			bool fp16;
1455 			bool fma;
1456 
1457 			bool wmmx;
1458 			bool wmmx2;
1459 			bool neon;
1460 		#endif
1461 		#if CPUINFO_ARCH_ARM64
1462 			bool atomics;
1463 			bool sve;
1464 			bool sve2;
1465 		#endif
1466 		bool rdm;
1467 		bool fp16arith;
1468 		bool dot;
1469 		bool jscvt;
1470 		bool fcma;
1471 
1472 		bool aes;
1473 		bool sha1;
1474 		bool sha2;
1475 		bool pmull;
1476 		bool crc32;
1477 	};
1478 
1479 	extern struct cpuinfo_arm_isa cpuinfo_isa;
1480 #endif
1481 
cpuinfo_has_arm_thumb(void)1482 static inline bool cpuinfo_has_arm_thumb(void) {
1483 	#if CPUINFO_ARCH_ARM
1484 		return cpuinfo_isa.thumb;
1485 	#else
1486 		return false;
1487 	#endif
1488 }
1489 
cpuinfo_has_arm_thumb2(void)1490 static inline bool cpuinfo_has_arm_thumb2(void) {
1491 	#if CPUINFO_ARCH_ARM
1492 		return cpuinfo_isa.thumb2;
1493 	#else
1494 		return false;
1495 	#endif
1496 }
1497 
cpuinfo_has_arm_v5e(void)1498 static inline bool cpuinfo_has_arm_v5e(void) {
1499 	#if CPUINFO_ARCH_ARM
1500 		return cpuinfo_isa.armv5e;
1501 	#else
1502 		return false;
1503 	#endif
1504 }
1505 
cpuinfo_has_arm_v6(void)1506 static inline bool cpuinfo_has_arm_v6(void) {
1507 	#if CPUINFO_ARCH_ARM
1508 		return cpuinfo_isa.armv6;
1509 	#else
1510 		return false;
1511 	#endif
1512 }
1513 
cpuinfo_has_arm_v6k(void)1514 static inline bool cpuinfo_has_arm_v6k(void) {
1515 	#if CPUINFO_ARCH_ARM
1516 		return cpuinfo_isa.armv6k;
1517 	#else
1518 		return false;
1519 	#endif
1520 }
1521 
cpuinfo_has_arm_v7(void)1522 static inline bool cpuinfo_has_arm_v7(void) {
1523 	#if CPUINFO_ARCH_ARM
1524 		return cpuinfo_isa.armv7;
1525 	#else
1526 		return false;
1527 	#endif
1528 }
1529 
cpuinfo_has_arm_v7mp(void)1530 static inline bool cpuinfo_has_arm_v7mp(void) {
1531 	#if CPUINFO_ARCH_ARM
1532 		return cpuinfo_isa.armv7mp;
1533 	#else
1534 		return false;
1535 	#endif
1536 }
1537 
cpuinfo_has_arm_v8(void)1538 static inline bool cpuinfo_has_arm_v8(void) {
1539 	#if CPUINFO_ARCH_ARM64
1540 		return true;
1541 	#elif CPUINFO_ARCH_ARM
1542 		return cpuinfo_isa.armv8;
1543 	#else
1544 		return false;
1545 	#endif
1546 }
1547 
cpuinfo_has_arm_idiv(void)1548 static inline bool cpuinfo_has_arm_idiv(void) {
1549 	#if CPUINFO_ARCH_ARM64
1550 		return true;
1551 	#elif CPUINFO_ARCH_ARM
1552 		return cpuinfo_isa.idiv;
1553 	#else
1554 		return false;
1555 	#endif
1556 }
1557 
cpuinfo_has_arm_vfpv2(void)1558 static inline bool cpuinfo_has_arm_vfpv2(void) {
1559 	#if CPUINFO_ARCH_ARM
1560 		return cpuinfo_isa.vfpv2;
1561 	#else
1562 		return false;
1563 	#endif
1564 }
1565 
cpuinfo_has_arm_vfpv3(void)1566 static inline bool cpuinfo_has_arm_vfpv3(void) {
1567 	#if CPUINFO_ARCH_ARM64
1568 		return true;
1569 	#elif CPUINFO_ARCH_ARM
1570 		return cpuinfo_isa.vfpv3;
1571 	#else
1572 		return false;
1573 	#endif
1574 }
1575 
cpuinfo_has_arm_vfpv3_d32(void)1576 static inline bool cpuinfo_has_arm_vfpv3_d32(void) {
1577 	#if CPUINFO_ARCH_ARM64
1578 		return true;
1579 	#elif CPUINFO_ARCH_ARM
1580 		return cpuinfo_isa.vfpv3 && cpuinfo_isa.d32;
1581 	#else
1582 		return false;
1583 	#endif
1584 }
1585 
cpuinfo_has_arm_vfpv3_fp16(void)1586 static inline bool cpuinfo_has_arm_vfpv3_fp16(void) {
1587 	#if CPUINFO_ARCH_ARM64
1588 		return true;
1589 	#elif CPUINFO_ARCH_ARM
1590 		return cpuinfo_isa.vfpv3 && cpuinfo_isa.fp16;
1591 	#else
1592 		return false;
1593 	#endif
1594 }
1595 
cpuinfo_has_arm_vfpv3_fp16_d32(void)1596 static inline bool cpuinfo_has_arm_vfpv3_fp16_d32(void) {
1597 	#if CPUINFO_ARCH_ARM64
1598 		return true;
1599 	#elif CPUINFO_ARCH_ARM
1600 		return cpuinfo_isa.vfpv3 && cpuinfo_isa.fp16 && cpuinfo_isa.d32;
1601 	#else
1602 		return false;
1603 	#endif
1604 }
1605 
cpuinfo_has_arm_vfpv4(void)1606 static inline bool cpuinfo_has_arm_vfpv4(void) {
1607 	#if CPUINFO_ARCH_ARM64
1608 		return true;
1609 	#elif CPUINFO_ARCH_ARM
1610 		return cpuinfo_isa.vfpv3 && cpuinfo_isa.fma;
1611 	#else
1612 		return false;
1613 	#endif
1614 }
1615 
cpuinfo_has_arm_vfpv4_d32(void)1616 static inline bool cpuinfo_has_arm_vfpv4_d32(void) {
1617 	#if CPUINFO_ARCH_ARM64
1618 		return true;
1619 	#elif CPUINFO_ARCH_ARM
1620 		return cpuinfo_isa.vfpv3 && cpuinfo_isa.fma && cpuinfo_isa.d32;
1621 	#else
1622 		return false;
1623 	#endif
1624 }
1625 
cpuinfo_has_arm_wmmx(void)1626 static inline bool cpuinfo_has_arm_wmmx(void) {
1627 	#if CPUINFO_ARCH_ARM
1628 		return cpuinfo_isa.wmmx;
1629 	#else
1630 		return false;
1631 	#endif
1632 }
1633 
cpuinfo_has_arm_wmmx2(void)1634 static inline bool cpuinfo_has_arm_wmmx2(void) {
1635 	#if CPUINFO_ARCH_ARM
1636 		return cpuinfo_isa.wmmx2;
1637 	#else
1638 		return false;
1639 	#endif
1640 }
1641 
cpuinfo_has_arm_neon(void)1642 static inline bool cpuinfo_has_arm_neon(void) {
1643 	#if CPUINFO_ARCH_ARM64
1644 		return true;
1645 	#elif CPUINFO_ARCH_ARM
1646 		return cpuinfo_isa.neon;
1647 	#else
1648 		return false;
1649 	#endif
1650 }
1651 
cpuinfo_has_arm_neon_fp16(void)1652 static inline bool cpuinfo_has_arm_neon_fp16(void) {
1653 	#if CPUINFO_ARCH_ARM64
1654 		return true;
1655 	#elif CPUINFO_ARCH_ARM
1656 		return cpuinfo_isa.neon && cpuinfo_isa.fp16;
1657 	#else
1658 		return false;
1659 	#endif
1660 }
1661 
cpuinfo_has_arm_neon_fma(void)1662 static inline bool cpuinfo_has_arm_neon_fma(void) {
1663 	#if CPUINFO_ARCH_ARM64
1664 		return true;
1665 	#elif CPUINFO_ARCH_ARM
1666 		return cpuinfo_isa.neon && cpuinfo_isa.fma;
1667 	#else
1668 		return false;
1669 	#endif
1670 }
1671 
cpuinfo_has_arm_neon_v8(void)1672 static inline bool cpuinfo_has_arm_neon_v8(void) {
1673 	#if CPUINFO_ARCH_ARM64
1674 		return true;
1675 	#elif CPUINFO_ARCH_ARM
1676 		return cpuinfo_isa.neon && cpuinfo_isa.armv8;
1677 	#else
1678 		return false;
1679 	#endif
1680 }
1681 
cpuinfo_has_arm_atomics(void)1682 static inline bool cpuinfo_has_arm_atomics(void) {
1683 	#if CPUINFO_ARCH_ARM64
1684 		return cpuinfo_isa.atomics;
1685 	#else
1686 		return false;
1687 	#endif
1688 }
1689 
cpuinfo_has_arm_neon_rdm(void)1690 static inline bool cpuinfo_has_arm_neon_rdm(void) {
1691 	#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
1692 		return cpuinfo_isa.rdm;
1693 	#else
1694 		return false;
1695 	#endif
1696 }
1697 
cpuinfo_has_arm_neon_fp16_arith(void)1698 static inline bool cpuinfo_has_arm_neon_fp16_arith(void) {
1699 	#if CPUINFO_ARCH_ARM
1700 		return cpuinfo_isa.neon && cpuinfo_isa.fp16arith;
1701 	#elif CPUINFO_ARCH_ARM64
1702 		return cpuinfo_isa.fp16arith;
1703 	#else
1704 		return false;
1705 	#endif
1706 }
1707 
cpuinfo_has_arm_fp16_arith(void)1708 static inline bool cpuinfo_has_arm_fp16_arith(void) {
1709 	#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
1710 		return cpuinfo_isa.fp16arith;
1711 	#else
1712 		return false;
1713 	#endif
1714 }
1715 
cpuinfo_has_arm_neon_dot(void)1716 static inline bool cpuinfo_has_arm_neon_dot(void) {
1717 	#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
1718 		return cpuinfo_isa.dot;
1719 	#else
1720 		return false;
1721 	#endif
1722 }
1723 
cpuinfo_has_arm_jscvt(void)1724 static inline bool cpuinfo_has_arm_jscvt(void) {
1725 	#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
1726 		return cpuinfo_isa.jscvt;
1727 	#else
1728 		return false;
1729 	#endif
1730 }
1731 
cpuinfo_has_arm_fcma(void)1732 static inline bool cpuinfo_has_arm_fcma(void) {
1733 	#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
1734 		return cpuinfo_isa.fcma;
1735 	#else
1736 		return false;
1737 	#endif
1738 }
1739 
cpuinfo_has_arm_aes(void)1740 static inline bool cpuinfo_has_arm_aes(void) {
1741 	#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
1742 		return cpuinfo_isa.aes;
1743 	#else
1744 		return false;
1745 	#endif
1746 }
1747 
cpuinfo_has_arm_sha1(void)1748 static inline bool cpuinfo_has_arm_sha1(void) {
1749 	#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
1750 		return cpuinfo_isa.sha1;
1751 	#else
1752 		return false;
1753 	#endif
1754 }
1755 
cpuinfo_has_arm_sha2(void)1756 static inline bool cpuinfo_has_arm_sha2(void) {
1757 	#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
1758 		return cpuinfo_isa.sha2;
1759 	#else
1760 		return false;
1761 	#endif
1762 }
1763 
cpuinfo_has_arm_pmull(void)1764 static inline bool cpuinfo_has_arm_pmull(void) {
1765 	#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
1766 		return cpuinfo_isa.pmull;
1767 	#else
1768 		return false;
1769 	#endif
1770 }
1771 
cpuinfo_has_arm_crc32(void)1772 static inline bool cpuinfo_has_arm_crc32(void) {
1773 	#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
1774 		return cpuinfo_isa.crc32;
1775 	#else
1776 		return false;
1777 	#endif
1778 }
1779 
cpuinfo_has_arm_sve(void)1780 static inline bool cpuinfo_has_arm_sve(void) {
1781 	#if CPUINFO_ARCH_ARM64
1782 		return cpuinfo_isa.sve;
1783 	#else
1784 		return false;
1785 	#endif
1786 }
1787 
cpuinfo_has_arm_sve2(void)1788 static inline bool cpuinfo_has_arm_sve2(void) {
1789 	#if CPUINFO_ARCH_ARM64
1790 		return cpuinfo_isa.sve2;
1791 	#else
1792 		return false;
1793 	#endif
1794 }
1795 
1796 const struct cpuinfo_processor* CPUINFO_ABI cpuinfo_get_processors(void);
1797 const struct cpuinfo_core* CPUINFO_ABI cpuinfo_get_cores(void);
1798 const struct cpuinfo_cluster* CPUINFO_ABI cpuinfo_get_clusters(void);
1799 const struct cpuinfo_package* CPUINFO_ABI cpuinfo_get_packages(void);
1800 const struct cpuinfo_uarch_info* CPUINFO_ABI cpuinfo_get_uarchs(void);
1801 const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l1i_caches(void);
1802 const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l1d_caches(void);
1803 const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l2_caches(void);
1804 const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l3_caches(void);
1805 const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l4_caches(void);
1806 
1807 const struct cpuinfo_processor* CPUINFO_ABI cpuinfo_get_processor(uint32_t index);
1808 const struct cpuinfo_core* CPUINFO_ABI cpuinfo_get_core(uint32_t index);
1809 const struct cpuinfo_cluster* CPUINFO_ABI cpuinfo_get_cluster(uint32_t index);
1810 const struct cpuinfo_package* CPUINFO_ABI cpuinfo_get_package(uint32_t index);
1811 const struct cpuinfo_uarch_info* CPUINFO_ABI cpuinfo_get_uarch(uint32_t index);
1812 const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l1i_cache(uint32_t index);
1813 const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l1d_cache(uint32_t index);
1814 const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l2_cache(uint32_t index);
1815 const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l3_cache(uint32_t index);
1816 const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l4_cache(uint32_t index);
1817 
1818 uint32_t CPUINFO_ABI cpuinfo_get_processors_count(void);
1819 uint32_t CPUINFO_ABI cpuinfo_get_cores_count(void);
1820 uint32_t CPUINFO_ABI cpuinfo_get_clusters_count(void);
1821 uint32_t CPUINFO_ABI cpuinfo_get_packages_count(void);
1822 uint32_t CPUINFO_ABI cpuinfo_get_uarchs_count(void);
1823 uint32_t CPUINFO_ABI cpuinfo_get_l1i_caches_count(void);
1824 uint32_t CPUINFO_ABI cpuinfo_get_l1d_caches_count(void);
1825 uint32_t CPUINFO_ABI cpuinfo_get_l2_caches_count(void);
1826 uint32_t CPUINFO_ABI cpuinfo_get_l3_caches_count(void);
1827 uint32_t CPUINFO_ABI cpuinfo_get_l4_caches_count(void);
1828 
1829 /**
1830  * Returns upper bound on cache size.
1831  */
1832 uint32_t CPUINFO_ABI cpuinfo_get_max_cache_size(void);
1833 
1834 /**
1835  * Identify the logical processor that executes the current thread.
1836  *
1837  * There is no guarantee that the thread will stay on the same logical processor for any time.
1838  * Callers should treat the result as only a hint, and be prepared to handle NULL return value.
1839  */
1840 const struct cpuinfo_processor* CPUINFO_ABI cpuinfo_get_current_processor(void);
1841 
1842 /**
1843  * Identify the core that executes the current thread.
1844  *
1845  * There is no guarantee that the thread will stay on the same core for any time.
1846  * Callers should treat the result as only a hint, and be prepared to handle NULL return value.
1847  */
1848 const struct cpuinfo_core* CPUINFO_ABI cpuinfo_get_current_core(void);
1849 
1850 /**
1851  * Identify the microarchitecture index of the core that executes the current thread.
1852  * If the system does not support such identification, the function returns 0.
1853  *
1854  * There is no guarantee that the thread will stay on the same type of core for any time.
1855  * Callers should treat the result as only a hint.
1856  */
1857 uint32_t CPUINFO_ABI cpuinfo_get_current_uarch_index(void);
1858 
1859 /**
1860  * Identify the microarchitecture index of the core that executes the current thread.
1861  * If the system does not support such identification, the function returns the user-specified default value.
1862  *
1863  * There is no guarantee that the thread will stay on the same type of core for any time.
1864  * Callers should treat the result as only a hint.
1865  */
1866 uint32_t CPUINFO_ABI cpuinfo_get_current_uarch_index_with_default(uint32_t default_uarch_index);
1867 
1868 #ifdef __cplusplus
1869 } /* extern "C" */
1870 #endif
1871 
1872 #endif /* CPUINFO_H */
1873