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