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";
160 case AMDHSA: return "amdhsa";
163 llvm_unreachable("Invalid OSType");
166 const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
168 case UnknownEnvironment: return "unknown";
169 case GNU: return "gnu";
170 case GNUEABIHF: return "gnueabihf";
171 case GNUEABI: return "gnueabi";
172 case GNUX32: return "gnux32";
173 case CODE16: return "code16";
174 case EABI: return "eabi";
175 case EABIHF: return "eabihf";
176 case Android: return "android";
177 case MSVC: return "msvc";
178 case Itanium: return "itanium";
179 case Cygnus: return "cygnus";
182 llvm_unreachable("Invalid EnvironmentType!");
185 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
186 return StringSwitch<Triple::ArchType>(Name)
187 .Case("aarch64", aarch64)
188 .Case("aarch64_be", aarch64_be)
189 .Case("arm64", aarch64) // "arm64" is an alias for "aarch64"
191 .Case("armeb", armeb)
193 .Case("mipsel", mipsel)
194 .Case("mips64", mips64)
195 .Case("mips64el", mips64el)
196 .Case("msp430", msp430)
197 .Case("ppc64", ppc64)
200 .Case("ppc64le", ppc64le)
202 .Case("hexagon", hexagon)
203 .Case("sparc", sparc)
204 .Case("sparcv9", sparcv9)
205 .Case("systemz", systemz)
207 .Case("thumb", thumb)
208 .Case("thumbeb", thumbeb)
210 .Case("x86-64", x86_64)
211 .Case("xcore", xcore)
212 .Case("nvptx", nvptx)
213 .Case("nvptx64", nvptx64)
216 .Case("amdil", amdil)
217 .Case("amdil64", amdil64)
218 .Case("hsail", hsail)
219 .Case("hsail64", hsail64)
221 .Case("spir64", spir64)
222 .Case("kalimba", kalimba)
223 .Default(UnknownArch);
226 static Triple::ArchType parseARMArch(StringRef ArchName) {
227 size_t offset = StringRef::npos;
228 Triple::ArchType arch = Triple::UnknownArch;
229 bool isThumb = ArchName.startswith("thumb");
231 if (ArchName.equals("arm"))
233 if (ArchName.equals("armeb"))
234 return Triple::armeb;
235 if (ArchName.equals("thumb"))
236 return Triple::thumb;
237 if (ArchName.equals("thumbeb"))
238 return Triple::thumbeb;
239 if (ArchName.equals("arm64") || ArchName.equals("aarch64"))
240 return Triple::aarch64;
241 if (ArchName.equals("aarch64_be"))
242 return Triple::aarch64_be;
244 if (ArchName.startswith("armv")) {
247 } else if (ArchName.startswith("armebv")) {
249 arch = Triple::armeb;
250 } else if (ArchName.startswith("thumbv")) {
252 arch = Triple::thumb;
253 } else if (ArchName.startswith("thumbebv")) {
255 arch = Triple::thumbeb;
257 return StringSwitch<Triple::ArchType>(ArchName.substr(offset))
258 .Cases("v2", "v2a", isThumb ? Triple::UnknownArch : arch)
259 .Cases("v3", "v3m", isThumb ? Triple::UnknownArch : arch)
260 .Cases("v4", "v4t", arch)
261 .Cases("v5", "v5e", "v5t", "v5te", "v5tej", arch)
262 .Cases("v6", "v6j", "v6k", "v6m", arch)
263 .Cases("v6t2", "v6z", "v6zk", arch)
264 .Cases("v7", "v7a", "v7em", "v7l", arch)
265 .Cases("v7m", "v7r", "v7s", arch)
266 .Cases("v8", "v8a", arch)
267 .Default(Triple::UnknownArch);
270 static Triple::ArchType parseArch(StringRef ArchName) {
271 return StringSwitch<Triple::ArchType>(ArchName)
272 .Cases("i386", "i486", "i586", "i686", Triple::x86)
273 // FIXME: Do we need to support these?
274 .Cases("i786", "i886", "i986", Triple::x86)
275 .Cases("amd64", "x86_64", "x86_64h", Triple::x86_64)
276 .Case("powerpc", Triple::ppc)
277 .Cases("powerpc64", "ppu", Triple::ppc64)
278 .Case("powerpc64le", Triple::ppc64le)
279 .Case("xscale", Triple::arm)
280 .StartsWith("arm", parseARMArch(ArchName))
281 .StartsWith("thumb", parseARMArch(ArchName))
282 .StartsWith("aarch64", parseARMArch(ArchName))
283 .Case("msp430", Triple::msp430)
284 .Cases("mips", "mipseb", "mipsallegrex", Triple::mips)
285 .Cases("mipsel", "mipsallegrexel", Triple::mipsel)
286 .Cases("mips64", "mips64eb", Triple::mips64)
287 .Case("mips64el", Triple::mips64el)
288 .Case("r600", Triple::r600)
289 .Case("hexagon", Triple::hexagon)
290 .Case("s390x", Triple::systemz)
291 .Case("sparc", Triple::sparc)
292 .Cases("sparcv9", "sparc64", Triple::sparcv9)
293 .Case("tce", Triple::tce)
294 .Case("xcore", Triple::xcore)
295 .Case("nvptx", Triple::nvptx)
296 .Case("nvptx64", Triple::nvptx64)
297 .Case("le32", Triple::le32)
298 .Case("le64", Triple::le64)
299 .Case("amdil", Triple::amdil)
300 .Case("amdil64", Triple::amdil64)
301 .Case("hsail", Triple::hsail)
302 .Case("hsail64", Triple::hsail64)
303 .Case("spir", Triple::spir)
304 .Case("spir64", Triple::spir64)
305 .StartsWith("kalimba", Triple::kalimba)
306 .Default(Triple::UnknownArch);
309 static Triple::VendorType parseVendor(StringRef VendorName) {
310 return StringSwitch<Triple::VendorType>(VendorName)
311 .Case("apple", Triple::Apple)
312 .Case("pc", Triple::PC)
313 .Case("scei", Triple::SCEI)
314 .Case("bgp", Triple::BGP)
315 .Case("bgq", Triple::BGQ)
316 .Case("fsl", Triple::Freescale)
317 .Case("ibm", Triple::IBM)
318 .Case("img", Triple::ImaginationTechnologies)
319 .Case("mti", Triple::MipsTechnologies)
320 .Case("nvidia", Triple::NVIDIA)
321 .Case("csr", Triple::CSR)
322 .Default(Triple::UnknownVendor);
325 static Triple::OSType parseOS(StringRef OSName) {
326 return StringSwitch<Triple::OSType>(OSName)
327 .StartsWith("darwin", Triple::Darwin)
328 .StartsWith("dragonfly", Triple::DragonFly)
329 .StartsWith("freebsd", Triple::FreeBSD)
330 .StartsWith("ios", Triple::IOS)
331 .StartsWith("kfreebsd", Triple::KFreeBSD)
332 .StartsWith("linux", Triple::Linux)
333 .StartsWith("lv2", Triple::Lv2)
334 .StartsWith("macosx", Triple::MacOSX)
335 .StartsWith("netbsd", Triple::NetBSD)
336 .StartsWith("openbsd", Triple::OpenBSD)
337 .StartsWith("solaris", Triple::Solaris)
338 .StartsWith("win32", Triple::Win32)
339 .StartsWith("windows", Triple::Win32)
340 .StartsWith("haiku", Triple::Haiku)
341 .StartsWith("minix", Triple::Minix)
342 .StartsWith("rtems", Triple::RTEMS)
343 .StartsWith("nacl", Triple::NaCl)
344 .StartsWith("cnk", Triple::CNK)
345 .StartsWith("bitrig", Triple::Bitrig)
346 .StartsWith("aix", Triple::AIX)
347 .StartsWith("cuda", Triple::CUDA)
348 .StartsWith("nvcl", Triple::NVCL)
349 .StartsWith("amdhsa", Triple::AMDHSA)
350 .Default(Triple::UnknownOS);
353 static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) {
354 return StringSwitch<Triple::EnvironmentType>(EnvironmentName)
355 .StartsWith("eabihf", Triple::EABIHF)
356 .StartsWith("eabi", Triple::EABI)
357 .StartsWith("gnueabihf", Triple::GNUEABIHF)
358 .StartsWith("gnueabi", Triple::GNUEABI)
359 .StartsWith("gnux32", Triple::GNUX32)
360 .StartsWith("code16", Triple::CODE16)
361 .StartsWith("gnu", Triple::GNU)
362 .StartsWith("android", Triple::Android)
363 .StartsWith("msvc", Triple::MSVC)
364 .StartsWith("itanium", Triple::Itanium)
365 .StartsWith("cygnus", Triple::Cygnus)
366 .Default(Triple::UnknownEnvironment);
369 static Triple::ObjectFormatType parseFormat(StringRef EnvironmentName) {
370 return StringSwitch<Triple::ObjectFormatType>(EnvironmentName)
371 .EndsWith("coff", Triple::COFF)
372 .EndsWith("elf", Triple::ELF)
373 .EndsWith("macho", Triple::MachO)
374 .Default(Triple::UnknownObjectFormat);
377 static Triple::SubArchType parseSubArch(StringRef SubArchName) {
378 return StringSwitch<Triple::SubArchType>(SubArchName)
379 .EndsWith("v8", Triple::ARMSubArch_v8)
380 .EndsWith("v8a", Triple::ARMSubArch_v8)
381 .EndsWith("v7", Triple::ARMSubArch_v7)
382 .EndsWith("v7a", Triple::ARMSubArch_v7)
383 .EndsWith("v7em", Triple::ARMSubArch_v7em)
384 .EndsWith("v7l", Triple::ARMSubArch_v7)
385 .EndsWith("v7m", Triple::ARMSubArch_v7m)
386 .EndsWith("v7r", Triple::ARMSubArch_v7)
387 .EndsWith("v7s", Triple::ARMSubArch_v7s)
388 .EndsWith("v6", Triple::ARMSubArch_v6)
389 .EndsWith("v6m", Triple::ARMSubArch_v6m)
390 .EndsWith("v6t2", Triple::ARMSubArch_v6t2)
391 .EndsWith("v5", Triple::ARMSubArch_v5)
392 .EndsWith("v5e", Triple::ARMSubArch_v5)
393 .EndsWith("v5t", Triple::ARMSubArch_v5)
394 .EndsWith("v5te", Triple::ARMSubArch_v5te)
395 .EndsWith("v4t", Triple::ARMSubArch_v4t)
396 .EndsWith("kalimba3", Triple::KalimbaSubArch_v3)
397 .EndsWith("kalimba4", Triple::KalimbaSubArch_v4)
398 .EndsWith("kalimba5", Triple::KalimbaSubArch_v5)
399 .Default(Triple::NoSubArch);
402 static const char *getObjectFormatTypeName(Triple::ObjectFormatType Kind) {
404 case Triple::UnknownObjectFormat: return "";
405 case Triple::COFF: return "coff";
406 case Triple::ELF: return "elf";
407 case Triple::MachO: return "macho";
409 llvm_unreachable("unknown object format type");
412 static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
414 return Triple::MachO;
415 else if (T.isOSWindows())
420 /// \brief Construct a triple from the string representation provided.
422 /// This stores the string representation and parses the various pieces into
424 Triple::Triple(const Twine &Str)
426 Arch(parseArch(getArchName())),
427 SubArch(parseSubArch(getArchName())),
428 Vendor(parseVendor(getVendorName())),
429 OS(parseOS(getOSName())),
430 Environment(parseEnvironment(getEnvironmentName())),
431 ObjectFormat(parseFormat(getEnvironmentName())) {
432 if (ObjectFormat == Triple::UnknownObjectFormat)
433 ObjectFormat = getDefaultFormat(*this);
436 /// \brief Construct a triple from string representations of the architecture,
439 /// This joins each argument into a canonical string representation and parses
440 /// them into enum members. It leaves the environment unknown and omits it from
441 /// the string representation.
442 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr)
443 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()),
444 Arch(parseArch(ArchStr.str())),
445 SubArch(parseSubArch(ArchStr.str())),
446 Vendor(parseVendor(VendorStr.str())),
447 OS(parseOS(OSStr.str())),
448 Environment(), ObjectFormat(Triple::UnknownObjectFormat) {
449 ObjectFormat = getDefaultFormat(*this);
452 /// \brief Construct a triple from string representations of the architecture,
453 /// vendor, OS, and environment.
455 /// This joins each argument into a canonical string representation and parses
456 /// them into enum members.
457 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr,
458 const Twine &EnvironmentStr)
459 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr + Twine('-') +
460 EnvironmentStr).str()),
461 Arch(parseArch(ArchStr.str())),
462 SubArch(parseSubArch(ArchStr.str())),
463 Vendor(parseVendor(VendorStr.str())),
464 OS(parseOS(OSStr.str())),
465 Environment(parseEnvironment(EnvironmentStr.str())),
466 ObjectFormat(parseFormat(EnvironmentStr.str())) {
467 if (ObjectFormat == Triple::UnknownObjectFormat)
468 ObjectFormat = getDefaultFormat(*this);
471 std::string Triple::normalize(StringRef Str) {
472 bool IsMinGW32 = false;
473 bool IsCygwin = false;
475 // Parse into components.
476 SmallVector<StringRef, 4> Components;
477 Str.split(Components, "-");
479 // If the first component corresponds to a known architecture, preferentially
480 // use it for the architecture. If the second component corresponds to a
481 // known vendor, preferentially use it for the vendor, etc. This avoids silly
482 // component movement when a component parses as (eg) both a valid arch and a
484 ArchType Arch = UnknownArch;
485 if (Components.size() > 0)
486 Arch = parseArch(Components[0]);
487 VendorType Vendor = UnknownVendor;
488 if (Components.size() > 1)
489 Vendor = parseVendor(Components[1]);
490 OSType OS = UnknownOS;
491 if (Components.size() > 2) {
492 OS = parseOS(Components[2]);
493 IsCygwin = Components[2].startswith("cygwin");
494 IsMinGW32 = Components[2].startswith("mingw");
496 EnvironmentType Environment = UnknownEnvironment;
497 if (Components.size() > 3)
498 Environment = parseEnvironment(Components[3]);
499 ObjectFormatType ObjectFormat = UnknownObjectFormat;
500 if (Components.size() > 4)
501 ObjectFormat = parseFormat(Components[4]);
503 // Note which components are already in their final position. These will not
506 Found[0] = Arch != UnknownArch;
507 Found[1] = Vendor != UnknownVendor;
508 Found[2] = OS != UnknownOS;
509 Found[3] = Environment != UnknownEnvironment;
511 // If they are not there already, permute the components into their canonical
512 // positions by seeing if they parse as a valid architecture, and if so moving
513 // the component to the architecture position etc.
514 for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) {
516 continue; // Already in the canonical position.
518 for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
519 // Do not reparse any components that already matched.
520 if (Idx < array_lengthof(Found) && Found[Idx])
523 // Does this component parse as valid for the target position?
525 StringRef Comp = Components[Idx];
527 default: llvm_unreachable("unexpected component type!");
529 Arch = parseArch(Comp);
530 Valid = Arch != UnknownArch;
533 Vendor = parseVendor(Comp);
534 Valid = Vendor != UnknownVendor;
538 IsCygwin = Comp.startswith("cygwin");
539 IsMinGW32 = Comp.startswith("mingw");
540 Valid = OS != UnknownOS || IsCygwin || IsMinGW32;
543 Environment = parseEnvironment(Comp);
544 Valid = Environment != UnknownEnvironment;
546 ObjectFormat = parseFormat(Comp);
547 Valid = ObjectFormat != UnknownObjectFormat;
552 continue; // Nope, try the next component.
554 // Move the component to the target position, pushing any non-fixed
555 // components that are in the way to the right. This tends to give
556 // good results in the common cases of a forgotten vendor component
557 // or a wrongly positioned environment.
559 // Insert left, pushing the existing components to the right. For
560 // example, a-b-i386 -> i386-a-b when moving i386 to the front.
561 StringRef CurrentComponent(""); // The empty component.
562 // Replace the component we are moving with an empty component.
563 std::swap(CurrentComponent, Components[Idx]);
564 // Insert the component being moved at Pos, displacing any existing
565 // components to the right.
566 for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
567 // Skip over any fixed components.
568 while (i < array_lengthof(Found) && Found[i])
570 // Place the component at the new position, getting the component
571 // that was at this position - it will be moved right.
572 std::swap(CurrentComponent, Components[i]);
574 } else if (Pos > Idx) {
575 // Push right by inserting empty components until the component at Idx
576 // reaches the target position Pos. For example, pc-a -> -pc-a when
577 // moving pc to the second position.
579 // Insert one empty component at Idx.
580 StringRef CurrentComponent(""); // The empty component.
581 for (unsigned i = Idx; i < Components.size();) {
582 // Place the component at the new position, getting the component
583 // that was at this position - it will be moved right.
584 std::swap(CurrentComponent, Components[i]);
585 // If it was placed on top of an empty component then we are done.
586 if (CurrentComponent.empty())
588 // Advance to the next component, skipping any fixed components.
589 while (++i < array_lengthof(Found) && Found[i])
592 // The last component was pushed off the end - append it.
593 if (!CurrentComponent.empty())
594 Components.push_back(CurrentComponent);
596 // Advance Idx to the component's new position.
597 while (++Idx < array_lengthof(Found) && Found[Idx])
599 } while (Idx < Pos); // Add more until the final position is reached.
601 assert(Pos < Components.size() && Components[Pos] == Comp &&
602 "Component moved wrong!");
608 // Special case logic goes here. At this point Arch, Vendor and OS have the
609 // correct values for the computed components.
611 if (OS == Triple::Win32) {
612 Components.resize(4);
613 Components[2] = "windows";
614 if (Environment == UnknownEnvironment) {
615 if (ObjectFormat == UnknownObjectFormat || ObjectFormat == Triple::COFF)
616 Components[3] = "msvc";
618 Components[3] = getObjectFormatTypeName(ObjectFormat);
620 } else if (IsMinGW32) {
621 Components.resize(4);
622 Components[2] = "windows";
623 Components[3] = "gnu";
624 } else if (IsCygwin) {
625 Components.resize(4);
626 Components[2] = "windows";
627 Components[3] = "cygnus";
629 if (IsMinGW32 || IsCygwin ||
630 (OS == Triple::Win32 && Environment != UnknownEnvironment)) {
631 if (ObjectFormat != UnknownObjectFormat && ObjectFormat != Triple::COFF) {
632 Components.resize(5);
633 Components[4] = getObjectFormatTypeName(ObjectFormat);
637 // Stick the corrected components back together to form the normalized string.
638 std::string Normalized;
639 for (unsigned i = 0, e = Components.size(); i != e; ++i) {
640 if (i) Normalized += '-';
641 Normalized += Components[i];
646 StringRef Triple::getArchName() const {
647 return StringRef(Data).split('-').first; // Isolate first component
650 StringRef Triple::getVendorName() const {
651 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
652 return Tmp.split('-').first; // Isolate second component
655 StringRef Triple::getOSName() const {
656 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
657 Tmp = Tmp.split('-').second; // Strip second component
658 return Tmp.split('-').first; // Isolate third component
661 StringRef Triple::getEnvironmentName() const {
662 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
663 Tmp = Tmp.split('-').second; // Strip second component
664 return Tmp.split('-').second; // Strip third component
667 StringRef Triple::getOSAndEnvironmentName() const {
668 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
669 return Tmp.split('-').second; // Strip second component
672 static unsigned EatNumber(StringRef &Str) {
673 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
677 // Consume the leading digit.
678 Result = Result*10 + (Str[0] - '0');
682 } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9');
687 void Triple::getOSVersion(unsigned &Major, unsigned &Minor,
688 unsigned &Micro) const {
689 StringRef OSName = getOSName();
691 // Assume that the OS portion of the triple starts with the canonical name.
692 StringRef OSTypeName = getOSTypeName(getOS());
693 if (OSName.startswith(OSTypeName))
694 OSName = OSName.substr(OSTypeName.size());
696 // Any unset version defaults to 0.
697 Major = Minor = Micro = 0;
699 // Parse up to three components.
700 unsigned *Components[3] = { &Major, &Minor, &Micro };
701 for (unsigned i = 0; i != 3; ++i) {
702 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
705 // Consume the leading number.
706 *Components[i] = EatNumber(OSName);
708 // Consume the separator, if present.
709 if (OSName.startswith("."))
710 OSName = OSName.substr(1);
714 bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor,
715 unsigned &Micro) const {
716 getOSVersion(Major, Minor, Micro);
719 default: llvm_unreachable("unexpected OS for Darwin triple");
721 // Default to darwin8, i.e., MacOSX 10.4.
724 // Darwin version numbers are skewed from OS X versions.
741 // Ignore the version from the triple. This is only handled because the
742 // the clang driver combines OS X and IOS support into a common Darwin
743 // toolchain that wants to know the OS X version number even when targeting
753 void Triple::getiOSVersion(unsigned &Major, unsigned &Minor,
754 unsigned &Micro) const {
756 default: llvm_unreachable("unexpected OS for Darwin triple");
759 // Ignore the version from the triple. This is only handled because the
760 // the clang driver combines OS X and IOS support into a common Darwin
761 // toolchain that wants to know the iOS version number even when targeting
768 getOSVersion(Major, Minor, Micro);
769 // Default to 5.0 (or 7.0 for arm64).
771 Major = (getArch() == aarch64) ? 7 : 5;
776 void Triple::setTriple(const Twine &Str) {
780 void Triple::setArch(ArchType Kind) {
781 setArchName(getArchTypeName(Kind));
784 void Triple::setVendor(VendorType Kind) {
785 setVendorName(getVendorTypeName(Kind));
788 void Triple::setOS(OSType Kind) {
789 setOSName(getOSTypeName(Kind));
792 void Triple::setEnvironment(EnvironmentType Kind) {
793 setEnvironmentName(getEnvironmentTypeName(Kind));
796 void Triple::setObjectFormat(ObjectFormatType Kind) {
797 if (Environment == UnknownEnvironment)
798 return setEnvironmentName(getObjectFormatTypeName(Kind));
800 setEnvironmentName((getEnvironmentTypeName(Environment) + Twine("-") +
801 getObjectFormatTypeName(Kind)).str());
804 void Triple::setArchName(StringRef Str) {
805 // Work around a miscompilation bug for Twines in gcc 4.0.3.
806 SmallString<64> Triple;
809 Triple += getVendorName();
811 Triple += getOSAndEnvironmentName();
812 setTriple(Triple.str());
815 void Triple::setVendorName(StringRef Str) {
816 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
819 void Triple::setOSName(StringRef Str) {
820 if (hasEnvironment())
821 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
822 "-" + getEnvironmentName());
824 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
827 void Triple::setEnvironmentName(StringRef Str) {
828 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
832 void Triple::setOSAndEnvironmentName(StringRef Str) {
833 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
836 static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
838 case llvm::Triple::UnknownArch:
841 case llvm::Triple::msp430:
844 case llvm::Triple::arm:
845 case llvm::Triple::armeb:
846 case llvm::Triple::hexagon:
847 case llvm::Triple::le32:
848 case llvm::Triple::mips:
849 case llvm::Triple::mipsel:
850 case llvm::Triple::nvptx:
851 case llvm::Triple::ppc:
852 case llvm::Triple::r600:
853 case llvm::Triple::sparc:
854 case llvm::Triple::tce:
855 case llvm::Triple::thumb:
856 case llvm::Triple::thumbeb:
857 case llvm::Triple::x86:
858 case llvm::Triple::xcore:
859 case llvm::Triple::amdil:
860 case llvm::Triple::hsail:
861 case llvm::Triple::spir:
862 case llvm::Triple::kalimba:
865 case llvm::Triple::aarch64:
866 case llvm::Triple::aarch64_be:
867 case llvm::Triple::le64:
868 case llvm::Triple::mips64:
869 case llvm::Triple::mips64el:
870 case llvm::Triple::nvptx64:
871 case llvm::Triple::ppc64:
872 case llvm::Triple::ppc64le:
873 case llvm::Triple::sparcv9:
874 case llvm::Triple::systemz:
875 case llvm::Triple::x86_64:
876 case llvm::Triple::amdil64:
877 case llvm::Triple::hsail64:
878 case llvm::Triple::spir64:
881 llvm_unreachable("Invalid architecture value");
884 bool Triple::isArch64Bit() const {
885 return getArchPointerBitWidth(getArch()) == 64;
888 bool Triple::isArch32Bit() const {
889 return getArchPointerBitWidth(getArch()) == 32;
892 bool Triple::isArch16Bit() const {
893 return getArchPointerBitWidth(getArch()) == 16;
896 Triple Triple::get32BitArchVariant() const {
899 case Triple::UnknownArch:
900 case Triple::aarch64:
901 case Triple::aarch64_be:
903 case Triple::systemz:
904 case Triple::ppc64le:
905 T.setArch(UnknownArch);
913 case Triple::hexagon:
914 case Triple::kalimba:
924 case Triple::thumbeb:
930 case Triple::le64: T.setArch(Triple::le32); break;
931 case Triple::mips64: T.setArch(Triple::mips); break;
932 case Triple::mips64el: T.setArch(Triple::mipsel); break;
933 case Triple::nvptx64: T.setArch(Triple::nvptx); break;
934 case Triple::ppc64: T.setArch(Triple::ppc); break;
935 case Triple::sparcv9: T.setArch(Triple::sparc); break;
936 case Triple::x86_64: T.setArch(Triple::x86); break;
937 case Triple::amdil64: T.setArch(Triple::amdil); break;
938 case Triple::hsail64: T.setArch(Triple::hsail); break;
939 case Triple::spir64: T.setArch(Triple::spir); break;
944 Triple Triple::get64BitArchVariant() const {
947 case Triple::UnknownArch:
950 case Triple::hexagon:
951 case Triple::kalimba:
956 case Triple::thumbeb:
958 T.setArch(UnknownArch);
961 case Triple::aarch64:
962 case Triple::aarch64_be:
964 case Triple::amdil64:
965 case Triple::hsail64:
968 case Triple::mips64el:
969 case Triple::nvptx64:
971 case Triple::ppc64le:
972 case Triple::sparcv9:
973 case Triple::systemz:
978 case Triple::le32: T.setArch(Triple::le64); break;
979 case Triple::mips: T.setArch(Triple::mips64); break;
980 case Triple::mipsel: T.setArch(Triple::mips64el); break;
981 case Triple::nvptx: T.setArch(Triple::nvptx64); break;
982 case Triple::ppc: T.setArch(Triple::ppc64); break;
983 case Triple::sparc: T.setArch(Triple::sparcv9); break;
984 case Triple::x86: T.setArch(Triple::x86_64); break;
985 case Triple::amdil: T.setArch(Triple::amdil64); break;
986 case Triple::hsail: T.setArch(Triple::hsail64); break;
987 case Triple::spir: T.setArch(Triple::spir64); break;
992 // FIXME: tblgen this.
993 const char *Triple::getARMCPUForArch(StringRef MArch) const {
995 MArch = getArchName();
998 case llvm::Triple::FreeBSD:
999 case llvm::Triple::NetBSD:
1000 if (MArch == "armv6")
1001 return "arm1176jzf-s";
1003 case llvm::Triple::Win32:
1004 // FIXME: this is invalid for WindowsCE
1010 const char *result = nullptr;
1011 size_t offset = StringRef::npos;
1012 if (MArch.startswith("arm"))
1014 if (MArch.startswith("thumb"))
1016 if (offset != StringRef::npos && MArch.substr(offset, 2) == "eb")
1018 if (offset != StringRef::npos)
1019 result = llvm::StringSwitch<const char *>(MArch.substr(offset))
1020 .Cases("v2", "v2a", "arm2")
1022 .Case("v3m", "arm7m")
1023 .Case("v4", "strongarm")
1024 .Case("v4t", "arm7tdmi")
1025 .Cases("v5", "v5t", "arm10tdmi")
1026 .Cases("v5e", "v5te", "arm1022e")
1027 .Case("v5tej", "arm926ej-s")
1028 .Cases("v6", "v6k", "arm1136jf-s")
1029 .Case("v6j", "arm1136j-s")
1030 .Cases("v6z", "v6zk", "arm1176jzf-s")
1031 .Case("v6t2", "arm1156t2-s")
1032 .Cases("v6m", "v6-m", "cortex-m0")
1033 .Cases("v7", "v7a", "v7-a", "v7l", "v7-l", "cortex-a8")
1034 .Cases("v7s", "v7-s", "swift")
1035 .Cases("v7r", "v7-r", "cortex-r4")
1036 .Cases("v7m", "v7-m", "cortex-m3")
1037 .Cases("v7em", "v7e-m", "cortex-m4")
1038 .Cases("v8", "v8a", "v8-a", "cortex-a53")
1041 result = llvm::StringSwitch<const char *>(MArch)
1042 .Case("ep9312", "ep9312")
1043 .Case("iwmmxt", "iwmmxt")
1044 .Case("xscale", "xscale")
1050 // If all else failed, return the most base CPU with thumb interworking
1051 // supported by LLVM.
1052 // FIXME: Should warn once that we're falling back.
1054 case llvm::Triple::NetBSD:
1055 switch (getEnvironment()) {
1056 case llvm::Triple::GNUEABIHF:
1057 case llvm::Triple::GNUEABI:
1058 case llvm::Triple::EABIHF:
1059 case llvm::Triple::EABI:
1060 return "arm926ej-s";
1065 switch (getEnvironment()) {
1066 case llvm::Triple::EABIHF:
1067 case llvm::Triple::GNUEABIHF:
1068 return "arm1176jzf-s";