ARMSubtarget.cpp revision 3ef1c8759a20167457eb7fd82ebcaffe7ccaa1d1
1//===-- ARMSubtarget.cpp - ARM Subtarget Information ------------*- 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 implements the ARM specific subclass of TargetSubtarget. 11// 12//===----------------------------------------------------------------------===// 13 14#include "ARMSubtarget.h" 15#include "ARMGenSubtarget.inc" 16#include "llvm/GlobalValue.h" 17#include "llvm/Target/TargetOptions.h" 18#include "llvm/Support/CommandLine.h" 19#include "llvm/ADT/SmallVector.h" 20using namespace llvm; 21 22static cl::opt<bool> 23ReserveR9("arm-reserve-r9", cl::Hidden, 24 cl::desc("Reserve R9, making it unavailable as GPR")); 25 26static cl::opt<bool> 27UseMOVT("arm-use-movt", 28 cl::init(true), cl::Hidden); 29 30ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &FS, 31 bool isT) 32 : ARMArchVersion(V4) 33 , ARMProcFamily(Others) 34 , ARMFPUType(None) 35 , UseNEONForSinglePrecisionFP(false) 36 , SlowVMLx(false) 37 , SlowFPBrcc(false) 38 , IsThumb(isT) 39 , ThumbMode(Thumb1) 40 , NoARM(false) 41 , PostRAScheduler(false) 42 , IsR9Reserved(ReserveR9) 43 , UseMovt(UseMOVT) 44 , HasFP16(false) 45 , HasHardwareDivide(false) 46 , HasT2ExtractPack(false) 47 , HasDataBarrier(false) 48 , Pref32BitThumb(false) 49 , FPOnlySP(false) 50 , stackAlignment(4) 51 , CPUString("generic") 52 , TargetType(isELF) // Default to ELF unless otherwise specified. 53 , TargetABI(ARM_ABI_APCS) { 54 // Default to soft float ABI 55 if (FloatABIType == FloatABI::Default) 56 FloatABIType = FloatABI::Soft; 57 58 // Determine default and user specified characteristics 59 60 // Parse features string. 61 CPUString = ParseSubtargetFeatures(FS, CPUString); 62 63 // When no arch is specified either by CPU or by attributes, make the default 64 // ARMv4T. 65 if (CPUString == "generic" && (FS.empty() || FS == "generic")) 66 ARMArchVersion = V4T; 67 68 // Set the boolean corresponding to the current target triple, or the default 69 // if one cannot be determined, to true. 70 unsigned Len = TT.length(); 71 unsigned Idx = 0; 72 73 if (Len >= 5 && TT.substr(0, 4) == "armv") 74 Idx = 4; 75 else if (Len >= 6 && TT.substr(0, 5) == "thumb") { 76 IsThumb = true; 77 if (Len >= 7 && TT[5] == 'v') 78 Idx = 6; 79 } 80 if (Idx) { 81 unsigned SubVer = TT[Idx]; 82 if (SubVer >= '7' && SubVer <= '9') { 83 ARMArchVersion = V7A; 84 if (Len >= Idx+2 && TT[Idx+1] == 'm') 85 ARMArchVersion = V7M; 86 } else if (SubVer == '6') { 87 ARMArchVersion = V6; 88 if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == '2') 89 ARMArchVersion = V6T2; 90 } else if (SubVer == '5') { 91 ARMArchVersion = V5T; 92 if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == 'e') 93 ARMArchVersion = V5TE; 94 } else if (SubVer == '4') { 95 if (Len >= Idx+2 && TT[Idx+1] == 't') 96 ARMArchVersion = V4T; 97 else 98 ARMArchVersion = V4; 99 } 100 } 101 102 // Thumb2 implies at least V6T2. 103 if (ARMArchVersion >= V6T2) 104 ThumbMode = Thumb2; 105 else if (ThumbMode >= Thumb2) 106 ARMArchVersion = V6T2; 107 108 if (Len >= 10) { 109 if (TT.find("-darwin") != std::string::npos) 110 // arm-darwin 111 TargetType = isDarwin; 112 } 113 114 if (TT.find("eabi") != std::string::npos) 115 TargetABI = ARM_ABI_AAPCS; 116 117 if (isAAPCS_ABI()) 118 stackAlignment = 8; 119 120 if (isTargetDarwin()) 121 IsR9Reserved = ReserveR9 | (ARMArchVersion < V6); 122 123 if (!isThumb() || hasThumb2()) 124 PostRAScheduler = true; 125} 126 127/// GVIsIndirectSymbol - true if the GV will be accessed via an indirect symbol. 128bool 129ARMSubtarget::GVIsIndirectSymbol(const GlobalValue *GV, 130 Reloc::Model RelocM) const { 131 if (RelocM == Reloc::Static) 132 return false; 133 134 // Materializable GVs (in JIT lazy compilation mode) do not require an extra 135 // load from stub. 136 bool isDecl = GV->isDeclaration() && !GV->isMaterializable(); 137 138 if (!isTargetDarwin()) { 139 // Extra load is needed for all externally visible. 140 if (GV->hasLocalLinkage() || GV->hasHiddenVisibility()) 141 return false; 142 return true; 143 } else { 144 if (RelocM == Reloc::PIC_) { 145 // If this is a strong reference to a definition, it is definitely not 146 // through a stub. 147 if (!isDecl && !GV->isWeakForLinker()) 148 return false; 149 150 // Unless we have a symbol with hidden visibility, we have to go through a 151 // normal $non_lazy_ptr stub because this symbol might be resolved late. 152 if (!GV->hasHiddenVisibility()) // Non-hidden $non_lazy_ptr reference. 153 return true; 154 155 // If symbol visibility is hidden, we have a stub for common symbol 156 // references and external declarations. 157 if (isDecl || GV->hasCommonLinkage()) 158 // Hidden $non_lazy_ptr reference. 159 return true; 160 161 return false; 162 } else { 163 // If this is a strong reference to a definition, it is definitely not 164 // through a stub. 165 if (!isDecl && !GV->isWeakForLinker()) 166 return false; 167 168 // Unless we have a symbol with hidden visibility, we have to go through a 169 // normal $non_lazy_ptr stub because this symbol might be resolved late. 170 if (!GV->hasHiddenVisibility()) // Non-hidden $non_lazy_ptr reference. 171 return true; 172 } 173 } 174 175 return false; 176} 177 178bool ARMSubtarget::enablePostRAScheduler( 179 CodeGenOpt::Level OptLevel, 180 TargetSubtarget::AntiDepBreakMode& Mode, 181 RegClassVector& CriticalPathRCs) const { 182 Mode = TargetSubtarget::ANTIDEP_CRITICAL; 183 CriticalPathRCs.clear(); 184 CriticalPathRCs.push_back(&ARM::GPRRegClass); 185 return PostRAScheduler && OptLevel >= CodeGenOpt::Default; 186} 187