diff options
Diffstat (limited to 'source/Core/ArchSpec.cpp')
-rw-r--r-- | source/Core/ArchSpec.cpp | 174 |
1 files changed, 118 insertions, 56 deletions
diff --git a/source/Core/ArchSpec.cpp b/source/Core/ArchSpec.cpp index 2dc001a9047f..ffe717f29c43 100644 --- a/source/Core/ArchSpec.cpp +++ b/source/Core/ArchSpec.cpp @@ -419,8 +419,8 @@ ArchSpec::ArchSpec() : m_triple (), m_core (kCore_invalid), m_byte_order (eByteOrderInvalid), - m_distribution_id (), - m_flags (0) + m_flags (0), + m_distribution_id () { } @@ -428,8 +428,8 @@ ArchSpec::ArchSpec (const char *triple_cstr, Platform *platform) : m_triple (), m_core (kCore_invalid), m_byte_order (eByteOrderInvalid), - m_distribution_id (), - m_flags (0) + m_flags (0), + m_distribution_id () { if (triple_cstr) SetTriple(triple_cstr, platform); @@ -440,8 +440,8 @@ ArchSpec::ArchSpec (const char *triple_cstr) : m_triple (), m_core (kCore_invalid), m_byte_order (eByteOrderInvalid), - m_distribution_id (), - m_flags (0) + m_flags (0), + m_distribution_id () { if (triple_cstr) SetTriple(triple_cstr); @@ -451,8 +451,8 @@ ArchSpec::ArchSpec(const llvm::Triple &triple) : m_triple (), m_core (kCore_invalid), m_byte_order (eByteOrderInvalid), - m_distribution_id (), - m_flags (0) + m_flags (0), + m_distribution_id () { SetTriple(triple); } @@ -461,8 +461,8 @@ ArchSpec::ArchSpec (ArchitectureType arch_type, uint32_t cpu, uint32_t subtype) m_triple (), m_core (kCore_invalid), m_byte_order (eByteOrderInvalid), - m_distribution_id (), - m_flags (0) + m_flags (0), + m_distribution_id () { SetArchitecture (arch_type, cpu, subtype); } @@ -602,7 +602,15 @@ ArchSpec::GetAddressByteSize() const { const CoreDefinition *core_def = FindCoreDefinition (m_core); if (core_def) - return core_def->addr_byte_size; + { + if (core_def->machine == llvm::Triple::mips64 || core_def->machine == llvm::Triple::mips64el) + { + // For N32/O32 applications Address size is 4 bytes. + if (m_flags & (eMIPSABI_N32 | eMIPSABI_O32)) + return 4; + } + return core_def->addr_byte_size; + } return 0; } @@ -836,14 +844,17 @@ ArchSpec::SetTriple (const char *triple_cstr, Platform *platform) void ArchSpec::MergeFrom(const ArchSpec &other) { - if (GetTriple().getVendor() == llvm::Triple::UnknownVendor && !TripleVendorWasSpecified()) + if (TripleVendorIsUnspecifiedUnknown() && !other.TripleVendorIsUnspecifiedUnknown()) GetTriple().setVendor(other.GetTriple().getVendor()); - if (GetTriple().getOS() == llvm::Triple::UnknownOS && !TripleOSWasSpecified()) + if (TripleOSIsUnspecifiedUnknown() && !other.TripleOSIsUnspecifiedUnknown()) GetTriple().setOS(other.GetTriple().getOS()); if (GetTriple().getArch() == llvm::Triple::UnknownArch) GetTriple().setArch(other.GetTriple().getArch()); - if (GetTriple().getEnvironment() == llvm::Triple::UnknownEnvironment) - GetTriple().setEnvironment(other.GetTriple().getEnvironment()); + if (GetTriple().getEnvironment() == llvm::Triple::UnknownEnvironment && !TripleVendorWasSpecified()) + { + if (other.TripleVendorWasSpecified()) + GetTriple().setEnvironment(other.GetTriple().getEnvironment()); + } } bool @@ -868,29 +879,14 @@ ArchSpec::SetArchitecture (ArchitectureType arch_type, uint32_t cpu, uint32_t su if (arch_type == eArchTypeMachO) { m_triple.setVendor (llvm::Triple::Apple); - switch (core_def->machine) - { - case llvm::Triple::aarch64: - case llvm::Triple::arm: - case llvm::Triple::thumb: - m_triple.setOS (llvm::Triple::IOS); - break; - - case llvm::Triple::x86: - case llvm::Triple::x86_64: - // Don't set the OS for x86_64 or for x86 as we want to leave it as an "unspecified unknown" - // which means if we ask for the OS from the llvm::Triple we get back llvm::Triple::UnknownOS, but - // if we ask for the string value for the OS it will come back empty (unspecified). - // We do this because we now have iOS and MacOSX as the OS values for x86 and x86_64 for - // normal desktop and simulator binaries. And if we compare a "x86_64-apple-ios" to a "x86_64-apple-" - // triple, it will say it is compatible (because the OS is unspecified in the second one and will match - // anything in the first - break; - - default: - m_triple.setOS (llvm::Triple::MacOSX); - break; - } + + // Don't set the OS. It could be simulator, macosx, ios, watchos, tvos. We could + // get close with the cpu type - but we can't get it right all of the time. Better + // to leave this unset so other sections of code will set it when they have more + // information. + // NB: don't call m_triple.setOS (llvm::Triple::UnknownOS). That sets the OSName to + // "unknown" and the ArchSpec::TripleVendorWasSpecified() method says that any + // OSName setting means it was specified. } else if (arch_type == eArchTypeELF) { @@ -904,6 +900,11 @@ ArchSpec::SetArchitecture (ArchitectureType arch_type, uint32_t cpu, uint32_t su case llvm::ELF::ELFOSABI_SOLARIS: m_triple.setOS (llvm::Triple::OSType::Solaris); break; } } + else + { + m_triple.setVendor (llvm::Triple::UnknownVendor); + m_triple.setOS (llvm::Triple::UnknownOS); + } // Fall back onto setting the machine type if the arch by name failed... if (m_triple.getArch () == llvm::Triple::UnknownArch) m_triple.setArch (core_def->machine); @@ -966,15 +967,12 @@ ArchSpec::IsEqualTo (const ArchSpec& rhs, bool exact_match) const const llvm::Triple::VendorType rhs_triple_vendor = rhs_triple.getVendor(); if (lhs_triple_vendor != rhs_triple_vendor) { - if (exact_match) - { - const bool rhs_vendor_specified = rhs.TripleVendorWasSpecified(); - const bool lhs_vendor_specified = TripleVendorWasSpecified(); - // Both architectures had the vendor specified, so if they aren't - // equal then we return false - if (rhs_vendor_specified && lhs_vendor_specified) - return false; - } + const bool rhs_vendor_specified = rhs.TripleVendorWasSpecified(); + const bool lhs_vendor_specified = TripleVendorWasSpecified(); + // Both architectures had the vendor specified, so if they aren't + // equal then we return false + if (rhs_vendor_specified && lhs_vendor_specified) + return false; // Only fail if both vendor types are not unknown if (lhs_triple_vendor != llvm::Triple::UnknownVendor && @@ -986,15 +984,12 @@ ArchSpec::IsEqualTo (const ArchSpec& rhs, bool exact_match) const const llvm::Triple::OSType rhs_triple_os = rhs_triple.getOS(); if (lhs_triple_os != rhs_triple_os) { - if (exact_match) - { - const bool rhs_os_specified = rhs.TripleOSWasSpecified(); - const bool lhs_os_specified = TripleOSWasSpecified(); - // Both architectures had the OS specified, so if they aren't - // equal then we return false - if (rhs_os_specified && lhs_os_specified) - return false; - } + const bool rhs_os_specified = rhs.TripleOSWasSpecified(); + const bool lhs_os_specified = TripleOSWasSpecified(); + // Both architectures had the OS specified, so if they aren't + // equal then we return false + if (rhs_os_specified && lhs_os_specified) + return false; // Only fail if both os types are not unknown if (lhs_triple_os != llvm::Triple::UnknownOS && @@ -1103,6 +1098,10 @@ cores_match (const ArchSpec::Core core1, const ArchSpec::Core core2, bool try_in return true; break; + // v. https://en.wikipedia.org/wiki/ARM_Cortex-M#Silicon_customization + // Cortex-M0 - ARMv6-M - armv6m + // Cortex-M3 - ARMv7-M - armv7m + // Cortex-M4 - ARMv7E-M - armv7em case ArchSpec::eCore_arm_armv7em: if (!enforce_exact_match) { @@ -1118,6 +1117,10 @@ cores_match (const ArchSpec::Core core1, const ArchSpec::Core core2, bool try_in } break; + // v. https://en.wikipedia.org/wiki/ARM_Cortex-M#Silicon_customization + // Cortex-M0 - ARMv6-M - armv6m + // Cortex-M3 - ARMv7-M - armv7m + // Cortex-M4 - ARMv7E-M - armv7em case ArchSpec::eCore_arm_armv7m: if (!enforce_exact_match) { @@ -1428,3 +1431,62 @@ ArchSpec::GetStopInfoOverrideCallback () const return StopInfoOverrideCallbackTypeARM; return NULL; } + +bool +ArchSpec::IsFullySpecifiedTriple () const +{ + const auto& user_specified_triple = GetTriple(); + + bool user_triple_fully_specified = false; + + if ((user_specified_triple.getOS() != llvm::Triple::UnknownOS) || TripleOSWasSpecified()) + { + if ((user_specified_triple.getVendor() != llvm::Triple::UnknownVendor) || TripleVendorWasSpecified()) + { + const unsigned unspecified = 0; + if (user_specified_triple.getOSMajorVersion() != unspecified) + { + user_triple_fully_specified = true; + } + } + } + + return user_triple_fully_specified; +} + +void +ArchSpec::PiecewiseTripleCompare (const ArchSpec &other, + bool &arch_different, + bool &vendor_different, + bool &os_different, + bool &os_version_different, + bool &env_different) +{ + const llvm::Triple &me(GetTriple()); + const llvm::Triple &them(other.GetTriple()); + + arch_different = (me.getArch() != them.getArch()); + + vendor_different = (me.getVendor() != them.getVendor()); + + os_different = (me.getOS() != them.getOS()); + + os_version_different = (me.getOSMajorVersion() != them.getOSMajorVersion()); + + env_different = (me.getEnvironment() != them.getEnvironment()); +} + +void +ArchSpec::DumpTriple(Stream &s) const +{ + const llvm::Triple &triple = GetTriple(); + llvm::StringRef arch_str = triple.getArchName(); + llvm::StringRef vendor_str = triple.getVendorName(); + llvm::StringRef os_str = triple.getOSName(); + + s.Printf("%s-%s-%s", + arch_str.empty() ? "*" : arch_str.str().c_str(), + vendor_str.empty() ? "*" : vendor_str.str().c_str(), + os_str.empty() ? "*" : os_str.str().c_str() + ); +} |