From: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
To: <Ezra.Sitorus@arm.com>
Cc: <gdb-patches@sourceware.org>, <luis.machado.foss@gmail.com>
Subject: Re: [PATCH 1/4] gdb/aarch64: record/replay support for LRCPC3
Date: Sat, 25 Apr 2026 02:08:36 -0300 [thread overview]
Message-ID: <87o6j7bp9n.fsf@linaro.org> (raw)
In-Reply-To: <20260420215232.68675-2-Ezra.Sitorus@arm.com> (Ezra Sitorus's message of "Mon, 20 Apr 2026 22:52:29 +0100")
Hello Ezra,
<Ezra.Sitorus@arm.com> writes:
> 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.
> ---
> gdb/aarch64-tdep.c | 87 +++++
> gdb/testsuite/gdb.reverse/aarch64-lrcpc3.c | 319 +++++++++++++++++++
> gdb/testsuite/gdb.reverse/aarch64-lrcpc3.exp | 203 ++++++++++++
> gdb/testsuite/lib/gdb.exp | 63 ++++
> 4 files changed, 672 insertions(+)
> create mode 100644 gdb/testsuite/gdb.reverse/aarch64-lrcpc3.c
> create mode 100644 gdb/testsuite/gdb.reverse/aarch64-lrcpc3.exp
Thanks! I have just a few nits.
I appreciate the well-commented changes in aarch64-tdep.c. They made the
code easier to follow.
> diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
> index 4befaa2720d..81d4f160f8f 100644
> --- a/gdb/aarch64-tdep.c
> +++ b/gdb/aarch64-tdep.c
> @@ -5812,6 +5812,93 @@ aarch64_record_load_store (aarch64_insn_decode_record *aarch64_insn_r)
> aarch64_insn_r->reg_rec_count = 1;
> }
> }
> + /* LRCPC3 instructions. This covers ldiapp/stilp, ldapur/stlur (FP/SIMD),
> + ldapr/stlr. */
> + else if ((insn_bits24_27 & 0x0b) == 0x09 && insn_bits28_29 == 0x01
> + && insn_bits10_11 == 0x02 && !insn_bit21)
> + {
> + /* ldapur/stlur (FP/SIMD), ldapr/stlr. We can differentiate between the
> + 2 types by checking the vector flag. */
> + if (insn_bit23 || vector_flag)
> + {
> + /* For the vector instruction, the offset comes from the imm9
> + bitfield, whereas the other can only take possible values from the
> + size bitfield. */
> + int16_t imm9_off = sbits (aarch64_insn_r->aarch64_insn, 12, 20);
> + offset = vector_flag ? imm9_off : -(1 << size_bits);
> + uint32_t regnum_offset = vector_flag ? AARCH64_V0_REGNUM : 0;
> + if (ld_flag)
> + {
> + record_buf[0] = reg_rt + regnum_offset;
> + aarch64_insn_r->reg_rec_count = 1;
> + if (!vector_flag)
> + {
> + /* The Rn register always has writeback in LRCPC3. This is
> + not the case in LRCPC. */
> + record_buf[1] = reg_rn;
> + aarch64_insn_r->reg_rec_count = 2;
> + }
> + }
> + else
> + {
> + regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn,
> + &address);
> + /* (vector_flag && insn_bit23) is the STLUR instruction with Q
> + register. */
> + datasize = (vector_flag && insn_bit23) ? 128 : (8 << size_bits);
> + /* LRCPC3 adds STLR with a pre-indexed offset. There is another
> + STLR variant without offset but this has a different encoding. */
> + if (!vector_flag)
> + {
> + record_buf[0] = reg_rn;
> + aarch64_insn_r->reg_rec_count = 1;
> + }
> + record_buf_mem[0] = datasize >> 3;
> + record_buf_mem[1] = address + offset;
> + aarch64_insn_r->mem_rec_count = 1;
> + }
> + }
> + else
> + {
> + /* ldiapp/stilp. */
> + uint8_t opc2 = bits (aarch64_insn_r->aarch64_insn, 12, 15);
> + reg_rt2 = bits (aarch64_insn_r->aarch64_insn, 16, 20);
> + if (ld_flag)
> + {
> + record_buf[0] = reg_rt;
> + record_buf[1] = reg_rt2;
> + aarch64_insn_r->reg_rec_count = 2;
> +
> + /* If the registers don't match and there's no offset then
> + there's WB. */
The line above is indented with 8 spaces which can be substituted
by a \t. git am complained about it.
> + if (reg_rn != reg_rt && reg_rn != reg_rt2 && opc2 == 0)
> + {
> + record_buf[2] = reg_rn;
> + aarch64_insn_r->reg_rec_count = 3;
> + }
> + }
> + else
> + {
> + datasize = 8 << size_bits;
> + regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn,
> + &address);
> + offset = (opc2 == 0) ? (2 << size_bits) : 0;
> + address -= offset;
> +
> + record_buf_mem[0] = datasize >> 3;
> + record_buf_mem[1] = address;
> + record_buf_mem[2] = datasize >> 3;
> + record_buf_mem[3] = address + (datasize >> 3);
> + aarch64_insn_r->mem_rec_count = 2;
> +
> + if (offset != 0)
> + {
> + record_buf[0] = reg_rn;
> + aarch64_insn_r->reg_rec_count = 1;
> + }
> + }
> + }
> + }
> /* Load/store register (register offset) instructions. */
> else if ((insn_bits24_27 & 0x0b) == 0x08 && insn_bits28_29 == 0x03
> && insn_bits10_11 == 0x02 && insn_bit21)
> diff --git a/gdb/testsuite/gdb.reverse/aarch64-lrcpc3.c b/gdb/testsuite/gdb.reverse/aarch64-lrcpc3.c
> new file mode 100644
> index 00000000000..9265489ff70
> --- /dev/null
> +++ b/gdb/testsuite/gdb.reverse/aarch64-lrcpc3.c
> @@ -0,0 +1,319 @@
> +/* This test program is part of GDB, the GNU debugger.
> +
> + Copyright 2024-2026 Free Software Foundation, Inc.
The copyright should start with 2026.
> diff --git a/gdb/testsuite/gdb.reverse/aarch64-lrcpc3.exp b/gdb/testsuite/gdb.reverse/aarch64-lrcpc3.exp
> new file mode 100644
> index 00000000000..7d7a8c45445
> --- /dev/null
> +++ b/gdb/testsuite/gdb.reverse/aarch64-lrcpc3.exp
> @@ -0,0 +1,203 @@
> +# Copyright 2024-2026 Free Software Foundation, Inc.
Here too, the copyright should start with 2026.
> +
> +# 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]]
> +} {
The style we use in Tcl puts the { and } of the if condition in the same
line as the condition expression.
> + return -1
Top-level returns from .exp files don't need to return anything anymore.
The current style is to have a bare "return".
Applies to this return ...
> +}
> +
> +if {![runto_main]} {
> + return -1
... and this return.
gdb.reverse/aarch64-mops.exp is wrong in that regard. Sorry for the bad influence.
> +set ldiapp_cases {
> + { ldiapp-0 { x19 x20 } { } { } { } { ptr } { src } }
> + { ldiapp-1 { w19 w20 } { } { } { } { ptr } { src } }
> + { ldiapp-2 { x19 x20 } { ptr } { } { } { } { src } }
> + { ldiapp-3 { w19 w20 } { ptr } { } { } { } { src } }
> + { ldiapp-4 { x21 x20 } { } { } { } { } { src } }
> + { ldiapp-5 { w21 w20 } { } { } { } { } { src } }
> +}
> +
> +set stilp_cases {
> + { stilp-0 { } { } { src } { x19 x20 } { ptr } { } }
> + { stilp-1 { } { } { src } { w19 w20 } { ptr } { } }
> + { stilp-2 { } { ptr } { src } { x19 x20 } { } { } }
> + { stilp-3 { } { ptr } { src } { x19 x20 } { } { } }
> + { stilp-4 { } { } { src } { x20 } { ptr } { } }
> + { stilp-5 { } { } { src } { w20 } { ptr } { } }
> +}
> +
> +set ldapr_stlr_cases {
> + { ldapr-0 { x19 } { ptr } { } { } { } { src } }
> + { ldapr-1 { w19 } { ptr } { } { } { } { src } }
> + { stlr-0 { } { ptr } { src } { x19 } { } { } }
> + { stlr-1 { } { ptr } { src } { w19 } { } { } }
> +}
> +
> +set ldap1_stl1_cases {
> + { ldap1-0 { v22 } { } { } { ptr } { } { src } }
> + { stl1-0 { } { } { src } { v22 } { } { } }
> +}
> +
> +set ldapur_stlur_cases {
> + { ldapur-0 { v22 } { } { } { ptr } { } { src } }
> + { stlur-0 { } { } { src } { v22 } { ptr } { } }
> + { ldapur-1 { v22 } { } { } { ptr } { } { src } }
> + { stlur-1 { } { } { src } { v22 } { ptr } { } }
> + { ldapur-2 { v22 } { } { } { ptr } { } { src } }
> + { stlur-2 { } { } { src } { v22 } { ptr } { } }
> + { ldapur-3 { v22 } { } { } { ptr } { } { src } }
> + { stlur-3 { } { } { src } { v22 } { ptr } { } }
> + { ldapur-4 { v22 } { } { } { ptr } { } { src } }
> + { stlur-4 { } { } { src } { v22 } { ptr } { } }
> + { ldapur-5 { v22 } { } { } { ptr } { } { src } }
> + { stlur-5 { } { } { src } { v22 } { ptr } { } }
> + { ldapur-6 { v22 } { } { } { ptr } { } { src } }
> + { stlur-6 { } { } { src } { v22 } { ptr } { } }
> +}
> +
> +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
> +}
Nice way of structuring all the cases!
--
Thiago
next prev parent reply other threads:[~2026-04-25 5:09 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 [this message]
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
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=87o6j7bp9n.fsf@linaro.org \
--to=thiago.bauermann@linaro.org \
--cc=Ezra.Sitorus@arm.com \
--cc=gdb-patches@sourceware.org \
--cc=luis.machado.foss@gmail.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