fix "pc" to be lower case in a target triple, patch by Yonggang Luo
[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 ppc64:   return "powerpc64";
32   case ppc:     return "powerpc";
33   case sparc:   return "sparc";
34   case systemz: return "s390x";
35   case thumb:   return "thumb";
36   case x86:     return "i386";
37   case x86_64:  return "x86_64";
38   case xcore:   return "xcore";
39   }
40
41   return "<invalid>";
42 }
43
44 const char *Triple::getVendorTypeName(VendorType Kind) {
45   switch (Kind) {
46   case UnknownVendor: return "unknown";
47
48   case Apple: return "apple";
49   case PC: return "pc";
50   }
51
52   return "<invalid>";
53 }
54
55 const char *Triple::getOSTypeName(OSType Kind) {
56   switch (Kind) {
57   case UnknownOS: return "unknown";
58
59   case AuroraUX: return "auroraux";
60   case Cygwin: return "cygwin";
61   case Darwin: return "darwin";
62   case DragonFly: return "dragonfly";
63   case FreeBSD: return "freebsd";
64   case Linux: return "linux";
65   case MinGW32: return "mingw32";
66   case MinGW64: return "mingw64";
67   case NetBSD: return "netbsd";
68   case OpenBSD: return "openbsd";
69   case Win32: return "win32";
70   }
71
72   return "<invalid>";
73 }
74
75 Triple::ArchType Triple::getArchTypeForLLVMName(const StringRef &Name) {
76   if (Name == "alpha")
77     return alpha;
78   if (Name == "arm")
79     return arm;
80   if (Name == "bfin")
81     return bfin;
82   if (Name == "cellspu")
83     return cellspu;
84   if (Name == "mips")
85     return mips;
86   if (Name == "mipsel")
87     return mipsel;
88   if (Name == "msp430")
89     return msp430;
90   if (Name == "ppc64")
91     return ppc64;
92   if (Name == "ppc")
93     return ppc;
94   if (Name == "sparc")
95     return sparc;
96   if (Name == "systemz")
97     return systemz;
98   if (Name == "thumb")
99     return thumb;
100   if (Name == "x86")
101     return x86;
102   if (Name == "x86-64")
103     return x86_64;
104   if (Name == "xcore")
105     return xcore;
106
107   return UnknownArch;
108 }
109
110 //
111
112 void Triple::Parse() const {
113   assert(!isInitialized() && "Invalid parse call.");
114
115   StringRef ArchName = getArchName();
116   if (ArchName.size() == 4 && ArchName[0] == 'i' && 
117       ArchName[2] == '8' && ArchName[3] == '6' && 
118       ArchName[1] - '3' < 6) // i[3-9]86
119     Arch = x86;
120   else if (ArchName == "amd64" || ArchName == "x86_64")
121     Arch = x86_64;
122   else if (ArchName == "powerpc")
123     Arch = ppc;
124   else if (ArchName == "powerpc64")
125     Arch = ppc64;
126   else if (ArchName == "arm" ||
127            ArchName.startswith("armv"))
128     Arch = arm;
129   else if (ArchName == "thumb" ||
130            ArchName.startswith("thumbv"))
131     Arch = thumb;
132   else if (ArchName.startswith("alpha"))
133     Arch = alpha;
134   else if (ArchName == "spu" || ArchName == "cellspu")
135     Arch = cellspu;
136   else if (ArchName == "msp430")
137     Arch = msp430;
138   else if (ArchName == "mips" || ArchName == "mipsallegrex")
139     Arch = mips;
140   else if (ArchName == "mipsel" || ArchName == "mipsallegrexel" ||
141            ArchName == "psp")
142     Arch = mipsel;
143   else if (ArchName == "sparc")
144     Arch = sparc;
145   else if (ArchName == "s390x")
146     Arch = systemz;
147   else if (ArchName == "bfin")
148     Arch = bfin;
149   else
150     Arch = UnknownArch;
151
152   StringRef VendorName = getVendorName();
153   if (VendorName == "apple")
154     Vendor = Apple;
155   else if (VendorName == "pc")
156     Vendor = PC;
157   else
158     Vendor = UnknownVendor;
159
160   StringRef OSName = getOSName();
161   if (OSName.startswith("auroraux"))
162     OS = AuroraUX;
163   else if (OSName.startswith("cygwin"))
164     OS = Cygwin;
165   else if (OSName.startswith("darwin"))
166     OS = Darwin;
167   else if (OSName.startswith("dragonfly"))
168     OS = DragonFly;
169   else if (OSName.startswith("freebsd"))
170     OS = FreeBSD;
171   else if (OSName.startswith("linux"))
172     OS = Linux;
173   else if (OSName.startswith("mingw32"))
174     OS = MinGW32;
175   else if (OSName.startswith("mingw64"))
176     OS = MinGW64;
177   else if (OSName.startswith("netbsd"))
178     OS = NetBSD;
179   else if (OSName.startswith("openbsd"))
180     OS = OpenBSD;
181   else if (OSName.startswith("win32"))
182     OS = Win32;
183   else
184     OS = UnknownOS;
185
186   assert(isInitialized() && "Failed to initialize!");
187 }
188
189 StringRef Triple::getArchName() const {
190   return StringRef(Data).split('-').first;           // Isolate first component
191 }
192
193 StringRef Triple::getVendorName() const {
194   StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
195   return Tmp.split('-').first;                       // Isolate second component
196 }
197
198 StringRef Triple::getOSName() const {
199   StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
200   Tmp = Tmp.split('-').second;                       // Strip second component
201   return Tmp.split('-').first;                       // Isolate third component
202 }
203
204 StringRef Triple::getEnvironmentName() const {
205   StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
206   Tmp = Tmp.split('-').second;                       // Strip second component
207   return Tmp.split('-').second;                      // Strip third component
208 }
209
210 StringRef Triple::getOSAndEnvironmentName() const {
211   StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
212   return Tmp.split('-').second;                      // Strip second component
213 }
214
215 static unsigned EatNumber(StringRef &Str) {
216   assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
217   unsigned Result = Str[0]-'0';
218   
219   // Eat the digit.
220   Str = Str.substr(1);
221   
222   // Handle "darwin11".
223   if (Result == 1 && !Str.empty() && Str[0] >= '0' && Str[0] <= '9') {
224     Result = Result*10 + (Str[0] - '0');
225     // Eat the digit.
226     Str = Str.substr(1);
227   }
228   
229   return Result;
230 }
231
232 /// getDarwinNumber - Parse the 'darwin number' out of the specific target
233 /// triple.  For example, if we have darwin8.5 return 8,5,0.  If any entry is
234 /// not defined, return 0's.  This requires that the triple have an OSType of
235 /// darwin before it is called.
236 void Triple::getDarwinNumber(unsigned &Maj, unsigned &Min,
237                              unsigned &Revision) const {
238   assert(getOS() == Darwin && "Not a darwin target triple!");
239   StringRef OSName = getOSName();
240   assert(OSName.startswith("darwin") && "Unknown darwin target triple!");
241   
242   // Strip off "darwin".
243   OSName = OSName.substr(6);
244   
245   Maj = Min = Revision = 0;
246
247   if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
248     return;
249
250   // The major version is the first digit.
251   Maj = EatNumber(OSName);
252   if (OSName.empty()) return;
253   
254   // Handle minor version: 10.4.9 -> darwin8.9.
255   if (OSName[0] != '.')
256     return;
257   
258   // Eat the '.'.
259   OSName = OSName.substr(1);
260
261   if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
262     return;
263   
264   Min = EatNumber(OSName);
265   if (OSName.empty()) return;
266
267   // Handle revision darwin8.9.1
268   if (OSName[0] != '.')
269     return;
270   
271   // Eat the '.'.
272   OSName = OSName.substr(1);
273   
274   if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
275     return;
276
277   Revision = EatNumber(OSName);
278 }
279
280 void Triple::setTriple(const Twine &Str) {
281   Data = Str.str();
282   Arch = InvalidArch;
283 }
284
285 void Triple::setArch(ArchType Kind) {
286   setArchName(getArchTypeName(Kind));
287 }
288
289 void Triple::setVendor(VendorType Kind) {
290   setVendorName(getVendorTypeName(Kind));
291 }
292
293 void Triple::setOS(OSType Kind) {
294   setOSName(getOSTypeName(Kind));
295 }
296
297 void Triple::setArchName(const StringRef &Str) {
298   setTriple(Str + "-" + getVendorName() + "-" + getOSAndEnvironmentName());
299 }
300
301 void Triple::setVendorName(const StringRef &Str) {
302   setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
303 }
304
305 void Triple::setOSName(const StringRef &Str) {
306   if (hasEnvironment())
307     setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
308               "-" + getEnvironmentName());
309   else
310     setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
311 }
312
313 void Triple::setEnvironmentName(const StringRef &Str) {
314   setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() + 
315             "-" + Str);
316 }
317
318 void Triple::setOSAndEnvironmentName(const StringRef &Str) {
319   setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
320 }