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