#pragma once #ifndef CPUINFO_H #define CPUINFO_H #ifndef __cplusplus #include #endif #ifdef __APPLE__ #include #endif #include /* Identify architecture and define corresponding macro */ #if defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) || defined(_M_IX86) #define CPUINFO_ARCH_X86 1 #endif #if defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64) #define CPUINFO_ARCH_X86_64 1 #endif #if defined(__arm__) || defined(_M_ARM) #define CPUINFO_ARCH_ARM 1 #endif #if defined(__aarch64__) || defined(_M_ARM64) #define CPUINFO_ARCH_ARM64 1 #endif #if defined(__PPC64__) || defined(__powerpc64__) || defined(_ARCH_PPC64) #define CPUINFO_ARCH_PPC64 1 #endif #if defined(__asmjs__) #define CPUINFO_ARCH_ASMJS 1 #endif #if defined(__wasm__) #if defined(__wasm_simd128__) #define CPUINFO_ARCH_WASMSIMD 1 #else #define CPUINFO_ARCH_WASM 1 #endif #endif /* Define other architecture-specific macros as 0 */ #ifndef CPUINFO_ARCH_X86 #define CPUINFO_ARCH_X86 0 #endif #ifndef CPUINFO_ARCH_X86_64 #define CPUINFO_ARCH_X86_64 0 #endif #ifndef CPUINFO_ARCH_ARM #define CPUINFO_ARCH_ARM 0 #endif #ifndef CPUINFO_ARCH_ARM64 #define CPUINFO_ARCH_ARM64 0 #endif #ifndef CPUINFO_ARCH_PPC64 #define CPUINFO_ARCH_PPC64 0 #endif #ifndef CPUINFO_ARCH_ASMJS #define CPUINFO_ARCH_ASMJS 0 #endif #ifndef CPUINFO_ARCH_WASM #define CPUINFO_ARCH_WASM 0 #endif #ifndef CPUINFO_ARCH_WASMSIMD #define CPUINFO_ARCH_WASMSIMD 0 #endif #if CPUINFO_ARCH_X86 && defined(_MSC_VER) #define CPUINFO_ABI __cdecl #elif CPUINFO_ARCH_X86 && defined(__GNUC__) #define CPUINFO_ABI __attribute__((__cdecl__)) #else #define CPUINFO_ABI #endif #define CPUINFO_CACHE_UNIFIED 0x00000001 #define CPUINFO_CACHE_INCLUSIVE 0x00000002 #define CPUINFO_CACHE_COMPLEX_INDEXING 0x00000004 struct cpuinfo_cache { /** Cache size in bytes */ uint32_t size; /** Number of ways of associativity */ uint32_t associativity; /** Number of sets */ uint32_t sets; /** Number of partitions */ uint32_t partitions; /** Line size in bytes */ uint32_t line_size; /** * Binary characteristics of the cache (unified cache, inclusive cache, cache with complex indexing). * * @see CPUINFO_CACHE_UNIFIED, CPUINFO_CACHE_INCLUSIVE, CPUINFO_CACHE_COMPLEX_INDEXING */ uint32_t flags; /** Index of the first logical processor that shares this cache */ uint32_t processor_start; /** Number of logical processors that share this cache */ uint32_t processor_count; }; struct cpuinfo_trace_cache { uint32_t uops; uint32_t associativity; }; #define CPUINFO_PAGE_SIZE_4KB 0x1000 #define CPUINFO_PAGE_SIZE_1MB 0x100000 #define CPUINFO_PAGE_SIZE_2MB 0x200000 #define CPUINFO_PAGE_SIZE_4MB 0x400000 #define CPUINFO_PAGE_SIZE_16MB 0x1000000 #define CPUINFO_PAGE_SIZE_1GB 0x40000000 struct cpuinfo_tlb { uint32_t entries; uint32_t associativity; uint64_t pages; }; /** Vendor of processor core design */ enum cpuinfo_vendor { /** Processor vendor is not known to the library, or the library failed to get vendor information from the OS. */ cpuinfo_vendor_unknown = 0, /* Active vendors of modern CPUs */ /** * Intel Corporation. Vendor of x86, x86-64, IA64, and ARM processor microarchitectures. * * Sold its ARM design subsidiary in 2006. The last ARM processor design was released in 2004. */ cpuinfo_vendor_intel = 1, /** Advanced Micro Devices, Inc. Vendor of x86 and x86-64 processor microarchitectures. */ cpuinfo_vendor_amd = 2, /** ARM Holdings plc. Vendor of ARM and ARM64 processor microarchitectures. */ cpuinfo_vendor_arm = 3, /** Qualcomm Incorporated. Vendor of ARM and ARM64 processor microarchitectures. */ cpuinfo_vendor_qualcomm = 4, /** Apple Inc. Vendor of ARM and ARM64 processor microarchitectures. */ cpuinfo_vendor_apple = 5, /** Samsung Electronics Co., Ltd. Vendir if ARM64 processor microarchitectures. */ cpuinfo_vendor_samsung = 6, /** Nvidia Corporation. Vendor of ARM64-compatible processor microarchitectures. */ cpuinfo_vendor_nvidia = 7, /** MIPS Technologies, Inc. Vendor of MIPS processor microarchitectures. */ cpuinfo_vendor_mips = 8, /** International Business Machines Corporation. Vendor of PowerPC processor microarchitectures. */ cpuinfo_vendor_ibm = 9, /** Ingenic Semiconductor. Vendor of MIPS processor microarchitectures. */ cpuinfo_vendor_ingenic = 10, /** * VIA Technologies, Inc. Vendor of x86 and x86-64 processor microarchitectures. * * Processors are designed by Centaur Technology, a subsidiary of VIA Technologies. */ cpuinfo_vendor_via = 11, /** Cavium, Inc. Vendor of ARM64 processor microarchitectures. */ cpuinfo_vendor_cavium = 12, /** Broadcom, Inc. Vendor of ARM processor microarchitectures. */ cpuinfo_vendor_broadcom = 13, /** Applied Micro Circuits Corporation (APM). Vendor of ARM64 processor microarchitectures. */ cpuinfo_vendor_apm = 14, /** * Huawei Technologies Co., Ltd. Vendor of ARM64 processor microarchitectures. * * Processors are designed by HiSilicon, a subsidiary of Huawei. */ cpuinfo_vendor_huawei = 15, /** * Hygon (Chengdu Haiguang Integrated Circuit Design Co., Ltd), Vendor of x86-64 processor microarchitectures. * * Processors are variants of AMD cores. */ cpuinfo_vendor_hygon = 16, /* Active vendors of embedded CPUs */ /** Texas Instruments Inc. Vendor of ARM processor microarchitectures. */ cpuinfo_vendor_texas_instruments = 30, /** Marvell Technology Group Ltd. Vendor of ARM processor microarchitectures. */ cpuinfo_vendor_marvell = 31, /** RDC Semiconductor Co., Ltd. Vendor of x86 processor microarchitectures. */ cpuinfo_vendor_rdc = 32, /** DM&P Electronics Inc. Vendor of x86 processor microarchitectures. */ cpuinfo_vendor_dmp = 33, /** Motorola, Inc. Vendor of PowerPC and ARM processor microarchitectures. */ cpuinfo_vendor_motorola = 34, /* Defunct CPU vendors */ /** * Transmeta Corporation. Vendor of x86 processor microarchitectures. * * Now defunct. The last processor design was released in 2004. * Transmeta processors implemented VLIW ISA and used binary translation to execute x86 code. */ cpuinfo_vendor_transmeta = 50, /** * Cyrix Corporation. Vendor of x86 processor microarchitectures. * * Now defunct. The last processor design was released in 1996. */ cpuinfo_vendor_cyrix = 51, /** * Rise Technology. Vendor of x86 processor microarchitectures. * * Now defunct. The last processor design was released in 1999. */ cpuinfo_vendor_rise = 52, /** * National Semiconductor. Vendor of x86 processor microarchitectures. * * Sold its x86 design subsidiary in 1999. The last processor design was released in 1998. */ cpuinfo_vendor_nsc = 53, /** * Silicon Integrated Systems. Vendor of x86 processor microarchitectures. * * Sold its x86 design subsidiary in 2001. The last processor design was released in 2001. */ cpuinfo_vendor_sis = 54, /** * NexGen. Vendor of x86 processor microarchitectures. * * Now defunct. The last processor design was released in 1994. * NexGen designed the first x86 microarchitecture which decomposed x86 instructions into simple microoperations. */ cpuinfo_vendor_nexgen = 55, /** * United Microelectronics Corporation. Vendor of x86 processor microarchitectures. * * Ceased x86 in the early 1990s. The last processor design was released in 1991. * Designed U5C and U5D processors. Both are 486 level. */ cpuinfo_vendor_umc = 56, /** * Digital Equipment Corporation. Vendor of ARM processor microarchitecture. * * Sold its ARM designs in 1997. The last processor design was released in 1997. */ cpuinfo_vendor_dec = 57, }; /** * Processor microarchitecture * * Processors with different microarchitectures often have different instruction performance characteristics, * and may have dramatically different pipeline organization. */ enum cpuinfo_uarch { /** Microarchitecture is unknown, or the library failed to get information about the microarchitecture from OS */ cpuinfo_uarch_unknown = 0, /** Pentium and Pentium MMX microarchitecture. */ cpuinfo_uarch_p5 = 0x00100100, /** Intel Quark microarchitecture. */ cpuinfo_uarch_quark = 0x00100101, /** Pentium Pro, Pentium II, and Pentium III. */ cpuinfo_uarch_p6 = 0x00100200, /** Pentium M. */ cpuinfo_uarch_dothan = 0x00100201, /** Intel Core microarchitecture. */ cpuinfo_uarch_yonah = 0x00100202, /** Intel Core 2 microarchitecture on 65 nm process. */ cpuinfo_uarch_conroe = 0x00100203, /** Intel Core 2 microarchitecture on 45 nm process. */ cpuinfo_uarch_penryn = 0x00100204, /** Intel Nehalem and Westmere microarchitectures (Core i3/i5/i7 1st gen). */ cpuinfo_uarch_nehalem = 0x00100205, /** Intel Sandy Bridge microarchitecture (Core i3/i5/i7 2nd gen). */ cpuinfo_uarch_sandy_bridge = 0x00100206, /** Intel Ivy Bridge microarchitecture (Core i3/i5/i7 3rd gen). */ cpuinfo_uarch_ivy_bridge = 0x00100207, /** Intel Haswell microarchitecture (Core i3/i5/i7 4th gen). */ cpuinfo_uarch_haswell = 0x00100208, /** Intel Broadwell microarchitecture. */ cpuinfo_uarch_broadwell = 0x00100209, /** Intel Sky Lake microarchitecture (14 nm, including Kaby/Coffee/Whiskey/Amber/Comet/Cascade/Cooper Lake). */ cpuinfo_uarch_sky_lake = 0x0010020A, /** DEPRECATED (Intel Kaby Lake microarchitecture). */ cpuinfo_uarch_kaby_lake = 0x0010020A, /** Intel Palm Cove microarchitecture (10 nm, Cannon Lake). */ cpuinfo_uarch_palm_cove = 0x0010020B, /** Intel Sunny Cove microarchitecture (10 nm, Ice Lake). */ cpuinfo_uarch_sunny_cove = 0x0010020C, /** Pentium 4 with Willamette, Northwood, or Foster cores. */ cpuinfo_uarch_willamette = 0x00100300, /** Pentium 4 with Prescott and later cores. */ cpuinfo_uarch_prescott = 0x00100301, /** Intel Atom on 45 nm process. */ cpuinfo_uarch_bonnell = 0x00100400, /** Intel Atom on 32 nm process. */ cpuinfo_uarch_saltwell = 0x00100401, /** Intel Silvermont microarchitecture (22 nm out-of-order Atom). */ cpuinfo_uarch_silvermont = 0x00100402, /** Intel Airmont microarchitecture (14 nm out-of-order Atom). */ cpuinfo_uarch_airmont = 0x00100403, /** Intel Goldmont microarchitecture (Denverton, Apollo Lake). */ cpuinfo_uarch_goldmont = 0x00100404, /** Intel Goldmont Plus microarchitecture (Gemini Lake). */ cpuinfo_uarch_goldmont_plus = 0x00100405, /** Intel Knights Ferry HPC boards. */ cpuinfo_uarch_knights_ferry = 0x00100500, /** Intel Knights Corner HPC boards (aka Xeon Phi). */ cpuinfo_uarch_knights_corner = 0x00100501, /** Intel Knights Landing microarchitecture (second-gen MIC). */ cpuinfo_uarch_knights_landing = 0x00100502, /** Intel Knights Hill microarchitecture (third-gen MIC). */ cpuinfo_uarch_knights_hill = 0x00100503, /** Intel Knights Mill Xeon Phi. */ cpuinfo_uarch_knights_mill = 0x00100504, /** Intel/Marvell XScale series. */ cpuinfo_uarch_xscale = 0x00100600, /** AMD K5. */ cpuinfo_uarch_k5 = 0x00200100, /** AMD K6 and alike. */ cpuinfo_uarch_k6 = 0x00200101, /** AMD Athlon and Duron. */ cpuinfo_uarch_k7 = 0x00200102, /** AMD Athlon 64, Opteron 64. */ cpuinfo_uarch_k8 = 0x00200103, /** AMD Family 10h (Barcelona, Istambul, Magny-Cours). */ cpuinfo_uarch_k10 = 0x00200104, /** * AMD Bulldozer microarchitecture * Zambezi FX-series CPUs, Zurich, Valencia and Interlagos Opteron CPUs. */ cpuinfo_uarch_bulldozer = 0x00200105, /** * AMD Piledriver microarchitecture * Vishera FX-series CPUs, Trinity and Richland APUs, Delhi, Seoul, Abu Dhabi Opteron CPUs. */ cpuinfo_uarch_piledriver = 0x00200106, /** AMD Steamroller microarchitecture (Kaveri APUs). */ cpuinfo_uarch_steamroller = 0x00200107, /** AMD Excavator microarchitecture (Carizzo APUs). */ cpuinfo_uarch_excavator = 0x00200108, /** AMD Zen microarchitecture (12/14 nm Ryzen and EPYC CPUs). */ cpuinfo_uarch_zen = 0x00200109, /** AMD Zen 2 microarchitecture (7 nm Ryzen and EPYC CPUs). */ cpuinfo_uarch_zen2 = 0x0020010A, /** AMD Zen 3 microarchitecture. */ cpuinfo_uarch_zen3 = 0x0020010B, /** AMD Zen 4 microarchitecture. */ cpuinfo_uarch_zen4 = 0x0020010C, /** NSC Geode and AMD Geode GX and LX. */ cpuinfo_uarch_geode = 0x00200200, /** AMD Bobcat mobile microarchitecture. */ cpuinfo_uarch_bobcat = 0x00200201, /** AMD Jaguar mobile microarchitecture. */ cpuinfo_uarch_jaguar = 0x00200202, /** AMD Puma mobile microarchitecture. */ cpuinfo_uarch_puma = 0x00200203, /** ARM7 series. */ cpuinfo_uarch_arm7 = 0x00300100, /** ARM9 series. */ cpuinfo_uarch_arm9 = 0x00300101, /** ARM 1136, ARM 1156, ARM 1176, or ARM 11MPCore. */ cpuinfo_uarch_arm11 = 0x00300102, /** ARM Cortex-A5. */ cpuinfo_uarch_cortex_a5 = 0x00300205, /** ARM Cortex-A7. */ cpuinfo_uarch_cortex_a7 = 0x00300207, /** ARM Cortex-A8. */ cpuinfo_uarch_cortex_a8 = 0x00300208, /** ARM Cortex-A9. */ cpuinfo_uarch_cortex_a9 = 0x00300209, /** ARM Cortex-A12. */ cpuinfo_uarch_cortex_a12 = 0x00300212, /** ARM Cortex-A15. */ cpuinfo_uarch_cortex_a15 = 0x00300215, /** ARM Cortex-A17. */ cpuinfo_uarch_cortex_a17 = 0x00300217, /** ARM Cortex-A32. */ cpuinfo_uarch_cortex_a32 = 0x00300332, /** ARM Cortex-A35. */ cpuinfo_uarch_cortex_a35 = 0x00300335, /** ARM Cortex-A53. */ cpuinfo_uarch_cortex_a53 = 0x00300353, /** ARM Cortex-A55 revision 0 (restricted dual-issue capabilities compared to revision 1+). */ cpuinfo_uarch_cortex_a55r0 = 0x00300354, /** ARM Cortex-A55. */ cpuinfo_uarch_cortex_a55 = 0x00300355, /** ARM Cortex-A57. */ cpuinfo_uarch_cortex_a57 = 0x00300357, /** ARM Cortex-A65. */ cpuinfo_uarch_cortex_a65 = 0x00300365, /** ARM Cortex-A72. */ cpuinfo_uarch_cortex_a72 = 0x00300372, /** ARM Cortex-A73. */ cpuinfo_uarch_cortex_a73 = 0x00300373, /** ARM Cortex-A75. */ cpuinfo_uarch_cortex_a75 = 0x00300375, /** ARM Cortex-A76. */ cpuinfo_uarch_cortex_a76 = 0x00300376, /** ARM Cortex-A77. */ cpuinfo_uarch_cortex_a77 = 0x00300377, /** ARM Cortex-A78. */ cpuinfo_uarch_cortex_a78 = 0x00300378, /** ARM Neoverse N1. */ cpuinfo_uarch_neoverse_n1 = 0x00300400, /** ARM Neoverse E1. */ cpuinfo_uarch_neoverse_e1 = 0x00300401, /** ARM Neoverse V1. */ cpuinfo_uarch_neoverse_v1 = 0x00300402, /** ARM Neoverse N2. */ cpuinfo_uarch_neoverse_n2 = 0x00300403, /** ARM Neoverse V2. */ cpuinfo_uarch_neoverse_v2 = 0x00300404, /** ARM Cortex-X1. */ cpuinfo_uarch_cortex_x1 = 0x00300501, /** ARM Cortex-X2. */ cpuinfo_uarch_cortex_x2 = 0x00300502, /** ARM Cortex-X3. */ cpuinfo_uarch_cortex_x3 = 0x00300503, /** ARM Cortex-A510. */ cpuinfo_uarch_cortex_a510 = 0x00300551, /** ARM Cortex-A710. */ cpuinfo_uarch_cortex_a710 = 0x00300571, /** ARM Cortex-A715. */ cpuinfo_uarch_cortex_a715 = 0x00300572, /** Qualcomm Scorpion. */ cpuinfo_uarch_scorpion = 0x00400100, /** Qualcomm Krait. */ cpuinfo_uarch_krait = 0x00400101, /** Qualcomm Kryo. */ cpuinfo_uarch_kryo = 0x00400102, /** Qualcomm Falkor. */ cpuinfo_uarch_falkor = 0x00400103, /** Qualcomm Saphira. */ cpuinfo_uarch_saphira = 0x00400104, /** Nvidia Denver. */ cpuinfo_uarch_denver = 0x00500100, /** Nvidia Denver 2. */ cpuinfo_uarch_denver2 = 0x00500101, /** Nvidia Carmel. */ cpuinfo_uarch_carmel = 0x00500102, /** Samsung Exynos M1 (Exynos 8890 big cores). */ cpuinfo_uarch_exynos_m1 = 0x00600100, /** Samsung Exynos M2 (Exynos 8895 big cores). */ cpuinfo_uarch_exynos_m2 = 0x00600101, /** Samsung Exynos M3 (Exynos 9810 big cores). */ cpuinfo_uarch_exynos_m3 = 0x00600102, /** Samsung Exynos M4 (Exynos 9820 big cores). */ cpuinfo_uarch_exynos_m4 = 0x00600103, /** Samsung Exynos M5 (Exynos 9830 big cores). */ cpuinfo_uarch_exynos_m5 = 0x00600104, /* Deprecated synonym for Cortex-A76 */ cpuinfo_uarch_cortex_a76ae = 0x00300376, /* Deprecated names for Exynos. */ cpuinfo_uarch_mongoose_m1 = 0x00600100, cpuinfo_uarch_mongoose_m2 = 0x00600101, cpuinfo_uarch_meerkat_m3 = 0x00600102, cpuinfo_uarch_meerkat_m4 = 0x00600103, /** Apple A6 and A6X processors. */ cpuinfo_uarch_swift = 0x00700100, /** Apple A7 processor. */ cpuinfo_uarch_cyclone = 0x00700101, /** Apple A8 and A8X processor. */ cpuinfo_uarch_typhoon = 0x00700102, /** Apple A9 and A9X processor. */ cpuinfo_uarch_twister = 0x00700103, /** Apple A10 and A10X processor. */ cpuinfo_uarch_hurricane = 0x00700104, /** Apple A11 processor (big cores). */ cpuinfo_uarch_monsoon = 0x00700105, /** Apple A11 processor (little cores). */ cpuinfo_uarch_mistral = 0x00700106, /** Apple A12 processor (big cores). */ cpuinfo_uarch_vortex = 0x00700107, /** Apple A12 processor (little cores). */ cpuinfo_uarch_tempest = 0x00700108, /** Apple A13 processor (big cores). */ cpuinfo_uarch_lightning = 0x00700109, /** Apple A13 processor (little cores). */ cpuinfo_uarch_thunder = 0x0070010A, /** Apple A14 / M1 processor (big cores). */ cpuinfo_uarch_firestorm = 0x0070010B, /** Apple A14 / M1 processor (little cores). */ cpuinfo_uarch_icestorm = 0x0070010C, /** Apple A15 / M2 processor (big cores). */ cpuinfo_uarch_avalanche = 0x0070010D, /** Apple A15 / M2 processor (little cores). */ cpuinfo_uarch_blizzard = 0x0070010E, /** Cavium ThunderX. */ cpuinfo_uarch_thunderx = 0x00800100, /** Cavium ThunderX2 (originally Broadcom Vulkan). */ cpuinfo_uarch_thunderx2 = 0x00800200, /** Marvell PJ4. */ cpuinfo_uarch_pj4 = 0x00900100, /** Broadcom Brahma B15. */ cpuinfo_uarch_brahma_b15 = 0x00A00100, /** Broadcom Brahma B53. */ cpuinfo_uarch_brahma_b53 = 0x00A00101, /** Applied Micro X-Gene. */ cpuinfo_uarch_xgene = 0x00B00100, /* Hygon Dhyana (a modification of AMD Zen for Chinese market). */ cpuinfo_uarch_dhyana = 0x01000100, /** HiSilicon TaiShan v110 (Huawei Kunpeng 920 series processors). */ cpuinfo_uarch_taishan_v110 = 0x00C00100, }; struct cpuinfo_processor { /** SMT (hyperthread) ID within a core */ uint32_t smt_id; /** Core containing this logical processor */ const struct cpuinfo_core* core; /** Cluster of cores containing this logical processor */ const struct cpuinfo_cluster* cluster; /** Physical package containing this logical processor */ const struct cpuinfo_package* package; #if defined(__linux__) /** * Linux-specific ID for the logical processor: * - Linux kernel exposes information about this logical processor in /sys/devices/system/cpu/cpu/ * - Bit in the cpu_set_t identifies this logical processor */ int linux_id; #endif #if defined(_WIN32) || defined(__CYGWIN__) /** Windows-specific ID for the group containing the logical processor. */ uint16_t windows_group_id; /** * Windows-specific ID of the logical processor within its group: * - Bit in the KAFFINITY mask identifies this logical processor within its group. */ uint16_t windows_processor_id; #endif #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 /** APIC ID (unique x86-specific ID of the logical processor) */ uint32_t apic_id; #endif struct { /** Level 1 instruction cache */ const struct cpuinfo_cache* l1i; /** Level 1 data cache */ const struct cpuinfo_cache* l1d; /** Level 2 unified or data cache */ const struct cpuinfo_cache* l2; /** Level 3 unified or data cache */ const struct cpuinfo_cache* l3; /** Level 4 unified or data cache */ const struct cpuinfo_cache* l4; } cache; }; struct cpuinfo_core { /** Index of the first logical processor on this core. */ uint32_t processor_start; /** Number of logical processors on this core */ uint32_t processor_count; /** Core ID within a package */ uint32_t core_id; /** Cluster containing this core */ const struct cpuinfo_cluster* cluster; /** Physical package containing this core. */ const struct cpuinfo_package* package; /** Vendor of the CPU microarchitecture for this core */ enum cpuinfo_vendor vendor; /** CPU microarchitecture for this core */ enum cpuinfo_uarch uarch; #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 /** Value of CPUID leaf 1 EAX register for this core */ uint32_t cpuid; #elif CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 /** Value of Main ID Register (MIDR) for this core */ uint32_t midr; #endif /** Clock rate (non-Turbo) of the core, in Hz */ uint64_t frequency; }; struct cpuinfo_cluster { /** Index of the first logical processor in the cluster */ uint32_t processor_start; /** Number of logical processors in the cluster */ uint32_t processor_count; /** Index of the first core in the cluster */ uint32_t core_start; /** Number of cores on the cluster */ uint32_t core_count; /** Cluster ID within a package */ uint32_t cluster_id; /** Physical package containing the cluster */ const struct cpuinfo_package* package; /** CPU microarchitecture vendor of the cores in the cluster */ enum cpuinfo_vendor vendor; /** CPU microarchitecture of the cores in the cluster */ enum cpuinfo_uarch uarch; #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 /** Value of CPUID leaf 1 EAX register of the cores in the cluster */ uint32_t cpuid; #elif CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 /** Value of Main ID Register (MIDR) of the cores in the cluster */ uint32_t midr; #endif /** Clock rate (non-Turbo) of the cores in the cluster, in Hz */ uint64_t frequency; }; #define CPUINFO_PACKAGE_NAME_MAX 48 struct cpuinfo_package { /** SoC or processor chip model name */ char name[CPUINFO_PACKAGE_NAME_MAX]; /** Index of the first logical processor on this physical package */ uint32_t processor_start; /** Number of logical processors on this physical package */ uint32_t processor_count; /** Index of the first core on this physical package */ uint32_t core_start; /** Number of cores on this physical package */ uint32_t core_count; /** Index of the first cluster of cores on this physical package */ uint32_t cluster_start; /** Number of clusters of cores on this physical package */ uint32_t cluster_count; }; struct cpuinfo_uarch_info { /** Type of CPU microarchitecture */ enum cpuinfo_uarch uarch; #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 /** Value of CPUID leaf 1 EAX register for the microarchitecture */ uint32_t cpuid; #elif CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 /** Value of Main ID Register (MIDR) for the microarchitecture */ uint32_t midr; #endif /** Number of logical processors with the microarchitecture */ uint32_t processor_count; /** Number of cores with the microarchitecture */ uint32_t core_count; }; #ifdef __cplusplus extern "C" { #endif bool CPUINFO_ABI cpuinfo_initialize(void); void CPUINFO_ABI cpuinfo_deinitialize(void); #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 /* This structure is not a part of stable API. Use cpuinfo_has_x86_* functions instead. */ struct cpuinfo_x86_isa { #if CPUINFO_ARCH_X86 bool rdtsc; #endif bool rdtscp; bool rdpid; bool sysenter; #if CPUINFO_ARCH_X86 bool syscall; #endif bool msr; bool clzero; bool clflush; bool clflushopt; bool mwait; bool mwaitx; #if CPUINFO_ARCH_X86 bool emmx; #endif bool fxsave; bool xsave; #if CPUINFO_ARCH_X86 bool fpu; bool mmx; bool mmx_plus; #endif bool three_d_now; bool three_d_now_plus; #if CPUINFO_ARCH_X86 bool three_d_now_geode; #endif bool prefetch; bool prefetchw; bool prefetchwt1; #if CPUINFO_ARCH_X86 bool daz; bool sse; bool sse2; #endif bool sse3; bool ssse3; bool sse4_1; bool sse4_2; bool sse4a; bool misaligned_sse; bool avx; bool avxvnni; bool fma3; bool fma4; bool xop; bool f16c; bool avx2; bool avx512f; bool avx512pf; bool avx512er; bool avx512cd; bool avx512dq; bool avx512bw; bool avx512vl; bool avx512ifma; bool avx512vbmi; bool avx512vbmi2; bool avx512bitalg; bool avx512vpopcntdq; bool avx512vnni; bool avx512bf16; bool avx512fp16; bool avx512vp2intersect; bool avx512_4vnniw; bool avx512_4fmaps; bool hle; bool rtm; bool xtest; bool mpx; #if CPUINFO_ARCH_X86 bool cmov; bool cmpxchg8b; #endif bool cmpxchg16b; bool clwb; bool movbe; #if CPUINFO_ARCH_X86_64 bool lahf_sahf; #endif bool fs_gs_base; bool lzcnt; bool popcnt; bool tbm; bool bmi; bool bmi2; bool adx; bool aes; bool vaes; bool pclmulqdq; bool vpclmulqdq; bool gfni; bool rdrand; bool rdseed; bool sha; bool rng; bool ace; bool ace2; bool phe; bool pmm; bool lwp; }; extern struct cpuinfo_x86_isa cpuinfo_isa; #endif static inline bool cpuinfo_has_x86_rdtsc(void) { #if CPUINFO_ARCH_X86_64 return true; #elif CPUINFO_ARCH_X86 #if defined(__ANDROID__) return true; #else return cpuinfo_isa.rdtsc; #endif #else return false; #endif } static inline bool cpuinfo_has_x86_rdtscp(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.rdtscp; #else return false; #endif } static inline bool cpuinfo_has_x86_rdpid(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.rdpid; #else return false; #endif } static inline bool cpuinfo_has_x86_clzero(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.clzero; #else return false; #endif } static inline bool cpuinfo_has_x86_mwait(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.mwait; #else return false; #endif } static inline bool cpuinfo_has_x86_mwaitx(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.mwaitx; #else return false; #endif } static inline bool cpuinfo_has_x86_fxsave(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.fxsave; #else return false; #endif } static inline bool cpuinfo_has_x86_xsave(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.xsave; #else return false; #endif } static inline bool cpuinfo_has_x86_fpu(void) { #if CPUINFO_ARCH_X86_64 return true; #elif CPUINFO_ARCH_X86 #if defined(__ANDROID__) return true; #else return cpuinfo_isa.fpu; #endif #else return false; #endif } static inline bool cpuinfo_has_x86_mmx(void) { #if CPUINFO_ARCH_X86_64 return true; #elif CPUINFO_ARCH_X86 #if defined(__ANDROID__) return true; #else return cpuinfo_isa.mmx; #endif #else return false; #endif } static inline bool cpuinfo_has_x86_mmx_plus(void) { #if CPUINFO_ARCH_X86_64 return true; #elif CPUINFO_ARCH_X86 #if defined(__ANDROID__) return true; #else return cpuinfo_isa.mmx_plus; #endif #else return false; #endif } static inline bool cpuinfo_has_x86_3dnow(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.three_d_now; #else return false; #endif } static inline bool cpuinfo_has_x86_3dnow_plus(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.three_d_now_plus; #else return false; #endif } static inline bool cpuinfo_has_x86_3dnow_geode(void) { #if CPUINFO_ARCH_X86_64 return false; #elif CPUINFO_ARCH_X86 #if defined(__ANDROID__) return false; #else return cpuinfo_isa.three_d_now_geode; #endif #else return false; #endif } static inline bool cpuinfo_has_x86_prefetch(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.prefetch; #else return false; #endif } static inline bool cpuinfo_has_x86_prefetchw(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.prefetchw; #else return false; #endif } static inline bool cpuinfo_has_x86_prefetchwt1(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.prefetchwt1; #else return false; #endif } static inline bool cpuinfo_has_x86_daz(void) { #if CPUINFO_ARCH_X86_64 return true; #elif CPUINFO_ARCH_X86 #if defined(__ANDROID__) return true; #else return cpuinfo_isa.daz; #endif #else return false; #endif } static inline bool cpuinfo_has_x86_sse(void) { #if CPUINFO_ARCH_X86_64 return true; #elif CPUINFO_ARCH_X86 #if defined(__ANDROID__) return true; #else return cpuinfo_isa.sse; #endif #else return false; #endif } static inline bool cpuinfo_has_x86_sse2(void) { #if CPUINFO_ARCH_X86_64 return true; #elif CPUINFO_ARCH_X86 #if defined(__ANDROID__) return true; #else return cpuinfo_isa.sse2; #endif #else return false; #endif } static inline bool cpuinfo_has_x86_sse3(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 #if defined(__ANDROID__) return true; #else return cpuinfo_isa.sse3; #endif #else return false; #endif } static inline bool cpuinfo_has_x86_ssse3(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 #if defined(__ANDROID__) return true; #else return cpuinfo_isa.ssse3; #endif #else return false; #endif } static inline bool cpuinfo_has_x86_sse4_1(void) { #if CPUINFO_ARCH_X86_64 #if defined(__ANDROID__) return true; #else return cpuinfo_isa.sse4_1; #endif #elif CPUINFO_ARCH_X86 return cpuinfo_isa.sse4_1; #else return false; #endif } static inline bool cpuinfo_has_x86_sse4_2(void) { #if CPUINFO_ARCH_X86_64 #if defined(__ANDROID__) return true; #else return cpuinfo_isa.sse4_2; #endif #elif CPUINFO_ARCH_X86 return cpuinfo_isa.sse4_2; #else return false; #endif } static inline bool cpuinfo_has_x86_sse4a(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.sse4a; #else return false; #endif } static inline bool cpuinfo_has_x86_misaligned_sse(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.misaligned_sse; #else return false; #endif } static inline bool cpuinfo_has_x86_avx(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.avx; #else return false; #endif } static inline bool cpuinfo_has_x86_avxvnni(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.avxvnni; #else return false; #endif } static inline bool cpuinfo_has_x86_fma3(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.fma3; #else return false; #endif } static inline bool cpuinfo_has_x86_fma4(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.fma4; #else return false; #endif } static inline bool cpuinfo_has_x86_xop(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.xop; #else return false; #endif } static inline bool cpuinfo_has_x86_f16c(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.f16c; #else return false; #endif } static inline bool cpuinfo_has_x86_avx2(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.avx2; #else return false; #endif } static inline bool cpuinfo_has_x86_avx512f(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.avx512f; #else return false; #endif } static inline bool cpuinfo_has_x86_avx512pf(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.avx512pf; #else return false; #endif } static inline bool cpuinfo_has_x86_avx512er(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.avx512er; #else return false; #endif } static inline bool cpuinfo_has_x86_avx512cd(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.avx512cd; #else return false; #endif } static inline bool cpuinfo_has_x86_avx512dq(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.avx512dq; #else return false; #endif } static inline bool cpuinfo_has_x86_avx512bw(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.avx512bw; #else return false; #endif } static inline bool cpuinfo_has_x86_avx512vl(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.avx512vl; #else return false; #endif } static inline bool cpuinfo_has_x86_avx512ifma(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.avx512ifma; #else return false; #endif } static inline bool cpuinfo_has_x86_avx512vbmi(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.avx512vbmi; #else return false; #endif } static inline bool cpuinfo_has_x86_avx512vbmi2(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.avx512vbmi2; #else return false; #endif } static inline bool cpuinfo_has_x86_avx512bitalg(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.avx512bitalg; #else return false; #endif } static inline bool cpuinfo_has_x86_avx512vpopcntdq(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.avx512vpopcntdq; #else return false; #endif } static inline bool cpuinfo_has_x86_avx512vnni(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.avx512vnni; #else return false; #endif } static inline bool cpuinfo_has_x86_avx512bf16(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.avx512bf16; #else return false; #endif } static inline bool cpuinfo_has_x86_avx512fp16(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.avx512fp16; #else return false; #endif } static inline bool cpuinfo_has_x86_avx512vp2intersect(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.avx512vp2intersect; #else return false; #endif } static inline bool cpuinfo_has_x86_avx512_4vnniw(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.avx512_4vnniw; #else return false; #endif } static inline bool cpuinfo_has_x86_avx512_4fmaps(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.avx512_4fmaps; #else return false; #endif } static inline bool cpuinfo_has_x86_hle(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.hle; #else return false; #endif } static inline bool cpuinfo_has_x86_rtm(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.rtm; #else return false; #endif } static inline bool cpuinfo_has_x86_xtest(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.xtest; #else return false; #endif } static inline bool cpuinfo_has_x86_mpx(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.mpx; #else return false; #endif } static inline bool cpuinfo_has_x86_cmov(void) { #if CPUINFO_ARCH_X86_64 return true; #elif CPUINFO_ARCH_X86 return cpuinfo_isa.cmov; #else return false; #endif } static inline bool cpuinfo_has_x86_cmpxchg8b(void) { #if CPUINFO_ARCH_X86_64 return true; #elif CPUINFO_ARCH_X86 return cpuinfo_isa.cmpxchg8b; #else return false; #endif } static inline bool cpuinfo_has_x86_cmpxchg16b(void) { #if CPUINFO_ARCH_X86_64 return cpuinfo_isa.cmpxchg16b; #else return false; #endif } static inline bool cpuinfo_has_x86_clwb(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.clwb; #else return false; #endif } static inline bool cpuinfo_has_x86_movbe(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.movbe; #else return false; #endif } static inline bool cpuinfo_has_x86_lahf_sahf(void) { #if CPUINFO_ARCH_X86 return true; #elif CPUINFO_ARCH_X86_64 return cpuinfo_isa.lahf_sahf; #else return false; #endif } static inline bool cpuinfo_has_x86_lzcnt(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.lzcnt; #else return false; #endif } static inline bool cpuinfo_has_x86_popcnt(void) { #if CPUINFO_ARCH_X86_64 #if defined(__ANDROID__) return true; #else return cpuinfo_isa.popcnt; #endif #elif CPUINFO_ARCH_X86 return cpuinfo_isa.popcnt; #else return false; #endif } static inline bool cpuinfo_has_x86_tbm(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.tbm; #else return false; #endif } static inline bool cpuinfo_has_x86_bmi(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.bmi; #else return false; #endif } static inline bool cpuinfo_has_x86_bmi2(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.bmi2; #else return false; #endif } static inline bool cpuinfo_has_x86_adx(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.adx; #else return false; #endif } static inline bool cpuinfo_has_x86_aes(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.aes; #else return false; #endif } static inline bool cpuinfo_has_x86_vaes(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.vaes; #else return false; #endif } static inline bool cpuinfo_has_x86_pclmulqdq(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.pclmulqdq; #else return false; #endif } static inline bool cpuinfo_has_x86_vpclmulqdq(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.vpclmulqdq; #else return false; #endif } static inline bool cpuinfo_has_x86_gfni(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.gfni; #else return false; #endif } static inline bool cpuinfo_has_x86_rdrand(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.rdrand; #else return false; #endif } static inline bool cpuinfo_has_x86_rdseed(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.rdseed; #else return false; #endif } static inline bool cpuinfo_has_x86_sha(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.sha; #else return false; #endif } #if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 /* This structure is not a part of stable API. Use cpuinfo_has_arm_* functions instead. */ struct cpuinfo_arm_isa { #if CPUINFO_ARCH_ARM bool thumb; bool thumb2; bool thumbee; bool jazelle; bool armv5e; bool armv6; bool armv6k; bool armv7; bool armv7mp; bool armv8; bool idiv; bool vfpv2; bool vfpv3; bool d32; bool fp16; bool fma; bool wmmx; bool wmmx2; bool neon; #endif #if CPUINFO_ARCH_ARM64 bool atomics; bool bf16; bool sve; bool sve2; bool i8mm; #endif bool rdm; bool fp16arith; bool dot; bool jscvt; bool fcma; bool fhm; bool aes; bool sha1; bool sha2; bool pmull; bool crc32; }; extern struct cpuinfo_arm_isa cpuinfo_isa; #endif static inline bool cpuinfo_has_arm_thumb(void) { #if CPUINFO_ARCH_ARM return cpuinfo_isa.thumb; #else return false; #endif } static inline bool cpuinfo_has_arm_thumb2(void) { #if CPUINFO_ARCH_ARM return cpuinfo_isa.thumb2; #else return false; #endif } static inline bool cpuinfo_has_arm_v5e(void) { #if CPUINFO_ARCH_ARM return cpuinfo_isa.armv5e; #else return false; #endif } static inline bool cpuinfo_has_arm_v6(void) { #if CPUINFO_ARCH_ARM return cpuinfo_isa.armv6; #else return false; #endif } static inline bool cpuinfo_has_arm_v6k(void) { #if CPUINFO_ARCH_ARM return cpuinfo_isa.armv6k; #else return false; #endif } static inline bool cpuinfo_has_arm_v7(void) { #if CPUINFO_ARCH_ARM return cpuinfo_isa.armv7; #else return false; #endif } static inline bool cpuinfo_has_arm_v7mp(void) { #if CPUINFO_ARCH_ARM return cpuinfo_isa.armv7mp; #else return false; #endif } static inline bool cpuinfo_has_arm_v8(void) { #if CPUINFO_ARCH_ARM64 return true; #elif CPUINFO_ARCH_ARM return cpuinfo_isa.armv8; #else return false; #endif } static inline bool cpuinfo_has_arm_idiv(void) { #if CPUINFO_ARCH_ARM64 return true; #elif CPUINFO_ARCH_ARM return cpuinfo_isa.idiv; #else return false; #endif } static inline bool cpuinfo_has_arm_vfpv2(void) { #if CPUINFO_ARCH_ARM return cpuinfo_isa.vfpv2; #else return false; #endif } static inline bool cpuinfo_has_arm_vfpv3(void) { #if CPUINFO_ARCH_ARM64 return true; #elif CPUINFO_ARCH_ARM return cpuinfo_isa.vfpv3; #else return false; #endif } static inline bool cpuinfo_has_arm_vfpv3_d32(void) { #if CPUINFO_ARCH_ARM64 return true; #elif CPUINFO_ARCH_ARM return cpuinfo_isa.vfpv3 && cpuinfo_isa.d32; #else return false; #endif } static inline bool cpuinfo_has_arm_vfpv3_fp16(void) { #if CPUINFO_ARCH_ARM64 return true; #elif CPUINFO_ARCH_ARM return cpuinfo_isa.vfpv3 && cpuinfo_isa.fp16; #else return false; #endif } static inline bool cpuinfo_has_arm_vfpv3_fp16_d32(void) { #if CPUINFO_ARCH_ARM64 return true; #elif CPUINFO_ARCH_ARM return cpuinfo_isa.vfpv3 && cpuinfo_isa.fp16 && cpuinfo_isa.d32; #else return false; #endif } static inline bool cpuinfo_has_arm_vfpv4(void) { #if CPUINFO_ARCH_ARM64 return true; #elif CPUINFO_ARCH_ARM return cpuinfo_isa.vfpv3 && cpuinfo_isa.fma; #else return false; #endif } static inline bool cpuinfo_has_arm_vfpv4_d32(void) { #if CPUINFO_ARCH_ARM64 return true; #elif CPUINFO_ARCH_ARM return cpuinfo_isa.vfpv3 && cpuinfo_isa.fma && cpuinfo_isa.d32; #else return false; #endif } static inline bool cpuinfo_has_arm_fp16_arith(void) { #if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 return cpuinfo_isa.fp16arith; #else return false; #endif } static inline bool cpuinfo_has_arm_bf16(void) { #if CPUINFO_ARCH_ARM64 return cpuinfo_isa.bf16; #else return false; #endif } static inline bool cpuinfo_has_arm_wmmx(void) { #if CPUINFO_ARCH_ARM return cpuinfo_isa.wmmx; #else return false; #endif } static inline bool cpuinfo_has_arm_wmmx2(void) { #if CPUINFO_ARCH_ARM return cpuinfo_isa.wmmx2; #else return false; #endif } static inline bool cpuinfo_has_arm_neon(void) { #if CPUINFO_ARCH_ARM64 return true; #elif CPUINFO_ARCH_ARM return cpuinfo_isa.neon; #else return false; #endif } static inline bool cpuinfo_has_arm_neon_fp16(void) { #if CPUINFO_ARCH_ARM64 return true; #elif CPUINFO_ARCH_ARM return cpuinfo_isa.neon && cpuinfo_isa.fp16; #else return false; #endif } static inline bool cpuinfo_has_arm_neon_fma(void) { #if CPUINFO_ARCH_ARM64 return true; #elif CPUINFO_ARCH_ARM return cpuinfo_isa.neon && cpuinfo_isa.fma; #else return false; #endif } static inline bool cpuinfo_has_arm_neon_v8(void) { #if CPUINFO_ARCH_ARM64 return true; #elif CPUINFO_ARCH_ARM return cpuinfo_isa.neon && cpuinfo_isa.armv8; #else return false; #endif } static inline bool cpuinfo_has_arm_atomics(void) { #if CPUINFO_ARCH_ARM64 return cpuinfo_isa.atomics; #else return false; #endif } static inline bool cpuinfo_has_arm_neon_rdm(void) { #if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 return cpuinfo_isa.rdm; #else return false; #endif } static inline bool cpuinfo_has_arm_neon_fp16_arith(void) { #if CPUINFO_ARCH_ARM return cpuinfo_isa.neon && cpuinfo_isa.fp16arith; #elif CPUINFO_ARCH_ARM64 return cpuinfo_isa.fp16arith; #else return false; #endif } static inline bool cpuinfo_has_arm_fhm(void) { #if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 return cpuinfo_isa.fhm; #else return false; #endif } static inline bool cpuinfo_has_arm_neon_dot(void) { #if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 return cpuinfo_isa.dot; #else return false; #endif } static inline bool cpuinfo_has_arm_neon_bf16(void) { #if CPUINFO_ARCH_ARM64 return cpuinfo_isa.bf16; #else return false; #endif } static inline bool cpuinfo_has_arm_jscvt(void) { #if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 return cpuinfo_isa.jscvt; #else return false; #endif } static inline bool cpuinfo_has_arm_fcma(void) { #if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 return cpuinfo_isa.fcma; #else return false; #endif } static inline bool cpuinfo_has_arm_i8mm(void) { #if CPUINFO_ARCH_ARM64 return cpuinfo_isa.i8mm; #else return false; #endif } static inline bool cpuinfo_has_arm_aes(void) { #if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 return cpuinfo_isa.aes; #else return false; #endif } static inline bool cpuinfo_has_arm_sha1(void) { #if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 return cpuinfo_isa.sha1; #else return false; #endif } static inline bool cpuinfo_has_arm_sha2(void) { #if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 return cpuinfo_isa.sha2; #else return false; #endif } static inline bool cpuinfo_has_arm_pmull(void) { #if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 return cpuinfo_isa.pmull; #else return false; #endif } static inline bool cpuinfo_has_arm_crc32(void) { #if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 return cpuinfo_isa.crc32; #else return false; #endif } static inline bool cpuinfo_has_arm_sve(void) { #if CPUINFO_ARCH_ARM64 return cpuinfo_isa.sve; #else return false; #endif } static inline bool cpuinfo_has_arm_sve_bf16(void) { #if CPUINFO_ARCH_ARM64 return cpuinfo_isa.sve && cpuinfo_isa.bf16; #else return false; #endif } static inline bool cpuinfo_has_arm_sve2(void) { #if CPUINFO_ARCH_ARM64 return cpuinfo_isa.sve2; #else return false; #endif } const struct cpuinfo_processor* CPUINFO_ABI cpuinfo_get_processors(void); const struct cpuinfo_core* CPUINFO_ABI cpuinfo_get_cores(void); const struct cpuinfo_cluster* CPUINFO_ABI cpuinfo_get_clusters(void); const struct cpuinfo_package* CPUINFO_ABI cpuinfo_get_packages(void); const struct cpuinfo_uarch_info* CPUINFO_ABI cpuinfo_get_uarchs(void); const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l1i_caches(void); const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l1d_caches(void); const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l2_caches(void); const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l3_caches(void); const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l4_caches(void); const struct cpuinfo_processor* CPUINFO_ABI cpuinfo_get_processor(uint32_t index); const struct cpuinfo_core* CPUINFO_ABI cpuinfo_get_core(uint32_t index); const struct cpuinfo_cluster* CPUINFO_ABI cpuinfo_get_cluster(uint32_t index); const struct cpuinfo_package* CPUINFO_ABI cpuinfo_get_package(uint32_t index); const struct cpuinfo_uarch_info* CPUINFO_ABI cpuinfo_get_uarch(uint32_t index); const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l1i_cache(uint32_t index); const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l1d_cache(uint32_t index); const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l2_cache(uint32_t index); const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l3_cache(uint32_t index); const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l4_cache(uint32_t index); uint32_t CPUINFO_ABI cpuinfo_get_processors_count(void); uint32_t CPUINFO_ABI cpuinfo_get_cores_count(void); uint32_t CPUINFO_ABI cpuinfo_get_clusters_count(void); uint32_t CPUINFO_ABI cpuinfo_get_packages_count(void); uint32_t CPUINFO_ABI cpuinfo_get_uarchs_count(void); uint32_t CPUINFO_ABI cpuinfo_get_l1i_caches_count(void); uint32_t CPUINFO_ABI cpuinfo_get_l1d_caches_count(void); uint32_t CPUINFO_ABI cpuinfo_get_l2_caches_count(void); uint32_t CPUINFO_ABI cpuinfo_get_l3_caches_count(void); uint32_t CPUINFO_ABI cpuinfo_get_l4_caches_count(void); /** * Returns upper bound on cache size. */ uint32_t CPUINFO_ABI cpuinfo_get_max_cache_size(void); /** * Identify the logical processor that executes the current thread. * * There is no guarantee that the thread will stay on the same logical processor for any time. * Callers should treat the result as only a hint, and be prepared to handle NULL return value. */ const struct cpuinfo_processor* CPUINFO_ABI cpuinfo_get_current_processor(void); /** * Identify the core that executes the current thread. * * There is no guarantee that the thread will stay on the same core for any time. * Callers should treat the result as only a hint, and be prepared to handle NULL return value. */ const struct cpuinfo_core* CPUINFO_ABI cpuinfo_get_current_core(void); /** * Identify the microarchitecture index of the core that executes the current thread. * If the system does not support such identification, the function returns 0. * * There is no guarantee that the thread will stay on the same type of core for any time. * Callers should treat the result as only a hint. */ uint32_t CPUINFO_ABI cpuinfo_get_current_uarch_index(void); /** * Identify the microarchitecture index of the core that executes the current thread. * If the system does not support such identification, the function returns the user-specified default value. * * There is no guarantee that the thread will stay on the same type of core for any time. * Callers should treat the result as only a hint. */ uint32_t CPUINFO_ABI cpuinfo_get_current_uarch_index_with_default(uint32_t default_uarch_index); #ifdef __cplusplus } /* extern "C" */ #endif #endif /* CPUINFO_H */