Line data Source code
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 :
14 : #ifndef LLVM_LIB_TARGET_ARM_ARMSUBTARGET_H
15 : #define LLVM_LIB_TARGET_ARM_ARMSUBTARGET_H
16 :
17 : #include "ARMBaseInstrInfo.h"
18 : #include "ARMBaseRegisterInfo.h"
19 : #include "ARMConstantPoolValue.h"
20 : #include "ARMFrameLowering.h"
21 : #include "ARMISelLowering.h"
22 : #include "ARMSelectionDAGInfo.h"
23 : #include "llvm/ADT/Triple.h"
24 : #include "llvm/CodeGen/GlobalISel/CallLowering.h"
25 : #include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
26 : #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
27 : #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
28 : #include "llvm/CodeGen/MachineFunction.h"
29 : #include "llvm/CodeGen/TargetSubtargetInfo.h"
30 : #include "llvm/MC/MCInstrItineraries.h"
31 : #include "llvm/MC/MCSchedule.h"
32 : #include "llvm/Target/TargetOptions.h"
33 : #include <memory>
34 : #include <string>
35 :
36 : #define GET_SUBTARGETINFO_HEADER
37 : #include "ARMGenSubtargetInfo.inc"
38 :
39 : namespace llvm {
40 :
41 : class ARMBaseTargetMachine;
42 : class GlobalValue;
43 : class StringRef;
44 :
45 : class ARMSubtarget : public ARMGenSubtargetInfo {
46 : protected:
47 : enum ARMProcFamilyEnum {
48 : Others,
49 :
50 : CortexA12,
51 : CortexA15,
52 : CortexA17,
53 : CortexA32,
54 : CortexA35,
55 : CortexA5,
56 : CortexA53,
57 : CortexA55,
58 : CortexA57,
59 : CortexA7,
60 : CortexA72,
61 : CortexA73,
62 : CortexA75,
63 : CortexA8,
64 : CortexA9,
65 : CortexM3,
66 : CortexR4,
67 : CortexR4F,
68 : CortexR5,
69 : CortexR52,
70 : CortexR7,
71 : Exynos,
72 : Krait,
73 : Kryo,
74 : Swift
75 : };
76 : enum ARMProcClassEnum {
77 : None,
78 :
79 : AClass,
80 : MClass,
81 : RClass
82 : };
83 : enum ARMArchEnum {
84 : ARMv2,
85 : ARMv2a,
86 : ARMv3,
87 : ARMv3m,
88 : ARMv4,
89 : ARMv4t,
90 : ARMv5,
91 : ARMv5t,
92 : ARMv5te,
93 : ARMv5tej,
94 : ARMv6,
95 : ARMv6k,
96 : ARMv6kz,
97 : ARMv6m,
98 : ARMv6sm,
99 : ARMv6t2,
100 : ARMv7a,
101 : ARMv7em,
102 : ARMv7m,
103 : ARMv7r,
104 : ARMv7ve,
105 : ARMv81a,
106 : ARMv82a,
107 : ARMv83a,
108 : ARMv84a,
109 : ARMv85a,
110 : ARMv8a,
111 : ARMv8mBaseline,
112 : ARMv8mMainline,
113 : ARMv8r
114 : };
115 :
116 : public:
117 : /// What kind of timing do load multiple/store multiple instructions have.
118 : enum ARMLdStMultipleTiming {
119 : /// Can load/store 2 registers/cycle.
120 : DoubleIssue,
121 : /// Can load/store 2 registers/cycle, but needs an extra cycle if the access
122 : /// is not 64-bit aligned.
123 : DoubleIssueCheckUnalignedAccess,
124 : /// Can load/store 1 register/cycle.
125 : SingleIssue,
126 : /// Can load/store 1 register/cycle, but needs an extra cycle for address
127 : /// computation and potentially also for register writeback.
128 : SingleIssuePlusExtras,
129 : };
130 :
131 : protected:
132 : /// ARMProcFamily - ARM processor family: Cortex-A8, Cortex-A9, and others.
133 : ARMProcFamilyEnum ARMProcFamily = Others;
134 :
135 : /// ARMProcClass - ARM processor class: None, AClass, RClass or MClass.
136 : ARMProcClassEnum ARMProcClass = None;
137 :
138 : /// ARMArch - ARM architecture
139 : ARMArchEnum ARMArch = ARMv4t;
140 :
141 : /// HasV4TOps, HasV5TOps, HasV5TEOps,
142 : /// HasV6Ops, HasV6MOps, HasV6KOps, HasV6T2Ops, HasV7Ops, HasV8Ops -
143 : /// Specify whether target support specific ARM ISA variants.
144 : bool HasV4TOps = false;
145 : bool HasV5TOps = false;
146 : bool HasV5TEOps = false;
147 : bool HasV6Ops = false;
148 : bool HasV6MOps = false;
149 : bool HasV6KOps = false;
150 : bool HasV6T2Ops = false;
151 : bool HasV7Ops = false;
152 : bool HasV8Ops = false;
153 : bool HasV8_1aOps = false;
154 : bool HasV8_2aOps = false;
155 : bool HasV8_3aOps = false;
156 : bool HasV8_4aOps = false;
157 : bool HasV8_5aOps = false;
158 : bool HasV8MBaselineOps = false;
159 : bool HasV8MMainlineOps = false;
160 :
161 : /// HasVFPv2, HasVFPv3, HasVFPv4, HasFPARMv8, HasNEON - Specify what
162 : /// floating point ISAs are supported.
163 : bool HasVFPv2 = false;
164 : bool HasVFPv3 = false;
165 : bool HasVFPv4 = false;
166 : bool HasFPARMv8 = false;
167 : bool HasNEON = false;
168 :
169 : /// HasDotProd - True if the ARMv8.2A dot product instructions are supported.
170 : bool HasDotProd = false;
171 :
172 : /// UseNEONForSinglePrecisionFP - if the NEONFP attribute has been
173 : /// specified. Use the method useNEONForSinglePrecisionFP() to
174 : /// determine if NEON should actually be used.
175 : bool UseNEONForSinglePrecisionFP = false;
176 :
177 : /// UseMulOps - True if non-microcoded fused integer multiply-add and
178 : /// multiply-subtract instructions should be used.
179 : bool UseMulOps = false;
180 :
181 : /// SlowFPVMLx - If the VFP2 / NEON instructions are available, indicates
182 : /// whether the FP VML[AS] instructions are slow (if so, don't use them).
183 : bool SlowFPVMLx = false;
184 :
185 : /// HasVMLxForwarding - If true, NEON has special multiplier accumulator
186 : /// forwarding to allow mul + mla being issued back to back.
187 : bool HasVMLxForwarding = false;
188 :
189 : /// SlowFPBrcc - True if floating point compare + branch is slow.
190 : bool SlowFPBrcc = false;
191 :
192 : /// InThumbMode - True if compiling for Thumb, false for ARM.
193 : bool InThumbMode = false;
194 :
195 : /// UseSoftFloat - True if we're using software floating point features.
196 : bool UseSoftFloat = false;
197 :
198 : /// UseMISched - True if MachineScheduler should be used for this subtarget.
199 : bool UseMISched = false;
200 :
201 : /// DisablePostRAScheduler - False if scheduling should happen again after
202 : /// register allocation.
203 : bool DisablePostRAScheduler = false;
204 :
205 : /// UseAA - True if using AA during codegen (DAGCombine, MISched, etc)
206 : bool UseAA = false;
207 :
208 : /// HasThumb2 - True if Thumb2 instructions are supported.
209 : bool HasThumb2 = false;
210 :
211 : /// NoARM - True if subtarget does not support ARM mode execution.
212 : bool NoARM = false;
213 :
214 : /// ReserveR9 - True if R9 is not available as a general purpose register.
215 : bool ReserveR9 = false;
216 :
217 : /// NoMovt - True if MOVT / MOVW pairs are not used for materialization of
218 : /// 32-bit imms (including global addresses).
219 : bool NoMovt = false;
220 :
221 : /// SupportsTailCall - True if the OS supports tail call. The dynamic linker
222 : /// must be able to synthesize call stubs for interworking between ARM and
223 : /// Thumb.
224 : bool SupportsTailCall = false;
225 :
226 : /// HasFP16 - True if subtarget supports half-precision FP conversions
227 : bool HasFP16 = false;
228 :
229 : /// HasFullFP16 - True if subtarget supports half-precision FP operations
230 : bool HasFullFP16 = false;
231 :
232 : /// HasFP16FML - True if subtarget supports half-precision FP fml operations
233 : bool HasFP16FML = false;
234 :
235 : /// HasD16 - True if subtarget is limited to 16 double precision
236 : /// FP registers for VFPv3.
237 : bool HasD16 = false;
238 :
239 : /// HasHardwareDivide - True if subtarget supports [su]div in Thumb mode
240 : bool HasHardwareDivideInThumb = false;
241 :
242 : /// HasHardwareDivideInARM - True if subtarget supports [su]div in ARM mode
243 : bool HasHardwareDivideInARM = false;
244 :
245 : /// HasDataBarrier - True if the subtarget supports DMB / DSB data barrier
246 : /// instructions.
247 : bool HasDataBarrier = false;
248 :
249 : /// HasFullDataBarrier - True if the subtarget supports DFB data barrier
250 : /// instruction.
251 : bool HasFullDataBarrier = false;
252 :
253 : /// HasV7Clrex - True if the subtarget supports CLREX instructions
254 : bool HasV7Clrex = false;
255 :
256 : /// HasAcquireRelease - True if the subtarget supports v8 atomics (LDA/LDAEX etc)
257 : /// instructions
258 : bool HasAcquireRelease = false;
259 :
260 : /// Pref32BitThumb - If true, codegen would prefer 32-bit Thumb instructions
261 : /// over 16-bit ones.
262 : bool Pref32BitThumb = false;
263 :
264 : /// AvoidCPSRPartialUpdate - If true, codegen would avoid using instructions
265 : /// that partially update CPSR and add false dependency on the previous
266 : /// CPSR setting instruction.
267 : bool AvoidCPSRPartialUpdate = false;
268 :
269 : /// CheapPredicableCPSRDef - If true, disable +1 predication cost
270 : /// for instructions updating CPSR. Enabled for Cortex-A57.
271 : bool CheapPredicableCPSRDef = false;
272 :
273 : /// AvoidMOVsShifterOperand - If true, codegen should avoid using flag setting
274 : /// movs with shifter operand (i.e. asr, lsl, lsr).
275 : bool AvoidMOVsShifterOperand = false;
276 :
277 : /// HasRetAddrStack - Some processors perform return stack prediction. CodeGen should
278 : /// avoid issue "normal" call instructions to callees which do not return.
279 : bool HasRetAddrStack = false;
280 :
281 : /// HasBranchPredictor - True if the subtarget has a branch predictor. Having
282 : /// a branch predictor or not changes the expected cost of taking a branch
283 : /// which affects the choice of whether to use predicated instructions.
284 : bool HasBranchPredictor = true;
285 :
286 : /// HasMPExtension - True if the subtarget supports Multiprocessing
287 : /// extension (ARMv7 only).
288 : bool HasMPExtension = false;
289 :
290 : /// HasVirtualization - True if the subtarget supports the Virtualization
291 : /// extension.
292 : bool HasVirtualization = false;
293 :
294 : /// FPOnlySP - If true, the floating point unit only supports single
295 : /// precision.
296 : bool FPOnlySP = false;
297 :
298 : /// If true, the processor supports the Performance Monitor Extensions. These
299 : /// include a generic cycle-counter as well as more fine-grained (often
300 : /// implementation-specific) events.
301 : bool HasPerfMon = false;
302 :
303 : /// HasTrustZone - if true, processor supports TrustZone security extensions
304 : bool HasTrustZone = false;
305 :
306 : /// Has8MSecExt - if true, processor supports ARMv8-M Security Extensions
307 : bool Has8MSecExt = false;
308 :
309 : /// HasSHA2 - if true, processor supports SHA1 and SHA256
310 : bool HasSHA2 = false;
311 :
312 : /// HasAES - if true, processor supports AES
313 : bool HasAES = false;
314 :
315 : /// HasCrypto - if true, processor supports Cryptography extensions
316 : bool HasCrypto = false;
317 :
318 : /// HasCRC - if true, processor supports CRC instructions
319 : bool HasCRC = false;
320 :
321 : /// HasRAS - if true, the processor supports RAS extensions
322 : bool HasRAS = false;
323 :
324 : /// If true, the instructions "vmov.i32 d0, #0" and "vmov.i32 q0, #0" are
325 : /// particularly effective at zeroing a VFP register.
326 : bool HasZeroCycleZeroing = false;
327 :
328 : /// HasFPAO - if true, processor does positive address offset computation faster
329 : bool HasFPAO = false;
330 :
331 : /// HasFuseAES - if true, processor executes back to back AES instruction
332 : /// pairs faster.
333 : bool HasFuseAES = false;
334 :
335 : /// HasFuseLiterals - if true, processor executes back to back
336 : /// bottom and top halves of literal generation faster.
337 : bool HasFuseLiterals = false;
338 :
339 : /// If true, if conversion may decide to leave some instructions unpredicated.
340 : bool IsProfitableToUnpredicate = false;
341 :
342 : /// If true, VMOV will be favored over VGETLNi32.
343 : bool HasSlowVGETLNi32 = false;
344 :
345 : /// If true, VMOV will be favored over VDUP.
346 : bool HasSlowVDUP32 = false;
347 :
348 : /// If true, VMOVSR will be favored over VMOVDRR.
349 : bool PreferVMOVSR = false;
350 :
351 : /// If true, ISHST barriers will be used for Release semantics.
352 : bool PreferISHST = false;
353 :
354 : /// If true, a VLDM/VSTM starting with an odd register number is considered to
355 : /// take more microops than single VLDRS/VSTRS.
356 : bool SlowOddRegister = false;
357 :
358 : /// If true, loading into a D subregister will be penalized.
359 : bool SlowLoadDSubregister = false;
360 :
361 : /// If true, use a wider stride when allocating VFP registers.
362 : bool UseWideStrideVFP = false;
363 :
364 : /// If true, the AGU and NEON/FPU units are multiplexed.
365 : bool HasMuxedUnits = false;
366 :
367 : /// If true, VMOVS will never be widened to VMOVD.
368 : bool DontWidenVMOVS = false;
369 :
370 : /// If true, splat a register between VFP and NEON instructions.
371 : bool SplatVFPToNeon = false;
372 :
373 : /// If true, run the MLx expansion pass.
374 : bool ExpandMLx = false;
375 :
376 : /// If true, VFP/NEON VMLA/VMLS have special RAW hazards.
377 : bool HasVMLxHazards = false;
378 :
379 : // If true, read thread pointer from coprocessor register.
380 : bool ReadTPHard = false;
381 :
382 : /// If true, VMOVRS, VMOVSR and VMOVS will be converted from VFP to NEON.
383 : bool UseNEONForFPMovs = false;
384 :
385 : /// If true, VLDn instructions take an extra cycle for unaligned accesses.
386 : bool CheckVLDnAlign = false;
387 :
388 : /// If true, VFP instructions are not pipelined.
389 : bool NonpipelinedVFP = false;
390 :
391 : /// StrictAlign - If true, the subtarget disallows unaligned memory
392 : /// accesses for some types. For details, see
393 : /// ARMTargetLowering::allowsMisalignedMemoryAccesses().
394 : bool StrictAlign = false;
395 :
396 : /// RestrictIT - If true, the subtarget disallows generation of deprecated IT
397 : /// blocks to conform to ARMv8 rule.
398 : bool RestrictIT = false;
399 :
400 : /// HasDSP - If true, the subtarget supports the DSP (saturating arith
401 : /// and such) instructions.
402 : bool HasDSP = false;
403 :
404 : /// NaCl TRAP instruction is generated instead of the regular TRAP.
405 : bool UseNaClTrap = false;
406 :
407 : /// Generate calls via indirect call instructions.
408 : bool GenLongCalls = false;
409 :
410 : /// Generate code that does not contain data access to code sections.
411 : bool GenExecuteOnly = false;
412 :
413 : /// Target machine allowed unsafe FP math (such as use of NEON fp)
414 : bool UnsafeFPMath = false;
415 :
416 : /// UseSjLjEH - If true, the target uses SjLj exception handling (e.g. iOS).
417 : bool UseSjLjEH = false;
418 :
419 : /// Has speculation barrier
420 : bool HasSpecCtrl = false;
421 :
422 : /// Implicitly convert an instruction to a different one if its immediates
423 : /// cannot be encoded. For example, ADD r0, r1, #FFFFFFFF -> SUB r0, r1, #1.
424 : bool NegativeImmediates = true;
425 :
426 : /// stackAlignment - The minimum alignment known to hold of the stack frame on
427 : /// entry to the function and which must be maintained by every function.
428 : unsigned stackAlignment = 4;
429 :
430 : /// CPUString - String name of used CPU.
431 : std::string CPUString;
432 :
433 : unsigned MaxInterleaveFactor = 1;
434 :
435 : /// Clearance before partial register updates (in number of instructions)
436 : unsigned PartialUpdateClearance = 0;
437 :
438 : /// What kind of timing do load multiple/store multiple have (double issue,
439 : /// single issue etc).
440 : ARMLdStMultipleTiming LdStMultipleTiming = SingleIssue;
441 :
442 : /// The adjustment that we need to apply to get the operand latency from the
443 : /// operand cycle returned by the itinerary data for pre-ISel operands.
444 : int PreISelOperandLatencyAdjustment = 2;
445 :
446 : /// What alignment is preferred for loop bodies, in log2(bytes).
447 : unsigned PrefLoopAlignment = 0;
448 :
449 : /// IsLittle - The target is Little Endian
450 : bool IsLittle;
451 :
452 : /// TargetTriple - What processor and OS we're targeting.
453 : Triple TargetTriple;
454 :
455 : /// SchedModel - Processor specific instruction costs.
456 : MCSchedModel SchedModel;
457 :
458 : /// Selected instruction itineraries (one entry per itinerary class.)
459 : InstrItineraryData InstrItins;
460 :
461 : /// Options passed via command line that could influence the target
462 : const TargetOptions &Options;
463 :
464 : const ARMBaseTargetMachine &TM;
465 :
466 : public:
467 : /// This constructor initializes the data members to match that
468 : /// of the specified triple.
469 : ///
470 : ARMSubtarget(const Triple &TT, const std::string &CPU, const std::string &FS,
471 : const ARMBaseTargetMachine &TM, bool IsLittle);
472 :
473 : /// getMaxInlineSizeThreshold - Returns the maximum memset / memcpy size
474 : /// that still makes it profitable to inline the call.
475 0 : unsigned getMaxInlineSizeThreshold() const {
476 0 : return 64;
477 : }
478 :
479 : /// ParseSubtargetFeatures - Parses features string setting specified
480 : /// subtarget options. Definition of function is auto generated by tblgen.
481 : void ParseSubtargetFeatures(StringRef CPU, StringRef FS);
482 :
483 : /// initializeSubtargetDependencies - Initializes using a CPU and feature string
484 : /// so that we can use initializer lists for subtarget initialization.
485 : ARMSubtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS);
486 :
487 14446 : const ARMSelectionDAGInfo *getSelectionDAGInfo() const override {
488 14446 : return &TSInfo;
489 : }
490 :
491 1372808 : const ARMBaseInstrInfo *getInstrInfo() const override {
492 1372808 : return InstrInfo.get();
493 : }
494 :
495 609937 : const ARMTargetLowering *getTargetLowering() const override {
496 609937 : return &TLInfo;
497 : }
498 :
499 2169543 : const ARMFrameLowering *getFrameLowering() const override {
500 2169543 : return FrameLowering.get();
501 : }
502 :
503 2853288 : const ARMBaseRegisterInfo *getRegisterInfo() const override {
504 2858338 : return &InstrInfo->getRegisterInfo();
505 : }
506 :
507 : const CallLowering *getCallLowering() const override;
508 : const InstructionSelector *getInstructionSelector() const override;
509 : const LegalizerInfo *getLegalizerInfo() const override;
510 : const RegisterBankInfo *getRegBankInfo() const override;
511 :
512 : private:
513 : ARMSelectionDAGInfo TSInfo;
514 : // Either Thumb1FrameLowering or ARMFrameLowering.
515 : std::unique_ptr<ARMFrameLowering> FrameLowering;
516 : // Either Thumb1InstrInfo or Thumb2InstrInfo.
517 : std::unique_ptr<ARMBaseInstrInfo> InstrInfo;
518 : ARMTargetLowering TLInfo;
519 :
520 : /// GlobalISel related APIs.
521 : std::unique_ptr<CallLowering> CallLoweringInfo;
522 : std::unique_ptr<InstructionSelector> InstSelector;
523 : std::unique_ptr<LegalizerInfo> Legalizer;
524 : std::unique_ptr<RegisterBankInfo> RegBankInfo;
525 :
526 : void initializeEnvironment();
527 : void initSubtargetFeatures(StringRef CPU, StringRef FS);
528 : ARMFrameLowering *initializeFrameLowering(StringRef CPU, StringRef FS);
529 :
530 : public:
531 : void computeIssueWidth();
532 :
533 0 : bool hasV4TOps() const { return HasV4TOps; }
534 0 : bool hasV5TOps() const { return HasV5TOps; }
535 0 : bool hasV5TEOps() const { return HasV5TEOps; }
536 0 : bool hasV6Ops() const { return HasV6Ops; }
537 0 : bool hasV6MOps() const { return HasV6MOps; }
538 0 : bool hasV6KOps() const { return HasV6KOps; }
539 0 : bool hasV6T2Ops() const { return HasV6T2Ops; }
540 0 : bool hasV7Ops() const { return HasV7Ops; }
541 0 : bool hasV8Ops() const { return HasV8Ops; }
542 0 : bool hasV8_1aOps() const { return HasV8_1aOps; }
543 : bool hasV8_2aOps() const { return HasV8_2aOps; }
544 : bool hasV8_3aOps() const { return HasV8_3aOps; }
545 : bool hasV8_4aOps() const { return HasV8_4aOps; }
546 : bool hasV8_5aOps() const { return HasV8_5aOps; }
547 0 : bool hasV8MBaselineOps() const { return HasV8MBaselineOps; }
548 : bool hasV8MMainlineOps() const { return HasV8MMainlineOps; }
549 :
550 : /// @{
551 : /// These functions are obsolete, please consider adding subtarget features
552 : /// or properties instead of calling them.
553 : bool isCortexA5() const { return ARMProcFamily == CortexA5; }
554 0 : bool isCortexA7() const { return ARMProcFamily == CortexA7; }
555 0 : bool isCortexA8() const { return ARMProcFamily == CortexA8; }
556 0 : bool isCortexA9() const { return ARMProcFamily == CortexA9; }
557 0 : bool isCortexA15() const { return ARMProcFamily == CortexA15; }
558 174 : bool isSwift() const { return ARMProcFamily == Swift; }
559 0 : bool isCortexM3() const { return ARMProcFamily == CortexM3; }
560 156887 : bool isLikeA9() const { return isCortexA9() || isCortexA15() || isKrait(); }
561 : bool isCortexR5() const { return ARMProcFamily == CortexR5; }
562 0 : bool isKrait() const { return ARMProcFamily == Krait; }
563 : /// @}
564 :
565 0 : bool hasARMOps() const { return !NoARM; }
566 :
567 0 : bool hasVFP2() const { return HasVFPv2; }
568 0 : bool hasVFP3() const { return HasVFPv3; }
569 0 : bool hasVFP4() const { return HasVFPv4; }
570 0 : bool hasFPARMv8() const { return HasFPARMv8; }
571 0 : bool hasNEON() const { return HasNEON; }
572 : bool hasSHA2() const { return HasSHA2; }
573 : bool hasAES() const { return HasAES; }
574 0 : bool hasCrypto() const { return HasCrypto; }
575 0 : bool hasDotProd() const { return HasDotProd; }
576 0 : bool hasCRC() const { return HasCRC; }
577 : bool hasRAS() const { return HasRAS; }
578 : bool hasVirtualization() const { return HasVirtualization; }
579 :
580 : bool useNEONForSinglePrecisionFP() const {
581 39353 : return hasNEON() && UseNEONForSinglePrecisionFP;
582 : }
583 :
584 0 : bool hasDivideInThumbMode() const { return HasHardwareDivideInThumb; }
585 0 : bool hasDivideInARMMode() const { return HasHardwareDivideInARM; }
586 0 : bool hasDataBarrier() const { return HasDataBarrier; }
587 : bool hasFullDataBarrier() const { return HasFullDataBarrier; }
588 0 : bool hasV7Clrex() const { return HasV7Clrex; }
589 0 : bool hasAcquireRelease() const { return HasAcquireRelease; }
590 :
591 : bool hasAnyDataBarrier() const {
592 21619 : return HasDataBarrier || (hasV6Ops() && !isThumb());
593 : }
594 :
595 0 : bool useMulOps() const { return UseMulOps; }
596 0 : bool useFPVMLx() const { return !SlowFPVMLx; }
597 0 : bool hasVMLxForwarding() const { return HasVMLxForwarding; }
598 0 : bool isFPBrccSlow() const { return SlowFPBrcc; }
599 0 : bool isFPOnlySP() const { return FPOnlySP; }
600 0 : bool hasPerfMon() const { return HasPerfMon; }
601 : bool hasTrustZone() const { return HasTrustZone; }
602 : bool has8MSecExt() const { return Has8MSecExt; }
603 0 : bool hasZeroCycleZeroing() const { return HasZeroCycleZeroing; }
604 0 : bool hasFPAO() const { return HasFPAO; }
605 0 : bool isProfitableToUnpredicate() const { return IsProfitableToUnpredicate; }
606 0 : bool hasSlowVGETLNi32() const { return HasSlowVGETLNi32; }
607 0 : bool hasSlowVDUP32() const { return HasSlowVDUP32; }
608 0 : bool preferVMOVSR() const { return PreferVMOVSR; }
609 0 : bool preferISHSTBarriers() const { return PreferISHST; }
610 0 : bool expandMLx() const { return ExpandMLx; }
611 0 : bool hasVMLxHazards() const { return HasVMLxHazards; }
612 0 : bool hasSlowOddRegister() const { return SlowOddRegister; }
613 0 : bool hasSlowLoadDSubregister() const { return SlowLoadDSubregister; }
614 0 : bool useWideStrideVFP() const { return UseWideStrideVFP; }
615 0 : bool hasMuxedUnits() const { return HasMuxedUnits; }
616 0 : bool dontWidenVMOVS() const { return DontWidenVMOVS; }
617 0 : bool useSplatVFPToNeon() const { return SplatVFPToNeon; }
618 0 : bool useNEONForFPMovs() const { return UseNEONForFPMovs; }
619 0 : bool checkVLDnAccessAlignment() const { return CheckVLDnAlign; }
620 0 : bool nonpipelinedVFP() const { return NonpipelinedVFP; }
621 0 : bool prefers32BitThumb() const { return Pref32BitThumb; }
622 0 : bool avoidCPSRPartialUpdate() const { return AvoidCPSRPartialUpdate; }
623 0 : bool cheapPredicableCPSRDef() const { return CheapPredicableCPSRDef; }
624 0 : bool avoidMOVsShifterOperand() const { return AvoidMOVsShifterOperand; }
625 0 : bool hasRetAddrStack() const { return HasRetAddrStack; }
626 0 : bool hasBranchPredictor() const { return HasBranchPredictor; }
627 0 : bool hasMPExtension() const { return HasMPExtension; }
628 0 : bool hasDSP() const { return HasDSP; }
629 0 : bool useNaClTrap() const { return UseNaClTrap; }
630 0 : bool useSjLjEH() const { return UseSjLjEH; }
631 : bool hasSpecCtrl() const { return HasSpecCtrl; }
632 0 : bool genLongCalls() const { return GenLongCalls; }
633 0 : bool genExecuteOnly() const { return GenExecuteOnly; }
634 :
635 0 : bool hasFP16() const { return HasFP16; }
636 0 : bool hasD16() const { return HasD16; }
637 0 : bool hasFullFP16() const { return HasFullFP16; }
638 : bool hasFP16FML() const { return HasFP16FML; }
639 :
640 0 : bool hasFuseAES() const { return HasFuseAES; }
641 0 : bool hasFuseLiterals() const { return HasFuseLiterals; }
642 : /// Return true if the CPU supports any kind of instruction fusion.
643 292 : bool hasFusion() const { return hasFuseAES() || hasFuseLiterals(); }
644 :
645 382 : const Triple &getTargetTriple() const { return TargetTriple; }
646 :
647 : bool isTargetDarwin() const { return TargetTriple.isOSDarwin(); }
648 : bool isTargetIOS() const { return TargetTriple.isiOS(); }
649 : bool isTargetWatchOS() const { return TargetTriple.isWatchOS(); }
650 : bool isTargetWatchABI() const { return TargetTriple.isWatchABI(); }
651 : bool isTargetLinux() const { return TargetTriple.isOSLinux(); }
652 : bool isTargetNaCl() const { return TargetTriple.isOSNaCl(); }
653 : bool isTargetNetBSD() const { return TargetTriple.isOSNetBSD(); }
654 : bool isTargetWindows() const { return TargetTriple.isOSWindows(); }
655 :
656 : bool isTargetCOFF() const { return TargetTriple.isOSBinFormatCOFF(); }
657 : bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }
658 : bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); }
659 :
660 : // ARM EABI is the bare-metal EABI described in ARM ABI documents and
661 : // can be accessed via -target arm-none-eabi. This is NOT GNUEABI.
662 : // FIXME: Add a flag for bare-metal for that target and set Triple::EABI
663 : // even for GNUEABI, so we can make a distinction here and still conform to
664 : // the EABI on GNU (and Android) mode. This requires change in Clang, too.
665 : // FIXME: The Darwin exception is temporary, while we move users to
666 : // "*-*-*-macho" triples as quickly as possible.
667 : bool isTargetAEABI() const {
668 17431 : return (TargetTriple.getEnvironment() == Triple::EABI ||
669 : TargetTriple.getEnvironment() == Triple::EABIHF) &&
670 38875 : !isTargetDarwin() && !isTargetWindows();
671 : }
672 : bool isTargetGNUAEABI() const {
673 8951 : return (TargetTriple.getEnvironment() == Triple::GNUEABI ||
674 : TargetTriple.getEnvironment() == Triple::GNUEABIHF) &&
675 19379 : !isTargetDarwin() && !isTargetWindows();
676 : }
677 : bool isTargetMuslAEABI() const {
678 7734 : return (TargetTriple.getEnvironment() == Triple::MuslEABI ||
679 : TargetTriple.getEnvironment() == Triple::MuslEABIHF) &&
680 8321 : !isTargetDarwin() && !isTargetWindows();
681 : }
682 :
683 : // ARM Targets that support EHABI exception handling standard
684 : // Darwin uses SjLj. Other targets might need more checks.
685 142538 : bool isTargetEHABICompatible() const {
686 99912 : return (TargetTriple.getEnvironment() == Triple::EABI ||
687 82479 : TargetTriple.getEnvironment() == Triple::GNUEABI ||
688 81580 : TargetTriple.getEnvironment() == Triple::MuslEABI ||
689 75149 : TargetTriple.getEnvironment() == Triple::EABIHF ||
690 70739 : TargetTriple.getEnvironment() == Triple::GNUEABIHF ||
691 70368 : TargetTriple.getEnvironment() == Triple::MuslEABIHF ||
692 : isTargetAndroid()) &&
693 217193 : !isTargetDarwin() && !isTargetWindows();
694 : }
695 :
696 : bool isTargetHardFloat() const;
697 :
698 : bool isTargetAndroid() const { return TargetTriple.isAndroid(); }
699 :
700 : bool isXRaySupported() const override;
701 :
702 : bool isAPCS_ABI() const;
703 : bool isAAPCS_ABI() const;
704 : bool isAAPCS16_ABI() const;
705 :
706 : bool isROPI() const;
707 : bool isRWPI() const;
708 :
709 0 : bool useMachineScheduler() const { return UseMISched; }
710 0 : bool disablePostRAScheduler() const { return DisablePostRAScheduler; }
711 0 : bool useSoftFloat() const { return UseSoftFloat; }
712 0 : bool isThumb() const { return InThumbMode; }
713 571239 : bool isThumb1Only() const { return InThumbMode && !HasThumb2; }
714 146697 : bool isThumb2() const { return InThumbMode && HasThumb2; }
715 0 : bool hasThumb2() const { return HasThumb2; }
716 47 : bool isMClass() const { return ARMProcClass == MClass; }
717 : bool isRClass() const { return ARMProcClass == RClass; }
718 : bool isAClass() const { return ARMProcClass == AClass; }
719 0 : bool isReadTPHard() const { return ReadTPHard; }
720 :
721 : bool isR9Reserved() const {
722 44203 : return isTargetMachO() ? (ReserveR9 || !HasV6Ops) : ReserveR9;
723 : }
724 :
725 : bool useR7AsFramePointer() const {
726 431161 : return isTargetDarwin() || (!isTargetWindows() && isThumb());
727 : }
728 :
729 : /// Returns true if the frame setup is split into two separate pushes (first
730 : /// r0-r7,lr then r8-r11), principally so that the frame pointer is adjacent
731 : /// to lr. This is always required on Thumb1-only targets, as the push and
732 : /// pop instructions can't access the high registers.
733 405390 : bool splitFramePushPop(const MachineFunction &MF) const {
734 201427 : return (useR7AsFramePointer() &&
735 201427 : MF.getTarget().Options.DisableFramePointerElim(MF)) ||
736 365687 : isThumb1Only();
737 : }
738 :
739 : bool useStride4VFPs(const MachineFunction &MF) const;
740 :
741 : bool useMovt(const MachineFunction &MF) const;
742 :
743 0 : bool supportsTailCall() const { return SupportsTailCall; }
744 :
745 3389 : bool allowsUnalignedMem() const { return !StrictAlign; }
746 :
747 0 : bool restrictIT() const { return RestrictIT; }
748 :
749 : const std::string & getCPUString() const { return CPUString; }
750 :
751 0 : bool isLittle() const { return IsLittle; }
752 :
753 : unsigned getMispredictionPenalty() const;
754 :
755 : /// Returns true if machine scheduler should be enabled.
756 : bool enableMachineScheduler() const override;
757 :
758 : /// True for some subtargets at > -O0.
759 : bool enablePostRAScheduler() const override;
760 :
761 : /// Enable use of alias analysis during code generation (during MI
762 : /// scheduling, DAGCombine, etc.).
763 73898 : bool useAA() const override { return UseAA; }
764 :
765 : // enableAtomicExpand- True if we need to expand our atomics.
766 : bool enableAtomicExpand() const override;
767 :
768 : /// getInstrItins - Return the instruction itineraries based on subtarget
769 : /// selection.
770 61018 : const InstrItineraryData *getInstrItineraryData() const override {
771 61018 : return &InstrItins;
772 : }
773 :
774 : /// getStackAlignment - Returns the minimum alignment known to hold of the
775 : /// stack frame on entry to the function and which must be maintained by every
776 : /// function for this subtarget.
777 0 : unsigned getStackAlignment() const { return stackAlignment; }
778 :
779 0 : unsigned getMaxInterleaveFactor() const { return MaxInterleaveFactor; }
780 :
781 0 : unsigned getPartialUpdateClearance() const { return PartialUpdateClearance; }
782 :
783 0 : ARMLdStMultipleTiming getLdStMultipleTiming() const {
784 0 : return LdStMultipleTiming;
785 : }
786 :
787 0 : int getPreISelOperandLatencyAdjustment() const {
788 0 : return PreISelOperandLatencyAdjustment;
789 : }
790 :
791 : /// True if the GV will be accessed via an indirect symbol.
792 : bool isGVIndirectSymbol(const GlobalValue *GV) const;
793 :
794 : /// Returns the constant pool modifier needed to access the GV.
795 : bool isGVInGOT(const GlobalValue *GV) const;
796 :
797 : /// True if fast-isel is used.
798 : bool useFastISel() const;
799 :
800 : /// Returns the correct return opcode for the current feature set.
801 : /// Use BX if available to allow mixing thumb/arm code, but fall back
802 : /// to plain mov pc,lr on ARMv4.
803 : unsigned getReturnOpcode() const {
804 1162 : if (isThumb())
805 : return ARM::tBX_RET;
806 840 : if (hasV4TOps())
807 : return ARM::BX_RET;
808 : return ARM::MOVPCLR;
809 : }
810 :
811 : /// Allow movt+movw for PIC global address calculation.
812 : /// ELF does not have GOT relocations for movt+movw.
813 : /// ROPI does not use GOT.
814 : bool allowPositionIndependentMovt() const {
815 1639 : return isROPI() || !isTargetELF();
816 : }
817 :
818 0 : unsigned getPrefLoopAlignment() const {
819 0 : return PrefLoopAlignment;
820 : }
821 : };
822 :
823 : } // end namespace llvm
824 :
825 : #endif // LLVM_LIB_TARGET_ARM_ARMSUBTARGET_H
|