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/Twine.h"
19 const char *Triple::getArchTypeName(ArchType Kind) {
21 case InvalidArch: return "<invalid>";
22 case UnknownArch: return "unknown";
24 case alpha: return "alpha";
25 case arm: return "arm";
26 case bfin: return "bfin";
27 case cellspu: return "cellspu";
28 case mips: return "mips";
29 case mipsel: return "mipsel";
30 case msp430: return "msp430";
31 case pic16: return "pic16";
32 case ppc64: return "powerpc64";
33 case ppc: return "powerpc";
34 case sparc: return "sparc";
35 case systemz: return "s390x";
36 case tce: return "tce";
37 case thumb: return "thumb";
38 case x86: return "i386";
39 case x86_64: return "x86_64";
40 case xcore: return "xcore";
46 const char *Triple::getArchTypePrefix(ArchType Kind) {
51 case alpha: return "alpha";
54 case thumb: return "arm";
56 case bfin: return "bfin";
58 case cellspu: return "spu";
61 case ppc: return "ppc";
63 case sparc: return "sparc";
66 case x86_64: return "x86";
67 case xcore: return "xcore";
71 const char *Triple::getVendorTypeName(VendorType Kind) {
73 case UnknownVendor: return "unknown";
75 case Apple: return "apple";
82 const char *Triple::getOSTypeName(OSType Kind) {
84 case UnknownOS: return "unknown";
86 case AuroraUX: return "auroraux";
87 case Cygwin: return "cygwin";
88 case Darwin: return "darwin";
89 case DragonFly: return "dragonfly";
90 case FreeBSD: return "freebsd";
91 case Linux: return "linux";
92 case MinGW32: return "mingw32";
93 case MinGW64: return "mingw64";
94 case NetBSD: return "netbsd";
95 case OpenBSD: return "openbsd";
96 case Solaris: return "solaris";
97 case Win32: return "win32";
103 Triple::ArchType Triple::getArchTypeForLLVMName(const StringRef &Name) {
110 if (Name == "cellspu")
114 if (Name == "mipsel")
116 if (Name == "msp430")
126 if (Name == "systemz")
134 if (Name == "x86-64")
142 Triple::ArchType Triple::getArchTypeForDarwinArchName(const StringRef &Str) {
143 // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
144 // archs which Darwin doesn't use.
146 // The matching this routine does is fairly pointless, since it is neither the
147 // complete architecture list, nor a reasonable subset. The problem is that
148 // historically the driver driver accepts this and also ties its -march=
149 // handling to the architecture name, so we need to be careful before removing
152 if (Str == "ppc" || Str == "ppc601" || Str == "ppc603" || Str == "ppc604" ||
153 Str == "ppc604e" || Str == "ppc750" || Str == "ppc7400" ||
154 Str == "ppc7450" || Str == "ppc970")
158 return Triple::ppc64;
160 if (Str == "i386" || Str == "i486" || Str == "i486SX" || Str == "pentium" ||
161 Str == "i586" || Str == "pentpro" || Str == "i686" || Str == "pentIIm3" ||
162 Str == "pentIIm5" || Str == "pentium4")
166 return Triple::x86_64;
168 // This is derived from the driver driver.
169 if (Str == "arm" || Str == "armv4t" || Str == "armv5" || Str == "xscale" ||
170 Str == "armv6" || Str == "armv7")
173 return Triple::UnknownArch;
178 void Triple::Parse() const {
179 assert(!isInitialized() && "Invalid parse call.");
181 StringRef ArchName = getArchName();
182 StringRef VendorName = getVendorName();
183 StringRef OSName = getOSName();
185 if (ArchName.size() == 4 && ArchName[0] == 'i' &&
186 ArchName[2] == '8' && ArchName[3] == '6' &&
187 ArchName[1] - '3' < 6) // i[3-9]86
189 else if (ArchName == "amd64" || ArchName == "x86_64")
191 else if (ArchName == "bfin")
193 else if (ArchName == "pic16")
195 else if (ArchName == "powerpc")
197 else if (ArchName == "powerpc64")
199 else if (ArchName == "arm" ||
200 ArchName.startswith("armv") ||
201 ArchName == "xscale")
203 else if (ArchName == "thumb" ||
204 ArchName.startswith("thumbv"))
206 else if (ArchName.startswith("alpha"))
208 else if (ArchName == "spu" || ArchName == "cellspu")
210 else if (ArchName == "msp430")
212 else if (ArchName == "mips" || ArchName == "mipsallegrex")
214 else if (ArchName == "mipsel" || ArchName == "mipsallegrexel" ||
217 else if (ArchName == "sparc")
219 else if (ArchName == "s390x")
221 else if (ArchName == "tce")
223 else if (ArchName == "xcore")
229 // Handle some exceptional cases where the OS / environment components are
230 // stuck into the vendor field.
231 if (StringRef(getTriple()).count('-') == 1) {
232 StringRef VendorName = getVendorName();
234 if (VendorName.startswith("mingw32")) { // 'i386-mingw32', etc.
240 // arm-elf is another example, but we don't currently parse anything about
244 if (VendorName == "apple")
246 else if (VendorName == "pc")
249 Vendor = UnknownVendor;
251 if (OSName.startswith("auroraux"))
253 else if (OSName.startswith("cygwin"))
255 else if (OSName.startswith("darwin"))
257 else if (OSName.startswith("dragonfly"))
259 else if (OSName.startswith("freebsd"))
261 else if (OSName.startswith("linux"))
263 else if (OSName.startswith("mingw32"))
265 else if (OSName.startswith("mingw64"))
267 else if (OSName.startswith("netbsd"))
269 else if (OSName.startswith("openbsd"))
271 else if (OSName.startswith("solaris"))
273 else if (OSName.startswith("win32"))
278 assert(isInitialized() && "Failed to initialize!");
281 StringRef Triple::getArchName() const {
282 return StringRef(Data).split('-').first; // Isolate first component
285 StringRef Triple::getVendorName() const {
286 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
287 return Tmp.split('-').first; // Isolate second component
290 StringRef Triple::getOSName() const {
291 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
292 Tmp = Tmp.split('-').second; // Strip second component
293 return Tmp.split('-').first; // Isolate third component
296 StringRef Triple::getEnvironmentName() const {
297 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
298 Tmp = Tmp.split('-').second; // Strip second component
299 return Tmp.split('-').second; // Strip third component
302 StringRef Triple::getOSAndEnvironmentName() const {
303 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
304 return Tmp.split('-').second; // Strip second component
307 static unsigned EatNumber(StringRef &Str) {
308 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
309 unsigned Result = Str[0]-'0';
314 // Handle "darwin11".
315 if (Result == 1 && !Str.empty() && Str[0] >= '0' && Str[0] <= '9') {
316 Result = Result*10 + (Str[0] - '0');
324 /// getDarwinNumber - Parse the 'darwin number' out of the specific target
325 /// triple. For example, if we have darwin8.5 return 8,5,0. If any entry is
326 /// not defined, return 0's. This requires that the triple have an OSType of
327 /// darwin before it is called.
328 void Triple::getDarwinNumber(unsigned &Maj, unsigned &Min,
329 unsigned &Revision) const {
330 assert(getOS() == Darwin && "Not a darwin target triple!");
331 StringRef OSName = getOSName();
332 assert(OSName.startswith("darwin") && "Unknown darwin target triple!");
334 // Strip off "darwin".
335 OSName = OSName.substr(6);
337 Maj = Min = Revision = 0;
339 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
342 // The major version is the first digit.
343 Maj = EatNumber(OSName);
344 if (OSName.empty()) return;
346 // Handle minor version: 10.4.9 -> darwin8.9.
347 if (OSName[0] != '.')
351 OSName = OSName.substr(1);
353 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
356 Min = EatNumber(OSName);
357 if (OSName.empty()) return;
359 // Handle revision darwin8.9.1
360 if (OSName[0] != '.')
364 OSName = OSName.substr(1);
366 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
369 Revision = EatNumber(OSName);
372 void Triple::setTriple(const Twine &Str) {
377 void Triple::setArch(ArchType Kind) {
378 setArchName(getArchTypeName(Kind));
381 void Triple::setVendor(VendorType Kind) {
382 setVendorName(getVendorTypeName(Kind));
385 void Triple::setOS(OSType Kind) {
386 setOSName(getOSTypeName(Kind));
389 void Triple::setArchName(const StringRef &Str) {
390 setTriple(Str + "-" + getVendorName() + "-" + getOSAndEnvironmentName());
393 void Triple::setVendorName(const StringRef &Str) {
394 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
397 void Triple::setOSName(const StringRef &Str) {
398 if (hasEnvironment())
399 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
400 "-" + getEnvironmentName());
402 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
405 void Triple::setEnvironmentName(const StringRef &Str) {
406 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
410 void Triple::setOSAndEnvironmentName(const StringRef &Str) {
411 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);