This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: PATCH: PR target/30040: -mtune=native is wrong on Core 2 Duo and Core Duo


On Sat, Dec 02, 2006 at 10:44:14AM -0700, Roger Sayle wrote:
> 
> Hi HJ,
> 
> On Fri, 1 Dec 2006, H. J. Lu wrote:
> > 2006-12-01  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=*.
> 
> This is OK for mainline.  Thanks.
> 

I checked it in. I added

	* config/i386/x-i386 (driver-i386.o): Also depend on $(TM_H)
	coretypes.h.

for make depedency. Here is the backported patch for 4.2. Tested on
Linux/x86 and Linux/x86-64.

Thanks.

H.J.
----
2006-12-02  H.J. Lu  <hongjiu.lu@intel.com>

	Backport from mainline:
	2006-12-02  H.J. Lu  <hongjiu.lu@intel.com>

	PR target/30040
	* config/i386/driver-i386.c: Include "coretypes.h" and "tm.h".
	(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.

--- gcc/config/i386/driver-i386.c.native	2006-11-18 06:26:01.000000000 -0800
+++ gcc/config/i386/driver-i386.c	2006-12-02 08:17:02.000000000 -0800
@@ -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);
@@ -57,19 +59,24 @@ const char *host_detect_local_cpu (int a
    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_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 +90,7 @@ const char *host_detect_local_cpu (int a
     goto done;
 #endif
 
-  cpu = "i586";
+  processor = PROCESSOR_PENTIUM;
 
   /* Check the highest input value for eax.  */
   cpuid (0, eax, ebx, ecx, edx);
@@ -94,6 +101,7 @@ const char *host_detect_local_cpu (int a
     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);
@@ -117,44 +125,147 @@ const char *host_detect_local_cpu (int a
   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_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;
 	}
-      else if (has_mmx)
-        cpu = "pentium2";
-      if (has_sse)
-        cpu = "pentium3";
-      if (has_sse2)
+    }
+
+  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 (arch)
 	{
-	  if (family == 6)
-	    /* It's a pentiumpro with sse2 --> pentium-m */
-            cpu = "pentium-m";
+	  if (has_sse3)
+	    {
+	      if (has_longmode)
+		{
+		  /* It is Core 2 Duo.  */
+		  cpu = "nocona";
+		}
+	      else
+		{
+		  /* 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
-	    /* Would have to look at extended family, but it's at least
-	       an pentium4 core.  */
-	    cpu = "pentium4";
+	    {
+	      /* Default to Pentium Pro.  */
+	      cpu = "pentiumpro";
+	    }
+	}
+      else
+	{
+	  /* For -mtune, we default to -mtune=generic.  */
+	  cpu = "generic";
 	}
+      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 +276,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 */
--- gcc/config/i386/i386.h.native	2006-12-02 08:17:02.000000000 -0800
+++ gcc/config/i386/i386.h	2006-12-02 08:17:02.000000000 -0800
@@ -318,7 +318,8 @@ extern const char *host_detect_local_cpu
 #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
--- gcc/config/i386/x-i386.native	2006-11-18 06:26:01.000000000 -0800
+++ gcc/config/i386/x-i386	2006-12-02 08:49:18.000000000 -0800
@@ -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) $<


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]