From: Guinevere Larsen <guinevere@redhat.com>
To: Ezra.Sitorus@arm.com, gdb-patches@sourceware.org
Cc: luis.machado.foss@gmail.com, thiago.bauermann@linaro.org
Subject: Re: [PATCH v2 1/4] gdb/aarch64: record/replay support for LRCPC3
Date: Tue, 26 May 2026 11:30:10 -0300 [thread overview]
Message-ID: <f741185a-f505-439f-9951-53c2a4d6003a@redhat.com> (raw)
In-Reply-To: <20260512231707.18123-2-Ezra.Sitorus@arm.com>
On 5/12/26 8:17 PM, Ezra.Sitorus@arm.com wrote:
> From: Ezra Sitorus <ezra.sitorus@arm.com>
>
> FEAT_LRCPC3 introduces various load/store instructions with release
> consistency for cases where ordering is required. This patch teaches GDB
> to decode these instructions for recording and reversing.
>
> The gdb.reverse/aarch64-lrcpc3.exp testcase verifies that the
> instructions are recorded and correctly reversed. In particular, there
> are some interesting cases to note:
> * ldapur/stlur are SIMD instructions, but are not decoded in the simd
> function.
> * There are writeback cases to cover too. These were taken from the
> binutils testcases: gas/testsuite/gas/aarch64/rcpc3.s.
>
> The full testsuite was done on aarch64-none-linux-gnu without LRCPC3.
> The gdb.arch and gdb.reverse tests were run on Shrinkwrap with LRCPC3
> support.
>
> Please note:
> 1) There is no support for LRCPC and LRCPC2 instructions
> 2) LRCPC3 is gated with +rcpc3 in GCC/binutils and LLVM.
> ---
Hi Ezra! I have one tiny comment with regards to the test (that can
truthfully probably be ignored), but you shouldn't need to send a v3
just to fix that. Feel free to add my review tag
Reviewed-By: Guinevere Larsen <guinevere@redhat.com
> gdb/aarch64-tdep.c | 87 ++++++++
> gdb/testsuite/gdb.reverse/aarch64-lrcpc3.c | 216 +++++++++++++++++++
> gdb/testsuite/gdb.reverse/aarch64-lrcpc3.exp | 203 +++++++++++++++++
> gdb/testsuite/lib/gdb.exp | 63 ++++++
> 4 files changed, 569 insertions(+)
> create mode 100644 gdb/testsuite/gdb.reverse/aarch64-lrcpc3.c
> create mode 100644 gdb/testsuite/gdb.reverse/aarch64-lrcpc3.exp
>
<snip>
> diff --git a/gdb/testsuite/gdb.reverse/aarch64-lrcpc3.exp b/gdb/testsuite/gdb.reverse/aarch64-lrcpc3.exp
> new file mode 100644
> index 00000000..adcf2906
> --- /dev/null
> +++ b/gdb/testsuite/gdb.reverse/aarch64-lrcpc3.exp
> @@ -0,0 +1,203 @@
> +# 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_LRCPC3 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_lrcpc3_tests
> +
> +standard_testfile
> +
> +if {[prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \
> + [list debug additional_flags=-march=armv8-a+rcpc3]]} {
> + return
> +}
> +
> +if {![runto_main]} {
> + return
> +}
> +
> +gdb_test_no_output "record full"
> +
> +proc test_single_asm {name diff_reg diff_var diff_mem same_reg same_var same_mem} {
> + with_test_prefix $name {
> +
> + set before_seq [gdb_get_line_number "Before ${name}"]
> + set after_seq [gdb_get_line_number "After ${name}"]
> +
> + set insn [lindex [split $name "-"] 0]
> +
> + gdb_test "break $before_seq" \
> + "Breakpoint ${::decimal} at ${::hex}: file .*/aarch64-lrcpc3.c, line ${::decimal}\\." \
> + "$insn before instruction sequence"
> +
> + gdb_continue_to_breakpoint "about to execute instruction sequence" \
> + [multi_line ".*/aarch64-lrcpc3.c:${::decimal}" \
> + "${::decimal}\[ \t\]+__asm__ volatile \\(\"${insn} .*\".*"]
> +
> + # 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-lrcpc3.c, line ${::decimal}\\." \
> + "break at prologue instruction"
> +
> + # Record the initial memory and register values.
> + set regs [concat $diff_reg $same_reg]
> + set vars [concat $diff_var $same_var]
> + set mem [concat $diff_mem $same_mem]
> + foreach r $regs {
> + set ${r}_initial [capture_command_output "info register $r" ""]
> + }
> + foreach v $vars {
> + set ${v}_initial [get_valueof "/x" "$v" "unable to read $v" \
> + "get $v initial value"]
> + }
> + foreach m $mem {
> + set ${m}_initial [capture_command_output "x/x $m" ""]
> + }
> +
> + gdb_test "break $after_seq" \
> + "Breakpoint ${::decimal} at ${::hex}: file .*/aarch64-lrcpc3.c, line ${::decimal}\\." \
> + "$insn after instruction sequence"
> + gdb_continue_to_breakpoint "executed instruction sequence" \
> + [multi_line ".*/aarch64-lrcpc3.c:${::decimal}" ".*"]
> +
> + # Record the new memory and register values.
> + foreach r $regs {
> + set ${r}_new [capture_command_output "info register $r" ""]
> + }
> + foreach v $vars {
> + set ${v}_new [get_valueof "/x" "$v" "unable to read $v" \
> + "get $v new value"]
> + }
> + foreach m $mem {
> + set ${m}_new [capture_command_output "x/x $m" ""]
> + }
> +
> + # 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-lrcpc3.c:${::decimal}" \
> + "${::decimal}\[ \t\]+__asm__ volatile \\(\"${insn} .*\".*"]
> +
> + # Record the final memory and register values.
> + foreach r $regs {
> + set ${r}_final [capture_command_output "info register $r" ""]
> + }
> + foreach v $vars {
> + set ${v}_final [get_valueof "/x" "$v" "unable to read $v" \
> + "get $v final value"]
> + }
> + foreach m $mem {
> + set ${m}_final [capture_command_output "x/x $m" ""]
> + }
> +
> + foreach v [concat $same_reg $same_var $same_mem] {
> + gdb_assert ![string compare [set ${v}_initial] [set ${v}_new]] \
> + "check $v initial value versus $v new value"
> + gdb_assert ![string compare [set ${v}_initial] [set ${v}_final]] \
> + "check $v initial value versus $v final value"
> + }
> +
> + foreach v [concat $diff_reg $diff_var $diff_mem] {
> + gdb_assert [string compare [set ${v}_initial] [set ${v}_new]] \
> + "check $v initial value versus $v new value"
> + gdb_assert ![string compare [set ${v}_initial] [set ${v}_final]] \
> + "check $v initial value versus $v final 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-lrcpc3.c:${::decimal}" \
> + ".*"]
> + }
> +}
> +
> +set ldiapp_cases {
> + { ldiapp-0 { x19 x20 } { } { } { x21 } { } { src } }
> + { ldiapp-1 { w19 w20 } { } { } { x21 } { } { src } }
> + { ldiapp-2 { x19 x20 x21 } { } { } { } { } { src } }
> + { ldiapp-3 { w19 w20 x21 } { } { } { } { } { src } }
> + { ldiapp-4 { x21 x20 } { } { } { } { } { src } }
> + { ldiapp-5 { w21 w20 } { } { } { } { } { src } }
> +}
> +
> +set stilp_cases {
> + { stilp-0 { } { } { src } { x19 x20 x21 } { } { } }
> + { stilp-1 { } { } { src } { w19 w20 x21 } { } { } }
> + { stilp-2 { x21 } { } { src } { x19 x20 } { } { } }
> + { stilp-3 { x21 } { } { src } { x19 x20 } { } { } }
> + { stilp-4 { } { } { src } { x20 x21 } { } { } }
> + { stilp-5 { } { } { src } { w20 x21 } { } { } }
> +}
> +
> +set ldapr_stlr_cases {
> + { ldapr-0 { x19 x21 } { } { } { } { } { src } }
> + { ldapr-1 { w19 x21 } { } { } { } { } { src } }
> + { stlr-0 { x21 } { } { src } { x19 } { } { } }
> + { stlr-1 { x21 } { } { src } { w19 } { } { } }
> +}
> +
> +set ldap1_stl1_cases {
> + { ldap1-0 { v22 } { } { } { x21 } { } { src } }
> + { stl1-0 { } { } { src } { v22 } { } { } }
> +}
> +
> +set ldapur_stlur_cases {
> + { ldapur-0 { v22 } { } { } { x21 } { } { src } }
> + { stlur-0 { } { } { src } { x21 v22 } { } { } }
> + { ldapur-1 { v22 } { } { } { x21 } { } { src } }
> + { stlur-1 { } { } { src } { x21 v22 } { } { } }
> + { ldapur-2 { v22 } { } { } { x21 } { } { src } }
> + { stlur-2 { } { } { src } { x21 v22 } { } { } }
> + { ldapur-3 { v22 } { } { } { x21 } { } { src } }
> + { stlur-3 { } { } { src } { x21 v22 } { } { } }
> + { ldapur-4 { v22 } { } { } { x21 } { } { src } }
> + { stlur-4 { } { } { src } { x21 v22 } { } { } }
> + { ldapur-5 { v22 } { } { } { x21 } { } { src } }
> + { stlur-5 { } { } { src } { x21 v22 } { } { } }
> + { ldapur-6 { v22 } { } { } { x21 } { } { src } }
> + { stlur-6 { } { } { src } { x21 v22 } { } { } }
> +}
All of the cases have the third and second-to-last argument list as
empty. They can probably be dropped there, and dropped as arguments to
the test_single_asm proc.
> +
> +set all_cases [concat \
> + $ldiapp_cases $stilp_cases $ldapr_stlr_cases \
> + $ldap1_stl1_cases $ldapur_stlur_cases]
> +
> +foreach c $all_cases {
> + lassign $c name diff_reg diff_var diff_mem same_reg same_var same_mem
> + test_single_asm $name $diff_reg $diff_var $diff_mem $same_reg $same_var $same_mem
> +}
--
Cheers,
Guinevere Larsen
It/she
next prev parent reply other threads:[~2026-05-26 14:30 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-12 23:17 [PATCH v2 0/4] gdb/aarch64: record/replay support for AArch64 Ezra.Sitorus
2026-05-12 23:17 ` [PATCH v2 1/4] gdb/aarch64: record/replay support for LRCPC3 Ezra.Sitorus
2026-05-15 3:50 ` Thiago Jung Bauermann
2026-05-15 11:45 ` Ezra Sitorus
2026-05-15 23:03 ` Thiago Jung Bauermann
2026-05-26 14:30 ` Guinevere Larsen [this message]
2026-05-26 23:36 ` Ezra Sitorus
2026-05-27 0:05 ` Thiago Jung Bauermann
2026-05-12 23:17 ` [PATCH v2 2/4] gdb/aarch64: Test record/replay support for CSSC Ezra.Sitorus
2026-05-15 3:50 ` Thiago Jung Bauermann
2026-05-26 19:40 ` Guinevere Larsen
2026-05-26 16:40 ` Guinevere Larsen
2026-05-12 23:17 ` [PATCH v2 3/4] gdb/aarch64: record/replay support for RPRFM, PRFM (reg), PRFUM Ezra.Sitorus
2026-05-15 3:56 ` Thiago Jung Bauermann
2026-05-12 23:17 ` [PATCH v2 4/4] gdb/aarch64: record/replay support for LSE128 Ezra.Sitorus
2026-05-15 3:58 ` Thiago Jung Bauermann
2026-05-26 19:40 ` Guinevere Larsen
2026-05-15 3:59 ` [PATCH v2 0/4] gdb/aarch64: record/replay support for AArch64 Thiago Jung Bauermann
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=f741185a-f505-439f-9951-53c2a4d6003a@redhat.com \
--to=guinevere@redhat.com \
--cc=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