1
//===--- Triple.cpp - Target triple helper class --------------------------===//
3
// The LLVM Compiler Infrastructure
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
8
//===----------------------------------------------------------------------===//
10
#include "llvm/ADT/Triple.h"
12
#include "llvm/ADT/SmallString.h"
13
#include "llvm/ADT/Twine.h"
20
const char *Triple::getArchTypeName(ArchType Kind) {
22
case InvalidArch: return "<invalid>";
23
case UnknownArch: return "unknown";
25
case alpha: return "alpha";
26
case arm: return "arm";
27
case bfin: return "bfin";
28
case cellspu: return "cellspu";
29
case mips: return "mips";
30
case mipsel: return "mipsel";
31
case msp430: return "msp430";
32
case pic16: return "pic16";
33
case ppc64: return "powerpc64";
34
case ppc: return "powerpc";
35
case sparc: return "sparc";
36
case sparcv9: return "sparcv9";
37
case systemz: return "s390x";
38
case tce: return "tce";
39
case thumb: return "thumb";
40
case x86: return "i386";
41
case x86_64: return "x86_64";
42
case xcore: return "xcore";
43
case mblaze: return "mblaze";
49
const char *Triple::getArchTypePrefix(ArchType Kind) {
54
case alpha: return "alpha";
57
case thumb: return "arm";
59
case bfin: return "bfin";
61
case cellspu: return "spu";
64
case ppc: return "ppc";
66
case mblaze: return "mblaze";
69
case sparc: return "sparc";
72
case x86_64: return "x86";
73
case xcore: return "xcore";
77
const char *Triple::getVendorTypeName(VendorType Kind) {
79
case UnknownVendor: return "unknown";
81
case Apple: return "apple";
88
const char *Triple::getOSTypeName(OSType Kind) {
90
case UnknownOS: return "unknown";
92
case AuroraUX: return "auroraux";
93
case Cygwin: return "cygwin";
94
case Darwin: return "darwin";
95
case DragonFly: return "dragonfly";
96
case FreeBSD: return "freebsd";
97
case Linux: return "linux";
98
case Lv2: return "lv2";
99
case MinGW32: return "mingw32";
100
case MinGW64: return "mingw64";
101
case NetBSD: return "netbsd";
102
case OpenBSD: return "openbsd";
103
case Psp: return "psp";
104
case Solaris: return "solaris";
105
case Win32: return "win32";
106
case Haiku: return "haiku";
107
case Minix: return "minix";
113
Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
120
if (Name == "cellspu")
124
if (Name == "mipsel")
126
if (Name == "msp430")
134
if (Name == "mblaze")
138
if (Name == "sparcv9")
140
if (Name == "systemz")
148
if (Name == "x86-64")
156
Triple::ArchType Triple::getArchTypeForDarwinArchName(StringRef Str) {
157
// See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
158
// archs which Darwin doesn't use.
160
// The matching this routine does is fairly pointless, since it is neither the
161
// complete architecture list, nor a reasonable subset. The problem is that
162
// historically the driver driver accepts this and also ties its -march=
163
// handling to the architecture name, so we need to be careful before removing
166
// This code must be kept in sync with Clang's Darwin specific argument
169
if (Str == "ppc" || Str == "ppc601" || Str == "ppc603" || Str == "ppc604" ||
170
Str == "ppc604e" || Str == "ppc750" || Str == "ppc7400" ||
171
Str == "ppc7450" || Str == "ppc970")
175
return Triple::ppc64;
177
if (Str == "i386" || Str == "i486" || Str == "i486SX" || Str == "pentium" ||
178
Str == "i586" || Str == "pentpro" || Str == "i686" || Str == "pentIIm3" ||
179
Str == "pentIIm5" || Str == "pentium4")
183
return Triple::x86_64;
185
// This is derived from the driver driver.
186
if (Str == "arm" || Str == "armv4t" || Str == "armv5" || Str == "xscale" ||
187
Str == "armv6" || Str == "armv7")
190
return Triple::UnknownArch;
193
// Returns architecture name that is understood by the target assembler.
194
const char *Triple::getArchNameForAssembler() {
195
if (getOS() != Triple::Darwin && getVendor() != Triple::Apple)
198
StringRef Str = getArchName();
203
if (Str == "powerpc")
205
if (Str == "powerpc64")
207
if (Str == "mblaze" || Str == "microblaze")
211
if (Str == "armv4t" || Str == "thumbv4t")
213
if (Str == "armv5" || Str == "armv5e" || Str == "thumbv5" || Str == "thumbv5e")
215
if (Str == "armv6" || Str == "thumbv6")
217
if (Str == "armv7" || Str == "thumbv7")
224
Triple::ArchType Triple::ParseArch(StringRef ArchName) {
225
if (ArchName.size() == 4 && ArchName[0] == 'i' &&
226
ArchName[2] == '8' && ArchName[3] == '6' &&
227
ArchName[1] - '3' < 6) // i[3-9]86
229
else if (ArchName == "amd64" || ArchName == "x86_64")
231
else if (ArchName == "bfin")
233
else if (ArchName == "pic16")
235
else if (ArchName == "powerpc")
237
else if ((ArchName == "powerpc64") || (ArchName == "ppu"))
239
else if (ArchName == "mblaze")
241
else if (ArchName == "arm" ||
242
ArchName.startswith("armv") ||
243
ArchName == "xscale")
245
else if (ArchName == "thumb" ||
246
ArchName.startswith("thumbv"))
248
else if (ArchName.startswith("alpha"))
250
else if (ArchName == "spu" || ArchName == "cellspu")
252
else if (ArchName == "msp430")
254
else if (ArchName == "mips" || ArchName == "mipsallegrex")
256
else if (ArchName == "mipsel" || ArchName == "mipsallegrexel" ||
259
else if (ArchName == "sparc")
261
else if (ArchName == "sparcv9")
263
else if (ArchName == "s390x")
265
else if (ArchName == "tce")
267
else if (ArchName == "xcore")
273
Triple::VendorType Triple::ParseVendor(StringRef VendorName) {
274
if (VendorName == "apple")
276
else if (VendorName == "pc")
279
return UnknownVendor;
282
Triple::OSType Triple::ParseOS(StringRef OSName) {
283
if (OSName.startswith("auroraux"))
285
else if (OSName.startswith("cygwin"))
287
else if (OSName.startswith("darwin"))
289
else if (OSName.startswith("dragonfly"))
291
else if (OSName.startswith("freebsd"))
293
else if (OSName.startswith("linux"))
295
else if (OSName.startswith("lv2"))
297
else if (OSName.startswith("mingw32"))
299
else if (OSName.startswith("mingw64"))
301
else if (OSName.startswith("netbsd"))
303
else if (OSName.startswith("openbsd"))
305
else if (OSName.startswith("psp"))
307
else if (OSName.startswith("solaris"))
309
else if (OSName.startswith("win32"))
311
else if (OSName.startswith("haiku"))
313
else if (OSName.startswith("minix"))
319
void Triple::Parse() const {
320
assert(!isInitialized() && "Invalid parse call.");
322
Arch = ParseArch(getArchName());
323
Vendor = ParseVendor(getVendorName());
324
OS = ParseOS(getOSName());
326
assert(isInitialized() && "Failed to initialize!");
329
std::string Triple::normalize(StringRef Str) {
330
// Parse into components.
331
SmallVector<StringRef, 4> Components;
332
for (size_t First = 0, Last = 0; Last != StringRef::npos; First = Last + 1) {
333
Last = Str.find('-', First);
334
Components.push_back(Str.slice(First, Last));
337
// If the first component corresponds to a known architecture, preferentially
338
// use it for the architecture. If the second component corresponds to a
339
// known vendor, preferentially use it for the vendor, etc. This avoids silly
340
// component movement when a component parses as (eg) both a valid arch and a
342
ArchType Arch = UnknownArch;
343
if (Components.size() > 0)
344
Arch = ParseArch(Components[0]);
345
VendorType Vendor = UnknownVendor;
346
if (Components.size() > 1)
347
Vendor = ParseVendor(Components[1]);
348
OSType OS = UnknownOS;
349
if (Components.size() > 2)
350
OS = ParseOS(Components[2]);
352
// Note which components are already in their final position. These will not
355
Found[0] = Arch != UnknownArch;
356
Found[1] = Vendor != UnknownVendor;
357
Found[2] = OS != UnknownOS;
359
// If they are not there already, permute the components into their canonical
360
// positions by seeing if they parse as a valid architecture, and if so moving
361
// the component to the architecture position etc.
362
for (unsigned Pos = 0; Pos != 3; ++Pos) {
364
continue; // Already in the canonical position.
366
for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
367
// Do not reparse any components that already matched.
368
if (Idx < 3 && Found[Idx])
371
// Does this component parse as valid for the target position?
373
StringRef Comp = Components[Idx];
376
assert(false && "unexpected component type!");
378
Arch = ParseArch(Comp);
379
Valid = Arch != UnknownArch;
382
Vendor = ParseVendor(Comp);
383
Valid = Vendor != UnknownVendor;
387
Valid = OS != UnknownOS;
391
continue; // Nope, try the next component.
393
// Move the component to the target position, pushing any non-fixed
394
// components that are in the way to the right. This tends to give
395
// good results in the common cases of a forgotten vendor component
396
// or a wrongly positioned environment.
398
// Insert left, pushing the existing components to the right. For
399
// example, a-b-i386 -> i386-a-b when moving i386 to the front.
400
StringRef CurrentComponent(""); // The empty component.
401
// Replace the component we are moving with an empty component.
402
std::swap(CurrentComponent, Components[Idx]);
403
// Insert the component being moved at Pos, displacing any existing
404
// components to the right.
405
for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
406
// Skip over any fixed components.
407
while (i < 3 && Found[i]) ++i;
408
// Place the component at the new position, getting the component
409
// that was at this position - it will be moved right.
410
std::swap(CurrentComponent, Components[i]);
412
} else if (Pos > Idx) {
413
// Push right by inserting empty components until the component at Idx
414
// reaches the target position Pos. For example, pc-a -> -pc-a when
415
// moving pc to the second position.
417
// Insert one empty component at Idx.
418
StringRef CurrentComponent(""); // The empty component.
419
for (unsigned i = Idx; i < Components.size(); ++i) {
420
// Skip over any fixed components.
421
while (i < 3 && Found[i]) ++i;
422
// Place the component at the new position, getting the component
423
// that was at this position - it will be moved right.
424
std::swap(CurrentComponent, Components[i]);
425
// If it was placed on top of an empty component then we are done.
426
if (CurrentComponent.empty())
429
// The last component was pushed off the end - append it.
430
if (!CurrentComponent.empty())
431
Components.push_back(CurrentComponent);
433
// Advance Idx to the component's new position.
434
while (++Idx < 3 && Found[Idx]) {}
435
} while (Idx < Pos); // Add more until the final position is reached.
437
assert(Pos < Components.size() && Components[Pos] == Comp &&
438
"Component moved wrong!");
444
// Special case logic goes here. At this point Arch, Vendor and OS have the
445
// correct values for the computed components.
447
// Stick the corrected components back together to form the normalized string.
448
std::string Normalized;
449
for (unsigned i = 0, e = Components.size(); i != e; ++i) {
450
if (i) Normalized += '-';
451
Normalized += Components[i];
456
StringRef Triple::getArchName() const {
457
return StringRef(Data).split('-').first; // Isolate first component
460
StringRef Triple::getVendorName() const {
461
StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
462
return Tmp.split('-').first; // Isolate second component
465
StringRef Triple::getOSName() const {
466
StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
467
Tmp = Tmp.split('-').second; // Strip second component
468
return Tmp.split('-').first; // Isolate third component
471
StringRef Triple::getEnvironmentName() const {
472
StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
473
Tmp = Tmp.split('-').second; // Strip second component
474
return Tmp.split('-').second; // Strip third component
477
StringRef Triple::getOSAndEnvironmentName() const {
478
StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
479
return Tmp.split('-').second; // Strip second component
482
static unsigned EatNumber(StringRef &Str) {
483
assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
484
unsigned Result = Str[0]-'0';
489
// Handle "darwin11".
490
if (Result == 1 && !Str.empty() && Str[0] >= '0' && Str[0] <= '9') {
491
Result = Result*10 + (Str[0] - '0');
499
/// getDarwinNumber - Parse the 'darwin number' out of the specific target
500
/// triple. For example, if we have darwin8.5 return 8,5,0. If any entry is
501
/// not defined, return 0's. This requires that the triple have an OSType of
502
/// darwin before it is called.
503
void Triple::getDarwinNumber(unsigned &Maj, unsigned &Min,
504
unsigned &Revision) const {
505
assert(getOS() == Darwin && "Not a darwin target triple!");
506
StringRef OSName = getOSName();
507
assert(OSName.startswith("darwin") && "Unknown darwin target triple!");
509
// Strip off "darwin".
510
OSName = OSName.substr(6);
512
Maj = Min = Revision = 0;
514
if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
517
// The major version is the first digit.
518
Maj = EatNumber(OSName);
519
if (OSName.empty()) return;
521
// Handle minor version: 10.4.9 -> darwin8.9.
522
if (OSName[0] != '.')
526
OSName = OSName.substr(1);
528
if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
531
Min = EatNumber(OSName);
532
if (OSName.empty()) return;
534
// Handle revision darwin8.9.1
535
if (OSName[0] != '.')
539
OSName = OSName.substr(1);
541
if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
544
Revision = EatNumber(OSName);
547
void Triple::setTriple(const Twine &Str) {
552
void Triple::setArch(ArchType Kind) {
553
setArchName(getArchTypeName(Kind));
556
void Triple::setVendor(VendorType Kind) {
557
setVendorName(getVendorTypeName(Kind));
560
void Triple::setOS(OSType Kind) {
561
setOSName(getOSTypeName(Kind));
564
void Triple::setArchName(StringRef Str) {
565
// Work around a miscompilation bug for Twines in gcc 4.0.3.
566
SmallString<64> Triple;
569
Triple += getVendorName();
571
Triple += getOSAndEnvironmentName();
572
setTriple(Triple.str());
575
void Triple::setVendorName(StringRef Str) {
576
setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
579
void Triple::setOSName(StringRef Str) {
580
if (hasEnvironment())
581
setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
582
"-" + getEnvironmentName());
584
setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
587
void Triple::setEnvironmentName(StringRef Str) {
588
setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
592
void Triple::setOSAndEnvironmentName(StringRef Str) {
593
setTriple(getArchName() + "-" + getVendorName() + "-" + Str);