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 Lv2: return "lv2";
94 case MinGW32: return "mingw32";
95 case MinGW64: return "mingw64";
96 case NetBSD: return "netbsd";
97 case OpenBSD: return "openbsd";
98 case Psp: return "psp";
99 case Solaris: return "solaris";
100 case Win32: return "win32";
101 case Haiku: return "haiku";
107 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
114 if (Name == "cellspu")
118 if (Name == "mipsel")
120 if (Name == "msp430")
130 if (Name == "systemz")
138 if (Name == "x86-64")
146 Triple::ArchType Triple::getArchTypeForDarwinArchName(StringRef Str) {
147 // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
148 // archs which Darwin doesn't use.
150 // The matching this routine does is fairly pointless, since it is neither the
151 // complete architecture list, nor a reasonable subset. The problem is that
152 // historically the driver driver accepts this and also ties its -march=
153 // handling to the architecture name, so we need to be careful before removing
156 // This code must be kept in sync with Clang's Darwin specific argument
159 if (Str == "ppc" || Str == "ppc601" || Str == "ppc603" || Str == "ppc604" ||
160 Str == "ppc604e" || Str == "ppc750" || Str == "ppc7400" ||
161 Str == "ppc7450" || Str == "ppc970")
165 return Triple::ppc64;
167 if (Str == "i386" || Str == "i486" || Str == "i486SX" || Str == "pentium" ||
168 Str == "i586" || Str == "pentpro" || Str == "i686" || Str == "pentIIm3" ||
169 Str == "pentIIm5" || Str == "pentium4")
173 return Triple::x86_64;
175 // This is derived from the driver driver.
176 if (Str == "arm" || Str == "armv4t" || Str == "armv5" || Str == "xscale" ||
177 Str == "armv6" || Str == "armv7")
180 return Triple::UnknownArch;
183 // Returns architecture name that is unsderstood by the target assembler.
184 const char *Triple::getArchNameForAssembler() {
185 if (getOS() != Triple::Darwin && getVendor() != Triple::Apple)
188 StringRef Str = getArchName();
193 if (Str == "powerpc")
195 if (Str == "powerpc64")
199 if (Str == "armv4t" || Str == "thumbv4t")
201 if (Str == "armv5" || Str == "armv5e" || Str == "thumbv5" || Str == "thumbv5e")
203 if (Str == "armv6" || Str == "thumbv6")
205 if (Str == "armv7" || Str == "thumbv7")
212 void Triple::Parse() const {
213 assert(!isInitialized() && "Invalid parse call.");
215 StringRef ArchName = getArchName();
216 StringRef VendorName = getVendorName();
217 StringRef OSName = getOSName();
219 if (ArchName.size() == 4 && ArchName[0] == 'i' &&
220 ArchName[2] == '8' && ArchName[3] == '6' &&
221 ArchName[1] - '3' < 6) // i[3-9]86
223 else if (ArchName == "amd64" || ArchName == "x86_64")
225 else if (ArchName == "bfin")
227 else if (ArchName == "pic16")
229 else if (ArchName == "powerpc")
231 else if ((ArchName == "powerpc64") || (ArchName == "ppu"))
233 else if (ArchName == "arm" ||
234 ArchName.startswith("armv") ||
235 ArchName == "xscale")
237 else if (ArchName == "thumb" ||
238 ArchName.startswith("thumbv"))
240 else if (ArchName.startswith("alpha"))
242 else if (ArchName == "spu" || ArchName == "cellspu")
244 else if (ArchName == "msp430")
246 else if (ArchName == "mips" || ArchName == "mipsallegrex")
248 else if (ArchName == "mipsel" || ArchName == "mipsallegrexel" ||
251 else if (ArchName == "sparc")
253 else if (ArchName == "s390x")
255 else if (ArchName == "tce")
257 else if (ArchName == "xcore")
263 // Handle some exceptional cases where the OS / environment components are
264 // stuck into the vendor field.
265 if (StringRef(getTriple()).count('-') == 1) {
266 StringRef VendorName = getVendorName();
268 if (VendorName.startswith("mingw32")) { // 'i386-mingw32', etc.
274 // arm-elf is another example, but we don't currently parse anything about
278 if (VendorName == "apple")
280 else if (VendorName == "pc")
283 Vendor = UnknownVendor;
285 if (OSName.startswith("auroraux"))
287 else if (OSName.startswith("cygwin"))
289 else if (OSName.startswith("darwin"))
291 else if (OSName.startswith("dragonfly"))
293 else if (OSName.startswith("freebsd"))
295 else if (OSName.startswith("linux"))
297 else if (OSName.startswith("lv2"))
299 else if (OSName.startswith("mingw32"))
301 else if (OSName.startswith("mingw64"))
303 else if (OSName.startswith("netbsd"))
305 else if (OSName.startswith("openbsd"))
307 else if (OSName.startswith("psp"))
309 else if (OSName.startswith("solaris"))
311 else if (OSName.startswith("win32"))
313 else if (OSName.startswith("haiku"))
318 assert(isInitialized() && "Failed to initialize!");
321 StringRef Triple::getArchName() const {
322 return StringRef(Data).split('-').first; // Isolate first component
325 StringRef Triple::getVendorName() const {
326 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
327 return Tmp.split('-').first; // Isolate second component
330 StringRef Triple::getOSName() const {
331 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
332 Tmp = Tmp.split('-').second; // Strip second component
333 return Tmp.split('-').first; // Isolate third component
336 StringRef Triple::getEnvironmentName() const {
337 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
338 Tmp = Tmp.split('-').second; // Strip second component
339 return Tmp.split('-').second; // Strip third component
342 StringRef Triple::getOSAndEnvironmentName() const {
343 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
344 return Tmp.split('-').second; // Strip second component
347 static unsigned EatNumber(StringRef &Str) {
348 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
349 unsigned Result = Str[0]-'0';
354 // Handle "darwin11".
355 if (Result == 1 && !Str.empty() && Str[0] >= '0' && Str[0] <= '9') {
356 Result = Result*10 + (Str[0] - '0');
364 /// getDarwinNumber - Parse the 'darwin number' out of the specific target
365 /// triple. For example, if we have darwin8.5 return 8,5,0. If any entry is
366 /// not defined, return 0's. This requires that the triple have an OSType of
367 /// darwin before it is called.
368 void Triple::getDarwinNumber(unsigned &Maj, unsigned &Min,
369 unsigned &Revision) const {
370 assert(getOS() == Darwin && "Not a darwin target triple!");
371 StringRef OSName = getOSName();
372 assert(OSName.startswith("darwin") && "Unknown darwin target triple!");
374 // Strip off "darwin".
375 OSName = OSName.substr(6);
377 Maj = Min = Revision = 0;
379 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
382 // The major version is the first digit.
383 Maj = EatNumber(OSName);
384 if (OSName.empty()) return;
386 // Handle minor version: 10.4.9 -> darwin8.9.
387 if (OSName[0] != '.')
391 OSName = OSName.substr(1);
393 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
396 Min = EatNumber(OSName);
397 if (OSName.empty()) return;
399 // Handle revision darwin8.9.1
400 if (OSName[0] != '.')
404 OSName = OSName.substr(1);
406 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
409 Revision = EatNumber(OSName);
412 void Triple::setTriple(const Twine &Str) {
417 void Triple::setArch(ArchType Kind) {
418 setArchName(getArchTypeName(Kind));
421 void Triple::setVendor(VendorType Kind) {
422 setVendorName(getVendorTypeName(Kind));
425 void Triple::setOS(OSType Kind) {
426 setOSName(getOSTypeName(Kind));
429 void Triple::setArchName(StringRef Str) {
430 // Work around a miscompilation bug for Twines in gcc 4.0.3.
431 SmallString<64> Triple;
434 Triple += getVendorName();
436 Triple += getOSAndEnvironmentName();
437 setTriple(Triple.str());
440 void Triple::setVendorName(StringRef Str) {
441 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
444 void Triple::setOSName(StringRef Str) {
445 if (hasEnvironment())
446 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
447 "-" + getEnvironmentName());
449 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
452 void Triple::setEnvironmentName(StringRef Str) {
453 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
457 void Triple::setOSAndEnvironmentName(StringRef Str) {
458 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);