]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgcc/config/i386/cpuinfo.c
Update copyright years.
[thirdparty/gcc.git] / libgcc / config / i386 / cpuinfo.c
CommitLineData
792317cc 1/* Get CPU type and Features for x86 processors.
a5544970 2 Copyright (C) 2012-2019 Free Software Foundation, Inc.
792317cc
ST
3 Contributed by Sriraman Tallam (tmsriram@google.com)
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 3, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
46549c20
MK
17Under Section 7 of GPL version 3, you are granted additional
18permissions described in the GCC Runtime Library Exception, version
193.1, as published by the Free Software Foundation.
20
21You should have received a copy of the GNU General Public License and
22a copy of the GCC Runtime Library Exception along with this program;
23see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24<http://www.gnu.org/licenses/>. */
792317cc
ST
25
26#include "cpuid.h"
27#include "tsystem.h"
aca06c90 28#include "auto-target.h"
31cfd832 29#include "cpuinfo.h"
792317cc 30
aca06c90
RO
31#ifdef HAVE_INIT_PRIORITY
32#define CONSTRUCTOR_PRIORITY (101)
33#else
34#define CONSTRUCTOR_PRIORITY
35#endif
36
37int __cpu_indicator_init (void)
38 __attribute__ ((constructor CONSTRUCTOR_PRIORITY));
792317cc 39
792317cc 40
31cfd832 41struct __processor_model __cpu_model = { };
ae6dca8c
JJ
42#ifndef SHARED
43/* We want to move away from __cpu_model in libgcc_s.so.1 and the
44 size of __cpu_model is part of ABI. So, new features that don't
45 fit into __cpu_model.__cpu_features[0] go into extra variables
46 in libgcc.a only, preferrably hidden. */
47unsigned int __cpu_features2;
48#endif
792317cc
ST
49
50
51/* Get the specific type of AMD CPU. */
52
53static void
54get_amd_cpu (unsigned int family, unsigned int model)
55{
56 switch (family)
57 {
58 /* AMD Family 10h. */
59 case 0x10:
74924838 60 __cpu_model.__cpu_type = AMDFAM10H;
792317cc
ST
61 switch (model)
62 {
63 case 0x2:
64 /* Barcelona. */
792317cc
ST
65 __cpu_model.__cpu_subtype = AMDFAM10H_BARCELONA;
66 break;
67 case 0x4:
68 /* Shanghai. */
792317cc
ST
69 __cpu_model.__cpu_subtype = AMDFAM10H_SHANGHAI;
70 break;
71 case 0x8:
72 /* Istanbul. */
792317cc
ST
73 __cpu_model.__cpu_subtype = AMDFAM10H_ISTANBUL;
74 break;
75 default:
76 break;
77 }
78 break;
f4a4bdbb 79 /* AMD Family 14h "btver1". */
74924838 80 case 0x14:
f4a4bdbb 81 __cpu_model.__cpu_type = AMD_BTVER1;
74924838
ASJ
82 break;
83 /* AMD Family 15h "Bulldozer". */
792317cc
ST
84 case 0x15:
85 __cpu_model.__cpu_type = AMDFAM15H;
8b8003ed
UB
86
87 if (model == 0x2)
88 __cpu_model.__cpu_subtype = AMDFAM15H_BDVER2;
792317cc 89 /* Bulldozer version 1. */
8b8003ed 90 else if (model <= 0xf)
792317cc 91 __cpu_model.__cpu_subtype = AMDFAM15H_BDVER1;
74924838 92 /* Bulldozer version 2 "Piledriver" */
8b8003ed 93 else if (model <= 0x2f)
74924838
ASJ
94 __cpu_model.__cpu_subtype = AMDFAM15H_BDVER2;
95 /* Bulldozer version 3 "Steamroller" */
8b8003ed 96 else if (model <= 0x4f)
74924838 97 __cpu_model.__cpu_subtype = AMDFAM15H_BDVER3;
fac812f0 98 /* Bulldozer version 4 "Excavator" */
8b8003ed 99 else if (model <= 0x7f)
fac812f0 100 __cpu_model.__cpu_subtype = AMDFAM15H_BDVER4;
74924838 101 break;
f4a4bdbb 102 /* AMD Family 16h "btver2" */
74924838 103 case 0x16:
f4a4bdbb 104 __cpu_model.__cpu_type = AMD_BTVER2;
792317cc 105 break;
2ef543e4
VK
106 case 0x17:
107 __cpu_model.__cpu_type = AMDFAM17H;
108 /* AMD family 17h version 1. */
109 if (model <= 0x1f)
110 __cpu_model.__cpu_subtype = AMDFAM17H_ZNVER1;
2901f42f
VK
111 if (model >= 0x30)
112 __cpu_model.__cpu_subtype = AMDFAM17H_ZNVER2;
2ef543e4 113 break;
792317cc
ST
114 default:
115 break;
116 }
117}
118
119/* Get the specific type of Intel CPU. */
120
121static void
122get_intel_cpu (unsigned int family, unsigned int model, unsigned int brand_id)
123{
124 /* Parse family and model only if brand ID is 0. */
125 if (brand_id == 0)
126 {
127 switch (family)
128 {
129 case 0x5:
130 /* Pentium. */
131 break;
132 case 0x6:
133 switch (model)
134 {
135 case 0x1c:
136 case 0x26:
d3c11974
L
137 /* Bonnell. */
138 __cpu_model.__cpu_type = INTEL_BONNELL;
792317cc 139 break;
e5287671 140 case 0x37:
c8f2dff2 141 case 0x4a:
e5287671 142 case 0x4d:
c8f2dff2
L
143 case 0x5a:
144 case 0x5d:
e5287671 145 /* Silvermont. */
d3c11974 146 __cpu_model.__cpu_type = INTEL_SILVERMONT;
e5287671 147 break;
50e461df
OM
148 case 0x5c:
149 case 0x5f:
150 /* Goldmont. */
151 __cpu_model.__cpu_type = INTEL_GOLDMONT;
152 break;
74b2bb19
OM
153 case 0x7a:
154 /* Goldmont Plus. */
155 __cpu_model.__cpu_type = INTEL_GOLDMONT_PLUS;
156 break;
51c728b1
L
157 case 0x57:
158 /* Knights Landing. */
159 __cpu_model.__cpu_type = INTEL_KNL;
160 break;
cace2309
SP
161 case 0x85:
162 /* Knights Mill. */
163 __cpu_model.__cpu_type = INTEL_KNM;
164 break;
792317cc
ST
165 case 0x1a:
166 case 0x1e:
167 case 0x1f:
168 case 0x2e:
169 /* Nehalem. */
170 __cpu_model.__cpu_type = INTEL_COREI7;
171 __cpu_model.__cpu_subtype = INTEL_COREI7_NEHALEM;
172 break;
173 case 0x25:
174 case 0x2c:
175 case 0x2f:
176 /* Westmere. */
177 __cpu_model.__cpu_type = INTEL_COREI7;
178 __cpu_model.__cpu_subtype = INTEL_COREI7_WESTMERE;
179 break;
180 case 0x2a:
84ea618a 181 case 0x2d:
792317cc
ST
182 /* Sandy Bridge. */
183 __cpu_model.__cpu_type = INTEL_COREI7;
184 __cpu_model.__cpu_subtype = INTEL_COREI7_SANDYBRIDGE;
185 break;
74924838
ASJ
186 case 0x3a:
187 case 0x3e:
188 /* Ivy Bridge. */
189 __cpu_model.__cpu_type = INTEL_COREI7;
190 __cpu_model.__cpu_subtype = INTEL_COREI7_IVYBRIDGE;
191 break;
192 case 0x3c:
c8f2dff2 193 case 0x3f:
74924838
ASJ
194 case 0x45:
195 case 0x46:
196 /* Haswell. */
197 __cpu_model.__cpu_type = INTEL_COREI7;
198 __cpu_model.__cpu_subtype = INTEL_COREI7_HASWELL;
199 break;
c8f2dff2 200 case 0x3d:
736e56da 201 case 0x47:
c8f2dff2
L
202 case 0x4f:
203 case 0x56:
204 /* Broadwell. */
205 __cpu_model.__cpu_type = INTEL_COREI7;
206 __cpu_model.__cpu_subtype = INTEL_COREI7_BROADWELL;
207 break;
3e0f3349
YR
208 case 0x4e:
209 case 0x5e:
210 /* Skylake. */
60edf8bb
MT
211 case 0x8e:
212 case 0x9e:
213 /* Kaby Lake. */
3e0f3349
YR
214 __cpu_model.__cpu_type = INTEL_COREI7;
215 __cpu_model.__cpu_subtype = INTEL_COREI7_SKYLAKE;
216 break;
6a192b5a 217 case 0x55:
5d54c798
WX
218 {
219 unsigned int eax, ebx, ecx, edx;
220 __cpu_model.__cpu_type = INTEL_COREI7;
221 __cpuid_count (7, 0, eax, ebx, ecx, edx);
222 if (ecx & bit_AVX512VNNI)
223 /* Cascade Lake. */
224 __cpu_model.__cpu_subtype = INTEL_COREI7_CASCADELAKE;
225 else
226 /* Skylake with AVX-512 support. */
227 __cpu_model.__cpu_subtype = INTEL_COREI7_SKYLAKE_AVX512;
228 }
6a192b5a 229 break;
c234d831
UB
230 case 0x66:
231 /* Cannon Lake. */
232 __cpu_model.__cpu_type = INTEL_COREI7;
233 __cpu_model.__cpu_subtype = INTEL_COREI7_CANNONLAKE;
234 break;
792317cc
ST
235 case 0x17:
236 case 0x1d:
237 /* Penryn. */
238 case 0x0f:
239 /* Merom. */
240 __cpu_model.__cpu_type = INTEL_CORE2;
241 break;
242 default:
243 break;
244 }
245 break;
246 default:
247 /* We have no idea. */
248 break;
249 }
250 }
251}
252
5ddecff9
ST
253/* ECX and EDX are output of CPUID at level one. MAX_CPUID_LEVEL is
254 the max possible level of CPUID insn. */
792317cc 255static void
5ddecff9
ST
256get_available_features (unsigned int ecx, unsigned int edx,
257 int max_cpuid_level)
792317cc 258{
fbed6f36
UB
259 unsigned int eax, ebx;
260 unsigned int ext_level;
261
792317cc 262 unsigned int features = 0;
ae6dca8c
JJ
263 unsigned int features2 = 0;
264
059cc8ac
L
265 /* Get XCR_XFEATURE_ENABLED_MASK register with xgetbv. */
266#define XCR_XFEATURE_ENABLED_MASK 0x0
267#define XSTATE_FP 0x1
268#define XSTATE_SSE 0x2
269#define XSTATE_YMM 0x4
270#define XSTATE_OPMASK 0x20
271#define XSTATE_ZMM 0x40
272#define XSTATE_HI_ZMM 0x80
273
274#define XCR_AVX_ENABLED_MASK \
275 (XSTATE_SSE | XSTATE_YMM)
276#define XCR_AVX512F_ENABLED_MASK \
277 (XSTATE_SSE | XSTATE_YMM | XSTATE_OPMASK | XSTATE_ZMM | XSTATE_HI_ZMM)
278
279 /* Check if AVX and AVX512 are usable. */
280 int avx_usable = 0;
281 int avx512_usable = 0;
282 if ((ecx & bit_OSXSAVE))
283 {
284 /* Check if XMM, YMM, OPMASK, upper 256 bits of ZMM0-ZMM15 and
285 ZMM16-ZMM31 states are supported by OSXSAVE. */
286 unsigned int xcrlow;
287 unsigned int xcrhigh;
288 asm (".byte 0x0f, 0x01, 0xd0"
289 : "=a" (xcrlow), "=d" (xcrhigh)
290 : "c" (XCR_XFEATURE_ENABLED_MASK));
291 if ((xcrlow & XCR_AVX_ENABLED_MASK) == XCR_AVX_ENABLED_MASK)
292 {
293 avx_usable = 1;
294 avx512_usable = ((xcrlow & XCR_AVX512F_ENABLED_MASK)
295 == XCR_AVX512F_ENABLED_MASK);
296 }
297 }
298
ae6dca8c 299#define set_feature(f) \
a57f99ba
JJ
300 do \
301 { \
302 if (f < 32) \
303 features |= (1U << (f & 31)); \
304 else \
305 features2 |= (1U << ((f - 32) & 31)); \
306 } \
307 while (0)
792317cc
ST
308
309 if (edx & bit_CMOV)
ae6dca8c 310 set_feature (FEATURE_CMOV);
792317cc 311 if (edx & bit_MMX)
ae6dca8c 312 set_feature (FEATURE_MMX);
792317cc 313 if (edx & bit_SSE)
ae6dca8c 314 set_feature (FEATURE_SSE);
792317cc 315 if (edx & bit_SSE2)
ae6dca8c 316 set_feature (FEATURE_SSE2);
792317cc 317 if (ecx & bit_POPCNT)
ae6dca8c 318 set_feature (FEATURE_POPCNT);
54d22142 319 if (ecx & bit_AES)
ae6dca8c 320 set_feature (FEATURE_AES);
aff4eeac 321 if (ecx & bit_PCLMUL)
ae6dca8c 322 set_feature (FEATURE_PCLMUL);
792317cc 323 if (ecx & bit_SSE3)
ae6dca8c 324 set_feature (FEATURE_SSE3);
792317cc 325 if (ecx & bit_SSSE3)
ae6dca8c 326 set_feature (FEATURE_SSSE3);
792317cc 327 if (ecx & bit_SSE4_1)
ae6dca8c 328 set_feature (FEATURE_SSE4_1);
792317cc 329 if (ecx & bit_SSE4_2)
ae6dca8c 330 set_feature (FEATURE_SSE4_2);
059cc8ac
L
331 if (avx_usable)
332 {
333 if (ecx & bit_AVX)
334 set_feature (FEATURE_AVX);
335 if (ecx & bit_FMA)
336 set_feature (FEATURE_FMA);
337 }
792317cc 338
5ddecff9
ST
339 /* Get Advanced Features at level 7 (eax = 7, ecx = 0). */
340 if (max_cpuid_level >= 7)
341 {
5ddecff9 342 __cpuid_count (7, 0, eax, ebx, ecx, edx);
939911c5 343 if (ebx & bit_BMI)
ae6dca8c 344 set_feature (FEATURE_BMI);
059cc8ac
L
345 if (avx_usable)
346 {
347 if (ebx & bit_AVX2)
348 set_feature (FEATURE_AVX2);
349 }
939911c5 350 if (ebx & bit_BMI2)
ae6dca8c 351 set_feature (FEATURE_BMI2);
059cc8ac
L
352 if (avx512_usable)
353 {
354 if (ebx & bit_AVX512F)
355 set_feature (FEATURE_AVX512F);
356 if (ebx & bit_AVX512VL)
357 set_feature (FEATURE_AVX512VL);
358 if (ebx & bit_AVX512BW)
359 set_feature (FEATURE_AVX512BW);
360 if (ebx & bit_AVX512DQ)
361 set_feature (FEATURE_AVX512DQ);
362 if (ebx & bit_AVX512CD)
363 set_feature (FEATURE_AVX512CD);
364 if (ebx & bit_AVX512PF)
365 set_feature (FEATURE_AVX512PF);
366 if (ebx & bit_AVX512ER)
367 set_feature (FEATURE_AVX512ER);
368 if (ebx & bit_AVX512IFMA)
369 set_feature (FEATURE_AVX512IFMA);
370 if (ecx & bit_AVX512VBMI)
371 set_feature (FEATURE_AVX512VBMI);
372 if (ecx & bit_AVX512VBMI2)
373 set_feature (FEATURE_AVX512VBMI2);
374 if (ecx & bit_GFNI)
375 set_feature (FEATURE_GFNI);
376 if (ecx & bit_VPCLMULQDQ)
377 set_feature (FEATURE_VPCLMULQDQ);
378 if (ecx & bit_AVX512VNNI)
379 set_feature (FEATURE_AVX512VNNI);
380 if (ecx & bit_AVX512BITALG)
381 set_feature (FEATURE_AVX512BITALG);
382 if (ecx & bit_AVX512VPOPCNTDQ)
383 set_feature (FEATURE_AVX512VPOPCNTDQ);
384 if (edx & bit_AVX5124VNNIW)
385 set_feature (FEATURE_AVX5124VNNIW);
386 if (edx & bit_AVX5124FMAPS)
387 set_feature (FEATURE_AVX5124FMAPS);
388 }
5ddecff9
ST
389 }
390
74924838
ASJ
391 /* Check cpuid level of extended features. */
392 __cpuid (0x80000000, ext_level, ebx, ecx, edx);
393
fbed6f36 394 if (ext_level >= 0x80000001)
74924838
ASJ
395 {
396 __cpuid (0x80000001, eax, ebx, ecx, edx);
397
398 if (ecx & bit_SSE4a)
ae6dca8c 399 set_feature (FEATURE_SSE4_A);
059cc8ac
L
400 if (avx_usable)
401 {
402 if (ecx & bit_FMA4)
403 set_feature (FEATURE_FMA4);
404 if (ecx & bit_XOP)
405 set_feature (FEATURE_XOP);
406 }
74924838
ASJ
407 }
408
792317cc 409 __cpu_model.__cpu_features[0] = features;
ae6dca8c
JJ
410#ifndef SHARED
411 __cpu_features2 = features2;
412#else
413 (void) features2;
414#endif
792317cc
ST
415}
416
792317cc
ST
417/* A constructor function that is sets __cpu_model and __cpu_features with
418 the right values. This needs to run only once. This constructor is
419 given the highest priority and it should run before constructors without
420 the priority set. However, it still runs after ifunc initializers and
421 needs to be called explicitly there. */
422
aca06c90 423int __attribute__ ((constructor CONSTRUCTOR_PRIORITY))
792317cc
ST
424__cpu_indicator_init (void)
425{
426 unsigned int eax, ebx, ecx, edx;
427
e0ab3753 428 int max_level;
792317cc
ST
429 unsigned int vendor;
430 unsigned int model, family, brand_id;
431 unsigned int extended_model, extended_family;
432
433 /* This function needs to run just once. */
434 if (__cpu_model.__cpu_vendor)
435 return 0;
436
437 /* Assume cpuid insn present. Run in level 0 to get vendor id. */
e0ab3753 438 if (!__get_cpuid (0, &eax, &ebx, &ecx, &edx))
ad491329
ST
439 {
440 __cpu_model.__cpu_vendor = VENDOR_OTHER;
441 return -1;
442 }
792317cc
ST
443
444 vendor = ebx;
445 max_level = eax;
446
447 if (max_level < 1)
ad491329
ST
448 {
449 __cpu_model.__cpu_vendor = VENDOR_OTHER;
450 return -1;
451 }
792317cc 452
e0ab3753 453 if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
ad491329
ST
454 {
455 __cpu_model.__cpu_vendor = VENDOR_OTHER;
456 return -1;
457 }
792317cc
ST
458
459 model = (eax >> 4) & 0x0f;
460 family = (eax >> 8) & 0x0f;
461 brand_id = ebx & 0xff;
462 extended_model = (eax >> 12) & 0xf0;
463 extended_family = (eax >> 20) & 0xff;
464
1879e97f 465 if (vendor == signature_INTEL_ebx)
792317cc
ST
466 {
467 /* Adjust model and family for Intel CPUS. */
468 if (family == 0x0f)
469 {
470 family += extended_family;
471 model += extended_model;
472 }
473 else if (family == 0x06)
474 model += extended_model;
475
476 /* Get CPU type. */
477 get_intel_cpu (family, model, brand_id);
478 /* Find available features. */
5ddecff9 479 get_available_features (ecx, edx, max_level);
792317cc
ST
480 __cpu_model.__cpu_vendor = VENDOR_INTEL;
481 }
1879e97f 482 else if (vendor == signature_AMD_ebx)
792317cc
ST
483 {
484 /* Adjust model and family for AMD CPUS. */
485 if (family == 0x0f)
486 {
487 family += extended_family;
fac812f0 488 model += extended_model;
792317cc
ST
489 }
490
491 /* Get CPU type. */
492 get_amd_cpu (family, model);
493 /* Find available features. */
5ddecff9 494 get_available_features (ecx, edx, max_level);
792317cc
ST
495 __cpu_model.__cpu_vendor = VENDOR_AMD;
496 }
497 else
498 __cpu_model.__cpu_vendor = VENDOR_OTHER;
499
500 gcc_assert (__cpu_model.__cpu_vendor < VENDOR_MAX);
501 gcc_assert (__cpu_model.__cpu_type < CPU_TYPE_MAX);
502 gcc_assert (__cpu_model.__cpu_subtype < CPU_SUBTYPE_MAX);
503
504 return 0;
505}
abd0cdc9
L
506
507#if defined SHARED && defined USE_ELF_SYMVER
508__asm__ (".symver __cpu_indicator_init, __cpu_indicator_init@GCC_4.8.0");
509__asm__ (".symver __cpu_model, __cpu_model@GCC_4.8.0");
510#endif