aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2014-08-11 14:19:15 -0700
committerChris Robinson <[email protected]>2014-08-11 14:19:15 -0700
commit74c8de6372bc84916551a6685f337e69017eb239 (patch)
treea2c1cd64d5cf67b6c6256f13fdec4942aa4b1f3b
parente3ee534c3961c4a7c9961019a242693e0da402ef (diff)
Try the __cpuid intrinsic if GCC's __get_cpuid isn't available
-rw-r--r--Alc/helpers.c52
-rw-r--r--CMakeLists.txt11
-rw-r--r--config.h.in6
3 files changed, 59 insertions, 10 deletions
diff --git a/Alc/helpers.c b/Alc/helpers.c
index 22e99d7e..90419c17 100644
--- a/Alc/helpers.c
+++ b/Alc/helpers.c
@@ -66,6 +66,9 @@ DEFINE_DEVPROPKEY(DEVPKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80,
#ifdef HAVE_DLFCN_H
#include <dlfcn.h>
#endif
+#ifdef HAVE_INTRIN_H
+#include <intrin.h>
+#endif
#ifdef HAVE_CPUID_H
#include <cpuid.h>
#endif
@@ -147,19 +150,48 @@ void FillCPUCaps(ALuint capfilter)
}
}
}
-#elif defined(HAVE_WINDOWS_H)
- HMODULE k32 = GetModuleHandleA("kernel32.dll");
- BOOL (WINAPI*IsProcessorFeaturePresent)(DWORD ProcessorFeature);
- IsProcessorFeaturePresent = (BOOL(WINAPI*)(DWORD))GetProcAddress(k32, "IsProcessorFeaturePresent");
- if(!IsProcessorFeaturePresent)
- ERR("IsProcessorFeaturePresent not available; CPU caps not detected\n");
+#elif defined(HAVE_CPUID_INTRINSIC) && (defined(__i386__) || defined(__x86_64__) || \
+ defined(_M_IX86) || defined(_M_X64))
+ union {
+ int regs[4];
+ char str[sizeof(int[4])];
+ } cpuinf[3];
+
+ (__cpuid)(cpuinf[0].regs, 0);
+ if(cpuinf[0].regs[0] == 0)
+ ERR("Failed to get CPUID\n");
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;
- if(IsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE))
- caps |= CPU_CAP_SSE2;
+ (__cpuid)(cpuinf[0].regs, 0x80000002);
+ (__cpuid)(cpuinf[1].regs, 0x80000003);
+ (__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
diff --git a/CMakeLists.txt b/CMakeLists.txt
index cbb6844b..f1de92d6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -351,6 +351,7 @@ CHECK_INCLUDE_FILE(ftw.h HAVE_FTW_H)
CHECK_INCLUDE_FILE(io.h HAVE_IO_H)
CHECK_INCLUDE_FILE(strings.h HAVE_STRINGS_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(fenv.h HAVE_FENV_H)
CHECK_INCLUDE_FILE(float.h HAVE_FLOAT_H)
@@ -369,6 +370,16 @@ IF(HAVE_CPUID_H)
}" HAVE_GCC_GET_CPUID)
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
CHECK_LIBRARY_EXISTS(m pow "" HAVE_LIBM)
IF(HAVE_LIBM)
diff --git a/config.h.in b/config.h.in
index 27184824..af0d8bfd 100644
--- a/config.h.in
+++ b/config.h.in
@@ -148,6 +148,9 @@
/* Define if we have cpuid.h */
#cmakedefine HAVE_CPUID_H
+/* Define if we have intrin.h */
+#cmakedefine HAVE_INTRIN_H
+
/* Define if we have sys/sysconf.h */
#cmakedefine HAVE_SYS_SYSCONF_H
@@ -169,6 +172,9 @@
/* Define if we have GCC's __get_cpuid() */
#cmakedefine HAVE_GCC_GET_CPUID
+/* Define if we have the __cpuid() intrinsic */
+#cmakedefine HAVE_CPUID_INTRINSIC
+
/* Define if we have _controlfp() */
#cmakedefine HAVE__CONTROLFP