blob: 5a76184caaa0b351388a0714cfaa04fa226382c8 [file] [log] [blame]
Daniel Dunbar23e97b02009-04-01 21:53:23 +00001//===--- 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"
Daniel Dunbara14d2252009-07-26 03:31:47 +000011
Jeffrey Yasskin0b228732009-10-06 21:45:26 +000012#include "llvm/ADT/SmallString.h"
Daniel Dunbara14d2252009-07-26 03:31:47 +000013#include "llvm/ADT/Twine.h"
Daniel Dunbar23e97b02009-04-01 21:53:23 +000014#include <cassert>
Mikhail Glushenkov70748752009-04-02 01:11:37 +000015#include <cstring>
Daniel Dunbar23e97b02009-04-01 21:53:23 +000016using namespace llvm;
17
18//
19
20const char *Triple::getArchTypeName(ArchType Kind) {
21 switch (Kind) {
22 case InvalidArch: return "<invalid>";
23 case UnknownArch: return "unknown";
Daniel Dunbar6337f152009-07-26 04:23:03 +000024
25 case alpha: return "alpha";
26 case arm: return "arm";
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +000027 case bfin: return "bfin";
Daniel Dunbar6337f152009-07-26 04:23:03 +000028 case cellspu: return "cellspu";
29 case mips: return "mips";
30 case mipsel: return "mipsel";
31 case msp430: return "msp430";
Daniel Dunbarfdb0b7b2009-08-18 04:43:27 +000032 case pic16: return "pic16";
Daniel Dunbar8c2f1d72009-07-26 04:52:45 +000033 case ppc64: return "powerpc64";
34 case ppc: return "powerpc";
Daniel Dunbar6337f152009-07-26 04:23:03 +000035 case sparc: return "sparc";
Chris Lattner87c06d62010-02-04 06:34:01 +000036 case sparcv9: return "sparcv9";
Daniel Dunbar6337f152009-07-26 04:23:03 +000037 case systemz: return "s390x";
Eli Friedman74db89e2009-08-19 20:46:03 +000038 case tce: return "tce";
Daniel Dunbar6337f152009-07-26 04:23:03 +000039 case thumb: return "thumb";
40 case x86: return "i386";
41 case x86_64: return "x86_64";
Daniel Dunbar8c2f1d72009-07-26 04:52:45 +000042 case xcore: return "xcore";
Daniel Dunbar23e97b02009-04-01 21:53:23 +000043 }
44
45 return "<invalid>";
46}
47
Daniel Dunbar688b55b2009-08-24 09:53:06 +000048const char *Triple::getArchTypePrefix(ArchType Kind) {
49 switch (Kind) {
50 default:
51 return 0;
52
53 case alpha: return "alpha";
54
55 case arm:
56 case thumb: return "arm";
57
58 case bfin: return "bfin";
59
60 case cellspu: return "spu";
61
62 case ppc64:
63 case ppc: return "ppc";
64
Chris Lattner87c06d62010-02-04 06:34:01 +000065 case sparcv9:
Daniel Dunbar688b55b2009-08-24 09:53:06 +000066 case sparc: return "sparc";
67
68 case x86:
69 case x86_64: return "x86";
70 case xcore: return "xcore";
71 }
72}
73
Daniel Dunbar23e97b02009-04-01 21:53:23 +000074const char *Triple::getVendorTypeName(VendorType Kind) {
75 switch (Kind) {
76 case UnknownVendor: return "unknown";
77
78 case Apple: return "apple";
Chris Lattner56ce0f42009-08-14 18:48:13 +000079 case PC: return "pc";
Daniel Dunbar23e97b02009-04-01 21:53:23 +000080 }
81
82 return "<invalid>";
83}
84
85const char *Triple::getOSTypeName(OSType Kind) {
86 switch (Kind) {
87 case UnknownOS: return "unknown";
88
Duncan Sands852cd112009-06-19 14:40:01 +000089 case AuroraUX: return "auroraux";
Daniel Dunbar6337f152009-07-26 04:23:03 +000090 case Cygwin: return "cygwin";
Daniel Dunbar23e97b02009-04-01 21:53:23 +000091 case Darwin: return "darwin";
Daniel Dunbar7eaf0572009-05-22 02:24:11 +000092 case DragonFly: return "dragonfly";
Daniel Dunbar23e97b02009-04-01 21:53:23 +000093 case FreeBSD: return "freebsd";
94 case Linux: return "linux";
Edward O'Callaghancc9fa812009-11-19 11:59:00 +000095 case Lv2: return "lv2";
Daniel Dunbar6337f152009-07-26 04:23:03 +000096 case MinGW32: return "mingw32";
Chris Lattner8e620832009-08-12 06:32:10 +000097 case MinGW64: return "mingw64";
Chris Lattnerb8ac8412009-07-13 20:22:23 +000098 case NetBSD: return "netbsd";
Duncan Sandscd1267d2009-06-29 13:36:13 +000099 case OpenBSD: return "openbsd";
Edward O'Callaghane0fb75d2009-11-15 10:18:17 +0000100 case Psp: return "psp";
Daniel Dunbarfdb0b7b2009-08-18 04:43:27 +0000101 case Solaris: return "solaris";
Daniel Dunbar6337f152009-07-26 04:23:03 +0000102 case Win32: return "win32";
Chris Lattnera43fc342009-10-16 02:06:30 +0000103 case Haiku: return "haiku";
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000104 }
105
106 return "<invalid>";
107}
108
Daniel Dunbar2928c832009-11-06 10:58:06 +0000109Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
Daniel Dunbar3c2d4bf2009-08-03 04:03:51 +0000110 if (Name == "alpha")
111 return alpha;
112 if (Name == "arm")
113 return arm;
114 if (Name == "bfin")
115 return bfin;
116 if (Name == "cellspu")
117 return cellspu;
118 if (Name == "mips")
119 return mips;
120 if (Name == "mipsel")
121 return mipsel;
122 if (Name == "msp430")
123 return msp430;
Daniel Dunbarfdb0b7b2009-08-18 04:43:27 +0000124 if (Name == "pic16")
125 return pic16;
Daniel Dunbar3c2d4bf2009-08-03 04:03:51 +0000126 if (Name == "ppc64")
127 return ppc64;
128 if (Name == "ppc")
129 return ppc;
130 if (Name == "sparc")
131 return sparc;
Chris Lattner87c06d62010-02-04 06:34:01 +0000132 if (Name == "sparcv9")
133 return sparcv9;
Daniel Dunbar3c2d4bf2009-08-03 04:03:51 +0000134 if (Name == "systemz")
135 return systemz;
Eli Friedman74db89e2009-08-19 20:46:03 +0000136 if (Name == "tce")
137 return tce;
Daniel Dunbar3c2d4bf2009-08-03 04:03:51 +0000138 if (Name == "thumb")
139 return thumb;
140 if (Name == "x86")
141 return x86;
Chris Lattnerb796c4f2009-08-12 06:45:02 +0000142 if (Name == "x86-64")
Daniel Dunbar3c2d4bf2009-08-03 04:03:51 +0000143 return x86_64;
144 if (Name == "xcore")
145 return xcore;
146
147 return UnknownArch;
148}
149
Daniel Dunbar2928c832009-11-06 10:58:06 +0000150Triple::ArchType Triple::getArchTypeForDarwinArchName(StringRef Str) {
Daniel Dunbarbaf9b562009-09-08 23:32:51 +0000151 // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
152 // archs which Darwin doesn't use.
153
154 // The matching this routine does is fairly pointless, since it is neither the
155 // complete architecture list, nor a reasonable subset. The problem is that
156 // historically the driver driver accepts this and also ties its -march=
157 // handling to the architecture name, so we need to be careful before removing
158 // support for it.
159
Daniel Dunbared687882009-09-09 23:01:25 +0000160 // This code must be kept in sync with Clang's Darwin specific argument
161 // translation.
162
Daniel Dunbarbaf9b562009-09-08 23:32:51 +0000163 if (Str == "ppc" || Str == "ppc601" || Str == "ppc603" || Str == "ppc604" ||
164 Str == "ppc604e" || Str == "ppc750" || Str == "ppc7400" ||
165 Str == "ppc7450" || Str == "ppc970")
166 return Triple::ppc;
167
168 if (Str == "ppc64")
169 return Triple::ppc64;
170
171 if (Str == "i386" || Str == "i486" || Str == "i486SX" || Str == "pentium" ||
172 Str == "i586" || Str == "pentpro" || Str == "i686" || Str == "pentIIm3" ||
173 Str == "pentIIm5" || Str == "pentium4")
174 return Triple::x86;
175
176 if (Str == "x86_64")
177 return Triple::x86_64;
178
179 // This is derived from the driver driver.
180 if (Str == "arm" || Str == "armv4t" || Str == "armv5" || Str == "xscale" ||
181 Str == "armv6" || Str == "armv7")
182 return Triple::arm;
183
184 return Triple::UnknownArch;
185}
186
Viktor Kutuzov51cdac02009-11-17 18:48:27 +0000187// Returns architecture name that is unsderstood by the target assembler.
188const char *Triple::getArchNameForAssembler() {
189 if (getOS() != Triple::Darwin && getVendor() != Triple::Apple)
190 return NULL;
191
192 StringRef Str = getArchName();
193 if (Str == "i386")
194 return "i386";
195 if (Str == "x86_64")
196 return "x86_64";
197 if (Str == "powerpc")
198 return "ppc";
199 if (Str == "powerpc64")
200 return "ppc64";
201 if (Str == "arm")
202 return "arm";
203 if (Str == "armv4t" || Str == "thumbv4t")
204 return "armv4t";
205 if (Str == "armv5" || Str == "armv5e" || Str == "thumbv5" || Str == "thumbv5e")
206 return "armv5";
207 if (Str == "armv6" || Str == "thumbv6")
208 return "armv6";
209 if (Str == "armv7" || Str == "thumbv7")
210 return "armv7";
211 return NULL;
212}
213
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000214//
215
216void Triple::Parse() const {
217 assert(!isInitialized() && "Invalid parse call.");
218
Daniel Dunbara14d2252009-07-26 03:31:47 +0000219 StringRef ArchName = getArchName();
Daniel Dunbar651aa682009-08-18 19:26:55 +0000220 StringRef VendorName = getVendorName();
221 StringRef OSName = getOSName();
222
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000223 if (ArchName.size() == 4 && ArchName[0] == 'i' &&
Daniel Dunbar6337f152009-07-26 04:23:03 +0000224 ArchName[2] == '8' && ArchName[3] == '6' &&
225 ArchName[1] - '3' < 6) // i[3-9]86
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000226 Arch = x86;
227 else if (ArchName == "amd64" || ArchName == "x86_64")
228 Arch = x86_64;
Daniel Dunbarb26bc422009-08-18 07:06:26 +0000229 else if (ArchName == "bfin")
230 Arch = bfin;
Daniel Dunbarfdb0b7b2009-08-18 04:43:27 +0000231 else if (ArchName == "pic16")
232 Arch = pic16;
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000233 else if (ArchName == "powerpc")
234 Arch = ppc;
Edward O'Callaghancc9fa812009-11-19 11:59:00 +0000235 else if ((ArchName == "powerpc64") || (ArchName == "ppu"))
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000236 Arch = ppc64;
Daniel Dunbar6337f152009-07-26 04:23:03 +0000237 else if (ArchName == "arm" ||
Daniel Dunbar24473892009-08-18 04:51:26 +0000238 ArchName.startswith("armv") ||
239 ArchName == "xscale")
Daniel Dunbar6337f152009-07-26 04:23:03 +0000240 Arch = arm;
241 else if (ArchName == "thumb" ||
242 ArchName.startswith("thumbv"))
243 Arch = thumb;
244 else if (ArchName.startswith("alpha"))
245 Arch = alpha;
246 else if (ArchName == "spu" || ArchName == "cellspu")
247 Arch = cellspu;
248 else if (ArchName == "msp430")
249 Arch = msp430;
250 else if (ArchName == "mips" || ArchName == "mipsallegrex")
251 Arch = mips;
252 else if (ArchName == "mipsel" || ArchName == "mipsallegrexel" ||
253 ArchName == "psp")
254 Arch = mipsel;
255 else if (ArchName == "sparc")
256 Arch = sparc;
Chris Lattner87c06d62010-02-04 06:34:01 +0000257 else if (ArchName == "sparcv9")
258 Arch = sparcv9;
Daniel Dunbar6337f152009-07-26 04:23:03 +0000259 else if (ArchName == "s390x")
260 Arch = systemz;
Eli Friedman74db89e2009-08-19 20:46:03 +0000261 else if (ArchName == "tce")
262 Arch = tce;
Richard Osborne768f1dd2009-08-31 21:51:36 +0000263 else if (ArchName == "xcore")
264 Arch = xcore;
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000265 else
266 Arch = UnknownArch;
267
Daniel Dunbar651aa682009-08-18 19:26:55 +0000268
269 // Handle some exceptional cases where the OS / environment components are
270 // stuck into the vendor field.
271 if (StringRef(getTriple()).count('-') == 1) {
272 StringRef VendorName = getVendorName();
273
274 if (VendorName.startswith("mingw32")) { // 'i386-mingw32', etc.
275 Vendor = PC;
276 OS = MinGW32;
277 return;
278 }
279
280 // arm-elf is another example, but we don't currently parse anything about
281 // the environment.
282 }
283
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000284 if (VendorName == "apple")
285 Vendor = Apple;
286 else if (VendorName == "pc")
287 Vendor = PC;
288 else
289 Vendor = UnknownVendor;
290
Daniel Dunbara14d2252009-07-26 03:31:47 +0000291 if (OSName.startswith("auroraux"))
Duncan Sands852cd112009-06-19 14:40:01 +0000292 OS = AuroraUX;
Daniel Dunbar6337f152009-07-26 04:23:03 +0000293 else if (OSName.startswith("cygwin"))
294 OS = Cygwin;
Daniel Dunbara14d2252009-07-26 03:31:47 +0000295 else if (OSName.startswith("darwin"))
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000296 OS = Darwin;
Daniel Dunbara14d2252009-07-26 03:31:47 +0000297 else if (OSName.startswith("dragonfly"))
Daniel Dunbar7eaf0572009-05-22 02:24:11 +0000298 OS = DragonFly;
Daniel Dunbara14d2252009-07-26 03:31:47 +0000299 else if (OSName.startswith("freebsd"))
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000300 OS = FreeBSD;
Daniel Dunbara14d2252009-07-26 03:31:47 +0000301 else if (OSName.startswith("linux"))
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000302 OS = Linux;
Edward O'Callaghancc9fa812009-11-19 11:59:00 +0000303 else if (OSName.startswith("lv2"))
304 OS = Lv2;
Daniel Dunbar6337f152009-07-26 04:23:03 +0000305 else if (OSName.startswith("mingw32"))
306 OS = MinGW32;
Chris Lattner8e620832009-08-12 06:32:10 +0000307 else if (OSName.startswith("mingw64"))
308 OS = MinGW64;
Daniel Dunbara14d2252009-07-26 03:31:47 +0000309 else if (OSName.startswith("netbsd"))
Chris Lattnerb8ac8412009-07-13 20:22:23 +0000310 OS = NetBSD;
Daniel Dunbara14d2252009-07-26 03:31:47 +0000311 else if (OSName.startswith("openbsd"))
Duncan Sandscd1267d2009-06-29 13:36:13 +0000312 OS = OpenBSD;
Edward O'Callaghane0fb75d2009-11-15 10:18:17 +0000313 else if (OSName.startswith("psp"))
314 OS = Psp;
Daniel Dunbarfdb0b7b2009-08-18 04:43:27 +0000315 else if (OSName.startswith("solaris"))
316 OS = Solaris;
Daniel Dunbar6337f152009-07-26 04:23:03 +0000317 else if (OSName.startswith("win32"))
318 OS = Win32;
Chris Lattnera43fc342009-10-16 02:06:30 +0000319 else if (OSName.startswith("haiku"))
320 OS = Haiku;
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000321 else
322 OS = UnknownOS;
323
324 assert(isInitialized() && "Failed to initialize!");
325}
326
Daniel Dunbara14d2252009-07-26 03:31:47 +0000327StringRef Triple::getArchName() const {
328 return StringRef(Data).split('-').first; // Isolate first component
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000329}
330
Daniel Dunbara14d2252009-07-26 03:31:47 +0000331StringRef Triple::getVendorName() const {
332 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
333 return Tmp.split('-').first; // Isolate second component
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000334}
335
Daniel Dunbara14d2252009-07-26 03:31:47 +0000336StringRef Triple::getOSName() const {
337 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
338 Tmp = Tmp.split('-').second; // Strip second component
339 return Tmp.split('-').first; // Isolate third component
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000340}
341
Daniel Dunbara14d2252009-07-26 03:31:47 +0000342StringRef Triple::getEnvironmentName() const {
343 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
344 Tmp = Tmp.split('-').second; // Strip second component
345 return Tmp.split('-').second; // Strip third component
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000346}
347
Daniel Dunbara14d2252009-07-26 03:31:47 +0000348StringRef Triple::getOSAndEnvironmentName() const {
349 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
350 return Tmp.split('-').second; // Strip second component
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000351}
352
Chris Lattnerdfc17f72009-08-12 06:19:40 +0000353static unsigned EatNumber(StringRef &Str) {
354 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
355 unsigned Result = Str[0]-'0';
356
357 // Eat the digit.
358 Str = Str.substr(1);
359
360 // Handle "darwin11".
361 if (Result == 1 && !Str.empty() && Str[0] >= '0' && Str[0] <= '9') {
362 Result = Result*10 + (Str[0] - '0');
363 // Eat the digit.
364 Str = Str.substr(1);
365 }
366
367 return Result;
368}
369
370/// getDarwinNumber - Parse the 'darwin number' out of the specific target
371/// triple. For example, if we have darwin8.5 return 8,5,0. If any entry is
372/// not defined, return 0's. This requires that the triple have an OSType of
373/// darwin before it is called.
374void Triple::getDarwinNumber(unsigned &Maj, unsigned &Min,
375 unsigned &Revision) const {
376 assert(getOS() == Darwin && "Not a darwin target triple!");
377 StringRef OSName = getOSName();
378 assert(OSName.startswith("darwin") && "Unknown darwin target triple!");
379
380 // Strip off "darwin".
381 OSName = OSName.substr(6);
382
383 Maj = Min = Revision = 0;
384
385 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
386 return;
387
388 // The major version is the first digit.
389 Maj = EatNumber(OSName);
390 if (OSName.empty()) return;
391
392 // Handle minor version: 10.4.9 -> darwin8.9.
393 if (OSName[0] != '.')
394 return;
395
396 // Eat the '.'.
397 OSName = OSName.substr(1);
398
399 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
400 return;
401
402 Min = EatNumber(OSName);
403 if (OSName.empty()) return;
404
405 // Handle revision darwin8.9.1
406 if (OSName[0] != '.')
407 return;
408
409 // Eat the '.'.
410 OSName = OSName.substr(1);
411
412 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
413 return;
414
415 Revision = EatNumber(OSName);
416}
417
Daniel Dunbara14d2252009-07-26 03:31:47 +0000418void Triple::setTriple(const Twine &Str) {
419 Data = Str.str();
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000420 Arch = InvalidArch;
421}
422
423void Triple::setArch(ArchType Kind) {
424 setArchName(getArchTypeName(Kind));
425}
426
427void Triple::setVendor(VendorType Kind) {
428 setVendorName(getVendorTypeName(Kind));
429}
430
431void Triple::setOS(OSType Kind) {
432 setOSName(getOSTypeName(Kind));
433}
434
Daniel Dunbar2928c832009-11-06 10:58:06 +0000435void Triple::setArchName(StringRef Str) {
Jeffrey Yasskin0b228732009-10-06 21:45:26 +0000436 // Work around a miscompilation bug for Twines in gcc 4.0.3.
437 SmallString<64> Triple;
438 Triple += Str;
439 Triple += "-";
440 Triple += getVendorName();
441 Triple += "-";
442 Triple += getOSAndEnvironmentName();
443 setTriple(Triple.str());
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000444}
445
Daniel Dunbar2928c832009-11-06 10:58:06 +0000446void Triple::setVendorName(StringRef Str) {
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000447 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
448}
449
Daniel Dunbar2928c832009-11-06 10:58:06 +0000450void Triple::setOSName(StringRef Str) {
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000451 if (hasEnvironment())
452 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
453 "-" + getEnvironmentName());
454 else
455 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
456}
457
Daniel Dunbar2928c832009-11-06 10:58:06 +0000458void Triple::setEnvironmentName(StringRef Str) {
459 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000460 "-" + Str);
461}
462
Daniel Dunbar2928c832009-11-06 10:58:06 +0000463void Triple::setOSAndEnvironmentName(StringRef Str) {
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000464 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
465}