• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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