1 1.1 mrg /* Get CPU type and Features for x86 processors. 2 1.1 mrg Copyright (C) 2012-2022 Free Software Foundation, Inc. 3 1.1 mrg Contributed by Sriraman Tallam (tmsriram (at) google.com) 4 1.1 mrg 5 1.1 mrg This file is part of GCC. 6 1.1 mrg 7 1.1 mrg GCC is free software; you can redistribute it and/or modify it under 8 1.1 mrg the terms of the GNU General Public License as published by the Free 9 1.1 mrg Software Foundation; either version 3, or (at your option) any later 10 1.1 mrg version. 11 1.1 mrg 12 1.1 mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY 13 1.1 mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 1.1 mrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 1.1 mrg for more details. 16 1.1 mrg 17 1.1 mrg Under Section 7 of GPL version 3, you are granted additional 18 1.1 mrg permissions described in the GCC Runtime Library Exception, version 19 1.1 mrg 3.1, as published by the Free Software Foundation. 20 1.1 mrg 21 1.1 mrg You should have received a copy of the GNU General Public License and 22 1.1 mrg a copy of the GCC Runtime Library Exception along with this program; 23 1.1 mrg see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 24 1.1 mrg <http://www.gnu.org/licenses/>. */ 25 1.1 mrg 26 1.1 mrg struct __processor_model 27 1.1 mrg { 28 1.1 mrg unsigned int __cpu_vendor; 29 1.1 mrg unsigned int __cpu_type; 30 1.1 mrg unsigned int __cpu_subtype; 31 1.1 mrg /* The first 32 features are stored as bitmasks in __cpu_features. 32 1.1 mrg The rest of features are stored as bitmasks in a separate array 33 1.1 mrg of unsigned int. */ 34 1.1 mrg unsigned int __cpu_features[1]; 35 1.1 mrg }; 36 1.1 mrg 37 1.1 mrg struct __processor_model2 38 1.1 mrg { 39 1.1 mrg unsigned int __cpu_family; 40 1.1 mrg unsigned int __cpu_model; 41 1.1 mrg unsigned int __cpu_max_level; 42 1.1 mrg unsigned int __cpu_ext_level; 43 1.1 mrg }; 44 1.1 mrg 45 1.1 mrg #ifndef CHECK___builtin_cpu_is 46 1.1 mrg # define CHECK___builtin_cpu_is(cpu) 47 1.1 mrg #endif 48 1.1 mrg 49 1.1 mrg #ifndef CHECK___builtin_cpu_supports 50 1.1 mrg # define CHECK___builtin_cpu_supports(isa) 51 1.1 mrg #endif 52 1.1 mrg 53 1.1 mrg /* Return non-zero if the processor has feature F. */ 54 1.1 mrg 55 1.1 mrg static inline int 56 1.1 mrg has_cpu_feature (struct __processor_model *cpu_model, 57 1.1 mrg unsigned int *cpu_features2, 58 1.1 mrg enum processor_features feature) 59 1.1 mrg { 60 1.1 mrg unsigned index, offset; 61 1.1 mrg unsigned f = feature; 62 1.1 mrg 63 1.1 mrg if (f < 32) 64 1.1 mrg { 65 1.1 mrg /* The first 32 features. */ 66 1.1 mrg return cpu_model->__cpu_features[0] & (1U << f); 67 1.1 mrg } 68 1.1 mrg else 69 1.1 mrg { 70 1.1 mrg /* The rest of features. cpu_features2[i] contains features from 71 1.1 mrg (32 + i * 32) to (31 + 32 + i * 32), inclusively. */ 72 1.1 mrg f -= 32; 73 1.1 mrg index = f / 32; 74 1.1 mrg offset = f % 32; 75 1.1 mrg return cpu_features2[index] & (1U << offset); 76 1.1 mrg } 77 1.1 mrg } 78 1.1 mrg 79 1.1 mrg static inline void 80 1.1 mrg set_cpu_feature (struct __processor_model *cpu_model, 81 1.1 mrg unsigned int *cpu_features2, 82 1.1 mrg enum processor_features feature) 83 1.1 mrg { 84 1.1 mrg unsigned index, offset; 85 1.1 mrg unsigned f = feature; 86 1.1 mrg 87 1.1 mrg if (f < 32) 88 1.1 mrg { 89 1.1 mrg /* The first 32 features. */ 90 1.1 mrg cpu_model->__cpu_features[0] |= (1U << f); 91 1.1 mrg } 92 1.1 mrg else 93 1.1 mrg { 94 1.1 mrg /* The rest of features. cpu_features2[i] contains features from 95 1.1 mrg (32 + i * 32) to (31 + 32 + i * 32), inclusively. */ 96 1.1 mrg f -= 32; 97 1.1 mrg index = f / 32; 98 1.1 mrg offset = f % 32; 99 1.1 mrg cpu_features2[index] |= (1U << offset); 100 1.1 mrg } 101 1.1 mrg } 102 1.1 mrg 103 1.1 mrg /* Get the specific type of AMD CPU and return AMD CPU name. Return 104 1.1 mrg NULL for unknown AMD CPU. */ 105 1.1 mrg 106 1.1 mrg static inline const char * 107 1.1 mrg get_amd_cpu (struct __processor_model *cpu_model, 108 1.1 mrg struct __processor_model2 *cpu_model2, 109 1.1 mrg unsigned int *cpu_features2) 110 1.1 mrg { 111 1.1 mrg const char *cpu = NULL; 112 1.1 mrg unsigned int family = cpu_model2->__cpu_family; 113 1.1 mrg unsigned int model = cpu_model2->__cpu_model; 114 1.1 mrg 115 1.1 mrg switch (family) 116 1.1 mrg { 117 1.1 mrg case 0x10: 118 1.1 mrg /* AMD Family 10h. */ 119 1.1 mrg cpu = "amdfam10"; 120 1.1 mrg cpu_model->__cpu_type = AMDFAM10H; 121 1.1 mrg switch (model) 122 1.1 mrg { 123 1.1 mrg case 0x2: 124 1.1 mrg /* Barcelona. */ 125 1.1 mrg CHECK___builtin_cpu_is ("amdfam10h"); 126 1.1 mrg CHECK___builtin_cpu_is ("barcelona"); 127 1.1 mrg cpu_model->__cpu_subtype = AMDFAM10H_BARCELONA; 128 1.1 mrg break; 129 1.1 mrg case 0x4: 130 1.1 mrg /* Shanghai. */ 131 1.1 mrg CHECK___builtin_cpu_is ("amdfam10h"); 132 1.1 mrg CHECK___builtin_cpu_is ("shanghai"); 133 1.1 mrg cpu_model->__cpu_subtype = AMDFAM10H_SHANGHAI; 134 1.1 mrg break; 135 1.1 mrg case 0x8: 136 1.1 mrg /* Istanbul. */ 137 1.1 mrg CHECK___builtin_cpu_is ("amdfam10h"); 138 1.1 mrg CHECK___builtin_cpu_is ("istanbul"); 139 1.1 mrg cpu_model->__cpu_subtype = AMDFAM10H_ISTANBUL; 140 1.1 mrg break; 141 1.1 mrg default: 142 1.1 mrg break; 143 1.1 mrg } 144 1.1 mrg break; 145 1.1 mrg case 0x14: 146 1.1 mrg /* AMD Family 14h "btver1". */ 147 1.1 mrg cpu = "btver1"; 148 1.1 mrg CHECK___builtin_cpu_is ("btver1"); 149 1.1 mrg cpu_model->__cpu_type = AMD_BTVER1; 150 1.1 mrg break; 151 1.1 mrg case 0x15: 152 1.1 mrg /* AMD Family 15h "Bulldozer". */ 153 1.1 mrg cpu_model->__cpu_type = AMDFAM15H; 154 1.1 mrg if (model == 0x2) 155 1.1 mrg { 156 1.1 mrg /* Bulldozer version 2 "Piledriver" */ 157 1.1 mrg cpu = "bdver2"; 158 1.1 mrg CHECK___builtin_cpu_is ("bdver2"); 159 1.1 mrg cpu_model->__cpu_subtype = AMDFAM15H_BDVER2; 160 1.1 mrg } 161 1.1 mrg else if (model <= 0xf) 162 1.1 mrg { 163 1.1 mrg /* Bulldozer version 1. */ 164 1.1 mrg cpu = "bdver1"; 165 1.1 mrg CHECK___builtin_cpu_is ("bdver1"); 166 1.1 mrg cpu_model->__cpu_subtype = AMDFAM15H_BDVER1; 167 1.1 mrg } 168 1.1 mrg else if (model <= 0x2f) 169 1.1 mrg { 170 1.1 mrg /* Bulldozer version 2 "Piledriver" */ 171 1.1 mrg cpu = "bdver2"; 172 1.1 mrg CHECK___builtin_cpu_is ("bdver2"); 173 1.1 mrg cpu_model->__cpu_subtype = AMDFAM15H_BDVER2; 174 1.1 mrg } 175 1.1 mrg else if (model <= 0x4f) 176 1.1 mrg { 177 1.1 mrg /* Bulldozer version 3 "Steamroller" */ 178 1.1 mrg cpu = "bdver3"; 179 1.1 mrg CHECK___builtin_cpu_is ("bdver3"); 180 1.1 mrg cpu_model->__cpu_subtype = AMDFAM15H_BDVER3; 181 1.1 mrg } 182 1.1 mrg else if (model <= 0x7f) 183 1.1 mrg { 184 1.1 mrg /* Bulldozer version 4 "Excavator" */ 185 1.1 mrg cpu = "bdver4"; 186 1.1 mrg CHECK___builtin_cpu_is ("bdver4"); 187 1.1 mrg cpu_model->__cpu_subtype = AMDFAM15H_BDVER4; 188 1.1 mrg } 189 1.1 mrg else if (has_cpu_feature (cpu_model, cpu_features2, 190 1.1 mrg FEATURE_AVX2)) 191 1.1 mrg { 192 1.1 mrg cpu = "bdver4"; 193 1.1 mrg CHECK___builtin_cpu_is ("bdver4"); 194 1.1 mrg cpu_model->__cpu_subtype = AMDFAM15H_BDVER4; 195 1.1 mrg } 196 1.1 mrg else if (has_cpu_feature (cpu_model, cpu_features2, 197 1.1 mrg FEATURE_XSAVEOPT)) 198 1.1 mrg { 199 1.1 mrg cpu = "bdver3"; 200 1.1 mrg CHECK___builtin_cpu_is ("bdver3"); 201 1.1 mrg cpu_model->__cpu_subtype = AMDFAM15H_BDVER3; 202 1.1 mrg } 203 1.1 mrg else if (has_cpu_feature (cpu_model, cpu_features2, 204 1.1 mrg FEATURE_BMI)) 205 1.1 mrg { 206 1.1 mrg cpu = "bdver2"; 207 1.1 mrg CHECK___builtin_cpu_is ("bdver2"); 208 1.1 mrg cpu_model->__cpu_subtype = AMDFAM15H_BDVER2; 209 1.1 mrg } 210 1.1 mrg else if (has_cpu_feature (cpu_model, cpu_features2, 211 1.1 mrg FEATURE_XOP)) 212 1.1 mrg { 213 1.1 mrg cpu = "bdver1"; 214 1.1 mrg CHECK___builtin_cpu_is ("bdver1"); 215 1.1 mrg cpu_model->__cpu_subtype = AMDFAM15H_BDVER1; 216 1.1 mrg } 217 1.1 mrg break; 218 1.1 mrg case 0x16: 219 1.1 mrg /* AMD Family 16h "btver2" */ 220 1.1 mrg cpu = "btver2"; 221 1.1 mrg CHECK___builtin_cpu_is ("btver2"); 222 1.1 mrg cpu_model->__cpu_type = AMD_BTVER2; 223 1.1 mrg break; 224 1.1 mrg case 0x17: 225 1.1 mrg cpu_model->__cpu_type = AMDFAM17H; 226 1.1 mrg if (model <= 0x1f) 227 1.1 mrg { 228 1.1 mrg /* AMD family 17h version 1. */ 229 1.1 mrg cpu = "znver1"; 230 1.1 mrg CHECK___builtin_cpu_is ("znver1"); 231 1.1 mrg cpu_model->__cpu_subtype = AMDFAM17H_ZNVER1; 232 1.1 mrg } 233 1.1 mrg else if (model >= 0x30) 234 1.1 mrg { 235 1.1 mrg cpu = "znver2"; 236 1.1 mrg CHECK___builtin_cpu_is ("znver2"); 237 1.1 mrg cpu_model->__cpu_subtype = AMDFAM17H_ZNVER2; 238 1.1 mrg } 239 1.1 mrg else if (has_cpu_feature (cpu_model, cpu_features2, 240 1.1 mrg FEATURE_CLWB)) 241 1.1 mrg { 242 1.1 mrg cpu = "znver2"; 243 1.1 mrg CHECK___builtin_cpu_is ("znver2"); 244 1.1 mrg cpu_model->__cpu_subtype = AMDFAM17H_ZNVER2; 245 1.1 mrg } 246 1.1 mrg else if (has_cpu_feature (cpu_model, cpu_features2, 247 1.1 mrg FEATURE_CLZERO)) 248 1.1 mrg { 249 1.1 mrg cpu = "znver1"; 250 1.1 mrg CHECK___builtin_cpu_is ("znver1"); 251 1.1 mrg cpu_model->__cpu_subtype = AMDFAM17H_ZNVER1; 252 1.1 mrg } 253 1.1 mrg break; 254 1.1 mrg case 0x19: 255 1.1 mrg cpu_model->__cpu_type = AMDFAM19H; 256 1.1 mrg /* AMD family 19h. */ 257 1.1 mrg if (model <= 0x0f) 258 1.1 mrg { 259 1.1 mrg cpu = "znver3"; 260 1.1 mrg CHECK___builtin_cpu_is ("znver3"); 261 1.1 mrg cpu_model->__cpu_subtype = AMDFAM19H_ZNVER3; 262 1.1 mrg } 263 1.1 mrg else if ((model >= 0x10 && model <= 0x1f) 264 1.1 mrg || (model >= 0x60 && model <= 0xaf)) 265 1.1 mrg { 266 1.1 mrg cpu = "znver4"; 267 1.1 mrg CHECK___builtin_cpu_is ("znver4"); 268 1.1 mrg cpu_model->__cpu_subtype = AMDFAM19H_ZNVER4; 269 1.1 mrg } 270 1.1 mrg else if (has_cpu_feature (cpu_model, cpu_features2, 271 1.1 mrg FEATURE_AVX512F)) 272 1.1 mrg { 273 1.1 mrg cpu = "znver4"; 274 1.1 mrg CHECK___builtin_cpu_is ("znver4"); 275 1.1 mrg cpu_model->__cpu_subtype = AMDFAM19H_ZNVER4; 276 1.1 mrg } 277 1.1 mrg else if (has_cpu_feature (cpu_model, cpu_features2, 278 1.1 mrg FEATURE_VAES)) 279 1.1 mrg { 280 1.1 mrg cpu = "znver3"; 281 1.1 mrg CHECK___builtin_cpu_is ("znver3"); 282 1.1 mrg cpu_model->__cpu_subtype = AMDFAM19H_ZNVER3; 283 1.1 mrg } 284 1.1 mrg break; 285 1.1 mrg case 0x1a: 286 1.1 mrg cpu_model->__cpu_type = AMDFAM1AH; 287 1.1 mrg if (model <= 0x77) 288 1.1 mrg { 289 1.1 mrg cpu = "znver5"; 290 1.1 mrg CHECK___builtin_cpu_is ("znver5"); 291 1.1 mrg cpu_model->__cpu_subtype = AMDFAM1AH_ZNVER5; 292 1.1 mrg } 293 1.1 mrg else if (has_cpu_feature (cpu_model, cpu_features2, 294 1.1 mrg FEATURE_AVX512VP2INTERSECT)) 295 1.1 mrg { 296 1.1 mrg cpu = "znver5"; 297 1.1 mrg CHECK___builtin_cpu_is ("znver5"); 298 1.1 mrg cpu_model->__cpu_subtype = AMDFAM1AH_ZNVER5; 299 1.1 mrg } 300 1.1 mrg break; 301 1.1 mrg default: 302 1.1 mrg break; 303 1.1 mrg } 304 1.1 mrg 305 1.1 mrg return cpu; 306 1.1 mrg } 307 1.1 mrg 308 1.1 mrg /* Get the specific type of Intel CPU and return Intel CPU name. Return 309 1.1 mrg NULL for unknown Intel CPU. */ 310 1.1 mrg 311 1.1 mrg static inline const char * 312 1.1 mrg get_intel_cpu (struct __processor_model *cpu_model, 313 1.1 mrg struct __processor_model2 *cpu_model2, 314 1.1 mrg unsigned int *cpu_features2) 315 1.1 mrg { 316 1.1 mrg const char *cpu = NULL; 317 1.1 mrg 318 1.1 mrg /* Parse family and model only for model 6. */ 319 1.1 mrg if (cpu_model2->__cpu_family != 0x6) 320 1.1 mrg return cpu; 321 1.1 mrg 322 1.1 mrg switch (cpu_model2->__cpu_model) 323 1.1 mrg { 324 1.1 mrg case 0x1c: 325 1.1 mrg case 0x26: 326 1.1 mrg /* Bonnell. */ 327 1.1 mrg cpu = "bonnell"; 328 1.1 mrg CHECK___builtin_cpu_is ("atom"); 329 1.1 mrg cpu_model->__cpu_type = INTEL_BONNELL; 330 1.1 mrg break; 331 1.1 mrg case 0x37: 332 1.1 mrg case 0x4a: 333 1.1 mrg case 0x4d: 334 1.1 mrg case 0x5d: 335 1.1 mrg /* Silvermont. */ 336 1.1 mrg case 0x4c: 337 1.1 mrg case 0x5a: 338 1.1 mrg case 0x75: 339 1.1 mrg /* Airmont. */ 340 1.1 mrg cpu = "silvermont"; 341 1.1 mrg CHECK___builtin_cpu_is ("silvermont"); 342 1.1 mrg cpu_model->__cpu_type = INTEL_SILVERMONT; 343 1.1 mrg break; 344 1.1 mrg case 0x5c: 345 1.1 mrg case 0x5f: 346 1.1 mrg /* Goldmont. */ 347 1.1 mrg cpu = "goldmont"; 348 1.1 mrg CHECK___builtin_cpu_is ("goldmont"); 349 1.1 mrg cpu_model->__cpu_type = INTEL_GOLDMONT; 350 1.1 mrg break; 351 1.1 mrg case 0x7a: 352 1.1 mrg /* Goldmont Plus. */ 353 1.1 mrg cpu = "goldmont-plus"; 354 1.1 mrg CHECK___builtin_cpu_is ("goldmont-plus"); 355 1.1 mrg cpu_model->__cpu_type = INTEL_GOLDMONT_PLUS; 356 1.1 mrg break; 357 1.1 mrg case 0x86: 358 1.1 mrg case 0x96: 359 1.1 mrg case 0x9c: 360 1.1 mrg /* Tremont. */ 361 1.1 mrg cpu = "tremont"; 362 1.1 mrg CHECK___builtin_cpu_is ("tremont"); 363 1.1 mrg cpu_model->__cpu_type = INTEL_TREMONT; 364 1.1 mrg break; 365 1.1 mrg case 0x57: 366 1.1 mrg /* Knights Landing. */ 367 1.1 mrg cpu = "knl"; 368 1.1 mrg CHECK___builtin_cpu_is ("knl"); 369 1.1 mrg cpu_model->__cpu_type = INTEL_KNL; 370 1.1 mrg break; 371 1.1 mrg case 0x85: 372 1.1 mrg /* Knights Mill. */ 373 1.1 mrg cpu = "knm"; 374 1.1 mrg CHECK___builtin_cpu_is ("knm"); 375 1.1 mrg cpu_model->__cpu_type = INTEL_KNM; 376 1.1 mrg break; 377 1.1 mrg case 0x1a: 378 1.1 mrg case 0x1e: 379 1.1 mrg case 0x1f: 380 1.1 mrg case 0x2e: 381 1.1 mrg /* Nehalem. */ 382 1.1 mrg cpu = "nehalem"; 383 1.1 mrg CHECK___builtin_cpu_is ("corei7"); 384 1.1 mrg CHECK___builtin_cpu_is ("nehalem"); 385 1.1 mrg cpu_model->__cpu_type = INTEL_COREI7; 386 1.1 mrg cpu_model->__cpu_subtype = INTEL_COREI7_NEHALEM; 387 1.1 mrg break; 388 1.1 mrg case 0x25: 389 1.1 mrg case 0x2c: 390 1.1 mrg case 0x2f: 391 1.1 mrg /* Westmere. */ 392 1.1 mrg cpu = "westmere"; 393 1.1 mrg CHECK___builtin_cpu_is ("corei7"); 394 1.1 mrg CHECK___builtin_cpu_is ("westmere"); 395 1.1 mrg cpu_model->__cpu_type = INTEL_COREI7; 396 1.1 mrg cpu_model->__cpu_subtype = INTEL_COREI7_WESTMERE; 397 1.1 mrg break; 398 1.1 mrg case 0x2a: 399 1.1 mrg case 0x2d: 400 1.1 mrg /* Sandy Bridge. */ 401 1.1 mrg cpu = "sandybridge"; 402 1.1 mrg CHECK___builtin_cpu_is ("corei7"); 403 1.1 mrg CHECK___builtin_cpu_is ("sandybridge"); 404 1.1 mrg cpu_model->__cpu_type = INTEL_COREI7; 405 1.1 mrg cpu_model->__cpu_subtype = INTEL_COREI7_SANDYBRIDGE; 406 1.1 mrg break; 407 1.1 mrg case 0x3a: 408 1.1 mrg case 0x3e: 409 1.1 mrg /* Ivy Bridge. */ 410 1.1 mrg cpu = "ivybridge"; 411 1.1 mrg CHECK___builtin_cpu_is ("corei7"); 412 1.1 mrg CHECK___builtin_cpu_is ("ivybridge"); 413 1.1 mrg cpu_model->__cpu_type = INTEL_COREI7; 414 1.1 mrg cpu_model->__cpu_subtype = INTEL_COREI7_IVYBRIDGE; 415 1.1 mrg break; 416 1.1 mrg case 0x3c: 417 1.1 mrg case 0x3f: 418 1.1 mrg case 0x45: 419 1.1 mrg case 0x46: 420 1.1 mrg /* Haswell. */ 421 1.1 mrg cpu = "haswell"; 422 1.1 mrg CHECK___builtin_cpu_is ("corei7"); 423 1.1 mrg CHECK___builtin_cpu_is ("haswell"); 424 1.1 mrg cpu_model->__cpu_type = INTEL_COREI7; 425 1.1 mrg cpu_model->__cpu_subtype = INTEL_COREI7_HASWELL; 426 1.1 mrg break; 427 1.1 mrg case 0x3d: 428 1.1 mrg case 0x47: 429 1.1 mrg case 0x4f: 430 1.1 mrg case 0x56: 431 1.1 mrg /* Broadwell. */ 432 1.1 mrg cpu = "broadwell"; 433 1.1 mrg CHECK___builtin_cpu_is ("corei7"); 434 1.1 mrg CHECK___builtin_cpu_is ("broadwell"); 435 1.1 mrg cpu_model->__cpu_type = INTEL_COREI7; 436 1.1 mrg cpu_model->__cpu_subtype = INTEL_COREI7_BROADWELL; 437 1.1 mrg break; 438 1.1 mrg case 0x4e: 439 1.1 mrg case 0x5e: 440 1.1 mrg /* Skylake. */ 441 1.1 mrg case 0x8e: 442 1.1 mrg case 0x9e: 443 1.1 mrg /* Kaby Lake. */ 444 1.1 mrg case 0xa5: 445 1.1 mrg case 0xa6: 446 1.1 mrg /* Comet Lake. */ 447 1.1 mrg cpu = "skylake"; 448 1.1 mrg CHECK___builtin_cpu_is ("corei7"); 449 1.1 mrg CHECK___builtin_cpu_is ("skylake"); 450 1.1 mrg cpu_model->__cpu_type = INTEL_COREI7; 451 1.1 mrg cpu_model->__cpu_subtype = INTEL_COREI7_SKYLAKE; 452 1.1 mrg break; 453 1.1 mrg case 0xa7: 454 1.1 mrg /* Rocket Lake. */ 455 1.1 mrg cpu = "rocketlake"; 456 1.1 mrg CHECK___builtin_cpu_is ("corei7"); 457 1.1 mrg CHECK___builtin_cpu_is ("rocketlake"); 458 1.1 mrg cpu_model->__cpu_type = INTEL_COREI7; 459 1.1 mrg cpu_model->__cpu_subtype = INTEL_COREI7_ROCKETLAKE; 460 1.1 mrg break; 461 1.1 mrg case 0x55: 462 1.1 mrg CHECK___builtin_cpu_is ("corei7"); 463 1.1 mrg cpu_model->__cpu_type = INTEL_COREI7; 464 1.1 mrg if (has_cpu_feature (cpu_model, cpu_features2, 465 1.1 mrg FEATURE_AVX512BF16)) 466 1.1 mrg { 467 1.1 mrg /* Cooper Lake. */ 468 1.1 mrg cpu = "cooperlake"; 469 1.1 mrg CHECK___builtin_cpu_is ("cooperlake"); 470 1.1 mrg cpu_model->__cpu_subtype = INTEL_COREI7_COOPERLAKE; 471 1.1 mrg } 472 1.1 mrg else if (has_cpu_feature (cpu_model, cpu_features2, 473 1.1 mrg FEATURE_AVX512VNNI)) 474 1.1 mrg { 475 1.1 mrg /* Cascade Lake. */ 476 1.1 mrg cpu = "cascadelake"; 477 1.1 mrg CHECK___builtin_cpu_is ("cascadelake"); 478 1.1 mrg cpu_model->__cpu_subtype = INTEL_COREI7_CASCADELAKE; 479 1.1 mrg } 480 1.1 mrg else 481 1.1 mrg { 482 1.1 mrg /* Skylake with AVX-512 support. */ 483 1.1 mrg cpu = "skylake-avx512"; 484 1.1 mrg CHECK___builtin_cpu_is ("skylake-avx512"); 485 1.1 mrg cpu_model->__cpu_subtype = INTEL_COREI7_SKYLAKE_AVX512; 486 1.1 mrg } 487 1.1 mrg break; 488 1.1 mrg case 0x66: 489 1.1 mrg /* Cannon Lake. */ 490 1.1 mrg cpu = "cannonlake"; 491 1.1 mrg CHECK___builtin_cpu_is ("corei7"); 492 1.1 mrg CHECK___builtin_cpu_is ("cannonlake"); 493 1.1 mrg cpu_model->__cpu_type = INTEL_COREI7; 494 1.1 mrg cpu_model->__cpu_subtype = INTEL_COREI7_CANNONLAKE; 495 1.1 mrg break; 496 1.1 mrg case 0x6a: 497 1.1 mrg case 0x6c: 498 1.1 mrg /* Ice Lake server. */ 499 1.1 mrg cpu = "icelake-server"; 500 1.1 mrg CHECK___builtin_cpu_is ("corei7"); 501 1.1 mrg CHECK___builtin_cpu_is ("icelake-server"); 502 1.1 mrg cpu_model->__cpu_type = INTEL_COREI7; 503 1.1 mrg cpu_model->__cpu_subtype = INTEL_COREI7_ICELAKE_SERVER; 504 1.1 mrg break; 505 1.1 mrg case 0x7e: 506 1.1 mrg case 0x7d: 507 1.1 mrg case 0x9d: 508 1.1 mrg /* Ice Lake client. */ 509 1.1 mrg cpu = "icelake-client"; 510 1.1 mrg CHECK___builtin_cpu_is ("corei7"); 511 1.1 mrg CHECK___builtin_cpu_is ("icelake-client"); 512 1.1 mrg cpu_model->__cpu_type = INTEL_COREI7; 513 1.1 mrg cpu_model->__cpu_subtype = INTEL_COREI7_ICELAKE_CLIENT; 514 1.1 mrg break; 515 1.1 mrg case 0x8c: 516 1.1 mrg case 0x8d: 517 1.1 mrg /* Tiger Lake. */ 518 1.1 mrg cpu = "tigerlake"; 519 1.1 mrg CHECK___builtin_cpu_is ("corei7"); 520 1.1 mrg CHECK___builtin_cpu_is ("tigerlake"); 521 1.1 mrg cpu_model->__cpu_type = INTEL_COREI7; 522 1.1 mrg cpu_model->__cpu_subtype = INTEL_COREI7_TIGERLAKE; 523 1.1 mrg break; 524 1.1 mrg case 0x97: 525 1.1 mrg case 0x9a: 526 1.1 mrg /* Alder Lake. */ 527 1.1 mrg cpu = "alderlake"; 528 1.1 mrg CHECK___builtin_cpu_is ("corei7"); 529 1.1 mrg CHECK___builtin_cpu_is ("alderlake"); 530 1.1 mrg cpu_model->__cpu_type = INTEL_COREI7; 531 1.1 mrg cpu_model->__cpu_subtype = INTEL_COREI7_ALDERLAKE; 532 1.1 mrg break; 533 1.1 mrg case 0x8f: 534 1.1 mrg /* Sapphire Rapids. */ 535 1.1 mrg cpu = "sapphirerapids"; 536 1.1 mrg CHECK___builtin_cpu_is ("corei7"); 537 1.1 mrg CHECK___builtin_cpu_is ("sapphirerapids"); 538 1.1 mrg cpu_model->__cpu_type = INTEL_COREI7; 539 1.1 mrg cpu_model->__cpu_subtype = INTEL_COREI7_SAPPHIRERAPIDS; 540 1.1 mrg break; 541 1.1 mrg case 0x17: 542 1.1 mrg case 0x1d: 543 1.1 mrg /* Penryn. */ 544 1.1 mrg case 0x0f: 545 1.1 mrg /* Merom. */ 546 1.1 mrg cpu = "core2"; 547 1.1 mrg CHECK___builtin_cpu_is ("core2"); 548 1.1 mrg cpu_model->__cpu_type = INTEL_CORE2; 549 1.1 mrg break; 550 1.1 mrg default: 551 1.1 mrg break; 552 1.1 mrg } 553 1.1 mrg 554 1.1 mrg return cpu; 555 1.1 mrg } 556 1.1 mrg 557 1.1 mrg /* ECX and EDX are output of CPUID at level one. */ 558 1.1 mrg static inline void 559 1.1 mrg get_available_features (struct __processor_model *cpu_model, 560 1.1 mrg struct __processor_model2 *cpu_model2, 561 1.1 mrg unsigned int *cpu_features2, 562 1.1 mrg unsigned int ecx, unsigned int edx) 563 1.1 mrg { 564 1.1 mrg unsigned int max_cpuid_level = cpu_model2->__cpu_max_level; 565 1.1 mrg unsigned int eax, ebx; 566 1.1 mrg unsigned int ext_level; 567 1.1 mrg 568 1.1 mrg /* Get XCR_XFEATURE_ENABLED_MASK register with xgetbv. */ 569 1.1 mrg #define XCR_XFEATURE_ENABLED_MASK 0x0 570 1.1 mrg #define XSTATE_FP 0x1 571 1.1 mrg #define XSTATE_SSE 0x2 572 1.1 mrg #define XSTATE_YMM 0x4 573 1.1 mrg #define XSTATE_OPMASK 0x20 574 1.1 mrg #define XSTATE_ZMM 0x40 575 1.1 mrg #define XSTATE_HI_ZMM 0x80 576 1.1 mrg #define XSTATE_TILECFG 0x20000 577 1.1 mrg #define XSTATE_TILEDATA 0x40000 578 1.1 mrg 579 1.1 mrg #define XCR_AVX_ENABLED_MASK \ 580 1.1 mrg (XSTATE_SSE | XSTATE_YMM) 581 1.1 mrg #define XCR_AVX512F_ENABLED_MASK \ 582 1.1 mrg (XSTATE_SSE | XSTATE_YMM | XSTATE_OPMASK | XSTATE_ZMM | XSTATE_HI_ZMM) 583 1.1 mrg #define XCR_AMX_ENABLED_MASK \ 584 1.1 mrg (XSTATE_TILECFG | XSTATE_TILEDATA) 585 1.1 mrg 586 1.1 mrg /* Check if AVX and AVX512 are usable. */ 587 1.1 mrg int avx_usable = 0; 588 1.1 mrg int avx512_usable = 0; 589 1.1 mrg int amx_usable = 0; 590 1.1 mrg /* Check if KL is usable. */ 591 1.1 mrg int has_kl = 0; 592 1.1 mrg if ((ecx & bit_OSXSAVE)) 593 1.1 mrg { 594 1.1 mrg /* Check if XMM, YMM, OPMASK, upper 256 bits of ZMM0-ZMM15 and 595 1.1 mrg ZMM16-ZMM31 states are supported by OSXSAVE. */ 596 1.1 mrg unsigned int xcrlow; 597 1.1 mrg unsigned int xcrhigh; 598 1.1 mrg __asm__ (".byte 0x0f, 0x01, 0xd0" 599 1.1 mrg : "=a" (xcrlow), "=d" (xcrhigh) 600 1.1 mrg : "c" (XCR_XFEATURE_ENABLED_MASK)); 601 1.1 mrg if ((xcrlow & XCR_AVX_ENABLED_MASK) == XCR_AVX_ENABLED_MASK) 602 1.1 mrg { 603 1.1 mrg avx_usable = 1; 604 1.1 mrg avx512_usable = ((xcrlow & XCR_AVX512F_ENABLED_MASK) 605 1.1 mrg == XCR_AVX512F_ENABLED_MASK); 606 1.1 mrg } 607 1.1 mrg amx_usable = ((xcrlow & XCR_AMX_ENABLED_MASK) 608 1.1 mrg == XCR_AMX_ENABLED_MASK); 609 1.1 mrg } 610 1.1 mrg 611 1.1 mrg #define set_feature(f) \ 612 1.1 mrg set_cpu_feature (cpu_model, cpu_features2, f) 613 1.1 mrg 614 1.1 mrg if (edx & bit_CMOV) 615 1.1 mrg set_feature (FEATURE_CMOV); 616 1.1 mrg if (edx & bit_MMX) 617 1.1 mrg set_feature (FEATURE_MMX); 618 1.1 mrg if (edx & bit_SSE) 619 1.1 mrg set_feature (FEATURE_SSE); 620 1.1 mrg if (edx & bit_SSE2) 621 1.1 mrg set_feature (FEATURE_SSE2); 622 1.1 mrg if (edx & bit_CMPXCHG8B) 623 1.1 mrg set_feature (FEATURE_CMPXCHG8B); 624 1.1 mrg if (edx & bit_FXSAVE) 625 1.1 mrg set_feature (FEATURE_FXSAVE); 626 1.1 mrg 627 1.1 mrg if (ecx & bit_POPCNT) 628 1.1 mrg set_feature (FEATURE_POPCNT); 629 1.1 mrg if (ecx & bit_AES) 630 1.1 mrg set_feature (FEATURE_AES); 631 1.1 mrg if (ecx & bit_PCLMUL) 632 1.1 mrg set_feature (FEATURE_PCLMUL); 633 1.1 mrg if (ecx & bit_SSE3) 634 1.1 mrg set_feature (FEATURE_SSE3); 635 1.1 mrg if (ecx & bit_SSSE3) 636 1.1 mrg set_feature (FEATURE_SSSE3); 637 1.1 mrg if (ecx & bit_SSE4_1) 638 1.1 mrg set_feature (FEATURE_SSE4_1); 639 1.1 mrg if (ecx & bit_SSE4_2) 640 1.1 mrg set_feature (FEATURE_SSE4_2); 641 1.1 mrg if (ecx & bit_OSXSAVE) 642 1.1 mrg set_feature (FEATURE_OSXSAVE); 643 1.1 mrg if (ecx & bit_CMPXCHG16B) 644 1.1 mrg set_feature (FEATURE_CMPXCHG16B); 645 1.1 mrg if (ecx & bit_MOVBE) 646 1.1 mrg set_feature (FEATURE_MOVBE); 647 1.1 mrg if (ecx & bit_AES) 648 1.1 mrg set_feature (FEATURE_AES); 649 1.1 mrg if (ecx & bit_RDRND) 650 1.1 mrg set_feature (FEATURE_RDRND); 651 1.1 mrg if (ecx & bit_XSAVE) 652 1.1 mrg set_feature (FEATURE_XSAVE); 653 1.1 mrg if (avx_usable) 654 1.1 mrg { 655 1.1 mrg if (ecx & bit_AVX) 656 1.1 mrg set_feature (FEATURE_AVX); 657 1.1 mrg if (ecx & bit_FMA) 658 1.1 mrg set_feature (FEATURE_FMA); 659 1.1 mrg if (ecx & bit_F16C) 660 1.1 mrg set_feature (FEATURE_F16C); 661 1.1 mrg } 662 1.1 mrg 663 1.1 mrg /* Get Advanced Features at level 7 (eax = 7, ecx = 0/1). */ 664 1.1 mrg if (max_cpuid_level >= 7) 665 1.1 mrg { 666 1.1 mrg unsigned int max_subleaf_level; 667 1.1 mrg 668 1.1 mrg __cpuid_count (7, 0, max_subleaf_level, ebx, ecx, edx); 669 1.1 mrg if (ebx & bit_BMI) 670 1.1 mrg set_feature (FEATURE_BMI); 671 1.1 mrg if (ebx & bit_SGX) 672 1.1 mrg set_feature (FEATURE_SGX); 673 1.1 mrg if (ebx & bit_HLE) 674 1.1 mrg set_feature (FEATURE_HLE); 675 1.1 mrg if (ebx & bit_RTM) 676 1.1 mrg set_feature (FEATURE_RTM); 677 1.1 mrg if (avx_usable) 678 1.1 mrg { 679 1.1 mrg if (ebx & bit_AVX2) 680 1.1 mrg set_feature (FEATURE_AVX2); 681 1.1 mrg if (ecx & bit_VPCLMULQDQ) 682 1.1 mrg set_feature (FEATURE_VPCLMULQDQ); 683 1.1 mrg if (ecx & bit_VAES) 684 1.1 mrg set_feature (FEATURE_VAES); 685 1.1 mrg } 686 1.1 mrg if (ebx & bit_BMI2) 687 1.1 mrg set_feature (FEATURE_BMI2); 688 1.1 mrg if (ebx & bit_FSGSBASE) 689 1.1 mrg set_feature (FEATURE_FSGSBASE); 690 1.1 mrg if (ebx & bit_RDSEED) 691 1.1 mrg set_feature (FEATURE_RDSEED); 692 1.1 mrg if (ebx & bit_ADX) 693 1.1 mrg set_feature (FEATURE_ADX); 694 1.1 mrg if (ebx & bit_SHA) 695 1.1 mrg set_feature (FEATURE_SHA); 696 1.1 mrg if (ebx & bit_CLFLUSHOPT) 697 1.1 mrg set_feature (FEATURE_CLFLUSHOPT); 698 1.1 mrg if (ebx & bit_CLWB) 699 1.1 mrg set_feature (FEATURE_CLWB); 700 1.1 mrg if (ecx & bit_PREFETCHWT1) 701 1.1 mrg set_feature (FEATURE_PREFETCHWT1); 702 1.1 mrg /* NB: bit_OSPKE indicates that OS supports PKU. */ 703 1.1 mrg if (ecx & bit_OSPKE) 704 1.1 mrg set_feature (FEATURE_PKU); 705 1.1 mrg if (ecx & bit_RDPID) 706 1.1 mrg set_feature (FEATURE_RDPID); 707 1.1 mrg if (ecx & bit_GFNI) 708 1.1 mrg set_feature (FEATURE_GFNI); 709 1.1 mrg if (ecx & bit_MOVDIRI) 710 1.1 mrg set_feature (FEATURE_MOVDIRI); 711 1.1 mrg if (ecx & bit_MOVDIR64B) 712 1.1 mrg set_feature (FEATURE_MOVDIR64B); 713 1.1 mrg if (ecx & bit_ENQCMD) 714 1.1 mrg set_feature (FEATURE_ENQCMD); 715 1.1 mrg if (ecx & bit_CLDEMOTE) 716 1.1 mrg set_feature (FEATURE_CLDEMOTE); 717 1.1 mrg if (ecx & bit_WAITPKG) 718 1.1 mrg set_feature (FEATURE_WAITPKG); 719 1.1 mrg if (ecx & bit_SHSTK) 720 1.1 mrg set_feature (FEATURE_SHSTK); 721 1.1 mrg if (ecx & bit_KL) 722 1.1 mrg has_kl = 1; 723 1.1 mrg if (edx & bit_SERIALIZE) 724 1.1 mrg set_feature (FEATURE_SERIALIZE); 725 1.1 mrg if (edx & bit_TSXLDTRK) 726 1.1 mrg set_feature (FEATURE_TSXLDTRK); 727 1.1 mrg if (edx & bit_PCONFIG) 728 1.1 mrg set_feature (FEATURE_PCONFIG); 729 1.1 mrg if (edx & bit_IBT) 730 1.1 mrg set_feature (FEATURE_IBT); 731 1.1 mrg if (edx & bit_UINTR) 732 1.1 mrg set_feature (FEATURE_UINTR); 733 1.1 mrg if (amx_usable) 734 1.1 mrg { 735 1.1 mrg if (edx & bit_AMX_TILE) 736 1.1 mrg set_feature (FEATURE_AMX_TILE); 737 1.1 mrg if (edx & bit_AMX_INT8) 738 1.1 mrg set_feature (FEATURE_AMX_INT8); 739 1.1 mrg if (edx & bit_AMX_BF16) 740 1.1 mrg set_feature (FEATURE_AMX_BF16); 741 1.1 mrg } 742 1.1 mrg if (avx512_usable) 743 1.1 mrg { 744 1.1 mrg if (ebx & bit_AVX512F) 745 1.1 mrg set_feature (FEATURE_AVX512F); 746 1.1 mrg if (ebx & bit_AVX512VL) 747 1.1 mrg set_feature (FEATURE_AVX512VL); 748 1.1 mrg if (ebx & bit_AVX512BW) 749 1.1 mrg set_feature (FEATURE_AVX512BW); 750 1.1 mrg if (ebx & bit_AVX512DQ) 751 1.1 mrg set_feature (FEATURE_AVX512DQ); 752 1.1 mrg if (ebx & bit_AVX512CD) 753 1.1 mrg set_feature (FEATURE_AVX512CD); 754 1.1 mrg if (ebx & bit_AVX512PF) 755 1.1 mrg set_feature (FEATURE_AVX512PF); 756 1.1 mrg if (ebx & bit_AVX512ER) 757 1.1 mrg set_feature (FEATURE_AVX512ER); 758 1.1 mrg if (ebx & bit_AVX512IFMA) 759 1.1 mrg set_feature (FEATURE_AVX512IFMA); 760 1.1 mrg if (ecx & bit_AVX512VBMI) 761 1.1 mrg set_feature (FEATURE_AVX512VBMI); 762 1.1 mrg if (ecx & bit_AVX512VBMI2) 763 1.1 mrg set_feature (FEATURE_AVX512VBMI2); 764 1.1 mrg if (ecx & bit_AVX512VNNI) 765 1.1 mrg set_feature (FEATURE_AVX512VNNI); 766 1.1 mrg if (ecx & bit_AVX512BITALG) 767 1.1 mrg set_feature (FEATURE_AVX512BITALG); 768 1.1 mrg if (ecx & bit_AVX512VPOPCNTDQ) 769 1.1 mrg set_feature (FEATURE_AVX512VPOPCNTDQ); 770 1.1 mrg if (edx & bit_AVX5124VNNIW) 771 1.1 mrg set_feature (FEATURE_AVX5124VNNIW); 772 1.1 mrg if (edx & bit_AVX5124FMAPS) 773 1.1 mrg set_feature (FEATURE_AVX5124FMAPS); 774 1.1 mrg if (edx & bit_AVX512VP2INTERSECT) 775 1.1 mrg set_feature (FEATURE_AVX512VP2INTERSECT); 776 1.1 mrg if (edx & bit_AVX512FP16) 777 1.1 mrg set_feature (FEATURE_AVX512FP16); 778 1.1 mrg } 779 1.1 mrg 780 1.1 mrg if (max_subleaf_level >= 1) 781 1.1 mrg { 782 1.1 mrg __cpuid_count (7, 1, eax, ebx, ecx, edx); 783 1.1 mrg if (eax & bit_HRESET) 784 1.1 mrg set_feature (FEATURE_HRESET); 785 1.1 mrg if (avx_usable) 786 1.1 mrg { 787 1.1 mrg if (eax & bit_AVXVNNI) 788 1.1 mrg set_feature (FEATURE_AVXVNNI); 789 1.1 mrg } 790 1.1 mrg if (avx512_usable) 791 1.1 mrg { 792 1.1 mrg if (eax & bit_AVX512BF16) 793 1.1 mrg set_feature (FEATURE_AVX512BF16); 794 1.1 mrg } 795 1.1 mrg } 796 1.1 mrg } 797 1.1 mrg 798 1.1 mrg /* Get Advanced Features at level 0xd (eax = 0xd, ecx = 1). */ 799 1.1 mrg if (max_cpuid_level >= 0xd) 800 1.1 mrg { 801 1.1 mrg __cpuid_count (0xd, 1, eax, ebx, ecx, edx); 802 1.1 mrg if (eax & bit_XSAVEOPT) 803 1.1 mrg set_feature (FEATURE_XSAVEOPT); 804 1.1 mrg if (eax & bit_XSAVEC) 805 1.1 mrg set_feature (FEATURE_XSAVEC); 806 1.1 mrg if (eax & bit_XSAVES) 807 1.1 mrg set_feature (FEATURE_XSAVES); 808 1.1 mrg } 809 1.1 mrg 810 1.1 mrg /* Get Advanced Features at level 0x14 (eax = 0x14, ecx = 0). */ 811 1.1 mrg if (max_cpuid_level >= 0x14) 812 1.1 mrg { 813 1.1 mrg __cpuid_count (0x14, 0, eax, ebx, ecx, edx); 814 1.1 mrg if (ebx & bit_PTWRITE) 815 1.1 mrg set_feature (FEATURE_PTWRITE); 816 1.1 mrg } 817 1.1 mrg 818 1.1 mrg /* Get Advanced Features at level 0x19 (eax = 0x19). */ 819 1.1 mrg if (max_cpuid_level >= 0x19) 820 1.1 mrg { 821 1.1 mrg __cpuid (0x19, eax, ebx, ecx, edx); 822 1.1 mrg /* Check if OS support keylocker. */ 823 1.1 mrg if (ebx & bit_AESKLE) 824 1.1 mrg { 825 1.1 mrg set_feature (FEATURE_AESKLE); 826 1.1 mrg if (ebx & bit_WIDEKL) 827 1.1 mrg set_feature (FEATURE_WIDEKL); 828 1.1 mrg if (has_kl) 829 1.1 mrg set_feature (FEATURE_KL); 830 1.1 mrg } 831 1.1 mrg } 832 1.1 mrg 833 1.1 mrg /* Check cpuid level of extended features. */ 834 1.1 mrg __cpuid (0x80000000, ext_level, ebx, ecx, edx); 835 1.1 mrg 836 1.1 mrg cpu_model2->__cpu_ext_level = ext_level; 837 1.1 mrg 838 1.1 mrg if (ext_level >= 0x80000001) 839 1.1 mrg { 840 1.1 mrg __cpuid (0x80000001, eax, ebx, ecx, edx); 841 1.1 mrg 842 1.1 mrg if (ecx & bit_SSE4a) 843 1.1 mrg set_feature (FEATURE_SSE4_A); 844 1.1 mrg if (ecx & bit_LAHF_LM) 845 1.1 mrg set_feature (FEATURE_LAHF_LM); 846 1.1 mrg if (ecx & bit_ABM) 847 1.1 mrg set_feature (FEATURE_ABM); 848 1.1 mrg if (ecx & bit_LWP) 849 1.1 mrg set_feature (FEATURE_LWP); 850 1.1 mrg if (ecx & bit_TBM) 851 1.1 mrg set_feature (FEATURE_TBM); 852 1.1 mrg if (ecx & bit_LZCNT) 853 1.1 mrg set_feature (FEATURE_LZCNT); 854 1.1 mrg if (ecx & bit_PRFCHW) 855 1.1 mrg set_feature (FEATURE_PRFCHW); 856 1.1 mrg if (ecx & bit_MWAITX) 857 1.1 mrg set_feature (FEATURE_MWAITX); 858 1.1 mrg 859 1.1 mrg if (edx & bit_LM) 860 1.1 mrg set_feature (FEATURE_LM); 861 1.1 mrg if (edx & bit_3DNOWP) 862 1.1 mrg set_feature (FEATURE_3DNOWP); 863 1.1 mrg if (edx & bit_3DNOW) 864 1.1 mrg set_feature (FEATURE_3DNOW); 865 1.1 mrg 866 1.1 mrg if (avx_usable) 867 1.1 mrg { 868 1.1 mrg if (ecx & bit_FMA4) 869 1.1 mrg set_feature (FEATURE_FMA4); 870 1.1 mrg if (ecx & bit_XOP) 871 1.1 mrg set_feature (FEATURE_XOP); 872 1.1 mrg } 873 1.1 mrg } 874 1.1 mrg 875 1.1 mrg if (ext_level >= 0x80000008) 876 1.1 mrg { 877 1.1 mrg __cpuid (0x80000008, eax, ebx, ecx, edx); 878 1.1 mrg if (ebx & bit_CLZERO) 879 1.1 mrg set_feature (FEATURE_CLZERO); 880 1.1 mrg if (ebx & bit_WBNOINVD) 881 1.1 mrg set_feature (FEATURE_WBNOINVD); 882 1.1 mrg } 883 1.1 mrg 884 1.1 mrg #undef set_feature 885 1.1 mrg } 886 1.1 mrg 887 1.1 mrg static inline int 888 1.1 mrg cpu_indicator_init (struct __processor_model *cpu_model, 889 1.1 mrg struct __processor_model2 *cpu_model2, 890 1.1 mrg unsigned int *cpu_features2) 891 1.1 mrg { 892 1.1 mrg unsigned int eax, ebx, ecx, edx; 893 1.1 mrg 894 1.1 mrg int max_level; 895 1.1 mrg unsigned int vendor; 896 1.1 mrg unsigned int model, family; 897 1.1 mrg unsigned int extended_model, extended_family; 898 1.1 mrg 899 1.1 mrg /* This function needs to run just once. */ 900 1.1 mrg if (cpu_model->__cpu_vendor) 901 1.1 mrg return 0; 902 1.1 mrg 903 1.1 mrg /* Assume cpuid insn present. Run in level 0 to get vendor id. */ 904 1.1 mrg if (!__get_cpuid (0, &eax, &ebx, &ecx, &edx)) 905 1.1 mrg { 906 1.1 mrg cpu_model->__cpu_vendor = VENDOR_OTHER; 907 1.1 mrg return -1; 908 1.1 mrg } 909 1.1 mrg 910 1.1 mrg vendor = ebx; 911 1.1 mrg max_level = eax; 912 1.1 mrg 913 1.1 mrg if (max_level < 1) 914 1.1 mrg { 915 1.1 mrg cpu_model->__cpu_vendor = VENDOR_OTHER; 916 1.1 mrg return -1; 917 1.1 mrg } 918 1.1 mrg 919 1.1 mrg if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx)) 920 1.1 mrg { 921 1.1 mrg cpu_model->__cpu_vendor = VENDOR_OTHER; 922 1.1 mrg return -1; 923 1.1 mrg } 924 1.1 mrg 925 1.1 mrg cpu_model2->__cpu_max_level = max_level; 926 1.1 mrg 927 1.1 mrg model = (eax >> 4) & 0x0f; 928 1.1 mrg family = (eax >> 8) & 0x0f; 929 1.1 mrg extended_model = (eax >> 12) & 0xf0; 930 1.1 mrg extended_family = (eax >> 20) & 0xff; 931 1.1 mrg 932 1.1 mrg /* Find available features. */ 933 1.1 mrg get_available_features (cpu_model, cpu_model2, cpu_features2, 934 1.1 mrg ecx, edx); 935 1.1 mrg 936 1.1 mrg if (vendor == signature_INTEL_ebx) 937 1.1 mrg { 938 1.1 mrg /* Adjust model and family for Intel CPUS. */ 939 1.1 mrg if (family == 0x0f) 940 1.1 mrg { 941 1.1 mrg family += extended_family; 942 1.1 mrg model += extended_model; 943 1.1 mrg } 944 1.1 mrg else if (family == 0x06) 945 1.1 mrg model += extended_model; 946 1.1 mrg 947 1.1 mrg cpu_model2->__cpu_family = family; 948 1.1 mrg cpu_model2->__cpu_model = model; 949 1.1 mrg 950 1.1 mrg /* Get CPU type. */ 951 1.1 mrg get_intel_cpu (cpu_model, cpu_model2, cpu_features2); 952 1.1 mrg cpu_model->__cpu_vendor = VENDOR_INTEL; 953 1.1 mrg } 954 1.1 mrg else if (vendor == signature_AMD_ebx) 955 1.1 mrg { 956 1.1 mrg /* Adjust model and family for AMD CPUS. */ 957 1.1 mrg if (family == 0x0f) 958 1.1 mrg { 959 1.1 mrg family += extended_family; 960 1.1 mrg model += extended_model; 961 1.1 mrg } 962 1.1 mrg 963 1.1 mrg cpu_model2->__cpu_family = family; 964 1.1 mrg cpu_model2->__cpu_model = model; 965 1.1 mrg 966 1.1 mrg /* Get CPU type. */ 967 1.1 mrg get_amd_cpu (cpu_model, cpu_model2, cpu_features2); 968 1.1 mrg cpu_model->__cpu_vendor = VENDOR_AMD; 969 1.1 mrg } 970 1.1 mrg else if (vendor == signature_CENTAUR_ebx) 971 1.1 mrg cpu_model->__cpu_vendor = VENDOR_CENTAUR; 972 1.1 mrg else if (vendor == signature_CYRIX_ebx) 973 1.1 mrg cpu_model->__cpu_vendor = VENDOR_CYRIX; 974 1.1 mrg else if (vendor == signature_NSC_ebx) 975 1.1 mrg cpu_model->__cpu_vendor = VENDOR_NSC; 976 1.1 mrg else 977 1.1 mrg cpu_model->__cpu_vendor = VENDOR_OTHER; 978 1.1 mrg 979 1.1 mrg if (has_cpu_feature (cpu_model, cpu_features2, FEATURE_LM) 980 1.1 mrg && has_cpu_feature (cpu_model, cpu_features2, FEATURE_SSE2)) 981 1.1 mrg { 982 1.1 mrg CHECK___builtin_cpu_supports ("x86-64"); 983 1.1 mrg set_cpu_feature (cpu_model, cpu_features2, 984 1.1 mrg FEATURE_X86_64_BASELINE); 985 1.1 mrg if (has_cpu_feature (cpu_model, cpu_features2, FEATURE_CMPXCHG16B) 986 1.1 mrg && has_cpu_feature (cpu_model, cpu_features2, FEATURE_POPCNT) 987 1.1 mrg && has_cpu_feature (cpu_model, cpu_features2, FEATURE_LAHF_LM) 988 1.1 mrg && has_cpu_feature (cpu_model, cpu_features2, FEATURE_SSE4_2)) 989 1.1 mrg { 990 1.1 mrg CHECK___builtin_cpu_supports ("x86-64-v2"); 991 1.1 mrg set_cpu_feature (cpu_model, cpu_features2, 992 1.1 mrg FEATURE_X86_64_V2); 993 1.1 mrg if (has_cpu_feature (cpu_model, cpu_features2, FEATURE_AVX2) 994 1.1 mrg && has_cpu_feature (cpu_model, cpu_features2, FEATURE_BMI) 995 1.1 mrg && has_cpu_feature (cpu_model, cpu_features2, FEATURE_BMI2) 996 1.1 mrg && has_cpu_feature (cpu_model, cpu_features2, FEATURE_F16C) 997 1.1 mrg && has_cpu_feature (cpu_model, cpu_features2, FEATURE_FMA) 998 1.1 mrg && has_cpu_feature (cpu_model, cpu_features2, 999 1.1 mrg FEATURE_LZCNT) 1000 1.1 mrg && has_cpu_feature (cpu_model, cpu_features2, 1001 1.1 mrg FEATURE_MOVBE)) 1002 1.1 mrg { 1003 1.1 mrg CHECK___builtin_cpu_supports ("x86-64-v3"); 1004 1.1 mrg set_cpu_feature (cpu_model, cpu_features2, 1005 1.1 mrg FEATURE_X86_64_V3); 1006 1.1 mrg if (has_cpu_feature (cpu_model, cpu_features2, 1007 1.1 mrg FEATURE_AVX512BW) 1008 1.1 mrg && has_cpu_feature (cpu_model, cpu_features2, 1009 1.1 mrg FEATURE_AVX512CD) 1010 1.1 mrg && has_cpu_feature (cpu_model, cpu_features2, 1011 1.1 mrg FEATURE_AVX512DQ) 1012 1.1 mrg && has_cpu_feature (cpu_model, cpu_features2, 1013 1.1 mrg FEATURE_AVX512VL)) 1014 1.1 mrg { 1015 1.1 mrg CHECK___builtin_cpu_supports ("x86-64-v4"); 1016 1.1 mrg set_cpu_feature (cpu_model, cpu_features2, 1017 1.1 mrg FEATURE_X86_64_V4); 1018 1.1 mrg } 1019 1.1 mrg } 1020 1.1 mrg } 1021 1.1 mrg } 1022 1.1 mrg 1023 1.1 mrg gcc_assert (cpu_model->__cpu_vendor < VENDOR_MAX); 1024 1.1 mrg gcc_assert (cpu_model->__cpu_type < CPU_TYPE_MAX); 1025 1.1 mrg gcc_assert (cpu_model->__cpu_subtype < CPU_SUBTYPE_MAX); 1026 1.1 mrg 1027 1.1 mrg return 0; 1028 1.1 mrg } 1029