aarch64: Enable the use of LDAPR for load-acquire semantics

This patch enables the use of LDAPR for load-acquire semantics.

2022-11-15  Andre Vieira  <andre.simoesdiasvieira@arm.com>
	    Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

gcc/ChangeLog:

	* config/aarch64/aarch64.h (AARCH64_ISA_RCPC): New Macro.
	(TARGET_RCPC): New Macro.
	* config/aarch64/atomics.md (atomic_load<mode>): Change into an expand.
	(aarch64_atomic_load<mode>_rcpc): New define_insn for ldapr.
	(aarch64_atomic_load<mode>): Rename of old define_insn for ldar.
	* config/aarch64/iterators.md (UNSPEC_LDAP): New unspec enum value.
	* doc/invoke.texi (rcpc): Ammend documentation to mention the effects
	on code generation.

gcc/testsuite/ChangeLog:

	* gcc.target/aarch64/ldapr.c: New test.
This commit is contained in:
Andre Vieira 2022-11-15 09:50:39 +00:00
parent 9a4129f5c5
commit 0431e8ae5b
5 changed files with 74 additions and 4 deletions

View file

@ -222,6 +222,7 @@ enum class aarch64_feature : unsigned char {
#define AARCH64_ISA_MOPS (aarch64_isa_flags & AARCH64_FL_MOPS)
#define AARCH64_ISA_LS64 (aarch64_isa_flags & AARCH64_FL_LS64)
#define AARCH64_ISA_CSSC (aarch64_isa_flags & AARCH64_FL_CSSC)
#define AARCH64_ISA_RCPC (aarch64_isa_flags & AARCH64_FL_RCPC)
/* Crypto is an optional extension to AdvSIMD. */
#define TARGET_CRYPTO (AARCH64_ISA_CRYPTO)
@ -332,6 +333,9 @@ enum class aarch64_feature : unsigned char {
/* SB instruction is enabled through +sb. */
#define TARGET_SB (AARCH64_ISA_SB)
/* RCPC loads from Armv8.3-a. */
#define TARGET_RCPC (AARCH64_ISA_RCPC)
/* Apply the workaround for Cortex-A53 erratum 835769. */
#define TARGET_FIX_ERR_A53_835769 \
((aarch64_fix_a53_err835769 == 2) \

View file

@ -657,7 +657,38 @@
}
)
(define_insn "atomic_load<mode>"
(define_expand "atomic_load<mode>"
[(match_operand:ALLI 0 "register_operand" "=r")
(match_operand:ALLI 1 "aarch64_sync_memory_operand" "Q")
(match_operand:SI 2 "const_int_operand")]
""
{
/* If TARGET_RCPC and this is an ACQUIRE load, then expand to a pattern
using UNSPECV_LDAP. */
enum memmodel model = memmodel_from_int (INTVAL (operands[2]));
if (TARGET_RCPC
&& (is_mm_acquire (model)
|| is_mm_acq_rel (model)))
emit_insn (gen_aarch64_atomic_load<mode>_rcpc (operands[0], operands[1],
operands[2]));
else
emit_insn (gen_aarch64_atomic_load<mode> (operands[0], operands[1],
operands[2]));
DONE;
}
)
(define_insn "aarch64_atomic_load<mode>_rcpc"
[(set (match_operand:ALLI 0 "register_operand" "=r")
(unspec_volatile:ALLI
[(match_operand:ALLI 1 "aarch64_sync_memory_operand" "Q")
(match_operand:SI 2 "const_int_operand")] ;; model
UNSPECV_LDAP))]
"TARGET_RCPC"
"ldapr<atomic_sfx>\t%<w>0, %1"
)
(define_insn "aarch64_atomic_load<mode>"
[(set (match_operand:ALLI 0 "register_operand" "=r")
(unspec_volatile:ALLI
[(match_operand:ALLI 1 "aarch64_sync_memory_operand" "Q")

View file

@ -988,6 +988,7 @@
UNSPECV_LX ; Represent a load-exclusive.
UNSPECV_SX ; Represent a store-exclusive.
UNSPECV_LDA ; Represent an atomic load or load-acquire.
UNSPECV_LDAP ; Represent an atomic acquire load with RCpc semantics.
UNSPECV_STL ; Represent an atomic store or store-release.
UNSPECV_ATOMIC_CMPSW ; Represent an atomic compare swap.
UNSPECV_ATOMIC_EXCHG ; Represent an atomic exchange.

View file

@ -20147,9 +20147,9 @@ Enable FP16 fmla extension. This also enables FP16 extensions and
floating-point instructions. This option is enabled by default for @option{-march=armv8.4-a}. Use of this option with architectures prior to Armv8.2-A is not supported.
@item rcpc
Enable the RcPc extension. This does not change code generation from GCC,
but is passed on to the assembler, enabling inline asm statements to use
instructions from the RcPc extension.
Enable the RCpc extension. This enables the use of the LDAPR instructions for
load-acquire atomic semantics, and passes it on to the assembler, enabling
inline asm statements to use instructions from the RCpc extension.
@item dotprod
Enable the Dot Product extension. This also enables Advanced SIMD instructions.
@item aes

View file

@ -0,0 +1,34 @@
/* { dg-do compile } */
/* { dg-options "-O1 -std=c99" } */
#include <stdatomic.h>
#pragma GCC target "+rcpc"
atomic_ullong u64;
atomic_llong s64;
atomic_uint u32;
atomic_int s32;
atomic_ushort u16;
atomic_short s16;
atomic_uchar u8;
atomic_schar s8;
#define TEST(size, rettype) \
rettype \
test_##size (void) \
{ \
return atomic_load_explicit (&size, memory_order_acquire); \
} \
TEST(u64, unsigned long long)
TEST(s64, long long)
TEST(u32, unsigned int)
TEST(s32, int)
TEST(u16, unsigned short)
TEST(s16, short)
TEST(u8, unsigned char)
TEST(s8, signed char)
/* { dg-final { scan-assembler-times "ldapr\tx" 2 } } */
/* { dg-final { scan-assembler-times "ldapr\tw" 2 } } */
/* { dg-final { scan-assembler-times "ldaprh\tw" 2 } } */
/* { dg-final { scan-assembler-times "ldaprb\tw" 2 } } */