xref: /freebsd/contrib/llvm-project/clang/include/clang/Basic/TargetInfo.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1 //===--- TargetInfo.h - Expose information about the target -----*- 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 /// \file
10 /// Defines the clang::TargetInfo interface.
11 ///
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CLANG_BASIC_TARGETINFO_H
15 #define LLVM_CLANG_BASIC_TARGETINFO_H
16 
17 #include "clang/Basic/AddressSpaces.h"
18 #include "clang/Basic/BitmaskEnum.h"
19 #include "clang/Basic/CodeGenOptions.h"
20 #include "clang/Basic/LLVM.h"
21 #include "clang/Basic/LangOptions.h"
22 #include "clang/Basic/Specifiers.h"
23 #include "clang/Basic/TargetCXXABI.h"
24 #include "clang/Basic/TargetOptions.h"
25 #include "llvm/ADT/APFloat.h"
26 #include "llvm/ADT/APInt.h"
27 #include "llvm/ADT/APSInt.h"
28 #include "llvm/ADT/ArrayRef.h"
29 #include "llvm/ADT/IntrusiveRefCntPtr.h"
30 #include "llvm/ADT/SmallSet.h"
31 #include "llvm/ADT/StringMap.h"
32 #include "llvm/ADT/StringRef.h"
33 #include "llvm/ADT/StringSet.h"
34 #include "llvm/Frontend/OpenMP/OMPGridValues.h"
35 #include "llvm/IR/DerivedTypes.h"
36 #include "llvm/Support/DataTypes.h"
37 #include "llvm/Support/Error.h"
38 #include "llvm/Support/VersionTuple.h"
39 #include "llvm/TargetParser/Triple.h"
40 #include <cassert>
41 #include <optional>
42 #include <string>
43 #include <utility>
44 #include <vector>
45 
46 namespace llvm {
47 struct fltSemantics;
48 }
49 
50 namespace clang {
51 class DiagnosticsEngine;
52 class LangOptions;
53 class CodeGenOptions;
54 class MacroBuilder;
55 
56 /// Contains information gathered from parsing the contents of TargetAttr.
57 struct ParsedTargetAttr {
58   std::vector<std::string> Features;
59   StringRef CPU;
60   StringRef Tune;
61   StringRef BranchProtection;
62   StringRef Duplicate;
63   bool operator ==(const ParsedTargetAttr &Other) const {
64     return Duplicate == Other.Duplicate && CPU == Other.CPU &&
65            Tune == Other.Tune && BranchProtection == Other.BranchProtection &&
66            Features == Other.Features;
67   }
68 };
69 
70 namespace Builtin { struct Info; }
71 
72 enum class FloatModeKind {
73   NoFloat = 0,
74   Half = 1 << 0,
75   Float = 1 << 1,
76   Double = 1 << 2,
77   LongDouble = 1 << 3,
78   Float128 = 1 << 4,
79   Ibm128 = 1 << 5,
80   LLVM_MARK_AS_BITMASK_ENUM(Ibm128)
81 };
82 
83 /// Fields controlling how types are laid out in memory; these may need to
84 /// be copied for targets like AMDGPU that base their ABIs on an auxiliary
85 /// CPU target.
86 struct TransferrableTargetInfo {
87   unsigned char PointerWidth, PointerAlign;
88   unsigned char BoolWidth, BoolAlign;
89   unsigned char IntWidth, IntAlign;
90   unsigned char HalfWidth, HalfAlign;
91   unsigned char BFloat16Width, BFloat16Align;
92   unsigned char FloatWidth, FloatAlign;
93   unsigned char DoubleWidth, DoubleAlign;
94   unsigned char LongDoubleWidth, LongDoubleAlign, Float128Align, Ibm128Align;
95   unsigned char LargeArrayMinWidth, LargeArrayAlign;
96   unsigned char LongWidth, LongAlign;
97   unsigned char LongLongWidth, LongLongAlign;
98   unsigned char Int128Align;
99 
100   // This is an optional parameter for targets that
101   // don't use 'LongLongAlign' for '_BitInt' max alignment
102   std::optional<unsigned> BitIntMaxAlign;
103 
104   // Fixed point bit widths
105   unsigned char ShortAccumWidth, ShortAccumAlign;
106   unsigned char AccumWidth, AccumAlign;
107   unsigned char LongAccumWidth, LongAccumAlign;
108   unsigned char ShortFractWidth, ShortFractAlign;
109   unsigned char FractWidth, FractAlign;
110   unsigned char LongFractWidth, LongFractAlign;
111 
112   // If true, unsigned fixed point types have the same number of fractional bits
113   // as their signed counterparts, forcing the unsigned types to have one extra
114   // bit of padding. Otherwise, unsigned fixed point types have
115   // one more fractional bit than its corresponding signed type. This is false
116   // by default.
117   bool PaddingOnUnsignedFixedPoint;
118 
119   // Fixed point integral and fractional bit sizes
120   // Saturated types share the same integral/fractional bits as their
121   // corresponding unsaturated types.
122   // For simplicity, the fractional bits in a _Fract type will be one less the
123   // width of that _Fract type. This leaves all signed _Fract types having no
124   // padding and unsigned _Fract types will only have 1 bit of padding after the
125   // sign if PaddingOnUnsignedFixedPoint is set.
126   unsigned char ShortAccumScale;
127   unsigned char AccumScale;
128   unsigned char LongAccumScale;
129 
130   unsigned char DefaultAlignForAttributeAligned;
131   unsigned char MinGlobalAlign;
132 
133   unsigned short SuitableAlign;
134   unsigned short NewAlign;
135   unsigned MaxVectorAlign;
136   unsigned MaxTLSAlign;
137 
138   const llvm::fltSemantics *HalfFormat, *BFloat16Format, *FloatFormat,
139       *DoubleFormat, *LongDoubleFormat, *Float128Format, *Ibm128Format;
140 
141   ///===---- Target Data Type Query Methods -------------------------------===//
142   enum IntType {
143     NoInt = 0,
144     SignedChar,
145     UnsignedChar,
146     SignedShort,
147     UnsignedShort,
148     SignedInt,
149     UnsignedInt,
150     SignedLong,
151     UnsignedLong,
152     SignedLongLong,
153     UnsignedLongLong
154   };
155 
156 protected:
157   IntType SizeType, IntMaxType, PtrDiffType, IntPtrType, WCharType, WIntType,
158       Char16Type, Char32Type, Int64Type, Int16Type, SigAtomicType,
159       ProcessIDType;
160 
161   /// Whether Objective-C's built-in boolean type should be signed char.
162   ///
163   /// Otherwise, when this flag is not set, the normal built-in boolean type is
164   /// used.
165   LLVM_PREFERRED_TYPE(bool)
166   unsigned UseSignedCharForObjCBool : 1;
167 
168   /// Control whether the alignment of bit-field types is respected when laying
169   /// out structures. If true, then the alignment of the bit-field type will be
170   /// used to (a) impact the alignment of the containing structure, and (b)
171   /// ensure that the individual bit-field will not straddle an alignment
172   /// boundary.
173   LLVM_PREFERRED_TYPE(bool)
174   unsigned UseBitFieldTypeAlignment : 1;
175 
176   /// Whether zero length bitfields (e.g., int : 0;) force alignment of
177   /// the next bitfield.
178   ///
179   /// If the alignment of the zero length bitfield is greater than the member
180   /// that follows it, `bar', `bar' will be aligned as the type of the
181   /// zero-length bitfield.
182   LLVM_PREFERRED_TYPE(bool)
183   unsigned UseZeroLengthBitfieldAlignment : 1;
184 
185   /// Whether zero length bitfield alignment is respected if they are the
186   /// leading members.
187   LLVM_PREFERRED_TYPE(bool)
188   unsigned UseLeadingZeroLengthBitfield : 1;
189 
190   ///  Whether explicit bit field alignment attributes are honored.
191   LLVM_PREFERRED_TYPE(bool)
192   unsigned UseExplicitBitFieldAlignment : 1;
193 
194   /// If non-zero, specifies a fixed alignment value for bitfields that follow
195   /// zero length bitfield, regardless of the zero length bitfield type.
196   unsigned ZeroLengthBitfieldBoundary;
197 
198   /// If non-zero, specifies a maximum alignment to truncate alignment
199   /// specified in the aligned attribute of a static variable to this value.
200   unsigned MaxAlignedAttribute;
201 };
202 
203 /// OpenCL type kinds.
204 enum OpenCLTypeKind : uint8_t {
205   OCLTK_Default,
206   OCLTK_ClkEvent,
207   OCLTK_Event,
208   OCLTK_Image,
209   OCLTK_Pipe,
210   OCLTK_Queue,
211   OCLTK_ReserveID,
212   OCLTK_Sampler,
213 };
214 
215 /// Exposes information about the current target.
216 ///
217 class TargetInfo : public TransferrableTargetInfo,
218                    public RefCountedBase<TargetInfo> {
219   std::shared_ptr<TargetOptions> TargetOpts;
220   llvm::Triple Triple;
221 protected:
222   // Target values set by the ctor of the actual target implementation.  Default
223   // values are specified by the TargetInfo constructor.
224   bool BigEndian;
225   bool TLSSupported;
226   bool VLASupported;
227   bool NoAsmVariants;  // True if {|} are normal characters.
228   bool HasLegalHalfType; // True if the backend supports operations on the half
229                          // LLVM IR type.
230   bool HalfArgsAndReturns;
231   bool HasFloat128;
232   bool HasFloat16;
233   bool HasBFloat16;
234   bool HasFullBFloat16; // True if the backend supports native bfloat16
235                         // arithmetic. Used to determine excess precision
236                         // support in the frontend.
237   bool HasIbm128;
238   bool HasLongDouble;
239   bool HasFPReturn;
240   bool HasStrictFP;
241 
242   unsigned char MaxAtomicPromoteWidth, MaxAtomicInlineWidth;
243   std::string DataLayoutString;
244   const char *UserLabelPrefix;
245   const char *MCountName;
246   unsigned char RegParmMax, SSERegParmMax;
247   TargetCXXABI TheCXXABI;
248   const LangASMap *AddrSpaceMap;
249 
250   mutable StringRef PlatformName;
251   mutable VersionTuple PlatformMinVersion;
252 
253   LLVM_PREFERRED_TYPE(bool)
254   unsigned HasAlignMac68kSupport : 1;
255   LLVM_PREFERRED_TYPE(FloatModeKind)
256   unsigned RealTypeUsesObjCFPRetMask : llvm::BitWidth<FloatModeKind>;
257   LLVM_PREFERRED_TYPE(bool)
258   unsigned ComplexLongDoubleUsesFP2Ret : 1;
259 
260   LLVM_PREFERRED_TYPE(bool)
261   unsigned HasBuiltinMSVaList : 1;
262 
263   LLVM_PREFERRED_TYPE(bool)
264   unsigned IsRenderScriptTarget : 1;
265 
266   LLVM_PREFERRED_TYPE(bool)
267   unsigned HasAArch64SVETypes : 1;
268 
269   LLVM_PREFERRED_TYPE(bool)
270   unsigned HasRISCVVTypes : 1;
271 
272   LLVM_PREFERRED_TYPE(bool)
273   unsigned AllowAMDGPUUnsafeFPAtomics : 1;
274 
275   LLVM_PREFERRED_TYPE(bool)
276   unsigned HasUnalignedAccess : 1;
277 
278   unsigned ARMCDECoprocMask : 8;
279 
280   unsigned MaxOpenCLWorkGroupSize;
281 
282   std::optional<unsigned> MaxBitIntWidth;
283 
284   std::optional<llvm::Triple> DarwinTargetVariantTriple;
285 
286   // TargetInfo Constructor.  Default initializes all fields.
287   TargetInfo(const llvm::Triple &T);
288 
289   // UserLabelPrefix must match DL's getGlobalPrefix() when interpreted
290   // as a DataLayout object.
291   void resetDataLayout(StringRef DL, const char *UserLabelPrefix = "");
292 
293   // Target features that are read-only and should not be disabled/enabled
294   // by command line options. Such features are for emitting predefined
295   // macros or checking availability of builtin functions and can be omitted
296   // in function attributes in IR.
297   llvm::StringSet<> ReadOnlyFeatures;
298 
299 public:
300   /// Construct a target for the given options.
301   ///
302   /// \param Opts - The options to use to initialize the target. The target may
303   /// modify the options to canonicalize the target feature information to match
304   /// what the backend expects.
305   static TargetInfo *
306   CreateTargetInfo(DiagnosticsEngine &Diags,
307                    const std::shared_ptr<TargetOptions> &Opts);
308 
309   virtual ~TargetInfo();
310 
311   /// Retrieve the target options.
getTargetOpts()312   TargetOptions &getTargetOpts() const {
313     assert(TargetOpts && "Missing target options");
314     return *TargetOpts;
315   }
316 
317   /// The different kinds of __builtin_va_list types defined by
318   /// the target implementation.
319   enum BuiltinVaListKind {
320     /// typedef char* __builtin_va_list;
321     CharPtrBuiltinVaList = 0,
322 
323     /// typedef void* __builtin_va_list;
324     VoidPtrBuiltinVaList,
325 
326     /// __builtin_va_list as defined by the AArch64 ABI
327     /// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055a/IHI0055A_aapcs64.pdf
328     AArch64ABIBuiltinVaList,
329 
330     /// __builtin_va_list as defined by the PNaCl ABI:
331     /// http://www.chromium.org/nativeclient/pnacl/bitcode-abi#TOC-Machine-Types
332     PNaClABIBuiltinVaList,
333 
334     /// __builtin_va_list as defined by the Power ABI:
335     /// https://www.power.org
336     ///        /resources/downloads/Power-Arch-32-bit-ABI-supp-1.0-Embedded.pdf
337     PowerABIBuiltinVaList,
338 
339     /// __builtin_va_list as defined by the x86-64 ABI:
340     /// http://refspecs.linuxbase.org/elf/x86_64-abi-0.21.pdf
341     X86_64ABIBuiltinVaList,
342 
343     /// __builtin_va_list as defined by ARM AAPCS ABI
344     /// http://infocenter.arm.com
345     //        /help/topic/com.arm.doc.ihi0042d/IHI0042D_aapcs.pdf
346     AAPCSABIBuiltinVaList,
347 
348     // typedef struct __va_list_tag
349     //   {
350     //     long __gpr;
351     //     long __fpr;
352     //     void *__overflow_arg_area;
353     //     void *__reg_save_area;
354     //   } va_list[1];
355     SystemZBuiltinVaList,
356 
357     // typedef struct __va_list_tag {
358     //    void *__current_saved_reg_area_pointer;
359     //    void *__saved_reg_area_end_pointer;
360     //    void *__overflow_area_pointer;
361     //} va_list;
362     HexagonBuiltinVaList
363   };
364 
365 protected:
366   /// Specify if mangling based on address space map should be used or
367   /// not for language specific address spaces
368   bool UseAddrSpaceMapMangling;
369 
370 public:
getSizeType()371   IntType getSizeType() const { return SizeType; }
getSignedSizeType()372   IntType getSignedSizeType() const {
373     switch (SizeType) {
374     case UnsignedShort:
375       return SignedShort;
376     case UnsignedInt:
377       return SignedInt;
378     case UnsignedLong:
379       return SignedLong;
380     case UnsignedLongLong:
381       return SignedLongLong;
382     default:
383       llvm_unreachable("Invalid SizeType");
384     }
385   }
getIntMaxType()386   IntType getIntMaxType() const { return IntMaxType; }
getUIntMaxType()387   IntType getUIntMaxType() const {
388     return getCorrespondingUnsignedType(IntMaxType);
389   }
getPtrDiffType(LangAS AddrSpace)390   IntType getPtrDiffType(LangAS AddrSpace) const {
391     return AddrSpace == LangAS::Default ? PtrDiffType
392                                         : getPtrDiffTypeV(AddrSpace);
393   }
getUnsignedPtrDiffType(LangAS AddrSpace)394   IntType getUnsignedPtrDiffType(LangAS AddrSpace) const {
395     return getCorrespondingUnsignedType(getPtrDiffType(AddrSpace));
396   }
getIntPtrType()397   IntType getIntPtrType() const { return IntPtrType; }
getUIntPtrType()398   IntType getUIntPtrType() const {
399     return getCorrespondingUnsignedType(IntPtrType);
400   }
getWCharType()401   IntType getWCharType() const { return WCharType; }
getWIntType()402   IntType getWIntType() const { return WIntType; }
getChar16Type()403   IntType getChar16Type() const { return Char16Type; }
getChar32Type()404   IntType getChar32Type() const { return Char32Type; }
getInt64Type()405   IntType getInt64Type() const { return Int64Type; }
getUInt64Type()406   IntType getUInt64Type() const {
407     return getCorrespondingUnsignedType(Int64Type);
408   }
getInt16Type()409   IntType getInt16Type() const { return Int16Type; }
getUInt16Type()410   IntType getUInt16Type() const {
411     return getCorrespondingUnsignedType(Int16Type);
412   }
getSigAtomicType()413   IntType getSigAtomicType() const { return SigAtomicType; }
getProcessIDType()414   IntType getProcessIDType() const { return ProcessIDType; }
415 
getCorrespondingUnsignedType(IntType T)416   static IntType getCorrespondingUnsignedType(IntType T) {
417     switch (T) {
418     case SignedChar:
419       return UnsignedChar;
420     case SignedShort:
421       return UnsignedShort;
422     case SignedInt:
423       return UnsignedInt;
424     case SignedLong:
425       return UnsignedLong;
426     case SignedLongLong:
427       return UnsignedLongLong;
428     default:
429       llvm_unreachable("Unexpected signed integer type");
430     }
431   }
432 
433   /// In the event this target uses the same number of fractional bits for its
434   /// unsigned types as it does with its signed counterparts, there will be
435   /// exactly one bit of padding.
436   /// Return true if unsigned fixed point types have padding for this target.
doUnsignedFixedPointTypesHavePadding()437   bool doUnsignedFixedPointTypesHavePadding() const {
438     return PaddingOnUnsignedFixedPoint;
439   }
440 
441   /// Return the width (in bits) of the specified integer type enum.
442   ///
443   /// For example, SignedInt -> getIntWidth().
444   unsigned getTypeWidth(IntType T) const;
445 
446   /// Return integer type with specified width.
447   virtual IntType getIntTypeByWidth(unsigned BitWidth, bool IsSigned) const;
448 
449   /// Return the smallest integer type with at least the specified width.
450   virtual IntType getLeastIntTypeByWidth(unsigned BitWidth,
451                                          bool IsSigned) const;
452 
453   /// Return floating point type with specified width. On PPC, there are
454   /// three possible types for 128-bit floating point: "PPC double-double",
455   /// IEEE 754R quad precision, and "long double" (which under the covers
456   /// is represented as one of those two). At this time, there is no support
457   /// for an explicit "PPC double-double" type (i.e. __ibm128) so we only
458   /// need to differentiate between "long double" and IEEE quad precision.
459   FloatModeKind getRealTypeByWidth(unsigned BitWidth,
460                                    FloatModeKind ExplicitType) const;
461 
462   /// Return the alignment (in bits) of the specified integer type enum.
463   ///
464   /// For example, SignedInt -> getIntAlign().
465   unsigned getTypeAlign(IntType T) const;
466 
467   /// Returns true if the type is signed; false otherwise.
468   static bool isTypeSigned(IntType T);
469 
470   /// Return the width of pointers on this target, for the
471   /// specified address space.
getPointerWidth(LangAS AddrSpace)472   uint64_t getPointerWidth(LangAS AddrSpace) const {
473     return AddrSpace == LangAS::Default ? PointerWidth
474                                         : getPointerWidthV(AddrSpace);
475   }
getPointerAlign(LangAS AddrSpace)476   uint64_t getPointerAlign(LangAS AddrSpace) const {
477     return AddrSpace == LangAS::Default ? PointerAlign
478                                         : getPointerAlignV(AddrSpace);
479   }
480 
481   /// Return the maximum width of pointers on this target.
getMaxPointerWidth()482   virtual uint64_t getMaxPointerWidth() const {
483     return PointerWidth;
484   }
485 
486   /// Get integer value for null pointer.
487   /// \param AddrSpace address space of pointee in source language.
getNullPointerValue(LangAS AddrSpace)488   virtual uint64_t getNullPointerValue(LangAS AddrSpace) const { return 0; }
489 
490   /// Return the size of '_Bool' and C++ 'bool' for this target, in bits.
getBoolWidth()491   unsigned getBoolWidth() const { return BoolWidth; }
492 
493   /// Return the alignment of '_Bool' and C++ 'bool' for this target.
getBoolAlign()494   unsigned getBoolAlign() const { return BoolAlign; }
495 
getCharWidth()496   unsigned getCharWidth() const { return 8; } // FIXME
getCharAlign()497   unsigned getCharAlign() const { return 8; } // FIXME
498 
499   /// Return the size of 'signed short' and 'unsigned short' for this
500   /// target, in bits.
getShortWidth()501   unsigned getShortWidth() const { return 16; } // FIXME
502 
503   /// Return the alignment of 'signed short' and 'unsigned short' for
504   /// this target.
getShortAlign()505   unsigned getShortAlign() const { return 16; } // FIXME
506 
507   /// getIntWidth/Align - Return the size of 'signed int' and 'unsigned int' for
508   /// this target, in bits.
getIntWidth()509   unsigned getIntWidth() const { return IntWidth; }
getIntAlign()510   unsigned getIntAlign() const { return IntAlign; }
511 
512   /// getLongWidth/Align - Return the size of 'signed long' and 'unsigned long'
513   /// for this target, in bits.
getLongWidth()514   unsigned getLongWidth() const { return LongWidth; }
getLongAlign()515   unsigned getLongAlign() const { return LongAlign; }
516 
517   /// getLongLongWidth/Align - Return the size of 'signed long long' and
518   /// 'unsigned long long' for this target, in bits.
getLongLongWidth()519   unsigned getLongLongWidth() const { return LongLongWidth; }
getLongLongAlign()520   unsigned getLongLongAlign() const { return LongLongAlign; }
521 
522   /// getInt128Align() - Returns the alignment of Int128.
getInt128Align()523   unsigned getInt128Align() const { return Int128Align; }
524 
525   /// getBitIntMaxAlign() - Returns the maximum possible alignment of
526   /// '_BitInt' and 'unsigned _BitInt'.
getBitIntMaxAlign()527   unsigned getBitIntMaxAlign() const {
528     return BitIntMaxAlign.value_or(LongLongAlign);
529   }
530 
531   /// getBitIntAlign/Width - Return aligned size of '_BitInt' and
532   /// 'unsigned _BitInt' for this target, in bits.
getBitIntWidth(unsigned NumBits)533   unsigned getBitIntWidth(unsigned NumBits) const {
534     return llvm::alignTo(NumBits, getBitIntAlign(NumBits));
535   }
getBitIntAlign(unsigned NumBits)536   unsigned getBitIntAlign(unsigned NumBits) const {
537     return std::clamp<unsigned>(llvm::PowerOf2Ceil(NumBits), getCharWidth(),
538                                 getBitIntMaxAlign());
539   }
540 
541   /// getShortAccumWidth/Align - Return the size of 'signed short _Accum' and
542   /// 'unsigned short _Accum' for this target, in bits.
getShortAccumWidth()543   unsigned getShortAccumWidth() const { return ShortAccumWidth; }
getShortAccumAlign()544   unsigned getShortAccumAlign() const { return ShortAccumAlign; }
545 
546   /// getAccumWidth/Align - Return the size of 'signed _Accum' and
547   /// 'unsigned _Accum' for this target, in bits.
getAccumWidth()548   unsigned getAccumWidth() const { return AccumWidth; }
getAccumAlign()549   unsigned getAccumAlign() const { return AccumAlign; }
550 
551   /// getLongAccumWidth/Align - Return the size of 'signed long _Accum' and
552   /// 'unsigned long _Accum' for this target, in bits.
getLongAccumWidth()553   unsigned getLongAccumWidth() const { return LongAccumWidth; }
getLongAccumAlign()554   unsigned getLongAccumAlign() const { return LongAccumAlign; }
555 
556   /// getShortFractWidth/Align - Return the size of 'signed short _Fract' and
557   /// 'unsigned short _Fract' for this target, in bits.
getShortFractWidth()558   unsigned getShortFractWidth() const { return ShortFractWidth; }
getShortFractAlign()559   unsigned getShortFractAlign() const { return ShortFractAlign; }
560 
561   /// getFractWidth/Align - Return the size of 'signed _Fract' and
562   /// 'unsigned _Fract' for this target, in bits.
getFractWidth()563   unsigned getFractWidth() const { return FractWidth; }
getFractAlign()564   unsigned getFractAlign() const { return FractAlign; }
565 
566   /// getLongFractWidth/Align - Return the size of 'signed long _Fract' and
567   /// 'unsigned long _Fract' for this target, in bits.
getLongFractWidth()568   unsigned getLongFractWidth() const { return LongFractWidth; }
getLongFractAlign()569   unsigned getLongFractAlign() const { return LongFractAlign; }
570 
571   /// getShortAccumScale/IBits - Return the number of fractional/integral bits
572   /// in a 'signed short _Accum' type.
getShortAccumScale()573   unsigned getShortAccumScale() const { return ShortAccumScale; }
getShortAccumIBits()574   unsigned getShortAccumIBits() const {
575     return ShortAccumWidth - ShortAccumScale - 1;
576   }
577 
578   /// getAccumScale/IBits - Return the number of fractional/integral bits
579   /// in a 'signed _Accum' type.
getAccumScale()580   unsigned getAccumScale() const { return AccumScale; }
getAccumIBits()581   unsigned getAccumIBits() const { return AccumWidth - AccumScale - 1; }
582 
583   /// getLongAccumScale/IBits - Return the number of fractional/integral bits
584   /// in a 'signed long _Accum' type.
getLongAccumScale()585   unsigned getLongAccumScale() const { return LongAccumScale; }
getLongAccumIBits()586   unsigned getLongAccumIBits() const {
587     return LongAccumWidth - LongAccumScale - 1;
588   }
589 
590   /// getUnsignedShortAccumScale/IBits - Return the number of
591   /// fractional/integral bits in a 'unsigned short _Accum' type.
getUnsignedShortAccumScale()592   unsigned getUnsignedShortAccumScale() const {
593     return PaddingOnUnsignedFixedPoint ? ShortAccumScale : ShortAccumScale + 1;
594   }
getUnsignedShortAccumIBits()595   unsigned getUnsignedShortAccumIBits() const {
596     return PaddingOnUnsignedFixedPoint
597                ? getShortAccumIBits()
598                : ShortAccumWidth - getUnsignedShortAccumScale();
599   }
600 
601   /// getUnsignedAccumScale/IBits - Return the number of fractional/integral
602   /// bits in a 'unsigned _Accum' type.
getUnsignedAccumScale()603   unsigned getUnsignedAccumScale() const {
604     return PaddingOnUnsignedFixedPoint ? AccumScale : AccumScale + 1;
605   }
getUnsignedAccumIBits()606   unsigned getUnsignedAccumIBits() const {
607     return PaddingOnUnsignedFixedPoint ? getAccumIBits()
608                                        : AccumWidth - getUnsignedAccumScale();
609   }
610 
611   /// getUnsignedLongAccumScale/IBits - Return the number of fractional/integral
612   /// bits in a 'unsigned long _Accum' type.
getUnsignedLongAccumScale()613   unsigned getUnsignedLongAccumScale() const {
614     return PaddingOnUnsignedFixedPoint ? LongAccumScale : LongAccumScale + 1;
615   }
getUnsignedLongAccumIBits()616   unsigned getUnsignedLongAccumIBits() const {
617     return PaddingOnUnsignedFixedPoint
618                ? getLongAccumIBits()
619                : LongAccumWidth - getUnsignedLongAccumScale();
620   }
621 
622   /// getShortFractScale - Return the number of fractional bits
623   /// in a 'signed short _Fract' type.
getShortFractScale()624   unsigned getShortFractScale() const { return ShortFractWidth - 1; }
625 
626   /// getFractScale - Return the number of fractional bits
627   /// in a 'signed _Fract' type.
getFractScale()628   unsigned getFractScale() const { return FractWidth - 1; }
629 
630   /// getLongFractScale - Return the number of fractional bits
631   /// in a 'signed long _Fract' type.
getLongFractScale()632   unsigned getLongFractScale() const { return LongFractWidth - 1; }
633 
634   /// getUnsignedShortFractScale - Return the number of fractional bits
635   /// in a 'unsigned short _Fract' type.
getUnsignedShortFractScale()636   unsigned getUnsignedShortFractScale() const {
637     return PaddingOnUnsignedFixedPoint ? getShortFractScale()
638                                        : getShortFractScale() + 1;
639   }
640 
641   /// getUnsignedFractScale - Return the number of fractional bits
642   /// in a 'unsigned _Fract' type.
getUnsignedFractScale()643   unsigned getUnsignedFractScale() const {
644     return PaddingOnUnsignedFixedPoint ? getFractScale() : getFractScale() + 1;
645   }
646 
647   /// getUnsignedLongFractScale - Return the number of fractional bits
648   /// in a 'unsigned long _Fract' type.
getUnsignedLongFractScale()649   unsigned getUnsignedLongFractScale() const {
650     return PaddingOnUnsignedFixedPoint ? getLongFractScale()
651                                        : getLongFractScale() + 1;
652   }
653 
654   /// Determine whether the __int128 type is supported on this target.
hasInt128Type()655   virtual bool hasInt128Type() const {
656     return (getPointerWidth(LangAS::Default) >= 64) ||
657            getTargetOpts().ForceEnableInt128;
658   } // FIXME
659 
660   /// Determine whether the _BitInt type is supported on this target. This
661   /// limitation is put into place for ABI reasons.
662   /// FIXME: _BitInt is a required type in C23, so there's not much utility in
663   /// asking whether the target supported it or not; I think this should be
664   /// removed once backends have been alerted to the type and have had the
665   /// chance to do implementation work if needed.
hasBitIntType()666   virtual bool hasBitIntType() const {
667     return false;
668   }
669 
670   // Different targets may support a different maximum width for the _BitInt
671   // type, depending on what operations are supported.
getMaxBitIntWidth()672   virtual size_t getMaxBitIntWidth() const {
673     // Consider -fexperimental-max-bitint-width= first.
674     if (MaxBitIntWidth)
675       return std::min<size_t>(*MaxBitIntWidth, llvm::IntegerType::MAX_INT_BITS);
676 
677     // FIXME: this value should be llvm::IntegerType::MAX_INT_BITS, which is
678     // maximum bit width that LLVM claims its IR can support. However, most
679     // backends currently have a bug where they only support float to int
680     // conversion (and vice versa) on types that are <= 128 bits and crash
681     // otherwise. We're setting the max supported value to 128 to be
682     // conservative.
683     return 128;
684   }
685 
686   /// Determine whether _Float16 is supported on this target.
hasLegalHalfType()687   virtual bool hasLegalHalfType() const { return HasLegalHalfType; }
688 
689   /// Whether half args and returns are supported.
allowHalfArgsAndReturns()690   virtual bool allowHalfArgsAndReturns() const { return HalfArgsAndReturns; }
691 
692   /// Determine whether the __float128 type is supported on this target.
hasFloat128Type()693   virtual bool hasFloat128Type() const { return HasFloat128; }
694 
695   /// Determine whether the _Float16 type is supported on this target.
hasFloat16Type()696   virtual bool hasFloat16Type() const { return HasFloat16; }
697 
698   /// Determine whether the _BFloat16 type is supported on this target.
hasBFloat16Type()699   virtual bool hasBFloat16Type() const {
700     return HasBFloat16 || HasFullBFloat16;
701   }
702 
703   /// Determine whether the BFloat type is fully supported on this target, i.e
704   /// arithemtic operations.
hasFullBFloat16Type()705   virtual bool hasFullBFloat16Type() const { return HasFullBFloat16; }
706 
707   /// Determine whether the __ibm128 type is supported on this target.
hasIbm128Type()708   virtual bool hasIbm128Type() const { return HasIbm128; }
709 
710   /// Determine whether the long double type is supported on this target.
hasLongDoubleType()711   virtual bool hasLongDoubleType() const { return HasLongDouble; }
712 
713   /// Determine whether return of a floating point value is supported
714   /// on this target.
hasFPReturn()715   virtual bool hasFPReturn() const { return HasFPReturn; }
716 
717   /// Determine whether constrained floating point is supported on this target.
hasStrictFP()718   virtual bool hasStrictFP() const { return HasStrictFP; }
719 
720   /// Return the alignment that is the largest alignment ever used for any
721   /// scalar/SIMD data type on the target machine you are compiling for
722   /// (including types with an extended alignment requirement).
getSuitableAlign()723   unsigned getSuitableAlign() const { return SuitableAlign; }
724 
725   /// Return the default alignment for __attribute__((aligned)) on
726   /// this target, to be used if no alignment value is specified.
getDefaultAlignForAttributeAligned()727   unsigned getDefaultAlignForAttributeAligned() const {
728     return DefaultAlignForAttributeAligned;
729   }
730 
731   /// getMinGlobalAlign - Return the minimum alignment of a global variable,
732   /// unless its alignment is explicitly reduced via attributes. If \param
733   /// HasNonWeakDef is true, this concerns a VarDecl which has a definition
734   /// in current translation unit and that is not weak.
getMinGlobalAlign(uint64_t Size,bool HasNonWeakDef)735   virtual unsigned getMinGlobalAlign(uint64_t Size, bool HasNonWeakDef) const {
736     return MinGlobalAlign;
737   }
738 
739   /// Return the largest alignment for which a suitably-sized allocation with
740   /// '::operator new(size_t)' is guaranteed to produce a correctly-aligned
741   /// pointer.
getNewAlign()742   unsigned getNewAlign() const {
743     return NewAlign ? NewAlign : std::max(LongDoubleAlign, LongLongAlign);
744   }
745 
746   /// getWCharWidth/Align - Return the size of 'wchar_t' for this target, in
747   /// bits.
getWCharWidth()748   unsigned getWCharWidth() const { return getTypeWidth(WCharType); }
getWCharAlign()749   unsigned getWCharAlign() const { return getTypeAlign(WCharType); }
750 
751   /// getChar16Width/Align - Return the size of 'char16_t' for this target, in
752   /// bits.
getChar16Width()753   unsigned getChar16Width() const { return getTypeWidth(Char16Type); }
getChar16Align()754   unsigned getChar16Align() const { return getTypeAlign(Char16Type); }
755 
756   /// getChar32Width/Align - Return the size of 'char32_t' for this target, in
757   /// bits.
getChar32Width()758   unsigned getChar32Width() const { return getTypeWidth(Char32Type); }
getChar32Align()759   unsigned getChar32Align() const { return getTypeAlign(Char32Type); }
760 
761   /// getHalfWidth/Align/Format - Return the size/align/format of 'half'.
getHalfWidth()762   unsigned getHalfWidth() const { return HalfWidth; }
getHalfAlign()763   unsigned getHalfAlign() const { return HalfAlign; }
getHalfFormat()764   const llvm::fltSemantics &getHalfFormat() const { return *HalfFormat; }
765 
766   /// getFloatWidth/Align/Format - Return the size/align/format of 'float'.
getFloatWidth()767   unsigned getFloatWidth() const { return FloatWidth; }
getFloatAlign()768   unsigned getFloatAlign() const { return FloatAlign; }
getFloatFormat()769   const llvm::fltSemantics &getFloatFormat() const { return *FloatFormat; }
770 
771   /// getBFloat16Width/Align/Format - Return the size/align/format of '__bf16'.
getBFloat16Width()772   unsigned getBFloat16Width() const { return BFloat16Width; }
getBFloat16Align()773   unsigned getBFloat16Align() const { return BFloat16Align; }
getBFloat16Format()774   const llvm::fltSemantics &getBFloat16Format() const { return *BFloat16Format; }
775 
776   /// getDoubleWidth/Align/Format - Return the size/align/format of 'double'.
getDoubleWidth()777   unsigned getDoubleWidth() const { return DoubleWidth; }
getDoubleAlign()778   unsigned getDoubleAlign() const { return DoubleAlign; }
getDoubleFormat()779   const llvm::fltSemantics &getDoubleFormat() const { return *DoubleFormat; }
780 
781   /// getLongDoubleWidth/Align/Format - Return the size/align/format of 'long
782   /// double'.
getLongDoubleWidth()783   unsigned getLongDoubleWidth() const { return LongDoubleWidth; }
getLongDoubleAlign()784   unsigned getLongDoubleAlign() const { return LongDoubleAlign; }
getLongDoubleFormat()785   const llvm::fltSemantics &getLongDoubleFormat() const {
786     return *LongDoubleFormat;
787   }
788 
789   /// getFloat128Width/Align/Format - Return the size/align/format of
790   /// '__float128'.
getFloat128Width()791   unsigned getFloat128Width() const { return 128; }
getFloat128Align()792   unsigned getFloat128Align() const { return Float128Align; }
getFloat128Format()793   const llvm::fltSemantics &getFloat128Format() const {
794     return *Float128Format;
795   }
796 
797   /// getIbm128Width/Align/Format - Return the size/align/format of
798   /// '__ibm128'.
getIbm128Width()799   unsigned getIbm128Width() const { return 128; }
getIbm128Align()800   unsigned getIbm128Align() const { return Ibm128Align; }
getIbm128Format()801   const llvm::fltSemantics &getIbm128Format() const { return *Ibm128Format; }
802 
803   /// Return the mangled code of long double.
getLongDoubleMangling()804   virtual const char *getLongDoubleMangling() const { return "e"; }
805 
806   /// Return the mangled code of __float128.
getFloat128Mangling()807   virtual const char *getFloat128Mangling() const { return "g"; }
808 
809   /// Return the mangled code of __ibm128.
getIbm128Mangling()810   virtual const char *getIbm128Mangling() const {
811     llvm_unreachable("ibm128 not implemented on this target");
812   }
813 
814   /// Return the mangled code of bfloat.
getBFloat16Mangling()815   virtual const char *getBFloat16Mangling() const { return "DF16b"; }
816 
817   /// Return the value for the C99 FLT_EVAL_METHOD macro.
getFPEvalMethod()818   virtual LangOptions::FPEvalMethodKind getFPEvalMethod() const {
819     return LangOptions::FPEvalMethodKind::FEM_Source;
820   }
821 
supportSourceEvalMethod()822   virtual bool supportSourceEvalMethod() const { return true; }
823 
824   // getLargeArrayMinWidth/Align - Return the minimum array size that is
825   // 'large' and its alignment.
getLargeArrayMinWidth()826   unsigned getLargeArrayMinWidth() const { return LargeArrayMinWidth; }
getLargeArrayAlign()827   unsigned getLargeArrayAlign() const { return LargeArrayAlign; }
828 
829   /// Return the maximum width lock-free atomic operation which will
830   /// ever be supported for the given target
getMaxAtomicPromoteWidth()831   unsigned getMaxAtomicPromoteWidth() const { return MaxAtomicPromoteWidth; }
832   /// Return the maximum width lock-free atomic operation which can be
833   /// inlined given the supported features of the given target.
getMaxAtomicInlineWidth()834   unsigned getMaxAtomicInlineWidth() const { return MaxAtomicInlineWidth; }
835   /// Set the maximum inline or promote width lock-free atomic operation
836   /// for the given target.
setMaxAtomicWidth()837   virtual void setMaxAtomicWidth() {}
838   /// Returns true if the given target supports lock-free atomic
839   /// operations at the specified width and alignment.
hasBuiltinAtomic(uint64_t AtomicSizeInBits,uint64_t AlignmentInBits)840   virtual bool hasBuiltinAtomic(uint64_t AtomicSizeInBits,
841                                 uint64_t AlignmentInBits) const {
842     return AtomicSizeInBits <= AlignmentInBits &&
843            AtomicSizeInBits <= getMaxAtomicInlineWidth() &&
844            (AtomicSizeInBits <= getCharWidth() ||
845             llvm::isPowerOf2_64(AtomicSizeInBits / getCharWidth()));
846   }
847 
848   /// Return the maximum vector alignment supported for the given target.
getMaxVectorAlign()849   unsigned getMaxVectorAlign() const { return MaxVectorAlign; }
850 
getMaxOpenCLWorkGroupSize()851   unsigned getMaxOpenCLWorkGroupSize() const { return MaxOpenCLWorkGroupSize; }
852 
853   /// Return the alignment (in bits) of the thrown exception object. This is
854   /// only meaningful for targets that allocate C++ exceptions in a system
855   /// runtime, such as those using the Itanium C++ ABI.
getExnObjectAlignment()856   virtual unsigned getExnObjectAlignment() const {
857     // Itanium says that an _Unwind_Exception has to be "double-word"
858     // aligned (and thus the end of it is also so-aligned), meaning 16
859     // bytes.  Of course, that was written for the actual Itanium,
860     // which is a 64-bit platform.  Classically, the ABI doesn't really
861     // specify the alignment on other platforms, but in practice
862     // libUnwind declares the struct with __attribute__((aligned)), so
863     // we assume that alignment here.  (It's generally 16 bytes, but
864     // some targets overwrite it.)
865     return getDefaultAlignForAttributeAligned();
866   }
867 
868   /// Return the size of intmax_t and uintmax_t for this target, in bits.
getIntMaxTWidth()869   unsigned getIntMaxTWidth() const {
870     return getTypeWidth(IntMaxType);
871   }
872 
873   // Return the size of unwind_word for this target.
getUnwindWordWidth()874   virtual unsigned getUnwindWordWidth() const {
875     return getPointerWidth(LangAS::Default);
876   }
877 
878   /// Return the "preferred" register width on this target.
getRegisterWidth()879   virtual unsigned getRegisterWidth() const {
880     // Currently we assume the register width on the target matches the pointer
881     // width, we can introduce a new variable for this if/when some target wants
882     // it.
883     return PointerWidth;
884   }
885 
886   /// Return true iff unaligned accesses are a single instruction (rather than
887   /// a synthesized sequence).
hasUnalignedAccess()888   bool hasUnalignedAccess() const { return HasUnalignedAccess; }
889 
890   /// Return true iff unaligned accesses are cheap. This affects placement and
891   /// size of bitfield loads/stores. (Not the ABI-mandated placement of
892   /// the bitfields themselves.)
hasCheapUnalignedBitFieldAccess()893   bool hasCheapUnalignedBitFieldAccess() const {
894     // Simply forward to the unaligned access getter.
895     return hasUnalignedAccess();
896   }
897 
898   /// \brief Returns the default value of the __USER_LABEL_PREFIX__ macro,
899   /// which is the prefix given to user symbols by default.
900   ///
901   /// On most platforms this is "", but it is "_" on some.
getUserLabelPrefix()902   const char *getUserLabelPrefix() const { return UserLabelPrefix; }
903 
904   /// Returns the name of the mcount instrumentation function.
getMCountName()905   const char *getMCountName() const {
906     return MCountName;
907   }
908 
909   /// Check if the Objective-C built-in boolean type should be signed
910   /// char.
911   ///
912   /// Otherwise, if this returns false, the normal built-in boolean type
913   /// should also be used for Objective-C.
useSignedCharForObjCBool()914   bool useSignedCharForObjCBool() const {
915     return UseSignedCharForObjCBool;
916   }
noSignedCharForObjCBool()917   void noSignedCharForObjCBool() {
918     UseSignedCharForObjCBool = false;
919   }
920 
921   /// Check whether the alignment of bit-field types is respected
922   /// when laying out structures.
useBitFieldTypeAlignment()923   bool useBitFieldTypeAlignment() const {
924     return UseBitFieldTypeAlignment;
925   }
926 
927   /// Check whether zero length bitfields should force alignment of
928   /// the next member.
useZeroLengthBitfieldAlignment()929   bool useZeroLengthBitfieldAlignment() const {
930     return UseZeroLengthBitfieldAlignment;
931   }
932 
933   /// Check whether zero length bitfield alignment is respected if they are
934   /// leading members.
useLeadingZeroLengthBitfield()935   bool useLeadingZeroLengthBitfield() const {
936     return UseLeadingZeroLengthBitfield;
937   }
938 
939   /// Get the fixed alignment value in bits for a member that follows
940   /// a zero length bitfield.
getZeroLengthBitfieldBoundary()941   unsigned getZeroLengthBitfieldBoundary() const {
942     return ZeroLengthBitfieldBoundary;
943   }
944 
945   /// Get the maximum alignment in bits for a static variable with
946   /// aligned attribute.
getMaxAlignedAttribute()947   unsigned getMaxAlignedAttribute() const { return MaxAlignedAttribute; }
948 
949   /// Check whether explicit bitfield alignment attributes should be
950   //  honored, as in "__attribute__((aligned(2))) int b : 1;".
useExplicitBitFieldAlignment()951   bool useExplicitBitFieldAlignment() const {
952     return UseExplicitBitFieldAlignment;
953   }
954 
955   /// Check whether this target support '\#pragma options align=mac68k'.
hasAlignMac68kSupport()956   bool hasAlignMac68kSupport() const {
957     return HasAlignMac68kSupport;
958   }
959 
960   /// Return the user string for the specified integer type enum.
961   ///
962   /// For example, SignedShort -> "short".
963   static const char *getTypeName(IntType T);
964 
965   /// Return the constant suffix for the specified integer type enum.
966   ///
967   /// For example, SignedLong -> "L".
968   const char *getTypeConstantSuffix(IntType T) const;
969 
970   /// Return the printf format modifier for the specified
971   /// integer type enum.
972   ///
973   /// For example, SignedLong -> "l".
974   static const char *getTypeFormatModifier(IntType T);
975 
976   /// Check whether the given real type should use the "fpret" flavor of
977   /// Objective-C message passing on this target.
useObjCFPRetForRealType(FloatModeKind T)978   bool useObjCFPRetForRealType(FloatModeKind T) const {
979     return (int)((FloatModeKind)RealTypeUsesObjCFPRetMask & T);
980   }
981 
982   /// Check whether _Complex long double should use the "fp2ret" flavor
983   /// of Objective-C message passing on this target.
useObjCFP2RetForComplexLongDouble()984   bool useObjCFP2RetForComplexLongDouble() const {
985     return ComplexLongDoubleUsesFP2Ret;
986   }
987 
988   /// Check whether llvm intrinsics such as llvm.convert.to.fp16 should be used
989   /// to convert to and from __fp16.
990   /// FIXME: This function should be removed once all targets stop using the
991   /// conversion intrinsics.
useFP16ConversionIntrinsics()992   virtual bool useFP16ConversionIntrinsics() const {
993     return true;
994   }
995 
996   /// Specify if mangling based on address space map should be used or
997   /// not for language specific address spaces
useAddressSpaceMapMangling()998   bool useAddressSpaceMapMangling() const {
999     return UseAddrSpaceMapMangling;
1000   }
1001 
1002   ///===---- Other target property query methods --------------------------===//
1003 
1004   /// Appends the target-specific \#define values for this
1005   /// target set to the specified buffer.
1006   virtual void getTargetDefines(const LangOptions &Opts,
1007                                 MacroBuilder &Builder) const = 0;
1008 
1009 
1010   /// Return information about target-specific builtins for
1011   /// the current primary target, and info about which builtins are non-portable
1012   /// across the current set of primary and secondary targets.
1013   virtual ArrayRef<Builtin::Info> getTargetBuiltins() const = 0;
1014 
1015   /// Returns target-specific min and max values VScale_Range.
1016   virtual std::optional<std::pair<unsigned, unsigned>>
getVScaleRange(const LangOptions & LangOpts)1017   getVScaleRange(const LangOptions &LangOpts) const {
1018     return std::nullopt;
1019   }
1020   /// The __builtin_clz* and __builtin_ctz* built-in
1021   /// functions are specified to have undefined results for zero inputs, but
1022   /// on targets that support these operations in a way that provides
1023   /// well-defined results for zero without loss of performance, it is a good
1024   /// idea to avoid optimizing based on that undef behavior.
isCLZForZeroUndef()1025   virtual bool isCLZForZeroUndef() const { return true; }
1026 
1027   /// Returns the kind of __builtin_va_list type that should be used
1028   /// with this target.
1029   virtual BuiltinVaListKind getBuiltinVaListKind() const = 0;
1030 
1031   /// Returns whether or not type \c __builtin_ms_va_list type is
1032   /// available on this target.
hasBuiltinMSVaList()1033   bool hasBuiltinMSVaList() const { return HasBuiltinMSVaList; }
1034 
1035   /// Returns true for RenderScript.
isRenderScriptTarget()1036   bool isRenderScriptTarget() const { return IsRenderScriptTarget; }
1037 
1038   /// Returns whether or not the AArch64 SVE built-in types are
1039   /// available on this target.
hasAArch64SVETypes()1040   bool hasAArch64SVETypes() const { return HasAArch64SVETypes; }
1041 
1042   /// Returns whether or not the RISC-V V built-in types are
1043   /// available on this target.
hasRISCVVTypes()1044   bool hasRISCVVTypes() const { return HasRISCVVTypes; }
1045 
1046   /// Returns whether or not the AMDGPU unsafe floating point atomics are
1047   /// allowed.
allowAMDGPUUnsafeFPAtomics()1048   bool allowAMDGPUUnsafeFPAtomics() const { return AllowAMDGPUUnsafeFPAtomics; }
1049 
1050   /// For ARM targets returns a mask defining which coprocessors are configured
1051   /// as Custom Datapath.
getARMCDECoprocMask()1052   uint32_t getARMCDECoprocMask() const { return ARMCDECoprocMask; }
1053 
1054   /// Returns whether the passed in string is a valid clobber in an
1055   /// inline asm statement.
1056   ///
1057   /// This is used by Sema.
1058   bool isValidClobber(StringRef Name) const;
1059 
1060   /// Returns whether the passed in string is a valid register name
1061   /// according to GCC.
1062   ///
1063   /// This is used by Sema for inline asm statements.
1064   virtual bool isValidGCCRegisterName(StringRef Name) const;
1065 
1066   /// Returns the "normalized" GCC register name.
1067   ///
1068   /// ReturnCannonical true will return the register name without any additions
1069   /// such as "{}" or "%" in it's canonical form, for example:
1070   /// ReturnCanonical = true and Name = "rax", will return "ax".
1071   StringRef getNormalizedGCCRegisterName(StringRef Name,
1072                                          bool ReturnCanonical = false) const;
1073 
isSPRegName(StringRef)1074   virtual bool isSPRegName(StringRef) const { return false; }
1075 
1076   /// Extracts a register from the passed constraint (if it is a
1077   /// single-register constraint) and the asm label expression related to a
1078   /// variable in the input or output list of an inline asm statement.
1079   ///
1080   /// This function is used by Sema in order to diagnose conflicts between
1081   /// the clobber list and the input/output lists.
getConstraintRegister(StringRef Constraint,StringRef Expression)1082   virtual StringRef getConstraintRegister(StringRef Constraint,
1083                                           StringRef Expression) const {
1084     return "";
1085   }
1086 
1087   struct ConstraintInfo {
1088     enum {
1089       CI_None = 0x00,
1090       CI_AllowsMemory = 0x01,
1091       CI_AllowsRegister = 0x02,
1092       CI_ReadWrite = 0x04,         // "+r" output constraint (read and write).
1093       CI_HasMatchingInput = 0x08,  // This output operand has a matching input.
1094       CI_ImmediateConstant = 0x10, // This operand must be an immediate constant
1095       CI_EarlyClobber = 0x20,      // "&" output constraint (early clobber).
1096     };
1097     unsigned Flags;
1098     int TiedOperand;
1099     struct {
1100       int Min;
1101       int Max;
1102       bool isConstrained;
1103     } ImmRange;
1104     llvm::SmallSet<int, 4> ImmSet;
1105 
1106     std::string ConstraintStr;  // constraint: "=rm"
1107     std::string Name;           // Operand name: [foo] with no []'s.
1108   public:
ConstraintInfoConstraintInfo1109     ConstraintInfo(StringRef ConstraintStr, StringRef Name)
1110         : Flags(0), TiedOperand(-1), ConstraintStr(ConstraintStr.str()),
1111           Name(Name.str()) {
1112       ImmRange.Min = ImmRange.Max = 0;
1113       ImmRange.isConstrained = false;
1114     }
1115 
getConstraintStrConstraintInfo1116     const std::string &getConstraintStr() const { return ConstraintStr; }
getNameConstraintInfo1117     const std::string &getName() const { return Name; }
isReadWriteConstraintInfo1118     bool isReadWrite() const { return (Flags & CI_ReadWrite) != 0; }
earlyClobberConstraintInfo1119     bool earlyClobber() { return (Flags & CI_EarlyClobber) != 0; }
allowsRegisterConstraintInfo1120     bool allowsRegister() const { return (Flags & CI_AllowsRegister) != 0; }
allowsMemoryConstraintInfo1121     bool allowsMemory() const { return (Flags & CI_AllowsMemory) != 0; }
1122 
1123     /// Return true if this output operand has a matching
1124     /// (tied) input operand.
hasMatchingInputConstraintInfo1125     bool hasMatchingInput() const { return (Flags & CI_HasMatchingInput) != 0; }
1126 
1127     /// Return true if this input operand is a matching
1128     /// constraint that ties it to an output operand.
1129     ///
1130     /// If this returns true then getTiedOperand will indicate which output
1131     /// operand this is tied to.
hasTiedOperandConstraintInfo1132     bool hasTiedOperand() const { return TiedOperand != -1; }
getTiedOperandConstraintInfo1133     unsigned getTiedOperand() const {
1134       assert(hasTiedOperand() && "Has no tied operand!");
1135       return (unsigned)TiedOperand;
1136     }
1137 
requiresImmediateConstantConstraintInfo1138     bool requiresImmediateConstant() const {
1139       return (Flags & CI_ImmediateConstant) != 0;
1140     }
isValidAsmImmediateConstraintInfo1141     bool isValidAsmImmediate(const llvm::APInt &Value) const {
1142       if (!ImmSet.empty())
1143         return Value.isSignedIntN(32) && ImmSet.contains(Value.getZExtValue());
1144       return !ImmRange.isConstrained ||
1145              (Value.sge(ImmRange.Min) && Value.sle(ImmRange.Max));
1146     }
1147 
setIsReadWriteConstraintInfo1148     void setIsReadWrite() { Flags |= CI_ReadWrite; }
setEarlyClobberConstraintInfo1149     void setEarlyClobber() { Flags |= CI_EarlyClobber; }
setAllowsMemoryConstraintInfo1150     void setAllowsMemory() { Flags |= CI_AllowsMemory; }
setAllowsRegisterConstraintInfo1151     void setAllowsRegister() { Flags |= CI_AllowsRegister; }
setHasMatchingInputConstraintInfo1152     void setHasMatchingInput() { Flags |= CI_HasMatchingInput; }
setRequiresImmediateConstraintInfo1153     void setRequiresImmediate(int Min, int Max) {
1154       Flags |= CI_ImmediateConstant;
1155       ImmRange.Min = Min;
1156       ImmRange.Max = Max;
1157       ImmRange.isConstrained = true;
1158     }
setRequiresImmediateConstraintInfo1159     void setRequiresImmediate(llvm::ArrayRef<int> Exacts) {
1160       Flags |= CI_ImmediateConstant;
1161       for (int Exact : Exacts)
1162         ImmSet.insert(Exact);
1163     }
setRequiresImmediateConstraintInfo1164     void setRequiresImmediate(int Exact) {
1165       Flags |= CI_ImmediateConstant;
1166       ImmSet.insert(Exact);
1167     }
setRequiresImmediateConstraintInfo1168     void setRequiresImmediate() {
1169       Flags |= CI_ImmediateConstant;
1170     }
1171 
1172     /// Indicate that this is an input operand that is tied to
1173     /// the specified output operand.
1174     ///
1175     /// Copy over the various constraint information from the output.
setTiedOperandConstraintInfo1176     void setTiedOperand(unsigned N, ConstraintInfo &Output) {
1177       Output.setHasMatchingInput();
1178       Flags = Output.Flags;
1179       TiedOperand = N;
1180       // Don't copy Name or constraint string.
1181     }
1182   };
1183 
1184   /// Validate register name used for global register variables.
1185   ///
1186   /// This function returns true if the register passed in RegName can be used
1187   /// for global register variables on this target. In addition, it returns
1188   /// true in HasSizeMismatch if the size of the register doesn't match the
1189   /// variable size passed in RegSize.
validateGlobalRegisterVariable(StringRef RegName,unsigned RegSize,bool & HasSizeMismatch)1190   virtual bool validateGlobalRegisterVariable(StringRef RegName,
1191                                               unsigned RegSize,
1192                                               bool &HasSizeMismatch) const {
1193     HasSizeMismatch = false;
1194     return true;
1195   }
1196 
1197   // validateOutputConstraint, validateInputConstraint - Checks that
1198   // a constraint is valid and provides information about it.
1199   // FIXME: These should return a real error instead of just true/false.
1200   bool validateOutputConstraint(ConstraintInfo &Info) const;
1201   bool validateInputConstraint(MutableArrayRef<ConstraintInfo> OutputConstraints,
1202                                ConstraintInfo &info) const;
1203 
validateOutputSize(const llvm::StringMap<bool> & FeatureMap,StringRef,unsigned)1204   virtual bool validateOutputSize(const llvm::StringMap<bool> &FeatureMap,
1205                                   StringRef /*Constraint*/,
1206                                   unsigned /*Size*/) const {
1207     return true;
1208   }
1209 
validateInputSize(const llvm::StringMap<bool> & FeatureMap,StringRef,unsigned)1210   virtual bool validateInputSize(const llvm::StringMap<bool> &FeatureMap,
1211                                  StringRef /*Constraint*/,
1212                                  unsigned /*Size*/) const {
1213     return true;
1214   }
1215   virtual bool
validateConstraintModifier(StringRef,char,unsigned,std::string &)1216   validateConstraintModifier(StringRef /*Constraint*/,
1217                              char /*Modifier*/,
1218                              unsigned /*Size*/,
1219                              std::string &/*SuggestedModifier*/) const {
1220     return true;
1221   }
1222   virtual bool
1223   validateAsmConstraint(const char *&Name,
1224                         TargetInfo::ConstraintInfo &info) const = 0;
1225 
1226   bool resolveSymbolicName(const char *&Name,
1227                            ArrayRef<ConstraintInfo> OutputConstraints,
1228                            unsigned &Index) const;
1229 
1230   // Constraint parm will be left pointing at the last character of
1231   // the constraint.  In practice, it won't be changed unless the
1232   // constraint is longer than one character.
convertConstraint(const char * & Constraint)1233   virtual std::string convertConstraint(const char *&Constraint) const {
1234     // 'p' defaults to 'r', but can be overridden by targets.
1235     if (*Constraint == 'p')
1236       return std::string("r");
1237     return std::string(1, *Constraint);
1238   }
1239 
1240   /// Replace some escaped characters with another string based on
1241   /// target-specific rules
handleAsmEscapedChar(char C)1242   virtual std::optional<std::string> handleAsmEscapedChar(char C) const {
1243     return std::nullopt;
1244   }
1245 
1246   /// Returns a string of target-specific clobbers, in LLVM format.
1247   virtual std::string_view getClobbers() const = 0;
1248 
1249   /// Returns true if NaN encoding is IEEE 754-2008.
1250   /// Only MIPS allows a different encoding.
isNan2008()1251   virtual bool isNan2008() const {
1252     return true;
1253   }
1254 
1255   /// Returns the target triple of the primary target.
getTriple()1256   const llvm::Triple &getTriple() const {
1257     return Triple;
1258   }
1259 
1260   /// Returns the target ID if supported.
getTargetID()1261   virtual std::optional<std::string> getTargetID() const {
1262     return std::nullopt;
1263   }
1264 
getDataLayoutString()1265   const char *getDataLayoutString() const {
1266     assert(!DataLayoutString.empty() && "Uninitialized DataLayout!");
1267     return DataLayoutString.c_str();
1268   }
1269 
1270   struct GCCRegAlias {
1271     const char * const Aliases[5];
1272     const char * const Register;
1273   };
1274 
1275   struct AddlRegName {
1276     const char * const Names[5];
1277     const unsigned RegNum;
1278   };
1279 
1280   /// Does this target support "protected" visibility?
1281   ///
1282   /// Any target which dynamic libraries will naturally support
1283   /// something like "default" (meaning that the symbol is visible
1284   /// outside this shared object) and "hidden" (meaning that it isn't)
1285   /// visibilities, but "protected" is really an ELF-specific concept
1286   /// with weird semantics designed around the convenience of dynamic
1287   /// linker implementations.  Which is not to suggest that there's
1288   /// consistent target-independent semantics for "default" visibility
1289   /// either; the entire thing is pretty badly mangled.
hasProtectedVisibility()1290   virtual bool hasProtectedVisibility() const { return true; }
1291 
1292   /// Does this target aim for semantic compatibility with
1293   /// Microsoft C++ code using dllimport/export attributes?
shouldDLLImportComdatSymbols()1294   virtual bool shouldDLLImportComdatSymbols() const {
1295     return getTriple().isWindowsMSVCEnvironment() ||
1296            getTriple().isWindowsItaniumEnvironment() || getTriple().isPS();
1297   }
1298 
1299   // Does this target have PS4 specific dllimport/export handling?
hasPS4DLLImportExport()1300   virtual bool hasPS4DLLImportExport() const {
1301     return getTriple().isPS() ||
1302            // Windows Itanium support allows for testing the SCEI flavour of
1303            // dllimport/export handling on a Windows system.
1304            (getTriple().isWindowsItaniumEnvironment() &&
1305             getTriple().getVendor() == llvm::Triple::SCEI);
1306   }
1307 
1308   /// Set forced language options.
1309   ///
1310   /// Apply changes to the target information with respect to certain
1311   /// language options which change the target configuration and adjust
1312   /// the language based on the target options where applicable.
1313   virtual void adjust(DiagnosticsEngine &Diags, LangOptions &Opts);
1314 
1315   /// Initialize the map with the default set of target features for the
1316   /// CPU this should include all legal feature strings on the target.
1317   ///
1318   /// \return False on error (invalid features).
1319   virtual bool initFeatureMap(llvm::StringMap<bool> &Features,
1320                               DiagnosticsEngine &Diags, StringRef CPU,
1321                               const std::vector<std::string> &FeatureVec) const;
1322 
1323   /// Get the ABI currently in use.
getABI()1324   virtual StringRef getABI() const { return StringRef(); }
1325 
1326   /// Get the C++ ABI currently in use.
getCXXABI()1327   TargetCXXABI getCXXABI() const {
1328     return TheCXXABI;
1329   }
1330 
1331   /// Target the specified CPU.
1332   ///
1333   /// \return  False on error (invalid CPU name).
setCPU(const std::string & Name)1334   virtual bool setCPU(const std::string &Name) {
1335     return false;
1336   }
1337 
1338   /// Fill a SmallVectorImpl with the valid values to setCPU.
fillValidCPUList(SmallVectorImpl<StringRef> & Values)1339   virtual void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {}
1340 
1341   /// Fill a SmallVectorImpl with the valid values for tuning CPU.
fillValidTuneCPUList(SmallVectorImpl<StringRef> & Values)1342   virtual void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const {
1343     fillValidCPUList(Values);
1344   }
1345 
1346   /// Determine whether this TargetInfo supports the given CPU name.
isValidCPUName(StringRef Name)1347   virtual bool isValidCPUName(StringRef Name) const {
1348     return true;
1349   }
1350 
1351   /// Determine whether this TargetInfo supports the given CPU name for
1352   /// tuning.
isValidTuneCPUName(StringRef Name)1353   virtual bool isValidTuneCPUName(StringRef Name) const {
1354     return isValidCPUName(Name);
1355   }
1356 
1357   virtual ParsedTargetAttr parseTargetAttr(StringRef Str) const;
1358 
1359   /// Determine whether this TargetInfo supports tune in target attribute.
supportsTargetAttributeTune()1360   virtual bool supportsTargetAttributeTune() const {
1361     return false;
1362   }
1363 
1364   /// Use the specified ABI.
1365   ///
1366   /// \return False on error (invalid ABI name).
setABI(const std::string & Name)1367   virtual bool setABI(const std::string &Name) {
1368     return false;
1369   }
1370 
1371   /// Use the specified unit for FP math.
1372   ///
1373   /// \return False on error (invalid unit name).
setFPMath(StringRef Name)1374   virtual bool setFPMath(StringRef Name) {
1375     return false;
1376   }
1377 
1378   /// Check if target has a given feature enabled
hasFeatureEnabled(const llvm::StringMap<bool> & Features,StringRef Name)1379   virtual bool hasFeatureEnabled(const llvm::StringMap<bool> &Features,
1380                                  StringRef Name) const {
1381     return Features.lookup(Name);
1382   }
1383 
1384   /// Enable or disable a specific target feature;
1385   /// the feature name must be valid.
setFeatureEnabled(llvm::StringMap<bool> & Features,StringRef Name,bool Enabled)1386   virtual void setFeatureEnabled(llvm::StringMap<bool> &Features,
1387                                  StringRef Name,
1388                                  bool Enabled) const {
1389     Features[Name] = Enabled;
1390   }
1391 
1392   /// Determine whether this TargetInfo supports the given feature.
isValidFeatureName(StringRef Feature)1393   virtual bool isValidFeatureName(StringRef Feature) const {
1394     return true;
1395   }
1396 
1397   /// Returns true if feature has an impact on target code
1398   /// generation.
doesFeatureAffectCodeGen(StringRef Feature)1399   virtual bool doesFeatureAffectCodeGen(StringRef Feature) const {
1400     return true;
1401   }
1402 
1403   class BranchProtectionInfo {
1404   public:
1405     LangOptions::SignReturnAddressScopeKind SignReturnAddr;
1406     LangOptions::SignReturnAddressKeyKind SignKey;
1407     bool BranchTargetEnforcement;
1408     bool BranchProtectionPAuthLR;
1409     bool GuardedControlStack;
1410 
getSignReturnAddrStr()1411     const char *getSignReturnAddrStr() const {
1412       switch (SignReturnAddr) {
1413       case LangOptions::SignReturnAddressScopeKind::None:
1414         return "none";
1415       case LangOptions::SignReturnAddressScopeKind::NonLeaf:
1416         return "non-leaf";
1417       case LangOptions::SignReturnAddressScopeKind::All:
1418         return "all";
1419       }
1420       llvm_unreachable("Unexpected SignReturnAddressScopeKind");
1421     }
1422 
getSignKeyStr()1423     const char *getSignKeyStr() const {
1424       switch (SignKey) {
1425       case LangOptions::SignReturnAddressKeyKind::AKey:
1426         return "a_key";
1427       case LangOptions::SignReturnAddressKeyKind::BKey:
1428         return "b_key";
1429       }
1430       llvm_unreachable("Unexpected SignReturnAddressKeyKind");
1431     }
1432 
BranchProtectionInfo()1433     BranchProtectionInfo()
1434         : SignReturnAddr(LangOptions::SignReturnAddressScopeKind::None),
1435           SignKey(LangOptions::SignReturnAddressKeyKind::AKey),
1436           BranchTargetEnforcement(false), BranchProtectionPAuthLR(false),
1437           GuardedControlStack(false) {}
1438 
BranchProtectionInfo(const LangOptions & LangOpts)1439     BranchProtectionInfo(const LangOptions &LangOpts) {
1440       SignReturnAddr =
1441           LangOpts.hasSignReturnAddress()
1442               ? (LangOpts.isSignReturnAddressScopeAll()
1443                      ? LangOptions::SignReturnAddressScopeKind::All
1444                      : LangOptions::SignReturnAddressScopeKind::NonLeaf)
1445               : LangOptions::SignReturnAddressScopeKind::None;
1446       SignKey = LangOpts.isSignReturnAddressWithAKey()
1447                     ? LangOptions::SignReturnAddressKeyKind::AKey
1448                     : LangOptions::SignReturnAddressKeyKind::BKey;
1449       BranchTargetEnforcement = LangOpts.BranchTargetEnforcement;
1450       BranchProtectionPAuthLR = LangOpts.BranchProtectionPAuthLR;
1451       GuardedControlStack = LangOpts.GuardedControlStack;
1452     }
1453   };
1454 
1455   /// Determine if the Architecture in this TargetInfo supports branch
1456   /// protection
isBranchProtectionSupportedArch(StringRef Arch)1457   virtual bool isBranchProtectionSupportedArch(StringRef Arch) const {
1458     return false;
1459   }
1460 
1461   /// Determine if this TargetInfo supports the given branch protection
1462   /// specification
validateBranchProtection(StringRef Spec,StringRef Arch,BranchProtectionInfo & BPI,StringRef & Err)1463   virtual bool validateBranchProtection(StringRef Spec, StringRef Arch,
1464                                         BranchProtectionInfo &BPI,
1465                                         StringRef &Err) const {
1466     Err = "";
1467     return false;
1468   }
1469 
1470   /// Perform initialization based on the user configured
1471   /// set of features (e.g., +sse4).
1472   ///
1473   /// The list is guaranteed to have at most one entry per feature.
1474   ///
1475   /// The target may modify the features list, to change which options are
1476   /// passed onwards to the backend.
1477   /// FIXME: This part should be fixed so that we can change handleTargetFeatures
1478   /// to merely a TargetInfo initialization routine.
1479   ///
1480   /// \return  False on error.
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)1481   virtual bool handleTargetFeatures(std::vector<std::string> &Features,
1482                                     DiagnosticsEngine &Diags) {
1483     return true;
1484   }
1485 
1486   /// Determine whether the given target has the given feature.
hasFeature(StringRef Feature)1487   virtual bool hasFeature(StringRef Feature) const {
1488     return false;
1489   }
1490 
1491   /// Determine whether the given target feature is read only.
isReadOnlyFeature(StringRef Feature)1492   bool isReadOnlyFeature(StringRef Feature) const {
1493     return ReadOnlyFeatures.count(Feature);
1494   }
1495 
1496   /// Identify whether this target supports multiversioning of functions,
1497   /// which requires support for cpu_supports and cpu_is functionality.
supportsMultiVersioning()1498   bool supportsMultiVersioning() const {
1499     return getTriple().isX86() || getTriple().isAArch64();
1500   }
1501 
1502   /// Identify whether this target supports IFuncs.
supportsIFunc()1503   bool supportsIFunc() const {
1504     if (getTriple().isOSBinFormatMachO())
1505       return true;
1506     return getTriple().isOSBinFormatELF() &&
1507            ((getTriple().isOSLinux() && !getTriple().isMusl()) ||
1508             getTriple().isOSFreeBSD());
1509   }
1510 
1511   // Identify whether this target supports __builtin_cpu_supports and
1512   // __builtin_cpu_is.
supportsCpuSupports()1513   virtual bool supportsCpuSupports() const { return false; }
supportsCpuIs()1514   virtual bool supportsCpuIs() const { return false; }
supportsCpuInit()1515   virtual bool supportsCpuInit() const { return false; }
1516 
1517   // Validate the contents of the __builtin_cpu_supports(const char*)
1518   // argument.
validateCpuSupports(StringRef Name)1519   virtual bool validateCpuSupports(StringRef Name) const { return false; }
1520 
1521   // Return the target-specific priority for features/cpus/vendors so
1522   // that they can be properly sorted for checking.
multiVersionSortPriority(StringRef Name)1523   virtual unsigned multiVersionSortPriority(StringRef Name) const {
1524     return 0;
1525   }
1526 
1527   // Return the target-specific cost for feature
1528   // that taken into account in priority sorting.
multiVersionFeatureCost()1529   virtual unsigned multiVersionFeatureCost() const { return 0; }
1530 
1531   // Validate the contents of the __builtin_cpu_is(const char*)
1532   // argument.
validateCpuIs(StringRef Name)1533   virtual bool validateCpuIs(StringRef Name) const { return false; }
1534 
1535   // Validate a cpu_dispatch/cpu_specific CPU option, which is a different list
1536   // from cpu_is, since it checks via features rather than CPUs directly.
validateCPUSpecificCPUDispatch(StringRef Name)1537   virtual bool validateCPUSpecificCPUDispatch(StringRef Name) const {
1538     return false;
1539   }
1540 
1541   // Get the character to be added for mangling purposes for cpu_specific.
CPUSpecificManglingCharacter(StringRef Name)1542   virtual char CPUSpecificManglingCharacter(StringRef Name) const {
1543     llvm_unreachable(
1544         "cpu_specific Multiversioning not implemented on this target");
1545   }
1546 
1547   // Get the value for the 'tune-cpu' flag for a cpu_specific variant with the
1548   // programmer-specified 'Name'.
getCPUSpecificTuneName(StringRef Name)1549   virtual StringRef getCPUSpecificTuneName(StringRef Name) const {
1550     llvm_unreachable(
1551         "cpu_specific Multiversioning not implemented on this target");
1552   }
1553 
1554   // Get a list of the features that make up the CPU option for
1555   // cpu_specific/cpu_dispatch so that it can be passed to llvm as optimization
1556   // options.
getCPUSpecificCPUDispatchFeatures(StringRef Name,llvm::SmallVectorImpl<StringRef> & Features)1557   virtual void getCPUSpecificCPUDispatchFeatures(
1558       StringRef Name, llvm::SmallVectorImpl<StringRef> &Features) const {
1559     llvm_unreachable(
1560         "cpu_specific Multiversioning not implemented on this target");
1561   }
1562 
1563   // Get the cache line size of a given cpu. This method switches over
1564   // the given cpu and returns "std::nullopt" if the CPU is not found.
getCPUCacheLineSize()1565   virtual std::optional<unsigned> getCPUCacheLineSize() const {
1566     return std::nullopt;
1567   }
1568 
1569   // Returns maximal number of args passed in registers.
getRegParmMax()1570   unsigned getRegParmMax() const {
1571     assert(RegParmMax < 7 && "RegParmMax value is larger than AST can handle");
1572     return RegParmMax;
1573   }
1574 
1575   /// Whether the target supports thread-local storage.
isTLSSupported()1576   bool isTLSSupported() const {
1577     return TLSSupported;
1578   }
1579 
1580   /// Return the maximum alignment (in bits) of a TLS variable
1581   ///
1582   /// Gets the maximum alignment (in bits) of a TLS variable on this target.
1583   /// Returns zero if there is no such constraint.
getMaxTLSAlign()1584   unsigned getMaxTLSAlign() const { return MaxTLSAlign; }
1585 
1586   /// Whether target supports variable-length arrays.
isVLASupported()1587   bool isVLASupported() const { return VLASupported; }
1588 
1589   /// Whether the target supports SEH __try.
isSEHTrySupported()1590   bool isSEHTrySupported() const {
1591     return getTriple().isOSWindows() &&
1592            (getTriple().isX86() ||
1593             getTriple().getArch() == llvm::Triple::aarch64);
1594   }
1595 
1596   /// Return true if {|} are normal characters in the asm string.
1597   ///
1598   /// If this returns false (the default), then {abc|xyz} is syntax
1599   /// that says that when compiling for asm variant #0, "abc" should be
1600   /// generated, but when compiling for asm variant #1, "xyz" should be
1601   /// generated.
hasNoAsmVariants()1602   bool hasNoAsmVariants() const {
1603     return NoAsmVariants;
1604   }
1605 
1606   /// Return the register number that __builtin_eh_return_regno would
1607   /// return with the specified argument.
1608   /// This corresponds with TargetLowering's getExceptionPointerRegister
1609   /// and getExceptionSelectorRegister in the backend.
getEHDataRegisterNumber(unsigned RegNo)1610   virtual int getEHDataRegisterNumber(unsigned RegNo) const {
1611     return -1;
1612   }
1613 
1614   /// Return the section to use for C++ static initialization functions.
getStaticInitSectionSpecifier()1615   virtual const char *getStaticInitSectionSpecifier() const {
1616     return nullptr;
1617   }
1618 
getAddressSpaceMap()1619   const LangASMap &getAddressSpaceMap() const { return *AddrSpaceMap; }
getTargetAddressSpace(LangAS AS)1620   unsigned getTargetAddressSpace(LangAS AS) const {
1621     if (isTargetAddressSpace(AS))
1622       return toTargetAddressSpace(AS);
1623     return getAddressSpaceMap()[(unsigned)AS];
1624   }
1625 
1626   /// Determine whether the given pointer-authentication key is valid.
1627   ///
1628   /// The value has been coerced to type 'int'.
1629   virtual bool validatePointerAuthKey(const llvm::APSInt &value) const;
1630 
1631   /// Map from the address space field in builtin description strings to the
1632   /// language address space.
getOpenCLBuiltinAddressSpace(unsigned AS)1633   virtual LangAS getOpenCLBuiltinAddressSpace(unsigned AS) const {
1634     return getLangASFromTargetAS(AS);
1635   }
1636 
1637   /// Map from the address space field in builtin description strings to the
1638   /// language address space.
getCUDABuiltinAddressSpace(unsigned AS)1639   virtual LangAS getCUDABuiltinAddressSpace(unsigned AS) const {
1640     return getLangASFromTargetAS(AS);
1641   }
1642 
1643   /// Return an AST address space which can be used opportunistically
1644   /// for constant global memory. It must be possible to convert pointers into
1645   /// this address space to LangAS::Default. If no such address space exists,
1646   /// this may return std::nullopt, and such optimizations will be disabled.
getConstantAddressSpace()1647   virtual std::optional<LangAS> getConstantAddressSpace() const {
1648     return LangAS::Default;
1649   }
1650 
1651   // access target-specific GPU grid values that must be consistent between
1652   // host RTL (plugin), deviceRTL and clang.
getGridValue()1653   virtual const llvm::omp::GV &getGridValue() const {
1654     llvm_unreachable("getGridValue not implemented on this target");
1655   }
1656 
1657   /// Retrieve the name of the platform as it is used in the
1658   /// availability attribute.
getPlatformName()1659   StringRef getPlatformName() const { return PlatformName; }
1660 
1661   /// Retrieve the minimum desired version of the platform, to
1662   /// which the program should be compiled.
getPlatformMinVersion()1663   VersionTuple getPlatformMinVersion() const { return PlatformMinVersion; }
1664 
isBigEndian()1665   bool isBigEndian() const { return BigEndian; }
isLittleEndian()1666   bool isLittleEndian() const { return !BigEndian; }
1667 
1668   /// Whether the option -fextend-arguments={32,64} is supported on the target.
supportsExtendIntArgs()1669   virtual bool supportsExtendIntArgs() const { return false; }
1670 
1671   /// Controls if __arithmetic_fence is supported in the targeted backend.
checkArithmeticFenceSupported()1672   virtual bool checkArithmeticFenceSupported() const { return false; }
1673 
1674   /// Gets the default calling convention for the given target and
1675   /// declaration context.
getDefaultCallingConv()1676   virtual CallingConv getDefaultCallingConv() const {
1677     // Not all targets will specify an explicit calling convention that we can
1678     // express.  This will always do the right thing, even though it's not
1679     // an explicit calling convention.
1680     return CC_C;
1681   }
1682 
1683   enum CallingConvCheckResult {
1684     CCCR_OK,
1685     CCCR_Warning,
1686     CCCR_Ignore,
1687     CCCR_Error,
1688   };
1689 
1690   /// Determines whether a given calling convention is valid for the
1691   /// target. A calling convention can either be accepted, produce a warning
1692   /// and be substituted with the default calling convention, or (someday)
1693   /// produce an error (such as using thiscall on a non-instance function).
checkCallingConvention(CallingConv CC)1694   virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const {
1695     switch (CC) {
1696       default:
1697         return CCCR_Warning;
1698       case CC_C:
1699         return CCCR_OK;
1700     }
1701   }
1702 
1703   enum CallingConvKind {
1704     CCK_Default,
1705     CCK_ClangABI4OrPS4,
1706     CCK_MicrosoftWin64
1707   };
1708 
1709   virtual CallingConvKind getCallingConvKind(bool ClangABICompat4) const;
1710 
1711   /// Controls whether explicitly defaulted (`= default`) special member
1712   /// functions disqualify something from being POD-for-the-purposes-of-layout.
1713   /// Historically, Clang didn't consider these acceptable for POD, but GCC
1714   /// does. So in newer Clang ABIs they are acceptable for POD to be compatible
1715   /// with GCC/Itanium ABI, and remains disqualifying for targets that need
1716   /// Clang backwards compatibility rather than GCC/Itanium ABI compatibility.
1717   virtual bool areDefaultedSMFStillPOD(const LangOptions&) const;
1718 
1719   /// Controls if __builtin_longjmp / __builtin_setjmp can be lowered to
1720   /// llvm.eh.sjlj.longjmp / llvm.eh.sjlj.setjmp.
hasSjLjLowering()1721   virtual bool hasSjLjLowering() const {
1722     return false;
1723   }
1724 
1725   /// Check if the target supports CFProtection branch.
1726   virtual bool
1727   checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const;
1728 
1729   /// Check if the target supports CFProtection return.
1730   virtual bool
1731   checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const;
1732 
1733   /// Whether target allows to overalign ABI-specified preferred alignment
allowsLargerPreferedTypeAlignment()1734   virtual bool allowsLargerPreferedTypeAlignment() const { return true; }
1735 
1736   /// Whether target defaults to the `power` alignment rules of AIX.
defaultsToAIXPowerAlignment()1737   virtual bool defaultsToAIXPowerAlignment() const { return false; }
1738 
1739   /// Set supported OpenCL extensions and optional core features.
setSupportedOpenCLOpts()1740   virtual void setSupportedOpenCLOpts() {}
1741 
1742   virtual void supportAllOpenCLOpts(bool V = true) {
1743 #define OPENCLEXTNAME(Ext)                                                     \
1744   setFeatureEnabled(getTargetOpts().OpenCLFeaturesMap, #Ext, V);
1745 #include "clang/Basic/OpenCLExtensions.def"
1746   }
1747 
1748   /// Set supported OpenCL extensions as written on command line
setCommandLineOpenCLOpts()1749   virtual void setCommandLineOpenCLOpts() {
1750     for (const auto &Ext : getTargetOpts().OpenCLExtensionsAsWritten) {
1751       bool IsPrefixed = (Ext[0] == '+' || Ext[0] == '-');
1752       std::string Name = IsPrefixed ? Ext.substr(1) : Ext;
1753       bool V = IsPrefixed ? Ext[0] == '+' : true;
1754 
1755       if (Name == "all") {
1756         supportAllOpenCLOpts(V);
1757         continue;
1758       }
1759 
1760       getTargetOpts().OpenCLFeaturesMap[Name] = V;
1761     }
1762   }
1763 
1764   /// Get supported OpenCL extensions and optional core features.
getSupportedOpenCLOpts()1765   llvm::StringMap<bool> &getSupportedOpenCLOpts() {
1766     return getTargetOpts().OpenCLFeaturesMap;
1767   }
1768 
1769   /// Get const supported OpenCL extensions and optional core features.
getSupportedOpenCLOpts()1770   const llvm::StringMap<bool> &getSupportedOpenCLOpts() const {
1771     return getTargetOpts().OpenCLFeaturesMap;
1772   }
1773 
1774   /// Get address space for OpenCL type.
1775   virtual LangAS getOpenCLTypeAddrSpace(OpenCLTypeKind TK) const;
1776 
1777   /// \returns Target specific vtbl ptr address space.
getVtblPtrAddressSpace()1778   virtual unsigned getVtblPtrAddressSpace() const {
1779     return 0;
1780   }
1781 
1782   /// \returns If a target requires an address within a target specific address
1783   /// space \p AddressSpace to be converted in order to be used, then return the
1784   /// corresponding target specific DWARF address space.
1785   ///
1786   /// \returns Otherwise return std::nullopt and no conversion will be emitted
1787   /// in the DWARF.
getDWARFAddressSpace(unsigned AddressSpace)1788   virtual std::optional<unsigned> getDWARFAddressSpace(unsigned AddressSpace)
1789       const {
1790     return std::nullopt;
1791   }
1792 
1793   /// \returns The version of the SDK which was used during the compilation if
1794   /// one was specified, or an empty version otherwise.
getSDKVersion()1795   const llvm::VersionTuple &getSDKVersion() const {
1796     return getTargetOpts().SDKVersion;
1797   }
1798 
1799   /// Check the target is valid after it is fully initialized.
validateTarget(DiagnosticsEngine & Diags)1800   virtual bool validateTarget(DiagnosticsEngine &Diags) const {
1801     return true;
1802   }
1803 
1804   /// Check that OpenCL target has valid options setting based on OpenCL
1805   /// version.
1806   virtual bool validateOpenCLTarget(const LangOptions &Opts,
1807                                     DiagnosticsEngine &Diags) const;
1808 
setAuxTarget(const TargetInfo * Aux)1809   virtual void setAuxTarget(const TargetInfo *Aux) {}
1810 
1811   /// Whether target allows debuginfo types for decl only variables/functions.
allowDebugInfoForExternalRef()1812   virtual bool allowDebugInfoForExternalRef() const { return false; }
1813 
1814   /// Returns the darwin target variant triple, the variant of the deployment
1815   /// target for which the code is being compiled.
getDarwinTargetVariantTriple()1816   const llvm::Triple *getDarwinTargetVariantTriple() const {
1817     return DarwinTargetVariantTriple ? &*DarwinTargetVariantTriple : nullptr;
1818   }
1819 
1820   /// Returns the version of the darwin target variant SDK which was used during
1821   /// the compilation if one was specified, or an empty version otherwise.
getDarwinTargetVariantSDKVersion()1822   const std::optional<VersionTuple> getDarwinTargetVariantSDKVersion() const {
1823     return !getTargetOpts().DarwinTargetVariantSDKVersion.empty()
1824                ? getTargetOpts().DarwinTargetVariantSDKVersion
1825                : std::optional<VersionTuple>();
1826   }
1827 
1828   /// Whether to support HIP image/texture API's.
hasHIPImageSupport()1829   virtual bool hasHIPImageSupport() const { return true; }
1830 
1831   /// The first value in the pair is the minimum offset between two objects to
1832   /// avoid false sharing (destructive interference). The second value in the
1833   /// pair is maximum size of contiguous memory to promote true sharing
1834   /// (constructive interference). Neither of these values are considered part
1835   /// of the ABI and can be changed by targets at any time.
hardwareInterferenceSizes()1836   virtual std::pair<unsigned, unsigned> hardwareInterferenceSizes() const {
1837     return std::make_pair(64, 64);
1838   }
1839 
1840 protected:
1841   /// Copy type and layout related info.
1842   void copyAuxTarget(const TargetInfo *Aux);
getPointerWidthV(LangAS AddrSpace)1843   virtual uint64_t getPointerWidthV(LangAS AddrSpace) const {
1844     return PointerWidth;
1845   }
getPointerAlignV(LangAS AddrSpace)1846   virtual uint64_t getPointerAlignV(LangAS AddrSpace) const {
1847     return PointerAlign;
1848   }
getPtrDiffTypeV(LangAS AddrSpace)1849   virtual enum IntType getPtrDiffTypeV(LangAS AddrSpace) const {
1850     return PtrDiffType;
1851   }
1852   virtual ArrayRef<const char *> getGCCRegNames() const = 0;
1853   virtual ArrayRef<GCCRegAlias> getGCCRegAliases() const = 0;
getGCCAddlRegNames()1854   virtual ArrayRef<AddlRegName> getGCCAddlRegNames() const {
1855     return std::nullopt;
1856   }
1857 
1858  private:
1859   // Assert the values for the fractional and integral bits for each fixed point
1860   // type follow the restrictions given in clause 6.2.6.3 of N1169.
1861   void CheckFixedPointBits() const;
1862 };
1863 
1864 }  // end namespace clang
1865 
1866 #endif
1867