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.
GetX86CpuIDAndInfo(unsigned value,unsigned * rEAX,unsigned * rEBX,unsigned * rECX,unsigned * rEDX)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
DetectX86FamilyModel(unsigned EAX,unsigned & Family,unsigned & Model)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
getHostCPUName()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__))
getHostCPUName()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__))
getHostCPUName()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__)
getHostCPUName()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
getHostCPUName()519 std::string sys::getHostCPUName() {
520 return "generic";
521 }
522 #endif
523
524 #if defined(__linux__) && defined(__arm__)
getHostCPUFeatures(StringMap<bool> & Features)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
getHostCPUFeatures(StringMap<bool> & Features)581 bool sys::getHostCPUFeatures(StringMap<bool> &Features){
582 return false;
583 }
584 #endif
585
getProcessTriple()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