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