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