1 //===--- Triple.cpp - Target triple helper class --------------------------===// 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 #include "llvm/ADT/Triple.h" 11 12 #include "llvm/ADT/SmallString.h" 13 #include "llvm/ADT/Twine.h" 14 #include <cassert> 15 #include <cstring> 16 using namespace llvm; 17 18 // 19 20 const char *Triple::getArchTypeName(ArchType Kind) { 21 switch (Kind) { 22 case InvalidArch: return "<invalid>"; 23 case UnknownArch: return "unknown"; 24 25 case alpha: return "alpha"; 26 case arm: return "arm"; 27 case bfin: return "bfin"; 28 case cellspu: return "cellspu"; 29 case mips: return "mips"; 30 case mipsel: return "mipsel"; 31 case msp430: return "msp430"; 32 case pic16: return "pic16"; 33 case ppc64: return "powerpc64"; 34 case ppc: return "powerpc"; 35 case sparc: return "sparc"; 36 case sparcv9: return "sparcv9"; 37 case systemz: return "s390x"; 38 case tce: return "tce"; 39 case thumb: return "thumb"; 40 case x86: return "i386"; 41 case x86_64: return "x86_64"; 42 case xcore: return "xcore"; 43 case mblaze: return "mblaze"; 44 } 45 46 return "<invalid>"; 47 } 48 49 const char *Triple::getArchTypePrefix(ArchType Kind) { 50 switch (Kind) { 51 default: 52 return 0; 53 54 case alpha: return "alpha"; 55 56 case arm: 57 case thumb: return "arm"; 58 59 case bfin: return "bfin"; 60 61 case cellspu: return "spu"; 62 63 case ppc64: 64 case ppc: return "ppc"; 65 66 case mblaze: return "mblaze"; 67 68 case sparcv9: 69 case sparc: return "sparc"; 70 71 case x86: 72 case x86_64: return "x86"; 73 case xcore: return "xcore"; 74 } 75 } 76 77 const char *Triple::getVendorTypeName(VendorType Kind) { 78 switch (Kind) { 79 case UnknownVendor: return "unknown"; 80 81 case Apple: return "apple"; 82 case PC: return "pc"; 83 } 84 85 return "<invalid>"; 86 } 87 88 const char *Triple::getOSTypeName(OSType Kind) { 89 switch (Kind) { 90 case UnknownOS: return "unknown"; 91 92 case AuroraUX: return "auroraux"; 93 case Cygwin: return "cygwin"; 94 case Darwin: return "darwin"; 95 case DragonFly: return "dragonfly"; 96 case FreeBSD: return "freebsd"; 97 case Linux: return "linux"; 98 case Lv2: return "lv2"; 99 case MinGW32: return "mingw32"; 100 case MinGW64: return "mingw64"; 101 case NetBSD: return "netbsd"; 102 case OpenBSD: return "openbsd"; 103 case Psp: return "psp"; 104 case Solaris: return "solaris"; 105 case Win32: return "win32"; 106 case Haiku: return "haiku"; 107 } 108 109 return "<invalid>"; 110 } 111 112 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) { 113 if (Name == "alpha") 114 return alpha; 115 if (Name == "arm") 116 return arm; 117 if (Name == "bfin") 118 return bfin; 119 if (Name == "cellspu") 120 return cellspu; 121 if (Name == "mips") 122 return mips; 123 if (Name == "mipsel") 124 return mipsel; 125 if (Name == "msp430") 126 return msp430; 127 if (Name == "pic16") 128 return pic16; 129 if (Name == "ppc64") 130 return ppc64; 131 if (Name == "ppc") 132 return ppc; 133 if (Name == "mblaze") 134 return mblaze; 135 if (Name == "sparc") 136 return sparc; 137 if (Name == "sparcv9") 138 return sparcv9; 139 if (Name == "systemz") 140 return systemz; 141 if (Name == "tce") 142 return tce; 143 if (Name == "thumb") 144 return thumb; 145 if (Name == "x86") 146 return x86; 147 if (Name == "x86-64") 148 return x86_64; 149 if (Name == "xcore") 150 return xcore; 151 152 return UnknownArch; 153 } 154 155 Triple::ArchType Triple::getArchTypeForDarwinArchName(StringRef Str) { 156 // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for 157 // archs which Darwin doesn't use. 158 159 // The matching this routine does is fairly pointless, since it is neither the 160 // complete architecture list, nor a reasonable subset. The problem is that 161 // historically the driver driver accepts this and also ties its -march= 162 // handling to the architecture name, so we need to be careful before removing 163 // support for it. 164 165 // This code must be kept in sync with Clang's Darwin specific argument 166 // translation. 167 168 if (Str == "ppc" || Str == "ppc601" || Str == "ppc603" || Str == "ppc604" || 169 Str == "ppc604e" || Str == "ppc750" || Str == "ppc7400" || 170 Str == "ppc7450" || Str == "ppc970") 171 return Triple::ppc; 172 173 if (Str == "ppc64") 174 return Triple::ppc64; 175 176 if (Str == "i386" || Str == "i486" || Str == "i486SX" || Str == "pentium" || 177 Str == "i586" || Str == "pentpro" || Str == "i686" || Str == "pentIIm3" || 178 Str == "pentIIm5" || Str == "pentium4") 179 return Triple::x86; 180 181 if (Str == "x86_64") 182 return Triple::x86_64; 183 184 // This is derived from the driver driver. 185 if (Str == "arm" || Str == "armv4t" || Str == "armv5" || Str == "xscale" || 186 Str == "armv6" || Str == "armv7") 187 return Triple::arm; 188 189 return Triple::UnknownArch; 190 } 191 192 // Returns architecture name that is understood by the target assembler. 193 const char *Triple::getArchNameForAssembler() { 194 if (getOS() != Triple::Darwin && getVendor() != Triple::Apple) 195 return NULL; 196 197 StringRef Str = getArchName(); 198 if (Str == "i386") 199 return "i386"; 200 if (Str == "x86_64") 201 return "x86_64"; 202 if (Str == "powerpc") 203 return "ppc"; 204 if (Str == "powerpc64") 205 return "ppc64"; 206 if (Str == "mblaze" || Str == "microblaze") 207 return "mblaze"; 208 if (Str == "arm") 209 return "arm"; 210 if (Str == "armv4t" || Str == "thumbv4t") 211 return "armv4t"; 212 if (Str == "armv5" || Str == "armv5e" || Str == "thumbv5" || Str == "thumbv5e") 213 return "armv5"; 214 if (Str == "armv6" || Str == "thumbv6") 215 return "armv6"; 216 if (Str == "armv7" || Str == "thumbv7") 217 return "armv7"; 218 return NULL; 219 } 220 221 // 222 223 void Triple::Parse() const { 224 assert(!isInitialized() && "Invalid parse call."); 225 226 StringRef ArchName = getArchName(); 227 StringRef VendorName = getVendorName(); 228 StringRef OSName = getOSName(); 229 230 if (ArchName.size() == 4 && ArchName[0] == 'i' && 231 ArchName[2] == '8' && ArchName[3] == '6' && 232 ArchName[1] - '3' < 6) // i[3-9]86 233 Arch = x86; 234 else if (ArchName == "amd64" || ArchName == "x86_64") 235 Arch = x86_64; 236 else if (ArchName == "bfin") 237 Arch = bfin; 238 else if (ArchName == "pic16") 239 Arch = pic16; 240 else if (ArchName == "powerpc") 241 Arch = ppc; 242 else if ((ArchName == "powerpc64") || (ArchName == "ppu")) 243 Arch = ppc64; 244 else if (ArchName == "mblaze") 245 Arch = mblaze; 246 else if (ArchName == "arm" || 247 ArchName.startswith("armv") || 248 ArchName == "xscale") 249 Arch = arm; 250 else if (ArchName == "thumb" || 251 ArchName.startswith("thumbv")) 252 Arch = thumb; 253 else if (ArchName.startswith("alpha")) 254 Arch = alpha; 255 else if (ArchName == "spu" || ArchName == "cellspu") 256 Arch = cellspu; 257 else if (ArchName == "msp430") 258 Arch = msp430; 259 else if (ArchName == "mips" || ArchName == "mipsallegrex") 260 Arch = mips; 261 else if (ArchName == "mipsel" || ArchName == "mipsallegrexel" || 262 ArchName == "psp") 263 Arch = mipsel; 264 else if (ArchName == "sparc") 265 Arch = sparc; 266 else if (ArchName == "sparcv9") 267 Arch = sparcv9; 268 else if (ArchName == "s390x") 269 Arch = systemz; 270 else if (ArchName == "tce") 271 Arch = tce; 272 else if (ArchName == "xcore") 273 Arch = xcore; 274 else 275 Arch = UnknownArch; 276 277 278 // Handle some exceptional cases where the OS / environment components are 279 // stuck into the vendor field. 280 if (StringRef(getTriple()).count('-') == 1) { 281 StringRef VendorName = getVendorName(); 282 283 if (VendorName.startswith("mingw32")) { // 'i386-mingw32', etc. 284 Vendor = PC; 285 OS = MinGW32; 286 return; 287 } 288 289 // arm-elf is another example, but we don't currently parse anything about 290 // the environment. 291 } 292 293 if (VendorName == "apple") 294 Vendor = Apple; 295 else if (VendorName == "pc") 296 Vendor = PC; 297 else 298 Vendor = UnknownVendor; 299 300 if (OSName.startswith("auroraux")) 301 OS = AuroraUX; 302 else if (OSName.startswith("cygwin")) 303 OS = Cygwin; 304 else if (OSName.startswith("darwin")) 305 OS = Darwin; 306 else if (OSName.startswith("dragonfly")) 307 OS = DragonFly; 308 else if (OSName.startswith("freebsd")) 309 OS = FreeBSD; 310 else if (OSName.startswith("linux")) 311 OS = Linux; 312 else if (OSName.startswith("lv2")) 313 OS = Lv2; 314 else if (OSName.startswith("mingw32")) 315 OS = MinGW32; 316 else if (OSName.startswith("mingw64")) 317 OS = MinGW64; 318 else if (OSName.startswith("netbsd")) 319 OS = NetBSD; 320 else if (OSName.startswith("openbsd")) 321 OS = OpenBSD; 322 else if (OSName.startswith("psp")) 323 OS = Psp; 324 else if (OSName.startswith("solaris")) 325 OS = Solaris; 326 else if (OSName.startswith("win32")) 327 OS = Win32; 328 else if (OSName.startswith("haiku")) 329 OS = Haiku; 330 else 331 OS = UnknownOS; 332 333 assert(isInitialized() && "Failed to initialize!"); 334 } 335 336 StringRef Triple::getArchName() const { 337 return StringRef(Data).split('-').first; // Isolate first component 338 } 339 340 StringRef Triple::getVendorName() const { 341 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 342 return Tmp.split('-').first; // Isolate second component 343 } 344 345 StringRef Triple::getOSName() const { 346 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 347 Tmp = Tmp.split('-').second; // Strip second component 348 return Tmp.split('-').first; // Isolate third component 349 } 350 351 StringRef Triple::getEnvironmentName() const { 352 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 353 Tmp = Tmp.split('-').second; // Strip second component 354 return Tmp.split('-').second; // Strip third component 355 } 356 357 StringRef Triple::getOSAndEnvironmentName() const { 358 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 359 return Tmp.split('-').second; // Strip second component 360 } 361 362 static unsigned EatNumber(StringRef &Str) { 363 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number"); 364 unsigned Result = Str[0]-'0'; 365 366 // Eat the digit. 367 Str = Str.substr(1); 368 369 // Handle "darwin11". 370 if (Result == 1 && !Str.empty() && Str[0] >= '0' && Str[0] <= '9') { 371 Result = Result*10 + (Str[0] - '0'); 372 // Eat the digit. 373 Str = Str.substr(1); 374 } 375 376 return Result; 377 } 378 379 /// getDarwinNumber - Parse the 'darwin number' out of the specific target 380 /// triple. For example, if we have darwin8.5 return 8,5,0. If any entry is 381 /// not defined, return 0's. This requires that the triple have an OSType of 382 /// darwin before it is called. 383 void Triple::getDarwinNumber(unsigned &Maj, unsigned &Min, 384 unsigned &Revision) const { 385 assert(getOS() == Darwin && "Not a darwin target triple!"); 386 StringRef OSName = getOSName(); 387 assert(OSName.startswith("darwin") && "Unknown darwin target triple!"); 388 389 // Strip off "darwin". 390 OSName = OSName.substr(6); 391 392 Maj = Min = Revision = 0; 393 394 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9') 395 return; 396 397 // The major version is the first digit. 398 Maj = EatNumber(OSName); 399 if (OSName.empty()) return; 400 401 // Handle minor version: 10.4.9 -> darwin8.9. 402 if (OSName[0] != '.') 403 return; 404 405 // Eat the '.'. 406 OSName = OSName.substr(1); 407 408 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9') 409 return; 410 411 Min = EatNumber(OSName); 412 if (OSName.empty()) return; 413 414 // Handle revision darwin8.9.1 415 if (OSName[0] != '.') 416 return; 417 418 // Eat the '.'. 419 OSName = OSName.substr(1); 420 421 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9') 422 return; 423 424 Revision = EatNumber(OSName); 425 } 426 427 void Triple::setTriple(const Twine &Str) { 428 Data = Str.str(); 429 Arch = InvalidArch; 430 } 431 432 void Triple::setArch(ArchType Kind) { 433 setArchName(getArchTypeName(Kind)); 434 } 435 436 void Triple::setVendor(VendorType Kind) { 437 setVendorName(getVendorTypeName(Kind)); 438 } 439 440 void Triple::setOS(OSType Kind) { 441 setOSName(getOSTypeName(Kind)); 442 } 443 444 void Triple::setArchName(StringRef Str) { 445 // Work around a miscompilation bug for Twines in gcc 4.0.3. 446 SmallString<64> Triple; 447 Triple += Str; 448 Triple += "-"; 449 Triple += getVendorName(); 450 Triple += "-"; 451 Triple += getOSAndEnvironmentName(); 452 setTriple(Triple.str()); 453 } 454 455 void Triple::setVendorName(StringRef Str) { 456 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName()); 457 } 458 459 void Triple::setOSName(StringRef Str) { 460 if (hasEnvironment()) 461 setTriple(getArchName() + "-" + getVendorName() + "-" + Str + 462 "-" + getEnvironmentName()); 463 else 464 setTriple(getArchName() + "-" + getVendorName() + "-" + Str); 465 } 466 467 void Triple::setEnvironmentName(StringRef Str) { 468 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() + 469 "-" + Str); 470 } 471 472 void Triple::setOSAndEnvironmentName(StringRef Str) { 473 setTriple(getArchName() + "-" + getVendorName() + "-" + Str); 474 } 475