diff options
author | Alan Modra <amodra@gmail.com> | 2011-11-22 08:19:16 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2011-11-22 08:19:16 +0000 |
commit | a3769e0c797d0c521aeed2a23b34aa83887ef472 (patch) | |
tree | 27917e12bd8e9a5e498dd012cd3658f6da77c485 /gdb/rs6000-tdep.c | |
parent | ae1d1a5355c8e528aa3ec086d7c158550e9c044d (diff) | |
download | gdb-a3769e0c797d0c521aeed2a23b34aa83887ef472.zip gdb-a3769e0c797d0c521aeed2a23b34aa83887ef472.tar.gz gdb-a3769e0c797d0c521aeed2a23b34aa83887ef472.tar.bz2 |
* rs6000-tdep.c (ppc_deal_with_atomic_sequence): Correct branch
destination calculation. Don't expect >> to sign extend. Don't
add a break if branch lands inside the sequence anywhere.
Diffstat (limited to 'gdb/rs6000-tdep.c')
-rw-r--r-- | gdb/rs6000-tdep.c | 15 |
1 files changed, 7 insertions, 8 deletions
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index 65396443..da3a7a4 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -1116,8 +1116,8 @@ ppc_deal_with_atomic_sequence (struct frame_info *frame) its destination address. */ if ((insn & BRANCH_MASK) == BC_INSN) { - int immediate = ((insn & ~3) << 16) >> 16; - int absolute = ((insn >> 1) & 1); + int immediate = ((insn & 0xfffc) ^ 0x8000) - 0x8000; + int absolute = insn & 2; if (bc_insn_count >= 1) return 0; /* More than one conditional branch found, fallback @@ -1126,7 +1126,7 @@ ppc_deal_with_atomic_sequence (struct frame_info *frame) if (absolute) breaks[1] = immediate; else - breaks[1] = pc + immediate; + breaks[1] = loc + immediate; bc_insn_count++; last_breakpoint++; @@ -1150,11 +1150,10 @@ ppc_deal_with_atomic_sequence (struct frame_info *frame) breaks[0] = loc; /* Check for duplicated breakpoints. Check also for a breakpoint - placed (branch instruction's destination) at the stwcx/stdcx - instruction, this resets the reservation and take us back to the - lwarx/ldarx instruction at the beginning of the atomic sequence. */ - if (last_breakpoint && ((breaks[1] == breaks[0]) - || (breaks[1] == closing_insn))) + placed (branch instruction's destination) anywhere in sequence. */ + if (last_breakpoint + && (breaks[1] == breaks[0] + || (breaks[1] >= pc && breaks[1] <= closing_insn))) last_breakpoint = 0; /* Effectively inserts the breakpoints. */ |