chiark / gitweb /
Fix handling of cpuid and PIC on i386 systems
authornick.j.sanders <nick.j.sanders@93e54ea4-8218-11de-8aaf-8d8425684b44>
Mon, 7 Jan 2013 22:13:27 +0000 (22:13 +0000)
committernick.j.sanders <nick.j.sanders@93e54ea4-8218-11de-8aaf-8d8425684b44>
Mon, 7 Jan 2013 22:13:27 +0000 (22:13 +0000)
The current cpuid logic clobbers %ebx.  this is OK if the code is not PIC, but if you're building PIEs, it'll fail because %ebx is the PIC register and gcc doesn't let you clobber it.

Thanks to vapier@chromium.org

src/os.cc
src/worker.cc

index 944ff8851cf872fead5f58db70a6e079a78c9c25..225e86cac61ce3ff2b2332cca776c34b77d3b3ae 100644 (file)
--- a/src/os.cc
+++ b/src/os.cc
@@ -169,7 +169,16 @@ void OsLayer::GetFeatures() {
   // http://www.sandpile.org/ia32/cpuid.htm
   int ax, bx, cx, dx;
   __asm__ __volatile__ (
-      "cpuid": "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx) : "a" (1));
+# if defined(STRESSAPPTEST_CPU_I686) && defined(__PIC__)
+      "xchg %%ebx, %%esi;"
+      "cpuid;"
+      "xchg %%esi, %%ebx;"
+      : "=S" (bx),
+# else
+      "cpuid;"
+      : "=b" (bx),
+# endif
+        "=a" (ax), "=c" (cx), "=d" (dx) : "a" (1));
   has_clflush_ = (dx >> 19) & 1;
   has_sse2_ = (dx >> 26) & 1;
 
index dcf4dcb6e6370ab18cfab6eafec1c21c64e41e9b..eddea6c12bb38a1ea6a3663eb803d047be94ef02 100644 (file)
@@ -82,7 +82,17 @@ namespace {
   inline int apicid(void) {
     int cpu;
 #if defined(STRESSAPPTEST_CPU_X86_64) || defined(STRESSAPPTEST_CPU_I686)
-    __asm __volatile("cpuid" : "=b" (cpu) : "a" (1) : "cx", "dx");
+    __asm__ __volatile__ (
+# if defined(STRESSAPPTEST_CPU_I686) && defined(__PIC__)
+        "xchg %%ebx, %%esi;"
+        "cpuid;"
+        "xchg %%esi, %%ebx;"
+        : "=S" (cpu)
+# else
+        "cpuid;"
+        : "=b" (cpu)
+# endif
+        : "a" (1) : "cx", "dx");
 #elif defined(STRESSAPPTEST_CPU_ARMV7A)
   #warning "Unsupported CPU type ARMV7A: unable to determine core ID."
     cpu = 0;