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