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