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        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__))
338std::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__))
367std::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__)
457std::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
511std::string sys::getHostCPUName() {
512  return "generic";
513}
514#endif
515
516bool sys::getHostCPUFeatures(StringMap<bool> &Features){
517  return false;
518}
519