blob: f5840977e1205b6a70e13e7cc5d4c8505aa6ad1e [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>
Daniel Dunbare52e6bf2008-10-02 01:17:28 +000024
25// Include the platform-specific parts of this class.
26#ifdef LLVM_ON_UNIX
27#include "Unix/Host.inc"
28#endif
29#ifdef LLVM_ON_WIN32
Michael J. Spencer447762d2010-11-29 18:16:10 +000030#include "Windows/Host.inc"
Daniel Dunbare52e6bf2008-10-02 01:17:28 +000031#endif
Benjamin Kramer38465062009-11-19 12:17:31 +000032#ifdef _MSC_VER
33#include <intrin.h>
34#endif
Hal Finkel59b0ee82012-06-12 03:03:13 +000035#if defined(__APPLE__) && (defined(__ppc__) || defined(__powerpc__))
Eric Christopher5db9d662016-06-02 21:03:19 +000036#include <mach/host_info.h>
Hal Finkel59b0ee82012-06-12 03:03:13 +000037#include <mach/mach.h>
38#include <mach/mach_host.h>
Hal Finkel59b0ee82012-06-12 03:03:13 +000039#include <mach/machine.h>
40#endif
Daniel Dunbare52e6bf2008-10-02 01:17:28 +000041
Chandler Carruth66f38db2014-04-21 23:58:10 +000042#define DEBUG_TYPE "host-detection"
43
Daniel Dunbar241d01b2009-11-14 10:09:12 +000044//===----------------------------------------------------------------------===//
45//
46// Implementations of the CPU detection routines
47//
48//===----------------------------------------------------------------------===//
49
50using namespace llvm;
51
Rafael Espindola81adfb52014-12-17 02:42:20 +000052#if defined(__linux__)
Duncan P. N. Exon Smith91d3cfe2016-04-05 20:45:04 +000053static ssize_t LLVM_ATTRIBUTE_UNUSED readCpuInfo(void *Buf, size_t Size) {
Rafael Espindola97935a92014-12-17 02:32:44 +000054 // Note: We cannot mmap /proc/cpuinfo here and then process the resulting
55 // memory buffer because the 'file' has 0 size (it can be read from only
56 // as a stream).
57
58 int FD;
59 std::error_code EC = sys::fs::openFileForRead("/proc/cpuinfo", FD);
60 if (EC) {
61 DEBUG(dbgs() << "Unable to open /proc/cpuinfo: " << EC.message() << "\n");
62 return -1;
63 }
64 int Ret = read(FD, Buf, Size);
65 int CloseStatus = close(FD);
66 if (CloseStatus)
67 return -1;
68 return Ret;
69}
Rafael Espindola81adfb52014-12-17 02:42:20 +000070#endif
Rafael Espindola97935a92014-12-17 02:32:44 +000071
Eric Christopher5db9d662016-06-02 21:03:19 +000072#if defined(i386) || defined(__i386__) || defined(__x86__) || \
73 defined(_M_IX86) || defined(__x86_64__) || defined(_M_AMD64) || \
74 defined(_M_X64)
Daniel Dunbar241d01b2009-11-14 10:09:12 +000075
Eric Christopher5db9d662016-06-02 21:03:19 +000076/// GetX86CpuIDAndInfo - Execute the specified cpuid and return the 4 values in
77/// the
Daniel Dunbar241d01b2009-11-14 10:09:12 +000078/// specified arguments. If we can't run cpuid on the host, return true.
Duncan P. N. Exon Smith91d3cfe2016-04-05 20:45:04 +000079static bool GetX86CpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX,
80 unsigned *rECX, unsigned *rEDX) {
Reid Klecknerbf4f9eb2013-08-16 22:42:42 +000081#if defined(__GNUC__) || defined(__clang__)
Eric Christopher5db9d662016-06-02 21:03:19 +000082#if defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
83 // gcc doesn't know cpuid would clobber ebx/rbx. Preseve it manually.
84 asm("movq\t%%rbx, %%rsi\n\t"
85 "cpuid\n\t"
86 "xchgq\t%%rbx, %%rsi\n\t"
87 : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
88 : "a"(value));
89 return false;
90#elif defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)
91 asm("movl\t%%ebx, %%esi\n\t"
92 "cpuid\n\t"
93 "xchgl\t%%ebx, %%esi\n\t"
94 : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
95 : "a"(value));
96 return false;
David Blaikieb48ed1a2012-01-17 04:43:56 +000097// pedantic #else returns to appease -Wunreachable-code (so we don't generate
98// postprocessed code that looks like "return true; return false;")
Eric Christopher5db9d662016-06-02 21:03:19 +000099#else
100 return true;
101#endif
Reid Klecknerbf4f9eb2013-08-16 22:42:42 +0000102#elif defined(_MSC_VER)
103 // The MSVC intrinsic is portable across x86 and x64.
104 int registers[4];
105 __cpuid(registers, value);
106 *rEAX = registers[0];
107 *rEBX = registers[1];
108 *rECX = registers[2];
109 *rEDX = registers[3];
110 return false;
David Blaikieb48ed1a2012-01-17 04:43:56 +0000111#else
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000112 return true;
David Blaikieb48ed1a2012-01-17 04:43:56 +0000113#endif
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000114}
115
Eric Christopher5db9d662016-06-02 21:03:19 +0000116/// GetX86CpuIDAndInfoEx - Execute the specified cpuid with subleaf and return
117/// the
Tim Northover89ccb612013-11-25 09:52:59 +0000118/// 4 values in the specified arguments. If we can't run cpuid on the host,
119/// return true.
Duncan P. N. Exon Smith91d3cfe2016-04-05 20:45:04 +0000120static bool GetX86CpuIDAndInfoEx(unsigned value, unsigned subleaf,
121 unsigned *rEAX, unsigned *rEBX, unsigned *rECX,
122 unsigned *rEDX) {
Eric Christopher5db9d662016-06-02 21:03:19 +0000123#if defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
124#if defined(__GNUC__)
125 // gcc doesn't know cpuid would clobber ebx/rbx. Preseve it manually.
126 asm("movq\t%%rbx, %%rsi\n\t"
127 "cpuid\n\t"
128 "xchgq\t%%rbx, %%rsi\n\t"
129 : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
130 : "a"(value), "c"(subleaf));
131 return false;
132#elif defined(_MSC_VER)
133 int registers[4];
134 __cpuidex(registers, value, subleaf);
135 *rEAX = registers[0];
136 *rEBX = registers[1];
137 *rECX = registers[2];
138 *rEDX = registers[3];
139 return false;
140#else
141 return true;
142#endif
Tim Northover89ccb612013-11-25 09:52:59 +0000143#elif defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)
Eric Christopher5db9d662016-06-02 21:03:19 +0000144#if defined(__GNUC__)
145 asm("movl\t%%ebx, %%esi\n\t"
146 "cpuid\n\t"
147 "xchgl\t%%ebx, %%esi\n\t"
148 : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
149 : "a"(value), "c"(subleaf));
150 return false;
151#elif defined(_MSC_VER)
152 __asm {
Tim Northover89ccb612013-11-25 09:52:59 +0000153 mov eax,value
154 mov ecx,subleaf
155 cpuid
156 mov esi,rEAX
157 mov dword ptr [esi],eax
158 mov esi,rEBX
159 mov dword ptr [esi],ebx
160 mov esi,rECX
161 mov dword ptr [esi],ecx
162 mov esi,rEDX
163 mov dword ptr [esi],edx
Eric Christopher5db9d662016-06-02 21:03:19 +0000164 }
165 return false;
166#else
167 return true;
168#endif
Tim Northover89ccb612013-11-25 09:52:59 +0000169#else
170 return true;
171#endif
172}
173
Duncan P. N. Exon Smith91d3cfe2016-04-05 20:45:04 +0000174static bool GetX86XCR0(unsigned *rEAX, unsigned *rEDX) {
Craig Topper7af39d72013-04-22 05:38:01 +0000175#if defined(__GNUC__)
176 // Check xgetbv; this uses a .byte sequence instead of the instruction
177 // directly because older assemblers do not include support for xgetbv and
178 // there is no easy way to conditionally compile based on the assembler used.
Eric Christopher5db9d662016-06-02 21:03:19 +0000179 __asm__(".byte 0x0f, 0x01, 0xd0" : "=a"(*rEAX), "=d"(*rEDX) : "c"(0));
Craig Topper798a2602015-03-29 01:00:23 +0000180 return false;
Aaron Ballman31c0adc2013-04-23 17:38:44 +0000181#elif defined(_MSC_FULL_VER) && defined(_XCR_XFEATURE_ENABLED_MASK)
Craig Topper798a2602015-03-29 01:00:23 +0000182 unsigned long long Result = _xgetbv(_XCR_XFEATURE_ENABLED_MASK);
Craig Topper7db49fd2015-03-29 01:07:57 +0000183 *rEAX = Result;
184 *rEDX = Result >> 32;
Craig Topper798a2602015-03-29 01:00:23 +0000185 return false;
Craig Topper7af39d72013-04-22 05:38:01 +0000186#else
Craig Topper798a2602015-03-29 01:00:23 +0000187 return true;
Craig Topper7af39d72013-04-22 05:38:01 +0000188#endif
Aaron Ballman5f7c6802013-04-03 12:25:06 +0000189}
190
Duncan P. N. Exon Smith91d3cfe2016-04-05 20:45:04 +0000191static void DetectX86FamilyModel(unsigned EAX, unsigned &Family,
192 unsigned &Model) {
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000193 Family = (EAX >> 8) & 0xf; // Bits 8 - 11
Eric Christopher5db9d662016-06-02 21:03:19 +0000194 Model = (EAX >> 4) & 0xf; // Bits 4 - 7
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000195 if (Family == 6 || Family == 0xf) {
196 if (Family == 0xf)
197 // Examine extended family ID if family ID is F.
Eric Christopher5db9d662016-06-02 21:03:19 +0000198 Family += (EAX >> 20) & 0xff; // Bits 20 - 27
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000199 // Examine extended model ID if family ID is 6 or F.
200 Model += ((EAX >> 16) & 0xf) << 4; // Bits 16 - 19
201 }
202}
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000203
Rafael Espindola74f444c2013-12-12 15:45:32 +0000204StringRef sys::getHostCPUName() {
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000205 unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
206 if (GetX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX))
207 return "generic";
208 unsigned Family = 0;
Eric Christopher5db9d662016-06-02 21:03:19 +0000209 unsigned Model = 0;
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000210 DetectX86FamilyModel(EAX, Family, Model);
211
Tim Northover89ccb612013-11-25 09:52:59 +0000212 union {
213 unsigned u[3];
Eric Christopher5db9d662016-06-02 21:03:19 +0000214 char c[12];
Tim Northover89ccb612013-11-25 09:52:59 +0000215 } text;
216
Craig Topper1214bdc2015-03-31 05:42:45 +0000217 unsigned MaxLeaf;
Eric Christopher5db9d662016-06-02 21:03:19 +0000218 GetX86CpuIDAndInfo(0, &MaxLeaf, text.u + 0, text.u + 2, text.u + 1);
Tim Northover89ccb612013-11-25 09:52:59 +0000219
Eric Christopher5db9d662016-06-02 21:03:19 +0000220 bool HasMMX = (EDX >> 23) & 1;
221 bool HasSSE = (EDX >> 25) & 1;
222 bool HasSSE2 = (EDX >> 26) & 1;
223 bool HasSSE3 = (ECX >> 0) & 1;
224 bool HasSSSE3 = (ECX >> 9) & 1;
Craig Topper1214bdc2015-03-31 05:42:45 +0000225 bool HasSSE41 = (ECX >> 19) & 1;
226 bool HasSSE42 = (ECX >> 20) & 1;
227 bool HasMOVBE = (ECX >> 22) & 1;
228 // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV
Aaron Ballman5f7c6802013-04-03 12:25:06 +0000229 // indicates that the AVX registers will be saved and restored on context
230 // switch, then we have full AVX support.
Aaron Ballman5e6d2052013-04-03 18:00:22 +0000231 const unsigned AVXBits = (1 << 27) | (1 << 28);
Craig Topper798a2602015-03-29 01:00:23 +0000232 bool HasAVX = ((ECX & AVXBits) == AVXBits) && !GetX86XCR0(&EAX, &EDX) &&
233 ((EAX & 0x6) == 0x6);
Craig Topper1214bdc2015-03-31 05:42:45 +0000234 bool HasAVX512Save = HasAVX && ((EAX & 0xe0) == 0xe0);
Eric Christopher5db9d662016-06-02 21:03:19 +0000235 bool HasLeaf7 =
236 MaxLeaf >= 0x7 && !GetX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
Craig Topper1214bdc2015-03-31 05:42:45 +0000237 bool HasADX = HasLeaf7 && ((EBX >> 19) & 1);
238 bool HasAVX2 = HasAVX && HasLeaf7 && (EBX & 0x20);
239 bool HasAVX512 = HasLeaf7 && HasAVX512Save && ((EBX >> 16) & 1);
240
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000241 GetX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
242 bool Em64T = (EDX >> 29) & 0x1;
Kaelyn Takataa39d2a02014-05-05 16:32:10 +0000243 bool HasTBM = (ECX >> 21) & 0x1;
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000244
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000245 if (memcmp(text.c, "GenuineIntel", 12) == 0) {
246 switch (Family) {
Daniel Dunbar397235f2009-11-14 21:36:19 +0000247 case 3:
248 return "i386";
249 case 4:
250 switch (Model) {
NAKAMURA Takumi19e11f12010-09-09 13:30:48 +0000251 case 0: // Intel486 DX processors
252 case 1: // Intel486 DX processors
Daniel Dunbar397235f2009-11-14 21:36:19 +0000253 case 2: // Intel486 SX processors
NAKAMURA Takumi19e11f12010-09-09 13:30:48 +0000254 case 3: // Intel487 processors, IntelDX2 OverDrive processors,
255 // IntelDX2 processors
Daniel Dunbar397235f2009-11-14 21:36:19 +0000256 case 4: // Intel486 SL processor
NAKAMURA Takumi19e11f12010-09-09 13:30:48 +0000257 case 5: // IntelSX2 processors
Daniel Dunbar397235f2009-11-14 21:36:19 +0000258 case 7: // Write-Back Enhanced IntelDX2 processors
NAKAMURA Takumi19e11f12010-09-09 13:30:48 +0000259 case 8: // IntelDX4 OverDrive processors, IntelDX4 processors
Eric Christopher5db9d662016-06-02 21:03:19 +0000260 default:
261 return "i486";
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000262 }
Daniel Dunbar397235f2009-11-14 21:36:19 +0000263 case 5:
264 switch (Model) {
Eric Christopher5db9d662016-06-02 21:03:19 +0000265 case 1: // Pentium OverDrive processor for Pentium processor (60, 66),
266 // Pentium processors (60, 66)
267 case 2: // Pentium OverDrive processor for Pentium processor (75, 90,
268 // 100, 120, 133), Pentium processors (75, 90, 100, 120, 133,
269 // 150, 166, 200)
270 case 3: // Pentium OverDrive processors for Intel486 processor-based
271 // systems
Daniel Dunbar397235f2009-11-14 21:36:19 +0000272 return "pentium";
273
Eric Christopher5db9d662016-06-02 21:03:19 +0000274 case 4: // Pentium OverDrive processor with MMX technology for Pentium
275 // processor (75, 90, 100, 120, 133), Pentium processor with
276 // MMX technology (166, 200)
Daniel Dunbar397235f2009-11-14 21:36:19 +0000277 return "pentium-mmx";
278
Eric Christopher5db9d662016-06-02 21:03:19 +0000279 default:
280 return "pentium";
Daniel Dunbar397235f2009-11-14 21:36:19 +0000281 }
282 case 6:
283 switch (Model) {
Craig Toppere7d743c2016-04-27 05:16:58 +0000284 case 0x01: // Pentium Pro processor
Daniel Dunbar397235f2009-11-14 21:36:19 +0000285 return "pentiumpro";
286
Craig Toppere7d743c2016-04-27 05:16:58 +0000287 case 0x03: // Intel Pentium II OverDrive processor, Pentium II processor,
288 // model 03
289 case 0x05: // Pentium II processor, model 05, Pentium II Xeon processor,
290 // model 05, and Intel Celeron processor, model 05
291 case 0x06: // Celeron processor, model 06
Daniel Dunbar397235f2009-11-14 21:36:19 +0000292 return "pentium2";
293
Craig Toppere7d743c2016-04-27 05:16:58 +0000294 case 0x07: // Pentium III processor, model 07, and Pentium III Xeon
295 // processor, model 07
296 case 0x08: // Pentium III processor, model 08, Pentium III Xeon processor,
297 // model 08, and Celeron processor, model 08
298 case 0x0a: // Pentium III Xeon processor, model 0Ah
299 case 0x0b: // Pentium III processor, model 0Bh
Daniel Dunbar397235f2009-11-14 21:36:19 +0000300 return "pentium3";
301
Eric Christopher5db9d662016-06-02 21:03:19 +0000302 case 0x09: // Intel Pentium M processor, Intel Celeron M processor model
303 // 09.
Craig Toppere7d743c2016-04-27 05:16:58 +0000304 case 0x0d: // Intel Pentium M processor, Intel Celeron M processor, model
Eric Christopher5db9d662016-06-02 21:03:19 +0000305 // 0Dh. All processors are manufactured using the 90 nm process.
Craig Toppere7d743c2016-04-27 05:16:58 +0000306 case 0x15: // Intel EP80579 Integrated Processor and Intel EP80579
307 // Integrated Processor with Intel QuickAssist Technology
Daniel Dunbar397235f2009-11-14 21:36:19 +0000308 return "pentium-m";
309
Craig Toppere7d743c2016-04-27 05:16:58 +0000310 case 0x0e: // Intel Core Duo processor, Intel Core Solo processor, model
Eric Christopher5db9d662016-06-02 21:03:19 +0000311 // 0Eh. All processors are manufactured using the 65 nm process.
Daniel Dunbar397235f2009-11-14 21:36:19 +0000312 return "yonah";
313
Craig Toppere7d743c2016-04-27 05:16:58 +0000314 case 0x0f: // Intel Core 2 Duo processor, Intel Core 2 Duo mobile
315 // processor, Intel Core 2 Quad processor, Intel Core 2 Quad
316 // mobile processor, Intel Core 2 Extreme processor, Intel
317 // Pentium Dual-Core processor, Intel Xeon processor, model
Eric Christopher5db9d662016-06-02 21:03:19 +0000318 // 0Fh. All processors are manufactured using the 65 nm process.
Craig Toppere7d743c2016-04-27 05:16:58 +0000319 case 0x16: // Intel Celeron processor model 16h. All processors are
320 // manufactured using the 65 nm process
Daniel Dunbar397235f2009-11-14 21:36:19 +0000321 return "core2";
322
Craig Toppere7d743c2016-04-27 05:16:58 +0000323 case 0x17: // Intel Core 2 Extreme processor, Intel Xeon processor, model
Eric Christopher5db9d662016-06-02 21:03:19 +0000324 // 17h. All processors are manufactured using the 45 nm process.
325 //
326 // 45nm: Penryn , Wolfdale, Yorkfield (XE)
327 case 0x1d: // Intel Xeon processor MP. All processors are manufactured
328 // using
Craig Toppere7d743c2016-04-27 05:16:58 +0000329 // the 45 nm process.
Craig Topper545b9512015-03-31 06:18:31 +0000330 return "penryn";
Daniel Dunbar397235f2009-11-14 21:36:19 +0000331
Craig Toppere7d743c2016-04-27 05:16:58 +0000332 case 0x1a: // Intel Core i7 processor and Intel Xeon processor. All
333 // processors are manufactured using the 45 nm process.
334 case 0x1e: // Intel(R) Core(TM) i7 CPU 870 @ 2.93GHz.
335 // As found in a Summer 2010 model iMac.
336 case 0x2e: // Nehalem EX
Craig Topper3c2e7582015-03-30 06:31:09 +0000337 return "nehalem";
Craig Toppere7d743c2016-04-27 05:16:58 +0000338 case 0x25: // Intel Core i7, laptop version.
339 case 0x2c: // Intel Core i7 processor and Intel Xeon processor. All
340 // processors are manufactured using the 32 nm process.
341 case 0x2f: // Westmere EX
Craig Topper3c2e7582015-03-30 06:31:09 +0000342 return "westmere";
Bob Wilsond0f06002011-07-08 22:33:59 +0000343
Craig Toppere7d743c2016-04-27 05:16:58 +0000344 case 0x2a: // Intel Core i7 processor. All processors are manufactured
345 // using the 32 nm process.
346 case 0x2d:
Craig Topper545b9512015-03-31 06:18:31 +0000347 return "sandybridge";
Daniel Dunbar397235f2009-11-14 21:36:19 +0000348
Craig Toppere7d743c2016-04-27 05:16:58 +0000349 case 0x3a:
350 case 0x3e: // Ivy Bridge EP
Craig Topper545b9512015-03-31 06:18:31 +0000351 return "ivybridge";
Evan Cheng7fd16072012-04-23 22:41:39 +0000352
Tim Northover89ccb612013-11-25 09:52:59 +0000353 // Haswell:
Craig Toppere7d743c2016-04-27 05:16:58 +0000354 case 0x3c:
355 case 0x3f:
356 case 0x45:
357 case 0x46:
Craig Topper545b9512015-03-31 06:18:31 +0000358 return "haswell";
Tim Northover89ccb612013-11-25 09:52:59 +0000359
Craig Topper1e1b0f72015-03-23 00:15:06 +0000360 // Broadwell:
Craig Toppere7d743c2016-04-27 05:16:58 +0000361 case 0x3d:
362 case 0x47:
363 case 0x4f:
364 case 0x56:
Craig Topper545b9512015-03-31 06:18:31 +0000365 return "broadwell";
Craig Topper1e1b0f72015-03-23 00:15:06 +0000366
Craig Topper68ba18f2015-08-08 01:29:15 +0000367 // Skylake:
Craig Toppere7d743c2016-04-27 05:16:58 +0000368 case 0x4e:
Sanjoy Dasaa63dc02016-02-21 17:12:03 +0000369 return "skylake-avx512";
Craig Toppere7d743c2016-04-27 05:16:58 +0000370 case 0x5e:
Craig Topper68ba18f2015-08-08 01:29:15 +0000371 return "skylake";
372
Craig Toppere7d743c2016-04-27 05:16:58 +0000373 case 0x1c: // Most 45 nm Intel Atom processors
374 case 0x26: // 45 nm Atom Lincroft
375 case 0x27: // 32 nm Atom Medfield
376 case 0x35: // 32 nm Atom Midview
377 case 0x36: // 32 nm Atom Midview
Craig Topper3c2e7582015-03-30 06:31:09 +0000378 return "bonnell";
Daniel Dunbar397235f2009-11-14 21:36:19 +0000379
Preston Gurd3fe264d2013-09-13 19:23:28 +0000380 // Atom Silvermont codes from the Intel software optimization guide.
Craig Toppere7d743c2016-04-27 05:16:58 +0000381 case 0x37:
382 case 0x4a:
383 case 0x4d:
384 case 0x5a:
385 case 0x5d:
Craig Topperde4318b2016-04-27 05:17:00 +0000386 case 0x4c: // really airmont
Craig Topper3c2e7582015-03-30 06:31:09 +0000387 return "silvermont";
Benjamin Kramer8f429382013-08-30 14:05:32 +0000388
Craig Topperde4318b2016-04-27 05:17:00 +0000389 case 0x57:
390 return "knl";
391
Craig Topper1214bdc2015-03-31 05:42:45 +0000392 default: // Unknown family 6 CPU, try to guess.
393 if (HasAVX512)
394 return "knl";
395 if (HasADX)
396 return "broadwell";
397 if (HasAVX2)
398 return "haswell";
399 if (HasAVX)
400 return "sandybridge";
401 if (HasSSE42)
402 return HasMOVBE ? "silvermont" : "nehalem";
403 if (HasSSE41)
404 return "penryn";
405 if (HasSSSE3)
406 return HasMOVBE ? "bonnell" : "core2";
407 if (Em64T)
408 return "x86-64";
409 if (HasSSE2)
410 return "pentium-m";
411 if (HasSSE)
412 return "pentium3";
413 if (HasMMX)
414 return "pentium2";
415 return "pentiumpro";
Daniel Dunbar397235f2009-11-14 21:36:19 +0000416 }
417 case 15: {
418 switch (Model) {
Eric Christopher5db9d662016-06-02 21:03:19 +0000419 case 0: // Pentium 4 processor, Intel Xeon processor. All processors are
420 // model 00h and manufactured using the 0.18 micron process.
421 case 1: // Pentium 4 processor, Intel Xeon processor, Intel Xeon
422 // processor MP, and Intel Celeron processor. All processors are
423 // model 01h and manufactured using the 0.18 micron process.
424 case 2: // Pentium 4 processor, Mobile Intel Pentium 4 processor - M,
425 // Intel Xeon processor, Intel Xeon processor MP, Intel Celeron
426 // processor, and Mobile Intel Celeron processor. All processors
427 // are model 02h and manufactured using the 0.13 micron process.
Daniel Dunbar397235f2009-11-14 21:36:19 +0000428 return (Em64T) ? "x86-64" : "pentium4";
429
Eric Christopher5db9d662016-06-02 21:03:19 +0000430 case 3: // Pentium 4 processor, Intel Xeon processor, Intel Celeron D
431 // processor. All processors are model 03h and manufactured using
432 // the 90 nm process.
433 case 4: // Pentium 4 processor, Pentium 4 processor Extreme Edition,
434 // Pentium D processor, Intel Xeon processor, Intel Xeon
435 // processor MP, Intel Celeron D processor. All processors are
436 // model 04h and manufactured using the 90 nm process.
437 case 6: // Pentium 4 processor, Pentium D processor, Pentium processor
438 // Extreme Edition, Intel Xeon processor, Intel Xeon processor
439 // MP, Intel Celeron D processor. All processors are model 06h
440 // and manufactured using the 65 nm process.
Daniel Dunbar397235f2009-11-14 21:36:19 +0000441 return (Em64T) ? "nocona" : "prescott";
442
Daniel Dunbar397235f2009-11-14 21:36:19 +0000443 default:
444 return (Em64T) ? "x86-64" : "pentium4";
445 }
446 }
447
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000448 default:
Benjamin Kramer713fd352009-11-17 17:57:04 +0000449 return "generic";
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000450 }
451 } else if (memcmp(text.c, "AuthenticAMD", 12) == 0) {
452 // FIXME: this poorly matches the generated SubtargetFeatureKV table. There
453 // appears to be no way to generate the wide variety of AMD-specific targets
454 // from the information returned from CPUID.
455 switch (Family) {
Eric Christopher5db9d662016-06-02 21:03:19 +0000456 case 4:
457 return "i486";
458 case 5:
459 switch (Model) {
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000460 case 6:
Eric Christopher5db9d662016-06-02 21:03:19 +0000461 case 7:
462 return "k6";
463 case 8:
464 return "k6-2";
465 case 9:
466 case 13:
467 return "k6-3";
468 case 10:
469 return "geode";
470 default:
471 return "pentium";
472 }
473 case 6:
474 switch (Model) {
475 case 4:
476 return "athlon-tbird";
477 case 6:
478 case 7:
479 case 8:
480 return "athlon-mp";
481 case 10:
482 return "athlon-xp";
483 default:
484 return "athlon";
485 }
486 case 15:
487 if (HasSSE3)
488 return "k8-sse3";
489 switch (Model) {
490 case 1:
491 return "opteron";
492 case 5:
493 return "athlon-fx"; // also opteron
494 default:
495 return "athlon64";
496 }
497 case 16:
498 return "amdfam10";
499 case 20:
500 return "btver1";
501 case 21:
502 if (!HasAVX) // If the OS doesn't support AVX provide a sane fallback.
Benjamin Kramer077ae1d2012-01-10 11:50:02 +0000503 return "btver1";
Eric Christopher5db9d662016-06-02 21:03:19 +0000504 if (Model >= 0x50)
505 return "bdver4"; // 50h-6Fh: Excavator
506 if (Model >= 0x30)
507 return "bdver3"; // 30h-3Fh: Steamroller
508 if (Model >= 0x10 || HasTBM)
509 return "bdver2"; // 10h-1Fh: Piledriver
510 return "bdver1"; // 00h-0Fh: Bulldozer
511 case 22:
512 if (!HasAVX) // If the OS doesn't support AVX provide a sane fallback.
513 return "btver1";
514 return "btver2";
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000515 default:
Benjamin Kramer713fd352009-11-17 17:57:04 +0000516 return "generic";
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000517 }
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000518 }
Torok Edwin022336a2009-12-14 12:38:18 +0000519 return "generic";
Torok Edwinabdc1c22009-12-13 08:59:40 +0000520}
Hal Finkel59b0ee82012-06-12 03:03:13 +0000521#elif defined(__APPLE__) && (defined(__ppc__) || defined(__powerpc__))
Rafael Espindola1f58e4d2013-12-12 16:10:48 +0000522StringRef sys::getHostCPUName() {
Hal Finkel59b0ee82012-06-12 03:03:13 +0000523 host_basic_info_data_t hostInfo;
524 mach_msg_type_number_t infoCount;
525
526 infoCount = HOST_BASIC_INFO_COUNT;
Eric Christopher5db9d662016-06-02 21:03:19 +0000527 host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostInfo,
Hal Finkel59b0ee82012-06-12 03:03:13 +0000528 &infoCount);
Hal Finkel59b0ee82012-06-12 03:03:13 +0000529
Eric Christopher5db9d662016-06-02 21:03:19 +0000530 if (hostInfo.cpu_type != CPU_TYPE_POWERPC)
531 return "generic";
532
533 switch (hostInfo.cpu_subtype) {
534 case CPU_SUBTYPE_POWERPC_601:
535 return "601";
536 case CPU_SUBTYPE_POWERPC_602:
537 return "602";
538 case CPU_SUBTYPE_POWERPC_603:
539 return "603";
540 case CPU_SUBTYPE_POWERPC_603e:
541 return "603e";
542 case CPU_SUBTYPE_POWERPC_603ev:
543 return "603ev";
544 case CPU_SUBTYPE_POWERPC_604:
545 return "604";
546 case CPU_SUBTYPE_POWERPC_604e:
547 return "604e";
548 case CPU_SUBTYPE_POWERPC_620:
549 return "620";
550 case CPU_SUBTYPE_POWERPC_750:
551 return "750";
552 case CPU_SUBTYPE_POWERPC_7400:
553 return "7400";
554 case CPU_SUBTYPE_POWERPC_7450:
555 return "7450";
556 case CPU_SUBTYPE_POWERPC_970:
557 return "970";
558 default:;
Hal Finkel59b0ee82012-06-12 03:03:13 +0000559 }
Eric Christopher5db9d662016-06-02 21:03:19 +0000560
Hal Finkel59b0ee82012-06-12 03:03:13 +0000561 return "generic";
562}
563#elif defined(__linux__) && (defined(__ppc__) || defined(__powerpc__))
Rafael Espindolab75ea012013-12-12 16:17:40 +0000564StringRef sys::getHostCPUName() {
Hal Finkel59b0ee82012-06-12 03:03:13 +0000565 // Access to the Processor Version Register (PVR) on PowerPC is privileged,
566 // and so we must use an operating-system interface to determine the current
567 // processor type. On Linux, this is exposed through the /proc/cpuinfo file.
568 const char *generic = "generic";
569
Hal Finkel59b0ee82012-06-12 03:03:13 +0000570 // The cpu line is second (after the 'processor: 0' line), so if this
571 // buffer is too small then something has changed (or is wrong).
572 char buffer[1024];
Rafael Espindola97935a92014-12-17 02:32:44 +0000573 ssize_t CPUInfoSize = readCpuInfo(buffer, sizeof(buffer));
574 if (CPUInfoSize == -1)
575 return generic;
Hal Finkel59b0ee82012-06-12 03:03:13 +0000576
577 const char *CPUInfoStart = buffer;
578 const char *CPUInfoEnd = buffer + CPUInfoSize;
579
580 const char *CIP = CPUInfoStart;
581
582 const char *CPUStart = 0;
583 size_t CPULen = 0;
584
585 // We need to find the first line which starts with cpu, spaces, and a colon.
586 // After the colon, there may be some additional spaces and then the cpu type.
587 while (CIP < CPUInfoEnd && CPUStart == 0) {
588 if (CIP < CPUInfoEnd && *CIP == '\n')
589 ++CIP;
590
591 if (CIP < CPUInfoEnd && *CIP == 'c') {
592 ++CIP;
593 if (CIP < CPUInfoEnd && *CIP == 'p') {
594 ++CIP;
595 if (CIP < CPUInfoEnd && *CIP == 'u') {
596 ++CIP;
597 while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t'))
598 ++CIP;
Eric Christopher5db9d662016-06-02 21:03:19 +0000599
Hal Finkel59b0ee82012-06-12 03:03:13 +0000600 if (CIP < CPUInfoEnd && *CIP == ':') {
601 ++CIP;
602 while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t'))
603 ++CIP;
Eric Christopher5db9d662016-06-02 21:03:19 +0000604
Hal Finkel59b0ee82012-06-12 03:03:13 +0000605 if (CIP < CPUInfoEnd) {
606 CPUStart = CIP;
607 while (CIP < CPUInfoEnd && (*CIP != ' ' && *CIP != '\t' &&
608 *CIP != ',' && *CIP != '\n'))
609 ++CIP;
610 CPULen = CIP - CPUStart;
611 }
612 }
613 }
614 }
615 }
616
617 if (CPUStart == 0)
618 while (CIP < CPUInfoEnd && *CIP != '\n')
619 ++CIP;
620 }
621
622 if (CPUStart == 0)
623 return generic;
624
625 return StringSwitch<const char *>(StringRef(CPUStart, CPULen))
Eric Christopher5db9d662016-06-02 21:03:19 +0000626 .Case("604e", "604e")
627 .Case("604", "604")
628 .Case("7400", "7400")
629 .Case("7410", "7400")
630 .Case("7447", "7400")
631 .Case("7455", "7450")
632 .Case("G4", "g4")
633 .Case("POWER4", "970")
634 .Case("PPC970FX", "970")
635 .Case("PPC970MP", "970")
636 .Case("G5", "g5")
637 .Case("POWER5", "g5")
638 .Case("A2", "a2")
639 .Case("POWER6", "pwr6")
640 .Case("POWER7", "pwr7")
641 .Case("POWER8", "pwr8")
642 .Case("POWER8E", "pwr8")
643 .Case("POWER9", "pwr9")
644 .Default(generic);
Hal Finkel59b0ee82012-06-12 03:03:13 +0000645}
Benjamin Kramerefe40282012-06-26 21:36:32 +0000646#elif defined(__linux__) && defined(__arm__)
Rafael Espindola1f58e4d2013-12-12 16:10:48 +0000647StringRef sys::getHostCPUName() {
Benjamin Kramerefe40282012-06-26 21:36:32 +0000648 // The cpuid register on arm is not accessible from user space. On Linux,
649 // it is exposed through the /proc/cpuinfo file.
Benjamin Kramerefe40282012-06-26 21:36:32 +0000650
651 // Read 1024 bytes from /proc/cpuinfo, which should contain the CPU part line
652 // in all cases.
653 char buffer[1024];
Rafael Espindola97935a92014-12-17 02:32:44 +0000654 ssize_t CPUInfoSize = readCpuInfo(buffer, sizeof(buffer));
655 if (CPUInfoSize == -1)
656 return "generic";
Benjamin Kramerefe40282012-06-26 21:36:32 +0000657
658 StringRef Str(buffer, CPUInfoSize);
659
660 SmallVector<StringRef, 32> Lines;
661 Str.split(Lines, "\n");
662
663 // Look for the CPU implementer line.
664 StringRef Implementer;
665 for (unsigned I = 0, E = Lines.size(); I != E; ++I)
666 if (Lines[I].startswith("CPU implementer"))
667 Implementer = Lines[I].substr(15).ltrim("\t :");
668
669 if (Implementer == "0x41") // ARM Ltd.
670 // Look for the CPU part line.
671 for (unsigned I = 0, E = Lines.size(); I != E; ++I)
672 if (Lines[I].startswith("CPU part"))
673 // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The
674 // values correspond to the "Part number" in the CP15/c0 register. The
675 // contents are specified in the various processor manuals.
676 return StringSwitch<const char *>(Lines[I].substr(8).ltrim("\t :"))
Eric Christopher5db9d662016-06-02 21:03:19 +0000677 .Case("0x926", "arm926ej-s")
678 .Case("0xb02", "mpcore")
679 .Case("0xb36", "arm1136j-s")
680 .Case("0xb56", "arm1156t2-s")
681 .Case("0xb76", "arm1176jz-s")
682 .Case("0xc08", "cortex-a8")
683 .Case("0xc09", "cortex-a9")
684 .Case("0xc0f", "cortex-a15")
685 .Case("0xc20", "cortex-m0")
686 .Case("0xc23", "cortex-m3")
687 .Case("0xc24", "cortex-m4")
688 .Default("generic");
Benjamin Kramerefe40282012-06-26 21:36:32 +0000689
Kai Nackeb38bf962013-12-20 09:24:13 +0000690 if (Implementer == "0x51") // Qualcomm Technologies, Inc.
691 // Look for the CPU part line.
692 for (unsigned I = 0, E = Lines.size(); I != E; ++I)
693 if (Lines[I].startswith("CPU part"))
694 // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The
695 // values correspond to the "Part number" in the CP15/c0 register. The
696 // contents are specified in the various processor manuals.
697 return StringSwitch<const char *>(Lines[I].substr(8).ltrim("\t :"))
Eric Christopher5db9d662016-06-02 21:03:19 +0000698 .Case("0x06f", "krait") // APQ8064
699 .Default("generic");
Kai Nackeb38bf962013-12-20 09:24:13 +0000700
Benjamin Kramerefe40282012-06-26 21:36:32 +0000701 return "generic";
702}
Richard Sandifordf834ea12013-10-31 12:14:17 +0000703#elif defined(__linux__) && defined(__s390x__)
Rafael Espindola1f58e4d2013-12-12 16:10:48 +0000704StringRef sys::getHostCPUName() {
Richard Sandifordf834ea12013-10-31 12:14:17 +0000705 // STIDP is a privileged operation, so use /proc/cpuinfo instead.
Richard Sandifordf834ea12013-10-31 12:14:17 +0000706
707 // The "processor 0:" line comes after a fair amount of other information,
708 // including a cache breakdown, but this should be plenty.
709 char buffer[2048];
Rafael Espindola97935a92014-12-17 02:32:44 +0000710 ssize_t CPUInfoSize = readCpuInfo(buffer, sizeof(buffer));
711 if (CPUInfoSize == -1)
712 return "generic";
Richard Sandifordf834ea12013-10-31 12:14:17 +0000713
714 StringRef Str(buffer, CPUInfoSize);
715 SmallVector<StringRef, 32> Lines;
716 Str.split(Lines, "\n");
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000717
718 // Look for the CPU features.
719 SmallVector<StringRef, 32> CPUFeatures;
720 for (unsigned I = 0, E = Lines.size(); I != E; ++I)
721 if (Lines[I].startswith("features")) {
722 size_t Pos = Lines[I].find(":");
723 if (Pos != StringRef::npos) {
Chandler Carruthe4405e92015-09-10 06:12:31 +0000724 Lines[I].drop_front(Pos + 1).split(CPUFeatures, ' ');
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000725 break;
726 }
727 }
728
729 // We need to check for the presence of vector support independently of
730 // the machine type, since we may only use the vector register set when
731 // supported by the kernel (and hypervisor).
732 bool HaveVectorSupport = false;
733 for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) {
734 if (CPUFeatures[I] == "vx")
735 HaveVectorSupport = true;
736 }
737
738 // Now check the processor machine type.
Richard Sandifordf834ea12013-10-31 12:14:17 +0000739 for (unsigned I = 0, E = Lines.size(); I != E; ++I) {
740 if (Lines[I].startswith("processor ")) {
741 size_t Pos = Lines[I].find("machine = ");
742 if (Pos != StringRef::npos) {
743 Pos += sizeof("machine = ") - 1;
744 unsigned int Id;
745 if (!Lines[I].drop_front(Pos).getAsInteger(10, Id)) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000746 if (Id >= 2964 && HaveVectorSupport)
747 return "z13";
Richard Sandifordf834ea12013-10-31 12:14:17 +0000748 if (Id >= 2827)
749 return "zEC12";
750 if (Id >= 2817)
751 return "z196";
752 }
753 }
754 break;
755 }
756 }
Eric Christopher5db9d662016-06-02 21:03:19 +0000757
Richard Sandifordf834ea12013-10-31 12:14:17 +0000758 return "generic";
759}
Torok Edwinabdc1c22009-12-13 08:59:40 +0000760#else
Eric Christopher5db9d662016-06-02 21:03:19 +0000761StringRef sys::getHostCPUName() { return "generic"; }
Torok Edwinabdc1c22009-12-13 08:59:40 +0000762#endif
Xerxes Ranby17dc3a02010-01-19 21:26:05 +0000763
Eric Christopher5db9d662016-06-02 21:03:19 +0000764#if defined(i386) || defined(__i386__) || defined(__x86__) || \
765 defined(_M_IX86) || defined(__x86_64__) || defined(_M_AMD64) || \
766 defined(_M_X64)
Craig Topper798a2602015-03-29 01:00:23 +0000767bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
768 unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
769 unsigned MaxLevel;
770 union {
771 unsigned u[3];
Eric Christopher5db9d662016-06-02 21:03:19 +0000772 char c[12];
Craig Topper798a2602015-03-29 01:00:23 +0000773 } text;
774
Eric Christopher5db9d662016-06-02 21:03:19 +0000775 if (GetX86CpuIDAndInfo(0, &MaxLevel, text.u + 0, text.u + 2, text.u + 1) ||
Craig Topper798a2602015-03-29 01:00:23 +0000776 MaxLevel < 1)
777 return false;
778
779 GetX86CpuIDAndInfo(1, &EAX, &EBX, &ECX, &EDX);
780
Eric Christopher5db9d662016-06-02 21:03:19 +0000781 Features["cmov"] = (EDX >> 15) & 1;
782 Features["mmx"] = (EDX >> 23) & 1;
783 Features["sse"] = (EDX >> 25) & 1;
784 Features["sse2"] = (EDX >> 26) & 1;
785 Features["sse3"] = (ECX >> 0) & 1;
786 Features["ssse3"] = (ECX >> 9) & 1;
Craig Topper798a2602015-03-29 01:00:23 +0000787 Features["sse4.1"] = (ECX >> 19) & 1;
788 Features["sse4.2"] = (ECX >> 20) & 1;
789
Eric Christopher5db9d662016-06-02 21:03:19 +0000790 Features["pclmul"] = (ECX >> 1) & 1;
791 Features["cx16"] = (ECX >> 13) & 1;
792 Features["movbe"] = (ECX >> 22) & 1;
Craig Topper798a2602015-03-29 01:00:23 +0000793 Features["popcnt"] = (ECX >> 23) & 1;
Eric Christopher5db9d662016-06-02 21:03:19 +0000794 Features["aes"] = (ECX >> 25) & 1;
795 Features["rdrnd"] = (ECX >> 30) & 1;
Craig Topper798a2602015-03-29 01:00:23 +0000796
797 // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV
798 // indicates that the AVX registers will be saved and restored on context
799 // switch, then we have full AVX support.
Craig Topperb84b1262015-10-14 05:37:42 +0000800 bool HasAVXSave = ((ECX >> 27) & 1) && ((ECX >> 28) & 1) &&
801 !GetX86XCR0(&EAX, &EDX) && ((EAX & 0x6) == 0x6);
Eric Christopher5db9d662016-06-02 21:03:19 +0000802 Features["avx"] = HasAVXSave;
803 Features["fma"] = HasAVXSave && (ECX >> 12) & 1;
804 Features["f16c"] = HasAVXSave && (ECX >> 29) & 1;
Craig Topperb84b1262015-10-14 05:37:42 +0000805
806 // Only enable XSAVE if OS has enabled support for saving YMM state.
Eric Christopher5db9d662016-06-02 21:03:19 +0000807 Features["xsave"] = HasAVXSave && (ECX >> 26) & 1;
Craig Topper798a2602015-03-29 01:00:23 +0000808
809 // AVX512 requires additional context to be saved by the OS.
Craig Topperb84b1262015-10-14 05:37:42 +0000810 bool HasAVX512Save = HasAVXSave && ((EAX & 0xe0) == 0xe0);
Craig Topper798a2602015-03-29 01:00:23 +0000811
812 unsigned MaxExtLevel;
813 GetX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX);
814
815 bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 &&
816 !GetX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
Eric Christopher5db9d662016-06-02 21:03:19 +0000817 Features["lzcnt"] = HasExtLeaf1 && ((ECX >> 5) & 1);
818 Features["sse4a"] = HasExtLeaf1 && ((ECX >> 6) & 1);
819 Features["prfchw"] = HasExtLeaf1 && ((ECX >> 8) & 1);
820 Features["xop"] = HasExtLeaf1 && ((ECX >> 11) & 1) && HasAVXSave;
821 Features["fma4"] = HasExtLeaf1 && ((ECX >> 16) & 1) && HasAVXSave;
822 Features["tbm"] = HasExtLeaf1 && ((ECX >> 21) & 1);
Ashutosh Nema348af9c2016-05-18 11:59:12 +0000823 Features["mwaitx"] = HasExtLeaf1 && ((ECX >> 29) & 1);
Craig Topper798a2602015-03-29 01:00:23 +0000824
Eric Christopher5db9d662016-06-02 21:03:19 +0000825 bool HasLeaf7 =
826 MaxLevel >= 7 && !GetX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
Craig Topper798a2602015-03-29 01:00:23 +0000827
828 // AVX2 is only supported if we have the OS save support from AVX.
Eric Christopher5db9d662016-06-02 21:03:19 +0000829 Features["avx2"] = HasAVXSave && HasLeaf7 && ((EBX >> 5) & 1);
Craig Topper798a2602015-03-29 01:00:23 +0000830
Eric Christopher5db9d662016-06-02 21:03:19 +0000831 Features["fsgsbase"] = HasLeaf7 && ((EBX >> 0) & 1);
832 Features["sgx"] = HasLeaf7 && ((EBX >> 2) & 1);
833 Features["bmi"] = HasLeaf7 && ((EBX >> 3) & 1);
834 Features["hle"] = HasLeaf7 && ((EBX >> 4) & 1);
835 Features["bmi2"] = HasLeaf7 && ((EBX >> 8) & 1);
836 Features["invpcid"] = HasLeaf7 && ((EBX >> 10) & 1);
837 Features["rtm"] = HasLeaf7 && ((EBX >> 11) & 1);
838 Features["rdseed"] = HasLeaf7 && ((EBX >> 18) & 1);
839 Features["adx"] = HasLeaf7 && ((EBX >> 19) & 1);
840 Features["smap"] = HasLeaf7 && ((EBX >> 20) & 1);
841 Features["pcommit"] = HasLeaf7 && ((EBX >> 22) & 1);
Elena Demikhovsky29cde352016-01-24 10:41:28 +0000842 Features["clflushopt"] = HasLeaf7 && ((EBX >> 23) & 1);
Eric Christopher5db9d662016-06-02 21:03:19 +0000843 Features["clwb"] = HasLeaf7 && ((EBX >> 24) & 1);
844 Features["sha"] = HasLeaf7 && ((EBX >> 29) & 1);
Craig Topper798a2602015-03-29 01:00:23 +0000845
846 // AVX512 is only supported if the OS supports the context save for it.
Eric Christopher5db9d662016-06-02 21:03:19 +0000847 Features["avx512f"] = HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save;
Craig Topper798a2602015-03-29 01:00:23 +0000848 Features["avx512dq"] = HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save;
Elena Demikhovsky29cde352016-01-24 10:41:28 +0000849 Features["avx512ifma"] = HasLeaf7 && ((EBX >> 21) & 1) && HasAVX512Save;
Craig Topper798a2602015-03-29 01:00:23 +0000850 Features["avx512pf"] = HasLeaf7 && ((EBX >> 26) & 1) && HasAVX512Save;
851 Features["avx512er"] = HasLeaf7 && ((EBX >> 27) & 1) && HasAVX512Save;
852 Features["avx512cd"] = HasLeaf7 && ((EBX >> 28) & 1) && HasAVX512Save;
853 Features["avx512bw"] = HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save;
854 Features["avx512vl"] = HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save;
Elena Demikhovsky29cde352016-01-24 10:41:28 +0000855
856 Features["prefetchwt1"] = HasLeaf7 && (ECX & 1);
Eric Christopher5db9d662016-06-02 21:03:19 +0000857 Features["avx512vbmi"] = HasLeaf7 && ((ECX >> 1) & 1) && HasAVX512Save;
Elena Demikhovsky29cde352016-01-24 10:41:28 +0000858 // Enable protection keys
Eric Christopher5db9d662016-06-02 21:03:19 +0000859 Features["pku"] = HasLeaf7 && ((ECX >> 4) & 1);
Craig Topper798a2602015-03-29 01:00:23 +0000860
Amjad Aboud1db6d7a2015-10-12 11:47:46 +0000861 bool HasLeafD = MaxLevel >= 0xd &&
Eric Christopher5db9d662016-06-02 21:03:19 +0000862 !GetX86CpuIDAndInfoEx(0xd, 0x1, &EAX, &EBX, &ECX, &EDX);
Amjad Aboud1db6d7a2015-10-12 11:47:46 +0000863
Craig Topperb84b1262015-10-14 05:37:42 +0000864 // Only enable XSAVE if OS has enabled support for saving YMM state.
865 Features["xsaveopt"] = HasAVXSave && HasLeafD && ((EAX >> 0) & 1);
Eric Christopher5db9d662016-06-02 21:03:19 +0000866 Features["xsavec"] = HasAVXSave && HasLeafD && ((EAX >> 1) & 1);
867 Features["xsaves"] = HasAVXSave && HasLeafD && ((EAX >> 3) & 1);
Amjad Aboud1db6d7a2015-10-12 11:47:46 +0000868
Craig Topper798a2602015-03-29 01:00:23 +0000869 return true;
870}
871#elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__))
Hao Liu10be3b22012-12-13 02:40:20 +0000872bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
Hao Liu10be3b22012-12-13 02:40:20 +0000873 // Read 1024 bytes from /proc/cpuinfo, which should contain the Features line
874 // in all cases.
875 char buffer[1024];
Rafael Espindola97935a92014-12-17 02:32:44 +0000876 ssize_t CPUInfoSize = readCpuInfo(buffer, sizeof(buffer));
877 if (CPUInfoSize == -1)
878 return false;
Hao Liu10be3b22012-12-13 02:40:20 +0000879
880 StringRef Str(buffer, CPUInfoSize);
881
882 SmallVector<StringRef, 32> Lines;
883 Str.split(Lines, "\n");
884
Tobias Grosserbd9e5492013-06-11 21:45:01 +0000885 SmallVector<StringRef, 32> CPUFeatures;
886
887 // Look for the CPU features.
Hao Liu10be3b22012-12-13 02:40:20 +0000888 for (unsigned I = 0, E = Lines.size(); I != E; ++I)
Tobias Grosserbd9e5492013-06-11 21:45:01 +0000889 if (Lines[I].startswith("Features")) {
Chandler Carruthe4405e92015-09-10 06:12:31 +0000890 Lines[I].split(CPUFeatures, ' ');
Tobias Grosserbd9e5492013-06-11 21:45:01 +0000891 break;
Hao Liu10be3b22012-12-13 02:40:20 +0000892 }
893
Bradley Smith9288b212014-05-22 11:44:34 +0000894#if defined(__aarch64__)
895 // Keep track of which crypto features we have seen
Eric Christopher5db9d662016-06-02 21:03:19 +0000896 enum { CAP_AES = 0x1, CAP_PMULL = 0x2, CAP_SHA1 = 0x4, CAP_SHA2 = 0x8 };
Bradley Smith9288b212014-05-22 11:44:34 +0000897 uint32_t crypto = 0;
898#endif
899
Tobias Grosserbd9e5492013-06-11 21:45:01 +0000900 for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) {
901 StringRef LLVMFeatureStr = StringSwitch<StringRef>(CPUFeatures[I])
Bradley Smith9288b212014-05-22 11:44:34 +0000902#if defined(__aarch64__)
Eric Christopher5db9d662016-06-02 21:03:19 +0000903 .Case("asimd", "neon")
904 .Case("fp", "fp-armv8")
905 .Case("crc32", "crc")
Bradley Smith9288b212014-05-22 11:44:34 +0000906#else
Eric Christopher5db9d662016-06-02 21:03:19 +0000907 .Case("half", "fp16")
908 .Case("neon", "neon")
909 .Case("vfpv3", "vfp3")
910 .Case("vfpv3d16", "d16")
911 .Case("vfpv4", "vfp4")
912 .Case("idiva", "hwdiv-arm")
913 .Case("idivt", "hwdiv")
Bradley Smith9288b212014-05-22 11:44:34 +0000914#endif
Eric Christopher5db9d662016-06-02 21:03:19 +0000915 .Default("");
Tobias Grosserbd9e5492013-06-11 21:45:01 +0000916
Bradley Smith9288b212014-05-22 11:44:34 +0000917#if defined(__aarch64__)
Alp Tokerda0c7932014-05-31 21:26:28 +0000918 // We need to check crypto separately since we need all of the crypto
Bradley Smith9288b212014-05-22 11:44:34 +0000919 // extensions to enable the subtarget feature
920 if (CPUFeatures[I] == "aes")
Bradley Smith63c8b1b2014-05-23 10:14:13 +0000921 crypto |= CAP_AES;
Bradley Smith9288b212014-05-22 11:44:34 +0000922 else if (CPUFeatures[I] == "pmull")
Bradley Smith63c8b1b2014-05-23 10:14:13 +0000923 crypto |= CAP_PMULL;
Bradley Smith9288b212014-05-22 11:44:34 +0000924 else if (CPUFeatures[I] == "sha1")
Bradley Smith63c8b1b2014-05-23 10:14:13 +0000925 crypto |= CAP_SHA1;
Bradley Smith9288b212014-05-22 11:44:34 +0000926 else if (CPUFeatures[I] == "sha2")
Bradley Smith63c8b1b2014-05-23 10:14:13 +0000927 crypto |= CAP_SHA2;
Bradley Smith9288b212014-05-22 11:44:34 +0000928#endif
929
Tobias Grosserbd9e5492013-06-11 21:45:01 +0000930 if (LLVMFeatureStr != "")
David Blaikie5106ce72014-11-19 05:49:42 +0000931 Features[LLVMFeatureStr] = true;
Hao Liu10be3b22012-12-13 02:40:20 +0000932 }
933
Bradley Smith9288b212014-05-22 11:44:34 +0000934#if defined(__aarch64__)
935 // If we have all crypto bits we can add the feature
Bradley Smith63c8b1b2014-05-23 10:14:13 +0000936 if (crypto == (CAP_AES | CAP_PMULL | CAP_SHA1 | CAP_SHA2))
David Blaikie5106ce72014-11-19 05:49:42 +0000937 Features["crypto"] = true;
Bradley Smith9288b212014-05-22 11:44:34 +0000938#endif
939
Tobias Grosserbd9e5492013-06-11 21:45:01 +0000940 return true;
Hao Liu10be3b22012-12-13 02:40:20 +0000941}
942#else
Eric Christopher5db9d662016-06-02 21:03:19 +0000943bool sys::getHostCPUFeatures(StringMap<bool> &Features) { return false; }
Hao Liu10be3b22012-12-13 02:40:20 +0000944#endif
Peter Collingbournea51c6ed2013-01-16 17:27:22 +0000945
946std::string sys::getProcessTriple() {
Duncan Sandse2cd1392013-07-17 11:01:05 +0000947 Triple PT(Triple::normalize(LLVM_HOST_TRIPLE));
Peter Collingbournea51c6ed2013-01-16 17:27:22 +0000948
949 if (sizeof(void *) == 8 && PT.isArch32Bit())
950 PT = PT.get64BitArchVariant();
951 if (sizeof(void *) == 4 && PT.isArch64Bit())
952 PT = PT.get32BitArchVariant();
953
954 return PT.str();
955}