1 //===-- Host.cpp - Implement OS Host Concept --------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This header file implements the operating system Host concept.
12 //===----------------------------------------------------------------------===//
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/Config/config.h"
19 #include "llvm/Support/DataStream.h"
20 #include "llvm/Support/Debug.h"
21 #include "llvm/Support/raw_ostream.h"
24 // Include the platform-specific parts of this class.
26 #include "Unix/Host.inc"
29 #include "Windows/Host.inc"
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>
41 //===----------------------------------------------------------------------===//
43 // Implementations of the CPU detection routines
45 //===----------------------------------------------------------------------===//
49 #if defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)\
50 || defined(__x86_64__) || defined(_M_AMD64) || defined (_M_X64)
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.
54 static bool GetX86CpuIDAndInfo(unsigned value, unsigned *rEAX,
55 unsigned *rEBX, unsigned *rECX, unsigned *rEDX) {
56 #if defined(__x86_64__) || defined(_M_AMD64) || defined (_M_X64)
58 // gcc doesn't know cpuid would clobber ebx/rbx. Preseve it manually.
59 asm ("movq\t%%rbx, %%rsi\n\t"
61 "xchgq\t%%rbx, %%rsi\n\t"
68 #elif defined(_MSC_VER)
70 __cpuid(registers, value);
79 #elif defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)
81 asm ("movl\t%%ebx, %%esi\n\t"
83 "xchgl\t%%ebx, %%esi\n\t"
90 #elif defined(_MSC_VER)
95 mov dword ptr [esi],eax
97 mov dword ptr [esi],ebx
99 mov dword ptr [esi],ecx
101 mov dword ptr [esi],edx
104 // pedantic #else returns to appease -Wunreachable-code (so we don't generate
105 // postprocessed code that looks like "return true; return false;")
114 static void DetectX86FamilyModel(unsigned EAX, unsigned &Family,
116 Family = (EAX >> 8) & 0xf; // Bits 8 - 11
117 Model = (EAX >> 4) & 0xf; // Bits 4 - 7
118 if (Family == 6 || 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
127 std::string sys::getHostCPUName() {
128 unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
129 if (GetX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX))
133 DetectX86FamilyModel(EAX, Family, Model);
135 bool HasSSE3 = (ECX & 0x1);
136 GetX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
137 bool Em64T = (EDX >> 29) & 0x1;
144 GetX86CpuIDAndInfo(0, &EAX, text.u+0, text.u+2, text.u+1);
145 if (memcmp(text.c, "GenuineIntel", 12) == 0) {
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";
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,
169 case 3: // Pentium OverDrive processors for Intel486 processor-based
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";
178 default: return "pentium";
182 case 1: // Pentium Pro processor
185 case 3: // Intel Pentium II OverDrive processor, Pentium II processor,
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
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
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.
205 case 14: // Intel Core Duo processor, Intel Core Solo processor, model
206 // 0Eh. All processors are manufactured using the 65 nm process.
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
218 case 21: // Intel EP80579 Integrated Processor and Intel EP80579
219 // Integrated Processor with Intel QuickAssist Technology
220 return "i686"; // FIXME: ???
222 case 23: // Intel Core 2 Extreme processor, Intel Xeon processor, model
223 // 17h. All processors are manufactured using the 45 nm process.
225 // 45nm: Penryn , Wolfdale, Yorkfield (XE)
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
242 case 42: // Intel Core i7 processor. All processors are manufactured
243 // using the 32 nm process.
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
258 default: return (Em64T) ? "x86-64" : "i686";
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";
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";
287 return (Em64T) ? "x86-64" : "pentium4";
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.
305 case 8: return "k6-2";
307 case 13: return "k6-3";
308 case 10: return "geode";
309 default: return "pentium";
313 case 4: return "athlon-tbird";
316 case 8: return "athlon-mp";
317 case 10: return "athlon-xp";
318 default: return "athlon";
324 case 1: return "opteron";
325 case 5: return "athlon-fx"; // also opteron
326 default: return "athlon64";
340 #elif defined(__APPLE__) && (defined(__ppc__) || defined(__powerpc__))
341 std::string sys::getHostCPUName() {
342 host_basic_info_data_t hostInfo;
343 mach_msg_type_number_t infoCount;
345 infoCount = HOST_BASIC_INFO_COUNT;
346 host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostInfo,
349 if (hostInfo.cpu_type != CPU_TYPE_POWERPC) return "generic";
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";
369 #elif defined(__linux__) && (defined(__ppc__) || defined(__powerpc__))
370 std::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";
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
381 DataStreamer *DS = getDataFileStreamer("/proc/cpuinfo", &Err);
383 DEBUG(dbgs() << "Unable to open /proc/cpuinfo: " << Err << "\n");
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).
390 size_t CPUInfoSize = DS->GetBytes((unsigned char*) buffer, sizeof(buffer));
393 const char *CPUInfoStart = buffer;
394 const char *CPUInfoEnd = buffer + CPUInfoSize;
396 const char *CIP = CPUInfoStart;
398 const char *CPUStart = 0;
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')
407 if (CIP < CPUInfoEnd && *CIP == 'c') {
409 if (CIP < CPUInfoEnd && *CIP == 'p') {
411 if (CIP < CPUInfoEnd && *CIP == 'u') {
413 while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t'))
416 if (CIP < CPUInfoEnd && *CIP == ':') {
418 while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t'))
421 if (CIP < CPUInfoEnd) {
423 while (CIP < CPUInfoEnd && (*CIP != ' ' && *CIP != '\t' &&
424 *CIP != ',' && *CIP != '\n'))
426 CPULen = CIP - CPUStart;
434 while (CIP < CPUInfoEnd && *CIP != '\n')
441 return StringSwitch<const char *>(StringRef(CPUStart, CPULen))
442 .Case("604e", "604e")
444 .Case("7400", "7400")
445 .Case("7410", "7400")
446 .Case("7447", "7400")
447 .Case("7455", "7450")
449 .Case("POWER4", "970")
450 .Case("PPC970FX", "970")
451 .Case("PPC970MP", "970")
453 .Case("POWER5", "g5")
455 .Case("POWER6", "pwr6")
456 .Case("POWER7", "pwr7")
459 #elif defined(__linux__) && defined(__arm__)
460 std::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
468 DataStreamer *DS = getDataFileStreamer("/proc/cpuinfo", &Err);
470 DEBUG(dbgs() << "Unable to open /proc/cpuinfo: " << Err << "\n");
474 // Read 1024 bytes from /proc/cpuinfo, which should contain the CPU part line
477 size_t CPUInfoSize = DS->GetBytes((unsigned char*) buffer, sizeof(buffer));
480 StringRef Str(buffer, CPUInfoSize);
482 SmallVector<StringRef, 32> Lines;
483 Str.split(Lines, "\n");
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 :");
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")
515 std::string sys::getHostCPUName() {
520 bool sys::getHostCPUFeatures(StringMap<bool> &Features){