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