]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/rs6000/driver-rs6000.cc
Change references of .c files to .cc files
[thirdparty/gcc.git] / gcc / config / rs6000 / driver-rs6000.cc
CommitLineData
0eab6840 1/* Subroutines for the gcc driver.
7adcbafe 2 Copyright (C) 2007-2022 Free Software Foundation, Inc.
0eab6840
DE
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 3, or (at your option)
9any later version.
10
11GCC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
19
8fcc61f8
RS
20#define IN_TARGET_CODE 1
21
0eab6840
DE
22#include "config.h"
23#include "system.h"
24#include "coretypes.h"
25#include "tm.h"
6a92e053
PB
26#include "diagnostic.h"
27#include "opts.h"
0eab6840
DE
28#include <stdlib.h>
29
30#ifdef _AIX
31# include <sys/systemcfg.h>
32#endif
33
34#ifdef __linux__
656ca3ad 35# include <link.h>
0eab6840
DE
36#endif
37
3b7abfda 38#if defined (__APPLE__) || (__FreeBSD__)
0eab6840
DE
39# include <sys/types.h>
40# include <sys/sysctl.h>
41#endif
42
6a92e053
PB
43#ifdef __linux__
44/* Canonical GCC cpu name table. */
45static 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
57static 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
0eab6840
DE
81const 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
88static char *
89describe_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
108static char *
109detect_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
126static const char *
127detect_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
3b7abfda
AT
169#ifdef __FreeBSD__
170
171/* Returns the description of caches on FreeBSD PPC. */
172
173static char *
174detect_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. */
191static const char *
192detect_processor_freebsd (void)
193{
194 return "powerpc";
195}
196
197#endif /* __FreeBSD__ */
198
0eab6840
DE
199#ifdef __linux__
200
6a92e053 201/* Returns the canonical AT_PLATFORM if present, otherwise NULL. */
0eab6840
DE
202
203static const char *
204elf_platform (void)
205{
6a92e053
PB
206 /* Used to cache the result we determine below. */
207 static const char *cpu = NULL;
0eab6840 208
6a92e053
PB
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);
0eab6840
DE
214
215 if (fd != -1)
216 {
567969e4 217 char buf[1024];
656ca3ad 218 ElfW(auxv_t) *av;
0eab6840
DE
219 ssize_t n;
220
221 n = read (fd, buf, sizeof (buf));
222 close (fd);
223
224 if (n > 0)
225 {
656ca3ad 226 for (av = (ElfW(auxv_t) *) buf; av->a_type != AT_NULL; ++av)
6a92e053 227 if (av->a_type == AT_PLATFORM)
0eab6840 228 {
6a92e053
PB
229 /* Cache the result. */
230 cpu = (const char *) av->a_un.a_val;
0eab6840
DE
231 break;
232 }
233 }
6a92e053
PB
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);
cb7ac91b
ML
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);
6a92e053 270 }
0eab6840
DE
271 }
272 return NULL;
273}
274
19e34aa2 275/* Returns AT_DCACHEBSIZE if present, otherwise generic 32. */
0eab6840
DE
276
277static int
278elf_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];
656ca3ad 287 ElfW(auxv_t) *av;
0eab6840
DE
288 ssize_t n;
289
290 n = read (fd, buf, sizeof (buf));
291 close (fd);
292
293 if (n > 0)
294 {
656ca3ad 295 for (av = (ElfW(auxv_t) *) buf; av->a_type != AT_NULL; ++av)
0eab6840
DE
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
311static char *
312detect_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
341static const char *
342detect_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
359static char *
360detect_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
375static const char *
376detect_processor_aix (void)
377{
378 switch (_system_configuration.implementation)
379 {
0eab6840
DE
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
b9f12a01
DE
412 case 0x8000:
413 return "power7";
414
415 case 0x10000:
416 return "power8";
417
5128d392
DE
418 case 0x20000:
419 return "power9";
420
e3dbd2e1
DE
421 case 0x40000:
422 return "power10";
423
0eab6840
DE
424 default:
425 return "powerpc";
426 }
427}
428#endif /* _AIX */
429
430
cacf1ca8
MM
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
437struct asm_name {
438 const char *cpu;
439 const char *asm_sw;
440};
441
442static 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" },
428bffcb 451 { "power8", "-mpwr8" },
2e987dd5 452 { "power9", "-mpwr9" },
5d9d0c94 453 { "power10", "-mpwr10" },
cacf1ca8 454 { "powerpc", "-mppc" },
f7bdd292 455 { "rs64", "-mppc" },
cacf1ca8
MM
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, "\
28a09576
AM
465 %{mvsx: -mpwr6; \
466 maltivec: -m970; \
467 maix64|mpowerpc64: -mppc64; \
468 : %(asm_default)}" },
cacf1ca8
MM
469
470#else
cacf1ca8 471 { "cell", "-mcell" },
cacf1ca8
MM
472 { "power3", "-mppc64" },
473 { "power4", "-mpower4" },
68cf2892
SB
474 { "power5", "-mpower5" },
475 { "power5+", "-mpower5" },
28a09576
AM
476 { "power6", "-mpower6 %{!mvsx:%{!maltivec:-maltivec}}" },
477 { "power6x", "-mpower6 %{!mvsx:%{!maltivec:-maltivec}}" },
68cf2892 478 { "power7", "-mpower7" },
28a09576 479 { "power8", "%{mpower9-vector:-mpower9;:-mpower8}" },
68cf2892 480 { "power9", "-mpower9" },
5d9d0c94 481 { "power10", "-mpower10" },
28a09576 482 { "a2", "-ma2" },
cacf1ca8 483 { "powerpc", "-mppc" },
f7bdd292 484 { "powerpc64", "-mppc64" },
28a09576 485 { "powerpc64le", "%{mpower9-vector:-mpower9;:-mpower8}" },
f7bdd292 486 { "rs64", "-mppc64" },
cacf1ca8
MM
487 { "401", "-mppc" },
488 { "403", "-m403" },
489 { "405", "-m405" },
490 { "405fp", "-m405" },
491 { "440", "-m440" },
492 { "440fp", "-m440" },
493 { "464", "-m440" },
494 { "464fp", "-m440" },
28a09576
AM
495 { "476", "-m476" },
496 { "476fp", "-m476" },
cacf1ca8
MM
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" },
28a09576
AM
510 { "7400", "-mppc %{!mvsx:%{!maltivec:-maltivec}}" },
511 { "7450", "-mppc %{!mvsx:%{!maltivec:-maltivec}}" },
512 { "G4", "-mppc %{!mvsx:%{!maltivec:-maltivec}}" },
cacf1ca8
MM
513 { "801", "-mppc" },
514 { "821", "-mppc" },
515 { "823", "-mppc" },
516 { "860", "-mppc" },
28a09576
AM
517 { "970", "-mpower4 %{!mvsx:%{!maltivec:-maltivec}}" },
518 { "G5", "-mpower4 %{!mvsx:%{!maltivec:-maltivec}}" },
cacf1ca8
MM
519 { "8540", "-me500" },
520 { "8548", "-me500" },
521 { "e300c2", "-me300" },
522 { "e300c3", "-me300" },
523 { "e500mc", "-me500mc" },
28a09576
AM
524 { "e500mc64", "-me500mc64" },
525 { "e5500", "-me5500" },
526 { "e6500", "-me6500" },
f7bdd292 527 { "titan", "-mtitan" },
cacf1ca8 528 { NULL, "\
28a09576
AM
529%{mpower9-vector: -mpower9; \
530 mpower8-vector|mcrypto|mdirect-move|mhtm: -mpower8; \
531 mvsx: -mpower7; \
532 mpowerpc64: -mppc64; \
533 : %(asm_default)}" },
cacf1ca8
MM
534#endif
535};
536
e53b6e56 537/* This will be called by the spec parser in gcc.cc when it sees
0eab6840
DE
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
cacf1ca8
MM
542 Additionally it will be called with "asm" to select the appropriate flags
543 for the assembler.
544
0eab6840
DE
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. */
cacf1ca8
MM
551const char *
552host_detect_local_cpu (int argc, const char **argv)
0eab6840
DE
553{
554 const char *cpu = NULL;
555 const char *cache = "";
556 const char *options = "";
557 bool arch;
cacf1ca8
MM
558 bool assembler;
559 size_t i;
0eab6840
DE
560
561 if (argc < 1)
562 return NULL;
563
564 arch = strcmp (argv[0], "cpu") == 0;
cacf1ca8
MM
565 assembler = (!arch && strcmp (argv[0], "asm") == 0);
566 if (!arch && !assembler && strcmp (argv[0], "tune"))
0eab6840
DE
567 return NULL;
568
cacf1ca8
MM
569 if (! assembler)
570 {
0eab6840 571#if defined (_AIX)
cacf1ca8 572 cache = detect_caches_aix ();
0eab6840 573#elif defined (__APPLE__)
cacf1ca8 574 cache = detect_caches_darwin ();
3b7abfda 575#elif defined (__FreeBSD__)
cacf1ca8
MM
576 cache = detect_caches_freebsd ();
577 /* FreeBSD PPC does not provide any cache information yet. */
578 cache = "";
0eab6840 579#elif defined (__linux__)
cacf1ca8
MM
580 cache = detect_caches_linux ();
581 /* PPC Linux does not provide any cache information yet. */
582 cache = "";
0eab6840 583#else
cacf1ca8 584 cache = "";
0eab6840 585#endif
cacf1ca8 586 }
0eab6840
DE
587
588#if defined (_AIX)
589 cpu = detect_processor_aix ();
590#elif defined (__APPLE__)
591 cpu = detect_processor_darwin ();
3b7abfda
AT
592#elif defined (__FreeBSD__)
593 cpu = detect_processor_freebsd ();
0eab6840
DE
594#elif defined (__linux__)
595 cpu = detect_processor_linux ();
596#else
597 cpu = "powerpc";
598#endif
599
cacf1ca8
MM
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
0eab6840
DE
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. */
cacf1ca8
MM
618const char *
619host_detect_local_cpu (int argc, const char **argv)
0eab6840
DE
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