public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/vendors/ARM/heads/morello)] Add alternative-base support for __atomic_load, etc.
@ 2022-05-06 14:44 Matthew Malcomson
  0 siblings, 0 replies; only message in thread
From: Matthew Malcomson @ 2022-05-06 14:44 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:3ccc0052728f50bddd5dd81f1548d69e583753a0

commit 3ccc0052728f50bddd5dd81f1548d69e583753a0
Author: Richard Sandiford <richard.sandiford@arm.com>
Date:   Wed Apr 27 10:48:33 2022 +0100

    Add alternative-base support for __atomic_load, etc.
    
    This patch adds alternative-base support for the following
    overloaded atomic functions:
    
      __atomic_load
      __atomic_store
      __atomic_exchange
      __atomic_compare_exchange
    
    sync-builtins.def gave these functions a specific prototype,
    but the prototype had the wrong number of arguments: it started
    with a size argument that the functions don't actually have.
    The patch therefore gives the functions a BT_FN_<RET>_VAR type
    instead, for consistency with the overloaded _n functions.
    
    Otherwise, the only substantial change is to make sure that the first
    pointer argument to the resolved call has the same “flavour” as the
    first pointer argument to the original call.  The second argument to
    __atomic_compare_exchange is always a default-flavour pointer, even
    for the _c version.  (This is also what clang does.)

Diff:
---
 gcc/c-family/c-common.c                            |  10 +-
 gcc/fortran/types.def                              |   1 +
 gcc/sync-builtins.def                              |  10 +-
 .../morello/alt-base-atomic-compare-exchange-4.c   |  59 ++++
 .../aarch64/morello/alt-base-atomic-exchange-4.c   |  63 +++++
 .../aarch64/morello/alt-base-atomic-load-3.c       | 304 +++++++++++++++++++++
 .../aarch64/morello/alt-base-atomic-store-3.c      | 252 +++++++++++++++++
 .../gcc.target/aarch64/morello/mixed-pointers-1.c  |  28 ++
 gcc/tree.c                                         |  11 +
 gcc/tree.h                                         |   1 +
 10 files changed, 728 insertions(+), 11 deletions(-)

diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 588b1ce363a..2175d8cf69f 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -7429,7 +7429,7 @@ resolve_overloaded_atomic_exchange (location_t loc, tree function,
   else
     I_type = intcap_type_node;
 
-  I_type_ptr = build_pointer_type (I_type);
+  I_type_ptr = change_pointer_target_type (TREE_TYPE (p0), I_type);
 
   /* Convert object pointer to required type.  */
   p0 = build1 (VIEW_CONVERT_EXPR, I_type_ptr, p0);
@@ -7515,13 +7515,13 @@ resolve_overloaded_atomic_compare_exchange (location_t loc, tree function,
   else
     I_type = intcap_type_node;
 
-  I_type_ptr = build_pointer_type (I_type);
+  I_type_ptr = change_pointer_target_type (TREE_TYPE (p0), I_type);
 
   /* Convert object pointer to required type.  */
   p0 = build1 (VIEW_CONVERT_EXPR, I_type_ptr, p0);
 
   /* Convert expected pointer to required type.  */
-  p1 = build1 (VIEW_CONVERT_EXPR, I_type_ptr, p1);
+  p1 = build1 (CONVERT_EXPR, build_pointer_type (I_type), p1);
 
   /* Convert desired value to required type, and dereference it.  */
   p2 = build_indirect_ref (loc, p2, RO_UNARY_STAR);
@@ -7591,7 +7591,7 @@ resolve_overloaded_atomic_load (location_t loc, tree function,
   else
     I_type = intcap_type_node;
 
-  I_type_ptr = build_pointer_type (I_type);
+  I_type_ptr = change_pointer_target_type (TREE_TYPE (p0), I_type);
 
   /* Convert object pointer to required type.  */
   p0 = build1 (VIEW_CONVERT_EXPR, I_type_ptr, p0);
@@ -7660,7 +7660,7 @@ resolve_overloaded_atomic_store (location_t loc, tree function,
   else
     I_type = intcap_type_node;
 
-  I_type_ptr = build_pointer_type (I_type);
+  I_type_ptr = change_pointer_target_type (TREE_TYPE (p0), I_type);
 
   /* Convert object pointer to required type.  */
   p0 = build1 (VIEW_CONVERT_EXPR, I_type_ptr, p0);
diff --git a/gcc/fortran/types.def b/gcc/fortran/types.def
index 566cbff2538..d080ddf746b 100644
--- a/gcc/fortran/types.def
+++ b/gcc/fortran/types.def
@@ -308,6 +308,7 @@ DEF_FUNCTION_TYPE_11 (BT_FN_VOID_OMPFN_PTR_OMPCPYFN_LONG_LONG_UINT_LONG_INT_ULL_
 		      BT_ULONGLONG, BT_ULONGLONG, BT_ULONGLONG)
 
 DEF_FUNCTION_TYPE_VAR_0 (BT_FN_VOID_VAR, BT_VOID)
+DEF_FUNCTION_TYPE_VAR_0 (BT_FN_BOOL_VAR, BT_BOOL)
 
 DEF_FUNCTION_TYPE_VAR_1 (BT_FN_VOID_LONG_VAR,
 			 BT_VOID, BT_LONG)
diff --git a/gcc/sync-builtins.def b/gcc/sync-builtins.def
index 2ebc125475c..118ea515b01 100644
--- a/gcc/sync-builtins.def
+++ b/gcc/sync-builtins.def
@@ -293,26 +293,24 @@ DEF_SYNC_BUILTIN (BUILT_IN_ATOMIC_CLEAR, "__atomic_clear", BT_FN_VOID_VPTR_INT,
 
 DEF_SYNC_BUILTIN (BUILT_IN_ATOMIC_EXCHANGE,
 		  "__atomic_exchange",
-		  BT_FN_VOID_SIZE_VPTR_PTR_PTR_INT, ATTR_NOTHROWCALL_LEAF_LIST)
+		  BT_FN_VOID_VAR, ATTR_NOTHROWCALL_LEAF_LIST)
 DEF_SYNC_BUILTIN_RMW_ORDER_ALL_N (BUILT_IN_ATOMIC_EXCHANGE,
 				  "__atomic_exchange", "_n")
 
 DEF_SYNC_BUILTIN (BUILT_IN_ATOMIC_LOAD,
 		  "__atomic_load",
-		  BT_FN_VOID_SIZE_CONST_VPTR_PTR_INT,
-		  ATTR_NOTHROWCALL_LEAF_LIST)
+		  BT_FN_VOID_VAR, ATTR_NOTHROWCALL_LEAF_LIST)
 DEF_SYNC_BUILTIN_LOAD_ORDER_ALL_N (BUILT_IN_ATOMIC_LOAD, "__atomic_load", "_n")
 
 DEF_SYNC_BUILTIN (BUILT_IN_ATOMIC_COMPARE_EXCHANGE,
 		  "__atomic_compare_exchange",
-		  BT_FN_BOOL_SIZE_VPTR_PTR_PTR_INT_INT,
-		  ATTR_NOTHROWCALL_LEAF_LIST)
+		  BT_FN_BOOL_VAR, ATTR_NOTHROWCALL_LEAF_LIST)
 DEF_SYNC_BUILTIN_CMP_XCHG_ORDER_ALL_N (BUILT_IN_ATOMIC_COMPARE_EXCHANGE,
 				       "__atomic_compare_exchange", "_n")
 
 DEF_SYNC_BUILTIN (BUILT_IN_ATOMIC_STORE,
 		  "__atomic_store",
-		  BT_FN_VOID_SIZE_VPTR_PTR_INT, ATTR_NOTHROWCALL_LEAF_LIST)
+		  BT_FN_VOID_VAR, ATTR_NOTHROWCALL_LEAF_LIST)
 DEF_SYNC_BUILTIN_STORE_ORDER_ALL_N (BUILT_IN_ATOMIC_STORE,
 				    "__atomic_store", "_n")
 
diff --git a/gcc/testsuite/gcc.target/aarch64/morello/alt-base-atomic-compare-exchange-4.c b/gcc/testsuite/gcc.target/aarch64/morello/alt-base-atomic-compare-exchange-4.c
new file mode 100644
index 00000000000..4c566d991c6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/morello/alt-base-atomic-compare-exchange-4.c
@@ -0,0 +1,59 @@
+/* { dg-do assemble } */
+/* { dg-additional-options "-foptimize-sibling-calls -save-temps" } */
+/* { dg-skip-if "" { *-*-* } { "-mabi=purecap" "-mfake-capability" } { "" } }  */
+
+#include <stdint.h>
+
+typedef __uint128_t uint128;
+typedef __intcap intcap;
+
+#define TEST_SIZE(TYPE, SIZE)						\
+  TYPE									\
+  test_##TYPE##_relaxed (TYPE *__capability ptr, TYPE *expected,	\
+			 TYPE desired)					\
+  {									\
+    __atomic_compare_exchange (ptr, expected, &desired, 0,		\
+			       __ATOMIC_RELAXED,__ATOMIC_RELAXED);	\
+    return desired;							\
+  }									\
+									\
+  TYPE									\
+  test_##TYPE##_acquire (TYPE *__capability ptr, TYPE *expected,	\
+			 TYPE desired)					\
+  {									\
+    __atomic_compare_exchange (ptr, expected, &desired, 0,		\
+			       __ATOMIC_ACQUIRE, __ATOMIC_RELAXED);	\
+    return desired;							\
+  }									\
+									\
+  TYPE									\
+  test_##TYPE##_release (TYPE *__capability ptr, TYPE *expected,	\
+			 TYPE desired)					\
+  {									\
+    __atomic_compare_exchange (ptr, expected, &desired, 0,		\
+			       __ATOMIC_RELEASE, __ATOMIC_RELAXED);	\
+    return desired;							\
+  }									\
+									\
+  TYPE									\
+  test_##TYPE##_seq_cst (TYPE *__capability ptr, TYPE *expected,	\
+			 TYPE desired)					\
+  {									\
+    __atomic_compare_exchange (ptr, expected, &desired, 0,		\
+			       __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);	\
+    return desired;							\
+  }
+
+TEST_SIZE (uint8_t, 1)
+TEST_SIZE (uint16_t, 2)
+TEST_SIZE (uint32_t, 4)
+TEST_SIZE (uint64_t, 8)
+TEST_SIZE (uint128, 16)
+TEST_SIZE (intcap, capability)
+
+/* { dg-final { scan-assembler-times {\t__atomic_compare_exchange_1_c} 4 } } */
+/* { dg-final { scan-assembler-times {\t__atomic_compare_exchange_2_c} 4 } } */
+/* { dg-final { scan-assembler-times {\t__atomic_compare_exchange_4_c} 4 } } */
+/* { dg-final { scan-assembler-times {\t__atomic_compare_exchange_8_c} 4 } } */
+/* { dg-final { scan-assembler-times {\t__atomic_compare_exchange_16_c} 4 } } */
+/* { dg-final { scan-assembler-times {\t__atomic_compare_exchange_capability_c} 4 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/morello/alt-base-atomic-exchange-4.c b/gcc/testsuite/gcc.target/aarch64/morello/alt-base-atomic-exchange-4.c
new file mode 100644
index 00000000000..f6a1bdac7e4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/morello/alt-base-atomic-exchange-4.c
@@ -0,0 +1,63 @@
+/* { dg-do assemble } */
+/* { dg-additional-options "-foptimize-sibling-calls -save-temps" } */
+/* { dg-skip-if "" { *-*-* } { "-mabi=purecap" "-mfake-capability" } { "" } }  */
+
+#include <stdint.h>
+
+typedef __uint128_t uint128;
+typedef __intcap intcap;
+
+#define TEST_SIZE(TYPE, SIZE)						\
+  TYPE									\
+  test_##TYPE##_relaxed (TYPE *__capability ptr, TYPE val)		\
+  {									\
+    TYPE res;								\
+    __atomic_exchange (ptr, &val, &res, __ATOMIC_RELAXED);		\
+    return res;								\
+  }									\
+									\
+  TYPE									\
+  test_##TYPE##_acquire (TYPE *__capability ptr, TYPE val)		\
+  {									\
+    TYPE res;								\
+    __atomic_exchange (ptr, &val, &res, __ATOMIC_ACQUIRE);		\
+    return res;								\
+  }									\
+									\
+  TYPE									\
+  test_##TYPE##_release (TYPE *__capability ptr, TYPE val)		\
+  {									\
+    TYPE res;								\
+    __atomic_exchange (ptr, &val, &res, __ATOMIC_RELEASE);		\
+    return res;								\
+  }									\
+									\
+  TYPE									\
+  test_##TYPE##_acq_rel (TYPE *__capability ptr, TYPE val)		\
+  {									\
+    TYPE res;								\
+    __atomic_exchange (ptr, &val, &res, __ATOMIC_ACQ_REL);		\
+    return res;								\
+  }									\
+									\
+  TYPE									\
+  test_##TYPE##_seq_cst (TYPE *__capability ptr, TYPE val)		\
+  {									\
+    TYPE res;								\
+    __atomic_exchange (ptr, &val, &res, __ATOMIC_SEQ_CST);		\
+    return res;								\
+  }
+
+TEST_SIZE (uint8_t, 1)
+TEST_SIZE (uint16_t, 2)
+TEST_SIZE (uint32_t, 4)
+TEST_SIZE (uint64_t, 8)
+TEST_SIZE (uint128, 16)
+TEST_SIZE (intcap, capability)
+
+/* { dg-final { scan-assembler-times {\t__atomic_exchange_1_c} 5 } } */
+/* { dg-final { scan-assembler-times {\t__atomic_exchange_2_c} 5 } } */
+/* { dg-final { scan-assembler-times {\t__atomic_exchange_4_c} 5 } } */
+/* { dg-final { scan-assembler-times {\t__atomic_exchange_8_c} 5 } } */
+/* { dg-final { scan-assembler-times {\t__atomic_exchange_16_c} 5 } } */
+/* { dg-final { scan-assembler-times {\t__atomic_exchange_capability_c} 5 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/morello/alt-base-atomic-load-3.c b/gcc/testsuite/gcc.target/aarch64/morello/alt-base-atomic-load-3.c
new file mode 100644
index 00000000000..9d3a4e6867e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/morello/alt-base-atomic-load-3.c
@@ -0,0 +1,304 @@
+/* { dg-do assemble } */
+/* { dg-additional-options "-foptimize-sibling-calls -save-temps" } */
+/* { dg-final { check-function-bodies "**" ""  { {-O[123s]} } } } */
+/* { dg-skip-if "" { *-*-* } { "-mabi=purecap" "-mfake-capability" } { "" } }  */
+
+#include <stdint.h>
+
+typedef __uint128_t uint128;
+typedef __intcap intcap;
+
+#define TEST_SIZE(TYPE, SIZE)						\
+  TYPE									\
+  test_##TYPE (TYPE *__capability ptr)					\
+  {									\
+    TYPE res;								\
+    __atomic_load (ptr, &res, __ATOMIC_ACQUIRE);			\
+    return res;								\
+  }									\
+									\
+  TYPE									\
+  test_##TYPE##_offset (TYPE *__capability ptr)				\
+  {									\
+    TYPE res;								\
+    __atomic_load (ptr + 1, &res, __ATOMIC_ACQUIRE);			\
+    return res;								\
+  }									\
+									\
+  TYPE									\
+  test_##TYPE##_index (TYPE *__capability ptr, int index)		\
+  {									\
+    TYPE res;								\
+    __atomic_load (ptr + index, &res, __ATOMIC_ACQUIRE);		\
+    return res;								\
+  }									\
+									\
+  TYPE									\
+  test_##TYPE##_convert (TYPE *__capability ptr, int index)		\
+  {									\
+    TYPE res;								\
+    __atomic_load ((TYPE *) ptr, &res, __ATOMIC_ACQUIRE);		\
+    return res;								\
+  }									\
+									\
+  TYPE									\
+  test_##TYPE##_relaxed (TYPE *__capability ptr, int index)		\
+  {									\
+    TYPE res;								\
+    __atomic_load (ptr, &res, __ATOMIC_RELAXED);			\
+    return res;								\
+  }									\
+									\
+  TYPE									\
+  test_##TYPE##_consume (TYPE *__capability ptr, int index)		\
+  {									\
+    TYPE res;								\
+    __atomic_load (ptr, &res, __ATOMIC_CONSUME);			\
+    return res;								\
+  }									\
+									\
+  TYPE									\
+  test_##TYPE##_seq_cst (TYPE *__capability ptr, int index)		\
+  {									\
+    TYPE res;								\
+    __atomic_load (ptr, &res, __ATOMIC_SEQ_CST);			\
+    return res;								\
+  }
+
+/*
+** test_uint8_t:
+**	ldarb	w0, \[c0\]
+**	ret
+*/
+
+/*
+** test_uint8_t_offset:
+**	add	(c[0-9]+), c0, #?1
+**	ldarb	w0, \[\1\]
+**	ret
+*/
+
+/*
+** test_uint8_t_index:
+**	add	(c[0-9]+), c0, w1, sxtw
+**	ldarb	w0, \[\1\]
+**	ret
+*/
+
+/*
+** test_uint8_t_convert:
+**	ldarb	w0, \[x0\]
+**	ret
+*/
+
+/*
+** test_uint8_t_relaxed:
+**	ldrb	w0, \[c0\]
+**	ret
+*/
+
+/*
+** test_uint8_t_consume:
+**	ldarb	w0, \[c0\]
+**	ret
+*/
+
+/*
+** test_uint8_t_seq_cst:
+**	ldarb	w0, \[c0\]
+**	ret
+*/
+TEST_SIZE (uint8_t, 1)
+
+/*
+** test_uint16_t:
+**	ldrh	w0, \[c0\]
+**	dmb	ishld
+**	ret
+*/
+
+/*
+** test_uint16_t_offset:
+**	ldrh	w0, \[c0, #?2\]
+**	dmb	ishld
+**	ret
+*/
+
+/* test_uint16_t_index not matched.  */
+
+/*
+** test_uint16_t_convert:
+**	ldarh	w0, \[x0\]
+**	ret
+*/
+
+/*
+** test_uint16_t_relaxed:
+**	ldrh	w0, \[c0\]
+**	ret
+*/
+
+/*
+** test_uint16_t_consume:
+**	ldrh	w0, \[c0\]
+**	dmb	ishld
+**	ret
+*/
+
+/*
+** test_uint16_t_seq_cst:
+**	dmb	ish
+**	ldrh	w0, \[c0\]
+**	dmb	ish
+**	ret
+*/
+TEST_SIZE (uint16_t, 2)
+
+/*
+** test_uint32_t:
+**	ldar	w0, \[c0\]
+**	ret
+*/
+
+/*
+** test_uint32_t_offset:
+**	add	(c[0-9]+), c0, #?4
+**	ldar	w0, \[\1\]
+**	ret
+*/
+
+/*
+** test_uint32_t_index:
+**	add	(c[0-9]+), c0, w1, sxtw #?2
+**	ldar	w0, \[\1\]
+**	ret
+*/
+
+/*
+** test_uint32_t_convert:
+**	ldar	w0, \[x0\]
+**	ret
+*/
+
+/*
+** test_uint32_t_relaxed:
+**	ldr	w0, \[c0\]
+**	ret
+*/
+
+/*
+** test_uint32_t_consume:
+**	ldar	w0, \[c0\]
+**	ret
+*/
+
+/*
+** test_uint32_t_seq_cst:
+**	ldar	w0, \[c0\]
+**	ret
+*/
+TEST_SIZE (uint32_t, 4)
+
+/*
+** test_uint64_t:
+**	ldr	x0, \[c0\]
+**	dmb	ishld
+**	ret
+*/
+
+/*
+** test_uint64_t_offset:
+**	ldr	x0, \[c0, #?8\]
+**	dmb	ishld
+**	ret
+*/
+
+/* test_uint64_t_index not matched.  */
+
+/*
+** test_uint64_t_convert:
+**	ldar	x0, \[x0\]
+**	ret
+*/
+
+/*
+** test_uint64_t_relaxed:
+**	ldr	x0, \[c0\]
+**	ret
+*/
+
+/*
+** test_uint64_t_consume:
+**	ldr	x0, \[c0\]
+**	dmb	ishld
+**	ret
+*/
+
+/*
+** test_uint64_t_seq_cst:
+**	dmb	ish
+**	ldr	x0, \[c0\]
+**	dmb	ish
+**	ret
+*/
+TEST_SIZE (uint64_t, 8)
+
+/*
+** test_uint128:
+**	mov	w1, #?2
+**	b	__atomic_load_16_c
+*/
+
+/*
+** test_uint128_convert:
+**	mov	w1, #?2
+**	b	__atomic_load_16
+*/
+
+/* Others test_uint128_t not matched.  */
+TEST_SIZE (uint128, 16)
+
+/*
+** test_intcap:
+**	ldar	c0, \[c0\]
+**	ret
+*/
+
+/*
+** test_intcap_offset:
+**	add	(c[0-9]+), c0, #?16
+**	ldar	c0, \[\1\]
+**	ret
+*/
+
+/*
+** test_intcap_index:
+**	add	(c[0-9]+), c0, w1, sxtw #?4
+**	ldar	c0, \[\1\]
+**	ret
+*/
+
+/*
+** test_intcap_convert:
+**	ldar	c0, \[x0\]
+**	ret
+*/
+
+/*
+** test_intcap_relaxed:
+**	ldr	c0, \[c0\]
+**	ret
+*/
+
+/*
+** test_intcap_consume:
+**	ldar	c0, \[c0\]
+**	ret
+*/
+
+/*
+** test_intcap_seq_cst:
+**	ldar	c0, \[c0\]
+**	ret
+*/
+TEST_SIZE (intcap, capability)
diff --git a/gcc/testsuite/gcc.target/aarch64/morello/alt-base-atomic-store-3.c b/gcc/testsuite/gcc.target/aarch64/morello/alt-base-atomic-store-3.c
new file mode 100644
index 00000000000..f22ce4c3586
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/morello/alt-base-atomic-store-3.c
@@ -0,0 +1,252 @@
+/* { dg-do assemble } */
+/* { dg-additional-options "-foptimize-sibling-calls -save-temps" } */
+/* { dg-final { check-function-bodies "**" ""  { {-O[123s]} } } } */
+/* { dg-skip-if "" { *-*-* } { "-mabi=purecap" "-mfake-capability" } { "" } }  */
+
+#include <stdint.h>
+
+typedef __uint128_t uint128;
+typedef __intcap intcap;
+
+#define TEST_SIZE(TYPE, SIZE)						\
+  void									\
+  test_##TYPE (TYPE *__capability ptr, TYPE data)			\
+  {									\
+    __atomic_store (ptr, &data, __ATOMIC_RELEASE);			\
+  }									\
+									\
+  TYPE									\
+  test_##TYPE##_offset (TYPE *__capability ptr, TYPE data)		\
+  {									\
+    __atomic_store (ptr + 1, &data, __ATOMIC_RELEASE);			\
+  }									\
+									\
+  TYPE									\
+  test_##TYPE##_index (TYPE *__capability ptr, TYPE data, int index)	\
+  {									\
+    __atomic_store (ptr + index, &data, __ATOMIC_RELEASE);		\
+  }									\
+									\
+  TYPE									\
+  test_##TYPE##_convert (TYPE *__capability ptr, TYPE data, int index)	\
+  {									\
+    __atomic_store ((TYPE *) ptr, &data, __ATOMIC_RELEASE);		\
+  }									\
+									\
+  TYPE									\
+  test_##TYPE##_relaxed (TYPE *__capability ptr, TYPE data, int index)	\
+  {									\
+    __atomic_store (ptr, &data, __ATOMIC_RELAXED);			\
+  }									\
+									\
+  TYPE									\
+  test_##TYPE##_seq_cst (TYPE *__capability ptr, TYPE data, int index)	\
+  {									\
+    __atomic_store (ptr, &data, __ATOMIC_SEQ_CST);			\
+  }
+
+/*
+** test_uint8_t:
+**	...
+**	stlrb	w1, \[c0\]
+**	ret
+*/
+
+/*
+** test_uint8_t_offset:
+**	...
+**	add	(c[0-9]+), c0, #?1
+**	...
+**	stlrb	w1, \[\1\]
+**	ret
+*/
+
+/*
+** test_uint8_t_index:
+**	...
+**	add	(c[0-9]+), c0, w2, sxtw
+**	...
+**	stlrb	w1, \[\1\]
+**	ret
+*/
+
+/*
+** test_uint8_t_convert:
+**	...
+**	stlrb	w1, \[x0\]
+**	ret
+*/
+
+/*
+** test_uint8_t_relaxed:
+**	...
+**	strb	w1, \[c0\]
+**	ret
+*/
+
+/*
+** test_uint8_t_seq_cst:
+**	...
+**	stlrb	w1, \[c0\]
+**	ret
+*/
+TEST_SIZE (uint8_t, 1)
+
+/*
+** test_uint16_t:
+**	...
+**	dmb	ish
+**	...
+**	strh	w1, \[c0\]
+**	ret
+*/
+
+/* test_uint16_t offset and test_uint16_t_index not matched.  */
+
+/*
+** test_uint16_t_convert:
+**	...
+**	stlrh	w1, \[x0\]
+**	ret
+*/
+
+/*
+** test_uint16_t_relaxed:
+**	...
+**	strh	w1, \[c0\]
+**	ret
+*/
+
+/*
+** test_uint16_t_seq_cst:
+**	...
+**	dmb	ish
+**	...
+**	dmb	ish
+**	ret
+*/
+TEST_SIZE (uint16_t, 2)
+
+/*
+** test_uint32_t:
+**	stlr	w1, \[c0\]
+**	ret
+*/
+
+/*
+** test_uint32_t_offset:
+**	add	(c[0-9]+), c0, #?4
+**	stlr	w1, \[\1\]
+**	ret
+*/
+
+/*
+** test_uint32_t_index:
+**	add	(c[0-9]+), c0, w2, sxtw #?2
+**	stlr	w1, \[\1\]
+**	ret
+*/
+
+/*
+** test_uint32_t_convert:
+**	stlr	w1, \[x0\]
+**	ret
+*/
+
+/*
+** test_uint32_t_relaxed:
+**	str	w1, \[c0\]
+**	ret
+*/
+
+/*
+** test_uint32_t_seq_cst:
+**	stlr	w1, \[c0\]
+**	ret
+*/
+TEST_SIZE (uint32_t, 4)
+
+/*
+** test_uint64_t:
+**	dmb	ish
+**	str	x1, \[c0\]
+**	ret
+*/
+
+/* test_uint64_t_offset and test_uint64_t_index not matched.  */
+
+/*
+** test_uint64_t_convert:
+**	stlr	x1, \[x0\]
+**	ret
+*/
+
+/*
+** test_uint64_t_relaxed:
+**	str	x1, \[c0\]
+**	ret
+*/
+
+/*
+** test_uint64_t_seq_cst:
+**	dmb	ish
+**	str	x1, \[c0\]
+**	dmb	ish
+**	ret
+*/
+TEST_SIZE (uint64_t, 8)
+
+/*
+** test_uint128:
+**	mov	w4, #?3
+**	b	__atomic_store_16_c
+*/
+
+/*
+** test_uint128_convert:
+**	...
+**	bl?	__atomic_store_16
+**	...
+*/
+
+/* Others test_uint128_t not matched.  */
+TEST_SIZE (uint128, 16)
+
+/*
+** test_intcap:
+**	stlr	c1, \[c0\]
+**	ret
+*/
+
+/*
+** test_intcap_offset:
+**	add	(c[0-9]+), c0, #?16
+**	stlr	c1, \[\1\]
+**	ret
+*/
+
+/*
+** test_intcap_index:
+**	add	(c[0-9]+), c0, w2, sxtw #?4
+**	stlr	c1, \[\1\]
+**	ret
+*/
+
+/*
+** test_intcap_convert:
+**	stlr	c1, \[x0\]
+**	ret
+*/
+
+/*
+** test_intcap_relaxed:
+**	str	c1, \[c0\]
+**	ret
+*/
+
+/*
+** test_intcap_seq_cst:
+**	stlr	c1, \[c0\]
+**	ret
+*/
+TEST_SIZE (intcap, capability)
diff --git a/gcc/testsuite/gcc.target/aarch64/morello/mixed-pointers-1.c b/gcc/testsuite/gcc.target/aarch64/morello/mixed-pointers-1.c
new file mode 100644
index 00000000000..18e0ca479c2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/morello/mixed-pointers-1.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+
+void
+f1 (int *__capability a, int *__capability b, int *__capability c)
+{
+  __atomic_load (a, b, __ATOMIC_SEQ_CST);
+  __atomic_store (a, b, __ATOMIC_SEQ_CST);
+  __atomic_exchange (a, b, c, __ATOMIC_SEQ_CST);
+  __atomic_compare_exchange (a, b, c, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
+}
+
+void
+f2 (int *__capability a, int *b, int *__capability c)
+{
+  __atomic_load (a, b, __ATOMIC_SEQ_CST);
+  __atomic_store (a, b, __ATOMIC_SEQ_CST);
+  __atomic_exchange (a, b, c, __ATOMIC_SEQ_CST);
+  __atomic_compare_exchange (a, b, c, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
+  __atomic_exchange (a, c, b, __ATOMIC_SEQ_CST);
+  __atomic_compare_exchange (a, c, b, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
+}
+
+void
+f3 (int *__capability a, int *b, int *c)
+{
+  __atomic_exchange (a, c, b, __ATOMIC_SEQ_CST);
+  __atomic_compare_exchange (a, c, b, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
+}
diff --git a/gcc/tree.c b/gcc/tree.c
index c5d2ecb9959..081727c9e4b 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -8104,6 +8104,17 @@ try_building_capability_pointer_type (tree to_type)
   return error_mark_node;
 }
 
+/* Return a pointer like PTR_TYPE but with its target type (i.e. its TREE_TYPE)
+   replaced by TO_TYPE.  */
+
+tree
+change_pointer_target_type (tree ptr_type, tree to_type)
+{
+  tree t = addr_expr_type (addr_expr_code (ptr_type), to_type);
+  return build_type_attribute_qual_variant (t, TYPE_ATTRIBUTES (ptr_type),
+					    TYPE_QUALS (ptr_type));
+}
+
 /* Build REPLACE_ADDRESS_VALUE internal function.  This represents replacing
    the value of a pointer with something else.  It is different to a simple
    assignment since it works with pointers represented by capabilities and not
diff --git a/gcc/tree.h b/gcc/tree.h
index 72013ec0778..61c217ebf86 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -4584,6 +4584,7 @@ extern tree truth_type_for (tree);
 extern tree build_pointer_type_for_mode (tree, machine_mode, bool);
 extern tree build_pointer_type (tree);
 extern tree try_building_capability_pointer_type (tree);
+extern tree change_pointer_target_type (tree, tree);
 extern tree addr_expr_type (tree_code, tree);
 extern tree build_intcap_type_for_mode (machine_mode, int);
 extern tree build_reference_type_for_mode (tree, machine_mode, bool);


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-05-06 14:44 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-06 14:44 [gcc(refs/vendors/ARM/heads/morello)] Add alternative-base support for __atomic_load, etc Matthew Malcomson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).