[Lldb-commits] [lldb] r265377 - Consolidate the knowledge of what arm cores are always executing

Jason Molenda via lldb-commits lldb-commits at lists.llvm.org
Mon Apr 4 22:01:32 PDT 2016


Author: jmolenda
Date: Tue Apr  5 00:01:30 2016
New Revision: 265377

URL: http://llvm.org/viewvc/llvm-project?rev=265377&view=rev
Log:
Consolidate the knowledge of what arm cores are always executing
in thumb mode into one method in ArchSpec, replace checks for
specific cores in the disassembler with calls to this.  Also call
this from the arm instruction emulation code.

The determination of whether a given ArchSpec is thumb-only is still
a bit of a hack, but at least the hack is consolidated into a single
place.  In my original version of this patch http://reviews.llvm.org/D13578
I was calling into llvm's feature arm feature tables to make this
determination, like

#include "llvm/Support/TargetRegistry.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/../../lib/Target/ARM/ARMGenRegisterInfo.inc"
#include "llvm/../../lib/Target/ARM/ARMFeatures.h"

[...]

        std::string triple (GetTriple().getTriple());
        const char *cpu = "";
        const char *features_str = "";
        const llvm::Target *curr_target = llvm::TargetRegistry::lookupTarget(triple.c_str(), Error);
        std::unique_ptr<llvm::MCSubtargetInfo> subtarget_info_up (curr_target->createMCSubtargetInfo(triple.c_str(), cpu, features_str));
        if (subtarget_info_up->getFeatureBits()[llvm::ARM::FeatureNoARM])
        {
            return true;
        }

but those tables are post-llvm-build generated and linking against them
for all of our different build system methods was a big hiccup that I
haven't had time to revisit convincingly.

I'll keep that reviews.llvm.org patch around to remind myself that I
need to take another run at linking against the necessary tables 
again in llvm.

<rdar://problem/23022803> 


Modified:
    lldb/trunk/include/lldb/Core/ArchSpec.h
    lldb/trunk/source/Core/ArchSpec.cpp
    lldb/trunk/source/Core/Disassembler.cpp
    lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
    lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp

Modified: lldb/trunk/include/lldb/Core/ArchSpec.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ArchSpec.h?rev=265377&r1=265376&r2=265377&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ArchSpec.h (original)
+++ lldb/trunk/include/lldb/Core/ArchSpec.h Tue Apr  5 00:01:30 2016
@@ -622,6 +622,22 @@ public:
                             bool &os_version_different,
                             bool &env_different);
     
+    //------------------------------------------------------------------
+    /// Detect whether this architecture uses thumb code exclusively
+    ///
+    /// Some embedded ARM chips (e.g. the ARM Cortex M0-7 line) can
+    /// only execute the Thumb instructions, never Arm.  We should normally
+    /// pick up arm/thumbness from their the processor status bits (cpsr/xpsr)
+    /// or hints on each function - but when doing bare-boards low level
+    /// debugging (especially common with these embedded processors), we may
+    /// not have those things easily accessible.
+    ///
+    /// @return true if this is an arm ArchSpec which can only execute Thumb
+    ///         instructions
+    //------------------------------------------------------------------
+    bool
+    IsAlwaysThumbInstructions () const;
+
     uint32_t
     GetFlags () const
     {

Modified: lldb/trunk/source/Core/ArchSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ArchSpec.cpp?rev=265377&r1=265376&r2=265377&view=diff
==============================================================================
--- lldb/trunk/source/Core/ArchSpec.cpp (original)
+++ lldb/trunk/source/Core/ArchSpec.cpp Tue Apr  5 00:01:30 2016
@@ -898,6 +898,17 @@ ArchSpec::MergeFrom(const ArchSpec &othe
         if (other.TripleVendorWasSpecified())
             GetTriple().setEnvironment(other.GetTriple().getEnvironment());
     }
+    // If this and other are both arm ArchSpecs and this ArchSpec is a generic "some kind of arm"
+    // spec but the other ArchSpec is a specific arm core, adopt the specific arm core.
+    if (GetTriple().getArch() == llvm::Triple::arm
+        && other.GetTriple().getArch() == llvm::Triple::arm
+        && IsCompatibleMatch (other)
+        && GetCore() == ArchSpec::eCore_arm_generic
+        && other.GetCore() != ArchSpec::eCore_arm_generic)
+    {
+        m_core = other.GetCore();
+        CoreUpdated (true);
+    }
 }
 
 bool
@@ -1522,6 +1533,31 @@ ArchSpec::PiecewiseTripleCompare (const
     env_different = (me.getEnvironment() != them.getEnvironment());
 }
 
+bool
+ArchSpec::IsAlwaysThumbInstructions () const
+{
+    std::string Error;
+    if (GetTriple().getArch() == llvm::Triple::arm || GetTriple().getArch() == llvm::Triple::thumb)
+    {
+        // v. https://en.wikipedia.org/wiki/ARM_Cortex-M
+        //
+        // Cortex-M0 through Cortex-M7 are ARM processor cores which can only
+        // execute thumb instructions.  We map the cores to arch names like this:
+        //
+        // Cortex-M0, Cortex-M0+, Cortex-M1:  armv6m
+        // Cortex-M3: armv7m
+        // Cortex-M4, Cortex-M7: armv7em
+
+        if (GetCore() == ArchSpec::Core::eCore_arm_armv7m
+            || GetCore() == ArchSpec::Core::eCore_arm_armv7em
+            || GetCore() == ArchSpec::Core::eCore_arm_armv6m)
+        {
+            return true;
+        }
+    }
+    return false;
+}
+
 void
 ArchSpec::DumpTriple(Stream &s) const
 {

Modified: lldb/trunk/source/Core/Disassembler.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Disassembler.cpp?rev=265377&r1=265376&r2=265377&view=diff
==============================================================================
--- lldb/trunk/source/Core/Disassembler.cpp (original)
+++ lldb/trunk/source/Core/Disassembler.cpp Tue Apr  5 00:01:30 2016
@@ -1236,10 +1236,7 @@ Disassembler::Disassembler(const ArchSpe
     // If this is an arm variant that can only include thumb (T16, T32)
     // instructions, force the arch triple to be "thumbv.." instead of
     // "armv..."
-    if ((arch.GetTriple().getArch() == llvm::Triple::arm || arch.GetTriple().getArch() == llvm::Triple::thumb)
-        && (arch.GetCore() == ArchSpec::Core::eCore_arm_armv7m
-            || arch.GetCore() == ArchSpec::Core::eCore_arm_armv7em
-            || arch.GetCore() == ArchSpec::Core::eCore_arm_armv6m))
+    if (arch.IsAlwaysThumbInstructions())
     {
         std::string thumb_arch_name (arch.GetTriple().getArchName().str());
         // Replace "arm" with "thumb" so we get all thumb variants correct

Modified: lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp?rev=265377&r1=265376&r2=265377&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp (original)
+++ lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp Tue Apr  5 00:01:30 2016
@@ -647,18 +647,8 @@ DisassemblerLLVMC::DisassemblerLLVMC (co
 
     const char *triple_str = triple.getTriple().c_str();
 
-    // v. https://en.wikipedia.org/wiki/ARM_Cortex-M#Silicon_customization
-    // 
-    // Cortex-M3 devices (e.g. armv7m) can only execute thumb (T2) instructions,
-    // so hardcode the primary disassembler to thumb mode.  Same for Cortex-M4 (armv7em).
-    //
-    // Handle the Cortex-M0 (armv6m) the same; the ISA is a subset of the T and T32
-    // instructions defined in ARMv7-A.
-
-    if ((triple.getArch() == llvm::Triple::arm || triple.getArch() == llvm::Triple::thumb)
-        && (arch.GetCore() == ArchSpec::Core::eCore_arm_armv7m
-            || arch.GetCore() == ArchSpec::Core::eCore_arm_armv7em
-            || arch.GetCore() == ArchSpec::Core::eCore_arm_armv6m))
+    // ARM Cortex M0-M7 devices only execute thumb instructions
+    if (arch.IsAlwaysThumbInstructions ())
     {
         triple_str = thumb_arch.GetTriple().getTriple().c_str();
     }

Modified: lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp?rev=265377&r1=265376&r2=265377&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp (original)
+++ lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp Tue Apr  5 00:01:30 2016
@@ -13004,7 +13004,7 @@ EmulateInstructionARM::SetInstruction (c
 {
     if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target))
     {
-        if (m_arch.GetTriple().getArch() == llvm::Triple::thumb)
+        if (m_arch.GetTriple().getArch() == llvm::Triple::thumb || m_arch.IsAlwaysThumbInstructions ())
             m_opcode_mode = eModeThumb;
         else
         {
@@ -13017,7 +13017,7 @@ EmulateInstructionARM::SetInstruction (c
             else
                 return false;
         }
-        if (m_opcode_mode == eModeThumb)
+        if (m_opcode_mode == eModeThumb || m_arch.IsAlwaysThumbInstructions ())
             m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
         else
             m_opcode_cpsr = CPSR_MODE_USR;
@@ -13040,7 +13040,7 @@ EmulateInstructionARM::ReadInstruction (
             read_inst_context.type = eContextReadOpcode;
             read_inst_context.SetNoArgs ();
                   
-            if (m_opcode_cpsr & MASK_CPSR_T)
+            if ((m_opcode_cpsr & MASK_CPSR_T) || m_arch.IsAlwaysThumbInstructions ())
             {
                 m_opcode_mode = eModeThumb;
                 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
@@ -13678,19 +13678,19 @@ EmulateInstructionARM::TestEmulation (St
     }
     test_opcode = value_sp->GetUInt64Value ();
 
-    if (arch.GetTriple().getArch() == llvm::Triple::arm)
-    {
-        m_opcode_mode = eModeARM;
-        m_opcode.SetOpcode32 (test_opcode, GetByteOrder());
-    }
-    else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
+
+    if (arch.GetTriple().getArch() == llvm::Triple::thumb || arch.IsAlwaysThumbInstructions ())
     {
         m_opcode_mode = eModeThumb;
         if (test_opcode < 0x10000)
             m_opcode.SetOpcode16 (test_opcode, GetByteOrder());
         else
             m_opcode.SetOpcode32 (test_opcode, GetByteOrder());
-
+    }
+    else if (arch.GetTriple().getArch() == llvm::Triple::arm)
+    {
+        m_opcode_mode = eModeARM;
+        m_opcode.SetOpcode32 (test_opcode, GetByteOrder());
     }
     else
     {




More information about the lldb-commits mailing list