]>
Commit | Line | Data |
---|---|---|
223e47cc LB |
1 | //===-- ARMSubtarget.h - Define Subtarget for the ARM ----------*- 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 declares the ARM specific subclass of TargetSubtargetInfo. | |
11 | // | |
12 | //===----------------------------------------------------------------------===// | |
13 | ||
1a4d82fc JJ |
14 | #ifndef LLVM_LIB_TARGET_ARM_ARMSUBTARGET_H |
15 | #define LLVM_LIB_TARGET_ARM_ARMSUBTARGET_H | |
16 | ||
17 | ||
18 | #include "ARMFrameLowering.h" | |
19 | #include "ARMISelLowering.h" | |
20 | #include "ARMInstrInfo.h" | |
21 | #include "ARMSelectionDAGInfo.h" | |
22 | #include "ARMSubtarget.h" | |
85aaf69f | 23 | #include "MCTargetDesc/ARMMCTargetDesc.h" |
1a4d82fc JJ |
24 | #include "Thumb1FrameLowering.h" |
25 | #include "Thumb1InstrInfo.h" | |
26 | #include "Thumb2InstrInfo.h" | |
223e47cc | 27 | #include "llvm/ADT/Triple.h" |
1a4d82fc | 28 | #include "llvm/IR/DataLayout.h" |
970d7e83 LB |
29 | #include "llvm/MC/MCInstrItineraries.h" |
30 | #include "llvm/Target/TargetSubtargetInfo.h" | |
223e47cc LB |
31 | #include <string> |
32 | ||
33 | #define GET_SUBTARGETINFO_HEADER | |
34 | #include "ARMGenSubtargetInfo.inc" | |
35 | ||
36 | namespace llvm { | |
37 | class GlobalValue; | |
38 | class StringRef; | |
1a4d82fc | 39 | class TargetOptions; |
85aaf69f | 40 | class ARMBaseTargetMachine; |
223e47cc LB |
41 | |
42 | class ARMSubtarget : public ARMGenSubtargetInfo { | |
43 | protected: | |
44 | enum ARMProcFamilyEnum { | |
1a4d82fc | 45 | Others, CortexA5, CortexA7, CortexA8, CortexA9, CortexA12, CortexA15, |
85aaf69f | 46 | CortexA17, CortexR5, Swift, CortexA53, CortexA57, Krait, |
1a4d82fc JJ |
47 | }; |
48 | enum ARMProcClassEnum { | |
49 | None, AClass, RClass, MClass | |
223e47cc LB |
50 | }; |
51 | ||
52 | /// ARMProcFamily - ARM processor family: Cortex-A8, Cortex-A9, and others. | |
53 | ARMProcFamilyEnum ARMProcFamily; | |
54 | ||
1a4d82fc JJ |
55 | /// ARMProcClass - ARM processor class: None, AClass, RClass or MClass. |
56 | ARMProcClassEnum ARMProcClass; | |
57 | ||
58 | /// HasV4TOps, HasV5TOps, HasV5TEOps, | |
59 | /// HasV6Ops, HasV6MOps, HasV6T2Ops, HasV7Ops, HasV8Ops - | |
223e47cc LB |
60 | /// Specify whether target support specific ARM ISA variants. |
61 | bool HasV4TOps; | |
62 | bool HasV5TOps; | |
63 | bool HasV5TEOps; | |
64 | bool HasV6Ops; | |
1a4d82fc | 65 | bool HasV6MOps; |
223e47cc LB |
66 | bool HasV6T2Ops; |
67 | bool HasV7Ops; | |
1a4d82fc | 68 | bool HasV8Ops; |
223e47cc | 69 | |
1a4d82fc | 70 | /// HasVFPv2, HasVFPv3, HasVFPv4, HasFPARMv8, HasNEON - Specify what |
223e47cc LB |
71 | /// floating point ISAs are supported. |
72 | bool HasVFPv2; | |
73 | bool HasVFPv3; | |
74 | bool HasVFPv4; | |
1a4d82fc | 75 | bool HasFPARMv8; |
223e47cc LB |
76 | bool HasNEON; |
77 | ||
78 | /// UseNEONForSinglePrecisionFP - if the NEONFP attribute has been | |
79 | /// specified. Use the method useNEONForSinglePrecisionFP() to | |
80 | /// determine if NEON should actually be used. | |
81 | bool UseNEONForSinglePrecisionFP; | |
82 | ||
83 | /// UseMulOps - True if non-microcoded fused integer multiply-add and | |
84 | /// multiply-subtract instructions should be used. | |
85 | bool UseMulOps; | |
86 | ||
87 | /// SlowFPVMLx - If the VFP2 / NEON instructions are available, indicates | |
88 | /// whether the FP VML[AS] instructions are slow (if so, don't use them). | |
89 | bool SlowFPVMLx; | |
90 | ||
91 | /// HasVMLxForwarding - If true, NEON has special multiplier accumulator | |
92 | /// forwarding to allow mul + mla being issued back to back. | |
93 | bool HasVMLxForwarding; | |
94 | ||
95 | /// SlowFPBrcc - True if floating point compare + branch is slow. | |
96 | bool SlowFPBrcc; | |
97 | ||
98 | /// InThumbMode - True if compiling for Thumb, false for ARM. | |
99 | bool InThumbMode; | |
100 | ||
101 | /// HasThumb2 - True if Thumb2 instructions are supported. | |
102 | bool HasThumb2; | |
103 | ||
223e47cc LB |
104 | /// NoARM - True if subtarget does not support ARM mode execution. |
105 | bool NoARM; | |
106 | ||
223e47cc LB |
107 | /// IsR9Reserved - True if R9 is a not available as general purpose register. |
108 | bool IsR9Reserved; | |
109 | ||
110 | /// UseMovt - True if MOVT / MOVW pairs are used for materialization of 32-bit | |
111 | /// imms (including global addresses). | |
112 | bool UseMovt; | |
113 | ||
114 | /// SupportsTailCall - True if the OS supports tail call. The dynamic linker | |
115 | /// must be able to synthesize call stubs for interworking between ARM and | |
116 | /// Thumb. | |
117 | bool SupportsTailCall; | |
118 | ||
119 | /// HasFP16 - True if subtarget supports half-precision FP (We support VFP+HF | |
120 | /// only so far) | |
121 | bool HasFP16; | |
122 | ||
123 | /// HasD16 - True if subtarget is limited to 16 double precision | |
124 | /// FP registers for VFPv3. | |
125 | bool HasD16; | |
126 | ||
127 | /// HasHardwareDivide - True if subtarget supports [su]div | |
128 | bool HasHardwareDivide; | |
129 | ||
130 | /// HasHardwareDivideInARM - True if subtarget supports [su]div in ARM mode | |
131 | bool HasHardwareDivideInARM; | |
132 | ||
133 | /// HasT2ExtractPack - True if subtarget supports thumb2 extract/pack | |
134 | /// instructions. | |
135 | bool HasT2ExtractPack; | |
136 | ||
137 | /// HasDataBarrier - True if the subtarget supports DMB / DSB data barrier | |
138 | /// instructions. | |
139 | bool HasDataBarrier; | |
140 | ||
141 | /// Pref32BitThumb - If true, codegen would prefer 32-bit Thumb instructions | |
142 | /// over 16-bit ones. | |
143 | bool Pref32BitThumb; | |
144 | ||
145 | /// AvoidCPSRPartialUpdate - If true, codegen would avoid using instructions | |
146 | /// that partially update CPSR and add false dependency on the previous | |
147 | /// CPSR setting instruction. | |
148 | bool AvoidCPSRPartialUpdate; | |
149 | ||
970d7e83 LB |
150 | /// AvoidMOVsShifterOperand - If true, codegen should avoid using flag setting |
151 | /// movs with shifter operand (i.e. asr, lsl, lsr). | |
152 | bool AvoidMOVsShifterOperand; | |
153 | ||
223e47cc LB |
154 | /// HasRAS - Some processors perform return stack prediction. CodeGen should |
155 | /// avoid issue "normal" call instructions to callees which do not return. | |
156 | bool HasRAS; | |
157 | ||
158 | /// HasMPExtension - True if the subtarget supports Multiprocessing | |
159 | /// extension (ARMv7 only). | |
160 | bool HasMPExtension; | |
161 | ||
1a4d82fc JJ |
162 | /// HasVirtualization - True if the subtarget supports the Virtualization |
163 | /// extension. | |
164 | bool HasVirtualization; | |
165 | ||
223e47cc LB |
166 | /// FPOnlySP - If true, the floating point unit only supports single |
167 | /// precision. | |
168 | bool FPOnlySP; | |
169 | ||
1a4d82fc JJ |
170 | /// If true, the processor supports the Performance Monitor Extensions. These |
171 | /// include a generic cycle-counter as well as more fine-grained (often | |
172 | /// implementation-specific) events. | |
173 | bool HasPerfMon; | |
174 | ||
175 | /// HasTrustZone - if true, processor supports TrustZone security extensions | |
176 | bool HasTrustZone; | |
177 | ||
178 | /// HasCrypto - if true, processor supports Cryptography extensions | |
179 | bool HasCrypto; | |
180 | ||
181 | /// HasCRC - if true, processor supports CRC instructions | |
182 | bool HasCRC; | |
183 | ||
184 | /// If true, the instructions "vmov.i32 d0, #0" and "vmov.i32 q0, #0" are | |
185 | /// particularly effective at zeroing a VFP register. | |
186 | bool HasZeroCycleZeroing; | |
187 | ||
223e47cc LB |
188 | /// AllowsUnalignedMem - If true, the subtarget allows unaligned memory |
189 | /// accesses for some types. For details, see | |
1a4d82fc | 190 | /// ARMTargetLowering::allowsMisalignedMemoryAccesses(). |
223e47cc LB |
191 | bool AllowsUnalignedMem; |
192 | ||
1a4d82fc JJ |
193 | /// RestrictIT - If true, the subtarget disallows generation of deprecated IT |
194 | /// blocks to conform to ARMv8 rule. | |
195 | bool RestrictIT; | |
196 | ||
223e47cc LB |
197 | /// Thumb2DSP - If true, the subtarget supports the v7 DSP (saturating arith |
198 | /// and such) instructions in Thumb2 code. | |
199 | bool Thumb2DSP; | |
200 | ||
970d7e83 LB |
201 | /// NaCl TRAP instruction is generated instead of the regular TRAP. |
202 | bool UseNaClTrap; | |
203 | ||
1a4d82fc JJ |
204 | /// Target machine allowed unsafe FP math (such as use of NEON fp) |
205 | bool UnsafeFPMath; | |
206 | ||
223e47cc LB |
207 | /// stackAlignment - The minimum alignment known to hold of the stack frame on |
208 | /// entry to the function and which must be maintained by every function. | |
209 | unsigned stackAlignment; | |
210 | ||
211 | /// CPUString - String name of used CPU. | |
212 | std::string CPUString; | |
213 | ||
1a4d82fc JJ |
214 | /// IsLittle - The target is Little Endian |
215 | bool IsLittle; | |
216 | ||
223e47cc LB |
217 | /// TargetTriple - What processor and OS we're targeting. |
218 | Triple TargetTriple; | |
219 | ||
220 | /// SchedModel - Processor specific instruction costs. | |
1a4d82fc | 221 | MCSchedModel SchedModel; |
223e47cc LB |
222 | |
223 | /// Selected instruction itineraries (one entry per itinerary class.) | |
224 | InstrItineraryData InstrItins; | |
225 | ||
1a4d82fc JJ |
226 | /// Options passed via command line that could influence the target |
227 | const TargetOptions &Options; | |
223e47cc | 228 | |
85aaf69f | 229 | const ARMBaseTargetMachine &TM; |
223e47cc | 230 | |
85aaf69f | 231 | public: |
223e47cc LB |
232 | /// This constructor initializes the data members to match that |
233 | /// of the specified triple. | |
234 | /// | |
235 | ARMSubtarget(const std::string &TT, const std::string &CPU, | |
85aaf69f | 236 | const std::string &FS, const ARMBaseTargetMachine &TM, bool IsLittle); |
223e47cc LB |
237 | |
238 | /// getMaxInlineSizeThreshold - Returns the maximum memset / memcpy size | |
239 | /// that still makes it profitable to inline the call. | |
240 | unsigned getMaxInlineSizeThreshold() const { | |
1a4d82fc | 241 | return 64; |
223e47cc LB |
242 | } |
243 | /// ParseSubtargetFeatures - Parses features string setting specified | |
244 | /// subtarget options. Definition of function is auto generated by tblgen. | |
245 | void ParseSubtargetFeatures(StringRef CPU, StringRef FS); | |
246 | ||
1a4d82fc JJ |
247 | /// initializeSubtargetDependencies - Initializes using a CPU and feature string |
248 | /// so that we can use initializer lists for subtarget initialization. | |
249 | ARMSubtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS); | |
250 | ||
251 | const DataLayout *getDataLayout() const override { return &DL; } | |
252 | const ARMSelectionDAGInfo *getSelectionDAGInfo() const override { | |
253 | return &TSInfo; | |
254 | } | |
255 | const ARMBaseInstrInfo *getInstrInfo() const override { | |
256 | return InstrInfo.get(); | |
257 | } | |
258 | const ARMTargetLowering *getTargetLowering() const override { | |
259 | return &TLInfo; | |
260 | } | |
261 | const ARMFrameLowering *getFrameLowering() const override { | |
262 | return FrameLowering.get(); | |
263 | } | |
264 | const ARMBaseRegisterInfo *getRegisterInfo() const override { | |
265 | return &InstrInfo->getRegisterInfo(); | |
266 | } | |
267 | ||
970d7e83 | 268 | private: |
1a4d82fc JJ |
269 | const DataLayout DL; |
270 | ARMSelectionDAGInfo TSInfo; | |
271 | // Either Thumb1InstrInfo or Thumb2InstrInfo. | |
272 | std::unique_ptr<ARMBaseInstrInfo> InstrInfo; | |
273 | ARMTargetLowering TLInfo; | |
274 | // Either Thumb1FrameLowering or ARMFrameLowering. | |
275 | std::unique_ptr<ARMFrameLowering> FrameLowering; | |
276 | ||
970d7e83 | 277 | void initializeEnvironment(); |
1a4d82fc | 278 | void initSubtargetFeatures(StringRef CPU, StringRef FS); |
970d7e83 | 279 | public: |
223e47cc LB |
280 | void computeIssueWidth(); |
281 | ||
282 | bool hasV4TOps() const { return HasV4TOps; } | |
283 | bool hasV5TOps() const { return HasV5TOps; } | |
284 | bool hasV5TEOps() const { return HasV5TEOps; } | |
285 | bool hasV6Ops() const { return HasV6Ops; } | |
1a4d82fc | 286 | bool hasV6MOps() const { return HasV6MOps; } |
223e47cc LB |
287 | bool hasV6T2Ops() const { return HasV6T2Ops; } |
288 | bool hasV7Ops() const { return HasV7Ops; } | |
1a4d82fc | 289 | bool hasV8Ops() const { return HasV8Ops; } |
223e47cc | 290 | |
970d7e83 | 291 | bool isCortexA5() const { return ARMProcFamily == CortexA5; } |
1a4d82fc | 292 | bool isCortexA7() const { return ARMProcFamily == CortexA7; } |
223e47cc LB |
293 | bool isCortexA8() const { return ARMProcFamily == CortexA8; } |
294 | bool isCortexA9() const { return ARMProcFamily == CortexA9; } | |
295 | bool isCortexA15() const { return ARMProcFamily == CortexA15; } | |
296 | bool isSwift() const { return ARMProcFamily == Swift; } | |
297 | bool isCortexM3() const { return CPUString == "cortex-m3"; } | |
1a4d82fc | 298 | bool isLikeA9() const { return isCortexA9() || isCortexA15() || isKrait(); } |
970d7e83 | 299 | bool isCortexR5() const { return ARMProcFamily == CortexR5; } |
1a4d82fc | 300 | bool isKrait() const { return ARMProcFamily == Krait; } |
223e47cc LB |
301 | |
302 | bool hasARMOps() const { return !NoARM; } | |
303 | ||
304 | bool hasVFP2() const { return HasVFPv2; } | |
305 | bool hasVFP3() const { return HasVFPv3; } | |
306 | bool hasVFP4() const { return HasVFPv4; } | |
1a4d82fc | 307 | bool hasFPARMv8() const { return HasFPARMv8; } |
223e47cc | 308 | bool hasNEON() const { return HasNEON; } |
1a4d82fc JJ |
309 | bool hasCrypto() const { return HasCrypto; } |
310 | bool hasCRC() const { return HasCRC; } | |
311 | bool hasVirtualization() const { return HasVirtualization; } | |
223e47cc LB |
312 | bool useNEONForSinglePrecisionFP() const { |
313 | return hasNEON() && UseNEONForSinglePrecisionFP; } | |
314 | ||
315 | bool hasDivide() const { return HasHardwareDivide; } | |
316 | bool hasDivideInARMMode() const { return HasHardwareDivideInARM; } | |
317 | bool hasT2ExtractPack() const { return HasT2ExtractPack; } | |
318 | bool hasDataBarrier() const { return HasDataBarrier; } | |
1a4d82fc JJ |
319 | bool hasAnyDataBarrier() const { |
320 | return HasDataBarrier || (hasV6Ops() && !isThumb()); | |
321 | } | |
223e47cc LB |
322 | bool useMulOps() const { return UseMulOps; } |
323 | bool useFPVMLx() const { return !SlowFPVMLx; } | |
324 | bool hasVMLxForwarding() const { return HasVMLxForwarding; } | |
325 | bool isFPBrccSlow() const { return SlowFPBrcc; } | |
326 | bool isFPOnlySP() const { return FPOnlySP; } | |
1a4d82fc JJ |
327 | bool hasPerfMon() const { return HasPerfMon; } |
328 | bool hasTrustZone() const { return HasTrustZone; } | |
329 | bool hasZeroCycleZeroing() const { return HasZeroCycleZeroing; } | |
223e47cc LB |
330 | bool prefers32BitThumb() const { return Pref32BitThumb; } |
331 | bool avoidCPSRPartialUpdate() const { return AvoidCPSRPartialUpdate; } | |
970d7e83 | 332 | bool avoidMOVsShifterOperand() const { return AvoidMOVsShifterOperand; } |
223e47cc LB |
333 | bool hasRAS() const { return HasRAS; } |
334 | bool hasMPExtension() const { return HasMPExtension; } | |
335 | bool hasThumb2DSP() const { return Thumb2DSP; } | |
970d7e83 | 336 | bool useNaClTrap() const { return UseNaClTrap; } |
223e47cc LB |
337 | |
338 | bool hasFP16() const { return HasFP16; } | |
339 | bool hasD16() const { return HasD16; } | |
340 | ||
341 | const Triple &getTargetTriple() const { return TargetTriple; } | |
342 | ||
223e47cc | 343 | bool isTargetDarwin() const { return TargetTriple.isOSDarwin(); } |
1a4d82fc JJ |
344 | bool isTargetIOS() const { return TargetTriple.isiOS(); } |
345 | bool isTargetLinux() const { return TargetTriple.isOSLinux(); } | |
346 | bool isTargetNaCl() const { return TargetTriple.isOSNaCl(); } | |
85aaf69f | 347 | bool isTargetNetBSD() const { return TargetTriple.isOSNetBSD(); } |
1a4d82fc JJ |
348 | bool isTargetWindows() const { return TargetTriple.isOSWindows(); } |
349 | ||
350 | bool isTargetCOFF() const { return TargetTriple.isOSBinFormatCOFF(); } | |
351 | bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); } | |
352 | bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); } | |
353 | ||
354 | // ARM EABI is the bare-metal EABI described in ARM ABI documents and | |
355 | // can be accessed via -target arm-none-eabi. This is NOT GNUEABI. | |
356 | // FIXME: Add a flag for bare-metal for that target and set Triple::EABI | |
357 | // even for GNUEABI, so we can make a distinction here and still conform to | |
358 | // the EABI on GNU (and Android) mode. This requires change in Clang, too. | |
359 | // FIXME: The Darwin exception is temporary, while we move users to | |
360 | // "*-*-*-macho" triples as quickly as possible. | |
361 | bool isTargetAEABI() const { | |
362 | return (TargetTriple.getEnvironment() == Triple::EABI || | |
363 | TargetTriple.getEnvironment() == Triple::EABIHF) && | |
364 | !isTargetDarwin() && !isTargetWindows(); | |
365 | } | |
366 | ||
367 | // ARM Targets that support EHABI exception handling standard | |
368 | // Darwin uses SjLj. Other targets might need more checks. | |
369 | bool isTargetEHABICompatible() const { | |
370 | return (TargetTriple.getEnvironment() == Triple::EABI || | |
371 | TargetTriple.getEnvironment() == Triple::GNUEABI || | |
372 | TargetTriple.getEnvironment() == Triple::EABIHF || | |
373 | TargetTriple.getEnvironment() == Triple::GNUEABIHF || | |
374 | TargetTriple.getEnvironment() == Triple::Android) && | |
375 | !isTargetDarwin() && !isTargetWindows(); | |
376 | } | |
377 | ||
378 | bool isTargetHardFloat() const { | |
379 | // FIXME: this is invalid for WindowsCE | |
380 | return TargetTriple.getEnvironment() == Triple::GNUEABIHF || | |
381 | TargetTriple.getEnvironment() == Triple::EABIHF || | |
382 | isTargetWindows(); | |
223e47cc | 383 | } |
970d7e83 LB |
384 | bool isTargetAndroid() const { |
385 | return TargetTriple.getEnvironment() == Triple::Android; | |
386 | } | |
223e47cc | 387 | |
85aaf69f SL |
388 | bool isAPCS_ABI() const; |
389 | bool isAAPCS_ABI() const; | |
223e47cc LB |
390 | |
391 | bool isThumb() const { return InThumbMode; } | |
392 | bool isThumb1Only() const { return InThumbMode && !HasThumb2; } | |
393 | bool isThumb2() const { return InThumbMode && HasThumb2; } | |
394 | bool hasThumb2() const { return HasThumb2; } | |
1a4d82fc JJ |
395 | bool isMClass() const { return ARMProcClass == MClass; } |
396 | bool isRClass() const { return ARMProcClass == RClass; } | |
397 | bool isAClass() const { return ARMProcClass == AClass; } | |
223e47cc | 398 | |
85aaf69f SL |
399 | bool isV6M() const { |
400 | return isThumb1Only() && isMClass(); | |
401 | } | |
402 | ||
223e47cc LB |
403 | bool isR9Reserved() const { return IsR9Reserved; } |
404 | ||
1a4d82fc JJ |
405 | bool useMovt(const MachineFunction &MF) const; |
406 | ||
223e47cc LB |
407 | bool supportsTailCall() const { return SupportsTailCall; } |
408 | ||
409 | bool allowsUnalignedMem() const { return AllowsUnalignedMem; } | |
410 | ||
1a4d82fc JJ |
411 | bool restrictIT() const { return RestrictIT; } |
412 | ||
223e47cc LB |
413 | const std::string & getCPUString() const { return CPUString; } |
414 | ||
1a4d82fc JJ |
415 | bool isLittle() const { return IsLittle; } |
416 | ||
223e47cc LB |
417 | unsigned getMispredictionPenalty() const; |
418 | ||
1a4d82fc JJ |
419 | /// This function returns true if the target has sincos() routine in its |
420 | /// compiler runtime or math libraries. | |
421 | bool hasSinCos() const; | |
223e47cc | 422 | |
1a4d82fc JJ |
423 | /// True for some subtargets at > -O0. |
424 | bool enablePostMachineScheduler() const override; | |
425 | ||
426 | // enableAtomicExpand- True if we need to expand our atomics. | |
427 | bool enableAtomicExpand() const override; | |
428 | ||
429 | /// getInstrItins - Return the instruction itineraries based on subtarget | |
223e47cc | 430 | /// selection. |
1a4d82fc JJ |
431 | const InstrItineraryData *getInstrItineraryData() const override { |
432 | return &InstrItins; | |
433 | } | |
223e47cc LB |
434 | |
435 | /// getStackAlignment - Returns the minimum alignment known to hold of the | |
436 | /// stack frame on entry to the function and which must be maintained by every | |
437 | /// function for this subtarget. | |
438 | unsigned getStackAlignment() const { return stackAlignment; } | |
439 | ||
440 | /// GVIsIndirectSymbol - true if the GV will be accessed via an indirect | |
441 | /// symbol. | |
442 | bool GVIsIndirectSymbol(const GlobalValue *GV, Reloc::Model RelocM) const; | |
1a4d82fc | 443 | |
223e47cc LB |
444 | }; |
445 | } // End llvm namespace | |
446 | ||
447 | #endif // ARMSUBTARGET_H |