OSDN Git Service

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