106f32e7eSjoerg //===--- TargetInfo.cpp - Information about Target machine ----------------===//
206f32e7eSjoerg //
306f32e7eSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406f32e7eSjoerg // See https://llvm.org/LICENSE.txt for license information.
506f32e7eSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606f32e7eSjoerg //
706f32e7eSjoerg //===----------------------------------------------------------------------===//
806f32e7eSjoerg //
906f32e7eSjoerg //  This file implements the TargetInfo and TargetInfoImpl interfaces.
1006f32e7eSjoerg //
1106f32e7eSjoerg //===----------------------------------------------------------------------===//
1206f32e7eSjoerg 
1306f32e7eSjoerg #include "clang/Basic/TargetInfo.h"
1406f32e7eSjoerg #include "clang/Basic/AddressSpaces.h"
1506f32e7eSjoerg #include "clang/Basic/CharInfo.h"
1606f32e7eSjoerg #include "clang/Basic/Diagnostic.h"
1706f32e7eSjoerg #include "clang/Basic/LangOptions.h"
1806f32e7eSjoerg #include "llvm/ADT/APFloat.h"
1906f32e7eSjoerg #include "llvm/ADT/STLExtras.h"
2006f32e7eSjoerg #include "llvm/Support/ErrorHandling.h"
2106f32e7eSjoerg #include "llvm/Support/TargetParser.h"
2206f32e7eSjoerg #include <cstdlib>
2306f32e7eSjoerg using namespace clang;
2406f32e7eSjoerg 
2506f32e7eSjoerg static const LangASMap DefaultAddrSpaceMap = {0};
2606f32e7eSjoerg 
2706f32e7eSjoerg // TargetInfo Constructor.
TargetInfo(const llvm::Triple & T)2806f32e7eSjoerg TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) {
2906f32e7eSjoerg   // Set defaults.  Defaults are set for a 32-bit RISC platform, like PPC or
3006f32e7eSjoerg   // SPARC.  These should be overridden by concrete targets as needed.
3106f32e7eSjoerg   BigEndian = !T.isLittleEndian();
3206f32e7eSjoerg   TLSSupported = true;
3306f32e7eSjoerg   VLASupported = true;
3406f32e7eSjoerg   NoAsmVariants = false;
3506f32e7eSjoerg   HasLegalHalfType = false;
3606f32e7eSjoerg   HasFloat128 = false;
3706f32e7eSjoerg   HasFloat16 = false;
38*13fbcb42Sjoerg   HasBFloat16 = false;
39*13fbcb42Sjoerg   HasStrictFP = false;
4006f32e7eSjoerg   PointerWidth = PointerAlign = 32;
4106f32e7eSjoerg   BoolWidth = BoolAlign = 8;
4206f32e7eSjoerg   IntWidth = IntAlign = 32;
4306f32e7eSjoerg   LongWidth = LongAlign = 32;
4406f32e7eSjoerg   LongLongWidth = LongLongAlign = 64;
4506f32e7eSjoerg 
4606f32e7eSjoerg   // Fixed point default bit widths
4706f32e7eSjoerg   ShortAccumWidth = ShortAccumAlign = 16;
4806f32e7eSjoerg   AccumWidth = AccumAlign = 32;
4906f32e7eSjoerg   LongAccumWidth = LongAccumAlign = 64;
5006f32e7eSjoerg   ShortFractWidth = ShortFractAlign = 8;
5106f32e7eSjoerg   FractWidth = FractAlign = 16;
5206f32e7eSjoerg   LongFractWidth = LongFractAlign = 32;
5306f32e7eSjoerg 
5406f32e7eSjoerg   // Fixed point default integral and fractional bit sizes
5506f32e7eSjoerg   // We give the _Accum 1 fewer fractional bits than their corresponding _Fract
5606f32e7eSjoerg   // types by default to have the same number of fractional bits between _Accum
5706f32e7eSjoerg   // and _Fract types.
5806f32e7eSjoerg   PaddingOnUnsignedFixedPoint = false;
5906f32e7eSjoerg   ShortAccumScale = 7;
6006f32e7eSjoerg   AccumScale = 15;
6106f32e7eSjoerg   LongAccumScale = 31;
6206f32e7eSjoerg 
6306f32e7eSjoerg   SuitableAlign = 64;
6406f32e7eSjoerg   DefaultAlignForAttributeAligned = 128;
6506f32e7eSjoerg   MinGlobalAlign = 0;
6606f32e7eSjoerg   // From the glibc documentation, on GNU systems, malloc guarantees 16-byte
6706f32e7eSjoerg   // alignment on 64-bit systems and 8-byte alignment on 32-bit systems. See
6806f32e7eSjoerg   // https://www.gnu.org/software/libc/manual/html_node/Malloc-Examples.html.
69*13fbcb42Sjoerg   // This alignment guarantee also applies to Windows and Android. On Darwin,
70*13fbcb42Sjoerg   // the alignment is 16 bytes on both 64-bit and 32-bit systems.
7106f32e7eSjoerg   if (T.isGNUEnvironment() || T.isWindowsMSVCEnvironment() || T.isAndroid())
7206f32e7eSjoerg     NewAlign = Triple.isArch64Bit() ? 128 : Triple.isArch32Bit() ? 64 : 0;
73*13fbcb42Sjoerg   else if (T.isOSDarwin())
74*13fbcb42Sjoerg     NewAlign = 128;
7506f32e7eSjoerg   else
7606f32e7eSjoerg     NewAlign = 0; // Infer from basic type alignment.
7706f32e7eSjoerg   HalfWidth = 16;
7806f32e7eSjoerg   HalfAlign = 16;
7906f32e7eSjoerg   FloatWidth = 32;
8006f32e7eSjoerg   FloatAlign = 32;
8106f32e7eSjoerg   DoubleWidth = 64;
8206f32e7eSjoerg   DoubleAlign = 64;
8306f32e7eSjoerg   LongDoubleWidth = 64;
8406f32e7eSjoerg   LongDoubleAlign = 64;
8506f32e7eSjoerg   Float128Align = 128;
8606f32e7eSjoerg   LargeArrayMinWidth = 0;
8706f32e7eSjoerg   LargeArrayAlign = 0;
8806f32e7eSjoerg   MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 0;
8906f32e7eSjoerg   MaxVectorAlign = 0;
9006f32e7eSjoerg   MaxTLSAlign = 0;
9106f32e7eSjoerg   SimdDefaultAlign = 0;
9206f32e7eSjoerg   SizeType = UnsignedLong;
9306f32e7eSjoerg   PtrDiffType = SignedLong;
9406f32e7eSjoerg   IntMaxType = SignedLongLong;
9506f32e7eSjoerg   IntPtrType = SignedLong;
9606f32e7eSjoerg   WCharType = SignedInt;
9706f32e7eSjoerg   WIntType = SignedInt;
9806f32e7eSjoerg   Char16Type = UnsignedShort;
9906f32e7eSjoerg   Char32Type = UnsignedInt;
10006f32e7eSjoerg   Int64Type = SignedLongLong;
101*13fbcb42Sjoerg   Int16Type = SignedShort;
10206f32e7eSjoerg   SigAtomicType = SignedInt;
10306f32e7eSjoerg   ProcessIDType = SignedInt;
10406f32e7eSjoerg   UseSignedCharForObjCBool = true;
10506f32e7eSjoerg   UseBitFieldTypeAlignment = true;
10606f32e7eSjoerg   UseZeroLengthBitfieldAlignment = false;
107*13fbcb42Sjoerg   UseLeadingZeroLengthBitfield = true;
10806f32e7eSjoerg   UseExplicitBitFieldAlignment = true;
10906f32e7eSjoerg   ZeroLengthBitfieldBoundary = 0;
110*13fbcb42Sjoerg   MaxAlignedAttribute = 0;
11106f32e7eSjoerg   HalfFormat = &llvm::APFloat::IEEEhalf();
11206f32e7eSjoerg   FloatFormat = &llvm::APFloat::IEEEsingle();
11306f32e7eSjoerg   DoubleFormat = &llvm::APFloat::IEEEdouble();
11406f32e7eSjoerg   LongDoubleFormat = &llvm::APFloat::IEEEdouble();
11506f32e7eSjoerg   Float128Format = &llvm::APFloat::IEEEquad();
11606f32e7eSjoerg   MCountName = "mcount";
117*13fbcb42Sjoerg   UserLabelPrefix = "_";
11806f32e7eSjoerg   RegParmMax = 0;
11906f32e7eSjoerg   SSERegParmMax = 0;
12006f32e7eSjoerg   HasAlignMac68kSupport = false;
12106f32e7eSjoerg   HasBuiltinMSVaList = false;
12206f32e7eSjoerg   IsRenderScriptTarget = false;
12306f32e7eSjoerg   HasAArch64SVETypes = false;
124*13fbcb42Sjoerg   HasRISCVVTypes = false;
125*13fbcb42Sjoerg   AllowAMDGPUUnsafeFPAtomics = false;
126*13fbcb42Sjoerg   ARMCDECoprocMask = 0;
12706f32e7eSjoerg 
12806f32e7eSjoerg   // Default to no types using fpret.
12906f32e7eSjoerg   RealTypeUsesObjCFPRet = 0;
13006f32e7eSjoerg 
13106f32e7eSjoerg   // Default to not using fp2ret for __Complex long double
13206f32e7eSjoerg   ComplexLongDoubleUsesFP2Ret = false;
13306f32e7eSjoerg 
13406f32e7eSjoerg   // Set the C++ ABI based on the triple.
13506f32e7eSjoerg   TheCXXABI.set(Triple.isKnownWindowsMSVCEnvironment()
13606f32e7eSjoerg                     ? TargetCXXABI::Microsoft
13706f32e7eSjoerg                     : TargetCXXABI::GenericItanium);
13806f32e7eSjoerg 
13906f32e7eSjoerg   // Default to an empty address space map.
14006f32e7eSjoerg   AddrSpaceMap = &DefaultAddrSpaceMap;
14106f32e7eSjoerg   UseAddrSpaceMapMangling = false;
14206f32e7eSjoerg 
14306f32e7eSjoerg   // Default to an unknown platform name.
14406f32e7eSjoerg   PlatformName = "unknown";
14506f32e7eSjoerg   PlatformMinVersion = VersionTuple();
146*13fbcb42Sjoerg 
147*13fbcb42Sjoerg   MaxOpenCLWorkGroupSize = 1024;
14806f32e7eSjoerg }
14906f32e7eSjoerg 
15006f32e7eSjoerg // Out of line virtual dtor for TargetInfo.
~TargetInfo()15106f32e7eSjoerg TargetInfo::~TargetInfo() {}
15206f32e7eSjoerg 
resetDataLayout(StringRef DL,const char * ULP)153*13fbcb42Sjoerg void TargetInfo::resetDataLayout(StringRef DL, const char *ULP) {
154*13fbcb42Sjoerg   DataLayoutString = DL.str();
155*13fbcb42Sjoerg   UserLabelPrefix = ULP;
15606f32e7eSjoerg }
15706f32e7eSjoerg 
15806f32e7eSjoerg bool
checkCFProtectionBranchSupported(DiagnosticsEngine & Diags) const15906f32e7eSjoerg TargetInfo::checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const {
16006f32e7eSjoerg   Diags.Report(diag::err_opt_not_valid_on_target) << "cf-protection=branch";
16106f32e7eSjoerg   return false;
16206f32e7eSjoerg }
16306f32e7eSjoerg 
16406f32e7eSjoerg bool
checkCFProtectionReturnSupported(DiagnosticsEngine & Diags) const16506f32e7eSjoerg TargetInfo::checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const {
16606f32e7eSjoerg   Diags.Report(diag::err_opt_not_valid_on_target) << "cf-protection=return";
16706f32e7eSjoerg   return false;
16806f32e7eSjoerg }
16906f32e7eSjoerg 
17006f32e7eSjoerg /// getTypeName - Return the user string for the specified integer type enum.
17106f32e7eSjoerg /// For example, SignedShort -> "short".
getTypeName(IntType T)17206f32e7eSjoerg const char *TargetInfo::getTypeName(IntType T) {
17306f32e7eSjoerg   switch (T) {
17406f32e7eSjoerg   default: llvm_unreachable("not an integer!");
17506f32e7eSjoerg   case SignedChar:       return "signed char";
17606f32e7eSjoerg   case UnsignedChar:     return "unsigned char";
17706f32e7eSjoerg   case SignedShort:      return "short";
17806f32e7eSjoerg   case UnsignedShort:    return "unsigned short";
17906f32e7eSjoerg   case SignedInt:        return "int";
18006f32e7eSjoerg   case UnsignedInt:      return "unsigned int";
18106f32e7eSjoerg   case SignedLong:       return "long int";
18206f32e7eSjoerg   case UnsignedLong:     return "long unsigned int";
18306f32e7eSjoerg   case SignedLongLong:   return "long long int";
18406f32e7eSjoerg   case UnsignedLongLong: return "long long unsigned int";
18506f32e7eSjoerg   }
18606f32e7eSjoerg }
18706f32e7eSjoerg 
18806f32e7eSjoerg /// getTypeConstantSuffix - Return the constant suffix for the specified
18906f32e7eSjoerg /// integer type enum. For example, SignedLong -> "L".
getTypeConstantSuffix(IntType T) const19006f32e7eSjoerg const char *TargetInfo::getTypeConstantSuffix(IntType T) const {
19106f32e7eSjoerg   switch (T) {
19206f32e7eSjoerg   default: llvm_unreachable("not an integer!");
19306f32e7eSjoerg   case SignedChar:
19406f32e7eSjoerg   case SignedShort:
19506f32e7eSjoerg   case SignedInt:        return "";
19606f32e7eSjoerg   case SignedLong:       return "L";
19706f32e7eSjoerg   case SignedLongLong:   return "LL";
19806f32e7eSjoerg   case UnsignedChar:
19906f32e7eSjoerg     if (getCharWidth() < getIntWidth())
20006f32e7eSjoerg       return "";
20106f32e7eSjoerg     LLVM_FALLTHROUGH;
20206f32e7eSjoerg   case UnsignedShort:
20306f32e7eSjoerg     if (getShortWidth() < getIntWidth())
20406f32e7eSjoerg       return "";
20506f32e7eSjoerg     LLVM_FALLTHROUGH;
20606f32e7eSjoerg   case UnsignedInt:      return "U";
20706f32e7eSjoerg   case UnsignedLong:     return "UL";
20806f32e7eSjoerg   case UnsignedLongLong: return "ULL";
20906f32e7eSjoerg   }
21006f32e7eSjoerg }
21106f32e7eSjoerg 
21206f32e7eSjoerg /// getTypeFormatModifier - Return the printf format modifier for the
21306f32e7eSjoerg /// specified integer type enum. For example, SignedLong -> "l".
21406f32e7eSjoerg 
getTypeFormatModifier(IntType T)21506f32e7eSjoerg const char *TargetInfo::getTypeFormatModifier(IntType T) {
21606f32e7eSjoerg   switch (T) {
21706f32e7eSjoerg   default: llvm_unreachable("not an integer!");
21806f32e7eSjoerg   case SignedChar:
21906f32e7eSjoerg   case UnsignedChar:     return "hh";
22006f32e7eSjoerg   case SignedShort:
22106f32e7eSjoerg   case UnsignedShort:    return "h";
22206f32e7eSjoerg   case SignedInt:
22306f32e7eSjoerg   case UnsignedInt:      return "";
22406f32e7eSjoerg   case SignedLong:
22506f32e7eSjoerg   case UnsignedLong:     return "l";
22606f32e7eSjoerg   case SignedLongLong:
22706f32e7eSjoerg   case UnsignedLongLong: return "ll";
22806f32e7eSjoerg   }
22906f32e7eSjoerg }
23006f32e7eSjoerg 
23106f32e7eSjoerg /// getTypeWidth - Return the width (in bits) of the specified integer type
23206f32e7eSjoerg /// enum. For example, SignedInt -> getIntWidth().
getTypeWidth(IntType T) const23306f32e7eSjoerg unsigned TargetInfo::getTypeWidth(IntType T) const {
23406f32e7eSjoerg   switch (T) {
23506f32e7eSjoerg   default: llvm_unreachable("not an integer!");
23606f32e7eSjoerg   case SignedChar:
23706f32e7eSjoerg   case UnsignedChar:     return getCharWidth();
23806f32e7eSjoerg   case SignedShort:
23906f32e7eSjoerg   case UnsignedShort:    return getShortWidth();
24006f32e7eSjoerg   case SignedInt:
24106f32e7eSjoerg   case UnsignedInt:      return getIntWidth();
24206f32e7eSjoerg   case SignedLong:
24306f32e7eSjoerg   case UnsignedLong:     return getLongWidth();
24406f32e7eSjoerg   case SignedLongLong:
24506f32e7eSjoerg   case UnsignedLongLong: return getLongLongWidth();
24606f32e7eSjoerg   };
24706f32e7eSjoerg }
24806f32e7eSjoerg 
getIntTypeByWidth(unsigned BitWidth,bool IsSigned) const24906f32e7eSjoerg TargetInfo::IntType TargetInfo::getIntTypeByWidth(
25006f32e7eSjoerg     unsigned BitWidth, bool IsSigned) const {
25106f32e7eSjoerg   if (getCharWidth() == BitWidth)
25206f32e7eSjoerg     return IsSigned ? SignedChar : UnsignedChar;
25306f32e7eSjoerg   if (getShortWidth() == BitWidth)
25406f32e7eSjoerg     return IsSigned ? SignedShort : UnsignedShort;
25506f32e7eSjoerg   if (getIntWidth() == BitWidth)
25606f32e7eSjoerg     return IsSigned ? SignedInt : UnsignedInt;
25706f32e7eSjoerg   if (getLongWidth() == BitWidth)
25806f32e7eSjoerg     return IsSigned ? SignedLong : UnsignedLong;
25906f32e7eSjoerg   if (getLongLongWidth() == BitWidth)
26006f32e7eSjoerg     return IsSigned ? SignedLongLong : UnsignedLongLong;
26106f32e7eSjoerg   return NoInt;
26206f32e7eSjoerg }
26306f32e7eSjoerg 
getLeastIntTypeByWidth(unsigned BitWidth,bool IsSigned) const26406f32e7eSjoerg TargetInfo::IntType TargetInfo::getLeastIntTypeByWidth(unsigned BitWidth,
26506f32e7eSjoerg                                                        bool IsSigned) const {
26606f32e7eSjoerg   if (getCharWidth() >= BitWidth)
26706f32e7eSjoerg     return IsSigned ? SignedChar : UnsignedChar;
26806f32e7eSjoerg   if (getShortWidth() >= BitWidth)
26906f32e7eSjoerg     return IsSigned ? SignedShort : UnsignedShort;
27006f32e7eSjoerg   if (getIntWidth() >= BitWidth)
27106f32e7eSjoerg     return IsSigned ? SignedInt : UnsignedInt;
27206f32e7eSjoerg   if (getLongWidth() >= BitWidth)
27306f32e7eSjoerg     return IsSigned ? SignedLong : UnsignedLong;
27406f32e7eSjoerg   if (getLongLongWidth() >= BitWidth)
27506f32e7eSjoerg     return IsSigned ? SignedLongLong : UnsignedLongLong;
27606f32e7eSjoerg   return NoInt;
27706f32e7eSjoerg }
27806f32e7eSjoerg 
getRealTypeByWidth(unsigned BitWidth,bool ExplicitIEEE) const279*13fbcb42Sjoerg TargetInfo::RealType TargetInfo::getRealTypeByWidth(unsigned BitWidth,
280*13fbcb42Sjoerg                                                     bool ExplicitIEEE) const {
28106f32e7eSjoerg   if (getFloatWidth() == BitWidth)
28206f32e7eSjoerg     return Float;
28306f32e7eSjoerg   if (getDoubleWidth() == BitWidth)
28406f32e7eSjoerg     return Double;
28506f32e7eSjoerg 
28606f32e7eSjoerg   switch (BitWidth) {
28706f32e7eSjoerg   case 96:
28806f32e7eSjoerg     if (&getLongDoubleFormat() == &llvm::APFloat::x87DoubleExtended())
28906f32e7eSjoerg       return LongDouble;
29006f32e7eSjoerg     break;
29106f32e7eSjoerg   case 128:
292*13fbcb42Sjoerg     // The caller explicitly asked for an IEEE compliant type but we still
293*13fbcb42Sjoerg     // have to check if the target supports it.
294*13fbcb42Sjoerg     if (ExplicitIEEE)
295*13fbcb42Sjoerg       return hasFloat128Type() ? Float128 : NoFloat;
29606f32e7eSjoerg     if (&getLongDoubleFormat() == &llvm::APFloat::PPCDoubleDouble() ||
29706f32e7eSjoerg         &getLongDoubleFormat() == &llvm::APFloat::IEEEquad())
29806f32e7eSjoerg       return LongDouble;
29906f32e7eSjoerg     if (hasFloat128Type())
30006f32e7eSjoerg       return Float128;
30106f32e7eSjoerg     break;
30206f32e7eSjoerg   }
30306f32e7eSjoerg 
30406f32e7eSjoerg   return NoFloat;
30506f32e7eSjoerg }
30606f32e7eSjoerg 
30706f32e7eSjoerg /// getTypeAlign - Return the alignment (in bits) of the specified integer type
30806f32e7eSjoerg /// enum. For example, SignedInt -> getIntAlign().
getTypeAlign(IntType T) const30906f32e7eSjoerg unsigned TargetInfo::getTypeAlign(IntType T) const {
31006f32e7eSjoerg   switch (T) {
31106f32e7eSjoerg   default: llvm_unreachable("not an integer!");
31206f32e7eSjoerg   case SignedChar:
31306f32e7eSjoerg   case UnsignedChar:     return getCharAlign();
31406f32e7eSjoerg   case SignedShort:
31506f32e7eSjoerg   case UnsignedShort:    return getShortAlign();
31606f32e7eSjoerg   case SignedInt:
31706f32e7eSjoerg   case UnsignedInt:      return getIntAlign();
31806f32e7eSjoerg   case SignedLong:
31906f32e7eSjoerg   case UnsignedLong:     return getLongAlign();
32006f32e7eSjoerg   case SignedLongLong:
32106f32e7eSjoerg   case UnsignedLongLong: return getLongLongAlign();
32206f32e7eSjoerg   };
32306f32e7eSjoerg }
32406f32e7eSjoerg 
32506f32e7eSjoerg /// isTypeSigned - Return whether an integer types is signed. Returns true if
32606f32e7eSjoerg /// the type is signed; false otherwise.
isTypeSigned(IntType T)32706f32e7eSjoerg bool TargetInfo::isTypeSigned(IntType T) {
32806f32e7eSjoerg   switch (T) {
32906f32e7eSjoerg   default: llvm_unreachable("not an integer!");
33006f32e7eSjoerg   case SignedChar:
33106f32e7eSjoerg   case SignedShort:
33206f32e7eSjoerg   case SignedInt:
33306f32e7eSjoerg   case SignedLong:
33406f32e7eSjoerg   case SignedLongLong:
33506f32e7eSjoerg     return true;
33606f32e7eSjoerg   case UnsignedChar:
33706f32e7eSjoerg   case UnsignedShort:
33806f32e7eSjoerg   case UnsignedInt:
33906f32e7eSjoerg   case UnsignedLong:
34006f32e7eSjoerg   case UnsignedLongLong:
34106f32e7eSjoerg     return false;
34206f32e7eSjoerg   };
34306f32e7eSjoerg }
34406f32e7eSjoerg 
34506f32e7eSjoerg /// adjust - Set forced language options.
34606f32e7eSjoerg /// Apply changes to the target information with respect to certain
34706f32e7eSjoerg /// language options which change the target configuration and adjust
34806f32e7eSjoerg /// the language based on the target options where applicable.
adjust(LangOptions & Opts)34906f32e7eSjoerg void TargetInfo::adjust(LangOptions &Opts) {
35006f32e7eSjoerg   if (Opts.NoBitFieldTypeAlign)
35106f32e7eSjoerg     UseBitFieldTypeAlignment = false;
35206f32e7eSjoerg 
35306f32e7eSjoerg   switch (Opts.WCharSize) {
35406f32e7eSjoerg   default: llvm_unreachable("invalid wchar_t width");
35506f32e7eSjoerg   case 0: break;
35606f32e7eSjoerg   case 1: WCharType = Opts.WCharIsSigned ? SignedChar : UnsignedChar; break;
35706f32e7eSjoerg   case 2: WCharType = Opts.WCharIsSigned ? SignedShort : UnsignedShort; break;
35806f32e7eSjoerg   case 4: WCharType = Opts.WCharIsSigned ? SignedInt : UnsignedInt; break;
35906f32e7eSjoerg   }
36006f32e7eSjoerg 
36106f32e7eSjoerg   if (Opts.AlignDouble) {
36206f32e7eSjoerg     DoubleAlign = LongLongAlign = 64;
36306f32e7eSjoerg     LongDoubleAlign = 64;
36406f32e7eSjoerg   }
36506f32e7eSjoerg 
36606f32e7eSjoerg   if (Opts.OpenCL) {
36706f32e7eSjoerg     // OpenCL C requires specific widths for types, irrespective of
36806f32e7eSjoerg     // what these normally are for the target.
36906f32e7eSjoerg     // We also define long long and long double here, although the
37006f32e7eSjoerg     // OpenCL standard only mentions these as "reserved".
37106f32e7eSjoerg     IntWidth = IntAlign = 32;
37206f32e7eSjoerg     LongWidth = LongAlign = 64;
37306f32e7eSjoerg     LongLongWidth = LongLongAlign = 128;
37406f32e7eSjoerg     HalfWidth = HalfAlign = 16;
37506f32e7eSjoerg     FloatWidth = FloatAlign = 32;
37606f32e7eSjoerg 
37706f32e7eSjoerg     // Embedded 32-bit targets (OpenCL EP) might have double C type
37806f32e7eSjoerg     // defined as float. Let's not override this as it might lead
37906f32e7eSjoerg     // to generating illegal code that uses 64bit doubles.
38006f32e7eSjoerg     if (DoubleWidth != FloatWidth) {
38106f32e7eSjoerg       DoubleWidth = DoubleAlign = 64;
38206f32e7eSjoerg       DoubleFormat = &llvm::APFloat::IEEEdouble();
38306f32e7eSjoerg     }
38406f32e7eSjoerg     LongDoubleWidth = LongDoubleAlign = 128;
38506f32e7eSjoerg 
38606f32e7eSjoerg     unsigned MaxPointerWidth = getMaxPointerWidth();
38706f32e7eSjoerg     assert(MaxPointerWidth == 32 || MaxPointerWidth == 64);
38806f32e7eSjoerg     bool Is32BitArch = MaxPointerWidth == 32;
38906f32e7eSjoerg     SizeType = Is32BitArch ? UnsignedInt : UnsignedLong;
39006f32e7eSjoerg     PtrDiffType = Is32BitArch ? SignedInt : SignedLong;
39106f32e7eSjoerg     IntPtrType = Is32BitArch ? SignedInt : SignedLong;
39206f32e7eSjoerg 
39306f32e7eSjoerg     IntMaxType = SignedLongLong;
39406f32e7eSjoerg     Int64Type = SignedLong;
39506f32e7eSjoerg 
39606f32e7eSjoerg     HalfFormat = &llvm::APFloat::IEEEhalf();
39706f32e7eSjoerg     FloatFormat = &llvm::APFloat::IEEEsingle();
39806f32e7eSjoerg     LongDoubleFormat = &llvm::APFloat::IEEEquad();
39906f32e7eSjoerg   }
40006f32e7eSjoerg 
401*13fbcb42Sjoerg   if (Opts.DoubleSize) {
402*13fbcb42Sjoerg     if (Opts.DoubleSize == 32) {
403*13fbcb42Sjoerg       DoubleWidth = 32;
404*13fbcb42Sjoerg       LongDoubleWidth = 32;
405*13fbcb42Sjoerg       DoubleFormat = &llvm::APFloat::IEEEsingle();
406*13fbcb42Sjoerg       LongDoubleFormat = &llvm::APFloat::IEEEsingle();
407*13fbcb42Sjoerg     } else if (Opts.DoubleSize == 64) {
408*13fbcb42Sjoerg       DoubleWidth = 64;
409*13fbcb42Sjoerg       LongDoubleWidth = 64;
410*13fbcb42Sjoerg       DoubleFormat = &llvm::APFloat::IEEEdouble();
411*13fbcb42Sjoerg       LongDoubleFormat = &llvm::APFloat::IEEEdouble();
412*13fbcb42Sjoerg     }
413*13fbcb42Sjoerg   }
414*13fbcb42Sjoerg 
41506f32e7eSjoerg   if (Opts.LongDoubleSize) {
41606f32e7eSjoerg     if (Opts.LongDoubleSize == DoubleWidth) {
41706f32e7eSjoerg       LongDoubleWidth = DoubleWidth;
41806f32e7eSjoerg       LongDoubleAlign = DoubleAlign;
41906f32e7eSjoerg       LongDoubleFormat = DoubleFormat;
42006f32e7eSjoerg     } else if (Opts.LongDoubleSize == 128) {
42106f32e7eSjoerg       LongDoubleWidth = LongDoubleAlign = 128;
42206f32e7eSjoerg       LongDoubleFormat = &llvm::APFloat::IEEEquad();
42306f32e7eSjoerg     }
42406f32e7eSjoerg   }
42506f32e7eSjoerg 
42606f32e7eSjoerg   if (Opts.NewAlignOverride)
42706f32e7eSjoerg     NewAlign = Opts.NewAlignOverride * getCharWidth();
42806f32e7eSjoerg 
42906f32e7eSjoerg   // Each unsigned fixed point type has the same number of fractional bits as
43006f32e7eSjoerg   // its corresponding signed type.
43106f32e7eSjoerg   PaddingOnUnsignedFixedPoint |= Opts.PaddingOnUnsignedFixedPoint;
43206f32e7eSjoerg   CheckFixedPointBits();
43306f32e7eSjoerg }
43406f32e7eSjoerg 
initFeatureMap(llvm::StringMap<bool> & Features,DiagnosticsEngine & Diags,StringRef CPU,const std::vector<std::string> & FeatureVec) const43506f32e7eSjoerg bool TargetInfo::initFeatureMap(
43606f32e7eSjoerg     llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
43706f32e7eSjoerg     const std::vector<std::string> &FeatureVec) const {
43806f32e7eSjoerg   for (const auto &F : FeatureVec) {
43906f32e7eSjoerg     StringRef Name = F;
44006f32e7eSjoerg     // Apply the feature via the target.
44106f32e7eSjoerg     bool Enabled = Name[0] == '+';
44206f32e7eSjoerg     setFeatureEnabled(Features, Name.substr(1), Enabled);
44306f32e7eSjoerg   }
44406f32e7eSjoerg   return true;
44506f32e7eSjoerg }
44606f32e7eSjoerg 
44706f32e7eSjoerg TargetInfo::CallingConvKind
getCallingConvKind(bool ClangABICompat4) const44806f32e7eSjoerg TargetInfo::getCallingConvKind(bool ClangABICompat4) const {
44906f32e7eSjoerg   if (getCXXABI() != TargetCXXABI::Microsoft &&
45006f32e7eSjoerg       (ClangABICompat4 || getTriple().getOS() == llvm::Triple::PS4))
45106f32e7eSjoerg     return CCK_ClangABI4OrPS4;
45206f32e7eSjoerg   return CCK_Default;
45306f32e7eSjoerg }
45406f32e7eSjoerg 
getOpenCLTypeAddrSpace(OpenCLTypeKind TK) const45506f32e7eSjoerg LangAS TargetInfo::getOpenCLTypeAddrSpace(OpenCLTypeKind TK) const {
45606f32e7eSjoerg   switch (TK) {
45706f32e7eSjoerg   case OCLTK_Image:
45806f32e7eSjoerg   case OCLTK_Pipe:
45906f32e7eSjoerg     return LangAS::opencl_global;
46006f32e7eSjoerg 
46106f32e7eSjoerg   case OCLTK_Sampler:
46206f32e7eSjoerg     return LangAS::opencl_constant;
46306f32e7eSjoerg 
46406f32e7eSjoerg   default:
46506f32e7eSjoerg     return LangAS::Default;
46606f32e7eSjoerg   }
46706f32e7eSjoerg }
46806f32e7eSjoerg 
46906f32e7eSjoerg //===----------------------------------------------------------------------===//
47006f32e7eSjoerg 
47106f32e7eSjoerg 
removeGCCRegisterPrefix(StringRef Name)47206f32e7eSjoerg static StringRef removeGCCRegisterPrefix(StringRef Name) {
47306f32e7eSjoerg   if (Name[0] == '%' || Name[0] == '#')
47406f32e7eSjoerg     Name = Name.substr(1);
47506f32e7eSjoerg 
47606f32e7eSjoerg   return Name;
47706f32e7eSjoerg }
47806f32e7eSjoerg 
47906f32e7eSjoerg /// isValidClobber - Returns whether the passed in string is
48006f32e7eSjoerg /// a valid clobber in an inline asm statement. This is used by
48106f32e7eSjoerg /// Sema.
isValidClobber(StringRef Name) const48206f32e7eSjoerg bool TargetInfo::isValidClobber(StringRef Name) const {
483*13fbcb42Sjoerg   return (isValidGCCRegisterName(Name) || Name == "memory" || Name == "cc" ||
484*13fbcb42Sjoerg           Name == "unwind");
48506f32e7eSjoerg }
48606f32e7eSjoerg 
48706f32e7eSjoerg /// isValidGCCRegisterName - Returns whether the passed in string
48806f32e7eSjoerg /// is a valid register name according to GCC. This is used by Sema for
48906f32e7eSjoerg /// inline asm statements.
isValidGCCRegisterName(StringRef Name) const49006f32e7eSjoerg bool TargetInfo::isValidGCCRegisterName(StringRef Name) const {
49106f32e7eSjoerg   if (Name.empty())
49206f32e7eSjoerg     return false;
49306f32e7eSjoerg 
49406f32e7eSjoerg   // Get rid of any register prefix.
49506f32e7eSjoerg   Name = removeGCCRegisterPrefix(Name);
49606f32e7eSjoerg   if (Name.empty())
49706f32e7eSjoerg     return false;
49806f32e7eSjoerg 
49906f32e7eSjoerg   ArrayRef<const char *> Names = getGCCRegNames();
50006f32e7eSjoerg 
50106f32e7eSjoerg   // If we have a number it maps to an entry in the register name array.
50206f32e7eSjoerg   if (isDigit(Name[0])) {
50306f32e7eSjoerg     unsigned n;
50406f32e7eSjoerg     if (!Name.getAsInteger(0, n))
50506f32e7eSjoerg       return n < Names.size();
50606f32e7eSjoerg   }
50706f32e7eSjoerg 
50806f32e7eSjoerg   // Check register names.
50906f32e7eSjoerg   if (llvm::is_contained(Names, Name))
51006f32e7eSjoerg     return true;
51106f32e7eSjoerg 
51206f32e7eSjoerg   // Check any additional names that we have.
51306f32e7eSjoerg   for (const AddlRegName &ARN : getGCCAddlRegNames())
51406f32e7eSjoerg     for (const char *AN : ARN.Names) {
51506f32e7eSjoerg       if (!AN)
51606f32e7eSjoerg         break;
51706f32e7eSjoerg       // Make sure the register that the additional name is for is within
51806f32e7eSjoerg       // the bounds of the register names from above.
51906f32e7eSjoerg       if (AN == Name && ARN.RegNum < Names.size())
52006f32e7eSjoerg         return true;
52106f32e7eSjoerg     }
52206f32e7eSjoerg 
52306f32e7eSjoerg   // Now check aliases.
52406f32e7eSjoerg   for (const GCCRegAlias &GRA : getGCCRegAliases())
52506f32e7eSjoerg     for (const char *A : GRA.Aliases) {
52606f32e7eSjoerg       if (!A)
52706f32e7eSjoerg         break;
52806f32e7eSjoerg       if (A == Name)
52906f32e7eSjoerg         return true;
53006f32e7eSjoerg     }
53106f32e7eSjoerg 
53206f32e7eSjoerg   return false;
53306f32e7eSjoerg }
53406f32e7eSjoerg 
getNormalizedGCCRegisterName(StringRef Name,bool ReturnCanonical) const53506f32e7eSjoerg StringRef TargetInfo::getNormalizedGCCRegisterName(StringRef Name,
53606f32e7eSjoerg                                                    bool ReturnCanonical) const {
53706f32e7eSjoerg   assert(isValidGCCRegisterName(Name) && "Invalid register passed in");
53806f32e7eSjoerg 
53906f32e7eSjoerg   // Get rid of any register prefix.
54006f32e7eSjoerg   Name = removeGCCRegisterPrefix(Name);
54106f32e7eSjoerg 
54206f32e7eSjoerg   ArrayRef<const char *> Names = getGCCRegNames();
54306f32e7eSjoerg 
54406f32e7eSjoerg   // First, check if we have a number.
54506f32e7eSjoerg   if (isDigit(Name[0])) {
54606f32e7eSjoerg     unsigned n;
54706f32e7eSjoerg     if (!Name.getAsInteger(0, n)) {
54806f32e7eSjoerg       assert(n < Names.size() && "Out of bounds register number!");
54906f32e7eSjoerg       return Names[n];
55006f32e7eSjoerg     }
55106f32e7eSjoerg   }
55206f32e7eSjoerg 
55306f32e7eSjoerg   // Check any additional names that we have.
55406f32e7eSjoerg   for (const AddlRegName &ARN : getGCCAddlRegNames())
55506f32e7eSjoerg     for (const char *AN : ARN.Names) {
55606f32e7eSjoerg       if (!AN)
55706f32e7eSjoerg         break;
55806f32e7eSjoerg       // Make sure the register that the additional name is for is within
55906f32e7eSjoerg       // the bounds of the register names from above.
56006f32e7eSjoerg       if (AN == Name && ARN.RegNum < Names.size())
56106f32e7eSjoerg         return ReturnCanonical ? Names[ARN.RegNum] : Name;
56206f32e7eSjoerg     }
56306f32e7eSjoerg 
56406f32e7eSjoerg   // Now check aliases.
56506f32e7eSjoerg   for (const GCCRegAlias &RA : getGCCRegAliases())
56606f32e7eSjoerg     for (const char *A : RA.Aliases) {
56706f32e7eSjoerg       if (!A)
56806f32e7eSjoerg         break;
56906f32e7eSjoerg       if (A == Name)
57006f32e7eSjoerg         return RA.Register;
57106f32e7eSjoerg     }
57206f32e7eSjoerg 
57306f32e7eSjoerg   return Name;
57406f32e7eSjoerg }
57506f32e7eSjoerg 
validateOutputConstraint(ConstraintInfo & Info) const57606f32e7eSjoerg bool TargetInfo::validateOutputConstraint(ConstraintInfo &Info) const {
57706f32e7eSjoerg   const char *Name = Info.getConstraintStr().c_str();
57806f32e7eSjoerg   // An output constraint must start with '=' or '+'
57906f32e7eSjoerg   if (*Name != '=' && *Name != '+')
58006f32e7eSjoerg     return false;
58106f32e7eSjoerg 
58206f32e7eSjoerg   if (*Name == '+')
58306f32e7eSjoerg     Info.setIsReadWrite();
58406f32e7eSjoerg 
58506f32e7eSjoerg   Name++;
58606f32e7eSjoerg   while (*Name) {
58706f32e7eSjoerg     switch (*Name) {
58806f32e7eSjoerg     default:
58906f32e7eSjoerg       if (!validateAsmConstraint(Name, Info)) {
59006f32e7eSjoerg         // FIXME: We temporarily return false
59106f32e7eSjoerg         // so we can add more constraints as we hit it.
59206f32e7eSjoerg         // Eventually, an unknown constraint should just be treated as 'g'.
59306f32e7eSjoerg         return false;
59406f32e7eSjoerg       }
59506f32e7eSjoerg       break;
59606f32e7eSjoerg     case '&': // early clobber.
59706f32e7eSjoerg       Info.setEarlyClobber();
59806f32e7eSjoerg       break;
59906f32e7eSjoerg     case '%': // commutative.
60006f32e7eSjoerg       // FIXME: Check that there is a another register after this one.
60106f32e7eSjoerg       break;
60206f32e7eSjoerg     case 'r': // general register.
60306f32e7eSjoerg       Info.setAllowsRegister();
60406f32e7eSjoerg       break;
60506f32e7eSjoerg     case 'm': // memory operand.
60606f32e7eSjoerg     case 'o': // offsetable memory operand.
60706f32e7eSjoerg     case 'V': // non-offsetable memory operand.
60806f32e7eSjoerg     case '<': // autodecrement memory operand.
60906f32e7eSjoerg     case '>': // autoincrement memory operand.
61006f32e7eSjoerg       Info.setAllowsMemory();
61106f32e7eSjoerg       break;
61206f32e7eSjoerg     case 'g': // general register, memory operand or immediate integer.
61306f32e7eSjoerg     case 'X': // any operand.
61406f32e7eSjoerg       Info.setAllowsRegister();
61506f32e7eSjoerg       Info.setAllowsMemory();
61606f32e7eSjoerg       break;
61706f32e7eSjoerg     case ',': // multiple alternative constraint.  Pass it.
61806f32e7eSjoerg       // Handle additional optional '=' or '+' modifiers.
61906f32e7eSjoerg       if (Name[1] == '=' || Name[1] == '+')
62006f32e7eSjoerg         Name++;
62106f32e7eSjoerg       break;
62206f32e7eSjoerg     case '#': // Ignore as constraint.
62306f32e7eSjoerg       while (Name[1] && Name[1] != ',')
62406f32e7eSjoerg         Name++;
62506f32e7eSjoerg       break;
62606f32e7eSjoerg     case '?': // Disparage slightly code.
62706f32e7eSjoerg     case '!': // Disparage severely.
62806f32e7eSjoerg     case '*': // Ignore for choosing register preferences.
62906f32e7eSjoerg     case 'i': // Ignore i,n,E,F as output constraints (match from the other
63006f32e7eSjoerg               // chars)
63106f32e7eSjoerg     case 'n':
63206f32e7eSjoerg     case 'E':
63306f32e7eSjoerg     case 'F':
63406f32e7eSjoerg       break;  // Pass them.
63506f32e7eSjoerg     }
63606f32e7eSjoerg 
63706f32e7eSjoerg     Name++;
63806f32e7eSjoerg   }
63906f32e7eSjoerg 
64006f32e7eSjoerg   // Early clobber with a read-write constraint which doesn't permit registers
64106f32e7eSjoerg   // is invalid.
64206f32e7eSjoerg   if (Info.earlyClobber() && Info.isReadWrite() && !Info.allowsRegister())
64306f32e7eSjoerg     return false;
64406f32e7eSjoerg 
64506f32e7eSjoerg   // If a constraint allows neither memory nor register operands it contains
64606f32e7eSjoerg   // only modifiers. Reject it.
64706f32e7eSjoerg   return Info.allowsMemory() || Info.allowsRegister();
64806f32e7eSjoerg }
64906f32e7eSjoerg 
resolveSymbolicName(const char * & Name,ArrayRef<ConstraintInfo> OutputConstraints,unsigned & Index) const65006f32e7eSjoerg bool TargetInfo::resolveSymbolicName(const char *&Name,
65106f32e7eSjoerg                                      ArrayRef<ConstraintInfo> OutputConstraints,
65206f32e7eSjoerg                                      unsigned &Index) const {
65306f32e7eSjoerg   assert(*Name == '[' && "Symbolic name did not start with '['");
65406f32e7eSjoerg   Name++;
65506f32e7eSjoerg   const char *Start = Name;
65606f32e7eSjoerg   while (*Name && *Name != ']')
65706f32e7eSjoerg     Name++;
65806f32e7eSjoerg 
65906f32e7eSjoerg   if (!*Name) {
66006f32e7eSjoerg     // Missing ']'
66106f32e7eSjoerg     return false;
66206f32e7eSjoerg   }
66306f32e7eSjoerg 
66406f32e7eSjoerg   std::string SymbolicName(Start, Name - Start);
66506f32e7eSjoerg 
66606f32e7eSjoerg   for (Index = 0; Index != OutputConstraints.size(); ++Index)
66706f32e7eSjoerg     if (SymbolicName == OutputConstraints[Index].getName())
66806f32e7eSjoerg       return true;
66906f32e7eSjoerg 
67006f32e7eSjoerg   return false;
67106f32e7eSjoerg }
67206f32e7eSjoerg 
validateInputConstraint(MutableArrayRef<ConstraintInfo> OutputConstraints,ConstraintInfo & Info) const67306f32e7eSjoerg bool TargetInfo::validateInputConstraint(
67406f32e7eSjoerg                               MutableArrayRef<ConstraintInfo> OutputConstraints,
67506f32e7eSjoerg                               ConstraintInfo &Info) const {
67606f32e7eSjoerg   const char *Name = Info.ConstraintStr.c_str();
67706f32e7eSjoerg 
67806f32e7eSjoerg   if (!*Name)
67906f32e7eSjoerg     return false;
68006f32e7eSjoerg 
68106f32e7eSjoerg   while (*Name) {
68206f32e7eSjoerg     switch (*Name) {
68306f32e7eSjoerg     default:
68406f32e7eSjoerg       // Check if we have a matching constraint
68506f32e7eSjoerg       if (*Name >= '0' && *Name <= '9') {
68606f32e7eSjoerg         const char *DigitStart = Name;
68706f32e7eSjoerg         while (Name[1] >= '0' && Name[1] <= '9')
68806f32e7eSjoerg           Name++;
68906f32e7eSjoerg         const char *DigitEnd = Name;
69006f32e7eSjoerg         unsigned i;
69106f32e7eSjoerg         if (StringRef(DigitStart, DigitEnd - DigitStart + 1)
69206f32e7eSjoerg                 .getAsInteger(10, i))
69306f32e7eSjoerg           return false;
69406f32e7eSjoerg 
69506f32e7eSjoerg         // Check if matching constraint is out of bounds.
69606f32e7eSjoerg         if (i >= OutputConstraints.size()) return false;
69706f32e7eSjoerg 
69806f32e7eSjoerg         // A number must refer to an output only operand.
69906f32e7eSjoerg         if (OutputConstraints[i].isReadWrite())
70006f32e7eSjoerg           return false;
70106f32e7eSjoerg 
70206f32e7eSjoerg         // If the constraint is already tied, it must be tied to the
70306f32e7eSjoerg         // same operand referenced to by the number.
70406f32e7eSjoerg         if (Info.hasTiedOperand() && Info.getTiedOperand() != i)
70506f32e7eSjoerg           return false;
70606f32e7eSjoerg 
70706f32e7eSjoerg         // The constraint should have the same info as the respective
70806f32e7eSjoerg         // output constraint.
70906f32e7eSjoerg         Info.setTiedOperand(i, OutputConstraints[i]);
71006f32e7eSjoerg       } else if (!validateAsmConstraint(Name, Info)) {
71106f32e7eSjoerg         // FIXME: This error return is in place temporarily so we can
71206f32e7eSjoerg         // add more constraints as we hit it.  Eventually, an unknown
71306f32e7eSjoerg         // constraint should just be treated as 'g'.
71406f32e7eSjoerg         return false;
71506f32e7eSjoerg       }
71606f32e7eSjoerg       break;
71706f32e7eSjoerg     case '[': {
71806f32e7eSjoerg       unsigned Index = 0;
71906f32e7eSjoerg       if (!resolveSymbolicName(Name, OutputConstraints, Index))
72006f32e7eSjoerg         return false;
72106f32e7eSjoerg 
72206f32e7eSjoerg       // If the constraint is already tied, it must be tied to the
72306f32e7eSjoerg       // same operand referenced to by the number.
72406f32e7eSjoerg       if (Info.hasTiedOperand() && Info.getTiedOperand() != Index)
72506f32e7eSjoerg         return false;
72606f32e7eSjoerg 
72706f32e7eSjoerg       // A number must refer to an output only operand.
72806f32e7eSjoerg       if (OutputConstraints[Index].isReadWrite())
72906f32e7eSjoerg         return false;
73006f32e7eSjoerg 
73106f32e7eSjoerg       Info.setTiedOperand(Index, OutputConstraints[Index]);
73206f32e7eSjoerg       break;
73306f32e7eSjoerg     }
73406f32e7eSjoerg     case '%': // commutative
73506f32e7eSjoerg       // FIXME: Fail if % is used with the last operand.
73606f32e7eSjoerg       break;
73706f32e7eSjoerg     case 'i': // immediate integer.
73806f32e7eSjoerg       break;
73906f32e7eSjoerg     case 'n': // immediate integer with a known value.
74006f32e7eSjoerg       Info.setRequiresImmediate();
74106f32e7eSjoerg       break;
74206f32e7eSjoerg     case 'I':  // Various constant constraints with target-specific meanings.
74306f32e7eSjoerg     case 'J':
74406f32e7eSjoerg     case 'K':
74506f32e7eSjoerg     case 'L':
74606f32e7eSjoerg     case 'M':
74706f32e7eSjoerg     case 'N':
74806f32e7eSjoerg     case 'O':
74906f32e7eSjoerg     case 'P':
75006f32e7eSjoerg       if (!validateAsmConstraint(Name, Info))
75106f32e7eSjoerg         return false;
75206f32e7eSjoerg       break;
75306f32e7eSjoerg     case 'r': // general register.
75406f32e7eSjoerg       Info.setAllowsRegister();
75506f32e7eSjoerg       break;
75606f32e7eSjoerg     case 'm': // memory operand.
75706f32e7eSjoerg     case 'o': // offsettable memory operand.
75806f32e7eSjoerg     case 'V': // non-offsettable memory operand.
75906f32e7eSjoerg     case '<': // autodecrement memory operand.
76006f32e7eSjoerg     case '>': // autoincrement memory operand.
76106f32e7eSjoerg       Info.setAllowsMemory();
76206f32e7eSjoerg       break;
76306f32e7eSjoerg     case 'g': // general register, memory operand or immediate integer.
76406f32e7eSjoerg     case 'X': // any operand.
76506f32e7eSjoerg       Info.setAllowsRegister();
76606f32e7eSjoerg       Info.setAllowsMemory();
76706f32e7eSjoerg       break;
76806f32e7eSjoerg     case 'E': // immediate floating point.
76906f32e7eSjoerg     case 'F': // immediate floating point.
77006f32e7eSjoerg     case 'p': // address operand.
77106f32e7eSjoerg       break;
77206f32e7eSjoerg     case ',': // multiple alternative constraint.  Ignore comma.
77306f32e7eSjoerg       break;
77406f32e7eSjoerg     case '#': // Ignore as constraint.
77506f32e7eSjoerg       while (Name[1] && Name[1] != ',')
77606f32e7eSjoerg         Name++;
77706f32e7eSjoerg       break;
77806f32e7eSjoerg     case '?': // Disparage slightly code.
77906f32e7eSjoerg     case '!': // Disparage severely.
78006f32e7eSjoerg     case '*': // Ignore for choosing register preferences.
78106f32e7eSjoerg       break;  // Pass them.
78206f32e7eSjoerg     }
78306f32e7eSjoerg 
78406f32e7eSjoerg     Name++;
78506f32e7eSjoerg   }
78606f32e7eSjoerg 
78706f32e7eSjoerg   return true;
78806f32e7eSjoerg }
78906f32e7eSjoerg 
CheckFixedPointBits() const79006f32e7eSjoerg void TargetInfo::CheckFixedPointBits() const {
79106f32e7eSjoerg   // Check that the number of fractional and integral bits (and maybe sign) can
79206f32e7eSjoerg   // fit into the bits given for a fixed point type.
79306f32e7eSjoerg   assert(ShortAccumScale + getShortAccumIBits() + 1 <= ShortAccumWidth);
79406f32e7eSjoerg   assert(AccumScale + getAccumIBits() + 1 <= AccumWidth);
79506f32e7eSjoerg   assert(LongAccumScale + getLongAccumIBits() + 1 <= LongAccumWidth);
79606f32e7eSjoerg   assert(getUnsignedShortAccumScale() + getUnsignedShortAccumIBits() <=
79706f32e7eSjoerg          ShortAccumWidth);
79806f32e7eSjoerg   assert(getUnsignedAccumScale() + getUnsignedAccumIBits() <= AccumWidth);
79906f32e7eSjoerg   assert(getUnsignedLongAccumScale() + getUnsignedLongAccumIBits() <=
80006f32e7eSjoerg          LongAccumWidth);
80106f32e7eSjoerg 
80206f32e7eSjoerg   assert(getShortFractScale() + 1 <= ShortFractWidth);
80306f32e7eSjoerg   assert(getFractScale() + 1 <= FractWidth);
80406f32e7eSjoerg   assert(getLongFractScale() + 1 <= LongFractWidth);
80506f32e7eSjoerg   assert(getUnsignedShortFractScale() <= ShortFractWidth);
80606f32e7eSjoerg   assert(getUnsignedFractScale() <= FractWidth);
80706f32e7eSjoerg   assert(getUnsignedLongFractScale() <= LongFractWidth);
80806f32e7eSjoerg 
80906f32e7eSjoerg   // Each unsigned fract type has either the same number of fractional bits
81006f32e7eSjoerg   // as, or one more fractional bit than, its corresponding signed fract type.
81106f32e7eSjoerg   assert(getShortFractScale() == getUnsignedShortFractScale() ||
81206f32e7eSjoerg          getShortFractScale() == getUnsignedShortFractScale() - 1);
81306f32e7eSjoerg   assert(getFractScale() == getUnsignedFractScale() ||
81406f32e7eSjoerg          getFractScale() == getUnsignedFractScale() - 1);
81506f32e7eSjoerg   assert(getLongFractScale() == getUnsignedLongFractScale() ||
81606f32e7eSjoerg          getLongFractScale() == getUnsignedLongFractScale() - 1);
81706f32e7eSjoerg 
81806f32e7eSjoerg   // When arranged in order of increasing rank (see 6.3.1.3a), the number of
81906f32e7eSjoerg   // fractional bits is nondecreasing for each of the following sets of
82006f32e7eSjoerg   // fixed-point types:
82106f32e7eSjoerg   // - signed fract types
82206f32e7eSjoerg   // - unsigned fract types
82306f32e7eSjoerg   // - signed accum types
82406f32e7eSjoerg   // - unsigned accum types.
82506f32e7eSjoerg   assert(getLongFractScale() >= getFractScale() &&
82606f32e7eSjoerg          getFractScale() >= getShortFractScale());
82706f32e7eSjoerg   assert(getUnsignedLongFractScale() >= getUnsignedFractScale() &&
82806f32e7eSjoerg          getUnsignedFractScale() >= getUnsignedShortFractScale());
82906f32e7eSjoerg   assert(LongAccumScale >= AccumScale && AccumScale >= ShortAccumScale);
83006f32e7eSjoerg   assert(getUnsignedLongAccumScale() >= getUnsignedAccumScale() &&
83106f32e7eSjoerg          getUnsignedAccumScale() >= getUnsignedShortAccumScale());
83206f32e7eSjoerg 
83306f32e7eSjoerg   // When arranged in order of increasing rank (see 6.3.1.3a), the number of
83406f32e7eSjoerg   // integral bits is nondecreasing for each of the following sets of
83506f32e7eSjoerg   // fixed-point types:
83606f32e7eSjoerg   // - signed accum types
83706f32e7eSjoerg   // - unsigned accum types
83806f32e7eSjoerg   assert(getLongAccumIBits() >= getAccumIBits() &&
83906f32e7eSjoerg          getAccumIBits() >= getShortAccumIBits());
84006f32e7eSjoerg   assert(getUnsignedLongAccumIBits() >= getUnsignedAccumIBits() &&
84106f32e7eSjoerg          getUnsignedAccumIBits() >= getUnsignedShortAccumIBits());
84206f32e7eSjoerg 
84306f32e7eSjoerg   // Each signed accum type has at least as many integral bits as its
84406f32e7eSjoerg   // corresponding unsigned accum type.
84506f32e7eSjoerg   assert(getShortAccumIBits() >= getUnsignedShortAccumIBits());
84606f32e7eSjoerg   assert(getAccumIBits() >= getUnsignedAccumIBits());
84706f32e7eSjoerg   assert(getLongAccumIBits() >= getUnsignedLongAccumIBits());
84806f32e7eSjoerg }
84906f32e7eSjoerg 
copyAuxTarget(const TargetInfo * Aux)85006f32e7eSjoerg void TargetInfo::copyAuxTarget(const TargetInfo *Aux) {
85106f32e7eSjoerg   auto *Target = static_cast<TransferrableTargetInfo*>(this);
85206f32e7eSjoerg   auto *Src = static_cast<const TransferrableTargetInfo*>(Aux);
85306f32e7eSjoerg   *Target = *Src;
85406f32e7eSjoerg }
855