This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PATCH] [ppc64] Add POWER8 atomic sequences single-stepping support
- From: Edjunior Barbosa Machado <emachado at linux dot vnet dot ibm dot com>
- To: gdb-patches at sourceware dot org
- Cc: uweigand at de dot ibm dot com, Edjunior Barbosa Machado <emachado at linux dot vnet dot ibm dot com>
- Date: Mon, 6 Feb 2017 01:03:02 -0200
- Subject: [PATCH] [ppc64] Add POWER8 atomic sequences single-stepping support
- Authentication-results: sourceware.org; auth=none
Hi,
this patch aims to add single-stepping support for POWER8 atomic sequences
lbarx/stbcx, lharx/sthcx and lqarx/stqcx. Tested on ppc64 and ppc64le. Ok?
Thanks,
--
Edjunior
gdb/
2017-02-06 Edjunior Barbosa Machado <emachado@linux.vnet.ibm.com>
* rs6000-tdep.c (LBARX_INSTRUCTION, LHARX_INSTRUCTION,
LQARX_INSTRUCTION, STBCX_INSTRUCTION, STHCX_INSTRUCTION,
STQCX_INSTRUCTION): New defines.
(ppc_displaced_step_copy_insn): Check for lbarx/stbcx, lharx/sthcx and
lqarx/stqcx.
(ppc_deal_with_atomic_sequence): Likewise.
gdb/testsuite/
2017-02-06 Edjunior Barbosa Machado <emachado@linux.vnet.ibm.com>
* gdb.arch/ppc64-atomic-inst.exp: Add tests for lbarx/stbcx,
lharx/sthcx and lqarx/stqcx.
* gdb.arch/ppc64-atomic-inst.S: Likewise.
---
gdb/rs6000-tdep.c | 26 ++++++++++--
gdb/testsuite/gdb.arch/ppc64-atomic-inst.S | 59 +++++++++++++++++++++++++++-
gdb/testsuite/gdb.arch/ppc64-atomic-inst.exp | 47 +++++++++++++++++++++-
3 files changed, 124 insertions(+), 8 deletions(-)
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index 527f643..4cd3b59 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -986,9 +986,15 @@ typedef BP_MANIPULATION_ENDIAN (little_breakpoint, big_breakpoint)
#define LWARX_MASK 0xfc0007fe
#define LWARX_INSTRUCTION 0x7c000028
#define LDARX_INSTRUCTION 0x7c0000A8
+#define LBARX_INSTRUCTION 0x7c000068
+#define LHARX_INSTRUCTION 0x7c0000e8
+#define LQARX_INSTRUCTION 0x7c000228
#define STWCX_MASK 0xfc0007ff
#define STWCX_INSTRUCTION 0x7c00012d
#define STDCX_INSTRUCTION 0x7c0001ad
+#define STBCX_INSTRUCTION 0x7c00056d
+#define STHCX_INSTRUCTION 0x7c0005ad
+#define STQCX_INSTRUCTION 0x7c00016d
/* We can't displaced step atomic sequences. Otherwise this is just
like simple_displaced_step_copy_insn. */
@@ -1010,7 +1016,10 @@ ppc_displaced_step_copy_insn (struct gdbarch *gdbarch,
/* Assume all atomic sequences start with a lwarx/ldarx instruction. */
if ((insn & LWARX_MASK) == LWARX_INSTRUCTION
- || (insn & LWARX_MASK) == LDARX_INSTRUCTION)
+ || (insn & LWARX_MASK) == LDARX_INSTRUCTION
+ || (insn & LWARX_MASK) == LBARX_INSTRUCTION
+ || (insn & LWARX_MASK) == LHARX_INSTRUCTION
+ || (insn & LWARX_MASK) == LQARX_INSTRUCTION)
{
if (debug_displaced)
{
@@ -1162,7 +1171,10 @@ ppc_deal_with_atomic_sequence (struct regcache *regcache)
/* Assume all atomic sequences start with a lwarx/ldarx instruction. */
if ((insn & LWARX_MASK) != LWARX_INSTRUCTION
- && (insn & LWARX_MASK) != LDARX_INSTRUCTION)
+ && (insn & LWARX_MASK) != LDARX_INSTRUCTION
+ && (insn & LWARX_MASK) != LBARX_INSTRUCTION
+ && (insn & LWARX_MASK) != LHARX_INSTRUCTION
+ && (insn & LWARX_MASK) != LQARX_INSTRUCTION)
return NULL;
/* Assume that no atomic sequence is longer than "atomic_sequence_length"
@@ -1194,13 +1206,19 @@ ppc_deal_with_atomic_sequence (struct regcache *regcache)
}
if ((insn & STWCX_MASK) == STWCX_INSTRUCTION
- || (insn & STWCX_MASK) == STDCX_INSTRUCTION)
+ || (insn & STWCX_MASK) == STDCX_INSTRUCTION
+ || (insn & STWCX_MASK) == STBCX_INSTRUCTION
+ || (insn & STWCX_MASK) == STHCX_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)
+ && (insn & STWCX_MASK) != STDCX_INSTRUCTION
+ && (insn & STWCX_MASK) != STBCX_INSTRUCTION
+ && (insn & STWCX_MASK) != STHCX_INSTRUCTION
+ && (insn & STWCX_MASK) != STQCX_INSTRUCTION)
return NULL;
closing_insn = loc;
diff --git a/gdb/testsuite/gdb.arch/ppc64-atomic-inst.S b/gdb/testsuite/gdb.arch/ppc64-atomic-inst.S
index 52c887f..6c84fd8 100644
--- a/gdb/testsuite/gdb.arch/ppc64-atomic-inst.S
+++ b/gdb/testsuite/gdb.arch/ppc64-atomic-inst.S
@@ -49,9 +49,64 @@ main:
bne 3f
addi 5,5,1
stdcx. 5,0,4
- bne 1b
+ bne 2b
+
+ stb 0,0(4)
+3: lbarx 5,0,4
+ cmpdi 5,0
+ bne 4f
+ addi 5,5,1
+ stbcx. 5,0,4
+ bne 3b
+
+ sth 0,0(4)
+4: lharx 5,0,4
+ cmpdi 5,0
+ bne 5f
+ addi 5,5,1
+ sthcx. 5,0,4
+ bne 4b
+
+#ifdef __BIG_ENDIAN__
+ li 10,0
+ li 6,0
+ li 7,1
+ std 10,-16(1)
+ li 10,1
+ std 10,-8(1)
+ addi 4,1,-16
+#else
+ std 9,40(1)
+ li 9,1
+ addi 4,1,32
+ std 9,32(1)
+ mr 8,9
+ ld 3,8(4)
+#endif
+5: lqarx 10,0,4
+#ifdef __BIG_ENDIAN__
+ li 8,0
+ li 9,2
+ mr 5,10
+ xor 10,11,7
+ xor 5,5,6
+ or. 4,5,10
+ bne- 6f
+ addi 10,1,-16
+ stqcx. 8,0,10
+#else
+ xor 9,11,8
+ mr 6,11
+ xor 11,10,3
+ or. 0,9,11
+ bne 6f
+ li 14,0
+ li 15,2
+ stqcx. 14,0,4
+#endif
+ bne 5b
-3: li 3,0
+6: li 3,0
blr
#if _CALL_ELF == 2
diff --git a/gdb/testsuite/gdb.arch/ppc64-atomic-inst.exp b/gdb/testsuite/gdb.arch/ppc64-atomic-inst.exp
index d1b3a7d..678a4a7 100644
--- a/gdb/testsuite/gdb.arch/ppc64-atomic-inst.exp
+++ b/gdb/testsuite/gdb.arch/ppc64-atomic-inst.exp
@@ -28,7 +28,8 @@ if {![istarget "powerpc*"] || ![is_lp64_target]} {
standard_testfile .S
-if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} {debug quiet}] } {
+if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \
+ [list debug quiet additional_flags=-mcpu=power8]] } {
return -1
}
@@ -36,6 +37,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} {debug quie
# stepping.
proc do_test { displaced } {
global decimal hex
+ global gdb_prompt
if ![runto_main] then {
untested "could not run to main"
@@ -52,6 +54,18 @@ proc do_test { displaced } {
gdb_breakpoint "$bp2" "Breakpoint $decimal at $hex" \
"Set the breakpoint at the start of the ldarx/stdcx sequence"
+ set bp3 [gdb_get_line_number "lbarx"]
+ gdb_breakpoint "$bp3" "Breakpoint $decimal at $hex" \
+ "Set the breakpoint at the start of the lbarx/stbcx sequence"
+
+ set bp4 [gdb_get_line_number "lharx"]
+ gdb_breakpoint "$bp4" "Breakpoint $decimal at $hex" \
+ "Set the breakpoint at the start of the lharx/sthcx sequence"
+
+ set bp5 [gdb_get_line_number "lqarx"]
+ gdb_breakpoint "$bp5" "Breakpoint $decimal at $hex" \
+ "Set the breakpoint at the start of the lqarx/stqcx sequence"
+
gdb_test continue "Continuing.*Breakpoint $decimal.*" \
"Continue until lwarx/stwcx start breakpoint"
@@ -61,8 +75,37 @@ proc do_test { displaced } {
gdb_test continue "Continuing.*Breakpoint $decimal.*" \
"Continue until ldarx/stdcx start breakpoint"
- gdb_test nexti "bne.*1b" \
+ gdb_test nexti "bne.*2b" \
"Step through the ldarx/stdcx sequence"
+
+ gdb_test continue "Continuing.*Breakpoint $decimal.*" \
+ "Continue until lbarx/stbcx start breakpoint"
+
+ gdb_test_multiple "nexti" "Check for lbarx instruction support" {
+ -re "Program received signal SIGILL,.*\r\n$gdb_prompt $" {
+ unsupported "lbarx instruction unsupported"
+ return
+ }
+ -re "bne.*3b\r\n$gdb_prompt $" {
+ pass "Step through the lbarx/stbcx sequence"
+ }
+ -re "$gdb_prompt $" {
+ unsupported "lbarx instruction unsupported (unknown error)"
+ return
+ }
+ }
+
+ gdb_test continue "Continuing.*Breakpoint $decimal.*" \
+ "Continue until lharx/sthcx start breakpoint"
+
+ gdb_test nexti "bne.*4b" \
+ "Step through the lharx/sthcx sequence"
+
+ gdb_test continue "Continuing.*Breakpoint $decimal.*" \
+ "Continue until ldqrx/stqcx start breakpoint"
+
+ gdb_test nexti "bne.*5b" \
+ "Step through the lqarx/stqcx sequence"
}
foreach displaced { "off" "on" } {
--
2.9.3