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