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 CloudABI: return "cloudabi";
145 case Darwin: return "darwin";
146 case DragonFly: return "dragonfly";
147 case FreeBSD: return "freebsd";
148 case IOS: return "ios";
149 case KFreeBSD: return "kfreebsd";
150 case Linux: return "linux";
151 case Lv2: return "lv2";
152 case MacOSX: return "macosx";
153 case NetBSD: return "netbsd";
154 case OpenBSD: return "openbsd";
155 case Solaris: return "solaris";
156 case Win32: return "windows";
157 case Haiku: return "haiku";
158 case Minix: return "minix";
159 case RTEMS: return "rtems";
160 case NaCl: return "nacl";
161 case CNK: return "cnk";
162 case Bitrig: return "bitrig";
163 case AIX: return "aix";
164 case CUDA: return "cuda";
165 case NVCL: return "nvcl";
166 case AMDHSA: return "amdhsa";
167 case PS4: return "ps4";
170 llvm_unreachable("Invalid OSType");
173 const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
175 case UnknownEnvironment: return "unknown";
176 case GNU: return "gnu";
177 case GNUEABIHF: return "gnueabihf";
178 case GNUEABI: return "gnueabi";
179 case GNUX32: return "gnux32";
180 case CODE16: return "code16";
181 case EABI: return "eabi";
182 case EABIHF: return "eabihf";
183 case Android: return "android";
184 case MSVC: return "msvc";
185 case Itanium: return "itanium";
186 case Cygnus: return "cygnus";
189 llvm_unreachable("Invalid EnvironmentType!");
192 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
193 return StringSwitch<Triple::ArchType>(Name)
194 .Case("aarch64", aarch64)
195 .Case("aarch64_be", aarch64_be)
196 .Case("arm64", aarch64) // "arm64" is an alias for "aarch64"
198 .Case("armeb", armeb)
201 .Case("mipsel", mipsel)
202 .Case("mips64", mips64)
203 .Case("mips64el", mips64el)
204 .Case("msp430", msp430)
205 .Case("ppc64", ppc64)
208 .Case("ppc64le", ppc64le)
210 .Case("amdgcn", amdgcn)
211 .Case("hexagon", hexagon)
212 .Case("sparc", sparc)
213 .Case("sparcv9", sparcv9)
214 .Case("systemz", systemz)
216 .Case("thumb", thumb)
217 .Case("thumbeb", thumbeb)
219 .Case("x86-64", x86_64)
220 .Case("xcore", xcore)
221 .Case("nvptx", nvptx)
222 .Case("nvptx64", nvptx64)
225 .Case("amdil", amdil)
226 .Case("amdil64", amdil64)
227 .Case("hsail", hsail)
228 .Case("hsail64", hsail64)
230 .Case("spir64", spir64)
231 .Case("kalimba", kalimba)
232 .Default(UnknownArch);
235 static Triple::ArchType parseARMArch(StringRef ArchName) {
236 size_t offset = StringRef::npos;
237 Triple::ArchType arch = Triple::UnknownArch;
238 bool isThumb = ArchName.startswith("thumb");
240 if (ArchName.equals("arm"))
242 if (ArchName.equals("armeb"))
243 return Triple::armeb;
244 if (ArchName.equals("thumb"))
245 return Triple::thumb;
246 if (ArchName.equals("thumbeb"))
247 return Triple::thumbeb;
248 if (ArchName.equals("arm64") || ArchName.equals("aarch64"))
249 return Triple::aarch64;
250 if (ArchName.equals("aarch64_be"))
251 return Triple::aarch64_be;
253 if (ArchName.startswith("armv")) {
255 if (ArchName.endswith("eb")) {
256 arch = Triple::armeb;
257 ArchName = ArchName.substr(0, ArchName.size() - 2);
260 } else if (ArchName.startswith("armebv")) {
262 arch = Triple::armeb;
263 } else if (ArchName.startswith("thumbv")) {
265 if (ArchName.endswith("eb")) {
266 arch = Triple::thumbeb;
267 ArchName = ArchName.substr(0, ArchName.size() - 2);
269 arch = Triple::thumb;
270 } else if (ArchName.startswith("thumbebv")) {
272 arch = Triple::thumbeb;
274 return StringSwitch<Triple::ArchType>(ArchName.substr(offset))
275 .Cases("v2", "v2a", isThumb ? Triple::UnknownArch : arch)
276 .Cases("v3", "v3m", isThumb ? Triple::UnknownArch : arch)
277 .Cases("v4", "v4t", arch)
278 .Cases("v5", "v5e", "v5t", "v5te", "v5tej", arch)
279 .Cases("v6", "v6j", "v6k", "v6m", "v6sm", arch)
280 .Cases("v6t2", "v6z", "v6zk", arch)
281 .Cases("v7", "v7a", "v7em", "v7l", arch)
282 .Cases("v7m", "v7r", "v7s", arch)
283 .Cases("v8", "v8a", arch)
284 .Default(Triple::UnknownArch);
287 static Triple::ArchType parseArch(StringRef ArchName) {
288 Triple::ArchType ARMArch(parseARMArch(ArchName));
290 return StringSwitch<Triple::ArchType>(ArchName)
291 .Cases("i386", "i486", "i586", "i686", Triple::x86)
292 // FIXME: Do we need to support these?
293 .Cases("i786", "i886", "i986", Triple::x86)
294 .Cases("amd64", "x86_64", "x86_64h", Triple::x86_64)
295 .Case("powerpc", Triple::ppc)
296 .Cases("powerpc64", "ppu", Triple::ppc64)
297 .Case("powerpc64le", Triple::ppc64le)
298 .Case("xscale", Triple::arm)
299 .Case("xscaleeb", Triple::armeb)
300 .StartsWith("arm", ARMArch)
301 .StartsWith("thumb", ARMArch)
302 .StartsWith("aarch64", ARMArch)
303 .Case("msp430", Triple::msp430)
304 .Cases("mips", "mipseb", "mipsallegrex", Triple::mips)
305 .Cases("mipsel", "mipsallegrexel", Triple::mipsel)
306 .Cases("mips64", "mips64eb", Triple::mips64)
307 .Case("mips64el", Triple::mips64el)
308 .Case("r600", Triple::r600)
309 .Case("amdgcn", Triple::amdgcn)
310 .Case("bpf", Triple::bpf)
311 .Case("hexagon", Triple::hexagon)
312 .Case("s390x", Triple::systemz)
313 .Case("sparc", Triple::sparc)
314 .Cases("sparcv9", "sparc64", Triple::sparcv9)
315 .Case("tce", Triple::tce)
316 .Case("xcore", Triple::xcore)
317 .Case("nvptx", Triple::nvptx)
318 .Case("nvptx64", Triple::nvptx64)
319 .Case("le32", Triple::le32)
320 .Case("le64", Triple::le64)
321 .Case("amdil", Triple::amdil)
322 .Case("amdil64", Triple::amdil64)
323 .Case("hsail", Triple::hsail)
324 .Case("hsail64", Triple::hsail64)
325 .Case("spir", Triple::spir)
326 .Case("spir64", Triple::spir64)
327 .StartsWith("kalimba", Triple::kalimba)
328 .Default(Triple::UnknownArch);
331 static Triple::VendorType parseVendor(StringRef VendorName) {
332 return StringSwitch<Triple::VendorType>(VendorName)
333 .Case("apple", Triple::Apple)
334 .Case("pc", Triple::PC)
335 .Case("scei", Triple::SCEI)
336 .Case("bgp", Triple::BGP)
337 .Case("bgq", Triple::BGQ)
338 .Case("fsl", Triple::Freescale)
339 .Case("ibm", Triple::IBM)
340 .Case("img", Triple::ImaginationTechnologies)
341 .Case("mti", Triple::MipsTechnologies)
342 .Case("nvidia", Triple::NVIDIA)
343 .Case("csr", Triple::CSR)
344 .Default(Triple::UnknownVendor);
347 static Triple::OSType parseOS(StringRef OSName) {
348 return StringSwitch<Triple::OSType>(OSName)
349 .StartsWith("cloudabi", Triple::CloudABI)
350 .StartsWith("darwin", Triple::Darwin)
351 .StartsWith("dragonfly", Triple::DragonFly)
352 .StartsWith("freebsd", Triple::FreeBSD)
353 .StartsWith("ios", Triple::IOS)
354 .StartsWith("kfreebsd", Triple::KFreeBSD)
355 .StartsWith("linux", Triple::Linux)
356 .StartsWith("lv2", Triple::Lv2)
357 .StartsWith("macosx", Triple::MacOSX)
358 .StartsWith("netbsd", Triple::NetBSD)
359 .StartsWith("openbsd", Triple::OpenBSD)
360 .StartsWith("solaris", Triple::Solaris)
361 .StartsWith("win32", Triple::Win32)
362 .StartsWith("windows", Triple::Win32)
363 .StartsWith("haiku", Triple::Haiku)
364 .StartsWith("minix", Triple::Minix)
365 .StartsWith("rtems", Triple::RTEMS)
366 .StartsWith("nacl", Triple::NaCl)
367 .StartsWith("cnk", Triple::CNK)
368 .StartsWith("bitrig", Triple::Bitrig)
369 .StartsWith("aix", Triple::AIX)
370 .StartsWith("cuda", Triple::CUDA)
371 .StartsWith("nvcl", Triple::NVCL)
372 .StartsWith("amdhsa", Triple::AMDHSA)
373 .StartsWith("ps4", Triple::PS4)
374 .Default(Triple::UnknownOS);
377 static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) {
378 return StringSwitch<Triple::EnvironmentType>(EnvironmentName)
379 .StartsWith("eabihf", Triple::EABIHF)
380 .StartsWith("eabi", Triple::EABI)
381 .StartsWith("gnueabihf", Triple::GNUEABIHF)
382 .StartsWith("gnueabi", Triple::GNUEABI)
383 .StartsWith("gnux32", Triple::GNUX32)
384 .StartsWith("code16", Triple::CODE16)
385 .StartsWith("gnu", Triple::GNU)
386 .StartsWith("android", Triple::Android)
387 .StartsWith("msvc", Triple::MSVC)
388 .StartsWith("itanium", Triple::Itanium)
389 .StartsWith("cygnus", Triple::Cygnus)
390 .Default(Triple::UnknownEnvironment);
393 static Triple::ObjectFormatType parseFormat(StringRef EnvironmentName) {
394 return StringSwitch<Triple::ObjectFormatType>(EnvironmentName)
395 .EndsWith("coff", Triple::COFF)
396 .EndsWith("elf", Triple::ELF)
397 .EndsWith("macho", Triple::MachO)
398 .Default(Triple::UnknownObjectFormat);
401 static Triple::SubArchType parseSubArch(StringRef SubArchName) {
402 if (SubArchName.endswith("eb"))
403 SubArchName = SubArchName.substr(0, SubArchName.size() - 2);
405 return StringSwitch<Triple::SubArchType>(SubArchName)
406 .EndsWith("v8", Triple::ARMSubArch_v8)
407 .EndsWith("v8a", Triple::ARMSubArch_v8)
408 .EndsWith("v7", Triple::ARMSubArch_v7)
409 .EndsWith("v7a", Triple::ARMSubArch_v7)
410 .EndsWith("v7em", Triple::ARMSubArch_v7em)
411 .EndsWith("v7l", Triple::ARMSubArch_v7)
412 .EndsWith("v7m", Triple::ARMSubArch_v7m)
413 .EndsWith("v7r", Triple::ARMSubArch_v7)
414 .EndsWith("v7s", Triple::ARMSubArch_v7s)
415 .EndsWith("v6", Triple::ARMSubArch_v6)
416 .EndsWith("v6m", Triple::ARMSubArch_v6m)
417 .EndsWith("v6sm", Triple::ARMSubArch_v6m)
418 .EndsWith("v6t2", Triple::ARMSubArch_v6t2)
419 .EndsWith("v5", Triple::ARMSubArch_v5)
420 .EndsWith("v5e", Triple::ARMSubArch_v5)
421 .EndsWith("v5t", Triple::ARMSubArch_v5)
422 .EndsWith("v5te", Triple::ARMSubArch_v5te)
423 .EndsWith("v4t", Triple::ARMSubArch_v4t)
424 .EndsWith("kalimba3", Triple::KalimbaSubArch_v3)
425 .EndsWith("kalimba4", Triple::KalimbaSubArch_v4)
426 .EndsWith("kalimba5", Triple::KalimbaSubArch_v5)
427 .Default(Triple::NoSubArch);
430 static const char *getObjectFormatTypeName(Triple::ObjectFormatType Kind) {
432 case Triple::UnknownObjectFormat: return "";
433 case Triple::COFF: return "coff";
434 case Triple::ELF: return "elf";
435 case Triple::MachO: return "macho";
437 llvm_unreachable("unknown object format type");
440 static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
442 return Triple::MachO;
443 else if (T.isOSWindows())
448 /// \brief Construct a triple from the string representation provided.
450 /// This stores the string representation and parses the various pieces into
452 Triple::Triple(const Twine &Str)
454 Arch(parseArch(getArchName())),
455 SubArch(parseSubArch(getArchName())),
456 Vendor(parseVendor(getVendorName())),
457 OS(parseOS(getOSName())),
458 Environment(parseEnvironment(getEnvironmentName())),
459 ObjectFormat(parseFormat(getEnvironmentName())) {
460 if (ObjectFormat == Triple::UnknownObjectFormat)
461 ObjectFormat = getDefaultFormat(*this);
464 /// \brief Construct a triple from string representations of the architecture,
467 /// This joins each argument into a canonical string representation and parses
468 /// them into enum members. It leaves the environment unknown and omits it from
469 /// the string representation.
470 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr)
471 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()),
472 Arch(parseArch(ArchStr.str())),
473 SubArch(parseSubArch(ArchStr.str())),
474 Vendor(parseVendor(VendorStr.str())),
475 OS(parseOS(OSStr.str())),
476 Environment(), ObjectFormat(Triple::UnknownObjectFormat) {
477 ObjectFormat = getDefaultFormat(*this);
480 /// \brief Construct a triple from string representations of the architecture,
481 /// vendor, OS, and environment.
483 /// This joins each argument into a canonical string representation and parses
484 /// them into enum members.
485 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr,
486 const Twine &EnvironmentStr)
487 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr + Twine('-') +
488 EnvironmentStr).str()),
489 Arch(parseArch(ArchStr.str())),
490 SubArch(parseSubArch(ArchStr.str())),
491 Vendor(parseVendor(VendorStr.str())),
492 OS(parseOS(OSStr.str())),
493 Environment(parseEnvironment(EnvironmentStr.str())),
494 ObjectFormat(parseFormat(EnvironmentStr.str())) {
495 if (ObjectFormat == Triple::UnknownObjectFormat)
496 ObjectFormat = getDefaultFormat(*this);
499 std::string Triple::normalize(StringRef Str) {
500 bool IsMinGW32 = false;
501 bool IsCygwin = false;
503 // Parse into components.
504 SmallVector<StringRef, 4> Components;
505 Str.split(Components, "-");
507 // If the first component corresponds to a known architecture, preferentially
508 // use it for the architecture. If the second component corresponds to a
509 // known vendor, preferentially use it for the vendor, etc. This avoids silly
510 // component movement when a component parses as (eg) both a valid arch and a
512 ArchType Arch = UnknownArch;
513 if (Components.size() > 0)
514 Arch = parseArch(Components[0]);
515 VendorType Vendor = UnknownVendor;
516 if (Components.size() > 1)
517 Vendor = parseVendor(Components[1]);
518 OSType OS = UnknownOS;
519 if (Components.size() > 2) {
520 OS = parseOS(Components[2]);
521 IsCygwin = Components[2].startswith("cygwin");
522 IsMinGW32 = Components[2].startswith("mingw");
524 EnvironmentType Environment = UnknownEnvironment;
525 if (Components.size() > 3)
526 Environment = parseEnvironment(Components[3]);
527 ObjectFormatType ObjectFormat = UnknownObjectFormat;
528 if (Components.size() > 4)
529 ObjectFormat = parseFormat(Components[4]);
531 // Note which components are already in their final position. These will not
534 Found[0] = Arch != UnknownArch;
535 Found[1] = Vendor != UnknownVendor;
536 Found[2] = OS != UnknownOS;
537 Found[3] = Environment != UnknownEnvironment;
539 // If they are not there already, permute the components into their canonical
540 // positions by seeing if they parse as a valid architecture, and if so moving
541 // the component to the architecture position etc.
542 for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) {
544 continue; // Already in the canonical position.
546 for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
547 // Do not reparse any components that already matched.
548 if (Idx < array_lengthof(Found) && Found[Idx])
551 // Does this component parse as valid for the target position?
553 StringRef Comp = Components[Idx];
555 default: llvm_unreachable("unexpected component type!");
557 Arch = parseArch(Comp);
558 Valid = Arch != UnknownArch;
561 Vendor = parseVendor(Comp);
562 Valid = Vendor != UnknownVendor;
566 IsCygwin = Comp.startswith("cygwin");
567 IsMinGW32 = Comp.startswith("mingw");
568 Valid = OS != UnknownOS || IsCygwin || IsMinGW32;
571 Environment = parseEnvironment(Comp);
572 Valid = Environment != UnknownEnvironment;
574 ObjectFormat = parseFormat(Comp);
575 Valid = ObjectFormat != UnknownObjectFormat;
580 continue; // Nope, try the next component.
582 // Move the component to the target position, pushing any non-fixed
583 // components that are in the way to the right. This tends to give
584 // good results in the common cases of a forgotten vendor component
585 // or a wrongly positioned environment.
587 // Insert left, pushing the existing components to the right. For
588 // example, a-b-i386 -> i386-a-b when moving i386 to the front.
589 StringRef CurrentComponent(""); // The empty component.
590 // Replace the component we are moving with an empty component.
591 std::swap(CurrentComponent, Components[Idx]);
592 // Insert the component being moved at Pos, displacing any existing
593 // components to the right.
594 for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
595 // Skip over any fixed components.
596 while (i < array_lengthof(Found) && Found[i])
598 // Place the component at the new position, getting the component
599 // that was at this position - it will be moved right.
600 std::swap(CurrentComponent, Components[i]);
602 } else if (Pos > Idx) {
603 // Push right by inserting empty components until the component at Idx
604 // reaches the target position Pos. For example, pc-a -> -pc-a when
605 // moving pc to the second position.
607 // Insert one empty component at Idx.
608 StringRef CurrentComponent(""); // The empty component.
609 for (unsigned i = Idx; i < Components.size();) {
610 // Place the component at the new position, getting the component
611 // that was at this position - it will be moved right.
612 std::swap(CurrentComponent, Components[i]);
613 // If it was placed on top of an empty component then we are done.
614 if (CurrentComponent.empty())
616 // Advance to the next component, skipping any fixed components.
617 while (++i < array_lengthof(Found) && Found[i])
620 // The last component was pushed off the end - append it.
621 if (!CurrentComponent.empty())
622 Components.push_back(CurrentComponent);
624 // Advance Idx to the component's new position.
625 while (++Idx < array_lengthof(Found) && Found[Idx])
627 } while (Idx < Pos); // Add more until the final position is reached.
629 assert(Pos < Components.size() && Components[Pos] == Comp &&
630 "Component moved wrong!");
636 // Special case logic goes here. At this point Arch, Vendor and OS have the
637 // correct values for the computed components.
639 if (OS == Triple::Win32) {
640 Components.resize(4);
641 Components[2] = "windows";
642 if (Environment == UnknownEnvironment) {
643 if (ObjectFormat == UnknownObjectFormat || ObjectFormat == Triple::COFF)
644 Components[3] = "msvc";
646 Components[3] = getObjectFormatTypeName(ObjectFormat);
648 } else if (IsMinGW32) {
649 Components.resize(4);
650 Components[2] = "windows";
651 Components[3] = "gnu";
652 } else if (IsCygwin) {
653 Components.resize(4);
654 Components[2] = "windows";
655 Components[3] = "cygnus";
657 if (IsMinGW32 || IsCygwin ||
658 (OS == Triple::Win32 && Environment != UnknownEnvironment)) {
659 if (ObjectFormat != UnknownObjectFormat && ObjectFormat != Triple::COFF) {
660 Components.resize(5);
661 Components[4] = getObjectFormatTypeName(ObjectFormat);
665 // Stick the corrected components back together to form the normalized string.
666 std::string Normalized;
667 for (unsigned i = 0, e = Components.size(); i != e; ++i) {
668 if (i) Normalized += '-';
669 Normalized += Components[i];
674 StringRef Triple::getArchName() const {
675 return StringRef(Data).split('-').first; // Isolate first component
678 StringRef Triple::getVendorName() const {
679 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
680 return Tmp.split('-').first; // Isolate second component
683 StringRef Triple::getOSName() const {
684 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
685 Tmp = Tmp.split('-').second; // Strip second component
686 return Tmp.split('-').first; // Isolate third component
689 StringRef Triple::getEnvironmentName() const {
690 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
691 Tmp = Tmp.split('-').second; // Strip second component
692 return Tmp.split('-').second; // Strip third component
695 StringRef Triple::getOSAndEnvironmentName() const {
696 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
697 return Tmp.split('-').second; // Strip second component
700 static unsigned EatNumber(StringRef &Str) {
701 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
705 // Consume the leading digit.
706 Result = Result*10 + (Str[0] - '0');
710 } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9');
715 void Triple::getOSVersion(unsigned &Major, unsigned &Minor,
716 unsigned &Micro) const {
717 StringRef OSName = getOSName();
719 // For Android, we care about the Android version rather than the Linux
721 if (getEnvironment() == Android) {
722 OSName = getEnvironmentName().substr(strlen("android"));
723 if (OSName.startswith("eabi"))
724 OSName = OSName.substr(strlen("eabi"));
727 // Assume that the OS portion of the triple starts with the canonical name.
728 StringRef OSTypeName = getOSTypeName(getOS());
729 if (OSName.startswith(OSTypeName))
730 OSName = OSName.substr(OSTypeName.size());
732 // Any unset version defaults to 0.
733 Major = Minor = Micro = 0;
735 // Parse up to three components.
736 unsigned *Components[3] = { &Major, &Minor, &Micro };
737 for (unsigned i = 0; i != 3; ++i) {
738 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
741 // Consume the leading number.
742 *Components[i] = EatNumber(OSName);
744 // Consume the separator, if present.
745 if (OSName.startswith("."))
746 OSName = OSName.substr(1);
750 bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor,
751 unsigned &Micro) const {
752 getOSVersion(Major, Minor, Micro);
755 default: llvm_unreachable("unexpected OS for Darwin triple");
757 // Default to darwin8, i.e., MacOSX 10.4.
760 // Darwin version numbers are skewed from OS X versions.
777 // Ignore the version from the triple. This is only handled because the
778 // the clang driver combines OS X and IOS support into a common Darwin
779 // toolchain that wants to know the OS X version number even when targeting
789 void Triple::getiOSVersion(unsigned &Major, unsigned &Minor,
790 unsigned &Micro) const {
792 default: llvm_unreachable("unexpected OS for Darwin triple");
795 // Ignore the version from the triple. This is only handled because the
796 // the clang driver combines OS X and IOS support into a common Darwin
797 // toolchain that wants to know the iOS version number even when targeting
804 getOSVersion(Major, Minor, Micro);
805 // Default to 5.0 (or 7.0 for arm64).
807 Major = (getArch() == aarch64) ? 7 : 5;
812 void Triple::setTriple(const Twine &Str) {
816 void Triple::setArch(ArchType Kind) {
817 setArchName(getArchTypeName(Kind));
820 void Triple::setVendor(VendorType Kind) {
821 setVendorName(getVendorTypeName(Kind));
824 void Triple::setOS(OSType Kind) {
825 setOSName(getOSTypeName(Kind));
828 void Triple::setEnvironment(EnvironmentType Kind) {
829 if (ObjectFormat == getDefaultFormat(*this))
830 return setEnvironmentName(getEnvironmentTypeName(Kind));
832 setEnvironmentName((getEnvironmentTypeName(Kind) + Twine("-") +
833 getObjectFormatTypeName(ObjectFormat)).str());
836 void Triple::setObjectFormat(ObjectFormatType Kind) {
837 if (Environment == UnknownEnvironment)
838 return setEnvironmentName(getObjectFormatTypeName(Kind));
840 setEnvironmentName((getEnvironmentTypeName(Environment) + Twine("-") +
841 getObjectFormatTypeName(Kind)).str());
844 void Triple::setArchName(StringRef Str) {
845 // Work around a miscompilation bug for Twines in gcc 4.0.3.
846 SmallString<64> Triple;
849 Triple += getVendorName();
851 Triple += getOSAndEnvironmentName();
852 setTriple(Triple.str());
855 void Triple::setVendorName(StringRef Str) {
856 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
859 void Triple::setOSName(StringRef Str) {
860 if (hasEnvironment())
861 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
862 "-" + getEnvironmentName());
864 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
867 void Triple::setEnvironmentName(StringRef Str) {
868 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
872 void Triple::setOSAndEnvironmentName(StringRef Str) {
873 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
876 static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
878 case llvm::Triple::UnknownArch:
881 case llvm::Triple::msp430:
884 case llvm::Triple::arm:
885 case llvm::Triple::armeb:
886 case llvm::Triple::hexagon:
887 case llvm::Triple::le32:
888 case llvm::Triple::mips:
889 case llvm::Triple::mipsel:
890 case llvm::Triple::nvptx:
891 case llvm::Triple::ppc:
892 case llvm::Triple::r600:
893 case llvm::Triple::sparc:
894 case llvm::Triple::tce:
895 case llvm::Triple::thumb:
896 case llvm::Triple::thumbeb:
897 case llvm::Triple::x86:
898 case llvm::Triple::xcore:
899 case llvm::Triple::amdil:
900 case llvm::Triple::hsail:
901 case llvm::Triple::spir:
902 case llvm::Triple::kalimba:
905 case llvm::Triple::aarch64:
906 case llvm::Triple::aarch64_be:
907 case llvm::Triple::amdgcn:
908 case llvm::Triple::bpf:
909 case llvm::Triple::le64:
910 case llvm::Triple::mips64:
911 case llvm::Triple::mips64el:
912 case llvm::Triple::nvptx64:
913 case llvm::Triple::ppc64:
914 case llvm::Triple::ppc64le:
915 case llvm::Triple::sparcv9:
916 case llvm::Triple::systemz:
917 case llvm::Triple::x86_64:
918 case llvm::Triple::amdil64:
919 case llvm::Triple::hsail64:
920 case llvm::Triple::spir64:
923 llvm_unreachable("Invalid architecture value");
926 bool Triple::isArch64Bit() const {
927 return getArchPointerBitWidth(getArch()) == 64;
930 bool Triple::isArch32Bit() const {
931 return getArchPointerBitWidth(getArch()) == 32;
934 bool Triple::isArch16Bit() const {
935 return getArchPointerBitWidth(getArch()) == 16;
938 Triple Triple::get32BitArchVariant() const {
941 case Triple::UnknownArch:
942 case Triple::aarch64:
943 case Triple::aarch64_be:
947 case Triple::systemz:
948 case Triple::ppc64le:
949 T.setArch(UnknownArch);
957 case Triple::hexagon:
958 case Triple::kalimba:
968 case Triple::thumbeb:
974 case Triple::le64: T.setArch(Triple::le32); break;
975 case Triple::mips64: T.setArch(Triple::mips); break;
976 case Triple::mips64el: T.setArch(Triple::mipsel); break;
977 case Triple::nvptx64: T.setArch(Triple::nvptx); break;
978 case Triple::ppc64: T.setArch(Triple::ppc); break;
979 case Triple::sparcv9: T.setArch(Triple::sparc); break;
980 case Triple::x86_64: T.setArch(Triple::x86); break;
981 case Triple::amdil64: T.setArch(Triple::amdil); break;
982 case Triple::hsail64: T.setArch(Triple::hsail); break;
983 case Triple::spir64: T.setArch(Triple::spir); break;
988 Triple Triple::get64BitArchVariant() const {
991 case Triple::UnknownArch:
994 case Triple::hexagon:
995 case Triple::kalimba:
1000 case Triple::thumbeb:
1002 T.setArch(UnknownArch);
1005 case Triple::aarch64:
1006 case Triple::aarch64_be:
1009 case Triple::amdil64:
1010 case Triple::amdgcn:
1011 case Triple::hsail64:
1012 case Triple::spir64:
1013 case Triple::mips64:
1014 case Triple::mips64el:
1015 case Triple::nvptx64:
1017 case Triple::ppc64le:
1018 case Triple::sparcv9:
1019 case Triple::systemz:
1020 case Triple::x86_64:
1024 case Triple::le32: T.setArch(Triple::le64); break;
1025 case Triple::mips: T.setArch(Triple::mips64); break;
1026 case Triple::mipsel: T.setArch(Triple::mips64el); break;
1027 case Triple::nvptx: T.setArch(Triple::nvptx64); break;
1028 case Triple::ppc: T.setArch(Triple::ppc64); break;
1029 case Triple::sparc: T.setArch(Triple::sparcv9); break;
1030 case Triple::x86: T.setArch(Triple::x86_64); break;
1031 case Triple::amdil: T.setArch(Triple::amdil64); break;
1032 case Triple::hsail: T.setArch(Triple::hsail64); break;
1033 case Triple::spir: T.setArch(Triple::spir64); break;
1038 // FIXME: tblgen this.
1039 const char *Triple::getARMCPUForArch(StringRef MArch) const {
1041 MArch = getArchName();
1044 case llvm::Triple::FreeBSD:
1045 case llvm::Triple::NetBSD:
1046 if (MArch == "armv6")
1047 return "arm1176jzf-s";
1049 case llvm::Triple::Win32:
1050 // FIXME: this is invalid for WindowsCE
1056 const char *result = nullptr;
1057 size_t offset = StringRef::npos;
1058 if (MArch.startswith("arm"))
1060 if (MArch.startswith("thumb"))
1062 if (offset != StringRef::npos && MArch.substr(offset, 2) == "eb")
1064 if (MArch.endswith("eb"))
1065 MArch = MArch.substr(0, MArch.size() - 2);
1066 if (offset != StringRef::npos)
1067 result = llvm::StringSwitch<const char *>(MArch.substr(offset))
1068 .Cases("v2", "v2a", "arm2")
1070 .Case("v3m", "arm7m")
1071 .Case("v4", "strongarm")
1072 .Case("v4t", "arm7tdmi")
1073 .Cases("v5", "v5t", "arm10tdmi")
1074 .Cases("v5e", "v5te", "arm1022e")
1075 .Case("v5tej", "arm926ej-s")
1076 .Cases("v6", "v6k", "arm1136jf-s")
1077 .Case("v6j", "arm1136j-s")
1078 .Cases("v6z", "v6zk", "arm1176jzf-s")
1079 .Case("v6t2", "arm1156t2-s")
1080 .Cases("v6m", "v6-m", "v6sm", "v6s-m", "cortex-m0")
1081 .Cases("v7", "v7a", "v7-a", "v7l", "v7-l", "cortex-a8")
1082 .Cases("v7s", "v7-s", "swift")
1083 .Cases("v7r", "v7-r", "cortex-r4")
1084 .Cases("v7m", "v7-m", "cortex-m3")
1085 .Cases("v7em", "v7e-m", "cortex-m4")
1086 .Cases("v8", "v8a", "v8-a", "cortex-a53")
1089 result = llvm::StringSwitch<const char *>(MArch)
1090 .Case("ep9312", "ep9312")
1091 .Case("iwmmxt", "iwmmxt")
1092 .Case("xscale", "xscale")
1098 // If all else failed, return the most base CPU with thumb interworking
1099 // supported by LLVM.
1100 // FIXME: Should warn once that we're falling back.
1102 case llvm::Triple::NetBSD:
1103 switch (getEnvironment()) {
1104 case llvm::Triple::GNUEABIHF:
1105 case llvm::Triple::GNUEABI:
1106 case llvm::Triple::EABIHF:
1107 case llvm::Triple::EABI:
1108 return "arm926ej-s";
1113 switch (getEnvironment()) {
1114 case llvm::Triple::EABIHF:
1115 case llvm::Triple::GNUEABIHF:
1116 return "arm1176jzf-s";