Workaround PIC limitations in cpuid.
authorIsaac Dunham <ibid.ag@gmail.com>
Thu, 28 Aug 2014 20:05:07 +0000 (13:05 -0700)
committerIsaac Dunham <ibid.ag@gmail.com>
Thu, 28 Aug 2014 20:05:07 +0000 (13:05 -0700)
cpuid uses register ebx, but ebx is reserved in PIC.
So save ebx, swap ebx & edi, and return edi.

Copied from Igor Pavlov's equivalent fix for 7zip (in CpuArch.c),
which is public domain and thus OK license-wise.

cpuid_x86.c

index 53016e1..f9df722 100644 (file)
 void cpuid(int op, int *eax, int *ebx, int *ecx, int *edx);
 #else
 static inline void cpuid(int op, int *eax, int *ebx, int *ecx, int *edx){
+#if defined(__i386__) && defined(__PIC__)
+  __asm__ __volatile__
+    ("mov %%ebx, %%edi;"
+     "cpuid;"
+     "xchgl %%ebx, %%edi;"
+     : "=a" (*eax), "=D" (*ebx), "=c" (*ecx), "=d" (*edx) : "a" (op) : "cc");
+#else
   __asm__ __volatile__
     ("cpuid": "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx) : "a" (op) : "cc");
-
+#endif
 }
 #endif