blob: af951fe9002bed24e4810e6aa0989a935e522535 [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) {
Daniel Dunbar23e97b02009-04-01 21:53:23 +000020 case UnknownArch: return "unknown";
Jim Grosbache509aa92010-12-17 02:10:59 +000021
Daniel Dunbar6337f152009-07-26 04:23:03 +000022 case arm: return "arm";
23 case cellspu: return "cellspu";
Tony Linthicumb4b54152011-12-12 21:14:40 +000024 case hexagon: return "hexagon";
Daniel Dunbar6337f152009-07-26 04:23:03 +000025 case mips: return "mips";
26 case mipsel: return "mipsel";
Akira Hatanaka70303682011-09-20 18:09:37 +000027 case mips64: return "mips64";
28 case mips64el:return "mips64el";
Daniel Dunbar6337f152009-07-26 04:23:03 +000029 case msp430: return "msp430";
Daniel Dunbar8c2f1d72009-07-26 04:52:45 +000030 case ppc64: return "powerpc64";
31 case ppc: return "powerpc";
Daniel Dunbar6337f152009-07-26 04:23:03 +000032 case sparc: return "sparc";
Chris Lattner87c06d62010-02-04 06:34:01 +000033 case sparcv9: return "sparcv9";
Eli Friedman74db89e2009-08-19 20:46:03 +000034 case tce: return "tce";
Daniel Dunbar6337f152009-07-26 04:23:03 +000035 case thumb: return "thumb";
36 case x86: return "i386";
37 case x86_64: return "x86_64";
Daniel Dunbar8c2f1d72009-07-26 04:52:45 +000038 case xcore: return "xcore";
Wesley Pecka70f28c2010-02-23 19:15:24 +000039 case mblaze: return "mblaze";
Justin Holewinskie1fee482011-04-20 15:37:17 +000040 case ptx32: return "ptx32";
41 case ptx64: return "ptx64";
Ivan Krasin38fb2db2011-08-23 16:59:00 +000042 case le32: return "le32";
Tobias Grosser05d71382011-08-29 15:44:55 +000043 case amdil: return "amdil";
Daniel Dunbar23e97b02009-04-01 21:53:23 +000044 }
45
David Blaikie4d6ccb52012-01-20 21:51:11 +000046 llvm_unreachable("Invalid ArchType!");
Daniel Dunbar23e97b02009-04-01 21:53:23 +000047}
48
Daniel Dunbar688b55b2009-08-24 09:53:06 +000049const char *Triple::getArchTypePrefix(ArchType Kind) {
50 switch (Kind) {
51 default:
52 return 0;
53
Daniel Dunbar688b55b2009-08-24 09:53:06 +000054 case arm:
55 case thumb: return "arm";
56
Daniel Dunbar688b55b2009-08-24 09:53:06 +000057 case cellspu: return "spu";
58
59 case ppc64:
60 case ppc: return "ppc";
61
Wesley Pecka70f28c2010-02-23 19:15:24 +000062 case mblaze: return "mblaze";
63
Tony Linthicumb4b54152011-12-12 21:14:40 +000064 case hexagon: return "hexagon";
65
Chris Lattner87c06d62010-02-04 06:34:01 +000066 case sparcv9:
Daniel Dunbar688b55b2009-08-24 09:53:06 +000067 case sparc: return "sparc";
68
69 case x86:
70 case x86_64: return "x86";
Nick Lewyckyf7a3c502010-09-07 18:14:24 +000071
Daniel Dunbar688b55b2009-08-24 09:53:06 +000072 case xcore: return "xcore";
Nick Lewyckyf7a3c502010-09-07 18:14:24 +000073
Justin Holewinskie1fee482011-04-20 15:37:17 +000074 case ptx32: return "ptx";
75 case ptx64: return "ptx";
Ivan Krasin38fb2db2011-08-23 16:59:00 +000076 case le32: return "le32";
Tobias Grosser05d71382011-08-29 15:44:55 +000077 case amdil: return "amdil";
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";
John Thompson6046cff2011-03-15 21:51:56 +000087 case SCEI: return "scei";
Daniel Dunbar23e97b02009-04-01 21:53:23 +000088 }
89
David Blaikie4d6ccb52012-01-20 21:51:11 +000090 llvm_unreachable("Invalid VendorType!");
Daniel Dunbar23e97b02009-04-01 21:53:23 +000091}
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";
Daniel Dunbar0dde4c02011-04-19 20:19:27 +0000102 case IOS: return "ios";
Duncan Sands652b48b2011-07-26 15:30:04 +0000103 case KFreeBSD: return "kfreebsd";
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000104 case Linux: return "linux";
Edward O'Callaghancc9fa812009-11-19 11:59:00 +0000105 case Lv2: return "lv2";
Daniel Dunbar1af39472011-04-19 23:34:12 +0000106 case MacOSX: return "macosx";
Daniel Dunbar6337f152009-07-26 04:23:03 +0000107 case MinGW32: return "mingw32";
Chris Lattnerb8ac8412009-07-13 20:22:23 +0000108 case NetBSD: return "netbsd";
Duncan Sandscd1267d2009-06-29 13:36:13 +0000109 case OpenBSD: return "openbsd";
Edward O'Callaghane0fb75d2009-11-15 10:18:17 +0000110 case Psp: return "psp";
Daniel Dunbarfdb0b7b2009-08-18 04:43:27 +0000111 case Solaris: return "solaris";
Daniel Dunbar6337f152009-07-26 04:23:03 +0000112 case Win32: return "win32";
Chris Lattnera43fc342009-10-16 02:06:30 +0000113 case Haiku: return "haiku";
Chris Lattner29269d02010-07-07 15:52:27 +0000114 case Minix: return "minix";
Douglas Gregor6ced1d12011-07-01 22:41:06 +0000115 case RTEMS: return "rtems";
Ivan Krasinfb234622011-08-18 22:54:21 +0000116 case NativeClient: return "nacl";
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000117 }
118
David Blaikie4d6ccb52012-01-20 21:51:11 +0000119 llvm_unreachable("Invalid OSType");
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000120}
121
Duncan Sands5754a452010-09-16 08:25:48 +0000122const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
123 switch (Kind) {
124 case UnknownEnvironment: return "unknown";
Renato Golin859f8182011-01-21 18:25:47 +0000125 case GNU: return "gnu";
Rafael Espindola8887a0f2012-01-18 23:35:29 +0000126 case GNUEABIHF: return "gnueabihf";
Renato Golin859f8182011-01-21 18:25:47 +0000127 case GNUEABI: return "gnueabi";
128 case EABI: return "eabi";
Evan Cheng2bffee22011-02-01 01:14:13 +0000129 case MachO: return "macho";
Chandler Carruthfd553c22012-01-10 19:46:00 +0000130 case ANDROIDEABI: return "androideabi";
Duncan Sands5754a452010-09-16 08:25:48 +0000131 }
132
David Blaikie4d6ccb52012-01-20 21:51:11 +0000133 llvm_unreachable("Invalid EnvironmentType!");
Duncan Sands5754a452010-09-16 08:25:48 +0000134}
135
Daniel Dunbar2928c832009-11-06 10:58:06 +0000136Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
Chandler Carruth06accda2012-02-12 09:27:38 +0000137 return StringSwitch<Triple::ArchType>(Name)
138 .Case("arm", arm)
139 .Case("cellspu", cellspu)
140 .Case("mips", mips)
141 .Case("mipsel", mipsel)
142 .Case("mips64", mips64)
143 .Case("mips64el", mips64el)
144 .Case("msp430", msp430)
145 .Case("ppc64", ppc64)
146 .Case("ppc32", ppc)
147 .Case("ppc", ppc)
148 .Case("mblaze", mblaze)
149 .Case("hexagon", hexagon)
150 .Case("sparc", sparc)
151 .Case("sparcv9", sparcv9)
152 .Case("tce", tce)
153 .Case("thumb", thumb)
154 .Case("x86", x86)
155 .Case("x86-64", x86_64)
156 .Case("xcore", xcore)
157 .Case("ptx32", ptx32)
158 .Case("ptx64", ptx64)
159 .Case("le32", le32)
160 .Case("amdil", amdil)
161 .Default(UnknownArch);
Daniel Dunbar3c2d4bf2009-08-03 04:03:51 +0000162}
163
Daniel Dunbar2928c832009-11-06 10:58:06 +0000164Triple::ArchType Triple::getArchTypeForDarwinArchName(StringRef Str) {
Daniel Dunbarbaf9b562009-09-08 23:32:51 +0000165 // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
166 // archs which Darwin doesn't use.
167
168 // The matching this routine does is fairly pointless, since it is neither the
169 // complete architecture list, nor a reasonable subset. The problem is that
170 // historically the driver driver accepts this and also ties its -march=
171 // handling to the architecture name, so we need to be careful before removing
172 // support for it.
173
Daniel Dunbared687882009-09-09 23:01:25 +0000174 // This code must be kept in sync with Clang's Darwin specific argument
175 // translation.
176
Chandler Carruth06accda2012-02-12 09:27:38 +0000177 return StringSwitch<ArchType>(Str)
178 .Cases("ppc", "ppc601", "ppc603", "ppc604", "ppc604e", Triple::ppc)
179 .Cases("ppc750", "ppc7400", "ppc7450", "ppc970", Triple::ppc)
180 .Case("ppc64", Triple::ppc64)
181 .Cases("i386", "i486", "i486SX", "i586", "i686", Triple::x86)
182 .Cases("pentium", "pentpro", "pentIIm3", "pentIIm5", "pentium4",
183 Triple::x86)
184 .Case("x86_64", Triple::x86_64)
185 // This is derived from the driver driver.
186 .Cases("arm", "armv4t", "armv5", "armv6", Triple::arm)
187 .Cases("armv7", "armv7f", "armv7k", "armv7s", "xscale", Triple::arm)
188 .Case("ptx32", Triple::ptx32)
189 .Case("ptx64", Triple::ptx64)
190 .Case("amdil", Triple::amdil)
191 .Default(Triple::UnknownArch);
Daniel Dunbarbaf9b562009-09-08 23:32:51 +0000192}
193
Duncan Sandsbbdca3f2010-03-24 09:05:14 +0000194// Returns architecture name that is understood by the target assembler.
Viktor Kutuzov51cdac02009-11-17 18:48:27 +0000195const char *Triple::getArchNameForAssembler() {
Daniel Dunbare1fe09f2011-04-19 21:12:05 +0000196 if (!isOSDarwin() && getVendor() != Triple::Apple)
Viktor Kutuzov51cdac02009-11-17 18:48:27 +0000197 return NULL;
198
Chandler Carruth06accda2012-02-12 09:27:38 +0000199 return StringSwitch<const char*>(getArchName())
200 .Case("i386", "i386")
201 .Case("x86_64", "x86_64")
202 .Case("powerpc", "ppc")
203 .Case("powerpc64", "ppc64")
204 .Cases("mblaze", "microblaze", "mblaze")
205 .Case("arm", "arm")
206 .Cases("armv4t", "thumbv4t", "armv4t")
207 .Cases("armv5", "armv5e", "thumbv5", "thumbv5e", "armv5")
208 .Cases("armv6", "thumbv6", "armv6")
209 .Cases("armv7", "thumbv7", "armv7")
210 .Case("ptx32", "ptx32")
211 .Case("ptx64", "ptx64")
212 .Case("le32", "le32")
213 .Case("amdil", "amdil")
214 .Default(NULL);
Viktor Kutuzov51cdac02009-11-17 18:48:27 +0000215}
216
Duncan Sands335db222010-08-12 11:31:39 +0000217Triple::ArchType Triple::ParseArch(StringRef ArchName) {
Chandler Carruth06accda2012-02-12 09:27:38 +0000218 return StringSwitch<ArchType>(ArchName)
219 .Cases("i386", "i486", "i586", "i686", x86)
220 .Cases("i786", "i886", "i986", x86) // FIXME: Do we need to support these?
221 .Cases("amd64", "x86_64", x86_64)
222 .Case("powerpc", ppc)
223 .Cases("powerpc64", "ppu", ppc64)
224 .Case("mblaze", mblaze)
225 .Cases("arm", "xscale", arm)
Chandler Carruth0a857712012-02-18 04:34:17 +0000226 // FIXME: It would be good to replace these with explicit names for all the
227 // various suffixes supported.
228 .StartsWith("armv", arm)
Chandler Carruth06accda2012-02-12 09:27:38 +0000229 .Case("thumb", thumb)
Chandler Carruth0a857712012-02-18 04:34:17 +0000230 .StartsWith("thumbv", thumb)
Chandler Carruth06accda2012-02-12 09:27:38 +0000231 .Cases("spu", "cellspu", cellspu)
232 .Case("msp430", msp430)
233 .Cases("mips", "mipseb", "mipsallegrex", mips)
234 .Cases("mipsel", "mipsallegrexel", "psp", mipsel)
235 .Cases("mips64", "mips64eb", mips64)
236 .Case("mips64el", mips64el)
237 .Case("hexagon", hexagon)
238 .Case("sparc", sparc)
239 .Case("sparcv9", sparcv9)
240 .Case("tce", tce)
241 .Case("xcore", xcore)
242 .Case("ptx32", ptx32)
243 .Case("ptx64", ptx64)
244 .Case("le32", le32)
245 .Case("amdil", amdil)
246 .Default(UnknownArch);
Duncan Sands335db222010-08-12 11:31:39 +0000247}
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000248
Duncan Sands335db222010-08-12 11:31:39 +0000249Triple::VendorType Triple::ParseVendor(StringRef VendorName) {
Chandler Carruth06accda2012-02-12 09:27:38 +0000250 return StringSwitch<VendorType>(VendorName)
251 .Case("apple", Apple)
252 .Case("pc", PC)
253 .Case("scei", SCEI)
254 .Default(UnknownVendor);
Duncan Sands335db222010-08-12 11:31:39 +0000255}
256
257Triple::OSType Triple::ParseOS(StringRef OSName) {
Benjamin Kramer61c2c122012-02-12 10:56:52 +0000258 return StringSwitch<OSType>(OSName)
259 .StartsWith("auroraux", AuroraUX)
260 .StartsWith("cygwin", Cygwin)
261 .StartsWith("darwin", Darwin)
262 .StartsWith("dragonfly", DragonFly)
263 .StartsWith("freebsd", FreeBSD)
264 .StartsWith("ios", IOS)
265 .StartsWith("kfreebsd", KFreeBSD)
266 .StartsWith("linux", Linux)
267 .StartsWith("lv2", Lv2)
268 .StartsWith("macosx", MacOSX)
269 .StartsWith("mingw32", MinGW32)
270 .StartsWith("netbsd", NetBSD)
271 .StartsWith("openbsd", OpenBSD)
272 .StartsWith("psp", Psp)
273 .StartsWith("solaris", Solaris)
274 .StartsWith("win32", Win32)
275 .StartsWith("haiku", Haiku)
276 .StartsWith("minix", Minix)
277 .StartsWith("rtems", RTEMS)
278 .StartsWith("nacl", NativeClient)
279 .Default(UnknownOS);
Duncan Sands335db222010-08-12 11:31:39 +0000280}
281
Duncan Sands5754a452010-09-16 08:25:48 +0000282Triple::EnvironmentType Triple::ParseEnvironment(StringRef EnvironmentName) {
Benjamin Kramer61c2c122012-02-12 10:56:52 +0000283 return StringSwitch<EnvironmentType>(EnvironmentName)
284 .StartsWith("eabi", EABI)
285 .StartsWith("gnueabihf", GNUEABIHF)
286 .StartsWith("gnueabi", GNUEABI)
287 .StartsWith("gnu", GNU)
288 .StartsWith("macho", MachO)
289 .StartsWith("androideabi", ANDROIDEABI)
290 .Default(UnknownEnvironment);
Duncan Sands5754a452010-09-16 08:25:48 +0000291}
292
Chandler Carruthcceb8f42012-02-20 00:02:47 +0000293/// \brief Construct a triple from the string representation provided.
294///
295/// This doesn't actually parse the string representation eagerly. Instead it
296/// stores it, and tracks the fact that it hasn't been parsed. The first time
297/// any of the structural queries are made, the string is parsed and the
298/// results cached in various members.
Chandler Carruth124e51c2012-02-21 03:39:36 +0000299Triple::Triple(const Twine &Str)
300 : Data(Str.str()),
301 Arch(ParseArch(getArchName())),
302 Vendor(ParseVendor(getVendorName())),
303 OS(ParseOS(getOSName())),
304 Environment(ParseEnvironment(getEnvironmentName())) {
305}
Chandler Carruthcceb8f42012-02-20 00:02:47 +0000306
307/// \brief Construct a triple from string representations of the architecture,
308/// vendor, and OS.
309///
310/// This doesn't actually use these already distinct strings to setup the
311/// triple information. Instead it joins them into a canonical form of a triple
312/// string, and lazily parses it on use.
313Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr)
314 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()),
Chandler Carruth124e51c2012-02-21 03:39:36 +0000315 Arch(ParseArch(ArchStr.str())),
316 Vendor(ParseVendor(VendorStr.str())),
317 OS(ParseOS(OSStr.str())),
318 Environment() {
Chandler Carruthcceb8f42012-02-20 00:02:47 +0000319}
320
321/// \brief Construct a triple from string representations of the architecture,
322/// vendor, OS, and environment.
323///
324/// This doesn't actually use these already distinct strings to setup the
325/// triple information. Instead it joins them into a canonical form of a triple
326/// string, and lazily parses it on use.
327Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr,
328 const Twine &EnvironmentStr)
329 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr + Twine('-') +
330 EnvironmentStr).str()),
Chandler Carruth124e51c2012-02-21 03:39:36 +0000331 Arch(ParseArch(ArchStr.str())),
332 Vendor(ParseVendor(VendorStr.str())),
333 OS(ParseOS(OSStr.str())),
334 Environment(ParseEnvironment(EnvironmentStr.str())) {
Chandler Carruthcceb8f42012-02-20 00:02:47 +0000335}
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) {
Chandler Carruth124e51c2012-02-21 03:39:36 +0000580 *this = Triple(Str);
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000581}
582
583void Triple::setArch(ArchType Kind) {
584 setArchName(getArchTypeName(Kind));
585}
586
587void Triple::setVendor(VendorType Kind) {
588 setVendorName(getVendorTypeName(Kind));
589}
590
591void Triple::setOS(OSType Kind) {
592 setOSName(getOSTypeName(Kind));
593}
594
Duncan Sands5754a452010-09-16 08:25:48 +0000595void Triple::setEnvironment(EnvironmentType Kind) {
596 setEnvironmentName(getEnvironmentTypeName(Kind));
597}
598
Daniel Dunbar2928c832009-11-06 10:58:06 +0000599void Triple::setArchName(StringRef Str) {
Jeffrey Yasskin0b228732009-10-06 21:45:26 +0000600 // Work around a miscompilation bug for Twines in gcc 4.0.3.
601 SmallString<64> Triple;
602 Triple += Str;
603 Triple += "-";
604 Triple += getVendorName();
605 Triple += "-";
606 Triple += getOSAndEnvironmentName();
607 setTriple(Triple.str());
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000608}
609
Daniel Dunbar2928c832009-11-06 10:58:06 +0000610void Triple::setVendorName(StringRef Str) {
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000611 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
612}
613
Daniel Dunbar2928c832009-11-06 10:58:06 +0000614void Triple::setOSName(StringRef Str) {
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000615 if (hasEnvironment())
616 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
617 "-" + getEnvironmentName());
618 else
619 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
620}
621
Daniel Dunbar2928c832009-11-06 10:58:06 +0000622void Triple::setEnvironmentName(StringRef Str) {
623 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000624 "-" + Str);
625}
626
Daniel Dunbar2928c832009-11-06 10:58:06 +0000627void Triple::setOSAndEnvironmentName(StringRef Str) {
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000628 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
629}
Chandler Carruth6f72ac42012-01-31 04:52:32 +0000630
631static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
632 switch (Arch) {
633 case llvm::Triple::UnknownArch:
Chandler Carruth6f72ac42012-01-31 04:52:32 +0000634 return 0;
635
636 case llvm::Triple::msp430:
637 return 16;
638
639 case llvm::Triple::amdil:
640 case llvm::Triple::arm:
641 case llvm::Triple::cellspu:
642 case llvm::Triple::hexagon:
643 case llvm::Triple::le32:
644 case llvm::Triple::mblaze:
645 case llvm::Triple::mips:
646 case llvm::Triple::mipsel:
647 case llvm::Triple::ppc:
648 case llvm::Triple::ptx32:
649 case llvm::Triple::sparc:
650 case llvm::Triple::tce:
651 case llvm::Triple::thumb:
652 case llvm::Triple::x86:
653 case llvm::Triple::xcore:
654 return 32;
655
656 case llvm::Triple::mips64:
657 case llvm::Triple::mips64el:
658 case llvm::Triple::ppc64:
659 case llvm::Triple::ptx64:
660 case llvm::Triple::sparcv9:
661 case llvm::Triple::x86_64:
662 return 64;
663 }
664 llvm_unreachable("Invalid architecture value");
665}
666
667bool Triple::isArch64Bit() const {
668 return getArchPointerBitWidth(getArch()) == 64;
669}
670
671bool Triple::isArch32Bit() const {
672 return getArchPointerBitWidth(getArch()) == 32;
673}
674
675bool Triple::isArch16Bit() const {
676 return getArchPointerBitWidth(getArch()) == 16;
677}
Chandler Carruth7d5a2892012-02-06 20:46:33 +0000678
679Triple Triple::get32BitArchVariant() const {
680 Triple T(*this);
681 switch (getArch()) {
682 case Triple::UnknownArch:
Chandler Carruth7d5a2892012-02-06 20:46:33 +0000683 case Triple::msp430:
684 T.setArch(UnknownArch);
685 break;
686
687 case Triple::amdil:
688 case Triple::arm:
689 case Triple::cellspu:
690 case Triple::hexagon:
691 case Triple::le32:
692 case Triple::mblaze:
693 case Triple::mips:
694 case Triple::mipsel:
695 case Triple::ppc:
696 case Triple::ptx32:
697 case Triple::sparc:
698 case Triple::tce:
699 case Triple::thumb:
700 case Triple::x86:
701 case Triple::xcore:
702 // Already 32-bit.
703 break;
704
705 case Triple::mips64: T.setArch(Triple::mips); break;
706 case Triple::mips64el: T.setArch(Triple::mipsel); break;
707 case Triple::ppc64: T.setArch(Triple::ppc); break;
708 case Triple::ptx64: T.setArch(Triple::ptx32); break;
709 case Triple::sparcv9: T.setArch(Triple::sparc); break;
710 case Triple::x86_64: T.setArch(Triple::x86); break;
711 }
712 return T;
713}
714
715Triple Triple::get64BitArchVariant() const {
716 Triple T(*this);
717 switch (getArch()) {
Chandler Carruth7d5a2892012-02-06 20:46:33 +0000718 case Triple::UnknownArch:
719 case Triple::amdil:
720 case Triple::arm:
721 case Triple::cellspu:
722 case Triple::hexagon:
723 case Triple::le32:
724 case Triple::mblaze:
725 case Triple::msp430:
726 case Triple::tce:
727 case Triple::thumb:
728 case Triple::xcore:
729 T.setArch(UnknownArch);
730 break;
731
732 case Triple::mips64:
733 case Triple::mips64el:
734 case Triple::ppc64:
735 case Triple::ptx64:
736 case Triple::sparcv9:
737 case Triple::x86_64:
738 // Already 64-bit.
739 break;
740
741 case Triple::mips: T.setArch(Triple::mips64); break;
742 case Triple::mipsel: T.setArch(Triple::mips64el); break;
743 case Triple::ppc: T.setArch(Triple::ppc64); break;
744 case Triple::ptx32: T.setArch(Triple::ptx64); break;
745 case Triple::sparc: T.setArch(Triple::sparcv9); break;
746 case Triple::x86: T.setArch(Triple::x86_64); break;
747 }
748 return T;
749}