xref: /aosp_15_r20/external/clang/lib/Basic/TargetInfo.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
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