Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-11-13 11:02:40

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