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/InlineAsmLowering.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     A64FX,
43     AppleA7,
44     AppleA10,
45     AppleA11,
46     AppleA12,
47     AppleA13,
48     AppleA14,
49     Carmel,
50     CortexA35,
51     CortexA53,
52     CortexA55,
53     CortexA57,
54     CortexA65,
55     CortexA72,
56     CortexA73,
57     CortexA75,
58     CortexA76,
59     CortexA77,
60     CortexA78,
61     CortexA78C,
62     CortexR82,
63     CortexX1,
64     ExynosM3,
65     Falkor,
66     Kryo,
67     NeoverseE1,
68     NeoverseN1,
69     NeoverseN2,
70     NeoverseV1,
71     Saphira,
72     ThunderX2T99,
73     ThunderX,
74     ThunderXT81,
75     ThunderXT83,
76     ThunderXT88,
77     ThunderX3T110,
78     TSV110
79   };
80 
81 protected:
82   /// ARMProcFamily - ARM processor family: Cortex-A53, Cortex-A57, and others.
83   ARMProcFamilyEnum ARMProcFamily = Others;
84 
85   bool HasV8_1aOps = false;
86   bool HasV8_2aOps = false;
87   bool HasV8_3aOps = false;
88   bool HasV8_4aOps = false;
89   bool HasV8_5aOps = false;
90   bool HasV8_6aOps = false;
91   bool HasV8_7aOps = false;
92   bool HasV9_0aOps = false;
93   bool HasV9_1aOps = false;
94   bool HasV9_2aOps = false;
95 
96   bool HasV8_0rOps = false;
97   bool HasCONTEXTIDREL2 = false;
98 
99   bool HasFPARMv8 = false;
100   bool HasNEON = false;
101   bool HasCrypto = false;
102   bool HasDotProd = false;
103   bool HasCRC = false;
104   bool HasLSE = false;
105   bool HasLSE2 = false;
106   bool HasRAS = false;
107   bool HasRDM = false;
108   bool HasPerfMon = false;
109   bool HasFullFP16 = false;
110   bool HasFP16FML = false;
111   bool HasSPE = false;
112 
113   // ARMv8.1 extensions
114   bool HasVH = false;
115   bool HasPAN = false;
116   bool HasLOR = false;
117 
118   // ARMv8.2 extensions
119   bool HasPsUAO = false;
120   bool HasPAN_RWV = false;
121   bool HasCCPP = false;
122 
123   // SVE extensions
124   bool HasSVE = false;
125   bool UseExperimentalZeroingPseudos = false;
126 
127   // Armv8.2 Crypto extensions
128   bool HasSM4 = false;
129   bool HasSHA3 = false;
130   bool HasSHA2 = false;
131   bool HasAES = false;
132 
133   // ARMv8.3 extensions
134   bool HasPAuth = false;
135   bool HasJS = false;
136   bool HasCCIDX = false;
137   bool HasComplxNum = false;
138 
139   // ARMv8.4 extensions
140   bool HasNV = false;
141   bool HasMPAM = false;
142   bool HasDIT = false;
143   bool HasTRACEV8_4 = false;
144   bool HasAM = false;
145   bool HasSEL2 = false;
146   bool HasTLB_RMI = false;
147   bool HasFlagM = false;
148   bool HasRCPC_IMMO = false;
149 
150   bool HasLSLFast = false;
151   bool HasRCPC = false;
152   bool HasAggressiveFMA = false;
153 
154   // Armv8.5-A Extensions
155   bool HasAlternativeNZCV = false;
156   bool HasFRInt3264 = false;
157   bool HasSpecRestrict = false;
158   bool HasSSBS = false;
159   bool HasSB = false;
160   bool HasPredRes = false;
161   bool HasCCDP = false;
162   bool HasBTI = false;
163   bool HasRandGen = false;
164   bool HasMTE = false;
165   bool HasTME = false;
166 
167   // Armv8.6-A Extensions
168   bool HasBF16 = false;
169   bool HasMatMulInt8 = false;
170   bool HasMatMulFP32 = false;
171   bool HasMatMulFP64 = false;
172   bool HasAMVS = false;
173   bool HasFineGrainedTraps = false;
174   bool HasEnhancedCounterVirtualization = false;
175 
176   // Armv8.7-A Extensions
177   bool HasXS = false;
178   bool HasWFxT = false;
179   bool HasHCX = false;
180   bool HasLS64 = false;
181 
182   // Arm SVE2 extensions
183   bool HasSVE2 = false;
184   bool HasSVE2AES = false;
185   bool HasSVE2SM4 = false;
186   bool HasSVE2SHA3 = false;
187   bool HasSVE2BitPerm = false;
188 
189   // Armv9-A Extensions
190   bool HasRME = false;
191 
192   // Arm Scalable Matrix Extension (SME)
193   bool HasSME = false;
194   bool HasSMEF64 = false;
195   bool HasSMEI64 = false;
196   bool HasStreamingSVE = false;
197 
198   // Future architecture extensions.
199   bool HasETE = false;
200   bool HasTRBE = false;
201   bool HasBRBE = false;
202   bool HasPAUTH = false;
203   bool HasSPE_EEF = false;
204 
205   // HasZeroCycleRegMove - Has zero-cycle register mov instructions.
206   bool HasZeroCycleRegMove = false;
207 
208   // HasZeroCycleZeroing - Has zero-cycle zeroing instructions.
209   bool HasZeroCycleZeroing = false;
210   bool HasZeroCycleZeroingGP = false;
211   bool HasZeroCycleZeroingFPWorkaround = false;
212 
213   // It is generally beneficial to rewrite "fmov s0, wzr" to "movi d0, #0".
214   // as movi is more efficient across all cores. Newer cores can eliminate
215   // fmovs early and there is no difference with movi, but this not true for
216   // all implementations.
217   bool HasZeroCycleZeroingFP = true;
218 
219   // StrictAlign - Disallow unaligned memory accesses.
220   bool StrictAlign = false;
221 
222   // NegativeImmediates - transform instructions with negative immediates
223   bool NegativeImmediates = true;
224 
225   // Enable 64-bit vectorization in SLP.
226   unsigned MinVectorRegisterBitWidth = 64;
227 
228   bool OutlineAtomics = false;
229   bool PredictableSelectIsExpensive = false;
230   bool BalanceFPOps = false;
231   bool CustomAsCheapAsMove = false;
232   bool ExynosAsCheapAsMove = false;
233   bool UsePostRAScheduler = false;
234   bool Misaligned128StoreIsSlow = false;
235   bool Paired128IsSlow = false;
236   bool STRQroIsSlow = false;
237   bool UseAlternateSExtLoadCVTF32Pattern = false;
238   bool HasArithmeticBccFusion = false;
239   bool HasArithmeticCbzFusion = false;
240   bool HasCmpBccFusion = false;
241   bool HasFuseAddress = false;
242   bool HasFuseAES = false;
243   bool HasFuseArithmeticLogic = false;
244   bool HasFuseCCSelect = false;
245   bool HasFuseCryptoEOR = false;
246   bool HasFuseLiterals = false;
247   bool DisableLatencySchedHeuristic = false;
248   bool UseRSqrt = false;
249   bool Force32BitJumpTables = false;
250   bool UseEL1ForTP = false;
251   bool UseEL2ForTP = false;
252   bool UseEL3ForTP = false;
253   bool AllowTaggedGlobals = false;
254   bool HardenSlsRetBr = false;
255   bool HardenSlsBlr = false;
256   bool HardenSlsNoComdat = false;
257   uint8_t MaxInterleaveFactor = 2;
258   uint8_t VectorInsertExtractBaseCost = 3;
259   uint16_t CacheLineSize = 0;
260   uint16_t PrefetchDistance = 0;
261   uint16_t MinPrefetchStride = 1;
262   unsigned MaxPrefetchIterationsAhead = UINT_MAX;
263   unsigned PrefFunctionLogAlignment = 0;
264   unsigned PrefLoopLogAlignment = 0;
265   unsigned MaxJumpTableSize = 0;
266   unsigned WideningBaseCost = 0;
267 
268   // ReserveXRegister[i] - X#i is not available as a general purpose register.
269   BitVector ReserveXRegister;
270 
271   // CustomCallUsedXRegister[i] - X#i call saved.
272   BitVector CustomCallSavedXRegs;
273 
274   bool IsLittle;
275 
276   unsigned MinSVEVectorSizeInBits;
277   unsigned MaxSVEVectorSizeInBits;
278 
279   /// TargetTriple - What processor and OS we're targeting.
280   Triple TargetTriple;
281 
282   AArch64FrameLowering FrameLowering;
283   AArch64InstrInfo InstrInfo;
284   AArch64SelectionDAGInfo TSInfo;
285   AArch64TargetLowering TLInfo;
286 
287   /// GlobalISel related APIs.
288   std::unique_ptr<CallLowering> CallLoweringInfo;
289   std::unique_ptr<InlineAsmLowering> InlineAsmLoweringInfo;
290   std::unique_ptr<InstructionSelector> InstSelector;
291   std::unique_ptr<LegalizerInfo> Legalizer;
292   std::unique_ptr<RegisterBankInfo> RegBankInfo;
293 
294 private:
295   /// initializeSubtargetDependencies - Initializes using CPUString and the
296   /// passed in feature string so that we can use initializer lists for
297   /// subtarget initialization.
298   AArch64Subtarget &initializeSubtargetDependencies(StringRef FS,
299                                                     StringRef CPUString);
300 
301   /// Initialize properties based on the selected processor family.
302   void initializeProperties();
303 
304 public:
305   /// This constructor initializes the data members to match that
306   /// of the specified triple.
307   AArch64Subtarget(const Triple &TT, const std::string &CPU,
308                    const std::string &FS, const TargetMachine &TM,
309                    bool LittleEndian,
310                    unsigned MinSVEVectorSizeInBitsOverride = 0,
311                    unsigned MaxSVEVectorSizeInBitsOverride = 0);
312 
getSelectionDAGInfo()313   const AArch64SelectionDAGInfo *getSelectionDAGInfo() const override {
314     return &TSInfo;
315   }
getFrameLowering()316   const AArch64FrameLowering *getFrameLowering() const override {
317     return &FrameLowering;
318   }
getTargetLowering()319   const AArch64TargetLowering *getTargetLowering() const override {
320     return &TLInfo;
321   }
getInstrInfo()322   const AArch64InstrInfo *getInstrInfo() const override { return &InstrInfo; }
getRegisterInfo()323   const AArch64RegisterInfo *getRegisterInfo() const override {
324     return &getInstrInfo()->getRegisterInfo();
325   }
326   const CallLowering *getCallLowering() const override;
327   const InlineAsmLowering *getInlineAsmLowering() const override;
328   InstructionSelector *getInstructionSelector() const override;
329   const LegalizerInfo *getLegalizerInfo() const override;
330   const RegisterBankInfo *getRegBankInfo() const override;
getTargetTriple()331   const Triple &getTargetTriple() const { return TargetTriple; }
enableMachineScheduler()332   bool enableMachineScheduler() const override { return true; }
enablePostRAScheduler()333   bool enablePostRAScheduler() const override {
334     return UsePostRAScheduler;
335   }
336 
337   /// Returns ARM processor family.
338   /// Avoid this function! CPU specifics should be kept local to this class
339   /// and preferably modeled with SubtargetFeatures or properties in
340   /// initializeProperties().
getProcFamily()341   ARMProcFamilyEnum getProcFamily() const {
342     return ARMProcFamily;
343   }
344 
hasV8_1aOps()345   bool hasV8_1aOps() const { return HasV8_1aOps; }
hasV8_2aOps()346   bool hasV8_2aOps() const { return HasV8_2aOps; }
hasV8_3aOps()347   bool hasV8_3aOps() const { return HasV8_3aOps; }
hasV8_4aOps()348   bool hasV8_4aOps() const { return HasV8_4aOps; }
hasV8_5aOps()349   bool hasV8_5aOps() const { return HasV8_5aOps; }
hasV9_0aOps()350   bool hasV9_0aOps() const { return HasV9_0aOps; }
hasV9_1aOps()351   bool hasV9_1aOps() const { return HasV9_1aOps; }
hasV9_2aOps()352   bool hasV9_2aOps() const { return HasV9_2aOps; }
hasV8_0rOps()353   bool hasV8_0rOps() const { return HasV8_0rOps; }
354 
hasZeroCycleRegMove()355   bool hasZeroCycleRegMove() const { return HasZeroCycleRegMove; }
356 
hasZeroCycleZeroingGP()357   bool hasZeroCycleZeroingGP() const { return HasZeroCycleZeroingGP; }
358 
hasZeroCycleZeroingFP()359   bool hasZeroCycleZeroingFP() const { return HasZeroCycleZeroingFP; }
360 
hasZeroCycleZeroingFPWorkaround()361   bool hasZeroCycleZeroingFPWorkaround() const {
362     return HasZeroCycleZeroingFPWorkaround;
363   }
364 
requiresStrictAlign()365   bool requiresStrictAlign() const { return StrictAlign; }
366 
isXRaySupported()367   bool isXRaySupported() const override { return true; }
368 
getMinVectorRegisterBitWidth()369   unsigned getMinVectorRegisterBitWidth() const {
370     return MinVectorRegisterBitWidth;
371   }
372 
isXRegisterReserved(size_t i)373   bool isXRegisterReserved(size_t i) const { return ReserveXRegister[i]; }
getNumXRegisterReserved()374   unsigned getNumXRegisterReserved() const { return ReserveXRegister.count(); }
isXRegCustomCalleeSaved(size_t i)375   bool isXRegCustomCalleeSaved(size_t i) const {
376     return CustomCallSavedXRegs[i];
377   }
hasCustomCallingConv()378   bool hasCustomCallingConv() const { return CustomCallSavedXRegs.any(); }
hasFPARMv8()379   bool hasFPARMv8() const { return HasFPARMv8; }
hasNEON()380   bool hasNEON() const { return HasNEON; }
hasCrypto()381   bool hasCrypto() const { return HasCrypto; }
hasDotProd()382   bool hasDotProd() const { return HasDotProd; }
hasCRC()383   bool hasCRC() const { return HasCRC; }
hasLSE()384   bool hasLSE() const { return HasLSE; }
hasLSE2()385   bool hasLSE2() const { return HasLSE2; }
hasRAS()386   bool hasRAS() const { return HasRAS; }
hasRDM()387   bool hasRDM() const { return HasRDM; }
hasSM4()388   bool hasSM4() const { return HasSM4; }
hasSHA3()389   bool hasSHA3() const { return HasSHA3; }
hasSHA2()390   bool hasSHA2() const { return HasSHA2; }
hasAES()391   bool hasAES() const { return HasAES; }
hasCONTEXTIDREL2()392   bool hasCONTEXTIDREL2() const { return HasCONTEXTIDREL2; }
balanceFPOps()393   bool balanceFPOps() const { return BalanceFPOps; }
predictableSelectIsExpensive()394   bool predictableSelectIsExpensive() const {
395     return PredictableSelectIsExpensive;
396   }
hasCustomCheapAsMoveHandling()397   bool hasCustomCheapAsMoveHandling() const { return CustomAsCheapAsMove; }
hasExynosCheapAsMoveHandling()398   bool hasExynosCheapAsMoveHandling() const { return ExynosAsCheapAsMove; }
isMisaligned128StoreSlow()399   bool isMisaligned128StoreSlow() const { return Misaligned128StoreIsSlow; }
isPaired128Slow()400   bool isPaired128Slow() const { return Paired128IsSlow; }
isSTRQroSlow()401   bool isSTRQroSlow() const { return STRQroIsSlow; }
useAlternateSExtLoadCVTF32Pattern()402   bool useAlternateSExtLoadCVTF32Pattern() const {
403     return UseAlternateSExtLoadCVTF32Pattern;
404   }
hasArithmeticBccFusion()405   bool hasArithmeticBccFusion() const { return HasArithmeticBccFusion; }
hasArithmeticCbzFusion()406   bool hasArithmeticCbzFusion() const { return HasArithmeticCbzFusion; }
hasCmpBccFusion()407   bool hasCmpBccFusion() const { return HasCmpBccFusion; }
hasFuseAddress()408   bool hasFuseAddress() const { return HasFuseAddress; }
hasFuseAES()409   bool hasFuseAES() const { return HasFuseAES; }
hasFuseArithmeticLogic()410   bool hasFuseArithmeticLogic() const { return HasFuseArithmeticLogic; }
hasFuseCCSelect()411   bool hasFuseCCSelect() const { return HasFuseCCSelect; }
hasFuseCryptoEOR()412   bool hasFuseCryptoEOR() const { return HasFuseCryptoEOR; }
hasFuseLiterals()413   bool hasFuseLiterals() const { return HasFuseLiterals; }
414 
415   /// Return true if the CPU supports any kind of instruction fusion.
hasFusion()416   bool hasFusion() const {
417     return hasArithmeticBccFusion() || hasArithmeticCbzFusion() ||
418            hasFuseAES() || hasFuseArithmeticLogic() ||
419            hasFuseCCSelect() || hasFuseLiterals();
420   }
421 
hardenSlsRetBr()422   bool hardenSlsRetBr() const { return HardenSlsRetBr; }
hardenSlsBlr()423   bool hardenSlsBlr() const { return HardenSlsBlr; }
hardenSlsNoComdat()424   bool hardenSlsNoComdat() const { return HardenSlsNoComdat; }
425 
useEL1ForTP()426   bool useEL1ForTP() const { return UseEL1ForTP; }
useEL2ForTP()427   bool useEL2ForTP() const { return UseEL2ForTP; }
useEL3ForTP()428   bool useEL3ForTP() const { return UseEL3ForTP; }
429 
useRSqrt()430   bool useRSqrt() const { return UseRSqrt; }
force32BitJumpTables()431   bool force32BitJumpTables() const { return Force32BitJumpTables; }
getMaxInterleaveFactor()432   unsigned getMaxInterleaveFactor() const { return MaxInterleaveFactor; }
getVectorInsertExtractBaseCost()433   unsigned getVectorInsertExtractBaseCost() const {
434     return VectorInsertExtractBaseCost;
435   }
getCacheLineSize()436   unsigned getCacheLineSize() const override { return CacheLineSize; }
getPrefetchDistance()437   unsigned getPrefetchDistance() const override { return PrefetchDistance; }
getMinPrefetchStride(unsigned NumMemAccesses,unsigned NumStridedMemAccesses,unsigned NumPrefetches,bool HasCall)438   unsigned getMinPrefetchStride(unsigned NumMemAccesses,
439                                 unsigned NumStridedMemAccesses,
440                                 unsigned NumPrefetches,
441                                 bool HasCall) const override {
442     return MinPrefetchStride;
443   }
getMaxPrefetchIterationsAhead()444   unsigned getMaxPrefetchIterationsAhead() const override {
445     return MaxPrefetchIterationsAhead;
446   }
getPrefFunctionLogAlignment()447   unsigned getPrefFunctionLogAlignment() const {
448     return PrefFunctionLogAlignment;
449   }
getPrefLoopLogAlignment()450   unsigned getPrefLoopLogAlignment() const { return PrefLoopLogAlignment; }
451 
getMaximumJumpTableSize()452   unsigned getMaximumJumpTableSize() const { return MaxJumpTableSize; }
453 
getWideningBaseCost()454   unsigned getWideningBaseCost() const { return WideningBaseCost; }
455 
useExperimentalZeroingPseudos()456   bool useExperimentalZeroingPseudos() const {
457     return UseExperimentalZeroingPseudos;
458   }
459 
460   /// CPU has TBI (top byte of addresses is ignored during HW address
461   /// translation) and OS enables it.
462   bool supportsAddressTopByteIgnored() const;
463 
hasPerfMon()464   bool hasPerfMon() const { return HasPerfMon; }
hasFullFP16()465   bool hasFullFP16() const { return HasFullFP16; }
hasFP16FML()466   bool hasFP16FML() const { return HasFP16FML; }
hasSPE()467   bool hasSPE() const { return HasSPE; }
hasLSLFast()468   bool hasLSLFast() const { return HasLSLFast; }
hasSVE()469   bool hasSVE() const { return HasSVE; }
hasSVE2()470   bool hasSVE2() const { return HasSVE2; }
hasRCPC()471   bool hasRCPC() const { return HasRCPC; }
hasAggressiveFMA()472   bool hasAggressiveFMA() const { return HasAggressiveFMA; }
hasAlternativeNZCV()473   bool hasAlternativeNZCV() const { return HasAlternativeNZCV; }
hasFRInt3264()474   bool hasFRInt3264() const { return HasFRInt3264; }
hasSpecRestrict()475   bool hasSpecRestrict() const { return HasSpecRestrict; }
hasSSBS()476   bool hasSSBS() const { return HasSSBS; }
hasSB()477   bool hasSB() const { return HasSB; }
hasPredRes()478   bool hasPredRes() const { return HasPredRes; }
hasCCDP()479   bool hasCCDP() const { return HasCCDP; }
hasBTI()480   bool hasBTI() const { return HasBTI; }
hasRandGen()481   bool hasRandGen() const { return HasRandGen; }
hasMTE()482   bool hasMTE() const { return HasMTE; }
hasTME()483   bool hasTME() const { return HasTME; }
hasPAUTH()484   bool hasPAUTH() const { return HasPAUTH; }
485   // Arm SVE2 extensions
hasSVE2AES()486   bool hasSVE2AES() const { return HasSVE2AES; }
hasSVE2SM4()487   bool hasSVE2SM4() const { return HasSVE2SM4; }
hasSVE2SHA3()488   bool hasSVE2SHA3() const { return HasSVE2SHA3; }
hasSVE2BitPerm()489   bool hasSVE2BitPerm() const { return HasSVE2BitPerm; }
hasMatMulInt8()490   bool hasMatMulInt8() const { return HasMatMulInt8; }
hasMatMulFP32()491   bool hasMatMulFP32() const { return HasMatMulFP32; }
hasMatMulFP64()492   bool hasMatMulFP64() const { return HasMatMulFP64; }
493 
494   // Armv8.6-A Extensions
hasBF16()495   bool hasBF16() const { return HasBF16; }
hasFineGrainedTraps()496   bool hasFineGrainedTraps() const { return HasFineGrainedTraps; }
hasEnhancedCounterVirtualization()497   bool hasEnhancedCounterVirtualization() const {
498     return HasEnhancedCounterVirtualization;
499   }
500 
501   // Arm Scalable Matrix Extension (SME)
hasSME()502   bool hasSME() const { return HasSME; }
hasSMEF64()503   bool hasSMEF64() const { return HasSMEF64; }
hasSMEI64()504   bool hasSMEI64() const { return HasSMEI64; }
hasStreamingSVE()505   bool hasStreamingSVE() const { return HasStreamingSVE; }
506 
isLittleEndian()507   bool isLittleEndian() const { return IsLittle; }
508 
isTargetDarwin()509   bool isTargetDarwin() const { return TargetTriple.isOSDarwin(); }
isTargetIOS()510   bool isTargetIOS() const { return TargetTriple.isiOS(); }
isTargetLinux()511   bool isTargetLinux() const { return TargetTriple.isOSLinux(); }
isTargetWindows()512   bool isTargetWindows() const { return TargetTriple.isOSWindows(); }
isTargetAndroid()513   bool isTargetAndroid() const { return TargetTriple.isAndroid(); }
isTargetFuchsia()514   bool isTargetFuchsia() const { return TargetTriple.isOSFuchsia(); }
515 
isTargetCOFF()516   bool isTargetCOFF() const { return TargetTriple.isOSBinFormatCOFF(); }
isTargetELF()517   bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }
isTargetMachO()518   bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); }
519 
isTargetILP32()520   bool isTargetILP32() const {
521     return TargetTriple.isArch32Bit() ||
522            TargetTriple.getEnvironment() == Triple::GNUILP32;
523   }
524 
525   bool useAA() const override;
526 
outlineAtomics()527   bool outlineAtomics() const { return OutlineAtomics; }
528 
hasVH()529   bool hasVH() const { return HasVH; }
hasPAN()530   bool hasPAN() const { return HasPAN; }
hasLOR()531   bool hasLOR() const { return HasLOR; }
532 
hasPsUAO()533   bool hasPsUAO() const { return HasPsUAO; }
hasPAN_RWV()534   bool hasPAN_RWV() const { return HasPAN_RWV; }
hasCCPP()535   bool hasCCPP() const { return HasCCPP; }
536 
hasPAuth()537   bool hasPAuth() const { return HasPAuth; }
hasJS()538   bool hasJS() const { return HasJS; }
hasCCIDX()539   bool hasCCIDX() const { return HasCCIDX; }
hasComplxNum()540   bool hasComplxNum() const { return HasComplxNum; }
541 
hasNV()542   bool hasNV() const { return HasNV; }
hasMPAM()543   bool hasMPAM() const { return HasMPAM; }
hasDIT()544   bool hasDIT() const { return HasDIT; }
hasTRACEV8_4()545   bool hasTRACEV8_4() const { return HasTRACEV8_4; }
hasAM()546   bool hasAM() const { return HasAM; }
hasAMVS()547   bool hasAMVS() const { return HasAMVS; }
hasXS()548   bool hasXS() const { return HasXS; }
hasWFxT()549   bool hasWFxT() const { return HasWFxT; }
hasHCX()550   bool hasHCX() const { return HasHCX; }
hasLS64()551   bool hasLS64() const { return HasLS64; }
hasSEL2()552   bool hasSEL2() const { return HasSEL2; }
hasTLB_RMI()553   bool hasTLB_RMI() const { return HasTLB_RMI; }
hasFlagM()554   bool hasFlagM() const { return HasFlagM; }
hasRCPC_IMMO()555   bool hasRCPC_IMMO() const { return HasRCPC_IMMO; }
556 
addrSinkUsingGEPs()557   bool addrSinkUsingGEPs() const override {
558     // Keeping GEPs inbounds is important for exploiting AArch64
559     // addressing-modes in ILP32 mode.
560     return useAA() || isTargetILP32();
561   }
562 
useSmallAddressing()563   bool useSmallAddressing() const {
564     switch (TLInfo.getTargetMachine().getCodeModel()) {
565       case CodeModel::Kernel:
566         // Kernel is currently allowed only for Fuchsia targets,
567         // where it is the same as Small for almost all purposes.
568       case CodeModel::Small:
569         return true;
570       default:
571         return false;
572     }
573   }
574 
575   /// ParseSubtargetFeatures - Parses features string setting specified
576   /// subtarget options.  Definition of function is auto generated by tblgen.
577   void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
578 
579   /// ClassifyGlobalReference - Find the target operand flags that describe
580   /// how a global value should be referenced for the current subtarget.
581   unsigned ClassifyGlobalReference(const GlobalValue *GV,
582                                    const TargetMachine &TM) const;
583 
584   unsigned classifyGlobalFunctionReference(const GlobalValue *GV,
585                                            const TargetMachine &TM) const;
586 
587   void overrideSchedPolicy(MachineSchedPolicy &Policy,
588                            unsigned NumRegionInstrs) const override;
589 
590   bool enableEarlyIfConversion() const override;
591 
enableAdvancedRASplitCost()592   bool enableAdvancedRASplitCost() const override { return false; }
593 
594   std::unique_ptr<PBQPRAConstraint> getCustomPBQPConstraints() const override;
595 
isCallingConvWin64(CallingConv::ID CC)596   bool isCallingConvWin64(CallingConv::ID CC) const {
597     switch (CC) {
598     case CallingConv::C:
599     case CallingConv::Fast:
600     case CallingConv::Swift:
601       return isTargetWindows();
602     case CallingConv::Win64:
603       return true;
604     default:
605       return false;
606     }
607   }
608 
609   /// Return whether FrameLowering should always set the "extended frame
610   /// present" bit in FP, or set it based on a symbol in the runtime.
swiftAsyncContextIsDynamicallySet()611   bool swiftAsyncContextIsDynamicallySet() const {
612     // Older OS versions (particularly system unwinders) are confused by the
613     // Swift extended frame, so when building code that might be run on them we
614     // must dynamically query the concurrency library to determine whether
615     // extended frames should be flagged as present.
616     const Triple &TT = getTargetTriple();
617 
618     unsigned Major, Minor, Micro;
619     TT.getOSVersion(Major, Minor, Micro);
620     switch(TT.getOS()) {
621     default:
622       return false;
623     case Triple::IOS:
624     case Triple::TvOS:
625       return Major < 15;
626     case Triple::WatchOS:
627       return Major < 8;
628     case Triple::MacOSX:
629     case Triple::Darwin:
630       return Major < 12;
631     }
632   }
633 
634   void mirFileLoaded(MachineFunction &MF) const override;
635 
636   // Return the known range for the bit length of SVE data registers. A value
637   // of 0 means nothing is known about that particular limit beyong what's
638   // implied by the architecture.
getMaxSVEVectorSizeInBits()639   unsigned getMaxSVEVectorSizeInBits() const {
640     assert(HasSVE && "Tried to get SVE vector length without SVE support!");
641     return MaxSVEVectorSizeInBits;
642   }
643 
getMinSVEVectorSizeInBits()644   unsigned getMinSVEVectorSizeInBits() const {
645     assert(HasSVE && "Tried to get SVE vector length without SVE support!");
646     return MinSVEVectorSizeInBits;
647   }
648 
649   bool useSVEForFixedLengthVectors() const;
650 };
651 } // End llvm namespace
652 
653 #endif
654