TargetInfo.h revision 344779
1193326Sed//===--- TargetInfo.h - Expose information about the target -----*- C++ -*-===// 2193326Sed// 3193326Sed// The LLVM Compiler Infrastructure 4193326Sed// 5193326Sed// This file is distributed under the University of Illinois Open Source 6193326Sed// License. See LICENSE.TXT for details. 7193326Sed// 8193326Sed//===----------------------------------------------------------------------===// 9239462Sdim/// 10239462Sdim/// \file 11341825Sdim/// Defines the clang::TargetInfo interface. 12239462Sdim/// 13193326Sed//===----------------------------------------------------------------------===// 14193326Sed 15193326Sed#ifndef LLVM_CLANG_BASIC_TARGETINFO_H 16193326Sed#define LLVM_CLANG_BASIC_TARGETINFO_H 17193326Sed 18249423Sdim#include "clang/Basic/AddressSpaces.h" 19226633Sdim#include "clang/Basic/LLVM.h" 20249423Sdim#include "clang/Basic/Specifiers.h" 21276479Sdim#include "clang/Basic/TargetCXXABI.h" 22249423Sdim#include "clang/Basic/TargetOptions.h" 23309124Sdim#include "llvm/ADT/APInt.h" 24221345Sdim#include "llvm/ADT/IntrusiveRefCntPtr.h" 25321369Sdim#include "llvm/ADT/Optional.h" 26296417Sdim#include "llvm/ADT/SmallSet.h" 27193326Sed#include "llvm/ADT/StringMap.h" 28221345Sdim#include "llvm/ADT/StringRef.h" 29198092Srdivacky#include "llvm/ADT/Triple.h" 30309124Sdim#include "llvm/IR/DataLayout.h" 31218893Sdim#include "llvm/Support/DataTypes.h" 32341825Sdim#include "llvm/Support/VersionTuple.h" 33193326Sed#include <cassert> 34249423Sdim#include <string> 35193326Sed#include <vector> 36193326Sed 37198092Srdivackynamespace llvm { 38198092Srdivackystruct fltSemantics; 39198092Srdivacky} 40193326Sed 41193326Sednamespace clang { 42226633Sdimclass DiagnosticsEngine; 43199482Srdivackyclass LangOptions; 44314564Sdimclass CodeGenOptions; 45202379Srdivackyclass MacroBuilder; 46314564Sdimclass QualType; 47198092Srdivackyclass SourceLocation; 48193326Sedclass SourceManager; 49199482Srdivacky 50193326Sednamespace Builtin { struct Info; } 51198092Srdivacky 52341825Sdim/// Exposes information about the current target. 53193326Sed/// 54234353Sdimclass TargetInfo : public RefCountedBase<TargetInfo> { 55276479Sdim std::shared_ptr<TargetOptions> TargetOpts; 56198092Srdivacky llvm::Triple Triple; 57193326Sedprotected: 58193326Sed // Target values set by the ctor of the actual target implementation. Default 59193326Sed // values are specified by the TargetInfo constructor. 60234353Sdim bool BigEndian; 61193326Sed bool TLSSupported; 62327952Sdim bool VLASupported; 63207619Srdivacky bool NoAsmVariants; // True if {|} are normal characters. 64341825Sdim bool HasLegalHalfType; // True if the backend supports operations on the half 65341825Sdim // LLVM IR type. 66309124Sdim bool HasFloat128; 67344779Sdim bool HasFloat16; 68193326Sed unsigned char PointerWidth, PointerAlign; 69218893Sdim unsigned char BoolWidth, BoolAlign; 70193326Sed unsigned char IntWidth, IntAlign; 71226633Sdim unsigned char HalfWidth, HalfAlign; 72193326Sed unsigned char FloatWidth, FloatAlign; 73193326Sed unsigned char DoubleWidth, DoubleAlign; 74309124Sdim unsigned char LongDoubleWidth, LongDoubleAlign, Float128Align; 75210299Sed unsigned char LargeArrayMinWidth, LargeArrayAlign; 76193326Sed unsigned char LongWidth, LongAlign; 77193326Sed unsigned char LongLongWidth, LongLongAlign; 78341825Sdim 79341825Sdim // Fixed point bit widths 80341825Sdim unsigned char ShortAccumWidth, ShortAccumAlign; 81341825Sdim unsigned char AccumWidth, AccumAlign; 82341825Sdim unsigned char LongAccumWidth, LongAccumAlign; 83341825Sdim unsigned char ShortFractWidth, ShortFractAlign; 84341825Sdim unsigned char FractWidth, FractAlign; 85341825Sdim unsigned char LongFractWidth, LongFractAlign; 86341825Sdim 87341825Sdim // If true, unsigned fixed point types have the same number of fractional bits 88341825Sdim // as their signed counterparts, forcing the unsigned types to have one extra 89341825Sdim // bit of padding. Otherwise, unsigned fixed point types have 90341825Sdim // one more fractional bit than its corresponding signed type. This is false 91341825Sdim // by default. 92341825Sdim bool PaddingOnUnsignedFixedPoint; 93341825Sdim 94341825Sdim // Fixed point integral and fractional bit sizes 95341825Sdim // Saturated types share the same integral/fractional bits as their 96341825Sdim // corresponding unsaturated types. 97341825Sdim // For simplicity, the fractional bits in a _Fract type will be one less the 98341825Sdim // width of that _Fract type. This leaves all signed _Fract types having no 99341825Sdim // padding and unsigned _Fract types will only have 1 bit of padding after the 100341825Sdim // sign if PaddingOnUnsignedFixedPoint is set. 101341825Sdim unsigned char ShortAccumScale; 102341825Sdim unsigned char AccumScale; 103341825Sdim unsigned char LongAccumScale; 104341825Sdim 105234353Sdim unsigned char SuitableAlign; 106288943Sdim unsigned char DefaultAlignForAttributeAligned; 107251662Sdim unsigned char MinGlobalAlign; 108226633Sdim unsigned char MaxAtomicPromoteWidth, MaxAtomicInlineWidth; 109239462Sdim unsigned short MaxVectorAlign; 110288943Sdim unsigned short MaxTLSAlign; 111288943Sdim unsigned short SimdDefaultAlign; 112314564Sdim unsigned short NewAlign; 113309124Sdim std::unique_ptr<llvm::DataLayout> DataLayout; 114218893Sdim const char *MCountName; 115226633Sdim const llvm::fltSemantics *HalfFormat, *FloatFormat, *DoubleFormat, 116309124Sdim *LongDoubleFormat, *Float128Format; 117193326Sed unsigned char RegParmMax, SSERegParmMax; 118249423Sdim TargetCXXABI TheCXXABI; 119327952Sdim const LangASMap *AddrSpaceMap; 120193326Sed 121226633Sdim mutable StringRef PlatformName; 122221345Sdim mutable VersionTuple PlatformMinVersion; 123221345Sdim 124208600Srdivacky unsigned HasAlignMac68kSupport : 1; 125210299Sed unsigned RealTypeUsesObjCFPRet : 3; 126234353Sdim unsigned ComplexLongDoubleUsesFP2Ret : 1; 127208600Srdivacky 128296417Sdim unsigned HasBuiltinMSVaList : 1; 129296417Sdim 130314564Sdim unsigned IsRenderScriptTarget : 1; 131314564Sdim 132193326Sed // TargetInfo Constructor. Default initializes all fields. 133261991Sdim TargetInfo(const llvm::Triple &T); 134198092Srdivacky 135309124Sdim void resetDataLayout(StringRef DL) { 136309124Sdim DataLayout.reset(new llvm::DataLayout(DL)); 137309124Sdim } 138309124Sdim 139198092Srdivackypublic: 140341825Sdim /// Construct a target for the given options. 141201361Srdivacky /// 142201361Srdivacky /// \param Opts - The options to use to initialize the target. The target may 143201361Srdivacky /// modify the options to canonicalize the target feature information to match 144201361Srdivacky /// what the backend expects. 145276479Sdim static TargetInfo * 146276479Sdim CreateTargetInfo(DiagnosticsEngine &Diags, 147276479Sdim const std::shared_ptr<TargetOptions> &Opts); 148193326Sed 149193326Sed virtual ~TargetInfo(); 150193326Sed 151341825Sdim /// Retrieve the target options. 152296417Sdim TargetOptions &getTargetOpts() const { 153243830Sdim assert(TargetOpts && "Missing target options"); 154296417Sdim return *TargetOpts; 155243830Sdim } 156243830Sdim 157193326Sed ///===---- Target Data Type Query Methods -------------------------------===// 158193326Sed enum IntType { 159193326Sed NoInt = 0, 160261991Sdim SignedChar, 161261991Sdim UnsignedChar, 162193326Sed SignedShort, 163193326Sed UnsignedShort, 164193326Sed SignedInt, 165193326Sed UnsignedInt, 166193326Sed SignedLong, 167193326Sed UnsignedLong, 168193326Sed SignedLongLong, 169193326Sed UnsignedLongLong 170193326Sed }; 171210299Sed 172210299Sed enum RealType { 173261991Sdim NoFloat = 255, 174210299Sed Float = 0, 175210299Sed Double, 176309124Sdim LongDouble, 177309124Sdim Float128 178210299Sed }; 179210299Sed 180341825Sdim /// The different kinds of __builtin_va_list types defined by 181239462Sdim /// the target implementation. 182239462Sdim enum BuiltinVaListKind { 183239462Sdim /// typedef char* __builtin_va_list; 184239462Sdim CharPtrBuiltinVaList = 0, 185239462Sdim 186239462Sdim /// typedef void* __builtin_va_list; 187239462Sdim VoidPtrBuiltinVaList, 188239462Sdim 189321369Sdim /// __builtin_va_list as defined by the AArch64 ABI 190249423Sdim /// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055a/IHI0055A_aapcs64.pdf 191249423Sdim AArch64ABIBuiltinVaList, 192249423Sdim 193239462Sdim /// __builtin_va_list as defined by the PNaCl ABI: 194239462Sdim /// http://www.chromium.org/nativeclient/pnacl/bitcode-abi#TOC-Machine-Types 195239462Sdim PNaClABIBuiltinVaList, 196239462Sdim 197239462Sdim /// __builtin_va_list as defined by the Power ABI: 198239462Sdim /// https://www.power.org 199239462Sdim /// /resources/downloads/Power-Arch-32-bit-ABI-supp-1.0-Embedded.pdf 200239462Sdim PowerABIBuiltinVaList, 201239462Sdim 202239462Sdim /// __builtin_va_list as defined by the x86-64 ABI: 203321369Sdim /// http://refspecs.linuxbase.org/elf/x86_64-abi-0.21.pdf 204243830Sdim X86_64ABIBuiltinVaList, 205243830Sdim 206243830Sdim /// __builtin_va_list as defined by ARM AAPCS ABI 207243830Sdim /// http://infocenter.arm.com 208243830Sdim // /help/topic/com.arm.doc.ihi0042d/IHI0042D_aapcs.pdf 209251662Sdim AAPCSABIBuiltinVaList, 210251662Sdim 211251662Sdim // typedef struct __va_list_tag 212251662Sdim // { 213251662Sdim // long __gpr; 214251662Sdim // long __fpr; 215251662Sdim // void *__overflow_arg_area; 216251662Sdim // void *__reg_save_area; 217251662Sdim // } va_list[1]; 218251662Sdim SystemZBuiltinVaList 219239462Sdim }; 220239462Sdim 221193326Sedprotected: 222276479Sdim IntType SizeType, IntMaxType, PtrDiffType, IntPtrType, WCharType, 223243830Sdim WIntType, Char16Type, Char32Type, Int64Type, SigAtomicType, 224243830Sdim ProcessIDType; 225207619Srdivacky 226341825Sdim /// Whether Objective-C's built-in boolean type should be signed char. 227239462Sdim /// 228234982Sdim /// Otherwise, when this flag is not set, the normal built-in boolean type is 229234982Sdim /// used. 230234982Sdim unsigned UseSignedCharForObjCBool : 1; 231234982Sdim 232207619Srdivacky /// Control whether the alignment of bit-field types is respected when laying 233207619Srdivacky /// out structures. If true, then the alignment of the bit-field type will be 234207619Srdivacky /// used to (a) impact the alignment of the containing structure, and (b) 235207619Srdivacky /// ensure that the individual bit-field will not straddle an alignment 236207619Srdivacky /// boundary. 237207619Srdivacky unsigned UseBitFieldTypeAlignment : 1; 238207619Srdivacky 239341825Sdim /// Whether zero length bitfields (e.g., int : 0;) force alignment of 240239462Sdim /// the next bitfield. 241239462Sdim /// 242239462Sdim /// If the alignment of the zero length bitfield is greater than the member 243239462Sdim /// that follows it, `bar', `bar' will be aligned as the type of the 244239462Sdim /// zero-length bitfield. 245226633Sdim unsigned UseZeroLengthBitfieldAlignment : 1; 246226633Sdim 247341825Sdim /// Whether explicit bit field alignment attributes are honored. 248309124Sdim unsigned UseExplicitBitFieldAlignment : 1; 249309124Sdim 250226633Sdim /// If non-zero, specifies a fixed alignment value for bitfields that follow 251226633Sdim /// zero length bitfield, regardless of the zero length bitfield type. 252226633Sdim unsigned ZeroLengthBitfieldBoundary; 253226633Sdim 254341825Sdim /// Specify if mangling based on address space map should be used or 255261991Sdim /// not for language specific address spaces 256261991Sdim bool UseAddrSpaceMapMangling; 257261991Sdim 258193326Sedpublic: 259193326Sed IntType getSizeType() const { return SizeType; } 260321369Sdim IntType getSignedSizeType() const { 261321369Sdim switch (SizeType) { 262321369Sdim case UnsignedShort: 263321369Sdim return SignedShort; 264321369Sdim case UnsignedInt: 265321369Sdim return SignedInt; 266321369Sdim case UnsignedLong: 267321369Sdim return SignedLong; 268321369Sdim case UnsignedLongLong: 269321369Sdim return SignedLongLong; 270321369Sdim default: 271321369Sdim llvm_unreachable("Invalid SizeType"); 272321369Sdim } 273321369Sdim } 274193326Sed IntType getIntMaxType() const { return IntMaxType; } 275276479Sdim IntType getUIntMaxType() const { 276276479Sdim return getCorrespondingUnsignedType(IntMaxType); 277276479Sdim } 278193326Sed IntType getPtrDiffType(unsigned AddrSpace) const { 279193326Sed return AddrSpace == 0 ? PtrDiffType : getPtrDiffTypeV(AddrSpace); 280193326Sed } 281327952Sdim IntType getUnsignedPtrDiffType(unsigned AddrSpace) const { 282327952Sdim return getCorrespondingUnsignedType(getPtrDiffType(AddrSpace)); 283327952Sdim } 284193326Sed IntType getIntPtrType() const { return IntPtrType; } 285276479Sdim IntType getUIntPtrType() const { 286276479Sdim return getCorrespondingUnsignedType(IntPtrType); 287276479Sdim } 288193326Sed IntType getWCharType() const { return WCharType; } 289198398Srdivacky IntType getWIntType() const { return WIntType; } 290198092Srdivacky IntType getChar16Type() const { return Char16Type; } 291198092Srdivacky IntType getChar32Type() const { return Char32Type; } 292195341Sed IntType getInt64Type() const { return Int64Type; } 293276479Sdim IntType getUInt64Type() const { 294276479Sdim return getCorrespondingUnsignedType(Int64Type); 295276479Sdim } 296199990Srdivacky IntType getSigAtomicType() const { return SigAtomicType; } 297243830Sdim IntType getProcessIDType() const { return ProcessIDType; } 298193326Sed 299276479Sdim static IntType getCorrespondingUnsignedType(IntType T) { 300276479Sdim switch (T) { 301276479Sdim case SignedChar: 302276479Sdim return UnsignedChar; 303276479Sdim case SignedShort: 304276479Sdim return UnsignedShort; 305276479Sdim case SignedInt: 306276479Sdim return UnsignedInt; 307276479Sdim case SignedLong: 308276479Sdim return UnsignedLong; 309276479Sdim case SignedLongLong: 310276479Sdim return UnsignedLongLong; 311276479Sdim default: 312276479Sdim llvm_unreachable("Unexpected signed integer type"); 313276479Sdim } 314276479Sdim } 315276479Sdim 316344779Sdim /// In the event this target uses the same number of fractional bits for its 317344779Sdim /// unsigned types as it does with its signed counterparts, there will be 318344779Sdim /// exactly one bit of padding. 319344779Sdim /// Return true if unsigned fixed point types have padding for this target. 320344779Sdim bool doUnsignedFixedPointTypesHavePadding() const { 321344779Sdim return PaddingOnUnsignedFixedPoint; 322344779Sdim } 323344779Sdim 324341825Sdim /// Return the width (in bits) of the specified integer type enum. 325239462Sdim /// 326239462Sdim /// For example, SignedInt -> getIntWidth(). 327198398Srdivacky unsigned getTypeWidth(IntType T) const; 328198398Srdivacky 329341825Sdim /// Return integer type with specified width. 330296417Sdim virtual IntType getIntTypeByWidth(unsigned BitWidth, bool IsSigned) const; 331261991Sdim 332341825Sdim /// Return the smallest integer type with at least the specified width. 333296417Sdim virtual IntType getLeastIntTypeByWidth(unsigned BitWidth, 334296417Sdim bool IsSigned) const; 335276479Sdim 336341825Sdim /// Return floating point type with specified width. 337261991Sdim RealType getRealTypeByWidth(unsigned BitWidth) const; 338261991Sdim 339341825Sdim /// Return the alignment (in bits) of the specified integer type enum. 340239462Sdim /// 341239462Sdim /// For example, SignedInt -> getIntAlign(). 342199482Srdivacky unsigned getTypeAlign(IntType T) const; 343199482Srdivacky 344341825Sdim /// Returns true if the type is signed; false otherwise. 345218893Sdim static bool isTypeSigned(IntType T); 346198398Srdivacky 347341825Sdim /// Return the width of pointers on this target, for the 348193326Sed /// specified address space. 349193326Sed uint64_t getPointerWidth(unsigned AddrSpace) const { 350193326Sed return AddrSpace == 0 ? PointerWidth : getPointerWidthV(AddrSpace); 351193326Sed } 352193326Sed uint64_t getPointerAlign(unsigned AddrSpace) const { 353193326Sed return AddrSpace == 0 ? PointerAlign : getPointerAlignV(AddrSpace); 354193326Sed } 355198092Srdivacky 356341825Sdim /// Return the maximum width of pointers on this target. 357314564Sdim virtual uint64_t getMaxPointerWidth() const { 358314564Sdim return PointerWidth; 359314564Sdim } 360314564Sdim 361341825Sdim /// Get integer value for null pointer. 362314564Sdim /// \param AddrSpace address space of pointee in source language. 363327952Sdim virtual uint64_t getNullPointerValue(LangAS AddrSpace) const { return 0; } 364314564Sdim 365341825Sdim /// Return the size of '_Bool' and C++ 'bool' for this target, in bits. 366218893Sdim unsigned getBoolWidth() const { return BoolWidth; } 367239462Sdim 368341825Sdim /// Return the alignment of '_Bool' and C++ 'bool' for this target. 369218893Sdim unsigned getBoolAlign() const { return BoolAlign; } 370198092Srdivacky 371198092Srdivacky unsigned getCharWidth() const { return 8; } // FIXME 372198092Srdivacky unsigned getCharAlign() const { return 8; } // FIXME 373198092Srdivacky 374341825Sdim /// Return the size of 'signed short' and 'unsigned short' for this 375239462Sdim /// target, in bits. 376193326Sed unsigned getShortWidth() const { return 16; } // FIXME 377239462Sdim 378341825Sdim /// Return the alignment of 'signed short' and 'unsigned short' for 379239462Sdim /// this target. 380193326Sed unsigned getShortAlign() const { return 16; } // FIXME 381198092Srdivacky 382193326Sed /// getIntWidth/Align - Return the size of 'signed int' and 'unsigned int' for 383193326Sed /// this target, in bits. 384193326Sed unsigned getIntWidth() const { return IntWidth; } 385193326Sed unsigned getIntAlign() const { return IntAlign; } 386198092Srdivacky 387193326Sed /// getLongWidth/Align - Return the size of 'signed long' and 'unsigned long' 388193326Sed /// for this target, in bits. 389193326Sed unsigned getLongWidth() const { return LongWidth; } 390193326Sed unsigned getLongAlign() const { return LongAlign; } 391198092Srdivacky 392193326Sed /// getLongLongWidth/Align - Return the size of 'signed long long' and 393193326Sed /// 'unsigned long long' for this target, in bits. 394193326Sed unsigned getLongLongWidth() const { return LongLongWidth; } 395193326Sed unsigned getLongLongAlign() const { return LongLongAlign; } 396198092Srdivacky 397341825Sdim /// getShortAccumWidth/Align - Return the size of 'signed short _Accum' and 398341825Sdim /// 'unsigned short _Accum' for this target, in bits. 399341825Sdim unsigned getShortAccumWidth() const { return ShortAccumWidth; } 400341825Sdim unsigned getShortAccumAlign() const { return ShortAccumAlign; } 401341825Sdim 402341825Sdim /// getAccumWidth/Align - Return the size of 'signed _Accum' and 403341825Sdim /// 'unsigned _Accum' for this target, in bits. 404341825Sdim unsigned getAccumWidth() const { return AccumWidth; } 405341825Sdim unsigned getAccumAlign() const { return AccumAlign; } 406341825Sdim 407341825Sdim /// getLongAccumWidth/Align - Return the size of 'signed long _Accum' and 408341825Sdim /// 'unsigned long _Accum' for this target, in bits. 409341825Sdim unsigned getLongAccumWidth() const { return LongAccumWidth; } 410341825Sdim unsigned getLongAccumAlign() const { return LongAccumAlign; } 411341825Sdim 412341825Sdim /// getShortFractWidth/Align - Return the size of 'signed short _Fract' and 413341825Sdim /// 'unsigned short _Fract' for this target, in bits. 414341825Sdim unsigned getShortFractWidth() const { return ShortFractWidth; } 415341825Sdim unsigned getShortFractAlign() const { return ShortFractAlign; } 416341825Sdim 417341825Sdim /// getFractWidth/Align - Return the size of 'signed _Fract' and 418341825Sdim /// 'unsigned _Fract' for this target, in bits. 419341825Sdim unsigned getFractWidth() const { return FractWidth; } 420341825Sdim unsigned getFractAlign() const { return FractAlign; } 421341825Sdim 422341825Sdim /// getLongFractWidth/Align - Return the size of 'signed long _Fract' and 423341825Sdim /// 'unsigned long _Fract' for this target, in bits. 424341825Sdim unsigned getLongFractWidth() const { return LongFractWidth; } 425341825Sdim unsigned getLongFractAlign() const { return LongFractAlign; } 426341825Sdim 427341825Sdim /// getShortAccumScale/IBits - Return the number of fractional/integral bits 428341825Sdim /// in a 'signed short _Accum' type. 429341825Sdim unsigned getShortAccumScale() const { return ShortAccumScale; } 430341825Sdim unsigned getShortAccumIBits() const { 431341825Sdim return ShortAccumWidth - ShortAccumScale - 1; 432341825Sdim } 433341825Sdim 434341825Sdim /// getAccumScale/IBits - Return the number of fractional/integral bits 435341825Sdim /// in a 'signed _Accum' type. 436341825Sdim unsigned getAccumScale() const { return AccumScale; } 437341825Sdim unsigned getAccumIBits() const { return AccumWidth - AccumScale - 1; } 438341825Sdim 439341825Sdim /// getLongAccumScale/IBits - Return the number of fractional/integral bits 440341825Sdim /// in a 'signed long _Accum' type. 441341825Sdim unsigned getLongAccumScale() const { return LongAccumScale; } 442341825Sdim unsigned getLongAccumIBits() const { 443341825Sdim return LongAccumWidth - LongAccumScale - 1; 444341825Sdim } 445341825Sdim 446341825Sdim /// getUnsignedShortAccumScale/IBits - Return the number of 447341825Sdim /// fractional/integral bits in a 'unsigned short _Accum' type. 448341825Sdim unsigned getUnsignedShortAccumScale() const { 449341825Sdim return PaddingOnUnsignedFixedPoint ? ShortAccumScale : ShortAccumScale + 1; 450341825Sdim } 451341825Sdim unsigned getUnsignedShortAccumIBits() const { 452341825Sdim return PaddingOnUnsignedFixedPoint 453341825Sdim ? getShortAccumIBits() 454341825Sdim : ShortAccumWidth - getUnsignedShortAccumScale(); 455341825Sdim } 456341825Sdim 457341825Sdim /// getUnsignedAccumScale/IBits - Return the number of fractional/integral 458341825Sdim /// bits in a 'unsigned _Accum' type. 459341825Sdim unsigned getUnsignedAccumScale() const { 460341825Sdim return PaddingOnUnsignedFixedPoint ? AccumScale : AccumScale + 1; 461341825Sdim } 462341825Sdim unsigned getUnsignedAccumIBits() const { 463341825Sdim return PaddingOnUnsignedFixedPoint ? getAccumIBits() 464341825Sdim : AccumWidth - getUnsignedAccumScale(); 465341825Sdim } 466341825Sdim 467341825Sdim /// getUnsignedLongAccumScale/IBits - Return the number of fractional/integral 468341825Sdim /// bits in a 'unsigned long _Accum' type. 469341825Sdim unsigned getUnsignedLongAccumScale() const { 470341825Sdim return PaddingOnUnsignedFixedPoint ? LongAccumScale : LongAccumScale + 1; 471341825Sdim } 472341825Sdim unsigned getUnsignedLongAccumIBits() const { 473341825Sdim return PaddingOnUnsignedFixedPoint 474341825Sdim ? getLongAccumIBits() 475341825Sdim : LongAccumWidth - getUnsignedLongAccumScale(); 476341825Sdim } 477341825Sdim 478341825Sdim /// getShortFractScale - Return the number of fractional bits 479341825Sdim /// in a 'signed short _Fract' type. 480341825Sdim unsigned getShortFractScale() const { return ShortFractWidth - 1; } 481341825Sdim 482341825Sdim /// getFractScale - Return the number of fractional bits 483341825Sdim /// in a 'signed _Fract' type. 484341825Sdim unsigned getFractScale() const { return FractWidth - 1; } 485341825Sdim 486341825Sdim /// getLongFractScale - Return the number of fractional bits 487341825Sdim /// in a 'signed long _Fract' type. 488341825Sdim unsigned getLongFractScale() const { return LongFractWidth - 1; } 489341825Sdim 490341825Sdim /// getUnsignedShortFractScale - Return the number of fractional bits 491341825Sdim /// in a 'unsigned short _Fract' type. 492341825Sdim unsigned getUnsignedShortFractScale() const { 493341825Sdim return PaddingOnUnsignedFixedPoint ? getShortFractScale() 494341825Sdim : getShortFractScale() + 1; 495341825Sdim } 496341825Sdim 497341825Sdim /// getUnsignedFractScale - Return the number of fractional bits 498341825Sdim /// in a 'unsigned _Fract' type. 499341825Sdim unsigned getUnsignedFractScale() const { 500341825Sdim return PaddingOnUnsignedFixedPoint ? getFractScale() : getFractScale() + 1; 501341825Sdim } 502341825Sdim 503341825Sdim /// getUnsignedLongFractScale - Return the number of fractional bits 504341825Sdim /// in a 'unsigned long _Fract' type. 505341825Sdim unsigned getUnsignedLongFractScale() const { 506341825Sdim return PaddingOnUnsignedFixedPoint ? getLongFractScale() 507341825Sdim : getLongFractScale() + 1; 508341825Sdim } 509341825Sdim 510341825Sdim /// Determine whether the __int128 type is supported on this target. 511296417Sdim virtual bool hasInt128Type() const { 512341825Sdim return (getPointerWidth(0) >= 64) || getTargetOpts().ForceEnableInt128; 513296417Sdim } // FIXME 514249423Sdim 515341825Sdim /// Determine whether _Float16 is supported on this target. 516341825Sdim virtual bool hasLegalHalfType() const { return HasLegalHalfType; } 517341825Sdim 518341825Sdim /// Determine whether the __float128 type is supported on this target. 519309124Sdim virtual bool hasFloat128Type() const { return HasFloat128; } 520309124Sdim 521344779Sdim /// Determine whether the _Float16 type is supported on this target. 522344779Sdim virtual bool hasFloat16Type() const { return HasFloat16; } 523344779Sdim 524341825Sdim /// Return the alignment that is suitable for storing any 525234353Sdim /// object with a fundamental alignment requirement. 526234353Sdim unsigned getSuitableAlign() const { return SuitableAlign; } 527234353Sdim 528341825Sdim /// Return the default alignment for __attribute__((aligned)) on 529288943Sdim /// this target, to be used if no alignment value is specified. 530288943Sdim unsigned getDefaultAlignForAttributeAligned() const { 531288943Sdim return DefaultAlignForAttributeAligned; 532288943Sdim } 533288943Sdim 534251662Sdim /// getMinGlobalAlign - Return the minimum alignment of a global variable, 535251662Sdim /// unless its alignment is explicitly reduced via attributes. 536251662Sdim unsigned getMinGlobalAlign() const { return MinGlobalAlign; } 537251662Sdim 538314564Sdim /// Return the largest alignment for which a suitably-sized allocation with 539314564Sdim /// '::operator new(size_t)' is guaranteed to produce a correctly-aligned 540314564Sdim /// pointer. 541314564Sdim unsigned getNewAlign() const { 542314564Sdim return NewAlign ? NewAlign : std::max(LongDoubleAlign, LongLongAlign); 543314564Sdim } 544314564Sdim 545198092Srdivacky /// getWCharWidth/Align - Return the size of 'wchar_t' for this target, in 546193326Sed /// bits. 547199482Srdivacky unsigned getWCharWidth() const { return getTypeWidth(WCharType); } 548199482Srdivacky unsigned getWCharAlign() const { return getTypeAlign(WCharType); } 549193326Sed 550198092Srdivacky /// getChar16Width/Align - Return the size of 'char16_t' for this target, in 551198092Srdivacky /// bits. 552199482Srdivacky unsigned getChar16Width() const { return getTypeWidth(Char16Type); } 553199482Srdivacky unsigned getChar16Align() const { return getTypeAlign(Char16Type); } 554198092Srdivacky 555198092Srdivacky /// getChar32Width/Align - Return the size of 'char32_t' for this target, in 556198092Srdivacky /// bits. 557199482Srdivacky unsigned getChar32Width() const { return getTypeWidth(Char32Type); } 558199482Srdivacky unsigned getChar32Align() const { return getTypeAlign(Char32Type); } 559198092Srdivacky 560226633Sdim /// getHalfWidth/Align/Format - Return the size/align/format of 'half'. 561226633Sdim unsigned getHalfWidth() const { return HalfWidth; } 562226633Sdim unsigned getHalfAlign() const { return HalfAlign; } 563226633Sdim const llvm::fltSemantics &getHalfFormat() const { return *HalfFormat; } 564226633Sdim 565193326Sed /// getFloatWidth/Align/Format - Return the size/align/format of 'float'. 566193326Sed unsigned getFloatWidth() const { return FloatWidth; } 567193326Sed unsigned getFloatAlign() const { return FloatAlign; } 568193326Sed const llvm::fltSemantics &getFloatFormat() const { return *FloatFormat; } 569193326Sed 570193326Sed /// getDoubleWidth/Align/Format - Return the size/align/format of 'double'. 571193326Sed unsigned getDoubleWidth() const { return DoubleWidth; } 572193326Sed unsigned getDoubleAlign() const { return DoubleAlign; } 573193326Sed const llvm::fltSemantics &getDoubleFormat() const { return *DoubleFormat; } 574193326Sed 575193326Sed /// getLongDoubleWidth/Align/Format - Return the size/align/format of 'long 576193326Sed /// double'. 577193326Sed unsigned getLongDoubleWidth() const { return LongDoubleWidth; } 578193326Sed unsigned getLongDoubleAlign() const { return LongDoubleAlign; } 579193326Sed const llvm::fltSemantics &getLongDoubleFormat() const { 580193326Sed return *LongDoubleFormat; 581193326Sed } 582198092Srdivacky 583309124Sdim /// getFloat128Width/Align/Format - Return the size/align/format of 584309124Sdim /// '__float128'. 585309124Sdim unsigned getFloat128Width() const { return 128; } 586309124Sdim unsigned getFloat128Align() const { return Float128Align; } 587309124Sdim const llvm::fltSemantics &getFloat128Format() const { 588309124Sdim return *Float128Format; 589309124Sdim } 590309124Sdim 591341825Sdim /// Return true if the 'long double' type should be mangled like 592288943Sdim /// __float128. 593288943Sdim virtual bool useFloat128ManglingForLongDouble() const { return false; } 594288943Sdim 595341825Sdim /// Return the value for the C99 FLT_EVAL_METHOD macro. 596234353Sdim virtual unsigned getFloatEvalMethod() const { return 0; } 597234353Sdim 598210299Sed // getLargeArrayMinWidth/Align - Return the minimum array size that is 599210299Sed // 'large' and its alignment. 600210299Sed unsigned getLargeArrayMinWidth() const { return LargeArrayMinWidth; } 601210299Sed unsigned getLargeArrayAlign() const { return LargeArrayAlign; } 602210299Sed 603341825Sdim /// Return the maximum width lock-free atomic operation which will 604239462Sdim /// ever be supported for the given target 605226633Sdim unsigned getMaxAtomicPromoteWidth() const { return MaxAtomicPromoteWidth; } 606341825Sdim /// Return the maximum width lock-free atomic operation which can be 607239462Sdim /// inlined given the supported features of the given target. 608226633Sdim unsigned getMaxAtomicInlineWidth() const { return MaxAtomicInlineWidth; } 609341825Sdim /// Set the maximum inline or promote width lock-free atomic operation 610327952Sdim /// for the given target. 611327952Sdim virtual void setMaxAtomicWidth() {} 612341825Sdim /// Returns true if the given target supports lock-free atomic 613280031Sdim /// operations at the specified width and alignment. 614280031Sdim virtual bool hasBuiltinAtomic(uint64_t AtomicSizeInBits, 615280031Sdim uint64_t AlignmentInBits) const { 616280031Sdim return AtomicSizeInBits <= AlignmentInBits && 617280031Sdim AtomicSizeInBits <= getMaxAtomicInlineWidth() && 618280031Sdim (AtomicSizeInBits <= getCharWidth() || 619280031Sdim llvm::isPowerOf2_64(AtomicSizeInBits / getCharWidth())); 620280031Sdim } 621226633Sdim 622341825Sdim /// Return the maximum vector alignment supported for the given target. 623239462Sdim unsigned getMaxVectorAlign() const { return MaxVectorAlign; } 624341825Sdim /// Return default simd alignment for the given target. Generally, this 625288943Sdim /// value is type-specific, but this alignment can be used for most of the 626288943Sdim /// types for the given target. 627288943Sdim unsigned getSimdDefaultAlign() const { return SimdDefaultAlign; } 628239462Sdim 629341825Sdim /// Return the size of intmax_t and uintmax_t for this target, in bits. 630193326Sed unsigned getIntMaxTWidth() const { 631199482Srdivacky return getTypeWidth(IntMaxType); 632193326Sed } 633198092Srdivacky 634249423Sdim // Return the size of unwind_word for this target. 635309124Sdim virtual unsigned getUnwindWordWidth() const { return getPointerWidth(0); } 636249423Sdim 637341825Sdim /// Return the "preferred" register width on this target. 638309124Sdim virtual unsigned getRegisterWidth() const { 639224145Sdim // Currently we assume the register width on the target matches the pointer 640224145Sdim // width, we can introduce a new variable for this if/when some target wants 641224145Sdim // it. 642261991Sdim return PointerWidth; 643224145Sdim } 644224145Sdim 645341825Sdim /// Returns the name of the mcount instrumentation function. 646218893Sdim const char *getMCountName() const { 647218893Sdim return MCountName; 648218893Sdim } 649218893Sdim 650341825Sdim /// Check if the Objective-C built-in boolean type should be signed 651239462Sdim /// char. 652239462Sdim /// 653239462Sdim /// Otherwise, if this returns false, the normal built-in boolean type 654239462Sdim /// should also be used for Objective-C. 655234982Sdim bool useSignedCharForObjCBool() const { 656234982Sdim return UseSignedCharForObjCBool; 657234982Sdim } 658234982Sdim void noSignedCharForObjCBool() { 659234982Sdim UseSignedCharForObjCBool = false; 660234982Sdim } 661234982Sdim 662341825Sdim /// Check whether the alignment of bit-field types is respected 663239462Sdim /// when laying out structures. 664207619Srdivacky bool useBitFieldTypeAlignment() const { 665207619Srdivacky return UseBitFieldTypeAlignment; 666207619Srdivacky } 667207619Srdivacky 668341825Sdim /// Check whether zero length bitfields should force alignment of 669239462Sdim /// the next member. 670226633Sdim bool useZeroLengthBitfieldAlignment() const { 671226633Sdim return UseZeroLengthBitfieldAlignment; 672226633Sdim } 673226633Sdim 674341825Sdim /// Get the fixed alignment value in bits for a member that follows 675239462Sdim /// a zero length bitfield. 676226633Sdim unsigned getZeroLengthBitfieldBoundary() const { 677226633Sdim return ZeroLengthBitfieldBoundary; 678226633Sdim } 679226633Sdim 680341825Sdim /// Check whether explicit bitfield alignment attributes should be 681309124Sdim // honored, as in "__attribute__((aligned(2))) int b : 1;". 682309124Sdim bool useExplicitBitFieldAlignment() const { 683309124Sdim return UseExplicitBitFieldAlignment; 684309124Sdim } 685309124Sdim 686341825Sdim /// Check whether this target support '\#pragma options align=mac68k'. 687208600Srdivacky bool hasAlignMac68kSupport() const { 688208600Srdivacky return HasAlignMac68kSupport; 689208600Srdivacky } 690208600Srdivacky 691341825Sdim /// Return the user string for the specified integer type enum. 692239462Sdim /// 693193326Sed /// For example, SignedShort -> "short". 694193326Sed static const char *getTypeName(IntType T); 695198092Srdivacky 696341825Sdim /// Return the constant suffix for the specified integer type enum. 697239462Sdim /// 698239462Sdim /// For example, SignedLong -> "L". 699276479Sdim const char *getTypeConstantSuffix(IntType T) const; 700198398Srdivacky 701341825Sdim /// Return the printf format modifier for the specified 702276479Sdim /// integer type enum. 703276479Sdim /// 704276479Sdim /// For example, SignedLong -> "l". 705276479Sdim static const char *getTypeFormatModifier(IntType T); 706276479Sdim 707341825Sdim /// Check whether the given real type should use the "fpret" flavor of 708239462Sdim /// Objective-C message passing on this target. 709210299Sed bool useObjCFPRetForRealType(RealType T) const { 710210299Sed return RealTypeUsesObjCFPRet & (1 << T); 711210299Sed } 712210299Sed 713341825Sdim /// Check whether _Complex long double should use the "fp2ret" flavor 714239462Sdim /// of Objective-C message passing on this target. 715234353Sdim bool useObjCFP2RetForComplexLongDouble() const { 716234353Sdim return ComplexLongDoubleUsesFP2Ret; 717234353Sdim } 718234353Sdim 719327952Sdim /// Check whether llvm intrinsics such as llvm.convert.to.fp16 should be used 720327952Sdim /// to convert to and from __fp16. 721327952Sdim /// FIXME: This function should be removed once all targets stop using the 722327952Sdim /// conversion intrinsics. 723327952Sdim virtual bool useFP16ConversionIntrinsics() const { 724327952Sdim return true; 725327952Sdim } 726327952Sdim 727341825Sdim /// Specify if mangling based on address space map should be used or 728261991Sdim /// not for language specific address spaces 729261991Sdim bool useAddressSpaceMapMangling() const { 730261991Sdim return UseAddrSpaceMapMangling; 731261991Sdim } 732261991Sdim 733193326Sed ///===---- Other target property query methods --------------------------===// 734198092Srdivacky 735341825Sdim /// Appends the target-specific \#define values for this 736193326Sed /// target set to the specified buffer. 737193326Sed virtual void getTargetDefines(const LangOptions &Opts, 738202379Srdivacky MacroBuilder &Builder) const = 0; 739198092Srdivacky 740198398Srdivacky 741239462Sdim /// Return information about target-specific builtins for 742193326Sed /// the current primary target, and info about which builtins are non-portable 743193326Sed /// across the current set of primary and secondary targets. 744296417Sdim virtual ArrayRef<Builtin::Info> getTargetBuiltins() const = 0; 745193326Sed 746239462Sdim /// The __builtin_clz* and __builtin_ctz* built-in 747234353Sdim /// functions are specified to have undefined results for zero inputs, but 748234353Sdim /// on targets that support these operations in a way that provides 749234353Sdim /// well-defined results for zero without loss of performance, it is a good 750234353Sdim /// idea to avoid optimizing based on that undef behavior. 751234353Sdim virtual bool isCLZForZeroUndef() const { return true; } 752234353Sdim 753341825Sdim /// Returns the kind of __builtin_va_list type that should be used 754239462Sdim /// with this target. 755239462Sdim virtual BuiltinVaListKind getBuiltinVaListKind() const = 0; 756193326Sed 757296417Sdim /// Returns whether or not type \c __builtin_ms_va_list type is 758296417Sdim /// available on this target. 759296417Sdim bool hasBuiltinMSVaList() const { return HasBuiltinMSVaList; } 760296417Sdim 761314564Sdim /// Returns true for RenderScript. 762314564Sdim bool isRenderScriptTarget() const { return IsRenderScriptTarget; } 763314564Sdim 764341825Sdim /// Returns whether the passed in string is a valid clobber in an 765239462Sdim /// inline asm statement. 766239462Sdim /// 767239462Sdim /// This is used by Sema. 768226633Sdim bool isValidClobber(StringRef Name) const; 769224145Sdim 770341825Sdim /// Returns whether the passed in string is a valid register name 771239462Sdim /// according to GCC. 772239462Sdim /// 773239462Sdim /// This is used by Sema for inline asm statements. 774341825Sdim virtual bool isValidGCCRegisterName(StringRef Name) const; 775193326Sed 776341825Sdim /// Returns the "normalized" GCC register name. 777239462Sdim /// 778314564Sdim /// ReturnCannonical true will return the register name without any additions 779314564Sdim /// such as "{}" or "%" in it's canonical form, for example: 780314564Sdim /// ReturnCanonical = true and Name = "rax", will return "ax". 781314564Sdim StringRef getNormalizedGCCRegisterName(StringRef Name, 782314564Sdim bool ReturnCanonical = false) const; 783341825Sdim 784341825Sdim /// Extracts a register from the passed constraint (if it is a 785341825Sdim /// single-register constraint) and the asm label expression related to a 786341825Sdim /// variable in the input or output list of an inline asm statement. 787341825Sdim /// 788341825Sdim /// This function is used by Sema in order to diagnose conflicts between 789341825Sdim /// the clobber list and the input/output lists. 790341825Sdim virtual StringRef getConstraintRegister(StringRef Constraint, 791341825Sdim StringRef Expression) const { 792314564Sdim return ""; 793314564Sdim } 794198092Srdivacky 795193326Sed struct ConstraintInfo { 796193326Sed enum { 797193326Sed CI_None = 0x00, 798193326Sed CI_AllowsMemory = 0x01, 799193326Sed CI_AllowsRegister = 0x02, 800280031Sdim CI_ReadWrite = 0x04, // "+r" output constraint (read and write). 801280031Sdim CI_HasMatchingInput = 0x08, // This output operand has a matching input. 802280031Sdim CI_ImmediateConstant = 0x10, // This operand must be an immediate constant 803280031Sdim CI_EarlyClobber = 0x20, // "&" output constraint (early clobber). 804193326Sed }; 805193326Sed unsigned Flags; 806193326Sed int TiedOperand; 807280031Sdim struct { 808280031Sdim int Min; 809280031Sdim int Max; 810280031Sdim } ImmRange; 811296417Sdim llvm::SmallSet<int, 4> ImmSet; 812198092Srdivacky 813193326Sed std::string ConstraintStr; // constraint: "=rm" 814193326Sed std::string Name; // Operand name: [foo] with no []'s. 815193326Sed public: 816226633Sdim ConstraintInfo(StringRef ConstraintStr, StringRef Name) 817280031Sdim : Flags(0), TiedOperand(-1), ConstraintStr(ConstraintStr.str()), 818280031Sdim Name(Name.str()) { 819280031Sdim ImmRange.Min = ImmRange.Max = 0; 820280031Sdim } 821193326Sed 822193326Sed const std::string &getConstraintStr() const { return ConstraintStr; } 823193326Sed const std::string &getName() const { return Name; } 824193326Sed bool isReadWrite() const { return (Flags & CI_ReadWrite) != 0; } 825280031Sdim bool earlyClobber() { return (Flags & CI_EarlyClobber) != 0; } 826193326Sed bool allowsRegister() const { return (Flags & CI_AllowsRegister) != 0; } 827193326Sed bool allowsMemory() const { return (Flags & CI_AllowsMemory) != 0; } 828198092Srdivacky 829341825Sdim /// Return true if this output operand has a matching 830193326Sed /// (tied) input operand. 831193326Sed bool hasMatchingInput() const { return (Flags & CI_HasMatchingInput) != 0; } 832198092Srdivacky 833341825Sdim /// Return true if this input operand is a matching 834239462Sdim /// constraint that ties it to an output operand. 835239462Sdim /// 836239462Sdim /// If this returns true then getTiedOperand will indicate which output 837239462Sdim /// operand this is tied to. 838193326Sed bool hasTiedOperand() const { return TiedOperand != -1; } 839193326Sed unsigned getTiedOperand() const { 840193326Sed assert(hasTiedOperand() && "Has no tied operand!"); 841193326Sed return (unsigned)TiedOperand; 842193326Sed } 843198092Srdivacky 844280031Sdim bool requiresImmediateConstant() const { 845280031Sdim return (Flags & CI_ImmediateConstant) != 0; 846280031Sdim } 847296417Sdim bool isValidAsmImmediate(const llvm::APInt &Value) const { 848296417Sdim return (Value.sge(ImmRange.Min) && Value.sle(ImmRange.Max)) || 849296417Sdim ImmSet.count(Value.getZExtValue()) != 0; 850296417Sdim } 851280031Sdim 852193326Sed void setIsReadWrite() { Flags |= CI_ReadWrite; } 853280031Sdim void setEarlyClobber() { Flags |= CI_EarlyClobber; } 854193326Sed void setAllowsMemory() { Flags |= CI_AllowsMemory; } 855193326Sed void setAllowsRegister() { Flags |= CI_AllowsRegister; } 856193326Sed void setHasMatchingInput() { Flags |= CI_HasMatchingInput; } 857280031Sdim void setRequiresImmediate(int Min, int Max) { 858280031Sdim Flags |= CI_ImmediateConstant; 859280031Sdim ImmRange.Min = Min; 860280031Sdim ImmRange.Max = Max; 861280031Sdim } 862296417Sdim void setRequiresImmediate(llvm::ArrayRef<int> Exacts) { 863296417Sdim Flags |= CI_ImmediateConstant; 864296417Sdim for (int Exact : Exacts) 865296417Sdim ImmSet.insert(Exact); 866296417Sdim } 867296417Sdim void setRequiresImmediate(int Exact) { 868296417Sdim Flags |= CI_ImmediateConstant; 869296417Sdim ImmSet.insert(Exact); 870296417Sdim } 871296417Sdim void setRequiresImmediate() { 872296417Sdim Flags |= CI_ImmediateConstant; 873296417Sdim ImmRange.Min = INT_MIN; 874296417Sdim ImmRange.Max = INT_MAX; 875296417Sdim } 876198092Srdivacky 877341825Sdim /// Indicate that this is an input operand that is tied to 878296417Sdim /// the specified output operand. 879239462Sdim /// 880239462Sdim /// Copy over the various constraint information from the output. 881193326Sed void setTiedOperand(unsigned N, ConstraintInfo &Output) { 882193326Sed Output.setHasMatchingInput(); 883193326Sed Flags = Output.Flags; 884193326Sed TiedOperand = N; 885193326Sed // Don't copy Name or constraint string. 886193326Sed } 887193326Sed }; 888193326Sed 889341825Sdim /// Validate register name used for global register variables. 890296417Sdim /// 891296417Sdim /// This function returns true if the register passed in RegName can be used 892296417Sdim /// for global register variables on this target. In addition, it returns 893296417Sdim /// true in HasSizeMismatch if the size of the register doesn't match the 894296417Sdim /// variable size passed in RegSize. 895296417Sdim virtual bool validateGlobalRegisterVariable(StringRef RegName, 896296417Sdim unsigned RegSize, 897296417Sdim bool &HasSizeMismatch) const { 898296417Sdim HasSizeMismatch = false; 899296417Sdim return true; 900296417Sdim } 901288943Sdim 902193326Sed // validateOutputConstraint, validateInputConstraint - Checks that 903193326Sed // a constraint is valid and provides information about it. 904193326Sed // FIXME: These should return a real error instead of just true/false. 905193326Sed bool validateOutputConstraint(ConstraintInfo &Info) const; 906296417Sdim bool validateInputConstraint(MutableArrayRef<ConstraintInfo> OutputConstraints, 907193326Sed ConstraintInfo &info) const; 908280031Sdim 909280031Sdim virtual bool validateOutputSize(StringRef /*Constraint*/, 910280031Sdim unsigned /*Size*/) const { 911280031Sdim return true; 912280031Sdim } 913280031Sdim 914249423Sdim virtual bool validateInputSize(StringRef /*Constraint*/, 915249423Sdim unsigned /*Size*/) const { 916249423Sdim return true; 917249423Sdim } 918280031Sdim virtual bool 919280031Sdim validateConstraintModifier(StringRef /*Constraint*/, 920280031Sdim char /*Modifier*/, 921280031Sdim unsigned /*Size*/, 922280031Sdim std::string &/*SuggestedModifier*/) const { 923243830Sdim return true; 924243830Sdim } 925296417Sdim virtual bool 926296417Sdim validateAsmConstraint(const char *&Name, 927296417Sdim TargetInfo::ConstraintInfo &info) const = 0; 928296417Sdim 929193326Sed bool resolveSymbolicName(const char *&Name, 930296417Sdim ArrayRef<ConstraintInfo> OutputConstraints, 931296417Sdim unsigned &Index) const; 932198092Srdivacky 933223017Sdim // Constraint parm will be left pointing at the last character of 934223017Sdim // the constraint. In practice, it won't be changed unless the 935223017Sdim // constraint is longer than one character. 936223017Sdim virtual std::string convertConstraint(const char *&Constraint) const { 937218893Sdim // 'p' defaults to 'r', but can be overridden by targets. 938223017Sdim if (*Constraint == 'p') 939218893Sdim return std::string("r"); 940223017Sdim return std::string(1, *Constraint); 941193326Sed } 942198092Srdivacky 943341825Sdim /// Returns a string of target-specific clobbers, in LLVM format. 944296417Sdim virtual const char *getClobbers() const = 0; 945296417Sdim 946341825Sdim /// Returns true if NaN encoding is IEEE 754-2008. 947288943Sdim /// Only MIPS allows a different encoding. 948288943Sdim virtual bool isNan2008() const { 949288943Sdim return true; 950288943Sdim } 951288943Sdim 952341825Sdim /// Returns the target triple of the primary target. 953198092Srdivacky const llvm::Triple &getTriple() const { 954198092Srdivacky return Triple; 955193326Sed } 956198092Srdivacky 957309124Sdim const llvm::DataLayout &getDataLayout() const { 958309124Sdim assert(DataLayout && "Uninitialized DataLayout!"); 959309124Sdim return *DataLayout; 960193326Sed } 961193326Sed 962193326Sed struct GCCRegAlias { 963193326Sed const char * const Aliases[5]; 964193326Sed const char * const Register; 965193326Sed }; 966193326Sed 967224145Sdim struct AddlRegName { 968224145Sdim const char * const Names[5]; 969224145Sdim const unsigned RegNum; 970224145Sdim }; 971224145Sdim 972341825Sdim /// Does this target support "protected" visibility? 973234353Sdim /// 974234353Sdim /// Any target which dynamic libraries will naturally support 975234353Sdim /// something like "default" (meaning that the symbol is visible 976234353Sdim /// outside this shared object) and "hidden" (meaning that it isn't) 977234353Sdim /// visibilities, but "protected" is really an ELF-specific concept 978239462Sdim /// with weird semantics designed around the convenience of dynamic 979234353Sdim /// linker implementations. Which is not to suggest that there's 980234353Sdim /// consistent target-independent semantics for "default" visibility 981234353Sdim /// either; the entire thing is pretty badly mangled. 982234353Sdim virtual bool hasProtectedVisibility() const { return true; } 983234353Sdim 984341825Sdim /// An optional hook that targets can implement to perform semantic 985239462Sdim /// checking on attribute((section("foo"))) specifiers. 986239462Sdim /// 987239462Sdim /// In this case, "foo" is passed in to be checked. If the section 988239462Sdim /// specifier is invalid, the backend should return a non-empty string 989198092Srdivacky /// that indicates the problem. 990198092Srdivacky /// 991198092Srdivacky /// This hook is a simple quality of implementation feature to catch errors 992198092Srdivacky /// and give good diagnostics in cases when the assembler or code generator 993198092Srdivacky /// would otherwise reject the section specifier. 994198092Srdivacky /// 995226633Sdim virtual std::string isValidSectionSpecifier(StringRef SR) const { 996198092Srdivacky return ""; 997193326Sed } 998193326Sed 999341825Sdim /// Set forced language options. 1000239462Sdim /// 1001199482Srdivacky /// Apply changes to the target information with respect to certain 1002321369Sdim /// language options which change the target configuration and adjust 1003321369Sdim /// the language based on the target options where applicable. 1004321369Sdim virtual void adjust(LangOptions &Opts); 1005193326Sed 1006341825Sdim /// Adjust target options based on codegen options. 1007314564Sdim virtual void adjustTargetOptions(const CodeGenOptions &CGOpts, 1008314564Sdim TargetOptions &TargetOpts) const {} 1009314564Sdim 1010341825Sdim /// Initialize the map with the default set of target features for the 1011296417Sdim /// CPU this should include all legal feature strings on the target. 1012296417Sdim /// 1013296417Sdim /// \return False on error (invalid features). 1014296417Sdim virtual bool initFeatureMap(llvm::StringMap<bool> &Features, 1015296417Sdim DiagnosticsEngine &Diags, StringRef CPU, 1016296417Sdim const std::vector<std::string> &FeatureVec) const; 1017193326Sed 1018341825Sdim /// Get the ABI currently in use. 1019276479Sdim virtual StringRef getABI() const { return StringRef(); } 1020198092Srdivacky 1021341825Sdim /// Get the C++ ABI currently in use. 1022249423Sdim TargetCXXABI getCXXABI() const { 1023249423Sdim return TheCXXABI; 1024210299Sed } 1025210299Sed 1026341825Sdim /// Target the specified CPU. 1027201361Srdivacky /// 1028239462Sdim /// \return False on error (invalid CPU name). 1029201361Srdivacky virtual bool setCPU(const std::string &Name) { 1030226633Sdim return false; 1031201361Srdivacky } 1032201361Srdivacky 1033341825Sdim /// Fill a SmallVectorImpl with the valid values to setCPU. 1034341825Sdim virtual void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {} 1035341825Sdim 1036327952Sdim /// brief Determine whether this TargetInfo supports the given CPU name. 1037327952Sdim virtual bool isValidCPUName(StringRef Name) const { 1038327952Sdim return true; 1039327952Sdim } 1040327952Sdim 1041341825Sdim /// Use the specified ABI. 1042198092Srdivacky /// 1043239462Sdim /// \return False on error (invalid ABI name). 1044198092Srdivacky virtual bool setABI(const std::string &Name) { 1045198092Srdivacky return false; 1046198092Srdivacky } 1047198092Srdivacky 1048341825Sdim /// Use the specified unit for FP math. 1049261991Sdim /// 1050261991Sdim /// \return False on error (invalid unit name). 1051261991Sdim virtual bool setFPMath(StringRef Name) { 1052261991Sdim return false; 1053261991Sdim } 1054261991Sdim 1055341825Sdim /// Enable or disable a specific target feature; 1056193326Sed /// the feature name must be valid. 1057261991Sdim virtual void setFeatureEnabled(llvm::StringMap<bool> &Features, 1058234353Sdim StringRef Name, 1059193326Sed bool Enabled) const { 1060261991Sdim Features[Name] = Enabled; 1061193326Sed } 1062193326Sed 1063341825Sdim /// Determine whether this TargetInfo supports the given feature. 1064327952Sdim virtual bool isValidFeatureName(StringRef Feature) const { 1065327952Sdim return true; 1066327952Sdim } 1067327952Sdim 1068341825Sdim /// Perform initialization based on the user configured 1069239462Sdim /// set of features (e.g., +sse4). 1070201361Srdivacky /// 1071239462Sdim /// The list is guaranteed to have at most one entry per feature. 1072239462Sdim /// 1073201361Srdivacky /// The target may modify the features list, to change which options are 1074201361Srdivacky /// passed onwards to the backend. 1075296417Sdim /// FIXME: This part should be fixed so that we can change handleTargetFeatures 1076296417Sdim /// to merely a TargetInfo initialization routine. 1077261991Sdim /// 1078261991Sdim /// \return False on error. 1079261991Sdim virtual bool handleTargetFeatures(std::vector<std::string> &Features, 1080261991Sdim DiagnosticsEngine &Diags) { 1081261991Sdim return true; 1082193326Sed } 1083193326Sed 1084341825Sdim /// Determine whether the given target has the given feature. 1085234353Sdim virtual bool hasFeature(StringRef Feature) const { 1086234353Sdim return false; 1087234353Sdim } 1088296417Sdim 1089344779Sdim /// Identify whether this target supports multiversioning of functions, 1090341825Sdim /// which requires support for cpu_supports and cpu_is functionality. 1091344779Sdim bool supportsMultiVersioning() const { 1092344779Sdim return getTriple().getArch() == llvm::Triple::x86 || 1093344779Sdim getTriple().getArch() == llvm::Triple::x86_64; 1094344779Sdim } 1095341825Sdim 1096344779Sdim /// Identify whether this target supports IFuncs. 1097344779Sdim bool supportsIFunc() const { return getTriple().isOSBinFormatELF(); } 1098344779Sdim 1099341825Sdim // Validate the contents of the __builtin_cpu_supports(const char*) 1100296417Sdim // argument. 1101296417Sdim virtual bool validateCpuSupports(StringRef Name) const { return false; } 1102296417Sdim 1103341825Sdim // Return the target-specific priority for features/cpus/vendors so 1104341825Sdim // that they can be properly sorted for checking. 1105341825Sdim virtual unsigned multiVersionSortPriority(StringRef Name) const { 1106341825Sdim return 0; 1107341825Sdim } 1108341825Sdim 1109341825Sdim // Validate the contents of the __builtin_cpu_is(const char*) 1110327952Sdim // argument. 1111327952Sdim virtual bool validateCpuIs(StringRef Name) const { return false; } 1112327952Sdim 1113341825Sdim // Validate a cpu_dispatch/cpu_specific CPU option, which is a different list 1114341825Sdim // from cpu_is, since it checks via features rather than CPUs directly. 1115341825Sdim virtual bool validateCPUSpecificCPUDispatch(StringRef Name) const { 1116341825Sdim return false; 1117341825Sdim } 1118341825Sdim 1119341825Sdim // Get the character to be added for mangling purposes for cpu_specific. 1120341825Sdim virtual char CPUSpecificManglingCharacter(StringRef Name) const { 1121341825Sdim llvm_unreachable( 1122341825Sdim "cpu_specific Multiversioning not implemented on this target"); 1123341825Sdim } 1124341825Sdim 1125341825Sdim // Get a list of the features that make up the CPU option for 1126341825Sdim // cpu_specific/cpu_dispatch so that it can be passed to llvm as optimization 1127341825Sdim // options. 1128341825Sdim virtual void getCPUSpecificCPUDispatchFeatures( 1129341825Sdim StringRef Name, llvm::SmallVectorImpl<StringRef> &Features) const { 1130341825Sdim llvm_unreachable( 1131341825Sdim "cpu_specific Multiversioning not implemented on this target"); 1132341825Sdim } 1133341825Sdim 1134341825Sdim // Returns maximal number of args passed in registers. 1135193326Sed unsigned getRegParmMax() const { 1136224145Sdim assert(RegParmMax < 7 && "RegParmMax value is larger than AST can handle"); 1137193326Sed return RegParmMax; 1138193326Sed } 1139193326Sed 1140341825Sdim /// Whether the target supports thread-local storage. 1141198092Srdivacky bool isTLSSupported() const { 1142193326Sed return TLSSupported; 1143193326Sed } 1144218893Sdim 1145341825Sdim /// Return the maximum alignment (in bits) of a TLS variable 1146288943Sdim /// 1147288943Sdim /// Gets the maximum alignment (in bits) of a TLS variable on this target. 1148288943Sdim /// Returns zero if there is no such constraint. 1149288943Sdim unsigned short getMaxTLSAlign() const { 1150288943Sdim return MaxTLSAlign; 1151288943Sdim } 1152288943Sdim 1153341825Sdim /// Whether target supports variable-length arrays. 1154327952Sdim bool isVLASupported() const { return VLASupported; } 1155327952Sdim 1156341825Sdim /// Whether the target supports SEH __try. 1157288943Sdim bool isSEHTrySupported() const { 1158288943Sdim return getTriple().isOSWindows() && 1159288943Sdim (getTriple().getArch() == llvm::Triple::x86 || 1160341825Sdim getTriple().getArch() == llvm::Triple::x86_64 || 1161341825Sdim getTriple().getArch() == llvm::Triple::aarch64); 1162288943Sdim } 1163288943Sdim 1164341825Sdim /// Return true if {|} are normal characters in the asm string. 1165239462Sdim /// 1166239462Sdim /// If this returns false (the default), then {abc|xyz} is syntax 1167207619Srdivacky /// that says that when compiling for asm variant #0, "abc" should be 1168207619Srdivacky /// generated, but when compiling for asm variant #1, "xyz" should be 1169207619Srdivacky /// generated. 1170207619Srdivacky bool hasNoAsmVariants() const { 1171207619Srdivacky return NoAsmVariants; 1172207619Srdivacky } 1173218893Sdim 1174341825Sdim /// Return the register number that __builtin_eh_return_regno would 1175239462Sdim /// return with the specified argument. 1176309124Sdim /// This corresponds with TargetLowering's getExceptionPointerRegister 1177309124Sdim /// and getExceptionSelectorRegister in the backend. 1178198092Srdivacky virtual int getEHDataRegisterNumber(unsigned RegNo) const { 1179218893Sdim return -1; 1180198092Srdivacky } 1181218893Sdim 1182341825Sdim /// Return the section to use for C++ static initialization functions. 1183210299Sed virtual const char *getStaticInitSectionSpecifier() const { 1184276479Sdim return nullptr; 1185210299Sed } 1186221345Sdim 1187327952Sdim const LangASMap &getAddressSpaceMap() const { return *AddrSpaceMap; } 1188221345Sdim 1189344779Sdim /// Map from the address space field in builtin description strings to the 1190344779Sdim /// language address space. 1191344779Sdim virtual LangAS getOpenCLBuiltinAddressSpace(unsigned AS) const { 1192344779Sdim return getLangASFromTargetAS(AS); 1193344779Sdim } 1194344779Sdim 1195344779Sdim /// Map from the address space field in builtin description strings to the 1196344779Sdim /// language address space. 1197344779Sdim virtual LangAS getCUDABuiltinAddressSpace(unsigned AS) const { 1198344779Sdim return getLangASFromTargetAS(AS); 1199344779Sdim } 1200344779Sdim 1201341825Sdim /// Return an AST address space which can be used opportunistically 1202321369Sdim /// for constant global memory. It must be possible to convert pointers into 1203321369Sdim /// this address space to LangAS::Default. If no such address space exists, 1204321369Sdim /// this may return None, and such optimizations will be disabled. 1205327952Sdim virtual llvm::Optional<LangAS> getConstantAddressSpace() const { 1206321369Sdim return LangAS::Default; 1207321369Sdim } 1208321369Sdim 1209341825Sdim /// Retrieve the name of the platform as it is used in the 1210221345Sdim /// availability attribute. 1211226633Sdim StringRef getPlatformName() const { return PlatformName; } 1212221345Sdim 1213341825Sdim /// Retrieve the minimum desired version of the platform, to 1214221345Sdim /// which the program should be compiled. 1215221345Sdim VersionTuple getPlatformMinVersion() const { return PlatformMinVersion; } 1216221345Sdim 1217234353Sdim bool isBigEndian() const { return BigEndian; } 1218314564Sdim bool isLittleEndian() const { return !BigEndian; } 1219234353Sdim 1220249423Sdim enum CallingConvMethodType { 1221249423Sdim CCMT_Unknown, 1222249423Sdim CCMT_Member, 1223249423Sdim CCMT_NonMember 1224249423Sdim }; 1225249423Sdim 1226341825Sdim /// Gets the default calling convention for the given target and 1227243830Sdim /// declaration context. 1228249423Sdim virtual CallingConv getDefaultCallingConv(CallingConvMethodType MT) const { 1229243830Sdim // Not all targets will specify an explicit calling convention that we can 1230243830Sdim // express. This will always do the right thing, even though it's not 1231243830Sdim // an explicit calling convention. 1232249423Sdim return CC_C; 1233243830Sdim } 1234243830Sdim 1235243830Sdim enum CallingConvCheckResult { 1236243830Sdim CCCR_OK, 1237288943Sdim CCCR_Warning, 1238288943Sdim CCCR_Ignore, 1239243830Sdim }; 1240243830Sdim 1241341825Sdim /// Determines whether a given calling convention is valid for the 1242296417Sdim /// target. A calling convention can either be accepted, produce a warning 1243243830Sdim /// and be substituted with the default calling convention, or (someday) 1244243830Sdim /// produce an error (such as using thiscall on a non-instance function). 1245243830Sdim virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const { 1246243830Sdim switch (CC) { 1247243830Sdim default: 1248243830Sdim return CCCR_Warning; 1249243830Sdim case CC_C: 1250243830Sdim return CCCR_OK; 1251243830Sdim } 1252243830Sdim } 1253243830Sdim 1254341825Sdim enum CallingConvKind { 1255341825Sdim CCK_Default, 1256341825Sdim CCK_ClangABI4OrPS4, 1257341825Sdim CCK_MicrosoftWin64 1258341825Sdim }; 1259341825Sdim 1260341825Sdim virtual CallingConvKind getCallingConvKind(bool ClangABICompat4) const; 1261341825Sdim 1262283526Sdim /// Controls if __builtin_longjmp / __builtin_setjmp can be lowered to 1263283526Sdim /// llvm.eh.sjlj.longjmp / llvm.eh.sjlj.setjmp. 1264283526Sdim virtual bool hasSjLjLowering() const { 1265283526Sdim return false; 1266283526Sdim } 1267283526Sdim 1268341825Sdim /// Check if the target supports CFProtection branch. 1269341825Sdim virtual bool 1270341825Sdim checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const; 1271341825Sdim 1272341825Sdim /// Check if the target supports CFProtection branch. 1273341825Sdim virtual bool 1274341825Sdim checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const; 1275341825Sdim 1276341825Sdim /// Whether target allows to overalign ABI-specified preferred alignment 1277309124Sdim virtual bool allowsLargerPreferedTypeAlignment() const { return true; } 1278309124Sdim 1279341825Sdim /// Set supported OpenCL extensions and optional core features. 1280309124Sdim virtual void setSupportedOpenCLOpts() {} 1281309124Sdim 1282341825Sdim /// Set supported OpenCL extensions as written on command line 1283314564Sdim virtual void setOpenCLExtensionOpts() { 1284314564Sdim for (const auto &Ext : getTargetOpts().OpenCLExtensionsAsWritten) { 1285314564Sdim getTargetOpts().SupportedOpenCLOptions.support(Ext); 1286314564Sdim } 1287314564Sdim } 1288314564Sdim 1289341825Sdim /// Get supported OpenCL extensions and optional core features. 1290309124Sdim OpenCLOptions &getSupportedOpenCLOpts() { 1291309124Sdim return getTargetOpts().SupportedOpenCLOptions; 1292309124Sdim } 1293309124Sdim 1294341825Sdim /// Get const supported OpenCL extensions and optional core features. 1295309124Sdim const OpenCLOptions &getSupportedOpenCLOpts() const { 1296309124Sdim return getTargetOpts().SupportedOpenCLOptions; 1297309124Sdim } 1298309124Sdim 1299327952Sdim enum OpenCLTypeKind { 1300327952Sdim OCLTK_Default, 1301327952Sdim OCLTK_ClkEvent, 1302327952Sdim OCLTK_Event, 1303327952Sdim OCLTK_Image, 1304327952Sdim OCLTK_Pipe, 1305327952Sdim OCLTK_Queue, 1306327952Sdim OCLTK_ReserveID, 1307327952Sdim OCLTK_Sampler, 1308327952Sdim }; 1309314564Sdim 1310341825Sdim /// Get address space for OpenCL type. 1311327952Sdim virtual LangAS getOpenCLTypeAddrSpace(OpenCLTypeKind TK) const; 1312327952Sdim 1313321369Sdim /// \returns Target specific vtbl ptr address space. 1314321369Sdim virtual unsigned getVtblPtrAddressSpace() const { 1315321369Sdim return 0; 1316321369Sdim } 1317321369Sdim 1318321369Sdim /// \returns If a target requires an address within a target specific address 1319321369Sdim /// space \p AddressSpace to be converted in order to be used, then return the 1320321369Sdim /// corresponding target specific DWARF address space. 1321321369Sdim /// 1322321369Sdim /// \returns Otherwise return None and no conversion will be emitted in the 1323321369Sdim /// DWARF. 1324321369Sdim virtual Optional<unsigned> getDWARFAddressSpace(unsigned AddressSpace) const { 1325321369Sdim return None; 1326321369Sdim } 1327321369Sdim 1328344779Sdim /// \returns The version of the SDK which was used during the compilation if 1329344779Sdim /// one was specified, or an empty version otherwise. 1330344779Sdim const llvm::VersionTuple &getSDKVersion() const { 1331344779Sdim return getTargetOpts().SDKVersion; 1332344779Sdim } 1333344779Sdim 1334341825Sdim /// Check the target is valid after it is fully initialized. 1335309124Sdim virtual bool validateTarget(DiagnosticsEngine &Diags) const { 1336309124Sdim return true; 1337309124Sdim } 1338309124Sdim 1339193326Sedprotected: 1340193326Sed virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { 1341193326Sed return PointerWidth; 1342193326Sed } 1343193326Sed virtual uint64_t getPointerAlignV(unsigned AddrSpace) const { 1344193326Sed return PointerAlign; 1345193326Sed } 1346193326Sed virtual enum IntType getPtrDiffTypeV(unsigned AddrSpace) const { 1347193326Sed return PtrDiffType; 1348193326Sed } 1349296417Sdim virtual ArrayRef<const char *> getGCCRegNames() const = 0; 1350296417Sdim virtual ArrayRef<GCCRegAlias> getGCCRegAliases() const = 0; 1351296417Sdim virtual ArrayRef<AddlRegName> getGCCAddlRegNames() const { 1352296417Sdim return None; 1353224145Sdim } 1354341825Sdim 1355341825Sdim private: 1356341825Sdim // Assert the values for the fractional and integral bits for each fixed point 1357341825Sdim // type follow the restrictions given in clause 6.2.6.3 of N1169. 1358341825Sdim void CheckFixedPointBits() const; 1359193326Sed}; 1360193326Sed 1361193326Sed} // end namespace clang 1362193326Sed 1363193326Sed#endif 1364