blob: c9da964ce130ed15ae1d94078b34dcf989a2e733 [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"
Duncan Sands5754a452010-09-16 08:25:48 +000013#include "llvm/ADT/STLExtras.h"
Daniel Dunbara14d2252009-07-26 03:31:47 +000014#include "llvm/ADT/Twine.h"
Daniel Dunbar23e97b02009-04-01 21:53:23 +000015#include <cassert>
Mikhail Glushenkov70748752009-04-02 01:11:37 +000016#include <cstring>
Daniel Dunbar23e97b02009-04-01 21:53:23 +000017using namespace llvm;
18
19//
20
21const char *Triple::getArchTypeName(ArchType Kind) {
22 switch (Kind) {
23 case InvalidArch: return "<invalid>";
24 case UnknownArch: return "unknown";
Jim Grosbache509aa92010-12-17 02:10:59 +000025
Daniel Dunbar6337f152009-07-26 04:23:03 +000026 case alpha: return "alpha";
27 case arm: return "arm";
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +000028 case bfin: return "bfin";
Daniel Dunbar6337f152009-07-26 04:23:03 +000029 case cellspu: return "cellspu";
30 case mips: return "mips";
31 case mipsel: return "mipsel";
32 case msp430: return "msp430";
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";
Wesley Pecka70f28c2010-02-23 19:15:24 +000043 case mblaze: return "mblaze";
Nick Lewyckyf7a3c502010-09-07 18:14:24 +000044 case ptx: return "ptx";
Daniel Dunbar23e97b02009-04-01 21:53:23 +000045 }
46
47 return "<invalid>";
48}
49
Daniel Dunbar688b55b2009-08-24 09:53:06 +000050const char *Triple::getArchTypePrefix(ArchType Kind) {
51 switch (Kind) {
52 default:
53 return 0;
54
55 case alpha: return "alpha";
56
57 case arm:
58 case thumb: return "arm";
59
60 case bfin: return "bfin";
61
62 case cellspu: return "spu";
63
64 case ppc64:
65 case ppc: return "ppc";
66
Wesley Pecka70f28c2010-02-23 19:15:24 +000067 case mblaze: return "mblaze";
68
Chris Lattner87c06d62010-02-04 06:34:01 +000069 case sparcv9:
Daniel Dunbar688b55b2009-08-24 09:53:06 +000070 case sparc: return "sparc";
71
72 case x86:
73 case x86_64: return "x86";
Nick Lewyckyf7a3c502010-09-07 18:14:24 +000074
Daniel Dunbar688b55b2009-08-24 09:53:06 +000075 case xcore: return "xcore";
Nick Lewyckyf7a3c502010-09-07 18:14:24 +000076
77 case ptx: return "ptx";
Daniel Dunbar688b55b2009-08-24 09:53:06 +000078 }
79}
80
Daniel Dunbar23e97b02009-04-01 21:53:23 +000081const char *Triple::getVendorTypeName(VendorType Kind) {
82 switch (Kind) {
83 case UnknownVendor: return "unknown";
84
85 case Apple: return "apple";
Chris Lattner56ce0f42009-08-14 18:48:13 +000086 case PC: return "pc";
Renato Golin859f8182011-01-21 18:25:47 +000087 case NoVendor: return "none";
Daniel Dunbar23e97b02009-04-01 21:53:23 +000088 }
89
90 return "<invalid>";
91}
92
93const char *Triple::getOSTypeName(OSType Kind) {
94 switch (Kind) {
95 case UnknownOS: return "unknown";
96
Duncan Sands852cd112009-06-19 14:40:01 +000097 case AuroraUX: return "auroraux";
Daniel Dunbar6337f152009-07-26 04:23:03 +000098 case Cygwin: return "cygwin";
Daniel Dunbar23e97b02009-04-01 21:53:23 +000099 case Darwin: return "darwin";
Daniel Dunbar7eaf0572009-05-22 02:24:11 +0000100 case DragonFly: return "dragonfly";
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000101 case FreeBSD: return "freebsd";
102 case Linux: return "linux";
Edward O'Callaghancc9fa812009-11-19 11:59:00 +0000103 case Lv2: return "lv2";
Daniel Dunbar6337f152009-07-26 04:23:03 +0000104 case MinGW32: return "mingw32";
Chris Lattner8e620832009-08-12 06:32:10 +0000105 case MinGW64: return "mingw64";
Chris Lattnerb8ac8412009-07-13 20:22:23 +0000106 case NetBSD: return "netbsd";
Duncan Sandscd1267d2009-06-29 13:36:13 +0000107 case OpenBSD: return "openbsd";
Edward O'Callaghane0fb75d2009-11-15 10:18:17 +0000108 case Psp: return "psp";
Daniel Dunbarfdb0b7b2009-08-18 04:43:27 +0000109 case Solaris: return "solaris";
Daniel Dunbar6337f152009-07-26 04:23:03 +0000110 case Win32: return "win32";
Chris Lattnera43fc342009-10-16 02:06:30 +0000111 case Haiku: return "haiku";
Chris Lattner29269d02010-07-07 15:52:27 +0000112 case Minix: return "minix";
Renato Golin859f8182011-01-21 18:25:47 +0000113 case NoOS: return "none";
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000114 }
115
116 return "<invalid>";
117}
118
Duncan Sands5754a452010-09-16 08:25:48 +0000119const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
120 switch (Kind) {
121 case UnknownEnvironment: return "unknown";
Renato Golin859f8182011-01-21 18:25:47 +0000122 case GNU: return "gnu";
123 case GNUEABI: return "gnueabi";
124 case EABI: return "eabi";
Duncan Sands5754a452010-09-16 08:25:48 +0000125 }
126
127 return "<invalid>";
128}
129
Daniel Dunbar2928c832009-11-06 10:58:06 +0000130Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
Daniel Dunbar3c2d4bf2009-08-03 04:03:51 +0000131 if (Name == "alpha")
132 return alpha;
133 if (Name == "arm")
134 return arm;
135 if (Name == "bfin")
136 return bfin;
137 if (Name == "cellspu")
138 return cellspu;
139 if (Name == "mips")
140 return mips;
141 if (Name == "mipsel")
142 return mipsel;
143 if (Name == "msp430")
144 return msp430;
145 if (Name == "ppc64")
146 return ppc64;
147 if (Name == "ppc")
148 return ppc;
Wesley Pecka70f28c2010-02-23 19:15:24 +0000149 if (Name == "mblaze")
150 return mblaze;
Daniel Dunbar3c2d4bf2009-08-03 04:03:51 +0000151 if (Name == "sparc")
152 return sparc;
Chris Lattner87c06d62010-02-04 06:34:01 +0000153 if (Name == "sparcv9")
154 return sparcv9;
Daniel Dunbar3c2d4bf2009-08-03 04:03:51 +0000155 if (Name == "systemz")
156 return systemz;
Eli Friedman74db89e2009-08-19 20:46:03 +0000157 if (Name == "tce")
158 return tce;
Daniel Dunbar3c2d4bf2009-08-03 04:03:51 +0000159 if (Name == "thumb")
160 return thumb;
161 if (Name == "x86")
162 return x86;
Chris Lattnerb796c4f2009-08-12 06:45:02 +0000163 if (Name == "x86-64")
Daniel Dunbar3c2d4bf2009-08-03 04:03:51 +0000164 return x86_64;
165 if (Name == "xcore")
166 return xcore;
Nick Lewyckyf7a3c502010-09-07 18:14:24 +0000167 if (Name == "ptx")
168 return ptx;
Daniel Dunbar3c2d4bf2009-08-03 04:03:51 +0000169
170 return UnknownArch;
171}
172
Daniel Dunbar2928c832009-11-06 10:58:06 +0000173Triple::ArchType Triple::getArchTypeForDarwinArchName(StringRef Str) {
Daniel Dunbarbaf9b562009-09-08 23:32:51 +0000174 // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
175 // archs which Darwin doesn't use.
176
177 // The matching this routine does is fairly pointless, since it is neither the
178 // complete architecture list, nor a reasonable subset. The problem is that
179 // historically the driver driver accepts this and also ties its -march=
180 // handling to the architecture name, so we need to be careful before removing
181 // support for it.
182
Daniel Dunbared687882009-09-09 23:01:25 +0000183 // This code must be kept in sync with Clang's Darwin specific argument
184 // translation.
185
Daniel Dunbarbaf9b562009-09-08 23:32:51 +0000186 if (Str == "ppc" || Str == "ppc601" || Str == "ppc603" || Str == "ppc604" ||
187 Str == "ppc604e" || Str == "ppc750" || Str == "ppc7400" ||
188 Str == "ppc7450" || Str == "ppc970")
189 return Triple::ppc;
190
191 if (Str == "ppc64")
192 return Triple::ppc64;
193
194 if (Str == "i386" || Str == "i486" || Str == "i486SX" || Str == "pentium" ||
195 Str == "i586" || Str == "pentpro" || Str == "i686" || Str == "pentIIm3" ||
196 Str == "pentIIm5" || Str == "pentium4")
197 return Triple::x86;
198
199 if (Str == "x86_64")
200 return Triple::x86_64;
201
202 // This is derived from the driver driver.
203 if (Str == "arm" || Str == "armv4t" || Str == "armv5" || Str == "xscale" ||
204 Str == "armv6" || Str == "armv7")
205 return Triple::arm;
206
Nick Lewyckyf7a3c502010-09-07 18:14:24 +0000207 if (Str == "ptx")
208 return Triple::ptx;
209
Daniel Dunbarbaf9b562009-09-08 23:32:51 +0000210 return Triple::UnknownArch;
211}
212
Duncan Sandsbbdca3f2010-03-24 09:05:14 +0000213// Returns architecture name that is understood by the target assembler.
Viktor Kutuzov51cdac02009-11-17 18:48:27 +0000214const char *Triple::getArchNameForAssembler() {
215 if (getOS() != Triple::Darwin && getVendor() != Triple::Apple)
216 return NULL;
217
218 StringRef Str = getArchName();
219 if (Str == "i386")
220 return "i386";
221 if (Str == "x86_64")
222 return "x86_64";
223 if (Str == "powerpc")
224 return "ppc";
225 if (Str == "powerpc64")
226 return "ppc64";
Wesley Pecka70f28c2010-02-23 19:15:24 +0000227 if (Str == "mblaze" || Str == "microblaze")
228 return "mblaze";
Viktor Kutuzov51cdac02009-11-17 18:48:27 +0000229 if (Str == "arm")
230 return "arm";
231 if (Str == "armv4t" || Str == "thumbv4t")
232 return "armv4t";
Jim Grosbache509aa92010-12-17 02:10:59 +0000233 if (Str == "armv5" || Str == "armv5e" || Str == "thumbv5"
234 || Str == "thumbv5e")
Viktor Kutuzov51cdac02009-11-17 18:48:27 +0000235 return "armv5";
236 if (Str == "armv6" || Str == "thumbv6")
237 return "armv6";
238 if (Str == "armv7" || Str == "thumbv7")
239 return "armv7";
Nick Lewyckyf7a3c502010-09-07 18:14:24 +0000240 if (Str == "ptx")
241 return "ptx";
Viktor Kutuzov51cdac02009-11-17 18:48:27 +0000242 return NULL;
243}
244
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000245//
246
Duncan Sands335db222010-08-12 11:31:39 +0000247Triple::ArchType Triple::ParseArch(StringRef ArchName) {
Jim Grosbache509aa92010-12-17 02:10:59 +0000248 if (ArchName.size() == 4 && ArchName[0] == 'i' &&
249 ArchName[2] == '8' && ArchName[3] == '6' &&
Daniel Dunbar6337f152009-07-26 04:23:03 +0000250 ArchName[1] - '3' < 6) // i[3-9]86
Duncan Sands335db222010-08-12 11:31:39 +0000251 return x86;
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000252 else if (ArchName == "amd64" || ArchName == "x86_64")
Duncan Sands335db222010-08-12 11:31:39 +0000253 return x86_64;
Daniel Dunbarb26bc422009-08-18 07:06:26 +0000254 else if (ArchName == "bfin")
Duncan Sands335db222010-08-12 11:31:39 +0000255 return bfin;
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000256 else if (ArchName == "powerpc")
Duncan Sands335db222010-08-12 11:31:39 +0000257 return ppc;
Edward O'Callaghancc9fa812009-11-19 11:59:00 +0000258 else if ((ArchName == "powerpc64") || (ArchName == "ppu"))
Duncan Sands335db222010-08-12 11:31:39 +0000259 return ppc64;
Wesley Pecka70f28c2010-02-23 19:15:24 +0000260 else if (ArchName == "mblaze")
Duncan Sands335db222010-08-12 11:31:39 +0000261 return mblaze;
Daniel Dunbar6337f152009-07-26 04:23:03 +0000262 else if (ArchName == "arm" ||
Daniel Dunbar24473892009-08-18 04:51:26 +0000263 ArchName.startswith("armv") ||
264 ArchName == "xscale")
Duncan Sands335db222010-08-12 11:31:39 +0000265 return arm;
Daniel Dunbar6337f152009-07-26 04:23:03 +0000266 else if (ArchName == "thumb" ||
267 ArchName.startswith("thumbv"))
Duncan Sands335db222010-08-12 11:31:39 +0000268 return thumb;
Daniel Dunbar6337f152009-07-26 04:23:03 +0000269 else if (ArchName.startswith("alpha"))
Duncan Sands335db222010-08-12 11:31:39 +0000270 return alpha;
Daniel Dunbar6337f152009-07-26 04:23:03 +0000271 else if (ArchName == "spu" || ArchName == "cellspu")
Duncan Sands335db222010-08-12 11:31:39 +0000272 return cellspu;
Daniel Dunbar6337f152009-07-26 04:23:03 +0000273 else if (ArchName == "msp430")
Duncan Sands335db222010-08-12 11:31:39 +0000274 return msp430;
Daniel Dunbar6337f152009-07-26 04:23:03 +0000275 else if (ArchName == "mips" || ArchName == "mipsallegrex")
Duncan Sands335db222010-08-12 11:31:39 +0000276 return mips;
Daniel Dunbar6337f152009-07-26 04:23:03 +0000277 else if (ArchName == "mipsel" || ArchName == "mipsallegrexel" ||
278 ArchName == "psp")
Duncan Sands335db222010-08-12 11:31:39 +0000279 return mipsel;
Daniel Dunbar6337f152009-07-26 04:23:03 +0000280 else if (ArchName == "sparc")
Duncan Sands335db222010-08-12 11:31:39 +0000281 return sparc;
Chris Lattner87c06d62010-02-04 06:34:01 +0000282 else if (ArchName == "sparcv9")
Duncan Sands335db222010-08-12 11:31:39 +0000283 return sparcv9;
Daniel Dunbar6337f152009-07-26 04:23:03 +0000284 else if (ArchName == "s390x")
Duncan Sands335db222010-08-12 11:31:39 +0000285 return systemz;
Eli Friedman74db89e2009-08-19 20:46:03 +0000286 else if (ArchName == "tce")
Duncan Sands335db222010-08-12 11:31:39 +0000287 return tce;
Richard Osborne768f1dd2009-08-31 21:51:36 +0000288 else if (ArchName == "xcore")
Duncan Sands335db222010-08-12 11:31:39 +0000289 return xcore;
Nick Lewyckyf7a3c502010-09-07 18:14:24 +0000290 else if (ArchName == "ptx")
291 return ptx;
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000292 else
Duncan Sands335db222010-08-12 11:31:39 +0000293 return UnknownArch;
294}
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000295
Duncan Sands335db222010-08-12 11:31:39 +0000296Triple::VendorType Triple::ParseVendor(StringRef VendorName) {
297 if (VendorName == "apple")
298 return Apple;
299 else if (VendorName == "pc")
300 return PC;
Renato Golin859f8182011-01-21 18:25:47 +0000301 else if (VendorName == "none")
302 return NoVendor;
Duncan Sands335db222010-08-12 11:31:39 +0000303 else
304 return UnknownVendor;
305}
306
307Triple::OSType Triple::ParseOS(StringRef OSName) {
308 if (OSName.startswith("auroraux"))
309 return AuroraUX;
310 else if (OSName.startswith("cygwin"))
311 return Cygwin;
312 else if (OSName.startswith("darwin"))
313 return Darwin;
314 else if (OSName.startswith("dragonfly"))
315 return DragonFly;
316 else if (OSName.startswith("freebsd"))
317 return FreeBSD;
318 else if (OSName.startswith("linux"))
319 return Linux;
320 else if (OSName.startswith("lv2"))
321 return Lv2;
322 else if (OSName.startswith("mingw32"))
323 return MinGW32;
324 else if (OSName.startswith("mingw64"))
325 return MinGW64;
326 else if (OSName.startswith("netbsd"))
327 return NetBSD;
328 else if (OSName.startswith("openbsd"))
329 return OpenBSD;
330 else if (OSName.startswith("psp"))
331 return Psp;
332 else if (OSName.startswith("solaris"))
333 return Solaris;
334 else if (OSName.startswith("win32"))
335 return Win32;
336 else if (OSName.startswith("haiku"))
337 return Haiku;
338 else if (OSName.startswith("minix"))
339 return Minix;
Renato Golin859f8182011-01-21 18:25:47 +0000340 else if (OSName.startswith("eabi"))
341 return NoOS;
Duncan Sands335db222010-08-12 11:31:39 +0000342 else
343 return UnknownOS;
344}
345
Duncan Sands5754a452010-09-16 08:25:48 +0000346Triple::EnvironmentType Triple::ParseEnvironment(StringRef EnvironmentName) {
Renato Golin859f8182011-01-21 18:25:47 +0000347 if (EnvironmentName.startswith("eabi"))
348 return EABI;
349 else if (EnvironmentName.startswith("gnueabi"))
350 return GNUEABI;
351 else if (EnvironmentName.startswith("gnu"))
352 return GNU;
353 else
354 return UnknownEnvironment;
Duncan Sands5754a452010-09-16 08:25:48 +0000355}
356
Duncan Sands335db222010-08-12 11:31:39 +0000357void Triple::Parse() const {
358 assert(!isInitialized() && "Invalid parse call.");
359
360 Arch = ParseArch(getArchName());
361 Vendor = ParseVendor(getVendorName());
362 OS = ParseOS(getOSName());
Renato Golin859f8182011-01-21 18:25:47 +0000363 if (OS == NoOS) {
364 // Some targets don't have an OS (embedded systems)
365 Environment = ParseEnvironment(getOSName());
366 } else {
367 Environment = ParseEnvironment(getEnvironmentName());
368 }
Daniel Dunbar651aa682009-08-18 19:26:55 +0000369
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000370 assert(isInitialized() && "Failed to initialize!");
371}
372
Duncan Sands335db222010-08-12 11:31:39 +0000373std::string Triple::normalize(StringRef Str) {
374 // Parse into components.
375 SmallVector<StringRef, 4> Components;
376 for (size_t First = 0, Last = 0; Last != StringRef::npos; First = Last + 1) {
377 Last = Str.find('-', First);
378 Components.push_back(Str.slice(First, Last));
379 }
380
381 // If the first component corresponds to a known architecture, preferentially
382 // use it for the architecture. If the second component corresponds to a
383 // known vendor, preferentially use it for the vendor, etc. This avoids silly
384 // component movement when a component parses as (eg) both a valid arch and a
385 // valid os.
386 ArchType Arch = UnknownArch;
387 if (Components.size() > 0)
388 Arch = ParseArch(Components[0]);
389 VendorType Vendor = UnknownVendor;
390 if (Components.size() > 1)
391 Vendor = ParseVendor(Components[1]);
392 OSType OS = UnknownOS;
393 if (Components.size() > 2)
394 OS = ParseOS(Components[2]);
Duncan Sands5754a452010-09-16 08:25:48 +0000395 EnvironmentType Environment = UnknownEnvironment;
396 if (Components.size() > 3)
397 Environment = ParseEnvironment(Components[3]);
Duncan Sands335db222010-08-12 11:31:39 +0000398
399 // Note which components are already in their final position. These will not
400 // be moved.
Duncan Sands5754a452010-09-16 08:25:48 +0000401 bool Found[4];
Duncan Sands335db222010-08-12 11:31:39 +0000402 Found[0] = Arch != UnknownArch;
403 Found[1] = Vendor != UnknownVendor;
404 Found[2] = OS != UnknownOS;
Duncan Sands5754a452010-09-16 08:25:48 +0000405 Found[3] = Environment != UnknownEnvironment;
Duncan Sands335db222010-08-12 11:31:39 +0000406
407 // If they are not there already, permute the components into their canonical
408 // positions by seeing if they parse as a valid architecture, and if so moving
409 // the component to the architecture position etc.
Duncan Sands5754a452010-09-16 08:25:48 +0000410 for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) {
Duncan Sands335db222010-08-12 11:31:39 +0000411 if (Found[Pos])
412 continue; // Already in the canonical position.
413
414 for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
415 // Do not reparse any components that already matched.
Duncan Sands5754a452010-09-16 08:25:48 +0000416 if (Idx < array_lengthof(Found) && Found[Idx])
Duncan Sands335db222010-08-12 11:31:39 +0000417 continue;
418
419 // Does this component parse as valid for the target position?
420 bool Valid = false;
421 StringRef Comp = Components[Idx];
422 switch (Pos) {
423 default:
424 assert(false && "unexpected component type!");
425 case 0:
426 Arch = ParseArch(Comp);
427 Valid = Arch != UnknownArch;
428 break;
429 case 1:
430 Vendor = ParseVendor(Comp);
431 Valid = Vendor != UnknownVendor;
432 break;
433 case 2:
434 OS = ParseOS(Comp);
Renato Golin859f8182011-01-21 18:25:47 +0000435 // Some targets don't have an OS (embedded systems)
436 if (OS == NoOS) {
437 Environment = ParseEnvironment(Comp);
438 Valid = Environment != UnknownEnvironment;
439 } else {
440 Valid = OS != UnknownOS;
441 }
Duncan Sands335db222010-08-12 11:31:39 +0000442 break;
Duncan Sands5754a452010-09-16 08:25:48 +0000443 case 3:
444 Environment = ParseEnvironment(Comp);
445 Valid = Environment != UnknownEnvironment;
446 break;
Duncan Sands335db222010-08-12 11:31:39 +0000447 }
448 if (!Valid)
449 continue; // Nope, try the next component.
450
451 // Move the component to the target position, pushing any non-fixed
452 // components that are in the way to the right. This tends to give
453 // good results in the common cases of a forgotten vendor component
454 // or a wrongly positioned environment.
455 if (Pos < Idx) {
456 // Insert left, pushing the existing components to the right. For
457 // example, a-b-i386 -> i386-a-b when moving i386 to the front.
458 StringRef CurrentComponent(""); // The empty component.
459 // Replace the component we are moving with an empty component.
460 std::swap(CurrentComponent, Components[Idx]);
461 // Insert the component being moved at Pos, displacing any existing
462 // components to the right.
463 for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
464 // Skip over any fixed components.
Duncan Sands5754a452010-09-16 08:25:48 +0000465 while (i < array_lengthof(Found) && Found[i]) ++i;
Duncan Sands335db222010-08-12 11:31:39 +0000466 // Place the component at the new position, getting the component
467 // that was at this position - it will be moved right.
468 std::swap(CurrentComponent, Components[i]);
469 }
470 } else if (Pos > Idx) {
471 // Push right by inserting empty components until the component at Idx
472 // reaches the target position Pos. For example, pc-a -> -pc-a when
473 // moving pc to the second position.
474 do {
475 // Insert one empty component at Idx.
476 StringRef CurrentComponent(""); // The empty component.
477 for (unsigned i = Idx; i < Components.size(); ++i) {
478 // Skip over any fixed components.
Duncan Sands5754a452010-09-16 08:25:48 +0000479 while (i < array_lengthof(Found) && Found[i]) ++i;
Renato Golin859f8182011-01-21 18:25:47 +0000480 // Fix problem when Components vector is not big enough
481 if (i >= Components.size())
482 Components.push_back(StringRef(""));
Duncan Sands335db222010-08-12 11:31:39 +0000483 // Place the component at the new position, getting the component
484 // that was at this position - it will be moved right.
485 std::swap(CurrentComponent, Components[i]);
486 // If it was placed on top of an empty component then we are done.
487 if (CurrentComponent.empty())
488 break;
489 }
490 // The last component was pushed off the end - append it.
491 if (!CurrentComponent.empty())
492 Components.push_back(CurrentComponent);
493
494 // Advance Idx to the component's new position.
Duncan Sands5754a452010-09-16 08:25:48 +0000495 while (++Idx < array_lengthof(Found) && Found[Idx]) {}
Duncan Sands335db222010-08-12 11:31:39 +0000496 } while (Idx < Pos); // Add more until the final position is reached.
497 }
498 assert(Pos < Components.size() && Components[Pos] == Comp &&
499 "Component moved wrong!");
500 Found[Pos] = true;
501 break;
502 }
503 }
504
505 // Special case logic goes here. At this point Arch, Vendor and OS have the
506 // correct values for the computed components.
507
508 // Stick the corrected components back together to form the normalized string.
509 std::string Normalized;
510 for (unsigned i = 0, e = Components.size(); i != e; ++i) {
511 if (i) Normalized += '-';
512 Normalized += Components[i];
513 }
514 return Normalized;
515}
516
Daniel Dunbara14d2252009-07-26 03:31:47 +0000517StringRef Triple::getArchName() const {
518 return StringRef(Data).split('-').first; // Isolate first component
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000519}
520
Daniel Dunbara14d2252009-07-26 03:31:47 +0000521StringRef Triple::getVendorName() const {
522 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
523 return Tmp.split('-').first; // Isolate second component
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000524}
525
Daniel Dunbara14d2252009-07-26 03:31:47 +0000526StringRef Triple::getOSName() const {
527 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
528 Tmp = Tmp.split('-').second; // Strip second component
529 return Tmp.split('-').first; // Isolate third component
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000530}
531
Daniel Dunbara14d2252009-07-26 03:31:47 +0000532StringRef Triple::getEnvironmentName() const {
533 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
534 Tmp = Tmp.split('-').second; // Strip second component
535 return Tmp.split('-').second; // Strip third component
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000536}
537
Daniel Dunbara14d2252009-07-26 03:31:47 +0000538StringRef Triple::getOSAndEnvironmentName() const {
539 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
540 return Tmp.split('-').second; // Strip second component
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000541}
542
Chris Lattnerdfc17f72009-08-12 06:19:40 +0000543static unsigned EatNumber(StringRef &Str) {
544 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
545 unsigned Result = Str[0]-'0';
Jim Grosbache509aa92010-12-17 02:10:59 +0000546
Chris Lattnerdfc17f72009-08-12 06:19:40 +0000547 // Eat the digit.
548 Str = Str.substr(1);
Jim Grosbache509aa92010-12-17 02:10:59 +0000549
Chris Lattnerdfc17f72009-08-12 06:19:40 +0000550 // Handle "darwin11".
551 if (Result == 1 && !Str.empty() && Str[0] >= '0' && Str[0] <= '9') {
552 Result = Result*10 + (Str[0] - '0');
553 // Eat the digit.
554 Str = Str.substr(1);
555 }
Jim Grosbache509aa92010-12-17 02:10:59 +0000556
Chris Lattnerdfc17f72009-08-12 06:19:40 +0000557 return Result;
558}
559
560/// getDarwinNumber - Parse the 'darwin number' out of the specific target
561/// triple. For example, if we have darwin8.5 return 8,5,0. If any entry is
562/// not defined, return 0's. This requires that the triple have an OSType of
563/// darwin before it is called.
564void Triple::getDarwinNumber(unsigned &Maj, unsigned &Min,
565 unsigned &Revision) const {
566 assert(getOS() == Darwin && "Not a darwin target triple!");
567 StringRef OSName = getOSName();
568 assert(OSName.startswith("darwin") && "Unknown darwin target triple!");
Jim Grosbache509aa92010-12-17 02:10:59 +0000569
Chris Lattnerdfc17f72009-08-12 06:19:40 +0000570 // Strip off "darwin".
571 OSName = OSName.substr(6);
Jim Grosbache509aa92010-12-17 02:10:59 +0000572
Chris Lattnerdfc17f72009-08-12 06:19:40 +0000573 Maj = Min = Revision = 0;
574
575 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
576 return;
577
578 // The major version is the first digit.
579 Maj = EatNumber(OSName);
580 if (OSName.empty()) return;
Jim Grosbache509aa92010-12-17 02:10:59 +0000581
Chris Lattnerdfc17f72009-08-12 06:19:40 +0000582 // Handle minor version: 10.4.9 -> darwin8.9.
583 if (OSName[0] != '.')
584 return;
Jim Grosbache509aa92010-12-17 02:10:59 +0000585
Chris Lattnerdfc17f72009-08-12 06:19:40 +0000586 // Eat the '.'.
587 OSName = OSName.substr(1);
588
589 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
590 return;
Jim Grosbache509aa92010-12-17 02:10:59 +0000591
Chris Lattnerdfc17f72009-08-12 06:19:40 +0000592 Min = EatNumber(OSName);
593 if (OSName.empty()) return;
594
595 // Handle revision darwin8.9.1
596 if (OSName[0] != '.')
597 return;
Jim Grosbache509aa92010-12-17 02:10:59 +0000598
Chris Lattnerdfc17f72009-08-12 06:19:40 +0000599 // Eat the '.'.
600 OSName = OSName.substr(1);
Jim Grosbache509aa92010-12-17 02:10:59 +0000601
Chris Lattnerdfc17f72009-08-12 06:19:40 +0000602 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
603 return;
604
605 Revision = EatNumber(OSName);
606}
607
Daniel Dunbara14d2252009-07-26 03:31:47 +0000608void Triple::setTriple(const Twine &Str) {
609 Data = Str.str();
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000610 Arch = InvalidArch;
611}
612
613void Triple::setArch(ArchType Kind) {
614 setArchName(getArchTypeName(Kind));
615}
616
617void Triple::setVendor(VendorType Kind) {
618 setVendorName(getVendorTypeName(Kind));
619}
620
621void Triple::setOS(OSType Kind) {
622 setOSName(getOSTypeName(Kind));
623}
624
Duncan Sands5754a452010-09-16 08:25:48 +0000625void Triple::setEnvironment(EnvironmentType Kind) {
626 setEnvironmentName(getEnvironmentTypeName(Kind));
627}
628
Daniel Dunbar2928c832009-11-06 10:58:06 +0000629void Triple::setArchName(StringRef Str) {
Jeffrey Yasskin0b228732009-10-06 21:45:26 +0000630 // Work around a miscompilation bug for Twines in gcc 4.0.3.
631 SmallString<64> Triple;
632 Triple += Str;
633 Triple += "-";
634 Triple += getVendorName();
635 Triple += "-";
636 Triple += getOSAndEnvironmentName();
637 setTriple(Triple.str());
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000638}
639
Daniel Dunbar2928c832009-11-06 10:58:06 +0000640void Triple::setVendorName(StringRef Str) {
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000641 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
642}
643
Daniel Dunbar2928c832009-11-06 10:58:06 +0000644void Triple::setOSName(StringRef Str) {
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000645 if (hasEnvironment())
646 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
647 "-" + getEnvironmentName());
648 else
649 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
650}
651
Daniel Dunbar2928c832009-11-06 10:58:06 +0000652void Triple::setEnvironmentName(StringRef Str) {
653 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000654 "-" + Str);
655}
656
Daniel Dunbar2928c832009-11-06 10:58:06 +0000657void Triple::setOSAndEnvironmentName(StringRef Str) {
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000658 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
659}