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