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";
104 Triple::ArchType Triple::getArchTypeForLLVMName(const StringRef &Name) {
111 if (Name == "cellspu")
115 if (Name == "mipsel")
117 if (Name == "msp430")
127 if (Name == "systemz")
135 if (Name == "x86-64")
143 Triple::ArchType Triple::getArchTypeForDarwinArchName(const StringRef &Str) {
144 // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
145 // archs which Darwin doesn't use.
147 // The matching this routine does is fairly pointless, since it is neither the
148 // complete architecture list, nor a reasonable subset. The problem is that
149 // historically the driver driver accepts this and also ties its -march=
150 // handling to the architecture name, so we need to be careful before removing
153 // This code must be kept in sync with Clang's Darwin specific argument
156 if (Str == "ppc" || Str == "ppc601" || Str == "ppc603" || Str == "ppc604" ||
157 Str == "ppc604e" || Str == "ppc750" || Str == "ppc7400" ||
158 Str == "ppc7450" || Str == "ppc970")
162 return Triple::ppc64;
164 if (Str == "i386" || Str == "i486" || Str == "i486SX" || Str == "pentium" ||
165 Str == "i586" || Str == "pentpro" || Str == "i686" || Str == "pentIIm3" ||
166 Str == "pentIIm5" || Str == "pentium4")
170 return Triple::x86_64;
172 // This is derived from the driver driver.
173 if (Str == "arm" || Str == "armv4t" || Str == "armv5" || Str == "xscale" ||
174 Str == "armv6" || Str == "armv7")
177 return Triple::UnknownArch;
182 void Triple::Parse() const {
183 assert(!isInitialized() && "Invalid parse call.");
185 StringRef ArchName = getArchName();
186 StringRef VendorName = getVendorName();
187 StringRef OSName = getOSName();
189 if (ArchName.size() == 4 && ArchName[0] == 'i' &&
190 ArchName[2] == '8' && ArchName[3] == '6' &&
191 ArchName[1] - '3' < 6) // i[3-9]86
193 else if (ArchName == "amd64" || ArchName == "x86_64")
195 else if (ArchName == "bfin")
197 else if (ArchName == "pic16")
199 else if (ArchName == "powerpc")
201 else if (ArchName == "powerpc64")
203 else if (ArchName == "arm" ||
204 ArchName.startswith("armv") ||
205 ArchName == "xscale")
207 else if (ArchName == "thumb" ||
208 ArchName.startswith("thumbv"))
210 else if (ArchName.startswith("alpha"))
212 else if (ArchName == "spu" || ArchName == "cellspu")
214 else if (ArchName == "msp430")
216 else if (ArchName == "mips" || ArchName == "mipsallegrex")
218 else if (ArchName == "mipsel" || ArchName == "mipsallegrexel" ||
221 else if (ArchName == "sparc")
223 else if (ArchName == "s390x")
225 else if (ArchName == "tce")
227 else if (ArchName == "xcore")
233 // Handle some exceptional cases where the OS / environment components are
234 // stuck into the vendor field.
235 if (StringRef(getTriple()).count('-') == 1) {
236 StringRef VendorName = getVendorName();
238 if (VendorName.startswith("mingw32")) { // 'i386-mingw32', etc.
244 // arm-elf is another example, but we don't currently parse anything about
248 if (VendorName == "apple")
250 else if (VendorName == "pc")
253 Vendor = UnknownVendor;
255 if (OSName.startswith("auroraux"))
257 else if (OSName.startswith("cygwin"))
259 else if (OSName.startswith("darwin"))
261 else if (OSName.startswith("dragonfly"))
263 else if (OSName.startswith("freebsd"))
265 else if (OSName.startswith("linux"))
267 else if (OSName.startswith("mingw32"))
269 else if (OSName.startswith("mingw64"))
271 else if (OSName.startswith("netbsd"))
273 else if (OSName.startswith("openbsd"))
275 else if (OSName.startswith("solaris"))
277 else if (OSName.startswith("win32"))
282 assert(isInitialized() && "Failed to initialize!");
285 StringRef Triple::getArchName() const {
286 return StringRef(Data).split('-').first; // Isolate first component
289 StringRef Triple::getVendorName() const {
290 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
291 return Tmp.split('-').first; // Isolate second component
294 StringRef Triple::getOSName() const {
295 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
296 Tmp = Tmp.split('-').second; // Strip second component
297 return Tmp.split('-').first; // Isolate third component
300 StringRef Triple::getEnvironmentName() const {
301 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
302 Tmp = Tmp.split('-').second; // Strip second component
303 return Tmp.split('-').second; // Strip third component
306 StringRef Triple::getOSAndEnvironmentName() const {
307 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
308 return Tmp.split('-').second; // Strip second component
311 static unsigned EatNumber(StringRef &Str) {
312 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
313 unsigned Result = Str[0]-'0';
318 // Handle "darwin11".
319 if (Result == 1 && !Str.empty() && Str[0] >= '0' && Str[0] <= '9') {
320 Result = Result*10 + (Str[0] - '0');
328 /// getDarwinNumber - Parse the 'darwin number' out of the specific target
329 /// triple. For example, if we have darwin8.5 return 8,5,0. If any entry is
330 /// not defined, return 0's. This requires that the triple have an OSType of
331 /// darwin before it is called.
332 void Triple::getDarwinNumber(unsigned &Maj, unsigned &Min,
333 unsigned &Revision) const {
334 assert(getOS() == Darwin && "Not a darwin target triple!");
335 StringRef OSName = getOSName();
336 assert(OSName.startswith("darwin") && "Unknown darwin target triple!");
338 // Strip off "darwin".
339 OSName = OSName.substr(6);
341 Maj = Min = Revision = 0;
343 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
346 // The major version is the first digit.
347 Maj = EatNumber(OSName);
348 if (OSName.empty()) return;
350 // Handle minor version: 10.4.9 -> darwin8.9.
351 if (OSName[0] != '.')
355 OSName = OSName.substr(1);
357 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
360 Min = EatNumber(OSName);
361 if (OSName.empty()) return;
363 // Handle revision darwin8.9.1
364 if (OSName[0] != '.')
368 OSName = OSName.substr(1);
370 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
373 Revision = EatNumber(OSName);
376 void Triple::setTriple(const Twine &Str) {
381 void Triple::setArch(ArchType Kind) {
382 setArchName(getArchTypeName(Kind));
385 void Triple::setVendor(VendorType Kind) {
386 setVendorName(getVendorTypeName(Kind));
389 void Triple::setOS(OSType Kind) {
390 setOSName(getOSTypeName(Kind));
393 void Triple::setArchName(const StringRef &Str) {
394 // Work around a miscompilation bug for Twines in gcc 4.0.3.
395 SmallString<64> Triple;
398 Triple += getVendorName();
400 Triple += getOSAndEnvironmentName();
401 setTriple(Triple.str());
404 void Triple::setVendorName(const StringRef &Str) {
405 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
408 void Triple::setOSName(const StringRef &Str) {
409 if (hasEnvironment())
410 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
411 "-" + getEnvironmentName());
413 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
416 void Triple::setEnvironmentName(const StringRef &Str) {
417 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
421 void Triple::setOSAndEnvironmentName(const StringRef &Str) {
422 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);