Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Guinevere Larsen <guinevere@redhat.com>
To: Ezra.Sitorus@arm.com, gdb-patches@sourceware.org
Cc: luis.machado.foss@gmail.com, thiago.bauermann@linaro.org
Subject: Re: [PATCH v3] gdb/aarch64: record/replay support for LRCPC3
Date: Mon, 1 Jun 2026 10:21:37 -0300	[thread overview]
Message-ID: <8d8de19a-4fa0-4f07-aefd-feaf41a7af62@redhat.com> (raw)
In-Reply-To: <20260529230109.4123-1-Ezra.Sitorus@arm.com>

On 5/29/26 8:01 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!

This looks ready to go in from the record-full side. Feel free to add my tag

Approved-By: Guinevere Larsen <guinevere@redhat.com> (record-full)

You should wait for Luis's or Thiago's approval for the aarch64 parts 
before pushing it, though, as I only approved the test parts and ack the 
changes to the recording part

> Changes from v2:
> * Renamed the constant to HWCAP2_LRCPC3.
> * Fixed up the HWCAP bit check. It fails correctly on systems without
>    LRCPC3 support.
> * Cleaned up the test argument lists.
>
> Ezra
>
>   gdb/aarch64-tdep.c                           |  87 ++++++++
>   gdb/testsuite/gdb.reverse/aarch64-lrcpc3.c   | 216 +++++++++++++++++++
>   gdb/testsuite/gdb.reverse/aarch64-lrcpc3.exp | 190 ++++++++++++++++
>   gdb/testsuite/lib/gdb.exp                    |  59 +++++
>   4 files changed, 552 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 673815c2..0cce4072 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..b9e48147
> --- /dev/null
> +++ b/gdb/testsuite/gdb.reverse/aarch64-lrcpc3.exp
> @@ -0,0 +1,190 @@
> +# 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_mem same_reg 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 mem [concat $diff_mem $same_mem]
> +	foreach r $regs {
> +	    set ${r}_initial [capture_command_output "info register $r" ""]
> +	}
> +	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 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 m $mem {
> +	    set ${m}_final [capture_command_output "x/x $m" ""]
> +	}
> +
> +	foreach v [concat $same_reg $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_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_mem same_reg same_mem
> +    test_single_asm $name $diff_reg $diff_mem $same_reg $same_mem
> +}
> diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
> index cd59ada7..07f9c8df 100644
> --- a/gdb/testsuite/lib/gdb.exp
> +++ b/gdb/testsuite/lib/gdb.exp
> @@ -5287,6 +5287,65 @@ 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 HWCAP2_LRCPC3
> +	#define HWCAP2_LRCPC3 (1ULL << 46)
> +	#endif
> +
> +	int main (void) {
> +	    bool lrcpc3_supported = getauxval (AT_HWCAP2) & HWCAP2_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 ".*$inferior_exited_re normally.*${gdb_prompt} $" {
> +	    verbose -log "\n$me: lrcpc3 support detected"
> +	    set allow_lrcpc3_tests 1
> +	}
> +	-re ".*$inferior_exited_re with code 01.*${gdb_prompt} $" {
> +	    verbose -log "\n$me: lrcpc3 support not detected"
> +	    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 the AArch64 CSSC feature.
>   # Return 1 if so, 0 if it does not.  Note this causes a restart of GDB.
>   


-- 
Cheers,
Guinevere Larsen
It/she


  reply	other threads:[~2026-06-01 13:22 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-29 23:01 Ezra.Sitorus
2026-06-01 13:21 ` Guinevere Larsen [this message]
2026-06-01 22:10   ` Thiago Jung Bauermann
2026-06-01 22:40     ` Ezra Sitorus

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=8d8de19a-4fa0-4f07-aefd-feaf41a7af62@redhat.com \
    --to=guinevere@redhat.com \
    --cc=Ezra.Sitorus@arm.com \
    --cc=gdb-patches@sourceware.org \
    --cc=luis.machado.foss@gmail.com \
    --cc=thiago.bauermann@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox