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