[PATCH 4/4] Add lbarx/stbcx., lharx/sthcx. and lqarx/stqcx. single stepping

Anton Blanchard
2014-03-28T03:42:03Z

Newer CPUs support byte, half word and quad word atomic update
sequences.

gdb/testsuite/
2014-03-28 Anton Blanchard <anton@samba.org>

* rs6000-tdep.c (ppc_deal_with_atomic_sequence): Add single step
support for lbarx/stbcx., lharx/sthcx. and lqarx/stqcx.
---
gdb/rs6000-tdep.c | 36 ++++++++++++++++++++++++++----------
1 file changed, 26 insertions(+), 10 deletions(-)

diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index be14e39..7257cc3 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -1070,14 +1070,21 @@ ppc_displaced_step_hw_singlestep (struct gdbarch *gdbarch,

/* Instruction masks used during single-stepping of atomic sequences. */
#define LWARX_MASK 0xfc0007fe
+#define LBARX_INSTRUCTION 0x7c000068
+#define LHARX_INSTRUCTION 0x7c0000e8
#define LWARX_INSTRUCTION 0x7c000028
#define LDARX_INSTRUCTION 0x7c0000A8
+#define LQARX_INSTRUCTION 0x7c000228
+
#define STWCX_MASK 0xfc0007ff
+#define STBCX_INSTRUCTION 0x7c00056d
+#define STHCX_INSTRUCTION 0x7c0005ad
#define STWCX_INSTRUCTION 0x7c00012d
#define STDCX_INSTRUCTION 0x7c0001ad
+#define STQCX_INSTRUCTION 0x7c00016d

-/* Checks for an atomic sequence of instructions beginning with a LWARX/LDARX
- instruction and ending with a STWCX/STDCX instruction. If such a sequence
+/* Checks for an atomic sequence of instructions beginning with a l[bhwdq]arx
+ instruction and ending with a st[bhwdq]cx instruction. If such a sequence
is found, attempt to step through it. A breakpoint is placed at the end of
the sequence. */

@@ -1098,9 +1105,12 @@ ppc_deal_with_atomic_sequence (struct frame_info *frame)
const int atomic_sequence_length = 16; /* Instruction sequence length. */
int opcode; /* Branch instruction's OPcode. */

- /* Assume all atomic sequences start with a lwarx/ldarx instruction. */
- if ((insn & LWARX_MASK) != LWARX_INSTRUCTION
- && (insn & LWARX_MASK) != LDARX_INSTRUCTION)
+ /* Assume all atomic sequences start with a l[bhwdq]arx instruction. */
+ if ((insn & LWARX_MASK) != LBARX_INSTRUCTION
+ && (insn & LWARX_MASK) != LHARX_INSTRUCTION
+ && (insn & LWARX_MASK) != LWARX_INSTRUCTION
+ && (insn & LWARX_MASK) != LDARX_INSTRUCTION
+ && (insn & LWARX_MASK) != LQARX_INSTRUCTION)
return 0;

/* Assume that no atomic sequence is longer than "atomic_sequence_length"
@@ -1127,14 +1137,20 @@ ppc_deal_with_atomic_sequence (struct frame_info *frame)
last_breakpoint++;
}

- if ((insn & STWCX_MASK) == STWCX_INSTRUCTION
- || (insn & STWCX_MASK) == STDCX_INSTRUCTION)
+ if ((insn & STWCX_MASK) == STBCX_INSTRUCTION
+ || (insn & STWCX_MASK) == STHCX_INSTRUCTION
+ || (insn & STWCX_MASK) == STWCX_INSTRUCTION
+ || (insn & STWCX_MASK) == STDCX_INSTRUCTION
+ || (insn & STWCX_MASK) == STQCX_INSTRUCTION)
break;
}

- /* Assume that the atomic sequence ends with a stwcx/stdcx instruction. */
- if ((insn & STWCX_MASK) != STWCX_INSTRUCTION
- && (insn & STWCX_MASK) != STDCX_INSTRUCTION)
+ /* Assume that the atomic sequence ends with a st[bhwdq]cx instruction. */
+ if ((insn & STWCX_MASK) != STBCX_INSTRUCTION
+ && (insn & STWCX_MASK) != STHCX_INSTRUCTION
+ && (insn & STWCX_MASK) != STWCX_INSTRUCTION
+ && (insn & STWCX_MASK) != STDCX_INSTRUCTION
+ && (insn & STWCX_MASK) != STQCX_INSTRUCTION)
return 0;

closing_insn = loc;
--
1.8.3.2