Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: <Ezra.Sitorus@arm.com>
To: <gdb-patches@sourceware.org>
Cc: <luis.machado.foss@gmail.com>, <thiago.bauermann@linaro.org>,
	Ezra Sitorus <ezra.sitorus@arm.com>
Subject: [PATCH 2/4] gdb/aarch64: Test record/replay support for CSSC
Date: Mon, 20 Apr 2026 22:52:30 +0100	[thread overview]
Message-ID: <20260420215232.68675-3-Ezra.Sitorus@arm.com> (raw)
In-Reply-To: <20260420215232.68675-1-Ezra.Sitorus@arm.com>

From: Ezra Sitorus <ezra.sitorus@arm.com>

This patch checks that the handling of CSSC instructions is correct.
There is no explicit support for handling these instructions which is
why this patch is composed of tests.

Regression tested on aarch64-none-linux-gnu on QEMU with CSSC support.
I observe unrelated regressions that appear to be environmental rather
than caused by this patch.
---
 gdb/testsuite/gdb.reverse/aarch64-cssc.c   | 113 +++++++++++++++++
 gdb/testsuite/gdb.reverse/aarch64-cssc.exp | 141 +++++++++++++++++++++
 gdb/testsuite/lib/gdb.exp                  |  52 ++++++++
 3 files changed, 306 insertions(+)
 create mode 100644 gdb/testsuite/gdb.reverse/aarch64-cssc.c
 create mode 100644 gdb/testsuite/gdb.reverse/aarch64-cssc.exp

diff --git a/gdb/testsuite/gdb.reverse/aarch64-cssc.c b/gdb/testsuite/gdb.reverse/aarch64-cssc.c
new file mode 100644
index 00000000000..d80d202590c
--- /dev/null
+++ b/gdb/testsuite/gdb.reverse/aarch64-cssc.c
@@ -0,0 +1,113 @@
+/* This test program is part of GDB, the GNU debugger.
+
+   Copyright 2024-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/>.  */
+
+#include <stdint.h>
+
+#define PREPARE_REGS(X, Y, Z) \
+	__asm__ volatile ("mov %0, %1\n" : "=r"(xa): "r"(X):); \
+	__asm__ volatile ("mov %0, %1\n" : "=r"(xb): "r"(Y):); \
+	__asm__ volatile ("mov %0, %1\n" : "=r"(xc): "r"(Z):); \
+
+int
+main (void)
+{
+  register uint64_t xa asm ("x19");
+  register uint32_t xb asm ("x20");
+  register uint64_t xc asm ("x21");
+  const uint64_t a = 0x0123456789abcdef;
+  const uint64_t b = 0xfedbca9876543210;
+  const uint64_t c = 0xdeadbeefc001face;
+
+  PREPARE_REGS (a, b, c);
+  /* Before abs.  */
+  __asm__ volatile ("abs %0, %1\n"
+		    : "+r"(xa)
+		    : "r"(xb));
+  /* After abs.  */
+
+  PREPARE_REGS (a, b, c);
+  /* Before cnt.  */
+  __asm__ volatile ("cnt %0, %1\n"
+		    : "+r"(xa)
+		    : "r"(xb));
+  /* After cnt.  */
+
+  PREPARE_REGS (a, b, c);
+  /* Before ctz.  */
+  __asm__ volatile ("ctz %0, %1\n"
+		    : "+r"(xa)
+		    : "r"(xb));
+  /* After ctz.  */
+
+  PREPARE_REGS (a, b, c);
+  /* Before smax-1.  */
+  __asm__ volatile ("smax %0, %1, #10\n"
+		    : "+r"(xa)
+		    : "r"(xb));
+  /* After smax-1.  */
+
+  PREPARE_REGS (a, b, c);
+  /* Before smax-2.  */
+  __asm__ volatile ("smax %0, %1, %2\n"
+		    : "+r"(xa)
+		    : "r"(xb), "r"(xc));
+  /* After smax-2.  */
+
+  PREPARE_REGS (a, b, c);
+  /* Before smin-1.  */
+  __asm__ volatile ("smin %0, %1, #10\n"
+		    : "+r"(xa)
+		    : "r"(xb));
+  /* After smin-1.  */
+
+  PREPARE_REGS (a, b, c);
+  /* Before smin-2.  */
+  __asm__ volatile ("smin %0, %1, %2\n"
+		    : "+r"(xa)
+		    : "r"(xb), "r"(xc));
+  /* After smin-2.  */
+
+  PREPARE_REGS (a, b, c);
+  /* Before umax-1.  */
+  __asm__ volatile ("umax %0, %1, #10\n"
+		    : "+r"(xa)
+		    : "r"(xb));
+  /* After umax-1.  */
+
+  PREPARE_REGS (a, b, c);
+  /* Before umax-2.  */
+  __asm__ volatile ("umax %0, %1, %2\n"
+		    : "+r"(xa)
+		    : "r"(xb), "r"(xc));
+  /* After umax-2.  */
+
+  PREPARE_REGS (a, b, c);
+  /* Before umin-1.  */
+  __asm__ volatile ("umin %0, %1, #10\n"
+		    : "+r"(xa)
+		    : "r"(xb));
+  /* After umin-1.  */
+
+  PREPARE_REGS (a, b, c);
+  /* Before umin-2.  */
+  __asm__ volatile ("umin %0, %1, %2\n"
+		    : "+r"(xa)
+		    : "r"(xb), "r"(xc));
+  /* After umin-2.  */
+
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.reverse/aarch64-cssc.exp b/gdb/testsuite/gdb.reverse/aarch64-cssc.exp
new file mode 100644
index 00000000000..640ea4ae19f
--- /dev/null
+++ b/gdb/testsuite/gdb.reverse/aarch64-cssc.exp
@@ -0,0 +1,141 @@
+# Copyright 2024-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 instruction record for AArch64 FEAT_CSSC instructions.
+# Based on gdb.reverse/aarch64-mops.exp
+#
+# The basic flow of the record tests are:
+#    1) Stop before executing the instructions of interest.  Record
+#       the initial value of the registers that the instruction will
+#       change, i.e. the destination register.
+#    2) Execute the instructions.  Record the new value of the
+#       registers that changed.
+#    3) Reverse the direction of the execution and execute back to
+#       just before the instructions of interest.  Record the final
+#       value of the registers of interest.
+#    4) Check that the initial and new values of the registers are
+#       different, i.e. the instruction changed the registers as expected.
+#    5) Check that the initial and final values of the registers are
+#       the same, i.e. GDB record restored the registers to their
+#       original values.
+
+require allow_aarch64_cssc_tests
+standard_testfile
+
+if {
+    [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \
+	[list debug additional_flags=-march=armv8-a+cssc]]
+} {
+    return -1
+}
+
+if {![runto_main]} {
+    return -1
+}
+
+gdb_test_no_output "record full"
+
+proc test_single_asm { name } {
+    global decimal hex
+
+    set before_seq [gdb_get_line_number "Before ${name}"]
+    set after_seq [gdb_get_line_number "After ${name}"]
+    set regs { x19 x20 x21 }
+
+    set insn [lindex [split $name "-"] 0]
+
+    gdb_test "break $before_seq" \
+	"Breakpoint $decimal at $hex: file .*/aarch64-cssc.c, line $decimal\\." \
+	"$insn: break before instruction sequence"
+    gdb_continue_to_breakpoint "$insn: about to execute instruction sequence" \
+	[multi_line ".*/aarch64-cssc.c:$decimal" \
+	    "$decimal\[ \t\]+__asm__ volatile \\(\"${insn} \[^\r\n\]+\""]
+
+    # Depending on the compiler, the line number information may put GDB a few
+    # instructions before the beginning of the asm statement.
+    arrive_at_instruction $insn
+    # Add a breakpoint that we're sure is at the prologue instruction.
+    gdb_test "break *\$pc" \
+	"Breakpoint $decimal at $hex: file .*/aarch64-cssc.c, line $decimal\\." \
+	"$insn: break at prologue instruction"
+
+    # Record the initial register values.
+    foreach r $regs {
+	set ${r}_initial [capture_command_output "info register $r" ""]
+    }
+
+    gdb_test "break $after_seq" \
+	"Breakpoint $decimal at $hex: file .*/aarch64-cssc.c, line $decimal\\." \
+	"$insn: break after instruction sequence"
+    gdb_continue_to_breakpoint "$insn: executed instruction sequence" \
+	[multi_line ".*/aarch64-cssc.c:$decimal" ".*"]
+
+    # Record the new register values.
+    foreach r $regs {
+	set ${r}_new [capture_command_output "info register $r" ""]
+    }
+
+    # Execute in reverse to before the instruction sequence.
+    gdb_test_no_output "set exec-direction reverse"
+
+    gdb_continue_to_breakpoint "reversed execution of instruction sequence" \
+	[multi_line ".*/aarch64-cssc.c:$decimal" \
+	    "$decimal\[ \t\]+__asm__ volatile \\(\"${insn} \[^\r\n\]+\""]
+
+    # Record the final register values.
+    foreach r $regs {
+	set ${r}_final [capture_command_output "info register $r" ""]
+    }
+
+    foreach v { x19 x20 x21 } {
+	gdb_assert ![string compare [set ${v}_initial] [set ${v}_final]] \
+	    "$insn: check $v initial value versus $v final value"
+    }
+
+    gdb_assert [string compare [set x19_initial] [set x19_new]] \
+	    "$insn: check x19 initial value versus x19 new value"
+
+    foreach v { x20 x21 } {
+	gdb_assert ![string compare [set ${v}_initial] [set ${v}_new]] \
+	    "$insn: check $v initial value versus $v new value"
+    }
+
+    # Restore forward execution and go to end of recording.
+    gdb_test_no_output "set exec-direction forward"
+    gdb_test "record goto end" \
+	[multi_line \
+	    "Go forward to insn number $decimal" \
+	    "#0  main \\(\\) at .*/aarch64-cssc.c:$decimal" \
+	    ".*"]
+}
+
+set cases {
+	{ abs }
+	{ cnt }
+	{ ctz }
+	{ smax-1 }
+	{ smax-2 }
+	{ smin-1 }
+	{ smin-2 }
+	{ umax-1 }
+	{ umax-2 }
+	{ umin-1 }
+	{ umin-2 }
+}
+
+foreach c $cases {
+    lassign $c insn
+    test_single_asm $insn
+}
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index c6afc556548..7d400e9028a 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -5350,6 +5350,58 @@ gdb_caching_proc allow_aarch64_lrcpc3_tests {} {
     return $allow_lrcpc3_tests
 }
 
+# Run a test on the target to see if it supports the AArch64 CSSC feature.
+# Return 1 if so, 0 if it does not.  Note this causes a restart of GDB.
+
+gdb_caching_proc allow_aarch64_cssc_tests {} {
+    global srcdir subdir gdb_prompt inferior_exited_re
+
+    set me "allow_aarch64_cssc_tests"
+
+    if { ![is_aarch64_target]} {
+	return 0
+    }
+
+    set compile_flags "{additional_flags=-march=armv8-a+cssc}"
+
+    # Compile a test program reading CSSC.
+    set src {
+	int main() {
+	    asm volatile ("abs x0, x1");
+	    return 0;
+	}
+    }
+
+    if {![gdb_simple_compile $me $src executable $compile_flags]} {
+	    return 0
+    }
+
+    # Compilation succeeded so now run it via gdb.
+    clean_restart
+    gdb_load $obj
+    gdb_run_cmd
+
+    gdb_expect {
+	-re ".*Illegal instruction.*${gdb_prompt} $" {
+	    verbose -log "\n$me cssc support not detected"
+	    set allow_cssc_tests 0
+	}
+	-re ".*$inferior_exited_re normally.*${gdb_prompt} $" {
+	    verbose -log "\n$me: cssc support detected"
+	    set allow_cssc_tests 1
+	}
+	default {
+	  warning "\n$me: default case taken"
+	    set allow_cssc_tests 0
+	}
+    }
+    gdb_exit
+    remote_file build delete $obj
+
+    verbose "$me:  returning $allow_cssc_tests" 2
+    return $allow_cssc_tests
+}
+
 # Run a test on the target to see if it supports AArch64 MOPS (Memory
 # Operations) extensions.  Return 1 if so, 0 if it does not.  Note this
 # causes a restart of GDB.
-- 
2.43.0


  parent reply	other threads:[~2026-04-20 21:54 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-20 21:52 [PATCH 0/4] gdb/aarch64: record/replay support for AArch64 Ezra.Sitorus
2026-04-20 21:52 ` [PATCH 1/4] gdb/aarch64: record/replay support for LRCPC3 Ezra.Sitorus
2026-04-24  7:00   ` Luis
2026-04-24 15:09   ` Guinevere Larsen
2026-04-25  5:08   ` Thiago Jung Bauermann
2026-04-25  7:21   ` Thiago Jung Bauermann
2026-04-20 21:52 ` Ezra.Sitorus [this message]
2026-04-24  7:07   ` [PATCH 2/4] gdb/aarch64: Test record/replay support for CSSC Luis
2026-04-24 16:53   ` Guinevere Larsen
2026-04-25  6:10   ` Thiago Jung Bauermann
2026-04-25  7:28   ` Thiago Jung Bauermann
2026-04-20 21:52 ` [PATCH 3/4] gdb/aarch64: record/replay support for RPRFM and PRFM (reg) Ezra.Sitorus
2026-04-24  7:08   ` Luis
2026-04-24 16:56   ` Guinevere Larsen
2026-04-25  8:12   ` Thiago Jung Bauermann
2026-04-20 21:52 ` [PATCH 4/4] gdb/aarch64: record/replay support for LSE128 Ezra.Sitorus
2026-04-24  7:11   ` Luis
2026-04-24 17:12   ` Guinevere Larsen
2026-04-25  8:38   ` Thiago Jung Bauermann
2026-04-23 17:31 ` [PATCH 0/4] gdb/aarch64: record/replay support for AArch64 Guinevere Larsen
2026-04-23 22:20   ` Ezra Sitorus
2026-04-24  5:33   ` Thiago Jung Bauermann
2026-04-24  7:16 ` Luis

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=20260420215232.68675-3-Ezra.Sitorus@arm.com \
    --to=ezra.sitorus@arm.com \
    --cc=gdb-patches@sourceware.org \
    --cc=luis.machado.foss@gmail.com \
    --cc=thiago.bauermann@linaro.org \
    /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