blob: f8e2b54688fca487517e5d2444ad07bf0ca7626d [file] [log] [blame]
# Copyright 2010-2012 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 single stepping over Thumb-2 IT blocks.
if {![istarget arm*-*eabi*]} then {
verbose "Skipping Thumb-2 tests."
return
}
set testfile "thumb2-it"
set srcfile ${testfile}.S
set binfile ${objdir}/${subdir}/${testfile}
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable debug] != "" } {
untested thumb2-it.exp
return -1
}
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}
if ![runto_main] then {
untested thumb2-it.exp
return -1
}
# Make sure that the compiler options allow Thumb-2.
gdb_test_multiple "list" "list main" {
-re ".*@ No Thumb-2.*$gdb_prompt $" {
pass "list main"
untested thumb2-it.exp
return -1
}
-re ".*@ Thumb-2 OK.*$gdb_prompt $" {
pass "list main"
}
}
proc test_it_block { func } {
global gdb_prompt
global software_step
if { ! [gdb_breakpoint "*${func}"] } {
unresolved "$func, IT block tests"
return
}
gdb_test "call ${func}()" "Breakpoint.*@ Setup.*" "$func, call"
set expected 0
set reached 0
set steps 0
set ok 1
while { $ok } {
set ok 0
set msg "$func, stepi $steps"
gdb_test_multiple "stepi" "$msg" {
-re ".*@ Setup.*$gdb_prompt $" {
pass "$msg"
set ok 1
}
-re ".*@ IT instruction, Expected == (\[0-9\]*)\r\n$gdb_prompt $" {
set expected $expect_out(1,string)
pass "$msg"
set ok 1
}
-re ".*@ Reached.*$gdb_prompt $" {
incr reached
pass "$msg"
set ok 1
if { [regexp {@ Reached, Set ([^\r\n]*)\r\n} $expect_out(0,string) dummy change] } {
gdb_test "set $change" "" "$func, set $change"
}
}
-re ".*@ Not reached.*$gdb_prompt $" {
# An instruction in an IT block whose predicate is false when
# we reach it. If using software single step, we should not
# stop here.
if { $software_step } {
fail "$msg"
} else {
pass "$msg"
set ok 1
}
}
-re ".*@ Never reached.*$gdb_prompt $" {
# An instruction that should be branched over.
fail "$msg"
}
-re ".*@ Done.*$gdb_prompt $" {
pass "$msg"
if { $reached == $expected } {
pass "$func, correct instructions reached"
} else {
fail "$func, correct instructions reached"
}
if { [regexp {@ Done, Check ([^\r\n]*)\r\n} $expect_out(0,string) dummy check] } {
gdb_test "print $check" ".* = 1" "$func, $check"
}
}
}
if { ! $ok } {
break
}
incr steps
continue
}
gdb_test "continue" "" "$func, continue"
return
}
proc test_it_break { ndx } {
global software_step
set line [gdb_get_line_number "@ Break ${ndx}"]
if { ! [gdb_breakpoint "${line}"] } {
unresolved "continue to breakpoint: test ${ndx}"
return
}
if { $software_step } {
gdb_continue_to_breakpoint "test ${ndx}" ".*@ Location ${ndx}.*"
} else {
gdb_continue_to_breakpoint "test ${ndx}" ".*@ Break ${ndx}.*"
}
}
# If we are using software single-stepping in GDB, then GDB will not
# stop at conditional instructions with a false predicate during stepi.
# If we are using a simulator or debug interface with hardware single
# step, then GDB will stop at such instructions.
if { [istarget arm*-linux*] } {
set software_step 1
} else {
set software_step 0
}
for { set i 1 } { $i <= 8 } { incr i } {
test_it_block it_${i}
}
gdb_breakpoint "*it_breakpoints"
gdb_test "call it_breakpoints()" "Breakpoint.*"
for { set i 1 } { $i <= 7 } { incr i } {
test_it_break ${i}
}