Add avx5124vnniw/avx5124fmaps to target attributes
[official-gcc.git] / libgcc / config / i386 / cpuinfo.c
blob4a0ad254cd9a9248bdea381c223a3462655d6a26
1 /* Get CPU type and Features for x86 processors.
2 Copyright (C) 2012-2016 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"
30 #ifdef HAVE_INIT_PRIORITY
31 #define CONSTRUCTOR_PRIORITY (101)
32 #else
33 #define CONSTRUCTOR_PRIORITY
34 #endif
36 int __cpu_indicator_init (void)
37 __attribute__ ((constructor CONSTRUCTOR_PRIORITY));
39 /* Processor Vendor and Models. */
41 enum processor_vendor
43 VENDOR_INTEL = 1,
44 VENDOR_AMD,
45 VENDOR_OTHER,
46 VENDOR_MAX
49 /* Any new types or subtypes have to be inserted at the end. */
51 enum processor_types
53 INTEL_BONNELL = 1,
54 INTEL_CORE2,
55 INTEL_COREI7,
56 AMDFAM10H,
57 AMDFAM15H,
58 INTEL_SILVERMONT,
59 INTEL_KNL,
60 AMD_BTVER1,
61 AMD_BTVER2,
62 AMDFAM17H,
63 CPU_TYPE_MAX
66 enum processor_subtypes
68 INTEL_COREI7_NEHALEM = 1,
69 INTEL_COREI7_WESTMERE,
70 INTEL_COREI7_SANDYBRIDGE,
71 AMDFAM10H_BARCELONA,
72 AMDFAM10H_SHANGHAI,
73 AMDFAM10H_ISTANBUL,
74 AMDFAM15H_BDVER1,
75 AMDFAM15H_BDVER2,
76 AMDFAM15H_BDVER3,
77 AMDFAM15H_BDVER4,
78 AMDFAM17H_ZNVER1,
79 INTEL_COREI7_IVYBRIDGE,
80 INTEL_COREI7_HASWELL,
81 INTEL_COREI7_BROADWELL,
82 INTEL_COREI7_SKYLAKE,
83 INTEL_COREI7_SKYLAKE_AVX512,
84 CPU_SUBTYPE_MAX
87 /* ISA Features supported. New features have to be inserted at the end. */
89 enum processor_features
91 FEATURE_CMOV = 0,
92 FEATURE_MMX,
93 FEATURE_POPCNT,
94 FEATURE_SSE,
95 FEATURE_SSE2,
96 FEATURE_SSE3,
97 FEATURE_SSSE3,
98 FEATURE_SSE4_1,
99 FEATURE_SSE4_2,
100 FEATURE_AVX,
101 FEATURE_AVX2,
102 FEATURE_SSE4_A,
103 FEATURE_FMA4,
104 FEATURE_XOP,
105 FEATURE_FMA,
106 FEATURE_AVX512F,
107 FEATURE_BMI,
108 FEATURE_BMI2,
109 FEATURE_AES,
110 FEATURE_PCLMUL,
111 FEATURE_AVX512VL,
112 FEATURE_AVX512BW,
113 FEATURE_AVX512DQ,
114 FEATURE_AVX512CD,
115 FEATURE_AVX512ER,
116 FEATURE_AVX512PF,
117 FEATURE_AVX512VBMI,
118 FEATURE_AVX512IFMA,
119 FEATURE_AVX5124VNNIW,
120 FEATURE_AVX5124FMAPS
123 struct __processor_model
125 unsigned int __cpu_vendor;
126 unsigned int __cpu_type;
127 unsigned int __cpu_subtype;
128 unsigned int __cpu_features[1];
129 } __cpu_model = { };
132 /* Get the specific type of AMD CPU. */
134 static void
135 get_amd_cpu (unsigned int family, unsigned int model)
137 switch (family)
139 /* AMD Family 10h. */
140 case 0x10:
141 __cpu_model.__cpu_type = AMDFAM10H;
142 switch (model)
144 case 0x2:
145 /* Barcelona. */
146 __cpu_model.__cpu_subtype = AMDFAM10H_BARCELONA;
147 break;
148 case 0x4:
149 /* Shanghai. */
150 __cpu_model.__cpu_subtype = AMDFAM10H_SHANGHAI;
151 break;
152 case 0x8:
153 /* Istanbul. */
154 __cpu_model.__cpu_subtype = AMDFAM10H_ISTANBUL;
155 break;
156 default:
157 break;
159 break;
160 /* AMD Family 14h "btver1". */
161 case 0x14:
162 __cpu_model.__cpu_type = AMD_BTVER1;
163 break;
164 /* AMD Family 15h "Bulldozer". */
165 case 0x15:
166 __cpu_model.__cpu_type = AMDFAM15H;
167 /* Bulldozer version 1. */
168 if ( model <= 0xf)
169 __cpu_model.__cpu_subtype = AMDFAM15H_BDVER1;
170 /* Bulldozer version 2 "Piledriver" */
171 if (model >= 0x10 && model <= 0x2f)
172 __cpu_model.__cpu_subtype = AMDFAM15H_BDVER2;
173 /* Bulldozer version 3 "Steamroller" */
174 if (model >= 0x30 && model <= 0x4f)
175 __cpu_model.__cpu_subtype = AMDFAM15H_BDVER3;
176 /* Bulldozer version 4 "Excavator" */
177 if (model >= 0x60 && model <= 0x7f)
178 __cpu_model.__cpu_subtype = AMDFAM15H_BDVER4;
179 break;
180 /* AMD Family 16h "btver2" */
181 case 0x16:
182 __cpu_model.__cpu_type = AMD_BTVER2;
183 break;
184 case 0x17:
185 __cpu_model.__cpu_type = AMDFAM17H;
186 /* AMD family 17h version 1. */
187 if (model <= 0x1f)
188 __cpu_model.__cpu_subtype = AMDFAM17H_ZNVER1;
189 break;
190 default:
191 break;
195 /* Get the specific type of Intel CPU. */
197 static void
198 get_intel_cpu (unsigned int family, unsigned int model, unsigned int brand_id)
200 /* Parse family and model only if brand ID is 0. */
201 if (brand_id == 0)
203 switch (family)
205 case 0x5:
206 /* Pentium. */
207 break;
208 case 0x6:
209 switch (model)
211 case 0x1c:
212 case 0x26:
213 /* Bonnell. */
214 __cpu_model.__cpu_type = INTEL_BONNELL;
215 break;
216 case 0x37:
217 case 0x4a:
218 case 0x4d:
219 case 0x5a:
220 case 0x5d:
221 /* Silvermont. */
222 __cpu_model.__cpu_type = INTEL_SILVERMONT;
223 break;
224 case 0x57:
225 /* Knights Landing. */
226 __cpu_model.__cpu_type = INTEL_KNL;
227 break;
228 case 0x1a:
229 case 0x1e:
230 case 0x1f:
231 case 0x2e:
232 /* Nehalem. */
233 __cpu_model.__cpu_type = INTEL_COREI7;
234 __cpu_model.__cpu_subtype = INTEL_COREI7_NEHALEM;
235 break;
236 case 0x25:
237 case 0x2c:
238 case 0x2f:
239 /* Westmere. */
240 __cpu_model.__cpu_type = INTEL_COREI7;
241 __cpu_model.__cpu_subtype = INTEL_COREI7_WESTMERE;
242 break;
243 case 0x2a:
244 case 0x2d:
245 /* Sandy Bridge. */
246 __cpu_model.__cpu_type = INTEL_COREI7;
247 __cpu_model.__cpu_subtype = INTEL_COREI7_SANDYBRIDGE;
248 break;
249 case 0x3a:
250 case 0x3e:
251 /* Ivy Bridge. */
252 __cpu_model.__cpu_type = INTEL_COREI7;
253 __cpu_model.__cpu_subtype = INTEL_COREI7_IVYBRIDGE;
254 break;
255 case 0x3c:
256 case 0x3f:
257 case 0x45:
258 case 0x46:
259 /* Haswell. */
260 __cpu_model.__cpu_type = INTEL_COREI7;
261 __cpu_model.__cpu_subtype = INTEL_COREI7_HASWELL;
262 break;
263 case 0x3d:
264 case 0x47:
265 case 0x4f:
266 case 0x56:
267 /* Broadwell. */
268 __cpu_model.__cpu_type = INTEL_COREI7;
269 __cpu_model.__cpu_subtype = INTEL_COREI7_BROADWELL;
270 break;
271 case 0x4e:
272 case 0x5e:
273 /* Skylake. */
274 __cpu_model.__cpu_type = INTEL_COREI7;
275 __cpu_model.__cpu_subtype = INTEL_COREI7_SKYLAKE;
276 break;
277 case 0x55:
278 /* Skylake with AVX-512 support. */
279 __cpu_model.__cpu_type = INTEL_COREI7;
280 __cpu_model.__cpu_subtype = INTEL_COREI7_SKYLAKE_AVX512;
281 break;
282 case 0x17:
283 case 0x1d:
284 /* Penryn. */
285 case 0x0f:
286 /* Merom. */
287 __cpu_model.__cpu_type = INTEL_CORE2;
288 break;
289 default:
290 break;
292 break;
293 default:
294 /* We have no idea. */
295 break;
300 /* ECX and EDX are output of CPUID at level one. MAX_CPUID_LEVEL is
301 the max possible level of CPUID insn. */
302 static void
303 get_available_features (unsigned int ecx, unsigned int edx,
304 int max_cpuid_level)
306 unsigned int features = 0;
308 if (edx & bit_CMOV)
309 features |= (1 << FEATURE_CMOV);
310 if (edx & bit_MMX)
311 features |= (1 << FEATURE_MMX);
312 if (edx & bit_SSE)
313 features |= (1 << FEATURE_SSE);
314 if (edx & bit_SSE2)
315 features |= (1 << FEATURE_SSE2);
316 if (ecx & bit_POPCNT)
317 features |= (1 << FEATURE_POPCNT);
318 if (ecx & bit_AES)
319 features |= (1 << FEATURE_AES);
320 if (ecx & bit_PCLMUL)
321 features |= (1 << FEATURE_PCLMUL);
322 if (ecx & bit_SSE3)
323 features |= (1 << FEATURE_SSE3);
324 if (ecx & bit_SSSE3)
325 features |= (1 << FEATURE_SSSE3);
326 if (ecx & bit_SSE4_1)
327 features |= (1 << FEATURE_SSE4_1);
328 if (ecx & bit_SSE4_2)
329 features |= (1 << FEATURE_SSE4_2);
330 if (ecx & bit_AVX)
331 features |= (1 << FEATURE_AVX);
332 if (ecx & bit_FMA)
333 features |= (1 << FEATURE_FMA);
335 /* Get Advanced Features at level 7 (eax = 7, ecx = 0). */
336 if (max_cpuid_level >= 7)
338 unsigned int eax, ebx, ecx, edx;
339 __cpuid_count (7, 0, eax, ebx, ecx, edx);
340 if (ebx & bit_BMI)
341 features |= (1 << FEATURE_BMI);
342 if (ebx & bit_AVX2)
343 features |= (1 << FEATURE_AVX2);
344 if (ebx & bit_BMI2)
345 features |= (1 << FEATURE_BMI2);
346 if (ebx & bit_AVX512F)
347 features |= (1 << FEATURE_AVX512F);
348 if (ebx & bit_AVX512VL)
349 features |= (1 << FEATURE_AVX512VL);
350 if (ebx & bit_AVX512BW)
351 features |= (1 << FEATURE_AVX512BW);
352 if (ebx & bit_AVX512DQ)
353 features |= (1 << FEATURE_AVX512DQ);
354 if (ebx & bit_AVX512CD)
355 features |= (1 << FEATURE_AVX512CD);
356 if (ebx & bit_AVX512PF)
357 features |= (1 << FEATURE_AVX512PF);
358 if (ebx & bit_AVX512ER)
359 features |= (1 << FEATURE_AVX512ER);
360 if (ebx & bit_AVX512IFMA)
361 features |= (1 << FEATURE_AVX512IFMA);
362 if (ecx & bit_AVX512VBMI)
363 features |= (1 << FEATURE_AVX512VBMI);
364 if (edx & bit_AVX5124VNNIW)
365 features |= (1 << FEATURE_AVX5124VNNIW);
366 if (edx & bit_AVX5124FMAPS)
367 features |= (1 << FEATURE_AVX5124FMAPS);
370 unsigned int ext_level;
371 unsigned int eax, ebx;
372 /* Check cpuid level of extended features. */
373 __cpuid (0x80000000, ext_level, ebx, ecx, edx);
375 if (ext_level > 0x80000000)
377 __cpuid (0x80000001, eax, ebx, ecx, edx);
379 if (ecx & bit_SSE4a)
380 features |= (1 << FEATURE_SSE4_A);
381 if (ecx & bit_FMA4)
382 features |= (1 << FEATURE_FMA4);
383 if (ecx & bit_XOP)
384 features |= (1 << FEATURE_XOP);
387 __cpu_model.__cpu_features[0] = features;
390 /* A constructor function that is sets __cpu_model and __cpu_features with
391 the right values. This needs to run only once. This constructor is
392 given the highest priority and it should run before constructors without
393 the priority set. However, it still runs after ifunc initializers and
394 needs to be called explicitly there. */
396 int __attribute__ ((constructor CONSTRUCTOR_PRIORITY))
397 __cpu_indicator_init (void)
399 unsigned int eax, ebx, ecx, edx;
401 int max_level;
402 unsigned int vendor;
403 unsigned int model, family, brand_id;
404 unsigned int extended_model, extended_family;
406 /* This function needs to run just once. */
407 if (__cpu_model.__cpu_vendor)
408 return 0;
410 /* Assume cpuid insn present. Run in level 0 to get vendor id. */
411 if (!__get_cpuid (0, &eax, &ebx, &ecx, &edx))
413 __cpu_model.__cpu_vendor = VENDOR_OTHER;
414 return -1;
417 vendor = ebx;
418 max_level = eax;
420 if (max_level < 1)
422 __cpu_model.__cpu_vendor = VENDOR_OTHER;
423 return -1;
426 if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
428 __cpu_model.__cpu_vendor = VENDOR_OTHER;
429 return -1;
432 model = (eax >> 4) & 0x0f;
433 family = (eax >> 8) & 0x0f;
434 brand_id = ebx & 0xff;
435 extended_model = (eax >> 12) & 0xf0;
436 extended_family = (eax >> 20) & 0xff;
438 if (vendor == signature_INTEL_ebx)
440 /* Adjust model and family for Intel CPUS. */
441 if (family == 0x0f)
443 family += extended_family;
444 model += extended_model;
446 else if (family == 0x06)
447 model += extended_model;
449 /* Get CPU type. */
450 get_intel_cpu (family, model, brand_id);
451 /* Find available features. */
452 get_available_features (ecx, edx, max_level);
453 __cpu_model.__cpu_vendor = VENDOR_INTEL;
455 else if (vendor == signature_AMD_ebx)
457 /* Adjust model and family for AMD CPUS. */
458 if (family == 0x0f)
460 family += extended_family;
461 model += extended_model;
464 /* Get CPU type. */
465 get_amd_cpu (family, model);
466 /* Find available features. */
467 get_available_features (ecx, edx, max_level);
468 __cpu_model.__cpu_vendor = VENDOR_AMD;
470 else
471 __cpu_model.__cpu_vendor = VENDOR_OTHER;
473 gcc_assert (__cpu_model.__cpu_vendor < VENDOR_MAX);
474 gcc_assert (__cpu_model.__cpu_type < CPU_TYPE_MAX);
475 gcc_assert (__cpu_model.__cpu_subtype < CPU_SUBTYPE_MAX);
477 return 0;
480 #if defined SHARED && defined USE_ELF_SYMVER
481 __asm__ (".symver __cpu_indicator_init, __cpu_indicator_init@GCC_4.8.0");
482 __asm__ (".symver __cpu_model, __cpu_model@GCC_4.8.0");
483 #endif