1234353Sdim//===-- X86Subtarget.h - Define Subtarget for the X86 ----------*- C++ -*--===// 2193323Sed// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6193323Sed// 7193323Sed//===----------------------------------------------------------------------===// 8193323Sed// 9224145Sdim// This file declares the X86 specific subclass of TargetSubtargetInfo. 10193323Sed// 11193323Sed//===----------------------------------------------------------------------===// 12193323Sed 13280031Sdim#ifndef LLVM_LIB_TARGET_X86_X86SUBTARGET_H 14280031Sdim#define LLVM_LIB_TARGET_X86_X86SUBTARGET_H 15193323Sed 16276479Sdim#include "X86FrameLowering.h" 17276479Sdim#include "X86ISelLowering.h" 18276479Sdim#include "X86InstrInfo.h" 19276479Sdim#include "X86SelectionDAGInfo.h" 20321369Sdim#include "llvm/ADT/StringRef.h" 21210299Sed#include "llvm/ADT/Triple.h" 22327952Sdim#include "llvm/CodeGen/GlobalISel/CallLowering.h" 23327952Sdim#include "llvm/CodeGen/GlobalISel/InstructionSelector.h" 24327952Sdim#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" 25327952Sdim#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h" 26327952Sdim#include "llvm/CodeGen/TargetSubtargetInfo.h" 27249423Sdim#include "llvm/IR/CallingConv.h" 28321369Sdim#include "llvm/Target/TargetMachine.h" 29341825Sdim#include <climits> 30321369Sdim#include <memory> 31193323Sed 32224145Sdim#define GET_SUBTARGETINFO_HEADER 33224145Sdim#include "X86GenSubtargetInfo.inc" 34224145Sdim 35193323Sednamespace llvm { 36321369Sdim 37193323Sedclass GlobalValue; 38204642Srdivacky 39288943Sdim/// The X86 backend supports a number of different styles of PIC. 40204642Srdivacky/// 41193323Sednamespace PICStyles { 42321369Sdim 43360784Sdimenum class Style { 44309124Sdim StubPIC, // Used on i386-darwin in pic mode. 45309124Sdim GOT, // Used on 32 bit elf on when in pic mode. 46309124Sdim RIPRel, // Used on X86-64 when in pic mode. 47309124Sdim None // Set when not in pic mode. 48193323Sed}; 49193323Sed 50321369Sdim} // end namespace PICStyles 51321369Sdim 52276479Sdimclass X86Subtarget final : public X86GenSubtargetInfo { 53341825Sdimpublic: 54344779Sdim // NOTE: Do not add anything new to this list. Coarse, CPU name based flags 55344779Sdim // are not a good idea. We should be migrating away from these. 56327952Sdim enum X86ProcFamilyEnum { 57327952Sdim Others, 58327952Sdim IntelAtom, 59360784Sdim IntelSLM 60327952Sdim }; 61327952Sdim 62193323Sedprotected: 63193323Sed enum X86SSEEnum { 64296417Sdim NoSSE, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42, AVX, AVX2, AVX512F 65193323Sed }; 66193323Sed 67193323Sed enum X863DNowEnum { 68296417Sdim NoThreeDNow, MMX, ThreeDNow, ThreeDNowA 69193323Sed }; 70193323Sed 71288943Sdim /// X86 processor family: Intel Atom, and others 72341825Sdim X86ProcFamilyEnum X86ProcFamily = Others; 73239462Sdim 74288943Sdim /// Which PIC style to use 75193323Sed PICStyles::Style PICStyle; 76204642Srdivacky 77309124Sdim const TargetMachine &TM; 78309124Sdim 79296417Sdim /// SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42, or none supported. 80341825Sdim X86SSEEnum X86SSELevel = NoSSE; 81193323Sed 82296417Sdim /// MMX, 3DNow, 3DNow Athlon, or none supported. 83341825Sdim X863DNowEnum X863DNowLevel = NoThreeDNow; 84193323Sed 85309124Sdim /// True if the processor supports X87 instructions. 86341825Sdim bool HasX87 = false; 87309124Sdim 88353358Sdim /// True if the processor supports CMPXCHG8B. 89353358Sdim bool HasCmpxchg8b = false; 90353358Sdim 91341825Sdim /// True if this processor has NOPL instruction 92341825Sdim /// (generally pentium pro+). 93341825Sdim bool HasNOPL = false; 94341825Sdim 95288943Sdim /// True if this processor has conditional move instructions 96198090Srdivacky /// (generally pentium pro+). 97341825Sdim bool HasCMov = false; 98204642Srdivacky 99288943Sdim /// True if the processor supports X86-64 instructions. 100341825Sdim bool HasX86_64 = false; 101193323Sed 102288943Sdim /// True if the processor supports POPCNT. 103341825Sdim bool HasPOPCNT = false; 104218893Sdim 105288943Sdim /// True if the processor supports SSE4A instructions. 106341825Sdim bool HasSSE4A = false; 107195098Sed 108288943Sdim /// Target has AES instructions 109341825Sdim bool HasAES = false; 110341825Sdim bool HasVAES = false; 111206124Srdivacky 112296417Sdim /// Target has FXSAVE/FXRESTOR instructions 113341825Sdim bool HasFXSR = false; 114296417Sdim 115296417Sdim /// Target has XSAVE instructions 116341825Sdim bool HasXSAVE = false; 117321369Sdim 118296417Sdim /// Target has XSAVEOPT instructions 119341825Sdim bool HasXSAVEOPT = false; 120321369Sdim 121296417Sdim /// Target has XSAVEC instructions 122341825Sdim bool HasXSAVEC = false; 123321369Sdim 124296417Sdim /// Target has XSAVES instructions 125341825Sdim bool HasXSAVES = false; 126296417Sdim 127288943Sdim /// Target has carry-less multiplication 128341825Sdim bool HasPCLMUL = false; 129341825Sdim bool HasVPCLMULQDQ = false; 130212904Sdim 131327952Sdim /// Target has Galois Field Arithmetic instructions 132341825Sdim bool HasGFNI = false; 133327952Sdim 134288943Sdim /// Target has 3-operand fused multiply-add 135341825Sdim bool HasFMA = false; 136195098Sed 137288943Sdim /// Target has 4-operand fused multiply-add 138341825Sdim bool HasFMA4 = false; 139195098Sed 140288943Sdim /// Target has XOP instructions 141341825Sdim bool HasXOP = false; 142234353Sdim 143288943Sdim /// Target has TBM instructions. 144341825Sdim bool HasTBM = false; 145261991Sdim 146321369Sdim /// Target has LWP instructions 147341825Sdim bool HasLWP = false; 148321369Sdim 149288943Sdim /// True if the processor has the MOVBE instruction. 150341825Sdim bool HasMOVBE = false; 151226633Sdim 152288943Sdim /// True if the processor has the RDRAND instruction. 153341825Sdim bool HasRDRAND = false; 154226633Sdim 155288943Sdim /// Processor has 16-bit floating point conversion instructions. 156341825Sdim bool HasF16C = false; 157226633Sdim 158288943Sdim /// Processor has FS/GS base insturctions. 159341825Sdim bool HasFSGSBase = false; 160234353Sdim 161288943Sdim /// Processor has LZCNT instruction. 162341825Sdim bool HasLZCNT = false; 163226633Sdim 164288943Sdim /// Processor has BMI1 instructions. 165341825Sdim bool HasBMI = false; 166226633Sdim 167288943Sdim /// Processor has BMI2 instructions. 168341825Sdim bool HasBMI2 = false; 169234353Sdim 170309124Sdim /// Processor has VBMI instructions. 171341825Sdim bool HasVBMI = false; 172309124Sdim 173327952Sdim /// Processor has VBMI2 instructions. 174341825Sdim bool HasVBMI2 = false; 175327952Sdim 176309124Sdim /// Processor has Integer Fused Multiply Add 177341825Sdim bool HasIFMA = false; 178309124Sdim 179288943Sdim /// Processor has RTM instructions. 180341825Sdim bool HasRTM = false; 181243830Sdim 182288943Sdim /// Processor has ADX instructions. 183341825Sdim bool HasADX = false; 184249423Sdim 185288943Sdim /// Processor has SHA instructions. 186341825Sdim bool HasSHA = false; 187261991Sdim 188288943Sdim /// Processor has PRFCHW instructions. 189341825Sdim bool HasPRFCHW = false; 190249423Sdim 191288943Sdim /// Processor has RDSEED instructions. 192341825Sdim bool HasRDSEED = false; 193249423Sdim 194296417Sdim /// Processor has LAHF/SAHF instructions. 195341825Sdim bool HasLAHFSAHF = false; 196296417Sdim 197309124Sdim /// Processor has MONITORX/MWAITX instructions. 198341825Sdim bool HasMWAITX = false; 199309124Sdim 200321369Sdim /// Processor has Cache Line Zero instruction 201341825Sdim bool HasCLZERO = false; 202321369Sdim 203341825Sdim /// Processor has Cache Line Demote instruction 204341825Sdim bool HasCLDEMOTE = false; 205341825Sdim 206341825Sdim /// Processor has MOVDIRI instruction (direct store integer). 207341825Sdim bool HasMOVDIRI = false; 208341825Sdim 209341825Sdim /// Processor has MOVDIR64B instruction (direct store 64 bytes). 210341825Sdim bool HasMOVDIR64B = false; 211341825Sdim 212341825Sdim /// Processor has ptwrite instruction. 213341825Sdim bool HasPTWRITE = false; 214341825Sdim 215309124Sdim /// Processor has Prefetch with intent to Write instruction 216341825Sdim bool HasPREFETCHWT1 = false; 217309124Sdim 218288943Sdim /// True if SHLD instructions are slow. 219341825Sdim bool IsSHLDSlow = false; 220276479Sdim 221314564Sdim /// True if the PMULLD instruction is slow compared to PMULLW/PMULHW and 222314564Sdim // PMULUDQ. 223341825Sdim bool IsPMULLDSlow = false; 224314564Sdim 225344779Sdim /// True if the PMADDWD instruction is slow compared to PMULLD. 226344779Sdim bool IsPMADDWDSlow = false; 227344779Sdim 228296417Sdim /// True if unaligned memory accesses of 16-bytes are slow. 229341825Sdim bool IsUAMem16Slow = false; 230206083Srdivacky 231296417Sdim /// True if unaligned memory accesses of 32-bytes are slow. 232341825Sdim bool IsUAMem32Slow = false; 233202375Srdivacky 234280031Sdim /// True if SSE operations can have unaligned memory operands. 235280031Sdim /// This may require setting a configuration bit in the processor. 236341825Sdim bool HasSSEUnalignedMem = false; 237280031Sdim 238288943Sdim /// True if this processor has the CMPXCHG16B instruction; 239226633Sdim /// this is true for most x86-64 chips, but not the first AMD chips. 240341825Sdim bool HasCmpxchg16b = false; 241226633Sdim 242288943Sdim /// True if the LEA instruction should be used for adjusting 243234353Sdim /// the stack pointer. This is an optimization for Intel Atom processors. 244341825Sdim bool UseLeaForSP = false; 245234353Sdim 246341825Sdim /// True if POPCNT instruction has a false dependency on the destination register. 247341825Sdim bool HasPOPCNTFalseDeps = false; 248341825Sdim 249341825Sdim /// True if LZCNT/TZCNT instructions have a false dependency on the destination register. 250341825Sdim bool HasLZCNTFalseDeps = false; 251341825Sdim 252327952Sdim /// True if its preferable to combine to a single shuffle using a variable 253327952Sdim /// mask over multiple fixed shuffles. 254341825Sdim bool HasFastVariableShuffle = false; 255327952Sdim 256360784Sdim /// True if vzeroupper instructions should be inserted after code that uses 257360784Sdim /// ymm or zmm registers. 258360784Sdim bool InsertVZEROUPPER = false; 259309124Sdim 260341825Sdim /// True if there is no performance penalty for writing NOPs with up to 261341825Sdim /// 11 bytes. 262341825Sdim bool HasFast11ByteNOP = false; 263341825Sdim 264341825Sdim /// True if there is no performance penalty for writing NOPs with up to 265341825Sdim /// 15 bytes. 266341825Sdim bool HasFast15ByteNOP = false; 267341825Sdim 268327952Sdim /// True if gather is reasonably fast. This is true for Skylake client and 269327952Sdim /// all AVX-512 CPUs. 270341825Sdim bool HasFastGather = false; 271327952Sdim 272314564Sdim /// True if hardware SQRTSS instruction is at least as fast (latency) as 273314564Sdim /// RSQRTSS followed by a Newton-Raphson iteration. 274341825Sdim bool HasFastScalarFSQRT = false; 275314564Sdim 276314564Sdim /// True if hardware SQRTPS/VSQRTPS instructions are at least as fast 277314564Sdim /// (throughput) as RSQRTPS/VRSQRTPS followed by a Newton-Raphson iteration. 278341825Sdim bool HasFastVectorFSQRT = false; 279314564Sdim 280288943Sdim /// True if 8-bit divisions are significantly faster than 281280031Sdim /// 32-bit divisions and should be used when possible. 282341825Sdim bool HasSlowDivide32 = false; 283243830Sdim 284314564Sdim /// True if 32-bit divides are significantly faster than 285280031Sdim /// 64-bit divisions and should be used when possible. 286341825Sdim bool HasSlowDivide64 = false; 287280031Sdim 288314564Sdim /// True if LZCNT instruction is fast. 289341825Sdim bool HasFastLZCNT = false; 290314564Sdim 291321369Sdim /// True if SHLD based rotate is fast. 292341825Sdim bool HasFastSHLDRotate = false; 293321369Sdim 294327952Sdim /// True if the processor supports macrofusion. 295341825Sdim bool HasMacroFusion = false; 296327952Sdim 297353358Sdim /// True if the processor supports branch fusion. 298353358Sdim bool HasBranchFusion = false; 299353358Sdim 300321369Sdim /// True if the processor has enhanced REP MOVSB/STOSB. 301341825Sdim bool HasERMSB = false; 302321369Sdim 303288943Sdim /// True if the short functions should be padded to prevent 304249423Sdim /// a stall when returning too early. 305341825Sdim bool PadShortFunctions = false; 306249423Sdim 307327952Sdim /// True if two memory operand instructions should use a temporary register 308327952Sdim /// instead. 309341825Sdim bool SlowTwoMemOps = false; 310288943Sdim 311288943Sdim /// True if the LEA instruction inputs have to be ready at address generation 312288943Sdim /// (AG) time. 313341825Sdim bool LEAUsesAG = false; 314249423Sdim 315288943Sdim /// True if the LEA instruction with certain arguments is slow 316341825Sdim bool SlowLEA = false; 317276479Sdim 318321369Sdim /// True if the LEA instruction has all three source operands: base, index, 319321369Sdim /// and offset or if the LEA instruction uses base and index registers where 320321369Sdim /// the base is EBP, RBP,or R13 321341825Sdim bool Slow3OpsLEA = false; 322321369Sdim 323288943Sdim /// True if INC and DEC instructions are slow when writing to flags 324341825Sdim bool SlowIncDec = false; 325276479Sdim 326261991Sdim /// Processor has AVX-512 PreFetch Instructions 327341825Sdim bool HasPFI = false; 328276479Sdim 329261991Sdim /// Processor has AVX-512 Exponential and Reciprocal Instructions 330341825Sdim bool HasERI = false; 331276479Sdim 332261991Sdim /// Processor has AVX-512 Conflict Detection Instructions 333341825Sdim bool HasCDI = false; 334276479Sdim 335321369Sdim /// Processor has AVX-512 population count Instructions 336341825Sdim bool HasVPOPCNTDQ = false; 337321369Sdim 338276479Sdim /// Processor has AVX-512 Doubleword and Quadword instructions 339341825Sdim bool HasDQI = false; 340276479Sdim 341276479Sdim /// Processor has AVX-512 Byte and Word instructions 342341825Sdim bool HasBWI = false; 343276479Sdim 344276479Sdim /// Processor has AVX-512 Vector Length eXtenstions 345341825Sdim bool HasVLX = false; 346276479Sdim 347296417Sdim /// Processor has PKU extenstions 348341825Sdim bool HasPKU = false; 349296417Sdim 350327952Sdim /// Processor has AVX-512 Vector Neural Network Instructions 351341825Sdim bool HasVNNI = false; 352327952Sdim 353353358Sdim /// Processor has AVX-512 bfloat16 floating-point extensions 354353358Sdim bool HasBF16 = false; 355353358Sdim 356353358Sdim /// Processor supports ENQCMD instructions 357353358Sdim bool HasENQCMD = false; 358353358Sdim 359327952Sdim /// Processor has AVX-512 Bit Algorithms instructions 360341825Sdim bool HasBITALG = false; 361327952Sdim 362353358Sdim /// Processor has AVX-512 vp2intersect instructions 363353358Sdim bool HasVP2INTERSECT = false; 364353358Sdim 365360784Sdim /// Deprecated flag for MPX instructions. 366360784Sdim bool DeprecatedHasMPX = false; 367288943Sdim 368327952Sdim /// Processor supports CET SHSTK - Control-Flow Enforcement Technology 369327952Sdim /// using Shadow Stack 370341825Sdim bool HasSHSTK = false; 371327952Sdim 372341825Sdim /// Processor supports Invalidate Process-Context Identifier 373341825Sdim bool HasINVPCID = false; 374327952Sdim 375309124Sdim /// Processor has Software Guard Extensions 376341825Sdim bool HasSGX = false; 377309124Sdim 378309124Sdim /// Processor supports Flush Cache Line instruction 379341825Sdim bool HasCLFLUSHOPT = false; 380309124Sdim 381309124Sdim /// Processor supports Cache Line Write Back instruction 382341825Sdim bool HasCLWB = false; 383309124Sdim 384341825Sdim /// Processor supports Write Back No Invalidate instruction 385341825Sdim bool HasWBNOINVD = false; 386341825Sdim 387341825Sdim /// Processor support RDPID instruction 388341825Sdim bool HasRDPID = false; 389341825Sdim 390341825Sdim /// Processor supports WaitPKG instructions 391341825Sdim bool HasWAITPKG = false; 392341825Sdim 393341825Sdim /// Processor supports PCONFIG instruction 394341825Sdim bool HasPCONFIG = false; 395341825Sdim 396344779Sdim /// Processor has a single uop BEXTR implementation. 397344779Sdim bool HasFastBEXTR = false; 398344779Sdim 399344779Sdim /// Try harder to combine to horizontal vector ops if they are fast. 400344779Sdim bool HasFastHorizontalOps = false; 401344779Sdim 402353358Sdim /// Prefer a left/right scalar logical shifts pair over a shift+and pair. 403353358Sdim bool HasFastScalarShiftMasks = false; 404353358Sdim 405353358Sdim /// Prefer a left/right vector logical shifts pair over a shift+and pair. 406353358Sdim bool HasFastVectorShiftMasks = false; 407353358Sdim 408328817Sdim /// Use a retpoline thunk rather than indirect calls to block speculative 409328817Sdim /// execution. 410344779Sdim bool UseRetpolineIndirectCalls = false; 411328817Sdim 412344779Sdim /// Use a retpoline thunk or remove any indirect branch to block speculative 413344779Sdim /// execution. 414344779Sdim bool UseRetpolineIndirectBranches = false; 415344779Sdim 416344779Sdim /// Deprecated flag, query `UseRetpolineIndirectCalls` and 417344779Sdim /// `UseRetpolineIndirectBranches` instead. 418344779Sdim bool DeprecatedUseRetpoline = false; 419344779Sdim 420328817Sdim /// When using a retpoline thunk, call an externally provided thunk rather 421328817Sdim /// than emitting one inside the compiler. 422341825Sdim bool UseRetpolineExternalThunk = false; 423328817Sdim 424363496Sdim /// Prevent generation of indirect call/branch instructions from memory, 425363496Sdim /// and force all indirect call/branch instructions from a register to be 426363496Sdim /// preceded by an LFENCE. Also decompose RET instructions into a 427363496Sdim /// POP+LFENCE+JMP sequence. 428363496Sdim bool UseLVIControlFlowIntegrity = false; 429363496Sdim 430363496Sdim /// Insert LFENCE instructions to prevent data speculatively injected into 431363496Sdim /// loads from being used maliciously. 432363496Sdim bool UseLVILoadHardening = false; 433363496Sdim 434288943Sdim /// Use software floating point for code generation. 435341825Sdim bool UseSoftFloat = false; 436288943Sdim 437360784Sdim /// Use alias analysis during code generation. 438360784Sdim bool UseAA = false; 439360784Sdim 440288943Sdim /// The minimum alignment known to hold of the stack frame on 441193323Sed /// entry to the function and which must be maintained by every function. 442360784Sdim Align stackAlignment = Align(4); 443193323Sed 444193323Sed /// Max. memset / memcpy size that is turned into rep/movs, rep/stos ops. 445193323Sed /// 446341825Sdim // FIXME: this is a known good value for Yonah. How about others? 447341825Sdim unsigned MaxInlineSizeThreshold = 128; 448218893Sdim 449360784Sdim /// Indicates target prefers 128 bit instructions. 450360784Sdim bool Prefer128Bit = false; 451360784Sdim 452341825Sdim /// Indicates target prefers 256 bit instructions. 453341825Sdim bool Prefer256Bit = false; 454341825Sdim 455360784Sdim /// Indicates target prefers AVX512 mask registers. 456360784Sdim bool PreferMaskRegisters = false; 457360784Sdim 458344779Sdim /// Threeway branch is profitable in this subtarget. 459344779Sdim bool ThreewayBranchProfitable = false; 460344779Sdim 461360784Sdim /// Use Goldmont specific floating point div/sqrt costs. 462360784Sdim bool UseGLMDivSqrtCosts = false; 463360784Sdim 464288943Sdim /// What processor and OS we're targeting. 465210299Sed Triple TargetTriple; 466239462Sdim 467327952Sdim /// GlobalISel related APIs. 468327952Sdim std::unique_ptr<CallLowering> CallLoweringInfo; 469327952Sdim std::unique_ptr<LegalizerInfo> Legalizer; 470327952Sdim std::unique_ptr<RegisterBankInfo> RegBankInfo; 471327952Sdim std::unique_ptr<InstructionSelector> InstSelector; 472321369Sdim 473193323Sedprivate: 474288943Sdim /// Override the stack alignment. 475360784Sdim MaybeAlign StackAlignOverride; 476249423Sdim 477341825Sdim /// Preferred vector width from function attribute. 478341825Sdim unsigned PreferVectorWidthOverride; 479341825Sdim 480341825Sdim /// Resolved preferred vector width from function attribute and subtarget 481341825Sdim /// features. 482341825Sdim unsigned PreferVectorWidth = UINT32_MAX; 483341825Sdim 484341825Sdim /// Required vector width from function attribute. 485341825Sdim unsigned RequiredVectorWidth; 486341825Sdim 487288943Sdim /// True if compiling for 64-bit, false for 16-bit or 32-bit. 488224145Sdim bool In64BitMode; 489193323Sed 490288943Sdim /// True if compiling for 32-bit, false for 16-bit or 64-bit. 491276479Sdim bool In32BitMode; 492276479Sdim 493288943Sdim /// True if compiling for 16-bit, false for 32-bit or 64-bit. 494276479Sdim bool In16BitMode; 495276479Sdim 496327952Sdim /// Contains the Overhead of gather\scatter instructions 497341825Sdim int GatherOverhead = 1024; 498341825Sdim int ScatterOverhead = 1024; 499327952Sdim 500276479Sdim X86SelectionDAGInfo TSInfo; 501276479Sdim // Ordering here is important. X86InstrInfo initializes X86RegisterInfo which 502276479Sdim // X86TargetLowering needs. 503276479Sdim X86InstrInfo InstrInfo; 504276479Sdim X86TargetLowering TLInfo; 505276479Sdim X86FrameLowering FrameLowering; 506276479Sdim 507193323Sedpublic: 508193323Sed /// This constructor initializes the data members to match that 509198090Srdivacky /// of the specified triple. 510193323Sed /// 511309124Sdim X86Subtarget(const Triple &TT, StringRef CPU, StringRef FS, 512360784Sdim const X86TargetMachine &TM, MaybeAlign StackAlignOverride, 513341825Sdim unsigned PreferVectorWidthOverride, 514341825Sdim unsigned RequiredVectorWidth); 515193323Sed 516280031Sdim const X86TargetLowering *getTargetLowering() const override { 517280031Sdim return &TLInfo; 518280031Sdim } 519321369Sdim 520280031Sdim const X86InstrInfo *getInstrInfo() const override { return &InstrInfo; } 521321369Sdim 522280031Sdim const X86FrameLowering *getFrameLowering() const override { 523280031Sdim return &FrameLowering; 524280031Sdim } 525321369Sdim 526280031Sdim const X86SelectionDAGInfo *getSelectionDAGInfo() const override { 527280031Sdim return &TSInfo; 528280031Sdim } 529321369Sdim 530280031Sdim const X86RegisterInfo *getRegisterInfo() const override { 531280031Sdim return &getInstrInfo()->getRegisterInfo(); 532280031Sdim } 533276479Sdim 534288943Sdim /// Returns the minimum alignment known to hold of the 535193323Sed /// stack frame on entry to the function and which must be maintained by every 536193323Sed /// function for this subtarget. 537360784Sdim Align getStackAlignment() const { return stackAlignment; } 538193323Sed 539288943Sdim /// Returns the maximum memset / memcpy size 540193323Sed /// that still makes it profitable to inline the call. 541193323Sed unsigned getMaxInlineSizeThreshold() const { return MaxInlineSizeThreshold; } 542193323Sed 543193323Sed /// ParseSubtargetFeatures - Parses features string setting specified 544193323Sed /// subtarget options. Definition of function is auto generated by tblgen. 545224145Sdim void ParseSubtargetFeatures(StringRef CPU, StringRef FS); 546193323Sed 547314564Sdim /// Methods used by Global ISel 548314564Sdim const CallLowering *getCallLowering() const override; 549360784Sdim InstructionSelector *getInstructionSelector() const override; 550314564Sdim const LegalizerInfo *getLegalizerInfo() const override; 551314564Sdim const RegisterBankInfo *getRegBankInfo() const override; 552321369Sdim 553249423Sdimprivate: 554288943Sdim /// Initialize the full set of dependencies so we can use an initializer 555276479Sdim /// list for X86Subtarget. 556276479Sdim X86Subtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS); 557280031Sdim void initSubtargetFeatures(StringRef CPU, StringRef FS); 558321369Sdim 559249423Sdimpublic: 560249423Sdim /// Is this x86_64? (disregarding specific ABI / programming model) 561249423Sdim bool is64Bit() const { 562249423Sdim return In64BitMode; 563249423Sdim } 564193323Sed 565276479Sdim bool is32Bit() const { 566276479Sdim return In32BitMode; 567276479Sdim } 568276479Sdim 569276479Sdim bool is16Bit() const { 570276479Sdim return In16BitMode; 571276479Sdim } 572276479Sdim 573249423Sdim /// Is this x86_64 with the ILP32 programming model (x32 ABI)? 574249423Sdim bool isTarget64BitILP32() const { 575276479Sdim return In64BitMode && (TargetTriple.getEnvironment() == Triple::GNUX32 || 576280031Sdim TargetTriple.isOSNaCl()); 577249423Sdim } 578249423Sdim 579249423Sdim /// Is this x86_64 with the LP64 programming model (standard AMD64, no x32)? 580249423Sdim bool isTarget64BitLP64() const { 581280031Sdim return In64BitMode && (TargetTriple.getEnvironment() != Triple::GNUX32 && 582280031Sdim !TargetTriple.isOSNaCl()); 583249423Sdim } 584249423Sdim 585193323Sed PICStyles::Style getPICStyle() const { return PICStyle; } 586193323Sed void setPICStyle(PICStyles::Style Style) { PICStyle = Style; } 587193323Sed 588309124Sdim bool hasX87() const { return HasX87; } 589353358Sdim bool hasCmpxchg8b() const { return HasCmpxchg8b; } 590341825Sdim bool hasNOPL() const { return HasNOPL; } 591344779Sdim // SSE codegen depends on cmovs, and all SSE1+ processors support them. 592344779Sdim // All 64-bit processors support cmov. 593344779Sdim bool hasCMov() const { return HasCMov || X86SSELevel >= SSE1 || is64Bit(); } 594193323Sed bool hasSSE1() const { return X86SSELevel >= SSE1; } 595193323Sed bool hasSSE2() const { return X86SSELevel >= SSE2; } 596193323Sed bool hasSSE3() const { return X86SSELevel >= SSE3; } 597193323Sed bool hasSSSE3() const { return X86SSELevel >= SSSE3; } 598193323Sed bool hasSSE41() const { return X86SSELevel >= SSE41; } 599193323Sed bool hasSSE42() const { return X86SSELevel >= SSE42; } 600234353Sdim bool hasAVX() const { return X86SSELevel >= AVX; } 601234353Sdim bool hasAVX2() const { return X86SSELevel >= AVX2; } 602261991Sdim bool hasAVX512() const { return X86SSELevel >= AVX512F; } 603249423Sdim bool hasInt256() const { return hasAVX2(); } 604193323Sed bool hasSSE4A() const { return HasSSE4A; } 605296417Sdim bool hasMMX() const { return X863DNowLevel >= MMX; } 606193323Sed bool has3DNow() const { return X863DNowLevel >= ThreeDNow; } 607193323Sed bool has3DNowA() const { return X863DNowLevel >= ThreeDNowA; } 608218893Sdim bool hasPOPCNT() const { return HasPOPCNT; } 609206124Srdivacky bool hasAES() const { return HasAES; } 610327952Sdim bool hasVAES() const { return HasVAES; } 611296417Sdim bool hasFXSR() const { return HasFXSR; } 612296417Sdim bool hasXSAVE() const { return HasXSAVE; } 613296417Sdim bool hasXSAVEOPT() const { return HasXSAVEOPT; } 614296417Sdim bool hasXSAVEC() const { return HasXSAVEC; } 615296417Sdim bool hasXSAVES() const { return HasXSAVES; } 616239462Sdim bool hasPCLMUL() const { return HasPCLMUL; } 617327952Sdim bool hasVPCLMULQDQ() const { return HasVPCLMULQDQ; } 618327952Sdim bool hasGFNI() const { return HasGFNI; } 619296417Sdim // Prefer FMA4 to FMA - its better for commutation/memory folding and 620296417Sdim // has equal or better performance on all supported targets. 621327952Sdim bool hasFMA() const { return HasFMA; } 622296417Sdim bool hasFMA4() const { return HasFMA4; } 623321369Sdim bool hasAnyFMA() const { return hasFMA() || hasFMA4(); } 624234353Sdim bool hasXOP() const { return HasXOP; } 625261991Sdim bool hasTBM() const { return HasTBM; } 626321369Sdim bool hasLWP() const { return HasLWP; } 627226633Sdim bool hasMOVBE() const { return HasMOVBE; } 628226633Sdim bool hasRDRAND() const { return HasRDRAND; } 629226633Sdim bool hasF16C() const { return HasF16C; } 630234353Sdim bool hasFSGSBase() const { return HasFSGSBase; } 631226633Sdim bool hasLZCNT() const { return HasLZCNT; } 632226633Sdim bool hasBMI() const { return HasBMI; } 633234353Sdim bool hasBMI2() const { return HasBMI2; } 634309124Sdim bool hasVBMI() const { return HasVBMI; } 635327952Sdim bool hasVBMI2() const { return HasVBMI2; } 636309124Sdim bool hasIFMA() const { return HasIFMA; } 637243830Sdim bool hasRTM() const { return HasRTM; } 638249423Sdim bool hasADX() const { return HasADX; } 639261991Sdim bool hasSHA() const { return HasSHA; } 640327952Sdim bool hasPRFCHW() const { return HasPRFCHW || HasPREFETCHWT1; } 641327952Sdim bool hasPREFETCHWT1() const { return HasPREFETCHWT1; } 642327952Sdim bool hasSSEPrefetch() const { 643327952Sdim // We implicitly enable these when we have a write prefix supporting cache 644327952Sdim // level OR if we have prfchw, but don't already have a read prefetch from 645327952Sdim // 3dnow. 646327952Sdim return hasSSE1() || (hasPRFCHW() && !has3DNow()) || hasPREFETCHWT1(); 647327952Sdim } 648249423Sdim bool hasRDSEED() const { return HasRDSEED; } 649296417Sdim bool hasLAHFSAHF() const { return HasLAHFSAHF; } 650309124Sdim bool hasMWAITX() const { return HasMWAITX; } 651321369Sdim bool hasCLZERO() const { return HasCLZERO; } 652341825Sdim bool hasCLDEMOTE() const { return HasCLDEMOTE; } 653341825Sdim bool hasMOVDIRI() const { return HasMOVDIRI; } 654341825Sdim bool hasMOVDIR64B() const { return HasMOVDIR64B; } 655341825Sdim bool hasPTWRITE() const { return HasPTWRITE; } 656276479Sdim bool isSHLDSlow() const { return IsSHLDSlow; } 657314564Sdim bool isPMULLDSlow() const { return IsPMULLDSlow; } 658344779Sdim bool isPMADDWDSlow() const { return IsPMADDWDSlow; } 659296417Sdim bool isUnalignedMem16Slow() const { return IsUAMem16Slow; } 660280031Sdim bool isUnalignedMem32Slow() const { return IsUAMem32Slow; } 661327952Sdim int getGatherOverhead() const { return GatherOverhead; } 662327952Sdim int getScatterOverhead() const { return ScatterOverhead; } 663280031Sdim bool hasSSEUnalignedMem() const { return HasSSEUnalignedMem; } 664353358Sdim bool hasCmpxchg16b() const { return HasCmpxchg16b && is64Bit(); } 665234353Sdim bool useLeaForSP() const { return UseLeaForSP; } 666341825Sdim bool hasPOPCNTFalseDeps() const { return HasPOPCNTFalseDeps; } 667341825Sdim bool hasLZCNTFalseDeps() const { return HasLZCNTFalseDeps; } 668327952Sdim bool hasFastVariableShuffle() const { 669327952Sdim return HasFastVariableShuffle; 670327952Sdim } 671360784Sdim bool insertVZEROUPPER() const { return InsertVZEROUPPER; } 672327952Sdim bool hasFastGather() const { return HasFastGather; } 673314564Sdim bool hasFastScalarFSQRT() const { return HasFastScalarFSQRT; } 674314564Sdim bool hasFastVectorFSQRT() const { return HasFastVectorFSQRT; } 675314564Sdim bool hasFastLZCNT() const { return HasFastLZCNT; } 676321369Sdim bool hasFastSHLDRotate() const { return HasFastSHLDRotate; } 677344779Sdim bool hasFastBEXTR() const { return HasFastBEXTR; } 678344779Sdim bool hasFastHorizontalOps() const { return HasFastHorizontalOps; } 679353358Sdim bool hasFastScalarShiftMasks() const { return HasFastScalarShiftMasks; } 680353358Sdim bool hasFastVectorShiftMasks() const { return HasFastVectorShiftMasks; } 681327952Sdim bool hasMacroFusion() const { return HasMacroFusion; } 682353358Sdim bool hasBranchFusion() const { return HasBranchFusion; } 683321369Sdim bool hasERMSB() const { return HasERMSB; } 684280031Sdim bool hasSlowDivide32() const { return HasSlowDivide32; } 685280031Sdim bool hasSlowDivide64() const { return HasSlowDivide64; } 686249423Sdim bool padShortFunctions() const { return PadShortFunctions; } 687327952Sdim bool slowTwoMemOps() const { return SlowTwoMemOps; } 688251662Sdim bool LEAusesAG() const { return LEAUsesAG; } 689276479Sdim bool slowLEA() const { return SlowLEA; } 690321369Sdim bool slow3OpsLEA() const { return Slow3OpsLEA; } 691276479Sdim bool slowIncDec() const { return SlowIncDec; } 692261991Sdim bool hasCDI() const { return HasCDI; } 693321369Sdim bool hasVPOPCNTDQ() const { return HasVPOPCNTDQ; } 694261991Sdim bool hasPFI() const { return HasPFI; } 695261991Sdim bool hasERI() const { return HasERI; } 696276479Sdim bool hasDQI() const { return HasDQI; } 697276479Sdim bool hasBWI() const { return HasBWI; } 698276479Sdim bool hasVLX() const { return HasVLX; } 699296417Sdim bool hasPKU() const { return HasPKU; } 700327952Sdim bool hasVNNI() const { return HasVNNI; } 701353358Sdim bool hasBF16() const { return HasBF16; } 702353358Sdim bool hasVP2INTERSECT() const { return HasVP2INTERSECT; } 703327952Sdim bool hasBITALG() const { return HasBITALG; } 704327952Sdim bool hasSHSTK() const { return HasSHSTK; } 705321369Sdim bool hasCLFLUSHOPT() const { return HasCLFLUSHOPT; } 706327952Sdim bool hasCLWB() const { return HasCLWB; } 707341825Sdim bool hasWBNOINVD() const { return HasWBNOINVD; } 708341825Sdim bool hasRDPID() const { return HasRDPID; } 709341825Sdim bool hasWAITPKG() const { return HasWAITPKG; } 710341825Sdim bool hasPCONFIG() const { return HasPCONFIG; } 711341825Sdim bool hasSGX() const { return HasSGX; } 712344779Sdim bool threewayBranchProfitable() const { return ThreewayBranchProfitable; } 713341825Sdim bool hasINVPCID() const { return HasINVPCID; } 714353358Sdim bool hasENQCMD() const { return HasENQCMD; } 715344779Sdim bool useRetpolineIndirectCalls() const { return UseRetpolineIndirectCalls; } 716344779Sdim bool useRetpolineIndirectBranches() const { 717344779Sdim return UseRetpolineIndirectBranches; 718344779Sdim } 719328817Sdim bool useRetpolineExternalThunk() const { return UseRetpolineExternalThunk; } 720363496Sdim 721363496Sdim // These are generic getters that OR together all of the thunk types 722363496Sdim // supported by the subtarget. Therefore useIndirectThunk*() will return true 723363496Sdim // if any respective thunk feature is enabled. 724363496Sdim bool useIndirectThunkCalls() const { 725363496Sdim return useRetpolineIndirectCalls() || useLVIControlFlowIntegrity(); 726363496Sdim } 727363496Sdim bool useIndirectThunkBranches() const { 728363496Sdim return useRetpolineIndirectBranches() || useLVIControlFlowIntegrity(); 729363496Sdim } 730363496Sdim 731360784Sdim bool preferMaskRegisters() const { return PreferMaskRegisters; } 732360784Sdim bool useGLMDivSqrtCosts() const { return UseGLMDivSqrtCosts; } 733363496Sdim bool useLVIControlFlowIntegrity() const { return UseLVIControlFlowIntegrity; } 734363496Sdim bool useLVILoadHardening() const { return UseLVILoadHardening; } 735193323Sed 736341825Sdim unsigned getPreferVectorWidth() const { return PreferVectorWidth; } 737341825Sdim unsigned getRequiredVectorWidth() const { return RequiredVectorWidth; } 738341825Sdim 739341825Sdim // Helper functions to determine when we should allow widening to 512-bit 740341825Sdim // during codegen. 741341825Sdim // TODO: Currently we're always allowing widening on CPUs without VLX, 742341825Sdim // because for many cases we don't have a better option. 743341825Sdim bool canExtendTo512DQ() const { 744341825Sdim return hasAVX512() && (!hasVLX() || getPreferVectorWidth() >= 512); 745341825Sdim } 746341825Sdim bool canExtendTo512BW() const { 747341825Sdim return hasBWI() && canExtendTo512DQ(); 748341825Sdim } 749341825Sdim 750341825Sdim // If there are no 512-bit vectors and we prefer not to use 512-bit registers, 751341825Sdim // disable them in the legalizer. 752341825Sdim bool useAVX512Regs() const { 753341825Sdim return hasAVX512() && (canExtendTo512DQ() || RequiredVectorWidth > 256); 754341825Sdim } 755341825Sdim 756341825Sdim bool useBWIRegs() const { 757341825Sdim return hasBWI() && useAVX512Regs(); 758341825Sdim } 759341825Sdim 760321369Sdim bool isXRaySupported() const override { return is64Bit(); } 761314564Sdim 762327952Sdim X86ProcFamilyEnum getProcFamily() const { return X86ProcFamily; } 763327952Sdim 764327952Sdim /// TODO: to be removed later and replaced with suitable properties 765234353Sdim bool isAtom() const { return X86ProcFamily == IntelAtom; } 766276479Sdim bool isSLM() const { return X86ProcFamily == IntelSLM; } 767288943Sdim bool useSoftFloat() const { return UseSoftFloat; } 768360784Sdim bool useAA() const override { return UseAA; } 769234353Sdim 770309124Sdim /// Use mfence if we have SSE2 or we're on x86-64 (even if we asked for 771309124Sdim /// no-sse2). There isn't any reason to disable it if the target processor 772309124Sdim /// supports it. 773309124Sdim bool hasMFence() const { return hasSSE2() || is64Bit(); } 774309124Sdim 775221345Sdim const Triple &getTargetTriple() const { return TargetTriple; } 776218893Sdim 777221345Sdim bool isTargetDarwin() const { return TargetTriple.isOSDarwin(); } 778280031Sdim bool isTargetFreeBSD() const { return TargetTriple.isOSFreeBSD(); } 779280031Sdim bool isTargetDragonFly() const { return TargetTriple.isOSDragonFly(); } 780280031Sdim bool isTargetSolaris() const { return TargetTriple.isOSSolaris(); } 781314564Sdim bool isTargetPS4() const { return TargetTriple.isPS4CPU(); } 782276479Sdim 783276479Sdim bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); } 784276479Sdim bool isTargetCOFF() const { return TargetTriple.isOSBinFormatCOFF(); } 785280031Sdim bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); } 786276479Sdim 787261991Sdim bool isTargetLinux() const { return TargetTriple.isOSLinux(); } 788309124Sdim bool isTargetKFreeBSD() const { return TargetTriple.isOSKFreeBSD(); } 789309124Sdim bool isTargetGlibc() const { return TargetTriple.isOSGlibc(); } 790296417Sdim bool isTargetAndroid() const { return TargetTriple.isAndroid(); } 791261991Sdim bool isTargetNaCl() const { return TargetTriple.isOSNaCl(); } 792226633Sdim bool isTargetNaCl32() const { return isTargetNaCl() && !is64Bit(); } 793226633Sdim bool isTargetNaCl64() const { return isTargetNaCl() && is64Bit(); } 794296417Sdim bool isTargetMCU() const { return TargetTriple.isOSIAMCU(); } 795321369Sdim bool isTargetFuchsia() const { return TargetTriple.isOSFuchsia(); } 796276479Sdim 797276479Sdim bool isTargetWindowsMSVC() const { 798276479Sdim return TargetTriple.isWindowsMSVCEnvironment(); 799243830Sdim } 800218893Sdim 801296417Sdim bool isTargetWindowsCoreCLR() const { 802296417Sdim return TargetTriple.isWindowsCoreCLREnvironment(); 803296417Sdim } 804296417Sdim 805276479Sdim bool isTargetWindowsCygwin() const { 806276479Sdim return TargetTriple.isWindowsCygwinEnvironment(); 807276479Sdim } 808276479Sdim 809276479Sdim bool isTargetWindowsGNU() const { 810276479Sdim return TargetTriple.isWindowsGNUEnvironment(); 811276479Sdim } 812276479Sdim 813280031Sdim bool isTargetWindowsItanium() const { 814280031Sdim return TargetTriple.isWindowsItaniumEnvironment(); 815280031Sdim } 816280031Sdim 817276479Sdim bool isTargetCygMing() const { return TargetTriple.isOSCygMing(); } 818276479Sdim 819261991Sdim bool isOSWindows() const { return TargetTriple.isOSWindows(); } 820261991Sdim 821327952Sdim bool isTargetWin64() const { return In64BitMode && isOSWindows(); } 822193323Sed 823327952Sdim bool isTargetWin32() const { return !In64BitMode && isOSWindows(); } 824212904Sdim 825360784Sdim bool isPICStyleGOT() const { return PICStyle == PICStyles::Style::GOT; } 826360784Sdim bool isPICStyleRIPRel() const { return PICStyle == PICStyles::Style::RIPRel; } 827198090Srdivacky 828198090Srdivacky bool isPICStyleStubPIC() const { 829360784Sdim return PICStyle == PICStyles::Style::StubPIC; 830198090Srdivacky } 831198090Srdivacky 832309124Sdim bool isPositionIndependent() const { return TM.isPositionIndependent(); } 833204642Srdivacky 834256030Sdim bool isCallingConvWin64(CallingConv::ID CC) const { 835288943Sdim switch (CC) { 836288943Sdim // On Win64, all these conventions just use the default convention. 837288943Sdim case CallingConv::C: 838288943Sdim case CallingConv::Fast: 839360784Sdim case CallingConv::Tail: 840327952Sdim case CallingConv::Swift: 841288943Sdim case CallingConv::X86_FastCall: 842288943Sdim case CallingConv::X86_StdCall: 843288943Sdim case CallingConv::X86_ThisCall: 844288943Sdim case CallingConv::X86_VectorCall: 845288943Sdim case CallingConv::Intel_OCL_BI: 846288943Sdim return isTargetWin64(); 847288943Sdim // This convention allows using the Win64 convention on other targets. 848321369Sdim case CallingConv::Win64: 849288943Sdim return true; 850288943Sdim // This convention allows using the SysV convention on Windows targets. 851288943Sdim case CallingConv::X86_64_SysV: 852288943Sdim return false; 853288943Sdim // Otherwise, who knows what this is. 854288943Sdim default: 855288943Sdim return false; 856288943Sdim } 857256030Sdim } 858256030Sdim 859309124Sdim /// Classify a global variable reference for the current subtarget according 860309124Sdim /// to how we should reference it in a non-pcrel context. 861309124Sdim unsigned char classifyLocalReference(const GlobalValue *GV) const; 862193323Sed 863309124Sdim unsigned char classifyGlobalReference(const GlobalValue *GV, 864309124Sdim const Module &M) const; 865309124Sdim unsigned char classifyGlobalReference(const GlobalValue *GV) const; 866309124Sdim 867309124Sdim /// Classify a global function reference for the current subtarget. 868309124Sdim unsigned char classifyGlobalFunctionReference(const GlobalValue *GV, 869309124Sdim const Module &M) const; 870309124Sdim unsigned char classifyGlobalFunctionReference(const GlobalValue *GV) const; 871309124Sdim 872288943Sdim /// Classify a blockaddress reference for the current subtarget according to 873288943Sdim /// how we should reference it in a non-pcrel context. 874309124Sdim unsigned char classifyBlockAddressReference() const; 875199989Srdivacky 876288943Sdim /// Return true if the subtarget allows calls to immediate address. 877309124Sdim bool isLegalToCallImmediateAddr() const; 878193323Sed 879363496Sdim /// If we are using indirect thunks, we need to expand indirectbr to avoid it 880328817Sdim /// lowering to an actual indirect jump. 881344779Sdim bool enableIndirectBrExpand() const override { 882363496Sdim return useIndirectThunkBranches(); 883344779Sdim } 884328817Sdim 885261991Sdim /// Enable the MachineScheduler pass for all X86 subtargets. 886276479Sdim bool enableMachineScheduler() const override { return true; } 887261991Sdim 888276479Sdim bool enableEarlyIfConversion() const override; 889234353Sdim 890353358Sdim void getPostRAMutations(std::vector<std::unique_ptr<ScheduleDAGMutation>> 891353358Sdim &Mutations) const override; 892353358Sdim 893276479Sdim AntiDepBreakMode getAntiDepBreakMode() const override { 894276479Sdim return TargetSubtargetInfo::ANTIDEP_CRITICAL; 895276479Sdim } 896327952Sdim 897327952Sdim bool enableAdvancedRASplitCost() const override { return true; } 898193323Sed}; 899193323Sed 900321369Sdim} // end namespace llvm 901193323Sed 902321369Sdim#endif // LLVM_LIB_TARGET_X86_X86SUBTARGET_H 903