1 //===--- AArch64Subtarget.h - Define Subtarget for the AArch64 -*- 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 AArch64 specific subclass of TargetSubtarget. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_LIB_TARGET_AARCH64_AARCH64SUBTARGET_H 14 #define LLVM_LIB_TARGET_AARCH64_AARCH64SUBTARGET_H 15 16 #include "AArch64FrameLowering.h" 17 #include "AArch64ISelLowering.h" 18 #include "AArch64InstrInfo.h" 19 #include "AArch64RegisterInfo.h" 20 #include "AArch64SelectionDAGInfo.h" 21 #include "llvm/CodeGen/GlobalISel/CallLowering.h" 22 #include "llvm/CodeGen/GlobalISel/InlineAsmLowering.h" 23 #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" 24 #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" 25 #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h" 26 #include "llvm/CodeGen/TargetSubtargetInfo.h" 27 #include "llvm/IR/DataLayout.h" 28 #include <string> 29 30 #define GET_SUBTARGETINFO_HEADER 31 #include "AArch64GenSubtargetInfo.inc" 32 33 namespace llvm { 34 class GlobalValue; 35 class StringRef; 36 class Triple; 37 38 class AArch64Subtarget final : public AArch64GenSubtargetInfo { 39 public: 40 enum ARMProcFamilyEnum : uint8_t { 41 Others, 42 A64FX, 43 AppleA7, 44 AppleA10, 45 AppleA11, 46 AppleA12, 47 AppleA13, 48 AppleA14, 49 Carmel, 50 CortexA35, 51 CortexA53, 52 CortexA55, 53 CortexA57, 54 CortexA65, 55 CortexA72, 56 CortexA73, 57 CortexA75, 58 CortexA76, 59 CortexA77, 60 CortexA78, 61 CortexA78C, 62 CortexR82, 63 CortexX1, 64 ExynosM3, 65 Falkor, 66 Kryo, 67 NeoverseE1, 68 NeoverseN1, 69 NeoverseN2, 70 NeoverseV1, 71 Saphira, 72 ThunderX2T99, 73 ThunderX, 74 ThunderXT81, 75 ThunderXT83, 76 ThunderXT88, 77 ThunderX3T110, 78 TSV110 79 }; 80 81 protected: 82 /// ARMProcFamily - ARM processor family: Cortex-A53, Cortex-A57, and others. 83 ARMProcFamilyEnum ARMProcFamily = Others; 84 85 bool HasV8_1aOps = false; 86 bool HasV8_2aOps = false; 87 bool HasV8_3aOps = false; 88 bool HasV8_4aOps = false; 89 bool HasV8_5aOps = false; 90 bool HasV8_6aOps = false; 91 bool HasV8_7aOps = false; 92 93 bool HasV8_0rOps = false; 94 bool HasCONTEXTIDREL2 = false; 95 96 bool HasFPARMv8 = false; 97 bool HasNEON = false; 98 bool HasCrypto = false; 99 bool HasDotProd = false; 100 bool HasCRC = false; 101 bool HasLSE = false; 102 bool HasRAS = false; 103 bool HasRDM = false; 104 bool HasPerfMon = false; 105 bool HasFullFP16 = false; 106 bool HasFP16FML = false; 107 bool HasSPE = false; 108 109 // ARMv8.1 extensions 110 bool HasVH = false; 111 bool HasPAN = false; 112 bool HasLOR = false; 113 114 // ARMv8.2 extensions 115 bool HasPsUAO = false; 116 bool HasPAN_RWV = false; 117 bool HasCCPP = false; 118 119 // SVE extensions 120 bool HasSVE = false; 121 bool UseExperimentalZeroingPseudos = false; 122 123 // Armv8.2 Crypto extensions 124 bool HasSM4 = false; 125 bool HasSHA3 = false; 126 bool HasSHA2 = false; 127 bool HasAES = false; 128 129 // ARMv8.3 extensions 130 bool HasPAuth = false; 131 bool HasJS = false; 132 bool HasCCIDX = false; 133 bool HasComplxNum = false; 134 135 // ARMv8.4 extensions 136 bool HasNV = false; 137 bool HasMPAM = false; 138 bool HasDIT = false; 139 bool HasTRACEV8_4 = false; 140 bool HasAM = false; 141 bool HasSEL2 = false; 142 bool HasPMU = false; 143 bool HasTLB_RMI = false; 144 bool HasFlagM = false; 145 bool HasRCPC_IMMO = false; 146 147 bool HasLSLFast = false; 148 bool HasRCPC = false; 149 bool HasAggressiveFMA = false; 150 151 // Armv8.5-A Extensions 152 bool HasAlternativeNZCV = false; 153 bool HasFRInt3264 = false; 154 bool HasSpecRestrict = false; 155 bool HasSSBS = false; 156 bool HasSB = false; 157 bool HasPredRes = false; 158 bool HasCCDP = false; 159 bool HasBTI = false; 160 bool HasRandGen = false; 161 bool HasMTE = false; 162 bool HasTME = false; 163 164 // Armv8.6-A Extensions 165 bool HasBF16 = false; 166 bool HasMatMulInt8 = false; 167 bool HasMatMulFP32 = false; 168 bool HasMatMulFP64 = false; 169 bool HasAMVS = false; 170 bool HasFineGrainedTraps = false; 171 bool HasEnhancedCounterVirtualization = false; 172 173 // Armv8.7-A Extensions 174 bool HasXS = false; 175 bool HasWFxT = false; 176 bool HasHCX = false; 177 bool HasLS64 = false; 178 179 // Arm SVE2 extensions 180 bool HasSVE2 = false; 181 bool HasSVE2AES = false; 182 bool HasSVE2SM4 = false; 183 bool HasSVE2SHA3 = false; 184 bool HasSVE2BitPerm = false; 185 186 // Future architecture extensions. 187 bool HasETE = false; 188 bool HasTRBE = false; 189 bool HasBRBE = false; 190 bool HasPAUTH = false; 191 bool HasSPE_EEF = false; 192 193 // HasZeroCycleRegMove - Has zero-cycle register mov instructions. 194 bool HasZeroCycleRegMove = false; 195 196 // HasZeroCycleZeroing - Has zero-cycle zeroing instructions. 197 bool HasZeroCycleZeroing = false; 198 bool HasZeroCycleZeroingGP = false; 199 bool HasZeroCycleZeroingFP = false; 200 bool HasZeroCycleZeroingFPWorkaround = false; 201 202 // StrictAlign - Disallow unaligned memory accesses. 203 bool StrictAlign = false; 204 205 // NegativeImmediates - transform instructions with negative immediates 206 bool NegativeImmediates = true; 207 208 // Enable 64-bit vectorization in SLP. 209 unsigned MinVectorRegisterBitWidth = 64; 210 211 bool OutlineAtomics = false; 212 bool UseAA = false; 213 bool PredictableSelectIsExpensive = false; 214 bool BalanceFPOps = false; 215 bool CustomAsCheapAsMove = false; 216 bool ExynosAsCheapAsMove = false; 217 bool UsePostRAScheduler = false; 218 bool Misaligned128StoreIsSlow = false; 219 bool Paired128IsSlow = false; 220 bool STRQroIsSlow = false; 221 bool UseAlternateSExtLoadCVTF32Pattern = false; 222 bool HasArithmeticBccFusion = false; 223 bool HasArithmeticCbzFusion = false; 224 bool HasCmpBccFusion = false; 225 bool HasFuseAddress = false; 226 bool HasFuseAES = false; 227 bool HasFuseArithmeticLogic = false; 228 bool HasFuseCCSelect = false; 229 bool HasFuseCryptoEOR = false; 230 bool HasFuseLiterals = false; 231 bool DisableLatencySchedHeuristic = false; 232 bool UseRSqrt = false; 233 bool Force32BitJumpTables = false; 234 bool UseEL1ForTP = false; 235 bool UseEL2ForTP = false; 236 bool UseEL3ForTP = false; 237 bool AllowTaggedGlobals = false; 238 bool HardenSlsRetBr = false; 239 bool HardenSlsBlr = false; 240 uint8_t MaxInterleaveFactor = 2; 241 uint8_t VectorInsertExtractBaseCost = 3; 242 uint16_t CacheLineSize = 0; 243 uint16_t PrefetchDistance = 0; 244 uint16_t MinPrefetchStride = 1; 245 unsigned MaxPrefetchIterationsAhead = UINT_MAX; 246 unsigned PrefFunctionLogAlignment = 0; 247 unsigned PrefLoopLogAlignment = 0; 248 unsigned MaxJumpTableSize = 0; 249 unsigned WideningBaseCost = 0; 250 251 // ReserveXRegister[i] - X#i is not available as a general purpose register. 252 BitVector ReserveXRegister; 253 254 // CustomCallUsedXRegister[i] - X#i call saved. 255 BitVector CustomCallSavedXRegs; 256 257 bool IsLittle; 258 259 /// TargetTriple - What processor and OS we're targeting. 260 Triple TargetTriple; 261 262 AArch64FrameLowering FrameLowering; 263 AArch64InstrInfo InstrInfo; 264 AArch64SelectionDAGInfo TSInfo; 265 AArch64TargetLowering TLInfo; 266 267 /// GlobalISel related APIs. 268 std::unique_ptr<CallLowering> CallLoweringInfo; 269 std::unique_ptr<InlineAsmLowering> InlineAsmLoweringInfo; 270 std::unique_ptr<InstructionSelector> InstSelector; 271 std::unique_ptr<LegalizerInfo> Legalizer; 272 std::unique_ptr<RegisterBankInfo> RegBankInfo; 273 274 private: 275 /// initializeSubtargetDependencies - Initializes using CPUString and the 276 /// passed in feature string so that we can use initializer lists for 277 /// subtarget initialization. 278 AArch64Subtarget &initializeSubtargetDependencies(StringRef FS, 279 StringRef CPUString); 280 281 /// Initialize properties based on the selected processor family. 282 void initializeProperties(); 283 284 public: 285 /// This constructor initializes the data members to match that 286 /// of the specified triple. 287 AArch64Subtarget(const Triple &TT, const std::string &CPU, 288 const std::string &FS, const TargetMachine &TM, 289 bool LittleEndian); 290 291 const AArch64SelectionDAGInfo *getSelectionDAGInfo() const override { 292 return &TSInfo; 293 } 294 const AArch64FrameLowering *getFrameLowering() const override { 295 return &FrameLowering; 296 } 297 const AArch64TargetLowering *getTargetLowering() const override { 298 return &TLInfo; 299 } 300 const AArch64InstrInfo *getInstrInfo() const override { return &InstrInfo; } 301 const AArch64RegisterInfo *getRegisterInfo() const override { 302 return &getInstrInfo()->getRegisterInfo(); 303 } 304 const CallLowering *getCallLowering() const override; 305 const InlineAsmLowering *getInlineAsmLowering() const override; 306 InstructionSelector *getInstructionSelector() const override; 307 const LegalizerInfo *getLegalizerInfo() const override; 308 const RegisterBankInfo *getRegBankInfo() const override; 309 const Triple &getTargetTriple() const { return TargetTriple; } 310 bool enableMachineScheduler() const override { return true; } 311 bool enablePostRAScheduler() const override { 312 return UsePostRAScheduler; 313 } 314 315 /// Returns ARM processor family. 316 /// Avoid this function! CPU specifics should be kept local to this class 317 /// and preferably modeled with SubtargetFeatures or properties in 318 /// initializeProperties(). 319 ARMProcFamilyEnum getProcFamily() const { 320 return ARMProcFamily; 321 } 322 323 bool hasV8_1aOps() const { return HasV8_1aOps; } 324 bool hasV8_2aOps() const { return HasV8_2aOps; } 325 bool hasV8_3aOps() const { return HasV8_3aOps; } 326 bool hasV8_4aOps() const { return HasV8_4aOps; } 327 bool hasV8_5aOps() const { return HasV8_5aOps; } 328 bool hasV8_0rOps() const { return HasV8_0rOps; } 329 330 bool hasZeroCycleRegMove() const { return HasZeroCycleRegMove; } 331 332 bool hasZeroCycleZeroingGP() const { return HasZeroCycleZeroingGP; } 333 334 bool hasZeroCycleZeroingFP() const { return HasZeroCycleZeroingFP; } 335 336 bool hasZeroCycleZeroingFPWorkaround() const { 337 return HasZeroCycleZeroingFPWorkaround; 338 } 339 340 bool requiresStrictAlign() const { return StrictAlign; } 341 342 bool isXRaySupported() const override { return true; } 343 344 unsigned getMinVectorRegisterBitWidth() const { 345 return MinVectorRegisterBitWidth; 346 } 347 348 bool isXRegisterReserved(size_t i) const { return ReserveXRegister[i]; } 349 unsigned getNumXRegisterReserved() const { return ReserveXRegister.count(); } 350 bool isXRegCustomCalleeSaved(size_t i) const { 351 return CustomCallSavedXRegs[i]; 352 } 353 bool hasCustomCallingConv() const { return CustomCallSavedXRegs.any(); } 354 bool hasFPARMv8() const { return HasFPARMv8; } 355 bool hasNEON() const { return HasNEON; } 356 bool hasCrypto() const { return HasCrypto; } 357 bool hasDotProd() const { return HasDotProd; } 358 bool hasCRC() const { return HasCRC; } 359 bool hasLSE() const { return HasLSE; } 360 bool hasRAS() const { return HasRAS; } 361 bool hasRDM() const { return HasRDM; } 362 bool hasSM4() const { return HasSM4; } 363 bool hasSHA3() const { return HasSHA3; } 364 bool hasSHA2() const { return HasSHA2; } 365 bool hasAES() const { return HasAES; } 366 bool hasCONTEXTIDREL2() const { return HasCONTEXTIDREL2; } 367 bool balanceFPOps() const { return BalanceFPOps; } 368 bool predictableSelectIsExpensive() const { 369 return PredictableSelectIsExpensive; 370 } 371 bool hasCustomCheapAsMoveHandling() const { return CustomAsCheapAsMove; } 372 bool hasExynosCheapAsMoveHandling() const { return ExynosAsCheapAsMove; } 373 bool isMisaligned128StoreSlow() const { return Misaligned128StoreIsSlow; } 374 bool isPaired128Slow() const { return Paired128IsSlow; } 375 bool isSTRQroSlow() const { return STRQroIsSlow; } 376 bool useAlternateSExtLoadCVTF32Pattern() const { 377 return UseAlternateSExtLoadCVTF32Pattern; 378 } 379 bool hasArithmeticBccFusion() const { return HasArithmeticBccFusion; } 380 bool hasArithmeticCbzFusion() const { return HasArithmeticCbzFusion; } 381 bool hasCmpBccFusion() const { return HasCmpBccFusion; } 382 bool hasFuseAddress() const { return HasFuseAddress; } 383 bool hasFuseAES() const { return HasFuseAES; } 384 bool hasFuseArithmeticLogic() const { return HasFuseArithmeticLogic; } 385 bool hasFuseCCSelect() const { return HasFuseCCSelect; } 386 bool hasFuseCryptoEOR() const { return HasFuseCryptoEOR; } 387 bool hasFuseLiterals() const { return HasFuseLiterals; } 388 389 /// Return true if the CPU supports any kind of instruction fusion. 390 bool hasFusion() const { 391 return hasArithmeticBccFusion() || hasArithmeticCbzFusion() || 392 hasFuseAES() || hasFuseArithmeticLogic() || 393 hasFuseCCSelect() || hasFuseLiterals(); 394 } 395 396 bool hardenSlsRetBr() const { return HardenSlsRetBr; } 397 bool hardenSlsBlr() const { return HardenSlsBlr; } 398 399 bool useEL1ForTP() const { return UseEL1ForTP; } 400 bool useEL2ForTP() const { return UseEL2ForTP; } 401 bool useEL3ForTP() const { return UseEL3ForTP; } 402 403 bool useRSqrt() const { return UseRSqrt; } 404 bool force32BitJumpTables() const { return Force32BitJumpTables; } 405 unsigned getMaxInterleaveFactor() const { return MaxInterleaveFactor; } 406 unsigned getVectorInsertExtractBaseCost() const { 407 return VectorInsertExtractBaseCost; 408 } 409 unsigned getCacheLineSize() const override { return CacheLineSize; } 410 unsigned getPrefetchDistance() const override { return PrefetchDistance; } 411 unsigned getMinPrefetchStride(unsigned NumMemAccesses, 412 unsigned NumStridedMemAccesses, 413 unsigned NumPrefetches, 414 bool HasCall) const override { 415 return MinPrefetchStride; 416 } 417 unsigned getMaxPrefetchIterationsAhead() const override { 418 return MaxPrefetchIterationsAhead; 419 } 420 unsigned getPrefFunctionLogAlignment() const { 421 return PrefFunctionLogAlignment; 422 } 423 unsigned getPrefLoopLogAlignment() const { return PrefLoopLogAlignment; } 424 425 unsigned getMaximumJumpTableSize() const { return MaxJumpTableSize; } 426 427 unsigned getWideningBaseCost() const { return WideningBaseCost; } 428 429 bool useExperimentalZeroingPseudos() const { 430 return UseExperimentalZeroingPseudos; 431 } 432 433 /// CPU has TBI (top byte of addresses is ignored during HW address 434 /// translation) and OS enables it. 435 bool supportsAddressTopByteIgnored() const; 436 437 bool hasPerfMon() const { return HasPerfMon; } 438 bool hasFullFP16() const { return HasFullFP16; } 439 bool hasFP16FML() const { return HasFP16FML; } 440 bool hasSPE() const { return HasSPE; } 441 bool hasLSLFast() const { return HasLSLFast; } 442 bool hasSVE() const { return HasSVE; } 443 bool hasSVE2() const { return HasSVE2; } 444 bool hasRCPC() const { return HasRCPC; } 445 bool hasAggressiveFMA() const { return HasAggressiveFMA; } 446 bool hasAlternativeNZCV() const { return HasAlternativeNZCV; } 447 bool hasFRInt3264() const { return HasFRInt3264; } 448 bool hasSpecRestrict() const { return HasSpecRestrict; } 449 bool hasSSBS() const { return HasSSBS; } 450 bool hasSB() const { return HasSB; } 451 bool hasPredRes() const { return HasPredRes; } 452 bool hasCCDP() const { return HasCCDP; } 453 bool hasBTI() const { return HasBTI; } 454 bool hasRandGen() const { return HasRandGen; } 455 bool hasMTE() const { return HasMTE; } 456 bool hasTME() const { return HasTME; } 457 bool hasPAUTH() const { return HasPAUTH; } 458 // Arm SVE2 extensions 459 bool hasSVE2AES() const { return HasSVE2AES; } 460 bool hasSVE2SM4() const { return HasSVE2SM4; } 461 bool hasSVE2SHA3() const { return HasSVE2SHA3; } 462 bool hasSVE2BitPerm() const { return HasSVE2BitPerm; } 463 bool hasMatMulInt8() const { return HasMatMulInt8; } 464 bool hasMatMulFP32() const { return HasMatMulFP32; } 465 bool hasMatMulFP64() const { return HasMatMulFP64; } 466 467 // Armv8.6-A Extensions 468 bool hasBF16() const { return HasBF16; } 469 bool hasFineGrainedTraps() const { return HasFineGrainedTraps; } 470 bool hasEnhancedCounterVirtualization() const { 471 return HasEnhancedCounterVirtualization; 472 } 473 474 bool isLittleEndian() const { return IsLittle; } 475 476 bool isTargetDarwin() const { return TargetTriple.isOSDarwin(); } 477 bool isTargetIOS() const { return TargetTriple.isiOS(); } 478 bool isTargetLinux() const { return TargetTriple.isOSLinux(); } 479 bool isTargetWindows() const { return TargetTriple.isOSWindows(); } 480 bool isTargetAndroid() const { return TargetTriple.isAndroid(); } 481 bool isTargetFuchsia() const { return TargetTriple.isOSFuchsia(); } 482 483 bool isTargetCOFF() const { return TargetTriple.isOSBinFormatCOFF(); } 484 bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); } 485 bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); } 486 487 bool isTargetILP32() const { 488 return TargetTriple.isArch32Bit() || 489 TargetTriple.getEnvironment() == Triple::GNUILP32; 490 } 491 492 bool useAA() const override { return UseAA; } 493 494 bool outlineAtomics() const { return OutlineAtomics; } 495 496 bool hasVH() const { return HasVH; } 497 bool hasPAN() const { return HasPAN; } 498 bool hasLOR() const { return HasLOR; } 499 500 bool hasPsUAO() const { return HasPsUAO; } 501 bool hasPAN_RWV() const { return HasPAN_RWV; } 502 bool hasCCPP() const { return HasCCPP; } 503 504 bool hasPAuth() const { return HasPAuth; } 505 bool hasJS() const { return HasJS; } 506 bool hasCCIDX() const { return HasCCIDX; } 507 bool hasComplxNum() const { return HasComplxNum; } 508 509 bool hasNV() const { return HasNV; } 510 bool hasMPAM() const { return HasMPAM; } 511 bool hasDIT() const { return HasDIT; } 512 bool hasTRACEV8_4() const { return HasTRACEV8_4; } 513 bool hasAM() const { return HasAM; } 514 bool hasAMVS() const { return HasAMVS; } 515 bool hasXS() const { return HasXS; } 516 bool hasWFxT() const { return HasWFxT; } 517 bool hasHCX() const { return HasHCX; } 518 bool hasLS64() const { return HasLS64; } 519 bool hasSEL2() const { return HasSEL2; } 520 bool hasPMU() const { return HasPMU; } 521 bool hasTLB_RMI() const { return HasTLB_RMI; } 522 bool hasFlagM() const { return HasFlagM; } 523 bool hasRCPC_IMMO() const { return HasRCPC_IMMO; } 524 525 bool addrSinkUsingGEPs() const override { 526 // Keeping GEPs inbounds is important for exploiting AArch64 527 // addressing-modes in ILP32 mode. 528 return useAA() || isTargetILP32(); 529 } 530 531 bool useSmallAddressing() const { 532 switch (TLInfo.getTargetMachine().getCodeModel()) { 533 case CodeModel::Kernel: 534 // Kernel is currently allowed only for Fuchsia targets, 535 // where it is the same as Small for almost all purposes. 536 case CodeModel::Small: 537 return true; 538 default: 539 return false; 540 } 541 } 542 543 /// ParseSubtargetFeatures - Parses features string setting specified 544 /// subtarget options. Definition of function is auto generated by tblgen. 545 void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS); 546 547 /// ClassifyGlobalReference - Find the target operand flags that describe 548 /// how a global value should be referenced for the current subtarget. 549 unsigned ClassifyGlobalReference(const GlobalValue *GV, 550 const TargetMachine &TM) const; 551 552 unsigned classifyGlobalFunctionReference(const GlobalValue *GV, 553 const TargetMachine &TM) const; 554 555 void overrideSchedPolicy(MachineSchedPolicy &Policy, 556 unsigned NumRegionInstrs) const override; 557 558 bool enableEarlyIfConversion() const override; 559 560 bool enableAdvancedRASplitCost() const override { return true; } 561 562 std::unique_ptr<PBQPRAConstraint> getCustomPBQPConstraints() const override; 563 564 bool isCallingConvWin64(CallingConv::ID CC) const { 565 switch (CC) { 566 case CallingConv::C: 567 case CallingConv::Fast: 568 case CallingConv::Swift: 569 return isTargetWindows(); 570 case CallingConv::Win64: 571 return true; 572 default: 573 return false; 574 } 575 } 576 577 void mirFileLoaded(MachineFunction &MF) const override; 578 579 // Return the known range for the bit length of SVE data registers. A value 580 // of 0 means nothing is known about that particular limit beyong what's 581 // implied by the architecture. 582 unsigned getMaxSVEVectorSizeInBits() const; 583 unsigned getMinSVEVectorSizeInBits() const; 584 bool useSVEForFixedLengthVectors() const; 585 }; 586 } // End llvm namespace 587 588 #endif 589