1 //===-- X86Subtarget.h - Define Subtarget for the X86 ----------*- 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 declares the X86 specific subclass of TargetSubtargetInfo. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_LIB_TARGET_X86_X86SUBTARGET_H 15 #define LLVM_LIB_TARGET_X86_X86SUBTARGET_H 16 17 #include "X86FrameLowering.h" 18 #include "X86ISelLowering.h" 19 #include "X86InstrInfo.h" 20 #include "X86SelectionDAGInfo.h" 21 #include "llvm/ADT/Triple.h" 22 #include "llvm/IR/CallingConv.h" 23 #include "llvm/Target/TargetSubtargetInfo.h" 24 #include <string> 25 26 #define GET_SUBTARGETINFO_HEADER 27 #include "X86GenSubtargetInfo.inc" 28 29 namespace llvm { 30 class GlobalValue; 31 class StringRef; 32 class TargetMachine; 33 34 /// The X86 backend supports a number of different styles of PIC. 35 /// 36 namespace PICStyles { 37 enum Style { 38 StubPIC, // Used on i386-darwin in -fPIC mode. 39 StubDynamicNoPIC, // Used on i386-darwin in -mdynamic-no-pic mode. 40 GOT, // Used on many 32-bit unices in -fPIC mode. 41 RIPRel, // Used on X86-64 when not in -static mode. 42 None // Set when in -static mode (not PIC or DynamicNoPIC mode). 43 }; 44 } 45 46 class X86Subtarget final : public X86GenSubtargetInfo { 47 48 protected: 49 enum X86SSEEnum { 50 NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42, AVX, AVX2, AVX512F 51 }; 52 53 enum X863DNowEnum { 54 NoThreeDNow, ThreeDNow, ThreeDNowA 55 }; 56 57 enum X86ProcFamilyEnum { 58 Others, IntelAtom, IntelSLM 59 }; 60 61 /// X86 processor family: Intel Atom, and others 62 X86ProcFamilyEnum X86ProcFamily; 63 64 /// Which PIC style to use 65 PICStyles::Style PICStyle; 66 67 /// MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42, or none supported. 68 X86SSEEnum X86SSELevel; 69 70 /// 3DNow, 3DNow Athlon, or none supported. 71 X863DNowEnum X863DNowLevel; 72 73 /// True if this processor has conditional move instructions 74 /// (generally pentium pro+). 75 bool HasCMov; 76 77 /// True if the processor supports X86-64 instructions. 78 bool HasX86_64; 79 80 /// True if the processor supports POPCNT. 81 bool HasPOPCNT; 82 83 /// True if the processor supports SSE4A instructions. 84 bool HasSSE4A; 85 86 /// Target has AES instructions 87 bool HasAES; 88 89 /// Target has carry-less multiplication 90 bool HasPCLMUL; 91 92 /// Target has 3-operand fused multiply-add 93 bool HasFMA; 94 95 /// Target has 4-operand fused multiply-add 96 bool HasFMA4; 97 98 /// Target has XOP instructions 99 bool HasXOP; 100 101 /// Target has TBM instructions. 102 bool HasTBM; 103 104 /// True if the processor has the MOVBE instruction. 105 bool HasMOVBE; 106 107 /// True if the processor has the RDRAND instruction. 108 bool HasRDRAND; 109 110 /// Processor has 16-bit floating point conversion instructions. 111 bool HasF16C; 112 113 /// Processor has FS/GS base insturctions. 114 bool HasFSGSBase; 115 116 /// Processor has LZCNT instruction. 117 bool HasLZCNT; 118 119 /// Processor has BMI1 instructions. 120 bool HasBMI; 121 122 /// Processor has BMI2 instructions. 123 bool HasBMI2; 124 125 /// Processor has RTM instructions. 126 bool HasRTM; 127 128 /// Processor has HLE. 129 bool HasHLE; 130 131 /// Processor has ADX instructions. 132 bool HasADX; 133 134 /// Processor has SHA instructions. 135 bool HasSHA; 136 137 /// Processor has PRFCHW instructions. 138 bool HasPRFCHW; 139 140 /// Processor has RDSEED instructions. 141 bool HasRDSEED; 142 143 /// True if BT (bit test) of memory instructions are slow. 144 bool IsBTMemSlow; 145 146 /// True if SHLD instructions are slow. 147 bool IsSHLDSlow; 148 149 /// True if unaligned memory access is fast. 150 bool IsUAMemFast; 151 152 /// True if unaligned 32-byte memory accesses are slow. 153 bool IsUAMem32Slow; 154 155 /// True if SSE operations can have unaligned memory operands. 156 /// This may require setting a configuration bit in the processor. 157 bool HasSSEUnalignedMem; 158 159 /// True if this processor has the CMPXCHG16B instruction; 160 /// this is true for most x86-64 chips, but not the first AMD chips. 161 bool HasCmpxchg16b; 162 163 /// True if the LEA instruction should be used for adjusting 164 /// the stack pointer. This is an optimization for Intel Atom processors. 165 bool UseLeaForSP; 166 167 /// True if 8-bit divisions are significantly faster than 168 /// 32-bit divisions and should be used when possible. 169 bool HasSlowDivide32; 170 171 /// True if 16-bit divides are significantly faster than 172 /// 64-bit divisions and should be used when possible. 173 bool HasSlowDivide64; 174 175 /// True if the short functions should be padded to prevent 176 /// a stall when returning too early. 177 bool PadShortFunctions; 178 179 /// True if the Calls with memory reference should be converted 180 /// to a register-based indirect call. 181 bool CallRegIndirect; 182 183 /// True if the LEA instruction inputs have to be ready at address generation 184 /// (AG) time. 185 bool LEAUsesAG; 186 187 /// True if the LEA instruction with certain arguments is slow 188 bool SlowLEA; 189 190 /// True if INC and DEC instructions are slow when writing to flags 191 bool SlowIncDec; 192 193 /// Processor has AVX-512 PreFetch Instructions 194 bool HasPFI; 195 196 /// Processor has AVX-512 Exponential and Reciprocal Instructions 197 bool HasERI; 198 199 /// Processor has AVX-512 Conflict Detection Instructions 200 bool HasCDI; 201 202 /// Processor has AVX-512 Doubleword and Quadword instructions 203 bool HasDQI; 204 205 /// Processor has AVX-512 Byte and Word instructions 206 bool HasBWI; 207 208 /// Processor has AVX-512 Vector Length eXtenstions 209 bool HasVLX; 210 211 /// Processot supports MPX - Memory Protection Extensions 212 bool HasMPX; 213 214 /// Use software floating point for code generation. 215 bool UseSoftFloat; 216 217 /// The minimum alignment known to hold of the stack frame on 218 /// entry to the function and which must be maintained by every function. 219 unsigned stackAlignment; 220 221 /// Max. memset / memcpy size that is turned into rep/movs, rep/stos ops. 222 /// 223 unsigned MaxInlineSizeThreshold; 224 225 /// What processor and OS we're targeting. 226 Triple TargetTriple; 227 228 /// Instruction itineraries for scheduling 229 InstrItineraryData InstrItins; 230 231 private: 232 233 /// Override the stack alignment. 234 unsigned StackAlignOverride; 235 236 /// True if compiling for 64-bit, false for 16-bit or 32-bit. 237 bool In64BitMode; 238 239 /// True if compiling for 32-bit, false for 16-bit or 64-bit. 240 bool In32BitMode; 241 242 /// True if compiling for 16-bit, false for 32-bit or 64-bit. 243 bool In16BitMode; 244 245 X86SelectionDAGInfo TSInfo; 246 // Ordering here is important. X86InstrInfo initializes X86RegisterInfo which 247 // X86TargetLowering needs. 248 X86InstrInfo InstrInfo; 249 X86TargetLowering TLInfo; 250 X86FrameLowering FrameLowering; 251 252 public: 253 /// This constructor initializes the data members to match that 254 /// of the specified triple. 255 /// 256 X86Subtarget(const Triple &TT, const std::string &CPU, const std::string &FS, 257 const X86TargetMachine &TM, unsigned StackAlignOverride); 258 getTargetLowering()259 const X86TargetLowering *getTargetLowering() const override { 260 return &TLInfo; 261 } getInstrInfo()262 const X86InstrInfo *getInstrInfo() const override { return &InstrInfo; } getFrameLowering()263 const X86FrameLowering *getFrameLowering() const override { 264 return &FrameLowering; 265 } getSelectionDAGInfo()266 const X86SelectionDAGInfo *getSelectionDAGInfo() const override { 267 return &TSInfo; 268 } getRegisterInfo()269 const X86RegisterInfo *getRegisterInfo() const override { 270 return &getInstrInfo()->getRegisterInfo(); 271 } 272 273 /// Returns the minimum alignment known to hold of the 274 /// stack frame on entry to the function and which must be maintained by every 275 /// function for this subtarget. getStackAlignment()276 unsigned getStackAlignment() const { return stackAlignment; } 277 278 /// Returns the maximum memset / memcpy size 279 /// that still makes it profitable to inline the call. getMaxInlineSizeThreshold()280 unsigned getMaxInlineSizeThreshold() const { return MaxInlineSizeThreshold; } 281 282 /// ParseSubtargetFeatures - Parses features string setting specified 283 /// subtarget options. Definition of function is auto generated by tblgen. 284 void ParseSubtargetFeatures(StringRef CPU, StringRef FS); 285 286 private: 287 /// Initialize the full set of dependencies so we can use an initializer 288 /// list for X86Subtarget. 289 X86Subtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS); 290 void initializeEnvironment(); 291 void initSubtargetFeatures(StringRef CPU, StringRef FS); 292 public: 293 /// Is this x86_64? (disregarding specific ABI / programming model) is64Bit()294 bool is64Bit() const { 295 return In64BitMode; 296 } 297 is32Bit()298 bool is32Bit() const { 299 return In32BitMode; 300 } 301 is16Bit()302 bool is16Bit() const { 303 return In16BitMode; 304 } 305 306 /// Is this x86_64 with the ILP32 programming model (x32 ABI)? isTarget64BitILP32()307 bool isTarget64BitILP32() const { 308 return In64BitMode && (TargetTriple.getEnvironment() == Triple::GNUX32 || 309 TargetTriple.isOSNaCl()); 310 } 311 312 /// Is this x86_64 with the LP64 programming model (standard AMD64, no x32)? isTarget64BitLP64()313 bool isTarget64BitLP64() const { 314 return In64BitMode && (TargetTriple.getEnvironment() != Triple::GNUX32 && 315 !TargetTriple.isOSNaCl()); 316 } 317 getPICStyle()318 PICStyles::Style getPICStyle() const { return PICStyle; } setPICStyle(PICStyles::Style Style)319 void setPICStyle(PICStyles::Style Style) { PICStyle = Style; } 320 hasCMov()321 bool hasCMov() const { return HasCMov; } hasMMX()322 bool hasMMX() const { return X86SSELevel >= MMX; } hasSSE1()323 bool hasSSE1() const { return X86SSELevel >= SSE1; } hasSSE2()324 bool hasSSE2() const { return X86SSELevel >= SSE2; } hasSSE3()325 bool hasSSE3() const { return X86SSELevel >= SSE3; } hasSSSE3()326 bool hasSSSE3() const { return X86SSELevel >= SSSE3; } hasSSE41()327 bool hasSSE41() const { return X86SSELevel >= SSE41; } hasSSE42()328 bool hasSSE42() const { return X86SSELevel >= SSE42; } hasAVX()329 bool hasAVX() const { return X86SSELevel >= AVX; } hasAVX2()330 bool hasAVX2() const { return X86SSELevel >= AVX2; } hasAVX512()331 bool hasAVX512() const { return X86SSELevel >= AVX512F; } hasFp256()332 bool hasFp256() const { return hasAVX(); } hasInt256()333 bool hasInt256() const { return hasAVX2(); } hasSSE4A()334 bool hasSSE4A() const { return HasSSE4A; } has3DNow()335 bool has3DNow() const { return X863DNowLevel >= ThreeDNow; } has3DNowA()336 bool has3DNowA() const { return X863DNowLevel >= ThreeDNowA; } hasPOPCNT()337 bool hasPOPCNT() const { return HasPOPCNT; } hasAES()338 bool hasAES() const { return HasAES; } hasPCLMUL()339 bool hasPCLMUL() const { return HasPCLMUL; } hasFMA()340 bool hasFMA() const { return HasFMA; } 341 // FIXME: Favor FMA when both are enabled. Is this the right thing to do? hasFMA4()342 bool hasFMA4() const { return HasFMA4 && !HasFMA; } hasXOP()343 bool hasXOP() const { return HasXOP; } hasTBM()344 bool hasTBM() const { return HasTBM; } hasMOVBE()345 bool hasMOVBE() const { return HasMOVBE; } hasRDRAND()346 bool hasRDRAND() const { return HasRDRAND; } hasF16C()347 bool hasF16C() const { return HasF16C; } hasFSGSBase()348 bool hasFSGSBase() const { return HasFSGSBase; } hasLZCNT()349 bool hasLZCNT() const { return HasLZCNT; } hasBMI()350 bool hasBMI() const { return HasBMI; } hasBMI2()351 bool hasBMI2() const { return HasBMI2; } hasRTM()352 bool hasRTM() const { return HasRTM; } hasHLE()353 bool hasHLE() const { return HasHLE; } hasADX()354 bool hasADX() const { return HasADX; } hasSHA()355 bool hasSHA() const { return HasSHA; } hasPRFCHW()356 bool hasPRFCHW() const { return HasPRFCHW; } hasRDSEED()357 bool hasRDSEED() const { return HasRDSEED; } isBTMemSlow()358 bool isBTMemSlow() const { return IsBTMemSlow; } isSHLDSlow()359 bool isSHLDSlow() const { return IsSHLDSlow; } isUnalignedMemAccessFast()360 bool isUnalignedMemAccessFast() const { return IsUAMemFast; } isUnalignedMem32Slow()361 bool isUnalignedMem32Slow() const { return IsUAMem32Slow; } hasSSEUnalignedMem()362 bool hasSSEUnalignedMem() const { return HasSSEUnalignedMem; } hasCmpxchg16b()363 bool hasCmpxchg16b() const { return HasCmpxchg16b; } useLeaForSP()364 bool useLeaForSP() const { return UseLeaForSP; } hasSlowDivide32()365 bool hasSlowDivide32() const { return HasSlowDivide32; } hasSlowDivide64()366 bool hasSlowDivide64() const { return HasSlowDivide64; } padShortFunctions()367 bool padShortFunctions() const { return PadShortFunctions; } callRegIndirect()368 bool callRegIndirect() const { return CallRegIndirect; } LEAusesAG()369 bool LEAusesAG() const { return LEAUsesAG; } slowLEA()370 bool slowLEA() const { return SlowLEA; } slowIncDec()371 bool slowIncDec() const { return SlowIncDec; } hasCDI()372 bool hasCDI() const { return HasCDI; } hasPFI()373 bool hasPFI() const { return HasPFI; } hasERI()374 bool hasERI() const { return HasERI; } hasDQI()375 bool hasDQI() const { return HasDQI; } hasBWI()376 bool hasBWI() const { return HasBWI; } hasVLX()377 bool hasVLX() const { return HasVLX; } hasMPX()378 bool hasMPX() const { return HasMPX; } 379 isAtom()380 bool isAtom() const { return X86ProcFamily == IntelAtom; } isSLM()381 bool isSLM() const { return X86ProcFamily == IntelSLM; } useSoftFloat()382 bool useSoftFloat() const { return UseSoftFloat; } 383 getTargetTriple()384 const Triple &getTargetTriple() const { return TargetTriple; } 385 isTargetDarwin()386 bool isTargetDarwin() const { return TargetTriple.isOSDarwin(); } isTargetFreeBSD()387 bool isTargetFreeBSD() const { return TargetTriple.isOSFreeBSD(); } isTargetDragonFly()388 bool isTargetDragonFly() const { return TargetTriple.isOSDragonFly(); } isTargetSolaris()389 bool isTargetSolaris() const { return TargetTriple.isOSSolaris(); } isTargetPS4()390 bool isTargetPS4() const { return TargetTriple.isPS4(); } 391 isTargetELF()392 bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); } isTargetCOFF()393 bool isTargetCOFF() const { return TargetTriple.isOSBinFormatCOFF(); } isTargetMachO()394 bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); } 395 isTargetLinux()396 bool isTargetLinux() const { return TargetTriple.isOSLinux(); } isTargetNaCl()397 bool isTargetNaCl() const { return TargetTriple.isOSNaCl(); } isTargetNaCl32()398 bool isTargetNaCl32() const { return isTargetNaCl() && !is64Bit(); } isTargetNaCl64()399 bool isTargetNaCl64() const { return isTargetNaCl() && is64Bit(); } 400 isTargetWindowsMSVC()401 bool isTargetWindowsMSVC() const { 402 return TargetTriple.isWindowsMSVCEnvironment(); 403 } 404 isTargetKnownWindowsMSVC()405 bool isTargetKnownWindowsMSVC() const { 406 return TargetTriple.isKnownWindowsMSVCEnvironment(); 407 } 408 isTargetWindowsCygwin()409 bool isTargetWindowsCygwin() const { 410 return TargetTriple.isWindowsCygwinEnvironment(); 411 } 412 isTargetWindowsGNU()413 bool isTargetWindowsGNU() const { 414 return TargetTriple.isWindowsGNUEnvironment(); 415 } 416 isTargetWindowsItanium()417 bool isTargetWindowsItanium() const { 418 return TargetTriple.isWindowsItaniumEnvironment(); 419 } 420 isTargetCygMing()421 bool isTargetCygMing() const { return TargetTriple.isOSCygMing(); } 422 isOSWindows()423 bool isOSWindows() const { return TargetTriple.isOSWindows(); } 424 isTargetWin64()425 bool isTargetWin64() const { 426 return In64BitMode && TargetTriple.isOSWindows(); 427 } 428 isTargetWin32()429 bool isTargetWin32() const { 430 return !In64BitMode && (isTargetCygMing() || isTargetKnownWindowsMSVC()); 431 } 432 isPICStyleSet()433 bool isPICStyleSet() const { return PICStyle != PICStyles::None; } isPICStyleGOT()434 bool isPICStyleGOT() const { return PICStyle == PICStyles::GOT; } isPICStyleRIPRel()435 bool isPICStyleRIPRel() const { return PICStyle == PICStyles::RIPRel; } 436 isPICStyleStubPIC()437 bool isPICStyleStubPIC() const { 438 return PICStyle == PICStyles::StubPIC; 439 } 440 isPICStyleStubNoDynamic()441 bool isPICStyleStubNoDynamic() const { 442 return PICStyle == PICStyles::StubDynamicNoPIC; 443 } isPICStyleStubAny()444 bool isPICStyleStubAny() const { 445 return PICStyle == PICStyles::StubDynamicNoPIC || 446 PICStyle == PICStyles::StubPIC; 447 } 448 isCallingConvWin64(CallingConv::ID CC)449 bool isCallingConvWin64(CallingConv::ID CC) const { 450 switch (CC) { 451 // On Win64, all these conventions just use the default convention. 452 case CallingConv::C: 453 case CallingConv::Fast: 454 case CallingConv::X86_FastCall: 455 case CallingConv::X86_StdCall: 456 case CallingConv::X86_ThisCall: 457 case CallingConv::X86_VectorCall: 458 case CallingConv::Intel_OCL_BI: 459 return isTargetWin64(); 460 // This convention allows using the Win64 convention on other targets. 461 case CallingConv::X86_64_Win64: 462 return true; 463 // This convention allows using the SysV convention on Windows targets. 464 case CallingConv::X86_64_SysV: 465 return false; 466 // Otherwise, who knows what this is. 467 default: 468 return false; 469 } 470 } 471 472 /// ClassifyGlobalReference - Classify a global variable reference for the 473 /// current subtarget according to how we should reference it in a non-pcrel 474 /// context. 475 unsigned char ClassifyGlobalReference(const GlobalValue *GV, 476 const TargetMachine &TM)const; 477 478 /// Classify a blockaddress reference for the current subtarget according to 479 /// how we should reference it in a non-pcrel context. 480 unsigned char ClassifyBlockAddressReference() const; 481 482 /// Return true if the subtarget allows calls to immediate address. 483 bool IsLegalToCallImmediateAddr(const TargetMachine &TM) const; 484 485 /// This function returns the name of a function which has an interface 486 /// like the non-standard bzero function, if such a function exists on 487 /// the current subtarget and it is considered prefereable over 488 /// memset with zero passed as the second argument. Otherwise it 489 /// returns null. 490 const char *getBZeroEntry() const; 491 492 /// This function returns true if the target has sincos() routine in its 493 /// compiler runtime or math libraries. 494 bool hasSinCos() const; 495 496 /// Enable the MachineScheduler pass for all X86 subtargets. enableMachineScheduler()497 bool enableMachineScheduler() const override { return true; } 498 499 bool enableEarlyIfConversion() const override; 500 501 /// Return the instruction itineraries based on the subtarget selection. getInstrItineraryData()502 const InstrItineraryData *getInstrItineraryData() const override { 503 return &InstrItins; 504 } 505 getAntiDepBreakMode()506 AntiDepBreakMode getAntiDepBreakMode() const override { 507 return TargetSubtargetInfo::ANTIDEP_CRITICAL; 508 } 509 }; 510 511 } // End llvm namespace 512 513 #endif 514