xref: /freebsd/contrib/llvm-project/llvm/lib/Target/ARM/ARMSubtarget.h (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric //===-- ARMSubtarget.h - Define Subtarget for the ARM ----------*- C++ -*--===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric //
9*0b57cec5SDimitry Andric // This file declares the ARM specific subclass of TargetSubtargetInfo.
10*0b57cec5SDimitry Andric //
11*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
12*0b57cec5SDimitry Andric 
13*0b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_ARM_ARMSUBTARGET_H
14*0b57cec5SDimitry Andric #define LLVM_LIB_TARGET_ARM_ARMSUBTARGET_H
15*0b57cec5SDimitry Andric 
16*0b57cec5SDimitry Andric #include "ARMBaseInstrInfo.h"
17*0b57cec5SDimitry Andric #include "ARMBaseRegisterInfo.h"
18*0b57cec5SDimitry Andric #include "ARMConstantPoolValue.h"
19*0b57cec5SDimitry Andric #include "ARMFrameLowering.h"
20*0b57cec5SDimitry Andric #include "ARMISelLowering.h"
21*0b57cec5SDimitry Andric #include "ARMSelectionDAGInfo.h"
22*0b57cec5SDimitry Andric #include "llvm/ADT/Triple.h"
23*0b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/CallLowering.h"
24*0b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
25*0b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
26*0b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
27*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
28*0b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
29*0b57cec5SDimitry Andric #include "llvm/MC/MCInstrItineraries.h"
30*0b57cec5SDimitry Andric #include "llvm/MC/MCSchedule.h"
31*0b57cec5SDimitry Andric #include "llvm/Target/TargetOptions.h"
32*0b57cec5SDimitry Andric #include <memory>
33*0b57cec5SDimitry Andric #include <string>
34*0b57cec5SDimitry Andric 
35*0b57cec5SDimitry Andric #define GET_SUBTARGETINFO_HEADER
36*0b57cec5SDimitry Andric #include "ARMGenSubtargetInfo.inc"
37*0b57cec5SDimitry Andric 
38*0b57cec5SDimitry Andric namespace llvm {
39*0b57cec5SDimitry Andric 
40*0b57cec5SDimitry Andric class ARMBaseTargetMachine;
41*0b57cec5SDimitry Andric class GlobalValue;
42*0b57cec5SDimitry Andric class StringRef;
43*0b57cec5SDimitry Andric 
44*0b57cec5SDimitry Andric class ARMSubtarget : public ARMGenSubtargetInfo {
45*0b57cec5SDimitry Andric protected:
46*0b57cec5SDimitry Andric   enum ARMProcFamilyEnum {
47*0b57cec5SDimitry Andric     Others,
48*0b57cec5SDimitry Andric 
49*0b57cec5SDimitry Andric     CortexA12,
50*0b57cec5SDimitry Andric     CortexA15,
51*0b57cec5SDimitry Andric     CortexA17,
52*0b57cec5SDimitry Andric     CortexA32,
53*0b57cec5SDimitry Andric     CortexA35,
54*0b57cec5SDimitry Andric     CortexA5,
55*0b57cec5SDimitry Andric     CortexA53,
56*0b57cec5SDimitry Andric     CortexA55,
57*0b57cec5SDimitry Andric     CortexA57,
58*0b57cec5SDimitry Andric     CortexA7,
59*0b57cec5SDimitry Andric     CortexA72,
60*0b57cec5SDimitry Andric     CortexA73,
61*0b57cec5SDimitry Andric     CortexA75,
62*0b57cec5SDimitry Andric     CortexA76,
63*0b57cec5SDimitry Andric     CortexA8,
64*0b57cec5SDimitry Andric     CortexA9,
65*0b57cec5SDimitry Andric     CortexM3,
66*0b57cec5SDimitry Andric     CortexR4,
67*0b57cec5SDimitry Andric     CortexR4F,
68*0b57cec5SDimitry Andric     CortexR5,
69*0b57cec5SDimitry Andric     CortexR52,
70*0b57cec5SDimitry Andric     CortexR7,
71*0b57cec5SDimitry Andric     Exynos,
72*0b57cec5SDimitry Andric     Krait,
73*0b57cec5SDimitry Andric     Kryo,
74*0b57cec5SDimitry Andric     Swift
75*0b57cec5SDimitry Andric   };
76*0b57cec5SDimitry Andric   enum ARMProcClassEnum {
77*0b57cec5SDimitry Andric     None,
78*0b57cec5SDimitry Andric 
79*0b57cec5SDimitry Andric     AClass,
80*0b57cec5SDimitry Andric     MClass,
81*0b57cec5SDimitry Andric     RClass
82*0b57cec5SDimitry Andric   };
83*0b57cec5SDimitry Andric   enum ARMArchEnum {
84*0b57cec5SDimitry Andric     ARMv2,
85*0b57cec5SDimitry Andric     ARMv2a,
86*0b57cec5SDimitry Andric     ARMv3,
87*0b57cec5SDimitry Andric     ARMv3m,
88*0b57cec5SDimitry Andric     ARMv4,
89*0b57cec5SDimitry Andric     ARMv4t,
90*0b57cec5SDimitry Andric     ARMv5,
91*0b57cec5SDimitry Andric     ARMv5t,
92*0b57cec5SDimitry Andric     ARMv5te,
93*0b57cec5SDimitry Andric     ARMv5tej,
94*0b57cec5SDimitry Andric     ARMv6,
95*0b57cec5SDimitry Andric     ARMv6k,
96*0b57cec5SDimitry Andric     ARMv6kz,
97*0b57cec5SDimitry Andric     ARMv6m,
98*0b57cec5SDimitry Andric     ARMv6sm,
99*0b57cec5SDimitry Andric     ARMv6t2,
100*0b57cec5SDimitry Andric     ARMv7a,
101*0b57cec5SDimitry Andric     ARMv7em,
102*0b57cec5SDimitry Andric     ARMv7m,
103*0b57cec5SDimitry Andric     ARMv7r,
104*0b57cec5SDimitry Andric     ARMv7ve,
105*0b57cec5SDimitry Andric     ARMv81a,
106*0b57cec5SDimitry Andric     ARMv82a,
107*0b57cec5SDimitry Andric     ARMv83a,
108*0b57cec5SDimitry Andric     ARMv84a,
109*0b57cec5SDimitry Andric     ARMv85a,
110*0b57cec5SDimitry Andric     ARMv8a,
111*0b57cec5SDimitry Andric     ARMv8mBaseline,
112*0b57cec5SDimitry Andric     ARMv8mMainline,
113*0b57cec5SDimitry Andric     ARMv8r,
114*0b57cec5SDimitry Andric     ARMv81mMainline,
115*0b57cec5SDimitry Andric   };
116*0b57cec5SDimitry Andric 
117*0b57cec5SDimitry Andric public:
118*0b57cec5SDimitry Andric   /// What kind of timing do load multiple/store multiple instructions have.
119*0b57cec5SDimitry Andric   enum ARMLdStMultipleTiming {
120*0b57cec5SDimitry Andric     /// Can load/store 2 registers/cycle.
121*0b57cec5SDimitry Andric     DoubleIssue,
122*0b57cec5SDimitry Andric     /// Can load/store 2 registers/cycle, but needs an extra cycle if the access
123*0b57cec5SDimitry Andric     /// is not 64-bit aligned.
124*0b57cec5SDimitry Andric     DoubleIssueCheckUnalignedAccess,
125*0b57cec5SDimitry Andric     /// Can load/store 1 register/cycle.
126*0b57cec5SDimitry Andric     SingleIssue,
127*0b57cec5SDimitry Andric     /// Can load/store 1 register/cycle, but needs an extra cycle for address
128*0b57cec5SDimitry Andric     /// computation and potentially also for register writeback.
129*0b57cec5SDimitry Andric     SingleIssuePlusExtras,
130*0b57cec5SDimitry Andric   };
131*0b57cec5SDimitry Andric 
132*0b57cec5SDimitry Andric protected:
133*0b57cec5SDimitry Andric   /// ARMProcFamily - ARM processor family: Cortex-A8, Cortex-A9, and others.
134*0b57cec5SDimitry Andric   ARMProcFamilyEnum ARMProcFamily = Others;
135*0b57cec5SDimitry Andric 
136*0b57cec5SDimitry Andric   /// ARMProcClass - ARM processor class: None, AClass, RClass or MClass.
137*0b57cec5SDimitry Andric   ARMProcClassEnum ARMProcClass = None;
138*0b57cec5SDimitry Andric 
139*0b57cec5SDimitry Andric   /// ARMArch - ARM architecture
140*0b57cec5SDimitry Andric   ARMArchEnum ARMArch = ARMv4t;
141*0b57cec5SDimitry Andric 
142*0b57cec5SDimitry Andric   /// HasV4TOps, HasV5TOps, HasV5TEOps,
143*0b57cec5SDimitry Andric   /// HasV6Ops, HasV6MOps, HasV6KOps, HasV6T2Ops, HasV7Ops, HasV8Ops -
144*0b57cec5SDimitry Andric   /// Specify whether target support specific ARM ISA variants.
145*0b57cec5SDimitry Andric   bool HasV4TOps = false;
146*0b57cec5SDimitry Andric   bool HasV5TOps = false;
147*0b57cec5SDimitry Andric   bool HasV5TEOps = false;
148*0b57cec5SDimitry Andric   bool HasV6Ops = false;
149*0b57cec5SDimitry Andric   bool HasV6MOps = false;
150*0b57cec5SDimitry Andric   bool HasV6KOps = false;
151*0b57cec5SDimitry Andric   bool HasV6T2Ops = false;
152*0b57cec5SDimitry Andric   bool HasV7Ops = false;
153*0b57cec5SDimitry Andric   bool HasV8Ops = false;
154*0b57cec5SDimitry Andric   bool HasV8_1aOps = false;
155*0b57cec5SDimitry Andric   bool HasV8_2aOps = false;
156*0b57cec5SDimitry Andric   bool HasV8_3aOps = false;
157*0b57cec5SDimitry Andric   bool HasV8_4aOps = false;
158*0b57cec5SDimitry Andric   bool HasV8_5aOps = false;
159*0b57cec5SDimitry Andric   bool HasV8MBaselineOps = false;
160*0b57cec5SDimitry Andric   bool HasV8MMainlineOps = false;
161*0b57cec5SDimitry Andric   bool HasV8_1MMainlineOps = false;
162*0b57cec5SDimitry Andric   bool HasMVEIntegerOps = false;
163*0b57cec5SDimitry Andric   bool HasMVEFloatOps = false;
164*0b57cec5SDimitry Andric 
165*0b57cec5SDimitry Andric   /// HasVFPv2, HasVFPv3, HasVFPv4, HasFPARMv8, HasNEON - Specify what
166*0b57cec5SDimitry Andric   /// floating point ISAs are supported.
167*0b57cec5SDimitry Andric   bool HasVFPv2 = false;
168*0b57cec5SDimitry Andric   bool HasVFPv3 = false;
169*0b57cec5SDimitry Andric   bool HasVFPv4 = false;
170*0b57cec5SDimitry Andric   bool HasFPARMv8 = false;
171*0b57cec5SDimitry Andric   bool HasNEON = false;
172*0b57cec5SDimitry Andric   bool HasFPRegs = false;
173*0b57cec5SDimitry Andric   bool HasFPRegs16 = false;
174*0b57cec5SDimitry Andric   bool HasFPRegs64 = false;
175*0b57cec5SDimitry Andric 
176*0b57cec5SDimitry Andric   /// Versions of the VFP flags restricted to single precision, or to
177*0b57cec5SDimitry Andric   /// 16 d-registers, or both.
178*0b57cec5SDimitry Andric   bool HasVFPv2SP = false;
179*0b57cec5SDimitry Andric   bool HasVFPv3SP = false;
180*0b57cec5SDimitry Andric   bool HasVFPv4SP = false;
181*0b57cec5SDimitry Andric   bool HasFPARMv8SP = false;
182*0b57cec5SDimitry Andric   bool HasVFPv3D16 = false;
183*0b57cec5SDimitry Andric   bool HasVFPv4D16 = false;
184*0b57cec5SDimitry Andric   bool HasFPARMv8D16 = false;
185*0b57cec5SDimitry Andric   bool HasVFPv3D16SP = false;
186*0b57cec5SDimitry Andric   bool HasVFPv4D16SP = false;
187*0b57cec5SDimitry Andric   bool HasFPARMv8D16SP = false;
188*0b57cec5SDimitry Andric 
189*0b57cec5SDimitry Andric   /// HasDotProd - True if the ARMv8.2A dot product instructions are supported.
190*0b57cec5SDimitry Andric   bool HasDotProd = false;
191*0b57cec5SDimitry Andric 
192*0b57cec5SDimitry Andric   /// UseNEONForSinglePrecisionFP - if the NEONFP attribute has been
193*0b57cec5SDimitry Andric   /// specified. Use the method useNEONForSinglePrecisionFP() to
194*0b57cec5SDimitry Andric   /// determine if NEON should actually be used.
195*0b57cec5SDimitry Andric   bool UseNEONForSinglePrecisionFP = false;
196*0b57cec5SDimitry Andric 
197*0b57cec5SDimitry Andric   /// UseMulOps - True if non-microcoded fused integer multiply-add and
198*0b57cec5SDimitry Andric   /// multiply-subtract instructions should be used.
199*0b57cec5SDimitry Andric   bool UseMulOps = false;
200*0b57cec5SDimitry Andric 
201*0b57cec5SDimitry Andric   /// SlowFPVMLx - If the VFP2 / NEON instructions are available, indicates
202*0b57cec5SDimitry Andric   /// whether the FP VML[AS] instructions are slow (if so, don't use them).
203*0b57cec5SDimitry Andric   bool SlowFPVMLx = false;
204*0b57cec5SDimitry Andric 
205*0b57cec5SDimitry Andric   /// HasVMLxForwarding - If true, NEON has special multiplier accumulator
206*0b57cec5SDimitry Andric   /// forwarding to allow mul + mla being issued back to back.
207*0b57cec5SDimitry Andric   bool HasVMLxForwarding = false;
208*0b57cec5SDimitry Andric 
209*0b57cec5SDimitry Andric   /// SlowFPBrcc - True if floating point compare + branch is slow.
210*0b57cec5SDimitry Andric   bool SlowFPBrcc = false;
211*0b57cec5SDimitry Andric 
212*0b57cec5SDimitry Andric   /// InThumbMode - True if compiling for Thumb, false for ARM.
213*0b57cec5SDimitry Andric   bool InThumbMode = false;
214*0b57cec5SDimitry Andric 
215*0b57cec5SDimitry Andric   /// UseSoftFloat - True if we're using software floating point features.
216*0b57cec5SDimitry Andric   bool UseSoftFloat = false;
217*0b57cec5SDimitry Andric 
218*0b57cec5SDimitry Andric   /// UseMISched - True if MachineScheduler should be used for this subtarget.
219*0b57cec5SDimitry Andric   bool UseMISched = false;
220*0b57cec5SDimitry Andric 
221*0b57cec5SDimitry Andric   /// DisablePostRAScheduler - False if scheduling should happen again after
222*0b57cec5SDimitry Andric   /// register allocation.
223*0b57cec5SDimitry Andric   bool DisablePostRAScheduler = false;
224*0b57cec5SDimitry Andric 
225*0b57cec5SDimitry Andric   /// UseAA - True if using AA during codegen (DAGCombine, MISched, etc)
226*0b57cec5SDimitry Andric   bool UseAA = false;
227*0b57cec5SDimitry Andric 
228*0b57cec5SDimitry Andric   /// HasThumb2 - True if Thumb2 instructions are supported.
229*0b57cec5SDimitry Andric   bool HasThumb2 = false;
230*0b57cec5SDimitry Andric 
231*0b57cec5SDimitry Andric   /// NoARM - True if subtarget does not support ARM mode execution.
232*0b57cec5SDimitry Andric   bool NoARM = false;
233*0b57cec5SDimitry Andric 
234*0b57cec5SDimitry Andric   /// ReserveR9 - True if R9 is not available as a general purpose register.
235*0b57cec5SDimitry Andric   bool ReserveR9 = false;
236*0b57cec5SDimitry Andric 
237*0b57cec5SDimitry Andric   /// NoMovt - True if MOVT / MOVW pairs are not used for materialization of
238*0b57cec5SDimitry Andric   /// 32-bit imms (including global addresses).
239*0b57cec5SDimitry Andric   bool NoMovt = false;
240*0b57cec5SDimitry Andric 
241*0b57cec5SDimitry Andric   /// SupportsTailCall - True if the OS supports tail call. The dynamic linker
242*0b57cec5SDimitry Andric   /// must be able to synthesize call stubs for interworking between ARM and
243*0b57cec5SDimitry Andric   /// Thumb.
244*0b57cec5SDimitry Andric   bool SupportsTailCall = false;
245*0b57cec5SDimitry Andric 
246*0b57cec5SDimitry Andric   /// HasFP16 - True if subtarget supports half-precision FP conversions
247*0b57cec5SDimitry Andric   bool HasFP16 = false;
248*0b57cec5SDimitry Andric 
249*0b57cec5SDimitry Andric   /// HasFullFP16 - True if subtarget supports half-precision FP operations
250*0b57cec5SDimitry Andric   bool HasFullFP16 = false;
251*0b57cec5SDimitry Andric 
252*0b57cec5SDimitry Andric   /// HasFP16FML - True if subtarget supports half-precision FP fml operations
253*0b57cec5SDimitry Andric   bool HasFP16FML = false;
254*0b57cec5SDimitry Andric 
255*0b57cec5SDimitry Andric   /// HasD32 - True if subtarget has the full 32 double precision
256*0b57cec5SDimitry Andric   /// FP registers for VFPv3.
257*0b57cec5SDimitry Andric   bool HasD32 = false;
258*0b57cec5SDimitry Andric 
259*0b57cec5SDimitry Andric   /// HasHardwareDivide - True if subtarget supports [su]div in Thumb mode
260*0b57cec5SDimitry Andric   bool HasHardwareDivideInThumb = false;
261*0b57cec5SDimitry Andric 
262*0b57cec5SDimitry Andric   /// HasHardwareDivideInARM - True if subtarget supports [su]div in ARM mode
263*0b57cec5SDimitry Andric   bool HasHardwareDivideInARM = false;
264*0b57cec5SDimitry Andric 
265*0b57cec5SDimitry Andric   /// HasDataBarrier - True if the subtarget supports DMB / DSB data barrier
266*0b57cec5SDimitry Andric   /// instructions.
267*0b57cec5SDimitry Andric   bool HasDataBarrier = false;
268*0b57cec5SDimitry Andric 
269*0b57cec5SDimitry Andric   /// HasFullDataBarrier - True if the subtarget supports DFB data barrier
270*0b57cec5SDimitry Andric   /// instruction.
271*0b57cec5SDimitry Andric   bool HasFullDataBarrier = false;
272*0b57cec5SDimitry Andric 
273*0b57cec5SDimitry Andric   /// HasV7Clrex - True if the subtarget supports CLREX instructions
274*0b57cec5SDimitry Andric   bool HasV7Clrex = false;
275*0b57cec5SDimitry Andric 
276*0b57cec5SDimitry Andric   /// HasAcquireRelease - True if the subtarget supports v8 atomics (LDA/LDAEX etc)
277*0b57cec5SDimitry Andric   /// instructions
278*0b57cec5SDimitry Andric   bool HasAcquireRelease = false;
279*0b57cec5SDimitry Andric 
280*0b57cec5SDimitry Andric   /// Pref32BitThumb - If true, codegen would prefer 32-bit Thumb instructions
281*0b57cec5SDimitry Andric   /// over 16-bit ones.
282*0b57cec5SDimitry Andric   bool Pref32BitThumb = false;
283*0b57cec5SDimitry Andric 
284*0b57cec5SDimitry Andric   /// AvoidCPSRPartialUpdate - If true, codegen would avoid using instructions
285*0b57cec5SDimitry Andric   /// that partially update CPSR and add false dependency on the previous
286*0b57cec5SDimitry Andric   /// CPSR setting instruction.
287*0b57cec5SDimitry Andric   bool AvoidCPSRPartialUpdate = false;
288*0b57cec5SDimitry Andric 
289*0b57cec5SDimitry Andric   /// CheapPredicableCPSRDef - If true, disable +1 predication cost
290*0b57cec5SDimitry Andric   /// for instructions updating CPSR. Enabled for Cortex-A57.
291*0b57cec5SDimitry Andric   bool CheapPredicableCPSRDef = false;
292*0b57cec5SDimitry Andric 
293*0b57cec5SDimitry Andric   /// AvoidMOVsShifterOperand - If true, codegen should avoid using flag setting
294*0b57cec5SDimitry Andric   /// movs with shifter operand (i.e. asr, lsl, lsr).
295*0b57cec5SDimitry Andric   bool AvoidMOVsShifterOperand = false;
296*0b57cec5SDimitry Andric 
297*0b57cec5SDimitry Andric   /// HasRetAddrStack - Some processors perform return stack prediction. CodeGen should
298*0b57cec5SDimitry Andric   /// avoid issue "normal" call instructions to callees which do not return.
299*0b57cec5SDimitry Andric   bool HasRetAddrStack = false;
300*0b57cec5SDimitry Andric 
301*0b57cec5SDimitry Andric   /// HasBranchPredictor - True if the subtarget has a branch predictor. Having
302*0b57cec5SDimitry Andric   /// a branch predictor or not changes the expected cost of taking a branch
303*0b57cec5SDimitry Andric   /// which affects the choice of whether to use predicated instructions.
304*0b57cec5SDimitry Andric   bool HasBranchPredictor = true;
305*0b57cec5SDimitry Andric 
306*0b57cec5SDimitry Andric   /// HasMPExtension - True if the subtarget supports Multiprocessing
307*0b57cec5SDimitry Andric   /// extension (ARMv7 only).
308*0b57cec5SDimitry Andric   bool HasMPExtension = false;
309*0b57cec5SDimitry Andric 
310*0b57cec5SDimitry Andric   /// HasVirtualization - True if the subtarget supports the Virtualization
311*0b57cec5SDimitry Andric   /// extension.
312*0b57cec5SDimitry Andric   bool HasVirtualization = false;
313*0b57cec5SDimitry Andric 
314*0b57cec5SDimitry Andric   /// HasFP64 - If true, the floating point unit supports double
315*0b57cec5SDimitry Andric   /// precision.
316*0b57cec5SDimitry Andric   bool HasFP64 = false;
317*0b57cec5SDimitry Andric 
318*0b57cec5SDimitry Andric   /// If true, the processor supports the Performance Monitor Extensions. These
319*0b57cec5SDimitry Andric   /// include a generic cycle-counter as well as more fine-grained (often
320*0b57cec5SDimitry Andric   /// implementation-specific) events.
321*0b57cec5SDimitry Andric   bool HasPerfMon = false;
322*0b57cec5SDimitry Andric 
323*0b57cec5SDimitry Andric   /// HasTrustZone - if true, processor supports TrustZone security extensions
324*0b57cec5SDimitry Andric   bool HasTrustZone = false;
325*0b57cec5SDimitry Andric 
326*0b57cec5SDimitry Andric   /// Has8MSecExt - if true, processor supports ARMv8-M Security Extensions
327*0b57cec5SDimitry Andric   bool Has8MSecExt = false;
328*0b57cec5SDimitry Andric 
329*0b57cec5SDimitry Andric   /// HasSHA2 - if true, processor supports SHA1 and SHA256
330*0b57cec5SDimitry Andric   bool HasSHA2 = false;
331*0b57cec5SDimitry Andric 
332*0b57cec5SDimitry Andric   /// HasAES - if true, processor supports AES
333*0b57cec5SDimitry Andric   bool HasAES = false;
334*0b57cec5SDimitry Andric 
335*0b57cec5SDimitry Andric   /// HasCrypto - if true, processor supports Cryptography extensions
336*0b57cec5SDimitry Andric   bool HasCrypto = false;
337*0b57cec5SDimitry Andric 
338*0b57cec5SDimitry Andric   /// HasCRC - if true, processor supports CRC instructions
339*0b57cec5SDimitry Andric   bool HasCRC = false;
340*0b57cec5SDimitry Andric 
341*0b57cec5SDimitry Andric   /// HasRAS - if true, the processor supports RAS extensions
342*0b57cec5SDimitry Andric   bool HasRAS = false;
343*0b57cec5SDimitry Andric 
344*0b57cec5SDimitry Andric   /// HasLOB - if true, the processor supports the Low Overhead Branch extension
345*0b57cec5SDimitry Andric   bool HasLOB = false;
346*0b57cec5SDimitry Andric 
347*0b57cec5SDimitry Andric   /// If true, the instructions "vmov.i32 d0, #0" and "vmov.i32 q0, #0" are
348*0b57cec5SDimitry Andric   /// particularly effective at zeroing a VFP register.
349*0b57cec5SDimitry Andric   bool HasZeroCycleZeroing = false;
350*0b57cec5SDimitry Andric 
351*0b57cec5SDimitry Andric   /// HasFPAO - if true, processor  does positive address offset computation faster
352*0b57cec5SDimitry Andric   bool HasFPAO = false;
353*0b57cec5SDimitry Andric 
354*0b57cec5SDimitry Andric   /// HasFuseAES - if true, processor executes back to back AES instruction
355*0b57cec5SDimitry Andric   /// pairs faster.
356*0b57cec5SDimitry Andric   bool HasFuseAES = false;
357*0b57cec5SDimitry Andric 
358*0b57cec5SDimitry Andric   /// HasFuseLiterals - if true, processor executes back to back
359*0b57cec5SDimitry Andric   /// bottom and top halves of literal generation faster.
360*0b57cec5SDimitry Andric   bool HasFuseLiterals = false;
361*0b57cec5SDimitry Andric 
362*0b57cec5SDimitry Andric   /// If true, if conversion may decide to leave some instructions unpredicated.
363*0b57cec5SDimitry Andric   bool IsProfitableToUnpredicate = false;
364*0b57cec5SDimitry Andric 
365*0b57cec5SDimitry Andric   /// If true, VMOV will be favored over VGETLNi32.
366*0b57cec5SDimitry Andric   bool HasSlowVGETLNi32 = false;
367*0b57cec5SDimitry Andric 
368*0b57cec5SDimitry Andric   /// If true, VMOV will be favored over VDUP.
369*0b57cec5SDimitry Andric   bool HasSlowVDUP32 = false;
370*0b57cec5SDimitry Andric 
371*0b57cec5SDimitry Andric   /// If true, VMOVSR will be favored over VMOVDRR.
372*0b57cec5SDimitry Andric   bool PreferVMOVSR = false;
373*0b57cec5SDimitry Andric 
374*0b57cec5SDimitry Andric   /// If true, ISHST barriers will be used for Release semantics.
375*0b57cec5SDimitry Andric   bool PreferISHST = false;
376*0b57cec5SDimitry Andric 
377*0b57cec5SDimitry Andric   /// If true, a VLDM/VSTM starting with an odd register number is considered to
378*0b57cec5SDimitry Andric   /// take more microops than single VLDRS/VSTRS.
379*0b57cec5SDimitry Andric   bool SlowOddRegister = false;
380*0b57cec5SDimitry Andric 
381*0b57cec5SDimitry Andric   /// If true, loading into a D subregister will be penalized.
382*0b57cec5SDimitry Andric   bool SlowLoadDSubregister = false;
383*0b57cec5SDimitry Andric 
384*0b57cec5SDimitry Andric   /// If true, use a wider stride when allocating VFP registers.
385*0b57cec5SDimitry Andric   bool UseWideStrideVFP = false;
386*0b57cec5SDimitry Andric 
387*0b57cec5SDimitry Andric   /// If true, the AGU and NEON/FPU units are multiplexed.
388*0b57cec5SDimitry Andric   bool HasMuxedUnits = false;
389*0b57cec5SDimitry Andric 
390*0b57cec5SDimitry Andric   /// If true, VMOVS will never be widened to VMOVD.
391*0b57cec5SDimitry Andric   bool DontWidenVMOVS = false;
392*0b57cec5SDimitry Andric 
393*0b57cec5SDimitry Andric   /// If true, splat a register between VFP and NEON instructions.
394*0b57cec5SDimitry Andric   bool SplatVFPToNeon = false;
395*0b57cec5SDimitry Andric 
396*0b57cec5SDimitry Andric   /// If true, run the MLx expansion pass.
397*0b57cec5SDimitry Andric   bool ExpandMLx = false;
398*0b57cec5SDimitry Andric 
399*0b57cec5SDimitry Andric   /// If true, VFP/NEON VMLA/VMLS have special RAW hazards.
400*0b57cec5SDimitry Andric   bool HasVMLxHazards = false;
401*0b57cec5SDimitry Andric 
402*0b57cec5SDimitry Andric   // If true, read thread pointer from coprocessor register.
403*0b57cec5SDimitry Andric   bool ReadTPHard = false;
404*0b57cec5SDimitry Andric 
405*0b57cec5SDimitry Andric   /// If true, VMOVRS, VMOVSR and VMOVS will be converted from VFP to NEON.
406*0b57cec5SDimitry Andric   bool UseNEONForFPMovs = false;
407*0b57cec5SDimitry Andric 
408*0b57cec5SDimitry Andric   /// If true, VLDn instructions take an extra cycle for unaligned accesses.
409*0b57cec5SDimitry Andric   bool CheckVLDnAlign = false;
410*0b57cec5SDimitry Andric 
411*0b57cec5SDimitry Andric   /// If true, VFP instructions are not pipelined.
412*0b57cec5SDimitry Andric   bool NonpipelinedVFP = false;
413*0b57cec5SDimitry Andric 
414*0b57cec5SDimitry Andric   /// StrictAlign - If true, the subtarget disallows unaligned memory
415*0b57cec5SDimitry Andric   /// accesses for some types.  For details, see
416*0b57cec5SDimitry Andric   /// ARMTargetLowering::allowsMisalignedMemoryAccesses().
417*0b57cec5SDimitry Andric   bool StrictAlign = false;
418*0b57cec5SDimitry Andric 
419*0b57cec5SDimitry Andric   /// RestrictIT - If true, the subtarget disallows generation of deprecated IT
420*0b57cec5SDimitry Andric   ///  blocks to conform to ARMv8 rule.
421*0b57cec5SDimitry Andric   bool RestrictIT = false;
422*0b57cec5SDimitry Andric 
423*0b57cec5SDimitry Andric   /// HasDSP - If true, the subtarget supports the DSP (saturating arith
424*0b57cec5SDimitry Andric   /// and such) instructions.
425*0b57cec5SDimitry Andric   bool HasDSP = false;
426*0b57cec5SDimitry Andric 
427*0b57cec5SDimitry Andric   /// NaCl TRAP instruction is generated instead of the regular TRAP.
428*0b57cec5SDimitry Andric   bool UseNaClTrap = false;
429*0b57cec5SDimitry Andric 
430*0b57cec5SDimitry Andric   /// Generate calls via indirect call instructions.
431*0b57cec5SDimitry Andric   bool GenLongCalls = false;
432*0b57cec5SDimitry Andric 
433*0b57cec5SDimitry Andric   /// Generate code that does not contain data access to code sections.
434*0b57cec5SDimitry Andric   bool GenExecuteOnly = false;
435*0b57cec5SDimitry Andric 
436*0b57cec5SDimitry Andric   /// Target machine allowed unsafe FP math (such as use of NEON fp)
437*0b57cec5SDimitry Andric   bool UnsafeFPMath = false;
438*0b57cec5SDimitry Andric 
439*0b57cec5SDimitry Andric   /// UseSjLjEH - If true, the target uses SjLj exception handling (e.g. iOS).
440*0b57cec5SDimitry Andric   bool UseSjLjEH = false;
441*0b57cec5SDimitry Andric 
442*0b57cec5SDimitry Andric   /// Has speculation barrier
443*0b57cec5SDimitry Andric   bool HasSB = false;
444*0b57cec5SDimitry Andric 
445*0b57cec5SDimitry Andric   /// Implicitly convert an instruction to a different one if its immediates
446*0b57cec5SDimitry Andric   /// cannot be encoded. For example, ADD r0, r1, #FFFFFFFF -> SUB r0, r1, #1.
447*0b57cec5SDimitry Andric   bool NegativeImmediates = true;
448*0b57cec5SDimitry Andric 
449*0b57cec5SDimitry Andric   /// stackAlignment - The minimum alignment known to hold of the stack frame on
450*0b57cec5SDimitry Andric   /// entry to the function and which must be maintained by every function.
451*0b57cec5SDimitry Andric   unsigned stackAlignment = 4;
452*0b57cec5SDimitry Andric 
453*0b57cec5SDimitry Andric   /// CPUString - String name of used CPU.
454*0b57cec5SDimitry Andric   std::string CPUString;
455*0b57cec5SDimitry Andric 
456*0b57cec5SDimitry Andric   unsigned MaxInterleaveFactor = 1;
457*0b57cec5SDimitry Andric 
458*0b57cec5SDimitry Andric   /// Clearance before partial register updates (in number of instructions)
459*0b57cec5SDimitry Andric   unsigned PartialUpdateClearance = 0;
460*0b57cec5SDimitry Andric 
461*0b57cec5SDimitry Andric   /// What kind of timing do load multiple/store multiple have (double issue,
462*0b57cec5SDimitry Andric   /// single issue etc).
463*0b57cec5SDimitry Andric   ARMLdStMultipleTiming LdStMultipleTiming = SingleIssue;
464*0b57cec5SDimitry Andric 
465*0b57cec5SDimitry Andric   /// The adjustment that we need to apply to get the operand latency from the
466*0b57cec5SDimitry Andric   /// operand cycle returned by the itinerary data for pre-ISel operands.
467*0b57cec5SDimitry Andric   int PreISelOperandLatencyAdjustment = 2;
468*0b57cec5SDimitry Andric 
469*0b57cec5SDimitry Andric   /// What alignment is preferred for loop bodies, in log2(bytes).
470*0b57cec5SDimitry Andric   unsigned PrefLoopAlignment = 0;
471*0b57cec5SDimitry Andric 
472*0b57cec5SDimitry Andric   /// OptMinSize - True if we're optimising for minimum code size, equal to
473*0b57cec5SDimitry Andric   /// the function attribute.
474*0b57cec5SDimitry Andric   bool OptMinSize = false;
475*0b57cec5SDimitry Andric 
476*0b57cec5SDimitry Andric   /// IsLittle - The target is Little Endian
477*0b57cec5SDimitry Andric   bool IsLittle;
478*0b57cec5SDimitry Andric 
479*0b57cec5SDimitry Andric   /// TargetTriple - What processor and OS we're targeting.
480*0b57cec5SDimitry Andric   Triple TargetTriple;
481*0b57cec5SDimitry Andric 
482*0b57cec5SDimitry Andric   /// SchedModel - Processor specific instruction costs.
483*0b57cec5SDimitry Andric   MCSchedModel SchedModel;
484*0b57cec5SDimitry Andric 
485*0b57cec5SDimitry Andric   /// Selected instruction itineraries (one entry per itinerary class.)
486*0b57cec5SDimitry Andric   InstrItineraryData InstrItins;
487*0b57cec5SDimitry Andric 
488*0b57cec5SDimitry Andric   /// Options passed via command line that could influence the target
489*0b57cec5SDimitry Andric   const TargetOptions &Options;
490*0b57cec5SDimitry Andric 
491*0b57cec5SDimitry Andric   const ARMBaseTargetMachine &TM;
492*0b57cec5SDimitry Andric 
493*0b57cec5SDimitry Andric public:
494*0b57cec5SDimitry Andric   /// This constructor initializes the data members to match that
495*0b57cec5SDimitry Andric   /// of the specified triple.
496*0b57cec5SDimitry Andric   ///
497*0b57cec5SDimitry Andric   ARMSubtarget(const Triple &TT, const std::string &CPU, const std::string &FS,
498*0b57cec5SDimitry Andric                const ARMBaseTargetMachine &TM, bool IsLittle,
499*0b57cec5SDimitry Andric                bool MinSize = false);
500*0b57cec5SDimitry Andric 
501*0b57cec5SDimitry Andric   /// getMaxInlineSizeThreshold - Returns the maximum memset / memcpy size
502*0b57cec5SDimitry Andric   /// that still makes it profitable to inline the call.
503*0b57cec5SDimitry Andric   unsigned getMaxInlineSizeThreshold() const {
504*0b57cec5SDimitry Andric     return 64;
505*0b57cec5SDimitry Andric   }
506*0b57cec5SDimitry Andric 
507*0b57cec5SDimitry Andric   /// ParseSubtargetFeatures - Parses features string setting specified
508*0b57cec5SDimitry Andric   /// subtarget options.  Definition of function is auto generated by tblgen.
509*0b57cec5SDimitry Andric   void ParseSubtargetFeatures(StringRef CPU, StringRef FS);
510*0b57cec5SDimitry Andric 
511*0b57cec5SDimitry Andric   /// initializeSubtargetDependencies - Initializes using a CPU and feature string
512*0b57cec5SDimitry Andric   /// so that we can use initializer lists for subtarget initialization.
513*0b57cec5SDimitry Andric   ARMSubtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS);
514*0b57cec5SDimitry Andric 
515*0b57cec5SDimitry Andric   const ARMSelectionDAGInfo *getSelectionDAGInfo() const override {
516*0b57cec5SDimitry Andric     return &TSInfo;
517*0b57cec5SDimitry Andric   }
518*0b57cec5SDimitry Andric 
519*0b57cec5SDimitry Andric   const ARMBaseInstrInfo *getInstrInfo() const override {
520*0b57cec5SDimitry Andric     return InstrInfo.get();
521*0b57cec5SDimitry Andric   }
522*0b57cec5SDimitry Andric 
523*0b57cec5SDimitry Andric   const ARMTargetLowering *getTargetLowering() const override {
524*0b57cec5SDimitry Andric     return &TLInfo;
525*0b57cec5SDimitry Andric   }
526*0b57cec5SDimitry Andric 
527*0b57cec5SDimitry Andric   const ARMFrameLowering *getFrameLowering() const override {
528*0b57cec5SDimitry Andric     return FrameLowering.get();
529*0b57cec5SDimitry Andric   }
530*0b57cec5SDimitry Andric 
531*0b57cec5SDimitry Andric   const ARMBaseRegisterInfo *getRegisterInfo() const override {
532*0b57cec5SDimitry Andric     return &InstrInfo->getRegisterInfo();
533*0b57cec5SDimitry Andric   }
534*0b57cec5SDimitry Andric 
535*0b57cec5SDimitry Andric   const CallLowering *getCallLowering() const override;
536*0b57cec5SDimitry Andric   const InstructionSelector *getInstructionSelector() const override;
537*0b57cec5SDimitry Andric   const LegalizerInfo *getLegalizerInfo() const override;
538*0b57cec5SDimitry Andric   const RegisterBankInfo *getRegBankInfo() const override;
539*0b57cec5SDimitry Andric 
540*0b57cec5SDimitry Andric private:
541*0b57cec5SDimitry Andric   ARMSelectionDAGInfo TSInfo;
542*0b57cec5SDimitry Andric   // Either Thumb1FrameLowering or ARMFrameLowering.
543*0b57cec5SDimitry Andric   std::unique_ptr<ARMFrameLowering> FrameLowering;
544*0b57cec5SDimitry Andric   // Either Thumb1InstrInfo or Thumb2InstrInfo.
545*0b57cec5SDimitry Andric   std::unique_ptr<ARMBaseInstrInfo> InstrInfo;
546*0b57cec5SDimitry Andric   ARMTargetLowering   TLInfo;
547*0b57cec5SDimitry Andric 
548*0b57cec5SDimitry Andric   /// GlobalISel related APIs.
549*0b57cec5SDimitry Andric   std::unique_ptr<CallLowering> CallLoweringInfo;
550*0b57cec5SDimitry Andric   std::unique_ptr<InstructionSelector> InstSelector;
551*0b57cec5SDimitry Andric   std::unique_ptr<LegalizerInfo> Legalizer;
552*0b57cec5SDimitry Andric   std::unique_ptr<RegisterBankInfo> RegBankInfo;
553*0b57cec5SDimitry Andric 
554*0b57cec5SDimitry Andric   void initializeEnvironment();
555*0b57cec5SDimitry Andric   void initSubtargetFeatures(StringRef CPU, StringRef FS);
556*0b57cec5SDimitry Andric   ARMFrameLowering *initializeFrameLowering(StringRef CPU, StringRef FS);
557*0b57cec5SDimitry Andric 
558*0b57cec5SDimitry Andric public:
559*0b57cec5SDimitry Andric   void computeIssueWidth();
560*0b57cec5SDimitry Andric 
561*0b57cec5SDimitry Andric   bool hasV4TOps()  const { return HasV4TOps;  }
562*0b57cec5SDimitry Andric   bool hasV5TOps()  const { return HasV5TOps;  }
563*0b57cec5SDimitry Andric   bool hasV5TEOps() const { return HasV5TEOps; }
564*0b57cec5SDimitry Andric   bool hasV6Ops()   const { return HasV6Ops;   }
565*0b57cec5SDimitry Andric   bool hasV6MOps()  const { return HasV6MOps;  }
566*0b57cec5SDimitry Andric   bool hasV6KOps()  const { return HasV6KOps; }
567*0b57cec5SDimitry Andric   bool hasV6T2Ops() const { return HasV6T2Ops; }
568*0b57cec5SDimitry Andric   bool hasV7Ops()   const { return HasV7Ops;  }
569*0b57cec5SDimitry Andric   bool hasV8Ops()   const { return HasV8Ops;  }
570*0b57cec5SDimitry Andric   bool hasV8_1aOps() const { return HasV8_1aOps; }
571*0b57cec5SDimitry Andric   bool hasV8_2aOps() const { return HasV8_2aOps; }
572*0b57cec5SDimitry Andric   bool hasV8_3aOps() const { return HasV8_3aOps; }
573*0b57cec5SDimitry Andric   bool hasV8_4aOps() const { return HasV8_4aOps; }
574*0b57cec5SDimitry Andric   bool hasV8_5aOps() const { return HasV8_5aOps; }
575*0b57cec5SDimitry Andric   bool hasV8MBaselineOps() const { return HasV8MBaselineOps; }
576*0b57cec5SDimitry Andric   bool hasV8MMainlineOps() const { return HasV8MMainlineOps; }
577*0b57cec5SDimitry Andric   bool hasV8_1MMainlineOps() const { return HasV8_1MMainlineOps; }
578*0b57cec5SDimitry Andric   bool hasMVEIntegerOps() const { return HasMVEIntegerOps; }
579*0b57cec5SDimitry Andric   bool hasMVEFloatOps() const { return HasMVEFloatOps; }
580*0b57cec5SDimitry Andric   bool hasFPRegs() const { return HasFPRegs; }
581*0b57cec5SDimitry Andric   bool hasFPRegs16() const { return HasFPRegs16; }
582*0b57cec5SDimitry Andric   bool hasFPRegs64() const { return HasFPRegs64; }
583*0b57cec5SDimitry Andric 
584*0b57cec5SDimitry Andric   /// @{
585*0b57cec5SDimitry Andric   /// These functions are obsolete, please consider adding subtarget features
586*0b57cec5SDimitry Andric   /// or properties instead of calling them.
587*0b57cec5SDimitry Andric   bool isCortexA5() const { return ARMProcFamily == CortexA5; }
588*0b57cec5SDimitry Andric   bool isCortexA7() const { return ARMProcFamily == CortexA7; }
589*0b57cec5SDimitry Andric   bool isCortexA8() const { return ARMProcFamily == CortexA8; }
590*0b57cec5SDimitry Andric   bool isCortexA9() const { return ARMProcFamily == CortexA9; }
591*0b57cec5SDimitry Andric   bool isCortexA15() const { return ARMProcFamily == CortexA15; }
592*0b57cec5SDimitry Andric   bool isSwift()    const { return ARMProcFamily == Swift; }
593*0b57cec5SDimitry Andric   bool isCortexM3() const { return ARMProcFamily == CortexM3; }
594*0b57cec5SDimitry Andric   bool isLikeA9() const { return isCortexA9() || isCortexA15() || isKrait(); }
595*0b57cec5SDimitry Andric   bool isCortexR5() const { return ARMProcFamily == CortexR5; }
596*0b57cec5SDimitry Andric   bool isKrait() const { return ARMProcFamily == Krait; }
597*0b57cec5SDimitry Andric   /// @}
598*0b57cec5SDimitry Andric 
599*0b57cec5SDimitry Andric   bool hasARMOps() const { return !NoARM; }
600*0b57cec5SDimitry Andric 
601*0b57cec5SDimitry Andric   bool hasVFP2Base() const { return HasVFPv2SP; }
602*0b57cec5SDimitry Andric   bool hasVFP3Base() const { return HasVFPv3D16SP; }
603*0b57cec5SDimitry Andric   bool hasVFP4Base() const { return HasVFPv4D16SP; }
604*0b57cec5SDimitry Andric   bool hasFPARMv8Base() const { return HasFPARMv8D16SP; }
605*0b57cec5SDimitry Andric   bool hasNEON() const { return HasNEON;  }
606*0b57cec5SDimitry Andric   bool hasSHA2() const { return HasSHA2; }
607*0b57cec5SDimitry Andric   bool hasAES() const { return HasAES; }
608*0b57cec5SDimitry Andric   bool hasCrypto() const { return HasCrypto; }
609*0b57cec5SDimitry Andric   bool hasDotProd() const { return HasDotProd; }
610*0b57cec5SDimitry Andric   bool hasCRC() const { return HasCRC; }
611*0b57cec5SDimitry Andric   bool hasRAS() const { return HasRAS; }
612*0b57cec5SDimitry Andric   bool hasLOB() const { return HasLOB; }
613*0b57cec5SDimitry Andric   bool hasVirtualization() const { return HasVirtualization; }
614*0b57cec5SDimitry Andric 
615*0b57cec5SDimitry Andric   bool useNEONForSinglePrecisionFP() const {
616*0b57cec5SDimitry Andric     return hasNEON() && UseNEONForSinglePrecisionFP;
617*0b57cec5SDimitry Andric   }
618*0b57cec5SDimitry Andric 
619*0b57cec5SDimitry Andric   bool hasDivideInThumbMode() const { return HasHardwareDivideInThumb; }
620*0b57cec5SDimitry Andric   bool hasDivideInARMMode() const { return HasHardwareDivideInARM; }
621*0b57cec5SDimitry Andric   bool hasDataBarrier() const { return HasDataBarrier; }
622*0b57cec5SDimitry Andric   bool hasFullDataBarrier() const { return HasFullDataBarrier; }
623*0b57cec5SDimitry Andric   bool hasV7Clrex() const { return HasV7Clrex; }
624*0b57cec5SDimitry Andric   bool hasAcquireRelease() const { return HasAcquireRelease; }
625*0b57cec5SDimitry Andric 
626*0b57cec5SDimitry Andric   bool hasAnyDataBarrier() const {
627*0b57cec5SDimitry Andric     return HasDataBarrier || (hasV6Ops() && !isThumb());
628*0b57cec5SDimitry Andric   }
629*0b57cec5SDimitry Andric 
630*0b57cec5SDimitry Andric   bool useMulOps() const { return UseMulOps; }
631*0b57cec5SDimitry Andric   bool useFPVMLx() const { return !SlowFPVMLx; }
632*0b57cec5SDimitry Andric   bool hasVMLxForwarding() const { return HasVMLxForwarding; }
633*0b57cec5SDimitry Andric   bool isFPBrccSlow() const { return SlowFPBrcc; }
634*0b57cec5SDimitry Andric   bool hasFP64() const { return HasFP64; }
635*0b57cec5SDimitry Andric   bool hasPerfMon() const { return HasPerfMon; }
636*0b57cec5SDimitry Andric   bool hasTrustZone() const { return HasTrustZone; }
637*0b57cec5SDimitry Andric   bool has8MSecExt() const { return Has8MSecExt; }
638*0b57cec5SDimitry Andric   bool hasZeroCycleZeroing() const { return HasZeroCycleZeroing; }
639*0b57cec5SDimitry Andric   bool hasFPAO() const { return HasFPAO; }
640*0b57cec5SDimitry Andric   bool isProfitableToUnpredicate() const { return IsProfitableToUnpredicate; }
641*0b57cec5SDimitry Andric   bool hasSlowVGETLNi32() const { return HasSlowVGETLNi32; }
642*0b57cec5SDimitry Andric   bool hasSlowVDUP32() const { return HasSlowVDUP32; }
643*0b57cec5SDimitry Andric   bool preferVMOVSR() const { return PreferVMOVSR; }
644*0b57cec5SDimitry Andric   bool preferISHSTBarriers() const { return PreferISHST; }
645*0b57cec5SDimitry Andric   bool expandMLx() const { return ExpandMLx; }
646*0b57cec5SDimitry Andric   bool hasVMLxHazards() const { return HasVMLxHazards; }
647*0b57cec5SDimitry Andric   bool hasSlowOddRegister() const { return SlowOddRegister; }
648*0b57cec5SDimitry Andric   bool hasSlowLoadDSubregister() const { return SlowLoadDSubregister; }
649*0b57cec5SDimitry Andric   bool useWideStrideVFP() const { return UseWideStrideVFP; }
650*0b57cec5SDimitry Andric   bool hasMuxedUnits() const { return HasMuxedUnits; }
651*0b57cec5SDimitry Andric   bool dontWidenVMOVS() const { return DontWidenVMOVS; }
652*0b57cec5SDimitry Andric   bool useSplatVFPToNeon() const { return SplatVFPToNeon; }
653*0b57cec5SDimitry Andric   bool useNEONForFPMovs() const { return UseNEONForFPMovs; }
654*0b57cec5SDimitry Andric   bool checkVLDnAccessAlignment() const { return CheckVLDnAlign; }
655*0b57cec5SDimitry Andric   bool nonpipelinedVFP() const { return NonpipelinedVFP; }
656*0b57cec5SDimitry Andric   bool prefers32BitThumb() const { return Pref32BitThumb; }
657*0b57cec5SDimitry Andric   bool avoidCPSRPartialUpdate() const { return AvoidCPSRPartialUpdate; }
658*0b57cec5SDimitry Andric   bool cheapPredicableCPSRDef() const { return CheapPredicableCPSRDef; }
659*0b57cec5SDimitry Andric   bool avoidMOVsShifterOperand() const { return AvoidMOVsShifterOperand; }
660*0b57cec5SDimitry Andric   bool hasRetAddrStack() const { return HasRetAddrStack; }
661*0b57cec5SDimitry Andric   bool hasBranchPredictor() const { return HasBranchPredictor; }
662*0b57cec5SDimitry Andric   bool hasMPExtension() const { return HasMPExtension; }
663*0b57cec5SDimitry Andric   bool hasDSP() const { return HasDSP; }
664*0b57cec5SDimitry Andric   bool useNaClTrap() const { return UseNaClTrap; }
665*0b57cec5SDimitry Andric   bool useSjLjEH() const { return UseSjLjEH; }
666*0b57cec5SDimitry Andric   bool hasSB() const { return HasSB; }
667*0b57cec5SDimitry Andric   bool genLongCalls() const { return GenLongCalls; }
668*0b57cec5SDimitry Andric   bool genExecuteOnly() const { return GenExecuteOnly; }
669*0b57cec5SDimitry Andric 
670*0b57cec5SDimitry Andric   bool hasFP16() const { return HasFP16; }
671*0b57cec5SDimitry Andric   bool hasD32() const { return HasD32; }
672*0b57cec5SDimitry Andric   bool hasFullFP16() const { return HasFullFP16; }
673*0b57cec5SDimitry Andric   bool hasFP16FML() const { return HasFP16FML; }
674*0b57cec5SDimitry Andric 
675*0b57cec5SDimitry Andric   bool hasFuseAES() const { return HasFuseAES; }
676*0b57cec5SDimitry Andric   bool hasFuseLiterals() const { return HasFuseLiterals; }
677*0b57cec5SDimitry Andric   /// Return true if the CPU supports any kind of instruction fusion.
678*0b57cec5SDimitry Andric   bool hasFusion() const { return hasFuseAES() || hasFuseLiterals(); }
679*0b57cec5SDimitry Andric 
680*0b57cec5SDimitry Andric   const Triple &getTargetTriple() const { return TargetTriple; }
681*0b57cec5SDimitry Andric 
682*0b57cec5SDimitry Andric   bool isTargetDarwin() const { return TargetTriple.isOSDarwin(); }
683*0b57cec5SDimitry Andric   bool isTargetIOS() const { return TargetTriple.isiOS(); }
684*0b57cec5SDimitry Andric   bool isTargetWatchOS() const { return TargetTriple.isWatchOS(); }
685*0b57cec5SDimitry Andric   bool isTargetWatchABI() const { return TargetTriple.isWatchABI(); }
686*0b57cec5SDimitry Andric   bool isTargetLinux() const { return TargetTriple.isOSLinux(); }
687*0b57cec5SDimitry Andric   bool isTargetNaCl() const { return TargetTriple.isOSNaCl(); }
688*0b57cec5SDimitry Andric   bool isTargetNetBSD() const { return TargetTriple.isOSNetBSD(); }
689*0b57cec5SDimitry Andric   bool isTargetWindows() const { return TargetTriple.isOSWindows(); }
690*0b57cec5SDimitry Andric 
691*0b57cec5SDimitry Andric   bool isTargetCOFF() const { return TargetTriple.isOSBinFormatCOFF(); }
692*0b57cec5SDimitry Andric   bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }
693*0b57cec5SDimitry Andric   bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); }
694*0b57cec5SDimitry Andric 
695*0b57cec5SDimitry Andric   // ARM EABI is the bare-metal EABI described in ARM ABI documents and
696*0b57cec5SDimitry Andric   // can be accessed via -target arm-none-eabi. This is NOT GNUEABI.
697*0b57cec5SDimitry Andric   // FIXME: Add a flag for bare-metal for that target and set Triple::EABI
698*0b57cec5SDimitry Andric   // even for GNUEABI, so we can make a distinction here and still conform to
699*0b57cec5SDimitry Andric   // the EABI on GNU (and Android) mode. This requires change in Clang, too.
700*0b57cec5SDimitry Andric   // FIXME: The Darwin exception is temporary, while we move users to
701*0b57cec5SDimitry Andric   // "*-*-*-macho" triples as quickly as possible.
702*0b57cec5SDimitry Andric   bool isTargetAEABI() const {
703*0b57cec5SDimitry Andric     return (TargetTriple.getEnvironment() == Triple::EABI ||
704*0b57cec5SDimitry Andric             TargetTriple.getEnvironment() == Triple::EABIHF) &&
705*0b57cec5SDimitry Andric            !isTargetDarwin() && !isTargetWindows();
706*0b57cec5SDimitry Andric   }
707*0b57cec5SDimitry Andric   bool isTargetGNUAEABI() const {
708*0b57cec5SDimitry Andric     return (TargetTriple.getEnvironment() == Triple::GNUEABI ||
709*0b57cec5SDimitry Andric             TargetTriple.getEnvironment() == Triple::GNUEABIHF) &&
710*0b57cec5SDimitry Andric            !isTargetDarwin() && !isTargetWindows();
711*0b57cec5SDimitry Andric   }
712*0b57cec5SDimitry Andric   bool isTargetMuslAEABI() const {
713*0b57cec5SDimitry Andric     return (TargetTriple.getEnvironment() == Triple::MuslEABI ||
714*0b57cec5SDimitry Andric             TargetTriple.getEnvironment() == Triple::MuslEABIHF) &&
715*0b57cec5SDimitry Andric            !isTargetDarwin() && !isTargetWindows();
716*0b57cec5SDimitry Andric   }
717*0b57cec5SDimitry Andric 
718*0b57cec5SDimitry Andric   // ARM Targets that support EHABI exception handling standard
719*0b57cec5SDimitry Andric   // Darwin uses SjLj. Other targets might need more checks.
720*0b57cec5SDimitry Andric   bool isTargetEHABICompatible() const {
721*0b57cec5SDimitry Andric     return (TargetTriple.getEnvironment() == Triple::EABI ||
722*0b57cec5SDimitry Andric             TargetTriple.getEnvironment() == Triple::GNUEABI ||
723*0b57cec5SDimitry Andric             TargetTriple.getEnvironment() == Triple::MuslEABI ||
724*0b57cec5SDimitry Andric             TargetTriple.getEnvironment() == Triple::EABIHF ||
725*0b57cec5SDimitry Andric             TargetTriple.getEnvironment() == Triple::GNUEABIHF ||
726*0b57cec5SDimitry Andric             TargetTriple.getEnvironment() == Triple::MuslEABIHF ||
727*0b57cec5SDimitry Andric             isTargetAndroid()) &&
728*0b57cec5SDimitry Andric            !isTargetDarwin() && !isTargetWindows();
729*0b57cec5SDimitry Andric   }
730*0b57cec5SDimitry Andric 
731*0b57cec5SDimitry Andric   bool isTargetHardFloat() const;
732*0b57cec5SDimitry Andric 
733*0b57cec5SDimitry Andric   bool isTargetAndroid() const { return TargetTriple.isAndroid(); }
734*0b57cec5SDimitry Andric 
735*0b57cec5SDimitry Andric   bool isXRaySupported() const override;
736*0b57cec5SDimitry Andric 
737*0b57cec5SDimitry Andric   bool isAPCS_ABI() const;
738*0b57cec5SDimitry Andric   bool isAAPCS_ABI() const;
739*0b57cec5SDimitry Andric   bool isAAPCS16_ABI() const;
740*0b57cec5SDimitry Andric 
741*0b57cec5SDimitry Andric   bool isROPI() const;
742*0b57cec5SDimitry Andric   bool isRWPI() const;
743*0b57cec5SDimitry Andric 
744*0b57cec5SDimitry Andric   bool useMachineScheduler() const { return UseMISched; }
745*0b57cec5SDimitry Andric   bool disablePostRAScheduler() const { return DisablePostRAScheduler; }
746*0b57cec5SDimitry Andric   bool useSoftFloat() const { return UseSoftFloat; }
747*0b57cec5SDimitry Andric   bool isThumb() const { return InThumbMode; }
748*0b57cec5SDimitry Andric   bool hasMinSize() const { return OptMinSize; }
749*0b57cec5SDimitry Andric   bool isThumb1Only() const { return InThumbMode && !HasThumb2; }
750*0b57cec5SDimitry Andric   bool isThumb2() const { return InThumbMode && HasThumb2; }
751*0b57cec5SDimitry Andric   bool hasThumb2() const { return HasThumb2; }
752*0b57cec5SDimitry Andric   bool isMClass() const { return ARMProcClass == MClass; }
753*0b57cec5SDimitry Andric   bool isRClass() const { return ARMProcClass == RClass; }
754*0b57cec5SDimitry Andric   bool isAClass() const { return ARMProcClass == AClass; }
755*0b57cec5SDimitry Andric   bool isReadTPHard() const { return ReadTPHard; }
756*0b57cec5SDimitry Andric 
757*0b57cec5SDimitry Andric   bool isR9Reserved() const {
758*0b57cec5SDimitry Andric     return isTargetMachO() ? (ReserveR9 || !HasV6Ops) : ReserveR9;
759*0b57cec5SDimitry Andric   }
760*0b57cec5SDimitry Andric 
761*0b57cec5SDimitry Andric   bool useR7AsFramePointer() const {
762*0b57cec5SDimitry Andric     return isTargetDarwin() || (!isTargetWindows() && isThumb());
763*0b57cec5SDimitry Andric   }
764*0b57cec5SDimitry Andric 
765*0b57cec5SDimitry Andric   /// Returns true if the frame setup is split into two separate pushes (first
766*0b57cec5SDimitry Andric   /// r0-r7,lr then r8-r11), principally so that the frame pointer is adjacent
767*0b57cec5SDimitry Andric   /// to lr. This is always required on Thumb1-only targets, as the push and
768*0b57cec5SDimitry Andric   /// pop instructions can't access the high registers.
769*0b57cec5SDimitry Andric   bool splitFramePushPop(const MachineFunction &MF) const {
770*0b57cec5SDimitry Andric     return (useR7AsFramePointer() &&
771*0b57cec5SDimitry Andric             MF.getTarget().Options.DisableFramePointerElim(MF)) ||
772*0b57cec5SDimitry Andric            isThumb1Only();
773*0b57cec5SDimitry Andric   }
774*0b57cec5SDimitry Andric 
775*0b57cec5SDimitry Andric   bool useStride4VFPs() const;
776*0b57cec5SDimitry Andric 
777*0b57cec5SDimitry Andric   bool useMovt() const;
778*0b57cec5SDimitry Andric 
779*0b57cec5SDimitry Andric   bool supportsTailCall() const { return SupportsTailCall; }
780*0b57cec5SDimitry Andric 
781*0b57cec5SDimitry Andric   bool allowsUnalignedMem() const { return !StrictAlign; }
782*0b57cec5SDimitry Andric 
783*0b57cec5SDimitry Andric   bool restrictIT() const { return RestrictIT; }
784*0b57cec5SDimitry Andric 
785*0b57cec5SDimitry Andric   const std::string & getCPUString() const { return CPUString; }
786*0b57cec5SDimitry Andric 
787*0b57cec5SDimitry Andric   bool isLittle() const { return IsLittle; }
788*0b57cec5SDimitry Andric 
789*0b57cec5SDimitry Andric   unsigned getMispredictionPenalty() const;
790*0b57cec5SDimitry Andric 
791*0b57cec5SDimitry Andric   /// Returns true if machine scheduler should be enabled.
792*0b57cec5SDimitry Andric   bool enableMachineScheduler() const override;
793*0b57cec5SDimitry Andric 
794*0b57cec5SDimitry Andric   /// True for some subtargets at > -O0.
795*0b57cec5SDimitry Andric   bool enablePostRAScheduler() const override;
796*0b57cec5SDimitry Andric 
797*0b57cec5SDimitry Andric   /// Enable use of alias analysis during code generation (during MI
798*0b57cec5SDimitry Andric   /// scheduling, DAGCombine, etc.).
799*0b57cec5SDimitry Andric   bool useAA() const override { return UseAA; }
800*0b57cec5SDimitry Andric 
801*0b57cec5SDimitry Andric   // enableAtomicExpand- True if we need to expand our atomics.
802*0b57cec5SDimitry Andric   bool enableAtomicExpand() const override;
803*0b57cec5SDimitry Andric 
804*0b57cec5SDimitry Andric   /// getInstrItins - Return the instruction itineraries based on subtarget
805*0b57cec5SDimitry Andric   /// selection.
806*0b57cec5SDimitry Andric   const InstrItineraryData *getInstrItineraryData() const override {
807*0b57cec5SDimitry Andric     return &InstrItins;
808*0b57cec5SDimitry Andric   }
809*0b57cec5SDimitry Andric 
810*0b57cec5SDimitry Andric   /// getStackAlignment - Returns the minimum alignment known to hold of the
811*0b57cec5SDimitry Andric   /// stack frame on entry to the function and which must be maintained by every
812*0b57cec5SDimitry Andric   /// function for this subtarget.
813*0b57cec5SDimitry Andric   unsigned getStackAlignment() const { return stackAlignment; }
814*0b57cec5SDimitry Andric 
815*0b57cec5SDimitry Andric   unsigned getMaxInterleaveFactor() const { return MaxInterleaveFactor; }
816*0b57cec5SDimitry Andric 
817*0b57cec5SDimitry Andric   unsigned getPartialUpdateClearance() const { return PartialUpdateClearance; }
818*0b57cec5SDimitry Andric 
819*0b57cec5SDimitry Andric   ARMLdStMultipleTiming getLdStMultipleTiming() const {
820*0b57cec5SDimitry Andric     return LdStMultipleTiming;
821*0b57cec5SDimitry Andric   }
822*0b57cec5SDimitry Andric 
823*0b57cec5SDimitry Andric   int getPreISelOperandLatencyAdjustment() const {
824*0b57cec5SDimitry Andric     return PreISelOperandLatencyAdjustment;
825*0b57cec5SDimitry Andric   }
826*0b57cec5SDimitry Andric 
827*0b57cec5SDimitry Andric   /// True if the GV will be accessed via an indirect symbol.
828*0b57cec5SDimitry Andric   bool isGVIndirectSymbol(const GlobalValue *GV) const;
829*0b57cec5SDimitry Andric 
830*0b57cec5SDimitry Andric   /// Returns the constant pool modifier needed to access the GV.
831*0b57cec5SDimitry Andric   bool isGVInGOT(const GlobalValue *GV) const;
832*0b57cec5SDimitry Andric 
833*0b57cec5SDimitry Andric   /// True if fast-isel is used.
834*0b57cec5SDimitry Andric   bool useFastISel() const;
835*0b57cec5SDimitry Andric 
836*0b57cec5SDimitry Andric   /// Returns the correct return opcode for the current feature set.
837*0b57cec5SDimitry Andric   /// Use BX if available to allow mixing thumb/arm code, but fall back
838*0b57cec5SDimitry Andric   /// to plain mov pc,lr on ARMv4.
839*0b57cec5SDimitry Andric   unsigned getReturnOpcode() const {
840*0b57cec5SDimitry Andric     if (isThumb())
841*0b57cec5SDimitry Andric       return ARM::tBX_RET;
842*0b57cec5SDimitry Andric     if (hasV4TOps())
843*0b57cec5SDimitry Andric       return ARM::BX_RET;
844*0b57cec5SDimitry Andric     return ARM::MOVPCLR;
845*0b57cec5SDimitry Andric   }
846*0b57cec5SDimitry Andric 
847*0b57cec5SDimitry Andric   /// Allow movt+movw for PIC global address calculation.
848*0b57cec5SDimitry Andric   /// ELF does not have GOT relocations for movt+movw.
849*0b57cec5SDimitry Andric   /// ROPI does not use GOT.
850*0b57cec5SDimitry Andric   bool allowPositionIndependentMovt() const {
851*0b57cec5SDimitry Andric     return isROPI() || !isTargetELF();
852*0b57cec5SDimitry Andric   }
853*0b57cec5SDimitry Andric 
854*0b57cec5SDimitry Andric   unsigned getPrefLoopAlignment() const {
855*0b57cec5SDimitry Andric     return PrefLoopAlignment;
856*0b57cec5SDimitry Andric   }
857*0b57cec5SDimitry Andric 
858*0b57cec5SDimitry Andric   bool ignoreCSRForAllocationOrder(const MachineFunction &MF,
859*0b57cec5SDimitry Andric                                    unsigned PhysReg) const override;
860*0b57cec5SDimitry Andric   unsigned getGPRAllocationOrder(const MachineFunction &MF) const;
861*0b57cec5SDimitry Andric };
862*0b57cec5SDimitry Andric 
863*0b57cec5SDimitry Andric } // end namespace llvm
864*0b57cec5SDimitry Andric 
865*0b57cec5SDimitry Andric #endif  // LLVM_LIB_TARGET_ARM_ARMSUBTARGET_H
866