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