@@ -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.
10511069static 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