1 //===-- Host.cpp - Implement OS Host Concept --------------------*- 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 concept. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "llvm/Support/Host.h" 14 #include "llvm/ADT/SmallSet.h" 15 #include "llvm/ADT/SmallVector.h" 16 #include "llvm/ADT/StringMap.h" 17 #include "llvm/ADT/StringRef.h" 18 #include "llvm/ADT/StringSwitch.h" 19 #include "llvm/ADT/Triple.h" 20 #include "llvm/Config/llvm-config.h" 21 #include "llvm/Support/Debug.h" 22 #include "llvm/Support/FileSystem.h" 23 #include "llvm/Support/MemoryBuffer.h" 24 #include "llvm/Support/X86TargetParser.h" 25 #include "llvm/Support/raw_ostream.h" 26 #include <assert.h> 27 #include <string.h> 28 29 // Include the platform-specific parts of this class. 30 #ifdef LLVM_ON_UNIX 31 #include "Unix/Host.inc" 32 #include <sched.h> 33 #endif 34 #ifdef _WIN32 35 #include "Windows/Host.inc" 36 #endif 37 #ifdef _MSC_VER 38 #include <intrin.h> 39 #endif 40 #if defined(__APPLE__) && (!defined(__x86_64__)) 41 #include <mach/host_info.h> 42 #include <mach/mach.h> 43 #include <mach/mach_host.h> 44 #include <mach/machine.h> 45 #endif 46 #ifdef _AIX 47 #include <sys/systemcfg.h> 48 #endif 49 50 #define DEBUG_TYPE "host-detection" 51 52 //===----------------------------------------------------------------------===// 53 // 54 // Implementations of the CPU detection routines 55 // 56 //===----------------------------------------------------------------------===// 57 58 using namespace llvm; 59 60 static std::unique_ptr<llvm::MemoryBuffer> 61 LLVM_ATTRIBUTE_UNUSED getProcCpuinfoContent() { 62 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text = 63 llvm::MemoryBuffer::getFileAsStream("/proc/cpuinfo"); 64 if (std::error_code EC = Text.getError()) { 65 llvm::errs() << "Can't read " 66 << "/proc/cpuinfo: " << EC.message() << "\n"; 67 return nullptr; 68 } 69 return std::move(*Text); 70 } 71 72 StringRef sys::detail::getHostCPUNameForPowerPC(StringRef ProcCpuinfoContent) { 73 // Access to the Processor Version Register (PVR) on PowerPC is privileged, 74 // and so we must use an operating-system interface to determine the current 75 // processor type. On Linux, this is exposed through the /proc/cpuinfo file. 76 const char *generic = "generic"; 77 78 // The cpu line is second (after the 'processor: 0' line), so if this 79 // buffer is too small then something has changed (or is wrong). 80 StringRef::const_iterator CPUInfoStart = ProcCpuinfoContent.begin(); 81 StringRef::const_iterator CPUInfoEnd = ProcCpuinfoContent.end(); 82 83 StringRef::const_iterator CIP = CPUInfoStart; 84 85 StringRef::const_iterator CPUStart = 0; 86 size_t CPULen = 0; 87 88 // We need to find the first line which starts with cpu, spaces, and a colon. 89 // After the colon, there may be some additional spaces and then the cpu type. 90 while (CIP < CPUInfoEnd && CPUStart == 0) { 91 if (CIP < CPUInfoEnd && *CIP == '\n') 92 ++CIP; 93 94 if (CIP < CPUInfoEnd && *CIP == 'c') { 95 ++CIP; 96 if (CIP < CPUInfoEnd && *CIP == 'p') { 97 ++CIP; 98 if (CIP < CPUInfoEnd && *CIP == 'u') { 99 ++CIP; 100 while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t')) 101 ++CIP; 102 103 if (CIP < CPUInfoEnd && *CIP == ':') { 104 ++CIP; 105 while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t')) 106 ++CIP; 107 108 if (CIP < CPUInfoEnd) { 109 CPUStart = CIP; 110 while (CIP < CPUInfoEnd && (*CIP != ' ' && *CIP != '\t' && 111 *CIP != ',' && *CIP != '\n')) 112 ++CIP; 113 CPULen = CIP - CPUStart; 114 } 115 } 116 } 117 } 118 } 119 120 if (CPUStart == 0) 121 while (CIP < CPUInfoEnd && *CIP != '\n') 122 ++CIP; 123 } 124 125 if (CPUStart == 0) 126 return generic; 127 128 return StringSwitch<const char *>(StringRef(CPUStart, CPULen)) 129 .Case("604e", "604e") 130 .Case("604", "604") 131 .Case("7400", "7400") 132 .Case("7410", "7400") 133 .Case("7447", "7400") 134 .Case("7455", "7450") 135 .Case("G4", "g4") 136 .Case("POWER4", "970") 137 .Case("PPC970FX", "970") 138 .Case("PPC970MP", "970") 139 .Case("G5", "g5") 140 .Case("POWER5", "g5") 141 .Case("A2", "a2") 142 .Case("POWER6", "pwr6") 143 .Case("POWER7", "pwr7") 144 .Case("POWER8", "pwr8") 145 .Case("POWER8E", "pwr8") 146 .Case("POWER8NVL", "pwr8") 147 .Case("POWER9", "pwr9") 148 .Case("POWER10", "pwr10") 149 // FIXME: If we get a simulator or machine with the capabilities of 150 // mcpu=future, we should revisit this and add the name reported by the 151 // simulator/machine. 152 .Default(generic); 153 } 154 155 StringRef sys::detail::getHostCPUNameForARM(StringRef ProcCpuinfoContent) { 156 // The cpuid register on arm is not accessible from user space. On Linux, 157 // it is exposed through the /proc/cpuinfo file. 158 159 // Read 32 lines from /proc/cpuinfo, which should contain the CPU part line 160 // in all cases. 161 SmallVector<StringRef, 32> Lines; 162 ProcCpuinfoContent.split(Lines, "\n"); 163 164 // Look for the CPU implementer line. 165 StringRef Implementer; 166 StringRef Hardware; 167 StringRef Part; 168 for (unsigned I = 0, E = Lines.size(); I != E; ++I) { 169 if (Lines[I].startswith("CPU implementer")) 170 Implementer = Lines[I].substr(15).ltrim("\t :"); 171 if (Lines[I].startswith("Hardware")) 172 Hardware = Lines[I].substr(8).ltrim("\t :"); 173 if (Lines[I].startswith("CPU part")) 174 Part = Lines[I].substr(8).ltrim("\t :"); 175 } 176 177 if (Implementer == "0x41") { // ARM Ltd. 178 // MSM8992/8994 may give cpu part for the core that the kernel is running on, 179 // which is undeterministic and wrong. Always return cortex-a53 for these SoC. 180 if (Hardware.endswith("MSM8994") || Hardware.endswith("MSM8996")) 181 return "cortex-a53"; 182 183 184 // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The 185 // values correspond to the "Part number" in the CP15/c0 register. The 186 // contents are specified in the various processor manuals. 187 // This corresponds to the Main ID Register in Technical Reference Manuals. 188 // and is used in programs like sys-utils 189 return StringSwitch<const char *>(Part) 190 .Case("0x926", "arm926ej-s") 191 .Case("0xb02", "mpcore") 192 .Case("0xb36", "arm1136j-s") 193 .Case("0xb56", "arm1156t2-s") 194 .Case("0xb76", "arm1176jz-s") 195 .Case("0xc08", "cortex-a8") 196 .Case("0xc09", "cortex-a9") 197 .Case("0xc0f", "cortex-a15") 198 .Case("0xc20", "cortex-m0") 199 .Case("0xc23", "cortex-m3") 200 .Case("0xc24", "cortex-m4") 201 .Case("0xd22", "cortex-m55") 202 .Case("0xd02", "cortex-a34") 203 .Case("0xd04", "cortex-a35") 204 .Case("0xd03", "cortex-a53") 205 .Case("0xd07", "cortex-a57") 206 .Case("0xd08", "cortex-a72") 207 .Case("0xd09", "cortex-a73") 208 .Case("0xd0a", "cortex-a75") 209 .Case("0xd0b", "cortex-a76") 210 .Case("0xd0d", "cortex-a77") 211 .Case("0xd41", "cortex-a78") 212 .Case("0xd44", "cortex-x1") 213 .Case("0xd0c", "neoverse-n1") 214 .Case("0xd49", "neoverse-n2") 215 .Default("generic"); 216 } 217 218 if (Implementer == "0x42" || Implementer == "0x43") { // Broadcom | Cavium. 219 return StringSwitch<const char *>(Part) 220 .Case("0x516", "thunderx2t99") 221 .Case("0x0516", "thunderx2t99") 222 .Case("0xaf", "thunderx2t99") 223 .Case("0x0af", "thunderx2t99") 224 .Case("0xa1", "thunderxt88") 225 .Case("0x0a1", "thunderxt88") 226 .Default("generic"); 227 } 228 229 if (Implementer == "0x46") { // Fujitsu Ltd. 230 return StringSwitch<const char *>(Part) 231 .Case("0x001", "a64fx") 232 .Default("generic"); 233 } 234 235 if (Implementer == "0x4e") { // NVIDIA Corporation 236 return StringSwitch<const char *>(Part) 237 .Case("0x004", "carmel") 238 .Default("generic"); 239 } 240 241 if (Implementer == "0x48") // HiSilicon Technologies, Inc. 242 // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The 243 // values correspond to the "Part number" in the CP15/c0 register. The 244 // contents are specified in the various processor manuals. 245 return StringSwitch<const char *>(Part) 246 .Case("0xd01", "tsv110") 247 .Default("generic"); 248 249 if (Implementer == "0x51") // Qualcomm Technologies, Inc. 250 // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The 251 // values correspond to the "Part number" in the CP15/c0 register. The 252 // contents are specified in the various processor manuals. 253 return StringSwitch<const char *>(Part) 254 .Case("0x06f", "krait") // APQ8064 255 .Case("0x201", "kryo") 256 .Case("0x205", "kryo") 257 .Case("0x211", "kryo") 258 .Case("0x800", "cortex-a73") // Kryo 2xx Gold 259 .Case("0x801", "cortex-a73") // Kryo 2xx Silver 260 .Case("0x802", "cortex-a75") // Kryo 3xx Gold 261 .Case("0x803", "cortex-a75") // Kryo 3xx Silver 262 .Case("0x804", "cortex-a76") // Kryo 4xx Gold 263 .Case("0x805", "cortex-a76") // Kryo 4xx/5xx Silver 264 .Case("0xc00", "falkor") 265 .Case("0xc01", "saphira") 266 .Default("generic"); 267 if (Implementer == "0x53") { // Samsung Electronics Co., Ltd. 268 // The Exynos chips have a convoluted ID scheme that doesn't seem to follow 269 // any predictive pattern across variants and parts. 270 unsigned Variant = 0, Part = 0; 271 272 // Look for the CPU variant line, whose value is a 1 digit hexadecimal 273 // number, corresponding to the Variant bits in the CP15/C0 register. 274 for (auto I : Lines) 275 if (I.consume_front("CPU variant")) 276 I.ltrim("\t :").getAsInteger(0, Variant); 277 278 // Look for the CPU part line, whose value is a 3 digit hexadecimal 279 // number, corresponding to the PartNum bits in the CP15/C0 register. 280 for (auto I : Lines) 281 if (I.consume_front("CPU part")) 282 I.ltrim("\t :").getAsInteger(0, Part); 283 284 unsigned Exynos = (Variant << 12) | Part; 285 switch (Exynos) { 286 default: 287 // Default by falling through to Exynos M3. 288 LLVM_FALLTHROUGH; 289 case 0x1002: 290 return "exynos-m3"; 291 case 0x1003: 292 return "exynos-m4"; 293 } 294 } 295 296 return "generic"; 297 } 298 299 StringRef sys::detail::getHostCPUNameForS390x(StringRef ProcCpuinfoContent) { 300 // STIDP is a privileged operation, so use /proc/cpuinfo instead. 301 302 // The "processor 0:" line comes after a fair amount of other information, 303 // including a cache breakdown, but this should be plenty. 304 SmallVector<StringRef, 32> Lines; 305 ProcCpuinfoContent.split(Lines, "\n"); 306 307 // Look for the CPU features. 308 SmallVector<StringRef, 32> CPUFeatures; 309 for (unsigned I = 0, E = Lines.size(); I != E; ++I) 310 if (Lines[I].startswith("features")) { 311 size_t Pos = Lines[I].find(':'); 312 if (Pos != StringRef::npos) { 313 Lines[I].drop_front(Pos + 1).split(CPUFeatures, ' '); 314 break; 315 } 316 } 317 318 // We need to check for the presence of vector support independently of 319 // the machine type, since we may only use the vector register set when 320 // supported by the kernel (and hypervisor). 321 bool HaveVectorSupport = false; 322 for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) { 323 if (CPUFeatures[I] == "vx") 324 HaveVectorSupport = true; 325 } 326 327 // Now check the processor machine type. 328 for (unsigned I = 0, E = Lines.size(); I != E; ++I) { 329 if (Lines[I].startswith("processor ")) { 330 size_t Pos = Lines[I].find("machine = "); 331 if (Pos != StringRef::npos) { 332 Pos += sizeof("machine = ") - 1; 333 unsigned int Id; 334 if (!Lines[I].drop_front(Pos).getAsInteger(10, Id)) { 335 if (Id >= 8561 && HaveVectorSupport) 336 return "z15"; 337 if (Id >= 3906 && HaveVectorSupport) 338 return "z14"; 339 if (Id >= 2964 && HaveVectorSupport) 340 return "z13"; 341 if (Id >= 2827) 342 return "zEC12"; 343 if (Id >= 2817) 344 return "z196"; 345 } 346 } 347 break; 348 } 349 } 350 351 return "generic"; 352 } 353 354 StringRef sys::detail::getHostCPUNameForBPF() { 355 #if !defined(__linux__) || !defined(__x86_64__) 356 return "generic"; 357 #else 358 uint8_t v3_insns[40] __attribute__ ((aligned (8))) = 359 /* BPF_MOV64_IMM(BPF_REG_0, 0) */ 360 { 0xb7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 361 /* BPF_MOV64_IMM(BPF_REG_2, 1) */ 362 0xb7, 0x2, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 363 /* BPF_JMP32_REG(BPF_JLT, BPF_REG_0, BPF_REG_2, 1) */ 364 0xae, 0x20, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 365 /* BPF_MOV64_IMM(BPF_REG_0, 1) */ 366 0xb7, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 367 /* BPF_EXIT_INSN() */ 368 0x95, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }; 369 370 uint8_t v2_insns[40] __attribute__ ((aligned (8))) = 371 /* BPF_MOV64_IMM(BPF_REG_0, 0) */ 372 { 0xb7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 373 /* BPF_MOV64_IMM(BPF_REG_2, 1) */ 374 0xb7, 0x2, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 375 /* BPF_JMP_REG(BPF_JLT, BPF_REG_0, BPF_REG_2, 1) */ 376 0xad, 0x20, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 377 /* BPF_MOV64_IMM(BPF_REG_0, 1) */ 378 0xb7, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 379 /* BPF_EXIT_INSN() */ 380 0x95, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }; 381 382 struct bpf_prog_load_attr { 383 uint32_t prog_type; 384 uint32_t insn_cnt; 385 uint64_t insns; 386 uint64_t license; 387 uint32_t log_level; 388 uint32_t log_size; 389 uint64_t log_buf; 390 uint32_t kern_version; 391 uint32_t prog_flags; 392 } attr = {}; 393 attr.prog_type = 1; /* BPF_PROG_TYPE_SOCKET_FILTER */ 394 attr.insn_cnt = 5; 395 attr.insns = (uint64_t)v3_insns; 396 attr.license = (uint64_t)"DUMMY"; 397 398 int fd = syscall(321 /* __NR_bpf */, 5 /* BPF_PROG_LOAD */, &attr, 399 sizeof(attr)); 400 if (fd >= 0) { 401 close(fd); 402 return "v3"; 403 } 404 405 /* Clear the whole attr in case its content changed by syscall. */ 406 memset(&attr, 0, sizeof(attr)); 407 attr.prog_type = 1; /* BPF_PROG_TYPE_SOCKET_FILTER */ 408 attr.insn_cnt = 5; 409 attr.insns = (uint64_t)v2_insns; 410 attr.license = (uint64_t)"DUMMY"; 411 fd = syscall(321 /* __NR_bpf */, 5 /* BPF_PROG_LOAD */, &attr, sizeof(attr)); 412 if (fd >= 0) { 413 close(fd); 414 return "v2"; 415 } 416 return "v1"; 417 #endif 418 } 419 420 #if defined(__i386__) || defined(_M_IX86) || \ 421 defined(__x86_64__) || defined(_M_X64) 422 423 enum VendorSignatures { 424 SIG_INTEL = 0x756e6547 /* Genu */, 425 SIG_AMD = 0x68747541 /* Auth */ 426 }; 427 428 // The check below for i386 was copied from clang's cpuid.h (__get_cpuid_max). 429 // Check motivated by bug reports for OpenSSL crashing on CPUs without CPUID 430 // support. Consequently, for i386, the presence of CPUID is checked first 431 // via the corresponding eflags bit. 432 // Removal of cpuid.h header motivated by PR30384 433 // Header cpuid.h and method __get_cpuid_max are not used in llvm, clang, openmp 434 // or test-suite, but are used in external projects e.g. libstdcxx 435 static bool isCpuIdSupported() { 436 #if defined(__GNUC__) || defined(__clang__) 437 #if defined(__i386__) 438 int __cpuid_supported; 439 __asm__(" pushfl\n" 440 " popl %%eax\n" 441 " movl %%eax,%%ecx\n" 442 " xorl $0x00200000,%%eax\n" 443 " pushl %%eax\n" 444 " popfl\n" 445 " pushfl\n" 446 " popl %%eax\n" 447 " movl $0,%0\n" 448 " cmpl %%eax,%%ecx\n" 449 " je 1f\n" 450 " movl $1,%0\n" 451 "1:" 452 : "=r"(__cpuid_supported) 453 : 454 : "eax", "ecx"); 455 if (!__cpuid_supported) 456 return false; 457 #endif 458 return true; 459 #endif 460 return true; 461 } 462 463 /// getX86CpuIDAndInfo - Execute the specified cpuid and return the 4 values in 464 /// the specified arguments. If we can't run cpuid on the host, return true. 465 static bool getX86CpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX, 466 unsigned *rECX, unsigned *rEDX) { 467 #if defined(__GNUC__) || defined(__clang__) 468 #if defined(__x86_64__) 469 // gcc doesn't know cpuid would clobber ebx/rbx. Preserve it manually. 470 // FIXME: should we save this for Clang? 471 __asm__("movq\t%%rbx, %%rsi\n\t" 472 "cpuid\n\t" 473 "xchgq\t%%rbx, %%rsi\n\t" 474 : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX) 475 : "a"(value)); 476 return false; 477 #elif defined(__i386__) 478 __asm__("movl\t%%ebx, %%esi\n\t" 479 "cpuid\n\t" 480 "xchgl\t%%ebx, %%esi\n\t" 481 : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX) 482 : "a"(value)); 483 return false; 484 #else 485 return true; 486 #endif 487 #elif defined(_MSC_VER) 488 // The MSVC intrinsic is portable across x86 and x64. 489 int registers[4]; 490 __cpuid(registers, value); 491 *rEAX = registers[0]; 492 *rEBX = registers[1]; 493 *rECX = registers[2]; 494 *rEDX = registers[3]; 495 return false; 496 #else 497 return true; 498 #endif 499 } 500 501 /// getX86CpuIDAndInfoEx - Execute the specified cpuid with subleaf and return 502 /// the 4 values in the specified arguments. If we can't run cpuid on the host, 503 /// return true. 504 static bool getX86CpuIDAndInfoEx(unsigned value, unsigned subleaf, 505 unsigned *rEAX, unsigned *rEBX, unsigned *rECX, 506 unsigned *rEDX) { 507 #if defined(__GNUC__) || defined(__clang__) 508 #if defined(__x86_64__) 509 // gcc doesn't know cpuid would clobber ebx/rbx. Preserve it manually. 510 // FIXME: should we save this for Clang? 511 __asm__("movq\t%%rbx, %%rsi\n\t" 512 "cpuid\n\t" 513 "xchgq\t%%rbx, %%rsi\n\t" 514 : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX) 515 : "a"(value), "c"(subleaf)); 516 return false; 517 #elif defined(__i386__) 518 __asm__("movl\t%%ebx, %%esi\n\t" 519 "cpuid\n\t" 520 "xchgl\t%%ebx, %%esi\n\t" 521 : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX) 522 : "a"(value), "c"(subleaf)); 523 return false; 524 #else 525 return true; 526 #endif 527 #elif defined(_MSC_VER) 528 int registers[4]; 529 __cpuidex(registers, value, subleaf); 530 *rEAX = registers[0]; 531 *rEBX = registers[1]; 532 *rECX = registers[2]; 533 *rEDX = registers[3]; 534 return false; 535 #else 536 return true; 537 #endif 538 } 539 540 // Read control register 0 (XCR0). Used to detect features such as AVX. 541 static bool getX86XCR0(unsigned *rEAX, unsigned *rEDX) { 542 #if defined(__GNUC__) || defined(__clang__) 543 // Check xgetbv; this uses a .byte sequence instead of the instruction 544 // directly because older assemblers do not include support for xgetbv and 545 // there is no easy way to conditionally compile based on the assembler used. 546 __asm__(".byte 0x0f, 0x01, 0xd0" : "=a"(*rEAX), "=d"(*rEDX) : "c"(0)); 547 return false; 548 #elif defined(_MSC_FULL_VER) && defined(_XCR_XFEATURE_ENABLED_MASK) 549 unsigned long long Result = _xgetbv(_XCR_XFEATURE_ENABLED_MASK); 550 *rEAX = Result; 551 *rEDX = Result >> 32; 552 return false; 553 #else 554 return true; 555 #endif 556 } 557 558 static void detectX86FamilyModel(unsigned EAX, unsigned *Family, 559 unsigned *Model) { 560 *Family = (EAX >> 8) & 0xf; // Bits 8 - 11 561 *Model = (EAX >> 4) & 0xf; // Bits 4 - 7 562 if (*Family == 6 || *Family == 0xf) { 563 if (*Family == 0xf) 564 // Examine extended family ID if family ID is F. 565 *Family += (EAX >> 20) & 0xff; // Bits 20 - 27 566 // Examine extended model ID if family ID is 6 or F. 567 *Model += ((EAX >> 16) & 0xf) << 4; // Bits 16 - 19 568 } 569 } 570 571 static StringRef 572 getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model, 573 const unsigned *Features, 574 unsigned *Type, unsigned *Subtype) { 575 auto testFeature = [&](unsigned F) { 576 return (Features[F / 32] & (1U << (F % 32))) != 0; 577 }; 578 579 StringRef CPU; 580 581 switch (Family) { 582 case 3: 583 CPU = "i386"; 584 break; 585 case 4: 586 CPU = "i486"; 587 break; 588 case 5: 589 if (testFeature(X86::FEATURE_MMX)) { 590 CPU = "pentium-mmx"; 591 break; 592 } 593 CPU = "pentium"; 594 break; 595 case 6: 596 switch (Model) { 597 case 0x0f: // Intel Core 2 Duo processor, Intel Core 2 Duo mobile 598 // processor, Intel Core 2 Quad processor, Intel Core 2 Quad 599 // mobile processor, Intel Core 2 Extreme processor, Intel 600 // Pentium Dual-Core processor, Intel Xeon processor, model 601 // 0Fh. All processors are manufactured using the 65 nm process. 602 case 0x16: // Intel Celeron processor model 16h. All processors are 603 // manufactured using the 65 nm process 604 CPU = "core2"; 605 *Type = X86::INTEL_CORE2; 606 break; 607 case 0x17: // Intel Core 2 Extreme processor, Intel Xeon processor, model 608 // 17h. All processors are manufactured using the 45 nm process. 609 // 610 // 45nm: Penryn , Wolfdale, Yorkfield (XE) 611 case 0x1d: // Intel Xeon processor MP. All processors are manufactured using 612 // the 45 nm process. 613 CPU = "penryn"; 614 *Type = X86::INTEL_CORE2; 615 break; 616 case 0x1a: // Intel Core i7 processor and Intel Xeon processor. All 617 // processors are manufactured using the 45 nm process. 618 case 0x1e: // Intel(R) Core(TM) i7 CPU 870 @ 2.93GHz. 619 // As found in a Summer 2010 model iMac. 620 case 0x1f: 621 case 0x2e: // Nehalem EX 622 CPU = "nehalem"; 623 *Type = X86::INTEL_COREI7; 624 *Subtype = X86::INTEL_COREI7_NEHALEM; 625 break; 626 case 0x25: // Intel Core i7, laptop version. 627 case 0x2c: // Intel Core i7 processor and Intel Xeon processor. All 628 // processors are manufactured using the 32 nm process. 629 case 0x2f: // Westmere EX 630 CPU = "westmere"; 631 *Type = X86::INTEL_COREI7; 632 *Subtype = X86::INTEL_COREI7_WESTMERE; 633 break; 634 case 0x2a: // Intel Core i7 processor. All processors are manufactured 635 // using the 32 nm process. 636 case 0x2d: 637 CPU = "sandybridge"; 638 *Type = X86::INTEL_COREI7; 639 *Subtype = X86::INTEL_COREI7_SANDYBRIDGE; 640 break; 641 case 0x3a: 642 case 0x3e: // Ivy Bridge EP 643 CPU = "ivybridge"; 644 *Type = X86::INTEL_COREI7; 645 *Subtype = X86::INTEL_COREI7_IVYBRIDGE; 646 break; 647 648 // Haswell: 649 case 0x3c: 650 case 0x3f: 651 case 0x45: 652 case 0x46: 653 CPU = "haswell"; 654 *Type = X86::INTEL_COREI7; 655 *Subtype = X86::INTEL_COREI7_HASWELL; 656 break; 657 658 // Broadwell: 659 case 0x3d: 660 case 0x47: 661 case 0x4f: 662 case 0x56: 663 CPU = "broadwell"; 664 *Type = X86::INTEL_COREI7; 665 *Subtype = X86::INTEL_COREI7_BROADWELL; 666 break; 667 668 // Skylake: 669 case 0x4e: // Skylake mobile 670 case 0x5e: // Skylake desktop 671 case 0x8e: // Kaby Lake mobile 672 case 0x9e: // Kaby Lake desktop 673 case 0xa5: // Comet Lake-H/S 674 case 0xa6: // Comet Lake-U 675 CPU = "skylake"; 676 *Type = X86::INTEL_COREI7; 677 *Subtype = X86::INTEL_COREI7_SKYLAKE; 678 break; 679 680 // Skylake Xeon: 681 case 0x55: 682 *Type = X86::INTEL_COREI7; 683 if (testFeature(X86::FEATURE_AVX512BF16)) { 684 CPU = "cooperlake"; 685 *Subtype = X86::INTEL_COREI7_COOPERLAKE; 686 } else if (testFeature(X86::FEATURE_AVX512VNNI)) { 687 CPU = "cascadelake"; 688 *Subtype = X86::INTEL_COREI7_CASCADELAKE; 689 } else { 690 CPU = "skylake-avx512"; 691 *Subtype = X86::INTEL_COREI7_SKYLAKE_AVX512; 692 } 693 break; 694 695 // Cannonlake: 696 case 0x66: 697 CPU = "cannonlake"; 698 *Type = X86::INTEL_COREI7; 699 *Subtype = X86::INTEL_COREI7_CANNONLAKE; 700 break; 701 702 // Icelake: 703 case 0x7d: 704 case 0x7e: 705 CPU = "icelake-client"; 706 *Type = X86::INTEL_COREI7; 707 *Subtype = X86::INTEL_COREI7_ICELAKE_CLIENT; 708 break; 709 710 // Icelake Xeon: 711 case 0x6a: 712 case 0x6c: 713 CPU = "icelake-server"; 714 *Type = X86::INTEL_COREI7; 715 *Subtype = X86::INTEL_COREI7_ICELAKE_SERVER; 716 break; 717 718 // Sapphire Rapids: 719 case 0x8f: 720 CPU = "sapphirerapids"; 721 *Type = X86::INTEL_COREI7; 722 *Subtype = X86::INTEL_COREI7_SAPPHIRERAPIDS; 723 break; 724 725 case 0x1c: // Most 45 nm Intel Atom processors 726 case 0x26: // 45 nm Atom Lincroft 727 case 0x27: // 32 nm Atom Medfield 728 case 0x35: // 32 nm Atom Midview 729 case 0x36: // 32 nm Atom Midview 730 CPU = "bonnell"; 731 *Type = X86::INTEL_BONNELL; 732 break; 733 734 // Atom Silvermont codes from the Intel software optimization guide. 735 case 0x37: 736 case 0x4a: 737 case 0x4d: 738 case 0x5a: 739 case 0x5d: 740 case 0x4c: // really airmont 741 CPU = "silvermont"; 742 *Type = X86::INTEL_SILVERMONT; 743 break; 744 // Goldmont: 745 case 0x5c: // Apollo Lake 746 case 0x5f: // Denverton 747 CPU = "goldmont"; 748 *Type = X86::INTEL_GOLDMONT; 749 break; 750 case 0x7a: 751 CPU = "goldmont-plus"; 752 *Type = X86::INTEL_GOLDMONT_PLUS; 753 break; 754 case 0x86: 755 CPU = "tremont"; 756 *Type = X86::INTEL_TREMONT; 757 break; 758 759 // Xeon Phi (Knights Landing + Knights Mill): 760 case 0x57: 761 CPU = "knl"; 762 *Type = X86::INTEL_KNL; 763 break; 764 case 0x85: 765 CPU = "knm"; 766 *Type = X86::INTEL_KNM; 767 break; 768 769 default: // Unknown family 6 CPU, try to guess. 770 // Don't both with Type/Subtype here, they aren't used by the caller. 771 // They're used above to keep the code in sync with compiler-rt. 772 // TODO detect tigerlake host from model 773 if (testFeature(X86::FEATURE_AVX512VP2INTERSECT)) { 774 CPU = "tigerlake"; 775 } else if (testFeature(X86::FEATURE_AVX512VBMI2)) { 776 CPU = "icelake-client"; 777 } else if (testFeature(X86::FEATURE_AVX512VBMI)) { 778 CPU = "cannonlake"; 779 } else if (testFeature(X86::FEATURE_AVX512BF16)) { 780 CPU = "cooperlake"; 781 } else if (testFeature(X86::FEATURE_AVX512VNNI)) { 782 CPU = "cascadelake"; 783 } else if (testFeature(X86::FEATURE_AVX512VL)) { 784 CPU = "skylake-avx512"; 785 } else if (testFeature(X86::FEATURE_AVX512ER)) { 786 CPU = "knl"; 787 } else if (testFeature(X86::FEATURE_CLFLUSHOPT)) { 788 if (testFeature(X86::FEATURE_SHA)) 789 CPU = "goldmont"; 790 else 791 CPU = "skylake"; 792 } else if (testFeature(X86::FEATURE_ADX)) { 793 CPU = "broadwell"; 794 } else if (testFeature(X86::FEATURE_AVX2)) { 795 CPU = "haswell"; 796 } else if (testFeature(X86::FEATURE_AVX)) { 797 CPU = "sandybridge"; 798 } else if (testFeature(X86::FEATURE_SSE4_2)) { 799 if (testFeature(X86::FEATURE_MOVBE)) 800 CPU = "silvermont"; 801 else 802 CPU = "nehalem"; 803 } else if (testFeature(X86::FEATURE_SSE4_1)) { 804 CPU = "penryn"; 805 } else if (testFeature(X86::FEATURE_SSSE3)) { 806 if (testFeature(X86::FEATURE_MOVBE)) 807 CPU = "bonnell"; 808 else 809 CPU = "core2"; 810 } else if (testFeature(X86::FEATURE_64BIT)) { 811 CPU = "core2"; 812 } else if (testFeature(X86::FEATURE_SSE3)) { 813 CPU = "yonah"; 814 } else if (testFeature(X86::FEATURE_SSE2)) { 815 CPU = "pentium-m"; 816 } else if (testFeature(X86::FEATURE_SSE)) { 817 CPU = "pentium3"; 818 } else if (testFeature(X86::FEATURE_MMX)) { 819 CPU = "pentium2"; 820 } else { 821 CPU = "pentiumpro"; 822 } 823 break; 824 } 825 break; 826 case 15: { 827 if (testFeature(X86::FEATURE_64BIT)) { 828 CPU = "nocona"; 829 break; 830 } 831 if (testFeature(X86::FEATURE_SSE3)) { 832 CPU = "prescott"; 833 break; 834 } 835 CPU = "pentium4"; 836 break; 837 } 838 default: 839 break; // Unknown. 840 } 841 842 return CPU; 843 } 844 845 static StringRef 846 getAMDProcessorTypeAndSubtype(unsigned Family, unsigned Model, 847 const unsigned *Features, 848 unsigned *Type, unsigned *Subtype) { 849 auto testFeature = [&](unsigned F) { 850 return (Features[F / 32] & (1U << (F % 32))) != 0; 851 }; 852 853 StringRef CPU; 854 855 switch (Family) { 856 case 4: 857 CPU = "i486"; 858 break; 859 case 5: 860 CPU = "pentium"; 861 switch (Model) { 862 case 6: 863 case 7: 864 CPU = "k6"; 865 break; 866 case 8: 867 CPU = "k6-2"; 868 break; 869 case 9: 870 case 13: 871 CPU = "k6-3"; 872 break; 873 case 10: 874 CPU = "geode"; 875 break; 876 } 877 break; 878 case 6: 879 if (testFeature(X86::FEATURE_SSE)) { 880 CPU = "athlon-xp"; 881 break; 882 } 883 CPU = "athlon"; 884 break; 885 case 15: 886 if (testFeature(X86::FEATURE_SSE3)) { 887 CPU = "k8-sse3"; 888 break; 889 } 890 CPU = "k8"; 891 break; 892 case 16: 893 CPU = "amdfam10"; 894 *Type = X86::AMDFAM10H; // "amdfam10" 895 switch (Model) { 896 case 2: 897 *Subtype = X86::AMDFAM10H_BARCELONA; 898 break; 899 case 4: 900 *Subtype = X86::AMDFAM10H_SHANGHAI; 901 break; 902 case 8: 903 *Subtype = X86::AMDFAM10H_ISTANBUL; 904 break; 905 } 906 break; 907 case 20: 908 CPU = "btver1"; 909 *Type = X86::AMD_BTVER1; 910 break; 911 case 21: 912 CPU = "bdver1"; 913 *Type = X86::AMDFAM15H; 914 if (Model >= 0x60 && Model <= 0x7f) { 915 CPU = "bdver4"; 916 *Subtype = X86::AMDFAM15H_BDVER4; 917 break; // 60h-7Fh: Excavator 918 } 919 if (Model >= 0x30 && Model <= 0x3f) { 920 CPU = "bdver3"; 921 *Subtype = X86::AMDFAM15H_BDVER3; 922 break; // 30h-3Fh: Steamroller 923 } 924 if ((Model >= 0x10 && Model <= 0x1f) || Model == 0x02) { 925 CPU = "bdver2"; 926 *Subtype = X86::AMDFAM15H_BDVER2; 927 break; // 02h, 10h-1Fh: Piledriver 928 } 929 if (Model <= 0x0f) { 930 *Subtype = X86::AMDFAM15H_BDVER1; 931 break; // 00h-0Fh: Bulldozer 932 } 933 break; 934 case 22: 935 CPU = "btver2"; 936 *Type = X86::AMD_BTVER2; 937 break; 938 case 23: 939 CPU = "znver1"; 940 *Type = X86::AMDFAM17H; 941 if ((Model >= 0x30 && Model <= 0x3f) || Model == 0x71) { 942 CPU = "znver2"; 943 *Subtype = X86::AMDFAM17H_ZNVER2; 944 break; // 30h-3fh, 71h: Zen2 945 } 946 if (Model <= 0x0f) { 947 *Subtype = X86::AMDFAM17H_ZNVER1; 948 break; // 00h-0Fh: Zen1 949 } 950 break; 951 case 25: 952 CPU = "znver3"; 953 *Type = X86::AMDFAM19H; 954 if (Model <= 0x0f) { 955 *Subtype = X86::AMDFAM19H_ZNVER3; 956 break; // 00h-0Fh: Zen3 957 } 958 break; 959 default: 960 break; // Unknown AMD CPU. 961 } 962 963 return CPU; 964 } 965 966 static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf, 967 unsigned *Features) { 968 unsigned EAX, EBX; 969 970 auto setFeature = [&](unsigned F) { 971 Features[F / 32] |= 1U << (F % 32); 972 }; 973 974 if ((EDX >> 15) & 1) 975 setFeature(X86::FEATURE_CMOV); 976 if ((EDX >> 23) & 1) 977 setFeature(X86::FEATURE_MMX); 978 if ((EDX >> 25) & 1) 979 setFeature(X86::FEATURE_SSE); 980 if ((EDX >> 26) & 1) 981 setFeature(X86::FEATURE_SSE2); 982 983 if ((ECX >> 0) & 1) 984 setFeature(X86::FEATURE_SSE3); 985 if ((ECX >> 1) & 1) 986 setFeature(X86::FEATURE_PCLMUL); 987 if ((ECX >> 9) & 1) 988 setFeature(X86::FEATURE_SSSE3); 989 if ((ECX >> 12) & 1) 990 setFeature(X86::FEATURE_FMA); 991 if ((ECX >> 19) & 1) 992 setFeature(X86::FEATURE_SSE4_1); 993 if ((ECX >> 20) & 1) 994 setFeature(X86::FEATURE_SSE4_2); 995 if ((ECX >> 23) & 1) 996 setFeature(X86::FEATURE_POPCNT); 997 if ((ECX >> 25) & 1) 998 setFeature(X86::FEATURE_AES); 999 1000 if ((ECX >> 22) & 1) 1001 setFeature(X86::FEATURE_MOVBE); 1002 1003 // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV 1004 // indicates that the AVX registers will be saved and restored on context 1005 // switch, then we have full AVX support. 1006 const unsigned AVXBits = (1 << 27) | (1 << 28); 1007 bool HasAVX = ((ECX & AVXBits) == AVXBits) && !getX86XCR0(&EAX, &EDX) && 1008 ((EAX & 0x6) == 0x6); 1009 #if defined(__APPLE__) 1010 // Darwin lazily saves the AVX512 context on first use: trust that the OS will 1011 // save the AVX512 context if we use AVX512 instructions, even the bit is not 1012 // set right now. 1013 bool HasAVX512Save = true; 1014 #else 1015 // AVX512 requires additional context to be saved by the OS. 1016 bool HasAVX512Save = HasAVX && ((EAX & 0xe0) == 0xe0); 1017 #endif 1018 1019 if (HasAVX) 1020 setFeature(X86::FEATURE_AVX); 1021 1022 bool HasLeaf7 = 1023 MaxLeaf >= 0x7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX); 1024 1025 if (HasLeaf7 && ((EBX >> 3) & 1)) 1026 setFeature(X86::FEATURE_BMI); 1027 if (HasLeaf7 && ((EBX >> 5) & 1) && HasAVX) 1028 setFeature(X86::FEATURE_AVX2); 1029 if (HasLeaf7 && ((EBX >> 8) & 1)) 1030 setFeature(X86::FEATURE_BMI2); 1031 if (HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save) 1032 setFeature(X86::FEATURE_AVX512F); 1033 if (HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save) 1034 setFeature(X86::FEATURE_AVX512DQ); 1035 if (HasLeaf7 && ((EBX >> 19) & 1)) 1036 setFeature(X86::FEATURE_ADX); 1037 if (HasLeaf7 && ((EBX >> 21) & 1) && HasAVX512Save) 1038 setFeature(X86::FEATURE_AVX512IFMA); 1039 if (HasLeaf7 && ((EBX >> 23) & 1)) 1040 setFeature(X86::FEATURE_CLFLUSHOPT); 1041 if (HasLeaf7 && ((EBX >> 26) & 1) && HasAVX512Save) 1042 setFeature(X86::FEATURE_AVX512PF); 1043 if (HasLeaf7 && ((EBX >> 27) & 1) && HasAVX512Save) 1044 setFeature(X86::FEATURE_AVX512ER); 1045 if (HasLeaf7 && ((EBX >> 28) & 1) && HasAVX512Save) 1046 setFeature(X86::FEATURE_AVX512CD); 1047 if (HasLeaf7 && ((EBX >> 29) & 1)) 1048 setFeature(X86::FEATURE_SHA); 1049 if (HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save) 1050 setFeature(X86::FEATURE_AVX512BW); 1051 if (HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save) 1052 setFeature(X86::FEATURE_AVX512VL); 1053 1054 if (HasLeaf7 && ((ECX >> 1) & 1) && HasAVX512Save) 1055 setFeature(X86::FEATURE_AVX512VBMI); 1056 if (HasLeaf7 && ((ECX >> 6) & 1) && HasAVX512Save) 1057 setFeature(X86::FEATURE_AVX512VBMI2); 1058 if (HasLeaf7 && ((ECX >> 8) & 1)) 1059 setFeature(X86::FEATURE_GFNI); 1060 if (HasLeaf7 && ((ECX >> 10) & 1) && HasAVX) 1061 setFeature(X86::FEATURE_VPCLMULQDQ); 1062 if (HasLeaf7 && ((ECX >> 11) & 1) && HasAVX512Save) 1063 setFeature(X86::FEATURE_AVX512VNNI); 1064 if (HasLeaf7 && ((ECX >> 12) & 1) && HasAVX512Save) 1065 setFeature(X86::FEATURE_AVX512BITALG); 1066 if (HasLeaf7 && ((ECX >> 14) & 1) && HasAVX512Save) 1067 setFeature(X86::FEATURE_AVX512VPOPCNTDQ); 1068 1069 if (HasLeaf7 && ((EDX >> 2) & 1) && HasAVX512Save) 1070 setFeature(X86::FEATURE_AVX5124VNNIW); 1071 if (HasLeaf7 && ((EDX >> 3) & 1) && HasAVX512Save) 1072 setFeature(X86::FEATURE_AVX5124FMAPS); 1073 if (HasLeaf7 && ((EDX >> 8) & 1) && HasAVX512Save) 1074 setFeature(X86::FEATURE_AVX512VP2INTERSECT); 1075 1076 bool HasLeaf7Subleaf1 = 1077 MaxLeaf >= 7 && !getX86CpuIDAndInfoEx(0x7, 0x1, &EAX, &EBX, &ECX, &EDX); 1078 if (HasLeaf7Subleaf1 && ((EAX >> 5) & 1) && HasAVX512Save) 1079 setFeature(X86::FEATURE_AVX512BF16); 1080 1081 unsigned MaxExtLevel; 1082 getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX); 1083 1084 bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 && 1085 !getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX); 1086 if (HasExtLeaf1 && ((ECX >> 6) & 1)) 1087 setFeature(X86::FEATURE_SSE4_A); 1088 if (HasExtLeaf1 && ((ECX >> 11) & 1)) 1089 setFeature(X86::FEATURE_XOP); 1090 if (HasExtLeaf1 && ((ECX >> 16) & 1)) 1091 setFeature(X86::FEATURE_FMA4); 1092 1093 if (HasExtLeaf1 && ((EDX >> 29) & 1)) 1094 setFeature(X86::FEATURE_64BIT); 1095 } 1096 1097 StringRef sys::getHostCPUName() { 1098 unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0; 1099 unsigned MaxLeaf, Vendor; 1100 1101 if (!isCpuIdSupported()) 1102 return "generic"; 1103 1104 if (getX86CpuIDAndInfo(0, &MaxLeaf, &Vendor, &ECX, &EDX) || MaxLeaf < 1) 1105 return "generic"; 1106 getX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX); 1107 1108 unsigned Family = 0, Model = 0; 1109 unsigned Features[(X86::CPU_FEATURE_MAX + 31) / 32] = {0}; 1110 detectX86FamilyModel(EAX, &Family, &Model); 1111 getAvailableFeatures(ECX, EDX, MaxLeaf, Features); 1112 1113 // These aren't consumed in this file, but we try to keep some source code the 1114 // same or similar to compiler-rt. 1115 unsigned Type = 0; 1116 unsigned Subtype = 0; 1117 1118 StringRef CPU; 1119 1120 if (Vendor == SIG_INTEL) { 1121 CPU = getIntelProcessorTypeAndSubtype(Family, Model, Features, &Type, 1122 &Subtype); 1123 } else if (Vendor == SIG_AMD) { 1124 CPU = getAMDProcessorTypeAndSubtype(Family, Model, Features, &Type, 1125 &Subtype); 1126 } 1127 1128 if (!CPU.empty()) 1129 return CPU; 1130 1131 return "generic"; 1132 } 1133 1134 #elif defined(__APPLE__) && (defined(__ppc__) || defined(__powerpc__)) 1135 StringRef sys::getHostCPUName() { 1136 host_basic_info_data_t hostInfo; 1137 mach_msg_type_number_t infoCount; 1138 1139 infoCount = HOST_BASIC_INFO_COUNT; 1140 mach_port_t hostPort = mach_host_self(); 1141 host_info(hostPort, HOST_BASIC_INFO, (host_info_t)&hostInfo, 1142 &infoCount); 1143 mach_port_deallocate(mach_task_self(), hostPort); 1144 1145 if (hostInfo.cpu_type != CPU_TYPE_POWERPC) 1146 return "generic"; 1147 1148 switch (hostInfo.cpu_subtype) { 1149 case CPU_SUBTYPE_POWERPC_601: 1150 return "601"; 1151 case CPU_SUBTYPE_POWERPC_602: 1152 return "602"; 1153 case CPU_SUBTYPE_POWERPC_603: 1154 return "603"; 1155 case CPU_SUBTYPE_POWERPC_603e: 1156 return "603e"; 1157 case CPU_SUBTYPE_POWERPC_603ev: 1158 return "603ev"; 1159 case CPU_SUBTYPE_POWERPC_604: 1160 return "604"; 1161 case CPU_SUBTYPE_POWERPC_604e: 1162 return "604e"; 1163 case CPU_SUBTYPE_POWERPC_620: 1164 return "620"; 1165 case CPU_SUBTYPE_POWERPC_750: 1166 return "750"; 1167 case CPU_SUBTYPE_POWERPC_7400: 1168 return "7400"; 1169 case CPU_SUBTYPE_POWERPC_7450: 1170 return "7450"; 1171 case CPU_SUBTYPE_POWERPC_970: 1172 return "970"; 1173 default:; 1174 } 1175 1176 return "generic"; 1177 } 1178 #elif defined(__linux__) && (defined(__ppc__) || defined(__powerpc__)) 1179 StringRef sys::getHostCPUName() { 1180 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent(); 1181 StringRef Content = P ? P->getBuffer() : ""; 1182 return detail::getHostCPUNameForPowerPC(Content); 1183 } 1184 #elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__)) 1185 StringRef sys::getHostCPUName() { 1186 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent(); 1187 StringRef Content = P ? P->getBuffer() : ""; 1188 return detail::getHostCPUNameForARM(Content); 1189 } 1190 #elif defined(__linux__) && defined(__s390x__) 1191 StringRef sys::getHostCPUName() { 1192 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent(); 1193 StringRef Content = P ? P->getBuffer() : ""; 1194 return detail::getHostCPUNameForS390x(Content); 1195 } 1196 #elif defined(__APPLE__) && defined(__aarch64__) 1197 StringRef sys::getHostCPUName() { 1198 return "cyclone"; 1199 } 1200 #elif defined(__APPLE__) && defined(__arm__) 1201 StringRef sys::getHostCPUName() { 1202 host_basic_info_data_t hostInfo; 1203 mach_msg_type_number_t infoCount; 1204 1205 infoCount = HOST_BASIC_INFO_COUNT; 1206 mach_port_t hostPort = mach_host_self(); 1207 host_info(hostPort, HOST_BASIC_INFO, (host_info_t)&hostInfo, 1208 &infoCount); 1209 mach_port_deallocate(mach_task_self(), hostPort); 1210 1211 if (hostInfo.cpu_type != CPU_TYPE_ARM) { 1212 assert(false && "CPUType not equal to ARM should not be possible on ARM"); 1213 return "generic"; 1214 } 1215 switch (hostInfo.cpu_subtype) { 1216 case CPU_SUBTYPE_ARM_V7S: 1217 return "swift"; 1218 default:; 1219 } 1220 1221 return "generic"; 1222 } 1223 #elif defined(_AIX) 1224 StringRef sys::getHostCPUName() { 1225 switch (_system_configuration.implementation) { 1226 case POWER_4: 1227 if (_system_configuration.version == PV_4_3) 1228 return "970"; 1229 return "pwr4"; 1230 case POWER_5: 1231 if (_system_configuration.version == PV_5) 1232 return "pwr5"; 1233 return "pwr5x"; 1234 case POWER_6: 1235 if (_system_configuration.version == PV_6_Compat) 1236 return "pwr6"; 1237 return "pwr6x"; 1238 case POWER_7: 1239 return "pwr7"; 1240 case POWER_8: 1241 return "pwr8"; 1242 case POWER_9: 1243 return "pwr9"; 1244 // TODO: simplify this once the macro is available in all OS levels. 1245 #ifdef POWER_10 1246 case POWER_10: 1247 #else 1248 case 0x40000: 1249 #endif 1250 return "pwr10"; 1251 default: 1252 return "generic"; 1253 } 1254 } 1255 #else 1256 StringRef sys::getHostCPUName() { return "generic"; } 1257 #endif 1258 1259 #if defined(__linux__) && (defined(__i386__) || defined(__x86_64__)) 1260 // On Linux, the number of physical cores can be computed from /proc/cpuinfo, 1261 // using the number of unique physical/core id pairs. The following 1262 // implementation reads the /proc/cpuinfo format on an x86_64 system. 1263 int computeHostNumPhysicalCores() { 1264 // Enabled represents the number of physical id/core id pairs with at least 1265 // one processor id enabled by the CPU affinity mask. 1266 cpu_set_t Affinity, Enabled; 1267 if (sched_getaffinity(0, sizeof(Affinity), &Affinity) != 0) 1268 return -1; 1269 CPU_ZERO(&Enabled); 1270 1271 // Read /proc/cpuinfo as a stream (until EOF reached). It cannot be 1272 // mmapped because it appears to have 0 size. 1273 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text = 1274 llvm::MemoryBuffer::getFileAsStream("/proc/cpuinfo"); 1275 if (std::error_code EC = Text.getError()) { 1276 llvm::errs() << "Can't read " 1277 << "/proc/cpuinfo: " << EC.message() << "\n"; 1278 return -1; 1279 } 1280 SmallVector<StringRef, 8> strs; 1281 (*Text)->getBuffer().split(strs, "\n", /*MaxSplit=*/-1, 1282 /*KeepEmpty=*/false); 1283 int CurProcessor = -1; 1284 int CurPhysicalId = -1; 1285 int CurSiblings = -1; 1286 int CurCoreId = -1; 1287 for (StringRef Line : strs) { 1288 std::pair<StringRef, StringRef> Data = Line.split(':'); 1289 auto Name = Data.first.trim(); 1290 auto Val = Data.second.trim(); 1291 // These fields are available if the kernel is configured with CONFIG_SMP. 1292 if (Name == "processor") 1293 Val.getAsInteger(10, CurProcessor); 1294 else if (Name == "physical id") 1295 Val.getAsInteger(10, CurPhysicalId); 1296 else if (Name == "siblings") 1297 Val.getAsInteger(10, CurSiblings); 1298 else if (Name == "core id") { 1299 Val.getAsInteger(10, CurCoreId); 1300 // The processor id corresponds to an index into cpu_set_t. 1301 if (CPU_ISSET(CurProcessor, &Affinity)) 1302 CPU_SET(CurPhysicalId * CurSiblings + CurCoreId, &Enabled); 1303 } 1304 } 1305 return CPU_COUNT(&Enabled); 1306 } 1307 #elif defined(__linux__) && defined(__powerpc__) 1308 int computeHostNumPhysicalCores() { 1309 cpu_set_t Affinity; 1310 if (sched_getaffinity(0, sizeof(Affinity), &Affinity) == 0) 1311 return CPU_COUNT(&Affinity); 1312 1313 // The call to sched_getaffinity() may have failed because the Affinity 1314 // mask is too small for the number of CPU's on the system (i.e. the 1315 // system has more than 1024 CPUs). Allocate a mask large enough for 1316 // twice as many CPUs. 1317 cpu_set_t *DynAffinity; 1318 DynAffinity = CPU_ALLOC(2048); 1319 if (sched_getaffinity(0, CPU_ALLOC_SIZE(2048), DynAffinity) == 0) { 1320 int NumCPUs = CPU_COUNT(DynAffinity); 1321 CPU_FREE(DynAffinity); 1322 return NumCPUs; 1323 } 1324 return -1; 1325 } 1326 #elif defined(__linux__) && defined(__s390x__) 1327 int computeHostNumPhysicalCores() { return sysconf(_SC_NPROCESSORS_ONLN); } 1328 #elif defined(__APPLE__) && defined(__x86_64__) 1329 #include <sys/param.h> 1330 #include <sys/sysctl.h> 1331 1332 // Gets the number of *physical cores* on the machine. 1333 int computeHostNumPhysicalCores() { 1334 uint32_t count; 1335 size_t len = sizeof(count); 1336 sysctlbyname("hw.physicalcpu", &count, &len, NULL, 0); 1337 if (count < 1) { 1338 int nm[2]; 1339 nm[0] = CTL_HW; 1340 nm[1] = HW_AVAILCPU; 1341 sysctl(nm, 2, &count, &len, NULL, 0); 1342 if (count < 1) 1343 return -1; 1344 } 1345 return count; 1346 } 1347 #elif defined(__MVS__) 1348 int computeHostNumPhysicalCores() { 1349 enum { 1350 // Byte offset of the pointer to the Communications Vector Table (CVT) in 1351 // the Prefixed Save Area (PSA). The table entry is a 31-bit pointer and 1352 // will be zero-extended to uintptr_t. 1353 FLCCVT = 16, 1354 // Byte offset of the pointer to the Common System Data Area (CSD) in the 1355 // CVT. The table entry is a 31-bit pointer and will be zero-extended to 1356 // uintptr_t. 1357 CVTCSD = 660, 1358 // Byte offset to the number of live CPs in the LPAR, stored as a signed 1359 // 32-bit value in the table. 1360 CSD_NUMBER_ONLINE_STANDARD_CPS = 264, 1361 }; 1362 char *PSA = 0; 1363 char *CVT = reinterpret_cast<char *>( 1364 static_cast<uintptr_t>(reinterpret_cast<unsigned int &>(PSA[FLCCVT]))); 1365 char *CSD = reinterpret_cast<char *>( 1366 static_cast<uintptr_t>(reinterpret_cast<unsigned int &>(CVT[CVTCSD]))); 1367 return reinterpret_cast<int &>(CSD[CSD_NUMBER_ONLINE_STANDARD_CPS]); 1368 } 1369 #elif defined(_WIN32) && LLVM_ENABLE_THREADS != 0 1370 // Defined in llvm/lib/Support/Windows/Threading.inc 1371 int computeHostNumPhysicalCores(); 1372 #else 1373 // On other systems, return -1 to indicate unknown. 1374 static int computeHostNumPhysicalCores() { return -1; } 1375 #endif 1376 1377 int sys::getHostNumPhysicalCores() { 1378 static int NumCores = computeHostNumPhysicalCores(); 1379 return NumCores; 1380 } 1381 1382 #if defined(__i386__) || defined(_M_IX86) || \ 1383 defined(__x86_64__) || defined(_M_X64) 1384 bool sys::getHostCPUFeatures(StringMap<bool> &Features) { 1385 unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0; 1386 unsigned MaxLevel; 1387 1388 if (getX86CpuIDAndInfo(0, &MaxLevel, &EBX, &ECX, &EDX) || MaxLevel < 1) 1389 return false; 1390 1391 getX86CpuIDAndInfo(1, &EAX, &EBX, &ECX, &EDX); 1392 1393 Features["cx8"] = (EDX >> 8) & 1; 1394 Features["cmov"] = (EDX >> 15) & 1; 1395 Features["mmx"] = (EDX >> 23) & 1; 1396 Features["fxsr"] = (EDX >> 24) & 1; 1397 Features["sse"] = (EDX >> 25) & 1; 1398 Features["sse2"] = (EDX >> 26) & 1; 1399 1400 Features["sse3"] = (ECX >> 0) & 1; 1401 Features["pclmul"] = (ECX >> 1) & 1; 1402 Features["ssse3"] = (ECX >> 9) & 1; 1403 Features["cx16"] = (ECX >> 13) & 1; 1404 Features["sse4.1"] = (ECX >> 19) & 1; 1405 Features["sse4.2"] = (ECX >> 20) & 1; 1406 Features["movbe"] = (ECX >> 22) & 1; 1407 Features["popcnt"] = (ECX >> 23) & 1; 1408 Features["aes"] = (ECX >> 25) & 1; 1409 Features["rdrnd"] = (ECX >> 30) & 1; 1410 1411 // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV 1412 // indicates that the AVX registers will be saved and restored on context 1413 // switch, then we have full AVX support. 1414 bool HasXSave = ((ECX >> 27) & 1) && !getX86XCR0(&EAX, &EDX); 1415 bool HasAVXSave = HasXSave && ((ECX >> 28) & 1) && ((EAX & 0x6) == 0x6); 1416 #if defined(__APPLE__) 1417 // Darwin lazily saves the AVX512 context on first use: trust that the OS will 1418 // save the AVX512 context if we use AVX512 instructions, even the bit is not 1419 // set right now. 1420 bool HasAVX512Save = true; 1421 #else 1422 // AVX512 requires additional context to be saved by the OS. 1423 bool HasAVX512Save = HasAVXSave && ((EAX & 0xe0) == 0xe0); 1424 #endif 1425 // AMX requires additional context to be saved by the OS. 1426 const unsigned AMXBits = (1 << 17) | (1 << 18); 1427 bool HasAMXSave = HasXSave && ((EAX & AMXBits) == AMXBits); 1428 1429 Features["avx"] = HasAVXSave; 1430 Features["fma"] = ((ECX >> 12) & 1) && HasAVXSave; 1431 // Only enable XSAVE if OS has enabled support for saving YMM state. 1432 Features["xsave"] = ((ECX >> 26) & 1) && HasAVXSave; 1433 Features["f16c"] = ((ECX >> 29) & 1) && HasAVXSave; 1434 1435 unsigned MaxExtLevel; 1436 getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX); 1437 1438 bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 && 1439 !getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX); 1440 Features["sahf"] = HasExtLeaf1 && ((ECX >> 0) & 1); 1441 Features["lzcnt"] = HasExtLeaf1 && ((ECX >> 5) & 1); 1442 Features["sse4a"] = HasExtLeaf1 && ((ECX >> 6) & 1); 1443 Features["prfchw"] = HasExtLeaf1 && ((ECX >> 8) & 1); 1444 Features["xop"] = HasExtLeaf1 && ((ECX >> 11) & 1) && HasAVXSave; 1445 Features["lwp"] = HasExtLeaf1 && ((ECX >> 15) & 1); 1446 Features["fma4"] = HasExtLeaf1 && ((ECX >> 16) & 1) && HasAVXSave; 1447 Features["tbm"] = HasExtLeaf1 && ((ECX >> 21) & 1); 1448 Features["mwaitx"] = HasExtLeaf1 && ((ECX >> 29) & 1); 1449 1450 Features["64bit"] = HasExtLeaf1 && ((EDX >> 29) & 1); 1451 1452 // Miscellaneous memory related features, detected by 1453 // using the 0x80000008 leaf of the CPUID instruction 1454 bool HasExtLeaf8 = MaxExtLevel >= 0x80000008 && 1455 !getX86CpuIDAndInfo(0x80000008, &EAX, &EBX, &ECX, &EDX); 1456 Features["clzero"] = HasExtLeaf8 && ((EBX >> 0) & 1); 1457 Features["wbnoinvd"] = HasExtLeaf8 && ((EBX >> 9) & 1); 1458 1459 bool HasLeaf7 = 1460 MaxLevel >= 7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX); 1461 1462 Features["fsgsbase"] = HasLeaf7 && ((EBX >> 0) & 1); 1463 Features["sgx"] = HasLeaf7 && ((EBX >> 2) & 1); 1464 Features["bmi"] = HasLeaf7 && ((EBX >> 3) & 1); 1465 // AVX2 is only supported if we have the OS save support from AVX. 1466 Features["avx2"] = HasLeaf7 && ((EBX >> 5) & 1) && HasAVXSave; 1467 Features["bmi2"] = HasLeaf7 && ((EBX >> 8) & 1); 1468 Features["invpcid"] = HasLeaf7 && ((EBX >> 10) & 1); 1469 Features["rtm"] = HasLeaf7 && ((EBX >> 11) & 1); 1470 // AVX512 is only supported if the OS supports the context save for it. 1471 Features["avx512f"] = HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save; 1472 Features["avx512dq"] = HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save; 1473 Features["rdseed"] = HasLeaf7 && ((EBX >> 18) & 1); 1474 Features["adx"] = HasLeaf7 && ((EBX >> 19) & 1); 1475 Features["avx512ifma"] = HasLeaf7 && ((EBX >> 21) & 1) && HasAVX512Save; 1476 Features["clflushopt"] = HasLeaf7 && ((EBX >> 23) & 1); 1477 Features["clwb"] = HasLeaf7 && ((EBX >> 24) & 1); 1478 Features["avx512pf"] = HasLeaf7 && ((EBX >> 26) & 1) && HasAVX512Save; 1479 Features["avx512er"] = HasLeaf7 && ((EBX >> 27) & 1) && HasAVX512Save; 1480 Features["avx512cd"] = HasLeaf7 && ((EBX >> 28) & 1) && HasAVX512Save; 1481 Features["sha"] = HasLeaf7 && ((EBX >> 29) & 1); 1482 Features["avx512bw"] = HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save; 1483 Features["avx512vl"] = HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save; 1484 1485 Features["prefetchwt1"] = HasLeaf7 && ((ECX >> 0) & 1); 1486 Features["avx512vbmi"] = HasLeaf7 && ((ECX >> 1) & 1) && HasAVX512Save; 1487 Features["pku"] = HasLeaf7 && ((ECX >> 4) & 1); 1488 Features["waitpkg"] = HasLeaf7 && ((ECX >> 5) & 1); 1489 Features["avx512vbmi2"] = HasLeaf7 && ((ECX >> 6) & 1) && HasAVX512Save; 1490 Features["shstk"] = HasLeaf7 && ((ECX >> 7) & 1); 1491 Features["gfni"] = HasLeaf7 && ((ECX >> 8) & 1); 1492 Features["vaes"] = HasLeaf7 && ((ECX >> 9) & 1) && HasAVXSave; 1493 Features["vpclmulqdq"] = HasLeaf7 && ((ECX >> 10) & 1) && HasAVXSave; 1494 Features["avx512vnni"] = HasLeaf7 && ((ECX >> 11) & 1) && HasAVX512Save; 1495 Features["avx512bitalg"] = HasLeaf7 && ((ECX >> 12) & 1) && HasAVX512Save; 1496 Features["avx512vpopcntdq"] = HasLeaf7 && ((ECX >> 14) & 1) && HasAVX512Save; 1497 Features["rdpid"] = HasLeaf7 && ((ECX >> 22) & 1); 1498 Features["kl"] = HasLeaf7 && ((ECX >> 23) & 1); // key locker 1499 Features["cldemote"] = HasLeaf7 && ((ECX >> 25) & 1); 1500 Features["movdiri"] = HasLeaf7 && ((ECX >> 27) & 1); 1501 Features["movdir64b"] = HasLeaf7 && ((ECX >> 28) & 1); 1502 Features["enqcmd"] = HasLeaf7 && ((ECX >> 29) & 1); 1503 1504 Features["uintr"] = HasLeaf7 && ((EDX >> 5) & 1); 1505 Features["avx512vp2intersect"] = 1506 HasLeaf7 && ((EDX >> 8) & 1) && HasAVX512Save; 1507 Features["serialize"] = HasLeaf7 && ((EDX >> 14) & 1); 1508 Features["tsxldtrk"] = HasLeaf7 && ((EDX >> 16) & 1); 1509 // There are two CPUID leafs which information associated with the pconfig 1510 // instruction: 1511 // EAX=0x7, ECX=0x0 indicates the availability of the instruction (via the 18th 1512 // bit of EDX), while the EAX=0x1b leaf returns information on the 1513 // availability of specific pconfig leafs. 1514 // The target feature here only refers to the the first of these two. 1515 // Users might need to check for the availability of specific pconfig 1516 // leaves using cpuid, since that information is ignored while 1517 // detecting features using the "-march=native" flag. 1518 // For more info, see X86 ISA docs. 1519 Features["pconfig"] = HasLeaf7 && ((EDX >> 18) & 1); 1520 Features["amx-bf16"] = HasLeaf7 && ((EDX >> 22) & 1) && HasAMXSave; 1521 Features["amx-tile"] = HasLeaf7 && ((EDX >> 24) & 1) && HasAMXSave; 1522 Features["amx-int8"] = HasLeaf7 && ((EDX >> 25) & 1) && HasAMXSave; 1523 bool HasLeaf7Subleaf1 = 1524 MaxLevel >= 7 && !getX86CpuIDAndInfoEx(0x7, 0x1, &EAX, &EBX, &ECX, &EDX); 1525 Features["avxvnni"] = HasLeaf7Subleaf1 && ((EAX >> 4) & 1) && HasAVXSave; 1526 Features["avx512bf16"] = HasLeaf7Subleaf1 && ((EAX >> 5) & 1) && HasAVX512Save; 1527 Features["hreset"] = HasLeaf7Subleaf1 && ((EAX >> 22) & 1); 1528 1529 bool HasLeafD = MaxLevel >= 0xd && 1530 !getX86CpuIDAndInfoEx(0xd, 0x1, &EAX, &EBX, &ECX, &EDX); 1531 1532 // Only enable XSAVE if OS has enabled support for saving YMM state. 1533 Features["xsaveopt"] = HasLeafD && ((EAX >> 0) & 1) && HasAVXSave; 1534 Features["xsavec"] = HasLeafD && ((EAX >> 1) & 1) && HasAVXSave; 1535 Features["xsaves"] = HasLeafD && ((EAX >> 3) & 1) && HasAVXSave; 1536 1537 bool HasLeaf14 = MaxLevel >= 0x14 && 1538 !getX86CpuIDAndInfoEx(0x14, 0x0, &EAX, &EBX, &ECX, &EDX); 1539 1540 Features["ptwrite"] = HasLeaf14 && ((EBX >> 4) & 1); 1541 1542 bool HasLeaf19 = 1543 MaxLevel >= 0x19 && !getX86CpuIDAndInfo(0x19, &EAX, &EBX, &ECX, &EDX); 1544 Features["widekl"] = HasLeaf7 && HasLeaf19 && ((EBX >> 2) & 1); 1545 1546 return true; 1547 } 1548 #elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__)) 1549 bool sys::getHostCPUFeatures(StringMap<bool> &Features) { 1550 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent(); 1551 if (!P) 1552 return false; 1553 1554 SmallVector<StringRef, 32> Lines; 1555 P->getBuffer().split(Lines, "\n"); 1556 1557 SmallVector<StringRef, 32> CPUFeatures; 1558 1559 // Look for the CPU features. 1560 for (unsigned I = 0, E = Lines.size(); I != E; ++I) 1561 if (Lines[I].startswith("Features")) { 1562 Lines[I].split(CPUFeatures, ' '); 1563 break; 1564 } 1565 1566 #if defined(__aarch64__) 1567 // Keep track of which crypto features we have seen 1568 enum { CAP_AES = 0x1, CAP_PMULL = 0x2, CAP_SHA1 = 0x4, CAP_SHA2 = 0x8 }; 1569 uint32_t crypto = 0; 1570 #endif 1571 1572 for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) { 1573 StringRef LLVMFeatureStr = StringSwitch<StringRef>(CPUFeatures[I]) 1574 #if defined(__aarch64__) 1575 .Case("asimd", "neon") 1576 .Case("fp", "fp-armv8") 1577 .Case("crc32", "crc") 1578 #else 1579 .Case("half", "fp16") 1580 .Case("neon", "neon") 1581 .Case("vfpv3", "vfp3") 1582 .Case("vfpv3d16", "d16") 1583 .Case("vfpv4", "vfp4") 1584 .Case("idiva", "hwdiv-arm") 1585 .Case("idivt", "hwdiv") 1586 #endif 1587 .Default(""); 1588 1589 #if defined(__aarch64__) 1590 // We need to check crypto separately since we need all of the crypto 1591 // extensions to enable the subtarget feature 1592 if (CPUFeatures[I] == "aes") 1593 crypto |= CAP_AES; 1594 else if (CPUFeatures[I] == "pmull") 1595 crypto |= CAP_PMULL; 1596 else if (CPUFeatures[I] == "sha1") 1597 crypto |= CAP_SHA1; 1598 else if (CPUFeatures[I] == "sha2") 1599 crypto |= CAP_SHA2; 1600 #endif 1601 1602 if (LLVMFeatureStr != "") 1603 Features[LLVMFeatureStr] = true; 1604 } 1605 1606 #if defined(__aarch64__) 1607 // If we have all crypto bits we can add the feature 1608 if (crypto == (CAP_AES | CAP_PMULL | CAP_SHA1 | CAP_SHA2)) 1609 Features["crypto"] = true; 1610 #endif 1611 1612 return true; 1613 } 1614 #elif defined(_WIN32) && (defined(__aarch64__) || defined(_M_ARM64)) 1615 bool sys::getHostCPUFeatures(StringMap<bool> &Features) { 1616 if (IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE)) 1617 Features["neon"] = true; 1618 if (IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE)) 1619 Features["crc"] = true; 1620 if (IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE)) 1621 Features["crypto"] = true; 1622 1623 return true; 1624 } 1625 #else 1626 bool sys::getHostCPUFeatures(StringMap<bool> &Features) { return false; } 1627 #endif 1628 1629 std::string sys::getProcessTriple() { 1630 std::string TargetTripleString = updateTripleOSVersion(LLVM_HOST_TRIPLE); 1631 Triple PT(Triple::normalize(TargetTripleString)); 1632 1633 if (sizeof(void *) == 8 && PT.isArch32Bit()) 1634 PT = PT.get64BitArchVariant(); 1635 if (sizeof(void *) == 4 && PT.isArch64Bit()) 1636 PT = PT.get32BitArchVariant(); 1637 1638 return PT.str(); 1639 } 1640