X86Subtarget.h revision 251662
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 { 45234353Sdim NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42, AVX, AVX2 46193323Sed }; 47193323Sed 48193323Sed enum X863DNowEnum { 49193323Sed NoThreeDNow, ThreeDNow, ThreeDNowA 50193323Sed }; 51193323Sed 52234353Sdim enum X86ProcFamilyEnum { 53234353Sdim Others, IntelAtom 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 100226633Sdim /// HasMOVBE - True if the processor has the MOVBE instruction. 101226633Sdim bool HasMOVBE; 102226633Sdim 103226633Sdim /// HasRDRAND - True if the processor has the RDRAND instruction. 104226633Sdim bool HasRDRAND; 105226633Sdim 106226633Sdim /// HasF16C - Processor has 16-bit floating point conversion instructions. 107226633Sdim bool HasF16C; 108226633Sdim 109234353Sdim /// HasFSGSBase - Processor has FS/GS base insturctions. 110234353Sdim bool HasFSGSBase; 111234353Sdim 112226633Sdim /// HasLZCNT - Processor has LZCNT instruction. 113226633Sdim bool HasLZCNT; 114226633Sdim 115226633Sdim /// HasBMI - Processor has BMI1 instructions. 116226633Sdim bool HasBMI; 117226633Sdim 118234353Sdim /// HasBMI2 - Processor has BMI2 instructions. 119234353Sdim bool HasBMI2; 120234353Sdim 121243830Sdim /// HasRTM - Processor has RTM instructions. 122243830Sdim bool HasRTM; 123243830Sdim 124249423Sdim /// HasHLE - Processor has HLE. 125249423Sdim bool HasHLE; 126249423Sdim 127249423Sdim /// HasADX - Processor has ADX instructions. 128249423Sdim bool HasADX; 129249423Sdim 130249423Sdim /// HasPRFCHW - Processor has PRFCHW instructions. 131249423Sdim bool HasPRFCHW; 132249423Sdim 133249423Sdim /// HasRDSEED - Processor has RDSEED instructions. 134249423Sdim bool HasRDSEED; 135249423Sdim 136193323Sed /// IsBTMemSlow - True if BT (bit test) of memory instructions are slow. 137193323Sed bool IsBTMemSlow; 138201360Srdivacky 139206083Srdivacky /// IsUAMemFast - True if unaligned memory access is fast. 140206083Srdivacky bool IsUAMemFast; 141206083Srdivacky 142204642Srdivacky /// HasVectorUAMem - True if SIMD operations can have unaligned memory 143207618Srdivacky /// operands. This may require setting a feature bit in the processor. 144202375Srdivacky bool HasVectorUAMem; 145202375Srdivacky 146226633Sdim /// HasCmpxchg16b - True if this processor has the CMPXCHG16B instruction; 147226633Sdim /// this is true for most x86-64 chips, but not the first AMD chips. 148226633Sdim bool HasCmpxchg16b; 149226633Sdim 150234353Sdim /// UseLeaForSP - True if the LEA instruction should be used for adjusting 151234353Sdim /// the stack pointer. This is an optimization for Intel Atom processors. 152234353Sdim bool UseLeaForSP; 153234353Sdim 154243830Sdim /// HasSlowDivide - True if smaller divides are significantly faster than 155243830Sdim /// full divides and should be used when possible. 156243830Sdim bool HasSlowDivide; 157243830Sdim 158234353Sdim /// PostRAScheduler - True if using post-register-allocation scheduler. 159234353Sdim bool PostRAScheduler; 160234353Sdim 161249423Sdim /// PadShortFunctions - True if the short functions should be padded to prevent 162249423Sdim /// a stall when returning too early. 163249423Sdim bool PadShortFunctions; 164249423Sdim 165249423Sdim /// CallRegIndirect - True if the Calls with memory reference should be converted 166249423Sdim /// to a register-based indirect call. 167249423Sdim bool CallRegIndirect; 168251662Sdim /// LEAUsesAG - True if the LEA instruction inputs have to be ready at 169251662Sdim /// address generation (AG) time. 170251662Sdim bool LEAUsesAG; 171249423Sdim 172193323Sed /// stackAlignment - The minimum alignment known to hold of the stack frame on 173193323Sed /// entry to the function and which must be maintained by every function. 174193323Sed unsigned stackAlignment; 175193323Sed 176193323Sed /// Max. memset / memcpy size that is turned into rep/movs, rep/stos ops. 177193323Sed /// 178193323Sed unsigned MaxInlineSizeThreshold; 179218893Sdim 180210299Sed /// TargetTriple - What processor and OS we're targeting. 181210299Sed Triple TargetTriple; 182239462Sdim 183234353Sdim /// Instruction itineraries for scheduling 184234353Sdim InstrItineraryData InstrItins; 185193323Sed 186193323Sedprivate: 187249423Sdim /// StackAlignOverride - Override the stack alignment. 188249423Sdim unsigned StackAlignOverride; 189249423Sdim 190224145Sdim /// In64BitMode - True if compiling for 64-bit, false for 32-bit. 191224145Sdim bool In64BitMode; 192193323Sed 193193323Sedpublic: 194193323Sed /// This constructor initializes the data members to match that 195198090Srdivacky /// of the specified triple. 196193323Sed /// 197224145Sdim X86Subtarget(const std::string &TT, const std::string &CPU, 198224145Sdim const std::string &FS, 199224145Sdim unsigned StackAlignOverride, bool is64Bit); 200193323Sed 201193323Sed /// getStackAlignment - Returns the minimum alignment known to hold of the 202193323Sed /// stack frame on entry to the function and which must be maintained by every 203193323Sed /// function for this subtarget. 204193323Sed unsigned getStackAlignment() const { return stackAlignment; } 205193323Sed 206193323Sed /// getMaxInlineSizeThreshold - Returns the maximum memset / memcpy size 207193323Sed /// that still makes it profitable to inline the call. 208193323Sed unsigned getMaxInlineSizeThreshold() const { return MaxInlineSizeThreshold; } 209193323Sed 210193323Sed /// ParseSubtargetFeatures - Parses features string setting specified 211193323Sed /// subtarget options. Definition of function is auto generated by tblgen. 212224145Sdim void ParseSubtargetFeatures(StringRef CPU, StringRef FS); 213193323Sed 214193323Sed /// AutoDetectSubtargetFeatures - Auto-detect CPU features using CPUID 215193323Sed /// instruction. 216193323Sed void AutoDetectSubtargetFeatures(); 217193323Sed 218249423Sdim /// \brief Reset the features for the X86 target. 219249423Sdim virtual void resetSubtargetFeatures(const MachineFunction *MF); 220249423Sdimprivate: 221249423Sdim void initializeEnvironment(); 222249423Sdim void resetSubtargetFeatures(StringRef CPU, StringRef FS); 223249423Sdimpublic: 224249423Sdim /// Is this x86_64? (disregarding specific ABI / programming model) 225249423Sdim bool is64Bit() const { 226249423Sdim return In64BitMode; 227249423Sdim } 228193323Sed 229249423Sdim /// Is this x86_64 with the ILP32 programming model (x32 ABI)? 230249423Sdim bool isTarget64BitILP32() const { 231249423Sdim return In64BitMode && (TargetTriple.getEnvironment() == Triple::GNUX32); 232249423Sdim } 233249423Sdim 234249423Sdim /// Is this x86_64 with the LP64 programming model (standard AMD64, no x32)? 235249423Sdim bool isTarget64BitLP64() const { 236249423Sdim return In64BitMode && (TargetTriple.getEnvironment() != Triple::GNUX32); 237249423Sdim } 238249423Sdim 239193323Sed PICStyles::Style getPICStyle() const { return PICStyle; } 240193323Sed void setPICStyle(PICStyles::Style Style) { PICStyle = Style; } 241193323Sed 242205218Srdivacky bool hasCMov() const { return HasCMov; } 243193323Sed bool hasMMX() const { return X86SSELevel >= MMX; } 244193323Sed bool hasSSE1() const { return X86SSELevel >= SSE1; } 245193323Sed bool hasSSE2() const { return X86SSELevel >= SSE2; } 246193323Sed bool hasSSE3() const { return X86SSELevel >= SSE3; } 247193323Sed bool hasSSSE3() const { return X86SSELevel >= SSSE3; } 248193323Sed bool hasSSE41() const { return X86SSELevel >= SSE41; } 249193323Sed bool hasSSE42() const { return X86SSELevel >= SSE42; } 250234353Sdim bool hasAVX() const { return X86SSELevel >= AVX; } 251234353Sdim bool hasAVX2() const { return X86SSELevel >= AVX2; } 252249423Sdim bool hasFp256() const { return hasAVX(); } 253249423Sdim bool hasInt256() const { return hasAVX2(); } 254193323Sed bool hasSSE4A() const { return HasSSE4A; } 255193323Sed bool has3DNow() const { return X863DNowLevel >= ThreeDNow; } 256193323Sed bool has3DNowA() const { return X863DNowLevel >= ThreeDNowA; } 257218893Sdim bool hasPOPCNT() const { return HasPOPCNT; } 258206124Srdivacky bool hasAES() const { return HasAES; } 259239462Sdim bool hasPCLMUL() const { return HasPCLMUL; } 260239462Sdim bool hasFMA() const { return HasFMA; } 261243830Sdim // FIXME: Favor FMA when both are enabled. Is this the right thing to do? 262243830Sdim bool hasFMA4() const { return HasFMA4 && !HasFMA; } 263234353Sdim bool hasXOP() const { return HasXOP; } 264226633Sdim bool hasMOVBE() const { return HasMOVBE; } 265226633Sdim bool hasRDRAND() const { return HasRDRAND; } 266226633Sdim bool hasF16C() const { return HasF16C; } 267234353Sdim bool hasFSGSBase() const { return HasFSGSBase; } 268226633Sdim bool hasLZCNT() const { return HasLZCNT; } 269226633Sdim bool hasBMI() const { return HasBMI; } 270234353Sdim bool hasBMI2() const { return HasBMI2; } 271243830Sdim bool hasRTM() const { return HasRTM; } 272249423Sdim bool hasHLE() const { return HasHLE; } 273249423Sdim bool hasADX() const { return HasADX; } 274249423Sdim bool hasPRFCHW() const { return HasPRFCHW; } 275249423Sdim bool hasRDSEED() const { return HasRDSEED; } 276193323Sed bool isBTMemSlow() const { return IsBTMemSlow; } 277206083Srdivacky bool isUnalignedMemAccessFast() const { return IsUAMemFast; } 278202375Srdivacky bool hasVectorUAMem() const { return HasVectorUAMem; } 279226633Sdim bool hasCmpxchg16b() const { return HasCmpxchg16b; } 280234353Sdim bool useLeaForSP() const { return UseLeaForSP; } 281243830Sdim bool hasSlowDivide() const { return HasSlowDivide; } 282249423Sdim bool padShortFunctions() const { return PadShortFunctions; } 283249423Sdim bool callRegIndirect() const { return CallRegIndirect; } 284251662Sdim bool LEAusesAG() const { return LEAUsesAG; } 285193323Sed 286234353Sdim bool isAtom() const { return X86ProcFamily == IntelAtom; } 287234353Sdim 288221345Sdim const Triple &getTargetTriple() const { return TargetTriple; } 289218893Sdim 290221345Sdim bool isTargetDarwin() const { return TargetTriple.isOSDarwin(); } 291221345Sdim bool isTargetFreeBSD() const { 292221345Sdim return TargetTriple.getOS() == Triple::FreeBSD; 293221345Sdim } 294221345Sdim bool isTargetSolaris() const { 295221345Sdim return TargetTriple.getOS() == Triple::Solaris; 296221345Sdim } 297243830Sdim bool isTargetELF() const { 298243830Sdim return (TargetTriple.getEnvironment() == Triple::ELF || 299243830Sdim TargetTriple.isOSBinFormatELF()); 300243830Sdim } 301210299Sed bool isTargetLinux() const { return TargetTriple.getOS() == Triple::Linux; } 302226633Sdim bool isTargetNaCl() const { 303249423Sdim return TargetTriple.getOS() == Triple::NaCl; 304226633Sdim } 305226633Sdim bool isTargetNaCl32() const { return isTargetNaCl() && !is64Bit(); } 306226633Sdim bool isTargetNaCl64() const { return isTargetNaCl() && is64Bit(); } 307210299Sed bool isTargetWindows() const { return TargetTriple.getOS() == Triple::Win32; } 308218893Sdim bool isTargetMingw() const { return TargetTriple.getOS() == Triple::MinGW32; } 309210299Sed bool isTargetCygwin() const { return TargetTriple.getOS() == Triple::Cygwin; } 310234353Sdim bool isTargetCygMing() const { return TargetTriple.isOSCygMing(); } 311243830Sdim bool isTargetCOFF() const { 312243830Sdim return (TargetTriple.getEnvironment() != Triple::ELF && 313243830Sdim TargetTriple.isOSBinFormatCOFF()); 314243830Sdim } 315234353Sdim bool isTargetEnvMacho() const { return TargetTriple.isEnvironmentMachO(); } 316218893Sdim 317193323Sed bool isTargetWin64() const { 318226633Sdim // FIXME: x86_64-cygwin has not been released yet. 319234353Sdim return In64BitMode && TargetTriple.isOSWindows(); 320193323Sed } 321193323Sed 322212904Sdim bool isTargetWin32() const { 323234353Sdim // FIXME: Cygwin is included for isTargetWin64 -- should it be included 324234353Sdim // here too? 325224145Sdim return !In64BitMode && (isTargetMingw() || isTargetWindows()); 326212904Sdim } 327212904Sdim 328193323Sed bool isPICStyleSet() const { return PICStyle != PICStyles::None; } 329193323Sed bool isPICStyleGOT() const { return PICStyle == PICStyles::GOT; } 330193323Sed bool isPICStyleRIPRel() const { return PICStyle == PICStyles::RIPRel; } 331198090Srdivacky 332198090Srdivacky bool isPICStyleStubPIC() const { 333198090Srdivacky return PICStyle == PICStyles::StubPIC; 334198090Srdivacky } 335198090Srdivacky 336198090Srdivacky bool isPICStyleStubNoDynamic() const { 337198090Srdivacky return PICStyle == PICStyles::StubDynamicNoPIC; 338198090Srdivacky } 339198090Srdivacky bool isPICStyleStubAny() const { 340198090Srdivacky return PICStyle == PICStyles::StubDynamicNoPIC || 341198090Srdivacky PICStyle == PICStyles::StubPIC; } 342204642Srdivacky 343198090Srdivacky /// ClassifyGlobalReference - Classify a global variable reference for the 344198090Srdivacky /// current subtarget according to how we should reference it in a non-pcrel 345198090Srdivacky /// context. 346198090Srdivacky unsigned char ClassifyGlobalReference(const GlobalValue *GV, 347198090Srdivacky const TargetMachine &TM)const; 348193323Sed 349199989Srdivacky /// ClassifyBlockAddressReference - Classify a blockaddress reference for the 350199989Srdivacky /// current subtarget according to how we should reference it in a non-pcrel 351199989Srdivacky /// context. 352199989Srdivacky unsigned char ClassifyBlockAddressReference() const; 353199989Srdivacky 354193323Sed /// IsLegalToCallImmediateAddr - Return true if the subtarget allows calls 355193323Sed /// to immediate address. 356193323Sed bool IsLegalToCallImmediateAddr(const TargetMachine &TM) const; 357193323Sed 358193323Sed /// This function returns the name of a function which has an interface 359193323Sed /// like the non-standard bzero function, if such a function exists on 360193323Sed /// the current subtarget and it is considered prefereable over 361193323Sed /// memset with zero passed as the second argument. Otherwise it 362193323Sed /// returns null. 363193323Sed const char *getBZeroEntry() const; 364249423Sdim 365249423Sdim /// This function returns true if the target has sincos() routine in its 366249423Sdim /// compiler runtime or math libraries. 367249423Sdim bool hasSinCos() const; 368193323Sed 369234353Sdim /// enablePostRAScheduler - run for Atom optimization. 370234353Sdim bool enablePostRAScheduler(CodeGenOpt::Level OptLevel, 371234353Sdim TargetSubtargetInfo::AntiDepBreakMode& Mode, 372234353Sdim RegClassVector& CriticalPathRCs) const; 373234353Sdim 374239462Sdim bool postRAScheduler() const { return PostRAScheduler; } 375239462Sdim 376234353Sdim /// getInstrItins = Return the instruction itineraries based on the 377234353Sdim /// subtarget selection. 378234353Sdim const InstrItineraryData &getInstrItineraryData() const { return InstrItins; } 379193323Sed}; 380193323Sed 381193323Sed} // End llvm namespace 382193323Sed 383193323Sed#endif 384