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