From 3e39b739c0d602413426e8268fd84e8d91525b6d Mon Sep 17 00:00:00 2001 From: gadoofou87 Date: Sun, 15 Mar 2020 12:14:42 +0500 Subject: [PATCH 1/3] SSE detection fix on non-AVX CPUs --- CMakeLists.txt | 23 +++++++++++++++ src/cpuinfo_x86.c | 71 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 91 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2c52e778..b933fd18 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -91,6 +91,20 @@ macro(add_cpu_features_headers_and_sources HDRS_LIST_NAME SRCS_LIST_NAME) endif() endmacro() +if(UNIX) + include(CheckCSourceCompiles) + check_c_source_compiles(" + #include + int main(void) + { + __builtin_cpu_init(); + }" HAVE_CPU_INIT) + if(NOT HAVE_CPU_INIT) + check_include_file(sys/utsname.h HAVE_UTSNAME_H) + check_symbol_exists(sysctlbyname sys/sysctl.h HAVE_SYSCTLBYNAME) + endif() +endif() + # # library : utils # @@ -148,6 +162,15 @@ set_property(TARGET cpu_features PROPERTY POSITION_INDEPENDENT_CODE ${BUILD_PIC} target_include_directories(cpu_features PUBLIC $ ) +if(HAVE_CPU_INIT) + target_compile_definitions(cpu_features PRIVATE HAVE_CPU_INIT) +endif() +if(HAVE_UTSNAME_H) + target_compile_definitions(cpu_features PRIVATE HAVE_UTSNAME_H) +endif() +if(HAVE_SYSCTLBYNAME) + target_compile_definitions(cpu_features PRIVATE HAVE_SYSCTLBYNAME) +endif() add_library(CpuFeature::cpu_features ALIAS cpu_features) # diff --git a/src/cpuinfo_x86.c b/src/cpuinfo_x86.c index 1f27e143..d25e2e79 100644 --- a/src/cpuinfo_x86.c +++ b/src/cpuinfo_x86.c @@ -1047,6 +1047,24 @@ typedef struct { bool have_avx512; } OsSupport; +#if defined(CPU_FEATURES_COMPILER_CLANG) || defined(CPU_FEATURES_COMPILER_GCC) +#if defined(HAVE_CPU_INIT) +#include +#else +#include "internal/filesystem.h" +#include "internal/stack_line_reader.h" +#include "internal/string_view.h" +#if defined(HAVE_UTSNAME_H) +#include +#if defined(HAVE_SYSCTLBYNAME) +#include +#endif +#endif +#endif +#elif defined(CPU_FEATURES_COMPILER_MSC) +#include +#endif + // Reference https://en.wikipedia.org/wiki/CPUID. static void ParseCpuId(const uint32_t max_cpuid_leaf, X86Info* info, OsSupport* os_support) { const Leaf leaf_1 = SafeCpuId(max_cpuid_leaf, 1); @@ -1055,9 +1073,56 @@ static void ParseCpuId(const uint32_t max_cpuid_leaf, X86Info* info, OsSupport* const bool have_xsave = IsBitSet(leaf_1.ecx, 26); const bool have_osxsave = IsBitSet(leaf_1.ecx, 27); const uint32_t xcr0_eax = (have_xsave && have_osxsave) ? GetXCR0Eax() : 0; - os_support->have_sse = HasXmmOsXSave(xcr0_eax); - os_support->have_avx = HasYmmOsXSave(xcr0_eax); - os_support->have_avx512 = HasZmmOsXSave(xcr0_eax); + if (xcr0_eax) { + os_support->have_sse = HasXmmOsXSave(xcr0_eax); + os_support->have_avx = HasYmmOsXSave(xcr0_eax); + os_support->have_avx512 = HasZmmOsXSave(xcr0_eax); + } else { +#if defined(CPU_FEATURES_COMPILER_CLANG) || defined(CPU_FEATURES_COMPILER_GCC) +#if defined(HAVE_CPU_INIT) + __builtin_cpu_init(); + os_support->have_sse = __builtin_cpu_supports("sse"); +#else +#if defined(HAVE_UTSNAME_H) + struct utsname buf; + uname(&buf); + if (strncmp(buf.sysname, "Darwin", sizeof(buf.sysname)) == 0) { +#if defined(HAVE_SYSCTLBYNAME) + int enabled, result; + size_t len = sizeof(enabled); + result = sysctlbyname("hw.optional.sse", &enabled, &len, NULL, 0); + if (result == 0) { + os_support->have_sse = enabled; + } +#endif + } else if (strncmp(buf.sysname, "Linux", sizeof(buf.sysname)) == 0) { + const int fd = CpuFeatures_OpenFile("/proc/cpuinfo"); + if (fd >= 0) { + StackLineReader reader; + StackLineReader_Initialize(&reader, fd); + for (;;) { + const LineResult result = StackLineReader_NextLine(&reader); + StringView line = result.line; + StringView key, value; + if (CpuFeatures_StringView_GetAttributeKeyValue(line, &key, &value)) { + if (CpuFeatures_StringView_IsEquals(key, str("flags"))) { + os_support->have_sse = CpuFeatures_StringView_HasWord(value, "sse"); + break; + } + } + if (result.eof) { + break; + } + } + CpuFeatures_CloseFile(fd); + } + } +#endif +#endif +#elif defined(CPU_FEATURES_COMPILER_MSC) + os_support->have_sse = IsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE); +#endif + } const uint32_t family = ExtractBitRange(leaf_1.eax, 11, 8); const uint32_t extended_family = ExtractBitRange(leaf_1.eax, 27, 20); From 7d3fb9da9a675996e25a4d0d83083bbb51b0dcc3 Mon Sep 17 00:00:00 2001 From: gadoofou87 Date: Fri, 3 Apr 2020 17:20:23 +0500 Subject: [PATCH 2/3] Corrections --- CMakeLists.txt | 14 +++++++------- src/cpuinfo_x86.c | 7 ++++--- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b933fd18..565859e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -101,7 +101,6 @@ if(UNIX) }" HAVE_CPU_INIT) if(NOT HAVE_CPU_INIT) check_include_file(sys/utsname.h HAVE_UTSNAME_H) - check_symbol_exists(sysctlbyname sys/sysctl.h HAVE_SYSCTLBYNAME) endif() endif() @@ -164,12 +163,13 @@ target_include_directories(cpu_features ) if(HAVE_CPU_INIT) target_compile_definitions(cpu_features PRIVATE HAVE_CPU_INIT) -endif() -if(HAVE_UTSNAME_H) - target_compile_definitions(cpu_features PRIVATE HAVE_UTSNAME_H) -endif() -if(HAVE_SYSCTLBYNAME) - target_compile_definitions(cpu_features PRIVATE HAVE_SYSCTLBYNAME) +else() + if(HAVE_UTSNAME_H) + target_compile_definitions(cpu_features PRIVATE HAVE_UTSNAME_H) + endif() + if(APPLE) + target_compile_definitions(cpu_features PRIVATE HAVE_SYSCTLBYNAME) + endif() endif() add_library(CpuFeature::cpu_features ALIAS cpu_features) diff --git a/src/cpuinfo_x86.c b/src/cpuinfo_x86.c index d25e2e79..c44f533b 100644 --- a/src/cpuinfo_x86.c +++ b/src/cpuinfo_x86.c @@ -1051,10 +1051,10 @@ typedef struct { #if defined(HAVE_CPU_INIT) #include #else +#if defined(HAVE_UTSNAME_H) #include "internal/filesystem.h" #include "internal/stack_line_reader.h" #include "internal/string_view.h" -#if defined(HAVE_UTSNAME_H) #include #if defined(HAVE_SYSCTLBYNAME) #include @@ -1117,9 +1117,10 @@ static void ParseCpuId(const uint32_t max_cpuid_leaf, X86Info* info, OsSupport* CpuFeatures_CloseFile(fd); } } -#endif -#endif +#endif // defined(HAVE_UTSNAME_H) +#endif // defined(CPU_FEATURES_COMPILER_CLANG) || defined(CPU_FEATURES_COMPILER_GCC) #elif defined(CPU_FEATURES_COMPILER_MSC) + // see: https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-isprocessorfeaturepresent os_support->have_sse = IsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE); #endif } From 9cab5fa4697b9d935dfee2cd860ff728d10c330f Mon Sep 17 00:00:00 2001 From: gadoofou87 Date: Fri, 3 Apr 2020 17:30:06 +0500 Subject: [PATCH 3/3] Added check of processor architecture --- CMakeLists.txt | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 565859e1..18e89815 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -91,7 +91,7 @@ macro(add_cpu_features_headers_and_sources HDRS_LIST_NAME SRCS_LIST_NAME) endif() endmacro() -if(UNIX) +if(UNIX AND PROCESSOR_IS_X86) include(CheckCSourceCompiles) check_c_source_compiles(" #include @@ -161,14 +161,16 @@ set_property(TARGET cpu_features PROPERTY POSITION_INDEPENDENT_CODE ${BUILD_PIC} target_include_directories(cpu_features PUBLIC $ ) -if(HAVE_CPU_INIT) - target_compile_definitions(cpu_features PRIVATE HAVE_CPU_INIT) -else() - if(HAVE_UTSNAME_H) - target_compile_definitions(cpu_features PRIVATE HAVE_UTSNAME_H) - endif() - if(APPLE) - target_compile_definitions(cpu_features PRIVATE HAVE_SYSCTLBYNAME) +if(PROCESSOR_IS_X86) + if(HAVE_CPU_INIT) + target_compile_definitions(cpu_features PRIVATE HAVE_CPU_INIT) + else() + if(HAVE_UTSNAME_H) + target_compile_definitions(cpu_features PRIVATE HAVE_UTSNAME_H) + endif() + if(APPLE) + target_compile_definitions(cpu_features PRIVATE HAVE_SYSCTLBYNAME) + endif() endif() endif() add_library(CpuFeature::cpu_features ALIAS cpu_features)