From c5caaa92114c74d02780a42d2eba758d8f1166f0 Mon Sep 17 00:00:00 2001 From: Birk Magnussen Date: Fri, 23 Mar 2018 23:08:13 +0100 Subject: [PATCH] Fix missing Detection for AVX OS Support --- Utilities/sysinfo.cpp | 6 +++--- Utilities/sysinfo.h | 11 +++++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/Utilities/sysinfo.cpp b/Utilities/sysinfo.cpp index 8ec13aaf6d..00075a5ec7 100644 --- a/Utilities/sysinfo.cpp +++ b/Utilities/sysinfo.cpp @@ -15,13 +15,13 @@ bool utils::has_ssse3() bool utils::has_avx() { - static const bool g_value = get_cpuid(0, 0)[0] >= 0x1 && get_cpuid(1, 0)[2] & 0x10000000; + static const bool g_value = get_cpuid(0, 0)[0] >= 0x1 && get_cpuid(1, 0)[2] & 0x10000000 && (get_cpuid(1, 0)[2] & 0x0C000000) == 0x0C000000 && (get_xgetbv(0) & 0x6) == 0x6; return g_value; } bool utils::has_avx2() { - static const bool g_value = get_cpuid(0, 0)[0] >= 0x7 && get_cpuid(7, 0)[1] & 0x20; + static const bool g_value = get_cpuid(0, 0)[0] >= 0x7 && get_cpuid(7, 0)[1] & 0x20 && (get_cpuid(1, 0)[2] & 0x0C000000) == 0x0C000000 && (get_xgetbv(0) & 0x6) == 0x6; return g_value; } @@ -35,7 +35,7 @@ bool utils::has_rtm() bool utils::has_512() { // Check AVX512F, AVX512CD, AVX512DQ, AVX512BW, AVX512VL extensions (Skylake-X level support) - static const bool g_value = get_cpuid(0, 0)[0] >= 0x7 && (get_cpuid(7, 0)[1] & 0xd0030000) == 0xd0030000; + static const bool g_value = get_cpuid(0, 0)[0] >= 0x7 && (get_cpuid(7, 0)[1] & 0xd0030000) == 0xd0030000 && (get_cpuid(1,0)[2] & 0x0C000000) == 0x0C000000 && (get_xgetbv(0) & 0xe6) == 0xe6; return g_value; } diff --git a/Utilities/sysinfo.h b/Utilities/sysinfo.h index 4151acb15a..54e07c559d 100644 --- a/Utilities/sysinfo.h +++ b/Utilities/sysinfo.h @@ -16,6 +16,17 @@ namespace utils return {0u+regs[0], 0u+regs[1], 0u+regs[2], 0u+regs[3]}; } + inline u64 get_xgetbv(u32 xcr) + { +#ifdef _MSC_VER + return _xgetbv(xcr); +#else + u32 eax, edx; + __asm__ volatile( "xgetbv" : "=a"(eax), "=d"(edx) : "c"(xcr)); + return eax | (u64(edx) << 32); +#endif + } + bool has_ssse3(); bool has_avx();