10b57cec5SDimitry Andric //===-- X86Subtarget.h - Define Subtarget for the X86 ----------*- C++ -*--===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file declares the X86 specific subclass of TargetSubtargetInfo. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_X86_X86SUBTARGET_H 140b57cec5SDimitry Andric #define LLVM_LIB_TARGET_X86_X86SUBTARGET_H 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "X86FrameLowering.h" 170b57cec5SDimitry Andric #include "X86ISelLowering.h" 180b57cec5SDimitry Andric #include "X86InstrInfo.h" 190b57cec5SDimitry Andric #include "X86SelectionDAGInfo.h" 205f757f3fSDimitry Andric #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" 210b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h" 220b57cec5SDimitry Andric #include "llvm/IR/CallingConv.h" 2306c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h" 240b57cec5SDimitry Andric #include <climits> 250b57cec5SDimitry Andric #include <memory> 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric #define GET_SUBTARGETINFO_HEADER 280b57cec5SDimitry Andric #include "X86GenSubtargetInfo.inc" 290b57cec5SDimitry Andric 300b57cec5SDimitry Andric namespace llvm { 310b57cec5SDimitry Andric 325ffd83dbSDimitry Andric class CallLowering; 330b57cec5SDimitry Andric class GlobalValue; 345ffd83dbSDimitry Andric class InstructionSelector; 355ffd83dbSDimitry Andric class LegalizerInfo; 365ffd83dbSDimitry Andric class RegisterBankInfo; 375ffd83dbSDimitry Andric class StringRef; 385ffd83dbSDimitry Andric class TargetMachine; 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric /// The X86 backend supports a number of different styles of PIC. 410b57cec5SDimitry Andric /// 420b57cec5SDimitry Andric namespace PICStyles { 430b57cec5SDimitry Andric 44480093f4SDimitry Andric enum class Style { 450b57cec5SDimitry Andric StubPIC, // Used on i386-darwin in pic mode. 460b57cec5SDimitry Andric GOT, // Used on 32 bit elf on when in pic mode. 470b57cec5SDimitry Andric RIPRel, // Used on X86-64 when in pic mode. 480b57cec5SDimitry Andric None // Set when not in pic mode. 490b57cec5SDimitry Andric }; 500b57cec5SDimitry Andric 510b57cec5SDimitry Andric } // end namespace PICStyles 520b57cec5SDimitry Andric 530b57cec5SDimitry Andric class X86Subtarget final : public X86GenSubtargetInfo { 540b57cec5SDimitry Andric enum X86SSEEnum { 5581ad6265SDimitry Andric NoSSE, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42, AVX, AVX2, AVX512 560b57cec5SDimitry Andric }; 570b57cec5SDimitry Andric 580b57cec5SDimitry Andric /// Which PIC style to use 590b57cec5SDimitry Andric PICStyles::Style PICStyle; 600b57cec5SDimitry Andric 610b57cec5SDimitry Andric const TargetMachine &TM; 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric /// SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42, or none supported. 640b57cec5SDimitry Andric X86SSEEnum X86SSELevel = NoSSE; 650b57cec5SDimitry Andric 6681ad6265SDimitry Andric #define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \ 6781ad6265SDimitry Andric bool ATTRIBUTE = DEFAULT; 6881ad6265SDimitry Andric #include "X86GenSubtargetInfo.inc" 690b57cec5SDimitry Andric /// The minimum alignment known to hold of the stack frame on 700b57cec5SDimitry Andric /// entry to the function and which must be maintained by every function. 718bcb0991SDimitry Andric Align stackAlignment = Align(4); 720b57cec5SDimitry Andric 73e8d8bef9SDimitry Andric Align TileConfigAlignment = Align(4); 74e8d8bef9SDimitry Andric 750b57cec5SDimitry Andric /// Max. memset / memcpy size that is turned into rep/movs, rep/stos ops. 760b57cec5SDimitry Andric /// 770b57cec5SDimitry Andric // FIXME: this is a known good value for Yonah. How about others? 780b57cec5SDimitry Andric unsigned MaxInlineSizeThreshold = 128; 790b57cec5SDimitry Andric 800b57cec5SDimitry Andric /// What processor and OS we're targeting. 810b57cec5SDimitry Andric Triple TargetTriple; 820b57cec5SDimitry Andric 830b57cec5SDimitry Andric /// GlobalISel related APIs. 840b57cec5SDimitry Andric std::unique_ptr<CallLowering> CallLoweringInfo; 850b57cec5SDimitry Andric std::unique_ptr<LegalizerInfo> Legalizer; 860b57cec5SDimitry Andric std::unique_ptr<RegisterBankInfo> RegBankInfo; 870b57cec5SDimitry Andric std::unique_ptr<InstructionSelector> InstSelector; 880b57cec5SDimitry Andric 890b57cec5SDimitry Andric /// Override the stack alignment. 908bcb0991SDimitry Andric MaybeAlign StackAlignOverride; 910b57cec5SDimitry Andric 920b57cec5SDimitry Andric /// Preferred vector width from function attribute. 930b57cec5SDimitry Andric unsigned PreferVectorWidthOverride; 940b57cec5SDimitry Andric 950b57cec5SDimitry Andric /// Resolved preferred vector width from function attribute and subtarget 960b57cec5SDimitry Andric /// features. 970b57cec5SDimitry Andric unsigned PreferVectorWidth = UINT32_MAX; 980b57cec5SDimitry Andric 990b57cec5SDimitry Andric /// Required vector width from function attribute. 1000b57cec5SDimitry Andric unsigned RequiredVectorWidth; 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric X86SelectionDAGInfo TSInfo; 1030b57cec5SDimitry Andric // Ordering here is important. X86InstrInfo initializes X86RegisterInfo which 1040b57cec5SDimitry Andric // X86TargetLowering needs. 1050b57cec5SDimitry Andric X86InstrInfo InstrInfo; 1060b57cec5SDimitry Andric X86TargetLowering TLInfo; 1070b57cec5SDimitry Andric X86FrameLowering FrameLowering; 1080b57cec5SDimitry Andric 1090b57cec5SDimitry Andric public: 1100b57cec5SDimitry Andric /// This constructor initializes the data members to match that 1110b57cec5SDimitry Andric /// of the specified triple. 1120b57cec5SDimitry Andric /// 113e8d8bef9SDimitry Andric X86Subtarget(const Triple &TT, StringRef CPU, StringRef TuneCPU, StringRef FS, 1148bcb0991SDimitry Andric const X86TargetMachine &TM, MaybeAlign StackAlignOverride, 1150b57cec5SDimitry Andric unsigned PreferVectorWidthOverride, 1160b57cec5SDimitry Andric unsigned RequiredVectorWidth); 1170b57cec5SDimitry Andric getTargetLowering()1180b57cec5SDimitry Andric const X86TargetLowering *getTargetLowering() const override { 1190b57cec5SDimitry Andric return &TLInfo; 1200b57cec5SDimitry Andric } 1210b57cec5SDimitry Andric getInstrInfo()1220b57cec5SDimitry Andric const X86InstrInfo *getInstrInfo() const override { return &InstrInfo; } 1230b57cec5SDimitry Andric getFrameLowering()1240b57cec5SDimitry Andric const X86FrameLowering *getFrameLowering() const override { 1250b57cec5SDimitry Andric return &FrameLowering; 1260b57cec5SDimitry Andric } 1270b57cec5SDimitry Andric getSelectionDAGInfo()1280b57cec5SDimitry Andric const X86SelectionDAGInfo *getSelectionDAGInfo() const override { 1290b57cec5SDimitry Andric return &TSInfo; 1300b57cec5SDimitry Andric } 1310b57cec5SDimitry Andric getRegisterInfo()1320b57cec5SDimitry Andric const X86RegisterInfo *getRegisterInfo() const override { 1330b57cec5SDimitry Andric return &getInstrInfo()->getRegisterInfo(); 1340b57cec5SDimitry Andric } 1350b57cec5SDimitry Andric getTileConfigSize()136e8d8bef9SDimitry Andric unsigned getTileConfigSize() const { return 64; } getTileConfigAlignment()137e8d8bef9SDimitry Andric Align getTileConfigAlignment() const { return TileConfigAlignment; } 138e8d8bef9SDimitry Andric 1390b57cec5SDimitry Andric /// Returns the minimum alignment known to hold of the 1400b57cec5SDimitry Andric /// stack frame on entry to the function and which must be maintained by every 1410b57cec5SDimitry Andric /// function for this subtarget. getStackAlignment()1428bcb0991SDimitry Andric Align getStackAlignment() const { return stackAlignment; } 1430b57cec5SDimitry Andric 1440b57cec5SDimitry Andric /// Returns the maximum memset / memcpy size 1450b57cec5SDimitry Andric /// that still makes it profitable to inline the call. getMaxInlineSizeThreshold()1460b57cec5SDimitry Andric unsigned getMaxInlineSizeThreshold() const { return MaxInlineSizeThreshold; } 1470b57cec5SDimitry Andric 1480b57cec5SDimitry Andric /// ParseSubtargetFeatures - Parses features string setting specified 1490b57cec5SDimitry Andric /// subtarget options. Definition of function is auto generated by tblgen. 150e8d8bef9SDimitry Andric void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS); 1510b57cec5SDimitry Andric 1520b57cec5SDimitry Andric /// Methods used by Global ISel 1530b57cec5SDimitry Andric const CallLowering *getCallLowering() const override; 1548bcb0991SDimitry Andric InstructionSelector *getInstructionSelector() const override; 1550b57cec5SDimitry Andric const LegalizerInfo *getLegalizerInfo() const override; 1560b57cec5SDimitry Andric const RegisterBankInfo *getRegBankInfo() const override; 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric private: 1590b57cec5SDimitry Andric /// Initialize the full set of dependencies so we can use an initializer 1600b57cec5SDimitry Andric /// list for X86Subtarget. 161e8d8bef9SDimitry Andric X86Subtarget &initializeSubtargetDependencies(StringRef CPU, 162e8d8bef9SDimitry Andric StringRef TuneCPU, 163e8d8bef9SDimitry Andric StringRef FS); 164e8d8bef9SDimitry Andric void initSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS); 1650b57cec5SDimitry Andric 1660b57cec5SDimitry Andric public: 1670b57cec5SDimitry Andric 16881ad6265SDimitry Andric #define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \ 16981ad6265SDimitry Andric bool GETTER() const { return ATTRIBUTE; } 17081ad6265SDimitry Andric #include "X86GenSubtargetInfo.inc" 1710b57cec5SDimitry Andric 1720b57cec5SDimitry Andric /// Is this x86_64 with the ILP32 programming model (x32 ABI)? isTarget64BitILP32()1730b57cec5SDimitry Andric bool isTarget64BitILP32() const { 17481ad6265SDimitry Andric return Is64Bit && (TargetTriple.isX32() || TargetTriple.isOSNaCl()); 1750b57cec5SDimitry Andric } 1760b57cec5SDimitry Andric 1770b57cec5SDimitry Andric /// Is this x86_64 with the LP64 programming model (standard AMD64, no x32)? isTarget64BitLP64()1780b57cec5SDimitry Andric bool isTarget64BitLP64() const { 17981ad6265SDimitry Andric return Is64Bit && (!TargetTriple.isX32() && !TargetTriple.isOSNaCl()); 1800b57cec5SDimitry Andric } 1810b57cec5SDimitry Andric getPICStyle()1820b57cec5SDimitry Andric PICStyles::Style getPICStyle() const { return PICStyle; } setPICStyle(PICStyles::Style Style)1830b57cec5SDimitry Andric void setPICStyle(PICStyles::Style Style) { PICStyle = Style; } 1840b57cec5SDimitry Andric canUseCMPXCHG8B()18581ad6265SDimitry Andric bool canUseCMPXCHG8B() const { return hasCX8(); } canUseCMPXCHG16B()18681ad6265SDimitry Andric bool canUseCMPXCHG16B() const { 18781ad6265SDimitry Andric // CX16 is just the CPUID bit, instruction requires 64-bit mode too. 18881ad6265SDimitry Andric return hasCX16() && is64Bit(); 18981ad6265SDimitry Andric } 1900b57cec5SDimitry Andric // SSE codegen depends on cmovs, and all SSE1+ processors support them. 1910b57cec5SDimitry Andric // All 64-bit processors support cmov. canUseCMOV()19281ad6265SDimitry Andric bool canUseCMOV() const { return hasCMOV() || hasSSE1() || is64Bit(); } hasSSE1()1930b57cec5SDimitry Andric bool hasSSE1() const { return X86SSELevel >= SSE1; } hasSSE2()1940b57cec5SDimitry Andric bool hasSSE2() const { return X86SSELevel >= SSE2; } hasSSE3()1950b57cec5SDimitry Andric bool hasSSE3() const { return X86SSELevel >= SSE3; } hasSSSE3()1960b57cec5SDimitry Andric bool hasSSSE3() const { return X86SSELevel >= SSSE3; } hasSSE41()1970b57cec5SDimitry Andric bool hasSSE41() const { return X86SSELevel >= SSE41; } hasSSE42()1980b57cec5SDimitry Andric bool hasSSE42() const { return X86SSELevel >= SSE42; } hasAVX()1990b57cec5SDimitry Andric bool hasAVX() const { return X86SSELevel >= AVX; } hasAVX2()2000b57cec5SDimitry Andric bool hasAVX2() const { return X86SSELevel >= AVX2; } hasAVX512()20181ad6265SDimitry Andric bool hasAVX512() const { return X86SSELevel >= AVX512; } hasInt256()2020b57cec5SDimitry Andric bool hasInt256() const { return hasAVX2(); } hasAnyFMA()2030b57cec5SDimitry Andric bool hasAnyFMA() const { return hasFMA() || hasFMA4(); } hasPrefetchW()2045ffd83dbSDimitry Andric bool hasPrefetchW() const { 2055ffd83dbSDimitry Andric // The PREFETCHW instruction was added with 3DNow but later CPUs gave it 206*0fca6ea1SDimitry Andric // its own CPUID bit as part of deprecating 3DNow. 207*0fca6ea1SDimitry Andric return hasPRFCHW(); 2085ffd83dbSDimitry Andric } hasSSEPrefetch()2090b57cec5SDimitry Andric bool hasSSEPrefetch() const { 210*0fca6ea1SDimitry Andric // We also implicitly enable these when we have a write prefix supporting 211*0fca6ea1SDimitry Andric // cache level OR if we have prfchw. 212*0fca6ea1SDimitry Andric return hasSSE1() || hasPRFCHW() || hasPREFETCHI(); 2130b57cec5SDimitry Andric } canUseLAHFSAHF()21481ad6265SDimitry Andric bool canUseLAHFSAHF() const { return hasLAHFSAHF64() || !is64Bit(); } 2150946e70aSDimitry Andric // These are generic getters that OR together all of the thunk types 2160946e70aSDimitry Andric // supported by the subtarget. Therefore useIndirectThunk*() will return true 2170946e70aSDimitry Andric // if any respective thunk feature is enabled. useIndirectThunkCalls()2180946e70aSDimitry Andric bool useIndirectThunkCalls() const { 2190946e70aSDimitry Andric return useRetpolineIndirectCalls() || useLVIControlFlowIntegrity(); 2200946e70aSDimitry Andric } useIndirectThunkBranches()2210946e70aSDimitry Andric bool useIndirectThunkBranches() const { 2220946e70aSDimitry Andric return useRetpolineIndirectBranches() || useLVIControlFlowIntegrity(); 2230946e70aSDimitry Andric } 2240946e70aSDimitry Andric getPreferVectorWidth()2250b57cec5SDimitry Andric unsigned getPreferVectorWidth() const { return PreferVectorWidth; } getRequiredVectorWidth()2260b57cec5SDimitry Andric unsigned getRequiredVectorWidth() const { return RequiredVectorWidth; } 2270b57cec5SDimitry Andric 2280b57cec5SDimitry Andric // Helper functions to determine when we should allow widening to 512-bit 2290b57cec5SDimitry Andric // during codegen. 2300b57cec5SDimitry Andric // TODO: Currently we're always allowing widening on CPUs without VLX, 2310b57cec5SDimitry Andric // because for many cases we don't have a better option. canExtendTo512DQ()2320b57cec5SDimitry Andric bool canExtendTo512DQ() const { 2335678d1d9SDimitry Andric return hasAVX512() && hasEVEX512() && 2345678d1d9SDimitry Andric (!hasVLX() || getPreferVectorWidth() >= 512); 2350b57cec5SDimitry Andric } canExtendTo512BW()2360b57cec5SDimitry Andric bool canExtendTo512BW() const { 2370b57cec5SDimitry Andric return hasBWI() && canExtendTo512DQ(); 2380b57cec5SDimitry Andric } 2390b57cec5SDimitry Andric hasNoDomainDelay()24006c3fb27SDimitry Andric bool hasNoDomainDelay() const { return NoDomainDelay; } hasNoDomainDelayMov()24106c3fb27SDimitry Andric bool hasNoDomainDelayMov() const { 24206c3fb27SDimitry Andric return hasNoDomainDelay() || NoDomainDelayMov; 24306c3fb27SDimitry Andric } hasNoDomainDelayBlend()24406c3fb27SDimitry Andric bool hasNoDomainDelayBlend() const { 24506c3fb27SDimitry Andric return hasNoDomainDelay() || NoDomainDelayBlend; 24606c3fb27SDimitry Andric } hasNoDomainDelayShuffle()24706c3fb27SDimitry Andric bool hasNoDomainDelayShuffle() const { 24806c3fb27SDimitry Andric return hasNoDomainDelay() || NoDomainDelayShuffle; 24906c3fb27SDimitry Andric } 25006c3fb27SDimitry Andric 2510b57cec5SDimitry Andric // If there are no 512-bit vectors and we prefer not to use 512-bit registers, 2520b57cec5SDimitry Andric // disable them in the legalizer. useAVX512Regs()2530b57cec5SDimitry Andric bool useAVX512Regs() const { 2545f757f3fSDimitry Andric return hasAVX512() && hasEVEX512() && 2555f757f3fSDimitry Andric (canExtendTo512DQ() || RequiredVectorWidth > 256); 2560b57cec5SDimitry Andric } 2570b57cec5SDimitry Andric useLight256BitInstructions()258bdd1243dSDimitry Andric bool useLight256BitInstructions() const { 259bdd1243dSDimitry Andric return getPreferVectorWidth() >= 256 || AllowLight256Bit; 260bdd1243dSDimitry Andric } 261bdd1243dSDimitry Andric useBWIRegs()2620b57cec5SDimitry Andric bool useBWIRegs() const { 2630b57cec5SDimitry Andric return hasBWI() && useAVX512Regs(); 2640b57cec5SDimitry Andric } 2650b57cec5SDimitry Andric isXRaySupported()2660b57cec5SDimitry Andric bool isXRaySupported() const override { return is64Bit(); } 2670b57cec5SDimitry Andric 268bdd1243dSDimitry Andric /// Use clflush if we have SSE2 or we're on x86-64 (even if we asked for 269bdd1243dSDimitry Andric /// no-sse2). There isn't any reason to disable it if the target processor 270bdd1243dSDimitry Andric /// supports it. hasCLFLUSH()271bdd1243dSDimitry Andric bool hasCLFLUSH() const { return hasSSE2() || is64Bit(); } 272bdd1243dSDimitry Andric 2730b57cec5SDimitry Andric /// Use mfence if we have SSE2 or we're on x86-64 (even if we asked for 2740b57cec5SDimitry Andric /// no-sse2). There isn't any reason to disable it if the target processor 2750b57cec5SDimitry Andric /// supports it. hasMFence()2760b57cec5SDimitry Andric bool hasMFence() const { return hasSSE2() || is64Bit(); } 2770b57cec5SDimitry Andric getTargetTriple()2780b57cec5SDimitry Andric const Triple &getTargetTriple() const { return TargetTriple; } 2790b57cec5SDimitry Andric isTargetDarwin()2800b57cec5SDimitry Andric bool isTargetDarwin() const { return TargetTriple.isOSDarwin(); } isTargetFreeBSD()2810b57cec5SDimitry Andric bool isTargetFreeBSD() const { return TargetTriple.isOSFreeBSD(); } isTargetDragonFly()2820b57cec5SDimitry Andric bool isTargetDragonFly() const { return TargetTriple.isOSDragonFly(); } isTargetSolaris()2830b57cec5SDimitry Andric bool isTargetSolaris() const { return TargetTriple.isOSSolaris(); } isTargetPS()28481ad6265SDimitry Andric bool isTargetPS() const { return TargetTriple.isPS(); } 2850b57cec5SDimitry Andric isTargetELF()2860b57cec5SDimitry Andric bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); } isTargetCOFF()2870b57cec5SDimitry Andric bool isTargetCOFF() const { return TargetTriple.isOSBinFormatCOFF(); } isTargetMachO()2880b57cec5SDimitry Andric bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); } 2890b57cec5SDimitry Andric isTargetLinux()2900b57cec5SDimitry Andric bool isTargetLinux() const { return TargetTriple.isOSLinux(); } isTargetKFreeBSD()2910b57cec5SDimitry Andric bool isTargetKFreeBSD() const { return TargetTriple.isOSKFreeBSD(); } isTargetGlibc()2920b57cec5SDimitry Andric bool isTargetGlibc() const { return TargetTriple.isOSGlibc(); } isTargetAndroid()2930b57cec5SDimitry Andric bool isTargetAndroid() const { return TargetTriple.isAndroid(); } isTargetNaCl()2940b57cec5SDimitry Andric bool isTargetNaCl() const { return TargetTriple.isOSNaCl(); } isTargetNaCl32()2950b57cec5SDimitry Andric bool isTargetNaCl32() const { return isTargetNaCl() && !is64Bit(); } isTargetNaCl64()2960b57cec5SDimitry Andric bool isTargetNaCl64() const { return isTargetNaCl() && is64Bit(); } isTargetMCU()2970b57cec5SDimitry Andric bool isTargetMCU() const { return TargetTriple.isOSIAMCU(); } isTargetFuchsia()2980b57cec5SDimitry Andric bool isTargetFuchsia() const { return TargetTriple.isOSFuchsia(); } 2990b57cec5SDimitry Andric isTargetWindowsMSVC()3000b57cec5SDimitry Andric bool isTargetWindowsMSVC() const { 3010b57cec5SDimitry Andric return TargetTriple.isWindowsMSVCEnvironment(); 3020b57cec5SDimitry Andric } 3030b57cec5SDimitry Andric isTargetWindowsCoreCLR()3040b57cec5SDimitry Andric bool isTargetWindowsCoreCLR() const { 3050b57cec5SDimitry Andric return TargetTriple.isWindowsCoreCLREnvironment(); 3060b57cec5SDimitry Andric } 3070b57cec5SDimitry Andric isTargetWindowsCygwin()3080b57cec5SDimitry Andric bool isTargetWindowsCygwin() const { 3090b57cec5SDimitry Andric return TargetTriple.isWindowsCygwinEnvironment(); 3100b57cec5SDimitry Andric } 3110b57cec5SDimitry Andric isTargetWindowsGNU()3120b57cec5SDimitry Andric bool isTargetWindowsGNU() const { 3130b57cec5SDimitry Andric return TargetTriple.isWindowsGNUEnvironment(); 3140b57cec5SDimitry Andric } 3150b57cec5SDimitry Andric isTargetWindowsItanium()3160b57cec5SDimitry Andric bool isTargetWindowsItanium() const { 3170b57cec5SDimitry Andric return TargetTriple.isWindowsItaniumEnvironment(); 3180b57cec5SDimitry Andric } 3190b57cec5SDimitry Andric isTargetCygMing()3200b57cec5SDimitry Andric bool isTargetCygMing() const { return TargetTriple.isOSCygMing(); } 3210b57cec5SDimitry Andric isOSWindows()3220b57cec5SDimitry Andric bool isOSWindows() const { return TargetTriple.isOSWindows(); } 3230b57cec5SDimitry Andric isTargetWin64()32481ad6265SDimitry Andric bool isTargetWin64() const { return Is64Bit && isOSWindows(); } 3250b57cec5SDimitry Andric isTargetWin32()32681ad6265SDimitry Andric bool isTargetWin32() const { return !Is64Bit && isOSWindows(); } 3270b57cec5SDimitry Andric isPICStyleGOT()328480093f4SDimitry Andric bool isPICStyleGOT() const { return PICStyle == PICStyles::Style::GOT; } isPICStyleRIPRel()329480093f4SDimitry Andric bool isPICStyleRIPRel() const { return PICStyle == PICStyles::Style::RIPRel; } 3300b57cec5SDimitry Andric isPICStyleStubPIC()3310b57cec5SDimitry Andric bool isPICStyleStubPIC() const { 332480093f4SDimitry Andric return PICStyle == PICStyles::Style::StubPIC; 3330b57cec5SDimitry Andric } 3340b57cec5SDimitry Andric 3355ffd83dbSDimitry Andric bool isPositionIndependent() const; 3360b57cec5SDimitry Andric isCallingConvWin64(CallingConv::ID CC)3370b57cec5SDimitry Andric bool isCallingConvWin64(CallingConv::ID CC) const { 3380b57cec5SDimitry Andric switch (CC) { 3390b57cec5SDimitry Andric // On Win64, all these conventions just use the default convention. 3400b57cec5SDimitry Andric case CallingConv::C: 3410b57cec5SDimitry Andric case CallingConv::Fast: 3428bcb0991SDimitry Andric case CallingConv::Tail: 3430b57cec5SDimitry Andric case CallingConv::Swift: 344fe6060f1SDimitry Andric case CallingConv::SwiftTail: 3450b57cec5SDimitry Andric case CallingConv::X86_FastCall: 3460b57cec5SDimitry Andric case CallingConv::X86_StdCall: 3470b57cec5SDimitry Andric case CallingConv::X86_ThisCall: 3480b57cec5SDimitry Andric case CallingConv::X86_VectorCall: 3490b57cec5SDimitry Andric case CallingConv::Intel_OCL_BI: 3500b57cec5SDimitry Andric return isTargetWin64(); 3510b57cec5SDimitry Andric // This convention allows using the Win64 convention on other targets. 3520b57cec5SDimitry Andric case CallingConv::Win64: 3530b57cec5SDimitry Andric return true; 3540b57cec5SDimitry Andric // This convention allows using the SysV convention on Windows targets. 3550b57cec5SDimitry Andric case CallingConv::X86_64_SysV: 3560b57cec5SDimitry Andric return false; 3570b57cec5SDimitry Andric // Otherwise, who knows what this is. 3580b57cec5SDimitry Andric default: 3590b57cec5SDimitry Andric return false; 3600b57cec5SDimitry Andric } 3610b57cec5SDimitry Andric } 3620b57cec5SDimitry Andric 3630b57cec5SDimitry Andric /// Classify a global variable reference for the current subtarget according 3640b57cec5SDimitry Andric /// to how we should reference it in a non-pcrel context. 3650b57cec5SDimitry Andric unsigned char classifyLocalReference(const GlobalValue *GV) const; 3660b57cec5SDimitry Andric 3670b57cec5SDimitry Andric unsigned char classifyGlobalReference(const GlobalValue *GV, 3680b57cec5SDimitry Andric const Module &M) const; 3690b57cec5SDimitry Andric unsigned char classifyGlobalReference(const GlobalValue *GV) const; 3700b57cec5SDimitry Andric 3710b57cec5SDimitry Andric /// Classify a global function reference for the current subtarget. 3720b57cec5SDimitry Andric unsigned char classifyGlobalFunctionReference(const GlobalValue *GV, 3730b57cec5SDimitry Andric const Module &M) const; 374bdd1243dSDimitry Andric unsigned char 375bdd1243dSDimitry Andric classifyGlobalFunctionReference(const GlobalValue *GV) const override; 3760b57cec5SDimitry Andric 3770b57cec5SDimitry Andric /// Classify a blockaddress reference for the current subtarget according to 3780b57cec5SDimitry Andric /// how we should reference it in a non-pcrel context. 3790b57cec5SDimitry Andric unsigned char classifyBlockAddressReference() const; 3800b57cec5SDimitry Andric 3810b57cec5SDimitry Andric /// Return true if the subtarget allows calls to immediate address. 3820b57cec5SDimitry Andric bool isLegalToCallImmediateAddr() const; 3830b57cec5SDimitry Andric 384349cc55cSDimitry Andric /// Return whether FrameLowering should always set the "extended frame 385349cc55cSDimitry Andric /// present" bit in FP, or set it based on a symbol in the runtime. swiftAsyncContextIsDynamicallySet()386349cc55cSDimitry Andric bool swiftAsyncContextIsDynamicallySet() const { 387349cc55cSDimitry Andric // Older OS versions (particularly system unwinders) are confused by the 388349cc55cSDimitry Andric // Swift extended frame, so when building code that might be run on them we 389349cc55cSDimitry Andric // must dynamically query the concurrency library to determine whether 390349cc55cSDimitry Andric // extended frames should be flagged as present. 391349cc55cSDimitry Andric const Triple &TT = getTargetTriple(); 392349cc55cSDimitry Andric 3930eae32dcSDimitry Andric unsigned Major = TT.getOSVersion().getMajor(); 394349cc55cSDimitry Andric switch(TT.getOS()) { 395349cc55cSDimitry Andric default: 396349cc55cSDimitry Andric return false; 397349cc55cSDimitry Andric case Triple::IOS: 398349cc55cSDimitry Andric case Triple::TvOS: 399349cc55cSDimitry Andric return Major < 15; 400349cc55cSDimitry Andric case Triple::WatchOS: 401349cc55cSDimitry Andric return Major < 8; 402349cc55cSDimitry Andric case Triple::MacOSX: 403349cc55cSDimitry Andric case Triple::Darwin: 404349cc55cSDimitry Andric return Major < 12; 405349cc55cSDimitry Andric } 406349cc55cSDimitry Andric } 407349cc55cSDimitry Andric 4080946e70aSDimitry Andric /// If we are using indirect thunks, we need to expand indirectbr to avoid it 4090b57cec5SDimitry Andric /// lowering to an actual indirect jump. enableIndirectBrExpand()4100b57cec5SDimitry Andric bool enableIndirectBrExpand() const override { 4110946e70aSDimitry Andric return useIndirectThunkBranches(); 4120b57cec5SDimitry Andric } 4130b57cec5SDimitry Andric 4140b57cec5SDimitry Andric /// Enable the MachineScheduler pass for all X86 subtargets. enableMachineScheduler()4150b57cec5SDimitry Andric bool enableMachineScheduler() const override { return true; } 4160b57cec5SDimitry Andric 4170b57cec5SDimitry Andric bool enableEarlyIfConversion() const override; 4180b57cec5SDimitry Andric 4190b57cec5SDimitry Andric void getPostRAMutations(std::vector<std::unique_ptr<ScheduleDAGMutation>> 4200b57cec5SDimitry Andric &Mutations) const override; 4210b57cec5SDimitry Andric getAntiDepBreakMode()4220b57cec5SDimitry Andric AntiDepBreakMode getAntiDepBreakMode() const override { 4230b57cec5SDimitry Andric return TargetSubtargetInfo::ANTIDEP_CRITICAL; 4240b57cec5SDimitry Andric } 4250b57cec5SDimitry Andric }; 4260b57cec5SDimitry Andric 4270b57cec5SDimitry Andric } // end namespace llvm 4280b57cec5SDimitry Andric 4290b57cec5SDimitry Andric #endif // LLVM_LIB_TARGET_X86_X86SUBTARGET_H 430