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