Add llvm::Triple::getArchTypePrefix for getting the intrinsic prefix for an
[oota-llvm.git] / lib / Support / Triple.cpp
1 //===--- Triple.cpp - Target triple helper class --------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "llvm/ADT/Triple.h"
11
12 #include "llvm/ADT/Twine.h"
13 #include <cassert>
14 #include <cstring>
15 using namespace llvm;
16
17 //
18
19 const char *Triple::getArchTypeName(ArchType Kind) {
20   switch (Kind) {
21   case InvalidArch: return "<invalid>";
22   case UnknownArch: return "unknown";
23     
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";
41   }
42
43   return "<invalid>";
44 }
45
46 const char *Triple::getArchTypePrefix(ArchType Kind) {
47   switch (Kind) {
48   default:
49     return 0;
50
51   case alpha:   return "alpha";
52
53   case arm:
54   case thumb:   return "arm";
55
56   case bfin:    return "bfin";
57
58   case cellspu: return "spu";
59
60   case ppc64:
61   case ppc:     return "ppc";
62
63   case sparc:   return "sparc";
64
65   case x86:
66   case x86_64:  return "x86";
67   case xcore:   return "xcore";
68   }
69 }
70
71 const char *Triple::getVendorTypeName(VendorType Kind) {
72   switch (Kind) {
73   case UnknownVendor: return "unknown";
74
75   case Apple: return "apple";
76   case PC: return "pc";
77   }
78
79   return "<invalid>";
80 }
81
82 const char *Triple::getOSTypeName(OSType Kind) {
83   switch (Kind) {
84   case UnknownOS: return "unknown";
85
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";
98   }
99
100   return "<invalid>";
101 }
102
103 Triple::ArchType Triple::getArchTypeForLLVMName(const StringRef &Name) {
104   if (Name == "alpha")
105     return alpha;
106   if (Name == "arm")
107     return arm;
108   if (Name == "bfin")
109     return bfin;
110   if (Name == "cellspu")
111     return cellspu;
112   if (Name == "mips")
113     return mips;
114   if (Name == "mipsel")
115     return mipsel;
116   if (Name == "msp430")
117     return msp430;
118   if (Name == "pic16")
119     return pic16;
120   if (Name == "ppc64")
121     return ppc64;
122   if (Name == "ppc")
123     return ppc;
124   if (Name == "sparc")
125     return sparc;
126   if (Name == "systemz")
127     return systemz;
128   if (Name == "tce")
129     return tce;
130   if (Name == "thumb")
131     return thumb;
132   if (Name == "x86")
133     return x86;
134   if (Name == "x86-64")
135     return x86_64;
136   if (Name == "xcore")
137     return xcore;
138
139   return UnknownArch;
140 }
141
142 //
143
144 void Triple::Parse() const {
145   assert(!isInitialized() && "Invalid parse call.");
146
147   StringRef ArchName = getArchName();
148   StringRef VendorName = getVendorName();
149   StringRef OSName = getOSName();
150
151   if (ArchName.size() == 4 && ArchName[0] == 'i' && 
152       ArchName[2] == '8' && ArchName[3] == '6' && 
153       ArchName[1] - '3' < 6) // i[3-9]86
154     Arch = x86;
155   else if (ArchName == "amd64" || ArchName == "x86_64")
156     Arch = x86_64;
157   else if (ArchName == "bfin")
158     Arch = bfin;
159   else if (ArchName == "pic16")
160     Arch = pic16;
161   else if (ArchName == "powerpc")
162     Arch = ppc;
163   else if (ArchName == "powerpc64")
164     Arch = ppc64;
165   else if (ArchName == "arm" ||
166            ArchName.startswith("armv") ||
167            ArchName == "xscale")
168     Arch = arm;
169   else if (ArchName == "thumb" ||
170            ArchName.startswith("thumbv"))
171     Arch = thumb;
172   else if (ArchName.startswith("alpha"))
173     Arch = alpha;
174   else if (ArchName == "spu" || ArchName == "cellspu")
175     Arch = cellspu;
176   else if (ArchName == "msp430")
177     Arch = msp430;
178   else if (ArchName == "mips" || ArchName == "mipsallegrex")
179     Arch = mips;
180   else if (ArchName == "mipsel" || ArchName == "mipsallegrexel" ||
181            ArchName == "psp")
182     Arch = mipsel;
183   else if (ArchName == "sparc")
184     Arch = sparc;
185   else if (ArchName == "s390x")
186     Arch = systemz;
187   else if (ArchName == "tce")
188     Arch = tce;
189   else
190     Arch = UnknownArch;
191
192
193   // Handle some exceptional cases where the OS / environment components are
194   // stuck into the vendor field.
195   if (StringRef(getTriple()).count('-') == 1) {
196     StringRef VendorName = getVendorName();
197
198     if (VendorName.startswith("mingw32")) { // 'i386-mingw32', etc.
199       Vendor = PC;
200       OS = MinGW32;
201       return;
202     }
203
204     // arm-elf is another example, but we don't currently parse anything about
205     // the environment.
206   }
207
208   if (VendorName == "apple")
209     Vendor = Apple;
210   else if (VendorName == "pc")
211     Vendor = PC;
212   else
213     Vendor = UnknownVendor;
214
215   if (OSName.startswith("auroraux"))
216     OS = AuroraUX;
217   else if (OSName.startswith("cygwin"))
218     OS = Cygwin;
219   else if (OSName.startswith("darwin"))
220     OS = Darwin;
221   else if (OSName.startswith("dragonfly"))
222     OS = DragonFly;
223   else if (OSName.startswith("freebsd"))
224     OS = FreeBSD;
225   else if (OSName.startswith("linux"))
226     OS = Linux;
227   else if (OSName.startswith("mingw32"))
228     OS = MinGW32;
229   else if (OSName.startswith("mingw64"))
230     OS = MinGW64;
231   else if (OSName.startswith("netbsd"))
232     OS = NetBSD;
233   else if (OSName.startswith("openbsd"))
234     OS = OpenBSD;
235   else if (OSName.startswith("solaris"))
236     OS = Solaris;
237   else if (OSName.startswith("win32"))
238     OS = Win32;
239   else
240     OS = UnknownOS;
241
242   assert(isInitialized() && "Failed to initialize!");
243 }
244
245 StringRef Triple::getArchName() const {
246   return StringRef(Data).split('-').first;           // Isolate first component
247 }
248
249 StringRef Triple::getVendorName() const {
250   StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
251   return Tmp.split('-').first;                       // Isolate second component
252 }
253
254 StringRef Triple::getOSName() const {
255   StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
256   Tmp = Tmp.split('-').second;                       // Strip second component
257   return Tmp.split('-').first;                       // Isolate third component
258 }
259
260 StringRef Triple::getEnvironmentName() const {
261   StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
262   Tmp = Tmp.split('-').second;                       // Strip second component
263   return Tmp.split('-').second;                      // Strip third component
264 }
265
266 StringRef Triple::getOSAndEnvironmentName() const {
267   StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
268   return Tmp.split('-').second;                      // Strip second component
269 }
270
271 static unsigned EatNumber(StringRef &Str) {
272   assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
273   unsigned Result = Str[0]-'0';
274   
275   // Eat the digit.
276   Str = Str.substr(1);
277   
278   // Handle "darwin11".
279   if (Result == 1 && !Str.empty() && Str[0] >= '0' && Str[0] <= '9') {
280     Result = Result*10 + (Str[0] - '0');
281     // Eat the digit.
282     Str = Str.substr(1);
283   }
284   
285   return Result;
286 }
287
288 /// getDarwinNumber - Parse the 'darwin number' out of the specific target
289 /// triple.  For example, if we have darwin8.5 return 8,5,0.  If any entry is
290 /// not defined, return 0's.  This requires that the triple have an OSType of
291 /// darwin before it is called.
292 void Triple::getDarwinNumber(unsigned &Maj, unsigned &Min,
293                              unsigned &Revision) const {
294   assert(getOS() == Darwin && "Not a darwin target triple!");
295   StringRef OSName = getOSName();
296   assert(OSName.startswith("darwin") && "Unknown darwin target triple!");
297   
298   // Strip off "darwin".
299   OSName = OSName.substr(6);
300   
301   Maj = Min = Revision = 0;
302
303   if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
304     return;
305
306   // The major version is the first digit.
307   Maj = EatNumber(OSName);
308   if (OSName.empty()) return;
309   
310   // Handle minor version: 10.4.9 -> darwin8.9.
311   if (OSName[0] != '.')
312     return;
313   
314   // Eat the '.'.
315   OSName = OSName.substr(1);
316
317   if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
318     return;
319   
320   Min = EatNumber(OSName);
321   if (OSName.empty()) return;
322
323   // Handle revision darwin8.9.1
324   if (OSName[0] != '.')
325     return;
326   
327   // Eat the '.'.
328   OSName = OSName.substr(1);
329   
330   if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
331     return;
332
333   Revision = EatNumber(OSName);
334 }
335
336 void Triple::setTriple(const Twine &Str) {
337   Data = Str.str();
338   Arch = InvalidArch;
339 }
340
341 void Triple::setArch(ArchType Kind) {
342   setArchName(getArchTypeName(Kind));
343 }
344
345 void Triple::setVendor(VendorType Kind) {
346   setVendorName(getVendorTypeName(Kind));
347 }
348
349 void Triple::setOS(OSType Kind) {
350   setOSName(getOSTypeName(Kind));
351 }
352
353 void Triple::setArchName(const StringRef &Str) {
354   setTriple(Str + "-" + getVendorName() + "-" + getOSAndEnvironmentName());
355 }
356
357 void Triple::setVendorName(const StringRef &Str) {
358   setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
359 }
360
361 void Triple::setOSName(const StringRef &Str) {
362   if (hasEnvironment())
363     setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
364               "-" + getEnvironmentName());
365   else
366     setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
367 }
368
369 void Triple::setEnvironmentName(const StringRef &Str) {
370   setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() + 
371             "-" + Str);
372 }
373
374 void Triple::setOSAndEnvironmentName(const StringRef &Str) {
375   setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
376 }