TargetInfo.cpp revision 68086b9ad26c471322449ea1c030c2ac8397fd07
1//===--- TargetInfo.cpp - Information about Target machine ----------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements the TargetInfo and TargetInfoImpl interfaces. 11// 12//===----------------------------------------------------------------------===// 13 14#include "clang/Basic/TargetInfo.h" 15#include "clang/Basic/LangOptions.h" 16#include "llvm/ADT/APFloat.h" 17#include "llvm/ADT/STLExtras.h" 18#include <cstdlib> 19using namespace clang; 20 21// TargetInfo Constructor. 22TargetInfo::TargetInfo(const std::string &T) : Triple(T) { 23 // Set defaults. Defaults are set for a 32-bit RISC platform, like PPC or 24 // SPARC. These should be overridden by concrete targets as needed. 25 TLSSupported = true; 26 NoAsmVariants = false; 27 PointerWidth = PointerAlign = 32; 28 IntWidth = IntAlign = 32; 29 LongWidth = LongAlign = 32; 30 LongLongWidth = LongLongAlign = 64; 31 FloatWidth = 32; 32 FloatAlign = 32; 33 DoubleWidth = 64; 34 DoubleAlign = 64; 35 LongDoubleWidth = 64; 36 LongDoubleAlign = 64; 37 LargeArrayMinWidth = 0; 38 LargeArrayAlign = 0; 39 SizeType = UnsignedLong; 40 PtrDiffType = SignedLong; 41 IntMaxType = SignedLongLong; 42 UIntMaxType = UnsignedLongLong; 43 IntPtrType = SignedLong; 44 WCharType = SignedInt; 45 WIntType = SignedInt; 46 Char16Type = UnsignedShort; 47 Char32Type = UnsignedInt; 48 Int64Type = SignedLongLong; 49 SigAtomicType = SignedInt; 50 UseBitFieldTypeAlignment = true; 51 FloatFormat = &llvm::APFloat::IEEEsingle; 52 DoubleFormat = &llvm::APFloat::IEEEdouble; 53 LongDoubleFormat = &llvm::APFloat::IEEEdouble; 54 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 55 "i64:64:64-f32:32:32-f64:64:64-n32"; 56 UserLabelPrefix = "_"; 57 HasAlignMac68kSupport = false; 58 59 // Default to no types using fpret. 60 RealTypeUsesObjCFPRet = 0; 61 62 // Default to using the Itanium ABI. 63 CXXABI = CXXABI_Itanium; 64} 65 66// Out of line virtual dtor for TargetInfo. 67TargetInfo::~TargetInfo() {} 68 69/// getTypeName - Return the user string for the specified integer type enum. 70/// For example, SignedShort -> "short". 71const char *TargetInfo::getTypeName(IntType T) { 72 switch (T) { 73 default: assert(0 && "not an integer!"); 74 case SignedShort: return "short"; 75 case UnsignedShort: return "unsigned short"; 76 case SignedInt: return "int"; 77 case UnsignedInt: return "unsigned int"; 78 case SignedLong: return "long int"; 79 case UnsignedLong: return "long unsigned int"; 80 case SignedLongLong: return "long long int"; 81 case UnsignedLongLong: return "long long unsigned int"; 82 } 83} 84 85/// getTypeConstantSuffix - Return the constant suffix for the specified 86/// integer type enum. For example, SignedLong -> "L". 87const char *TargetInfo::getTypeConstantSuffix(IntType T) { 88 switch (T) { 89 default: assert(0 && "not an integer!"); 90 case SignedShort: 91 case SignedInt: return ""; 92 case SignedLong: return "L"; 93 case SignedLongLong: return "LL"; 94 case UnsignedShort: 95 case UnsignedInt: return "U"; 96 case UnsignedLong: return "UL"; 97 case UnsignedLongLong: return "ULL"; 98 } 99} 100 101/// getTypeWidth - Return the width (in bits) of the specified integer type 102/// enum. For example, SignedInt -> getIntWidth(). 103unsigned TargetInfo::getTypeWidth(IntType T) const { 104 switch (T) { 105 default: assert(0 && "not an integer!"); 106 case SignedShort: 107 case UnsignedShort: return getShortWidth(); 108 case SignedInt: 109 case UnsignedInt: return getIntWidth(); 110 case SignedLong: 111 case UnsignedLong: return getLongWidth(); 112 case SignedLongLong: 113 case UnsignedLongLong: return getLongLongWidth(); 114 }; 115} 116 117/// getTypeAlign - Return the alignment (in bits) of the specified integer type 118/// enum. For example, SignedInt -> getIntAlign(). 119unsigned TargetInfo::getTypeAlign(IntType T) const { 120 switch (T) { 121 default: assert(0 && "not an integer!"); 122 case SignedShort: 123 case UnsignedShort: return getShortAlign(); 124 case SignedInt: 125 case UnsignedInt: return getIntAlign(); 126 case SignedLong: 127 case UnsignedLong: return getLongAlign(); 128 case SignedLongLong: 129 case UnsignedLongLong: return getLongLongAlign(); 130 }; 131} 132 133/// isTypeSigned - Return whether an integer types is signed. Returns true if 134/// the type is signed; false otherwise. 135bool TargetInfo::isTypeSigned(IntType T) const { 136 switch (T) { 137 default: assert(0 && "not an integer!"); 138 case SignedShort: 139 case SignedInt: 140 case SignedLong: 141 case SignedLongLong: 142 return true; 143 case UnsignedShort: 144 case UnsignedInt: 145 case UnsignedLong: 146 case UnsignedLongLong: 147 return false; 148 }; 149} 150 151/// setForcedLangOptions - Set forced language options. 152/// Apply changes to the target information with respect to certain 153/// language options which change the target configuration. 154void TargetInfo::setForcedLangOptions(LangOptions &Opts) { 155 if (Opts.NoBitFieldTypeAlign) 156 UseBitFieldTypeAlignment = false; 157 if (Opts.ShortWChar) 158 WCharType = UnsignedShort; 159} 160 161//===----------------------------------------------------------------------===// 162 163 164static llvm::StringRef removeGCCRegisterPrefix(llvm::StringRef Name) { 165 if (Name[0] == '%' || Name[0] == '#') 166 Name = Name.substr(1); 167 168 return Name; 169} 170 171/// isValidGCCRegisterName - Returns whether the passed in string 172/// is a valid register name according to GCC. This is used by Sema for 173/// inline asm statements. 174bool TargetInfo::isValidGCCRegisterName(llvm::StringRef Name) const { 175 if (Name.empty()) 176 return false; 177 178 const char * const *Names; 179 unsigned NumNames; 180 181 // Get rid of any register prefix. 182 Name = removeGCCRegisterPrefix(Name); 183 184 if (Name == "memory" || Name == "cc") 185 return true; 186 187 getGCCRegNames(Names, NumNames); 188 189 // If we have a number it maps to an entry in the register name array. 190 if (isdigit(Name[0])) { 191 int n; 192 if (!Name.getAsInteger(0, n)) 193 return n >= 0 && (unsigned)n < NumNames; 194 } 195 196 // Check register names. 197 for (unsigned i = 0; i < NumNames; i++) { 198 if (Name == Names[i]) 199 return true; 200 } 201 202 // Now check aliases. 203 const GCCRegAlias *Aliases; 204 unsigned NumAliases; 205 206 getGCCRegAliases(Aliases, NumAliases); 207 for (unsigned i = 0; i < NumAliases; i++) { 208 for (unsigned j = 0 ; j < llvm::array_lengthof(Aliases[i].Aliases); j++) { 209 if (!Aliases[i].Aliases[j]) 210 break; 211 if (Aliases[i].Aliases[j] == Name) 212 return true; 213 } 214 } 215 216 return false; 217} 218 219llvm::StringRef 220TargetInfo::getNormalizedGCCRegisterName(llvm::StringRef Name) const { 221 assert(isValidGCCRegisterName(Name) && "Invalid register passed in"); 222 223 // Get rid of any register prefix. 224 Name = removeGCCRegisterPrefix(Name); 225 226 const char * const *Names; 227 unsigned NumNames; 228 229 getGCCRegNames(Names, NumNames); 230 231 // First, check if we have a number. 232 if (isdigit(Name[0])) { 233 int n; 234 if (!Name.getAsInteger(0, n)) { 235 assert(n >= 0 && (unsigned)n < NumNames && 236 "Out of bounds register number!"); 237 return Names[n]; 238 } 239 } 240 241 // Now check aliases. 242 const GCCRegAlias *Aliases; 243 unsigned NumAliases; 244 245 getGCCRegAliases(Aliases, NumAliases); 246 for (unsigned i = 0; i < NumAliases; i++) { 247 for (unsigned j = 0 ; j < llvm::array_lengthof(Aliases[i].Aliases); j++) { 248 if (!Aliases[i].Aliases[j]) 249 break; 250 if (Aliases[i].Aliases[j] == Name) 251 return Aliases[i].Register; 252 } 253 } 254 255 return Name; 256} 257 258bool TargetInfo::validateOutputConstraint(ConstraintInfo &Info) const { 259 const char *Name = Info.getConstraintStr().c_str(); 260 // An output constraint must start with '=' or '+' 261 if (*Name != '=' && *Name != '+') 262 return false; 263 264 if (*Name == '+') 265 Info.setIsReadWrite(); 266 267 Name++; 268 while (*Name) { 269 switch (*Name) { 270 default: 271 if (!validateAsmConstraint(Name, Info)) { 272 // FIXME: We temporarily return false 273 // so we can add more constraints as we hit it. 274 // Eventually, an unknown constraint should just be treated as 'g'. 275 return false; 276 } 277 case '&': // early clobber. 278 break; 279 case '%': // commutative. 280 // FIXME: Check that there is a another register after this one. 281 break; 282 case 'r': // general register. 283 Info.setAllowsRegister(); 284 break; 285 case 'm': // memory operand. 286 Info.setAllowsMemory(); 287 break; 288 case 'g': // general register, memory operand or immediate integer. 289 case 'X': // any operand. 290 Info.setAllowsRegister(); 291 Info.setAllowsMemory(); 292 break; 293 case ',': // multiple alternative constraint. Pass it. 294 Name++; 295 // Handle additional optional '=' or '+' modifiers. 296 if (*Name == '=' || *Name == '+') 297 Name++; 298 break; 299 case '?': // Disparage slightly code. 300 case '!': // Disparage severly. 301 break; // Pass them. 302 } 303 304 Name++; 305 } 306 307 return true; 308} 309 310bool TargetInfo::resolveSymbolicName(const char *&Name, 311 ConstraintInfo *OutputConstraints, 312 unsigned NumOutputs, 313 unsigned &Index) const { 314 assert(*Name == '[' && "Symbolic name did not start with '['"); 315 Name++; 316 const char *Start = Name; 317 while (*Name && *Name != ']') 318 Name++; 319 320 if (!*Name) { 321 // Missing ']' 322 return false; 323 } 324 325 std::string SymbolicName(Start, Name - Start); 326 327 for (Index = 0; Index != NumOutputs; ++Index) 328 if (SymbolicName == OutputConstraints[Index].getName()) 329 return true; 330 331 return false; 332} 333 334bool TargetInfo::validateInputConstraint(ConstraintInfo *OutputConstraints, 335 unsigned NumOutputs, 336 ConstraintInfo &Info) const { 337 const char *Name = Info.ConstraintStr.c_str(); 338 339 while (*Name) { 340 switch (*Name) { 341 default: 342 // Check if we have a matching constraint 343 if (*Name >= '0' && *Name <= '9') { 344 unsigned i = *Name - '0'; 345 346 // Check if matching constraint is out of bounds. 347 if (i >= NumOutputs) 348 return false; 349 350 // The constraint should have the same info as the respective 351 // output constraint. 352 Info.setTiedOperand(i, OutputConstraints[i]); 353 } else if (!validateAsmConstraint(Name, Info)) { 354 // FIXME: This error return is in place temporarily so we can 355 // add more constraints as we hit it. Eventually, an unknown 356 // constraint should just be treated as 'g'. 357 return false; 358 } 359 break; 360 case '[': { 361 unsigned Index = 0; 362 if (!resolveSymbolicName(Name, OutputConstraints, NumOutputs, Index)) 363 return false; 364 365 Info.setTiedOperand(Index, OutputConstraints[Index]); 366 break; 367 } 368 case '%': // commutative 369 // FIXME: Fail if % is used with the last operand. 370 break; 371 case 'i': // immediate integer. 372 case 'n': // immediate integer with a known value. 373 break; 374 case 'I': // Various constant constraints with target-specific meanings. 375 case 'J': 376 case 'K': 377 case 'L': 378 case 'M': 379 case 'N': 380 case 'O': 381 case 'P': 382 break; 383 case 'r': // general register. 384 Info.setAllowsRegister(); 385 break; 386 case 'm': // memory operand. 387 case 'o': // offsettable memory operand 388 case 'V': // non-offsettable memory operand 389 Info.setAllowsMemory(); 390 break; 391 case 'g': // general register, memory operand or immediate integer. 392 case 'X': // any operand. 393 Info.setAllowsRegister(); 394 Info.setAllowsMemory(); 395 break; 396 case ',': // multiple alternative constraint. Ignore comma. 397 break; 398 case '?': // Disparage slightly code. 399 case '!': // Disparage severly. 400 break; // Pass them. 401 } 402 403 Name++; 404 } 405 406 return true; 407} 408