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