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 if (Model <= 15) 335 return "bdver1"; 336 else if (Model <= 31) 337 return "bdver2"; 338 default: 339 return "generic"; 340 } 341 } 342 return "generic"; 343 } 344 #elif defined(__APPLE__) && (defined(__ppc__) || defined(__powerpc__)) 345 std::string sys::getHostCPUName() { 346 host_basic_info_data_t hostInfo; 347 mach_msg_type_number_t infoCount; 348 349 infoCount = HOST_BASIC_INFO_COUNT; 350 host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostInfo, 351 &infoCount); 352 353 if (hostInfo.cpu_type != CPU_TYPE_POWERPC) return "generic"; 354 355 switch(hostInfo.cpu_subtype) { 356 case CPU_SUBTYPE_POWERPC_601: return "601"; 357 case CPU_SUBTYPE_POWERPC_602: return "602"; 358 case CPU_SUBTYPE_POWERPC_603: return "603"; 359 case CPU_SUBTYPE_POWERPC_603e: return "603e"; 360 case CPU_SUBTYPE_POWERPC_603ev: return "603ev"; 361 case CPU_SUBTYPE_POWERPC_604: return "604"; 362 case CPU_SUBTYPE_POWERPC_604e: return "604e"; 363 case CPU_SUBTYPE_POWERPC_620: return "620"; 364 case CPU_SUBTYPE_POWERPC_750: return "750"; 365 case CPU_SUBTYPE_POWERPC_7400: return "7400"; 366 case CPU_SUBTYPE_POWERPC_7450: return "7450"; 367 case CPU_SUBTYPE_POWERPC_970: return "970"; 368 default: ; 369 } 370 371 return "generic"; 372 } 373 #elif defined(__linux__) && (defined(__ppc__) || defined(__powerpc__)) 374 std::string sys::getHostCPUName() { 375 // Access to the Processor Version Register (PVR) on PowerPC is privileged, 376 // and so we must use an operating-system interface to determine the current 377 // processor type. On Linux, this is exposed through the /proc/cpuinfo file. 378 const char *generic = "generic"; 379 380 // Note: We cannot mmap /proc/cpuinfo here and then process the resulting 381 // memory buffer because the 'file' has 0 size (it can be read from only 382 // as a stream). 383 384 std::string Err; 385 DataStreamer *DS = getDataFileStreamer("/proc/cpuinfo", &Err); 386 if (!DS) { 387 DEBUG(dbgs() << "Unable to open /proc/cpuinfo: " << Err << "\n"); 388 return generic; 389 } 390 391 // The cpu line is second (after the 'processor: 0' line), so if this 392 // buffer is too small then something has changed (or is wrong). 393 char buffer[1024]; 394 size_t CPUInfoSize = DS->GetBytes((unsigned char*) buffer, sizeof(buffer)); 395 delete DS; 396 397 const char *CPUInfoStart = buffer; 398 const char *CPUInfoEnd = buffer + CPUInfoSize; 399 400 const char *CIP = CPUInfoStart; 401 402 const char *CPUStart = 0; 403 size_t CPULen = 0; 404 405 // We need to find the first line which starts with cpu, spaces, and a colon. 406 // After the colon, there may be some additional spaces and then the cpu type. 407 while (CIP < CPUInfoEnd && CPUStart == 0) { 408 if (CIP < CPUInfoEnd && *CIP == '\n') 409 ++CIP; 410 411 if (CIP < CPUInfoEnd && *CIP == 'c') { 412 ++CIP; 413 if (CIP < CPUInfoEnd && *CIP == 'p') { 414 ++CIP; 415 if (CIP < CPUInfoEnd && *CIP == 'u') { 416 ++CIP; 417 while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t')) 418 ++CIP; 419 420 if (CIP < CPUInfoEnd && *CIP == ':') { 421 ++CIP; 422 while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t')) 423 ++CIP; 424 425 if (CIP < CPUInfoEnd) { 426 CPUStart = CIP; 427 while (CIP < CPUInfoEnd && (*CIP != ' ' && *CIP != '\t' && 428 *CIP != ',' && *CIP != '\n')) 429 ++CIP; 430 CPULen = CIP - CPUStart; 431 } 432 } 433 } 434 } 435 } 436 437 if (CPUStart == 0) 438 while (CIP < CPUInfoEnd && *CIP != '\n') 439 ++CIP; 440 } 441 442 if (CPUStart == 0) 443 return generic; 444 445 return StringSwitch<const char *>(StringRef(CPUStart, CPULen)) 446 .Case("604e", "604e") 447 .Case("604", "604") 448 .Case("7400", "7400") 449 .Case("7410", "7400") 450 .Case("7447", "7400") 451 .Case("7455", "7450") 452 .Case("G4", "g4") 453 .Case("POWER4", "970") 454 .Case("PPC970FX", "970") 455 .Case("PPC970MP", "970") 456 .Case("G5", "g5") 457 .Case("POWER5", "g5") 458 .Case("A2", "a2") 459 .Case("POWER6", "pwr6") 460 .Case("POWER7", "pwr7") 461 .Default(generic); 462 } 463 #elif defined(__linux__) && defined(__arm__) 464 std::string sys::getHostCPUName() { 465 // The cpuid register on arm is not accessible from user space. On Linux, 466 // it is exposed through the /proc/cpuinfo file. 467 // Note: We cannot mmap /proc/cpuinfo here and then process the resulting 468 // memory buffer because the 'file' has 0 size (it can be read from only 469 // as a stream). 470 471 std::string Err; 472 DataStreamer *DS = getDataFileStreamer("/proc/cpuinfo", &Err); 473 if (!DS) { 474 DEBUG(dbgs() << "Unable to open /proc/cpuinfo: " << Err << "\n"); 475 return "generic"; 476 } 477 478 // Read 1024 bytes from /proc/cpuinfo, which should contain the CPU part line 479 // in all cases. 480 char buffer[1024]; 481 size_t CPUInfoSize = DS->GetBytes((unsigned char*) buffer, sizeof(buffer)); 482 delete DS; 483 484 StringRef Str(buffer, CPUInfoSize); 485 486 SmallVector<StringRef, 32> Lines; 487 Str.split(Lines, "\n"); 488 489 // Look for the CPU implementer line. 490 StringRef Implementer; 491 for (unsigned I = 0, E = Lines.size(); I != E; ++I) 492 if (Lines[I].startswith("CPU implementer")) 493 Implementer = Lines[I].substr(15).ltrim("\t :"); 494 495 if (Implementer == "0x41") // ARM Ltd. 496 // Look for the CPU part line. 497 for (unsigned I = 0, E = Lines.size(); I != E; ++I) 498 if (Lines[I].startswith("CPU part")) 499 // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The 500 // values correspond to the "Part number" in the CP15/c0 register. The 501 // contents are specified in the various processor manuals. 502 return StringSwitch<const char *>(Lines[I].substr(8).ltrim("\t :")) 503 .Case("0x926", "arm926ej-s") 504 .Case("0xb02", "mpcore") 505 .Case("0xb36", "arm1136j-s") 506 .Case("0xb56", "arm1156t2-s") 507 .Case("0xb76", "arm1176jz-s") 508 .Case("0xc08", "cortex-a8") 509 .Case("0xc09", "cortex-a9") 510 .Case("0xc0f", "cortex-a15") 511 .Case("0xc20", "cortex-m0") 512 .Case("0xc23", "cortex-m3") 513 .Case("0xc24", "cortex-m4") 514 .Default("generic"); 515 516 return "generic"; 517 } 518 #else 519 std::string sys::getHostCPUName() { 520 return "generic"; 521 } 522 #endif 523 524 #if defined(__linux__) && defined(__arm__) 525 bool sys::getHostCPUFeatures(StringMap<bool> &Features) { 526 std::string Err; 527 DataStreamer *DS = getDataFileStreamer("/proc/cpuinfo", &Err); 528 if (!DS) { 529 DEBUG(dbgs() << "Unable to open /proc/cpuinfo: " << Err << "\n"); 530 return false; 531 } 532 533 // Read 1024 bytes from /proc/cpuinfo, which should contain the Features line 534 // in all cases. 535 char buffer[1024]; 536 size_t CPUInfoSize = DS->GetBytes((unsigned char*) buffer, sizeof(buffer)); 537 delete DS; 538 539 StringRef Str(buffer, CPUInfoSize); 540 541 SmallVector<StringRef, 32> Lines; 542 Str.split(Lines, "\n"); 543 544 // Look for the CPU implementer line. 545 StringRef Implementer; 546 for (unsigned I = 0, E = Lines.size(); I != E; ++I) 547 if (Lines[I].startswith("CPU implementer")) 548 Implementer = Lines[I].substr(15).ltrim("\t :"); 549 550 if (Implementer == "0x41") { // ARM Ltd. 551 SmallVector<StringRef, 32> CPUFeatures; 552 553 // Look for the CPU features. 554 for (unsigned I = 0, E = Lines.size(); I != E; ++I) 555 if (Lines[I].startswith("Features")) { 556 Lines[I].split(CPUFeatures, " "); 557 break; 558 } 559 560 for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) { 561 StringRef LLVMFeatureStr = StringSwitch<StringRef>(CPUFeatures[I]) 562 .Case("half", "fp16") 563 .Case("neon", "neon") 564 .Case("vfpv3", "vfp3") 565 .Case("vfpv3d16", "d16") 566 .Case("vfpv4", "vfp4") 567 .Case("idiva", "hwdiv-arm") 568 .Case("idivt", "hwdiv") 569 .Default(""); 570 571 if (LLVMFeatureStr != "") 572 Features.GetOrCreateValue(LLVMFeatureStr).setValue(true); 573 } 574 575 return true; 576 } 577 578 return false; 579 } 580 #else 581 bool sys::getHostCPUFeatures(StringMap<bool> &Features){ 582 return false; 583 } 584 #endif 585 586 std::string sys::getProcessTriple() { 587 Triple PT(LLVM_HOSTTRIPLE); 588 589 if (sizeof(void *) == 8 && PT.isArch32Bit()) 590 PT = PT.get64BitArchVariant(); 591 if (sizeof(void *) == 4 && PT.isArch64Bit()) 592 PT = PT.get32BitArchVariant(); 593 594 return PT.str(); 595 } 596