* gcc-interface/trans.c (Subprogram_Body_to_gnu): Initialize locus.
[official-gcc.git] / libgcc / config / i386 / cpuinfo.c
blob15799f4c4972fbc944f3a8d249b3d7099b6d78d7
1 /* Get CPU type and Features for x86 processors.
2 Copyright (C) 2012-2017 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 = { };
44 /* Get the specific type of AMD CPU. */
46 static void
47 get_amd_cpu (unsigned int family, unsigned int model)
49 switch (family)
51 /* AMD Family 10h. */
52 case 0x10:
53 __cpu_model.__cpu_type = AMDFAM10H;
54 switch (model)
56 case 0x2:
57 /* Barcelona. */
58 __cpu_model.__cpu_subtype = AMDFAM10H_BARCELONA;
59 break;
60 case 0x4:
61 /* Shanghai. */
62 __cpu_model.__cpu_subtype = AMDFAM10H_SHANGHAI;
63 break;
64 case 0x8:
65 /* Istanbul. */
66 __cpu_model.__cpu_subtype = AMDFAM10H_ISTANBUL;
67 break;
68 default:
69 break;
71 break;
72 /* AMD Family 14h "btver1". */
73 case 0x14:
74 __cpu_model.__cpu_type = AMD_BTVER1;
75 break;
76 /* AMD Family 15h "Bulldozer". */
77 case 0x15:
78 __cpu_model.__cpu_type = AMDFAM15H;
79 /* Bulldozer version 1. */
80 if ( model <= 0xf)
81 __cpu_model.__cpu_subtype = AMDFAM15H_BDVER1;
82 /* Bulldozer version 2 "Piledriver" */
83 if (model >= 0x10 && model <= 0x2f)
84 __cpu_model.__cpu_subtype = AMDFAM15H_BDVER2;
85 /* Bulldozer version 3 "Steamroller" */
86 if (model >= 0x30 && model <= 0x4f)
87 __cpu_model.__cpu_subtype = AMDFAM15H_BDVER3;
88 /* Bulldozer version 4 "Excavator" */
89 if (model >= 0x60 && model <= 0x7f)
90 __cpu_model.__cpu_subtype = AMDFAM15H_BDVER4;
91 break;
92 /* AMD Family 16h "btver2" */
93 case 0x16:
94 __cpu_model.__cpu_type = AMD_BTVER2;
95 break;
96 case 0x17:
97 __cpu_model.__cpu_type = AMDFAM17H;
98 /* AMD family 17h version 1. */
99 if (model <= 0x1f)
100 __cpu_model.__cpu_subtype = AMDFAM17H_ZNVER1;
101 break;
102 default:
103 break;
107 /* Get the specific type of Intel CPU. */
109 static void
110 get_intel_cpu (unsigned int family, unsigned int model, unsigned int brand_id)
112 /* Parse family and model only if brand ID is 0. */
113 if (brand_id == 0)
115 switch (family)
117 case 0x5:
118 /* Pentium. */
119 break;
120 case 0x6:
121 switch (model)
123 case 0x1c:
124 case 0x26:
125 /* Bonnell. */
126 __cpu_model.__cpu_type = INTEL_BONNELL;
127 break;
128 case 0x37:
129 case 0x4a:
130 case 0x4d:
131 case 0x5a:
132 case 0x5d:
133 /* Silvermont. */
134 __cpu_model.__cpu_type = INTEL_SILVERMONT;
135 break;
136 case 0x57:
137 /* Knights Landing. */
138 __cpu_model.__cpu_type = INTEL_KNL;
139 break;
140 case 0x85:
141 /* Knights Mill. */
142 __cpu_model.__cpu_type = INTEL_KNM;
143 break;
144 case 0x1a:
145 case 0x1e:
146 case 0x1f:
147 case 0x2e:
148 /* Nehalem. */
149 __cpu_model.__cpu_type = INTEL_COREI7;
150 __cpu_model.__cpu_subtype = INTEL_COREI7_NEHALEM;
151 break;
152 case 0x25:
153 case 0x2c:
154 case 0x2f:
155 /* Westmere. */
156 __cpu_model.__cpu_type = INTEL_COREI7;
157 __cpu_model.__cpu_subtype = INTEL_COREI7_WESTMERE;
158 break;
159 case 0x2a:
160 case 0x2d:
161 /* Sandy Bridge. */
162 __cpu_model.__cpu_type = INTEL_COREI7;
163 __cpu_model.__cpu_subtype = INTEL_COREI7_SANDYBRIDGE;
164 break;
165 case 0x3a:
166 case 0x3e:
167 /* Ivy Bridge. */
168 __cpu_model.__cpu_type = INTEL_COREI7;
169 __cpu_model.__cpu_subtype = INTEL_COREI7_IVYBRIDGE;
170 break;
171 case 0x3c:
172 case 0x3f:
173 case 0x45:
174 case 0x46:
175 /* Haswell. */
176 __cpu_model.__cpu_type = INTEL_COREI7;
177 __cpu_model.__cpu_subtype = INTEL_COREI7_HASWELL;
178 break;
179 case 0x3d:
180 case 0x47:
181 case 0x4f:
182 case 0x56:
183 /* Broadwell. */
184 __cpu_model.__cpu_type = INTEL_COREI7;
185 __cpu_model.__cpu_subtype = INTEL_COREI7_BROADWELL;
186 break;
187 case 0x4e:
188 case 0x5e:
189 /* Skylake. */
190 case 0x8e:
191 case 0x9e:
192 /* Kaby Lake. */
193 __cpu_model.__cpu_type = INTEL_COREI7;
194 __cpu_model.__cpu_subtype = INTEL_COREI7_SKYLAKE;
195 break;
196 case 0x55:
197 /* Skylake with AVX-512 support. */
198 __cpu_model.__cpu_type = INTEL_COREI7;
199 __cpu_model.__cpu_subtype = INTEL_COREI7_SKYLAKE_AVX512;
200 break;
201 case 0x66:
202 /* Cannon Lake. */
203 __cpu_model.__cpu_type = INTEL_COREI7;
204 __cpu_model.__cpu_subtype = INTEL_COREI7_CANNONLAKE;
205 break;
206 case 0x17:
207 case 0x1d:
208 /* Penryn. */
209 case 0x0f:
210 /* Merom. */
211 __cpu_model.__cpu_type = INTEL_CORE2;
212 break;
213 default:
214 break;
216 break;
217 default:
218 /* We have no idea. */
219 break;
224 /* ECX and EDX are output of CPUID at level one. MAX_CPUID_LEVEL is
225 the max possible level of CPUID insn. */
226 static void
227 get_available_features (unsigned int ecx, unsigned int edx,
228 int max_cpuid_level)
230 unsigned int eax, ebx;
231 unsigned int ext_level;
233 unsigned int features = 0;
235 if (edx & bit_CMOV)
236 features |= (1 << FEATURE_CMOV);
237 if (edx & bit_MMX)
238 features |= (1 << FEATURE_MMX);
239 if (edx & bit_SSE)
240 features |= (1 << FEATURE_SSE);
241 if (edx & bit_SSE2)
242 features |= (1 << FEATURE_SSE2);
243 if (ecx & bit_POPCNT)
244 features |= (1 << FEATURE_POPCNT);
245 if (ecx & bit_AES)
246 features |= (1 << FEATURE_AES);
247 if (ecx & bit_PCLMUL)
248 features |= (1 << FEATURE_PCLMUL);
249 if (ecx & bit_SSE3)
250 features |= (1 << FEATURE_SSE3);
251 if (ecx & bit_SSSE3)
252 features |= (1 << FEATURE_SSSE3);
253 if (ecx & bit_SSE4_1)
254 features |= (1 << FEATURE_SSE4_1);
255 if (ecx & bit_SSE4_2)
256 features |= (1 << FEATURE_SSE4_2);
257 if (ecx & bit_AVX)
258 features |= (1 << FEATURE_AVX);
259 if (ecx & bit_FMA)
260 features |= (1 << FEATURE_FMA);
262 /* Get Advanced Features at level 7 (eax = 7, ecx = 0). */
263 if (max_cpuid_level >= 7)
265 __cpuid_count (7, 0, eax, ebx, ecx, edx);
266 if (ebx & bit_BMI)
267 features |= (1 << FEATURE_BMI);
268 if (ebx & bit_AVX2)
269 features |= (1 << FEATURE_AVX2);
270 if (ebx & bit_BMI2)
271 features |= (1 << FEATURE_BMI2);
272 if (ebx & bit_AVX512F)
273 features |= (1 << FEATURE_AVX512F);
274 if (ebx & bit_AVX512VL)
275 features |= (1 << FEATURE_AVX512VL);
276 if (ebx & bit_AVX512BW)
277 features |= (1 << FEATURE_AVX512BW);
278 if (ebx & bit_AVX512DQ)
279 features |= (1 << FEATURE_AVX512DQ);
280 if (ebx & bit_AVX512CD)
281 features |= (1 << FEATURE_AVX512CD);
282 if (ebx & bit_AVX512PF)
283 features |= (1 << FEATURE_AVX512PF);
284 if (ebx & bit_AVX512ER)
285 features |= (1 << FEATURE_AVX512ER);
286 if (ebx & bit_AVX512IFMA)
287 features |= (1 << FEATURE_AVX512IFMA);
288 if (ecx & bit_AVX512VBMI)
289 features |= (1 << FEATURE_AVX512VBMI);
290 if (ecx & bit_AVX512VPOPCNTDQ)
291 features |= (1 << FEATURE_AVX512VPOPCNTDQ);
292 if (edx & bit_AVX5124VNNIW)
293 features |= (1 << FEATURE_AVX5124VNNIW);
294 if (edx & bit_AVX5124FMAPS)
295 features |= (1 << FEATURE_AVX5124FMAPS);
298 /* Check cpuid level of extended features. */
299 __cpuid (0x80000000, ext_level, ebx, ecx, edx);
301 if (ext_level >= 0x80000001)
303 __cpuid (0x80000001, eax, ebx, ecx, edx);
305 if (ecx & bit_SSE4a)
306 features |= (1 << FEATURE_SSE4_A);
307 if (ecx & bit_FMA4)
308 features |= (1 << FEATURE_FMA4);
309 if (ecx & bit_XOP)
310 features |= (1 << FEATURE_XOP);
313 __cpu_model.__cpu_features[0] = features;
316 /* A constructor function that is sets __cpu_model and __cpu_features with
317 the right values. This needs to run only once. This constructor is
318 given the highest priority and it should run before constructors without
319 the priority set. However, it still runs after ifunc initializers and
320 needs to be called explicitly there. */
322 int __attribute__ ((constructor CONSTRUCTOR_PRIORITY))
323 __cpu_indicator_init (void)
325 unsigned int eax, ebx, ecx, edx;
327 int max_level;
328 unsigned int vendor;
329 unsigned int model, family, brand_id;
330 unsigned int extended_model, extended_family;
332 /* This function needs to run just once. */
333 if (__cpu_model.__cpu_vendor)
334 return 0;
336 /* Assume cpuid insn present. Run in level 0 to get vendor id. */
337 if (!__get_cpuid (0, &eax, &ebx, &ecx, &edx))
339 __cpu_model.__cpu_vendor = VENDOR_OTHER;
340 return -1;
343 vendor = ebx;
344 max_level = eax;
346 if (max_level < 1)
348 __cpu_model.__cpu_vendor = VENDOR_OTHER;
349 return -1;
352 if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
354 __cpu_model.__cpu_vendor = VENDOR_OTHER;
355 return -1;
358 model = (eax >> 4) & 0x0f;
359 family = (eax >> 8) & 0x0f;
360 brand_id = ebx & 0xff;
361 extended_model = (eax >> 12) & 0xf0;
362 extended_family = (eax >> 20) & 0xff;
364 if (vendor == signature_INTEL_ebx)
366 /* Adjust model and family for Intel CPUS. */
367 if (family == 0x0f)
369 family += extended_family;
370 model += extended_model;
372 else if (family == 0x06)
373 model += extended_model;
375 /* Get CPU type. */
376 get_intel_cpu (family, model, brand_id);
377 /* Find available features. */
378 get_available_features (ecx, edx, max_level);
379 __cpu_model.__cpu_vendor = VENDOR_INTEL;
381 else if (vendor == signature_AMD_ebx)
383 /* Adjust model and family for AMD CPUS. */
384 if (family == 0x0f)
386 family += extended_family;
387 model += extended_model;
390 /* Get CPU type. */
391 get_amd_cpu (family, model);
392 /* Find available features. */
393 get_available_features (ecx, edx, max_level);
394 __cpu_model.__cpu_vendor = VENDOR_AMD;
396 else
397 __cpu_model.__cpu_vendor = VENDOR_OTHER;
399 gcc_assert (__cpu_model.__cpu_vendor < VENDOR_MAX);
400 gcc_assert (__cpu_model.__cpu_type < CPU_TYPE_MAX);
401 gcc_assert (__cpu_model.__cpu_subtype < CPU_SUBTYPE_MAX);
403 return 0;
406 #if defined SHARED && defined USE_ELF_SYMVER
407 __asm__ (".symver __cpu_indicator_init, __cpu_indicator_init@GCC_4.8.0");
408 __asm__ (".symver __cpu_model, __cpu_model@GCC_4.8.0");
409 #endif