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 #include "llvm/ADT/STLExtras.h" 12 #include "llvm/ADT/SmallString.h" 13 #include "llvm/ADT/StringSwitch.h" 14 #include "llvm/Support/ErrorHandling.h" 15 #include <cstring> 16 using namespace llvm; 17 18 const char *Triple::getArchTypeName(ArchType Kind) { 19 switch (Kind) { 20 case UnknownArch: return "unknown"; 21 22 case aarch64: return "aarch64"; 23 case aarch64_be: return "aarch64_be"; 24 case arm: return "arm"; 25 case armeb: return "armeb"; 26 case hexagon: return "hexagon"; 27 case mips: return "mips"; 28 case mipsel: return "mipsel"; 29 case mips64: return "mips64"; 30 case mips64el: return "mips64el"; 31 case msp430: return "msp430"; 32 case ppc64: return "powerpc64"; 33 case ppc64le: return "powerpc64le"; 34 case ppc: return "powerpc"; 35 case r600: return "r600"; 36 case sparc: return "sparc"; 37 case sparcv9: return "sparcv9"; 38 case systemz: return "s390x"; 39 case tce: return "tce"; 40 case thumb: return "thumb"; 41 case thumbeb: return "thumbeb"; 42 case x86: return "i386"; 43 case x86_64: return "x86_64"; 44 case xcore: return "xcore"; 45 case nvptx: return "nvptx"; 46 case nvptx64: return "nvptx64"; 47 case le32: return "le32"; 48 case le64: return "le64"; 49 case amdil: return "amdil"; 50 case amdil64: return "amdil64"; 51 case hsail: return "hsail"; 52 case hsail64: return "hsail64"; 53 case spir: return "spir"; 54 case spir64: return "spir64"; 55 case kalimba: return "kalimba"; 56 } 57 58 llvm_unreachable("Invalid ArchType!"); 59 } 60 61 const char *Triple::getArchTypePrefix(ArchType Kind) { 62 switch (Kind) { 63 default: 64 return nullptr; 65 66 case aarch64: 67 case aarch64_be: return "aarch64"; 68 69 case arm: 70 case armeb: 71 case thumb: 72 case thumbeb: return "arm"; 73 74 case ppc64: 75 case ppc64le: 76 case ppc: return "ppc"; 77 78 case mips: 79 case mipsel: 80 case mips64: 81 case mips64el: return "mips"; 82 83 case hexagon: return "hexagon"; 84 85 case r600: return "r600"; 86 87 case sparcv9: 88 case sparc: return "sparc"; 89 90 case systemz: return "systemz"; 91 92 case x86: 93 case x86_64: return "x86"; 94 95 case xcore: return "xcore"; 96 97 case nvptx: return "nvptx"; 98 case nvptx64: return "nvptx"; 99 100 case le32: return "le32"; 101 case le64: return "le64"; 102 103 case amdil: 104 case amdil64: return "amdil"; 105 106 case hsail: 107 case hsail64: return "hsail"; 108 109 case spir: 110 case spir64: return "spir"; 111 case kalimba: return "kalimba"; 112 } 113 } 114 115 const char *Triple::getVendorTypeName(VendorType Kind) { 116 switch (Kind) { 117 case UnknownVendor: return "unknown"; 118 119 case Apple: return "apple"; 120 case PC: return "pc"; 121 case SCEI: return "scei"; 122 case BGP: return "bgp"; 123 case BGQ: return "bgq"; 124 case Freescale: return "fsl"; 125 case IBM: return "ibm"; 126 case ImaginationTechnologies: return "img"; 127 case MipsTechnologies: return "mti"; 128 case NVIDIA: return "nvidia"; 129 case CSR: return "csr"; 130 } 131 132 llvm_unreachable("Invalid VendorType!"); 133 } 134 135 const char *Triple::getOSTypeName(OSType Kind) { 136 switch (Kind) { 137 case UnknownOS: return "unknown"; 138 139 case Darwin: return "darwin"; 140 case DragonFly: return "dragonfly"; 141 case FreeBSD: return "freebsd"; 142 case IOS: return "ios"; 143 case KFreeBSD: return "kfreebsd"; 144 case Linux: return "linux"; 145 case Lv2: return "lv2"; 146 case MacOSX: return "macosx"; 147 case NetBSD: return "netbsd"; 148 case OpenBSD: return "openbsd"; 149 case Solaris: return "solaris"; 150 case Win32: return "windows"; 151 case Haiku: return "haiku"; 152 case Minix: return "minix"; 153 case RTEMS: return "rtems"; 154 case NaCl: return "nacl"; 155 case CNK: return "cnk"; 156 case Bitrig: return "bitrig"; 157 case AIX: return "aix"; 158 case CUDA: return "cuda"; 159 case NVCL: return "nvcl"; 160 } 161 162 llvm_unreachable("Invalid OSType"); 163 } 164 165 const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) { 166 switch (Kind) { 167 case UnknownEnvironment: return "unknown"; 168 case GNU: return "gnu"; 169 case GNUEABIHF: return "gnueabihf"; 170 case GNUEABI: return "gnueabi"; 171 case GNUX32: return "gnux32"; 172 case CODE16: return "code16"; 173 case EABI: return "eabi"; 174 case EABIHF: return "eabihf"; 175 case Android: return "android"; 176 case MSVC: return "msvc"; 177 case Itanium: return "itanium"; 178 case Cygnus: return "cygnus"; 179 } 180 181 llvm_unreachable("Invalid EnvironmentType!"); 182 } 183 184 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) { 185 return StringSwitch<Triple::ArchType>(Name) 186 .Case("aarch64", aarch64) 187 .Case("aarch64_be", aarch64_be) 188 .Case("arm64", aarch64) // "arm64" is an alias for "aarch64" 189 .Case("arm", arm) 190 .Case("armeb", armeb) 191 .Case("mips", mips) 192 .Case("mipsel", mipsel) 193 .Case("mips64", mips64) 194 .Case("mips64el", mips64el) 195 .Case("msp430", msp430) 196 .Case("ppc64", ppc64) 197 .Case("ppc32", ppc) 198 .Case("ppc", ppc) 199 .Case("ppc64le", ppc64le) 200 .Case("r600", r600) 201 .Case("hexagon", hexagon) 202 .Case("sparc", sparc) 203 .Case("sparcv9", sparcv9) 204 .Case("systemz", systemz) 205 .Case("tce", tce) 206 .Case("thumb", thumb) 207 .Case("thumbeb", thumbeb) 208 .Case("x86", x86) 209 .Case("x86-64", x86_64) 210 .Case("xcore", xcore) 211 .Case("nvptx", nvptx) 212 .Case("nvptx64", nvptx64) 213 .Case("le32", le32) 214 .Case("le64", le64) 215 .Case("amdil", amdil) 216 .Case("amdil64", amdil64) 217 .Case("hsail", hsail) 218 .Case("hsail64", hsail64) 219 .Case("spir", spir) 220 .Case("spir64", spir64) 221 .Case("kalimba", kalimba) 222 .Default(UnknownArch); 223 } 224 225 static Triple::ArchType parseArch(StringRef ArchName) { 226 return StringSwitch<Triple::ArchType>(ArchName) 227 .Cases("i386", "i486", "i586", "i686", Triple::x86) 228 // FIXME: Do we need to support these? 229 .Cases("i786", "i886", "i986", Triple::x86) 230 .Cases("amd64", "x86_64", "x86_64h", Triple::x86_64) 231 .Case("powerpc", Triple::ppc) 232 .Cases("powerpc64", "ppu", Triple::ppc64) 233 .Case("powerpc64le", Triple::ppc64le) 234 .Case("aarch64", Triple::aarch64) 235 .Case("aarch64_be", Triple::aarch64_be) 236 .Case("arm64", Triple::aarch64) 237 .Cases("arm", "xscale", Triple::arm) 238 // FIXME: It would be good to replace these with explicit names for all the 239 // various suffixes supported. 240 .StartsWith("armv", Triple::arm) 241 .Case("armeb", Triple::armeb) 242 .StartsWith("armebv", Triple::armeb) 243 .Case("thumb", Triple::thumb) 244 .StartsWith("thumbv", Triple::thumb) 245 .Case("thumbeb", Triple::thumbeb) 246 .StartsWith("thumbebv", Triple::thumbeb) 247 .Case("msp430", Triple::msp430) 248 .Cases("mips", "mipseb", "mipsallegrex", Triple::mips) 249 .Cases("mipsel", "mipsallegrexel", Triple::mipsel) 250 .Cases("mips64", "mips64eb", Triple::mips64) 251 .Case("mips64el", Triple::mips64el) 252 .Case("r600", Triple::r600) 253 .Case("hexagon", Triple::hexagon) 254 .Case("s390x", Triple::systemz) 255 .Case("sparc", Triple::sparc) 256 .Cases("sparcv9", "sparc64", Triple::sparcv9) 257 .Case("tce", Triple::tce) 258 .Case("xcore", Triple::xcore) 259 .Case("nvptx", Triple::nvptx) 260 .Case("nvptx64", Triple::nvptx64) 261 .Case("le32", Triple::le32) 262 .Case("le64", Triple::le64) 263 .Case("amdil", Triple::amdil) 264 .Case("amdil64", Triple::amdil64) 265 .Case("hsail", Triple::hsail) 266 .Case("hsail64", Triple::hsail64) 267 .Case("spir", Triple::spir) 268 .Case("spir64", Triple::spir64) 269 .StartsWith("kalimba", Triple::kalimba) 270 .Default(Triple::UnknownArch); 271 } 272 273 static Triple::VendorType parseVendor(StringRef VendorName) { 274 return StringSwitch<Triple::VendorType>(VendorName) 275 .Case("apple", Triple::Apple) 276 .Case("pc", Triple::PC) 277 .Case("scei", Triple::SCEI) 278 .Case("bgp", Triple::BGP) 279 .Case("bgq", Triple::BGQ) 280 .Case("fsl", Triple::Freescale) 281 .Case("ibm", Triple::IBM) 282 .Case("img", Triple::ImaginationTechnologies) 283 .Case("mti", Triple::MipsTechnologies) 284 .Case("nvidia", Triple::NVIDIA) 285 .Case("csr", Triple::CSR) 286 .Default(Triple::UnknownVendor); 287 } 288 289 static Triple::OSType parseOS(StringRef OSName) { 290 return StringSwitch<Triple::OSType>(OSName) 291 .StartsWith("darwin", Triple::Darwin) 292 .StartsWith("dragonfly", Triple::DragonFly) 293 .StartsWith("freebsd", Triple::FreeBSD) 294 .StartsWith("ios", Triple::IOS) 295 .StartsWith("kfreebsd", Triple::KFreeBSD) 296 .StartsWith("linux", Triple::Linux) 297 .StartsWith("lv2", Triple::Lv2) 298 .StartsWith("macosx", Triple::MacOSX) 299 .StartsWith("netbsd", Triple::NetBSD) 300 .StartsWith("openbsd", Triple::OpenBSD) 301 .StartsWith("solaris", Triple::Solaris) 302 .StartsWith("win32", Triple::Win32) 303 .StartsWith("windows", Triple::Win32) 304 .StartsWith("haiku", Triple::Haiku) 305 .StartsWith("minix", Triple::Minix) 306 .StartsWith("rtems", Triple::RTEMS) 307 .StartsWith("nacl", Triple::NaCl) 308 .StartsWith("cnk", Triple::CNK) 309 .StartsWith("bitrig", Triple::Bitrig) 310 .StartsWith("aix", Triple::AIX) 311 .StartsWith("cuda", Triple::CUDA) 312 .StartsWith("nvcl", Triple::NVCL) 313 .Default(Triple::UnknownOS); 314 } 315 316 static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) { 317 return StringSwitch<Triple::EnvironmentType>(EnvironmentName) 318 .StartsWith("eabihf", Triple::EABIHF) 319 .StartsWith("eabi", Triple::EABI) 320 .StartsWith("gnueabihf", Triple::GNUEABIHF) 321 .StartsWith("gnueabi", Triple::GNUEABI) 322 .StartsWith("gnux32", Triple::GNUX32) 323 .StartsWith("code16", Triple::CODE16) 324 .StartsWith("gnu", Triple::GNU) 325 .StartsWith("android", Triple::Android) 326 .StartsWith("msvc", Triple::MSVC) 327 .StartsWith("itanium", Triple::Itanium) 328 .StartsWith("cygnus", Triple::Cygnus) 329 .Default(Triple::UnknownEnvironment); 330 } 331 332 static Triple::ObjectFormatType parseFormat(StringRef EnvironmentName) { 333 return StringSwitch<Triple::ObjectFormatType>(EnvironmentName) 334 .EndsWith("coff", Triple::COFF) 335 .EndsWith("elf", Triple::ELF) 336 .EndsWith("macho", Triple::MachO) 337 .Default(Triple::UnknownObjectFormat); 338 } 339 340 static Triple::SubArchType parseSubArch(StringRef SubArchName) { 341 return StringSwitch<Triple::SubArchType>(SubArchName) 342 .EndsWith("v8", Triple::ARMSubArch_v8) 343 .EndsWith("v8a", Triple::ARMSubArch_v8) 344 .EndsWith("v7", Triple::ARMSubArch_v7) 345 .EndsWith("v7a", Triple::ARMSubArch_v7) 346 .EndsWith("v7em", Triple::ARMSubArch_v7em) 347 .EndsWith("v7l", Triple::ARMSubArch_v7) 348 .EndsWith("v7m", Triple::ARMSubArch_v7m) 349 .EndsWith("v7r", Triple::ARMSubArch_v7) 350 .EndsWith("v7s", Triple::ARMSubArch_v7s) 351 .EndsWith("v6", Triple::ARMSubArch_v6) 352 .EndsWith("v6m", Triple::ARMSubArch_v6m) 353 .EndsWith("v6t2", Triple::ARMSubArch_v6t2) 354 .EndsWith("v5", Triple::ARMSubArch_v5) 355 .EndsWith("v5e", Triple::ARMSubArch_v5) 356 .EndsWith("v5t", Triple::ARMSubArch_v5) 357 .EndsWith("v5te", Triple::ARMSubArch_v5te) 358 .EndsWith("v4t", Triple::ARMSubArch_v4t) 359 .EndsWith("kalimba3", Triple::KalimbaSubArch_v3) 360 .EndsWith("kalimba4", Triple::KalimbaSubArch_v4) 361 .EndsWith("kalimba5", Triple::KalimbaSubArch_v5) 362 .Default(Triple::NoSubArch); 363 } 364 365 static const char *getObjectFormatTypeName(Triple::ObjectFormatType Kind) { 366 switch (Kind) { 367 case Triple::UnknownObjectFormat: return ""; 368 case Triple::COFF: return "coff"; 369 case Triple::ELF: return "elf"; 370 case Triple::MachO: return "macho"; 371 } 372 llvm_unreachable("unknown object format type"); 373 } 374 375 static Triple::ObjectFormatType getDefaultFormat(const Triple &T) { 376 if (T.isOSDarwin()) 377 return Triple::MachO; 378 else if (T.isOSWindows()) 379 return Triple::COFF; 380 return Triple::ELF; 381 } 382 383 /// \brief Construct a triple from the string representation provided. 384 /// 385 /// This stores the string representation and parses the various pieces into 386 /// enum members. 387 Triple::Triple(const Twine &Str) 388 : Data(Str.str()), 389 Arch(parseArch(getArchName())), 390 SubArch(parseSubArch(getArchName())), 391 Vendor(parseVendor(getVendorName())), 392 OS(parseOS(getOSName())), 393 Environment(parseEnvironment(getEnvironmentName())), 394 ObjectFormat(parseFormat(getEnvironmentName())) { 395 if (ObjectFormat == Triple::UnknownObjectFormat) 396 ObjectFormat = getDefaultFormat(*this); 397 } 398 399 /// \brief Construct a triple from string representations of the architecture, 400 /// vendor, and OS. 401 /// 402 /// This joins each argument into a canonical string representation and parses 403 /// them into enum members. It leaves the environment unknown and omits it from 404 /// the string representation. 405 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr) 406 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()), 407 Arch(parseArch(ArchStr.str())), 408 SubArch(parseSubArch(ArchStr.str())), 409 Vendor(parseVendor(VendorStr.str())), 410 OS(parseOS(OSStr.str())), 411 Environment(), ObjectFormat(Triple::UnknownObjectFormat) { 412 ObjectFormat = getDefaultFormat(*this); 413 } 414 415 /// \brief Construct a triple from string representations of the architecture, 416 /// vendor, OS, and environment. 417 /// 418 /// This joins each argument into a canonical string representation and parses 419 /// them into enum members. 420 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr, 421 const Twine &EnvironmentStr) 422 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr + Twine('-') + 423 EnvironmentStr).str()), 424 Arch(parseArch(ArchStr.str())), 425 SubArch(parseSubArch(ArchStr.str())), 426 Vendor(parseVendor(VendorStr.str())), 427 OS(parseOS(OSStr.str())), 428 Environment(parseEnvironment(EnvironmentStr.str())), 429 ObjectFormat(parseFormat(EnvironmentStr.str())) { 430 if (ObjectFormat == Triple::UnknownObjectFormat) 431 ObjectFormat = getDefaultFormat(*this); 432 } 433 434 std::string Triple::normalize(StringRef Str) { 435 bool IsMinGW32 = false; 436 bool IsCygwin = false; 437 438 // Parse into components. 439 SmallVector<StringRef, 4> Components; 440 Str.split(Components, "-"); 441 442 // If the first component corresponds to a known architecture, preferentially 443 // use it for the architecture. If the second component corresponds to a 444 // known vendor, preferentially use it for the vendor, etc. This avoids silly 445 // component movement when a component parses as (eg) both a valid arch and a 446 // valid os. 447 ArchType Arch = UnknownArch; 448 if (Components.size() > 0) 449 Arch = parseArch(Components[0]); 450 VendorType Vendor = UnknownVendor; 451 if (Components.size() > 1) 452 Vendor = parseVendor(Components[1]); 453 OSType OS = UnknownOS; 454 if (Components.size() > 2) { 455 OS = parseOS(Components[2]); 456 IsCygwin = Components[2].startswith("cygwin"); 457 IsMinGW32 = Components[2].startswith("mingw"); 458 } 459 EnvironmentType Environment = UnknownEnvironment; 460 if (Components.size() > 3) 461 Environment = parseEnvironment(Components[3]); 462 ObjectFormatType ObjectFormat = UnknownObjectFormat; 463 if (Components.size() > 4) 464 ObjectFormat = parseFormat(Components[4]); 465 466 // Note which components are already in their final position. These will not 467 // be moved. 468 bool Found[4]; 469 Found[0] = Arch != UnknownArch; 470 Found[1] = Vendor != UnknownVendor; 471 Found[2] = OS != UnknownOS; 472 Found[3] = Environment != UnknownEnvironment; 473 474 // If they are not there already, permute the components into their canonical 475 // positions by seeing if they parse as a valid architecture, and if so moving 476 // the component to the architecture position etc. 477 for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) { 478 if (Found[Pos]) 479 continue; // Already in the canonical position. 480 481 for (unsigned Idx = 0; Idx != Components.size(); ++Idx) { 482 // Do not reparse any components that already matched. 483 if (Idx < array_lengthof(Found) && Found[Idx]) 484 continue; 485 486 // Does this component parse as valid for the target position? 487 bool Valid = false; 488 StringRef Comp = Components[Idx]; 489 switch (Pos) { 490 default: llvm_unreachable("unexpected component type!"); 491 case 0: 492 Arch = parseArch(Comp); 493 Valid = Arch != UnknownArch; 494 break; 495 case 1: 496 Vendor = parseVendor(Comp); 497 Valid = Vendor != UnknownVendor; 498 break; 499 case 2: 500 OS = parseOS(Comp); 501 IsCygwin = Comp.startswith("cygwin"); 502 IsMinGW32 = Comp.startswith("mingw"); 503 Valid = OS != UnknownOS || IsCygwin || IsMinGW32; 504 break; 505 case 3: 506 Environment = parseEnvironment(Comp); 507 Valid = Environment != UnknownEnvironment; 508 if (!Valid) { 509 ObjectFormat = parseFormat(Comp); 510 Valid = ObjectFormat != UnknownObjectFormat; 511 } 512 break; 513 } 514 if (!Valid) 515 continue; // Nope, try the next component. 516 517 // Move the component to the target position, pushing any non-fixed 518 // components that are in the way to the right. This tends to give 519 // good results in the common cases of a forgotten vendor component 520 // or a wrongly positioned environment. 521 if (Pos < Idx) { 522 // Insert left, pushing the existing components to the right. For 523 // example, a-b-i386 -> i386-a-b when moving i386 to the front. 524 StringRef CurrentComponent(""); // The empty component. 525 // Replace the component we are moving with an empty component. 526 std::swap(CurrentComponent, Components[Idx]); 527 // Insert the component being moved at Pos, displacing any existing 528 // components to the right. 529 for (unsigned i = Pos; !CurrentComponent.empty(); ++i) { 530 // Skip over any fixed components. 531 while (i < array_lengthof(Found) && Found[i]) 532 ++i; 533 // Place the component at the new position, getting the component 534 // that was at this position - it will be moved right. 535 std::swap(CurrentComponent, Components[i]); 536 } 537 } else if (Pos > Idx) { 538 // Push right by inserting empty components until the component at Idx 539 // reaches the target position Pos. For example, pc-a -> -pc-a when 540 // moving pc to the second position. 541 do { 542 // Insert one empty component at Idx. 543 StringRef CurrentComponent(""); // The empty component. 544 for (unsigned i = Idx; i < Components.size();) { 545 // Place the component at the new position, getting the component 546 // that was at this position - it will be moved right. 547 std::swap(CurrentComponent, Components[i]); 548 // If it was placed on top of an empty component then we are done. 549 if (CurrentComponent.empty()) 550 break; 551 // Advance to the next component, skipping any fixed components. 552 while (++i < array_lengthof(Found) && Found[i]) 553 ; 554 } 555 // The last component was pushed off the end - append it. 556 if (!CurrentComponent.empty()) 557 Components.push_back(CurrentComponent); 558 559 // Advance Idx to the component's new position. 560 while (++Idx < array_lengthof(Found) && Found[Idx]) 561 ; 562 } while (Idx < Pos); // Add more until the final position is reached. 563 } 564 assert(Pos < Components.size() && Components[Pos] == Comp && 565 "Component moved wrong!"); 566 Found[Pos] = true; 567 break; 568 } 569 } 570 571 // Special case logic goes here. At this point Arch, Vendor and OS have the 572 // correct values for the computed components. 573 574 if (OS == Triple::Win32) { 575 Components.resize(4); 576 Components[2] = "windows"; 577 if (Environment == UnknownEnvironment) { 578 if (ObjectFormat == UnknownObjectFormat || ObjectFormat == Triple::COFF) 579 Components[3] = "msvc"; 580 else 581 Components[3] = getObjectFormatTypeName(ObjectFormat); 582 } 583 } else if (IsMinGW32) { 584 Components.resize(4); 585 Components[2] = "windows"; 586 Components[3] = "gnu"; 587 } else if (IsCygwin) { 588 Components.resize(4); 589 Components[2] = "windows"; 590 Components[3] = "cygnus"; 591 } 592 if (IsMinGW32 || IsCygwin || 593 (OS == Triple::Win32 && Environment != UnknownEnvironment)) { 594 if (ObjectFormat != UnknownObjectFormat && ObjectFormat != Triple::COFF) { 595 Components.resize(5); 596 Components[4] = getObjectFormatTypeName(ObjectFormat); 597 } 598 } 599 600 // Stick the corrected components back together to form the normalized string. 601 std::string Normalized; 602 for (unsigned i = 0, e = Components.size(); i != e; ++i) { 603 if (i) Normalized += '-'; 604 Normalized += Components[i]; 605 } 606 return Normalized; 607 } 608 609 StringRef Triple::getArchName() const { 610 return StringRef(Data).split('-').first; // Isolate first component 611 } 612 613 StringRef Triple::getVendorName() const { 614 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 615 return Tmp.split('-').first; // Isolate second component 616 } 617 618 StringRef Triple::getOSName() const { 619 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 620 Tmp = Tmp.split('-').second; // Strip second component 621 return Tmp.split('-').first; // Isolate third component 622 } 623 624 StringRef Triple::getEnvironmentName() const { 625 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 626 Tmp = Tmp.split('-').second; // Strip second component 627 return Tmp.split('-').second; // Strip third component 628 } 629 630 StringRef Triple::getOSAndEnvironmentName() const { 631 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 632 return Tmp.split('-').second; // Strip second component 633 } 634 635 static unsigned EatNumber(StringRef &Str) { 636 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number"); 637 unsigned Result = 0; 638 639 do { 640 // Consume the leading digit. 641 Result = Result*10 + (Str[0] - '0'); 642 643 // Eat the digit. 644 Str = Str.substr(1); 645 } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9'); 646 647 return Result; 648 } 649 650 void Triple::getOSVersion(unsigned &Major, unsigned &Minor, 651 unsigned &Micro) const { 652 StringRef OSName = getOSName(); 653 654 // Assume that the OS portion of the triple starts with the canonical name. 655 StringRef OSTypeName = getOSTypeName(getOS()); 656 if (OSName.startswith(OSTypeName)) 657 OSName = OSName.substr(OSTypeName.size()); 658 659 // Any unset version defaults to 0. 660 Major = Minor = Micro = 0; 661 662 // Parse up to three components. 663 unsigned *Components[3] = { &Major, &Minor, &Micro }; 664 for (unsigned i = 0; i != 3; ++i) { 665 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9') 666 break; 667 668 // Consume the leading number. 669 *Components[i] = EatNumber(OSName); 670 671 // Consume the separator, if present. 672 if (OSName.startswith(".")) 673 OSName = OSName.substr(1); 674 } 675 } 676 677 bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor, 678 unsigned &Micro) const { 679 getOSVersion(Major, Minor, Micro); 680 681 switch (getOS()) { 682 default: llvm_unreachable("unexpected OS for Darwin triple"); 683 case Darwin: 684 // Default to darwin8, i.e., MacOSX 10.4. 685 if (Major == 0) 686 Major = 8; 687 // Darwin version numbers are skewed from OS X versions. 688 if (Major < 4) 689 return false; 690 Micro = 0; 691 Minor = Major - 4; 692 Major = 10; 693 break; 694 case MacOSX: 695 // Default to 10.4. 696 if (Major == 0) { 697 Major = 10; 698 Minor = 4; 699 } 700 if (Major != 10) 701 return false; 702 break; 703 case IOS: 704 // Ignore the version from the triple. This is only handled because the 705 // the clang driver combines OS X and IOS support into a common Darwin 706 // toolchain that wants to know the OS X version number even when targeting 707 // IOS. 708 Major = 10; 709 Minor = 4; 710 Micro = 0; 711 break; 712 } 713 return true; 714 } 715 716 void Triple::getiOSVersion(unsigned &Major, unsigned &Minor, 717 unsigned &Micro) const { 718 switch (getOS()) { 719 default: llvm_unreachable("unexpected OS for Darwin triple"); 720 case Darwin: 721 case MacOSX: 722 // Ignore the version from the triple. This is only handled because the 723 // the clang driver combines OS X and IOS support into a common Darwin 724 // toolchain that wants to know the iOS version number even when targeting 725 // OS X. 726 Major = 5; 727 Minor = 0; 728 Micro = 0; 729 break; 730 case IOS: 731 getOSVersion(Major, Minor, Micro); 732 // Default to 5.0 (or 7.0 for arm64). 733 if (Major == 0) 734 Major = (getArch() == aarch64) ? 7 : 5; 735 break; 736 } 737 } 738 739 void Triple::setTriple(const Twine &Str) { 740 *this = Triple(Str); 741 } 742 743 void Triple::setArch(ArchType Kind) { 744 setArchName(getArchTypeName(Kind)); 745 } 746 747 void Triple::setVendor(VendorType Kind) { 748 setVendorName(getVendorTypeName(Kind)); 749 } 750 751 void Triple::setOS(OSType Kind) { 752 setOSName(getOSTypeName(Kind)); 753 } 754 755 void Triple::setEnvironment(EnvironmentType Kind) { 756 setEnvironmentName(getEnvironmentTypeName(Kind)); 757 } 758 759 void Triple::setObjectFormat(ObjectFormatType Kind) { 760 if (Environment == UnknownEnvironment) 761 return setEnvironmentName(getObjectFormatTypeName(Kind)); 762 763 setEnvironmentName((getEnvironmentTypeName(Environment) + Twine("-") + 764 getObjectFormatTypeName(Kind)).str()); 765 } 766 767 void Triple::setArchName(StringRef Str) { 768 // Work around a miscompilation bug for Twines in gcc 4.0.3. 769 SmallString<64> Triple; 770 Triple += Str; 771 Triple += "-"; 772 Triple += getVendorName(); 773 Triple += "-"; 774 Triple += getOSAndEnvironmentName(); 775 setTriple(Triple.str()); 776 } 777 778 void Triple::setVendorName(StringRef Str) { 779 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName()); 780 } 781 782 void Triple::setOSName(StringRef Str) { 783 if (hasEnvironment()) 784 setTriple(getArchName() + "-" + getVendorName() + "-" + Str + 785 "-" + getEnvironmentName()); 786 else 787 setTriple(getArchName() + "-" + getVendorName() + "-" + Str); 788 } 789 790 void Triple::setEnvironmentName(StringRef Str) { 791 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() + 792 "-" + Str); 793 } 794 795 void Triple::setOSAndEnvironmentName(StringRef Str) { 796 setTriple(getArchName() + "-" + getVendorName() + "-" + Str); 797 } 798 799 static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) { 800 switch (Arch) { 801 case llvm::Triple::UnknownArch: 802 return 0; 803 804 case llvm::Triple::msp430: 805 return 16; 806 807 case llvm::Triple::arm: 808 case llvm::Triple::armeb: 809 case llvm::Triple::hexagon: 810 case llvm::Triple::le32: 811 case llvm::Triple::mips: 812 case llvm::Triple::mipsel: 813 case llvm::Triple::nvptx: 814 case llvm::Triple::ppc: 815 case llvm::Triple::r600: 816 case llvm::Triple::sparc: 817 case llvm::Triple::tce: 818 case llvm::Triple::thumb: 819 case llvm::Triple::thumbeb: 820 case llvm::Triple::x86: 821 case llvm::Triple::xcore: 822 case llvm::Triple::amdil: 823 case llvm::Triple::hsail: 824 case llvm::Triple::spir: 825 case llvm::Triple::kalimba: 826 return 32; 827 828 case llvm::Triple::aarch64: 829 case llvm::Triple::aarch64_be: 830 case llvm::Triple::le64: 831 case llvm::Triple::mips64: 832 case llvm::Triple::mips64el: 833 case llvm::Triple::nvptx64: 834 case llvm::Triple::ppc64: 835 case llvm::Triple::ppc64le: 836 case llvm::Triple::sparcv9: 837 case llvm::Triple::systemz: 838 case llvm::Triple::x86_64: 839 case llvm::Triple::amdil64: 840 case llvm::Triple::hsail64: 841 case llvm::Triple::spir64: 842 return 64; 843 } 844 llvm_unreachable("Invalid architecture value"); 845 } 846 847 bool Triple::isArch64Bit() const { 848 return getArchPointerBitWidth(getArch()) == 64; 849 } 850 851 bool Triple::isArch32Bit() const { 852 return getArchPointerBitWidth(getArch()) == 32; 853 } 854 855 bool Triple::isArch16Bit() const { 856 return getArchPointerBitWidth(getArch()) == 16; 857 } 858 859 Triple Triple::get32BitArchVariant() const { 860 Triple T(*this); 861 switch (getArch()) { 862 case Triple::UnknownArch: 863 case Triple::aarch64: 864 case Triple::aarch64_be: 865 case Triple::msp430: 866 case Triple::systemz: 867 case Triple::ppc64le: 868 T.setArch(UnknownArch); 869 break; 870 871 case Triple::amdil: 872 case Triple::hsail: 873 case Triple::spir: 874 case Triple::arm: 875 case Triple::armeb: 876 case Triple::hexagon: 877 case Triple::kalimba: 878 case Triple::le32: 879 case Triple::mips: 880 case Triple::mipsel: 881 case Triple::nvptx: 882 case Triple::ppc: 883 case Triple::r600: 884 case Triple::sparc: 885 case Triple::tce: 886 case Triple::thumb: 887 case Triple::thumbeb: 888 case Triple::x86: 889 case Triple::xcore: 890 // Already 32-bit. 891 break; 892 893 case Triple::le64: T.setArch(Triple::le32); break; 894 case Triple::mips64: T.setArch(Triple::mips); break; 895 case Triple::mips64el: T.setArch(Triple::mipsel); break; 896 case Triple::nvptx64: T.setArch(Triple::nvptx); break; 897 case Triple::ppc64: T.setArch(Triple::ppc); break; 898 case Triple::sparcv9: T.setArch(Triple::sparc); break; 899 case Triple::x86_64: T.setArch(Triple::x86); break; 900 case Triple::amdil64: T.setArch(Triple::amdil); break; 901 case Triple::hsail64: T.setArch(Triple::hsail); break; 902 case Triple::spir64: T.setArch(Triple::spir); break; 903 } 904 return T; 905 } 906 907 Triple Triple::get64BitArchVariant() const { 908 Triple T(*this); 909 switch (getArch()) { 910 case Triple::UnknownArch: 911 case Triple::arm: 912 case Triple::armeb: 913 case Triple::hexagon: 914 case Triple::kalimba: 915 case Triple::msp430: 916 case Triple::r600: 917 case Triple::tce: 918 case Triple::thumb: 919 case Triple::thumbeb: 920 case Triple::xcore: 921 T.setArch(UnknownArch); 922 break; 923 924 case Triple::aarch64: 925 case Triple::aarch64_be: 926 case Triple::le64: 927 case Triple::amdil64: 928 case Triple::hsail64: 929 case Triple::spir64: 930 case Triple::mips64: 931 case Triple::mips64el: 932 case Triple::nvptx64: 933 case Triple::ppc64: 934 case Triple::ppc64le: 935 case Triple::sparcv9: 936 case Triple::systemz: 937 case Triple::x86_64: 938 // Already 64-bit. 939 break; 940 941 case Triple::le32: T.setArch(Triple::le64); break; 942 case Triple::mips: T.setArch(Triple::mips64); break; 943 case Triple::mipsel: T.setArch(Triple::mips64el); break; 944 case Triple::nvptx: T.setArch(Triple::nvptx64); break; 945 case Triple::ppc: T.setArch(Triple::ppc64); break; 946 case Triple::sparc: T.setArch(Triple::sparcv9); break; 947 case Triple::x86: T.setArch(Triple::x86_64); break; 948 case Triple::amdil: T.setArch(Triple::amdil64); break; 949 case Triple::hsail: T.setArch(Triple::hsail64); break; 950 case Triple::spir: T.setArch(Triple::spir64); break; 951 } 952 return T; 953 } 954 955 // FIXME: tblgen this. 956 const char *Triple::getARMCPUForArch(StringRef MArch) const { 957 if (MArch.empty()) 958 MArch = getArchName(); 959 960 switch (getOS()) { 961 case llvm::Triple::FreeBSD: 962 case llvm::Triple::NetBSD: 963 if (MArch == "armv6") 964 return "arm1176jzf-s"; 965 break; 966 case llvm::Triple::Win32: 967 // FIXME: this is invalid for WindowsCE 968 return "cortex-a9"; 969 default: 970 break; 971 } 972 973 const char *result = nullptr; 974 size_t offset = StringRef::npos; 975 if (MArch.startswith("arm")) 976 offset = 3; 977 if (MArch.startswith("thumb")) 978 offset = 5; 979 if (offset != StringRef::npos && MArch.substr(offset, 2) == "eb") 980 offset += 2; 981 if (offset != StringRef::npos) 982 result = llvm::StringSwitch<const char *>(MArch.substr(offset)) 983 .Cases("v2", "v2a", "arm2") 984 .Case("v3", "arm6") 985 .Case("v3m", "arm7m") 986 .Case("v4", "strongarm") 987 .Case("v4t", "arm7tdmi") 988 .Cases("v5", "v5t", "arm10tdmi") 989 .Cases("v5e", "v5te", "arm1022e") 990 .Case("v5tej", "arm926ej-s") 991 .Cases("v6", "v6k", "arm1136jf-s") 992 .Case("v6j", "arm1136j-s") 993 .Cases("v6z", "v6zk", "arm1176jzf-s") 994 .Case("v6t2", "arm1156t2-s") 995 .Cases("v6m", "v6-m", "cortex-m0") 996 .Cases("v7", "v7a", "v7-a", "v7l", "v7-l", "cortex-a8") 997 .Cases("v7s", "v7-s", "swift") 998 .Cases("v7r", "v7-r", "cortex-r4") 999 .Cases("v7m", "v7-m", "cortex-m3") 1000 .Cases("v7em", "v7e-m", "cortex-m4") 1001 .Cases("v8", "v8a", "v8-a", "cortex-a53") 1002 .Default(nullptr); 1003 else 1004 result = llvm::StringSwitch<const char *>(MArch) 1005 .Case("ep9312", "ep9312") 1006 .Case("iwmmxt", "iwmmxt") 1007 .Case("xscale", "xscale") 1008 .Default(nullptr); 1009 1010 if (result) 1011 return result; 1012 1013 // If all else failed, return the most base CPU with thumb interworking 1014 // supported by LLVM. 1015 // FIXME: Should warn once that we're falling back. 1016 switch (getOS()) { 1017 case llvm::Triple::NetBSD: 1018 switch (getEnvironment()) { 1019 case llvm::Triple::GNUEABIHF: 1020 case llvm::Triple::GNUEABI: 1021 case llvm::Triple::EABIHF: 1022 case llvm::Triple::EABI: 1023 return "arm926ej-s"; 1024 default: 1025 return "strongarm"; 1026 } 1027 default: 1028 switch (getEnvironment()) { 1029 case llvm::Triple::EABIHF: 1030 case llvm::Triple::GNUEABIHF: 1031 return "arm1176jzf-s"; 1032 default: 1033 return "arm7tdmi"; 1034 } 1035 } 1036 } 1037