aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/testsuite')
-rw-r--r--gdb/testsuite/ChangeLog5
-rw-r--r--gdb/testsuite/gdb.arch/powerpc-htm-regs.c39
-rw-r--r--gdb/testsuite/gdb.arch/powerpc-htm-regs.exp328
3 files changed, 372 insertions, 0 deletions
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index bb02933..a8c83d7 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,5 +1,10 @@
2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com>
+ * gdb.arch/powerpc-htm-regs.c: New file.
+ * gdb.arch/powerpc-htm-regs.exp: New file.
+
+2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com>
+
* gdb.arch/powerpc-tar.c: New file.
* gdb.arch/powerpc-tar.exp: New file.
diff --git a/gdb/testsuite/gdb.arch/powerpc-htm-regs.c b/gdb/testsuite/gdb.arch/powerpc-htm-regs.c
new file mode 100644
index 0000000..8c062ce
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/powerpc-htm-regs.c
@@ -0,0 +1,39 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright (C) 2018 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+int main (void)
+{
+ /* Touch DSCR. Some kernels won't schedule the thread with a DSCR
+ altered by ptrace unless the register was used at some point. */
+ unsigned long dscr = 0x0;
+
+ /* This is the non-privileged SPR number to access DSCR,
+ available since isa 207. */
+ asm volatile ("mtspr 3,%0" : : "r" (dscr));
+
+ asm volatile ("tbegin."); // first marker
+ asm volatile goto ("bc 12,2,%l[end]"
+ :
+ :
+ :
+ : end);
+ asm volatile ("tabort. 0");
+end:
+ asm volatile ("nop"); // second marker
+
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.arch/powerpc-htm-regs.exp b/gdb/testsuite/gdb.arch/powerpc-htm-regs.exp
new file mode 100644
index 0000000..a1c876a
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/powerpc-htm-regs.exp
@@ -0,0 +1,328 @@
+# Copyright (C) 2018 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# This file is part of the gdb testsuite.
+
+# Test access to HTM (Hardware Transactional Memory) registers. The
+# tests read the values of various registers before stepping the
+# inferior through a "tbegin." instruction to start a transaction,
+# then the checkpointed versions of the registers are checked against
+# the pre-transactional values. Then, new values are written to some
+# of the checkpointed registers, these values are read back and saved,
+# the inferior continues until the transaction aborts, and the regular
+# registers are then checked against the saved values, because the
+# abort should have reverted the registers to these values.
+
+if {![istarget "powerpc*-*-linux*"]} then {
+ verbose "Skipping PowerPC test for HTM registers."
+ return
+}
+
+standard_testfile .c .gen.c
+
+# First check if our processor and kernel support access to
+# the registers we need and to the HTM facility.
+
+proc check_register_access { regname } {
+ global gdb_prompt
+
+ set test "$regname register access"
+ gdb_test_multiple "info reg $regname" "$test" {
+ -re "Invalid register.*\r\n$gdb_prompt $" {
+ unsupported "$test"
+ return 0
+ }
+ -re "\r\n$regname.*\r\n$gdb_prompt $" {
+ pass "$test"
+ return 1
+ }
+ }
+ return 0
+}
+
+proc check_htm_support {} {
+ global gdb_prompt
+ set test "htm support"
+
+ gdb_test_multiple "stepi" "$test" {
+ -re "Illegal instruction.*\r\n$gdb_prompt $" {
+ unsupported $test
+ return 0
+ }
+ -re "nop.*\r\n$gdb_prompt $"
+ {
+ pass $test
+ return 1
+ }
+ }
+ return 0;
+}
+
+with_test_prefix "check htm support" {
+ set gen_src [standard_output_file $srcfile2]
+
+ gdb_produce_source $gen_src {
+ int main () {
+ asm volatile ("tbegin."); // marker
+ asm volatile ("nop");
+ return 0;
+ }
+ }
+
+ if {[build_executable "compile" $binfile $gen_src {debug}] == -1} {
+ return
+ }
+
+ clean_restart $binfile
+
+ # Displaced-stepping a tbegin. causes problems,
+ # so we make the breakpoint temporary.
+ gdb_breakpoint [gdb_get_line_number "marker" "$gen_src"] temporary
+
+ gdb_run_cmd
+
+ # Wait for the prompt.
+ if {[gdb_test "" "Temporary breakpoint.*"] != 0 } {
+ return
+ }
+
+ # Make sure that we stopped at the right place (just before tbegin. is
+ # executed).
+ if { [gdb_test "x/i \$pc" "=> $hex.*:.*tbegin\\..*" "disassemble tbegin"] != 0} {
+ return
+ }
+
+ if {![check_register_access "vs0"]} {
+ return
+ }
+
+ if {![check_register_access "texasr"]} {
+ return
+ }
+
+ if {![check_register_access "dscr"]} {
+ return
+ }
+
+ if {![check_register_access "ppr"]} {
+ return
+ }
+
+ if {![check_register_access "tar"]} {
+ return
+ }
+
+ if {![check_htm_support]} {
+ return
+ }
+}
+
+# Now do the actual test.
+if {[build_executable "compile" $binfile $srcfile {debug}] == -1} {
+ return
+}
+
+clean_restart $binfile
+
+gdb_breakpoint [gdb_get_line_number "first marker"] temporary
+
+gdb_run_cmd
+
+# Wait for the prompt.
+gdb_test "" "Temporary breakpoint.*"
+
+if {[gdb_test "x/i \$pc" "=> $hex.*:.*tbegin\\..*" "disassemble tbegin"] != 0} {
+ return
+}
+
+# Now we write non-zero values to some registers, then read the values
+# of various registers, then stepi to start the transaction. The
+# checkpointed register state should correspond to the values we read.
+
+# Write to the GPRs
+for {set i 0} {$i < 32} {incr i 1} {
+ gdb_test_no_output "set \$r$i = $i"
+}
+
+gdb_test_no_output "set \$xer = 0xc0000000"
+
+# FPRs
+gdb_test_no_output "set \$f0 = 0.5"
+for {set i 1} {$i < 32} {incr i 1} {
+ gdb_test_no_output "set \$f$i = \$f[expr $i - 1] + 1.0"
+}
+
+gdb_test_no_output "set \$fpscr = 0x84005000"
+
+# VRs
+for {set i 0} {$i < 32} {incr i 1} {
+ for {set j 0} {$j < 4} {incr j 1} {
+ gdb_test_no_output "set \$vr$i.v4_int32\[$j\] = $i"
+ }
+}
+
+gdb_test_no_output "set \$dscr = 0x2"
+gdb_test_no_output "set \$tar = &main" "set tar"
+
+# Get the pre-transactional value of the registers.
+for {set i 0} {$i < 32} {incr i 1} {
+ set "r$i" [get_hexadecimal_valueof "\$r$i" "default0"]
+}
+
+set cr [get_hexadecimal_valueof "\$cr" "default0"]
+set xer [get_hexadecimal_valueof "\$xer" "default0"]
+set lr [get_hexadecimal_valueof "\$lr" "default0"]
+set ctr [get_hexadecimal_valueof "\$ctr" "default0"]
+
+for {set i 0} {$i < 32} {incr i 1} {
+ set "f$i" [get_valueof "" "\$f$i" "default0"]
+}
+
+set fpscr [get_hexadecimal_valueof "\$fpscr" "default0"]
+
+for {set i 0} {$i < 32} {incr i 1} {
+ set "vr$i" [get_hexadecimal_valueof "\$vr$i.uint128" "default0"]
+}
+
+set vscr [get_hexadecimal_valueof "\$vscr" "default0"]
+set vrsave [get_hexadecimal_valueof "\$vrsave" "default0"]
+
+for {set i 0} {$i < 64} {incr i 1} {
+ set "vs$i" [get_hexadecimal_valueof "\$vs$i.uint128" "default0"]
+}
+
+set dscr [get_hexadecimal_valueof "\$dscr" "default0"]
+set ppr [get_hexadecimal_valueof "\$ppr" "default0"]
+set tar [get_hexadecimal_valueof "\$tar" "default0"]
+
+gdb_test "stepi" "asm.*bc.*"
+
+proc test_register_match {reg_name reg_var_name hex} {
+ set test "$reg_name matches $reg_var_name"
+
+ # In some infrequent cases CXER doesn't match the
+ # pre-transactional XER, possibly due to a linux kernel bug.
+ set should_xfail 0
+ if [istarget "powerpc*-*-linux*" && reg_name == "cxer"] {
+ set should_xfail 1
+ }
+
+ upvar $reg_var_name expected_val
+
+ if {$hex} {
+ set actual_val [get_hexadecimal_valueof "\$$reg_name" "default1"]
+ } else {
+ set actual_val [get_valueof "" "\$$reg_name" "default1"]
+ }
+
+ if { "$expected_val" == "$actual_val" } {
+ pass $test
+ } else {
+ if {$should_xfail} {
+ xfail $test
+ } else {
+ fail $test
+ }
+ }
+}
+
+for {set i 0} {$i < 32} {incr i 1} {
+ test_register_match "cr$i" "r$i" 1
+}
+
+test_register_match "ccr" "cr" 1
+test_register_match "cxer" "xer" 1
+test_register_match "clr" "lr" 1
+test_register_match "cctr" "ctr" 1
+
+for {set i 0} {$i < 32} {incr i 1} {
+ test_register_match "cf$i" "f$i" 0
+}
+
+test_register_match "cfpscr" "fpscr" 1
+
+for {set i 0} {$i < 32} {incr i 1} {
+ test_register_match "cvr$i.uint128" "vr$i" 1
+}
+
+test_register_match "cvscr" "vscr" 1
+test_register_match "cvrsave" "vrsave" 1
+
+for {set i 0} {$i < 64} {incr i 1} {
+ test_register_match "cvs$i.uint128" "vs$i" 1
+}
+
+test_register_match "cdscr" "dscr" 1
+test_register_match "cppr" "ppr" 1
+test_register_match "ctar" "tar" 1
+
+# Support for writing to the checkpointed registers is not
+# currently available in the gdbserver stub.
+if [target_is_gdbserver] {
+ unsupported "write to checkpointed registers"
+ return
+}
+
+# Now write different values to some of the checkpointed registers and
+# check that the transaction abort reverts the register to these
+# values.
+for {set i 0} {$i < 32} {incr i 1} {
+ gdb_test_no_output "set \$cr$i = $i + 0xC00"
+}
+
+gdb_test_no_output "set \$cf0 = 0.25"
+for {set i 1} {$i < 32} {incr i 1} {
+ gdb_test_no_output "set \$cf$i = \$cf[expr $i - 1] + 1.0"
+}
+
+for {set i 0} {$i < 32} {incr i 1} {
+ for {set j 0} {$j < 4} {incr j 1} {
+ gdb_test_no_output "set \$cvr$i.v4_int32\[$j\] = $i + 0xF00"
+ }
+}
+
+# Read back the values.
+with_test_prefix "after write" {
+ for {set i 0} {$i < 32} {incr i 1} {
+ set "cr$i" [get_hexadecimal_valueof "\$cr$i" "default0"]
+ }
+
+ for {set i 0} {$i < 32} {incr i 1} {
+ set "cf$i" [get_valueof "" "\$cf$i" "default0"]
+ }
+
+ for {set i 0} {$i < 64} {incr i 1} {
+ set "cvs$i" [get_hexadecimal_valueof "\$cvs$i.uint128" "default0"]
+ }
+}
+
+gdb_breakpoint [gdb_get_line_number "second marker"]
+
+gdb_test "continue"
+
+with_test_prefix "after transaction failure" {
+ for {set i 0} {$i < 32} {incr i 1} {
+ test_register_match "r$i" "cr$i" 1
+ }
+
+ for {set i 0} {$i < 32} {incr i 1} {
+ test_register_match "f$i" "cf$i" 0
+ }
+
+ for {set i 0} {$i < 64} {incr i 1} {
+ test_register_match "vs$i.uint128" "cvs$i" 1
+ }
+}
+