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