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)
4 
5 This file is part of GCC.
6 
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.
11 
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.
16 
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.
20 
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/>.  */
25 
26 #include "cpuid.h"
27 #include "tsystem.h"
28 #include "auto-target.h"
29 #include "cpuinfo.h"
30 
31 #ifdef HAVE_INIT_PRIORITY
32 #define CONSTRUCTOR_PRIORITY (101)
33 #else
34 #define CONSTRUCTOR_PRIORITY
35 #endif
36 
37 int __cpu_indicator_init (void)
38   __attribute__ ((constructor CONSTRUCTOR_PRIORITY));
39 
40 
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
49 
50 
51 /* Get the specific type of AMD CPU.  */
52 
53 static void
54 get_amd_cpu (unsigned int family, unsigned int model)
55 {
56   switch (family)
57     {
58     /* AMD Family 10h.  */
59     case 0x10:
60       __cpu_model.__cpu_type = AMDFAM10H;
61       switch (model)
62 	{
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;
77 	}
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;
111     }
112 }
113 
114 /* Get the specific type of Intel CPU.  */
115 
116 static void
117 get_intel_cpu (unsigned int family, unsigned int model, unsigned int brand_id)
118 {
119   /* Parse family and model only if brand ID is 0. */
120   if (brand_id == 0)
121     {
122       switch (family)
123 	{
124 	case 0x5:
125 	  /* Pentium.  */
126 	  break;
127 	case 0x6:
128 	  switch (model)
129 	    {
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 0x57:
144 	      /* Knights Landing.  */
145 	      __cpu_model.__cpu_type = INTEL_KNL;
146 	      break;
147 	    case 0x85:
148 	      /* Knights Mill. */
149 	      __cpu_model.__cpu_type = INTEL_KNM;
150 	      break;
151 	    case 0x1a:
152 	    case 0x1e:
153 	    case 0x1f:
154 	    case 0x2e:
155 	      /* Nehalem.  */
156 	      __cpu_model.__cpu_type = INTEL_COREI7;
157 	      __cpu_model.__cpu_subtype = INTEL_COREI7_NEHALEM;
158 	      break;
159 	    case 0x25:
160 	    case 0x2c:
161 	    case 0x2f:
162 	      /* Westmere.  */
163 	      __cpu_model.__cpu_type = INTEL_COREI7;
164 	      __cpu_model.__cpu_subtype = INTEL_COREI7_WESTMERE;
165 	      break;
166 	    case 0x2a:
167 	    case 0x2d:
168 	      /* Sandy Bridge.  */
169 	      __cpu_model.__cpu_type = INTEL_COREI7;
170 	      __cpu_model.__cpu_subtype = INTEL_COREI7_SANDYBRIDGE;
171 	      break;
172 	    case 0x3a:
173 	    case 0x3e:
174 	      /* Ivy Bridge.  */
175 	      __cpu_model.__cpu_type = INTEL_COREI7;
176 	      __cpu_model.__cpu_subtype = INTEL_COREI7_IVYBRIDGE;
177 	      break;
178 	    case 0x3c:
179 	    case 0x3f:
180 	    case 0x45:
181 	    case 0x46:
182 	      /* Haswell.  */
183 	      __cpu_model.__cpu_type = INTEL_COREI7;
184 	      __cpu_model.__cpu_subtype = INTEL_COREI7_HASWELL;
185 	      break;
186 	    case 0x3d:
187 	    case 0x47:
188 	    case 0x4f:
189 	    case 0x56:
190 	      /* Broadwell.  */
191 	      __cpu_model.__cpu_type = INTEL_COREI7;
192 	      __cpu_model.__cpu_subtype = INTEL_COREI7_BROADWELL;
193 	      break;
194 	    case 0x4e:
195 	    case 0x5e:
196 	      /* Skylake.  */
197 	    case 0x8e:
198 	    case 0x9e:
199 	      /* Kaby Lake.  */
200 	      __cpu_model.__cpu_type = INTEL_COREI7;
201 	      __cpu_model.__cpu_subtype = INTEL_COREI7_SKYLAKE;
202 	      break;
203 	    case 0x55:
204 	      /* Skylake with AVX-512 support.  */
205 	      __cpu_model.__cpu_type = INTEL_COREI7;
206 	      __cpu_model.__cpu_subtype = INTEL_COREI7_SKYLAKE_AVX512;
207 	      break;
208 	    case 0x66:
209 	      /* Cannon Lake.  */
210 	      __cpu_model.__cpu_type = INTEL_COREI7;
211 	      __cpu_model.__cpu_subtype = INTEL_COREI7_CANNONLAKE;
212 	      break;
213 	    case 0x17:
214 	    case 0x1d:
215 	      /* Penryn.  */
216 	    case 0x0f:
217 	      /* Merom.  */
218 	      __cpu_model.__cpu_type = INTEL_CORE2;
219 	      break;
220 	    default:
221 	      break;
222 	    }
223 	  break;
224 	default:
225 	  /* We have no idea.  */
226 	  break;
227 	}
228     }
229 }
230 
231 /* ECX and EDX are output of CPUID at level one.  MAX_CPUID_LEVEL is
232    the max possible level of CPUID insn.  */
233 static void
234 get_available_features (unsigned int ecx, unsigned int edx,
235 			int max_cpuid_level)
236 {
237   unsigned int eax, ebx;
238   unsigned int ext_level;
239 
240   unsigned int features = 0;
241   unsigned int features2 = 0;
242 
243   /* Get XCR_XFEATURE_ENABLED_MASK register with xgetbv.  */
244 #define XCR_XFEATURE_ENABLED_MASK	0x0
245 #define XSTATE_FP			0x1
246 #define XSTATE_SSE			0x2
247 #define XSTATE_YMM			0x4
248 #define XSTATE_OPMASK			0x20
249 #define XSTATE_ZMM			0x40
250 #define XSTATE_HI_ZMM			0x80
251 
252 #define XCR_AVX_ENABLED_MASK \
253   (XSTATE_SSE | XSTATE_YMM)
254 #define XCR_AVX512F_ENABLED_MASK \
255   (XSTATE_SSE | XSTATE_YMM | XSTATE_OPMASK | XSTATE_ZMM | XSTATE_HI_ZMM)
256 
257   /* Check if AVX and AVX512 are usable.  */
258   int avx_usable = 0;
259   int avx512_usable = 0;
260   if ((ecx & bit_OSXSAVE))
261     {
262       /* Check if XMM, YMM, OPMASK, upper 256 bits of ZMM0-ZMM15 and
263          ZMM16-ZMM31 states are supported by OSXSAVE.  */
264       unsigned int xcrlow;
265       unsigned int xcrhigh;
266       asm (".byte 0x0f, 0x01, 0xd0"
267 	   : "=a" (xcrlow), "=d" (xcrhigh)
268 	   : "c" (XCR_XFEATURE_ENABLED_MASK));
269       if ((xcrlow & XCR_AVX_ENABLED_MASK) == XCR_AVX_ENABLED_MASK)
270 	{
271 	  avx_usable = 1;
272 	  avx512_usable = ((xcrlow & XCR_AVX512F_ENABLED_MASK)
273 			   == XCR_AVX512F_ENABLED_MASK);
274 	}
275     }
276 
277 #define set_feature(f) \
278   do						\
279     {						\
280       if (f < 32)				\
281 	features |= (1U << (f & 31));		\
282       else					\
283 	features2 |= (1U << ((f - 32) & 31));	\
284     }						\
285   while (0)
286 
287   if (edx & bit_CMOV)
288     set_feature (FEATURE_CMOV);
289   if (edx & bit_MMX)
290     set_feature (FEATURE_MMX);
291   if (edx & bit_SSE)
292     set_feature (FEATURE_SSE);
293   if (edx & bit_SSE2)
294     set_feature (FEATURE_SSE2);
295   if (ecx & bit_POPCNT)
296     set_feature (FEATURE_POPCNT);
297   if (ecx & bit_AES)
298     set_feature (FEATURE_AES);
299   if (ecx & bit_PCLMUL)
300     set_feature (FEATURE_PCLMUL);
301   if (ecx & bit_SSE3)
302     set_feature (FEATURE_SSE3);
303   if (ecx & bit_SSSE3)
304     set_feature (FEATURE_SSSE3);
305   if (ecx & bit_SSE4_1)
306     set_feature (FEATURE_SSE4_1);
307   if (ecx & bit_SSE4_2)
308     set_feature (FEATURE_SSE4_2);
309   if (avx_usable)
310     {
311       if (ecx & bit_AVX)
312 	set_feature (FEATURE_AVX);
313       if (ecx & bit_FMA)
314 	set_feature (FEATURE_FMA);
315     }
316 
317   /* Get Advanced Features at level 7 (eax = 7, ecx = 0). */
318   if (max_cpuid_level >= 7)
319     {
320       __cpuid_count (7, 0, eax, ebx, ecx, edx);
321       if (ebx & bit_BMI)
322 	set_feature (FEATURE_BMI);
323       if (avx_usable)
324 	{
325 	  if (ebx & bit_AVX2)
326 	    set_feature (FEATURE_AVX2);
327 	}
328       if (ebx & bit_BMI2)
329 	set_feature (FEATURE_BMI2);
330       if (avx512_usable)
331 	{
332 	  if (ebx & bit_AVX512F)
333 	    set_feature (FEATURE_AVX512F);
334 	  if (ebx & bit_AVX512VL)
335 	    set_feature (FEATURE_AVX512VL);
336 	  if (ebx & bit_AVX512BW)
337 	    set_feature (FEATURE_AVX512BW);
338 	  if (ebx & bit_AVX512DQ)
339 	    set_feature (FEATURE_AVX512DQ);
340 	  if (ebx & bit_AVX512CD)
341 	    set_feature (FEATURE_AVX512CD);
342 	  if (ebx & bit_AVX512PF)
343 	    set_feature (FEATURE_AVX512PF);
344 	  if (ebx & bit_AVX512ER)
345 	    set_feature (FEATURE_AVX512ER);
346 	  if (ebx & bit_AVX512IFMA)
347 	    set_feature (FEATURE_AVX512IFMA);
348 	  if (ecx & bit_AVX512VBMI)
349 	    set_feature (FEATURE_AVX512VBMI);
350 	  if (ecx & bit_AVX512VBMI2)
351 	    set_feature (FEATURE_AVX512VBMI2);
352 	  if (ecx & bit_GFNI)
353 	    set_feature (FEATURE_GFNI);
354 	  if (ecx & bit_VPCLMULQDQ)
355 	    set_feature (FEATURE_VPCLMULQDQ);
356 	  if (ecx & bit_AVX512VNNI)
357 	    set_feature (FEATURE_AVX512VNNI);
358 	  if (ecx & bit_AVX512BITALG)
359 	    set_feature (FEATURE_AVX512BITALG);
360 	  if (ecx & bit_AVX512VPOPCNTDQ)
361 	    set_feature (FEATURE_AVX512VPOPCNTDQ);
362 	  if (edx & bit_AVX5124VNNIW)
363 	    set_feature (FEATURE_AVX5124VNNIW);
364 	  if (edx & bit_AVX5124FMAPS)
365 	    set_feature (FEATURE_AVX5124FMAPS);
366 	}
367     }
368 
369   /* Check cpuid level of extended features.  */
370   __cpuid (0x80000000, ext_level, ebx, ecx, edx);
371 
372   if (ext_level >= 0x80000001)
373     {
374       __cpuid (0x80000001, eax, ebx, ecx, edx);
375 
376       if (ecx & bit_SSE4a)
377 	set_feature (FEATURE_SSE4_A);
378       if (avx_usable)
379 	{
380 	  if (ecx & bit_FMA4)
381 	    set_feature (FEATURE_FMA4);
382 	  if (ecx & bit_XOP)
383 	    set_feature (FEATURE_XOP);
384 	}
385     }
386 
387   __cpu_model.__cpu_features[0] = features;
388 #ifndef SHARED
389   __cpu_features2 = features2;
390 #else
391   (void) features2;
392 #endif
393 }
394 
395 /* A constructor function that is sets __cpu_model and __cpu_features with
396    the right values.  This needs to run only once.  This constructor is
397    given the highest priority and it should run before constructors without
398    the priority set.  However, it still runs after ifunc initializers and
399    needs to be called explicitly there.  */
400 
401 int __attribute__ ((constructor CONSTRUCTOR_PRIORITY))
402 __cpu_indicator_init (void)
403 {
404   unsigned int eax, ebx, ecx, edx;
405 
406   int max_level;
407   unsigned int vendor;
408   unsigned int model, family, brand_id;
409   unsigned int extended_model, extended_family;
410 
411   /* This function needs to run just once.  */
412   if (__cpu_model.__cpu_vendor)
413     return 0;
414 
415   /* Assume cpuid insn present. Run in level 0 to get vendor id. */
416   if (!__get_cpuid (0, &eax, &ebx, &ecx, &edx))
417     {
418       __cpu_model.__cpu_vendor = VENDOR_OTHER;
419       return -1;
420     }
421 
422   vendor = ebx;
423   max_level = eax;
424 
425   if (max_level < 1)
426     {
427       __cpu_model.__cpu_vendor = VENDOR_OTHER;
428       return -1;
429     }
430 
431   if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
432     {
433       __cpu_model.__cpu_vendor = VENDOR_OTHER;
434       return -1;
435     }
436 
437   model = (eax >> 4) & 0x0f;
438   family = (eax >> 8) & 0x0f;
439   brand_id = ebx & 0xff;
440   extended_model = (eax >> 12) & 0xf0;
441   extended_family = (eax >> 20) & 0xff;
442 
443   if (vendor == signature_INTEL_ebx)
444     {
445       /* Adjust model and family for Intel CPUS. */
446       if (family == 0x0f)
447 	{
448 	  family += extended_family;
449 	  model += extended_model;
450 	}
451       else if (family == 0x06)
452 	model += extended_model;
453 
454       /* Get CPU type.  */
455       get_intel_cpu (family, model, brand_id);
456       /* Find available features. */
457       get_available_features (ecx, edx, max_level);
458       __cpu_model.__cpu_vendor = VENDOR_INTEL;
459     }
460   else if (vendor == signature_AMD_ebx)
461     {
462       /* Adjust model and family for AMD CPUS. */
463       if (family == 0x0f)
464 	{
465 	  family += extended_family;
466 	  model += extended_model;
467 	}
468 
469       /* Get CPU type.  */
470       get_amd_cpu (family, model);
471       /* Find available features. */
472       get_available_features (ecx, edx, max_level);
473       __cpu_model.__cpu_vendor = VENDOR_AMD;
474     }
475   else
476     __cpu_model.__cpu_vendor = VENDOR_OTHER;
477 
478   gcc_assert (__cpu_model.__cpu_vendor < VENDOR_MAX);
479   gcc_assert (__cpu_model.__cpu_type < CPU_TYPE_MAX);
480   gcc_assert (__cpu_model.__cpu_subtype < CPU_SUBTYPE_MAX);
481 
482   return 0;
483 }
484 
485 #if defined SHARED && defined USE_ELF_SYMVER
486 __asm__ (".symver __cpu_indicator_init, __cpu_indicator_init@GCC_4.8.0");
487 __asm__ (".symver __cpu_model, __cpu_model@GCC_4.8.0");
488 #endif
489