]>
Commit | Line | Data |
---|---|---|
fa959ce4 | 1 | /* Subroutines for the gcc driver. |
83ffe9cd | 2 | Copyright (C) 2006-2023 Free Software Foundation, Inc. |
fa959ce4 MM |
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 | |
2f83c7d6 | 8 | the Free Software Foundation; either version 3, or (at your option) |
fa959ce4 MM |
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 | |
2f83c7d6 NC |
17 | along with GCC; see the file COPYING3. If not see |
18 | <http://www.gnu.org/licenses/>. */ | |
fa959ce4 | 19 | |
8fcc61f8 RS |
20 | #define IN_TARGET_CODE 1 |
21 | ||
fa959ce4 MM |
22 | #include "config.h" |
23 | #include "system.h" | |
edccdcb1 L |
24 | #include "coretypes.h" |
25 | #include "tm.h" | |
fa959ce4 | 26 | |
895016f6 UB |
27 | const char *host_detect_local_cpu (int argc, const char **argv); |
28 | ||
02147868 | 29 | #if defined(__GNUC__) && (__GNUC__ >= 5 || !defined(__PIC__)) |
b3172cab | 30 | #include "cpuid.h" |
6c35d16a L |
31 | #include "common/config/i386/cpuinfo.h" |
32 | #include "common/config/i386/i386-isas.h" | |
fa959ce4 | 33 | |
cb0dee88 UB |
34 | struct cache_desc |
35 | { | |
36 | unsigned sizekb; | |
37 | unsigned assoc; | |
38 | unsigned line; | |
39 | }; | |
40 | ||
41 | /* Returns command line parameters that describe size and | |
42 | cache line size of the processor caches. */ | |
2711355f ZD |
43 | |
44 | static char * | |
cb0dee88 | 45 | describe_cache (struct cache_desc level1, struct cache_desc level2) |
2711355f | 46 | { |
f4a1dd0d | 47 | char size[100], line[100], size2[100]; |
2711355f | 48 | |
cb0dee88 UB |
49 | /* At the moment, gcc does not use the information |
50 | about the associativity of the cache. */ | |
51 | ||
f3afc8a7 UB |
52 | snprintf (size, sizeof (size), |
53 | "--param l1-cache-size=%u ", level1.sizekb); | |
54 | snprintf (line, sizeof (line), | |
55 | "--param l1-cache-line-size=%u ", level1.line); | |
2711355f | 56 | |
f3afc8a7 UB |
57 | snprintf (size2, sizeof (size2), |
58 | "--param l2-cache-size=%u ", level2.sizekb); | |
2711355f | 59 | |
f3afc8a7 | 60 | return concat (size, line, size2, NULL); |
f4a1dd0d ZM |
61 | } |
62 | ||
cb0dee88 UB |
63 | /* Detect L2 cache parameters using CPUID extended function 0x80000006. */ |
64 | ||
f4a1dd0d | 65 | static void |
cb0dee88 | 66 | detect_l2_cache (struct cache_desc *level2) |
f4a1dd0d | 67 | { |
cb0dee88 UB |
68 | unsigned eax, ebx, ecx, edx; |
69 | unsigned assoc; | |
f4a1dd0d ZM |
70 | |
71 | __cpuid (0x80000006, eax, ebx, ecx, edx); | |
72 | ||
cb0dee88 UB |
73 | level2->sizekb = (ecx >> 16) & 0xffff; |
74 | level2->line = ecx & 0xff; | |
75 | ||
f4a1dd0d ZM |
76 | assoc = (ecx >> 12) & 0xf; |
77 | if (assoc == 6) | |
78 | assoc = 8; | |
79 | else if (assoc == 8) | |
80 | assoc = 16; | |
81 | else if (assoc >= 0xa && assoc <= 0xc) | |
82 | assoc = 32 + (assoc - 0xa) * 16; | |
83 | else if (assoc >= 0xd && assoc <= 0xe) | |
84 | assoc = 96 + (assoc - 0xd) * 32; | |
cb0dee88 UB |
85 | |
86 | level2->assoc = assoc; | |
2711355f ZD |
87 | } |
88 | ||
89 | /* Returns the description of caches for an AMD processor. */ | |
90 | ||
d3bfe4de | 91 | static const char * |
2711355f ZD |
92 | detect_caches_amd (unsigned max_ext_level) |
93 | { | |
94 | unsigned eax, ebx, ecx, edx; | |
cb0dee88 UB |
95 | |
96 | struct cache_desc level1, level2 = {0, 0, 0}; | |
2711355f ZD |
97 | |
98 | if (max_ext_level < 0x80000005) | |
d3bfe4de | 99 | return ""; |
2711355f | 100 | |
b3172cab | 101 | __cpuid (0x80000005, eax, ebx, ecx, edx); |
2711355f | 102 | |
cb0dee88 UB |
103 | level1.sizekb = (ecx >> 24) & 0xff; |
104 | level1.assoc = (ecx >> 16) & 0xff; | |
105 | level1.line = ecx & 0xff; | |
2711355f | 106 | |
f4a1dd0d | 107 | if (max_ext_level >= 0x80000006) |
cb0dee88 | 108 | detect_l2_cache (&level2); |
f4a1dd0d | 109 | |
cb0dee88 | 110 | return describe_cache (level1, level2); |
2711355f ZD |
111 | } |
112 | ||
cb0dee88 UB |
113 | /* Decodes the size, the associativity and the cache line size of |
114 | L1/L2 caches of an Intel processor. Values are based on | |
115 | "Intel Processor Identification and the CPUID Instruction" | |
116 | [Application Note 485], revision -032, December 2007. */ | |
2711355f ZD |
117 | |
118 | static void | |
cb0dee88 UB |
119 | decode_caches_intel (unsigned reg, bool xeon_mp, |
120 | struct cache_desc *level1, struct cache_desc *level2) | |
2711355f | 121 | { |
cb0dee88 UB |
122 | int i; |
123 | ||
124 | for (i = 24; i >= 0; i -= 8) | |
125 | switch ((reg >> i) & 0xff) | |
126 | { | |
127 | case 0x0a: | |
128 | level1->sizekb = 8; level1->assoc = 2; level1->line = 32; | |
129 | break; | |
130 | case 0x0c: | |
131 | level1->sizekb = 16; level1->assoc = 4; level1->line = 32; | |
132 | break; | |
f313cce5 UB |
133 | case 0x0d: |
134 | level1->sizekb = 16; level1->assoc = 4; level1->line = 64; | |
135 | break; | |
136 | case 0x0e: | |
137 | level1->sizekb = 24; level1->assoc = 6; level1->line = 64; | |
138 | break; | |
139 | case 0x21: | |
140 | level2->sizekb = 256; level2->assoc = 8; level2->line = 64; | |
141 | break; | |
142 | case 0x24: | |
143 | level2->sizekb = 1024; level2->assoc = 16; level2->line = 64; | |
144 | break; | |
cb0dee88 UB |
145 | case 0x2c: |
146 | level1->sizekb = 32; level1->assoc = 8; level1->line = 64; | |
147 | break; | |
148 | case 0x39: | |
149 | level2->sizekb = 128; level2->assoc = 4; level2->line = 64; | |
150 | break; | |
151 | case 0x3a: | |
152 | level2->sizekb = 192; level2->assoc = 6; level2->line = 64; | |
153 | break; | |
154 | case 0x3b: | |
155 | level2->sizekb = 128; level2->assoc = 2; level2->line = 64; | |
156 | break; | |
157 | case 0x3c: | |
158 | level2->sizekb = 256; level2->assoc = 4; level2->line = 64; | |
159 | break; | |
160 | case 0x3d: | |
161 | level2->sizekb = 384; level2->assoc = 6; level2->line = 64; | |
162 | break; | |
163 | case 0x3e: | |
164 | level2->sizekb = 512; level2->assoc = 4; level2->line = 64; | |
165 | break; | |
166 | case 0x41: | |
167 | level2->sizekb = 128; level2->assoc = 4; level2->line = 32; | |
168 | break; | |
169 | case 0x42: | |
170 | level2->sizekb = 256; level2->assoc = 4; level2->line = 32; | |
171 | break; | |
172 | case 0x43: | |
173 | level2->sizekb = 512; level2->assoc = 4; level2->line = 32; | |
174 | break; | |
175 | case 0x44: | |
176 | level2->sizekb = 1024; level2->assoc = 4; level2->line = 32; | |
177 | break; | |
178 | case 0x45: | |
179 | level2->sizekb = 2048; level2->assoc = 4; level2->line = 32; | |
180 | break; | |
f313cce5 UB |
181 | case 0x48: |
182 | level2->sizekb = 3072; level2->assoc = 12; level2->line = 64; | |
183 | break; | |
cb0dee88 UB |
184 | case 0x49: |
185 | if (xeon_mp) | |
186 | break; | |
187 | level2->sizekb = 4096; level2->assoc = 16; level2->line = 64; | |
188 | break; | |
189 | case 0x4e: | |
190 | level2->sizekb = 6144; level2->assoc = 24; level2->line = 64; | |
191 | break; | |
192 | case 0x60: | |
193 | level1->sizekb = 16; level1->assoc = 8; level1->line = 64; | |
194 | break; | |
195 | case 0x66: | |
196 | level1->sizekb = 8; level1->assoc = 4; level1->line = 64; | |
197 | break; | |
198 | case 0x67: | |
199 | level1->sizekb = 16; level1->assoc = 4; level1->line = 64; | |
200 | break; | |
201 | case 0x68: | |
202 | level1->sizekb = 32; level1->assoc = 4; level1->line = 64; | |
203 | break; | |
204 | case 0x78: | |
205 | level2->sizekb = 1024; level2->assoc = 4; level2->line = 64; | |
206 | break; | |
207 | case 0x79: | |
208 | level2->sizekb = 128; level2->assoc = 8; level2->line = 64; | |
209 | break; | |
210 | case 0x7a: | |
211 | level2->sizekb = 256; level2->assoc = 8; level2->line = 64; | |
212 | break; | |
213 | case 0x7b: | |
214 | level2->sizekb = 512; level2->assoc = 8; level2->line = 64; | |
215 | break; | |
216 | case 0x7c: | |
217 | level2->sizekb = 1024; level2->assoc = 8; level2->line = 64; | |
218 | break; | |
219 | case 0x7d: | |
220 | level2->sizekb = 2048; level2->assoc = 8; level2->line = 64; | |
221 | break; | |
222 | case 0x7f: | |
223 | level2->sizekb = 512; level2->assoc = 2; level2->line = 64; | |
224 | break; | |
f313cce5 UB |
225 | case 0x80: |
226 | level2->sizekb = 512; level2->assoc = 8; level2->line = 64; | |
227 | break; | |
cb0dee88 UB |
228 | case 0x82: |
229 | level2->sizekb = 256; level2->assoc = 8; level2->line = 32; | |
230 | break; | |
231 | case 0x83: | |
232 | level2->sizekb = 512; level2->assoc = 8; level2->line = 32; | |
233 | break; | |
234 | case 0x84: | |
235 | level2->sizekb = 1024; level2->assoc = 8; level2->line = 32; | |
236 | break; | |
237 | case 0x85: | |
238 | level2->sizekb = 2048; level2->assoc = 8; level2->line = 32; | |
239 | break; | |
240 | case 0x86: | |
241 | level2->sizekb = 512; level2->assoc = 4; level2->line = 64; | |
242 | break; | |
243 | case 0x87: | |
244 | level2->sizekb = 1024; level2->assoc = 8; level2->line = 64; | |
245 | ||
246 | default: | |
247 | break; | |
248 | } | |
249 | } | |
2711355f | 250 | |
cb0dee88 | 251 | /* Detect cache parameters using CPUID function 2. */ |
2711355f | 252 | |
cb0dee88 UB |
253 | static void |
254 | detect_caches_cpuid2 (bool xeon_mp, | |
255 | struct cache_desc *level1, struct cache_desc *level2) | |
256 | { | |
dc8bd8d9 UB |
257 | unsigned regs[4]; |
258 | int nreps, i; | |
cb0dee88 | 259 | |
dc8bd8d9 | 260 | __cpuid (2, regs[0], regs[1], regs[2], regs[3]); |
cb0dee88 | 261 | |
dc8bd8d9 UB |
262 | nreps = regs[0] & 0x0f; |
263 | regs[0] &= ~0x0f; | |
cb0dee88 UB |
264 | |
265 | while (--nreps >= 0) | |
2711355f | 266 | { |
dc8bd8d9 UB |
267 | for (i = 0; i < 4; i++) |
268 | if (regs[i] && !((regs[i] >> 31) & 1)) | |
269 | decode_caches_intel (regs[i], xeon_mp, level1, level2); | |
cb0dee88 UB |
270 | |
271 | if (nreps) | |
dc8bd8d9 | 272 | __cpuid (2, regs[0], regs[1], regs[2], regs[3]); |
cb0dee88 UB |
273 | } |
274 | } | |
2711355f | 275 | |
cb0dee88 UB |
276 | /* Detect cache parameters using CPUID function 4. This |
277 | method doesn't require hardcoded tables. */ | |
2711355f | 278 | |
cb0dee88 UB |
279 | enum cache_type |
280 | { | |
281 | CACHE_END = 0, | |
282 | CACHE_DATA = 1, | |
283 | CACHE_INST = 2, | |
284 | CACHE_UNIFIED = 3 | |
285 | }; | |
286 | ||
287 | static void | |
a0463099 AK |
288 | detect_caches_cpuid4 (struct cache_desc *level1, struct cache_desc *level2, |
289 | struct cache_desc *level3) | |
cb0dee88 UB |
290 | { |
291 | struct cache_desc *cache; | |
292 | ||
293 | unsigned eax, ebx, ecx, edx; | |
294 | int count; | |
295 | ||
296 | for (count = 0;; count++) | |
297 | { | |
298 | __cpuid_count(4, count, eax, ebx, ecx, edx); | |
299 | switch (eax & 0x1f) | |
300 | { | |
301 | case CACHE_END: | |
302 | return; | |
303 | case CACHE_DATA: | |
304 | case CACHE_UNIFIED: | |
305 | { | |
306 | switch ((eax >> 5) & 0x07) | |
307 | { | |
308 | case 1: | |
309 | cache = level1; | |
310 | break; | |
311 | case 2: | |
312 | cache = level2; | |
313 | break; | |
a0463099 AK |
314 | case 3: |
315 | cache = level3; | |
316 | break; | |
cb0dee88 UB |
317 | default: |
318 | cache = NULL; | |
319 | } | |
320 | ||
321 | if (cache) | |
322 | { | |
323 | unsigned sets = ecx + 1; | |
dc8bd8d9 | 324 | unsigned part = ((ebx >> 12) & 0x03ff) + 1; |
cb0dee88 | 325 | |
dc8bd8d9 | 326 | cache->assoc = ((ebx >> 22) & 0x03ff) + 1; |
cb0dee88 | 327 | cache->line = (ebx & 0x0fff) + 1; |
cb0dee88 UB |
328 | |
329 | cache->sizekb = (cache->assoc * part | |
330 | * cache->line * sets) / 1024; | |
a0463099 | 331 | } |
cb0dee88 | 332 | } |
2711355f ZD |
333 | default: |
334 | break; | |
335 | } | |
336 | } | |
337 | } | |
338 | ||
cb0dee88 | 339 | /* Returns the description of caches for an Intel processor. */ |
2711355f | 340 | |
d3bfe4de | 341 | static const char * |
a0463099 AK |
342 | detect_caches_intel (bool xeon_mp, unsigned max_level, |
343 | unsigned max_ext_level, unsigned *l2sizekb) | |
2711355f | 344 | { |
a0463099 | 345 | struct cache_desc level1 = {0, 0, 0}, level2 = {0, 0, 0}, level3 = {0, 0, 0}; |
2711355f | 346 | |
cb0dee88 | 347 | if (max_level >= 4) |
a0463099 | 348 | detect_caches_cpuid4 (&level1, &level2, &level3); |
cb0dee88 UB |
349 | else if (max_level >= 2) |
350 | detect_caches_cpuid2 (xeon_mp, &level1, &level2); | |
351 | else | |
d3bfe4de | 352 | return ""; |
2711355f | 353 | |
cb0dee88 | 354 | if (level1.sizekb == 0) |
d3bfe4de | 355 | return ""; |
2711355f | 356 | |
a0463099 AK |
357 | /* Let the L3 replace the L2. This assumes inclusive caches |
358 | and single threaded program for now. */ | |
359 | if (level3.sizekb) | |
360 | level2 = level3; | |
361 | ||
cb0dee88 UB |
362 | /* Intel CPUs are equipped with AMD style L2 cache info. Try this |
363 | method if other methods fail to provide L2 cache parameters. */ | |
364 | if (level2.sizekb == 0 && max_ext_level >= 0x80000006) | |
365 | detect_l2_cache (&level2); | |
f4a1dd0d | 366 | |
a0463099 AK |
367 | *l2sizekb = level2.sizekb; |
368 | ||
cb0dee88 | 369 | return describe_cache (level1, level2); |
2711355f ZD |
370 | } |
371 | ||
e53b6e56 | 372 | /* This will be called by the spec parser in gcc.cc when it sees |
cc11b924 L |
373 | a %:local_cpu_detect(args) construct. Currently it will be |
374 | called with either "arch [32|64]" or "tune [32|64]" as argument | |
375 | depending on if -march=native or -mtune=native is to be substituted. | |
fa959ce4 MM |
376 | |
377 | It returns a string containing new command line parameters to be | |
378 | put at the place of the above two options, depending on what CPU | |
379 | this is executed. E.g. "-march=k8" on an AMD64 machine | |
380 | for -march=native. | |
381 | ||
382 | ARGC and ARGV are set depending on the actual arguments given | |
383 | in the spec. */ | |
b3172cab | 384 | |
fa959ce4 MM |
385 | const char *host_detect_local_cpu (int argc, const char **argv) |
386 | { | |
b3172cab UB |
387 | enum processor_type processor = PROCESSOR_I386; |
388 | const char *cpu = "i386"; | |
389 | ||
2711355f | 390 | const char *cache = ""; |
5be6cb59 | 391 | const char *options = ""; |
b3172cab | 392 | |
6c35d16a | 393 | unsigned int ebx, ecx, edx; |
b3172cab UB |
394 | |
395 | unsigned int max_level, ext_level; | |
cb0dee88 | 396 | |
fa959ce4 | 397 | unsigned int vendor; |
cb0dee88 | 398 | unsigned int model, family; |
b3172cab | 399 | |
edccdcb1 L |
400 | bool arch; |
401 | ||
a0463099 AK |
402 | unsigned int l2sizekb = 0; |
403 | ||
cc11b924 | 404 | if (argc < 2) |
edccdcb1 L |
405 | return NULL; |
406 | ||
b3172cab UB |
407 | arch = !strcmp (argv[0], "arch"); |
408 | ||
edccdcb1 | 409 | if (!arch && strcmp (argv[0], "tune")) |
fa959ce4 MM |
410 | return NULL; |
411 | ||
cc11b924 L |
412 | bool codegen_x86_64; |
413 | ||
414 | if (!strcmp (argv[1], "32")) | |
415 | codegen_x86_64 = false; | |
416 | else if (!strcmp (argv[1], "64")) | |
417 | codegen_x86_64 = true; | |
418 | else | |
419 | return NULL; | |
420 | ||
6c35d16a L |
421 | struct __processor_model cpu_model = { }; |
422 | struct __processor_model2 cpu_model2 = { }; | |
423 | unsigned int cpu_features2[SIZE_OF_CPU_FEATURES] = { }; | |
fa959ce4 | 424 | |
6c35d16a L |
425 | if (cpu_indicator_init (&cpu_model, &cpu_model2, cpu_features2) != 0) |
426 | goto done; | |
a91529c4 | 427 | |
6c35d16a L |
428 | vendor = cpu_model.__cpu_vendor; |
429 | family = cpu_model2.__cpu_family; | |
430 | model = cpu_model2.__cpu_model; | |
431 | max_level = cpu_model2.__cpu_max_level; | |
432 | ext_level = cpu_model2.__cpu_ext_level; | |
2c12f2f4 | 433 | |
2711355f ZD |
434 | if (!arch) |
435 | { | |
6c35d16a L |
436 | if (vendor == VENDOR_AMD |
437 | || vendor == VENDOR_CENTAUR | |
438 | || vendor == VENDOR_CYRIX | |
439 | || vendor == VENDOR_NSC) | |
2711355f | 440 | cache = detect_caches_amd (ext_level); |
a239aff8 M |
441 | else if (vendor == VENDOR_INTEL |
442 | || vendor == VENDOR_ZHAOXIN) | |
cb0dee88 UB |
443 | { |
444 | bool xeon_mp = (family == 15 && model == 6); | |
a0463099 AK |
445 | cache = detect_caches_intel (xeon_mp, max_level, |
446 | ext_level, &l2sizekb); | |
cb0dee88 | 447 | } |
2711355f ZD |
448 | } |
449 | ||
6c35d16a L |
450 | /* Extended features */ |
451 | #define has_feature(f) \ | |
452 | has_cpu_feature (&cpu_model, cpu_features2, f) | |
453 | ||
454 | if (vendor == VENDOR_AMD) | |
fa959ce4 | 455 | { |
fbdf817d | 456 | unsigned int name; |
b3172cab | 457 | |
fbdf817d | 458 | /* Detect geode processor by its processor signature. */ |
0a2d7bc0 | 459 | if (ext_level >= 0x80000002) |
fbdf817d UB |
460 | __cpuid (0x80000002, name, ebx, ecx, edx); |
461 | else | |
462 | name = 0; | |
463 | ||
ef64d158 | 464 | if (name == signature_NSC_ebx) |
fbdf817d | 465 | processor = PROCESSOR_GEODE; |
6c35d16a | 466 | else if (has_feature (FEATURE_MOVBE) && family == 22) |
e32bfc16 | 467 | processor = PROCESSOR_BTVER2; |
bf3b532b TJ |
468 | else if (has_feature (FEATURE_AVX512F)) |
469 | processor = PROCESSOR_ZNVER4; | |
3e2ae3ee VK |
470 | else if (has_feature (FEATURE_VAES)) |
471 | processor = PROCESSOR_ZNVER3; | |
6c35d16a | 472 | else if (has_feature (FEATURE_CLWB)) |
2901f42f | 473 | processor = PROCESSOR_ZNVER2; |
6c35d16a | 474 | else if (has_feature (FEATURE_CLZERO)) |
9ce29eb0 | 475 | processor = PROCESSOR_ZNVER1; |
6c35d16a L |
476 | else if (has_feature (FEATURE_AVX2)) |
477 | processor = PROCESSOR_BDVER4; | |
478 | else if (has_feature (FEATURE_XSAVEOPT)) | |
479 | processor = PROCESSOR_BDVER3; | |
480 | else if (has_feature (FEATURE_BMI)) | |
481 | processor = PROCESSOR_BDVER2; | |
482 | else if (has_feature (FEATURE_XOP)) | |
1133125e | 483 | processor = PROCESSOR_BDVER1; |
6c35d16a L |
484 | else if (has_feature (FEATURE_SSE4_A) |
485 | && has_feature (FEATURE_SSSE3)) | |
486 | processor = PROCESSOR_BTVER1; | |
487 | else if (has_feature (FEATURE_SSE4_A)) | |
35a63f21 | 488 | processor = PROCESSOR_AMDFAM10; |
6c35d16a L |
489 | else if (has_feature (FEATURE_SSE2) |
490 | || has_feature (FEATURE_LM)) | |
fbdf817d | 491 | processor = PROCESSOR_K8; |
6c35d16a | 492 | else if (has_feature (FEATURE_3DNOWP) && family == 6) |
fbdf817d | 493 | processor = PROCESSOR_ATHLON; |
6c35d16a | 494 | else if (has_feature (FEATURE_MMX)) |
fbdf817d UB |
495 | processor = PROCESSOR_K6; |
496 | else | |
497 | processor = PROCESSOR_PENTIUM; | |
fa959ce4 | 498 | } |
6c35d16a | 499 | else if (vendor == VENDOR_CENTAUR) |
19db293a | 500 | { |
4bdf739d UB |
501 | processor = PROCESSOR_GENERIC; |
502 | ||
503 | switch (family) | |
19db293a | 504 | { |
4bdf739d UB |
505 | default: |
506 | /* We have no idea. */ | |
507 | break; | |
508 | ||
509 | case 5: | |
6c35d16a L |
510 | if (has_feature (FEATURE_3DNOW) |
511 | || has_feature (FEATURE_MMX)) | |
4bdf739d UB |
512 | processor = PROCESSOR_I486; |
513 | break; | |
514 | ||
515 | case 6: | |
6c35d16a | 516 | if (has_feature (FEATURE_LM)) |
d3606ee3 | 517 | processor = PROCESSOR_K8; |
a239d460 | 518 | else if (model >= 9) |
4bdf739d UB |
519 | processor = PROCESSOR_PENTIUMPRO; |
520 | else if (model >= 6) | |
521 | processor = PROCESSOR_I486; | |
19db293a UB |
522 | } |
523 | } | |
a239aff8 M |
524 | else if (vendor == VENDOR_ZHAOXIN) |
525 | { | |
526 | processor = PROCESSOR_GENERIC; | |
527 | ||
528 | switch (family) | |
529 | { | |
530 | case 7: | |
531 | if (model == 0x3b) | |
532 | processor = PROCESSOR_LUJIAZUI; | |
533 | break; | |
534 | default: | |
535 | break; | |
536 | } | |
537 | } | |
fa959ce4 MM |
538 | else |
539 | { | |
edccdcb1 L |
540 | switch (family) |
541 | { | |
b3172cab UB |
542 | case 4: |
543 | processor = PROCESSOR_I486; | |
544 | break; | |
edccdcb1 | 545 | case 5: |
b3172cab | 546 | processor = PROCESSOR_PENTIUM; |
edccdcb1 L |
547 | break; |
548 | case 6: | |
549 | processor = PROCESSOR_PENTIUMPRO; | |
550 | break; | |
551 | case 15: | |
552 | processor = PROCESSOR_PENTIUM4; | |
553 | break; | |
554 | default: | |
b3172cab | 555 | /* We have no idea. */ |
9d532162 | 556 | processor = PROCESSOR_GENERIC; |
edccdcb1 L |
557 | } |
558 | } | |
559 | ||
560 | switch (processor) | |
561 | { | |
562 | case PROCESSOR_I386: | |
b3172cab | 563 | /* Default. */ |
edccdcb1 L |
564 | break; |
565 | case PROCESSOR_I486: | |
6c35d16a | 566 | if (arch && vendor == VENDOR_CENTAUR) |
4bdf739d UB |
567 | { |
568 | if (model >= 6) | |
569 | cpu = "c3"; | |
6c35d16a | 570 | else if (has_feature (FEATURE_3DNOW)) |
4bdf739d UB |
571 | cpu = "winchip2"; |
572 | else | |
573 | /* Assume WinChip C6. */ | |
574 | cpu = "winchip-c6"; | |
575 | } | |
576 | else | |
577 | cpu = "i486"; | |
edccdcb1 L |
578 | break; |
579 | case PROCESSOR_PENTIUM: | |
6c35d16a | 580 | if (arch && has_feature (FEATURE_MMX)) |
edccdcb1 L |
581 | cpu = "pentium-mmx"; |
582 | else | |
583 | cpu = "pentium"; | |
584 | break; | |
585 | case PROCESSOR_PENTIUMPRO: | |
134f7c94 | 586 | cpu = get_intel_cpu (&cpu_model, &cpu_model2, cpu_features2); |
6c35d16a | 587 | if (cpu == NULL) |
edccdcb1 | 588 | { |
44f276c6 L |
589 | if (arch) |
590 | { | |
4ffae7ff | 591 | /* This is unknown family 0x6 CPU. */ |
6c35d16a L |
592 | if (has_feature (FEATURE_AVX)) |
593 | { | |
c4f8f8af HL |
594 | /* Assume Grand Ridge. */ |
595 | if (has_feature (FEATURE_RAOINT)) | |
596 | cpu = "grandridge"; | |
339ffc5a | 597 | /* Assume Granite Rapids. */ |
c4f8f8af | 598 | else if (has_feature (FEATURE_AMX_FP16)) |
339ffc5a | 599 | cpu = "graniterapids"; |
fabe470b | 600 | /* Assume Sierra Forest. */ |
339ffc5a | 601 | else if (has_feature (FEATURE_AVXVNNIINT8)) |
fabe470b | 602 | cpu = "sierraforest"; |
11c72f20 | 603 | /* Assume Tiger Lake */ |
fabe470b | 604 | else if (has_feature (FEATURE_AVX512VP2INTERSECT)) |
11c72f20 CL |
605 | cpu = "tigerlake"; |
606 | /* Assume Sapphire Rapids. */ | |
607 | else if (has_feature (FEATURE_TSXLDTRK)) | |
608 | cpu = "sapphirerapids"; | |
6c35d16a L |
609 | /* Assume Cooper Lake */ |
610 | else if (has_feature (FEATURE_AVX512BF16)) | |
611 | cpu = "cooperlake"; | |
612 | /* Assume Ice Lake Server. */ | |
613 | else if (has_feature (FEATURE_WBNOINVD)) | |
614 | cpu = "icelake-server"; | |
a9fcfec3 | 615 | /* Assume Ice Lake. */ |
6c35d16a | 616 | else if (has_feature (FEATURE_AVX512BITALG)) |
a9fcfec3 HL |
617 | cpu = "icelake-client"; |
618 | /* Assume Cannon Lake. */ | |
6c35d16a | 619 | else if (has_feature (FEATURE_AVX512VBMI)) |
a9fcfec3 HL |
620 | cpu = "cannonlake"; |
621 | /* Assume Knights Mill. */ | |
6c35d16a | 622 | else if (has_feature (FEATURE_AVX5124VNNIW)) |
a9fcfec3 HL |
623 | cpu = "knm"; |
624 | /* Assume Knights Landing. */ | |
6c35d16a | 625 | else if (has_feature (FEATURE_AVX512ER)) |
a9fcfec3 HL |
626 | cpu = "knl"; |
627 | /* Assume Skylake with AVX-512. */ | |
6c35d16a | 628 | else if (has_feature (FEATURE_AVX512F)) |
a9fcfec3 | 629 | cpu = "skylake-avx512"; |
ba9c87d3 CL |
630 | /* Assume Alder Lake */ |
631 | else if (has_feature (FEATURE_SERIALIZE)) | |
632 | cpu = "alderlake"; | |
a9fcfec3 | 633 | /* Assume Skylake. */ |
6c35d16a | 634 | else if (has_feature (FEATURE_CLFLUSHOPT)) |
a9fcfec3 HL |
635 | cpu = "skylake"; |
636 | /* Assume Broadwell. */ | |
6c35d16a | 637 | else if (has_feature (FEATURE_ADX)) |
a9fcfec3 | 638 | cpu = "broadwell"; |
6c35d16a | 639 | else if (has_feature (FEATURE_AVX2)) |
992592ec | 640 | /* Assume Haswell. */ |
a9fcfec3 HL |
641 | cpu = "haswell"; |
642 | else | |
4ffae7ff | 643 | /* Assume Sandy Bridge. */ |
a9fcfec3 HL |
644 | cpu = "sandybridge"; |
645 | } | |
6c35d16a | 646 | else if (has_feature (FEATURE_SSE4_2)) |
0b871ccf | 647 | { |
6c35d16a | 648 | if (has_feature (FEATURE_GFNI)) |
a548a5a1 OM |
649 | /* Assume Tremont. */ |
650 | cpu = "tremont"; | |
6c35d16a | 651 | else if (has_feature (FEATURE_SGX)) |
74b2bb19 OM |
652 | /* Assume Goldmont Plus. */ |
653 | cpu = "goldmont-plus"; | |
6c35d16a | 654 | else if (has_feature (FEATURE_XSAVE)) |
50e461df OM |
655 | /* Assume Goldmont. */ |
656 | cpu = "goldmont"; | |
6c35d16a | 657 | else if (has_feature (FEATURE_MOVBE)) |
d3c11974 L |
658 | /* Assume Silvermont. */ |
659 | cpu = "silvermont"; | |
0b871ccf | 660 | else |
d3c11974 L |
661 | /* Assume Nehalem. */ |
662 | cpu = "nehalem"; | |
0b871ccf | 663 | } |
6c35d16a | 664 | else if (has_feature (FEATURE_SSSE3)) |
4ffae7ff | 665 | { |
6c35d16a | 666 | if (has_feature (FEATURE_MOVBE)) |
d3c11974 L |
667 | /* Assume Bonnell. */ |
668 | cpu = "bonnell"; | |
4ffae7ff L |
669 | else |
670 | /* Assume Core 2. */ | |
671 | cpu = "core2"; | |
672 | } | |
6c35d16a | 673 | else if (has_feature (FEATURE_LM)) |
8d37375b JJ |
674 | /* Perhaps some emulator? Assume x86-64, otherwise gcc |
675 | -march=native would be unusable for 64-bit compilations, | |
676 | as all the CPUs below are 32-bit only. */ | |
677 | cpu = "x86-64"; | |
6c35d16a | 678 | else if (has_feature (FEATURE_SSE3)) |
a239d460 | 679 | { |
6c35d16a | 680 | if (vendor == VENDOR_CENTAUR) |
a239d460 JM |
681 | /* C7 / Eden "Esther" */ |
682 | cpu = "c7"; | |
683 | else | |
684 | /* It is Core Duo. */ | |
685 | cpu = "pentium-m"; | |
686 | } | |
6c35d16a | 687 | else if (has_feature (FEATURE_SSE2)) |
fb112177 L |
688 | /* It is Pentium M. */ |
689 | cpu = "pentium-m"; | |
6c35d16a | 690 | else if (has_feature (FEATURE_SSE)) |
4bdf739d | 691 | { |
6c35d16a | 692 | if (vendor == VENDOR_CENTAUR) |
a239d460 JM |
693 | { |
694 | if (model >= 9) | |
695 | /* Eden "Nehemiah" */ | |
696 | cpu = "nehemiah"; | |
697 | else | |
698 | cpu = "c3-2"; | |
699 | } | |
4bdf739d UB |
700 | else |
701 | /* It is Pentium III. */ | |
702 | cpu = "pentium3"; | |
703 | } | |
6c35d16a | 704 | else if (has_feature (FEATURE_MMX)) |
fb112177 L |
705 | /* It is Pentium II. */ |
706 | cpu = "pentium2"; | |
44f276c6 | 707 | else |
fb112177 L |
708 | /* Default to Pentium Pro. */ |
709 | cpu = "pentiumpro"; | |
44f276c6 | 710 | } |
b3172cab | 711 | else |
44f276c6 L |
712 | /* For -mtune, we default to -mtune=generic. */ |
713 | cpu = "generic"; | |
fa959ce4 | 714 | } |
b3172cab UB |
715 | break; |
716 | case PROCESSOR_PENTIUM4: | |
6c35d16a | 717 | if (has_feature (FEATURE_SSE3)) |
fa959ce4 | 718 | { |
6c35d16a | 719 | if (has_feature (FEATURE_LM)) |
b3172cab | 720 | cpu = "nocona"; |
fa959ce4 | 721 | else |
fb112177 | 722 | cpu = "prescott"; |
fa959ce4 | 723 | } |
b3172cab | 724 | else |
fb112177 | 725 | cpu = "pentium4"; |
edccdcb1 L |
726 | break; |
727 | case PROCESSOR_GEODE: | |
728 | cpu = "geode"; | |
729 | break; | |
730 | case PROCESSOR_K6: | |
6c35d16a | 731 | if (arch && has_feature (FEATURE_3DNOW)) |
b3172cab | 732 | cpu = "k6-3"; |
edccdcb1 L |
733 | else |
734 | cpu = "k6"; | |
735 | break; | |
736 | case PROCESSOR_ATHLON: | |
6c35d16a | 737 | if (arch && has_feature (FEATURE_SSE)) |
edccdcb1 L |
738 | cpu = "athlon-4"; |
739 | else | |
740 | cpu = "athlon"; | |
741 | break; | |
edccdcb1 | 742 | case PROCESSOR_K8: |
d3606ee3 JM |
743 | if (arch) |
744 | { | |
6c35d16a | 745 | if (vendor == VENDOR_CENTAUR) |
d3606ee3 | 746 | { |
6c35d16a | 747 | if (has_feature (FEATURE_SSE4_1)) |
d3606ee3 JM |
748 | /* Nano 3000 | Nano dual / quad core | Eden X4 */ |
749 | cpu = "nano-3000"; | |
6c35d16a | 750 | else if (has_feature (FEATURE_SSSE3)) |
d3606ee3 JM |
751 | /* Nano 1000 | Nano 2000 */ |
752 | cpu = "nano"; | |
6c35d16a | 753 | else if (has_feature (FEATURE_SSE3)) |
d3606ee3 JM |
754 | /* Eden X2 */ |
755 | cpu = "eden-x2"; | |
756 | else | |
757 | /* Default to k8 */ | |
758 | cpu = "k8"; | |
759 | } | |
6c35d16a | 760 | else if (has_feature (FEATURE_SSE3)) |
d3606ee3 JM |
761 | cpu = "k8-sse3"; |
762 | else | |
763 | cpu = "k8"; | |
764 | } | |
b3172cab | 765 | else |
d3606ee3 | 766 | /* For -mtune, we default to -mtune=k8 */ |
b3172cab | 767 | cpu = "k8"; |
edccdcb1 | 768 | break; |
35a63f21 DR |
769 | case PROCESSOR_AMDFAM10: |
770 | cpu = "amdfam10"; | |
771 | break; | |
1133125e HJ |
772 | case PROCESSOR_BDVER1: |
773 | cpu = "bdver1"; | |
774 | break; | |
4d652a18 HJ |
775 | case PROCESSOR_BDVER2: |
776 | cpu = "bdver2"; | |
777 | break; | |
eb2f2b44 GG |
778 | case PROCESSOR_BDVER3: |
779 | cpu = "bdver3"; | |
780 | break; | |
ed97ad47 GG |
781 | case PROCESSOR_BDVER4: |
782 | cpu = "bdver4"; | |
783 | break; | |
9ce29eb0 VK |
784 | case PROCESSOR_ZNVER1: |
785 | cpu = "znver1"; | |
786 | break; | |
2901f42f VK |
787 | case PROCESSOR_ZNVER2: |
788 | cpu = "znver2"; | |
789 | break; | |
3e2ae3ee VK |
790 | case PROCESSOR_ZNVER3: |
791 | cpu = "znver3"; | |
792 | break; | |
bf3b532b TJ |
793 | case PROCESSOR_ZNVER4: |
794 | cpu = "znver4"; | |
795 | break; | |
14b52538 CF |
796 | case PROCESSOR_BTVER1: |
797 | cpu = "btver1"; | |
798 | break; | |
e32bfc16 VK |
799 | case PROCESSOR_BTVER2: |
800 | cpu = "btver2"; | |
801 | break; | |
a239aff8 M |
802 | case PROCESSOR_LUJIAZUI: |
803 | cpu = "lujiazui"; | |
804 | break; | |
b3172cab | 805 | |
edccdcb1 | 806 | default: |
b3172cab UB |
807 | /* Use something reasonable. */ |
808 | if (arch) | |
809 | { | |
6c35d16a | 810 | if (has_feature (FEATURE_SSSE3)) |
b3172cab | 811 | cpu = "core2"; |
6c35d16a | 812 | else if (has_feature (FEATURE_SSE3)) |
b3172cab | 813 | { |
6c35d16a | 814 | if (has_feature (FEATURE_LM)) |
b3172cab UB |
815 | cpu = "nocona"; |
816 | else | |
817 | cpu = "prescott"; | |
818 | } | |
6c35d16a | 819 | else if (has_feature (FEATURE_LM)) |
4bdf739d UB |
820 | /* Perhaps some emulator? Assume x86-64, otherwise gcc |
821 | -march=native would be unusable for 64-bit compilations, | |
822 | as all the CPUs below are 32-bit only. */ | |
823 | cpu = "x86-64"; | |
6c35d16a | 824 | else if (has_feature (FEATURE_SSE2)) |
b3172cab | 825 | cpu = "pentium4"; |
6c35d16a | 826 | else if (has_feature (FEATURE_CMOV)) |
b3172cab | 827 | cpu = "pentiumpro"; |
6c35d16a | 828 | else if (has_feature (FEATURE_MMX)) |
b3172cab | 829 | cpu = "pentium-mmx"; |
6c35d16a | 830 | else if (has_feature (FEATURE_CMPXCHG8B)) |
b3172cab UB |
831 | cpu = "pentium"; |
832 | } | |
833 | else | |
834 | cpu = "generic"; | |
fa959ce4 MM |
835 | } |
836 | ||
5be6cb59 UB |
837 | if (arch) |
838 | { | |
6c35d16a L |
839 | unsigned int i; |
840 | const char *const neg_option = " -mno-"; | |
841 | for (i = 0; i < ARRAY_SIZE (isa_names_table); i++) | |
842 | if (isa_names_table[i].option) | |
843 | { | |
844 | if (has_feature (isa_names_table[i].feature)) | |
cc11b924 L |
845 | { |
846 | if (codegen_x86_64 | |
847 | || isa_names_table[i].feature != FEATURE_UINTR) | |
848 | options = concat (options, " ", | |
849 | isa_names_table[i].option, NULL); | |
850 | } | |
6c35d16a L |
851 | else |
852 | options = concat (options, neg_option, | |
853 | isa_names_table[i].option + 2, NULL); | |
854 | } | |
5be6cb59 UB |
855 | } |
856 | ||
fa959ce4 | 857 | done: |
f3afc8a7 | 858 | return concat (cache, "-m", argv[0], "=", cpu, options, NULL); |
fa959ce4 MM |
859 | } |
860 | #else | |
b3172cab | 861 | |
02147868 UB |
862 | /* If we are compiling with GCC where %EBX register is fixed, then the |
863 | driver will just ignore -march and -mtune "native" target and will leave | |
864 | to the newly built compiler to generate code for its default target. */ | |
b3172cab | 865 | |
997ef9e7 | 866 | const char *host_detect_local_cpu (int, const char **) |
fa959ce4 | 867 | { |
f3afc8a7 | 868 | return NULL; |
fa959ce4 | 869 | } |
a6ecb05c | 870 | #endif /* __GNUC__ */ |