Home | History | Annotate | Line # | Download | only in X86
      1 //===-- X86Subtarget.h - Define Subtarget for the X86 ----------*- C++ -*--===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 //
      9 // This file declares the X86 specific subclass of TargetSubtargetInfo.
     10 //
     11 //===----------------------------------------------------------------------===//
     12 
     13 #ifndef LLVM_LIB_TARGET_X86_X86SUBTARGET_H
     14 #define LLVM_LIB_TARGET_X86_X86SUBTARGET_H
     15 
     16 #include "X86FrameLowering.h"
     17 #include "X86ISelLowering.h"
     18 #include "X86InstrInfo.h"
     19 #include "X86SelectionDAGInfo.h"
     20 #include "llvm/ADT/Triple.h"
     21 #include "llvm/CodeGen/TargetSubtargetInfo.h"
     22 #include "llvm/IR/CallingConv.h"
     23 #include <climits>
     24 #include <memory>
     25 
     26 #define GET_SUBTARGETINFO_HEADER
     27 #include "X86GenSubtargetInfo.inc"
     28 
     29 namespace llvm {
     30 
     31 class CallLowering;
     32 class GlobalValue;
     33 class InstructionSelector;
     34 class LegalizerInfo;
     35 class RegisterBankInfo;
     36 class StringRef;
     37 class TargetMachine;
     38 
     39 /// The X86 backend supports a number of different styles of PIC.
     40 ///
     41 namespace PICStyles {
     42 
     43 enum class Style {
     44   StubPIC,          // Used on i386-darwin in pic mode.
     45   GOT,              // Used on 32 bit elf on when in pic mode.
     46   RIPRel,           // Used on X86-64 when in pic mode.
     47   None              // Set when not in pic mode.
     48 };
     49 
     50 } // end namespace PICStyles
     51 
     52 class X86Subtarget final : public X86GenSubtargetInfo {
     53   // NOTE: Do not add anything new to this list. Coarse, CPU name based flags
     54   // are not a good idea. We should be migrating away from these.
     55   enum X86ProcFamilyEnum {
     56     Others,
     57     IntelAtom,
     58     IntelSLM
     59   };
     60 
     61   enum X86SSEEnum {
     62     NoSSE, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42, AVX, AVX2, AVX512F
     63   };
     64 
     65   enum X863DNowEnum {
     66     NoThreeDNow, MMX, ThreeDNow, ThreeDNowA
     67   };
     68 
     69   /// X86 processor family: Intel Atom, and others
     70   X86ProcFamilyEnum X86ProcFamily = Others;
     71 
     72   /// Which PIC style to use
     73   PICStyles::Style PICStyle;
     74 
     75   const TargetMachine &TM;
     76 
     77   /// SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42, or none supported.
     78   X86SSEEnum X86SSELevel = NoSSE;
     79 
     80   /// MMX, 3DNow, 3DNow Athlon, or none supported.
     81   X863DNowEnum X863DNowLevel = NoThreeDNow;
     82 
     83   /// True if the processor supports X87 instructions.
     84   bool HasX87 = false;
     85 
     86   /// True if the processor supports CMPXCHG8B.
     87   bool HasCmpxchg8b = false;
     88 
     89   /// True if this processor has NOPL instruction
     90   /// (generally pentium pro+).
     91   bool HasNOPL = false;
     92 
     93   /// True if this processor has conditional move instructions
     94   /// (generally pentium pro+).
     95   bool HasCMov = false;
     96 
     97   /// True if the processor supports X86-64 instructions.
     98   bool HasX86_64 = false;
     99 
    100   /// True if the processor supports POPCNT.
    101   bool HasPOPCNT = false;
    102 
    103   /// True if the processor supports SSE4A instructions.
    104   bool HasSSE4A = false;
    105 
    106   /// Target has AES instructions
    107   bool HasAES = false;
    108   bool HasVAES = false;
    109 
    110   /// Target has FXSAVE/FXRESTOR instructions
    111   bool HasFXSR = false;
    112 
    113   /// Target has XSAVE instructions
    114   bool HasXSAVE = false;
    115 
    116   /// Target has XSAVEOPT instructions
    117   bool HasXSAVEOPT = false;
    118 
    119   /// Target has XSAVEC instructions
    120   bool HasXSAVEC = false;
    121 
    122   /// Target has XSAVES instructions
    123   bool HasXSAVES = false;
    124 
    125   /// Target has carry-less multiplication
    126   bool HasPCLMUL = false;
    127   bool HasVPCLMULQDQ = false;
    128 
    129   /// Target has Galois Field Arithmetic instructions
    130   bool HasGFNI = false;
    131 
    132   /// Target has 3-operand fused multiply-add
    133   bool HasFMA = false;
    134 
    135   /// Target has 4-operand fused multiply-add
    136   bool HasFMA4 = false;
    137 
    138   /// Target has XOP instructions
    139   bool HasXOP = false;
    140 
    141   /// Target has TBM instructions.
    142   bool HasTBM = false;
    143 
    144   /// Target has LWP instructions
    145   bool HasLWP = false;
    146 
    147   /// True if the processor has the MOVBE instruction.
    148   bool HasMOVBE = false;
    149 
    150   /// True if the processor has the RDRAND instruction.
    151   bool HasRDRAND = false;
    152 
    153   /// Processor has 16-bit floating point conversion instructions.
    154   bool HasF16C = false;
    155 
    156   /// Processor has FS/GS base insturctions.
    157   bool HasFSGSBase = false;
    158 
    159   /// Processor has LZCNT instruction.
    160   bool HasLZCNT = false;
    161 
    162   /// Processor has BMI1 instructions.
    163   bool HasBMI = false;
    164 
    165   /// Processor has BMI2 instructions.
    166   bool HasBMI2 = false;
    167 
    168   /// Processor has VBMI instructions.
    169   bool HasVBMI = false;
    170 
    171   /// Processor has VBMI2 instructions.
    172   bool HasVBMI2 = false;
    173 
    174   /// Processor has Integer Fused Multiply Add
    175   bool HasIFMA = false;
    176 
    177   /// Processor has RTM instructions.
    178   bool HasRTM = false;
    179 
    180   /// Processor has ADX instructions.
    181   bool HasADX = false;
    182 
    183   /// Processor has SHA instructions.
    184   bool HasSHA = false;
    185 
    186   /// Processor has PRFCHW instructions.
    187   bool HasPRFCHW = false;
    188 
    189   /// Processor has RDSEED instructions.
    190   bool HasRDSEED = false;
    191 
    192   /// Processor has LAHF/SAHF instructions in 64-bit mode.
    193   bool HasLAHFSAHF64 = false;
    194 
    195   /// Processor has MONITORX/MWAITX instructions.
    196   bool HasMWAITX = false;
    197 
    198   /// Processor has Cache Line Zero instruction
    199   bool HasCLZERO = false;
    200 
    201   /// Processor has Cache Line Demote instruction
    202   bool HasCLDEMOTE = false;
    203 
    204   /// Processor has MOVDIRI instruction (direct store integer).
    205   bool HasMOVDIRI = false;
    206 
    207   /// Processor has MOVDIR64B instruction (direct store 64 bytes).
    208   bool HasMOVDIR64B = false;
    209 
    210   /// Processor has ptwrite instruction.
    211   bool HasPTWRITE = false;
    212 
    213   /// Processor has Prefetch with intent to Write instruction
    214   bool HasPREFETCHWT1 = false;
    215 
    216   /// True if SHLD instructions are slow.
    217   bool IsSHLDSlow = false;
    218 
    219   /// True if the PMULLD instruction is slow compared to PMULLW/PMULHW and
    220   //  PMULUDQ.
    221   bool IsPMULLDSlow = false;
    222 
    223   /// True if the PMADDWD instruction is slow compared to PMULLD.
    224   bool IsPMADDWDSlow = false;
    225 
    226   /// True if unaligned memory accesses of 16-bytes are slow.
    227   bool IsUAMem16Slow = false;
    228 
    229   /// True if unaligned memory accesses of 32-bytes are slow.
    230   bool IsUAMem32Slow = false;
    231 
    232   /// True if SSE operations can have unaligned memory operands.
    233   /// This may require setting a configuration bit in the processor.
    234   bool HasSSEUnalignedMem = false;
    235 
    236   /// True if this processor has the CMPXCHG16B instruction;
    237   /// this is true for most x86-64 chips, but not the first AMD chips.
    238   bool HasCmpxchg16b = false;
    239 
    240   /// True if the LEA instruction should be used for adjusting
    241   /// the stack pointer. This is an optimization for Intel Atom processors.
    242   bool UseLeaForSP = false;
    243 
    244   /// True if POPCNT instruction has a false dependency on the destination register.
    245   bool HasPOPCNTFalseDeps = false;
    246 
    247   /// True if LZCNT/TZCNT instructions have a false dependency on the destination register.
    248   bool HasLZCNTFalseDeps = false;
    249 
    250   /// True if its preferable to combine to a single shuffle using a variable
    251   /// mask over multiple fixed shuffles.
    252   bool HasFastVariableShuffle = false;
    253 
    254   /// True if vzeroupper instructions should be inserted after code that uses
    255   /// ymm or zmm registers.
    256   bool InsertVZEROUPPER = false;
    257 
    258   /// True if there is no performance penalty for writing NOPs with up to
    259   /// 7 bytes.
    260   bool HasFast7ByteNOP = false;
    261 
    262   /// True if there is no performance penalty for writing NOPs with up to
    263   /// 11 bytes.
    264   bool HasFast11ByteNOP = false;
    265 
    266   /// True if there is no performance penalty for writing NOPs with up to
    267   /// 15 bytes.
    268   bool HasFast15ByteNOP = false;
    269 
    270   /// True if gather is reasonably fast. This is true for Skylake client and
    271   /// all AVX-512 CPUs.
    272   bool HasFastGather = false;
    273 
    274   /// True if hardware SQRTSS instruction is at least as fast (latency) as
    275   /// RSQRTSS followed by a Newton-Raphson iteration.
    276   bool HasFastScalarFSQRT = false;
    277 
    278   /// True if hardware SQRTPS/VSQRTPS instructions are at least as fast
    279   /// (throughput) as RSQRTPS/VRSQRTPS followed by a Newton-Raphson iteration.
    280   bool HasFastVectorFSQRT = false;
    281 
    282   /// True if 8-bit divisions are significantly faster than
    283   /// 32-bit divisions and should be used when possible.
    284   bool HasSlowDivide32 = false;
    285 
    286   /// True if 32-bit divides are significantly faster than
    287   /// 64-bit divisions and should be used when possible.
    288   bool HasSlowDivide64 = false;
    289 
    290   /// True if LZCNT instruction is fast.
    291   bool HasFastLZCNT = false;
    292 
    293   /// True if SHLD based rotate is fast.
    294   bool HasFastSHLDRotate = false;
    295 
    296   /// True if the processor supports macrofusion.
    297   bool HasMacroFusion = false;
    298 
    299   /// True if the processor supports branch fusion.
    300   bool HasBranchFusion = false;
    301 
    302   /// True if the processor has enhanced REP MOVSB/STOSB.
    303   bool HasERMSB = false;
    304 
    305   /// True if the processor has fast short REP MOV.
    306   bool HasFSRM = false;
    307 
    308   /// True if the short functions should be padded to prevent
    309   /// a stall when returning too early.
    310   bool PadShortFunctions = false;
    311 
    312   /// True if two memory operand instructions should use a temporary register
    313   /// instead.
    314   bool SlowTwoMemOps = false;
    315 
    316   /// True if the LEA instruction inputs have to be ready at address generation
    317   /// (AG) time.
    318   bool LEAUsesAG = false;
    319 
    320   /// True if the LEA instruction with certain arguments is slow
    321   bool SlowLEA = false;
    322 
    323   /// True if the LEA instruction has all three source operands: base, index,
    324   /// and offset or if the LEA instruction uses base and index registers where
    325   /// the base is EBP, RBP,or R13
    326   bool Slow3OpsLEA = false;
    327 
    328   /// True if INC and DEC instructions are slow when writing to flags
    329   bool SlowIncDec = false;
    330 
    331   /// Processor has AVX-512 PreFetch Instructions
    332   bool HasPFI = false;
    333 
    334   /// Processor has AVX-512 Exponential and Reciprocal Instructions
    335   bool HasERI = false;
    336 
    337   /// Processor has AVX-512 Conflict Detection Instructions
    338   bool HasCDI = false;
    339 
    340   /// Processor has AVX-512 population count Instructions
    341   bool HasVPOPCNTDQ = false;
    342 
    343   /// Processor has AVX-512 Doubleword and Quadword instructions
    344   bool HasDQI = false;
    345 
    346   /// Processor has AVX-512 Byte and Word instructions
    347   bool HasBWI = false;
    348 
    349   /// Processor has AVX-512 Vector Length eXtenstions
    350   bool HasVLX = false;
    351 
    352   /// Processor has PKU extenstions
    353   bool HasPKU = false;
    354 
    355   /// Processor has AVX-512 Vector Neural Network Instructions
    356   bool HasVNNI = false;
    357 
    358   /// Processor has AVX Vector Neural Network Instructions
    359   bool HasAVXVNNI = false;
    360 
    361   /// Processor has AVX-512 bfloat16 floating-point extensions
    362   bool HasBF16 = false;
    363 
    364   /// Processor supports ENQCMD instructions
    365   bool HasENQCMD = false;
    366 
    367   /// Processor has AVX-512 Bit Algorithms instructions
    368   bool HasBITALG = false;
    369 
    370   /// Processor has AVX-512 vp2intersect instructions
    371   bool HasVP2INTERSECT = false;
    372 
    373   /// Processor supports CET SHSTK - Control-Flow Enforcement Technology
    374   /// using Shadow Stack
    375   bool HasSHSTK = false;
    376 
    377   /// Processor supports Invalidate Process-Context Identifier
    378   bool HasINVPCID = false;
    379 
    380   /// Processor has Software Guard Extensions
    381   bool HasSGX = false;
    382 
    383   /// Processor supports Flush Cache Line instruction
    384   bool HasCLFLUSHOPT = false;
    385 
    386   /// Processor supports Cache Line Write Back instruction
    387   bool HasCLWB = false;
    388 
    389   /// Processor supports Write Back No Invalidate instruction
    390   bool HasWBNOINVD = false;
    391 
    392   /// Processor support RDPID instruction
    393   bool HasRDPID = false;
    394 
    395   /// Processor supports WaitPKG instructions
    396   bool HasWAITPKG = false;
    397 
    398   /// Processor supports PCONFIG instruction
    399   bool HasPCONFIG = false;
    400 
    401   /// Processor support key locker instructions
    402   bool HasKL = false;
    403 
    404   /// Processor support key locker wide instructions
    405   bool HasWIDEKL = false;
    406 
    407   /// Processor supports HRESET instruction
    408   bool HasHRESET = false;
    409 
    410   /// Processor supports SERIALIZE instruction
    411   bool HasSERIALIZE = false;
    412 
    413   /// Processor supports TSXLDTRK instruction
    414   bool HasTSXLDTRK = false;
    415 
    416   /// Processor has AMX support
    417   bool HasAMXTILE = false;
    418   bool HasAMXBF16 = false;
    419   bool HasAMXINT8 = false;
    420 
    421   /// Processor supports User Level Interrupt instructions
    422   bool HasUINTR = false;
    423 
    424   /// Processor has a single uop BEXTR implementation.
    425   bool HasFastBEXTR = false;
    426 
    427   /// Try harder to combine to horizontal vector ops if they are fast.
    428   bool HasFastHorizontalOps = false;
    429 
    430   /// Prefer a left/right scalar logical shifts pair over a shift+and pair.
    431   bool HasFastScalarShiftMasks = false;
    432 
    433   /// Prefer a left/right vector logical shifts pair over a shift+and pair.
    434   bool HasFastVectorShiftMasks = false;
    435 
    436   /// Prefer a movbe over a single-use load + bswap / single-use bswap + store.
    437   bool HasFastMOVBE = false;
    438 
    439   /// Use a retpoline thunk rather than indirect calls to block speculative
    440   /// execution.
    441   bool UseRetpolineIndirectCalls = false;
    442 
    443   /// Use a retpoline thunk or remove any indirect branch to block speculative
    444   /// execution.
    445   bool UseRetpolineIndirectBranches = false;
    446 
    447   /// Deprecated flag, query `UseRetpolineIndirectCalls` and
    448   /// `UseRetpolineIndirectBranches` instead.
    449   bool DeprecatedUseRetpoline = false;
    450 
    451   /// When using a retpoline thunk, call an externally provided thunk rather
    452   /// than emitting one inside the compiler.
    453   bool UseRetpolineExternalThunk = false;
    454 
    455   /// Prevent generation of indirect call/branch instructions from memory,
    456   /// and force all indirect call/branch instructions from a register to be
    457   /// preceded by an LFENCE. Also decompose RET instructions into a
    458   /// POP+LFENCE+JMP sequence.
    459   bool UseLVIControlFlowIntegrity = false;
    460 
    461   /// Enable Speculative Execution Side Effect Suppression
    462   bool UseSpeculativeExecutionSideEffectSuppression = false;
    463 
    464   /// Insert LFENCE instructions to prevent data speculatively injected into
    465   /// loads from being used maliciously.
    466   bool UseLVILoadHardening = false;
    467 
    468   /// Use software floating point for code generation.
    469   bool UseSoftFloat = false;
    470 
    471   /// Use alias analysis during code generation.
    472   bool UseAA = false;
    473 
    474   /// The minimum alignment known to hold of the stack frame on
    475   /// entry to the function and which must be maintained by every function.
    476   Align stackAlignment = Align(4);
    477 
    478   Align TileConfigAlignment = Align(4);
    479 
    480   /// Max. memset / memcpy size that is turned into rep/movs, rep/stos ops.
    481   ///
    482   // FIXME: this is a known good value for Yonah. How about others?
    483   unsigned MaxInlineSizeThreshold = 128;
    484 
    485   /// Indicates target prefers 128 bit instructions.
    486   bool Prefer128Bit = false;
    487 
    488   /// Indicates target prefers 256 bit instructions.
    489   bool Prefer256Bit = false;
    490 
    491   /// Indicates target prefers AVX512 mask registers.
    492   bool PreferMaskRegisters = false;
    493 
    494   /// Use Goldmont specific floating point div/sqrt costs.
    495   bool UseGLMDivSqrtCosts = false;
    496 
    497   /// What processor and OS we're targeting.
    498   Triple TargetTriple;
    499 
    500   /// GlobalISel related APIs.
    501   std::unique_ptr<CallLowering> CallLoweringInfo;
    502   std::unique_ptr<LegalizerInfo> Legalizer;
    503   std::unique_ptr<RegisterBankInfo> RegBankInfo;
    504   std::unique_ptr<InstructionSelector> InstSelector;
    505 
    506 private:
    507   /// Override the stack alignment.
    508   MaybeAlign StackAlignOverride;
    509 
    510   /// Preferred vector width from function attribute.
    511   unsigned PreferVectorWidthOverride;
    512 
    513   /// Resolved preferred vector width from function attribute and subtarget
    514   /// features.
    515   unsigned PreferVectorWidth = UINT32_MAX;
    516 
    517   /// Required vector width from function attribute.
    518   unsigned RequiredVectorWidth;
    519 
    520   /// True if compiling for 64-bit, false for 16-bit or 32-bit.
    521   bool In64BitMode = false;
    522 
    523   /// True if compiling for 32-bit, false for 16-bit or 64-bit.
    524   bool In32BitMode = false;
    525 
    526   /// True if compiling for 16-bit, false for 32-bit or 64-bit.
    527   bool In16BitMode = false;
    528 
    529   X86SelectionDAGInfo TSInfo;
    530   // Ordering here is important. X86InstrInfo initializes X86RegisterInfo which
    531   // X86TargetLowering needs.
    532   X86InstrInfo InstrInfo;
    533   X86TargetLowering TLInfo;
    534   X86FrameLowering FrameLowering;
    535 
    536 public:
    537   /// This constructor initializes the data members to match that
    538   /// of the specified triple.
    539   ///
    540   X86Subtarget(const Triple &TT, StringRef CPU, StringRef TuneCPU, StringRef FS,
    541                const X86TargetMachine &TM, MaybeAlign StackAlignOverride,
    542                unsigned PreferVectorWidthOverride,
    543                unsigned RequiredVectorWidth);
    544 
    545   const X86TargetLowering *getTargetLowering() const override {
    546     return &TLInfo;
    547   }
    548 
    549   const X86InstrInfo *getInstrInfo() const override { return &InstrInfo; }
    550 
    551   const X86FrameLowering *getFrameLowering() const override {
    552     return &FrameLowering;
    553   }
    554 
    555   const X86SelectionDAGInfo *getSelectionDAGInfo() const override {
    556     return &TSInfo;
    557   }
    558 
    559   const X86RegisterInfo *getRegisterInfo() const override {
    560     return &getInstrInfo()->getRegisterInfo();
    561   }
    562 
    563   unsigned getTileConfigSize() const { return 64; }
    564   Align getTileConfigAlignment() const { return TileConfigAlignment; }
    565 
    566   /// Returns the minimum alignment known to hold of the
    567   /// stack frame on entry to the function and which must be maintained by every
    568   /// function for this subtarget.
    569   Align getStackAlignment() const { return stackAlignment; }
    570 
    571   /// Returns the maximum memset / memcpy size
    572   /// that still makes it profitable to inline the call.
    573   unsigned getMaxInlineSizeThreshold() const { return MaxInlineSizeThreshold; }
    574 
    575   /// ParseSubtargetFeatures - Parses features string setting specified
    576   /// subtarget options.  Definition of function is auto generated by tblgen.
    577   void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
    578 
    579   /// Methods used by Global ISel
    580   const CallLowering *getCallLowering() const override;
    581   InstructionSelector *getInstructionSelector() const override;
    582   const LegalizerInfo *getLegalizerInfo() const override;
    583   const RegisterBankInfo *getRegBankInfo() const override;
    584 
    585 private:
    586   /// Initialize the full set of dependencies so we can use an initializer
    587   /// list for X86Subtarget.
    588   X86Subtarget &initializeSubtargetDependencies(StringRef CPU,
    589                                                 StringRef TuneCPU,
    590                                                 StringRef FS);
    591   void initSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
    592 
    593 public:
    594   /// Is this x86_64? (disregarding specific ABI / programming model)
    595   bool is64Bit() const {
    596     return In64BitMode;
    597   }
    598 
    599   bool is32Bit() const {
    600     return In32BitMode;
    601   }
    602 
    603   bool is16Bit() const {
    604     return In16BitMode;
    605   }
    606 
    607   /// Is this x86_64 with the ILP32 programming model (x32 ABI)?
    608   bool isTarget64BitILP32() const {
    609     return In64BitMode && (TargetTriple.getEnvironment() == Triple::GNUX32 ||
    610                            TargetTriple.isOSNaCl());
    611   }
    612 
    613   /// Is this x86_64 with the LP64 programming model (standard AMD64, no x32)?
    614   bool isTarget64BitLP64() const {
    615     return In64BitMode && (TargetTriple.getEnvironment() != Triple::GNUX32 &&
    616                            !TargetTriple.isOSNaCl());
    617   }
    618 
    619   PICStyles::Style getPICStyle() const { return PICStyle; }
    620   void setPICStyle(PICStyles::Style Style)  { PICStyle = Style; }
    621 
    622   bool hasX87() const { return HasX87; }
    623   bool hasCmpxchg8b() const { return HasCmpxchg8b; }
    624   bool hasNOPL() const { return HasNOPL; }
    625   // SSE codegen depends on cmovs, and all SSE1+ processors support them.
    626   // All 64-bit processors support cmov.
    627   bool hasCMov() const { return HasCMov || X86SSELevel >= SSE1 || is64Bit(); }
    628   bool hasSSE1() const { return X86SSELevel >= SSE1; }
    629   bool hasSSE2() const { return X86SSELevel >= SSE2; }
    630   bool hasSSE3() const { return X86SSELevel >= SSE3; }
    631   bool hasSSSE3() const { return X86SSELevel >= SSSE3; }
    632   bool hasSSE41() const { return X86SSELevel >= SSE41; }
    633   bool hasSSE42() const { return X86SSELevel >= SSE42; }
    634   bool hasAVX() const { return X86SSELevel >= AVX; }
    635   bool hasAVX2() const { return X86SSELevel >= AVX2; }
    636   bool hasAVX512() const { return X86SSELevel >= AVX512F; }
    637   bool hasInt256() const { return hasAVX2(); }
    638   bool hasSSE4A() const { return HasSSE4A; }
    639   bool hasMMX() const { return X863DNowLevel >= MMX; }
    640   bool has3DNow() const { return X863DNowLevel >= ThreeDNow; }
    641   bool has3DNowA() const { return X863DNowLevel >= ThreeDNowA; }
    642   bool hasPOPCNT() const { return HasPOPCNT; }
    643   bool hasAES() const { return HasAES; }
    644   bool hasVAES() const { return HasVAES; }
    645   bool hasFXSR() const { return HasFXSR; }
    646   bool hasXSAVE() const { return HasXSAVE; }
    647   bool hasXSAVEOPT() const { return HasXSAVEOPT; }
    648   bool hasXSAVEC() const { return HasXSAVEC; }
    649   bool hasXSAVES() const { return HasXSAVES; }
    650   bool hasPCLMUL() const { return HasPCLMUL; }
    651   bool hasVPCLMULQDQ() const { return HasVPCLMULQDQ; }
    652   bool hasGFNI() const { return HasGFNI; }
    653   // Prefer FMA4 to FMA - its better for commutation/memory folding and
    654   // has equal or better performance on all supported targets.
    655   bool hasFMA() const { return HasFMA; }
    656   bool hasFMA4() const { return HasFMA4; }
    657   bool hasAnyFMA() const { return hasFMA() || hasFMA4(); }
    658   bool hasXOP() const { return HasXOP; }
    659   bool hasTBM() const { return HasTBM; }
    660   bool hasLWP() const { return HasLWP; }
    661   bool hasMOVBE() const { return HasMOVBE; }
    662   bool hasRDRAND() const { return HasRDRAND; }
    663   bool hasF16C() const { return HasF16C; }
    664   bool hasFSGSBase() const { return HasFSGSBase; }
    665   bool hasLZCNT() const { return HasLZCNT; }
    666   bool hasBMI() const { return HasBMI; }
    667   bool hasBMI2() const { return HasBMI2; }
    668   bool hasVBMI() const { return HasVBMI; }
    669   bool hasVBMI2() const { return HasVBMI2; }
    670   bool hasIFMA() const { return HasIFMA; }
    671   bool hasRTM() const { return HasRTM; }
    672   bool hasADX() const { return HasADX; }
    673   bool hasSHA() const { return HasSHA; }
    674   bool hasPRFCHW() const { return HasPRFCHW; }
    675   bool hasPREFETCHWT1() const { return HasPREFETCHWT1; }
    676   bool hasPrefetchW() const {
    677     // The PREFETCHW instruction was added with 3DNow but later CPUs gave it
    678     // its own CPUID bit as part of deprecating 3DNow. Intel eventually added
    679     // it and KNL has another that prefetches to L2 cache. We assume the
    680     // L1 version exists if the L2 version does.
    681     return has3DNow() || hasPRFCHW() || hasPREFETCHWT1();
    682   }
    683   bool hasSSEPrefetch() const {
    684     // We implicitly enable these when we have a write prefix supporting cache
    685     // level OR if we have prfchw, but don't already have a read prefetch from
    686     // 3dnow.
    687     return hasSSE1() || (hasPRFCHW() && !has3DNow()) || hasPREFETCHWT1();
    688   }
    689   bool hasRDSEED() const { return HasRDSEED; }
    690   bool hasLAHFSAHF() const { return HasLAHFSAHF64 || !is64Bit(); }
    691   bool hasMWAITX() const { return HasMWAITX; }
    692   bool hasCLZERO() const { return HasCLZERO; }
    693   bool hasCLDEMOTE() const { return HasCLDEMOTE; }
    694   bool hasMOVDIRI() const { return HasMOVDIRI; }
    695   bool hasMOVDIR64B() const { return HasMOVDIR64B; }
    696   bool hasPTWRITE() const { return HasPTWRITE; }
    697   bool isSHLDSlow() const { return IsSHLDSlow; }
    698   bool isPMULLDSlow() const { return IsPMULLDSlow; }
    699   bool isPMADDWDSlow() const { return IsPMADDWDSlow; }
    700   bool isUnalignedMem16Slow() const { return IsUAMem16Slow; }
    701   bool isUnalignedMem32Slow() const { return IsUAMem32Slow; }
    702   bool hasSSEUnalignedMem() const { return HasSSEUnalignedMem; }
    703   bool hasCmpxchg16b() const { return HasCmpxchg16b && is64Bit(); }
    704   bool useLeaForSP() const { return UseLeaForSP; }
    705   bool hasPOPCNTFalseDeps() const { return HasPOPCNTFalseDeps; }
    706   bool hasLZCNTFalseDeps() const { return HasLZCNTFalseDeps; }
    707   bool hasFastVariableShuffle() const {
    708     return HasFastVariableShuffle;
    709   }
    710   bool insertVZEROUPPER() const { return InsertVZEROUPPER; }
    711   bool hasFastGather() const { return HasFastGather; }
    712   bool hasFastScalarFSQRT() const { return HasFastScalarFSQRT; }
    713   bool hasFastVectorFSQRT() const { return HasFastVectorFSQRT; }
    714   bool hasFastLZCNT() const { return HasFastLZCNT; }
    715   bool hasFastSHLDRotate() const { return HasFastSHLDRotate; }
    716   bool hasFastBEXTR() const { return HasFastBEXTR; }
    717   bool hasFastHorizontalOps() const { return HasFastHorizontalOps; }
    718   bool hasFastScalarShiftMasks() const { return HasFastScalarShiftMasks; }
    719   bool hasFastVectorShiftMasks() const { return HasFastVectorShiftMasks; }
    720   bool hasFastMOVBE() const { return HasFastMOVBE; }
    721   bool hasMacroFusion() const { return HasMacroFusion; }
    722   bool hasBranchFusion() const { return HasBranchFusion; }
    723   bool hasERMSB() const { return HasERMSB; }
    724   bool hasFSRM() const { return HasFSRM; }
    725   bool hasSlowDivide32() const { return HasSlowDivide32; }
    726   bool hasSlowDivide64() const { return HasSlowDivide64; }
    727   bool padShortFunctions() const { return PadShortFunctions; }
    728   bool slowTwoMemOps() const { return SlowTwoMemOps; }
    729   bool LEAusesAG() const { return LEAUsesAG; }
    730   bool slowLEA() const { return SlowLEA; }
    731   bool slow3OpsLEA() const { return Slow3OpsLEA; }
    732   bool slowIncDec() const { return SlowIncDec; }
    733   bool hasCDI() const { return HasCDI; }
    734   bool hasVPOPCNTDQ() const { return HasVPOPCNTDQ; }
    735   bool hasPFI() const { return HasPFI; }
    736   bool hasERI() const { return HasERI; }
    737   bool hasDQI() const { return HasDQI; }
    738   bool hasBWI() const { return HasBWI; }
    739   bool hasVLX() const { return HasVLX; }
    740   bool hasPKU() const { return HasPKU; }
    741   bool hasVNNI() const { return HasVNNI; }
    742   bool hasBF16() const { return HasBF16; }
    743   bool hasVP2INTERSECT() const { return HasVP2INTERSECT; }
    744   bool hasBITALG() const { return HasBITALG; }
    745   bool hasSHSTK() const { return HasSHSTK; }
    746   bool hasCLFLUSHOPT() const { return HasCLFLUSHOPT; }
    747   bool hasCLWB() const { return HasCLWB; }
    748   bool hasWBNOINVD() const { return HasWBNOINVD; }
    749   bool hasRDPID() const { return HasRDPID; }
    750   bool hasWAITPKG() const { return HasWAITPKG; }
    751   bool hasPCONFIG() const { return HasPCONFIG; }
    752   bool hasSGX() const { return HasSGX; }
    753   bool hasINVPCID() const { return HasINVPCID; }
    754   bool hasENQCMD() const { return HasENQCMD; }
    755   bool hasKL() const { return HasKL; }
    756   bool hasWIDEKL() const { return HasWIDEKL; }
    757   bool hasHRESET() const { return HasHRESET; }
    758   bool hasSERIALIZE() const { return HasSERIALIZE; }
    759   bool hasTSXLDTRK() const { return HasTSXLDTRK; }
    760   bool hasUINTR() const { return HasUINTR; }
    761   bool useRetpolineIndirectCalls() const { return UseRetpolineIndirectCalls; }
    762   bool useRetpolineIndirectBranches() const {
    763     return UseRetpolineIndirectBranches;
    764   }
    765   bool hasAVXVNNI() const { return HasAVXVNNI; }
    766   bool hasAMXTILE() const { return HasAMXTILE; }
    767   bool hasAMXBF16() const { return HasAMXBF16; }
    768   bool hasAMXINT8() const { return HasAMXINT8; }
    769   bool useRetpolineExternalThunk() const { return UseRetpolineExternalThunk; }
    770 
    771   // These are generic getters that OR together all of the thunk types
    772   // supported by the subtarget. Therefore useIndirectThunk*() will return true
    773   // if any respective thunk feature is enabled.
    774   bool useIndirectThunkCalls() const {
    775     return useRetpolineIndirectCalls() || useLVIControlFlowIntegrity();
    776   }
    777   bool useIndirectThunkBranches() const {
    778     return useRetpolineIndirectBranches() || useLVIControlFlowIntegrity();
    779   }
    780 
    781   bool preferMaskRegisters() const { return PreferMaskRegisters; }
    782   bool useGLMDivSqrtCosts() const { return UseGLMDivSqrtCosts; }
    783   bool useLVIControlFlowIntegrity() const { return UseLVIControlFlowIntegrity; }
    784   bool useLVILoadHardening() const { return UseLVILoadHardening; }
    785   bool useSpeculativeExecutionSideEffectSuppression() const {
    786     return UseSpeculativeExecutionSideEffectSuppression;
    787   }
    788 
    789   unsigned getPreferVectorWidth() const { return PreferVectorWidth; }
    790   unsigned getRequiredVectorWidth() const { return RequiredVectorWidth; }
    791 
    792   // Helper functions to determine when we should allow widening to 512-bit
    793   // during codegen.
    794   // TODO: Currently we're always allowing widening on CPUs without VLX,
    795   // because for many cases we don't have a better option.
    796   bool canExtendTo512DQ() const {
    797     return hasAVX512() && (!hasVLX() || getPreferVectorWidth() >= 512);
    798   }
    799   bool canExtendTo512BW() const  {
    800     return hasBWI() && canExtendTo512DQ();
    801   }
    802 
    803   // If there are no 512-bit vectors and we prefer not to use 512-bit registers,
    804   // disable them in the legalizer.
    805   bool useAVX512Regs() const {
    806     return hasAVX512() && (canExtendTo512DQ() || RequiredVectorWidth > 256);
    807   }
    808 
    809   bool useBWIRegs() const {
    810     return hasBWI() && useAVX512Regs();
    811   }
    812 
    813   bool isXRaySupported() const override { return is64Bit(); }
    814 
    815   /// TODO: to be removed later and replaced with suitable properties
    816   bool isAtom() const { return X86ProcFamily == IntelAtom; }
    817   bool isSLM() const { return X86ProcFamily == IntelSLM; }
    818   bool useSoftFloat() const { return UseSoftFloat; }
    819   bool useAA() const override { return UseAA; }
    820 
    821   /// Use mfence if we have SSE2 or we're on x86-64 (even if we asked for
    822   /// no-sse2). There isn't any reason to disable it if the target processor
    823   /// supports it.
    824   bool hasMFence() const { return hasSSE2() || is64Bit(); }
    825 
    826   const Triple &getTargetTriple() const { return TargetTriple; }
    827 
    828   bool isTargetDarwin() const { return TargetTriple.isOSDarwin(); }
    829   bool isTargetFreeBSD() const { return TargetTriple.isOSFreeBSD(); }
    830   bool isTargetDragonFly() const { return TargetTriple.isOSDragonFly(); }
    831   bool isTargetSolaris() const { return TargetTriple.isOSSolaris(); }
    832   bool isTargetPS4() const { return TargetTriple.isPS4CPU(); }
    833 
    834   bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }
    835   bool isTargetCOFF() const { return TargetTriple.isOSBinFormatCOFF(); }
    836   bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); }
    837 
    838   bool isTargetLinux() const { return TargetTriple.isOSLinux(); }
    839   bool isTargetKFreeBSD() const { return TargetTriple.isOSKFreeBSD(); }
    840   bool isTargetGlibc() const { return TargetTriple.isOSGlibc(); }
    841   bool isTargetAndroid() const { return TargetTriple.isAndroid(); }
    842   bool isTargetNaCl() const { return TargetTriple.isOSNaCl(); }
    843   bool isTargetNaCl32() const { return isTargetNaCl() && !is64Bit(); }
    844   bool isTargetNaCl64() const { return isTargetNaCl() && is64Bit(); }
    845   bool isTargetMCU() const { return TargetTriple.isOSIAMCU(); }
    846   bool isTargetFuchsia() const { return TargetTriple.isOSFuchsia(); }
    847 
    848   bool isTargetWindowsMSVC() const {
    849     return TargetTriple.isWindowsMSVCEnvironment();
    850   }
    851 
    852   bool isTargetWindowsCoreCLR() const {
    853     return TargetTriple.isWindowsCoreCLREnvironment();
    854   }
    855 
    856   bool isTargetWindowsCygwin() const {
    857     return TargetTriple.isWindowsCygwinEnvironment();
    858   }
    859 
    860   bool isTargetWindowsGNU() const {
    861     return TargetTriple.isWindowsGNUEnvironment();
    862   }
    863 
    864   bool isTargetWindowsItanium() const {
    865     return TargetTriple.isWindowsItaniumEnvironment();
    866   }
    867 
    868   bool isTargetCygMing() const { return TargetTriple.isOSCygMing(); }
    869 
    870   bool isOSWindows() const { return TargetTriple.isOSWindows(); }
    871 
    872   bool isTargetWin64() const { return In64BitMode && isOSWindows(); }
    873 
    874   bool isTargetWin32() const { return !In64BitMode && isOSWindows(); }
    875 
    876   bool isPICStyleGOT() const { return PICStyle == PICStyles::Style::GOT; }
    877   bool isPICStyleRIPRel() const { return PICStyle == PICStyles::Style::RIPRel; }
    878 
    879   bool isPICStyleStubPIC() const {
    880     return PICStyle == PICStyles::Style::StubPIC;
    881   }
    882 
    883   bool isPositionIndependent() const;
    884 
    885   bool isCallingConvWin64(CallingConv::ID CC) const {
    886     switch (CC) {
    887     // On Win64, all these conventions just use the default convention.
    888     case CallingConv::C:
    889     case CallingConv::Fast:
    890     case CallingConv::Tail:
    891     case CallingConv::Swift:
    892     case CallingConv::SwiftTail:
    893     case CallingConv::X86_FastCall:
    894     case CallingConv::X86_StdCall:
    895     case CallingConv::X86_ThisCall:
    896     case CallingConv::X86_VectorCall:
    897     case CallingConv::Intel_OCL_BI:
    898       return isTargetWin64();
    899     // This convention allows using the Win64 convention on other targets.
    900     case CallingConv::Win64:
    901       return true;
    902     // This convention allows using the SysV convention on Windows targets.
    903     case CallingConv::X86_64_SysV:
    904       return false;
    905     // Otherwise, who knows what this is.
    906     default:
    907       return false;
    908     }
    909   }
    910 
    911   /// Classify a global variable reference for the current subtarget according
    912   /// to how we should reference it in a non-pcrel context.
    913   unsigned char classifyLocalReference(const GlobalValue *GV) const;
    914 
    915   unsigned char classifyGlobalReference(const GlobalValue *GV,
    916                                         const Module &M) const;
    917   unsigned char classifyGlobalReference(const GlobalValue *GV) const;
    918 
    919   /// Classify a global function reference for the current subtarget.
    920   unsigned char classifyGlobalFunctionReference(const GlobalValue *GV,
    921                                                 const Module &M) const;
    922   unsigned char classifyGlobalFunctionReference(const GlobalValue *GV) const;
    923 
    924   /// Classify a blockaddress reference for the current subtarget according to
    925   /// how we should reference it in a non-pcrel context.
    926   unsigned char classifyBlockAddressReference() const;
    927 
    928   /// Return true if the subtarget allows calls to immediate address.
    929   bool isLegalToCallImmediateAddr() const;
    930 
    931   /// If we are using indirect thunks, we need to expand indirectbr to avoid it
    932   /// lowering to an actual indirect jump.
    933   bool enableIndirectBrExpand() const override {
    934     return useIndirectThunkBranches();
    935   }
    936 
    937   /// Enable the MachineScheduler pass for all X86 subtargets.
    938   bool enableMachineScheduler() const override { return true; }
    939 
    940   bool enableEarlyIfConversion() const override;
    941 
    942   void getPostRAMutations(std::vector<std::unique_ptr<ScheduleDAGMutation>>
    943                               &Mutations) const override;
    944 
    945   AntiDepBreakMode getAntiDepBreakMode() const override {
    946     return TargetSubtargetInfo::ANTIDEP_CRITICAL;
    947   }
    948 
    949   bool enableAdvancedRASplitCost() const override { return false; }
    950 };
    951 
    952 } // end namespace llvm
    953 
    954 #endif // LLVM_LIB_TARGET_X86_X86SUBTARGET_H
    955