public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/vendors/ARM/heads/morello)] Make overload resolution pick _c functions
@ 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:b8a49ddde04a0305498dd378878d885bbf7e4b4b

commit b8a49ddde04a0305498dd378878d885bbf7e4b4b
Author: Richard Sandiford <richard.sandiford@arm.com>
Date:   Mon Apr 25 17:42:03 2022 +0100

    Make overload resolution pick _c functions
    
    Following on from the previous patch to add _c forms of
    atomic functions, this patch makes the overloaded forms
    choose the _c versions where appropriate.

Diff:
---
 gcc/ada/gcc-interface/utils2.c                     |   6 +-
 gcc/builtins.c                                     |  18 +-
 gcc/builtins.h                                     |   2 +-
 gcc/c-family/c-common.c                            |   6 +-
 gcc/cp/decl2.c                                     |   4 +-
 gcc/fortran/trans-intrinsic.c                      |   9 +-
 gcc/omp-expand.c                                   |  15 +-
 .../morello/alt-base-atomic-compare-exchange-3.c   |  59 +++
 .../aarch64/morello/alt-base-atomic-exchange-3.c   |  53 +++
 .../aarch64/morello/alt-base-atomic-load-2.c       | 290 ++++++++++++
 .../aarch64/morello/alt-base-atomic-operation-3.c  | 497 +++++++++++++++++++++
 .../aarch64/morello/alt-base-atomic-store-2.c      | 252 +++++++++++
 .../aarch64/morello/alt-base-sync-compare-swap-3.c |  88 ++++
 .../aarch64/morello/alt-base-sync-lock-release-2.c |  89 ++++
 .../morello/alt-base-sync-lock-test-and-set-3.c    |  52 +++
 .../aarch64/morello/alt-base-sync-operation-3.c    | 396 ++++++++++++++++
 16 files changed, 1818 insertions(+), 18 deletions(-)

diff --git a/gcc/ada/gcc-interface/utils2.c b/gcc/ada/gcc-interface/utils2.c
index eeb30a14752..dcaf44145cf 100644
--- a/gcc/ada/gcc-interface/utils2.c
+++ b/gcc/ada/gcc-interface/utils2.c
@@ -701,7 +701,8 @@ build_atomic_load (tree src, bool sync)
   if (size == 0)
     return orig_src;
 
-  t = builtin_decl_implicit (builtin_sync_code (BUILT_IN_ATOMIC_LOAD_N, size));
+  t = builtin_decl_implicit (builtin_sync_code (BUILT_IN_ATOMIC_LOAD_N, size,
+						capability_type_p (ptr_type)));
 
   addr = build_unary_op (unqualified_addr_expr (), ptr_type, src);
   val = build_call_expr (t, 2, addr, mem_model);
@@ -735,7 +736,8 @@ build_atomic_store (tree dest, tree src, bool sync)
   if (size == 0)
     return build_binary_op (MODIFY_EXPR, NULL_TREE, orig_dest, src);
 
-  auto fncode = builtin_sync_code (BUILT_IN_ATOMIC_STORE_N, size);
+  auto fncode = builtin_sync_code (BUILT_IN_ATOMIC_STORE_N, size,
+				   capability_type_p (ptr_type));
   t = builtin_decl_implicit (fncode);
   int_type = gnat_type_for_size (BITS_PER_UNIT * size, 1);
 
diff --git a/gcc/builtins.c b/gcc/builtins.c
index f31032bfeb0..aa6307d6e0f 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -6632,13 +6632,16 @@ log2_nbytes_int_mode (int nbytes_log2)
 
 /* BASE_CODE is an overloaded BUILT_IN_*_N function defined in
    sync-builtins.def.  Return the non-overloaded function associated
-   with sync_dsize DSIZE.
+   with DSIZE and CAPABILITY_POINTERS_P, where DSIZE specifies the
+   sync_dsize of the data and CAPABILITY_POINTERS_P specifies whether
+   the first pointer argument is a capability.
 
    The type of the perameter is int rather than sync_dsize because many
    callers can validly pass a plain byte size.  */
 
 built_in_function
-builtin_sync_code (built_in_function base_code, int dsize)
+builtin_sync_code (built_in_function base_code, int dsize,
+		   bool capability_pointers_p)
 {
   gcc_assert (dsize == SYNC_I1
 	      || dsize == SYNC_I2
@@ -6649,7 +6652,13 @@ builtin_sync_code (built_in_function base_code, int dsize)
   /* The capability entry comes after the numerical ones.  */
   if (dsize == SYNC_ICAP)
     dsize = 32;
-  return (built_in_function) ((int) base_code + exact_log2 (dsize) * 2 + 1);
+  int index = exact_log2 (dsize) * 2;
+  if (CAPABILITY_MODE_P (Pmode))
+    gcc_assert (capability_pointers_p);
+  else if (capability_pointers_p)
+    /* Pick the _c form.  */
+    index += 1;
+  return (built_in_function) ((int) base_code + index + 1);
 }
 
 /* BASE_CODE is an overloaded BUILT_IN_*_N function defined in
@@ -7068,7 +7077,8 @@ expand_ifn_atomic_compare_exchange_into_call (gcall *call, machine_mode mode)
   /* At present we only have BUILT_IN_ATOMIC_COMPARE_EXCHANGE_{1,2,4,8,16}.  */
   unsigned int nbytes = GET_MODE_SIZE (mode).to_constant ();
   built_in_function fncode
-    = builtin_sync_code (BUILT_IN_ATOMIC_COMPARE_EXCHANGE_N, nbytes);
+    = builtin_sync_code (BUILT_IN_ATOMIC_COMPARE_EXCHANGE_N, nbytes,
+			 capability_type_p (TREE_TYPE ((*vec)[0])));
   tree fndecl = builtin_decl_explicit (fncode);
   tree fn = build_addr_expr (build_pointer_type (TREE_TYPE (fndecl)), fndecl);
   tree exp = build_call_vec (boolean_type_node, fn, vec);
diff --git a/gcc/builtins.h b/gcc/builtins.h
index 1258d287778..2055549aed1 100644
--- a/gcc/builtins.h
+++ b/gcc/builtins.h
@@ -197,7 +197,7 @@ enum sync_dsize {
   SYNC_I16 = 16,
   SYNC_ICAP = 0xcafe
 };
-extern built_in_function builtin_sync_code (built_in_function, int);
+extern built_in_function builtin_sync_code (built_in_function, int, bool);
 extern sync_dsize builtin_sync_dsize (built_in_function, built_in_function);
 
 #endif /* GCC_BUILTINS_H */
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 7b9680e7524..588b1ce363a 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -6967,6 +6967,7 @@ sync_resolve_function (tree function, built_in_function orig_fcode,
   /* Type the argument points to.  */
   tree type;
   int size;
+  bool capability_p;
 
   argtype = type = TREE_TYPE ((*params)[0]);
 
@@ -6979,6 +6980,7 @@ sync_resolve_function (tree function, built_in_function orig_fcode,
   if (TREE_CODE (type) != POINTER_TYPE)
     goto incompatible;
 
+  capability_p = capability_type_p (type);
   type = TREE_TYPE (type);
   if (!INTEGRAL_TYPE_P (type)
       && !POINTER_TYPE_P (type)
@@ -6992,11 +6994,11 @@ sync_resolve_function (tree function, built_in_function orig_fcode,
     goto incompatible;
 
   if (capability_type_p (type))
-    return builtin_sync_code (orig_fcode, SYNC_ICAP);
+    return builtin_sync_code (orig_fcode, SYNC_ICAP, capability_p);
 
   size = tree_to_uhwi (TYPE_SIZE_UNIT (type));
   if (size == 1 || size == 2 || size == 4 || size == 8 || size == 16)
-    return builtin_sync_code (orig_fcode, size);
+    return builtin_sync_code (orig_fcode, size, capability_p);
 
  incompatible:
   /* Issue the diagnostic only if the argument is valid, otherwise
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 021b1a8ca5b..c1dba94408a 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -3330,7 +3330,9 @@ build_atomic_load_byte (tree src, HOST_WIDE_INT model)
 
   size = tree_to_uhwi (TYPE_SIZE_UNIT (char_type_node));
 
-  t = builtin_decl_implicit (builtin_sync_code (BUILT_IN_ATOMIC_LOAD_N, size));
+  auto fcode = builtin_sync_code (BUILT_IN_ATOMIC_LOAD_N, size,
+				  capability_type_p (ptr_type));
+  t = builtin_decl_implicit (fcode);
 
   addr = build_addr_expr (ptr_type, src);
   val = build_call_expr (t, 2, addr, mem_model);
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index 2cc2b18dd37..1b07bc6a263 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -11360,7 +11360,8 @@ conv_intrinsic_atomic_op (gfc_code *code)
     }
 
   tmp = TREE_TYPE (TREE_TYPE (atom));
-  fn = builtin_sync_code (fn, tree_to_uhwi (TYPE_SIZE_UNIT (tmp)));
+  fn = builtin_sync_code (fn, tree_to_uhwi (TYPE_SIZE_UNIT (tmp)),
+			  capability_type_p (TREE_TYPE (atom)));
   tree itype = TREE_TYPE (TREE_TYPE (atom));
   tmp = builtin_decl_explicit (fn);
 
@@ -11483,7 +11484,8 @@ conv_intrinsic_atomic_ref (gfc_code *code)
 
   tmp = TREE_TYPE (TREE_TYPE (atom));
   fn = builtin_sync_code (BUILT_IN_ATOMIC_LOAD_N,
-			  tree_to_uhwi (TYPE_SIZE_UNIT (tmp)));
+			  tree_to_uhwi (TYPE_SIZE_UNIT (tmp)),
+			  capability_type_p (TREE_TYPE (atom)));
   tmp = builtin_decl_explicit (fn);
   tmp = build_call_expr_loc (input_location, tmp, 2, atom,
 			     build_int_cst (integer_type_node,
@@ -11608,7 +11610,8 @@ conv_intrinsic_atomic_cas (gfc_code *code)
 
   tmp = TREE_TYPE (TREE_TYPE (atom));
   fn = builtin_sync_code (BUILT_IN_ATOMIC_COMPARE_EXCHANGE_N,
-			  tree_to_uhwi (TYPE_SIZE_UNIT (tmp)));
+			  tree_to_uhwi (TYPE_SIZE_UNIT (tmp)),
+			  capability_type_p (TREE_TYPE (atom)));
   tmp = builtin_decl_explicit (fn);
 
   gfc_add_modify (&block, old, comp);
diff --git a/gcc/omp-expand.c b/gcc/omp-expand.c
index b33d55b8d19..755189e9336 100644
--- a/gcc/omp-expand.c
+++ b/gcc/omp-expand.c
@@ -8151,7 +8151,8 @@ expand_omp_atomic_load (basic_block load_bb, tree addr,
      is smaller than word size, then expand_atomic_load assumes that the load
      is atomic.  We could avoid the builtin entirely in this case.  */
 
-  tmpbase = builtin_sync_code (BUILT_IN_ATOMIC_LOAD_N, nbytes);
+  tmpbase = builtin_sync_code (BUILT_IN_ATOMIC_LOAD_N, nbytes,
+			       capability_type_p (TREE_TYPE (addr)));
   decl = builtin_decl_explicit (tmpbase);
   if (decl == NULL_TREE)
     return false;
@@ -8213,7 +8214,8 @@ expand_omp_atomic_store (basic_block load_bb, tree addr,
      is atomic.  We could avoid the builtin entirely in this case.  */
 
   tmpbase = (exchange ? BUILT_IN_ATOMIC_EXCHANGE_N : BUILT_IN_ATOMIC_STORE_N);
-  tmpbase = builtin_sync_code (tmpbase, nbytes);
+  tmpbase = builtin_sync_code (tmpbase, nbytes,
+			       capability_type_p (TREE_TYPE (addr)));
   decl = builtin_decl_explicit (tmpbase);
   if (decl == NULL_TREE)
     return false;
@@ -8353,7 +8355,8 @@ expand_omp_atomic_fetch_op (basic_block load_bb,
   else
     return false;
 
-  tmpbase = builtin_sync_code (need_new ? newbase : oldbase, nbytes);
+  tmpbase = builtin_sync_code (need_new ? newbase : oldbase, nbytes,
+			       capability_type_p (TREE_TYPE (addr)));
   decl = builtin_decl_explicit (tmpbase);
   if (decl == NULL_TREE)
     return false;
@@ -8430,7 +8433,8 @@ expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb,
 
   /* ??? We need a non-pointer interface to __atomic_compare_exchange in
      order to use the RELAXED memory model effectively.  */
-  fncode = builtin_sync_code (BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_N, nbytes);
+  fncode = builtin_sync_code (BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_N, nbytes,
+			      capability_type_p (TREE_TYPE (addr)));
   cmpxchg = builtin_decl_explicit (fncode);
   if (cmpxchg == NULL_TREE)
     return false;
@@ -8472,7 +8476,8 @@ expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb,
       loadedi = loaded_val;
     }
 
-  fncode = builtin_sync_code (BUILT_IN_ATOMIC_LOAD_N, nbytes);
+  fncode = builtin_sync_code (BUILT_IN_ATOMIC_LOAD_N, nbytes,
+			      capability_type_p (TREE_TYPE (addr)));
   tree loaddecl = builtin_decl_explicit (fncode);
   if (loaddecl)
     initial
diff --git a/gcc/testsuite/gcc.target/aarch64/morello/alt-base-atomic-compare-exchange-3.c b/gcc/testsuite/gcc.target/aarch64/morello/alt-base-atomic-compare-exchange-3.c
new file mode 100644
index 00000000000..1f6e527c3f8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/morello/alt-base-atomic-compare-exchange-3.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)					\
+  {									\
+    return __atomic_compare_exchange_n (ptr, expected, desired,		\
+					0, __ATOMIC_RELAXED,		\
+					__ATOMIC_RELAXED);		\
+  }									\
+									\
+  TYPE									\
+  test_##TYPE##_acquire (TYPE *__capability ptr, TYPE *expected,	\
+			 TYPE desired)					\
+  {									\
+    return __atomic_compare_exchange_n (ptr, expected, desired,		\
+					0, __ATOMIC_ACQUIRE,		\
+					__ATOMIC_RELAXED);		\
+  }									\
+									\
+  TYPE									\
+  test_##TYPE##_release (TYPE *__capability ptr, TYPE *expected,	\
+			 TYPE desired)					\
+  {									\
+    return __atomic_compare_exchange_n (ptr, expected, desired,		\
+					0, __ATOMIC_RELEASE,		\
+					__ATOMIC_RELAXED);		\
+  }									\
+									\
+  TYPE									\
+  test_##TYPE##_seq_cst (TYPE *__capability ptr, TYPE *expected,	\
+			 TYPE desired)					\
+  {									\
+    return __atomic_compare_exchange_n (ptr, expected, desired,		\
+					0, __ATOMIC_SEQ_CST,		\
+					__ATOMIC_SEQ_CST);		\
+  }
+
+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-3.c b/gcc/testsuite/gcc.target/aarch64/morello/alt-base-atomic-exchange-3.c
new file mode 100644
index 00000000000..c47b0c508c8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/morello/alt-base-atomic-exchange-3.c
@@ -0,0 +1,53 @@
+/* { 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)	\
+  {								\
+    return __atomic_exchange_n (ptr, val, __ATOMIC_RELAXED);	\
+  }								\
+								\
+  TYPE								\
+  test_##TYPE##_acquire (TYPE *__capability ptr, TYPE val)	\
+  {								\
+    return __atomic_exchange_n (ptr, val, __ATOMIC_ACQUIRE);	\
+  }								\
+								\
+  TYPE								\
+  test_##TYPE##_release (TYPE *__capability ptr, TYPE val)	\
+  {								\
+    return __atomic_exchange_n (ptr, val, __ATOMIC_RELEASE);	\
+  }								\
+								\
+  TYPE								\
+  test_##TYPE##_acq_rel (TYPE *__capability ptr, TYPE val)	\
+  {								\
+    return __atomic_exchange_n (ptr, val, __ATOMIC_ACQ_REL);	\
+  }								\
+								\
+  TYPE								\
+  test_##TYPE##_seq_cst (TYPE *__capability ptr, TYPE val)	\
+  {								\
+    return __atomic_exchange_n (ptr, val, __ATOMIC_SEQ_CST);	\
+  }
+
+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-2.c b/gcc/testsuite/gcc.target/aarch64/morello/alt-base-atomic-load-2.c
new file mode 100644
index 00000000000..6dc100c6233
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/morello/alt-base-atomic-load-2.c
@@ -0,0 +1,290 @@
+/* { 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)				\
+  {								\
+    return __atomic_load_n (ptr, __ATOMIC_ACQUIRE);		\
+  }								\
+								\
+  TYPE								\
+  test_##TYPE##_offset (TYPE *__capability ptr)			\
+  {								\
+    return __atomic_load_n (ptr + 1, __ATOMIC_ACQUIRE);		\
+  }								\
+								\
+  TYPE								\
+  test_##TYPE##_index (TYPE *__capability ptr, int index)	\
+  {								\
+    return __atomic_load_n (ptr + index, __ATOMIC_ACQUIRE);	\
+  }								\
+								\
+  TYPE								\
+  test_##TYPE##_convert (TYPE *__capability ptr, int index)	\
+  {								\
+    return __atomic_load_n ((TYPE *) ptr, __ATOMIC_ACQUIRE);	\
+  }								\
+								\
+  TYPE								\
+  test_##TYPE##_relaxed (TYPE *__capability ptr, int index)	\
+  {								\
+    return __atomic_load_n (ptr, __ATOMIC_RELAXED);		\
+  }								\
+								\
+  TYPE								\
+  test_##TYPE##_consume (TYPE *__capability ptr, int index)	\
+  {								\
+    return __atomic_load_n (ptr, __ATOMIC_CONSUME);		\
+  }								\
+								\
+  TYPE								\
+  test_##TYPE##_seq_cst (TYPE *__capability ptr, int index)	\
+  {								\
+    return __atomic_load_n (ptr, __ATOMIC_SEQ_CST);		\
+  }
+
+/*
+** 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-operation-3.c b/gcc/testsuite/gcc.target/aarch64/morello/alt-base-atomic-operation-3.c
new file mode 100644
index 00000000000..9b3a13e36bf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/morello/alt-base-atomic-operation-3.c
@@ -0,0 +1,497 @@
+/* { 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_OPERATION(TYPE, SIZE, OPERATION)				\
+  TYPE									\
+  test_##TYPE##_fetch_##OPERATION (TYPE *__capability ptr, TYPE val)	\
+  {									\
+    return __atomic_fetch_##OPERATION (ptr, val, __ATOMIC_RELAXED);	\
+  }									\
+									\
+  TYPE									\
+  test_##TYPE##_##OPERATION##_fetch (TYPE *__capability ptr, TYPE val)	\
+  {									\
+    return __atomic_##OPERATION##_fetch (ptr, val, __ATOMIC_RELAXED);	\
+  }
+
+#define TEST_SIZE(TYPE, SIZE)				\
+  TEST_OPERATION (TYPE, SIZE, add)			\
+  TEST_OPERATION (TYPE, SIZE, sub)			\
+  TEST_OPERATION (TYPE, SIZE, and)			\
+  TEST_OPERATION (TYPE, SIZE, nand)			\
+  TEST_OPERATION (TYPE, SIZE, or)			\
+  TEST_OPERATION (TYPE, SIZE, xor)
+
+/*
+** test_uint8_t_fetch_add:
+**	mov	w2, #?0
+**	b	__atomic_fetch_add_1_c
+*/
+
+/*
+** test_uint8_t_fetch_sub:
+**	mov	w2, #?0
+**	b	__atomic_fetch_sub_1_c
+*/
+
+/*
+** test_uint8_t_fetch_and:
+**	mov	w2, #?0
+**	b	__atomic_fetch_and_1_c
+*/
+
+/*
+** test_uint8_t_fetch_nand:
+**	mov	w2, #?0
+**	b	__atomic_fetch_nand_1_c
+*/
+
+/*
+** test_uint8_t_fetch_or:
+**	mov	w2, #?0
+**	b	__atomic_fetch_or_1_c
+*/
+
+/*
+** test_uint8_t_fetch_xor:
+**	mov	w2, #?0
+**	b	__atomic_fetch_xor_1_c
+*/
+
+/*
+** test_uint8_t_add_fetch:
+**	...
+**	bl	__atomic_fetch_add_1_c
+**	...
+**	add	w0, (w[0-9]+, w0|w0, w[0-9]+)
+**	...
+*/
+
+/*
+** test_uint8_t_sub_fetch:
+**	...
+**	bl	__atomic_fetch_sub_1_c
+**	...
+**	sub	w0, (w[0-9]+, w0|w0, w[0-9]+)
+**	...
+*/
+
+/*
+** test_uint8_t_and_fetch:
+**	...
+**	bl	__atomic_fetch_and_1_c
+**	...
+**	and	w0, (w[0-9]+, w0|w0, w[0-9]+)
+**	...
+*/
+
+/*
+** test_uint8_t_nand_fetch:
+**	...
+**	bl	__atomic_fetch_nand_1_c
+**	...
+**	and	(w[0-9]+), (w[0-9]+, w0|w0, w[0-9]+)
+**	mvn	w0, \1
+**	...
+*/
+
+/*
+** test_uint8_t_or_fetch:
+**	...
+**	bl	__atomic_fetch_or_1_c
+**	...
+**	orr	w0, (w[0-9]+, w0|w0, w[0-9]+)
+**	...
+*/
+
+/*
+** test_uint8_t_xor_fetch:
+**	...
+**	bl	__atomic_fetch_xor_1_c
+**	...
+**	eor	w0, (w[0-9]+, w0|w0, w[0-9]+)
+**	...
+*/
+TEST_SIZE (uint8_t, 1)
+
+/*
+** test_uint16_t_fetch_add:
+**	mov	w2, #?0
+**	b	__atomic_fetch_add_2_c
+*/
+
+/*
+** test_uint16_t_fetch_sub:
+**	mov	w2, #?0
+**	b	__atomic_fetch_sub_2_c
+*/
+
+/*
+** test_uint16_t_fetch_and:
+**	mov	w2, #?0
+**	b	__atomic_fetch_and_2_c
+*/
+
+/*
+** test_uint16_t_fetch_nand:
+**	mov	w2, #?0
+**	b	__atomic_fetch_nand_2_c
+*/
+
+/*
+** test_uint16_t_fetch_or:
+**	mov	w2, #?0
+**	b	__atomic_fetch_or_2_c
+*/
+
+/*
+** test_uint16_t_fetch_xor:
+**	mov	w2, #?0
+**	b	__atomic_fetch_xor_2_c
+*/
+
+/*
+** test_uint16_t_add_fetch:
+**	...
+**	bl	__atomic_fetch_add_2_c
+**	...
+**	add	w0, (w[0-9]+, w0|w0, w[0-9]+)
+**	...
+*/
+
+/*
+** test_uint16_t_sub_fetch:
+**	...
+**	bl	__atomic_fetch_sub_2_c
+**	...
+**	sub	w0, (w[0-9]+, w0|w0, w[0-9]+)
+**	...
+*/
+
+/*
+** test_uint16_t_and_fetch:
+**	...
+**	bl	__atomic_fetch_and_2_c
+**	...
+**	and	w0, (w[0-9]+, w0|w0, w[0-9]+)
+**	...
+*/
+
+/*
+** test_uint16_t_nand_fetch:
+**	...
+**	bl	__atomic_fetch_nand_2_c
+**	...
+**	and	(w[0-9]+), (w[0-9]+, w0|w0, w[0-9]+)
+**	mvn	w0, \1
+**	...
+*/
+
+/*
+** test_uint16_t_or_fetch:
+**	...
+**	bl	__atomic_fetch_or_2_c
+**	...
+**	orr	w0, (w[0-9]+, w0|w0, w[0-9]+)
+**	...
+*/
+
+/*
+** test_uint16_t_xor_fetch:
+**	...
+**	bl	__atomic_fetch_xor_2_c
+**	...
+**	eor	w0, (w[0-9]+, w0|w0, w[0-9]+)
+**	...
+*/
+TEST_SIZE (uint16_t, 2)
+
+/*
+** test_uint32_t_fetch_add:
+**	mov	w2, #?0
+**	b	__atomic_fetch_add_4_c
+*/
+
+/*
+** test_uint32_t_fetch_sub:
+**	mov	w2, #?0
+**	b	__atomic_fetch_sub_4_c
+*/
+
+/*
+** test_uint32_t_fetch_and:
+**	mov	w2, #?0
+**	b	__atomic_fetch_and_4_c
+*/
+
+/*
+** test_uint32_t_fetch_nand:
+**	mov	w2, #?0
+**	b	__atomic_fetch_nand_4_c
+*/
+
+/*
+** test_uint32_t_fetch_or:
+**	mov	w2, #?0
+**	b	__atomic_fetch_or_4_c
+*/
+
+/*
+** test_uint32_t_fetch_xor:
+**	mov	w2, #?0
+**	b	__atomic_fetch_xor_4_c
+*/
+
+/*
+** test_uint32_t_add_fetch:
+**	...
+**	bl	__atomic_fetch_add_4_c
+**	...
+**	add	w0, (w[0-9]+, w0|w0, w[0-9]+)
+**	...
+*/
+
+/*
+** test_uint32_t_sub_fetch:
+**	...
+**	bl	__atomic_fetch_sub_4_c
+**	...
+**	sub	w0, (w[0-9]+, w0|w0, w[0-9]+)
+**	...
+*/
+
+/*
+** test_uint32_t_and_fetch:
+**	...
+**	bl	__atomic_fetch_and_4_c
+**	...
+**	and	w0, (w[0-9]+, w0|w0, w[0-9]+)
+**	...
+*/
+
+/*
+** test_uint32_t_nand_fetch:
+**	...
+**	bl	__atomic_fetch_nand_4_c
+**	...
+**	and	(w[0-9]+), (w[0-9]+, w0|w0, w[0-9]+)
+**	mvn	w0, \1
+**	...
+*/
+
+/*
+** test_uint32_t_or_fetch:
+**	...
+**	bl	__atomic_fetch_or_4_c
+**	...
+**	orr	w0, (w[0-9]+, w0|w0, w[0-9]+)
+**	...
+*/
+
+/*
+** test_uint32_t_xor_fetch:
+**	...
+**	bl	__atomic_fetch_xor_4_c
+**	...
+**	eor	w0, (w[0-9]+, w0|w0, w[0-9]+)
+**	...
+*/
+TEST_SIZE (uint32_t, 4)
+
+/*
+** test_uint64_t_fetch_add:
+**	mov	w2, #?0
+**	b	__atomic_fetch_add_8_c
+*/
+
+/*
+** test_uint64_t_fetch_sub:
+**	mov	w2, #?0
+**	b	__atomic_fetch_sub_8_c
+*/
+
+/*
+** test_uint64_t_fetch_and:
+**	mov	w2, #?0
+**	b	__atomic_fetch_and_8_c
+*/
+
+/*
+** test_uint64_t_fetch_nand:
+**	mov	w2, #?0
+**	b	__atomic_fetch_nand_8_c
+*/
+
+/*
+** test_uint64_t_fetch_or:
+**	mov	w2, #?0
+**	b	__atomic_fetch_or_8_c
+*/
+
+/*
+** test_uint64_t_fetch_xor:
+**	mov	w2, #?0
+**	b	__atomic_fetch_xor_8_c
+*/
+
+/*
+** test_uint64_t_add_fetch:
+**	...
+**	bl	__atomic_fetch_add_8_c
+**	...
+**	add	x0, (x[0-9]+, x0|x0, x[0-9]+)
+**	...
+*/
+
+/*
+** test_uint64_t_sub_fetch:
+**	...
+**	bl	__atomic_fetch_sub_8_c
+**	...
+**	sub	x0, (x[0-9]+, x0|x0, x[0-9]+)
+**	...
+*/
+
+/*
+** test_uint64_t_and_fetch:
+**	...
+**	bl	__atomic_fetch_and_8_c
+**	...
+**	and	x0, (x[0-9]+, x0|x0, x[0-9]+)
+**	...
+*/
+
+/*
+** test_uint64_t_nand_fetch:
+**	...
+**	bl	__atomic_fetch_nand_8_c
+**	...
+**	and	(x[0-9]+), (x[0-9]+, x0|x0, x[0-9]+)
+**	mvn	x0, \1
+**	...
+*/
+
+/*
+** test_uint64_t_or_fetch:
+**	...
+**	bl	__atomic_fetch_or_8_c
+**	...
+**	orr	x0, (x[0-9]+, x0|x0, x[0-9]+)
+**	...
+*/
+
+/*
+** test_uint64_t_xor_fetch:
+**	...
+**	bl	__atomic_fetch_xor_8_c
+**	...
+**	eor	x0, (x[0-9]+, x0|x0, x[0-9]+)
+**	...
+*/
+TEST_SIZE (uint64_t, 8)
+
+TEST_SIZE (uint128, 16)
+
+/*
+** test_intcap_fetch_add:
+**	mov	w2, #?0
+**	b	__atomic_fetch_add_capability_c
+*/
+
+/*
+** test_intcap_fetch_sub:
+**	mov	w2, #?0
+**	b	__atomic_fetch_sub_capability_c
+*/
+
+/*
+** test_intcap_fetch_and:
+**	mov	w2, #?0
+**	b	__atomic_fetch_and_capability_c
+*/
+
+/*
+** test_intcap_fetch_nand:
+**	mov	w2, #?0
+**	b	__atomic_fetch_nand_capability_c
+*/
+
+/*
+** test_intcap_fetch_or:
+**	mov	w2, #?0
+**	b	__atomic_fetch_or_capability_c
+*/
+
+/*
+** test_intcap_fetch_xor:
+**	mov	w2, #?0
+**	b	__atomic_fetch_xor_capability_c
+*/
+
+/*
+** test_intcap_add_fetch:
+**	...
+**	bl	__atomic_fetch_add_capability_c
+**	...
+**	add	c0, c0, x[0-9]+
+**	...
+*/
+
+/*
+** test_intcap_sub_fetch:
+**	...
+**	bl	__atomic_fetch_sub_capability_c
+**	...
+**	sub	(x[0-9]+), (x[0-9]+, x0|x0, x[0-9]+)
+**	scvalue	c0, c0, \1
+**	...
+*/
+
+/*
+** test_intcap_and_fetch:
+**	...
+**	bl	__atomic_fetch_and_capability_c
+**	...
+**	and	(x[0-9]+), (x[0-9]+, x0|x0, x[0-9]+)
+**	scvalue	c0, c0, \1
+**	...
+*/
+
+/*
+** test_intcap_nand_fetch:
+**	...
+**	bl	__atomic_fetch_nand_capability_c
+**	...
+**	and	(x[0-9]+), (x[0-9]+, x0|x0, x[0-9]+)
+**	mvn	(x[0-9]+), \1
+**	scvalue	c0, c0, \3
+**	...
+*/
+
+/*
+** test_intcap_or_fetch:
+**	...
+**	bl	__atomic_fetch_or_capability_c
+**	...
+**	orr	(x[0-9]+), (x[0-9]+, x0|x0, x[0-9]+)
+**	scvalue	c0, c0, \1
+**	...
+*/
+
+/*
+** test_intcap_xor_fetch:
+**	...
+**	bl	__atomic_fetch_xor_capability_c
+**	...
+**	eor	(x[0-9]+), (x[0-9]+, x0|x0, x[0-9]+)
+**	scvalue	c0, c0, \1
+**	...
+*/
+TEST_SIZE (intcap, capability)
diff --git a/gcc/testsuite/gcc.target/aarch64/morello/alt-base-atomic-store-2.c b/gcc/testsuite/gcc.target/aarch64/morello/alt-base-atomic-store-2.c
new file mode 100644
index 00000000000..b0ef9004e39
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/morello/alt-base-atomic-store-2.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_n (ptr, data, __ATOMIC_RELEASE);			\
+  }									\
+									\
+  TYPE									\
+  test_##TYPE##_offset (TYPE *__capability ptr, TYPE data)		\
+  {									\
+    __atomic_store_n (ptr + 1, data, __ATOMIC_RELEASE);			\
+  }									\
+									\
+  TYPE									\
+  test_##TYPE##_index (TYPE *__capability ptr, TYPE data, int index)	\
+  {									\
+    __atomic_store_n (ptr + index, data, __ATOMIC_RELEASE);		\
+  }									\
+									\
+  TYPE									\
+  test_##TYPE##_convert (TYPE *__capability ptr, TYPE data, int index)	\
+  {									\
+    __atomic_store_##SIZE ((TYPE *) ptr, data, __ATOMIC_RELEASE);	\
+  }									\
+									\
+  TYPE									\
+  test_##TYPE##_relaxed (TYPE *__capability ptr, TYPE data, int index)	\
+  {									\
+    __atomic_store_n (ptr, data, __ATOMIC_RELAXED);			\
+  }									\
+									\
+  TYPE									\
+  test_##TYPE##_seq_cst (TYPE *__capability ptr, TYPE data, int index)	\
+  {									\
+    __atomic_store_n (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/alt-base-sync-compare-swap-3.c b/gcc/testsuite/gcc.target/aarch64/morello/alt-base-sync-compare-swap-3.c
new file mode 100644
index 00000000000..7ad17ee4dae
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/morello/alt-base-sync-compare-swap-3.c
@@ -0,0 +1,88 @@
+/* { 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)						\
+  _Bool									\
+  bool_##TYPE (TYPE *__capability ptr, TYPE oldval, TYPE newval) 	\
+  {									\
+    return __sync_bool_compare_and_swap (ptr, oldval, newval);		\
+  }									\
+									\
+  TYPE									\
+  val_##TYPE (TYPE *__capability ptr, TYPE oldval, TYPE newval)		\
+  {									\
+    return __sync_val_compare_and_swap (ptr, oldval, newval);		\
+  }
+
+/*
+** bool_uint8_t:
+**	b	__sync_bool_compare_and_swap_1_c
+*/
+
+/*
+** val_uint8_t:
+**	b	__sync_val_compare_and_swap_1_c
+*/
+TEST_SIZE (uint8_t, 1)
+
+/*
+** bool_uint16_t:
+**	b	__sync_bool_compare_and_swap_2_c
+*/
+
+/*
+** val_uint16_t:
+**	b	__sync_val_compare_and_swap_2_c
+*/
+TEST_SIZE (uint16_t, 2)
+
+/*
+** bool_uint32_t:
+**	b	__sync_bool_compare_and_swap_4_c
+*/
+
+/*
+** val_uint32_t:
+**	b	__sync_val_compare_and_swap_4_c
+*/
+TEST_SIZE (uint32_t, 4)
+
+/*
+** bool_uint64_t:
+**	b	__sync_bool_compare_and_swap_8_c
+*/
+
+/*
+** val_uint64_t:
+**	b	__sync_val_compare_and_swap_8_c
+*/
+TEST_SIZE (uint64_t, 8)
+
+/*
+** bool_uint128:
+**	b	__sync_bool_compare_and_swap_16_c
+*/
+
+/*
+** val_uint128:
+**	b	__sync_val_compare_and_swap_16_c
+*/
+TEST_SIZE (uint128, 16)
+
+/*
+** bool_intcap:
+**	b	__sync_bool_compare_and_swap_capability_c
+*/
+
+/*
+** val_intcap:
+**	b	__sync_val_compare_and_swap_capability_c
+*/
+TEST_SIZE (intcap, capability)
diff --git a/gcc/testsuite/gcc.target/aarch64/morello/alt-base-sync-lock-release-2.c b/gcc/testsuite/gcc.target/aarch64/morello/alt-base-sync-lock-release-2.c
new file mode 100644
index 00000000000..329b06b8b63
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/morello/alt-base-sync-lock-release-2.c
@@ -0,0 +1,89 @@
+/* { 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;
+
+#define TEST_SIZE(TYPE, SIZE)				\
+  void							\
+  test_##TYPE (TYPE *__capability ptr)			\
+  {							\
+    __sync_lock_release (ptr);				\
+  }							\
+							\
+  TYPE							\
+  test_##TYPE##_convert (TYPE *__capability ptr)	\
+  {							\
+    __sync_lock_release ((TYPE *) ptr);			\
+  }
+
+/*
+** test_uint8_t:
+**	stlrb	wzr, \[c0\]
+**	ret
+*/
+
+/*
+** test_uint8_t_convert:
+**	stlrb	wzr, \[x0\]
+**	ret
+*/
+TEST_SIZE (uint8_t, 1)
+
+/*
+** test_uint16_t:
+**	dmb	ish
+**	strh	wzr, \[c0\]
+**	ret
+*/
+
+/*
+** test_uint16_t_convert:
+**	stlrh	wzr, \[x0\]
+**	ret
+*/
+
+TEST_SIZE (uint16_t, 2)
+
+/*
+** test_uint32_t:
+**	stlr	wzr, \[c0\]
+**	ret
+*/
+
+/*
+** test_uint32_t_convert:
+**	stlr	wzr, \[x0\]
+**	ret
+*/
+TEST_SIZE (uint32_t, 4)
+
+/*
+** test_uint64_t:
+**	dmb	ish
+**	str	xzr, \[c0\]
+**	ret
+*/
+
+/*
+** test_uint64_t_convert:
+**	stlr	xzr, \[x0\]
+**	ret
+*/
+TEST_SIZE (uint64_t, 8)
+
+/*
+** test_uint128:
+**	stlr	czr, \[c0\]
+**	ret
+*/
+
+/*
+** test_uint128_convert:
+**	stlr	czr, \[x0\]
+**	ret
+*/
+TEST_SIZE (uint128, 16)
diff --git a/gcc/testsuite/gcc.target/aarch64/morello/alt-base-sync-lock-test-and-set-3.c b/gcc/testsuite/gcc.target/aarch64/morello/alt-base-sync-lock-test-and-set-3.c
new file mode 100644
index 00000000000..574116a1d0d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/morello/alt-base-sync-lock-test-and-set-3.c
@@ -0,0 +1,52 @@
+/* { 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 val)	\
+  {							\
+    return __sync_lock_test_and_set (ptr, val);		\
+  }
+
+/*
+** test_uint8_t:
+**	b	__sync_lock_test_and_set_1_c
+*/
+TEST_SIZE (uint8_t, 1)
+
+/*
+** test_uint16_t:
+**	b	__sync_lock_test_and_set_2_c
+*/
+TEST_SIZE (uint16_t, 2)
+
+/*
+** test_uint32_t:
+**	b	__sync_lock_test_and_set_4_c
+*/
+TEST_SIZE (uint32_t, 4)
+
+/*
+** test_uint64_t:
+**	b	__sync_lock_test_and_set_8_c
+*/
+TEST_SIZE (uint64_t, 8)
+
+/*
+** test_uint128:
+**	b	__sync_lock_test_and_set_16_c
+*/
+TEST_SIZE (uint128, 16)
+
+/*
+** test_intcap:
+**	b	__sync_lock_test_and_set_capability_c
+*/
+TEST_SIZE (intcap, capability)
diff --git a/gcc/testsuite/gcc.target/aarch64/morello/alt-base-sync-operation-3.c b/gcc/testsuite/gcc.target/aarch64/morello/alt-base-sync-operation-3.c
new file mode 100644
index 00000000000..34105142b51
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/morello/alt-base-sync-operation-3.c
@@ -0,0 +1,396 @@
+/* { 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_OPERATION(TYPE, SIZE, OPERATION)				\
+  TYPE									\
+  test_##TYPE##_fetch_and_##OPERATION (TYPE *__capability ptr, TYPE val) \
+  {									\
+    return __sync_fetch_and_##OPERATION (ptr, val);			\
+  }									\
+									\
+  TYPE									\
+  test_##TYPE##_##OPERATION##_and_fetch (TYPE *__capability ptr, TYPE val) \
+  {									\
+    return __sync_##OPERATION##_and_fetch (ptr, val);			\
+  }
+
+#define TEST_SIZE(TYPE, SIZE)				\
+  TEST_OPERATION (TYPE, SIZE, add)			\
+  TEST_OPERATION (TYPE, SIZE, sub)			\
+  TEST_OPERATION (TYPE, SIZE, and)			\
+  TEST_OPERATION (TYPE, SIZE, nand)			\
+  TEST_OPERATION (TYPE, SIZE, or)			\
+  TEST_OPERATION (TYPE, SIZE, xor)
+
+/*
+** test_uint8_t_fetch_and_add:
+**	b	__sync_fetch_and_add_1_c
+*/
+
+/*
+** test_uint8_t_fetch_and_sub:
+**	b	__sync_fetch_and_sub_1_c
+*/
+
+/*
+** test_uint8_t_fetch_and_and:
+**	b	__sync_fetch_and_and_1_c
+*/
+
+/*
+** test_uint8_t_fetch_and_nand:
+**	b	__sync_fetch_and_nand_1_c
+*/
+
+/*
+** test_uint8_t_fetch_and_or:
+**	b	__sync_fetch_and_or_1_c
+*/
+
+/*
+** test_uint8_t_fetch_and_xor:
+**	b	__sync_fetch_and_xor_1_c
+*/
+
+/*
+** test_uint8_t_add_and_fetch:
+**	b	__sync_add_and_fetch_1_c
+*/
+
+/*
+** test_uint8_t_sub_and_fetch:
+**	b	__sync_sub_and_fetch_1_c
+*/
+
+/*
+** test_uint8_t_and_and_fetch:
+**	b	__sync_and_and_fetch_1_c
+*/
+
+/*
+** test_uint8_t_nand_and_fetch:
+**	b	__sync_nand_and_fetch_1_c
+*/
+
+/*
+** test_uint8_t_or_and_fetch:
+**	b	__sync_or_and_fetch_1_c
+*/
+
+/*
+** test_uint8_t_xor_and_fetch:
+**	b	__sync_xor_and_fetch_1_c
+*/
+TEST_SIZE (uint8_t, 1)
+
+/*
+** test_uint16_t_fetch_and_add:
+**	b	__sync_fetch_and_add_2_c
+*/
+
+/*
+** test_uint16_t_fetch_and_sub:
+**	b	__sync_fetch_and_sub_2_c
+*/
+
+/*
+** test_uint16_t_fetch_and_and:
+**	b	__sync_fetch_and_and_2_c
+*/
+
+/*
+** test_uint16_t_fetch_and_nand:
+**	b	__sync_fetch_and_nand_2_c
+*/
+
+/*
+** test_uint16_t_fetch_and_or:
+**	b	__sync_fetch_and_or_2_c
+*/
+
+/*
+** test_uint16_t_fetch_and_xor:
+**	b	__sync_fetch_and_xor_2_c
+*/
+
+/*
+** test_uint16_t_add_and_fetch:
+**	b	__sync_add_and_fetch_2_c
+*/
+
+/*
+** test_uint16_t_sub_and_fetch:
+**	b	__sync_sub_and_fetch_2_c
+*/
+
+/*
+** test_uint16_t_and_and_fetch:
+**	b	__sync_and_and_fetch_2_c
+*/
+
+/*
+** test_uint16_t_nand_and_fetch:
+**	b	__sync_nand_and_fetch_2_c
+*/
+
+/*
+** test_uint16_t_or_and_fetch:
+**	b	__sync_or_and_fetch_2_c
+*/
+
+/*
+** test_uint16_t_xor_and_fetch:
+**	b	__sync_xor_and_fetch_2_c
+*/
+TEST_SIZE (uint16_t, 2)
+
+/*
+** test_uint32_t_fetch_and_add:
+**	b	__sync_fetch_and_add_4_c
+*/
+
+/*
+** test_uint32_t_fetch_and_sub:
+**	b	__sync_fetch_and_sub_4_c
+*/
+
+/*
+** test_uint32_t_fetch_and_and:
+**	b	__sync_fetch_and_and_4_c
+*/
+
+/*
+** test_uint32_t_fetch_and_nand:
+**	b	__sync_fetch_and_nand_4_c
+*/
+
+/*
+** test_uint32_t_fetch_and_or:
+**	b	__sync_fetch_and_or_4_c
+*/
+
+/*
+** test_uint32_t_fetch_and_xor:
+**	b	__sync_fetch_and_xor_4_c
+*/
+
+/*
+** test_uint32_t_add_and_fetch:
+**	b	__sync_add_and_fetch_4_c
+*/
+
+/*
+** test_uint32_t_sub_and_fetch:
+**	b	__sync_sub_and_fetch_4_c
+*/
+
+/*
+** test_uint32_t_and_and_fetch:
+**	b	__sync_and_and_fetch_4_c
+*/
+
+/*
+** test_uint32_t_nand_and_fetch:
+**	b	__sync_nand_and_fetch_4_c
+*/
+
+/*
+** test_uint32_t_or_and_fetch:
+**	b	__sync_or_and_fetch_4_c
+*/
+
+/*
+** test_uint32_t_xor_and_fetch:
+**	b	__sync_xor_and_fetch_4_c
+*/
+TEST_SIZE (uint32_t, 4)
+
+/*
+** test_uint64_t_fetch_and_add:
+**	b	__sync_fetch_and_add_8_c
+*/
+
+/*
+** test_uint64_t_fetch_and_sub:
+**	b	__sync_fetch_and_sub_8_c
+*/
+
+/*
+** test_uint64_t_fetch_and_and:
+**	b	__sync_fetch_and_and_8_c
+*/
+
+/*
+** test_uint64_t_fetch_and_nand:
+**	b	__sync_fetch_and_nand_8_c
+*/
+
+/*
+** test_uint64_t_fetch_and_or:
+**	b	__sync_fetch_and_or_8_c
+*/
+
+/*
+** test_uint64_t_fetch_and_xor:
+**	b	__sync_fetch_and_xor_8_c
+*/
+
+/*
+** test_uint64_t_add_and_fetch:
+**	b	__sync_add_and_fetch_8_c
+*/
+
+/*
+** test_uint64_t_sub_and_fetch:
+**	b	__sync_sub_and_fetch_8_c
+*/
+
+/*
+** test_uint64_t_and_and_fetch:
+**	b	__sync_and_and_fetch_8_c
+*/
+
+/*
+** test_uint64_t_nand_and_fetch:
+**	b	__sync_nand_and_fetch_8_c
+*/
+
+/*
+** test_uint64_t_or_and_fetch:
+**	b	__sync_or_and_fetch_8_c
+*/
+
+/*
+** test_uint64_t_xor_and_fetch:
+**	b	__sync_xor_and_fetch_8_c
+*/
+TEST_SIZE (uint64_t, 8)
+
+/*
+** test_uint128_fetch_and_add:
+**	b	__sync_fetch_and_add_16_c
+*/
+
+/*
+** test_uint128_fetch_and_sub:
+**	b	__sync_fetch_and_sub_16_c
+*/
+
+/*
+** test_uint128_fetch_and_and:
+**	b	__sync_fetch_and_and_16_c
+*/
+
+/*
+** test_uint128_fetch_and_nand:
+**	b	__sync_fetch_and_nand_16_c
+*/
+
+/*
+** test_uint128_fetch_and_or:
+**	b	__sync_fetch_and_or_16_c
+*/
+
+/*
+** test_uint128_fetch_and_xor:
+**	b	__sync_fetch_and_xor_16_c
+*/
+
+/*
+** test_uint128_add_and_fetch:
+**	b	__sync_add_and_fetch_16_c
+*/
+
+/*
+** test_uint128_sub_and_fetch:
+**	b	__sync_sub_and_fetch_16_c
+*/
+
+/*
+** test_uint128_and_and_fetch:
+**	b	__sync_and_and_fetch_16_c
+*/
+
+/*
+** test_uint128_nand_and_fetch:
+**	b	__sync_nand_and_fetch_16_c
+*/
+
+/*
+** test_uint128_or_and_fetch:
+**	b	__sync_or_and_fetch_16_c
+*/
+
+/*
+** test_uint128_xor_and_fetch:
+**	b	__sync_xor_and_fetch_16_c
+*/
+TEST_SIZE (uint128, 16)
+
+/*
+** test_intcap_fetch_and_add:
+**	b	__sync_fetch_and_add_capability_c
+*/
+
+/*
+** test_intcap_fetch_and_sub:
+**	b	__sync_fetch_and_sub_capability_c
+*/
+
+/*
+** test_intcap_fetch_and_and:
+**	b	__sync_fetch_and_and_capability_c
+*/
+
+/*
+** test_intcap_fetch_and_nand:
+**	b	__sync_fetch_and_nand_capability_c
+*/
+
+/*
+** test_intcap_fetch_and_or:
+**	b	__sync_fetch_and_or_capability_c
+*/
+
+/*
+** test_intcap_fetch_and_xor:
+**	b	__sync_fetch_and_xor_capability_c
+*/
+
+/*
+** test_intcap_add_and_fetch:
+**	b	__sync_add_and_fetch_capability_c
+*/
+
+/*
+** test_intcap_sub_and_fetch:
+**	b	__sync_sub_and_fetch_capability_c
+*/
+
+/*
+** test_intcap_and_and_fetch:
+**	b	__sync_and_and_fetch_capability_c
+*/
+
+/*
+** test_intcap_nand_and_fetch:
+**	b	__sync_nand_and_fetch_capability_c
+*/
+
+/*
+** test_intcap_or_and_fetch:
+**	b	__sync_or_and_fetch_capability_c
+*/
+
+/*
+** test_intcap_xor_and_fetch:
+**	b	__sync_xor_and_fetch_capability_c
+*/
+TEST_SIZE (intcap, capability)


^ 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)] Make overload resolution pick _c functions 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).