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