LCOV - code coverage report
Current view: top level - lib/Support - Host.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 124 533 23.3 %
Date: 2018-06-17 00:07:59 Functions: 8 13 61.5 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13