Fixed bug 2404 - CPU detection not working with MSVC on x64
authorSam Lantinga <slouken@libsdl.org>
Sat, 22 Feb 2014 19:10:45 -0800
changeset 8241 b6d5a589ce3f
parent 8240 334257cd613d
child 8242 f6a2b1a6932b
Fixed bug 2404 - CPU detection not working with MSVC on x64 Tiemo Jung All CPU detection functions SDL_Has* will return false, even if it is supported by the CPU, if SDL is compiled with MSVC and the target is x64. The reason for this is that 'CPU_haveCPUID' will return 0 and macro 'cpuid' in SDL_cpuinfo.c is the fallback implementation, which sets all params to zero. It is safe to assume that cpuid is supported on a CPU that runs windows x64, so CPU_haveCPUID can just return 1, and the empty macro can be replaced with a small wrap around the __cpuid intrinsic.
src/cpuinfo/SDL_cpuinfo.c
--- a/src/cpuinfo/SDL_cpuinfo.c	Sat Feb 22 18:01:18 2014 -0800
+++ b/src/cpuinfo/SDL_cpuinfo.c	Sat Feb 22 19:10:45 2014 -0800
@@ -98,7 +98,7 @@
     );
 #elif defined(__GNUC__) && defined(__x86_64__)
 /* Technically, if this is being compiled under __x86_64__ then it has 
-CPUid by definition.  But it's nice to be able to prove it.  :)      */
+   CPUid by definition.  But it's nice to be able to prove it.  :)      */
     __asm__ (
 "        pushfq                      # Get original EFLAGS             \n"
 "        popq    %%rax                                                 \n"
@@ -131,6 +131,8 @@
         mov     has_CPUID,1         ; We have CPUID support
 done:
     }
+#elif defined(_MSC_VER) && defined(_M_X64)
+    has_CPUID = 1;
 #elif defined(__sun) && defined(__i386)
     __asm (
 "       pushfl                 \n"
@@ -191,7 +193,17 @@
         __asm mov b, ebx \
         __asm mov c, ecx \
         __asm mov d, edx \
-    }
+}
+#elif defined(_MSC_VER) && defined(_M_X64)
+#define cpuid(func, a, b, c, d) \
+{ \
+    int CPUInfo[4]; \
+    __cpuid(CPUInfo, func); \
+    a = CPUInfo[0]; \
+    b = CPUInfo[1]; \
+    c = CPUInfo[2]; \
+    d = CPUInfo[3]; \
+}
 #else
 #define cpuid(func, a, b, c, d) \
     a = b = c = d = 0