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