config.gcc (powerpc64le*): Revert January 16th...
[official-gcc.git] / gcc / config / powerpcspe / driver-powerpcspe.c
blobcf3ef94dcb0fa710093e91a9b7455e464036a733
1 /* Subroutines for the gcc driver.
2 Copyright (C) 2007-2018 Free Software Foundation, Inc.
4 This file is part of GCC.
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.
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.
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/>. */
20 #define IN_TARGET_CODE 1
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include <stdlib.h>
28 #ifdef _AIX
29 # include <sys/systemcfg.h>
30 #endif
32 #ifdef __linux__
33 # include <link.h>
34 #endif
36 #if defined (__APPLE__) || (__FreeBSD__)
37 # include <sys/types.h>
38 # include <sys/sysctl.h>
39 #endif
41 const char *host_detect_local_cpu (int argc, const char **argv);
43 #if GCC_VERSION >= 0
45 /* Returns parameters that describe L1_ASSOC associative cache of size
46 L1_SIZEKB with lines of size L1_LINE, and L2_SIZEKB. */
48 static char *
49 describe_cache (unsigned l1_sizekb, unsigned l1_line,
50 unsigned l1_assoc ATTRIBUTE_UNUSED, unsigned l2_sizekb)
52 char l1size[1000], line[1000], l2size[1000];
54 /* At the moment, gcc middle-end does not use the information about the
55 associativity of the cache. */
57 sprintf (l1size, "--param l1-cache-size=%u", l1_sizekb);
58 sprintf (line, "--param l1-cache-line-size=%u", l1_line);
59 sprintf (l2size, "--param l2-cache-size=%u", l2_sizekb);
61 return concat (l1size, " ", line, " ", l2size, " ", NULL);
64 #ifdef __APPLE__
66 /* Returns the description of caches on Darwin. */
68 static char *
69 detect_caches_darwin (void)
71 unsigned l1_sizekb, l1_line, l1_assoc, l2_sizekb;
72 size_t len = 4;
73 static int l1_size_name[2] = { CTL_HW, HW_L1DCACHESIZE };
74 static int l1_line_name[2] = { CTL_HW, HW_CACHELINE };
75 static int l2_size_name[2] = { CTL_HW, HW_L2CACHESIZE };
77 sysctl (l1_size_name, 2, &l1_sizekb, &len, NULL, 0);
78 sysctl (l1_line_name, 2, &l1_line, &len, NULL, 0);
79 sysctl (l2_size_name, 2, &l2_sizekb, &len, NULL, 0);
80 l1_assoc = 0;
82 return describe_cache (l1_sizekb / 1024, l1_line, l1_assoc,
83 l2_sizekb / 1024);
86 static const char *
87 detect_processor_darwin (void)
89 unsigned int proc;
90 size_t len = 4;
92 sysctlbyname ("hw.cpusubtype", &proc, &len, NULL, 0);
94 if (len > 0)
95 switch (proc)
97 case 1:
98 return "601";
99 case 2:
100 return "602";
101 case 3:
102 return "603";
103 case 4:
104 case 5:
105 return "603e";
106 case 6:
107 return "604";
108 case 7:
109 return "604e";
110 case 8:
111 return "620";
112 case 9:
113 return "750";
114 case 10:
115 return "7400";
116 case 11:
117 return "7450";
118 case 100:
119 return "970";
120 default:
121 return "powerpc";
124 return "powerpc";
127 #endif /* __APPLE__ */
129 #ifdef __FreeBSD__
131 /* Returns the description of caches on FreeBSD PPC. */
133 static char *
134 detect_caches_freebsd (void)
136 unsigned l1_sizekb, l1_line, l1_assoc, l2_sizekb;
137 size_t len = 4;
139 /* Currently, as of FreeBSD-7.0, there is only the cacheline_size
140 available via sysctl. */
141 sysctlbyname ("machdep.cacheline_size", &l1_line, &len, NULL, 0);
143 l1_sizekb = 32;
144 l1_assoc = 0;
145 l2_sizekb = 512;
147 return describe_cache (l1_sizekb, l1_line, l1_assoc, l2_sizekb);
150 /* Currently returns default powerpc. */
151 static const char *
152 detect_processor_freebsd (void)
154 return "powerpc";
157 #endif /* __FreeBSD__ */
159 #ifdef __linux__
161 /* Returns AT_PLATFORM if present, otherwise generic PowerPC. */
163 static const char *
164 elf_platform (void)
166 int fd;
168 fd = open ("/proc/self/auxv", O_RDONLY);
170 if (fd != -1)
172 char buf[1024];
173 ElfW(auxv_t) *av;
174 ssize_t n;
176 n = read (fd, buf, sizeof (buf));
177 close (fd);
179 if (n > 0)
181 for (av = (ElfW(auxv_t) *) buf; av->a_type != AT_NULL; ++av)
182 switch (av->a_type)
184 case AT_PLATFORM:
185 return (const char *) av->a_un.a_val;
187 default:
188 break;
192 return NULL;
195 /* Returns AT_DCACHEBSIZE if present, otherwise generic 32. */
197 static int
198 elf_dcachebsize (void)
200 int fd;
202 fd = open ("/proc/self/auxv", O_RDONLY);
204 if (fd != -1)
206 char buf[1024];
207 ElfW(auxv_t) *av;
208 ssize_t n;
210 n = read (fd, buf, sizeof (buf));
211 close (fd);
213 if (n > 0)
215 for (av = (ElfW(auxv_t) *) buf; av->a_type != AT_NULL; ++av)
216 switch (av->a_type)
218 case AT_DCACHEBSIZE:
219 return av->a_un.a_val;
221 default:
222 break;
226 return 32;
229 /* Returns the description of caches on Linux. */
231 static char *
232 detect_caches_linux (void)
234 unsigned l1_sizekb, l1_line, l1_assoc, l2_sizekb;
235 const char *platform;
237 platform = elf_platform ();
239 if (platform != NULL)
241 l1_line = 128;
243 if (platform[5] == '6')
244 /* POWER6 and POWER6x */
245 l1_sizekb = 64;
246 else
247 l1_sizekb = 32;
249 else
251 l1_line = elf_dcachebsize ();
252 l1_sizekb = 32;
255 l1_assoc = 0;
256 l2_sizekb = 512;
258 return describe_cache (l1_sizekb, l1_line, l1_assoc, l2_sizekb);
261 static const char *
262 detect_processor_linux (void)
264 const char *platform;
266 platform = elf_platform ();
268 if (platform != NULL)
269 return platform;
270 else
271 return "powerpc";
274 #endif /* __linux__ */
276 #ifdef _AIX
277 /* Returns the description of caches on AIX. */
279 static char *
280 detect_caches_aix (void)
282 unsigned l1_sizekb, l1_line, l1_assoc, l2_sizekb;
284 l1_sizekb = _system_configuration.dcache_size / 1024;
285 l1_line = _system_configuration.dcache_line;
286 l1_assoc = _system_configuration.dcache_asc;
287 l2_sizekb = _system_configuration.L2_cache_size / 1024;
289 return describe_cache (l1_sizekb, l1_line, l1_assoc, l2_sizekb);
293 /* Returns the processor implementation on AIX. */
295 static const char *
296 detect_processor_aix (void)
298 switch (_system_configuration.implementation)
300 case 0x0008:
301 return "601";
303 case 0x0020:
304 return "603";
306 case 0x0010:
307 return "604";
309 case 0x0040:
310 return "620";
312 case 0x0080:
313 return "630";
315 case 0x0100:
316 case 0x0200:
317 case 0x0400:
318 return "rs64";
320 case 0x0800:
321 return "power4";
323 case 0x2000:
324 if (_system_configuration.version == 0x0F0000)
325 return "power5";
326 else
327 return "power5+";
329 case 0x4000:
330 return "power6";
332 case 0x8000:
333 return "power7";
335 case 0x10000:
336 return "power8";
338 case 0x20000:
339 return "power9";
341 default:
342 return "powerpc";
345 #endif /* _AIX */
349 * Array to map -mcpu=native names to the switches passed to the assembler.
350 * This list mirrors the specs in ASM_CPU_SPEC, and any changes made here
351 * should be made there as well.
354 struct asm_name {
355 const char *cpu;
356 const char *asm_sw;
359 static const struct asm_name asm_names[] = {
360 #if defined (_AIX)
361 { "power3", "-m620" },
362 { "power4", "-mpwr4" },
363 { "power5", "-mpwr5" },
364 { "power5+", "-mpwr5x" },
365 { "power6", "-mpwr6" },
366 { "power6x", "-mpwr6" },
367 { "power7", "-mpwr7" },
368 { "power8", "-mpwr8" },
369 { "power9", "-mpwr9" },
370 { "powerpc", "-mppc" },
371 { "rs64a", "-mppc" },
372 { "603", "-m603" },
373 { "603e", "-m603" },
374 { "604", "-m604" },
375 { "604e", "-m604" },
376 { "620", "-m620" },
377 { "630", "-m620" },
378 { "970", "-m970" },
379 { "G5", "-m970" },
380 { NULL, "\
381 %{!maix64: \
382 %{mpowerpc64: -mppc64} \
383 %{maltivec: -m970} \
384 %{!maltivec: %{!mpowerpc64: %(asm_default)}}}" },
386 #else
387 { "cell", "-mcell" },
388 { "power3", "-mppc64" },
389 { "power4", "-mpower4" },
390 { "power5", "%(asm_cpu_power5)" },
391 { "power5+", "%(asm_cpu_power5)" },
392 { "power6", "%(asm_cpu_power6) -maltivec" },
393 { "power6x", "%(asm_cpu_power6) -maltivec" },
394 { "power7", "%(asm_cpu_power7)" },
395 { "power8", "%(asm_cpu_power8)" },
396 { "power9", "%(asm_cpu_power9)" },
397 { "powerpc", "-mppc" },
398 { "rs64a", "-mppc64" },
399 { "401", "-mppc" },
400 { "403", "-m403" },
401 { "405", "-m405" },
402 { "405fp", "-m405" },
403 { "440", "-m440" },
404 { "440fp", "-m440" },
405 { "464", "-m440" },
406 { "464fp", "-m440" },
407 { "505", "-mppc" },
408 { "601", "-m601" },
409 { "602", "-mppc" },
410 { "603", "-mppc" },
411 { "603e", "-mppc" },
412 { "ec603e", "-mppc" },
413 { "604", "-mppc" },
414 { "604e", "-mppc" },
415 { "620", "-mppc64" },
416 { "630", "-mppc64" },
417 { "740", "-mppc" },
418 { "750", "-mppc" },
419 { "G3", "-mppc" },
420 { "7400", "-mppc -maltivec" },
421 { "7450", "-mppc -maltivec" },
422 { "G4", "-mppc -maltivec" },
423 { "801", "-mppc" },
424 { "821", "-mppc" },
425 { "823", "-mppc" },
426 { "860", "-mppc" },
427 { "970", "-mpower4 -maltivec" },
428 { "G5", "-mpower4 -maltivec" },
429 { "8540", "-me500" },
430 { "8548", "-me500" },
431 { "e300c2", "-me300" },
432 { "e300c3", "-me300" },
433 { "e500mc", "-me500mc" },
434 { NULL, "\
435 %{mpowerpc64*: -mppc64} \
436 %{!mpowerpc64*: %(asm_default)}" },
437 #endif
440 /* This will be called by the spec parser in gcc.c when it sees
441 a %:local_cpu_detect(args) construct. Currently it will be called
442 with either "arch" or "tune" as argument depending on if -march=native
443 or -mtune=native is to be substituted.
445 Additionally it will be called with "asm" to select the appropriate flags
446 for the assembler.
448 It returns a string containing new command line parameters to be
449 put at the place of the above two options, depending on what CPU
450 this is executed.
452 ARGC and ARGV are set depending on the actual arguments given
453 in the spec. */
454 const char *
455 host_detect_local_cpu (int argc, const char **argv)
457 const char *cpu = NULL;
458 const char *cache = "";
459 const char *options = "";
460 bool arch;
461 bool assembler;
462 size_t i;
464 if (argc < 1)
465 return NULL;
467 arch = strcmp (argv[0], "cpu") == 0;
468 assembler = (!arch && strcmp (argv[0], "asm") == 0);
469 if (!arch && !assembler && strcmp (argv[0], "tune"))
470 return NULL;
472 if (! assembler)
474 #if defined (_AIX)
475 cache = detect_caches_aix ();
476 #elif defined (__APPLE__)
477 cache = detect_caches_darwin ();
478 #elif defined (__FreeBSD__)
479 cache = detect_caches_freebsd ();
480 /* FreeBSD PPC does not provide any cache information yet. */
481 cache = "";
482 #elif defined (__linux__)
483 cache = detect_caches_linux ();
484 /* PPC Linux does not provide any cache information yet. */
485 cache = "";
486 #else
487 cache = "";
488 #endif
491 #if defined (_AIX)
492 cpu = detect_processor_aix ();
493 #elif defined (__APPLE__)
494 cpu = detect_processor_darwin ();
495 #elif defined (__FreeBSD__)
496 cpu = detect_processor_freebsd ();
497 #elif defined (__linux__)
498 cpu = detect_processor_linux ();
499 #else
500 cpu = "powerpc";
501 #endif
503 if (assembler)
505 for (i = 0; i < sizeof (asm_names) / sizeof (asm_names[0]); i++)
507 if (!asm_names[i].cpu || !strcmp (asm_names[i].cpu, cpu))
508 return asm_names[i].asm_sw;
511 return NULL;
514 return concat (cache, "-m", argv[0], "=", cpu, " ", options, NULL);
517 #else /* GCC_VERSION */
519 /* If we aren't compiling with GCC we just provide a minimal
520 default value. */
521 const char *
522 host_detect_local_cpu (int argc, const char **argv)
524 const char *cpu;
525 bool arch;
527 if (argc < 1)
528 return NULL;
530 arch = strcmp (argv[0], "cpu") == 0;
531 if (!arch && strcmp (argv[0], "tune"))
532 return NULL;
534 if (arch)
535 cpu = "powerpc";
537 return concat ("-m", argv[0], "=", cpu, NULL);
540 #endif /* GCC_VERSION */