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