1*67e74705SXin Li //===--- TargetInfo.cpp - Information about Target machine ----------------===//
2*67e74705SXin Li //
3*67e74705SXin Li // The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li //
10*67e74705SXin Li // This file implements the TargetInfo and TargetInfoImpl interfaces.
11*67e74705SXin Li //
12*67e74705SXin Li //===----------------------------------------------------------------------===//
13*67e74705SXin Li
14*67e74705SXin Li #include "clang/Basic/TargetInfo.h"
15*67e74705SXin Li #include "clang/Basic/AddressSpaces.h"
16*67e74705SXin Li #include "clang/Basic/CharInfo.h"
17*67e74705SXin Li #include "clang/Basic/LangOptions.h"
18*67e74705SXin Li #include "llvm/ADT/APFloat.h"
19*67e74705SXin Li #include "llvm/ADT/STLExtras.h"
20*67e74705SXin Li #include "llvm/Support/ErrorHandling.h"
21*67e74705SXin Li #include <cstdlib>
22*67e74705SXin Li using namespace clang;
23*67e74705SXin Li
24*67e74705SXin Li static const LangAS::Map DefaultAddrSpaceMap = { 0 };
25*67e74705SXin Li
26*67e74705SXin Li // TargetInfo Constructor.
TargetInfo(const llvm::Triple & T)27*67e74705SXin Li TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) {
28*67e74705SXin Li // Set defaults. Defaults are set for a 32-bit RISC platform, like PPC or
29*67e74705SXin Li // SPARC. These should be overridden by concrete targets as needed.
30*67e74705SXin Li BigEndian = true;
31*67e74705SXin Li TLSSupported = true;
32*67e74705SXin Li NoAsmVariants = false;
33*67e74705SXin Li HasFloat128 = false;
34*67e74705SXin Li PointerWidth = PointerAlign = 32;
35*67e74705SXin Li BoolWidth = BoolAlign = 8;
36*67e74705SXin Li IntWidth = IntAlign = 32;
37*67e74705SXin Li LongWidth = LongAlign = 32;
38*67e74705SXin Li LongLongWidth = LongLongAlign = 64;
39*67e74705SXin Li SuitableAlign = 64;
40*67e74705SXin Li DefaultAlignForAttributeAligned = 128;
41*67e74705SXin Li MinGlobalAlign = 0;
42*67e74705SXin Li HalfWidth = 16;
43*67e74705SXin Li HalfAlign = 16;
44*67e74705SXin Li FloatWidth = 32;
45*67e74705SXin Li FloatAlign = 32;
46*67e74705SXin Li DoubleWidth = 64;
47*67e74705SXin Li DoubleAlign = 64;
48*67e74705SXin Li LongDoubleWidth = 64;
49*67e74705SXin Li LongDoubleAlign = 64;
50*67e74705SXin Li Float128Align = 128;
51*67e74705SXin Li LargeArrayMinWidth = 0;
52*67e74705SXin Li LargeArrayAlign = 0;
53*67e74705SXin Li MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 0;
54*67e74705SXin Li MaxVectorAlign = 0;
55*67e74705SXin Li MaxTLSAlign = 0;
56*67e74705SXin Li SimdDefaultAlign = 0;
57*67e74705SXin Li SizeType = UnsignedLong;
58*67e74705SXin Li PtrDiffType = SignedLong;
59*67e74705SXin Li IntMaxType = SignedLongLong;
60*67e74705SXin Li IntPtrType = SignedLong;
61*67e74705SXin Li WCharType = SignedInt;
62*67e74705SXin Li WIntType = SignedInt;
63*67e74705SXin Li Char16Type = UnsignedShort;
64*67e74705SXin Li Char32Type = UnsignedInt;
65*67e74705SXin Li Int64Type = SignedLongLong;
66*67e74705SXin Li SigAtomicType = SignedInt;
67*67e74705SXin Li ProcessIDType = SignedInt;
68*67e74705SXin Li UseSignedCharForObjCBool = true;
69*67e74705SXin Li UseBitFieldTypeAlignment = true;
70*67e74705SXin Li UseZeroLengthBitfieldAlignment = false;
71*67e74705SXin Li UseExplicitBitFieldAlignment = true;
72*67e74705SXin Li ZeroLengthBitfieldBoundary = 0;
73*67e74705SXin Li HalfFormat = &llvm::APFloat::IEEEhalf;
74*67e74705SXin Li FloatFormat = &llvm::APFloat::IEEEsingle;
75*67e74705SXin Li DoubleFormat = &llvm::APFloat::IEEEdouble;
76*67e74705SXin Li LongDoubleFormat = &llvm::APFloat::IEEEdouble;
77*67e74705SXin Li Float128Format = &llvm::APFloat::IEEEquad;
78*67e74705SXin Li MCountName = "mcount";
79*67e74705SXin Li RegParmMax = 0;
80*67e74705SXin Li SSERegParmMax = 0;
81*67e74705SXin Li HasAlignMac68kSupport = false;
82*67e74705SXin Li HasBuiltinMSVaList = false;
83*67e74705SXin Li IsRenderScriptTarget = false;
84*67e74705SXin Li
85*67e74705SXin Li // Default to no types using fpret.
86*67e74705SXin Li RealTypeUsesObjCFPRet = 0;
87*67e74705SXin Li
88*67e74705SXin Li // Default to not using fp2ret for __Complex long double
89*67e74705SXin Li ComplexLongDoubleUsesFP2Ret = false;
90*67e74705SXin Li
91*67e74705SXin Li // Set the C++ ABI based on the triple.
92*67e74705SXin Li TheCXXABI.set(Triple.isKnownWindowsMSVCEnvironment()
93*67e74705SXin Li ? TargetCXXABI::Microsoft
94*67e74705SXin Li : TargetCXXABI::GenericItanium);
95*67e74705SXin Li
96*67e74705SXin Li // Default to an empty address space map.
97*67e74705SXin Li AddrSpaceMap = &DefaultAddrSpaceMap;
98*67e74705SXin Li UseAddrSpaceMapMangling = false;
99*67e74705SXin Li
100*67e74705SXin Li // Default to an unknown platform name.
101*67e74705SXin Li PlatformName = "unknown";
102*67e74705SXin Li PlatformMinVersion = VersionTuple();
103*67e74705SXin Li }
104*67e74705SXin Li
105*67e74705SXin Li // Out of line virtual dtor for TargetInfo.
~TargetInfo()106*67e74705SXin Li TargetInfo::~TargetInfo() {}
107*67e74705SXin Li
108*67e74705SXin Li /// getTypeName - Return the user string for the specified integer type enum.
109*67e74705SXin Li /// For example, SignedShort -> "short".
getTypeName(IntType T)110*67e74705SXin Li const char *TargetInfo::getTypeName(IntType T) {
111*67e74705SXin Li switch (T) {
112*67e74705SXin Li default: llvm_unreachable("not an integer!");
113*67e74705SXin Li case SignedChar: return "signed char";
114*67e74705SXin Li case UnsignedChar: return "unsigned char";
115*67e74705SXin Li case SignedShort: return "short";
116*67e74705SXin Li case UnsignedShort: return "unsigned short";
117*67e74705SXin Li case SignedInt: return "int";
118*67e74705SXin Li case UnsignedInt: return "unsigned int";
119*67e74705SXin Li case SignedLong: return "long int";
120*67e74705SXin Li case UnsignedLong: return "long unsigned int";
121*67e74705SXin Li case SignedLongLong: return "long long int";
122*67e74705SXin Li case UnsignedLongLong: return "long long unsigned int";
123*67e74705SXin Li }
124*67e74705SXin Li }
125*67e74705SXin Li
126*67e74705SXin Li /// getTypeConstantSuffix - Return the constant suffix for the specified
127*67e74705SXin Li /// integer type enum. For example, SignedLong -> "L".
getTypeConstantSuffix(IntType T) const128*67e74705SXin Li const char *TargetInfo::getTypeConstantSuffix(IntType T) const {
129*67e74705SXin Li switch (T) {
130*67e74705SXin Li default: llvm_unreachable("not an integer!");
131*67e74705SXin Li case SignedChar:
132*67e74705SXin Li case SignedShort:
133*67e74705SXin Li case SignedInt: return "";
134*67e74705SXin Li case SignedLong: return "L";
135*67e74705SXin Li case SignedLongLong: return "LL";
136*67e74705SXin Li case UnsignedChar:
137*67e74705SXin Li if (getCharWidth() < getIntWidth())
138*67e74705SXin Li return "";
139*67e74705SXin Li case UnsignedShort:
140*67e74705SXin Li if (getShortWidth() < getIntWidth())
141*67e74705SXin Li return "";
142*67e74705SXin Li case UnsignedInt: return "U";
143*67e74705SXin Li case UnsignedLong: return "UL";
144*67e74705SXin Li case UnsignedLongLong: return "ULL";
145*67e74705SXin Li }
146*67e74705SXin Li }
147*67e74705SXin Li
148*67e74705SXin Li /// getTypeFormatModifier - Return the printf format modifier for the
149*67e74705SXin Li /// specified integer type enum. For example, SignedLong -> "l".
150*67e74705SXin Li
getTypeFormatModifier(IntType T)151*67e74705SXin Li const char *TargetInfo::getTypeFormatModifier(IntType T) {
152*67e74705SXin Li switch (T) {
153*67e74705SXin Li default: llvm_unreachable("not an integer!");
154*67e74705SXin Li case SignedChar:
155*67e74705SXin Li case UnsignedChar: return "hh";
156*67e74705SXin Li case SignedShort:
157*67e74705SXin Li case UnsignedShort: return "h";
158*67e74705SXin Li case SignedInt:
159*67e74705SXin Li case UnsignedInt: return "";
160*67e74705SXin Li case SignedLong:
161*67e74705SXin Li case UnsignedLong: return "l";
162*67e74705SXin Li case SignedLongLong:
163*67e74705SXin Li case UnsignedLongLong: return "ll";
164*67e74705SXin Li }
165*67e74705SXin Li }
166*67e74705SXin Li
167*67e74705SXin Li /// getTypeWidth - Return the width (in bits) of the specified integer type
168*67e74705SXin Li /// enum. For example, SignedInt -> getIntWidth().
getTypeWidth(IntType T) const169*67e74705SXin Li unsigned TargetInfo::getTypeWidth(IntType T) const {
170*67e74705SXin Li switch (T) {
171*67e74705SXin Li default: llvm_unreachable("not an integer!");
172*67e74705SXin Li case SignedChar:
173*67e74705SXin Li case UnsignedChar: return getCharWidth();
174*67e74705SXin Li case SignedShort:
175*67e74705SXin Li case UnsignedShort: return getShortWidth();
176*67e74705SXin Li case SignedInt:
177*67e74705SXin Li case UnsignedInt: return getIntWidth();
178*67e74705SXin Li case SignedLong:
179*67e74705SXin Li case UnsignedLong: return getLongWidth();
180*67e74705SXin Li case SignedLongLong:
181*67e74705SXin Li case UnsignedLongLong: return getLongLongWidth();
182*67e74705SXin Li };
183*67e74705SXin Li }
184*67e74705SXin Li
getIntTypeByWidth(unsigned BitWidth,bool IsSigned) const185*67e74705SXin Li TargetInfo::IntType TargetInfo::getIntTypeByWidth(
186*67e74705SXin Li unsigned BitWidth, bool IsSigned) const {
187*67e74705SXin Li if (getCharWidth() == BitWidth)
188*67e74705SXin Li return IsSigned ? SignedChar : UnsignedChar;
189*67e74705SXin Li if (getShortWidth() == BitWidth)
190*67e74705SXin Li return IsSigned ? SignedShort : UnsignedShort;
191*67e74705SXin Li if (getIntWidth() == BitWidth)
192*67e74705SXin Li return IsSigned ? SignedInt : UnsignedInt;
193*67e74705SXin Li if (getLongWidth() == BitWidth)
194*67e74705SXin Li return IsSigned ? SignedLong : UnsignedLong;
195*67e74705SXin Li if (getLongLongWidth() == BitWidth)
196*67e74705SXin Li return IsSigned ? SignedLongLong : UnsignedLongLong;
197*67e74705SXin Li return NoInt;
198*67e74705SXin Li }
199*67e74705SXin Li
getLeastIntTypeByWidth(unsigned BitWidth,bool IsSigned) const200*67e74705SXin Li TargetInfo::IntType TargetInfo::getLeastIntTypeByWidth(unsigned BitWidth,
201*67e74705SXin Li bool IsSigned) const {
202*67e74705SXin Li if (getCharWidth() >= BitWidth)
203*67e74705SXin Li return IsSigned ? SignedChar : UnsignedChar;
204*67e74705SXin Li if (getShortWidth() >= BitWidth)
205*67e74705SXin Li return IsSigned ? SignedShort : UnsignedShort;
206*67e74705SXin Li if (getIntWidth() >= BitWidth)
207*67e74705SXin Li return IsSigned ? SignedInt : UnsignedInt;
208*67e74705SXin Li if (getLongWidth() >= BitWidth)
209*67e74705SXin Li return IsSigned ? SignedLong : UnsignedLong;
210*67e74705SXin Li if (getLongLongWidth() >= BitWidth)
211*67e74705SXin Li return IsSigned ? SignedLongLong : UnsignedLongLong;
212*67e74705SXin Li return NoInt;
213*67e74705SXin Li }
214*67e74705SXin Li
getRealTypeByWidth(unsigned BitWidth) const215*67e74705SXin Li TargetInfo::RealType TargetInfo::getRealTypeByWidth(unsigned BitWidth) const {
216*67e74705SXin Li if (getFloatWidth() == BitWidth)
217*67e74705SXin Li return Float;
218*67e74705SXin Li if (getDoubleWidth() == BitWidth)
219*67e74705SXin Li return Double;
220*67e74705SXin Li
221*67e74705SXin Li switch (BitWidth) {
222*67e74705SXin Li case 96:
223*67e74705SXin Li if (&getLongDoubleFormat() == &llvm::APFloat::x87DoubleExtended)
224*67e74705SXin Li return LongDouble;
225*67e74705SXin Li break;
226*67e74705SXin Li case 128:
227*67e74705SXin Li if (&getLongDoubleFormat() == &llvm::APFloat::PPCDoubleDouble ||
228*67e74705SXin Li &getLongDoubleFormat() == &llvm::APFloat::IEEEquad)
229*67e74705SXin Li return LongDouble;
230*67e74705SXin Li if (hasFloat128Type())
231*67e74705SXin Li return Float128;
232*67e74705SXin Li break;
233*67e74705SXin Li }
234*67e74705SXin Li
235*67e74705SXin Li return NoFloat;
236*67e74705SXin Li }
237*67e74705SXin Li
238*67e74705SXin Li /// getTypeAlign - Return the alignment (in bits) of the specified integer type
239*67e74705SXin Li /// enum. For example, SignedInt -> getIntAlign().
getTypeAlign(IntType T) const240*67e74705SXin Li unsigned TargetInfo::getTypeAlign(IntType T) const {
241*67e74705SXin Li switch (T) {
242*67e74705SXin Li default: llvm_unreachable("not an integer!");
243*67e74705SXin Li case SignedChar:
244*67e74705SXin Li case UnsignedChar: return getCharAlign();
245*67e74705SXin Li case SignedShort:
246*67e74705SXin Li case UnsignedShort: return getShortAlign();
247*67e74705SXin Li case SignedInt:
248*67e74705SXin Li case UnsignedInt: return getIntAlign();
249*67e74705SXin Li case SignedLong:
250*67e74705SXin Li case UnsignedLong: return getLongAlign();
251*67e74705SXin Li case SignedLongLong:
252*67e74705SXin Li case UnsignedLongLong: return getLongLongAlign();
253*67e74705SXin Li };
254*67e74705SXin Li }
255*67e74705SXin Li
256*67e74705SXin Li /// isTypeSigned - Return whether an integer types is signed. Returns true if
257*67e74705SXin Li /// the type is signed; false otherwise.
isTypeSigned(IntType T)258*67e74705SXin Li bool TargetInfo::isTypeSigned(IntType T) {
259*67e74705SXin Li switch (T) {
260*67e74705SXin Li default: llvm_unreachable("not an integer!");
261*67e74705SXin Li case SignedChar:
262*67e74705SXin Li case SignedShort:
263*67e74705SXin Li case SignedInt:
264*67e74705SXin Li case SignedLong:
265*67e74705SXin Li case SignedLongLong:
266*67e74705SXin Li return true;
267*67e74705SXin Li case UnsignedChar:
268*67e74705SXin Li case UnsignedShort:
269*67e74705SXin Li case UnsignedInt:
270*67e74705SXin Li case UnsignedLong:
271*67e74705SXin Li case UnsignedLongLong:
272*67e74705SXin Li return false;
273*67e74705SXin Li };
274*67e74705SXin Li }
275*67e74705SXin Li
276*67e74705SXin Li /// adjust - Set forced language options.
277*67e74705SXin Li /// Apply changes to the target information with respect to certain
278*67e74705SXin Li /// language options which change the target configuration.
adjust(const LangOptions & Opts)279*67e74705SXin Li void TargetInfo::adjust(const LangOptions &Opts) {
280*67e74705SXin Li if (Opts.NoBitFieldTypeAlign)
281*67e74705SXin Li UseBitFieldTypeAlignment = false;
282*67e74705SXin Li if (Opts.ShortWChar)
283*67e74705SXin Li WCharType = UnsignedShort;
284*67e74705SXin Li if (Opts.AlignDouble) {
285*67e74705SXin Li DoubleAlign = LongLongAlign = 64;
286*67e74705SXin Li LongDoubleAlign = 64;
287*67e74705SXin Li }
288*67e74705SXin Li
289*67e74705SXin Li if (Opts.OpenCL) {
290*67e74705SXin Li // OpenCL C requires specific widths for types, irrespective of
291*67e74705SXin Li // what these normally are for the target.
292*67e74705SXin Li // We also define long long and long double here, although the
293*67e74705SXin Li // OpenCL standard only mentions these as "reserved".
294*67e74705SXin Li IntWidth = IntAlign = 32;
295*67e74705SXin Li LongWidth = LongAlign = 64;
296*67e74705SXin Li LongLongWidth = LongLongAlign = 128;
297*67e74705SXin Li HalfWidth = HalfAlign = 16;
298*67e74705SXin Li FloatWidth = FloatAlign = 32;
299*67e74705SXin Li
300*67e74705SXin Li // Embedded 32-bit targets (OpenCL EP) might have double C type
301*67e74705SXin Li // defined as float. Let's not override this as it might lead
302*67e74705SXin Li // to generating illegal code that uses 64bit doubles.
303*67e74705SXin Li if (DoubleWidth != FloatWidth) {
304*67e74705SXin Li DoubleWidth = DoubleAlign = 64;
305*67e74705SXin Li DoubleFormat = &llvm::APFloat::IEEEdouble;
306*67e74705SXin Li }
307*67e74705SXin Li LongDoubleWidth = LongDoubleAlign = 128;
308*67e74705SXin Li
309*67e74705SXin Li assert(PointerWidth == 32 || PointerWidth == 64);
310*67e74705SXin Li bool Is32BitArch = PointerWidth == 32;
311*67e74705SXin Li SizeType = Is32BitArch ? UnsignedInt : UnsignedLong;
312*67e74705SXin Li PtrDiffType = Is32BitArch ? SignedInt : SignedLong;
313*67e74705SXin Li IntPtrType = Is32BitArch ? SignedInt : SignedLong;
314*67e74705SXin Li
315*67e74705SXin Li IntMaxType = SignedLongLong;
316*67e74705SXin Li Int64Type = SignedLong;
317*67e74705SXin Li
318*67e74705SXin Li HalfFormat = &llvm::APFloat::IEEEhalf;
319*67e74705SXin Li FloatFormat = &llvm::APFloat::IEEEsingle;
320*67e74705SXin Li LongDoubleFormat = &llvm::APFloat::IEEEquad;
321*67e74705SXin Li }
322*67e74705SXin Li }
323*67e74705SXin Li
initFeatureMap(llvm::StringMap<bool> & Features,DiagnosticsEngine & Diags,StringRef CPU,const std::vector<std::string> & FeatureVec) const324*67e74705SXin Li bool TargetInfo::initFeatureMap(
325*67e74705SXin Li llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
326*67e74705SXin Li const std::vector<std::string> &FeatureVec) const {
327*67e74705SXin Li for (const auto &F : FeatureVec) {
328*67e74705SXin Li StringRef Name = F;
329*67e74705SXin Li // Apply the feature via the target.
330*67e74705SXin Li bool Enabled = Name[0] == '+';
331*67e74705SXin Li setFeatureEnabled(Features, Name.substr(1), Enabled);
332*67e74705SXin Li }
333*67e74705SXin Li return true;
334*67e74705SXin Li }
335*67e74705SXin Li
336*67e74705SXin Li //===----------------------------------------------------------------------===//
337*67e74705SXin Li
338*67e74705SXin Li
removeGCCRegisterPrefix(StringRef Name)339*67e74705SXin Li static StringRef removeGCCRegisterPrefix(StringRef Name) {
340*67e74705SXin Li if (Name[0] == '%' || Name[0] == '#')
341*67e74705SXin Li Name = Name.substr(1);
342*67e74705SXin Li
343*67e74705SXin Li return Name;
344*67e74705SXin Li }
345*67e74705SXin Li
346*67e74705SXin Li /// isValidClobber - Returns whether the passed in string is
347*67e74705SXin Li /// a valid clobber in an inline asm statement. This is used by
348*67e74705SXin Li /// Sema.
isValidClobber(StringRef Name) const349*67e74705SXin Li bool TargetInfo::isValidClobber(StringRef Name) const {
350*67e74705SXin Li return (isValidGCCRegisterName(Name) ||
351*67e74705SXin Li Name == "memory" || Name == "cc");
352*67e74705SXin Li }
353*67e74705SXin Li
354*67e74705SXin Li /// isValidGCCRegisterName - Returns whether the passed in string
355*67e74705SXin Li /// is a valid register name according to GCC. This is used by Sema for
356*67e74705SXin Li /// inline asm statements.
isValidGCCRegisterName(StringRef Name) const357*67e74705SXin Li bool TargetInfo::isValidGCCRegisterName(StringRef Name) const {
358*67e74705SXin Li if (Name.empty())
359*67e74705SXin Li return false;
360*67e74705SXin Li
361*67e74705SXin Li // Get rid of any register prefix.
362*67e74705SXin Li Name = removeGCCRegisterPrefix(Name);
363*67e74705SXin Li if (Name.empty())
364*67e74705SXin Li return false;
365*67e74705SXin Li
366*67e74705SXin Li ArrayRef<const char *> Names = getGCCRegNames();
367*67e74705SXin Li
368*67e74705SXin Li // If we have a number it maps to an entry in the register name array.
369*67e74705SXin Li if (isDigit(Name[0])) {
370*67e74705SXin Li unsigned n;
371*67e74705SXin Li if (!Name.getAsInteger(0, n))
372*67e74705SXin Li return n < Names.size();
373*67e74705SXin Li }
374*67e74705SXin Li
375*67e74705SXin Li // Check register names.
376*67e74705SXin Li if (std::find(Names.begin(), Names.end(), Name) != Names.end())
377*67e74705SXin Li return true;
378*67e74705SXin Li
379*67e74705SXin Li // Check any additional names that we have.
380*67e74705SXin Li for (const AddlRegName &ARN : getGCCAddlRegNames())
381*67e74705SXin Li for (const char *AN : ARN.Names) {
382*67e74705SXin Li if (!AN)
383*67e74705SXin Li break;
384*67e74705SXin Li // Make sure the register that the additional name is for is within
385*67e74705SXin Li // the bounds of the register names from above.
386*67e74705SXin Li if (AN == Name && ARN.RegNum < Names.size())
387*67e74705SXin Li return true;
388*67e74705SXin Li }
389*67e74705SXin Li
390*67e74705SXin Li // Now check aliases.
391*67e74705SXin Li for (const GCCRegAlias &GRA : getGCCRegAliases())
392*67e74705SXin Li for (const char *A : GRA.Aliases) {
393*67e74705SXin Li if (!A)
394*67e74705SXin Li break;
395*67e74705SXin Li if (A == Name)
396*67e74705SXin Li return true;
397*67e74705SXin Li }
398*67e74705SXin Li
399*67e74705SXin Li return false;
400*67e74705SXin Li }
401*67e74705SXin Li
402*67e74705SXin Li StringRef
getNormalizedGCCRegisterName(StringRef Name) const403*67e74705SXin Li TargetInfo::getNormalizedGCCRegisterName(StringRef Name) const {
404*67e74705SXin Li assert(isValidGCCRegisterName(Name) && "Invalid register passed in");
405*67e74705SXin Li
406*67e74705SXin Li // Get rid of any register prefix.
407*67e74705SXin Li Name = removeGCCRegisterPrefix(Name);
408*67e74705SXin Li
409*67e74705SXin Li ArrayRef<const char *> Names = getGCCRegNames();
410*67e74705SXin Li
411*67e74705SXin Li // First, check if we have a number.
412*67e74705SXin Li if (isDigit(Name[0])) {
413*67e74705SXin Li unsigned n;
414*67e74705SXin Li if (!Name.getAsInteger(0, n)) {
415*67e74705SXin Li assert(n < Names.size() && "Out of bounds register number!");
416*67e74705SXin Li return Names[n];
417*67e74705SXin Li }
418*67e74705SXin Li }
419*67e74705SXin Li
420*67e74705SXin Li // Check any additional names that we have.
421*67e74705SXin Li for (const AddlRegName &ARN : getGCCAddlRegNames())
422*67e74705SXin Li for (const char *AN : ARN.Names) {
423*67e74705SXin Li if (!AN)
424*67e74705SXin Li break;
425*67e74705SXin Li // Make sure the register that the additional name is for is within
426*67e74705SXin Li // the bounds of the register names from above.
427*67e74705SXin Li if (AN == Name && ARN.RegNum < Names.size())
428*67e74705SXin Li return Name;
429*67e74705SXin Li }
430*67e74705SXin Li
431*67e74705SXin Li // Now check aliases.
432*67e74705SXin Li for (const GCCRegAlias &RA : getGCCRegAliases())
433*67e74705SXin Li for (const char *A : RA.Aliases) {
434*67e74705SXin Li if (!A)
435*67e74705SXin Li break;
436*67e74705SXin Li if (A == Name)
437*67e74705SXin Li return RA.Register;
438*67e74705SXin Li }
439*67e74705SXin Li
440*67e74705SXin Li return Name;
441*67e74705SXin Li }
442*67e74705SXin Li
validateOutputConstraint(ConstraintInfo & Info) const443*67e74705SXin Li bool TargetInfo::validateOutputConstraint(ConstraintInfo &Info) const {
444*67e74705SXin Li const char *Name = Info.getConstraintStr().c_str();
445*67e74705SXin Li // An output constraint must start with '=' or '+'
446*67e74705SXin Li if (*Name != '=' && *Name != '+')
447*67e74705SXin Li return false;
448*67e74705SXin Li
449*67e74705SXin Li if (*Name == '+')
450*67e74705SXin Li Info.setIsReadWrite();
451*67e74705SXin Li
452*67e74705SXin Li Name++;
453*67e74705SXin Li while (*Name) {
454*67e74705SXin Li switch (*Name) {
455*67e74705SXin Li default:
456*67e74705SXin Li if (!validateAsmConstraint(Name, Info)) {
457*67e74705SXin Li // FIXME: We temporarily return false
458*67e74705SXin Li // so we can add more constraints as we hit it.
459*67e74705SXin Li // Eventually, an unknown constraint should just be treated as 'g'.
460*67e74705SXin Li return false;
461*67e74705SXin Li }
462*67e74705SXin Li break;
463*67e74705SXin Li case '&': // early clobber.
464*67e74705SXin Li Info.setEarlyClobber();
465*67e74705SXin Li break;
466*67e74705SXin Li case '%': // commutative.
467*67e74705SXin Li // FIXME: Check that there is a another register after this one.
468*67e74705SXin Li break;
469*67e74705SXin Li case 'r': // general register.
470*67e74705SXin Li Info.setAllowsRegister();
471*67e74705SXin Li break;
472*67e74705SXin Li case 'm': // memory operand.
473*67e74705SXin Li case 'o': // offsetable memory operand.
474*67e74705SXin Li case 'V': // non-offsetable memory operand.
475*67e74705SXin Li case '<': // autodecrement memory operand.
476*67e74705SXin Li case '>': // autoincrement memory operand.
477*67e74705SXin Li Info.setAllowsMemory();
478*67e74705SXin Li break;
479*67e74705SXin Li case 'g': // general register, memory operand or immediate integer.
480*67e74705SXin Li case 'X': // any operand.
481*67e74705SXin Li Info.setAllowsRegister();
482*67e74705SXin Li Info.setAllowsMemory();
483*67e74705SXin Li break;
484*67e74705SXin Li case ',': // multiple alternative constraint. Pass it.
485*67e74705SXin Li // Handle additional optional '=' or '+' modifiers.
486*67e74705SXin Li if (Name[1] == '=' || Name[1] == '+')
487*67e74705SXin Li Name++;
488*67e74705SXin Li break;
489*67e74705SXin Li case '#': // Ignore as constraint.
490*67e74705SXin Li while (Name[1] && Name[1] != ',')
491*67e74705SXin Li Name++;
492*67e74705SXin Li break;
493*67e74705SXin Li case '?': // Disparage slightly code.
494*67e74705SXin Li case '!': // Disparage severely.
495*67e74705SXin Li case '*': // Ignore for choosing register preferences.
496*67e74705SXin Li break; // Pass them.
497*67e74705SXin Li }
498*67e74705SXin Li
499*67e74705SXin Li Name++;
500*67e74705SXin Li }
501*67e74705SXin Li
502*67e74705SXin Li // Early clobber with a read-write constraint which doesn't permit registers
503*67e74705SXin Li // is invalid.
504*67e74705SXin Li if (Info.earlyClobber() && Info.isReadWrite() && !Info.allowsRegister())
505*67e74705SXin Li return false;
506*67e74705SXin Li
507*67e74705SXin Li // If a constraint allows neither memory nor register operands it contains
508*67e74705SXin Li // only modifiers. Reject it.
509*67e74705SXin Li return Info.allowsMemory() || Info.allowsRegister();
510*67e74705SXin Li }
511*67e74705SXin Li
resolveSymbolicName(const char * & Name,ArrayRef<ConstraintInfo> OutputConstraints,unsigned & Index) const512*67e74705SXin Li bool TargetInfo::resolveSymbolicName(const char *&Name,
513*67e74705SXin Li ArrayRef<ConstraintInfo> OutputConstraints,
514*67e74705SXin Li unsigned &Index) const {
515*67e74705SXin Li assert(*Name == '[' && "Symbolic name did not start with '['");
516*67e74705SXin Li Name++;
517*67e74705SXin Li const char *Start = Name;
518*67e74705SXin Li while (*Name && *Name != ']')
519*67e74705SXin Li Name++;
520*67e74705SXin Li
521*67e74705SXin Li if (!*Name) {
522*67e74705SXin Li // Missing ']'
523*67e74705SXin Li return false;
524*67e74705SXin Li }
525*67e74705SXin Li
526*67e74705SXin Li std::string SymbolicName(Start, Name - Start);
527*67e74705SXin Li
528*67e74705SXin Li for (Index = 0; Index != OutputConstraints.size(); ++Index)
529*67e74705SXin Li if (SymbolicName == OutputConstraints[Index].getName())
530*67e74705SXin Li return true;
531*67e74705SXin Li
532*67e74705SXin Li return false;
533*67e74705SXin Li }
534*67e74705SXin Li
validateInputConstraint(MutableArrayRef<ConstraintInfo> OutputConstraints,ConstraintInfo & Info) const535*67e74705SXin Li bool TargetInfo::validateInputConstraint(
536*67e74705SXin Li MutableArrayRef<ConstraintInfo> OutputConstraints,
537*67e74705SXin Li ConstraintInfo &Info) const {
538*67e74705SXin Li const char *Name = Info.ConstraintStr.c_str();
539*67e74705SXin Li
540*67e74705SXin Li if (!*Name)
541*67e74705SXin Li return false;
542*67e74705SXin Li
543*67e74705SXin Li while (*Name) {
544*67e74705SXin Li switch (*Name) {
545*67e74705SXin Li default:
546*67e74705SXin Li // Check if we have a matching constraint
547*67e74705SXin Li if (*Name >= '0' && *Name <= '9') {
548*67e74705SXin Li const char *DigitStart = Name;
549*67e74705SXin Li while (Name[1] >= '0' && Name[1] <= '9')
550*67e74705SXin Li Name++;
551*67e74705SXin Li const char *DigitEnd = Name;
552*67e74705SXin Li unsigned i;
553*67e74705SXin Li if (StringRef(DigitStart, DigitEnd - DigitStart + 1)
554*67e74705SXin Li .getAsInteger(10, i))
555*67e74705SXin Li return false;
556*67e74705SXin Li
557*67e74705SXin Li // Check if matching constraint is out of bounds.
558*67e74705SXin Li if (i >= OutputConstraints.size()) return false;
559*67e74705SXin Li
560*67e74705SXin Li // A number must refer to an output only operand.
561*67e74705SXin Li if (OutputConstraints[i].isReadWrite())
562*67e74705SXin Li return false;
563*67e74705SXin Li
564*67e74705SXin Li // If the constraint is already tied, it must be tied to the
565*67e74705SXin Li // same operand referenced to by the number.
566*67e74705SXin Li if (Info.hasTiedOperand() && Info.getTiedOperand() != i)
567*67e74705SXin Li return false;
568*67e74705SXin Li
569*67e74705SXin Li // The constraint should have the same info as the respective
570*67e74705SXin Li // output constraint.
571*67e74705SXin Li Info.setTiedOperand(i, OutputConstraints[i]);
572*67e74705SXin Li } else if (!validateAsmConstraint(Name, Info)) {
573*67e74705SXin Li // FIXME: This error return is in place temporarily so we can
574*67e74705SXin Li // add more constraints as we hit it. Eventually, an unknown
575*67e74705SXin Li // constraint should just be treated as 'g'.
576*67e74705SXin Li return false;
577*67e74705SXin Li }
578*67e74705SXin Li break;
579*67e74705SXin Li case '[': {
580*67e74705SXin Li unsigned Index = 0;
581*67e74705SXin Li if (!resolveSymbolicName(Name, OutputConstraints, Index))
582*67e74705SXin Li return false;
583*67e74705SXin Li
584*67e74705SXin Li // If the constraint is already tied, it must be tied to the
585*67e74705SXin Li // same operand referenced to by the number.
586*67e74705SXin Li if (Info.hasTiedOperand() && Info.getTiedOperand() != Index)
587*67e74705SXin Li return false;
588*67e74705SXin Li
589*67e74705SXin Li // A number must refer to an output only operand.
590*67e74705SXin Li if (OutputConstraints[Index].isReadWrite())
591*67e74705SXin Li return false;
592*67e74705SXin Li
593*67e74705SXin Li Info.setTiedOperand(Index, OutputConstraints[Index]);
594*67e74705SXin Li break;
595*67e74705SXin Li }
596*67e74705SXin Li case '%': // commutative
597*67e74705SXin Li // FIXME: Fail if % is used with the last operand.
598*67e74705SXin Li break;
599*67e74705SXin Li case 'i': // immediate integer.
600*67e74705SXin Li case 'n': // immediate integer with a known value.
601*67e74705SXin Li break;
602*67e74705SXin Li case 'I': // Various constant constraints with target-specific meanings.
603*67e74705SXin Li case 'J':
604*67e74705SXin Li case 'K':
605*67e74705SXin Li case 'L':
606*67e74705SXin Li case 'M':
607*67e74705SXin Li case 'N':
608*67e74705SXin Li case 'O':
609*67e74705SXin Li case 'P':
610*67e74705SXin Li if (!validateAsmConstraint(Name, Info))
611*67e74705SXin Li return false;
612*67e74705SXin Li break;
613*67e74705SXin Li case 'r': // general register.
614*67e74705SXin Li Info.setAllowsRegister();
615*67e74705SXin Li break;
616*67e74705SXin Li case 'm': // memory operand.
617*67e74705SXin Li case 'o': // offsettable memory operand.
618*67e74705SXin Li case 'V': // non-offsettable memory operand.
619*67e74705SXin Li case '<': // autodecrement memory operand.
620*67e74705SXin Li case '>': // autoincrement memory operand.
621*67e74705SXin Li Info.setAllowsMemory();
622*67e74705SXin Li break;
623*67e74705SXin Li case 'g': // general register, memory operand or immediate integer.
624*67e74705SXin Li case 'X': // any operand.
625*67e74705SXin Li Info.setAllowsRegister();
626*67e74705SXin Li Info.setAllowsMemory();
627*67e74705SXin Li break;
628*67e74705SXin Li case 'E': // immediate floating point.
629*67e74705SXin Li case 'F': // immediate floating point.
630*67e74705SXin Li case 'p': // address operand.
631*67e74705SXin Li break;
632*67e74705SXin Li case ',': // multiple alternative constraint. Ignore comma.
633*67e74705SXin Li break;
634*67e74705SXin Li case '#': // Ignore as constraint.
635*67e74705SXin Li while (Name[1] && Name[1] != ',')
636*67e74705SXin Li Name++;
637*67e74705SXin Li break;
638*67e74705SXin Li case '?': // Disparage slightly code.
639*67e74705SXin Li case '!': // Disparage severely.
640*67e74705SXin Li case '*': // Ignore for choosing register preferences.
641*67e74705SXin Li break; // Pass them.
642*67e74705SXin Li }
643*67e74705SXin Li
644*67e74705SXin Li Name++;
645*67e74705SXin Li }
646*67e74705SXin Li
647*67e74705SXin Li return true;
648*67e74705SXin Li }
649