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, 56 unsigned *rEBX, unsigned *rECX, unsigned *rEDX) { 57 #if defined(__x86_64__) || defined(_M_AMD64) || defined (_M_X64) 58 #if defined(__GNUC__) 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(_MSC_VER) 70 int registers[4]; 71 __cpuid(registers, value); 72 *rEAX = registers[0]; 73 *rEBX = registers[1]; 74 *rECX = registers[2]; 75 *rEDX = registers[3]; 76 return false; 77 #else 78 return true; 79 #endif 80 #elif defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86) 81 #if defined(__GNUC__) 82 asm ("movl\t%%ebx, %%esi\n\t" 83 "cpuid\n\t" 84 "xchgl\t%%ebx, %%esi\n\t" 85 : "=a" (*rEAX), 86 "=S" (*rEBX), 87 "=c" (*rECX), 88 "=d" (*rEDX) 89 : "a" (value)); 90 return false; 91 #elif defined(_MSC_VER) 92 __asm { 93 mov eax,value 94 cpuid 95 mov esi,rEAX 96 mov dword ptr [esi],eax 97 mov esi,rEBX 98 mov dword ptr [esi],ebx 99 mov esi,rECX 100 mov dword ptr [esi],ecx 101 mov esi,rEDX 102 mov dword ptr [esi],edx 103 } 104 return false; 105 // pedantic #else returns to appease -Wunreachable-code (so we don't generate 106 // postprocessed code that looks like "return true; return false;") 107 #else 108 return true; 109 #endif 110 #else 111 return true; 112 #endif 113 } 114 115 static void DetectX86FamilyModel(unsigned EAX, unsigned &Family, 116 unsigned &Model) { 117 Family = (EAX >> 8) & 0xf; // Bits 8 - 11 118 Model = (EAX >> 4) & 0xf; // Bits 4 - 7 119 if (Family == 6 || Family == 0xf) { 120 if (Family == 0xf) 121 // Examine extended family ID if family ID is F. 122 Family += (EAX >> 20) & 0xff; // Bits 20 - 27 123 // Examine extended model ID if family ID is 6 or F. 124 Model += ((EAX >> 16) & 0xf) << 4; // Bits 16 - 19 125 } 126 } 127 128 std::string sys::getHostCPUName() { 129 unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0; 130 if (GetX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX)) 131 return "generic"; 132 unsigned Family = 0; 133 unsigned Model = 0; 134 DetectX86FamilyModel(EAX, Family, Model); 135 136 bool HasSSE3 = (ECX & 0x1); 137 GetX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX); 138 bool Em64T = (EDX >> 29) & 0x1; 139 140 union { 141 unsigned u[3]; 142 char c[12]; 143 } text; 144 145 GetX86CpuIDAndInfo(0, &EAX, text.u+0, text.u+2, text.u+1); 146 if (memcmp(text.c, "GenuineIntel", 12) == 0) { 147 switch (Family) { 148 case 3: 149 return "i386"; 150 case 4: 151 switch (Model) { 152 case 0: // Intel486 DX processors 153 case 1: // Intel486 DX processors 154 case 2: // Intel486 SX processors 155 case 3: // Intel487 processors, IntelDX2 OverDrive processors, 156 // IntelDX2 processors 157 case 4: // Intel486 SL processor 158 case 5: // IntelSX2 processors 159 case 7: // Write-Back Enhanced IntelDX2 processors 160 case 8: // IntelDX4 OverDrive processors, IntelDX4 processors 161 default: return "i486"; 162 } 163 case 5: 164 switch (Model) { 165 case 1: // Pentium OverDrive processor for Pentium processor (60, 66), 166 // Pentium processors (60, 66) 167 case 2: // Pentium OverDrive processor for Pentium processor (75, 90, 168 // 100, 120, 133), Pentium processors (75, 90, 100, 120, 133, 169 // 150, 166, 200) 170 case 3: // Pentium OverDrive processors for Intel486 processor-based 171 // systems 172 return "pentium"; 173 174 case 4: // Pentium OverDrive processor with MMX technology for Pentium 175 // processor (75, 90, 100, 120, 133), Pentium processor with 176 // MMX technology (166, 200) 177 return "pentium-mmx"; 178 179 default: return "pentium"; 180 } 181 case 6: 182 switch (Model) { 183 case 1: // Pentium Pro processor 184 return "pentiumpro"; 185 186 case 3: // Intel Pentium II OverDrive processor, Pentium II processor, 187 // model 03 188 case 5: // Pentium II processor, model 05, Pentium II Xeon processor, 189 // model 05, and Intel Celeron processor, model 05 190 case 6: // Celeron processor, model 06 191 return "pentium2"; 192 193 case 7: // Pentium III processor, model 07, and Pentium III Xeon 194 // processor, model 07 195 case 8: // Pentium III processor, model 08, Pentium III Xeon processor, 196 // model 08, and Celeron processor, model 08 197 case 10: // Pentium III Xeon processor, model 0Ah 198 case 11: // Pentium III processor, model 0Bh 199 return "pentium3"; 200 201 case 9: // Intel Pentium M processor, Intel Celeron M processor model 09. 202 case 13: // Intel Pentium M processor, Intel Celeron M processor, model 203 // 0Dh. All processors are manufactured using the 90 nm process. 204 return "pentium-m"; 205 206 case 14: // Intel Core Duo processor, Intel Core Solo processor, model 207 // 0Eh. All processors are manufactured using the 65 nm process. 208 return "yonah"; 209 210 case 15: // Intel Core 2 Duo processor, Intel Core 2 Duo mobile 211 // processor, Intel Core 2 Quad processor, Intel Core 2 Quad 212 // mobile processor, Intel Core 2 Extreme processor, Intel 213 // Pentium Dual-Core processor, Intel Xeon processor, model 214 // 0Fh. All processors are manufactured using the 65 nm process. 215 case 22: // Intel Celeron processor model 16h. All processors are 216 // manufactured using the 65 nm process 217 return "core2"; 218 219 case 21: // Intel EP80579 Integrated Processor and Intel EP80579 220 // Integrated Processor with Intel QuickAssist Technology 221 return "i686"; // FIXME: ??? 222 223 case 23: // Intel Core 2 Extreme processor, Intel Xeon processor, model 224 // 17h. All processors are manufactured using the 45 nm process. 225 // 226 // 45nm: Penryn , Wolfdale, Yorkfield (XE) 227 return "penryn"; 228 229 case 26: // Intel Core i7 processor and Intel Xeon processor. All 230 // processors are manufactured using the 45 nm process. 231 case 29: // Intel Xeon processor MP. All processors are manufactured using 232 // the 45 nm process. 233 case 30: // Intel(R) Core(TM) i7 CPU 870 @ 2.93GHz. 234 // As found in a Summer 2010 model iMac. 235 case 37: // Intel Core i7, laptop version. 236 case 44: // Intel Core i7 processor and Intel Xeon processor. All 237 // processors are manufactured using the 32 nm process. 238 case 46: // Nehalem EX 239 case 47: // Westmere EX 240 return "corei7"; 241 242 // SandyBridge: 243 case 42: // Intel Core i7 processor. All processors are manufactured 244 // using the 32 nm process. 245 case 45: 246 return "corei7-avx"; 247 248 // Ivy Bridge: 249 case 58: 250 return "core-avx-i"; 251 252 case 28: // Most 45 nm Intel Atom processors 253 case 38: // 45 nm Atom Lincroft 254 case 39: // 32 nm Atom Medfield 255 case 53: // 32 nm Atom Midview 256 case 54: // 32 nm Atom Midview 257 return "atom"; 258 259 default: return (Em64T) ? "x86-64" : "i686"; 260 } 261 case 15: { 262 switch (Model) { 263 case 0: // Pentium 4 processor, Intel Xeon processor. All processors are 264 // model 00h and manufactured using the 0.18 micron process. 265 case 1: // Pentium 4 processor, Intel Xeon processor, Intel Xeon 266 // processor MP, and Intel Celeron processor. All processors are 267 // model 01h and manufactured using the 0.18 micron process. 268 case 2: // Pentium 4 processor, Mobile Intel Pentium 4 processor - M, 269 // Intel Xeon processor, Intel Xeon processor MP, Intel Celeron 270 // processor, and Mobile Intel Celeron processor. All processors 271 // are model 02h and manufactured using the 0.13 micron process. 272 return (Em64T) ? "x86-64" : "pentium4"; 273 274 case 3: // Pentium 4 processor, Intel Xeon processor, Intel Celeron D 275 // processor. All processors are model 03h and manufactured using 276 // the 90 nm process. 277 case 4: // Pentium 4 processor, Pentium 4 processor Extreme Edition, 278 // Pentium D processor, Intel Xeon processor, Intel Xeon 279 // processor MP, Intel Celeron D processor. All processors are 280 // model 04h and manufactured using the 90 nm process. 281 case 6: // Pentium 4 processor, Pentium D processor, Pentium processor 282 // Extreme Edition, Intel Xeon processor, Intel Xeon processor 283 // MP, Intel Celeron D processor. All processors are model 06h 284 // and manufactured using the 65 nm process. 285 return (Em64T) ? "nocona" : "prescott"; 286 287 default: 288 return (Em64T) ? "x86-64" : "pentium4"; 289 } 290 } 291 292 default: 293 return "generic"; 294 } 295 } else if (memcmp(text.c, "AuthenticAMD", 12) == 0) { 296 // FIXME: this poorly matches the generated SubtargetFeatureKV table. There 297 // appears to be no way to generate the wide variety of AMD-specific targets 298 // from the information returned from CPUID. 299 switch (Family) { 300 case 4: 301 return "i486"; 302 case 5: 303 switch (Model) { 304 case 6: 305 case 7: return "k6"; 306 case 8: return "k6-2"; 307 case 9: 308 case 13: return "k6-3"; 309 case 10: return "geode"; 310 default: return "pentium"; 311 } 312 case 6: 313 switch (Model) { 314 case 4: return "athlon-tbird"; 315 case 6: 316 case 7: 317 case 8: return "athlon-mp"; 318 case 10: return "athlon-xp"; 319 default: return "athlon"; 320 } 321 case 15: 322 if (HasSSE3) 323 return "k8-sse3"; 324 switch (Model) { 325 case 1: return "opteron"; 326 case 5: return "athlon-fx"; // also opteron 327 default: return "athlon64"; 328 } 329 case 16: 330 return "amdfam10"; 331 case 20: 332 return "btver1"; 333 case 21: 334 return "bdver1"; 335 default: 336 return "generic"; 337 } 338 } 339 return "generic"; 340 } 341 #elif defined(__APPLE__) && (defined(__ppc__) || defined(__powerpc__)) 342 std::string sys::getHostCPUName() { 343 host_basic_info_data_t hostInfo; 344 mach_msg_type_number_t infoCount; 345 346 infoCount = HOST_BASIC_INFO_COUNT; 347 host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostInfo, 348 &infoCount); 349 350 if (hostInfo.cpu_type != CPU_TYPE_POWERPC) return "generic"; 351 352 switch(hostInfo.cpu_subtype) { 353 case CPU_SUBTYPE_POWERPC_601: return "601"; 354 case CPU_SUBTYPE_POWERPC_602: return "602"; 355 case CPU_SUBTYPE_POWERPC_603: return "603"; 356 case CPU_SUBTYPE_POWERPC_603e: return "603e"; 357 case CPU_SUBTYPE_POWERPC_603ev: return "603ev"; 358 case CPU_SUBTYPE_POWERPC_604: return "604"; 359 case CPU_SUBTYPE_POWERPC_604e: return "604e"; 360 case CPU_SUBTYPE_POWERPC_620: return "620"; 361 case CPU_SUBTYPE_POWERPC_750: return "750"; 362 case CPU_SUBTYPE_POWERPC_7400: return "7400"; 363 case CPU_SUBTYPE_POWERPC_7450: return "7450"; 364 case CPU_SUBTYPE_POWERPC_970: return "970"; 365 default: ; 366 } 367 368 return "generic"; 369 } 370 #elif defined(__linux__) && (defined(__ppc__) || defined(__powerpc__)) 371 std::string sys::getHostCPUName() { 372 // Access to the Processor Version Register (PVR) on PowerPC is privileged, 373 // and so we must use an operating-system interface to determine the current 374 // processor type. On Linux, this is exposed through the /proc/cpuinfo file. 375 const char *generic = "generic"; 376 377 // Note: We cannot mmap /proc/cpuinfo here and then process the resulting 378 // memory buffer because the 'file' has 0 size (it can be read from only 379 // as a stream). 380 381 std::string Err; 382 DataStreamer *DS = getDataFileStreamer("/proc/cpuinfo", &Err); 383 if (!DS) { 384 DEBUG(dbgs() << "Unable to open /proc/cpuinfo: " << Err << "\n"); 385 return generic; 386 } 387 388 // The cpu line is second (after the 'processor: 0' line), so if this 389 // buffer is too small then something has changed (or is wrong). 390 char buffer[1024]; 391 size_t CPUInfoSize = DS->GetBytes((unsigned char*) buffer, sizeof(buffer)); 392 delete DS; 393 394 const char *CPUInfoStart = buffer; 395 const char *CPUInfoEnd = buffer + CPUInfoSize; 396 397 const char *CIP = CPUInfoStart; 398 399 const char *CPUStart = 0; 400 size_t CPULen = 0; 401 402 // We need to find the first line which starts with cpu, spaces, and a colon. 403 // After the colon, there may be some additional spaces and then the cpu type. 404 while (CIP < CPUInfoEnd && CPUStart == 0) { 405 if (CIP < CPUInfoEnd && *CIP == '\n') 406 ++CIP; 407 408 if (CIP < CPUInfoEnd && *CIP == 'c') { 409 ++CIP; 410 if (CIP < CPUInfoEnd && *CIP == 'p') { 411 ++CIP; 412 if (CIP < CPUInfoEnd && *CIP == 'u') { 413 ++CIP; 414 while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t')) 415 ++CIP; 416 417 if (CIP < CPUInfoEnd && *CIP == ':') { 418 ++CIP; 419 while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t')) 420 ++CIP; 421 422 if (CIP < CPUInfoEnd) { 423 CPUStart = CIP; 424 while (CIP < CPUInfoEnd && (*CIP != ' ' && *CIP != '\t' && 425 *CIP != ',' && *CIP != '\n')) 426 ++CIP; 427 CPULen = CIP - CPUStart; 428 } 429 } 430 } 431 } 432 } 433 434 if (CPUStart == 0) 435 while (CIP < CPUInfoEnd && *CIP != '\n') 436 ++CIP; 437 } 438 439 if (CPUStart == 0) 440 return generic; 441 442 return StringSwitch<const char *>(StringRef(CPUStart, CPULen)) 443 .Case("604e", "604e") 444 .Case("604", "604") 445 .Case("7400", "7400") 446 .Case("7410", "7400") 447 .Case("7447", "7400") 448 .Case("7455", "7450") 449 .Case("G4", "g4") 450 .Case("POWER4", "970") 451 .Case("PPC970FX", "970") 452 .Case("PPC970MP", "970") 453 .Case("G5", "g5") 454 .Case("POWER5", "g5") 455 .Case("A2", "a2") 456 .Case("POWER6", "pwr6") 457 .Case("POWER7", "pwr7") 458 .Default(generic); 459 } 460 #elif defined(__linux__) && defined(__arm__) 461 std::string sys::getHostCPUName() { 462 // The cpuid register on arm is not accessible from user space. On Linux, 463 // it is exposed through the /proc/cpuinfo file. 464 // Note: We cannot mmap /proc/cpuinfo here and then process the resulting 465 // memory buffer because the 'file' has 0 size (it can be read from only 466 // as a stream). 467 468 std::string Err; 469 DataStreamer *DS = getDataFileStreamer("/proc/cpuinfo", &Err); 470 if (!DS) { 471 DEBUG(dbgs() << "Unable to open /proc/cpuinfo: " << Err << "\n"); 472 return "generic"; 473 } 474 475 // Read 1024 bytes from /proc/cpuinfo, which should contain the CPU part line 476 // in all cases. 477 char buffer[1024]; 478 size_t CPUInfoSize = DS->GetBytes((unsigned char*) buffer, sizeof(buffer)); 479 delete DS; 480 481 StringRef Str(buffer, CPUInfoSize); 482 483 SmallVector<StringRef, 32> Lines; 484 Str.split(Lines, "\n"); 485 486 // Look for the CPU implementer line. 487 StringRef Implementer; 488 for (unsigned I = 0, E = Lines.size(); I != E; ++I) 489 if (Lines[I].startswith("CPU implementer")) 490 Implementer = Lines[I].substr(15).ltrim("\t :"); 491 492 if (Implementer == "0x41") // ARM Ltd. 493 // Look for the CPU part line. 494 for (unsigned I = 0, E = Lines.size(); I != E; ++I) 495 if (Lines[I].startswith("CPU part")) 496 // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The 497 // values correspond to the "Part number" in the CP15/c0 register. The 498 // contents are specified in the various processor manuals. 499 return StringSwitch<const char *>(Lines[I].substr(8).ltrim("\t :")) 500 .Case("0x926", "arm926ej-s") 501 .Case("0xb02", "mpcore") 502 .Case("0xb36", "arm1136j-s") 503 .Case("0xb56", "arm1156t2-s") 504 .Case("0xb76", "arm1176jz-s") 505 .Case("0xc08", "cortex-a8") 506 .Case("0xc09", "cortex-a9") 507 .Case("0xc0f", "cortex-a15") 508 .Case("0xc20", "cortex-m0") 509 .Case("0xc23", "cortex-m3") 510 .Case("0xc24", "cortex-m4") 511 .Default("generic"); 512 513 return "generic"; 514 } 515 #else 516 std::string sys::getHostCPUName() { 517 return "generic"; 518 } 519 #endif 520 521 #if defined(__linux__) && defined(__arm__) 522 bool sys::getHostCPUFeatures(StringMap<bool> &Features) { 523 std::string Err; 524 DataStreamer *DS = getDataFileStreamer("/proc/cpuinfo", &Err); 525 if (!DS) { 526 DEBUG(dbgs() << "Unable to open /proc/cpuinfo: " << Err << "\n"); 527 return false; 528 } 529 530 // Read 1024 bytes from /proc/cpuinfo, which should contain the Features line 531 // in all cases. 532 char buffer[1024]; 533 size_t CPUInfoSize = DS->GetBytes((unsigned char*) buffer, sizeof(buffer)); 534 delete DS; 535 536 StringRef Str(buffer, CPUInfoSize); 537 538 SmallVector<StringRef, 32> Lines; 539 Str.split(Lines, "\n"); 540 541 // Look for the CPU implementer line. 542 StringRef Implementer; 543 for (unsigned I = 0, E = Lines.size(); I != E; ++I) 544 if (Lines[I].startswith("CPU implementer")) 545 Implementer = Lines[I].substr(15).ltrim("\t :"); 546 547 if (Implementer == "0x41") { // ARM Ltd. 548 SmallVector<StringRef, 32> CPUFeatures; 549 550 // Look for the CPU features. 551 for (unsigned I = 0, E = Lines.size(); I != E; ++I) 552 if (Lines[I].startswith("Features")) { 553 Lines[I].split(CPUFeatures, " "); 554 break; 555 } 556 557 for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) { 558 StringRef LLVMFeatureStr = StringSwitch<StringRef>(CPUFeatures[I]) 559 .Case("half", "fp16") 560 .Case("neon", "neon") 561 .Case("vfpv3", "vfp3") 562 .Case("vfpv3d16", "d16") 563 .Case("vfpv4", "vfp4") 564 .Case("idiva", "hwdiv-arm") 565 .Case("idivt", "hwdiv") 566 .Default(""); 567 568 if (LLVMFeatureStr != "") 569 Features.GetOrCreateValue(LLVMFeatureStr).setValue(true); 570 } 571 572 return true; 573 } 574 575 return false; 576 } 577 #else 578 bool sys::getHostCPUFeatures(StringMap<bool> &Features){ 579 return false; 580 } 581 #endif 582 583 std::string sys::getProcessTriple() { 584 Triple PT(LLVM_HOSTTRIPLE); 585 586 if (sizeof(void *) == 8 && PT.isArch32Bit()) 587 PT = PT.get64BitArchVariant(); 588 if (sizeof(void *) == 4 && PT.isArch64Bit()) 589 PT = PT.get32BitArchVariant(); 590 591 return PT.str(); 592 } 593