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