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