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