From a3769e0c797d0c521aeed2a23b34aa83887ef472 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Tue, 22 Nov 2011 08:19:16 +0000 Subject: [PATCH] * 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. --- gdb/ChangeLog | 6 ++++++ gdb/rs6000-tdep.c | 15 +++++++-------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 109c2f7..d94e506 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,9 @@ +2011-11-22 Alan Modra + + * 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. + 2011-11-21 Keith Seitz * gdb.mi/mi-var-display.exp: Remove XFAIL for c_variable-7.51, 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. */ -- 2.7.4