1# Copyright (C) 2018-2020 Free Software Foundation, Inc. 2 3# This program is free software; you can redistribute it and/or modify 4# it under the terms of the GNU General Public License as published by 5# the Free Software Foundation; either version 3 of the License, or 6# (at your option) any later version. 7# 8# This program is distributed in the hope that it will be useful, 9# but WITHOUT ANY WARRANTY; without even the implied warranty of 10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11# GNU General Public License for more details. 12# 13# You should have received a copy of the GNU General Public License 14# along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16# This file is part of the gdb testsuite. 17 18# Test access to HTM (Hardware Transactional Memory) registers. The 19# tests read the values of various registers before stepping the 20# inferior through a "tbegin." instruction to start a transaction, 21# then the checkpointed versions of the registers are checked against 22# the pre-transactional values. Then, new values are written to some 23# of the checkpointed registers, these values are read back and saved, 24# the inferior continues until the transaction aborts, and the regular 25# registers are then checked against the saved values, because the 26# abort should have reverted the registers to these values. 27 28if {![istarget "powerpc*-*-linux*"]} then { 29 verbose "Skipping PowerPC test for HTM registers." 30 return 31} 32 33standard_testfile .c .gen.c 34 35# First check if our processor and kernel support access to 36# the registers we need and to the HTM facility. 37 38proc check_register_access { regname } { 39 global gdb_prompt 40 41 set test "$regname register access" 42 gdb_test_multiple "info reg $regname" "$test" { 43 -re "Invalid register.*\r\n$gdb_prompt $" { 44 unsupported "$test" 45 return 0 46 } 47 -re "\r\n$regname.*\r\n$gdb_prompt $" { 48 pass "$test" 49 return 1 50 } 51 } 52 return 0 53} 54 55proc check_htm_support {} { 56 global gdb_prompt 57 set test "htm support" 58 59 gdb_test_multiple "stepi" "$test" { 60 -re "Illegal instruction.*\r\n$gdb_prompt $" { 61 unsupported $test 62 return 0 63 } 64 -re "nop.*\r\n$gdb_prompt $" 65 { 66 pass $test 67 return 1 68 } 69 } 70 return 0; 71} 72 73with_test_prefix "check htm support" { 74 set gen_src [standard_output_file $srcfile2] 75 76 gdb_produce_source $gen_src { 77 int main () { 78 asm volatile ("tbegin."); // marker 79 asm volatile ("nop"); 80 return 0; 81 } 82 } 83 84 if {[build_executable "compile" $binfile $gen_src {debug}] == -1} { 85 return 86 } 87 88 clean_restart $binfile 89 90 # Displaced-stepping a tbegin. causes problems, 91 # so we make the breakpoint temporary. 92 gdb_breakpoint [gdb_get_line_number "marker" "$gen_src"] temporary 93 94 gdb_run_cmd 95 96 # Wait for the prompt. 97 if {[gdb_test "" "Temporary breakpoint.*"] != 0 } { 98 return 99 } 100 101 # Make sure that we stopped at the right place (just before tbegin. is 102 # executed). 103 if { [gdb_test "x/i \$pc" "=> $hex.*:.*tbegin\\..*" "disassemble tbegin"] != 0} { 104 return 105 } 106 107 if {![check_register_access "vs0"]} { 108 return 109 } 110 111 if {![check_register_access "texasr"]} { 112 return 113 } 114 115 if {![check_register_access "dscr"]} { 116 return 117 } 118 119 if {![check_register_access "ppr"]} { 120 return 121 } 122 123 if {![check_register_access "tar"]} { 124 return 125 } 126 127 if {![check_htm_support]} { 128 return 129 } 130} 131 132# Now do the actual test. 133if {[build_executable "compile" $binfile $srcfile {debug}] == -1} { 134 return 135} 136 137clean_restart $binfile 138 139gdb_breakpoint [gdb_get_line_number "first marker"] temporary 140 141gdb_run_cmd 142 143# Wait for the prompt. 144gdb_test "" "Temporary breakpoint.*" 145 146if {[gdb_test "x/i \$pc" "=> $hex.*:.*tbegin\\..*" "disassemble tbegin"] != 0} { 147 return 148} 149 150# Now we write non-zero values to some registers, then read the values 151# of various registers, then stepi to start the transaction. The 152# checkpointed register state should correspond to the values we read. 153 154# Write to the GPRs 155for {set i 0} {$i < 32} {incr i 1} { 156 gdb_test_no_output "set \$r$i = $i" 157} 158 159gdb_test_no_output "set \$xer = 0xc0000000" 160 161# FPRs 162gdb_test_no_output "set \$f0 = 0.5" 163for {set i 1} {$i < 32} {incr i 1} { 164 gdb_test_no_output "set \$f$i = \$f[expr $i - 1] + 1.0" 165} 166 167gdb_test_no_output "set \$fpscr = 0x84005000" 168 169# VRs 170for {set i 0} {$i < 32} {incr i 1} { 171 for {set j 0} {$j < 4} {incr j 1} { 172 gdb_test_no_output "set \$vr$i.v4_int32\[$j\] = $i" 173 } 174} 175 176gdb_test_no_output "set \$dscr = 0x2" 177gdb_test_no_output "set \$tar = &main" "set tar" 178 179# Get the pre-transactional value of the registers. 180for {set i 0} {$i < 32} {incr i 1} { 181 set "r$i" [get_hexadecimal_valueof "\$r$i" "default0"] 182} 183 184set cr [get_hexadecimal_valueof "\$cr" "default0"] 185set xer [get_hexadecimal_valueof "\$xer" "default0"] 186set lr [get_hexadecimal_valueof "\$lr" "default0"] 187set ctr [get_hexadecimal_valueof "\$ctr" "default0"] 188 189for {set i 0} {$i < 32} {incr i 1} { 190 set "f$i" [get_valueof "" "\$f$i" "default0"] 191} 192 193set fpscr [get_hexadecimal_valueof "\$fpscr" "default0"] 194 195for {set i 0} {$i < 32} {incr i 1} { 196 set "vr$i" [get_hexadecimal_valueof "\$vr$i.uint128" "default0"] 197} 198 199set vscr [get_hexadecimal_valueof "\$vscr" "default0"] 200set vrsave [get_hexadecimal_valueof "\$vrsave" "default0"] 201 202for {set i 0} {$i < 64} {incr i 1} { 203 set "vs$i" [get_hexadecimal_valueof "\$vs$i.uint128" "default0"] 204} 205 206set dscr [get_hexadecimal_valueof "\$dscr" "default0"] 207set ppr [get_hexadecimal_valueof "\$ppr" "default0"] 208set tar [get_hexadecimal_valueof "\$tar" "default0"] 209 210gdb_test "stepi" "asm.*bc.*" 211 212proc test_register_match {reg_name reg_var_name hex} { 213 set test "$reg_name matches $reg_var_name" 214 215 # In some infrequent cases CXER doesn't match the 216 # pre-transactional XER, possibly due to a linux kernel bug. 217 set should_xfail 0 218 if [istarget "powerpc*-*-linux*" && reg_name == "cxer"] { 219 set should_xfail 1 220 } 221 222 upvar $reg_var_name expected_val 223 224 if {$hex} { 225 set actual_val [get_hexadecimal_valueof "\$$reg_name" "default1"] 226 } else { 227 set actual_val [get_valueof "" "\$$reg_name" "default1"] 228 } 229 230 if { "$expected_val" == "$actual_val" } { 231 pass $test 232 } else { 233 if {$should_xfail} { 234 xfail $test 235 } else { 236 fail $test 237 } 238 } 239} 240 241for {set i 0} {$i < 32} {incr i 1} { 242 test_register_match "cr$i" "r$i" 1 243} 244 245test_register_match "ccr" "cr" 1 246test_register_match "cxer" "xer" 1 247test_register_match "clr" "lr" 1 248test_register_match "cctr" "ctr" 1 249 250for {set i 0} {$i < 32} {incr i 1} { 251 test_register_match "cf$i" "f$i" 0 252} 253 254test_register_match "cfpscr" "fpscr" 1 255 256for {set i 0} {$i < 32} {incr i 1} { 257 test_register_match "cvr$i.uint128" "vr$i" 1 258} 259 260test_register_match "cvscr" "vscr" 1 261test_register_match "cvrsave" "vrsave" 1 262 263for {set i 0} {$i < 64} {incr i 1} { 264 test_register_match "cvs$i.uint128" "vs$i" 1 265} 266 267test_register_match "cdscr" "dscr" 1 268test_register_match "cppr" "ppr" 1 269test_register_match "ctar" "tar" 1 270 271# Support for writing to the checkpointed registers is not 272# currently available in the gdbserver stub. 273if [target_is_gdbserver] { 274 unsupported "write to checkpointed registers" 275 return 276} 277 278# Now write different values to some of the checkpointed registers and 279# check that the transaction abort reverts the register to these 280# values. 281for {set i 0} {$i < 32} {incr i 1} { 282 gdb_test_no_output "set \$cr$i = $i + 0xC00" 283} 284 285gdb_test_no_output "set \$cf0 = 0.25" 286for {set i 1} {$i < 32} {incr i 1} { 287 gdb_test_no_output "set \$cf$i = \$cf[expr $i - 1] + 1.0" 288} 289 290for {set i 0} {$i < 32} {incr i 1} { 291 for {set j 0} {$j < 4} {incr j 1} { 292 gdb_test_no_output "set \$cvr$i.v4_int32\[$j\] = $i + 0xF00" 293 } 294} 295 296# Read back the values. 297with_test_prefix "after write" { 298 for {set i 0} {$i < 32} {incr i 1} { 299 set "cr$i" [get_hexadecimal_valueof "\$cr$i" "default0"] 300 } 301 302 for {set i 0} {$i < 32} {incr i 1} { 303 set "cf$i" [get_valueof "" "\$cf$i" "default0"] 304 } 305 306 for {set i 0} {$i < 64} {incr i 1} { 307 set "cvs$i" [get_hexadecimal_valueof "\$cvs$i.uint128" "default0"] 308 } 309} 310 311gdb_breakpoint [gdb_get_line_number "second marker"] 312 313gdb_test "continue" 314 315with_test_prefix "after transaction failure" { 316 for {set i 0} {$i < 32} {incr i 1} { 317 test_register_match "r$i" "cr$i" 1 318 } 319 320 for {set i 0} {$i < 32} {incr i 1} { 321 test_register_match "f$i" "cf$i" 0 322 } 323 324 for {set i 0} {$i < 64} {incr i 1} { 325 test_register_match "vs$i.uint128" "cvs$i" 1 326 } 327} 328 329