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