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