Triple.cpp revision 29269d03af6dc3feb69d0230831a059f39c03700
1//===--- 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" 11 12#include "llvm/ADT/SmallString.h" 13#include "llvm/ADT/Twine.h" 14#include <cassert> 15#include <cstring> 16using namespace llvm; 17 18// 19 20const char *Triple::getArchTypeName(ArchType Kind) { 21 switch (Kind) { 22 case InvalidArch: return "<invalid>"; 23 case UnknownArch: return "unknown"; 24 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"; 44 } 45 46 return "<invalid>"; 47} 48 49const char *Triple::getArchTypePrefix(ArchType Kind) { 50 switch (Kind) { 51 default: 52 return 0; 53 54 case alpha: return "alpha"; 55 56 case arm: 57 case thumb: return "arm"; 58 59 case bfin: return "bfin"; 60 61 case cellspu: return "spu"; 62 63 case ppc64: 64 case ppc: return "ppc"; 65 66 case mblaze: return "mblaze"; 67 68 case sparcv9: 69 case sparc: return "sparc"; 70 71 case x86: 72 case x86_64: return "x86"; 73 case xcore: return "xcore"; 74 } 75} 76 77const char *Triple::getVendorTypeName(VendorType Kind) { 78 switch (Kind) { 79 case UnknownVendor: return "unknown"; 80 81 case Apple: return "apple"; 82 case PC: return "pc"; 83 } 84 85 return "<invalid>"; 86} 87 88const char *Triple::getOSTypeName(OSType Kind) { 89 switch (Kind) { 90 case UnknownOS: return "unknown"; 91 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"; 108 } 109 110 return "<invalid>"; 111} 112 113Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) { 114 if (Name == "alpha") 115 return alpha; 116 if (Name == "arm") 117 return arm; 118 if (Name == "bfin") 119 return bfin; 120 if (Name == "cellspu") 121 return cellspu; 122 if (Name == "mips") 123 return mips; 124 if (Name == "mipsel") 125 return mipsel; 126 if (Name == "msp430") 127 return msp430; 128 if (Name == "pic16") 129 return pic16; 130 if (Name == "ppc64") 131 return ppc64; 132 if (Name == "ppc") 133 return ppc; 134 if (Name == "mblaze") 135 return mblaze; 136 if (Name == "sparc") 137 return sparc; 138 if (Name == "sparcv9") 139 return sparcv9; 140 if (Name == "systemz") 141 return systemz; 142 if (Name == "tce") 143 return tce; 144 if (Name == "thumb") 145 return thumb; 146 if (Name == "x86") 147 return x86; 148 if (Name == "x86-64") 149 return x86_64; 150 if (Name == "xcore") 151 return xcore; 152 153 return UnknownArch; 154} 155 156Triple::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. 159 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 164 // support for it. 165 166 // This code must be kept in sync with Clang's Darwin specific argument 167 // translation. 168 169 if (Str == "ppc" || Str == "ppc601" || Str == "ppc603" || Str == "ppc604" || 170 Str == "ppc604e" || Str == "ppc750" || Str == "ppc7400" || 171 Str == "ppc7450" || Str == "ppc970") 172 return Triple::ppc; 173 174 if (Str == "ppc64") 175 return Triple::ppc64; 176 177 if (Str == "i386" || Str == "i486" || Str == "i486SX" || Str == "pentium" || 178 Str == "i586" || Str == "pentpro" || Str == "i686" || Str == "pentIIm3" || 179 Str == "pentIIm5" || Str == "pentium4") 180 return Triple::x86; 181 182 if (Str == "x86_64") 183 return Triple::x86_64; 184 185 // This is derived from the driver driver. 186 if (Str == "arm" || Str == "armv4t" || Str == "armv5" || Str == "xscale" || 187 Str == "armv6" || Str == "armv7") 188 return Triple::arm; 189 190 return Triple::UnknownArch; 191} 192 193// Returns architecture name that is understood by the target assembler. 194const char *Triple::getArchNameForAssembler() { 195 if (getOS() != Triple::Darwin && getVendor() != Triple::Apple) 196 return NULL; 197 198 StringRef Str = getArchName(); 199 if (Str == "i386") 200 return "i386"; 201 if (Str == "x86_64") 202 return "x86_64"; 203 if (Str == "powerpc") 204 return "ppc"; 205 if (Str == "powerpc64") 206 return "ppc64"; 207 if (Str == "mblaze" || Str == "microblaze") 208 return "mblaze"; 209 if (Str == "arm") 210 return "arm"; 211 if (Str == "armv4t" || Str == "thumbv4t") 212 return "armv4t"; 213 if (Str == "armv5" || Str == "armv5e" || Str == "thumbv5" || Str == "thumbv5e") 214 return "armv5"; 215 if (Str == "armv6" || Str == "thumbv6") 216 return "armv6"; 217 if (Str == "armv7" || Str == "thumbv7") 218 return "armv7"; 219 return NULL; 220} 221 222// 223 224void Triple::Parse() const { 225 assert(!isInitialized() && "Invalid parse call."); 226 227 StringRef ArchName = getArchName(); 228 StringRef VendorName = getVendorName(); 229 StringRef OSName = getOSName(); 230 231 if (ArchName.size() == 4 && ArchName[0] == 'i' && 232 ArchName[2] == '8' && ArchName[3] == '6' && 233 ArchName[1] - '3' < 6) // i[3-9]86 234 Arch = x86; 235 else if (ArchName == "amd64" || ArchName == "x86_64") 236 Arch = x86_64; 237 else if (ArchName == "bfin") 238 Arch = bfin; 239 else if (ArchName == "pic16") 240 Arch = pic16; 241 else if (ArchName == "powerpc") 242 Arch = ppc; 243 else if ((ArchName == "powerpc64") || (ArchName == "ppu")) 244 Arch = ppc64; 245 else if (ArchName == "mblaze") 246 Arch = mblaze; 247 else if (ArchName == "arm" || 248 ArchName.startswith("armv") || 249 ArchName == "xscale") 250 Arch = arm; 251 else if (ArchName == "thumb" || 252 ArchName.startswith("thumbv")) 253 Arch = thumb; 254 else if (ArchName.startswith("alpha")) 255 Arch = alpha; 256 else if (ArchName == "spu" || ArchName == "cellspu") 257 Arch = cellspu; 258 else if (ArchName == "msp430") 259 Arch = msp430; 260 else if (ArchName == "mips" || ArchName == "mipsallegrex") 261 Arch = mips; 262 else if (ArchName == "mipsel" || ArchName == "mipsallegrexel" || 263 ArchName == "psp") 264 Arch = mipsel; 265 else if (ArchName == "sparc") 266 Arch = sparc; 267 else if (ArchName == "sparcv9") 268 Arch = sparcv9; 269 else if (ArchName == "s390x") 270 Arch = systemz; 271 else if (ArchName == "tce") 272 Arch = tce; 273 else if (ArchName == "xcore") 274 Arch = xcore; 275 else 276 Arch = UnknownArch; 277 278 279 // Handle some exceptional cases where the OS / environment components are 280 // stuck into the vendor field. 281 if (StringRef(getTriple()).count('-') == 1) { 282 StringRef VendorName = getVendorName(); 283 284 if (VendorName.startswith("mingw32")) { // 'i386-mingw32', etc. 285 Vendor = PC; 286 OS = MinGW32; 287 return; 288 } 289 290 // arm-elf is another example, but we don't currently parse anything about 291 // the environment. 292 } 293 294 if (VendorName == "apple") 295 Vendor = Apple; 296 else if (VendorName == "pc") 297 Vendor = PC; 298 else 299 Vendor = UnknownVendor; 300 301 if (OSName.startswith("auroraux")) 302 OS = AuroraUX; 303 else if (OSName.startswith("cygwin")) 304 OS = Cygwin; 305 else if (OSName.startswith("darwin")) 306 OS = Darwin; 307 else if (OSName.startswith("dragonfly")) 308 OS = DragonFly; 309 else if (OSName.startswith("freebsd")) 310 OS = FreeBSD; 311 else if (OSName.startswith("linux")) 312 OS = Linux; 313 else if (OSName.startswith("lv2")) 314 OS = Lv2; 315 else if (OSName.startswith("mingw32")) 316 OS = MinGW32; 317 else if (OSName.startswith("mingw64")) 318 OS = MinGW64; 319 else if (OSName.startswith("netbsd")) 320 OS = NetBSD; 321 else if (OSName.startswith("openbsd")) 322 OS = OpenBSD; 323 else if (OSName.startswith("psp")) 324 OS = Psp; 325 else if (OSName.startswith("solaris")) 326 OS = Solaris; 327 else if (OSName.startswith("win32")) 328 OS = Win32; 329 else if (OSName.startswith("haiku")) 330 OS = Haiku; 331 else if (OSName.startswith("minix")) 332 OS = Minix; 333 else 334 OS = UnknownOS; 335 336 assert(isInitialized() && "Failed to initialize!"); 337} 338 339StringRef Triple::getArchName() const { 340 return StringRef(Data).split('-').first; // Isolate first component 341} 342 343StringRef Triple::getVendorName() const { 344 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 345 return Tmp.split('-').first; // Isolate second component 346} 347 348StringRef Triple::getOSName() const { 349 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 350 Tmp = Tmp.split('-').second; // Strip second component 351 return Tmp.split('-').first; // Isolate third component 352} 353 354StringRef Triple::getEnvironmentName() const { 355 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 356 Tmp = Tmp.split('-').second; // Strip second component 357 return Tmp.split('-').second; // Strip third component 358} 359 360StringRef Triple::getOSAndEnvironmentName() const { 361 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 362 return Tmp.split('-').second; // Strip second component 363} 364 365static unsigned EatNumber(StringRef &Str) { 366 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number"); 367 unsigned Result = Str[0]-'0'; 368 369 // Eat the digit. 370 Str = Str.substr(1); 371 372 // Handle "darwin11". 373 if (Result == 1 && !Str.empty() && Str[0] >= '0' && Str[0] <= '9') { 374 Result = Result*10 + (Str[0] - '0'); 375 // Eat the digit. 376 Str = Str.substr(1); 377 } 378 379 return Result; 380} 381 382/// getDarwinNumber - Parse the 'darwin number' out of the specific target 383/// triple. For example, if we have darwin8.5 return 8,5,0. If any entry is 384/// not defined, return 0's. This requires that the triple have an OSType of 385/// darwin before it is called. 386void Triple::getDarwinNumber(unsigned &Maj, unsigned &Min, 387 unsigned &Revision) const { 388 assert(getOS() == Darwin && "Not a darwin target triple!"); 389 StringRef OSName = getOSName(); 390 assert(OSName.startswith("darwin") && "Unknown darwin target triple!"); 391 392 // Strip off "darwin". 393 OSName = OSName.substr(6); 394 395 Maj = Min = Revision = 0; 396 397 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9') 398 return; 399 400 // The major version is the first digit. 401 Maj = EatNumber(OSName); 402 if (OSName.empty()) return; 403 404 // Handle minor version: 10.4.9 -> darwin8.9. 405 if (OSName[0] != '.') 406 return; 407 408 // Eat the '.'. 409 OSName = OSName.substr(1); 410 411 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9') 412 return; 413 414 Min = EatNumber(OSName); 415 if (OSName.empty()) return; 416 417 // Handle revision darwin8.9.1 418 if (OSName[0] != '.') 419 return; 420 421 // Eat the '.'. 422 OSName = OSName.substr(1); 423 424 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9') 425 return; 426 427 Revision = EatNumber(OSName); 428} 429 430void Triple::setTriple(const Twine &Str) { 431 Data = Str.str(); 432 Arch = InvalidArch; 433} 434 435void Triple::setArch(ArchType Kind) { 436 setArchName(getArchTypeName(Kind)); 437} 438 439void Triple::setVendor(VendorType Kind) { 440 setVendorName(getVendorTypeName(Kind)); 441} 442 443void Triple::setOS(OSType Kind) { 444 setOSName(getOSTypeName(Kind)); 445} 446 447void Triple::setArchName(StringRef Str) { 448 // Work around a miscompilation bug for Twines in gcc 4.0.3. 449 SmallString<64> Triple; 450 Triple += Str; 451 Triple += "-"; 452 Triple += getVendorName(); 453 Triple += "-"; 454 Triple += getOSAndEnvironmentName(); 455 setTriple(Triple.str()); 456} 457 458void Triple::setVendorName(StringRef Str) { 459 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName()); 460} 461 462void Triple::setOSName(StringRef Str) { 463 if (hasEnvironment()) 464 setTriple(getArchName() + "-" + getVendorName() + "-" + Str + 465 "-" + getEnvironmentName()); 466 else 467 setTriple(getArchName() + "-" + getVendorName() + "-" + Str); 468} 469 470void Triple::setEnvironmentName(StringRef Str) { 471 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() + 472 "-" + Str); 473} 474 475void Triple::setOSAndEnvironmentName(StringRef Str) { 476 setTriple(getArchName() + "-" + getVendorName() + "-" + Str); 477} 478