Commit edccdcb1 by H.J. Lu Committed by H.J. Lu

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
parent a9690009
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> 2006-12-02 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* doc/install.texi: Update recommended MPFR version. Remove * doc/install.texi: Update recommended MPFR version. Remove
......
...@@ -20,6 +20,8 @@ Boston, MA 02110-1301, USA. */ ...@@ -20,6 +20,8 @@ Boston, MA 02110-1301, USA. */
#include "config.h" #include "config.h"
#include "system.h" #include "system.h"
#include "coretypes.h"
#include "tm.h"
#include <stdlib.h> #include <stdlib.h>
const char *host_detect_local_cpu (int argc, const char **argv); 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); ...@@ -37,6 +39,7 @@ const char *host_detect_local_cpu (int argc, const char **argv);
#define bit_SSE2 (1 << 26) #define bit_SSE2 (1 << 26)
#define bit_SSE3 (1 << 0) #define bit_SSE3 (1 << 0)
#define bit_SSSE3 (1 << 9)
#define bit_CMPXCHG16B (1 << 13) #define bit_CMPXCHG16B (1 << 13)
#define bit_3DNOW (1 << 31) #define bit_3DNOW (1 << 31)
...@@ -57,19 +60,24 @@ const char *host_detect_local_cpu (int argc, const char **argv); ...@@ -57,19 +60,24 @@ const char *host_detect_local_cpu (int argc, const char **argv);
in the spec. */ in the spec. */
const char *host_detect_local_cpu (int argc, const char **argv) 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 eax, ebx, ecx, edx;
unsigned int max_level; unsigned int max_level;
unsigned int vendor; unsigned int vendor;
unsigned int ext_level; unsigned int ext_level;
unsigned char has_mmx = 0, has_3dnow = 0, has_3dnowp = 0, has_sse = 0; 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_sse2 = 0, has_sse3 = 0, has_ssse3 = 0, has_cmov = 0;
unsigned char has_longmode = 0; unsigned char has_longmode = 0, has_cmpxchg8b = 0;
unsigned char is_amd = 0; unsigned char is_amd = 0;
unsigned int family = 0; unsigned int family = 0;
if (argc < 1 bool arch;
|| (strcmp (argv[0], "arch")
&& strcmp (argv[0], "tune"))) if (argc < 1)
return NULL;
arch = strcmp (argv[0], "arch") == 0;
if (!arch && strcmp (argv[0], "tune"))
return NULL; return NULL;
#ifndef __x86_64__ #ifndef __x86_64__
...@@ -83,7 +91,7 @@ const char *host_detect_local_cpu (int argc, const char **argv) ...@@ -83,7 +91,7 @@ const char *host_detect_local_cpu (int argc, const char **argv)
goto done; goto done;
#endif #endif
cpu = "i586"; processor = PROCESSOR_PENTIUM;
/* Check the highest input value for eax. */ /* Check the highest input value for eax. */
cpuid (0, eax, ebx, ecx, edx); cpuid (0, eax, ebx, ecx, edx);
...@@ -94,11 +102,13 @@ const char *host_detect_local_cpu (int argc, const char **argv) ...@@ -94,11 +102,13 @@ const char *host_detect_local_cpu (int argc, const char **argv)
goto done; goto done;
cpuid (1, eax, ebx, ecx, edx); cpuid (1, eax, ebx, ecx, edx);
has_cmpxchg8b = !!(edx & bit_CMPXCHG8B);
has_cmov = !!(edx & bit_CMOV); has_cmov = !!(edx & bit_CMOV);
has_mmx = !!(edx & bit_MMX); has_mmx = !!(edx & bit_MMX);
has_sse = !!(edx & bit_SSE); has_sse = !!(edx & bit_SSE);
has_sse2 = !!(edx & bit_SSE2); has_sse2 = !!(edx & bit_SSE2);
has_sse3 = !!(ecx & bit_SSE3); has_sse3 = !!(ecx & bit_SSE3);
has_ssse3 = !!(ecx & bit_SSSE3);
/* We don't care for extended family. */ /* We don't care for extended family. */
family = (eax >> 8) & ~(1 << 4); family = (eax >> 8) & ~(1 << 4);
...@@ -117,37 +127,129 @@ const char *host_detect_local_cpu (int argc, const char **argv) ...@@ -117,37 +127,129 @@ const char *host_detect_local_cpu (int argc, const char **argv)
if (is_amd) if (is_amd)
{ {
if (has_mmx) if (has_mmx)
cpu = "k6"; processor = PROCESSOR_K6;
if (has_3dnow)
cpu = "k6-3";
if (has_3dnowp) if (has_3dnowp)
cpu = "athlon"; processor = PROCESSOR_ATHLON;
if (has_sse)
cpu = "athlon-4";
if (has_sse2 || has_longmode) if (has_sse2 || has_longmode)
cpu = "k8"; processor = PROCESSOR_K8;
} }
else else
{ {
if (family == 5) 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) if (has_mmx)
cpu = "pentium-mmx"; cpu = "pentium-mmx";
else
cpu = "pentium";
break;
case PROCESSOR_PENTIUMPRO:
if (has_longmode)
{
/* It is Core 2 Duo. */
cpu = "core2";
}
else
{
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) else if (has_mmx)
{
/* It is Pentium II. */
cpu = "pentium2"; cpu = "pentium2";
if (has_sse) }
cpu = "pentium3"; else
if (has_sse2)
{ {
if (family == 6) /* Default to Pentium Pro. */
/* It's a pentiumpro with sse2 --> pentium-m */ cpu = "pentiumpro";
cpu = "pentium-m"; }
}
else else
/* Would have to look at extended family, but it's at least {
an pentium4 core. */ /* For -mtune, we default to -mtune=generic. */
cpu = "pentium4"; 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_sse3)
{ {
if (has_longmode) if (has_longmode)
...@@ -155,6 +257,22 @@ const char *host_detect_local_cpu (int argc, const char **argv) ...@@ -155,6 +257,22 @@ const char *host_detect_local_cpu (int argc, const char **argv)
else else
cpu = "prescott"; 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: done:
...@@ -165,6 +283,25 @@ done: ...@@ -165,6 +283,25 @@ done:
default value. */ default value. */
const char *host_detect_local_cpu (int argc, const char **argv) 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 */ #endif /* GCC_VERSION */
...@@ -356,7 +356,8 @@ extern const char *host_detect_local_cpu (int argc, const char **argv); ...@@ -356,7 +356,8 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
#define CC1_CPU_SPEC CC1_CPU_SPEC_1 #define CC1_CPU_SPEC CC1_CPU_SPEC_1
#else #else
#define CC1_CPU_SPEC CC1_CPU_SPEC_1 \ #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)}" %{mtune=native:%<mtune=native %:local_cpu_detect(tune)}"
#endif #endif
#endif #endif
......
driver-i386.o : $(srcdir)/config/i386/driver-i386.c \ 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) $< $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment