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