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      // Haswell
252      case 69:
253	return "core-avx-i";
254
255      case 28: // Most 45 nm Intel Atom processors
256      case 38: // 45 nm Atom Lincroft
257      case 39: // 32 nm Atom Medfield
258      case 53: // 32 nm Atom Midview
259      case 54: // 32 nm Atom Midview
260        return "atom";
261
262      default: return (Em64T) ? "x86-64" : "i686";
263      }
264    case 15: {
265      switch (Model) {
266      case  0: // Pentium 4 processor, Intel Xeon processor. All processors are
267               // model 00h and manufactured using the 0.18 micron process.
268      case  1: // Pentium 4 processor, Intel Xeon processor, Intel Xeon
269               // processor MP, and Intel Celeron processor. All processors are
270               // model 01h and manufactured using the 0.18 micron process.
271      case  2: // Pentium 4 processor, Mobile Intel Pentium 4 processor - M,
272               // Intel Xeon processor, Intel Xeon processor MP, Intel Celeron
273               // processor, and Mobile Intel Celeron processor. All processors
274               // are model 02h and manufactured using the 0.13 micron process.
275        return (Em64T) ? "x86-64" : "pentium4";
276
277      case  3: // Pentium 4 processor, Intel Xeon processor, Intel Celeron D
278               // processor. All processors are model 03h and manufactured using
279               // the 90 nm process.
280      case  4: // Pentium 4 processor, Pentium 4 processor Extreme Edition,
281               // Pentium D processor, Intel Xeon processor, Intel Xeon
282               // processor MP, Intel Celeron D processor. All processors are
283               // model 04h and manufactured using the 90 nm process.
284      case  6: // Pentium 4 processor, Pentium D processor, Pentium processor
285               // Extreme Edition, Intel Xeon processor, Intel Xeon processor
286               // MP, Intel Celeron D processor. All processors are model 06h
287               // and manufactured using the 65 nm process.
288        return (Em64T) ? "nocona" : "prescott";
289
290      default:
291        return (Em64T) ? "x86-64" : "pentium4";
292      }
293    }
294
295    default:
296      return "generic";
297    }
298  } else if (memcmp(text.c, "AuthenticAMD", 12) == 0) {
299    // FIXME: this poorly matches the generated SubtargetFeatureKV table.  There
300    // appears to be no way to generate the wide variety of AMD-specific targets
301    // from the information returned from CPUID.
302    switch (Family) {
303      case 4:
304        return "i486";
305      case 5:
306        switch (Model) {
307        case 6:
308        case 7:  return "k6";
309        case 8:  return "k6-2";
310        case 9:
311        case 13: return "k6-3";
312        case 10: return "geode";
313        default: return "pentium";
314        }
315      case 6:
316        switch (Model) {
317        case 4:  return "athlon-tbird";
318        case 6:
319        case 7:
320        case 8:  return "athlon-mp";
321        case 10: return "athlon-xp";
322        default: return "athlon";
323        }
324      case 15:
325        if (HasSSE3)
326          return "k8-sse3";
327        switch (Model) {
328        case 1:  return "opteron";
329        case 5:  return "athlon-fx"; // also opteron
330        default: return "athlon64";
331        }
332      case 16:
333        return "amdfam10";
334      case 20:
335        return "btver1";
336      case 21:
337        return "bdver1";
338    default:
339      return "generic";
340    }
341  }
342  return "generic";
343}
344#elif defined(__APPLE__) && (defined(__ppc__) || defined(__powerpc__))
345std::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__))
374std::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__)
464std::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("0xc20", "cortex-m0")
511          .Case("0xc23", "cortex-m3")
512          .Case("0xc24", "cortex-m4")
513          .Default("generic");
514
515  return "generic";
516}
517#else
518std::string sys::getHostCPUName() {
519  return "generic";
520}
521#endif
522
523bool sys::getHostCPUFeatures(StringMap<bool> &Features){
524  return false;
525}
526