Home | History | Annotate | Download | only in X86
      1 //===-- X86Subtarget.cpp - X86 Subtarget Information ----------------------===//
      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 X86 specific subclass of TargetSubtargetInfo.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "X86Subtarget.h"
     15 #include "X86InstrInfo.h"
     16 #include "X86TargetMachine.h"
     17 #include "llvm/IR/Attributes.h"
     18 #include "llvm/IR/Function.h"
     19 #include "llvm/IR/GlobalValue.h"
     20 #include "llvm/Support/CommandLine.h"
     21 #include "llvm/Support/Debug.h"
     22 #include "llvm/Support/ErrorHandling.h"
     23 #include "llvm/Support/Host.h"
     24 #include "llvm/Support/raw_ostream.h"
     25 #include "llvm/Target/TargetMachine.h"
     26 #include "llvm/Target/TargetOptions.h"
     27 
     28 #if defined(_MSC_VER)
     29 #include <intrin.h>
     30 #endif
     31 
     32 using namespace llvm;
     33 
     34 #define DEBUG_TYPE "subtarget"
     35 
     36 #define GET_SUBTARGETINFO_TARGET_DESC
     37 #define GET_SUBTARGETINFO_CTOR
     38 #include "X86GenSubtargetInfo.inc"
     39 
     40 // Temporary option to control early if-conversion for x86 while adding machine
     41 // models.
     42 static cl::opt<bool>
     43 X86EarlyIfConv("x86-early-ifcvt", cl::Hidden,
     44                cl::desc("Enable early if-conversion on X86"));
     45 
     46 
     47 /// Classify a blockaddress reference for the current subtarget according to how
     48 /// we should reference it in a non-pcrel context.
     49 unsigned char X86Subtarget::classifyBlockAddressReference() const {
     50   return classifyLocalReference(nullptr);
     51 }
     52 
     53 /// Classify a global variable reference for the current subtarget according to
     54 /// how we should reference it in a non-pcrel context.
     55 unsigned char
     56 X86Subtarget::classifyGlobalReference(const GlobalValue *GV) const {
     57   return classifyGlobalReference(GV, *GV->getParent());
     58 }
     59 
     60 unsigned char
     61 X86Subtarget::classifyLocalReference(const GlobalValue *GV) const {
     62   // 64 bits can use %rip addressing for anything local.
     63   if (is64Bit())
     64     return X86II::MO_NO_FLAG;
     65 
     66   // If this is for a position dependent executable, the static linker can
     67   // figure it out.
     68   if (!isPositionIndependent())
     69     return X86II::MO_NO_FLAG;
     70 
     71   // The COFF dynamic linker just patches the executable sections.
     72   if (isTargetCOFF())
     73     return X86II::MO_NO_FLAG;
     74 
     75   if (isTargetDarwin()) {
     76     // 32 bit macho has no relocation for a-b if a is undefined, even if
     77     // b is in the section that is being relocated.
     78     // This means we have to use o load even for GVs that are known to be
     79     // local to the dso.
     80     if (GV && (GV->isDeclarationForLinker() || GV->hasCommonLinkage()))
     81       return X86II::MO_DARWIN_NONLAZY_PIC_BASE;
     82 
     83     return X86II::MO_PIC_BASE_OFFSET;
     84   }
     85 
     86   return X86II::MO_GOTOFF;
     87 }
     88 
     89 unsigned char X86Subtarget::classifyGlobalReference(const GlobalValue *GV,
     90                                                     const Module &M) const {
     91   // Large model never uses stubs.
     92   if (TM.getCodeModel() == CodeModel::Large)
     93     return X86II::MO_NO_FLAG;
     94 
     95   if (TM.shouldAssumeDSOLocal(M, GV))
     96     return classifyLocalReference(GV);
     97 
     98   if (isTargetCOFF())
     99     return X86II::MO_DLLIMPORT;
    100 
    101   if (is64Bit())
    102     return X86II::MO_GOTPCREL;
    103 
    104   if (isTargetDarwin()) {
    105     if (!isPositionIndependent())
    106       return X86II::MO_DARWIN_NONLAZY;
    107     return X86II::MO_DARWIN_NONLAZY_PIC_BASE;
    108   }
    109 
    110   return X86II::MO_GOT;
    111 }
    112 
    113 unsigned char
    114 X86Subtarget::classifyGlobalFunctionReference(const GlobalValue *GV) const {
    115   return classifyGlobalFunctionReference(GV, *GV->getParent());
    116 }
    117 
    118 unsigned char
    119 X86Subtarget::classifyGlobalFunctionReference(const GlobalValue *GV,
    120                                               const Module &M) const {
    121   if (TM.shouldAssumeDSOLocal(M, GV))
    122     return X86II::MO_NO_FLAG;
    123 
    124   assert(!isTargetCOFF());
    125 
    126   if (isTargetELF())
    127     return X86II::MO_PLT;
    128 
    129   if (is64Bit()) {
    130     auto *F = dyn_cast_or_null<Function>(GV);
    131     if (F && F->hasFnAttribute(Attribute::NonLazyBind))
    132       // If the function is marked as non-lazy, generate an indirect call
    133       // which loads from the GOT directly. This avoids runtime overhead
    134       // at the cost of eager binding (and one extra byte of encoding).
    135       return X86II::MO_GOTPCREL;
    136     return X86II::MO_NO_FLAG;
    137   }
    138 
    139   return X86II::MO_NO_FLAG;
    140 }
    141 
    142 /// This function returns the name of a function which has an interface like
    143 /// the non-standard bzero function, if such a function exists on the
    144 /// current subtarget and it is considered preferable over memset with zero
    145 /// passed as the second argument. Otherwise it returns null.
    146 const char *X86Subtarget::getBZeroEntry() const {
    147   // Darwin 10 has a __bzero entry point for this purpose.
    148   if (getTargetTriple().isMacOSX() &&
    149       !getTargetTriple().isMacOSXVersionLT(10, 6))
    150     return "__bzero";
    151 
    152   return nullptr;
    153 }
    154 
    155 bool X86Subtarget::hasSinCos() const {
    156   return getTargetTriple().isMacOSX() &&
    157     !getTargetTriple().isMacOSXVersionLT(10, 9) &&
    158     is64Bit();
    159 }
    160 
    161 /// Return true if the subtarget allows calls to immediate address.
    162 bool X86Subtarget::isLegalToCallImmediateAddr() const {
    163   // FIXME: I386 PE/COFF supports PC relative calls using IMAGE_REL_I386_REL32
    164   // but WinCOFFObjectWriter::RecordRelocation cannot emit them.  Once it does,
    165   // the following check for Win32 should be removed.
    166   if (In64BitMode || isTargetWin32())
    167     return false;
    168   return isTargetELF() || TM.getRelocationModel() == Reloc::Static;
    169 }
    170 
    171 void X86Subtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) {
    172   std::string CPUName = CPU;
    173   if (CPUName.empty())
    174     CPUName = "generic";
    175 
    176   // Make sure 64-bit features are available in 64-bit mode. (But make sure
    177   // SSE2 can be turned off explicitly.)
    178   std::string FullFS = FS;
    179   if (In64BitMode) {
    180     if (!FullFS.empty())
    181       FullFS = "+64bit,+sse2," + FullFS;
    182     else
    183       FullFS = "+64bit,+sse2";
    184   }
    185 
    186   // LAHF/SAHF are always supported in non-64-bit mode.
    187   if (!In64BitMode) {
    188     if (!FullFS.empty())
    189       FullFS = "+sahf," + FullFS;
    190     else
    191       FullFS = "+sahf";
    192   }
    193 
    194 
    195   // Parse features string and set the CPU.
    196   ParseSubtargetFeatures(CPUName, FullFS);
    197 
    198   // All CPUs that implement SSE4.2 or SSE4A support unaligned accesses of
    199   // 16-bytes and under that are reasonably fast. These features were
    200   // introduced with Intel's Nehalem/Silvermont and AMD's Family10h
    201   // micro-architectures respectively.
    202   if (hasSSE42() || hasSSE4A())
    203     IsUAMem16Slow = false;
    204 
    205   InstrItins = getInstrItineraryForCPU(CPUName);
    206 
    207   // It's important to keep the MCSubtargetInfo feature bits in sync with
    208   // target data structure which is shared with MC code emitter, etc.
    209   if (In64BitMode)
    210     ToggleFeature(X86::Mode64Bit);
    211   else if (In32BitMode)
    212     ToggleFeature(X86::Mode32Bit);
    213   else if (In16BitMode)
    214     ToggleFeature(X86::Mode16Bit);
    215   else
    216     llvm_unreachable("Not 16-bit, 32-bit or 64-bit mode!");
    217 
    218   DEBUG(dbgs() << "Subtarget features: SSELevel " << X86SSELevel
    219                << ", 3DNowLevel " << X863DNowLevel
    220                << ", 64bit " << HasX86_64 << "\n");
    221   assert((!In64BitMode || HasX86_64) &&
    222          "64-bit code requested on a subtarget that doesn't support it!");
    223 
    224   // Stack alignment is 16 bytes on Darwin, Linux, kFreeBSD and Solaris (both
    225   // 32 and 64 bit) and for all 64-bit targets.
    226   if (StackAlignOverride)
    227     stackAlignment = StackAlignOverride;
    228   else if (isTargetDarwin() || isTargetLinux() || isTargetSolaris() ||
    229            isTargetKFreeBSD() || In64BitMode)
    230     stackAlignment = 16;
    231 }
    232 
    233 void X86Subtarget::initializeEnvironment() {
    234   X86SSELevel = NoSSE;
    235   X863DNowLevel = NoThreeDNow;
    236   HasX87 = false;
    237   HasCMov = false;
    238   HasX86_64 = false;
    239   HasPOPCNT = false;
    240   HasSSE4A = false;
    241   HasAES = false;
    242   HasFXSR = false;
    243   HasXSAVE = false;
    244   HasXSAVEOPT = false;
    245   HasXSAVEC = false;
    246   HasXSAVES = false;
    247   HasPCLMUL = false;
    248   HasFMA = false;
    249   HasFMA4 = false;
    250   HasXOP = false;
    251   HasTBM = false;
    252   HasMOVBE = false;
    253   HasRDRAND = false;
    254   HasF16C = false;
    255   HasFSGSBase = false;
    256   HasLZCNT = false;
    257   HasBMI = false;
    258   HasBMI2 = false;
    259   HasVBMI = false;
    260   HasIFMA = false;
    261   HasRTM = false;
    262   HasHLE = false;
    263   HasERI = false;
    264   HasCDI = false;
    265   HasPFI = false;
    266   HasDQI = false;
    267   HasBWI = false;
    268   HasVLX = false;
    269   HasADX = false;
    270   HasPKU = false;
    271   HasSHA = false;
    272   HasPRFCHW = false;
    273   HasRDSEED = false;
    274   HasLAHFSAHF = false;
    275   HasMWAITX = false;
    276   HasMPX = false;
    277   IsBTMemSlow = false;
    278   IsSHLDSlow = false;
    279   IsUAMem16Slow = false;
    280   IsUAMem32Slow = false;
    281   HasSSEUnalignedMem = false;
    282   HasCmpxchg16b = false;
    283   UseLeaForSP = false;
    284   HasFastPartialYMMWrite = false;
    285   HasSlowDivide32 = false;
    286   HasSlowDivide64 = false;
    287   PadShortFunctions = false;
    288   CallRegIndirect = false;
    289   LEAUsesAG = false;
    290   SlowLEA = false;
    291   SlowIncDec = false;
    292   stackAlignment = 4;
    293   // FIXME: this is a known good value for Yonah. How about others?
    294   MaxInlineSizeThreshold = 128;
    295   UseSoftFloat = false;
    296 }
    297 
    298 X86Subtarget &X86Subtarget::initializeSubtargetDependencies(StringRef CPU,
    299                                                             StringRef FS) {
    300   initializeEnvironment();
    301   initSubtargetFeatures(CPU, FS);
    302   return *this;
    303 }
    304 
    305 X86Subtarget::X86Subtarget(const Triple &TT, StringRef CPU, StringRef FS,
    306                            const X86TargetMachine &TM,
    307                            unsigned StackAlignOverride)
    308     : X86GenSubtargetInfo(TT, CPU, FS), X86ProcFamily(Others),
    309       PICStyle(PICStyles::None), TM(TM), TargetTriple(TT),
    310       StackAlignOverride(StackAlignOverride),
    311       In64BitMode(TargetTriple.getArch() == Triple::x86_64),
    312       In32BitMode(TargetTriple.getArch() == Triple::x86 &&
    313                   TargetTriple.getEnvironment() != Triple::CODE16),
    314       In16BitMode(TargetTriple.getArch() == Triple::x86 &&
    315                   TargetTriple.getEnvironment() == Triple::CODE16),
    316       TSInfo(), InstrInfo(initializeSubtargetDependencies(CPU, FS)),
    317       TLInfo(TM, *this), FrameLowering(*this, getStackAlignment()) {
    318   // Determine the PICStyle based on the target selected.
    319   if (!isPositionIndependent())
    320     setPICStyle(PICStyles::None);
    321   else if (is64Bit())
    322     setPICStyle(PICStyles::RIPRel);
    323   else if (isTargetCOFF())
    324     setPICStyle(PICStyles::None);
    325   else if (isTargetDarwin())
    326     setPICStyle(PICStyles::StubPIC);
    327   else if (isTargetELF())
    328     setPICStyle(PICStyles::GOT);
    329 }
    330 
    331 bool X86Subtarget::enableEarlyIfConversion() const {
    332   return hasCMov() && X86EarlyIfConv;
    333 }
    334 
    335