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 | 62 ++++++
gcc/config/aarch64/aarch64-c.cc | 3 +-
gcc/config/aarch64/arm_acle.h | 24 +--
.../aarch64/atomic_store_with_stshh.C | 186 ++++++++++++++++++
.../aarch64/atomic_store_with_stshh.c | 7 +-
5 files changed, 257 insertions(+), 25 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 07c78ac0630..453948a5592 100644
--- a/gcc/config/aarch64/aarch64-builtins.cc
+++ b/gcc/config/aarch64/aarch64-builtins.cc
@@ -902,12 +902,14 @@ 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,
AARCH64_BUILTIN_STSHH_DI,
AARCH64_BUILTIN_STSHH_SF,
AARCH64_BUILTIN_STSHH_DF,
+ AARCH64_BUILTIN_STSHH_PTR,
AARCH64_BUILTIN_PLDIR,
AARCH64_BUILTIN_MAX
};
@@ -2481,6 +2483,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,
@@ -2529,6 +2539,14 @@ aarch64_init_pcdphint_builtins (void)
= aarch64_general_add_builtin ("__builtin_aarch64_stshh_df", ftype,
AARCH64_BUILTIN_STSHH_DF);
+ ftype = build_function_type_list (void_type_node, ptr_type_node,
+ ptr_type_node,
+ unsigned_type_node,
+ unsigned_type_node, NULL_TREE);
+ aarch64_builtin_decls[AARCH64_BUILTIN_STSHH_PTR]
+ = aarch64_general_add_builtin ("__builtin_aarch64_stshh_ptr", ftype,
+ AARCH64_BUILTIN_STSHH_PTR);
+
tree cv_argtype = build_qualified_type (void_type_node, TYPE_QUAL_CONST
| TYPE_QUAL_VOLATILE);
cv_argtype = build_pointer_type (cv_argtype);
@@ -4599,6 +4617,7 @@ aarch64_general_expand_builtin (unsigned int fcode, tree
exp, rtx target,
case AARCH64_BUILTIN_STSHH_DI:
case AARCH64_BUILTIN_STSHH_SF:
case AARCH64_BUILTIN_STSHH_DF:
+ case AARCH64_BUILTIN_STSHH_PTR:
aarch64_expand_stshh_builtin (exp, fcode);
return target;
@@ -5767,6 +5786,46 @@ 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));
+
+ if (POINTER_TYPE_P (ptr_type))
+ return aarch64_builtin_decls[AARCH64_BUILTIN_STSHH_PTR];
+
+ switch (TYPE_MODE (ptr_type))
+ {
+ case QImode:
+ return aarch64_builtin_decls[AARCH64_BUILTIN_STSHH_QI];
+ case HImode:
+ return aarch64_builtin_decls[AARCH64_BUILTIN_STSHH_HI];
+ case SImode:
+ return aarch64_builtin_decls[AARCH64_BUILTIN_STSHH_SI];
+ case DImode:
+ return aarch64_builtin_decls[AARCH64_BUILTIN_STSHH_DI];
+ case SFmode:
+ return aarch64_builtin_decls[AARCH64_BUILTIN_STSHH_SF];
+ case DFmode:
+ return aarch64_builtin_decls[AARCH64_BUILTIN_STSHH_DF];
+ default:
+ return NULL_TREE;
+ }
+}
+
/* Called at aarch64_resolve_overloaded_builtin in aarch64-c.cc. */
tree
aarch64_resolve_overloaded_builtin_general (location_t loc, tree function,
@@ -5778,6 +5837,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 f8be998da16..dbe940a8ba9 100644
--- a/gcc/config/aarch64/aarch64-c.cc
+++ b/gcc/config/aarch64/aarch64-c.cc
@@ -431,8 +431,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..d22412369ef
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/atomic_store_with_stshh.C
@@ -0,0 +1,186 @@
+/* { 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]+, \[x[0-9]+\]
+** ...
+*/
+void
+testFun5 ()
+{
+ long item5 = 10;
+ long *ptritem = &item5;
+ long **ptr5 = &ptritem;
+ 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);
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/atomic_store_with_stshh.c
b/gcc/testsuite/gcc.target/aarch64/atomic_store_with_stshh.c
index 9be42574b9c..516a45aa781 100644
--- a/gcc/testsuite/gcc.target/aarch64/atomic_store_with_stshh.c
+++ b/gcc/testsuite/gcc.target/aarch64/atomic_store_with_stshh.c
@@ -73,16 +73,17 @@ testFun4 ()
** testFun5:
** ...
** stshh keep
-** stlr x[0-9]+, \[sp\]
+** stlr x[0-9]+, \[x[0-9]+\]
** ...
*/
void
testFun5 ()
{
long item5 = 10;
- long* ptr5 = &item5;
+ long *ptritem = &item5;
+ long **ptr5 = &ptritem;
long test5item = 11;
- long* test5 = &test5item;
+ long *test5 = &test5item;
__atomic_store_with_stshh (ptr5, test5, __ATOMIC_SEQ_CST, 0);
}
--
2.34.1