1 //===--- Triple.cpp - Target triple helper class --------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
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"
15 #include <cstring>
16 using namespace llvm;
17
getArchTypeName(ArchType Kind)18 const char *Triple::getArchTypeName(ArchType Kind) {
19 switch (Kind) {
20 case UnknownArch: return "unknown";
21
22 case aarch64: return "aarch64";
23 case aarch64_be: return "aarch64_be";
24 case arm: return "arm";
25 case armeb: return "armeb";
26 case arm64: return "arm64";
27 case arm64_be: return "arm64_be";
28 case hexagon: return "hexagon";
29 case mips: return "mips";
30 case mipsel: return "mipsel";
31 case mips64: return "mips64";
32 case mips64el: return "mips64el";
33 case msp430: return "msp430";
34 case ppc64: return "powerpc64";
35 case ppc64le: return "powerpc64le";
36 case ppc: return "powerpc";
37 case r600: return "r600";
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 amdil: return "amdil";
51 case spir: return "spir";
52 case spir64: return "spir64";
53 case kalimba: return "kalimba";
54 }
55
56 llvm_unreachable("Invalid ArchType!");
57 }
58
getArchTypePrefix(ArchType Kind)59 const char *Triple::getArchTypePrefix(ArchType Kind) {
60 switch (Kind) {
61 default:
62 return nullptr;
63
64 case aarch64:
65 case aarch64_be: return "aarch64";
66
67 case arm:
68 case armeb:
69 case thumb:
70 case thumbeb: return "arm";
71
72 case arm64:
73 case arm64_be: return "arm64";
74
75 case ppc64:
76 case ppc64le:
77 case ppc: return "ppc";
78
79 case mips:
80 case mipsel:
81 case mips64:
82 case mips64el: return "mips";
83
84 case hexagon: return "hexagon";
85
86 case r600: return "r600";
87
88 case sparcv9:
89 case sparc: return "sparc";
90
91 case systemz: return "systemz";
92
93 case x86:
94 case x86_64: return "x86";
95
96 case xcore: return "xcore";
97
98 case nvptx: return "nvptx";
99 case nvptx64: return "nvptx";
100
101 case le32: return "le32";
102 case amdil: return "amdil";
103 case spir: return "spir";
104 case spir64: return "spir";
105 case kalimba: return "kalimba";
106 }
107 }
108
getVendorTypeName(VendorType Kind)109 const char *Triple::getVendorTypeName(VendorType Kind) {
110 switch (Kind) {
111 case UnknownVendor: return "unknown";
112
113 case Apple: return "apple";
114 case PC: return "pc";
115 case SCEI: return "scei";
116 case BGP: return "bgp";
117 case BGQ: return "bgq";
118 case Freescale: return "fsl";
119 case IBM: return "ibm";
120 case ImaginationTechnologies: return "img";
121 case NVIDIA: return "nvidia";
122 case CSR: return "csr";
123 }
124
125 llvm_unreachable("Invalid VendorType!");
126 }
127
getOSTypeName(OSType Kind)128 const char *Triple::getOSTypeName(OSType Kind) {
129 switch (Kind) {
130 case UnknownOS: return "unknown";
131
132 case AuroraUX: return "auroraux";
133 case Cygwin: return "cygwin";
134 case Darwin: return "darwin";
135 case DragonFly: return "dragonfly";
136 case FreeBSD: return "freebsd";
137 case IOS: return "ios";
138 case KFreeBSD: return "kfreebsd";
139 case Linux: return "linux";
140 case Lv2: return "lv2";
141 case MacOSX: return "macosx";
142 case MinGW32: return "mingw32";
143 case NetBSD: return "netbsd";
144 case OpenBSD: return "openbsd";
145 case Solaris: return "solaris";
146 case Win32: return "windows";
147 case Haiku: return "haiku";
148 case Minix: return "minix";
149 case RTEMS: return "rtems";
150 case NaCl: return "nacl";
151 case CNK: return "cnk";
152 case Bitrig: return "bitrig";
153 case AIX: return "aix";
154 case CUDA: return "cuda";
155 case NVCL: return "nvcl";
156 }
157
158 llvm_unreachable("Invalid OSType");
159 }
160
getEnvironmentTypeName(EnvironmentType Kind)161 const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
162 switch (Kind) {
163 case UnknownEnvironment: return "unknown";
164 case GNU: return "gnu";
165 case GNUEABIHF: return "gnueabihf";
166 case GNUEABI: return "gnueabi";
167 case GNUX32: return "gnux32";
168 case CODE16: return "code16";
169 case EABI: return "eabi";
170 case EABIHF: return "eabihf";
171 case Android: return "android";
172 case MSVC: return "msvc";
173 case Itanium: return "itanium";
174 case Cygnus: return "cygnus";
175 }
176
177 llvm_unreachable("Invalid EnvironmentType!");
178 }
179
getArchTypeForLLVMName(StringRef Name)180 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
181 return StringSwitch<Triple::ArchType>(Name)
182 .Case("aarch64", aarch64)
183 .Case("aarch64_be", aarch64_be)
184 .Case("arm", arm)
185 .Case("armeb", armeb)
186 .Case("arm64", arm64)
187 .Case("arm64_be", arm64_be)
188 .Case("mips", mips)
189 .Case("mipsel", mipsel)
190 .Case("mips64", mips64)
191 .Case("mips64el", mips64el)
192 .Case("msp430", msp430)
193 .Case("ppc64", ppc64)
194 .Case("ppc32", ppc)
195 .Case("ppc", ppc)
196 .Case("ppc64le", ppc64le)
197 .Case("r600", r600)
198 .Case("hexagon", hexagon)
199 .Case("sparc", sparc)
200 .Case("sparcv9", sparcv9)
201 .Case("systemz", systemz)
202 .Case("tce", tce)
203 .Case("thumb", thumb)
204 .Case("thumbeb", thumbeb)
205 .Case("x86", x86)
206 .Case("x86-64", x86_64)
207 .Case("xcore", xcore)
208 .Case("nvptx", nvptx)
209 .Case("nvptx64", nvptx64)
210 .Case("le32", le32)
211 .Case("amdil", amdil)
212 .Case("spir", spir)
213 .Case("spir64", spir64)
214 .Case("kalimba", kalimba)
215 .Default(UnknownArch);
216 }
217
218 // Returns architecture name that is understood by the target assembler.
getArchNameForAssembler()219 const char *Triple::getArchNameForAssembler() {
220 if (!isOSDarwin() && getVendor() != Triple::Apple)
221 return nullptr;
222
223 return StringSwitch<const char*>(getArchName())
224 .Case("i386", "i386")
225 .Case("x86_64", "x86_64")
226 .Case("powerpc", "ppc")
227 .Case("powerpc64", "ppc64")
228 .Case("powerpc64le", "ppc64le")
229 .Case("arm", "arm")
230 .Cases("armv4t", "thumbv4t", "armv4t")
231 .Cases("armv5", "armv5e", "thumbv5", "thumbv5e", "armv5")
232 .Cases("armv6", "thumbv6", "armv6")
233 .Cases("armv7", "thumbv7", "armv7")
234 .Case("armeb", "armeb")
235 .Case("arm64", "arm64")
236 .Case("arm64_be", "arm64")
237 .Case("r600", "r600")
238 .Case("nvptx", "nvptx")
239 .Case("nvptx64", "nvptx64")
240 .Case("le32", "le32")
241 .Case("amdil", "amdil")
242 .Case("spir", "spir")
243 .Case("spir64", "spir64")
244 .Default(nullptr);
245 }
246
parseArch(StringRef ArchName)247 static Triple::ArchType parseArch(StringRef ArchName) {
248 return StringSwitch<Triple::ArchType>(ArchName)
249 .Cases("i386", "i486", "i586", "i686", Triple::x86)
250 // FIXME: Do we need to support these?
251 .Cases("i786", "i886", "i986", Triple::x86)
252 .Cases("amd64", "x86_64", "x86_64h", Triple::x86_64)
253 .Case("powerpc", Triple::ppc)
254 .Cases("powerpc64", "ppu", Triple::ppc64)
255 .Case("powerpc64le", Triple::ppc64le)
256 .Case("aarch64", Triple::aarch64)
257 .Case("aarch64_be", Triple::aarch64_be)
258 .Cases("arm", "xscale", Triple::arm)
259 // FIXME: It would be good to replace these with explicit names for all the
260 // various suffixes supported.
261 .StartsWith("armv", Triple::arm)
262 .Case("armeb", Triple::armeb)
263 .StartsWith("armebv", Triple::armeb)
264 .Case("thumb", Triple::thumb)
265 .StartsWith("thumbv", Triple::thumb)
266 .Case("thumbeb", Triple::thumbeb)
267 .StartsWith("thumbebv", Triple::thumbeb)
268 .Case("arm64", Triple::arm64)
269 .Case("arm64_be", Triple::arm64_be)
270 .Case("msp430", Triple::msp430)
271 .Cases("mips", "mipseb", "mipsallegrex", Triple::mips)
272 .Cases("mipsel", "mipsallegrexel", Triple::mipsel)
273 .Cases("mips64", "mips64eb", Triple::mips64)
274 .Case("mips64el", Triple::mips64el)
275 .Case("r600", Triple::r600)
276 .Case("hexagon", Triple::hexagon)
277 .Case("s390x", Triple::systemz)
278 .Case("sparc", Triple::sparc)
279 .Cases("sparcv9", "sparc64", Triple::sparcv9)
280 .Case("tce", Triple::tce)
281 .Case("xcore", Triple::xcore)
282 .Case("nvptx", Triple::nvptx)
283 .Case("nvptx64", Triple::nvptx64)
284 .Case("le32", Triple::le32)
285 .Case("amdil", Triple::amdil)
286 .Case("spir", Triple::spir)
287 .Case("spir64", Triple::spir64)
288 .Case("kalimba", Triple::kalimba)
289 .Default(Triple::UnknownArch);
290 }
291
parseVendor(StringRef VendorName)292 static Triple::VendorType parseVendor(StringRef VendorName) {
293 return StringSwitch<Triple::VendorType>(VendorName)
294 .Case("apple", Triple::Apple)
295 .Case("pc", Triple::PC)
296 .Case("scei", Triple::SCEI)
297 .Case("bgp", Triple::BGP)
298 .Case("bgq", Triple::BGQ)
299 .Case("fsl", Triple::Freescale)
300 .Case("ibm", Triple::IBM)
301 .Case("img", Triple::ImaginationTechnologies)
302 .Case("nvidia", Triple::NVIDIA)
303 .Case("csr", Triple::CSR)
304 .Default(Triple::UnknownVendor);
305 }
306
parseOS(StringRef OSName)307 static Triple::OSType parseOS(StringRef OSName) {
308 return StringSwitch<Triple::OSType>(OSName)
309 .StartsWith("auroraux", Triple::AuroraUX)
310 .StartsWith("cygwin", Triple::Cygwin)
311 .StartsWith("darwin", Triple::Darwin)
312 .StartsWith("dragonfly", Triple::DragonFly)
313 .StartsWith("freebsd", Triple::FreeBSD)
314 .StartsWith("ios", Triple::IOS)
315 .StartsWith("kfreebsd", Triple::KFreeBSD)
316 .StartsWith("linux", Triple::Linux)
317 .StartsWith("lv2", Triple::Lv2)
318 .StartsWith("macosx", Triple::MacOSX)
319 .StartsWith("mingw32", Triple::MinGW32)
320 .StartsWith("netbsd", Triple::NetBSD)
321 .StartsWith("openbsd", Triple::OpenBSD)
322 .StartsWith("solaris", Triple::Solaris)
323 .StartsWith("win32", Triple::Win32)
324 .StartsWith("windows", Triple::Win32)
325 .StartsWith("haiku", Triple::Haiku)
326 .StartsWith("minix", Triple::Minix)
327 .StartsWith("rtems", Triple::RTEMS)
328 .StartsWith("nacl", Triple::NaCl)
329 .StartsWith("cnk", Triple::CNK)
330 .StartsWith("bitrig", Triple::Bitrig)
331 .StartsWith("aix", Triple::AIX)
332 .StartsWith("cuda", Triple::CUDA)
333 .StartsWith("nvcl", Triple::NVCL)
334 .Default(Triple::UnknownOS);
335 }
336
parseEnvironment(StringRef EnvironmentName)337 static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) {
338 return StringSwitch<Triple::EnvironmentType>(EnvironmentName)
339 .StartsWith("eabihf", Triple::EABIHF)
340 .StartsWith("eabi", Triple::EABI)
341 .StartsWith("gnueabihf", Triple::GNUEABIHF)
342 .StartsWith("gnueabi", Triple::GNUEABI)
343 .StartsWith("gnux32", Triple::GNUX32)
344 .StartsWith("code16", Triple::CODE16)
345 .StartsWith("gnu", Triple::GNU)
346 .StartsWith("android", Triple::Android)
347 .StartsWith("msvc", Triple::MSVC)
348 .StartsWith("itanium", Triple::Itanium)
349 .StartsWith("cygnus", Triple::Cygnus)
350 .Default(Triple::UnknownEnvironment);
351 }
352
parseFormat(StringRef EnvironmentName)353 static Triple::ObjectFormatType parseFormat(StringRef EnvironmentName) {
354 return StringSwitch<Triple::ObjectFormatType>(EnvironmentName)
355 .EndsWith("coff", Triple::COFF)
356 .EndsWith("elf", Triple::ELF)
357 .EndsWith("macho", Triple::MachO)
358 .Default(Triple::UnknownObjectFormat);
359 }
360
getObjectFormatTypeName(Triple::ObjectFormatType Kind)361 static const char *getObjectFormatTypeName(Triple::ObjectFormatType Kind) {
362 switch (Kind) {
363 case Triple::UnknownObjectFormat: return "";
364 case Triple::COFF: return "coff";
365 case Triple::ELF: return "elf";
366 case Triple::MachO: return "macho";
367 }
368 llvm_unreachable("unknown object format type");
369 }
370
getDefaultFormat(const Triple & T)371 static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
372 if (T.isOSDarwin())
373 return Triple::MachO;
374 else if (T.isOSWindows())
375 return Triple::COFF;
376 return Triple::ELF;
377 }
378
379 /// \brief Construct a triple from the string representation provided.
380 ///
381 /// This stores the string representation and parses the various pieces into
382 /// enum members.
Triple(const Twine & Str)383 Triple::Triple(const Twine &Str)
384 : Data(Str.str()),
385 Arch(parseArch(getArchName())),
386 Vendor(parseVendor(getVendorName())),
387 OS(parseOS(getOSName())),
388 Environment(parseEnvironment(getEnvironmentName())),
389 ObjectFormat(parseFormat(getEnvironmentName())) {
390 if (ObjectFormat == Triple::UnknownObjectFormat)
391 ObjectFormat = getDefaultFormat(*this);
392 }
393
394 /// \brief Construct a triple from string representations of the architecture,
395 /// vendor, and OS.
396 ///
397 /// This joins each argument into a canonical string representation and parses
398 /// them into enum members. It leaves the environment unknown and omits it from
399 /// the string representation.
Triple(const Twine & ArchStr,const Twine & VendorStr,const Twine & OSStr)400 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr)
401 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()),
402 Arch(parseArch(ArchStr.str())),
403 Vendor(parseVendor(VendorStr.str())),
404 OS(parseOS(OSStr.str())),
405 Environment(), ObjectFormat(Triple::UnknownObjectFormat) {
406 ObjectFormat = getDefaultFormat(*this);
407 }
408
409 /// \brief Construct a triple from string representations of the architecture,
410 /// vendor, OS, and environment.
411 ///
412 /// This joins each argument into a canonical string representation and parses
413 /// them into enum members.
Triple(const Twine & ArchStr,const Twine & VendorStr,const Twine & OSStr,const Twine & EnvironmentStr)414 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr,
415 const Twine &EnvironmentStr)
416 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr + Twine('-') +
417 EnvironmentStr).str()),
418 Arch(parseArch(ArchStr.str())),
419 Vendor(parseVendor(VendorStr.str())),
420 OS(parseOS(OSStr.str())),
421 Environment(parseEnvironment(EnvironmentStr.str())),
422 ObjectFormat(parseFormat(EnvironmentStr.str())) {
423 if (ObjectFormat == Triple::UnknownObjectFormat)
424 ObjectFormat = getDefaultFormat(*this);
425 }
426
normalize(StringRef Str)427 std::string Triple::normalize(StringRef Str) {
428 // Parse into components.
429 SmallVector<StringRef, 4> Components;
430 Str.split(Components, "-");
431
432 // If the first component corresponds to a known architecture, preferentially
433 // use it for the architecture. If the second component corresponds to a
434 // known vendor, preferentially use it for the vendor, etc. This avoids silly
435 // component movement when a component parses as (eg) both a valid arch and a
436 // valid os.
437 ArchType Arch = UnknownArch;
438 if (Components.size() > 0)
439 Arch = parseArch(Components[0]);
440 VendorType Vendor = UnknownVendor;
441 if (Components.size() > 1)
442 Vendor = parseVendor(Components[1]);
443 OSType OS = UnknownOS;
444 if (Components.size() > 2)
445 OS = parseOS(Components[2]);
446 EnvironmentType Environment = UnknownEnvironment;
447 if (Components.size() > 3)
448 Environment = parseEnvironment(Components[3]);
449 ObjectFormatType ObjectFormat = UnknownObjectFormat;
450 if (Components.size() > 4)
451 ObjectFormat = parseFormat(Components[4]);
452
453 // Note which components are already in their final position. These will not
454 // be moved.
455 bool Found[4];
456 Found[0] = Arch != UnknownArch;
457 Found[1] = Vendor != UnknownVendor;
458 Found[2] = OS != UnknownOS;
459 Found[3] = Environment != UnknownEnvironment;
460
461 // If they are not there already, permute the components into their canonical
462 // positions by seeing if they parse as a valid architecture, and if so moving
463 // the component to the architecture position etc.
464 for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) {
465 if (Found[Pos])
466 continue; // Already in the canonical position.
467
468 for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
469 // Do not reparse any components that already matched.
470 if (Idx < array_lengthof(Found) && Found[Idx])
471 continue;
472
473 // Does this component parse as valid for the target position?
474 bool Valid = false;
475 StringRef Comp = Components[Idx];
476 switch (Pos) {
477 default: llvm_unreachable("unexpected component type!");
478 case 0:
479 Arch = parseArch(Comp);
480 Valid = Arch != UnknownArch;
481 break;
482 case 1:
483 Vendor = parseVendor(Comp);
484 Valid = Vendor != UnknownVendor;
485 break;
486 case 2:
487 OS = parseOS(Comp);
488 Valid = OS != UnknownOS;
489 break;
490 case 3:
491 Environment = parseEnvironment(Comp);
492 Valid = Environment != UnknownEnvironment;
493 if (!Valid) {
494 ObjectFormat = parseFormat(Comp);
495 Valid = ObjectFormat != UnknownObjectFormat;
496 }
497 break;
498 }
499 if (!Valid)
500 continue; // Nope, try the next component.
501
502 // Move the component to the target position, pushing any non-fixed
503 // components that are in the way to the right. This tends to give
504 // good results in the common cases of a forgotten vendor component
505 // or a wrongly positioned environment.
506 if (Pos < Idx) {
507 // Insert left, pushing the existing components to the right. For
508 // example, a-b-i386 -> i386-a-b when moving i386 to the front.
509 StringRef CurrentComponent(""); // The empty component.
510 // Replace the component we are moving with an empty component.
511 std::swap(CurrentComponent, Components[Idx]);
512 // Insert the component being moved at Pos, displacing any existing
513 // components to the right.
514 for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
515 // Skip over any fixed components.
516 while (i < array_lengthof(Found) && Found[i])
517 ++i;
518 // Place the component at the new position, getting the component
519 // that was at this position - it will be moved right.
520 std::swap(CurrentComponent, Components[i]);
521 }
522 } else if (Pos > Idx) {
523 // Push right by inserting empty components until the component at Idx
524 // reaches the target position Pos. For example, pc-a -> -pc-a when
525 // moving pc to the second position.
526 do {
527 // Insert one empty component at Idx.
528 StringRef CurrentComponent(""); // The empty component.
529 for (unsigned i = Idx; i < Components.size();) {
530 // Place the component at the new position, getting the component
531 // that was at this position - it will be moved right.
532 std::swap(CurrentComponent, Components[i]);
533 // If it was placed on top of an empty component then we are done.
534 if (CurrentComponent.empty())
535 break;
536 // Advance to the next component, skipping any fixed components.
537 while (++i < array_lengthof(Found) && Found[i])
538 ;
539 }
540 // The last component was pushed off the end - append it.
541 if (!CurrentComponent.empty())
542 Components.push_back(CurrentComponent);
543
544 // Advance Idx to the component's new position.
545 while (++Idx < array_lengthof(Found) && Found[Idx])
546 ;
547 } while (Idx < Pos); // Add more until the final position is reached.
548 }
549 assert(Pos < Components.size() && Components[Pos] == Comp &&
550 "Component moved wrong!");
551 Found[Pos] = true;
552 break;
553 }
554 }
555
556 // Special case logic goes here. At this point Arch, Vendor and OS have the
557 // correct values for the computed components.
558
559 if (OS == Triple::Win32) {
560 Components.resize(4);
561 Components[2] = "windows";
562 if (Environment == UnknownEnvironment) {
563 if (ObjectFormat == UnknownObjectFormat || ObjectFormat == Triple::COFF)
564 Components[3] = "msvc";
565 else
566 Components[3] = getObjectFormatTypeName(ObjectFormat);
567 }
568 } else if (OS == Triple::MinGW32) {
569 Components.resize(4);
570 Components[2] = "windows";
571 Components[3] = "gnu";
572 } else if (OS == Triple::Cygwin) {
573 Components.resize(4);
574 Components[2] = "windows";
575 Components[3] = "cygnus";
576 }
577 if (OS == Triple::MinGW32 || OS == Triple::Cygwin ||
578 (OS == Triple::Win32 && Environment != UnknownEnvironment)) {
579 if (ObjectFormat != UnknownObjectFormat && ObjectFormat != Triple::COFF) {
580 Components.resize(5);
581 Components[4] = getObjectFormatTypeName(ObjectFormat);
582 }
583 }
584
585 // Stick the corrected components back together to form the normalized string.
586 std::string Normalized;
587 for (unsigned i = 0, e = Components.size(); i != e; ++i) {
588 if (i) Normalized += '-';
589 Normalized += Components[i];
590 }
591 return Normalized;
592 }
593
getArchName() const594 StringRef Triple::getArchName() const {
595 return StringRef(Data).split('-').first; // Isolate first component
596 }
597
getVendorName() const598 StringRef Triple::getVendorName() const {
599 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
600 return Tmp.split('-').first; // Isolate second component
601 }
602
getOSName() const603 StringRef Triple::getOSName() const {
604 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
605 Tmp = Tmp.split('-').second; // Strip second component
606 return Tmp.split('-').first; // Isolate third component
607 }
608
getEnvironmentName() const609 StringRef Triple::getEnvironmentName() const {
610 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
611 Tmp = Tmp.split('-').second; // Strip second component
612 return Tmp.split('-').second; // Strip third component
613 }
614
getOSAndEnvironmentName() const615 StringRef Triple::getOSAndEnvironmentName() const {
616 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
617 return Tmp.split('-').second; // Strip second component
618 }
619
EatNumber(StringRef & Str)620 static unsigned EatNumber(StringRef &Str) {
621 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
622 unsigned Result = 0;
623
624 do {
625 // Consume the leading digit.
626 Result = Result*10 + (Str[0] - '0');
627
628 // Eat the digit.
629 Str = Str.substr(1);
630 } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9');
631
632 return Result;
633 }
634
getOSVersion(unsigned & Major,unsigned & Minor,unsigned & Micro) const635 void Triple::getOSVersion(unsigned &Major, unsigned &Minor,
636 unsigned &Micro) const {
637 StringRef OSName = getOSName();
638
639 // Assume that the OS portion of the triple starts with the canonical name.
640 StringRef OSTypeName = getOSTypeName(getOS());
641 if (OSName.startswith(OSTypeName))
642 OSName = OSName.substr(OSTypeName.size());
643
644 // Any unset version defaults to 0.
645 Major = Minor = Micro = 0;
646
647 // Parse up to three components.
648 unsigned *Components[3] = { &Major, &Minor, &Micro };
649 for (unsigned i = 0; i != 3; ++i) {
650 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
651 break;
652
653 // Consume the leading number.
654 *Components[i] = EatNumber(OSName);
655
656 // Consume the separator, if present.
657 if (OSName.startswith("."))
658 OSName = OSName.substr(1);
659 }
660 }
661
getMacOSXVersion(unsigned & Major,unsigned & Minor,unsigned & Micro) const662 bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor,
663 unsigned &Micro) const {
664 getOSVersion(Major, Minor, Micro);
665
666 switch (getOS()) {
667 default: llvm_unreachable("unexpected OS for Darwin triple");
668 case Darwin:
669 // Default to darwin8, i.e., MacOSX 10.4.
670 if (Major == 0)
671 Major = 8;
672 // Darwin version numbers are skewed from OS X versions.
673 if (Major < 4)
674 return false;
675 Micro = 0;
676 Minor = Major - 4;
677 Major = 10;
678 break;
679 case MacOSX:
680 // Default to 10.4.
681 if (Major == 0) {
682 Major = 10;
683 Minor = 4;
684 }
685 if (Major != 10)
686 return false;
687 break;
688 case IOS:
689 // Ignore the version from the triple. This is only handled because the
690 // the clang driver combines OS X and IOS support into a common Darwin
691 // toolchain that wants to know the OS X version number even when targeting
692 // IOS.
693 Major = 10;
694 Minor = 4;
695 Micro = 0;
696 break;
697 }
698 return true;
699 }
700
getiOSVersion(unsigned & Major,unsigned & Minor,unsigned & Micro) const701 void Triple::getiOSVersion(unsigned &Major, unsigned &Minor,
702 unsigned &Micro) const {
703 switch (getOS()) {
704 default: llvm_unreachable("unexpected OS for Darwin triple");
705 case Darwin:
706 case MacOSX:
707 // Ignore the version from the triple. This is only handled because the
708 // the clang driver combines OS X and IOS support into a common Darwin
709 // toolchain that wants to know the iOS version number even when targeting
710 // OS X.
711 Major = 5;
712 Minor = 0;
713 Micro = 0;
714 break;
715 case IOS:
716 getOSVersion(Major, Minor, Micro);
717 // Default to 5.0 (or 7.0 for arm64).
718 if (Major == 0)
719 Major = (getArch() == arm64) ? 7 : 5;
720 break;
721 }
722 }
723
setTriple(const Twine & Str)724 void Triple::setTriple(const Twine &Str) {
725 *this = Triple(Str);
726 }
727
setArch(ArchType Kind)728 void Triple::setArch(ArchType Kind) {
729 setArchName(getArchTypeName(Kind));
730 }
731
setVendor(VendorType Kind)732 void Triple::setVendor(VendorType Kind) {
733 setVendorName(getVendorTypeName(Kind));
734 }
735
setOS(OSType Kind)736 void Triple::setOS(OSType Kind) {
737 setOSName(getOSTypeName(Kind));
738 }
739
setEnvironment(EnvironmentType Kind)740 void Triple::setEnvironment(EnvironmentType Kind) {
741 setEnvironmentName(getEnvironmentTypeName(Kind));
742 }
743
setObjectFormat(ObjectFormatType Kind)744 void Triple::setObjectFormat(ObjectFormatType Kind) {
745 if (Environment == UnknownEnvironment)
746 return setEnvironmentName(getObjectFormatTypeName(Kind));
747
748 setEnvironmentName((getEnvironmentTypeName(Environment) + Twine("-") +
749 getObjectFormatTypeName(Kind)).str());
750 }
751
setArchName(StringRef Str)752 void Triple::setArchName(StringRef Str) {
753 // Work around a miscompilation bug for Twines in gcc 4.0.3.
754 SmallString<64> Triple;
755 Triple += Str;
756 Triple += "-";
757 Triple += getVendorName();
758 Triple += "-";
759 Triple += getOSAndEnvironmentName();
760 setTriple(Triple.str());
761 }
762
setVendorName(StringRef Str)763 void Triple::setVendorName(StringRef Str) {
764 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
765 }
766
setOSName(StringRef Str)767 void Triple::setOSName(StringRef Str) {
768 if (hasEnvironment())
769 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
770 "-" + getEnvironmentName());
771 else
772 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
773 }
774
setEnvironmentName(StringRef Str)775 void Triple::setEnvironmentName(StringRef Str) {
776 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
777 "-" + Str);
778 }
779
setOSAndEnvironmentName(StringRef Str)780 void Triple::setOSAndEnvironmentName(StringRef Str) {
781 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
782 }
783
getArchPointerBitWidth(llvm::Triple::ArchType Arch)784 static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
785 switch (Arch) {
786 case llvm::Triple::UnknownArch:
787 return 0;
788
789 case llvm::Triple::msp430:
790 return 16;
791
792 case llvm::Triple::amdil:
793 case llvm::Triple::arm:
794 case llvm::Triple::armeb:
795 case llvm::Triple::hexagon:
796 case llvm::Triple::le32:
797 case llvm::Triple::mips:
798 case llvm::Triple::mipsel:
799 case llvm::Triple::nvptx:
800 case llvm::Triple::ppc:
801 case llvm::Triple::r600:
802 case llvm::Triple::sparc:
803 case llvm::Triple::tce:
804 case llvm::Triple::thumb:
805 case llvm::Triple::thumbeb:
806 case llvm::Triple::x86:
807 case llvm::Triple::xcore:
808 case llvm::Triple::spir:
809 case llvm::Triple::kalimba:
810 return 32;
811
812 case llvm::Triple::arm64:
813 case llvm::Triple::arm64_be:
814 case llvm::Triple::aarch64:
815 case llvm::Triple::aarch64_be:
816 case llvm::Triple::mips64:
817 case llvm::Triple::mips64el:
818 case llvm::Triple::nvptx64:
819 case llvm::Triple::ppc64:
820 case llvm::Triple::ppc64le:
821 case llvm::Triple::sparcv9:
822 case llvm::Triple::systemz:
823 case llvm::Triple::x86_64:
824 case llvm::Triple::spir64:
825 return 64;
826 }
827 llvm_unreachable("Invalid architecture value");
828 }
829
isArch64Bit() const830 bool Triple::isArch64Bit() const {
831 return getArchPointerBitWidth(getArch()) == 64;
832 }
833
isArch32Bit() const834 bool Triple::isArch32Bit() const {
835 return getArchPointerBitWidth(getArch()) == 32;
836 }
837
isArch16Bit() const838 bool Triple::isArch16Bit() const {
839 return getArchPointerBitWidth(getArch()) == 16;
840 }
841
get32BitArchVariant() const842 Triple Triple::get32BitArchVariant() const {
843 Triple T(*this);
844 switch (getArch()) {
845 case Triple::UnknownArch:
846 case Triple::aarch64:
847 case Triple::aarch64_be:
848 case Triple::arm64:
849 case Triple::arm64_be:
850 case Triple::msp430:
851 case Triple::systemz:
852 case Triple::ppc64le:
853 T.setArch(UnknownArch);
854 break;
855
856 case Triple::amdil:
857 case Triple::spir:
858 case Triple::arm:
859 case Triple::armeb:
860 case Triple::hexagon:
861 case Triple::kalimba:
862 case Triple::le32:
863 case Triple::mips:
864 case Triple::mipsel:
865 case Triple::nvptx:
866 case Triple::ppc:
867 case Triple::r600:
868 case Triple::sparc:
869 case Triple::tce:
870 case Triple::thumb:
871 case Triple::thumbeb:
872 case Triple::x86:
873 case Triple::xcore:
874 // Already 32-bit.
875 break;
876
877 case Triple::mips64: T.setArch(Triple::mips); break;
878 case Triple::mips64el: T.setArch(Triple::mipsel); break;
879 case Triple::nvptx64: T.setArch(Triple::nvptx); break;
880 case Triple::ppc64: T.setArch(Triple::ppc); break;
881 case Triple::sparcv9: T.setArch(Triple::sparc); break;
882 case Triple::x86_64: T.setArch(Triple::x86); break;
883 case Triple::spir64: T.setArch(Triple::spir); break;
884 }
885 return T;
886 }
887
get64BitArchVariant() const888 Triple Triple::get64BitArchVariant() const {
889 Triple T(*this);
890 switch (getArch()) {
891 case Triple::UnknownArch:
892 case Triple::amdil:
893 case Triple::arm:
894 case Triple::armeb:
895 case Triple::hexagon:
896 case Triple::kalimba:
897 case Triple::le32:
898 case Triple::msp430:
899 case Triple::r600:
900 case Triple::tce:
901 case Triple::thumb:
902 case Triple::thumbeb:
903 case Triple::xcore:
904 T.setArch(UnknownArch);
905 break;
906
907 case Triple::aarch64:
908 case Triple::aarch64_be:
909 case Triple::spir64:
910 case Triple::mips64:
911 case Triple::mips64el:
912 case Triple::nvptx64:
913 case Triple::ppc64:
914 case Triple::ppc64le:
915 case Triple::sparcv9:
916 case Triple::systemz:
917 case Triple::x86_64:
918 case Triple::arm64:
919 case Triple::arm64_be:
920 // Already 64-bit.
921 break;
922
923 case Triple::mips: T.setArch(Triple::mips64); break;
924 case Triple::mipsel: T.setArch(Triple::mips64el); break;
925 case Triple::nvptx: T.setArch(Triple::nvptx64); break;
926 case Triple::ppc: T.setArch(Triple::ppc64); break;
927 case Triple::sparc: T.setArch(Triple::sparcv9); break;
928 case Triple::x86: T.setArch(Triple::x86_64); break;
929 case Triple::spir: T.setArch(Triple::spir64); break;
930 }
931 return T;
932 }
933