From 712a92caa12fb55830dd0700fd0b94f478ada28e Mon Sep 17 00:00:00 2001 From: Ykkrosh Date: Sat, 5 Mar 2011 13:53:02 +0000 Subject: [PATCH] Save PIC register in cpuid() to fix "can't find a register in class 'BREG'" error in some versions of GCC This was SVN commit r9023. --- source/lib/sysdep/arch/x86_x64/x86_x64.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/source/lib/sysdep/arch/x86_x64/x86_x64.cpp b/source/lib/sysdep/arch/x86_x64/x86_x64.cpp index ca039421a8..be0c20775e 100644 --- a/source/lib/sysdep/arch/x86_x64/x86_x64.cpp +++ b/source/lib/sysdep/arch/x86_x64/x86_x64.cpp @@ -79,7 +79,24 @@ static void cpuid(x86_x64_CpuidRegs* regs) cassert(sizeof(*regs) == 4*sizeof(int)); __cpuidex((int*)regs, regs->eax, regs->ecx); #elif GCC_VERSION - __asm__ __volatile__ ("cpuid": "=a" (regs->eax), "=b" (regs->ebx), "=c" (regs->ecx), "=d" (regs->edx) : "a" (regs->eax), "c" (regs->ecx)); +// Need to preserve the PIC register (ebx/rbx) in case GCC is using it +# if ARCH_AMD64 + __asm__ __volatile__ ( + "pushq %%rbx\n" + "cpuid\n" + "movl %%ebx, %1\n" + "popq %%rbx\n" + : "=a" (regs->eax), "=m" (regs->ebx), "=c" (regs->ecx), "=d" (regs->edx) + : "a" (regs->eax), "c" (regs->ecx)); +# else + __asm__ __volatile__ ( + "pushl %%ebx\n" + "cpuid\n" + "movl %%ebx, %1\n" + "popl %%ebx\n" + : "=a" (regs->eax), "=m" (regs->ebx), "=c" (regs->ecx), "=d" (regs->edx) + : "a" (regs->eax), "c" (regs->ecx)); +# endif #else # if ARCH_AMD64 amd64_asm_cpuid(regs);