This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] [ppc64] Add POWER8 atomic sequences single-stepping support


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]