From: Richard Ball <[email protected]>
This patch rewrites the _Generic in arm_acle.h into a
resolve_overloaded_builtin.
The reason for this was the lack of support in C++ for _Generic.
---
gcc/config/aarch64/aarch64-builtins.cc | 64 ++++++
gcc/config/aarch64/aarch64-c.cc | 3 +-
gcc/config/aarch64/arm_acle.h | 24 +--
.../aarch64/atomic_store_with_stshh.C | 185 ++++++++++++++++++
4 files changed, 254 insertions(+), 22 deletions(-)
create mode 100644 gcc/testsuite/g++.target/aarch64/atomic_store_with_stshh.C
diff --git a/gcc/config/aarch64/aarch64-builtins.cc
b/gcc/config/aarch64/aarch64-builtins.cc
index c2a9e3d3412..8149c440536 100644
--- a/gcc/config/aarch64/aarch64-builtins.cc
+++ b/gcc/config/aarch64/aarch64-builtins.cc
@@ -902,6 +902,7 @@ enum aarch64_builtins
AARCH64_BUILTIN_GCSPOPM,
AARCH64_BUILTIN_GCSSS,
/* Armv9.6-A builtins. */
+ AARCH64_BUILTIN_STSHH,
AARCH64_BUILTIN_STSHH_QI,
AARCH64_BUILTIN_STSHH_HI,
AARCH64_BUILTIN_STSHH_SI,
@@ -2481,6 +2482,14 @@ aarch64_init_pcdphint_builtins (void)
{
tree ftype;
+ ftype = build_function_type_list (void_type_node, ptr_type_node,
+ void_type_node,
+ unsigned_type_node,
+ unsigned_type_node, NULL_TREE);
+ aarch64_builtin_decls[AARCH64_BUILTIN_STSHH]
+ = aarch64_general_add_builtin ("__builtin_aarch64_stshh", ftype,
+ AARCH64_BUILTIN_STSHH);
+
ftype = build_function_type_list (void_type_node, ptr_type_node,
unsigned_char_type_node,
unsigned_type_node,
@@ -5767,6 +5776,58 @@ aarch64_resolve_overloaded_memtag (location_t loc,
return NULL_TREE;
}
+static tree
+aarch64_resolve_overloaded_builtin_stshh (void *pass_params)
+{
+ vec<tree, va_gc> *params = static_cast<vec<tree, va_gc> *> (pass_params);
+ if (vec_safe_length (params) != 4)
+ return NULL_TREE;
+
+ tree addr = (*params)[0];
+ tree val = (*params)[1];
+ addr = tree_strip_nop_conversions (addr);
+ val = tree_strip_nop_conversions (val);
+
+ tree addr_type = TREE_TYPE (addr);
+ if (!POINTER_TYPE_P (addr_type))
+ return NULL_TREE;
+
+ tree ptr_type = TYPE_MAIN_VARIANT (TREE_TYPE (addr_type));
+ enum aarch64_builtins decl;
+
+ if (INTEGRAL_TYPE_P (ptr_type) && POINTER_TYPE_P (TREE_TYPE (val)))
+ {
+ val = convert (size_type_node, val);
+ if (val == error_mark_node)
+ return NULL_TREE;
+ (*params)[1] = val;
+ }
+
+ if (ptr_type == char_type_node
+ || ptr_type == signed_char_type_node
+ || ptr_type == unsigned_char_type_node)
+ decl = AARCH64_BUILTIN_STSHH_QI;
+ else if (ptr_type == short_integer_type_node
+ || ptr_type == short_unsigned_type_node)
+ decl = AARCH64_BUILTIN_STSHH_HI;
+ else if (ptr_type == integer_type_node
+ || ptr_type == unsigned_type_node)
+ decl = AARCH64_BUILTIN_STSHH_SI;
+ else if (ptr_type == long_long_integer_type_node
+ || ptr_type == long_long_unsigned_type_node
+ || ptr_type == long_integer_type_node
+ || ptr_type == long_unsigned_type_node)
+ decl = AARCH64_BUILTIN_STSHH_DI;
+ else if (ptr_type == float_type_node)
+ decl = AARCH64_BUILTIN_STSHH_SF;
+ else if (ptr_type == double_type_node)
+ decl = AARCH64_BUILTIN_STSHH_DF;
+ else
+ return NULL_TREE;
+
+ return aarch64_builtin_decls[decl];
+}
+
/* Called at aarch64_resolve_overloaded_builtin in aarch64-c.cc. */
tree
aarch64_resolve_overloaded_builtin_general (location_t loc, tree function,
@@ -5778,6 +5839,9 @@ aarch64_resolve_overloaded_builtin_general (location_t
loc, tree function,
&& fcode <= AARCH64_MEMTAG_BUILTIN_END)
return aarch64_resolve_overloaded_memtag(loc, function, pass_params);
+ if (fcode == AARCH64_BUILTIN_STSHH)
+ return aarch64_resolve_overloaded_builtin_stshh (pass_params);
+
return NULL_TREE;
}
diff --git a/gcc/config/aarch64/aarch64-c.cc b/gcc/config/aarch64/aarch64-c.cc
index b52ea7649f9..ecb37bd525f 100644
--- a/gcc/config/aarch64/aarch64-c.cc
+++ b/gcc/config/aarch64/aarch64-c.cc
@@ -429,8 +429,9 @@ aarch64_resolve_overloaded_builtin (location_t location,
switch (code & AARCH64_BUILTIN_CLASS)
{
case AARCH64_BUILTIN_GENERAL:
- return aarch64_resolve_overloaded_builtin_general (location, fndecl,
+ new_fndecl = aarch64_resolve_overloaded_builtin_general (location,
fndecl,
uncast_arglist);
+ break;
case AARCH64_BUILTIN_SVE:
new_fndecl = aarch64_sve::resolve_overloaded_builtin (location, subcode,
arglist);
diff --git a/gcc/config/aarch64/arm_acle.h b/gcc/config/aarch64/arm_acle.h
index 651f4cb8b60..a99756542ef 100644
--- a/gcc/config/aarch64/arm_acle.h
+++ b/gcc/config/aarch64/arm_acle.h
@@ -139,27 +139,9 @@ __sqrtf (float __x)
return __builtin_aarch64_sqrtsf (__x);
}
-#define __atomic_store_with_stshh(addr, value, memory_order, ret) \
-({ \
- __auto_type ptr = (addr); \
- typedef __typeof__ (*ptr) ptr_type; \
- _Generic ((*ptr), \
- char: __builtin_aarch64_stshh_qi, \
- unsigned char: __builtin_aarch64_stshh_qi, \
- signed char: __builtin_aarch64_stshh_qi, \
- unsigned short: __builtin_aarch64_stshh_hi, \
- short: __builtin_aarch64_stshh_hi, \
- unsigned int: __builtin_aarch64_stshh_si, \
- int: __builtin_aarch64_stshh_si, \
- unsigned long: __builtin_aarch64_stshh_di, \
- long: __builtin_aarch64_stshh_di, \
- unsigned long long: __builtin_aarch64_stshh_di, \
- long long: __builtin_aarch64_stshh_di, \
- float: __builtin_aarch64_stshh_sf, \
- double: __builtin_aarch64_stshh_df, \
- default: __builtin_aarch64_stshh_di \
- )((ptr), (ptr_type)(value), (memory_order), (ret)); \
-})
+#define __atomic_store_with_stshh(__addr, __value, __memory_order, __ret) \
+ __builtin_aarch64_stshh ((__addr), (__value), \
+ (__memory_order), (__ret))
#pragma GCC push_options
#pragma GCC target ("+nothing+jscvt")
diff --git a/gcc/testsuite/g++.target/aarch64/atomic_store_with_stshh.C
b/gcc/testsuite/g++.target/aarch64/atomic_store_with_stshh.C
new file mode 100644
index 00000000000..a4b6650bb39
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/atomic_store_with_stshh.C
@@ -0,0 +1,185 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=armv8-a -save-temps" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include <arm_acle.h>
+
+/*
+** _Z8testFun1v:
+** ...
+** stshh keep
+** strb w[0-9]+, \[x[0-9]+\]
+** ...
+*/
+void
+testFun1 ()
+{
+ char item1 = 0;
+ char* ptr1 = &item1;
+ char test1 = 1;
+
+ __atomic_store_with_stshh (ptr1, test1, __ATOMIC_RELAXED, 0);
+}
+
+/*
+** _Z8testFun2v:
+** ...
+** stshh keep
+** stlrh w[0-9]+, \[x[0-9]+\]
+** ...
+*/
+void
+testFun2 ()
+{
+ short item2 = 10;
+ short* ptr2 = &item2;
+ short test2 = 11;
+ __atomic_store_with_stshh (ptr2, test2, __ATOMIC_RELEASE, 0);
+}
+
+/*
+** _Z8testFun3v:
+** ...
+** stshh strm
+** stlr w[0-9]+, \[x[0-9]+\]
+** ...
+*/
+void
+testFun3 ()
+{
+ unsigned int item3 = 10;
+ unsigned int* ptr3 = &item3;
+ unsigned int test3 = 11;
+ __atomic_store_with_stshh (ptr3, test3, __ATOMIC_SEQ_CST, 1);
+}
+
+/*
+** _Z8testFun4v:
+** ...
+** stshh strm
+** str x[0-9]+, \[x[0-9]+\]
+** ...
+*/
+void
+testFun4 ()
+{
+ long item4 = 10;
+ long* ptr4 = &item4;
+ long test4 = 11;
+ __atomic_store_with_stshh (ptr4, test4, __ATOMIC_RELAXED, 1);
+}
+
+/*
+** _Z8testFun5v:
+** ...
+** stshh keep
+** stlr x[0-9]+, \[sp\]
+** ...
+*/
+void
+testFun5 ()
+{
+ long item5 = 10;
+ long* ptr5 = &item5;
+ long test5item = 11;
+ long* test5 = &test5item;
+ __atomic_store_with_stshh (ptr5, test5, __ATOMIC_SEQ_CST, 0);
+}
+
+/*
+** _Z8testFun6v:
+** ...
+** stshh keep
+** stlr w[0-9]+, \[x[0-9]+\]
+** ...
+*/
+void
+testFun6 ()
+{
+ float item6 = 10;
+ float* ptr6 = &item6;
+ float test6 = 11;
+ __atomic_store_with_stshh (ptr6, test6, __ATOMIC_SEQ_CST, 0);
+}
+
+/*
+** _Z8testFun7v:
+** ...
+** stshh strm
+** str x[0-9]+, \[x[0-9]+\]
+** ...
+*/
+void
+testFun7 ()
+{
+ double item7 = 10;
+ double* ptr7 = &item7;
+ double test7 = 11;
+ __atomic_store_with_stshh (ptr7, test7, __ATOMIC_RELAXED, 1);
+}
+
+/*
+** _Z8testFun8v:
+** ...
+** stshh keep
+** strb w[0-9]+, \[x[0-9]+\]
+** ...
+*/
+void
+testFun8 ()
+{
+ char item8 = 0;
+ char* ptr8 = &item8;
+ long test8 = 1;
+
+ __atomic_store_with_stshh (ptr8, test8, __ATOMIC_RELAXED, 0);
+}
+
+/*
+** _Z8testFun9v:
+** ...
+** stshh strm
+** str w[0-9]+, \[x[0-9]+\]
+** ...
+*/
+void
+testFun9 ()
+{
+ int item9 = 0;
+ int* ptr9 = &item9;
+ float test9 = 1;
+
+ __atomic_store_with_stshh (ptr9, test9, __ATOMIC_RELAXED, 1);
+}
+
+/*
+** _Z9testFun10v:
+** ...
+** add (x[0-9]+), \1, 1
+** mov (w[0-9]+), 7
+** stshh strm
+** strb \2, \[\1\]
+** ...
+*/
+static char buf[8];
+void
+testFun10 (void)
+{
+ __atomic_store_with_stshh((buf + 1), (char)7, __ATOMIC_RELAXED, 1);
+}
+
+/*
+** _Z9testFun11v:
+** ...
+** stshh strm
+** str wzr, \[x[0-9]+\]
+** ...
+*/
+void
+testFun11 ()
+{
+ int item11 = 10;
+ int* ptr11 = &item11;
+
+ __atomic_store_with_stshh (ptr11, 0, __ATOMIC_RELAXED, 1);
+}
--
2.34.1