LLVM  3.7.0
ARMSubtarget.cpp
Go to the documentation of this file.
1 //===-- ARMSubtarget.cpp - ARM Subtarget Information ----------------------===//
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 TargetSubtargetInfo.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "ARMSubtarget.h"
15 #include "ARMFrameLowering.h"
16 #include "ARMISelLowering.h"
17 #include "ARMInstrInfo.h"
18 #include "ARMMachineFunctionInfo.h"
19 #include "ARMSelectionDAGInfo.h"
20 #include "ARMSubtarget.h"
21 #include "ARMTargetMachine.h"
22 #include "Thumb1FrameLowering.h"
23 #include "Thumb1InstrInfo.h"
24 #include "Thumb2InstrInfo.h"
26 #include "llvm/IR/Attributes.h"
27 #include "llvm/IR/Function.h"
28 #include "llvm/IR/GlobalValue.h"
33 
34 using namespace llvm;
35 
36 #define DEBUG_TYPE "arm-subtarget"
37 
38 #define GET_SUBTARGETINFO_TARGET_DESC
39 #define GET_SUBTARGETINFO_CTOR
40 #include "ARMGenSubtargetInfo.inc"
41 
42 static cl::opt<bool>
43 ReserveR9("arm-reserve-r9", cl::Hidden,
44  cl::desc("Reserve R9, making it unavailable as GPR"));
45 
46 static cl::opt<bool>
47 ArmUseMOVT("arm-use-movt", cl::init(true), cl::Hidden);
48 
49 static cl::opt<bool>
50 UseFusedMulOps("arm-use-mulops",
51  cl::init(true), cl::Hidden);
52 
53 namespace {
54 enum AlignMode {
55  DefaultAlign,
56  StrictAlign,
57  NoStrictAlign
58 };
59 }
60 
61 static cl::opt<AlignMode>
62 Align(cl::desc("Load/store alignment support"),
63  cl::Hidden, cl::init(DefaultAlign),
64  cl::values(
65  clEnumValN(DefaultAlign, "arm-default-align",
66  "Generate unaligned accesses only on hardware/OS "
67  "combinations that are known to support them"),
68  clEnumValN(StrictAlign, "arm-strict-align",
69  "Disallow all unaligned memory accesses"),
70  clEnumValN(NoStrictAlign, "arm-no-strict-align",
71  "Allow unaligned memory accesses"),
72  clEnumValEnd));
73 
74 enum ITMode {
78 };
79 
80 static cl::opt<ITMode>
81 IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT),
83  cl::values(clEnumValN(DefaultIT, "arm-default-it",
84  "Generate IT block based on arch"),
85  clEnumValN(RestrictedIT, "arm-restrict-it",
86  "Disallow deprecated IT based on ARMv8"),
87  clEnumValN(NoRestrictedIT, "arm-no-restrict-it",
88  "Allow IT blocks based on ARMv7"),
89  clEnumValEnd));
90 
91 /// initializeSubtargetDependencies - Initializes using a CPU and feature string
92 /// so that we can use initializer lists for subtarget initialization.
94  StringRef FS) {
95  initializeEnvironment();
96  initSubtargetFeatures(CPU, FS);
97  return *this;
98 }
99 
100 ARMFrameLowering *ARMSubtarget::initializeFrameLowering(StringRef CPU,
101  StringRef FS) {
103  if (STI.isThumb1Only())
104  return (ARMFrameLowering *)new Thumb1FrameLowering(STI);
105 
106  return new ARMFrameLowering(STI);
107 }
108 
109 ARMSubtarget::ARMSubtarget(const Triple &TT, const std::string &CPU,
110  const std::string &FS,
111  const ARMBaseTargetMachine &TM, bool IsLittle)
112  : ARMGenSubtargetInfo(TT, CPU, FS), ARMProcFamily(Others),
113  ARMProcClass(None), stackAlignment(4), CPUString(CPU), IsLittle(IsLittle),
114  TargetTriple(TT), Options(TM.Options), TM(TM),
115  FrameLowering(initializeFrameLowering(CPU, FS)),
116  // At this point initializeSubtargetDependencies has been called so
117  // we can query directly.
118  InstrInfo(isThumb1Only()
119  ? (ARMBaseInstrInfo *)new Thumb1InstrInfo(*this)
120  : !isThumb()
121  ? (ARMBaseInstrInfo *)new ARMInstrInfo(*this)
122  : (ARMBaseInstrInfo *)new Thumb2InstrInfo(*this)),
123  TLInfo(TM, *this) {}
124 
125 void ARMSubtarget::initializeEnvironment() {
126  HasV4TOps = false;
127  HasV5TOps = false;
128  HasV5TEOps = false;
129  HasV6Ops = false;
130  HasV6MOps = false;
131  HasV6KOps = false;
132  HasV6T2Ops = false;
133  HasV7Ops = false;
134  HasV8Ops = false;
135  HasV8_1aOps = false;
136  HasVFPv2 = false;
137  HasVFPv3 = false;
138  HasVFPv4 = false;
139  HasFPARMv8 = false;
140  HasNEON = false;
143  SlowFPVMLx = false;
144  HasVMLxForwarding = false;
145  SlowFPBrcc = false;
146  InThumbMode = false;
147  UseSoftFloat = false;
148  HasThumb2 = false;
149  NoARM = false;
151  UseMovt = false;
152  SupportsTailCall = false;
153  HasFP16 = false;
154  HasD16 = false;
155  HasHardwareDivide = false;
156  HasHardwareDivideInARM = false;
157  HasT2ExtractPack = false;
158  HasDataBarrier = false;
159  Pref32BitThumb = false;
160  AvoidCPSRPartialUpdate = false;
161  AvoidMOVsShifterOperand = false;
162  HasRAS = false;
163  HasMPExtension = false;
164  HasVirtualization = false;
165  FPOnlySP = false;
166  HasPerfMon = false;
167  HasTrustZone = false;
168  HasCrypto = false;
169  HasCRC = false;
170  HasZeroCycleZeroing = false;
171  AllowsUnalignedMem = false;
172  Thumb2DSP = false;
173  UseNaClTrap = false;
174  GenLongCalls = false;
175  UnsafeFPMath = false;
176 }
177 
178 void ARMSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) {
179  if (CPUString.empty()) {
181  // Default to the Swift CPU when targeting armv7s/thumbv7s.
182  CPUString = "swift";
183  else
184  CPUString = "generic";
185  }
186 
187  // Insert the architecture feature derived from the target triple into the
188  // feature string. This is important for setting features that are implied
189  // based on the architecture version.
190  std::string ArchFS = ARM_MC::ParseARMTriple(TargetTriple, CPUString);
191  if (!FS.empty()) {
192  if (!ArchFS.empty())
193  ArchFS = (Twine(ArchFS) + "," + FS).str();
194  else
195  ArchFS = FS;
196  }
198 
199  // FIXME: This used enable V6T2 support implicitly for Thumb2 mode.
200  // Assert this for now to make the change obvious.
201  assert(hasV6T2Ops() || !hasThumb2());
202 
203  // Keep a pointer to static instruction cost data for the specified CPU.
204  SchedModel = getSchedModelForCPU(CPUString);
205 
206  // Initialize scheduling itinerary for the specified CPU.
207  InstrItins = getInstrItineraryForCPU(CPUString);
208 
209  // FIXME: this is invalid for WindowsCE
210  if (isTargetWindows())
211  NoARM = true;
212 
213  if (isAAPCS_ABI())
214  stackAlignment = 8;
215  if (isTargetNaCl())
216  stackAlignment = 16;
217 
219 
220  if (isTargetMachO()) {
223  } else {
226  }
227 
228  if (Align == DefaultAlign) {
229  // Assume pre-ARMv6 doesn't support unaligned accesses.
230  //
231  // ARMv6 may or may not support unaligned accesses depending on the
232  // SCTLR.U bit, which is architecture-specific. We assume ARMv6
233  // Darwin and NetBSD targets support unaligned accesses, and others don't.
234  //
235  // ARMv7 always has SCTLR.U set to 1, but it has a new SCTLR.A bit
236  // which raises an alignment fault on unaligned accesses. Linux
237  // defaults this bit to 0 and handles it as a system-wide (not
238  // per-process) setting. It is therefore safe to assume that ARMv7+
239  // Linux targets support unaligned accesses. The same goes for NaCl.
240  //
241  // The above behavior is consistent with GCC.
243  (hasV7Ops() && (isTargetLinux() || isTargetNaCl() ||
244  isTargetNetBSD())) ||
245  (hasV6Ops() && (isTargetMachO() || isTargetNetBSD()));
246  } else {
247  AllowsUnalignedMem = !(Align == StrictAlign);
248  }
249 
250  // No v6M core supports unaligned memory access (v6M ARM ARM A3.2)
251  if (isV6M())
252  AllowsUnalignedMem = false;
253 
254  switch (IT) {
255  case DefaultIT:
256  RestrictIT = hasV8Ops();
257  break;
258  case RestrictedIT:
259  RestrictIT = true;
260  break;
261  case NoRestrictedIT:
262  RestrictIT = false;
263  break;
264  }
265 
266  // NEON f32 ops are non-IEEE 754 compliant. Darwin is ok with it by default.
267  const FeatureBitset &Bits = getFeatureBits();
268  if ((Bits[ARM::ProcA5] || Bits[ARM::ProcA8]) && // Where this matters
271 }
272 
276 }
280 }
281 
282 /// GVIsIndirectSymbol - true if the GV will be accessed via an indirect symbol.
283 bool
285  Reloc::Model RelocM) const {
286  if (RelocM == Reloc::Static)
287  return false;
288 
289  bool isDef = GV->isStrongDefinitionForLinker();
290 
291  if (!isTargetMachO()) {
292  // Extra load is needed for all externally visible.
293  if (GV->hasLocalLinkage() || GV->hasHiddenVisibility())
294  return false;
295  return true;
296  } else {
297  // If this is a strong reference to a definition, it is definitely not
298  // through a stub.
299  if (isDef)
300  return false;
301 
302  // Unless we have a symbol with hidden visibility, we have to go through a
303  // normal $non_lazy_ptr stub because this symbol might be resolved late.
304  if (!GV->hasHiddenVisibility()) // Non-hidden $non_lazy_ptr reference.
305  return true;
306 
307  if (RelocM == Reloc::PIC_) {
308  // If symbol visibility is hidden, we have a stub for common symbol
309  // references and external declarations.
310  if (GV->isDeclarationForLinker() || GV->hasCommonLinkage())
311  // Hidden $non_lazy_ptr reference.
312  return true;
313  }
314  }
315 
316  return false;
317 }
318 
321 }
322 
324  return getTargetTriple().isiOS() && !getTargetTriple().isOSVersionLT(7, 0);
325 }
326 
327 // This overrides the PostRAScheduler bit in the SchedModel for any CPU.
329  return (!isThumb() || hasThumb2());
330 }
331 
333  return hasAnyDataBarrier() && !isThumb1Only();
334 }
335 
336 bool ARMSubtarget::useMovt(const MachineFunction &MF) const {
337  // NOTE Windows on ARM needs to use mov.w/mov.t pairs to materialise 32-bit
338  // immediates as it is inherently position independent, and may be out of
339  // range otherwise.
340  return UseMovt && (isTargetWindows() ||
342 }
343 
345  // Thumb2 support on iOS; ARM support on iOS, Linux and NaCl.
346  return TM.Options.EnableFastISel &&
347  ((isTargetMachO() && !isThumb1Only()) ||
348  (isTargetLinux() && !isThumb()) || (isTargetNaCl() && !isThumb()));
349 }
const NoneType None
Definition: None.h:23
unsigned MispredictPenalty
Definition: MCSchedule.h:184
ValuesClass< DataType > LLVM_END_WITH_NULL values(const char *Arg, DataType Val, const char *Desc,...)
Definition: CommandLine.h:536
unsigned stackAlignment
stackAlignment - The minimum alignment known to hold of the stack frame on entry to the function and ...
Definition: ARMSubtarget.h:217
Triple TargetTriple
TargetTriple - What processor and OS we're targeting.
Definition: ARMSubtarget.h:226
static cl::opt< bool > ArmUseMOVT("arm-use-movt", cl::init(true), cl::Hidden)
unsigned getMispredictionPenalty() const
unsigned EnableFastISel
EnableFastISel - This flag enables fast-path instruction selection which trades away generated code q...
bool SlowFPVMLx
SlowFPVMLx - If the VFP2 / NEON instructions are available, indicates whether the FP VML[AS] instruct...
Definition: ARMSubtarget.h:91
#define clEnumValEnd
Definition: CommandLine.h:498
bool AllowsUnalignedMem
AllowsUnalignedMem - If true, the subtarget allows unaligned memory accesses for some types...
Definition: ARMSubtarget.h:196
bool endswith(StringRef Suffix) const
Check if this string ends with the given Suffix.
Definition: StringRef.h:224
bool useFastISel() const
True if fast-isel is used.
bool HasVFPv2
HasVFPv2, HasVFPv3, HasVFPv4, HasFPARMv8, HasNEON - Specify what floating point ISAs are supported...
Definition: ARMSubtarget.h:74
bool hasV6Ops() const
Definition: ARMSubtarget.h:293
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
bool HasHardwareDivideInARM
HasHardwareDivideInARM - True if subtarget supports [su]div in ARM mode.
Definition: ARMSubtarget.h:136
enum llvm::ARMBaseTargetMachine::ARMABI TargetABI
bool hasV6T2Ops() const
Definition: ARMSubtarget.h:296
bool isThumb1Only() const
Definition: ARMSubtarget.h:405
const ARMBaseTargetMachine & TM
Definition: ARMSubtarget.h:237
bool GenLongCalls
Generate calls via indirect call instructions.
Definition: ARMSubtarget.h:210
bool SupportsTailCall
SupportsTailCall - True if the OS supports tail call.
Definition: ARMSubtarget.h:122
static bool isThumb(const MCSubtargetInfo &STI)
bool UseMulOps
UseMulOps - True if non-microcoded fused integer multiply-add and multiply-subtract instructions shou...
Definition: ARMSubtarget.h:87
bool hasV8Ops() const
Definition: ARMSubtarget.h:298
bool hasCommonLinkage() const
Definition: GlobalValue.h:282
bool HasRAS
HasRAS - Some processors perform return stack prediction.
Definition: ARMSubtarget.h:161
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:79
static cl::opt< ITMode > IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT), cl::ZeroOrMore, cl::values(clEnumValN(DefaultIT,"arm-default-it","Generate IT block based on arch"), clEnumValN(RestrictedIT,"arm-restrict-it","Disallow deprecated IT based on ARMv8"), clEnumValN(NoRestrictedIT,"arm-no-restrict-it","Allow IT blocks based on ARMv7"), clEnumValEnd))
bool hasThumb2() const
Definition: ARMSubtarget.h:407
bool isTargetDarwin() const
Definition: ARMSubtarget.h:355
bool HasZeroCycleZeroing
If true, the instructions "vmov.i32 d0, #0" and "vmov.i32 q0, #0" are particularly effective at zeroi...
Definition: ARMSubtarget.h:191
This file contains the simple types necessary to represent the attributes associated with functions a...
bool HasThumb2
HasThumb2 - True if Thumb2 instructions are supported.
Definition: ARMSubtarget.h:107
bool UnsafeFPMath
Target machine allowed unsafe FP math (such as use of NEON fp)
Definition: ARMSubtarget.h:213
bool isStrongDefinitionForLinker() const
Returns true if this global's definition will be the one chosen by the linker.
Definition: GlobalValue.h:353
bool isThumb() const
Definition: ARMSubtarget.h:404
bool hasV7Ops() const
Definition: ARMSubtarget.h:297
bool Pref32BitThumb
Pref32BitThumb - If true, codegen would prefer 32-bit Thumb instructions over 16-bit ones...
Definition: ARMSubtarget.h:148
const Triple & getTargetTriple() const
Definition: ARMSubtarget.h:353
bool enableAtomicExpand() const override
bool isTargetMachO() const
Definition: ARMSubtarget.h:364
bool NoARM
NoARM - True if subtarget does not support ARM mode execution.
Definition: ARMSubtarget.h:110
bool hasAnyDataBarrier() const
Definition: ARMSubtarget.h:330
bool HasT2ExtractPack
HasT2ExtractPack - True if subtarget supports thumb2 extract/pack instructions.
Definition: ARMSubtarget.h:140
bool HasPerfMon
If true, the processor supports the Performance Monitor Extensions.
Definition: ARMSubtarget.h:178
bool isTargetIOS() const
Definition: ARMSubtarget.h:356
bool isTargetNetBSD() const
Definition: ARMSubtarget.h:359
bool isiOS() const
Is this an iOS triple.
Definition: Triple.h:399
bool AvoidMOVsShifterOperand
AvoidMOVsShifterOperand - If true, codegen should avoid using flag setting movs with shifter operand ...
Definition: ARMSubtarget.h:157
bool HasCRC
HasCRC - if true, processor supports CRC instructions.
Definition: ARMSubtarget.h:187
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:325
unsigned UnsafeFPMath
UnsafeFPMath - This flag is enabled when the -enable-unsafe-fp-math flag is specified on the command ...
bool HasVirtualization
HasVirtualization - True if the subtarget supports the Virtualization extension.
Definition: ARMSubtarget.h:169
bool RestrictIT
RestrictIT - If true, the subtarget disallows generation of deprecated IT blocks to conform to ARMv8 ...
Definition: ARMSubtarget.h:200
static cl::opt< bool > UseFusedMulOps("arm-use-mulops", cl::init(true), cl::Hidden)
bool hasHiddenVisibility() const
Definition: GlobalValue.h:141
bool UseMovt
UseMovt - True if MOVT / MOVW pairs are used for materialization of 32-bit imms (including global add...
Definition: ARMSubtarget.h:117
bool HasV4TOps
HasV4TOps, HasV5TOps, HasV5TEOps, HasV6Ops, HasV6MOps, HasV6KOps, HasV6T2Ops, HasV7Ops, HasV8Ops - Specify whether target support specific ARM ISA variants.
Definition: ARMSubtarget.h:61
bool HasVMLxForwarding
HasVMLxForwarding - If true, NEON has special multiplier accumulator forwarding to allow mul + mla be...
Definition: ARMSubtarget.h:95
bool HasCrypto
HasCrypto - if true, processor supports Cryptography extensions.
Definition: ARMSubtarget.h:184
bool Thumb2DSP
Thumb2DSP - If true, the subtarget supports the v7 DSP (saturating arith and such) instructions in Th...
Definition: ARMSubtarget.h:204
bool HasMPExtension
HasMPExtension - True if the subtarget supports Multiprocessing extension (ARMv7 only).
Definition: ARMSubtarget.h:165
bool hasSinCos() const
This function returns true if the target has sincos() routine in its compiler runtime or math librari...
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
bool HasFP16
HasFP16 - True if subtarget supports half-precision FP (We support VFP+HF only so far) ...
Definition: ARMSubtarget.h:126
bool HasTrustZone
HasTrustZone - if true, processor supports TrustZone security extensions.
Definition: ARMSubtarget.h:181
bool InThumbMode
InThumbMode - True if compiling for Thumb, false for ARM.
Definition: ARMSubtarget.h:101
ARMSubtarget(const Triple &TT, const std::string &CPU, const std::string &FS, const ARMBaseTargetMachine &TM, bool IsLittle)
This constructor initializes the data members to match that of the specified triple.
bool isTargetNaCl() const
Definition: ARMSubtarget.h:358
bool isV6M() const
Definition: ARMSubtarget.h:412
void ParseSubtargetFeatures(StringRef CPU, StringRef FS)
ParseSubtargetFeatures - Parses features string setting specified subtarget options.
bool GVIsIndirectSymbol(const GlobalValue *GV, Reloc::Model RelocM) const
GVIsIndirectSymbol - true if the GV will be accessed via an indirect symbol.
bool FPOnlySP
FPOnlySP - If true, the floating point unit only supports single precision.
Definition: ARMSubtarget.h:173
bool UseNaClTrap
NaCl TRAP instruction is generated instead of the regular TRAP.
Definition: ARMSubtarget.h:207
MCSchedModel SchedModel
SchedModel - Processor specific instruction costs.
Definition: ARMSubtarget.h:229
const TargetOptions & Options
Options passed via command line that could influence the target.
Definition: ARMSubtarget.h:235
static cl::opt< bool > ReserveR9("arm-reserve-r9", cl::Hidden, cl::desc("Reserve R9, making it unavailable as GPR"))
ARMSubtarget & initializeSubtargetDependencies(StringRef CPU, StringRef FS)
initializeSubtargetDependencies - Initializes using a CPU and feature string so that we can use initi...
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(DefaultAlign), cl::values(clEnumValN(DefaultAlign,"arm-default-align","Generate unaligned accesses only on hardware/OS ""combinations that are known to support them"), clEnumValN(StrictAlign,"arm-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"arm-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
bool UseSoftFloat
UseSoftFloat - True if we're using software floating point features.
Definition: ARMSubtarget.h:104
bool isOSVersionLT(unsigned Major, unsigned Minor=0, unsigned Micro=0) const
isOSVersionLT - Helper function for doing comparisons against version numbers included in the target ...
Definition: Triple.h:355
bool IsR9Reserved
IsR9Reserved - True if R9 is a not available as general purpose register.
Definition: ARMSubtarget.h:113
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
Definition: CommandLine.h:497
bool isAPCS_ABI() const
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.h:217
bool isAAPCS_ABI() const
bool isTargetLinux() const
Definition: ARMSubtarget.h:357
StringRef getArchName() const
getArchName - Get the architecture (first) component of the triple.
Definition: Triple.cpp:783
InstrItineraryData InstrItins
Selected instruction itineraries (one entry per itinerary class.)
Definition: ARMSubtarget.h:232
bool UseNEONForSinglePrecisionFP
UseNEONForSinglePrecisionFP - if the NEONFP attribute has been specified.
Definition: ARMSubtarget.h:83
bool useMovt(const MachineFunction &MF) const
bool hasLocalLinkage() const
Definition: GlobalValue.h:280
bool SlowFPBrcc
SlowFPBrcc - True if floating point compare + branch is slow.
Definition: ARMSubtarget.h:98
bool HasD16
HasD16 - True if subtarget is limited to 16 double precision FP registers for VFPv3.
Definition: ARMSubtarget.h:130
bool enablePostRAScheduler() const override
True for some subtargets at > -O0.
bool AvoidCPSRPartialUpdate
AvoidCPSRPartialUpdate - If true, codegen would avoid using instructions that partially update CPSR a...
Definition: ARMSubtarget.h:153
std::string ParseARMTriple(const Triple &TT, StringRef CPU)
std::string CPUString
CPUString - String name of used CPU.
Definition: ARMSubtarget.h:220
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:40
ITMode
bool HasDataBarrier
HasDataBarrier - True if the subtarget supports DMB / DSB data barrier instructions.
Definition: ARMSubtarget.h:144
bool isDeclarationForLinker() const
Definition: GlobalValue.h:344
bool isTargetWindows() const
Definition: ARMSubtarget.h:360
bool HasHardwareDivide
HasHardwareDivide - True if subtarget supports [su]div.
Definition: ARMSubtarget.h:133
bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:110
Function must be optimized for size first.
Definition: Attributes.h:80