1 //===--- Triple.cpp - Target triple helper class --------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/ADT/Triple.h"
11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/ADT/SmallString.h"
13 #include "llvm/ADT/StringSwitch.h"
14 #include "llvm/Support/ErrorHandling.h"
18 const char *Triple::getArchTypeName(ArchType Kind) {
20 case UnknownArch: return "unknown";
22 case aarch64: return "aarch64";
23 case aarch64_be: return "aarch64_be";
24 case arm: return "arm";
25 case armeb: return "armeb";
26 case bpf: return "bpf";
27 case hexagon: return "hexagon";
28 case mips: return "mips";
29 case mipsel: return "mipsel";
30 case mips64: return "mips64";
31 case mips64el: return "mips64el";
32 case msp430: return "msp430";
33 case ppc64: return "powerpc64";
34 case ppc64le: return "powerpc64le";
35 case ppc: return "powerpc";
36 case r600: return "r600";
37 case amdgcn: return "amdgcn";
38 case sparc: return "sparc";
39 case sparcv9: return "sparcv9";
40 case systemz: return "s390x";
41 case tce: return "tce";
42 case thumb: return "thumb";
43 case thumbeb: return "thumbeb";
44 case x86: return "i386";
45 case x86_64: return "x86_64";
46 case xcore: return "xcore";
47 case nvptx: return "nvptx";
48 case nvptx64: return "nvptx64";
49 case le32: return "le32";
50 case le64: return "le64";
51 case amdil: return "amdil";
52 case amdil64: return "amdil64";
53 case hsail: return "hsail";
54 case hsail64: return "hsail64";
55 case spir: return "spir";
56 case spir64: return "spir64";
57 case kalimba: return "kalimba";
60 llvm_unreachable("Invalid ArchType!");
63 const char *Triple::getArchTypePrefix(ArchType Kind) {
69 case aarch64_be: return "aarch64";
74 case thumbeb: return "arm";
78 case ppc: return "ppc";
83 case mips64el: return "mips";
85 case hexagon: return "hexagon";
88 case r600: return "amdgpu";
90 case bpf: return "bpf";
93 case sparc: return "sparc";
95 case systemz: return "systemz";
98 case x86_64: return "x86";
100 case xcore: return "xcore";
102 case nvptx: return "nvptx";
103 case nvptx64: return "nvptx";
105 case le32: return "le32";
106 case le64: return "le64";
109 case amdil64: return "amdil";
112 case hsail64: return "hsail";
115 case spir64: return "spir";
116 case kalimba: return "kalimba";
120 const char *Triple::getVendorTypeName(VendorType Kind) {
122 case UnknownVendor: return "unknown";
124 case Apple: return "apple";
125 case PC: return "pc";
126 case SCEI: return "scei";
127 case BGP: return "bgp";
128 case BGQ: return "bgq";
129 case Freescale: return "fsl";
130 case IBM: return "ibm";
131 case ImaginationTechnologies: return "img";
132 case MipsTechnologies: return "mti";
133 case NVIDIA: return "nvidia";
134 case CSR: return "csr";
137 llvm_unreachable("Invalid VendorType!");
140 const char *Triple::getOSTypeName(OSType Kind) {
142 case UnknownOS: return "unknown";
144 case Darwin: return "darwin";
145 case DragonFly: return "dragonfly";
146 case FreeBSD: return "freebsd";
147 case IOS: return "ios";
148 case KFreeBSD: return "kfreebsd";
149 case Linux: return "linux";
150 case Lv2: return "lv2";
151 case MacOSX: return "macosx";
152 case NetBSD: return "netbsd";
153 case OpenBSD: return "openbsd";
154 case Solaris: return "solaris";
155 case Win32: return "windows";
156 case Haiku: return "haiku";
157 case Minix: return "minix";
158 case RTEMS: return "rtems";
159 case NaCl: return "nacl";
160 case CNK: return "cnk";
161 case Bitrig: return "bitrig";
162 case AIX: return "aix";
163 case CUDA: return "cuda";
164 case NVCL: return "nvcl";
165 case AMDHSA: return "amdhsa";
168 llvm_unreachable("Invalid OSType");
171 const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
173 case UnknownEnvironment: return "unknown";
174 case GNU: return "gnu";
175 case GNUEABIHF: return "gnueabihf";
176 case GNUEABI: return "gnueabi";
177 case GNUX32: return "gnux32";
178 case CODE16: return "code16";
179 case EABI: return "eabi";
180 case EABIHF: return "eabihf";
181 case Android: return "android";
182 case MSVC: return "msvc";
183 case Itanium: return "itanium";
184 case Cygnus: return "cygnus";
187 llvm_unreachable("Invalid EnvironmentType!");
190 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
191 return StringSwitch<Triple::ArchType>(Name)
192 .Case("aarch64", aarch64)
193 .Case("aarch64_be", aarch64_be)
194 .Case("arm64", aarch64) // "arm64" is an alias for "aarch64"
196 .Case("armeb", armeb)
199 .Case("mipsel", mipsel)
200 .Case("mips64", mips64)
201 .Case("mips64el", mips64el)
202 .Case("msp430", msp430)
203 .Case("ppc64", ppc64)
206 .Case("ppc64le", ppc64le)
208 .Case("amdgcn", amdgcn)
209 .Case("hexagon", hexagon)
210 .Case("sparc", sparc)
211 .Case("sparcv9", sparcv9)
212 .Case("systemz", systemz)
214 .Case("thumb", thumb)
215 .Case("thumbeb", thumbeb)
217 .Case("x86-64", x86_64)
218 .Case("xcore", xcore)
219 .Case("nvptx", nvptx)
220 .Case("nvptx64", nvptx64)
223 .Case("amdil", amdil)
224 .Case("amdil64", amdil64)
225 .Case("hsail", hsail)
226 .Case("hsail64", hsail64)
228 .Case("spir64", spir64)
229 .Case("kalimba", kalimba)
230 .Default(UnknownArch);
233 static Triple::ArchType parseARMArch(StringRef ArchName) {
234 size_t offset = StringRef::npos;
235 Triple::ArchType arch = Triple::UnknownArch;
236 bool isThumb = ArchName.startswith("thumb");
238 if (ArchName.equals("arm"))
240 if (ArchName.equals("armeb"))
241 return Triple::armeb;
242 if (ArchName.equals("thumb"))
243 return Triple::thumb;
244 if (ArchName.equals("thumbeb"))
245 return Triple::thumbeb;
246 if (ArchName.equals("arm64") || ArchName.equals("aarch64"))
247 return Triple::aarch64;
248 if (ArchName.equals("aarch64_be"))
249 return Triple::aarch64_be;
251 if (ArchName.startswith("armv")) {
254 } else if (ArchName.startswith("armebv")) {
256 arch = Triple::armeb;
257 } else if (ArchName.startswith("thumbv")) {
259 arch = Triple::thumb;
260 } else if (ArchName.startswith("thumbebv")) {
262 arch = Triple::thumbeb;
264 return StringSwitch<Triple::ArchType>(ArchName.substr(offset))
265 .Cases("v2", "v2a", isThumb ? Triple::UnknownArch : arch)
266 .Cases("v3", "v3m", isThumb ? Triple::UnknownArch : arch)
267 .Cases("v4", "v4t", arch)
268 .Cases("v5", "v5e", "v5t", "v5te", "v5tej", arch)
269 .Cases("v6", "v6j", "v6k", "v6m", arch)
270 .Cases("v6t2", "v6z", "v6zk", arch)
271 .Cases("v7", "v7a", "v7em", "v7l", arch)
272 .Cases("v7m", "v7r", "v7s", arch)
273 .Cases("v8", "v8a", arch)
274 .Default(Triple::UnknownArch);
277 static Triple::ArchType parseArch(StringRef ArchName) {
278 return StringSwitch<Triple::ArchType>(ArchName)
279 .Cases("i386", "i486", "i586", "i686", Triple::x86)
280 // FIXME: Do we need to support these?
281 .Cases("i786", "i886", "i986", Triple::x86)
282 .Cases("amd64", "x86_64", "x86_64h", Triple::x86_64)
283 .Case("powerpc", Triple::ppc)
284 .Cases("powerpc64", "ppu", Triple::ppc64)
285 .Case("powerpc64le", Triple::ppc64le)
286 .Case("xscale", Triple::arm)
287 .StartsWith("arm", parseARMArch(ArchName))
288 .StartsWith("thumb", parseARMArch(ArchName))
289 .StartsWith("aarch64", parseARMArch(ArchName))
290 .Case("msp430", Triple::msp430)
291 .Cases("mips", "mipseb", "mipsallegrex", Triple::mips)
292 .Cases("mipsel", "mipsallegrexel", Triple::mipsel)
293 .Cases("mips64", "mips64eb", Triple::mips64)
294 .Case("mips64el", Triple::mips64el)
295 .Case("r600", Triple::r600)
296 .Case("amdgcn", Triple::amdgcn)
297 .Case("bpf", Triple::bpf)
298 .Case("hexagon", Triple::hexagon)
299 .Case("s390x", Triple::systemz)
300 .Case("sparc", Triple::sparc)
301 .Cases("sparcv9", "sparc64", Triple::sparcv9)
302 .Case("tce", Triple::tce)
303 .Case("xcore", Triple::xcore)
304 .Case("nvptx", Triple::nvptx)
305 .Case("nvptx64", Triple::nvptx64)
306 .Case("le32", Triple::le32)
307 .Case("le64", Triple::le64)
308 .Case("amdil", Triple::amdil)
309 .Case("amdil64", Triple::amdil64)
310 .Case("hsail", Triple::hsail)
311 .Case("hsail64", Triple::hsail64)
312 .Case("spir", Triple::spir)
313 .Case("spir64", Triple::spir64)
314 .StartsWith("kalimba", Triple::kalimba)
315 .Default(Triple::UnknownArch);
318 static Triple::VendorType parseVendor(StringRef VendorName) {
319 return StringSwitch<Triple::VendorType>(VendorName)
320 .Case("apple", Triple::Apple)
321 .Case("pc", Triple::PC)
322 .Case("scei", Triple::SCEI)
323 .Case("bgp", Triple::BGP)
324 .Case("bgq", Triple::BGQ)
325 .Case("fsl", Triple::Freescale)
326 .Case("ibm", Triple::IBM)
327 .Case("img", Triple::ImaginationTechnologies)
328 .Case("mti", Triple::MipsTechnologies)
329 .Case("nvidia", Triple::NVIDIA)
330 .Case("csr", Triple::CSR)
331 .Default(Triple::UnknownVendor);
334 static Triple::OSType parseOS(StringRef OSName) {
335 return StringSwitch<Triple::OSType>(OSName)
336 .StartsWith("darwin", Triple::Darwin)
337 .StartsWith("dragonfly", Triple::DragonFly)
338 .StartsWith("freebsd", Triple::FreeBSD)
339 .StartsWith("ios", Triple::IOS)
340 .StartsWith("kfreebsd", Triple::KFreeBSD)
341 .StartsWith("linux", Triple::Linux)
342 .StartsWith("lv2", Triple::Lv2)
343 .StartsWith("macosx", Triple::MacOSX)
344 .StartsWith("netbsd", Triple::NetBSD)
345 .StartsWith("openbsd", Triple::OpenBSD)
346 .StartsWith("solaris", Triple::Solaris)
347 .StartsWith("win32", Triple::Win32)
348 .StartsWith("windows", Triple::Win32)
349 .StartsWith("haiku", Triple::Haiku)
350 .StartsWith("minix", Triple::Minix)
351 .StartsWith("rtems", Triple::RTEMS)
352 .StartsWith("nacl", Triple::NaCl)
353 .StartsWith("cnk", Triple::CNK)
354 .StartsWith("bitrig", Triple::Bitrig)
355 .StartsWith("aix", Triple::AIX)
356 .StartsWith("cuda", Triple::CUDA)
357 .StartsWith("nvcl", Triple::NVCL)
358 .StartsWith("amdhsa", Triple::AMDHSA)
359 .Default(Triple::UnknownOS);
362 static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) {
363 return StringSwitch<Triple::EnvironmentType>(EnvironmentName)
364 .StartsWith("eabihf", Triple::EABIHF)
365 .StartsWith("eabi", Triple::EABI)
366 .StartsWith("gnueabihf", Triple::GNUEABIHF)
367 .StartsWith("gnueabi", Triple::GNUEABI)
368 .StartsWith("gnux32", Triple::GNUX32)
369 .StartsWith("code16", Triple::CODE16)
370 .StartsWith("gnu", Triple::GNU)
371 .StartsWith("android", Triple::Android)
372 .StartsWith("msvc", Triple::MSVC)
373 .StartsWith("itanium", Triple::Itanium)
374 .StartsWith("cygnus", Triple::Cygnus)
375 .Default(Triple::UnknownEnvironment);
378 static Triple::ObjectFormatType parseFormat(StringRef EnvironmentName) {
379 return StringSwitch<Triple::ObjectFormatType>(EnvironmentName)
380 .EndsWith("coff", Triple::COFF)
381 .EndsWith("elf", Triple::ELF)
382 .EndsWith("macho", Triple::MachO)
383 .Default(Triple::UnknownObjectFormat);
386 static Triple::SubArchType parseSubArch(StringRef SubArchName) {
387 return StringSwitch<Triple::SubArchType>(SubArchName)
388 .EndsWith("v8", Triple::ARMSubArch_v8)
389 .EndsWith("v8a", Triple::ARMSubArch_v8)
390 .EndsWith("v7", Triple::ARMSubArch_v7)
391 .EndsWith("v7a", Triple::ARMSubArch_v7)
392 .EndsWith("v7em", Triple::ARMSubArch_v7em)
393 .EndsWith("v7l", Triple::ARMSubArch_v7)
394 .EndsWith("v7m", Triple::ARMSubArch_v7m)
395 .EndsWith("v7r", Triple::ARMSubArch_v7)
396 .EndsWith("v7s", Triple::ARMSubArch_v7s)
397 .EndsWith("v6", Triple::ARMSubArch_v6)
398 .EndsWith("v6m", Triple::ARMSubArch_v6m)
399 .EndsWith("v6t2", Triple::ARMSubArch_v6t2)
400 .EndsWith("v5", Triple::ARMSubArch_v5)
401 .EndsWith("v5e", Triple::ARMSubArch_v5)
402 .EndsWith("v5t", Triple::ARMSubArch_v5)
403 .EndsWith("v5te", Triple::ARMSubArch_v5te)
404 .EndsWith("v4t", Triple::ARMSubArch_v4t)
405 .EndsWith("kalimba3", Triple::KalimbaSubArch_v3)
406 .EndsWith("kalimba4", Triple::KalimbaSubArch_v4)
407 .EndsWith("kalimba5", Triple::KalimbaSubArch_v5)
408 .Default(Triple::NoSubArch);
411 static const char *getObjectFormatTypeName(Triple::ObjectFormatType Kind) {
413 case Triple::UnknownObjectFormat: return "";
414 case Triple::COFF: return "coff";
415 case Triple::ELF: return "elf";
416 case Triple::MachO: return "macho";
418 llvm_unreachable("unknown object format type");
421 static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
423 return Triple::MachO;
424 else if (T.isOSWindows())
429 /// \brief Construct a triple from the string representation provided.
431 /// This stores the string representation and parses the various pieces into
433 Triple::Triple(const Twine &Str)
435 Arch(parseArch(getArchName())),
436 SubArch(parseSubArch(getArchName())),
437 Vendor(parseVendor(getVendorName())),
438 OS(parseOS(getOSName())),
439 Environment(parseEnvironment(getEnvironmentName())),
440 ObjectFormat(parseFormat(getEnvironmentName())) {
441 if (ObjectFormat == Triple::UnknownObjectFormat)
442 ObjectFormat = getDefaultFormat(*this);
445 /// \brief Construct a triple from string representations of the architecture,
448 /// This joins each argument into a canonical string representation and parses
449 /// them into enum members. It leaves the environment unknown and omits it from
450 /// the string representation.
451 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr)
452 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()),
453 Arch(parseArch(ArchStr.str())),
454 SubArch(parseSubArch(ArchStr.str())),
455 Vendor(parseVendor(VendorStr.str())),
456 OS(parseOS(OSStr.str())),
457 Environment(), ObjectFormat(Triple::UnknownObjectFormat) {
458 ObjectFormat = getDefaultFormat(*this);
461 /// \brief Construct a triple from string representations of the architecture,
462 /// vendor, OS, and environment.
464 /// This joins each argument into a canonical string representation and parses
465 /// them into enum members.
466 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr,
467 const Twine &EnvironmentStr)
468 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr + Twine('-') +
469 EnvironmentStr).str()),
470 Arch(parseArch(ArchStr.str())),
471 SubArch(parseSubArch(ArchStr.str())),
472 Vendor(parseVendor(VendorStr.str())),
473 OS(parseOS(OSStr.str())),
474 Environment(parseEnvironment(EnvironmentStr.str())),
475 ObjectFormat(parseFormat(EnvironmentStr.str())) {
476 if (ObjectFormat == Triple::UnknownObjectFormat)
477 ObjectFormat = getDefaultFormat(*this);
480 std::string Triple::normalize(StringRef Str) {
481 bool IsMinGW32 = false;
482 bool IsCygwin = false;
484 // Parse into components.
485 SmallVector<StringRef, 4> Components;
486 Str.split(Components, "-");
488 // If the first component corresponds to a known architecture, preferentially
489 // use it for the architecture. If the second component corresponds to a
490 // known vendor, preferentially use it for the vendor, etc. This avoids silly
491 // component movement when a component parses as (eg) both a valid arch and a
493 ArchType Arch = UnknownArch;
494 if (Components.size() > 0)
495 Arch = parseArch(Components[0]);
496 VendorType Vendor = UnknownVendor;
497 if (Components.size() > 1)
498 Vendor = parseVendor(Components[1]);
499 OSType OS = UnknownOS;
500 if (Components.size() > 2) {
501 OS = parseOS(Components[2]);
502 IsCygwin = Components[2].startswith("cygwin");
503 IsMinGW32 = Components[2].startswith("mingw");
505 EnvironmentType Environment = UnknownEnvironment;
506 if (Components.size() > 3)
507 Environment = parseEnvironment(Components[3]);
508 ObjectFormatType ObjectFormat = UnknownObjectFormat;
509 if (Components.size() > 4)
510 ObjectFormat = parseFormat(Components[4]);
512 // Note which components are already in their final position. These will not
515 Found[0] = Arch != UnknownArch;
516 Found[1] = Vendor != UnknownVendor;
517 Found[2] = OS != UnknownOS;
518 Found[3] = Environment != UnknownEnvironment;
520 // If they are not there already, permute the components into their canonical
521 // positions by seeing if they parse as a valid architecture, and if so moving
522 // the component to the architecture position etc.
523 for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) {
525 continue; // Already in the canonical position.
527 for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
528 // Do not reparse any components that already matched.
529 if (Idx < array_lengthof(Found) && Found[Idx])
532 // Does this component parse as valid for the target position?
534 StringRef Comp = Components[Idx];
536 default: llvm_unreachable("unexpected component type!");
538 Arch = parseArch(Comp);
539 Valid = Arch != UnknownArch;
542 Vendor = parseVendor(Comp);
543 Valid = Vendor != UnknownVendor;
547 IsCygwin = Comp.startswith("cygwin");
548 IsMinGW32 = Comp.startswith("mingw");
549 Valid = OS != UnknownOS || IsCygwin || IsMinGW32;
552 Environment = parseEnvironment(Comp);
553 Valid = Environment != UnknownEnvironment;
555 ObjectFormat = parseFormat(Comp);
556 Valid = ObjectFormat != UnknownObjectFormat;
561 continue; // Nope, try the next component.
563 // Move the component to the target position, pushing any non-fixed
564 // components that are in the way to the right. This tends to give
565 // good results in the common cases of a forgotten vendor component
566 // or a wrongly positioned environment.
568 // Insert left, pushing the existing components to the right. For
569 // example, a-b-i386 -> i386-a-b when moving i386 to the front.
570 StringRef CurrentComponent(""); // The empty component.
571 // Replace the component we are moving with an empty component.
572 std::swap(CurrentComponent, Components[Idx]);
573 // Insert the component being moved at Pos, displacing any existing
574 // components to the right.
575 for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
576 // Skip over any fixed components.
577 while (i < array_lengthof(Found) && Found[i])
579 // Place the component at the new position, getting the component
580 // that was at this position - it will be moved right.
581 std::swap(CurrentComponent, Components[i]);
583 } else if (Pos > Idx) {
584 // Push right by inserting empty components until the component at Idx
585 // reaches the target position Pos. For example, pc-a -> -pc-a when
586 // moving pc to the second position.
588 // Insert one empty component at Idx.
589 StringRef CurrentComponent(""); // The empty component.
590 for (unsigned i = Idx; i < Components.size();) {
591 // Place the component at the new position, getting the component
592 // that was at this position - it will be moved right.
593 std::swap(CurrentComponent, Components[i]);
594 // If it was placed on top of an empty component then we are done.
595 if (CurrentComponent.empty())
597 // Advance to the next component, skipping any fixed components.
598 while (++i < array_lengthof(Found) && Found[i])
601 // The last component was pushed off the end - append it.
602 if (!CurrentComponent.empty())
603 Components.push_back(CurrentComponent);
605 // Advance Idx to the component's new position.
606 while (++Idx < array_lengthof(Found) && Found[Idx])
608 } while (Idx < Pos); // Add more until the final position is reached.
610 assert(Pos < Components.size() && Components[Pos] == Comp &&
611 "Component moved wrong!");
617 // Special case logic goes here. At this point Arch, Vendor and OS have the
618 // correct values for the computed components.
620 if (OS == Triple::Win32) {
621 Components.resize(4);
622 Components[2] = "windows";
623 if (Environment == UnknownEnvironment) {
624 if (ObjectFormat == UnknownObjectFormat || ObjectFormat == Triple::COFF)
625 Components[3] = "msvc";
627 Components[3] = getObjectFormatTypeName(ObjectFormat);
629 } else if (IsMinGW32) {
630 Components.resize(4);
631 Components[2] = "windows";
632 Components[3] = "gnu";
633 } else if (IsCygwin) {
634 Components.resize(4);
635 Components[2] = "windows";
636 Components[3] = "cygnus";
638 if (IsMinGW32 || IsCygwin ||
639 (OS == Triple::Win32 && Environment != UnknownEnvironment)) {
640 if (ObjectFormat != UnknownObjectFormat && ObjectFormat != Triple::COFF) {
641 Components.resize(5);
642 Components[4] = getObjectFormatTypeName(ObjectFormat);
646 // Stick the corrected components back together to form the normalized string.
647 std::string Normalized;
648 for (unsigned i = 0, e = Components.size(); i != e; ++i) {
649 if (i) Normalized += '-';
650 Normalized += Components[i];
655 StringRef Triple::getArchName() const {
656 return StringRef(Data).split('-').first; // Isolate first component
659 StringRef Triple::getVendorName() const {
660 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
661 return Tmp.split('-').first; // Isolate second component
664 StringRef Triple::getOSName() const {
665 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
666 Tmp = Tmp.split('-').second; // Strip second component
667 return Tmp.split('-').first; // Isolate third component
670 StringRef Triple::getEnvironmentName() const {
671 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
672 Tmp = Tmp.split('-').second; // Strip second component
673 return Tmp.split('-').second; // Strip third component
676 StringRef Triple::getOSAndEnvironmentName() const {
677 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
678 return Tmp.split('-').second; // Strip second component
681 static unsigned EatNumber(StringRef &Str) {
682 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
686 // Consume the leading digit.
687 Result = Result*10 + (Str[0] - '0');
691 } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9');
696 void Triple::getOSVersion(unsigned &Major, unsigned &Minor,
697 unsigned &Micro) const {
698 StringRef OSName = getOSName();
700 // Assume that the OS portion of the triple starts with the canonical name.
701 StringRef OSTypeName = getOSTypeName(getOS());
702 if (OSName.startswith(OSTypeName))
703 OSName = OSName.substr(OSTypeName.size());
705 // Any unset version defaults to 0.
706 Major = Minor = Micro = 0;
708 // Parse up to three components.
709 unsigned *Components[3] = { &Major, &Minor, &Micro };
710 for (unsigned i = 0; i != 3; ++i) {
711 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
714 // Consume the leading number.
715 *Components[i] = EatNumber(OSName);
717 // Consume the separator, if present.
718 if (OSName.startswith("."))
719 OSName = OSName.substr(1);
723 bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor,
724 unsigned &Micro) const {
725 getOSVersion(Major, Minor, Micro);
728 default: llvm_unreachable("unexpected OS for Darwin triple");
730 // Default to darwin8, i.e., MacOSX 10.4.
733 // Darwin version numbers are skewed from OS X versions.
750 // Ignore the version from the triple. This is only handled because the
751 // the clang driver combines OS X and IOS support into a common Darwin
752 // toolchain that wants to know the OS X version number even when targeting
762 void Triple::getiOSVersion(unsigned &Major, unsigned &Minor,
763 unsigned &Micro) const {
765 default: llvm_unreachable("unexpected OS for Darwin triple");
768 // Ignore the version from the triple. This is only handled because the
769 // the clang driver combines OS X and IOS support into a common Darwin
770 // toolchain that wants to know the iOS version number even when targeting
777 getOSVersion(Major, Minor, Micro);
778 // Default to 5.0 (or 7.0 for arm64).
780 Major = (getArch() == aarch64) ? 7 : 5;
785 void Triple::setTriple(const Twine &Str) {
789 void Triple::setArch(ArchType Kind) {
790 setArchName(getArchTypeName(Kind));
793 void Triple::setVendor(VendorType Kind) {
794 setVendorName(getVendorTypeName(Kind));
797 void Triple::setOS(OSType Kind) {
798 setOSName(getOSTypeName(Kind));
801 void Triple::setEnvironment(EnvironmentType Kind) {
802 setEnvironmentName(getEnvironmentTypeName(Kind));
805 void Triple::setObjectFormat(ObjectFormatType Kind) {
806 if (Environment == UnknownEnvironment)
807 return setEnvironmentName(getObjectFormatTypeName(Kind));
809 setEnvironmentName((getEnvironmentTypeName(Environment) + Twine("-") +
810 getObjectFormatTypeName(Kind)).str());
813 void Triple::setArchName(StringRef Str) {
814 // Work around a miscompilation bug for Twines in gcc 4.0.3.
815 SmallString<64> Triple;
818 Triple += getVendorName();
820 Triple += getOSAndEnvironmentName();
821 setTriple(Triple.str());
824 void Triple::setVendorName(StringRef Str) {
825 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
828 void Triple::setOSName(StringRef Str) {
829 if (hasEnvironment())
830 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
831 "-" + getEnvironmentName());
833 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
836 void Triple::setEnvironmentName(StringRef Str) {
837 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
841 void Triple::setOSAndEnvironmentName(StringRef Str) {
842 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
845 static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
847 case llvm::Triple::UnknownArch:
850 case llvm::Triple::msp430:
853 case llvm::Triple::arm:
854 case llvm::Triple::armeb:
855 case llvm::Triple::hexagon:
856 case llvm::Triple::le32:
857 case llvm::Triple::mips:
858 case llvm::Triple::mipsel:
859 case llvm::Triple::nvptx:
860 case llvm::Triple::ppc:
861 case llvm::Triple::r600:
862 case llvm::Triple::sparc:
863 case llvm::Triple::tce:
864 case llvm::Triple::thumb:
865 case llvm::Triple::thumbeb:
866 case llvm::Triple::x86:
867 case llvm::Triple::xcore:
868 case llvm::Triple::amdil:
869 case llvm::Triple::hsail:
870 case llvm::Triple::spir:
871 case llvm::Triple::kalimba:
874 case llvm::Triple::aarch64:
875 case llvm::Triple::aarch64_be:
876 case llvm::Triple::amdgcn:
877 case llvm::Triple::bpf:
878 case llvm::Triple::le64:
879 case llvm::Triple::mips64:
880 case llvm::Triple::mips64el:
881 case llvm::Triple::nvptx64:
882 case llvm::Triple::ppc64:
883 case llvm::Triple::ppc64le:
884 case llvm::Triple::sparcv9:
885 case llvm::Triple::systemz:
886 case llvm::Triple::x86_64:
887 case llvm::Triple::amdil64:
888 case llvm::Triple::hsail64:
889 case llvm::Triple::spir64:
892 llvm_unreachable("Invalid architecture value");
895 bool Triple::isArch64Bit() const {
896 return getArchPointerBitWidth(getArch()) == 64;
899 bool Triple::isArch32Bit() const {
900 return getArchPointerBitWidth(getArch()) == 32;
903 bool Triple::isArch16Bit() const {
904 return getArchPointerBitWidth(getArch()) == 16;
907 Triple Triple::get32BitArchVariant() const {
910 case Triple::UnknownArch:
911 case Triple::aarch64:
912 case Triple::aarch64_be:
916 case Triple::systemz:
917 case Triple::ppc64le:
918 T.setArch(UnknownArch);
926 case Triple::hexagon:
927 case Triple::kalimba:
937 case Triple::thumbeb:
943 case Triple::le64: T.setArch(Triple::le32); break;
944 case Triple::mips64: T.setArch(Triple::mips); break;
945 case Triple::mips64el: T.setArch(Triple::mipsel); break;
946 case Triple::nvptx64: T.setArch(Triple::nvptx); break;
947 case Triple::ppc64: T.setArch(Triple::ppc); break;
948 case Triple::sparcv9: T.setArch(Triple::sparc); break;
949 case Triple::x86_64: T.setArch(Triple::x86); break;
950 case Triple::amdil64: T.setArch(Triple::amdil); break;
951 case Triple::hsail64: T.setArch(Triple::hsail); break;
952 case Triple::spir64: T.setArch(Triple::spir); break;
957 Triple Triple::get64BitArchVariant() const {
960 case Triple::UnknownArch:
963 case Triple::hexagon:
964 case Triple::kalimba:
969 case Triple::thumbeb:
971 T.setArch(UnknownArch);
974 case Triple::aarch64:
975 case Triple::aarch64_be:
978 case Triple::amdil64:
980 case Triple::hsail64:
983 case Triple::mips64el:
984 case Triple::nvptx64:
986 case Triple::ppc64le:
987 case Triple::sparcv9:
988 case Triple::systemz:
993 case Triple::le32: T.setArch(Triple::le64); break;
994 case Triple::mips: T.setArch(Triple::mips64); break;
995 case Triple::mipsel: T.setArch(Triple::mips64el); break;
996 case Triple::nvptx: T.setArch(Triple::nvptx64); break;
997 case Triple::ppc: T.setArch(Triple::ppc64); break;
998 case Triple::sparc: T.setArch(Triple::sparcv9); break;
999 case Triple::x86: T.setArch(Triple::x86_64); break;
1000 case Triple::amdil: T.setArch(Triple::amdil64); break;
1001 case Triple::hsail: T.setArch(Triple::hsail64); break;
1002 case Triple::spir: T.setArch(Triple::spir64); break;
1007 // FIXME: tblgen this.
1008 const char *Triple::getARMCPUForArch(StringRef MArch) const {
1010 MArch = getArchName();
1013 case llvm::Triple::FreeBSD:
1014 case llvm::Triple::NetBSD:
1015 if (MArch == "armv6")
1016 return "arm1176jzf-s";
1018 case llvm::Triple::Win32:
1019 // FIXME: this is invalid for WindowsCE
1025 const char *result = nullptr;
1026 size_t offset = StringRef::npos;
1027 if (MArch.startswith("arm"))
1029 if (MArch.startswith("thumb"))
1031 if (offset != StringRef::npos && MArch.substr(offset, 2) == "eb")
1033 if (offset != StringRef::npos)
1034 result = llvm::StringSwitch<const char *>(MArch.substr(offset))
1035 .Cases("v2", "v2a", "arm2")
1037 .Case("v3m", "arm7m")
1038 .Case("v4", "strongarm")
1039 .Case("v4t", "arm7tdmi")
1040 .Cases("v5", "v5t", "arm10tdmi")
1041 .Cases("v5e", "v5te", "arm1022e")
1042 .Case("v5tej", "arm926ej-s")
1043 .Cases("v6", "v6k", "arm1136jf-s")
1044 .Case("v6j", "arm1136j-s")
1045 .Cases("v6z", "v6zk", "arm1176jzf-s")
1046 .Case("v6t2", "arm1156t2-s")
1047 .Cases("v6m", "v6-m", "cortex-m0")
1048 .Cases("v7", "v7a", "v7-a", "v7l", "v7-l", "cortex-a8")
1049 .Cases("v7s", "v7-s", "swift")
1050 .Cases("v7r", "v7-r", "cortex-r4")
1051 .Cases("v7m", "v7-m", "cortex-m3")
1052 .Cases("v7em", "v7e-m", "cortex-m4")
1053 .Cases("v8", "v8a", "v8-a", "cortex-a53")
1056 result = llvm::StringSwitch<const char *>(MArch)
1057 .Case("ep9312", "ep9312")
1058 .Case("iwmmxt", "iwmmxt")
1059 .Case("xscale", "xscale")
1065 // If all else failed, return the most base CPU with thumb interworking
1066 // supported by LLVM.
1067 // FIXME: Should warn once that we're falling back.
1069 case llvm::Triple::NetBSD:
1070 switch (getEnvironment()) {
1071 case llvm::Triple::GNUEABIHF:
1072 case llvm::Triple::GNUEABI:
1073 case llvm::Triple::EABIHF:
1074 case llvm::Triple::EABI:
1075 return "arm926ej-s";
1080 switch (getEnvironment()) {
1081 case llvm::Triple::EABIHF:
1082 case llvm::Triple::GNUEABIHF:
1083 return "arm1176jzf-s";