X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FSupport%2FTriple.cpp;h=ed91c209d545567a1abef90197501da678eca0da;hb=8855924964c05ae46fe93905a974d4b4577e7461;hp=f96c5fd9ce1da4950f368a95c6528745007add1d;hpb=f74703a44f2b3c765bfa57287cca4ac620c76188;p=oota-llvm.git diff --git a/lib/Support/Triple.cpp b/lib/Support/Triple.cpp index f96c5fd9ce1..ed91c209d54 100644 --- a/lib/Support/Triple.cpp +++ b/lib/Support/Triple.cpp @@ -12,6 +12,8 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/TargetParser.h" +#include "llvm/Support/Host.h" #include using namespace llvm; @@ -23,7 +25,9 @@ const char *Triple::getArchTypeName(ArchType Kind) { case aarch64_be: return "aarch64_be"; case arm: return "arm"; case armeb: return "armeb"; - case bpf: return "bpf"; + case avr: return "avr"; + case bpfel: return "bpfel"; + case bpfeb: return "bpfeb"; case hexagon: return "hexagon"; case mips: return "mips"; case mipsel: return "mipsel"; @@ -56,6 +60,9 @@ const char *Triple::getArchTypeName(ArchType Kind) { case spir: return "spir"; case spir64: return "spir64"; case kalimba: return "kalimba"; + case shave: return "shave"; + case wasm32: return "wasm32"; + case wasm64: return "wasm64"; } llvm_unreachable("Invalid ArchType!"); @@ -74,6 +81,8 @@ const char *Triple::getArchTypePrefix(ArchType Kind) { case thumb: case thumbeb: return "arm"; + case avr: return "avr"; + case ppc64: case ppc64le: case ppc: return "ppc"; @@ -88,7 +97,8 @@ const char *Triple::getArchTypePrefix(ArchType Kind) { case amdgcn: case r600: return "amdgpu"; - case bpf: return "bpf"; + case bpfel: + case bpfeb: return "bpf"; case sparcv9: case sparcel: @@ -116,6 +126,9 @@ const char *Triple::getArchTypePrefix(ArchType Kind) { case spir: case spir64: return "spir"; case kalimba: return "kalimba"; + case shave: return "shave"; + case wasm32: + case wasm64: return "wasm"; } } @@ -134,6 +147,7 @@ const char *Triple::getVendorTypeName(VendorType Kind) { case MipsTechnologies: return "mti"; case NVIDIA: return "nvidia"; case CSR: return "csr"; + case Myriad: return "myriad"; } llvm_unreachable("Invalid VendorType!"); @@ -167,6 +181,9 @@ const char *Triple::getOSTypeName(OSType Kind) { case NVCL: return "nvcl"; case AMDHSA: return "amdhsa"; case PS4: return "ps4"; + case ELFIAMCU: return "elfiamcu"; + case TvOS: return "tvos"; + case WatchOS: return "watchos"; } llvm_unreachable("Invalid OSType"); @@ -186,19 +203,38 @@ const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) { case MSVC: return "msvc"; case Itanium: return "itanium"; case Cygnus: return "cygnus"; + case AMDOpenCL: return "amdopencl"; + case CoreCLR: return "coreclr"; } llvm_unreachable("Invalid EnvironmentType!"); } +static Triple::ArchType parseBPFArch(StringRef ArchName) { + if (ArchName.equals("bpf")) { + if (sys::IsLittleEndianHost) + return Triple::bpfel; + else + return Triple::bpfeb; + } else if (ArchName.equals("bpf_be") || ArchName.equals("bpfeb")) { + return Triple::bpfeb; + } else if (ArchName.equals("bpf_le") || ArchName.equals("bpfel")) { + return Triple::bpfel; + } else { + return Triple::UnknownArch; + } +} + Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) { + Triple::ArchType BPFArch(parseBPFArch(Name)); return StringSwitch(Name) .Case("aarch64", aarch64) .Case("aarch64_be", aarch64_be) .Case("arm64", aarch64) // "arm64" is an alias for "aarch64" .Case("arm", arm) .Case("armeb", armeb) - .Case("bpf", bpf) + .Case("avr", avr) + .StartsWith("bpf", BPFArch) .Case("mips", mips) .Case("mipsel", mipsel) .Case("mips64", mips64) @@ -212,6 +248,7 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) { .Case("amdgcn", amdgcn) .Case("hexagon", hexagon) .Case("sparc", sparc) + .Case("sparcel", sparcel) .Case("sparcv9", sparcv9) .Case("systemz", systemz) .Case("tce", tce) @@ -231,66 +268,72 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) { .Case("spir", spir) .Case("spir64", spir64) .Case("kalimba", kalimba) + .Case("shave", shave) + .Case("wasm32", wasm32) + .Case("wasm64", wasm64) .Default(UnknownArch); } static Triple::ArchType parseARMArch(StringRef ArchName) { - size_t offset = StringRef::npos; + unsigned ISA = ARM::parseArchISA(ArchName); + unsigned ENDIAN = ARM::parseArchEndian(ArchName); + Triple::ArchType arch = Triple::UnknownArch; - bool isThumb = ArchName.startswith("thumb"); - - if (ArchName.equals("arm")) - return Triple::arm; - if (ArchName.equals("armeb")) - return Triple::armeb; - if (ArchName.equals("thumb")) - return Triple::thumb; - if (ArchName.equals("thumbeb")) - return Triple::thumbeb; - if (ArchName.equals("arm64") || ArchName.equals("aarch64")) - return Triple::aarch64; - if (ArchName.equals("aarch64_be")) - return Triple::aarch64_be; - - if (ArchName.startswith("armv")) { - offset = 3; - if (ArchName.endswith("eb")) { - arch = Triple::armeb; - ArchName = ArchName.substr(0, ArchName.size() - 2); - } else + switch (ENDIAN) { + case ARM::EK_LITTLE: { + switch (ISA) { + case ARM::IK_ARM: arch = Triple::arm; - } else if (ArchName.startswith("armebv")) { - offset = 5; - arch = Triple::armeb; - } else if (ArchName.startswith("thumbv")) { - offset = 5; - if (ArchName.endswith("eb")) { - arch = Triple::thumbeb; - ArchName = ArchName.substr(0, ArchName.size() - 2); - } else + break; + case ARM::IK_THUMB: arch = Triple::thumb; - } else if (ArchName.startswith("thumbebv")) { - offset = 7; - arch = Triple::thumbeb; + break; + case ARM::IK_AARCH64: + arch = Triple::aarch64; + break; + } + break; } - return StringSwitch(ArchName.substr(offset)) - .Cases("v2", "v2a", isThumb ? Triple::UnknownArch : arch) - .Cases("v3", "v3m", isThumb ? Triple::UnknownArch : arch) - .Cases("v4", "v4t", arch) - .Cases("v5", "v5e", "v5t", "v5te", "v5tej", arch) - .Cases("v6", "v6j", "v6k", "v6m", "v6sm", arch) - .Cases("v6t2", "v6z", "v6zk", arch) - .Cases("v7", "v7a", "v7em", "v7l", arch) - .Cases("v7m", "v7r", "v7s", arch) - .Cases("v8", "v8a", arch) - .Cases("v8.1", "v8.1a", arch) - .Default(Triple::UnknownArch); + case ARM::EK_BIG: { + switch (ISA) { + case ARM::IK_ARM: + arch = Triple::armeb; + break; + case ARM::IK_THUMB: + arch = Triple::thumbeb; + break; + case ARM::IK_AARCH64: + arch = Triple::aarch64_be; + break; + } + break; + } + } + + ArchName = ARM::getCanonicalArchName(ArchName); + if (ArchName.empty()) + return Triple::UnknownArch; + + // Thumb only exists in v4+ + if (ISA == ARM::IK_THUMB && + (ArchName.startswith("v2") || ArchName.startswith("v3"))) + return Triple::UnknownArch; + + // Thumb only for v6m + unsigned Profile = ARM::parseArchProfile(ArchName); + unsigned Version = ARM::parseArchVersion(ArchName); + if (Profile == ARM::PK_M && Version == 6) { + if (ENDIAN == ARM::EK_BIG) + return Triple::thumbeb; + else + return Triple::thumb; + } + + return arch; } static Triple::ArchType parseArch(StringRef ArchName) { - Triple::ArchType ARMArch(parseARMArch(ArchName)); - - return StringSwitch(ArchName) + auto AT = StringSwitch(ArchName) .Cases("i386", "i486", "i586", "i686", Triple::x86) // FIXME: Do we need to support these? .Cases("i786", "i886", "i986", Triple::x86) @@ -300,9 +343,14 @@ static Triple::ArchType parseArch(StringRef ArchName) { .Case("powerpc64le", Triple::ppc64le) .Case("xscale", Triple::arm) .Case("xscaleeb", Triple::armeb) - .StartsWith("arm", ARMArch) - .StartsWith("thumb", ARMArch) - .StartsWith("aarch64", ARMArch) + .Case("aarch64", Triple::aarch64) + .Case("aarch64_be", Triple::aarch64_be) + .Case("arm64", Triple::aarch64) + .Case("arm", Triple::arm) + .Case("armeb", Triple::armeb) + .Case("thumb", Triple::thumb) + .Case("thumbeb", Triple::thumbeb) + .Case("avr", Triple::avr) .Case("msp430", Triple::msp430) .Cases("mips", "mipseb", "mipsallegrex", Triple::mips) .Cases("mipsel", "mipsallegrexel", Triple::mipsel) @@ -310,7 +358,6 @@ static Triple::ArchType parseArch(StringRef ArchName) { .Case("mips64el", Triple::mips64el) .Case("r600", Triple::r600) .Case("amdgcn", Triple::amdgcn) - .Case("bpf", Triple::bpf) .Case("hexagon", Triple::hexagon) .Case("s390x", Triple::systemz) .Case("sparc", Triple::sparc) @@ -329,7 +376,22 @@ static Triple::ArchType parseArch(StringRef ArchName) { .Case("spir", Triple::spir) .Case("spir64", Triple::spir64) .StartsWith("kalimba", Triple::kalimba) + .Case("shave", Triple::shave) + .Case("wasm32", Triple::wasm32) + .Case("wasm64", Triple::wasm64) .Default(Triple::UnknownArch); + + // Some architectures require special parsing logic just to compute the + // ArchType result. + if (AT == Triple::UnknownArch) { + if (ArchName.startswith("arm") || ArchName.startswith("thumb") || + ArchName.startswith("aarch64")) + return parseARMArch(ArchName); + if (ArchName.startswith("bpf")) + return parseBPFArch(ArchName); + } + + return AT; } static Triple::VendorType parseVendor(StringRef VendorName) { @@ -345,6 +407,7 @@ static Triple::VendorType parseVendor(StringRef VendorName) { .Case("mti", Triple::MipsTechnologies) .Case("nvidia", Triple::NVIDIA) .Case("csr", Triple::CSR) + .Case("myriad", Triple::Myriad) .Default(Triple::UnknownVendor); } @@ -375,6 +438,9 @@ static Triple::OSType parseOS(StringRef OSName) { .StartsWith("nvcl", Triple::NVCL) .StartsWith("amdhsa", Triple::AMDHSA) .StartsWith("ps4", Triple::PS4) + .StartsWith("elfiamcu", Triple::ELFIAMCU) + .StartsWith("tvos", Triple::TvOS) + .StartsWith("watchos", Triple::WatchOS) .Default(Triple::UnknownOS); } @@ -391,6 +457,8 @@ static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) { .StartsWith("msvc", Triple::MSVC) .StartsWith("itanium", Triple::Itanium) .StartsWith("cygnus", Triple::Cygnus) + .StartsWith("amdopencl", Triple::AMDOpenCL) + .StartsWith("coreclr", Triple::CoreCLR) .Default(Triple::UnknownEnvironment); } @@ -403,34 +471,59 @@ static Triple::ObjectFormatType parseFormat(StringRef EnvironmentName) { } static Triple::SubArchType parseSubArch(StringRef SubArchName) { - if (SubArchName.endswith("eb")) - SubArchName = SubArchName.substr(0, SubArchName.size() - 2); - - return StringSwitch(SubArchName) - .EndsWith("v8.1a", Triple::ARMSubArch_v8_1a) - .EndsWith("v8", Triple::ARMSubArch_v8) - .EndsWith("v8a", Triple::ARMSubArch_v8) - .EndsWith("v7", Triple::ARMSubArch_v7) - .EndsWith("v7a", Triple::ARMSubArch_v7) - .EndsWith("v7em", Triple::ARMSubArch_v7em) - .EndsWith("v7l", Triple::ARMSubArch_v7) - .EndsWith("v7m", Triple::ARMSubArch_v7m) - .EndsWith("v7r", Triple::ARMSubArch_v7) - .EndsWith("v7s", Triple::ARMSubArch_v7s) - .EndsWith("v6", Triple::ARMSubArch_v6) - .EndsWith("v6m", Triple::ARMSubArch_v6m) - .EndsWith("v6sm", Triple::ARMSubArch_v6m) - .EndsWith("v6k", Triple::ARMSubArch_v6k) - .EndsWith("v6t2", Triple::ARMSubArch_v6t2) - .EndsWith("v5", Triple::ARMSubArch_v5) - .EndsWith("v5e", Triple::ARMSubArch_v5) - .EndsWith("v5t", Triple::ARMSubArch_v5) - .EndsWith("v5te", Triple::ARMSubArch_v5te) - .EndsWith("v4t", Triple::ARMSubArch_v4t) - .EndsWith("kalimba3", Triple::KalimbaSubArch_v3) - .EndsWith("kalimba4", Triple::KalimbaSubArch_v4) - .EndsWith("kalimba5", Triple::KalimbaSubArch_v5) - .Default(Triple::NoSubArch); + StringRef ARMSubArch = ARM::getCanonicalArchName(SubArchName); + + // For now, this is the small part. Early return. + if (ARMSubArch.empty()) + return StringSwitch(SubArchName) + .EndsWith("kalimba3", Triple::KalimbaSubArch_v3) + .EndsWith("kalimba4", Triple::KalimbaSubArch_v4) + .EndsWith("kalimba5", Triple::KalimbaSubArch_v5) + .Default(Triple::NoSubArch); + + // ARM sub arch. + switch(ARM::parseArch(ARMSubArch)) { + case ARM::AK_ARMV4: + return Triple::NoSubArch; + case ARM::AK_ARMV4T: + return Triple::ARMSubArch_v4t; + case ARM::AK_ARMV5T: + return Triple::ARMSubArch_v5; + case ARM::AK_ARMV5TE: + case ARM::AK_IWMMXT: + case ARM::AK_IWMMXT2: + case ARM::AK_XSCALE: + case ARM::AK_ARMV5TEJ: + return Triple::ARMSubArch_v5te; + case ARM::AK_ARMV6: + return Triple::ARMSubArch_v6; + case ARM::AK_ARMV6K: + case ARM::AK_ARMV6KZ: + return Triple::ARMSubArch_v6k; + case ARM::AK_ARMV6T2: + return Triple::ARMSubArch_v6t2; + case ARM::AK_ARMV6M: + return Triple::ARMSubArch_v6m; + case ARM::AK_ARMV7A: + case ARM::AK_ARMV7R: + return Triple::ARMSubArch_v7; + case ARM::AK_ARMV7K: + return Triple::ARMSubArch_v7k; + case ARM::AK_ARMV7M: + return Triple::ARMSubArch_v7m; + case ARM::AK_ARMV7S: + return Triple::ARMSubArch_v7s; + case ARM::AK_ARMV7EM: + return Triple::ARMSubArch_v7em; + case ARM::AK_ARMV8A: + return Triple::ARMSubArch_v8; + case ARM::AK_ARMV8_1A: + return Triple::ARMSubArch_v8_1a; + case ARM::AK_ARMV8_2A: + return Triple::ARMSubArch_v8_2a; + default: + return Triple::NoSubArch; + } } static const char *getObjectFormatTypeName(Triple::ObjectFormatType Kind) { @@ -466,6 +559,11 @@ static Triple::ObjectFormatType getDefaultFormat(const Triple &T) { if (T.isOSDarwin()) return Triple::MachO; return Triple::ELF; + + case Triple::wasm32: + case Triple::wasm64: + // Unknown for now, until an object format is specified. + return Triple::UnknownObjectFormat; } if (T.isOSDarwin()) @@ -480,14 +578,27 @@ static Triple::ObjectFormatType getDefaultFormat(const Triple &T) { /// This stores the string representation and parses the various pieces into /// enum members. Triple::Triple(const Twine &Str) - : Data(Str.str()), - Arch(parseArch(getArchName())), - SubArch(parseSubArch(getArchName())), - Vendor(parseVendor(getVendorName())), - OS(parseOS(getOSName())), - Environment(parseEnvironment(getEnvironmentName())), - ObjectFormat(parseFormat(getEnvironmentName())) { - if (ObjectFormat == Triple::UnknownObjectFormat) + : Data(Str.str()), Arch(UnknownArch), SubArch(NoSubArch), + Vendor(UnknownVendor), OS(UnknownOS), Environment(UnknownEnvironment), + ObjectFormat(UnknownObjectFormat) { + // Do minimal parsing by hand here. + SmallVector Components; + StringRef(Data).split(Components, '-', /*MaxSplit*/ 3); + if (Components.size() > 0) { + Arch = parseArch(Components[0]); + SubArch = parseSubArch(Components[0]); + if (Components.size() > 1) { + Vendor = parseVendor(Components[1]); + if (Components.size() > 2) { + OS = parseOS(Components[2]); + if (Components.size() > 3) { + Environment = parseEnvironment(Components[3]); + ObjectFormat = parseFormat(Components[3]); + } + } + } + } + if (ObjectFormat == UnknownObjectFormat) ObjectFormat = getDefaultFormat(*this); } @@ -532,7 +643,7 @@ std::string Triple::normalize(StringRef Str) { // Parse into components. SmallVector Components; - Str.split(Components, "-"); + Str.split(Components, '-'); // If the first component corresponds to a known architecture, preferentially // use it for the architecture. If the second component corresponds to a @@ -665,6 +776,16 @@ std::string Triple::normalize(StringRef Str) { // Special case logic goes here. At this point Arch, Vendor and OS have the // correct values for the computed components. + std::string NormalizedEnvironment; + if (Environment == Triple::Android && Components[3].startswith("androideabi")) { + StringRef AndroidVersion = Components[3].drop_front(strlen("androideabi")); + if (AndroidVersion.empty()) { + Components[3] = "android"; + } else { + NormalizedEnvironment = Twine("android", AndroidVersion).str(); + Components[3] = NormalizedEnvironment; + } + } if (OS == Triple::Win32) { Components.resize(4); @@ -742,41 +863,47 @@ static unsigned EatNumber(StringRef &Str) { return Result; } -void Triple::getOSVersion(unsigned &Major, unsigned &Minor, - unsigned &Micro) const { - StringRef OSName = getOSName(); - - // For Android, we care about the Android version rather than the Linux - // version. - if (getEnvironment() == Android) { - OSName = getEnvironmentName().substr(strlen("android")); - if (OSName.startswith("eabi")) - OSName = OSName.substr(strlen("eabi")); - } - - // Assume that the OS portion of the triple starts with the canonical name. - StringRef OSTypeName = getOSTypeName(getOS()); - if (OSName.startswith(OSTypeName)) - OSName = OSName.substr(OSTypeName.size()); - +static void parseVersionFromName(StringRef Name, unsigned &Major, + unsigned &Minor, unsigned &Micro) { // Any unset version defaults to 0. Major = Minor = Micro = 0; // Parse up to three components. - unsigned *Components[3] = { &Major, &Minor, &Micro }; + unsigned *Components[3] = {&Major, &Minor, &Micro}; for (unsigned i = 0; i != 3; ++i) { - if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9') + if (Name.empty() || Name[0] < '0' || Name[0] > '9') break; // Consume the leading number. - *Components[i] = EatNumber(OSName); + *Components[i] = EatNumber(Name); // Consume the separator, if present. - if (OSName.startswith(".")) - OSName = OSName.substr(1); + if (Name.startswith(".")) + Name = Name.substr(1); } } +void Triple::getEnvironmentVersion(unsigned &Major, unsigned &Minor, + unsigned &Micro) const { + StringRef EnvironmentName = getEnvironmentName(); + StringRef EnvironmentTypeName = getEnvironmentTypeName(getEnvironment()); + if (EnvironmentName.startswith(EnvironmentTypeName)) + EnvironmentName = EnvironmentName.substr(EnvironmentTypeName.size()); + + parseVersionFromName(EnvironmentName, Major, Minor, Micro); +} + +void Triple::getOSVersion(unsigned &Major, unsigned &Minor, + unsigned &Micro) const { + StringRef OSName = getOSName(); + // Assume that the OS portion of the triple starts with the canonical name. + StringRef OSTypeName = getOSTypeName(getOS()); + if (OSName.startswith(OSTypeName)) + OSName = OSName.substr(OSTypeName.size()); + + parseVersionFromName(OSName, Major, Minor, Micro); +} + bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor, unsigned &Micro) const { getOSVersion(Major, Minor, Micro); @@ -804,6 +931,8 @@ bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor, return false; break; case IOS: + case TvOS: + case WatchOS: // Ignore the version from the triple. This is only handled because the // the clang driver combines OS X and IOS support into a common Darwin // toolchain that wants to know the OS X version number even when targeting @@ -831,11 +960,38 @@ void Triple::getiOSVersion(unsigned &Major, unsigned &Minor, Micro = 0; break; case IOS: + case TvOS: getOSVersion(Major, Minor, Micro); // Default to 5.0 (or 7.0 for arm64). if (Major == 0) Major = (getArch() == aarch64) ? 7 : 5; break; + case WatchOS: + llvm_unreachable("conflicting triple info"); + } +} + +void Triple::getWatchOSVersion(unsigned &Major, unsigned &Minor, + unsigned &Micro) const { + switch (getOS()) { + default: llvm_unreachable("unexpected OS for Darwin triple"); + case Darwin: + case MacOSX: + // Ignore the version from the triple. This is only handled because the + // the clang driver combines OS X and IOS support into a common Darwin + // toolchain that wants to know the iOS version number even when targeting + // OS X. + Major = 2; + Minor = 0; + Micro = 0; + break; + case WatchOS: + getOSVersion(Major, Minor, Micro); + if (Major == 0) + Major = 2; + break; + case IOS: + llvm_unreachable("conflicting triple info"); } } @@ -908,6 +1064,7 @@ static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) { case llvm::Triple::UnknownArch: return 0; + case llvm::Triple::avr: case llvm::Triple::msp430: return 16; @@ -931,12 +1088,15 @@ static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) { case llvm::Triple::hsail: case llvm::Triple::spir: case llvm::Triple::kalimba: + case llvm::Triple::shave: + case llvm::Triple::wasm32: return 32; case llvm::Triple::aarch64: case llvm::Triple::aarch64_be: case llvm::Triple::amdgcn: - case llvm::Triple::bpf: + case llvm::Triple::bpfel: + case llvm::Triple::bpfeb: case llvm::Triple::le64: case llvm::Triple::mips64: case llvm::Triple::mips64el: @@ -949,6 +1109,7 @@ static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) { case llvm::Triple::amdil64: case llvm::Triple::hsail64: case llvm::Triple::spir64: + case llvm::Triple::wasm64: return 64; } llvm_unreachable("Invalid architecture value"); @@ -973,7 +1134,9 @@ Triple Triple::get32BitArchVariant() const { case Triple::aarch64: case Triple::aarch64_be: case Triple::amdgcn: - case Triple::bpf: + case Triple::avr: + case Triple::bpfel: + case Triple::bpfeb: case Triple::msp430: case Triple::systemz: case Triple::ppc64le: @@ -1000,6 +1163,8 @@ Triple Triple::get32BitArchVariant() const { case Triple::thumbeb: case Triple::x86: case Triple::xcore: + case Triple::shave: + case Triple::wasm32: // Already 32-bit. break; @@ -1013,6 +1178,7 @@ Triple Triple::get32BitArchVariant() const { case Triple::amdil64: T.setArch(Triple::amdil); break; case Triple::hsail64: T.setArch(Triple::hsail); break; case Triple::spir64: T.setArch(Triple::spir); break; + case Triple::wasm64: T.setArch(Triple::wasm32); break; } return T; } @@ -1023,6 +1189,7 @@ Triple Triple::get64BitArchVariant() const { case Triple::UnknownArch: case Triple::arm: case Triple::armeb: + case Triple::avr: case Triple::hexagon: case Triple::kalimba: case Triple::msp430: @@ -1032,12 +1199,14 @@ Triple Triple::get64BitArchVariant() const { case Triple::thumbeb: case Triple::xcore: case Triple::sparcel: + case Triple::shave: T.setArch(UnknownArch); break; case Triple::aarch64: case Triple::aarch64_be: - case Triple::bpf: + case Triple::bpfel: + case Triple::bpfeb: case Triple::le64: case Triple::amdil64: case Triple::amdgcn: @@ -1051,6 +1220,7 @@ Triple Triple::get64BitArchVariant() const { case Triple::sparcv9: case Triple::systemz: case Triple::x86_64: + case Triple::wasm64: // Already 64-bit. break; @@ -1064,74 +1234,163 @@ Triple Triple::get64BitArchVariant() const { case Triple::amdil: T.setArch(Triple::amdil64); break; case Triple::hsail: T.setArch(Triple::hsail64); break; case Triple::spir: T.setArch(Triple::spir64); break; + case Triple::wasm32: T.setArch(Triple::wasm64); break; } return T; } -// FIXME: tblgen this. -const char *Triple::getARMCPUForArch(StringRef MArch) const { +Triple Triple::getBigEndianArchVariant() const { + Triple T(*this); + switch (getArch()) { + case Triple::UnknownArch: + case Triple::amdgcn: + case Triple::amdil64: + case Triple::amdil: + case Triple::avr: + case Triple::hexagon: + case Triple::hsail64: + case Triple::hsail: + case Triple::kalimba: + case Triple::le32: + case Triple::le64: + case Triple::msp430: + case Triple::nvptx64: + case Triple::nvptx: + case Triple::r600: + case Triple::shave: + case Triple::spir64: + case Triple::spir: + case Triple::wasm32: + case Triple::wasm64: + case Triple::x86: + case Triple::x86_64: + case Triple::xcore: + + // ARM is intentionally unsupported here, changing the architecture would + // drop any arch suffixes. + case Triple::arm: + case Triple::thumb: + T.setArch(UnknownArch); + break; + + case Triple::aarch64_be: + case Triple::armeb: + case Triple::bpfeb: + case Triple::mips64: + case Triple::mips: + case Triple::ppc64: + case Triple::ppc: + case Triple::sparc: + case Triple::sparcv9: + case Triple::systemz: + case Triple::tce: + case Triple::thumbeb: + // Already big endian. + break; + + case Triple::aarch64: T.setArch(Triple::aarch64_be); break; + case Triple::bpfel: T.setArch(Triple::bpfeb); break; + case Triple::mips64el:T.setArch(Triple::mips64); break; + case Triple::mipsel: T.setArch(Triple::mips); break; + case Triple::ppc64le: T.setArch(Triple::ppc64); break; + case Triple::sparcel: T.setArch(Triple::sparc); break; + } + return T; +} + +Triple Triple::getLittleEndianArchVariant() const { + Triple T(*this); + switch (getArch()) { + case Triple::UnknownArch: + case Triple::ppc: + case Triple::sparcv9: + case Triple::systemz: + case Triple::tce: + + // ARM is intentionally unsupported here, changing the architecture would + // drop any arch suffixes. + case Triple::armeb: + case Triple::thumbeb: + T.setArch(UnknownArch); + break; + + case Triple::aarch64: + case Triple::amdgcn: + case Triple::amdil64: + case Triple::amdil: + case Triple::arm: + case Triple::avr: + case Triple::bpfel: + case Triple::hexagon: + case Triple::hsail64: + case Triple::hsail: + case Triple::kalimba: + case Triple::le32: + case Triple::le64: + case Triple::mips64el: + case Triple::mipsel: + case Triple::msp430: + case Triple::nvptx64: + case Triple::nvptx: + case Triple::ppc64le: + case Triple::r600: + case Triple::shave: + case Triple::sparcel: + case Triple::spir64: + case Triple::spir: + case Triple::thumb: + case Triple::wasm32: + case Triple::wasm64: + case Triple::x86: + case Triple::x86_64: + case Triple::xcore: + // Already little endian. + break; + + case Triple::aarch64_be: T.setArch(Triple::aarch64); break; + case Triple::bpfeb: T.setArch(Triple::bpfel); break; + case Triple::mips64: T.setArch(Triple::mips64el); break; + case Triple::mips: T.setArch(Triple::mipsel); break; + case Triple::ppc64: T.setArch(Triple::ppc64le); break; + case Triple::sparc: T.setArch(Triple::sparcel); break; + } + return T; +} + +StringRef Triple::getARMCPUForArch(StringRef MArch) const { if (MArch.empty()) MArch = getArchName(); + MArch = ARM::getCanonicalArchName(MArch); + // Some defaults are forced. switch (getOS()) { case llvm::Triple::FreeBSD: case llvm::Triple::NetBSD: - if (MArch == "armv6") + if (!MArch.empty() && MArch == "v6") return "arm1176jzf-s"; break; case llvm::Triple::Win32: // FIXME: this is invalid for WindowsCE return "cortex-a9"; + case llvm::Triple::MacOSX: + case llvm::Triple::IOS: + case llvm::Triple::WatchOS: + if (MArch == "v7k") + return "cortex-a7"; + break; default: break; } - const char *result = nullptr; - size_t offset = StringRef::npos; - if (MArch.startswith("arm")) - offset = 3; - if (MArch.startswith("thumb")) - offset = 5; - if (offset != StringRef::npos && MArch.substr(offset, 2) == "eb") - offset += 2; - if (MArch.endswith("eb")) - MArch = MArch.substr(0, MArch.size() - 2); - if (offset != StringRef::npos) - result = llvm::StringSwitch(MArch.substr(offset)) - .Cases("v2", "v2a", "arm2") - .Case("v3", "arm6") - .Case("v3m", "arm7m") - .Case("v4", "strongarm") - .Case("v4t", "arm7tdmi") - .Cases("v5", "v5t", "arm10tdmi") - .Cases("v5e", "v5te", "arm1022e") - .Case("v5tej", "arm926ej-s") - .Case("v6", "arm1136jf-s") - .Case("v6j", "arm1136j-s") - .Cases("v6k", "v6z", "v6zk", "arm1176jzf-s") - .Case("v6t2", "arm1156t2-s") - .Cases("v6m", "v6-m", "v6sm", "v6s-m", "cortex-m0") - .Cases("v7", "v7a", "v7-a", "v7l", "v7-l", "cortex-a8") - .Cases("v7s", "v7-s", "swift") - .Cases("v7r", "v7-r", "cortex-r4") - .Cases("v7m", "v7-m", "cortex-m3") - .Cases("v7em", "v7e-m", "cortex-m4") - .Cases("v8", "v8a", "v8-a", "cortex-a53") - .Cases("v8.1a", "v8.1-a", "generic") - .Default(nullptr); - else - result = llvm::StringSwitch(MArch) - .Case("ep9312", "ep9312") - .Case("iwmmxt", "iwmmxt") - .Case("xscale", "xscale") - .Default(nullptr); - - if (result) - return result; - - // If all else failed, return the most base CPU with thumb interworking - // supported by LLVM. - // FIXME: Should warn once that we're falling back. + if (MArch.empty()) + return StringRef(); + + StringRef CPU = ARM::getDefaultCPU(MArch); + if (!CPU.empty()) + return CPU; + + // If no specific architecture version is requested, return the minimum CPU + // required by the OS and environment. switch (getOS()) { case llvm::Triple::NetBSD: switch (getEnvironment()) { @@ -1154,4 +1413,6 @@ const char *Triple::getARMCPUForArch(StringRef MArch) const { return "arm7tdmi"; } } + + llvm_unreachable("invalid arch name"); }