xref: /freebsd-src/contrib/llvm-project/clang/lib/Basic/TargetInfo.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===--- TargetInfo.cpp - Information about Target machine ----------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
906c3fb27SDimitry Andric //  This file implements the TargetInfo interface.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h"
140b57cec5SDimitry Andric #include "clang/Basic/AddressSpaces.h"
150b57cec5SDimitry Andric #include "clang/Basic/CharInfo.h"
160b57cec5SDimitry Andric #include "clang/Basic/Diagnostic.h"
17bdd1243dSDimitry Andric #include "clang/Basic/DiagnosticFrontend.h"
180b57cec5SDimitry Andric #include "clang/Basic/LangOptions.h"
190b57cec5SDimitry Andric #include "llvm/ADT/APFloat.h"
200b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
210b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
2206c3fb27SDimitry Andric #include "llvm/TargetParser/TargetParser.h"
230b57cec5SDimitry Andric #include <cstdlib>
240b57cec5SDimitry Andric using namespace clang;
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric static const LangASMap DefaultAddrSpaceMap = {0};
27bdd1243dSDimitry Andric // The fake address space map must have a distinct entry for each
28bdd1243dSDimitry Andric // language-specific address space.
29bdd1243dSDimitry Andric static const LangASMap FakeAddrSpaceMap = {
30bdd1243dSDimitry Andric     0,  // Default
31bdd1243dSDimitry Andric     1,  // opencl_global
32bdd1243dSDimitry Andric     3,  // opencl_local
33bdd1243dSDimitry Andric     2,  // opencl_constant
34bdd1243dSDimitry Andric     0,  // opencl_private
35bdd1243dSDimitry Andric     4,  // opencl_generic
36bdd1243dSDimitry Andric     5,  // opencl_global_device
37bdd1243dSDimitry Andric     6,  // opencl_global_host
38bdd1243dSDimitry Andric     7,  // cuda_device
39bdd1243dSDimitry Andric     8,  // cuda_constant
40bdd1243dSDimitry Andric     9,  // cuda_shared
41bdd1243dSDimitry Andric     1,  // sycl_global
42bdd1243dSDimitry Andric     5,  // sycl_global_device
43bdd1243dSDimitry Andric     6,  // sycl_global_host
44bdd1243dSDimitry Andric     3,  // sycl_local
45bdd1243dSDimitry Andric     0,  // sycl_private
46bdd1243dSDimitry Andric     10, // ptr32_sptr
47bdd1243dSDimitry Andric     11, // ptr32_uptr
48bdd1243dSDimitry Andric     12, // ptr64
49bdd1243dSDimitry Andric     13, // hlsl_groupshared
5006c3fb27SDimitry Andric     20, // wasm_funcref
51bdd1243dSDimitry Andric };
520b57cec5SDimitry Andric 
530b57cec5SDimitry Andric // TargetInfo Constructor.
5404eeddc0SDimitry Andric TargetInfo::TargetInfo(const llvm::Triple &T) : Triple(T) {
550b57cec5SDimitry Andric   // Set defaults.  Defaults are set for a 32-bit RISC platform, like PPC or
560b57cec5SDimitry Andric   // SPARC.  These should be overridden by concrete targets as needed.
570b57cec5SDimitry Andric   BigEndian = !T.isLittleEndian();
580b57cec5SDimitry Andric   TLSSupported = true;
590b57cec5SDimitry Andric   VLASupported = true;
600b57cec5SDimitry Andric   NoAsmVariants = false;
610b57cec5SDimitry Andric   HasLegalHalfType = false;
62bdd1243dSDimitry Andric   HalfArgsAndReturns = false;
630b57cec5SDimitry Andric   HasFloat128 = false;
64349cc55cSDimitry Andric   HasIbm128 = false;
650b57cec5SDimitry Andric   HasFloat16 = false;
665ffd83dbSDimitry Andric   HasBFloat16 = false;
6706c3fb27SDimitry Andric   HasFullBFloat16 = false;
68349cc55cSDimitry Andric   HasLongDouble = true;
69349cc55cSDimitry Andric   HasFPReturn = true;
705ffd83dbSDimitry Andric   HasStrictFP = false;
710b57cec5SDimitry Andric   PointerWidth = PointerAlign = 32;
720b57cec5SDimitry Andric   BoolWidth = BoolAlign = 8;
730b57cec5SDimitry Andric   IntWidth = IntAlign = 32;
740b57cec5SDimitry Andric   LongWidth = LongAlign = 32;
750b57cec5SDimitry Andric   LongLongWidth = LongLongAlign = 64;
76bdd1243dSDimitry Andric   Int128Align = 128;
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric   // Fixed point default bit widths
790b57cec5SDimitry Andric   ShortAccumWidth = ShortAccumAlign = 16;
800b57cec5SDimitry Andric   AccumWidth = AccumAlign = 32;
810b57cec5SDimitry Andric   LongAccumWidth = LongAccumAlign = 64;
820b57cec5SDimitry Andric   ShortFractWidth = ShortFractAlign = 8;
830b57cec5SDimitry Andric   FractWidth = FractAlign = 16;
840b57cec5SDimitry Andric   LongFractWidth = LongFractAlign = 32;
850b57cec5SDimitry Andric 
860b57cec5SDimitry Andric   // Fixed point default integral and fractional bit sizes
870b57cec5SDimitry Andric   // We give the _Accum 1 fewer fractional bits than their corresponding _Fract
880b57cec5SDimitry Andric   // types by default to have the same number of fractional bits between _Accum
890b57cec5SDimitry Andric   // and _Fract types.
900b57cec5SDimitry Andric   PaddingOnUnsignedFixedPoint = false;
910b57cec5SDimitry Andric   ShortAccumScale = 7;
920b57cec5SDimitry Andric   AccumScale = 15;
930b57cec5SDimitry Andric   LongAccumScale = 31;
940b57cec5SDimitry Andric 
950b57cec5SDimitry Andric   SuitableAlign = 64;
960b57cec5SDimitry Andric   DefaultAlignForAttributeAligned = 128;
970b57cec5SDimitry Andric   MinGlobalAlign = 0;
980b57cec5SDimitry Andric   // From the glibc documentation, on GNU systems, malloc guarantees 16-byte
990b57cec5SDimitry Andric   // alignment on 64-bit systems and 8-byte alignment on 32-bit systems. See
1000b57cec5SDimitry Andric   // https://www.gnu.org/software/libc/manual/html_node/Malloc-Examples.html.
1012a66634dSDimitry Andric   // This alignment guarantee also applies to Windows and Android. On Darwin
1022a66634dSDimitry Andric   // and OpenBSD, the alignment is 16 bytes on both 64-bit and 32-bit systems.
10306c3fb27SDimitry Andric   if (T.isGNUEnvironment() || T.isWindowsMSVCEnvironment() || T.isAndroid() ||
10406c3fb27SDimitry Andric       T.isOHOSFamily())
1050b57cec5SDimitry Andric     NewAlign = Triple.isArch64Bit() ? 128 : Triple.isArch32Bit() ? 64 : 0;
1062a66634dSDimitry Andric   else if (T.isOSDarwin() || T.isOSOpenBSD())
107fe6060f1SDimitry Andric     NewAlign = 128;
1080b57cec5SDimitry Andric   else
1090b57cec5SDimitry Andric     NewAlign = 0; // Infer from basic type alignment.
1100b57cec5SDimitry Andric   HalfWidth = 16;
1110b57cec5SDimitry Andric   HalfAlign = 16;
1120b57cec5SDimitry Andric   FloatWidth = 32;
1130b57cec5SDimitry Andric   FloatAlign = 32;
1140b57cec5SDimitry Andric   DoubleWidth = 64;
1150b57cec5SDimitry Andric   DoubleAlign = 64;
1160b57cec5SDimitry Andric   LongDoubleWidth = 64;
1170b57cec5SDimitry Andric   LongDoubleAlign = 64;
1180b57cec5SDimitry Andric   Float128Align = 128;
119349cc55cSDimitry Andric   Ibm128Align = 128;
1200b57cec5SDimitry Andric   LargeArrayMinWidth = 0;
1210b57cec5SDimitry Andric   LargeArrayAlign = 0;
1220b57cec5SDimitry Andric   MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 0;
1230b57cec5SDimitry Andric   MaxVectorAlign = 0;
1240b57cec5SDimitry Andric   MaxTLSAlign = 0;
1250b57cec5SDimitry Andric   SizeType = UnsignedLong;
1260b57cec5SDimitry Andric   PtrDiffType = SignedLong;
1270b57cec5SDimitry Andric   IntMaxType = SignedLongLong;
1280b57cec5SDimitry Andric   IntPtrType = SignedLong;
1290b57cec5SDimitry Andric   WCharType = SignedInt;
1300b57cec5SDimitry Andric   WIntType = SignedInt;
1310b57cec5SDimitry Andric   Char16Type = UnsignedShort;
1320b57cec5SDimitry Andric   Char32Type = UnsignedInt;
1330b57cec5SDimitry Andric   Int64Type = SignedLongLong;
134fe6060f1SDimitry Andric   Int16Type = SignedShort;
1350b57cec5SDimitry Andric   SigAtomicType = SignedInt;
1360b57cec5SDimitry Andric   ProcessIDType = SignedInt;
1370b57cec5SDimitry Andric   UseSignedCharForObjCBool = true;
1380b57cec5SDimitry Andric   UseBitFieldTypeAlignment = true;
1390b57cec5SDimitry Andric   UseZeroLengthBitfieldAlignment = false;
140fe6060f1SDimitry Andric   UseLeadingZeroLengthBitfield = true;
1410b57cec5SDimitry Andric   UseExplicitBitFieldAlignment = true;
1420b57cec5SDimitry Andric   ZeroLengthBitfieldBoundary = 0;
143fe6060f1SDimitry Andric   MaxAlignedAttribute = 0;
1440b57cec5SDimitry Andric   HalfFormat = &llvm::APFloat::IEEEhalf();
1450b57cec5SDimitry Andric   FloatFormat = &llvm::APFloat::IEEEsingle();
1460b57cec5SDimitry Andric   DoubleFormat = &llvm::APFloat::IEEEdouble();
1470b57cec5SDimitry Andric   LongDoubleFormat = &llvm::APFloat::IEEEdouble();
1480b57cec5SDimitry Andric   Float128Format = &llvm::APFloat::IEEEquad();
149349cc55cSDimitry Andric   Ibm128Format = &llvm::APFloat::PPCDoubleDouble();
1500b57cec5SDimitry Andric   MCountName = "mcount";
151fe6060f1SDimitry Andric   UserLabelPrefix = "_";
1520b57cec5SDimitry Andric   RegParmMax = 0;
1530b57cec5SDimitry Andric   SSERegParmMax = 0;
1540b57cec5SDimitry Andric   HasAlignMac68kSupport = false;
1550b57cec5SDimitry Andric   HasBuiltinMSVaList = false;
1560b57cec5SDimitry Andric   IsRenderScriptTarget = false;
157a7dea167SDimitry Andric   HasAArch64SVETypes = false;
158fe6060f1SDimitry Andric   HasRISCVVTypes = false;
159e8d8bef9SDimitry Andric   AllowAMDGPUUnsafeFPAtomics = false;
160*0fca6ea1SDimitry Andric   HasUnalignedAccess = false;
1615ffd83dbSDimitry Andric   ARMCDECoprocMask = 0;
1620b57cec5SDimitry Andric 
1630b57cec5SDimitry Andric   // Default to no types using fpret.
16481ad6265SDimitry Andric   RealTypeUsesObjCFPRetMask = 0;
1650b57cec5SDimitry Andric 
1660b57cec5SDimitry Andric   // Default to not using fp2ret for __Complex long double
1670b57cec5SDimitry Andric   ComplexLongDoubleUsesFP2Ret = false;
1680b57cec5SDimitry Andric 
1690b57cec5SDimitry Andric   // Set the C++ ABI based on the triple.
1700b57cec5SDimitry Andric   TheCXXABI.set(Triple.isKnownWindowsMSVCEnvironment()
1710b57cec5SDimitry Andric                     ? TargetCXXABI::Microsoft
1720b57cec5SDimitry Andric                     : TargetCXXABI::GenericItanium);
1730b57cec5SDimitry Andric 
1740b57cec5SDimitry Andric   // Default to an empty address space map.
1750b57cec5SDimitry Andric   AddrSpaceMap = &DefaultAddrSpaceMap;
1760b57cec5SDimitry Andric   UseAddrSpaceMapMangling = false;
1770b57cec5SDimitry Andric 
1780b57cec5SDimitry Andric   // Default to an unknown platform name.
1790b57cec5SDimitry Andric   PlatformName = "unknown";
1800b57cec5SDimitry Andric   PlatformMinVersion = VersionTuple();
1815ffd83dbSDimitry Andric 
1825ffd83dbSDimitry Andric   MaxOpenCLWorkGroupSize = 1024;
18381ad6265SDimitry Andric 
18481ad6265SDimitry Andric   MaxBitIntWidth.reset();
1850b57cec5SDimitry Andric }
1860b57cec5SDimitry Andric 
1870b57cec5SDimitry Andric // Out of line virtual dtor for TargetInfo.
1880b57cec5SDimitry Andric TargetInfo::~TargetInfo() {}
1890b57cec5SDimitry Andric 
190fe6060f1SDimitry Andric void TargetInfo::resetDataLayout(StringRef DL, const char *ULP) {
191fe6060f1SDimitry Andric   DataLayoutString = DL.str();
192fe6060f1SDimitry Andric   UserLabelPrefix = ULP;
193a7dea167SDimitry Andric }
194a7dea167SDimitry Andric 
1950b57cec5SDimitry Andric bool
1960b57cec5SDimitry Andric TargetInfo::checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const {
1970b57cec5SDimitry Andric   Diags.Report(diag::err_opt_not_valid_on_target) << "cf-protection=branch";
1980b57cec5SDimitry Andric   return false;
1990b57cec5SDimitry Andric }
2000b57cec5SDimitry Andric 
2010b57cec5SDimitry Andric bool
2020b57cec5SDimitry Andric TargetInfo::checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const {
2030b57cec5SDimitry Andric   Diags.Report(diag::err_opt_not_valid_on_target) << "cf-protection=return";
2040b57cec5SDimitry Andric   return false;
2050b57cec5SDimitry Andric }
2060b57cec5SDimitry Andric 
2070b57cec5SDimitry Andric /// getTypeName - Return the user string for the specified integer type enum.
2080b57cec5SDimitry Andric /// For example, SignedShort -> "short".
2090b57cec5SDimitry Andric const char *TargetInfo::getTypeName(IntType T) {
2100b57cec5SDimitry Andric   switch (T) {
2110b57cec5SDimitry Andric   default: llvm_unreachable("not an integer!");
2120b57cec5SDimitry Andric   case SignedChar:       return "signed char";
2130b57cec5SDimitry Andric   case UnsignedChar:     return "unsigned char";
2140b57cec5SDimitry Andric   case SignedShort:      return "short";
2150b57cec5SDimitry Andric   case UnsignedShort:    return "unsigned short";
2160b57cec5SDimitry Andric   case SignedInt:        return "int";
2170b57cec5SDimitry Andric   case UnsignedInt:      return "unsigned int";
2180b57cec5SDimitry Andric   case SignedLong:       return "long int";
2190b57cec5SDimitry Andric   case UnsignedLong:     return "long unsigned int";
2200b57cec5SDimitry Andric   case SignedLongLong:   return "long long int";
2210b57cec5SDimitry Andric   case UnsignedLongLong: return "long long unsigned int";
2220b57cec5SDimitry Andric   }
2230b57cec5SDimitry Andric }
2240b57cec5SDimitry Andric 
2250b57cec5SDimitry Andric /// getTypeConstantSuffix - Return the constant suffix for the specified
2260b57cec5SDimitry Andric /// integer type enum. For example, SignedLong -> "L".
2270b57cec5SDimitry Andric const char *TargetInfo::getTypeConstantSuffix(IntType T) const {
2280b57cec5SDimitry Andric   switch (T) {
2290b57cec5SDimitry Andric   default: llvm_unreachable("not an integer!");
2300b57cec5SDimitry Andric   case SignedChar:
2310b57cec5SDimitry Andric   case SignedShort:
2320b57cec5SDimitry Andric   case SignedInt:        return "";
2330b57cec5SDimitry Andric   case SignedLong:       return "L";
2340b57cec5SDimitry Andric   case SignedLongLong:   return "LL";
2350b57cec5SDimitry Andric   case UnsignedChar:
2360b57cec5SDimitry Andric     if (getCharWidth() < getIntWidth())
2370b57cec5SDimitry Andric       return "";
238bdd1243dSDimitry Andric     [[fallthrough]];
2390b57cec5SDimitry Andric   case UnsignedShort:
2400b57cec5SDimitry Andric     if (getShortWidth() < getIntWidth())
2410b57cec5SDimitry Andric       return "";
242bdd1243dSDimitry Andric     [[fallthrough]];
2430b57cec5SDimitry Andric   case UnsignedInt:      return "U";
2440b57cec5SDimitry Andric   case UnsignedLong:     return "UL";
2450b57cec5SDimitry Andric   case UnsignedLongLong: return "ULL";
2460b57cec5SDimitry Andric   }
2470b57cec5SDimitry Andric }
2480b57cec5SDimitry Andric 
2490b57cec5SDimitry Andric /// getTypeFormatModifier - Return the printf format modifier for the
2500b57cec5SDimitry Andric /// specified integer type enum. For example, SignedLong -> "l".
2510b57cec5SDimitry Andric 
2520b57cec5SDimitry Andric const char *TargetInfo::getTypeFormatModifier(IntType T) {
2530b57cec5SDimitry Andric   switch (T) {
2540b57cec5SDimitry Andric   default: llvm_unreachable("not an integer!");
2550b57cec5SDimitry Andric   case SignedChar:
2560b57cec5SDimitry Andric   case UnsignedChar:     return "hh";
2570b57cec5SDimitry Andric   case SignedShort:
2580b57cec5SDimitry Andric   case UnsignedShort:    return "h";
2590b57cec5SDimitry Andric   case SignedInt:
2600b57cec5SDimitry Andric   case UnsignedInt:      return "";
2610b57cec5SDimitry Andric   case SignedLong:
2620b57cec5SDimitry Andric   case UnsignedLong:     return "l";
2630b57cec5SDimitry Andric   case SignedLongLong:
2640b57cec5SDimitry Andric   case UnsignedLongLong: return "ll";
2650b57cec5SDimitry Andric   }
2660b57cec5SDimitry Andric }
2670b57cec5SDimitry Andric 
2680b57cec5SDimitry Andric /// getTypeWidth - Return the width (in bits) of the specified integer type
2690b57cec5SDimitry Andric /// enum. For example, SignedInt -> getIntWidth().
2700b57cec5SDimitry Andric unsigned TargetInfo::getTypeWidth(IntType T) const {
2710b57cec5SDimitry Andric   switch (T) {
2720b57cec5SDimitry Andric   default: llvm_unreachable("not an integer!");
2730b57cec5SDimitry Andric   case SignedChar:
2740b57cec5SDimitry Andric   case UnsignedChar:     return getCharWidth();
2750b57cec5SDimitry Andric   case SignedShort:
2760b57cec5SDimitry Andric   case UnsignedShort:    return getShortWidth();
2770b57cec5SDimitry Andric   case SignedInt:
2780b57cec5SDimitry Andric   case UnsignedInt:      return getIntWidth();
2790b57cec5SDimitry Andric   case SignedLong:
2800b57cec5SDimitry Andric   case UnsignedLong:     return getLongWidth();
2810b57cec5SDimitry Andric   case SignedLongLong:
2820b57cec5SDimitry Andric   case UnsignedLongLong: return getLongLongWidth();
2830b57cec5SDimitry Andric   };
2840b57cec5SDimitry Andric }
2850b57cec5SDimitry Andric 
2860b57cec5SDimitry Andric TargetInfo::IntType TargetInfo::getIntTypeByWidth(
2870b57cec5SDimitry Andric     unsigned BitWidth, bool IsSigned) const {
2880b57cec5SDimitry Andric   if (getCharWidth() == BitWidth)
2890b57cec5SDimitry Andric     return IsSigned ? SignedChar : UnsignedChar;
2900b57cec5SDimitry Andric   if (getShortWidth() == BitWidth)
2910b57cec5SDimitry Andric     return IsSigned ? SignedShort : UnsignedShort;
2920b57cec5SDimitry Andric   if (getIntWidth() == BitWidth)
2930b57cec5SDimitry Andric     return IsSigned ? SignedInt : UnsignedInt;
2940b57cec5SDimitry Andric   if (getLongWidth() == BitWidth)
2950b57cec5SDimitry Andric     return IsSigned ? SignedLong : UnsignedLong;
2960b57cec5SDimitry Andric   if (getLongLongWidth() == BitWidth)
2970b57cec5SDimitry Andric     return IsSigned ? SignedLongLong : UnsignedLongLong;
2980b57cec5SDimitry Andric   return NoInt;
2990b57cec5SDimitry Andric }
3000b57cec5SDimitry Andric 
3010b57cec5SDimitry Andric TargetInfo::IntType TargetInfo::getLeastIntTypeByWidth(unsigned BitWidth,
3020b57cec5SDimitry Andric                                                        bool IsSigned) const {
3030b57cec5SDimitry Andric   if (getCharWidth() >= BitWidth)
3040b57cec5SDimitry Andric     return IsSigned ? SignedChar : UnsignedChar;
3050b57cec5SDimitry Andric   if (getShortWidth() >= BitWidth)
3060b57cec5SDimitry Andric     return IsSigned ? SignedShort : UnsignedShort;
3070b57cec5SDimitry Andric   if (getIntWidth() >= BitWidth)
3080b57cec5SDimitry Andric     return IsSigned ? SignedInt : UnsignedInt;
3090b57cec5SDimitry Andric   if (getLongWidth() >= BitWidth)
3100b57cec5SDimitry Andric     return IsSigned ? SignedLong : UnsignedLong;
3110b57cec5SDimitry Andric   if (getLongLongWidth() >= BitWidth)
3120b57cec5SDimitry Andric     return IsSigned ? SignedLongLong : UnsignedLongLong;
3130b57cec5SDimitry Andric   return NoInt;
3140b57cec5SDimitry Andric }
3150b57cec5SDimitry Andric 
316349cc55cSDimitry Andric FloatModeKind TargetInfo::getRealTypeByWidth(unsigned BitWidth,
317349cc55cSDimitry Andric                                              FloatModeKind ExplicitType) const {
31881ad6265SDimitry Andric   if (getHalfWidth() == BitWidth)
31981ad6265SDimitry Andric     return FloatModeKind::Half;
3200b57cec5SDimitry Andric   if (getFloatWidth() == BitWidth)
321349cc55cSDimitry Andric     return FloatModeKind::Float;
3220b57cec5SDimitry Andric   if (getDoubleWidth() == BitWidth)
323349cc55cSDimitry Andric     return FloatModeKind::Double;
3240b57cec5SDimitry Andric 
3250b57cec5SDimitry Andric   switch (BitWidth) {
3260b57cec5SDimitry Andric   case 96:
3270b57cec5SDimitry Andric     if (&getLongDoubleFormat() == &llvm::APFloat::x87DoubleExtended())
328349cc55cSDimitry Andric       return FloatModeKind::LongDouble;
3290b57cec5SDimitry Andric     break;
3300b57cec5SDimitry Andric   case 128:
3315ffd83dbSDimitry Andric     // The caller explicitly asked for an IEEE compliant type but we still
3325ffd83dbSDimitry Andric     // have to check if the target supports it.
333349cc55cSDimitry Andric     if (ExplicitType == FloatModeKind::Float128)
334349cc55cSDimitry Andric       return hasFloat128Type() ? FloatModeKind::Float128
335349cc55cSDimitry Andric                                : FloatModeKind::NoFloat;
336349cc55cSDimitry Andric     if (ExplicitType == FloatModeKind::Ibm128)
337349cc55cSDimitry Andric       return hasIbm128Type() ? FloatModeKind::Ibm128
338349cc55cSDimitry Andric                              : FloatModeKind::NoFloat;
3390b57cec5SDimitry Andric     if (&getLongDoubleFormat() == &llvm::APFloat::PPCDoubleDouble() ||
3400b57cec5SDimitry Andric         &getLongDoubleFormat() == &llvm::APFloat::IEEEquad())
341349cc55cSDimitry Andric       return FloatModeKind::LongDouble;
3420b57cec5SDimitry Andric     if (hasFloat128Type())
343349cc55cSDimitry Andric       return FloatModeKind::Float128;
3440b57cec5SDimitry Andric     break;
3450b57cec5SDimitry Andric   }
3460b57cec5SDimitry Andric 
347349cc55cSDimitry Andric   return FloatModeKind::NoFloat;
3480b57cec5SDimitry Andric }
3490b57cec5SDimitry Andric 
3500b57cec5SDimitry Andric /// getTypeAlign - Return the alignment (in bits) of the specified integer type
3510b57cec5SDimitry Andric /// enum. For example, SignedInt -> getIntAlign().
3520b57cec5SDimitry Andric unsigned TargetInfo::getTypeAlign(IntType T) const {
3530b57cec5SDimitry Andric   switch (T) {
3540b57cec5SDimitry Andric   default: llvm_unreachable("not an integer!");
3550b57cec5SDimitry Andric   case SignedChar:
3560b57cec5SDimitry Andric   case UnsignedChar:     return getCharAlign();
3570b57cec5SDimitry Andric   case SignedShort:
3580b57cec5SDimitry Andric   case UnsignedShort:    return getShortAlign();
3590b57cec5SDimitry Andric   case SignedInt:
3600b57cec5SDimitry Andric   case UnsignedInt:      return getIntAlign();
3610b57cec5SDimitry Andric   case SignedLong:
3620b57cec5SDimitry Andric   case UnsignedLong:     return getLongAlign();
3630b57cec5SDimitry Andric   case SignedLongLong:
3640b57cec5SDimitry Andric   case UnsignedLongLong: return getLongLongAlign();
3650b57cec5SDimitry Andric   };
3660b57cec5SDimitry Andric }
3670b57cec5SDimitry Andric 
3680b57cec5SDimitry Andric /// isTypeSigned - Return whether an integer types is signed. Returns true if
3690b57cec5SDimitry Andric /// the type is signed; false otherwise.
3700b57cec5SDimitry Andric bool TargetInfo::isTypeSigned(IntType T) {
3710b57cec5SDimitry Andric   switch (T) {
3720b57cec5SDimitry Andric   default: llvm_unreachable("not an integer!");
3730b57cec5SDimitry Andric   case SignedChar:
3740b57cec5SDimitry Andric   case SignedShort:
3750b57cec5SDimitry Andric   case SignedInt:
3760b57cec5SDimitry Andric   case SignedLong:
3770b57cec5SDimitry Andric   case SignedLongLong:
3780b57cec5SDimitry Andric     return true;
3790b57cec5SDimitry Andric   case UnsignedChar:
3800b57cec5SDimitry Andric   case UnsignedShort:
3810b57cec5SDimitry Andric   case UnsignedInt:
3820b57cec5SDimitry Andric   case UnsignedLong:
3830b57cec5SDimitry Andric   case UnsignedLongLong:
3840b57cec5SDimitry Andric     return false;
3850b57cec5SDimitry Andric   };
3860b57cec5SDimitry Andric }
3870b57cec5SDimitry Andric 
3880b57cec5SDimitry Andric /// adjust - Set forced language options.
3890b57cec5SDimitry Andric /// Apply changes to the target information with respect to certain
3900b57cec5SDimitry Andric /// language options which change the target configuration and adjust
3910b57cec5SDimitry Andric /// the language based on the target options where applicable.
392fe6060f1SDimitry Andric void TargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) {
3930b57cec5SDimitry Andric   if (Opts.NoBitFieldTypeAlign)
3940b57cec5SDimitry Andric     UseBitFieldTypeAlignment = false;
3950b57cec5SDimitry Andric 
3960b57cec5SDimitry Andric   switch (Opts.WCharSize) {
3970b57cec5SDimitry Andric   default: llvm_unreachable("invalid wchar_t width");
3980b57cec5SDimitry Andric   case 0: break;
3990b57cec5SDimitry Andric   case 1: WCharType = Opts.WCharIsSigned ? SignedChar : UnsignedChar; break;
4000b57cec5SDimitry Andric   case 2: WCharType = Opts.WCharIsSigned ? SignedShort : UnsignedShort; break;
4010b57cec5SDimitry Andric   case 4: WCharType = Opts.WCharIsSigned ? SignedInt : UnsignedInt; break;
4020b57cec5SDimitry Andric   }
4030b57cec5SDimitry Andric 
4040b57cec5SDimitry Andric   if (Opts.AlignDouble) {
4050b57cec5SDimitry Andric     DoubleAlign = LongLongAlign = 64;
4060b57cec5SDimitry Andric     LongDoubleAlign = 64;
4070b57cec5SDimitry Andric   }
4080b57cec5SDimitry Andric 
409*0fca6ea1SDimitry Andric   // HLSL explicitly defines the sizes and formats of some data types, and we
410*0fca6ea1SDimitry Andric   // need to conform to those regardless of what architecture you are targeting.
411*0fca6ea1SDimitry Andric   if (Opts.HLSL) {
412*0fca6ea1SDimitry Andric     LongWidth = LongAlign = 64;
413*0fca6ea1SDimitry Andric     if (!Opts.NativeHalfType) {
414*0fca6ea1SDimitry Andric       HalfFormat = &llvm::APFloat::IEEEsingle();
415*0fca6ea1SDimitry Andric       HalfWidth = HalfAlign = 32;
416*0fca6ea1SDimitry Andric     }
417*0fca6ea1SDimitry Andric   }
418*0fca6ea1SDimitry Andric 
4190b57cec5SDimitry Andric   if (Opts.OpenCL) {
4200b57cec5SDimitry Andric     // OpenCL C requires specific widths for types, irrespective of
4210b57cec5SDimitry Andric     // what these normally are for the target.
4220b57cec5SDimitry Andric     // We also define long long and long double here, although the
4230b57cec5SDimitry Andric     // OpenCL standard only mentions these as "reserved".
4240b57cec5SDimitry Andric     IntWidth = IntAlign = 32;
4250b57cec5SDimitry Andric     LongWidth = LongAlign = 64;
4260b57cec5SDimitry Andric     LongLongWidth = LongLongAlign = 128;
4270b57cec5SDimitry Andric     HalfWidth = HalfAlign = 16;
4280b57cec5SDimitry Andric     FloatWidth = FloatAlign = 32;
4290b57cec5SDimitry Andric 
4300b57cec5SDimitry Andric     // Embedded 32-bit targets (OpenCL EP) might have double C type
4310b57cec5SDimitry Andric     // defined as float. Let's not override this as it might lead
4320b57cec5SDimitry Andric     // to generating illegal code that uses 64bit doubles.
4330b57cec5SDimitry Andric     if (DoubleWidth != FloatWidth) {
4340b57cec5SDimitry Andric       DoubleWidth = DoubleAlign = 64;
4350b57cec5SDimitry Andric       DoubleFormat = &llvm::APFloat::IEEEdouble();
4360b57cec5SDimitry Andric     }
4370b57cec5SDimitry Andric     LongDoubleWidth = LongDoubleAlign = 128;
4380b57cec5SDimitry Andric 
4390b57cec5SDimitry Andric     unsigned MaxPointerWidth = getMaxPointerWidth();
4400b57cec5SDimitry Andric     assert(MaxPointerWidth == 32 || MaxPointerWidth == 64);
4410b57cec5SDimitry Andric     bool Is32BitArch = MaxPointerWidth == 32;
4420b57cec5SDimitry Andric     SizeType = Is32BitArch ? UnsignedInt : UnsignedLong;
4430b57cec5SDimitry Andric     PtrDiffType = Is32BitArch ? SignedInt : SignedLong;
4440b57cec5SDimitry Andric     IntPtrType = Is32BitArch ? SignedInt : SignedLong;
4450b57cec5SDimitry Andric 
4460b57cec5SDimitry Andric     IntMaxType = SignedLongLong;
4470b57cec5SDimitry Andric     Int64Type = SignedLong;
4480b57cec5SDimitry Andric 
4490b57cec5SDimitry Andric     HalfFormat = &llvm::APFloat::IEEEhalf();
4500b57cec5SDimitry Andric     FloatFormat = &llvm::APFloat::IEEEsingle();
4510b57cec5SDimitry Andric     LongDoubleFormat = &llvm::APFloat::IEEEquad();
452fe6060f1SDimitry Andric 
453fe6060f1SDimitry Andric     // OpenCL C v3.0 s6.7.5 - The generic address space requires support for
454fe6060f1SDimitry Andric     // OpenCL C 2.0 or OpenCL C 3.0 with the __opencl_c_generic_address_space
455fe6060f1SDimitry Andric     // feature
4566e75b2fbSDimitry Andric     // OpenCL C v3.0 s6.2.1 - OpenCL pipes require support of OpenCL C 2.0
4576e75b2fbSDimitry Andric     // or later and __opencl_c_pipes feature
4586e75b2fbSDimitry Andric     // FIXME: These language options are also defined in setLangDefaults()
459fe6060f1SDimitry Andric     // for OpenCL C 2.0 but with no access to target capabilities. Target
4606e75b2fbSDimitry Andric     // should be immutable once created and thus these language options need
461fe6060f1SDimitry Andric     // to be defined only once.
462349cc55cSDimitry Andric     if (Opts.getOpenCLCompatibleVersion() == 300) {
463fe6060f1SDimitry Andric       const auto &OpenCLFeaturesMap = getSupportedOpenCLOpts();
464fe6060f1SDimitry Andric       Opts.OpenCLGenericAddressSpace = hasFeatureEnabled(
465fe6060f1SDimitry Andric           OpenCLFeaturesMap, "__opencl_c_generic_address_space");
4666e75b2fbSDimitry Andric       Opts.OpenCLPipes =
4676e75b2fbSDimitry Andric           hasFeatureEnabled(OpenCLFeaturesMap, "__opencl_c_pipes");
46804eeddc0SDimitry Andric       Opts.Blocks =
46904eeddc0SDimitry Andric           hasFeatureEnabled(OpenCLFeaturesMap, "__opencl_c_device_enqueue");
470fe6060f1SDimitry Andric     }
4710b57cec5SDimitry Andric   }
4720b57cec5SDimitry Andric 
4735ffd83dbSDimitry Andric   if (Opts.DoubleSize) {
4745ffd83dbSDimitry Andric     if (Opts.DoubleSize == 32) {
4755ffd83dbSDimitry Andric       DoubleWidth = 32;
4765ffd83dbSDimitry Andric       LongDoubleWidth = 32;
4775ffd83dbSDimitry Andric       DoubleFormat = &llvm::APFloat::IEEEsingle();
4785ffd83dbSDimitry Andric       LongDoubleFormat = &llvm::APFloat::IEEEsingle();
4795ffd83dbSDimitry Andric     } else if (Opts.DoubleSize == 64) {
4805ffd83dbSDimitry Andric       DoubleWidth = 64;
4815ffd83dbSDimitry Andric       LongDoubleWidth = 64;
4825ffd83dbSDimitry Andric       DoubleFormat = &llvm::APFloat::IEEEdouble();
4835ffd83dbSDimitry Andric       LongDoubleFormat = &llvm::APFloat::IEEEdouble();
4845ffd83dbSDimitry Andric     }
4855ffd83dbSDimitry Andric   }
4865ffd83dbSDimitry Andric 
4870b57cec5SDimitry Andric   if (Opts.LongDoubleSize) {
4880b57cec5SDimitry Andric     if (Opts.LongDoubleSize == DoubleWidth) {
4890b57cec5SDimitry Andric       LongDoubleWidth = DoubleWidth;
4900b57cec5SDimitry Andric       LongDoubleAlign = DoubleAlign;
4910b57cec5SDimitry Andric       LongDoubleFormat = DoubleFormat;
4920b57cec5SDimitry Andric     } else if (Opts.LongDoubleSize == 128) {
4930b57cec5SDimitry Andric       LongDoubleWidth = LongDoubleAlign = 128;
4940b57cec5SDimitry Andric       LongDoubleFormat = &llvm::APFloat::IEEEquad();
49581ad6265SDimitry Andric     } else if (Opts.LongDoubleSize == 80) {
49681ad6265SDimitry Andric       LongDoubleFormat = &llvm::APFloat::x87DoubleExtended();
49781ad6265SDimitry Andric       if (getTriple().isWindowsMSVCEnvironment()) {
49881ad6265SDimitry Andric         LongDoubleWidth = 128;
49981ad6265SDimitry Andric         LongDoubleAlign = 128;
50081ad6265SDimitry Andric       } else { // Linux
50181ad6265SDimitry Andric         if (getTriple().getArch() == llvm::Triple::x86) {
50281ad6265SDimitry Andric           LongDoubleWidth = 96;
50381ad6265SDimitry Andric           LongDoubleAlign = 32;
50481ad6265SDimitry Andric         } else {
50581ad6265SDimitry Andric           LongDoubleWidth = 128;
50681ad6265SDimitry Andric           LongDoubleAlign = 128;
50781ad6265SDimitry Andric         }
50881ad6265SDimitry Andric       }
5090b57cec5SDimitry Andric     }
5100b57cec5SDimitry Andric   }
5110b57cec5SDimitry Andric 
5120b57cec5SDimitry Andric   if (Opts.NewAlignOverride)
5130b57cec5SDimitry Andric     NewAlign = Opts.NewAlignOverride * getCharWidth();
5140b57cec5SDimitry Andric 
5150b57cec5SDimitry Andric   // Each unsigned fixed point type has the same number of fractional bits as
5160b57cec5SDimitry Andric   // its corresponding signed type.
5170b57cec5SDimitry Andric   PaddingOnUnsignedFixedPoint |= Opts.PaddingOnUnsignedFixedPoint;
5180b57cec5SDimitry Andric   CheckFixedPointBits();
519fe6060f1SDimitry Andric 
520fe6060f1SDimitry Andric   if (Opts.ProtectParens && !checkArithmeticFenceSupported()) {
521fe6060f1SDimitry Andric     Diags.Report(diag::err_opt_not_valid_on_target) << "-fprotect-parens";
522fe6060f1SDimitry Andric     Opts.ProtectParens = false;
523fe6060f1SDimitry Andric   }
52481ad6265SDimitry Andric 
52581ad6265SDimitry Andric   if (Opts.MaxBitIntWidth)
526bdd1243dSDimitry Andric     MaxBitIntWidth = static_cast<unsigned>(Opts.MaxBitIntWidth);
527bdd1243dSDimitry Andric 
528bdd1243dSDimitry Andric   if (Opts.FakeAddressSpaceMap)
529bdd1243dSDimitry Andric     AddrSpaceMap = &FakeAddrSpaceMap;
5300b57cec5SDimitry Andric }
5310b57cec5SDimitry Andric 
5320b57cec5SDimitry Andric bool TargetInfo::initFeatureMap(
5330b57cec5SDimitry Andric     llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
5340b57cec5SDimitry Andric     const std::vector<std::string> &FeatureVec) const {
5350b57cec5SDimitry Andric   for (const auto &F : FeatureVec) {
5360b57cec5SDimitry Andric     StringRef Name = F;
537bdd1243dSDimitry Andric     if (Name.empty())
538bdd1243dSDimitry Andric       continue;
5390b57cec5SDimitry Andric     // Apply the feature via the target.
540bdd1243dSDimitry Andric     if (Name[0] != '+' && Name[0] != '-')
541bdd1243dSDimitry Andric       Diags.Report(diag::warn_fe_backend_invalid_feature_flag) << Name;
542bdd1243dSDimitry Andric     else
543bdd1243dSDimitry Andric       setFeatureEnabled(Features, Name.substr(1), Name[0] == '+');
5440b57cec5SDimitry Andric   }
5450b57cec5SDimitry Andric   return true;
5460b57cec5SDimitry Andric }
5470b57cec5SDimitry Andric 
548bdd1243dSDimitry Andric ParsedTargetAttr TargetInfo::parseTargetAttr(StringRef Features) const {
549bdd1243dSDimitry Andric   ParsedTargetAttr Ret;
550bdd1243dSDimitry Andric   if (Features == "default")
551bdd1243dSDimitry Andric     return Ret;
552bdd1243dSDimitry Andric   SmallVector<StringRef, 1> AttrFeatures;
553bdd1243dSDimitry Andric   Features.split(AttrFeatures, ",");
554bdd1243dSDimitry Andric 
555bdd1243dSDimitry Andric   // Grab the various features and prepend a "+" to turn on the feature to
556bdd1243dSDimitry Andric   // the backend and add them to our existing set of features.
557bdd1243dSDimitry Andric   for (auto &Feature : AttrFeatures) {
558bdd1243dSDimitry Andric     // Go ahead and trim whitespace rather than either erroring or
559bdd1243dSDimitry Andric     // accepting it weirdly.
560bdd1243dSDimitry Andric     Feature = Feature.trim();
561bdd1243dSDimitry Andric 
562bdd1243dSDimitry Andric     // TODO: Support the fpmath option. It will require checking
563bdd1243dSDimitry Andric     // overall feature validity for the function with the rest of the
564bdd1243dSDimitry Andric     // attributes on the function.
5655f757f3fSDimitry Andric     if (Feature.starts_with("fpmath="))
566bdd1243dSDimitry Andric       continue;
567bdd1243dSDimitry Andric 
5685f757f3fSDimitry Andric     if (Feature.starts_with("branch-protection=")) {
569bdd1243dSDimitry Andric       Ret.BranchProtection = Feature.split('=').second.trim();
570bdd1243dSDimitry Andric       continue;
571bdd1243dSDimitry Andric     }
572bdd1243dSDimitry Andric 
573bdd1243dSDimitry Andric     // While we're here iterating check for a different target cpu.
5745f757f3fSDimitry Andric     if (Feature.starts_with("arch=")) {
575bdd1243dSDimitry Andric       if (!Ret.CPU.empty())
576bdd1243dSDimitry Andric         Ret.Duplicate = "arch=";
577bdd1243dSDimitry Andric       else
578bdd1243dSDimitry Andric         Ret.CPU = Feature.split("=").second.trim();
5795f757f3fSDimitry Andric     } else if (Feature.starts_with("tune=")) {
580bdd1243dSDimitry Andric       if (!Ret.Tune.empty())
581bdd1243dSDimitry Andric         Ret.Duplicate = "tune=";
582bdd1243dSDimitry Andric       else
583bdd1243dSDimitry Andric         Ret.Tune = Feature.split("=").second.trim();
5845f757f3fSDimitry Andric     } else if (Feature.starts_with("no-"))
585bdd1243dSDimitry Andric       Ret.Features.push_back("-" + Feature.split("-").second.str());
586bdd1243dSDimitry Andric     else
587bdd1243dSDimitry Andric       Ret.Features.push_back("+" + Feature.str());
588bdd1243dSDimitry Andric   }
589bdd1243dSDimitry Andric   return Ret;
590bdd1243dSDimitry Andric }
591bdd1243dSDimitry Andric 
5920b57cec5SDimitry Andric TargetInfo::CallingConvKind
5930b57cec5SDimitry Andric TargetInfo::getCallingConvKind(bool ClangABICompat4) const {
5940b57cec5SDimitry Andric   if (getCXXABI() != TargetCXXABI::Microsoft &&
595753f127fSDimitry Andric       (ClangABICompat4 || getTriple().isPS4()))
5960b57cec5SDimitry Andric     return CCK_ClangABI4OrPS4;
5970b57cec5SDimitry Andric   return CCK_Default;
5980b57cec5SDimitry Andric }
5990b57cec5SDimitry Andric 
600bdd1243dSDimitry Andric bool TargetInfo::areDefaultedSMFStillPOD(const LangOptions &LangOpts) const {
601bdd1243dSDimitry Andric   return LangOpts.getClangABICompat() > LangOptions::ClangABI::Ver15;
602bdd1243dSDimitry Andric }
603bdd1243dSDimitry Andric 
6040b57cec5SDimitry Andric LangAS TargetInfo::getOpenCLTypeAddrSpace(OpenCLTypeKind TK) const {
6050b57cec5SDimitry Andric   switch (TK) {
6060b57cec5SDimitry Andric   case OCLTK_Image:
6070b57cec5SDimitry Andric   case OCLTK_Pipe:
6080b57cec5SDimitry Andric     return LangAS::opencl_global;
6090b57cec5SDimitry Andric 
6100b57cec5SDimitry Andric   case OCLTK_Sampler:
6110b57cec5SDimitry Andric     return LangAS::opencl_constant;
6120b57cec5SDimitry Andric 
6130b57cec5SDimitry Andric   default:
6140b57cec5SDimitry Andric     return LangAS::Default;
6150b57cec5SDimitry Andric   }
6160b57cec5SDimitry Andric }
6170b57cec5SDimitry Andric 
6180b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
6190b57cec5SDimitry Andric 
6200b57cec5SDimitry Andric 
6210b57cec5SDimitry Andric static StringRef removeGCCRegisterPrefix(StringRef Name) {
6220b57cec5SDimitry Andric   if (Name[0] == '%' || Name[0] == '#')
6230b57cec5SDimitry Andric     Name = Name.substr(1);
6240b57cec5SDimitry Andric 
6250b57cec5SDimitry Andric   return Name;
6260b57cec5SDimitry Andric }
6270b57cec5SDimitry Andric 
6280b57cec5SDimitry Andric /// isValidClobber - Returns whether the passed in string is
6290b57cec5SDimitry Andric /// a valid clobber in an inline asm statement. This is used by
6300b57cec5SDimitry Andric /// Sema.
6310b57cec5SDimitry Andric bool TargetInfo::isValidClobber(StringRef Name) const {
632fe6060f1SDimitry Andric   return (isValidGCCRegisterName(Name) || Name == "memory" || Name == "cc" ||
633fe6060f1SDimitry Andric           Name == "unwind");
6340b57cec5SDimitry Andric }
6350b57cec5SDimitry Andric 
6360b57cec5SDimitry Andric /// isValidGCCRegisterName - Returns whether the passed in string
6370b57cec5SDimitry Andric /// is a valid register name according to GCC. This is used by Sema for
6380b57cec5SDimitry Andric /// inline asm statements.
6390b57cec5SDimitry Andric bool TargetInfo::isValidGCCRegisterName(StringRef Name) const {
6400b57cec5SDimitry Andric   if (Name.empty())
6410b57cec5SDimitry Andric     return false;
6420b57cec5SDimitry Andric 
6430b57cec5SDimitry Andric   // Get rid of any register prefix.
6440b57cec5SDimitry Andric   Name = removeGCCRegisterPrefix(Name);
6450b57cec5SDimitry Andric   if (Name.empty())
6460b57cec5SDimitry Andric     return false;
6470b57cec5SDimitry Andric 
6480b57cec5SDimitry Andric   ArrayRef<const char *> Names = getGCCRegNames();
6490b57cec5SDimitry Andric 
6500b57cec5SDimitry Andric   // If we have a number it maps to an entry in the register name array.
6510b57cec5SDimitry Andric   if (isDigit(Name[0])) {
6520b57cec5SDimitry Andric     unsigned n;
6530b57cec5SDimitry Andric     if (!Name.getAsInteger(0, n))
6540b57cec5SDimitry Andric       return n < Names.size();
6550b57cec5SDimitry Andric   }
6560b57cec5SDimitry Andric 
6570b57cec5SDimitry Andric   // Check register names.
6580b57cec5SDimitry Andric   if (llvm::is_contained(Names, Name))
6590b57cec5SDimitry Andric     return true;
6600b57cec5SDimitry Andric 
6610b57cec5SDimitry Andric   // Check any additional names that we have.
6620b57cec5SDimitry Andric   for (const AddlRegName &ARN : getGCCAddlRegNames())
6630b57cec5SDimitry Andric     for (const char *AN : ARN.Names) {
6640b57cec5SDimitry Andric       if (!AN)
6650b57cec5SDimitry Andric         break;
6660b57cec5SDimitry Andric       // Make sure the register that the additional name is for is within
6670b57cec5SDimitry Andric       // the bounds of the register names from above.
6680b57cec5SDimitry Andric       if (AN == Name && ARN.RegNum < Names.size())
6690b57cec5SDimitry Andric         return true;
6700b57cec5SDimitry Andric     }
6710b57cec5SDimitry Andric 
6720b57cec5SDimitry Andric   // Now check aliases.
6730b57cec5SDimitry Andric   for (const GCCRegAlias &GRA : getGCCRegAliases())
6740b57cec5SDimitry Andric     for (const char *A : GRA.Aliases) {
6750b57cec5SDimitry Andric       if (!A)
6760b57cec5SDimitry Andric         break;
6770b57cec5SDimitry Andric       if (A == Name)
6780b57cec5SDimitry Andric         return true;
6790b57cec5SDimitry Andric     }
6800b57cec5SDimitry Andric 
6810b57cec5SDimitry Andric   return false;
6820b57cec5SDimitry Andric }
6830b57cec5SDimitry Andric 
6840b57cec5SDimitry Andric StringRef TargetInfo::getNormalizedGCCRegisterName(StringRef Name,
6850b57cec5SDimitry Andric                                                    bool ReturnCanonical) const {
6860b57cec5SDimitry Andric   assert(isValidGCCRegisterName(Name) && "Invalid register passed in");
6870b57cec5SDimitry Andric 
6880b57cec5SDimitry Andric   // Get rid of any register prefix.
6890b57cec5SDimitry Andric   Name = removeGCCRegisterPrefix(Name);
6900b57cec5SDimitry Andric 
6910b57cec5SDimitry Andric   ArrayRef<const char *> Names = getGCCRegNames();
6920b57cec5SDimitry Andric 
6930b57cec5SDimitry Andric   // First, check if we have a number.
6940b57cec5SDimitry Andric   if (isDigit(Name[0])) {
6950b57cec5SDimitry Andric     unsigned n;
6960b57cec5SDimitry Andric     if (!Name.getAsInteger(0, n)) {
6970b57cec5SDimitry Andric       assert(n < Names.size() && "Out of bounds register number!");
6980b57cec5SDimitry Andric       return Names[n];
6990b57cec5SDimitry Andric     }
7000b57cec5SDimitry Andric   }
7010b57cec5SDimitry Andric 
7020b57cec5SDimitry Andric   // Check any additional names that we have.
7030b57cec5SDimitry Andric   for (const AddlRegName &ARN : getGCCAddlRegNames())
7040b57cec5SDimitry Andric     for (const char *AN : ARN.Names) {
7050b57cec5SDimitry Andric       if (!AN)
7060b57cec5SDimitry Andric         break;
7070b57cec5SDimitry Andric       // Make sure the register that the additional name is for is within
7080b57cec5SDimitry Andric       // the bounds of the register names from above.
7090b57cec5SDimitry Andric       if (AN == Name && ARN.RegNum < Names.size())
7100b57cec5SDimitry Andric         return ReturnCanonical ? Names[ARN.RegNum] : Name;
7110b57cec5SDimitry Andric     }
7120b57cec5SDimitry Andric 
7130b57cec5SDimitry Andric   // Now check aliases.
7140b57cec5SDimitry Andric   for (const GCCRegAlias &RA : getGCCRegAliases())
7150b57cec5SDimitry Andric     for (const char *A : RA.Aliases) {
7160b57cec5SDimitry Andric       if (!A)
7170b57cec5SDimitry Andric         break;
7180b57cec5SDimitry Andric       if (A == Name)
7190b57cec5SDimitry Andric         return RA.Register;
7200b57cec5SDimitry Andric     }
7210b57cec5SDimitry Andric 
7220b57cec5SDimitry Andric   return Name;
7230b57cec5SDimitry Andric }
7240b57cec5SDimitry Andric 
7250b57cec5SDimitry Andric bool TargetInfo::validateOutputConstraint(ConstraintInfo &Info) const {
7260b57cec5SDimitry Andric   const char *Name = Info.getConstraintStr().c_str();
7270b57cec5SDimitry Andric   // An output constraint must start with '=' or '+'
7280b57cec5SDimitry Andric   if (*Name != '=' && *Name != '+')
7290b57cec5SDimitry Andric     return false;
7300b57cec5SDimitry Andric 
7310b57cec5SDimitry Andric   if (*Name == '+')
7320b57cec5SDimitry Andric     Info.setIsReadWrite();
7330b57cec5SDimitry Andric 
7340b57cec5SDimitry Andric   Name++;
7350b57cec5SDimitry Andric   while (*Name) {
7360b57cec5SDimitry Andric     switch (*Name) {
7370b57cec5SDimitry Andric     default:
7380b57cec5SDimitry Andric       if (!validateAsmConstraint(Name, Info)) {
7390b57cec5SDimitry Andric         // FIXME: We temporarily return false
7400b57cec5SDimitry Andric         // so we can add more constraints as we hit it.
7410b57cec5SDimitry Andric         // Eventually, an unknown constraint should just be treated as 'g'.
7420b57cec5SDimitry Andric         return false;
7430b57cec5SDimitry Andric       }
7440b57cec5SDimitry Andric       break;
7450b57cec5SDimitry Andric     case '&': // early clobber.
7460b57cec5SDimitry Andric       Info.setEarlyClobber();
7470b57cec5SDimitry Andric       break;
7480b57cec5SDimitry Andric     case '%': // commutative.
7490b57cec5SDimitry Andric       // FIXME: Check that there is a another register after this one.
7500b57cec5SDimitry Andric       break;
7510b57cec5SDimitry Andric     case 'r': // general register.
7520b57cec5SDimitry Andric       Info.setAllowsRegister();
7530b57cec5SDimitry Andric       break;
7540b57cec5SDimitry Andric     case 'm': // memory operand.
7550b57cec5SDimitry Andric     case 'o': // offsetable memory operand.
7560b57cec5SDimitry Andric     case 'V': // non-offsetable memory operand.
7570b57cec5SDimitry Andric     case '<': // autodecrement memory operand.
7580b57cec5SDimitry Andric     case '>': // autoincrement memory operand.
7590b57cec5SDimitry Andric       Info.setAllowsMemory();
7600b57cec5SDimitry Andric       break;
7610b57cec5SDimitry Andric     case 'g': // general register, memory operand or immediate integer.
7620b57cec5SDimitry Andric     case 'X': // any operand.
7630b57cec5SDimitry Andric       Info.setAllowsRegister();
7640b57cec5SDimitry Andric       Info.setAllowsMemory();
7650b57cec5SDimitry Andric       break;
7660b57cec5SDimitry Andric     case ',': // multiple alternative constraint.  Pass it.
7670b57cec5SDimitry Andric       // Handle additional optional '=' or '+' modifiers.
7680b57cec5SDimitry Andric       if (Name[1] == '=' || Name[1] == '+')
7690b57cec5SDimitry Andric         Name++;
7700b57cec5SDimitry Andric       break;
7710b57cec5SDimitry Andric     case '#': // Ignore as constraint.
7720b57cec5SDimitry Andric       while (Name[1] && Name[1] != ',')
7730b57cec5SDimitry Andric         Name++;
7740b57cec5SDimitry Andric       break;
7750b57cec5SDimitry Andric     case '?': // Disparage slightly code.
7760b57cec5SDimitry Andric     case '!': // Disparage severely.
7770b57cec5SDimitry Andric     case '*': // Ignore for choosing register preferences.
7780b57cec5SDimitry Andric     case 'i': // Ignore i,n,E,F as output constraints (match from the other
7790b57cec5SDimitry Andric               // chars)
7800b57cec5SDimitry Andric     case 'n':
7810b57cec5SDimitry Andric     case 'E':
7820b57cec5SDimitry Andric     case 'F':
7830b57cec5SDimitry Andric       break;  // Pass them.
7840b57cec5SDimitry Andric     }
7850b57cec5SDimitry Andric 
7860b57cec5SDimitry Andric     Name++;
7870b57cec5SDimitry Andric   }
7880b57cec5SDimitry Andric 
7890b57cec5SDimitry Andric   // Early clobber with a read-write constraint which doesn't permit registers
7900b57cec5SDimitry Andric   // is invalid.
7910b57cec5SDimitry Andric   if (Info.earlyClobber() && Info.isReadWrite() && !Info.allowsRegister())
7920b57cec5SDimitry Andric     return false;
7930b57cec5SDimitry Andric 
7940b57cec5SDimitry Andric   // If a constraint allows neither memory nor register operands it contains
7950b57cec5SDimitry Andric   // only modifiers. Reject it.
7960b57cec5SDimitry Andric   return Info.allowsMemory() || Info.allowsRegister();
7970b57cec5SDimitry Andric }
7980b57cec5SDimitry Andric 
7990b57cec5SDimitry Andric bool TargetInfo::resolveSymbolicName(const char *&Name,
8000b57cec5SDimitry Andric                                      ArrayRef<ConstraintInfo> OutputConstraints,
8010b57cec5SDimitry Andric                                      unsigned &Index) const {
8020b57cec5SDimitry Andric   assert(*Name == '[' && "Symbolic name did not start with '['");
8030b57cec5SDimitry Andric   Name++;
8040b57cec5SDimitry Andric   const char *Start = Name;
8050b57cec5SDimitry Andric   while (*Name && *Name != ']')
8060b57cec5SDimitry Andric     Name++;
8070b57cec5SDimitry Andric 
8080b57cec5SDimitry Andric   if (!*Name) {
8090b57cec5SDimitry Andric     // Missing ']'
8100b57cec5SDimitry Andric     return false;
8110b57cec5SDimitry Andric   }
8120b57cec5SDimitry Andric 
8130b57cec5SDimitry Andric   std::string SymbolicName(Start, Name - Start);
8140b57cec5SDimitry Andric 
8150b57cec5SDimitry Andric   for (Index = 0; Index != OutputConstraints.size(); ++Index)
8160b57cec5SDimitry Andric     if (SymbolicName == OutputConstraints[Index].getName())
8170b57cec5SDimitry Andric       return true;
8180b57cec5SDimitry Andric 
8190b57cec5SDimitry Andric   return false;
8200b57cec5SDimitry Andric }
8210b57cec5SDimitry Andric 
8220b57cec5SDimitry Andric bool TargetInfo::validateInputConstraint(
8230b57cec5SDimitry Andric                               MutableArrayRef<ConstraintInfo> OutputConstraints,
8240b57cec5SDimitry Andric                               ConstraintInfo &Info) const {
8250b57cec5SDimitry Andric   const char *Name = Info.ConstraintStr.c_str();
8260b57cec5SDimitry Andric 
8270b57cec5SDimitry Andric   if (!*Name)
8280b57cec5SDimitry Andric     return false;
8290b57cec5SDimitry Andric 
8300b57cec5SDimitry Andric   while (*Name) {
8310b57cec5SDimitry Andric     switch (*Name) {
8320b57cec5SDimitry Andric     default:
8330b57cec5SDimitry Andric       // Check if we have a matching constraint
8340b57cec5SDimitry Andric       if (*Name >= '0' && *Name <= '9') {
8350b57cec5SDimitry Andric         const char *DigitStart = Name;
8360b57cec5SDimitry Andric         while (Name[1] >= '0' && Name[1] <= '9')
8370b57cec5SDimitry Andric           Name++;
8380b57cec5SDimitry Andric         const char *DigitEnd = Name;
8390b57cec5SDimitry Andric         unsigned i;
8400b57cec5SDimitry Andric         if (StringRef(DigitStart, DigitEnd - DigitStart + 1)
8410b57cec5SDimitry Andric                 .getAsInteger(10, i))
8420b57cec5SDimitry Andric           return false;
8430b57cec5SDimitry Andric 
8440b57cec5SDimitry Andric         // Check if matching constraint is out of bounds.
8450b57cec5SDimitry Andric         if (i >= OutputConstraints.size()) return false;
8460b57cec5SDimitry Andric 
8470b57cec5SDimitry Andric         // A number must refer to an output only operand.
8480b57cec5SDimitry Andric         if (OutputConstraints[i].isReadWrite())
8490b57cec5SDimitry Andric           return false;
8500b57cec5SDimitry Andric 
8510b57cec5SDimitry Andric         // If the constraint is already tied, it must be tied to the
8520b57cec5SDimitry Andric         // same operand referenced to by the number.
8530b57cec5SDimitry Andric         if (Info.hasTiedOperand() && Info.getTiedOperand() != i)
8540b57cec5SDimitry Andric           return false;
8550b57cec5SDimitry Andric 
8560b57cec5SDimitry Andric         // The constraint should have the same info as the respective
8570b57cec5SDimitry Andric         // output constraint.
8580b57cec5SDimitry Andric         Info.setTiedOperand(i, OutputConstraints[i]);
8590b57cec5SDimitry Andric       } else if (!validateAsmConstraint(Name, Info)) {
8600b57cec5SDimitry Andric         // FIXME: This error return is in place temporarily so we can
8610b57cec5SDimitry Andric         // add more constraints as we hit it.  Eventually, an unknown
8620b57cec5SDimitry Andric         // constraint should just be treated as 'g'.
8630b57cec5SDimitry Andric         return false;
8640b57cec5SDimitry Andric       }
8650b57cec5SDimitry Andric       break;
8660b57cec5SDimitry Andric     case '[': {
8670b57cec5SDimitry Andric       unsigned Index = 0;
8680b57cec5SDimitry Andric       if (!resolveSymbolicName(Name, OutputConstraints, Index))
8690b57cec5SDimitry Andric         return false;
8700b57cec5SDimitry Andric 
8710b57cec5SDimitry Andric       // If the constraint is already tied, it must be tied to the
8720b57cec5SDimitry Andric       // same operand referenced to by the number.
8730b57cec5SDimitry Andric       if (Info.hasTiedOperand() && Info.getTiedOperand() != Index)
8740b57cec5SDimitry Andric         return false;
8750b57cec5SDimitry Andric 
8760b57cec5SDimitry Andric       // A number must refer to an output only operand.
8770b57cec5SDimitry Andric       if (OutputConstraints[Index].isReadWrite())
8780b57cec5SDimitry Andric         return false;
8790b57cec5SDimitry Andric 
8800b57cec5SDimitry Andric       Info.setTiedOperand(Index, OutputConstraints[Index]);
8810b57cec5SDimitry Andric       break;
8820b57cec5SDimitry Andric     }
8830b57cec5SDimitry Andric     case '%': // commutative
8840b57cec5SDimitry Andric       // FIXME: Fail if % is used with the last operand.
8850b57cec5SDimitry Andric       break;
8860b57cec5SDimitry Andric     case 'i': // immediate integer.
8870b57cec5SDimitry Andric       break;
8880b57cec5SDimitry Andric     case 'n': // immediate integer with a known value.
8890b57cec5SDimitry Andric       Info.setRequiresImmediate();
8900b57cec5SDimitry Andric       break;
8910b57cec5SDimitry Andric     case 'I':  // Various constant constraints with target-specific meanings.
8920b57cec5SDimitry Andric     case 'J':
8930b57cec5SDimitry Andric     case 'K':
8940b57cec5SDimitry Andric     case 'L':
8950b57cec5SDimitry Andric     case 'M':
8960b57cec5SDimitry Andric     case 'N':
8970b57cec5SDimitry Andric     case 'O':
8980b57cec5SDimitry Andric     case 'P':
8990b57cec5SDimitry Andric       if (!validateAsmConstraint(Name, Info))
9000b57cec5SDimitry Andric         return false;
9010b57cec5SDimitry Andric       break;
9020b57cec5SDimitry Andric     case 'r': // general register.
9030b57cec5SDimitry Andric       Info.setAllowsRegister();
9040b57cec5SDimitry Andric       break;
9050b57cec5SDimitry Andric     case 'm': // memory operand.
9060b57cec5SDimitry Andric     case 'o': // offsettable memory operand.
9070b57cec5SDimitry Andric     case 'V': // non-offsettable memory operand.
9080b57cec5SDimitry Andric     case '<': // autodecrement memory operand.
9090b57cec5SDimitry Andric     case '>': // autoincrement memory operand.
9100b57cec5SDimitry Andric       Info.setAllowsMemory();
9110b57cec5SDimitry Andric       break;
9120b57cec5SDimitry Andric     case 'g': // general register, memory operand or immediate integer.
9130b57cec5SDimitry Andric     case 'X': // any operand.
9140b57cec5SDimitry Andric       Info.setAllowsRegister();
9150b57cec5SDimitry Andric       Info.setAllowsMemory();
9160b57cec5SDimitry Andric       break;
9170b57cec5SDimitry Andric     case 'E': // immediate floating point.
9180b57cec5SDimitry Andric     case 'F': // immediate floating point.
9190b57cec5SDimitry Andric     case 'p': // address operand.
9200b57cec5SDimitry Andric       break;
9210b57cec5SDimitry Andric     case ',': // multiple alternative constraint.  Ignore comma.
9220b57cec5SDimitry Andric       break;
9230b57cec5SDimitry Andric     case '#': // Ignore as constraint.
9240b57cec5SDimitry Andric       while (Name[1] && Name[1] != ',')
9250b57cec5SDimitry Andric         Name++;
9260b57cec5SDimitry Andric       break;
9270b57cec5SDimitry Andric     case '?': // Disparage slightly code.
9280b57cec5SDimitry Andric     case '!': // Disparage severely.
9290b57cec5SDimitry Andric     case '*': // Ignore for choosing register preferences.
9300b57cec5SDimitry Andric       break;  // Pass them.
9310b57cec5SDimitry Andric     }
9320b57cec5SDimitry Andric 
9330b57cec5SDimitry Andric     Name++;
9340b57cec5SDimitry Andric   }
9350b57cec5SDimitry Andric 
9360b57cec5SDimitry Andric   return true;
9370b57cec5SDimitry Andric }
9380b57cec5SDimitry Andric 
939*0fca6ea1SDimitry Andric bool TargetInfo::validatePointerAuthKey(const llvm::APSInt &value) const {
940*0fca6ea1SDimitry Andric   return false;
941*0fca6ea1SDimitry Andric }
942*0fca6ea1SDimitry Andric 
9430b57cec5SDimitry Andric void TargetInfo::CheckFixedPointBits() const {
9440b57cec5SDimitry Andric   // Check that the number of fractional and integral bits (and maybe sign) can
9450b57cec5SDimitry Andric   // fit into the bits given for a fixed point type.
9460b57cec5SDimitry Andric   assert(ShortAccumScale + getShortAccumIBits() + 1 <= ShortAccumWidth);
9470b57cec5SDimitry Andric   assert(AccumScale + getAccumIBits() + 1 <= AccumWidth);
9480b57cec5SDimitry Andric   assert(LongAccumScale + getLongAccumIBits() + 1 <= LongAccumWidth);
9490b57cec5SDimitry Andric   assert(getUnsignedShortAccumScale() + getUnsignedShortAccumIBits() <=
9500b57cec5SDimitry Andric          ShortAccumWidth);
9510b57cec5SDimitry Andric   assert(getUnsignedAccumScale() + getUnsignedAccumIBits() <= AccumWidth);
9520b57cec5SDimitry Andric   assert(getUnsignedLongAccumScale() + getUnsignedLongAccumIBits() <=
9530b57cec5SDimitry Andric          LongAccumWidth);
9540b57cec5SDimitry Andric 
9550b57cec5SDimitry Andric   assert(getShortFractScale() + 1 <= ShortFractWidth);
9560b57cec5SDimitry Andric   assert(getFractScale() + 1 <= FractWidth);
9570b57cec5SDimitry Andric   assert(getLongFractScale() + 1 <= LongFractWidth);
9580b57cec5SDimitry Andric   assert(getUnsignedShortFractScale() <= ShortFractWidth);
9590b57cec5SDimitry Andric   assert(getUnsignedFractScale() <= FractWidth);
9600b57cec5SDimitry Andric   assert(getUnsignedLongFractScale() <= LongFractWidth);
9610b57cec5SDimitry Andric 
9620b57cec5SDimitry Andric   // Each unsigned fract type has either the same number of fractional bits
9630b57cec5SDimitry Andric   // as, or one more fractional bit than, its corresponding signed fract type.
9640b57cec5SDimitry Andric   assert(getShortFractScale() == getUnsignedShortFractScale() ||
9650b57cec5SDimitry Andric          getShortFractScale() == getUnsignedShortFractScale() - 1);
9660b57cec5SDimitry Andric   assert(getFractScale() == getUnsignedFractScale() ||
9670b57cec5SDimitry Andric          getFractScale() == getUnsignedFractScale() - 1);
9680b57cec5SDimitry Andric   assert(getLongFractScale() == getUnsignedLongFractScale() ||
9690b57cec5SDimitry Andric          getLongFractScale() == getUnsignedLongFractScale() - 1);
9700b57cec5SDimitry Andric 
9710b57cec5SDimitry Andric   // When arranged in order of increasing rank (see 6.3.1.3a), the number of
9720b57cec5SDimitry Andric   // fractional bits is nondecreasing for each of the following sets of
9730b57cec5SDimitry Andric   // fixed-point types:
9740b57cec5SDimitry Andric   // - signed fract types
9750b57cec5SDimitry Andric   // - unsigned fract types
9760b57cec5SDimitry Andric   // - signed accum types
9770b57cec5SDimitry Andric   // - unsigned accum types.
9780b57cec5SDimitry Andric   assert(getLongFractScale() >= getFractScale() &&
9790b57cec5SDimitry Andric          getFractScale() >= getShortFractScale());
9800b57cec5SDimitry Andric   assert(getUnsignedLongFractScale() >= getUnsignedFractScale() &&
9810b57cec5SDimitry Andric          getUnsignedFractScale() >= getUnsignedShortFractScale());
9820b57cec5SDimitry Andric   assert(LongAccumScale >= AccumScale && AccumScale >= ShortAccumScale);
9830b57cec5SDimitry Andric   assert(getUnsignedLongAccumScale() >= getUnsignedAccumScale() &&
9840b57cec5SDimitry Andric          getUnsignedAccumScale() >= getUnsignedShortAccumScale());
9850b57cec5SDimitry Andric 
9860b57cec5SDimitry Andric   // When arranged in order of increasing rank (see 6.3.1.3a), the number of
9870b57cec5SDimitry Andric   // integral bits is nondecreasing for each of the following sets of
9880b57cec5SDimitry Andric   // fixed-point types:
9890b57cec5SDimitry Andric   // - signed accum types
9900b57cec5SDimitry Andric   // - unsigned accum types
9910b57cec5SDimitry Andric   assert(getLongAccumIBits() >= getAccumIBits() &&
9920b57cec5SDimitry Andric          getAccumIBits() >= getShortAccumIBits());
9930b57cec5SDimitry Andric   assert(getUnsignedLongAccumIBits() >= getUnsignedAccumIBits() &&
9940b57cec5SDimitry Andric          getUnsignedAccumIBits() >= getUnsignedShortAccumIBits());
9950b57cec5SDimitry Andric 
9960b57cec5SDimitry Andric   // Each signed accum type has at least as many integral bits as its
9970b57cec5SDimitry Andric   // corresponding unsigned accum type.
9980b57cec5SDimitry Andric   assert(getShortAccumIBits() >= getUnsignedShortAccumIBits());
9990b57cec5SDimitry Andric   assert(getAccumIBits() >= getUnsignedAccumIBits());
10000b57cec5SDimitry Andric   assert(getLongAccumIBits() >= getUnsignedLongAccumIBits());
10010b57cec5SDimitry Andric }
10020b57cec5SDimitry Andric 
10030b57cec5SDimitry Andric void TargetInfo::copyAuxTarget(const TargetInfo *Aux) {
10040b57cec5SDimitry Andric   auto *Target = static_cast<TransferrableTargetInfo*>(this);
10050b57cec5SDimitry Andric   auto *Src = static_cast<const TransferrableTargetInfo*>(Aux);
10060b57cec5SDimitry Andric   *Target = *Src;
10070b57cec5SDimitry Andric }
1008