[NDS32] Support Linux target for nds32.
[official-gcc.git] / libgcc / config / i386 / cpuinfo.c
bloba7bb9dac151374055110a479f1a62bbaa1226e48
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;
87 if (model == 0x2)
88 __cpu_model.__cpu_subtype = AMDFAM15H_BDVER2;
89 /* Bulldozer version 1. */
90 else if (model <= 0xf)
91 __cpu_model.__cpu_subtype = AMDFAM15H_BDVER1;
92 /* Bulldozer version 2 "Piledriver" */
93 else if (model <= 0x2f)
94 __cpu_model.__cpu_subtype = AMDFAM15H_BDVER2;
95 /* Bulldozer version 3 "Steamroller" */
96 else if (model <= 0x4f)
97 __cpu_model.__cpu_subtype = AMDFAM15H_BDVER3;
98 /* Bulldozer version 4 "Excavator" */
99 else if (model <= 0x7f)
100 __cpu_model.__cpu_subtype = AMDFAM15H_BDVER4;
101 break;
102 /* AMD Family 16h "btver2" */
103 case 0x16:
104 __cpu_model.__cpu_type = AMD_BTVER2;
105 break;
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;
111 break;
112 default:
113 break;
117 /* Get the specific type of Intel CPU. */
119 static void
120 get_intel_cpu (unsigned int family, unsigned int model, unsigned int brand_id)
122 /* Parse family and model only if brand ID is 0. */
123 if (brand_id == 0)
125 switch (family)
127 case 0x5:
128 /* Pentium. */
129 break;
130 case 0x6:
131 switch (model)
133 case 0x1c:
134 case 0x26:
135 /* Bonnell. */
136 __cpu_model.__cpu_type = INTEL_BONNELL;
137 break;
138 case 0x37:
139 case 0x4a:
140 case 0x4d:
141 case 0x5a:
142 case 0x5d:
143 /* Silvermont. */
144 __cpu_model.__cpu_type = INTEL_SILVERMONT;
145 break;
146 case 0x5c:
147 case 0x5f:
148 /* Goldmont. */
149 __cpu_model.__cpu_type = INTEL_GOLDMONT;
150 break;
151 case 0x7a:
152 /* Goldmont Plus. */
153 __cpu_model.__cpu_type = INTEL_GOLDMONT_PLUS;
154 break;
155 case 0x57:
156 /* Knights Landing. */
157 __cpu_model.__cpu_type = INTEL_KNL;
158 break;
159 case 0x85:
160 /* Knights Mill. */
161 __cpu_model.__cpu_type = INTEL_KNM;
162 break;
163 case 0x1a:
164 case 0x1e:
165 case 0x1f:
166 case 0x2e:
167 /* Nehalem. */
168 __cpu_model.__cpu_type = INTEL_COREI7;
169 __cpu_model.__cpu_subtype = INTEL_COREI7_NEHALEM;
170 break;
171 case 0x25:
172 case 0x2c:
173 case 0x2f:
174 /* Westmere. */
175 __cpu_model.__cpu_type = INTEL_COREI7;
176 __cpu_model.__cpu_subtype = INTEL_COREI7_WESTMERE;
177 break;
178 case 0x2a:
179 case 0x2d:
180 /* Sandy Bridge. */
181 __cpu_model.__cpu_type = INTEL_COREI7;
182 __cpu_model.__cpu_subtype = INTEL_COREI7_SANDYBRIDGE;
183 break;
184 case 0x3a:
185 case 0x3e:
186 /* Ivy Bridge. */
187 __cpu_model.__cpu_type = INTEL_COREI7;
188 __cpu_model.__cpu_subtype = INTEL_COREI7_IVYBRIDGE;
189 break;
190 case 0x3c:
191 case 0x3f:
192 case 0x45:
193 case 0x46:
194 /* Haswell. */
195 __cpu_model.__cpu_type = INTEL_COREI7;
196 __cpu_model.__cpu_subtype = INTEL_COREI7_HASWELL;
197 break;
198 case 0x3d:
199 case 0x47:
200 case 0x4f:
201 case 0x56:
202 /* Broadwell. */
203 __cpu_model.__cpu_type = INTEL_COREI7;
204 __cpu_model.__cpu_subtype = INTEL_COREI7_BROADWELL;
205 break;
206 case 0x4e:
207 case 0x5e:
208 /* Skylake. */
209 case 0x8e:
210 case 0x9e:
211 /* Kaby Lake. */
212 __cpu_model.__cpu_type = INTEL_COREI7;
213 __cpu_model.__cpu_subtype = INTEL_COREI7_SKYLAKE;
214 break;
215 case 0x55:
216 /* Skylake with AVX-512 support. */
217 __cpu_model.__cpu_type = INTEL_COREI7;
218 __cpu_model.__cpu_subtype = INTEL_COREI7_SKYLAKE_AVX512;
219 break;
220 case 0x66:
221 /* Cannon Lake. */
222 __cpu_model.__cpu_type = INTEL_COREI7;
223 __cpu_model.__cpu_subtype = INTEL_COREI7_CANNONLAKE;
224 break;
225 case 0x17:
226 case 0x1d:
227 /* Penryn. */
228 case 0x0f:
229 /* Merom. */
230 __cpu_model.__cpu_type = INTEL_CORE2;
231 break;
232 default:
233 break;
235 break;
236 default:
237 /* We have no idea. */
238 break;
243 /* ECX and EDX are output of CPUID at level one. MAX_CPUID_LEVEL is
244 the max possible level of CPUID insn. */
245 static void
246 get_available_features (unsigned int ecx, unsigned int edx,
247 int max_cpuid_level)
249 unsigned int eax, ebx;
250 unsigned int ext_level;
252 unsigned int features = 0;
253 unsigned int features2 = 0;
255 /* Get XCR_XFEATURE_ENABLED_MASK register with xgetbv. */
256 #define XCR_XFEATURE_ENABLED_MASK 0x0
257 #define XSTATE_FP 0x1
258 #define XSTATE_SSE 0x2
259 #define XSTATE_YMM 0x4
260 #define XSTATE_OPMASK 0x20
261 #define XSTATE_ZMM 0x40
262 #define XSTATE_HI_ZMM 0x80
264 #define XCR_AVX_ENABLED_MASK \
265 (XSTATE_SSE | XSTATE_YMM)
266 #define XCR_AVX512F_ENABLED_MASK \
267 (XSTATE_SSE | XSTATE_YMM | XSTATE_OPMASK | XSTATE_ZMM | XSTATE_HI_ZMM)
269 /* Check if AVX and AVX512 are usable. */
270 int avx_usable = 0;
271 int avx512_usable = 0;
272 if ((ecx & bit_OSXSAVE))
274 /* Check if XMM, YMM, OPMASK, upper 256 bits of ZMM0-ZMM15 and
275 ZMM16-ZMM31 states are supported by OSXSAVE. */
276 unsigned int xcrlow;
277 unsigned int xcrhigh;
278 asm (".byte 0x0f, 0x01, 0xd0"
279 : "=a" (xcrlow), "=d" (xcrhigh)
280 : "c" (XCR_XFEATURE_ENABLED_MASK));
281 if ((xcrlow & XCR_AVX_ENABLED_MASK) == XCR_AVX_ENABLED_MASK)
283 avx_usable = 1;
284 avx512_usable = ((xcrlow & XCR_AVX512F_ENABLED_MASK)
285 == XCR_AVX512F_ENABLED_MASK);
289 #define set_feature(f) \
290 do \
292 if (f < 32) \
293 features |= (1U << (f & 31)); \
294 else \
295 features2 |= (1U << ((f - 32) & 31)); \
297 while (0)
299 if (edx & bit_CMOV)
300 set_feature (FEATURE_CMOV);
301 if (edx & bit_MMX)
302 set_feature (FEATURE_MMX);
303 if (edx & bit_SSE)
304 set_feature (FEATURE_SSE);
305 if (edx & bit_SSE2)
306 set_feature (FEATURE_SSE2);
307 if (ecx & bit_POPCNT)
308 set_feature (FEATURE_POPCNT);
309 if (ecx & bit_AES)
310 set_feature (FEATURE_AES);
311 if (ecx & bit_PCLMUL)
312 set_feature (FEATURE_PCLMUL);
313 if (ecx & bit_SSE3)
314 set_feature (FEATURE_SSE3);
315 if (ecx & bit_SSSE3)
316 set_feature (FEATURE_SSSE3);
317 if (ecx & bit_SSE4_1)
318 set_feature (FEATURE_SSE4_1);
319 if (ecx & bit_SSE4_2)
320 set_feature (FEATURE_SSE4_2);
321 if (avx_usable)
323 if (ecx & bit_AVX)
324 set_feature (FEATURE_AVX);
325 if (ecx & bit_FMA)
326 set_feature (FEATURE_FMA);
329 /* Get Advanced Features at level 7 (eax = 7, ecx = 0). */
330 if (max_cpuid_level >= 7)
332 __cpuid_count (7, 0, eax, ebx, ecx, edx);
333 if (ebx & bit_BMI)
334 set_feature (FEATURE_BMI);
335 if (avx_usable)
337 if (ebx & bit_AVX2)
338 set_feature (FEATURE_AVX2);
340 if (ebx & bit_BMI2)
341 set_feature (FEATURE_BMI2);
342 if (avx512_usable)
344 if (ebx & bit_AVX512F)
345 set_feature (FEATURE_AVX512F);
346 if (ebx & bit_AVX512VL)
347 set_feature (FEATURE_AVX512VL);
348 if (ebx & bit_AVX512BW)
349 set_feature (FEATURE_AVX512BW);
350 if (ebx & bit_AVX512DQ)
351 set_feature (FEATURE_AVX512DQ);
352 if (ebx & bit_AVX512CD)
353 set_feature (FEATURE_AVX512CD);
354 if (ebx & bit_AVX512PF)
355 set_feature (FEATURE_AVX512PF);
356 if (ebx & bit_AVX512ER)
357 set_feature (FEATURE_AVX512ER);
358 if (ebx & bit_AVX512IFMA)
359 set_feature (FEATURE_AVX512IFMA);
360 if (ecx & bit_AVX512VBMI)
361 set_feature (FEATURE_AVX512VBMI);
362 if (ecx & bit_AVX512VBMI2)
363 set_feature (FEATURE_AVX512VBMI2);
364 if (ecx & bit_GFNI)
365 set_feature (FEATURE_GFNI);
366 if (ecx & bit_VPCLMULQDQ)
367 set_feature (FEATURE_VPCLMULQDQ);
368 if (ecx & bit_AVX512VNNI)
369 set_feature (FEATURE_AVX512VNNI);
370 if (ecx & bit_AVX512BITALG)
371 set_feature (FEATURE_AVX512BITALG);
372 if (ecx & bit_AVX512VPOPCNTDQ)
373 set_feature (FEATURE_AVX512VPOPCNTDQ);
374 if (edx & bit_AVX5124VNNIW)
375 set_feature (FEATURE_AVX5124VNNIW);
376 if (edx & bit_AVX5124FMAPS)
377 set_feature (FEATURE_AVX5124FMAPS);
381 /* Check cpuid level of extended features. */
382 __cpuid (0x80000000, ext_level, ebx, ecx, edx);
384 if (ext_level >= 0x80000001)
386 __cpuid (0x80000001, eax, ebx, ecx, edx);
388 if (ecx & bit_SSE4a)
389 set_feature (FEATURE_SSE4_A);
390 if (avx_usable)
392 if (ecx & bit_FMA4)
393 set_feature (FEATURE_FMA4);
394 if (ecx & bit_XOP)
395 set_feature (FEATURE_XOP);
399 __cpu_model.__cpu_features[0] = features;
400 #ifndef SHARED
401 __cpu_features2 = features2;
402 #else
403 (void) features2;
404 #endif
407 /* A constructor function that is sets __cpu_model and __cpu_features with
408 the right values. This needs to run only once. This constructor is
409 given the highest priority and it should run before constructors without
410 the priority set. However, it still runs after ifunc initializers and
411 needs to be called explicitly there. */
413 int __attribute__ ((constructor CONSTRUCTOR_PRIORITY))
414 __cpu_indicator_init (void)
416 unsigned int eax, ebx, ecx, edx;
418 int max_level;
419 unsigned int vendor;
420 unsigned int model, family, brand_id;
421 unsigned int extended_model, extended_family;
423 /* This function needs to run just once. */
424 if (__cpu_model.__cpu_vendor)
425 return 0;
427 /* Assume cpuid insn present. Run in level 0 to get vendor id. */
428 if (!__get_cpuid (0, &eax, &ebx, &ecx, &edx))
430 __cpu_model.__cpu_vendor = VENDOR_OTHER;
431 return -1;
434 vendor = ebx;
435 max_level = eax;
437 if (max_level < 1)
439 __cpu_model.__cpu_vendor = VENDOR_OTHER;
440 return -1;
443 if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
445 __cpu_model.__cpu_vendor = VENDOR_OTHER;
446 return -1;
449 model = (eax >> 4) & 0x0f;
450 family = (eax >> 8) & 0x0f;
451 brand_id = ebx & 0xff;
452 extended_model = (eax >> 12) & 0xf0;
453 extended_family = (eax >> 20) & 0xff;
455 if (vendor == signature_INTEL_ebx)
457 /* Adjust model and family for Intel CPUS. */
458 if (family == 0x0f)
460 family += extended_family;
461 model += extended_model;
463 else if (family == 0x06)
464 model += extended_model;
466 /* Get CPU type. */
467 get_intel_cpu (family, model, brand_id);
468 /* Find available features. */
469 get_available_features (ecx, edx, max_level);
470 __cpu_model.__cpu_vendor = VENDOR_INTEL;
472 else if (vendor == signature_AMD_ebx)
474 /* Adjust model and family for AMD CPUS. */
475 if (family == 0x0f)
477 family += extended_family;
478 model += extended_model;
481 /* Get CPU type. */
482 get_amd_cpu (family, model);
483 /* Find available features. */
484 get_available_features (ecx, edx, max_level);
485 __cpu_model.__cpu_vendor = VENDOR_AMD;
487 else
488 __cpu_model.__cpu_vendor = VENDOR_OTHER;
490 gcc_assert (__cpu_model.__cpu_vendor < VENDOR_MAX);
491 gcc_assert (__cpu_model.__cpu_type < CPU_TYPE_MAX);
492 gcc_assert (__cpu_model.__cpu_subtype < CPU_SUBTYPE_MAX);
494 return 0;
497 #if defined SHARED && defined USE_ELF_SYMVER
498 __asm__ (".symver __cpu_indicator_init, __cpu_indicator_init@GCC_4.8.0");
499 __asm__ (".symver __cpu_model, __cpu_model@GCC_4.8.0");
500 #endif