Home | History | Annotate | Line # | Download | only in rs6000
driver-rs6000.cc revision 1.1
      1 /* Subroutines for the gcc driver.
      2    Copyright (C) 2007-2022 Free Software Foundation, Inc.
      3 
      4 This file is part of GCC.
      5 
      6 GCC is free software; you can redistribute it and/or modify
      7 it under the terms of the GNU General Public License as published by
      8 the Free Software Foundation; either version 3, or (at your option)
      9 any later version.
     10 
     11 GCC is distributed in the hope that it will be useful,
     12 but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 GNU General Public License for more details.
     15 
     16 You should have received a copy of the GNU General Public License
     17 along with GCC; see the file COPYING3.  If not see
     18 <http://www.gnu.org/licenses/>.  */
     19 
     20 #define IN_TARGET_CODE 1
     21 
     22 #include "config.h"
     23 #include "system.h"
     24 #include "coretypes.h"
     25 #include "tm.h"
     26 #include "diagnostic.h"
     27 #include "opts.h"
     28 #include <stdlib.h>
     29 
     30 #ifdef _AIX
     31 # include <sys/systemcfg.h>
     32 #endif
     33 
     34 #ifdef __linux__
     35 # include <link.h>
     36 #endif
     37 
     38 #if defined (__APPLE__) || (__FreeBSD__)
     39 # include <sys/types.h>
     40 # include <sys/sysctl.h>
     41 #endif
     42 
     43 #ifdef __linux__
     44 /* Canonical GCC cpu name table.  */
     45 static const char *rs6000_supported_cpu_names[] =
     46 {
     47 #define RS6000_CPU(NAME, CPU, FLAGS) NAME,
     48 #include "rs6000-cpus.def"
     49 #undef RS6000_CPU
     50 };
     51 
     52 /* This table holds a list of cpus where their Linux AT_PLATFORM name differs
     53    from their GCC canonical name.  The first column in a row contains the GCC
     54    canonical cpu name and the other columns in that row contain AT_PLATFORM
     55    names that should be mapped to the canonical name.  */
     56 
     57 static const char *linux_cpu_translation_table[][4] = {
     58   { "403", "ppc403", NULL },
     59   { "405", "ppc405", NULL },
     60   { "440", "ppc440", "ppc440gp", NULL },
     61   { "476", "ppc470", NULL },
     62   { "601", "ppc601", NULL },
     63   { "603", "ppc603", NULL },
     64   { "604", "ppc604", NULL },
     65   { "7400", "ppc7400", NULL },
     66   { "7450", "ppc7450", NULL },
     67   { "750", "ppc750", NULL },
     68   { "823", "ppc823", NULL },
     69   { "8540", "ppc8540", NULL },
     70   { "8548", "ppc8548", NULL },
     71   { "970", "ppc970", NULL },
     72   { "cell", "ppc-cell-be", NULL },
     73   { "e500mc", "ppce500mc", NULL },
     74   { "e5500", "ppce5500", NULL },
     75   { "e6500", "ppce6500", NULL },
     76   { "power7", "power7+", NULL },
     77   { NULL } /* End of table sentinel.  */
     78 };
     79 #endif
     80 
     81 const char *host_detect_local_cpu (int argc, const char **argv);
     82 
     83 #if GCC_VERSION >= 0
     84 
     85 /* Returns parameters that describe L1_ASSOC associative cache of size
     86    L1_SIZEKB with lines of size L1_LINE, and L2_SIZEKB.  */
     87 
     88 static char *
     89 describe_cache (unsigned l1_sizekb, unsigned l1_line,
     90 		unsigned l1_assoc ATTRIBUTE_UNUSED, unsigned l2_sizekb)
     91 {
     92   char l1size[1000], line[1000], l2size[1000];
     93 
     94   /* At the moment, gcc middle-end does not use the information about the
     95      associativity of the cache.  */
     96 
     97   sprintf (l1size, "--param l1-cache-size=%u", l1_sizekb);
     98   sprintf (line, "--param l1-cache-line-size=%u", l1_line);
     99   sprintf (l2size, "--param l2-cache-size=%u", l2_sizekb);
    100 
    101   return concat (l1size, " ", line, " ", l2size, " ", NULL);
    102 }
    103 
    104 #ifdef __APPLE__
    105 
    106 /* Returns the description of caches on Darwin.  */
    107 
    108 static char *
    109 detect_caches_darwin (void)
    110 {
    111   unsigned l1_sizekb, l1_line, l1_assoc, l2_sizekb;
    112   size_t len = 4;
    113   static int l1_size_name[2] = { CTL_HW, HW_L1DCACHESIZE };
    114   static int l1_line_name[2] = { CTL_HW, HW_CACHELINE };
    115   static int l2_size_name[2] = { CTL_HW, HW_L2CACHESIZE };
    116 
    117   sysctl (l1_size_name, 2, &l1_sizekb, &len, NULL, 0);
    118   sysctl (l1_line_name, 2, &l1_line, &len, NULL, 0);
    119   sysctl (l2_size_name, 2, &l2_sizekb, &len, NULL, 0);
    120   l1_assoc = 0;
    121 
    122   return describe_cache (l1_sizekb / 1024, l1_line, l1_assoc,
    123 			 l2_sizekb / 1024);
    124 }
    125 
    126 static const char *
    127 detect_processor_darwin (void)
    128 {
    129   unsigned int proc;
    130   size_t len = 4;
    131 
    132   sysctlbyname ("hw.cpusubtype", &proc, &len, NULL, 0);
    133 
    134   if (len > 0)
    135     switch (proc)
    136       {
    137       case 1:
    138 	return "601";
    139       case 2:
    140 	return "602";
    141       case 3:
    142 	return "603";
    143       case 4:
    144       case 5:
    145 	return "603e";
    146       case 6:
    147 	return "604";
    148       case 7:
    149 	return "604e";
    150       case 8:
    151 	return "620";
    152       case 9:
    153 	return "750";
    154       case 10:
    155 	return "7400";
    156       case 11:
    157 	return "7450";
    158       case 100:
    159 	return "970";
    160       default:
    161 	return "powerpc";
    162       }
    163 
    164   return "powerpc";
    165 }
    166 
    167 #endif /* __APPLE__ */
    168 
    169 #ifdef __FreeBSD__
    170 
    171 /* Returns the description of caches on FreeBSD PPC.  */
    172 
    173 static char *
    174 detect_caches_freebsd (void)
    175 {
    176   unsigned l1_sizekb, l1_line, l1_assoc, l2_sizekb;
    177   size_t len = 4;
    178 
    179   /* Currently, as of FreeBSD-7.0, there is only the cacheline_size
    180      available via sysctl.  */
    181   sysctlbyname ("machdep.cacheline_size", &l1_line, &len, NULL, 0);
    182 
    183   l1_sizekb = 32;
    184   l1_assoc = 0;
    185   l2_sizekb = 512;
    186 
    187   return describe_cache (l1_sizekb, l1_line, l1_assoc, l2_sizekb);
    188 }
    189 
    190 /* Currently returns default powerpc.  */
    191 static const char *
    192 detect_processor_freebsd (void)
    193 {
    194   return "powerpc";
    195 }
    196 
    197 #endif /* __FreeBSD__  */
    198 
    199 #ifdef __linux__
    200 
    201 /* Returns the canonical AT_PLATFORM if present, otherwise NULL.  */
    202 
    203 static const char *
    204 elf_platform (void)
    205 {
    206   /* Used to cache the result we determine below.  */
    207   static const char *cpu = NULL;
    208 
    209   /* Use the cached AT_PLATFORM cpu name if we've already determined it.  */
    210   if (cpu != NULL)
    211     return cpu;
    212 
    213   int fd = open ("/proc/self/auxv", O_RDONLY);
    214 
    215   if (fd != -1)
    216     {
    217       char buf[1024];
    218       ElfW(auxv_t) *av;
    219       ssize_t n;
    220 
    221       n = read (fd, buf, sizeof (buf));
    222       close (fd);
    223 
    224       if (n > 0)
    225 	{
    226 	  for (av = (ElfW(auxv_t) *) buf; av->a_type != AT_NULL; ++av)
    227 	    if (av->a_type == AT_PLATFORM)
    228 	      {
    229 		/* Cache the result.  */
    230 		cpu = (const char *) av->a_un.a_val;
    231 		break;
    232 	      }
    233 	}
    234 
    235       /* Verify that CPU is either a valid -mcpu=<cpu> option name, or is a
    236 	 valid alternative name.  If it is a valid alternative name, then use
    237 	 the canonical name.  */
    238       if (cpu != NULL)
    239 	{
    240 	  size_t i, j;
    241 	  char *s;
    242 
    243 	  /* Check if AT_PLATFORM is a GCC canonical cpu name.  */
    244 	  for (i = 0; i < ARRAY_SIZE (rs6000_supported_cpu_names); i++)
    245 	    if (!strcmp (cpu, rs6000_supported_cpu_names[i]))
    246 	      return cpu;
    247 
    248 	  /* Check if AT_PLATFORM can be translated to a canonical cpu name.  */
    249 	  for (i = 0; linux_cpu_translation_table[i][0] != NULL; i++)
    250 	    {
    251 	      const char *canonical = linux_cpu_translation_table[i][0];
    252 	      for (j = 1; linux_cpu_translation_table[i][j] != NULL; j++)
    253 		if (!strcmp (cpu, linux_cpu_translation_table[i][j]))
    254 		  {
    255 		    /* Cache the result.  */
    256 		    cpu = canonical;
    257 		    return cpu;
    258 		  }
    259 	    }
    260 
    261 	  /* The kernel returned an AT_PLATFORM name we do not support.  */
    262 	  auto_vec <const char *> candidates;
    263 	  for (i = 0; i < ARRAY_SIZE (rs6000_supported_cpu_names); i++)
    264 	    candidates.safe_push (rs6000_supported_cpu_names[i]);
    265 	  candidates_list_and_hint (cpu, s, candidates);
    266 	  error ("unsupported cpu name returned from kernel "
    267 		 "for %<-mcpu=native%>: %s", cpu);
    268 	  fatal_error (input_location, "please use an explicit cpu name; "
    269 		       "valid cpu names are: %s", s);
    270 	}
    271     }
    272   return NULL;
    273 }
    274 
    275 /* Returns AT_DCACHEBSIZE if present, otherwise generic 32.  */
    276 
    277 static int
    278 elf_dcachebsize (void)
    279 {
    280   int fd;
    281 
    282   fd = open ("/proc/self/auxv", O_RDONLY);
    283 
    284   if (fd != -1)
    285     {
    286       char buf[1024];
    287       ElfW(auxv_t) *av;
    288       ssize_t n;
    289 
    290       n = read (fd, buf, sizeof (buf));
    291       close (fd);
    292 
    293       if (n > 0)
    294 	{
    295 	  for (av = (ElfW(auxv_t) *) buf; av->a_type != AT_NULL; ++av)
    296 	    switch (av->a_type)
    297 	      {
    298 	      case AT_DCACHEBSIZE:
    299 		return av->a_un.a_val;
    300 
    301 	      default:
    302 		break;
    303 	      }
    304 	}
    305     }
    306   return 32;
    307 }
    308 
    309 /* Returns the description of caches on Linux.  */
    310 
    311 static char *
    312 detect_caches_linux (void)
    313 {
    314   unsigned l1_sizekb, l1_line, l1_assoc, l2_sizekb;
    315   const char *platform;
    316 
    317   platform = elf_platform ();
    318 
    319   if (platform != NULL)
    320     {
    321       l1_line = 128;
    322 
    323       if (platform[5] == '6')
    324 	/* POWER6 and POWER6x */
    325 	l1_sizekb = 64;
    326       else
    327 	l1_sizekb = 32;
    328     }
    329   else
    330     {
    331       l1_line = elf_dcachebsize ();
    332       l1_sizekb = 32;
    333     }
    334 
    335   l1_assoc = 0;
    336   l2_sizekb = 512;
    337 
    338   return describe_cache (l1_sizekb, l1_line, l1_assoc, l2_sizekb);
    339 }
    340 
    341 static const char *
    342 detect_processor_linux (void)
    343 {
    344   const char *platform;
    345 
    346   platform = elf_platform ();
    347 
    348   if (platform != NULL)
    349     return platform;
    350   else
    351     return "powerpc";
    352 }
    353 
    354 #endif /* __linux__ */
    355 
    356 #ifdef _AIX
    357 /* Returns the description of caches on AIX.  */
    358 
    359 static char *
    360 detect_caches_aix (void)
    361 {
    362   unsigned l1_sizekb, l1_line, l1_assoc, l2_sizekb;
    363 
    364   l1_sizekb = _system_configuration.dcache_size / 1024;
    365   l1_line = _system_configuration.dcache_line;
    366   l1_assoc = _system_configuration.dcache_asc;
    367   l2_sizekb = _system_configuration.L2_cache_size / 1024;
    368 
    369   return describe_cache (l1_sizekb, l1_line, l1_assoc, l2_sizekb);
    370 }
    371 
    372 
    373 /* Returns the processor implementation on AIX.  */
    374 
    375 static const char *
    376 detect_processor_aix (void)
    377 {
    378   switch (_system_configuration.implementation)
    379     {
    380     case 0x0008:
    381       return "601";
    382 
    383     case 0x0020:
    384       return "603";
    385 
    386     case 0x0010:
    387       return "604";
    388 
    389     case 0x0040:
    390       return "620";
    391 
    392     case 0x0080:
    393       return "630";
    394 
    395     case 0x0100:
    396     case 0x0200:
    397     case 0x0400:
    398       return "rs64";
    399 
    400     case 0x0800:
    401       return "power4";
    402 
    403     case 0x2000:
    404       if (_system_configuration.version == 0x0F0000)
    405 	return "power5";
    406       else
    407 	return "power5+";
    408 
    409     case 0x4000:
    410       return "power6";
    411 
    412     case 0x8000:
    413       return "power7";
    414 
    415     case 0x10000:
    416       return "power8";
    417 
    418     case 0x20000:
    419       return "power9";
    420 
    421     case 0x40000:
    422       return "power10";
    423 
    424     default:
    425       return "powerpc";
    426     }
    427 }
    428 #endif /* _AIX */
    429 
    430 
    431 /*
    432  * Array to map -mcpu=native names to the switches passed to the assembler.
    433  * This list mirrors the specs in ASM_CPU_SPEC, and any changes made here
    434  * should be made there as well.
    435  */
    436 
    437 struct asm_name {
    438   const char *cpu;
    439   const char *asm_sw;
    440 };
    441 
    442 static const struct asm_name asm_names[] = {
    443 #if defined (_AIX)
    444   { "power3",	"-m620" },
    445   { "power4",	"-mpwr4" },
    446   { "power5",	"-mpwr5" },
    447   { "power5+",	"-mpwr5x" },
    448   { "power6",	"-mpwr6" },
    449   { "power6x",	"-mpwr6" },
    450   { "power7",	"-mpwr7" },
    451   { "power8",	"-mpwr8" },
    452   { "power9",	"-mpwr9" },
    453   { "power10",	"-mpwr10" },
    454   { "powerpc",	"-mppc" },
    455   { "rs64",	"-mppc" },
    456   { "603",	"-m603" },
    457   { "603e",	"-m603" },
    458   { "604",	"-m604" },
    459   { "604e",	"-m604" },
    460   { "620",	"-m620" },
    461   { "630",	"-m620" },
    462   { "970",	"-m970" },
    463   { "G5",	"-m970" },
    464   { NULL,	"\
    465   %{mvsx: -mpwr6; \
    466     maltivec: -m970; \
    467     maix64|mpowerpc64: -mppc64; \
    468     : %(asm_default)}" },
    469 
    470 #else
    471   { "cell",	"-mcell" },
    472   { "power3",	"-mppc64" },
    473   { "power4",	"-mpower4" },
    474   { "power5",	"-mpower5" },
    475   { "power5+",	"-mpower5" },
    476   { "power6",	"-mpower6 %{!mvsx:%{!maltivec:-maltivec}}" },
    477   { "power6x",	"-mpower6 %{!mvsx:%{!maltivec:-maltivec}}" },
    478   { "power7",	"-mpower7" },
    479   { "power8",	"%{mpower9-vector:-mpower9;:-mpower8}" },
    480   { "power9",	"-mpower9" },
    481   { "power10",	"-mpower10" },
    482   { "a2",	"-ma2" },
    483   { "powerpc",	"-mppc" },
    484   { "powerpc64", "-mppc64" },
    485   { "powerpc64le", "%{mpower9-vector:-mpower9;:-mpower8}" },
    486   { "rs64",	"-mppc64" },
    487   { "401",	"-mppc" },
    488   { "403",	"-m403" },
    489   { "405",	"-m405" },
    490   { "405fp",	"-m405" },
    491   { "440",	"-m440" },
    492   { "440fp",	"-m440" },
    493   { "464",	"-m440" },
    494   { "464fp",	"-m440" },
    495   { "476",	"-m476" },
    496   { "476fp",	"-m476" },
    497   { "505",	"-mppc" },
    498   { "601",	"-m601" },
    499   { "602",	"-mppc" },
    500   { "603",	"-mppc" },
    501   { "603e",	"-mppc" },
    502   { "ec603e",	"-mppc" },
    503   { "604",	"-mppc" },
    504   { "604e",	"-mppc" },
    505   { "620",	"-mppc64" },
    506   { "630",	"-mppc64" },
    507   { "740",	"-mppc" },
    508   { "750",	"-mppc" },
    509   { "G3",	"-mppc" },
    510   { "7400",	"-mppc %{!mvsx:%{!maltivec:-maltivec}}" },
    511   { "7450",	"-mppc %{!mvsx:%{!maltivec:-maltivec}}" },
    512   { "G4",	"-mppc %{!mvsx:%{!maltivec:-maltivec}}" },
    513   { "801",	"-mppc" },
    514   { "821",	"-mppc" },
    515   { "823",	"-mppc" },
    516   { "860",	"-mppc" },
    517   { "970",	"-mpower4 %{!mvsx:%{!maltivec:-maltivec}}" },
    518   { "G5",	"-mpower4 %{!mvsx:%{!maltivec:-maltivec}}" },
    519   { "8540",	"-me500" },
    520   { "8548",	"-me500" },
    521   { "e300c2",	"-me300" },
    522   { "e300c3",	"-me300" },
    523   { "e500mc",	"-me500mc" },
    524   { "e500mc64",	"-me500mc64" },
    525   { "e5500",	"-me5500" },
    526   { "e6500",	"-me6500" },
    527   { "titan",	"-mtitan" },
    528   { NULL,	"\
    529 %{mpower9-vector: -mpower9; \
    530   mpower8-vector|mcrypto|mdirect-move|mhtm: -mpower8; \
    531   mvsx: -mpower7; \
    532   mpowerpc64: -mppc64; \
    533   : %(asm_default)}" },
    534 #endif
    535 };
    536 
    537 /* This will be called by the spec parser in gcc.cc when it sees
    538    a %:local_cpu_detect(args) construct.  Currently it will be called
    539    with either "arch" or "tune" as argument depending on if -march=native
    540    or -mtune=native is to be substituted.
    541 
    542    Additionally it will be called with "asm" to select the appropriate flags
    543    for the assembler.
    544 
    545    It returns a string containing new command line parameters to be
    546    put at the place of the above two options, depending on what CPU
    547    this is executed.
    548 
    549    ARGC and ARGV are set depending on the actual arguments given
    550    in the spec.  */
    551 const char *
    552 host_detect_local_cpu (int argc, const char **argv)
    553 {
    554   const char *cpu = NULL;
    555   const char *cache = "";
    556   const char *options = "";
    557   bool arch;
    558   bool assembler;
    559   size_t i;
    560 
    561   if (argc < 1)
    562     return NULL;
    563 
    564   arch = strcmp (argv[0], "cpu") == 0;
    565   assembler = (!arch && strcmp (argv[0], "asm") == 0);
    566   if (!arch && !assembler && strcmp (argv[0], "tune"))
    567     return NULL;
    568 
    569   if (! assembler)
    570     {
    571 #if defined (_AIX)
    572       cache = detect_caches_aix ();
    573 #elif defined (__APPLE__)
    574       cache = detect_caches_darwin ();
    575 #elif defined (__FreeBSD__)
    576       cache = detect_caches_freebsd ();
    577       /* FreeBSD PPC does not provide any cache information yet.  */
    578       cache = "";
    579 #elif defined (__linux__)
    580       cache = detect_caches_linux ();
    581       /* PPC Linux does not provide any cache information yet.  */
    582       cache = "";
    583 #else
    584       cache = "";
    585 #endif
    586     }
    587 
    588 #if defined (_AIX)
    589   cpu = detect_processor_aix ();
    590 #elif defined (__APPLE__)
    591   cpu = detect_processor_darwin ();
    592 #elif defined (__FreeBSD__)
    593   cpu = detect_processor_freebsd ();
    594 #elif defined (__linux__)
    595   cpu = detect_processor_linux ();
    596 #else
    597   cpu = "powerpc";
    598 #endif
    599 
    600   if (assembler)
    601     {
    602       for (i = 0; i < sizeof (asm_names) / sizeof (asm_names[0]); i++)
    603 	{
    604 	  if (!asm_names[i].cpu || !strcmp (asm_names[i].cpu, cpu))
    605 	    return asm_names[i].asm_sw;
    606 	}
    607 
    608       return NULL;
    609     }
    610 
    611   return concat (cache, "-m", argv[0], "=", cpu, " ", options, NULL);
    612 }
    613 
    614 #else /* GCC_VERSION */
    615 
    616 /* If we aren't compiling with GCC we just provide a minimal
    617    default value.  */
    618 const char *
    619 host_detect_local_cpu (int argc, const char **argv)
    620 {
    621   const char *cpu;
    622   bool arch;
    623 
    624   if (argc < 1)
    625     return NULL;
    626 
    627   arch = strcmp (argv[0], "cpu") == 0;
    628   if (!arch && strcmp (argv[0], "tune"))
    629     return NULL;
    630 
    631   if (arch)
    632     cpu = "powerpc";
    633 
    634   return concat ("-m", argv[0], "=", cpu, NULL);
    635 }
    636 
    637 #endif /* GCC_VERSION */
    638 
    639