Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-29 10:20:47

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