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