diff --git a/include/cpuinfo.h b/include/cpuinfo.h index 6eb4b8c3..ea3c1d07 100644 --- a/include/cpuinfo.h +++ b/include/cpuinfo.h @@ -821,6 +821,7 @@ struct cpuinfo_x86_isa { bool avx512_4vnniw; bool avx512_4fmaps; bool avx10_1; + bool avx10_2; bool amx_bf16; bool amx_tile; bool amx_int8; @@ -1444,6 +1445,14 @@ static inline bool cpuinfo_has_x86_avx10_1(void) { #endif } +static inline bool cpuinfo_has_x86_avx10_2(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.avx10_2; +#else + return false; +#endif +} + static inline bool cpuinfo_has_x86_hle(void) { #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 return cpuinfo_isa.hle; diff --git a/src/x86/isa.c b/src/x86/isa.c index 47a6afa3..377583b3 100644 --- a/src/x86/isa.c +++ b/src/x86/isa.c @@ -46,6 +46,8 @@ struct cpuinfo_x86_isa cpuinfo_x86_detect_isa( (max_base_index >= 7) ? cpuidex(7, 0) : (struct cpuid_regs){0, 0, 0, 0}; const struct cpuid_regs structured_feature_info1 = (max_base_index >= 7) ? cpuidex(7, 1) : (struct cpuid_regs){0, 0, 0, 0}; + const struct cpuid_regs structured_feature_info2 = + (max_base_index >= 7) ? cpuidex(0x24, 0) : (struct cpuid_regs){0, 0, 0, 0}; const uint32_t processor_capacity_info_index = UINT32_C(0x80000008); const struct cpuid_regs processor_capacity_info = (max_extended_index >= processor_capacity_info_index) @@ -430,10 +432,17 @@ struct cpuinfo_x86_isa cpuinfo_x86_detect_isa( isa.avx512f = avx512_regs && !!(structured_feature_info0.ebx & UINT32_C(0x00010000)); /* - * AVX 10.1 instructions: + * AVX 10.1 instructions: avx 10 isa supported. + * - Intel: edx[bit 19] in structured feature info (ecx = 1). */ isa.avx10_1 = avx512_regs && !!(structured_feature_info1.edx & UINT32_C(0x00080000)); + /* + * AVX 10.2 instructions: avx 10 version information. + * - Intel: ebx[bits 0-7] in structured features info (eax = 24 ecx = 0). + */ + isa.avx10_2 = ((structured_feature_info2.ebx & UINT32_C(0x000000FF)) >= 2) && isa.avx10_1; + /* * AVX512PF instructions: * - Intel: ebx[bit 26] in structured feature info (ecx = 0). diff --git a/tools/cpuid-dump.c b/tools/cpuid-dump.c index 87c403d5..1a65510f 100644 --- a/tools/cpuid-dump.c +++ b/tools/cpuid-dump.c @@ -123,6 +123,15 @@ int main(int argc, char** argv) { print_cpuidex(regs, eax, ecx); } break; + case UINT32_C(0x00000024): + for (uint32_t ecx = 0; ecx <= max_socid_index; ecx++) { + const struct cpuid_regs regs = cpuidex(eax, ecx); + if (ecx == 0) { + max_socid_index = regs.eax; + } + print_cpuidex(regs, eax, ecx); + } + break; default: print_cpuid(cpuidex(eax, 0), eax); break; diff --git a/tools/isa-info.c b/tools/isa-info.c index 96bcdd7a..21f94a5f 100644 --- a/tools/isa-info.c +++ b/tools/isa-info.c @@ -71,6 +71,7 @@ int main(int argc, char** argv) { printf("\tAVX512_4VNNIW: %s\n", cpuinfo_has_x86_avx512_4vnniw() ? "yes" : "no"); printf("\tAVX512_4FMAPS: %s\n", cpuinfo_has_x86_avx512_4fmaps() ? "yes" : "no"); printf("\tAVX10_1: %s\n", cpuinfo_has_x86_avx10_1() ? "yes" : "no"); + printf("\tAVX10_2: %s\n", cpuinfo_has_x86_avx10_2() ? "yes" : "no"); printf("\tAMX_BF16: %s\n", cpuinfo_has_x86_amx_bf16() ? "yes" : "no"); printf("\tAMX_TILE: %s\n", cpuinfo_has_x86_amx_tile() ? "yes" : "no"); printf("\tAMX_INT8: %s\n", cpuinfo_has_x86_amx_int8() ? "yes" : "no");