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; }