aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndre Vieira <andre.simoesdiasvieira@arm.com>2022-11-15 09:50:39 +0000
committerAndre Vieira <andre.simoesdiasvieira@arm.com>2022-11-15 09:50:39 +0000
commit0431e8ae5bdb854bda5f9005e41c8c4d03f6d74e (patch)
treeb65df33fbe1c4b36a63276d5e48037ac3c25fa78
parent9a4129f5c5a697ad7726687d5932eef90feec53b (diff)
downloadgcc-0431e8ae5bdb854bda5f9005e41c8c4d03f6d74e.zip
gcc-0431e8ae5bdb854bda5f9005e41c8c4d03f6d74e.tar.gz
gcc-0431e8ae5bdb854bda5f9005e41c8c4d03f6d74e.tar.bz2
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.
-rw-r--r--gcc/config/aarch64/aarch64.h4
-rw-r--r--gcc/config/aarch64/atomics.md33
-rw-r--r--gcc/config/aarch64/iterators.md1
-rw-r--r--gcc/doc/invoke.texi6
-rw-r--r--gcc/testsuite/gcc.target/aarch64/ldapr.c34
5 files changed, 74 insertions, 4 deletions
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index bbbb7e4..070466d 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -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) \
diff --git a/gcc/config/aarch64/atomics.md b/gcc/config/aarch64/atomics.md
index bc95f6d..dc5f52e 100644
--- a/gcc/config/aarch64/atomics.md
+++ b/gcc/config/aarch64/atomics.md
@@ -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")
diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
index 718b4c0..7c7fcbb 100644
--- a/gcc/config/aarch64/iterators.md
+++ b/gcc/config/aarch64/iterators.md
@@ -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.
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 55e8a14..9d73394 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -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
diff --git a/gcc/testsuite/gcc.target/aarch64/ldapr.c b/gcc/testsuite/gcc.target/aarch64/ldapr.c
new file mode 100644
index 0000000..21f6464
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/ldapr.c
@@ -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 } } */