1 //===--- Triple.cpp - Target triple helper class --------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/ADT/Triple.h"
12 #include "llvm/ADT/SmallString.h"
13 #include "llvm/ADT/Twine.h"
20 const char *Triple::getArchTypeName(ArchType Kind) {
22 case InvalidArch: return "<invalid>";
23 case UnknownArch: return "unknown";
25 case alpha: return "alpha";
26 case arm: return "arm";
27 case bfin: return "bfin";
28 case cellspu: return "cellspu";
29 case mips: return "mips";
30 case mipsel: return "mipsel";
31 case msp430: return "msp430";
32 case pic16: return "pic16";
33 case ppc64: return "powerpc64";
34 case ppc: return "powerpc";
35 case sparc: return "sparc";
36 case sparcv9: return "sparcv9";
37 case systemz: return "s390x";
38 case tce: return "tce";
39 case thumb: return "thumb";
40 case x86: return "i386";
41 case x86_64: return "x86_64";
42 case xcore: return "xcore";
43 case mblaze: return "mblaze";
49 const char *Triple::getArchTypePrefix(ArchType Kind) {
54 case alpha: return "alpha";
57 case thumb: return "arm";
59 case bfin: return "bfin";
61 case cellspu: return "spu";
64 case ppc: return "ppc";
66 case mblaze: return "mblaze";
69 case sparc: return "sparc";
72 case x86_64: return "x86";
73 case xcore: return "xcore";
77 const char *Triple::getVendorTypeName(VendorType Kind) {
79 case UnknownVendor: return "unknown";
81 case Apple: return "apple";
88 const char *Triple::getOSTypeName(OSType Kind) {
90 case UnknownOS: return "unknown";
92 case AuroraUX: return "auroraux";
93 case Cygwin: return "cygwin";
94 case Darwin: return "darwin";
95 case DragonFly: return "dragonfly";
96 case FreeBSD: return "freebsd";
97 case Linux: return "linux";
98 case Lv2: return "lv2";
99 case MinGW32: return "mingw32";
100 case MinGW64: return "mingw64";
101 case NetBSD: return "netbsd";
102 case OpenBSD: return "openbsd";
103 case Psp: return "psp";
104 case Solaris: return "solaris";
105 case Win32: return "win32";
106 case Haiku: return "haiku";
112 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
119 if (Name == "cellspu")
123 if (Name == "mipsel")
125 if (Name == "msp430")
133 if (Name == "mblaze")
137 if (Name == "sparcv9")
139 if (Name == "systemz")
147 if (Name == "x86-64")
155 Triple::ArchType Triple::getArchTypeForDarwinArchName(StringRef Str) {
156 // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
157 // archs which Darwin doesn't use.
159 // The matching this routine does is fairly pointless, since it is neither the
160 // complete architecture list, nor a reasonable subset. The problem is that
161 // historically the driver driver accepts this and also ties its -march=
162 // handling to the architecture name, so we need to be careful before removing
165 // This code must be kept in sync with Clang's Darwin specific argument
168 if (Str == "ppc" || Str == "ppc601" || Str == "ppc603" || Str == "ppc604" ||
169 Str == "ppc604e" || Str == "ppc750" || Str == "ppc7400" ||
170 Str == "ppc7450" || Str == "ppc970")
174 return Triple::ppc64;
176 if (Str == "i386" || Str == "i486" || Str == "i486SX" || Str == "pentium" ||
177 Str == "i586" || Str == "pentpro" || Str == "i686" || Str == "pentIIm3" ||
178 Str == "pentIIm5" || Str == "pentium4")
182 return Triple::x86_64;
184 // This is derived from the driver driver.
185 if (Str == "arm" || Str == "armv4t" || Str == "armv5" || Str == "xscale" ||
186 Str == "armv6" || Str == "armv7")
189 return Triple::UnknownArch;
192 // Returns architecture name that is understood by the target assembler.
193 const char *Triple::getArchNameForAssembler() {
194 if (getOS() != Triple::Darwin && getVendor() != Triple::Apple)
197 StringRef Str = getArchName();
202 if (Str == "powerpc")
204 if (Str == "powerpc64")
206 if (Str == "mblaze" || Str == "microblaze")
210 if (Str == "armv4t" || Str == "thumbv4t")
212 if (Str == "armv5" || Str == "armv5e" || Str == "thumbv5" || Str == "thumbv5e")
214 if (Str == "armv6" || Str == "thumbv6")
216 if (Str == "armv7" || Str == "thumbv7")
223 void Triple::Parse() const {
224 assert(!isInitialized() && "Invalid parse call.");
226 StringRef ArchName = getArchName();
227 StringRef VendorName = getVendorName();
228 StringRef OSName = getOSName();
230 if (ArchName.size() == 4 && ArchName[0] == 'i' &&
231 ArchName[2] == '8' && ArchName[3] == '6' &&
232 ArchName[1] - '3' < 6) // i[3-9]86
234 else if (ArchName == "amd64" || ArchName == "x86_64")
236 else if (ArchName == "bfin")
238 else if (ArchName == "pic16")
240 else if (ArchName == "powerpc")
242 else if ((ArchName == "powerpc64") || (ArchName == "ppu"))
244 else if (ArchName == "mblaze")
246 else if (ArchName == "arm" ||
247 ArchName.startswith("armv") ||
248 ArchName == "xscale")
250 else if (ArchName == "thumb" ||
251 ArchName.startswith("thumbv"))
253 else if (ArchName.startswith("alpha"))
255 else if (ArchName == "spu" || ArchName == "cellspu")
257 else if (ArchName == "msp430")
259 else if (ArchName == "mips" || ArchName == "mipsallegrex")
261 else if (ArchName == "mipsel" || ArchName == "mipsallegrexel" ||
264 else if (ArchName == "sparc")
266 else if (ArchName == "sparcv9")
268 else if (ArchName == "s390x")
270 else if (ArchName == "tce")
272 else if (ArchName == "xcore")
278 // Handle some exceptional cases where the OS / environment components are
279 // stuck into the vendor field.
280 if (StringRef(getTriple()).count('-') == 1) {
281 StringRef VendorName = getVendorName();
283 if (VendorName.startswith("mingw32")) { // 'i386-mingw32', etc.
289 // arm-elf is another example, but we don't currently parse anything about
293 if (VendorName == "apple")
295 else if (VendorName == "pc")
298 Vendor = UnknownVendor;
300 if (OSName.startswith("auroraux"))
302 else if (OSName.startswith("cygwin"))
304 else if (OSName.startswith("darwin"))
306 else if (OSName.startswith("dragonfly"))
308 else if (OSName.startswith("freebsd"))
310 else if (OSName.startswith("linux"))
312 else if (OSName.startswith("lv2"))
314 else if (OSName.startswith("mingw32"))
316 else if (OSName.startswith("mingw64"))
318 else if (OSName.startswith("netbsd"))
320 else if (OSName.startswith("openbsd"))
322 else if (OSName.startswith("psp"))
324 else if (OSName.startswith("solaris"))
326 else if (OSName.startswith("win32"))
328 else if (OSName.startswith("haiku"))
333 assert(isInitialized() && "Failed to initialize!");
336 StringRef Triple::getArchName() const {
337 return StringRef(Data).split('-').first; // Isolate first component
340 StringRef Triple::getVendorName() const {
341 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
342 return Tmp.split('-').first; // Isolate second component
345 StringRef Triple::getOSName() const {
346 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
347 Tmp = Tmp.split('-').second; // Strip second component
348 return Tmp.split('-').first; // Isolate third component
351 StringRef Triple::getEnvironmentName() const {
352 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
353 Tmp = Tmp.split('-').second; // Strip second component
354 return Tmp.split('-').second; // Strip third component
357 StringRef Triple::getOSAndEnvironmentName() const {
358 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
359 return Tmp.split('-').second; // Strip second component
362 static unsigned EatNumber(StringRef &Str) {
363 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
364 unsigned Result = Str[0]-'0';
369 // Handle "darwin11".
370 if (Result == 1 && !Str.empty() && Str[0] >= '0' && Str[0] <= '9') {
371 Result = Result*10 + (Str[0] - '0');
379 /// getDarwinNumber - Parse the 'darwin number' out of the specific target
380 /// triple. For example, if we have darwin8.5 return 8,5,0. If any entry is
381 /// not defined, return 0's. This requires that the triple have an OSType of
382 /// darwin before it is called.
383 void Triple::getDarwinNumber(unsigned &Maj, unsigned &Min,
384 unsigned &Revision) const {
385 assert(getOS() == Darwin && "Not a darwin target triple!");
386 StringRef OSName = getOSName();
387 assert(OSName.startswith("darwin") && "Unknown darwin target triple!");
389 // Strip off "darwin".
390 OSName = OSName.substr(6);
392 Maj = Min = Revision = 0;
394 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
397 // The major version is the first digit.
398 Maj = EatNumber(OSName);
399 if (OSName.empty()) return;
401 // Handle minor version: 10.4.9 -> darwin8.9.
402 if (OSName[0] != '.')
406 OSName = OSName.substr(1);
408 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
411 Min = EatNumber(OSName);
412 if (OSName.empty()) return;
414 // Handle revision darwin8.9.1
415 if (OSName[0] != '.')
419 OSName = OSName.substr(1);
421 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
424 Revision = EatNumber(OSName);
427 void Triple::setTriple(const Twine &Str) {
432 void Triple::setArch(ArchType Kind) {
433 setArchName(getArchTypeName(Kind));
436 void Triple::setVendor(VendorType Kind) {
437 setVendorName(getVendorTypeName(Kind));
440 void Triple::setOS(OSType Kind) {
441 setOSName(getOSTypeName(Kind));
444 void Triple::setArchName(StringRef Str) {
445 // Work around a miscompilation bug for Twines in gcc 4.0.3.
446 SmallString<64> Triple;
449 Triple += getVendorName();
451 Triple += getOSAndEnvironmentName();
452 setTriple(Triple.str());
455 void Triple::setVendorName(StringRef Str) {
456 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
459 void Triple::setOSName(StringRef Str) {
460 if (hasEnvironment())
461 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
462 "-" + getEnvironmentName());
464 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
467 void Triple::setEnvironmentName(StringRef Str) {
468 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
472 void Triple::setOSAndEnvironmentName(StringRef Str) {
473 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);