Skip to content

Commit 39339a4

Browse files
author
gadoofou87
committed
SSE detection fix on non-AVX CPUs
1 parent 339bfd3 commit 39339a4

File tree

2 files changed

+91
-3
lines changed

2 files changed

+91
-3
lines changed

CMakeLists.txt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,20 @@ macro(add_cpu_features_headers_and_sources HDRS_LIST_NAME SRCS_LIST_NAME)
9191
endif()
9292
endmacro()
9393

94+
if(UNIX)
95+
include(CheckCSourceCompiles)
96+
check_c_source_compiles("
97+
#include <stdlib.h>
98+
int main(void)
99+
{
100+
__builtin_cpu_init();
101+
}" HAVE_CPU_INIT)
102+
if(NOT HAVE_CPU_INIT)
103+
check_include_file(sys/utsname.h HAVE_UTSNAME_H)
104+
check_symbol_exists(sysctlbyname sys/sysctl.h HAVE_SYSCTLBYNAME)
105+
endif()
106+
endif()
107+
94108
#
95109
# library : utils
96110
#
@@ -148,6 +162,15 @@ set_property(TARGET cpu_features PROPERTY POSITION_INDEPENDENT_CODE ${BUILD_PIC}
148162
target_include_directories(cpu_features
149163
PUBLIC $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/cpu_features>
150164
)
165+
if(HAVE_CPU_INIT)
166+
target_compile_definitions(cpu_features PRIVATE HAVE_CPU_INIT)
167+
endif()
168+
if(HAVE_UTSNAME_H)
169+
target_compile_definitions(cpu_features PRIVATE HAVE_UTSNAME_H)
170+
endif()
171+
if(HAVE_SYSCTLBYNAME)
172+
target_compile_definitions(cpu_features PRIVATE HAVE_SYSCTLBYNAME)
173+
endif()
151174
add_library(CpuFeature::cpu_features ALIAS cpu_features)
152175

153176
#

src/cpuinfo_x86.c

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,6 +1047,24 @@ typedef struct {
10471047
bool have_avx512;
10481048
} OsSupport;
10491049

1050+
#if defined(CPU_FEATURES_COMPILER_CLANG) || defined(CPU_FEATURES_COMPILER_GCC)
1051+
#if defined(HAVE_CPU_INIT)
1052+
#include <stdlib.h>
1053+
#else
1054+
#include "internal/filesystem.h"
1055+
#include "internal/stack_line_reader.h"
1056+
#include "internal/string_view.h"
1057+
#if defined(HAVE_UTSNAME_H)
1058+
#include <sys/utsname.h>
1059+
#if defined(HAVE_SYSCTLBYNAME)
1060+
#include <sys/sysctl.h>
1061+
#endif
1062+
#endif
1063+
#endif
1064+
#elif defined(CPU_FEATURES_COMPILER_MSC)
1065+
#include <windows.h>
1066+
#endif
1067+
10501068
// Reference https://en.wikipedia.org/wiki/CPUID.
10511069
static void ParseCpuId(const uint32_t max_cpuid_leaf, X86Info* info, OsSupport* os_support) {
10521070
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*
10551073
const bool have_xsave = IsBitSet(leaf_1.ecx, 26);
10561074
const bool have_osxsave = IsBitSet(leaf_1.ecx, 27);
10571075
const uint32_t xcr0_eax = (have_xsave && have_osxsave) ? GetXCR0Eax() : 0;
1058-
os_support->have_sse = HasXmmOsXSave(xcr0_eax);
1059-
os_support->have_avx = HasYmmOsXSave(xcr0_eax);
1060-
os_support->have_avx512 = HasZmmOsXSave(xcr0_eax);
1076+
if (xcr0_eax) {
1077+
os_support->have_sse = HasXmmOsXSave(xcr0_eax);
1078+
os_support->have_avx = HasYmmOsXSave(xcr0_eax);
1079+
os_support->have_avx512 = HasZmmOsXSave(xcr0_eax);
1080+
} else {
1081+
#if defined(CPU_FEATURES_COMPILER_CLANG) || defined(CPU_FEATURES_COMPILER_GCC)
1082+
#if defined(HAVE_CPU_INIT)
1083+
__builtin_cpu_init();
1084+
os_support->have_sse = __builtin_cpu_supports("sse");
1085+
#else
1086+
#if defined(HAVE_UTSNAME_H)
1087+
struct utsname buf;
1088+
uname(&buf);
1089+
if (strncmp(buf.sysname, "Darwin", sizeof(buf.sysname)) == 0) {
1090+
#if defined(HAVE_SYSCTLBYNAME)
1091+
int enabled, result;
1092+
size_t len = sizeof(enabled);
1093+
result = sysctlbyname("hw.optional.sse", &enabled, &len, NULL, 0);
1094+
if (result == 0) {
1095+
os_support->have_sse = enabled;
1096+
}
1097+
#endif
1098+
} else if (strncmp(buf.sysname, "Linux", sizeof(buf.sysname) == 0) {
1099+
const int fd = CpuFeatures_OpenFile("/proc/cpuinfo");
1100+
if (fd >= 0) {
1101+
StackLineReader reader;
1102+
StackLineReader_Initialize(&reader, fd);
1103+
for (;;) {
1104+
const LineResult result = StackLineReader_NextLine(&reader);
1105+
StringView line = result.line;
1106+
StringView key, value;
1107+
if (CpuFeatures_StringView_GetAttributeKeyValue(line, &key, &value)) {
1108+
if (CpuFeatures_StringView_IsEquals(key, str("flags"))) {
1109+
os_support->have_sse = CpuFeatures_StringView_HasWord(value, "sse");
1110+
break;
1111+
}
1112+
}
1113+
if (result.eof) {
1114+
break;
1115+
}
1116+
}
1117+
CpuFeatures_CloseFile(fd);
1118+
}
1119+
}
1120+
#endif
1121+
#endif
1122+
#elif defined(CPU_FEATURES_COMPILER_MSC)
1123+
os_support->have_sse = IsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE);
1124+
#endif
1125+
}
10611126

10621127
const uint32_t family = ExtractBitRange(leaf_1.eax, 11, 8);
10631128
const uint32_t extended_family = ExtractBitRange(leaf_1.eax, 27, 20);

0 commit comments

Comments
 (0)