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