blob: 24ead35c20dff481d5cad5d4a43b9fdc7c699857 [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
Duncan Sands335db222010-08-12 11:31:39 +0000218Triple::ArchType Triple::ParseArch(StringRef ArchName) {
Chandler Carruth06accda2012-02-12 09:27:38 +0000219 return StringSwitch<ArchType>(ArchName)
220 .Cases("i386", "i486", "i586", "i686", x86)
221 .Cases("i786", "i886", "i986", x86) // FIXME: Do we need to support these?
222 .Cases("amd64", "x86_64", x86_64)
223 .Case("powerpc", ppc)
224 .Cases("powerpc64", "ppu", ppc64)
225 .Case("mblaze", mblaze)
226 .Cases("arm", "xscale", arm)
Chandler Carruth0a857712012-02-18 04:34:17 +0000227 // FIXME: It would be good to replace these with explicit names for all the
228 // various suffixes supported.
229 .StartsWith("armv", arm)
Chandler Carruth06accda2012-02-12 09:27:38 +0000230 .Case("thumb", thumb)
Chandler Carruth0a857712012-02-18 04:34:17 +0000231 .StartsWith("thumbv", thumb)
Chandler Carruth06accda2012-02-12 09:27:38 +0000232 .Cases("spu", "cellspu", cellspu)
233 .Case("msp430", msp430)
234 .Cases("mips", "mipseb", "mipsallegrex", mips)
235 .Cases("mipsel", "mipsallegrexel", "psp", mipsel)
236 .Cases("mips64", "mips64eb", mips64)
237 .Case("mips64el", mips64el)
238 .Case("hexagon", hexagon)
239 .Case("sparc", sparc)
240 .Case("sparcv9", sparcv9)
241 .Case("tce", tce)
242 .Case("xcore", xcore)
243 .Case("ptx32", ptx32)
244 .Case("ptx64", ptx64)
245 .Case("le32", le32)
246 .Case("amdil", amdil)
247 .Default(UnknownArch);
Duncan Sands335db222010-08-12 11:31:39 +0000248}
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000249
Duncan Sands335db222010-08-12 11:31:39 +0000250Triple::VendorType Triple::ParseVendor(StringRef VendorName) {
Chandler Carruth06accda2012-02-12 09:27:38 +0000251 return StringSwitch<VendorType>(VendorName)
252 .Case("apple", Apple)
253 .Case("pc", PC)
254 .Case("scei", SCEI)
255 .Default(UnknownVendor);
Duncan Sands335db222010-08-12 11:31:39 +0000256}
257
258Triple::OSType Triple::ParseOS(StringRef OSName) {
Benjamin Kramer61c2c122012-02-12 10:56:52 +0000259 return StringSwitch<OSType>(OSName)
260 .StartsWith("auroraux", AuroraUX)
261 .StartsWith("cygwin", Cygwin)
262 .StartsWith("darwin", Darwin)
263 .StartsWith("dragonfly", DragonFly)
264 .StartsWith("freebsd", FreeBSD)
265 .StartsWith("ios", IOS)
266 .StartsWith("kfreebsd", KFreeBSD)
267 .StartsWith("linux", Linux)
268 .StartsWith("lv2", Lv2)
269 .StartsWith("macosx", MacOSX)
270 .StartsWith("mingw32", MinGW32)
271 .StartsWith("netbsd", NetBSD)
272 .StartsWith("openbsd", OpenBSD)
273 .StartsWith("psp", Psp)
274 .StartsWith("solaris", Solaris)
275 .StartsWith("win32", Win32)
276 .StartsWith("haiku", Haiku)
277 .StartsWith("minix", Minix)
278 .StartsWith("rtems", RTEMS)
279 .StartsWith("nacl", NativeClient)
280 .Default(UnknownOS);
Duncan Sands335db222010-08-12 11:31:39 +0000281}
282
Duncan Sands5754a452010-09-16 08:25:48 +0000283Triple::EnvironmentType Triple::ParseEnvironment(StringRef EnvironmentName) {
Benjamin Kramer61c2c122012-02-12 10:56:52 +0000284 return StringSwitch<EnvironmentType>(EnvironmentName)
285 .StartsWith("eabi", EABI)
286 .StartsWith("gnueabihf", GNUEABIHF)
287 .StartsWith("gnueabi", GNUEABI)
288 .StartsWith("gnu", GNU)
289 .StartsWith("macho", MachO)
290 .StartsWith("androideabi", ANDROIDEABI)
291 .Default(UnknownEnvironment);
Duncan Sands5754a452010-09-16 08:25:48 +0000292}
293
Duncan Sands335db222010-08-12 11:31:39 +0000294void Triple::Parse() const {
295 assert(!isInitialized() && "Invalid parse call.");
296
297 Arch = ParseArch(getArchName());
298 Vendor = ParseVendor(getVendorName());
299 OS = ParseOS(getOSName());
Duncan Sandsae200c62011-02-02 10:08:38 +0000300 Environment = ParseEnvironment(getEnvironmentName());
Daniel Dunbar651aa682009-08-18 19:26:55 +0000301
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000302 assert(isInitialized() && "Failed to initialize!");
303}
304
Chandler Carruthcceb8f42012-02-20 00:02:47 +0000305/// \brief Construct a triple from the string representation provided.
306///
307/// This doesn't actually parse the string representation eagerly. Instead it
308/// stores it, and tracks the fact that it hasn't been parsed. The first time
309/// any of the structural queries are made, the string is parsed and the
310/// results cached in various members.
311Triple::Triple(const Twine &Str) : Data(Str.str()), Arch(InvalidArch) {}
312
313/// \brief Construct a triple from string representations of the architecture,
314/// vendor, and OS.
315///
316/// This doesn't actually use these already distinct strings to setup the
317/// triple information. Instead it joins them into a canonical form of a triple
318/// string, and lazily parses it on use.
319Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr)
320 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()),
321 Arch(InvalidArch) {
322}
323
324/// \brief Construct a triple from string representations of the architecture,
325/// vendor, OS, and environment.
326///
327/// This doesn't actually use these already distinct strings to setup the
328/// triple information. Instead it joins them into a canonical form of a triple
329/// string, and lazily parses it on use.
330Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr,
331 const Twine &EnvironmentStr)
332 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr + Twine('-') +
333 EnvironmentStr).str()),
334 Arch(InvalidArch) {
335}
336
Duncan Sands335db222010-08-12 11:31:39 +0000337std::string Triple::normalize(StringRef Str) {
338 // Parse into components.
339 SmallVector<StringRef, 4> Components;
340 for (size_t First = 0, Last = 0; Last != StringRef::npos; First = Last + 1) {
341 Last = Str.find('-', First);
342 Components.push_back(Str.slice(First, Last));
343 }
344
345 // If the first component corresponds to a known architecture, preferentially
346 // use it for the architecture. If the second component corresponds to a
347 // known vendor, preferentially use it for the vendor, etc. This avoids silly
348 // component movement when a component parses as (eg) both a valid arch and a
349 // valid os.
350 ArchType Arch = UnknownArch;
351 if (Components.size() > 0)
352 Arch = ParseArch(Components[0]);
353 VendorType Vendor = UnknownVendor;
354 if (Components.size() > 1)
355 Vendor = ParseVendor(Components[1]);
356 OSType OS = UnknownOS;
357 if (Components.size() > 2)
358 OS = ParseOS(Components[2]);
Duncan Sands5754a452010-09-16 08:25:48 +0000359 EnvironmentType Environment = UnknownEnvironment;
360 if (Components.size() > 3)
361 Environment = ParseEnvironment(Components[3]);
Duncan Sands335db222010-08-12 11:31:39 +0000362
363 // Note which components are already in their final position. These will not
364 // be moved.
Duncan Sands5754a452010-09-16 08:25:48 +0000365 bool Found[4];
Duncan Sands335db222010-08-12 11:31:39 +0000366 Found[0] = Arch != UnknownArch;
367 Found[1] = Vendor != UnknownVendor;
368 Found[2] = OS != UnknownOS;
Duncan Sands5754a452010-09-16 08:25:48 +0000369 Found[3] = Environment != UnknownEnvironment;
Duncan Sands335db222010-08-12 11:31:39 +0000370
371 // If they are not there already, permute the components into their canonical
372 // positions by seeing if they parse as a valid architecture, and if so moving
373 // the component to the architecture position etc.
Duncan Sands5754a452010-09-16 08:25:48 +0000374 for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) {
Duncan Sands335db222010-08-12 11:31:39 +0000375 if (Found[Pos])
376 continue; // Already in the canonical position.
377
378 for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
379 // Do not reparse any components that already matched.
Duncan Sands5754a452010-09-16 08:25:48 +0000380 if (Idx < array_lengthof(Found) && Found[Idx])
Duncan Sands335db222010-08-12 11:31:39 +0000381 continue;
382
383 // Does this component parse as valid for the target position?
384 bool Valid = false;
385 StringRef Comp = Components[Idx];
386 switch (Pos) {
Craig Topper85814382012-02-07 05:05:23 +0000387 default: llvm_unreachable("unexpected component type!");
Duncan Sands335db222010-08-12 11:31:39 +0000388 case 0:
389 Arch = ParseArch(Comp);
390 Valid = Arch != UnknownArch;
391 break;
392 case 1:
393 Vendor = ParseVendor(Comp);
394 Valid = Vendor != UnknownVendor;
395 break;
396 case 2:
397 OS = ParseOS(Comp);
Duncan Sandsae200c62011-02-02 10:08:38 +0000398 Valid = OS != UnknownOS;
Duncan Sands335db222010-08-12 11:31:39 +0000399 break;
Duncan Sands5754a452010-09-16 08:25:48 +0000400 case 3:
401 Environment = ParseEnvironment(Comp);
402 Valid = Environment != UnknownEnvironment;
403 break;
Duncan Sands335db222010-08-12 11:31:39 +0000404 }
405 if (!Valid)
406 continue; // Nope, try the next component.
407
408 // Move the component to the target position, pushing any non-fixed
409 // components that are in the way to the right. This tends to give
410 // good results in the common cases of a forgotten vendor component
411 // or a wrongly positioned environment.
412 if (Pos < Idx) {
413 // Insert left, pushing the existing components to the right. For
414 // example, a-b-i386 -> i386-a-b when moving i386 to the front.
415 StringRef CurrentComponent(""); // The empty component.
416 // Replace the component we are moving with an empty component.
417 std::swap(CurrentComponent, Components[Idx]);
418 // Insert the component being moved at Pos, displacing any existing
419 // components to the right.
420 for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
421 // Skip over any fixed components.
Duncan Sands5754a452010-09-16 08:25:48 +0000422 while (i < array_lengthof(Found) && Found[i]) ++i;
Duncan Sands335db222010-08-12 11:31:39 +0000423 // Place the component at the new position, getting the component
424 // that was at this position - it will be moved right.
425 std::swap(CurrentComponent, Components[i]);
426 }
427 } else if (Pos > Idx) {
428 // Push right by inserting empty components until the component at Idx
429 // reaches the target position Pos. For example, pc-a -> -pc-a when
430 // moving pc to the second position.
431 do {
432 // Insert one empty component at Idx.
433 StringRef CurrentComponent(""); // The empty component.
Duncan Sandsae200c62011-02-02 10:08:38 +0000434 for (unsigned i = Idx; i < Components.size();) {
Duncan Sands335db222010-08-12 11:31:39 +0000435 // Place the component at the new position, getting the component
436 // that was at this position - it will be moved right.
437 std::swap(CurrentComponent, Components[i]);
438 // If it was placed on top of an empty component then we are done.
439 if (CurrentComponent.empty())
440 break;
Duncan Sandsae200c62011-02-02 10:08:38 +0000441 // Advance to the next component, skipping any fixed components.
Anders Carlsson15ec6952011-02-05 18:19:35 +0000442 while (++i < array_lengthof(Found) && Found[i])
443 ;
Duncan Sands335db222010-08-12 11:31:39 +0000444 }
445 // The last component was pushed off the end - append it.
446 if (!CurrentComponent.empty())
447 Components.push_back(CurrentComponent);
448
449 // Advance Idx to the component's new position.
Duncan Sands5754a452010-09-16 08:25:48 +0000450 while (++Idx < array_lengthof(Found) && Found[Idx]) {}
Duncan Sands335db222010-08-12 11:31:39 +0000451 } while (Idx < Pos); // Add more until the final position is reached.
452 }
453 assert(Pos < Components.size() && Components[Pos] == Comp &&
454 "Component moved wrong!");
455 Found[Pos] = true;
456 break;
457 }
458 }
459
460 // Special case logic goes here. At this point Arch, Vendor and OS have the
461 // correct values for the computed components.
462
463 // Stick the corrected components back together to form the normalized string.
464 std::string Normalized;
465 for (unsigned i = 0, e = Components.size(); i != e; ++i) {
466 if (i) Normalized += '-';
467 Normalized += Components[i];
468 }
469 return Normalized;
470}
471
Daniel Dunbara14d2252009-07-26 03:31:47 +0000472StringRef Triple::getArchName() const {
473 return StringRef(Data).split('-').first; // Isolate first component
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000474}
475
Daniel Dunbara14d2252009-07-26 03:31:47 +0000476StringRef Triple::getVendorName() const {
477 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
478 return Tmp.split('-').first; // Isolate second component
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000479}
480
Daniel Dunbara14d2252009-07-26 03:31:47 +0000481StringRef Triple::getOSName() const {
482 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
483 Tmp = Tmp.split('-').second; // Strip second component
484 return Tmp.split('-').first; // Isolate third component
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000485}
486
Daniel Dunbara14d2252009-07-26 03:31:47 +0000487StringRef Triple::getEnvironmentName() const {
488 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
489 Tmp = Tmp.split('-').second; // Strip second component
490 return Tmp.split('-').second; // Strip third component
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000491}
492
Daniel Dunbara14d2252009-07-26 03:31:47 +0000493StringRef Triple::getOSAndEnvironmentName() const {
494 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
495 return Tmp.split('-').second; // Strip second component
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000496}
497
Chris Lattnerdfc17f72009-08-12 06:19:40 +0000498static unsigned EatNumber(StringRef &Str) {
499 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
Daniel Dunbar087d6a52011-04-19 20:24:34 +0000500 unsigned Result = 0;
Jim Grosbache509aa92010-12-17 02:10:59 +0000501
Daniel Dunbar087d6a52011-04-19 20:24:34 +0000502 do {
503 // Consume the leading digit.
Chris Lattnerdfc17f72009-08-12 06:19:40 +0000504 Result = Result*10 + (Str[0] - '0');
Daniel Dunbar087d6a52011-04-19 20:24:34 +0000505
Chris Lattnerdfc17f72009-08-12 06:19:40 +0000506 // Eat the digit.
507 Str = Str.substr(1);
Daniel Dunbar087d6a52011-04-19 20:24:34 +0000508 } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9');
Jim Grosbache509aa92010-12-17 02:10:59 +0000509
Chris Lattnerdfc17f72009-08-12 06:19:40 +0000510 return Result;
511}
512
Daniel Dunbar087d6a52011-04-19 20:24:34 +0000513void Triple::getOSVersion(unsigned &Major, unsigned &Minor,
514 unsigned &Micro) const {
Chris Lattnerdfc17f72009-08-12 06:19:40 +0000515 StringRef OSName = getOSName();
Jim Grosbache509aa92010-12-17 02:10:59 +0000516
Daniel Dunbar087d6a52011-04-19 20:24:34 +0000517 // Assume that the OS portion of the triple starts with the canonical name.
518 StringRef OSTypeName = getOSTypeName(getOS());
519 if (OSName.startswith(OSTypeName))
520 OSName = OSName.substr(OSTypeName.size());
Jim Grosbache509aa92010-12-17 02:10:59 +0000521
Daniel Dunbar087d6a52011-04-19 20:24:34 +0000522 // Any unset version defaults to 0.
523 Major = Minor = Micro = 0;
Chris Lattnerdfc17f72009-08-12 06:19:40 +0000524
Daniel Dunbar087d6a52011-04-19 20:24:34 +0000525 // Parse up to three components.
526 unsigned *Components[3] = { &Major, &Minor, &Micro };
527 for (unsigned i = 0; i != 3; ++i) {
528 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
529 break;
Chris Lattnerdfc17f72009-08-12 06:19:40 +0000530
Daniel Dunbar087d6a52011-04-19 20:24:34 +0000531 // Consume the leading number.
532 *Components[i] = EatNumber(OSName);
Jim Grosbache509aa92010-12-17 02:10:59 +0000533
Daniel Dunbar087d6a52011-04-19 20:24:34 +0000534 // Consume the separator, if present.
535 if (OSName.startswith("."))
536 OSName = OSName.substr(1);
537 }
Chris Lattnerdfc17f72009-08-12 06:19:40 +0000538}
539
Bob Wilsonbda59fd2012-01-31 22:32:29 +0000540bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor,
541 unsigned &Micro) const {
542 getOSVersion(Major, Minor, Micro);
543
544 switch (getOS()) {
Craig Topper85814382012-02-07 05:05:23 +0000545 default: llvm_unreachable("unexpected OS for Darwin triple");
Bob Wilsonbda59fd2012-01-31 22:32:29 +0000546 case Darwin:
547 // Default to darwin8, i.e., MacOSX 10.4.
548 if (Major == 0)
549 Major = 8;
550 // Darwin version numbers are skewed from OS X versions.
551 if (Major < 4)
552 return false;
553 Micro = 0;
554 Minor = Major - 4;
555 Major = 10;
556 break;
557 case MacOSX:
558 // Default to 10.4.
559 if (Major == 0) {
560 Major = 10;
561 Minor = 4;
562 }
563 if (Major != 10)
564 return false;
565 break;
566 case IOS:
567 // Ignore the version from the triple. This is only handled because the
568 // the clang driver combines OS X and IOS support into a common Darwin
569 // toolchain that wants to know the OS X version number even when targeting
570 // IOS.
571 Major = 10;
572 Minor = 4;
573 Micro = 0;
574 break;
575 }
576 return true;
577}
578
Daniel Dunbara14d2252009-07-26 03:31:47 +0000579void Triple::setTriple(const Twine &Str) {
580 Data = Str.str();
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000581 Arch = InvalidArch;
582}
583
584void Triple::setArch(ArchType Kind) {
585 setArchName(getArchTypeName(Kind));
586}
587
588void Triple::setVendor(VendorType Kind) {
589 setVendorName(getVendorTypeName(Kind));
590}
591
592void Triple::setOS(OSType Kind) {
593 setOSName(getOSTypeName(Kind));
594}
595
Duncan Sands5754a452010-09-16 08:25:48 +0000596void Triple::setEnvironment(EnvironmentType Kind) {
597 setEnvironmentName(getEnvironmentTypeName(Kind));
598}
599
Daniel Dunbar2928c832009-11-06 10:58:06 +0000600void Triple::setArchName(StringRef Str) {
Jeffrey Yasskin0b228732009-10-06 21:45:26 +0000601 // Work around a miscompilation bug for Twines in gcc 4.0.3.
602 SmallString<64> Triple;
603 Triple += Str;
604 Triple += "-";
605 Triple += getVendorName();
606 Triple += "-";
607 Triple += getOSAndEnvironmentName();
608 setTriple(Triple.str());
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000609}
610
Daniel Dunbar2928c832009-11-06 10:58:06 +0000611void Triple::setVendorName(StringRef Str) {
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000612 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
613}
614
Daniel Dunbar2928c832009-11-06 10:58:06 +0000615void Triple::setOSName(StringRef Str) {
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000616 if (hasEnvironment())
617 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
618 "-" + getEnvironmentName());
619 else
620 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
621}
622
Daniel Dunbar2928c832009-11-06 10:58:06 +0000623void Triple::setEnvironmentName(StringRef Str) {
624 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000625 "-" + Str);
626}
627
Daniel Dunbar2928c832009-11-06 10:58:06 +0000628void Triple::setOSAndEnvironmentName(StringRef Str) {
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000629 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
630}
Chandler Carruth6f72ac42012-01-31 04:52:32 +0000631
632static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
633 switch (Arch) {
634 case llvm::Triple::UnknownArch:
635 case llvm::Triple::InvalidArch:
636 return 0;
637
638 case llvm::Triple::msp430:
639 return 16;
640
641 case llvm::Triple::amdil:
642 case llvm::Triple::arm:
643 case llvm::Triple::cellspu:
644 case llvm::Triple::hexagon:
645 case llvm::Triple::le32:
646 case llvm::Triple::mblaze:
647 case llvm::Triple::mips:
648 case llvm::Triple::mipsel:
649 case llvm::Triple::ppc:
650 case llvm::Triple::ptx32:
651 case llvm::Triple::sparc:
652 case llvm::Triple::tce:
653 case llvm::Triple::thumb:
654 case llvm::Triple::x86:
655 case llvm::Triple::xcore:
656 return 32;
657
658 case llvm::Triple::mips64:
659 case llvm::Triple::mips64el:
660 case llvm::Triple::ppc64:
661 case llvm::Triple::ptx64:
662 case llvm::Triple::sparcv9:
663 case llvm::Triple::x86_64:
664 return 64;
665 }
666 llvm_unreachable("Invalid architecture value");
667}
668
669bool Triple::isArch64Bit() const {
670 return getArchPointerBitWidth(getArch()) == 64;
671}
672
673bool Triple::isArch32Bit() const {
674 return getArchPointerBitWidth(getArch()) == 32;
675}
676
677bool Triple::isArch16Bit() const {
678 return getArchPointerBitWidth(getArch()) == 16;
679}
Chandler Carruth7d5a2892012-02-06 20:46:33 +0000680
681Triple Triple::get32BitArchVariant() const {
682 Triple T(*this);
683 switch (getArch()) {
684 case Triple::UnknownArch:
685 case Triple::InvalidArch:
686 case Triple::msp430:
687 T.setArch(UnknownArch);
688 break;
689
690 case Triple::amdil:
691 case Triple::arm:
692 case Triple::cellspu:
693 case Triple::hexagon:
694 case Triple::le32:
695 case Triple::mblaze:
696 case Triple::mips:
697 case Triple::mipsel:
698 case Triple::ppc:
699 case Triple::ptx32:
700 case Triple::sparc:
701 case Triple::tce:
702 case Triple::thumb:
703 case Triple::x86:
704 case Triple::xcore:
705 // Already 32-bit.
706 break;
707
708 case Triple::mips64: T.setArch(Triple::mips); break;
709 case Triple::mips64el: T.setArch(Triple::mipsel); break;
710 case Triple::ppc64: T.setArch(Triple::ppc); break;
711 case Triple::ptx64: T.setArch(Triple::ptx32); break;
712 case Triple::sparcv9: T.setArch(Triple::sparc); break;
713 case Triple::x86_64: T.setArch(Triple::x86); break;
714 }
715 return T;
716}
717
718Triple Triple::get64BitArchVariant() const {
719 Triple T(*this);
720 switch (getArch()) {
721 case Triple::InvalidArch:
722 case Triple::UnknownArch:
723 case Triple::amdil:
724 case Triple::arm:
725 case Triple::cellspu:
726 case Triple::hexagon:
727 case Triple::le32:
728 case Triple::mblaze:
729 case Triple::msp430:
730 case Triple::tce:
731 case Triple::thumb:
732 case Triple::xcore:
733 T.setArch(UnknownArch);
734 break;
735
736 case Triple::mips64:
737 case Triple::mips64el:
738 case Triple::ppc64:
739 case Triple::ptx64:
740 case Triple::sparcv9:
741 case Triple::x86_64:
742 // Already 64-bit.
743 break;
744
745 case Triple::mips: T.setArch(Triple::mips64); break;
746 case Triple::mipsel: T.setArch(Triple::mips64el); break;
747 case Triple::ppc: T.setArch(Triple::ppc64); break;
748 case Triple::ptx32: T.setArch(Triple::ptx64); break;
749 case Triple::sparc: T.setArch(Triple::sparcv9); break;
750 case Triple::x86: T.setArch(Triple::x86_64); break;
751 }
752 return T;
753}