1*9880d681SAndroid Build Coastguard Worker //===-- Host.cpp - Implement OS Host Concept --------------------*- C++ -*-===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file implements the operating system Host concept.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Host.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallVector.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/StringRef.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/StringSwitch.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Triple.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/Config/config.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/FileSystem.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
23*9880d681SAndroid Build Coastguard Worker #include <string.h>
24*9880d681SAndroid Build Coastguard Worker
25*9880d681SAndroid Build Coastguard Worker // Include the platform-specific parts of this class.
26*9880d681SAndroid Build Coastguard Worker #ifdef LLVM_ON_UNIX
27*9880d681SAndroid Build Coastguard Worker #include "Unix/Host.inc"
28*9880d681SAndroid Build Coastguard Worker #endif
29*9880d681SAndroid Build Coastguard Worker #ifdef LLVM_ON_WIN32
30*9880d681SAndroid Build Coastguard Worker #include "Windows/Host.inc"
31*9880d681SAndroid Build Coastguard Worker #endif
32*9880d681SAndroid Build Coastguard Worker #ifdef _MSC_VER
33*9880d681SAndroid Build Coastguard Worker #include <intrin.h>
34*9880d681SAndroid Build Coastguard Worker #endif
35*9880d681SAndroid Build Coastguard Worker #if defined(__APPLE__) && (defined(__ppc__) || defined(__powerpc__))
36*9880d681SAndroid Build Coastguard Worker #include <mach/host_info.h>
37*9880d681SAndroid Build Coastguard Worker #include <mach/mach.h>
38*9880d681SAndroid Build Coastguard Worker #include <mach/mach_host.h>
39*9880d681SAndroid Build Coastguard Worker #include <mach/machine.h>
40*9880d681SAndroid Build Coastguard Worker #endif
41*9880d681SAndroid Build Coastguard Worker
42*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "host-detection"
43*9880d681SAndroid Build Coastguard Worker
44*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
45*9880d681SAndroid Build Coastguard Worker //
46*9880d681SAndroid Build Coastguard Worker // Implementations of the CPU detection routines
47*9880d681SAndroid Build Coastguard Worker //
48*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
49*9880d681SAndroid Build Coastguard Worker
50*9880d681SAndroid Build Coastguard Worker using namespace llvm;
51*9880d681SAndroid Build Coastguard Worker
52*9880d681SAndroid Build Coastguard Worker #if defined(__linux__)
readCpuInfo(void * Buf,size_t Size)53*9880d681SAndroid Build Coastguard Worker static ssize_t LLVM_ATTRIBUTE_UNUSED readCpuInfo(void *Buf, size_t Size) {
54*9880d681SAndroid Build Coastguard Worker // Note: We cannot mmap /proc/cpuinfo here and then process the resulting
55*9880d681SAndroid Build Coastguard Worker // memory buffer because the 'file' has 0 size (it can be read from only
56*9880d681SAndroid Build Coastguard Worker // as a stream).
57*9880d681SAndroid Build Coastguard Worker
58*9880d681SAndroid Build Coastguard Worker int FD;
59*9880d681SAndroid Build Coastguard Worker std::error_code EC = sys::fs::openFileForRead("/proc/cpuinfo", FD);
60*9880d681SAndroid Build Coastguard Worker if (EC) {
61*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "Unable to open /proc/cpuinfo: " << EC.message() << "\n");
62*9880d681SAndroid Build Coastguard Worker return -1;
63*9880d681SAndroid Build Coastguard Worker }
64*9880d681SAndroid Build Coastguard Worker int Ret = read(FD, Buf, Size);
65*9880d681SAndroid Build Coastguard Worker int CloseStatus = close(FD);
66*9880d681SAndroid Build Coastguard Worker if (CloseStatus)
67*9880d681SAndroid Build Coastguard Worker return -1;
68*9880d681SAndroid Build Coastguard Worker return Ret;
69*9880d681SAndroid Build Coastguard Worker }
70*9880d681SAndroid Build Coastguard Worker #endif
71*9880d681SAndroid Build Coastguard Worker
72*9880d681SAndroid Build Coastguard Worker #if defined(i386) || defined(__i386__) || defined(__x86__) || \
73*9880d681SAndroid Build Coastguard Worker defined(_M_IX86) || defined(__x86_64__) || defined(_M_AMD64) || \
74*9880d681SAndroid Build Coastguard Worker defined(_M_X64)
75*9880d681SAndroid Build Coastguard Worker
76*9880d681SAndroid Build Coastguard Worker enum VendorSignatures {
77*9880d681SAndroid Build Coastguard Worker SIG_INTEL = 0x756e6547 /* Genu */,
78*9880d681SAndroid Build Coastguard Worker SIG_AMD = 0x68747541 /* Auth */
79*9880d681SAndroid Build Coastguard Worker };
80*9880d681SAndroid Build Coastguard Worker
81*9880d681SAndroid Build Coastguard Worker enum ProcessorVendors {
82*9880d681SAndroid Build Coastguard Worker VENDOR_INTEL = 1,
83*9880d681SAndroid Build Coastguard Worker VENDOR_AMD,
84*9880d681SAndroid Build Coastguard Worker VENDOR_OTHER,
85*9880d681SAndroid Build Coastguard Worker VENDOR_MAX
86*9880d681SAndroid Build Coastguard Worker };
87*9880d681SAndroid Build Coastguard Worker
88*9880d681SAndroid Build Coastguard Worker enum ProcessorTypes {
89*9880d681SAndroid Build Coastguard Worker INTEL_ATOM = 1,
90*9880d681SAndroid Build Coastguard Worker INTEL_CORE2,
91*9880d681SAndroid Build Coastguard Worker INTEL_COREI7,
92*9880d681SAndroid Build Coastguard Worker AMDFAM10H,
93*9880d681SAndroid Build Coastguard Worker AMDFAM15H,
94*9880d681SAndroid Build Coastguard Worker INTEL_i386,
95*9880d681SAndroid Build Coastguard Worker INTEL_i486,
96*9880d681SAndroid Build Coastguard Worker INTEL_PENTIUM,
97*9880d681SAndroid Build Coastguard Worker INTEL_PENTIUM_PRO,
98*9880d681SAndroid Build Coastguard Worker INTEL_PENTIUM_II,
99*9880d681SAndroid Build Coastguard Worker INTEL_PENTIUM_III,
100*9880d681SAndroid Build Coastguard Worker INTEL_PENTIUM_IV,
101*9880d681SAndroid Build Coastguard Worker INTEL_PENTIUM_M,
102*9880d681SAndroid Build Coastguard Worker INTEL_CORE_DUO,
103*9880d681SAndroid Build Coastguard Worker INTEL_XEONPHI,
104*9880d681SAndroid Build Coastguard Worker INTEL_X86_64,
105*9880d681SAndroid Build Coastguard Worker INTEL_NOCONA,
106*9880d681SAndroid Build Coastguard Worker INTEL_PRESCOTT,
107*9880d681SAndroid Build Coastguard Worker AMD_i486,
108*9880d681SAndroid Build Coastguard Worker AMDPENTIUM,
109*9880d681SAndroid Build Coastguard Worker AMDATHLON,
110*9880d681SAndroid Build Coastguard Worker AMDFAM14H,
111*9880d681SAndroid Build Coastguard Worker AMDFAM16H,
112*9880d681SAndroid Build Coastguard Worker CPU_TYPE_MAX
113*9880d681SAndroid Build Coastguard Worker };
114*9880d681SAndroid Build Coastguard Worker
115*9880d681SAndroid Build Coastguard Worker enum ProcessorSubtypes {
116*9880d681SAndroid Build Coastguard Worker INTEL_COREI7_NEHALEM = 1,
117*9880d681SAndroid Build Coastguard Worker INTEL_COREI7_WESTMERE,
118*9880d681SAndroid Build Coastguard Worker INTEL_COREI7_SANDYBRIDGE,
119*9880d681SAndroid Build Coastguard Worker AMDFAM10H_BARCELONA,
120*9880d681SAndroid Build Coastguard Worker AMDFAM10H_SHANGHAI,
121*9880d681SAndroid Build Coastguard Worker AMDFAM10H_ISTANBUL,
122*9880d681SAndroid Build Coastguard Worker AMDFAM15H_BDVER1,
123*9880d681SAndroid Build Coastguard Worker AMDFAM15H_BDVER2,
124*9880d681SAndroid Build Coastguard Worker INTEL_PENTIUM_MMX,
125*9880d681SAndroid Build Coastguard Worker INTEL_CORE2_65,
126*9880d681SAndroid Build Coastguard Worker INTEL_CORE2_45,
127*9880d681SAndroid Build Coastguard Worker INTEL_COREI7_IVYBRIDGE,
128*9880d681SAndroid Build Coastguard Worker INTEL_COREI7_HASWELL,
129*9880d681SAndroid Build Coastguard Worker INTEL_COREI7_BROADWELL,
130*9880d681SAndroid Build Coastguard Worker INTEL_COREI7_SKYLAKE,
131*9880d681SAndroid Build Coastguard Worker INTEL_COREI7_SKYLAKE_AVX512,
132*9880d681SAndroid Build Coastguard Worker INTEL_ATOM_BONNELL,
133*9880d681SAndroid Build Coastguard Worker INTEL_ATOM_SILVERMONT,
134*9880d681SAndroid Build Coastguard Worker INTEL_KNIGHTS_LANDING,
135*9880d681SAndroid Build Coastguard Worker AMDPENTIUM_K6,
136*9880d681SAndroid Build Coastguard Worker AMDPENTIUM_K62,
137*9880d681SAndroid Build Coastguard Worker AMDPENTIUM_K63,
138*9880d681SAndroid Build Coastguard Worker AMDPENTIUM_GEODE,
139*9880d681SAndroid Build Coastguard Worker AMDATHLON_TBIRD,
140*9880d681SAndroid Build Coastguard Worker AMDATHLON_MP,
141*9880d681SAndroid Build Coastguard Worker AMDATHLON_XP,
142*9880d681SAndroid Build Coastguard Worker AMDATHLON_K8SSE3,
143*9880d681SAndroid Build Coastguard Worker AMDATHLON_OPTERON,
144*9880d681SAndroid Build Coastguard Worker AMDATHLON_FX,
145*9880d681SAndroid Build Coastguard Worker AMDATHLON_64,
146*9880d681SAndroid Build Coastguard Worker AMD_BTVER1,
147*9880d681SAndroid Build Coastguard Worker AMD_BTVER2,
148*9880d681SAndroid Build Coastguard Worker AMDFAM15H_BDVER3,
149*9880d681SAndroid Build Coastguard Worker AMDFAM15H_BDVER4,
150*9880d681SAndroid Build Coastguard Worker CPU_SUBTYPE_MAX
151*9880d681SAndroid Build Coastguard Worker };
152*9880d681SAndroid Build Coastguard Worker
153*9880d681SAndroid Build Coastguard Worker enum ProcessorFeatures {
154*9880d681SAndroid Build Coastguard Worker FEATURE_CMOV = 0,
155*9880d681SAndroid Build Coastguard Worker FEATURE_MMX,
156*9880d681SAndroid Build Coastguard Worker FEATURE_POPCNT,
157*9880d681SAndroid Build Coastguard Worker FEATURE_SSE,
158*9880d681SAndroid Build Coastguard Worker FEATURE_SSE2,
159*9880d681SAndroid Build Coastguard Worker FEATURE_SSE3,
160*9880d681SAndroid Build Coastguard Worker FEATURE_SSSE3,
161*9880d681SAndroid Build Coastguard Worker FEATURE_SSE4_1,
162*9880d681SAndroid Build Coastguard Worker FEATURE_SSE4_2,
163*9880d681SAndroid Build Coastguard Worker FEATURE_AVX,
164*9880d681SAndroid Build Coastguard Worker FEATURE_AVX2,
165*9880d681SAndroid Build Coastguard Worker FEATURE_AVX512,
166*9880d681SAndroid Build Coastguard Worker FEATURE_AVX512SAVE,
167*9880d681SAndroid Build Coastguard Worker FEATURE_MOVBE,
168*9880d681SAndroid Build Coastguard Worker FEATURE_ADX,
169*9880d681SAndroid Build Coastguard Worker FEATURE_EM64T
170*9880d681SAndroid Build Coastguard Worker };
171*9880d681SAndroid Build Coastguard Worker
172*9880d681SAndroid Build Coastguard Worker /// getX86CpuIDAndInfo - Execute the specified cpuid and return the 4 values in
173*9880d681SAndroid Build Coastguard Worker /// the specified arguments. If we can't run cpuid on the host, return true.
getX86CpuIDAndInfo(unsigned value,unsigned * rEAX,unsigned * rEBX,unsigned * rECX,unsigned * rEDX)174*9880d681SAndroid Build Coastguard Worker static bool getX86CpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX,
175*9880d681SAndroid Build Coastguard Worker unsigned *rECX, unsigned *rEDX) {
176*9880d681SAndroid Build Coastguard Worker #if defined(__GNUC__) || defined(__clang__)
177*9880d681SAndroid Build Coastguard Worker #if defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
178*9880d681SAndroid Build Coastguard Worker // gcc doesn't know cpuid would clobber ebx/rbx. Preseve it manually.
179*9880d681SAndroid Build Coastguard Worker asm("movq\t%%rbx, %%rsi\n\t"
180*9880d681SAndroid Build Coastguard Worker "cpuid\n\t"
181*9880d681SAndroid Build Coastguard Worker "xchgq\t%%rbx, %%rsi\n\t"
182*9880d681SAndroid Build Coastguard Worker : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
183*9880d681SAndroid Build Coastguard Worker : "a"(value));
184*9880d681SAndroid Build Coastguard Worker return false;
185*9880d681SAndroid Build Coastguard Worker #elif defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)
186*9880d681SAndroid Build Coastguard Worker asm("movl\t%%ebx, %%esi\n\t"
187*9880d681SAndroid Build Coastguard Worker "cpuid\n\t"
188*9880d681SAndroid Build Coastguard Worker "xchgl\t%%ebx, %%esi\n\t"
189*9880d681SAndroid Build Coastguard Worker : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
190*9880d681SAndroid Build Coastguard Worker : "a"(value));
191*9880d681SAndroid Build Coastguard Worker return false;
192*9880d681SAndroid Build Coastguard Worker // pedantic #else returns to appease -Wunreachable-code (so we don't generate
193*9880d681SAndroid Build Coastguard Worker // postprocessed code that looks like "return true; return false;")
194*9880d681SAndroid Build Coastguard Worker #else
195*9880d681SAndroid Build Coastguard Worker return true;
196*9880d681SAndroid Build Coastguard Worker #endif
197*9880d681SAndroid Build Coastguard Worker #elif defined(_MSC_VER)
198*9880d681SAndroid Build Coastguard Worker // The MSVC intrinsic is portable across x86 and x64.
199*9880d681SAndroid Build Coastguard Worker int registers[4];
200*9880d681SAndroid Build Coastguard Worker __cpuid(registers, value);
201*9880d681SAndroid Build Coastguard Worker *rEAX = registers[0];
202*9880d681SAndroid Build Coastguard Worker *rEBX = registers[1];
203*9880d681SAndroid Build Coastguard Worker *rECX = registers[2];
204*9880d681SAndroid Build Coastguard Worker *rEDX = registers[3];
205*9880d681SAndroid Build Coastguard Worker return false;
206*9880d681SAndroid Build Coastguard Worker #else
207*9880d681SAndroid Build Coastguard Worker return true;
208*9880d681SAndroid Build Coastguard Worker #endif
209*9880d681SAndroid Build Coastguard Worker }
210*9880d681SAndroid Build Coastguard Worker
211*9880d681SAndroid Build Coastguard Worker /// getX86CpuIDAndInfoEx - Execute the specified cpuid with subleaf and return
212*9880d681SAndroid Build Coastguard Worker /// the 4 values in the specified arguments. If we can't run cpuid on the host,
213*9880d681SAndroid Build Coastguard Worker /// return true.
getX86CpuIDAndInfoEx(unsigned value,unsigned subleaf,unsigned * rEAX,unsigned * rEBX,unsigned * rECX,unsigned * rEDX)214*9880d681SAndroid Build Coastguard Worker static bool getX86CpuIDAndInfoEx(unsigned value, unsigned subleaf,
215*9880d681SAndroid Build Coastguard Worker unsigned *rEAX, unsigned *rEBX, unsigned *rECX,
216*9880d681SAndroid Build Coastguard Worker unsigned *rEDX) {
217*9880d681SAndroid Build Coastguard Worker #if defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
218*9880d681SAndroid Build Coastguard Worker #if defined(__GNUC__)
219*9880d681SAndroid Build Coastguard Worker // gcc doesn't know cpuid would clobber ebx/rbx. Preseve it manually.
220*9880d681SAndroid Build Coastguard Worker asm("movq\t%%rbx, %%rsi\n\t"
221*9880d681SAndroid Build Coastguard Worker "cpuid\n\t"
222*9880d681SAndroid Build Coastguard Worker "xchgq\t%%rbx, %%rsi\n\t"
223*9880d681SAndroid Build Coastguard Worker : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
224*9880d681SAndroid Build Coastguard Worker : "a"(value), "c"(subleaf));
225*9880d681SAndroid Build Coastguard Worker return false;
226*9880d681SAndroid Build Coastguard Worker #elif defined(_MSC_VER)
227*9880d681SAndroid Build Coastguard Worker int registers[4];
228*9880d681SAndroid Build Coastguard Worker __cpuidex(registers, value, subleaf);
229*9880d681SAndroid Build Coastguard Worker *rEAX = registers[0];
230*9880d681SAndroid Build Coastguard Worker *rEBX = registers[1];
231*9880d681SAndroid Build Coastguard Worker *rECX = registers[2];
232*9880d681SAndroid Build Coastguard Worker *rEDX = registers[3];
233*9880d681SAndroid Build Coastguard Worker return false;
234*9880d681SAndroid Build Coastguard Worker #else
235*9880d681SAndroid Build Coastguard Worker return true;
236*9880d681SAndroid Build Coastguard Worker #endif
237*9880d681SAndroid Build Coastguard Worker #elif defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)
238*9880d681SAndroid Build Coastguard Worker #if defined(__GNUC__)
239*9880d681SAndroid Build Coastguard Worker asm("movl\t%%ebx, %%esi\n\t"
240*9880d681SAndroid Build Coastguard Worker "cpuid\n\t"
241*9880d681SAndroid Build Coastguard Worker "xchgl\t%%ebx, %%esi\n\t"
242*9880d681SAndroid Build Coastguard Worker : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
243*9880d681SAndroid Build Coastguard Worker : "a"(value), "c"(subleaf));
244*9880d681SAndroid Build Coastguard Worker return false;
245*9880d681SAndroid Build Coastguard Worker #elif defined(_MSC_VER)
246*9880d681SAndroid Build Coastguard Worker __asm {
247*9880d681SAndroid Build Coastguard Worker mov eax,value
248*9880d681SAndroid Build Coastguard Worker mov ecx,subleaf
249*9880d681SAndroid Build Coastguard Worker cpuid
250*9880d681SAndroid Build Coastguard Worker mov esi,rEAX
251*9880d681SAndroid Build Coastguard Worker mov dword ptr [esi],eax
252*9880d681SAndroid Build Coastguard Worker mov esi,rEBX
253*9880d681SAndroid Build Coastguard Worker mov dword ptr [esi],ebx
254*9880d681SAndroid Build Coastguard Worker mov esi,rECX
255*9880d681SAndroid Build Coastguard Worker mov dword ptr [esi],ecx
256*9880d681SAndroid Build Coastguard Worker mov esi,rEDX
257*9880d681SAndroid Build Coastguard Worker mov dword ptr [esi],edx
258*9880d681SAndroid Build Coastguard Worker }
259*9880d681SAndroid Build Coastguard Worker return false;
260*9880d681SAndroid Build Coastguard Worker #else
261*9880d681SAndroid Build Coastguard Worker return true;
262*9880d681SAndroid Build Coastguard Worker #endif
263*9880d681SAndroid Build Coastguard Worker #else
264*9880d681SAndroid Build Coastguard Worker return true;
265*9880d681SAndroid Build Coastguard Worker #endif
266*9880d681SAndroid Build Coastguard Worker }
267*9880d681SAndroid Build Coastguard Worker
getX86XCR0(unsigned * rEAX,unsigned * rEDX)268*9880d681SAndroid Build Coastguard Worker static bool getX86XCR0(unsigned *rEAX, unsigned *rEDX) {
269*9880d681SAndroid Build Coastguard Worker #if defined(__GNUC__)
270*9880d681SAndroid Build Coastguard Worker // Check xgetbv; this uses a .byte sequence instead of the instruction
271*9880d681SAndroid Build Coastguard Worker // directly because older assemblers do not include support for xgetbv and
272*9880d681SAndroid Build Coastguard Worker // there is no easy way to conditionally compile based on the assembler used.
273*9880d681SAndroid Build Coastguard Worker __asm__(".byte 0x0f, 0x01, 0xd0" : "=a"(*rEAX), "=d"(*rEDX) : "c"(0));
274*9880d681SAndroid Build Coastguard Worker return false;
275*9880d681SAndroid Build Coastguard Worker #elif defined(_MSC_FULL_VER) && defined(_XCR_XFEATURE_ENABLED_MASK)
276*9880d681SAndroid Build Coastguard Worker unsigned long long Result = _xgetbv(_XCR_XFEATURE_ENABLED_MASK);
277*9880d681SAndroid Build Coastguard Worker *rEAX = Result;
278*9880d681SAndroid Build Coastguard Worker *rEDX = Result >> 32;
279*9880d681SAndroid Build Coastguard Worker return false;
280*9880d681SAndroid Build Coastguard Worker #else
281*9880d681SAndroid Build Coastguard Worker return true;
282*9880d681SAndroid Build Coastguard Worker #endif
283*9880d681SAndroid Build Coastguard Worker }
284*9880d681SAndroid Build Coastguard Worker
detectX86FamilyModel(unsigned EAX,unsigned * Family,unsigned * Model)285*9880d681SAndroid Build Coastguard Worker static void detectX86FamilyModel(unsigned EAX, unsigned *Family,
286*9880d681SAndroid Build Coastguard Worker unsigned *Model) {
287*9880d681SAndroid Build Coastguard Worker *Family = (EAX >> 8) & 0xf; // Bits 8 - 11
288*9880d681SAndroid Build Coastguard Worker *Model = (EAX >> 4) & 0xf; // Bits 4 - 7
289*9880d681SAndroid Build Coastguard Worker if (*Family == 6 || *Family == 0xf) {
290*9880d681SAndroid Build Coastguard Worker if (*Family == 0xf)
291*9880d681SAndroid Build Coastguard Worker // Examine extended family ID if family ID is F.
292*9880d681SAndroid Build Coastguard Worker *Family += (EAX >> 20) & 0xff; // Bits 20 - 27
293*9880d681SAndroid Build Coastguard Worker // Examine extended model ID if family ID is 6 or F.
294*9880d681SAndroid Build Coastguard Worker *Model += ((EAX >> 16) & 0xf) << 4; // Bits 16 - 19
295*9880d681SAndroid Build Coastguard Worker }
296*9880d681SAndroid Build Coastguard Worker }
297*9880d681SAndroid Build Coastguard Worker
298*9880d681SAndroid Build Coastguard Worker static void
getIntelProcessorTypeAndSubtype(unsigned int Family,unsigned int Model,unsigned int Brand_id,unsigned int Features,unsigned * Type,unsigned * Subtype)299*9880d681SAndroid Build Coastguard Worker getIntelProcessorTypeAndSubtype(unsigned int Family, unsigned int Model,
300*9880d681SAndroid Build Coastguard Worker unsigned int Brand_id, unsigned int Features,
301*9880d681SAndroid Build Coastguard Worker unsigned *Type, unsigned *Subtype) {
302*9880d681SAndroid Build Coastguard Worker if (Brand_id != 0)
303*9880d681SAndroid Build Coastguard Worker return;
304*9880d681SAndroid Build Coastguard Worker switch (Family) {
305*9880d681SAndroid Build Coastguard Worker case 3:
306*9880d681SAndroid Build Coastguard Worker *Type = INTEL_i386;
307*9880d681SAndroid Build Coastguard Worker break;
308*9880d681SAndroid Build Coastguard Worker case 4:
309*9880d681SAndroid Build Coastguard Worker switch (Model) {
310*9880d681SAndroid Build Coastguard Worker case 0: // Intel486 DX processors
311*9880d681SAndroid Build Coastguard Worker case 1: // Intel486 DX processors
312*9880d681SAndroid Build Coastguard Worker case 2: // Intel486 SX processors
313*9880d681SAndroid Build Coastguard Worker case 3: // Intel487 processors, IntelDX2 OverDrive processors,
314*9880d681SAndroid Build Coastguard Worker // IntelDX2 processors
315*9880d681SAndroid Build Coastguard Worker case 4: // Intel486 SL processor
316*9880d681SAndroid Build Coastguard Worker case 5: // IntelSX2 processors
317*9880d681SAndroid Build Coastguard Worker case 7: // Write-Back Enhanced IntelDX2 processors
318*9880d681SAndroid Build Coastguard Worker case 8: // IntelDX4 OverDrive processors, IntelDX4 processors
319*9880d681SAndroid Build Coastguard Worker default:
320*9880d681SAndroid Build Coastguard Worker *Type = INTEL_i486;
321*9880d681SAndroid Build Coastguard Worker break;
322*9880d681SAndroid Build Coastguard Worker }
323*9880d681SAndroid Build Coastguard Worker break;
324*9880d681SAndroid Build Coastguard Worker case 5:
325*9880d681SAndroid Build Coastguard Worker switch (Model) {
326*9880d681SAndroid Build Coastguard Worker case 1: // Pentium OverDrive processor for Pentium processor (60, 66),
327*9880d681SAndroid Build Coastguard Worker // Pentium processors (60, 66)
328*9880d681SAndroid Build Coastguard Worker case 2: // Pentium OverDrive processor for Pentium processor (75, 90,
329*9880d681SAndroid Build Coastguard Worker // 100, 120, 133), Pentium processors (75, 90, 100, 120, 133,
330*9880d681SAndroid Build Coastguard Worker // 150, 166, 200)
331*9880d681SAndroid Build Coastguard Worker case 3: // Pentium OverDrive processors for Intel486 processor-based
332*9880d681SAndroid Build Coastguard Worker // systems
333*9880d681SAndroid Build Coastguard Worker *Type = INTEL_PENTIUM;
334*9880d681SAndroid Build Coastguard Worker break;
335*9880d681SAndroid Build Coastguard Worker case 4: // Pentium OverDrive processor with MMX technology for Pentium
336*9880d681SAndroid Build Coastguard Worker // processor (75, 90, 100, 120, 133), Pentium processor with
337*9880d681SAndroid Build Coastguard Worker // MMX technology (166, 200)
338*9880d681SAndroid Build Coastguard Worker *Type = INTEL_PENTIUM;
339*9880d681SAndroid Build Coastguard Worker *Subtype = INTEL_PENTIUM_MMX;
340*9880d681SAndroid Build Coastguard Worker break;
341*9880d681SAndroid Build Coastguard Worker default:
342*9880d681SAndroid Build Coastguard Worker *Type = INTEL_PENTIUM;
343*9880d681SAndroid Build Coastguard Worker break;
344*9880d681SAndroid Build Coastguard Worker }
345*9880d681SAndroid Build Coastguard Worker break;
346*9880d681SAndroid Build Coastguard Worker case 6:
347*9880d681SAndroid Build Coastguard Worker switch (Model) {
348*9880d681SAndroid Build Coastguard Worker case 0x01: // Pentium Pro processor
349*9880d681SAndroid Build Coastguard Worker *Type = INTEL_PENTIUM_PRO;
350*9880d681SAndroid Build Coastguard Worker break;
351*9880d681SAndroid Build Coastguard Worker case 0x03: // Intel Pentium II OverDrive processor, Pentium II processor,
352*9880d681SAndroid Build Coastguard Worker // model 03
353*9880d681SAndroid Build Coastguard Worker case 0x05: // Pentium II processor, model 05, Pentium II Xeon processor,
354*9880d681SAndroid Build Coastguard Worker // model 05, and Intel Celeron processor, model 05
355*9880d681SAndroid Build Coastguard Worker case 0x06: // Celeron processor, model 06
356*9880d681SAndroid Build Coastguard Worker *Type = INTEL_PENTIUM_II;
357*9880d681SAndroid Build Coastguard Worker break;
358*9880d681SAndroid Build Coastguard Worker case 0x07: // Pentium III processor, model 07, and Pentium III Xeon
359*9880d681SAndroid Build Coastguard Worker // processor, model 07
360*9880d681SAndroid Build Coastguard Worker case 0x08: // Pentium III processor, model 08, Pentium III Xeon processor,
361*9880d681SAndroid Build Coastguard Worker // model 08, and Celeron processor, model 08
362*9880d681SAndroid Build Coastguard Worker case 0x0a: // Pentium III Xeon processor, model 0Ah
363*9880d681SAndroid Build Coastguard Worker case 0x0b: // Pentium III processor, model 0Bh
364*9880d681SAndroid Build Coastguard Worker *Type = INTEL_PENTIUM_III;
365*9880d681SAndroid Build Coastguard Worker break;
366*9880d681SAndroid Build Coastguard Worker case 0x09: // Intel Pentium M processor, Intel Celeron M processor model 09.
367*9880d681SAndroid Build Coastguard Worker case 0x0d: // Intel Pentium M processor, Intel Celeron M processor, model
368*9880d681SAndroid Build Coastguard Worker // 0Dh. All processors are manufactured using the 90 nm process.
369*9880d681SAndroid Build Coastguard Worker case 0x15: // Intel EP80579 Integrated Processor and Intel EP80579
370*9880d681SAndroid Build Coastguard Worker // Integrated Processor with Intel QuickAssist Technology
371*9880d681SAndroid Build Coastguard Worker *Type = INTEL_PENTIUM_M;
372*9880d681SAndroid Build Coastguard Worker break;
373*9880d681SAndroid Build Coastguard Worker case 0x0e: // Intel Core Duo processor, Intel Core Solo processor, model
374*9880d681SAndroid Build Coastguard Worker // 0Eh. All processors are manufactured using the 65 nm process.
375*9880d681SAndroid Build Coastguard Worker *Type = INTEL_CORE_DUO;
376*9880d681SAndroid Build Coastguard Worker break; // yonah
377*9880d681SAndroid Build Coastguard Worker case 0x0f: // Intel Core 2 Duo processor, Intel Core 2 Duo mobile
378*9880d681SAndroid Build Coastguard Worker // processor, Intel Core 2 Quad processor, Intel Core 2 Quad
379*9880d681SAndroid Build Coastguard Worker // mobile processor, Intel Core 2 Extreme processor, Intel
380*9880d681SAndroid Build Coastguard Worker // Pentium Dual-Core processor, Intel Xeon processor, model
381*9880d681SAndroid Build Coastguard Worker // 0Fh. All processors are manufactured using the 65 nm process.
382*9880d681SAndroid Build Coastguard Worker case 0x16: // Intel Celeron processor model 16h. All processors are
383*9880d681SAndroid Build Coastguard Worker // manufactured using the 65 nm process
384*9880d681SAndroid Build Coastguard Worker *Type = INTEL_CORE2; // "core2"
385*9880d681SAndroid Build Coastguard Worker *Subtype = INTEL_CORE2_65;
386*9880d681SAndroid Build Coastguard Worker break;
387*9880d681SAndroid Build Coastguard Worker case 0x17: // Intel Core 2 Extreme processor, Intel Xeon processor, model
388*9880d681SAndroid Build Coastguard Worker // 17h. All processors are manufactured using the 45 nm process.
389*9880d681SAndroid Build Coastguard Worker //
390*9880d681SAndroid Build Coastguard Worker // 45nm: Penryn , Wolfdale, Yorkfield (XE)
391*9880d681SAndroid Build Coastguard Worker case 0x1d: // Intel Xeon processor MP. All processors are manufactured using
392*9880d681SAndroid Build Coastguard Worker // the 45 nm process.
393*9880d681SAndroid Build Coastguard Worker *Type = INTEL_CORE2; // "penryn"
394*9880d681SAndroid Build Coastguard Worker *Subtype = INTEL_CORE2_45;
395*9880d681SAndroid Build Coastguard Worker break;
396*9880d681SAndroid Build Coastguard Worker case 0x1a: // Intel Core i7 processor and Intel Xeon processor. All
397*9880d681SAndroid Build Coastguard Worker // processors are manufactured using the 45 nm process.
398*9880d681SAndroid Build Coastguard Worker case 0x1e: // Intel(R) Core(TM) i7 CPU 870 @ 2.93GHz.
399*9880d681SAndroid Build Coastguard Worker // As found in a Summer 2010 model iMac.
400*9880d681SAndroid Build Coastguard Worker case 0x1f:
401*9880d681SAndroid Build Coastguard Worker case 0x2e: // Nehalem EX
402*9880d681SAndroid Build Coastguard Worker *Type = INTEL_COREI7; // "nehalem"
403*9880d681SAndroid Build Coastguard Worker *Subtype = INTEL_COREI7_NEHALEM;
404*9880d681SAndroid Build Coastguard Worker break;
405*9880d681SAndroid Build Coastguard Worker case 0x25: // Intel Core i7, laptop version.
406*9880d681SAndroid Build Coastguard Worker case 0x2c: // Intel Core i7 processor and Intel Xeon processor. All
407*9880d681SAndroid Build Coastguard Worker // processors are manufactured using the 32 nm process.
408*9880d681SAndroid Build Coastguard Worker case 0x2f: // Westmere EX
409*9880d681SAndroid Build Coastguard Worker *Type = INTEL_COREI7; // "westmere"
410*9880d681SAndroid Build Coastguard Worker *Subtype = INTEL_COREI7_WESTMERE;
411*9880d681SAndroid Build Coastguard Worker break;
412*9880d681SAndroid Build Coastguard Worker case 0x2a: // Intel Core i7 processor. All processors are manufactured
413*9880d681SAndroid Build Coastguard Worker // using the 32 nm process.
414*9880d681SAndroid Build Coastguard Worker case 0x2d:
415*9880d681SAndroid Build Coastguard Worker *Type = INTEL_COREI7; //"sandybridge"
416*9880d681SAndroid Build Coastguard Worker *Subtype = INTEL_COREI7_SANDYBRIDGE;
417*9880d681SAndroid Build Coastguard Worker break;
418*9880d681SAndroid Build Coastguard Worker case 0x3a:
419*9880d681SAndroid Build Coastguard Worker case 0x3e: // Ivy Bridge EP
420*9880d681SAndroid Build Coastguard Worker *Type = INTEL_COREI7; // "ivybridge"
421*9880d681SAndroid Build Coastguard Worker *Subtype = INTEL_COREI7_IVYBRIDGE;
422*9880d681SAndroid Build Coastguard Worker break;
423*9880d681SAndroid Build Coastguard Worker
424*9880d681SAndroid Build Coastguard Worker // Haswell:
425*9880d681SAndroid Build Coastguard Worker case 0x3c:
426*9880d681SAndroid Build Coastguard Worker case 0x3f:
427*9880d681SAndroid Build Coastguard Worker case 0x45:
428*9880d681SAndroid Build Coastguard Worker case 0x46:
429*9880d681SAndroid Build Coastguard Worker *Type = INTEL_COREI7; // "haswell"
430*9880d681SAndroid Build Coastguard Worker *Subtype = INTEL_COREI7_HASWELL;
431*9880d681SAndroid Build Coastguard Worker break;
432*9880d681SAndroid Build Coastguard Worker
433*9880d681SAndroid Build Coastguard Worker // Broadwell:
434*9880d681SAndroid Build Coastguard Worker case 0x3d:
435*9880d681SAndroid Build Coastguard Worker case 0x47:
436*9880d681SAndroid Build Coastguard Worker case 0x4f:
437*9880d681SAndroid Build Coastguard Worker case 0x56:
438*9880d681SAndroid Build Coastguard Worker *Type = INTEL_COREI7; // "broadwell"
439*9880d681SAndroid Build Coastguard Worker *Subtype = INTEL_COREI7_BROADWELL;
440*9880d681SAndroid Build Coastguard Worker break;
441*9880d681SAndroid Build Coastguard Worker
442*9880d681SAndroid Build Coastguard Worker // Skylake:
443*9880d681SAndroid Build Coastguard Worker case 0x4e:
444*9880d681SAndroid Build Coastguard Worker *Type = INTEL_COREI7; // "skylake-avx512"
445*9880d681SAndroid Build Coastguard Worker *Subtype = INTEL_COREI7_SKYLAKE_AVX512;
446*9880d681SAndroid Build Coastguard Worker break;
447*9880d681SAndroid Build Coastguard Worker case 0x5e:
448*9880d681SAndroid Build Coastguard Worker *Type = INTEL_COREI7; // "skylake"
449*9880d681SAndroid Build Coastguard Worker *Subtype = INTEL_COREI7_SKYLAKE;
450*9880d681SAndroid Build Coastguard Worker break;
451*9880d681SAndroid Build Coastguard Worker
452*9880d681SAndroid Build Coastguard Worker case 0x1c: // Most 45 nm Intel Atom processors
453*9880d681SAndroid Build Coastguard Worker case 0x26: // 45 nm Atom Lincroft
454*9880d681SAndroid Build Coastguard Worker case 0x27: // 32 nm Atom Medfield
455*9880d681SAndroid Build Coastguard Worker case 0x35: // 32 nm Atom Midview
456*9880d681SAndroid Build Coastguard Worker case 0x36: // 32 nm Atom Midview
457*9880d681SAndroid Build Coastguard Worker *Type = INTEL_ATOM;
458*9880d681SAndroid Build Coastguard Worker *Subtype = INTEL_ATOM_BONNELL;
459*9880d681SAndroid Build Coastguard Worker break; // "bonnell"
460*9880d681SAndroid Build Coastguard Worker
461*9880d681SAndroid Build Coastguard Worker // Atom Silvermont codes from the Intel software optimization guide.
462*9880d681SAndroid Build Coastguard Worker case 0x37:
463*9880d681SAndroid Build Coastguard Worker case 0x4a:
464*9880d681SAndroid Build Coastguard Worker case 0x4d:
465*9880d681SAndroid Build Coastguard Worker case 0x5a:
466*9880d681SAndroid Build Coastguard Worker case 0x5d:
467*9880d681SAndroid Build Coastguard Worker case 0x4c: // really airmont
468*9880d681SAndroid Build Coastguard Worker *Type = INTEL_ATOM;
469*9880d681SAndroid Build Coastguard Worker *Subtype = INTEL_ATOM_SILVERMONT;
470*9880d681SAndroid Build Coastguard Worker break; // "silvermont"
471*9880d681SAndroid Build Coastguard Worker
472*9880d681SAndroid Build Coastguard Worker case 0x57:
473*9880d681SAndroid Build Coastguard Worker *Type = INTEL_XEONPHI; // knl
474*9880d681SAndroid Build Coastguard Worker *Subtype = INTEL_KNIGHTS_LANDING;
475*9880d681SAndroid Build Coastguard Worker break;
476*9880d681SAndroid Build Coastguard Worker
477*9880d681SAndroid Build Coastguard Worker default: // Unknown family 6 CPU, try to guess.
478*9880d681SAndroid Build Coastguard Worker if (Features & (1 << FEATURE_AVX512)) {
479*9880d681SAndroid Build Coastguard Worker *Type = INTEL_XEONPHI; // knl
480*9880d681SAndroid Build Coastguard Worker *Subtype = INTEL_KNIGHTS_LANDING;
481*9880d681SAndroid Build Coastguard Worker break;
482*9880d681SAndroid Build Coastguard Worker }
483*9880d681SAndroid Build Coastguard Worker if (Features & (1 << FEATURE_ADX)) {
484*9880d681SAndroid Build Coastguard Worker *Type = INTEL_COREI7;
485*9880d681SAndroid Build Coastguard Worker *Subtype = INTEL_COREI7_BROADWELL;
486*9880d681SAndroid Build Coastguard Worker break;
487*9880d681SAndroid Build Coastguard Worker }
488*9880d681SAndroid Build Coastguard Worker if (Features & (1 << FEATURE_AVX2)) {
489*9880d681SAndroid Build Coastguard Worker *Type = INTEL_COREI7;
490*9880d681SAndroid Build Coastguard Worker *Subtype = INTEL_COREI7_HASWELL;
491*9880d681SAndroid Build Coastguard Worker break;
492*9880d681SAndroid Build Coastguard Worker }
493*9880d681SAndroid Build Coastguard Worker if (Features & (1 << FEATURE_AVX)) {
494*9880d681SAndroid Build Coastguard Worker *Type = INTEL_COREI7;
495*9880d681SAndroid Build Coastguard Worker *Subtype = INTEL_COREI7_SANDYBRIDGE;
496*9880d681SAndroid Build Coastguard Worker break;
497*9880d681SAndroid Build Coastguard Worker }
498*9880d681SAndroid Build Coastguard Worker if (Features & (1 << FEATURE_SSE4_2)) {
499*9880d681SAndroid Build Coastguard Worker if (Features & (1 << FEATURE_MOVBE)) {
500*9880d681SAndroid Build Coastguard Worker *Type = INTEL_ATOM;
501*9880d681SAndroid Build Coastguard Worker *Subtype = INTEL_ATOM_SILVERMONT;
502*9880d681SAndroid Build Coastguard Worker } else {
503*9880d681SAndroid Build Coastguard Worker *Type = INTEL_COREI7;
504*9880d681SAndroid Build Coastguard Worker *Subtype = INTEL_COREI7_NEHALEM;
505*9880d681SAndroid Build Coastguard Worker }
506*9880d681SAndroid Build Coastguard Worker break;
507*9880d681SAndroid Build Coastguard Worker }
508*9880d681SAndroid Build Coastguard Worker if (Features & (1 << FEATURE_SSE4_1)) {
509*9880d681SAndroid Build Coastguard Worker *Type = INTEL_CORE2; // "penryn"
510*9880d681SAndroid Build Coastguard Worker *Subtype = INTEL_CORE2_45;
511*9880d681SAndroid Build Coastguard Worker break;
512*9880d681SAndroid Build Coastguard Worker }
513*9880d681SAndroid Build Coastguard Worker if (Features & (1 << FEATURE_SSSE3)) {
514*9880d681SAndroid Build Coastguard Worker if (Features & (1 << FEATURE_MOVBE)) {
515*9880d681SAndroid Build Coastguard Worker *Type = INTEL_ATOM;
516*9880d681SAndroid Build Coastguard Worker *Subtype = INTEL_ATOM_BONNELL; // "bonnell"
517*9880d681SAndroid Build Coastguard Worker } else {
518*9880d681SAndroid Build Coastguard Worker *Type = INTEL_CORE2; // "core2"
519*9880d681SAndroid Build Coastguard Worker *Subtype = INTEL_CORE2_65;
520*9880d681SAndroid Build Coastguard Worker }
521*9880d681SAndroid Build Coastguard Worker break;
522*9880d681SAndroid Build Coastguard Worker }
523*9880d681SAndroid Build Coastguard Worker if (Features & (1 << FEATURE_EM64T)) {
524*9880d681SAndroid Build Coastguard Worker *Type = INTEL_X86_64;
525*9880d681SAndroid Build Coastguard Worker break; // x86-64
526*9880d681SAndroid Build Coastguard Worker }
527*9880d681SAndroid Build Coastguard Worker if (Features & (1 << FEATURE_SSE2)) {
528*9880d681SAndroid Build Coastguard Worker *Type = INTEL_PENTIUM_M;
529*9880d681SAndroid Build Coastguard Worker break;
530*9880d681SAndroid Build Coastguard Worker }
531*9880d681SAndroid Build Coastguard Worker if (Features & (1 << FEATURE_SSE)) {
532*9880d681SAndroid Build Coastguard Worker *Type = INTEL_PENTIUM_III;
533*9880d681SAndroid Build Coastguard Worker break;
534*9880d681SAndroid Build Coastguard Worker }
535*9880d681SAndroid Build Coastguard Worker if (Features & (1 << FEATURE_MMX)) {
536*9880d681SAndroid Build Coastguard Worker *Type = INTEL_PENTIUM_II;
537*9880d681SAndroid Build Coastguard Worker break;
538*9880d681SAndroid Build Coastguard Worker }
539*9880d681SAndroid Build Coastguard Worker *Type = INTEL_PENTIUM_PRO;
540*9880d681SAndroid Build Coastguard Worker break;
541*9880d681SAndroid Build Coastguard Worker }
542*9880d681SAndroid Build Coastguard Worker break;
543*9880d681SAndroid Build Coastguard Worker case 15: {
544*9880d681SAndroid Build Coastguard Worker switch (Model) {
545*9880d681SAndroid Build Coastguard Worker case 0: // Pentium 4 processor, Intel Xeon processor. All processors are
546*9880d681SAndroid Build Coastguard Worker // model 00h and manufactured using the 0.18 micron process.
547*9880d681SAndroid Build Coastguard Worker case 1: // Pentium 4 processor, Intel Xeon processor, Intel Xeon
548*9880d681SAndroid Build Coastguard Worker // processor MP, and Intel Celeron processor. All processors are
549*9880d681SAndroid Build Coastguard Worker // model 01h and manufactured using the 0.18 micron process.
550*9880d681SAndroid Build Coastguard Worker case 2: // Pentium 4 processor, Mobile Intel Pentium 4 processor - M,
551*9880d681SAndroid Build Coastguard Worker // Intel Xeon processor, Intel Xeon processor MP, Intel Celeron
552*9880d681SAndroid Build Coastguard Worker // processor, and Mobile Intel Celeron processor. All processors
553*9880d681SAndroid Build Coastguard Worker // are model 02h and manufactured using the 0.13 micron process.
554*9880d681SAndroid Build Coastguard Worker *Type =
555*9880d681SAndroid Build Coastguard Worker ((Features & (1 << FEATURE_EM64T)) ? INTEL_X86_64 : INTEL_PENTIUM_IV);
556*9880d681SAndroid Build Coastguard Worker break;
557*9880d681SAndroid Build Coastguard Worker
558*9880d681SAndroid Build Coastguard Worker case 3: // Pentium 4 processor, Intel Xeon processor, Intel Celeron D
559*9880d681SAndroid Build Coastguard Worker // processor. All processors are model 03h and manufactured using
560*9880d681SAndroid Build Coastguard Worker // the 90 nm process.
561*9880d681SAndroid Build Coastguard Worker case 4: // Pentium 4 processor, Pentium 4 processor Extreme Edition,
562*9880d681SAndroid Build Coastguard Worker // Pentium D processor, Intel Xeon processor, Intel Xeon
563*9880d681SAndroid Build Coastguard Worker // processor MP, Intel Celeron D processor. All processors are
564*9880d681SAndroid Build Coastguard Worker // model 04h and manufactured using the 90 nm process.
565*9880d681SAndroid Build Coastguard Worker case 6: // Pentium 4 processor, Pentium D processor, Pentium processor
566*9880d681SAndroid Build Coastguard Worker // Extreme Edition, Intel Xeon processor, Intel Xeon processor
567*9880d681SAndroid Build Coastguard Worker // MP, Intel Celeron D processor. All processors are model 06h
568*9880d681SAndroid Build Coastguard Worker // and manufactured using the 65 nm process.
569*9880d681SAndroid Build Coastguard Worker *Type =
570*9880d681SAndroid Build Coastguard Worker ((Features & (1 << FEATURE_EM64T)) ? INTEL_NOCONA : INTEL_PRESCOTT);
571*9880d681SAndroid Build Coastguard Worker break;
572*9880d681SAndroid Build Coastguard Worker
573*9880d681SAndroid Build Coastguard Worker default:
574*9880d681SAndroid Build Coastguard Worker *Type =
575*9880d681SAndroid Build Coastguard Worker ((Features & (1 << FEATURE_EM64T)) ? INTEL_X86_64 : INTEL_PENTIUM_IV);
576*9880d681SAndroid Build Coastguard Worker break;
577*9880d681SAndroid Build Coastguard Worker }
578*9880d681SAndroid Build Coastguard Worker break;
579*9880d681SAndroid Build Coastguard Worker }
580*9880d681SAndroid Build Coastguard Worker default:
581*9880d681SAndroid Build Coastguard Worker break; /*"generic"*/
582*9880d681SAndroid Build Coastguard Worker }
583*9880d681SAndroid Build Coastguard Worker }
584*9880d681SAndroid Build Coastguard Worker
getAMDProcessorTypeAndSubtype(unsigned int Family,unsigned int Model,unsigned int Features,unsigned * Type,unsigned * Subtype)585*9880d681SAndroid Build Coastguard Worker static void getAMDProcessorTypeAndSubtype(unsigned int Family,
586*9880d681SAndroid Build Coastguard Worker unsigned int Model,
587*9880d681SAndroid Build Coastguard Worker unsigned int Features,
588*9880d681SAndroid Build Coastguard Worker unsigned *Type,
589*9880d681SAndroid Build Coastguard Worker unsigned *Subtype) {
590*9880d681SAndroid Build Coastguard Worker // FIXME: this poorly matches the generated SubtargetFeatureKV table. There
591*9880d681SAndroid Build Coastguard Worker // appears to be no way to generate the wide variety of AMD-specific targets
592*9880d681SAndroid Build Coastguard Worker // from the information returned from CPUID.
593*9880d681SAndroid Build Coastguard Worker switch (Family) {
594*9880d681SAndroid Build Coastguard Worker case 4:
595*9880d681SAndroid Build Coastguard Worker *Type = AMD_i486;
596*9880d681SAndroid Build Coastguard Worker break;
597*9880d681SAndroid Build Coastguard Worker case 5:
598*9880d681SAndroid Build Coastguard Worker *Type = AMDPENTIUM;
599*9880d681SAndroid Build Coastguard Worker switch (Model) {
600*9880d681SAndroid Build Coastguard Worker case 6:
601*9880d681SAndroid Build Coastguard Worker case 7:
602*9880d681SAndroid Build Coastguard Worker *Subtype = AMDPENTIUM_K6;
603*9880d681SAndroid Build Coastguard Worker break; // "k6"
604*9880d681SAndroid Build Coastguard Worker case 8:
605*9880d681SAndroid Build Coastguard Worker *Subtype = AMDPENTIUM_K62;
606*9880d681SAndroid Build Coastguard Worker break; // "k6-2"
607*9880d681SAndroid Build Coastguard Worker case 9:
608*9880d681SAndroid Build Coastguard Worker case 13:
609*9880d681SAndroid Build Coastguard Worker *Subtype = AMDPENTIUM_K63;
610*9880d681SAndroid Build Coastguard Worker break; // "k6-3"
611*9880d681SAndroid Build Coastguard Worker case 10:
612*9880d681SAndroid Build Coastguard Worker *Subtype = AMDPENTIUM_GEODE;
613*9880d681SAndroid Build Coastguard Worker break; // "geode"
614*9880d681SAndroid Build Coastguard Worker }
615*9880d681SAndroid Build Coastguard Worker break;
616*9880d681SAndroid Build Coastguard Worker case 6:
617*9880d681SAndroid Build Coastguard Worker *Type = AMDATHLON;
618*9880d681SAndroid Build Coastguard Worker switch (Model) {
619*9880d681SAndroid Build Coastguard Worker case 4:
620*9880d681SAndroid Build Coastguard Worker *Subtype = AMDATHLON_TBIRD;
621*9880d681SAndroid Build Coastguard Worker break; // "athlon-tbird"
622*9880d681SAndroid Build Coastguard Worker case 6:
623*9880d681SAndroid Build Coastguard Worker case 7:
624*9880d681SAndroid Build Coastguard Worker case 8:
625*9880d681SAndroid Build Coastguard Worker *Subtype = AMDATHLON_MP;
626*9880d681SAndroid Build Coastguard Worker break; // "athlon-mp"
627*9880d681SAndroid Build Coastguard Worker case 10:
628*9880d681SAndroid Build Coastguard Worker *Subtype = AMDATHLON_XP;
629*9880d681SAndroid Build Coastguard Worker break; // "athlon-xp"
630*9880d681SAndroid Build Coastguard Worker }
631*9880d681SAndroid Build Coastguard Worker break;
632*9880d681SAndroid Build Coastguard Worker case 15:
633*9880d681SAndroid Build Coastguard Worker *Type = AMDATHLON;
634*9880d681SAndroid Build Coastguard Worker if (Features & (1 << FEATURE_SSE3)) {
635*9880d681SAndroid Build Coastguard Worker *Subtype = AMDATHLON_K8SSE3;
636*9880d681SAndroid Build Coastguard Worker break; // "k8-sse3"
637*9880d681SAndroid Build Coastguard Worker }
638*9880d681SAndroid Build Coastguard Worker switch (Model) {
639*9880d681SAndroid Build Coastguard Worker case 1:
640*9880d681SAndroid Build Coastguard Worker *Subtype = AMDATHLON_OPTERON;
641*9880d681SAndroid Build Coastguard Worker break; // "opteron"
642*9880d681SAndroid Build Coastguard Worker case 5:
643*9880d681SAndroid Build Coastguard Worker *Subtype = AMDATHLON_FX;
644*9880d681SAndroid Build Coastguard Worker break; // "athlon-fx"; also opteron
645*9880d681SAndroid Build Coastguard Worker default:
646*9880d681SAndroid Build Coastguard Worker *Subtype = AMDATHLON_64;
647*9880d681SAndroid Build Coastguard Worker break; // "athlon64"
648*9880d681SAndroid Build Coastguard Worker }
649*9880d681SAndroid Build Coastguard Worker break;
650*9880d681SAndroid Build Coastguard Worker case 16:
651*9880d681SAndroid Build Coastguard Worker *Type = AMDFAM10H; // "amdfam10"
652*9880d681SAndroid Build Coastguard Worker switch (Model) {
653*9880d681SAndroid Build Coastguard Worker case 2:
654*9880d681SAndroid Build Coastguard Worker *Subtype = AMDFAM10H_BARCELONA;
655*9880d681SAndroid Build Coastguard Worker break;
656*9880d681SAndroid Build Coastguard Worker case 4:
657*9880d681SAndroid Build Coastguard Worker *Subtype = AMDFAM10H_SHANGHAI;
658*9880d681SAndroid Build Coastguard Worker break;
659*9880d681SAndroid Build Coastguard Worker case 8:
660*9880d681SAndroid Build Coastguard Worker *Subtype = AMDFAM10H_ISTANBUL;
661*9880d681SAndroid Build Coastguard Worker break;
662*9880d681SAndroid Build Coastguard Worker }
663*9880d681SAndroid Build Coastguard Worker break;
664*9880d681SAndroid Build Coastguard Worker case 20:
665*9880d681SAndroid Build Coastguard Worker *Type = AMDFAM14H;
666*9880d681SAndroid Build Coastguard Worker *Subtype = AMD_BTVER1;
667*9880d681SAndroid Build Coastguard Worker break; // "btver1";
668*9880d681SAndroid Build Coastguard Worker case 21:
669*9880d681SAndroid Build Coastguard Worker *Type = AMDFAM15H;
670*9880d681SAndroid Build Coastguard Worker if (!(Features &
671*9880d681SAndroid Build Coastguard Worker (1 << FEATURE_AVX))) { // If no AVX support, provide a sane fallback.
672*9880d681SAndroid Build Coastguard Worker *Subtype = AMD_BTVER1;
673*9880d681SAndroid Build Coastguard Worker break; // "btver1"
674*9880d681SAndroid Build Coastguard Worker }
675*9880d681SAndroid Build Coastguard Worker if (Model >= 0x50 && Model <= 0x6f) {
676*9880d681SAndroid Build Coastguard Worker *Subtype = AMDFAM15H_BDVER4;
677*9880d681SAndroid Build Coastguard Worker break; // "bdver4"; 50h-6Fh: Excavator
678*9880d681SAndroid Build Coastguard Worker }
679*9880d681SAndroid Build Coastguard Worker if (Model >= 0x30 && Model <= 0x3f) {
680*9880d681SAndroid Build Coastguard Worker *Subtype = AMDFAM15H_BDVER3;
681*9880d681SAndroid Build Coastguard Worker break; // "bdver3"; 30h-3Fh: Steamroller
682*9880d681SAndroid Build Coastguard Worker }
683*9880d681SAndroid Build Coastguard Worker if (Model >= 0x10 && Model <= 0x1f) {
684*9880d681SAndroid Build Coastguard Worker *Subtype = AMDFAM15H_BDVER2;
685*9880d681SAndroid Build Coastguard Worker break; // "bdver2"; 10h-1Fh: Piledriver
686*9880d681SAndroid Build Coastguard Worker }
687*9880d681SAndroid Build Coastguard Worker if (Model <= 0x0f) {
688*9880d681SAndroid Build Coastguard Worker *Subtype = AMDFAM15H_BDVER1;
689*9880d681SAndroid Build Coastguard Worker break; // "bdver1"; 00h-0Fh: Bulldozer
690*9880d681SAndroid Build Coastguard Worker }
691*9880d681SAndroid Build Coastguard Worker break;
692*9880d681SAndroid Build Coastguard Worker case 22:
693*9880d681SAndroid Build Coastguard Worker *Type = AMDFAM16H;
694*9880d681SAndroid Build Coastguard Worker if (!(Features &
695*9880d681SAndroid Build Coastguard Worker (1 << FEATURE_AVX))) { // If no AVX support provide a sane fallback.
696*9880d681SAndroid Build Coastguard Worker *Subtype = AMD_BTVER1;
697*9880d681SAndroid Build Coastguard Worker break; // "btver1";
698*9880d681SAndroid Build Coastguard Worker }
699*9880d681SAndroid Build Coastguard Worker *Subtype = AMD_BTVER2;
700*9880d681SAndroid Build Coastguard Worker break; // "btver2"
701*9880d681SAndroid Build Coastguard Worker default:
702*9880d681SAndroid Build Coastguard Worker break; // "generic"
703*9880d681SAndroid Build Coastguard Worker }
704*9880d681SAndroid Build Coastguard Worker }
705*9880d681SAndroid Build Coastguard Worker
getAvailableFeatures(unsigned int ECX,unsigned int EDX,unsigned MaxLeaf)706*9880d681SAndroid Build Coastguard Worker static unsigned getAvailableFeatures(unsigned int ECX, unsigned int EDX,
707*9880d681SAndroid Build Coastguard Worker unsigned MaxLeaf) {
708*9880d681SAndroid Build Coastguard Worker unsigned Features = 0;
709*9880d681SAndroid Build Coastguard Worker unsigned int EAX, EBX;
710*9880d681SAndroid Build Coastguard Worker Features |= (((EDX >> 23) & 1) << FEATURE_MMX);
711*9880d681SAndroid Build Coastguard Worker Features |= (((EDX >> 25) & 1) << FEATURE_SSE);
712*9880d681SAndroid Build Coastguard Worker Features |= (((EDX >> 26) & 1) << FEATURE_SSE2);
713*9880d681SAndroid Build Coastguard Worker Features |= (((ECX >> 0) & 1) << FEATURE_SSE3);
714*9880d681SAndroid Build Coastguard Worker Features |= (((ECX >> 9) & 1) << FEATURE_SSSE3);
715*9880d681SAndroid Build Coastguard Worker Features |= (((ECX >> 19) & 1) << FEATURE_SSE4_1);
716*9880d681SAndroid Build Coastguard Worker Features |= (((ECX >> 20) & 1) << FEATURE_SSE4_2);
717*9880d681SAndroid Build Coastguard Worker Features |= (((ECX >> 22) & 1) << FEATURE_MOVBE);
718*9880d681SAndroid Build Coastguard Worker
719*9880d681SAndroid Build Coastguard Worker // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV
720*9880d681SAndroid Build Coastguard Worker // indicates that the AVX registers will be saved and restored on context
721*9880d681SAndroid Build Coastguard Worker // switch, then we have full AVX support.
722*9880d681SAndroid Build Coastguard Worker const unsigned AVXBits = (1 << 27) | (1 << 28);
723*9880d681SAndroid Build Coastguard Worker bool HasAVX = ((ECX & AVXBits) == AVXBits) && !getX86XCR0(&EAX, &EDX) &&
724*9880d681SAndroid Build Coastguard Worker ((EAX & 0x6) == 0x6);
725*9880d681SAndroid Build Coastguard Worker bool HasAVX512Save = HasAVX && ((EAX & 0xe0) == 0xe0);
726*9880d681SAndroid Build Coastguard Worker bool HasLeaf7 =
727*9880d681SAndroid Build Coastguard Worker MaxLeaf >= 0x7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
728*9880d681SAndroid Build Coastguard Worker bool HasADX = HasLeaf7 && ((EBX >> 19) & 1);
729*9880d681SAndroid Build Coastguard Worker bool HasAVX2 = HasAVX && HasLeaf7 && (EBX & 0x20);
730*9880d681SAndroid Build Coastguard Worker bool HasAVX512 = HasLeaf7 && HasAVX512Save && ((EBX >> 16) & 1);
731*9880d681SAndroid Build Coastguard Worker Features |= (HasAVX << FEATURE_AVX);
732*9880d681SAndroid Build Coastguard Worker Features |= (HasAVX2 << FEATURE_AVX2);
733*9880d681SAndroid Build Coastguard Worker Features |= (HasAVX512 << FEATURE_AVX512);
734*9880d681SAndroid Build Coastguard Worker Features |= (HasAVX512Save << FEATURE_AVX512SAVE);
735*9880d681SAndroid Build Coastguard Worker Features |= (HasADX << FEATURE_ADX);
736*9880d681SAndroid Build Coastguard Worker
737*9880d681SAndroid Build Coastguard Worker getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
738*9880d681SAndroid Build Coastguard Worker Features |= (((EDX >> 29) & 0x1) << FEATURE_EM64T);
739*9880d681SAndroid Build Coastguard Worker return Features;
740*9880d681SAndroid Build Coastguard Worker }
741*9880d681SAndroid Build Coastguard Worker
getHostCPUName()742*9880d681SAndroid Build Coastguard Worker StringRef sys::getHostCPUName() {
743*9880d681SAndroid Build Coastguard Worker unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
744*9880d681SAndroid Build Coastguard Worker unsigned MaxLeaf, Vendor;
745*9880d681SAndroid Build Coastguard Worker
746*9880d681SAndroid Build Coastguard Worker if (getX86CpuIDAndInfo(0, &MaxLeaf, &Vendor, &ECX, &EDX))
747*9880d681SAndroid Build Coastguard Worker return "generic";
748*9880d681SAndroid Build Coastguard Worker if (getX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX))
749*9880d681SAndroid Build Coastguard Worker return "generic";
750*9880d681SAndroid Build Coastguard Worker
751*9880d681SAndroid Build Coastguard Worker unsigned Brand_id = EBX & 0xff;
752*9880d681SAndroid Build Coastguard Worker unsigned Family = 0, Model = 0;
753*9880d681SAndroid Build Coastguard Worker unsigned Features = 0;
754*9880d681SAndroid Build Coastguard Worker detectX86FamilyModel(EAX, &Family, &Model);
755*9880d681SAndroid Build Coastguard Worker Features = getAvailableFeatures(ECX, EDX, MaxLeaf);
756*9880d681SAndroid Build Coastguard Worker
757*9880d681SAndroid Build Coastguard Worker unsigned Type;
758*9880d681SAndroid Build Coastguard Worker unsigned Subtype;
759*9880d681SAndroid Build Coastguard Worker
760*9880d681SAndroid Build Coastguard Worker if (Vendor == SIG_INTEL) {
761*9880d681SAndroid Build Coastguard Worker getIntelProcessorTypeAndSubtype(Family, Model, Brand_id, Features, &Type,
762*9880d681SAndroid Build Coastguard Worker &Subtype);
763*9880d681SAndroid Build Coastguard Worker switch (Type) {
764*9880d681SAndroid Build Coastguard Worker case INTEL_i386:
765*9880d681SAndroid Build Coastguard Worker return "i386";
766*9880d681SAndroid Build Coastguard Worker case INTEL_i486:
767*9880d681SAndroid Build Coastguard Worker return "i486";
768*9880d681SAndroid Build Coastguard Worker case INTEL_PENTIUM:
769*9880d681SAndroid Build Coastguard Worker if (Subtype == INTEL_PENTIUM_MMX)
770*9880d681SAndroid Build Coastguard Worker return "pentium-mmx";
771*9880d681SAndroid Build Coastguard Worker return "pentium";
772*9880d681SAndroid Build Coastguard Worker case INTEL_PENTIUM_PRO:
773*9880d681SAndroid Build Coastguard Worker return "pentiumpro";
774*9880d681SAndroid Build Coastguard Worker case INTEL_PENTIUM_II:
775*9880d681SAndroid Build Coastguard Worker return "pentium2";
776*9880d681SAndroid Build Coastguard Worker case INTEL_PENTIUM_III:
777*9880d681SAndroid Build Coastguard Worker return "pentium3";
778*9880d681SAndroid Build Coastguard Worker case INTEL_PENTIUM_IV:
779*9880d681SAndroid Build Coastguard Worker return "pentium4";
780*9880d681SAndroid Build Coastguard Worker case INTEL_PENTIUM_M:
781*9880d681SAndroid Build Coastguard Worker return "pentium-m";
782*9880d681SAndroid Build Coastguard Worker case INTEL_CORE_DUO:
783*9880d681SAndroid Build Coastguard Worker return "yonah";
784*9880d681SAndroid Build Coastguard Worker case INTEL_CORE2:
785*9880d681SAndroid Build Coastguard Worker switch (Subtype) {
786*9880d681SAndroid Build Coastguard Worker case INTEL_CORE2_65:
787*9880d681SAndroid Build Coastguard Worker return "core2";
788*9880d681SAndroid Build Coastguard Worker case INTEL_CORE2_45:
789*9880d681SAndroid Build Coastguard Worker return "penryn";
790*9880d681SAndroid Build Coastguard Worker default:
791*9880d681SAndroid Build Coastguard Worker return "core2";
792*9880d681SAndroid Build Coastguard Worker }
793*9880d681SAndroid Build Coastguard Worker case INTEL_COREI7:
794*9880d681SAndroid Build Coastguard Worker switch (Subtype) {
795*9880d681SAndroid Build Coastguard Worker case INTEL_COREI7_NEHALEM:
796*9880d681SAndroid Build Coastguard Worker return "nehalem";
797*9880d681SAndroid Build Coastguard Worker case INTEL_COREI7_WESTMERE:
798*9880d681SAndroid Build Coastguard Worker return "westmere";
799*9880d681SAndroid Build Coastguard Worker case INTEL_COREI7_SANDYBRIDGE:
800*9880d681SAndroid Build Coastguard Worker return "sandybridge";
801*9880d681SAndroid Build Coastguard Worker case INTEL_COREI7_IVYBRIDGE:
802*9880d681SAndroid Build Coastguard Worker return "ivybridge";
803*9880d681SAndroid Build Coastguard Worker case INTEL_COREI7_HASWELL:
804*9880d681SAndroid Build Coastguard Worker return "haswell";
805*9880d681SAndroid Build Coastguard Worker case INTEL_COREI7_BROADWELL:
806*9880d681SAndroid Build Coastguard Worker return "broadwell";
807*9880d681SAndroid Build Coastguard Worker case INTEL_COREI7_SKYLAKE:
808*9880d681SAndroid Build Coastguard Worker return "skylake";
809*9880d681SAndroid Build Coastguard Worker case INTEL_COREI7_SKYLAKE_AVX512:
810*9880d681SAndroid Build Coastguard Worker return "skylake-avx512";
811*9880d681SAndroid Build Coastguard Worker default:
812*9880d681SAndroid Build Coastguard Worker return "corei7";
813*9880d681SAndroid Build Coastguard Worker }
814*9880d681SAndroid Build Coastguard Worker case INTEL_ATOM:
815*9880d681SAndroid Build Coastguard Worker switch (Subtype) {
816*9880d681SAndroid Build Coastguard Worker case INTEL_ATOM_BONNELL:
817*9880d681SAndroid Build Coastguard Worker return "bonnell";
818*9880d681SAndroid Build Coastguard Worker case INTEL_ATOM_SILVERMONT:
819*9880d681SAndroid Build Coastguard Worker return "silvermont";
820*9880d681SAndroid Build Coastguard Worker default:
821*9880d681SAndroid Build Coastguard Worker return "atom";
822*9880d681SAndroid Build Coastguard Worker }
823*9880d681SAndroid Build Coastguard Worker case INTEL_XEONPHI:
824*9880d681SAndroid Build Coastguard Worker return "knl"; /*update for more variants added*/
825*9880d681SAndroid Build Coastguard Worker case INTEL_X86_64:
826*9880d681SAndroid Build Coastguard Worker return "x86-64";
827*9880d681SAndroid Build Coastguard Worker case INTEL_NOCONA:
828*9880d681SAndroid Build Coastguard Worker return "nocona";
829*9880d681SAndroid Build Coastguard Worker case INTEL_PRESCOTT:
830*9880d681SAndroid Build Coastguard Worker return "prescott";
831*9880d681SAndroid Build Coastguard Worker default:
832*9880d681SAndroid Build Coastguard Worker return "generic";
833*9880d681SAndroid Build Coastguard Worker }
834*9880d681SAndroid Build Coastguard Worker } else if (Vendor == SIG_AMD) {
835*9880d681SAndroid Build Coastguard Worker getAMDProcessorTypeAndSubtype(Family, Model, Features, &Type, &Subtype);
836*9880d681SAndroid Build Coastguard Worker switch (Type) {
837*9880d681SAndroid Build Coastguard Worker case AMD_i486:
838*9880d681SAndroid Build Coastguard Worker return "i486";
839*9880d681SAndroid Build Coastguard Worker case AMDPENTIUM:
840*9880d681SAndroid Build Coastguard Worker switch (Subtype) {
841*9880d681SAndroid Build Coastguard Worker case AMDPENTIUM_K6:
842*9880d681SAndroid Build Coastguard Worker return "k6";
843*9880d681SAndroid Build Coastguard Worker case AMDPENTIUM_K62:
844*9880d681SAndroid Build Coastguard Worker return "k6-2";
845*9880d681SAndroid Build Coastguard Worker case AMDPENTIUM_K63:
846*9880d681SAndroid Build Coastguard Worker return "k6-3";
847*9880d681SAndroid Build Coastguard Worker case AMDPENTIUM_GEODE:
848*9880d681SAndroid Build Coastguard Worker return "geode";
849*9880d681SAndroid Build Coastguard Worker default:
850*9880d681SAndroid Build Coastguard Worker return "pentium";
851*9880d681SAndroid Build Coastguard Worker }
852*9880d681SAndroid Build Coastguard Worker case AMDATHLON:
853*9880d681SAndroid Build Coastguard Worker switch (Subtype) {
854*9880d681SAndroid Build Coastguard Worker case AMDATHLON_TBIRD:
855*9880d681SAndroid Build Coastguard Worker return "athlon-tbird";
856*9880d681SAndroid Build Coastguard Worker case AMDATHLON_MP:
857*9880d681SAndroid Build Coastguard Worker return "athlon-mp";
858*9880d681SAndroid Build Coastguard Worker case AMDATHLON_XP:
859*9880d681SAndroid Build Coastguard Worker return "athlon-xp";
860*9880d681SAndroid Build Coastguard Worker case AMDATHLON_K8SSE3:
861*9880d681SAndroid Build Coastguard Worker return "k8-sse3";
862*9880d681SAndroid Build Coastguard Worker case AMDATHLON_OPTERON:
863*9880d681SAndroid Build Coastguard Worker return "opteron";
864*9880d681SAndroid Build Coastguard Worker case AMDATHLON_FX:
865*9880d681SAndroid Build Coastguard Worker return "athlon-fx";
866*9880d681SAndroid Build Coastguard Worker case AMDATHLON_64:
867*9880d681SAndroid Build Coastguard Worker return "athlon64";
868*9880d681SAndroid Build Coastguard Worker default:
869*9880d681SAndroid Build Coastguard Worker return "athlon";
870*9880d681SAndroid Build Coastguard Worker }
871*9880d681SAndroid Build Coastguard Worker case AMDFAM10H:
872*9880d681SAndroid Build Coastguard Worker if(Subtype == AMDFAM10H_BARCELONA)
873*9880d681SAndroid Build Coastguard Worker return "barcelona";
874*9880d681SAndroid Build Coastguard Worker return "amdfam10";
875*9880d681SAndroid Build Coastguard Worker case AMDFAM14H:
876*9880d681SAndroid Build Coastguard Worker return "btver1";
877*9880d681SAndroid Build Coastguard Worker case AMDFAM15H:
878*9880d681SAndroid Build Coastguard Worker switch (Subtype) {
879*9880d681SAndroid Build Coastguard Worker case AMDFAM15H_BDVER1:
880*9880d681SAndroid Build Coastguard Worker return "bdver1";
881*9880d681SAndroid Build Coastguard Worker case AMDFAM15H_BDVER2:
882*9880d681SAndroid Build Coastguard Worker return "bdver2";
883*9880d681SAndroid Build Coastguard Worker case AMDFAM15H_BDVER3:
884*9880d681SAndroid Build Coastguard Worker return "bdver3";
885*9880d681SAndroid Build Coastguard Worker case AMDFAM15H_BDVER4:
886*9880d681SAndroid Build Coastguard Worker return "bdver4";
887*9880d681SAndroid Build Coastguard Worker case AMD_BTVER1:
888*9880d681SAndroid Build Coastguard Worker return "btver1";
889*9880d681SAndroid Build Coastguard Worker default:
890*9880d681SAndroid Build Coastguard Worker return "amdfam15";
891*9880d681SAndroid Build Coastguard Worker }
892*9880d681SAndroid Build Coastguard Worker case AMDFAM16H:
893*9880d681SAndroid Build Coastguard Worker switch (Subtype) {
894*9880d681SAndroid Build Coastguard Worker case AMD_BTVER1:
895*9880d681SAndroid Build Coastguard Worker return "btver1";
896*9880d681SAndroid Build Coastguard Worker case AMD_BTVER2:
897*9880d681SAndroid Build Coastguard Worker return "btver2";
898*9880d681SAndroid Build Coastguard Worker default:
899*9880d681SAndroid Build Coastguard Worker return "amdfam16";
900*9880d681SAndroid Build Coastguard Worker }
901*9880d681SAndroid Build Coastguard Worker default:
902*9880d681SAndroid Build Coastguard Worker return "generic";
903*9880d681SAndroid Build Coastguard Worker }
904*9880d681SAndroid Build Coastguard Worker }
905*9880d681SAndroid Build Coastguard Worker return "generic";
906*9880d681SAndroid Build Coastguard Worker }
907*9880d681SAndroid Build Coastguard Worker
908*9880d681SAndroid Build Coastguard Worker #elif defined(__APPLE__) && (defined(__ppc__) || defined(__powerpc__))
getHostCPUName()909*9880d681SAndroid Build Coastguard Worker StringRef sys::getHostCPUName() {
910*9880d681SAndroid Build Coastguard Worker host_basic_info_data_t hostInfo;
911*9880d681SAndroid Build Coastguard Worker mach_msg_type_number_t infoCount;
912*9880d681SAndroid Build Coastguard Worker
913*9880d681SAndroid Build Coastguard Worker infoCount = HOST_BASIC_INFO_COUNT;
914*9880d681SAndroid Build Coastguard Worker host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostInfo,
915*9880d681SAndroid Build Coastguard Worker &infoCount);
916*9880d681SAndroid Build Coastguard Worker
917*9880d681SAndroid Build Coastguard Worker if (hostInfo.cpu_type != CPU_TYPE_POWERPC)
918*9880d681SAndroid Build Coastguard Worker return "generic";
919*9880d681SAndroid Build Coastguard Worker
920*9880d681SAndroid Build Coastguard Worker switch (hostInfo.cpu_subtype) {
921*9880d681SAndroid Build Coastguard Worker case CPU_SUBTYPE_POWERPC_601:
922*9880d681SAndroid Build Coastguard Worker return "601";
923*9880d681SAndroid Build Coastguard Worker case CPU_SUBTYPE_POWERPC_602:
924*9880d681SAndroid Build Coastguard Worker return "602";
925*9880d681SAndroid Build Coastguard Worker case CPU_SUBTYPE_POWERPC_603:
926*9880d681SAndroid Build Coastguard Worker return "603";
927*9880d681SAndroid Build Coastguard Worker case CPU_SUBTYPE_POWERPC_603e:
928*9880d681SAndroid Build Coastguard Worker return "603e";
929*9880d681SAndroid Build Coastguard Worker case CPU_SUBTYPE_POWERPC_603ev:
930*9880d681SAndroid Build Coastguard Worker return "603ev";
931*9880d681SAndroid Build Coastguard Worker case CPU_SUBTYPE_POWERPC_604:
932*9880d681SAndroid Build Coastguard Worker return "604";
933*9880d681SAndroid Build Coastguard Worker case CPU_SUBTYPE_POWERPC_604e:
934*9880d681SAndroid Build Coastguard Worker return "604e";
935*9880d681SAndroid Build Coastguard Worker case CPU_SUBTYPE_POWERPC_620:
936*9880d681SAndroid Build Coastguard Worker return "620";
937*9880d681SAndroid Build Coastguard Worker case CPU_SUBTYPE_POWERPC_750:
938*9880d681SAndroid Build Coastguard Worker return "750";
939*9880d681SAndroid Build Coastguard Worker case CPU_SUBTYPE_POWERPC_7400:
940*9880d681SAndroid Build Coastguard Worker return "7400";
941*9880d681SAndroid Build Coastguard Worker case CPU_SUBTYPE_POWERPC_7450:
942*9880d681SAndroid Build Coastguard Worker return "7450";
943*9880d681SAndroid Build Coastguard Worker case CPU_SUBTYPE_POWERPC_970:
944*9880d681SAndroid Build Coastguard Worker return "970";
945*9880d681SAndroid Build Coastguard Worker default:;
946*9880d681SAndroid Build Coastguard Worker }
947*9880d681SAndroid Build Coastguard Worker
948*9880d681SAndroid Build Coastguard Worker return "generic";
949*9880d681SAndroid Build Coastguard Worker }
950*9880d681SAndroid Build Coastguard Worker #elif defined(__linux__) && (defined(__ppc__) || defined(__powerpc__))
getHostCPUName()951*9880d681SAndroid Build Coastguard Worker StringRef sys::getHostCPUName() {
952*9880d681SAndroid Build Coastguard Worker // Access to the Processor Version Register (PVR) on PowerPC is privileged,
953*9880d681SAndroid Build Coastguard Worker // and so we must use an operating-system interface to determine the current
954*9880d681SAndroid Build Coastguard Worker // processor type. On Linux, this is exposed through the /proc/cpuinfo file.
955*9880d681SAndroid Build Coastguard Worker const char *generic = "generic";
956*9880d681SAndroid Build Coastguard Worker
957*9880d681SAndroid Build Coastguard Worker // The cpu line is second (after the 'processor: 0' line), so if this
958*9880d681SAndroid Build Coastguard Worker // buffer is too small then something has changed (or is wrong).
959*9880d681SAndroid Build Coastguard Worker char buffer[1024];
960*9880d681SAndroid Build Coastguard Worker ssize_t CPUInfoSize = readCpuInfo(buffer, sizeof(buffer));
961*9880d681SAndroid Build Coastguard Worker if (CPUInfoSize == -1)
962*9880d681SAndroid Build Coastguard Worker return generic;
963*9880d681SAndroid Build Coastguard Worker
964*9880d681SAndroid Build Coastguard Worker const char *CPUInfoStart = buffer;
965*9880d681SAndroid Build Coastguard Worker const char *CPUInfoEnd = buffer + CPUInfoSize;
966*9880d681SAndroid Build Coastguard Worker
967*9880d681SAndroid Build Coastguard Worker const char *CIP = CPUInfoStart;
968*9880d681SAndroid Build Coastguard Worker
969*9880d681SAndroid Build Coastguard Worker const char *CPUStart = 0;
970*9880d681SAndroid Build Coastguard Worker size_t CPULen = 0;
971*9880d681SAndroid Build Coastguard Worker
972*9880d681SAndroid Build Coastguard Worker // We need to find the first line which starts with cpu, spaces, and a colon.
973*9880d681SAndroid Build Coastguard Worker // After the colon, there may be some additional spaces and then the cpu type.
974*9880d681SAndroid Build Coastguard Worker while (CIP < CPUInfoEnd && CPUStart == 0) {
975*9880d681SAndroid Build Coastguard Worker if (CIP < CPUInfoEnd && *CIP == '\n')
976*9880d681SAndroid Build Coastguard Worker ++CIP;
977*9880d681SAndroid Build Coastguard Worker
978*9880d681SAndroid Build Coastguard Worker if (CIP < CPUInfoEnd && *CIP == 'c') {
979*9880d681SAndroid Build Coastguard Worker ++CIP;
980*9880d681SAndroid Build Coastguard Worker if (CIP < CPUInfoEnd && *CIP == 'p') {
981*9880d681SAndroid Build Coastguard Worker ++CIP;
982*9880d681SAndroid Build Coastguard Worker if (CIP < CPUInfoEnd && *CIP == 'u') {
983*9880d681SAndroid Build Coastguard Worker ++CIP;
984*9880d681SAndroid Build Coastguard Worker while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t'))
985*9880d681SAndroid Build Coastguard Worker ++CIP;
986*9880d681SAndroid Build Coastguard Worker
987*9880d681SAndroid Build Coastguard Worker if (CIP < CPUInfoEnd && *CIP == ':') {
988*9880d681SAndroid Build Coastguard Worker ++CIP;
989*9880d681SAndroid Build Coastguard Worker while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t'))
990*9880d681SAndroid Build Coastguard Worker ++CIP;
991*9880d681SAndroid Build Coastguard Worker
992*9880d681SAndroid Build Coastguard Worker if (CIP < CPUInfoEnd) {
993*9880d681SAndroid Build Coastguard Worker CPUStart = CIP;
994*9880d681SAndroid Build Coastguard Worker while (CIP < CPUInfoEnd && (*CIP != ' ' && *CIP != '\t' &&
995*9880d681SAndroid Build Coastguard Worker *CIP != ',' && *CIP != '\n'))
996*9880d681SAndroid Build Coastguard Worker ++CIP;
997*9880d681SAndroid Build Coastguard Worker CPULen = CIP - CPUStart;
998*9880d681SAndroid Build Coastguard Worker }
999*9880d681SAndroid Build Coastguard Worker }
1000*9880d681SAndroid Build Coastguard Worker }
1001*9880d681SAndroid Build Coastguard Worker }
1002*9880d681SAndroid Build Coastguard Worker }
1003*9880d681SAndroid Build Coastguard Worker
1004*9880d681SAndroid Build Coastguard Worker if (CPUStart == 0)
1005*9880d681SAndroid Build Coastguard Worker while (CIP < CPUInfoEnd && *CIP != '\n')
1006*9880d681SAndroid Build Coastguard Worker ++CIP;
1007*9880d681SAndroid Build Coastguard Worker }
1008*9880d681SAndroid Build Coastguard Worker
1009*9880d681SAndroid Build Coastguard Worker if (CPUStart == 0)
1010*9880d681SAndroid Build Coastguard Worker return generic;
1011*9880d681SAndroid Build Coastguard Worker
1012*9880d681SAndroid Build Coastguard Worker return StringSwitch<const char *>(StringRef(CPUStart, CPULen))
1013*9880d681SAndroid Build Coastguard Worker .Case("604e", "604e")
1014*9880d681SAndroid Build Coastguard Worker .Case("604", "604")
1015*9880d681SAndroid Build Coastguard Worker .Case("7400", "7400")
1016*9880d681SAndroid Build Coastguard Worker .Case("7410", "7400")
1017*9880d681SAndroid Build Coastguard Worker .Case("7447", "7400")
1018*9880d681SAndroid Build Coastguard Worker .Case("7455", "7450")
1019*9880d681SAndroid Build Coastguard Worker .Case("G4", "g4")
1020*9880d681SAndroid Build Coastguard Worker .Case("POWER4", "970")
1021*9880d681SAndroid Build Coastguard Worker .Case("PPC970FX", "970")
1022*9880d681SAndroid Build Coastguard Worker .Case("PPC970MP", "970")
1023*9880d681SAndroid Build Coastguard Worker .Case("G5", "g5")
1024*9880d681SAndroid Build Coastguard Worker .Case("POWER5", "g5")
1025*9880d681SAndroid Build Coastguard Worker .Case("A2", "a2")
1026*9880d681SAndroid Build Coastguard Worker .Case("POWER6", "pwr6")
1027*9880d681SAndroid Build Coastguard Worker .Case("POWER7", "pwr7")
1028*9880d681SAndroid Build Coastguard Worker .Case("POWER8", "pwr8")
1029*9880d681SAndroid Build Coastguard Worker .Case("POWER8E", "pwr8")
1030*9880d681SAndroid Build Coastguard Worker .Case("POWER9", "pwr9")
1031*9880d681SAndroid Build Coastguard Worker .Default(generic);
1032*9880d681SAndroid Build Coastguard Worker }
1033*9880d681SAndroid Build Coastguard Worker #elif defined(__linux__) && defined(__arm__)
getHostCPUName()1034*9880d681SAndroid Build Coastguard Worker StringRef sys::getHostCPUName() {
1035*9880d681SAndroid Build Coastguard Worker // The cpuid register on arm is not accessible from user space. On Linux,
1036*9880d681SAndroid Build Coastguard Worker // it is exposed through the /proc/cpuinfo file.
1037*9880d681SAndroid Build Coastguard Worker
1038*9880d681SAndroid Build Coastguard Worker // Read 1024 bytes from /proc/cpuinfo, which should contain the CPU part line
1039*9880d681SAndroid Build Coastguard Worker // in all cases.
1040*9880d681SAndroid Build Coastguard Worker char buffer[1024];
1041*9880d681SAndroid Build Coastguard Worker ssize_t CPUInfoSize = readCpuInfo(buffer, sizeof(buffer));
1042*9880d681SAndroid Build Coastguard Worker if (CPUInfoSize == -1)
1043*9880d681SAndroid Build Coastguard Worker return "generic";
1044*9880d681SAndroid Build Coastguard Worker
1045*9880d681SAndroid Build Coastguard Worker StringRef Str(buffer, CPUInfoSize);
1046*9880d681SAndroid Build Coastguard Worker
1047*9880d681SAndroid Build Coastguard Worker SmallVector<StringRef, 32> Lines;
1048*9880d681SAndroid Build Coastguard Worker Str.split(Lines, "\n");
1049*9880d681SAndroid Build Coastguard Worker
1050*9880d681SAndroid Build Coastguard Worker // Look for the CPU implementer line.
1051*9880d681SAndroid Build Coastguard Worker StringRef Implementer;
1052*9880d681SAndroid Build Coastguard Worker for (unsigned I = 0, E = Lines.size(); I != E; ++I)
1053*9880d681SAndroid Build Coastguard Worker if (Lines[I].startswith("CPU implementer"))
1054*9880d681SAndroid Build Coastguard Worker Implementer = Lines[I].substr(15).ltrim("\t :");
1055*9880d681SAndroid Build Coastguard Worker
1056*9880d681SAndroid Build Coastguard Worker if (Implementer == "0x41") // ARM Ltd.
1057*9880d681SAndroid Build Coastguard Worker // Look for the CPU part line.
1058*9880d681SAndroid Build Coastguard Worker for (unsigned I = 0, E = Lines.size(); I != E; ++I)
1059*9880d681SAndroid Build Coastguard Worker if (Lines[I].startswith("CPU part"))
1060*9880d681SAndroid Build Coastguard Worker // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The
1061*9880d681SAndroid Build Coastguard Worker // values correspond to the "Part number" in the CP15/c0 register. The
1062*9880d681SAndroid Build Coastguard Worker // contents are specified in the various processor manuals.
1063*9880d681SAndroid Build Coastguard Worker return StringSwitch<const char *>(Lines[I].substr(8).ltrim("\t :"))
1064*9880d681SAndroid Build Coastguard Worker .Case("0x926", "arm926ej-s")
1065*9880d681SAndroid Build Coastguard Worker .Case("0xb02", "mpcore")
1066*9880d681SAndroid Build Coastguard Worker .Case("0xb36", "arm1136j-s")
1067*9880d681SAndroid Build Coastguard Worker .Case("0xb56", "arm1156t2-s")
1068*9880d681SAndroid Build Coastguard Worker .Case("0xb76", "arm1176jz-s")
1069*9880d681SAndroid Build Coastguard Worker .Case("0xc08", "cortex-a8")
1070*9880d681SAndroid Build Coastguard Worker .Case("0xc09", "cortex-a9")
1071*9880d681SAndroid Build Coastguard Worker .Case("0xc0f", "cortex-a15")
1072*9880d681SAndroid Build Coastguard Worker .Case("0xc20", "cortex-m0")
1073*9880d681SAndroid Build Coastguard Worker .Case("0xc23", "cortex-m3")
1074*9880d681SAndroid Build Coastguard Worker .Case("0xc24", "cortex-m4")
1075*9880d681SAndroid Build Coastguard Worker .Default("generic");
1076*9880d681SAndroid Build Coastguard Worker
1077*9880d681SAndroid Build Coastguard Worker if (Implementer == "0x51") // Qualcomm Technologies, Inc.
1078*9880d681SAndroid Build Coastguard Worker // Look for the CPU part line.
1079*9880d681SAndroid Build Coastguard Worker for (unsigned I = 0, E = Lines.size(); I != E; ++I)
1080*9880d681SAndroid Build Coastguard Worker if (Lines[I].startswith("CPU part"))
1081*9880d681SAndroid Build Coastguard Worker // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The
1082*9880d681SAndroid Build Coastguard Worker // values correspond to the "Part number" in the CP15/c0 register. The
1083*9880d681SAndroid Build Coastguard Worker // contents are specified in the various processor manuals.
1084*9880d681SAndroid Build Coastguard Worker return StringSwitch<const char *>(Lines[I].substr(8).ltrim("\t :"))
1085*9880d681SAndroid Build Coastguard Worker .Case("0x06f", "krait") // APQ8064
1086*9880d681SAndroid Build Coastguard Worker .Default("generic");
1087*9880d681SAndroid Build Coastguard Worker
1088*9880d681SAndroid Build Coastguard Worker return "generic";
1089*9880d681SAndroid Build Coastguard Worker }
1090*9880d681SAndroid Build Coastguard Worker #elif defined(__linux__) && defined(__s390x__)
getHostCPUName()1091*9880d681SAndroid Build Coastguard Worker StringRef sys::getHostCPUName() {
1092*9880d681SAndroid Build Coastguard Worker // STIDP is a privileged operation, so use /proc/cpuinfo instead.
1093*9880d681SAndroid Build Coastguard Worker
1094*9880d681SAndroid Build Coastguard Worker // The "processor 0:" line comes after a fair amount of other information,
1095*9880d681SAndroid Build Coastguard Worker // including a cache breakdown, but this should be plenty.
1096*9880d681SAndroid Build Coastguard Worker char buffer[2048];
1097*9880d681SAndroid Build Coastguard Worker ssize_t CPUInfoSize = readCpuInfo(buffer, sizeof(buffer));
1098*9880d681SAndroid Build Coastguard Worker if (CPUInfoSize == -1)
1099*9880d681SAndroid Build Coastguard Worker return "generic";
1100*9880d681SAndroid Build Coastguard Worker
1101*9880d681SAndroid Build Coastguard Worker StringRef Str(buffer, CPUInfoSize);
1102*9880d681SAndroid Build Coastguard Worker SmallVector<StringRef, 32> Lines;
1103*9880d681SAndroid Build Coastguard Worker Str.split(Lines, "\n");
1104*9880d681SAndroid Build Coastguard Worker
1105*9880d681SAndroid Build Coastguard Worker // Look for the CPU features.
1106*9880d681SAndroid Build Coastguard Worker SmallVector<StringRef, 32> CPUFeatures;
1107*9880d681SAndroid Build Coastguard Worker for (unsigned I = 0, E = Lines.size(); I != E; ++I)
1108*9880d681SAndroid Build Coastguard Worker if (Lines[I].startswith("features")) {
1109*9880d681SAndroid Build Coastguard Worker size_t Pos = Lines[I].find(":");
1110*9880d681SAndroid Build Coastguard Worker if (Pos != StringRef::npos) {
1111*9880d681SAndroid Build Coastguard Worker Lines[I].drop_front(Pos + 1).split(CPUFeatures, ' ');
1112*9880d681SAndroid Build Coastguard Worker break;
1113*9880d681SAndroid Build Coastguard Worker }
1114*9880d681SAndroid Build Coastguard Worker }
1115*9880d681SAndroid Build Coastguard Worker
1116*9880d681SAndroid Build Coastguard Worker // We need to check for the presence of vector support independently of
1117*9880d681SAndroid Build Coastguard Worker // the machine type, since we may only use the vector register set when
1118*9880d681SAndroid Build Coastguard Worker // supported by the kernel (and hypervisor).
1119*9880d681SAndroid Build Coastguard Worker bool HaveVectorSupport = false;
1120*9880d681SAndroid Build Coastguard Worker for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) {
1121*9880d681SAndroid Build Coastguard Worker if (CPUFeatures[I] == "vx")
1122*9880d681SAndroid Build Coastguard Worker HaveVectorSupport = true;
1123*9880d681SAndroid Build Coastguard Worker }
1124*9880d681SAndroid Build Coastguard Worker
1125*9880d681SAndroid Build Coastguard Worker // Now check the processor machine type.
1126*9880d681SAndroid Build Coastguard Worker for (unsigned I = 0, E = Lines.size(); I != E; ++I) {
1127*9880d681SAndroid Build Coastguard Worker if (Lines[I].startswith("processor ")) {
1128*9880d681SAndroid Build Coastguard Worker size_t Pos = Lines[I].find("machine = ");
1129*9880d681SAndroid Build Coastguard Worker if (Pos != StringRef::npos) {
1130*9880d681SAndroid Build Coastguard Worker Pos += sizeof("machine = ") - 1;
1131*9880d681SAndroid Build Coastguard Worker unsigned int Id;
1132*9880d681SAndroid Build Coastguard Worker if (!Lines[I].drop_front(Pos).getAsInteger(10, Id)) {
1133*9880d681SAndroid Build Coastguard Worker if (Id >= 2964 && HaveVectorSupport)
1134*9880d681SAndroid Build Coastguard Worker return "z13";
1135*9880d681SAndroid Build Coastguard Worker if (Id >= 2827)
1136*9880d681SAndroid Build Coastguard Worker return "zEC12";
1137*9880d681SAndroid Build Coastguard Worker if (Id >= 2817)
1138*9880d681SAndroid Build Coastguard Worker return "z196";
1139*9880d681SAndroid Build Coastguard Worker }
1140*9880d681SAndroid Build Coastguard Worker }
1141*9880d681SAndroid Build Coastguard Worker break;
1142*9880d681SAndroid Build Coastguard Worker }
1143*9880d681SAndroid Build Coastguard Worker }
1144*9880d681SAndroid Build Coastguard Worker
1145*9880d681SAndroid Build Coastguard Worker return "generic";
1146*9880d681SAndroid Build Coastguard Worker }
1147*9880d681SAndroid Build Coastguard Worker #else
getHostCPUName()1148*9880d681SAndroid Build Coastguard Worker StringRef sys::getHostCPUName() { return "generic"; }
1149*9880d681SAndroid Build Coastguard Worker #endif
1150*9880d681SAndroid Build Coastguard Worker
1151*9880d681SAndroid Build Coastguard Worker #if defined(i386) || defined(__i386__) || defined(__x86__) || \
1152*9880d681SAndroid Build Coastguard Worker defined(_M_IX86) || defined(__x86_64__) || defined(_M_AMD64) || \
1153*9880d681SAndroid Build Coastguard Worker defined(_M_X64)
getHostCPUFeatures(StringMap<bool> & Features)1154*9880d681SAndroid Build Coastguard Worker bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
1155*9880d681SAndroid Build Coastguard Worker unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
1156*9880d681SAndroid Build Coastguard Worker unsigned MaxLevel;
1157*9880d681SAndroid Build Coastguard Worker union {
1158*9880d681SAndroid Build Coastguard Worker unsigned u[3];
1159*9880d681SAndroid Build Coastguard Worker char c[12];
1160*9880d681SAndroid Build Coastguard Worker } text;
1161*9880d681SAndroid Build Coastguard Worker
1162*9880d681SAndroid Build Coastguard Worker if (getX86CpuIDAndInfo(0, &MaxLevel, text.u + 0, text.u + 2, text.u + 1) ||
1163*9880d681SAndroid Build Coastguard Worker MaxLevel < 1)
1164*9880d681SAndroid Build Coastguard Worker return false;
1165*9880d681SAndroid Build Coastguard Worker
1166*9880d681SAndroid Build Coastguard Worker getX86CpuIDAndInfo(1, &EAX, &EBX, &ECX, &EDX);
1167*9880d681SAndroid Build Coastguard Worker
1168*9880d681SAndroid Build Coastguard Worker Features["cmov"] = (EDX >> 15) & 1;
1169*9880d681SAndroid Build Coastguard Worker Features["mmx"] = (EDX >> 23) & 1;
1170*9880d681SAndroid Build Coastguard Worker Features["sse"] = (EDX >> 25) & 1;
1171*9880d681SAndroid Build Coastguard Worker Features["sse2"] = (EDX >> 26) & 1;
1172*9880d681SAndroid Build Coastguard Worker Features["sse3"] = (ECX >> 0) & 1;
1173*9880d681SAndroid Build Coastguard Worker Features["ssse3"] = (ECX >> 9) & 1;
1174*9880d681SAndroid Build Coastguard Worker Features["sse4.1"] = (ECX >> 19) & 1;
1175*9880d681SAndroid Build Coastguard Worker Features["sse4.2"] = (ECX >> 20) & 1;
1176*9880d681SAndroid Build Coastguard Worker
1177*9880d681SAndroid Build Coastguard Worker Features["pclmul"] = (ECX >> 1) & 1;
1178*9880d681SAndroid Build Coastguard Worker Features["cx16"] = (ECX >> 13) & 1;
1179*9880d681SAndroid Build Coastguard Worker Features["movbe"] = (ECX >> 22) & 1;
1180*9880d681SAndroid Build Coastguard Worker Features["popcnt"] = (ECX >> 23) & 1;
1181*9880d681SAndroid Build Coastguard Worker Features["aes"] = (ECX >> 25) & 1;
1182*9880d681SAndroid Build Coastguard Worker Features["rdrnd"] = (ECX >> 30) & 1;
1183*9880d681SAndroid Build Coastguard Worker
1184*9880d681SAndroid Build Coastguard Worker // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV
1185*9880d681SAndroid Build Coastguard Worker // indicates that the AVX registers will be saved and restored on context
1186*9880d681SAndroid Build Coastguard Worker // switch, then we have full AVX support.
1187*9880d681SAndroid Build Coastguard Worker bool HasAVXSave = ((ECX >> 27) & 1) && ((ECX >> 28) & 1) &&
1188*9880d681SAndroid Build Coastguard Worker !getX86XCR0(&EAX, &EDX) && ((EAX & 0x6) == 0x6);
1189*9880d681SAndroid Build Coastguard Worker Features["avx"] = HasAVXSave;
1190*9880d681SAndroid Build Coastguard Worker Features["fma"] = HasAVXSave && (ECX >> 12) & 1;
1191*9880d681SAndroid Build Coastguard Worker Features["f16c"] = HasAVXSave && (ECX >> 29) & 1;
1192*9880d681SAndroid Build Coastguard Worker
1193*9880d681SAndroid Build Coastguard Worker // Only enable XSAVE if OS has enabled support for saving YMM state.
1194*9880d681SAndroid Build Coastguard Worker Features["xsave"] = HasAVXSave && (ECX >> 26) & 1;
1195*9880d681SAndroid Build Coastguard Worker
1196*9880d681SAndroid Build Coastguard Worker // AVX512 requires additional context to be saved by the OS.
1197*9880d681SAndroid Build Coastguard Worker bool HasAVX512Save = HasAVXSave && ((EAX & 0xe0) == 0xe0);
1198*9880d681SAndroid Build Coastguard Worker
1199*9880d681SAndroid Build Coastguard Worker unsigned MaxExtLevel;
1200*9880d681SAndroid Build Coastguard Worker getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX);
1201*9880d681SAndroid Build Coastguard Worker
1202*9880d681SAndroid Build Coastguard Worker bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 &&
1203*9880d681SAndroid Build Coastguard Worker !getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
1204*9880d681SAndroid Build Coastguard Worker Features["lzcnt"] = HasExtLeaf1 && ((ECX >> 5) & 1);
1205*9880d681SAndroid Build Coastguard Worker Features["sse4a"] = HasExtLeaf1 && ((ECX >> 6) & 1);
1206*9880d681SAndroid Build Coastguard Worker Features["prfchw"] = HasExtLeaf1 && ((ECX >> 8) & 1);
1207*9880d681SAndroid Build Coastguard Worker Features["xop"] = HasExtLeaf1 && ((ECX >> 11) & 1) && HasAVXSave;
1208*9880d681SAndroid Build Coastguard Worker Features["fma4"] = HasExtLeaf1 && ((ECX >> 16) & 1) && HasAVXSave;
1209*9880d681SAndroid Build Coastguard Worker Features["tbm"] = HasExtLeaf1 && ((ECX >> 21) & 1);
1210*9880d681SAndroid Build Coastguard Worker Features["mwaitx"] = HasExtLeaf1 && ((ECX >> 29) & 1);
1211*9880d681SAndroid Build Coastguard Worker
1212*9880d681SAndroid Build Coastguard Worker bool HasLeaf7 =
1213*9880d681SAndroid Build Coastguard Worker MaxLevel >= 7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
1214*9880d681SAndroid Build Coastguard Worker
1215*9880d681SAndroid Build Coastguard Worker // AVX2 is only supported if we have the OS save support from AVX.
1216*9880d681SAndroid Build Coastguard Worker Features["avx2"] = HasAVXSave && HasLeaf7 && ((EBX >> 5) & 1);
1217*9880d681SAndroid Build Coastguard Worker
1218*9880d681SAndroid Build Coastguard Worker Features["fsgsbase"] = HasLeaf7 && ((EBX >> 0) & 1);
1219*9880d681SAndroid Build Coastguard Worker Features["sgx"] = HasLeaf7 && ((EBX >> 2) & 1);
1220*9880d681SAndroid Build Coastguard Worker Features["bmi"] = HasLeaf7 && ((EBX >> 3) & 1);
1221*9880d681SAndroid Build Coastguard Worker Features["hle"] = HasLeaf7 && ((EBX >> 4) & 1);
1222*9880d681SAndroid Build Coastguard Worker Features["bmi2"] = HasLeaf7 && ((EBX >> 8) & 1);
1223*9880d681SAndroid Build Coastguard Worker Features["invpcid"] = HasLeaf7 && ((EBX >> 10) & 1);
1224*9880d681SAndroid Build Coastguard Worker Features["rtm"] = HasLeaf7 && ((EBX >> 11) & 1);
1225*9880d681SAndroid Build Coastguard Worker Features["rdseed"] = HasLeaf7 && ((EBX >> 18) & 1);
1226*9880d681SAndroid Build Coastguard Worker Features["adx"] = HasLeaf7 && ((EBX >> 19) & 1);
1227*9880d681SAndroid Build Coastguard Worker Features["smap"] = HasLeaf7 && ((EBX >> 20) & 1);
1228*9880d681SAndroid Build Coastguard Worker Features["pcommit"] = HasLeaf7 && ((EBX >> 22) & 1);
1229*9880d681SAndroid Build Coastguard Worker Features["clflushopt"] = HasLeaf7 && ((EBX >> 23) & 1);
1230*9880d681SAndroid Build Coastguard Worker Features["clwb"] = HasLeaf7 && ((EBX >> 24) & 1);
1231*9880d681SAndroid Build Coastguard Worker Features["sha"] = HasLeaf7 && ((EBX >> 29) & 1);
1232*9880d681SAndroid Build Coastguard Worker
1233*9880d681SAndroid Build Coastguard Worker // AVX512 is only supported if the OS supports the context save for it.
1234*9880d681SAndroid Build Coastguard Worker Features["avx512f"] = HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save;
1235*9880d681SAndroid Build Coastguard Worker Features["avx512dq"] = HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save;
1236*9880d681SAndroid Build Coastguard Worker Features["avx512ifma"] = HasLeaf7 && ((EBX >> 21) & 1) && HasAVX512Save;
1237*9880d681SAndroid Build Coastguard Worker Features["avx512pf"] = HasLeaf7 && ((EBX >> 26) & 1) && HasAVX512Save;
1238*9880d681SAndroid Build Coastguard Worker Features["avx512er"] = HasLeaf7 && ((EBX >> 27) & 1) && HasAVX512Save;
1239*9880d681SAndroid Build Coastguard Worker Features["avx512cd"] = HasLeaf7 && ((EBX >> 28) & 1) && HasAVX512Save;
1240*9880d681SAndroid Build Coastguard Worker Features["avx512bw"] = HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save;
1241*9880d681SAndroid Build Coastguard Worker Features["avx512vl"] = HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save;
1242*9880d681SAndroid Build Coastguard Worker
1243*9880d681SAndroid Build Coastguard Worker Features["prefetchwt1"] = HasLeaf7 && (ECX & 1);
1244*9880d681SAndroid Build Coastguard Worker Features["avx512vbmi"] = HasLeaf7 && ((ECX >> 1) & 1) && HasAVX512Save;
1245*9880d681SAndroid Build Coastguard Worker // Enable protection keys
1246*9880d681SAndroid Build Coastguard Worker Features["pku"] = HasLeaf7 && ((ECX >> 4) & 1);
1247*9880d681SAndroid Build Coastguard Worker
1248*9880d681SAndroid Build Coastguard Worker bool HasLeafD = MaxLevel >= 0xd &&
1249*9880d681SAndroid Build Coastguard Worker !getX86CpuIDAndInfoEx(0xd, 0x1, &EAX, &EBX, &ECX, &EDX);
1250*9880d681SAndroid Build Coastguard Worker
1251*9880d681SAndroid Build Coastguard Worker // Only enable XSAVE if OS has enabled support for saving YMM state.
1252*9880d681SAndroid Build Coastguard Worker Features["xsaveopt"] = HasAVXSave && HasLeafD && ((EAX >> 0) & 1);
1253*9880d681SAndroid Build Coastguard Worker Features["xsavec"] = HasAVXSave && HasLeafD && ((EAX >> 1) & 1);
1254*9880d681SAndroid Build Coastguard Worker Features["xsaves"] = HasAVXSave && HasLeafD && ((EAX >> 3) & 1);
1255*9880d681SAndroid Build Coastguard Worker
1256*9880d681SAndroid Build Coastguard Worker return true;
1257*9880d681SAndroid Build Coastguard Worker }
1258*9880d681SAndroid Build Coastguard Worker #elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__))
getHostCPUFeatures(StringMap<bool> & Features)1259*9880d681SAndroid Build Coastguard Worker bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
1260*9880d681SAndroid Build Coastguard Worker // Read 1024 bytes from /proc/cpuinfo, which should contain the Features line
1261*9880d681SAndroid Build Coastguard Worker // in all cases.
1262*9880d681SAndroid Build Coastguard Worker char buffer[1024];
1263*9880d681SAndroid Build Coastguard Worker ssize_t CPUInfoSize = readCpuInfo(buffer, sizeof(buffer));
1264*9880d681SAndroid Build Coastguard Worker if (CPUInfoSize == -1)
1265*9880d681SAndroid Build Coastguard Worker return false;
1266*9880d681SAndroid Build Coastguard Worker
1267*9880d681SAndroid Build Coastguard Worker StringRef Str(buffer, CPUInfoSize);
1268*9880d681SAndroid Build Coastguard Worker
1269*9880d681SAndroid Build Coastguard Worker SmallVector<StringRef, 32> Lines;
1270*9880d681SAndroid Build Coastguard Worker Str.split(Lines, "\n");
1271*9880d681SAndroid Build Coastguard Worker
1272*9880d681SAndroid Build Coastguard Worker SmallVector<StringRef, 32> CPUFeatures;
1273*9880d681SAndroid Build Coastguard Worker
1274*9880d681SAndroid Build Coastguard Worker // Look for the CPU features.
1275*9880d681SAndroid Build Coastguard Worker for (unsigned I = 0, E = Lines.size(); I != E; ++I)
1276*9880d681SAndroid Build Coastguard Worker if (Lines[I].startswith("Features")) {
1277*9880d681SAndroid Build Coastguard Worker Lines[I].split(CPUFeatures, ' ');
1278*9880d681SAndroid Build Coastguard Worker break;
1279*9880d681SAndroid Build Coastguard Worker }
1280*9880d681SAndroid Build Coastguard Worker
1281*9880d681SAndroid Build Coastguard Worker #if defined(__aarch64__)
1282*9880d681SAndroid Build Coastguard Worker // Keep track of which crypto features we have seen
1283*9880d681SAndroid Build Coastguard Worker enum { CAP_AES = 0x1, CAP_PMULL = 0x2, CAP_SHA1 = 0x4, CAP_SHA2 = 0x8 };
1284*9880d681SAndroid Build Coastguard Worker uint32_t crypto = 0;
1285*9880d681SAndroid Build Coastguard Worker #endif
1286*9880d681SAndroid Build Coastguard Worker
1287*9880d681SAndroid Build Coastguard Worker for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) {
1288*9880d681SAndroid Build Coastguard Worker StringRef LLVMFeatureStr = StringSwitch<StringRef>(CPUFeatures[I])
1289*9880d681SAndroid Build Coastguard Worker #if defined(__aarch64__)
1290*9880d681SAndroid Build Coastguard Worker .Case("asimd", "neon")
1291*9880d681SAndroid Build Coastguard Worker .Case("fp", "fp-armv8")
1292*9880d681SAndroid Build Coastguard Worker .Case("crc32", "crc")
1293*9880d681SAndroid Build Coastguard Worker #else
1294*9880d681SAndroid Build Coastguard Worker .Case("half", "fp16")
1295*9880d681SAndroid Build Coastguard Worker .Case("neon", "neon")
1296*9880d681SAndroid Build Coastguard Worker .Case("vfpv3", "vfp3")
1297*9880d681SAndroid Build Coastguard Worker .Case("vfpv3d16", "d16")
1298*9880d681SAndroid Build Coastguard Worker .Case("vfpv4", "vfp4")
1299*9880d681SAndroid Build Coastguard Worker .Case("idiva", "hwdiv-arm")
1300*9880d681SAndroid Build Coastguard Worker .Case("idivt", "hwdiv")
1301*9880d681SAndroid Build Coastguard Worker #endif
1302*9880d681SAndroid Build Coastguard Worker .Default("");
1303*9880d681SAndroid Build Coastguard Worker
1304*9880d681SAndroid Build Coastguard Worker #if defined(__aarch64__)
1305*9880d681SAndroid Build Coastguard Worker // We need to check crypto separately since we need all of the crypto
1306*9880d681SAndroid Build Coastguard Worker // extensions to enable the subtarget feature
1307*9880d681SAndroid Build Coastguard Worker if (CPUFeatures[I] == "aes")
1308*9880d681SAndroid Build Coastguard Worker crypto |= CAP_AES;
1309*9880d681SAndroid Build Coastguard Worker else if (CPUFeatures[I] == "pmull")
1310*9880d681SAndroid Build Coastguard Worker crypto |= CAP_PMULL;
1311*9880d681SAndroid Build Coastguard Worker else if (CPUFeatures[I] == "sha1")
1312*9880d681SAndroid Build Coastguard Worker crypto |= CAP_SHA1;
1313*9880d681SAndroid Build Coastguard Worker else if (CPUFeatures[I] == "sha2")
1314*9880d681SAndroid Build Coastguard Worker crypto |= CAP_SHA2;
1315*9880d681SAndroid Build Coastguard Worker #endif
1316*9880d681SAndroid Build Coastguard Worker
1317*9880d681SAndroid Build Coastguard Worker if (LLVMFeatureStr != "")
1318*9880d681SAndroid Build Coastguard Worker Features[LLVMFeatureStr] = true;
1319*9880d681SAndroid Build Coastguard Worker }
1320*9880d681SAndroid Build Coastguard Worker
1321*9880d681SAndroid Build Coastguard Worker #if defined(__aarch64__)
1322*9880d681SAndroid Build Coastguard Worker // If we have all crypto bits we can add the feature
1323*9880d681SAndroid Build Coastguard Worker if (crypto == (CAP_AES | CAP_PMULL | CAP_SHA1 | CAP_SHA2))
1324*9880d681SAndroid Build Coastguard Worker Features["crypto"] = true;
1325*9880d681SAndroid Build Coastguard Worker #endif
1326*9880d681SAndroid Build Coastguard Worker
1327*9880d681SAndroid Build Coastguard Worker return true;
1328*9880d681SAndroid Build Coastguard Worker }
1329*9880d681SAndroid Build Coastguard Worker #else
getHostCPUFeatures(StringMap<bool> & Features)1330*9880d681SAndroid Build Coastguard Worker bool sys::getHostCPUFeatures(StringMap<bool> &Features) { return false; }
1331*9880d681SAndroid Build Coastguard Worker #endif
1332*9880d681SAndroid Build Coastguard Worker
getProcessTriple()1333*9880d681SAndroid Build Coastguard Worker std::string sys::getProcessTriple() {
1334*9880d681SAndroid Build Coastguard Worker Triple PT(Triple::normalize(LLVM_HOST_TRIPLE));
1335*9880d681SAndroid Build Coastguard Worker
1336*9880d681SAndroid Build Coastguard Worker if (sizeof(void *) == 8 && PT.isArch32Bit())
1337*9880d681SAndroid Build Coastguard Worker PT = PT.get64BitArchVariant();
1338*9880d681SAndroid Build Coastguard Worker if (sizeof(void *) == 4 && PT.isArch64Bit())
1339*9880d681SAndroid Build Coastguard Worker PT = PT.get32BitArchVariant();
1340*9880d681SAndroid Build Coastguard Worker
1341*9880d681SAndroid Build Coastguard Worker return PT.str();
1342*9880d681SAndroid Build Coastguard Worker }
1343