Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Luis <luis.machado.foss@gmail.com>
To: Ezra.Sitorus@arm.com, gdb-patches@sourceware.org
Cc: thiago.bauermann@linaro.org
Subject: Re: [PATCH 2/4] gdb/aarch64: Test record/replay support for CSSC
Date: Fri, 24 Apr 2026 08:07:08 +0100	[thread overview]
Message-ID: <c9cb5e29-151c-41d0-9624-10037a460c19@gmail.com> (raw)
In-Reply-To: <20260420215232.68675-3-Ezra.Sitorus@arm.com>

On 20/04/2026 22:52, Ezra.Sitorus@arm.com wrote:
> 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.
> +

Not for this series, but if we're going to repeat these entries, we 
might split off the common parts of Arm record/replay testing and 
include them in testcases that only have unique logic.

> +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
> +}
> +

Again, the same for this function. To avoid proliferating duplicated 
content, we could have a main body that does the testing based on 
arguments passed, like source file and compiler flags.

>   # 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.

Looks reasonable to me, assuming these have passed on QEMU.

I'll wait for Guinevere's input.

Reviewed-By: Luis Machado <luis.machado.foss@gmail.com>

  reply	other threads:[~2026-04-24  7:07 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 ` [PATCH 2/4] gdb/aarch64: Test record/replay support for CSSC Ezra.Sitorus
2026-04-24  7:07   ` Luis [this message]
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=c9cb5e29-151c-41d0-9624-10037a460c19@gmail.com \
    --to=luis.machado.foss@gmail.com \
    --cc=Ezra.Sitorus@arm.com \
    --cc=gdb-patches@sourceware.org \
    --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