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