17a51313dSChris Lattner //===--- TargetInfo.cpp - Information about Target machine ----------------===//
27a51313dSChris Lattner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67a51313dSChris Lattner //
77a51313dSChris Lattner //===----------------------------------------------------------------------===//
87a51313dSChris Lattner //
97a51313dSChris Lattner // This file implements the TargetInfo and TargetInfoImpl interfaces.
107a51313dSChris Lattner //
117a51313dSChris Lattner //===----------------------------------------------------------------------===//
127a51313dSChris Lattner
137a51313dSChris Lattner #include "clang/Basic/TargetInfo.h"
143a02247dSChandler Carruth #include "clang/Basic/AddressSpaces.h"
15a7d03840SJordan Rose #include "clang/Basic/CharInfo.h"
160fb8c877SAlexander Ivchenko #include "clang/Basic/Diagnostic.h"
17ed4e2950SJohn Thompson #include "clang/Basic/LangOptions.h"
187a51313dSChris Lattner #include "llvm/ADT/APFloat.h"
197a51313dSChris Lattner #include "llvm/ADT/STLExtras.h"
2076bd3c80SDavid Blaikie #include "llvm/Support/ErrorHandling.h"
21729379a1SSaleem Abdulrasool #include "llvm/Support/TargetParser.h"
22c4f02b6bSChris Lattner #include <cstdlib>
237a51313dSChris Lattner using namespace clang;
247a51313dSChris Lattner
256d989436SAlexander Richardson static const LangASMap DefaultAddrSpaceMap = {0};
26599cb8e4SPeter Collingbourne
277a51313dSChris Lattner // TargetInfo Constructor.
TargetInfo(const llvm::Triple & T)28d677a7cbSKazu Hirata TargetInfo::TargetInfo(const llvm::Triple &T) : Triple(T) {
293d9289c7SDaniel Dunbar // Set defaults. Defaults are set for a 32-bit RISC platform, like PPC or
303d9289c7SDaniel Dunbar // SPARC. These should be overridden by concrete targets as needed.
31f333de37SMatt Arsenault BigEndian = !T.isLittleEndian();
32d88c8a10SEli Friedman TLSSupported = true;
3387d44269SJonas Hahnfeld VLASupported = true;
341a8f394aSChris Lattner NoAsmVariants = false;
3587793e75SSjoerd Meijer HasLegalHalfType = false;
36bb1ea2d6SNemanja Ivanovic HasFloat128 = false;
37fae0dfa6SQiu Chaofan HasIbm128 = false;
381d1d438eSErich Keane HasFloat16 = false;
39ecd682bbSTies Stuij HasBFloat16 = false;
40a8083d42SAndrew Savonichev HasLongDouble = true;
41a8083d42SAndrew Savonichev HasFPReturn = true;
42d4ce862fSKevin P. Neal HasStrictFP = false;
435e2ef0c1SChris Lattner PointerWidth = PointerAlign = 32;
44965b0b72SRoman Divacky BoolWidth = BoolAlign = 8;
45b781dc79SChris Lattner IntWidth = IntAlign = 32;
465a9aaaf6SChris Lattner LongWidth = LongAlign = 32;
475a9aaaf6SChris Lattner LongLongWidth = LongLongAlign = 64;
48db01c3adSLeonard Chan
49db01c3adSLeonard Chan // Fixed point default bit widths
50f921d854SLeonard Chan ShortAccumWidth = ShortAccumAlign = 16;
51f921d854SLeonard Chan AccumWidth = AccumAlign = 32;
52f921d854SLeonard Chan LongAccumWidth = LongAccumAlign = 64;
53db01c3adSLeonard Chan ShortFractWidth = ShortFractAlign = 8;
54db01c3adSLeonard Chan FractWidth = FractAlign = 16;
55db01c3adSLeonard Chan LongFractWidth = LongFractAlign = 32;
56db01c3adSLeonard Chan
57db01c3adSLeonard Chan // Fixed point default integral and fractional bit sizes
58db01c3adSLeonard Chan // We give the _Accum 1 fewer fractional bits than their corresponding _Fract
59db01c3adSLeonard Chan // types by default to have the same number of fractional bits between _Accum
60db01c3adSLeonard Chan // and _Fract types.
616e16c60fSLeonard Chan PaddingOnUnsignedFixedPoint = false;
62db01c3adSLeonard Chan ShortAccumScale = 7;
63db01c3adSLeonard Chan AccumScale = 15;
64db01c3adSLeonard Chan LongAccumScale = 31;
65db01c3adSLeonard Chan
66f59e129cSNick Lewycky SuitableAlign = 64;
67ca3cb7f3SUlrich Weigand DefaultAlignForAttributeAligned = 128;
68fa806422SUlrich Weigand MinGlobalAlign = 0;
6959139028SRichard Smith // From the glibc documentation, on GNU systems, malloc guarantees 16-byte
7059139028SRichard Smith // alignment on 64-bit systems and 8-byte alignment on 32-bit systems. See
71b818347aSPirama Arumuga Nainar // https://www.gnu.org/software/libc/manual/html_node/Malloc-Examples.html.
72c7ee0b8bSMark Kettenis // This alignment guarantee also applies to Windows and Android. On Darwin
73c7ee0b8bSMark Kettenis // and OpenBSD, the alignment is 16 bytes on both 64-bit and 32-bit systems.
74b818347aSPirama Arumuga Nainar if (T.isGNUEnvironment() || T.isWindowsMSVCEnvironment() || T.isAndroid())
7559139028SRichard Smith NewAlign = Triple.isArch64Bit() ? 128 : Triple.isArch32Bit() ? 64 : 0;
76c7ee0b8bSMark Kettenis else if (T.isOSDarwin() || T.isOSOpenBSD())
77aade0ec2SAkira Hatanaka NewAlign = 128;
7859139028SRichard Smith else
7959139028SRichard Smith NewAlign = 0; // Infer from basic type alignment.
80f0c267e6SAnton Korobeynikov HalfWidth = 16;
81f0c267e6SAnton Korobeynikov HalfAlign = 16;
82b5366069SEli Friedman FloatWidth = 32;
83b5366069SEli Friedman FloatAlign = 32;
84c00bed38SNate Begeman DoubleWidth = 64;
85b5366069SEli Friedman DoubleAlign = 64;
86b5366069SEli Friedman LongDoubleWidth = 64;
87b5366069SEli Friedman LongDoubleAlign = 64;
88bb1ea2d6SNemanja Ivanovic Float128Align = 128;
89fae0dfa6SQiu Chaofan Ibm128Align = 128;
90e971b9a2SRafael Espindola LargeArrayMinWidth = 0;
91e971b9a2SRafael Espindola LargeArrayAlign = 0;
924b72fdddSEli Friedman MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 0;
93cc40ea7fSChad Rosier MaxVectorAlign = 0;
94d30e2eefSPaul Robinson MaxTLSAlign = 0;
9500396513SAlexey Bataev SimdDefaultAlign = 0;
962a79a904SAnders Carlsson SizeType = UnsignedLong;
97d50881c6SEli Friedman PtrDiffType = SignedLong;
98d7959244SSanjiv Gupta IntMaxType = SignedLongLong;
997e4c81c8SChris Lattner IntPtrType = SignedLong;
100d50881c6SEli Friedman WCharType = SignedInt;
1016720492cSChris Lattner WIntType = SignedInt;
102a9ad47d9SAlisdair Meredith Char16Type = UnsignedShort;
103a9ad47d9SAlisdair Meredith Char32Type = UnsignedInt;
1042857ccbaSEli Friedman Int64Type = SignedLongLong;
105b99e2c56SBen Shi Int16Type = SignedShort;
106847f2a10SEdward O'Callaghan SigAtomicType = SignedInt;
1074e91899eSEli Friedman ProcessIDType = SignedInt;
10829898f45SFariborz Jahanian UseSignedCharForObjCBool = true;
1091da6511bSDaniel Dunbar UseBitFieldTypeAlignment = true;
11018903ee2SChad Rosier UseZeroLengthBitfieldAlignment = false;
1116f91cf75SFanbo Meng UseLeadingZeroLengthBitfield = true;
1120ce2f227SSunil Srivastava UseExplicitBitFieldAlignment = true;
11318903ee2SChad Rosier ZeroLengthBitfieldBoundary = 0;
1140858f0e0SFanbo Meng MaxAlignedAttribute = 0;
11517c7f703SStephan Bergmann HalfFormat = &llvm::APFloat::IEEEhalf();
11617c7f703SStephan Bergmann FloatFormat = &llvm::APFloat::IEEEsingle();
11717c7f703SStephan Bergmann DoubleFormat = &llvm::APFloat::IEEEdouble();
11817c7f703SStephan Bergmann LongDoubleFormat = &llvm::APFloat::IEEEdouble();
11917c7f703SStephan Bergmann Float128Format = &llvm::APFloat::IEEEquad();
120fae0dfa6SQiu Chaofan Ibm128Format = &llvm::APFloat::PPCDoubleDouble();
121178e0160SRoman Divacky MCountName = "mcount";
1220f1137baSNico Weber UserLabelPrefix = "_";
12341bfb66eSAbramo Bagnara RegParmMax = 0;
12441bfb66eSAbramo Bagnara SSERegParmMax = 0;
125bd60652aSDaniel Dunbar HasAlignMac68kSupport = false;
126c7d5c94fSCharles Davis HasBuiltinMSVaList = false;
127bb846a32SPirama Arumuga Nainar IsRenderScriptTarget = false;
128eb485fbcSRichard Sandiford HasAArch64SVETypes = false;
129766ee109SHsiangkai Wang HasRISCVVTypes = false;
1303f4b5893SYaxun (Sam) Liu AllowAMDGPUUnsafeFPAtomics = false;
131cdeeb548SMikhail Maltsev ARMCDECoprocMask = 0;
1326f2e8396SDaniel Dunbar
1336f2e8396SDaniel Dunbar // Default to no types using fpret.
134c80c5767SJolanta Jensen RealTypeUsesObjCFPRetMask = 0;
13586353416SJohn McCall
1362f1a6c3fSAnders Carlsson // Default to not using fp2ret for __Complex long double
1372f1a6c3fSAnders Carlsson ComplexLongDoubleUsesFP2Ret = false;
1382f1a6c3fSAnders Carlsson
139c9bd88e6SHans Wennborg // Set the C++ ABI based on the triple.
140377066a5SSaleem Abdulrasool TheCXXABI.set(Triple.isKnownWindowsMSVCEnvironment()
141c9bd88e6SHans Wennborg ? TargetCXXABI::Microsoft
142c9bd88e6SHans Wennborg : TargetCXXABI::GenericItanium);
143599cb8e4SPeter Collingbourne
144599cb8e4SPeter Collingbourne // Default to an empty address space map.
145599cb8e4SPeter Collingbourne AddrSpaceMap = &DefaultAddrSpaceMap;
14631d09b0cSDavid Tweed UseAddrSpaceMapMangling = false;
14720b2ebd7SDouglas Gregor
14820b2ebd7SDouglas Gregor // Default to an unknown platform name.
14920b2ebd7SDouglas Gregor PlatformName = "unknown";
15020b2ebd7SDouglas Gregor PlatformMinVersion = VersionTuple();
151369e26caSYaxun (Sam) Liu
152369e26caSYaxun (Sam) Liu MaxOpenCLWorkGroupSize = 1024;
1537e17e15cSMatthias Gehre
1547e17e15cSMatthias Gehre MaxBitIntWidth.reset();
1557e17e15cSMatthias Gehre
1564eaf5846SElizabeth Andrews ProgramAddrSpace = 0;
1577a51313dSChris Lattner }
1587a51313dSChris Lattner
1597a51313dSChris Lattner // Out of line virtual dtor for TargetInfo.
~TargetInfo()160637d1e66SAngel Garcia Gomez TargetInfo::~TargetInfo() {}
1617a51313dSChris Lattner
resetDataLayout(StringRef DL,const char * ULP)1620f1137baSNico Weber void TargetInfo::resetDataLayout(StringRef DL, const char *ULP) {
1630f1137baSNico Weber DataLayoutString = DL.str();
1640f1137baSNico Weber UserLabelPrefix = ULP;
16578424e5fSBjorn Pettersson }
16678424e5fSBjorn Pettersson
1670fb8c877SAlexander Ivchenko bool
checkCFProtectionBranchSupported(DiagnosticsEngine & Diags) const1680fb8c877SAlexander Ivchenko TargetInfo::checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const {
1690fb8c877SAlexander Ivchenko Diags.Report(diag::err_opt_not_valid_on_target) << "cf-protection=branch";
1700fb8c877SAlexander Ivchenko return false;
1710fb8c877SAlexander Ivchenko }
1720fb8c877SAlexander Ivchenko
1730fb8c877SAlexander Ivchenko bool
checkCFProtectionReturnSupported(DiagnosticsEngine & Diags) const1740fb8c877SAlexander Ivchenko TargetInfo::checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const {
1750fb8c877SAlexander Ivchenko Diags.Report(diag::err_opt_not_valid_on_target) << "cf-protection=return";
1760fb8c877SAlexander Ivchenko return false;
1770fb8c877SAlexander Ivchenko }
1780fb8c877SAlexander Ivchenko
179a91c30fdSChris Lattner /// getTypeName - Return the user string for the specified integer type enum.
180a91c30fdSChris Lattner /// For example, SignedShort -> "short".
getTypeName(IntType T)181a91c30fdSChris Lattner const char *TargetInfo::getTypeName(IntType T) {
182a91c30fdSChris Lattner switch (T) {
18383d382b1SDavid Blaikie default: llvm_unreachable("not an integer!");
1843d9478cfSJoerg Sonnenberger case SignedChar: return "signed char";
1855a637922SStepan Dyatkovskiy case UnsignedChar: return "unsigned char";
186a91c30fdSChris Lattner case SignedShort: return "short";
187a91c30fdSChris Lattner case UnsignedShort: return "unsigned short";
188a91c30fdSChris Lattner case SignedInt: return "int";
189a91c30fdSChris Lattner case UnsignedInt: return "unsigned int";
190a91c30fdSChris Lattner case SignedLong: return "long int";
191a91c30fdSChris Lattner case UnsignedLong: return "long unsigned int";
192a91c30fdSChris Lattner case SignedLongLong: return "long long int";
193a91c30fdSChris Lattner case UnsignedLongLong: return "long long unsigned int";
194a91c30fdSChris Lattner }
195a91c30fdSChris Lattner }
196a91c30fdSChris Lattner
19772cdcacbSChris Lattner /// getTypeConstantSuffix - Return the constant suffix for the specified
19872cdcacbSChris Lattner /// integer type enum. For example, SignedLong -> "L".
getTypeConstantSuffix(IntType T) const199587deea8SJoerg Sonnenberger const char *TargetInfo::getTypeConstantSuffix(IntType T) const {
20072cdcacbSChris Lattner switch (T) {
20183d382b1SDavid Blaikie default: llvm_unreachable("not an integer!");
2025a637922SStepan Dyatkovskiy case SignedChar:
20372cdcacbSChris Lattner case SignedShort:
20472cdcacbSChris Lattner case SignedInt: return "";
20572cdcacbSChris Lattner case SignedLong: return "L";
20672cdcacbSChris Lattner case SignedLongLong: return "LL";
2075a637922SStepan Dyatkovskiy case UnsignedChar:
208587deea8SJoerg Sonnenberger if (getCharWidth() < getIntWidth())
209587deea8SJoerg Sonnenberger return "";
21096088f4dSGalina Kistanova LLVM_FALLTHROUGH;
21172cdcacbSChris Lattner case UnsignedShort:
212587deea8SJoerg Sonnenberger if (getShortWidth() < getIntWidth())
213587deea8SJoerg Sonnenberger return "";
21496088f4dSGalina Kistanova LLVM_FALLTHROUGH;
21572cdcacbSChris Lattner case UnsignedInt: return "U";
21672cdcacbSChris Lattner case UnsignedLong: return "UL";
21772cdcacbSChris Lattner case UnsignedLongLong: return "ULL";
21872cdcacbSChris Lattner }
21972cdcacbSChris Lattner }
22072cdcacbSChris Lattner
221be324f98SJoerg Sonnenberger /// getTypeFormatModifier - Return the printf format modifier for the
222be324f98SJoerg Sonnenberger /// specified integer type enum. For example, SignedLong -> "l".
223be324f98SJoerg Sonnenberger
getTypeFormatModifier(IntType T)224be324f98SJoerg Sonnenberger const char *TargetInfo::getTypeFormatModifier(IntType T) {
225be324f98SJoerg Sonnenberger switch (T) {
226be324f98SJoerg Sonnenberger default: llvm_unreachable("not an integer!");
227be324f98SJoerg Sonnenberger case SignedChar:
228be324f98SJoerg Sonnenberger case UnsignedChar: return "hh";
229be324f98SJoerg Sonnenberger case SignedShort:
230be324f98SJoerg Sonnenberger case UnsignedShort: return "h";
231be324f98SJoerg Sonnenberger case SignedInt:
232be324f98SJoerg Sonnenberger case UnsignedInt: return "";
233be324f98SJoerg Sonnenberger case SignedLong:
234be324f98SJoerg Sonnenberger case UnsignedLong: return "l";
235be324f98SJoerg Sonnenberger case SignedLongLong:
236be324f98SJoerg Sonnenberger case UnsignedLongLong: return "ll";
237be324f98SJoerg Sonnenberger }
238be324f98SJoerg Sonnenberger }
239be324f98SJoerg Sonnenberger
24072cdcacbSChris Lattner /// getTypeWidth - Return the width (in bits) of the specified integer type
24172cdcacbSChris Lattner /// enum. For example, SignedInt -> getIntWidth().
getTypeWidth(IntType T) const24272cdcacbSChris Lattner unsigned TargetInfo::getTypeWidth(IntType T) const {
24372cdcacbSChris Lattner switch (T) {
24483d382b1SDavid Blaikie default: llvm_unreachable("not an integer!");
2455a637922SStepan Dyatkovskiy case SignedChar:
2465a637922SStepan Dyatkovskiy case UnsignedChar: return getCharWidth();
247e4a8c647SChris Lattner case SignedShort:
24872cdcacbSChris Lattner case UnsignedShort: return getShortWidth();
249e4a8c647SChris Lattner case SignedInt:
25072cdcacbSChris Lattner case UnsignedInt: return getIntWidth();
251e4a8c647SChris Lattner case SignedLong:
25272cdcacbSChris Lattner case UnsignedLong: return getLongWidth();
253e4a8c647SChris Lattner case SignedLongLong:
25472cdcacbSChris Lattner case UnsignedLongLong: return getLongLongWidth();
25572cdcacbSChris Lattner };
25672cdcacbSChris Lattner }
25772cdcacbSChris Lattner
getIntTypeByWidth(unsigned BitWidth,bool IsSigned) const2585a637922SStepan Dyatkovskiy TargetInfo::IntType TargetInfo::getIntTypeByWidth(
2595a637922SStepan Dyatkovskiy unsigned BitWidth, bool IsSigned) const {
2605a637922SStepan Dyatkovskiy if (getCharWidth() == BitWidth)
2615a637922SStepan Dyatkovskiy return IsSigned ? SignedChar : UnsignedChar;
2625a637922SStepan Dyatkovskiy if (getShortWidth() == BitWidth)
2635a637922SStepan Dyatkovskiy return IsSigned ? SignedShort : UnsignedShort;
2645a637922SStepan Dyatkovskiy if (getIntWidth() == BitWidth)
2655a637922SStepan Dyatkovskiy return IsSigned ? SignedInt : UnsignedInt;
2665a637922SStepan Dyatkovskiy if (getLongWidth() == BitWidth)
2675a637922SStepan Dyatkovskiy return IsSigned ? SignedLong : UnsignedLong;
2685a637922SStepan Dyatkovskiy if (getLongLongWidth() == BitWidth)
2695a637922SStepan Dyatkovskiy return IsSigned ? SignedLongLong : UnsignedLongLong;
2705a637922SStepan Dyatkovskiy return NoInt;
2715a637922SStepan Dyatkovskiy }
2725a637922SStepan Dyatkovskiy
getLeastIntTypeByWidth(unsigned BitWidth,bool IsSigned) const273ab8d0a0dSJF Bastien TargetInfo::IntType TargetInfo::getLeastIntTypeByWidth(unsigned BitWidth,
274ab8d0a0dSJF Bastien bool IsSigned) const {
275ab8d0a0dSJF Bastien if (getCharWidth() >= BitWidth)
276ab8d0a0dSJF Bastien return IsSigned ? SignedChar : UnsignedChar;
277ab8d0a0dSJF Bastien if (getShortWidth() >= BitWidth)
278ab8d0a0dSJF Bastien return IsSigned ? SignedShort : UnsignedShort;
279ab8d0a0dSJF Bastien if (getIntWidth() >= BitWidth)
280ab8d0a0dSJF Bastien return IsSigned ? SignedInt : UnsignedInt;
281ab8d0a0dSJF Bastien if (getLongWidth() >= BitWidth)
282ab8d0a0dSJF Bastien return IsSigned ? SignedLong : UnsignedLong;
283ab8d0a0dSJF Bastien if (getLongLongWidth() >= BitWidth)
284ab8d0a0dSJF Bastien return IsSigned ? SignedLongLong : UnsignedLongLong;
285ab8d0a0dSJF Bastien return NoInt;
286ab8d0a0dSJF Bastien }
287ab8d0a0dSJF Bastien
getRealTypeByWidth(unsigned BitWidth,FloatModeKind ExplicitType) const2888a714722SQiu Chaofan FloatModeKind TargetInfo::getRealTypeByWidth(unsigned BitWidth,
2898a714722SQiu Chaofan FloatModeKind ExplicitType) const {
290c80c5767SJolanta Jensen if (getHalfWidth() == BitWidth)
291c80c5767SJolanta Jensen return FloatModeKind::Half;
2925a637922SStepan Dyatkovskiy if (getFloatWidth() == BitWidth)
2938a714722SQiu Chaofan return FloatModeKind::Float;
2945a637922SStepan Dyatkovskiy if (getDoubleWidth() == BitWidth)
2958a714722SQiu Chaofan return FloatModeKind::Double;
2965a637922SStepan Dyatkovskiy
2975a637922SStepan Dyatkovskiy switch (BitWidth) {
2985a637922SStepan Dyatkovskiy case 96:
29917c7f703SStephan Bergmann if (&getLongDoubleFormat() == &llvm::APFloat::x87DoubleExtended())
3008a714722SQiu Chaofan return FloatModeKind::LongDouble;
3015a637922SStepan Dyatkovskiy break;
3025a637922SStepan Dyatkovskiy case 128:
3039021ce95SNemanja Ivanovic // The caller explicitly asked for an IEEE compliant type but we still
3049021ce95SNemanja Ivanovic // have to check if the target supports it.
3058a714722SQiu Chaofan if (ExplicitType == FloatModeKind::Float128)
3068a714722SQiu Chaofan return hasFloat128Type() ? FloatModeKind::Float128
3078a714722SQiu Chaofan : FloatModeKind::NoFloat;
308d11ec6f6SQiu Chaofan if (ExplicitType == FloatModeKind::Ibm128)
309d11ec6f6SQiu Chaofan return hasIbm128Type() ? FloatModeKind::Ibm128
310d11ec6f6SQiu Chaofan : FloatModeKind::NoFloat;
3115c8d3053SElizabeth Andrews if (&getLongDoubleFormat() == &llvm::APFloat::PPCDoubleDouble() ||
3125c8d3053SElizabeth Andrews &getLongDoubleFormat() == &llvm::APFloat::IEEEquad())
3135c8d3053SElizabeth Andrews return FloatModeKind::LongDouble;
3145c8d3053SElizabeth Andrews if (hasFloat128Type())
3155c8d3053SElizabeth Andrews return FloatModeKind::Float128;
3165a637922SStepan Dyatkovskiy break;
3175a637922SStepan Dyatkovskiy }
3185a637922SStepan Dyatkovskiy
3198a714722SQiu Chaofan return FloatModeKind::NoFloat;
3205a637922SStepan Dyatkovskiy }
3215a637922SStepan Dyatkovskiy
322e4a8c647SChris Lattner /// getTypeAlign - Return the alignment (in bits) of the specified integer type
323e4a8c647SChris Lattner /// enum. For example, SignedInt -> getIntAlign().
getTypeAlign(IntType T) const324e4a8c647SChris Lattner unsigned TargetInfo::getTypeAlign(IntType T) const {
325e4a8c647SChris Lattner switch (T) {
32683d382b1SDavid Blaikie default: llvm_unreachable("not an integer!");
3275a637922SStepan Dyatkovskiy case SignedChar:
3285a637922SStepan Dyatkovskiy case UnsignedChar: return getCharAlign();
329e4a8c647SChris Lattner case SignedShort:
330e4a8c647SChris Lattner case UnsignedShort: return getShortAlign();
331e4a8c647SChris Lattner case SignedInt:
332e4a8c647SChris Lattner case UnsignedInt: return getIntAlign();
333e4a8c647SChris Lattner case SignedLong:
334e4a8c647SChris Lattner case UnsignedLong: return getLongAlign();
335e4a8c647SChris Lattner case SignedLongLong:
336e4a8c647SChris Lattner case UnsignedLongLong: return getLongLongAlign();
337e4a8c647SChris Lattner };
338e4a8c647SChris Lattner }
339e4a8c647SChris Lattner
340c0c04390SChris Lattner /// isTypeSigned - Return whether an integer types is signed. Returns true if
34172cdcacbSChris Lattner /// the type is signed; false otherwise.
isTypeSigned(IntType T)342ad3467eeSChris Lattner bool TargetInfo::isTypeSigned(IntType T) {
34372cdcacbSChris Lattner switch (T) {
34483d382b1SDavid Blaikie default: llvm_unreachable("not an integer!");
3455a637922SStepan Dyatkovskiy case SignedChar:
34672cdcacbSChris Lattner case SignedShort:
34772cdcacbSChris Lattner case SignedInt:
34872cdcacbSChris Lattner case SignedLong:
34972cdcacbSChris Lattner case SignedLongLong:
35072cdcacbSChris Lattner return true;
3515a637922SStepan Dyatkovskiy case UnsignedChar:
35272cdcacbSChris Lattner case UnsignedShort:
35372cdcacbSChris Lattner case UnsignedInt:
35472cdcacbSChris Lattner case UnsignedLong:
35572cdcacbSChris Lattner case UnsignedLongLong:
35672cdcacbSChris Lattner return false;
35772cdcacbSChris Lattner };
35872cdcacbSChris Lattner }
35972cdcacbSChris Lattner
36074437975SAlp Toker /// adjust - Set forced language options.
361ed4e2950SJohn Thompson /// Apply changes to the target information with respect to certain
3623646e628SEric Christopher /// language options which change the target configuration and adjust
3633646e628SEric Christopher /// the language based on the target options where applicable.
adjust(DiagnosticsEngine & Diags,LangOptions & Opts)364aaba3718SMelanie Blower void TargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) {
3659302f606SDaniel Dunbar if (Opts.NoBitFieldTypeAlign)
3669302f606SDaniel Dunbar UseBitFieldTypeAlignment = false;
367729379a1SSaleem Abdulrasool
368729379a1SSaleem Abdulrasool switch (Opts.WCharSize) {
369729379a1SSaleem Abdulrasool default: llvm_unreachable("invalid wchar_t width");
370729379a1SSaleem Abdulrasool case 0: break;
371729379a1SSaleem Abdulrasool case 1: WCharType = Opts.WCharIsSigned ? SignedChar : UnsignedChar; break;
372729379a1SSaleem Abdulrasool case 2: WCharType = Opts.WCharIsSigned ? SignedShort : UnsignedShort; break;
373729379a1SSaleem Abdulrasool case 4: WCharType = Opts.WCharIsSigned ? SignedInt : UnsignedInt; break;
374729379a1SSaleem Abdulrasool }
375729379a1SSaleem Abdulrasool
3768195f696SReid Kleckner if (Opts.AlignDouble) {
3778195f696SReid Kleckner DoubleAlign = LongLongAlign = 64;
3788195f696SReid Kleckner LongDoubleAlign = 64;
3798195f696SReid Kleckner }
3802da64389SDavid Tweed
3812da64389SDavid Tweed if (Opts.OpenCL) {
3822da64389SDavid Tweed // OpenCL C requires specific widths for types, irrespective of
3832da64389SDavid Tweed // what these normally are for the target.
3842da64389SDavid Tweed // We also define long long and long double here, although the
3852da64389SDavid Tweed // OpenCL standard only mentions these as "reserved".
3862da64389SDavid Tweed IntWidth = IntAlign = 32;
3872da64389SDavid Tweed LongWidth = LongAlign = 64;
3882da64389SDavid Tweed LongLongWidth = LongLongAlign = 128;
3892da64389SDavid Tweed HalfWidth = HalfAlign = 16;
3902da64389SDavid Tweed FloatWidth = FloatAlign = 32;
39143c39d5fSPekka Jaaskelainen
39243c39d5fSPekka Jaaskelainen // Embedded 32-bit targets (OpenCL EP) might have double C type
39343c39d5fSPekka Jaaskelainen // defined as float. Let's not override this as it might lead
39443c39d5fSPekka Jaaskelainen // to generating illegal code that uses 64bit doubles.
39543c39d5fSPekka Jaaskelainen if (DoubleWidth != FloatWidth) {
3962da64389SDavid Tweed DoubleWidth = DoubleAlign = 64;
39717c7f703SStephan Bergmann DoubleFormat = &llvm::APFloat::IEEEdouble();
39843c39d5fSPekka Jaaskelainen }
3992da64389SDavid Tweed LongDoubleWidth = LongDoubleAlign = 128;
4002da64389SDavid Tweed
40126f7566fSYaxun Liu unsigned MaxPointerWidth = getMaxPointerWidth();
40226f7566fSYaxun Liu assert(MaxPointerWidth == 32 || MaxPointerWidth == 64);
40326f7566fSYaxun Liu bool Is32BitArch = MaxPointerWidth == 32;
4046c2149b3SDavid Tweed SizeType = Is32BitArch ? UnsignedInt : UnsignedLong;
4056c2149b3SDavid Tweed PtrDiffType = Is32BitArch ? SignedInt : SignedLong;
4066c2149b3SDavid Tweed IntPtrType = Is32BitArch ? SignedInt : SignedLong;
4072da64389SDavid Tweed
4082da64389SDavid Tweed IntMaxType = SignedLongLong;
4092da64389SDavid Tweed Int64Type = SignedLong;
4102da64389SDavid Tweed
41117c7f703SStephan Bergmann HalfFormat = &llvm::APFloat::IEEEhalf();
41217c7f703SStephan Bergmann FloatFormat = &llvm::APFloat::IEEEsingle();
41317c7f703SStephan Bergmann LongDoubleFormat = &llvm::APFloat::IEEEquad();
41478463ebdSAnton Zabaznov
41578463ebdSAnton Zabaznov // OpenCL C v3.0 s6.7.5 - The generic address space requires support for
41678463ebdSAnton Zabaznov // OpenCL C 2.0 or OpenCL C 3.0 with the __opencl_c_generic_address_space
41778463ebdSAnton Zabaznov // feature
418acc58504SAnton Zabaznov // OpenCL C v3.0 s6.2.1 - OpenCL pipes require support of OpenCL C 2.0
419acc58504SAnton Zabaznov // or later and __opencl_c_pipes feature
420acc58504SAnton Zabaznov // FIXME: These language options are also defined in setLangDefaults()
42178463ebdSAnton Zabaznov // for OpenCL C 2.0 but with no access to target capabilities. Target
422acc58504SAnton Zabaznov // should be immutable once created and thus these language options need
42378463ebdSAnton Zabaznov // to be defined only once.
424cc9260a0SJustas Janickas if (Opts.getOpenCLCompatibleVersion() == 300) {
42578463ebdSAnton Zabaznov const auto &OpenCLFeaturesMap = getSupportedOpenCLOpts();
42678463ebdSAnton Zabaznov Opts.OpenCLGenericAddressSpace = hasFeatureEnabled(
42778463ebdSAnton Zabaznov OpenCLFeaturesMap, "__opencl_c_generic_address_space");
428acc58504SAnton Zabaznov Opts.OpenCLPipes =
429acc58504SAnton Zabaznov hasFeatureEnabled(OpenCLFeaturesMap, "__opencl_c_pipes");
430a5de66c4SAnton Zabaznov Opts.Blocks =
431a5de66c4SAnton Zabaznov hasFeatureEnabled(OpenCLFeaturesMap, "__opencl_c_device_enqueue");
43278463ebdSAnton Zabaznov }
4332da64389SDavid Tweed }
43459139028SRichard Smith
4354add2492SAyke van Laethem if (Opts.DoubleSize) {
4364add2492SAyke van Laethem if (Opts.DoubleSize == 32) {
4374add2492SAyke van Laethem DoubleWidth = 32;
4384add2492SAyke van Laethem LongDoubleWidth = 32;
4394add2492SAyke van Laethem DoubleFormat = &llvm::APFloat::IEEEsingle();
4404add2492SAyke van Laethem LongDoubleFormat = &llvm::APFloat::IEEEsingle();
4414add2492SAyke van Laethem } else if (Opts.DoubleSize == 64) {
4424add2492SAyke van Laethem DoubleWidth = 64;
4434add2492SAyke van Laethem LongDoubleWidth = 64;
4444add2492SAyke van Laethem DoubleFormat = &llvm::APFloat::IEEEdouble();
4454add2492SAyke van Laethem LongDoubleFormat = &llvm::APFloat::IEEEdouble();
4464add2492SAyke van Laethem }
4474add2492SAyke van Laethem }
4484add2492SAyke van Laethem
449c46d78d1SFangrui Song if (Opts.LongDoubleSize) {
450c46d78d1SFangrui Song if (Opts.LongDoubleSize == DoubleWidth) {
45111cb39c5SFangrui Song LongDoubleWidth = DoubleWidth;
45211cb39c5SFangrui Song LongDoubleAlign = DoubleAlign;
45311cb39c5SFangrui Song LongDoubleFormat = DoubleFormat;
454c46d78d1SFangrui Song } else if (Opts.LongDoubleSize == 128) {
455c46d78d1SFangrui Song LongDoubleWidth = LongDoubleAlign = 128;
456c46d78d1SFangrui Song LongDoubleFormat = &llvm::APFloat::IEEEquad();
4573e19ba36SPhoebe Wang } else if (Opts.LongDoubleSize == 80) {
4583e19ba36SPhoebe Wang LongDoubleFormat = &llvm::APFloat::x87DoubleExtended();
4593e19ba36SPhoebe Wang if (getTriple().isWindowsMSVCEnvironment()) {
4603e19ba36SPhoebe Wang LongDoubleWidth = 128;
4613e19ba36SPhoebe Wang LongDoubleAlign = 128;
4623e19ba36SPhoebe Wang } else { // Linux
4633e19ba36SPhoebe Wang if (getTriple().getArch() == llvm::Triple::x86) {
4643e19ba36SPhoebe Wang LongDoubleWidth = 96;
4653e19ba36SPhoebe Wang LongDoubleAlign = 32;
4663e19ba36SPhoebe Wang } else {
4673e19ba36SPhoebe Wang LongDoubleWidth = 128;
4683e19ba36SPhoebe Wang LongDoubleAlign = 128;
4693e19ba36SPhoebe Wang }
4703e19ba36SPhoebe Wang }
471c46d78d1SFangrui Song }
47211cb39c5SFangrui Song }
47311cb39c5SFangrui Song
47459139028SRichard Smith if (Opts.NewAlignOverride)
47559139028SRichard Smith NewAlign = Opts.NewAlignOverride * getCharWidth();
476db01c3adSLeonard Chan
477db01c3adSLeonard Chan // Each unsigned fixed point type has the same number of fractional bits as
478db01c3adSLeonard Chan // its corresponding signed type.
4796e16c60fSLeonard Chan PaddingOnUnsignedFixedPoint |= Opts.PaddingOnUnsignedFixedPoint;
480db01c3adSLeonard Chan CheckFixedPointBits();
481e773216fSMelanie Blower
482e773216fSMelanie Blower if (Opts.ProtectParens && !checkArithmeticFenceSupported()) {
483e773216fSMelanie Blower Diags.Report(diag::err_opt_not_valid_on_target) << "-fprotect-parens";
484e773216fSMelanie Blower Opts.ProtectParens = false;
485e773216fSMelanie Blower }
4867e17e15cSMatthias Gehre
4877e17e15cSMatthias Gehre if (Opts.MaxBitIntWidth)
4887e17e15cSMatthias Gehre MaxBitIntWidth = Opts.MaxBitIntWidth;
489ed4e2950SJohn Thompson }
49072cdcacbSChris Lattner
initFeatureMap(llvm::StringMap<bool> & Features,DiagnosticsEngine & Diags,StringRef CPU,const std::vector<std::string> & FeatureVec) const4918c47b427SEric Christopher bool TargetInfo::initFeatureMap(
4928c47b427SEric Christopher llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
4938c47b427SEric Christopher const std::vector<std::string> &FeatureVec) const {
494e9cdcaeeSEric Christopher for (const auto &F : FeatureVec) {
4958459aa8fSCraig Topper StringRef Name = F;
496e9cdcaeeSEric Christopher // Apply the feature via the target.
497e9cdcaeeSEric Christopher bool Enabled = Name[0] == '+';
4988459aa8fSCraig Topper setFeatureEnabled(Features, Name.substr(1), Enabled);
499e9cdcaeeSEric Christopher }
500e9cdcaeeSEric Christopher return true;
501e9cdcaeeSEric Christopher }
502e9cdcaeeSEric Christopher
503fcbe17c6SAkira Hatanaka TargetInfo::CallingConvKind
getCallingConvKind(bool ClangABICompat4) const504fcbe17c6SAkira Hatanaka TargetInfo::getCallingConvKind(bool ClangABICompat4) const {
505fcbe17c6SAkira Hatanaka if (getCXXABI() != TargetCXXABI::Microsoft &&
506*2b9055ceSPaul Robinson (ClangABICompat4 || getTriple().isPS4()))
507fcbe17c6SAkira Hatanaka return CCK_ClangABI4OrPS4;
508fcbe17c6SAkira Hatanaka return CCK_Default;
509fcbe17c6SAkira Hatanaka }
510fcbe17c6SAkira Hatanaka
getOpenCLTypeAddrSpace(OpenCLTypeKind TK) const5113bb7eaf7SSven van Haastregt LangAS TargetInfo::getOpenCLTypeAddrSpace(OpenCLTypeKind TK) const {
5123bb7eaf7SSven van Haastregt switch (TK) {
5133bb7eaf7SSven van Haastregt case OCLTK_Image:
5143bb7eaf7SSven van Haastregt case OCLTK_Pipe:
515efb4d4c7SSven van Haastregt return LangAS::opencl_global;
516efb4d4c7SSven van Haastregt
5173bb7eaf7SSven van Haastregt case OCLTK_Sampler:
518efb4d4c7SSven van Haastregt return LangAS::opencl_constant;
519efb4d4c7SSven van Haastregt
520efb4d4c7SSven van Haastregt default:
521efb4d4c7SSven van Haastregt return LangAS::Default;
522efb4d4c7SSven van Haastregt }
523efb4d4c7SSven van Haastregt }
524efb4d4c7SSven van Haastregt
5257a51313dSChris Lattner //===----------------------------------------------------------------------===//
5267a51313dSChris Lattner
5277a51313dSChris Lattner
removeGCCRegisterPrefix(StringRef Name)5280e62c1ccSChris Lattner static StringRef removeGCCRegisterPrefix(StringRef Name) {
5297a51313dSChris Lattner if (Name[0] == '%' || Name[0] == '#')
530c7c5baa4SAnders Carlsson Name = Name.substr(1);
531c7c5baa4SAnders Carlsson
532c7c5baa4SAnders Carlsson return Name;
5337a51313dSChris Lattner }
5347a51313dSChris Lattner
535fd9a5f4fSEric Christopher /// isValidClobber - Returns whether the passed in string is
536fd9a5f4fSEric Christopher /// a valid clobber in an inline asm statement. This is used by
537fd9a5f4fSEric Christopher /// Sema.
isValidClobber(StringRef Name) const5380e62c1ccSChris Lattner bool TargetInfo::isValidClobber(StringRef Name) const {
5398ec9fd48Scynecx return (isValidGCCRegisterName(Name) || Name == "memory" || Name == "cc" ||
5408ec9fd48Scynecx Name == "unwind");
541fd9a5f4fSEric Christopher }
542fd9a5f4fSEric Christopher
5437a51313dSChris Lattner /// isValidGCCRegisterName - Returns whether the passed in string
5447a51313dSChris Lattner /// is a valid register name according to GCC. This is used by Sema for
5457a51313dSChris Lattner /// inline asm statements.
isValidGCCRegisterName(StringRef Name) const5460e62c1ccSChris Lattner bool TargetInfo::isValidGCCRegisterName(StringRef Name) const {
547c7c5baa4SAnders Carlsson if (Name.empty())
548c7c5baa4SAnders Carlsson return false;
549c7c5baa4SAnders Carlsson
5507a51313dSChris Lattner // Get rid of any register prefix.
551c7c5baa4SAnders Carlsson Name = removeGCCRegisterPrefix(Name);
552fc8f8931SOlivier Goffart if (Name.empty())
553fc8f8931SOlivier Goffart return false;
5547a51313dSChris Lattner
555f054e3adSCraig Topper ArrayRef<const char *> Names = getGCCRegNames();
5567a51313dSChris Lattner
5577a51313dSChris Lattner // If we have a number it maps to an entry in the register name array.
558a7d03840SJordan Rose if (isDigit(Name[0])) {
55967288a9bSCraig Topper unsigned n;
560c7c5baa4SAnders Carlsson if (!Name.getAsInteger(0, n))
56167288a9bSCraig Topper return n < Names.size();
5627a51313dSChris Lattner }
5637a51313dSChris Lattner
5647a51313dSChris Lattner // Check register names.
5659ac13a12SFangrui Song if (llvm::is_contained(Names, Name))
5667a51313dSChris Lattner return true;
5677a51313dSChris Lattner
568cdd3635bSEric Christopher // Check any additional names that we have.
569dd2b74abSCraig Topper for (const AddlRegName &ARN : getGCCAddlRegNames())
570dd2b74abSCraig Topper for (const char *AN : ARN.Names) {
571dd2b74abSCraig Topper if (!AN)
572cdd3635bSEric Christopher break;
573cdd3635bSEric Christopher // Make sure the register that the additional name is for is within
574cdd3635bSEric Christopher // the bounds of the register names from above.
575dd2b74abSCraig Topper if (AN == Name && ARN.RegNum < Names.size())
576cdd3635bSEric Christopher return true;
577cdd3635bSEric Christopher }
578cdd3635bSEric Christopher
5797a51313dSChris Lattner // Now check aliases.
580dd2b74abSCraig Topper for (const GCCRegAlias &GRA : getGCCRegAliases())
581dd2b74abSCraig Topper for (const char *A : GRA.Aliases) {
582dd2b74abSCraig Topper if (!A)
5837a51313dSChris Lattner break;
584dd2b74abSCraig Topper if (A == Name)
5857a51313dSChris Lattner return true;
5867a51313dSChris Lattner }
5877a51313dSChris Lattner
5887a51313dSChris Lattner return false;
5897a51313dSChris Lattner }
5907a51313dSChris Lattner
getNormalizedGCCRegisterName(StringRef Name,bool ReturnCanonical) const591c42fd03bSMarina Yatsina StringRef TargetInfo::getNormalizedGCCRegisterName(StringRef Name,
592c42fd03bSMarina Yatsina bool ReturnCanonical) const {
5937a51313dSChris Lattner assert(isValidGCCRegisterName(Name) && "Invalid register passed in");
5947a51313dSChris Lattner
595c7c5baa4SAnders Carlsson // Get rid of any register prefix.
596c7c5baa4SAnders Carlsson Name = removeGCCRegisterPrefix(Name);
5977a51313dSChris Lattner
598f054e3adSCraig Topper ArrayRef<const char *> Names = getGCCRegNames();
5997a51313dSChris Lattner
6007a51313dSChris Lattner // First, check if we have a number.
601a7d03840SJordan Rose if (isDigit(Name[0])) {
60267288a9bSCraig Topper unsigned n;
603c7c5baa4SAnders Carlsson if (!Name.getAsInteger(0, n)) {
60467288a9bSCraig Topper assert(n < Names.size() && "Out of bounds register number!");
6057a51313dSChris Lattner return Names[n];
6067a51313dSChris Lattner }
6077a51313dSChris Lattner }
6087a51313dSChris Lattner
609cdd3635bSEric Christopher // Check any additional names that we have.
610dd2b74abSCraig Topper for (const AddlRegName &ARN : getGCCAddlRegNames())
611dd2b74abSCraig Topper for (const char *AN : ARN.Names) {
612dd2b74abSCraig Topper if (!AN)
613cdd3635bSEric Christopher break;
614cdd3635bSEric Christopher // Make sure the register that the additional name is for is within
615cdd3635bSEric Christopher // the bounds of the register names from above.
616dd2b74abSCraig Topper if (AN == Name && ARN.RegNum < Names.size())
617c42fd03bSMarina Yatsina return ReturnCanonical ? Names[ARN.RegNum] : Name;
618cdd3635bSEric Christopher }
619cdd3635bSEric Christopher
6207a51313dSChris Lattner // Now check aliases.
621dd2b74abSCraig Topper for (const GCCRegAlias &RA : getGCCRegAliases())
622dd2b74abSCraig Topper for (const char *A : RA.Aliases) {
623dd2b74abSCraig Topper if (!A)
6247a51313dSChris Lattner break;
625dd2b74abSCraig Topper if (A == Name)
626dd2b74abSCraig Topper return RA.Register;
6277a51313dSChris Lattner }
6287a51313dSChris Lattner
6297a51313dSChris Lattner return Name;
6307a51313dSChris Lattner }
6317a51313dSChris Lattner
validateOutputConstraint(ConstraintInfo & Info) const632c3f4c7b1SChris Lattner bool TargetInfo::validateOutputConstraint(ConstraintInfo &Info) const {
633c3f4c7b1SChris Lattner const char *Name = Info.getConstraintStr().c_str();
6347a51313dSChris Lattner // An output constraint must start with '=' or '+'
6357a51313dSChris Lattner if (*Name != '=' && *Name != '+')
6367a51313dSChris Lattner return false;
6377a51313dSChris Lattner
6387a51313dSChris Lattner if (*Name == '+')
639d9725f70SChris Lattner Info.setIsReadWrite();
6407a51313dSChris Lattner
6417a51313dSChris Lattner Name++;
6427a51313dSChris Lattner while (*Name) {
6437a51313dSChris Lattner switch (*Name) {
6447a51313dSChris Lattner default:
645d9725f70SChris Lattner if (!validateAsmConstraint(Name, Info)) {
646b44485b8STed Kremenek // FIXME: We temporarily return false
6477a51313dSChris Lattner // so we can add more constraints as we hit it.
6487a51313dSChris Lattner // Eventually, an unknown constraint should just be treated as 'g'.
649b44485b8STed Kremenek return false;
6507a51313dSChris Lattner }
651a0040df3SDavid Majnemer break;
6527a51313dSChris Lattner case '&': // early clobber.
653a0040df3SDavid Majnemer Info.setEarlyClobber();
6547a51313dSChris Lattner break;
655f315471eSChris Lattner case '%': // commutative.
656f315471eSChris Lattner // FIXME: Check that there is a another register after this one.
657f315471eSChris Lattner break;
6587a51313dSChris Lattner case 'r': // general register.
659d9725f70SChris Lattner Info.setAllowsRegister();
6607a51313dSChris Lattner break;
6617a51313dSChris Lattner case 'm': // memory operand.
6628499f47eSDale Johannesen case 'o': // offsetable memory operand.
6638499f47eSDale Johannesen case 'V': // non-offsetable memory operand.
6648499f47eSDale Johannesen case '<': // autodecrement memory operand.
6658499f47eSDale Johannesen case '>': // autoincrement memory operand.
666d9725f70SChris Lattner Info.setAllowsMemory();
6677a51313dSChris Lattner break;
6687a51313dSChris Lattner case 'g': // general register, memory operand or immediate integer.
669e70cde13SAnders Carlsson case 'X': // any operand.
670d9725f70SChris Lattner Info.setAllowsRegister();
671d9725f70SChris Lattner Info.setAllowsMemory();
6727a51313dSChris Lattner break;
673a5c7d706SJohn Thompson case ',': // multiple alternative constraint. Pass it.
67446667afcSJohn Thompson // Handle additional optional '=' or '+' modifiers.
67512240612SJohn Thompson if (Name[1] == '=' || Name[1] == '+')
67646667afcSJohn Thompson Name++;
677a5c7d706SJohn Thompson break;
67850cb0559SDavid Majnemer case '#': // Ignore as constraint.
67950cb0559SDavid Majnemer while (Name[1] && Name[1] != ',')
68050cb0559SDavid Majnemer Name++;
681c71a566dSDavid Majnemer break;
682a5c7d706SJohn Thompson case '?': // Disparage slightly code.
6838499f47eSDale Johannesen case '!': // Disparage severely.
6847bcc7ec7SUlrich Weigand case '*': // Ignore for choosing register preferences.
68533eb7752SMarina Yatsina case 'i': // Ignore i,n,E,F as output constraints (match from the other
68633eb7752SMarina Yatsina // chars)
68733eb7752SMarina Yatsina case 'n':
68833eb7752SMarina Yatsina case 'E':
68933eb7752SMarina Yatsina case 'F':
690a5c7d706SJohn Thompson break; // Pass them.
6917a51313dSChris Lattner }
6927a51313dSChris Lattner
6937a51313dSChris Lattner Name++;
6947a51313dSChris Lattner }
6957a51313dSChris Lattner
696a0040df3SDavid Majnemer // Early clobber with a read-write constraint which doesn't permit registers
697a0040df3SDavid Majnemer // is invalid.
698a0040df3SDavid Majnemer if (Info.earlyClobber() && Info.isReadWrite() && !Info.allowsRegister())
699a0040df3SDavid Majnemer return false;
700a0040df3SDavid Majnemer
7011e4a886cSBenjamin Kramer // If a constraint allows neither memory nor register operands it contains
7021e4a886cSBenjamin Kramer // only modifiers. Reject it.
7037ee3b9c0SBenjamin Kramer return Info.allowsMemory() || Info.allowsRegister();
7047a51313dSChris Lattner }
7057a51313dSChris Lattner
resolveSymbolicName(const char * & Name,ArrayRef<ConstraintInfo> OutputConstraints,unsigned & Index) const706a79203beSAnders Carlsson bool TargetInfo::resolveSymbolicName(const char *&Name,
70755765ca5SCraig Topper ArrayRef<ConstraintInfo> OutputConstraints,
708d9725f70SChris Lattner unsigned &Index) const {
709a79203beSAnders Carlsson assert(*Name == '[' && "Symbolic name did not start with '['");
710a79203beSAnders Carlsson Name++;
711a79203beSAnders Carlsson const char *Start = Name;
712a79203beSAnders Carlsson while (*Name && *Name != ']')
713a79203beSAnders Carlsson Name++;
714a79203beSAnders Carlsson
715a79203beSAnders Carlsson if (!*Name) {
716a79203beSAnders Carlsson // Missing ']'
717a79203beSAnders Carlsson return false;
718a79203beSAnders Carlsson }
719a79203beSAnders Carlsson
720a79203beSAnders Carlsson std::string SymbolicName(Start, Name - Start);
721a79203beSAnders Carlsson
72255765ca5SCraig Topper for (Index = 0; Index != OutputConstraints.size(); ++Index)
723c16d476bSChris Lattner if (SymbolicName == OutputConstraints[Index].getName())
724a79203beSAnders Carlsson return true;
725a79203beSAnders Carlsson
726a79203beSAnders Carlsson return false;
727a79203beSAnders Carlsson }
728a79203beSAnders Carlsson
validateInputConstraint(MutableArrayRef<ConstraintInfo> OutputConstraints,ConstraintInfo & Info) const72955765ca5SCraig Topper bool TargetInfo::validateInputConstraint(
73055765ca5SCraig Topper MutableArrayRef<ConstraintInfo> OutputConstraints,
731d9725f70SChris Lattner ConstraintInfo &Info) const {
732c3f4c7b1SChris Lattner const char *Name = Info.ConstraintStr.c_str();
733c3f4c7b1SChris Lattner
734d68c7aa7SDuncan P. N. Exon Smith if (!*Name)
735d68c7aa7SDuncan P. N. Exon Smith return false;
736d68c7aa7SDuncan P. N. Exon Smith
7377a51313dSChris Lattner while (*Name) {
7387a51313dSChris Lattner switch (*Name) {
7397a51313dSChris Lattner default:
7407a51313dSChris Lattner // Check if we have a matching constraint
7417a51313dSChris Lattner if (*Name >= '0' && *Name <= '9') {
742b6b5643bSDavid Majnemer const char *DigitStart = Name;
743b6b5643bSDavid Majnemer while (Name[1] >= '0' && Name[1] <= '9')
744b6b5643bSDavid Majnemer Name++;
745b6b5643bSDavid Majnemer const char *DigitEnd = Name;
746b6b5643bSDavid Majnemer unsigned i;
747b6b5643bSDavid Majnemer if (StringRef(DigitStart, DigitEnd - DigitStart + 1)
748b6b5643bSDavid Majnemer .getAsInteger(10, i))
749b6b5643bSDavid Majnemer return false;
7507a51313dSChris Lattner
7517a51313dSChris Lattner // Check if matching constraint is out of bounds.
75255765ca5SCraig Topper if (i >= OutputConstraints.size()) return false;
753570c357dSAnders Carlsson
754da1f5fc8SAnders Carlsson // A number must refer to an output only operand.
755da1f5fc8SAnders Carlsson if (OutputConstraints[i].isReadWrite())
756da1f5fc8SAnders Carlsson return false;
757da1f5fc8SAnders Carlsson
7582d5f8b42SAnders Carlsson // If the constraint is already tied, it must be tied to the
7592d5f8b42SAnders Carlsson // same operand referenced to by the number.
7602d5f8b42SAnders Carlsson if (Info.hasTiedOperand() && Info.getTiedOperand() != i)
7612d5f8b42SAnders Carlsson return false;
7622d5f8b42SAnders Carlsson
763570c357dSAnders Carlsson // The constraint should have the same info as the respective
764570c357dSAnders Carlsson // output constraint.
7654c92b510SChris Lattner Info.setTiedOperand(i, OutputConstraints[i]);
766d9725f70SChris Lattner } else if (!validateAsmConstraint(Name, Info)) {
76781128e04SDaniel Dunbar // FIXME: This error return is in place temporarily so we can
76881128e04SDaniel Dunbar // add more constraints as we hit it. Eventually, an unknown
76981128e04SDaniel Dunbar // constraint should just be treated as 'g'.
77081128e04SDaniel Dunbar return false;
7717a51313dSChris Lattner }
772a79203beSAnders Carlsson break;
773a79203beSAnders Carlsson case '[': {
774a79203beSAnders Carlsson unsigned Index = 0;
77555765ca5SCraig Topper if (!resolveSymbolicName(Name, OutputConstraints, Index))
776a79203beSAnders Carlsson return false;
777a79203beSAnders Carlsson
7782d5f8b42SAnders Carlsson // If the constraint is already tied, it must be tied to the
7792d5f8b42SAnders Carlsson // same operand referenced to by the number.
7802d5f8b42SAnders Carlsson if (Info.hasTiedOperand() && Info.getTiedOperand() != Index)
7812d5f8b42SAnders Carlsson return false;
7822d5f8b42SAnders Carlsson
78355164f90SDavid Majnemer // A number must refer to an output only operand.
78455164f90SDavid Majnemer if (OutputConstraints[Index].isReadWrite())
78555164f90SDavid Majnemer return false;
78655164f90SDavid Majnemer
787854f1108SEli Friedman Info.setTiedOperand(Index, OutputConstraints[Index]);
788a79203beSAnders Carlsson break;
789a79203beSAnders Carlsson }
7907a51313dSChris Lattner case '%': // commutative
7917a51313dSChris Lattner // FIXME: Fail if % is used with the last operand.
7927a51313dSChris Lattner break;
7937a51313dSChris Lattner case 'i': // immediate integer.
794aa77513bSBill Wendling break;
7957a51313dSChris Lattner case 'n': // immediate integer with a known value.
796aa77513bSBill Wendling Info.setRequiresImmediate();
7977a51313dSChris Lattner break;
798dbcc5ca5SChris Lattner case 'I': // Various constant constraints with target-specific meanings.
799dbcc5ca5SChris Lattner case 'J':
800dbcc5ca5SChris Lattner case 'K':
801dbcc5ca5SChris Lattner case 'L':
802dbcc5ca5SChris Lattner case 'M':
803dbcc5ca5SChris Lattner case 'N':
804dbcc5ca5SChris Lattner case 'O':
805dbcc5ca5SChris Lattner case 'P':
806a2823578SSaleem Abdulrasool if (!validateAsmConstraint(Name, Info))
807a2823578SSaleem Abdulrasool return false;
808dbcc5ca5SChris Lattner break;
8097a51313dSChris Lattner case 'r': // general register.
810d9725f70SChris Lattner Info.setAllowsRegister();
8117a51313dSChris Lattner break;
8127a51313dSChris Lattner case 'm': // memory operand.
8138499f47eSDale Johannesen case 'o': // offsettable memory operand.
8148499f47eSDale Johannesen case 'V': // non-offsettable memory operand.
8158499f47eSDale Johannesen case '<': // autodecrement memory operand.
8168499f47eSDale Johannesen case '>': // autoincrement memory operand.
817d9725f70SChris Lattner Info.setAllowsMemory();
8187a51313dSChris Lattner break;
8197a51313dSChris Lattner case 'g': // general register, memory operand or immediate integer.
820e70cde13SAnders Carlsson case 'X': // any operand.
821d9725f70SChris Lattner Info.setAllowsRegister();
822d9725f70SChris Lattner Info.setAllowsMemory();
8237a51313dSChris Lattner break;
824c467aa2fSJohn Thompson case 'E': // immediate floating point.
825c467aa2fSJohn Thompson case 'F': // immediate floating point.
826c467aa2fSJohn Thompson case 'p': // address operand.
827c467aa2fSJohn Thompson break;
828a5c7d706SJohn Thompson case ',': // multiple alternative constraint. Ignore comma.
829a5c7d706SJohn Thompson break;
830c71a566dSDavid Majnemer case '#': // Ignore as constraint.
831c71a566dSDavid Majnemer while (Name[1] && Name[1] != ',')
832c71a566dSDavid Majnemer Name++;
833c71a566dSDavid Majnemer break;
834a5c7d706SJohn Thompson case '?': // Disparage slightly code.
83557540c5bSChris Lattner case '!': // Disparage severely.
8367bcc7ec7SUlrich Weigand case '*': // Ignore for choosing register preferences.
837a5c7d706SJohn Thompson break; // Pass them.
8387a51313dSChris Lattner }
8397a51313dSChris Lattner
8407a51313dSChris Lattner Name++;
8417a51313dSChris Lattner }
8427a51313dSChris Lattner
8437a51313dSChris Lattner return true;
8447a51313dSChris Lattner }
845db01c3adSLeonard Chan
CheckFixedPointBits() const846db01c3adSLeonard Chan void TargetInfo::CheckFixedPointBits() const {
847db01c3adSLeonard Chan // Check that the number of fractional and integral bits (and maybe sign) can
848db01c3adSLeonard Chan // fit into the bits given for a fixed point type.
849db01c3adSLeonard Chan assert(ShortAccumScale + getShortAccumIBits() + 1 <= ShortAccumWidth);
850db01c3adSLeonard Chan assert(AccumScale + getAccumIBits() + 1 <= AccumWidth);
851db01c3adSLeonard Chan assert(LongAccumScale + getLongAccumIBits() + 1 <= LongAccumWidth);
852db01c3adSLeonard Chan assert(getUnsignedShortAccumScale() + getUnsignedShortAccumIBits() <=
853db01c3adSLeonard Chan ShortAccumWidth);
854db01c3adSLeonard Chan assert(getUnsignedAccumScale() + getUnsignedAccumIBits() <= AccumWidth);
855db01c3adSLeonard Chan assert(getUnsignedLongAccumScale() + getUnsignedLongAccumIBits() <=
856db01c3adSLeonard Chan LongAccumWidth);
857db01c3adSLeonard Chan
858db01c3adSLeonard Chan assert(getShortFractScale() + 1 <= ShortFractWidth);
859db01c3adSLeonard Chan assert(getFractScale() + 1 <= FractWidth);
860db01c3adSLeonard Chan assert(getLongFractScale() + 1 <= LongFractWidth);
861db01c3adSLeonard Chan assert(getUnsignedShortFractScale() <= ShortFractWidth);
862db01c3adSLeonard Chan assert(getUnsignedFractScale() <= FractWidth);
863db01c3adSLeonard Chan assert(getUnsignedLongFractScale() <= LongFractWidth);
864db01c3adSLeonard Chan
865db01c3adSLeonard Chan // Each unsigned fract type has either the same number of fractional bits
866db01c3adSLeonard Chan // as, or one more fractional bit than, its corresponding signed fract type.
867db01c3adSLeonard Chan assert(getShortFractScale() == getUnsignedShortFractScale() ||
868db01c3adSLeonard Chan getShortFractScale() == getUnsignedShortFractScale() - 1);
869db01c3adSLeonard Chan assert(getFractScale() == getUnsignedFractScale() ||
870db01c3adSLeonard Chan getFractScale() == getUnsignedFractScale() - 1);
871db01c3adSLeonard Chan assert(getLongFractScale() == getUnsignedLongFractScale() ||
872db01c3adSLeonard Chan getLongFractScale() == getUnsignedLongFractScale() - 1);
873db01c3adSLeonard Chan
874db01c3adSLeonard Chan // When arranged in order of increasing rank (see 6.3.1.3a), the number of
875db01c3adSLeonard Chan // fractional bits is nondecreasing for each of the following sets of
876db01c3adSLeonard Chan // fixed-point types:
877db01c3adSLeonard Chan // - signed fract types
878db01c3adSLeonard Chan // - unsigned fract types
879db01c3adSLeonard Chan // - signed accum types
880db01c3adSLeonard Chan // - unsigned accum types.
881db01c3adSLeonard Chan assert(getLongFractScale() >= getFractScale() &&
882db01c3adSLeonard Chan getFractScale() >= getShortFractScale());
883db01c3adSLeonard Chan assert(getUnsignedLongFractScale() >= getUnsignedFractScale() &&
884db01c3adSLeonard Chan getUnsignedFractScale() >= getUnsignedShortFractScale());
885db01c3adSLeonard Chan assert(LongAccumScale >= AccumScale && AccumScale >= ShortAccumScale);
886db01c3adSLeonard Chan assert(getUnsignedLongAccumScale() >= getUnsignedAccumScale() &&
887db01c3adSLeonard Chan getUnsignedAccumScale() >= getUnsignedShortAccumScale());
888db01c3adSLeonard Chan
889db01c3adSLeonard Chan // When arranged in order of increasing rank (see 6.3.1.3a), the number of
890db01c3adSLeonard Chan // integral bits is nondecreasing for each of the following sets of
891db01c3adSLeonard Chan // fixed-point types:
892db01c3adSLeonard Chan // - signed accum types
893db01c3adSLeonard Chan // - unsigned accum types
894db01c3adSLeonard Chan assert(getLongAccumIBits() >= getAccumIBits() &&
895db01c3adSLeonard Chan getAccumIBits() >= getShortAccumIBits());
896db01c3adSLeonard Chan assert(getUnsignedLongAccumIBits() >= getUnsignedAccumIBits() &&
897db01c3adSLeonard Chan getUnsignedAccumIBits() >= getUnsignedShortAccumIBits());
898db01c3adSLeonard Chan
899db01c3adSLeonard Chan // Each signed accum type has at least as many integral bits as its
900db01c3adSLeonard Chan // corresponding unsigned accum type.
901db01c3adSLeonard Chan assert(getShortAccumIBits() >= getUnsignedShortAccumIBits());
902db01c3adSLeonard Chan assert(getAccumIBits() >= getUnsignedAccumIBits());
903db01c3adSLeonard Chan assert(getLongAccumIBits() >= getUnsignedLongAccumIBits());
904db01c3adSLeonard Chan }
90595f2ca54SYaxun Liu
copyAuxTarget(const TargetInfo * Aux)90695f2ca54SYaxun Liu void TargetInfo::copyAuxTarget(const TargetInfo *Aux) {
90795f2ca54SYaxun Liu auto *Target = static_cast<TransferrableTargetInfo*>(this);
90895f2ca54SYaxun Liu auto *Src = static_cast<const TransferrableTargetInfo*>(Aux);
90995f2ca54SYaxun Liu *Target = *Src;
91095f2ca54SYaxun Liu }
911