1235633Sdim//===-- ARMSubtarget.h - Define Subtarget for the ARM ----------*- C++ -*--===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10224145Sdim// This file declares the ARM specific subclass of TargetSubtargetInfo. 11193323Sed// 12193323Sed//===----------------------------------------------------------------------===// 13193323Sed 14193323Sed#ifndef ARMSUBTARGET_H 15193323Sed#define ARMSUBTARGET_H 16193323Sed 17224145Sdim#include "MCTargetDesc/ARMMCTargetDesc.h" 18252723Sdim#include "llvm/ADT/Triple.h" 19252723Sdim#include "llvm/MC/MCInstrItineraries.h" 20224145Sdim#include "llvm/Target/TargetSubtargetInfo.h" 21193323Sed#include <string> 22193323Sed 23224145Sdim#define GET_SUBTARGETINFO_HEADER 24224145Sdim#include "ARMGenSubtargetInfo.inc" 25224145Sdim 26193323Sednamespace llvm { 27198090Srdivackyclass GlobalValue; 28224145Sdimclass StringRef; 29252723Sdimclass TargetOptions; 30193323Sed 31224145Sdimclass ARMSubtarget : public ARMGenSubtargetInfo { 32193323Sedprotected: 33218893Sdim enum ARMProcFamilyEnum { 34263509Sdim Others, CortexA5, CortexA8, CortexA9, CortexA15, CortexR5, Swift, CortexA53, CortexA57 35218893Sdim }; 36263509Sdim enum ARMProcClassEnum { 37263509Sdim None, AClass, RClass, MClass 38263509Sdim }; 39218893Sdim 40218893Sdim /// ARMProcFamily - ARM processor family: Cortex-A8, Cortex-A9, and others. 41218893Sdim ARMProcFamilyEnum ARMProcFamily; 42218893Sdim 43263509Sdim /// ARMProcClass - ARM processor class: None, AClass, RClass or MClass. 44263509Sdim ARMProcClassEnum ARMProcClass; 45263509Sdim 46263509Sdim /// HasV4TOps, HasV5TOps, HasV5TEOps, 47263509Sdim /// HasV6Ops, HasV6MOps, HasV6T2Ops, HasV7Ops, HasV8Ops - 48224145Sdim /// Specify whether target support specific ARM ISA variants. 49224145Sdim bool HasV4TOps; 50224145Sdim bool HasV5TOps; 51224145Sdim bool HasV5TEOps; 52224145Sdim bool HasV6Ops; 53263509Sdim bool HasV6MOps; 54224145Sdim bool HasV6T2Ops; 55224145Sdim bool HasV7Ops; 56263509Sdim bool HasV8Ops; 57193323Sed 58263509Sdim /// HasVFPv2, HasVFPv3, HasVFPv4, HasFPARMv8, HasNEON - Specify what 59235633Sdim /// floating point ISAs are supported. 60224145Sdim bool HasVFPv2; 61224145Sdim bool HasVFPv3; 62235633Sdim bool HasVFPv4; 63263509Sdim bool HasFPARMv8; 64224145Sdim bool HasNEON; 65224145Sdim 66198090Srdivacky /// UseNEONForSinglePrecisionFP - if the NEONFP attribute has been 67198090Srdivacky /// specified. Use the method useNEONForSinglePrecisionFP() to 68198090Srdivacky /// determine if NEON should actually be used. 69198090Srdivacky bool UseNEONForSinglePrecisionFP; 70198090Srdivacky 71245431Sdim /// UseMulOps - True if non-microcoded fused integer multiply-add and 72245431Sdim /// multiply-subtract instructions should be used. 73245431Sdim bool UseMulOps; 74245431Sdim 75218893Sdim /// SlowFPVMLx - If the VFP2 / NEON instructions are available, indicates 76218893Sdim /// whether the FP VML[AS] instructions are slow (if so, don't use them). 77218893Sdim bool SlowFPVMLx; 78206083Srdivacky 79221345Sdim /// HasVMLxForwarding - If true, NEON has special multiplier accumulator 80221345Sdim /// forwarding to allow mul + mla being issued back to back. 81221345Sdim bool HasVMLxForwarding; 82221345Sdim 83210299Sed /// SlowFPBrcc - True if floating point compare + branch is slow. 84210299Sed bool SlowFPBrcc; 85210299Sed 86224145Sdim /// InThumbMode - True if compiling for Thumb, false for ARM. 87224145Sdim bool InThumbMode; 88193323Sed 89224145Sdim /// HasThumb2 - True if Thumb2 instructions are supported. 90224145Sdim bool HasThumb2; 91193323Sed 92212904Sdim /// NoARM - True if subtarget does not support ARM mode execution. 93212904Sdim bool NoARM; 94212904Sdim 95198090Srdivacky /// PostRAScheduler - True if using post-register-allocation scheduler. 96198090Srdivacky bool PostRAScheduler; 97198090Srdivacky 98193323Sed /// IsR9Reserved - True if R9 is a not available as general purpose register. 99193323Sed bool IsR9Reserved; 100193323Sed 101199989Srdivacky /// UseMovt - True if MOVT / MOVW pairs are used for materialization of 32-bit 102199989Srdivacky /// imms (including global addresses). 103199989Srdivacky bool UseMovt; 104199989Srdivacky 105226890Sdim /// SupportsTailCall - True if the OS supports tail call. The dynamic linker 106226890Sdim /// must be able to synthesize call stubs for interworking between ARM and 107226890Sdim /// Thumb. 108226890Sdim bool SupportsTailCall; 109226890Sdim 110205218Srdivacky /// HasFP16 - True if subtarget supports half-precision FP (We support VFP+HF 111205218Srdivacky /// only so far) 112205218Srdivacky bool HasFP16; 113205218Srdivacky 114218893Sdim /// HasD16 - True if subtarget is limited to 16 double precision 115218893Sdim /// FP registers for VFPv3. 116218893Sdim bool HasD16; 117218893Sdim 118208599Srdivacky /// HasHardwareDivide - True if subtarget supports [su]div 119208599Srdivacky bool HasHardwareDivide; 120208599Srdivacky 121245431Sdim /// HasHardwareDivideInARM - True if subtarget supports [su]div in ARM mode 122245431Sdim bool HasHardwareDivideInARM; 123245431Sdim 124208599Srdivacky /// HasT2ExtractPack - True if subtarget supports thumb2 extract/pack 125208599Srdivacky /// instructions. 126208599Srdivacky bool HasT2ExtractPack; 127208599Srdivacky 128212904Sdim /// HasDataBarrier - True if the subtarget supports DMB / DSB data barrier 129212904Sdim /// instructions. 130212904Sdim bool HasDataBarrier; 131212904Sdim 132212904Sdim /// Pref32BitThumb - If true, codegen would prefer 32-bit Thumb instructions 133212904Sdim /// over 16-bit ones. 134212904Sdim bool Pref32BitThumb; 135212904Sdim 136221345Sdim /// AvoidCPSRPartialUpdate - If true, codegen would avoid using instructions 137221345Sdim /// that partially update CPSR and add false dependency on the previous 138221345Sdim /// CPSR setting instruction. 139221345Sdim bool AvoidCPSRPartialUpdate; 140221345Sdim 141252723Sdim /// AvoidMOVsShifterOperand - If true, codegen should avoid using flag setting 142252723Sdim /// movs with shifter operand (i.e. asr, lsl, lsr). 143252723Sdim bool AvoidMOVsShifterOperand; 144252723Sdim 145235633Sdim /// HasRAS - Some processors perform return stack prediction. CodeGen should 146235633Sdim /// avoid issue "normal" call instructions to callees which do not return. 147235633Sdim bool HasRAS; 148235633Sdim 149218893Sdim /// HasMPExtension - True if the subtarget supports Multiprocessing 150218893Sdim /// extension (ARMv7 only). 151218893Sdim bool HasMPExtension; 152218893Sdim 153263509Sdim /// HasVirtualization - True if the subtarget supports the Virtualization 154263509Sdim /// extension. 155263509Sdim bool HasVirtualization; 156263509Sdim 157212904Sdim /// FPOnlySP - If true, the floating point unit only supports single 158212904Sdim /// precision. 159212904Sdim bool FPOnlySP; 160212904Sdim 161263509Sdim /// If true, the processor supports the Performance Monitor Extensions. These 162263509Sdim /// include a generic cycle-counter as well as more fine-grained (often 163263509Sdim /// implementation-specific) events. 164263509Sdim bool HasPerfMon; 165263509Sdim 166252723Sdim /// HasTrustZone - if true, processor supports TrustZone security extensions 167252723Sdim bool HasTrustZone; 168252723Sdim 169263509Sdim /// HasCrypto - if true, processor supports Cryptography extensions 170263509Sdim bool HasCrypto; 171263509Sdim 172263509Sdim /// HasCRC - if true, processor supports CRC instructions 173263509Sdim bool HasCRC; 174263509Sdim 175218893Sdim /// AllowsUnalignedMem - If true, the subtarget allows unaligned memory 176218893Sdim /// accesses for some types. For details, see 177218893Sdim /// ARMTargetLowering::allowsUnalignedMemoryAccesses(). 178218893Sdim bool AllowsUnalignedMem; 179218893Sdim 180263509Sdim /// RestrictIT - If true, the subtarget disallows generation of deprecated IT 181263509Sdim /// blocks to conform to ARMv8 rule. 182263509Sdim bool RestrictIT; 183263509Sdim 184224145Sdim /// Thumb2DSP - If true, the subtarget supports the v7 DSP (saturating arith 185224145Sdim /// and such) instructions in Thumb2 code. 186224145Sdim bool Thumb2DSP; 187224145Sdim 188252723Sdim /// NaCl TRAP instruction is generated instead of the regular TRAP. 189252723Sdim bool UseNaClTrap; 190252723Sdim 191252723Sdim /// Target machine allowed unsafe FP math (such as use of NEON fp) 192252723Sdim bool UnsafeFPMath; 193252723Sdim 194193323Sed /// stackAlignment - The minimum alignment known to hold of the stack frame on 195193323Sed /// entry to the function and which must be maintained by every function. 196193323Sed unsigned stackAlignment; 197193323Sed 198193323Sed /// CPUString - String name of used CPU. 199193323Sed std::string CPUString; 200193323Sed 201218893Sdim /// TargetTriple - What processor and OS we're targeting. 202218893Sdim Triple TargetTriple; 203218893Sdim 204245431Sdim /// SchedModel - Processor specific instruction costs. 205245431Sdim const MCSchedModel *SchedModel; 206245431Sdim 207194612Sed /// Selected instruction itineraries (one entry per itinerary class.) 208194612Sed InstrItineraryData InstrItins; 209198090Srdivacky 210252723Sdim /// Options passed via command line that could influence the target 211252723Sdim const TargetOptions &Options; 212252723Sdim 213193323Sed public: 214193323Sed enum { 215193323Sed ARM_ABI_APCS, 216193323Sed ARM_ABI_AAPCS // ARM EABI 217193323Sed } TargetABI; 218193323Sed 219193323Sed /// This constructor initializes the data members to match that 220198090Srdivacky /// of the specified triple. 221193323Sed /// 222224145Sdim ARMSubtarget(const std::string &TT, const std::string &CPU, 223252723Sdim const std::string &FS, const TargetOptions &Options); 224193323Sed 225193323Sed /// getMaxInlineSizeThreshold - Returns the maximum memset / memcpy size 226193323Sed /// that still makes it profitable to inline the call. 227193323Sed unsigned getMaxInlineSizeThreshold() const { 228205218Srdivacky // FIXME: For now, we don't lower memcpy's to loads / stores for Thumb1. 229205218Srdivacky // Change this once Thumb1 ldmia / stmia support is added. 230205218Srdivacky return isThumb1Only() ? 0 : 64; 231193323Sed } 232193323Sed /// ParseSubtargetFeatures - Parses features string setting specified 233193323Sed /// subtarget options. Definition of function is auto generated by tblgen. 234224145Sdim void ParseSubtargetFeatures(StringRef CPU, StringRef FS); 235193323Sed 236252723Sdim /// \brief Reset the features for the ARM target. 237252723Sdim virtual void resetSubtargetFeatures(const MachineFunction *MF); 238252723Sdimprivate: 239252723Sdim void initializeEnvironment(); 240252723Sdim void resetSubtargetFeatures(StringRef CPU, StringRef FS); 241252723Sdimpublic: 242218893Sdim void computeIssueWidth(); 243218893Sdim 244224145Sdim bool hasV4TOps() const { return HasV4TOps; } 245224145Sdim bool hasV5TOps() const { return HasV5TOps; } 246224145Sdim bool hasV5TEOps() const { return HasV5TEOps; } 247224145Sdim bool hasV6Ops() const { return HasV6Ops; } 248263509Sdim bool hasV6MOps() const { return HasV6MOps; } 249224145Sdim bool hasV6T2Ops() const { return HasV6T2Ops; } 250224145Sdim bool hasV7Ops() const { return HasV7Ops; } 251263509Sdim bool hasV8Ops() const { return HasV8Ops; } 252193323Sed 253252723Sdim bool isCortexA5() const { return ARMProcFamily == CortexA5; } 254218893Sdim bool isCortexA8() const { return ARMProcFamily == CortexA8; } 255218893Sdim bool isCortexA9() const { return ARMProcFamily == CortexA9; } 256245431Sdim bool isCortexA15() const { return ARMProcFamily == CortexA15; } 257245431Sdim bool isSwift() const { return ARMProcFamily == Swift; } 258235633Sdim bool isCortexM3() const { return CPUString == "cortex-m3"; } 259245431Sdim bool isLikeA9() const { return isCortexA9() || isCortexA15(); } 260252723Sdim bool isCortexR5() const { return ARMProcFamily == CortexR5; } 261218893Sdim 262212904Sdim bool hasARMOps() const { return !NoARM; } 263212904Sdim 264224145Sdim bool hasVFP2() const { return HasVFPv2; } 265224145Sdim bool hasVFP3() const { return HasVFPv3; } 266235633Sdim bool hasVFP4() const { return HasVFPv4; } 267263509Sdim bool hasFPARMv8() const { return HasFPARMv8; } 268224145Sdim bool hasNEON() const { return HasNEON; } 269263509Sdim bool hasCrypto() const { return HasCrypto; } 270263509Sdim bool hasCRC() const { return HasCRC; } 271263509Sdim bool hasVirtualization() const { return HasVirtualization; } 272198090Srdivacky bool useNEONForSinglePrecisionFP() const { 273198090Srdivacky return hasNEON() && UseNEONForSinglePrecisionFP; } 274224145Sdim 275208599Srdivacky bool hasDivide() const { return HasHardwareDivide; } 276245431Sdim bool hasDivideInARMMode() const { return HasHardwareDivideInARM; } 277208599Srdivacky bool hasT2ExtractPack() const { return HasT2ExtractPack; } 278212904Sdim bool hasDataBarrier() const { return HasDataBarrier; } 279263509Sdim bool hasAnyDataBarrier() const { 280263509Sdim return HasDataBarrier || (hasV6Ops() && !isThumb()); 281263509Sdim } 282245431Sdim bool useMulOps() const { return UseMulOps; } 283218893Sdim bool useFPVMLx() const { return !SlowFPVMLx; } 284221345Sdim bool hasVMLxForwarding() const { return HasVMLxForwarding; } 285210299Sed bool isFPBrccSlow() const { return SlowFPBrcc; } 286212904Sdim bool isFPOnlySP() const { return FPOnlySP; } 287263509Sdim bool hasPerfMon() const { return HasPerfMon; } 288252723Sdim bool hasTrustZone() const { return HasTrustZone; } 289212904Sdim bool prefers32BitThumb() const { return Pref32BitThumb; } 290221345Sdim bool avoidCPSRPartialUpdate() const { return AvoidCPSRPartialUpdate; } 291252723Sdim bool avoidMOVsShifterOperand() const { return AvoidMOVsShifterOperand; } 292235633Sdim bool hasRAS() const { return HasRAS; } 293218893Sdim bool hasMPExtension() const { return HasMPExtension; } 294224145Sdim bool hasThumb2DSP() const { return Thumb2DSP; } 295252723Sdim bool useNaClTrap() const { return UseNaClTrap; } 296193323Sed 297205218Srdivacky bool hasFP16() const { return HasFP16; } 298218893Sdim bool hasD16() const { return HasD16; } 299205218Srdivacky 300221345Sdim const Triple &getTargetTriple() const { return TargetTriple; } 301221345Sdim 302263509Sdim bool isTargetIOS() const { return TargetTriple.isiOS(); } 303221345Sdim bool isTargetDarwin() const { return TargetTriple.isOSDarwin(); } 304263509Sdim bool isTargetNaCl() const { return TargetTriple.isOSNaCl(); } 305263509Sdim bool isTargetLinux() const { return TargetTriple.isOSLinux(); } 306263509Sdim bool isTargetELF() const { return !isTargetDarwin(); } 307263509Sdim // ARM EABI is the bare-metal EABI described in ARM ABI documents and 308263509Sdim // can be accessed via -target arm-none-eabi. This is NOT GNUEABI. 309263509Sdim // FIXME: Add a flag for bare-metal for that target and set Triple::EABI 310263509Sdim // even for GNUEABI, so we can make a distinction here and still conform to 311263509Sdim // the EABI on GNU (and Android) mode. This requires change in Clang, too. 312263509Sdim bool isTargetAEABI() const { 313263509Sdim return TargetTriple.getEnvironment() == Triple::EABI; 314226890Sdim } 315193323Sed 316193323Sed bool isAPCS_ABI() const { return TargetABI == ARM_ABI_APCS; } 317193323Sed bool isAAPCS_ABI() const { return TargetABI == ARM_ABI_AAPCS; } 318193323Sed 319224145Sdim bool isThumb() const { return InThumbMode; } 320224145Sdim bool isThumb1Only() const { return InThumbMode && !HasThumb2; } 321224145Sdim bool isThumb2() const { return InThumbMode && HasThumb2; } 322224145Sdim bool hasThumb2() const { return HasThumb2; } 323263509Sdim bool isMClass() const { return ARMProcClass == MClass; } 324263509Sdim bool isRClass() const { return ARMProcClass == RClass; } 325263509Sdim bool isAClass() const { return ARMProcClass == AClass; } 326193323Sed 327193323Sed bool isR9Reserved() const { return IsR9Reserved; } 328193323Sed 329199989Srdivacky bool useMovt() const { return UseMovt && hasV6T2Ops(); } 330226890Sdim bool supportsTailCall() const { return SupportsTailCall; } 331199989Srdivacky 332218893Sdim bool allowsUnalignedMem() const { return AllowsUnalignedMem; } 333218893Sdim 334263509Sdim bool restrictIT() const { return RestrictIT; } 335263509Sdim 336193323Sed const std::string & getCPUString() const { return CPUString; } 337199989Srdivacky 338218893Sdim unsigned getMispredictionPenalty() const; 339263509Sdim 340263509Sdim /// This function returns true if the target has sincos() routine in its 341263509Sdim /// compiler runtime or math libraries. 342263509Sdim bool hasSinCos() const; 343218893Sdim 344199481Srdivacky /// enablePostRAScheduler - True at 'More' optimization. 345198396Srdivacky bool enablePostRAScheduler(CodeGenOpt::Level OptLevel, 346224145Sdim TargetSubtargetInfo::AntiDepBreakMode& Mode, 347199481Srdivacky RegClassVector& CriticalPathRCs) const; 348193323Sed 349198090Srdivacky /// getInstrItins - Return the instruction itineraies based on subtarget 350194612Sed /// selection. 351194612Sed const InstrItineraryData &getInstrItineraryData() const { return InstrItins; } 352194612Sed 353193323Sed /// getStackAlignment - Returns the minimum alignment known to hold of the 354193323Sed /// stack frame on entry to the function and which must be maintained by every 355193323Sed /// function for this subtarget. 356193323Sed unsigned getStackAlignment() const { return stackAlignment; } 357198090Srdivacky 358198090Srdivacky /// GVIsIndirectSymbol - true if the GV will be accessed via an indirect 359198090Srdivacky /// symbol. 360207618Srdivacky bool GVIsIndirectSymbol(const GlobalValue *GV, Reloc::Model RelocM) const; 361193323Sed}; 362193323Sed} // End llvm namespace 363193323Sed 364193323Sed#endif // ARMSUBTARGET_H 365