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   /// SlowFPVFMx - If the VFP4 / NEON instructions are available, indicates
207   /// whether the FP VFM[AS] instructions are slow (if so, don't use them).
208   bool SlowFPVFMx = false;
209 
210   /// HasVMLxForwarding - If true, NEON has special multiplier accumulator
211   /// forwarding to allow mul + mla being issued back to back.
212   bool HasVMLxForwarding = false;
213 
214   /// SlowFPBrcc - True if floating point compare + branch is slow.
215   bool SlowFPBrcc = false;
216 
217   /// InThumbMode - True if compiling for Thumb, false for ARM.
218   bool InThumbMode = false;
219 
220   /// UseSoftFloat - True if we're using software floating point features.
221   bool UseSoftFloat = false;
222 
223   /// UseMISched - True if MachineScheduler should be used for this subtarget.
224   bool UseMISched = false;
225 
226   /// DisablePostRAScheduler - False if scheduling should happen again after
227   /// register allocation.
228   bool DisablePostRAScheduler = 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   Align stackAlignment = Align(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 PrefLoopLogAlignment = 0;
473 
474   /// The cost factor for MVE instructions, representing the multiple beats an
475   // instruction can take. The default is 2, (set in initSubtargetFeatures so
476   // that we can use subtarget features less than 2).
477   unsigned MVEVectorCostFactor = 0;
478 
479   /// OptMinSize - True if we're optimising for minimum code size, equal to
480   /// the function attribute.
481   bool OptMinSize = false;
482 
483   /// IsLittle - The target is Little Endian
484   bool IsLittle;
485 
486   /// TargetTriple - What processor and OS we're targeting.
487   Triple TargetTriple;
488 
489   /// SchedModel - Processor specific instruction costs.
490   MCSchedModel SchedModel;
491 
492   /// Selected instruction itineraries (one entry per itinerary class.)
493   InstrItineraryData InstrItins;
494 
495   /// Options passed via command line that could influence the target
496   const TargetOptions &Options;
497 
498   const ARMBaseTargetMachine &TM;
499 
500 public:
501   /// This constructor initializes the data members to match that
502   /// of the specified triple.
503   ///
504   ARMSubtarget(const Triple &TT, const std::string &CPU, const std::string &FS,
505                const ARMBaseTargetMachine &TM, bool IsLittle,
506                bool MinSize = false);
507 
508   /// getMaxInlineSizeThreshold - Returns the maximum memset / memcpy size
509   /// that still makes it profitable to inline the call.
510   unsigned getMaxInlineSizeThreshold() const {
511     return 64;
512   }
513 
514   /// ParseSubtargetFeatures - Parses features string setting specified
515   /// subtarget options.  Definition of function is auto generated by tblgen.
516   void ParseSubtargetFeatures(StringRef CPU, StringRef FS);
517 
518   /// initializeSubtargetDependencies - Initializes using a CPU and feature string
519   /// so that we can use initializer lists for subtarget initialization.
520   ARMSubtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS);
521 
522   const ARMSelectionDAGInfo *getSelectionDAGInfo() const override {
523     return &TSInfo;
524   }
525 
526   const ARMBaseInstrInfo *getInstrInfo() const override {
527     return InstrInfo.get();
528   }
529 
530   const ARMTargetLowering *getTargetLowering() const override {
531     return &TLInfo;
532   }
533 
534   const ARMFrameLowering *getFrameLowering() const override {
535     return FrameLowering.get();
536   }
537 
538   const ARMBaseRegisterInfo *getRegisterInfo() const override {
539     return &InstrInfo->getRegisterInfo();
540   }
541 
542   const CallLowering *getCallLowering() const override;
543   InstructionSelector *getInstructionSelector() const override;
544   const LegalizerInfo *getLegalizerInfo() const override;
545   const RegisterBankInfo *getRegBankInfo() const override;
546 
547 private:
548   ARMSelectionDAGInfo TSInfo;
549   // Either Thumb1FrameLowering or ARMFrameLowering.
550   std::unique_ptr<ARMFrameLowering> FrameLowering;
551   // Either Thumb1InstrInfo or Thumb2InstrInfo.
552   std::unique_ptr<ARMBaseInstrInfo> InstrInfo;
553   ARMTargetLowering   TLInfo;
554 
555   /// GlobalISel related APIs.
556   std::unique_ptr<CallLowering> CallLoweringInfo;
557   std::unique_ptr<InstructionSelector> InstSelector;
558   std::unique_ptr<LegalizerInfo> Legalizer;
559   std::unique_ptr<RegisterBankInfo> RegBankInfo;
560 
561   void initializeEnvironment();
562   void initSubtargetFeatures(StringRef CPU, StringRef FS);
563   ARMFrameLowering *initializeFrameLowering(StringRef CPU, StringRef FS);
564 
565 public:
566   void computeIssueWidth();
567 
568   bool hasV4TOps()  const { return HasV4TOps;  }
569   bool hasV5TOps()  const { return HasV5TOps;  }
570   bool hasV5TEOps() const { return HasV5TEOps; }
571   bool hasV6Ops()   const { return HasV6Ops;   }
572   bool hasV6MOps()  const { return HasV6MOps;  }
573   bool hasV6KOps()  const { return HasV6KOps; }
574   bool hasV6T2Ops() const { return HasV6T2Ops; }
575   bool hasV7Ops()   const { return HasV7Ops;  }
576   bool hasV8Ops()   const { return HasV8Ops;  }
577   bool hasV8_1aOps() const { return HasV8_1aOps; }
578   bool hasV8_2aOps() const { return HasV8_2aOps; }
579   bool hasV8_3aOps() const { return HasV8_3aOps; }
580   bool hasV8_4aOps() const { return HasV8_4aOps; }
581   bool hasV8_5aOps() const { return HasV8_5aOps; }
582   bool hasV8MBaselineOps() const { return HasV8MBaselineOps; }
583   bool hasV8MMainlineOps() const { return HasV8MMainlineOps; }
584   bool hasV8_1MMainlineOps() const { return HasV8_1MMainlineOps; }
585   bool hasMVEIntegerOps() const { return HasMVEIntegerOps; }
586   bool hasMVEFloatOps() const { return HasMVEFloatOps; }
587   bool hasFPRegs() const { return HasFPRegs; }
588   bool hasFPRegs16() const { return HasFPRegs16; }
589   bool hasFPRegs64() const { return HasFPRegs64; }
590 
591   /// @{
592   /// These functions are obsolete, please consider adding subtarget features
593   /// or properties instead of calling them.
594   bool isCortexA5() const { return ARMProcFamily == CortexA5; }
595   bool isCortexA7() const { return ARMProcFamily == CortexA7; }
596   bool isCortexA8() const { return ARMProcFamily == CortexA8; }
597   bool isCortexA9() const { return ARMProcFamily == CortexA9; }
598   bool isCortexA15() const { return ARMProcFamily == CortexA15; }
599   bool isSwift()    const { return ARMProcFamily == Swift; }
600   bool isCortexM3() const { return ARMProcFamily == CortexM3; }
601   bool isLikeA9() const { return isCortexA9() || isCortexA15() || isKrait(); }
602   bool isCortexR5() const { return ARMProcFamily == CortexR5; }
603   bool isKrait() const { return ARMProcFamily == Krait; }
604   /// @}
605 
606   bool hasARMOps() const { return !NoARM; }
607 
608   bool hasVFP2Base() const { return HasVFPv2SP; }
609   bool hasVFP3Base() const { return HasVFPv3D16SP; }
610   bool hasVFP4Base() const { return HasVFPv4D16SP; }
611   bool hasFPARMv8Base() const { return HasFPARMv8D16SP; }
612   bool hasNEON() const { return HasNEON;  }
613   bool hasSHA2() const { return HasSHA2; }
614   bool hasAES() const { return HasAES; }
615   bool hasCrypto() const { return HasCrypto; }
616   bool hasDotProd() const { return HasDotProd; }
617   bool hasCRC() const { return HasCRC; }
618   bool hasRAS() const { return HasRAS; }
619   bool hasLOB() const { return HasLOB; }
620   bool hasVirtualization() const { return HasVirtualization; }
621 
622   bool useNEONForSinglePrecisionFP() const {
623     return hasNEON() && UseNEONForSinglePrecisionFP;
624   }
625 
626   bool hasDivideInThumbMode() const { return HasHardwareDivideInThumb; }
627   bool hasDivideInARMMode() const { return HasHardwareDivideInARM; }
628   bool hasDataBarrier() const { return HasDataBarrier; }
629   bool hasFullDataBarrier() const { return HasFullDataBarrier; }
630   bool hasV7Clrex() const { return HasV7Clrex; }
631   bool hasAcquireRelease() const { return HasAcquireRelease; }
632 
633   bool hasAnyDataBarrier() const {
634     return HasDataBarrier || (hasV6Ops() && !isThumb());
635   }
636 
637   bool useMulOps() const { return UseMulOps; }
638   bool useFPVMLx() const { return !SlowFPVMLx; }
639   bool useFPVFMx() const {
640     return !isTargetDarwin() && hasVFP4Base() && !SlowFPVFMx;
641   }
642   bool useFPVFMx16() const { return useFPVFMx() && hasFullFP16(); }
643   bool useFPVFMx64() const { return useFPVFMx() && hasFP64(); }
644   bool hasVMLxForwarding() const { return HasVMLxForwarding; }
645   bool isFPBrccSlow() const { return SlowFPBrcc; }
646   bool hasFP64() const { return HasFP64; }
647   bool hasPerfMon() const { return HasPerfMon; }
648   bool hasTrustZone() const { return HasTrustZone; }
649   bool has8MSecExt() const { return Has8MSecExt; }
650   bool hasZeroCycleZeroing() const { return HasZeroCycleZeroing; }
651   bool hasFPAO() const { return HasFPAO; }
652   bool isProfitableToUnpredicate() const { return IsProfitableToUnpredicate; }
653   bool hasSlowVGETLNi32() const { return HasSlowVGETLNi32; }
654   bool hasSlowVDUP32() const { return HasSlowVDUP32; }
655   bool preferVMOVSR() const { return PreferVMOVSR; }
656   bool preferISHSTBarriers() const { return PreferISHST; }
657   bool expandMLx() const { return ExpandMLx; }
658   bool hasVMLxHazards() const { return HasVMLxHazards; }
659   bool hasSlowOddRegister() const { return SlowOddRegister; }
660   bool hasSlowLoadDSubregister() const { return SlowLoadDSubregister; }
661   bool useWideStrideVFP() const { return UseWideStrideVFP; }
662   bool hasMuxedUnits() const { return HasMuxedUnits; }
663   bool dontWidenVMOVS() const { return DontWidenVMOVS; }
664   bool useSplatVFPToNeon() const { return SplatVFPToNeon; }
665   bool useNEONForFPMovs() const { return UseNEONForFPMovs; }
666   bool checkVLDnAccessAlignment() const { return CheckVLDnAlign; }
667   bool nonpipelinedVFP() const { return NonpipelinedVFP; }
668   bool prefers32BitThumb() const { return Pref32BitThumb; }
669   bool avoidCPSRPartialUpdate() const { return AvoidCPSRPartialUpdate; }
670   bool cheapPredicableCPSRDef() const { return CheapPredicableCPSRDef; }
671   bool avoidMOVsShifterOperand() const { return AvoidMOVsShifterOperand; }
672   bool hasRetAddrStack() const { return HasRetAddrStack; }
673   bool hasBranchPredictor() const { return HasBranchPredictor; }
674   bool hasMPExtension() const { return HasMPExtension; }
675   bool hasDSP() const { return HasDSP; }
676   bool useNaClTrap() const { return UseNaClTrap; }
677   bool useSjLjEH() const { return UseSjLjEH; }
678   bool hasSB() const { return HasSB; }
679   bool genLongCalls() const { return GenLongCalls; }
680   bool genExecuteOnly() const { return GenExecuteOnly; }
681   bool hasBaseDSP() const {
682     if (isThumb())
683       return hasDSP();
684     else
685       return hasV5TEOps();
686   }
687 
688   bool hasFP16() const { return HasFP16; }
689   bool hasD32() const { return HasD32; }
690   bool hasFullFP16() const { return HasFullFP16; }
691   bool hasFP16FML() const { return HasFP16FML; }
692 
693   bool hasFuseAES() const { return HasFuseAES; }
694   bool hasFuseLiterals() const { return HasFuseLiterals; }
695   /// Return true if the CPU supports any kind of instruction fusion.
696   bool hasFusion() const { return hasFuseAES() || hasFuseLiterals(); }
697 
698   const Triple &getTargetTriple() const { return TargetTriple; }
699 
700   bool isTargetDarwin() const { return TargetTriple.isOSDarwin(); }
701   bool isTargetIOS() const { return TargetTriple.isiOS(); }
702   bool isTargetWatchOS() const { return TargetTriple.isWatchOS(); }
703   bool isTargetWatchABI() const { return TargetTriple.isWatchABI(); }
704   bool isTargetLinux() const { return TargetTriple.isOSLinux(); }
705   bool isTargetNaCl() const { return TargetTriple.isOSNaCl(); }
706   bool isTargetNetBSD() const { return TargetTriple.isOSNetBSD(); }
707   bool isTargetWindows() const { return TargetTriple.isOSWindows(); }
708 
709   bool isTargetCOFF() const { return TargetTriple.isOSBinFormatCOFF(); }
710   bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }
711   bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); }
712 
713   // ARM EABI is the bare-metal EABI described in ARM ABI documents and
714   // can be accessed via -target arm-none-eabi. This is NOT GNUEABI.
715   // FIXME: Add a flag for bare-metal for that target and set Triple::EABI
716   // even for GNUEABI, so we can make a distinction here and still conform to
717   // the EABI on GNU (and Android) mode. This requires change in Clang, too.
718   // FIXME: The Darwin exception is temporary, while we move users to
719   // "*-*-*-macho" triples as quickly as possible.
720   bool isTargetAEABI() const {
721     return (TargetTriple.getEnvironment() == Triple::EABI ||
722             TargetTriple.getEnvironment() == Triple::EABIHF) &&
723            !isTargetDarwin() && !isTargetWindows();
724   }
725   bool isTargetGNUAEABI() const {
726     return (TargetTriple.getEnvironment() == Triple::GNUEABI ||
727             TargetTriple.getEnvironment() == Triple::GNUEABIHF) &&
728            !isTargetDarwin() && !isTargetWindows();
729   }
730   bool isTargetMuslAEABI() const {
731     return (TargetTriple.getEnvironment() == Triple::MuslEABI ||
732             TargetTriple.getEnvironment() == Triple::MuslEABIHF) &&
733            !isTargetDarwin() && !isTargetWindows();
734   }
735 
736   // ARM Targets that support EHABI exception handling standard
737   // Darwin uses SjLj. Other targets might need more checks.
738   bool isTargetEHABICompatible() const {
739     return (TargetTriple.getEnvironment() == Triple::EABI ||
740             TargetTriple.getEnvironment() == Triple::GNUEABI ||
741             TargetTriple.getEnvironment() == Triple::MuslEABI ||
742             TargetTriple.getEnvironment() == Triple::EABIHF ||
743             TargetTriple.getEnvironment() == Triple::GNUEABIHF ||
744             TargetTriple.getEnvironment() == Triple::MuslEABIHF ||
745             isTargetAndroid()) &&
746            !isTargetDarwin() && !isTargetWindows();
747   }
748 
749   bool isTargetHardFloat() const;
750 
751   bool isTargetAndroid() const { return TargetTriple.isAndroid(); }
752 
753   bool isXRaySupported() const override;
754 
755   bool isAPCS_ABI() const;
756   bool isAAPCS_ABI() const;
757   bool isAAPCS16_ABI() const;
758 
759   bool isROPI() const;
760   bool isRWPI() const;
761 
762   bool useMachineScheduler() const { return UseMISched; }
763   bool disablePostRAScheduler() const { return DisablePostRAScheduler; }
764   bool useSoftFloat() const { return UseSoftFloat; }
765   bool isThumb() const { return InThumbMode; }
766   bool hasMinSize() const { return OptMinSize; }
767   bool isThumb1Only() const { return InThumbMode && !HasThumb2; }
768   bool isThumb2() const { return InThumbMode && HasThumb2; }
769   bool hasThumb2() const { return HasThumb2; }
770   bool isMClass() const { return ARMProcClass == MClass; }
771   bool isRClass() const { return ARMProcClass == RClass; }
772   bool isAClass() const { return ARMProcClass == AClass; }
773   bool isReadTPHard() const { return ReadTPHard; }
774 
775   bool isR9Reserved() const {
776     return isTargetMachO() ? (ReserveR9 || !HasV6Ops) : ReserveR9;
777   }
778 
779   bool useR7AsFramePointer() const {
780     return isTargetDarwin() || (!isTargetWindows() && isThumb());
781   }
782 
783   /// Returns true if the frame setup is split into two separate pushes (first
784   /// r0-r7,lr then r8-r11), principally so that the frame pointer is adjacent
785   /// to lr. This is always required on Thumb1-only targets, as the push and
786   /// pop instructions can't access the high registers.
787   bool splitFramePushPop(const MachineFunction &MF) const {
788     return (useR7AsFramePointer() &&
789             MF.getTarget().Options.DisableFramePointerElim(MF)) ||
790            isThumb1Only();
791   }
792 
793   bool useStride4VFPs() const;
794 
795   bool useMovt() const;
796 
797   bool supportsTailCall() const { return SupportsTailCall; }
798 
799   bool allowsUnalignedMem() const { return !StrictAlign; }
800 
801   bool restrictIT() const { return RestrictIT; }
802 
803   const std::string & getCPUString() const { return CPUString; }
804 
805   bool isLittle() const { return IsLittle; }
806 
807   unsigned getMispredictionPenalty() const;
808 
809   /// Returns true if machine scheduler should be enabled.
810   bool enableMachineScheduler() const override;
811 
812   /// True for some subtargets at > -O0.
813   bool enablePostRAScheduler() const override;
814 
815   /// True for some subtargets at > -O0.
816   bool enablePostRAMachineScheduler() const override;
817 
818   /// Check whether this subtarget wants to use subregister liveness.
819   bool enableSubRegLiveness() const override;
820 
821   /// Enable use of alias analysis during code generation (during MI
822   /// scheduling, DAGCombine, etc.).
823   bool useAA() const override { return true; }
824 
825   // enableAtomicExpand- True if we need to expand our atomics.
826   bool enableAtomicExpand() const override;
827 
828   /// getInstrItins - Return the instruction itineraries based on subtarget
829   /// selection.
830   const InstrItineraryData *getInstrItineraryData() const override {
831     return &InstrItins;
832   }
833 
834   /// getStackAlignment - Returns the minimum alignment known to hold of the
835   /// stack frame on entry to the function and which must be maintained by every
836   /// function for this subtarget.
837   Align getStackAlignment() const { return stackAlignment; }
838 
839   unsigned getMaxInterleaveFactor() const { return MaxInterleaveFactor; }
840 
841   unsigned getPartialUpdateClearance() const { return PartialUpdateClearance; }
842 
843   ARMLdStMultipleTiming getLdStMultipleTiming() const {
844     return LdStMultipleTiming;
845   }
846 
847   int getPreISelOperandLatencyAdjustment() const {
848     return PreISelOperandLatencyAdjustment;
849   }
850 
851   /// True if the GV will be accessed via an indirect symbol.
852   bool isGVIndirectSymbol(const GlobalValue *GV) const;
853 
854   /// Returns the constant pool modifier needed to access the GV.
855   bool isGVInGOT(const GlobalValue *GV) const;
856 
857   /// True if fast-isel is used.
858   bool useFastISel() const;
859 
860   /// Returns the correct return opcode for the current feature set.
861   /// Use BX if available to allow mixing thumb/arm code, but fall back
862   /// to plain mov pc,lr on ARMv4.
863   unsigned getReturnOpcode() const {
864     if (isThumb())
865       return ARM::tBX_RET;
866     if (hasV4TOps())
867       return ARM::BX_RET;
868     return ARM::MOVPCLR;
869   }
870 
871   /// Allow movt+movw for PIC global address calculation.
872   /// ELF does not have GOT relocations for movt+movw.
873   /// ROPI does not use GOT.
874   bool allowPositionIndependentMovt() const {
875     return isROPI() || !isTargetELF();
876   }
877 
878   unsigned getPrefLoopLogAlignment() const { return PrefLoopLogAlignment; }
879 
880   unsigned getMVEVectorCostFactor() const { return MVEVectorCostFactor; }
881 
882   bool ignoreCSRForAllocationOrder(const MachineFunction &MF,
883                                    unsigned PhysReg) const override;
884   unsigned getGPRAllocationOrder(const MachineFunction &MF) const;
885 };
886 
887 } // end namespace llvm
888 
889 #endif  // LLVM_LIB_TARGET_ARM_ARMSUBTARGET_H
890