]>
Commit | Line | Data |
---|---|---|
cb0edc39 | 1 | /* Subroutines for the gcc driver. |
a5544970 | 2 | Copyright (C) 2015-2019 Free Software Foundation, Inc. |
cb0edc39 DV |
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 | ||
8fcc61f8 RS |
20 | #define IN_TARGET_CODE 1 |
21 | ||
cb0edc39 DV |
22 | #include "config.h" |
23 | #include "system.h" | |
24 | #include "coretypes.h" | |
25 | #include "tm.h" | |
26 | ||
27 | /* This will be called by the spec parser in gcc.c when it sees | |
28 | a %:local_cpu_detect(args) construct. Currently it will be called | |
29 | with either "arch" or "tune" as argument depending on if -march=native | |
30 | or -mtune=native is to be substituted. | |
31 | ||
32 | It returns a string containing new command line parameters to be | |
33 | put at the place of the above two options, depending on what CPU | |
34 | this is executed. E.g. "-march=zEC12" on a zEC12 for -march=native. | |
35 | If the routine can't detect a known processor, the -march or -mtune | |
36 | option is discarded. | |
37 | ||
38 | ARGC and ARGV are set depending on the actual arguments given | |
39 | in the spec. */ | |
40 | const char * | |
41 | s390_host_detect_local_cpu (int argc, const char **argv) | |
42 | { | |
43 | const char *cpu = NULL; | |
44 | char buf[256]; | |
45 | FILE *f; | |
46 | bool arch; | |
b1b5aa2f DV |
47 | const char *options = ""; |
48 | unsigned int has_features; | |
49 | unsigned int has_processor; | |
50 | unsigned int is_cpu_z9_109 = 0; | |
51 | unsigned int has_highgprs = 0; | |
52 | unsigned int has_dfp = 0; | |
53 | unsigned int has_te = 0; | |
54 | unsigned int has_vx = 0; | |
55 | unsigned int has_opt_esa_zarch = 0; | |
56 | int i; | |
cb0edc39 DV |
57 | |
58 | if (argc < 1) | |
59 | return NULL; | |
60 | ||
61 | arch = strcmp (argv[0], "arch") == 0; | |
62 | if (!arch && strcmp (argv[0], "tune")) | |
63 | return NULL; | |
b1b5aa2f DV |
64 | for (i = 1; i < argc; i++) |
65 | if (strcmp (argv[i], "mesa_mzarch") == 0) | |
66 | has_opt_esa_zarch = 1; | |
cb0edc39 DV |
67 | |
68 | f = fopen ("/proc/cpuinfo", "r"); | |
69 | if (f == NULL) | |
70 | return NULL; | |
71 | ||
b1b5aa2f DV |
72 | for (has_features = 0, has_processor = 0; |
73 | (has_features == 0 || has_processor == 0) | |
74 | && fgets (buf, sizeof (buf), f) != NULL; ) | |
75 | { | |
76 | if (has_processor == 0 && strncmp (buf, "processor", 9) == 0) | |
77 | { | |
78 | const char *p; | |
79 | long machine_id; | |
80 | ||
81 | p = strstr (buf, "machine = "); | |
82 | if (p == NULL) | |
83 | continue; | |
84 | p += 10; | |
85 | has_processor = 1; | |
86 | machine_id = strtol (p, NULL, 16); | |
87 | switch (machine_id) | |
88 | { | |
b1b5aa2f DV |
89 | case 0x2064: |
90 | case 0x2066: | |
91 | cpu = "z900"; | |
92 | break; | |
93 | case 0x2084: | |
94 | case 0x2086: | |
95 | cpu = "z990"; | |
96 | break; | |
97 | case 0x2094: | |
98 | case 0x2096: | |
99 | cpu = "z9-109"; | |
100 | is_cpu_z9_109 = 1; | |
101 | break; | |
102 | case 0x2097: | |
103 | case 0x2098: | |
104 | cpu = "z10"; | |
105 | break; | |
106 | case 0x2817: | |
107 | case 0x2818: | |
108 | cpu = "z196"; | |
109 | break; | |
110 | case 0x2827: | |
111 | case 0x2828: | |
112 | cpu = "zEC12"; | |
113 | break; | |
114 | case 0x2964: | |
2731a5b3 | 115 | case 0x2965: |
b1b5aa2f DV |
116 | cpu = "z13"; |
117 | break; | |
2731a5b3 | 118 | case 0x3906: |
3c609d36 | 119 | case 0x3907: |
2731a5b3 AK |
120 | cpu = "z14"; |
121 | break; | |
6654e96f | 122 | default: |
2731a5b3 | 123 | cpu = "z14"; |
6654e96f | 124 | break; |
b1b5aa2f DV |
125 | } |
126 | } | |
127 | if (has_features == 0 && strncmp (buf, "features", 8) == 0) | |
128 | { | |
129 | const char *p; | |
130 | ||
131 | p = strchr (buf, ':'); | |
132 | if (p == NULL) | |
133 | continue; | |
134 | p++; | |
135 | while (*p != 0) | |
136 | { | |
137 | int i; | |
138 | ||
139 | while (ISSPACE (*p)) | |
140 | p++; | |
141 | for (i = 0; !ISSPACE (p[i]) && p[i] != 0; i++) | |
142 | ; | |
143 | if (i == 3 && strncmp (p, "dfp", 3) == 0) | |
144 | has_dfp = 1; | |
145 | else if (i == 2 && strncmp (p, "te", 2) == 0) | |
146 | has_te = 1; | |
147 | else if (i == 2 && strncmp (p, "vx", 2) == 0) | |
148 | has_vx = 1; | |
149 | else if (i == 8 && strncmp (p, "highgprs", 8) == 0) | |
150 | has_highgprs = 1; | |
151 | p += i; | |
152 | } | |
153 | has_features = 1; | |
154 | } | |
155 | } | |
cb0edc39 DV |
156 | |
157 | fclose (f); | |
158 | ||
159 | if (cpu == NULL) | |
160 | return NULL; | |
161 | ||
b1b5aa2f DV |
162 | if (arch) |
163 | { | |
164 | const char *opt_htm = ""; | |
165 | const char *opt_vx = ""; | |
166 | const char *opt_esa_zarch = ""; | |
167 | ||
168 | /* We may switch off these cpu features but never switch the on | |
169 | explicitly. This overrides options specified on the command line. */ | |
170 | if (!has_te) | |
171 | opt_htm = " -mno-htm"; | |
172 | if (!has_vx) | |
173 | opt_vx = " -mno-vx"; | |
174 | /* However, we set -mzarch only if neither -mzarch nor -mesa are used on | |
175 | the command line. This allows the user to switch to -mesa manually. | |
176 | */ | |
177 | if (!has_opt_esa_zarch && has_highgprs) | |
178 | opt_esa_zarch = " -mzarch"; | |
179 | options = concat (options, opt_htm, opt_vx, opt_esa_zarch, NULL); | |
180 | } | |
181 | if (has_dfp && is_cpu_z9_109) | |
182 | cpu = "z9-ec"; | |
183 | ||
184 | return concat ("-m", argv[0], "=", cpu, options, NULL); | |
cb0edc39 | 185 | } |