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;
184 void Triple::Parse() const {
185 assert(!isInitialized() && "Invalid parse call.");
187 StringRef ArchName = getArchName();
188 StringRef VendorName = getVendorName();
189 StringRef OSName = getOSName();
191 if (ArchName.size() == 4 && ArchName[0] == 'i' &&
192 ArchName[2] == '8' && ArchName[3] == '6' &&
193 ArchName[1] - '3' < 6) // i[3-9]86
195 else if (ArchName == "amd64" || ArchName == "x86_64")
197 else if (ArchName == "bfin")
199 else if (ArchName == "pic16")
201 else if (ArchName == "powerpc")
203 else if (ArchName == "powerpc64")
205 else if (ArchName == "arm" ||
206 ArchName.startswith("armv") ||
207 ArchName == "xscale")
209 else if (ArchName == "thumb" ||
210 ArchName.startswith("thumbv"))
212 else if (ArchName.startswith("alpha"))
214 else if (ArchName == "spu" || ArchName == "cellspu")
216 else if (ArchName == "msp430")
218 else if (ArchName == "mips" || ArchName == "mipsallegrex")
220 else if (ArchName == "mipsel" || ArchName == "mipsallegrexel" ||
223 else if (ArchName == "sparc")
225 else if (ArchName == "s390x")
227 else if (ArchName == "tce")
229 else if (ArchName == "xcore")
235 // Handle some exceptional cases where the OS / environment components are
236 // stuck into the vendor field.
237 if (StringRef(getTriple()).count('-') == 1) {
238 StringRef VendorName = getVendorName();
240 if (VendorName.startswith("mingw32")) { // 'i386-mingw32', etc.
246 // arm-elf is another example, but we don't currently parse anything about
250 if (VendorName == "apple")
252 else if (VendorName == "pc")
255 Vendor = UnknownVendor;
257 if (OSName.startswith("auroraux"))
259 else if (OSName.startswith("cygwin"))
261 else if (OSName.startswith("darwin"))
263 else if (OSName.startswith("dragonfly"))
265 else if (OSName.startswith("freebsd"))
267 else if (OSName.startswith("linux"))
269 else if (OSName.startswith("mingw32"))
271 else if (OSName.startswith("mingw64"))
273 else if (OSName.startswith("netbsd"))
275 else if (OSName.startswith("openbsd"))
277 else if (OSName.startswith("psp"))
279 else if (OSName.startswith("solaris"))
281 else if (OSName.startswith("win32"))
283 else if (OSName.startswith("haiku"))
288 assert(isInitialized() && "Failed to initialize!");
291 StringRef Triple::getArchName() const {
292 return StringRef(Data).split('-').first; // Isolate first component
295 StringRef Triple::getVendorName() const {
296 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
297 return Tmp.split('-').first; // Isolate second component
300 StringRef Triple::getOSName() const {
301 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
302 Tmp = Tmp.split('-').second; // Strip second component
303 return Tmp.split('-').first; // Isolate third component
306 StringRef Triple::getEnvironmentName() const {
307 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
308 Tmp = Tmp.split('-').second; // Strip second component
309 return Tmp.split('-').second; // Strip third component
312 StringRef Triple::getOSAndEnvironmentName() const {
313 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
314 return Tmp.split('-').second; // Strip second component
317 static unsigned EatNumber(StringRef &Str) {
318 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
319 unsigned Result = Str[0]-'0';
324 // Handle "darwin11".
325 if (Result == 1 && !Str.empty() && Str[0] >= '0' && Str[0] <= '9') {
326 Result = Result*10 + (Str[0] - '0');
334 /// getDarwinNumber - Parse the 'darwin number' out of the specific target
335 /// triple. For example, if we have darwin8.5 return 8,5,0. If any entry is
336 /// not defined, return 0's. This requires that the triple have an OSType of
337 /// darwin before it is called.
338 void Triple::getDarwinNumber(unsigned &Maj, unsigned &Min,
339 unsigned &Revision) const {
340 assert(getOS() == Darwin && "Not a darwin target triple!");
341 StringRef OSName = getOSName();
342 assert(OSName.startswith("darwin") && "Unknown darwin target triple!");
344 // Strip off "darwin".
345 OSName = OSName.substr(6);
347 Maj = Min = Revision = 0;
349 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
352 // The major version is the first digit.
353 Maj = EatNumber(OSName);
354 if (OSName.empty()) return;
356 // Handle minor version: 10.4.9 -> darwin8.9.
357 if (OSName[0] != '.')
361 OSName = OSName.substr(1);
363 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
366 Min = EatNumber(OSName);
367 if (OSName.empty()) return;
369 // Handle revision darwin8.9.1
370 if (OSName[0] != '.')
374 OSName = OSName.substr(1);
376 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
379 Revision = EatNumber(OSName);
382 void Triple::setTriple(const Twine &Str) {
387 void Triple::setArch(ArchType Kind) {
388 setArchName(getArchTypeName(Kind));
391 void Triple::setVendor(VendorType Kind) {
392 setVendorName(getVendorTypeName(Kind));
395 void Triple::setOS(OSType Kind) {
396 setOSName(getOSTypeName(Kind));
399 void Triple::setArchName(StringRef Str) {
400 // Work around a miscompilation bug for Twines in gcc 4.0.3.
401 SmallString<64> Triple;
404 Triple += getVendorName();
406 Triple += getOSAndEnvironmentName();
407 setTriple(Triple.str());
410 void Triple::setVendorName(StringRef Str) {
411 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
414 void Triple::setOSName(StringRef Str) {
415 if (hasEnvironment())
416 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
417 "-" + getEnvironmentName());
419 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
422 void Triple::setEnvironmentName(StringRef Str) {
423 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
427 void Triple::setOSAndEnvironmentName(StringRef Str) {
428 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);