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";
107 case Minix: return "minix";
113 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
120 if (Name == "cellspu")
124 if (Name == "mipsel")
126 if (Name == "msp430")
134 if (Name == "mblaze")
138 if (Name == "sparcv9")
140 if (Name == "systemz")
148 if (Name == "x86-64")
156 Triple::ArchType Triple::getArchTypeForDarwinArchName(StringRef Str) {
157 // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
158 // archs which Darwin doesn't use.
160 // The matching this routine does is fairly pointless, since it is neither the
161 // complete architecture list, nor a reasonable subset. The problem is that
162 // historically the driver driver accepts this and also ties its -march=
163 // handling to the architecture name, so we need to be careful before removing
166 // This code must be kept in sync with Clang's Darwin specific argument
169 if (Str == "ppc" || Str == "ppc601" || Str == "ppc603" || Str == "ppc604" ||
170 Str == "ppc604e" || Str == "ppc750" || Str == "ppc7400" ||
171 Str == "ppc7450" || Str == "ppc970")
175 return Triple::ppc64;
177 if (Str == "i386" || Str == "i486" || Str == "i486SX" || Str == "pentium" ||
178 Str == "i586" || Str == "pentpro" || Str == "i686" || Str == "pentIIm3" ||
179 Str == "pentIIm5" || Str == "pentium4")
183 return Triple::x86_64;
185 // This is derived from the driver driver.
186 if (Str == "arm" || Str == "armv4t" || Str == "armv5" || Str == "xscale" ||
187 Str == "armv6" || Str == "armv7")
190 return Triple::UnknownArch;
193 // Returns architecture name that is understood by the target assembler.
194 const char *Triple::getArchNameForAssembler() {
195 if (getOS() != Triple::Darwin && getVendor() != Triple::Apple)
198 StringRef Str = getArchName();
203 if (Str == "powerpc")
205 if (Str == "powerpc64")
207 if (Str == "mblaze" || Str == "microblaze")
211 if (Str == "armv4t" || Str == "thumbv4t")
213 if (Str == "armv5" || Str == "armv5e" || Str == "thumbv5" || Str == "thumbv5e")
215 if (Str == "armv6" || Str == "thumbv6")
217 if (Str == "armv7" || Str == "thumbv7")
224 void Triple::Parse() const {
225 assert(!isInitialized() && "Invalid parse call.");
227 StringRef ArchName = getArchName();
228 StringRef VendorName = getVendorName();
229 StringRef OSName = getOSName();
231 if (ArchName.size() == 4 && ArchName[0] == 'i' &&
232 ArchName[2] == '8' && ArchName[3] == '6' &&
233 ArchName[1] - '3' < 6) // i[3-9]86
235 else if (ArchName == "amd64" || ArchName == "x86_64")
237 else if (ArchName == "bfin")
239 else if (ArchName == "pic16")
241 else if (ArchName == "powerpc")
243 else if ((ArchName == "powerpc64") || (ArchName == "ppu"))
245 else if (ArchName == "mblaze")
247 else if (ArchName == "arm" ||
248 ArchName.startswith("armv") ||
249 ArchName == "xscale")
251 else if (ArchName == "thumb" ||
252 ArchName.startswith("thumbv"))
254 else if (ArchName.startswith("alpha"))
256 else if (ArchName == "spu" || ArchName == "cellspu")
258 else if (ArchName == "msp430")
260 else if (ArchName == "mips" || ArchName == "mipsallegrex")
262 else if (ArchName == "mipsel" || ArchName == "mipsallegrexel" ||
265 else if (ArchName == "sparc")
267 else if (ArchName == "sparcv9")
269 else if (ArchName == "s390x")
271 else if (ArchName == "tce")
273 else if (ArchName == "xcore")
279 // Handle some exceptional cases where the OS / environment components are
280 // stuck into the vendor field.
281 if (StringRef(getTriple()).count('-') == 1) {
282 StringRef VendorName = getVendorName();
284 if (VendorName.startswith("mingw32")) { // 'i386-mingw32', etc.
290 // arm-elf is another example, but we don't currently parse anything about
294 if (VendorName == "apple")
296 else if (VendorName == "pc")
299 Vendor = UnknownVendor;
301 if (OSName.startswith("auroraux"))
303 else if (OSName.startswith("cygwin"))
305 else if (OSName.startswith("darwin"))
307 else if (OSName.startswith("dragonfly"))
309 else if (OSName.startswith("freebsd"))
311 else if (OSName.startswith("linux"))
313 else if (OSName.startswith("lv2"))
315 else if (OSName.startswith("mingw32"))
317 else if (OSName.startswith("mingw64"))
319 else if (OSName.startswith("netbsd"))
321 else if (OSName.startswith("openbsd"))
323 else if (OSName.startswith("psp"))
325 else if (OSName.startswith("solaris"))
327 else if (OSName.startswith("win32"))
329 else if (OSName.startswith("haiku"))
331 else if (OSName.startswith("minix"))
336 assert(isInitialized() && "Failed to initialize!");
339 StringRef Triple::getArchName() const {
340 return StringRef(Data).split('-').first; // Isolate first component
343 StringRef Triple::getVendorName() const {
344 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
345 return Tmp.split('-').first; // Isolate second component
348 StringRef Triple::getOSName() const {
349 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
350 Tmp = Tmp.split('-').second; // Strip second component
351 return Tmp.split('-').first; // Isolate third component
354 StringRef Triple::getEnvironmentName() const {
355 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
356 Tmp = Tmp.split('-').second; // Strip second component
357 return Tmp.split('-').second; // Strip third component
360 StringRef Triple::getOSAndEnvironmentName() const {
361 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
362 return Tmp.split('-').second; // Strip second component
365 static unsigned EatNumber(StringRef &Str) {
366 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
367 unsigned Result = Str[0]-'0';
372 // Handle "darwin11".
373 if (Result == 1 && !Str.empty() && Str[0] >= '0' && Str[0] <= '9') {
374 Result = Result*10 + (Str[0] - '0');
382 /// getDarwinNumber - Parse the 'darwin number' out of the specific target
383 /// triple. For example, if we have darwin8.5 return 8,5,0. If any entry is
384 /// not defined, return 0's. This requires that the triple have an OSType of
385 /// darwin before it is called.
386 void Triple::getDarwinNumber(unsigned &Maj, unsigned &Min,
387 unsigned &Revision) const {
388 assert(getOS() == Darwin && "Not a darwin target triple!");
389 StringRef OSName = getOSName();
390 assert(OSName.startswith("darwin") && "Unknown darwin target triple!");
392 // Strip off "darwin".
393 OSName = OSName.substr(6);
395 Maj = Min = Revision = 0;
397 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
400 // The major version is the first digit.
401 Maj = EatNumber(OSName);
402 if (OSName.empty()) return;
404 // Handle minor version: 10.4.9 -> darwin8.9.
405 if (OSName[0] != '.')
409 OSName = OSName.substr(1);
411 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
414 Min = EatNumber(OSName);
415 if (OSName.empty()) return;
417 // Handle revision darwin8.9.1
418 if (OSName[0] != '.')
422 OSName = OSName.substr(1);
424 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
427 Revision = EatNumber(OSName);
430 void Triple::setTriple(const Twine &Str) {
435 void Triple::setArch(ArchType Kind) {
436 setArchName(getArchTypeName(Kind));
439 void Triple::setVendor(VendorType Kind) {
440 setVendorName(getVendorTypeName(Kind));
443 void Triple::setOS(OSType Kind) {
444 setOSName(getOSTypeName(Kind));
447 void Triple::setArchName(StringRef Str) {
448 // Work around a miscompilation bug for Twines in gcc 4.0.3.
449 SmallString<64> Triple;
452 Triple += getVendorName();
454 Triple += getOSAndEnvironmentName();
455 setTriple(Triple.str());
458 void Triple::setVendorName(StringRef Str) {
459 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
462 void Triple::setOSName(StringRef Str) {
463 if (hasEnvironment())
464 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
465 "-" + getEnvironmentName());
467 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
470 void Triple::setEnvironmentName(StringRef Str) {
471 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
475 void Triple::setOSAndEnvironmentName(StringRef Str) {
476 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);