1 //===-- Host.cpp - Implement OS Host Detection ------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements the operating system Host detection. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "llvm/TargetParser/Host.h" 14 #include "llvm/ADT/SmallVector.h" 15 #include "llvm/ADT/StringMap.h" 16 #include "llvm/ADT/StringRef.h" 17 #include "llvm/ADT/StringSwitch.h" 18 #include "llvm/Config/llvm-config.h" 19 #include "llvm/Support/MemoryBuffer.h" 20 #include "llvm/Support/raw_ostream.h" 21 #include "llvm/TargetParser/Triple.h" 22 #include "llvm/TargetParser/X86TargetParser.h" 23 #include <string.h> 24 25 // Include the platform-specific parts of this class. 26 #ifdef LLVM_ON_UNIX 27 #include "Unix/Host.inc" 28 #include <sched.h> 29 #endif 30 #ifdef _WIN32 31 #include "Windows/Host.inc" 32 #endif 33 #ifdef _MSC_VER 34 #include <intrin.h> 35 #endif 36 #ifdef __MVS__ 37 #include "llvm/Support/BCD.h" 38 #endif 39 #if defined(__APPLE__) 40 #include <mach/host_info.h> 41 #include <mach/mach.h> 42 #include <mach/mach_host.h> 43 #include <mach/machine.h> 44 #include <sys/param.h> 45 #include <sys/sysctl.h> 46 #endif 47 #ifdef _AIX 48 #include <sys/systemcfg.h> 49 #endif 50 #if defined(__sun__) && defined(__svr4__) 51 #include <kstat.h> 52 #endif 53 #if defined(__GNUC__) || defined(__clang__) 54 #if (defined(__i386__) || defined(__x86_64__)) && !defined(_MSC_VER) 55 #include <cpuid.h> 56 #endif 57 #endif 58 59 #define DEBUG_TYPE "host-detection" 60 61 //===----------------------------------------------------------------------===// 62 // 63 // Implementations of the CPU detection routines 64 // 65 //===----------------------------------------------------------------------===// 66 67 using namespace llvm; 68 69 static std::unique_ptr<llvm::MemoryBuffer> 70 LLVM_ATTRIBUTE_UNUSED getProcCpuinfoContent() { 71 const char *CPUInfoFile = "/proc/cpuinfo"; 72 if (const char *CpuinfoIntercept = std::getenv("LLVM_CPUINFO")) 73 CPUInfoFile = CpuinfoIntercept; 74 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text = 75 llvm::MemoryBuffer::getFileAsStream(CPUInfoFile); 76 77 if (std::error_code EC = Text.getError()) { 78 llvm::errs() << "Can't read " << CPUInfoFile << ": " << EC.message() 79 << "\n"; 80 return nullptr; 81 } 82 return std::move(*Text); 83 } 84 85 StringRef sys::detail::getHostCPUNameForPowerPC(StringRef ProcCpuinfoContent) { 86 // Access to the Processor Version Register (PVR) on PowerPC is privileged, 87 // and so we must use an operating-system interface to determine the current 88 // processor type. On Linux, this is exposed through the /proc/cpuinfo file. 89 const char *generic = "generic"; 90 91 // The cpu line is second (after the 'processor: 0' line), so if this 92 // buffer is too small then something has changed (or is wrong). 93 StringRef::const_iterator CPUInfoStart = ProcCpuinfoContent.begin(); 94 StringRef::const_iterator CPUInfoEnd = ProcCpuinfoContent.end(); 95 96 StringRef::const_iterator CIP = CPUInfoStart; 97 98 StringRef::const_iterator CPUStart = nullptr; 99 size_t CPULen = 0; 100 101 // We need to find the first line which starts with cpu, spaces, and a colon. 102 // After the colon, there may be some additional spaces and then the cpu type. 103 while (CIP < CPUInfoEnd && CPUStart == nullptr) { 104 if (CIP < CPUInfoEnd && *CIP == '\n') 105 ++CIP; 106 107 if (CIP < CPUInfoEnd && *CIP == 'c') { 108 ++CIP; 109 if (CIP < CPUInfoEnd && *CIP == 'p') { 110 ++CIP; 111 if (CIP < CPUInfoEnd && *CIP == 'u') { 112 ++CIP; 113 while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t')) 114 ++CIP; 115 116 if (CIP < CPUInfoEnd && *CIP == ':') { 117 ++CIP; 118 while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t')) 119 ++CIP; 120 121 if (CIP < CPUInfoEnd) { 122 CPUStart = CIP; 123 while (CIP < CPUInfoEnd && (*CIP != ' ' && *CIP != '\t' && 124 *CIP != ',' && *CIP != '\n')) 125 ++CIP; 126 CPULen = CIP - CPUStart; 127 } 128 } 129 } 130 } 131 } 132 133 if (CPUStart == nullptr) 134 while (CIP < CPUInfoEnd && *CIP != '\n') 135 ++CIP; 136 } 137 138 if (CPUStart == nullptr) 139 return generic; 140 141 return StringSwitch<const char *>(StringRef(CPUStart, CPULen)) 142 .Case("604e", "604e") 143 .Case("604", "604") 144 .Case("7400", "7400") 145 .Case("7410", "7400") 146 .Case("7447", "7400") 147 .Case("7455", "7450") 148 .Case("G4", "g4") 149 .Case("POWER4", "970") 150 .Case("PPC970FX", "970") 151 .Case("PPC970MP", "970") 152 .Case("G5", "g5") 153 .Case("POWER5", "g5") 154 .Case("A2", "a2") 155 .Case("POWER6", "pwr6") 156 .Case("POWER7", "pwr7") 157 .Case("POWER8", "pwr8") 158 .Case("POWER8E", "pwr8") 159 .Case("POWER8NVL", "pwr8") 160 .Case("POWER9", "pwr9") 161 .Case("POWER10", "pwr10") 162 .Case("POWER11", "pwr11") 163 // FIXME: If we get a simulator or machine with the capabilities of 164 // mcpu=future, we should revisit this and add the name reported by the 165 // simulator/machine. 166 .Default(generic); 167 } 168 169 StringRef sys::detail::getHostCPUNameForARM(StringRef ProcCpuinfoContent) { 170 // The cpuid register on arm is not accessible from user space. On Linux, 171 // it is exposed through the /proc/cpuinfo file. 172 173 // Read 32 lines from /proc/cpuinfo, which should contain the CPU part line 174 // in all cases. 175 SmallVector<StringRef, 32> Lines; 176 ProcCpuinfoContent.split(Lines, '\n'); 177 178 // Look for the CPU implementer line. 179 StringRef Implementer; 180 StringRef Hardware; 181 StringRef Part; 182 for (unsigned I = 0, E = Lines.size(); I != E; ++I) { 183 if (Lines[I].starts_with("CPU implementer")) 184 Implementer = Lines[I].substr(15).ltrim("\t :"); 185 if (Lines[I].starts_with("Hardware")) 186 Hardware = Lines[I].substr(8).ltrim("\t :"); 187 if (Lines[I].starts_with("CPU part")) 188 Part = Lines[I].substr(8).ltrim("\t :"); 189 } 190 191 if (Implementer == "0x41") { // ARM Ltd. 192 // MSM8992/8994 may give cpu part for the core that the kernel is running on, 193 // which is undeterministic and wrong. Always return cortex-a53 for these SoC. 194 if (Hardware.ends_with("MSM8994") || Hardware.ends_with("MSM8996")) 195 return "cortex-a53"; 196 197 198 // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The 199 // values correspond to the "Part number" in the CP15/c0 register. The 200 // contents are specified in the various processor manuals. 201 // This corresponds to the Main ID Register in Technical Reference Manuals. 202 // and is used in programs like sys-utils 203 return StringSwitch<const char *>(Part) 204 .Case("0x926", "arm926ej-s") 205 .Case("0xb02", "mpcore") 206 .Case("0xb36", "arm1136j-s") 207 .Case("0xb56", "arm1156t2-s") 208 .Case("0xb76", "arm1176jz-s") 209 .Case("0xc05", "cortex-a5") 210 .Case("0xc07", "cortex-a7") 211 .Case("0xc08", "cortex-a8") 212 .Case("0xc09", "cortex-a9") 213 .Case("0xc0f", "cortex-a15") 214 .Case("0xc0e", "cortex-a17") 215 .Case("0xc20", "cortex-m0") 216 .Case("0xc23", "cortex-m3") 217 .Case("0xc24", "cortex-m4") 218 .Case("0xc27", "cortex-m7") 219 .Case("0xd20", "cortex-m23") 220 .Case("0xd21", "cortex-m33") 221 .Case("0xd24", "cortex-m52") 222 .Case("0xd22", "cortex-m55") 223 .Case("0xd23", "cortex-m85") 224 .Case("0xc18", "cortex-r8") 225 .Case("0xd13", "cortex-r52") 226 .Case("0xd16", "cortex-r52plus") 227 .Case("0xd15", "cortex-r82") 228 .Case("0xd14", "cortex-r82ae") 229 .Case("0xd02", "cortex-a34") 230 .Case("0xd04", "cortex-a35") 231 .Case("0xd03", "cortex-a53") 232 .Case("0xd05", "cortex-a55") 233 .Case("0xd46", "cortex-a510") 234 .Case("0xd80", "cortex-a520") 235 .Case("0xd88", "cortex-a520ae") 236 .Case("0xd07", "cortex-a57") 237 .Case("0xd06", "cortex-a65") 238 .Case("0xd43", "cortex-a65ae") 239 .Case("0xd08", "cortex-a72") 240 .Case("0xd09", "cortex-a73") 241 .Case("0xd0a", "cortex-a75") 242 .Case("0xd0b", "cortex-a76") 243 .Case("0xd0e", "cortex-a76ae") 244 .Case("0xd0d", "cortex-a77") 245 .Case("0xd41", "cortex-a78") 246 .Case("0xd42", "cortex-a78ae") 247 .Case("0xd4b", "cortex-a78c") 248 .Case("0xd47", "cortex-a710") 249 .Case("0xd4d", "cortex-a715") 250 .Case("0xd81", "cortex-a720") 251 .Case("0xd89", "cortex-a720ae") 252 .Case("0xd87", "cortex-a725") 253 .Case("0xd44", "cortex-x1") 254 .Case("0xd4c", "cortex-x1c") 255 .Case("0xd48", "cortex-x2") 256 .Case("0xd4e", "cortex-x3") 257 .Case("0xd82", "cortex-x4") 258 .Case("0xd85", "cortex-x925") 259 .Case("0xd4a", "neoverse-e1") 260 .Case("0xd0c", "neoverse-n1") 261 .Case("0xd49", "neoverse-n2") 262 .Case("0xd8e", "neoverse-n3") 263 .Case("0xd40", "neoverse-v1") 264 .Case("0xd4f", "neoverse-v2") 265 .Case("0xd84", "neoverse-v3") 266 .Case("0xd83", "neoverse-v3ae") 267 .Default("generic"); 268 } 269 270 if (Implementer == "0x42" || Implementer == "0x43") { // Broadcom | Cavium. 271 return StringSwitch<const char *>(Part) 272 .Case("0x516", "thunderx2t99") 273 .Case("0x0516", "thunderx2t99") 274 .Case("0xaf", "thunderx2t99") 275 .Case("0x0af", "thunderx2t99") 276 .Case("0xa1", "thunderxt88") 277 .Case("0x0a1", "thunderxt88") 278 .Default("generic"); 279 } 280 281 if (Implementer == "0x46") { // Fujitsu Ltd. 282 return StringSwitch<const char *>(Part) 283 .Case("0x001", "a64fx") 284 .Case("0x003", "fujitsu-monaka") 285 .Default("generic"); 286 } 287 288 if (Implementer == "0x4e") { // NVIDIA Corporation 289 return StringSwitch<const char *>(Part) 290 .Case("0x004", "carmel") 291 .Default("generic"); 292 } 293 294 if (Implementer == "0x48") // HiSilicon Technologies, Inc. 295 // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The 296 // values correspond to the "Part number" in the CP15/c0 register. The 297 // contents are specified in the various processor manuals. 298 return StringSwitch<const char *>(Part) 299 .Case("0xd01", "tsv110") 300 .Default("generic"); 301 302 if (Implementer == "0x51") // Qualcomm Technologies, Inc. 303 // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The 304 // values correspond to the "Part number" in the CP15/c0 register. The 305 // contents are specified in the various processor manuals. 306 return StringSwitch<const char *>(Part) 307 .Case("0x06f", "krait") // APQ8064 308 .Case("0x201", "kryo") 309 .Case("0x205", "kryo") 310 .Case("0x211", "kryo") 311 .Case("0x800", "cortex-a73") // Kryo 2xx Gold 312 .Case("0x801", "cortex-a73") // Kryo 2xx Silver 313 .Case("0x802", "cortex-a75") // Kryo 3xx Gold 314 .Case("0x803", "cortex-a75") // Kryo 3xx Silver 315 .Case("0x804", "cortex-a76") // Kryo 4xx Gold 316 .Case("0x805", "cortex-a76") // Kryo 4xx/5xx Silver 317 .Case("0xc00", "falkor") 318 .Case("0xc01", "saphira") 319 .Case("0x001", "oryon-1") 320 .Default("generic"); 321 if (Implementer == "0x53") { // Samsung Electronics Co., Ltd. 322 // The Exynos chips have a convoluted ID scheme that doesn't seem to follow 323 // any predictive pattern across variants and parts. 324 unsigned Variant = 0, Part = 0; 325 326 // Look for the CPU variant line, whose value is a 1 digit hexadecimal 327 // number, corresponding to the Variant bits in the CP15/C0 register. 328 for (auto I : Lines) 329 if (I.consume_front("CPU variant")) 330 I.ltrim("\t :").getAsInteger(0, Variant); 331 332 // Look for the CPU part line, whose value is a 3 digit hexadecimal 333 // number, corresponding to the PartNum bits in the CP15/C0 register. 334 for (auto I : Lines) 335 if (I.consume_front("CPU part")) 336 I.ltrim("\t :").getAsInteger(0, Part); 337 338 unsigned Exynos = (Variant << 12) | Part; 339 switch (Exynos) { 340 default: 341 // Default by falling through to Exynos M3. 342 [[fallthrough]]; 343 case 0x1002: 344 return "exynos-m3"; 345 case 0x1003: 346 return "exynos-m4"; 347 } 348 } 349 350 if (Implementer == "0x61") { // Apple 351 return StringSwitch<const char *>(Part) 352 .Case("0x020", "apple-m1") 353 .Case("0x021", "apple-m1") 354 .Case("0x022", "apple-m1") 355 .Case("0x023", "apple-m1") 356 .Case("0x024", "apple-m1") 357 .Case("0x025", "apple-m1") 358 .Case("0x028", "apple-m1") 359 .Case("0x029", "apple-m1") 360 .Case("0x030", "apple-m2") 361 .Case("0x031", "apple-m2") 362 .Case("0x032", "apple-m2") 363 .Case("0x033", "apple-m2") 364 .Case("0x034", "apple-m2") 365 .Case("0x035", "apple-m2") 366 .Case("0x038", "apple-m2") 367 .Case("0x039", "apple-m2") 368 .Case("0x049", "apple-m3") 369 .Case("0x048", "apple-m3") 370 .Default("generic"); 371 } 372 373 if (Implementer == "0x63") { // Arm China. 374 return StringSwitch<const char *>(Part) 375 .Case("0x132", "star-mc1") 376 .Default("generic"); 377 } 378 379 if (Implementer == "0x6d") { // Microsoft Corporation. 380 // The Microsoft Azure Cobalt 100 CPU is handled as a Neoverse N2. 381 return StringSwitch<const char *>(Part) 382 .Case("0xd49", "neoverse-n2") 383 .Default("generic"); 384 } 385 386 if (Implementer == "0xc0") { // Ampere Computing 387 return StringSwitch<const char *>(Part) 388 .Case("0xac3", "ampere1") 389 .Case("0xac4", "ampere1a") 390 .Case("0xac5", "ampere1b") 391 .Default("generic"); 392 } 393 394 return "generic"; 395 } 396 397 namespace { 398 StringRef getCPUNameFromS390Model(unsigned int Id, bool HaveVectorSupport) { 399 switch (Id) { 400 case 2064: // z900 not supported by LLVM 401 case 2066: 402 case 2084: // z990 not supported by LLVM 403 case 2086: 404 case 2094: // z9-109 not supported by LLVM 405 case 2096: 406 return "generic"; 407 case 2097: 408 case 2098: 409 return "z10"; 410 case 2817: 411 case 2818: 412 return "z196"; 413 case 2827: 414 case 2828: 415 return "zEC12"; 416 case 2964: 417 case 2965: 418 return HaveVectorSupport? "z13" : "zEC12"; 419 case 3906: 420 case 3907: 421 return HaveVectorSupport? "z14" : "zEC12"; 422 case 8561: 423 case 8562: 424 return HaveVectorSupport? "z15" : "zEC12"; 425 case 3931: 426 case 3932: 427 return HaveVectorSupport? "z16" : "zEC12"; 428 case 9175: 429 case 9176: 430 default: 431 return HaveVectorSupport? "arch15" : "zEC12"; 432 } 433 } 434 } // end anonymous namespace 435 436 StringRef sys::detail::getHostCPUNameForS390x(StringRef ProcCpuinfoContent) { 437 // STIDP is a privileged operation, so use /proc/cpuinfo instead. 438 439 // The "processor 0:" line comes after a fair amount of other information, 440 // including a cache breakdown, but this should be plenty. 441 SmallVector<StringRef, 32> Lines; 442 ProcCpuinfoContent.split(Lines, '\n'); 443 444 // Look for the CPU features. 445 SmallVector<StringRef, 32> CPUFeatures; 446 for (unsigned I = 0, E = Lines.size(); I != E; ++I) 447 if (Lines[I].starts_with("features")) { 448 size_t Pos = Lines[I].find(':'); 449 if (Pos != StringRef::npos) { 450 Lines[I].drop_front(Pos + 1).split(CPUFeatures, ' '); 451 break; 452 } 453 } 454 455 // We need to check for the presence of vector support independently of 456 // the machine type, since we may only use the vector register set when 457 // supported by the kernel (and hypervisor). 458 bool HaveVectorSupport = false; 459 for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) { 460 if (CPUFeatures[I] == "vx") 461 HaveVectorSupport = true; 462 } 463 464 // Now check the processor machine type. 465 for (unsigned I = 0, E = Lines.size(); I != E; ++I) { 466 if (Lines[I].starts_with("processor ")) { 467 size_t Pos = Lines[I].find("machine = "); 468 if (Pos != StringRef::npos) { 469 Pos += sizeof("machine = ") - 1; 470 unsigned int Id; 471 if (!Lines[I].drop_front(Pos).getAsInteger(10, Id)) 472 return getCPUNameFromS390Model(Id, HaveVectorSupport); 473 } 474 break; 475 } 476 } 477 478 return "generic"; 479 } 480 481 StringRef sys::detail::getHostCPUNameForRISCV(StringRef ProcCpuinfoContent) { 482 // There are 24 lines in /proc/cpuinfo 483 SmallVector<StringRef> Lines; 484 ProcCpuinfoContent.split(Lines, '\n'); 485 486 // Look for uarch line to determine cpu name 487 StringRef UArch; 488 for (unsigned I = 0, E = Lines.size(); I != E; ++I) { 489 if (Lines[I].starts_with("uarch")) { 490 UArch = Lines[I].substr(5).ltrim("\t :"); 491 break; 492 } 493 } 494 495 return StringSwitch<const char *>(UArch) 496 .Case("sifive,u74-mc", "sifive-u74") 497 .Case("sifive,bullet0", "sifive-u74") 498 .Default(""); 499 } 500 501 StringRef sys::detail::getHostCPUNameForBPF() { 502 #if !defined(__linux__) || !defined(__x86_64__) 503 return "generic"; 504 #else 505 uint8_t v3_insns[40] __attribute__ ((aligned (8))) = 506 /* BPF_MOV64_IMM(BPF_REG_0, 0) */ 507 { 0xb7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 508 /* BPF_MOV64_IMM(BPF_REG_2, 1) */ 509 0xb7, 0x2, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 510 /* BPF_JMP32_REG(BPF_JLT, BPF_REG_0, BPF_REG_2, 1) */ 511 0xae, 0x20, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 512 /* BPF_MOV64_IMM(BPF_REG_0, 1) */ 513 0xb7, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 514 /* BPF_EXIT_INSN() */ 515 0x95, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }; 516 517 uint8_t v2_insns[40] __attribute__ ((aligned (8))) = 518 /* BPF_MOV64_IMM(BPF_REG_0, 0) */ 519 { 0xb7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 520 /* BPF_MOV64_IMM(BPF_REG_2, 1) */ 521 0xb7, 0x2, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 522 /* BPF_JMP_REG(BPF_JLT, BPF_REG_0, BPF_REG_2, 1) */ 523 0xad, 0x20, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 524 /* BPF_MOV64_IMM(BPF_REG_0, 1) */ 525 0xb7, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 526 /* BPF_EXIT_INSN() */ 527 0x95, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }; 528 529 struct bpf_prog_load_attr { 530 uint32_t prog_type; 531 uint32_t insn_cnt; 532 uint64_t insns; 533 uint64_t license; 534 uint32_t log_level; 535 uint32_t log_size; 536 uint64_t log_buf; 537 uint32_t kern_version; 538 uint32_t prog_flags; 539 } attr = {}; 540 attr.prog_type = 1; /* BPF_PROG_TYPE_SOCKET_FILTER */ 541 attr.insn_cnt = 5; 542 attr.insns = (uint64_t)v3_insns; 543 attr.license = (uint64_t)"DUMMY"; 544 545 int fd = syscall(321 /* __NR_bpf */, 5 /* BPF_PROG_LOAD */, &attr, 546 sizeof(attr)); 547 if (fd >= 0) { 548 close(fd); 549 return "v3"; 550 } 551 552 /* Clear the whole attr in case its content changed by syscall. */ 553 memset(&attr, 0, sizeof(attr)); 554 attr.prog_type = 1; /* BPF_PROG_TYPE_SOCKET_FILTER */ 555 attr.insn_cnt = 5; 556 attr.insns = (uint64_t)v2_insns; 557 attr.license = (uint64_t)"DUMMY"; 558 fd = syscall(321 /* __NR_bpf */, 5 /* BPF_PROG_LOAD */, &attr, sizeof(attr)); 559 if (fd >= 0) { 560 close(fd); 561 return "v2"; 562 } 563 return "v1"; 564 #endif 565 } 566 567 #if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || \ 568 defined(_M_X64) 569 570 /// getX86CpuIDAndInfo - Execute the specified cpuid and return the 4 values in 571 /// the specified arguments. If we can't run cpuid on the host, return true. 572 static bool getX86CpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX, 573 unsigned *rECX, unsigned *rEDX) { 574 #if (defined(__i386__) || defined(__x86_64__)) && !defined(_MSC_VER) 575 return !__get_cpuid(value, rEAX, rEBX, rECX, rEDX); 576 #elif defined(_MSC_VER) 577 // The MSVC intrinsic is portable across x86 and x64. 578 int registers[4]; 579 __cpuid(registers, value); 580 *rEAX = registers[0]; 581 *rEBX = registers[1]; 582 *rECX = registers[2]; 583 *rEDX = registers[3]; 584 return false; 585 #else 586 return true; 587 #endif 588 } 589 590 namespace llvm { 591 namespace sys { 592 namespace detail { 593 namespace x86 { 594 595 VendorSignatures getVendorSignature(unsigned *MaxLeaf) { 596 unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0; 597 if (MaxLeaf == nullptr) 598 MaxLeaf = &EAX; 599 else 600 *MaxLeaf = 0; 601 602 if (getX86CpuIDAndInfo(0, MaxLeaf, &EBX, &ECX, &EDX) || *MaxLeaf < 1) 603 return VendorSignatures::UNKNOWN; 604 605 // "Genu ineI ntel" 606 if (EBX == 0x756e6547 && EDX == 0x49656e69 && ECX == 0x6c65746e) 607 return VendorSignatures::GENUINE_INTEL; 608 609 // "Auth enti cAMD" 610 if (EBX == 0x68747541 && EDX == 0x69746e65 && ECX == 0x444d4163) 611 return VendorSignatures::AUTHENTIC_AMD; 612 613 return VendorSignatures::UNKNOWN; 614 } 615 616 } // namespace x86 617 } // namespace detail 618 } // namespace sys 619 } // namespace llvm 620 621 using namespace llvm::sys::detail::x86; 622 623 /// getX86CpuIDAndInfoEx - Execute the specified cpuid with subleaf and return 624 /// the 4 values in the specified arguments. If we can't run cpuid on the host, 625 /// return true. 626 static bool getX86CpuIDAndInfoEx(unsigned value, unsigned subleaf, 627 unsigned *rEAX, unsigned *rEBX, unsigned *rECX, 628 unsigned *rEDX) { 629 // TODO(boomanaiden154): When the minimum toolchain versions for gcc and clang 630 // are such that __cpuidex is defined within cpuid.h for both, we can remove 631 // the __get_cpuid_count function and share the MSVC implementation between 632 // all three. 633 #if (defined(__i386__) || defined(__x86_64__)) && !defined(_MSC_VER) 634 return !__get_cpuid_count(value, subleaf, rEAX, rEBX, rECX, rEDX); 635 #elif defined(_MSC_VER) 636 int registers[4]; 637 __cpuidex(registers, value, subleaf); 638 *rEAX = registers[0]; 639 *rEBX = registers[1]; 640 *rECX = registers[2]; 641 *rEDX = registers[3]; 642 return false; 643 #else 644 return true; 645 #endif 646 } 647 648 // Read control register 0 (XCR0). Used to detect features such as AVX. 649 static bool getX86XCR0(unsigned *rEAX, unsigned *rEDX) { 650 // TODO(boomanaiden154): When the minimum toolchain versions for gcc and clang 651 // are such that _xgetbv is supported by both, we can unify the implementation 652 // with MSVC and remove all inline assembly. 653 #if defined(__GNUC__) || defined(__clang__) 654 // Check xgetbv; this uses a .byte sequence instead of the instruction 655 // directly because older assemblers do not include support for xgetbv and 656 // there is no easy way to conditionally compile based on the assembler used. 657 __asm__(".byte 0x0f, 0x01, 0xd0" : "=a"(*rEAX), "=d"(*rEDX) : "c"(0)); 658 return false; 659 #elif defined(_MSC_FULL_VER) && defined(_XCR_XFEATURE_ENABLED_MASK) 660 unsigned long long Result = _xgetbv(_XCR_XFEATURE_ENABLED_MASK); 661 *rEAX = Result; 662 *rEDX = Result >> 32; 663 return false; 664 #else 665 return true; 666 #endif 667 } 668 669 static void detectX86FamilyModel(unsigned EAX, unsigned *Family, 670 unsigned *Model) { 671 *Family = (EAX >> 8) & 0xf; // Bits 8 - 11 672 *Model = (EAX >> 4) & 0xf; // Bits 4 - 7 673 if (*Family == 6 || *Family == 0xf) { 674 if (*Family == 0xf) 675 // Examine extended family ID if family ID is F. 676 *Family += (EAX >> 20) & 0xff; // Bits 20 - 27 677 // Examine extended model ID if family ID is 6 or F. 678 *Model += ((EAX >> 16) & 0xf) << 4; // Bits 16 - 19 679 } 680 } 681 682 #define testFeature(F) (Features[F / 32] & (1 << (F % 32))) != 0 683 684 static StringRef getIntelProcessorTypeAndSubtype(unsigned Family, 685 unsigned Model, 686 const unsigned *Features, 687 unsigned *Type, 688 unsigned *Subtype) { 689 StringRef CPU; 690 691 switch (Family) { 692 case 3: 693 CPU = "i386"; 694 break; 695 case 4: 696 CPU = "i486"; 697 break; 698 case 5: 699 if (testFeature(X86::FEATURE_MMX)) { 700 CPU = "pentium-mmx"; 701 break; 702 } 703 CPU = "pentium"; 704 break; 705 case 6: 706 switch (Model) { 707 case 0x0f: // Intel Core 2 Duo processor, Intel Core 2 Duo mobile 708 // processor, Intel Core 2 Quad processor, Intel Core 2 Quad 709 // mobile processor, Intel Core 2 Extreme processor, Intel 710 // Pentium Dual-Core processor, Intel Xeon processor, model 711 // 0Fh. All processors are manufactured using the 65 nm process. 712 case 0x16: // Intel Celeron processor model 16h. All processors are 713 // manufactured using the 65 nm process 714 CPU = "core2"; 715 *Type = X86::INTEL_CORE2; 716 break; 717 case 0x17: // Intel Core 2 Extreme processor, Intel Xeon processor, model 718 // 17h. All processors are manufactured using the 45 nm process. 719 // 720 // 45nm: Penryn , Wolfdale, Yorkfield (XE) 721 case 0x1d: // Intel Xeon processor MP. All processors are manufactured using 722 // the 45 nm process. 723 CPU = "penryn"; 724 *Type = X86::INTEL_CORE2; 725 break; 726 case 0x1a: // Intel Core i7 processor and Intel Xeon processor. All 727 // processors are manufactured using the 45 nm process. 728 case 0x1e: // Intel(R) Core(TM) i7 CPU 870 @ 2.93GHz. 729 // As found in a Summer 2010 model iMac. 730 case 0x1f: 731 case 0x2e: // Nehalem EX 732 CPU = "nehalem"; 733 *Type = X86::INTEL_COREI7; 734 *Subtype = X86::INTEL_COREI7_NEHALEM; 735 break; 736 case 0x25: // Intel Core i7, laptop version. 737 case 0x2c: // Intel Core i7 processor and Intel Xeon processor. All 738 // processors are manufactured using the 32 nm process. 739 case 0x2f: // Westmere EX 740 CPU = "westmere"; 741 *Type = X86::INTEL_COREI7; 742 *Subtype = X86::INTEL_COREI7_WESTMERE; 743 break; 744 case 0x2a: // Intel Core i7 processor. All processors are manufactured 745 // using the 32 nm process. 746 case 0x2d: 747 CPU = "sandybridge"; 748 *Type = X86::INTEL_COREI7; 749 *Subtype = X86::INTEL_COREI7_SANDYBRIDGE; 750 break; 751 case 0x3a: 752 case 0x3e: // Ivy Bridge EP 753 CPU = "ivybridge"; 754 *Type = X86::INTEL_COREI7; 755 *Subtype = X86::INTEL_COREI7_IVYBRIDGE; 756 break; 757 758 // Haswell: 759 case 0x3c: 760 case 0x3f: 761 case 0x45: 762 case 0x46: 763 CPU = "haswell"; 764 *Type = X86::INTEL_COREI7; 765 *Subtype = X86::INTEL_COREI7_HASWELL; 766 break; 767 768 // Broadwell: 769 case 0x3d: 770 case 0x47: 771 case 0x4f: 772 case 0x56: 773 CPU = "broadwell"; 774 *Type = X86::INTEL_COREI7; 775 *Subtype = X86::INTEL_COREI7_BROADWELL; 776 break; 777 778 // Skylake: 779 case 0x4e: // Skylake mobile 780 case 0x5e: // Skylake desktop 781 case 0x8e: // Kaby Lake mobile 782 case 0x9e: // Kaby Lake desktop 783 case 0xa5: // Comet Lake-H/S 784 case 0xa6: // Comet Lake-U 785 CPU = "skylake"; 786 *Type = X86::INTEL_COREI7; 787 *Subtype = X86::INTEL_COREI7_SKYLAKE; 788 break; 789 790 // Rocketlake: 791 case 0xa7: 792 CPU = "rocketlake"; 793 *Type = X86::INTEL_COREI7; 794 *Subtype = X86::INTEL_COREI7_ROCKETLAKE; 795 break; 796 797 // Skylake Xeon: 798 case 0x55: 799 *Type = X86::INTEL_COREI7; 800 if (testFeature(X86::FEATURE_AVX512BF16)) { 801 CPU = "cooperlake"; 802 *Subtype = X86::INTEL_COREI7_COOPERLAKE; 803 } else if (testFeature(X86::FEATURE_AVX512VNNI)) { 804 CPU = "cascadelake"; 805 *Subtype = X86::INTEL_COREI7_CASCADELAKE; 806 } else { 807 CPU = "skylake-avx512"; 808 *Subtype = X86::INTEL_COREI7_SKYLAKE_AVX512; 809 } 810 break; 811 812 // Cannonlake: 813 case 0x66: 814 CPU = "cannonlake"; 815 *Type = X86::INTEL_COREI7; 816 *Subtype = X86::INTEL_COREI7_CANNONLAKE; 817 break; 818 819 // Icelake: 820 case 0x7d: 821 case 0x7e: 822 CPU = "icelake-client"; 823 *Type = X86::INTEL_COREI7; 824 *Subtype = X86::INTEL_COREI7_ICELAKE_CLIENT; 825 break; 826 827 // Tigerlake: 828 case 0x8c: 829 case 0x8d: 830 CPU = "tigerlake"; 831 *Type = X86::INTEL_COREI7; 832 *Subtype = X86::INTEL_COREI7_TIGERLAKE; 833 break; 834 835 // Alderlake: 836 case 0x97: 837 case 0x9a: 838 CPU = "alderlake"; 839 *Type = X86::INTEL_COREI7; 840 *Subtype = X86::INTEL_COREI7_ALDERLAKE; 841 break; 842 843 // Gracemont 844 case 0xbe: 845 CPU = "gracemont"; 846 *Type = X86::INTEL_COREI7; 847 *Subtype = X86::INTEL_COREI7_ALDERLAKE; 848 break; 849 850 // Raptorlake: 851 case 0xb7: 852 case 0xba: 853 case 0xbf: 854 CPU = "raptorlake"; 855 *Type = X86::INTEL_COREI7; 856 *Subtype = X86::INTEL_COREI7_ALDERLAKE; 857 break; 858 859 // Meteorlake: 860 case 0xaa: 861 case 0xac: 862 CPU = "meteorlake"; 863 *Type = X86::INTEL_COREI7; 864 *Subtype = X86::INTEL_COREI7_ALDERLAKE; 865 break; 866 867 // Arrowlake: 868 case 0xc5: 869 // Arrowlake U: 870 case 0xb5: 871 CPU = "arrowlake"; 872 *Type = X86::INTEL_COREI7; 873 *Subtype = X86::INTEL_COREI7_ARROWLAKE; 874 break; 875 876 // Arrowlake S: 877 case 0xc6: 878 CPU = "arrowlake-s"; 879 *Type = X86::INTEL_COREI7; 880 *Subtype = X86::INTEL_COREI7_ARROWLAKE_S; 881 break; 882 883 // Lunarlake: 884 case 0xbd: 885 CPU = "lunarlake"; 886 *Type = X86::INTEL_COREI7; 887 *Subtype = X86::INTEL_COREI7_ARROWLAKE_S; 888 break; 889 890 // Pantherlake: 891 case 0xcc: 892 CPU = "pantherlake"; 893 *Type = X86::INTEL_COREI7; 894 *Subtype = X86::INTEL_COREI7_PANTHERLAKE; 895 break; 896 897 // Graniterapids: 898 case 0xad: 899 CPU = "graniterapids"; 900 *Type = X86::INTEL_COREI7; 901 *Subtype = X86::INTEL_COREI7_GRANITERAPIDS; 902 break; 903 904 // Granite Rapids D: 905 case 0xae: 906 CPU = "graniterapids-d"; 907 *Type = X86::INTEL_COREI7; 908 *Subtype = X86::INTEL_COREI7_GRANITERAPIDS_D; 909 break; 910 911 // Icelake Xeon: 912 case 0x6a: 913 case 0x6c: 914 CPU = "icelake-server"; 915 *Type = X86::INTEL_COREI7; 916 *Subtype = X86::INTEL_COREI7_ICELAKE_SERVER; 917 break; 918 919 // Emerald Rapids: 920 case 0xcf: 921 CPU = "emeraldrapids"; 922 *Type = X86::INTEL_COREI7; 923 *Subtype = X86::INTEL_COREI7_SAPPHIRERAPIDS; 924 break; 925 926 // Sapphire Rapids: 927 case 0x8f: 928 CPU = "sapphirerapids"; 929 *Type = X86::INTEL_COREI7; 930 *Subtype = X86::INTEL_COREI7_SAPPHIRERAPIDS; 931 break; 932 933 case 0x1c: // Most 45 nm Intel Atom processors 934 case 0x26: // 45 nm Atom Lincroft 935 case 0x27: // 32 nm Atom Medfield 936 case 0x35: // 32 nm Atom Midview 937 case 0x36: // 32 nm Atom Midview 938 CPU = "bonnell"; 939 *Type = X86::INTEL_BONNELL; 940 break; 941 942 // Atom Silvermont codes from the Intel software optimization guide. 943 case 0x37: 944 case 0x4a: 945 case 0x4d: 946 case 0x5a: 947 case 0x5d: 948 case 0x4c: // really airmont 949 CPU = "silvermont"; 950 *Type = X86::INTEL_SILVERMONT; 951 break; 952 // Goldmont: 953 case 0x5c: // Apollo Lake 954 case 0x5f: // Denverton 955 CPU = "goldmont"; 956 *Type = X86::INTEL_GOLDMONT; 957 break; 958 case 0x7a: 959 CPU = "goldmont-plus"; 960 *Type = X86::INTEL_GOLDMONT_PLUS; 961 break; 962 case 0x86: 963 case 0x8a: // Lakefield 964 case 0x96: // Elkhart Lake 965 case 0x9c: // Jasper Lake 966 CPU = "tremont"; 967 *Type = X86::INTEL_TREMONT; 968 break; 969 970 // Sierraforest: 971 case 0xaf: 972 CPU = "sierraforest"; 973 *Type = X86::INTEL_SIERRAFOREST; 974 break; 975 976 // Grandridge: 977 case 0xb6: 978 CPU = "grandridge"; 979 *Type = X86::INTEL_GRANDRIDGE; 980 break; 981 982 // Clearwaterforest: 983 case 0xdd: 984 CPU = "clearwaterforest"; 985 *Type = X86::INTEL_CLEARWATERFOREST; 986 break; 987 988 // Xeon Phi (Knights Landing + Knights Mill): 989 case 0x57: 990 CPU = "knl"; 991 *Type = X86::INTEL_KNL; 992 break; 993 case 0x85: 994 CPU = "knm"; 995 *Type = X86::INTEL_KNM; 996 break; 997 998 default: // Unknown family 6 CPU, try to guess. 999 // Don't both with Type/Subtype here, they aren't used by the caller. 1000 // They're used above to keep the code in sync with compiler-rt. 1001 // TODO detect tigerlake host from model 1002 if (testFeature(X86::FEATURE_AVX512VP2INTERSECT)) { 1003 CPU = "tigerlake"; 1004 } else if (testFeature(X86::FEATURE_AVX512VBMI2)) { 1005 CPU = "icelake-client"; 1006 } else if (testFeature(X86::FEATURE_AVX512VBMI)) { 1007 CPU = "cannonlake"; 1008 } else if (testFeature(X86::FEATURE_AVX512BF16)) { 1009 CPU = "cooperlake"; 1010 } else if (testFeature(X86::FEATURE_AVX512VNNI)) { 1011 CPU = "cascadelake"; 1012 } else if (testFeature(X86::FEATURE_AVX512VL)) { 1013 CPU = "skylake-avx512"; 1014 } else if (testFeature(X86::FEATURE_CLFLUSHOPT)) { 1015 if (testFeature(X86::FEATURE_SHA)) 1016 CPU = "goldmont"; 1017 else 1018 CPU = "skylake"; 1019 } else if (testFeature(X86::FEATURE_ADX)) { 1020 CPU = "broadwell"; 1021 } else if (testFeature(X86::FEATURE_AVX2)) { 1022 CPU = "haswell"; 1023 } else if (testFeature(X86::FEATURE_AVX)) { 1024 CPU = "sandybridge"; 1025 } else if (testFeature(X86::FEATURE_SSE4_2)) { 1026 if (testFeature(X86::FEATURE_MOVBE)) 1027 CPU = "silvermont"; 1028 else 1029 CPU = "nehalem"; 1030 } else if (testFeature(X86::FEATURE_SSE4_1)) { 1031 CPU = "penryn"; 1032 } else if (testFeature(X86::FEATURE_SSSE3)) { 1033 if (testFeature(X86::FEATURE_MOVBE)) 1034 CPU = "bonnell"; 1035 else 1036 CPU = "core2"; 1037 } else if (testFeature(X86::FEATURE_64BIT)) { 1038 CPU = "core2"; 1039 } else if (testFeature(X86::FEATURE_SSE3)) { 1040 CPU = "yonah"; 1041 } else if (testFeature(X86::FEATURE_SSE2)) { 1042 CPU = "pentium-m"; 1043 } else if (testFeature(X86::FEATURE_SSE)) { 1044 CPU = "pentium3"; 1045 } else if (testFeature(X86::FEATURE_MMX)) { 1046 CPU = "pentium2"; 1047 } else { 1048 CPU = "pentiumpro"; 1049 } 1050 break; 1051 } 1052 break; 1053 case 15: { 1054 if (testFeature(X86::FEATURE_64BIT)) { 1055 CPU = "nocona"; 1056 break; 1057 } 1058 if (testFeature(X86::FEATURE_SSE3)) { 1059 CPU = "prescott"; 1060 break; 1061 } 1062 CPU = "pentium4"; 1063 break; 1064 } 1065 case 19: 1066 switch (Model) { 1067 // Diamond Rapids: 1068 case 0x01: 1069 CPU = "diamondrapids"; 1070 *Type = X86::INTEL_COREI7; 1071 *Subtype = X86::INTEL_COREI7_DIAMONDRAPIDS; 1072 break; 1073 1074 default: // Unknown family 19 CPU. 1075 break; 1076 } 1077 break; 1078 default: 1079 break; // Unknown. 1080 } 1081 1082 return CPU; 1083 } 1084 1085 static const char *getAMDProcessorTypeAndSubtype(unsigned Family, 1086 unsigned Model, 1087 const unsigned *Features, 1088 unsigned *Type, 1089 unsigned *Subtype) { 1090 const char *CPU = 0; 1091 1092 switch (Family) { 1093 case 4: 1094 CPU = "i486"; 1095 break; 1096 case 5: 1097 CPU = "pentium"; 1098 switch (Model) { 1099 case 6: 1100 case 7: 1101 CPU = "k6"; 1102 break; 1103 case 8: 1104 CPU = "k6-2"; 1105 break; 1106 case 9: 1107 case 13: 1108 CPU = "k6-3"; 1109 break; 1110 case 10: 1111 CPU = "geode"; 1112 break; 1113 } 1114 break; 1115 case 6: 1116 if (testFeature(X86::FEATURE_SSE)) { 1117 CPU = "athlon-xp"; 1118 break; 1119 } 1120 CPU = "athlon"; 1121 break; 1122 case 15: 1123 if (testFeature(X86::FEATURE_SSE3)) { 1124 CPU = "k8-sse3"; 1125 break; 1126 } 1127 CPU = "k8"; 1128 break; 1129 case 16: 1130 case 18: 1131 CPU = "amdfam10"; 1132 *Type = X86::AMDFAM10H; // "amdfam10" 1133 switch (Model) { 1134 case 2: 1135 *Subtype = X86::AMDFAM10H_BARCELONA; 1136 break; 1137 case 4: 1138 *Subtype = X86::AMDFAM10H_SHANGHAI; 1139 break; 1140 case 8: 1141 *Subtype = X86::AMDFAM10H_ISTANBUL; 1142 break; 1143 } 1144 break; 1145 case 20: 1146 CPU = "btver1"; 1147 *Type = X86::AMD_BTVER1; 1148 break; 1149 case 21: 1150 CPU = "bdver1"; 1151 *Type = X86::AMDFAM15H; 1152 if (Model >= 0x60 && Model <= 0x7f) { 1153 CPU = "bdver4"; 1154 *Subtype = X86::AMDFAM15H_BDVER4; 1155 break; // 60h-7Fh: Excavator 1156 } 1157 if (Model >= 0x30 && Model <= 0x3f) { 1158 CPU = "bdver3"; 1159 *Subtype = X86::AMDFAM15H_BDVER3; 1160 break; // 30h-3Fh: Steamroller 1161 } 1162 if ((Model >= 0x10 && Model <= 0x1f) || Model == 0x02) { 1163 CPU = "bdver2"; 1164 *Subtype = X86::AMDFAM15H_BDVER2; 1165 break; // 02h, 10h-1Fh: Piledriver 1166 } 1167 if (Model <= 0x0f) { 1168 *Subtype = X86::AMDFAM15H_BDVER1; 1169 break; // 00h-0Fh: Bulldozer 1170 } 1171 break; 1172 case 22: 1173 CPU = "btver2"; 1174 *Type = X86::AMD_BTVER2; 1175 break; 1176 case 23: 1177 CPU = "znver1"; 1178 *Type = X86::AMDFAM17H; 1179 if ((Model >= 0x30 && Model <= 0x3f) || (Model == 0x47) || 1180 (Model >= 0x60 && Model <= 0x67) || (Model >= 0x68 && Model <= 0x6f) || 1181 (Model >= 0x70 && Model <= 0x7f) || (Model >= 0x84 && Model <= 0x87) || 1182 (Model >= 0x90 && Model <= 0x97) || (Model >= 0x98 && Model <= 0x9f) || 1183 (Model >= 0xa0 && Model <= 0xaf)) { 1184 // Family 17h Models 30h-3Fh (Starship) Zen 2 1185 // Family 17h Models 47h (Cardinal) Zen 2 1186 // Family 17h Models 60h-67h (Renoir) Zen 2 1187 // Family 17h Models 68h-6Fh (Lucienne) Zen 2 1188 // Family 17h Models 70h-7Fh (Matisse) Zen 2 1189 // Family 17h Models 84h-87h (ProjectX) Zen 2 1190 // Family 17h Models 90h-97h (VanGogh) Zen 2 1191 // Family 17h Models 98h-9Fh (Mero) Zen 2 1192 // Family 17h Models A0h-AFh (Mendocino) Zen 2 1193 CPU = "znver2"; 1194 *Subtype = X86::AMDFAM17H_ZNVER2; 1195 break; 1196 } 1197 if ((Model >= 0x10 && Model <= 0x1f) || (Model >= 0x20 && Model <= 0x2f)) { 1198 // Family 17h Models 10h-1Fh (Raven1) Zen 1199 // Family 17h Models 10h-1Fh (Picasso) Zen+ 1200 // Family 17h Models 20h-2Fh (Raven2 x86) Zen 1201 *Subtype = X86::AMDFAM17H_ZNVER1; 1202 break; 1203 } 1204 break; 1205 case 25: 1206 CPU = "znver3"; 1207 *Type = X86::AMDFAM19H; 1208 if (Model <= 0x0f || (Model >= 0x20 && Model <= 0x2f) || 1209 (Model >= 0x30 && Model <= 0x3f) || (Model >= 0x40 && Model <= 0x4f) || 1210 (Model >= 0x50 && Model <= 0x5f)) { 1211 // Family 19h Models 00h-0Fh (Genesis, Chagall) Zen 3 1212 // Family 19h Models 20h-2Fh (Vermeer) Zen 3 1213 // Family 19h Models 30h-3Fh (Badami) Zen 3 1214 // Family 19h Models 40h-4Fh (Rembrandt) Zen 3+ 1215 // Family 19h Models 50h-5Fh (Cezanne) Zen 3 1216 *Subtype = X86::AMDFAM19H_ZNVER3; 1217 break; 1218 } 1219 if ((Model >= 0x10 && Model <= 0x1f) || (Model >= 0x60 && Model <= 0x6f) || 1220 (Model >= 0x70 && Model <= 0x77) || (Model >= 0x78 && Model <= 0x7f) || 1221 (Model >= 0xa0 && Model <= 0xaf)) { 1222 // Family 19h Models 10h-1Fh (Stones; Storm Peak) Zen 4 1223 // Family 19h Models 60h-6Fh (Raphael) Zen 4 1224 // Family 19h Models 70h-77h (Phoenix, Hawkpoint1) Zen 4 1225 // Family 19h Models 78h-7Fh (Phoenix 2, Hawkpoint2) Zen 4 1226 // Family 19h Models A0h-AFh (Stones-Dense) Zen 4 1227 CPU = "znver4"; 1228 *Subtype = X86::AMDFAM19H_ZNVER4; 1229 break; // "znver4" 1230 } 1231 break; // family 19h 1232 case 26: 1233 CPU = "znver5"; 1234 *Type = X86::AMDFAM1AH; 1235 if (Model <= 0x77) { 1236 // Models 00h-0Fh (Breithorn). 1237 // Models 10h-1Fh (Breithorn-Dense). 1238 // Models 20h-2Fh (Strix 1). 1239 // Models 30h-37h (Strix 2). 1240 // Models 38h-3Fh (Strix 3). 1241 // Models 40h-4Fh (Granite Ridge). 1242 // Models 50h-5Fh (Weisshorn). 1243 // Models 60h-6Fh (Krackan1). 1244 // Models 70h-77h (Sarlak). 1245 CPU = "znver5"; 1246 *Subtype = X86::AMDFAM1AH_ZNVER5; 1247 break; // "znver5" 1248 } 1249 break; 1250 1251 default: 1252 break; // Unknown AMD CPU. 1253 } 1254 1255 return CPU; 1256 } 1257 1258 #undef testFeature 1259 1260 static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf, 1261 unsigned *Features) { 1262 unsigned EAX, EBX; 1263 1264 auto setFeature = [&](unsigned F) { 1265 Features[F / 32] |= 1U << (F % 32); 1266 }; 1267 1268 if ((EDX >> 15) & 1) 1269 setFeature(X86::FEATURE_CMOV); 1270 if ((EDX >> 23) & 1) 1271 setFeature(X86::FEATURE_MMX); 1272 if ((EDX >> 25) & 1) 1273 setFeature(X86::FEATURE_SSE); 1274 if ((EDX >> 26) & 1) 1275 setFeature(X86::FEATURE_SSE2); 1276 1277 if ((ECX >> 0) & 1) 1278 setFeature(X86::FEATURE_SSE3); 1279 if ((ECX >> 1) & 1) 1280 setFeature(X86::FEATURE_PCLMUL); 1281 if ((ECX >> 9) & 1) 1282 setFeature(X86::FEATURE_SSSE3); 1283 if ((ECX >> 12) & 1) 1284 setFeature(X86::FEATURE_FMA); 1285 if ((ECX >> 19) & 1) 1286 setFeature(X86::FEATURE_SSE4_1); 1287 if ((ECX >> 20) & 1) { 1288 setFeature(X86::FEATURE_SSE4_2); 1289 setFeature(X86::FEATURE_CRC32); 1290 } 1291 if ((ECX >> 23) & 1) 1292 setFeature(X86::FEATURE_POPCNT); 1293 if ((ECX >> 25) & 1) 1294 setFeature(X86::FEATURE_AES); 1295 1296 if ((ECX >> 22) & 1) 1297 setFeature(X86::FEATURE_MOVBE); 1298 1299 // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV 1300 // indicates that the AVX registers will be saved and restored on context 1301 // switch, then we have full AVX support. 1302 const unsigned AVXBits = (1 << 27) | (1 << 28); 1303 bool HasAVX = ((ECX & AVXBits) == AVXBits) && !getX86XCR0(&EAX, &EDX) && 1304 ((EAX & 0x6) == 0x6); 1305 #if defined(__APPLE__) 1306 // Darwin lazily saves the AVX512 context on first use: trust that the OS will 1307 // save the AVX512 context if we use AVX512 instructions, even the bit is not 1308 // set right now. 1309 bool HasAVX512Save = true; 1310 #else 1311 // AVX512 requires additional context to be saved by the OS. 1312 bool HasAVX512Save = HasAVX && ((EAX & 0xe0) == 0xe0); 1313 #endif 1314 1315 if (HasAVX) 1316 setFeature(X86::FEATURE_AVX); 1317 1318 bool HasLeaf7 = 1319 MaxLeaf >= 0x7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX); 1320 1321 if (HasLeaf7 && ((EBX >> 3) & 1)) 1322 setFeature(X86::FEATURE_BMI); 1323 if (HasLeaf7 && ((EBX >> 5) & 1) && HasAVX) 1324 setFeature(X86::FEATURE_AVX2); 1325 if (HasLeaf7 && ((EBX >> 8) & 1)) 1326 setFeature(X86::FEATURE_BMI2); 1327 if (HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save) { 1328 setFeature(X86::FEATURE_AVX512F); 1329 setFeature(X86::FEATURE_EVEX512); 1330 } 1331 if (HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save) 1332 setFeature(X86::FEATURE_AVX512DQ); 1333 if (HasLeaf7 && ((EBX >> 19) & 1)) 1334 setFeature(X86::FEATURE_ADX); 1335 if (HasLeaf7 && ((EBX >> 21) & 1) && HasAVX512Save) 1336 setFeature(X86::FEATURE_AVX512IFMA); 1337 if (HasLeaf7 && ((EBX >> 23) & 1)) 1338 setFeature(X86::FEATURE_CLFLUSHOPT); 1339 if (HasLeaf7 && ((EBX >> 28) & 1) && HasAVX512Save) 1340 setFeature(X86::FEATURE_AVX512CD); 1341 if (HasLeaf7 && ((EBX >> 29) & 1)) 1342 setFeature(X86::FEATURE_SHA); 1343 if (HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save) 1344 setFeature(X86::FEATURE_AVX512BW); 1345 if (HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save) 1346 setFeature(X86::FEATURE_AVX512VL); 1347 1348 if (HasLeaf7 && ((ECX >> 1) & 1) && HasAVX512Save) 1349 setFeature(X86::FEATURE_AVX512VBMI); 1350 if (HasLeaf7 && ((ECX >> 6) & 1) && HasAVX512Save) 1351 setFeature(X86::FEATURE_AVX512VBMI2); 1352 if (HasLeaf7 && ((ECX >> 8) & 1)) 1353 setFeature(X86::FEATURE_GFNI); 1354 if (HasLeaf7 && ((ECX >> 10) & 1) && HasAVX) 1355 setFeature(X86::FEATURE_VPCLMULQDQ); 1356 if (HasLeaf7 && ((ECX >> 11) & 1) && HasAVX512Save) 1357 setFeature(X86::FEATURE_AVX512VNNI); 1358 if (HasLeaf7 && ((ECX >> 12) & 1) && HasAVX512Save) 1359 setFeature(X86::FEATURE_AVX512BITALG); 1360 if (HasLeaf7 && ((ECX >> 14) & 1) && HasAVX512Save) 1361 setFeature(X86::FEATURE_AVX512VPOPCNTDQ); 1362 1363 if (HasLeaf7 && ((EDX >> 2) & 1) && HasAVX512Save) 1364 setFeature(X86::FEATURE_AVX5124VNNIW); 1365 if (HasLeaf7 && ((EDX >> 3) & 1) && HasAVX512Save) 1366 setFeature(X86::FEATURE_AVX5124FMAPS); 1367 if (HasLeaf7 && ((EDX >> 8) & 1) && HasAVX512Save) 1368 setFeature(X86::FEATURE_AVX512VP2INTERSECT); 1369 1370 // EAX from subleaf 0 is the maximum subleaf supported. Some CPUs don't 1371 // return all 0s for invalid subleaves so check the limit. 1372 bool HasLeaf7Subleaf1 = 1373 HasLeaf7 && EAX >= 1 && 1374 !getX86CpuIDAndInfoEx(0x7, 0x1, &EAX, &EBX, &ECX, &EDX); 1375 if (HasLeaf7Subleaf1 && ((EAX >> 5) & 1) && HasAVX512Save) 1376 setFeature(X86::FEATURE_AVX512BF16); 1377 1378 unsigned MaxExtLevel; 1379 getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX); 1380 1381 bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 && 1382 !getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX); 1383 if (HasExtLeaf1 && ((ECX >> 6) & 1)) 1384 setFeature(X86::FEATURE_SSE4_A); 1385 if (HasExtLeaf1 && ((ECX >> 11) & 1)) 1386 setFeature(X86::FEATURE_XOP); 1387 if (HasExtLeaf1 && ((ECX >> 16) & 1)) 1388 setFeature(X86::FEATURE_FMA4); 1389 1390 if (HasExtLeaf1 && ((EDX >> 29) & 1)) 1391 setFeature(X86::FEATURE_64BIT); 1392 } 1393 1394 StringRef sys::getHostCPUName() { 1395 unsigned MaxLeaf = 0; 1396 const VendorSignatures Vendor = getVendorSignature(&MaxLeaf); 1397 if (Vendor == VendorSignatures::UNKNOWN) 1398 return "generic"; 1399 1400 unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0; 1401 getX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX); 1402 1403 unsigned Family = 0, Model = 0; 1404 unsigned Features[(X86::CPU_FEATURE_MAX + 31) / 32] = {0}; 1405 detectX86FamilyModel(EAX, &Family, &Model); 1406 getAvailableFeatures(ECX, EDX, MaxLeaf, Features); 1407 1408 // These aren't consumed in this file, but we try to keep some source code the 1409 // same or similar to compiler-rt. 1410 unsigned Type = 0; 1411 unsigned Subtype = 0; 1412 1413 StringRef CPU; 1414 1415 if (Vendor == VendorSignatures::GENUINE_INTEL) { 1416 CPU = getIntelProcessorTypeAndSubtype(Family, Model, Features, &Type, 1417 &Subtype); 1418 } else if (Vendor == VendorSignatures::AUTHENTIC_AMD) { 1419 CPU = getAMDProcessorTypeAndSubtype(Family, Model, Features, &Type, 1420 &Subtype); 1421 } 1422 1423 if (!CPU.empty()) 1424 return CPU; 1425 1426 return "generic"; 1427 } 1428 1429 #elif defined(__APPLE__) && defined(__powerpc__) 1430 StringRef sys::getHostCPUName() { 1431 host_basic_info_data_t hostInfo; 1432 mach_msg_type_number_t infoCount; 1433 1434 infoCount = HOST_BASIC_INFO_COUNT; 1435 mach_port_t hostPort = mach_host_self(); 1436 host_info(hostPort, HOST_BASIC_INFO, (host_info_t)&hostInfo, 1437 &infoCount); 1438 mach_port_deallocate(mach_task_self(), hostPort); 1439 1440 if (hostInfo.cpu_type != CPU_TYPE_POWERPC) 1441 return "generic"; 1442 1443 switch (hostInfo.cpu_subtype) { 1444 case CPU_SUBTYPE_POWERPC_601: 1445 return "601"; 1446 case CPU_SUBTYPE_POWERPC_602: 1447 return "602"; 1448 case CPU_SUBTYPE_POWERPC_603: 1449 return "603"; 1450 case CPU_SUBTYPE_POWERPC_603e: 1451 return "603e"; 1452 case CPU_SUBTYPE_POWERPC_603ev: 1453 return "603ev"; 1454 case CPU_SUBTYPE_POWERPC_604: 1455 return "604"; 1456 case CPU_SUBTYPE_POWERPC_604e: 1457 return "604e"; 1458 case CPU_SUBTYPE_POWERPC_620: 1459 return "620"; 1460 case CPU_SUBTYPE_POWERPC_750: 1461 return "750"; 1462 case CPU_SUBTYPE_POWERPC_7400: 1463 return "7400"; 1464 case CPU_SUBTYPE_POWERPC_7450: 1465 return "7450"; 1466 case CPU_SUBTYPE_POWERPC_970: 1467 return "970"; 1468 default:; 1469 } 1470 1471 return "generic"; 1472 } 1473 #elif defined(__linux__) && defined(__powerpc__) 1474 StringRef sys::getHostCPUName() { 1475 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent(); 1476 StringRef Content = P ? P->getBuffer() : ""; 1477 return detail::getHostCPUNameForPowerPC(Content); 1478 } 1479 #elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__)) 1480 StringRef sys::getHostCPUName() { 1481 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent(); 1482 StringRef Content = P ? P->getBuffer() : ""; 1483 return detail::getHostCPUNameForARM(Content); 1484 } 1485 #elif defined(__linux__) && defined(__s390x__) 1486 StringRef sys::getHostCPUName() { 1487 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent(); 1488 StringRef Content = P ? P->getBuffer() : ""; 1489 return detail::getHostCPUNameForS390x(Content); 1490 } 1491 #elif defined(__MVS__) 1492 StringRef sys::getHostCPUName() { 1493 // Get pointer to Communications Vector Table (CVT). 1494 // The pointer is located at offset 16 of the Prefixed Save Area (PSA). 1495 // It is stored as 31 bit pointer and will be zero-extended to 64 bit. 1496 int *StartToCVTOffset = reinterpret_cast<int *>(0x10); 1497 // Since its stored as a 31-bit pointer, get the 4 bytes from the start 1498 // of address. 1499 int ReadValue = *StartToCVTOffset; 1500 // Explicitly clear the high order bit. 1501 ReadValue = (ReadValue & 0x7FFFFFFF); 1502 char *CVT = reinterpret_cast<char *>(ReadValue); 1503 // The model number is located in the CVT prefix at offset -6 and stored as 1504 // signless packed decimal. 1505 uint16_t Id = *(uint16_t *)&CVT[-6]; 1506 // Convert number to integer. 1507 Id = decodePackedBCD<uint16_t>(Id, false); 1508 // Check for vector support. It's stored in field CVTFLAG5 (offset 244), 1509 // bit CVTVEF (X'80'). The facilities list is part of the PSA but the vector 1510 // extension can only be used if bit CVTVEF is on. 1511 bool HaveVectorSupport = CVT[244] & 0x80; 1512 return getCPUNameFromS390Model(Id, HaveVectorSupport); 1513 } 1514 #elif defined(__APPLE__) && (defined(__arm__) || defined(__aarch64__)) 1515 // Copied from <mach/machine.h> in the macOS SDK. 1516 // 1517 // Also available here, though usually not as up-to-date: 1518 // https://github.com/apple-oss-distributions/xnu/blob/xnu-11215.41.3/osfmk/mach/machine.h#L403-L452. 1519 #define CPUFAMILY_UNKNOWN 0 1520 #define CPUFAMILY_ARM_9 0xe73283ae 1521 #define CPUFAMILY_ARM_11 0x8ff620d8 1522 #define CPUFAMILY_ARM_XSCALE 0x53b005f5 1523 #define CPUFAMILY_ARM_12 0xbd1b0ae9 1524 #define CPUFAMILY_ARM_13 0x0cc90e64 1525 #define CPUFAMILY_ARM_14 0x96077ef1 1526 #define CPUFAMILY_ARM_15 0xa8511bca 1527 #define CPUFAMILY_ARM_SWIFT 0x1e2d6381 1528 #define CPUFAMILY_ARM_CYCLONE 0x37a09642 1529 #define CPUFAMILY_ARM_TYPHOON 0x2c91a47e 1530 #define CPUFAMILY_ARM_TWISTER 0x92fb37c8 1531 #define CPUFAMILY_ARM_HURRICANE 0x67ceee93 1532 #define CPUFAMILY_ARM_MONSOON_MISTRAL 0xe81e7ef6 1533 #define CPUFAMILY_ARM_VORTEX_TEMPEST 0x07d34b9f 1534 #define CPUFAMILY_ARM_LIGHTNING_THUNDER 0x462504d2 1535 #define CPUFAMILY_ARM_FIRESTORM_ICESTORM 0x1b588bb3 1536 #define CPUFAMILY_ARM_BLIZZARD_AVALANCHE 0xda33d83d 1537 #define CPUFAMILY_ARM_EVEREST_SAWTOOTH 0x8765edea 1538 #define CPUFAMILY_ARM_IBIZA 0xfa33415e 1539 #define CPUFAMILY_ARM_PALMA 0x72015832 1540 #define CPUFAMILY_ARM_COLL 0x2876f5b5 1541 #define CPUFAMILY_ARM_LOBOS 0x5f4dea93 1542 #define CPUFAMILY_ARM_DONAN 0x6f5129ac 1543 #define CPUFAMILY_ARM_BRAVA 0x17d5b93a 1544 #define CPUFAMILY_ARM_TAHITI 0x75d4acb9 1545 #define CPUFAMILY_ARM_TUPAI 0x204526d0 1546 1547 StringRef sys::getHostCPUName() { 1548 uint32_t Family; 1549 size_t Length = sizeof(Family); 1550 sysctlbyname("hw.cpufamily", &Family, &Length, NULL, 0); 1551 1552 // This is found by testing on actual hardware, and by looking at: 1553 // https://github.com/apple-oss-distributions/xnu/blob/xnu-11215.41.3/osfmk/arm/cpuid.c#L109-L231. 1554 // 1555 // Another great resource is 1556 // https://github.com/AsahiLinux/docs/wiki/Codenames. 1557 // 1558 // NOTE: We choose to return `apple-mX` instead of `apple-aX`, since the M1, 1559 // M2, M3 etc. aliases are more widely known to users than A14, A15, A16 etc. 1560 // (and this code is basically only used on host macOS anyways). 1561 switch (Family) { 1562 case CPUFAMILY_UNKNOWN: 1563 return "generic"; 1564 case CPUFAMILY_ARM_9: 1565 return "arm920t"; // or arm926ej-s 1566 case CPUFAMILY_ARM_11: 1567 return "arm1136jf-s"; 1568 case CPUFAMILY_ARM_XSCALE: 1569 return "xscale"; 1570 case CPUFAMILY_ARM_12: // Seems unused by the kernel 1571 return "generic"; 1572 case CPUFAMILY_ARM_13: 1573 return "cortex-a8"; 1574 case CPUFAMILY_ARM_14: 1575 return "cortex-a9"; 1576 case CPUFAMILY_ARM_15: 1577 return "cortex-a7"; 1578 case CPUFAMILY_ARM_SWIFT: 1579 return "swift"; 1580 case CPUFAMILY_ARM_CYCLONE: 1581 return "apple-a7"; 1582 case CPUFAMILY_ARM_TYPHOON: 1583 return "apple-a8"; 1584 case CPUFAMILY_ARM_TWISTER: 1585 return "apple-a9"; 1586 case CPUFAMILY_ARM_HURRICANE: 1587 return "apple-a10"; 1588 case CPUFAMILY_ARM_MONSOON_MISTRAL: 1589 return "apple-a11"; 1590 case CPUFAMILY_ARM_VORTEX_TEMPEST: 1591 return "apple-a12"; 1592 case CPUFAMILY_ARM_LIGHTNING_THUNDER: 1593 return "apple-a13"; 1594 case CPUFAMILY_ARM_FIRESTORM_ICESTORM: // A14 / M1 1595 return "apple-m1"; 1596 case CPUFAMILY_ARM_BLIZZARD_AVALANCHE: // A15 / M2 1597 return "apple-m2"; 1598 case CPUFAMILY_ARM_EVEREST_SAWTOOTH: // A16 1599 case CPUFAMILY_ARM_IBIZA: // M3 1600 case CPUFAMILY_ARM_PALMA: // M3 Max 1601 case CPUFAMILY_ARM_LOBOS: // M3 Pro 1602 return "apple-m3"; 1603 case CPUFAMILY_ARM_COLL: // A17 Pro 1604 return "apple-a17"; 1605 case CPUFAMILY_ARM_DONAN: // M4 1606 case CPUFAMILY_ARM_BRAVA: // M4 Max 1607 case CPUFAMILY_ARM_TAHITI: // A18 Pro 1608 case CPUFAMILY_ARM_TUPAI: // A18 1609 return "apple-m4"; 1610 default: 1611 // Default to the newest CPU we know about. 1612 return "apple-m4"; 1613 } 1614 } 1615 #elif defined(_AIX) 1616 StringRef sys::getHostCPUName() { 1617 switch (_system_configuration.implementation) { 1618 case POWER_4: 1619 if (_system_configuration.version == PV_4_3) 1620 return "970"; 1621 return "pwr4"; 1622 case POWER_5: 1623 if (_system_configuration.version == PV_5) 1624 return "pwr5"; 1625 return "pwr5x"; 1626 case POWER_6: 1627 if (_system_configuration.version == PV_6_Compat) 1628 return "pwr6"; 1629 return "pwr6x"; 1630 case POWER_7: 1631 return "pwr7"; 1632 case POWER_8: 1633 return "pwr8"; 1634 case POWER_9: 1635 return "pwr9"; 1636 // TODO: simplify this once the macro is available in all OS levels. 1637 #ifdef POWER_10 1638 case POWER_10: 1639 #else 1640 case 0x40000: 1641 #endif 1642 return "pwr10"; 1643 #ifdef POWER_11 1644 case POWER_11: 1645 #else 1646 case 0x80000: 1647 #endif 1648 return "pwr11"; 1649 default: 1650 return "generic"; 1651 } 1652 } 1653 #elif defined(__loongarch__) 1654 StringRef sys::getHostCPUName() { 1655 // Use processor id to detect cpu name. 1656 uint32_t processor_id; 1657 __asm__("cpucfg %[prid], $zero\n\t" : [prid] "=r"(processor_id)); 1658 // Refer PRID_SERIES_MASK in linux kernel: arch/loongarch/include/asm/cpu.h. 1659 switch (processor_id & 0xf000) { 1660 case 0xc000: // Loongson 64bit, 4-issue 1661 return "la464"; 1662 case 0xd000: // Loongson 64bit, 6-issue 1663 return "la664"; 1664 // TODO: Others. 1665 default: 1666 break; 1667 } 1668 return "generic"; 1669 } 1670 #elif defined(__riscv) 1671 StringRef sys::getHostCPUName() { 1672 #if defined(__linux__) 1673 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent(); 1674 StringRef Content = P ? P->getBuffer() : ""; 1675 StringRef Name = detail::getHostCPUNameForRISCV(Content); 1676 if (!Name.empty()) 1677 return Name; 1678 #endif 1679 #if __riscv_xlen == 64 1680 return "generic-rv64"; 1681 #elif __riscv_xlen == 32 1682 return "generic-rv32"; 1683 #else 1684 #error "Unhandled value of __riscv_xlen" 1685 #endif 1686 } 1687 #elif defined(__sparc__) 1688 #if defined(__linux__) 1689 StringRef sys::detail::getHostCPUNameForSPARC(StringRef ProcCpuinfoContent) { 1690 SmallVector<StringRef> Lines; 1691 ProcCpuinfoContent.split(Lines, '\n'); 1692 1693 // Look for cpu line to determine cpu name 1694 StringRef Cpu; 1695 for (unsigned I = 0, E = Lines.size(); I != E; ++I) { 1696 if (Lines[I].starts_with("cpu")) { 1697 Cpu = Lines[I].substr(5).ltrim("\t :"); 1698 break; 1699 } 1700 } 1701 1702 return StringSwitch<const char *>(Cpu) 1703 .StartsWith("SuperSparc", "supersparc") 1704 .StartsWith("HyperSparc", "hypersparc") 1705 .StartsWith("SpitFire", "ultrasparc") 1706 .StartsWith("BlackBird", "ultrasparc") 1707 .StartsWith("Sabre", " ultrasparc") 1708 .StartsWith("Hummingbird", "ultrasparc") 1709 .StartsWith("Cheetah", "ultrasparc3") 1710 .StartsWith("Jalapeno", "ultrasparc3") 1711 .StartsWith("Jaguar", "ultrasparc3") 1712 .StartsWith("Panther", "ultrasparc3") 1713 .StartsWith("Serrano", "ultrasparc3") 1714 .StartsWith("UltraSparc T1", "niagara") 1715 .StartsWith("UltraSparc T2", "niagara2") 1716 .StartsWith("UltraSparc T3", "niagara3") 1717 .StartsWith("UltraSparc T4", "niagara4") 1718 .StartsWith("UltraSparc T5", "niagara4") 1719 .StartsWith("LEON", "leon3") 1720 // niagara7/m8 not supported by LLVM yet. 1721 .StartsWith("SPARC-M7", "niagara4" /* "niagara7" */) 1722 .StartsWith("SPARC-S7", "niagara4" /* "niagara7" */) 1723 .StartsWith("SPARC-M8", "niagara4" /* "m8" */) 1724 .Default("generic"); 1725 } 1726 #endif 1727 1728 StringRef sys::getHostCPUName() { 1729 #if defined(__linux__) 1730 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent(); 1731 StringRef Content = P ? P->getBuffer() : ""; 1732 return detail::getHostCPUNameForSPARC(Content); 1733 #elif defined(__sun__) && defined(__svr4__) 1734 char *buf = NULL; 1735 kstat_ctl_t *kc; 1736 kstat_t *ksp; 1737 kstat_named_t *brand = NULL; 1738 1739 kc = kstat_open(); 1740 if (kc != NULL) { 1741 ksp = kstat_lookup(kc, const_cast<char *>("cpu_info"), -1, NULL); 1742 if (ksp != NULL && kstat_read(kc, ksp, NULL) != -1 && 1743 ksp->ks_type == KSTAT_TYPE_NAMED) 1744 brand = 1745 (kstat_named_t *)kstat_data_lookup(ksp, const_cast<char *>("brand")); 1746 if (brand != NULL && brand->data_type == KSTAT_DATA_STRING) 1747 buf = KSTAT_NAMED_STR_PTR(brand); 1748 } 1749 kstat_close(kc); 1750 1751 return StringSwitch<const char *>(buf) 1752 .Case("TMS390S10", "supersparc") // Texas Instruments microSPARC I 1753 .Case("TMS390Z50", "supersparc") // Texas Instruments SuperSPARC I 1754 .Case("TMS390Z55", 1755 "supersparc") // Texas Instruments SuperSPARC I with SuperCache 1756 .Case("MB86904", "supersparc") // Fujitsu microSPARC II 1757 .Case("MB86907", "supersparc") // Fujitsu TurboSPARC 1758 .Case("RT623", "hypersparc") // Ross hyperSPARC 1759 .Case("RT625", "hypersparc") 1760 .Case("RT626", "hypersparc") 1761 .Case("UltraSPARC-I", "ultrasparc") 1762 .Case("UltraSPARC-II", "ultrasparc") 1763 .Case("UltraSPARC-IIe", "ultrasparc") 1764 .Case("UltraSPARC-IIi", "ultrasparc") 1765 .Case("SPARC64-III", "ultrasparc") 1766 .Case("SPARC64-IV", "ultrasparc") 1767 .Case("UltraSPARC-III", "ultrasparc3") 1768 .Case("UltraSPARC-III+", "ultrasparc3") 1769 .Case("UltraSPARC-IIIi", "ultrasparc3") 1770 .Case("UltraSPARC-IIIi+", "ultrasparc3") 1771 .Case("UltraSPARC-IV", "ultrasparc3") 1772 .Case("UltraSPARC-IV+", "ultrasparc3") 1773 .Case("SPARC64-V", "ultrasparc3") 1774 .Case("SPARC64-VI", "ultrasparc3") 1775 .Case("SPARC64-VII", "ultrasparc3") 1776 .Case("UltraSPARC-T1", "niagara") 1777 .Case("UltraSPARC-T2", "niagara2") 1778 .Case("UltraSPARC-T2", "niagara2") 1779 .Case("UltraSPARC-T2+", "niagara2") 1780 .Case("SPARC-T3", "niagara3") 1781 .Case("SPARC-T4", "niagara4") 1782 .Case("SPARC-T5", "niagara4") 1783 // niagara7/m8 not supported by LLVM yet. 1784 .Case("SPARC-M7", "niagara4" /* "niagara7" */) 1785 .Case("SPARC-S7", "niagara4" /* "niagara7" */) 1786 .Case("SPARC-M8", "niagara4" /* "m8" */) 1787 .Default("generic"); 1788 #else 1789 return "generic"; 1790 #endif 1791 } 1792 #else 1793 StringRef sys::getHostCPUName() { return "generic"; } 1794 namespace llvm { 1795 namespace sys { 1796 namespace detail { 1797 namespace x86 { 1798 1799 VendorSignatures getVendorSignature(unsigned *MaxLeaf) { 1800 return VendorSignatures::UNKNOWN; 1801 } 1802 1803 } // namespace x86 1804 } // namespace detail 1805 } // namespace sys 1806 } // namespace llvm 1807 #endif 1808 1809 #if defined(__i386__) || defined(_M_IX86) || \ 1810 defined(__x86_64__) || defined(_M_X64) 1811 const StringMap<bool> sys::getHostCPUFeatures() { 1812 unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0; 1813 unsigned MaxLevel; 1814 StringMap<bool> Features; 1815 1816 if (getX86CpuIDAndInfo(0, &MaxLevel, &EBX, &ECX, &EDX) || MaxLevel < 1) 1817 return Features; 1818 1819 getX86CpuIDAndInfo(1, &EAX, &EBX, &ECX, &EDX); 1820 1821 Features["cx8"] = (EDX >> 8) & 1; 1822 Features["cmov"] = (EDX >> 15) & 1; 1823 Features["mmx"] = (EDX >> 23) & 1; 1824 Features["fxsr"] = (EDX >> 24) & 1; 1825 Features["sse"] = (EDX >> 25) & 1; 1826 Features["sse2"] = (EDX >> 26) & 1; 1827 1828 Features["sse3"] = (ECX >> 0) & 1; 1829 Features["pclmul"] = (ECX >> 1) & 1; 1830 Features["ssse3"] = (ECX >> 9) & 1; 1831 Features["cx16"] = (ECX >> 13) & 1; 1832 Features["sse4.1"] = (ECX >> 19) & 1; 1833 Features["sse4.2"] = (ECX >> 20) & 1; 1834 Features["crc32"] = Features["sse4.2"]; 1835 Features["movbe"] = (ECX >> 22) & 1; 1836 Features["popcnt"] = (ECX >> 23) & 1; 1837 Features["aes"] = (ECX >> 25) & 1; 1838 Features["rdrnd"] = (ECX >> 30) & 1; 1839 1840 // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV 1841 // indicates that the AVX registers will be saved and restored on context 1842 // switch, then we have full AVX support. 1843 bool HasXSave = ((ECX >> 27) & 1) && !getX86XCR0(&EAX, &EDX); 1844 bool HasAVXSave = HasXSave && ((ECX >> 28) & 1) && ((EAX & 0x6) == 0x6); 1845 #if defined(__APPLE__) 1846 // Darwin lazily saves the AVX512 context on first use: trust that the OS will 1847 // save the AVX512 context if we use AVX512 instructions, even the bit is not 1848 // set right now. 1849 bool HasAVX512Save = true; 1850 #else 1851 // AVX512 requires additional context to be saved by the OS. 1852 bool HasAVX512Save = HasAVXSave && ((EAX & 0xe0) == 0xe0); 1853 #endif 1854 // AMX requires additional context to be saved by the OS. 1855 const unsigned AMXBits = (1 << 17) | (1 << 18); 1856 bool HasAMXSave = HasXSave && ((EAX & AMXBits) == AMXBits); 1857 1858 Features["avx"] = HasAVXSave; 1859 Features["fma"] = ((ECX >> 12) & 1) && HasAVXSave; 1860 // Only enable XSAVE if OS has enabled support for saving YMM state. 1861 Features["xsave"] = ((ECX >> 26) & 1) && HasAVXSave; 1862 Features["f16c"] = ((ECX >> 29) & 1) && HasAVXSave; 1863 1864 unsigned MaxExtLevel; 1865 getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX); 1866 1867 bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 && 1868 !getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX); 1869 Features["sahf"] = HasExtLeaf1 && ((ECX >> 0) & 1); 1870 Features["lzcnt"] = HasExtLeaf1 && ((ECX >> 5) & 1); 1871 Features["sse4a"] = HasExtLeaf1 && ((ECX >> 6) & 1); 1872 Features["prfchw"] = HasExtLeaf1 && ((ECX >> 8) & 1); 1873 Features["xop"] = HasExtLeaf1 && ((ECX >> 11) & 1) && HasAVXSave; 1874 Features["lwp"] = HasExtLeaf1 && ((ECX >> 15) & 1); 1875 Features["fma4"] = HasExtLeaf1 && ((ECX >> 16) & 1) && HasAVXSave; 1876 Features["tbm"] = HasExtLeaf1 && ((ECX >> 21) & 1); 1877 Features["mwaitx"] = HasExtLeaf1 && ((ECX >> 29) & 1); 1878 1879 Features["64bit"] = HasExtLeaf1 && ((EDX >> 29) & 1); 1880 1881 // Miscellaneous memory related features, detected by 1882 // using the 0x80000008 leaf of the CPUID instruction 1883 bool HasExtLeaf8 = MaxExtLevel >= 0x80000008 && 1884 !getX86CpuIDAndInfo(0x80000008, &EAX, &EBX, &ECX, &EDX); 1885 Features["clzero"] = HasExtLeaf8 && ((EBX >> 0) & 1); 1886 Features["rdpru"] = HasExtLeaf8 && ((EBX >> 4) & 1); 1887 Features["wbnoinvd"] = HasExtLeaf8 && ((EBX >> 9) & 1); 1888 1889 bool HasLeaf7 = 1890 MaxLevel >= 7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX); 1891 1892 Features["fsgsbase"] = HasLeaf7 && ((EBX >> 0) & 1); 1893 Features["sgx"] = HasLeaf7 && ((EBX >> 2) & 1); 1894 Features["bmi"] = HasLeaf7 && ((EBX >> 3) & 1); 1895 // AVX2 is only supported if we have the OS save support from AVX. 1896 Features["avx2"] = HasLeaf7 && ((EBX >> 5) & 1) && HasAVXSave; 1897 Features["bmi2"] = HasLeaf7 && ((EBX >> 8) & 1); 1898 Features["invpcid"] = HasLeaf7 && ((EBX >> 10) & 1); 1899 Features["rtm"] = HasLeaf7 && ((EBX >> 11) & 1); 1900 // AVX512 is only supported if the OS supports the context save for it. 1901 Features["avx512f"] = HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save; 1902 if (Features["avx512f"]) 1903 Features["evex512"] = true; 1904 Features["avx512dq"] = HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save; 1905 Features["rdseed"] = HasLeaf7 && ((EBX >> 18) & 1); 1906 Features["adx"] = HasLeaf7 && ((EBX >> 19) & 1); 1907 Features["avx512ifma"] = HasLeaf7 && ((EBX >> 21) & 1) && HasAVX512Save; 1908 Features["clflushopt"] = HasLeaf7 && ((EBX >> 23) & 1); 1909 Features["clwb"] = HasLeaf7 && ((EBX >> 24) & 1); 1910 Features["avx512cd"] = HasLeaf7 && ((EBX >> 28) & 1) && HasAVX512Save; 1911 Features["sha"] = HasLeaf7 && ((EBX >> 29) & 1); 1912 Features["avx512bw"] = HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save; 1913 Features["avx512vl"] = HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save; 1914 1915 Features["avx512vbmi"] = HasLeaf7 && ((ECX >> 1) & 1) && HasAVX512Save; 1916 Features["pku"] = HasLeaf7 && ((ECX >> 4) & 1); 1917 Features["waitpkg"] = HasLeaf7 && ((ECX >> 5) & 1); 1918 Features["avx512vbmi2"] = HasLeaf7 && ((ECX >> 6) & 1) && HasAVX512Save; 1919 Features["shstk"] = HasLeaf7 && ((ECX >> 7) & 1); 1920 Features["gfni"] = HasLeaf7 && ((ECX >> 8) & 1); 1921 Features["vaes"] = HasLeaf7 && ((ECX >> 9) & 1) && HasAVXSave; 1922 Features["vpclmulqdq"] = HasLeaf7 && ((ECX >> 10) & 1) && HasAVXSave; 1923 Features["avx512vnni"] = HasLeaf7 && ((ECX >> 11) & 1) && HasAVX512Save; 1924 Features["avx512bitalg"] = HasLeaf7 && ((ECX >> 12) & 1) && HasAVX512Save; 1925 Features["avx512vpopcntdq"] = HasLeaf7 && ((ECX >> 14) & 1) && HasAVX512Save; 1926 Features["rdpid"] = HasLeaf7 && ((ECX >> 22) & 1); 1927 Features["kl"] = HasLeaf7 && ((ECX >> 23) & 1); // key locker 1928 Features["cldemote"] = HasLeaf7 && ((ECX >> 25) & 1); 1929 Features["movdiri"] = HasLeaf7 && ((ECX >> 27) & 1); 1930 Features["movdir64b"] = HasLeaf7 && ((ECX >> 28) & 1); 1931 Features["enqcmd"] = HasLeaf7 && ((ECX >> 29) & 1); 1932 1933 Features["uintr"] = HasLeaf7 && ((EDX >> 5) & 1); 1934 Features["avx512vp2intersect"] = 1935 HasLeaf7 && ((EDX >> 8) & 1) && HasAVX512Save; 1936 Features["serialize"] = HasLeaf7 && ((EDX >> 14) & 1); 1937 Features["tsxldtrk"] = HasLeaf7 && ((EDX >> 16) & 1); 1938 // There are two CPUID leafs which information associated with the pconfig 1939 // instruction: 1940 // EAX=0x7, ECX=0x0 indicates the availability of the instruction (via the 18th 1941 // bit of EDX), while the EAX=0x1b leaf returns information on the 1942 // availability of specific pconfig leafs. 1943 // The target feature here only refers to the the first of these two. 1944 // Users might need to check for the availability of specific pconfig 1945 // leaves using cpuid, since that information is ignored while 1946 // detecting features using the "-march=native" flag. 1947 // For more info, see X86 ISA docs. 1948 Features["pconfig"] = HasLeaf7 && ((EDX >> 18) & 1); 1949 Features["amx-bf16"] = HasLeaf7 && ((EDX >> 22) & 1) && HasAMXSave; 1950 Features["avx512fp16"] = HasLeaf7 && ((EDX >> 23) & 1) && HasAVX512Save; 1951 Features["amx-tile"] = HasLeaf7 && ((EDX >> 24) & 1) && HasAMXSave; 1952 Features["amx-int8"] = HasLeaf7 && ((EDX >> 25) & 1) && HasAMXSave; 1953 // EAX from subleaf 0 is the maximum subleaf supported. Some CPUs don't 1954 // return all 0s for invalid subleaves so check the limit. 1955 bool HasLeaf7Subleaf1 = 1956 HasLeaf7 && EAX >= 1 && 1957 !getX86CpuIDAndInfoEx(0x7, 0x1, &EAX, &EBX, &ECX, &EDX); 1958 Features["sha512"] = HasLeaf7Subleaf1 && ((EAX >> 0) & 1); 1959 Features["sm3"] = HasLeaf7Subleaf1 && ((EAX >> 1) & 1); 1960 Features["sm4"] = HasLeaf7Subleaf1 && ((EAX >> 2) & 1); 1961 Features["raoint"] = HasLeaf7Subleaf1 && ((EAX >> 3) & 1); 1962 Features["avxvnni"] = HasLeaf7Subleaf1 && ((EAX >> 4) & 1) && HasAVXSave; 1963 Features["avx512bf16"] = HasLeaf7Subleaf1 && ((EAX >> 5) & 1) && HasAVX512Save; 1964 Features["amx-fp16"] = HasLeaf7Subleaf1 && ((EAX >> 21) & 1) && HasAMXSave; 1965 Features["cmpccxadd"] = HasLeaf7Subleaf1 && ((EAX >> 7) & 1); 1966 Features["hreset"] = HasLeaf7Subleaf1 && ((EAX >> 22) & 1); 1967 Features["avxifma"] = HasLeaf7Subleaf1 && ((EAX >> 23) & 1) && HasAVXSave; 1968 Features["movrs"] = HasLeaf7Subleaf1 && ((EAX >> 31) & 1); 1969 Features["avxvnniint8"] = HasLeaf7Subleaf1 && ((EDX >> 4) & 1) && HasAVXSave; 1970 Features["avxneconvert"] = HasLeaf7Subleaf1 && ((EDX >> 5) & 1) && HasAVXSave; 1971 Features["amx-complex"] = HasLeaf7Subleaf1 && ((EDX >> 8) & 1) && HasAMXSave; 1972 Features["avxvnniint16"] = HasLeaf7Subleaf1 && ((EDX >> 10) & 1) && HasAVXSave; 1973 Features["prefetchi"] = HasLeaf7Subleaf1 && ((EDX >> 14) & 1); 1974 Features["usermsr"] = HasLeaf7Subleaf1 && ((EDX >> 15) & 1); 1975 bool HasAVX10 = HasLeaf7Subleaf1 && ((EDX >> 19) & 1); 1976 bool HasAPXF = HasLeaf7Subleaf1 && ((EDX >> 21) & 1); 1977 Features["egpr"] = HasAPXF; 1978 Features["push2pop2"] = HasAPXF; 1979 Features["ppx"] = HasAPXF; 1980 Features["ndd"] = HasAPXF; 1981 Features["ccmp"] = HasAPXF; 1982 Features["nf"] = HasAPXF; 1983 Features["cf"] = HasAPXF; 1984 Features["zu"] = HasAPXF; 1985 1986 bool HasLeafD = MaxLevel >= 0xd && 1987 !getX86CpuIDAndInfoEx(0xd, 0x1, &EAX, &EBX, &ECX, &EDX); 1988 1989 // Only enable XSAVE if OS has enabled support for saving YMM state. 1990 Features["xsaveopt"] = HasLeafD && ((EAX >> 0) & 1) && HasAVXSave; 1991 Features["xsavec"] = HasLeafD && ((EAX >> 1) & 1) && HasAVXSave; 1992 Features["xsaves"] = HasLeafD && ((EAX >> 3) & 1) && HasAVXSave; 1993 1994 bool HasLeaf14 = MaxLevel >= 0x14 && 1995 !getX86CpuIDAndInfoEx(0x14, 0x0, &EAX, &EBX, &ECX, &EDX); 1996 1997 Features["ptwrite"] = HasLeaf14 && ((EBX >> 4) & 1); 1998 1999 bool HasLeaf19 = 2000 MaxLevel >= 0x19 && !getX86CpuIDAndInfo(0x19, &EAX, &EBX, &ECX, &EDX); 2001 Features["widekl"] = HasLeaf7 && HasLeaf19 && ((EBX >> 2) & 1); 2002 2003 bool HasLeaf1E = MaxLevel >= 0x1e && 2004 !getX86CpuIDAndInfoEx(0x1e, 0x1, &EAX, &EBX, &ECX, &EDX); 2005 Features["amx-fp8"] = HasLeaf1E && ((EAX >> 4) & 1) && HasAMXSave; 2006 Features["amx-transpose"] = HasLeaf1E && ((EAX >> 5) & 1) && HasAMXSave; 2007 Features["amx-tf32"] = HasLeaf1E && ((EAX >> 6) & 1) && HasAMXSave; 2008 Features["amx-avx512"] = HasLeaf1E && ((EAX >> 7) & 1) && HasAMXSave; 2009 Features["amx-movrs"] = HasLeaf1E && ((EAX >> 8) & 1) && HasAMXSave; 2010 2011 bool HasLeaf24 = 2012 MaxLevel >= 0x24 && !getX86CpuIDAndInfo(0x24, &EAX, &EBX, &ECX, &EDX); 2013 2014 int AVX10Ver = HasLeaf24 && (EBX & 0xff); 2015 int Has512Len = HasLeaf24 && ((EBX >> 18) & 1); 2016 Features["avx10.1-256"] = HasAVX10 && AVX10Ver >= 1; 2017 Features["avx10.1-512"] = HasAVX10 && AVX10Ver >= 1 && Has512Len; 2018 Features["avx10.2-256"] = HasAVX10 && AVX10Ver >= 2; 2019 Features["avx10.2-512"] = HasAVX10 && AVX10Ver >= 2 && Has512Len; 2020 2021 return Features; 2022 } 2023 #elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__)) 2024 const StringMap<bool> sys::getHostCPUFeatures() { 2025 StringMap<bool> Features; 2026 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent(); 2027 if (!P) 2028 return Features; 2029 2030 SmallVector<StringRef, 32> Lines; 2031 P->getBuffer().split(Lines, '\n'); 2032 2033 SmallVector<StringRef, 32> CPUFeatures; 2034 2035 // Look for the CPU features. 2036 for (unsigned I = 0, E = Lines.size(); I != E; ++I) 2037 if (Lines[I].starts_with("Features")) { 2038 Lines[I].split(CPUFeatures, ' '); 2039 break; 2040 } 2041 2042 #if defined(__aarch64__) 2043 // All of these are "crypto" features, but we must sift out actual features 2044 // as the former meaning of "crypto" as a single feature is no more. 2045 enum { CAP_AES = 0x1, CAP_PMULL = 0x2, CAP_SHA1 = 0x4, CAP_SHA2 = 0x8 }; 2046 uint32_t crypto = 0; 2047 #endif 2048 2049 for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) { 2050 StringRef LLVMFeatureStr = StringSwitch<StringRef>(CPUFeatures[I]) 2051 #if defined(__aarch64__) 2052 .Case("asimd", "neon") 2053 .Case("fp", "fp-armv8") 2054 .Case("crc32", "crc") 2055 .Case("atomics", "lse") 2056 .Case("sve", "sve") 2057 .Case("sve2", "sve2") 2058 #else 2059 .Case("half", "fp16") 2060 .Case("neon", "neon") 2061 .Case("vfpv3", "vfp3") 2062 .Case("vfpv3d16", "vfp3d16") 2063 .Case("vfpv4", "vfp4") 2064 .Case("idiva", "hwdiv-arm") 2065 .Case("idivt", "hwdiv") 2066 #endif 2067 .Default(""); 2068 2069 #if defined(__aarch64__) 2070 // We need to check crypto separately since we need all of the crypto 2071 // extensions to enable the subtarget feature 2072 if (CPUFeatures[I] == "aes") 2073 crypto |= CAP_AES; 2074 else if (CPUFeatures[I] == "pmull") 2075 crypto |= CAP_PMULL; 2076 else if (CPUFeatures[I] == "sha1") 2077 crypto |= CAP_SHA1; 2078 else if (CPUFeatures[I] == "sha2") 2079 crypto |= CAP_SHA2; 2080 #endif 2081 2082 if (LLVMFeatureStr != "") 2083 Features[LLVMFeatureStr] = true; 2084 } 2085 2086 #if defined(__aarch64__) 2087 // LLVM has decided some AArch64 CPUs have all the instructions they _may_ 2088 // have, as opposed to all the instructions they _must_ have, so allow runtime 2089 // information to correct us on that. 2090 uint32_t Aes = CAP_AES | CAP_PMULL; 2091 uint32_t Sha2 = CAP_SHA1 | CAP_SHA2; 2092 Features["aes"] = (crypto & Aes) == Aes; 2093 Features["sha2"] = (crypto & Sha2) == Sha2; 2094 #endif 2095 2096 return Features; 2097 } 2098 #elif defined(_WIN32) && (defined(__aarch64__) || defined(_M_ARM64)) 2099 const StringMap<bool> sys::getHostCPUFeatures() { 2100 StringMap<bool> Features; 2101 2102 // If we're asking the OS at runtime, believe what the OS says 2103 Features["neon"] = 2104 IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE); 2105 Features["crc"] = 2106 IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE); 2107 2108 // Avoid inferring "crypto" means more than the traditional AES + SHA2 2109 bool TradCrypto = 2110 IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE); 2111 Features["aes"] = TradCrypto; 2112 Features["sha2"] = TradCrypto; 2113 2114 return Features; 2115 } 2116 #elif defined(__linux__) && defined(__loongarch__) 2117 #include <sys/auxv.h> 2118 const StringMap<bool> sys::getHostCPUFeatures() { 2119 unsigned long hwcap = getauxval(AT_HWCAP); 2120 bool HasFPU = hwcap & (1UL << 3); // HWCAP_LOONGARCH_FPU 2121 uint32_t cpucfg2 = 0x2, cpucfg3 = 0x3; 2122 __asm__("cpucfg %[cpucfg2], %[cpucfg2]\n\t" : [cpucfg2] "+r"(cpucfg2)); 2123 __asm__("cpucfg %[cpucfg3], %[cpucfg3]\n\t" : [cpucfg3] "+r"(cpucfg3)); 2124 2125 StringMap<bool> Features; 2126 2127 Features["f"] = HasFPU && (cpucfg2 & (1U << 1)); // CPUCFG.2.FP_SP 2128 Features["d"] = HasFPU && (cpucfg2 & (1U << 2)); // CPUCFG.2.FP_DP 2129 2130 Features["lsx"] = hwcap & (1UL << 4); // HWCAP_LOONGARCH_LSX 2131 Features["lasx"] = hwcap & (1UL << 5); // HWCAP_LOONGARCH_LASX 2132 Features["lvz"] = hwcap & (1UL << 9); // HWCAP_LOONGARCH_LVZ 2133 2134 Features["frecipe"] = cpucfg2 & (1U << 25); // CPUCFG.2.FRECIPE 2135 Features["div32"] = cpucfg2 & (1U << 26); // CPUCFG.2.DIV32 2136 Features["lam-bh"] = cpucfg2 & (1U << 27); // CPUCFG.2.LAM_BH 2137 Features["lamcas"] = cpucfg2 & (1U << 28); // CPUCFG.2.LAMCAS 2138 Features["scq"] = cpucfg2 & (1U << 30); // CPUCFG.2.SCQ 2139 2140 Features["ld-seq-sa"] = cpucfg3 & (1U << 23); // CPUCFG.3.LD_SEQ_SA 2141 2142 // TODO: Need to complete. 2143 // Features["llacq-screl"] = cpucfg2 & (1U << 29); // CPUCFG.2.LLACQ_SCREL 2144 return Features; 2145 } 2146 #elif defined(__linux__) && defined(__riscv) 2147 // struct riscv_hwprobe 2148 struct RISCVHwProbe { 2149 int64_t Key; 2150 uint64_t Value; 2151 }; 2152 const StringMap<bool> sys::getHostCPUFeatures() { 2153 RISCVHwProbe Query[]{{/*RISCV_HWPROBE_KEY_BASE_BEHAVIOR=*/3, 0}, 2154 {/*RISCV_HWPROBE_KEY_IMA_EXT_0=*/4, 0}, 2155 {/*RISCV_HWPROBE_KEY_MISALIGNED_SCALAR_PERF=*/9, 0}}; 2156 int Ret = syscall(/*__NR_riscv_hwprobe=*/258, /*pairs=*/Query, 2157 /*pair_count=*/std::size(Query), /*cpu_count=*/0, 2158 /*cpus=*/0, /*flags=*/0); 2159 if (Ret != 0) 2160 return {}; 2161 2162 StringMap<bool> Features; 2163 uint64_t BaseMask = Query[0].Value; 2164 // Check whether RISCV_HWPROBE_BASE_BEHAVIOR_IMA is set. 2165 if (BaseMask & 1) { 2166 Features["i"] = true; 2167 Features["m"] = true; 2168 Features["a"] = true; 2169 } 2170 2171 uint64_t ExtMask = Query[1].Value; 2172 Features["f"] = ExtMask & (1 << 0); // RISCV_HWPROBE_IMA_FD 2173 Features["d"] = ExtMask & (1 << 0); // RISCV_HWPROBE_IMA_FD 2174 Features["c"] = ExtMask & (1 << 1); // RISCV_HWPROBE_IMA_C 2175 Features["v"] = ExtMask & (1 << 2); // RISCV_HWPROBE_IMA_V 2176 Features["zba"] = ExtMask & (1 << 3); // RISCV_HWPROBE_EXT_ZBA 2177 Features["zbb"] = ExtMask & (1 << 4); // RISCV_HWPROBE_EXT_ZBB 2178 Features["zbs"] = ExtMask & (1 << 5); // RISCV_HWPROBE_EXT_ZBS 2179 Features["zicboz"] = ExtMask & (1 << 6); // RISCV_HWPROBE_EXT_ZICBOZ 2180 Features["zbc"] = ExtMask & (1 << 7); // RISCV_HWPROBE_EXT_ZBC 2181 Features["zbkb"] = ExtMask & (1 << 8); // RISCV_HWPROBE_EXT_ZBKB 2182 Features["zbkc"] = ExtMask & (1 << 9); // RISCV_HWPROBE_EXT_ZBKC 2183 Features["zbkx"] = ExtMask & (1 << 10); // RISCV_HWPROBE_EXT_ZBKX 2184 Features["zknd"] = ExtMask & (1 << 11); // RISCV_HWPROBE_EXT_ZKND 2185 Features["zkne"] = ExtMask & (1 << 12); // RISCV_HWPROBE_EXT_ZKNE 2186 Features["zknh"] = ExtMask & (1 << 13); // RISCV_HWPROBE_EXT_ZKNH 2187 Features["zksed"] = ExtMask & (1 << 14); // RISCV_HWPROBE_EXT_ZKSED 2188 Features["zksh"] = ExtMask & (1 << 15); // RISCV_HWPROBE_EXT_ZKSH 2189 Features["zkt"] = ExtMask & (1 << 16); // RISCV_HWPROBE_EXT_ZKT 2190 Features["zvbb"] = ExtMask & (1 << 17); // RISCV_HWPROBE_EXT_ZVBB 2191 Features["zvbc"] = ExtMask & (1 << 18); // RISCV_HWPROBE_EXT_ZVBC 2192 Features["zvkb"] = ExtMask & (1 << 19); // RISCV_HWPROBE_EXT_ZVKB 2193 Features["zvkg"] = ExtMask & (1 << 20); // RISCV_HWPROBE_EXT_ZVKG 2194 Features["zvkned"] = ExtMask & (1 << 21); // RISCV_HWPROBE_EXT_ZVKNED 2195 Features["zvknha"] = ExtMask & (1 << 22); // RISCV_HWPROBE_EXT_ZVKNHA 2196 Features["zvknhb"] = ExtMask & (1 << 23); // RISCV_HWPROBE_EXT_ZVKNHB 2197 Features["zvksed"] = ExtMask & (1 << 24); // RISCV_HWPROBE_EXT_ZVKSED 2198 Features["zvksh"] = ExtMask & (1 << 25); // RISCV_HWPROBE_EXT_ZVKSH 2199 Features["zvkt"] = ExtMask & (1 << 26); // RISCV_HWPROBE_EXT_ZVKT 2200 Features["zfh"] = ExtMask & (1 << 27); // RISCV_HWPROBE_EXT_ZFH 2201 Features["zfhmin"] = ExtMask & (1 << 28); // RISCV_HWPROBE_EXT_ZFHMIN 2202 Features["zihintntl"] = ExtMask & (1 << 29); // RISCV_HWPROBE_EXT_ZIHINTNTL 2203 Features["zvfh"] = ExtMask & (1 << 30); // RISCV_HWPROBE_EXT_ZVFH 2204 Features["zvfhmin"] = ExtMask & (1ULL << 31); // RISCV_HWPROBE_EXT_ZVFHMIN 2205 Features["zfa"] = ExtMask & (1ULL << 32); // RISCV_HWPROBE_EXT_ZFA 2206 Features["ztso"] = ExtMask & (1ULL << 33); // RISCV_HWPROBE_EXT_ZTSO 2207 Features["zacas"] = ExtMask & (1ULL << 34); // RISCV_HWPROBE_EXT_ZACAS 2208 Features["zicond"] = ExtMask & (1ULL << 35); // RISCV_HWPROBE_EXT_ZICOND 2209 Features["zihintpause"] = 2210 ExtMask & (1ULL << 36); // RISCV_HWPROBE_EXT_ZIHINTPAUSE 2211 Features["zve32x"] = ExtMask & (1ULL << 37); // RISCV_HWPROBE_EXT_ZVE32X 2212 Features["zve32f"] = ExtMask & (1ULL << 38); // RISCV_HWPROBE_EXT_ZVE32F 2213 Features["zve64x"] = ExtMask & (1ULL << 39); // RISCV_HWPROBE_EXT_ZVE64X 2214 Features["zve64f"] = ExtMask & (1ULL << 40); // RISCV_HWPROBE_EXT_ZVE64F 2215 Features["zve64d"] = ExtMask & (1ULL << 41); // RISCV_HWPROBE_EXT_ZVE64D 2216 Features["zimop"] = ExtMask & (1ULL << 42); // RISCV_HWPROBE_EXT_ZIMOP 2217 Features["zca"] = ExtMask & (1ULL << 43); // RISCV_HWPROBE_EXT_ZCA 2218 Features["zcb"] = ExtMask & (1ULL << 44); // RISCV_HWPROBE_EXT_ZCB 2219 Features["zcd"] = ExtMask & (1ULL << 45); // RISCV_HWPROBE_EXT_ZCD 2220 Features["zcf"] = ExtMask & (1ULL << 46); // RISCV_HWPROBE_EXT_ZCF 2221 Features["zcmop"] = ExtMask & (1ULL << 47); // RISCV_HWPROBE_EXT_ZCMOP 2222 Features["zawrs"] = ExtMask & (1ULL << 48); // RISCV_HWPROBE_EXT_ZAWRS 2223 2224 // Check whether the processor supports fast misaligned scalar memory access. 2225 // NOTE: RISCV_HWPROBE_KEY_MISALIGNED_SCALAR_PERF is only available on 2226 // Linux 6.11 or later. If it is not recognized, the key field will be cleared 2227 // to -1. 2228 if (Query[2].Key != -1 && 2229 Query[2].Value == /*RISCV_HWPROBE_MISALIGNED_SCALAR_FAST=*/3) 2230 Features["unaligned-scalar-mem"] = true; 2231 2232 return Features; 2233 } 2234 #else 2235 const StringMap<bool> sys::getHostCPUFeatures() { return {}; } 2236 #endif 2237 2238 #if __APPLE__ 2239 /// \returns the \p triple, but with the Host's arch spliced in. 2240 static Triple withHostArch(Triple T) { 2241 #if defined(__arm__) 2242 T.setArch(Triple::arm); 2243 T.setArchName("arm"); 2244 #elif defined(__arm64e__) 2245 T.setArch(Triple::aarch64, Triple::AArch64SubArch_arm64e); 2246 T.setArchName("arm64e"); 2247 #elif defined(__aarch64__) 2248 T.setArch(Triple::aarch64); 2249 T.setArchName("arm64"); 2250 #elif defined(__x86_64h__) 2251 T.setArch(Triple::x86_64); 2252 T.setArchName("x86_64h"); 2253 #elif defined(__x86_64__) 2254 T.setArch(Triple::x86_64); 2255 T.setArchName("x86_64"); 2256 #elif defined(__i386__) 2257 T.setArch(Triple::x86); 2258 T.setArchName("i386"); 2259 #elif defined(__powerpc__) 2260 T.setArch(Triple::ppc); 2261 T.setArchName("powerpc"); 2262 #else 2263 # error "Unimplemented host arch fixup" 2264 #endif 2265 return T; 2266 } 2267 #endif 2268 2269 std::string sys::getProcessTriple() { 2270 std::string TargetTripleString = updateTripleOSVersion(LLVM_HOST_TRIPLE); 2271 Triple PT(Triple::normalize(TargetTripleString)); 2272 2273 #if __APPLE__ 2274 /// In Universal builds, LLVM_HOST_TRIPLE will have the wrong arch in one of 2275 /// the slices. This fixes that up. 2276 PT = withHostArch(PT); 2277 #endif 2278 2279 if (sizeof(void *) == 8 && PT.isArch32Bit()) 2280 PT = PT.get64BitArchVariant(); 2281 if (sizeof(void *) == 4 && PT.isArch64Bit()) 2282 PT = PT.get32BitArchVariant(); 2283 2284 return PT.str(); 2285 } 2286 2287 void sys::printDefaultTargetAndDetectedCPU(raw_ostream &OS) { 2288 #if LLVM_VERSION_PRINTER_SHOW_HOST_TARGET_INFO 2289 std::string CPU = std::string(sys::getHostCPUName()); 2290 if (CPU == "generic") 2291 CPU = "(unknown)"; 2292 OS << " Default target: " << sys::getDefaultTargetTriple() << '\n' 2293 << " Host CPU: " << CPU << '\n'; 2294 #endif 2295 } 2296