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

Generated by: LCOV version 1.13