7#if defined(__x86_64__) || defined(_M_X64) || defined(__amd64__) || \
8 defined(__i386__) || defined(_M_IX86)
9#define VECMAT_ARCH_X86 1
12#if defined(__aarch64__) || defined(_M_ARM64)
13#define VECMAT_ARCH_AARCH64 1
16#if defined(VECMAT_ARCH_X86)
24#if defined(VECMAT_ARCH_AARCH64) && defined(__linux__)
27#define HWCAP_SVE (1u << 22)
30#define HWCAP2_SVE2 (1u << 1)
37#if defined(VECMAT_ARCH_X86)
39static int vm_cpuid(
unsigned leaf,
unsigned sub,
40 unsigned *eax,
unsigned *ebx,
unsigned *ecx,
unsigned *edx)
43 __cpuidex(regs, (
int)leaf, (
int)sub);
44 *eax = (unsigned)regs[0];
45 *ebx = (unsigned)regs[1];
46 *ecx = (unsigned)regs[2];
47 *edx = (unsigned)regs[3];
51static unsigned vm_xgetbv(
unsigned idx)
53 return (
unsigned)_xgetbv(idx);
56static int vm_cpuid(
const unsigned leaf,
const unsigned sub,
57 unsigned *eax,
unsigned *ebx,
unsigned *ecx,
unsigned *edx)
59 const unsigned max = __get_cpuid_max(leaf & 0x80000000u, 0);
62 return (
int)__get_cpuid_count(leaf, sub, eax, ebx, ecx, edx);
65static unsigned vm_xgetbv(
unsigned idx)
68 __asm__
volatile(
"xgetbv" :
"=a"(eax),
"=d"(edx) :
"c"(idx));
73static int vm_cpu_probe_avx(
void)
75 unsigned eax = 0, ebx = 0, ecx = 0, edx = 0;
76 if (!vm_cpuid(1, 0, &eax, &ebx, &ecx, &edx))
79 if ((ecx & (1u << 27)) == 0 || (ecx & (1u << 28)) == 0)
81 return (vm_xgetbv(0) & 0x6u) == 0x6u;
84static int vm_cpu_probe_avx2(
void)
86 unsigned eax = 0, ebx = 0, ecx = 0, edx = 0;
87 if (!vm_cpu_probe_avx())
89 if (!vm_cpuid(7, 0, &eax, &ebx, &ecx, &edx))
91 return (ebx & (1u << 5)) != 0;
94static int vm_cpu_probe_avx512f(
void)
96 unsigned eax = 0, ebx = 0, ecx = 0, edx = 0;
97 if (!vm_cpuid(1, 0, &eax, &ebx, &ecx, &edx))
99 if ((ecx & (1u << 27)) == 0)
102 if ((vm_xgetbv(0) & 0xe6u) != 0xe6u)
104 if (!vm_cpuid(7, 0, &eax, &ebx, &ecx, &edx))
106 return (ebx & (1u << 16)) != 0;
112#if defined(VECMAT_ARCH_AARCH64) && defined(__linux__)
113 return (getauxval(AT_HWCAP) & HWCAP_SVE) != 0;
121#if defined(VECMAT_ARCH_AARCH64) && defined(__linux__)
124 return (getauxval(AT_HWCAP2) & HWCAP2_SVE2) != 0;
133#if defined(VECMAT_ENABLE_AVX) || defined(__AVX__)
136#if defined(VECMAT_ENABLE_AVX2) || defined(__AVX2__)
139#if defined(VECMAT_ENABLE_AVX512) || defined(__AVX512F__)
142#if defined(VECMAT_ENABLE_SVE) || defined(__ARM_FEATURE_SVE)
145#if defined(VECMAT_ENABLE_SVE2) || defined(__ARM_FEATURE_SVE2)
157#if defined(VECMAT_ARCH_X86)
158 if (vm_cpu_probe_avx())
160 if (vm_cpu_probe_avx2())
162 if (vm_cpu_probe_avx512f())
210#if !defined(VECMAT_RUNTIME_DISPATCH)
vm_cpu_features_t vm_cpu_compiled_features(void)
static int vm_cpu_probe_sve2(void)
const char * vm_cpu_name(const vm_cpu_features_t features)
static vm_cpu_features_t runtime_cache
static int vm_cpu_probe_sve(void)
static int runtime_cached
vm_cpu_features_t vm_cpu_runtime_features(void)
vm_cpu_features_t vm_cpu_selected_features(void)
uint32_t vm_cpu_features_t