LLVM API Documentation
00001 //===-- ARMSubtarget.h - Define Subtarget for the ARM ----------*- C++ -*--===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file declares the ARM specific subclass of TargetSubtargetInfo. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_LIB_TARGET_ARM_ARMSUBTARGET_H 00015 #define LLVM_LIB_TARGET_ARM_ARMSUBTARGET_H 00016 00017 00018 #include "ARMFrameLowering.h" 00019 #include "ARMISelLowering.h" 00020 #include "ARMInstrInfo.h" 00021 #include "ARMSelectionDAGInfo.h" 00022 #include "ARMSubtarget.h" 00023 #include "Thumb1FrameLowering.h" 00024 #include "Thumb1InstrInfo.h" 00025 #include "Thumb2InstrInfo.h" 00026 #include "MCTargetDesc/ARMMCTargetDesc.h" 00027 #include "llvm/ADT/Triple.h" 00028 #include "llvm/IR/DataLayout.h" 00029 #include "llvm/MC/MCInstrItineraries.h" 00030 #include "llvm/Target/TargetSubtargetInfo.h" 00031 #include <string> 00032 00033 #define GET_SUBTARGETINFO_HEADER 00034 #include "ARMGenSubtargetInfo.inc" 00035 00036 namespace llvm { 00037 class GlobalValue; 00038 class StringRef; 00039 class TargetOptions; 00040 00041 class ARMSubtarget : public ARMGenSubtargetInfo { 00042 protected: 00043 enum ARMProcFamilyEnum { 00044 Others, CortexA5, CortexA7, CortexA8, CortexA9, CortexA12, CortexA15, 00045 CortexR5, Swift, CortexA53, CortexA57, Krait 00046 }; 00047 enum ARMProcClassEnum { 00048 None, AClass, RClass, MClass 00049 }; 00050 00051 /// ARMProcFamily - ARM processor family: Cortex-A8, Cortex-A9, and others. 00052 ARMProcFamilyEnum ARMProcFamily; 00053 00054 /// ARMProcClass - ARM processor class: None, AClass, RClass or MClass. 00055 ARMProcClassEnum ARMProcClass; 00056 00057 /// HasV4TOps, HasV5TOps, HasV5TEOps, 00058 /// HasV6Ops, HasV6MOps, HasV6T2Ops, HasV7Ops, HasV8Ops - 00059 /// Specify whether target support specific ARM ISA variants. 00060 bool HasV4TOps; 00061 bool HasV5TOps; 00062 bool HasV5TEOps; 00063 bool HasV6Ops; 00064 bool HasV6MOps; 00065 bool HasV6T2Ops; 00066 bool HasV7Ops; 00067 bool HasV8Ops; 00068 00069 /// HasVFPv2, HasVFPv3, HasVFPv4, HasFPARMv8, HasNEON - Specify what 00070 /// floating point ISAs are supported. 00071 bool HasVFPv2; 00072 bool HasVFPv3; 00073 bool HasVFPv4; 00074 bool HasFPARMv8; 00075 bool HasNEON; 00076 00077 /// UseNEONForSinglePrecisionFP - if the NEONFP attribute has been 00078 /// specified. Use the method useNEONForSinglePrecisionFP() to 00079 /// determine if NEON should actually be used. 00080 bool UseNEONForSinglePrecisionFP; 00081 00082 /// UseMulOps - True if non-microcoded fused integer multiply-add and 00083 /// multiply-subtract instructions should be used. 00084 bool UseMulOps; 00085 00086 /// SlowFPVMLx - If the VFP2 / NEON instructions are available, indicates 00087 /// whether the FP VML[AS] instructions are slow (if so, don't use them). 00088 bool SlowFPVMLx; 00089 00090 /// HasVMLxForwarding - If true, NEON has special multiplier accumulator 00091 /// forwarding to allow mul + mla being issued back to back. 00092 bool HasVMLxForwarding; 00093 00094 /// SlowFPBrcc - True if floating point compare + branch is slow. 00095 bool SlowFPBrcc; 00096 00097 /// InThumbMode - True if compiling for Thumb, false for ARM. 00098 bool InThumbMode; 00099 00100 /// HasThumb2 - True if Thumb2 instructions are supported. 00101 bool HasThumb2; 00102 00103 /// NoARM - True if subtarget does not support ARM mode execution. 00104 bool NoARM; 00105 00106 /// IsR9Reserved - True if R9 is a not available as general purpose register. 00107 bool IsR9Reserved; 00108 00109 /// UseMovt - True if MOVT / MOVW pairs are used for materialization of 32-bit 00110 /// imms (including global addresses). 00111 bool UseMovt; 00112 00113 /// SupportsTailCall - True if the OS supports tail call. The dynamic linker 00114 /// must be able to synthesize call stubs for interworking between ARM and 00115 /// Thumb. 00116 bool SupportsTailCall; 00117 00118 /// HasFP16 - True if subtarget supports half-precision FP (We support VFP+HF 00119 /// only so far) 00120 bool HasFP16; 00121 00122 /// HasD16 - True if subtarget is limited to 16 double precision 00123 /// FP registers for VFPv3. 00124 bool HasD16; 00125 00126 /// HasHardwareDivide - True if subtarget supports [su]div 00127 bool HasHardwareDivide; 00128 00129 /// HasHardwareDivideInARM - True if subtarget supports [su]div in ARM mode 00130 bool HasHardwareDivideInARM; 00131 00132 /// HasT2ExtractPack - True if subtarget supports thumb2 extract/pack 00133 /// instructions. 00134 bool HasT2ExtractPack; 00135 00136 /// HasDataBarrier - True if the subtarget supports DMB / DSB data barrier 00137 /// instructions. 00138 bool HasDataBarrier; 00139 00140 /// Pref32BitThumb - If true, codegen would prefer 32-bit Thumb instructions 00141 /// over 16-bit ones. 00142 bool Pref32BitThumb; 00143 00144 /// AvoidCPSRPartialUpdate - If true, codegen would avoid using instructions 00145 /// that partially update CPSR and add false dependency on the previous 00146 /// CPSR setting instruction. 00147 bool AvoidCPSRPartialUpdate; 00148 00149 /// AvoidMOVsShifterOperand - If true, codegen should avoid using flag setting 00150 /// movs with shifter operand (i.e. asr, lsl, lsr). 00151 bool AvoidMOVsShifterOperand; 00152 00153 /// HasRAS - Some processors perform return stack prediction. CodeGen should 00154 /// avoid issue "normal" call instructions to callees which do not return. 00155 bool HasRAS; 00156 00157 /// HasMPExtension - True if the subtarget supports Multiprocessing 00158 /// extension (ARMv7 only). 00159 bool HasMPExtension; 00160 00161 /// HasVirtualization - True if the subtarget supports the Virtualization 00162 /// extension. 00163 bool HasVirtualization; 00164 00165 /// FPOnlySP - If true, the floating point unit only supports single 00166 /// precision. 00167 bool FPOnlySP; 00168 00169 /// If true, the processor supports the Performance Monitor Extensions. These 00170 /// include a generic cycle-counter as well as more fine-grained (often 00171 /// implementation-specific) events. 00172 bool HasPerfMon; 00173 00174 /// HasTrustZone - if true, processor supports TrustZone security extensions 00175 bool HasTrustZone; 00176 00177 /// HasCrypto - if true, processor supports Cryptography extensions 00178 bool HasCrypto; 00179 00180 /// HasCRC - if true, processor supports CRC instructions 00181 bool HasCRC; 00182 00183 /// If true, the instructions "vmov.i32 d0, #0" and "vmov.i32 q0, #0" are 00184 /// particularly effective at zeroing a VFP register. 00185 bool HasZeroCycleZeroing; 00186 00187 /// AllowsUnalignedMem - If true, the subtarget allows unaligned memory 00188 /// accesses for some types. For details, see 00189 /// ARMTargetLowering::allowsMisalignedMemoryAccesses(). 00190 bool AllowsUnalignedMem; 00191 00192 /// RestrictIT - If true, the subtarget disallows generation of deprecated IT 00193 /// blocks to conform to ARMv8 rule. 00194 bool RestrictIT; 00195 00196 /// Thumb2DSP - If true, the subtarget supports the v7 DSP (saturating arith 00197 /// and such) instructions in Thumb2 code. 00198 bool Thumb2DSP; 00199 00200 /// NaCl TRAP instruction is generated instead of the regular TRAP. 00201 bool UseNaClTrap; 00202 00203 /// Target machine allowed unsafe FP math (such as use of NEON fp) 00204 bool UnsafeFPMath; 00205 00206 /// stackAlignment - The minimum alignment known to hold of the stack frame on 00207 /// entry to the function and which must be maintained by every function. 00208 unsigned stackAlignment; 00209 00210 /// CPUString - String name of used CPU. 00211 std::string CPUString; 00212 00213 /// IsLittle - The target is Little Endian 00214 bool IsLittle; 00215 00216 /// TargetTriple - What processor and OS we're targeting. 00217 Triple TargetTriple; 00218 00219 /// SchedModel - Processor specific instruction costs. 00220 MCSchedModel SchedModel; 00221 00222 /// Selected instruction itineraries (one entry per itinerary class.) 00223 InstrItineraryData InstrItins; 00224 00225 /// Options passed via command line that could influence the target 00226 const TargetOptions &Options; 00227 00228 public: 00229 enum { 00230 ARM_ABI_UNKNOWN, 00231 ARM_ABI_APCS, 00232 ARM_ABI_AAPCS // ARM EABI 00233 } TargetABI; 00234 00235 /// This constructor initializes the data members to match that 00236 /// of the specified triple. 00237 /// 00238 ARMSubtarget(const std::string &TT, const std::string &CPU, 00239 const std::string &FS, TargetMachine &TM, bool IsLittle, 00240 const TargetOptions &Options); 00241 00242 /// getMaxInlineSizeThreshold - Returns the maximum memset / memcpy size 00243 /// that still makes it profitable to inline the call. 00244 unsigned getMaxInlineSizeThreshold() const { 00245 return 64; 00246 } 00247 /// ParseSubtargetFeatures - Parses features string setting specified 00248 /// subtarget options. Definition of function is auto generated by tblgen. 00249 void ParseSubtargetFeatures(StringRef CPU, StringRef FS); 00250 00251 /// initializeSubtargetDependencies - Initializes using a CPU and feature string 00252 /// so that we can use initializer lists for subtarget initialization. 00253 ARMSubtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS); 00254 00255 const DataLayout *getDataLayout() const override { return &DL; } 00256 const ARMSelectionDAGInfo *getSelectionDAGInfo() const override { 00257 return &TSInfo; 00258 } 00259 const ARMBaseInstrInfo *getInstrInfo() const override { 00260 return InstrInfo.get(); 00261 } 00262 const ARMTargetLowering *getTargetLowering() const override { 00263 return &TLInfo; 00264 } 00265 const ARMFrameLowering *getFrameLowering() const override { 00266 return FrameLowering.get(); 00267 } 00268 const ARMBaseRegisterInfo *getRegisterInfo() const override { 00269 return &InstrInfo->getRegisterInfo(); 00270 } 00271 00272 private: 00273 const DataLayout DL; 00274 ARMSelectionDAGInfo TSInfo; 00275 // Either Thumb1InstrInfo or Thumb2InstrInfo. 00276 std::unique_ptr<ARMBaseInstrInfo> InstrInfo; 00277 ARMTargetLowering TLInfo; 00278 // Either Thumb1FrameLowering or ARMFrameLowering. 00279 std::unique_ptr<ARMFrameLowering> FrameLowering; 00280 00281 void initializeEnvironment(); 00282 void initSubtargetFeatures(StringRef CPU, StringRef FS); 00283 public: 00284 void computeIssueWidth(); 00285 00286 bool hasV4TOps() const { return HasV4TOps; } 00287 bool hasV5TOps() const { return HasV5TOps; } 00288 bool hasV5TEOps() const { return HasV5TEOps; } 00289 bool hasV6Ops() const { return HasV6Ops; } 00290 bool hasV6MOps() const { return HasV6MOps; } 00291 bool hasV6T2Ops() const { return HasV6T2Ops; } 00292 bool hasV7Ops() const { return HasV7Ops; } 00293 bool hasV8Ops() const { return HasV8Ops; } 00294 00295 bool isCortexA5() const { return ARMProcFamily == CortexA5; } 00296 bool isCortexA7() const { return ARMProcFamily == CortexA7; } 00297 bool isCortexA8() const { return ARMProcFamily == CortexA8; } 00298 bool isCortexA9() const { return ARMProcFamily == CortexA9; } 00299 bool isCortexA15() const { return ARMProcFamily == CortexA15; } 00300 bool isSwift() const { return ARMProcFamily == Swift; } 00301 bool isCortexM3() const { return CPUString == "cortex-m3"; } 00302 bool isLikeA9() const { return isCortexA9() || isCortexA15() || isKrait(); } 00303 bool isCortexR5() const { return ARMProcFamily == CortexR5; } 00304 bool isKrait() const { return ARMProcFamily == Krait; } 00305 00306 bool hasARMOps() const { return !NoARM; } 00307 00308 bool hasVFP2() const { return HasVFPv2; } 00309 bool hasVFP3() const { return HasVFPv3; } 00310 bool hasVFP4() const { return HasVFPv4; } 00311 bool hasFPARMv8() const { return HasFPARMv8; } 00312 bool hasNEON() const { return HasNEON; } 00313 bool hasCrypto() const { return HasCrypto; } 00314 bool hasCRC() const { return HasCRC; } 00315 bool hasVirtualization() const { return HasVirtualization; } 00316 bool useNEONForSinglePrecisionFP() const { 00317 return hasNEON() && UseNEONForSinglePrecisionFP; } 00318 00319 bool hasDivide() const { return HasHardwareDivide; } 00320 bool hasDivideInARMMode() const { return HasHardwareDivideInARM; } 00321 bool hasT2ExtractPack() const { return HasT2ExtractPack; } 00322 bool hasDataBarrier() const { return HasDataBarrier; } 00323 bool hasAnyDataBarrier() const { 00324 return HasDataBarrier || (hasV6Ops() && !isThumb()); 00325 } 00326 bool useMulOps() const { return UseMulOps; } 00327 bool useFPVMLx() const { return !SlowFPVMLx; } 00328 bool hasVMLxForwarding() const { return HasVMLxForwarding; } 00329 bool isFPBrccSlow() const { return SlowFPBrcc; } 00330 bool isFPOnlySP() const { return FPOnlySP; } 00331 bool hasPerfMon() const { return HasPerfMon; } 00332 bool hasTrustZone() const { return HasTrustZone; } 00333 bool hasZeroCycleZeroing() const { return HasZeroCycleZeroing; } 00334 bool prefers32BitThumb() const { return Pref32BitThumb; } 00335 bool avoidCPSRPartialUpdate() const { return AvoidCPSRPartialUpdate; } 00336 bool avoidMOVsShifterOperand() const { return AvoidMOVsShifterOperand; } 00337 bool hasRAS() const { return HasRAS; } 00338 bool hasMPExtension() const { return HasMPExtension; } 00339 bool hasThumb2DSP() const { return Thumb2DSP; } 00340 bool useNaClTrap() const { return UseNaClTrap; } 00341 00342 bool hasFP16() const { return HasFP16; } 00343 bool hasD16() const { return HasD16; } 00344 00345 const Triple &getTargetTriple() const { return TargetTriple; } 00346 00347 bool isTargetDarwin() const { return TargetTriple.isOSDarwin(); } 00348 bool isTargetIOS() const { return TargetTriple.isiOS(); } 00349 bool isTargetLinux() const { return TargetTriple.isOSLinux(); } 00350 bool isTargetNaCl() const { return TargetTriple.isOSNaCl(); } 00351 bool isTargetNetBSD() const { return TargetTriple.getOS() == Triple::NetBSD; } 00352 bool isTargetWindows() const { return TargetTriple.isOSWindows(); } 00353 00354 bool isTargetCOFF() const { return TargetTriple.isOSBinFormatCOFF(); } 00355 bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); } 00356 bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); } 00357 00358 // ARM EABI is the bare-metal EABI described in ARM ABI documents and 00359 // can be accessed via -target arm-none-eabi. This is NOT GNUEABI. 00360 // FIXME: Add a flag for bare-metal for that target and set Triple::EABI 00361 // even for GNUEABI, so we can make a distinction here and still conform to 00362 // the EABI on GNU (and Android) mode. This requires change in Clang, too. 00363 // FIXME: The Darwin exception is temporary, while we move users to 00364 // "*-*-*-macho" triples as quickly as possible. 00365 bool isTargetAEABI() const { 00366 return (TargetTriple.getEnvironment() == Triple::EABI || 00367 TargetTriple.getEnvironment() == Triple::EABIHF) && 00368 !isTargetDarwin() && !isTargetWindows(); 00369 } 00370 00371 // ARM Targets that support EHABI exception handling standard 00372 // Darwin uses SjLj. Other targets might need more checks. 00373 bool isTargetEHABICompatible() const { 00374 return (TargetTriple.getEnvironment() == Triple::EABI || 00375 TargetTriple.getEnvironment() == Triple::GNUEABI || 00376 TargetTriple.getEnvironment() == Triple::EABIHF || 00377 TargetTriple.getEnvironment() == Triple::GNUEABIHF || 00378 TargetTriple.getEnvironment() == Triple::Android) && 00379 !isTargetDarwin() && !isTargetWindows(); 00380 } 00381 00382 bool isTargetHardFloat() const { 00383 // FIXME: this is invalid for WindowsCE 00384 return TargetTriple.getEnvironment() == Triple::GNUEABIHF || 00385 TargetTriple.getEnvironment() == Triple::EABIHF || 00386 isTargetWindows(); 00387 } 00388 bool isTargetAndroid() const { 00389 return TargetTriple.getEnvironment() == Triple::Android; 00390 } 00391 00392 bool isAPCS_ABI() const { 00393 assert(TargetABI != ARM_ABI_UNKNOWN); 00394 return TargetABI == ARM_ABI_APCS; 00395 } 00396 bool isAAPCS_ABI() const { 00397 assert(TargetABI != ARM_ABI_UNKNOWN); 00398 return TargetABI == ARM_ABI_AAPCS; 00399 } 00400 00401 bool isThumb() const { return InThumbMode; } 00402 bool isThumb1Only() const { return InThumbMode && !HasThumb2; } 00403 bool isThumb2() const { return InThumbMode && HasThumb2; } 00404 bool hasThumb2() const { return HasThumb2; } 00405 bool isMClass() const { return ARMProcClass == MClass; } 00406 bool isRClass() const { return ARMProcClass == RClass; } 00407 bool isAClass() const { return ARMProcClass == AClass; } 00408 00409 bool isR9Reserved() const { return IsR9Reserved; } 00410 00411 bool useMovt(const MachineFunction &MF) const; 00412 00413 bool supportsTailCall() const { return SupportsTailCall; } 00414 00415 bool allowsUnalignedMem() const { return AllowsUnalignedMem; } 00416 00417 bool restrictIT() const { return RestrictIT; } 00418 00419 const std::string & getCPUString() const { return CPUString; } 00420 00421 bool isLittle() const { return IsLittle; } 00422 00423 unsigned getMispredictionPenalty() const; 00424 00425 /// This function returns true if the target has sincos() routine in its 00426 /// compiler runtime or math libraries. 00427 bool hasSinCos() const; 00428 00429 /// True for some subtargets at > -O0. 00430 bool enablePostMachineScheduler() const override; 00431 00432 // enableAtomicExpand- True if we need to expand our atomics. 00433 bool enableAtomicExpand() const override; 00434 00435 /// getInstrItins - Return the instruction itineraries based on subtarget 00436 /// selection. 00437 const InstrItineraryData *getInstrItineraryData() const override { 00438 return &InstrItins; 00439 } 00440 00441 /// getStackAlignment - Returns the minimum alignment known to hold of the 00442 /// stack frame on entry to the function and which must be maintained by every 00443 /// function for this subtarget. 00444 unsigned getStackAlignment() const { return stackAlignment; } 00445 00446 /// GVIsIndirectSymbol - true if the GV will be accessed via an indirect 00447 /// symbol. 00448 bool GVIsIndirectSymbol(const GlobalValue *GV, Reloc::Model RelocM) const; 00449 00450 }; 00451 } // End llvm namespace 00452 00453 #endif // ARMSUBTARGET_H