mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-08-06 14:49:38 +08:00
S390: Vector register test case
Add a test case for S/390 vector registers support. gdb/testsuite/ChangeLog: * gdb.arch/s390-vregs.exp: New test. * gdb.arch/s390-vregs.S: New file.
This commit is contained in:

committed by
Andreas Krebbel

parent
bf2d68ab8c
commit
4fa5d7b436
@ -1,3 +1,8 @@
|
||||
2015-03-02 Andreas Arnez <arnez@linux.vnet.ibm.com>
|
||||
|
||||
* gdb.arch/s390-vregs.exp: New test.
|
||||
* gdb.arch/s390-vregs.S: New file.
|
||||
|
||||
2015-02-27 Pedro Alves <palves@redhat.com>
|
||||
|
||||
* gdb.gdb/python-interrupts.exp (test_python_interrupts): Adjust
|
||||
|
96
gdb/testsuite/gdb.arch/s390-vregs.S
Normal file
96
gdb/testsuite/gdb.arch/s390-vregs.S
Normal file
@ -0,0 +1,96 @@
|
||||
/* Copyright 2015 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
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/>. */
|
||||
|
||||
.text
|
||||
|
||||
/* 'check_vx': Yield SIGILL unless vector support is
|
||||
available. Have a "pit stop" breakpoint here. */
|
||||
|
||||
.align 8
|
||||
.type check_vx, @function
|
||||
check_vx:
|
||||
.cfi_startproc
|
||||
/* vlr %v0,%v0 */
|
||||
.byte 0xe7,0x00,0x00,0x00,0x00,0x56
|
||||
br %r14
|
||||
.cfi_endproc
|
||||
.size check_vx, .-check_vx
|
||||
|
||||
|
||||
/* 'store_vrs': Store vector registers in save_area. */
|
||||
|
||||
.align 8
|
||||
.type store_vrs, @function
|
||||
store_vrs:
|
||||
.cfi_startproc
|
||||
larl %r1,save_area
|
||||
/* vstm %v0,%v15,0(%r1) */
|
||||
.byte 0xe7,0x0f,0x10,0x00,0x00,0x3e
|
||||
/* vstm %v16,%v31,256(%r1) */
|
||||
.byte 0xe7,0x0f,0x11,0x00,0x0c,0x3e
|
||||
br %r14
|
||||
.cfi_endproc
|
||||
.size store_vrs, .-store_vrs
|
||||
|
||||
|
||||
/* 'change_vrs': Manipulate vector registers according to a
|
||||
simple algorithm. */
|
||||
|
||||
.align 8
|
||||
.type change_vrs, @function
|
||||
change_vrs:
|
||||
.cfi_startproc
|
||||
lghi %r1,16
|
||||
lghi %r3,0xff
|
||||
1: exrl %r3,2f
|
||||
exrl %r3,1f
|
||||
aghi %r3,-0x11
|
||||
brctg %r1,1b
|
||||
br %r14
|
||||
.cfi_endproc
|
||||
/* vmlf %v0,%v0,%v0 */
|
||||
1: .byte 0xe7,0x00,0x00,0x00,0x20,0xa2
|
||||
/* vmlf %v16,%v16,%v0 */
|
||||
2: .byte 0xe7,0x00,0x00,0x00,0x2c,0xa2
|
||||
|
||||
|
||||
/* 'main': Perform actions according to test case logic.
|
||||
Invoke check_vx whenever a pit stop is required. */
|
||||
|
||||
.section .text.startup,"ax",@progbits
|
||||
.align 8
|
||||
.globl main
|
||||
.type main, @function
|
||||
main:
|
||||
.cfi_startproc
|
||||
stmg %r14,%r15,112(%r15)
|
||||
aghi %r15,-160
|
||||
bras %r14,check_vx
|
||||
bras %r14,store_vrs
|
||||
bras %r14,check_vx
|
||||
bras %r14,change_vrs
|
||||
bras %r14,check_vx
|
||||
lmg %r14,%r15,272(%r15)
|
||||
lghi %r2,0
|
||||
br %r14
|
||||
.cfi_endproc
|
||||
.size main, .-main
|
||||
|
||||
.local save_area
|
||||
.comm save_area,512,16
|
||||
|
||||
.section .note.GNU-stack,"",@progbits
|
202
gdb/testsuite/gdb.arch/s390-vregs.exp
Normal file
202
gdb/testsuite/gdb.arch/s390-vregs.exp
Normal file
@ -0,0 +1,202 @@
|
||||
# Copyright 2015 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/>.
|
||||
|
||||
# Test vector register access for s390 platforms.
|
||||
|
||||
if { ![istarget s390-*-*] && ![istarget s390x-*-* ] } {
|
||||
verbose "Skipping s390 vector register tests."
|
||||
return
|
||||
}
|
||||
|
||||
standard_testfile .S
|
||||
|
||||
if [isnative] {
|
||||
# Create a temporary directory, to take a core dump there later.
|
||||
set coredir [standard_output_file ${testfile}.d]
|
||||
remote_exec build "rm -rf $coredir"
|
||||
remote_exec build "mkdir $coredir"
|
||||
}
|
||||
|
||||
if { [prepare_for_testing ${testfile}.exp $testfile $srcfile] } {
|
||||
return -1
|
||||
}
|
||||
|
||||
if ![runto_main] {
|
||||
untested "could not run to main"
|
||||
return -1
|
||||
}
|
||||
|
||||
# Run to the first vector instruction and step it. If the inferior
|
||||
# doesn't crash, we have vector support.
|
||||
|
||||
gdb_breakpoint "check_vx"
|
||||
gdb_continue_to_breakpoint "first vector insn"
|
||||
set before_pc 0
|
||||
gdb_test_multiple "x/i \$pc" "get PC at vector insn" {
|
||||
-re "(0x\\S+)\\s+\\S+\\s+vlr\\s+.*$gdb_prompt $" {
|
||||
set before_pc $expect_out(1,string)
|
||||
}
|
||||
}
|
||||
|
||||
gdb_test_multiple "stepi" "check for vector support" {
|
||||
-re "Program received signal SIGILL,.*\r\n$gdb_prompt $" {
|
||||
unsupported "no vector support."
|
||||
return
|
||||
}
|
||||
-re "\[0-9\]+.*\r\n$gdb_prompt $" {
|
||||
pass "vector support available"
|
||||
}
|
||||
-re "$gdb_prompt $" {
|
||||
fail "no vector support (unknown error)"
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
# Has the PC advanced by the expected amount? The kernel may do
|
||||
# something special for the first vector insn in the process.
|
||||
|
||||
set after_pc 0
|
||||
gdb_test_multiple "x/i \$pc" "get PC after vector insn" {
|
||||
-re "(0x\\S+)\\s+.*$gdb_prompt $" {
|
||||
set after_pc $expect_out(1,string)
|
||||
}
|
||||
}
|
||||
|
||||
if [expr $before_pc + 6 != $after_pc] {
|
||||
fail "stepping first vector insn"
|
||||
}
|
||||
|
||||
# Lift the core file limit, if possible, and change into the temporary
|
||||
# directory.
|
||||
|
||||
if { $coredir != "" } {
|
||||
gdb_test {print setrlimit (4, &(unsigned long [2]){~0UL, ~0UL})} \
|
||||
" = .*" "setrlimit"
|
||||
gdb_test "print chdir (\"${coredir}\")" " = 0" "chdir"
|
||||
}
|
||||
|
||||
# Initialize all vector registers with GDB "set" commands, using
|
||||
# distinct values. Handle left and right halves separately, in
|
||||
# pseudo-random order.
|
||||
|
||||
set a_high 1
|
||||
set a_low 2
|
||||
set b_high 3
|
||||
set b_low 5
|
||||
|
||||
set a [expr ($a_high << 32) | $a_low]
|
||||
set b [expr ($b_high << 32) | $b_low]
|
||||
|
||||
for {set j 0} {$j < 32} {incr j 1} {
|
||||
set i [expr 17 * $j % 32]
|
||||
gdb_test_no_output \
|
||||
"set \$v$i.v2_int64\[0\] = [expr $a * ($i + 1)]" \
|
||||
"set v$i left"
|
||||
set i [expr 19 * (31 - $j) % 32]
|
||||
gdb_test_no_output \
|
||||
"set \$v$i.v2_int64\[1\] = [expr $b * (32 - $i)]" \
|
||||
"set v$i right"
|
||||
}
|
||||
|
||||
# Verify a vector register's union members.
|
||||
|
||||
gdb_test "info register v0 v31" \
|
||||
"v4_float .* v2_double .* v16_int8 .* v8_int16 .* v4_int32 .* v2_int64 .* uint128\
|
||||
.*v4_float .* v2_double .* v16_int8 .* v8_int16 .* v4_int32 .* v2_int64 .* uint128 .*"
|
||||
|
||||
# Let the inferior store all vector registers in a buffer, then dump
|
||||
# the buffer and check it.
|
||||
|
||||
gdb_continue_to_breakpoint "store vrs"
|
||||
set vregs [capture_command_output "x/64xg &save_area" ""]
|
||||
|
||||
set i 0
|
||||
foreach {- left right} [regexp -all -inline -line {^.*:\s+(\w+)\s+(\w+)} $vregs] {
|
||||
if [expr $left != $a * ($i + 1) || $right != $b * (32 - $i)] {
|
||||
fail "verify \$v$i after set"
|
||||
}
|
||||
if { $i < 16 } {
|
||||
# Check that the FP register was updated accordingly.
|
||||
gdb_test "info register f$i" "raw ${left}.*"
|
||||
}
|
||||
incr i 1
|
||||
}
|
||||
|
||||
if { $i != 32 } {
|
||||
fail "dump save area (bad output)"
|
||||
}
|
||||
|
||||
# Let the inferior change all VRs according to a simple algorithm,
|
||||
# then print all VRs and compare their values with our result of the
|
||||
# same algorithm.
|
||||
|
||||
gdb_continue_to_breakpoint "change vrs"
|
||||
set vregs [capture_command_output "info registers vector" ""]
|
||||
|
||||
set j 1
|
||||
foreach {- r i val} [regexp -all -inline -line \
|
||||
{^(\D*)(\d+)\s+.*?uint128 = 0x([0-9a-f]+?)} $vregs] {
|
||||
if { $r ne "v" } {
|
||||
fail "info registers vector: bad line $j"
|
||||
} elseif { $val ne [format %08x%08x%08x%08x \
|
||||
[expr $a_high * ($i + 1) * $a_high ] \
|
||||
[expr $a_low * ($i + 1) * $a_low ] \
|
||||
[expr $b_high * (32 - $i) * $b_high * 32] \
|
||||
[expr $b_low * (32 - $i) * $b_low * 32] ] } {
|
||||
fail "compare \$v$i"
|
||||
}
|
||||
incr j 1
|
||||
}
|
||||
|
||||
if { $j != 33 } {
|
||||
fail "info registers vector"
|
||||
}
|
||||
|
||||
if { $coredir == "" } {
|
||||
return
|
||||
}
|
||||
|
||||
# Take a core dump.
|
||||
|
||||
gdb_test "signal SIGABRT" "Program terminated with signal SIGABRT, .*"
|
||||
gdb_exit
|
||||
|
||||
# Find the core file and rename it (avoid accumulating core files).
|
||||
|
||||
set cores [glob -nocomplain -directory $coredir *core*]
|
||||
if {[llength $cores] != 1} {
|
||||
untested "core file not found"
|
||||
remote_exec build "rm -rf $coredir"
|
||||
return -1
|
||||
}
|
||||
set destcore [standard_output_file ${testfile}.core]
|
||||
remote_exec build "mv [file join $coredir [lindex $cores 0]] $destcore"
|
||||
remote_exec build "rm -rf $coredir"
|
||||
|
||||
# Restart gdb and load the core file. Compare the VRs.
|
||||
|
||||
clean_restart ${testfile}
|
||||
|
||||
with_test_prefix "core" {
|
||||
set core_loaded [gdb_core_cmd $destcore "load"]
|
||||
if { $core_loaded != -1 } {
|
||||
set vregs_from_core [capture_command_output "info registers vector" ""]
|
||||
if { $vregs_from_core eq $vregs } {
|
||||
pass "compare vector registers"
|
||||
} else {
|
||||
fail "vector registers mismatch"
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user