summaryrefslogtreecommitdiff
path: root/gdb/testsuite/gdb.arch
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/testsuite/gdb.arch')
-rw-r--r--gdb/testsuite/gdb.arch/thumb2-it.S139
-rw-r--r--gdb/testsuite/gdb.arch/thumb2-it.exp140
2 files changed, 279 insertions, 0 deletions
diff --git a/gdb/testsuite/gdb.arch/thumb2-it.S b/gdb/testsuite/gdb.arch/thumb2-it.S
new file mode 100644
index 00000000000..a5aab8cb1be
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/thumb2-it.S
@@ -0,0 +1,139 @@
+/* Thumb-2 IT blocks test program.
+
+ Copyright 2010 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/>. */
+
+ .syntax unified
+ .text
+ .p2align 2
+ .code 16
+
+#ifndef __thumb2__
+
+ .type main,%function
+ .thumb_func
+ .globl main
+main:
+ mov r0, #0
+ bx lr @ No Thumb-2
+
+#else
+
+ .type main,%function
+ .thumb_func
+ .globl main
+main:
+ mov r0, #0
+ bx lr @ Thumb-2 OK
+
+ @ One conditional instruction, executed.
+ .type it_1,%function
+ .thumb_func
+it_1:
+ mov r0, #0 @ Setup
+ cmp r0, #0 @ Setup
+ it eq @ IT instruction, Expected == 1
+ addeq r0, #1 @ Reached
+ bx lr @ Done
+
+ @ One conditional instruction, skipped.
+ .type it_2,%function
+ .thumb_func
+it_2:
+ mov r0, #0 @ Setup
+ cmp r0, #0 @ Setup
+ it ne @ IT instruction, Expected == 0
+ addne r0, #1 @ Not reached
+ bx lr @ Done, Check $r0 == 0
+
+ @ Block of four, alternating, starting with executed.
+ .type it_3,%function
+ .thumb_func
+it_3:
+ mov r0, #0 @ Setup
+ cmp r0, #0 @ Setup
+ itete ge @ IT instruction, Expected == 2
+ addge r0, #1 @ Reached
+ addlt r0, #2 @ Not reached
+ addge r0, #4 @ Reached
+ addlt r0, #8 @ Not reached
+ bx lr @ Done, Check $r0 == 5
+
+ @ Block of four, changing flags.
+ .type it_4,%function
+ .thumb_func
+it_4:
+ mov r0, #0 @ Setup
+ cmp r0, #0 @ Setup
+ itttt ge @ IT instruction, Expected == 2
+ addge r0, #1 @ Reached
+ cmpge r0, #10 @ Reached
+ addge r0, #4 @ Not reached
+ addge r0, #8 @ Not reached
+ bx lr @ Done, Check $r0 == 1
+
+ @ Block of two, ending with taken branch.
+ .type it_5,%function
+ .thumb_func
+it_5:
+ mov r0, #0 @ Setup
+ cmp r0, #0 @ Setup
+ itt ge @ IT instruction, Expected == 2
+ addge r0, #1 @ Reached
+ bge .L5 @ Reached
+ add r0, #2 @ Never reached
+.L5: bx lr @ Done, Check $r0 == 1
+
+ @ Block of two, ending with untaken branch.
+ .type it_6,%function
+ .thumb_func
+it_6:
+ mov r0, #0 @ Setup
+ cmp r0, #0 @ Setup
+ ite ge @ IT instruction, Expected == 2
+ addge r0, #1 @ Reached
+ blt .L6 @ Not reached
+ add r0, #2 @ Reached
+.L6: bx lr @ Done, Check $r0 == 3
+
+ @ Block of four, taken, of different sizes
+ .type it_7,%function
+ .thumb_func
+it_7:
+ mov r0, #0 @ Setup
+ cmp r0, #0 @ Setup
+ itttt ge @ IT instruction, Expected == 4
+ addge.n r0, #1 @ Reached
+ addge.w r0, #2 @ Reached
+ addge.n r0, #4 @ Reached
+ addge.w r0, #8 @ Reached
+ bx lr @ Done, Check $r0 == 15
+
+ @ Block of four, only first executed.
+ .type it_3,%function
+ .thumb_func
+it_8:
+ mov r0, #0 @ Setup
+ cmp r0, #0 @ Setup
+ iteee ge @ IT instruction, Expected == 1
+ addge r0, #1 @ Reached
+ addlt r0, #2 @ Not reached
+ addlt r0, #4 @ Not reached
+ addlt r0, #8 @ Not reached
+ bx lr @ Done, Check $r0 == 1
+
+#endif /* __thumb2__ */
diff --git a/gdb/testsuite/gdb.arch/thumb2-it.exp b/gdb/testsuite/gdb.arch/thumb2-it.exp
new file mode 100644
index 00000000000..5ef8475fde2
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/thumb2-it.exp
@@ -0,0 +1,140 @@
+# Copyright 2010 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
+}
+
+# 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}
+}