TargetInfo.cpp revision 218893
155714Skris//===--- TargetInfo.cpp - Information about Target machine ----------------===// 255714Skris// 355714Skris// The LLVM Compiler Infrastructure 455714Skris// 555714Skris// This file is distributed under the University of Illinois Open Source 655714Skris// License. See LICENSE.TXT for details. 755714Skris// 855714Skris//===----------------------------------------------------------------------===// 955714Skris// 1055714Skris// This file implements the TargetInfo and TargetInfoImpl interfaces. 1155714Skris// 1255714Skris//===----------------------------------------------------------------------===// 1355714Skris 1455714Skris#include "clang/Basic/TargetInfo.h" 1555714Skris#include "clang/Basic/LangOptions.h" 1655714Skris#include "llvm/ADT/APFloat.h" 1755714Skris#include "llvm/ADT/STLExtras.h" 1855714Skris#include <cctype> 1955714Skris#include <cstdlib> 2055714Skrisusing namespace clang; 2155714Skris 2255714Skris// TargetInfo Constructor. 2355714SkrisTargetInfo::TargetInfo(const std::string &T) : Triple(T) { 2455714Skris // Set defaults. Defaults are set for a 32-bit RISC platform, like PPC or 2555714Skris // SPARC. These should be overridden by concrete targets as needed. 2655714Skris TLSSupported = true; 2755714Skris NoAsmVariants = false; 2855714Skris PointerWidth = PointerAlign = 32; 2955714Skris BoolWidth = BoolAlign = 8; 3055714Skris IntWidth = IntAlign = 32; 3155714Skris LongWidth = LongAlign = 32; 3255714Skris LongLongWidth = LongLongAlign = 64; 3355714Skris FloatWidth = 32; 3455714Skris FloatAlign = 32; 3555714Skris DoubleWidth = 64; 3655714Skris DoubleAlign = 64; 3755714Skris LongDoubleWidth = 64; 3855714Skris LongDoubleAlign = 64; 3955714Skris LargeArrayMinWidth = 0; 4055714Skris LargeArrayAlign = 0; 4155714Skris SizeType = UnsignedLong; 4255714Skris PtrDiffType = SignedLong; 4355714Skris IntMaxType = SignedLongLong; 4455714Skris UIntMaxType = UnsignedLongLong; 4555714Skris IntPtrType = SignedLong; 4655714Skris WCharType = SignedInt; 4755714Skris WIntType = SignedInt; 4855714Skris Char16Type = UnsignedShort; 4955714Skris Char32Type = UnsignedInt; 5055714Skris Int64Type = SignedLongLong; 5155714Skris SigAtomicType = SignedInt; 5255714Skris UseBitFieldTypeAlignment = true; 5355714Skris FloatFormat = &llvm::APFloat::IEEEsingle; 5455714Skris DoubleFormat = &llvm::APFloat::IEEEdouble; 5555714Skris LongDoubleFormat = &llvm::APFloat::IEEEdouble; 5655714Skris DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 5755714Skris "i64:64:64-f32:32:32-f64:64:64-n32"; 5855714Skris UserLabelPrefix = "_"; 5955714Skris MCountName = "mcount"; 6055714Skris HasAlignMac68kSupport = false; 6155714Skris 6255714Skris // Default to no types using fpret. 6355714Skris RealTypeUsesObjCFPRet = 0; 6455714Skris 6555714Skris // Default to using the Itanium ABI. 6655714Skris CXXABI = CXXABI_Itanium; 6755714Skris} 6855714Skris 6955714Skris// Out of line virtual dtor for TargetInfo. 7055714SkrisTargetInfo::~TargetInfo() {} 7155714Skris 7255714Skris/// getTypeName - Return the user string for the specified integer type enum. 7355714Skris/// For example, SignedShort -> "short". 7455714Skrisconst char *TargetInfo::getTypeName(IntType T) { 7555714Skris switch (T) { 7655714Skris default: assert(0 && "not an integer!"); 7755714Skris case SignedShort: return "short"; 7855714Skris case UnsignedShort: return "unsigned short"; 7955714Skris case SignedInt: return "int"; 8055714Skris case UnsignedInt: return "unsigned int"; 8155714Skris case SignedLong: return "long int"; 8255714Skris case UnsignedLong: return "long unsigned int"; 8355714Skris case SignedLongLong: return "long long int"; 8455714Skris case UnsignedLongLong: return "long long unsigned int"; 8555714Skris } 8655714Skris} 8755714Skris 8855714Skris/// getTypeConstantSuffix - Return the constant suffix for the specified 8955714Skris/// integer type enum. For example, SignedLong -> "L". 9055714Skrisconst char *TargetInfo::getTypeConstantSuffix(IntType T) { 9155714Skris switch (T) { 9255714Skris default: assert(0 && "not an integer!"); 9355714Skris case SignedShort: 9455714Skris case SignedInt: return ""; 9555714Skris case SignedLong: return "L"; 9655714Skris case SignedLongLong: return "LL"; 9755714Skris case UnsignedShort: 9855714Skris case UnsignedInt: return "U"; 9955714Skris case UnsignedLong: return "UL"; 10055714Skris case UnsignedLongLong: return "ULL"; 10155714Skris } 10255714Skris} 10355714Skris 10455714Skris/// getTypeWidth - Return the width (in bits) of the specified integer type 10555714Skris/// enum. For example, SignedInt -> getIntWidth(). 10655714Skrisunsigned TargetInfo::getTypeWidth(IntType T) const { 10755714Skris switch (T) { 108 default: assert(0 && "not an integer!"); 109 case SignedShort: 110 case UnsignedShort: return getShortWidth(); 111 case SignedInt: 112 case UnsignedInt: return getIntWidth(); 113 case SignedLong: 114 case UnsignedLong: return getLongWidth(); 115 case SignedLongLong: 116 case UnsignedLongLong: return getLongLongWidth(); 117 }; 118} 119 120/// getTypeAlign - Return the alignment (in bits) of the specified integer type 121/// enum. For example, SignedInt -> getIntAlign(). 122unsigned TargetInfo::getTypeAlign(IntType T) const { 123 switch (T) { 124 default: assert(0 && "not an integer!"); 125 case SignedShort: 126 case UnsignedShort: return getShortAlign(); 127 case SignedInt: 128 case UnsignedInt: return getIntAlign(); 129 case SignedLong: 130 case UnsignedLong: return getLongAlign(); 131 case SignedLongLong: 132 case UnsignedLongLong: return getLongLongAlign(); 133 }; 134} 135 136/// isTypeSigned - Return whether an integer types is signed. Returns true if 137/// the type is signed; false otherwise. 138bool TargetInfo::isTypeSigned(IntType T) { 139 switch (T) { 140 default: assert(0 && "not an integer!"); 141 case SignedShort: 142 case SignedInt: 143 case SignedLong: 144 case SignedLongLong: 145 return true; 146 case UnsignedShort: 147 case UnsignedInt: 148 case UnsignedLong: 149 case UnsignedLongLong: 150 return false; 151 }; 152} 153 154/// setForcedLangOptions - Set forced language options. 155/// Apply changes to the target information with respect to certain 156/// language options which change the target configuration. 157void TargetInfo::setForcedLangOptions(LangOptions &Opts) { 158 if (Opts.NoBitFieldTypeAlign) 159 UseBitFieldTypeAlignment = false; 160 if (Opts.ShortWChar) 161 WCharType = UnsignedShort; 162} 163 164//===----------------------------------------------------------------------===// 165 166 167static llvm::StringRef removeGCCRegisterPrefix(llvm::StringRef Name) { 168 if (Name[0] == '%' || Name[0] == '#') 169 Name = Name.substr(1); 170 171 return Name; 172} 173 174/// isValidGCCRegisterName - Returns whether the passed in string 175/// is a valid register name according to GCC. This is used by Sema for 176/// inline asm statements. 177bool TargetInfo::isValidGCCRegisterName(llvm::StringRef Name) const { 178 if (Name.empty()) 179 return false; 180 181 const char * const *Names; 182 unsigned NumNames; 183 184 // Get rid of any register prefix. 185 Name = removeGCCRegisterPrefix(Name); 186 187 if (Name == "memory" || Name == "cc") 188 return true; 189 190 getGCCRegNames(Names, NumNames); 191 192 // If we have a number it maps to an entry in the register name array. 193 if (isdigit(Name[0])) { 194 int n; 195 if (!Name.getAsInteger(0, n)) 196 return n >= 0 && (unsigned)n < NumNames; 197 } 198 199 // Check register names. 200 for (unsigned i = 0; i < NumNames; i++) { 201 if (Name == Names[i]) 202 return true; 203 } 204 205 // Now check aliases. 206 const GCCRegAlias *Aliases; 207 unsigned NumAliases; 208 209 getGCCRegAliases(Aliases, NumAliases); 210 for (unsigned i = 0; i < NumAliases; i++) { 211 for (unsigned j = 0 ; j < llvm::array_lengthof(Aliases[i].Aliases); j++) { 212 if (!Aliases[i].Aliases[j]) 213 break; 214 if (Aliases[i].Aliases[j] == Name) 215 return true; 216 } 217 } 218 219 return false; 220} 221 222llvm::StringRef 223TargetInfo::getNormalizedGCCRegisterName(llvm::StringRef Name) const { 224 assert(isValidGCCRegisterName(Name) && "Invalid register passed in"); 225 226 // Get rid of any register prefix. 227 Name = removeGCCRegisterPrefix(Name); 228 229 const char * const *Names; 230 unsigned NumNames; 231 232 getGCCRegNames(Names, NumNames); 233 234 // First, check if we have a number. 235 if (isdigit(Name[0])) { 236 int n; 237 if (!Name.getAsInteger(0, n)) { 238 assert(n >= 0 && (unsigned)n < NumNames && 239 "Out of bounds register number!"); 240 return Names[n]; 241 } 242 } 243 244 // Now check aliases. 245 const GCCRegAlias *Aliases; 246 unsigned NumAliases; 247 248 getGCCRegAliases(Aliases, NumAliases); 249 for (unsigned i = 0; i < NumAliases; i++) { 250 for (unsigned j = 0 ; j < llvm::array_lengthof(Aliases[i].Aliases); j++) { 251 if (!Aliases[i].Aliases[j]) 252 break; 253 if (Aliases[i].Aliases[j] == Name) 254 return Aliases[i].Register; 255 } 256 } 257 258 return Name; 259} 260 261bool TargetInfo::validateOutputConstraint(ConstraintInfo &Info) const { 262 const char *Name = Info.getConstraintStr().c_str(); 263 // An output constraint must start with '=' or '+' 264 if (*Name != '=' && *Name != '+') 265 return false; 266 267 if (*Name == '+') 268 Info.setIsReadWrite(); 269 270 Name++; 271 while (*Name) { 272 switch (*Name) { 273 default: 274 if (!validateAsmConstraint(Name, Info)) { 275 // FIXME: We temporarily return false 276 // so we can add more constraints as we hit it. 277 // Eventually, an unknown constraint should just be treated as 'g'. 278 return false; 279 } 280 case '&': // early clobber. 281 break; 282 case '%': // commutative. 283 // FIXME: Check that there is a another register after this one. 284 break; 285 case 'r': // general register. 286 Info.setAllowsRegister(); 287 break; 288 case 'm': // memory operand. 289 case 'o': // offsetable memory operand. 290 case 'V': // non-offsetable memory operand. 291 case '<': // autodecrement memory operand. 292 case '>': // autoincrement memory operand. 293 Info.setAllowsMemory(); 294 break; 295 case 'g': // general register, memory operand or immediate integer. 296 case 'X': // any operand. 297 Info.setAllowsRegister(); 298 Info.setAllowsMemory(); 299 break; 300 case ',': // multiple alternative constraint. Pass it. 301 // Handle additional optional '=' or '+' modifiers. 302 if (Name[1] == '=' || Name[1] == '+') 303 Name++; 304 break; 305 case '?': // Disparage slightly code. 306 case '!': // Disparage severely. 307 break; // Pass them. 308 } 309 310 Name++; 311 } 312 313 return true; 314} 315 316bool TargetInfo::resolveSymbolicName(const char *&Name, 317 ConstraintInfo *OutputConstraints, 318 unsigned NumOutputs, 319 unsigned &Index) const { 320 assert(*Name == '[' && "Symbolic name did not start with '['"); 321 Name++; 322 const char *Start = Name; 323 while (*Name && *Name != ']') 324 Name++; 325 326 if (!*Name) { 327 // Missing ']' 328 return false; 329 } 330 331 std::string SymbolicName(Start, Name - Start); 332 333 for (Index = 0; Index != NumOutputs; ++Index) 334 if (SymbolicName == OutputConstraints[Index].getName()) 335 return true; 336 337 return false; 338} 339 340bool TargetInfo::validateInputConstraint(ConstraintInfo *OutputConstraints, 341 unsigned NumOutputs, 342 ConstraintInfo &Info) const { 343 const char *Name = Info.ConstraintStr.c_str(); 344 345 while (*Name) { 346 switch (*Name) { 347 default: 348 // Check if we have a matching constraint 349 if (*Name >= '0' && *Name <= '9') { 350 unsigned i = *Name - '0'; 351 352 // Check if matching constraint is out of bounds. 353 if (i >= NumOutputs) 354 return false; 355 356 // A number must refer to an output only operand. 357 if (OutputConstraints[i].isReadWrite()) 358 return false; 359 360 // If the constraint is already tied, it must be tied to the 361 // same operand referenced to by the number. 362 if (Info.hasTiedOperand() && Info.getTiedOperand() != i) 363 return false; 364 365 // The constraint should have the same info as the respective 366 // output constraint. 367 Info.setTiedOperand(i, OutputConstraints[i]); 368 } else if (!validateAsmConstraint(Name, Info)) { 369 // FIXME: This error return is in place temporarily so we can 370 // add more constraints as we hit it. Eventually, an unknown 371 // constraint should just be treated as 'g'. 372 return false; 373 } 374 break; 375 case '[': { 376 unsigned Index = 0; 377 if (!resolveSymbolicName(Name, OutputConstraints, NumOutputs, Index)) 378 return false; 379 380 // If the constraint is already tied, it must be tied to the 381 // same operand referenced to by the number. 382 if (Info.hasTiedOperand() && Info.getTiedOperand() != Index) 383 return false; 384 385 Info.setTiedOperand(Index, OutputConstraints[Index]); 386 break; 387 } 388 case '%': // commutative 389 // FIXME: Fail if % is used with the last operand. 390 break; 391 case 'i': // immediate integer. 392 case 'n': // immediate integer with a known value. 393 break; 394 case 'I': // Various constant constraints with target-specific meanings. 395 case 'J': 396 case 'K': 397 case 'L': 398 case 'M': 399 case 'N': 400 case 'O': 401 case 'P': 402 break; 403 case 'r': // general register. 404 Info.setAllowsRegister(); 405 break; 406 case 'm': // memory operand. 407 case 'o': // offsettable memory operand. 408 case 'V': // non-offsettable memory operand. 409 case '<': // autodecrement memory operand. 410 case '>': // autoincrement memory operand. 411 Info.setAllowsMemory(); 412 break; 413 case 'g': // general register, memory operand or immediate integer. 414 case 'X': // any operand. 415 Info.setAllowsRegister(); 416 Info.setAllowsMemory(); 417 break; 418 case 'E': // immediate floating point. 419 case 'F': // immediate floating point. 420 case 'p': // address operand. 421 break; 422 case ',': // multiple alternative constraint. Ignore comma. 423 break; 424 case '?': // Disparage slightly code. 425 case '!': // Disparage severly. 426 break; // Pass them. 427 } 428 429 Name++; 430 } 431 432 return true; 433} 434