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