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