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";
48 const char *Triple::getArchTypePrefix(ArchType Kind) {
53 case alpha: return "alpha";
56 case thumb: return "arm";
58 case bfin: return "bfin";
60 case cellspu: return "spu";
63 case ppc: return "ppc";
66 case sparc: return "sparc";
69 case x86_64: return "x86";
70 case xcore: return "xcore";
74 const char *Triple::getVendorTypeName(VendorType Kind) {
76 case UnknownVendor: return "unknown";
78 case Apple: return "apple";
85 const char *Triple::getOSTypeName(OSType Kind) {
87 case UnknownOS: return "unknown";
89 case AuroraUX: return "auroraux";
90 case Cygwin: return "cygwin";
91 case Darwin: return "darwin";
92 case DragonFly: return "dragonfly";
93 case FreeBSD: return "freebsd";
94 case Linux: return "linux";
95 case Lv2: return "lv2";
96 case MinGW32: return "mingw32";
97 case MinGW64: return "mingw64";
98 case NetBSD: return "netbsd";
99 case OpenBSD: return "openbsd";
100 case Psp: return "psp";
101 case Solaris: return "solaris";
102 case Win32: return "win32";
103 case Haiku: return "haiku";
109 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
116 if (Name == "cellspu")
120 if (Name == "mipsel")
122 if (Name == "msp430")
132 if (Name == "sparcv9")
134 if (Name == "systemz")
142 if (Name == "x86-64")
150 Triple::ArchType Triple::getArchTypeForDarwinArchName(StringRef Str) {
151 // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
152 // archs which Darwin doesn't use.
154 // The matching this routine does is fairly pointless, since it is neither the
155 // complete architecture list, nor a reasonable subset. The problem is that
156 // historically the driver driver accepts this and also ties its -march=
157 // handling to the architecture name, so we need to be careful before removing
160 // This code must be kept in sync with Clang's Darwin specific argument
163 if (Str == "ppc" || Str == "ppc601" || Str == "ppc603" || Str == "ppc604" ||
164 Str == "ppc604e" || Str == "ppc750" || Str == "ppc7400" ||
165 Str == "ppc7450" || Str == "ppc970")
169 return Triple::ppc64;
171 if (Str == "i386" || Str == "i486" || Str == "i486SX" || Str == "pentium" ||
172 Str == "i586" || Str == "pentpro" || Str == "i686" || Str == "pentIIm3" ||
173 Str == "pentIIm5" || Str == "pentium4")
177 return Triple::x86_64;
179 // This is derived from the driver driver.
180 if (Str == "arm" || Str == "armv4t" || Str == "armv5" || Str == "xscale" ||
181 Str == "armv6" || Str == "armv7")
184 return Triple::UnknownArch;
187 // Returns architecture name that is unsderstood by the target assembler.
188 const char *Triple::getArchNameForAssembler() {
189 if (getOS() != Triple::Darwin && getVendor() != Triple::Apple)
192 StringRef Str = getArchName();
197 if (Str == "powerpc")
199 if (Str == "powerpc64")
203 if (Str == "armv4t" || Str == "thumbv4t")
205 if (Str == "armv5" || Str == "armv5e" || Str == "thumbv5" || Str == "thumbv5e")
207 if (Str == "armv6" || Str == "thumbv6")
209 if (Str == "armv7" || Str == "thumbv7")
216 void Triple::Parse() const {
217 assert(!isInitialized() && "Invalid parse call.");
219 StringRef ArchName = getArchName();
220 StringRef VendorName = getVendorName();
221 StringRef OSName = getOSName();
223 if (ArchName.size() == 4 && ArchName[0] == 'i' &&
224 ArchName[2] == '8' && ArchName[3] == '6' &&
225 ArchName[1] - '3' < 6) // i[3-9]86
227 else if (ArchName == "amd64" || ArchName == "x86_64")
229 else if (ArchName == "bfin")
231 else if (ArchName == "pic16")
233 else if (ArchName == "powerpc")
235 else if ((ArchName == "powerpc64") || (ArchName == "ppu"))
237 else if (ArchName == "arm" ||
238 ArchName.startswith("armv") ||
239 ArchName == "xscale")
241 else if (ArchName == "thumb" ||
242 ArchName.startswith("thumbv"))
244 else if (ArchName.startswith("alpha"))
246 else if (ArchName == "spu" || ArchName == "cellspu")
248 else if (ArchName == "msp430")
250 else if (ArchName == "mips" || ArchName == "mipsallegrex")
252 else if (ArchName == "mipsel" || ArchName == "mipsallegrexel" ||
255 else if (ArchName == "sparc")
257 else if (ArchName == "sparcv9")
259 else if (ArchName == "s390x")
261 else if (ArchName == "tce")
263 else if (ArchName == "xcore")
269 // Handle some exceptional cases where the OS / environment components are
270 // stuck into the vendor field.
271 if (StringRef(getTriple()).count('-') == 1) {
272 StringRef VendorName = getVendorName();
274 if (VendorName.startswith("mingw32")) { // 'i386-mingw32', etc.
280 // arm-elf is another example, but we don't currently parse anything about
284 if (VendorName == "apple")
286 else if (VendorName == "pc")
289 Vendor = UnknownVendor;
291 if (OSName.startswith("auroraux"))
293 else if (OSName.startswith("cygwin"))
295 else if (OSName.startswith("darwin"))
297 else if (OSName.startswith("dragonfly"))
299 else if (OSName.startswith("freebsd"))
301 else if (OSName.startswith("linux"))
303 else if (OSName.startswith("lv2"))
305 else if (OSName.startswith("mingw32"))
307 else if (OSName.startswith("mingw64"))
309 else if (OSName.startswith("netbsd"))
311 else if (OSName.startswith("openbsd"))
313 else if (OSName.startswith("psp"))
315 else if (OSName.startswith("solaris"))
317 else if (OSName.startswith("win32"))
319 else if (OSName.startswith("haiku"))
324 assert(isInitialized() && "Failed to initialize!");
327 StringRef Triple::getArchName() const {
328 return StringRef(Data).split('-').first; // Isolate first component
331 StringRef Triple::getVendorName() const {
332 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
333 return Tmp.split('-').first; // Isolate second component
336 StringRef Triple::getOSName() const {
337 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
338 Tmp = Tmp.split('-').second; // Strip second component
339 return Tmp.split('-').first; // Isolate third component
342 StringRef Triple::getEnvironmentName() const {
343 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
344 Tmp = Tmp.split('-').second; // Strip second component
345 return Tmp.split('-').second; // Strip third component
348 StringRef Triple::getOSAndEnvironmentName() const {
349 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
350 return Tmp.split('-').second; // Strip second component
353 static unsigned EatNumber(StringRef &Str) {
354 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
355 unsigned Result = Str[0]-'0';
360 // Handle "darwin11".
361 if (Result == 1 && !Str.empty() && Str[0] >= '0' && Str[0] <= '9') {
362 Result = Result*10 + (Str[0] - '0');
370 /// getDarwinNumber - Parse the 'darwin number' out of the specific target
371 /// triple. For example, if we have darwin8.5 return 8,5,0. If any entry is
372 /// not defined, return 0's. This requires that the triple have an OSType of
373 /// darwin before it is called.
374 void Triple::getDarwinNumber(unsigned &Maj, unsigned &Min,
375 unsigned &Revision) const {
376 assert(getOS() == Darwin && "Not a darwin target triple!");
377 StringRef OSName = getOSName();
378 assert(OSName.startswith("darwin") && "Unknown darwin target triple!");
380 // Strip off "darwin".
381 OSName = OSName.substr(6);
383 Maj = Min = Revision = 0;
385 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
388 // The major version is the first digit.
389 Maj = EatNumber(OSName);
390 if (OSName.empty()) return;
392 // Handle minor version: 10.4.9 -> darwin8.9.
393 if (OSName[0] != '.')
397 OSName = OSName.substr(1);
399 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
402 Min = EatNumber(OSName);
403 if (OSName.empty()) return;
405 // Handle revision darwin8.9.1
406 if (OSName[0] != '.')
410 OSName = OSName.substr(1);
412 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
415 Revision = EatNumber(OSName);
418 void Triple::setTriple(const Twine &Str) {
423 void Triple::setArch(ArchType Kind) {
424 setArchName(getArchTypeName(Kind));
427 void Triple::setVendor(VendorType Kind) {
428 setVendorName(getVendorTypeName(Kind));
431 void Triple::setOS(OSType Kind) {
432 setOSName(getOSTypeName(Kind));
435 void Triple::setArchName(StringRef Str) {
436 // Work around a miscompilation bug for Twines in gcc 4.0.3.
437 SmallString<64> Triple;
440 Triple += getVendorName();
442 Triple += getOSAndEnvironmentName();
443 setTriple(Triple.str());
446 void Triple::setVendorName(StringRef Str) {
447 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
450 void Triple::setOSName(StringRef Str) {
451 if (hasEnvironment())
452 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
453 "-" + getEnvironmentName());
455 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
458 void Triple::setEnvironmentName(StringRef Str) {
459 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
463 void Triple::setOSAndEnvironmentName(StringRef Str) {
464 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);