Re: ld plugin bfd_make_readable leak
[binutils-gdb.git] / gdb / testsuite / gdb.arch / powerpc-htm-regs.exp
blob59a4d4743c7816c73cf9a09899949fcf47de7ffc
1 # Copyright (C) 2018-2024 Free Software Foundation, Inc.
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.
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.
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/>.
16 # This file is part of the gdb testsuite.
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.
28 require {istarget "powerpc*-*-linux*"}
30 standard_testfile .c .gen.c
32 # First check if our processor and kernel support access to
33 # the registers we need and to the HTM facility.
35 proc check_register_access { regname } {
36     global gdb_prompt
38     set test "$regname register access"
39     gdb_test_multiple "info reg $regname" "$test" {
40         -re "Invalid register.*\r\n$gdb_prompt $" {
41             unsupported "$test"
42             return 0
43         }
44         -re "\r\n$regname.*\r\n$gdb_prompt $" {
45             pass "$test"
46             return 1
47         }
48     }
49     return 0
52 proc check_htm_support {} {
53     global gdb_prompt
54     set test "htm support"
56     gdb_test_multiple "stepi" "$test" {
57         -re "Illegal instruction.*\r\n$gdb_prompt $" {
58             unsupported $test
59             return 0
60         }
61         -re "nop.*\r\n$gdb_prompt $"
62         {
63             pass $test
64             return 1
65         }
66     }
67     return 0;
70 with_test_prefix "check htm support" {
71     set gen_src [standard_output_file $srcfile2]
73     gdb_produce_source $gen_src {
74         int main () {
75             asm volatile ("tbegin."); // marker
76             asm volatile ("nop");
77             return 0;
78         }
79     }
81     if {[build_executable "compile" $binfile $gen_src {debug}] == -1} {
82         return
83     }
85     clean_restart $binfile
87     # Displaced-stepping a tbegin. causes problems,
88     # so we make the breakpoint temporary.
89     gdb_breakpoint [gdb_get_line_number "marker" "$gen_src"] temporary
91     gdb_run_cmd
93     # Wait for the prompt.
94     if {[gdb_test "" "Temporary breakpoint.*"] != 0 } {
95         return
96     }
98     # Make sure that we stopped at the right place (just before tbegin. is
99     # executed).
100     if { [gdb_test "x/i \$pc" "=> $hex.*:.*tbegin\\..*" "disassemble tbegin"] != 0} {
101         return
102     }
104     if {![check_register_access "vs0"]} {
105         return
106     }
108     if {![check_register_access "texasr"]} {
109         return
110     }
112     if {![check_register_access "dscr"]} {
113         return
114     }
116     if {![check_register_access "ppr"]} {
117         return
118     }
120     if {![check_register_access "tar"]} {
121         return
122     }
124     if {![check_htm_support]} {
125         return
126     }
129 # Now do the actual test.
130 if {[build_executable "compile" $binfile $srcfile {debug}] == -1} {
131     return
134 clean_restart $binfile
136 gdb_breakpoint [gdb_get_line_number "first marker"] temporary
138 gdb_run_cmd
140 # Wait for the prompt.
141 gdb_test "" "Temporary breakpoint.*"
143 if {[gdb_test "x/i \$pc" "=> $hex.*:.*tbegin\\..*" "disassemble tbegin"] != 0} {
144     return
147 # Now we write non-zero values to some registers, then read the values
148 # of various registers, then stepi to start the transaction.  The
149 # checkpointed register state should correspond to the values we read.
151 # Write to the GPRs
152 for {set i 0} {$i < 32} {incr i 1} {
153     gdb_test_no_output "set \$r$i = $i"
156 gdb_test_no_output "set \$xer = 0xc0000000"
158 # FPRs
159 gdb_test_no_output "set \$f0 = 0.5"
160 for {set i 1} {$i < 32} {incr i 1} {
161     gdb_test_no_output "set \$f$i = \$f[expr $i - 1] + 1.0"
164 gdb_test_no_output "set \$fpscr = 0x84005000"
166 # VRs
167 for {set i 0} {$i < 32} {incr i 1} {
168     for {set j 0} {$j < 4} {incr j 1} {
169         gdb_test_no_output "set \$vr$i.v4_int32\[$j\] = $i"
170     }
173 gdb_test_no_output "set \$dscr = 0x2"
174 gdb_test_no_output "set \$tar = &main" "set tar"
176 # Get the pre-transactional value of the registers.
177 for {set i 0} {$i < 32} {incr i 1} {
178     set "r$i" [get_hexadecimal_valueof "\$r$i" "default0"]
181 set cr [get_hexadecimal_valueof "\$cr" "default0"]
182 set xer [get_hexadecimal_valueof "\$xer" "default0"]
183 set lr [get_hexadecimal_valueof "\$lr" "default0"]
184 set ctr [get_hexadecimal_valueof "\$ctr" "default0"]
186 for {set i 0} {$i < 32} {incr i 1} {
187     set "f$i" [get_valueof "" "\$f$i" "default0"]
190 set fpscr [get_hexadecimal_valueof "\$fpscr" "default0"]
192 for {set i 0} {$i < 32} {incr i 1} {
193     set "vr$i" [get_hexadecimal_valueof "\$vr$i.uint128" "default0"]
196 set vscr [get_hexadecimal_valueof "\$vscr" "default0"]
197 set vrsave [get_hexadecimal_valueof "\$vrsave" "default0"]
199 for {set i 0} {$i < 64} {incr i 1} {
200     set "vs$i" [get_hexadecimal_valueof "\$vs$i.uint128" "default0"]
203 set dscr [get_hexadecimal_valueof "\$dscr" "default0"]
204 set ppr [get_hexadecimal_valueof "\$ppr" "default0"]
205 set tar [get_hexadecimal_valueof "\$tar" "default0"]
207 gdb_test "stepi" "asm.*bc.*"
209 proc test_register_match {reg_name reg_var_name hex} {
210     set test "$reg_name matches $reg_var_name"
212     # In some infrequent cases CXER doesn't match the
213     # pre-transactional XER, possibly due to a linux kernel bug.
214     set should_xfail 0
215     if [istarget "powerpc*-*-linux*" && reg_name == "cxer"] {
216         set should_xfail 1
217     }
219     upvar $reg_var_name expected_val
221     if {$hex} {
222         set actual_val [get_hexadecimal_valueof "\$$reg_name" "default1"]
223     } else {
224         set actual_val [get_valueof "" "\$$reg_name" "default1"]
225     }
227     if { "$expected_val" == "$actual_val" } {
228         pass $test
229     } else {
230         if {$should_xfail} {
231             xfail $test
232         } else {
233             fail $test
234         }
235     }
238 for {set i 0} {$i < 32} {incr i 1} {
239     test_register_match "cr$i" "r$i" 1
242 test_register_match "ccr" "cr" 1
243 test_register_match "cxer" "xer" 1
244 test_register_match "clr" "lr" 1
245 test_register_match "cctr" "ctr" 1
247 for {set i 0} {$i < 32} {incr i 1} {
248     test_register_match "cf$i" "f$i" 0
251 test_register_match "cfpscr" "fpscr" 1
253 for {set i 0} {$i < 32} {incr i 1} {
254     test_register_match "cvr$i.uint128" "vr$i" 1
257 test_register_match "cvscr" "vscr" 1
258 test_register_match "cvrsave" "vrsave" 1
260 for {set i 0} {$i < 64} {incr i 1} {
261     test_register_match "cvs$i.uint128" "vs$i" 1
264 test_register_match "cdscr" "dscr" 1
265 test_register_match "cppr" "ppr" 1
266 test_register_match "ctar" "tar" 1
268 # Support for writing to the checkpointed registers is not
269 # currently available in the gdbserver stub.
270 if [target_is_gdbserver] {
271     unsupported "write to checkpointed registers"
272     return
275 # Now write different values to some of the checkpointed registers and
276 # check that the transaction abort reverts the register to these
277 # values.
278 for {set i 0} {$i < 32} {incr i 1} {
279     gdb_test_no_output "set \$cr$i = $i + 0xC00"
282 gdb_test_no_output "set \$cf0 = 0.25"
283 for {set i 1} {$i < 32} {incr i 1} {
284     gdb_test_no_output "set \$cf$i = \$cf[expr $i - 1] + 1.0"
287 for {set i 0} {$i < 32} {incr i 1} {
288     for {set j 0} {$j < 4} {incr j 1} {
289         gdb_test_no_output "set \$cvr$i.v4_int32\[$j\] = $i + 0xF00"
290     }
293 # Read back the values.
294 with_test_prefix "after write" {
295     for {set i 0} {$i < 32} {incr i 1} {
296         set "cr$i" [get_hexadecimal_valueof "\$cr$i" "default0"]
297     }
299     for {set i 0} {$i < 32} {incr i 1} {
300         set "cf$i" [get_valueof "" "\$cf$i" "default0"]
301     }
303     for {set i 0} {$i < 64} {incr i 1} {
304         set "cvs$i" [get_hexadecimal_valueof "\$cvs$i.uint128" "default0"]
305     }
308 gdb_breakpoint [gdb_get_line_number "second marker"]
310 gdb_test "continue"
312 with_test_prefix "after transaction failure" {
313     for {set i 0} {$i < 32} {incr i 1} {
314         test_register_match "r$i" "cr$i" 1
315     }
317     for {set i 0} {$i < 32} {incr i 1} {
318         test_register_match "f$i" "cf$i" 0
319     }
321     for {set i 0} {$i < 64} {incr i 1} {
322         test_register_match "vs$i.uint128" "cvs$i" 1
323     }