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