1 //===--- Triple.cpp - Target triple helper class --------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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"
18 const char *Triple::getArchTypeName(ArchType Kind) {
20 case UnknownArch: return "unknown";
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";
60 llvm_unreachable("Invalid ArchType!");
63 const char *Triple::getArchTypePrefix(ArchType Kind) {
69 case aarch64_be: return "aarch64";
74 case thumbeb: return "arm";
78 case ppc: return "ppc";
83 case mips64el: return "mips";
85 case hexagon: return "hexagon";
88 case r600: return "amdgpu";
90 case bpf: return "bpf";
93 case sparc: return "sparc";
95 case systemz: return "systemz";
98 case x86_64: return "x86";
100 case xcore: return "xcore";
102 case nvptx: return "nvptx";
103 case nvptx64: return "nvptx";
105 case le32: return "le32";
106 case le64: return "le64";
109 case amdil64: return "amdil";
112 case hsail64: return "hsail";
115 case spir64: return "spir";
116 case kalimba: return "kalimba";
120 const char *Triple::getVendorTypeName(VendorType Kind) {
122 case UnknownVendor: return "unknown";
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";
137 llvm_unreachable("Invalid VendorType!");
140 const char *Triple::getOSTypeName(OSType Kind) {
142 case UnknownOS: return "unknown";
144 case Darwin: return "darwin";
145 case DragonFly: return "dragonfly";
146 case FreeBSD: return "freebsd";
147 case IOS: return "ios";
148 case KFreeBSD: return "kfreebsd";
149 case Linux: return "linux";
150 case Lv2: return "lv2";
151 case MacOSX: return "macosx";
152 case NetBSD: return "netbsd";
153 case OpenBSD: return "openbsd";
154 case Solaris: return "solaris";
155 case Win32: return "windows";
156 case Haiku: return "haiku";
157 case Minix: return "minix";
158 case RTEMS: return "rtems";
159 case NaCl: return "nacl";
160 case CNK: return "cnk";
161 case Bitrig: return "bitrig";
162 case AIX: return "aix";
163 case CUDA: return "cuda";
164 case NVCL: return "nvcl";
165 case AMDHSA: return "amdhsa";
166 case PS4: return "ps4";
169 llvm_unreachable("Invalid OSType");
172 const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
174 case UnknownEnvironment: return "unknown";
175 case GNU: return "gnu";
176 case GNUEABIHF: return "gnueabihf";
177 case GNUEABI: return "gnueabi";
178 case GNUX32: return "gnux32";
179 case CODE16: return "code16";
180 case EABI: return "eabi";
181 case EABIHF: return "eabihf";
182 case Android: return "android";
183 case MSVC: return "msvc";
184 case Itanium: return "itanium";
185 case Cygnus: return "cygnus";
188 llvm_unreachable("Invalid EnvironmentType!");
191 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
192 return StringSwitch<Triple::ArchType>(Name)
193 .Case("aarch64", aarch64)
194 .Case("aarch64_be", aarch64_be)
195 .Case("arm64", aarch64) // "arm64" is an alias for "aarch64"
197 .Case("armeb", armeb)
200 .Case("mipsel", mipsel)
201 .Case("mips64", mips64)
202 .Case("mips64el", mips64el)
203 .Case("msp430", msp430)
204 .Case("ppc64", ppc64)
207 .Case("ppc64le", ppc64le)
209 .Case("amdgcn", amdgcn)
210 .Case("hexagon", hexagon)
211 .Case("sparc", sparc)
212 .Case("sparcv9", sparcv9)
213 .Case("systemz", systemz)
215 .Case("thumb", thumb)
216 .Case("thumbeb", thumbeb)
218 .Case("x86-64", x86_64)
219 .Case("xcore", xcore)
220 .Case("nvptx", nvptx)
221 .Case("nvptx64", nvptx64)
224 .Case("amdil", amdil)
225 .Case("amdil64", amdil64)
226 .Case("hsail", hsail)
227 .Case("hsail64", hsail64)
229 .Case("spir64", spir64)
230 .Case("kalimba", kalimba)
231 .Default(UnknownArch);
234 static Triple::ArchType parseARMArch(StringRef ArchName) {
235 size_t offset = StringRef::npos;
236 Triple::ArchType arch = Triple::UnknownArch;
237 bool isThumb = ArchName.startswith("thumb");
239 if (ArchName.equals("arm"))
241 if (ArchName.equals("armeb"))
242 return Triple::armeb;
243 if (ArchName.equals("thumb"))
244 return Triple::thumb;
245 if (ArchName.equals("thumbeb"))
246 return Triple::thumbeb;
247 if (ArchName.equals("arm64") || ArchName.equals("aarch64"))
248 return Triple::aarch64;
249 if (ArchName.equals("aarch64_be"))
250 return Triple::aarch64_be;
252 if (ArchName.startswith("armv")) {
254 if (ArchName.endswith("eb")) {
255 arch = Triple::armeb;
256 ArchName = ArchName.substr(0, ArchName.size() - 2);
259 } else if (ArchName.startswith("armebv")) {
261 arch = Triple::armeb;
262 } else if (ArchName.startswith("thumbv")) {
264 if (ArchName.endswith("eb")) {
265 arch = Triple::thumbeb;
266 ArchName = ArchName.substr(0, ArchName.size() - 2);
268 arch = Triple::thumb;
269 } else if (ArchName.startswith("thumbebv")) {
271 arch = Triple::thumbeb;
273 return StringSwitch<Triple::ArchType>(ArchName.substr(offset))
274 .Cases("v2", "v2a", isThumb ? Triple::UnknownArch : arch)
275 .Cases("v3", "v3m", isThumb ? Triple::UnknownArch : arch)
276 .Cases("v4", "v4t", arch)
277 .Cases("v5", "v5e", "v5t", "v5te", "v5tej", arch)
278 .Cases("v6", "v6j", "v6k", "v6m", "v6sm", arch)
279 .Cases("v6t2", "v6z", "v6zk", arch)
280 .Cases("v7", "v7a", "v7em", "v7l", arch)
281 .Cases("v7m", "v7r", "v7s", arch)
282 .Cases("v8", "v8a", arch)
283 .Default(Triple::UnknownArch);
286 static Triple::ArchType parseArch(StringRef ArchName) {
287 Triple::ArchType ARMArch(parseARMArch(ArchName));
289 return StringSwitch<Triple::ArchType>(ArchName)
290 .Cases("i386", "i486", "i586", "i686", Triple::x86)
291 // FIXME: Do we need to support these?
292 .Cases("i786", "i886", "i986", Triple::x86)
293 .Cases("amd64", "x86_64", "x86_64h", Triple::x86_64)
294 .Case("powerpc", Triple::ppc)
295 .Cases("powerpc64", "ppu", Triple::ppc64)
296 .Case("powerpc64le", Triple::ppc64le)
297 .Case("xscale", Triple::arm)
298 .Case("xscaleeb", Triple::armeb)
299 .StartsWith("arm", ARMArch)
300 .StartsWith("thumb", ARMArch)
301 .StartsWith("aarch64", ARMArch)
302 .Case("msp430", Triple::msp430)
303 .Cases("mips", "mipseb", "mipsallegrex", Triple::mips)
304 .Cases("mipsel", "mipsallegrexel", Triple::mipsel)
305 .Cases("mips64", "mips64eb", Triple::mips64)
306 .Case("mips64el", Triple::mips64el)
307 .Case("r600", Triple::r600)
308 .Case("amdgcn", Triple::amdgcn)
309 .Case("bpf", Triple::bpf)
310 .Case("hexagon", Triple::hexagon)
311 .Case("s390x", Triple::systemz)
312 .Case("sparc", Triple::sparc)
313 .Cases("sparcv9", "sparc64", Triple::sparcv9)
314 .Case("tce", Triple::tce)
315 .Case("xcore", Triple::xcore)
316 .Case("nvptx", Triple::nvptx)
317 .Case("nvptx64", Triple::nvptx64)
318 .Case("le32", Triple::le32)
319 .Case("le64", Triple::le64)
320 .Case("amdil", Triple::amdil)
321 .Case("amdil64", Triple::amdil64)
322 .Case("hsail", Triple::hsail)
323 .Case("hsail64", Triple::hsail64)
324 .Case("spir", Triple::spir)
325 .Case("spir64", Triple::spir64)
326 .StartsWith("kalimba", Triple::kalimba)
327 .Default(Triple::UnknownArch);
330 static Triple::VendorType parseVendor(StringRef VendorName) {
331 return StringSwitch<Triple::VendorType>(VendorName)
332 .Case("apple", Triple::Apple)
333 .Case("pc", Triple::PC)
334 .Case("scei", Triple::SCEI)
335 .Case("bgp", Triple::BGP)
336 .Case("bgq", Triple::BGQ)
337 .Case("fsl", Triple::Freescale)
338 .Case("ibm", Triple::IBM)
339 .Case("img", Triple::ImaginationTechnologies)
340 .Case("mti", Triple::MipsTechnologies)
341 .Case("nvidia", Triple::NVIDIA)
342 .Case("csr", Triple::CSR)
343 .Default(Triple::UnknownVendor);
346 static Triple::OSType parseOS(StringRef OSName) {
347 return StringSwitch<Triple::OSType>(OSName)
348 .StartsWith("darwin", Triple::Darwin)
349 .StartsWith("dragonfly", Triple::DragonFly)
350 .StartsWith("freebsd", Triple::FreeBSD)
351 .StartsWith("ios", Triple::IOS)
352 .StartsWith("kfreebsd", Triple::KFreeBSD)
353 .StartsWith("linux", Triple::Linux)
354 .StartsWith("lv2", Triple::Lv2)
355 .StartsWith("macosx", Triple::MacOSX)
356 .StartsWith("netbsd", Triple::NetBSD)
357 .StartsWith("openbsd", Triple::OpenBSD)
358 .StartsWith("solaris", Triple::Solaris)
359 .StartsWith("win32", Triple::Win32)
360 .StartsWith("windows", Triple::Win32)
361 .StartsWith("haiku", Triple::Haiku)
362 .StartsWith("minix", Triple::Minix)
363 .StartsWith("rtems", Triple::RTEMS)
364 .StartsWith("nacl", Triple::NaCl)
365 .StartsWith("cnk", Triple::CNK)
366 .StartsWith("bitrig", Triple::Bitrig)
367 .StartsWith("aix", Triple::AIX)
368 .StartsWith("cuda", Triple::CUDA)
369 .StartsWith("nvcl", Triple::NVCL)
370 .StartsWith("amdhsa", Triple::AMDHSA)
371 .StartsWith("ps4", Triple::PS4)
372 .Default(Triple::UnknownOS);
375 static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) {
376 return StringSwitch<Triple::EnvironmentType>(EnvironmentName)
377 .StartsWith("eabihf", Triple::EABIHF)
378 .StartsWith("eabi", Triple::EABI)
379 .StartsWith("gnueabihf", Triple::GNUEABIHF)
380 .StartsWith("gnueabi", Triple::GNUEABI)
381 .StartsWith("gnux32", Triple::GNUX32)
382 .StartsWith("code16", Triple::CODE16)
383 .StartsWith("gnu", Triple::GNU)
384 .StartsWith("android", Triple::Android)
385 .StartsWith("msvc", Triple::MSVC)
386 .StartsWith("itanium", Triple::Itanium)
387 .StartsWith("cygnus", Triple::Cygnus)
388 .Default(Triple::UnknownEnvironment);
391 static Triple::ObjectFormatType parseFormat(StringRef EnvironmentName) {
392 return StringSwitch<Triple::ObjectFormatType>(EnvironmentName)
393 .EndsWith("coff", Triple::COFF)
394 .EndsWith("elf", Triple::ELF)
395 .EndsWith("macho", Triple::MachO)
396 .Default(Triple::UnknownObjectFormat);
399 static Triple::SubArchType parseSubArch(StringRef SubArchName) {
400 if (SubArchName.endswith("eb"))
401 SubArchName = SubArchName.substr(0, SubArchName.size() - 2);
403 return StringSwitch<Triple::SubArchType>(SubArchName)
404 .EndsWith("v8", Triple::ARMSubArch_v8)
405 .EndsWith("v8a", Triple::ARMSubArch_v8)
406 .EndsWith("v7", Triple::ARMSubArch_v7)
407 .EndsWith("v7a", Triple::ARMSubArch_v7)
408 .EndsWith("v7em", Triple::ARMSubArch_v7em)
409 .EndsWith("v7l", Triple::ARMSubArch_v7)
410 .EndsWith("v7m", Triple::ARMSubArch_v7m)
411 .EndsWith("v7r", Triple::ARMSubArch_v7)
412 .EndsWith("v7s", Triple::ARMSubArch_v7s)
413 .EndsWith("v6", Triple::ARMSubArch_v6)
414 .EndsWith("v6m", Triple::ARMSubArch_v6m)
415 .EndsWith("v6sm", Triple::ARMSubArch_v6m)
416 .EndsWith("v6t2", Triple::ARMSubArch_v6t2)
417 .EndsWith("v5", Triple::ARMSubArch_v5)
418 .EndsWith("v5e", Triple::ARMSubArch_v5)
419 .EndsWith("v5t", Triple::ARMSubArch_v5)
420 .EndsWith("v5te", Triple::ARMSubArch_v5te)
421 .EndsWith("v4t", Triple::ARMSubArch_v4t)
422 .EndsWith("kalimba3", Triple::KalimbaSubArch_v3)
423 .EndsWith("kalimba4", Triple::KalimbaSubArch_v4)
424 .EndsWith("kalimba5", Triple::KalimbaSubArch_v5)
425 .Default(Triple::NoSubArch);
428 static const char *getObjectFormatTypeName(Triple::ObjectFormatType Kind) {
430 case Triple::UnknownObjectFormat: return "";
431 case Triple::COFF: return "coff";
432 case Triple::ELF: return "elf";
433 case Triple::MachO: return "macho";
435 llvm_unreachable("unknown object format type");
438 static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
440 return Triple::MachO;
441 else if (T.isOSWindows())
446 /// \brief Construct a triple from the string representation provided.
448 /// This stores the string representation and parses the various pieces into
450 Triple::Triple(const Twine &Str)
452 Arch(parseArch(getArchName())),
453 SubArch(parseSubArch(getArchName())),
454 Vendor(parseVendor(getVendorName())),
455 OS(parseOS(getOSName())),
456 Environment(parseEnvironment(getEnvironmentName())),
457 ObjectFormat(parseFormat(getEnvironmentName())) {
458 if (ObjectFormat == Triple::UnknownObjectFormat)
459 ObjectFormat = getDefaultFormat(*this);
462 /// \brief Construct a triple from string representations of the architecture,
465 /// This joins each argument into a canonical string representation and parses
466 /// them into enum members. It leaves the environment unknown and omits it from
467 /// the string representation.
468 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr)
469 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()),
470 Arch(parseArch(ArchStr.str())),
471 SubArch(parseSubArch(ArchStr.str())),
472 Vendor(parseVendor(VendorStr.str())),
473 OS(parseOS(OSStr.str())),
474 Environment(), ObjectFormat(Triple::UnknownObjectFormat) {
475 ObjectFormat = getDefaultFormat(*this);
478 /// \brief Construct a triple from string representations of the architecture,
479 /// vendor, OS, and environment.
481 /// This joins each argument into a canonical string representation and parses
482 /// them into enum members.
483 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr,
484 const Twine &EnvironmentStr)
485 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr + Twine('-') +
486 EnvironmentStr).str()),
487 Arch(parseArch(ArchStr.str())),
488 SubArch(parseSubArch(ArchStr.str())),
489 Vendor(parseVendor(VendorStr.str())),
490 OS(parseOS(OSStr.str())),
491 Environment(parseEnvironment(EnvironmentStr.str())),
492 ObjectFormat(parseFormat(EnvironmentStr.str())) {
493 if (ObjectFormat == Triple::UnknownObjectFormat)
494 ObjectFormat = getDefaultFormat(*this);
497 std::string Triple::normalize(StringRef Str) {
498 bool IsMinGW32 = false;
499 bool IsCygwin = false;
501 // Parse into components.
502 SmallVector<StringRef, 4> Components;
503 Str.split(Components, "-");
505 // If the first component corresponds to a known architecture, preferentially
506 // use it for the architecture. If the second component corresponds to a
507 // known vendor, preferentially use it for the vendor, etc. This avoids silly
508 // component movement when a component parses as (eg) both a valid arch and a
510 ArchType Arch = UnknownArch;
511 if (Components.size() > 0)
512 Arch = parseArch(Components[0]);
513 VendorType Vendor = UnknownVendor;
514 if (Components.size() > 1)
515 Vendor = parseVendor(Components[1]);
516 OSType OS = UnknownOS;
517 if (Components.size() > 2) {
518 OS = parseOS(Components[2]);
519 IsCygwin = Components[2].startswith("cygwin");
520 IsMinGW32 = Components[2].startswith("mingw");
522 EnvironmentType Environment = UnknownEnvironment;
523 if (Components.size() > 3)
524 Environment = parseEnvironment(Components[3]);
525 ObjectFormatType ObjectFormat = UnknownObjectFormat;
526 if (Components.size() > 4)
527 ObjectFormat = parseFormat(Components[4]);
529 // Note which components are already in their final position. These will not
532 Found[0] = Arch != UnknownArch;
533 Found[1] = Vendor != UnknownVendor;
534 Found[2] = OS != UnknownOS;
535 Found[3] = Environment != UnknownEnvironment;
537 // If they are not there already, permute the components into their canonical
538 // positions by seeing if they parse as a valid architecture, and if so moving
539 // the component to the architecture position etc.
540 for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) {
542 continue; // Already in the canonical position.
544 for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
545 // Do not reparse any components that already matched.
546 if (Idx < array_lengthof(Found) && Found[Idx])
549 // Does this component parse as valid for the target position?
551 StringRef Comp = Components[Idx];
553 default: llvm_unreachable("unexpected component type!");
555 Arch = parseArch(Comp);
556 Valid = Arch != UnknownArch;
559 Vendor = parseVendor(Comp);
560 Valid = Vendor != UnknownVendor;
564 IsCygwin = Comp.startswith("cygwin");
565 IsMinGW32 = Comp.startswith("mingw");
566 Valid = OS != UnknownOS || IsCygwin || IsMinGW32;
569 Environment = parseEnvironment(Comp);
570 Valid = Environment != UnknownEnvironment;
572 ObjectFormat = parseFormat(Comp);
573 Valid = ObjectFormat != UnknownObjectFormat;
578 continue; // Nope, try the next component.
580 // Move the component to the target position, pushing any non-fixed
581 // components that are in the way to the right. This tends to give
582 // good results in the common cases of a forgotten vendor component
583 // or a wrongly positioned environment.
585 // Insert left, pushing the existing components to the right. For
586 // example, a-b-i386 -> i386-a-b when moving i386 to the front.
587 StringRef CurrentComponent(""); // The empty component.
588 // Replace the component we are moving with an empty component.
589 std::swap(CurrentComponent, Components[Idx]);
590 // Insert the component being moved at Pos, displacing any existing
591 // components to the right.
592 for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
593 // Skip over any fixed components.
594 while (i < array_lengthof(Found) && Found[i])
596 // Place the component at the new position, getting the component
597 // that was at this position - it will be moved right.
598 std::swap(CurrentComponent, Components[i]);
600 } else if (Pos > Idx) {
601 // Push right by inserting empty components until the component at Idx
602 // reaches the target position Pos. For example, pc-a -> -pc-a when
603 // moving pc to the second position.
605 // Insert one empty component at Idx.
606 StringRef CurrentComponent(""); // The empty component.
607 for (unsigned i = Idx; i < Components.size();) {
608 // Place the component at the new position, getting the component
609 // that was at this position - it will be moved right.
610 std::swap(CurrentComponent, Components[i]);
611 // If it was placed on top of an empty component then we are done.
612 if (CurrentComponent.empty())
614 // Advance to the next component, skipping any fixed components.
615 while (++i < array_lengthof(Found) && Found[i])
618 // The last component was pushed off the end - append it.
619 if (!CurrentComponent.empty())
620 Components.push_back(CurrentComponent);
622 // Advance Idx to the component's new position.
623 while (++Idx < array_lengthof(Found) && Found[Idx])
625 } while (Idx < Pos); // Add more until the final position is reached.
627 assert(Pos < Components.size() && Components[Pos] == Comp &&
628 "Component moved wrong!");
634 // Special case logic goes here. At this point Arch, Vendor and OS have the
635 // correct values for the computed components.
637 if (OS == Triple::Win32) {
638 Components.resize(4);
639 Components[2] = "windows";
640 if (Environment == UnknownEnvironment) {
641 if (ObjectFormat == UnknownObjectFormat || ObjectFormat == Triple::COFF)
642 Components[3] = "msvc";
644 Components[3] = getObjectFormatTypeName(ObjectFormat);
646 } else if (IsMinGW32) {
647 Components.resize(4);
648 Components[2] = "windows";
649 Components[3] = "gnu";
650 } else if (IsCygwin) {
651 Components.resize(4);
652 Components[2] = "windows";
653 Components[3] = "cygnus";
655 if (IsMinGW32 || IsCygwin ||
656 (OS == Triple::Win32 && Environment != UnknownEnvironment)) {
657 if (ObjectFormat != UnknownObjectFormat && ObjectFormat != Triple::COFF) {
658 Components.resize(5);
659 Components[4] = getObjectFormatTypeName(ObjectFormat);
663 // Stick the corrected components back together to form the normalized string.
664 std::string Normalized;
665 for (unsigned i = 0, e = Components.size(); i != e; ++i) {
666 if (i) Normalized += '-';
667 Normalized += Components[i];
672 StringRef Triple::getArchName() const {
673 return StringRef(Data).split('-').first; // Isolate first component
676 StringRef Triple::getVendorName() const {
677 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
678 return Tmp.split('-').first; // Isolate second component
681 StringRef Triple::getOSName() const {
682 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
683 Tmp = Tmp.split('-').second; // Strip second component
684 return Tmp.split('-').first; // Isolate third component
687 StringRef Triple::getEnvironmentName() const {
688 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
689 Tmp = Tmp.split('-').second; // Strip second component
690 return Tmp.split('-').second; // Strip third component
693 StringRef Triple::getOSAndEnvironmentName() const {
694 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
695 return Tmp.split('-').second; // Strip second component
698 static unsigned EatNumber(StringRef &Str) {
699 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
703 // Consume the leading digit.
704 Result = Result*10 + (Str[0] - '0');
708 } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9');
713 void Triple::getOSVersion(unsigned &Major, unsigned &Minor,
714 unsigned &Micro) const {
715 StringRef OSName = getOSName();
717 // Assume that the OS portion of the triple starts with the canonical name.
718 StringRef OSTypeName = getOSTypeName(getOS());
719 if (OSName.startswith(OSTypeName))
720 OSName = OSName.substr(OSTypeName.size());
722 // Any unset version defaults to 0.
723 Major = Minor = Micro = 0;
725 // Parse up to three components.
726 unsigned *Components[3] = { &Major, &Minor, &Micro };
727 for (unsigned i = 0; i != 3; ++i) {
728 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
731 // Consume the leading number.
732 *Components[i] = EatNumber(OSName);
734 // Consume the separator, if present.
735 if (OSName.startswith("."))
736 OSName = OSName.substr(1);
740 bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor,
741 unsigned &Micro) const {
742 getOSVersion(Major, Minor, Micro);
745 default: llvm_unreachable("unexpected OS for Darwin triple");
747 // Default to darwin8, i.e., MacOSX 10.4.
750 // Darwin version numbers are skewed from OS X versions.
767 // Ignore the version from the triple. This is only handled because the
768 // the clang driver combines OS X and IOS support into a common Darwin
769 // toolchain that wants to know the OS X version number even when targeting
779 void Triple::getiOSVersion(unsigned &Major, unsigned &Minor,
780 unsigned &Micro) const {
782 default: llvm_unreachable("unexpected OS for Darwin triple");
785 // Ignore the version from the triple. This is only handled because the
786 // the clang driver combines OS X and IOS support into a common Darwin
787 // toolchain that wants to know the iOS version number even when targeting
794 getOSVersion(Major, Minor, Micro);
795 // Default to 5.0 (or 7.0 for arm64).
797 Major = (getArch() == aarch64) ? 7 : 5;
802 void Triple::setTriple(const Twine &Str) {
806 void Triple::setArch(ArchType Kind) {
807 setArchName(getArchTypeName(Kind));
810 void Triple::setVendor(VendorType Kind) {
811 setVendorName(getVendorTypeName(Kind));
814 void Triple::setOS(OSType Kind) {
815 setOSName(getOSTypeName(Kind));
818 void Triple::setEnvironment(EnvironmentType Kind) {
819 if (ObjectFormat == getDefaultFormat(*this))
820 return setEnvironmentName(getEnvironmentTypeName(Kind));
822 setEnvironmentName((getEnvironmentTypeName(Kind) + Twine("-") +
823 getObjectFormatTypeName(ObjectFormat)).str());
826 void Triple::setObjectFormat(ObjectFormatType Kind) {
827 if (Environment == UnknownEnvironment)
828 return setEnvironmentName(getObjectFormatTypeName(Kind));
830 setEnvironmentName((getEnvironmentTypeName(Environment) + Twine("-") +
831 getObjectFormatTypeName(Kind)).str());
834 void Triple::setArchName(StringRef Str) {
835 // Work around a miscompilation bug for Twines in gcc 4.0.3.
836 SmallString<64> Triple;
839 Triple += getVendorName();
841 Triple += getOSAndEnvironmentName();
842 setTriple(Triple.str());
845 void Triple::setVendorName(StringRef Str) {
846 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
849 void Triple::setOSName(StringRef Str) {
850 if (hasEnvironment())
851 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
852 "-" + getEnvironmentName());
854 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
857 void Triple::setEnvironmentName(StringRef Str) {
858 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
862 void Triple::setOSAndEnvironmentName(StringRef Str) {
863 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
866 static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
868 case llvm::Triple::UnknownArch:
871 case llvm::Triple::msp430:
874 case llvm::Triple::arm:
875 case llvm::Triple::armeb:
876 case llvm::Triple::hexagon:
877 case llvm::Triple::le32:
878 case llvm::Triple::mips:
879 case llvm::Triple::mipsel:
880 case llvm::Triple::nvptx:
881 case llvm::Triple::ppc:
882 case llvm::Triple::r600:
883 case llvm::Triple::sparc:
884 case llvm::Triple::tce:
885 case llvm::Triple::thumb:
886 case llvm::Triple::thumbeb:
887 case llvm::Triple::x86:
888 case llvm::Triple::xcore:
889 case llvm::Triple::amdil:
890 case llvm::Triple::hsail:
891 case llvm::Triple::spir:
892 case llvm::Triple::kalimba:
895 case llvm::Triple::aarch64:
896 case llvm::Triple::aarch64_be:
897 case llvm::Triple::amdgcn:
898 case llvm::Triple::bpf:
899 case llvm::Triple::le64:
900 case llvm::Triple::mips64:
901 case llvm::Triple::mips64el:
902 case llvm::Triple::nvptx64:
903 case llvm::Triple::ppc64:
904 case llvm::Triple::ppc64le:
905 case llvm::Triple::sparcv9:
906 case llvm::Triple::systemz:
907 case llvm::Triple::x86_64:
908 case llvm::Triple::amdil64:
909 case llvm::Triple::hsail64:
910 case llvm::Triple::spir64:
913 llvm_unreachable("Invalid architecture value");
916 bool Triple::isArch64Bit() const {
917 return getArchPointerBitWidth(getArch()) == 64;
920 bool Triple::isArch32Bit() const {
921 return getArchPointerBitWidth(getArch()) == 32;
924 bool Triple::isArch16Bit() const {
925 return getArchPointerBitWidth(getArch()) == 16;
928 Triple Triple::get32BitArchVariant() const {
931 case Triple::UnknownArch:
932 case Triple::aarch64:
933 case Triple::aarch64_be:
937 case Triple::systemz:
938 case Triple::ppc64le:
939 T.setArch(UnknownArch);
947 case Triple::hexagon:
948 case Triple::kalimba:
958 case Triple::thumbeb:
964 case Triple::le64: T.setArch(Triple::le32); break;
965 case Triple::mips64: T.setArch(Triple::mips); break;
966 case Triple::mips64el: T.setArch(Triple::mipsel); break;
967 case Triple::nvptx64: T.setArch(Triple::nvptx); break;
968 case Triple::ppc64: T.setArch(Triple::ppc); break;
969 case Triple::sparcv9: T.setArch(Triple::sparc); break;
970 case Triple::x86_64: T.setArch(Triple::x86); break;
971 case Triple::amdil64: T.setArch(Triple::amdil); break;
972 case Triple::hsail64: T.setArch(Triple::hsail); break;
973 case Triple::spir64: T.setArch(Triple::spir); break;
978 Triple Triple::get64BitArchVariant() const {
981 case Triple::UnknownArch:
984 case Triple::hexagon:
985 case Triple::kalimba:
990 case Triple::thumbeb:
992 T.setArch(UnknownArch);
995 case Triple::aarch64:
996 case Triple::aarch64_be:
999 case Triple::amdil64:
1000 case Triple::amdgcn:
1001 case Triple::hsail64:
1002 case Triple::spir64:
1003 case Triple::mips64:
1004 case Triple::mips64el:
1005 case Triple::nvptx64:
1007 case Triple::ppc64le:
1008 case Triple::sparcv9:
1009 case Triple::systemz:
1010 case Triple::x86_64:
1014 case Triple::le32: T.setArch(Triple::le64); break;
1015 case Triple::mips: T.setArch(Triple::mips64); break;
1016 case Triple::mipsel: T.setArch(Triple::mips64el); break;
1017 case Triple::nvptx: T.setArch(Triple::nvptx64); break;
1018 case Triple::ppc: T.setArch(Triple::ppc64); break;
1019 case Triple::sparc: T.setArch(Triple::sparcv9); break;
1020 case Triple::x86: T.setArch(Triple::x86_64); break;
1021 case Triple::amdil: T.setArch(Triple::amdil64); break;
1022 case Triple::hsail: T.setArch(Triple::hsail64); break;
1023 case Triple::spir: T.setArch(Triple::spir64); break;
1028 // FIXME: tblgen this.
1029 const char *Triple::getARMCPUForArch(StringRef MArch) const {
1031 MArch = getArchName();
1034 case llvm::Triple::FreeBSD:
1035 case llvm::Triple::NetBSD:
1036 if (MArch == "armv6")
1037 return "arm1176jzf-s";
1039 case llvm::Triple::Win32:
1040 // FIXME: this is invalid for WindowsCE
1046 const char *result = nullptr;
1047 size_t offset = StringRef::npos;
1048 if (MArch.startswith("arm"))
1050 if (MArch.startswith("thumb"))
1052 if (offset != StringRef::npos && MArch.substr(offset, 2) == "eb")
1054 if (MArch.endswith("eb"))
1055 MArch = MArch.substr(0, MArch.size() - 2);
1056 if (offset != StringRef::npos)
1057 result = llvm::StringSwitch<const char *>(MArch.substr(offset))
1058 .Cases("v2", "v2a", "arm2")
1060 .Case("v3m", "arm7m")
1061 .Case("v4", "strongarm")
1062 .Case("v4t", "arm7tdmi")
1063 .Cases("v5", "v5t", "arm10tdmi")
1064 .Cases("v5e", "v5te", "arm1022e")
1065 .Case("v5tej", "arm926ej-s")
1066 .Cases("v6", "v6k", "arm1136jf-s")
1067 .Case("v6j", "arm1136j-s")
1068 .Cases("v6z", "v6zk", "arm1176jzf-s")
1069 .Case("v6t2", "arm1156t2-s")
1070 .Cases("v6m", "v6-m", "v6sm", "v6s-m", "cortex-m0")
1071 .Cases("v7", "v7a", "v7-a", "v7l", "v7-l", "cortex-a8")
1072 .Cases("v7s", "v7-s", "swift")
1073 .Cases("v7r", "v7-r", "cortex-r4")
1074 .Cases("v7m", "v7-m", "cortex-m3")
1075 .Cases("v7em", "v7e-m", "cortex-m4")
1076 .Cases("v8", "v8a", "v8-a", "cortex-a53")
1079 result = llvm::StringSwitch<const char *>(MArch)
1080 .Case("ep9312", "ep9312")
1081 .Case("iwmmxt", "iwmmxt")
1082 .Case("xscale", "xscale")
1088 // If all else failed, return the most base CPU with thumb interworking
1089 // supported by LLVM.
1090 // FIXME: Should warn once that we're falling back.
1092 case llvm::Triple::NetBSD:
1093 switch (getEnvironment()) {
1094 case llvm::Triple::GNUEABIHF:
1095 case llvm::Triple::GNUEABI:
1096 case llvm::Triple::EABIHF:
1097 case llvm::Triple::EABI:
1098 return "arm926ej-s";
1103 switch (getEnvironment()) {
1104 case llvm::Triple::EABIHF:
1105 case llvm::Triple::GNUEABIHF:
1106 return "arm1176jzf-s";