From 03eaf9b461454e79bb4d9645cfcd093e4a32af8d Mon Sep 17 00:00:00 2001 From: historic_bruno Date: Sat, 18 Oct 2014 03:07:24 +0000 Subject: [PATCH] Fixes cpuid to work with i386 CPUs and PIE/PIC, based on old GCC cpuid.h source and patch by pstumpf, fixes #2675 This was SVN commit r15886. --- source/lib/sysdep/arch/x86_x64/x86_x64.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/source/lib/sysdep/arch/x86_x64/x86_x64.cpp b/source/lib/sysdep/arch/x86_x64/x86_x64.cpp index 789cc89c85..5cca3d0ac9 100644 --- a/source/lib/sysdep/arch/x86_x64/x86_x64.cpp +++ b/source/lib/sysdep/arch/x86_x64/x86_x64.cpp @@ -49,10 +49,21 @@ namespace x86_x64 { #if defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 150030729 // VC10+ and VC9 SP1: __cpuidex is already available #elif GCC_VERSION -# define __cpuidex(regsArray, level, index)\ - __asm__ __volatile__ ("cpuid"\ - : "=a" ((regsArray)[0]), "=b" ((regsArray)[1]), "=c" ((regsArray)[2]), "=d" ((regsArray)[3])\ - : "0" (level), "2" (index)); +// Adapted from GPLv2 version of GCC's cpuid.h +# if ARCH_IA32 && defined(__PIC__) +// %ebx may be the PIC register +# define __cpuidex(regsArray, level, index)\ + __asm__ ("xchgl\t%%ebx, %1\n\t"\ + "cpuid\n\t"\ + "xchgl\t%%ebx, %1\n\t"\ + : "=a" ((regsArray)[0]), "=r" ((regsArray)[1]), "=c" ((regsArray)[2]), "=d" ((regsArray)[3])\ + : "0" (level), "2" (index)); +# else +# define __cpuidex(regsArray, level, index)\ + __asm__ ("cpuid\n\t"\ + : "=a" ((regsArray)[0]), "=b" ((regsArray)[1]), "=c" ((regsArray)[2]), "=d" ((regsArray)[3])\ + : "0" (level), "2" (index)); +# endif #else # error "compiler not supported" #endif