1193326Sed//===--- TargetInfo.cpp - Information about Target machine ----------------===//
2193326Sed//
3193326Sed//                     The LLVM Compiler Infrastructure
4193326Sed//
5193326Sed// This file is distributed under the University of Illinois Open Source
6193326Sed// License. See LICENSE.TXT for details.
7193326Sed//
8193326Sed//===----------------------------------------------------------------------===//
9193326Sed//
10193326Sed//  This file implements the TargetInfo and TargetInfoImpl interfaces.
11193326Sed//
12193326Sed//===----------------------------------------------------------------------===//
13193326Sed
14249423Sdim#include "clang/Basic/TargetInfo.h"
15221345Sdim#include "clang/Basic/AddressSpaces.h"
16249423Sdim#include "clang/Basic/CharInfo.h"
17199482Srdivacky#include "clang/Basic/LangOptions.h"
18193326Sed#include "llvm/ADT/APFloat.h"
19193326Sed#include "llvm/ADT/STLExtras.h"
20226633Sdim#include "llvm/Support/ErrorHandling.h"
21193326Sed#include <cstdlib>
22193326Sedusing namespace clang;
23193326Sed
24221345Sdimstatic const LangAS::Map DefaultAddrSpaceMap = { 0 };
25221345Sdim
26193326Sed// TargetInfo Constructor.
27263508SdimTargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) {
28207619Srdivacky  // Set defaults.  Defaults are set for a 32-bit RISC platform, like PPC or
29207619Srdivacky  // SPARC.  These should be overridden by concrete targets as needed.
30234353Sdim  BigEndian = true;
31193326Sed  TLSSupported = true;
32207619Srdivacky  NoAsmVariants = false;
33193326Sed  PointerWidth = PointerAlign = 32;
34218893Sdim  BoolWidth = BoolAlign = 8;
35193326Sed  IntWidth = IntAlign = 32;
36193326Sed  LongWidth = LongAlign = 32;
37193326Sed  LongLongWidth = LongLongAlign = 64;
38234353Sdim  SuitableAlign = 64;
39251662Sdim  MinGlobalAlign = 0;
40226633Sdim  HalfWidth = 16;
41226633Sdim  HalfAlign = 16;
42193326Sed  FloatWidth = 32;
43193326Sed  FloatAlign = 32;
44193326Sed  DoubleWidth = 64;
45193326Sed  DoubleAlign = 64;
46193326Sed  LongDoubleWidth = 64;
47193326Sed  LongDoubleAlign = 64;
48210299Sed  LargeArrayMinWidth = 0;
49210299Sed  LargeArrayAlign = 0;
50226633Sdim  MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 0;
51239462Sdim  MaxVectorAlign = 0;
52193326Sed  SizeType = UnsignedLong;
53193326Sed  PtrDiffType = SignedLong;
54193326Sed  IntMaxType = SignedLongLong;
55193326Sed  UIntMaxType = UnsignedLongLong;
56193326Sed  IntPtrType = SignedLong;
57193326Sed  WCharType = SignedInt;
58198398Srdivacky  WIntType = SignedInt;
59198092Srdivacky  Char16Type = UnsignedShort;
60198092Srdivacky  Char32Type = UnsignedInt;
61195341Sed  Int64Type = SignedLongLong;
62199990Srdivacky  SigAtomicType = SignedInt;
63243830Sdim  ProcessIDType = SignedInt;
64234982Sdim  UseSignedCharForObjCBool = true;
65207619Srdivacky  UseBitFieldTypeAlignment = true;
66226633Sdim  UseZeroLengthBitfieldAlignment = false;
67226633Sdim  ZeroLengthBitfieldBoundary = 0;
68226633Sdim  HalfFormat = &llvm::APFloat::IEEEhalf;
69193326Sed  FloatFormat = &llvm::APFloat::IEEEsingle;
70193326Sed  DoubleFormat = &llvm::APFloat::IEEEdouble;
71193326Sed  LongDoubleFormat = &llvm::APFloat::IEEEdouble;
72193326Sed  DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
73199482Srdivacky                      "i64:64:64-f32:32:32-f64:64:64-n32";
74193326Sed  UserLabelPrefix = "_";
75218893Sdim  MCountName = "mcount";
76226633Sdim  RegParmMax = 0;
77226633Sdim  SSERegParmMax = 0;
78208600Srdivacky  HasAlignMac68kSupport = false;
79210299Sed
80210299Sed  // Default to no types using fpret.
81210299Sed  RealTypeUsesObjCFPRet = 0;
82212904Sdim
83234353Sdim  // Default to not using fp2ret for __Complex long double
84234353Sdim  ComplexLongDoubleUsesFP2Ret = false;
85234353Sdim
86212904Sdim  // Default to using the Itanium ABI.
87249423Sdim  TheCXXABI.set(TargetCXXABI::GenericItanium);
88221345Sdim
89221345Sdim  // Default to an empty address space map.
90221345Sdim  AddrSpaceMap = &DefaultAddrSpaceMap;
91263508Sdim  UseAddrSpaceMapMangling = false;
92221345Sdim
93221345Sdim  // Default to an unknown platform name.
94221345Sdim  PlatformName = "unknown";
95221345Sdim  PlatformMinVersion = VersionTuple();
96193326Sed}
97193326Sed
98193326Sed// Out of line virtual dtor for TargetInfo.
99193326SedTargetInfo::~TargetInfo() {}
100193326Sed
101193326Sed/// getTypeName - Return the user string for the specified integer type enum.
102193326Sed/// For example, SignedShort -> "short".
103193326Sedconst char *TargetInfo::getTypeName(IntType T) {
104193326Sed  switch (T) {
105226633Sdim  default: llvm_unreachable("not an integer!");
106263508Sdim  case SignedChar:       return "char";
107263508Sdim  case UnsignedChar:     return "unsigned char";
108193326Sed  case SignedShort:      return "short";
109193326Sed  case UnsignedShort:    return "unsigned short";
110193326Sed  case SignedInt:        return "int";
111193326Sed  case UnsignedInt:      return "unsigned int";
112193326Sed  case SignedLong:       return "long int";
113193326Sed  case UnsignedLong:     return "long unsigned int";
114193326Sed  case SignedLongLong:   return "long long int";
115193326Sed  case UnsignedLongLong: return "long long unsigned int";
116193326Sed  }
117193326Sed}
118193326Sed
119198398Srdivacky/// getTypeConstantSuffix - Return the constant suffix for the specified
120198398Srdivacky/// integer type enum. For example, SignedLong -> "L".
121198398Srdivackyconst char *TargetInfo::getTypeConstantSuffix(IntType T) {
122198398Srdivacky  switch (T) {
123226633Sdim  default: llvm_unreachable("not an integer!");
124263508Sdim  case SignedChar:
125198398Srdivacky  case SignedShort:
126198398Srdivacky  case SignedInt:        return "";
127198398Srdivacky  case SignedLong:       return "L";
128198398Srdivacky  case SignedLongLong:   return "LL";
129263508Sdim  case UnsignedChar:
130198398Srdivacky  case UnsignedShort:
131198398Srdivacky  case UnsignedInt:      return "U";
132198398Srdivacky  case UnsignedLong:     return "UL";
133198398Srdivacky  case UnsignedLongLong: return "ULL";
134198398Srdivacky  }
135198398Srdivacky}
136198398Srdivacky
137218893Sdim/// getTypeWidth - Return the width (in bits) of the specified integer type
138198398Srdivacky/// enum. For example, SignedInt -> getIntWidth().
139198398Srdivackyunsigned TargetInfo::getTypeWidth(IntType T) const {
140198398Srdivacky  switch (T) {
141226633Sdim  default: llvm_unreachable("not an integer!");
142263508Sdim  case SignedChar:
143263508Sdim  case UnsignedChar:     return getCharWidth();
144199482Srdivacky  case SignedShort:
145198398Srdivacky  case UnsignedShort:    return getShortWidth();
146199482Srdivacky  case SignedInt:
147198398Srdivacky  case UnsignedInt:      return getIntWidth();
148199482Srdivacky  case SignedLong:
149198398Srdivacky  case UnsignedLong:     return getLongWidth();
150199482Srdivacky  case SignedLongLong:
151198398Srdivacky  case UnsignedLongLong: return getLongLongWidth();
152198398Srdivacky  };
153198398Srdivacky}
154198398Srdivacky
155263508SdimTargetInfo::IntType TargetInfo::getIntTypeByWidth(
156263508Sdim    unsigned BitWidth, bool IsSigned) const {
157263508Sdim  if (getCharWidth() == BitWidth)
158263508Sdim    return IsSigned ? SignedChar : UnsignedChar;
159263508Sdim  if (getShortWidth() == BitWidth)
160263508Sdim    return IsSigned ? SignedShort : UnsignedShort;
161263508Sdim  if (getIntWidth() == BitWidth)
162263508Sdim    return IsSigned ? SignedInt : UnsignedInt;
163263508Sdim  if (getLongWidth() == BitWidth)
164263508Sdim    return IsSigned ? SignedLong : UnsignedLong;
165263508Sdim  if (getLongLongWidth() == BitWidth)
166263508Sdim    return IsSigned ? SignedLongLong : UnsignedLongLong;
167263508Sdim  return NoInt;
168263508Sdim}
169263508Sdim
170263508SdimTargetInfo::RealType TargetInfo::getRealTypeByWidth(unsigned BitWidth) const {
171263508Sdim  if (getFloatWidth() == BitWidth)
172263508Sdim    return Float;
173263508Sdim  if (getDoubleWidth() == BitWidth)
174263508Sdim    return Double;
175263508Sdim
176263508Sdim  switch (BitWidth) {
177263508Sdim  case 96:
178263508Sdim    if (&getLongDoubleFormat() == &llvm::APFloat::x87DoubleExtended)
179263508Sdim      return LongDouble;
180263508Sdim    break;
181263508Sdim  case 128:
182263508Sdim    if (&getLongDoubleFormat() == &llvm::APFloat::PPCDoubleDouble ||
183263508Sdim        &getLongDoubleFormat() == &llvm::APFloat::IEEEquad)
184263508Sdim      return LongDouble;
185263508Sdim    break;
186263508Sdim  }
187263508Sdim
188263508Sdim  return NoFloat;
189263508Sdim}
190263508Sdim
191218893Sdim/// getTypeAlign - Return the alignment (in bits) of the specified integer type
192199482Srdivacky/// enum. For example, SignedInt -> getIntAlign().
193199482Srdivackyunsigned TargetInfo::getTypeAlign(IntType T) const {
194199482Srdivacky  switch (T) {
195226633Sdim  default: llvm_unreachable("not an integer!");
196263508Sdim  case SignedChar:
197263508Sdim  case UnsignedChar:     return getCharAlign();
198199482Srdivacky  case SignedShort:
199199482Srdivacky  case UnsignedShort:    return getShortAlign();
200199482Srdivacky  case SignedInt:
201199482Srdivacky  case UnsignedInt:      return getIntAlign();
202199482Srdivacky  case SignedLong:
203199482Srdivacky  case UnsignedLong:     return getLongAlign();
204199482Srdivacky  case SignedLongLong:
205199482Srdivacky  case UnsignedLongLong: return getLongLongAlign();
206199482Srdivacky  };
207199482Srdivacky}
208199482Srdivacky
209198893Srdivacky/// isTypeSigned - Return whether an integer types is signed. Returns true if
210198398Srdivacky/// the type is signed; false otherwise.
211218893Sdimbool TargetInfo::isTypeSigned(IntType T) {
212198398Srdivacky  switch (T) {
213226633Sdim  default: llvm_unreachable("not an integer!");
214263508Sdim  case SignedChar:
215198398Srdivacky  case SignedShort:
216198398Srdivacky  case SignedInt:
217198398Srdivacky  case SignedLong:
218218893Sdim  case SignedLongLong:
219198398Srdivacky    return true;
220263508Sdim  case UnsignedChar:
221198398Srdivacky  case UnsignedShort:
222198398Srdivacky  case UnsignedInt:
223198398Srdivacky  case UnsignedLong:
224218893Sdim  case UnsignedLongLong:
225198398Srdivacky    return false;
226198398Srdivacky  };
227198398Srdivacky}
228198398Srdivacky
229199482Srdivacky/// setForcedLangOptions - Set forced language options.
230199482Srdivacky/// Apply changes to the target information with respect to certain
231199482Srdivacky/// language options which change the target configuration.
232199482Srdivackyvoid TargetInfo::setForcedLangOptions(LangOptions &Opts) {
233207619Srdivacky  if (Opts.NoBitFieldTypeAlign)
234207619Srdivacky    UseBitFieldTypeAlignment = false;
235207619Srdivacky  if (Opts.ShortWChar)
236199482Srdivacky    WCharType = UnsignedShort;
237263508Sdim
238263508Sdim  if (Opts.OpenCL) {
239263508Sdim    // OpenCL C requires specific widths for types, irrespective of
240263508Sdim    // what these normally are for the target.
241263508Sdim    // We also define long long and long double here, although the
242263508Sdim    // OpenCL standard only mentions these as "reserved".
243263508Sdim    IntWidth = IntAlign = 32;
244263508Sdim    LongWidth = LongAlign = 64;
245263508Sdim    LongLongWidth = LongLongAlign = 128;
246263508Sdim    HalfWidth = HalfAlign = 16;
247263508Sdim    FloatWidth = FloatAlign = 32;
248263508Sdim    DoubleWidth = DoubleAlign = 64;
249263508Sdim    LongDoubleWidth = LongDoubleAlign = 128;
250263508Sdim
251263508Sdim    assert(PointerWidth == 32 || PointerWidth == 64);
252263508Sdim    bool Is32BitArch = PointerWidth == 32;
253263508Sdim    SizeType = Is32BitArch ? UnsignedInt : UnsignedLong;
254263508Sdim    PtrDiffType = Is32BitArch ? SignedInt : SignedLong;
255263508Sdim    IntPtrType = Is32BitArch ? SignedInt : SignedLong;
256263508Sdim
257263508Sdim    IntMaxType = SignedLongLong;
258263508Sdim    UIntMaxType = UnsignedLongLong;
259263508Sdim    Int64Type = SignedLong;
260263508Sdim
261263508Sdim    HalfFormat = &llvm::APFloat::IEEEhalf;
262263508Sdim    FloatFormat = &llvm::APFloat::IEEEsingle;
263263508Sdim    DoubleFormat = &llvm::APFloat::IEEEdouble;
264263508Sdim    LongDoubleFormat = &llvm::APFloat::IEEEquad;
265263508Sdim  }
266199482Srdivacky}
267198398Srdivacky
268193326Sed//===----------------------------------------------------------------------===//
269193326Sed
270193326Sed
271226633Sdimstatic StringRef removeGCCRegisterPrefix(StringRef Name) {
272193326Sed  if (Name[0] == '%' || Name[0] == '#')
273203955Srdivacky    Name = Name.substr(1);
274218893Sdim
275203955Srdivacky  return Name;
276193326Sed}
277193326Sed
278224145Sdim/// isValidClobber - Returns whether the passed in string is
279224145Sdim/// a valid clobber in an inline asm statement. This is used by
280224145Sdim/// Sema.
281226633Sdimbool TargetInfo::isValidClobber(StringRef Name) const {
282224145Sdim  return (isValidGCCRegisterName(Name) ||
283224145Sdim	  Name == "memory" || Name == "cc");
284224145Sdim}
285224145Sdim
286193326Sed/// isValidGCCRegisterName - Returns whether the passed in string
287193326Sed/// is a valid register name according to GCC. This is used by Sema for
288193326Sed/// inline asm statements.
289226633Sdimbool TargetInfo::isValidGCCRegisterName(StringRef Name) const {
290203955Srdivacky  if (Name.empty())
291203955Srdivacky    return false;
292218893Sdim
293193326Sed  const char * const *Names;
294193326Sed  unsigned NumNames;
295198092Srdivacky
296193326Sed  // Get rid of any register prefix.
297203955Srdivacky  Name = removeGCCRegisterPrefix(Name);
298193326Sed
299193326Sed  getGCCRegNames(Names, NumNames);
300198092Srdivacky
301193326Sed  // If we have a number it maps to an entry in the register name array.
302249423Sdim  if (isDigit(Name[0])) {
303203955Srdivacky    int n;
304203955Srdivacky    if (!Name.getAsInteger(0, n))
305193326Sed      return n >= 0 && (unsigned)n < NumNames;
306193326Sed  }
307193326Sed
308193326Sed  // Check register names.
309193326Sed  for (unsigned i = 0; i < NumNames; i++) {
310203955Srdivacky    if (Name == Names[i])
311193326Sed      return true;
312193326Sed  }
313198092Srdivacky
314224145Sdim  // Check any additional names that we have.
315224145Sdim  const AddlRegName *AddlNames;
316224145Sdim  unsigned NumAddlNames;
317224145Sdim  getGCCAddlRegNames(AddlNames, NumAddlNames);
318224145Sdim  for (unsigned i = 0; i < NumAddlNames; i++)
319224145Sdim    for (unsigned j = 0; j < llvm::array_lengthof(AddlNames[i].Names); j++) {
320224145Sdim      if (!AddlNames[i].Names[j])
321224145Sdim	break;
322224145Sdim      // Make sure the register that the additional name is for is within
323224145Sdim      // the bounds of the register names from above.
324224145Sdim      if (AddlNames[i].Names[j] == Name && AddlNames[i].RegNum < NumNames)
325224145Sdim	return true;
326224145Sdim  }
327224145Sdim
328193326Sed  // Now check aliases.
329193326Sed  const GCCRegAlias *Aliases;
330193326Sed  unsigned NumAliases;
331198092Srdivacky
332193326Sed  getGCCRegAliases(Aliases, NumAliases);
333193326Sed  for (unsigned i = 0; i < NumAliases; i++) {
334193326Sed    for (unsigned j = 0 ; j < llvm::array_lengthof(Aliases[i].Aliases); j++) {
335193326Sed      if (!Aliases[i].Aliases[j])
336193326Sed        break;
337203955Srdivacky      if (Aliases[i].Aliases[j] == Name)
338193326Sed        return true;
339193326Sed    }
340193326Sed  }
341198092Srdivacky
342193326Sed  return false;
343193326Sed}
344193326Sed
345226633SdimStringRef
346226633SdimTargetInfo::getNormalizedGCCRegisterName(StringRef Name) const {
347193326Sed  assert(isValidGCCRegisterName(Name) && "Invalid register passed in");
348198092Srdivacky
349203955Srdivacky  // Get rid of any register prefix.
350203955Srdivacky  Name = removeGCCRegisterPrefix(Name);
351198092Srdivacky
352193326Sed  const char * const *Names;
353193326Sed  unsigned NumNames;
354193326Sed
355193326Sed  getGCCRegNames(Names, NumNames);
356193326Sed
357193326Sed  // First, check if we have a number.
358249423Sdim  if (isDigit(Name[0])) {
359203955Srdivacky    int n;
360203955Srdivacky    if (!Name.getAsInteger(0, n)) {
361198092Srdivacky      assert(n >= 0 && (unsigned)n < NumNames &&
362193326Sed             "Out of bounds register number!");
363193326Sed      return Names[n];
364193326Sed    }
365193326Sed  }
366198092Srdivacky
367224145Sdim  // Check any additional names that we have.
368224145Sdim  const AddlRegName *AddlNames;
369224145Sdim  unsigned NumAddlNames;
370224145Sdim  getGCCAddlRegNames(AddlNames, NumAddlNames);
371224145Sdim  for (unsigned i = 0; i < NumAddlNames; i++)
372224145Sdim    for (unsigned j = 0; j < llvm::array_lengthof(AddlNames[i].Names); j++) {
373224145Sdim      if (!AddlNames[i].Names[j])
374224145Sdim	break;
375224145Sdim      // Make sure the register that the additional name is for is within
376224145Sdim      // the bounds of the register names from above.
377224145Sdim      if (AddlNames[i].Names[j] == Name && AddlNames[i].RegNum < NumNames)
378224145Sdim	return Name;
379224145Sdim    }
380224145Sdim
381193326Sed  // Now check aliases.
382193326Sed  const GCCRegAlias *Aliases;
383193326Sed  unsigned NumAliases;
384198092Srdivacky
385193326Sed  getGCCRegAliases(Aliases, NumAliases);
386193326Sed  for (unsigned i = 0; i < NumAliases; i++) {
387193326Sed    for (unsigned j = 0 ; j < llvm::array_lengthof(Aliases[i].Aliases); j++) {
388193326Sed      if (!Aliases[i].Aliases[j])
389193326Sed        break;
390203955Srdivacky      if (Aliases[i].Aliases[j] == Name)
391193326Sed        return Aliases[i].Register;
392193326Sed    }
393193326Sed  }
394198092Srdivacky
395193326Sed  return Name;
396193326Sed}
397193326Sed
398193326Sedbool TargetInfo::validateOutputConstraint(ConstraintInfo &Info) const {
399193326Sed  const char *Name = Info.getConstraintStr().c_str();
400193326Sed  // An output constraint must start with '=' or '+'
401193326Sed  if (*Name != '=' && *Name != '+')
402193326Sed    return false;
403193326Sed
404193326Sed  if (*Name == '+')
405193326Sed    Info.setIsReadWrite();
406193326Sed
407193326Sed  Name++;
408193326Sed  while (*Name) {
409193326Sed    switch (*Name) {
410193326Sed    default:
411193326Sed      if (!validateAsmConstraint(Name, Info)) {
412193326Sed        // FIXME: We temporarily return false
413193326Sed        // so we can add more constraints as we hit it.
414193326Sed        // Eventually, an unknown constraint should just be treated as 'g'.
415193326Sed        return false;
416193326Sed      }
417193326Sed    case '&': // early clobber.
418193326Sed      break;
419198092Srdivacky    case '%': // commutative.
420198092Srdivacky      // FIXME: Check that there is a another register after this one.
421198092Srdivacky      break;
422193326Sed    case 'r': // general register.
423193326Sed      Info.setAllowsRegister();
424193326Sed      break;
425193326Sed    case 'm': // memory operand.
426218893Sdim    case 'o': // offsetable memory operand.
427218893Sdim    case 'V': // non-offsetable memory operand.
428218893Sdim    case '<': // autodecrement memory operand.
429218893Sdim    case '>': // autoincrement memory operand.
430193326Sed      Info.setAllowsMemory();
431193326Sed      break;
432193326Sed    case 'g': // general register, memory operand or immediate integer.
433193326Sed    case 'X': // any operand.
434193326Sed      Info.setAllowsRegister();
435193326Sed      Info.setAllowsMemory();
436193326Sed      break;
437212904Sdim    case ',': // multiple alternative constraint.  Pass it.
438212904Sdim      // Handle additional optional '=' or '+' modifiers.
439218893Sdim      if (Name[1] == '=' || Name[1] == '+')
440212904Sdim        Name++;
441212904Sdim      break;
442212904Sdim    case '?': // Disparage slightly code.
443218893Sdim    case '!': // Disparage severely.
444243830Sdim    case '#': // Ignore as constraint.
445243830Sdim    case '*': // Ignore for choosing register preferences.
446212904Sdim      break;  // Pass them.
447193326Sed    }
448198092Srdivacky
449193326Sed    Name++;
450193326Sed  }
451198092Srdivacky
452251662Sdim  // If a constraint allows neither memory nor register operands it contains
453251662Sdim  // only modifiers. Reject it.
454251662Sdim  return Info.allowsMemory() || Info.allowsRegister();
455193326Sed}
456193326Sed
457193326Sedbool TargetInfo::resolveSymbolicName(const char *&Name,
458193326Sed                                     ConstraintInfo *OutputConstraints,
459193326Sed                                     unsigned NumOutputs,
460193326Sed                                     unsigned &Index) const {
461193326Sed  assert(*Name == '[' && "Symbolic name did not start with '['");
462193326Sed  Name++;
463193326Sed  const char *Start = Name;
464193326Sed  while (*Name && *Name != ']')
465193326Sed    Name++;
466198092Srdivacky
467193326Sed  if (!*Name) {
468193326Sed    // Missing ']'
469193326Sed    return false;
470193326Sed  }
471198092Srdivacky
472193326Sed  std::string SymbolicName(Start, Name - Start);
473198092Srdivacky
474193326Sed  for (Index = 0; Index != NumOutputs; ++Index)
475193326Sed    if (SymbolicName == OutputConstraints[Index].getName())
476193326Sed      return true;
477193326Sed
478193326Sed  return false;
479193326Sed}
480193326Sed
481193326Sedbool TargetInfo::validateInputConstraint(ConstraintInfo *OutputConstraints,
482193326Sed                                         unsigned NumOutputs,
483193326Sed                                         ConstraintInfo &Info) const {
484193326Sed  const char *Name = Info.ConstraintStr.c_str();
485193326Sed
486193326Sed  while (*Name) {
487193326Sed    switch (*Name) {
488193326Sed    default:
489193326Sed      // Check if we have a matching constraint
490193326Sed      if (*Name >= '0' && *Name <= '9') {
491193326Sed        unsigned i = *Name - '0';
492198092Srdivacky
493193326Sed        // Check if matching constraint is out of bounds.
494193326Sed        if (i >= NumOutputs)
495193326Sed          return false;
496198092Srdivacky
497218893Sdim        // A number must refer to an output only operand.
498218893Sdim        if (OutputConstraints[i].isReadWrite())
499218893Sdim          return false;
500218893Sdim
501218893Sdim        // If the constraint is already tied, it must be tied to the
502218893Sdim        // same operand referenced to by the number.
503218893Sdim        if (Info.hasTiedOperand() && Info.getTiedOperand() != i)
504218893Sdim          return false;
505218893Sdim
506198092Srdivacky        // The constraint should have the same info as the respective
507193326Sed        // output constraint.
508193326Sed        Info.setTiedOperand(i, OutputConstraints[i]);
509193326Sed      } else if (!validateAsmConstraint(Name, Info)) {
510193326Sed        // FIXME: This error return is in place temporarily so we can
511193326Sed        // add more constraints as we hit it.  Eventually, an unknown
512193326Sed        // constraint should just be treated as 'g'.
513193326Sed        return false;
514193326Sed      }
515193326Sed      break;
516193326Sed    case '[': {
517193326Sed      unsigned Index = 0;
518193326Sed      if (!resolveSymbolicName(Name, OutputConstraints, NumOutputs, Index))
519193326Sed        return false;
520198092Srdivacky
521218893Sdim      // If the constraint is already tied, it must be tied to the
522218893Sdim      // same operand referenced to by the number.
523218893Sdim      if (Info.hasTiedOperand() && Info.getTiedOperand() != Index)
524218893Sdim        return false;
525218893Sdim
526212904Sdim      Info.setTiedOperand(Index, OutputConstraints[Index]);
527193326Sed      break;
528198092Srdivacky    }
529193326Sed    case '%': // commutative
530193326Sed      // FIXME: Fail if % is used with the last operand.
531193326Sed      break;
532193326Sed    case 'i': // immediate integer.
533193326Sed    case 'n': // immediate integer with a known value.
534193326Sed      break;
535193326Sed    case 'I':  // Various constant constraints with target-specific meanings.
536193326Sed    case 'J':
537193326Sed    case 'K':
538193326Sed    case 'L':
539193326Sed    case 'M':
540193326Sed    case 'N':
541193326Sed    case 'O':
542193326Sed    case 'P':
543193326Sed      break;
544193326Sed    case 'r': // general register.
545193326Sed      Info.setAllowsRegister();
546193326Sed      break;
547193326Sed    case 'm': // memory operand.
548218893Sdim    case 'o': // offsettable memory operand.
549218893Sdim    case 'V': // non-offsettable memory operand.
550218893Sdim    case '<': // autodecrement memory operand.
551218893Sdim    case '>': // autoincrement memory operand.
552193326Sed      Info.setAllowsMemory();
553193326Sed      break;
554193326Sed    case 'g': // general register, memory operand or immediate integer.
555193326Sed    case 'X': // any operand.
556193326Sed      Info.setAllowsRegister();
557193326Sed      Info.setAllowsMemory();
558193326Sed      break;
559218893Sdim    case 'E': // immediate floating point.
560218893Sdim    case 'F': // immediate floating point.
561218893Sdim    case 'p': // address operand.
562218893Sdim      break;
563212904Sdim    case ',': // multiple alternative constraint.  Ignore comma.
564212904Sdim      break;
565212904Sdim    case '?': // Disparage slightly code.
566221345Sdim    case '!': // Disparage severely.
567243830Sdim    case '#': // Ignore as constraint.
568243830Sdim    case '*': // Ignore for choosing register preferences.
569212904Sdim      break;  // Pass them.
570193326Sed    }
571198092Srdivacky
572193326Sed    Name++;
573193326Sed  }
574198092Srdivacky
575193326Sed  return true;
576193326Sed}
577249423Sdim
578249423Sdimbool TargetCXXABI::tryParse(llvm::StringRef name) {
579249423Sdim  const Kind unknown = static_cast<Kind>(-1);
580249423Sdim  Kind kind = llvm::StringSwitch<Kind>(name)
581249423Sdim    .Case("arm", GenericARM)
582249423Sdim    .Case("ios", iOS)
583249423Sdim    .Case("itanium", GenericItanium)
584249423Sdim    .Case("microsoft", Microsoft)
585249423Sdim    .Default(unknown);
586249423Sdim  if (kind == unknown) return false;
587249423Sdim
588249423Sdim  set(kind);
589249423Sdim  return true;
590249423Sdim}
591