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