xref: /freebsd/contrib/llvm-project/llvm/lib/Target/X86/X86Subtarget.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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