37int checkasm_check_vzeroupper = 0;
39COLD int checkasm_get_check_vzeroupper(
void)
41 return checkasm_check_vzeroupper;
44void checkasm_warmup_avx(
void);
45void checkasm_warmup_avx512(
void);
46void checkasm_dirty_ymm_state(
void);
52static size_t get_model_name(
char *
name)
56 checkasm_cpu_cpuid(&
r, 0x80000000, 0);
57 if (
r.eax >= 0x80000004) {
59 CpuidRegisters *buf = (CpuidRegisters *)
name;
60 checkasm_cpu_cpuid(buf + 0, 0x80000002, 0);
61 checkasm_cpu_cpuid(buf + 1, 0x80000003, 0);
62 checkasm_cpu_cpuid(buf + 2, 0x80000004, 0);
65 checkasm_cpu_cpuid(&
r, 0, 0);
66 memcpy(
name + 0, &
r.ebx, 4);
67 memcpy(
name + 4, &
r.edx, 4);
68 memcpy(
name + 8, &
r.ecx, 4);
80static unsigned get_cpuid(
void)
84 checkasm_cpu_cpuid(&
r, 0, 0);
85 const uint32_t max_leaf =
r.eax;
89 checkasm_cpu_cpuid(&
r, 1, 0);
90 const uint32_t cpuid_sig =
r.eax;
94COLD char *checkasm_get_x86_cpuid(
char *buf,
size_t buflen)
99 const size_t len = get_model_name(buf);
100 const unsigned cpuid = get_cpuid();
106COLD void checkasm_init_x86(
void)
110 checkasm_cpu_cpuid(&
r, 0, 0);
111 const uint32_t max_leaf =
r.eax;
115 checkasm_cpu_cpuid(&
r, 1, 0);
116 if (~
r.ecx & 0x18000000 )
119 checkasm_cpu_cpuid(&
r, 13, 1);
126 checkasm_dirty_ymm_state();
127 const uint64_t xcr1 = checkasm_cpu_xgetbv(1);
131#if ARCH_X86_32 && defined(_WIN32)
134#elif defined(_MSC_VER) && !defined(__clang__)
143 checkasm_check_vzeroupper = 1;
147typedef void (*checkasm_simd_warmup_func)(void);
148static COLD checkasm_simd_warmup_func get_simd_warmup(
void)
150 checkasm_simd_warmup_func simd_warmup =
noop;
152 checkasm_cpu_cpuid(&
r, 0, 0);
153 const uint32_t max_leaf =
r.eax;
157 checkasm_cpu_cpuid(&
r, 1, 0);
158 if (~
r.ecx & 0x18000000)
161 const uint64_t xcr0 = checkasm_cpu_xgetbv(0);
165 simd_warmup = checkasm_warmup_avx;
166 if (max_leaf < 7 || ~xcr0 & 0xe0)
169 checkasm_cpu_cpuid(&
r, 7, 0);
170 if (
r.ebx & 0x00010000)
171 simd_warmup = checkasm_warmup_avx512;
176void checkasm_simd_warmup(
void)
178 static checkasm_simd_warmup_func simd_warmup =
NULL;
180 simd_warmup = get_simd_warmup();