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