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