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
39namespace llvm {
40
41class ARMBaseTargetMachine;
42class GlobalValue;
43class StringRef;
44
45class ARMSubtarget : public ARMGenSubtargetInfo {
46protected:
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
123public:
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
138protected:
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
513public:
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.
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
535  const ARMSelectionDAGInfo *getSelectionDAGInfo() const override {
536    return &TSInfo;
537  }
538
539  const ARMBaseInstrInfo *getInstrInfo() const override {
540    return InstrInfo.get();
541  }
542
543  const ARMTargetLowering *getTargetLowering() const override {
544    return &TLInfo;
545  }
546
547  const ARMFrameLowering *getFrameLowering() const override {
548    return FrameLowering.get();
549  }
550
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
560private:
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 = {};
579public:
580  void computeIssueWidth();
581
582  bool hasV4TOps()  const { return HasV4TOps;  }
583  bool hasV5TOps()  const { return HasV5TOps;  }
584  bool hasV5TEOps() const { return HasV5TEOps; }
585  bool hasV6Ops()   const { return HasV6Ops;   }
586  bool hasV6MOps()  const { return HasV6MOps;  }
587  bool hasV6KOps()  const { return HasV6KOps; }
588  bool hasV6T2Ops() const { return HasV6T2Ops; }
589  bool hasV7Ops()   const { return HasV7Ops;  }
590  bool hasV8Ops()   const { return HasV8Ops;  }
591  bool hasV8_1aOps() const { return HasV8_1aOps; }
592  bool hasV8_2aOps() const { return HasV8_2aOps; }
593  bool hasV8_3aOps() const { return HasV8_3aOps; }
594  bool hasV8_4aOps() const { return HasV8_4aOps; }
595  bool hasV8_5aOps() const { return HasV8_5aOps; }
596  bool hasV8_6aOps() const { return HasV8_6aOps; }
597  bool hasV8MBaselineOps() const { return HasV8MBaselineOps; }
598  bool hasV8MMainlineOps() const { return HasV8MMainlineOps; }
599  bool hasV8_1MMainlineOps() const { return HasV8_1MMainlineOps; }
600  bool hasMVEIntegerOps() const { return HasMVEIntegerOps; }
601  bool hasMVEFloatOps() const { return HasMVEFloatOps; }
602  bool hasCDEOps() const { return HasCDEOps; }
603  bool hasFPRegs() const { return HasFPRegs; }
604  bool hasFPRegs16() const { return HasFPRegs16; }
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.
610  bool isCortexA5() const { return ARMProcFamily == CortexA5; }
611  bool isCortexA7() const { return ARMProcFamily == CortexA7; }
612  bool isCortexA8() const { return ARMProcFamily == CortexA8; }
613  bool isCortexA9() const { return ARMProcFamily == CortexA9; }
614  bool isCortexA15() const { return ARMProcFamily == CortexA15; }
615  bool isSwift()    const { return ARMProcFamily == Swift; }
616  bool isCortexM3() const { return ARMProcFamily == CortexM3; }
617  bool isLikeA9() const { return isCortexA9() || isCortexA15() || isKrait(); }
618  bool isCortexR5() const { return ARMProcFamily == CortexR5; }
619  bool isKrait() const { return ARMProcFamily == Krait; }
620  /// @}
621
622  bool hasARMOps() const { return !NoARM; }
623
624  bool hasVFP2Base() const { return HasVFPv2SP; }
625  bool hasVFP3Base() const { return HasVFPv3D16SP; }
626  bool hasVFP4Base() const { return HasVFPv4D16SP; }
627  bool hasFPARMv8Base() const { return HasFPARMv8D16SP; }
628  bool hasNEON() const { return HasNEON;  }
629  bool hasSHA2() const { return HasSHA2; }
630  bool hasAES() const { return HasAES; }
631  bool hasCrypto() const { return HasCrypto; }
632  bool hasDotProd() const { return HasDotProd; }
633  bool hasCRC() const { return HasCRC; }
634  bool hasRAS() const { return HasRAS; }
635  bool hasLOB() const { return HasLOB; }
636  bool hasVirtualization() const { return HasVirtualization; }
637
638  bool useNEONForSinglePrecisionFP() const {
639    return hasNEON() && UseNEONForSinglePrecisionFP;
640  }
641
642  bool hasDivideInThumbMode() const { return HasHardwareDivideInThumb; }
643  bool hasDivideInARMMode() const { return HasHardwareDivideInARM; }
644  bool hasDataBarrier() const { return HasDataBarrier; }
645  bool hasFullDataBarrier() const { return HasFullDataBarrier; }
646  bool hasV7Clrex() const { return HasV7Clrex; }
647  bool hasAcquireRelease() const { return HasAcquireRelease; }
648
649  bool hasAnyDataBarrier() const {
650    return HasDataBarrier || (hasV6Ops() && !isThumb());
651  }
652
653  bool useMulOps() const { return UseMulOps; }
654  bool useFPVMLx() const { return !SlowFPVMLx; }
655  bool useFPVFMx() const {
656    return !isTargetDarwin() && hasVFP4Base() && !SlowFPVFMx;
657  }
658  bool useFPVFMx16() const { return useFPVFMx() && hasFullFP16(); }
659  bool useFPVFMx64() const { return useFPVFMx() && hasFP64(); }
660  bool hasVMLxForwarding() const { return HasVMLxForwarding; }
661  bool isFPBrccSlow() const { return SlowFPBrcc; }
662  bool hasFP64() const { return HasFP64; }
663  bool hasPerfMon() const { return HasPerfMon; }
664  bool hasTrustZone() const { return HasTrustZone; }
665  bool has8MSecExt() const { return Has8MSecExt; }
666  bool hasZeroCycleZeroing() const { return HasZeroCycleZeroing; }
667  bool hasFPAO() const { return HasFPAO; }
668  bool isProfitableToUnpredicate() const { return IsProfitableToUnpredicate; }
669  bool hasSlowVGETLNi32() const { return HasSlowVGETLNi32; }
670  bool hasSlowVDUP32() const { return HasSlowVDUP32; }
671  bool preferVMOVSR() const { return PreferVMOVSR; }
672  bool preferISHSTBarriers() const { return PreferISHST; }
673  bool expandMLx() const { return ExpandMLx; }
674  bool hasVMLxHazards() const { return HasVMLxHazards; }
675  bool hasSlowOddRegister() const { return SlowOddRegister; }
676  bool hasSlowLoadDSubregister() const { return SlowLoadDSubregister; }
677  bool useWideStrideVFP() const { return UseWideStrideVFP; }
678  bool hasMuxedUnits() const { return HasMuxedUnits; }
679  bool dontWidenVMOVS() const { return DontWidenVMOVS; }
680  bool useSplatVFPToNeon() const { return SplatVFPToNeon; }
681  bool useNEONForFPMovs() const { return UseNEONForFPMovs; }
682  bool checkVLDnAccessAlignment() const { return CheckVLDnAlign; }
683  bool nonpipelinedVFP() const { return NonpipelinedVFP; }
684  bool prefers32BitThumb() const { return Pref32BitThumb; }
685  bool avoidCPSRPartialUpdate() const { return AvoidCPSRPartialUpdate; }
686  bool cheapPredicableCPSRDef() const { return CheapPredicableCPSRDef; }
687  bool avoidMOVsShifterOperand() const { return AvoidMOVsShifterOperand; }
688  bool hasRetAddrStack() const { return HasRetAddrStack; }
689  bool hasBranchPredictor() const { return HasBranchPredictor; }
690  bool hasMPExtension() const { return HasMPExtension; }
691  bool hasDSP() const { return HasDSP; }
692  bool useNaClTrap() const { return UseNaClTrap; }
693  bool useSjLjEH() const { return UseSjLjEH; }
694  bool hasSB() const { return HasSB; }
695  bool genLongCalls() const { return GenLongCalls; }
696  bool genExecuteOnly() const { return GenExecuteOnly; }
697  bool hasBaseDSP() const {
698    if (isThumb())
699      return hasDSP();
700    else
701      return hasV5TEOps();
702  }
703
704  bool hasFP16() const { return HasFP16; }
705  bool hasD32() const { return HasD32; }
706  bool hasFullFP16() const { return HasFullFP16; }
707  bool hasFP16FML() const { return HasFP16FML; }
708  bool hasBF16() const { return HasBF16; }
709
710  bool hasFuseAES() const { return HasFuseAES; }
711  bool hasFuseLiterals() const { return HasFuseLiterals; }
712  /// Return true if the CPU supports any kind of instruction fusion.
713  bool hasFusion() const { return hasFuseAES() || hasFuseLiterals(); }
714
715  bool hasMatMulInt8() const { return HasMatMulInt8; }
716
717  const Triple &getTargetTriple() const { return TargetTriple; }
718
719  bool isTargetDarwin() const { return TargetTriple.isOSDarwin(); }
720  bool isTargetIOS() const { return TargetTriple.isiOS(); }
721  bool isTargetWatchOS() const { return TargetTriple.isWatchOS(); }
722  bool isTargetWatchABI() const { return TargetTriple.isWatchABI(); }
723  bool isTargetLinux() const { return TargetTriple.isOSLinux(); }
724  bool isTargetNaCl() const { return TargetTriple.isOSNaCl(); }
725  bool isTargetNetBSD() const { return TargetTriple.isOSNetBSD(); }
726  bool isTargetWindows() const { return TargetTriple.isOSWindows(); }
727
728  bool isTargetCOFF() const { return TargetTriple.isOSBinFormatCOFF(); }
729  bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }
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.
739  bool isTargetAEABI() const {
740    return (TargetTriple.getEnvironment() == Triple::EABI ||
741            TargetTriple.getEnvironment() == Triple::EABIHF) &&
742           !isTargetDarwin() && !isTargetWindows();
743  }
744  bool isTargetGNUAEABI() const {
745    return (TargetTriple.getEnvironment() == Triple::GNUEABI ||
746            TargetTriple.getEnvironment() == Triple::GNUEABIHF) &&
747           !isTargetDarwin() && !isTargetWindows();
748  }
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.
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
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
781  bool useMachineScheduler() const { return UseMISched; }
782  bool disablePostRAScheduler() const { return DisablePostRAScheduler; }
783  bool useSoftFloat() const { return UseSoftFloat; }
784  bool isThumb() const { return InThumbMode; }
785  bool hasMinSize() const { return OptMinSize; }
786  bool isThumb1Only() const { return InThumbMode && !HasThumb2; }
787  bool isThumb2() const { return InThumbMode && HasThumb2; }
788  bool hasThumb2() const { return HasThumb2; }
789  bool isMClass() const { return ARMProcClass == MClass; }
790  bool isRClass() const { return ARMProcClass == RClass; }
791  bool isAClass() const { return ARMProcClass == AClass; }
792  bool isReadTPHard() const { return ReadTPHard; }
793
794  bool isR9Reserved() const {
795    return isTargetMachO() ? (ReserveR9 || !HasV6Ops) : ReserveR9;
796  }
797
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.
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
816  bool supportsTailCall() const { return SupportsTailCall; }
817
818  bool allowsUnalignedMem() const { return !StrictAlign; }
819
820  bool restrictIT() const { return RestrictIT; }
821
822  const std::string & getCPUString() const { return CPUString; }
823
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.).
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.
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.
856  Align getStackAlignment() const { return stackAlignment; }
857
858  unsigned getMaxInterleaveFactor() const { return MaxInterleaveFactor; }
859
860  unsigned getPartialUpdateClearance() const { return PartialUpdateClearance; }
861
862  ARMLdStMultipleTiming getLdStMultipleTiming() const {
863    return LdStMultipleTiming;
864  }
865
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.
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.
893  bool allowPositionIndependentMovt() const {
894    return isROPI() || !isTargetELF();
895  }
896
897  unsigned getPrefLoopLogAlignment() const { return PrefLoopLogAlignment; }
898
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