summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTed Woodward <ted.woodward@codeaurora.org>2015-05-11 21:12:33 +0000
committerTed Woodward <ted.woodward@codeaurora.org>2015-05-11 21:12:33 +0000
commite76e7e9369ca1b8309d15e26b31a2bf24b311ed7 (patch)
tree120d6affb5b7f5e56816122427bede3c1a61607c
parent5b202966f5e7dec49055fffd4b6eea005530b0bc (diff)
downloadbcm5719-llvm-e76e7e9369ca1b8309d15e26b31a2bf24b311ed7.tar.gz
bcm5719-llvm-e76e7e9369ca1b8309d15e26b31a2bf24b311ed7.zip
Add Hexagon packet support to ThreadPlanStepRange
Summary: Hexagon is a VLIW processor. It can execute multiple instructions at once, called a packet. Breakpoints need to be alone in a packet. This patch will make sure that temporary breakpoints used for stepping are set at the start of a packet, which will put the breakpoint in a packet by itself. Patch by Deepak Panickal of CodePlay and Ted Woodward of Qualcomm. Reviewers: deepak2427, clayborg Reviewed By: clayborg Subscribers: lldb-commits Differential Revision: http://reviews.llvm.org/D9437 llvm-svn: 237047
-rw-r--r--lldb/include/lldb/Core/Disassembler.h2
-rw-r--r--lldb/source/Core/Disassembler.cpp51
-rw-r--r--lldb/source/Target/ThreadPlanStepRange.cpp3
3 files changed, 52 insertions, 4 deletions
diff --git a/lldb/include/lldb/Core/Disassembler.h b/lldb/include/lldb/Core/Disassembler.h
index 46ac60557c5..e08e2def4c1 100644
--- a/lldb/include/lldb/Core/Disassembler.h
+++ b/lldb/include/lldb/Core/Disassembler.h
@@ -225,7 +225,7 @@ public:
GetInstructionAtIndex (size_t idx) const;
uint32_t
- GetIndexOfNextBranchInstruction(uint32_t start) const;
+ GetIndexOfNextBranchInstruction(uint32_t start, Target &target) const;
uint32_t
GetIndexOfInstructionAtLoadAddress (lldb::addr_t load_addr, Target &target);
diff --git a/lldb/source/Core/Disassembler.cpp b/lldb/source/Core/Disassembler.cpp
index 46d453d5cfc..1a698c3f5a1 100644
--- a/lldb/source/Core/Disassembler.cpp
+++ b/lldb/source/Core/Disassembler.cpp
@@ -1061,12 +1061,13 @@ InstructionList::Append (lldb::InstructionSP &inst_sp)
}
uint32_t
-InstructionList::GetIndexOfNextBranchInstruction(uint32_t start) const
+InstructionList::GetIndexOfNextBranchInstruction(uint32_t start, Target &target) const
{
size_t num_instructions = m_instructions.size();
uint32_t next_branch = UINT32_MAX;
- for (size_t i = start; i < num_instructions; i++)
+ size_t i;
+ for (i = start; i < num_instructions; i++)
{
if (m_instructions[i]->DoesBranch())
{
@@ -1074,6 +1075,52 @@ InstructionList::GetIndexOfNextBranchInstruction(uint32_t start) const
break;
}
}
+
+ // Hexagon needs the first instruction of the packet with the branch.
+ // Go backwards until we find an instruction marked end-of-packet, or
+ // until we hit start.
+ if (target.GetArchitecture().GetTriple().getArch() == llvm::Triple::hexagon)
+ {
+ // If we didn't find a branch, find the last packet start.
+ if (next_branch == UINT32_MAX)
+ {
+ i = num_instructions - 1;
+ }
+
+ while (i > start)
+ {
+ --i;
+
+ Error error;
+ uint32_t inst_bytes;
+ bool prefer_file_cache = false; // Read from process if process is running
+ lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
+ target.ReadMemory(m_instructions[i]->GetAddress(),
+ prefer_file_cache,
+ &inst_bytes,
+ sizeof(inst_bytes),
+ error,
+ &load_addr);
+ // If we have an error reading memory, return start
+ if (!error.Success())
+ return start;
+ // check if this is the last instruction in a packet
+ // bits 15:14 will be 11b or 00b for a duplex
+ if (((inst_bytes & 0xC000) == 0xC000) ||
+ ((inst_bytes & 0xC000) == 0x0000))
+ {
+ // instruction after this should be the start of next packet
+ next_branch = i + 1;
+ break;
+ }
+ }
+
+ if (next_branch == UINT32_MAX)
+ {
+ // We couldn't find the previous packet, so return start
+ next_branch = start;
+ }
+ }
return next_branch;
}
diff --git a/lldb/source/Target/ThreadPlanStepRange.cpp b/lldb/source/Target/ThreadPlanStepRange.cpp
index 55f2c2b8308..324f5a7c653 100644
--- a/lldb/source/Target/ThreadPlanStepRange.cpp
+++ b/lldb/source/Target/ThreadPlanStepRange.cpp
@@ -380,8 +380,9 @@ ThreadPlanStepRange::SetNextBranchBreakpoint ()
return false;
else
{
+ Target &target = GetThread().GetProcess()->GetTarget();
uint32_t branch_index;
- branch_index = instructions->GetIndexOfNextBranchInstruction (pc_index);
+ branch_index = instructions->GetIndexOfNextBranchInstruction (pc_index, target);
Address run_to_address;
OpenPOWER on IntegriCloud