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 hexagon: return "hexagon";
27 case mips: return "mips";
28 case mipsel: return "mipsel";
29 case mips64: return "mips64";
30 case mips64el: return "mips64el";
31 case msp430: return "msp430";
32 case ppc64: return "powerpc64";
33 case ppc64le: return "powerpc64le";
34 case ppc: return "powerpc";
35 case r600: return "r600";
36 case sparc: return "sparc";
37 case sparcv9: return "sparcv9";
38 case systemz: return "s390x";
39 case tce: return "tce";
40 case thumb: return "thumb";
41 case thumbeb: return "thumbeb";
42 case x86: return "i386";
43 case x86_64: return "x86_64";
44 case xcore: return "xcore";
45 case nvptx: return "nvptx";
46 case nvptx64: return "nvptx64";
47 case le32: return "le32";
48 case le64: return "le64";
49 case amdil: return "amdil";
50 case amdil64: return "amdil64";
51 case hsail: return "hsail";
52 case hsail64: return "hsail64";
53 case spir: return "spir";
54 case spir64: return "spir64";
55 case kalimba: return "kalimba";
58 llvm_unreachable("Invalid ArchType!");
61 const char *Triple::getArchTypePrefix(ArchType Kind) {
67 case aarch64_be: return "aarch64";
72 case thumbeb: return "arm";
76 case ppc: return "ppc";
81 case mips64el: return "mips";
83 case hexagon: return "hexagon";
85 case r600: return "r600";
88 case sparc: return "sparc";
90 case systemz: return "systemz";
93 case x86_64: return "x86";
95 case xcore: return "xcore";
97 case nvptx: return "nvptx";
98 case nvptx64: return "nvptx";
100 case le32: return "le32";
101 case le64: return "le64";
104 case amdil64: return "amdil";
107 case hsail64: return "hsail";
110 case spir64: return "spir";
111 case kalimba: return "kalimba";
115 const char *Triple::getVendorTypeName(VendorType Kind) {
117 case UnknownVendor: return "unknown";
119 case Apple: return "apple";
120 case PC: return "pc";
121 case SCEI: return "scei";
122 case BGP: return "bgp";
123 case BGQ: return "bgq";
124 case Freescale: return "fsl";
125 case IBM: return "ibm";
126 case ImaginationTechnologies: return "img";
127 case MipsTechnologies: return "mti";
128 case NVIDIA: return "nvidia";
129 case CSR: return "csr";
132 llvm_unreachable("Invalid VendorType!");
135 const char *Triple::getOSTypeName(OSType Kind) {
137 case UnknownOS: return "unknown";
139 case Darwin: return "darwin";
140 case DragonFly: return "dragonfly";
141 case FreeBSD: return "freebsd";
142 case IOS: return "ios";
143 case KFreeBSD: return "kfreebsd";
144 case Linux: return "linux";
145 case Lv2: return "lv2";
146 case MacOSX: return "macosx";
147 case NetBSD: return "netbsd";
148 case OpenBSD: return "openbsd";
149 case Solaris: return "solaris";
150 case Win32: return "windows";
151 case Haiku: return "haiku";
152 case Minix: return "minix";
153 case RTEMS: return "rtems";
154 case NaCl: return "nacl";
155 case CNK: return "cnk";
156 case Bitrig: return "bitrig";
157 case AIX: return "aix";
158 case CUDA: return "cuda";
159 case NVCL: return "nvcl";
162 llvm_unreachable("Invalid OSType");
165 const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
167 case UnknownEnvironment: return "unknown";
168 case GNU: return "gnu";
169 case GNUEABIHF: return "gnueabihf";
170 case GNUEABI: return "gnueabi";
171 case GNUX32: return "gnux32";
172 case CODE16: return "code16";
173 case EABI: return "eabi";
174 case EABIHF: return "eabihf";
175 case Android: return "android";
176 case MSVC: return "msvc";
177 case Itanium: return "itanium";
178 case Cygnus: return "cygnus";
181 llvm_unreachable("Invalid EnvironmentType!");
184 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
185 return StringSwitch<Triple::ArchType>(Name)
186 .Case("aarch64", aarch64)
187 .Case("aarch64_be", aarch64_be)
188 .Case("arm64", aarch64) // "arm64" is an alias for "aarch64"
190 .Case("armeb", armeb)
192 .Case("mipsel", mipsel)
193 .Case("mips64", mips64)
194 .Case("mips64el", mips64el)
195 .Case("msp430", msp430)
196 .Case("ppc64", ppc64)
199 .Case("ppc64le", ppc64le)
201 .Case("hexagon", hexagon)
202 .Case("sparc", sparc)
203 .Case("sparcv9", sparcv9)
204 .Case("systemz", systemz)
206 .Case("thumb", thumb)
207 .Case("thumbeb", thumbeb)
209 .Case("x86-64", x86_64)
210 .Case("xcore", xcore)
211 .Case("nvptx", nvptx)
212 .Case("nvptx64", nvptx64)
215 .Case("amdil", amdil)
216 .Case("amdil64", amdil64)
217 .Case("hsail", hsail)
218 .Case("hsail64", hsail64)
220 .Case("spir64", spir64)
221 .Case("kalimba", kalimba)
222 .Default(UnknownArch);
225 static Triple::ArchType parseARMArch(StringRef ArchName) {
226 size_t offset = StringRef::npos;
227 Triple::ArchType arch = Triple::UnknownArch;
228 bool isThumb = ArchName.startswith("thumb");
230 if (ArchName.equals("arm"))
232 if (ArchName.equals("armeb"))
233 return Triple::armeb;
234 if (ArchName.equals("thumb"))
235 return Triple::thumb;
236 if (ArchName.equals("thumbeb"))
237 return Triple::thumbeb;
238 if (ArchName.equals("arm64") || ArchName.equals("aarch64"))
239 return Triple::aarch64;
240 if (ArchName.equals("aarch64_be"))
241 return Triple::aarch64_be;
243 if (ArchName.startswith("armv")) {
246 } else if (ArchName.startswith("armebv")) {
248 arch = Triple::armeb;
249 } else if (ArchName.startswith("thumbv")) {
251 arch = Triple::thumb;
252 } else if (ArchName.startswith("thumbebv")) {
254 arch = Triple::thumbeb;
256 return StringSwitch<Triple::ArchType>(ArchName.substr(offset))
257 .Cases("v2", "v2a", isThumb ? Triple::UnknownArch : arch)
258 .Cases("v3", "v3m", isThumb ? Triple::UnknownArch : arch)
259 .Cases("v4", "v4t", arch)
260 .Cases("v5", "v5e", "v5t", "v5te", "v5tej", arch)
261 .Cases("v6", "v6j", "v6k", "v6m", arch)
262 .Cases("v6t2", "v6z", "v6zk", arch)
263 .Cases("v7", "v7a", "v7em", "v7l", arch)
264 .Cases("v7m", "v7r", "v7s", arch)
265 .Cases("v8", "v8a", arch)
266 .Default(Triple::UnknownArch);
269 static Triple::ArchType parseArch(StringRef ArchName) {
270 return StringSwitch<Triple::ArchType>(ArchName)
271 .Cases("i386", "i486", "i586", "i686", Triple::x86)
272 // FIXME: Do we need to support these?
273 .Cases("i786", "i886", "i986", Triple::x86)
274 .Cases("amd64", "x86_64", "x86_64h", Triple::x86_64)
275 .Case("powerpc", Triple::ppc)
276 .Cases("powerpc64", "ppu", Triple::ppc64)
277 .Case("powerpc64le", Triple::ppc64le)
278 .Case("xscale", Triple::arm)
279 .StartsWith("arm", parseARMArch(ArchName))
280 .StartsWith("thumb", parseARMArch(ArchName))
281 .StartsWith("aarch64", parseARMArch(ArchName))
282 .Case("msp430", Triple::msp430)
283 .Cases("mips", "mipseb", "mipsallegrex", Triple::mips)
284 .Cases("mipsel", "mipsallegrexel", Triple::mipsel)
285 .Cases("mips64", "mips64eb", Triple::mips64)
286 .Case("mips64el", Triple::mips64el)
287 .Case("r600", Triple::r600)
288 .Case("hexagon", Triple::hexagon)
289 .Case("s390x", Triple::systemz)
290 .Case("sparc", Triple::sparc)
291 .Cases("sparcv9", "sparc64", Triple::sparcv9)
292 .Case("tce", Triple::tce)
293 .Case("xcore", Triple::xcore)
294 .Case("nvptx", Triple::nvptx)
295 .Case("nvptx64", Triple::nvptx64)
296 .Case("le32", Triple::le32)
297 .Case("le64", Triple::le64)
298 .Case("amdil", Triple::amdil)
299 .Case("amdil64", Triple::amdil64)
300 .Case("hsail", Triple::hsail)
301 .Case("hsail64", Triple::hsail64)
302 .Case("spir", Triple::spir)
303 .Case("spir64", Triple::spir64)
304 .StartsWith("kalimba", Triple::kalimba)
305 .Default(Triple::UnknownArch);
308 static Triple::VendorType parseVendor(StringRef VendorName) {
309 return StringSwitch<Triple::VendorType>(VendorName)
310 .Case("apple", Triple::Apple)
311 .Case("pc", Triple::PC)
312 .Case("scei", Triple::SCEI)
313 .Case("bgp", Triple::BGP)
314 .Case("bgq", Triple::BGQ)
315 .Case("fsl", Triple::Freescale)
316 .Case("ibm", Triple::IBM)
317 .Case("img", Triple::ImaginationTechnologies)
318 .Case("mti", Triple::MipsTechnologies)
319 .Case("nvidia", Triple::NVIDIA)
320 .Case("csr", Triple::CSR)
321 .Default(Triple::UnknownVendor);
324 static Triple::OSType parseOS(StringRef OSName) {
325 return StringSwitch<Triple::OSType>(OSName)
326 .StartsWith("darwin", Triple::Darwin)
327 .StartsWith("dragonfly", Triple::DragonFly)
328 .StartsWith("freebsd", Triple::FreeBSD)
329 .StartsWith("ios", Triple::IOS)
330 .StartsWith("kfreebsd", Triple::KFreeBSD)
331 .StartsWith("linux", Triple::Linux)
332 .StartsWith("lv2", Triple::Lv2)
333 .StartsWith("macosx", Triple::MacOSX)
334 .StartsWith("netbsd", Triple::NetBSD)
335 .StartsWith("openbsd", Triple::OpenBSD)
336 .StartsWith("solaris", Triple::Solaris)
337 .StartsWith("win32", Triple::Win32)
338 .StartsWith("windows", Triple::Win32)
339 .StartsWith("haiku", Triple::Haiku)
340 .StartsWith("minix", Triple::Minix)
341 .StartsWith("rtems", Triple::RTEMS)
342 .StartsWith("nacl", Triple::NaCl)
343 .StartsWith("cnk", Triple::CNK)
344 .StartsWith("bitrig", Triple::Bitrig)
345 .StartsWith("aix", Triple::AIX)
346 .StartsWith("cuda", Triple::CUDA)
347 .StartsWith("nvcl", Triple::NVCL)
348 .Default(Triple::UnknownOS);
351 static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) {
352 return StringSwitch<Triple::EnvironmentType>(EnvironmentName)
353 .StartsWith("eabihf", Triple::EABIHF)
354 .StartsWith("eabi", Triple::EABI)
355 .StartsWith("gnueabihf", Triple::GNUEABIHF)
356 .StartsWith("gnueabi", Triple::GNUEABI)
357 .StartsWith("gnux32", Triple::GNUX32)
358 .StartsWith("code16", Triple::CODE16)
359 .StartsWith("gnu", Triple::GNU)
360 .StartsWith("android", Triple::Android)
361 .StartsWith("msvc", Triple::MSVC)
362 .StartsWith("itanium", Triple::Itanium)
363 .StartsWith("cygnus", Triple::Cygnus)
364 .Default(Triple::UnknownEnvironment);
367 static Triple::ObjectFormatType parseFormat(StringRef EnvironmentName) {
368 return StringSwitch<Triple::ObjectFormatType>(EnvironmentName)
369 .EndsWith("coff", Triple::COFF)
370 .EndsWith("elf", Triple::ELF)
371 .EndsWith("macho", Triple::MachO)
372 .Default(Triple::UnknownObjectFormat);
375 static Triple::SubArchType parseSubArch(StringRef SubArchName) {
376 return StringSwitch<Triple::SubArchType>(SubArchName)
377 .EndsWith("v8", Triple::ARMSubArch_v8)
378 .EndsWith("v8a", Triple::ARMSubArch_v8)
379 .EndsWith("v7", Triple::ARMSubArch_v7)
380 .EndsWith("v7a", Triple::ARMSubArch_v7)
381 .EndsWith("v7em", Triple::ARMSubArch_v7em)
382 .EndsWith("v7l", Triple::ARMSubArch_v7)
383 .EndsWith("v7m", Triple::ARMSubArch_v7m)
384 .EndsWith("v7r", Triple::ARMSubArch_v7)
385 .EndsWith("v7s", Triple::ARMSubArch_v7s)
386 .EndsWith("v6", Triple::ARMSubArch_v6)
387 .EndsWith("v6m", Triple::ARMSubArch_v6m)
388 .EndsWith("v6t2", Triple::ARMSubArch_v6t2)
389 .EndsWith("v5", Triple::ARMSubArch_v5)
390 .EndsWith("v5e", Triple::ARMSubArch_v5)
391 .EndsWith("v5t", Triple::ARMSubArch_v5)
392 .EndsWith("v5te", Triple::ARMSubArch_v5te)
393 .EndsWith("v4t", Triple::ARMSubArch_v4t)
394 .EndsWith("kalimba3", Triple::KalimbaSubArch_v3)
395 .EndsWith("kalimba4", Triple::KalimbaSubArch_v4)
396 .EndsWith("kalimba5", Triple::KalimbaSubArch_v5)
397 .Default(Triple::NoSubArch);
400 static const char *getObjectFormatTypeName(Triple::ObjectFormatType Kind) {
402 case Triple::UnknownObjectFormat: return "";
403 case Triple::COFF: return "coff";
404 case Triple::ELF: return "elf";
405 case Triple::MachO: return "macho";
407 llvm_unreachable("unknown object format type");
410 static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
412 return Triple::MachO;
413 else if (T.isOSWindows())
418 /// \brief Construct a triple from the string representation provided.
420 /// This stores the string representation and parses the various pieces into
422 Triple::Triple(const Twine &Str)
424 Arch(parseArch(getArchName())),
425 SubArch(parseSubArch(getArchName())),
426 Vendor(parseVendor(getVendorName())),
427 OS(parseOS(getOSName())),
428 Environment(parseEnvironment(getEnvironmentName())),
429 ObjectFormat(parseFormat(getEnvironmentName())) {
430 if (ObjectFormat == Triple::UnknownObjectFormat)
431 ObjectFormat = getDefaultFormat(*this);
434 /// \brief Construct a triple from string representations of the architecture,
437 /// This joins each argument into a canonical string representation and parses
438 /// them into enum members. It leaves the environment unknown and omits it from
439 /// the string representation.
440 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr)
441 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()),
442 Arch(parseArch(ArchStr.str())),
443 SubArch(parseSubArch(ArchStr.str())),
444 Vendor(parseVendor(VendorStr.str())),
445 OS(parseOS(OSStr.str())),
446 Environment(), ObjectFormat(Triple::UnknownObjectFormat) {
447 ObjectFormat = getDefaultFormat(*this);
450 /// \brief Construct a triple from string representations of the architecture,
451 /// vendor, OS, and environment.
453 /// This joins each argument into a canonical string representation and parses
454 /// them into enum members.
455 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr,
456 const Twine &EnvironmentStr)
457 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr + Twine('-') +
458 EnvironmentStr).str()),
459 Arch(parseArch(ArchStr.str())),
460 SubArch(parseSubArch(ArchStr.str())),
461 Vendor(parseVendor(VendorStr.str())),
462 OS(parseOS(OSStr.str())),
463 Environment(parseEnvironment(EnvironmentStr.str())),
464 ObjectFormat(parseFormat(EnvironmentStr.str())) {
465 if (ObjectFormat == Triple::UnknownObjectFormat)
466 ObjectFormat = getDefaultFormat(*this);
469 std::string Triple::normalize(StringRef Str) {
470 bool IsMinGW32 = false;
471 bool IsCygwin = false;
473 // Parse into components.
474 SmallVector<StringRef, 4> Components;
475 Str.split(Components, "-");
477 // If the first component corresponds to a known architecture, preferentially
478 // use it for the architecture. If the second component corresponds to a
479 // known vendor, preferentially use it for the vendor, etc. This avoids silly
480 // component movement when a component parses as (eg) both a valid arch and a
482 ArchType Arch = UnknownArch;
483 if (Components.size() > 0)
484 Arch = parseArch(Components[0]);
485 VendorType Vendor = UnknownVendor;
486 if (Components.size() > 1)
487 Vendor = parseVendor(Components[1]);
488 OSType OS = UnknownOS;
489 if (Components.size() > 2) {
490 OS = parseOS(Components[2]);
491 IsCygwin = Components[2].startswith("cygwin");
492 IsMinGW32 = Components[2].startswith("mingw");
494 EnvironmentType Environment = UnknownEnvironment;
495 if (Components.size() > 3)
496 Environment = parseEnvironment(Components[3]);
497 ObjectFormatType ObjectFormat = UnknownObjectFormat;
498 if (Components.size() > 4)
499 ObjectFormat = parseFormat(Components[4]);
501 // Note which components are already in their final position. These will not
504 Found[0] = Arch != UnknownArch;
505 Found[1] = Vendor != UnknownVendor;
506 Found[2] = OS != UnknownOS;
507 Found[3] = Environment != UnknownEnvironment;
509 // If they are not there already, permute the components into their canonical
510 // positions by seeing if they parse as a valid architecture, and if so moving
511 // the component to the architecture position etc.
512 for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) {
514 continue; // Already in the canonical position.
516 for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
517 // Do not reparse any components that already matched.
518 if (Idx < array_lengthof(Found) && Found[Idx])
521 // Does this component parse as valid for the target position?
523 StringRef Comp = Components[Idx];
525 default: llvm_unreachable("unexpected component type!");
527 Arch = parseArch(Comp);
528 Valid = Arch != UnknownArch;
531 Vendor = parseVendor(Comp);
532 Valid = Vendor != UnknownVendor;
536 IsCygwin = Comp.startswith("cygwin");
537 IsMinGW32 = Comp.startswith("mingw");
538 Valid = OS != UnknownOS || IsCygwin || IsMinGW32;
541 Environment = parseEnvironment(Comp);
542 Valid = Environment != UnknownEnvironment;
544 ObjectFormat = parseFormat(Comp);
545 Valid = ObjectFormat != UnknownObjectFormat;
550 continue; // Nope, try the next component.
552 // Move the component to the target position, pushing any non-fixed
553 // components that are in the way to the right. This tends to give
554 // good results in the common cases of a forgotten vendor component
555 // or a wrongly positioned environment.
557 // Insert left, pushing the existing components to the right. For
558 // example, a-b-i386 -> i386-a-b when moving i386 to the front.
559 StringRef CurrentComponent(""); // The empty component.
560 // Replace the component we are moving with an empty component.
561 std::swap(CurrentComponent, Components[Idx]);
562 // Insert the component being moved at Pos, displacing any existing
563 // components to the right.
564 for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
565 // Skip over any fixed components.
566 while (i < array_lengthof(Found) && Found[i])
568 // Place the component at the new position, getting the component
569 // that was at this position - it will be moved right.
570 std::swap(CurrentComponent, Components[i]);
572 } else if (Pos > Idx) {
573 // Push right by inserting empty components until the component at Idx
574 // reaches the target position Pos. For example, pc-a -> -pc-a when
575 // moving pc to the second position.
577 // Insert one empty component at Idx.
578 StringRef CurrentComponent(""); // The empty component.
579 for (unsigned i = Idx; i < Components.size();) {
580 // Place the component at the new position, getting the component
581 // that was at this position - it will be moved right.
582 std::swap(CurrentComponent, Components[i]);
583 // If it was placed on top of an empty component then we are done.
584 if (CurrentComponent.empty())
586 // Advance to the next component, skipping any fixed components.
587 while (++i < array_lengthof(Found) && Found[i])
590 // The last component was pushed off the end - append it.
591 if (!CurrentComponent.empty())
592 Components.push_back(CurrentComponent);
594 // Advance Idx to the component's new position.
595 while (++Idx < array_lengthof(Found) && Found[Idx])
597 } while (Idx < Pos); // Add more until the final position is reached.
599 assert(Pos < Components.size() && Components[Pos] == Comp &&
600 "Component moved wrong!");
606 // Special case logic goes here. At this point Arch, Vendor and OS have the
607 // correct values for the computed components.
609 if (OS == Triple::Win32) {
610 Components.resize(4);
611 Components[2] = "windows";
612 if (Environment == UnknownEnvironment) {
613 if (ObjectFormat == UnknownObjectFormat || ObjectFormat == Triple::COFF)
614 Components[3] = "msvc";
616 Components[3] = getObjectFormatTypeName(ObjectFormat);
618 } else if (IsMinGW32) {
619 Components.resize(4);
620 Components[2] = "windows";
621 Components[3] = "gnu";
622 } else if (IsCygwin) {
623 Components.resize(4);
624 Components[2] = "windows";
625 Components[3] = "cygnus";
627 if (IsMinGW32 || IsCygwin ||
628 (OS == Triple::Win32 && Environment != UnknownEnvironment)) {
629 if (ObjectFormat != UnknownObjectFormat && ObjectFormat != Triple::COFF) {
630 Components.resize(5);
631 Components[4] = getObjectFormatTypeName(ObjectFormat);
635 // Stick the corrected components back together to form the normalized string.
636 std::string Normalized;
637 for (unsigned i = 0, e = Components.size(); i != e; ++i) {
638 if (i) Normalized += '-';
639 Normalized += Components[i];
644 StringRef Triple::getArchName() const {
645 return StringRef(Data).split('-').first; // Isolate first component
648 StringRef Triple::getVendorName() const {
649 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
650 return Tmp.split('-').first; // Isolate second component
653 StringRef Triple::getOSName() const {
654 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
655 Tmp = Tmp.split('-').second; // Strip second component
656 return Tmp.split('-').first; // Isolate third component
659 StringRef Triple::getEnvironmentName() const {
660 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
661 Tmp = Tmp.split('-').second; // Strip second component
662 return Tmp.split('-').second; // Strip third component
665 StringRef Triple::getOSAndEnvironmentName() const {
666 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
667 return Tmp.split('-').second; // Strip second component
670 static unsigned EatNumber(StringRef &Str) {
671 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
675 // Consume the leading digit.
676 Result = Result*10 + (Str[0] - '0');
680 } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9');
685 void Triple::getOSVersion(unsigned &Major, unsigned &Minor,
686 unsigned &Micro) const {
687 StringRef OSName = getOSName();
689 // Assume that the OS portion of the triple starts with the canonical name.
690 StringRef OSTypeName = getOSTypeName(getOS());
691 if (OSName.startswith(OSTypeName))
692 OSName = OSName.substr(OSTypeName.size());
694 // Any unset version defaults to 0.
695 Major = Minor = Micro = 0;
697 // Parse up to three components.
698 unsigned *Components[3] = { &Major, &Minor, &Micro };
699 for (unsigned i = 0; i != 3; ++i) {
700 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
703 // Consume the leading number.
704 *Components[i] = EatNumber(OSName);
706 // Consume the separator, if present.
707 if (OSName.startswith("."))
708 OSName = OSName.substr(1);
712 bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor,
713 unsigned &Micro) const {
714 getOSVersion(Major, Minor, Micro);
717 default: llvm_unreachable("unexpected OS for Darwin triple");
719 // Default to darwin8, i.e., MacOSX 10.4.
722 // Darwin version numbers are skewed from OS X versions.
739 // Ignore the version from the triple. This is only handled because the
740 // the clang driver combines OS X and IOS support into a common Darwin
741 // toolchain that wants to know the OS X version number even when targeting
751 void Triple::getiOSVersion(unsigned &Major, unsigned &Minor,
752 unsigned &Micro) const {
754 default: llvm_unreachable("unexpected OS for Darwin triple");
757 // Ignore the version from the triple. This is only handled because the
758 // the clang driver combines OS X and IOS support into a common Darwin
759 // toolchain that wants to know the iOS version number even when targeting
766 getOSVersion(Major, Minor, Micro);
767 // Default to 5.0 (or 7.0 for arm64).
769 Major = (getArch() == aarch64) ? 7 : 5;
774 void Triple::setTriple(const Twine &Str) {
778 void Triple::setArch(ArchType Kind) {
779 setArchName(getArchTypeName(Kind));
782 void Triple::setVendor(VendorType Kind) {
783 setVendorName(getVendorTypeName(Kind));
786 void Triple::setOS(OSType Kind) {
787 setOSName(getOSTypeName(Kind));
790 void Triple::setEnvironment(EnvironmentType Kind) {
791 setEnvironmentName(getEnvironmentTypeName(Kind));
794 void Triple::setObjectFormat(ObjectFormatType Kind) {
795 if (Environment == UnknownEnvironment)
796 return setEnvironmentName(getObjectFormatTypeName(Kind));
798 setEnvironmentName((getEnvironmentTypeName(Environment) + Twine("-") +
799 getObjectFormatTypeName(Kind)).str());
802 void Triple::setArchName(StringRef Str) {
803 // Work around a miscompilation bug for Twines in gcc 4.0.3.
804 SmallString<64> Triple;
807 Triple += getVendorName();
809 Triple += getOSAndEnvironmentName();
810 setTriple(Triple.str());
813 void Triple::setVendorName(StringRef Str) {
814 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
817 void Triple::setOSName(StringRef Str) {
818 if (hasEnvironment())
819 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
820 "-" + getEnvironmentName());
822 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
825 void Triple::setEnvironmentName(StringRef Str) {
826 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
830 void Triple::setOSAndEnvironmentName(StringRef Str) {
831 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
834 static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
836 case llvm::Triple::UnknownArch:
839 case llvm::Triple::msp430:
842 case llvm::Triple::arm:
843 case llvm::Triple::armeb:
844 case llvm::Triple::hexagon:
845 case llvm::Triple::le32:
846 case llvm::Triple::mips:
847 case llvm::Triple::mipsel:
848 case llvm::Triple::nvptx:
849 case llvm::Triple::ppc:
850 case llvm::Triple::r600:
851 case llvm::Triple::sparc:
852 case llvm::Triple::tce:
853 case llvm::Triple::thumb:
854 case llvm::Triple::thumbeb:
855 case llvm::Triple::x86:
856 case llvm::Triple::xcore:
857 case llvm::Triple::amdil:
858 case llvm::Triple::hsail:
859 case llvm::Triple::spir:
860 case llvm::Triple::kalimba:
863 case llvm::Triple::aarch64:
864 case llvm::Triple::aarch64_be:
865 case llvm::Triple::le64:
866 case llvm::Triple::mips64:
867 case llvm::Triple::mips64el:
868 case llvm::Triple::nvptx64:
869 case llvm::Triple::ppc64:
870 case llvm::Triple::ppc64le:
871 case llvm::Triple::sparcv9:
872 case llvm::Triple::systemz:
873 case llvm::Triple::x86_64:
874 case llvm::Triple::amdil64:
875 case llvm::Triple::hsail64:
876 case llvm::Triple::spir64:
879 llvm_unreachable("Invalid architecture value");
882 bool Triple::isArch64Bit() const {
883 return getArchPointerBitWidth(getArch()) == 64;
886 bool Triple::isArch32Bit() const {
887 return getArchPointerBitWidth(getArch()) == 32;
890 bool Triple::isArch16Bit() const {
891 return getArchPointerBitWidth(getArch()) == 16;
894 Triple Triple::get32BitArchVariant() const {
897 case Triple::UnknownArch:
898 case Triple::aarch64:
899 case Triple::aarch64_be:
901 case Triple::systemz:
902 case Triple::ppc64le:
903 T.setArch(UnknownArch);
911 case Triple::hexagon:
912 case Triple::kalimba:
922 case Triple::thumbeb:
928 case Triple::le64: T.setArch(Triple::le32); break;
929 case Triple::mips64: T.setArch(Triple::mips); break;
930 case Triple::mips64el: T.setArch(Triple::mipsel); break;
931 case Triple::nvptx64: T.setArch(Triple::nvptx); break;
932 case Triple::ppc64: T.setArch(Triple::ppc); break;
933 case Triple::sparcv9: T.setArch(Triple::sparc); break;
934 case Triple::x86_64: T.setArch(Triple::x86); break;
935 case Triple::amdil64: T.setArch(Triple::amdil); break;
936 case Triple::hsail64: T.setArch(Triple::hsail); break;
937 case Triple::spir64: T.setArch(Triple::spir); break;
942 Triple Triple::get64BitArchVariant() const {
945 case Triple::UnknownArch:
948 case Triple::hexagon:
949 case Triple::kalimba:
954 case Triple::thumbeb:
956 T.setArch(UnknownArch);
959 case Triple::aarch64:
960 case Triple::aarch64_be:
962 case Triple::amdil64:
963 case Triple::hsail64:
966 case Triple::mips64el:
967 case Triple::nvptx64:
969 case Triple::ppc64le:
970 case Triple::sparcv9:
971 case Triple::systemz:
976 case Triple::le32: T.setArch(Triple::le64); break;
977 case Triple::mips: T.setArch(Triple::mips64); break;
978 case Triple::mipsel: T.setArch(Triple::mips64el); break;
979 case Triple::nvptx: T.setArch(Triple::nvptx64); break;
980 case Triple::ppc: T.setArch(Triple::ppc64); break;
981 case Triple::sparc: T.setArch(Triple::sparcv9); break;
982 case Triple::x86: T.setArch(Triple::x86_64); break;
983 case Triple::amdil: T.setArch(Triple::amdil64); break;
984 case Triple::hsail: T.setArch(Triple::hsail64); break;
985 case Triple::spir: T.setArch(Triple::spir64); break;
990 // FIXME: tblgen this.
991 const char *Triple::getARMCPUForArch(StringRef MArch) const {
993 MArch = getArchName();
996 case llvm::Triple::FreeBSD:
997 case llvm::Triple::NetBSD:
998 if (MArch == "armv6")
999 return "arm1176jzf-s";
1001 case llvm::Triple::Win32:
1002 // FIXME: this is invalid for WindowsCE
1008 const char *result = nullptr;
1009 size_t offset = StringRef::npos;
1010 if (MArch.startswith("arm"))
1012 if (MArch.startswith("thumb"))
1014 if (offset != StringRef::npos && MArch.substr(offset, 2) == "eb")
1016 if (offset != StringRef::npos)
1017 result = llvm::StringSwitch<const char *>(MArch.substr(offset))
1018 .Cases("v2", "v2a", "arm2")
1020 .Case("v3m", "arm7m")
1021 .Case("v4", "strongarm")
1022 .Case("v4t", "arm7tdmi")
1023 .Cases("v5", "v5t", "arm10tdmi")
1024 .Cases("v5e", "v5te", "arm1022e")
1025 .Case("v5tej", "arm926ej-s")
1026 .Cases("v6", "v6k", "arm1136jf-s")
1027 .Case("v6j", "arm1136j-s")
1028 .Cases("v6z", "v6zk", "arm1176jzf-s")
1029 .Case("v6t2", "arm1156t2-s")
1030 .Cases("v6m", "v6-m", "cortex-m0")
1031 .Cases("v7", "v7a", "v7-a", "v7l", "v7-l", "cortex-a8")
1032 .Cases("v7s", "v7-s", "swift")
1033 .Cases("v7r", "v7-r", "cortex-r4")
1034 .Cases("v7m", "v7-m", "cortex-m3")
1035 .Cases("v7em", "v7e-m", "cortex-m4")
1036 .Cases("v8", "v8a", "v8-a", "cortex-a53")
1039 result = llvm::StringSwitch<const char *>(MArch)
1040 .Case("ep9312", "ep9312")
1041 .Case("iwmmxt", "iwmmxt")
1042 .Case("xscale", "xscale")
1048 // If all else failed, return the most base CPU with thumb interworking
1049 // supported by LLVM.
1050 // FIXME: Should warn once that we're falling back.
1052 case llvm::Triple::NetBSD:
1053 switch (getEnvironment()) {
1054 case llvm::Triple::GNUEABIHF:
1055 case llvm::Triple::GNUEABI:
1056 case llvm::Triple::EABIHF:
1057 case llvm::Triple::EABI:
1058 return "arm926ej-s";
1063 switch (getEnvironment()) {
1064 case llvm::Triple::EABIHF:
1065 case llvm::Triple::GNUEABIHF:
1066 return "arm1176jzf-s";