1/* Subroutines for the gcc driver. 2 Copyright (C) 2011-2020 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#define IN_TARGET_CODE 1 21 22#include "config.h" 23#include "system.h" 24#include "coretypes.h" 25#include "tm.h" 26 27static const struct cpu_names { 28 const char *const name; 29 const char *const cpu; 30} cpu_names[] = { 31#if defined __sun__ && defined __svr4__ 32 { "TMS390S10", "supersparc" }, /* Texas Instruments microSPARC I */ 33 { "TMS390Z50", "supersparc" }, /* Texas Instruments SuperSPARC I */ 34 { "TMS390Z55", "supersparc" }, /* Texas Instruments 35 SuperSPARC I with SuperCache */ 36 { "MB86904", "supersparc" }, /* Fujitsu microSPARC II */ 37 { "MB86907", "supersparc" }, /* Fujitsu TurboSPARC */ 38 { "RT623", "hypersparc" }, /* Ross hyperSPARC */ 39 { "RT625", "hypersparc" }, 40 { "RT626", "hypersparc" }, 41 { "UltraSPARC-I", "ultrasparc" }, 42 { "UltraSPARC-II", "ultrasparc" }, 43 { "UltraSPARC-IIe", "ultrasparc" }, 44 { "UltraSPARC-IIi", "ultrasparc" }, 45 { "SPARC64-III", "ultrasparc" }, 46 { "SPARC64-IV", "ultrasparc" }, 47 { "UltraSPARC-III", "ultrasparc3" }, 48 { "UltraSPARC-III+", "ultrasparc3" }, 49 { "UltraSPARC-IIIi", "ultrasparc3" }, 50 { "UltraSPARC-IIIi+", "ultrasparc3" }, 51 { "UltraSPARC-IV", "ultrasparc3" }, 52 { "UltraSPARC-IV+", "ultrasparc3" }, 53 { "SPARC64-V", "ultrasparc3" }, 54 { "SPARC64-VI", "ultrasparc3" }, 55 { "SPARC64-VII", "ultrasparc3" }, 56 { "UltraSPARC-T1", "niagara" }, 57 { "UltraSPARC-T2", "niagara2" }, 58 { "UltraSPARC-T2", "niagara2" }, 59 { "UltraSPARC-T2+", "niagara2" }, 60 { "SPARC-T3", "niagara3" }, 61 { "SPARC-T4", "niagara4" }, 62 { "SPARC-T5", "niagara4" }, 63#else 64 { "SuperSparc", "supersparc" }, 65 { "HyperSparc", "hypersparc" }, 66 { "SpitFire", "ultrasparc" }, 67 { "BlackBird", "ultrasparc" }, 68 { "Sabre", "ultrasparc" }, 69 { "Hummingbird", "ultrasparc" }, 70 { "Cheetah", "ultrasparc3" }, 71 { "Jalapeno", "ultrasparc3" }, 72 { "Jaguar", "ultrasparc3" }, 73 { "Panther", "ultrasparc3" }, 74 { "Serrano", "ultrasparc3" }, 75 { "UltraSparc T1", "niagara" }, 76 { "UltraSparc T2", "niagara2" }, 77 { "UltraSparc T3", "niagara3" }, 78 { "UltraSparc T4", "niagara4" }, 79 { "UltraSparc T5", "niagara4" }, 80 { "LEON", "leon3" }, 81#endif 82 { "SPARC-M7", "niagara7" }, 83 { "SPARC-S7", "niagara7" }, 84 { "SPARC-M8", "m8" }, 85 { NULL, NULL } 86 }; 87 88#if defined __sun__ && defined __svr4__ 89#include <kstat.h> 90#endif 91 92/* This will be called by the spec parser in gcc.c when it sees 93 a %:local_cpu_detect(args) construct. Currently it will be called 94 with either "cpu" or "tune" as argument depending on if -mcpu=native 95 or -mtune=native is to be substituted. 96 97 It returns a string containing new command line parameters to be 98 put at the place of the above two options, depending on what CPU 99 this is executed. E.g. "-mcpu=ultrasparc3" on an UltraSPARC III for 100 -mcpu=native. If the routine can't detect a known processor, 101 the -mcpu or -mtune option is discarded. 102 103 ARGC and ARGV are set depending on the actual arguments given 104 in the spec. */ 105const char * 106host_detect_local_cpu (int argc, const char **argv) 107{ 108 const char *cpu = NULL; 109#if defined __sun__ && defined __svr4__ 110 char *buf = NULL; 111 kstat_ctl_t *kc; 112 kstat_t *ksp; 113 kstat_named_t *brand = NULL; 114#else 115 char buf[128]; 116 FILE *f; 117#endif 118 int i; 119 120 if (argc < 1) 121 return NULL; 122 123 if (strcmp (argv[0], "cpu") && strcmp (argv[0], "tune")) 124 return NULL; 125 126#if defined __sun__ && defined __svr4__ 127 kc = kstat_open (); 128 if (kc != NULL) 129 { 130 ksp = kstat_lookup (kc, CONST_CAST2 (char *, const char *, "cpu_info"), 131 -1, NULL); 132 if (ksp != NULL 133 && kstat_read (kc, ksp, NULL) != -1 134 && ksp->ks_type == KSTAT_TYPE_NAMED) 135 brand = (kstat_named_t *) 136 kstat_data_lookup (ksp, CONST_CAST2 (char *, const char *, "brand")); 137 if (brand != NULL && brand->data_type == KSTAT_DATA_STRING) 138 buf = KSTAT_NAMED_STR_PTR (brand); 139 } 140 kstat_close (kc); 141 142 for (i = 0; cpu_names[i].name != NULL; i++) 143 if (strcmp (buf, cpu_names[i].name) == 0) 144 cpu = cpu_names[i].cpu; 145#else 146 f = fopen ("/proc/cpuinfo", "r"); 147 if (f == NULL) 148 return NULL; 149 150 while (fgets (buf, sizeof (buf), f) != NULL) 151 if (strncmp (buf, "cpu\t\t:", sizeof ("cpu\t\t:") - 1) == 0) 152 { 153 for (i = 0; cpu_names [i].name; i++) 154 if (strstr (buf, cpu_names [i].name) != NULL) 155 { 156 cpu = cpu_names [i].cpu; 157 break; 158 } 159 break; 160 } 161 162 fclose (f); 163#endif 164 165 if (cpu == NULL) 166 return NULL; 167 168 return concat ("-m", argv[0], "=", cpu, NULL); 169} 170