blob: cf61e0487a58f911fa499dd5b80846a238901004 [file] [log] [blame]
Daniel Dunbare52e6bf2008-10-02 01:17:28 +00001//===-- 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//
Hans Wennborgcfe341f2014-06-20 01:36:00 +000010// This file implements the operating system Host concept.
Daniel Dunbare52e6bf2008-10-02 01:17:28 +000011//
12//===----------------------------------------------------------------------===//
13
Chandler Carruthed0881b2012-12-03 16:50:05 +000014#include "llvm/Support/Host.h"
Benjamin Kramerefe40282012-06-26 21:36:32 +000015#include "llvm/ADT/SmallVector.h"
Hal Finkel59b0ee82012-06-12 03:03:13 +000016#include "llvm/ADT/StringRef.h"
17#include "llvm/ADT/StringSwitch.h"
Peter Collingbournea51c6ed2013-01-16 17:27:22 +000018#include "llvm/ADT/Triple.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000019#include "llvm/Config/config.h"
Hal Finkel59b0ee82012-06-12 03:03:13 +000020#include "llvm/Support/Debug.h"
Rafael Espindola97935a92014-12-17 02:32:44 +000021#include "llvm/Support/FileSystem.h"
Duncan P. N. Exon Smith91d3cfe2016-04-05 20:45:04 +000022#include "llvm/Support/raw_ostream.h"
23#include <string.h>
Alina Sbirlea33588b12016-07-20 18:15:29 +000024#include <assert.h>
Daniel Dunbare52e6bf2008-10-02 01:17:28 +000025
26// Include the platform-specific parts of this class.
27#ifdef LLVM_ON_UNIX
28#include "Unix/Host.inc"
29#endif
30#ifdef LLVM_ON_WIN32
Michael J. Spencer447762d2010-11-29 18:16:10 +000031#include "Windows/Host.inc"
Daniel Dunbare52e6bf2008-10-02 01:17:28 +000032#endif
Benjamin Kramer38465062009-11-19 12:17:31 +000033#ifdef _MSC_VER
34#include <intrin.h>
35#endif
Hal Finkel59b0ee82012-06-12 03:03:13 +000036#if defined(__APPLE__) && (defined(__ppc__) || defined(__powerpc__))
Eric Christopher5db9d662016-06-02 21:03:19 +000037#include <mach/host_info.h>
Hal Finkel59b0ee82012-06-12 03:03:13 +000038#include <mach/mach.h>
39#include <mach/mach_host.h>
Hal Finkel59b0ee82012-06-12 03:03:13 +000040#include <mach/machine.h>
41#endif
Daniel Dunbare52e6bf2008-10-02 01:17:28 +000042
Chandler Carruth66f38db2014-04-21 23:58:10 +000043#define DEBUG_TYPE "host-detection"
44
Daniel Dunbar241d01b2009-11-14 10:09:12 +000045//===----------------------------------------------------------------------===//
46//
47// Implementations of the CPU detection routines
48//
49//===----------------------------------------------------------------------===//
50
51using namespace llvm;
52
Rafael Espindola81adfb52014-12-17 02:42:20 +000053#if defined(__linux__)
Duncan P. N. Exon Smith91d3cfe2016-04-05 20:45:04 +000054static ssize_t LLVM_ATTRIBUTE_UNUSED readCpuInfo(void *Buf, size_t Size) {
Rafael Espindola97935a92014-12-17 02:32:44 +000055 // Note: We cannot mmap /proc/cpuinfo here and then process the resulting
56 // memory buffer because the 'file' has 0 size (it can be read from only
57 // as a stream).
58
59 int FD;
60 std::error_code EC = sys::fs::openFileForRead("/proc/cpuinfo", FD);
61 if (EC) {
62 DEBUG(dbgs() << "Unable to open /proc/cpuinfo: " << EC.message() << "\n");
63 return -1;
64 }
65 int Ret = read(FD, Buf, Size);
66 int CloseStatus = close(FD);
67 if (CloseStatus)
68 return -1;
69 return Ret;
70}
Rafael Espindola81adfb52014-12-17 02:42:20 +000071#endif
Rafael Espindola97935a92014-12-17 02:32:44 +000072
Alina Sbirlea33588b12016-07-20 18:15:29 +000073#if defined(__i386__) || defined(_M_IX86) || \
74 defined(__x86_64__) || defined(_M_X64)
Daniel Dunbar241d01b2009-11-14 10:09:12 +000075
Alina Sbirlea76c4a852016-06-06 18:29:59 +000076enum VendorSignatures {
77 SIG_INTEL = 0x756e6547 /* Genu */,
78 SIG_AMD = 0x68747541 /* Auth */
79};
80
81enum ProcessorVendors {
82 VENDOR_INTEL = 1,
83 VENDOR_AMD,
84 VENDOR_OTHER,
85 VENDOR_MAX
86};
87
88enum ProcessorTypes {
89 INTEL_ATOM = 1,
90 INTEL_CORE2,
91 INTEL_COREI7,
92 AMDFAM10H,
93 AMDFAM15H,
94 INTEL_i386,
95 INTEL_i486,
96 INTEL_PENTIUM,
97 INTEL_PENTIUM_PRO,
98 INTEL_PENTIUM_II,
99 INTEL_PENTIUM_III,
100 INTEL_PENTIUM_IV,
101 INTEL_PENTIUM_M,
102 INTEL_CORE_DUO,
103 INTEL_XEONPHI,
104 INTEL_X86_64,
105 INTEL_NOCONA,
106 INTEL_PRESCOTT,
107 AMD_i486,
108 AMDPENTIUM,
109 AMDATHLON,
110 AMDFAM14H,
111 AMDFAM16H,
112 CPU_TYPE_MAX
113};
114
115enum ProcessorSubtypes {
116 INTEL_COREI7_NEHALEM = 1,
117 INTEL_COREI7_WESTMERE,
118 INTEL_COREI7_SANDYBRIDGE,
119 AMDFAM10H_BARCELONA,
120 AMDFAM10H_SHANGHAI,
121 AMDFAM10H_ISTANBUL,
122 AMDFAM15H_BDVER1,
123 AMDFAM15H_BDVER2,
124 INTEL_PENTIUM_MMX,
125 INTEL_CORE2_65,
126 INTEL_CORE2_45,
127 INTEL_COREI7_IVYBRIDGE,
128 INTEL_COREI7_HASWELL,
129 INTEL_COREI7_BROADWELL,
130 INTEL_COREI7_SKYLAKE,
131 INTEL_COREI7_SKYLAKE_AVX512,
132 INTEL_ATOM_BONNELL,
133 INTEL_ATOM_SILVERMONT,
134 INTEL_KNIGHTS_LANDING,
135 AMDPENTIUM_K6,
136 AMDPENTIUM_K62,
137 AMDPENTIUM_K63,
138 AMDPENTIUM_GEODE,
139 AMDATHLON_TBIRD,
140 AMDATHLON_MP,
141 AMDATHLON_XP,
142 AMDATHLON_K8SSE3,
143 AMDATHLON_OPTERON,
144 AMDATHLON_FX,
145 AMDATHLON_64,
146 AMD_BTVER1,
147 AMD_BTVER2,
148 AMDFAM15H_BDVER3,
149 AMDFAM15H_BDVER4,
150 CPU_SUBTYPE_MAX
151};
152
153enum ProcessorFeatures {
154 FEATURE_CMOV = 0,
155 FEATURE_MMX,
156 FEATURE_POPCNT,
157 FEATURE_SSE,
158 FEATURE_SSE2,
159 FEATURE_SSE3,
160 FEATURE_SSSE3,
161 FEATURE_SSE4_1,
162 FEATURE_SSE4_2,
163 FEATURE_AVX,
164 FEATURE_AVX2,
165 FEATURE_AVX512,
166 FEATURE_AVX512SAVE,
167 FEATURE_MOVBE,
168 FEATURE_ADX,
169 FEATURE_EM64T
170};
171
Alina Sbirlea9a78ebd2016-10-04 22:39:53 +0000172// The check below for i386 was copied from clang's cpuid.h (__get_cpuid_max).
173// Check motivated by bug reports for OpenSSL crashing on CPUs without CPUID
174// support. Consequently, for i386, the presence of CPUID is checked first
175// via the corresponding eflags bit.
176// Removal of cpuid.h header motivated by PR30384
177// Header cpuid.h and method __get_cpuid_max are not used in llvm, clang, openmp
178// or test-suite, but are used in external projects e.g. libstdcxx
179static bool isCpuIdSupported() {
180#if defined(__GNUC__) || defined(__clang__)
181#if defined(__i386__)
182 int __cpuid_supported;
183 __asm__(" pushfl\n"
184 " popl %%eax\n"
185 " movl %%eax,%%ecx\n"
186 " xorl $0x00200000,%%eax\n"
187 " pushl %%eax\n"
188 " popfl\n"
189 " pushfl\n"
190 " popl %%eax\n"
191 " movl $0,%0\n"
192 " cmpl %%eax,%%ecx\n"
193 " je 1f\n"
194 " movl $1,%0\n"
195 "1:"
196 : "=r"(__cpuid_supported)
197 :
198 : "eax", "ecx");
199 if (!__cpuid_supported)
200 return false;
201#endif
202 return true;
203#endif
204 return true;
205}
206
Alina Sbirlea400eb022016-06-03 20:27:50 +0000207/// getX86CpuIDAndInfo - Execute the specified cpuid and return the 4 values in
Eric Christopherd9804bb2016-06-02 21:09:17 +0000208/// the specified arguments. If we can't run cpuid on the host, return true.
Alina Sbirlea400eb022016-06-03 20:27:50 +0000209static bool getX86CpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX,
Duncan P. N. Exon Smith91d3cfe2016-04-05 20:45:04 +0000210 unsigned *rECX, unsigned *rEDX) {
Alina Sbirlea33588b12016-07-20 18:15:29 +0000211#if defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER)
Reid Klecknerbf4f9eb2013-08-16 22:42:42 +0000212#if defined(__GNUC__) || defined(__clang__)
Alina Sbirlea33588b12016-07-20 18:15:29 +0000213#if defined(__x86_64__)
214 // gcc doesn't know cpuid would clobber ebx/rbx. Preserve it manually.
215 // FIXME: should we save this for Clang?
216 __asm__("movq\t%%rbx, %%rsi\n\t"
217 "cpuid\n\t"
218 "xchgq\t%%rbx, %%rsi\n\t"
219 : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
220 : "a"(value));
221#elif defined(__i386__)
222 __asm__("movl\t%%ebx, %%esi\n\t"
223 "cpuid\n\t"
224 "xchgl\t%%ebx, %%esi\n\t"
225 : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
226 : "a"(value));
Eric Christopher5db9d662016-06-02 21:03:19 +0000227#else
Alina Sbirlea33588b12016-07-20 18:15:29 +0000228 assert(0 && "This method is defined only for x86.");
Eric Christopher5db9d662016-06-02 21:03:19 +0000229#endif
Reid Klecknerbf4f9eb2013-08-16 22:42:42 +0000230#elif defined(_MSC_VER)
231 // The MSVC intrinsic is portable across x86 and x64.
232 int registers[4];
233 __cpuid(registers, value);
234 *rEAX = registers[0];
235 *rEBX = registers[1];
236 *rECX = registers[2];
237 *rEDX = registers[3];
Alina Sbirlea33588b12016-07-20 18:15:29 +0000238#endif
Reid Klecknerbf4f9eb2013-08-16 22:42:42 +0000239 return false;
David Blaikieb48ed1a2012-01-17 04:43:56 +0000240#else
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000241 return true;
David Blaikieb48ed1a2012-01-17 04:43:56 +0000242#endif
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000243}
244
Alina Sbirlea400eb022016-06-03 20:27:50 +0000245/// getX86CpuIDAndInfoEx - Execute the specified cpuid with subleaf and return
246/// the 4 values in the specified arguments. If we can't run cpuid on the host,
Tim Northover89ccb612013-11-25 09:52:59 +0000247/// return true.
Alina Sbirlea400eb022016-06-03 20:27:50 +0000248static bool getX86CpuIDAndInfoEx(unsigned value, unsigned subleaf,
Duncan P. N. Exon Smith91d3cfe2016-04-05 20:45:04 +0000249 unsigned *rEAX, unsigned *rEBX, unsigned *rECX,
250 unsigned *rEDX) {
Alina Sbirlea33588b12016-07-20 18:15:29 +0000251#if defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER)
252#if defined(__x86_64__) || defined(_M_X64)
253#if defined(__GNUC__) || defined(__clang__)
Eric Christopher5db9d662016-06-02 21:03:19 +0000254 // gcc doesn't know cpuid would clobber ebx/rbx. Preseve it manually.
Alina Sbirlea33588b12016-07-20 18:15:29 +0000255 // FIXME: should we save this for Clang?
256 __asm__("movq\t%%rbx, %%rsi\n\t"
257 "cpuid\n\t"
258 "xchgq\t%%rbx, %%rsi\n\t"
259 : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
260 : "a"(value), "c"(subleaf));
Eric Christopher5db9d662016-06-02 21:03:19 +0000261#elif defined(_MSC_VER)
262 int registers[4];
263 __cpuidex(registers, value, subleaf);
264 *rEAX = registers[0];
265 *rEBX = registers[1];
266 *rECX = registers[2];
267 *rEDX = registers[3];
Eric Christopher5db9d662016-06-02 21:03:19 +0000268#endif
Alina Sbirlea33588b12016-07-20 18:15:29 +0000269#elif defined(__i386__) || defined(_M_IX86)
270#if defined(__GNUC__) || defined(__clang__)
271 __asm__("movl\t%%ebx, %%esi\n\t"
272 "cpuid\n\t"
273 "xchgl\t%%ebx, %%esi\n\t"
274 : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
275 : "a"(value), "c"(subleaf));
Eric Christopher5db9d662016-06-02 21:03:19 +0000276#elif defined(_MSC_VER)
277 __asm {
Tim Northover89ccb612013-11-25 09:52:59 +0000278 mov eax,value
279 mov ecx,subleaf
280 cpuid
281 mov esi,rEAX
282 mov dword ptr [esi],eax
283 mov esi,rEBX
284 mov dword ptr [esi],ebx
285 mov esi,rECX
286 mov dword ptr [esi],ecx
287 mov esi,rEDX
288 mov dword ptr [esi],edx
Eric Christopher5db9d662016-06-02 21:03:19 +0000289 }
Eric Christopher5db9d662016-06-02 21:03:19 +0000290#endif
Tim Northover89ccb612013-11-25 09:52:59 +0000291#else
Alina Sbirlea33588b12016-07-20 18:15:29 +0000292 assert(0 && "This method is defined only for x86.");
293#endif
294 return false;
295#else
Tim Northover89ccb612013-11-25 09:52:59 +0000296 return true;
297#endif
298}
299
Alina Sbirlea400eb022016-06-03 20:27:50 +0000300static bool getX86XCR0(unsigned *rEAX, unsigned *rEDX) {
Alina Sbirlea33588b12016-07-20 18:15:29 +0000301#if defined(__GNUC__) || defined(__clang__)
Craig Topper7af39d72013-04-22 05:38:01 +0000302 // Check xgetbv; this uses a .byte sequence instead of the instruction
303 // directly because older assemblers do not include support for xgetbv and
304 // there is no easy way to conditionally compile based on the assembler used.
Eric Christopher5db9d662016-06-02 21:03:19 +0000305 __asm__(".byte 0x0f, 0x01, 0xd0" : "=a"(*rEAX), "=d"(*rEDX) : "c"(0));
Craig Topper798a2602015-03-29 01:00:23 +0000306 return false;
Aaron Ballman31c0adc2013-04-23 17:38:44 +0000307#elif defined(_MSC_FULL_VER) && defined(_XCR_XFEATURE_ENABLED_MASK)
Craig Topper798a2602015-03-29 01:00:23 +0000308 unsigned long long Result = _xgetbv(_XCR_XFEATURE_ENABLED_MASK);
Craig Topper7db49fd2015-03-29 01:07:57 +0000309 *rEAX = Result;
310 *rEDX = Result >> 32;
Craig Topper798a2602015-03-29 01:00:23 +0000311 return false;
Craig Topper7af39d72013-04-22 05:38:01 +0000312#else
Craig Topper798a2602015-03-29 01:00:23 +0000313 return true;
Craig Topper7af39d72013-04-22 05:38:01 +0000314#endif
Aaron Ballman5f7c6802013-04-03 12:25:06 +0000315}
316
Alina Sbirlea400eb022016-06-03 20:27:50 +0000317static void detectX86FamilyModel(unsigned EAX, unsigned *Family,
318 unsigned *Model) {
319 *Family = (EAX >> 8) & 0xf; // Bits 8 - 11
320 *Model = (EAX >> 4) & 0xf; // Bits 4 - 7
321 if (*Family == 6 || *Family == 0xf) {
322 if (*Family == 0xf)
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000323 // Examine extended family ID if family ID is F.
Alina Sbirlea400eb022016-06-03 20:27:50 +0000324 *Family += (EAX >> 20) & 0xff; // Bits 20 - 27
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000325 // Examine extended model ID if family ID is 6 or F.
Alina Sbirlea400eb022016-06-03 20:27:50 +0000326 *Model += ((EAX >> 16) & 0xf) << 4; // Bits 16 - 19
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000327 }
328}
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000329
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000330static void
331getIntelProcessorTypeAndSubtype(unsigned int Family, unsigned int Model,
332 unsigned int Brand_id, unsigned int Features,
333 unsigned *Type, unsigned *Subtype) {
334 if (Brand_id != 0)
335 return;
336 switch (Family) {
337 case 3:
338 *Type = INTEL_i386;
339 break;
340 case 4:
341 switch (Model) {
342 case 0: // Intel486 DX processors
343 case 1: // Intel486 DX processors
344 case 2: // Intel486 SX processors
345 case 3: // Intel487 processors, IntelDX2 OverDrive processors,
346 // IntelDX2 processors
347 case 4: // Intel486 SL processor
348 case 5: // IntelSX2 processors
349 case 7: // Write-Back Enhanced IntelDX2 processors
350 case 8: // IntelDX4 OverDrive processors, IntelDX4 processors
351 default:
352 *Type = INTEL_i486;
353 break;
354 }
Alina Sbirlea080241b2016-06-09 00:08:15 +0000355 break;
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000356 case 5:
357 switch (Model) {
358 case 1: // Pentium OverDrive processor for Pentium processor (60, 66),
359 // Pentium processors (60, 66)
360 case 2: // Pentium OverDrive processor for Pentium processor (75, 90,
361 // 100, 120, 133), Pentium processors (75, 90, 100, 120, 133,
362 // 150, 166, 200)
363 case 3: // Pentium OverDrive processors for Intel486 processor-based
364 // systems
365 *Type = INTEL_PENTIUM;
366 break;
367 case 4: // Pentium OverDrive processor with MMX technology for Pentium
368 // processor (75, 90, 100, 120, 133), Pentium processor with
369 // MMX technology (166, 200)
370 *Type = INTEL_PENTIUM;
371 *Subtype = INTEL_PENTIUM_MMX;
372 break;
373 default:
374 *Type = INTEL_PENTIUM;
375 break;
376 }
Alina Sbirlea080241b2016-06-09 00:08:15 +0000377 break;
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000378 case 6:
379 switch (Model) {
380 case 0x01: // Pentium Pro processor
381 *Type = INTEL_PENTIUM_PRO;
382 break;
383 case 0x03: // Intel Pentium II OverDrive processor, Pentium II processor,
384 // model 03
385 case 0x05: // Pentium II processor, model 05, Pentium II Xeon processor,
386 // model 05, and Intel Celeron processor, model 05
387 case 0x06: // Celeron processor, model 06
388 *Type = INTEL_PENTIUM_II;
389 break;
390 case 0x07: // Pentium III processor, model 07, and Pentium III Xeon
391 // processor, model 07
392 case 0x08: // Pentium III processor, model 08, Pentium III Xeon processor,
393 // model 08, and Celeron processor, model 08
394 case 0x0a: // Pentium III Xeon processor, model 0Ah
395 case 0x0b: // Pentium III processor, model 0Bh
396 *Type = INTEL_PENTIUM_III;
397 break;
398 case 0x09: // Intel Pentium M processor, Intel Celeron M processor model 09.
399 case 0x0d: // Intel Pentium M processor, Intel Celeron M processor, model
400 // 0Dh. All processors are manufactured using the 90 nm process.
401 case 0x15: // Intel EP80579 Integrated Processor and Intel EP80579
402 // Integrated Processor with Intel QuickAssist Technology
403 *Type = INTEL_PENTIUM_M;
404 break;
405 case 0x0e: // Intel Core Duo processor, Intel Core Solo processor, model
406 // 0Eh. All processors are manufactured using the 65 nm process.
407 *Type = INTEL_CORE_DUO;
408 break; // yonah
409 case 0x0f: // Intel Core 2 Duo processor, Intel Core 2 Duo mobile
410 // processor, Intel Core 2 Quad processor, Intel Core 2 Quad
411 // mobile processor, Intel Core 2 Extreme processor, Intel
412 // Pentium Dual-Core processor, Intel Xeon processor, model
413 // 0Fh. All processors are manufactured using the 65 nm process.
414 case 0x16: // Intel Celeron processor model 16h. All processors are
415 // manufactured using the 65 nm process
416 *Type = INTEL_CORE2; // "core2"
417 *Subtype = INTEL_CORE2_65;
418 break;
419 case 0x17: // Intel Core 2 Extreme processor, Intel Xeon processor, model
420 // 17h. All processors are manufactured using the 45 nm process.
421 //
422 // 45nm: Penryn , Wolfdale, Yorkfield (XE)
423 case 0x1d: // Intel Xeon processor MP. All processors are manufactured using
424 // the 45 nm process.
425 *Type = INTEL_CORE2; // "penryn"
426 *Subtype = INTEL_CORE2_45;
427 break;
428 case 0x1a: // Intel Core i7 processor and Intel Xeon processor. All
429 // processors are manufactured using the 45 nm process.
430 case 0x1e: // Intel(R) Core(TM) i7 CPU 870 @ 2.93GHz.
431 // As found in a Summer 2010 model iMac.
432 case 0x1f:
433 case 0x2e: // Nehalem EX
434 *Type = INTEL_COREI7; // "nehalem"
435 *Subtype = INTEL_COREI7_NEHALEM;
436 break;
437 case 0x25: // Intel Core i7, laptop version.
438 case 0x2c: // Intel Core i7 processor and Intel Xeon processor. All
439 // processors are manufactured using the 32 nm process.
440 case 0x2f: // Westmere EX
441 *Type = INTEL_COREI7; // "westmere"
442 *Subtype = INTEL_COREI7_WESTMERE;
443 break;
444 case 0x2a: // Intel Core i7 processor. All processors are manufactured
445 // using the 32 nm process.
446 case 0x2d:
447 *Type = INTEL_COREI7; //"sandybridge"
448 *Subtype = INTEL_COREI7_SANDYBRIDGE;
449 break;
450 case 0x3a:
451 case 0x3e: // Ivy Bridge EP
452 *Type = INTEL_COREI7; // "ivybridge"
453 *Subtype = INTEL_COREI7_IVYBRIDGE;
454 break;
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000455
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000456 // Haswell:
457 case 0x3c:
458 case 0x3f:
459 case 0x45:
460 case 0x46:
461 *Type = INTEL_COREI7; // "haswell"
462 *Subtype = INTEL_COREI7_HASWELL;
463 break;
Tim Northover89ccb612013-11-25 09:52:59 +0000464
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000465 // Broadwell:
466 case 0x3d:
467 case 0x47:
468 case 0x4f:
469 case 0x56:
470 *Type = INTEL_COREI7; // "broadwell"
471 *Subtype = INTEL_COREI7_BROADWELL;
472 break;
Tim Northover89ccb612013-11-25 09:52:59 +0000473
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000474 // Skylake:
475 case 0x4e:
476 *Type = INTEL_COREI7; // "skylake-avx512"
477 *Subtype = INTEL_COREI7_SKYLAKE_AVX512;
478 break;
479 case 0x5e:
480 *Type = INTEL_COREI7; // "skylake"
481 *Subtype = INTEL_COREI7_SKYLAKE;
482 break;
483
484 case 0x1c: // Most 45 nm Intel Atom processors
485 case 0x26: // 45 nm Atom Lincroft
486 case 0x27: // 32 nm Atom Medfield
487 case 0x35: // 32 nm Atom Midview
488 case 0x36: // 32 nm Atom Midview
489 *Type = INTEL_ATOM;
490 *Subtype = INTEL_ATOM_BONNELL;
491 break; // "bonnell"
492
493 // Atom Silvermont codes from the Intel software optimization guide.
494 case 0x37:
495 case 0x4a:
496 case 0x4d:
497 case 0x5a:
498 case 0x5d:
499 case 0x4c: // really airmont
500 *Type = INTEL_ATOM;
501 *Subtype = INTEL_ATOM_SILVERMONT;
502 break; // "silvermont"
503
504 case 0x57:
505 *Type = INTEL_XEONPHI; // knl
506 *Subtype = INTEL_KNIGHTS_LANDING;
507 break;
508
509 default: // Unknown family 6 CPU, try to guess.
510 if (Features & (1 << FEATURE_AVX512)) {
511 *Type = INTEL_XEONPHI; // knl
512 *Subtype = INTEL_KNIGHTS_LANDING;
513 break;
514 }
515 if (Features & (1 << FEATURE_ADX)) {
516 *Type = INTEL_COREI7;
517 *Subtype = INTEL_COREI7_BROADWELL;
518 break;
519 }
520 if (Features & (1 << FEATURE_AVX2)) {
521 *Type = INTEL_COREI7;
522 *Subtype = INTEL_COREI7_HASWELL;
523 break;
524 }
525 if (Features & (1 << FEATURE_AVX)) {
526 *Type = INTEL_COREI7;
527 *Subtype = INTEL_COREI7_SANDYBRIDGE;
528 break;
529 }
530 if (Features & (1 << FEATURE_SSE4_2)) {
531 if (Features & (1 << FEATURE_MOVBE)) {
532 *Type = INTEL_ATOM;
533 *Subtype = INTEL_ATOM_SILVERMONT;
534 } else {
535 *Type = INTEL_COREI7;
536 *Subtype = INTEL_COREI7_NEHALEM;
537 }
538 break;
539 }
540 if (Features & (1 << FEATURE_SSE4_1)) {
541 *Type = INTEL_CORE2; // "penryn"
542 *Subtype = INTEL_CORE2_45;
543 break;
544 }
545 if (Features & (1 << FEATURE_SSSE3)) {
546 if (Features & (1 << FEATURE_MOVBE)) {
547 *Type = INTEL_ATOM;
548 *Subtype = INTEL_ATOM_BONNELL; // "bonnell"
549 } else {
550 *Type = INTEL_CORE2; // "core2"
551 *Subtype = INTEL_CORE2_65;
552 }
553 break;
554 }
555 if (Features & (1 << FEATURE_EM64T)) {
556 *Type = INTEL_X86_64;
557 break; // x86-64
558 }
559 if (Features & (1 << FEATURE_SSE2)) {
560 *Type = INTEL_PENTIUM_M;
561 break;
562 }
563 if (Features & (1 << FEATURE_SSE)) {
564 *Type = INTEL_PENTIUM_III;
565 break;
566 }
567 if (Features & (1 << FEATURE_MMX)) {
568 *Type = INTEL_PENTIUM_II;
569 break;
570 }
571 *Type = INTEL_PENTIUM_PRO;
572 break;
573 }
Alina Sbirlea080241b2016-06-09 00:08:15 +0000574 break;
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000575 case 15: {
576 switch (Model) {
577 case 0: // Pentium 4 processor, Intel Xeon processor. All processors are
578 // model 00h and manufactured using the 0.18 micron process.
579 case 1: // Pentium 4 processor, Intel Xeon processor, Intel Xeon
580 // processor MP, and Intel Celeron processor. All processors are
581 // model 01h and manufactured using the 0.18 micron process.
582 case 2: // Pentium 4 processor, Mobile Intel Pentium 4 processor - M,
583 // Intel Xeon processor, Intel Xeon processor MP, Intel Celeron
584 // processor, and Mobile Intel Celeron processor. All processors
585 // are model 02h and manufactured using the 0.13 micron process.
586 *Type =
587 ((Features & (1 << FEATURE_EM64T)) ? INTEL_X86_64 : INTEL_PENTIUM_IV);
588 break;
589
590 case 3: // Pentium 4 processor, Intel Xeon processor, Intel Celeron D
591 // processor. All processors are model 03h and manufactured using
592 // the 90 nm process.
593 case 4: // Pentium 4 processor, Pentium 4 processor Extreme Edition,
594 // Pentium D processor, Intel Xeon processor, Intel Xeon
595 // processor MP, Intel Celeron D processor. All processors are
596 // model 04h and manufactured using the 90 nm process.
597 case 6: // Pentium 4 processor, Pentium D processor, Pentium processor
598 // Extreme Edition, Intel Xeon processor, Intel Xeon processor
599 // MP, Intel Celeron D processor. All processors are model 06h
600 // and manufactured using the 65 nm process.
601 *Type =
602 ((Features & (1 << FEATURE_EM64T)) ? INTEL_NOCONA : INTEL_PRESCOTT);
603 break;
604
605 default:
606 *Type =
607 ((Features & (1 << FEATURE_EM64T)) ? INTEL_X86_64 : INTEL_PENTIUM_IV);
608 break;
609 }
Alina Sbirlea080241b2016-06-09 00:08:15 +0000610 break;
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000611 }
612 default:
613 break; /*"generic"*/
614 }
615}
616
617static void getAMDProcessorTypeAndSubtype(unsigned int Family,
618 unsigned int Model,
619 unsigned int Features,
620 unsigned *Type,
621 unsigned *Subtype) {
622 // FIXME: this poorly matches the generated SubtargetFeatureKV table. There
623 // appears to be no way to generate the wide variety of AMD-specific targets
624 // from the information returned from CPUID.
625 switch (Family) {
626 case 4:
627 *Type = AMD_i486;
Alina Sbirlea080241b2016-06-09 00:08:15 +0000628 break;
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000629 case 5:
630 *Type = AMDPENTIUM;
631 switch (Model) {
632 case 6:
633 case 7:
634 *Subtype = AMDPENTIUM_K6;
635 break; // "k6"
636 case 8:
637 *Subtype = AMDPENTIUM_K62;
638 break; // "k6-2"
639 case 9:
640 case 13:
641 *Subtype = AMDPENTIUM_K63;
642 break; // "k6-3"
643 case 10:
644 *Subtype = AMDPENTIUM_GEODE;
645 break; // "geode"
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000646 }
Alina Sbirlea080241b2016-06-09 00:08:15 +0000647 break;
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000648 case 6:
649 *Type = AMDATHLON;
650 switch (Model) {
651 case 4:
652 *Subtype = AMDATHLON_TBIRD;
653 break; // "athlon-tbird"
654 case 6:
655 case 7:
656 case 8:
657 *Subtype = AMDATHLON_MP;
658 break; // "athlon-mp"
659 case 10:
660 *Subtype = AMDATHLON_XP;
661 break; // "athlon-xp"
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000662 }
Alina Sbirlea080241b2016-06-09 00:08:15 +0000663 break;
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000664 case 15:
665 *Type = AMDATHLON;
666 if (Features & (1 << FEATURE_SSE3)) {
667 *Subtype = AMDATHLON_K8SSE3;
668 break; // "k8-sse3"
669 }
670 switch (Model) {
671 case 1:
672 *Subtype = AMDATHLON_OPTERON;
673 break; // "opteron"
674 case 5:
675 *Subtype = AMDATHLON_FX;
676 break; // "athlon-fx"; also opteron
677 default:
678 *Subtype = AMDATHLON_64;
679 break; // "athlon64"
680 }
Alina Sbirlea080241b2016-06-09 00:08:15 +0000681 break;
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000682 case 16:
683 *Type = AMDFAM10H; // "amdfam10"
684 switch (Model) {
685 case 2:
686 *Subtype = AMDFAM10H_BARCELONA;
687 break;
688 case 4:
689 *Subtype = AMDFAM10H_SHANGHAI;
690 break;
691 case 8:
692 *Subtype = AMDFAM10H_ISTANBUL;
693 break;
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000694 }
Alina Sbirlea080241b2016-06-09 00:08:15 +0000695 break;
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000696 case 20:
697 *Type = AMDFAM14H;
698 *Subtype = AMD_BTVER1;
699 break; // "btver1";
700 case 21:
701 *Type = AMDFAM15H;
702 if (!(Features &
703 (1 << FEATURE_AVX))) { // If no AVX support, provide a sane fallback.
704 *Subtype = AMD_BTVER1;
705 break; // "btver1"
706 }
707 if (Model >= 0x50 && Model <= 0x6f) {
708 *Subtype = AMDFAM15H_BDVER4;
709 break; // "bdver4"; 50h-6Fh: Excavator
710 }
711 if (Model >= 0x30 && Model <= 0x3f) {
712 *Subtype = AMDFAM15H_BDVER3;
713 break; // "bdver3"; 30h-3Fh: Steamroller
714 }
715 if (Model >= 0x10 && Model <= 0x1f) {
716 *Subtype = AMDFAM15H_BDVER2;
717 break; // "bdver2"; 10h-1Fh: Piledriver
718 }
719 if (Model <= 0x0f) {
720 *Subtype = AMDFAM15H_BDVER1;
721 break; // "bdver1"; 00h-0Fh: Bulldozer
722 }
723 break;
724 case 22:
725 *Type = AMDFAM16H;
726 if (!(Features &
727 (1 << FEATURE_AVX))) { // If no AVX support provide a sane fallback.
728 *Subtype = AMD_BTVER1;
729 break; // "btver1";
730 }
731 *Subtype = AMD_BTVER2;
732 break; // "btver2"
733 default:
734 break; // "generic"
735 }
736}
737
Benjamin Kramerb308f8b2016-07-10 16:11:53 +0000738static unsigned getAvailableFeatures(unsigned int ECX, unsigned int EDX,
739 unsigned MaxLeaf) {
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000740 unsigned Features = 0;
741 unsigned int EAX, EBX;
742 Features |= (((EDX >> 23) & 1) << FEATURE_MMX);
743 Features |= (((EDX >> 25) & 1) << FEATURE_SSE);
744 Features |= (((EDX >> 26) & 1) << FEATURE_SSE2);
745 Features |= (((ECX >> 0) & 1) << FEATURE_SSE3);
746 Features |= (((ECX >> 9) & 1) << FEATURE_SSSE3);
747 Features |= (((ECX >> 19) & 1) << FEATURE_SSE4_1);
748 Features |= (((ECX >> 20) & 1) << FEATURE_SSE4_2);
749 Features |= (((ECX >> 22) & 1) << FEATURE_MOVBE);
750
Craig Topper1214bdc2015-03-31 05:42:45 +0000751 // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV
Aaron Ballman5f7c6802013-04-03 12:25:06 +0000752 // indicates that the AVX registers will be saved and restored on context
753 // switch, then we have full AVX support.
Aaron Ballman5e6d2052013-04-03 18:00:22 +0000754 const unsigned AVXBits = (1 << 27) | (1 << 28);
Alina Sbirlea400eb022016-06-03 20:27:50 +0000755 bool HasAVX = ((ECX & AVXBits) == AVXBits) && !getX86XCR0(&EAX, &EDX) &&
Craig Topper798a2602015-03-29 01:00:23 +0000756 ((EAX & 0x6) == 0x6);
Craig Topper1214bdc2015-03-31 05:42:45 +0000757 bool HasAVX512Save = HasAVX && ((EAX & 0xe0) == 0xe0);
Eric Christopher5db9d662016-06-02 21:03:19 +0000758 bool HasLeaf7 =
Alina Sbirlea400eb022016-06-03 20:27:50 +0000759 MaxLeaf >= 0x7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
Craig Topper1214bdc2015-03-31 05:42:45 +0000760 bool HasADX = HasLeaf7 && ((EBX >> 19) & 1);
761 bool HasAVX2 = HasAVX && HasLeaf7 && (EBX & 0x20);
762 bool HasAVX512 = HasLeaf7 && HasAVX512Save && ((EBX >> 16) & 1);
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000763 Features |= (HasAVX << FEATURE_AVX);
764 Features |= (HasAVX2 << FEATURE_AVX2);
765 Features |= (HasAVX512 << FEATURE_AVX512);
766 Features |= (HasAVX512Save << FEATURE_AVX512SAVE);
767 Features |= (HasADX << FEATURE_ADX);
Craig Topper1214bdc2015-03-31 05:42:45 +0000768
Alina Sbirlea400eb022016-06-03 20:27:50 +0000769 getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000770 Features |= (((EDX >> 29) & 0x1) << FEATURE_EM64T);
771 return Features;
772}
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000773
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000774StringRef sys::getHostCPUName() {
775 unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
776 unsigned MaxLeaf, Vendor;
777
Alina Sbirleab86aa172016-07-20 18:54:26 +0000778#if defined(__GNUC__) || defined(__clang__)
Alina Sbirlea33588b12016-07-20 18:15:29 +0000779 //FIXME: include cpuid.h from clang or copy __get_cpuid_max here
780 // and simplify it to not invoke __cpuid (like cpu_model.c in
781 // compiler-rt/lib/builtins/cpu_model.c?
Alina Sbirlea9a78ebd2016-10-04 22:39:53 +0000782 // Opting for the second option.
783 if(!isCpuIdSupported())
Alina Sbirlea33588b12016-07-20 18:15:29 +0000784 return "generic";
Alina Sbirleab86aa172016-07-20 18:54:26 +0000785#endif
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000786 if (getX86CpuIDAndInfo(0, &MaxLeaf, &Vendor, &ECX, &EDX))
787 return "generic";
788 if (getX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX))
789 return "generic";
790
791 unsigned Brand_id = EBX & 0xff;
792 unsigned Family = 0, Model = 0;
793 unsigned Features = 0;
794 detectX86FamilyModel(EAX, &Family, &Model);
795 Features = getAvailableFeatures(ECX, EDX, MaxLeaf);
796
797 unsigned Type;
798 unsigned Subtype;
799
800 if (Vendor == SIG_INTEL) {
801 getIntelProcessorTypeAndSubtype(Family, Model, Brand_id, Features, &Type,
802 &Subtype);
803 switch (Type) {
804 case INTEL_i386:
Daniel Dunbar397235f2009-11-14 21:36:19 +0000805 return "i386";
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000806 case INTEL_i486:
807 return "i486";
808 case INTEL_PENTIUM:
809 if (Subtype == INTEL_PENTIUM_MMX)
Daniel Dunbar397235f2009-11-14 21:36:19 +0000810 return "pentium-mmx";
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000811 return "pentium";
812 case INTEL_PENTIUM_PRO:
813 return "pentiumpro";
814 case INTEL_PENTIUM_II:
815 return "pentium2";
816 case INTEL_PENTIUM_III:
817 return "pentium3";
818 case INTEL_PENTIUM_IV:
819 return "pentium4";
820 case INTEL_PENTIUM_M:
821 return "pentium-m";
822 case INTEL_CORE_DUO:
823 return "yonah";
824 case INTEL_CORE2:
825 switch (Subtype) {
826 case INTEL_CORE2_65:
Daniel Dunbar397235f2009-11-14 21:36:19 +0000827 return "core2";
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000828 case INTEL_CORE2_45:
Craig Topper545b9512015-03-31 06:18:31 +0000829 return "penryn";
Daniel Dunbar397235f2009-11-14 21:36:19 +0000830 default:
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000831 return "core2";
Daniel Dunbar397235f2009-11-14 21:36:19 +0000832 }
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000833 case INTEL_COREI7:
834 switch (Subtype) {
835 case INTEL_COREI7_NEHALEM:
836 return "nehalem";
837 case INTEL_COREI7_WESTMERE:
838 return "westmere";
839 case INTEL_COREI7_SANDYBRIDGE:
840 return "sandybridge";
841 case INTEL_COREI7_IVYBRIDGE:
842 return "ivybridge";
843 case INTEL_COREI7_HASWELL:
844 return "haswell";
845 case INTEL_COREI7_BROADWELL:
846 return "broadwell";
847 case INTEL_COREI7_SKYLAKE:
848 return "skylake";
849 case INTEL_COREI7_SKYLAKE_AVX512:
850 return "skylake-avx512";
851 default:
852 return "corei7";
853 }
854 case INTEL_ATOM:
855 switch (Subtype) {
856 case INTEL_ATOM_BONNELL:
857 return "bonnell";
858 case INTEL_ATOM_SILVERMONT:
859 return "silvermont";
860 default:
861 return "atom";
862 }
863 case INTEL_XEONPHI:
864 return "knl"; /*update for more variants added*/
865 case INTEL_X86_64:
866 return "x86-64";
867 case INTEL_NOCONA:
868 return "nocona";
869 case INTEL_PRESCOTT:
870 return "prescott";
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000871 default:
Benjamin Kramer713fd352009-11-17 17:57:04 +0000872 return "generic";
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000873 }
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000874 } else if (Vendor == SIG_AMD) {
875 getAMDProcessorTypeAndSubtype(Family, Model, Features, &Type, &Subtype);
876 switch (Type) {
877 case AMD_i486:
Eric Christopher5db9d662016-06-02 21:03:19 +0000878 return "i486";
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000879 case AMDPENTIUM:
880 switch (Subtype) {
881 case AMDPENTIUM_K6:
Eric Christopher5db9d662016-06-02 21:03:19 +0000882 return "k6";
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000883 case AMDPENTIUM_K62:
Eric Christopher5db9d662016-06-02 21:03:19 +0000884 return "k6-2";
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000885 case AMDPENTIUM_K63:
Eric Christopher5db9d662016-06-02 21:03:19 +0000886 return "k6-3";
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000887 case AMDPENTIUM_GEODE:
Eric Christopher5db9d662016-06-02 21:03:19 +0000888 return "geode";
889 default:
890 return "pentium";
891 }
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000892 case AMDATHLON:
893 switch (Subtype) {
894 case AMDATHLON_TBIRD:
Eric Christopher5db9d662016-06-02 21:03:19 +0000895 return "athlon-tbird";
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000896 case AMDATHLON_MP:
Eric Christopher5db9d662016-06-02 21:03:19 +0000897 return "athlon-mp";
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000898 case AMDATHLON_XP:
Eric Christopher5db9d662016-06-02 21:03:19 +0000899 return "athlon-xp";
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000900 case AMDATHLON_K8SSE3:
901 return "k8-sse3";
902 case AMDATHLON_OPTERON:
903 return "opteron";
904 case AMDATHLON_FX:
905 return "athlon-fx";
906 case AMDATHLON_64:
907 return "athlon64";
Eric Christopher5db9d662016-06-02 21:03:19 +0000908 default:
909 return "athlon";
910 }
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000911 case AMDFAM10H:
Alina Sbirlead665b412016-06-09 23:04:15 +0000912 if(Subtype == AMDFAM10H_BARCELONA)
913 return "barcelona";
914 return "amdfam10";
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000915 case AMDFAM14H:
Eric Christopher5db9d662016-06-02 21:03:19 +0000916 return "btver1";
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000917 case AMDFAM15H:
918 switch (Subtype) {
919 case AMDFAM15H_BDVER1:
920 return "bdver1";
921 case AMDFAM15H_BDVER2:
922 return "bdver2";
923 case AMDFAM15H_BDVER3:
924 return "bdver3";
925 case AMDFAM15H_BDVER4:
926 return "bdver4";
927 case AMD_BTVER1:
Benjamin Kramer077ae1d2012-01-10 11:50:02 +0000928 return "btver1";
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000929 default:
930 return "amdfam15";
931 }
932 case AMDFAM16H:
933 switch (Subtype) {
934 case AMD_BTVER1:
Eric Christopher5db9d662016-06-02 21:03:19 +0000935 return "btver1";
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000936 case AMD_BTVER2:
937 return "btver2";
938 default:
939 return "amdfam16";
940 }
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000941 default:
Benjamin Kramer713fd352009-11-17 17:57:04 +0000942 return "generic";
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000943 }
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000944 }
Torok Edwin022336a2009-12-14 12:38:18 +0000945 return "generic";
Torok Edwinabdc1c22009-12-13 08:59:40 +0000946}
Alina Sbirlea76c4a852016-06-06 18:29:59 +0000947
Hal Finkel59b0ee82012-06-12 03:03:13 +0000948#elif defined(__APPLE__) && (defined(__ppc__) || defined(__powerpc__))
Rafael Espindola1f58e4d2013-12-12 16:10:48 +0000949StringRef sys::getHostCPUName() {
Hal Finkel59b0ee82012-06-12 03:03:13 +0000950 host_basic_info_data_t hostInfo;
951 mach_msg_type_number_t infoCount;
952
953 infoCount = HOST_BASIC_INFO_COUNT;
Eric Christopher5db9d662016-06-02 21:03:19 +0000954 host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostInfo,
Hal Finkel59b0ee82012-06-12 03:03:13 +0000955 &infoCount);
Hal Finkel59b0ee82012-06-12 03:03:13 +0000956
Eric Christopher5db9d662016-06-02 21:03:19 +0000957 if (hostInfo.cpu_type != CPU_TYPE_POWERPC)
958 return "generic";
959
960 switch (hostInfo.cpu_subtype) {
961 case CPU_SUBTYPE_POWERPC_601:
962 return "601";
963 case CPU_SUBTYPE_POWERPC_602:
964 return "602";
965 case CPU_SUBTYPE_POWERPC_603:
966 return "603";
967 case CPU_SUBTYPE_POWERPC_603e:
968 return "603e";
969 case CPU_SUBTYPE_POWERPC_603ev:
970 return "603ev";
971 case CPU_SUBTYPE_POWERPC_604:
972 return "604";
973 case CPU_SUBTYPE_POWERPC_604e:
974 return "604e";
975 case CPU_SUBTYPE_POWERPC_620:
976 return "620";
977 case CPU_SUBTYPE_POWERPC_750:
978 return "750";
979 case CPU_SUBTYPE_POWERPC_7400:
980 return "7400";
981 case CPU_SUBTYPE_POWERPC_7450:
982 return "7450";
983 case CPU_SUBTYPE_POWERPC_970:
984 return "970";
985 default:;
Hal Finkel59b0ee82012-06-12 03:03:13 +0000986 }
Eric Christopher5db9d662016-06-02 21:03:19 +0000987
Hal Finkel59b0ee82012-06-12 03:03:13 +0000988 return "generic";
989}
990#elif defined(__linux__) && (defined(__ppc__) || defined(__powerpc__))
Rafael Espindolab75ea012013-12-12 16:17:40 +0000991StringRef sys::getHostCPUName() {
Hal Finkel59b0ee82012-06-12 03:03:13 +0000992 // Access to the Processor Version Register (PVR) on PowerPC is privileged,
993 // and so we must use an operating-system interface to determine the current
994 // processor type. On Linux, this is exposed through the /proc/cpuinfo file.
995 const char *generic = "generic";
996
Hal Finkel59b0ee82012-06-12 03:03:13 +0000997 // The cpu line is second (after the 'processor: 0' line), so if this
998 // buffer is too small then something has changed (or is wrong).
999 char buffer[1024];
Rafael Espindola97935a92014-12-17 02:32:44 +00001000 ssize_t CPUInfoSize = readCpuInfo(buffer, sizeof(buffer));
1001 if (CPUInfoSize == -1)
1002 return generic;
Hal Finkel59b0ee82012-06-12 03:03:13 +00001003
1004 const char *CPUInfoStart = buffer;
1005 const char *CPUInfoEnd = buffer + CPUInfoSize;
1006
1007 const char *CIP = CPUInfoStart;
1008
1009 const char *CPUStart = 0;
1010 size_t CPULen = 0;
1011
1012 // We need to find the first line which starts with cpu, spaces, and a colon.
1013 // After the colon, there may be some additional spaces and then the cpu type.
1014 while (CIP < CPUInfoEnd && CPUStart == 0) {
1015 if (CIP < CPUInfoEnd && *CIP == '\n')
1016 ++CIP;
1017
1018 if (CIP < CPUInfoEnd && *CIP == 'c') {
1019 ++CIP;
1020 if (CIP < CPUInfoEnd && *CIP == 'p') {
1021 ++CIP;
1022 if (CIP < CPUInfoEnd && *CIP == 'u') {
1023 ++CIP;
1024 while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t'))
1025 ++CIP;
Eric Christopher5db9d662016-06-02 21:03:19 +00001026
Hal Finkel59b0ee82012-06-12 03:03:13 +00001027 if (CIP < CPUInfoEnd && *CIP == ':') {
1028 ++CIP;
1029 while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t'))
1030 ++CIP;
Eric Christopher5db9d662016-06-02 21:03:19 +00001031
Hal Finkel59b0ee82012-06-12 03:03:13 +00001032 if (CIP < CPUInfoEnd) {
1033 CPUStart = CIP;
1034 while (CIP < CPUInfoEnd && (*CIP != ' ' && *CIP != '\t' &&
1035 *CIP != ',' && *CIP != '\n'))
1036 ++CIP;
1037 CPULen = CIP - CPUStart;
1038 }
1039 }
1040 }
1041 }
1042 }
1043
1044 if (CPUStart == 0)
1045 while (CIP < CPUInfoEnd && *CIP != '\n')
1046 ++CIP;
1047 }
1048
1049 if (CPUStart == 0)
1050 return generic;
1051
1052 return StringSwitch<const char *>(StringRef(CPUStart, CPULen))
Eric Christopher5db9d662016-06-02 21:03:19 +00001053 .Case("604e", "604e")
1054 .Case("604", "604")
1055 .Case("7400", "7400")
1056 .Case("7410", "7400")
1057 .Case("7447", "7400")
1058 .Case("7455", "7450")
1059 .Case("G4", "g4")
1060 .Case("POWER4", "970")
1061 .Case("PPC970FX", "970")
1062 .Case("PPC970MP", "970")
1063 .Case("G5", "g5")
1064 .Case("POWER5", "g5")
1065 .Case("A2", "a2")
1066 .Case("POWER6", "pwr6")
1067 .Case("POWER7", "pwr7")
1068 .Case("POWER8", "pwr8")
1069 .Case("POWER8E", "pwr8")
1070 .Case("POWER9", "pwr9")
1071 .Default(generic);
Hal Finkel59b0ee82012-06-12 03:03:13 +00001072}
Benjamin Kramerefe40282012-06-26 21:36:32 +00001073#elif defined(__linux__) && defined(__arm__)
Rafael Espindola1f58e4d2013-12-12 16:10:48 +00001074StringRef sys::getHostCPUName() {
Benjamin Kramerefe40282012-06-26 21:36:32 +00001075 // The cpuid register on arm is not accessible from user space. On Linux,
1076 // it is exposed through the /proc/cpuinfo file.
Benjamin Kramerefe40282012-06-26 21:36:32 +00001077
1078 // Read 1024 bytes from /proc/cpuinfo, which should contain the CPU part line
1079 // in all cases.
1080 char buffer[1024];
Rafael Espindola97935a92014-12-17 02:32:44 +00001081 ssize_t CPUInfoSize = readCpuInfo(buffer, sizeof(buffer));
1082 if (CPUInfoSize == -1)
1083 return "generic";
Benjamin Kramerefe40282012-06-26 21:36:32 +00001084
1085 StringRef Str(buffer, CPUInfoSize);
1086
1087 SmallVector<StringRef, 32> Lines;
1088 Str.split(Lines, "\n");
1089
1090 // Look for the CPU implementer line.
1091 StringRef Implementer;
1092 for (unsigned I = 0, E = Lines.size(); I != E; ++I)
1093 if (Lines[I].startswith("CPU implementer"))
1094 Implementer = Lines[I].substr(15).ltrim("\t :");
1095
1096 if (Implementer == "0x41") // ARM Ltd.
1097 // Look for the CPU part line.
1098 for (unsigned I = 0, E = Lines.size(); I != E; ++I)
1099 if (Lines[I].startswith("CPU part"))
1100 // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The
1101 // values correspond to the "Part number" in the CP15/c0 register. The
1102 // contents are specified in the various processor manuals.
1103 return StringSwitch<const char *>(Lines[I].substr(8).ltrim("\t :"))
Eric Christopher5db9d662016-06-02 21:03:19 +00001104 .Case("0x926", "arm926ej-s")
1105 .Case("0xb02", "mpcore")
1106 .Case("0xb36", "arm1136j-s")
1107 .Case("0xb56", "arm1156t2-s")
1108 .Case("0xb76", "arm1176jz-s")
1109 .Case("0xc08", "cortex-a8")
1110 .Case("0xc09", "cortex-a9")
1111 .Case("0xc0f", "cortex-a15")
1112 .Case("0xc20", "cortex-m0")
1113 .Case("0xc23", "cortex-m3")
1114 .Case("0xc24", "cortex-m4")
1115 .Default("generic");
Benjamin Kramerefe40282012-06-26 21:36:32 +00001116
Kai Nackeb38bf962013-12-20 09:24:13 +00001117 if (Implementer == "0x51") // Qualcomm Technologies, Inc.
1118 // Look for the CPU part line.
1119 for (unsigned I = 0, E = Lines.size(); I != E; ++I)
1120 if (Lines[I].startswith("CPU part"))
1121 // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The
1122 // values correspond to the "Part number" in the CP15/c0 register. The
1123 // contents are specified in the various processor manuals.
1124 return StringSwitch<const char *>(Lines[I].substr(8).ltrim("\t :"))
Eric Christopher5db9d662016-06-02 21:03:19 +00001125 .Case("0x06f", "krait") // APQ8064
1126 .Default("generic");
Kai Nackeb38bf962013-12-20 09:24:13 +00001127
Benjamin Kramerefe40282012-06-26 21:36:32 +00001128 return "generic";
1129}
Richard Sandifordf834ea12013-10-31 12:14:17 +00001130#elif defined(__linux__) && defined(__s390x__)
Rafael Espindola1f58e4d2013-12-12 16:10:48 +00001131StringRef sys::getHostCPUName() {
Richard Sandifordf834ea12013-10-31 12:14:17 +00001132 // STIDP is a privileged operation, so use /proc/cpuinfo instead.
Richard Sandifordf834ea12013-10-31 12:14:17 +00001133
1134 // The "processor 0:" line comes after a fair amount of other information,
1135 // including a cache breakdown, but this should be plenty.
1136 char buffer[2048];
Rafael Espindola97935a92014-12-17 02:32:44 +00001137 ssize_t CPUInfoSize = readCpuInfo(buffer, sizeof(buffer));
1138 if (CPUInfoSize == -1)
1139 return "generic";
Richard Sandifordf834ea12013-10-31 12:14:17 +00001140
1141 StringRef Str(buffer, CPUInfoSize);
1142 SmallVector<StringRef, 32> Lines;
1143 Str.split(Lines, "\n");
Ulrich Weiganda8b04e12015-05-05 19:23:40 +00001144
1145 // Look for the CPU features.
1146 SmallVector<StringRef, 32> CPUFeatures;
1147 for (unsigned I = 0, E = Lines.size(); I != E; ++I)
1148 if (Lines[I].startswith("features")) {
1149 size_t Pos = Lines[I].find(":");
1150 if (Pos != StringRef::npos) {
Chandler Carruthe4405e92015-09-10 06:12:31 +00001151 Lines[I].drop_front(Pos + 1).split(CPUFeatures, ' ');
Ulrich Weiganda8b04e12015-05-05 19:23:40 +00001152 break;
1153 }
1154 }
1155
1156 // We need to check for the presence of vector support independently of
1157 // the machine type, since we may only use the vector register set when
1158 // supported by the kernel (and hypervisor).
1159 bool HaveVectorSupport = false;
1160 for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) {
1161 if (CPUFeatures[I] == "vx")
1162 HaveVectorSupport = true;
1163 }
1164
1165 // Now check the processor machine type.
Richard Sandifordf834ea12013-10-31 12:14:17 +00001166 for (unsigned I = 0, E = Lines.size(); I != E; ++I) {
1167 if (Lines[I].startswith("processor ")) {
1168 size_t Pos = Lines[I].find("machine = ");
1169 if (Pos != StringRef::npos) {
1170 Pos += sizeof("machine = ") - 1;
1171 unsigned int Id;
1172 if (!Lines[I].drop_front(Pos).getAsInteger(10, Id)) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +00001173 if (Id >= 2964 && HaveVectorSupport)
1174 return "z13";
Richard Sandifordf834ea12013-10-31 12:14:17 +00001175 if (Id >= 2827)
1176 return "zEC12";
1177 if (Id >= 2817)
1178 return "z196";
1179 }
1180 }
1181 break;
1182 }
1183 }
Eric Christopher5db9d662016-06-02 21:03:19 +00001184
Richard Sandifordf834ea12013-10-31 12:14:17 +00001185 return "generic";
1186}
Torok Edwinabdc1c22009-12-13 08:59:40 +00001187#else
Eric Christopher5db9d662016-06-02 21:03:19 +00001188StringRef sys::getHostCPUName() { return "generic"; }
Torok Edwinabdc1c22009-12-13 08:59:40 +00001189#endif
Xerxes Ranby17dc3a02010-01-19 21:26:05 +00001190
Alina Sbirlea33588b12016-07-20 18:15:29 +00001191#if defined(__i386__) || defined(_M_IX86) || \
1192 defined(__x86_64__) || defined(_M_X64)
Craig Topper798a2602015-03-29 01:00:23 +00001193bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
1194 unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
1195 unsigned MaxLevel;
1196 union {
1197 unsigned u[3];
Eric Christopher5db9d662016-06-02 21:03:19 +00001198 char c[12];
Craig Topper798a2602015-03-29 01:00:23 +00001199 } text;
1200
Alina Sbirlea400eb022016-06-03 20:27:50 +00001201 if (getX86CpuIDAndInfo(0, &MaxLevel, text.u + 0, text.u + 2, text.u + 1) ||
Craig Topper798a2602015-03-29 01:00:23 +00001202 MaxLevel < 1)
1203 return false;
1204
Alina Sbirlea400eb022016-06-03 20:27:50 +00001205 getX86CpuIDAndInfo(1, &EAX, &EBX, &ECX, &EDX);
Craig Topper798a2602015-03-29 01:00:23 +00001206
Eric Christopher5db9d662016-06-02 21:03:19 +00001207 Features["cmov"] = (EDX >> 15) & 1;
1208 Features["mmx"] = (EDX >> 23) & 1;
1209 Features["sse"] = (EDX >> 25) & 1;
1210 Features["sse2"] = (EDX >> 26) & 1;
1211 Features["sse3"] = (ECX >> 0) & 1;
1212 Features["ssse3"] = (ECX >> 9) & 1;
Craig Topper798a2602015-03-29 01:00:23 +00001213 Features["sse4.1"] = (ECX >> 19) & 1;
1214 Features["sse4.2"] = (ECX >> 20) & 1;
1215
Eric Christopher5db9d662016-06-02 21:03:19 +00001216 Features["pclmul"] = (ECX >> 1) & 1;
1217 Features["cx16"] = (ECX >> 13) & 1;
1218 Features["movbe"] = (ECX >> 22) & 1;
Craig Topper798a2602015-03-29 01:00:23 +00001219 Features["popcnt"] = (ECX >> 23) & 1;
Eric Christopher5db9d662016-06-02 21:03:19 +00001220 Features["aes"] = (ECX >> 25) & 1;
1221 Features["rdrnd"] = (ECX >> 30) & 1;
Craig Topper798a2602015-03-29 01:00:23 +00001222
1223 // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV
1224 // indicates that the AVX registers will be saved and restored on context
1225 // switch, then we have full AVX support.
Craig Topperb84b1262015-10-14 05:37:42 +00001226 bool HasAVXSave = ((ECX >> 27) & 1) && ((ECX >> 28) & 1) &&
Alina Sbirlea400eb022016-06-03 20:27:50 +00001227 !getX86XCR0(&EAX, &EDX) && ((EAX & 0x6) == 0x6);
Eric Christopher5db9d662016-06-02 21:03:19 +00001228 Features["avx"] = HasAVXSave;
1229 Features["fma"] = HasAVXSave && (ECX >> 12) & 1;
1230 Features["f16c"] = HasAVXSave && (ECX >> 29) & 1;
Craig Topperb84b1262015-10-14 05:37:42 +00001231
1232 // Only enable XSAVE if OS has enabled support for saving YMM state.
Eric Christopher5db9d662016-06-02 21:03:19 +00001233 Features["xsave"] = HasAVXSave && (ECX >> 26) & 1;
Craig Topper798a2602015-03-29 01:00:23 +00001234
1235 // AVX512 requires additional context to be saved by the OS.
Craig Topperb84b1262015-10-14 05:37:42 +00001236 bool HasAVX512Save = HasAVXSave && ((EAX & 0xe0) == 0xe0);
Craig Topper798a2602015-03-29 01:00:23 +00001237
1238 unsigned MaxExtLevel;
Alina Sbirlea400eb022016-06-03 20:27:50 +00001239 getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX);
Craig Topper798a2602015-03-29 01:00:23 +00001240
1241 bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 &&
Alina Sbirlea400eb022016-06-03 20:27:50 +00001242 !getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
Eric Christopher5db9d662016-06-02 21:03:19 +00001243 Features["lzcnt"] = HasExtLeaf1 && ((ECX >> 5) & 1);
1244 Features["sse4a"] = HasExtLeaf1 && ((ECX >> 6) & 1);
1245 Features["prfchw"] = HasExtLeaf1 && ((ECX >> 8) & 1);
1246 Features["xop"] = HasExtLeaf1 && ((ECX >> 11) & 1) && HasAVXSave;
1247 Features["fma4"] = HasExtLeaf1 && ((ECX >> 16) & 1) && HasAVXSave;
1248 Features["tbm"] = HasExtLeaf1 && ((ECX >> 21) & 1);
Ashutosh Nema348af9c2016-05-18 11:59:12 +00001249 Features["mwaitx"] = HasExtLeaf1 && ((ECX >> 29) & 1);
Craig Topper798a2602015-03-29 01:00:23 +00001250
Eric Christopher5db9d662016-06-02 21:03:19 +00001251 bool HasLeaf7 =
Alina Sbirlea400eb022016-06-03 20:27:50 +00001252 MaxLevel >= 7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
Craig Topper798a2602015-03-29 01:00:23 +00001253
1254 // AVX2 is only supported if we have the OS save support from AVX.
Eric Christopher5db9d662016-06-02 21:03:19 +00001255 Features["avx2"] = HasAVXSave && HasLeaf7 && ((EBX >> 5) & 1);
Craig Topper798a2602015-03-29 01:00:23 +00001256
Eric Christopher5db9d662016-06-02 21:03:19 +00001257 Features["fsgsbase"] = HasLeaf7 && ((EBX >> 0) & 1);
1258 Features["sgx"] = HasLeaf7 && ((EBX >> 2) & 1);
1259 Features["bmi"] = HasLeaf7 && ((EBX >> 3) & 1);
1260 Features["hle"] = HasLeaf7 && ((EBX >> 4) & 1);
1261 Features["bmi2"] = HasLeaf7 && ((EBX >> 8) & 1);
1262 Features["invpcid"] = HasLeaf7 && ((EBX >> 10) & 1);
1263 Features["rtm"] = HasLeaf7 && ((EBX >> 11) & 1);
1264 Features["rdseed"] = HasLeaf7 && ((EBX >> 18) & 1);
1265 Features["adx"] = HasLeaf7 && ((EBX >> 19) & 1);
1266 Features["smap"] = HasLeaf7 && ((EBX >> 20) & 1);
1267 Features["pcommit"] = HasLeaf7 && ((EBX >> 22) & 1);
Elena Demikhovsky29cde352016-01-24 10:41:28 +00001268 Features["clflushopt"] = HasLeaf7 && ((EBX >> 23) & 1);
Eric Christopher5db9d662016-06-02 21:03:19 +00001269 Features["clwb"] = HasLeaf7 && ((EBX >> 24) & 1);
1270 Features["sha"] = HasLeaf7 && ((EBX >> 29) & 1);
Craig Topper798a2602015-03-29 01:00:23 +00001271
1272 // AVX512 is only supported if the OS supports the context save for it.
Eric Christopher5db9d662016-06-02 21:03:19 +00001273 Features["avx512f"] = HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save;
Craig Topper798a2602015-03-29 01:00:23 +00001274 Features["avx512dq"] = HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save;
Elena Demikhovsky29cde352016-01-24 10:41:28 +00001275 Features["avx512ifma"] = HasLeaf7 && ((EBX >> 21) & 1) && HasAVX512Save;
Craig Topper798a2602015-03-29 01:00:23 +00001276 Features["avx512pf"] = HasLeaf7 && ((EBX >> 26) & 1) && HasAVX512Save;
1277 Features["avx512er"] = HasLeaf7 && ((EBX >> 27) & 1) && HasAVX512Save;
1278 Features["avx512cd"] = HasLeaf7 && ((EBX >> 28) & 1) && HasAVX512Save;
1279 Features["avx512bw"] = HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save;
1280 Features["avx512vl"] = HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save;
Elena Demikhovsky29cde352016-01-24 10:41:28 +00001281
1282 Features["prefetchwt1"] = HasLeaf7 && (ECX & 1);
Eric Christopher5db9d662016-06-02 21:03:19 +00001283 Features["avx512vbmi"] = HasLeaf7 && ((ECX >> 1) & 1) && HasAVX512Save;
Elena Demikhovsky29cde352016-01-24 10:41:28 +00001284 // Enable protection keys
Eric Christopher5db9d662016-06-02 21:03:19 +00001285 Features["pku"] = HasLeaf7 && ((ECX >> 4) & 1);
Craig Topper798a2602015-03-29 01:00:23 +00001286
Amjad Aboud1db6d7a2015-10-12 11:47:46 +00001287 bool HasLeafD = MaxLevel >= 0xd &&
Alina Sbirlea400eb022016-06-03 20:27:50 +00001288 !getX86CpuIDAndInfoEx(0xd, 0x1, &EAX, &EBX, &ECX, &EDX);
Amjad Aboud1db6d7a2015-10-12 11:47:46 +00001289
Craig Topperb84b1262015-10-14 05:37:42 +00001290 // Only enable XSAVE if OS has enabled support for saving YMM state.
1291 Features["xsaveopt"] = HasAVXSave && HasLeafD && ((EAX >> 0) & 1);
Eric Christopher5db9d662016-06-02 21:03:19 +00001292 Features["xsavec"] = HasAVXSave && HasLeafD && ((EAX >> 1) & 1);
1293 Features["xsaves"] = HasAVXSave && HasLeafD && ((EAX >> 3) & 1);
Amjad Aboud1db6d7a2015-10-12 11:47:46 +00001294
Craig Topper798a2602015-03-29 01:00:23 +00001295 return true;
1296}
1297#elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__))
Hao Liu10be3b22012-12-13 02:40:20 +00001298bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
Hao Liu10be3b22012-12-13 02:40:20 +00001299 // Read 1024 bytes from /proc/cpuinfo, which should contain the Features line
1300 // in all cases.
1301 char buffer[1024];
Rafael Espindola97935a92014-12-17 02:32:44 +00001302 ssize_t CPUInfoSize = readCpuInfo(buffer, sizeof(buffer));
1303 if (CPUInfoSize == -1)
1304 return false;
Hao Liu10be3b22012-12-13 02:40:20 +00001305
1306 StringRef Str(buffer, CPUInfoSize);
1307
1308 SmallVector<StringRef, 32> Lines;
1309 Str.split(Lines, "\n");
1310
Tobias Grosserbd9e5492013-06-11 21:45:01 +00001311 SmallVector<StringRef, 32> CPUFeatures;
1312
1313 // Look for the CPU features.
Hao Liu10be3b22012-12-13 02:40:20 +00001314 for (unsigned I = 0, E = Lines.size(); I != E; ++I)
Tobias Grosserbd9e5492013-06-11 21:45:01 +00001315 if (Lines[I].startswith("Features")) {
Chandler Carruthe4405e92015-09-10 06:12:31 +00001316 Lines[I].split(CPUFeatures, ' ');
Tobias Grosserbd9e5492013-06-11 21:45:01 +00001317 break;
Hao Liu10be3b22012-12-13 02:40:20 +00001318 }
1319
Bradley Smith9288b212014-05-22 11:44:34 +00001320#if defined(__aarch64__)
1321 // Keep track of which crypto features we have seen
Eric Christopher5db9d662016-06-02 21:03:19 +00001322 enum { CAP_AES = 0x1, CAP_PMULL = 0x2, CAP_SHA1 = 0x4, CAP_SHA2 = 0x8 };
Bradley Smith9288b212014-05-22 11:44:34 +00001323 uint32_t crypto = 0;
1324#endif
1325
Tobias Grosserbd9e5492013-06-11 21:45:01 +00001326 for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) {
1327 StringRef LLVMFeatureStr = StringSwitch<StringRef>(CPUFeatures[I])
Bradley Smith9288b212014-05-22 11:44:34 +00001328#if defined(__aarch64__)
Eric Christopher5db9d662016-06-02 21:03:19 +00001329 .Case("asimd", "neon")
1330 .Case("fp", "fp-armv8")
1331 .Case("crc32", "crc")
Bradley Smith9288b212014-05-22 11:44:34 +00001332#else
Eric Christopher5db9d662016-06-02 21:03:19 +00001333 .Case("half", "fp16")
1334 .Case("neon", "neon")
1335 .Case("vfpv3", "vfp3")
1336 .Case("vfpv3d16", "d16")
1337 .Case("vfpv4", "vfp4")
1338 .Case("idiva", "hwdiv-arm")
1339 .Case("idivt", "hwdiv")
Bradley Smith9288b212014-05-22 11:44:34 +00001340#endif
Eric Christopher5db9d662016-06-02 21:03:19 +00001341 .Default("");
Tobias Grosserbd9e5492013-06-11 21:45:01 +00001342
Bradley Smith9288b212014-05-22 11:44:34 +00001343#if defined(__aarch64__)
Alp Tokerda0c7932014-05-31 21:26:28 +00001344 // We need to check crypto separately since we need all of the crypto
Bradley Smith9288b212014-05-22 11:44:34 +00001345 // extensions to enable the subtarget feature
1346 if (CPUFeatures[I] == "aes")
Bradley Smith63c8b1b2014-05-23 10:14:13 +00001347 crypto |= CAP_AES;
Bradley Smith9288b212014-05-22 11:44:34 +00001348 else if (CPUFeatures[I] == "pmull")
Bradley Smith63c8b1b2014-05-23 10:14:13 +00001349 crypto |= CAP_PMULL;
Bradley Smith9288b212014-05-22 11:44:34 +00001350 else if (CPUFeatures[I] == "sha1")
Bradley Smith63c8b1b2014-05-23 10:14:13 +00001351 crypto |= CAP_SHA1;
Bradley Smith9288b212014-05-22 11:44:34 +00001352 else if (CPUFeatures[I] == "sha2")
Bradley Smith63c8b1b2014-05-23 10:14:13 +00001353 crypto |= CAP_SHA2;
Bradley Smith9288b212014-05-22 11:44:34 +00001354#endif
1355
Tobias Grosserbd9e5492013-06-11 21:45:01 +00001356 if (LLVMFeatureStr != "")
David Blaikie5106ce72014-11-19 05:49:42 +00001357 Features[LLVMFeatureStr] = true;
Hao Liu10be3b22012-12-13 02:40:20 +00001358 }
1359
Bradley Smith9288b212014-05-22 11:44:34 +00001360#if defined(__aarch64__)
1361 // If we have all crypto bits we can add the feature
Bradley Smith63c8b1b2014-05-23 10:14:13 +00001362 if (crypto == (CAP_AES | CAP_PMULL | CAP_SHA1 | CAP_SHA2))
David Blaikie5106ce72014-11-19 05:49:42 +00001363 Features["crypto"] = true;
Bradley Smith9288b212014-05-22 11:44:34 +00001364#endif
1365
Tobias Grosserbd9e5492013-06-11 21:45:01 +00001366 return true;
Hao Liu10be3b22012-12-13 02:40:20 +00001367}
1368#else
Eric Christopher5db9d662016-06-02 21:03:19 +00001369bool sys::getHostCPUFeatures(StringMap<bool> &Features) { return false; }
Hao Liu10be3b22012-12-13 02:40:20 +00001370#endif
Peter Collingbournea51c6ed2013-01-16 17:27:22 +00001371
1372std::string sys::getProcessTriple() {
Duncan Sandse2cd1392013-07-17 11:01:05 +00001373 Triple PT(Triple::normalize(LLVM_HOST_TRIPLE));
Peter Collingbournea51c6ed2013-01-16 17:27:22 +00001374
1375 if (sizeof(void *) == 8 && PT.isArch32Bit())
1376 PT = PT.get64BitArchVariant();
1377 if (sizeof(void *) == 4 && PT.isArch64Bit())
1378 PT = PT.get32BitArchVariant();
1379
1380 return PT.str();
1381}