Try the __cpuid intrinsic if GCC's __get_cpuid isn't available

This commit is contained in:
Chris Robinson 2014-08-11 14:19:15 -07:00
parent e3ee534c39
commit 74c8de6372
3 changed files with 59 additions and 10 deletions

View File

@ -66,6 +66,9 @@ DEFINE_DEVPROPKEY(DEVPKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80,
#ifdef HAVE_DLFCN_H #ifdef HAVE_DLFCN_H
#include <dlfcn.h> #include <dlfcn.h>
#endif #endif
#ifdef HAVE_INTRIN_H
#include <intrin.h>
#endif
#ifdef HAVE_CPUID_H #ifdef HAVE_CPUID_H
#include <cpuid.h> #include <cpuid.h>
#endif #endif
@ -147,19 +150,48 @@ void FillCPUCaps(ALuint capfilter)
} }
} }
} }
#elif defined(HAVE_WINDOWS_H) #elif defined(HAVE_CPUID_INTRINSIC) && (defined(__i386__) || defined(__x86_64__) || \
HMODULE k32 = GetModuleHandleA("kernel32.dll"); defined(_M_IX86) || defined(_M_X64))
BOOL (WINAPI*IsProcessorFeaturePresent)(DWORD ProcessorFeature); union {
IsProcessorFeaturePresent = (BOOL(WINAPI*)(DWORD))GetProcAddress(k32, "IsProcessorFeaturePresent"); int regs[4];
if(!IsProcessorFeaturePresent) char str[sizeof(int[4])];
ERR("IsProcessorFeaturePresent not available; CPU caps not detected\n"); } cpuinf[3];
(__cpuid)(cpuinf[0].regs, 0);
if(cpuinf[0].regs[0] == 0)
ERR("Failed to get CPUID\n");
else else
{ {
if(IsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE)) unsigned int maxfunc = cpuinf[0].regs[0];
unsigned int maxextfunc;
(__cpuid)(cpuinf[0].regs, 0x80000000);
maxextfunc = cpuinf[0].regs[0];
TRACE("Detected max CPUID function: 0x%x (ext. 0x%x)\n", maxfunc, maxextfunc);
TRACE("Vendor ID: \"%.4s%.4s%.4s\"\n", cpuinf[0].str+4, cpuinf[0].str+12, cpuinf[0].str+8);
if(maxextfunc >= 0x80000004)
{ {
caps |= CPU_CAP_SSE; (__cpuid)(cpuinf[0].regs, 0x80000002);
if(IsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE)) (__cpuid)(cpuinf[1].regs, 0x80000003);
caps |= CPU_CAP_SSE2; (__cpuid)(cpuinf[2].regs, 0x80000004);
TRACE("Name: \"%.16s%.16s%.16s\"\n", cpuinf[0].str, cpuinf[1].str, cpuinf[2].str);
}
if(maxfunc >= 1)
{
(__cpuid)(cpuinf[0].regs, 1);
if((cpuinf[0].regs[3]&(1<<25)))
{
caps |= CPU_CAP_SSE;
if((cpuinf[0].regs[3]&(1<<26)))
{
caps |= CPU_CAP_SSE2;
if((cpuinf[0].regs[2]&(1<<19)))
caps |= CPU_CAP_SSE4_1;
}
}
} }
} }
#endif #endif

View File

@ -351,6 +351,7 @@ CHECK_INCLUDE_FILE(ftw.h HAVE_FTW_H)
CHECK_INCLUDE_FILE(io.h HAVE_IO_H) CHECK_INCLUDE_FILE(io.h HAVE_IO_H)
CHECK_INCLUDE_FILE(strings.h HAVE_STRINGS_H) CHECK_INCLUDE_FILE(strings.h HAVE_STRINGS_H)
CHECK_INCLUDE_FILE(cpuid.h HAVE_CPUID_H) CHECK_INCLUDE_FILE(cpuid.h HAVE_CPUID_H)
CHECK_INCLUDE_FILE(intrin.h HAVE_INTRIN_H)
CHECK_INCLUDE_FILE(sys/sysconf.h HAVE_SYS_SYSCONF_H) CHECK_INCLUDE_FILE(sys/sysconf.h HAVE_SYS_SYSCONF_H)
CHECK_INCLUDE_FILE(fenv.h HAVE_FENV_H) CHECK_INCLUDE_FILE(fenv.h HAVE_FENV_H)
CHECK_INCLUDE_FILE(float.h HAVE_FLOAT_H) CHECK_INCLUDE_FILE(float.h HAVE_FLOAT_H)
@ -369,6 +370,16 @@ IF(HAVE_CPUID_H)
}" HAVE_GCC_GET_CPUID) }" HAVE_GCC_GET_CPUID)
ENDIF() ENDIF()
IF(HAVE_INTRIN_H)
CHECK_C_SOURCE_COMPILES("#include <intrin.h>
int main()
{
int regs[4];
__cpuid(regs, 0);
return regs[0];
}" HAVE_CPUID_INTRINSIC)
ENDIF()
# Some systems need libm for some of the following math functions to work # Some systems need libm for some of the following math functions to work
CHECK_LIBRARY_EXISTS(m pow "" HAVE_LIBM) CHECK_LIBRARY_EXISTS(m pow "" HAVE_LIBM)
IF(HAVE_LIBM) IF(HAVE_LIBM)

View File

@ -148,6 +148,9 @@
/* Define if we have cpuid.h */ /* Define if we have cpuid.h */
#cmakedefine HAVE_CPUID_H #cmakedefine HAVE_CPUID_H
/* Define if we have intrin.h */
#cmakedefine HAVE_INTRIN_H
/* Define if we have sys/sysconf.h */ /* Define if we have sys/sysconf.h */
#cmakedefine HAVE_SYS_SYSCONF_H #cmakedefine HAVE_SYS_SYSCONF_H
@ -169,6 +172,9 @@
/* Define if we have GCC's __get_cpuid() */ /* Define if we have GCC's __get_cpuid() */
#cmakedefine HAVE_GCC_GET_CPUID #cmakedefine HAVE_GCC_GET_CPUID
/* Define if we have the __cpuid() intrinsic */
#cmakedefine HAVE_CPUID_INTRINSIC
/* Define if we have _controlfp() */ /* Define if we have _controlfp() */
#cmakedefine HAVE__CONTROLFP #cmakedefine HAVE__CONTROLFP