LLVM API Documentation
00001 //===-- X86Subtarget.h - Define Subtarget for the X86 ----------*- C++ -*--===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file declares the X86 specific subclass of TargetSubtargetInfo. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_LIB_TARGET_X86_X86SUBTARGET_H 00015 #define LLVM_LIB_TARGET_X86_X86SUBTARGET_H 00016 00017 #include "X86FrameLowering.h" 00018 #include "X86ISelLowering.h" 00019 #include "X86InstrInfo.h" 00020 #include "X86SelectionDAGInfo.h" 00021 #include "llvm/ADT/Triple.h" 00022 #include "llvm/IR/CallingConv.h" 00023 #include "llvm/Target/TargetSubtargetInfo.h" 00024 #include <string> 00025 00026 #define GET_SUBTARGETINFO_HEADER 00027 #include "X86GenSubtargetInfo.inc" 00028 00029 namespace llvm { 00030 class GlobalValue; 00031 class StringRef; 00032 class TargetMachine; 00033 00034 /// PICStyles - The X86 backend supports a number of different styles of PIC. 00035 /// 00036 namespace PICStyles { 00037 enum Style { 00038 StubPIC, // Used on i386-darwin in -fPIC mode. 00039 StubDynamicNoPIC, // Used on i386-darwin in -mdynamic-no-pic mode. 00040 GOT, // Used on many 32-bit unices in -fPIC mode. 00041 RIPRel, // Used on X86-64 when not in -static mode. 00042 None // Set when in -static mode (not PIC or DynamicNoPIC mode). 00043 }; 00044 } 00045 00046 class X86Subtarget final : public X86GenSubtargetInfo { 00047 00048 protected: 00049 enum X86SSEEnum { 00050 NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42, AVX, AVX2, AVX512F 00051 }; 00052 00053 enum X863DNowEnum { 00054 NoThreeDNow, ThreeDNow, ThreeDNowA 00055 }; 00056 00057 enum X86ProcFamilyEnum { 00058 Others, IntelAtom, IntelSLM 00059 }; 00060 00061 /// X86ProcFamily - X86 processor family: Intel Atom, and others 00062 X86ProcFamilyEnum X86ProcFamily; 00063 00064 /// PICStyle - Which PIC style to use 00065 /// 00066 PICStyles::Style PICStyle; 00067 00068 /// X86SSELevel - MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42, or 00069 /// none supported. 00070 X86SSEEnum X86SSELevel; 00071 00072 /// X863DNowLevel - 3DNow or 3DNow Athlon, or none supported. 00073 /// 00074 X863DNowEnum X863DNowLevel; 00075 00076 /// HasCMov - True if this processor has conditional move instructions 00077 /// (generally pentium pro+). 00078 bool HasCMov; 00079 00080 /// HasX86_64 - True if the processor supports X86-64 instructions. 00081 /// 00082 bool HasX86_64; 00083 00084 /// HasPOPCNT - True if the processor supports POPCNT. 00085 bool HasPOPCNT; 00086 00087 /// HasSSE4A - True if the processor supports SSE4A instructions. 00088 bool HasSSE4A; 00089 00090 /// HasAES - Target has AES instructions 00091 bool HasAES; 00092 00093 /// HasPCLMUL - Target has carry-less multiplication 00094 bool HasPCLMUL; 00095 00096 /// HasFMA - Target has 3-operand fused multiply-add 00097 bool HasFMA; 00098 00099 /// HasFMA4 - Target has 4-operand fused multiply-add 00100 bool HasFMA4; 00101 00102 /// HasXOP - Target has XOP instructions 00103 bool HasXOP; 00104 00105 /// HasTBM - Target has TBM instructions. 00106 bool HasTBM; 00107 00108 /// HasMOVBE - True if the processor has the MOVBE instruction. 00109 bool HasMOVBE; 00110 00111 /// HasRDRAND - True if the processor has the RDRAND instruction. 00112 bool HasRDRAND; 00113 00114 /// HasF16C - Processor has 16-bit floating point conversion instructions. 00115 bool HasF16C; 00116 00117 /// HasFSGSBase - Processor has FS/GS base insturctions. 00118 bool HasFSGSBase; 00119 00120 /// HasLZCNT - Processor has LZCNT instruction. 00121 bool HasLZCNT; 00122 00123 /// HasBMI - Processor has BMI1 instructions. 00124 bool HasBMI; 00125 00126 /// HasBMI2 - Processor has BMI2 instructions. 00127 bool HasBMI2; 00128 00129 /// HasRTM - Processor has RTM instructions. 00130 bool HasRTM; 00131 00132 /// HasHLE - Processor has HLE. 00133 bool HasHLE; 00134 00135 /// HasADX - Processor has ADX instructions. 00136 bool HasADX; 00137 00138 /// HasSHA - Processor has SHA instructions. 00139 bool HasSHA; 00140 00141 /// HasSGX - Processor has SGX instructions. 00142 bool HasSGX; 00143 00144 /// HasPRFCHW - Processor has PRFCHW instructions. 00145 bool HasPRFCHW; 00146 00147 /// HasRDSEED - Processor has RDSEED instructions. 00148 bool HasRDSEED; 00149 00150 /// HasSMAP - Processor has SMAP instructions. 00151 bool HasSMAP; 00152 00153 /// IsBTMemSlow - True if BT (bit test) of memory instructions are slow. 00154 bool IsBTMemSlow; 00155 00156 /// IsSHLDSlow - True if SHLD instructions are slow. 00157 bool IsSHLDSlow; 00158 00159 /// IsUAMemFast - True if unaligned memory access is fast. 00160 bool IsUAMemFast; 00161 00162 /// HasVectorUAMem - True if SIMD operations can have unaligned memory 00163 /// operands. This may require setting a feature bit in the processor. 00164 bool HasVectorUAMem; 00165 00166 /// HasCmpxchg16b - True if this processor has the CMPXCHG16B instruction; 00167 /// this is true for most x86-64 chips, but not the first AMD chips. 00168 bool HasCmpxchg16b; 00169 00170 /// UseLeaForSP - True if the LEA instruction should be used for adjusting 00171 /// the stack pointer. This is an optimization for Intel Atom processors. 00172 bool UseLeaForSP; 00173 00174 /// HasSlowDivide - True if smaller divides are significantly faster than 00175 /// full divides and should be used when possible. 00176 bool HasSlowDivide; 00177 00178 /// PadShortFunctions - True if the short functions should be padded to prevent 00179 /// a stall when returning too early. 00180 bool PadShortFunctions; 00181 00182 /// CallRegIndirect - True if the Calls with memory reference should be converted 00183 /// to a register-based indirect call. 00184 bool CallRegIndirect; 00185 /// LEAUsesAG - True if the LEA instruction inputs have to be ready at 00186 /// address generation (AG) time. 00187 bool LEAUsesAG; 00188 00189 /// SlowLEA - True if the LEA instruction with certain arguments is slow 00190 bool SlowLEA; 00191 00192 /// SlowIncDec - True if INC and DEC instructions are slow when writing to flags 00193 bool SlowIncDec; 00194 00195 /// Processor has AVX-512 PreFetch Instructions 00196 bool HasPFI; 00197 00198 /// Processor has AVX-512 Exponential and Reciprocal Instructions 00199 bool HasERI; 00200 00201 /// Processor has AVX-512 Conflict Detection Instructions 00202 bool HasCDI; 00203 00204 /// Processor has AVX-512 Doubleword and Quadword instructions 00205 bool HasDQI; 00206 00207 /// Processor has AVX-512 Byte and Word instructions 00208 bool HasBWI; 00209 00210 /// Processor has AVX-512 Vector Length eXtenstions 00211 bool HasVLX; 00212 00213 /// stackAlignment - The minimum alignment known to hold of the stack frame on 00214 /// entry to the function and which must be maintained by every function. 00215 unsigned stackAlignment; 00216 00217 /// Max. memset / memcpy size that is turned into rep/movs, rep/stos ops. 00218 /// 00219 unsigned MaxInlineSizeThreshold; 00220 00221 /// TargetTriple - What processor and OS we're targeting. 00222 Triple TargetTriple; 00223 00224 /// Instruction itineraries for scheduling 00225 InstrItineraryData InstrItins; 00226 00227 private: 00228 // Calculates type size & alignment 00229 const DataLayout DL; 00230 00231 /// StackAlignOverride - Override the stack alignment. 00232 unsigned StackAlignOverride; 00233 00234 /// In64BitMode - True if compiling for 64-bit, false for 16-bit or 32-bit. 00235 bool In64BitMode; 00236 00237 /// In32BitMode - True if compiling for 32-bit, false for 16-bit or 64-bit. 00238 bool In32BitMode; 00239 00240 /// In16BitMode - True if compiling for 16-bit, false for 32-bit or 64-bit. 00241 bool In16BitMode; 00242 00243 X86SelectionDAGInfo TSInfo; 00244 // Ordering here is important. X86InstrInfo initializes X86RegisterInfo which 00245 // X86TargetLowering needs. 00246 X86InstrInfo InstrInfo; 00247 X86TargetLowering TLInfo; 00248 X86FrameLowering FrameLowering; 00249 00250 public: 00251 /// This constructor initializes the data members to match that 00252 /// of the specified triple. 00253 /// 00254 X86Subtarget(const std::string &TT, const std::string &CPU, 00255 const std::string &FS, X86TargetMachine &TM, 00256 unsigned StackAlignOverride); 00257 00258 const X86TargetLowering *getTargetLowering() const override { 00259 return &TLInfo; 00260 } 00261 const X86InstrInfo *getInstrInfo() const override { return &InstrInfo; } 00262 const DataLayout *getDataLayout() const override { return &DL; } 00263 const X86FrameLowering *getFrameLowering() const override { 00264 return &FrameLowering; 00265 } 00266 const X86SelectionDAGInfo *getSelectionDAGInfo() const override { 00267 return &TSInfo; 00268 } 00269 const X86RegisterInfo *getRegisterInfo() const override { 00270 return &getInstrInfo()->getRegisterInfo(); 00271 } 00272 00273 /// getStackAlignment - Returns the minimum alignment known to hold of the 00274 /// stack frame on entry to the function and which must be maintained by every 00275 /// function for this subtarget. 00276 unsigned getStackAlignment() const { return stackAlignment; } 00277 00278 /// getMaxInlineSizeThreshold - Returns the maximum memset / memcpy size 00279 /// that still makes it profitable to inline the call. 00280 unsigned getMaxInlineSizeThreshold() const { return MaxInlineSizeThreshold; } 00281 00282 /// ParseSubtargetFeatures - Parses features string setting specified 00283 /// subtarget options. Definition of function is auto generated by tblgen. 00284 void ParseSubtargetFeatures(StringRef CPU, StringRef FS); 00285 00286 private: 00287 /// \brief Initialize the full set of dependencies so we can use an initializer 00288 /// list for X86Subtarget. 00289 X86Subtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS); 00290 void initializeEnvironment(); 00291 void initSubtargetFeatures(StringRef CPU, StringRef FS); 00292 public: 00293 /// Is this x86_64? (disregarding specific ABI / programming model) 00294 bool is64Bit() const { 00295 return In64BitMode; 00296 } 00297 00298 bool is32Bit() const { 00299 return In32BitMode; 00300 } 00301 00302 bool is16Bit() const { 00303 return In16BitMode; 00304 } 00305 00306 /// Is this x86_64 with the ILP32 programming model (x32 ABI)? 00307 bool isTarget64BitILP32() const { 00308 return In64BitMode && (TargetTriple.getEnvironment() == Triple::GNUX32 || 00309 TargetTriple.getOS() == Triple::NaCl); 00310 } 00311 00312 /// Is this x86_64 with the LP64 programming model (standard AMD64, no x32)? 00313 bool isTarget64BitLP64() const { 00314 return In64BitMode && (TargetTriple.getEnvironment() != Triple::GNUX32 && 00315 TargetTriple.getOS() != Triple::NaCl); 00316 } 00317 00318 PICStyles::Style getPICStyle() const { return PICStyle; } 00319 void setPICStyle(PICStyles::Style Style) { PICStyle = Style; } 00320 00321 bool hasCMov() const { return HasCMov; } 00322 bool hasMMX() const { return X86SSELevel >= MMX; } 00323 bool hasSSE1() const { return X86SSELevel >= SSE1; } 00324 bool hasSSE2() const { return X86SSELevel >= SSE2; } 00325 bool hasSSE3() const { return X86SSELevel >= SSE3; } 00326 bool hasSSSE3() const { return X86SSELevel >= SSSE3; } 00327 bool hasSSE41() const { return X86SSELevel >= SSE41; } 00328 bool hasSSE42() const { return X86SSELevel >= SSE42; } 00329 bool hasAVX() const { return X86SSELevel >= AVX; } 00330 bool hasAVX2() const { return X86SSELevel >= AVX2; } 00331 bool hasAVX512() const { return X86SSELevel >= AVX512F; } 00332 bool hasFp256() const { return hasAVX(); } 00333 bool hasInt256() const { return hasAVX2(); } 00334 bool hasSSE4A() const { return HasSSE4A; } 00335 bool has3DNow() const { return X863DNowLevel >= ThreeDNow; } 00336 bool has3DNowA() const { return X863DNowLevel >= ThreeDNowA; } 00337 bool hasPOPCNT() const { return HasPOPCNT; } 00338 bool hasAES() const { return HasAES; } 00339 bool hasPCLMUL() const { return HasPCLMUL; } 00340 bool hasFMA() const { return HasFMA; } 00341 // FIXME: Favor FMA when both are enabled. Is this the right thing to do? 00342 bool hasFMA4() const { return HasFMA4 && !HasFMA; } 00343 bool hasXOP() const { return HasXOP; } 00344 bool hasTBM() const { return HasTBM; } 00345 bool hasMOVBE() const { return HasMOVBE; } 00346 bool hasRDRAND() const { return HasRDRAND; } 00347 bool hasF16C() const { return HasF16C; } 00348 bool hasFSGSBase() const { return HasFSGSBase; } 00349 bool hasLZCNT() const { return HasLZCNT; } 00350 bool hasBMI() const { return HasBMI; } 00351 bool hasBMI2() const { return HasBMI2; } 00352 bool hasRTM() const { return HasRTM; } 00353 bool hasHLE() const { return HasHLE; } 00354 bool hasADX() const { return HasADX; } 00355 bool hasSHA() const { return HasSHA; } 00356 bool hasSGX() const { return HasSGX; } 00357 bool hasPRFCHW() const { return HasPRFCHW; } 00358 bool hasRDSEED() const { return HasRDSEED; } 00359 bool hasSMAP() const { return HasSMAP; } 00360 bool isBTMemSlow() const { return IsBTMemSlow; } 00361 bool isSHLDSlow() const { return IsSHLDSlow; } 00362 bool isUnalignedMemAccessFast() const { return IsUAMemFast; } 00363 bool hasVectorUAMem() const { return HasVectorUAMem; } 00364 bool hasCmpxchg16b() const { return HasCmpxchg16b; } 00365 bool useLeaForSP() const { return UseLeaForSP; } 00366 bool hasSlowDivide() const { return HasSlowDivide; } 00367 bool padShortFunctions() const { return PadShortFunctions; } 00368 bool callRegIndirect() const { return CallRegIndirect; } 00369 bool LEAusesAG() const { return LEAUsesAG; } 00370 bool slowLEA() const { return SlowLEA; } 00371 bool slowIncDec() const { return SlowIncDec; } 00372 bool hasCDI() const { return HasCDI; } 00373 bool hasPFI() const { return HasPFI; } 00374 bool hasERI() const { return HasERI; } 00375 bool hasDQI() const { return HasDQI; } 00376 bool hasBWI() const { return HasBWI; } 00377 bool hasVLX() const { return HasVLX; } 00378 00379 bool isAtom() const { return X86ProcFamily == IntelAtom; } 00380 bool isSLM() const { return X86ProcFamily == IntelSLM; } 00381 00382 const Triple &getTargetTriple() const { return TargetTriple; } 00383 00384 bool isTargetDarwin() const { return TargetTriple.isOSDarwin(); } 00385 bool isTargetFreeBSD() const { 00386 return TargetTriple.getOS() == Triple::FreeBSD; 00387 } 00388 bool isTargetSolaris() const { 00389 return TargetTriple.getOS() == Triple::Solaris; 00390 } 00391 00392 bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); } 00393 bool isTargetCOFF() const { return TargetTriple.isOSBinFormatCOFF(); } 00394 bool isTargetMacho() const { return TargetTriple.isOSBinFormatMachO(); } 00395 00396 bool isTargetLinux() const { return TargetTriple.isOSLinux(); } 00397 bool isTargetNaCl() const { return TargetTriple.isOSNaCl(); } 00398 bool isTargetNaCl32() const { return isTargetNaCl() && !is64Bit(); } 00399 bool isTargetNaCl64() const { return isTargetNaCl() && is64Bit(); } 00400 00401 bool isTargetWindowsMSVC() const { 00402 return TargetTriple.isWindowsMSVCEnvironment(); 00403 } 00404 00405 bool isTargetKnownWindowsMSVC() const { 00406 return TargetTriple.isKnownWindowsMSVCEnvironment(); 00407 } 00408 00409 bool isTargetWindowsCygwin() const { 00410 return TargetTriple.isWindowsCygwinEnvironment(); 00411 } 00412 00413 bool isTargetWindowsGNU() const { 00414 return TargetTriple.isWindowsGNUEnvironment(); 00415 } 00416 00417 bool isTargetCygMing() const { return TargetTriple.isOSCygMing(); } 00418 00419 bool isOSWindows() const { return TargetTriple.isOSWindows(); } 00420 00421 bool isTargetWin64() const { 00422 return In64BitMode && TargetTriple.isOSWindows(); 00423 } 00424 00425 bool isTargetWin32() const { 00426 return !In64BitMode && (isTargetCygMing() || isTargetKnownWindowsMSVC()); 00427 } 00428 00429 bool isPICStyleSet() const { return PICStyle != PICStyles::None; } 00430 bool isPICStyleGOT() const { return PICStyle == PICStyles::GOT; } 00431 bool isPICStyleRIPRel() const { return PICStyle == PICStyles::RIPRel; } 00432 00433 bool isPICStyleStubPIC() const { 00434 return PICStyle == PICStyles::StubPIC; 00435 } 00436 00437 bool isPICStyleStubNoDynamic() const { 00438 return PICStyle == PICStyles::StubDynamicNoPIC; 00439 } 00440 bool isPICStyleStubAny() const { 00441 return PICStyle == PICStyles::StubDynamicNoPIC || 00442 PICStyle == PICStyles::StubPIC; 00443 } 00444 00445 bool isCallingConvWin64(CallingConv::ID CC) const { 00446 return (isTargetWin64() && CC != CallingConv::X86_64_SysV) || 00447 CC == CallingConv::X86_64_Win64; 00448 } 00449 00450 /// ClassifyGlobalReference - Classify a global variable reference for the 00451 /// current subtarget according to how we should reference it in a non-pcrel 00452 /// context. 00453 unsigned char ClassifyGlobalReference(const GlobalValue *GV, 00454 const TargetMachine &TM)const; 00455 00456 /// ClassifyBlockAddressReference - Classify a blockaddress reference for the 00457 /// current subtarget according to how we should reference it in a non-pcrel 00458 /// context. 00459 unsigned char ClassifyBlockAddressReference() const; 00460 00461 /// IsLegalToCallImmediateAddr - Return true if the subtarget allows calls 00462 /// to immediate address. 00463 bool IsLegalToCallImmediateAddr(const TargetMachine &TM) const; 00464 00465 /// This function returns the name of a function which has an interface 00466 /// like the non-standard bzero function, if such a function exists on 00467 /// the current subtarget and it is considered prefereable over 00468 /// memset with zero passed as the second argument. Otherwise it 00469 /// returns null. 00470 const char *getBZeroEntry() const; 00471 00472 /// This function returns true if the target has sincos() routine in its 00473 /// compiler runtime or math libraries. 00474 bool hasSinCos() const; 00475 00476 /// Enable the MachineScheduler pass for all X86 subtargets. 00477 bool enableMachineScheduler() const override { return true; } 00478 00479 bool enableEarlyIfConversion() const override; 00480 00481 /// getInstrItins = Return the instruction itineraries based on the 00482 /// subtarget selection. 00483 const InstrItineraryData *getInstrItineraryData() const override { 00484 return &InstrItins; 00485 } 00486 00487 AntiDepBreakMode getAntiDepBreakMode() const override { 00488 return TargetSubtargetInfo::ANTIDEP_CRITICAL; 00489 } 00490 }; 00491 00492 } // End llvm namespace 00493 00494 #endif