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, rs6000] Fix PR56010 and PR83743, -mcpu=native use wrong names


On 1/25/18 3:56 PM, Peter Bergner wrote:
> Ok, I'll move the table to driver-rs6000.c and I'll resubmit.

Ok, here is a separate translation table like you wanted.  I still use the
RS6000_CPU table to hold entire list of canonical cpu names, the new
translation table in driver-rs6000.c only contains cpus whose AT_PLATFORM
names do not match their GCC canonical names.  I also added the pa6t to
970 translation you mentioned in the bugzilla.  If you want me to drop
that, that's easy enough to do.

I realize I also failed to mention in the first submission, that I have
added caching of the elf_plaform() result, so we don't have to mount and
scan /proc/self/auxv multiple times.

Is this better?  I did the same unit testing by forcing unknown names
and names that need translation and I've verified it works.  Bootstrap
and regtesting is still running though.

Peter

	PR target/56010
	PR target/83743
	* config/rs6000/driver-rs6000.c: #include "diagnostic.h".
	(rs6000_supported_cpu_names): New static variable.
	(linux_cpu_translation_table): Likewise.
	(elf_platform) <cpu>: Define new static variable and use it.
	Translate kernel AT_PLATFORM name to canonical name if needed.
	Error if platform name is unknown.

Index: gcc/config/rs6000/driver-rs6000.c
===================================================================
--- gcc/config/rs6000/driver-rs6000.c	(revision 256364)
+++ gcc/config/rs6000/driver-rs6000.c	(working copy)
@@ -23,6 +23,7 @@
 #include "system.h"
 #include "coretypes.h"
 #include "tm.h"
+#include "diagnostic.h"
 #include <stdlib.h>
 
 #ifdef _AIX
@@ -38,6 +39,44 @@
 # include <sys/sysctl.h>
 #endif
 
+#ifdef __linux__
+/* Canonical GCC cpu name table.  */
+static const char *rs6000_supported_cpu_names[] =
+{
+#define RS6000_CPU(NAME, CPU, FLAGS) NAME,
+#include "rs6000-cpus.def"
+#undef RS6000_CPU
+};
+
+/* This table holds a list of cpus where their Linux AT_PLATFORM name differs
+   from their GCC canonical name.  The first column in a row contains the GCC
+   canonical cpu name and the other columns in that row contain AT_PLATFORM
+   names that should be mapped to the canonical name.  */
+
+static const char *linux_cpu_translation_table[][4] = {
+  { "403", "ppc403", NULL },
+  { "405", "ppc405", NULL },
+  { "440", "ppc440", "ppc440gp", NULL },
+  { "476", "ppc470", NULL },
+  { "601", "ppc601", NULL },
+  { "603", "ppc603", NULL },
+  { "604", "ppc604", NULL },
+  { "7400", "ppc7400", NULL },
+  { "7450", "ppc7450", NULL },
+  { "750", "ppc750", NULL },
+  { "823", "ppc823", NULL },
+  { "8540", "ppc8540", NULL },
+  { "8548", "ppc8548", NULL },
+  { "970", "ppc970", "pa6t", NULL },
+  { "cell", "ppc-cell-be", NULL },
+  { "e500mc", "ppce500mc", NULL },
+  { "e5500", "ppce5500", NULL },
+  { "e6500", "ppce6500", NULL },
+  { "power7", "power7+", NULL },
+  { NULL } /* End of table sentinel.  */
+};
+#endif
+
 const char *host_detect_local_cpu (int argc, const char **argv);
 
 #if GCC_VERSION >= 0
@@ -158,15 +197,19 @@
 
 #ifdef __linux__
 
-/* Returns AT_PLATFORM if present, otherwise generic PowerPC.  */
+/* Returns the canonical AT_PLATFORM if present, otherwise NULL.  */
 
 static const char *
 elf_platform (void)
 {
-  int fd;
+  static const char *cpu = NULL;
 
-  fd = open ("/proc/self/auxv", O_RDONLY);
+  /* Use the cached AT_PLATFORM cpu name if we've already determined it.  */
+  if (cpu != NULL)
+    return cpu;
 
+  int fd = open ("/proc/self/auxv", O_RDONLY);
+
   if (fd != -1)
     {
       char buf[1024];
@@ -179,15 +222,60 @@
       if (n > 0)
 	{
 	  for (av = (ElfW(auxv_t) *) buf; av->a_type != AT_NULL; ++av)
-	    switch (av->a_type)
+	    if (av->a_type == AT_PLATFORM)
 	      {
-	      case AT_PLATFORM:
-		return (const char *) av->a_un.a_val;
-
-	      default:
+		cpu = (const char *) av->a_un.a_val;
 		break;
 	      }
 	}
+
+      /* Verify that CPU is either a valid -mcpu=<cpu> option name, or is a
+	 valid alternative name.  If it is a valid alternative name, then use
+	 the canonical name.  */
+      if (cpu != NULL)
+	{
+	  size_t i, j, len = 0;
+	  char *s, *p;
+
+	  /* Check if AT_PLATFORM is a GCC canonical cpu name.  */
+	  for (i = 0; i < ARRAY_SIZE (rs6000_supported_cpu_names); i++)
+	    {
+	      if (!strcmp (cpu, rs6000_supported_cpu_names[i]))
+		return cpu;
+	      len += strlen (rs6000_supported_cpu_names[i]) + 1;
+	    }
+
+	  /* Check if AT_PLATFORM can be translated to a canonical cpu name.  */
+	  for (i = 0; linux_cpu_translation_table[i][0] != NULL; i++)
+	    {
+	      const char *canonical = linux_cpu_translation_table[i][0];
+	      for (j = 1; linux_cpu_translation_table[i][j] != NULL; j++)
+		if (!strcmp (cpu, linux_cpu_translation_table[i][j]))
+		  {
+		    cpu = canonical;
+		    return cpu;
+		  }
+	    }
+
+	  /* The kernel returned an AT_PLATFORM name we do not support.  */
+	  s = XALLOCAVEC (char, len);
+	  p = s;
+	  for (i = 0; i < ARRAY_SIZE (rs6000_supported_cpu_names); i++)
+	    {
+	      size_t arglen = strlen (rs6000_supported_cpu_names[i]);
+	      memcpy (p, rs6000_supported_cpu_names[i], arglen);
+	      p[arglen] = ' ';
+	      p += arglen + 1;
+	    }
+	  p[-1] = 0;
+
+	  fatal_error (
+	    input_location,
+	    "Unsupported cpu name returned from kernel for -mcpu=native: %s\n"
+	    "Please use an explicit cpu name.  Valid cpu names are: %s",
+	    cpu, s);
+	}
+
     }
   return NULL;
 }


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