* [PATCH v2 0/4] gdb/aarch64: record/replay support for AArch64
@ 2026-05-12 23:17 Ezra.Sitorus
2026-05-12 23:17 ` [PATCH v2 1/4] gdb/aarch64: record/replay support for LRCPC3 Ezra.Sitorus
` (4 more replies)
0 siblings, 5 replies; 18+ messages in thread
From: Ezra.Sitorus @ 2026-05-12 23:17 UTC (permalink / raw)
To: gdb-patches; +Cc: luis.machado.foss, thiago.bauermann, guinevere, Ezra Sitorus
From: Ezra Sitorus <Ezra.Sitorus@arm.com>
This patch series enables record/replay for the following AArch64
features:
* FEAT_LRCPC3 (+rcpc3)
* FEAT_CSSC (+cssc)
* FEAT_RPRFM (+rprfm)
* FEAT_LSE128 (+lse128)
These were tested either with QEMU or Shrinkwrap, using both GCC 15 and
Clang 21.
Thiago mentioned about copyright years in the previous version. I think
I should be using the range 2024-2026 since the tests are based on
previous tests and I should be retaining the original years. In my case,
these come from the aarch64-mops.{c,exp} tests. The GDB contribution
checklist site says so too!
Changes from v1->v2:
* Removal of register keyword in the tests.
* Simplifying the setup macros in the tests.
* Fixup of globals in the tcl files.
* General formatting cleanup of files.
* gdb.exp fixup for feature detection
Ezra
Ezra Sitorus (4):
gdb/aarch64: record/replay support for LRCPC3
gdb/aarch64: Test record/replay support for CSSC
gdb/aarch64: record/replay support for RPRFM, PRFM (reg), PRFUM
gdb/aarch64: record/replay support for LSE128
gdb/aarch64-tdep.c | 113 +++++++++-
gdb/testsuite/gdb.reverse/aarch64-cssc.c | 88 ++++++++
gdb/testsuite/gdb.reverse/aarch64-cssc.exp | 139 ++++++++++++
gdb/testsuite/gdb.reverse/aarch64-lrcpc3.c | 216 +++++++++++++++++++
gdb/testsuite/gdb.reverse/aarch64-lrcpc3.exp | 203 +++++++++++++++++
gdb/testsuite/gdb.reverse/aarch64-lse128.c | 100 +++++++++
gdb/testsuite/gdb.reverse/aarch64-lse128.exp | 137 ++++++++++++
gdb/testsuite/lib/gdb.exp | 171 +++++++++++++++
8 files changed, 1165 insertions(+), 2 deletions(-)
create mode 100644 gdb/testsuite/gdb.reverse/aarch64-cssc.c
create mode 100644 gdb/testsuite/gdb.reverse/aarch64-cssc.exp
create mode 100644 gdb/testsuite/gdb.reverse/aarch64-lrcpc3.c
create mode 100644 gdb/testsuite/gdb.reverse/aarch64-lrcpc3.exp
create mode 100644 gdb/testsuite/gdb.reverse/aarch64-lse128.c
create mode 100644 gdb/testsuite/gdb.reverse/aarch64-lse128.exp
--
2.53.0
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v2 1/4] gdb/aarch64: record/replay support for LRCPC3
2026-05-12 23:17 [PATCH v2 0/4] gdb/aarch64: record/replay support for AArch64 Ezra.Sitorus
@ 2026-05-12 23:17 ` Ezra.Sitorus
2026-05-15 3:50 ` Thiago Jung Bauermann
2026-05-26 14:30 ` Guinevere Larsen
2026-05-12 23:17 ` [PATCH v2 2/4] gdb/aarch64: Test record/replay support for CSSC Ezra.Sitorus
` (3 subsequent siblings)
4 siblings, 2 replies; 18+ messages in thread
From: Ezra.Sitorus @ 2026-05-12 23:17 UTC (permalink / raw)
To: gdb-patches; +Cc: luis.machado.foss, thiago.bauermann, guinevere, Ezra Sitorus
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.
---
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
diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index 4befaa27..b10bba67 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. */
+ 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 00000000..d61d3239
--- /dev/null
+++ b/gdb/testsuite/gdb.reverse/aarch64-lrcpc3.c
@@ -0,0 +1,216 @@
+/* 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 <stdalign.h>
+#include <stdint.h>
+#include <string.h>
+
+#define INITIAL_STRING "This is just some string."
+#define BUF_SIZE sizeof (INITIAL_STRING)
+
+#define PREPARE_SRC_AND_PTR(OFFSET) \
+ strcpy (src, INITIAL_STRING); \
+ __asm__ volatile ("mov x21, %0" \
+ : \
+ : "r"((uint64_t *)((uint8_t *)src + (OFFSET))) \
+ : "x21")
+
+#define PREPARE_GPR(OFFSET) \
+ __asm__ volatile ("mov x19, #0\n" ::: "x19"); \
+ __asm__ volatile ("mov x20, #0\n" ::: "x20"); \
+ PREPARE_SRC_AND_PTR (OFFSET)
+
+#define PREPARE_VECTOR_REG(OFFSET) \
+ __asm__ volatile ("movi v22.2d, #0\n" ::: "v22"); \
+ PREPARE_SRC_AND_PTR (OFFSET)
+
+int
+main (void)
+{
+ alignas (16) char src[BUF_SIZE];
+
+ PREPARE_GPR (0);
+ /* Before ldiapp-0. */
+ __asm__ volatile ("ldiapp x19, x20, [x21]\n" : : : "x19", "x20", "memory");
+ /* After ldiapp-0. */
+
+ PREPARE_GPR (0);
+ /* Before ldiapp-1. */
+ __asm__ volatile ("ldiapp w19, w20, [x21]\n" : : : "x19", "x20", "memory");
+ /* After ldiapp-1. */
+
+ PREPARE_GPR (0);
+ /* Before ldiapp-2. */
+ __asm__ volatile ("ldiapp x19, x20, [x21], #16\n"
+ :
+ :
+ : "x19", "x20", "x21", "memory");
+ /* After ldiapp-2. */
+
+ PREPARE_GPR (0);
+ /* Before ldiapp-3. */
+ __asm__ volatile ("ldiapp w19, w20, [x21], #8\n"
+ :
+ :
+ : "x19", "x20", "x21", "memory");
+ /* After ldiapp-3. */
+ /* Register overlap between source and destination registers. Since there is
+ no offset, writeback is disabled. */
+
+ PREPARE_GPR (0);
+ /* Before ldiapp-4. */
+ __asm__ volatile ("ldiapp x21, x20, [x21]\n" : : : "x20", "x21", "memory");
+ /* After ldiapp-4. */
+
+ PREPARE_GPR (0);
+ /* Before ldiapp-5. */
+ __asm__ volatile ("ldiapp w21, w20, [x21]\n" : : : "x20", "x21", "memory");
+ /* After ldiapp-5. */
+
+ PREPARE_GPR (0);
+ /* Before stilp-0. */
+ __asm__ volatile ("stilp x19, x20, [x21]\n" : : : "memory");
+ /* After stilp-0. */
+
+ PREPARE_GPR (0);
+ /* Before stilp-1. */
+ __asm__ volatile ("stilp w19, w20, [x21]\n" : : : "memory");
+ /* After stilp-1. */
+
+ PREPARE_GPR (16);
+ /* Before stilp-2. */
+ __asm__ volatile ("stilp x19, x20, [x21, #-16]!\n" : : : "x21", "memory");
+ /* After stilp-2. */
+
+ PREPARE_GPR (8);
+ /* Before stilp-3. */
+ __asm__ volatile ("stilp w19, w20, [x21, #-8]!\n" : : : "x21", "memory");
+ /* After stilp-3. */
+ /* Register overlap. Since there is no offset, writeback is disabled. */
+
+ PREPARE_GPR (0);
+ /* Before stilp-4. */
+ __asm__ volatile ("stilp x21, x20, [x21]\n" : : : "memory");
+ /* After stilp-4. */
+
+ PREPARE_GPR (0);
+ /* Before stilp-5. */
+ __asm__ volatile ("stilp w21, w20, [x21]\n" : : : "memory");
+ /* After stilp-5. */
+
+ PREPARE_GPR (0);
+ /* Before ldapr-0. */
+ __asm__ volatile ("ldapr x19, [x21], #8\n" : : : "x19", "x21", "memory");
+ /* After ldapr-0. */
+
+ PREPARE_GPR (0);
+ /* Before ldapr-1. */
+ __asm__ volatile ("ldapr w19, [x21], #4\n" : : : "x19", "x21", "memory");
+ /* After ldapr-1. */
+
+ PREPARE_GPR (8);
+ /* Before stlr-0. */
+ __asm__ volatile ("stlr x19, [x21, #-8]!\n" : : : "x21", "memory");
+ /* After stlr-0. */
+
+ PREPARE_GPR (4);
+ /* Before stlr-1. */
+ __asm__ volatile ("stlr w19, [x21, #-4]!\n" : : : "x21", "memory");
+ /* After stlr-1. */
+
+ PREPARE_VECTOR_REG (0);
+ /* Before ldap1-0. */
+ __asm__ volatile ("ldap1 {v22.d}[0], [x21]\n" : : : "v22", "memory");
+ /* After ldap1-0. */
+
+ PREPARE_VECTOR_REG (0);
+ /* Before stl1-0. */
+ __asm__ volatile ("stl1 {v22.d}[0], [x21]\n" : : : "memory");
+ /* After stl1-0. */
+
+ PREPARE_VECTOR_REG (0);
+ /* Before ldapur-0. */
+ __asm__ volatile ("ldapur d22, [x21]\n" : : : "v22", "memory");
+ /* After ldapur-0. */
+
+ PREPARE_VECTOR_REG (0);
+ /* Before stlur-0. */
+ __asm__ volatile ("stlur d22, [x21]\n" : : : "memory");
+ /* After stlur-0. */
+
+ PREPARE_VECTOR_REG (256);
+ /* Before ldapur-1. */
+ __asm__ volatile ("ldapur d22, [x21, #-256]\n" : : : "v22", "memory");
+ /* After ldapur-1. */
+
+ PREPARE_VECTOR_REG (256);
+ /* Before stlur-1. */
+ __asm__ volatile ("stlur d22, [x21, #-256]\n" : : : "memory");
+ /* After stlur-1. */
+
+ PREPARE_VECTOR_REG (-255);
+ /* Before ldapur-2. */
+ __asm__ volatile ("ldapur d22, [x21, #255]\n" : : : "v22", "memory");
+ /* After ldapur-2. */
+
+ PREPARE_VECTOR_REG (-255);
+ /* Before stlur-2. */
+ __asm__ volatile ("stlur d22, [x21, #255]\n" : : : "memory");
+ /* After stlur-2. */
+
+ PREPARE_VECTOR_REG (0);
+ /* Before ldapur-3. */
+ __asm__ volatile ("ldapur h22, [x21]\n" : : : "v22", "memory");
+ /* After ldapur-3. */
+
+ PREPARE_VECTOR_REG (0);
+ /* Before stlur-3. */
+ __asm__ volatile ("stlur h22, [x21]\n" : : : "memory");
+ /* After stlur-3. */
+
+ PREPARE_VECTOR_REG (0);
+ /* Before ldapur-4. */
+ __asm__ volatile ("ldapur s22, [x21]\n" : : : "v22", "memory");
+ /* After ldapur-4. */
+
+ PREPARE_VECTOR_REG (0);
+ /* Before stlur-4. */
+ __asm__ volatile ("stlur s22, [x21]\n" : : : "memory");
+ /* After stlur-4. */
+
+ PREPARE_VECTOR_REG (0);
+ /* Before ldapur-5. */
+ __asm__ volatile ("ldapur d22, [x21]\n" : : : "v22", "memory");
+ /* After ldapur-5. */
+
+ PREPARE_VECTOR_REG (0);
+ /* Before stlur-5. */
+ __asm__ volatile ("stlur d22, [x21]\n" : : : "memory");
+ /* After stlur-5. */
+
+ PREPARE_VECTOR_REG (0);
+ /* Before ldapur-6. */
+ __asm__ volatile ("ldapur q22, [x21]\n" : : : "v22", "memory");
+ /* After ldapur-6. */
+
+ PREPARE_VECTOR_REG (0);
+ /* Before stlur-6. */
+ __asm__ volatile ("stlur q22, [x21]\n" : : : "memory");
+ /* After stlur-6. */
+
+ return 0;
+}
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 } { } { } }
+}
+
+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
+}
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index 28709004..3f3197cb 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -5287,6 +5287,69 @@ gdb_caching_proc allow_aarch64_fpmr_tests {} {
return $allow_fpmr_tests
}
+# Run a test on the target to see if it supports AArch64 LRCPC3 (Load-Acquire
+# RCpc instructions) extensions. Return 1 if so, 0 if it does not. Note this
+# causes a restart of GDB.
+
+gdb_caching_proc allow_aarch64_lrcpc3_tests {} {
+ global srcdir subdir gdb_prompt inferior_exited_re
+
+ set me "allow_aarch64_lrcpc3_tests"
+
+ if { ![is_aarch64_target] } {
+ return 0
+ }
+
+ # Take the opportunity to check whether the toolchain knows about LRCPC3.
+ set compile_flags "{additional_flags=-march=armv8-a+rcpc3}"
+
+ # Compile a program that tests the LRCPC3 feature.
+ set src {
+ #include <stdbool.h>
+ #include <sys/auxv.h>
+
+ /* Feature check for LRCPC3. */
+ #ifndef HWCAP_LRCPC3
+ #define HWCAP_LRCPC3 (1ULL << 46)
+ #endif
+
+ int main (void) {
+ bool lrcpc3_supported = getauxval (AT_HWCAP2) & HWCAP_LRCPC3;
+
+ /* Return success if LRCPC3 is supported. */
+ return !lrcpc3_supported;
+ }
+ }
+
+ 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 lrcpc3 support not detected"
+ set allow_lrcpc3_tests 0
+ }
+ -re ".*$inferior_exited_re normally.*${gdb_prompt} $" {
+ verbose -log "\n$me: lrcpc3 support detected"
+ set allow_lrcpc3_tests 1
+ }
+ default {
+ warning "\n$me: default case taken"
+ set allow_lrcpc3_tests 0
+ }
+ }
+ gdb_exit
+ remote_file build delete $obj
+
+ verbose "$me: returning $allow_lrcpc3_tests" 2
+ return $allow_lrcpc3_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.53.0
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v2 2/4] gdb/aarch64: Test record/replay support for CSSC
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-12 23:17 ` Ezra.Sitorus
2026-05-15 3:50 ` Thiago Jung Bauermann
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
` (2 subsequent siblings)
4 siblings, 2 replies; 18+ messages in thread
From: Ezra.Sitorus @ 2026-05-12 23:17 UTC (permalink / raw)
To: gdb-patches; +Cc: luis.machado.foss, thiago.bauermann, guinevere, Ezra Sitorus
From: Ezra Sitorus <ezra.sitorus@arm.com>
GDB can handle AArch64's CSSC instructions but there were no tests
ensuring that and ensuring no regressions would creep in. This commit
adds some tests for these instructions. This was tested on
aarch64-none-linux-gnu on QEMU with CSSC support.
---
gdb/testsuite/gdb.reverse/aarch64-cssc.c | 88 +++++++++++++
gdb/testsuite/gdb.reverse/aarch64-cssc.exp | 139 +++++++++++++++++++++
gdb/testsuite/lib/gdb.exp | 52 ++++++++
3 files changed, 279 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 00000000..67ccb68e
--- /dev/null
+++ b/gdb/testsuite/gdb.reverse/aarch64-cssc.c
@@ -0,0 +1,88 @@
+/* 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 x19, %0\n" : : "r"(X): "x19"); \
+ __asm__ volatile ("mov x20, %0\n" : : "r"(Y): "x20"); \
+ __asm__ volatile ("mov x21, %0\n" : : "r"(Z): "x21");
+
+int
+main (void)
+{
+ 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 x19, x21\n" ::: "x19");
+ /* After abs. */
+
+ PREPARE_REGS (a, b, c);
+ /* Before cnt. */
+ __asm__ volatile ("cnt x19, x20\n" : :: "x19");
+ /* After cnt. */
+
+ PREPARE_REGS (a, b, c);
+ /* Before ctz. */
+ __asm__ volatile ("ctz x19, x20\n" : :: "x19");
+ /* After ctz. */
+
+ PREPARE_REGS (a, b, c);
+ /* Before smax-1. */
+ __asm__ volatile ("smax x19, x20, #10\n" : :: "x19");
+ /* After smax-1. */
+
+ PREPARE_REGS (a, b, c);
+ /* Before smax-2. */
+ __asm__ volatile ("smax x19, x20, x21\n" : :: "x19");
+ /* After smax-2. */
+
+ PREPARE_REGS (a, b, c);
+ /* Before smin-1. */
+ __asm__ volatile ("smin x19, x20, #10\n" : :: "x19");
+ /* After smin-1. */
+
+ PREPARE_REGS (a, b, c);
+ /* Before smin-2. */
+ __asm__ volatile ("smin x19, x20, x21\n" : :: "x19");
+ /* After smin-2. */
+
+ PREPARE_REGS (a, b, c);
+ /* Before umax-1. */
+ __asm__ volatile ("umax x19, x20, #10\n" : :: "x19");
+ /* After umax-1. */
+
+ PREPARE_REGS (a, b, c);
+ /* Before umax-2. */
+ __asm__ volatile ("umax x19, x20, x21\n" : :: "x19");
+ /* After umax-2. */
+
+ PREPARE_REGS (a, b, c);
+ /* Before umin-1. */
+ __asm__ volatile ("umin x19, x20, #10\n" : :: "x19");
+ /* After umin-1. */
+
+ PREPARE_REGS (a, b, c);
+ /* Before umin-2. */
+ __asm__ volatile ("umin x19, x20, x21\n" : :: "x19");
+ /* 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 00000000..1e2980a6
--- /dev/null
+++ b/gdb/testsuite/gdb.reverse/aarch64-cssc.exp
@@ -0,0 +1,139 @@
+# 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
+}
+
+if {![runto_main]} {
+ return
+}
+
+gdb_test_no_output "record full"
+
+proc test_single_asm { name } {
+ with_test_prefix $name {
+ 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} .*\".*"]
+
+ # 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} .*\".*"]
+
+ # 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 3f3197cb..9d5c0e5a 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" ::: "x0");
+ 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.53.0
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v2 3/4] gdb/aarch64: record/replay support for RPRFM, PRFM (reg), PRFUM
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-12 23:17 ` [PATCH v2 2/4] gdb/aarch64: Test record/replay support for CSSC Ezra.Sitorus
@ 2026-05-12 23:17 ` 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:59 ` [PATCH v2 0/4] gdb/aarch64: record/replay support for AArch64 Thiago Jung Bauermann
4 siblings, 1 reply; 18+ messages in thread
From: Ezra.Sitorus @ 2026-05-12 23:17 UTC (permalink / raw)
To: gdb-patches; +Cc: luis.machado.foss, thiago.bauermann, guinevere, Ezra Sitorus
From: Ezra Sitorus <ezra.sitorus@arm.com>
The PRFM (register) instruction variant was unsupported. This is added
along with RPRFM and PRFUM.
No testcase has been added as these are hint instructions which don't
modify registers/memory.
The full testsuite was done on aarch64-none-linux-gnu without RPRFM.
The gdb.arch and gdb.reverse tests were run on Shrinkwrap with RPRFM
support.
---
gdb/aarch64-tdep.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index b10bba67..5c1f8af5 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -5914,6 +5914,11 @@ aarch64_record_load_store (aarch64_insn_decode_record *aarch64_insn_r)
else
if (size_bits != 0x03)
ld_flag = 0x01;
+ else if (size_bits == 0x3 && vector_flag == 0x0 && opc == 0x2)
+ {
+ /* PRFM (register) or RPRFM */
+ return AARCH64_RECORD_SUCCESS;
+ }
else
return AARCH64_RECORD_UNKNOWN;
@@ -5944,7 +5949,7 @@ aarch64_record_load_store (aarch64_insn_decode_record *aarch64_insn_r)
aarch64_insn_r->reg_rec_count = 1;
}
}
- /* Load/store register (immediate and unprivileged) instructions. */
+ /* Load/store register (immediate and unprivileged) instructions and PRFUM. */
else if ((insn_bits24_27 & 0x0b) == 0x08 && insn_bits28_29 == 0x03
&& !insn_bit21)
{
@@ -5963,7 +5968,11 @@ aarch64_record_load_store (aarch64_insn_decode_record *aarch64_insn_r)
if (size_bits != 0x03)
ld_flag = 0x01;
else
- return AARCH64_RECORD_UNKNOWN;
+ if (insn_bits10_11 == 0)
+ /* PRFUM instruction. */
+ return AARCH64_RECORD_SUCCESS;
+ else
+ return AARCH64_RECORD_UNKNOWN;
if (!ld_flag)
{
--
2.53.0
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v2 4/4] gdb/aarch64: record/replay support for LSE128
2026-05-12 23:17 [PATCH v2 0/4] gdb/aarch64: record/replay support for AArch64 Ezra.Sitorus
` (2 preceding siblings ...)
2026-05-12 23:17 ` [PATCH v2 3/4] gdb/aarch64: record/replay support for RPRFM, PRFM (reg), PRFUM Ezra.Sitorus
@ 2026-05-12 23:17 ` 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
4 siblings, 2 replies; 18+ messages in thread
From: Ezra.Sitorus @ 2026-05-12 23:17 UTC (permalink / raw)
To: gdb-patches; +Cc: luis.machado.foss, thiago.bauermann, guinevere, Ezra Sitorus
From: Ezra Sitorus <ezra.sitorus@arm.com>
FEAT_LSE128 introduces support for 128-bit atomic instructions. This
patch teaches GDB to decode these instructions for recording and
reversing.
Regression tested on aarch64-none-linux-gnu on QEMU with LSE128 support.
I observe unrelated regressions that appear to be environmental rather
than caused by this patch.
---
gdb/aarch64-tdep.c | 13 ++
gdb/testsuite/gdb.reverse/aarch64-lse128.c | 100 ++++++++++++++
gdb/testsuite/gdb.reverse/aarch64-lse128.exp | 137 +++++++++++++++++++
gdb/testsuite/lib/gdb.exp | 56 ++++++++
4 files changed, 306 insertions(+)
create mode 100644 gdb/testsuite/gdb.reverse/aarch64-lse128.c
create mode 100644 gdb/testsuite/gdb.reverse/aarch64-lse128.exp
diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index 5c1f8af5..0cce4072 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -6008,6 +6008,19 @@ aarch64_record_load_store (aarch64_insn_decode_record *aarch64_insn_r)
else if ((insn_bits24_27 & 1) == 1 && insn_bits28_29 == 1
&& insn_bits10_11 == 1 && !insn_bit21)
return aarch64_record_memcopy_memset (aarch64_insn_r);
+ /* Large System Extension 128 (LSE128) instructions. */
+ else if (vector_flag == 0 && insn_bits10_11 == 0 && insn_bit21
+ && size_bits == 0 && !bit (aarch64_insn_r->aarch64_insn, 29)
+ && bits (aarch64_insn_r->aarch64_insn, 24, 25) == 0x1)
+ {
+ regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn, &address);
+ record_buf_mem[0] = 128 >> 3;
+ record_buf_mem[1] = address;
+ aarch64_insn_r->mem_rec_count = 1;
+ record_buf[0] = reg_rt;
+ record_buf[1] = bits (aarch64_insn_r->aarch64_insn, 16, 20);
+ aarch64_insn_r->reg_rec_count = 2;
+ }
/* Advanced SIMD load/store instructions. */
else
return aarch64_record_asimd_load_store (aarch64_insn_r);
diff --git a/gdb/testsuite/gdb.reverse/aarch64-lse128.c b/gdb/testsuite/gdb.reverse/aarch64-lse128.c
new file mode 100644
index 00000000..0f1540e3
--- /dev/null
+++ b/gdb/testsuite/gdb.reverse/aarch64-lse128.c
@@ -0,0 +1,100 @@
+/* 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 <stdalign.h>
+#include <stdint.h>
+#include <string.h>
+
+#define INITIAL_STRING "This is just some string."
+#define BUF_SIZE sizeof (INITIAL_STRING)
+
+#define PREPARE_REGS(X, Y) \
+ strcpy (src, INITIAL_STRING); \
+ __asm__ volatile ("mov x21, %0\n" ::"r"((uint64_t *)src) : "x21"); \
+ __asm__ volatile ("mov x19, %0\n" ::"r"(X) : "x19"); \
+ __asm__ volatile ("mov x20, %0\n" ::"r"(Y) : "x20");
+
+int
+main (void)
+{
+ alignas (16) char src[BUF_SIZE];
+
+ uint64_t a = 0x0123456789abcdef;
+ uint64_t b = 0xfedbca9876543210;
+
+ PREPARE_REGS (a, b);
+ /* Before ldclrp. */
+ __asm__ volatile ("ldclrp x19, x20, [x21]\n" : : : "x19", "x20", "memory");
+ /* After ldclrp. */
+
+ PREPARE_REGS (a, b);
+ /* Before ldclrpa. */
+ __asm__ volatile ("ldclrpa x19, x20, [x21]\n" : : : "x19", "x20", "memory");
+ /* After ldclrpa. */
+
+ PREPARE_REGS (a, b);
+ /* Before ldclrpal. */
+ __asm__ volatile ("ldclrpal x19, x20, [x21]\n" : : : "x19", "x20", "memory");
+ /* After ldclrpal. */
+
+ PREPARE_REGS (a, b);
+ /* Before ldclrpl. */
+ __asm__ volatile ("ldclrpl x19, x20, [x21]\n" : : : "x19", "x20", "memory");
+ /* After ldclrpl. */
+
+ PREPARE_REGS (a, b);
+ /* Before ldsetp. */
+ __asm__ volatile ("ldsetp x19, x20, [x21]\n" : : : "x19", "x20", "memory");
+ /* After ldsetp. */
+
+ PREPARE_REGS (a, b);
+ /* Before ldsetpa. */
+ __asm__ volatile ("ldsetpa x19, x20, [x21]\n" : : : "x19", "x20", "memory");
+ /* After ldsetpa. */
+
+ PREPARE_REGS (a, b);
+ /* Before ldsetpal. */
+ __asm__ volatile ("ldsetpal x19, x20, [x21]\n" : : : "x19", "x20", "memory");
+ /* After ldsetpal. */
+
+ PREPARE_REGS (a, b);
+ /* Before ldsetpl. */
+ __asm__ volatile ("ldsetpl x19, x20, [x21]\n" : : : "x19", "x20", "memory");
+ /* After ldsetpl. */
+
+ PREPARE_REGS (a, b);
+ /* Before swpp. */
+ __asm__ volatile ("swpp x19, x20, [x21]\n" : : : "x19", "x20", "memory");
+ /* After swpp. */
+
+ PREPARE_REGS (a, b);
+ /* Before swppa. */
+ __asm__ volatile ("swppa x19, x20, [x21]\n" : : : "x19", "x20", "memory");
+ /* After swppa. */
+
+ PREPARE_REGS (a, b);
+ /* Before swppal. */
+ __asm__ volatile ("swppal x19, x20, [x21]\n" : : : "x19", "x20", "memory");
+ /* After swppal. */
+
+ PREPARE_REGS (a, b);
+ /* Before swppl. */
+ __asm__ volatile ("swppl x19, x20, [x21]\n" : : : "x19", "x20", "memory");
+ /* After swppl. */
+
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.reverse/aarch64-lse128.exp b/gdb/testsuite/gdb.reverse/aarch64-lse128.exp
new file mode 100644
index 00000000..edb254bc
--- /dev/null
+++ b/gdb/testsuite/gdb.reverse/aarch64-lse128.exp
@@ -0,0 +1,137 @@
+# 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_LSE128 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.
+
+standard_testfile
+
+require allow_aarch64_lse128_tests
+
+if {[prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \
+ [list debug additional_flags=-march=armv8-a+lse128]]} {
+ return
+}
+
+if {![runto_main]} {
+ return
+}
+
+gdb_test_no_output "record full"
+
+proc test_single_asm {insn} {
+ with_test_prefix $insn {
+ set before_seq [gdb_get_line_number "Before ${insn}"]
+ set after_seq [gdb_get_line_number "After ${insn}"]
+ set regs { x19 x20 x21 }
+
+ gdb_test "break $before_seq" \
+ "Breakpoint ${::decimal} at ${::hex}: file .*/aarch64-lse128.c, line ${::decimal}\\." \
+ "$insn: break before instruction sequence"
+ gdb_continue_to_breakpoint "$insn: about to execute instruction sequence" \
+ [multi_line ".*/aarch64-lse128.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-lse128.c, line ${::decimal}\\." \
+ "$insn: break at prologue instruction"
+
+ # Record the initial memory and 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-lse128.c, line ${::decimal}\\." \
+ "$insn: break after instruction sequence"
+ gdb_continue_to_breakpoint "$insn: executed instruction sequence" \
+ [multi_line ".*/aarch64-lse128.c:${::decimal}" ".*"]
+
+ # Record the new memory and 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-lse128.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 $regs {
+ gdb_assert ![string compare [set ${v}_initial] [set ${v}_final]] \
+ "$insn: check $v initial value versus $v final value"
+ }
+ foreach v {x19 x20} {
+ gdb_assert [string compare [set ${v}_initial] [set ${v}_new]] \
+ "$insn: check $v initial value versus $v new value"
+ }
+ gdb_assert ![string compare [set x21_initial] [set x21_new]] \
+ "$insn: check x21 initial value versus x21 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-lse128.c:${::decimal}" \
+ ".*"]
+ }
+}
+
+set cases {
+ { ldclrp }
+ { ldclrpa }
+ { ldclrpal }
+ { ldclrpl }
+ { ldsetp }
+ { ldsetpa }
+ { ldsetpal }
+ { ldsetpl }
+ { swpp }
+ { swppa }
+ { swppal }
+ { swppl }
+}
+
+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 9d5c0e5a..d62b4927 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -5402,6 +5402,62 @@ gdb_caching_proc allow_aarch64_cssc_tests {} {
return $allow_cssc_tests
}
+# Run a test on the target to see if it supports the AArch64 LSE128 feature.
+# Return 1 if so, 0 if it does not. Note this causes a restart of GDB.
+
+gdb_caching_proc allow_aarch64_lse128_tests {} {
+ global srcdir subdir gdb_prompt inferior_exited_re
+
+ set me "allow_aarch64_lse128_tests"
+
+ if { ![is_aarch64_target]} {
+ return 0
+ }
+
+ set compile_flags "{additional_flags=-march=armv8-a+lse128}"
+
+ # Compile a test program reading LSE128.
+ set src {
+ #include <stdint.h>
+
+ int main() {
+ __attribute__((aligned(16))) uint64_t mem[2] = { 0x0, 0x1 };
+ uint64_t *ptr = mem;
+ __asm__ volatile ("ldclrp x0, x1, [%0]\n" :: "r"(ptr) : "x0", "x1", "memory");
+ 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 lse128 support not detected"
+ set allow_lse128_tests 0
+ }
+ -re ".*$inferior_exited_re normally.*${gdb_prompt} $" {
+ verbose -log "\n$me: lse128 support detected"
+ set allow_lse128_tests 1
+ }
+ default {
+ warning "\n$me: default case taken"
+ set allow_lse128_tests 0
+ }
+ }
+ gdb_exit
+ remote_file build delete $obj
+
+ verbose "$me: returning $allow_lse128_tests" 2
+ return $allow_lse128_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.53.0
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 1/4] gdb/aarch64: record/replay support for LRCPC3
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-26 14:30 ` Guinevere Larsen
1 sibling, 1 reply; 18+ messages in thread
From: Thiago Jung Bauermann @ 2026-05-15 3:50 UTC (permalink / raw)
To: Ezra.Sitorus; +Cc: gdb-patches, luis.machado.foss, guinevere
Hello Ezra,
Mostly looks good to me. Just a couple of comments in
allow_aarch64_lrcpc3_tests and a question on how to test:
<Ezra.Sitorus@arm.com> writes:
> diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
> index 28709004..3f3197cb 100644
> --- a/gdb/testsuite/lib/gdb.exp
> +++ b/gdb/testsuite/lib/gdb.exp
> @@ -5287,6 +5287,69 @@ gdb_caching_proc allow_aarch64_fpmr_tests {} {
> return $allow_fpmr_tests
> }
>
> +# Run a test on the target to see if it supports AArch64 LRCPC3 (Load-Acquire
> +# RCpc instructions) extensions. Return 1 if so, 0 if it does not. Note this
> +# causes a restart of GDB.
> +
> +gdb_caching_proc allow_aarch64_lrcpc3_tests {} {
> + global srcdir subdir gdb_prompt inferior_exited_re
> +
> + set me "allow_aarch64_lrcpc3_tests"
> +
> + if { ![is_aarch64_target] } {
> + return 0
> + }
> +
> + # Take the opportunity to check whether the toolchain knows about LRCPC3.
> + set compile_flags "{additional_flags=-march=armv8-a+rcpc3}"
> +
> + # Compile a program that tests the LRCPC3 feature.
> + set src {
> + #include <stdbool.h>
> + #include <sys/auxv.h>
> +
> + /* Feature check for LRCPC3. */
> + #ifndef HWCAP_LRCPC3
> + #define HWCAP_LRCPC3 (1ULL << 46)
> + #endif
In the system headers, this constant is called HWCAP2_LRCPC3.
> +
> + int main (void) {
> + bool lrcpc3_supported = getauxval (AT_HWCAP2) & HWCAP_LRCPC3;
> +
> + /* Return success if LRCPC3 is supported. */
> + return !lrcpc3_supported;
> + }
> + }
> +
> + 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 lrcpc3 support not detected"
> + set allow_lrcpc3_tests 0
> + }
> + -re ".*$inferior_exited_re normally.*${gdb_prompt} $" {
> + verbose -log "\n$me: lrcpc3 support detected"
> + set allow_lrcpc3_tests 1
> + }
> + default {
> + warning "\n$me: default case taken"
> + set allow_lrcpc3_tests 0
> + }
> + }
The test program in v1 tried to execute an instruction to detect whether
LRCPC3 is supported, and in v2 it checks a bit in HWCAP. Nothing wrong
with that, but the gdb_expect above needs to be adapted accordingly. On
a machine which doesn't support the feature I see a WARNING, but the
test program just behaved as expected:
(gdb) file /home/bauermann/.cache/builds/gdb-native/gdb/testsuite/temp/1223/allow_aarch64_lrcpc3_tests.x
Reading symbols from /home/bauermann/.cache/builds/gdb-native/gdb/testsuite/temp/1223/allow_aarch64_lrcpc3_tests.x...
(gdb) run
Starting program: /home/bauermann/.cache/builds/gdb-native/gdb/testsuite/temp/1223/allow_aarch64_lrcpc3_tests.x
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/aarch64-linux-gnu/libthread_db.so.1".
[Inferior 1 (process 1299) exited with code 01]
(gdb) WARNING:
allow_aarch64_lrcpc3_tests: default case taken
gdb_caching_proc allow_aarch64_lrcpc3_tests caused gdb_exit to be called
gdb_caching_proc allow_aarch64_lrcpc3_tests marked as called
gdb_caching_proc get_compiler_info_1 marked as called
gdb_caching_proc is_aarch32_target marked as called
gdb_caching_proc universal_compile_options_c marked as called
UNSUPPORTED: gdb.reverse/aarch64-lrcpc3.exp: require failed: allow_aarch64_lrcpc3_tests
testcase /home/bauermann/src/binutils-gdb/gdb/testsuite/gdb.reverse/aarch64-lrcpc3.exp completed in 26 seconds
By the way, is there something specific I need to do to get an FVP
supporting LRCPC3? I set up FVP with:
$ shrinkwrap build --overlay=arch/v9.6.yaml ns-edk2.yaml
But then inside the guest the CPU features in /proc/cpuinfo and the
HWCAP2 don't mention LRCPC3. If I hard-code the testcase to run anyway,
then the inferior dies with a SIGILL.
> + gdb_exit
> + remote_file build delete $obj
> +
> + verbose "$me: returning $allow_lrcpc3_tests" 2
> + return $allow_lrcpc3_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.
--
Thiago
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 2/4] gdb/aarch64: Test record/replay support for CSSC
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
1 sibling, 1 reply; 18+ messages in thread
From: Thiago Jung Bauermann @ 2026-05-15 3:50 UTC (permalink / raw)
To: Ezra.Sitorus; +Cc: gdb-patches, luis.machado.foss, guinevere
<Ezra.Sitorus@arm.com> writes:
> From: Ezra Sitorus <ezra.sitorus@arm.com>
>
> GDB can handle AArch64's CSSC instructions but there were no tests
> ensuring that and ensuring no regressions would creep in. This commit
> adds some tests for these instructions. This was tested on
> aarch64-none-linux-gnu on QEMU with CSSC support.
> ---
> gdb/testsuite/gdb.reverse/aarch64-cssc.c | 88 +++++++++++++
> gdb/testsuite/gdb.reverse/aarch64-cssc.exp | 139 +++++++++++++++++++++
> gdb/testsuite/lib/gdb.exp | 52 ++++++++
> 3 files changed, 279 insertions(+)
> create mode 100644 gdb/testsuite/gdb.reverse/aarch64-cssc.c
> create mode 100644 gdb/testsuite/gdb.reverse/aarch64-cssc.exp
Looks good to me, thanks!
Reviewed-by: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
I think Guinevere should approve it though.
--
Thiago
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 3/4] gdb/aarch64: record/replay support for RPRFM, PRFM (reg), PRFUM
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
0 siblings, 0 replies; 18+ messages in thread
From: Thiago Jung Bauermann @ 2026-05-15 3:56 UTC (permalink / raw)
To: Ezra.Sitorus; +Cc: gdb-patches, luis.machado.foss, guinevere
<Ezra.Sitorus@arm.com> writes:
> From: Ezra Sitorus <ezra.sitorus@arm.com>
>
> The PRFM (register) instruction variant was unsupported. This is added
> along with RPRFM and PRFUM.
>
> No testcase has been added as these are hint instructions which don't
> modify registers/memory.
>
> The full testsuite was done on aarch64-none-linux-gnu without RPRFM.
> The gdb.arch and gdb.reverse tests were run on Shrinkwrap with RPRFM
> support.
> ---
> gdb/aarch64-tdep.c | 13 +++++++++++--
> 1 file changed, 11 insertions(+), 2 deletions(-)
Thank you for adding PRFUM support. You already had Luis' approval for
v1, here is mine as well:
Approved-by: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
If you want you can go ahead and push this patch separately.
--
Thiago
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 4/4] gdb/aarch64: record/replay support for LSE128
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
1 sibling, 0 replies; 18+ messages in thread
From: Thiago Jung Bauermann @ 2026-05-15 3:58 UTC (permalink / raw)
To: Ezra.Sitorus; +Cc: gdb-patches, luis.machado.foss, guinevere
<Ezra.Sitorus@arm.com> writes:
> From: Ezra Sitorus <ezra.sitorus@arm.com>
>
> FEAT_LSE128 introduces support for 128-bit atomic instructions. This
> patch teaches GDB to decode these instructions for recording and
> reversing.
>
> Regression tested on aarch64-none-linux-gnu on QEMU with LSE128 support.
> I observe unrelated regressions that appear to be environmental rather
> than caused by this patch.
> ---
> gdb/aarch64-tdep.c | 13 ++
> gdb/testsuite/gdb.reverse/aarch64-lse128.c | 100 ++++++++++++++
> gdb/testsuite/gdb.reverse/aarch64-lse128.exp | 137 +++++++++++++++++++
> gdb/testsuite/lib/gdb.exp | 56 ++++++++
> 4 files changed, 306 insertions(+)
> create mode 100644 gdb/testsuite/gdb.reverse/aarch64-lse128.c
> create mode 100644 gdb/testsuite/gdb.reverse/aarch64-lse128.exp
Looks good to me.
Reviewed-by: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
I think Guinevere should approve it though.
--
Thiago
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 0/4] gdb/aarch64: record/replay support for AArch64
2026-05-12 23:17 [PATCH v2 0/4] gdb/aarch64: record/replay support for AArch64 Ezra.Sitorus
` (3 preceding siblings ...)
2026-05-12 23:17 ` [PATCH v2 4/4] gdb/aarch64: record/replay support for LSE128 Ezra.Sitorus
@ 2026-05-15 3:59 ` Thiago Jung Bauermann
4 siblings, 0 replies; 18+ messages in thread
From: Thiago Jung Bauermann @ 2026-05-15 3:59 UTC (permalink / raw)
To: Ezra.Sitorus; +Cc: gdb-patches, luis.machado.foss, guinevere
<Ezra.Sitorus@arm.com> writes:
> Thiago mentioned about copyright years in the previous version. I think
> I should be using the range 2024-2026 since the tests are based on
> previous tests and I should be retaining the original years. In my case,
> these come from the aarch64-mops.{c,exp} tests. The GDB contribution
> checklist site says so too!
Indeed, you are right. I had a wrong understanding of this topic.
Thanks for checking and pointing it out!
--
Thiago
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 1/4] gdb/aarch64: record/replay support for LRCPC3
2026-05-15 3:50 ` Thiago Jung Bauermann
@ 2026-05-15 11:45 ` Ezra Sitorus
2026-05-15 23:03 ` Thiago Jung Bauermann
0 siblings, 1 reply; 18+ messages in thread
From: Ezra Sitorus @ 2026-05-15 11:45 UTC (permalink / raw)
To: Thiago Jung Bauermann; +Cc: gdb-patches, luis.machado.foss, guinevere
On Fri, May 15, 2026 at 12:50:30AM -0300, Thiago Jung Bauermann wrote:
> In the system headers, this constant is called HWCAP2_LRCPC3.
Yes that's right. I'll change that.
> The test program in v1 tried to execute an instruction to detect whether
> LRCPC3 is supported, and in v2 it checks a bit in HWCAP. Nothing wrong
> with that, but the gdb_expect above needs to be adapted accordingly. On
> a machine which doesn't support the feature I see a WARNING, but the
> test program just behaved as expected:
>
> (gdb) file /home/bauermann/.cache/builds/gdb-native/gdb/testsuite/temp/1223/allow_aarch64_lrcpc3_tests.x
> Reading symbols from /home/bauermann/.cache/builds/gdb-native/gdb/testsuite/temp/1223/allow_aarch64_lrcpc3_tests.x...
> (gdb) run
> Starting program: /home/bauermann/.cache/builds/gdb-native/gdb/testsuite/temp/1223/allow_aarch64_lrcpc3_tests.x
> [Thread debugging using libthread_db enabled]
> Using host libthread_db library "/usr/lib/aarch64-linux-gnu/libthread_db.so.1".
> [Inferior 1 (process 1299) exited with code 01]
> (gdb) WARNING:
> allow_aarch64_lrcpc3_tests: default case taken
> gdb_caching_proc allow_aarch64_lrcpc3_tests caused gdb_exit to be called
> gdb_caching_proc allow_aarch64_lrcpc3_tests marked as called
> gdb_caching_proc get_compiler_info_1 marked as called
> gdb_caching_proc is_aarch32_target marked as called
> gdb_caching_proc universal_compile_options_c marked as called
> UNSUPPORTED: gdb.reverse/aarch64-lrcpc3.exp: require failed: allow_aarch64_lrcpc3_tests
> testcase /home/bauermann/src/binutils-gdb/gdb/testsuite/gdb.reverse/aarch64-lrcpc3.exp completed in 26 seconds
Ahh I see. I'll compare it with the GCS support testing.
> By the way, is there something specific I need to do to get an FVP
> supporting LRCPC3? I set up FVP with:
>
> $ shrinkwrap build --overlay=arch/v9.6.yaml ns-edk2.yaml
>
You need to enable the feature in an overlay file. So I have something like this:
run:
rtvars:
ROOTFS:
value: /path/to/rootfs
CMDLINE:
value: loglevel=3 ip=dhcp kpti=off root=/dev/vda2 console=ttyAMA0
KERNEL:
value: path/to/Image
params:
-C bp.hostbridge.userNetworking: 1
-C bp.hostbridge.userNetPorts: 8022=22,8123=8123
-C bp.smsc_91c111.enabled: 1
-C bp.virtio_net.enabled: 0
-C cluster0.NUM_CORES: 1
-C cluster0.has_lrcpc3: 1
-C cluster0.has_rprfm: 1
-C pctl.CPU-affinities: 0.0.0.0
which enables LRCPC3, RPRFM and some networking. Then I run like so:
$ shrinkwrap run ns-edk2.yaml --overlay file.yaml.
Also, you can do:
$ shrinkwrap build --overlay=arch/v8.9.yaml ns-edk2.yaml
which should enable fewer features so it'll run slightly quicker.
On another note, it seems like patch 2 and 3 are OK? Can these be pushed while
I resend this one and wait for Guinevere for patch 4?
Ezra
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 1/4] gdb/aarch64: record/replay support for LRCPC3
2026-05-15 11:45 ` Ezra Sitorus
@ 2026-05-15 23:03 ` Thiago Jung Bauermann
0 siblings, 0 replies; 18+ messages in thread
From: Thiago Jung Bauermann @ 2026-05-15 23:03 UTC (permalink / raw)
To: Ezra Sitorus; +Cc: gdb-patches, luis.machado.foss, guinevere
Ezra Sitorus <ezra.sitorus@arm.com> writes:
> On Fri, May 15, 2026 at 12:50:30AM -0300, Thiago Jung Bauermann wrote:
>
>> By the way, is there something specific I need to do to get an FVP
>> supporting LRCPC3? I set up FVP with:
>>
>> $ shrinkwrap build --overlay=arch/v9.6.yaml ns-edk2.yaml
>>
> You need to enable the feature in an overlay file. So I have something like this:
>
> run:
> rtvars:
> ROOTFS:
> value: /path/to/rootfs
> CMDLINE:
> value: loglevel=3 ip=dhcp kpti=off root=/dev/vda2 console=ttyAMA0
> KERNEL:
> value: path/to/Image
> params:
> -C bp.hostbridge.userNetworking: 1
> -C bp.hostbridge.userNetPorts: 8022=22,8123=8123
> -C bp.smsc_91c111.enabled: 1
> -C bp.virtio_net.enabled: 0
> -C cluster0.NUM_CORES: 1
> -C cluster0.has_lrcpc3: 1
> -C cluster0.has_rprfm: 1
> -C pctl.CPU-affinities: 0.0.0.0
>
> which enables LRCPC3, RPRFM and some networking. Then I run like so:
> $ shrinkwrap run ns-edk2.yaml --overlay file.yaml.
Thanks! That worked but I had to make some adjustments:
1. Remove the pctl.CPU-affinities parameter. It was causing FVP to get
really slow after the edk2 UEFI firmware loads.
2. Add the same cluster0 settings to cluster1, otherwise lrcpc3 and
rprfm didn't actually get enabled. I think the CPU-affinities
parameter was meant to disable cluster1, but for some reason it
didn't work here.
> Also, you can do:
> $ shrinkwrap build --overlay=arch/v8.9.yaml ns-edk2.yaml
>
> which should enable fewer features so it'll run slightly quicker.
Thanks, that's useful. Slightly quicker already helps.
> On another note, it seems like patch 2 and 3 are OK? Can these be pushed while
> I resend this one and wait for Guinevere for patch 4?
Yes for patch 3, but regarding patches 1, 2 and 4 I'd like to see if
she's happy with how you addressed her suggestions.
--
Thiago
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 1/4] gdb/aarch64: record/replay support for LRCPC3
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-26 14:30 ` Guinevere Larsen
2026-05-26 23:36 ` Ezra Sitorus
1 sibling, 1 reply; 18+ messages in thread
From: Guinevere Larsen @ 2026-05-26 14:30 UTC (permalink / raw)
To: Ezra.Sitorus, gdb-patches; +Cc: luis.machado.foss, thiago.bauermann
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
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 2/4] gdb/aarch64: Test record/replay support for CSSC
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 16:40 ` Guinevere Larsen
1 sibling, 0 replies; 18+ messages in thread
From: Guinevere Larsen @ 2026-05-26 16:40 UTC (permalink / raw)
To: Ezra.Sitorus, gdb-patches; +Cc: luis.machado.foss, thiago.bauermann
On 5/12/26 8:17 PM, Ezra.Sitorus@arm.com wrote:
> From: Ezra Sitorus <ezra.sitorus@arm.com>
>
> GDB can handle AArch64's CSSC instructions but there were no tests
> ensuring that and ensuring no regressions would creep in. This commit
> adds some tests for these instructions. This was tested on
> aarch64-none-linux-gnu on QEMU with CSSC support.
> ---
Hi Ezra! This patch looks pretty good to me!
Reviewed-By: Guinevere Larsen <guinevere@redhat.com>
--
Cheers,
Guinevere Larsen
It/she
> gdb/testsuite/gdb.reverse/aarch64-cssc.c | 88 +++++++++++++
> gdb/testsuite/gdb.reverse/aarch64-cssc.exp | 139 +++++++++++++++++++++
> gdb/testsuite/lib/gdb.exp | 52 ++++++++
> 3 files changed, 279 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 00000000..67ccb68e
> --- /dev/null
> +++ b/gdb/testsuite/gdb.reverse/aarch64-cssc.c
> @@ -0,0 +1,88 @@
> +/* 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 x19, %0\n" : : "r"(X): "x19"); \
> + __asm__ volatile ("mov x20, %0\n" : : "r"(Y): "x20"); \
> + __asm__ volatile ("mov x21, %0\n" : : "r"(Z): "x21");
> +
> +int
> +main (void)
> +{
> + 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 x19, x21\n" ::: "x19");
> + /* After abs. */
> +
> + PREPARE_REGS (a, b, c);
> + /* Before cnt. */
> + __asm__ volatile ("cnt x19, x20\n" : :: "x19");
> + /* After cnt. */
> +
> + PREPARE_REGS (a, b, c);
> + /* Before ctz. */
> + __asm__ volatile ("ctz x19, x20\n" : :: "x19");
> + /* After ctz. */
> +
> + PREPARE_REGS (a, b, c);
> + /* Before smax-1. */
> + __asm__ volatile ("smax x19, x20, #10\n" : :: "x19");
> + /* After smax-1. */
> +
> + PREPARE_REGS (a, b, c);
> + /* Before smax-2. */
> + __asm__ volatile ("smax x19, x20, x21\n" : :: "x19");
> + /* After smax-2. */
> +
> + PREPARE_REGS (a, b, c);
> + /* Before smin-1. */
> + __asm__ volatile ("smin x19, x20, #10\n" : :: "x19");
> + /* After smin-1. */
> +
> + PREPARE_REGS (a, b, c);
> + /* Before smin-2. */
> + __asm__ volatile ("smin x19, x20, x21\n" : :: "x19");
> + /* After smin-2. */
> +
> + PREPARE_REGS (a, b, c);
> + /* Before umax-1. */
> + __asm__ volatile ("umax x19, x20, #10\n" : :: "x19");
> + /* After umax-1. */
> +
> + PREPARE_REGS (a, b, c);
> + /* Before umax-2. */
> + __asm__ volatile ("umax x19, x20, x21\n" : :: "x19");
> + /* After umax-2. */
> +
> + PREPARE_REGS (a, b, c);
> + /* Before umin-1. */
> + __asm__ volatile ("umin x19, x20, #10\n" : :: "x19");
> + /* After umin-1. */
> +
> + PREPARE_REGS (a, b, c);
> + /* Before umin-2. */
> + __asm__ volatile ("umin x19, x20, x21\n" : :: "x19");
> + /* 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 00000000..1e2980a6
> --- /dev/null
> +++ b/gdb/testsuite/gdb.reverse/aarch64-cssc.exp
> @@ -0,0 +1,139 @@
> +# 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
> +}
> +
> +if {![runto_main]} {
> + return
> +}
> +
> +gdb_test_no_output "record full"
> +
> +proc test_single_asm { name } {
> + with_test_prefix $name {
> + 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} .*\".*"]
> +
> + # 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} .*\".*"]
> +
> + # 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 3f3197cb..9d5c0e5a 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" ::: "x0");
> + 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.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 4/4] gdb/aarch64: record/replay support for LSE128
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
1 sibling, 0 replies; 18+ messages in thread
From: Guinevere Larsen @ 2026-05-26 19:40 UTC (permalink / raw)
To: Ezra.Sitorus, gdb-patches; +Cc: luis.machado.foss, thiago.bauermann
On 5/12/26 8:17 PM, Ezra.Sitorus@arm.com wrote:
> From: Ezra Sitorus <ezra.sitorus@arm.com>
>
> FEAT_LSE128 introduces support for 128-bit atomic instructions. This
> patch teaches GDB to decode these instructions for recording and
> reversing.
>
> Regression tested on aarch64-none-linux-gnu on QEMU with LSE128 support.
> I observe unrelated regressions that appear to be environmental rather
> than caused by this patch.
> ---
Hi Ezra!
Thanks for addressing all the things I raised on all the patches! I'm
happy to approve this patch!
Approved-By: Guinevere Larsen <guinevere@redhat.com>
--
Cheers,
Guinevere Larsen
It/she
> gdb/aarch64-tdep.c | 13 ++
> gdb/testsuite/gdb.reverse/aarch64-lse128.c | 100 ++++++++++++++
> gdb/testsuite/gdb.reverse/aarch64-lse128.exp | 137 +++++++++++++++++++
> gdb/testsuite/lib/gdb.exp | 56 ++++++++
> 4 files changed, 306 insertions(+)
> create mode 100644 gdb/testsuite/gdb.reverse/aarch64-lse128.c
> create mode 100644 gdb/testsuite/gdb.reverse/aarch64-lse128.exp
>
> diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
> index 5c1f8af5..0cce4072 100644
> --- a/gdb/aarch64-tdep.c
> +++ b/gdb/aarch64-tdep.c
> @@ -6008,6 +6008,19 @@ aarch64_record_load_store (aarch64_insn_decode_record *aarch64_insn_r)
> else if ((insn_bits24_27 & 1) == 1 && insn_bits28_29 == 1
> && insn_bits10_11 == 1 && !insn_bit21)
> return aarch64_record_memcopy_memset (aarch64_insn_r);
> + /* Large System Extension 128 (LSE128) instructions. */
> + else if (vector_flag == 0 && insn_bits10_11 == 0 && insn_bit21
> + && size_bits == 0 && !bit (aarch64_insn_r->aarch64_insn, 29)
> + && bits (aarch64_insn_r->aarch64_insn, 24, 25) == 0x1)
> + {
> + regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn, &address);
> + record_buf_mem[0] = 128 >> 3;
> + record_buf_mem[1] = address;
> + aarch64_insn_r->mem_rec_count = 1;
> + record_buf[0] = reg_rt;
> + record_buf[1] = bits (aarch64_insn_r->aarch64_insn, 16, 20);
> + aarch64_insn_r->reg_rec_count = 2;
> + }
> /* Advanced SIMD load/store instructions. */
> else
> return aarch64_record_asimd_load_store (aarch64_insn_r);
> diff --git a/gdb/testsuite/gdb.reverse/aarch64-lse128.c b/gdb/testsuite/gdb.reverse/aarch64-lse128.c
> new file mode 100644
> index 00000000..0f1540e3
> --- /dev/null
> +++ b/gdb/testsuite/gdb.reverse/aarch64-lse128.c
> @@ -0,0 +1,100 @@
> +/* 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 <stdalign.h>
> +#include <stdint.h>
> +#include <string.h>
> +
> +#define INITIAL_STRING "This is just some string."
> +#define BUF_SIZE sizeof (INITIAL_STRING)
> +
> +#define PREPARE_REGS(X, Y) \
> + strcpy (src, INITIAL_STRING); \
> + __asm__ volatile ("mov x21, %0\n" ::"r"((uint64_t *)src) : "x21"); \
> + __asm__ volatile ("mov x19, %0\n" ::"r"(X) : "x19"); \
> + __asm__ volatile ("mov x20, %0\n" ::"r"(Y) : "x20");
> +
> +int
> +main (void)
> +{
> + alignas (16) char src[BUF_SIZE];
> +
> + uint64_t a = 0x0123456789abcdef;
> + uint64_t b = 0xfedbca9876543210;
> +
> + PREPARE_REGS (a, b);
> + /* Before ldclrp. */
> + __asm__ volatile ("ldclrp x19, x20, [x21]\n" : : : "x19", "x20", "memory");
> + /* After ldclrp. */
> +
> + PREPARE_REGS (a, b);
> + /* Before ldclrpa. */
> + __asm__ volatile ("ldclrpa x19, x20, [x21]\n" : : : "x19", "x20", "memory");
> + /* After ldclrpa. */
> +
> + PREPARE_REGS (a, b);
> + /* Before ldclrpal. */
> + __asm__ volatile ("ldclrpal x19, x20, [x21]\n" : : : "x19", "x20", "memory");
> + /* After ldclrpal. */
> +
> + PREPARE_REGS (a, b);
> + /* Before ldclrpl. */
> + __asm__ volatile ("ldclrpl x19, x20, [x21]\n" : : : "x19", "x20", "memory");
> + /* After ldclrpl. */
> +
> + PREPARE_REGS (a, b);
> + /* Before ldsetp. */
> + __asm__ volatile ("ldsetp x19, x20, [x21]\n" : : : "x19", "x20", "memory");
> + /* After ldsetp. */
> +
> + PREPARE_REGS (a, b);
> + /* Before ldsetpa. */
> + __asm__ volatile ("ldsetpa x19, x20, [x21]\n" : : : "x19", "x20", "memory");
> + /* After ldsetpa. */
> +
> + PREPARE_REGS (a, b);
> + /* Before ldsetpal. */
> + __asm__ volatile ("ldsetpal x19, x20, [x21]\n" : : : "x19", "x20", "memory");
> + /* After ldsetpal. */
> +
> + PREPARE_REGS (a, b);
> + /* Before ldsetpl. */
> + __asm__ volatile ("ldsetpl x19, x20, [x21]\n" : : : "x19", "x20", "memory");
> + /* After ldsetpl. */
> +
> + PREPARE_REGS (a, b);
> + /* Before swpp. */
> + __asm__ volatile ("swpp x19, x20, [x21]\n" : : : "x19", "x20", "memory");
> + /* After swpp. */
> +
> + PREPARE_REGS (a, b);
> + /* Before swppa. */
> + __asm__ volatile ("swppa x19, x20, [x21]\n" : : : "x19", "x20", "memory");
> + /* After swppa. */
> +
> + PREPARE_REGS (a, b);
> + /* Before swppal. */
> + __asm__ volatile ("swppal x19, x20, [x21]\n" : : : "x19", "x20", "memory");
> + /* After swppal. */
> +
> + PREPARE_REGS (a, b);
> + /* Before swppl. */
> + __asm__ volatile ("swppl x19, x20, [x21]\n" : : : "x19", "x20", "memory");
> + /* After swppl. */
> +
> + return 0;
> +}
> diff --git a/gdb/testsuite/gdb.reverse/aarch64-lse128.exp b/gdb/testsuite/gdb.reverse/aarch64-lse128.exp
> new file mode 100644
> index 00000000..edb254bc
> --- /dev/null
> +++ b/gdb/testsuite/gdb.reverse/aarch64-lse128.exp
> @@ -0,0 +1,137 @@
> +# 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_LSE128 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.
> +
> +standard_testfile
> +
> +require allow_aarch64_lse128_tests
> +
> +if {[prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \
> + [list debug additional_flags=-march=armv8-a+lse128]]} {
> + return
> +}
> +
> +if {![runto_main]} {
> + return
> +}
> +
> +gdb_test_no_output "record full"
> +
> +proc test_single_asm {insn} {
> + with_test_prefix $insn {
> + set before_seq [gdb_get_line_number "Before ${insn}"]
> + set after_seq [gdb_get_line_number "After ${insn}"]
> + set regs { x19 x20 x21 }
> +
> + gdb_test "break $before_seq" \
> + "Breakpoint ${::decimal} at ${::hex}: file .*/aarch64-lse128.c, line ${::decimal}\\." \
> + "$insn: break before instruction sequence"
> + gdb_continue_to_breakpoint "$insn: about to execute instruction sequence" \
> + [multi_line ".*/aarch64-lse128.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-lse128.c, line ${::decimal}\\." \
> + "$insn: break at prologue instruction"
> +
> + # Record the initial memory and 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-lse128.c, line ${::decimal}\\." \
> + "$insn: break after instruction sequence"
> + gdb_continue_to_breakpoint "$insn: executed instruction sequence" \
> + [multi_line ".*/aarch64-lse128.c:${::decimal}" ".*"]
> +
> + # Record the new memory and 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-lse128.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 $regs {
> + gdb_assert ![string compare [set ${v}_initial] [set ${v}_final]] \
> + "$insn: check $v initial value versus $v final value"
> + }
> + foreach v {x19 x20} {
> + gdb_assert [string compare [set ${v}_initial] [set ${v}_new]] \
> + "$insn: check $v initial value versus $v new value"
> + }
> + gdb_assert ![string compare [set x21_initial] [set x21_new]] \
> + "$insn: check x21 initial value versus x21 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-lse128.c:${::decimal}" \
> + ".*"]
> + }
> +}
> +
> +set cases {
> + { ldclrp }
> + { ldclrpa }
> + { ldclrpal }
> + { ldclrpl }
> + { ldsetp }
> + { ldsetpa }
> + { ldsetpal }
> + { ldsetpl }
> + { swpp }
> + { swppa }
> + { swppal }
> + { swppl }
> +}
> +
> +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 9d5c0e5a..d62b4927 100644
> --- a/gdb/testsuite/lib/gdb.exp
> +++ b/gdb/testsuite/lib/gdb.exp
> @@ -5402,6 +5402,62 @@ gdb_caching_proc allow_aarch64_cssc_tests {} {
> return $allow_cssc_tests
> }
>
> +# Run a test on the target to see if it supports the AArch64 LSE128 feature.
> +# Return 1 if so, 0 if it does not. Note this causes a restart of GDB.
> +
> +gdb_caching_proc allow_aarch64_lse128_tests {} {
> + global srcdir subdir gdb_prompt inferior_exited_re
> +
> + set me "allow_aarch64_lse128_tests"
> +
> + if { ![is_aarch64_target]} {
> + return 0
> + }
> +
> + set compile_flags "{additional_flags=-march=armv8-a+lse128}"
> +
> + # Compile a test program reading LSE128.
> + set src {
> + #include <stdint.h>
> +
> + int main() {
> + __attribute__((aligned(16))) uint64_t mem[2] = { 0x0, 0x1 };
> + uint64_t *ptr = mem;
> + __asm__ volatile ("ldclrp x0, x1, [%0]\n" :: "r"(ptr) : "x0", "x1", "memory");
> + 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 lse128 support not detected"
> + set allow_lse128_tests 0
> + }
> + -re ".*$inferior_exited_re normally.*${gdb_prompt} $" {
> + verbose -log "\n$me: lse128 support detected"
> + set allow_lse128_tests 1
> + }
> + default {
> + warning "\n$me: default case taken"
> + set allow_lse128_tests 0
> + }
> + }
> + gdb_exit
> + remote_file build delete $obj
> +
> + verbose "$me: returning $allow_lse128_tests" 2
> + return $allow_lse128_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.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 2/4] gdb/aarch64: Test record/replay support for CSSC
2026-05-15 3:50 ` Thiago Jung Bauermann
@ 2026-05-26 19:40 ` Guinevere Larsen
0 siblings, 0 replies; 18+ messages in thread
From: Guinevere Larsen @ 2026-05-26 19:40 UTC (permalink / raw)
To: Thiago Jung Bauermann, Ezra.Sitorus; +Cc: gdb-patches, luis.machado.foss
On 5/15/26 12:50 AM, Thiago Jung Bauermann wrote:
> <Ezra.Sitorus@arm.com> writes:
>
>> From: Ezra Sitorus <ezra.sitorus@arm.com>
>>
>> GDB can handle AArch64's CSSC instructions but there were no tests
>> ensuring that and ensuring no regressions would creep in. This commit
>> adds some tests for these instructions. This was tested on
>> aarch64-none-linux-gnu on QEMU with CSSC support.
>> ---
>> gdb/testsuite/gdb.reverse/aarch64-cssc.c | 88 +++++++++++++
>> gdb/testsuite/gdb.reverse/aarch64-cssc.exp | 139 +++++++++++++++++++++
>> gdb/testsuite/lib/gdb.exp | 52 ++++++++
>> 3 files changed, 279 insertions(+)
>> create mode 100644 gdb/testsuite/gdb.reverse/aarch64-cssc.c
>> create mode 100644 gdb/testsuite/gdb.reverse/aarch64-cssc.exp
> Looks good to me, thanks!
>
> Reviewed-by: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
>
> I think Guinevere should approve it though.
>
Ah! I'm happy to change my review tag to an approval tag, then!
Approved-By: Guinevere Larsen <guinevere@redhat.com>
--
Cheers,
Guinevere Larsen
It/she
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 1/4] gdb/aarch64: record/replay support for LRCPC3
2026-05-26 14:30 ` Guinevere Larsen
@ 2026-05-26 23:36 ` Ezra Sitorus
2026-05-27 0:05 ` Thiago Jung Bauermann
0 siblings, 1 reply; 18+ messages in thread
From: Ezra Sitorus @ 2026-05-26 23:36 UTC (permalink / raw)
To: Guinevere Larsen; +Cc: gdb-patches, luis.machado.foss, thiago.bauermann
> 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
Hi! Thanks all for the reviews - I'll address those comments. One question I
have for GDB workflow: do I explicitly need an Approved-By before I can push?
Or in this case am I waiting on a final approval by Luis or Thiago?
Ezra
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 1/4] gdb/aarch64: record/replay support for LRCPC3
2026-05-26 23:36 ` Ezra Sitorus
@ 2026-05-27 0:05 ` Thiago Jung Bauermann
0 siblings, 0 replies; 18+ messages in thread
From: Thiago Jung Bauermann @ 2026-05-27 0:05 UTC (permalink / raw)
To: Ezra Sitorus; +Cc: Guinevere Larsen, gdb-patches, luis.machado.foss
Ezra Sitorus <ezra.sitorus@arm.com> writes:
>> 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
>
> Hi! Thanks all for the reviews - I'll address those comments. One question I
> have for GDB workflow: do I explicitly need an Approved-By before I can push?
Ideally a maintainer will explicitly provide an Approved-By to signal
that the patch can be pushed. A single tag is enough even if there are
other maintainers/reviewers involved in the discussion, unless the tag
is explicitly limited to the tag giver's area of the project.
Sometimes instead of a tag an approval is given in a hopefully
unambiguous sentence in English to the same effect.
The intended meaning of the tags is described in the gdb/MAINTAINERS
file.
> Or in this case am I waiting on a final approval by Luis or Thiago?
For this series, patches 2, 3 and 4 can be committed.
For patch 1, a v3 is needed.
--
Thiago
(he/him)
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2026-05-27 0:06 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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
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
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox