aboutsummaryrefslogtreecommitdiff
path: root/gdb/rs6000-tdep.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2011-11-22 08:19:16 +0000
committerAlan Modra <amodra@gmail.com>2011-11-22 08:19:16 +0000
commita3769e0c797d0c521aeed2a23b34aa83887ef472 (patch)
tree27917e12bd8e9a5e498dd012cd3658f6da77c485 /gdb/rs6000-tdep.c
parentae1d1a5355c8e528aa3ec086d7c158550e9c044d (diff)
downloadgdb-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.c15
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. */