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 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";
61 llvm_unreachable("Invalid ArchType!");
64 const char *Triple::getArchTypePrefix(ArchType Kind) {
70 case aarch64_be: return "aarch64";
75 case thumbeb: return "arm";
79 case ppc: return "ppc";
84 case mips64el: return "mips";
86 case hexagon: return "hexagon";
89 case r600: return "amdgpu";
91 case bpf: return "bpf";
95 case sparc: return "sparc";
97 case systemz: return "s390";
100 case x86_64: return "x86";
102 case xcore: return "xcore";
104 case nvptx: return "nvptx";
105 case nvptx64: return "nvptx";
107 case le32: return "le32";
108 case le64: return "le64";
111 case amdil64: return "amdil";
114 case hsail64: return "hsail";
117 case spir64: return "spir";
118 case kalimba: return "kalimba";
122 const char *Triple::getVendorTypeName(VendorType Kind) {
124 case UnknownVendor: return "unknown";
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";
139 llvm_unreachable("Invalid VendorType!");
142 const char *Triple::getOSTypeName(OSType Kind) {
144 case UnknownOS: return "unknown";
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";
172 llvm_unreachable("Invalid OSType");
175 const char *Triple::getEnvironmentTypeName(EnvironmentType 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";
191 llvm_unreachable("Invalid EnvironmentType!");
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"
200 .Case("armeb", armeb)
203 .Case("mipsel", mipsel)
204 .Case("mips64", mips64)
205 .Case("mips64el", mips64el)
206 .Case("msp430", msp430)
207 .Case("ppc64", ppc64)
210 .Case("ppc64le", ppc64le)
212 .Case("amdgcn", amdgcn)
213 .Case("hexagon", hexagon)
214 .Case("sparc", sparc)
215 .Case("sparcel", sparcel)
216 .Case("sparcv9", sparcv9)
217 .Case("systemz", systemz)
219 .Case("thumb", thumb)
220 .Case("thumbeb", thumbeb)
222 .Case("x86-64", x86_64)
223 .Case("xcore", xcore)
224 .Case("nvptx", nvptx)
225 .Case("nvptx64", nvptx64)
228 .Case("amdil", amdil)
229 .Case("amdil64", amdil64)
230 .Case("hsail", hsail)
231 .Case("hsail64", hsail64)
233 .Case("spir64", spir64)
234 .Case("kalimba", kalimba)
235 .Default(UnknownArch);
238 // FIXME: Use ARMTargetParser. This would require Triple::arm/thumb
239 // to be recogniseable universally.
240 static Triple::ArchType parseARMArch(StringRef ArchName) {
241 size_t offset = StringRef::npos;
242 Triple::ArchType arch = Triple::UnknownArch;
243 bool isThumb = ArchName.startswith("thumb");
245 if (ArchName.equals("arm"))
247 if (ArchName.equals("armeb"))
248 return Triple::armeb;
249 if (ArchName.equals("thumb"))
250 return Triple::thumb;
251 if (ArchName.equals("thumbeb"))
252 return Triple::thumbeb;
253 if (ArchName.equals("arm64") || ArchName.equals("aarch64"))
254 return Triple::aarch64;
255 if (ArchName.equals("aarch64_be"))
256 return Triple::aarch64_be;
258 if (ArchName.startswith("armv")) {
260 if (ArchName.endswith("eb")) {
261 arch = Triple::armeb;
262 ArchName = ArchName.substr(0, ArchName.size() - 2);
265 } else if (ArchName.startswith("armebv")) {
267 arch = Triple::armeb;
268 } else if (ArchName.startswith("thumbv")) {
270 if (ArchName.endswith("eb")) {
271 arch = Triple::thumbeb;
272 ArchName = ArchName.substr(0, ArchName.size() - 2);
274 arch = Triple::thumb;
275 } else if (ArchName.startswith("thumbebv")) {
277 arch = Triple::thumbeb;
279 return StringSwitch<Triple::ArchType>(ArchName.substr(offset))
280 .Cases("v2", "v2a", isThumb ? Triple::UnknownArch : arch)
281 .Cases("v3", "v3m", isThumb ? Triple::UnknownArch : arch)
282 .Cases("v4", "v4t", arch)
283 .Cases("v5", "v5e", "v5t", "v5te", "v5tej", arch)
284 .Cases("v6", "v6hl", "v6j", "v6k", arch)
285 .Cases("v6m", "v6sm", arch)
286 .Cases("v6t2", "v6z", "v6zk", arch)
287 .Cases("v7", "v7a", "v7em", "v7hl", "v7l", arch)
288 .Cases("v7m", "v7r", "v7s", arch)
289 .Cases("v8", "v8a", arch)
290 .Cases("v8.1", "v8.1a", arch)
291 .Default(Triple::UnknownArch);
294 static Triple::ArchType parseArch(StringRef ArchName) {
295 Triple::ArchType ARMArch(parseARMArch(ArchName));
297 return StringSwitch<Triple::ArchType>(ArchName)
298 .Cases("i386", "i486", "i586", "i686", Triple::x86)
299 // FIXME: Do we need to support these?
300 .Cases("i786", "i886", "i986", Triple::x86)
301 .Cases("amd64", "x86_64", "x86_64h", Triple::x86_64)
302 .Case("powerpc", Triple::ppc)
303 .Cases("powerpc64", "ppu", Triple::ppc64)
304 .Case("powerpc64le", Triple::ppc64le)
305 .Case("xscale", Triple::arm)
306 .Case("xscaleeb", Triple::armeb)
307 .StartsWith("arm", ARMArch)
308 .StartsWith("thumb", ARMArch)
309 .StartsWith("aarch64", ARMArch)
310 .Case("msp430", Triple::msp430)
311 .Cases("mips", "mipseb", "mipsallegrex", Triple::mips)
312 .Cases("mipsel", "mipsallegrexel", Triple::mipsel)
313 .Cases("mips64", "mips64eb", Triple::mips64)
314 .Case("mips64el", Triple::mips64el)
315 .Case("r600", Triple::r600)
316 .Case("amdgcn", Triple::amdgcn)
317 .Case("bpf", Triple::bpf)
318 .Case("hexagon", Triple::hexagon)
319 .Case("s390x", Triple::systemz)
320 .Case("sparc", Triple::sparc)
321 .Case("sparcel", Triple::sparcel)
322 .Cases("sparcv9", "sparc64", Triple::sparcv9)
323 .Case("tce", Triple::tce)
324 .Case("xcore", Triple::xcore)
325 .Case("nvptx", Triple::nvptx)
326 .Case("nvptx64", Triple::nvptx64)
327 .Case("le32", Triple::le32)
328 .Case("le64", Triple::le64)
329 .Case("amdil", Triple::amdil)
330 .Case("amdil64", Triple::amdil64)
331 .Case("hsail", Triple::hsail)
332 .Case("hsail64", Triple::hsail64)
333 .Case("spir", Triple::spir)
334 .Case("spir64", Triple::spir64)
335 .StartsWith("kalimba", Triple::kalimba)
336 .Default(Triple::UnknownArch);
339 static Triple::VendorType parseVendor(StringRef VendorName) {
340 return StringSwitch<Triple::VendorType>(VendorName)
341 .Case("apple", Triple::Apple)
342 .Case("pc", Triple::PC)
343 .Case("scei", Triple::SCEI)
344 .Case("bgp", Triple::BGP)
345 .Case("bgq", Triple::BGQ)
346 .Case("fsl", Triple::Freescale)
347 .Case("ibm", Triple::IBM)
348 .Case("img", Triple::ImaginationTechnologies)
349 .Case("mti", Triple::MipsTechnologies)
350 .Case("nvidia", Triple::NVIDIA)
351 .Case("csr", Triple::CSR)
352 .Default(Triple::UnknownVendor);
355 static Triple::OSType parseOS(StringRef OSName) {
356 return StringSwitch<Triple::OSType>(OSName)
357 .StartsWith("cloudabi", Triple::CloudABI)
358 .StartsWith("darwin", Triple::Darwin)
359 .StartsWith("dragonfly", Triple::DragonFly)
360 .StartsWith("freebsd", Triple::FreeBSD)
361 .StartsWith("ios", Triple::IOS)
362 .StartsWith("kfreebsd", Triple::KFreeBSD)
363 .StartsWith("linux", Triple::Linux)
364 .StartsWith("lv2", Triple::Lv2)
365 .StartsWith("macosx", Triple::MacOSX)
366 .StartsWith("netbsd", Triple::NetBSD)
367 .StartsWith("openbsd", Triple::OpenBSD)
368 .StartsWith("solaris", Triple::Solaris)
369 .StartsWith("win32", Triple::Win32)
370 .StartsWith("windows", Triple::Win32)
371 .StartsWith("haiku", Triple::Haiku)
372 .StartsWith("minix", Triple::Minix)
373 .StartsWith("rtems", Triple::RTEMS)
374 .StartsWith("nacl", Triple::NaCl)
375 .StartsWith("cnk", Triple::CNK)
376 .StartsWith("bitrig", Triple::Bitrig)
377 .StartsWith("aix", Triple::AIX)
378 .StartsWith("cuda", Triple::CUDA)
379 .StartsWith("nvcl", Triple::NVCL)
380 .StartsWith("amdhsa", Triple::AMDHSA)
381 .StartsWith("ps4", Triple::PS4)
382 .Default(Triple::UnknownOS);
385 static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) {
386 return StringSwitch<Triple::EnvironmentType>(EnvironmentName)
387 .StartsWith("eabihf", Triple::EABIHF)
388 .StartsWith("eabi", Triple::EABI)
389 .StartsWith("gnueabihf", Triple::GNUEABIHF)
390 .StartsWith("gnueabi", Triple::GNUEABI)
391 .StartsWith("gnux32", Triple::GNUX32)
392 .StartsWith("code16", Triple::CODE16)
393 .StartsWith("gnu", Triple::GNU)
394 .StartsWith("android", Triple::Android)
395 .StartsWith("msvc", Triple::MSVC)
396 .StartsWith("itanium", Triple::Itanium)
397 .StartsWith("cygnus", Triple::Cygnus)
398 .Default(Triple::UnknownEnvironment);
401 static Triple::ObjectFormatType parseFormat(StringRef EnvironmentName) {
402 return StringSwitch<Triple::ObjectFormatType>(EnvironmentName)
403 .EndsWith("coff", Triple::COFF)
404 .EndsWith("elf", Triple::ELF)
405 .EndsWith("macho", Triple::MachO)
406 .Default(Triple::UnknownObjectFormat);
409 // FIXME: Use ARMTargetParser. This would require using Triple::ARMSubArch*
410 // in ARMBuildAttrs and in ARCHNames' DefaultArch fields.
411 static Triple::SubArchType parseSubArch(StringRef SubArchName) {
412 if (SubArchName.endswith("eb"))
413 SubArchName = SubArchName.substr(0, SubArchName.size() - 2);
415 return StringSwitch<Triple::SubArchType>(SubArchName)
416 .EndsWith("v8.1a", Triple::ARMSubArch_v8_1a)
417 .EndsWith("v8", Triple::ARMSubArch_v8)
418 .EndsWith("v8a", Triple::ARMSubArch_v8)
419 .EndsWith("v7", Triple::ARMSubArch_v7)
420 .EndsWith("v7a", Triple::ARMSubArch_v7)
421 .EndsWith("v7em", Triple::ARMSubArch_v7em)
422 .EndsWith("v7l", Triple::ARMSubArch_v7)
423 .EndsWith("v7m", Triple::ARMSubArch_v7m)
424 .EndsWith("v7r", Triple::ARMSubArch_v7)
425 .EndsWith("v7s", Triple::ARMSubArch_v7s)
426 .EndsWith("v6", Triple::ARMSubArch_v6)
427 .EndsWith("v6m", Triple::ARMSubArch_v6m)
428 .EndsWith("v6sm", Triple::ARMSubArch_v6m)
429 .EndsWith("v6k", Triple::ARMSubArch_v6k)
430 .EndsWith("v6t2", Triple::ARMSubArch_v6t2)
431 .EndsWith("v5", Triple::ARMSubArch_v5)
432 .EndsWith("v5e", Triple::ARMSubArch_v5)
433 .EndsWith("v5t", Triple::ARMSubArch_v5)
434 .EndsWith("v5te", Triple::ARMSubArch_v5te)
435 .EndsWith("v4t", Triple::ARMSubArch_v4t)
436 .EndsWith("kalimba3", Triple::KalimbaSubArch_v3)
437 .EndsWith("kalimba4", Triple::KalimbaSubArch_v4)
438 .EndsWith("kalimba5", Triple::KalimbaSubArch_v5)
439 .Default(Triple::NoSubArch);
442 static const char *getObjectFormatTypeName(Triple::ObjectFormatType Kind) {
444 case Triple::UnknownObjectFormat: return "";
445 case Triple::COFF: return "coff";
446 case Triple::ELF: return "elf";
447 case Triple::MachO: return "macho";
449 llvm_unreachable("unknown object format type");
452 static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
453 switch (T.getArch()) {
456 case Triple::hexagon:
460 case Triple::mips64el:
464 case Triple::sparcv9:
465 case Triple::systemz:
467 case Triple::ppc64le:
473 return Triple::MachO;
478 return Triple::MachO;
479 else if (T.isOSWindows())
484 /// \brief Construct a triple from the string representation provided.
486 /// This stores the string representation and parses the various pieces into
488 Triple::Triple(const Twine &Str)
490 Arch(parseArch(getArchName())),
491 SubArch(parseSubArch(getArchName())),
492 Vendor(parseVendor(getVendorName())),
493 OS(parseOS(getOSName())),
494 Environment(parseEnvironment(getEnvironmentName())),
495 ObjectFormat(parseFormat(getEnvironmentName())) {
496 if (ObjectFormat == Triple::UnknownObjectFormat)
497 ObjectFormat = getDefaultFormat(*this);
500 /// \brief Construct a triple from string representations of the architecture,
503 /// This joins each argument into a canonical string representation and parses
504 /// them into enum members. It leaves the environment unknown and omits it from
505 /// the string representation.
506 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr)
507 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()),
508 Arch(parseArch(ArchStr.str())),
509 SubArch(parseSubArch(ArchStr.str())),
510 Vendor(parseVendor(VendorStr.str())),
511 OS(parseOS(OSStr.str())),
512 Environment(), ObjectFormat(Triple::UnknownObjectFormat) {
513 ObjectFormat = getDefaultFormat(*this);
516 /// \brief Construct a triple from string representations of the architecture,
517 /// vendor, OS, and environment.
519 /// This joins each argument into a canonical string representation and parses
520 /// them into enum members.
521 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr,
522 const Twine &EnvironmentStr)
523 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr + Twine('-') +
524 EnvironmentStr).str()),
525 Arch(parseArch(ArchStr.str())),
526 SubArch(parseSubArch(ArchStr.str())),
527 Vendor(parseVendor(VendorStr.str())),
528 OS(parseOS(OSStr.str())),
529 Environment(parseEnvironment(EnvironmentStr.str())),
530 ObjectFormat(parseFormat(EnvironmentStr.str())) {
531 if (ObjectFormat == Triple::UnknownObjectFormat)
532 ObjectFormat = getDefaultFormat(*this);
535 std::string Triple::normalize(StringRef Str) {
536 bool IsMinGW32 = false;
537 bool IsCygwin = false;
539 // Parse into components.
540 SmallVector<StringRef, 4> Components;
541 Str.split(Components, "-");
543 // If the first component corresponds to a known architecture, preferentially
544 // use it for the architecture. If the second component corresponds to a
545 // known vendor, preferentially use it for the vendor, etc. This avoids silly
546 // component movement when a component parses as (eg) both a valid arch and a
548 ArchType Arch = UnknownArch;
549 if (Components.size() > 0)
550 Arch = parseArch(Components[0]);
551 VendorType Vendor = UnknownVendor;
552 if (Components.size() > 1)
553 Vendor = parseVendor(Components[1]);
554 OSType OS = UnknownOS;
555 if (Components.size() > 2) {
556 OS = parseOS(Components[2]);
557 IsCygwin = Components[2].startswith("cygwin");
558 IsMinGW32 = Components[2].startswith("mingw");
560 EnvironmentType Environment = UnknownEnvironment;
561 if (Components.size() > 3)
562 Environment = parseEnvironment(Components[3]);
563 ObjectFormatType ObjectFormat = UnknownObjectFormat;
564 if (Components.size() > 4)
565 ObjectFormat = parseFormat(Components[4]);
567 // Note which components are already in their final position. These will not
570 Found[0] = Arch != UnknownArch;
571 Found[1] = Vendor != UnknownVendor;
572 Found[2] = OS != UnknownOS;
573 Found[3] = Environment != UnknownEnvironment;
575 // If they are not there already, permute the components into their canonical
576 // positions by seeing if they parse as a valid architecture, and if so moving
577 // the component to the architecture position etc.
578 for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) {
580 continue; // Already in the canonical position.
582 for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
583 // Do not reparse any components that already matched.
584 if (Idx < array_lengthof(Found) && Found[Idx])
587 // Does this component parse as valid for the target position?
589 StringRef Comp = Components[Idx];
591 default: llvm_unreachable("unexpected component type!");
593 Arch = parseArch(Comp);
594 Valid = Arch != UnknownArch;
597 Vendor = parseVendor(Comp);
598 Valid = Vendor != UnknownVendor;
602 IsCygwin = Comp.startswith("cygwin");
603 IsMinGW32 = Comp.startswith("mingw");
604 Valid = OS != UnknownOS || IsCygwin || IsMinGW32;
607 Environment = parseEnvironment(Comp);
608 Valid = Environment != UnknownEnvironment;
610 ObjectFormat = parseFormat(Comp);
611 Valid = ObjectFormat != UnknownObjectFormat;
616 continue; // Nope, try the next component.
618 // Move the component to the target position, pushing any non-fixed
619 // components that are in the way to the right. This tends to give
620 // good results in the common cases of a forgotten vendor component
621 // or a wrongly positioned environment.
623 // Insert left, pushing the existing components to the right. For
624 // example, a-b-i386 -> i386-a-b when moving i386 to the front.
625 StringRef CurrentComponent(""); // The empty component.
626 // Replace the component we are moving with an empty component.
627 std::swap(CurrentComponent, Components[Idx]);
628 // Insert the component being moved at Pos, displacing any existing
629 // components to the right.
630 for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
631 // Skip over any fixed components.
632 while (i < array_lengthof(Found) && Found[i])
634 // Place the component at the new position, getting the component
635 // that was at this position - it will be moved right.
636 std::swap(CurrentComponent, Components[i]);
638 } else if (Pos > Idx) {
639 // Push right by inserting empty components until the component at Idx
640 // reaches the target position Pos. For example, pc-a -> -pc-a when
641 // moving pc to the second position.
643 // Insert one empty component at Idx.
644 StringRef CurrentComponent(""); // The empty component.
645 for (unsigned i = Idx; i < Components.size();) {
646 // Place the component at the new position, getting the component
647 // that was at this position - it will be moved right.
648 std::swap(CurrentComponent, Components[i]);
649 // If it was placed on top of an empty component then we are done.
650 if (CurrentComponent.empty())
652 // Advance to the next component, skipping any fixed components.
653 while (++i < array_lengthof(Found) && Found[i])
656 // The last component was pushed off the end - append it.
657 if (!CurrentComponent.empty())
658 Components.push_back(CurrentComponent);
660 // Advance Idx to the component's new position.
661 while (++Idx < array_lengthof(Found) && Found[Idx])
663 } while (Idx < Pos); // Add more until the final position is reached.
665 assert(Pos < Components.size() && Components[Pos] == Comp &&
666 "Component moved wrong!");
672 // Special case logic goes here. At this point Arch, Vendor and OS have the
673 // correct values for the computed components.
675 if (OS == Triple::Win32) {
676 Components.resize(4);
677 Components[2] = "windows";
678 if (Environment == UnknownEnvironment) {
679 if (ObjectFormat == UnknownObjectFormat || ObjectFormat == Triple::COFF)
680 Components[3] = "msvc";
682 Components[3] = getObjectFormatTypeName(ObjectFormat);
684 } else if (IsMinGW32) {
685 Components.resize(4);
686 Components[2] = "windows";
687 Components[3] = "gnu";
688 } else if (IsCygwin) {
689 Components.resize(4);
690 Components[2] = "windows";
691 Components[3] = "cygnus";
693 if (IsMinGW32 || IsCygwin ||
694 (OS == Triple::Win32 && Environment != UnknownEnvironment)) {
695 if (ObjectFormat != UnknownObjectFormat && ObjectFormat != Triple::COFF) {
696 Components.resize(5);
697 Components[4] = getObjectFormatTypeName(ObjectFormat);
701 // Stick the corrected components back together to form the normalized string.
702 std::string Normalized;
703 for (unsigned i = 0, e = Components.size(); i != e; ++i) {
704 if (i) Normalized += '-';
705 Normalized += Components[i];
710 StringRef Triple::getArchName() const {
711 return StringRef(Data).split('-').first; // Isolate first component
714 StringRef Triple::getVendorName() const {
715 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
716 return Tmp.split('-').first; // Isolate second component
719 StringRef Triple::getOSName() const {
720 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
721 Tmp = Tmp.split('-').second; // Strip second component
722 return Tmp.split('-').first; // Isolate third component
725 StringRef Triple::getEnvironmentName() const {
726 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
727 Tmp = Tmp.split('-').second; // Strip second component
728 return Tmp.split('-').second; // Strip third component
731 StringRef Triple::getOSAndEnvironmentName() const {
732 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
733 return Tmp.split('-').second; // Strip second component
736 static unsigned EatNumber(StringRef &Str) {
737 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
741 // Consume the leading digit.
742 Result = Result*10 + (Str[0] - '0');
746 } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9');
751 void Triple::getOSVersion(unsigned &Major, unsigned &Minor,
752 unsigned &Micro) const {
753 StringRef OSName = getOSName();
755 // For Android, we care about the Android version rather than the Linux
757 if (getEnvironment() == Android) {
758 OSName = getEnvironmentName().substr(strlen("android"));
759 if (OSName.startswith("eabi"))
760 OSName = OSName.substr(strlen("eabi"));
763 // Assume that the OS portion of the triple starts with the canonical name.
764 StringRef OSTypeName = getOSTypeName(getOS());
765 if (OSName.startswith(OSTypeName))
766 OSName = OSName.substr(OSTypeName.size());
768 // Any unset version defaults to 0.
769 Major = Minor = Micro = 0;
771 // Parse up to three components.
772 unsigned *Components[3] = { &Major, &Minor, &Micro };
773 for (unsigned i = 0; i != 3; ++i) {
774 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
777 // Consume the leading number.
778 *Components[i] = EatNumber(OSName);
780 // Consume the separator, if present.
781 if (OSName.startswith("."))
782 OSName = OSName.substr(1);
786 bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor,
787 unsigned &Micro) const {
788 getOSVersion(Major, Minor, Micro);
791 default: llvm_unreachable("unexpected OS for Darwin triple");
793 // Default to darwin8, i.e., MacOSX 10.4.
796 // Darwin version numbers are skewed from OS X versions.
813 // Ignore the version from the triple. This is only handled because the
814 // the clang driver combines OS X and IOS support into a common Darwin
815 // toolchain that wants to know the OS X version number even when targeting
825 void Triple::getiOSVersion(unsigned &Major, unsigned &Minor,
826 unsigned &Micro) const {
828 default: llvm_unreachable("unexpected OS for Darwin triple");
831 // Ignore the version from the triple. This is only handled because the
832 // the clang driver combines OS X and IOS support into a common Darwin
833 // toolchain that wants to know the iOS version number even when targeting
840 getOSVersion(Major, Minor, Micro);
841 // Default to 5.0 (or 7.0 for arm64).
843 Major = (getArch() == aarch64) ? 7 : 5;
848 void Triple::setTriple(const Twine &Str) {
852 void Triple::setArch(ArchType Kind) {
853 setArchName(getArchTypeName(Kind));
856 void Triple::setVendor(VendorType Kind) {
857 setVendorName(getVendorTypeName(Kind));
860 void Triple::setOS(OSType Kind) {
861 setOSName(getOSTypeName(Kind));
864 void Triple::setEnvironment(EnvironmentType Kind) {
865 if (ObjectFormat == getDefaultFormat(*this))
866 return setEnvironmentName(getEnvironmentTypeName(Kind));
868 setEnvironmentName((getEnvironmentTypeName(Kind) + Twine("-") +
869 getObjectFormatTypeName(ObjectFormat)).str());
872 void Triple::setObjectFormat(ObjectFormatType Kind) {
873 if (Environment == UnknownEnvironment)
874 return setEnvironmentName(getObjectFormatTypeName(Kind));
876 setEnvironmentName((getEnvironmentTypeName(Environment) + Twine("-") +
877 getObjectFormatTypeName(Kind)).str());
880 void Triple::setArchName(StringRef Str) {
881 // Work around a miscompilation bug for Twines in gcc 4.0.3.
882 SmallString<64> Triple;
885 Triple += getVendorName();
887 Triple += getOSAndEnvironmentName();
891 void Triple::setVendorName(StringRef Str) {
892 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
895 void Triple::setOSName(StringRef Str) {
896 if (hasEnvironment())
897 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
898 "-" + getEnvironmentName());
900 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
903 void Triple::setEnvironmentName(StringRef Str) {
904 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
908 void Triple::setOSAndEnvironmentName(StringRef Str) {
909 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
912 static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
914 case llvm::Triple::UnknownArch:
917 case llvm::Triple::msp430:
920 case llvm::Triple::arm:
921 case llvm::Triple::armeb:
922 case llvm::Triple::hexagon:
923 case llvm::Triple::le32:
924 case llvm::Triple::mips:
925 case llvm::Triple::mipsel:
926 case llvm::Triple::nvptx:
927 case llvm::Triple::ppc:
928 case llvm::Triple::r600:
929 case llvm::Triple::sparc:
930 case llvm::Triple::sparcel:
931 case llvm::Triple::tce:
932 case llvm::Triple::thumb:
933 case llvm::Triple::thumbeb:
934 case llvm::Triple::x86:
935 case llvm::Triple::xcore:
936 case llvm::Triple::amdil:
937 case llvm::Triple::hsail:
938 case llvm::Triple::spir:
939 case llvm::Triple::kalimba:
942 case llvm::Triple::aarch64:
943 case llvm::Triple::aarch64_be:
944 case llvm::Triple::amdgcn:
945 case llvm::Triple::bpf:
946 case llvm::Triple::le64:
947 case llvm::Triple::mips64:
948 case llvm::Triple::mips64el:
949 case llvm::Triple::nvptx64:
950 case llvm::Triple::ppc64:
951 case llvm::Triple::ppc64le:
952 case llvm::Triple::sparcv9:
953 case llvm::Triple::systemz:
954 case llvm::Triple::x86_64:
955 case llvm::Triple::amdil64:
956 case llvm::Triple::hsail64:
957 case llvm::Triple::spir64:
960 llvm_unreachable("Invalid architecture value");
963 bool Triple::isArch64Bit() const {
964 return getArchPointerBitWidth(getArch()) == 64;
967 bool Triple::isArch32Bit() const {
968 return getArchPointerBitWidth(getArch()) == 32;
971 bool Triple::isArch16Bit() const {
972 return getArchPointerBitWidth(getArch()) == 16;
975 Triple Triple::get32BitArchVariant() const {
978 case Triple::UnknownArch:
979 case Triple::aarch64:
980 case Triple::aarch64_be:
984 case Triple::systemz:
985 case Triple::ppc64le:
986 T.setArch(UnknownArch);
994 case Triple::hexagon:
995 case Triple::kalimba:
1003 case Triple::sparcel:
1006 case Triple::thumbeb:
1012 case Triple::le64: T.setArch(Triple::le32); break;
1013 case Triple::mips64: T.setArch(Triple::mips); break;
1014 case Triple::mips64el: T.setArch(Triple::mipsel); break;
1015 case Triple::nvptx64: T.setArch(Triple::nvptx); break;
1016 case Triple::ppc64: T.setArch(Triple::ppc); break;
1017 case Triple::sparcv9: T.setArch(Triple::sparc); break;
1018 case Triple::x86_64: T.setArch(Triple::x86); break;
1019 case Triple::amdil64: T.setArch(Triple::amdil); break;
1020 case Triple::hsail64: T.setArch(Triple::hsail); break;
1021 case Triple::spir64: T.setArch(Triple::spir); break;
1026 Triple Triple::get64BitArchVariant() const {
1028 switch (getArch()) {
1029 case Triple::UnknownArch:
1032 case Triple::hexagon:
1033 case Triple::kalimba:
1034 case Triple::msp430:
1038 case Triple::thumbeb:
1040 case Triple::sparcel:
1041 T.setArch(UnknownArch);
1044 case Triple::aarch64:
1045 case Triple::aarch64_be:
1048 case Triple::amdil64:
1049 case Triple::amdgcn:
1050 case Triple::hsail64:
1051 case Triple::spir64:
1052 case Triple::mips64:
1053 case Triple::mips64el:
1054 case Triple::nvptx64:
1056 case Triple::ppc64le:
1057 case Triple::sparcv9:
1058 case Triple::systemz:
1059 case Triple::x86_64:
1063 case Triple::le32: T.setArch(Triple::le64); break;
1064 case Triple::mips: T.setArch(Triple::mips64); break;
1065 case Triple::mipsel: T.setArch(Triple::mips64el); break;
1066 case Triple::nvptx: T.setArch(Triple::nvptx64); break;
1067 case Triple::ppc: T.setArch(Triple::ppc64); break;
1068 case Triple::sparc: T.setArch(Triple::sparcv9); break;
1069 case Triple::x86: T.setArch(Triple::x86_64); break;
1070 case Triple::amdil: T.setArch(Triple::amdil64); break;
1071 case Triple::hsail: T.setArch(Triple::hsail64); break;
1072 case Triple::spir: T.setArch(Triple::spir64); break;
1077 // FIXME: Use ARMTargetParser. This would require ARCHNames to hold
1078 // specific CPU names, as well as default CPU arch.
1079 const char *Triple::getARMCPUForArch(StringRef MArch) const {
1081 MArch = getArchName();
1084 case llvm::Triple::FreeBSD:
1085 case llvm::Triple::NetBSD:
1086 if (MArch == "armv6")
1087 return "arm1176jzf-s";
1089 case llvm::Triple::Win32:
1090 // FIXME: this is invalid for WindowsCE
1096 // MArch is expected to be of the form (arm|thumb)?(eb)?(v.+)?(eb)?
1097 // Only the (v.+) part is relevant for determining the CPU, as it determines
1098 // the architecture version, so we first remove the surrounding parts.
1099 // (ep9312|iwmmxt|xscale)(eb)? is also permitted, so we have to be a bit
1100 // careful when removing the leading (arm|thumb)?(eb)? as we don't want to
1101 // permit things like armep9312.
1102 const char *result = nullptr;
1103 size_t offset = StringRef::npos;
1104 if (MArch.startswith("arm"))
1106 else if (MArch.startswith("thumb"))
1108 if (offset != StringRef::npos && MArch.substr(offset, 2) == "eb")
1110 else if (MArch.endswith("eb"))
1111 MArch = MArch.substr(0, MArch.size() - 2);
1112 if (offset != StringRef::npos && (offset == MArch.size() || MArch[offset] == 'v'))
1113 MArch = MArch.substr(offset);
1116 // If no specific architecture version is requested, return the minimum CPU
1117 // required by the OS and environment.
1119 case llvm::Triple::NetBSD:
1120 switch (getEnvironment()) {
1121 case llvm::Triple::GNUEABIHF:
1122 case llvm::Triple::GNUEABI:
1123 case llvm::Triple::EABIHF:
1124 case llvm::Triple::EABI:
1125 return "arm926ej-s";
1129 case llvm::Triple::NaCl:
1132 switch (getEnvironment()) {
1133 case llvm::Triple::EABIHF:
1134 case llvm::Triple::GNUEABIHF:
1135 return "arm1176jzf-s";
1141 result = llvm::StringSwitch<const char *>(MArch)
1142 .Cases("v2", "v2a", "arm2")
1144 .Case("v3m", "arm7m")
1145 .Case("v4", "strongarm")
1146 .Case("v4t", "arm7tdmi")
1147 .Cases("v5", "v5t", "arm10tdmi")
1148 .Cases("v5e", "v5te", "arm1022e")
1149 .Case("v5tej", "arm926ej-s")
1150 .Case("v6", "arm1136jf-s")
1151 .Case("v6j", "arm1136j-s")
1152 .Cases("v6k", "v6z", "v6zk", "arm1176jzf-s")
1153 .Case("v6t2", "arm1156t2-s")
1154 .Cases("v6m", "v6-m", "v6sm", "v6s-m", "cortex-m0")
1155 .Cases("v7", "v7a", "v7-a", "v7l", "v7-l", "cortex-a8")
1156 .Cases("v7s", "v7-s", "swift")
1157 .Cases("v7r", "v7-r", "cortex-r4")
1158 .Cases("v7m", "v7-m", "cortex-m3")
1159 .Cases("v7em", "v7e-m", "cortex-m4")
1160 .Cases("v8", "v8a", "v8-a", "cortex-a53")
1161 .Cases("v8.1a", "v8.1-a", "generic")
1162 .Case("ep9312", "ep9312")
1163 .Case("iwmmxt", "iwmmxt")
1164 .Case("xscale", "xscale")