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