1234353Sdim//===-- X86Subtarget.h - Define Subtarget for the X86 ----------*- C++ -*--===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10224145Sdim// This file declares the X86 specific subclass of TargetSubtargetInfo. 11193323Sed// 12193323Sed//===----------------------------------------------------------------------===// 13193323Sed 14193323Sed#ifndef X86SUBTARGET_H 15193323Sed#define X86SUBTARGET_H 16193323Sed 17210299Sed#include "llvm/ADT/Triple.h" 18249423Sdim#include "llvm/IR/CallingConv.h" 19224145Sdim#include "llvm/Target/TargetSubtargetInfo.h" 20193323Sed#include <string> 21193323Sed 22224145Sdim#define GET_SUBTARGETINFO_HEADER 23224145Sdim#include "X86GenSubtargetInfo.inc" 24224145Sdim 25193323Sednamespace llvm { 26193323Sedclass GlobalValue; 27224145Sdimclass StringRef; 28193323Sedclass TargetMachine; 29204642Srdivacky 30198090Srdivacky/// PICStyles - The X86 backend supports a number of different styles of PIC. 31204642Srdivacky/// 32193323Sednamespace PICStyles { 33193323Sedenum Style { 34198090Srdivacky StubPIC, // Used on i386-darwin in -fPIC mode. 35198090Srdivacky StubDynamicNoPIC, // Used on i386-darwin in -mdynamic-no-pic mode. 36198090Srdivacky GOT, // Used on many 32-bit unices in -fPIC mode. 37198090Srdivacky RIPRel, // Used on X86-64 when not in -static mode. 38198090Srdivacky None // Set when in -static mode (not PIC or DynamicNoPIC mode). 39193323Sed}; 40193323Sed} 41193323Sed 42224145Sdimclass X86Subtarget : public X86GenSubtargetInfo { 43193323Sedprotected: 44193323Sed enum X86SSEEnum { 45263508Sdim NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42, AVX, AVX2, AVX512F 46193323Sed }; 47193323Sed 48193323Sed enum X863DNowEnum { 49193323Sed NoThreeDNow, ThreeDNow, ThreeDNowA 50193323Sed }; 51193323Sed 52234353Sdim enum X86ProcFamilyEnum { 53263508Sdim Others, IntelAtom, IntelSLM 54234353Sdim }; 55234353Sdim 56234353Sdim /// X86ProcFamily - X86 processor family: Intel Atom, and others 57234353Sdim X86ProcFamilyEnum X86ProcFamily; 58239462Sdim 59193323Sed /// PICStyle - Which PIC style to use 60193323Sed /// 61193323Sed PICStyles::Style PICStyle; 62204642Srdivacky 63193323Sed /// X86SSELevel - MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42, or 64193323Sed /// none supported. 65193323Sed X86SSEEnum X86SSELevel; 66193323Sed 67193323Sed /// X863DNowLevel - 3DNow or 3DNow Athlon, or none supported. 68193323Sed /// 69193323Sed X863DNowEnum X863DNowLevel; 70193323Sed 71198090Srdivacky /// HasCMov - True if this processor has conditional move instructions 72198090Srdivacky /// (generally pentium pro+). 73198090Srdivacky bool HasCMov; 74204642Srdivacky 75193323Sed /// HasX86_64 - True if the processor supports X86-64 instructions. 76193323Sed /// 77193323Sed bool HasX86_64; 78193323Sed 79218893Sdim /// HasPOPCNT - True if the processor supports POPCNT. 80218893Sdim bool HasPOPCNT; 81218893Sdim 82195098Sed /// HasSSE4A - True if the processor supports SSE4A instructions. 83195098Sed bool HasSSE4A; 84195098Sed 85206124Srdivacky /// HasAES - Target has AES instructions 86206124Srdivacky bool HasAES; 87206124Srdivacky 88239462Sdim /// HasPCLMUL - Target has carry-less multiplication 89239462Sdim bool HasPCLMUL; 90212904Sdim 91239462Sdim /// HasFMA - Target has 3-operand fused multiply-add 92239462Sdim bool HasFMA; 93195098Sed 94195098Sed /// HasFMA4 - Target has 4-operand fused multiply-add 95195098Sed bool HasFMA4; 96195098Sed 97234353Sdim /// HasXOP - Target has XOP instructions 98234353Sdim bool HasXOP; 99234353Sdim 100263508Sdim /// HasTBM - Target has TBM instructions. 101263508Sdim bool HasTBM; 102263508Sdim 103226633Sdim /// HasMOVBE - True if the processor has the MOVBE instruction. 104226633Sdim bool HasMOVBE; 105226633Sdim 106226633Sdim /// HasRDRAND - True if the processor has the RDRAND instruction. 107226633Sdim bool HasRDRAND; 108226633Sdim 109226633Sdim /// HasF16C - Processor has 16-bit floating point conversion instructions. 110226633Sdim bool HasF16C; 111226633Sdim 112234353Sdim /// HasFSGSBase - Processor has FS/GS base insturctions. 113234353Sdim bool HasFSGSBase; 114234353Sdim 115226633Sdim /// HasLZCNT - Processor has LZCNT instruction. 116226633Sdim bool HasLZCNT; 117226633Sdim 118226633Sdim /// HasBMI - Processor has BMI1 instructions. 119226633Sdim bool HasBMI; 120226633Sdim 121234353Sdim /// HasBMI2 - Processor has BMI2 instructions. 122234353Sdim bool HasBMI2; 123234353Sdim 124243830Sdim /// HasRTM - Processor has RTM instructions. 125243830Sdim bool HasRTM; 126243830Sdim 127249423Sdim /// HasHLE - Processor has HLE. 128249423Sdim bool HasHLE; 129249423Sdim 130249423Sdim /// HasADX - Processor has ADX instructions. 131249423Sdim bool HasADX; 132249423Sdim 133263508Sdim /// HasSHA - Processor has SHA instructions. 134263508Sdim bool HasSHA; 135263508Sdim 136249423Sdim /// HasPRFCHW - Processor has PRFCHW instructions. 137249423Sdim bool HasPRFCHW; 138249423Sdim 139249423Sdim /// HasRDSEED - Processor has RDSEED instructions. 140249423Sdim bool HasRDSEED; 141249423Sdim 142193323Sed /// IsBTMemSlow - True if BT (bit test) of memory instructions are slow. 143193323Sed bool IsBTMemSlow; 144201360Srdivacky 145206083Srdivacky /// IsUAMemFast - True if unaligned memory access is fast. 146206083Srdivacky bool IsUAMemFast; 147206083Srdivacky 148204642Srdivacky /// HasVectorUAMem - True if SIMD operations can have unaligned memory 149207618Srdivacky /// operands. This may require setting a feature bit in the processor. 150202375Srdivacky bool HasVectorUAMem; 151202375Srdivacky 152226633Sdim /// HasCmpxchg16b - True if this processor has the CMPXCHG16B instruction; 153226633Sdim /// this is true for most x86-64 chips, but not the first AMD chips. 154226633Sdim bool HasCmpxchg16b; 155226633Sdim 156234353Sdim /// UseLeaForSP - True if the LEA instruction should be used for adjusting 157234353Sdim /// the stack pointer. This is an optimization for Intel Atom processors. 158234353Sdim bool UseLeaForSP; 159234353Sdim 160243830Sdim /// HasSlowDivide - True if smaller divides are significantly faster than 161243830Sdim /// full divides and should be used when possible. 162243830Sdim bool HasSlowDivide; 163243830Sdim 164234353Sdim /// PostRAScheduler - True if using post-register-allocation scheduler. 165234353Sdim bool PostRAScheduler; 166234353Sdim 167249423Sdim /// PadShortFunctions - True if the short functions should be padded to prevent 168249423Sdim /// a stall when returning too early. 169249423Sdim bool PadShortFunctions; 170249423Sdim 171249423Sdim /// CallRegIndirect - True if the Calls with memory reference should be converted 172249423Sdim /// to a register-based indirect call. 173249423Sdim bool CallRegIndirect; 174251662Sdim /// LEAUsesAG - True if the LEA instruction inputs have to be ready at 175251662Sdim /// address generation (AG) time. 176251662Sdim bool LEAUsesAG; 177249423Sdim 178263508Sdim /// Processor has AVX-512 PreFetch Instructions 179263508Sdim bool HasPFI; 180263508Sdim 181263508Sdim /// Processor has AVX-512 Exponential and Reciprocal Instructions 182263508Sdim bool HasERI; 183263508Sdim 184263508Sdim /// Processor has AVX-512 Conflict Detection Instructions 185263508Sdim bool HasCDI; 186263508Sdim 187193323Sed /// stackAlignment - The minimum alignment known to hold of the stack frame on 188193323Sed /// entry to the function and which must be maintained by every function. 189193323Sed unsigned stackAlignment; 190193323Sed 191193323Sed /// Max. memset / memcpy size that is turned into rep/movs, rep/stos ops. 192193323Sed /// 193193323Sed unsigned MaxInlineSizeThreshold; 194218893Sdim 195210299Sed /// TargetTriple - What processor and OS we're targeting. 196210299Sed Triple TargetTriple; 197239462Sdim 198234353Sdim /// Instruction itineraries for scheduling 199234353Sdim InstrItineraryData InstrItins; 200193323Sed 201193323Sedprivate: 202249423Sdim /// StackAlignOverride - Override the stack alignment. 203249423Sdim unsigned StackAlignOverride; 204249423Sdim 205224145Sdim /// In64BitMode - True if compiling for 64-bit, false for 32-bit. 206224145Sdim bool In64BitMode; 207193323Sed 208193323Sedpublic: 209193323Sed /// This constructor initializes the data members to match that 210198090Srdivacky /// of the specified triple. 211193323Sed /// 212224145Sdim X86Subtarget(const std::string &TT, const std::string &CPU, 213224145Sdim const std::string &FS, 214224145Sdim unsigned StackAlignOverride, bool is64Bit); 215193323Sed 216193323Sed /// getStackAlignment - Returns the minimum alignment known to hold of the 217193323Sed /// stack frame on entry to the function and which must be maintained by every 218193323Sed /// function for this subtarget. 219193323Sed unsigned getStackAlignment() const { return stackAlignment; } 220193323Sed 221193323Sed /// getMaxInlineSizeThreshold - Returns the maximum memset / memcpy size 222193323Sed /// that still makes it profitable to inline the call. 223193323Sed unsigned getMaxInlineSizeThreshold() const { return MaxInlineSizeThreshold; } 224193323Sed 225193323Sed /// ParseSubtargetFeatures - Parses features string setting specified 226193323Sed /// subtarget options. Definition of function is auto generated by tblgen. 227224145Sdim void ParseSubtargetFeatures(StringRef CPU, StringRef FS); 228193323Sed 229193323Sed /// AutoDetectSubtargetFeatures - Auto-detect CPU features using CPUID 230193323Sed /// instruction. 231193323Sed void AutoDetectSubtargetFeatures(); 232193323Sed 233249423Sdim /// \brief Reset the features for the X86 target. 234249423Sdim virtual void resetSubtargetFeatures(const MachineFunction *MF); 235249423Sdimprivate: 236249423Sdim void initializeEnvironment(); 237249423Sdim void resetSubtargetFeatures(StringRef CPU, StringRef FS); 238249423Sdimpublic: 239249423Sdim /// Is this x86_64? (disregarding specific ABI / programming model) 240249423Sdim bool is64Bit() const { 241249423Sdim return In64BitMode; 242249423Sdim } 243193323Sed 244249423Sdim /// Is this x86_64 with the ILP32 programming model (x32 ABI)? 245249423Sdim bool isTarget64BitILP32() const { 246249423Sdim return In64BitMode && (TargetTriple.getEnvironment() == Triple::GNUX32); 247249423Sdim } 248249423Sdim 249249423Sdim /// Is this x86_64 with the LP64 programming model (standard AMD64, no x32)? 250249423Sdim bool isTarget64BitLP64() const { 251249423Sdim return In64BitMode && (TargetTriple.getEnvironment() != Triple::GNUX32); 252249423Sdim } 253249423Sdim 254193323Sed PICStyles::Style getPICStyle() const { return PICStyle; } 255193323Sed void setPICStyle(PICStyles::Style Style) { PICStyle = Style; } 256193323Sed 257205218Srdivacky bool hasCMov() const { return HasCMov; } 258193323Sed bool hasMMX() const { return X86SSELevel >= MMX; } 259193323Sed bool hasSSE1() const { return X86SSELevel >= SSE1; } 260193323Sed bool hasSSE2() const { return X86SSELevel >= SSE2; } 261193323Sed bool hasSSE3() const { return X86SSELevel >= SSE3; } 262193323Sed bool hasSSSE3() const { return X86SSELevel >= SSSE3; } 263193323Sed bool hasSSE41() const { return X86SSELevel >= SSE41; } 264193323Sed bool hasSSE42() const { return X86SSELevel >= SSE42; } 265234353Sdim bool hasAVX() const { return X86SSELevel >= AVX; } 266234353Sdim bool hasAVX2() const { return X86SSELevel >= AVX2; } 267263508Sdim bool hasAVX512() const { return X86SSELevel >= AVX512F; } 268249423Sdim bool hasFp256() const { return hasAVX(); } 269249423Sdim bool hasInt256() const { return hasAVX2(); } 270193323Sed bool hasSSE4A() const { return HasSSE4A; } 271193323Sed bool has3DNow() const { return X863DNowLevel >= ThreeDNow; } 272193323Sed bool has3DNowA() const { return X863DNowLevel >= ThreeDNowA; } 273218893Sdim bool hasPOPCNT() const { return HasPOPCNT; } 274206124Srdivacky bool hasAES() const { return HasAES; } 275239462Sdim bool hasPCLMUL() const { return HasPCLMUL; } 276239462Sdim bool hasFMA() const { return HasFMA; } 277243830Sdim // FIXME: Favor FMA when both are enabled. Is this the right thing to do? 278243830Sdim bool hasFMA4() const { return HasFMA4 && !HasFMA; } 279234353Sdim bool hasXOP() const { return HasXOP; } 280263508Sdim bool hasTBM() const { return HasTBM; } 281226633Sdim bool hasMOVBE() const { return HasMOVBE; } 282226633Sdim bool hasRDRAND() const { return HasRDRAND; } 283226633Sdim bool hasF16C() const { return HasF16C; } 284234353Sdim bool hasFSGSBase() const { return HasFSGSBase; } 285226633Sdim bool hasLZCNT() const { return HasLZCNT; } 286226633Sdim bool hasBMI() const { return HasBMI; } 287234353Sdim bool hasBMI2() const { return HasBMI2; } 288243830Sdim bool hasRTM() const { return HasRTM; } 289249423Sdim bool hasHLE() const { return HasHLE; } 290249423Sdim bool hasADX() const { return HasADX; } 291263508Sdim bool hasSHA() const { return HasSHA; } 292249423Sdim bool hasPRFCHW() const { return HasPRFCHW; } 293249423Sdim bool hasRDSEED() const { return HasRDSEED; } 294193323Sed bool isBTMemSlow() const { return IsBTMemSlow; } 295206083Srdivacky bool isUnalignedMemAccessFast() const { return IsUAMemFast; } 296202375Srdivacky bool hasVectorUAMem() const { return HasVectorUAMem; } 297226633Sdim bool hasCmpxchg16b() const { return HasCmpxchg16b; } 298234353Sdim bool useLeaForSP() const { return UseLeaForSP; } 299243830Sdim bool hasSlowDivide() const { return HasSlowDivide; } 300249423Sdim bool padShortFunctions() const { return PadShortFunctions; } 301249423Sdim bool callRegIndirect() const { return CallRegIndirect; } 302251662Sdim bool LEAusesAG() const { return LEAUsesAG; } 303263508Sdim bool hasCDI() const { return HasCDI; } 304263508Sdim bool hasPFI() const { return HasPFI; } 305263508Sdim bool hasERI() const { return HasERI; } 306193323Sed 307234353Sdim bool isAtom() const { return X86ProcFamily == IntelAtom; } 308234353Sdim 309221345Sdim const Triple &getTargetTriple() const { return TargetTriple; } 310218893Sdim 311221345Sdim bool isTargetDarwin() const { return TargetTriple.isOSDarwin(); } 312221345Sdim bool isTargetFreeBSD() const { 313221345Sdim return TargetTriple.getOS() == Triple::FreeBSD; 314221345Sdim } 315221345Sdim bool isTargetSolaris() const { 316221345Sdim return TargetTriple.getOS() == Triple::Solaris; 317221345Sdim } 318243830Sdim bool isTargetELF() const { 319243830Sdim return (TargetTriple.getEnvironment() == Triple::ELF || 320243830Sdim TargetTriple.isOSBinFormatELF()); 321243830Sdim } 322263508Sdim bool isTargetLinux() const { return TargetTriple.isOSLinux(); } 323263508Sdim bool isTargetNaCl() const { return TargetTriple.isOSNaCl(); } 324226633Sdim bool isTargetNaCl32() const { return isTargetNaCl() && !is64Bit(); } 325226633Sdim bool isTargetNaCl64() const { return isTargetNaCl() && is64Bit(); } 326210299Sed bool isTargetWindows() const { return TargetTriple.getOS() == Triple::Win32; } 327218893Sdim bool isTargetMingw() const { return TargetTriple.getOS() == Triple::MinGW32; } 328210299Sed bool isTargetCygwin() const { return TargetTriple.getOS() == Triple::Cygwin; } 329234353Sdim bool isTargetCygMing() const { return TargetTriple.isOSCygMing(); } 330243830Sdim bool isTargetCOFF() const { 331243830Sdim return (TargetTriple.getEnvironment() != Triple::ELF && 332243830Sdim TargetTriple.isOSBinFormatCOFF()); 333243830Sdim } 334234353Sdim bool isTargetEnvMacho() const { return TargetTriple.isEnvironmentMachO(); } 335218893Sdim 336263508Sdim bool isOSWindows() const { return TargetTriple.isOSWindows(); } 337263508Sdim 338193323Sed bool isTargetWin64() const { 339234353Sdim return In64BitMode && TargetTriple.isOSWindows(); 340193323Sed } 341193323Sed 342212904Sdim bool isTargetWin32() const { 343263508Sdim return !In64BitMode && (isTargetCygMing() || isTargetWindows()); 344212904Sdim } 345212904Sdim 346193323Sed bool isPICStyleSet() const { return PICStyle != PICStyles::None; } 347193323Sed bool isPICStyleGOT() const { return PICStyle == PICStyles::GOT; } 348193323Sed bool isPICStyleRIPRel() const { return PICStyle == PICStyles::RIPRel; } 349198090Srdivacky 350198090Srdivacky bool isPICStyleStubPIC() const { 351198090Srdivacky return PICStyle == PICStyles::StubPIC; 352198090Srdivacky } 353198090Srdivacky 354198090Srdivacky bool isPICStyleStubNoDynamic() const { 355198090Srdivacky return PICStyle == PICStyles::StubDynamicNoPIC; 356198090Srdivacky } 357198090Srdivacky bool isPICStyleStubAny() const { 358198090Srdivacky return PICStyle == PICStyles::StubDynamicNoPIC || 359256030Sdim PICStyle == PICStyles::StubPIC; 360256030Sdim } 361204642Srdivacky 362256030Sdim bool isCallingConvWin64(CallingConv::ID CC) const { 363256030Sdim return (isTargetWin64() && CC != CallingConv::X86_64_SysV) || 364256030Sdim CC == CallingConv::X86_64_Win64; 365256030Sdim } 366256030Sdim 367198090Srdivacky /// ClassifyGlobalReference - Classify a global variable reference for the 368198090Srdivacky /// current subtarget according to how we should reference it in a non-pcrel 369198090Srdivacky /// context. 370198090Srdivacky unsigned char ClassifyGlobalReference(const GlobalValue *GV, 371198090Srdivacky const TargetMachine &TM)const; 372193323Sed 373199989Srdivacky /// ClassifyBlockAddressReference - Classify a blockaddress reference for the 374199989Srdivacky /// current subtarget according to how we should reference it in a non-pcrel 375199989Srdivacky /// context. 376199989Srdivacky unsigned char ClassifyBlockAddressReference() const; 377199989Srdivacky 378193323Sed /// IsLegalToCallImmediateAddr - Return true if the subtarget allows calls 379193323Sed /// to immediate address. 380193323Sed bool IsLegalToCallImmediateAddr(const TargetMachine &TM) const; 381193323Sed 382193323Sed /// This function returns the name of a function which has an interface 383193323Sed /// like the non-standard bzero function, if such a function exists on 384193323Sed /// the current subtarget and it is considered prefereable over 385193323Sed /// memset with zero passed as the second argument. Otherwise it 386193323Sed /// returns null. 387193323Sed const char *getBZeroEntry() const; 388263508Sdim 389249423Sdim /// This function returns true if the target has sincos() routine in its 390249423Sdim /// compiler runtime or math libraries. 391249423Sdim bool hasSinCos() const; 392193323Sed 393263508Sdim /// Enable the MachineScheduler pass for all X86 subtargets. 394263508Sdim bool enableMachineScheduler() const LLVM_OVERRIDE { return true; } 395263508Sdim 396234353Sdim /// enablePostRAScheduler - run for Atom optimization. 397234353Sdim bool enablePostRAScheduler(CodeGenOpt::Level OptLevel, 398234353Sdim TargetSubtargetInfo::AntiDepBreakMode& Mode, 399234353Sdim RegClassVector& CriticalPathRCs) const; 400234353Sdim 401239462Sdim bool postRAScheduler() const { return PostRAScheduler; } 402239462Sdim 403234353Sdim /// getInstrItins = Return the instruction itineraries based on the 404234353Sdim /// subtarget selection. 405234353Sdim const InstrItineraryData &getInstrItineraryData() const { return InstrItins; } 406193323Sed}; 407193323Sed 408193323Sed} // End llvm namespace 409193323Sed 410193323Sed#endif 411