On Thu, Oct 16, 2014 at 12:25 PM, Uros Bizjak <ubiz...@gmail.com> wrote:
>>> >> Now that %ebx is also allocatable in PIC modes, we can cleanup >>> >> config/i386/cpuid considerably. I propose to remove all PIC related >>> >> specializations of __cpuid and __cpuid_count and protect the >>> >> compilation with "#if __GNUC__ >= 5". >>> >> >>> >> The only drawback would be that non-bootstrapped build with gcc < 5.0 >>> >> will ignore -march=native, but I think this should be acceptable. >>> > >>> > I'm worried about that. >>> > Can't you instead keep the current cpuid.h stuff as is, just add >>> > && __GNUC__ < 5 >>> > to that, so it treats GCC 5+ PIC as if __PIC__ wasn't defined? >>> > >>> > Or, at least use cpuid.h even for older GCC if __PIC__ is not defined >>> > (or __x86_64__ is defined and not medium/large PIC model)? >>> >>> Do we really care that much about non-bootstrapped build? I don't see >> >> At least on Linux, driver-i386.c should not be built with PIC normally, >> so at least changing >> #if __GNUC__ >= 5 >> to >> #if defined(__GNUC__) && (__GNUC__ >= 5 || !defined(__PIC__)) >> would limit the -march=native change for non-bootstrapped compilers to >> Darwin only (or what other targets use PIC by default?). > > Yes, this would work for me - the goal is to keep only one "universal" > __cpuid (and __cpuid_count) define, and the above condition fits this > goal. I have committed the attached patch to mainline SVN. 2014-10-17 Uros Bizjak <ubiz...@gmail.com> * config/i386/cpuid.h (__cpuid): Remove definitions that handle %ebx register in a special way. (__cpuid_count): Ditto. * config/i386/driver-i386.h: Protect with "#if defined(__GNUC__) && (__GNUC__ >= 5 || !defined(__PIC__))". (host_detect_local_cpu): Mention that GCC with non-fixed %ebx is required to compile the function. Bootstrapped and regression tested on x86_64-linux-gnu. Uros.
Index: config/i386/cpuid.h =================================================================== --- config/i386/cpuid.h (revision 216298) +++ config/i386/cpuid.h (working copy) @@ -146,56 +146,7 @@ #define signature_VORTEX_ecx 0x436f5320 #define signature_VORTEX_edx 0x36387865 -#if defined(__i386__) && defined(__PIC__) -/* %ebx may be the PIC register. */ -#if __GNUC__ >= 3 #define __cpuid(level, a, b, c, d) \ - __asm__ ("xchg{l}\t{%%}ebx, %k1\n\t" \ - "cpuid\n\t" \ - "xchg{l}\t{%%}ebx, %k1\n\t" \ - : "=a" (a), "=&r" (b), "=c" (c), "=d" (d) \ - : "0" (level)) - -#define __cpuid_count(level, count, a, b, c, d) \ - __asm__ ("xchg{l}\t{%%}ebx, %k1\n\t" \ - "cpuid\n\t" \ - "xchg{l}\t{%%}ebx, %k1\n\t" \ - : "=a" (a), "=&r" (b), "=c" (c), "=d" (d) \ - : "0" (level), "2" (count)) -#else -/* Host GCCs older than 3.0 weren't supporting Intel asm syntax - nor alternatives in i386 code. */ -#define __cpuid(level, a, b, c, d) \ - __asm__ ("xchgl\t%%ebx, %k1\n\t" \ - "cpuid\n\t" \ - "xchgl\t%%ebx, %k1\n\t" \ - : "=a" (a), "=&r" (b), "=c" (c), "=d" (d) \ - : "0" (level)) - -#define __cpuid_count(level, count, a, b, c, d) \ - __asm__ ("xchgl\t%%ebx, %k1\n\t" \ - "cpuid\n\t" \ - "xchgl\t%%ebx, %k1\n\t" \ - : "=a" (a), "=&r" (b), "=c" (c), "=d" (d) \ - : "0" (level), "2" (count)) -#endif -#elif defined(__x86_64__) && (defined(__code_model_medium__) || defined(__code_model_large__)) && defined(__PIC__) -/* %rbx may be the PIC register. */ -#define __cpuid(level, a, b, c, d) \ - __asm__ ("xchg{q}\t{%%}rbx, %q1\n\t" \ - "cpuid\n\t" \ - "xchg{q}\t{%%}rbx, %q1\n\t" \ - : "=a" (a), "=&r" (b), "=c" (c), "=d" (d) \ - : "0" (level)) - -#define __cpuid_count(level, count, a, b, c, d) \ - __asm__ ("xchg{q}\t{%%}rbx, %q1\n\t" \ - "cpuid\n\t" \ - "xchg{q}\t{%%}rbx, %q1\n\t" \ - : "=a" (a), "=&r" (b), "=c" (c), "=d" (d) \ - : "0" (level), "2" (count)) -#else -#define __cpuid(level, a, b, c, d) \ __asm__ ("cpuid\n\t" \ : "=a" (a), "=b" (b), "=c" (c), "=d" (d) \ : "0" (level)) @@ -204,8 +155,8 @@ __asm__ ("cpuid\n\t" \ : "=a" (a), "=b" (b), "=c" (c), "=d" (d) \ : "0" (level), "2" (count)) -#endif + /* Return highest supported input value for cpuid instruction. ext can be either 0x0 or 0x8000000 to return highest supported value for basic or extended cpuid information. Function returns 0 if cpuid Index: config/i386/driver-i386.c =================================================================== --- config/i386/driver-i386.c (revision 216298) +++ config/i386/driver-i386.c (working copy) @@ -24,7 +24,7 @@ const char *host_detect_local_cpu (int argc, const char **argv); -#ifdef __GNUC__ +#if defined(__GNUC__) && (__GNUC__ >= 5 || !defined(__PIC__)) #include "cpuid.h" struct cache_desc @@ -942,9 +942,9 @@ } #else -/* If we aren't compiling with GCC then the driver will just ignore - -march and -mtune "native" target and will leave to the newly - built compiler to generate code for its default target. */ +/* If we are compiling with GCC where %EBX register is fixed, then the + driver will just ignore -march and -mtune "native" target and will leave + to the newly built compiler to generate code for its default target. */ const char *host_detect_local_cpu (int, const char **) {