1 //===-- Host.cpp - Implement OS Host Concept --------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This header file implements the operating system Host concept. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/Support/Host.h" 15 #include "llvm/ADT/SmallVector.h" 16 #include "llvm/ADT/StringRef.h" 17 #include "llvm/ADT/StringSwitch.h" 18 #include "llvm/ADT/Triple.h" 19 #include "llvm/Config/config.h" 20 #include "llvm/Support/DataStream.h" 21 #include "llvm/Support/Debug.h" 22 #include "llvm/Support/raw_ostream.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 #endif 29 #ifdef LLVM_ON_WIN32 30 #include "Windows/Host.inc" 31 #endif 32 #ifdef _MSC_VER 33 #include <intrin.h> 34 #endif 35 #if defined(__APPLE__) && (defined(__ppc__) || defined(__powerpc__)) 36 #include <mach/mach.h> 37 #include <mach/mach_host.h> 38 #include <mach/host_info.h> 39 #include <mach/machine.h> 40 #endif 41 42 //===----------------------------------------------------------------------===// 43 // 44 // Implementations of the CPU detection routines 45 // 46 //===----------------------------------------------------------------------===// 47 48 using namespace llvm; 49 50 #if defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)\ 51 || defined(__x86_64__) || defined(_M_AMD64) || defined (_M_X64) 52 53 /// GetX86CpuIDAndInfo - Execute the specified cpuid and return the 4 values in the 54 /// specified arguments. If we can't run cpuid on the host, return true. 55 static bool GetX86CpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX, 56 unsigned *rECX, unsigned *rEDX) { 57 #if defined(__GNUC__) || defined(__clang__) 58 #if defined(__x86_64__) || defined(_M_AMD64) || defined (_M_X64) 59 // gcc doesn't know cpuid would clobber ebx/rbx. Preseve it manually. 60 asm ("movq\t%%rbx, %%rsi\n\t" 61 "cpuid\n\t" 62 "xchgq\t%%rbx, %%rsi\n\t" 63 : "=a" (*rEAX), 64 "=S" (*rEBX), 65 "=c" (*rECX), 66 "=d" (*rEDX) 67 : "a" (value)); 68 return false; 69 #elif defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86) 70 asm ("movl\t%%ebx, %%esi\n\t" 71 "cpuid\n\t" 72 "xchgl\t%%ebx, %%esi\n\t" 73 : "=a" (*rEAX), 74 "=S" (*rEBX), 75 "=c" (*rECX), 76 "=d" (*rEDX) 77 : "a" (value)); 78 return false; 79 // pedantic #else returns to appease -Wunreachable-code (so we don't generate 80 // postprocessed code that looks like "return true; return false;") 81 #else 82 return true; 83 #endif 84 #elif defined(_MSC_VER) 85 // The MSVC intrinsic is portable across x86 and x64. 86 int registers[4]; 87 __cpuid(registers, value); 88 *rEAX = registers[0]; 89 *rEBX = registers[1]; 90 *rECX = registers[2]; 91 *rEDX = registers[3]; 92 return false; 93 #else 94 return true; 95 #endif 96 } 97 98 /// GetX86CpuIDAndInfoEx - Execute the specified cpuid with subleaf and return the 99 /// 4 values in the specified arguments. If we can't run cpuid on the host, 100 /// return true. 101 static bool GetX86CpuIDAndInfoEx(unsigned value, unsigned subleaf, 102 unsigned *rEAX, unsigned *rEBX, unsigned *rECX, 103 unsigned *rEDX) { 104 #if defined(__x86_64__) || defined(_M_AMD64) || defined (_M_X64) 105 #if defined(__GNUC__) 106 // gcc doesn't know cpuid would clobber ebx/rbx. Preseve it manually. 107 asm ("movq\t%%rbx, %%rsi\n\t" 108 "cpuid\n\t" 109 "xchgq\t%%rbx, %%rsi\n\t" 110 : "=a" (*rEAX), 111 "=S" (*rEBX), 112 "=c" (*rECX), 113 "=d" (*rEDX) 114 : "a" (value), 115 "c" (subleaf)); 116 return false; 117 #elif defined(_MSC_VER) 118 // __cpuidex was added in MSVC++ 9.0 SP1 119 #if (_MSC_VER > 1500) || (_MSC_VER == 1500 && _MSC_FULL_VER >= 150030729) 120 int registers[4]; 121 __cpuidex(registers, value, subleaf); 122 *rEAX = registers[0]; 123 *rEBX = registers[1]; 124 *rECX = registers[2]; 125 *rEDX = registers[3]; 126 return false; 127 #else 128 return true; 129 #endif 130 #else 131 return true; 132 #endif 133 #elif defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86) 134 #if defined(__GNUC__) 135 asm ("movl\t%%ebx, %%esi\n\t" 136 "cpuid\n\t" 137 "xchgl\t%%ebx, %%esi\n\t" 138 : "=a" (*rEAX), 139 "=S" (*rEBX), 140 "=c" (*rECX), 141 "=d" (*rEDX) 142 : "a" (value), 143 "c" (subleaf)); 144 return false; 145 #elif defined(_MSC_VER) 146 __asm { 147 mov eax,value 148 mov ecx,subleaf 149 cpuid 150 mov esi,rEAX 151 mov dword ptr [esi],eax 152 mov esi,rEBX 153 mov dword ptr [esi],ebx 154 mov esi,rECX 155 mov dword ptr [esi],ecx 156 mov esi,rEDX 157 mov dword ptr [esi],edx 158 } 159 return false; 160 #else 161 return true; 162 #endif 163 #else 164 return true; 165 #endif 166 } 167 168 static bool OSHasAVXSupport() { 169 #if defined(__GNUC__) 170 // Check xgetbv; this uses a .byte sequence instead of the instruction 171 // directly because older assemblers do not include support for xgetbv and 172 // there is no easy way to conditionally compile based on the assembler used. 173 int rEAX, rEDX; 174 __asm__ (".byte 0x0f, 0x01, 0xd0" : "=a" (rEAX), "=d" (rEDX) : "c" (0)); 175 #elif defined(_MSC_FULL_VER) && defined(_XCR_XFEATURE_ENABLED_MASK) 176 unsigned long long rEAX = _xgetbv(_XCR_XFEATURE_ENABLED_MASK); 177 #else 178 int rEAX = 0; // Ensures we return false 179 #endif 180 return (rEAX & 6) == 6; 181 } 182 183 static void DetectX86FamilyModel(unsigned EAX, unsigned &Family, 184 unsigned &Model) { 185 Family = (EAX >> 8) & 0xf; // Bits 8 - 11 186 Model = (EAX >> 4) & 0xf; // Bits 4 - 7 187 if (Family == 6 || Family == 0xf) { 188 if (Family == 0xf) 189 // Examine extended family ID if family ID is F. 190 Family += (EAX >> 20) & 0xff; // Bits 20 - 27 191 // Examine extended model ID if family ID is 6 or F. 192 Model += ((EAX >> 16) & 0xf) << 4; // Bits 16 - 19 193 } 194 } 195 196 StringRef sys::getHostCPUName() { 197 unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0; 198 if (GetX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX)) 199 return "generic"; 200 unsigned Family = 0; 201 unsigned Model = 0; 202 DetectX86FamilyModel(EAX, Family, Model); 203 204 union { 205 unsigned u[3]; 206 char c[12]; 207 } text; 208 209 GetX86CpuIDAndInfo(0, &EAX, text.u+0, text.u+2, text.u+1); 210 211 unsigned MaxLeaf = EAX; 212 bool HasSSE3 = (ECX & 0x1); 213 bool HasSSE41 = (ECX & 0x80000); 214 // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV 215 // indicates that the AVX registers will be saved and restored on context 216 // switch, then we have full AVX support. 217 const unsigned AVXBits = (1 << 27) | (1 << 28); 218 bool HasAVX = ((ECX & AVXBits) == AVXBits) && OSHasAVXSupport(); 219 bool HasAVX2 = HasAVX && MaxLeaf >= 0x7 && 220 !GetX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX) && 221 (EBX & 0x20); 222 GetX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX); 223 bool Em64T = (EDX >> 29) & 0x1; 224 225 if (memcmp(text.c, "GenuineIntel", 12) == 0) { 226 switch (Family) { 227 case 3: 228 return "i386"; 229 case 4: 230 switch (Model) { 231 case 0: // Intel486 DX processors 232 case 1: // Intel486 DX processors 233 case 2: // Intel486 SX processors 234 case 3: // Intel487 processors, IntelDX2 OverDrive processors, 235 // IntelDX2 processors 236 case 4: // Intel486 SL processor 237 case 5: // IntelSX2 processors 238 case 7: // Write-Back Enhanced IntelDX2 processors 239 case 8: // IntelDX4 OverDrive processors, IntelDX4 processors 240 default: return "i486"; 241 } 242 case 5: 243 switch (Model) { 244 case 1: // Pentium OverDrive processor for Pentium processor (60, 66), 245 // Pentium processors (60, 66) 246 case 2: // Pentium OverDrive processor for Pentium processor (75, 90, 247 // 100, 120, 133), Pentium processors (75, 90, 100, 120, 133, 248 // 150, 166, 200) 249 case 3: // Pentium OverDrive processors for Intel486 processor-based 250 // systems 251 return "pentium"; 252 253 case 4: // Pentium OverDrive processor with MMX technology for Pentium 254 // processor (75, 90, 100, 120, 133), Pentium processor with 255 // MMX technology (166, 200) 256 return "pentium-mmx"; 257 258 default: return "pentium"; 259 } 260 case 6: 261 switch (Model) { 262 case 1: // Pentium Pro processor 263 return "pentiumpro"; 264 265 case 3: // Intel Pentium II OverDrive processor, Pentium II processor, 266 // model 03 267 case 5: // Pentium II processor, model 05, Pentium II Xeon processor, 268 // model 05, and Intel Celeron processor, model 05 269 case 6: // Celeron processor, model 06 270 return "pentium2"; 271 272 case 7: // Pentium III processor, model 07, and Pentium III Xeon 273 // processor, model 07 274 case 8: // Pentium III processor, model 08, Pentium III Xeon processor, 275 // model 08, and Celeron processor, model 08 276 case 10: // Pentium III Xeon processor, model 0Ah 277 case 11: // Pentium III processor, model 0Bh 278 return "pentium3"; 279 280 case 9: // Intel Pentium M processor, Intel Celeron M processor model 09. 281 case 13: // Intel Pentium M processor, Intel Celeron M processor, model 282 // 0Dh. All processors are manufactured using the 90 nm process. 283 return "pentium-m"; 284 285 case 14: // Intel Core Duo processor, Intel Core Solo processor, model 286 // 0Eh. All processors are manufactured using the 65 nm process. 287 return "yonah"; 288 289 case 15: // Intel Core 2 Duo processor, Intel Core 2 Duo mobile 290 // processor, Intel Core 2 Quad processor, Intel Core 2 Quad 291 // mobile processor, Intel Core 2 Extreme processor, Intel 292 // Pentium Dual-Core processor, Intel Xeon processor, model 293 // 0Fh. All processors are manufactured using the 65 nm process. 294 case 22: // Intel Celeron processor model 16h. All processors are 295 // manufactured using the 65 nm process 296 return "core2"; 297 298 case 21: // Intel EP80579 Integrated Processor and Intel EP80579 299 // Integrated Processor with Intel QuickAssist Technology 300 return "i686"; // FIXME: ??? 301 302 case 23: // Intel Core 2 Extreme processor, Intel Xeon processor, model 303 // 17h. All processors are manufactured using the 45 nm process. 304 // 305 // 45nm: Penryn , Wolfdale, Yorkfield (XE) 306 // Not all Penryn processors support SSE 4.1 (such as the Pentium brand) 307 return HasSSE41 ? "penryn" : "core2"; 308 309 case 26: // Intel Core i7 processor and Intel Xeon processor. All 310 // processors are manufactured using the 45 nm process. 311 case 29: // Intel Xeon processor MP. All processors are manufactured using 312 // the 45 nm process. 313 case 30: // Intel(R) Core(TM) i7 CPU 870 @ 2.93GHz. 314 // As found in a Summer 2010 model iMac. 315 case 37: // Intel Core i7, laptop version. 316 case 44: // Intel Core i7 processor and Intel Xeon processor. All 317 // processors are manufactured using the 32 nm process. 318 case 46: // Nehalem EX 319 case 47: // Westmere EX 320 return "corei7"; 321 322 // SandyBridge: 323 case 42: // Intel Core i7 processor. All processors are manufactured 324 // using the 32 nm process. 325 case 45: 326 // Not all Sandy Bridge processors support AVX (such as the Pentium 327 // versions instead of the i7 versions). 328 return HasAVX ? "corei7-avx" : "corei7"; 329 330 // Ivy Bridge: 331 case 58: 332 case 62: // Ivy Bridge EP 333 // Not all Ivy Bridge processors support AVX (such as the Pentium 334 // versions instead of the i7 versions). 335 return HasAVX ? "core-avx-i" : "corei7"; 336 337 // Haswell: 338 case 60: 339 case 63: 340 case 69: 341 case 70: 342 // Not all Haswell processors support AVX too (such as the Pentium 343 // versions instead of the i7 versions). 344 return HasAVX2 ? "core-avx2" : "corei7"; 345 346 case 28: // Most 45 nm Intel Atom processors 347 case 38: // 45 nm Atom Lincroft 348 case 39: // 32 nm Atom Medfield 349 case 53: // 32 nm Atom Midview 350 case 54: // 32 nm Atom Midview 351 return "atom"; 352 353 // Atom Silvermont codes from the Intel software optimization guide. 354 case 55: 355 case 74: 356 case 77: 357 return "slm"; 358 359 default: return (Em64T) ? "x86-64" : "i686"; 360 } 361 case 15: { 362 switch (Model) { 363 case 0: // Pentium 4 processor, Intel Xeon processor. All processors are 364 // model 00h and manufactured using the 0.18 micron process. 365 case 1: // Pentium 4 processor, Intel Xeon processor, Intel Xeon 366 // processor MP, and Intel Celeron processor. All processors are 367 // model 01h and manufactured using the 0.18 micron process. 368 case 2: // Pentium 4 processor, Mobile Intel Pentium 4 processor - M, 369 // Intel Xeon processor, Intel Xeon processor MP, Intel Celeron 370 // processor, and Mobile Intel Celeron processor. All processors 371 // are model 02h and manufactured using the 0.13 micron process. 372 return (Em64T) ? "x86-64" : "pentium4"; 373 374 case 3: // Pentium 4 processor, Intel Xeon processor, Intel Celeron D 375 // processor. All processors are model 03h and manufactured using 376 // the 90 nm process. 377 case 4: // Pentium 4 processor, Pentium 4 processor Extreme Edition, 378 // Pentium D processor, Intel Xeon processor, Intel Xeon 379 // processor MP, Intel Celeron D processor. All processors are 380 // model 04h and manufactured using the 90 nm process. 381 case 6: // Pentium 4 processor, Pentium D processor, Pentium processor 382 // Extreme Edition, Intel Xeon processor, Intel Xeon processor 383 // MP, Intel Celeron D processor. All processors are model 06h 384 // and manufactured using the 65 nm process. 385 return (Em64T) ? "nocona" : "prescott"; 386 387 default: 388 return (Em64T) ? "x86-64" : "pentium4"; 389 } 390 } 391 392 default: 393 return "generic"; 394 } 395 } else if (memcmp(text.c, "AuthenticAMD", 12) == 0) { 396 // FIXME: this poorly matches the generated SubtargetFeatureKV table. There 397 // appears to be no way to generate the wide variety of AMD-specific targets 398 // from the information returned from CPUID. 399 switch (Family) { 400 case 4: 401 return "i486"; 402 case 5: 403 switch (Model) { 404 case 6: 405 case 7: return "k6"; 406 case 8: return "k6-2"; 407 case 9: 408 case 13: return "k6-3"; 409 case 10: return "geode"; 410 default: return "pentium"; 411 } 412 case 6: 413 switch (Model) { 414 case 4: return "athlon-tbird"; 415 case 6: 416 case 7: 417 case 8: return "athlon-mp"; 418 case 10: return "athlon-xp"; 419 default: return "athlon"; 420 } 421 case 15: 422 if (HasSSE3) 423 return "k8-sse3"; 424 switch (Model) { 425 case 1: return "opteron"; 426 case 5: return "athlon-fx"; // also opteron 427 default: return "athlon64"; 428 } 429 case 16: 430 return "amdfam10"; 431 case 20: 432 return "btver1"; 433 case 21: 434 if (!HasAVX) // If the OS doesn't support AVX provide a sane fallback. 435 return "btver1"; 436 if (Model >= 0x30) 437 return "bdver3"; // 30h-3Fh: Steamroller 438 if (Model >= 0x10) 439 return "bdver2"; // 10h-1Fh: Piledriver 440 return "bdver1"; // 00h-0Fh: Bulldozer 441 case 22: 442 if (!HasAVX) // If the OS doesn't support AVX provide a sane fallback. 443 return "btver1"; 444 return "btver2"; 445 default: 446 return "generic"; 447 } 448 } 449 return "generic"; 450 } 451 #elif defined(__APPLE__) && (defined(__ppc__) || defined(__powerpc__)) 452 StringRef sys::getHostCPUName() { 453 host_basic_info_data_t hostInfo; 454 mach_msg_type_number_t infoCount; 455 456 infoCount = HOST_BASIC_INFO_COUNT; 457 host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostInfo, 458 &infoCount); 459 460 if (hostInfo.cpu_type != CPU_TYPE_POWERPC) return "generic"; 461 462 switch(hostInfo.cpu_subtype) { 463 case CPU_SUBTYPE_POWERPC_601: return "601"; 464 case CPU_SUBTYPE_POWERPC_602: return "602"; 465 case CPU_SUBTYPE_POWERPC_603: return "603"; 466 case CPU_SUBTYPE_POWERPC_603e: return "603e"; 467 case CPU_SUBTYPE_POWERPC_603ev: return "603ev"; 468 case CPU_SUBTYPE_POWERPC_604: return "604"; 469 case CPU_SUBTYPE_POWERPC_604e: return "604e"; 470 case CPU_SUBTYPE_POWERPC_620: return "620"; 471 case CPU_SUBTYPE_POWERPC_750: return "750"; 472 case CPU_SUBTYPE_POWERPC_7400: return "7400"; 473 case CPU_SUBTYPE_POWERPC_7450: return "7450"; 474 case CPU_SUBTYPE_POWERPC_970: return "970"; 475 default: ; 476 } 477 478 return "generic"; 479 } 480 #elif defined(__linux__) && (defined(__ppc__) || defined(__powerpc__)) 481 StringRef sys::getHostCPUName() { 482 // Access to the Processor Version Register (PVR) on PowerPC is privileged, 483 // and so we must use an operating-system interface to determine the current 484 // processor type. On Linux, this is exposed through the /proc/cpuinfo file. 485 const char *generic = "generic"; 486 487 // Note: We cannot mmap /proc/cpuinfo here and then process the resulting 488 // memory buffer because the 'file' has 0 size (it can be read from only 489 // as a stream). 490 491 std::string Err; 492 DataStreamer *DS = getDataFileStreamer("/proc/cpuinfo", &Err); 493 if (!DS) { 494 DEBUG(dbgs() << "Unable to open /proc/cpuinfo: " << Err << "\n"); 495 return generic; 496 } 497 498 // The cpu line is second (after the 'processor: 0' line), so if this 499 // buffer is too small then something has changed (or is wrong). 500 char buffer[1024]; 501 size_t CPUInfoSize = DS->GetBytes((unsigned char*) buffer, sizeof(buffer)); 502 delete DS; 503 504 const char *CPUInfoStart = buffer; 505 const char *CPUInfoEnd = buffer + CPUInfoSize; 506 507 const char *CIP = CPUInfoStart; 508 509 const char *CPUStart = 0; 510 size_t CPULen = 0; 511 512 // We need to find the first line which starts with cpu, spaces, and a colon. 513 // After the colon, there may be some additional spaces and then the cpu type. 514 while (CIP < CPUInfoEnd && CPUStart == 0) { 515 if (CIP < CPUInfoEnd && *CIP == '\n') 516 ++CIP; 517 518 if (CIP < CPUInfoEnd && *CIP == 'c') { 519 ++CIP; 520 if (CIP < CPUInfoEnd && *CIP == 'p') { 521 ++CIP; 522 if (CIP < CPUInfoEnd && *CIP == 'u') { 523 ++CIP; 524 while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t')) 525 ++CIP; 526 527 if (CIP < CPUInfoEnd && *CIP == ':') { 528 ++CIP; 529 while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t')) 530 ++CIP; 531 532 if (CIP < CPUInfoEnd) { 533 CPUStart = CIP; 534 while (CIP < CPUInfoEnd && (*CIP != ' ' && *CIP != '\t' && 535 *CIP != ',' && *CIP != '\n')) 536 ++CIP; 537 CPULen = CIP - CPUStart; 538 } 539 } 540 } 541 } 542 } 543 544 if (CPUStart == 0) 545 while (CIP < CPUInfoEnd && *CIP != '\n') 546 ++CIP; 547 } 548 549 if (CPUStart == 0) 550 return generic; 551 552 return StringSwitch<const char *>(StringRef(CPUStart, CPULen)) 553 .Case("604e", "604e") 554 .Case("604", "604") 555 .Case("7400", "7400") 556 .Case("7410", "7400") 557 .Case("7447", "7400") 558 .Case("7455", "7450") 559 .Case("G4", "g4") 560 .Case("POWER4", "970") 561 .Case("PPC970FX", "970") 562 .Case("PPC970MP", "970") 563 .Case("G5", "g5") 564 .Case("POWER5", "g5") 565 .Case("A2", "a2") 566 .Case("POWER6", "pwr6") 567 .Case("POWER7", "pwr7") 568 .Default(generic); 569 } 570 #elif defined(__linux__) && defined(__arm__) 571 StringRef sys::getHostCPUName() { 572 // The cpuid register on arm is not accessible from user space. On Linux, 573 // it is exposed through the /proc/cpuinfo file. 574 // Note: We cannot mmap /proc/cpuinfo here and then process the resulting 575 // memory buffer because the 'file' has 0 size (it can be read from only 576 // as a stream). 577 578 std::string Err; 579 DataStreamer *DS = getDataFileStreamer("/proc/cpuinfo", &Err); 580 if (!DS) { 581 DEBUG(dbgs() << "Unable to open /proc/cpuinfo: " << Err << "\n"); 582 return "generic"; 583 } 584 585 // Read 1024 bytes from /proc/cpuinfo, which should contain the CPU part line 586 // in all cases. 587 char buffer[1024]; 588 size_t CPUInfoSize = DS->GetBytes((unsigned char*) buffer, sizeof(buffer)); 589 delete DS; 590 591 StringRef Str(buffer, CPUInfoSize); 592 593 SmallVector<StringRef, 32> Lines; 594 Str.split(Lines, "\n"); 595 596 // Look for the CPU implementer line. 597 StringRef Implementer; 598 for (unsigned I = 0, E = Lines.size(); I != E; ++I) 599 if (Lines[I].startswith("CPU implementer")) 600 Implementer = Lines[I].substr(15).ltrim("\t :"); 601 602 if (Implementer == "0x41") // ARM Ltd. 603 // Look for the CPU part line. 604 for (unsigned I = 0, E = Lines.size(); I != E; ++I) 605 if (Lines[I].startswith("CPU part")) 606 // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The 607 // values correspond to the "Part number" in the CP15/c0 register. The 608 // contents are specified in the various processor manuals. 609 return StringSwitch<const char *>(Lines[I].substr(8).ltrim("\t :")) 610 .Case("0x926", "arm926ej-s") 611 .Case("0xb02", "mpcore") 612 .Case("0xb36", "arm1136j-s") 613 .Case("0xb56", "arm1156t2-s") 614 .Case("0xb76", "arm1176jz-s") 615 .Case("0xc08", "cortex-a8") 616 .Case("0xc09", "cortex-a9") 617 .Case("0xc0f", "cortex-a15") 618 .Case("0xc20", "cortex-m0") 619 .Case("0xc23", "cortex-m3") 620 .Case("0xc24", "cortex-m4") 621 .Default("generic"); 622 623 if (Implementer == "0x51") // Qualcomm Technologies, Inc. 624 // Look for the CPU part line. 625 for (unsigned I = 0, E = Lines.size(); I != E; ++I) 626 if (Lines[I].startswith("CPU part")) 627 // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The 628 // values correspond to the "Part number" in the CP15/c0 register. The 629 // contents are specified in the various processor manuals. 630 return StringSwitch<const char *>(Lines[I].substr(8).ltrim("\t :")) 631 .Case("0x06f", "krait") // APQ8064 632 .Default("generic"); 633 634 return "generic"; 635 } 636 #elif defined(__linux__) && defined(__s390x__) 637 StringRef sys::getHostCPUName() { 638 // STIDP is a privileged operation, so use /proc/cpuinfo instead. 639 // Note: We cannot mmap /proc/cpuinfo here and then process the resulting 640 // memory buffer because the 'file' has 0 size (it can be read from only 641 // as a stream). 642 643 std::string Err; 644 DataStreamer *DS = getDataFileStreamer("/proc/cpuinfo", &Err); 645 if (!DS) { 646 DEBUG(dbgs() << "Unable to open /proc/cpuinfo: " << Err << "\n"); 647 return "generic"; 648 } 649 650 // The "processor 0:" line comes after a fair amount of other information, 651 // including a cache breakdown, but this should be plenty. 652 char buffer[2048]; 653 size_t CPUInfoSize = DS->GetBytes((unsigned char*) buffer, sizeof(buffer)); 654 delete DS; 655 656 StringRef Str(buffer, CPUInfoSize); 657 SmallVector<StringRef, 32> Lines; 658 Str.split(Lines, "\n"); 659 for (unsigned I = 0, E = Lines.size(); I != E; ++I) { 660 if (Lines[I].startswith("processor ")) { 661 size_t Pos = Lines[I].find("machine = "); 662 if (Pos != StringRef::npos) { 663 Pos += sizeof("machine = ") - 1; 664 unsigned int Id; 665 if (!Lines[I].drop_front(Pos).getAsInteger(10, Id)) { 666 if (Id >= 2827) 667 return "zEC12"; 668 if (Id >= 2817) 669 return "z196"; 670 } 671 } 672 break; 673 } 674 } 675 676 return "generic"; 677 } 678 #else 679 StringRef sys::getHostCPUName() { 680 return "generic"; 681 } 682 #endif 683 684 #if defined(__linux__) && defined(__arm__) 685 bool sys::getHostCPUFeatures(StringMap<bool> &Features) { 686 std::string Err; 687 DataStreamer *DS = getDataFileStreamer("/proc/cpuinfo", &Err); 688 if (!DS) { 689 DEBUG(dbgs() << "Unable to open /proc/cpuinfo: " << Err << "\n"); 690 return false; 691 } 692 693 // Read 1024 bytes from /proc/cpuinfo, which should contain the Features line 694 // in all cases. 695 char buffer[1024]; 696 size_t CPUInfoSize = DS->GetBytes((unsigned char*) buffer, sizeof(buffer)); 697 delete DS; 698 699 StringRef Str(buffer, CPUInfoSize); 700 701 SmallVector<StringRef, 32> Lines; 702 Str.split(Lines, "\n"); 703 704 SmallVector<StringRef, 32> CPUFeatures; 705 706 // Look for the CPU features. 707 for (unsigned I = 0, E = Lines.size(); I != E; ++I) 708 if (Lines[I].startswith("Features")) { 709 Lines[I].split(CPUFeatures, " "); 710 break; 711 } 712 713 for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) { 714 StringRef LLVMFeatureStr = StringSwitch<StringRef>(CPUFeatures[I]) 715 .Case("half", "fp16") 716 .Case("neon", "neon") 717 .Case("vfpv3", "vfp3") 718 .Case("vfpv3d16", "d16") 719 .Case("vfpv4", "vfp4") 720 .Case("idiva", "hwdiv-arm") 721 .Case("idivt", "hwdiv") 722 .Default(""); 723 724 if (LLVMFeatureStr != "") 725 Features.GetOrCreateValue(LLVMFeatureStr).setValue(true); 726 } 727 728 return true; 729 } 730 #else 731 bool sys::getHostCPUFeatures(StringMap<bool> &Features){ 732 return false; 733 } 734 #endif 735 736 std::string sys::getProcessTriple() { 737 Triple PT(Triple::normalize(LLVM_HOST_TRIPLE)); 738 739 if (sizeof(void *) == 8 && PT.isArch32Bit()) 740 PT = PT.get64BitArchVariant(); 741 if (sizeof(void *) == 4 && PT.isArch64Bit()) 742 PT = PT.get32BitArchVariant(); 743 744 return PT.str(); 745 } 746