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