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