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/STLExtras.h" 14 #include "llvm/ADT/Twine.h" 15 #include <cassert> 16 #include <cstring> 17 using namespace llvm; 18 19 // 20 21 const char *Triple::getArchTypeName(ArchType Kind) { 22 switch (Kind) { 23 case InvalidArch: return "<invalid>"; 24 case UnknownArch: return "unknown"; 25 26 case alpha: return "alpha"; 27 case arm: return "arm"; 28 case bfin: return "bfin"; 29 case cellspu: return "cellspu"; 30 case mips: return "mips"; 31 case mipsel: return "mipsel"; 32 case msp430: return "msp430"; 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 case ptx: return "ptx"; 45 } 46 47 return "<invalid>"; 48 } 49 50 const char *Triple::getArchTypePrefix(ArchType Kind) { 51 switch (Kind) { 52 default: 53 return 0; 54 55 case alpha: return "alpha"; 56 57 case arm: 58 case thumb: return "arm"; 59 60 case bfin: return "bfin"; 61 62 case cellspu: return "spu"; 63 64 case ppc64: 65 case ppc: return "ppc"; 66 67 case mblaze: return "mblaze"; 68 69 case sparcv9: 70 case sparc: return "sparc"; 71 72 case x86: 73 case x86_64: return "x86"; 74 75 case xcore: return "xcore"; 76 77 case ptx: return "ptx"; 78 } 79 } 80 81 const char *Triple::getVendorTypeName(VendorType Kind) { 82 switch (Kind) { 83 case UnknownVendor: return "unknown"; 84 85 case Apple: return "apple"; 86 case PC: return "pc"; 87 } 88 89 return "<invalid>"; 90 } 91 92 const char *Triple::getOSTypeName(OSType Kind) { 93 switch (Kind) { 94 case UnknownOS: return "unknown"; 95 96 case AuroraUX: return "auroraux"; 97 case Cygwin: return "cygwin"; 98 case Darwin: return "darwin"; 99 case DragonFly: return "dragonfly"; 100 case FreeBSD: return "freebsd"; 101 case Linux: return "linux"; 102 case Lv2: return "lv2"; 103 case MinGW32: return "mingw32"; 104 case MinGW64: return "mingw64"; 105 case NetBSD: return "netbsd"; 106 case OpenBSD: return "openbsd"; 107 case Psp: return "psp"; 108 case Solaris: return "solaris"; 109 case Win32: return "win32"; 110 case Haiku: return "haiku"; 111 case Minix: return "minix"; 112 } 113 114 return "<invalid>"; 115 } 116 117 const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) { 118 switch (Kind) { 119 case UnknownEnvironment: return "unknown"; 120 } 121 122 return "<invalid>"; 123 } 124 125 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) { 126 if (Name == "alpha") 127 return alpha; 128 if (Name == "arm") 129 return arm; 130 if (Name == "bfin") 131 return bfin; 132 if (Name == "cellspu") 133 return cellspu; 134 if (Name == "mips") 135 return mips; 136 if (Name == "mipsel") 137 return mipsel; 138 if (Name == "msp430") 139 return msp430; 140 if (Name == "ppc64") 141 return ppc64; 142 if (Name == "ppc") 143 return ppc; 144 if (Name == "mblaze") 145 return mblaze; 146 if (Name == "sparc") 147 return sparc; 148 if (Name == "sparcv9") 149 return sparcv9; 150 if (Name == "systemz") 151 return systemz; 152 if (Name == "tce") 153 return tce; 154 if (Name == "thumb") 155 return thumb; 156 if (Name == "x86") 157 return x86; 158 if (Name == "x86-64") 159 return x86_64; 160 if (Name == "xcore") 161 return xcore; 162 if (Name == "ptx") 163 return ptx; 164 165 return UnknownArch; 166 } 167 168 Triple::ArchType Triple::getArchTypeForDarwinArchName(StringRef Str) { 169 // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for 170 // archs which Darwin doesn't use. 171 172 // The matching this routine does is fairly pointless, since it is neither the 173 // complete architecture list, nor a reasonable subset. The problem is that 174 // historically the driver driver accepts this and also ties its -march= 175 // handling to the architecture name, so we need to be careful before removing 176 // support for it. 177 178 // This code must be kept in sync with Clang's Darwin specific argument 179 // translation. 180 181 if (Str == "ppc" || Str == "ppc601" || Str == "ppc603" || Str == "ppc604" || 182 Str == "ppc604e" || Str == "ppc750" || Str == "ppc7400" || 183 Str == "ppc7450" || Str == "ppc970") 184 return Triple::ppc; 185 186 if (Str == "ppc64") 187 return Triple::ppc64; 188 189 if (Str == "i386" || Str == "i486" || Str == "i486SX" || Str == "pentium" || 190 Str == "i586" || Str == "pentpro" || Str == "i686" || Str == "pentIIm3" || 191 Str == "pentIIm5" || Str == "pentium4") 192 return Triple::x86; 193 194 if (Str == "x86_64") 195 return Triple::x86_64; 196 197 // This is derived from the driver driver. 198 if (Str == "arm" || Str == "armv4t" || Str == "armv5" || Str == "xscale" || 199 Str == "armv6" || Str == "armv7") 200 return Triple::arm; 201 202 if (Str == "ptx") 203 return Triple::ptx; 204 205 return Triple::UnknownArch; 206 } 207 208 // Returns architecture name that is understood by the target assembler. 209 const char *Triple::getArchNameForAssembler() { 210 if (getOS() != Triple::Darwin && getVendor() != Triple::Apple) 211 return NULL; 212 213 StringRef Str = getArchName(); 214 if (Str == "i386") 215 return "i386"; 216 if (Str == "x86_64") 217 return "x86_64"; 218 if (Str == "powerpc") 219 return "ppc"; 220 if (Str == "powerpc64") 221 return "ppc64"; 222 if (Str == "mblaze" || Str == "microblaze") 223 return "mblaze"; 224 if (Str == "arm") 225 return "arm"; 226 if (Str == "armv4t" || Str == "thumbv4t") 227 return "armv4t"; 228 if (Str == "armv5" || Str == "armv5e" || Str == "thumbv5" 229 || Str == "thumbv5e") 230 return "armv5"; 231 if (Str == "armv6" || Str == "thumbv6") 232 return "armv6"; 233 if (Str == "armv7" || Str == "thumbv7") 234 return "armv7"; 235 if (Str == "ptx") 236 return "ptx"; 237 return NULL; 238 } 239 240 // 241 242 Triple::ArchType Triple::ParseArch(StringRef ArchName) { 243 if (ArchName.size() == 4 && ArchName[0] == 'i' && 244 ArchName[2] == '8' && ArchName[3] == '6' && 245 ArchName[1] - '3' < 6) // i[3-9]86 246 return x86; 247 else if (ArchName == "amd64" || ArchName == "x86_64") 248 return x86_64; 249 else if (ArchName == "bfin") 250 return bfin; 251 else if (ArchName == "powerpc") 252 return ppc; 253 else if ((ArchName == "powerpc64") || (ArchName == "ppu")) 254 return ppc64; 255 else if (ArchName == "mblaze") 256 return mblaze; 257 else if (ArchName == "arm" || 258 ArchName.startswith("armv") || 259 ArchName == "xscale") 260 return arm; 261 else if (ArchName == "thumb" || 262 ArchName.startswith("thumbv")) 263 return thumb; 264 else if (ArchName.startswith("alpha")) 265 return alpha; 266 else if (ArchName == "spu" || ArchName == "cellspu") 267 return cellspu; 268 else if (ArchName == "msp430") 269 return msp430; 270 else if (ArchName == "mips" || ArchName == "mipsallegrex") 271 return mips; 272 else if (ArchName == "mipsel" || ArchName == "mipsallegrexel" || 273 ArchName == "psp") 274 return mipsel; 275 else if (ArchName == "sparc") 276 return sparc; 277 else if (ArchName == "sparcv9") 278 return sparcv9; 279 else if (ArchName == "s390x") 280 return systemz; 281 else if (ArchName == "tce") 282 return tce; 283 else if (ArchName == "xcore") 284 return xcore; 285 else if (ArchName == "ptx") 286 return ptx; 287 else 288 return UnknownArch; 289 } 290 291 Triple::VendorType Triple::ParseVendor(StringRef VendorName) { 292 if (VendorName == "apple") 293 return Apple; 294 else if (VendorName == "pc") 295 return PC; 296 else 297 return UnknownVendor; 298 } 299 300 Triple::OSType Triple::ParseOS(StringRef OSName) { 301 if (OSName.startswith("auroraux")) 302 return AuroraUX; 303 else if (OSName.startswith("cygwin")) 304 return Cygwin; 305 else if (OSName.startswith("darwin")) 306 return Darwin; 307 else if (OSName.startswith("dragonfly")) 308 return DragonFly; 309 else if (OSName.startswith("freebsd")) 310 return FreeBSD; 311 else if (OSName.startswith("linux")) 312 return Linux; 313 else if (OSName.startswith("lv2")) 314 return Lv2; 315 else if (OSName.startswith("mingw32")) 316 return MinGW32; 317 else if (OSName.startswith("mingw64")) 318 return MinGW64; 319 else if (OSName.startswith("netbsd")) 320 return NetBSD; 321 else if (OSName.startswith("openbsd")) 322 return OpenBSD; 323 else if (OSName.startswith("psp")) 324 return Psp; 325 else if (OSName.startswith("solaris")) 326 return Solaris; 327 else if (OSName.startswith("win32")) 328 return Win32; 329 else if (OSName.startswith("haiku")) 330 return Haiku; 331 else if (OSName.startswith("minix")) 332 return Minix; 333 else 334 return UnknownOS; 335 } 336 337 Triple::EnvironmentType Triple::ParseEnvironment(StringRef EnvironmentName) { 338 return UnknownEnvironment; 339 } 340 341 void Triple::Parse() const { 342 assert(!isInitialized() && "Invalid parse call."); 343 344 Arch = ParseArch(getArchName()); 345 Vendor = ParseVendor(getVendorName()); 346 OS = ParseOS(getOSName()); 347 Environment = ParseEnvironment(getEnvironmentName()); 348 349 assert(isInitialized() && "Failed to initialize!"); 350 } 351 352 std::string Triple::normalize(StringRef Str) { 353 // Parse into components. 354 SmallVector<StringRef, 4> Components; 355 for (size_t First = 0, Last = 0; Last != StringRef::npos; First = Last + 1) { 356 Last = Str.find('-', First); 357 Components.push_back(Str.slice(First, Last)); 358 } 359 360 // If the first component corresponds to a known architecture, preferentially 361 // use it for the architecture. If the second component corresponds to a 362 // known vendor, preferentially use it for the vendor, etc. This avoids silly 363 // component movement when a component parses as (eg) both a valid arch and a 364 // valid os. 365 ArchType Arch = UnknownArch; 366 if (Components.size() > 0) 367 Arch = ParseArch(Components[0]); 368 VendorType Vendor = UnknownVendor; 369 if (Components.size() > 1) 370 Vendor = ParseVendor(Components[1]); 371 OSType OS = UnknownOS; 372 if (Components.size() > 2) 373 OS = ParseOS(Components[2]); 374 EnvironmentType Environment = UnknownEnvironment; 375 if (Components.size() > 3) 376 Environment = ParseEnvironment(Components[3]); 377 378 // Note which components are already in their final position. These will not 379 // be moved. 380 bool Found[4]; 381 Found[0] = Arch != UnknownArch; 382 Found[1] = Vendor != UnknownVendor; 383 Found[2] = OS != UnknownOS; 384 Found[3] = Environment != UnknownEnvironment; 385 386 // If they are not there already, permute the components into their canonical 387 // positions by seeing if they parse as a valid architecture, and if so moving 388 // the component to the architecture position etc. 389 for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) { 390 if (Found[Pos]) 391 continue; // Already in the canonical position. 392 393 for (unsigned Idx = 0; Idx != Components.size(); ++Idx) { 394 // Do not reparse any components that already matched. 395 if (Idx < array_lengthof(Found) && Found[Idx]) 396 continue; 397 398 // Does this component parse as valid for the target position? 399 bool Valid = false; 400 StringRef Comp = Components[Idx]; 401 switch (Pos) { 402 default: 403 assert(false && "unexpected component type!"); 404 case 0: 405 Arch = ParseArch(Comp); 406 Valid = Arch != UnknownArch; 407 break; 408 case 1: 409 Vendor = ParseVendor(Comp); 410 Valid = Vendor != UnknownVendor; 411 break; 412 case 2: 413 OS = ParseOS(Comp); 414 Valid = OS != UnknownOS; 415 break; 416 case 3: 417 Environment = ParseEnvironment(Comp); 418 Valid = Environment != UnknownEnvironment; 419 break; 420 } 421 if (!Valid) 422 continue; // Nope, try the next component. 423 424 // Move the component to the target position, pushing any non-fixed 425 // components that are in the way to the right. This tends to give 426 // good results in the common cases of a forgotten vendor component 427 // or a wrongly positioned environment. 428 if (Pos < Idx) { 429 // Insert left, pushing the existing components to the right. For 430 // example, a-b-i386 -> i386-a-b when moving i386 to the front. 431 StringRef CurrentComponent(""); // The empty component. 432 // Replace the component we are moving with an empty component. 433 std::swap(CurrentComponent, Components[Idx]); 434 // Insert the component being moved at Pos, displacing any existing 435 // components to the right. 436 for (unsigned i = Pos; !CurrentComponent.empty(); ++i) { 437 // Skip over any fixed components. 438 while (i < array_lengthof(Found) && Found[i]) ++i; 439 // Place the component at the new position, getting the component 440 // that was at this position - it will be moved right. 441 std::swap(CurrentComponent, Components[i]); 442 } 443 } else if (Pos > Idx) { 444 // Push right by inserting empty components until the component at Idx 445 // reaches the target position Pos. For example, pc-a -> -pc-a when 446 // moving pc to the second position. 447 do { 448 // Insert one empty component at Idx. 449 StringRef CurrentComponent(""); // The empty component. 450 for (unsigned i = Idx; i < Components.size(); ++i) { 451 // Skip over any fixed components. 452 while (i < array_lengthof(Found) && Found[i]) ++i; 453 // Place the component at the new position, getting the component 454 // that was at this position - it will be moved right. 455 std::swap(CurrentComponent, Components[i]); 456 // If it was placed on top of an empty component then we are done. 457 if (CurrentComponent.empty()) 458 break; 459 } 460 // The last component was pushed off the end - append it. 461 if (!CurrentComponent.empty()) 462 Components.push_back(CurrentComponent); 463 464 // Advance Idx to the component's new position. 465 while (++Idx < array_lengthof(Found) && Found[Idx]) {} 466 } while (Idx < Pos); // Add more until the final position is reached. 467 } 468 assert(Pos < Components.size() && Components[Pos] == Comp && 469 "Component moved wrong!"); 470 Found[Pos] = true; 471 break; 472 } 473 } 474 475 // Special case logic goes here. At this point Arch, Vendor and OS have the 476 // correct values for the computed components. 477 478 // Stick the corrected components back together to form the normalized string. 479 std::string Normalized; 480 for (unsigned i = 0, e = Components.size(); i != e; ++i) { 481 if (i) Normalized += '-'; 482 Normalized += Components[i]; 483 } 484 return Normalized; 485 } 486 487 StringRef Triple::getArchName() const { 488 return StringRef(Data).split('-').first; // Isolate first component 489 } 490 491 StringRef Triple::getVendorName() const { 492 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 493 return Tmp.split('-').first; // Isolate second component 494 } 495 496 StringRef Triple::getOSName() const { 497 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 498 Tmp = Tmp.split('-').second; // Strip second component 499 return Tmp.split('-').first; // Isolate third component 500 } 501 502 StringRef Triple::getEnvironmentName() const { 503 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 504 Tmp = Tmp.split('-').second; // Strip second component 505 return Tmp.split('-').second; // Strip third component 506 } 507 508 StringRef Triple::getOSAndEnvironmentName() const { 509 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 510 return Tmp.split('-').second; // Strip second component 511 } 512 513 static unsigned EatNumber(StringRef &Str) { 514 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number"); 515 unsigned Result = Str[0]-'0'; 516 517 // Eat the digit. 518 Str = Str.substr(1); 519 520 // Handle "darwin11". 521 if (Result == 1 && !Str.empty() && Str[0] >= '0' && Str[0] <= '9') { 522 Result = Result*10 + (Str[0] - '0'); 523 // Eat the digit. 524 Str = Str.substr(1); 525 } 526 527 return Result; 528 } 529 530 /// getDarwinNumber - Parse the 'darwin number' out of the specific target 531 /// triple. For example, if we have darwin8.5 return 8,5,0. If any entry is 532 /// not defined, return 0's. This requires that the triple have an OSType of 533 /// darwin before it is called. 534 void Triple::getDarwinNumber(unsigned &Maj, unsigned &Min, 535 unsigned &Revision) const { 536 assert(getOS() == Darwin && "Not a darwin target triple!"); 537 StringRef OSName = getOSName(); 538 assert(OSName.startswith("darwin") && "Unknown darwin target triple!"); 539 540 // Strip off "darwin". 541 OSName = OSName.substr(6); 542 543 Maj = Min = Revision = 0; 544 545 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9') 546 return; 547 548 // The major version is the first digit. 549 Maj = EatNumber(OSName); 550 if (OSName.empty()) return; 551 552 // Handle minor version: 10.4.9 -> darwin8.9. 553 if (OSName[0] != '.') 554 return; 555 556 // Eat the '.'. 557 OSName = OSName.substr(1); 558 559 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9') 560 return; 561 562 Min = EatNumber(OSName); 563 if (OSName.empty()) return; 564 565 // Handle revision darwin8.9.1 566 if (OSName[0] != '.') 567 return; 568 569 // Eat the '.'. 570 OSName = OSName.substr(1); 571 572 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9') 573 return; 574 575 Revision = EatNumber(OSName); 576 } 577 578 void Triple::setTriple(const Twine &Str) { 579 Data = Str.str(); 580 Arch = InvalidArch; 581 } 582 583 void Triple::setArch(ArchType Kind) { 584 setArchName(getArchTypeName(Kind)); 585 } 586 587 void Triple::setVendor(VendorType Kind) { 588 setVendorName(getVendorTypeName(Kind)); 589 } 590 591 void Triple::setOS(OSType Kind) { 592 setOSName(getOSTypeName(Kind)); 593 } 594 595 void Triple::setEnvironment(EnvironmentType Kind) { 596 setEnvironmentName(getEnvironmentTypeName(Kind)); 597 } 598 599 void Triple::setArchName(StringRef Str) { 600 // Work around a miscompilation bug for Twines in gcc 4.0.3. 601 SmallString<64> Triple; 602 Triple += Str; 603 Triple += "-"; 604 Triple += getVendorName(); 605 Triple += "-"; 606 Triple += getOSAndEnvironmentName(); 607 setTriple(Triple.str()); 608 } 609 610 void Triple::setVendorName(StringRef Str) { 611 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName()); 612 } 613 614 void Triple::setOSName(StringRef Str) { 615 if (hasEnvironment()) 616 setTriple(getArchName() + "-" + getVendorName() + "-" + Str + 617 "-" + getEnvironmentName()); 618 else 619 setTriple(getArchName() + "-" + getVendorName() + "-" + Str); 620 } 621 622 void Triple::setEnvironmentName(StringRef Str) { 623 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() + 624 "-" + Str); 625 } 626 627 void Triple::setOSAndEnvironmentName(StringRef Str) { 628 setTriple(getArchName() + "-" + getVendorName() + "-" + Str); 629 } 630