blob: d4ab8c1efd40220c5d7d6d1bcf3fd4d43b13e11f [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
Alina Sbirlea400eb022016-06-03 20:27:50 +000076/// getX86CpuIDAndInfo - Execute the specified cpuid and return the 4 values in
Eric Christopherd9804bb2016-06-02 21:09:17 +000077/// the specified arguments. If we can't run cpuid on the host, return true.
Alina Sbirlea400eb022016-06-03 20:27:50 +000078static bool getX86CpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX,
Duncan P. N. Exon Smith91d3cfe2016-04-05 20:45:04 +000079 unsigned *rECX, unsigned *rEDX) {
Reid Klecknerbf4f9eb2013-08-16 22:42:42 +000080#if defined(__GNUC__) || defined(__clang__)
Eric Christopher5db9d662016-06-02 21:03:19 +000081#if defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
82 // gcc doesn't know cpuid would clobber ebx/rbx. Preseve it manually.
83 asm("movq\t%%rbx, %%rsi\n\t"
84 "cpuid\n\t"
85 "xchgq\t%%rbx, %%rsi\n\t"
86 : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
87 : "a"(value));
88 return false;
89#elif defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)
90 asm("movl\t%%ebx, %%esi\n\t"
91 "cpuid\n\t"
92 "xchgl\t%%ebx, %%esi\n\t"
93 : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
94 : "a"(value));
95 return false;
David Blaikieb48ed1a2012-01-17 04:43:56 +000096// pedantic #else returns to appease -Wunreachable-code (so we don't generate
97// postprocessed code that looks like "return true; return false;")
Eric Christopher5db9d662016-06-02 21:03:19 +000098#else
99 return true;
100#endif
Reid Klecknerbf4f9eb2013-08-16 22:42:42 +0000101#elif defined(_MSC_VER)
102 // The MSVC intrinsic is portable across x86 and x64.
103 int registers[4];
104 __cpuid(registers, value);
105 *rEAX = registers[0];
106 *rEBX = registers[1];
107 *rECX = registers[2];
108 *rEDX = registers[3];
109 return false;
David Blaikieb48ed1a2012-01-17 04:43:56 +0000110#else
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000111 return true;
David Blaikieb48ed1a2012-01-17 04:43:56 +0000112#endif
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000113}
114
Alina Sbirlea400eb022016-06-03 20:27:50 +0000115/// getX86CpuIDAndInfoEx - Execute the specified cpuid with subleaf and return
116/// the 4 values in the specified arguments. If we can't run cpuid on the host,
Tim Northover89ccb612013-11-25 09:52:59 +0000117/// return true.
Alina Sbirlea400eb022016-06-03 20:27:50 +0000118static bool getX86CpuIDAndInfoEx(unsigned value, unsigned subleaf,
Duncan P. N. Exon Smith91d3cfe2016-04-05 20:45:04 +0000119 unsigned *rEAX, unsigned *rEBX, unsigned *rECX,
120 unsigned *rEDX) {
Eric Christopher5db9d662016-06-02 21:03:19 +0000121#if defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
122#if defined(__GNUC__)
123 // gcc doesn't know cpuid would clobber ebx/rbx. Preseve it manually.
124 asm("movq\t%%rbx, %%rsi\n\t"
125 "cpuid\n\t"
126 "xchgq\t%%rbx, %%rsi\n\t"
127 : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
128 : "a"(value), "c"(subleaf));
129 return false;
130#elif defined(_MSC_VER)
131 int registers[4];
132 __cpuidex(registers, value, subleaf);
133 *rEAX = registers[0];
134 *rEBX = registers[1];
135 *rECX = registers[2];
136 *rEDX = registers[3];
137 return false;
138#else
139 return true;
140#endif
Tim Northover89ccb612013-11-25 09:52:59 +0000141#elif defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)
Eric Christopher5db9d662016-06-02 21:03:19 +0000142#if defined(__GNUC__)
143 asm("movl\t%%ebx, %%esi\n\t"
144 "cpuid\n\t"
145 "xchgl\t%%ebx, %%esi\n\t"
146 : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
147 : "a"(value), "c"(subleaf));
148 return false;
149#elif defined(_MSC_VER)
150 __asm {
Tim Northover89ccb612013-11-25 09:52:59 +0000151 mov eax,value
152 mov ecx,subleaf
153 cpuid
154 mov esi,rEAX
155 mov dword ptr [esi],eax
156 mov esi,rEBX
157 mov dword ptr [esi],ebx
158 mov esi,rECX
159 mov dword ptr [esi],ecx
160 mov esi,rEDX
161 mov dword ptr [esi],edx
Eric Christopher5db9d662016-06-02 21:03:19 +0000162 }
163 return false;
164#else
165 return true;
166#endif
Tim Northover89ccb612013-11-25 09:52:59 +0000167#else
168 return true;
169#endif
170}
171
Alina Sbirlea400eb022016-06-03 20:27:50 +0000172static bool getX86XCR0(unsigned *rEAX, unsigned *rEDX) {
Craig Topper7af39d72013-04-22 05:38:01 +0000173#if defined(__GNUC__)
174 // Check xgetbv; this uses a .byte sequence instead of the instruction
175 // directly because older assemblers do not include support for xgetbv and
176 // there is no easy way to conditionally compile based on the assembler used.
Eric Christopher5db9d662016-06-02 21:03:19 +0000177 __asm__(".byte 0x0f, 0x01, 0xd0" : "=a"(*rEAX), "=d"(*rEDX) : "c"(0));
Craig Topper798a2602015-03-29 01:00:23 +0000178 return false;
Aaron Ballman31c0adc2013-04-23 17:38:44 +0000179#elif defined(_MSC_FULL_VER) && defined(_XCR_XFEATURE_ENABLED_MASK)
Craig Topper798a2602015-03-29 01:00:23 +0000180 unsigned long long Result = _xgetbv(_XCR_XFEATURE_ENABLED_MASK);
Craig Topper7db49fd2015-03-29 01:07:57 +0000181 *rEAX = Result;
182 *rEDX = Result >> 32;
Craig Topper798a2602015-03-29 01:00:23 +0000183 return false;
Craig Topper7af39d72013-04-22 05:38:01 +0000184#else
Craig Topper798a2602015-03-29 01:00:23 +0000185 return true;
Craig Topper7af39d72013-04-22 05:38:01 +0000186#endif
Aaron Ballman5f7c6802013-04-03 12:25:06 +0000187}
188
Alina Sbirlea400eb022016-06-03 20:27:50 +0000189static void detectX86FamilyModel(unsigned EAX, unsigned *Family,
190 unsigned *Model) {
191 *Family = (EAX >> 8) & 0xf; // Bits 8 - 11
192 *Model = (EAX >> 4) & 0xf; // Bits 4 - 7
193 if (*Family == 6 || *Family == 0xf) {
194 if (*Family == 0xf)
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000195 // Examine extended family ID if family ID is F.
Alina Sbirlea400eb022016-06-03 20:27:50 +0000196 *Family += (EAX >> 20) & 0xff; // Bits 20 - 27
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000197 // Examine extended model ID if family ID is 6 or F.
Alina Sbirlea400eb022016-06-03 20:27:50 +0000198 *Model += ((EAX >> 16) & 0xf) << 4; // Bits 16 - 19
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000199 }
200}
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000201
Rafael Espindola74f444c2013-12-12 15:45:32 +0000202StringRef sys::getHostCPUName() {
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000203 unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
Alina Sbirlea400eb022016-06-03 20:27:50 +0000204 if (getX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX))
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000205 return "generic";
206 unsigned Family = 0;
Eric Christopher5db9d662016-06-02 21:03:19 +0000207 unsigned Model = 0;
Alina Sbirlea400eb022016-06-03 20:27:50 +0000208 detectX86FamilyModel(EAX, &Family, &Model);
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000209
Tim Northover89ccb612013-11-25 09:52:59 +0000210 union {
211 unsigned u[3];
Eric Christopher5db9d662016-06-02 21:03:19 +0000212 char c[12];
Tim Northover89ccb612013-11-25 09:52:59 +0000213 } text;
214
Craig Topper1214bdc2015-03-31 05:42:45 +0000215 unsigned MaxLeaf;
Alina Sbirlea400eb022016-06-03 20:27:50 +0000216 getX86CpuIDAndInfo(0, &MaxLeaf, text.u + 0, text.u + 2, text.u + 1);
Tim Northover89ccb612013-11-25 09:52:59 +0000217
Eric Christopher5db9d662016-06-02 21:03:19 +0000218 bool HasMMX = (EDX >> 23) & 1;
219 bool HasSSE = (EDX >> 25) & 1;
220 bool HasSSE2 = (EDX >> 26) & 1;
221 bool HasSSE3 = (ECX >> 0) & 1;
222 bool HasSSSE3 = (ECX >> 9) & 1;
Craig Topper1214bdc2015-03-31 05:42:45 +0000223 bool HasSSE41 = (ECX >> 19) & 1;
224 bool HasSSE42 = (ECX >> 20) & 1;
225 bool HasMOVBE = (ECX >> 22) & 1;
226 // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV
Aaron Ballman5f7c6802013-04-03 12:25:06 +0000227 // indicates that the AVX registers will be saved and restored on context
228 // switch, then we have full AVX support.
Aaron Ballman5e6d2052013-04-03 18:00:22 +0000229 const unsigned AVXBits = (1 << 27) | (1 << 28);
Alina Sbirlea400eb022016-06-03 20:27:50 +0000230 bool HasAVX = ((ECX & AVXBits) == AVXBits) && !getX86XCR0(&EAX, &EDX) &&
Craig Topper798a2602015-03-29 01:00:23 +0000231 ((EAX & 0x6) == 0x6);
Craig Topper1214bdc2015-03-31 05:42:45 +0000232 bool HasAVX512Save = HasAVX && ((EAX & 0xe0) == 0xe0);
Eric Christopher5db9d662016-06-02 21:03:19 +0000233 bool HasLeaf7 =
Alina Sbirlea400eb022016-06-03 20:27:50 +0000234 MaxLeaf >= 0x7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
Craig Topper1214bdc2015-03-31 05:42:45 +0000235 bool HasADX = HasLeaf7 && ((EBX >> 19) & 1);
236 bool HasAVX2 = HasAVX && HasLeaf7 && (EBX & 0x20);
237 bool HasAVX512 = HasLeaf7 && HasAVX512Save && ((EBX >> 16) & 1);
238
Alina Sbirlea400eb022016-06-03 20:27:50 +0000239 getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000240 bool Em64T = (EDX >> 29) & 0x1;
Kaelyn Takataa39d2a02014-05-05 16:32:10 +0000241 bool HasTBM = (ECX >> 21) & 0x1;
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000242
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000243 if (memcmp(text.c, "GenuineIntel", 12) == 0) {
244 switch (Family) {
Daniel Dunbar397235f2009-11-14 21:36:19 +0000245 case 3:
246 return "i386";
247 case 4:
248 switch (Model) {
NAKAMURA Takumi19e11f12010-09-09 13:30:48 +0000249 case 0: // Intel486 DX processors
250 case 1: // Intel486 DX processors
Daniel Dunbar397235f2009-11-14 21:36:19 +0000251 case 2: // Intel486 SX processors
NAKAMURA Takumi19e11f12010-09-09 13:30:48 +0000252 case 3: // Intel487 processors, IntelDX2 OverDrive processors,
253 // IntelDX2 processors
Daniel Dunbar397235f2009-11-14 21:36:19 +0000254 case 4: // Intel486 SL processor
NAKAMURA Takumi19e11f12010-09-09 13:30:48 +0000255 case 5: // IntelSX2 processors
Daniel Dunbar397235f2009-11-14 21:36:19 +0000256 case 7: // Write-Back Enhanced IntelDX2 processors
NAKAMURA Takumi19e11f12010-09-09 13:30:48 +0000257 case 8: // IntelDX4 OverDrive processors, IntelDX4 processors
Eric Christopher5db9d662016-06-02 21:03:19 +0000258 default:
259 return "i486";
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000260 }
Daniel Dunbar397235f2009-11-14 21:36:19 +0000261 case 5:
262 switch (Model) {
Eric Christopher5db9d662016-06-02 21:03:19 +0000263 case 1: // Pentium OverDrive processor for Pentium processor (60, 66),
264 // Pentium processors (60, 66)
265 case 2: // Pentium OverDrive processor for Pentium processor (75, 90,
266 // 100, 120, 133), Pentium processors (75, 90, 100, 120, 133,
267 // 150, 166, 200)
268 case 3: // Pentium OverDrive processors for Intel486 processor-based
269 // systems
Daniel Dunbar397235f2009-11-14 21:36:19 +0000270 return "pentium";
271
Eric Christopher5db9d662016-06-02 21:03:19 +0000272 case 4: // Pentium OverDrive processor with MMX technology for Pentium
273 // processor (75, 90, 100, 120, 133), Pentium processor with
274 // MMX technology (166, 200)
Daniel Dunbar397235f2009-11-14 21:36:19 +0000275 return "pentium-mmx";
276
Eric Christopher5db9d662016-06-02 21:03:19 +0000277 default:
278 return "pentium";
Daniel Dunbar397235f2009-11-14 21:36:19 +0000279 }
280 case 6:
281 switch (Model) {
Craig Toppere7d743c2016-04-27 05:16:58 +0000282 case 0x01: // Pentium Pro processor
Daniel Dunbar397235f2009-11-14 21:36:19 +0000283 return "pentiumpro";
284
Craig Toppere7d743c2016-04-27 05:16:58 +0000285 case 0x03: // Intel Pentium II OverDrive processor, Pentium II processor,
286 // model 03
287 case 0x05: // Pentium II processor, model 05, Pentium II Xeon processor,
288 // model 05, and Intel Celeron processor, model 05
289 case 0x06: // Celeron processor, model 06
Daniel Dunbar397235f2009-11-14 21:36:19 +0000290 return "pentium2";
291
Craig Toppere7d743c2016-04-27 05:16:58 +0000292 case 0x07: // Pentium III processor, model 07, and Pentium III Xeon
293 // processor, model 07
294 case 0x08: // Pentium III processor, model 08, Pentium III Xeon processor,
295 // model 08, and Celeron processor, model 08
296 case 0x0a: // Pentium III Xeon processor, model 0Ah
297 case 0x0b: // Pentium III processor, model 0Bh
Daniel Dunbar397235f2009-11-14 21:36:19 +0000298 return "pentium3";
299
Eric Christopher5db9d662016-06-02 21:03:19 +0000300 case 0x09: // Intel Pentium M processor, Intel Celeron M processor model
301 // 09.
Craig Toppere7d743c2016-04-27 05:16:58 +0000302 case 0x0d: // Intel Pentium M processor, Intel Celeron M processor, model
Eric Christopherb820edd2016-06-02 21:32:30 +0000303 // 0Dh. All processors are manufactured using the 90 nm
304 // process.
Craig Toppere7d743c2016-04-27 05:16:58 +0000305 case 0x15: // Intel EP80579 Integrated Processor and Intel EP80579
306 // Integrated Processor with Intel QuickAssist Technology
Daniel Dunbar397235f2009-11-14 21:36:19 +0000307 return "pentium-m";
308
Craig Toppere7d743c2016-04-27 05:16:58 +0000309 case 0x0e: // Intel Core Duo processor, Intel Core Solo processor, model
Eric Christopherb820edd2016-06-02 21:32:30 +0000310 // 0Eh. All processors are manufactured using the 65 nm
311 // 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 Christopherb820edd2016-06-02 21:32:30 +0000318 // 0Fh. All processors are manufactured using the 65 nm
319 // process.
Craig Toppere7d743c2016-04-27 05:16:58 +0000320 case 0x16: // Intel Celeron processor model 16h. All processors are
321 // manufactured using the 65 nm process
Daniel Dunbar397235f2009-11-14 21:36:19 +0000322 return "core2";
323
Craig Toppere7d743c2016-04-27 05:16:58 +0000324 case 0x17: // Intel Core 2 Extreme processor, Intel Xeon processor, model
Eric Christopherb820edd2016-06-02 21:32:30 +0000325 // 17h. All processors are manufactured using the 45 nm
326 // process.
Eric Christopherd9804bb2016-06-02 21:09:17 +0000327 //
328 // 45nm: Penryn , Wolfdale, Yorkfield (XE)
Eric Christopher5db9d662016-06-02 21:03:19 +0000329 case 0x1d: // Intel Xeon processor MP. All processors are manufactured
330 // using
Craig Toppere7d743c2016-04-27 05:16:58 +0000331 // the 45 nm process.
Craig Topper545b9512015-03-31 06:18:31 +0000332 return "penryn";
Daniel Dunbar397235f2009-11-14 21:36:19 +0000333
Craig Toppere7d743c2016-04-27 05:16:58 +0000334 case 0x1a: // Intel Core i7 processor and Intel Xeon processor. All
335 // processors are manufactured using the 45 nm process.
336 case 0x1e: // Intel(R) Core(TM) i7 CPU 870 @ 2.93GHz.
337 // As found in a Summer 2010 model iMac.
338 case 0x2e: // Nehalem EX
Craig Topper3c2e7582015-03-30 06:31:09 +0000339 return "nehalem";
Craig Toppere7d743c2016-04-27 05:16:58 +0000340 case 0x25: // Intel Core i7, laptop version.
341 case 0x2c: // Intel Core i7 processor and Intel Xeon processor. All
342 // processors are manufactured using the 32 nm process.
343 case 0x2f: // Westmere EX
Craig Topper3c2e7582015-03-30 06:31:09 +0000344 return "westmere";
Bob Wilsond0f06002011-07-08 22:33:59 +0000345
Craig Toppere7d743c2016-04-27 05:16:58 +0000346 case 0x2a: // Intel Core i7 processor. All processors are manufactured
347 // using the 32 nm process.
348 case 0x2d:
Craig Topper545b9512015-03-31 06:18:31 +0000349 return "sandybridge";
Daniel Dunbar397235f2009-11-14 21:36:19 +0000350
Craig Toppere7d743c2016-04-27 05:16:58 +0000351 case 0x3a:
352 case 0x3e: // Ivy Bridge EP
Craig Topper545b9512015-03-31 06:18:31 +0000353 return "ivybridge";
Evan Cheng7fd16072012-04-23 22:41:39 +0000354
Tim Northover89ccb612013-11-25 09:52:59 +0000355 // Haswell:
Craig Toppere7d743c2016-04-27 05:16:58 +0000356 case 0x3c:
357 case 0x3f:
358 case 0x45:
359 case 0x46:
Craig Topper545b9512015-03-31 06:18:31 +0000360 return "haswell";
Tim Northover89ccb612013-11-25 09:52:59 +0000361
Craig Topper1e1b0f72015-03-23 00:15:06 +0000362 // Broadwell:
Craig Toppere7d743c2016-04-27 05:16:58 +0000363 case 0x3d:
364 case 0x47:
365 case 0x4f:
366 case 0x56:
Craig Topper545b9512015-03-31 06:18:31 +0000367 return "broadwell";
Craig Topper1e1b0f72015-03-23 00:15:06 +0000368
Craig Topper68ba18f2015-08-08 01:29:15 +0000369 // Skylake:
Craig Toppere7d743c2016-04-27 05:16:58 +0000370 case 0x4e:
Sanjoy Dasaa63dc02016-02-21 17:12:03 +0000371 return "skylake-avx512";
Craig Toppere7d743c2016-04-27 05:16:58 +0000372 case 0x5e:
Craig Topper68ba18f2015-08-08 01:29:15 +0000373 return "skylake";
374
Craig Toppere7d743c2016-04-27 05:16:58 +0000375 case 0x1c: // Most 45 nm Intel Atom processors
376 case 0x26: // 45 nm Atom Lincroft
377 case 0x27: // 32 nm Atom Medfield
378 case 0x35: // 32 nm Atom Midview
379 case 0x36: // 32 nm Atom Midview
Craig Topper3c2e7582015-03-30 06:31:09 +0000380 return "bonnell";
Daniel Dunbar397235f2009-11-14 21:36:19 +0000381
Preston Gurd3fe264d2013-09-13 19:23:28 +0000382 // Atom Silvermont codes from the Intel software optimization guide.
Craig Toppere7d743c2016-04-27 05:16:58 +0000383 case 0x37:
384 case 0x4a:
385 case 0x4d:
386 case 0x5a:
387 case 0x5d:
Craig Topperde4318b2016-04-27 05:17:00 +0000388 case 0x4c: // really airmont
Craig Topper3c2e7582015-03-30 06:31:09 +0000389 return "silvermont";
Benjamin Kramer8f429382013-08-30 14:05:32 +0000390
Craig Topperde4318b2016-04-27 05:17:00 +0000391 case 0x57:
392 return "knl";
393
Craig Topper1214bdc2015-03-31 05:42:45 +0000394 default: // Unknown family 6 CPU, try to guess.
395 if (HasAVX512)
396 return "knl";
397 if (HasADX)
398 return "broadwell";
399 if (HasAVX2)
400 return "haswell";
401 if (HasAVX)
402 return "sandybridge";
403 if (HasSSE42)
404 return HasMOVBE ? "silvermont" : "nehalem";
405 if (HasSSE41)
406 return "penryn";
407 if (HasSSSE3)
408 return HasMOVBE ? "bonnell" : "core2";
409 if (Em64T)
410 return "x86-64";
411 if (HasSSE2)
412 return "pentium-m";
413 if (HasSSE)
414 return "pentium3";
415 if (HasMMX)
416 return "pentium2";
417 return "pentiumpro";
Daniel Dunbar397235f2009-11-14 21:36:19 +0000418 }
419 case 15: {
420 switch (Model) {
Eric Christopher5db9d662016-06-02 21:03:19 +0000421 case 0: // Pentium 4 processor, Intel Xeon processor. All processors are
422 // model 00h and manufactured using the 0.18 micron process.
423 case 1: // Pentium 4 processor, Intel Xeon processor, Intel Xeon
424 // processor MP, and Intel Celeron processor. All processors are
425 // model 01h and manufactured using the 0.18 micron process.
426 case 2: // Pentium 4 processor, Mobile Intel Pentium 4 processor - M,
427 // Intel Xeon processor, Intel Xeon processor MP, Intel Celeron
428 // processor, and Mobile Intel Celeron processor. All processors
429 // are model 02h and manufactured using the 0.13 micron process.
Daniel Dunbar397235f2009-11-14 21:36:19 +0000430 return (Em64T) ? "x86-64" : "pentium4";
431
Eric Christopher5db9d662016-06-02 21:03:19 +0000432 case 3: // Pentium 4 processor, Intel Xeon processor, Intel Celeron D
433 // processor. All processors are model 03h and manufactured using
434 // the 90 nm process.
435 case 4: // Pentium 4 processor, Pentium 4 processor Extreme Edition,
436 // Pentium D processor, Intel Xeon processor, Intel Xeon
437 // processor MP, Intel Celeron D processor. All processors are
438 // model 04h and manufactured using the 90 nm process.
439 case 6: // Pentium 4 processor, Pentium D processor, Pentium processor
440 // Extreme Edition, Intel Xeon processor, Intel Xeon processor
441 // MP, Intel Celeron D processor. All processors are model 06h
442 // and manufactured using the 65 nm process.
Daniel Dunbar397235f2009-11-14 21:36:19 +0000443 return (Em64T) ? "nocona" : "prescott";
444
Daniel Dunbar397235f2009-11-14 21:36:19 +0000445 default:
446 return (Em64T) ? "x86-64" : "pentium4";
447 }
448 }
449
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000450 default:
Benjamin Kramer713fd352009-11-17 17:57:04 +0000451 return "generic";
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000452 }
453 } else if (memcmp(text.c, "AuthenticAMD", 12) == 0) {
454 // FIXME: this poorly matches the generated SubtargetFeatureKV table. There
455 // appears to be no way to generate the wide variety of AMD-specific targets
456 // from the information returned from CPUID.
457 switch (Family) {
Eric Christopher5db9d662016-06-02 21:03:19 +0000458 case 4:
459 return "i486";
460 case 5:
461 switch (Model) {
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000462 case 6:
Eric Christopher5db9d662016-06-02 21:03:19 +0000463 case 7:
464 return "k6";
465 case 8:
466 return "k6-2";
467 case 9:
468 case 13:
469 return "k6-3";
470 case 10:
471 return "geode";
472 default:
473 return "pentium";
474 }
475 case 6:
476 switch (Model) {
477 case 4:
478 return "athlon-tbird";
479 case 6:
480 case 7:
481 case 8:
482 return "athlon-mp";
483 case 10:
484 return "athlon-xp";
485 default:
486 return "athlon";
487 }
488 case 15:
489 if (HasSSE3)
490 return "k8-sse3";
491 switch (Model) {
492 case 1:
493 return "opteron";
494 case 5:
495 return "athlon-fx"; // also opteron
496 default:
497 return "athlon64";
498 }
499 case 16:
500 return "amdfam10";
501 case 20:
502 return "btver1";
503 case 21:
504 if (!HasAVX) // If the OS doesn't support AVX provide a sane fallback.
Benjamin Kramer077ae1d2012-01-10 11:50:02 +0000505 return "btver1";
Eric Christopher5db9d662016-06-02 21:03:19 +0000506 if (Model >= 0x50)
507 return "bdver4"; // 50h-6Fh: Excavator
508 if (Model >= 0x30)
509 return "bdver3"; // 30h-3Fh: Steamroller
510 if (Model >= 0x10 || HasTBM)
511 return "bdver2"; // 10h-1Fh: Piledriver
512 return "bdver1"; // 00h-0Fh: Bulldozer
513 case 22:
514 if (!HasAVX) // If the OS doesn't support AVX provide a sane fallback.
515 return "btver1";
516 return "btver2";
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000517 default:
Benjamin Kramer713fd352009-11-17 17:57:04 +0000518 return "generic";
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000519 }
Daniel Dunbar241d01b2009-11-14 10:09:12 +0000520 }
Torok Edwin022336a2009-12-14 12:38:18 +0000521 return "generic";
Torok Edwinabdc1c22009-12-13 08:59:40 +0000522}
Hal Finkel59b0ee82012-06-12 03:03:13 +0000523#elif defined(__APPLE__) && (defined(__ppc__) || defined(__powerpc__))
Rafael Espindola1f58e4d2013-12-12 16:10:48 +0000524StringRef sys::getHostCPUName() {
Hal Finkel59b0ee82012-06-12 03:03:13 +0000525 host_basic_info_data_t hostInfo;
526 mach_msg_type_number_t infoCount;
527
528 infoCount = HOST_BASIC_INFO_COUNT;
Eric Christopher5db9d662016-06-02 21:03:19 +0000529 host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostInfo,
Hal Finkel59b0ee82012-06-12 03:03:13 +0000530 &infoCount);
Hal Finkel59b0ee82012-06-12 03:03:13 +0000531
Eric Christopher5db9d662016-06-02 21:03:19 +0000532 if (hostInfo.cpu_type != CPU_TYPE_POWERPC)
533 return "generic";
534
535 switch (hostInfo.cpu_subtype) {
536 case CPU_SUBTYPE_POWERPC_601:
537 return "601";
538 case CPU_SUBTYPE_POWERPC_602:
539 return "602";
540 case CPU_SUBTYPE_POWERPC_603:
541 return "603";
542 case CPU_SUBTYPE_POWERPC_603e:
543 return "603e";
544 case CPU_SUBTYPE_POWERPC_603ev:
545 return "603ev";
546 case CPU_SUBTYPE_POWERPC_604:
547 return "604";
548 case CPU_SUBTYPE_POWERPC_604e:
549 return "604e";
550 case CPU_SUBTYPE_POWERPC_620:
551 return "620";
552 case CPU_SUBTYPE_POWERPC_750:
553 return "750";
554 case CPU_SUBTYPE_POWERPC_7400:
555 return "7400";
556 case CPU_SUBTYPE_POWERPC_7450:
557 return "7450";
558 case CPU_SUBTYPE_POWERPC_970:
559 return "970";
560 default:;
Hal Finkel59b0ee82012-06-12 03:03:13 +0000561 }
Eric Christopher5db9d662016-06-02 21:03:19 +0000562
Hal Finkel59b0ee82012-06-12 03:03:13 +0000563 return "generic";
564}
565#elif defined(__linux__) && (defined(__ppc__) || defined(__powerpc__))
Rafael Espindolab75ea012013-12-12 16:17:40 +0000566StringRef sys::getHostCPUName() {
Hal Finkel59b0ee82012-06-12 03:03:13 +0000567 // Access to the Processor Version Register (PVR) on PowerPC is privileged,
568 // and so we must use an operating-system interface to determine the current
569 // processor type. On Linux, this is exposed through the /proc/cpuinfo file.
570 const char *generic = "generic";
571
Hal Finkel59b0ee82012-06-12 03:03:13 +0000572 // The cpu line is second (after the 'processor: 0' line), so if this
573 // buffer is too small then something has changed (or is wrong).
574 char buffer[1024];
Rafael Espindola97935a92014-12-17 02:32:44 +0000575 ssize_t CPUInfoSize = readCpuInfo(buffer, sizeof(buffer));
576 if (CPUInfoSize == -1)
577 return generic;
Hal Finkel59b0ee82012-06-12 03:03:13 +0000578
579 const char *CPUInfoStart = buffer;
580 const char *CPUInfoEnd = buffer + CPUInfoSize;
581
582 const char *CIP = CPUInfoStart;
583
584 const char *CPUStart = 0;
585 size_t CPULen = 0;
586
587 // We need to find the first line which starts with cpu, spaces, and a colon.
588 // After the colon, there may be some additional spaces and then the cpu type.
589 while (CIP < CPUInfoEnd && CPUStart == 0) {
590 if (CIP < CPUInfoEnd && *CIP == '\n')
591 ++CIP;
592
593 if (CIP < CPUInfoEnd && *CIP == 'c') {
594 ++CIP;
595 if (CIP < CPUInfoEnd && *CIP == 'p') {
596 ++CIP;
597 if (CIP < CPUInfoEnd && *CIP == 'u') {
598 ++CIP;
599 while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t'))
600 ++CIP;
Eric Christopher5db9d662016-06-02 21:03:19 +0000601
Hal Finkel59b0ee82012-06-12 03:03:13 +0000602 if (CIP < CPUInfoEnd && *CIP == ':') {
603 ++CIP;
604 while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t'))
605 ++CIP;
Eric Christopher5db9d662016-06-02 21:03:19 +0000606
Hal Finkel59b0ee82012-06-12 03:03:13 +0000607 if (CIP < CPUInfoEnd) {
608 CPUStart = CIP;
609 while (CIP < CPUInfoEnd && (*CIP != ' ' && *CIP != '\t' &&
610 *CIP != ',' && *CIP != '\n'))
611 ++CIP;
612 CPULen = CIP - CPUStart;
613 }
614 }
615 }
616 }
617 }
618
619 if (CPUStart == 0)
620 while (CIP < CPUInfoEnd && *CIP != '\n')
621 ++CIP;
622 }
623
624 if (CPUStart == 0)
625 return generic;
626
627 return StringSwitch<const char *>(StringRef(CPUStart, CPULen))
Eric Christopher5db9d662016-06-02 21:03:19 +0000628 .Case("604e", "604e")
629 .Case("604", "604")
630 .Case("7400", "7400")
631 .Case("7410", "7400")
632 .Case("7447", "7400")
633 .Case("7455", "7450")
634 .Case("G4", "g4")
635 .Case("POWER4", "970")
636 .Case("PPC970FX", "970")
637 .Case("PPC970MP", "970")
638 .Case("G5", "g5")
639 .Case("POWER5", "g5")
640 .Case("A2", "a2")
641 .Case("POWER6", "pwr6")
642 .Case("POWER7", "pwr7")
643 .Case("POWER8", "pwr8")
644 .Case("POWER8E", "pwr8")
645 .Case("POWER9", "pwr9")
646 .Default(generic);
Hal Finkel59b0ee82012-06-12 03:03:13 +0000647}
Benjamin Kramerefe40282012-06-26 21:36:32 +0000648#elif defined(__linux__) && defined(__arm__)
Rafael Espindola1f58e4d2013-12-12 16:10:48 +0000649StringRef sys::getHostCPUName() {
Benjamin Kramerefe40282012-06-26 21:36:32 +0000650 // The cpuid register on arm is not accessible from user space. On Linux,
651 // it is exposed through the /proc/cpuinfo file.
Benjamin Kramerefe40282012-06-26 21:36:32 +0000652
653 // Read 1024 bytes from /proc/cpuinfo, which should contain the CPU part line
654 // in all cases.
655 char buffer[1024];
Rafael Espindola97935a92014-12-17 02:32:44 +0000656 ssize_t CPUInfoSize = readCpuInfo(buffer, sizeof(buffer));
657 if (CPUInfoSize == -1)
658 return "generic";
Benjamin Kramerefe40282012-06-26 21:36:32 +0000659
660 StringRef Str(buffer, CPUInfoSize);
661
662 SmallVector<StringRef, 32> Lines;
663 Str.split(Lines, "\n");
664
665 // Look for the CPU implementer line.
666 StringRef Implementer;
667 for (unsigned I = 0, E = Lines.size(); I != E; ++I)
668 if (Lines[I].startswith("CPU implementer"))
669 Implementer = Lines[I].substr(15).ltrim("\t :");
670
671 if (Implementer == "0x41") // ARM Ltd.
672 // Look for the CPU part line.
673 for (unsigned I = 0, E = Lines.size(); I != E; ++I)
674 if (Lines[I].startswith("CPU part"))
675 // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The
676 // values correspond to the "Part number" in the CP15/c0 register. The
677 // contents are specified in the various processor manuals.
678 return StringSwitch<const char *>(Lines[I].substr(8).ltrim("\t :"))
Eric Christopher5db9d662016-06-02 21:03:19 +0000679 .Case("0x926", "arm926ej-s")
680 .Case("0xb02", "mpcore")
681 .Case("0xb36", "arm1136j-s")
682 .Case("0xb56", "arm1156t2-s")
683 .Case("0xb76", "arm1176jz-s")
684 .Case("0xc08", "cortex-a8")
685 .Case("0xc09", "cortex-a9")
686 .Case("0xc0f", "cortex-a15")
687 .Case("0xc20", "cortex-m0")
688 .Case("0xc23", "cortex-m3")
689 .Case("0xc24", "cortex-m4")
690 .Default("generic");
Benjamin Kramerefe40282012-06-26 21:36:32 +0000691
Kai Nackeb38bf962013-12-20 09:24:13 +0000692 if (Implementer == "0x51") // Qualcomm Technologies, Inc.
693 // Look for the CPU part line.
694 for (unsigned I = 0, E = Lines.size(); I != E; ++I)
695 if (Lines[I].startswith("CPU part"))
696 // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The
697 // values correspond to the "Part number" in the CP15/c0 register. The
698 // contents are specified in the various processor manuals.
699 return StringSwitch<const char *>(Lines[I].substr(8).ltrim("\t :"))
Eric Christopher5db9d662016-06-02 21:03:19 +0000700 .Case("0x06f", "krait") // APQ8064
701 .Default("generic");
Kai Nackeb38bf962013-12-20 09:24:13 +0000702
Benjamin Kramerefe40282012-06-26 21:36:32 +0000703 return "generic";
704}
Richard Sandifordf834ea12013-10-31 12:14:17 +0000705#elif defined(__linux__) && defined(__s390x__)
Rafael Espindola1f58e4d2013-12-12 16:10:48 +0000706StringRef sys::getHostCPUName() {
Richard Sandifordf834ea12013-10-31 12:14:17 +0000707 // STIDP is a privileged operation, so use /proc/cpuinfo instead.
Richard Sandifordf834ea12013-10-31 12:14:17 +0000708
709 // The "processor 0:" line comes after a fair amount of other information,
710 // including a cache breakdown, but this should be plenty.
711 char buffer[2048];
Rafael Espindola97935a92014-12-17 02:32:44 +0000712 ssize_t CPUInfoSize = readCpuInfo(buffer, sizeof(buffer));
713 if (CPUInfoSize == -1)
714 return "generic";
Richard Sandifordf834ea12013-10-31 12:14:17 +0000715
716 StringRef Str(buffer, CPUInfoSize);
717 SmallVector<StringRef, 32> Lines;
718 Str.split(Lines, "\n");
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000719
720 // Look for the CPU features.
721 SmallVector<StringRef, 32> CPUFeatures;
722 for (unsigned I = 0, E = Lines.size(); I != E; ++I)
723 if (Lines[I].startswith("features")) {
724 size_t Pos = Lines[I].find(":");
725 if (Pos != StringRef::npos) {
Chandler Carruthe4405e92015-09-10 06:12:31 +0000726 Lines[I].drop_front(Pos + 1).split(CPUFeatures, ' ');
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000727 break;
728 }
729 }
730
731 // We need to check for the presence of vector support independently of
732 // the machine type, since we may only use the vector register set when
733 // supported by the kernel (and hypervisor).
734 bool HaveVectorSupport = false;
735 for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) {
736 if (CPUFeatures[I] == "vx")
737 HaveVectorSupport = true;
738 }
739
740 // Now check the processor machine type.
Richard Sandifordf834ea12013-10-31 12:14:17 +0000741 for (unsigned I = 0, E = Lines.size(); I != E; ++I) {
742 if (Lines[I].startswith("processor ")) {
743 size_t Pos = Lines[I].find("machine = ");
744 if (Pos != StringRef::npos) {
745 Pos += sizeof("machine = ") - 1;
746 unsigned int Id;
747 if (!Lines[I].drop_front(Pos).getAsInteger(10, Id)) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000748 if (Id >= 2964 && HaveVectorSupport)
749 return "z13";
Richard Sandifordf834ea12013-10-31 12:14:17 +0000750 if (Id >= 2827)
751 return "zEC12";
752 if (Id >= 2817)
753 return "z196";
754 }
755 }
756 break;
757 }
758 }
Eric Christopher5db9d662016-06-02 21:03:19 +0000759
Richard Sandifordf834ea12013-10-31 12:14:17 +0000760 return "generic";
761}
Torok Edwinabdc1c22009-12-13 08:59:40 +0000762#else
Eric Christopher5db9d662016-06-02 21:03:19 +0000763StringRef sys::getHostCPUName() { return "generic"; }
Torok Edwinabdc1c22009-12-13 08:59:40 +0000764#endif
Xerxes Ranby17dc3a02010-01-19 21:26:05 +0000765
Eric Christopher5db9d662016-06-02 21:03:19 +0000766#if defined(i386) || defined(__i386__) || defined(__x86__) || \
767 defined(_M_IX86) || defined(__x86_64__) || defined(_M_AMD64) || \
768 defined(_M_X64)
Craig Topper798a2602015-03-29 01:00:23 +0000769bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
770 unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
771 unsigned MaxLevel;
772 union {
773 unsigned u[3];
Eric Christopher5db9d662016-06-02 21:03:19 +0000774 char c[12];
Craig Topper798a2602015-03-29 01:00:23 +0000775 } text;
776
Alina Sbirlea400eb022016-06-03 20:27:50 +0000777 if (getX86CpuIDAndInfo(0, &MaxLevel, text.u + 0, text.u + 2, text.u + 1) ||
Craig Topper798a2602015-03-29 01:00:23 +0000778 MaxLevel < 1)
779 return false;
780
Alina Sbirlea400eb022016-06-03 20:27:50 +0000781 getX86CpuIDAndInfo(1, &EAX, &EBX, &ECX, &EDX);
Craig Topper798a2602015-03-29 01:00:23 +0000782
Eric Christopher5db9d662016-06-02 21:03:19 +0000783 Features["cmov"] = (EDX >> 15) & 1;
784 Features["mmx"] = (EDX >> 23) & 1;
785 Features["sse"] = (EDX >> 25) & 1;
786 Features["sse2"] = (EDX >> 26) & 1;
787 Features["sse3"] = (ECX >> 0) & 1;
788 Features["ssse3"] = (ECX >> 9) & 1;
Craig Topper798a2602015-03-29 01:00:23 +0000789 Features["sse4.1"] = (ECX >> 19) & 1;
790 Features["sse4.2"] = (ECX >> 20) & 1;
791
Eric Christopher5db9d662016-06-02 21:03:19 +0000792 Features["pclmul"] = (ECX >> 1) & 1;
793 Features["cx16"] = (ECX >> 13) & 1;
794 Features["movbe"] = (ECX >> 22) & 1;
Craig Topper798a2602015-03-29 01:00:23 +0000795 Features["popcnt"] = (ECX >> 23) & 1;
Eric Christopher5db9d662016-06-02 21:03:19 +0000796 Features["aes"] = (ECX >> 25) & 1;
797 Features["rdrnd"] = (ECX >> 30) & 1;
Craig Topper798a2602015-03-29 01:00:23 +0000798
799 // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV
800 // indicates that the AVX registers will be saved and restored on context
801 // switch, then we have full AVX support.
Craig Topperb84b1262015-10-14 05:37:42 +0000802 bool HasAVXSave = ((ECX >> 27) & 1) && ((ECX >> 28) & 1) &&
Alina Sbirlea400eb022016-06-03 20:27:50 +0000803 !getX86XCR0(&EAX, &EDX) && ((EAX & 0x6) == 0x6);
Eric Christopher5db9d662016-06-02 21:03:19 +0000804 Features["avx"] = HasAVXSave;
805 Features["fma"] = HasAVXSave && (ECX >> 12) & 1;
806 Features["f16c"] = HasAVXSave && (ECX >> 29) & 1;
Craig Topperb84b1262015-10-14 05:37:42 +0000807
808 // Only enable XSAVE if OS has enabled support for saving YMM state.
Eric Christopher5db9d662016-06-02 21:03:19 +0000809 Features["xsave"] = HasAVXSave && (ECX >> 26) & 1;
Craig Topper798a2602015-03-29 01:00:23 +0000810
811 // AVX512 requires additional context to be saved by the OS.
Craig Topperb84b1262015-10-14 05:37:42 +0000812 bool HasAVX512Save = HasAVXSave && ((EAX & 0xe0) == 0xe0);
Craig Topper798a2602015-03-29 01:00:23 +0000813
814 unsigned MaxExtLevel;
Alina Sbirlea400eb022016-06-03 20:27:50 +0000815 getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX);
Craig Topper798a2602015-03-29 01:00:23 +0000816
817 bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 &&
Alina Sbirlea400eb022016-06-03 20:27:50 +0000818 !getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
Eric Christopher5db9d662016-06-02 21:03:19 +0000819 Features["lzcnt"] = HasExtLeaf1 && ((ECX >> 5) & 1);
820 Features["sse4a"] = HasExtLeaf1 && ((ECX >> 6) & 1);
821 Features["prfchw"] = HasExtLeaf1 && ((ECX >> 8) & 1);
822 Features["xop"] = HasExtLeaf1 && ((ECX >> 11) & 1) && HasAVXSave;
823 Features["fma4"] = HasExtLeaf1 && ((ECX >> 16) & 1) && HasAVXSave;
824 Features["tbm"] = HasExtLeaf1 && ((ECX >> 21) & 1);
Ashutosh Nema348af9c2016-05-18 11:59:12 +0000825 Features["mwaitx"] = HasExtLeaf1 && ((ECX >> 29) & 1);
Craig Topper798a2602015-03-29 01:00:23 +0000826
Eric Christopher5db9d662016-06-02 21:03:19 +0000827 bool HasLeaf7 =
Alina Sbirlea400eb022016-06-03 20:27:50 +0000828 MaxLevel >= 7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
Craig Topper798a2602015-03-29 01:00:23 +0000829
830 // AVX2 is only supported if we have the OS save support from AVX.
Eric Christopher5db9d662016-06-02 21:03:19 +0000831 Features["avx2"] = HasAVXSave && HasLeaf7 && ((EBX >> 5) & 1);
Craig Topper798a2602015-03-29 01:00:23 +0000832
Eric Christopher5db9d662016-06-02 21:03:19 +0000833 Features["fsgsbase"] = HasLeaf7 && ((EBX >> 0) & 1);
834 Features["sgx"] = HasLeaf7 && ((EBX >> 2) & 1);
835 Features["bmi"] = HasLeaf7 && ((EBX >> 3) & 1);
836 Features["hle"] = HasLeaf7 && ((EBX >> 4) & 1);
837 Features["bmi2"] = HasLeaf7 && ((EBX >> 8) & 1);
838 Features["invpcid"] = HasLeaf7 && ((EBX >> 10) & 1);
839 Features["rtm"] = HasLeaf7 && ((EBX >> 11) & 1);
840 Features["rdseed"] = HasLeaf7 && ((EBX >> 18) & 1);
841 Features["adx"] = HasLeaf7 && ((EBX >> 19) & 1);
842 Features["smap"] = HasLeaf7 && ((EBX >> 20) & 1);
843 Features["pcommit"] = HasLeaf7 && ((EBX >> 22) & 1);
Elena Demikhovsky29cde352016-01-24 10:41:28 +0000844 Features["clflushopt"] = HasLeaf7 && ((EBX >> 23) & 1);
Eric Christopher5db9d662016-06-02 21:03:19 +0000845 Features["clwb"] = HasLeaf7 && ((EBX >> 24) & 1);
846 Features["sha"] = HasLeaf7 && ((EBX >> 29) & 1);
Craig Topper798a2602015-03-29 01:00:23 +0000847
848 // AVX512 is only supported if the OS supports the context save for it.
Eric Christopher5db9d662016-06-02 21:03:19 +0000849 Features["avx512f"] = HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save;
Craig Topper798a2602015-03-29 01:00:23 +0000850 Features["avx512dq"] = HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save;
Elena Demikhovsky29cde352016-01-24 10:41:28 +0000851 Features["avx512ifma"] = HasLeaf7 && ((EBX >> 21) & 1) && HasAVX512Save;
Craig Topper798a2602015-03-29 01:00:23 +0000852 Features["avx512pf"] = HasLeaf7 && ((EBX >> 26) & 1) && HasAVX512Save;
853 Features["avx512er"] = HasLeaf7 && ((EBX >> 27) & 1) && HasAVX512Save;
854 Features["avx512cd"] = HasLeaf7 && ((EBX >> 28) & 1) && HasAVX512Save;
855 Features["avx512bw"] = HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save;
856 Features["avx512vl"] = HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save;
Elena Demikhovsky29cde352016-01-24 10:41:28 +0000857
858 Features["prefetchwt1"] = HasLeaf7 && (ECX & 1);
Eric Christopher5db9d662016-06-02 21:03:19 +0000859 Features["avx512vbmi"] = HasLeaf7 && ((ECX >> 1) & 1) && HasAVX512Save;
Elena Demikhovsky29cde352016-01-24 10:41:28 +0000860 // Enable protection keys
Eric Christopher5db9d662016-06-02 21:03:19 +0000861 Features["pku"] = HasLeaf7 && ((ECX >> 4) & 1);
Craig Topper798a2602015-03-29 01:00:23 +0000862
Amjad Aboud1db6d7a2015-10-12 11:47:46 +0000863 bool HasLeafD = MaxLevel >= 0xd &&
Alina Sbirlea400eb022016-06-03 20:27:50 +0000864 !getX86CpuIDAndInfoEx(0xd, 0x1, &EAX, &EBX, &ECX, &EDX);
Amjad Aboud1db6d7a2015-10-12 11:47:46 +0000865
Craig Topperb84b1262015-10-14 05:37:42 +0000866 // Only enable XSAVE if OS has enabled support for saving YMM state.
867 Features["xsaveopt"] = HasAVXSave && HasLeafD && ((EAX >> 0) & 1);
Eric Christopher5db9d662016-06-02 21:03:19 +0000868 Features["xsavec"] = HasAVXSave && HasLeafD && ((EAX >> 1) & 1);
869 Features["xsaves"] = HasAVXSave && HasLeafD && ((EAX >> 3) & 1);
Amjad Aboud1db6d7a2015-10-12 11:47:46 +0000870
Craig Topper798a2602015-03-29 01:00:23 +0000871 return true;
872}
873#elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__))
Hao Liu10be3b22012-12-13 02:40:20 +0000874bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
Hao Liu10be3b22012-12-13 02:40:20 +0000875 // Read 1024 bytes from /proc/cpuinfo, which should contain the Features line
876 // in all cases.
877 char buffer[1024];
Rafael Espindola97935a92014-12-17 02:32:44 +0000878 ssize_t CPUInfoSize = readCpuInfo(buffer, sizeof(buffer));
879 if (CPUInfoSize == -1)
880 return false;
Hao Liu10be3b22012-12-13 02:40:20 +0000881
882 StringRef Str(buffer, CPUInfoSize);
883
884 SmallVector<StringRef, 32> Lines;
885 Str.split(Lines, "\n");
886
Tobias Grosserbd9e5492013-06-11 21:45:01 +0000887 SmallVector<StringRef, 32> CPUFeatures;
888
889 // Look for the CPU features.
Hao Liu10be3b22012-12-13 02:40:20 +0000890 for (unsigned I = 0, E = Lines.size(); I != E; ++I)
Tobias Grosserbd9e5492013-06-11 21:45:01 +0000891 if (Lines[I].startswith("Features")) {
Chandler Carruthe4405e92015-09-10 06:12:31 +0000892 Lines[I].split(CPUFeatures, ' ');
Tobias Grosserbd9e5492013-06-11 21:45:01 +0000893 break;
Hao Liu10be3b22012-12-13 02:40:20 +0000894 }
895
Bradley Smith9288b212014-05-22 11:44:34 +0000896#if defined(__aarch64__)
897 // Keep track of which crypto features we have seen
Eric Christopher5db9d662016-06-02 21:03:19 +0000898 enum { CAP_AES = 0x1, CAP_PMULL = 0x2, CAP_SHA1 = 0x4, CAP_SHA2 = 0x8 };
Bradley Smith9288b212014-05-22 11:44:34 +0000899 uint32_t crypto = 0;
900#endif
901
Tobias Grosserbd9e5492013-06-11 21:45:01 +0000902 for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) {
903 StringRef LLVMFeatureStr = StringSwitch<StringRef>(CPUFeatures[I])
Bradley Smith9288b212014-05-22 11:44:34 +0000904#if defined(__aarch64__)
Eric Christopher5db9d662016-06-02 21:03:19 +0000905 .Case("asimd", "neon")
906 .Case("fp", "fp-armv8")
907 .Case("crc32", "crc")
Bradley Smith9288b212014-05-22 11:44:34 +0000908#else
Eric Christopher5db9d662016-06-02 21:03:19 +0000909 .Case("half", "fp16")
910 .Case("neon", "neon")
911 .Case("vfpv3", "vfp3")
912 .Case("vfpv3d16", "d16")
913 .Case("vfpv4", "vfp4")
914 .Case("idiva", "hwdiv-arm")
915 .Case("idivt", "hwdiv")
Bradley Smith9288b212014-05-22 11:44:34 +0000916#endif
Eric Christopher5db9d662016-06-02 21:03:19 +0000917 .Default("");
Tobias Grosserbd9e5492013-06-11 21:45:01 +0000918
Bradley Smith9288b212014-05-22 11:44:34 +0000919#if defined(__aarch64__)
Alp Tokerda0c7932014-05-31 21:26:28 +0000920 // We need to check crypto separately since we need all of the crypto
Bradley Smith9288b212014-05-22 11:44:34 +0000921 // extensions to enable the subtarget feature
922 if (CPUFeatures[I] == "aes")
Bradley Smith63c8b1b2014-05-23 10:14:13 +0000923 crypto |= CAP_AES;
Bradley Smith9288b212014-05-22 11:44:34 +0000924 else if (CPUFeatures[I] == "pmull")
Bradley Smith63c8b1b2014-05-23 10:14:13 +0000925 crypto |= CAP_PMULL;
Bradley Smith9288b212014-05-22 11:44:34 +0000926 else if (CPUFeatures[I] == "sha1")
Bradley Smith63c8b1b2014-05-23 10:14:13 +0000927 crypto |= CAP_SHA1;
Bradley Smith9288b212014-05-22 11:44:34 +0000928 else if (CPUFeatures[I] == "sha2")
Bradley Smith63c8b1b2014-05-23 10:14:13 +0000929 crypto |= CAP_SHA2;
Bradley Smith9288b212014-05-22 11:44:34 +0000930#endif
931
Tobias Grosserbd9e5492013-06-11 21:45:01 +0000932 if (LLVMFeatureStr != "")
David Blaikie5106ce72014-11-19 05:49:42 +0000933 Features[LLVMFeatureStr] = true;
Hao Liu10be3b22012-12-13 02:40:20 +0000934 }
935
Bradley Smith9288b212014-05-22 11:44:34 +0000936#if defined(__aarch64__)
937 // If we have all crypto bits we can add the feature
Bradley Smith63c8b1b2014-05-23 10:14:13 +0000938 if (crypto == (CAP_AES | CAP_PMULL | CAP_SHA1 | CAP_SHA2))
David Blaikie5106ce72014-11-19 05:49:42 +0000939 Features["crypto"] = true;
Bradley Smith9288b212014-05-22 11:44:34 +0000940#endif
941
Tobias Grosserbd9e5492013-06-11 21:45:01 +0000942 return true;
Hao Liu10be3b22012-12-13 02:40:20 +0000943}
944#else
Eric Christopher5db9d662016-06-02 21:03:19 +0000945bool sys::getHostCPUFeatures(StringMap<bool> &Features) { return false; }
Hao Liu10be3b22012-12-13 02:40:20 +0000946#endif
Peter Collingbournea51c6ed2013-01-16 17:27:22 +0000947
948std::string sys::getProcessTriple() {
Duncan Sandse2cd1392013-07-17 11:01:05 +0000949 Triple PT(Triple::normalize(LLVM_HOST_TRIPLE));
Peter Collingbournea51c6ed2013-01-16 17:27:22 +0000950
951 if (sizeof(void *) == 8 && PT.isArch32Bit())
952 PT = PT.get64BitArchVariant();
953 if (sizeof(void *) == 4 && PT.isArch64Bit())
954 PT = PT.get32BitArchVariant();
955
956 return PT.str();
957}