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