blob: d261c5313946e8ffb343b30d2e4e362fcc70c3b3 [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";
Anton Korobeynikov74156592012-03-09 10:09:36 +000032 case r600: return "r600";
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
Anton Korobeynikov74156592012-03-09 10:09:36 +000067 case r600: return "r600";
68
Chris Lattner87c06d62010-02-04 06:34:01 +000069 case sparcv9:
Daniel Dunbar688b55b2009-08-24 09:53:06 +000070 case sparc: return "sparc";
71
72 case x86:
73 case x86_64: return "x86";
Nick Lewyckyf7a3c502010-09-07 18:14:24 +000074
Daniel Dunbar688b55b2009-08-24 09:53:06 +000075 case xcore: return "xcore";
Nick Lewyckyf7a3c502010-09-07 18:14:24 +000076
Justin Holewinskie1fee482011-04-20 15:37:17 +000077 case ptx32: return "ptx";
78 case ptx64: return "ptx";
Ivan Krasin38fb2db2011-08-23 16:59:00 +000079 case le32: return "le32";
Tobias Grosser05d71382011-08-29 15:44:55 +000080 case amdil: return "amdil";
Daniel Dunbar688b55b2009-08-24 09:53:06 +000081 }
82}
83
Daniel Dunbar23e97b02009-04-01 21:53:23 +000084const char *Triple::getVendorTypeName(VendorType Kind) {
85 switch (Kind) {
86 case UnknownVendor: return "unknown";
87
88 case Apple: return "apple";
Chris Lattner56ce0f42009-08-14 18:48:13 +000089 case PC: return "pc";
John Thompson6046cff2011-03-15 21:51:56 +000090 case SCEI: return "scei";
Daniel Dunbar23e97b02009-04-01 21:53:23 +000091 }
92
David Blaikie4d6ccb52012-01-20 21:51:11 +000093 llvm_unreachable("Invalid VendorType!");
Daniel Dunbar23e97b02009-04-01 21:53:23 +000094}
95
96const char *Triple::getOSTypeName(OSType Kind) {
97 switch (Kind) {
98 case UnknownOS: return "unknown";
99
Duncan Sands852cd112009-06-19 14:40:01 +0000100 case AuroraUX: return "auroraux";
Daniel Dunbar6337f152009-07-26 04:23:03 +0000101 case Cygwin: return "cygwin";
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000102 case Darwin: return "darwin";
Daniel Dunbar7eaf0572009-05-22 02:24:11 +0000103 case DragonFly: return "dragonfly";
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000104 case FreeBSD: return "freebsd";
Daniel Dunbar0dde4c02011-04-19 20:19:27 +0000105 case IOS: return "ios";
Duncan Sands652b48b2011-07-26 15:30:04 +0000106 case KFreeBSD: return "kfreebsd";
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000107 case Linux: return "linux";
Edward O'Callaghancc9fa812009-11-19 11:59:00 +0000108 case Lv2: return "lv2";
Daniel Dunbar1af39472011-04-19 23:34:12 +0000109 case MacOSX: return "macosx";
Daniel Dunbar6337f152009-07-26 04:23:03 +0000110 case MinGW32: return "mingw32";
Chris Lattnerb8ac8412009-07-13 20:22:23 +0000111 case NetBSD: return "netbsd";
Duncan Sandscd1267d2009-06-29 13:36:13 +0000112 case OpenBSD: return "openbsd";
Daniel Dunbarfdb0b7b2009-08-18 04:43:27 +0000113 case Solaris: return "solaris";
Daniel Dunbar6337f152009-07-26 04:23:03 +0000114 case Win32: return "win32";
Chris Lattnera43fc342009-10-16 02:06:30 +0000115 case Haiku: return "haiku";
Chris Lattner29269d02010-07-07 15:52:27 +0000116 case Minix: return "minix";
Douglas Gregor6ced1d12011-07-01 22:41:06 +0000117 case RTEMS: return "rtems";
Ivan Krasinfb234622011-08-18 22:54:21 +0000118 case NativeClient: return "nacl";
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000119 }
120
David Blaikie4d6ccb52012-01-20 21:51:11 +0000121 llvm_unreachable("Invalid OSType");
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000122}
123
Duncan Sands5754a452010-09-16 08:25:48 +0000124const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
125 switch (Kind) {
126 case UnknownEnvironment: return "unknown";
Renato Golin859f8182011-01-21 18:25:47 +0000127 case GNU: return "gnu";
Rafael Espindola8887a0f2012-01-18 23:35:29 +0000128 case GNUEABIHF: return "gnueabihf";
Renato Golin859f8182011-01-21 18:25:47 +0000129 case GNUEABI: return "gnueabi";
130 case EABI: return "eabi";
Evan Cheng2bffee22011-02-01 01:14:13 +0000131 case MachO: return "macho";
Chandler Carruthfd553c22012-01-10 19:46:00 +0000132 case ANDROIDEABI: return "androideabi";
Duncan Sands5754a452010-09-16 08:25:48 +0000133 }
134
David Blaikie4d6ccb52012-01-20 21:51:11 +0000135 llvm_unreachable("Invalid EnvironmentType!");
Duncan Sands5754a452010-09-16 08:25:48 +0000136}
137
Daniel Dunbar2928c832009-11-06 10:58:06 +0000138Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
Chandler Carruth06accda2012-02-12 09:27:38 +0000139 return StringSwitch<Triple::ArchType>(Name)
140 .Case("arm", arm)
141 .Case("cellspu", cellspu)
142 .Case("mips", mips)
143 .Case("mipsel", mipsel)
144 .Case("mips64", mips64)
145 .Case("mips64el", mips64el)
146 .Case("msp430", msp430)
147 .Case("ppc64", ppc64)
148 .Case("ppc32", ppc)
149 .Case("ppc", ppc)
150 .Case("mblaze", mblaze)
Anton Korobeynikov74156592012-03-09 10:09:36 +0000151 .Case("r600", r600)
Chandler Carruth06accda2012-02-12 09:27:38 +0000152 .Case("hexagon", hexagon)
153 .Case("sparc", sparc)
154 .Case("sparcv9", sparcv9)
155 .Case("tce", tce)
156 .Case("thumb", thumb)
157 .Case("x86", x86)
158 .Case("x86-64", x86_64)
159 .Case("xcore", xcore)
160 .Case("ptx32", ptx32)
161 .Case("ptx64", ptx64)
162 .Case("le32", le32)
163 .Case("amdil", amdil)
164 .Default(UnknownArch);
Daniel Dunbar3c2d4bf2009-08-03 04:03:51 +0000165}
166
Daniel Dunbar2928c832009-11-06 10:58:06 +0000167Triple::ArchType Triple::getArchTypeForDarwinArchName(StringRef Str) {
Daniel Dunbarbaf9b562009-09-08 23:32:51 +0000168 // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
169 // archs which Darwin doesn't use.
170
171 // The matching this routine does is fairly pointless, since it is neither the
172 // complete architecture list, nor a reasonable subset. The problem is that
173 // historically the driver driver accepts this and also ties its -march=
174 // handling to the architecture name, so we need to be careful before removing
175 // support for it.
176
Daniel Dunbared687882009-09-09 23:01:25 +0000177 // This code must be kept in sync with Clang's Darwin specific argument
178 // translation.
179
Chandler Carruth06accda2012-02-12 09:27:38 +0000180 return StringSwitch<ArchType>(Str)
181 .Cases("ppc", "ppc601", "ppc603", "ppc604", "ppc604e", Triple::ppc)
182 .Cases("ppc750", "ppc7400", "ppc7450", "ppc970", Triple::ppc)
183 .Case("ppc64", Triple::ppc64)
184 .Cases("i386", "i486", "i486SX", "i586", "i686", Triple::x86)
185 .Cases("pentium", "pentpro", "pentIIm3", "pentIIm5", "pentium4",
186 Triple::x86)
187 .Case("x86_64", Triple::x86_64)
188 // This is derived from the driver driver.
189 .Cases("arm", "armv4t", "armv5", "armv6", Triple::arm)
190 .Cases("armv7", "armv7f", "armv7k", "armv7s", "xscale", Triple::arm)
Anton Korobeynikov74156592012-03-09 10:09:36 +0000191 .Case("r600", Triple::r600)
Chandler Carruth06accda2012-02-12 09:27:38 +0000192 .Case("ptx32", Triple::ptx32)
193 .Case("ptx64", Triple::ptx64)
194 .Case("amdil", Triple::amdil)
195 .Default(Triple::UnknownArch);
Daniel Dunbarbaf9b562009-09-08 23:32:51 +0000196}
197
Duncan Sandsbbdca3f2010-03-24 09:05:14 +0000198// Returns architecture name that is understood by the target assembler.
Viktor Kutuzov51cdac02009-11-17 18:48:27 +0000199const char *Triple::getArchNameForAssembler() {
Daniel Dunbare1fe09f2011-04-19 21:12:05 +0000200 if (!isOSDarwin() && getVendor() != Triple::Apple)
Viktor Kutuzov51cdac02009-11-17 18:48:27 +0000201 return NULL;
202
Chandler Carruth06accda2012-02-12 09:27:38 +0000203 return StringSwitch<const char*>(getArchName())
204 .Case("i386", "i386")
205 .Case("x86_64", "x86_64")
206 .Case("powerpc", "ppc")
207 .Case("powerpc64", "ppc64")
208 .Cases("mblaze", "microblaze", "mblaze")
209 .Case("arm", "arm")
210 .Cases("armv4t", "thumbv4t", "armv4t")
211 .Cases("armv5", "armv5e", "thumbv5", "thumbv5e", "armv5")
212 .Cases("armv6", "thumbv6", "armv6")
213 .Cases("armv7", "thumbv7", "armv7")
Anton Korobeynikov74156592012-03-09 10:09:36 +0000214 .Case("r600", "r600")
Chandler Carruth06accda2012-02-12 09:27:38 +0000215 .Case("ptx32", "ptx32")
216 .Case("ptx64", "ptx64")
217 .Case("le32", "le32")
218 .Case("amdil", "amdil")
219 .Default(NULL);
Viktor Kutuzov51cdac02009-11-17 18:48:27 +0000220}
221
Chandler Carruth4fbf6582012-02-21 08:53:32 +0000222static Triple::ArchType parseArch(StringRef ArchName) {
223 return StringSwitch<Triple::ArchType>(ArchName)
224 .Cases("i386", "i486", "i586", "i686", Triple::x86)
225 // FIXME: Do we need to support these?
226 .Cases("i786", "i886", "i986", Triple::x86)
227 .Cases("amd64", "x86_64", Triple::x86_64)
228 .Case("powerpc", Triple::ppc)
229 .Cases("powerpc64", "ppu", Triple::ppc64)
230 .Case("mblaze", Triple::mblaze)
231 .Cases("arm", "xscale", Triple::arm)
Chandler Carruth0a857712012-02-18 04:34:17 +0000232 // FIXME: It would be good to replace these with explicit names for all the
233 // various suffixes supported.
Chandler Carruth4fbf6582012-02-21 08:53:32 +0000234 .StartsWith("armv", Triple::arm)
235 .Case("thumb", Triple::thumb)
236 .StartsWith("thumbv", Triple::thumb)
237 .Cases("spu", "cellspu", Triple::cellspu)
238 .Case("msp430", Triple::msp430)
239 .Cases("mips", "mipseb", "mipsallegrex", Triple::mips)
Chandler Carruthfdf0dc92012-02-22 11:32:54 +0000240 .Cases("mipsel", "mipsallegrexel", Triple::mipsel)
Chandler Carruth4fbf6582012-02-21 08:53:32 +0000241 .Cases("mips64", "mips64eb", Triple::mips64)
242 .Case("mips64el", Triple::mips64el)
Anton Korobeynikov74156592012-03-09 10:09:36 +0000243 .Case("r600", Triple::r600)
Chandler Carruth4fbf6582012-02-21 08:53:32 +0000244 .Case("hexagon", Triple::hexagon)
245 .Case("sparc", Triple::sparc)
246 .Case("sparcv9", Triple::sparcv9)
247 .Case("tce", Triple::tce)
248 .Case("xcore", Triple::xcore)
249 .Case("ptx32", Triple::ptx32)
250 .Case("ptx64", Triple::ptx64)
251 .Case("le32", Triple::le32)
252 .Case("amdil", Triple::amdil)
253 .Default(Triple::UnknownArch);
Duncan Sands335db222010-08-12 11:31:39 +0000254}
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000255
Chandler Carruth4fbf6582012-02-21 08:53:32 +0000256static Triple::VendorType parseVendor(StringRef VendorName) {
257 return StringSwitch<Triple::VendorType>(VendorName)
258 .Case("apple", Triple::Apple)
259 .Case("pc", Triple::PC)
260 .Case("scei", Triple::SCEI)
261 .Default(Triple::UnknownVendor);
Duncan Sands335db222010-08-12 11:31:39 +0000262}
263
Chandler Carruth4fbf6582012-02-21 08:53:32 +0000264static Triple::OSType parseOS(StringRef OSName) {
265 return StringSwitch<Triple::OSType>(OSName)
266 .StartsWith("auroraux", Triple::AuroraUX)
267 .StartsWith("cygwin", Triple::Cygwin)
268 .StartsWith("darwin", Triple::Darwin)
269 .StartsWith("dragonfly", Triple::DragonFly)
270 .StartsWith("freebsd", Triple::FreeBSD)
271 .StartsWith("ios", Triple::IOS)
272 .StartsWith("kfreebsd", Triple::KFreeBSD)
273 .StartsWith("linux", Triple::Linux)
274 .StartsWith("lv2", Triple::Lv2)
275 .StartsWith("macosx", Triple::MacOSX)
276 .StartsWith("mingw32", Triple::MinGW32)
277 .StartsWith("netbsd", Triple::NetBSD)
278 .StartsWith("openbsd", Triple::OpenBSD)
Chandler Carruth4fbf6582012-02-21 08:53:32 +0000279 .StartsWith("solaris", Triple::Solaris)
280 .StartsWith("win32", Triple::Win32)
281 .StartsWith("haiku", Triple::Haiku)
282 .StartsWith("minix", Triple::Minix)
283 .StartsWith("rtems", Triple::RTEMS)
284 .StartsWith("nacl", Triple::NativeClient)
285 .Default(Triple::UnknownOS);
Duncan Sands335db222010-08-12 11:31:39 +0000286}
287
Chandler Carruth4fbf6582012-02-21 08:53:32 +0000288static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) {
289 return StringSwitch<Triple::EnvironmentType>(EnvironmentName)
290 .StartsWith("eabi", Triple::EABI)
291 .StartsWith("gnueabihf", Triple::GNUEABIHF)
292 .StartsWith("gnueabi", Triple::GNUEABI)
293 .StartsWith("gnu", Triple::GNU)
294 .StartsWith("macho", Triple::MachO)
295 .StartsWith("androideabi", Triple::ANDROIDEABI)
296 .Default(Triple::UnknownEnvironment);
Duncan Sands5754a452010-09-16 08:25:48 +0000297}
298
Chandler Carruthcceb8f42012-02-20 00:02:47 +0000299/// \brief Construct a triple from the string representation provided.
300///
Chandler Carruth0523f412012-02-21 08:31:18 +0000301/// This stores the string representation and parses the various pieces into
302/// enum members.
Chandler Carruth124e51c2012-02-21 03:39:36 +0000303Triple::Triple(const Twine &Str)
304 : Data(Str.str()),
Chandler Carruth4fbf6582012-02-21 08:53:32 +0000305 Arch(parseArch(getArchName())),
306 Vendor(parseVendor(getVendorName())),
307 OS(parseOS(getOSName())),
308 Environment(parseEnvironment(getEnvironmentName())) {
Chandler Carruth124e51c2012-02-21 03:39:36 +0000309}
Chandler Carruthcceb8f42012-02-20 00:02:47 +0000310
311/// \brief Construct a triple from string representations of the architecture,
312/// vendor, and OS.
313///
Chandler Carruth0523f412012-02-21 08:31:18 +0000314/// This joins each argument into a canonical string representation and parses
315/// them into enum members. It leaves the environment unknown and omits it from
316/// the string representation.
Chandler Carruthcceb8f42012-02-20 00:02:47 +0000317Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr)
318 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()),
Chandler Carruth4fbf6582012-02-21 08:53:32 +0000319 Arch(parseArch(ArchStr.str())),
320 Vendor(parseVendor(VendorStr.str())),
321 OS(parseOS(OSStr.str())),
Chandler Carruth124e51c2012-02-21 03:39:36 +0000322 Environment() {
Chandler Carruthcceb8f42012-02-20 00:02:47 +0000323}
324
325/// \brief Construct a triple from string representations of the architecture,
326/// vendor, OS, and environment.
327///
Chandler Carruth0523f412012-02-21 08:31:18 +0000328/// This joins each argument into a canonical string representation and parses
329/// them into enum members.
Chandler Carruthcceb8f42012-02-20 00:02:47 +0000330Triple::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()),
Chandler Carruth4fbf6582012-02-21 08:53:32 +0000334 Arch(parseArch(ArchStr.str())),
335 Vendor(parseVendor(VendorStr.str())),
336 OS(parseOS(OSStr.str())),
337 Environment(parseEnvironment(EnvironmentStr.str())) {
Chandler Carruthcceb8f42012-02-20 00:02:47 +0000338}
339
Duncan Sands335db222010-08-12 11:31:39 +0000340std::string Triple::normalize(StringRef Str) {
341 // Parse into components.
342 SmallVector<StringRef, 4> Components;
Chandler Carruthdac3d362012-02-21 09:12:48 +0000343 Str.split(Components, "-");
Duncan Sands335db222010-08-12 11:31:39 +0000344
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)
Chandler Carruth4fbf6582012-02-21 08:53:32 +0000352 Arch = parseArch(Components[0]);
Duncan Sands335db222010-08-12 11:31:39 +0000353 VendorType Vendor = UnknownVendor;
354 if (Components.size() > 1)
Chandler Carruth4fbf6582012-02-21 08:53:32 +0000355 Vendor = parseVendor(Components[1]);
Duncan Sands335db222010-08-12 11:31:39 +0000356 OSType OS = UnknownOS;
357 if (Components.size() > 2)
Chandler Carruth4fbf6582012-02-21 08:53:32 +0000358 OS = parseOS(Components[2]);
Duncan Sands5754a452010-09-16 08:25:48 +0000359 EnvironmentType Environment = UnknownEnvironment;
360 if (Components.size() > 3)
Chandler Carruth4fbf6582012-02-21 08:53:32 +0000361 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:
Chandler Carruth4fbf6582012-02-21 08:53:32 +0000389 Arch = parseArch(Comp);
Duncan Sands335db222010-08-12 11:31:39 +0000390 Valid = Arch != UnknownArch;
391 break;
392 case 1:
Chandler Carruth4fbf6582012-02-21 08:53:32 +0000393 Vendor = parseVendor(Comp);
Duncan Sands335db222010-08-12 11:31:39 +0000394 Valid = Vendor != UnknownVendor;
395 break;
396 case 2:
Chandler Carruth4fbf6582012-02-21 08:53:32 +0000397 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:
Chandler Carruth4fbf6582012-02-21 08:53:32 +0000401 Environment = parseEnvironment(Comp);
Duncan Sands5754a452010-09-16 08:25:48 +0000402 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.
Chandler Carruthc5f18d32012-02-21 09:29:14 +0000422 while (i < array_lengthof(Found) && Found[i])
423 ++i;
Duncan Sands335db222010-08-12 11:31:39 +0000424 // Place the component at the new position, getting the component
425 // that was at this position - it will be moved right.
426 std::swap(CurrentComponent, Components[i]);
427 }
428 } else if (Pos > Idx) {
429 // Push right by inserting empty components until the component at Idx
430 // reaches the target position Pos. For example, pc-a -> -pc-a when
431 // moving pc to the second position.
432 do {
433 // Insert one empty component at Idx.
434 StringRef CurrentComponent(""); // The empty component.
Duncan Sandsae200c62011-02-02 10:08:38 +0000435 for (unsigned i = Idx; i < Components.size();) {
Duncan Sands335db222010-08-12 11:31:39 +0000436 // Place the component at the new position, getting the component
437 // that was at this position - it will be moved right.
438 std::swap(CurrentComponent, Components[i]);
439 // If it was placed on top of an empty component then we are done.
440 if (CurrentComponent.empty())
441 break;
Duncan Sandsae200c62011-02-02 10:08:38 +0000442 // Advance to the next component, skipping any fixed components.
Anders Carlsson15ec6952011-02-05 18:19:35 +0000443 while (++i < array_lengthof(Found) && Found[i])
444 ;
Duncan Sands335db222010-08-12 11:31:39 +0000445 }
446 // The last component was pushed off the end - append it.
447 if (!CurrentComponent.empty())
448 Components.push_back(CurrentComponent);
449
450 // Advance Idx to the component's new position.
Chandler Carruthc5f18d32012-02-21 09:29:14 +0000451 while (++Idx < array_lengthof(Found) && Found[Idx])
452 ;
Duncan Sands335db222010-08-12 11:31:39 +0000453 } while (Idx < Pos); // Add more until the final position is reached.
454 }
455 assert(Pos < Components.size() && Components[Pos] == Comp &&
456 "Component moved wrong!");
457 Found[Pos] = true;
458 break;
459 }
460 }
461
462 // Special case logic goes here. At this point Arch, Vendor and OS have the
463 // correct values for the computed components.
464
465 // Stick the corrected components back together to form the normalized string.
466 std::string Normalized;
467 for (unsigned i = 0, e = Components.size(); i != e; ++i) {
468 if (i) Normalized += '-';
469 Normalized += Components[i];
470 }
471 return Normalized;
472}
473
Daniel Dunbara14d2252009-07-26 03:31:47 +0000474StringRef Triple::getArchName() const {
475 return StringRef(Data).split('-').first; // Isolate first component
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000476}
477
Daniel Dunbara14d2252009-07-26 03:31:47 +0000478StringRef Triple::getVendorName() const {
479 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
480 return Tmp.split('-').first; // Isolate second component
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000481}
482
Daniel Dunbara14d2252009-07-26 03:31:47 +0000483StringRef Triple::getOSName() const {
484 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
485 Tmp = Tmp.split('-').second; // Strip second component
486 return Tmp.split('-').first; // Isolate third component
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000487}
488
Daniel Dunbara14d2252009-07-26 03:31:47 +0000489StringRef Triple::getEnvironmentName() const {
490 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
491 Tmp = Tmp.split('-').second; // Strip second component
492 return Tmp.split('-').second; // Strip third component
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000493}
494
Daniel Dunbara14d2252009-07-26 03:31:47 +0000495StringRef Triple::getOSAndEnvironmentName() const {
496 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
497 return Tmp.split('-').second; // Strip second component
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000498}
499
Chris Lattnerdfc17f72009-08-12 06:19:40 +0000500static unsigned EatNumber(StringRef &Str) {
501 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
Daniel Dunbar087d6a52011-04-19 20:24:34 +0000502 unsigned Result = 0;
Jim Grosbache509aa92010-12-17 02:10:59 +0000503
Daniel Dunbar087d6a52011-04-19 20:24:34 +0000504 do {
505 // Consume the leading digit.
Chris Lattnerdfc17f72009-08-12 06:19:40 +0000506 Result = Result*10 + (Str[0] - '0');
Daniel Dunbar087d6a52011-04-19 20:24:34 +0000507
Chris Lattnerdfc17f72009-08-12 06:19:40 +0000508 // Eat the digit.
509 Str = Str.substr(1);
Daniel Dunbar087d6a52011-04-19 20:24:34 +0000510 } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9');
Jim Grosbache509aa92010-12-17 02:10:59 +0000511
Chris Lattnerdfc17f72009-08-12 06:19:40 +0000512 return Result;
513}
514
Daniel Dunbar087d6a52011-04-19 20:24:34 +0000515void Triple::getOSVersion(unsigned &Major, unsigned &Minor,
516 unsigned &Micro) const {
Chris Lattnerdfc17f72009-08-12 06:19:40 +0000517 StringRef OSName = getOSName();
Jim Grosbache509aa92010-12-17 02:10:59 +0000518
Daniel Dunbar087d6a52011-04-19 20:24:34 +0000519 // Assume that the OS portion of the triple starts with the canonical name.
520 StringRef OSTypeName = getOSTypeName(getOS());
521 if (OSName.startswith(OSTypeName))
522 OSName = OSName.substr(OSTypeName.size());
Jim Grosbache509aa92010-12-17 02:10:59 +0000523
Daniel Dunbar087d6a52011-04-19 20:24:34 +0000524 // Any unset version defaults to 0.
525 Major = Minor = Micro = 0;
Chris Lattnerdfc17f72009-08-12 06:19:40 +0000526
Daniel Dunbar087d6a52011-04-19 20:24:34 +0000527 // Parse up to three components.
528 unsigned *Components[3] = { &Major, &Minor, &Micro };
529 for (unsigned i = 0; i != 3; ++i) {
530 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
531 break;
Chris Lattnerdfc17f72009-08-12 06:19:40 +0000532
Daniel Dunbar087d6a52011-04-19 20:24:34 +0000533 // Consume the leading number.
534 *Components[i] = EatNumber(OSName);
Jim Grosbache509aa92010-12-17 02:10:59 +0000535
Daniel Dunbar087d6a52011-04-19 20:24:34 +0000536 // Consume the separator, if present.
537 if (OSName.startswith("."))
538 OSName = OSName.substr(1);
539 }
Chris Lattnerdfc17f72009-08-12 06:19:40 +0000540}
541
Bob Wilsonbda59fd2012-01-31 22:32:29 +0000542bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor,
543 unsigned &Micro) const {
544 getOSVersion(Major, Minor, Micro);
545
546 switch (getOS()) {
Craig Topper85814382012-02-07 05:05:23 +0000547 default: llvm_unreachable("unexpected OS for Darwin triple");
Bob Wilsonbda59fd2012-01-31 22:32:29 +0000548 case Darwin:
549 // Default to darwin8, i.e., MacOSX 10.4.
550 if (Major == 0)
551 Major = 8;
552 // Darwin version numbers are skewed from OS X versions.
553 if (Major < 4)
554 return false;
555 Micro = 0;
556 Minor = Major - 4;
557 Major = 10;
558 break;
559 case MacOSX:
560 // Default to 10.4.
561 if (Major == 0) {
562 Major = 10;
563 Minor = 4;
564 }
565 if (Major != 10)
566 return false;
567 break;
568 case IOS:
569 // Ignore the version from the triple. This is only handled because the
570 // the clang driver combines OS X and IOS support into a common Darwin
571 // toolchain that wants to know the OS X version number even when targeting
572 // IOS.
573 Major = 10;
574 Minor = 4;
575 Micro = 0;
576 break;
577 }
578 return true;
579}
580
Daniel Dunbara14d2252009-07-26 03:31:47 +0000581void Triple::setTriple(const Twine &Str) {
Chandler Carruth124e51c2012-02-21 03:39:36 +0000582 *this = Triple(Str);
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000583}
584
585void Triple::setArch(ArchType Kind) {
586 setArchName(getArchTypeName(Kind));
587}
588
589void Triple::setVendor(VendorType Kind) {
590 setVendorName(getVendorTypeName(Kind));
591}
592
593void Triple::setOS(OSType Kind) {
594 setOSName(getOSTypeName(Kind));
595}
596
Duncan Sands5754a452010-09-16 08:25:48 +0000597void Triple::setEnvironment(EnvironmentType Kind) {
598 setEnvironmentName(getEnvironmentTypeName(Kind));
599}
600
Daniel Dunbar2928c832009-11-06 10:58:06 +0000601void Triple::setArchName(StringRef Str) {
Jeffrey Yasskin0b228732009-10-06 21:45:26 +0000602 // Work around a miscompilation bug for Twines in gcc 4.0.3.
603 SmallString<64> Triple;
604 Triple += Str;
605 Triple += "-";
606 Triple += getVendorName();
607 Triple += "-";
608 Triple += getOSAndEnvironmentName();
609 setTriple(Triple.str());
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000610}
611
Daniel Dunbar2928c832009-11-06 10:58:06 +0000612void Triple::setVendorName(StringRef Str) {
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000613 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
614}
615
Daniel Dunbar2928c832009-11-06 10:58:06 +0000616void Triple::setOSName(StringRef Str) {
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000617 if (hasEnvironment())
618 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
619 "-" + getEnvironmentName());
620 else
621 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
622}
623
Daniel Dunbar2928c832009-11-06 10:58:06 +0000624void Triple::setEnvironmentName(StringRef Str) {
625 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000626 "-" + Str);
627}
628
Daniel Dunbar2928c832009-11-06 10:58:06 +0000629void Triple::setOSAndEnvironmentName(StringRef Str) {
Daniel Dunbar23e97b02009-04-01 21:53:23 +0000630 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
631}
Chandler Carruth6f72ac42012-01-31 04:52:32 +0000632
633static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
634 switch (Arch) {
635 case llvm::Triple::UnknownArch:
Chandler Carruth6f72ac42012-01-31 04:52:32 +0000636 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:
Anton Korobeynikov74156592012-03-09 10:09:36 +0000651 case llvm::Triple::r600:
Chandler Carruth6f72ac42012-01-31 04:52:32 +0000652 case llvm::Triple::sparc:
653 case llvm::Triple::tce:
654 case llvm::Triple::thumb:
655 case llvm::Triple::x86:
656 case llvm::Triple::xcore:
657 return 32;
658
659 case llvm::Triple::mips64:
660 case llvm::Triple::mips64el:
661 case llvm::Triple::ppc64:
662 case llvm::Triple::ptx64:
663 case llvm::Triple::sparcv9:
664 case llvm::Triple::x86_64:
665 return 64;
666 }
667 llvm_unreachable("Invalid architecture value");
668}
669
670bool Triple::isArch64Bit() const {
671 return getArchPointerBitWidth(getArch()) == 64;
672}
673
674bool Triple::isArch32Bit() const {
675 return getArchPointerBitWidth(getArch()) == 32;
676}
677
678bool Triple::isArch16Bit() const {
679 return getArchPointerBitWidth(getArch()) == 16;
680}
Chandler Carruth7d5a2892012-02-06 20:46:33 +0000681
682Triple Triple::get32BitArchVariant() const {
683 Triple T(*this);
684 switch (getArch()) {
685 case Triple::UnknownArch:
Chandler Carruth7d5a2892012-02-06 20:46:33 +0000686 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:
Anton Korobeynikov74156592012-03-09 10:09:36 +0000700 case Triple::r600:
Chandler Carruth7d5a2892012-02-06 20:46:33 +0000701 case Triple::sparc:
702 case Triple::tce:
703 case Triple::thumb:
704 case Triple::x86:
705 case Triple::xcore:
706 // Already 32-bit.
707 break;
708
709 case Triple::mips64: T.setArch(Triple::mips); break;
710 case Triple::mips64el: T.setArch(Triple::mipsel); break;
711 case Triple::ppc64: T.setArch(Triple::ppc); break;
712 case Triple::ptx64: T.setArch(Triple::ptx32); break;
713 case Triple::sparcv9: T.setArch(Triple::sparc); break;
714 case Triple::x86_64: T.setArch(Triple::x86); break;
715 }
716 return T;
717}
718
719Triple Triple::get64BitArchVariant() const {
720 Triple T(*this);
721 switch (getArch()) {
Chandler Carruth7d5a2892012-02-06 20:46:33 +0000722 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:
Anton Korobeynikov74156592012-03-09 10:09:36 +0000730 case Triple::r600:
Chandler Carruth7d5a2892012-02-06 20:46:33 +0000731 case Triple::tce:
732 case Triple::thumb:
733 case Triple::xcore:
734 T.setArch(UnknownArch);
735 break;
736
737 case Triple::mips64:
738 case Triple::mips64el:
739 case Triple::ppc64:
740 case Triple::ptx64:
741 case Triple::sparcv9:
742 case Triple::x86_64:
743 // Already 64-bit.
744 break;
745
746 case Triple::mips: T.setArch(Triple::mips64); break;
747 case Triple::mipsel: T.setArch(Triple::mips64el); break;
748 case Triple::ppc: T.setArch(Triple::ppc64); break;
749 case Triple::ptx32: T.setArch(Triple::ptx64); break;
750 case Triple::sparc: T.setArch(Triple::sparcv9); break;
751 case Triple::x86: T.setArch(Triple::x86_64); break;
752 }
753 return T;
754}