Index: include/lldb/Target/ThreadPlanStepRange.h =================================================================== --- include/lldb/Target/ThreadPlanStepRange.h +++ include/lldb/Target/ThreadPlanStepRange.h @@ -68,6 +68,12 @@ bool SetNextBranchBreakpoint (); + // packet aware branch index finding strategy for hexagon architecture + bool + GetBranchIndexForHexagon( const InstructionList * instructions, + const uint32_t pc_index, + uint32_t & branch_index); + void ClearNextBranchBreakpoint(); Index: source/Target/ThreadPlanStepRange.cpp =================================================================== --- source/Target/ThreadPlanStepRange.cpp +++ source/Target/ThreadPlanStepRange.cpp @@ -360,6 +360,57 @@ } bool +ThreadPlanStepRange::GetBranchIndexForHexagon( const InstructionList * instructions, + const uint32_t pc_index, + uint32_t & branch_index) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + + branch_index = pc_index; + + // find the farthest viable packet within the range + { + Error error; + + // read all instructions up to the end of the range (not the last instruction!!) + for (uint32_t ix = pc_index; ix < instructions->GetSize() - 1; ix++) + { + lldb::InstructionSP inst = instructions->GetInstructionAtIndex(ix); + // if this instruction branched then we can only jump as far as branch_index + // which should be the last start of a packet we saw + if (inst->DoesBranch()) + break; + + // read instruction from memory + uint32_t inst_bytes = 0; + Target & target = m_thread.GetProcess()->GetTarget(); + lldb::addr_t addr = inst->GetAddress().GetLoadAddress(&target); + m_thread.GetProcess()->ReadMemory(addr, &inst_bytes, sizeof(inst_bytes), error); + if (!error.Success()) + return false; + + if (log) + log->Printf("Instruction @0x%08X : 0x%08X\n", (uint32_t)addr, inst_bytes); + + // 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 + branch_index = ix + 1; + + if (log) + log->Printf("Packet start @0x%08X\n", (uint32_t)addr + 4); + } + } + } + + // at this step branch_index should be packet aligned + return true; +} + +bool ThreadPlanStepRange::SetNextBranchBreakpoint () { if (m_next_branch_bp_sp) @@ -378,49 +429,59 @@ InstructionList *instructions = GetInstructionsForAddress (cur_addr, range_index, pc_index); if (instructions == NULL) return false; + + uint32_t branch_index = pc_index; + + // packet aware stepping strategy for hexagon architecture + const llvm::Triple &triple_ref = m_thread.GetProcess()->GetTarget().GetArchitecture().GetTriple(); + if (triple_ref.getArch() == llvm::Triple::hexagon) + { + if (log) + log->Printf("Finding branch index from address @ 0x%08x", (uint32_t)cur_addr); + + // get a packet aligned branch index + if (!GetBranchIndexForHexagon(instructions, pc_index, branch_index)) + return false; + } else { - uint32_t branch_index; - branch_index = instructions->GetIndexOfNextBranchInstruction (pc_index); - - Address run_to_address; - + branch_index = instructions->GetIndexOfNextBranchInstruction(pc_index); + // If we didn't find a branch, run to the end of the range. if (branch_index == UINT32_MAX) { branch_index = instructions->GetSize() - 1; } - - if (branch_index - pc_index > 1) + } + + if (branch_index - pc_index > 1) + { + Address run_to_address; + const bool is_internal = true; + run_to_address = instructions->GetInstructionAtIndex(branch_index)->GetAddress(); + m_next_branch_bp_sp = GetTarget().CreateBreakpoint(run_to_address, is_internal, false); + if (m_next_branch_bp_sp) { - const bool is_internal = true; - run_to_address = instructions->GetInstructionAtIndex(branch_index)->GetAddress(); - m_next_branch_bp_sp = GetTarget().CreateBreakpoint(run_to_address, is_internal, false); - if (m_next_branch_bp_sp) + if (log) { - if (log) + lldb::break_id_t bp_site_id = LLDB_INVALID_BREAK_ID; + BreakpointLocationSP bp_loc = m_next_branch_bp_sp->GetLocationAtIndex(0); + if (bp_loc) { - lldb::break_id_t bp_site_id = LLDB_INVALID_BREAK_ID; - BreakpointLocationSP bp_loc = m_next_branch_bp_sp->GetLocationAtIndex(0); - if (bp_loc) + BreakpointSiteSP bp_site = bp_loc->GetBreakpointSite(); + if (bp_site) { - BreakpointSiteSP bp_site = bp_loc->GetBreakpointSite(); - if (bp_site) - { - bp_site_id = bp_site->GetID(); - } + bp_site_id = bp_site->GetID(); } - log->Printf ("ThreadPlanStepRange::SetNextBranchBreakpoint - Setting breakpoint %d (site %d) to run to address 0x%" PRIx64, - m_next_branch_bp_sp->GetID(), - bp_site_id, - run_to_address.GetLoadAddress(&m_thread.GetProcess()->GetTarget())); } - m_next_branch_bp_sp->SetThreadID(m_thread.GetID()); - m_next_branch_bp_sp->SetBreakpointKind ("next-branch-location"); - return true; + log->Printf ("ThreadPlanStepRange::SetNextBranchBreakpoint - Setting breakpoint %d (site %d) to run to address 0x%" PRIx64, + m_next_branch_bp_sp->GetID(), + bp_site_id, + run_to_address.GetLoadAddress(&m_thread.GetProcess()->GetTarget())); } - else - return false; + m_next_branch_bp_sp->SetThreadID(m_thread.GetID()); + m_next_branch_bp_sp->SetBreakpointKind ("next-branch-location"); + return true; } } return false;