* [PATCH v2 00/12] MIPS+testsuite: BLEZL stepping fix and associated test infrastructure
@ 2026-08-17 16:53 Maciej W. Rozycki
2026-08-17 16:53 ` [PATCH v2 01/12] testsuite: Factor out target feature test template Maciej W. Rozycki
` (11 more replies)
0 siblings, 12 replies; 13+ messages in thread
From: Maciej W. Rozycki @ 2026-08-17 16:53 UTC (permalink / raw)
To: gdb-patches
Cc: Jovan Dmitrovic, Djordje Todorovic, Milica Matic, Maciej W. Rozycki
Hi,
In the course of further verification additional issues have been found
leading to the expansion of this patch set. Minor issues in the original
changes have been addressed as well. I have retained the original heading
for the purpose of thread sorting in mailer software even though the scope
has now expanded beyond just the BLEZL stepping fix. The original cover
letter follows, adjusted as appropriate.
This patch series is based on a buried bug fix extracted from a change
submitted to add MIPSr6 support, most recently posted at
<https://inbox.sourceware.org/gdb-patches/20250604123838.501596-3-jovan.dmitrovic@htecgroup.com/>,
that corrects the handling of single-stepping through the BLEZL MIPS II
instruction.
This fix begged for test coverage, as indeed does all the MIPS software
single-stepping infrastructure, so I have created a bunch of test cases
roughly based on the skeleton already provided with said MIPSr6 change,
however with extra feature checks to correctly enable individual tests
based on the target configuration chosen for the testsuite invocation and
target board's compatibility with the ISA required for test execution.
This in turn revealed a repeated pattern of feature check code across
numerous procedures in testsuite/lib/gdb.exp. Rather than adding a bunch
more, I chose to factor out the repeated pattern and build the new feature
checks around it. For illustration purposes I have converted the existing
`powerpc*-*-*' target feature checks I could verify with my POWER9 test
system.
Consequently this set of 12 changes has resulted, comprised of the new
generic procedure in 01/12, followed by the `powerpc*-*-*' updates in
02/12, and then the MIPS changes in 03/12 through 12/12. At this point
MIPS I, MIPS II, MIPS16 and microMIPS, as well as DSP ASE CPU branches are
covered at this point for condition evaluation and then the same branches
and jumps for stepping through to the delay slot (i.e. no CP1/FPU/MIPS3D
branches nor R6 branches or jumps).
See individual change descriptions for details. Authorship attributions
are on the best knowledge basis.
This patch set has been regression-tested with a `powerpc64le-linux-gnu'
native configuration using POWER9 hardware and with the `mips-linux-gnu'
and `mipsel-linux-gnu' targets, using real MIPS I, MIPS III and MIPS32r2
hardware, the latter with regular MIPS and MIPS16 test configurations.
Additional verification was done with QEMU, especially for microMIPS code,
on the best effort basis and triggering emulation issues with QEMU itself
(and overall instability of the target). Detailed logs were examined for
correctness with respect to the tests affected as well.
I request approval for the non-MIPS parts of the patch series; I can
self-approve the MIPS bits, though obviously I'm happy to address any
feedback.
Company copyright assignment with FSF is currently still being sorted.
Previous iterations:
- v1 at: <https://inbox.sourceware.org/gdb-patches/alpine.DEB.2.21.2607220148540.14485@angie.orcam.me.uk/>.
Maciej
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 01/12] testsuite: Factor out target feature test template
2026-08-17 16:53 [PATCH v2 00/12] MIPS+testsuite: BLEZL stepping fix and associated test infrastructure Maciej W. Rozycki
@ 2026-08-17 16:53 ` Maciej W. Rozycki
2026-08-17 16:53 ` [PATCH v2 02/12] PowerPC/testsuite: Reduce feature tests in terms of `allow_target_tests' Maciej W. Rozycki
` (10 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Maciej W. Rozycki @ 2026-08-17 16:53 UTC (permalink / raw)
To: gdb-patches
Cc: Jovan Dmitrovic, Djordje Todorovic, Milica Matic, Maciej W. Rozycki
From: Maciej W. Rozycki <macro@globalfoundries.com>
Implement `allow_target_tests' generic target feature test procedure,
factoring out duplicate code from tests such as `allow_altivec_tests',
`allow_power_isa_3_1_tests', `allow_vsx_tests', etc.
---
No change from v1 (1/7),
<https://inbox.sourceware.org/gdb-patches/alpine.DEB.2.21.2607222352260.14485@angie.orcam.me.uk/>.
---
gdb/testsuite/lib/gdb.exp | 44 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
gdb-test-target-allow.diff
Index: binutils-gdb/gdb/testsuite/lib/gdb.exp
===================================================================
--- binutils-gdb.orig/gdb/testsuite/lib/gdb.exp
+++ binutils-gdb/gdb/testsuite/lib/gdb.exp
@@ -4291,6 +4291,50 @@ gdb_caching_proc libc_has_debug_info {}
}
}
+# Using name ME for reporting, check for target feature FEATURE, the
+# absence of which is supposed to get message MESSAGE produced by GDB.
+# Use source SRC and optional list of additional compiler flags FLAGS
+# for the check. Make sure the source provided builds and then that
+# target hardware runs it.
+proc allow_target_tests { me feature message src { flags {} } } {
+ global srcdir subdir gdb_prompt inferior_exited_re
+
+ set compile_flags {}
+ foreach flag $flags {
+ require {have_compile_flag $flag}
+ lappend compile_flags "additional_flags=$flag"
+ }
+
+ if {![gdb_simple_compile $me $src executable $compile_flags]} {
+ return 0
+ }
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load "$obj"
+ gdb_run_cmd
+ gdb_expect {
+ -re ".*${message}.*${gdb_prompt} $" {
+ verbose -log "\n$me $feature not detected"
+ set allow_target_tests 0
+ }
+ -re ".*$inferior_exited_re normally.*${gdb_prompt} $" {
+ verbose -log "\n$me: $feature detected"
+ set allow_target_tests 1
+ }
+ default {
+ warning "\n$me: default case taken"
+ set allow_target_tests 0
+ }
+ }
+ gdb_exit
+ remote_file build delete $obj
+
+ verbose "$me: returning $allow_target_tests" 2
+ return $allow_target_tests
+}
+
# Run a test on the target to see if it supports vmx hardware. Return 1 if so,
# 0 if it does not. Based on 'check_vmx_hw_available' from the GCC testsuite.
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 02/12] PowerPC/testsuite: Reduce feature tests in terms of `allow_target_tests'
2026-08-17 16:53 [PATCH v2 00/12] MIPS+testsuite: BLEZL stepping fix and associated test infrastructure Maciej W. Rozycki
2026-08-17 16:53 ` [PATCH v2 01/12] testsuite: Factor out target feature test template Maciej W. Rozycki
@ 2026-08-17 16:53 ` Maciej W. Rozycki
2026-08-17 16:53 ` [PATCH v2 03/12] MIPS/testsuite: Verify MIPS I CPU branch stepping Maciej W. Rozycki
` (9 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Maciej W. Rozycki @ 2026-08-17 16:53 UTC (permalink / raw)
To: gdb-patches
Cc: Jovan Dmitrovic, Djordje Todorovic, Milica Matic, Maciej W. Rozycki
From: Maciej W. Rozycki <macro@globalfoundries.com>
Reimplement `allow_altivec_tests', `allow_power_isa_3_1_tests', and
`allow_vsx_tests' in terms of `allow_target_tests', removing duplicate
code. No functional change.
Eventually it may make sense to migrate the resulting wrappers to
testsuite/gdb.arch/ so as to declutter generic test framework from
target-specific stuff.
---
No change from v1 (2/7),
<https://inbox.sourceware.org/gdb-patches/alpine.DEB.2.21.2607222358210.14485@angie.orcam.me.uk/>.
---
gdb/testsuite/lib/gdb.exp | 163 +++++++++-------------------------------------
1 file changed, 35 insertions(+), 128 deletions(-)
gdb-powerpc-test-target-allow.diff
Index: binutils-gdb/gdb/testsuite/lib/gdb.exp
===================================================================
--- binutils-gdb.orig/gdb/testsuite/lib/gdb.exp
+++ binutils-gdb/gdb/testsuite/lib/gdb.exp
@@ -4339,8 +4339,6 @@ proc allow_target_tests { me feature mes
# 0 if it does not. Based on 'check_vmx_hw_available' from the GCC testsuite.
gdb_caching_proc allow_altivec_tests {} {
- global srcdir subdir gdb_prompt inferior_exited_re
-
set me "allow_altivec_tests"
# Some simulators are known to not support VMX instructions.
@@ -4356,110 +4354,47 @@ gdb_caching_proc allow_altivec_tests {}
# Make sure we have a compiler that understands altivec.
if {[test_compiler_info gcc*]} {
- set compile_flags "additional_flags=-maltivec"
+ set flags "-maltivec"
} elseif {[test_compiler_info xlc*]} {
- set compile_flags "additional_flags=-qaltivec"
+ set flags "-qaltivec"
} else {
verbose "Could not compile with altivec support, returning 0" 2
return 0
}
# Compile a test program containing VMX instructions.
- set src {
- int main() {
- #ifdef __MACH__
- asm volatile ("vor v0,v0,v0");
- #else
- asm volatile ("vor 0,0,0");
- #endif
- return 0;
- }
- }
- if {![gdb_simple_compile $me $src executable $compile_flags]} {
- return 0
- }
-
- # Compilation succeeded so now run it via gdb.
-
- gdb_exit
- gdb_start
- gdb_reinitialize_dir $srcdir/$subdir
- gdb_load "$obj"
- gdb_run_cmd
- gdb_expect {
- -re ".*Illegal instruction.*${gdb_prompt} $" {
- verbose -log "\n$me altivec hardware not detected"
- set allow_vmx_tests 0
- }
- -re ".*$inferior_exited_re normally.*${gdb_prompt} $" {
- verbose -log "\n$me: altivec hardware detected"
- set allow_vmx_tests 1
- }
- default {
- warning "\n$me: default case taken"
- set allow_vmx_tests 0
- }
- }
- gdb_exit
- remote_file build delete $obj
-
- verbose "$me: returning $allow_vmx_tests" 2
- return $allow_vmx_tests
+ return [allow_target_tests $me "altivec hardware" "Illegal instruction" \
+ {
+ int main() {
+ #ifdef __MACH__
+ asm volatile ("vor v0,v0,v0");
+ #else
+ asm volatile ("vor 0,0,0");
+ #endif
+ return 0;
+ }
+ } \
+ $flags]
}
# Run a test on the power target to see if it supports ISA 3.1 instructions
gdb_caching_proc allow_power_isa_3_1_tests {} {
- global srcdir subdir gdb_prompt inferior_exited_re
-
- set me "allow_power_isa_3_1_tests"
-
# Compile a test program containing ISA 3.1 instructions.
- set src {
- int main() {
- asm volatile ("pnop"); // marker
+ return [allow_target_tests "allow_power_isa_3_1_tests" \
+ "Power ISA 3.1 hardware" "Illegal instruction" \
+ {
+ int main() {
+ asm volatile ("pnop"); // marker
asm volatile ("nop");
return 0;
}
- }
-
- if {![gdb_simple_compile $me $src executable ]} {
- return 0
- }
-
- # No error message, compilation succeeded so now run it via gdb.
-
- gdb_exit
- gdb_start
- gdb_reinitialize_dir $srcdir/$subdir
- gdb_load "$obj"
- gdb_run_cmd
- gdb_expect {
- -re ".*Illegal instruction.*${gdb_prompt} $" {
- verbose -log "\n$me Power ISA 3.1 hardware not detected"
- set allow_power_isa_3_1_tests 0
- }
- -re ".*$inferior_exited_re normally.*${gdb_prompt} $" {
- verbose -log "\n$me: Power ISA 3.1 hardware detected"
- set allow_power_isa_3_1_tests 1
- }
- default {
- warning "\n$me: default case taken"
- set allow_power_isa_3_1_tests 0
- }
- }
- gdb_exit
- remote_file build delete $obj
-
- verbose "$me: returning $allow_power_isa_3_1_tests" 2
- return $allow_power_isa_3_1_tests
+ }]
}
# Run a test on the target to see if it supports vmx hardware. Return 1 if so,
# 0 if it does not. Based on 'check_vmx_hw_available' from the GCC testsuite.
gdb_caching_proc allow_vsx_tests {} {
- global srcdir subdir gdb_prompt inferior_exited_re
-
set me "allow_vsx_tests"
# Some simulators are known to not support Altivec instructions, so
@@ -4471,56 +4406,28 @@ gdb_caching_proc allow_vsx_tests {} {
# Make sure we have a compiler that understands altivec.
if {[test_compiler_info gcc*]} {
- set compile_flags "additional_flags=-mvsx"
+ set flags "-mvsx"
} elseif {[test_compiler_info xlc*]} {
- set compile_flags "additional_flags=-qasm=gcc"
+ set flags "-qasm=gcc"
} else {
verbose "Could not compile with vsx support, returning 0" 2
return 0
}
# Compile a test program containing VSX instructions.
- set src {
- int main() {
- double a[2] = { 1.0, 2.0 };
- #ifdef __MACH__
- asm volatile ("lxvd2x v0,v0,%[addr]" : : [addr] "r" (a));
- #else
- asm volatile ("lxvd2x 0,0,%[addr]" : : [addr] "r" (a));
- #endif
- return 0;
- }
- }
- if {![gdb_simple_compile $me $src executable $compile_flags]} {
- return 0
- }
-
- # No error message, compilation succeeded so now run it via gdb.
-
- gdb_exit
- gdb_start
- gdb_reinitialize_dir $srcdir/$subdir
- gdb_load "$obj"
- gdb_run_cmd
- gdb_expect {
- -re ".*Illegal instruction.*${gdb_prompt} $" {
- verbose -log "\n$me VSX hardware not detected"
- set allow_vsx_tests 0
- }
- -re ".*$inferior_exited_re normally.*${gdb_prompt} $" {
- verbose -log "\n$me: VSX hardware detected"
- set allow_vsx_tests 1
- }
- default {
- warning "\n$me: default case taken"
- set allow_vsx_tests 0
- }
- }
- gdb_exit
- remote_file build delete $obj
-
- verbose "$me: returning $allow_vsx_tests" 2
- return $allow_vsx_tests
+ return [allow_target_tests $me "VSX hardware" "Illegal instruction" \
+ {
+ int main() {
+ double a[2] = { 1.0, 2.0 };
+ #ifdef __MACH__
+ asm volatile ("lxvd2x v0,v0,%[addr]" : : [addr] "r" (a));
+ #else
+ asm volatile ("lxvd2x 0,0,%[addr]" : : [addr] "r" (a));
+ #endif
+ return 0;
+ }
+ } \
+ $flags]
}
# Run a test on the target to see if it supports TSX hardware. Return 1 if so,
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 03/12] MIPS/testsuite: Verify MIPS I CPU branch stepping
2026-08-17 16:53 [PATCH v2 00/12] MIPS+testsuite: BLEZL stepping fix and associated test infrastructure Maciej W. Rozycki
2026-08-17 16:53 ` [PATCH v2 01/12] testsuite: Factor out target feature test template Maciej W. Rozycki
2026-08-17 16:53 ` [PATCH v2 02/12] PowerPC/testsuite: Reduce feature tests in terms of `allow_target_tests' Maciej W. Rozycki
@ 2026-08-17 16:53 ` Maciej W. Rozycki
2026-08-17 16:53 ` [PATCH v2 04/12] MIPS: Correct BLEZL single-stepping Maciej W. Rozycki
` (8 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Maciej W. Rozycki @ 2026-08-17 16:53 UTC (permalink / raw)
To: gdb-patches
Cc: Jovan Dmitrovic, Djordje Todorovic, Milica Matic, Maciej W. Rozycki
From: Maciej W. Rozycki <macro@globalfoundries.com>
Verify that breakpoints are correctly placed via `mips32_next_pc' while
single-stepping through MIPS I CPU branches.
The idea behind these test cases is that if a branch is misinterpreted
by the stepping code, then the breakpoint will be placed at the wrong
place, usually at the branch destination rather than immediately beyond
the delay slot or vice versa. In the former case a step will be missed
over the extra NOP placed beyond the delay slot and therefore from the
count and in the latter case the single-stepping breakpoint will be
missed altogether, letting code run through to the end of the intended
stepping range. In either case the stepping counter will not reach 0 at
conclusion, causing the test case to fail.
It is perhaps worth noting that any missed steps from individual branch
interpretation failures recorded in the counter cannot be made up for by
other branch interpretation failures, because the structure of the code
does not make it possible for additional steps to be made in the case of
a single-stepping breakpoint misplacement save for the breakpoint having
been placed at the branch or its delay slot being stepped over, in which
case however stepping will loop over the branch and eventually fail once
the counter has reached zero prematurely, having not reached the end of
the intended stepping range.
The target feature tests for these test cases have been written somewhat
overly cautiously, for example BLTZL is never a macro, so `.set nomacro'
doesn't really guard against anything. This is however harmless while
making the feature tests more uniform.
Co-Authored-By: Andrew Bennett <andrew.bennett@imgtec.com>
Co-Authored-By: Matthew Fortune <matthew.fortune@mips.com>
Co-Authored-By: Faraz Shahbazker <fshahbazker@wavecomp.com>
Co-Authored-By: Milica Matic <milica.matic@htecgroup.com>
Co-Authored-By: Jovan Dmitrović <jovan.dmitrovic@htecgroup.com>
Approved-By: Maciej W. Rozycki <macro@orcam.me.uk>
---
Changes from v1 (3/7),
<https://inbox.sourceware.org/gdb-patches/alpine.DEB.2.21.2607230010440.14485@angie.orcam.me.uk/>:
- Robustify `stepi' for better performance in the case of test failures:
* Handle timeouts and EOF.
* Handle unexpected output in response to assignment to `err'.
* Bail out right away when `err' has reached zero and no breakpoint hit.
- Remove unused `any' variable from `test_mips1_bal'.
- Remove unnecessary "$31" clobber from `test_mips1_branch'.
- Clarify in the change description that individual branch interpretation
failures cannot make up for each other.
---
gdb/testsuite/gdb.arch/mips-allow.exp.tcl | 61 ++++++++++++++++
gdb/testsuite/gdb.arch/mips-stepi.exp.tcl | 108 ++++++++++++++++++++++++++++++
gdb/testsuite/gdb.arch/mips1-bal.c | 68 ++++++++++++++++++
gdb/testsuite/gdb.arch/mips1-bal.exp | 30 ++++++++
gdb/testsuite/gdb.arch/mips1-branch.c | 79 +++++++++++++++++++++
gdb/testsuite/gdb.arch/mips1-branch.exp | 30 ++++++++
6 files changed, 376 insertions(+)
gdb-mips1-next-pc-test.diff
Index: binutils-gdb/gdb/testsuite/gdb.arch/mips-allow.exp.tcl
===================================================================
--- /dev/null
+++ binutils-gdb/gdb/testsuite/gdb.arch/mips-allow.exp.tcl
@@ -0,0 +1,61 @@
+# Copyright (C) 2026 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/>.
+
+# Feature availability check helpers for MIPS tests.
+
+# Check for MIPS I branch support. These instructions may be absent,
+# such as with MIPS16 compilations. Make sure an actual BLTZ machine
+# instruction is produced and no macro expanded.
+proc allow_mips1_branch_tests {} {
+ return [allow_target_tests "allow_mips1_branch_tests" \
+ "MIPS I branch support" "Illegal instruction" \
+ {
+ int main() {
+ asm volatile (
+ ".set push\n\t"
+ ".set noreorder\n\t"
+ ".set nomacro\n\t"
+ "bltz $0, 0f\n\t"
+ " nop\n"
+ "0:\n\t"
+ ".set pop\n");
+ return 0;
+ }
+ } \
+ {-Wa,-fatal-warnings -mno-mips16 -minterlink-compressed}]
+}
+
+# Check for MIPS I branch-and-link support. These instructions may be
+# absent, such as with MIPSr6, or MIPS16 compilations. Make sure an
+# actual BLTZAL machine instruction is produced and no macro expanded.
+proc allow_mips1_bal_tests {} {
+ return [allow_target_tests "allow_mips1_bal_tests" \
+ "MIPS I branch-and-link support" "Illegal instruction" \
+ {
+ int main() {
+ asm volatile (
+ ".set push\n\t"
+ ".set noreorder\n\t"
+ ".set nomacro\n\t"
+ "bltzal $4, 0f\n\t"
+ " nop\n"
+ "0:\n\t"
+ ".set pop\n"
+ : : : "$31");
+ return 0;
+ }
+ } \
+ {-Wa,-fatal-warnings -mno-mips16 -minterlink-compressed}]
+}
Index: binutils-gdb/gdb/testsuite/gdb.arch/mips-stepi.exp.tcl
===================================================================
--- /dev/null
+++ binutils-gdb/gdb/testsuite/gdb.arch/mips-stepi.exp.tcl
@@ -0,0 +1,108 @@
+# Copyright (C) 2026 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/>.
+
+# Template for MIPS single-stepping tests.
+
+# Send `stepi' to gdb until inferior hits a breakpoint, starting with
+# ERR (which is a program variable) set to STEPS and decrementing it
+# with each step. Use MESSAGE for the test result.
+proc stepi { steps message } {
+ global gdb_prompt
+ global positive
+
+ set timeout [get_largest_timeout]
+ set start [timestamp]
+
+ gdb_test_no_output -nopass "set err = $steps"
+ while { [timestamp] - $start < $steps * $timeout } {
+ gdb_test_multiple "stepi" "" {
+ -re ".*Breakpoint.*$gdb_prompt" {
+ send_gdb "set err -= 1\n"
+ gdb_expect {
+ -re "$gdb_prompt" {
+ }
+ eof {
+ fail "$message (eof)"
+ return 0
+ }
+ timeout {
+ fail "$message (timeout)"
+ return 0
+ }
+ }
+ pass $message
+ return 1
+ }
+ -re ".*$gdb_prompt" {
+ send_gdb "print err -= 1\n"
+ gdb_expect {
+ -re "\\$$positive = $positive\r\n$gdb_prompt" {
+ }
+ -re "\\$$positive = 0\r\n$gdb_prompt" {
+ fail "$message (number of steps exceeded)"
+ return 0
+ }
+ -re "$gdb_prompt" {
+ fail "$message (unexpected output)"
+ return 0
+ }
+ eof {
+ fail "$message (eof)"
+ return 0
+ }
+ timeout {
+ fail "$message (timeout)"
+ return 0
+ }
+ }
+ }
+ default {
+ return 0
+ }
+ }
+ }
+ fail "$message (stepping duration exceeded)"
+ return 0
+}
+
+if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \
+ [lappend compile_flags debug]] } {
+ return
+}
+
+if { ![runto_main] } {
+ return
+}
+
+# Put breakpoints at the boundaries of the stepping range.
+foreach place [list step_start step_stop] {
+ if {![gdb_breakpoint "$place"]} {
+ unresolved "couldn't put breakpoint at $place"
+ return
+ }
+}
+
+# Advance to the beginning of the range.
+gdb_test "continue" ".*Breakpoint.*" "continue to step_start"
+
+# Make it easier to match results against expectations in the case of failures.
+gdb_test "info registers" ".*"
+gdb_test "display /i \$pc" ".*"
+
+# Step through to the end of the range.
+stepi $steps "step through to step_stop"
+
+# And run to completion to retrieve the result.
+gdb_test "continue" ".*exited normally.*" "continue to completion"
Index: binutils-gdb/gdb/testsuite/gdb.arch/mips1-bal.c
===================================================================
--- /dev/null
+++ binutils-gdb/gdb/testsuite/gdb.arch/mips1-bal.c
@@ -0,0 +1,68 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright (C) 2026 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 usefu,
+ 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 through MIPS I branch-and-link instructions. */
+
+int
+test_mips1_bal (void)
+{
+ /* Make 'err' available to the debugger to track the number of single
+ steps executed. Use `volatile' to prevent the variable from being
+ optimized away. */
+ volatile int err = -1;
+
+ int mone = -1;
+ int zero = 0;
+ int one = 1;
+
+ asm volatile (
+ ".macro b_test op, args:vararg\n\t"
+ "\\op \\args, 0f\n\t"
+ " nop\n\t"
+ "nop\n"
+ "0:\n\t"
+ ".endm\n\t"
+
+ ".set push\n\t"
+ ".set noreorder\n\t"
+ ".globl step_start\n\t"
+ ".type step_start, @function\n"
+ "step_start:\n\t" /* Units: steps. */
+ "nop\n\t" /* NOP: 1s */
+ "b_test bltzal, %[mone]\n\t" /* Taken: 1s */
+ "b_test bltzal, %[zero]\n\t" /* Not taken: 2s */
+ "b_test bltzal, %[one]\n\t" /* Not taken: 2s */
+ "b_test bgezal, %[mone]\n\t" /* Not taken: 2s */
+ "b_test bgezal, %[zero]\n\t" /* Taken: 1s */
+ "b_test bgezal, %[one]\n\t" /* Taken: 1s */
+ "nop\n\t" /* NOP: 1s */
+ ".globl step_stop\n\t" /* Total: 11s */
+ ".type step_stop, @function\n"
+ "step_stop:\n\t"
+ ".set pop\n"
+ :
+ : [mone] "r" (mone), [zero] "r" (zero), [one] "r" (one)
+ : "$31");
+
+ return err;
+}
+
+int
+main (void)
+{
+ return test_mips1_bal ();
+}
Index: binutils-gdb/gdb/testsuite/gdb.arch/mips1-bal.exp
===================================================================
--- /dev/null
+++ binutils-gdb/gdb/testsuite/gdb.arch/mips1-bal.exp
@@ -0,0 +1,30 @@
+# Copyright (C) 2026 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 through MIPS I branch-and-link instructions.
+
+require {istarget "mips*-*-*"}
+
+source $srcdir/$subdir/mips-allow.exp.tcl
+
+require allow_mips1_bal_tests
+
+standard_testfile
+
+set steps 11
+foreach flag {-mno-mips16 -minterlink-compressed} {
+ lappend compile_flags "additional_flags=$flag"
+}
+source $srcdir/$subdir/mips-stepi.exp.tcl
Index: binutils-gdb/gdb/testsuite/gdb.arch/mips1-branch.c
===================================================================
--- /dev/null
+++ binutils-gdb/gdb/testsuite/gdb.arch/mips1-branch.c
@@ -0,0 +1,79 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright (C) 2026 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 usefu,
+ 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 through MIPS I branch instructions. */
+
+int
+test_mips1_branch (void)
+{
+ /* Make 'err' available to the debugger to track the number of single
+ steps executed. Use `volatile' to prevent the variable from being
+ optimized away. */
+ volatile int err = -1;
+
+ int any = 0x55aa;
+ int mone = -1;
+ int zero = 0;
+ int one = 1;
+
+ asm volatile (
+ ".macro b_test op, args:vararg\n\t"
+ "\\op \\args, 0f\n\t"
+ " nop\n\t"
+ "nop\n"
+ "0:\n\t"
+ ".endm\n\t"
+
+ ".set push\n\t"
+ ".set noreorder\n\t"
+ ".globl step_start\n\t"
+ ".type step_start, @function\n"
+ "step_start:\n\t" /* Units: steps. */
+ "nop\n\t" /* NOP: 1s */
+ "b_test beq, %[any], %[any]\n\t" /* Taken: 1s */
+ "b_test beq, %[any], %[one]\n\t" /* Not taken: 2s */
+ "b_test bne, %[any], %[any]\n\t" /* Not taken: 2s */
+ "b_test bne, %[any], %[one]\n\t" /* Taken: 1s */
+ "b_test bltz, %[mone]\n\t" /* Taken: 1s */
+ "b_test bltz, %[zero]\n\t" /* Not taken: 2s */
+ "b_test bltz, %[one]\n\t" /* Not taken: 2s */
+ "b_test blez, %[mone]\n\t" /* Taken: 1s */
+ "b_test blez, %[zero]\n\t" /* Taken: 1s */
+ "b_test blez, %[one]\n\t" /* Not taken: 2s */
+ "b_test bgez, %[mone]\n\t" /* Not taken: 2s */
+ "b_test bgez, %[zero]\n\t" /* Taken: 1s */
+ "b_test bgez, %[one]\n\t" /* Taken: 1s */
+ "b_test bgtz, %[mone]\n\t" /* Not taken: 2s */
+ "b_test bgtz, %[zero]\n\t" /* Not taken: 2s */
+ "b_test bgtz, %[one]\n\t" /* Taken: 1s */
+ "nop\n\t" /* NOP: 1s */
+ ".globl step_stop\n\t" /* Total: 26s */
+ ".type step_stop, @function\n"
+ "step_stop:\n\t"
+ ".set pop\n"
+ :
+ : [mone] "r" (mone), [zero] "r" (zero), [one] "r" (one),
+ [any] "r" (any));
+
+ return err;
+}
+
+int
+main (void)
+{
+ return test_mips1_branch ();
+}
Index: binutils-gdb/gdb/testsuite/gdb.arch/mips1-branch.exp
===================================================================
--- /dev/null
+++ binutils-gdb/gdb/testsuite/gdb.arch/mips1-branch.exp
@@ -0,0 +1,30 @@
+# Copyright (C) 2026 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 through MIPS I branch instructions.
+
+require {istarget "mips*-*-*"}
+
+source $srcdir/$subdir/mips-allow.exp.tcl
+
+require allow_mips1_branch_tests
+
+standard_testfile
+
+set steps 26
+foreach flag {-mno-mips16 -minterlink-compressed} {
+ lappend compile_flags "additional_flags=$flag"
+}
+source $srcdir/$subdir/mips-stepi.exp.tcl
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 04/12] MIPS: Correct BLEZL single-stepping
2026-08-17 16:53 [PATCH v2 00/12] MIPS+testsuite: BLEZL stepping fix and associated test infrastructure Maciej W. Rozycki
` (2 preceding siblings ...)
2026-08-17 16:53 ` [PATCH v2 03/12] MIPS/testsuite: Verify MIPS I CPU branch stepping Maciej W. Rozycki
@ 2026-08-17 16:53 ` Maciej W. Rozycki
2026-08-17 16:53 ` [PATCH v2 05/12] MIPS/testsuite: Verify MIPS II CPU branch stepping Maciej W. Rozycki
` (7 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Maciej W. Rozycki @ 2026-08-17 16:53 UTC (permalink / raw)
To: gdb-patches
Cc: Jovan Dmitrovic, Djordje Todorovic, Milica Matic, Maciej W. Rozycki
From: Maciej W. Rozycki <macro@globalfoundries.com>
Correct `mips32_next_pc' and also consider BLEZL taken for the value of
zero held in the source register as per the instruction's semantics,
restoring `less_zero_branch' label discarded with commit 54f1137d66be
and actually matching the comment present in the source.
Verification will be provided with the test cases in the next change.
Co-Authored-By: Andrew Bennett <andrew.bennett@imgtec.com>
Co-Authored-By: Matthew Fortune <matthew.fortune@mips.com>
Co-Authored-By: Faraz Shahbazker <fshahbazker@wavecomp.com>
Co-Authored-By: Milica Matic <milica.matic@htecgroup.com>
Co-Authored-By: Jovan Dmitrović <jovan.dmitrovic@htecgroup.com>
Approved-By: Maciej W. Rozycki <macro@orcam.me.uk>
---
No change from v1 (4/7),
<https://inbox.sourceware.org/gdb-patches/alpine.DEB.2.21.2607230035130.14485@angie.orcam.me.uk/>.
---
gdb/mips-tdep.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
gdb-mips-next-pc-blezl.diff
Index: binutils-gdb/gdb/mips-tdep.c
===================================================================
--- binutils-gdb.orig/gdb/mips-tdep.c
+++ binutils-gdb/gdb/mips-tdep.c
@@ -1662,7 +1662,7 @@ mips32_next_pc (struct regcache *regcach
case 1: /* BNEL */
goto neq_branch;
case 2: /* BLEZL */
- goto less_branch;
+ goto less_equal_branch;
case 3: /* BGTZL */
goto greater_branch;
default:
@@ -1751,7 +1751,6 @@ mips32_next_pc (struct regcache *regcach
case 2: /* BLTZL */
case 16: /* BLTZAL */
case 18: /* BLTZALL */
- less_branch:
if (regcache_raw_get_signed (regcache, itype_rs (inst)) < 0)
pc += mips32_relative_offset (inst) + 4;
else
@@ -1817,6 +1816,7 @@ mips32_next_pc (struct regcache *regcach
pc += 8;
break;
case 6: /* BLEZ, BLEZL */
+ less_equal_branch:
if (regcache_raw_get_signed (regcache, itype_rs (inst)) <= 0)
pc += mips32_relative_offset (inst) + 4;
else
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 05/12] MIPS/testsuite: Verify MIPS II CPU branch stepping
2026-08-17 16:53 [PATCH v2 00/12] MIPS+testsuite: BLEZL stepping fix and associated test infrastructure Maciej W. Rozycki
` (3 preceding siblings ...)
2026-08-17 16:53 ` [PATCH v2 04/12] MIPS: Correct BLEZL single-stepping Maciej W. Rozycki
@ 2026-08-17 16:53 ` Maciej W. Rozycki
2026-08-17 16:53 ` [PATCH v2 06/12] MIPS/testsuite: Verify MIPS DSP ASE " Maciej W. Rozycki
` (6 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Maciej W. Rozycki @ 2026-08-17 16:53 UTC (permalink / raw)
To: gdb-patches
Cc: Jovan Dmitrovic, Djordje Todorovic, Milica Matic, Maciej W. Rozycki
From: Maciej W. Rozycki <macro@globalfoundries.com>
Verify that breakpoints are correctly placed via `mips32_next_pc' while
single-stepping through MIPS II CPU branches.
Approved-By: Maciej W. Rozycki <macro@orcam.me.uk>
---
No change from v1 (5/7),
<https://inbox.sourceware.org/gdb-patches/alpine.DEB.2.21.2607230104410.14485@angie.orcam.me.uk/>.
---
gdb/testsuite/gdb.arch/mips-allow.exp.tcl | 25 ++++++++
gdb/testsuite/gdb.arch/mips2-branch.c | 86 ++++++++++++++++++++++++++++++
gdb/testsuite/gdb.arch/mips2-branch.exp | 30 ++++++++++
3 files changed, 141 insertions(+)
gdb-mips2-next-pc-test.diff
Index: binutils-gdb/gdb/testsuite/gdb.arch/mips-allow.exp.tcl
===================================================================
--- binutils-gdb.orig/gdb/testsuite/gdb.arch/mips-allow.exp.tcl
+++ binutils-gdb/gdb/testsuite/gdb.arch/mips-allow.exp.tcl
@@ -59,3 +59,28 @@ proc allow_mips1_bal_tests {} {
} \
{-Wa,-fatal-warnings -mno-mips16 -minterlink-compressed}]
}
+
+# Check for MIPS II branch-likely support. These instructions may be
+# absent, such as with MIPS I, MIPSr6, or MIPS16 compilations, or only
+# supported as assembler macros, such as with microMIPS compilations.
+# Make sure an actual BEQL machine instruction is produced and no macro
+# expanded.
+proc allow_mips2_branch_tests {} {
+ return [allow_target_tests "allow_mips2_branch_tests" \
+ "MIPS II branch support" "Illegal instruction" \
+ {
+ int main() {
+ asm volatile (
+ ".set push\n\t"
+ ".set noreorder\n\t"
+ ".set nomacro\n\t"
+ "beql $0, $0, 0f\n\t"
+ " nop\n"
+ "0:\n\t"
+ ".set pop\n");
+ return 0;
+ }
+ } \
+ {-Wa,-fatal-warnings -mno-mips16 -mno-micromips
+ -minterlink-compressed}]
+}
Index: binutils-gdb/gdb/testsuite/gdb.arch/mips2-branch.c
===================================================================
--- /dev/null
+++ binutils-gdb/gdb/testsuite/gdb.arch/mips2-branch.c
@@ -0,0 +1,86 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright (C) 2026 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 through MIPS II branch instructions. */
+
+int
+test_mips2_branch (void)
+{
+ /* Make 'err' available to the debugger to track the number of single
+ steps executed. Use `volatile' to prevent the variable from being
+ optimized away. */
+ volatile int err = -1;
+
+ int any = 0x55aa;
+ int mone = -1;
+ int zero = 0;
+ int one = 1;
+
+ asm volatile (
+ ".macro b_test op, args:vararg\n\t"
+ "\\op \\args, 0f\n\t"
+ " nop\n\t"
+ "nop\n"
+ "0:\n\t"
+ ".endm\n\t"
+
+ ".set push\n\t"
+ ".set noreorder\n\t"
+ ".globl step_start\n\t"
+ ".type step_start, @function\n"
+ "step_start:\n\t" /* Units: steps. */
+ "nop\n\t" /* NOP: 1s */
+ "b_test beql, %[any], %[any]\n\t" /* Taken: 1s */
+ "b_test beql, %[any], %[one]\n\t" /* Not taken: 2s */
+ "b_test bnel, %[any], %[any]\n\t" /* Not taken: 2s */
+ "b_test bnel, %[any], %[one]\n\t" /* Taken: 1s */
+ "b_test bltzl, %[mone]\n\t" /* Taken: 1s */
+ "b_test bltzl, %[zero]\n\t" /* Not taken: 2s */
+ "b_test bltzl, %[one]\n\t" /* Not taken: 2s */
+ "b_test blezl, %[mone]\n\t" /* Taken: 1s */
+ "b_test blezl, %[zero]\n\t" /* Taken: 1s */
+ "b_test blezl, %[one]\n\t" /* Not taken: 2s */
+ "b_test bgezl, %[mone]\n\t" /* Not taken: 2s */
+ "b_test bgezl, %[zero]\n\t" /* Taken: 1s */
+ "b_test bgezl, %[one]\n\t" /* Taken: 1s */
+ "b_test bgtzl, %[mone]\n\t" /* Not taken: 2s */
+ "b_test bgtzl, %[zero]\n\t" /* Not taken: 2s */
+ "b_test bgtzl, %[one]\n\t" /* Taken: 1s */
+ "b_test bltzall, %[mone]\n\t" /* Taken: 1s */
+ "b_test bltzall, %[zero]\n\t" /* Not taken: 2s */
+ "b_test bltzall, %[one]\n\t" /* Not taken: 2s */
+ "b_test bgezall, %[mone]\n\t" /* Not taken: 2s */
+ "b_test bgezall, %[zero]\n\t" /* Taken: 1s */
+ "b_test bgezall, %[one]\n\t" /* Taken: 1s */
+ "nop\n\t" /* NOP: 1s */
+ ".globl step_stop\n\t" /* Total: 35s */
+ ".type step_stop, @function\n"
+ "step_stop:\n\t"
+ ".set pop\n"
+ :
+ : [mone] "r" (mone), [zero] "r" (zero), [one] "r" (one),
+ [any] "r" (any)
+ : "$31");
+
+ return err;
+}
+
+int
+main (void)
+{
+ return test_mips2_branch ();
+}
Index: binutils-gdb/gdb/testsuite/gdb.arch/mips2-branch.exp
===================================================================
--- /dev/null
+++ binutils-gdb/gdb/testsuite/gdb.arch/mips2-branch.exp
@@ -0,0 +1,30 @@
+# Copyright (C) 2026 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 through MIPS II branch instructions.
+
+require {istarget "mips*-*-*"}
+
+source $srcdir/$subdir/mips-allow.exp.tcl
+
+require allow_mips2_branch_tests
+
+standard_testfile
+
+set steps 35
+foreach flag {-mno-mips16 -mno-micromips -minterlink-compressed} {
+ lappend compile_flags "additional_flags=$flag"
+}
+source $srcdir/$subdir/mips-stepi.exp.tcl
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 06/12] MIPS/testsuite: Verify MIPS DSP ASE branch stepping
2026-08-17 16:53 [PATCH v2 00/12] MIPS+testsuite: BLEZL stepping fix and associated test infrastructure Maciej W. Rozycki
` (4 preceding siblings ...)
2026-08-17 16:53 ` [PATCH v2 05/12] MIPS/testsuite: Verify MIPS II CPU branch stepping Maciej W. Rozycki
@ 2026-08-17 16:53 ` Maciej W. Rozycki
2026-08-17 16:53 ` [PATCH v2 07/12] MIPS/testsuite: Verify MIPS16 " Maciej W. Rozycki
` (5 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Maciej W. Rozycki @ 2026-08-17 16:53 UTC (permalink / raw)
To: gdb-patches
Cc: Jovan Dmitrovic, Djordje Todorovic, Milica Matic, Maciej W. Rozycki
From: Maciej W. Rozycki <macro@globalfoundries.com>
Verify that breakpoints are correctly placed via `mips32_next_pc' while
single-stepping through MIPS DSP ASE branches. No 64-bit support here.
Approved-By: Maciej W. Rozycki <macro@orcam.me.uk>
---
New change in v2.
---
gdb/testsuite/gdb.arch/mips-allow.exp.tcl | 19 +++++++
gdb/testsuite/gdb.arch/mips-dsp-branch.c | 69 +++++++++++++++++++++++++++++
gdb/testsuite/gdb.arch/mips-dsp-branch.exp | 30 ++++++++++++
3 files changed, 118 insertions(+)
gdb-mips-dsp-next-pc-test.diff
Index: binutils-gdb/gdb/testsuite/gdb.arch/mips-allow.exp.tcl
===================================================================
--- binutils-gdb.orig/gdb/testsuite/gdb.arch/mips-allow.exp.tcl
+++ binutils-gdb/gdb/testsuite/gdb.arch/mips-allow.exp.tcl
@@ -84,3 +84,22 @@ proc allow_mips2_branch_tests {} {
{-Wa,-fatal-warnings -mno-mips16 -mno-micromips
-minterlink-compressed}]
}
+
+# Check for MIPS DSP ASE instruction support. These instructions may
+# be absent, such as with pre-MIPSr2 compilations or non-DSP hardware.
+proc allow_mips_dsp_ase_tests {} {
+ return [allow_target_tests "allow_mips_dsp_ase_tests" \
+ "MIPS DSP instruction support" "Illegal instruction" \
+ {
+ int main() {
+ asm volatile (
+ ".set push\n\t"
+ ".set noreorder\n\t"
+ ".set nomacro\n\t"
+ "rddsp $0, 0\n\t"
+ ".set pop\n");
+ return 0;
+ }
+ } \
+ {-Wa,-fatal-warnings -mno-mips16 -minterlink-compressed -mdsp}]
+}
Index: binutils-gdb/gdb/testsuite/gdb.arch/mips-dsp-branch.c
===================================================================
--- /dev/null
+++ binutils-gdb/gdb/testsuite/gdb.arch/mips-dsp-branch.c
@@ -0,0 +1,69 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright (C) 2026 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 usefu,
+ 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 through MIPS DSP branch instructions. */
+
+int
+test_mips_dsp_branch (void)
+{
+ /* Make 'err' available to the debugger to track the number of single
+ steps executed. Use `volatile' to prevent the variable from being
+ optimized away. */
+ volatile int err = -1;
+
+ int thr_one = 31;
+ int thr_two = 32;
+ int thr_thr = 33;
+
+ asm volatile (
+ ".macro b_test op\n\t"
+ "\\op 0f\n\t"
+ " nop\n\t"
+ "nop\n"
+ "0:\n\t"
+ ".endm\n\t"
+
+ ".set push\n\t"
+ ".set noreorder\n\t"
+ ".globl step_start\n\t"
+ ".type step_start, @function\n"
+ "step_start:\n\t" /* Units: steps. */
+ "nop\n\t" /* NOP: 1s */
+ "wrdsp %[thr_one], 1\n\t" /* WRDSP: 1s */
+ "b_test bposge32\n\t" /* Not taken: 2s */
+ "wrdsp %[thr_two], 1\n\t" /* WRDSP: 1s */
+ "b_test bposge32\n\t" /* Taken: 1s */
+ "wrdsp %[thr_thr], 1\n\t" /* WRDSP: 1s */
+ "b_test bposge32\n\t" /* Taken: 1s */
+ "nop\n\t" /* NOP: 1s */
+ ".globl step_stop\n\t" /* Total: 9s */
+ ".type step_stop, @function\n"
+ "step_stop:\n\t"
+ ".set pop\n"
+ :
+ : [thr_one] "r" (thr_one), [thr_two] "r" (thr_two),
+ [thr_thr] "r" (thr_thr)
+ : "$dsp_po");
+
+ return err;
+}
+
+int
+main (void)
+{
+ return test_mips_dsp_branch ();
+}
Index: binutils-gdb/gdb/testsuite/gdb.arch/mips-dsp-branch.exp
===================================================================
--- /dev/null
+++ binutils-gdb/gdb/testsuite/gdb.arch/mips-dsp-branch.exp
@@ -0,0 +1,30 @@
+# Copyright (C) 2026 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 through MIPS DSP branch instructions.
+
+require {istarget "mips*-*-*"}
+
+source $srcdir/$subdir/mips-allow.exp.tcl
+
+require allow_mips_dsp_ase_tests
+
+standard_testfile
+
+set steps 9
+foreach flag {-mno-mips16 -minterlink-compressed -mdsp} {
+ lappend compile_flags "additional_flags=$flag"
+}
+source $srcdir/$subdir/mips-stepi.exp.tcl
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 07/12] MIPS/testsuite: Verify MIPS16 branch stepping
2026-08-17 16:53 [PATCH v2 00/12] MIPS+testsuite: BLEZL stepping fix and associated test infrastructure Maciej W. Rozycki
` (5 preceding siblings ...)
2026-08-17 16:53 ` [PATCH v2 06/12] MIPS/testsuite: Verify MIPS DSP ASE " Maciej W. Rozycki
@ 2026-08-17 16:53 ` Maciej W. Rozycki
2026-08-17 16:53 ` [PATCH v2 08/12] MIPS/testsuite: Verify microMIPS " Maciej W. Rozycki
` (4 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Maciej W. Rozycki @ 2026-08-17 16:53 UTC (permalink / raw)
To: gdb-patches
Cc: Jovan Dmitrovic, Djordje Todorovic, Milica Matic, Maciej W. Rozycki
From: Maciej W. Rozycki <macro@globalfoundries.com>
Verify that breakpoints are correctly placed via `mips16_next_pc' while
single-stepping through MIPS16 branches. Explicit instruction suffixes
are used to get both regular and extended instruction forms covered, and
`-Wa,-W' GAS option is used to quiesce warnings as the tool is keen to
complain about the extended form where requested unnecessarily.
Approved-By: Maciej W. Rozycki <macro@orcam.me.uk>
---
Changes from v1 (6/7),
<https://inbox.sourceware.org/gdb-patches/alpine.DEB.2.21.2607230107330.14485@angie.orcam.me.uk/>:
- Correct the printed description of `allow_mips16_ase_tests'.
- Remove unused `mone' and `one' variables from `test_mips16_branch';
correct the function description.
---
gdb/testsuite/gdb.arch/mips-allow.exp.tcl | 21 +++++++
gdb/testsuite/gdb.arch/mips16-branch.c | 80 ++++++++++++++++++++++++++++++
gdb/testsuite/gdb.arch/mips16-branch.exp | 30 +++++++++++
3 files changed, 131 insertions(+)
gdb-mips16-next-pc-test.diff
Index: binutils-gdb/gdb/testsuite/gdb.arch/mips-allow.exp.tcl
===================================================================
--- binutils-gdb.orig/gdb/testsuite/gdb.arch/mips-allow.exp.tcl
+++ binutils-gdb/gdb/testsuite/gdb.arch/mips-allow.exp.tcl
@@ -103,3 +103,24 @@ proc allow_mips_dsp_ase_tests {} {
} \
{-Wa,-fatal-warnings -mno-mips16 -minterlink-compressed -mdsp}]
}
+
+# Check for MIPS16 ASE support. These instructions may be absent,
+# such as with microMIPS compilations. Make sure an actual BTEQZ
+# machine instruction is produced and no macro expanded.
+proc allow_mips16_ase_tests {} {
+ return [allow_target_tests "allow_mips16_ase_tests" \
+ "MIPS16 instruction support" "(:?Bus error|Illegal instruction)" \
+ {
+ int main() {
+ asm volatile (
+ ".set push\n\t"
+ ".set noreorder\n\t"
+ ".set nomacro\n\t"
+ "bteqz 0f\n\t"
+ "0:\n\t"
+ ".set pop\n");
+ return 0;
+ }
+ } \
+ {-Wa,-fatal-warnings -mno-micromips -mips16 -minterlink-compressed}]
+}
Index: binutils-gdb/gdb/testsuite/gdb.arch/mips16-branch.c
===================================================================
--- /dev/null
+++ binutils-gdb/gdb/testsuite/gdb.arch/mips16-branch.c
@@ -0,0 +1,80 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright (C) 2026 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 usefu,
+ 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 through MIPS16 branch instructions. */
+
+int
+test_mips16_branch (void)
+{
+ /* Make 'err' available to the debugger to track the number of single
+ steps executed. Use `volatile' to prevent the variable from being
+ optimized away. */
+ volatile int err = -1;
+
+ int any = 0x55aa;
+ int zero = 0;
+
+ asm volatile (
+ ".macro b_test op, args:vararg\n\t"
+ ".ifb \\args\n\t"
+ "\\op 0f\n\t"
+ ".else\n\t"
+ "\\op \\args, 0f\n\t"
+ ".endif\n\t"
+ "nop\n"
+ "0:\n\t"
+ ".endm\n\t"
+
+ ".set push\n\t"
+ ".set noreorder\n\t"
+ ".globl step_start\n\t"
+ ".type step_start, @function\n"
+ "step_start:\n\t" /* Units: steps. */
+ "nop\n\t" /* NOP: 1s */
+ "b_test beqz.t %[zero]\n\t" /* Taken: 1s */
+ "b_test beqz.e %[zero]\n\t" /* Taken: 1s */
+ "b_test beqz.t %[any]\n\t" /* Not taken: 2s */
+ "b_test beqz.e %[any]\n\t" /* Not taken: 2s */
+ "b_test bnez.t %[zero]\n\t" /* Not taken: 2s */
+ "b_test bnez.e %[zero]\n\t" /* Not taken: 2s */
+ "b_test bnez.t %[any]\n\t" /* Taken: 1s */
+ "b_test bnez.e %[any]\n\t" /* Taken: 1s */
+ "b_test bteqz.t\n\t" /* Taken: 1s */
+ "b_test bteqz.e\n\t" /* Taken: 1s */
+ "b_test btnez.t\n\t" /* Not taken: 2s */
+ "b_test btnez.e\n\t" /* Not taken: 2s */
+ "move %[t], %[any]\n\t" /* MOVE: 1s */
+ "b_test bteqz.t\n\t" /* Not taken: 2s */
+ "b_test bteqz.e\n\t" /* Not taken: 2s */
+ "b_test btnez.t\n\t" /* Taken: 1s */
+ "b_test btnez.e\n\t" /* Taken: 1s */
+ "nop\n\t" /* NOP: 1s */
+ ".globl step_stop\n\t" /* Total: 27s */
+ ".type step_stop, @function\n"
+ "step_stop:\n\t"
+ ".set pop\n"
+ : [t] "+t" (zero)
+ : [zero] "u" (zero), [any] "u" (any));
+
+ return err;
+}
+
+int
+main (void)
+{
+ return test_mips16_branch ();
+}
Index: binutils-gdb/gdb/testsuite/gdb.arch/mips16-branch.exp
===================================================================
--- /dev/null
+++ binutils-gdb/gdb/testsuite/gdb.arch/mips16-branch.exp
@@ -0,0 +1,30 @@
+# Copyright (C) 2026 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 through MIPS16 branch instructions.
+
+require {istarget "mips*-*-*"}
+
+source $srcdir/$subdir/mips-allow.exp.tcl
+
+require allow_mips16_ase_tests
+
+standard_testfile
+
+set steps 27
+foreach flag {-Wa,-W -mno-micromips -mips16 -minterlink-compressed} {
+ lappend compile_flags "additional_flags=$flag"
+}
+source $srcdir/$subdir/mips-stepi.exp.tcl
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 08/12] MIPS/testsuite: Verify microMIPS branch stepping
2026-08-17 16:53 [PATCH v2 00/12] MIPS+testsuite: BLEZL stepping fix and associated test infrastructure Maciej W. Rozycki
` (6 preceding siblings ...)
2026-08-17 16:53 ` [PATCH v2 07/12] MIPS/testsuite: Verify MIPS16 " Maciej W. Rozycki
@ 2026-08-17 16:53 ` Maciej W. Rozycki
2026-08-17 16:54 ` [PATCH v2 09/12] MIPS: Reorder a reference to "BGTZ, BGTZL" in `mips32_next_pc' Maciej W. Rozycki
` (3 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Maciej W. Rozycki @ 2026-08-17 16:53 UTC (permalink / raw)
To: gdb-patches
Cc: Jovan Dmitrovic, Djordje Todorovic, Milica Matic, Maciej W. Rozycki
From: Maciej W. Rozycki <macro@globalfoundries.com>
Verify that breakpoints are correctly placed via `micromips_next_pc'
while single-stepping through branches specific to the microMIPS ASE.
Approved-By: Maciej W. Rozycki <macro@orcam.me.uk>
---
New change in v2.
---
gdb/testsuite/gdb.arch/micromips-branch.c | 78 ++++++++++++++++++++++++++++
gdb/testsuite/gdb.arch/micromips-branch.exp | 30 ++++++++++
gdb/testsuite/gdb.arch/mips-allow.exp.tcl | 29 ++++++++++
3 files changed, 137 insertions(+)
gdb-micromips-next-pc-test.diff
Index: binutils-gdb/gdb/testsuite/gdb.arch/micromips-branch.c
===================================================================
--- /dev/null
+++ binutils-gdb/gdb/testsuite/gdb.arch/micromips-branch.c
@@ -0,0 +1,78 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright (C) 2026 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 usefu,
+ 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 through microMIPS branch instructions. */
+
+int
+test_micromips_branch (void)
+{
+ /* Make 'err' available to the debugger to track the number of single
+ steps executed. Use `volatile' to prevent the variable from being
+ optimized away. */
+ volatile int err = -1;
+
+ int any = 0x55aa;
+ int mone = -1;
+ int zero = 0;
+ int one = 1;
+
+ asm volatile (
+ ".macro b_test op, args:vararg\n\t"
+ "\\op \\args, 0f\n\t"
+ " nop\n"
+ "nop\n"
+ "0:\n\t"
+ ".endm\n\t"
+
+ ".set push\n\t"
+ ".set noreorder\n\t"
+ ".globl step_start\n\t"
+ ".type step_start, @function\n"
+ "step_start:\n\t" /* Units: steps. */
+ "nop\n\t" /* NOP: 1s */
+ "b_test beqz16 %[zero]\n\t" /* Taken: 1s */
+ "b_test beqz16 %[any]\n\t" /* Not taken: 2s */
+ "b_test beqzc %[zero]\n\t" /* Taken: 1s */
+ "b_test beqzc %[any]\n\t" /* Not taken: 3s */
+ "b_test bnez16 %[zero]\n\t" /* Not taken: 2s */
+ "b_test bnez16 %[any]\n\t" /* Taken: 1s */
+ "b_test bnezc %[zero]\n\t" /* Not taken: 3s */
+ "b_test bnezc %[any]\n\t" /* Taken: 1s */
+ "b_test bltzals, %[mone]\n\t" /* Taken: 1s */
+ "b_test bltzals, %[zero]\n\t" /* Not taken: 2s */
+ "b_test bltzals, %[one]\n\t" /* Not taken: 2s */
+ "b_test bgezals, %[mone]\n\t" /* Not taken: 2s */
+ "b_test bgezals, %[zero]\n\t" /* Taken: 1s */
+ "b_test bgezals, %[one]\n\t" /* Taken: 1s */
+ "nop\n\t" /* NOP: 1s */
+ ".globl step_stop\n\t" /* Total: 25s */
+ ".type step_stop, @function\n"
+ "step_stop:\n\t"
+ ".set pop\n"
+ :
+ : [mone] "r" (mone), [zero] "r" (zero), [one] "r" (one),
+ [any] "r" (any)
+ : "$31");
+
+ return err;
+}
+
+int
+main (void)
+{
+ return test_micromips_branch ();
+}
Index: binutils-gdb/gdb/testsuite/gdb.arch/micromips-branch.exp
===================================================================
--- /dev/null
+++ binutils-gdb/gdb/testsuite/gdb.arch/micromips-branch.exp
@@ -0,0 +1,30 @@
+# Copyright (C) 2026 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 through microMIPS branch instructions.
+
+require {istarget "mips*-*-*"}
+
+source $srcdir/$subdir/mips-allow.exp.tcl
+
+require allow_micromips_ase_tests
+
+standard_testfile
+
+set steps 25
+foreach flag {-Wa,-W -mno-mips16 -mmicromips -minterlink-compressed} {
+ lappend compile_flags "additional_flags=$flag"
+}
+source $srcdir/$subdir/mips-stepi.exp.tcl
Index: binutils-gdb/gdb/testsuite/gdb.arch/mips-allow.exp.tcl
===================================================================
--- binutils-gdb.orig/gdb/testsuite/gdb.arch/mips-allow.exp.tcl
+++ binutils-gdb/gdb/testsuite/gdb.arch/mips-allow.exp.tcl
@@ -124,3 +124,32 @@ proc allow_mips16_ase_tests {} {
} \
{-Wa,-fatal-warnings -mno-micromips -mips16 -minterlink-compressed}]
}
+
+# Check for microMIPS ASE support. These instructions may be absent,
+# such as with MIPS16 compilations. Make sure an actual JRADDIUSP
+# machine instruction is produced and no macro expanded such as with
+# `-Wa,-minsn32'.
+proc allow_micromips_ase_tests {} {
+ return [allow_target_tests "allow_micromips_ase_tests" \
+ "microMIPS instruction support" "(:?Bus error|Illegal instruction)" \
+ {
+ int main() {
+ extern const char jr asm("jr");
+ register char *ra asm("$31") = &jr;
+
+ asm volatile (
+ ".set push\n\t"
+ ".set noreorder\n\t"
+ ".set nomacro\n\t"
+ "jraddiusp 0\n\t"
+ ".globl jr\n\t"
+ ".type jr, @function\n"
+ "jr:\n\t"
+ ".set pop\n"
+ :
+ : "r" (ra));
+ return 0;
+ }
+ } \
+ {-Wa,-fatal-warnings -mno-mips16 -mmicromips -minterlink-compressed}]
+}
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 09/12] MIPS: Reorder a reference to "BGTZ, BGTZL" in `mips32_next_pc'
2026-08-17 16:53 [PATCH v2 00/12] MIPS+testsuite: BLEZL stepping fix and associated test infrastructure Maciej W. Rozycki
` (7 preceding siblings ...)
2026-08-17 16:53 ` [PATCH v2 08/12] MIPS/testsuite: Verify microMIPS " Maciej W. Rozycki
@ 2026-08-17 16:54 ` Maciej W. Rozycki
2026-08-17 16:54 ` [PATCH v2 10/12] MIPS: Correct segment calculation for MIPS16 JAL/X Maciej W. Rozycki
` (2 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Maciej W. Rozycki @ 2026-08-17 16:54 UTC (permalink / raw)
To: gdb-patches
Cc: Jovan Dmitrovic, Djordje Todorovic, Milica Matic, Maciej W. Rozycki
From: Maciej W. Rozycki <macro@globalfoundries.com>
Move a reference to "BGTZ, BGTZL" in `mips32_next_pc' to the leading
case label as with the other instructions called out in the function.
Approved-By: Maciej W. Rozycki <macro@orcam.me.uk>
---
No change from v1 (7/7),
<https://inbox.sourceware.org/gdb-patches/alpine.DEB.2.21.2607230115160.14485@angie.orcam.me.uk/>.
---
gdb/mips-tdep.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
gdb-mips-next-pc-bgtz-comment.diff
Index: binutils-gdb/gdb/mips-tdep.c
===================================================================
--- binutils-gdb.orig/gdb/mips-tdep.c
+++ binutils-gdb/gdb/mips-tdep.c
@@ -1822,9 +1822,9 @@ mips32_next_pc (struct regcache *regcach
else
pc += 8;
break;
- case 7:
+ case 7: /* BGTZ, BGTZL */
default:
- greater_branch: /* BGTZ, BGTZL */
+ greater_branch:
if (regcache_raw_get_signed (regcache, itype_rs (inst)) > 0)
pc += mips32_relative_offset (inst) + 4;
else
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 10/12] MIPS: Correct segment calculation for MIPS16 JAL/X
2026-08-17 16:53 [PATCH v2 00/12] MIPS+testsuite: BLEZL stepping fix and associated test infrastructure Maciej W. Rozycki
` (8 preceding siblings ...)
2026-08-17 16:54 ` [PATCH v2 09/12] MIPS: Reorder a reference to "BGTZ, BGTZL" in `mips32_next_pc' Maciej W. Rozycki
@ 2026-08-17 16:54 ` Maciej W. Rozycki
2026-08-17 16:54 ` [PATCH v2 11/12] MIPS: Return correct size from `mips_insn_size' " Maciej W. Rozycki
2026-08-17 16:54 ` [PATCH v2 12/12] MIPS: Fix stepping through instructions branching to own delay slot Maciej W. Rozycki
11 siblings, 0 replies; 13+ messages in thread
From: Maciej W. Rozycki @ 2026-08-17 16:54 UTC (permalink / raw)
To: gdb-patches
Cc: Jovan Dmitrovic, Djordje Todorovic, Milica Matic, Maciej W. Rozycki
From: Maciej W. Rozycki <macro@globalfoundries.com>
Fix an off-by-two segment calculation bug in determining the target PC
for MIPS16 JAL and JALX instructions in `extended_mips16_next_pc'. The
segment to use is determined by the address right after the instruction.
However unlike with extended instructions while JAL and JALX are being
decoded by said function `pc' points at the start of the instruction
rather than beyond the EXTEND prefix. Therefore the correct adjustment
for `pc' is 4 rather than 2.
This bug was originally present in `add_offset_16' and not eliminated
with the rewrite in commit 484933d11fca ("MIPS: Rewrite `add_offset_16'
to match its name").
No testcase added as that would require 256MiB+ of target memory and a
correspondingly large executable to be built, which seems not worth it
for such a corner-case bug.
Approved-By: Maciej W. Rozycki <macro@orcam.me.uk>
---
New change in v2.
---
gdb/mips-tdep.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
gdb-mips16-next-pc-jal.diff
Index: binutils-gdb/gdb/mips-tdep.c
===================================================================
--- binutils-gdb.orig/gdb/mips-tdep.c
+++ binutils-gdb/gdb/mips-tdep.c
@@ -2297,7 +2297,7 @@ extended_mips16_next_pc (regcache *regca
{
struct upk_mips16 upk;
unpack_mips16 (gdbarch, pc, extension, insn, jalxtype, &upk);
- pc = ((pc + 2) & (~(CORE_ADDR) 0x0fffffff)) | (upk.offset << 2);
+ pc = ((pc + 4) & (~(CORE_ADDR) 0x0fffffff)) | (upk.offset << 2);
if ((insn >> 10) & 0x01) /* Exchange mode */
pc = pc & ~0x01; /* Clear low bit, indicate 32 bit mode. */
else
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 11/12] MIPS: Return correct size from `mips_insn_size' for MIPS16 JAL/X
2026-08-17 16:53 [PATCH v2 00/12] MIPS+testsuite: BLEZL stepping fix and associated test infrastructure Maciej W. Rozycki
` (9 preceding siblings ...)
2026-08-17 16:54 ` [PATCH v2 10/12] MIPS: Correct segment calculation for MIPS16 JAL/X Maciej W. Rozycki
@ 2026-08-17 16:54 ` Maciej W. Rozycki
2026-08-17 16:54 ` [PATCH v2 12/12] MIPS: Fix stepping through instructions branching to own delay slot Maciej W. Rozycki
11 siblings, 0 replies; 13+ messages in thread
From: Maciej W. Rozycki @ 2026-08-17 16:54 UTC (permalink / raw)
To: gdb-patches
Cc: Jovan Dmitrovic, Djordje Todorovic, Milica Matic, Maciej W. Rozycki
From: Maciej W. Rozycki <macro@globalfoundries.com>
Among MIPS16 instructions not only the extended ones have the size of 4
bytes, but JAL and JALX as well, even though they have their distinct
major opcode and do not use the EXTEND prefix. Update `mips_insn_size'
accordingly.
This function is currently never called for ISA_MIPS16, so the bug does
not hit, but it will with the next change.
Approved-By: Maciej W. Rozycki <macro@orcam.me.uk>
---
New change in v2.
---
gdb/mips-tdep.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
gdb-mips16-insn-size-jal.diff
Index: binutils-gdb/gdb/mips-tdep.c
===================================================================
--- binutils-gdb.orig/gdb/mips-tdep.c
+++ binutils-gdb/gdb/mips-tdep.c
@@ -1563,7 +1563,8 @@ mips_insn_size (enum mips_isa isa, ULONG
else
return MIPS_INSN16_SIZE;
case ISA_MIPS16:
- if ((insn & 0xf800) == 0xf000)
+ if ((insn & 0xf800) == 0x1800
+ || (insn & 0xf800) == 0xf000)
return 2 * MIPS_INSN16_SIZE;
else
return MIPS_INSN16_SIZE;
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 12/12] MIPS: Fix stepping through instructions branching to own delay slot
2026-08-17 16:53 [PATCH v2 00/12] MIPS+testsuite: BLEZL stepping fix and associated test infrastructure Maciej W. Rozycki
` (10 preceding siblings ...)
2026-08-17 16:54 ` [PATCH v2 11/12] MIPS: Return correct size from `mips_insn_size' " Maciej W. Rozycki
@ 2026-08-17 16:54 ` Maciej W. Rozycki
11 siblings, 0 replies; 13+ messages in thread
From: Maciej W. Rozycki @ 2026-08-17 16:54 UTC (permalink / raw)
To: gdb-patches
Cc: Jovan Dmitrovic, Djordje Todorovic, Milica Matic, Maciej W. Rozycki
From: Maciej W. Rozycki <macro@globalfoundries.com>
Branching to own delay slot is not disallowed in the ISA and works as
expected. Especially for regular conditional branches it might be a
useful way to have the branch delay instruction conditionally executed
once or twice, which in some cases could avoid extra jumping around.
We do not handle this case specially in software stepping, which means
that for a taken branch or a jump a single-stepping breakpoint is placed
in the delay slot. This is also allowed by the ISA, however it causes
the execution of the containing branch to be abandoned and a breakpoint
exception triggered with the PC pointing at the branch. While the BD
bit is also set in the CP0 Cause register indicating the situation, we
do not examine it, following a deliberate design decision.
Consequently single-stepping over such a branch or jump loops forever
and execution progress cannot be made without manual intervention.
Recognize the situation then, and skip over the delay slot when placing
a single-stepping breakpoint, except for jumps that switch the ISA mode
(for which jumping to the delay slot instruction seems of questionable
use, even though valid) and where the delay slot instruction itself is a
branch or jump (which yields unpredictable operation according to the
ISA and is therefore unsupported; actual hardware implementations vary
from triggering the Reserved Instruction exception, through executing
the delay slot branch or jump instruction normally, to ignoring it and
proceeding from the target of the original branch or jump).
Add testcases accordingly, for MIPS I, MIPS II, MIPS16 and microMIPS CPU
branches and jumps, and DSP ASE branches except for 64-bit ones.
Approved-By: Maciej W. Rozycki <macro@orcam.me.uk>
---
New change in v2.
---
gdb/mips-tdep.c | 223 +++++++++++++++-------
gdb/testsuite/gdb.arch/micromips-branch-delay.c | 89 ++++++++
gdb/testsuite/gdb.arch/micromips-branch-delay.exp | 31 +++
gdb/testsuite/gdb.arch/micromips-jals-delay.c | 56 +++++
gdb/testsuite/gdb.arch/micromips-jals-delay.exp | 30 ++
gdb/testsuite/gdb.arch/mips-allow.exp.tcl | 58 +++++
gdb/testsuite/gdb.arch/mips-dsp-branch-delay.c | 62 ++++++
gdb/testsuite/gdb.arch/mips-dsp-branch-delay.exp | 31 +++
gdb/testsuite/gdb.arch/mips-jal-delay.c | 60 +++++
gdb/testsuite/gdb.arch/mips-jal-delay.exp | 27 ++
gdb/testsuite/gdb.arch/mips-jr-delay.c | 64 ++++++
gdb/testsuite/gdb.arch/mips-jr-delay.exp | 23 ++
gdb/testsuite/gdb.arch/mips1-bal-delay.c | 63 ++++++
gdb/testsuite/gdb.arch/mips1-bal-delay.exp | 31 +++
gdb/testsuite/gdb.arch/mips1-branch-delay.c | 67 ++++++
gdb/testsuite/gdb.arch/mips1-branch-delay.exp | 31 +++
gdb/testsuite/gdb.arch/mips2-branch-delay.c | 70 ++++++
gdb/testsuite/gdb.arch/mips2-branch-delay.exp | 31 +++
18 files changed, 980 insertions(+), 67 deletions(-)
gdb-mips-next-pc-bds.diff
Index: binutils-gdb/gdb/mips-tdep.c
===================================================================
--- binutils-gdb.orig/gdb/mips-tdep.c
+++ binutils-gdb/gdb/mips-tdep.c
@@ -1592,6 +1592,7 @@ mips32_bc1_pc (struct gdbarch *gdbarch,
int cnum = (itype_rt (inst) >> 2) & (count - 1);
int tf = itype_rt (inst) & 1;
int mask = (1 << count) - 1;
+ CORE_ADDR pc_adj;
ULONGEST fcs;
int cond;
@@ -1602,8 +1603,9 @@ mips32_bc1_pc (struct gdbarch *gdbarch,
fcs = regcache_raw_get_unsigned (regcache, fcsr);
cond = ((fcs >> 24) & 0xfe) | ((fcs >> 23) & 0x01);
- if (((cond >> cnum) & mask) != mask * !tf)
- pc += mips32_relative_offset (inst);
+ pc_adj = mips32_relative_offset (inst);
+ if (pc_adj && ((cond >> cnum) & mask) != mask * !tf)
+ pc += pc_adj;
else
pc += 4;
@@ -1647,6 +1649,7 @@ mips32_next_pc (struct regcache *regcach
{
struct gdbarch *gdbarch = regcache->arch ();
unsigned long inst;
+ CORE_ADDR pc_adj;
int op;
inst = mips_fetch_instruction (gdbarch, ISA_MIPS, pc, NULL);
op = itype_op (inst);
@@ -1702,10 +1705,12 @@ mips32_next_pc (struct regcache *regcach
if (op == 54 || op == 62)
bit += 32;
- if (((regcache_raw_get_signed (regcache,
- itype_rs (inst)) >> bit) & 1)
- == branch_if)
- pc += mips32_relative_offset (inst) + 4;
+ pc_adj = mips32_relative_offset (inst);
+ if (pc_adj
+ && ((regcache_raw_get_signed (regcache,
+ itype_rs (inst)) >> bit) & 1)
+ == branch_if)
+ pc += pc_adj + 4;
else
pc += 8; /* After the delay slot. */
}
@@ -1724,8 +1729,12 @@ mips32_next_pc (struct regcache *regcach
{
case 8: /* JR */
case 9: /* JALR */
- /* Set PC to that address. */
- pc = regcache_raw_get_signed (regcache, rtype_rs (inst));
+ /* Set PC to that address, avoiding the delay slot. */
+ pc_adj = regcache_raw_get_signed (regcache, rtype_rs (inst));
+ if (pc_adj != pc + 4)
+ pc = pc_adj;
+ else
+ pc += 8;
break;
case 12: /* SYSCALL */
{
@@ -1752,8 +1761,10 @@ mips32_next_pc (struct regcache *regcach
case 2: /* BLTZL */
case 16: /* BLTZAL */
case 18: /* BLTZALL */
- if (regcache_raw_get_signed (regcache, itype_rs (inst)) < 0)
- pc += mips32_relative_offset (inst) + 4;
+ pc_adj = mips32_relative_offset (inst);
+ if (pc_adj
+ && regcache_raw_get_signed (regcache, itype_rs (inst)) < 0)
+ pc += pc_adj + 4;
else
pc += 8; /* After the delay slot. */
break;
@@ -1761,8 +1772,10 @@ mips32_next_pc (struct regcache *regcach
case 3: /* BGEZL */
case 17: /* BGEZAL */
case 19: /* BGEZALL */
- if (regcache_raw_get_signed (regcache, itype_rs (inst)) >= 0)
- pc += mips32_relative_offset (inst) + 4;
+ pc_adj = mips32_relative_offset (inst);
+ if (pc_adj
+ && regcache_raw_get_signed (regcache, itype_rs (inst)) >= 0)
+ pc += pc_adj + 4;
else
pc += 8; /* After the delay slot. */
break;
@@ -1778,9 +1791,11 @@ mips32_next_pc (struct regcache *regcach
/* No way to handle; it'll most likely trap anyway. */
break;
- if ((regcache_raw_get_unsigned (regcache,
- dspctl) & 0x7f) >= pos)
- pc += mips32_relative_offset (inst);
+ pc_adj = mips32_relative_offset (inst);
+ if (pc_adj
+ && (regcache_raw_get_unsigned (regcache,
+ dspctl) & 0x7f) >= pos)
+ pc += pc_adj;
else
pc += 4;
}
@@ -1797,37 +1812,49 @@ mips32_next_pc (struct regcache *regcach
unsigned long reg;
reg = jtype_target (inst) << 2;
/* Upper four bits get never changed... */
- pc = reg + ((pc + 4) & ~(CORE_ADDR) 0x0fffffff);
+ pc_adj = reg + ((pc + 4) & ~(CORE_ADDR) 0x0fffffff);
+ if (pc_adj != pc + 4)
+ pc = pc_adj;
+ else
+ pc += 8;
}
break;
case 4: /* BEQ, BEQL */
equal_branch:
- if (regcache_raw_get_signed (regcache, itype_rs (inst)) ==
- regcache_raw_get_signed (regcache, itype_rt (inst)))
- pc += mips32_relative_offset (inst) + 4;
+ pc_adj = mips32_relative_offset (inst);
+ if (pc_adj
+ && (regcache_raw_get_signed (regcache, itype_rs (inst))
+ == regcache_raw_get_signed (regcache, itype_rt (inst))))
+ pc += pc_adj + 4;
else
pc += 8;
break;
case 5: /* BNE, BNEL */
neq_branch:
- if (regcache_raw_get_signed (regcache, itype_rs (inst)) !=
- regcache_raw_get_signed (regcache, itype_rt (inst)))
- pc += mips32_relative_offset (inst) + 4;
+ pc_adj = mips32_relative_offset (inst);
+ if (pc_adj
+ && (regcache_raw_get_signed (regcache, itype_rs (inst))
+ != regcache_raw_get_signed (regcache, itype_rt (inst))))
+ pc += pc_adj + 4;
else
pc += 8;
break;
case 6: /* BLEZ, BLEZL */
less_equal_branch:
- if (regcache_raw_get_signed (regcache, itype_rs (inst)) <= 0)
- pc += mips32_relative_offset (inst) + 4;
+ pc_adj = mips32_relative_offset (inst);
+ if (pc_adj
+ && regcache_raw_get_signed (regcache, itype_rs (inst)) <= 0)
+ pc += pc_adj + 4;
else
pc += 8;
break;
case 7: /* BGTZ, BGTZL */
default:
greater_branch:
- if (regcache_raw_get_signed (regcache, itype_rs (inst)) > 0)
- pc += mips32_relative_offset (inst) + 4;
+ pc_adj = mips32_relative_offset (inst);
+ if (pc_adj
+ && regcache_raw_get_signed (regcache, itype_rs (inst)) > 0)
+ pc += pc_adj + 4;
else
pc += 8;
break;
@@ -1887,6 +1914,7 @@ micromips_bc1_pc (struct gdbarch *gdbarc
int cnum = b2s3_cc (insn >> 16) & (count - 1);
int tf = b5s5_op (insn >> 16) & 1;
int mask = (1 << count) - 1;
+ CORE_ADDR pc_adj;
ULONGEST fcs;
int cond;
@@ -1897,8 +1925,9 @@ micromips_bc1_pc (struct gdbarch *gdbarc
fcs = regcache_raw_get_unsigned (regcache, fcsr);
cond = ((fcs >> 24) & 0xfe) | ((fcs >> 23) & 0x01);
- if (((cond >> cnum) & mask) != mask * !tf)
- pc += micromips_relative_offset16 (insn);
+ pc_adj = micromips_relative_offset16 (insn);
+ if (pc_adj && ((cond >> cnum) & mask) != mask * !tf)
+ pc += pc_adj;
else
pc += micromips_pc_insn_size (gdbarch, pc);
@@ -1912,6 +1941,7 @@ static CORE_ADDR
micromips_next_pc (struct regcache *regcache, CORE_ADDR pc)
{
struct gdbarch *gdbarch = regcache->arch ();
+ CORE_ADDR pc_adj;
ULONGEST insn;
insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, pc, NULL);
@@ -1935,8 +1965,12 @@ micromips_next_pc (struct regcache *regc
case 0x7c: /* JALR.HB: 000000 0001111100 111100 */
case 0x13c: /* JALRS: 000000 0100111100 111100 */
case 0x17c: /* JALRS.HB: 000000 0101111100 111100 */
- pc = regcache_raw_get_signed (regcache,
- b0s5_reg (insn >> 16));
+ pc_adj = regcache_raw_get_signed (regcache,
+ b0s5_reg (insn >> 16));
+ if (pc_adj != pc)
+ pc = pc_adj;
+ else
+ pc += micromips_pc_insn_size (gdbarch, pc);;
break;
case 0x22d: /* SYSCALL: 000000 1000101101 111100 */
{
@@ -1958,9 +1992,11 @@ micromips_next_pc (struct regcache *regc
case 0x00: /* BLTZ: bits 010000 00000 */
case 0x01: /* BLTZAL: bits 010000 00001 */
case 0x11: /* BLTZALS: bits 010000 10001 */
- if (regcache_raw_get_signed (regcache,
- b0s5_reg (insn >> 16)) < 0)
- pc += micromips_relative_offset16 (insn);
+ pc_adj = micromips_relative_offset16 (insn);
+ if (pc_adj
+ && regcache_raw_get_signed (regcache,
+ b0s5_reg (insn >> 16)) < 0)
+ pc += pc_adj;
else
pc += micromips_pc_insn_size (gdbarch, pc);
break;
@@ -1968,17 +2004,21 @@ micromips_next_pc (struct regcache *regc
case 0x02: /* BGEZ: bits 010000 00010 */
case 0x03: /* BGEZAL: bits 010000 00011 */
case 0x13: /* BGEZALS: bits 010000 10011 */
- if (regcache_raw_get_signed (regcache,
- b0s5_reg (insn >> 16)) >= 0)
- pc += micromips_relative_offset16 (insn);
+ pc_adj = micromips_relative_offset16 (insn);
+ if (pc_adj
+ && regcache_raw_get_signed (regcache,
+ b0s5_reg (insn >> 16)) >= 0)
+ pc += pc_adj;
else
pc += micromips_pc_insn_size (gdbarch, pc);
break;
case 0x04: /* BLEZ: bits 010000 00100 */
- if (regcache_raw_get_signed (regcache,
- b0s5_reg (insn >> 16)) <= 0)
- pc += micromips_relative_offset16 (insn);
+ pc_adj = micromips_relative_offset16 (insn);
+ if (pc_adj
+ && regcache_raw_get_signed (regcache,
+ b0s5_reg (insn >> 16)) <= 0)
+ pc += pc_adj;
else
pc += micromips_pc_insn_size (gdbarch, pc);
break;
@@ -1990,9 +2030,11 @@ micromips_next_pc (struct regcache *regc
break;
case 0x06: /* BGTZ: bits 010000 00110 */
- if (regcache_raw_get_signed (regcache,
- b0s5_reg (insn >> 16)) > 0)
- pc += micromips_relative_offset16 (insn);
+ pc_adj = micromips_relative_offset16 (insn);
+ if (pc_adj
+ && regcache_raw_get_signed (regcache,
+ b0s5_reg (insn >> 16)) > 0)
+ pc += pc_adj;
else
pc += micromips_pc_insn_size (gdbarch, pc);
break;
@@ -2020,9 +2062,11 @@ micromips_next_pc (struct regcache *regc
/* No way to handle; it'll most likely trap anyway. */
break;
- if ((regcache_raw_get_unsigned (regcache,
- dspctl) & 0x7f) >= pos)
- pc += micromips_relative_offset16 (insn);
+ pc_adj = micromips_relative_offset16 (insn);
+ if (pc_adj
+ && (regcache_raw_get_unsigned (regcache,
+ dspctl) & 0x7f) >= pos)
+ pc += pc_adj;
else
pc += micromips_pc_insn_size (gdbarch, pc);
}
@@ -2048,21 +2092,29 @@ micromips_next_pc (struct regcache *regc
case 0x1d: /* JALS: bits 011101 */
case 0x35: /* J: bits 110101 */
case 0x3d: /* JAL: bits 111101 */
- pc = ((pc | 0x7fffffe) ^ 0x7fffffe) | (b0s26_imm (insn) << 1);
+ pc_adj = ((pc | 0x7fffffe) ^ 0x7fffffe) | (b0s26_imm (insn) << 1);
+ if (pc_adj != pc)
+ pc = pc_adj;
+ else
+ pc += micromips_pc_insn_size (gdbarch, pc);;
break;
case 0x25: /* BEQ: bits 100101 */
- if (regcache_raw_get_signed (regcache, b0s5_reg (insn >> 16))
- == regcache_raw_get_signed (regcache, b5s5_reg (insn >> 16)))
- pc += micromips_relative_offset16 (insn);
+ pc_adj = micromips_relative_offset16 (insn);
+ if (pc_adj
+ && (regcache_raw_get_signed (regcache, b0s5_reg (insn >> 16))
+ == regcache_raw_get_signed (regcache, b5s5_reg (insn >> 16))))
+ pc += pc_adj;
else
pc += micromips_pc_insn_size (gdbarch, pc);
break;
case 0x2d: /* BNE: bits 101101 */
- if (regcache_raw_get_signed (regcache, b0s5_reg (insn >> 16))
- != regcache_raw_get_signed (regcache, b5s5_reg (insn >> 16)))
- pc += micromips_relative_offset16 (insn);
+ pc_adj = micromips_relative_offset16 (insn);
+ if (pc_adj
+ && (regcache_raw_get_signed (regcache, b0s5_reg (insn >> 16))
+ != regcache_raw_get_signed (regcache, b5s5_reg (insn >> 16))))
+ pc += pc_adj;
else
pc += micromips_pc_insn_size (gdbarch, pc);
break;
@@ -2078,20 +2130,33 @@ micromips_next_pc (struct regcache *regc
switch (micromips_op (insn))
{
case 0x11: /* POOL16C: bits 010001 */
- if ((b5s5_op (insn) & 0x1c) == 0xc)
- /* JR16, JRC, JALR16, JALRS16: 010001 011xx */
- pc = regcache_raw_get_signed (regcache, b0s5_reg (insn));
- else if (b5s5_op (insn) == 0x18)
- /* JRADDIUSP: bits 010001 11000 */
- pc = regcache_raw_get_signed (regcache, MIPS_RA_REGNUM);
+ switch (b5s5_op (insn))
+ {
+ case 0x0c: /* JR16: bits 010001 01100 */
+ case 0x0e: /* JALR16: bits 010001 01110 */
+ case 0x0f: /* JALRS16: bits 010001 01111 */
+ pc_adj = regcache_raw_get_signed (regcache, b0s5_reg (insn));
+ if (pc_adj != pc)
+ pc = pc_adj;
+ else
+ pc += micromips_pc_insn_size (gdbarch, pc);;
+ break;
+ case 0x0d: /* JRC: bits 010001 01101 */
+ pc = regcache_raw_get_signed (regcache, b0s5_reg (insn));
+ break;
+ case 0x18: /* JRADDIUSP: bits 010001 11000 */
+ pc = regcache_raw_get_signed (regcache, MIPS_RA_REGNUM);
+ break;
+ }
break;
case 0x23: /* BEQZ16: bits 100011 */
{
int rs = mips_reg3_to_reg[b7s3_reg (insn)];
- if (regcache_raw_get_signed (regcache, rs) == 0)
- pc += micromips_relative_offset7 (insn);
+ pc_adj = micromips_relative_offset7 (insn);
+ if (pc_adj && regcache_raw_get_signed (regcache, rs) == 0)
+ pc += pc_adj;
else
pc += micromips_pc_insn_size (gdbarch, pc);
}
@@ -2101,15 +2166,20 @@ micromips_next_pc (struct regcache *regc
{
int rs = mips_reg3_to_reg[b7s3_reg (insn)];
- if (regcache_raw_get_signed (regcache, rs) != 0)
- pc += micromips_relative_offset7 (insn);
+ pc_adj = micromips_relative_offset7 (insn);
+ if (pc_adj && regcache_raw_get_signed (regcache, rs) != 0)
+ pc += pc_adj;
else
pc += micromips_pc_insn_size (gdbarch, pc);
}
break;
case 0x33: /* B16: bits 110011 */
- pc += micromips_relative_offset10 (insn);
+ pc_adj = micromips_relative_offset10 (insn);
+ if (pc_adj)
+ pc += pc_adj;
+ else
+ pc += micromips_pc_insn_size (gdbarch, pc);;
break;
}
break;
@@ -2278,12 +2348,25 @@ add_offset_16 (CORE_ADDR pc, int offset)
return pc + (offset << 1) + 2;
}
+/* Return the size in bytes of the MIPS16 instruction at the address PC. */
+
+static int
+mips16_pc_insn_size (struct gdbarch *gdbarch, CORE_ADDR pc)
+{
+ ULONGEST insn;
+
+ insn = mips_fetch_instruction (gdbarch, ISA_MIPS16, pc, NULL);
+ return mips_insn_size (ISA_MIPS16, insn);
+}
+
static CORE_ADDR
extended_mips16_next_pc (regcache *regcache, CORE_ADDR pc,
unsigned int extension, unsigned int insn)
{
struct gdbarch *gdbarch = regcache->arch ();
int op = (insn >> 11);
+ CORE_ADDR pc_adj;
+
switch (op)
{
case 2: /* Branch */
@@ -2298,11 +2381,13 @@ extended_mips16_next_pc (regcache *regca
{
struct upk_mips16 upk;
unpack_mips16 (gdbarch, pc, extension, insn, jalxtype, &upk);
- pc = ((pc + 4) & (~(CORE_ADDR) 0x0fffffff)) | (upk.offset << 2);
+ pc_adj = ((pc + 4) & (~(CORE_ADDR) 0x0fffffff)) | (upk.offset << 2);
if ((insn >> 10) & 0x01) /* Exchange mode */
- pc = pc & ~0x01; /* Clear low bit, indicate 32 bit mode. */
+ pc = pc_adj & ~0x01; /* Clear low bit, indicate 32 bit mode. */
+ else if ((pc_adj | 0x01) != pc + 4)
+ pc = pc_adj | 0x01;
else
- pc |= 0x01;
+ pc += 4 + mips16_pc_insn_size (gdbarch, pc + 4);
break;
}
case 4: /* beqz */
@@ -2358,7 +2443,11 @@ extended_mips16_next_pc (regcache *regca
reg = mips_reg3_to_reg[upk.regx];
else
reg = 31; /* Function return instruction. */
- pc = regcache_raw_get_signed (regcache, reg);
+ pc_adj = regcache_raw_get_signed (regcache, reg);
+ if ((insn >> 7) & 0x01 || pc_adj != pc + 2)
+ pc = pc_adj;
+ else
+ pc += 2 + mips16_pc_insn_size (gdbarch, pc + 2);
}
else
pc += 2;
Index: binutils-gdb/gdb/testsuite/gdb.arch/micromips-branch-delay.c
===================================================================
--- /dev/null
+++ binutils-gdb/gdb/testsuite/gdb.arch/micromips-branch-delay.c
@@ -0,0 +1,89 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright (C) 2026 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 usefu,
+ 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 through microMIPS branch and jump instructions
+ to their delay slot. */
+
+int
+test_micromips_branch_delay (void)
+{
+ /* Make 'err' available to the debugger to track the number of single
+ steps executed. Use `volatile' to prevent the variable from being
+ optimized away. */
+ volatile int err = -1;
+
+ int mone = -1;
+ int zero = 0;
+
+ extern const char jr_one asm("jr_one");
+ extern const char jr_two asm("jr_two");
+ extern const char jr_thr asm("jr_thr");
+ extern const char jr_for asm("jr_for");
+
+ asm volatile (
+ ".macro b_test op, args:vararg\n\t"
+ ".ifb \\args\n\t"
+ "\\op 0f\n\t"
+ ".else\n\t"
+ "\\op \\args, 0f\n\t"
+ ".endif\n\t"
+ "0:\n\t"
+ " nop\n\t"
+ ".endm\n\t"
+
+ ".macro j_test op, reg, label\n\t"
+ "\\op \\reg\n\t"
+ ".globl \\label\n\t"
+ ".type \\label, @function\n"
+ "\\label:\n\t"
+ " nop\n\t"
+ ".endm\n\t"
+
+ ".set push\n\t"
+ ".set noreorder\n\t"
+ ".globl step_start\n\t"
+ ".type step_start, @function\n"
+ "step_start:\n\t" /* Units: steps. */
+ "nop\n\t" /* NOP: 1s */
+ "b_test b16\n\t" /* Taken: 1s */
+ "b_test beqz16, %[zero]\n\t" /* Taken: 1s */
+ "b_test bnez16, %[mone]\n\t" /* Taken: 1s */
+ "b_test bltzals, %[mone]\n\t" /* Taken: 1s */
+ "b_test bgezals, %[zero]\n\t" /* Taken: 1s */
+ "j_test jalr16, %[jr_one], jr_one\n\t" /* Taken: 1s */
+ "j_test jalrs16, %[jr_two], jr_two\n\t" /* Taken: 1s */
+ "j_test jalrs, %[jr_thr], jr_thr\n\t" /* Taken: 1s */
+ "j_test jalrs.hb, %[jr_for], jr_for\n\t" /* Taken: 1s */
+ "nop\n\t" /* NOP: 1s */
+ ".globl step_stop\n\t" /* Total: 11s */
+ ".type step_stop, @function\n"
+ "step_stop:\n\t"
+ ".set pop\n"
+ :
+ : [mone] "r" (mone), [zero] "r" (zero)
+ [jr_one] "r" (&jr_one), [jr_two] "r" (&jr_two),
+ [jr_thr] "r" (&jr_thr), [jr_for] "r" (&jr_for)
+ : "$31");
+
+ return err;
+}
+
+int
+main (void)
+{
+ return test_micromips_branch_delay ();
+}
Index: binutils-gdb/gdb/testsuite/gdb.arch/micromips-branch-delay.exp
===================================================================
--- /dev/null
+++ binutils-gdb/gdb/testsuite/gdb.arch/micromips-branch-delay.exp
@@ -0,0 +1,31 @@
+# Copyright (C) 2026 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 through microMIPS branch and jump instructions
+# to their delay slot.
+
+require {istarget "mips*-*-*"}
+
+source $srcdir/$subdir/mips-allow.exp.tcl
+
+require allow_micromips_ase_tests
+
+standard_testfile
+
+set steps 11
+foreach flag {-Wa,-W -mno-mips16 -mmicromips -minterlink-compressed} {
+ lappend compile_flags "additional_flags=$flag"
+}
+source $srcdir/$subdir/mips-stepi.exp.tcl
Index: binutils-gdb/gdb/testsuite/gdb.arch/micromips-jals-delay.c
===================================================================
--- /dev/null
+++ binutils-gdb/gdb/testsuite/gdb.arch/micromips-jals-delay.c
@@ -0,0 +1,56 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright (C) 2026 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 usefu,
+ 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 through microMIPS JALS to its delay slot. */
+
+int
+test_micromips_jals (void)
+{
+ /* Make 'err' available to the debugger to track the number of single
+ steps executed. Use `volatile' to prevent the variable from being
+ optimized away. */
+ volatile int err = -1;
+
+ asm volatile (
+ ".macro j_test op\n\t"
+ "\\op 0f\n"
+ "0:\n\t"
+ " nop\n\t"
+ ".endm\n\t"
+
+ ".set push\n\t"
+ ".set noreorder\n\t"
+ ".globl step_start\n\t"
+ ".type step_start, @function\n"
+ "step_start:\n\t" /* Units: steps. */
+ "nop\n\t" /* NOP: 1s */
+ "j_test jals\n\t" /* Taken: 1s */
+ "nop\n\t" /* NOP: 1s */
+ ".globl step_stop\n\t" /* Total: 3s */
+ ".type step_stop, @function\n"
+ "step_stop:\n\t"
+ ".set pop\n"
+ : : : "$31");
+
+ return err;
+}
+
+int
+main (void)
+{
+ return test_micromips_jals ();
+}
Index: binutils-gdb/gdb/testsuite/gdb.arch/micromips-jals-delay.exp
===================================================================
--- /dev/null
+++ binutils-gdb/gdb/testsuite/gdb.arch/micromips-jals-delay.exp
@@ -0,0 +1,30 @@
+# Copyright (C) 2026 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 through microMIPS JALS to its delay slot.
+
+require {istarget "mips*-*-*"}
+
+source $srcdir/$subdir/mips-allow.exp.tcl
+
+require allow_micromips_jals_tests
+
+standard_testfile
+
+set steps 3
+foreach flag {-Wa,-W -mno-mips16 -mmicromips -minterlink-compressed} {
+ lappend compile_flags "additional_flags=$flag"
+}
+source $srcdir/$subdir/mips-stepi.exp.tcl
Index: binutils-gdb/gdb/testsuite/gdb.arch/mips-allow.exp.tcl
===================================================================
--- binutils-gdb.orig/gdb/testsuite/gdb.arch/mips-allow.exp.tcl
+++ binutils-gdb/gdb/testsuite/gdb.arch/mips-allow.exp.tcl
@@ -15,6 +15,37 @@
# Feature availability check helpers for MIPS tests.
+# Check for JAL machine instruction support.
+#
+# The regular MIPS and microMIPS JAL assembly instruction is always
+# a macro, however in the non-PIC assembly mode it produces a single
+# machine instruction. In PIC/PIE assembly modes it expands to a PIC
+# call sequence using JALR instead. Make sure an actual JAL machine
+# instruction is produced and no macro expanded.
+#
+# MIPS16 JAL requires its jump target to be 32-bit aligned, so use
+# `.align' to satisfy this constraint.
+proc allow_mips_jal_tests {} {
+ return [allow_target_tests "allow_mips_jal_tests" \
+ "MIPS JAL support" "Segmentation fault" \
+ {
+ int main() {
+ asm volatile (
+ ".set push\n\t"
+ ".set noreorder\n\t"
+ ".set nomacro\n\t"
+ "jal 0f\n\t"
+ " nop\n\t"
+ ".align 2\n"
+ "0:\n\t"
+ ".set pop\n"
+ : : : "$31");
+ return 0;
+ }
+ } \
+ {-Wa,-fatal-warnings}]
+}
+
# Check for MIPS I branch support. These instructions may be absent,
# such as with MIPS16 compilations. Make sure an actual BLTZ machine
# instruction is produced and no macro expanded.
@@ -151,5 +182,32 @@ proc allow_micromips_ase_tests {} {
return 0;
}
} \
+ {-Wa,-fatal-warnings -mno-mips16 -mmicromips -minterlink-compressed}]
+}
+
+# Check for microMIPS JALS machine instruction support.
+#
+# The microMIPS JALS assembly instruction is always a macro, however
+# in the non-PIC assembly mode it produces a single machine instruction.
+# In PIC/PIE assembly modes it expands to a PIC call sequence using
+# JALRS instead. Make sure an actual JALS machine instruction is
+# produced and no macro expanded.
+proc allow_micromips_jals_tests {} {
+ return [allow_target_tests "allow_mips_jals_tests" \
+ "microMIPS JALS support" "Segmentation fault" \
+ {
+ int main() {
+ asm volatile (
+ ".set push\n\t"
+ ".set noreorder\n\t"
+ ".set nomacro\n\t"
+ "jals 0f\n\t"
+ " nop\n\t"
+ "0:\n\t"
+ ".set pop\n"
+ : : : "$31");
+ return 0;
+ }
+ } \
{-Wa,-fatal-warnings -mno-mips16 -mmicromips -minterlink-compressed}]
}
Index: binutils-gdb/gdb/testsuite/gdb.arch/mips-dsp-branch-delay.c
===================================================================
--- /dev/null
+++ binutils-gdb/gdb/testsuite/gdb.arch/mips-dsp-branch-delay.c
@@ -0,0 +1,62 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright (C) 2026 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 usefu,
+ 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 through MIPS DSP branch instructions
+ to their delay slot. */
+
+int
+test_mips_dsp_branch_delay (void)
+{
+ /* Make 'err' available to the debugger to track the number of single
+ steps executed. Use `volatile' to prevent the variable from being
+ optimized away. */
+ volatile int err = -1;
+
+ int thr_two = 32;
+
+ asm volatile (
+ ".macro b_test op\n\t"
+ "\\op 0f\n"
+ "0:\n\t"
+ " nop\n\t"
+ ".endm\n\t"
+
+ ".set push\n\t"
+ ".set noreorder\n\t"
+ ".globl step_start\n\t"
+ ".type step_start, @function\n"
+ "step_start:\n\t" /* Units: steps. */
+ "nop\n\t" /* NOP: 1s */
+ "wrdsp %[thr_two], 1\n\t" /* WRDSP: 1s */
+ "b_test bposge32\n\t" /* Taken: 1s */
+ "nop\n\t" /* NOP: 1s */
+ ".globl step_stop\n\t" /* Total: 4s */
+ ".type step_stop, @function\n"
+ "step_stop:\n\t"
+ ".set pop\n"
+ :
+ : [thr_two] "r" (thr_two)
+ : "$dsp_po");
+
+ return err;
+}
+
+int
+main (void)
+{
+ return test_mips_dsp_branch_delay ();
+}
Index: binutils-gdb/gdb/testsuite/gdb.arch/mips-dsp-branch-delay.exp
===================================================================
--- /dev/null
+++ binutils-gdb/gdb/testsuite/gdb.arch/mips-dsp-branch-delay.exp
@@ -0,0 +1,31 @@
+# Copyright (C) 2026 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 through MIPS DSP branch instructions
+# to their delay slot.
+
+require {istarget "mips*-*-*"}
+
+source $srcdir/$subdir/mips-allow.exp.tcl
+
+require allow_mips_dsp_ase_tests
+
+standard_testfile
+
+set steps 4
+foreach flag {-mno-mips16 -minterlink-compressed -mdsp} {
+ lappend compile_flags "additional_flags=$flag"
+}
+source $srcdir/$subdir/mips-stepi.exp.tcl
Index: binutils-gdb/gdb/testsuite/gdb.arch/mips-jal-delay.c
===================================================================
--- /dev/null
+++ binutils-gdb/gdb/testsuite/gdb.arch/mips-jal-delay.c
@@ -0,0 +1,60 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright (C) 2026 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 usefu,
+ 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 through JAL to its delay slot. */
+
+int
+test_mips_jal (void)
+{
+ /* Make 'err' available to the debugger to track the number of single
+ steps executed. Use `volatile' to prevent the variable from being
+ optimized away. */
+ volatile int err = -1;
+
+ /* MIPS16 JAL requires its jump target to be 32-bit aligned, so use
+ `.align' and two leading NOP instructions to meet this constraint. */
+ asm volatile (
+ ".macro j_test op\n\t"
+ "\\op 0f\n"
+ "0:\n\t"
+ " nop\n\t"
+ ".endm\n\t"
+
+ ".set push\n\t"
+ ".set noreorder\n\t"
+ ".align 2\n\t"
+ ".globl step_start\n\t"
+ ".type step_start, @function\n"
+ "step_start:\n\t" /* Units: steps. */
+ "nop\n\t" /* NOP: 1s */
+ "nop\n\t" /* NOP: 1s */
+ "j_test jal\n\t" /* Taken: 1s */
+ "nop\n\t" /* NOP: 1s */
+ ".globl step_stop\n\t" /* Total: 4s */
+ ".type step_stop, @function\n"
+ "step_stop:\n\t"
+ ".set pop\n"
+ : : : "$31");
+
+ return err;
+}
+
+int
+main (void)
+{
+ return test_mips_jal ();
+}
Index: binutils-gdb/gdb/testsuite/gdb.arch/mips-jal-delay.exp
===================================================================
--- /dev/null
+++ binutils-gdb/gdb/testsuite/gdb.arch/mips-jal-delay.exp
@@ -0,0 +1,27 @@
+# Copyright (C) 2026 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 through JAL to its delay slot.
+
+require {istarget "mips*-*-*"}
+
+source $srcdir/$subdir/mips-allow.exp.tcl
+
+require allow_mips_jal_tests
+
+standard_testfile
+
+set steps 4
+source $srcdir/$subdir/mips-stepi.exp.tcl
Index: binutils-gdb/gdb/testsuite/gdb.arch/mips-jr-delay.c
===================================================================
--- /dev/null
+++ binutils-gdb/gdb/testsuite/gdb.arch/mips-jr-delay.c
@@ -0,0 +1,64 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright (C) 2026 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 usefu,
+ 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 through JR to its delay slot. */
+
+int
+test_mips_jr (void)
+{
+ /* Make 'err' available to the debugger to track the number of single
+ steps executed. Use `volatile' to prevent the variable from being
+ optimized away. */
+ volatile int err = -1;
+
+ extern const char jr_one asm("jr_one");
+ extern const char jr_two asm("jr_two");
+
+ asm volatile (
+ ".macro j_test op, reg, label\n\t"
+ "\\op \\reg\n\t"
+ ".globl \\label\n\t"
+ ".type \\label, @function\n"
+ "\\label:\n\t"
+ " nop\n\t"
+ ".endm\n\t"
+
+ ".set push\n\t"
+ ".set noreorder\n\t"
+ ".globl step_start\n\t"
+ ".type step_start, @function\n"
+ "step_start:\n\t" /* Units: steps. */
+ "nop\n\t" /* NOP: 1s */
+ "j_test jr, %[jr_one], jr_one\n\t" /* Taken: 1s */
+ "j_test jalr, %[jr_two], jr_two\n\t" /* Taken: 1s */
+ "nop\n\t" /* NOP: 1s */
+ ".globl step_stop\n\t" /* Total: 4s */
+ ".type step_stop, @function\n"
+ "step_stop:\n\t"
+ ".set pop\n"
+ :
+ : [jr_one] "r" (&jr_one), [jr_two] "r" (&jr_two)
+ : "$31");
+
+ return err;
+}
+
+int
+main (void)
+{
+ return test_mips_jr ();
+}
Index: binutils-gdb/gdb/testsuite/gdb.arch/mips-jr-delay.exp
===================================================================
--- /dev/null
+++ binutils-gdb/gdb/testsuite/gdb.arch/mips-jr-delay.exp
@@ -0,0 +1,23 @@
+# Copyright (C) 2026 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 through JR to its delay slot.
+
+require {istarget "mips*-*-*"}
+
+standard_testfile
+
+set steps 4
+source $srcdir/$subdir/mips-stepi.exp.tcl
Index: binutils-gdb/gdb/testsuite/gdb.arch/mips1-bal-delay.c
===================================================================
--- /dev/null
+++ binutils-gdb/gdb/testsuite/gdb.arch/mips1-bal-delay.c
@@ -0,0 +1,63 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright (C) 2026 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 usefu,
+ 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 through MIPS I branch-and-link instructions
+ to their delay slot. */
+
+int
+test_mips1_bal_delay (void)
+{
+ /* Make 'err' available to the debugger to track the number of single
+ steps executed. Use `volatile' to prevent the variable from being
+ optimized away. */
+ volatile int err = -1;
+
+ int mone = -1;
+ int zero = 0;
+
+ asm volatile (
+ ".macro b_test op, args:vararg\n\t"
+ "\\op \\args, 0f\n"
+ "0:\n\t"
+ " nop\n\t"
+ ".endm\n\t"
+
+ ".set push\n\t"
+ ".set noreorder\n\t"
+ ".globl step_start\n\t"
+ ".type step_start, @function\n"
+ "step_start:\n\t" /* Units: steps. */
+ "nop\n\t" /* NOP: 1s */
+ "b_test bltzal, %[mone]\n\t" /* Taken: 1s */
+ "b_test bgezal, %[zero]\n\t" /* Taken: 1s */
+ "nop\n\t" /* NOP: 1s */
+ ".globl step_stop\n\t" /* Total: 4s */
+ ".type step_stop, @function\n"
+ "step_stop:\n\t"
+ ".set pop\n"
+ :
+ : [mone] "r" (mone), [zero] "r" (zero)
+ : "$31");
+
+ return err;
+}
+
+int
+main (void)
+{
+ return test_mips1_bal_delay ();
+}
Index: binutils-gdb/gdb/testsuite/gdb.arch/mips1-bal-delay.exp
===================================================================
--- /dev/null
+++ binutils-gdb/gdb/testsuite/gdb.arch/mips1-bal-delay.exp
@@ -0,0 +1,31 @@
+# Copyright (C) 2026 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 through MIPS I branch-and-link instructions
+# to their delay slot.
+
+require {istarget "mips*-*-*"}
+
+source $srcdir/$subdir/mips-allow.exp.tcl
+
+require allow_mips1_bal_tests
+
+standard_testfile
+
+set steps 4
+foreach flag {-mno-mips16 -minterlink-compressed} {
+ lappend compile_flags "additional_flags=$flag"
+}
+source $srcdir/$subdir/mips-stepi.exp.tcl
Index: binutils-gdb/gdb/testsuite/gdb.arch/mips1-branch-delay.c
===================================================================
--- /dev/null
+++ binutils-gdb/gdb/testsuite/gdb.arch/mips1-branch-delay.c
@@ -0,0 +1,67 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright (C) 2026 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 usefu,
+ 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 through MIPS I branch instructions
+ to their delay slot. */
+
+int
+test_mips1_branch_delay (void)
+{
+ /* Make 'err' available to the debugger to track the number of single
+ steps executed. Use `volatile' to prevent the variable from being
+ optimized away. */
+ volatile int err = -1;
+
+ int mone = -1;
+ int zero = 0;
+ int one = 1;
+
+ asm volatile (
+ ".macro b_test op, args:vararg\n\t"
+ "\\op \\args, 0f\n"
+ "0:\n\t"
+ " nop\n\t"
+ ".endm\n\t"
+
+ ".set push\n\t"
+ ".set noreorder\n\t"
+ ".globl step_start\n\t"
+ ".type step_start, @function\n"
+ "step_start:\n\t" /* Units: steps. */
+ "nop\n\t" /* NOP: 1s */
+ "b_test beq, %[zero], %[zero]\n\t" /* Taken: 1s */
+ "b_test bne, %[mone], %[one]\n\t" /* Taken: 1s */
+ "b_test bltz, %[mone]\n\t" /* Taken: 1s */
+ "b_test blez, %[zero]\n\t" /* Taken: 1s */
+ "b_test bgez, %[zero]\n\t" /* Taken: 1s */
+ "b_test bgtz, %[one]\n\t" /* Taken: 1s */
+ "nop\n\t" /* NOP: 1s */
+ ".globl step_stop\n\t" /* Total: 8s */
+ ".type step_stop, @function\n"
+ "step_stop:\n\t"
+ ".set pop\n"
+ :
+ : [mone] "r" (mone), [zero] "r" (zero), [one] "r" (one));
+
+ return err;
+}
+
+int
+main (void)
+{
+ return test_mips1_branch_delay ();
+}
Index: binutils-gdb/gdb/testsuite/gdb.arch/mips1-branch-delay.exp
===================================================================
--- /dev/null
+++ binutils-gdb/gdb/testsuite/gdb.arch/mips1-branch-delay.exp
@@ -0,0 +1,31 @@
+# Copyright (C) 2026 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 through MIPS I branch instructions
+# to their delay slot.
+
+require {istarget "mips*-*-*"}
+
+source $srcdir/$subdir/mips-allow.exp.tcl
+
+require allow_mips1_branch_tests
+
+standard_testfile
+
+set steps 8
+foreach flag {-mno-mips16 -minterlink-compressed} {
+ lappend compile_flags "additional_flags=$flag"
+}
+source $srcdir/$subdir/mips-stepi.exp.tcl
Index: binutils-gdb/gdb/testsuite/gdb.arch/mips2-branch-delay.c
===================================================================
--- /dev/null
+++ binutils-gdb/gdb/testsuite/gdb.arch/mips2-branch-delay.c
@@ -0,0 +1,70 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright (C) 2026 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 through MIPS II branch instructions
+ to their delay slot. */
+
+int
+test_mips2_branch_delay (void)
+{
+ /* Make 'err' available to the debugger to track the number of single
+ steps executed. Use `volatile' to prevent the variable from being
+ optimized away. */
+ volatile int err = -1;
+
+ int mone = -1;
+ int zero = 0;
+ int one = 1;
+
+ asm volatile (
+ ".macro b_test op, args:vararg\n\t"
+ "\\op \\args, 0f\n"
+ "0:\n\t"
+ " nop\n\t"
+ ".endm\n\t"
+
+ ".set push\n\t"
+ ".set noreorder\n\t"
+ ".globl step_start\n\t"
+ ".type step_start, @function\n"
+ "step_start:\n\t" /* Units: steps. */
+ "nop\n\t" /* NOP: 1s */
+ "b_test beql, %[zero], %[zero]\n\t" /* Taken: 1s */
+ "b_test bnel, %[mone], %[one]\n\t" /* Taken: 1s */
+ "b_test bltzl, %[mone]\n\t" /* Taken: 1s */
+ "b_test blezl, %[zero]\n\t" /* Taken: 1s */
+ "b_test bgezl, %[zero]\n\t" /* Taken: 1s */
+ "b_test bgtzl, %[one]\n\t" /* Taken: 1s */
+ "b_test bltzall, %[mone]\n\t" /* Taken: 1s */
+ "b_test bgezall, %[zero]\n\t" /* Taken: 1s */
+ "nop\n\t" /* NOP: 1s */
+ ".globl step_stop\n\t" /* Total: 10s */
+ ".type step_stop, @function\n"
+ "step_stop:\n\t"
+ ".set pop\n"
+ :
+ : [mone] "r" (mone), [zero] "r" (zero), [one] "r" (one)
+ : "$31");
+
+ return err;
+}
+
+int
+main (void)
+{
+ return test_mips2_branch_delay ();
+}
Index: binutils-gdb/gdb/testsuite/gdb.arch/mips2-branch-delay.exp
===================================================================
--- /dev/null
+++ binutils-gdb/gdb/testsuite/gdb.arch/mips2-branch-delay.exp
@@ -0,0 +1,31 @@
+# Copyright (C) 2026 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 through MIPS II branch instructions
+# to their delay slot.
+
+require {istarget "mips*-*-*"}
+
+source $srcdir/$subdir/mips-allow.exp.tcl
+
+require allow_mips2_branch_tests
+
+standard_testfile
+
+set steps 10
+foreach flag {-mno-mips16 -mno-micromips -minterlink-compressed} {
+ lappend compile_flags "additional_flags=$flag"
+}
+source $srcdir/$subdir/mips-stepi.exp.tcl
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2026-08-17 16:57 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-08-17 16:53 [PATCH v2 00/12] MIPS+testsuite: BLEZL stepping fix and associated test infrastructure Maciej W. Rozycki
2026-08-17 16:53 ` [PATCH v2 01/12] testsuite: Factor out target feature test template Maciej W. Rozycki
2026-08-17 16:53 ` [PATCH v2 02/12] PowerPC/testsuite: Reduce feature tests in terms of `allow_target_tests' Maciej W. Rozycki
2026-08-17 16:53 ` [PATCH v2 03/12] MIPS/testsuite: Verify MIPS I CPU branch stepping Maciej W. Rozycki
2026-08-17 16:53 ` [PATCH v2 04/12] MIPS: Correct BLEZL single-stepping Maciej W. Rozycki
2026-08-17 16:53 ` [PATCH v2 05/12] MIPS/testsuite: Verify MIPS II CPU branch stepping Maciej W. Rozycki
2026-08-17 16:53 ` [PATCH v2 06/12] MIPS/testsuite: Verify MIPS DSP ASE " Maciej W. Rozycki
2026-08-17 16:53 ` [PATCH v2 07/12] MIPS/testsuite: Verify MIPS16 " Maciej W. Rozycki
2026-08-17 16:53 ` [PATCH v2 08/12] MIPS/testsuite: Verify microMIPS " Maciej W. Rozycki
2026-08-17 16:54 ` [PATCH v2 09/12] MIPS: Reorder a reference to "BGTZ, BGTZL" in `mips32_next_pc' Maciej W. Rozycki
2026-08-17 16:54 ` [PATCH v2 10/12] MIPS: Correct segment calculation for MIPS16 JAL/X Maciej W. Rozycki
2026-08-17 16:54 ` [PATCH v2 11/12] MIPS: Return correct size from `mips_insn_size' " Maciej W. Rozycki
2026-08-17 16:54 ` [PATCH v2 12/12] MIPS: Fix stepping through instructions branching to own delay slot Maciej W. Rozycki
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox