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
47 using 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.
GetX86CpuIDAndInfo(unsigned value,unsigned * rEAX,unsigned * rEBX,unsigned * rECX,unsigned * rEDX)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)
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
DetectX86FamilyModel(unsigned EAX,unsigned & Family,unsigned & Model)114 static 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
getHostCPUName()127 std::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 return "corei7";
238
239 // SandyBridge:
240 case 42: // Intel Core i7 processor. All processors are manufactured
241 // using the 32 nm process.
242 case 45:
243 return "corei7-avx";
244
245 // Ivy Bridge:
246 case 58:
247 return "core-avx-i";
248
249 case 28: // Most 45 nm Intel Atom processors
250 case 38: // 45 nm Atom Lincroft
251 case 39: // 32 nm Atom Medfield
252 case 53: // 32 nm Atom Midview
253 case 54: // 32 nm Atom Midview
254 return "atom";
255
256 default: return (Em64T) ? "x86-64" : "i686";
257 }
258 case 15: {
259 switch (Model) {
260 case 0: // Pentium 4 processor, Intel Xeon processor. All processors are
261 // model 00h and manufactured using the 0.18 micron process.
262 case 1: // Pentium 4 processor, Intel Xeon processor, Intel Xeon
263 // processor MP, and Intel Celeron processor. All processors are
264 // model 01h and manufactured using the 0.18 micron process.
265 case 2: // Pentium 4 processor, Mobile Intel Pentium 4 processor - M,
266 // Intel Xeon processor, Intel Xeon processor MP, Intel Celeron
267 // processor, and Mobile Intel Celeron processor. All processors
268 // are model 02h and manufactured using the 0.13 micron process.
269 return (Em64T) ? "x86-64" : "pentium4";
270
271 case 3: // Pentium 4 processor, Intel Xeon processor, Intel Celeron D
272 // processor. All processors are model 03h and manufactured using
273 // the 90 nm process.
274 case 4: // Pentium 4 processor, Pentium 4 processor Extreme Edition,
275 // Pentium D processor, Intel Xeon processor, Intel Xeon
276 // processor MP, Intel Celeron D processor. All processors are
277 // model 04h and manufactured using the 90 nm process.
278 case 6: // Pentium 4 processor, Pentium D processor, Pentium processor
279 // Extreme Edition, Intel Xeon processor, Intel Xeon processor
280 // MP, Intel Celeron D processor. All processors are model 06h
281 // and manufactured using the 65 nm process.
282 return (Em64T) ? "nocona" : "prescott";
283
284 default:
285 return (Em64T) ? "x86-64" : "pentium4";
286 }
287 }
288
289 default:
290 return "generic";
291 }
292 } else if (memcmp(text.c, "AuthenticAMD", 12) == 0) {
293 // FIXME: this poorly matches the generated SubtargetFeatureKV table. There
294 // appears to be no way to generate the wide variety of AMD-specific targets
295 // from the information returned from CPUID.
296 switch (Family) {
297 case 4:
298 return "i486";
299 case 5:
300 switch (Model) {
301 case 6:
302 case 7: return "k6";
303 case 8: return "k6-2";
304 case 9:
305 case 13: return "k6-3";
306 default: return "pentium";
307 }
308 case 6:
309 switch (Model) {
310 case 4: return "athlon-tbird";
311 case 6:
312 case 7:
313 case 8: return "athlon-mp";
314 case 10: return "athlon-xp";
315 default: return "athlon";
316 }
317 case 15:
318 if (HasSSE3)
319 return "k8-sse3";
320 switch (Model) {
321 case 1: return "opteron";
322 case 5: return "athlon-fx"; // also opteron
323 default: return "athlon64";
324 }
325 case 16:
326 return "amdfam10";
327 case 20:
328 return "btver1";
329 case 21:
330 return "bdver1";
331 default:
332 return "generic";
333 }
334 }
335 return "generic";
336 }
337 #elif defined(__APPLE__) && (defined(__ppc__) || defined(__powerpc__))
getHostCPUName()338 std::string sys::getHostCPUName() {
339 host_basic_info_data_t hostInfo;
340 mach_msg_type_number_t infoCount;
341
342 infoCount = HOST_BASIC_INFO_COUNT;
343 host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostInfo,
344 &infoCount);
345
346 if (hostInfo.cpu_type != CPU_TYPE_POWERPC) return "generic";
347
348 switch(hostInfo.cpu_subtype) {
349 case CPU_SUBTYPE_POWERPC_601: return "601";
350 case CPU_SUBTYPE_POWERPC_602: return "602";
351 case CPU_SUBTYPE_POWERPC_603: return "603";
352 case CPU_SUBTYPE_POWERPC_603e: return "603e";
353 case CPU_SUBTYPE_POWERPC_603ev: return "603ev";
354 case CPU_SUBTYPE_POWERPC_604: return "604";
355 case CPU_SUBTYPE_POWERPC_604e: return "604e";
356 case CPU_SUBTYPE_POWERPC_620: return "620";
357 case CPU_SUBTYPE_POWERPC_750: return "750";
358 case CPU_SUBTYPE_POWERPC_7400: return "7400";
359 case CPU_SUBTYPE_POWERPC_7450: return "7450";
360 case CPU_SUBTYPE_POWERPC_970: return "970";
361 default: ;
362 }
363
364 return "generic";
365 }
366 #elif defined(__linux__) && (defined(__ppc__) || defined(__powerpc__))
getHostCPUName()367 std::string sys::getHostCPUName() {
368 // Access to the Processor Version Register (PVR) on PowerPC is privileged,
369 // and so we must use an operating-system interface to determine the current
370 // processor type. On Linux, this is exposed through the /proc/cpuinfo file.
371 const char *generic = "generic";
372
373 // Note: We cannot mmap /proc/cpuinfo here and then process the resulting
374 // memory buffer because the 'file' has 0 size (it can be read from only
375 // as a stream).
376
377 std::string Err;
378 DataStreamer *DS = getDataFileStreamer("/proc/cpuinfo", &Err);
379 if (!DS) {
380 DEBUG(dbgs() << "Unable to open /proc/cpuinfo: " << Err << "\n");
381 return generic;
382 }
383
384 // The cpu line is second (after the 'processor: 0' line), so if this
385 // buffer is too small then something has changed (or is wrong).
386 char buffer[1024];
387 size_t CPUInfoSize = DS->GetBytes((unsigned char*) buffer, sizeof(buffer));
388 delete DS;
389
390 const char *CPUInfoStart = buffer;
391 const char *CPUInfoEnd = buffer + CPUInfoSize;
392
393 const char *CIP = CPUInfoStart;
394
395 const char *CPUStart = 0;
396 size_t CPULen = 0;
397
398 // We need to find the first line which starts with cpu, spaces, and a colon.
399 // After the colon, there may be some additional spaces and then the cpu type.
400 while (CIP < CPUInfoEnd && CPUStart == 0) {
401 if (CIP < CPUInfoEnd && *CIP == '\n')
402 ++CIP;
403
404 if (CIP < CPUInfoEnd && *CIP == 'c') {
405 ++CIP;
406 if (CIP < CPUInfoEnd && *CIP == 'p') {
407 ++CIP;
408 if (CIP < CPUInfoEnd && *CIP == 'u') {
409 ++CIP;
410 while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t'))
411 ++CIP;
412
413 if (CIP < CPUInfoEnd && *CIP == ':') {
414 ++CIP;
415 while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t'))
416 ++CIP;
417
418 if (CIP < CPUInfoEnd) {
419 CPUStart = CIP;
420 while (CIP < CPUInfoEnd && (*CIP != ' ' && *CIP != '\t' &&
421 *CIP != ',' && *CIP != '\n'))
422 ++CIP;
423 CPULen = CIP - CPUStart;
424 }
425 }
426 }
427 }
428 }
429
430 if (CPUStart == 0)
431 while (CIP < CPUInfoEnd && *CIP != '\n')
432 ++CIP;
433 }
434
435 if (CPUStart == 0)
436 return generic;
437
438 return StringSwitch<const char *>(StringRef(CPUStart, CPULen))
439 .Case("604e", "604e")
440 .Case("604", "604")
441 .Case("7400", "7400")
442 .Case("7410", "7400")
443 .Case("7447", "7400")
444 .Case("7455", "7450")
445 .Case("G4", "g4")
446 .Case("POWER4", "970")
447 .Case("PPC970FX", "970")
448 .Case("PPC970MP", "970")
449 .Case("G5", "g5")
450 .Case("POWER5", "g5")
451 .Case("A2", "a2")
452 .Case("POWER6", "pwr6")
453 .Case("POWER7", "pwr7")
454 .Default(generic);
455 }
456 #elif defined(__linux__) && defined(__arm__)
getHostCPUName()457 std::string sys::getHostCPUName() {
458 // The cpuid register on arm is not accessible from user space. On Linux,
459 // it is exposed through the /proc/cpuinfo file.
460 // Note: We cannot mmap /proc/cpuinfo here and then process the resulting
461 // memory buffer because the 'file' has 0 size (it can be read from only
462 // as a stream).
463
464 std::string Err;
465 DataStreamer *DS = getDataFileStreamer("/proc/cpuinfo", &Err);
466 if (!DS) {
467 DEBUG(dbgs() << "Unable to open /proc/cpuinfo: " << Err << "\n");
468 return "generic";
469 }
470
471 // Read 1024 bytes from /proc/cpuinfo, which should contain the CPU part line
472 // in all cases.
473 char buffer[1024];
474 size_t CPUInfoSize = DS->GetBytes((unsigned char*) buffer, sizeof(buffer));
475 delete DS;
476
477 StringRef Str(buffer, CPUInfoSize);
478
479 SmallVector<StringRef, 32> Lines;
480 Str.split(Lines, "\n");
481
482 // Look for the CPU implementer line.
483 StringRef Implementer;
484 for (unsigned I = 0, E = Lines.size(); I != E; ++I)
485 if (Lines[I].startswith("CPU implementer"))
486 Implementer = Lines[I].substr(15).ltrim("\t :");
487
488 if (Implementer == "0x41") // ARM Ltd.
489 // Look for the CPU part line.
490 for (unsigned I = 0, E = Lines.size(); I != E; ++I)
491 if (Lines[I].startswith("CPU part"))
492 // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The
493 // values correspond to the "Part number" in the CP15/c0 register. The
494 // contents are specified in the various processor manuals.
495 return StringSwitch<const char *>(Lines[I].substr(8).ltrim("\t :"))
496 .Case("0x926", "arm926ej-s")
497 .Case("0xb02", "mpcore")
498 .Case("0xb36", "arm1136j-s")
499 .Case("0xb56", "arm1156t2-s")
500 .Case("0xb76", "arm1176jz-s")
501 .Case("0xc08", "cortex-a8")
502 .Case("0xc09", "cortex-a9")
503 .Case("0xc20", "cortex-m0")
504 .Case("0xc23", "cortex-m3")
505 .Case("0xc24", "cortex-m4")
506 .Default("generic");
507
508 return "generic";
509 }
510 #else
getHostCPUName()511 std::string sys::getHostCPUName() {
512 return "generic";
513 }
514 #endif
515
getHostCPUFeatures(StringMap<bool> & Features)516 bool sys::getHostCPUFeatures(StringMap<bool> &Features){
517 return false;
518 }
519