blob: 14e9f5bbfcfb00a10e0c8450bca014fe73eba184 [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"
Jeffrey Yasskin0b228732009-10-06 21:45:26 +000011#include "llvm/ADT/SmallString.h"
Chandler Carruth06accda2012-02-12 09:27:38 +000012#include "llvm/ADT/StringSwitch.h"
Duncan Sands5754a452010-09-16 08:25:48 +000013#include "llvm/ADT/STLExtras.h"
David Blaikie4d6ccb52012-01-20 21:51:11 +000014#include "llvm/Support/ErrorHandling.h"
Mikhail Glushenkov70748752009-04-02 01:11:37 +000015#include <cstring>
Daniel Dunbar23e97b02009-04-01 21:53:23 +000016using namespace llvm;
17
Daniel Dunbar23e97b02009-04-01 21:53:23 +000018const char *Triple::getArchTypeName(ArchType Kind) {
19 switch (Kind) {
20 case InvalidArch: return "<invalid>";
21 case UnknownArch: return "unknown";
Jim Grosbache509aa92010-12-17 02:10:59 +000022
Daniel Dunbar6337f152009-07-26 04:23:03 +000023 case arm: return "arm";
24 case cellspu: return "cellspu";
Tony Linthicumb4b54152011-12-12 21:14:40 +000025 case hexagon: return "hexagon";
Daniel Dunbar6337f152009-07-26 04:23:03 +000026 case mips: return "mips";
27 case mipsel: return "mipsel";
Akira Hatanaka70303682011-09-20 18:09:37 +000028 case mips64: return "mips64";
29 case mips64el:return "mips64el";
Daniel Dunbar6337f152009-07-26 04:23:03 +000030 case msp430: return "msp430";
Daniel Dunbar8c2f1d72009-07-26 04:52:45 +000031 case ppc64: return "powerpc64";
32 case ppc: return "powerpc";
Daniel Dunbar6337f152009-07-26 04:23:03 +000033 case sparc: return "sparc";
Chris Lattner87c06d62010-02-04 06:34:01 +000034 case sparcv9: return "sparcv9";
Eli Friedman74db89e2009-08-19 20:46:03 +000035 case tce: return "tce";
Daniel Dunbar6337f152009-07-26 04:23:03 +000036 case thumb: return "thumb";
37 case x86: return "i386";
38 case x86_64: return "x86_64";
Daniel Dunbar8c2f1d72009-07-26 04:52:45 +000039 case xcore: return "xcore";
Wesley Pecka70f28c2010-02-23 19:15:24 +000040 case mblaze: return "mblaze";
Justin Holewinskie1fee482011-04-20 15:37:17 +000041 case ptx32: return "ptx32";
42 case ptx64: return "ptx64";
Ivan Krasin38fb2db2011-08-23 16:59:00 +000043 case le32: return "le32";
Tobias Grosser05d71382011-08-29 15:44:55 +000044 case amdil: return "amdil";
Daniel Dunbar23e97b02009-04-01 21:53:23 +000045 }
46
David Blaikie4d6ccb52012-01-20 21:51:11 +000047 llvm_unreachable("Invalid ArchType!");
Daniel Dunbar23e97b02009-04-01 21:53:23 +000048}
49
Daniel Dunbar688b55b2009-08-24 09:53:06 +000050const char *Triple::getArchTypePrefix(ArchType Kind) {
51 switch (Kind) {
52 default:
53 return 0;
54
Daniel Dunbar688b55b2009-08-24 09:53:06 +000055 case arm:
56 case thumb: return "arm";
57
Daniel Dunbar688b55b2009-08-24 09:53:06 +000058 case cellspu: return "spu";
59
60 case ppc64:
61 case ppc: return "ppc";
62
Wesley Pecka70f28c2010-02-23 19:15:24 +000063 case mblaze: return "mblaze";
64
Tony Linthicumb4b54152011-12-12 21:14:40 +000065 case hexagon: return "hexagon";
66
Chris Lattner87c06d62010-02-04 06:34:01 +000067 case sparcv9:
Daniel Dunbar688b55b2009-08-24 09:53:06 +000068 case sparc: return "sparc";
69
70 case x86:
71 case x86_64: return "x86";
Nick Lewyckyf7a3c502010-09-07 18:14:24 +000072
Daniel Dunbar688b55b2009-08-24 09:53:06 +000073 case xcore: return "xcore";
Nick Lewyckyf7a3c502010-09-07 18:14:24 +000074
Justin Holewinskie1fee482011-04-20 15:37:17 +000075 case ptx32: return "ptx";
76 case ptx64: return "ptx";
Ivan Krasin38fb2db2011-08-23 16:59:00 +000077 case le32: return "le32";
Tobias Grosser05d71382011-08-29 15:44:55 +000078 case amdil: return "amdil";
Daniel Dunbar688b55b2009-08-24 09:53:06 +000079 }
80}
81
Daniel Dunbar23e97b02009-04-01 21:53:23 +000082const char *Triple::getVendorTypeName(VendorType Kind) {
83 switch (Kind) {
84 case UnknownVendor: return "unknown";
85
86 case Apple: return "apple";
Chris Lattner56ce0f42009-08-14 18:48:13 +000087 case PC: return "pc";
John Thompson6046cff2011-03-15 21:51:56 +000088 case SCEI: return "scei";
Daniel Dunbar23e97b02009-04-01 21:53:23 +000089 }
90
David Blaikie4d6ccb52012-01-20 21:51:11 +000091 llvm_unreachable("Invalid VendorType!");
Daniel Dunbar23e97b02009-04-01 21:53:23 +000092}
93
94const char *Triple::getOSTypeName(OSType Kind) {
95 switch (Kind) {
96 case UnknownOS: return "unknown";
97
Duncan Sands852cd112009-06-19 14:40:01 +000098 case AuroraUX: return "auroraux";
Daniel Dunbar6337f152009-07-26 04:23:03 +000099 case Cygwin: return "cygwin";
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000100 case Darwin: return "darwin";
Daniel Dunbar7eaf0572009-05-22 02:24:11 +0000101 case DragonFly: return "dragonfly";
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000102 case FreeBSD: return "freebsd";
Daniel Dunbar0dde4c02011-04-19 20:19:27 +0000103 case IOS: return "ios";
Duncan Sands652b48b2011-07-26 15:30:04 +0000104 case KFreeBSD: return "kfreebsd";
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000105 case Linux: return "linux";
Edward O'Callaghancc9fa812009-11-19 11:59:00 +0000106 case Lv2: return "lv2";
Daniel Dunbar1af39472011-04-19 23:34:12 +0000107 case MacOSX: return "macosx";
Daniel Dunbar6337f152009-07-26 04:23:03 +0000108 case MinGW32: return "mingw32";
Chris Lattnerb8ac8412009-07-13 20:22:23 +0000109 case NetBSD: return "netbsd";
Duncan Sandscd1267d2009-06-29 13:36:13 +0000110 case OpenBSD: return "openbsd";
Edward O'Callaghane0fb75d2009-11-15 10:18:17 +0000111 case Psp: return "psp";
Daniel Dunbarfdb0b7b2009-08-18 04:43:27 +0000112 case Solaris: return "solaris";
Daniel Dunbar6337f152009-07-26 04:23:03 +0000113 case Win32: return "win32";
Chris Lattnera43fc342009-10-16 02:06:30 +0000114 case Haiku: return "haiku";
Chris Lattner29269d02010-07-07 15:52:27 +0000115 case Minix: return "minix";
Douglas Gregor6ced1d12011-07-01 22:41:06 +0000116 case RTEMS: return "rtems";
Ivan Krasinfb234622011-08-18 22:54:21 +0000117 case NativeClient: return "nacl";
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000118 }
119
David Blaikie4d6ccb52012-01-20 21:51:11 +0000120 llvm_unreachable("Invalid OSType");
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000121}
122
Duncan Sands5754a452010-09-16 08:25:48 +0000123const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
124 switch (Kind) {
125 case UnknownEnvironment: return "unknown";
Renato Golin859f8182011-01-21 18:25:47 +0000126 case GNU: return "gnu";
Rafael Espindola8887a0f2012-01-18 23:35:29 +0000127 case GNUEABIHF: return "gnueabihf";
Renato Golin859f8182011-01-21 18:25:47 +0000128 case GNUEABI: return "gnueabi";
129 case EABI: return "eabi";
Evan Cheng2bffee22011-02-01 01:14:13 +0000130 case MachO: return "macho";
Chandler Carruthfd553c22012-01-10 19:46:00 +0000131 case ANDROIDEABI: return "androideabi";
Duncan Sands5754a452010-09-16 08:25:48 +0000132 }
133
David Blaikie4d6ccb52012-01-20 21:51:11 +0000134 llvm_unreachable("Invalid EnvironmentType!");
Duncan Sands5754a452010-09-16 08:25:48 +0000135}
136
Daniel Dunbar2928c832009-11-06 10:58:06 +0000137Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
Chandler Carruth06accda2012-02-12 09:27:38 +0000138 return StringSwitch<Triple::ArchType>(Name)
139 .Case("arm", arm)
140 .Case("cellspu", cellspu)
141 .Case("mips", mips)
142 .Case("mipsel", mipsel)
143 .Case("mips64", mips64)
144 .Case("mips64el", mips64el)
145 .Case("msp430", msp430)
146 .Case("ppc64", ppc64)
147 .Case("ppc32", ppc)
148 .Case("ppc", ppc)
149 .Case("mblaze", mblaze)
150 .Case("hexagon", hexagon)
151 .Case("sparc", sparc)
152 .Case("sparcv9", sparcv9)
153 .Case("tce", tce)
154 .Case("thumb", thumb)
155 .Case("x86", x86)
156 .Case("x86-64", x86_64)
157 .Case("xcore", xcore)
158 .Case("ptx32", ptx32)
159 .Case("ptx64", ptx64)
160 .Case("le32", le32)
161 .Case("amdil", amdil)
162 .Default(UnknownArch);
Daniel Dunbar3c2d4bf2009-08-03 04:03:51 +0000163}
164
Daniel Dunbar2928c832009-11-06 10:58:06 +0000165Triple::ArchType Triple::getArchTypeForDarwinArchName(StringRef Str) {
Daniel Dunbarbaf9b562009-09-08 23:32:51 +0000166 // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
167 // archs which Darwin doesn't use.
168
169 // The matching this routine does is fairly pointless, since it is neither the
170 // complete architecture list, nor a reasonable subset. The problem is that
171 // historically the driver driver accepts this and also ties its -march=
172 // handling to the architecture name, so we need to be careful before removing
173 // support for it.
174
Daniel Dunbared687882009-09-09 23:01:25 +0000175 // This code must be kept in sync with Clang's Darwin specific argument
176 // translation.
177
Chandler Carruth06accda2012-02-12 09:27:38 +0000178 return StringSwitch<ArchType>(Str)
179 .Cases("ppc", "ppc601", "ppc603", "ppc604", "ppc604e", Triple::ppc)
180 .Cases("ppc750", "ppc7400", "ppc7450", "ppc970", Triple::ppc)
181 .Case("ppc64", Triple::ppc64)
182 .Cases("i386", "i486", "i486SX", "i586", "i686", Triple::x86)
183 .Cases("pentium", "pentpro", "pentIIm3", "pentIIm5", "pentium4",
184 Triple::x86)
185 .Case("x86_64", Triple::x86_64)
186 // This is derived from the driver driver.
187 .Cases("arm", "armv4t", "armv5", "armv6", Triple::arm)
188 .Cases("armv7", "armv7f", "armv7k", "armv7s", "xscale", Triple::arm)
189 .Case("ptx32", Triple::ptx32)
190 .Case("ptx64", Triple::ptx64)
191 .Case("amdil", Triple::amdil)
192 .Default(Triple::UnknownArch);
Daniel Dunbarbaf9b562009-09-08 23:32:51 +0000193}
194
Duncan Sandsbbdca3f2010-03-24 09:05:14 +0000195// Returns architecture name that is understood by the target assembler.
Viktor Kutuzov51cdac02009-11-17 18:48:27 +0000196const char *Triple::getArchNameForAssembler() {
Daniel Dunbare1fe09f2011-04-19 21:12:05 +0000197 if (!isOSDarwin() && getVendor() != Triple::Apple)
Viktor Kutuzov51cdac02009-11-17 18:48:27 +0000198 return NULL;
199
Chandler Carruth06accda2012-02-12 09:27:38 +0000200 return StringSwitch<const char*>(getArchName())
201 .Case("i386", "i386")
202 .Case("x86_64", "x86_64")
203 .Case("powerpc", "ppc")
204 .Case("powerpc64", "ppc64")
205 .Cases("mblaze", "microblaze", "mblaze")
206 .Case("arm", "arm")
207 .Cases("armv4t", "thumbv4t", "armv4t")
208 .Cases("armv5", "armv5e", "thumbv5", "thumbv5e", "armv5")
209 .Cases("armv6", "thumbv6", "armv6")
210 .Cases("armv7", "thumbv7", "armv7")
211 .Case("ptx32", "ptx32")
212 .Case("ptx64", "ptx64")
213 .Case("le32", "le32")
214 .Case("amdil", "amdil")
215 .Default(NULL);
Viktor Kutuzov51cdac02009-11-17 18:48:27 +0000216}
217
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000218//
219
Duncan Sands335db222010-08-12 11:31:39 +0000220Triple::ArchType Triple::ParseArch(StringRef ArchName) {
Chandler Carruth06accda2012-02-12 09:27:38 +0000221 return StringSwitch<ArchType>(ArchName)
Benjamin Kramer61c2c122012-02-12 10:56:52 +0000222 // FIXME: It would be good to replace these with explicit names for all the
223 // various suffixes supported.
224 .StartsWith("armv", arm)
225 .StartsWith("thumbv", thumb)
Chandler Carruth06accda2012-02-12 09:27:38 +0000226 .Cases("i386", "i486", "i586", "i686", x86)
227 .Cases("i786", "i886", "i986", x86) // FIXME: Do we need to support these?
228 .Cases("amd64", "x86_64", x86_64)
229 .Case("powerpc", ppc)
230 .Cases("powerpc64", "ppu", ppc64)
231 .Case("mblaze", mblaze)
232 .Cases("arm", "xscale", arm)
233 .Case("thumb", thumb)
234 .Cases("spu", "cellspu", cellspu)
235 .Case("msp430", msp430)
236 .Cases("mips", "mipseb", "mipsallegrex", mips)
237 .Cases("mipsel", "mipsallegrexel", "psp", mipsel)
238 .Cases("mips64", "mips64eb", mips64)
239 .Case("mips64el", mips64el)
240 .Case("hexagon", hexagon)
241 .Case("sparc", sparc)
242 .Case("sparcv9", sparcv9)
243 .Case("tce", tce)
244 .Case("xcore", xcore)
245 .Case("ptx32", ptx32)
246 .Case("ptx64", ptx64)
247 .Case("le32", le32)
248 .Case("amdil", amdil)
249 .Default(UnknownArch);
Duncan Sands335db222010-08-12 11:31:39 +0000250}
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000251
Duncan Sands335db222010-08-12 11:31:39 +0000252Triple::VendorType Triple::ParseVendor(StringRef VendorName) {
Chandler Carruth06accda2012-02-12 09:27:38 +0000253 return StringSwitch<VendorType>(VendorName)
254 .Case("apple", Apple)
255 .Case("pc", PC)
256 .Case("scei", SCEI)
257 .Default(UnknownVendor);
Duncan Sands335db222010-08-12 11:31:39 +0000258}
259
260Triple::OSType Triple::ParseOS(StringRef OSName) {
Benjamin Kramer61c2c122012-02-12 10:56:52 +0000261 return StringSwitch<OSType>(OSName)
262 .StartsWith("auroraux", AuroraUX)
263 .StartsWith("cygwin", Cygwin)
264 .StartsWith("darwin", Darwin)
265 .StartsWith("dragonfly", DragonFly)
266 .StartsWith("freebsd", FreeBSD)
267 .StartsWith("ios", IOS)
268 .StartsWith("kfreebsd", KFreeBSD)
269 .StartsWith("linux", Linux)
270 .StartsWith("lv2", Lv2)
271 .StartsWith("macosx", MacOSX)
272 .StartsWith("mingw32", MinGW32)
273 .StartsWith("netbsd", NetBSD)
274 .StartsWith("openbsd", OpenBSD)
275 .StartsWith("psp", Psp)
276 .StartsWith("solaris", Solaris)
277 .StartsWith("win32", Win32)
278 .StartsWith("haiku", Haiku)
279 .StartsWith("minix", Minix)
280 .StartsWith("rtems", RTEMS)
281 .StartsWith("nacl", NativeClient)
282 .Default(UnknownOS);
Duncan Sands335db222010-08-12 11:31:39 +0000283}
284
Duncan Sands5754a452010-09-16 08:25:48 +0000285Triple::EnvironmentType Triple::ParseEnvironment(StringRef EnvironmentName) {
Benjamin Kramer61c2c122012-02-12 10:56:52 +0000286 return StringSwitch<EnvironmentType>(EnvironmentName)
287 .StartsWith("eabi", EABI)
288 .StartsWith("gnueabihf", GNUEABIHF)
289 .StartsWith("gnueabi", GNUEABI)
290 .StartsWith("gnu", GNU)
291 .StartsWith("macho", MachO)
292 .StartsWith("androideabi", ANDROIDEABI)
293 .Default(UnknownEnvironment);
Duncan Sands5754a452010-09-16 08:25:48 +0000294}
295
Duncan Sands335db222010-08-12 11:31:39 +0000296void Triple::Parse() const {
297 assert(!isInitialized() && "Invalid parse call.");
298
299 Arch = ParseArch(getArchName());
300 Vendor = ParseVendor(getVendorName());
301 OS = ParseOS(getOSName());
Duncan Sandsae200c62011-02-02 10:08:38 +0000302 Environment = ParseEnvironment(getEnvironmentName());
Daniel Dunbar651aa682009-08-18 19:26:55 +0000303
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000304 assert(isInitialized() && "Failed to initialize!");
305}
306
Duncan Sands335db222010-08-12 11:31:39 +0000307std::string Triple::normalize(StringRef Str) {
308 // Parse into components.
309 SmallVector<StringRef, 4> Components;
310 for (size_t First = 0, Last = 0; Last != StringRef::npos; First = Last + 1) {
311 Last = Str.find('-', First);
312 Components.push_back(Str.slice(First, Last));
313 }
314
315 // If the first component corresponds to a known architecture, preferentially
316 // use it for the architecture. If the second component corresponds to a
317 // known vendor, preferentially use it for the vendor, etc. This avoids silly
318 // component movement when a component parses as (eg) both a valid arch and a
319 // valid os.
320 ArchType Arch = UnknownArch;
321 if (Components.size() > 0)
322 Arch = ParseArch(Components[0]);
323 VendorType Vendor = UnknownVendor;
324 if (Components.size() > 1)
325 Vendor = ParseVendor(Components[1]);
326 OSType OS = UnknownOS;
327 if (Components.size() > 2)
328 OS = ParseOS(Components[2]);
Duncan Sands5754a452010-09-16 08:25:48 +0000329 EnvironmentType Environment = UnknownEnvironment;
330 if (Components.size() > 3)
331 Environment = ParseEnvironment(Components[3]);
Duncan Sands335db222010-08-12 11:31:39 +0000332
333 // Note which components are already in their final position. These will not
334 // be moved.
Duncan Sands5754a452010-09-16 08:25:48 +0000335 bool Found[4];
Duncan Sands335db222010-08-12 11:31:39 +0000336 Found[0] = Arch != UnknownArch;
337 Found[1] = Vendor != UnknownVendor;
338 Found[2] = OS != UnknownOS;
Duncan Sands5754a452010-09-16 08:25:48 +0000339 Found[3] = Environment != UnknownEnvironment;
Duncan Sands335db222010-08-12 11:31:39 +0000340
341 // If they are not there already, permute the components into their canonical
342 // positions by seeing if they parse as a valid architecture, and if so moving
343 // the component to the architecture position etc.
Duncan Sands5754a452010-09-16 08:25:48 +0000344 for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) {
Duncan Sands335db222010-08-12 11:31:39 +0000345 if (Found[Pos])
346 continue; // Already in the canonical position.
347
348 for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
349 // Do not reparse any components that already matched.
Duncan Sands5754a452010-09-16 08:25:48 +0000350 if (Idx < array_lengthof(Found) && Found[Idx])
Duncan Sands335db222010-08-12 11:31:39 +0000351 continue;
352
353 // Does this component parse as valid for the target position?
354 bool Valid = false;
355 StringRef Comp = Components[Idx];
356 switch (Pos) {
Craig Topper85814382012-02-07 05:05:23 +0000357 default: llvm_unreachable("unexpected component type!");
Duncan Sands335db222010-08-12 11:31:39 +0000358 case 0:
359 Arch = ParseArch(Comp);
360 Valid = Arch != UnknownArch;
361 break;
362 case 1:
363 Vendor = ParseVendor(Comp);
364 Valid = Vendor != UnknownVendor;
365 break;
366 case 2:
367 OS = ParseOS(Comp);
Duncan Sandsae200c62011-02-02 10:08:38 +0000368 Valid = OS != UnknownOS;
Duncan Sands335db222010-08-12 11:31:39 +0000369 break;
Duncan Sands5754a452010-09-16 08:25:48 +0000370 case 3:
371 Environment = ParseEnvironment(Comp);
372 Valid = Environment != UnknownEnvironment;
373 break;
Duncan Sands335db222010-08-12 11:31:39 +0000374 }
375 if (!Valid)
376 continue; // Nope, try the next component.
377
378 // Move the component to the target position, pushing any non-fixed
379 // components that are in the way to the right. This tends to give
380 // good results in the common cases of a forgotten vendor component
381 // or a wrongly positioned environment.
382 if (Pos < Idx) {
383 // Insert left, pushing the existing components to the right. For
384 // example, a-b-i386 -> i386-a-b when moving i386 to the front.
385 StringRef CurrentComponent(""); // The empty component.
386 // Replace the component we are moving with an empty component.
387 std::swap(CurrentComponent, Components[Idx]);
388 // Insert the component being moved at Pos, displacing any existing
389 // components to the right.
390 for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
391 // Skip over any fixed components.
Duncan Sands5754a452010-09-16 08:25:48 +0000392 while (i < array_lengthof(Found) && Found[i]) ++i;
Duncan Sands335db222010-08-12 11:31:39 +0000393 // Place the component at the new position, getting the component
394 // that was at this position - it will be moved right.
395 std::swap(CurrentComponent, Components[i]);
396 }
397 } else if (Pos > Idx) {
398 // Push right by inserting empty components until the component at Idx
399 // reaches the target position Pos. For example, pc-a -> -pc-a when
400 // moving pc to the second position.
401 do {
402 // Insert one empty component at Idx.
403 StringRef CurrentComponent(""); // The empty component.
Duncan Sandsae200c62011-02-02 10:08:38 +0000404 for (unsigned i = Idx; i < Components.size();) {
Duncan Sands335db222010-08-12 11:31:39 +0000405 // Place the component at the new position, getting the component
406 // that was at this position - it will be moved right.
407 std::swap(CurrentComponent, Components[i]);
408 // If it was placed on top of an empty component then we are done.
409 if (CurrentComponent.empty())
410 break;
Duncan Sandsae200c62011-02-02 10:08:38 +0000411 // Advance to the next component, skipping any fixed components.
Anders Carlsson15ec6952011-02-05 18:19:35 +0000412 while (++i < array_lengthof(Found) && Found[i])
413 ;
Duncan Sands335db222010-08-12 11:31:39 +0000414 }
415 // The last component was pushed off the end - append it.
416 if (!CurrentComponent.empty())
417 Components.push_back(CurrentComponent);
418
419 // Advance Idx to the component's new position.
Duncan Sands5754a452010-09-16 08:25:48 +0000420 while (++Idx < array_lengthof(Found) && Found[Idx]) {}
Duncan Sands335db222010-08-12 11:31:39 +0000421 } while (Idx < Pos); // Add more until the final position is reached.
422 }
423 assert(Pos < Components.size() && Components[Pos] == Comp &&
424 "Component moved wrong!");
425 Found[Pos] = true;
426 break;
427 }
428 }
429
430 // Special case logic goes here. At this point Arch, Vendor and OS have the
431 // correct values for the computed components.
432
433 // Stick the corrected components back together to form the normalized string.
434 std::string Normalized;
435 for (unsigned i = 0, e = Components.size(); i != e; ++i) {
436 if (i) Normalized += '-';
437 Normalized += Components[i];
438 }
439 return Normalized;
440}
441
Daniel Dunbara14d2252009-07-26 03:31:47 +0000442StringRef Triple::getArchName() const {
443 return StringRef(Data).split('-').first; // Isolate first component
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000444}
445
Daniel Dunbara14d2252009-07-26 03:31:47 +0000446StringRef Triple::getVendorName() const {
447 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
448 return Tmp.split('-').first; // Isolate second component
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000449}
450
Daniel Dunbara14d2252009-07-26 03:31:47 +0000451StringRef Triple::getOSName() const {
452 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
453 Tmp = Tmp.split('-').second; // Strip second component
454 return Tmp.split('-').first; // Isolate third component
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000455}
456
Daniel Dunbara14d2252009-07-26 03:31:47 +0000457StringRef Triple::getEnvironmentName() const {
458 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
459 Tmp = Tmp.split('-').second; // Strip second component
460 return Tmp.split('-').second; // Strip third component
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000461}
462
Daniel Dunbara14d2252009-07-26 03:31:47 +0000463StringRef Triple::getOSAndEnvironmentName() const {
464 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
465 return Tmp.split('-').second; // Strip second component
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000466}
467
Chris Lattnerdfc17f72009-08-12 06:19:40 +0000468static unsigned EatNumber(StringRef &Str) {
469 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
Daniel Dunbar087d6a52011-04-19 20:24:34 +0000470 unsigned Result = 0;
Jim Grosbache509aa92010-12-17 02:10:59 +0000471
Daniel Dunbar087d6a52011-04-19 20:24:34 +0000472 do {
473 // Consume the leading digit.
Chris Lattnerdfc17f72009-08-12 06:19:40 +0000474 Result = Result*10 + (Str[0] - '0');
Daniel Dunbar087d6a52011-04-19 20:24:34 +0000475
Chris Lattnerdfc17f72009-08-12 06:19:40 +0000476 // Eat the digit.
477 Str = Str.substr(1);
Daniel Dunbar087d6a52011-04-19 20:24:34 +0000478 } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9');
Jim Grosbache509aa92010-12-17 02:10:59 +0000479
Chris Lattnerdfc17f72009-08-12 06:19:40 +0000480 return Result;
481}
482
Daniel Dunbar087d6a52011-04-19 20:24:34 +0000483void Triple::getOSVersion(unsigned &Major, unsigned &Minor,
484 unsigned &Micro) const {
Chris Lattnerdfc17f72009-08-12 06:19:40 +0000485 StringRef OSName = getOSName();
Jim Grosbache509aa92010-12-17 02:10:59 +0000486
Daniel Dunbar087d6a52011-04-19 20:24:34 +0000487 // Assume that the OS portion of the triple starts with the canonical name.
488 StringRef OSTypeName = getOSTypeName(getOS());
489 if (OSName.startswith(OSTypeName))
490 OSName = OSName.substr(OSTypeName.size());
Jim Grosbache509aa92010-12-17 02:10:59 +0000491
Daniel Dunbar087d6a52011-04-19 20:24:34 +0000492 // Any unset version defaults to 0.
493 Major = Minor = Micro = 0;
Chris Lattnerdfc17f72009-08-12 06:19:40 +0000494
Daniel Dunbar087d6a52011-04-19 20:24:34 +0000495 // Parse up to three components.
496 unsigned *Components[3] = { &Major, &Minor, &Micro };
497 for (unsigned i = 0; i != 3; ++i) {
498 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
499 break;
Chris Lattnerdfc17f72009-08-12 06:19:40 +0000500
Daniel Dunbar087d6a52011-04-19 20:24:34 +0000501 // Consume the leading number.
502 *Components[i] = EatNumber(OSName);
Jim Grosbache509aa92010-12-17 02:10:59 +0000503
Daniel Dunbar087d6a52011-04-19 20:24:34 +0000504 // Consume the separator, if present.
505 if (OSName.startswith("."))
506 OSName = OSName.substr(1);
507 }
Chris Lattnerdfc17f72009-08-12 06:19:40 +0000508}
509
Bob Wilsonbda59fd2012-01-31 22:32:29 +0000510bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor,
511 unsigned &Micro) const {
512 getOSVersion(Major, Minor, Micro);
513
514 switch (getOS()) {
Craig Topper85814382012-02-07 05:05:23 +0000515 default: llvm_unreachable("unexpected OS for Darwin triple");
Bob Wilsonbda59fd2012-01-31 22:32:29 +0000516 case Darwin:
517 // Default to darwin8, i.e., MacOSX 10.4.
518 if (Major == 0)
519 Major = 8;
520 // Darwin version numbers are skewed from OS X versions.
521 if (Major < 4)
522 return false;
523 Micro = 0;
524 Minor = Major - 4;
525 Major = 10;
526 break;
527 case MacOSX:
528 // Default to 10.4.
529 if (Major == 0) {
530 Major = 10;
531 Minor = 4;
532 }
533 if (Major != 10)
534 return false;
535 break;
536 case IOS:
537 // Ignore the version from the triple. This is only handled because the
538 // the clang driver combines OS X and IOS support into a common Darwin
539 // toolchain that wants to know the OS X version number even when targeting
540 // IOS.
541 Major = 10;
542 Minor = 4;
543 Micro = 0;
544 break;
545 }
546 return true;
547}
548
Daniel Dunbara14d2252009-07-26 03:31:47 +0000549void Triple::setTriple(const Twine &Str) {
550 Data = Str.str();
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000551 Arch = InvalidArch;
552}
553
554void Triple::setArch(ArchType Kind) {
555 setArchName(getArchTypeName(Kind));
556}
557
558void Triple::setVendor(VendorType Kind) {
559 setVendorName(getVendorTypeName(Kind));
560}
561
562void Triple::setOS(OSType Kind) {
563 setOSName(getOSTypeName(Kind));
564}
565
Duncan Sands5754a452010-09-16 08:25:48 +0000566void Triple::setEnvironment(EnvironmentType Kind) {
567 setEnvironmentName(getEnvironmentTypeName(Kind));
568}
569
Daniel Dunbar2928c832009-11-06 10:58:06 +0000570void Triple::setArchName(StringRef Str) {
Jeffrey Yasskin0b228732009-10-06 21:45:26 +0000571 // Work around a miscompilation bug for Twines in gcc 4.0.3.
572 SmallString<64> Triple;
573 Triple += Str;
574 Triple += "-";
575 Triple += getVendorName();
576 Triple += "-";
577 Triple += getOSAndEnvironmentName();
578 setTriple(Triple.str());
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000579}
580
Daniel Dunbar2928c832009-11-06 10:58:06 +0000581void Triple::setVendorName(StringRef Str) {
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000582 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
583}
584
Daniel Dunbar2928c832009-11-06 10:58:06 +0000585void Triple::setOSName(StringRef Str) {
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000586 if (hasEnvironment())
587 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
588 "-" + getEnvironmentName());
589 else
590 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
591}
592
Daniel Dunbar2928c832009-11-06 10:58:06 +0000593void Triple::setEnvironmentName(StringRef Str) {
594 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000595 "-" + Str);
596}
597
Daniel Dunbar2928c832009-11-06 10:58:06 +0000598void Triple::setOSAndEnvironmentName(StringRef Str) {
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000599 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
600}
Chandler Carruth6f72ac42012-01-31 04:52:32 +0000601
602static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
603 switch (Arch) {
604 case llvm::Triple::UnknownArch:
605 case llvm::Triple::InvalidArch:
606 return 0;
607
608 case llvm::Triple::msp430:
609 return 16;
610
611 case llvm::Triple::amdil:
612 case llvm::Triple::arm:
613 case llvm::Triple::cellspu:
614 case llvm::Triple::hexagon:
615 case llvm::Triple::le32:
616 case llvm::Triple::mblaze:
617 case llvm::Triple::mips:
618 case llvm::Triple::mipsel:
619 case llvm::Triple::ppc:
620 case llvm::Triple::ptx32:
621 case llvm::Triple::sparc:
622 case llvm::Triple::tce:
623 case llvm::Triple::thumb:
624 case llvm::Triple::x86:
625 case llvm::Triple::xcore:
626 return 32;
627
628 case llvm::Triple::mips64:
629 case llvm::Triple::mips64el:
630 case llvm::Triple::ppc64:
631 case llvm::Triple::ptx64:
632 case llvm::Triple::sparcv9:
633 case llvm::Triple::x86_64:
634 return 64;
635 }
636 llvm_unreachable("Invalid architecture value");
637}
638
639bool Triple::isArch64Bit() const {
640 return getArchPointerBitWidth(getArch()) == 64;
641}
642
643bool Triple::isArch32Bit() const {
644 return getArchPointerBitWidth(getArch()) == 32;
645}
646
647bool Triple::isArch16Bit() const {
648 return getArchPointerBitWidth(getArch()) == 16;
649}
Chandler Carruth7d5a2892012-02-06 20:46:33 +0000650
651Triple Triple::get32BitArchVariant() const {
652 Triple T(*this);
653 switch (getArch()) {
654 case Triple::UnknownArch:
655 case Triple::InvalidArch:
656 case Triple::msp430:
657 T.setArch(UnknownArch);
658 break;
659
660 case Triple::amdil:
661 case Triple::arm:
662 case Triple::cellspu:
663 case Triple::hexagon:
664 case Triple::le32:
665 case Triple::mblaze:
666 case Triple::mips:
667 case Triple::mipsel:
668 case Triple::ppc:
669 case Triple::ptx32:
670 case Triple::sparc:
671 case Triple::tce:
672 case Triple::thumb:
673 case Triple::x86:
674 case Triple::xcore:
675 // Already 32-bit.
676 break;
677
678 case Triple::mips64: T.setArch(Triple::mips); break;
679 case Triple::mips64el: T.setArch(Triple::mipsel); break;
680 case Triple::ppc64: T.setArch(Triple::ppc); break;
681 case Triple::ptx64: T.setArch(Triple::ptx32); break;
682 case Triple::sparcv9: T.setArch(Triple::sparc); break;
683 case Triple::x86_64: T.setArch(Triple::x86); break;
684 }
685 return T;
686}
687
688Triple Triple::get64BitArchVariant() const {
689 Triple T(*this);
690 switch (getArch()) {
691 case Triple::InvalidArch:
692 case Triple::UnknownArch:
693 case Triple::amdil:
694 case Triple::arm:
695 case Triple::cellspu:
696 case Triple::hexagon:
697 case Triple::le32:
698 case Triple::mblaze:
699 case Triple::msp430:
700 case Triple::tce:
701 case Triple::thumb:
702 case Triple::xcore:
703 T.setArch(UnknownArch);
704 break;
705
706 case Triple::mips64:
707 case Triple::mips64el:
708 case Triple::ppc64:
709 case Triple::ptx64:
710 case Triple::sparcv9:
711 case Triple::x86_64:
712 // Already 64-bit.
713 break;
714
715 case Triple::mips: T.setArch(Triple::mips64); break;
716 case Triple::mipsel: T.setArch(Triple::mips64el); break;
717 case Triple::ppc: T.setArch(Triple::ppc64); break;
718 case Triple::ptx32: T.setArch(Triple::ptx64); break;
719 case Triple::sparc: T.setArch(Triple::sparcv9); break;
720 case Triple::x86: T.setArch(Triple::x86_64); break;
721 }
722 return T;
723}