re PR target/56010 (Powerpc, -mcpu=native and -mtune=native use the wrong name for...
authorPeter Bergner <bergner@vnet.ibm.com>
Thu, 1 Feb 2018 18:26:51 +0000 (12:26 -0600)
committerPeter Bergner <bergner@gcc.gnu.org>
Thu, 1 Feb 2018 18:26:51 +0000 (12:26 -0600)
PR target/56010
PR target/83743
* config/rs6000/driver-rs6000.c: #include "diagnostic.h".
#include "opts.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.

From-SVN: r257305

gcc/ChangeLog
gcc/config/rs6000/driver-rs6000.c

index 6fe5671ba16d56deea758dc0a6650d6023d0d234..c01487b8420afca4aaea34e4aada40389308f41e 100644 (file)
@@ -1,3 +1,15 @@
+2018-02-01  Peter Bergner  <bergner@vnet.ibm.com>
+
+       PR target/56010
+       PR target/83743
+       * config/rs6000/driver-rs6000.c: #include "diagnostic.h".
+       #include "opts.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.
+
 2018-02-01  Aldy Hernandez  <aldyh@redhat.com>
 
        PR target/84089
index cf3ef94dcb0fa710093e91a9b7455e464036a733..972099a47ee81f31d8b9a0eeb53fb782de1a6e77 100644 (file)
@@ -23,6 +23,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "system.h"
 #include "coretypes.h"
 #include "tm.h"
+#include "diagnostic.h"
+#include "opts.h"
 #include <stdlib.h>
 
 #ifdef _AIX
@@ -38,6 +40,44 @@ along with GCC; see the file COPYING3.  If not see
 # 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", 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,14 +198,19 @@ detect_processor_freebsd (void)
 
 #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;
+  /* Used to cache the result we determine below.  */
+  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)
     {
@@ -179,15 +224,51 @@ elf_platform (void)
       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:
+               /* Cache the result.  */
+               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;
+         char *s;
+
+         /* 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;
+
+         /* 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]))
+                 {
+                   /* Cache the result.  */
+                   cpu = canonical;
+                   return cpu;
+                 }
+           }
+
+         /* The kernel returned an AT_PLATFORM name we do not support.  */
+         auto_vec <const char *> candidates;
+         for (i = 0; i < ARRAY_SIZE (rs6000_supported_cpu_names); i++)
+           candidates.safe_push (rs6000_supported_cpu_names[i]);
+         candidates_list_and_hint (cpu, s, candidates);
+         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;
 }