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