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/ChangeLog:
* config/aarch64/aarch64-builtins.cc
(enum aarch64_builtins): Add ptr and generic variants.
(aarch64_init_pcdphint_builtins): Likewise.
(aarch64_general_expand_builtin): Add ptr variant.
(aarch64_resolve_overloaded_builtin_stshh): Function to handle
overloaded atomic_store_with_stshh.
(aarch64_resolve_overloaded_builtin_general): Add call to stshh function.
* config/aarch64/aarch64-c.cc
(aarch64_resolve_overloaded_builtin): Allow fndecl to return.
* config/aarch64/arm_acle.h
(__atomic_store_with_stshh): Remove __Generic.
gcc/testsuite/ChangeLog:
* gcc.target/aarch64/atomic_store_with_stshh.c: Testcase change.
* g++.target/aarch64/atomic_store_with_stshh.C: New test.
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_MAX
};
{
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,
= 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);
+
}
/* Initialize all builtins in the AARCH64_BUILTIN_GENERAL group. */
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;
}
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,
&& 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;
}
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);
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")
--- /dev/null
+/* { 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);
+}
** 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);
}