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