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