Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: "Maciej W. Rozycki" <macro@orcam.me.uk>
To: gdb-patches@sourceware.org
Cc: Jovan Dmitrovic <jovan.dmitrovic@htecgroup.com>,
	 Djordje Todorovic <Djordje.Todorovic@htecgroup.com>,
	 Milica Matic <milica.matic@htecgroup.com>,
	 "Maciej W. Rozycki" <macro@globalfoundries.com>
Subject: [PATCH 3/7] MIPS/testsuite: Verify MIPS I CPU branch stepping
Date: Thu, 23 Jul 2026 19:52:56 +0100 (BST)	[thread overview]
Message-ID: <alpine.DEB.2.21.2607230010440.14485@angie.orcam.me.uk> (raw)
In-Reply-To: <alpine.DEB.2.21.2607220148540.14485@angie.orcam.me.uk>

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.

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>
---
 gdb/testsuite/gdb.arch/mips-allow.exp.tcl |   61 ++++++++++++++++++++++
 gdb/testsuite/gdb.arch/mips-stepi.exp.tcl |   78 +++++++++++++++++++++++++++++
 gdb/testsuite/gdb.arch/mips1-bal.c        |   70 ++++++++++++++++++++++++++
 gdb/testsuite/gdb.arch/mips1-bal.exp      |   30 +++++++++++
 gdb/testsuite/gdb.arch/mips1-branch.c     |   80 ++++++++++++++++++++++++++++++
 gdb/testsuite/gdb.arch/mips1-branch.exp   |   30 +++++++++++
 6 files changed, 349 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,78 @@
+# 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
+
+    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" { }
+		}
+		pass $message
+		return 1
+	    }
+	    -re ".*$gdb_prompt" {
+		send_gdb "set err -= 1\n"
+		gdb_expect {
+		    -re "$gdb_prompt" { }
+		}
+	    }
+	}
+    }
+    fail $message
+    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,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 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 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	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),
+	  [any] "r" (any)
+	: "$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,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 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)
+	: "$31");
+
+  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

  parent reply	other threads:[~2026-07-23 18:53 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-23 18:52 [PATCH 0/7] MIPS+testsuite: BLEZL stepping fix and associated test infrastructure Maciej W. Rozycki
2026-07-23 18:52 ` [PATCH 1/7] testsuite: Factor out target feature test template Maciej W. Rozycki
2026-07-23 18:52 ` [PATCH 2/7] PowerPC/testsuite: Reduce feature tests in terms of `allow_target_tests' Maciej W. Rozycki
2026-07-23 18:52 ` Maciej W. Rozycki [this message]
2026-07-23 18:53 ` [PATCH 4/7] MIPS: Correct BLEZL single-stepping Maciej W. Rozycki
2026-07-23 18:53 ` [PATCH 5/7] MIPS/testsuite: Verify MIPS II CPU branch stepping Maciej W. Rozycki
2026-07-23 18:53 ` [PATCH 6/7] MIPS/testsuite: Verify MIPS16 " Maciej W. Rozycki
2026-07-23 18:53 ` [PATCH 7/7] MIPS: Reorder a reference to "BGTZ, BGTZL" in `mips32_next_pc' Maciej W. Rozycki

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=alpine.DEB.2.21.2607230010440.14485@angie.orcam.me.uk \
    --to=macro@orcam.me.uk \
    --cc=Djordje.Todorovic@htecgroup.com \
    --cc=gdb-patches@sourceware.org \
    --cc=jovan.dmitrovic@htecgroup.com \
    --cc=macro@globalfoundries.com \
    --cc=milica.matic@htecgroup.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox