[AArch64] Fix ICEs in aarch64_print_operand
[official-gcc.git] / gcc / config / powerpcspe / driver-powerpcspe.c
blob8215abbd625826f1cb662982b6710d21eb56680a
1 /* Subroutines for the gcc driver.
2 Copyright (C) 2007-2017 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 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "tm.h"
24 #include <stdlib.h>
26 #ifdef _AIX
27 # include <sys/systemcfg.h>
28 #endif
30 #ifdef __linux__
31 # include <link.h>
32 #endif
34 #if defined (__APPLE__) || (__FreeBSD__)
35 # include <sys/types.h>
36 # include <sys/sysctl.h>
37 #endif
39 const char *host_detect_local_cpu (int argc, const char **argv);
41 #if GCC_VERSION >= 0
43 /* Returns parameters that describe L1_ASSOC associative cache of size
44 L1_SIZEKB with lines of size L1_LINE, and L2_SIZEKB. */
46 static char *
47 describe_cache (unsigned l1_sizekb, unsigned l1_line,
48 unsigned l1_assoc ATTRIBUTE_UNUSED, unsigned l2_sizekb)
50 char l1size[1000], line[1000], l2size[1000];
52 /* At the moment, gcc middle-end does not use the information about the
53 associativity of the cache. */
55 sprintf (l1size, "--param l1-cache-size=%u", l1_sizekb);
56 sprintf (line, "--param l1-cache-line-size=%u", l1_line);
57 sprintf (l2size, "--param l2-cache-size=%u", l2_sizekb);
59 return concat (l1size, " ", line, " ", l2size, " ", NULL);
62 #ifdef __APPLE__
64 /* Returns the description of caches on Darwin. */
66 static char *
67 detect_caches_darwin (void)
69 unsigned l1_sizekb, l1_line, l1_assoc, l2_sizekb;
70 size_t len = 4;
71 static int l1_size_name[2] = { CTL_HW, HW_L1DCACHESIZE };
72 static int l1_line_name[2] = { CTL_HW, HW_CACHELINE };
73 static int l2_size_name[2] = { CTL_HW, HW_L2CACHESIZE };
75 sysctl (l1_size_name, 2, &l1_sizekb, &len, NULL, 0);
76 sysctl (l1_line_name, 2, &l1_line, &len, NULL, 0);
77 sysctl (l2_size_name, 2, &l2_sizekb, &len, NULL, 0);
78 l1_assoc = 0;
80 return describe_cache (l1_sizekb / 1024, l1_line, l1_assoc,
81 l2_sizekb / 1024);
84 static const char *
85 detect_processor_darwin (void)
87 unsigned int proc;
88 size_t len = 4;
90 sysctlbyname ("hw.cpusubtype", &proc, &len, NULL, 0);
92 if (len > 0)
93 switch (proc)
95 case 1:
96 return "601";
97 case 2:
98 return "602";
99 case 3:
100 return "603";
101 case 4:
102 case 5:
103 return "603e";
104 case 6:
105 return "604";
106 case 7:
107 return "604e";
108 case 8:
109 return "620";
110 case 9:
111 return "750";
112 case 10:
113 return "7400";
114 case 11:
115 return "7450";
116 case 100:
117 return "970";
118 default:
119 return "powerpc";
122 return "powerpc";
125 #endif /* __APPLE__ */
127 #ifdef __FreeBSD__
129 /* Returns the description of caches on FreeBSD PPC. */
131 static char *
132 detect_caches_freebsd (void)
134 unsigned l1_sizekb, l1_line, l1_assoc, l2_sizekb;
135 size_t len = 4;
137 /* Currently, as of FreeBSD-7.0, there is only the cacheline_size
138 available via sysctl. */
139 sysctlbyname ("machdep.cacheline_size", &l1_line, &len, NULL, 0);
141 l1_sizekb = 32;
142 l1_assoc = 0;
143 l2_sizekb = 512;
145 return describe_cache (l1_sizekb, l1_line, l1_assoc, l2_sizekb);
148 /* Currently returns default powerpc. */
149 static const char *
150 detect_processor_freebsd (void)
152 return "powerpc";
155 #endif /* __FreeBSD__ */
157 #ifdef __linux__
159 /* Returns AT_PLATFORM if present, otherwise generic PowerPC. */
161 static const char *
162 elf_platform (void)
164 int fd;
166 fd = open ("/proc/self/auxv", O_RDONLY);
168 if (fd != -1)
170 char buf[1024];
171 ElfW(auxv_t) *av;
172 ssize_t n;
174 n = read (fd, buf, sizeof (buf));
175 close (fd);
177 if (n > 0)
179 for (av = (ElfW(auxv_t) *) buf; av->a_type != AT_NULL; ++av)
180 switch (av->a_type)
182 case AT_PLATFORM:
183 return (const char *) av->a_un.a_val;
185 default:
186 break;
190 return NULL;
193 /* Returns AT_DCACHEBSIZE if present, otherwise generic 32. */
195 static int
196 elf_dcachebsize (void)
198 int fd;
200 fd = open ("/proc/self/auxv", O_RDONLY);
202 if (fd != -1)
204 char buf[1024];
205 ElfW(auxv_t) *av;
206 ssize_t n;
208 n = read (fd, buf, sizeof (buf));
209 close (fd);
211 if (n > 0)
213 for (av = (ElfW(auxv_t) *) buf; av->a_type != AT_NULL; ++av)
214 switch (av->a_type)
216 case AT_DCACHEBSIZE:
217 return av->a_un.a_val;
219 default:
220 break;
224 return 32;
227 /* Returns the description of caches on Linux. */
229 static char *
230 detect_caches_linux (void)
232 unsigned l1_sizekb, l1_line, l1_assoc, l2_sizekb;
233 const char *platform;
235 platform = elf_platform ();
237 if (platform != NULL)
239 l1_line = 128;
241 if (platform[5] == '6')
242 /* POWER6 and POWER6x */
243 l1_sizekb = 64;
244 else
245 l1_sizekb = 32;
247 else
249 l1_line = elf_dcachebsize ();
250 l1_sizekb = 32;
253 l1_assoc = 0;
254 l2_sizekb = 512;
256 return describe_cache (l1_sizekb, l1_line, l1_assoc, l2_sizekb);
259 static const char *
260 detect_processor_linux (void)
262 const char *platform;
264 platform = elf_platform ();
266 if (platform != NULL)
267 return platform;
268 else
269 return "powerpc";
272 #endif /* __linux__ */
274 #ifdef _AIX
275 /* Returns the description of caches on AIX. */
277 static char *
278 detect_caches_aix (void)
280 unsigned l1_sizekb, l1_line, l1_assoc, l2_sizekb;
282 l1_sizekb = _system_configuration.dcache_size / 1024;
283 l1_line = _system_configuration.dcache_line;
284 l1_assoc = _system_configuration.dcache_asc;
285 l2_sizekb = _system_configuration.L2_cache_size / 1024;
287 return describe_cache (l1_sizekb, l1_line, l1_assoc, l2_sizekb);
291 /* Returns the processor implementation on AIX. */
293 static const char *
294 detect_processor_aix (void)
296 switch (_system_configuration.implementation)
298 case 0x0008:
299 return "601";
301 case 0x0020:
302 return "603";
304 case 0x0010:
305 return "604";
307 case 0x0040:
308 return "620";
310 case 0x0080:
311 return "630";
313 case 0x0100:
314 case 0x0200:
315 case 0x0400:
316 return "rs64";
318 case 0x0800:
319 return "power4";
321 case 0x2000:
322 if (_system_configuration.version == 0x0F0000)
323 return "power5";
324 else
325 return "power5+";
327 case 0x4000:
328 return "power6";
330 case 0x8000:
331 return "power7";
333 case 0x10000:
334 return "power8";
336 case 0x20000:
337 return "power9";
339 default:
340 return "powerpc";
343 #endif /* _AIX */
347 * Array to map -mcpu=native names to the switches passed to the assembler.
348 * This list mirrors the specs in ASM_CPU_SPEC, and any changes made here
349 * should be made there as well.
352 struct asm_name {
353 const char *cpu;
354 const char *asm_sw;
357 static const struct asm_name asm_names[] = {
358 #if defined (_AIX)
359 { "power3", "-m620" },
360 { "power4", "-mpwr4" },
361 { "power5", "-mpwr5" },
362 { "power5+", "-mpwr5x" },
363 { "power6", "-mpwr6" },
364 { "power6x", "-mpwr6" },
365 { "power7", "-mpwr7" },
366 { "power8", "-mpwr8" },
367 { "power9", "-mpwr9" },
368 { "powerpc", "-mppc" },
369 { "rs64a", "-mppc" },
370 { "603", "-m603" },
371 { "603e", "-m603" },
372 { "604", "-m604" },
373 { "604e", "-m604" },
374 { "620", "-m620" },
375 { "630", "-m620" },
376 { "970", "-m970" },
377 { "G5", "-m970" },
378 { NULL, "\
379 %{!maix64: \
380 %{mpowerpc64: -mppc64} \
381 %{maltivec: -m970} \
382 %{!maltivec: %{!mpowerpc64: %(asm_default)}}}" },
384 #else
385 { "cell", "-mcell" },
386 { "power3", "-mppc64" },
387 { "power4", "-mpower4" },
388 { "power5", "%(asm_cpu_power5)" },
389 { "power5+", "%(asm_cpu_power5)" },
390 { "power6", "%(asm_cpu_power6) -maltivec" },
391 { "power6x", "%(asm_cpu_power6) -maltivec" },
392 { "power7", "%(asm_cpu_power7)" },
393 { "power8", "%(asm_cpu_power8)" },
394 { "power9", "%(asm_cpu_power9)" },
395 { "powerpc", "-mppc" },
396 { "rs64a", "-mppc64" },
397 { "401", "-mppc" },
398 { "403", "-m403" },
399 { "405", "-m405" },
400 { "405fp", "-m405" },
401 { "440", "-m440" },
402 { "440fp", "-m440" },
403 { "464", "-m440" },
404 { "464fp", "-m440" },
405 { "505", "-mppc" },
406 { "601", "-m601" },
407 { "602", "-mppc" },
408 { "603", "-mppc" },
409 { "603e", "-mppc" },
410 { "ec603e", "-mppc" },
411 { "604", "-mppc" },
412 { "604e", "-mppc" },
413 { "620", "-mppc64" },
414 { "630", "-mppc64" },
415 { "740", "-mppc" },
416 { "750", "-mppc" },
417 { "G3", "-mppc" },
418 { "7400", "-mppc -maltivec" },
419 { "7450", "-mppc -maltivec" },
420 { "G4", "-mppc -maltivec" },
421 { "801", "-mppc" },
422 { "821", "-mppc" },
423 { "823", "-mppc" },
424 { "860", "-mppc" },
425 { "970", "-mpower4 -maltivec" },
426 { "G5", "-mpower4 -maltivec" },
427 { "8540", "-me500" },
428 { "8548", "-me500" },
429 { "e300c2", "-me300" },
430 { "e300c3", "-me300" },
431 { "e500mc", "-me500mc" },
432 { NULL, "\
433 %{mpowerpc64*: -mppc64} \
434 %{!mpowerpc64*: %(asm_default)}" },
435 #endif
438 /* This will be called by the spec parser in gcc.c when it sees
439 a %:local_cpu_detect(args) construct. Currently it will be called
440 with either "arch" or "tune" as argument depending on if -march=native
441 or -mtune=native is to be substituted.
443 Additionally it will be called with "asm" to select the appropriate flags
444 for the assembler.
446 It returns a string containing new command line parameters to be
447 put at the place of the above two options, depending on what CPU
448 this is executed.
450 ARGC and ARGV are set depending on the actual arguments given
451 in the spec. */
452 const char *
453 host_detect_local_cpu (int argc, const char **argv)
455 const char *cpu = NULL;
456 const char *cache = "";
457 const char *options = "";
458 bool arch;
459 bool assembler;
460 size_t i;
462 if (argc < 1)
463 return NULL;
465 arch = strcmp (argv[0], "cpu") == 0;
466 assembler = (!arch && strcmp (argv[0], "asm") == 0);
467 if (!arch && !assembler && strcmp (argv[0], "tune"))
468 return NULL;
470 if (! assembler)
472 #if defined (_AIX)
473 cache = detect_caches_aix ();
474 #elif defined (__APPLE__)
475 cache = detect_caches_darwin ();
476 #elif defined (__FreeBSD__)
477 cache = detect_caches_freebsd ();
478 /* FreeBSD PPC does not provide any cache information yet. */
479 cache = "";
480 #elif defined (__linux__)
481 cache = detect_caches_linux ();
482 /* PPC Linux does not provide any cache information yet. */
483 cache = "";
484 #else
485 cache = "";
486 #endif
489 #if defined (_AIX)
490 cpu = detect_processor_aix ();
491 #elif defined (__APPLE__)
492 cpu = detect_processor_darwin ();
493 #elif defined (__FreeBSD__)
494 cpu = detect_processor_freebsd ();
495 #elif defined (__linux__)
496 cpu = detect_processor_linux ();
497 #else
498 cpu = "powerpc";
499 #endif
501 if (assembler)
503 for (i = 0; i < sizeof (asm_names) / sizeof (asm_names[0]); i++)
505 if (!asm_names[i].cpu || !strcmp (asm_names[i].cpu, cpu))
506 return asm_names[i].asm_sw;
509 return NULL;
512 return concat (cache, "-m", argv[0], "=", cpu, " ", options, NULL);
515 #else /* GCC_VERSION */
517 /* If we aren't compiling with GCC we just provide a minimal
518 default value. */
519 const char *
520 host_detect_local_cpu (int argc, const char **argv)
522 const char *cpu;
523 bool arch;
525 if (argc < 1)
526 return NULL;
528 arch = strcmp (argv[0], "cpu") == 0;
529 if (!arch && strcmp (argv[0], "tune"))
530 return NULL;
532 if (arch)
533 cpu = "powerpc";
535 return concat ("-m", argv[0], "=", cpu, NULL);
538 #endif /* GCC_VERSION */