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