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 // This code must be kept in sync with Clang's Darwin specific argument
155 if (Str
== "ppc" || Str
== "ppc601" || Str
== "ppc603" || Str
== "ppc604" ||
156 Str
== "ppc604e" || Str
== "ppc750" || Str
== "ppc7400" ||
157 Str
== "ppc7450" || Str
== "ppc970")
161 return Triple::ppc64
;
163 if (Str
== "i386" || Str
== "i486" || Str
== "i486SX" || Str
== "pentium" ||
164 Str
== "i586" || Str
== "pentpro" || Str
== "i686" || Str
== "pentIIm3" ||
165 Str
== "pentIIm5" || Str
== "pentium4")
169 return Triple::x86_64
;
171 // This is derived from the driver driver.
172 if (Str
== "arm" || Str
== "armv4t" || Str
== "armv5" || Str
== "xscale" ||
173 Str
== "armv6" || Str
== "armv7")
176 return Triple::UnknownArch
;
181 void Triple::Parse() const {
182 assert(!isInitialized() && "Invalid parse call.");
184 StringRef ArchName
= getArchName();
185 StringRef VendorName
= getVendorName();
186 StringRef OSName
= getOSName();
188 if (ArchName
.size() == 4 && ArchName
[0] == 'i' &&
189 ArchName
[2] == '8' && ArchName
[3] == '6' &&
190 ArchName
[1] - '3' < 6) // i[3-9]86
192 else if (ArchName
== "amd64" || ArchName
== "x86_64")
194 else if (ArchName
== "bfin")
196 else if (ArchName
== "pic16")
198 else if (ArchName
== "powerpc")
200 else if (ArchName
== "powerpc64")
202 else if (ArchName
== "arm" ||
203 ArchName
.startswith("armv") ||
204 ArchName
== "xscale")
206 else if (ArchName
== "thumb" ||
207 ArchName
.startswith("thumbv"))
209 else if (ArchName
.startswith("alpha"))
211 else if (ArchName
== "spu" || ArchName
== "cellspu")
213 else if (ArchName
== "msp430")
215 else if (ArchName
== "mips" || ArchName
== "mipsallegrex")
217 else if (ArchName
== "mipsel" || ArchName
== "mipsallegrexel" ||
220 else if (ArchName
== "sparc")
222 else if (ArchName
== "s390x")
224 else if (ArchName
== "tce")
226 else if (ArchName
== "xcore")
232 // Handle some exceptional cases where the OS / environment components are
233 // stuck into the vendor field.
234 if (StringRef(getTriple()).count('-') == 1) {
235 StringRef VendorName
= getVendorName();
237 if (VendorName
.startswith("mingw32")) { // 'i386-mingw32', etc.
243 // arm-elf is another example, but we don't currently parse anything about
247 if (VendorName
== "apple")
249 else if (VendorName
== "pc")
252 Vendor
= UnknownVendor
;
254 if (OSName
.startswith("auroraux"))
256 else if (OSName
.startswith("cygwin"))
258 else if (OSName
.startswith("darwin"))
260 else if (OSName
.startswith("dragonfly"))
262 else if (OSName
.startswith("freebsd"))
264 else if (OSName
.startswith("linux"))
266 else if (OSName
.startswith("mingw32"))
268 else if (OSName
.startswith("mingw64"))
270 else if (OSName
.startswith("netbsd"))
272 else if (OSName
.startswith("openbsd"))
274 else if (OSName
.startswith("solaris"))
276 else if (OSName
.startswith("win32"))
281 assert(isInitialized() && "Failed to initialize!");
284 StringRef
Triple::getArchName() const {
285 return StringRef(Data
).split('-').first
; // Isolate first component
288 StringRef
Triple::getVendorName() const {
289 StringRef Tmp
= StringRef(Data
).split('-').second
; // Strip first component
290 return Tmp
.split('-').first
; // Isolate second component
293 StringRef
Triple::getOSName() const {
294 StringRef Tmp
= StringRef(Data
).split('-').second
; // Strip first component
295 Tmp
= Tmp
.split('-').second
; // Strip second component
296 return Tmp
.split('-').first
; // Isolate third component
299 StringRef
Triple::getEnvironmentName() const {
300 StringRef Tmp
= StringRef(Data
).split('-').second
; // Strip first component
301 Tmp
= Tmp
.split('-').second
; // Strip second component
302 return Tmp
.split('-').second
; // Strip third component
305 StringRef
Triple::getOSAndEnvironmentName() const {
306 StringRef Tmp
= StringRef(Data
).split('-').second
; // Strip first component
307 return Tmp
.split('-').second
; // Strip second component
310 static unsigned EatNumber(StringRef
&Str
) {
311 assert(!Str
.empty() && Str
[0] >= '0' && Str
[0] <= '9' && "Not a number");
312 unsigned Result
= Str
[0]-'0';
317 // Handle "darwin11".
318 if (Result
== 1 && !Str
.empty() && Str
[0] >= '0' && Str
[0] <= '9') {
319 Result
= Result
*10 + (Str
[0] - '0');
327 /// getDarwinNumber - Parse the 'darwin number' out of the specific target
328 /// triple. For example, if we have darwin8.5 return 8,5,0. If any entry is
329 /// not defined, return 0's. This requires that the triple have an OSType of
330 /// darwin before it is called.
331 void Triple::getDarwinNumber(unsigned &Maj
, unsigned &Min
,
332 unsigned &Revision
) const {
333 assert(getOS() == Darwin
&& "Not a darwin target triple!");
334 StringRef OSName
= getOSName();
335 assert(OSName
.startswith("darwin") && "Unknown darwin target triple!");
337 // Strip off "darwin".
338 OSName
= OSName
.substr(6);
340 Maj
= Min
= Revision
= 0;
342 if (OSName
.empty() || OSName
[0] < '0' || OSName
[0] > '9')
345 // The major version is the first digit.
346 Maj
= EatNumber(OSName
);
347 if (OSName
.empty()) return;
349 // Handle minor version: 10.4.9 -> darwin8.9.
350 if (OSName
[0] != '.')
354 OSName
= OSName
.substr(1);
356 if (OSName
.empty() || OSName
[0] < '0' || OSName
[0] > '9')
359 Min
= EatNumber(OSName
);
360 if (OSName
.empty()) return;
362 // Handle revision darwin8.9.1
363 if (OSName
[0] != '.')
367 OSName
= OSName
.substr(1);
369 if (OSName
.empty() || OSName
[0] < '0' || OSName
[0] > '9')
372 Revision
= EatNumber(OSName
);
375 void Triple::setTriple(const Twine
&Str
) {
380 void Triple::setArch(ArchType Kind
) {
381 setArchName(getArchTypeName(Kind
));
384 void Triple::setVendor(VendorType Kind
) {
385 setVendorName(getVendorTypeName(Kind
));
388 void Triple::setOS(OSType Kind
) {
389 setOSName(getOSTypeName(Kind
));
392 void Triple::setArchName(const StringRef
&Str
) {
393 setTriple(Str
+ "-" + getVendorName() + "-" + getOSAndEnvironmentName());
396 void Triple::setVendorName(const StringRef
&Str
) {
397 setTriple(getArchName() + "-" + Str
+ "-" + getOSAndEnvironmentName());
400 void Triple::setOSName(const StringRef
&Str
) {
401 if (hasEnvironment())
402 setTriple(getArchName() + "-" + getVendorName() + "-" + Str
+
403 "-" + getEnvironmentName());
405 setTriple(getArchName() + "-" + getVendorName() + "-" + Str
);
408 void Triple::setEnvironmentName(const StringRef
&Str
) {
409 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
413 void Triple::setOSAndEnvironmentName(const StringRef
&Str
) {
414 setTriple(getArchName() + "-" + getVendorName() + "-" + Str
);