fix __cpuid() on x86
authorFlorian Weimer <fweimer@redhat.com>
Mon, 7 Mar 2016 15:45:32 +0000 (16:45 +0100)
committerRobin Gareus <robin@gareus.org>
Tue, 8 Mar 2016 13:54:41 +0000 (14:54 +0100)
The previous version used memory operands that gcc (probably dependent
on optimization flags and/or version) could address relative to the
stack pointer, but pushing %ebx onto the stack changed it. Here, the
address of the regs array is put into %esi and the individual members
are written into directly.

libs/pbd/fpu.cc

index fe2a3294392ea0735fb81a4d99477e5dc660b5b3..c72f65d303ce85e4c92e0995b9a83c4a4c10fddc 100644 (file)
@@ -48,32 +48,25 @@ FPU* FPU::_instance (0);
 static void
 __cpuid(int regs[4], int cpuid_leaf)
 {
-        int eax, ebx, ecx, edx;
         asm volatile (
 #if defined(__i386__)
                "pushl %%ebx;\n\t"
 #endif
-               "movl %4, %%eax;\n\t"
                "cpuid;\n\t"
-               "movl %%eax, %0;\n\t"
-               "movl %%ebx, %1;\n\t"
-               "movl %%ecx, %2;\n\t"
-               "movl %%edx, %3;\n\t"
+               "movl %%eax, (%1);\n\t"
+               "movl %%ebx, 4(%1);\n\t"
+               "movl %%ecx, 8(%1);\n\t"
+               "movl %%edx, 12(%1);\n\t"
 #if defined(__i386__)
                "popl %%ebx;\n\t"
 #endif
-               :"=m" (eax), "=m" (ebx), "=m" (ecx), "=m" (edx)
-               :"r" (cpuid_leaf)
-               :"%eax",
+               :"=a" (cpuid_leaf) /* %eax clobbered by CPUID */
+               :"S" (regs), "a" (cpuid_leaf)
+               :
 #if !defined(__i386__)
                 "%ebx",
 #endif
-                "%ecx", "%edx");
-
-        regs[0] = eax;
-        regs[1] = ebx;
-        regs[2] = ecx;
-        regs[3] = edx;
+                "%ecx", "%edx", "memory");
 }
 
 #endif /* !PLATFORM_WINDOWS */