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