From 5bf03bd8c8a97fb30bc7e146216396bbe9f6a36d Mon Sep 17 00:00:00 2001 From: Luke McHale Date: Fri, 7 Aug 2020 16:46:16 +0000 Subject: [PATCH] powerpcspe arch is missing AT_PLATFORM translation table present in the regular powerpc (rs6000) arch. Fixes -mcpu=native when run on e500v2 to correctly drop the ppc from AT_PLATFORM ppc8548 to GCC's canonical 8548. --- gcc/config/powerpcspe/driver-powerpcspe.c | 97 +++++++++++++++++++++-- 1 file changed, 89 insertions(+), 8 deletions(-) diff --git a/gcc/config/powerpcspe/driver-powerpcspe.c b/gcc/config/powerpcspe/driver-powerpcspe.c index cf3ef94..bd33865 100644 --- a/gcc/config/powerpcspe/driver-powerpcspe.c +++ b/gcc/config/powerpcspe/driver-powerpcspe.c @@ -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 #ifdef _AIX @@ -38,6 +40,44 @@ along with GCC; see the file COPYING3. If not see # include #endif +#ifdef __linux__ +/* Canonical GCC cpu name table. */ +static const char *rs6000_supported_cpu_names[] = +{ +#define RS6000_CPU(NAME, CPU, FLAGS) NAME, +#include "powerpcspe-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= 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 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; } -- 2.27.0