Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-17 08:26:59

0001 #pragma once
0002 #ifndef CPUINFO_H
0003 #define CPUINFO_H
0004 
0005 #ifndef __cplusplus
0006 #include <stdbool.h>
0007 #endif
0008 
0009 #ifdef __APPLE__
0010 #include <TargetConditionals.h>
0011 #endif
0012 
0013 #include <stdint.h>
0014 
0015 /* Identify architecture and define corresponding macro */
0016 
0017 #if defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) || defined(_M_IX86)
0018 #define CPUINFO_ARCH_X86 1
0019 #endif
0020 
0021 #if defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64)
0022 #define CPUINFO_ARCH_X86_64 1
0023 #endif
0024 
0025 #if defined(__arm__) || defined(_M_ARM)
0026 #define CPUINFO_ARCH_ARM 1
0027 #endif
0028 
0029 #if defined(__aarch64__) || defined(_M_ARM64)
0030 #define CPUINFO_ARCH_ARM64 1
0031 #endif
0032 
0033 #if defined(__PPC64__) || defined(__powerpc64__) || defined(_ARCH_PPC64)
0034 #define CPUINFO_ARCH_PPC64 1
0035 #endif
0036 
0037 #if defined(__asmjs__)
0038 #define CPUINFO_ARCH_ASMJS 1
0039 #endif
0040 
0041 #if defined(__wasm__)
0042 #if defined(__wasm_simd128__)
0043 #define CPUINFO_ARCH_WASMSIMD 1
0044 #else
0045 #define CPUINFO_ARCH_WASM 1
0046 #endif
0047 #endif
0048 
0049 #if defined(__riscv)
0050 #if (__riscv_xlen == 32)
0051 #define CPUINFO_ARCH_RISCV32 1
0052 #elif (__riscv_xlen == 64)
0053 #define CPUINFO_ARCH_RISCV64 1
0054 #endif
0055 #endif
0056 
0057 /* Define other architecture-specific macros as 0 */
0058 
0059 #ifndef CPUINFO_ARCH_X86
0060 #define CPUINFO_ARCH_X86 0
0061 #endif
0062 
0063 #ifndef CPUINFO_ARCH_X86_64
0064 #define CPUINFO_ARCH_X86_64 0
0065 #endif
0066 
0067 #ifndef CPUINFO_ARCH_ARM
0068 #define CPUINFO_ARCH_ARM 0
0069 #endif
0070 
0071 #ifndef CPUINFO_ARCH_ARM64
0072 #define CPUINFO_ARCH_ARM64 0
0073 #endif
0074 
0075 #ifndef CPUINFO_ARCH_PPC64
0076 #define CPUINFO_ARCH_PPC64 0
0077 #endif
0078 
0079 #ifndef CPUINFO_ARCH_ASMJS
0080 #define CPUINFO_ARCH_ASMJS 0
0081 #endif
0082 
0083 #ifndef CPUINFO_ARCH_WASM
0084 #define CPUINFO_ARCH_WASM 0
0085 #endif
0086 
0087 #ifndef CPUINFO_ARCH_WASMSIMD
0088 #define CPUINFO_ARCH_WASMSIMD 0
0089 #endif
0090 
0091 #ifndef CPUINFO_ARCH_RISCV32
0092 #define CPUINFO_ARCH_RISCV32 0
0093 #endif
0094 
0095 #ifndef CPUINFO_ARCH_RISCV64
0096 #define CPUINFO_ARCH_RISCV64 0
0097 #endif
0098 
0099 #if CPUINFO_ARCH_X86 && defined(_MSC_VER)
0100 #define CPUINFO_ABI __cdecl
0101 #elif CPUINFO_ARCH_X86 && defined(__GNUC__)
0102 #define CPUINFO_ABI __attribute__((__cdecl__))
0103 #else
0104 #define CPUINFO_ABI
0105 #endif
0106 
0107 #define CPUINFO_CACHE_UNIFIED 0x00000001
0108 #define CPUINFO_CACHE_INCLUSIVE 0x00000002
0109 #define CPUINFO_CACHE_COMPLEX_INDEXING 0x00000004
0110 
0111 struct cpuinfo_cache {
0112     /** Cache size in bytes */
0113     uint32_t size;
0114     /** Number of ways of associativity */
0115     uint32_t associativity;
0116     /** Number of sets */
0117     uint32_t sets;
0118     /** Number of partitions */
0119     uint32_t partitions;
0120     /** Line size in bytes */
0121     uint32_t line_size;
0122     /**
0123      * Binary characteristics of the cache (unified cache, inclusive cache,
0124      * cache with complex indexing).
0125      *
0126      * @see CPUINFO_CACHE_UNIFIED, CPUINFO_CACHE_INCLUSIVE,
0127      * CPUINFO_CACHE_COMPLEX_INDEXING
0128      */
0129     uint32_t flags;
0130     /** Index of the first logical processor that shares this cache */
0131     uint32_t processor_start;
0132     /** Number of logical processors that share this cache */
0133     uint32_t processor_count;
0134 };
0135 
0136 struct cpuinfo_trace_cache {
0137     uint32_t uops;
0138     uint32_t associativity;
0139 };
0140 
0141 #define CPUINFO_PAGE_SIZE_4KB 0x1000
0142 #define CPUINFO_PAGE_SIZE_1MB 0x100000
0143 #define CPUINFO_PAGE_SIZE_2MB 0x200000
0144 #define CPUINFO_PAGE_SIZE_4MB 0x400000
0145 #define CPUINFO_PAGE_SIZE_16MB 0x1000000
0146 #define CPUINFO_PAGE_SIZE_1GB 0x40000000
0147 
0148 struct cpuinfo_tlb {
0149     uint32_t entries;
0150     uint32_t associativity;
0151     uint64_t pages;
0152 };
0153 
0154 /** Vendor of processor core design */
0155 enum cpuinfo_vendor {
0156     /** Processor vendor is not known to the library, or the library failed
0157        to get vendor information from the OS. */
0158     cpuinfo_vendor_unknown = 0,
0159 
0160     /* Active vendors of modern CPUs */
0161 
0162     /**
0163      * Intel Corporation. Vendor of x86, x86-64, IA64, and ARM processor
0164      * microarchitectures.
0165      *
0166      * Sold its ARM design subsidiary in 2006. The last ARM processor design
0167      * was released in 2004.
0168      */
0169     cpuinfo_vendor_intel = 1,
0170     /** Advanced Micro Devices, Inc. Vendor of x86 and x86-64 processor
0171        microarchitectures. */
0172     cpuinfo_vendor_amd = 2,
0173     /** ARM Holdings plc. Vendor of ARM and ARM64 processor
0174        microarchitectures. */
0175     cpuinfo_vendor_arm = 3,
0176     /** Qualcomm Incorporated. Vendor of ARM and ARM64 processor
0177        microarchitectures. */
0178     cpuinfo_vendor_qualcomm = 4,
0179     /** Apple Inc. Vendor of ARM and ARM64 processor microarchitectures. */
0180     cpuinfo_vendor_apple = 5,
0181     /** Samsung Electronics Co., Ltd. Vendir if ARM64 processor
0182        microarchitectures. */
0183     cpuinfo_vendor_samsung = 6,
0184     /** Nvidia Corporation. Vendor of ARM64-compatible processor
0185        microarchitectures. */
0186     cpuinfo_vendor_nvidia = 7,
0187     /** MIPS Technologies, Inc. Vendor of MIPS processor microarchitectures.
0188      */
0189     cpuinfo_vendor_mips = 8,
0190     /** International Business Machines Corporation. Vendor of PowerPC
0191        processor microarchitectures. */
0192     cpuinfo_vendor_ibm = 9,
0193     /** Ingenic Semiconductor. Vendor of MIPS processor microarchitectures.
0194      */
0195     cpuinfo_vendor_ingenic = 10,
0196     /**
0197      * VIA Technologies, Inc. Vendor of x86 and x86-64 processor
0198      * microarchitectures.
0199      *
0200      * Processors are designed by Centaur Technology, a subsidiary of VIA
0201      * Technologies.
0202      */
0203     cpuinfo_vendor_via = 11,
0204     /** Cavium, Inc. Vendor of ARM64 processor microarchitectures. */
0205     cpuinfo_vendor_cavium = 12,
0206     /** Broadcom, Inc. Vendor of ARM processor microarchitectures. */
0207     cpuinfo_vendor_broadcom = 13,
0208     /** Applied Micro Circuits Corporation (APM). Vendor of ARM64 processor
0209        microarchitectures. */
0210     cpuinfo_vendor_apm = 14,
0211     /**
0212      * Huawei Technologies Co., Ltd. Vendor of ARM64 processor
0213      * microarchitectures.
0214      *
0215      * Processors are designed by HiSilicon, a subsidiary of Huawei.
0216      */
0217     cpuinfo_vendor_huawei = 15,
0218     /**
0219      * Hygon (Chengdu Haiguang Integrated Circuit Design Co., Ltd), Vendor
0220      * of x86-64 processor microarchitectures.
0221      *
0222      * Processors are variants of AMD cores.
0223      */
0224     cpuinfo_vendor_hygon = 16,
0225     /** SiFive, Inc. Vendor of RISC-V processor microarchitectures. */
0226     cpuinfo_vendor_sifive = 17,
0227 
0228     /* Active vendors of embedded CPUs */
0229 
0230     /** Texas Instruments Inc. Vendor of ARM processor microarchitectures.
0231      */
0232     cpuinfo_vendor_texas_instruments = 30,
0233     /** Marvell Technology Group Ltd. Vendor of ARM processor
0234      * microarchitectures.
0235      */
0236     cpuinfo_vendor_marvell = 31,
0237     /** RDC Semiconductor Co., Ltd. Vendor of x86 processor
0238        microarchitectures. */
0239     cpuinfo_vendor_rdc = 32,
0240     /** DM&P Electronics Inc. Vendor of x86 processor microarchitectures. */
0241     cpuinfo_vendor_dmp = 33,
0242     /** Motorola, Inc. Vendor of PowerPC and ARM processor
0243        microarchitectures. */
0244     cpuinfo_vendor_motorola = 34,
0245 
0246     /* Defunct CPU vendors */
0247 
0248     /**
0249      * Transmeta Corporation. Vendor of x86 processor microarchitectures.
0250      *
0251      * Now defunct. The last processor design was released in 2004.
0252      * Transmeta processors implemented VLIW ISA and used binary translation
0253      * to execute x86 code.
0254      */
0255     cpuinfo_vendor_transmeta = 50,
0256     /**
0257      * Cyrix Corporation. Vendor of x86 processor microarchitectures.
0258      *
0259      * Now defunct. The last processor design was released in 1996.
0260      */
0261     cpuinfo_vendor_cyrix = 51,
0262     /**
0263      * Rise Technology. Vendor of x86 processor microarchitectures.
0264      *
0265      * Now defunct. The last processor design was released in 1999.
0266      */
0267     cpuinfo_vendor_rise = 52,
0268     /**
0269      * National Semiconductor. Vendor of x86 processor microarchitectures.
0270      *
0271      * Sold its x86 design subsidiary in 1999. The last processor design was
0272      * released in 1998.
0273      */
0274     cpuinfo_vendor_nsc = 53,
0275     /**
0276      * Silicon Integrated Systems. Vendor of x86 processor
0277      * microarchitectures.
0278      *
0279      * Sold its x86 design subsidiary in 2001. The last processor design was
0280      * released in 2001.
0281      */
0282     cpuinfo_vendor_sis = 54,
0283     /**
0284      * NexGen. Vendor of x86 processor microarchitectures.
0285      *
0286      * Now defunct. The last processor design was released in 1994.
0287      * NexGen designed the first x86 microarchitecture which decomposed x86
0288      * instructions into simple microoperations.
0289      */
0290     cpuinfo_vendor_nexgen = 55,
0291     /**
0292      * United Microelectronics Corporation. Vendor of x86 processor
0293      * microarchitectures.
0294      *
0295      * Ceased x86 in the early 1990s. The last processor design was released
0296      * in 1991. Designed U5C and U5D processors. Both are 486 level.
0297      */
0298     cpuinfo_vendor_umc = 56,
0299     /**
0300      * Digital Equipment Corporation. Vendor of ARM processor
0301      * microarchitecture.
0302      *
0303      * Sold its ARM designs in 1997. The last processor design was released
0304      * in 1997.
0305      */
0306     cpuinfo_vendor_dec = 57,
0307 };
0308 
0309 /**
0310  * Processor microarchitecture
0311  *
0312  * Processors with different microarchitectures often have different instruction
0313  * performance characteristics, and may have dramatically different pipeline
0314  * organization.
0315  */
0316 enum cpuinfo_uarch {
0317     /** Microarchitecture is unknown, or the library failed to get
0318        information about the microarchitecture from OS */
0319     cpuinfo_uarch_unknown = 0,
0320 
0321     /** Pentium and Pentium MMX microarchitecture. */
0322     cpuinfo_uarch_p5 = 0x00100100,
0323     /** Intel Quark microarchitecture. */
0324     cpuinfo_uarch_quark = 0x00100101,
0325 
0326     /** Pentium Pro, Pentium II, and Pentium III. */
0327     cpuinfo_uarch_p6 = 0x00100200,
0328     /** Pentium M. */
0329     cpuinfo_uarch_dothan = 0x00100201,
0330     /** Intel Core microarchitecture. */
0331     cpuinfo_uarch_yonah = 0x00100202,
0332     /** Intel Core 2 microarchitecture on 65 nm process. */
0333     cpuinfo_uarch_conroe = 0x00100203,
0334     /** Intel Core 2 microarchitecture on 45 nm process. */
0335     cpuinfo_uarch_penryn = 0x00100204,
0336     /** Intel Nehalem and Westmere microarchitectures (Core i3/i5/i7 1st
0337        gen). */
0338     cpuinfo_uarch_nehalem = 0x00100205,
0339     /** Intel Sandy Bridge microarchitecture (Core i3/i5/i7 2nd gen). */
0340     cpuinfo_uarch_sandy_bridge = 0x00100206,
0341     /** Intel Ivy Bridge microarchitecture (Core i3/i5/i7 3rd gen). */
0342     cpuinfo_uarch_ivy_bridge = 0x00100207,
0343     /** Intel Haswell microarchitecture (Core i3/i5/i7 4th gen). */
0344     cpuinfo_uarch_haswell = 0x00100208,
0345     /** Intel Broadwell microarchitecture. */
0346     cpuinfo_uarch_broadwell = 0x00100209,
0347     /** Intel Sky Lake microarchitecture (14 nm, including
0348        Kaby/Coffee/Whiskey/Amber/Comet/Cascade/Cooper Lake). */
0349     cpuinfo_uarch_sky_lake = 0x0010020A,
0350     /** DEPRECATED (Intel Kaby Lake microarchitecture). */
0351     cpuinfo_uarch_kaby_lake = 0x0010020A,
0352     /** Intel Palm Cove microarchitecture (10 nm, Cannon Lake). */
0353     cpuinfo_uarch_palm_cove = 0x0010020B,
0354     /** Intel Sunny Cove microarchitecture (10 nm, Ice Lake). */
0355     cpuinfo_uarch_sunny_cove = 0x0010020C,
0356     /** Intel Willow Cove microarchitecture (10 nm, Tiger Lake). */
0357     cpuinfo_uarch_willow_cove = 0x0010020D,
0358 
0359     /** Pentium 4 with Willamette, Northwood, or Foster cores. */
0360     cpuinfo_uarch_willamette = 0x00100300,
0361     /** Pentium 4 with Prescott and later cores. */
0362     cpuinfo_uarch_prescott = 0x00100301,
0363 
0364     /** Intel Atom on 45 nm process. */
0365     cpuinfo_uarch_bonnell = 0x00100400,
0366     /** Intel Atom on 32 nm process. */
0367     cpuinfo_uarch_saltwell = 0x00100401,
0368     /** Intel Silvermont microarchitecture (22 nm out-of-order Atom). */
0369     cpuinfo_uarch_silvermont = 0x00100402,
0370     /** Intel Airmont microarchitecture (14 nm out-of-order Atom). */
0371     cpuinfo_uarch_airmont = 0x00100403,
0372     /** Intel Goldmont microarchitecture (Denverton, Apollo Lake). */
0373     cpuinfo_uarch_goldmont = 0x00100404,
0374     /** Intel Goldmont Plus microarchitecture (Gemini Lake). */
0375     cpuinfo_uarch_goldmont_plus = 0x00100405,
0376     /** Intel Airmont microarchitecture (10 nm out-of-order Atom). */
0377     cpuinfo_uarch_tremont = 0x00100406,
0378     /** Intel Gracemont microarchitecture (AlderLake N). */
0379     cpuinfo_uarch_gracemont = 0x00100407,
0380     /** Intel Crestmont microarchitecture (Sierra Forest). */
0381     cpuinfo_uarch_crestmont = 0x00100408,
0382     /** Intel Darkmont microarchitecture (e-core used in Clearwater Forest). */
0383     cpuinfo_uarch_darkmont = 0x00100409,
0384 
0385     /** Intel Knights Ferry HPC boards. */
0386     cpuinfo_uarch_knights_ferry = 0x00100500,
0387     /** Intel Knights Corner HPC boards (aka Xeon Phi). */
0388     cpuinfo_uarch_knights_corner = 0x00100501,
0389     /** Intel Knights Landing microarchitecture (second-gen MIC). */
0390     cpuinfo_uarch_knights_landing = 0x00100502,
0391     /** Intel Knights Hill microarchitecture (third-gen MIC). */
0392     cpuinfo_uarch_knights_hill = 0x00100503,
0393     /** Intel Knights Mill Xeon Phi. */
0394     cpuinfo_uarch_knights_mill = 0x00100504,
0395 
0396     /** Intel/Marvell XScale series. */
0397     cpuinfo_uarch_xscale = 0x00100600,
0398 
0399     /** AMD K5. */
0400     cpuinfo_uarch_k5 = 0x00200100,
0401     /** AMD K6 and alike. */
0402     cpuinfo_uarch_k6 = 0x00200101,
0403     /** AMD Athlon and Duron. */
0404     cpuinfo_uarch_k7 = 0x00200102,
0405     /** AMD Athlon 64, Opteron 64. */
0406     cpuinfo_uarch_k8 = 0x00200103,
0407     /** AMD Family 10h (Barcelona, Istambul, Magny-Cours). */
0408     cpuinfo_uarch_k10 = 0x00200104,
0409     /**
0410      * AMD Bulldozer microarchitecture
0411      * Zambezi FX-series CPUs, Zurich, Valencia and Interlagos Opteron CPUs.
0412      */
0413     cpuinfo_uarch_bulldozer = 0x00200105,
0414     /**
0415      * AMD Piledriver microarchitecture
0416      * Vishera FX-series CPUs, Trinity and Richland APUs, Delhi, Seoul, Abu
0417      * Dhabi Opteron CPUs.
0418      */
0419     cpuinfo_uarch_piledriver = 0x00200106,
0420     /** AMD Steamroller microarchitecture (Kaveri APUs). */
0421     cpuinfo_uarch_steamroller = 0x00200107,
0422     /** AMD Excavator microarchitecture (Carizzo APUs). */
0423     cpuinfo_uarch_excavator = 0x00200108,
0424     /** AMD Zen microarchitecture (12/14 nm Ryzen and EPYC CPUs). */
0425     cpuinfo_uarch_zen = 0x00200109,
0426     /** AMD Zen 2 microarchitecture (7 nm Ryzen and EPYC CPUs). */
0427     cpuinfo_uarch_zen2 = 0x0020010A,
0428     /** AMD Zen 3 microarchitecture. */
0429     cpuinfo_uarch_zen3 = 0x0020010B,
0430     /** AMD Zen 4 microarchitecture. */
0431     cpuinfo_uarch_zen4 = 0x0020010C,
0432     /** AMD Zen 5 microarchitecture. */
0433     cpuinfo_uarch_zen5 = 0x0020010D,
0434 
0435     /** NSC Geode and AMD Geode GX and LX. */
0436     cpuinfo_uarch_geode = 0x00200200,
0437     /** AMD Bobcat mobile microarchitecture. */
0438     cpuinfo_uarch_bobcat = 0x00200201,
0439     /** AMD Jaguar mobile microarchitecture. */
0440     cpuinfo_uarch_jaguar = 0x00200202,
0441     /** AMD Puma mobile microarchitecture. */
0442     cpuinfo_uarch_puma = 0x00200203,
0443 
0444     /** ARM7 series. */
0445     cpuinfo_uarch_arm7 = 0x00300100,
0446     /** ARM9 series. */
0447     cpuinfo_uarch_arm9 = 0x00300101,
0448     /** ARM 1136, ARM 1156, ARM 1176, or ARM 11MPCore. */
0449     cpuinfo_uarch_arm11 = 0x00300102,
0450 
0451     /** ARM Cortex-A5. */
0452     cpuinfo_uarch_cortex_a5 = 0x00300205,
0453     /** ARM Cortex-A7. */
0454     cpuinfo_uarch_cortex_a7 = 0x00300207,
0455     /** ARM Cortex-A8. */
0456     cpuinfo_uarch_cortex_a8 = 0x00300208,
0457     /** ARM Cortex-A9. */
0458     cpuinfo_uarch_cortex_a9 = 0x00300209,
0459     /** ARM Cortex-A12. */
0460     cpuinfo_uarch_cortex_a12 = 0x00300212,
0461     /** ARM Cortex-A15. */
0462     cpuinfo_uarch_cortex_a15 = 0x00300215,
0463     /** ARM Cortex-A17. */
0464     cpuinfo_uarch_cortex_a17 = 0x00300217,
0465 
0466     /** ARM Cortex-A32. */
0467     cpuinfo_uarch_cortex_a32 = 0x00300332,
0468     /** ARM Cortex-A35. */
0469     cpuinfo_uarch_cortex_a35 = 0x00300335,
0470     /** ARM Cortex-A53. */
0471     cpuinfo_uarch_cortex_a53 = 0x00300353,
0472     /** ARM Cortex-A55 revision 0 (restricted dual-issue capabilities
0473        compared to revision 1+). */
0474     cpuinfo_uarch_cortex_a55r0 = 0x00300354,
0475     /** ARM Cortex-A55. */
0476     cpuinfo_uarch_cortex_a55 = 0x00300355,
0477     /** ARM Cortex-A57. */
0478     cpuinfo_uarch_cortex_a57 = 0x00300357,
0479     /** ARM Cortex-A65. */
0480     cpuinfo_uarch_cortex_a65 = 0x00300365,
0481     /** ARM Cortex-A72. */
0482     cpuinfo_uarch_cortex_a72 = 0x00300372,
0483     /** ARM Cortex-A73. */
0484     cpuinfo_uarch_cortex_a73 = 0x00300373,
0485     /** ARM Cortex-A75. */
0486     cpuinfo_uarch_cortex_a75 = 0x00300375,
0487     /** ARM Cortex-A76. */
0488     cpuinfo_uarch_cortex_a76 = 0x00300376,
0489     /** ARM Cortex-A77. */
0490     cpuinfo_uarch_cortex_a77 = 0x00300377,
0491     /** ARM Cortex-A78. */
0492     cpuinfo_uarch_cortex_a78 = 0x00300378,
0493 
0494     /** ARM Neoverse N1. */
0495     cpuinfo_uarch_neoverse_n1 = 0x00300400,
0496     /** ARM Neoverse E1. */
0497     cpuinfo_uarch_neoverse_e1 = 0x00300401,
0498     /** ARM Neoverse V1. */
0499     cpuinfo_uarch_neoverse_v1 = 0x00300402,
0500     /** ARM Neoverse N2. */
0501     cpuinfo_uarch_neoverse_n2 = 0x00300403,
0502     /** ARM Neoverse V2. */
0503     cpuinfo_uarch_neoverse_v2 = 0x00300404,
0504 
0505     /** ARM Cortex-X1. */
0506     cpuinfo_uarch_cortex_x1 = 0x00300501,
0507     /** ARM Cortex-X2. */
0508     cpuinfo_uarch_cortex_x2 = 0x00300502,
0509     /** ARM Cortex-X3. */
0510     cpuinfo_uarch_cortex_x3 = 0x00300503,
0511     /** ARM Cortex-X4. */
0512     cpuinfo_uarch_cortex_x4 = 0x00300504,
0513     /** ARM Cortex-X925. */
0514     cpuinfo_uarch_cortex_x925 = 0x00300505,
0515 
0516     /** ARM Cortex-A510. */
0517     cpuinfo_uarch_cortex_a510 = 0x00300551,
0518     /** ARM Cortex-A520. */
0519     cpuinfo_uarch_cortex_a520 = 0x00300552,
0520     /** ARM Cortex-A710. */
0521     cpuinfo_uarch_cortex_a710 = 0x00300571,
0522     /** ARM Cortex-A715. */
0523     cpuinfo_uarch_cortex_a715 = 0x00300572,
0524     /** ARM Cortex-A720. */
0525     cpuinfo_uarch_cortex_a720 = 0x00300573,
0526     /** ARM Cortex-A725. */
0527     cpuinfo_uarch_cortex_a725 = 0x00300574,
0528 
0529     /** Qualcomm Scorpion. */
0530     cpuinfo_uarch_scorpion = 0x00400100,
0531     /** Qualcomm Krait. */
0532     cpuinfo_uarch_krait = 0x00400101,
0533     /** Qualcomm Kryo. */
0534     cpuinfo_uarch_kryo = 0x00400102,
0535     /** Qualcomm Falkor. */
0536     cpuinfo_uarch_falkor = 0x00400103,
0537     /** Qualcomm Saphira. */
0538     cpuinfo_uarch_saphira = 0x00400104,
0539     /** Qualcomm Oryon. */
0540     cpuinfo_uarch_oryon = 0x00400105,
0541 
0542     /** Nvidia Denver. */
0543     cpuinfo_uarch_denver = 0x00500100,
0544     /** Nvidia Denver 2. */
0545     cpuinfo_uarch_denver2 = 0x00500101,
0546     /** Nvidia Carmel. */
0547     cpuinfo_uarch_carmel = 0x00500102,
0548 
0549     /** Samsung Exynos M1 (Exynos 8890 big cores). */
0550     cpuinfo_uarch_exynos_m1 = 0x00600100,
0551     /** Samsung Exynos M2 (Exynos 8895 big cores). */
0552     cpuinfo_uarch_exynos_m2 = 0x00600101,
0553     /** Samsung Exynos M3 (Exynos 9810 big cores). */
0554     cpuinfo_uarch_exynos_m3 = 0x00600102,
0555     /** Samsung Exynos M4 (Exynos 9820 big cores). */
0556     cpuinfo_uarch_exynos_m4 = 0x00600103,
0557     /** Samsung Exynos M5 (Exynos 9830 big cores). */
0558     cpuinfo_uarch_exynos_m5 = 0x00600104,
0559 
0560     /* Deprecated synonym for Cortex-A76 */
0561     cpuinfo_uarch_cortex_a76ae = 0x00300376,
0562     /* Deprecated names for Exynos. */
0563     cpuinfo_uarch_mongoose_m1 = 0x00600100,
0564     cpuinfo_uarch_mongoose_m2 = 0x00600101,
0565     cpuinfo_uarch_meerkat_m3 = 0x00600102,
0566     cpuinfo_uarch_meerkat_m4 = 0x00600103,
0567 
0568     /** Apple A6 and A6X processors. */
0569     cpuinfo_uarch_swift = 0x00700100,
0570     /** Apple A7 processor. */
0571     cpuinfo_uarch_cyclone = 0x00700101,
0572     /** Apple A8 and A8X processor. */
0573     cpuinfo_uarch_typhoon = 0x00700102,
0574     /** Apple A9 and A9X processor. */
0575     cpuinfo_uarch_twister = 0x00700103,
0576     /** Apple A10 and A10X processor. */
0577     cpuinfo_uarch_hurricane = 0x00700104,
0578     /** Apple A11 processor (big cores). */
0579     cpuinfo_uarch_monsoon = 0x00700105,
0580     /** Apple A11 processor (little cores). */
0581     cpuinfo_uarch_mistral = 0x00700106,
0582     /** Apple A12 processor (big cores). */
0583     cpuinfo_uarch_vortex = 0x00700107,
0584     /** Apple A12 processor (little cores). */
0585     cpuinfo_uarch_tempest = 0x00700108,
0586     /** Apple A13 processor (big cores). */
0587     cpuinfo_uarch_lightning = 0x00700109,
0588     /** Apple A13 processor (little cores). */
0589     cpuinfo_uarch_thunder = 0x0070010A,
0590     /** Apple A14 / M1 processor (big cores). */
0591     cpuinfo_uarch_firestorm = 0x0070010B,
0592     /** Apple A14 / M1 processor (little cores). */
0593     cpuinfo_uarch_icestorm = 0x0070010C,
0594     /** Apple A15 / M2 processor (big cores). */
0595     cpuinfo_uarch_avalanche = 0x0070010D,
0596     /** Apple A15 / M2 processor (little cores). */
0597     cpuinfo_uarch_blizzard = 0x0070010E,
0598     /** Apple A16 processor (big cores). */
0599     cpuinfo_uarch_everest = 0x00700200,
0600     /** Apple A16 processor (little cores). */
0601     cpuinfo_uarch_sawtooth = 0x00700201,
0602     /** Apple A17 processor (big cores). */
0603     cpuinfo_uarch_coll_everest = 0x00700202,
0604     /** Apple A17 processor (little cores). */
0605     cpuinfo_uarch_coll_sawtooth = 0x00700203,
0606     /** Apple A18 processor (big cores). */
0607     cpuinfo_uarch_tupai_everest = 0x00700204,
0608     /** Apple A18 processor (little cores). */
0609     cpuinfo_uarch_tupai_sawtooth = 0x00700205,
0610     /** Apple A18 pro processor (big cores). */
0611     cpuinfo_uarch_tahiti_everest = 0x00700206,
0612     /** Apple A18 pro processor (little cores). */
0613     cpuinfo_uarch_tahiti_sawtooth = 0x00700207,
0614 
0615     /** Cavium ThunderX. */
0616     cpuinfo_uarch_thunderx = 0x00800100,
0617     /** Cavium ThunderX2 (originally Broadcom Vulkan). */
0618     cpuinfo_uarch_thunderx2 = 0x00800200,
0619 
0620     /** Marvell PJ4. */
0621     cpuinfo_uarch_pj4 = 0x00900100,
0622 
0623     /** Broadcom Brahma B15. */
0624     cpuinfo_uarch_brahma_b15 = 0x00A00100,
0625     /** Broadcom Brahma B53. */
0626     cpuinfo_uarch_brahma_b53 = 0x00A00101,
0627 
0628     /** Applied Micro X-Gene. */
0629     cpuinfo_uarch_xgene = 0x00B00100,
0630 
0631     /* Hygon Dhyana (a modification of AMD Zen for Chinese market). */
0632     cpuinfo_uarch_dhyana = 0x01000100,
0633 
0634     /** HiSilicon TaiShan v110 (Huawei Kunpeng 920 series processors). */
0635     cpuinfo_uarch_taishan_v110 = 0x00C00100,
0636 };
0637 
0638 struct cpuinfo_processor {
0639     /** SMT (hyperthread) ID within a core */
0640     uint32_t smt_id;
0641     /** Core containing this logical processor */
0642     const struct cpuinfo_core* core;
0643     /** Cluster of cores containing this logical processor */
0644     const struct cpuinfo_cluster* cluster;
0645     /** Physical package containing this logical processor */
0646     const struct cpuinfo_package* package;
0647 #if defined(__linux__)
0648     /**
0649      * Linux-specific ID for the logical processor:
0650      * - Linux kernel exposes information about this logical processor in
0651      * /sys/devices/system/cpu/cpu<linux_id>/
0652      * - Bit <linux_id> in the cpu_set_t identifies this logical processor
0653      */
0654     int linux_id;
0655 #endif
0656 #if defined(_WIN32) || defined(__CYGWIN__)
0657     /** Windows-specific ID for the group containing the logical processor.
0658      */
0659     uint16_t windows_group_id;
0660     /**
0661      * Windows-specific ID of the logical processor within its group:
0662      * - Bit <windows_processor_id> in the KAFFINITY mask identifies this
0663      * logical processor within its group.
0664      */
0665     uint16_t windows_processor_id;
0666 #endif
0667 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
0668     /** APIC ID (unique x86-specific ID of the logical processor) */
0669     uint32_t apic_id;
0670 #endif
0671     struct {
0672         /** Level 1 instruction cache */
0673         const struct cpuinfo_cache* l1i;
0674         /** Level 1 data cache */
0675         const struct cpuinfo_cache* l1d;
0676         /** Level 2 unified or data cache */
0677         const struct cpuinfo_cache* l2;
0678         /** Level 3 unified or data cache */
0679         const struct cpuinfo_cache* l3;
0680         /** Level 4 unified or data cache */
0681         const struct cpuinfo_cache* l4;
0682     } cache;
0683 };
0684 
0685 struct cpuinfo_core {
0686     /** Index of the first logical processor on this core. */
0687     uint32_t processor_start;
0688     /** Number of logical processors on this core */
0689     uint32_t processor_count;
0690     /** Core ID within a package */
0691     uint32_t core_id;
0692     /** Cluster containing this core */
0693     const struct cpuinfo_cluster* cluster;
0694     /** Physical package containing this core. */
0695     const struct cpuinfo_package* package;
0696     /** Vendor of the CPU microarchitecture for this core */
0697     enum cpuinfo_vendor vendor;
0698     /** CPU microarchitecture for this core */
0699     enum cpuinfo_uarch uarch;
0700 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
0701     /** Value of CPUID leaf 1 EAX register for this core */
0702     uint32_t cpuid;
0703 #elif CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
0704     /** Value of Main ID Register (MIDR) for this core */
0705     uint32_t midr;
0706 #endif
0707     /** Clock rate (non-Turbo) of the core, in Hz */
0708     uint64_t frequency;
0709 };
0710 
0711 struct cpuinfo_cluster {
0712     /** Index of the first logical processor in the cluster */
0713     uint32_t processor_start;
0714     /** Number of logical processors in the cluster */
0715     uint32_t processor_count;
0716     /** Index of the first core in the cluster */
0717     uint32_t core_start;
0718     /** Number of cores on the cluster */
0719     uint32_t core_count;
0720     /** Cluster ID within a package */
0721     uint32_t cluster_id;
0722     /** Physical package containing the cluster */
0723     const struct cpuinfo_package* package;
0724     /** CPU microarchitecture vendor of the cores in the cluster */
0725     enum cpuinfo_vendor vendor;
0726     /** CPU microarchitecture of the cores in the cluster */
0727     enum cpuinfo_uarch uarch;
0728 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
0729     /** Value of CPUID leaf 1 EAX register of the cores in the cluster */
0730     uint32_t cpuid;
0731 #elif CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
0732     /** Value of Main ID Register (MIDR) of the cores in the cluster */
0733     uint32_t midr;
0734 #endif
0735     /** Clock rate (non-Turbo) of the cores in the cluster, in Hz */
0736     uint64_t frequency;
0737 };
0738 
0739 #define CPUINFO_PACKAGE_NAME_MAX 64
0740 
0741 struct cpuinfo_package {
0742     /** SoC or processor chip model name */
0743     char name[CPUINFO_PACKAGE_NAME_MAX];
0744     /** Index of the first logical processor on this physical package */
0745     uint32_t processor_start;
0746     /** Number of logical processors on this physical package */
0747     uint32_t processor_count;
0748     /** Index of the first core on this physical package */
0749     uint32_t core_start;
0750     /** Number of cores on this physical package */
0751     uint32_t core_count;
0752     /** Index of the first cluster of cores on this physical package */
0753     uint32_t cluster_start;
0754     /** Number of clusters of cores on this physical package */
0755     uint32_t cluster_count;
0756 };
0757 
0758 struct cpuinfo_uarch_info {
0759     /** Type of CPU microarchitecture */
0760     enum cpuinfo_uarch uarch;
0761 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
0762     /** Value of CPUID leaf 1 EAX register for the microarchitecture */
0763     uint32_t cpuid;
0764 #elif CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
0765     /** Value of Main ID Register (MIDR) for the microarchitecture */
0766     uint32_t midr;
0767 #endif
0768     /** Number of logical processors with the microarchitecture */
0769     uint32_t processor_count;
0770     /** Number of cores with the microarchitecture */
0771     uint32_t core_count;
0772 };
0773 
0774 #ifdef __cplusplus
0775 extern "C" {
0776 #endif
0777 
0778 bool CPUINFO_ABI cpuinfo_initialize(void);
0779 
0780 void CPUINFO_ABI cpuinfo_deinitialize(void);
0781 
0782 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
0783 /* This structure is not a part of stable API. Use cpuinfo_has_x86_* functions
0784  * instead. */
0785 struct cpuinfo_x86_isa {
0786 #if CPUINFO_ARCH_X86
0787     bool rdtsc;
0788 #endif
0789     bool rdtscp;
0790     bool rdpid;
0791     bool sysenter;
0792 #if CPUINFO_ARCH_X86
0793     bool syscall;
0794 #endif
0795     bool msr;
0796     bool clzero;
0797     bool clflush;
0798     bool clflushopt;
0799     bool mwait;
0800     bool mwaitx;
0801 #if CPUINFO_ARCH_X86
0802     bool emmx;
0803 #endif
0804     bool fxsave;
0805     bool xsave;
0806 #if CPUINFO_ARCH_X86
0807     bool fpu;
0808     bool mmx;
0809     bool mmx_plus;
0810 #endif
0811     bool three_d_now;
0812     bool three_d_now_plus;
0813 #if CPUINFO_ARCH_X86
0814     bool three_d_now_geode;
0815 #endif
0816     bool prefetch;
0817     bool prefetchw;
0818     bool prefetchwt1;
0819 #if CPUINFO_ARCH_X86
0820     bool daz;
0821     bool sse;
0822     bool sse2;
0823 #endif
0824     bool sse3;
0825     bool ssse3;
0826     bool sse4_1;
0827     bool sse4_2;
0828     bool sse4a;
0829     bool misaligned_sse;
0830     bool avx;
0831     bool avxvnni;
0832     bool fma3;
0833     bool fma4;
0834     bool xop;
0835     bool f16c;
0836     bool avx2;
0837     bool avx512f;
0838     bool avx512pf;
0839     bool avx512er;
0840     bool avx512cd;
0841     bool avx512dq;
0842     bool avx512bw;
0843     bool avx512vl;
0844     bool avx512ifma;
0845     bool avx512vbmi;
0846     bool avx512vbmi2;
0847     bool avx512bitalg;
0848     bool avx512vpopcntdq;
0849     bool avx512vnni;
0850     bool avx512bf16;
0851     bool avx512fp16;
0852     bool avx512vp2intersect;
0853     bool avx512_4vnniw;
0854     bool avx512_4fmaps;
0855     bool avx10_1;
0856     bool avx10_2;
0857     bool amx_bf16;
0858     bool amx_tile;
0859     bool amx_int8;
0860     bool amx_fp16;
0861     bool avx_vnni_int8;
0862     bool avx_vnni_int16;
0863     bool avx_ne_convert;
0864     bool hle;
0865     bool rtm;
0866     bool xtest;
0867     bool mpx;
0868 #if CPUINFO_ARCH_X86
0869     bool cmov;
0870     bool cmpxchg8b;
0871 #endif
0872     bool cmpxchg16b;
0873     bool clwb;
0874     bool movbe;
0875 #if CPUINFO_ARCH_X86_64
0876     bool lahf_sahf;
0877 #endif
0878     bool fs_gs_base;
0879     bool lzcnt;
0880     bool popcnt;
0881     bool tbm;
0882     bool bmi;
0883     bool bmi2;
0884     bool adx;
0885     bool aes;
0886     bool vaes;
0887     bool pclmulqdq;
0888     bool vpclmulqdq;
0889     bool gfni;
0890     bool rdrand;
0891     bool rdseed;
0892     bool sha;
0893     bool rng;
0894     bool ace;
0895     bool ace2;
0896     bool phe;
0897     bool pmm;
0898     bool lwp;
0899 };
0900 
0901 extern struct cpuinfo_x86_isa cpuinfo_isa;
0902 #endif
0903 
0904 static inline bool cpuinfo_has_x86_rdtsc(void) {
0905 #if CPUINFO_ARCH_X86_64
0906     return true;
0907 #elif CPUINFO_ARCH_X86
0908 #if defined(__ANDROID__)
0909     return true;
0910 #else
0911     return cpuinfo_isa.rdtsc;
0912 #endif
0913 #else
0914     return false;
0915 #endif
0916 }
0917 
0918 static inline bool cpuinfo_has_x86_rdtscp(void) {
0919 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
0920     return cpuinfo_isa.rdtscp;
0921 #else
0922     return false;
0923 #endif
0924 }
0925 
0926 static inline bool cpuinfo_has_x86_rdpid(void) {
0927 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
0928     return cpuinfo_isa.rdpid;
0929 #else
0930     return false;
0931 #endif
0932 }
0933 
0934 static inline bool cpuinfo_has_x86_clzero(void) {
0935 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
0936     return cpuinfo_isa.clzero;
0937 #else
0938     return false;
0939 #endif
0940 }
0941 
0942 static inline bool cpuinfo_has_x86_mwait(void) {
0943 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
0944     return cpuinfo_isa.mwait;
0945 #else
0946     return false;
0947 #endif
0948 }
0949 
0950 static inline bool cpuinfo_has_x86_mwaitx(void) {
0951 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
0952     return cpuinfo_isa.mwaitx;
0953 #else
0954     return false;
0955 #endif
0956 }
0957 
0958 static inline bool cpuinfo_has_x86_fxsave(void) {
0959 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
0960     return cpuinfo_isa.fxsave;
0961 #else
0962     return false;
0963 #endif
0964 }
0965 
0966 static inline bool cpuinfo_has_x86_xsave(void) {
0967 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
0968     return cpuinfo_isa.xsave;
0969 #else
0970     return false;
0971 #endif
0972 }
0973 
0974 static inline bool cpuinfo_has_x86_fpu(void) {
0975 #if CPUINFO_ARCH_X86_64
0976     return true;
0977 #elif CPUINFO_ARCH_X86
0978 #if defined(__ANDROID__)
0979     return true;
0980 #else
0981     return cpuinfo_isa.fpu;
0982 #endif
0983 #else
0984     return false;
0985 #endif
0986 }
0987 
0988 static inline bool cpuinfo_has_x86_mmx(void) {
0989 #if CPUINFO_ARCH_X86_64
0990     return true;
0991 #elif CPUINFO_ARCH_X86
0992 #if defined(__ANDROID__)
0993     return true;
0994 #else
0995     return cpuinfo_isa.mmx;
0996 #endif
0997 #else
0998     return false;
0999 #endif
1000 }
1001 
1002 static inline bool cpuinfo_has_x86_mmx_plus(void) {
1003 #if CPUINFO_ARCH_X86_64
1004     return true;
1005 #elif CPUINFO_ARCH_X86
1006 #if defined(__ANDROID__)
1007     return true;
1008 #else
1009     return cpuinfo_isa.mmx_plus;
1010 #endif
1011 #else
1012     return false;
1013 #endif
1014 }
1015 
1016 static inline bool cpuinfo_has_x86_3dnow(void) {
1017 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1018     return cpuinfo_isa.three_d_now;
1019 #else
1020     return false;
1021 #endif
1022 }
1023 
1024 static inline bool cpuinfo_has_x86_3dnow_plus(void) {
1025 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1026     return cpuinfo_isa.three_d_now_plus;
1027 #else
1028     return false;
1029 #endif
1030 }
1031 
1032 static inline bool cpuinfo_has_x86_3dnow_geode(void) {
1033 #if CPUINFO_ARCH_X86_64
1034     return false;
1035 #elif CPUINFO_ARCH_X86
1036 #if defined(__ANDROID__)
1037     return false;
1038 #else
1039     return cpuinfo_isa.three_d_now_geode;
1040 #endif
1041 #else
1042     return false;
1043 #endif
1044 }
1045 
1046 static inline bool cpuinfo_has_x86_prefetch(void) {
1047 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1048     return cpuinfo_isa.prefetch;
1049 #else
1050     return false;
1051 #endif
1052 }
1053 
1054 static inline bool cpuinfo_has_x86_prefetchw(void) {
1055 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1056     return cpuinfo_isa.prefetchw;
1057 #else
1058     return false;
1059 #endif
1060 }
1061 
1062 static inline bool cpuinfo_has_x86_prefetchwt1(void) {
1063 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1064     return cpuinfo_isa.prefetchwt1;
1065 #else
1066     return false;
1067 #endif
1068 }
1069 
1070 static inline bool cpuinfo_has_x86_daz(void) {
1071 #if CPUINFO_ARCH_X86_64
1072     return true;
1073 #elif CPUINFO_ARCH_X86
1074 #if defined(__ANDROID__)
1075     return true;
1076 #else
1077     return cpuinfo_isa.daz;
1078 #endif
1079 #else
1080     return false;
1081 #endif
1082 }
1083 
1084 static inline bool cpuinfo_has_x86_sse(void) {
1085 #if CPUINFO_ARCH_X86_64
1086     return true;
1087 #elif CPUINFO_ARCH_X86
1088 #if defined(__ANDROID__)
1089     return true;
1090 #else
1091     return cpuinfo_isa.sse;
1092 #endif
1093 #else
1094     return false;
1095 #endif
1096 }
1097 
1098 static inline bool cpuinfo_has_x86_sse2(void) {
1099 #if CPUINFO_ARCH_X86_64
1100     return true;
1101 #elif CPUINFO_ARCH_X86
1102 #if defined(__ANDROID__)
1103     return true;
1104 #else
1105     return cpuinfo_isa.sse2;
1106 #endif
1107 #else
1108     return false;
1109 #endif
1110 }
1111 
1112 static inline bool cpuinfo_has_x86_sse3(void) {
1113 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1114 #if defined(__ANDROID__)
1115     return true;
1116 #else
1117     return cpuinfo_isa.sse3;
1118 #endif
1119 #else
1120     return false;
1121 #endif
1122 }
1123 
1124 static inline bool cpuinfo_has_x86_ssse3(void) {
1125 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1126 #if defined(__ANDROID__)
1127     return true;
1128 #else
1129     return cpuinfo_isa.ssse3;
1130 #endif
1131 #else
1132     return false;
1133 #endif
1134 }
1135 
1136 static inline bool cpuinfo_has_x86_sse4_1(void) {
1137 #if CPUINFO_ARCH_X86_64
1138 #if defined(__ANDROID__)
1139     return true;
1140 #else
1141     return cpuinfo_isa.sse4_1;
1142 #endif
1143 #elif CPUINFO_ARCH_X86
1144     return cpuinfo_isa.sse4_1;
1145 #else
1146     return false;
1147 #endif
1148 }
1149 
1150 static inline bool cpuinfo_has_x86_sse4_2(void) {
1151 #if CPUINFO_ARCH_X86_64
1152 #if defined(__ANDROID__)
1153     return true;
1154 #else
1155     return cpuinfo_isa.sse4_2;
1156 #endif
1157 #elif CPUINFO_ARCH_X86
1158     return cpuinfo_isa.sse4_2;
1159 #else
1160     return false;
1161 #endif
1162 }
1163 
1164 static inline bool cpuinfo_has_x86_sse4a(void) {
1165 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1166     return cpuinfo_isa.sse4a;
1167 #else
1168     return false;
1169 #endif
1170 }
1171 
1172 static inline bool cpuinfo_has_x86_misaligned_sse(void) {
1173 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1174     return cpuinfo_isa.misaligned_sse;
1175 #else
1176     return false;
1177 #endif
1178 }
1179 
1180 static inline bool cpuinfo_has_x86_avx(void) {
1181 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1182     return cpuinfo_isa.avx;
1183 #else
1184     return false;
1185 #endif
1186 }
1187 
1188 static inline bool cpuinfo_has_x86_avxvnni(void) {
1189 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1190     return cpuinfo_isa.avxvnni;
1191 #else
1192     return false;
1193 #endif
1194 }
1195 
1196 static inline bool cpuinfo_has_x86_fma3(void) {
1197 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1198     return cpuinfo_isa.fma3;
1199 #else
1200     return false;
1201 #endif
1202 }
1203 
1204 static inline bool cpuinfo_has_x86_fma4(void) {
1205 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1206     return cpuinfo_isa.fma4;
1207 #else
1208     return false;
1209 #endif
1210 }
1211 
1212 static inline bool cpuinfo_has_x86_xop(void) {
1213 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1214     return cpuinfo_isa.xop;
1215 #else
1216     return false;
1217 #endif
1218 }
1219 
1220 static inline bool cpuinfo_has_x86_f16c(void) {
1221 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1222     return cpuinfo_isa.f16c;
1223 #else
1224     return false;
1225 #endif
1226 }
1227 
1228 static inline bool cpuinfo_has_x86_avx2(void) {
1229 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1230     return cpuinfo_isa.avx2;
1231 #else
1232     return false;
1233 #endif
1234 }
1235 
1236 static inline bool cpuinfo_has_x86_avx512f(void) {
1237 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1238     return cpuinfo_isa.avx512f;
1239 #else
1240     return false;
1241 #endif
1242 }
1243 
1244 static inline bool cpuinfo_has_x86_avx512pf(void) {
1245 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1246     return cpuinfo_isa.avx512pf;
1247 #else
1248     return false;
1249 #endif
1250 }
1251 
1252 static inline bool cpuinfo_has_x86_avx512er(void) {
1253 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1254     return cpuinfo_isa.avx512er;
1255 #else
1256     return false;
1257 #endif
1258 }
1259 
1260 static inline bool cpuinfo_has_x86_avx512cd(void) {
1261 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1262     return cpuinfo_isa.avx512cd;
1263 #else
1264     return false;
1265 #endif
1266 }
1267 
1268 static inline bool cpuinfo_has_x86_avx512dq(void) {
1269 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1270     return cpuinfo_isa.avx512dq;
1271 #else
1272     return false;
1273 #endif
1274 }
1275 
1276 static inline bool cpuinfo_has_x86_avx512bw(void) {
1277 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1278     return cpuinfo_isa.avx512bw;
1279 #else
1280     return false;
1281 #endif
1282 }
1283 
1284 static inline bool cpuinfo_has_x86_avx512vl(void) {
1285 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1286     return cpuinfo_isa.avx512vl;
1287 #else
1288     return false;
1289 #endif
1290 }
1291 
1292 static inline bool cpuinfo_has_x86_avx512ifma(void) {
1293 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1294     return cpuinfo_isa.avx512ifma;
1295 #else
1296     return false;
1297 #endif
1298 }
1299 
1300 static inline bool cpuinfo_has_x86_avx512vbmi(void) {
1301 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1302     return cpuinfo_isa.avx512vbmi;
1303 #else
1304     return false;
1305 #endif
1306 }
1307 
1308 static inline bool cpuinfo_has_x86_avx512vbmi2(void) {
1309 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1310     return cpuinfo_isa.avx512vbmi2;
1311 #else
1312     return false;
1313 #endif
1314 }
1315 
1316 static inline bool cpuinfo_has_x86_avx512bitalg(void) {
1317 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1318     return cpuinfo_isa.avx512bitalg;
1319 #else
1320     return false;
1321 #endif
1322 }
1323 
1324 static inline bool cpuinfo_has_x86_avx512vpopcntdq(void) {
1325 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1326     return cpuinfo_isa.avx512vpopcntdq;
1327 #else
1328     return false;
1329 #endif
1330 }
1331 
1332 static inline bool cpuinfo_has_x86_avx512vnni(void) {
1333 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1334     return cpuinfo_isa.avx512vnni;
1335 #else
1336     return false;
1337 #endif
1338 }
1339 
1340 static inline bool cpuinfo_has_x86_avx512bf16(void) {
1341 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1342     return cpuinfo_isa.avx512bf16;
1343 #else
1344     return false;
1345 #endif
1346 }
1347 
1348 static inline bool cpuinfo_has_x86_avx512fp16(void) {
1349 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1350     return cpuinfo_isa.avx512fp16;
1351 #else
1352     return false;
1353 #endif
1354 }
1355 
1356 static inline bool cpuinfo_has_x86_avx512vp2intersect(void) {
1357 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1358     return cpuinfo_isa.avx512vp2intersect;
1359 #else
1360     return false;
1361 #endif
1362 }
1363 
1364 static inline bool cpuinfo_has_x86_avx512_4vnniw(void) {
1365 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1366     return cpuinfo_isa.avx512_4vnniw;
1367 #else
1368     return false;
1369 #endif
1370 }
1371 
1372 static inline bool cpuinfo_has_x86_avx512_4fmaps(void) {
1373 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1374     return cpuinfo_isa.avx512_4fmaps;
1375 #else
1376     return false;
1377 #endif
1378 }
1379 
1380 /* [NOTE] Intel Advanced Matrix Extensions (AMX) detection
1381  *
1382  * I.  AMX is a new extensions to the x86 ISA to work on matrices, consists of
1383  *   1) 2-dimentional registers (tiles), hold sub-matrices from larger matrices in memory
1384  *   2) Accelerator called Tile Matrix Multiply (TMUL), contains instructions operating on tiles
1385  *
1386  * II. Platforms that supports AMX:
1387  * +-----------------+-----+----------+----------+----------+----------+
1388  * |    Platforms    | Gen | amx-bf16 | amx-tile | amx-int8 | amx-fp16 |
1389  * +-----------------+-----+----------+----------+----------+----------+
1390  * | Sapphire Rapids | 4th |   YES    |   YES    |   YES    |    NO    |
1391  * +-----------------+-----+----------+----------+----------+----------+
1392  * | Emerald Rapids  | 5th |   YES    |   YES    |   YES    |    NO    |
1393  * +-----------------+-----+----------+----------+----------+----------+
1394  * | Granite Rapids  | 6th |   YES    |   YES    |   YES    |   YES    |
1395  * +-----------------+-----+----------+----------+----------+----------+
1396  *
1397  * Reference: https://www.intel.com/content/www/us/en/products/docs
1398  *    /accelerator-engines/advanced-matrix-extensions/overview.html
1399  */
1400 static inline bool cpuinfo_has_x86_amx_bf16(void) {
1401 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1402     return cpuinfo_isa.amx_bf16;
1403 #else
1404     return false;
1405 #endif
1406 }
1407 
1408 static inline bool cpuinfo_has_x86_amx_tile(void) {
1409 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1410     return cpuinfo_isa.amx_tile;
1411 #else
1412     return false;
1413 #endif
1414 }
1415 
1416 static inline bool cpuinfo_has_x86_amx_int8(void) {
1417 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1418     return cpuinfo_isa.amx_int8;
1419 #else
1420     return false;
1421 #endif
1422 }
1423 
1424 static inline bool cpuinfo_has_x86_amx_fp16(void) {
1425 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1426     return cpuinfo_isa.amx_fp16;
1427 #else
1428     return false;
1429 #endif
1430 }
1431 
1432 /*
1433  * Intel AVX Vector Neural Network Instructions (VNNI) INT8
1434  * Supported Platfroms: Sierra Forest, Arrow Lake, Lunar Lake
1435  */
1436 static inline bool cpuinfo_has_x86_avx_vnni_int8(void) {
1437 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1438     return cpuinfo_isa.avx_vnni_int8;
1439 #else
1440     return false;
1441 #endif
1442 }
1443 
1444 /*
1445  * Intel AVX Vector Neural Network Instructions (VNNI) INT16
1446  * Supported Platfroms: Arrow Lake, Lunar Lake
1447  */
1448 static inline bool cpuinfo_has_x86_avx_vnni_int16(void) {
1449 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1450     return cpuinfo_isa.avx_vnni_int16;
1451 #else
1452     return false;
1453 #endif
1454 }
1455 
1456 /*
1457  * A new set of instructions, which can convert low precision floating point
1458  * like BF16/FP16 to high precision floating point FP32, as well as convert FP32
1459  * elements to BF16. This instruction allows the platform to have improved AI
1460  * capabilities and better compatibility.
1461  *
1462  * Supported Platforms: Sierra Forest, Arrow Lake, Lunar Lake
1463  */
1464 static inline bool cpuinfo_has_x86_avx_ne_convert(void) {
1465 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1466     return cpuinfo_isa.avx_ne_convert;
1467 #else
1468     return false;
1469 #endif
1470 }
1471 
1472 static inline bool cpuinfo_has_x86_avx10_1(void) {
1473 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1474     return cpuinfo_isa.avx10_1;
1475 #else
1476     return false;
1477 #endif
1478 }
1479 
1480 static inline bool cpuinfo_has_x86_avx10_2(void) {
1481 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1482     return cpuinfo_isa.avx10_2;
1483 #else
1484     return false;
1485 #endif
1486 }
1487 
1488 static inline bool cpuinfo_has_x86_hle(void) {
1489 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1490     return cpuinfo_isa.hle;
1491 #else
1492     return false;
1493 #endif
1494 }
1495 
1496 static inline bool cpuinfo_has_x86_rtm(void) {
1497 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1498     return cpuinfo_isa.rtm;
1499 #else
1500     return false;
1501 #endif
1502 }
1503 
1504 static inline bool cpuinfo_has_x86_xtest(void) {
1505 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1506     return cpuinfo_isa.xtest;
1507 #else
1508     return false;
1509 #endif
1510 }
1511 
1512 static inline bool cpuinfo_has_x86_mpx(void) {
1513 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1514     return cpuinfo_isa.mpx;
1515 #else
1516     return false;
1517 #endif
1518 }
1519 
1520 static inline bool cpuinfo_has_x86_cmov(void) {
1521 #if CPUINFO_ARCH_X86_64
1522     return true;
1523 #elif CPUINFO_ARCH_X86
1524     return cpuinfo_isa.cmov;
1525 #else
1526     return false;
1527 #endif
1528 }
1529 
1530 static inline bool cpuinfo_has_x86_cmpxchg8b(void) {
1531 #if CPUINFO_ARCH_X86_64
1532     return true;
1533 #elif CPUINFO_ARCH_X86
1534     return cpuinfo_isa.cmpxchg8b;
1535 #else
1536     return false;
1537 #endif
1538 }
1539 
1540 static inline bool cpuinfo_has_x86_cmpxchg16b(void) {
1541 #if CPUINFO_ARCH_X86_64
1542     return cpuinfo_isa.cmpxchg16b;
1543 #else
1544     return false;
1545 #endif
1546 }
1547 
1548 static inline bool cpuinfo_has_x86_clwb(void) {
1549 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1550     return cpuinfo_isa.clwb;
1551 #else
1552     return false;
1553 #endif
1554 }
1555 
1556 static inline bool cpuinfo_has_x86_movbe(void) {
1557 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1558     return cpuinfo_isa.movbe;
1559 #else
1560     return false;
1561 #endif
1562 }
1563 
1564 static inline bool cpuinfo_has_x86_lahf_sahf(void) {
1565 #if CPUINFO_ARCH_X86
1566     return true;
1567 #elif CPUINFO_ARCH_X86_64
1568     return cpuinfo_isa.lahf_sahf;
1569 #else
1570     return false;
1571 #endif
1572 }
1573 
1574 static inline bool cpuinfo_has_x86_lzcnt(void) {
1575 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1576     return cpuinfo_isa.lzcnt;
1577 #else
1578     return false;
1579 #endif
1580 }
1581 
1582 static inline bool cpuinfo_has_x86_popcnt(void) {
1583 #if CPUINFO_ARCH_X86_64
1584 #if defined(__ANDROID__)
1585     return true;
1586 #else
1587     return cpuinfo_isa.popcnt;
1588 #endif
1589 #elif CPUINFO_ARCH_X86
1590     return cpuinfo_isa.popcnt;
1591 #else
1592     return false;
1593 #endif
1594 }
1595 
1596 static inline bool cpuinfo_has_x86_tbm(void) {
1597 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1598     return cpuinfo_isa.tbm;
1599 #else
1600     return false;
1601 #endif
1602 }
1603 
1604 static inline bool cpuinfo_has_x86_bmi(void) {
1605 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1606     return cpuinfo_isa.bmi;
1607 #else
1608     return false;
1609 #endif
1610 }
1611 
1612 static inline bool cpuinfo_has_x86_bmi2(void) {
1613 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1614     return cpuinfo_isa.bmi2;
1615 #else
1616     return false;
1617 #endif
1618 }
1619 
1620 static inline bool cpuinfo_has_x86_adx(void) {
1621 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1622     return cpuinfo_isa.adx;
1623 #else
1624     return false;
1625 #endif
1626 }
1627 
1628 static inline bool cpuinfo_has_x86_aes(void) {
1629 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1630     return cpuinfo_isa.aes;
1631 #else
1632     return false;
1633 #endif
1634 }
1635 
1636 static inline bool cpuinfo_has_x86_vaes(void) {
1637 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1638     return cpuinfo_isa.vaes;
1639 #else
1640     return false;
1641 #endif
1642 }
1643 
1644 static inline bool cpuinfo_has_x86_pclmulqdq(void) {
1645 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1646     return cpuinfo_isa.pclmulqdq;
1647 #else
1648     return false;
1649 #endif
1650 }
1651 
1652 static inline bool cpuinfo_has_x86_vpclmulqdq(void) {
1653 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1654     return cpuinfo_isa.vpclmulqdq;
1655 #else
1656     return false;
1657 #endif
1658 }
1659 
1660 static inline bool cpuinfo_has_x86_gfni(void) {
1661 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1662     return cpuinfo_isa.gfni;
1663 #else
1664     return false;
1665 #endif
1666 }
1667 
1668 static inline bool cpuinfo_has_x86_rdrand(void) {
1669 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1670     return cpuinfo_isa.rdrand;
1671 #else
1672     return false;
1673 #endif
1674 }
1675 
1676 static inline bool cpuinfo_has_x86_rdseed(void) {
1677 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1678     return cpuinfo_isa.rdseed;
1679 #else
1680     return false;
1681 #endif
1682 }
1683 
1684 static inline bool cpuinfo_has_x86_sha(void) {
1685 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
1686     return cpuinfo_isa.sha;
1687 #else
1688     return false;
1689 #endif
1690 }
1691 
1692 #if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
1693 /* This structure is not a part of stable API. Use cpuinfo_has_arm_* functions
1694  * instead. */
1695 struct cpuinfo_arm_isa {
1696 #if CPUINFO_ARCH_ARM
1697     bool thumb;
1698     bool thumb2;
1699     bool thumbee;
1700     bool jazelle;
1701     bool armv5e;
1702     bool armv6;
1703     bool armv6k;
1704     bool armv7;
1705     bool armv7mp;
1706     bool armv8;
1707     bool idiv;
1708 
1709     bool vfpv2;
1710     bool vfpv3;
1711     bool d32;
1712     bool fp16;
1713     bool fma;
1714 
1715     bool wmmx;
1716     bool wmmx2;
1717     bool neon;
1718 #endif
1719 #if CPUINFO_ARCH_ARM64
1720     bool atomics;
1721     bool bf16;
1722     bool sve;
1723     bool sve2;
1724     bool i8mm;
1725     bool sme;
1726     bool sme2;
1727     bool sme2p1;
1728     bool sme_i16i32;
1729     bool sme_bi32i32;
1730     bool sme_b16b16;
1731     bool sme_f16f16;
1732     uint32_t svelen;
1733     uint32_t smelen;
1734 #endif
1735     bool rdm;
1736     bool fp16arith;
1737     bool dot;
1738     bool jscvt;
1739     bool fcma;
1740     bool fhm;
1741 
1742     bool aes;
1743     bool sha1;
1744     bool sha2;
1745     bool pmull;
1746     bool crc32;
1747 };
1748 
1749 extern struct cpuinfo_arm_isa cpuinfo_isa;
1750 #endif
1751 
1752 static inline bool cpuinfo_has_arm_thumb(void) {
1753 #if CPUINFO_ARCH_ARM
1754     return cpuinfo_isa.thumb;
1755 #else
1756     return false;
1757 #endif
1758 }
1759 
1760 static inline bool cpuinfo_has_arm_thumb2(void) {
1761 #if CPUINFO_ARCH_ARM
1762     return cpuinfo_isa.thumb2;
1763 #else
1764     return false;
1765 #endif
1766 }
1767 
1768 static inline bool cpuinfo_has_arm_v5e(void) {
1769 #if CPUINFO_ARCH_ARM
1770     return cpuinfo_isa.armv5e;
1771 #else
1772     return false;
1773 #endif
1774 }
1775 
1776 static inline bool cpuinfo_has_arm_v6(void) {
1777 #if CPUINFO_ARCH_ARM
1778     return cpuinfo_isa.armv6;
1779 #else
1780     return false;
1781 #endif
1782 }
1783 
1784 static inline bool cpuinfo_has_arm_v6k(void) {
1785 #if CPUINFO_ARCH_ARM
1786     return cpuinfo_isa.armv6k;
1787 #else
1788     return false;
1789 #endif
1790 }
1791 
1792 static inline bool cpuinfo_has_arm_v7(void) {
1793 #if CPUINFO_ARCH_ARM
1794     return cpuinfo_isa.armv7;
1795 #else
1796     return false;
1797 #endif
1798 }
1799 
1800 static inline bool cpuinfo_has_arm_v7mp(void) {
1801 #if CPUINFO_ARCH_ARM
1802     return cpuinfo_isa.armv7mp;
1803 #else
1804     return false;
1805 #endif
1806 }
1807 
1808 static inline bool cpuinfo_has_arm_v8(void) {
1809 #if CPUINFO_ARCH_ARM64
1810     return true;
1811 #elif CPUINFO_ARCH_ARM
1812     return cpuinfo_isa.armv8;
1813 #else
1814     return false;
1815 #endif
1816 }
1817 
1818 static inline bool cpuinfo_has_arm_idiv(void) {
1819 #if CPUINFO_ARCH_ARM64
1820     return true;
1821 #elif CPUINFO_ARCH_ARM
1822     return cpuinfo_isa.idiv;
1823 #else
1824     return false;
1825 #endif
1826 }
1827 
1828 static inline bool cpuinfo_has_arm_vfpv2(void) {
1829 #if CPUINFO_ARCH_ARM
1830     return cpuinfo_isa.vfpv2;
1831 #else
1832     return false;
1833 #endif
1834 }
1835 
1836 static inline bool cpuinfo_has_arm_vfpv3(void) {
1837 #if CPUINFO_ARCH_ARM64
1838     return true;
1839 #elif CPUINFO_ARCH_ARM
1840     return cpuinfo_isa.vfpv3;
1841 #else
1842     return false;
1843 #endif
1844 }
1845 
1846 static inline bool cpuinfo_has_arm_vfpv3_d32(void) {
1847 #if CPUINFO_ARCH_ARM64
1848     return true;
1849 #elif CPUINFO_ARCH_ARM
1850     return cpuinfo_isa.vfpv3 && cpuinfo_isa.d32;
1851 #else
1852     return false;
1853 #endif
1854 }
1855 
1856 static inline bool cpuinfo_has_arm_vfpv3_fp16(void) {
1857 #if CPUINFO_ARCH_ARM64
1858     return true;
1859 #elif CPUINFO_ARCH_ARM
1860     return cpuinfo_isa.vfpv3 && cpuinfo_isa.fp16;
1861 #else
1862     return false;
1863 #endif
1864 }
1865 
1866 static inline bool cpuinfo_has_arm_vfpv3_fp16_d32(void) {
1867 #if CPUINFO_ARCH_ARM64
1868     return true;
1869 #elif CPUINFO_ARCH_ARM
1870     return cpuinfo_isa.vfpv3 && cpuinfo_isa.fp16 && cpuinfo_isa.d32;
1871 #else
1872     return false;
1873 #endif
1874 }
1875 
1876 static inline bool cpuinfo_has_arm_vfpv4(void) {
1877 #if CPUINFO_ARCH_ARM64
1878     return true;
1879 #elif CPUINFO_ARCH_ARM
1880     return cpuinfo_isa.vfpv3 && cpuinfo_isa.fma;
1881 #else
1882     return false;
1883 #endif
1884 }
1885 
1886 static inline bool cpuinfo_has_arm_vfpv4_d32(void) {
1887 #if CPUINFO_ARCH_ARM64
1888     return true;
1889 #elif CPUINFO_ARCH_ARM
1890     return cpuinfo_isa.vfpv3 && cpuinfo_isa.fma && cpuinfo_isa.d32;
1891 #else
1892     return false;
1893 #endif
1894 }
1895 
1896 static inline bool cpuinfo_has_arm_fp16_arith(void) {
1897 #if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
1898     return cpuinfo_isa.fp16arith;
1899 #else
1900     return false;
1901 #endif
1902 }
1903 
1904 static inline bool cpuinfo_has_arm_bf16(void) {
1905 #if CPUINFO_ARCH_ARM64
1906     return cpuinfo_isa.bf16;
1907 #else
1908     return false;
1909 #endif
1910 }
1911 
1912 static inline bool cpuinfo_has_arm_wmmx(void) {
1913 #if CPUINFO_ARCH_ARM
1914     return cpuinfo_isa.wmmx;
1915 #else
1916     return false;
1917 #endif
1918 }
1919 
1920 static inline bool cpuinfo_has_arm_wmmx2(void) {
1921 #if CPUINFO_ARCH_ARM
1922     return cpuinfo_isa.wmmx2;
1923 #else
1924     return false;
1925 #endif
1926 }
1927 
1928 static inline bool cpuinfo_has_arm_neon(void) {
1929 #if CPUINFO_ARCH_ARM64
1930     return true;
1931 #elif CPUINFO_ARCH_ARM
1932     return cpuinfo_isa.neon;
1933 #else
1934     return false;
1935 #endif
1936 }
1937 
1938 static inline bool cpuinfo_has_arm_neon_fp16(void) {
1939 #if CPUINFO_ARCH_ARM64
1940     return true;
1941 #elif CPUINFO_ARCH_ARM
1942     return cpuinfo_isa.neon && cpuinfo_isa.fp16;
1943 #else
1944     return false;
1945 #endif
1946 }
1947 
1948 static inline bool cpuinfo_has_arm_neon_fma(void) {
1949 #if CPUINFO_ARCH_ARM64
1950     return true;
1951 #elif CPUINFO_ARCH_ARM
1952     return cpuinfo_isa.neon && cpuinfo_isa.fma;
1953 #else
1954     return false;
1955 #endif
1956 }
1957 
1958 static inline bool cpuinfo_has_arm_neon_v8(void) {
1959 #if CPUINFO_ARCH_ARM64
1960     return true;
1961 #elif CPUINFO_ARCH_ARM
1962     return cpuinfo_isa.neon && cpuinfo_isa.armv8;
1963 #else
1964     return false;
1965 #endif
1966 }
1967 
1968 static inline bool cpuinfo_has_arm_atomics(void) {
1969 #if CPUINFO_ARCH_ARM64
1970     return cpuinfo_isa.atomics;
1971 #else
1972     return false;
1973 #endif
1974 }
1975 
1976 static inline bool cpuinfo_has_arm_neon_rdm(void) {
1977 #if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
1978     return cpuinfo_isa.rdm;
1979 #else
1980     return false;
1981 #endif
1982 }
1983 
1984 static inline bool cpuinfo_has_arm_neon_fp16_arith(void) {
1985 #if CPUINFO_ARCH_ARM
1986     return cpuinfo_isa.neon && cpuinfo_isa.fp16arith;
1987 #elif CPUINFO_ARCH_ARM64
1988     return cpuinfo_isa.fp16arith;
1989 #else
1990     return false;
1991 #endif
1992 }
1993 
1994 static inline bool cpuinfo_has_arm_fhm(void) {
1995 #if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
1996     return cpuinfo_isa.fhm;
1997 #else
1998     return false;
1999 #endif
2000 }
2001 
2002 static inline bool cpuinfo_has_arm_neon_dot(void) {
2003 #if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
2004     return cpuinfo_isa.dot;
2005 #else
2006     return false;
2007 #endif
2008 }
2009 
2010 static inline bool cpuinfo_has_arm_neon_bf16(void) {
2011 #if CPUINFO_ARCH_ARM64
2012     return cpuinfo_isa.bf16;
2013 #else
2014     return false;
2015 #endif
2016 }
2017 
2018 static inline bool cpuinfo_has_arm_jscvt(void) {
2019 #if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
2020     return cpuinfo_isa.jscvt;
2021 #else
2022     return false;
2023 #endif
2024 }
2025 
2026 static inline bool cpuinfo_has_arm_fcma(void) {
2027 #if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
2028     return cpuinfo_isa.fcma;
2029 #else
2030     return false;
2031 #endif
2032 }
2033 
2034 static inline bool cpuinfo_has_arm_i8mm(void) {
2035 #if CPUINFO_ARCH_ARM64
2036     return cpuinfo_isa.i8mm;
2037 #else
2038     return false;
2039 #endif
2040 }
2041 
2042 static inline bool cpuinfo_has_arm_aes(void) {
2043 #if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
2044     return cpuinfo_isa.aes;
2045 #else
2046     return false;
2047 #endif
2048 }
2049 
2050 static inline bool cpuinfo_has_arm_sha1(void) {
2051 #if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
2052     return cpuinfo_isa.sha1;
2053 #else
2054     return false;
2055 #endif
2056 }
2057 
2058 static inline bool cpuinfo_has_arm_sha2(void) {
2059 #if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
2060     return cpuinfo_isa.sha2;
2061 #else
2062     return false;
2063 #endif
2064 }
2065 
2066 static inline bool cpuinfo_has_arm_pmull(void) {
2067 #if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
2068     return cpuinfo_isa.pmull;
2069 #else
2070     return false;
2071 #endif
2072 }
2073 
2074 static inline bool cpuinfo_has_arm_crc32(void) {
2075 #if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
2076     return cpuinfo_isa.crc32;
2077 #else
2078     return false;
2079 #endif
2080 }
2081 
2082 static inline bool cpuinfo_has_arm_sve(void) {
2083 #if CPUINFO_ARCH_ARM64
2084     return cpuinfo_isa.sve;
2085 #else
2086     return false;
2087 #endif
2088 }
2089 
2090 static inline bool cpuinfo_has_arm_sve_bf16(void) {
2091 #if CPUINFO_ARCH_ARM64
2092     return cpuinfo_isa.sve && cpuinfo_isa.bf16;
2093 #else
2094     return false;
2095 #endif
2096 }
2097 
2098 static inline bool cpuinfo_has_arm_sve2(void) {
2099 #if CPUINFO_ARCH_ARM64
2100     return cpuinfo_isa.sve2;
2101 #else
2102     return false;
2103 #endif
2104 }
2105 
2106 // Function to get the max SVE vector length on ARM CPU's which support SVE.
2107 static inline uint32_t cpuinfo_get_max_arm_sve_length(void) {
2108 #if CPUINFO_ARCH_ARM64
2109     return cpuinfo_isa.svelen * 8; // bytes * 8 = bit length(vector length)
2110 #else
2111     return 0;
2112 #endif
2113 }
2114 
2115 // Function to get the max SME vector length on ARM CPU's which support SME.
2116 static inline uint32_t cpuinfo_get_max_arm_sme_length(void) {
2117 #if CPUINFO_ARCH_ARM64
2118     return cpuinfo_isa.smelen * 8; // bytes * 8 = bit length(vector length)
2119 #else
2120     return 0;
2121 #endif
2122 }
2123 
2124 static inline bool cpuinfo_has_arm_sme(void) {
2125 #if CPUINFO_ARCH_ARM64
2126     return cpuinfo_isa.sme;
2127 #else
2128     return false;
2129 #endif
2130 }
2131 
2132 static inline bool cpuinfo_has_arm_sme2(void) {
2133 #if CPUINFO_ARCH_ARM64
2134     return cpuinfo_isa.sme2;
2135 #else
2136     return false;
2137 #endif
2138 }
2139 
2140 static inline bool cpuinfo_has_arm_sme2p1(void) {
2141 #if CPUINFO_ARCH_ARM64
2142     return cpuinfo_isa.sme2p1;
2143 #else
2144     return false;
2145 #endif
2146 }
2147 
2148 static inline bool cpuinfo_has_arm_sme_i16i32(void) {
2149 #if CPUINFO_ARCH_ARM64
2150     return cpuinfo_isa.sme_i16i32;
2151 #else
2152     return false;
2153 #endif
2154 }
2155 
2156 static inline bool cpuinfo_has_arm_sme_bi32i32(void) {
2157 #if CPUINFO_ARCH_ARM64
2158     return cpuinfo_isa.sme_bi32i32;
2159 #else
2160     return false;
2161 #endif
2162 }
2163 
2164 static inline bool cpuinfo_has_arm_sme_b16b16(void) {
2165 #if CPUINFO_ARCH_ARM64
2166     return cpuinfo_isa.sme_b16b16;
2167 #else
2168     return false;
2169 #endif
2170 }
2171 
2172 static inline bool cpuinfo_has_arm_sme_f16f16(void) {
2173 #if CPUINFO_ARCH_ARM64
2174     return cpuinfo_isa.sme_f16f16;
2175 #else
2176     return false;
2177 #endif
2178 }
2179 
2180 #if CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64
2181 /* This structure is not a part of stable API. Use cpuinfo_has_riscv_* functions
2182  * instead. */
2183 struct cpuinfo_riscv_isa {
2184     /**
2185      * Keep fields in line with the canonical order as defined by
2186      * Section 27.11 Subset Naming Convention.
2187      */
2188     /* RV32I/64I/128I Base ISA. */
2189     bool i;
2190 #if CPUINFO_ARCH_RISCV32
2191     /* RV32E Base ISA. */
2192     bool e;
2193 #endif
2194     /* Integer Multiply/Divide Extension. */
2195     bool m;
2196     /* Atomic Extension. */
2197     bool a;
2198     /* Single-Precision Floating-Point Extension. */
2199     bool f;
2200     /* Double-Precision Floating-Point Extension. */
2201     bool d;
2202     /* Compressed Extension. */
2203     bool c;
2204     /* Vector Extension. */
2205     bool v;
2206 };
2207 
2208 extern struct cpuinfo_riscv_isa cpuinfo_isa;
2209 #endif
2210 
2211 static inline bool cpuinfo_has_riscv_i(void) {
2212 #if CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64
2213     return cpuinfo_isa.i;
2214 #else
2215     return false;
2216 #endif
2217 }
2218 
2219 static inline bool cpuinfo_has_riscv_e(void) {
2220 #if CPUINFO_ARCH_RISCV32
2221     return cpuinfo_isa.e;
2222 #else
2223     return false;
2224 #endif
2225 }
2226 
2227 static inline bool cpuinfo_has_riscv_m(void) {
2228 #if CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64
2229     return cpuinfo_isa.m;
2230 #else
2231     return false;
2232 #endif
2233 }
2234 
2235 static inline bool cpuinfo_has_riscv_a(void) {
2236 #if CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64
2237     return cpuinfo_isa.a;
2238 #else
2239     return false;
2240 #endif
2241 }
2242 
2243 static inline bool cpuinfo_has_riscv_f(void) {
2244 #if CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64
2245     return cpuinfo_isa.f;
2246 #else
2247     return false;
2248 #endif
2249 }
2250 
2251 static inline bool cpuinfo_has_riscv_d(void) {
2252 #if CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64
2253     return cpuinfo_isa.d;
2254 #else
2255     return false;
2256 #endif
2257 }
2258 
2259 static inline bool cpuinfo_has_riscv_g(void) {
2260     // The 'G' extension is simply shorthand for 'IMAFD'.
2261     return cpuinfo_has_riscv_i() && cpuinfo_has_riscv_m() && cpuinfo_has_riscv_a() && cpuinfo_has_riscv_f() &&
2262         cpuinfo_has_riscv_d();
2263 }
2264 
2265 static inline bool cpuinfo_has_riscv_c(void) {
2266 #if CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64
2267     return cpuinfo_isa.c;
2268 #else
2269     return false;
2270 #endif
2271 }
2272 
2273 static inline bool cpuinfo_has_riscv_v(void) {
2274 #if CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64
2275     return cpuinfo_isa.v;
2276 #else
2277     return false;
2278 #endif
2279 }
2280 
2281 const struct cpuinfo_processor* CPUINFO_ABI cpuinfo_get_processors(void);
2282 const struct cpuinfo_core* CPUINFO_ABI cpuinfo_get_cores(void);
2283 const struct cpuinfo_cluster* CPUINFO_ABI cpuinfo_get_clusters(void);
2284 const struct cpuinfo_package* CPUINFO_ABI cpuinfo_get_packages(void);
2285 const struct cpuinfo_uarch_info* CPUINFO_ABI cpuinfo_get_uarchs(void);
2286 const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l1i_caches(void);
2287 const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l1d_caches(void);
2288 const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l2_caches(void);
2289 const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l3_caches(void);
2290 const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l4_caches(void);
2291 
2292 const struct cpuinfo_processor* CPUINFO_ABI cpuinfo_get_processor(uint32_t index);
2293 const struct cpuinfo_core* CPUINFO_ABI cpuinfo_get_core(uint32_t index);
2294 const struct cpuinfo_cluster* CPUINFO_ABI cpuinfo_get_cluster(uint32_t index);
2295 const struct cpuinfo_package* CPUINFO_ABI cpuinfo_get_package(uint32_t index);
2296 const struct cpuinfo_uarch_info* CPUINFO_ABI cpuinfo_get_uarch(uint32_t index);
2297 const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l1i_cache(uint32_t index);
2298 const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l1d_cache(uint32_t index);
2299 const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l2_cache(uint32_t index);
2300 const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l3_cache(uint32_t index);
2301 const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l4_cache(uint32_t index);
2302 
2303 uint32_t CPUINFO_ABI cpuinfo_get_processors_count(void);
2304 uint32_t CPUINFO_ABI cpuinfo_get_cores_count(void);
2305 uint32_t CPUINFO_ABI cpuinfo_get_clusters_count(void);
2306 uint32_t CPUINFO_ABI cpuinfo_get_packages_count(void);
2307 uint32_t CPUINFO_ABI cpuinfo_get_uarchs_count(void);
2308 uint32_t CPUINFO_ABI cpuinfo_get_l1i_caches_count(void);
2309 uint32_t CPUINFO_ABI cpuinfo_get_l1d_caches_count(void);
2310 uint32_t CPUINFO_ABI cpuinfo_get_l2_caches_count(void);
2311 uint32_t CPUINFO_ABI cpuinfo_get_l3_caches_count(void);
2312 uint32_t CPUINFO_ABI cpuinfo_get_l4_caches_count(void);
2313 
2314 /**
2315  * Returns upper bound on cache size.
2316  */
2317 uint32_t CPUINFO_ABI cpuinfo_get_max_cache_size(void);
2318 
2319 /**
2320  * Identify the logical processor that executes the current thread.
2321  *
2322  * There is no guarantee that the thread will stay on the same logical processor
2323  * for any time. Callers should treat the result as only a hint, and be prepared
2324  * to handle NULL return value.
2325  */
2326 const struct cpuinfo_processor* CPUINFO_ABI cpuinfo_get_current_processor(void);
2327 
2328 /**
2329  * Identify the core that executes the current thread.
2330  *
2331  * There is no guarantee that the thread will stay on the same core for any
2332  * time. Callers should treat the result as only a hint, and be prepared to
2333  * handle NULL return value.
2334  */
2335 const struct cpuinfo_core* CPUINFO_ABI cpuinfo_get_current_core(void);
2336 
2337 /**
2338  * Identify the microarchitecture index of the core that executes the current
2339  * thread. If the system does not support such identification, the function
2340  * returns 0.
2341  *
2342  * There is no guarantee that the thread will stay on the same type of core for
2343  * any time. Callers should treat the result as only a hint.
2344  */
2345 uint32_t CPUINFO_ABI cpuinfo_get_current_uarch_index(void);
2346 
2347 /**
2348  * Identify the microarchitecture index of the core that executes the current
2349  * thread. If the system does not support such identification, the function
2350  * returns the user-specified default value.
2351  *
2352  * There is no guarantee that the thread will stay on the same type of core for
2353  * any time. Callers should treat the result as only a hint.
2354  */
2355 uint32_t CPUINFO_ABI cpuinfo_get_current_uarch_index_with_default(uint32_t default_uarch_index);
2356 
2357 #ifdef __cplusplus
2358 } /* extern "C" */
2359 #endif
2360 
2361 #endif /* CPUINFO_H */