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 thumb: return "thumb";
37 case x86: return "i386";
38 case x86_64: return "x86_64";
39 case xcore: return "xcore";
45 const char *Triple::getVendorTypeName(VendorType Kind) {
47 case UnknownVendor: return "unknown";
49 case Apple: return "apple";
56 const char *Triple::getOSTypeName(OSType Kind) {
58 case UnknownOS: return "unknown";
60 case AuroraUX: return "auroraux";
61 case Cygwin: return "cygwin";
62 case Darwin: return "darwin";
63 case DragonFly: return "dragonfly";
64 case FreeBSD: return "freebsd";
65 case Linux: return "linux";
66 case MinGW32: return "mingw32";
67 case MinGW64: return "mingw64";
68 case NetBSD: return "netbsd";
69 case OpenBSD: return "openbsd";
70 case Solaris: return "solaris";
71 case Win32: return "win32";
77 Triple::ArchType Triple::getArchTypeForLLVMName(const StringRef &Name) {
84 if (Name == "cellspu")
100 if (Name == "systemz")
106 if (Name == "x86-64")
116 void Triple::Parse() const {
117 assert(!isInitialized() && "Invalid parse call.");
119 StringRef ArchName = getArchName();
120 StringRef VendorName = getVendorName();
121 StringRef OSName = getOSName();
123 if (ArchName.size() == 4 && ArchName[0] == 'i' &&
124 ArchName[2] == '8' && ArchName[3] == '6' &&
125 ArchName[1] - '3' < 6) // i[3-9]86
127 else if (ArchName == "amd64" || ArchName == "x86_64")
129 else if (ArchName == "bfin")
131 else if (ArchName == "pic16")
133 else if (ArchName == "powerpc")
135 else if (ArchName == "powerpc64")
137 else if (ArchName == "arm" ||
138 ArchName.startswith("armv") ||
139 ArchName == "xscale")
141 else if (ArchName == "thumb" ||
142 ArchName.startswith("thumbv"))
144 else if (ArchName.startswith("alpha"))
146 else if (ArchName == "spu" || ArchName == "cellspu")
148 else if (ArchName == "msp430")
150 else if (ArchName == "mips" || ArchName == "mipsallegrex")
152 else if (ArchName == "mipsel" || ArchName == "mipsallegrexel" ||
155 else if (ArchName == "sparc")
157 else if (ArchName == "s390x")
163 // Handle some exceptional cases where the OS / environment components are
164 // stuck into the vendor field.
165 if (StringRef(getTriple()).count('-') == 1) {
166 StringRef VendorName = getVendorName();
168 if (VendorName.startswith("mingw32")) { // 'i386-mingw32', etc.
174 // arm-elf is another example, but we don't currently parse anything about
178 if (VendorName == "apple")
180 else if (VendorName == "pc")
183 Vendor = UnknownVendor;
185 if (OSName.startswith("auroraux"))
187 else if (OSName.startswith("cygwin"))
189 else if (OSName.startswith("darwin"))
191 else if (OSName.startswith("dragonfly"))
193 else if (OSName.startswith("freebsd"))
195 else if (OSName.startswith("linux"))
197 else if (OSName.startswith("mingw32"))
199 else if (OSName.startswith("mingw64"))
201 else if (OSName.startswith("netbsd"))
203 else if (OSName.startswith("openbsd"))
205 else if (OSName.startswith("solaris"))
207 else if (OSName.startswith("win32"))
212 assert(isInitialized() && "Failed to initialize!");
215 StringRef Triple::getArchName() const {
216 return StringRef(Data).split('-').first; // Isolate first component
219 StringRef Triple::getVendorName() const {
220 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
221 return Tmp.split('-').first; // Isolate second component
224 StringRef Triple::getOSName() const {
225 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
226 Tmp = Tmp.split('-').second; // Strip second component
227 return Tmp.split('-').first; // Isolate third component
230 StringRef Triple::getEnvironmentName() const {
231 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
232 Tmp = Tmp.split('-').second; // Strip second component
233 return Tmp.split('-').second; // Strip third component
236 StringRef Triple::getOSAndEnvironmentName() const {
237 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
238 return Tmp.split('-').second; // Strip second component
241 static unsigned EatNumber(StringRef &Str) {
242 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
243 unsigned Result = Str[0]-'0';
248 // Handle "darwin11".
249 if (Result == 1 && !Str.empty() && Str[0] >= '0' && Str[0] <= '9') {
250 Result = Result*10 + (Str[0] - '0');
258 /// getDarwinNumber - Parse the 'darwin number' out of the specific target
259 /// triple. For example, if we have darwin8.5 return 8,5,0. If any entry is
260 /// not defined, return 0's. This requires that the triple have an OSType of
261 /// darwin before it is called.
262 void Triple::getDarwinNumber(unsigned &Maj, unsigned &Min,
263 unsigned &Revision) const {
264 assert(getOS() == Darwin && "Not a darwin target triple!");
265 StringRef OSName = getOSName();
266 assert(OSName.startswith("darwin") && "Unknown darwin target triple!");
268 // Strip off "darwin".
269 OSName = OSName.substr(6);
271 Maj = Min = Revision = 0;
273 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
276 // The major version is the first digit.
277 Maj = EatNumber(OSName);
278 if (OSName.empty()) return;
280 // Handle minor version: 10.4.9 -> darwin8.9.
281 if (OSName[0] != '.')
285 OSName = OSName.substr(1);
287 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
290 Min = EatNumber(OSName);
291 if (OSName.empty()) return;
293 // Handle revision darwin8.9.1
294 if (OSName[0] != '.')
298 OSName = OSName.substr(1);
300 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
303 Revision = EatNumber(OSName);
306 void Triple::setTriple(const Twine &Str) {
311 void Triple::setArch(ArchType Kind) {
312 setArchName(getArchTypeName(Kind));
315 void Triple::setVendor(VendorType Kind) {
316 setVendorName(getVendorTypeName(Kind));
319 void Triple::setOS(OSType Kind) {
320 setOSName(getOSTypeName(Kind));
323 void Triple::setArchName(const StringRef &Str) {
324 setTriple(Str + "-" + getVendorName() + "-" + getOSAndEnvironmentName());
327 void Triple::setVendorName(const StringRef &Str) {
328 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
331 void Triple::setOSName(const StringRef &Str) {
332 if (hasEnvironment())
333 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
334 "-" + getEnvironmentName());
336 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
339 void Triple::setEnvironmentName(const StringRef &Str) {
340 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
344 void Triple::setOSAndEnvironmentName(const StringRef &Str) {
345 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);