aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorH.J. Lu <hongjiu.lu@intel.com>2006-12-02 22:18:25 +0000
committerH.J. Lu <hjl@gcc.gnu.org>2006-12-02 14:18:25 -0800
commitedccdcb19865cdc271cf2eead76d8aebc7ca89d3 (patch)
tree9b835745a452dc93b18173007faa8ff798b06f07 /gcc
parenta9690009903e4d8df766361db87da3098f4aa42f (diff)
downloadgcc-edccdcb19865cdc271cf2eead76d8aebc7ca89d3.zip
gcc-edccdcb19865cdc271cf2eead76d8aebc7ca89d3.tar.gz
gcc-edccdcb19865cdc271cf2eead76d8aebc7ca89d3.tar.bz2
re PR target/30040 (-mtune=native is wrong for Core 2 Duo and Core Duo)
2006-12-02 H.J. Lu <hongjiu.lu@intel.com> 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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/config/i386/driver-i386.c203
-rw-r--r--gcc/config/i386/i386.h3
-rw-r--r--gcc/config/i386/x-i3862
4 files changed, 187 insertions, 35 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6601a1d..eebf3f8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+2006-12-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ 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 <ghazi@caip.rutgers.edu>
* 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 6767997..d623c2c 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 <stdlib.h>
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 14de5d8..78b963b 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:%<march=native %:local_cpu_detect(arch)} \
+"%{march=native:%<march=native %:local_cpu_detect(arch) \
+ %{!mtune=*:%<mtune=native %:local_cpu_detect(tune)}} \
%{mtune=native:%<mtune=native %:local_cpu_detect(tune)}"
#endif
#endif
diff --git a/gcc/config/i386/x-i386 b/gcc/config/i386/x-i386
index 2c35e5b..e156bcd 100644
--- a/gcc/config/i386/x-i386
+++ b/gcc/config/i386/x-i386
@@ -1,3 +1,3 @@
driver-i386.o : $(srcdir)/config/i386/driver-i386.c \
- $(CONFIG_H) $(SYSTEM_H)
+ $(CONFIG_H) $(SYSTEM_H) $(TM_H) coretypes.h
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<