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 Solaris: return "solaris";
98 case Win32: return "win32";
99 case Haiku: return "haiku";
105 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
112 if (Name == "cellspu")
116 if (Name == "mipsel")
118 if (Name == "msp430")
128 if (Name == "systemz")
136 if (Name == "x86-64")
144 Triple::ArchType Triple::getArchTypeForDarwinArchName(StringRef Str) {
145 // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
146 // archs which Darwin doesn't use.
148 // The matching this routine does is fairly pointless, since it is neither the
149 // complete architecture list, nor a reasonable subset. The problem is that
150 // historically the driver driver accepts this and also ties its -march=
151 // handling to the architecture name, so we need to be careful before removing
154 // This code must be kept in sync with Clang's Darwin specific argument
157 if (Str == "ppc" || Str == "ppc601" || Str == "ppc603" || Str == "ppc604" ||
158 Str == "ppc604e" || Str == "ppc750" || Str == "ppc7400" ||
159 Str == "ppc7450" || Str == "ppc970")
163 return Triple::ppc64;
165 if (Str == "i386" || Str == "i486" || Str == "i486SX" || Str == "pentium" ||
166 Str == "i586" || Str == "pentpro" || Str == "i686" || Str == "pentIIm3" ||
167 Str == "pentIIm5" || Str == "pentium4")
171 return Triple::x86_64;
173 // This is derived from the driver driver.
174 if (Str == "arm" || Str == "armv4t" || Str == "armv5" || Str == "xscale" ||
175 Str == "armv6" || Str == "armv7")
178 return Triple::UnknownArch;
183 void Triple::Parse() const {
184 assert(!isInitialized() && "Invalid parse call.");
186 StringRef ArchName = getArchName();
187 StringRef VendorName = getVendorName();
188 StringRef OSName = getOSName();
190 if (ArchName.size() == 4 && ArchName[0] == 'i' &&
191 ArchName[2] == '8' && ArchName[3] == '6' &&
192 ArchName[1] - '3' < 6) // i[3-9]86
194 else if (ArchName == "amd64" || ArchName == "x86_64")
196 else if (ArchName == "bfin")
198 else if (ArchName == "pic16")
200 else if (ArchName == "powerpc")
202 else if (ArchName == "powerpc64")
204 else if (ArchName == "arm" ||
205 ArchName.startswith("armv") ||
206 ArchName == "xscale")
208 else if (ArchName == "thumb" ||
209 ArchName.startswith("thumbv"))
211 else if (ArchName.startswith("alpha"))
213 else if (ArchName == "spu" || ArchName == "cellspu")
215 else if (ArchName == "msp430")
217 else if (ArchName == "mips" || ArchName == "mipsallegrex")
219 else if (ArchName == "mipsel" || ArchName == "mipsallegrexel" ||
222 else if (ArchName == "sparc")
224 else if (ArchName == "s390x")
226 else if (ArchName == "tce")
228 else if (ArchName == "xcore")
234 // Handle some exceptional cases where the OS / environment components are
235 // stuck into the vendor field.
236 if (StringRef(getTriple()).count('-') == 1) {
237 StringRef VendorName = getVendorName();
239 if (VendorName.startswith("mingw32")) { // 'i386-mingw32', etc.
245 // arm-elf is another example, but we don't currently parse anything about
249 if (VendorName == "apple")
251 else if (VendorName == "pc")
254 Vendor = UnknownVendor;
256 if (OSName.startswith("auroraux"))
258 else if (OSName.startswith("cygwin"))
260 else if (OSName.startswith("darwin"))
262 else if (OSName.startswith("dragonfly"))
264 else if (OSName.startswith("freebsd"))
266 else if (OSName.startswith("linux"))
268 else if (OSName.startswith("mingw32"))
270 else if (OSName.startswith("mingw64"))
272 else if (OSName.startswith("netbsd"))
274 else if (OSName.startswith("openbsd"))
276 else if (OSName.startswith("solaris"))
278 else if (OSName.startswith("win32"))
280 else if (OSName.startswith("haiku"))
285 assert(isInitialized() && "Failed to initialize!");
288 StringRef Triple::getArchName() const {
289 return StringRef(Data).split('-').first; // Isolate first component
292 StringRef Triple::getVendorName() const {
293 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
294 return Tmp.split('-').first; // Isolate second component
297 StringRef Triple::getOSName() const {
298 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
299 Tmp = Tmp.split('-').second; // Strip second component
300 return Tmp.split('-').first; // Isolate third component
303 StringRef Triple::getEnvironmentName() const {
304 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
305 Tmp = Tmp.split('-').second; // Strip second component
306 return Tmp.split('-').second; // Strip third component
309 StringRef Triple::getOSAndEnvironmentName() const {
310 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
311 return Tmp.split('-').second; // Strip second component
314 static unsigned EatNumber(StringRef &Str) {
315 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
316 unsigned Result = Str[0]-'0';
321 // Handle "darwin11".
322 if (Result == 1 && !Str.empty() && Str[0] >= '0' && Str[0] <= '9') {
323 Result = Result*10 + (Str[0] - '0');
331 /// getDarwinNumber - Parse the 'darwin number' out of the specific target
332 /// triple. For example, if we have darwin8.5 return 8,5,0. If any entry is
333 /// not defined, return 0's. This requires that the triple have an OSType of
334 /// darwin before it is called.
335 void Triple::getDarwinNumber(unsigned &Maj, unsigned &Min,
336 unsigned &Revision) const {
337 assert(getOS() == Darwin && "Not a darwin target triple!");
338 StringRef OSName = getOSName();
339 assert(OSName.startswith("darwin") && "Unknown darwin target triple!");
341 // Strip off "darwin".
342 OSName = OSName.substr(6);
344 Maj = Min = Revision = 0;
346 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
349 // The major version is the first digit.
350 Maj = EatNumber(OSName);
351 if (OSName.empty()) return;
353 // Handle minor version: 10.4.9 -> darwin8.9.
354 if (OSName[0] != '.')
358 OSName = OSName.substr(1);
360 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
363 Min = EatNumber(OSName);
364 if (OSName.empty()) return;
366 // Handle revision darwin8.9.1
367 if (OSName[0] != '.')
371 OSName = OSName.substr(1);
373 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
376 Revision = EatNumber(OSName);
379 void Triple::setTriple(const Twine &Str) {
384 void Triple::setArch(ArchType Kind) {
385 setArchName(getArchTypeName(Kind));
388 void Triple::setVendor(VendorType Kind) {
389 setVendorName(getVendorTypeName(Kind));
392 void Triple::setOS(OSType Kind) {
393 setOSName(getOSTypeName(Kind));
396 void Triple::setArchName(StringRef Str) {
397 // Work around a miscompilation bug for Twines in gcc 4.0.3.
398 SmallString<64> Triple;
401 Triple += getVendorName();
403 Triple += getOSAndEnvironmentName();
404 setTriple(Triple.str());
407 void Triple::setVendorName(StringRef Str) {
408 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
411 void Triple::setOSName(StringRef Str) {
412 if (hasEnvironment())
413 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
414 "-" + getEnvironmentName());
416 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
419 void Triple::setEnvironmentName(StringRef Str) {
420 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
424 void Triple::setOSAndEnvironmentName(StringRef Str) {
425 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);