From: H.J. Lu Date: Sat, 2 Dec 2006 22:18:25 +0000 (+0000) Subject: re PR target/30040 (-mtune=native is wrong for Core 2 Duo and Core Duo) X-Git-Tag: releases/gcc-4.3.0~8168 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=edccdcb19865cdc271cf2eead76d8aebc7ca89d3;p=thirdparty%2Fgcc.git re PR target/30040 (-mtune=native is wrong for Core 2 Duo and Core Duo) 2006-12-02 H.J. Lu PR target/30040 * config/i386/driver-i386.c: Include "coretypes.h" and "tm.h". (bit_SSSE3): New. (host_detect_local_cpu): Check -mtune= vs. -march=. Rewrite processor detection. * config/i386/i386.h (CC1_CPU_SPEC): Add -mtune=native for -march=native if there is no -mtune=*. * config/i386/x-i386 (driver-i386.o): Also depend on $(TM_H) coretypes.h. From-SVN: r119454 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6601a1d7c1db..eebf3f81cf04 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2006-12-02 H.J. Lu + + PR target/30040 + * config/i386/driver-i386.c: Include "coretypes.h" and "tm.h". + (bit_SSSE3): New. + (host_detect_local_cpu): Check -mtune= vs. -march=. Rewrite + processor detection. + + * config/i386/i386.h (CC1_CPU_SPEC): Add -mtune=native for + -march=native if there is no -mtune=*. + + * config/i386/x-i386 (driver-i386.o): Also depend on $(TM_H) + coretypes.h. + 2006-12-02 Kaveh R. Ghazi * doc/install.texi: Update recommended MPFR version. Remove diff --git a/gcc/config/i386/driver-i386.c b/gcc/config/i386/driver-i386.c index 6767997a091d..d623c2c7b104 100644 --- a/gcc/config/i386/driver-i386.c +++ b/gcc/config/i386/driver-i386.c @@ -20,6 +20,8 @@ Boston, MA 02110-1301, USA. */ #include "config.h" #include "system.h" +#include "coretypes.h" +#include "tm.h" #include const char *host_detect_local_cpu (int argc, const char **argv); @@ -37,6 +39,7 @@ const char *host_detect_local_cpu (int argc, const char **argv); #define bit_SSE2 (1 << 26) #define bit_SSE3 (1 << 0) +#define bit_SSSE3 (1 << 9) #define bit_CMPXCHG16B (1 << 13) #define bit_3DNOW (1 << 31) @@ -57,19 +60,24 @@ const char *host_detect_local_cpu (int argc, const char **argv); in the spec. */ const char *host_detect_local_cpu (int argc, const char **argv) { - const char *cpu = "i386"; + const char *cpu = NULL; + enum processor_type processor = PROCESSOR_I386; unsigned int eax, ebx, ecx, edx; unsigned int max_level; unsigned int vendor; unsigned int ext_level; unsigned char has_mmx = 0, has_3dnow = 0, has_3dnowp = 0, has_sse = 0; - unsigned char has_sse2 = 0, has_sse3 = 0, has_cmov = 0; - unsigned char has_longmode = 0; + unsigned char has_sse2 = 0, has_sse3 = 0, has_ssse3 = 0, has_cmov = 0; + unsigned char has_longmode = 0, has_cmpxchg8b = 0; unsigned char is_amd = 0; unsigned int family = 0; - if (argc < 1 - || (strcmp (argv[0], "arch") - && strcmp (argv[0], "tune"))) + bool arch; + + if (argc < 1) + return NULL; + + arch = strcmp (argv[0], "arch") == 0; + if (!arch && strcmp (argv[0], "tune")) return NULL; #ifndef __x86_64__ @@ -83,7 +91,7 @@ const char *host_detect_local_cpu (int argc, const char **argv) goto done; #endif - cpu = "i586"; + processor = PROCESSOR_PENTIUM; /* Check the highest input value for eax. */ cpuid (0, eax, ebx, ecx, edx); @@ -94,11 +102,13 @@ const char *host_detect_local_cpu (int argc, const char **argv) goto done; cpuid (1, eax, ebx, ecx, edx); + has_cmpxchg8b = !!(edx & bit_CMPXCHG8B); has_cmov = !!(edx & bit_CMOV); has_mmx = !!(edx & bit_MMX); has_sse = !!(edx & bit_SSE); has_sse2 = !!(edx & bit_SSE2); has_sse3 = !!(ecx & bit_SSE3); + has_ssse3 = !!(ecx & bit_SSSE3); /* We don't care for extended family. */ family = (eax >> 8) & ~(1 << 4); @@ -117,44 +127,152 @@ const char *host_detect_local_cpu (int argc, const char **argv) if (is_amd) { if (has_mmx) - cpu = "k6"; - if (has_3dnow) - cpu = "k6-3"; + processor = PROCESSOR_K6; if (has_3dnowp) - cpu = "athlon"; - if (has_sse) - cpu = "athlon-4"; + processor = PROCESSOR_ATHLON; if (has_sse2 || has_longmode) - cpu = "k8"; + processor = PROCESSOR_K8; } else { - if (family == 5) - { - if (has_mmx) - cpu = "pentium-mmx"; + switch (family) + { + case 5: + /* Default is PROCESSOR_PENTIUM. */ + break; + case 6: + processor = PROCESSOR_PENTIUMPRO; + break; + case 15: + processor = PROCESSOR_PENTIUM4; + break; + default: + /* We have no idea. Use something reasonable. */ + if (arch) + { + if (has_ssse3) + cpu = "core2"; + else if (has_sse3) + { + if (has_longmode) + cpu = "nocona"; + else + cpu = "prescott"; + } + else if (has_sse2) + cpu = "pentium4"; + else if (has_cmov) + cpu = "pentiumpro"; + else if (has_mmx) + cpu = "pentium-mmx"; + else if (has_cmpxchg8b) + cpu = "pentium"; + else + cpu = "i386"; + } + else + cpu = "generic"; + goto done; + break; + } + } + + switch (processor) + { + case PROCESSOR_I386: + cpu = "i386"; + break; + case PROCESSOR_I486: + cpu = "i486"; + break; + case PROCESSOR_PENTIUM: + if (has_mmx) + cpu = "pentium-mmx"; + else + cpu = "pentium"; + break; + case PROCESSOR_PENTIUMPRO: + if (has_longmode) + { + /* It is Core 2 Duo. */ + cpu = "core2"; } - else if (has_mmx) - cpu = "pentium2"; - if (has_sse) - cpu = "pentium3"; - if (has_sse2) + else { - if (family == 6) - /* It's a pentiumpro with sse2 --> pentium-m */ - cpu = "pentium-m"; + if (arch) + { + if (has_sse3) + { + /* It is Core Duo. */ + cpu = "prescott"; + } + else if (has_sse2) + { + /* It is Pentium M. */ + cpu = "pentium4"; + } + else if (has_sse) + { + /* It is Pentium III. */ + cpu = "pentium3"; + } + else if (has_mmx) + { + /* It is Pentium II. */ + cpu = "pentium2"; + } + else + { + /* Default to Pentium Pro. */ + cpu = "pentiumpro"; + } + } else - /* Would have to look at extended family, but it's at least - an pentium4 core. */ - cpu = "pentium4"; + { + /* For -mtune, we default to -mtune=generic. */ + cpu = "generic"; + } } + break; + case PROCESSOR_GEODE: + cpu = "geode"; + break; + case PROCESSOR_K6: + if (has_3dnow) + cpu = "k6-3"; + else + cpu = "k6"; + break; + case PROCESSOR_ATHLON: + if (has_sse) + cpu = "athlon-4"; + else + cpu = "athlon"; + break; + case PROCESSOR_PENTIUM4: if (has_sse3) - { + { if (has_longmode) cpu = "nocona"; - else - cpu = "prescott"; + else + cpu = "prescott"; } + else + cpu = "pentium4"; + break; + case PROCESSOR_K8: + cpu = "k8"; + break; + case PROCESSOR_NOCONA: + cpu = "nocona"; + break; + case PROCESSOR_GENERIC32: + case PROCESSOR_GENERIC64: + cpu = "generic"; + break; + default: + abort (); + break; } done: @@ -165,6 +283,25 @@ done: default value. */ const char *host_detect_local_cpu (int argc, const char **argv) { - return concat ("-m", argv[0], "=i386", NULL); + const char *cpu; + bool arch; + + if (argc < 1) + return NULL; + + arch = strcmp (argv[0], "arch") == 0; + if (!arch && strcmp (argv[0], "tune")) + return NULL; + + if (arch) + { + /* FIXME: i386 is wrong for 64bit compiler. How can we tell if + we are generating 64bit or 32bit code? */ + cpu = "i386"; + } + else + cpu = "generic"; + + return concat ("-m", argv[0], "=", cpu, NULL); } #endif /* GCC_VERSION */ diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 14de5d848d69..78b963b7ab26 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -356,7 +356,8 @@ extern const char *host_detect_local_cpu (int argc, const char **argv); #define CC1_CPU_SPEC CC1_CPU_SPEC_1 #else #define CC1_CPU_SPEC CC1_CPU_SPEC_1 \ -"%{march=native:%