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