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 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";
58 }
59
60 llvm_unreachable("Invalid ArchType!");
61 }
62
getArchTypePrefix(ArchType Kind)63 const char *Triple::getArchTypePrefix(ArchType Kind) {
64 switch (Kind) {
65 default:
66 return nullptr;
67
68 case aarch64:
69 case aarch64_be: return "aarch64";
70
71 case arm:
72 case armeb:
73 case thumb:
74 case thumbeb: return "arm";
75
76 case ppc64:
77 case ppc64le:
78 case ppc: return "ppc";
79
80 case mips:
81 case mipsel:
82 case mips64:
83 case mips64el: return "mips";
84
85 case hexagon: return "hexagon";
86
87 case amdgcn:
88 case r600: return "amdgpu";
89
90 case bpf: return "bpf";
91
92 case sparcv9:
93 case sparc: return "sparc";
94
95 case systemz: return "s390";
96
97 case x86:
98 case x86_64: return "x86";
99
100 case xcore: return "xcore";
101
102 case nvptx: return "nvptx";
103 case nvptx64: return "nvptx";
104
105 case le32: return "le32";
106 case le64: return "le64";
107
108 case amdil:
109 case amdil64: return "amdil";
110
111 case hsail:
112 case hsail64: return "hsail";
113
114 case spir:
115 case spir64: return "spir";
116 case kalimba: return "kalimba";
117 }
118 }
119
getVendorTypeName(VendorType Kind)120 const char *Triple::getVendorTypeName(VendorType Kind) {
121 switch (Kind) {
122 case UnknownVendor: return "unknown";
123
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";
135 }
136
137 llvm_unreachable("Invalid VendorType!");
138 }
139
getOSTypeName(OSType Kind)140 const char *Triple::getOSTypeName(OSType Kind) {
141 switch (Kind) {
142 case UnknownOS: return "unknown";
143
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";
168 }
169
170 llvm_unreachable("Invalid OSType");
171 }
172
getEnvironmentTypeName(EnvironmentType Kind)173 const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
174 switch (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";
187 }
188
189 llvm_unreachable("Invalid EnvironmentType!");
190 }
191
getArchTypeForLLVMName(StringRef Name)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"
197 .Case("arm", arm)
198 .Case("armeb", armeb)
199 .Case("bpf", bpf)
200 .Case("mips", mips)
201 .Case("mipsel", mipsel)
202 .Case("mips64", mips64)
203 .Case("mips64el", mips64el)
204 .Case("msp430", msp430)
205 .Case("ppc64", ppc64)
206 .Case("ppc32", ppc)
207 .Case("ppc", ppc)
208 .Case("ppc64le", ppc64le)
209 .Case("r600", r600)
210 .Case("amdgcn", amdgcn)
211 .Case("hexagon", hexagon)
212 .Case("sparc", sparc)
213 .Case("sparcv9", sparcv9)
214 .Case("systemz", systemz)
215 .Case("tce", tce)
216 .Case("thumb", thumb)
217 .Case("thumbeb", thumbeb)
218 .Case("x86", x86)
219 .Case("x86-64", x86_64)
220 .Case("xcore", xcore)
221 .Case("nvptx", nvptx)
222 .Case("nvptx64", nvptx64)
223 .Case("le32", le32)
224 .Case("le64", le64)
225 .Case("amdil", amdil)
226 .Case("amdil64", amdil64)
227 .Case("hsail", hsail)
228 .Case("hsail64", hsail64)
229 .Case("spir", spir)
230 .Case("spir64", spir64)
231 .Case("kalimba", kalimba)
232 .Default(UnknownArch);
233 }
234
parseARMArch(StringRef ArchName)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");
239
240 if (ArchName.equals("arm"))
241 return Triple::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;
252
253 if (ArchName.startswith("armv")) {
254 offset = 3;
255 if (ArchName.endswith("eb")) {
256 arch = Triple::armeb;
257 ArchName = ArchName.substr(0, ArchName.size() - 2);
258 } else
259 arch = Triple::arm;
260 } else if (ArchName.startswith("armebv")) {
261 offset = 5;
262 arch = Triple::armeb;
263 } else if (ArchName.startswith("thumbv")) {
264 offset = 5;
265 if (ArchName.endswith("eb")) {
266 arch = Triple::thumbeb;
267 ArchName = ArchName.substr(0, ArchName.size() - 2);
268 } else
269 arch = Triple::thumb;
270 } else if (ArchName.startswith("thumbebv")) {
271 offset = 7;
272 arch = Triple::thumbeb;
273 }
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 .Cases("v8.1", "v8.1a", arch)
285 .Default(Triple::UnknownArch);
286 }
287
parseArch(StringRef ArchName)288 static Triple::ArchType parseArch(StringRef ArchName) {
289 Triple::ArchType ARMArch(parseARMArch(ArchName));
290
291 return StringSwitch<Triple::ArchType>(ArchName)
292 .Cases("i386", "i486", "i586", "i686", Triple::x86)
293 // FIXME: Do we need to support these?
294 .Cases("i786", "i886", "i986", Triple::x86)
295 .Cases("amd64", "x86_64", "x86_64h", Triple::x86_64)
296 .Case("powerpc", Triple::ppc)
297 .Cases("powerpc64", "ppu", Triple::ppc64)
298 .Case("powerpc64le", Triple::ppc64le)
299 .Case("xscale", Triple::arm)
300 .Case("xscaleeb", Triple::armeb)
301 .StartsWith("arm", ARMArch)
302 .StartsWith("thumb", ARMArch)
303 .StartsWith("aarch64", ARMArch)
304 .Case("msp430", Triple::msp430)
305 .Cases("mips", "mipseb", "mipsallegrex", Triple::mips)
306 .Cases("mipsel", "mipsallegrexel", Triple::mipsel)
307 .Cases("mips64", "mips64eb", Triple::mips64)
308 .Case("mips64el", Triple::mips64el)
309 .Case("r600", Triple::r600)
310 .Case("amdgcn", Triple::amdgcn)
311 .Case("bpf", Triple::bpf)
312 .Case("hexagon", Triple::hexagon)
313 .Case("s390x", Triple::systemz)
314 .Case("sparc", Triple::sparc)
315 .Cases("sparcv9", "sparc64", Triple::sparcv9)
316 .Case("tce", Triple::tce)
317 .Case("xcore", Triple::xcore)
318 .Case("nvptx", Triple::nvptx)
319 .Case("nvptx64", Triple::nvptx64)
320 .Case("le32", Triple::le32)
321 .Case("le64", Triple::le64)
322 .Case("amdil", Triple::amdil)
323 .Case("amdil64", Triple::amdil64)
324 .Case("hsail", Triple::hsail)
325 .Case("hsail64", Triple::hsail64)
326 .Case("spir", Triple::spir)
327 .Case("spir64", Triple::spir64)
328 .StartsWith("kalimba", Triple::kalimba)
329 .Default(Triple::UnknownArch);
330 }
331
parseVendor(StringRef VendorName)332 static Triple::VendorType parseVendor(StringRef VendorName) {
333 return StringSwitch<Triple::VendorType>(VendorName)
334 .Case("apple", Triple::Apple)
335 .Case("pc", Triple::PC)
336 .Case("scei", Triple::SCEI)
337 .Case("bgp", Triple::BGP)
338 .Case("bgq", Triple::BGQ)
339 .Case("fsl", Triple::Freescale)
340 .Case("ibm", Triple::IBM)
341 .Case("img", Triple::ImaginationTechnologies)
342 .Case("mti", Triple::MipsTechnologies)
343 .Case("nvidia", Triple::NVIDIA)
344 .Case("csr", Triple::CSR)
345 .Default(Triple::UnknownVendor);
346 }
347
parseOS(StringRef OSName)348 static Triple::OSType parseOS(StringRef OSName) {
349 return StringSwitch<Triple::OSType>(OSName)
350 .StartsWith("cloudabi", Triple::CloudABI)
351 .StartsWith("darwin", Triple::Darwin)
352 .StartsWith("dragonfly", Triple::DragonFly)
353 .StartsWith("freebsd", Triple::FreeBSD)
354 .StartsWith("ios", Triple::IOS)
355 .StartsWith("kfreebsd", Triple::KFreeBSD)
356 .StartsWith("linux", Triple::Linux)
357 .StartsWith("lv2", Triple::Lv2)
358 .StartsWith("macosx", Triple::MacOSX)
359 .StartsWith("netbsd", Triple::NetBSD)
360 .StartsWith("openbsd", Triple::OpenBSD)
361 .StartsWith("solaris", Triple::Solaris)
362 .StartsWith("win32", Triple::Win32)
363 .StartsWith("windows", Triple::Win32)
364 .StartsWith("haiku", Triple::Haiku)
365 .StartsWith("minix", Triple::Minix)
366 .StartsWith("rtems", Triple::RTEMS)
367 .StartsWith("nacl", Triple::NaCl)
368 .StartsWith("cnk", Triple::CNK)
369 .StartsWith("bitrig", Triple::Bitrig)
370 .StartsWith("aix", Triple::AIX)
371 .StartsWith("cuda", Triple::CUDA)
372 .StartsWith("nvcl", Triple::NVCL)
373 .StartsWith("amdhsa", Triple::AMDHSA)
374 .StartsWith("ps4", Triple::PS4)
375 .Default(Triple::UnknownOS);
376 }
377
parseEnvironment(StringRef EnvironmentName)378 static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) {
379 return StringSwitch<Triple::EnvironmentType>(EnvironmentName)
380 .StartsWith("eabihf", Triple::EABIHF)
381 .StartsWith("eabi", Triple::EABI)
382 .StartsWith("gnueabihf", Triple::GNUEABIHF)
383 .StartsWith("gnueabi", Triple::GNUEABI)
384 .StartsWith("gnux32", Triple::GNUX32)
385 .StartsWith("code16", Triple::CODE16)
386 .StartsWith("gnu", Triple::GNU)
387 .StartsWith("android", Triple::Android)
388 .StartsWith("msvc", Triple::MSVC)
389 .StartsWith("itanium", Triple::Itanium)
390 .StartsWith("cygnus", Triple::Cygnus)
391 .Default(Triple::UnknownEnvironment);
392 }
393
parseFormat(StringRef EnvironmentName)394 static Triple::ObjectFormatType parseFormat(StringRef EnvironmentName) {
395 return StringSwitch<Triple::ObjectFormatType>(EnvironmentName)
396 .EndsWith("coff", Triple::COFF)
397 .EndsWith("elf", Triple::ELF)
398 .EndsWith("macho", Triple::MachO)
399 .Default(Triple::UnknownObjectFormat);
400 }
401
parseSubArch(StringRef SubArchName)402 static Triple::SubArchType parseSubArch(StringRef SubArchName) {
403 if (SubArchName.endswith("eb"))
404 SubArchName = SubArchName.substr(0, SubArchName.size() - 2);
405
406 return StringSwitch<Triple::SubArchType>(SubArchName)
407 .EndsWith("v8.1a", Triple::ARMSubArch_v8_1a)
408 .EndsWith("v8", Triple::ARMSubArch_v8)
409 .EndsWith("v8a", Triple::ARMSubArch_v8)
410 .EndsWith("v7", Triple::ARMSubArch_v7)
411 .EndsWith("v7a", Triple::ARMSubArch_v7)
412 .EndsWith("v7em", Triple::ARMSubArch_v7em)
413 .EndsWith("v7l", Triple::ARMSubArch_v7)
414 .EndsWith("v7m", Triple::ARMSubArch_v7m)
415 .EndsWith("v7r", Triple::ARMSubArch_v7)
416 .EndsWith("v7s", Triple::ARMSubArch_v7s)
417 .EndsWith("v6", Triple::ARMSubArch_v6)
418 .EndsWith("v6m", Triple::ARMSubArch_v6m)
419 .EndsWith("v6sm", Triple::ARMSubArch_v6m)
420 .EndsWith("v6k", Triple::ARMSubArch_v6k)
421 .EndsWith("v6t2", Triple::ARMSubArch_v6t2)
422 .EndsWith("v5", Triple::ARMSubArch_v5)
423 .EndsWith("v5e", Triple::ARMSubArch_v5)
424 .EndsWith("v5t", Triple::ARMSubArch_v5)
425 .EndsWith("v5te", Triple::ARMSubArch_v5te)
426 .EndsWith("v4t", Triple::ARMSubArch_v4t)
427 .EndsWith("kalimba3", Triple::KalimbaSubArch_v3)
428 .EndsWith("kalimba4", Triple::KalimbaSubArch_v4)
429 .EndsWith("kalimba5", Triple::KalimbaSubArch_v5)
430 .Default(Triple::NoSubArch);
431 }
432
getObjectFormatTypeName(Triple::ObjectFormatType Kind)433 static const char *getObjectFormatTypeName(Triple::ObjectFormatType Kind) {
434 switch (Kind) {
435 case Triple::UnknownObjectFormat: return "";
436 case Triple::COFF: return "coff";
437 case Triple::ELF: return "elf";
438 case Triple::MachO: return "macho";
439 }
440 llvm_unreachable("unknown object format type");
441 }
442
getDefaultFormat(const Triple & T)443 static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
444 switch (T.getArch()) {
445 default:
446 break;
447 case Triple::hexagon:
448 case Triple::mips:
449 case Triple::mipsel:
450 case Triple::mips64:
451 case Triple::mips64el:
452 case Triple::r600:
453 case Triple::amdgcn:
454 case Triple::sparc:
455 case Triple::sparcv9:
456 case Triple::systemz:
457 case Triple::xcore:
458 case Triple::ppc64le:
459 return Triple::ELF;
460
461 case Triple::ppc:
462 case Triple::ppc64:
463 if (T.isOSDarwin())
464 return Triple::MachO;
465 return Triple::ELF;
466 }
467
468 if (T.isOSDarwin())
469 return Triple::MachO;
470 else if (T.isOSWindows())
471 return Triple::COFF;
472 return Triple::ELF;
473 }
474
475 /// \brief Construct a triple from the string representation provided.
476 ///
477 /// This stores the string representation and parses the various pieces into
478 /// enum members.
Triple(const Twine & Str)479 Triple::Triple(const Twine &Str)
480 : Data(Str.str()),
481 Arch(parseArch(getArchName())),
482 SubArch(parseSubArch(getArchName())),
483 Vendor(parseVendor(getVendorName())),
484 OS(parseOS(getOSName())),
485 Environment(parseEnvironment(getEnvironmentName())),
486 ObjectFormat(parseFormat(getEnvironmentName())) {
487 if (ObjectFormat == Triple::UnknownObjectFormat)
488 ObjectFormat = getDefaultFormat(*this);
489 }
490
491 /// \brief Construct a triple from string representations of the architecture,
492 /// vendor, and OS.
493 ///
494 /// This joins each argument into a canonical string representation and parses
495 /// them into enum members. It leaves the environment unknown and omits it from
496 /// the string representation.
Triple(const Twine & ArchStr,const Twine & VendorStr,const Twine & OSStr)497 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr)
498 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()),
499 Arch(parseArch(ArchStr.str())),
500 SubArch(parseSubArch(ArchStr.str())),
501 Vendor(parseVendor(VendorStr.str())),
502 OS(parseOS(OSStr.str())),
503 Environment(), ObjectFormat(Triple::UnknownObjectFormat) {
504 ObjectFormat = getDefaultFormat(*this);
505 }
506
507 /// \brief Construct a triple from string representations of the architecture,
508 /// vendor, OS, and environment.
509 ///
510 /// This joins each argument into a canonical string representation and parses
511 /// them into enum members.
Triple(const Twine & ArchStr,const Twine & VendorStr,const Twine & OSStr,const Twine & EnvironmentStr)512 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr,
513 const Twine &EnvironmentStr)
514 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr + Twine('-') +
515 EnvironmentStr).str()),
516 Arch(parseArch(ArchStr.str())),
517 SubArch(parseSubArch(ArchStr.str())),
518 Vendor(parseVendor(VendorStr.str())),
519 OS(parseOS(OSStr.str())),
520 Environment(parseEnvironment(EnvironmentStr.str())),
521 ObjectFormat(parseFormat(EnvironmentStr.str())) {
522 if (ObjectFormat == Triple::UnknownObjectFormat)
523 ObjectFormat = getDefaultFormat(*this);
524 }
525
normalize(StringRef Str)526 std::string Triple::normalize(StringRef Str) {
527 bool IsMinGW32 = false;
528 bool IsCygwin = false;
529
530 // Parse into components.
531 SmallVector<StringRef, 4> Components;
532 Str.split(Components, "-");
533
534 // If the first component corresponds to a known architecture, preferentially
535 // use it for the architecture. If the second component corresponds to a
536 // known vendor, preferentially use it for the vendor, etc. This avoids silly
537 // component movement when a component parses as (eg) both a valid arch and a
538 // valid os.
539 ArchType Arch = UnknownArch;
540 if (Components.size() > 0)
541 Arch = parseArch(Components[0]);
542 VendorType Vendor = UnknownVendor;
543 if (Components.size() > 1)
544 Vendor = parseVendor(Components[1]);
545 OSType OS = UnknownOS;
546 if (Components.size() > 2) {
547 OS = parseOS(Components[2]);
548 IsCygwin = Components[2].startswith("cygwin");
549 IsMinGW32 = Components[2].startswith("mingw");
550 }
551 EnvironmentType Environment = UnknownEnvironment;
552 if (Components.size() > 3)
553 Environment = parseEnvironment(Components[3]);
554 ObjectFormatType ObjectFormat = UnknownObjectFormat;
555 if (Components.size() > 4)
556 ObjectFormat = parseFormat(Components[4]);
557
558 // Note which components are already in their final position. These will not
559 // be moved.
560 bool Found[4];
561 Found[0] = Arch != UnknownArch;
562 Found[1] = Vendor != UnknownVendor;
563 Found[2] = OS != UnknownOS;
564 Found[3] = Environment != UnknownEnvironment;
565
566 // If they are not there already, permute the components into their canonical
567 // positions by seeing if they parse as a valid architecture, and if so moving
568 // the component to the architecture position etc.
569 for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) {
570 if (Found[Pos])
571 continue; // Already in the canonical position.
572
573 for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
574 // Do not reparse any components that already matched.
575 if (Idx < array_lengthof(Found) && Found[Idx])
576 continue;
577
578 // Does this component parse as valid for the target position?
579 bool Valid = false;
580 StringRef Comp = Components[Idx];
581 switch (Pos) {
582 default: llvm_unreachable("unexpected component type!");
583 case 0:
584 Arch = parseArch(Comp);
585 Valid = Arch != UnknownArch;
586 break;
587 case 1:
588 Vendor = parseVendor(Comp);
589 Valid = Vendor != UnknownVendor;
590 break;
591 case 2:
592 OS = parseOS(Comp);
593 IsCygwin = Comp.startswith("cygwin");
594 IsMinGW32 = Comp.startswith("mingw");
595 Valid = OS != UnknownOS || IsCygwin || IsMinGW32;
596 break;
597 case 3:
598 Environment = parseEnvironment(Comp);
599 Valid = Environment != UnknownEnvironment;
600 if (!Valid) {
601 ObjectFormat = parseFormat(Comp);
602 Valid = ObjectFormat != UnknownObjectFormat;
603 }
604 break;
605 }
606 if (!Valid)
607 continue; // Nope, try the next component.
608
609 // Move the component to the target position, pushing any non-fixed
610 // components that are in the way to the right. This tends to give
611 // good results in the common cases of a forgotten vendor component
612 // or a wrongly positioned environment.
613 if (Pos < Idx) {
614 // Insert left, pushing the existing components to the right. For
615 // example, a-b-i386 -> i386-a-b when moving i386 to the front.
616 StringRef CurrentComponent(""); // The empty component.
617 // Replace the component we are moving with an empty component.
618 std::swap(CurrentComponent, Components[Idx]);
619 // Insert the component being moved at Pos, displacing any existing
620 // components to the right.
621 for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
622 // Skip over any fixed components.
623 while (i < array_lengthof(Found) && Found[i])
624 ++i;
625 // Place the component at the new position, getting the component
626 // that was at this position - it will be moved right.
627 std::swap(CurrentComponent, Components[i]);
628 }
629 } else if (Pos > Idx) {
630 // Push right by inserting empty components until the component at Idx
631 // reaches the target position Pos. For example, pc-a -> -pc-a when
632 // moving pc to the second position.
633 do {
634 // Insert one empty component at Idx.
635 StringRef CurrentComponent(""); // The empty component.
636 for (unsigned i = Idx; i < Components.size();) {
637 // Place the component at the new position, getting the component
638 // that was at this position - it will be moved right.
639 std::swap(CurrentComponent, Components[i]);
640 // If it was placed on top of an empty component then we are done.
641 if (CurrentComponent.empty())
642 break;
643 // Advance to the next component, skipping any fixed components.
644 while (++i < array_lengthof(Found) && Found[i])
645 ;
646 }
647 // The last component was pushed off the end - append it.
648 if (!CurrentComponent.empty())
649 Components.push_back(CurrentComponent);
650
651 // Advance Idx to the component's new position.
652 while (++Idx < array_lengthof(Found) && Found[Idx])
653 ;
654 } while (Idx < Pos); // Add more until the final position is reached.
655 }
656 assert(Pos < Components.size() && Components[Pos] == Comp &&
657 "Component moved wrong!");
658 Found[Pos] = true;
659 break;
660 }
661 }
662
663 // Special case logic goes here. At this point Arch, Vendor and OS have the
664 // correct values for the computed components.
665
666 if (OS == Triple::Win32) {
667 Components.resize(4);
668 Components[2] = "windows";
669 if (Environment == UnknownEnvironment) {
670 if (ObjectFormat == UnknownObjectFormat || ObjectFormat == Triple::COFF)
671 Components[3] = "msvc";
672 else
673 Components[3] = getObjectFormatTypeName(ObjectFormat);
674 }
675 } else if (IsMinGW32) {
676 Components.resize(4);
677 Components[2] = "windows";
678 Components[3] = "gnu";
679 } else if (IsCygwin) {
680 Components.resize(4);
681 Components[2] = "windows";
682 Components[3] = "cygnus";
683 }
684 if (IsMinGW32 || IsCygwin ||
685 (OS == Triple::Win32 && Environment != UnknownEnvironment)) {
686 if (ObjectFormat != UnknownObjectFormat && ObjectFormat != Triple::COFF) {
687 Components.resize(5);
688 Components[4] = getObjectFormatTypeName(ObjectFormat);
689 }
690 }
691
692 // Stick the corrected components back together to form the normalized string.
693 std::string Normalized;
694 for (unsigned i = 0, e = Components.size(); i != e; ++i) {
695 if (i) Normalized += '-';
696 Normalized += Components[i];
697 }
698 return Normalized;
699 }
700
getArchName() const701 StringRef Triple::getArchName() const {
702 return StringRef(Data).split('-').first; // Isolate first component
703 }
704
getVendorName() const705 StringRef Triple::getVendorName() const {
706 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
707 return Tmp.split('-').first; // Isolate second component
708 }
709
getOSName() const710 StringRef Triple::getOSName() const {
711 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
712 Tmp = Tmp.split('-').second; // Strip second component
713 return Tmp.split('-').first; // Isolate third component
714 }
715
getEnvironmentName() const716 StringRef Triple::getEnvironmentName() const {
717 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
718 Tmp = Tmp.split('-').second; // Strip second component
719 return Tmp.split('-').second; // Strip third component
720 }
721
getOSAndEnvironmentName() const722 StringRef Triple::getOSAndEnvironmentName() const {
723 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
724 return Tmp.split('-').second; // Strip second component
725 }
726
EatNumber(StringRef & Str)727 static unsigned EatNumber(StringRef &Str) {
728 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
729 unsigned Result = 0;
730
731 do {
732 // Consume the leading digit.
733 Result = Result*10 + (Str[0] - '0');
734
735 // Eat the digit.
736 Str = Str.substr(1);
737 } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9');
738
739 return Result;
740 }
741
getOSVersion(unsigned & Major,unsigned & Minor,unsigned & Micro) const742 void Triple::getOSVersion(unsigned &Major, unsigned &Minor,
743 unsigned &Micro) const {
744 StringRef OSName = getOSName();
745
746 // For Android, we care about the Android version rather than the Linux
747 // version.
748 if (getEnvironment() == Android) {
749 OSName = getEnvironmentName().substr(strlen("android"));
750 if (OSName.startswith("eabi"))
751 OSName = OSName.substr(strlen("eabi"));
752 }
753
754 // Assume that the OS portion of the triple starts with the canonical name.
755 StringRef OSTypeName = getOSTypeName(getOS());
756 if (OSName.startswith(OSTypeName))
757 OSName = OSName.substr(OSTypeName.size());
758
759 // Any unset version defaults to 0.
760 Major = Minor = Micro = 0;
761
762 // Parse up to three components.
763 unsigned *Components[3] = { &Major, &Minor, &Micro };
764 for (unsigned i = 0; i != 3; ++i) {
765 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
766 break;
767
768 // Consume the leading number.
769 *Components[i] = EatNumber(OSName);
770
771 // Consume the separator, if present.
772 if (OSName.startswith("."))
773 OSName = OSName.substr(1);
774 }
775 }
776
getMacOSXVersion(unsigned & Major,unsigned & Minor,unsigned & Micro) const777 bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor,
778 unsigned &Micro) const {
779 getOSVersion(Major, Minor, Micro);
780
781 switch (getOS()) {
782 default: llvm_unreachable("unexpected OS for Darwin triple");
783 case Darwin:
784 // Default to darwin8, i.e., MacOSX 10.4.
785 if (Major == 0)
786 Major = 8;
787 // Darwin version numbers are skewed from OS X versions.
788 if (Major < 4)
789 return false;
790 Micro = 0;
791 Minor = Major - 4;
792 Major = 10;
793 break;
794 case MacOSX:
795 // Default to 10.4.
796 if (Major == 0) {
797 Major = 10;
798 Minor = 4;
799 }
800 if (Major != 10)
801 return false;
802 break;
803 case IOS:
804 // Ignore the version from the triple. This is only handled because the
805 // the clang driver combines OS X and IOS support into a common Darwin
806 // toolchain that wants to know the OS X version number even when targeting
807 // IOS.
808 Major = 10;
809 Minor = 4;
810 Micro = 0;
811 break;
812 }
813 return true;
814 }
815
getiOSVersion(unsigned & Major,unsigned & Minor,unsigned & Micro) const816 void Triple::getiOSVersion(unsigned &Major, unsigned &Minor,
817 unsigned &Micro) const {
818 switch (getOS()) {
819 default: llvm_unreachable("unexpected OS for Darwin triple");
820 case Darwin:
821 case MacOSX:
822 // Ignore the version from the triple. This is only handled because the
823 // the clang driver combines OS X and IOS support into a common Darwin
824 // toolchain that wants to know the iOS version number even when targeting
825 // OS X.
826 Major = 5;
827 Minor = 0;
828 Micro = 0;
829 break;
830 case IOS:
831 getOSVersion(Major, Minor, Micro);
832 // Default to 5.0 (or 7.0 for arm64).
833 if (Major == 0)
834 Major = (getArch() == aarch64) ? 7 : 5;
835 break;
836 }
837 }
838
setTriple(const Twine & Str)839 void Triple::setTriple(const Twine &Str) {
840 *this = Triple(Str);
841 }
842
setArch(ArchType Kind)843 void Triple::setArch(ArchType Kind) {
844 setArchName(getArchTypeName(Kind));
845 }
846
setVendor(VendorType Kind)847 void Triple::setVendor(VendorType Kind) {
848 setVendorName(getVendorTypeName(Kind));
849 }
850
setOS(OSType Kind)851 void Triple::setOS(OSType Kind) {
852 setOSName(getOSTypeName(Kind));
853 }
854
setEnvironment(EnvironmentType Kind)855 void Triple::setEnvironment(EnvironmentType Kind) {
856 if (ObjectFormat == getDefaultFormat(*this))
857 return setEnvironmentName(getEnvironmentTypeName(Kind));
858
859 setEnvironmentName((getEnvironmentTypeName(Kind) + Twine("-") +
860 getObjectFormatTypeName(ObjectFormat)).str());
861 }
862
setObjectFormat(ObjectFormatType Kind)863 void Triple::setObjectFormat(ObjectFormatType Kind) {
864 if (Environment == UnknownEnvironment)
865 return setEnvironmentName(getObjectFormatTypeName(Kind));
866
867 setEnvironmentName((getEnvironmentTypeName(Environment) + Twine("-") +
868 getObjectFormatTypeName(Kind)).str());
869 }
870
setArchName(StringRef Str)871 void Triple::setArchName(StringRef Str) {
872 // Work around a miscompilation bug for Twines in gcc 4.0.3.
873 SmallString<64> Triple;
874 Triple += Str;
875 Triple += "-";
876 Triple += getVendorName();
877 Triple += "-";
878 Triple += getOSAndEnvironmentName();
879 setTriple(Triple);
880 }
881
setVendorName(StringRef Str)882 void Triple::setVendorName(StringRef Str) {
883 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
884 }
885
setOSName(StringRef Str)886 void Triple::setOSName(StringRef Str) {
887 if (hasEnvironment())
888 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
889 "-" + getEnvironmentName());
890 else
891 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
892 }
893
setEnvironmentName(StringRef Str)894 void Triple::setEnvironmentName(StringRef Str) {
895 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
896 "-" + Str);
897 }
898
setOSAndEnvironmentName(StringRef Str)899 void Triple::setOSAndEnvironmentName(StringRef Str) {
900 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
901 }
902
getArchPointerBitWidth(llvm::Triple::ArchType Arch)903 static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
904 switch (Arch) {
905 case llvm::Triple::UnknownArch:
906 return 0;
907
908 case llvm::Triple::msp430:
909 return 16;
910
911 case llvm::Triple::arm:
912 case llvm::Triple::armeb:
913 case llvm::Triple::hexagon:
914 case llvm::Triple::le32:
915 case llvm::Triple::mips:
916 case llvm::Triple::mipsel:
917 case llvm::Triple::nvptx:
918 case llvm::Triple::ppc:
919 case llvm::Triple::r600:
920 case llvm::Triple::sparc:
921 case llvm::Triple::tce:
922 case llvm::Triple::thumb:
923 case llvm::Triple::thumbeb:
924 case llvm::Triple::x86:
925 case llvm::Triple::xcore:
926 case llvm::Triple::amdil:
927 case llvm::Triple::hsail:
928 case llvm::Triple::spir:
929 case llvm::Triple::kalimba:
930 return 32;
931
932 case llvm::Triple::aarch64:
933 case llvm::Triple::aarch64_be:
934 case llvm::Triple::amdgcn:
935 case llvm::Triple::bpf:
936 case llvm::Triple::le64:
937 case llvm::Triple::mips64:
938 case llvm::Triple::mips64el:
939 case llvm::Triple::nvptx64:
940 case llvm::Triple::ppc64:
941 case llvm::Triple::ppc64le:
942 case llvm::Triple::sparcv9:
943 case llvm::Triple::systemz:
944 case llvm::Triple::x86_64:
945 case llvm::Triple::amdil64:
946 case llvm::Triple::hsail64:
947 case llvm::Triple::spir64:
948 return 64;
949 }
950 llvm_unreachable("Invalid architecture value");
951 }
952
isArch64Bit() const953 bool Triple::isArch64Bit() const {
954 return getArchPointerBitWidth(getArch()) == 64;
955 }
956
isArch32Bit() const957 bool Triple::isArch32Bit() const {
958 return getArchPointerBitWidth(getArch()) == 32;
959 }
960
isArch16Bit() const961 bool Triple::isArch16Bit() const {
962 return getArchPointerBitWidth(getArch()) == 16;
963 }
964
get32BitArchVariant() const965 Triple Triple::get32BitArchVariant() const {
966 Triple T(*this);
967 switch (getArch()) {
968 case Triple::UnknownArch:
969 case Triple::aarch64:
970 case Triple::aarch64_be:
971 case Triple::amdgcn:
972 case Triple::bpf:
973 case Triple::msp430:
974 case Triple::systemz:
975 case Triple::ppc64le:
976 T.setArch(UnknownArch);
977 break;
978
979 case Triple::amdil:
980 case Triple::hsail:
981 case Triple::spir:
982 case Triple::arm:
983 case Triple::armeb:
984 case Triple::hexagon:
985 case Triple::kalimba:
986 case Triple::le32:
987 case Triple::mips:
988 case Triple::mipsel:
989 case Triple::nvptx:
990 case Triple::ppc:
991 case Triple::r600:
992 case Triple::sparc:
993 case Triple::tce:
994 case Triple::thumb:
995 case Triple::thumbeb:
996 case Triple::x86:
997 case Triple::xcore:
998 // Already 32-bit.
999 break;
1000
1001 case Triple::le64: T.setArch(Triple::le32); break;
1002 case Triple::mips64: T.setArch(Triple::mips); break;
1003 case Triple::mips64el: T.setArch(Triple::mipsel); break;
1004 case Triple::nvptx64: T.setArch(Triple::nvptx); break;
1005 case Triple::ppc64: T.setArch(Triple::ppc); break;
1006 case Triple::sparcv9: T.setArch(Triple::sparc); break;
1007 case Triple::x86_64: T.setArch(Triple::x86); break;
1008 case Triple::amdil64: T.setArch(Triple::amdil); break;
1009 case Triple::hsail64: T.setArch(Triple::hsail); break;
1010 case Triple::spir64: T.setArch(Triple::spir); break;
1011 }
1012 return T;
1013 }
1014
get64BitArchVariant() const1015 Triple Triple::get64BitArchVariant() const {
1016 Triple T(*this);
1017 switch (getArch()) {
1018 case Triple::UnknownArch:
1019 case Triple::arm:
1020 case Triple::armeb:
1021 case Triple::hexagon:
1022 case Triple::kalimba:
1023 case Triple::msp430:
1024 case Triple::r600:
1025 case Triple::tce:
1026 case Triple::thumb:
1027 case Triple::thumbeb:
1028 case Triple::xcore:
1029 T.setArch(UnknownArch);
1030 break;
1031
1032 case Triple::aarch64:
1033 case Triple::aarch64_be:
1034 case Triple::bpf:
1035 case Triple::le64:
1036 case Triple::amdil64:
1037 case Triple::amdgcn:
1038 case Triple::hsail64:
1039 case Triple::spir64:
1040 case Triple::mips64:
1041 case Triple::mips64el:
1042 case Triple::nvptx64:
1043 case Triple::ppc64:
1044 case Triple::ppc64le:
1045 case Triple::sparcv9:
1046 case Triple::systemz:
1047 case Triple::x86_64:
1048 // Already 64-bit.
1049 break;
1050
1051 case Triple::le32: T.setArch(Triple::le64); break;
1052 case Triple::mips: T.setArch(Triple::mips64); break;
1053 case Triple::mipsel: T.setArch(Triple::mips64el); break;
1054 case Triple::nvptx: T.setArch(Triple::nvptx64); break;
1055 case Triple::ppc: T.setArch(Triple::ppc64); break;
1056 case Triple::sparc: T.setArch(Triple::sparcv9); break;
1057 case Triple::x86: T.setArch(Triple::x86_64); break;
1058 case Triple::amdil: T.setArch(Triple::amdil64); break;
1059 case Triple::hsail: T.setArch(Triple::hsail64); break;
1060 case Triple::spir: T.setArch(Triple::spir64); break;
1061 }
1062 return T;
1063 }
1064
1065 // FIXME: tblgen this.
getARMCPUForArch(StringRef MArch) const1066 const char *Triple::getARMCPUForArch(StringRef MArch) const {
1067 if (MArch.empty())
1068 MArch = getArchName();
1069
1070 switch (getOS()) {
1071 case llvm::Triple::FreeBSD:
1072 case llvm::Triple::NetBSD:
1073 if (MArch == "armv6")
1074 return "arm1176jzf-s";
1075 break;
1076 case llvm::Triple::Win32:
1077 // FIXME: this is invalid for WindowsCE
1078 return "cortex-a9";
1079 default:
1080 break;
1081 }
1082
1083 const char *result = nullptr;
1084 size_t offset = StringRef::npos;
1085 if (MArch.startswith("arm"))
1086 offset = 3;
1087 if (MArch.startswith("thumb"))
1088 offset = 5;
1089 if (offset != StringRef::npos && MArch.substr(offset, 2) == "eb")
1090 offset += 2;
1091 if (MArch.endswith("eb"))
1092 MArch = MArch.substr(0, MArch.size() - 2);
1093 if (offset != StringRef::npos)
1094 result = llvm::StringSwitch<const char *>(MArch.substr(offset))
1095 .Cases("v2", "v2a", "arm2")
1096 .Case("v3", "arm6")
1097 .Case("v3m", "arm7m")
1098 .Case("v4", "strongarm")
1099 .Case("v4t", "arm7tdmi")
1100 .Cases("v5", "v5t", "arm10tdmi")
1101 .Cases("v5e", "v5te", "arm1022e")
1102 .Case("v5tej", "arm926ej-s")
1103 .Case("v6", "arm1136jf-s")
1104 .Case("v6j", "arm1136j-s")
1105 .Cases("v6k", "v6z", "v6zk", "arm1176jzf-s")
1106 .Case("v6t2", "arm1156t2-s")
1107 .Cases("v6m", "v6-m", "v6sm", "v6s-m", "cortex-m0")
1108 .Cases("v7", "v7a", "v7-a", "v7l", "v7-l", "cortex-a8")
1109 .Cases("v7s", "v7-s", "swift")
1110 .Cases("v7r", "v7-r", "cortex-r4")
1111 .Cases("v7m", "v7-m", "cortex-m3")
1112 .Cases("v7em", "v7e-m", "cortex-m4")
1113 .Cases("v8", "v8a", "v8-a", "cortex-a53")
1114 .Cases("v8.1a", "v8.1-a", "generic")
1115 .Default(nullptr);
1116 else
1117 result = llvm::StringSwitch<const char *>(MArch)
1118 .Case("ep9312", "ep9312")
1119 .Case("iwmmxt", "iwmmxt")
1120 .Case("xscale", "xscale")
1121 .Default(nullptr);
1122
1123 if (result)
1124 return result;
1125
1126 // If all else failed, return the most base CPU with thumb interworking
1127 // supported by LLVM.
1128 // FIXME: Should warn once that we're falling back.
1129 switch (getOS()) {
1130 case llvm::Triple::NetBSD:
1131 switch (getEnvironment()) {
1132 case llvm::Triple::GNUEABIHF:
1133 case llvm::Triple::GNUEABI:
1134 case llvm::Triple::EABIHF:
1135 case llvm::Triple::EABI:
1136 return "arm926ej-s";
1137 default:
1138 return "strongarm";
1139 }
1140 case llvm::Triple::NaCl:
1141 return "cortex-a8";
1142 default:
1143 switch (getEnvironment()) {
1144 case llvm::Triple::EABIHF:
1145 case llvm::Triple::GNUEABIHF:
1146 return "arm1176jzf-s";
1147 default:
1148 return "arm7tdmi";
1149 }
1150 }
1151 }
1152