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