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