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