summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2016-03-07 16:45:32 +0100
committerRobin Gareus <robin@gareus.org>2016-03-08 14:54:41 +0100
commit5a41b86028cd5068d8e74d7481dca60aefeff75d (patch)
treeeec7e38872e8c2cb4af9c62ca33069dcf04dd0fc /libs
parentd35e75554f1f88fac998314a78b03e554a4ded0a (diff)
fix __cpuid() on x86
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.
Diffstat (limited to 'libs')
-rw-r--r--libs/pbd/fpu.cc23
1 files changed, 8 insertions, 15 deletions
diff --git a/libs/pbd/fpu.cc b/libs/pbd/fpu.cc
index fe2a329439..c72f65d303 100644
--- a/libs/pbd/fpu.cc
+++ b/libs/pbd/fpu.cc
@@ -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 */