xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/testsuite/gdb.arch/s390-vregs.exp (revision 7d62b00eb9ad855ffcd7da46b41e23feb5476fac)
1# Copyright 2015-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# Test vector register access for s390 platforms.
17
18if { ![istarget s390-*-*] && ![istarget s390x-*-* ] } {
19    verbose "Skipping s390 vector register tests."
20    return
21}
22
23standard_testfile .S
24
25if [isnative] {
26    # Create a temporary directory, to take a core dump there later.
27    set coredir [standard_output_file ${testfile}.d]
28    remote_exec build "rm -rf $coredir"
29    remote_exec build "mkdir $coredir"
30}
31
32if { [prepare_for_testing "failed to prepare" $testfile $srcfile \
33	  [list "additional_flags=-mzarch"]] } {
34    return -1
35}
36
37if ![runto_main] {
38    untested "could not run to main"
39    return -1
40}
41
42# Run to the first vector instruction and step it.  If the inferior
43# doesn't crash, we have vector support.
44
45gdb_breakpoint "check_vx"
46gdb_continue_to_breakpoint "first vector insn"
47set before_pc 0
48gdb_test_multiple "x/i \$pc" "get PC at vector insn" {
49    -re "(0x\\S+)\\s+\\S+\\s+vlr\\s+.*$gdb_prompt $" {
50	set before_pc $expect_out(1,string)
51    }
52}
53
54gdb_test_multiple "stepi" "check for vector support" {
55    -re "Program received signal SIGILL,.*\r\n$gdb_prompt $" {
56	unsupported "no vector support."
57	return
58    }
59    -re "\[0-9\]+.*\r\n$gdb_prompt $" {
60	pass "vector support available"
61    }
62    -re "$gdb_prompt $" {
63	fail "no vector support (unknown error)"
64	return
65    }
66}
67
68# Has the PC advanced by the expected amount?  The kernel may do
69# something special for the first vector insn in the process.
70
71set after_pc 0
72gdb_test_multiple "x/i \$pc" "get PC after vector insn" {
73    -re "(0x\\S+)\\s+.*$gdb_prompt $" {
74	set after_pc $expect_out(1,string)
75    }
76}
77
78if [expr $before_pc + 6 != $after_pc] {
79    fail "stepping first vector insn"
80}
81
82# Lift the core file limit, if possible, and change into the temporary
83# directory.
84
85if { $coredir != "" } {
86    gdb_test {print (int) setrlimit (4, &(unsigned long [2]){~0UL, ~0UL})} \
87	" = .*" "setrlimit"
88    gdb_test "print (int) chdir (\"${coredir}\")" " = 0" "chdir"
89}
90
91# Initialize all vector registers with GDB "set" commands, using
92# distinct values.  Handle left and right halves separately, in
93# pseudo-random order.
94
95set a_high 1
96set a_low 2
97set b_high 3
98set b_low 5
99
100set a [expr ($a_high << 32) | $a_low]
101set b [expr ($b_high << 32) | $b_low]
102
103for {set j 0} {$j < 32} {incr j 1} {
104    set i [expr 17 * $j % 32]
105    gdb_test_no_output \
106	"set \$v$i.v2_int64\[0\] = [expr $a * ($i + 1)]" \
107	"set v$i left"
108    set i [expr 19 * (31 - $j) % 32]
109    gdb_test_no_output \
110	"set \$v$i.v2_int64\[1\] = [expr $b * (32 - $i)]" \
111	"set v$i right"
112}
113
114# Verify a vector register's union members.
115
116gdb_test "info register v0 v31" \
117    "v4_float .* v2_double .* v16_int8 .* v8_int16 .* v4_int32 .* v2_int64 .* uint128\
118     .*v4_float .* v2_double .* v16_int8 .* v8_int16 .* v4_int32 .* v2_int64 .* uint128 .*"
119
120# Let the inferior store all vector registers in a buffer, then dump
121# the buffer and check it.
122
123gdb_continue_to_breakpoint "store vrs"
124set vregs [capture_command_output "x/64xg &save_area" ""]
125
126set i 0
127foreach {- left right} [regexp -all -inline -line {^.*:\s+(\w+)\s+(\w+)} $vregs] {
128    if [expr $left != $a * ($i + 1) || $right != $b * (32 - $i)] {
129	fail "verify \$v$i after set"
130    }
131    if { $i < 16 } {
132	# Check that the FP register was updated accordingly.
133	gdb_test "info register f$i" "raw ${left}.*"
134    }
135    incr i 1
136}
137
138if { $i != 32 } {
139    fail "dump save area (bad output)"
140}
141
142# Let the inferior change all VRs according to a simple algorithm,
143# then print all VRs and compare their values with our result of the
144# same algorithm.
145
146gdb_continue_to_breakpoint "change vrs"
147set vregs [capture_command_output "info registers vector" ""]
148
149# Format a 128-bit value, given individual 4-byte values, as hex.
150# Suppress leading zeros.
151proc hex128 {a_high a_low b_high b_low} {
152    set result [format "%x%08x%08x%08x" $a_high $a_low $b_high $b_low]
153    regsub -- "^0*" $result "" result
154    if { $result eq "" } { set result 0 }
155    return $result
156}
157
158set j 1
159foreach {- r i val} [regexp -all -inline -line \
160			 {^(\D*)(\d+)\s+.*?uint128 = 0x([0-9a-f]+?)} $vregs] {
161    if { $r ne "v" } {
162	fail "info registers vector: bad line $j"
163    } elseif { $val ne [hex128 \
164			    [expr $a_high * ($i + 1) * $a_high ] \
165			    [expr $a_low * ($i + 1) * $a_low ] \
166			    [expr $b_high * (32 - $i) * $b_high * 32] \
167			    [expr $b_low * (32 - $i) * $b_low * 32] ] } {
168	fail "compare \$v$i"
169    }
170    incr j 1
171}
172
173if { $j != 33 } {
174    fail "info registers vector"
175}
176
177if { $coredir == "" } {
178    return
179}
180
181# Take a core dump.
182
183gdb_test "signal SIGABRT" "Program terminated with signal SIGABRT, .*"
184gdb_exit
185
186# Find the core file and rename it (avoid accumulating core files).
187
188set cores [glob -nocomplain -directory $coredir *core*]
189if {[llength $cores] != 1} {
190    untested "core file not found"
191    remote_exec build "rm -rf $coredir"
192    return -1
193}
194set destcore [standard_output_file ${testfile}.core]
195remote_exec build "mv [file join $coredir [lindex $cores 0]] $destcore"
196remote_exec build "rm -rf $coredir"
197
198# Restart gdb and load the core file.  Compare the VRs.
199
200clean_restart ${testfile}
201
202with_test_prefix "core" {
203    set core_loaded [gdb_core_cmd $destcore "load"]
204    if { $core_loaded != -1 } {
205	set vregs_from_core [capture_command_output "info registers vector" ""]
206	if { $vregs_from_core eq $vregs } {
207	    pass "compare vector registers"
208	} else {
209	    fail "vector registers mismatch"
210	}
211    }
212}
213