]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/testsuite/gdb.arch/powerpc-htm-regs.exp
aae33d454d396ef2c4fe6b848f6cf8c13783e638
[thirdparty/binutils-gdb.git] / gdb / testsuite / gdb.arch / powerpc-htm-regs.exp
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
28 if {![istarget "powerpc*-*-linux*"]} then {
29 verbose "Skipping PowerPC test for HTM registers."
30 return
31 }
32
33 standard_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
38 proc 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
55 proc 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
73 with_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.
133 if {[build_executable "compile" $binfile $srcfile {debug}] == -1} {
134 return
135 }
136
137 clean_restart $binfile
138
139 gdb_breakpoint [gdb_get_line_number "first marker"] temporary
140
141 gdb_run_cmd
142
143 # Wait for the prompt.
144 gdb_test "" "Temporary breakpoint.*"
145
146 if {[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
155 for {set i 0} {$i < 32} {incr i 1} {
156 gdb_test_no_output "set \$r$i = $i"
157 }
158
159 gdb_test_no_output "set \$xer = 0xc0000000"
160
161 # FPRs
162 gdb_test_no_output "set \$f0 = 0.5"
163 for {set i 1} {$i < 32} {incr i 1} {
164 gdb_test_no_output "set \$f$i = \$f[expr $i - 1] + 1.0"
165 }
166
167 gdb_test_no_output "set \$fpscr = 0x84005000"
168
169 # VRs
170 for {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
176 gdb_test_no_output "set \$dscr = 0x2"
177 gdb_test_no_output "set \$tar = &main" "set tar"
178
179 # Get the pre-transactional value of the registers.
180 for {set i 0} {$i < 32} {incr i 1} {
181 set "r$i" [get_hexadecimal_valueof "\$r$i" "default0"]
182 }
183
184 set cr [get_hexadecimal_valueof "\$cr" "default0"]
185 set xer [get_hexadecimal_valueof "\$xer" "default0"]
186 set lr [get_hexadecimal_valueof "\$lr" "default0"]
187 set ctr [get_hexadecimal_valueof "\$ctr" "default0"]
188
189 for {set i 0} {$i < 32} {incr i 1} {
190 set "f$i" [get_valueof "" "\$f$i" "default0"]
191 }
192
193 set fpscr [get_hexadecimal_valueof "\$fpscr" "default0"]
194
195 for {set i 0} {$i < 32} {incr i 1} {
196 set "vr$i" [get_hexadecimal_valueof "\$vr$i.uint128" "default0"]
197 }
198
199 set vscr [get_hexadecimal_valueof "\$vscr" "default0"]
200 set vrsave [get_hexadecimal_valueof "\$vrsave" "default0"]
201
202 for {set i 0} {$i < 64} {incr i 1} {
203 set "vs$i" [get_hexadecimal_valueof "\$vs$i.uint128" "default0"]
204 }
205
206 set dscr [get_hexadecimal_valueof "\$dscr" "default0"]
207 set ppr [get_hexadecimal_valueof "\$ppr" "default0"]
208 set tar [get_hexadecimal_valueof "\$tar" "default0"]
209
210 gdb_test "stepi" "asm.*bc.*"
211
212 proc 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
241 for {set i 0} {$i < 32} {incr i 1} {
242 test_register_match "cr$i" "r$i" 1
243 }
244
245 test_register_match "ccr" "cr" 1
246 test_register_match "cxer" "xer" 1
247 test_register_match "clr" "lr" 1
248 test_register_match "cctr" "ctr" 1
249
250 for {set i 0} {$i < 32} {incr i 1} {
251 test_register_match "cf$i" "f$i" 0
252 }
253
254 test_register_match "cfpscr" "fpscr" 1
255
256 for {set i 0} {$i < 32} {incr i 1} {
257 test_register_match "cvr$i.uint128" "vr$i" 1
258 }
259
260 test_register_match "cvscr" "vscr" 1
261 test_register_match "cvrsave" "vrsave" 1
262
263 for {set i 0} {$i < 64} {incr i 1} {
264 test_register_match "cvs$i.uint128" "vs$i" 1
265 }
266
267 test_register_match "cdscr" "dscr" 1
268 test_register_match "cppr" "ppr" 1
269 test_register_match "ctar" "tar" 1
270
271 # Support for writing to the checkpointed registers is not
272 # currently available in the gdbserver stub.
273 if [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.
281 for {set i 0} {$i < 32} {incr i 1} {
282 gdb_test_no_output "set \$cr$i = $i + 0xC00"
283 }
284
285 gdb_test_no_output "set \$cf0 = 0.25"
286 for {set i 1} {$i < 32} {incr i 1} {
287 gdb_test_no_output "set \$cf$i = \$cf[expr $i - 1] + 1.0"
288 }
289
290 for {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.
297 with_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
311 gdb_breakpoint [gdb_get_line_number "second marker"]
312
313 gdb_test "continue"
314
315 with_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