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