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