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 systemz: return "s390x";
37 case tce: return "tce";
38 case thumb: return "thumb";
39 case x86: return "i386";
40 case x86_64: return "x86_64";
41 case xcore: return "xcore";
47 const char *Triple::getArchTypePrefix(ArchType Kind) {
52 case alpha: return "alpha";
55 case thumb: return "arm";
57 case bfin: return "bfin";
59 case cellspu: return "spu";
62 case ppc: return "ppc";
64 case sparc: return "sparc";
67 case x86_64: return "x86";
68 case xcore: return "xcore";
72 const char *Triple::getVendorTypeName(VendorType Kind) {
74 case UnknownVendor: return "unknown";
76 case Apple: return "apple";
83 const char *Triple::getOSTypeName(OSType Kind) {
85 case UnknownOS: return "unknown";
87 case AuroraUX: return "auroraux";
88 case Cygwin: return "cygwin";
89 case Darwin: return "darwin";
90 case DragonFly: return "dragonfly";
91 case FreeBSD: return "freebsd";
92 case Linux: return "linux";
93 case MinGW32: return "mingw32";
94 case MinGW64: return "mingw64";
95 case NetBSD: return "netbsd";
96 case OpenBSD: return "openbsd";
97 case Psp: return "psp";
98 case Solaris: return "solaris";
99 case Win32: return "win32";
100 case Haiku: return "haiku";
106 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
113 if (Name == "cellspu")
117 if (Name == "mipsel")
119 if (Name == "msp430")
129 if (Name == "systemz")
137 if (Name == "x86-64")
145 Triple::ArchType Triple::getArchTypeForDarwinArchName(StringRef Str) {
146 // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
147 // archs which Darwin doesn't use.
149 // The matching this routine does is fairly pointless, since it is neither the
150 // complete architecture list, nor a reasonable subset. The problem is that
151 // historically the driver driver accepts this and also ties its -march=
152 // handling to the architecture name, so we need to be careful before removing
155 // This code must be kept in sync with Clang's Darwin specific argument
158 if (Str == "ppc" || Str == "ppc601" || Str == "ppc603" || Str == "ppc604" ||
159 Str == "ppc604e" || Str == "ppc750" || Str == "ppc7400" ||
160 Str == "ppc7450" || Str == "ppc970")
164 return Triple::ppc64;
166 if (Str == "i386" || Str == "i486" || Str == "i486SX" || Str == "pentium" ||
167 Str == "i586" || Str == "pentpro" || Str == "i686" || Str == "pentIIm3" ||
168 Str == "pentIIm5" || Str == "pentium4")
172 return Triple::x86_64;
174 // This is derived from the driver driver.
175 if (Str == "arm" || Str == "armv4t" || Str == "armv5" || Str == "xscale" ||
176 Str == "armv6" || Str == "armv7")
179 return Triple::UnknownArch;
182 // Returns architecture name that is unsderstood by the target assembler.
183 const char *Triple::getArchNameForAssembler() {
184 if (getOS() != Triple::Darwin && getVendor() != Triple::Apple)
187 StringRef Str = getArchName();
192 if (Str == "powerpc")
194 if (Str == "powerpc64")
198 if (Str == "armv4t" || Str == "thumbv4t")
200 if (Str == "armv5" || Str == "armv5e" || Str == "thumbv5" || Str == "thumbv5e")
202 if (Str == "armv6" || Str == "thumbv6")
204 if (Str == "armv7" || Str == "thumbv7")
211 void Triple::Parse() const {
212 assert(!isInitialized() && "Invalid parse call.");
214 StringRef ArchName = getArchName();
215 StringRef VendorName = getVendorName();
216 StringRef OSName = getOSName();
218 if (ArchName.size() == 4 && ArchName[0] == 'i' &&
219 ArchName[2] == '8' && ArchName[3] == '6' &&
220 ArchName[1] - '3' < 6) // i[3-9]86
222 else if (ArchName == "amd64" || ArchName == "x86_64")
224 else if (ArchName == "bfin")
226 else if (ArchName == "pic16")
228 else if (ArchName == "powerpc")
230 else if (ArchName == "powerpc64")
232 else if (ArchName == "arm" ||
233 ArchName.startswith("armv") ||
234 ArchName == "xscale")
236 else if (ArchName == "thumb" ||
237 ArchName.startswith("thumbv"))
239 else if (ArchName.startswith("alpha"))
241 else if (ArchName == "spu" || ArchName == "cellspu")
243 else if (ArchName == "msp430")
245 else if (ArchName == "mips" || ArchName == "mipsallegrex")
247 else if (ArchName == "mipsel" || ArchName == "mipsallegrexel" ||
250 else if (ArchName == "sparc")
252 else if (ArchName == "s390x")
254 else if (ArchName == "tce")
256 else if (ArchName == "xcore")
262 // Handle some exceptional cases where the OS / environment components are
263 // stuck into the vendor field.
264 if (StringRef(getTriple()).count('-') == 1) {
265 StringRef VendorName = getVendorName();
267 if (VendorName.startswith("mingw32")) { // 'i386-mingw32', etc.
273 // arm-elf is another example, but we don't currently parse anything about
277 if (VendorName == "apple")
279 else if (VendorName == "pc")
282 Vendor = UnknownVendor;
284 if (OSName.startswith("auroraux"))
286 else if (OSName.startswith("cygwin"))
288 else if (OSName.startswith("darwin"))
290 else if (OSName.startswith("dragonfly"))
292 else if (OSName.startswith("freebsd"))
294 else if (OSName.startswith("linux"))
296 else if (OSName.startswith("mingw32"))
298 else if (OSName.startswith("mingw64"))
300 else if (OSName.startswith("netbsd"))
302 else if (OSName.startswith("openbsd"))
304 else if (OSName.startswith("psp"))
306 else if (OSName.startswith("solaris"))
308 else if (OSName.startswith("win32"))
310 else if (OSName.startswith("haiku"))
315 assert(isInitialized() && "Failed to initialize!");
318 StringRef Triple::getArchName() const {
319 return StringRef(Data).split('-').first; // Isolate first component
322 StringRef Triple::getVendorName() const {
323 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
324 return Tmp.split('-').first; // Isolate second component
327 StringRef Triple::getOSName() const {
328 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
329 Tmp = Tmp.split('-').second; // Strip second component
330 return Tmp.split('-').first; // Isolate third component
333 StringRef Triple::getEnvironmentName() const {
334 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
335 Tmp = Tmp.split('-').second; // Strip second component
336 return Tmp.split('-').second; // Strip third component
339 StringRef Triple::getOSAndEnvironmentName() const {
340 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
341 return Tmp.split('-').second; // Strip second component
344 static unsigned EatNumber(StringRef &Str) {
345 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
346 unsigned Result = Str[0]-'0';
351 // Handle "darwin11".
352 if (Result == 1 && !Str.empty() && Str[0] >= '0' && Str[0] <= '9') {
353 Result = Result*10 + (Str[0] - '0');
361 /// getDarwinNumber - Parse the 'darwin number' out of the specific target
362 /// triple. For example, if we have darwin8.5 return 8,5,0. If any entry is
363 /// not defined, return 0's. This requires that the triple have an OSType of
364 /// darwin before it is called.
365 void Triple::getDarwinNumber(unsigned &Maj, unsigned &Min,
366 unsigned &Revision) const {
367 assert(getOS() == Darwin && "Not a darwin target triple!");
368 StringRef OSName = getOSName();
369 assert(OSName.startswith("darwin") && "Unknown darwin target triple!");
371 // Strip off "darwin".
372 OSName = OSName.substr(6);
374 Maj = Min = Revision = 0;
376 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
379 // The major version is the first digit.
380 Maj = EatNumber(OSName);
381 if (OSName.empty()) return;
383 // Handle minor version: 10.4.9 -> darwin8.9.
384 if (OSName[0] != '.')
388 OSName = OSName.substr(1);
390 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
393 Min = EatNumber(OSName);
394 if (OSName.empty()) return;
396 // Handle revision darwin8.9.1
397 if (OSName[0] != '.')
401 OSName = OSName.substr(1);
403 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
406 Revision = EatNumber(OSName);
409 void Triple::setTriple(const Twine &Str) {
414 void Triple::setArch(ArchType Kind) {
415 setArchName(getArchTypeName(Kind));
418 void Triple::setVendor(VendorType Kind) {
419 setVendorName(getVendorTypeName(Kind));
422 void Triple::setOS(OSType Kind) {
423 setOSName(getOSTypeName(Kind));
426 void Triple::setArchName(StringRef Str) {
427 // Work around a miscompilation bug for Twines in gcc 4.0.3.
428 SmallString<64> Triple;
431 Triple += getVendorName();
433 Triple += getOSAndEnvironmentName();
434 setTriple(Triple.str());
437 void Triple::setVendorName(StringRef Str) {
438 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
441 void Triple::setOSName(StringRef Str) {
442 if (hasEnvironment())
443 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
444 "-" + getEnvironmentName());
446 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
449 void Triple::setEnvironmentName(StringRef Str) {
450 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
454 void Triple::setOSAndEnvironmentName(StringRef Str) {
455 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);