mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-26 01:07:52 +00:00
arc: Determine a branch target of DBNZ correctly
DBNZ instruction was moved from BRANCH class to a separate one - DBNZ.
Thus, it must be processed separately in arc_insn_get_branch_target
to correctly determine an offset for a possible branch.
The testsuite for DBNZ instruction verifies these cases:
1. Check that dbnz does not branch and falls through if its source
register is 0 after decrementing. GDB must successfully break
on the following instruction after stepping over.
2. Check that dbnz branches to the target correctly if its source register
is not 0 after decrementing - GDB must successfully break on the target
instruction if a forward branch is performed after stepping over.
3. The same as point 2 but for a backward branching case.
Signed-off-by: Yuriy Kolerov <kolerov93@gmail.com>
This commit is contained in:
committed by
Shahab Vahedi
parent
f961273101
commit
33283d91d9
@@ -466,6 +466,16 @@ arc_insn_get_branch_target (const struct arc_instruction &insn)
|
||||
instruction, hence last two bits should be truncated. */
|
||||
return pcrel_addr + align_down (insn.address, 4);
|
||||
}
|
||||
/* DBNZ is the only branch instruction that keeps a branch address in
|
||||
the second operand. It must be intercepted and treated differently. */
|
||||
else if (insn.insn_class == DBNZ)
|
||||
{
|
||||
CORE_ADDR pcrel_addr = arc_insn_get_operand_value_signed (insn, 1);
|
||||
|
||||
/* Offset is relative to the 4-byte aligned address of the current
|
||||
instruction, hence last two bits should be truncated. */
|
||||
return pcrel_addr + align_down (insn.address, 4);
|
||||
}
|
||||
/* B, Bcc, BL, BLcc, LP, LPcc: PC = currentPC + operand. */
|
||||
else if (insn.insn_class == BRANCH || insn.insn_class == LOOP)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user