aboutsummaryrefslogtreecommitdiff
path: root/source/Core/ArchSpec.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Core/ArchSpec.cpp')
-rw-r--r--source/Core/ArchSpec.cpp174
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()
+ );
+}