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