1# Copyright 2010-2023 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 single stepping over Thumb-2 IT blocks. 17 18if {![istarget arm*-*eabi*]} { 19 verbose "Skipping Thumb-2 tests." 20 return 21} 22 23standard_testfile .S 24 25if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable debug] != "" } { 26 untested "failed to compile" 27 return -1 28} 29 30gdb_exit 31gdb_start 32gdb_reinitialize_dir $srcdir/$subdir 33gdb_load ${binfile} 34 35if {![runto_main]} { 36 return -1 37} 38 39# Make sure that the compiler options allow Thumb-2. 40gdb_test_multiple "list" "list main" { 41 -re ".*@ No Thumb-2.*$gdb_prompt $" { 42 pass "list main" 43 untested "skipping tests due to lack of Thumb-2" 44 return -1 45 } 46 -re ".*@ Thumb-2 OK.*$gdb_prompt $" { 47 pass "list main" 48 } 49} 50 51proc test_it_block { func } { 52 global gdb_prompt 53 global software_step 54 55 if { ! [gdb_breakpoint "*${func}"] } { 56 unresolved "$func, IT block tests" 57 return 58 } 59 60 gdb_test "call (int) ${func}()" "Breakpoint.*@ Setup.*" "$func, call" 61 62 set expected 0 63 set reached 0 64 set steps 0 65 set ok 1 66 while { $ok } { 67 set ok 0 68 set msg "$func, stepi $steps" 69 gdb_test_multiple "stepi" "$msg" { 70 -re ".*@ Setup.*$gdb_prompt $" { 71 pass "$msg" 72 set ok 1 73 } 74 -re ".*@ IT instruction, Expected == (\[0-9\]*)\r\n$gdb_prompt $" { 75 set expected $expect_out(1,string) 76 pass "$msg" 77 set ok 1 78 } 79 -re ".*@ Reached.*$gdb_prompt $" { 80 incr reached 81 pass "$msg" 82 set ok 1 83 if { [regexp {@ Reached, Set ([^\r\n]*)\r\n} $expect_out(0,string) dummy change] } { 84 gdb_test "set $change" "" "$func, set $change" 85 } 86 } 87 -re ".*@ Not reached.*$gdb_prompt $" { 88 # An instruction in an IT block whose predicate is false when 89 # we reach it. If using software single step, we should not 90 # stop here. 91 if { $software_step } { 92 fail "$msg" 93 } else { 94 pass "$msg" 95 set ok 1 96 } 97 } 98 -re ".*@ Never reached.*$gdb_prompt $" { 99 # An instruction that should be branched over. 100 fail "$msg" 101 } 102 -re ".*@ Done.*$gdb_prompt $" { 103 pass "$msg" 104 if { $reached == $expected } { 105 pass "$func, correct instructions reached" 106 } else { 107 fail "$func, correct instructions reached" 108 } 109 if { [regexp {@ Done, Check ([^\r\n]*)\r\n} $expect_out(0,string) dummy check] } { 110 gdb_test "print $check" ".* = 1" "$func, $check" 111 } 112 } 113 } 114 if { ! $ok } { 115 break 116 } 117 incr steps 118 continue 119 } 120 121 gdb_test "continue" "" "$func, continue" 122 return 123} 124 125proc test_it_break { ndx } { 126 global software_step 127 128 set line [gdb_get_line_number "@ Break ${ndx}"] 129 130 if { ! [gdb_breakpoint "${line}"] } { 131 unresolved "continue to breakpoint: test ${ndx}" 132 return 133 } 134 135 if { $software_step } { 136 gdb_continue_to_breakpoint "test ${ndx}" ".*@ Location ${ndx}.*" 137 } else { 138 gdb_continue_to_breakpoint "test ${ndx}" ".*@ Break ${ndx}.*" 139 } 140} 141 142# If we are using software single-stepping in GDB, then GDB will not 143# stop at conditional instructions with a false predicate during stepi. 144# If we are using a simulator or debug interface with hardware single 145# step, then GDB will stop at such instructions. 146if { [istarget arm*-linux*] } { 147 set software_step 1 148} else { 149 set software_step 0 150} 151 152for { set i 1 } { $i <= 8 } { incr i } { 153 test_it_block it_${i} 154} 155 156gdb_breakpoint "*it_breakpoints" 157gdb_test "call (int) it_breakpoints()" "Breakpoint.*" 158for { set i 1 } { $i <= 7 } { incr i } { 159 test_it_break ${i} 160} 161