LCOV - code coverage report
Current view: top level - lib/Target/ARM - ARMSubtarget.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 51 51 100.0 %
Date: 2018-07-13 00:08:38 Functions: 12 12 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13