https://gcc.gnu.org/g:4015b65b038bea050c7892aa4535020493cd7c66
commit r17-4449-g4015b65b038bea050c7892aa4535020493cd7c66 Author: Richard Ball <[email protected]> Date: Fri Sep 18 20:06:44 2026 +0100 aarch64: Add support for FEAT_CMH atomic_fetch intrinsics This patch adds support for a new atomic_fetch_with_hint intrinsic. This intrinsic will make use of a new hint added by FEAT_CMH which is SHUH and SHUH PH. gcc/ChangeLog: * config/aarch64/aarch64-builtins.cc (enum aarch64_builtins): Add new builtins. (aarch64_init_atomic_hints_builtins): Likewise. (aarch64_expand_atomic_hints_builtins_fetch): Handle Fetch intrinsics. (aarch64_general_expand_builtin): Add call for new builtins. (aarch64_resolve_overloaded_builtin_atomic_hint_fetch): Handle Fetch intrinsics. (aarch64_resolve_overloaded_builtin_general): Add new call. * config/aarch64/arm_acle.h (enum atomic_fetch): Store different Fetch types. (__arm_atomic_fetch_add_with_hint): Add new builtin. (__arm_atomic_fetch_sub_with_hint): Likewise. (__arm_atomic_fetch_and_with_hint): Likewise. (__arm_atomic_fetch_xor_with_hint): Likewise. (__arm_atomic_fetch_or_with_hint): Likewise. * config/aarch64/atomics.md (aarch64_atomic_fetch_<atomic_ldoptab><mode>_atomic_hint): New pattern for atomic_fetch. (@aarch64_atomic_hints_fetch<mode>): Likewise. * config/aarch64/iterators.md: New unspecs. gcc/testsuite/ChangeLog: * gcc.target/aarch64/atomic_fetch_add_with_shuh.c: New test. * gcc.target/aarch64/atomic_fetch_and_with_shuh.c: New test. * gcc.target/aarch64/atomic_fetch_or_with_shuh.c: New test. * gcc.target/aarch64/atomic_fetch_sub_with_shuh.c: New test. * gcc.target/aarch64/atomic_fetch_xor_with_shuh.c: New test. Diff: --- gcc/config/aarch64/aarch64-builtins.cc | 220 ++++++++++++++++++++- gcc/config/aarch64/arm_acle.h | 39 ++++ gcc/config/aarch64/atomics.md | 77 ++++++++ gcc/config/aarch64/iterators.md | 2 + .../aarch64/atomic_fetch_add_with_shuh.c | 151 ++++++++++++++ .../aarch64/atomic_fetch_and_with_shuh.c | 150 ++++++++++++++ .../gcc.target/aarch64/atomic_fetch_or_with_shuh.c | 150 ++++++++++++++ .../aarch64/atomic_fetch_sub_with_shuh.c | 162 +++++++++++++++ .../aarch64/atomic_fetch_xor_with_shuh.c | 150 ++++++++++++++ 9 files changed, 1099 insertions(+), 2 deletions(-) diff --git a/gcc/config/aarch64/aarch64-builtins.cc b/gcc/config/aarch64/aarch64-builtins.cc index 5b1f9485d352..3389fc93af73 100644 --- a/gcc/config/aarch64/aarch64-builtins.cc +++ b/gcc/config/aarch64/aarch64-builtins.cc @@ -751,6 +751,16 @@ enum aarch64_builtins AARCH64_BUILTIN_ATOMIC_HINTS_STORE_SF, AARCH64_BUILTIN_ATOMIC_HINTS_STORE_DF, AARCH64_BUILTIN_ATOMIC_HINTS_STORE_PTR, + AARCH64_BUILTIN_ATOMIC_HINTS_FETCH, + AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_QI, + AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_HI, + AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_SI, + AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_DI, + AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_SIGNED_QI, + AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_SIGNED_HI, + AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_SIGNED_SI, + AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_SIGNED_DI, + AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_PTR, /* System Hint Operation builtins. */ AARCH64_BUILTIN_YIELD, AARCH64_BUILTIN_WFE, @@ -2365,6 +2375,106 @@ aarch64_init_atomic_hints_builtins (void) ftype, AARCH64_BUILTIN_ATOMIC_HINTS_STORE_PTR); + ftype = build_function_type_list (void_type_node, ptr_type_node, + void_type_node, + unsigned_type_node, + unsigned_type_node, + unsigned_type_node, NULL_TREE); + aarch64_builtin_decls[AARCH64_BUILTIN_ATOMIC_HINTS_FETCH] + = aarch64_general_add_builtin ("__builtin_aarch64_atomic_hints_fetch", + ftype, + AARCH64_BUILTIN_ATOMIC_HINTS_FETCH); + + ftype = build_function_type_list (unsigned_char_type_node, ptr_type_node, + unsigned_char_type_node, + unsigned_type_node, + unsigned_type_node, + unsigned_type_node, NULL_TREE); + aarch64_builtin_decls[AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_QI] + = aarch64_general_add_builtin ("__builtin_aarch64_atomic_hints_fetch_qi", + ftype, + AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_QI); + + ftype = build_function_type_list (short_unsigned_type_node, ptr_type_node, + short_unsigned_type_node, + unsigned_type_node, + unsigned_type_node, + unsigned_type_node, NULL_TREE); + aarch64_builtin_decls[AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_HI] + = aarch64_general_add_builtin ("__builtin_aarch64_atomic_hints_fetch_hi", + ftype, + AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_HI); + + ftype = build_function_type_list (unsigned_type_node, ptr_type_node, + unsigned_type_node, + unsigned_type_node, + unsigned_type_node, + unsigned_type_node, NULL_TREE); + aarch64_builtin_decls[AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_SI] + = aarch64_general_add_builtin ("__builtin_aarch64_atomic_hints_fetch_si", + ftype, + AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_SI); + + ftype = build_function_type_list (long_long_unsigned_type_node, ptr_type_node, + long_long_unsigned_type_node, + unsigned_type_node, + unsigned_type_node, + unsigned_type_node, NULL_TREE); + aarch64_builtin_decls[AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_DI] + = aarch64_general_add_builtin ("__builtin_aarch64_atomic_hints_fetch_di", + ftype, + AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_DI); + + ftype = build_function_type_list (char_type_node, ptr_type_node, + char_type_node, + unsigned_type_node, + unsigned_type_node, + unsigned_type_node, NULL_TREE); + aarch64_builtin_decls[AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_SIGNED_QI] + = aarch64_general_add_builtin ("__builtin_aarch64_atomic_hints_fetch_signed_qi", + ftype, + AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_SIGNED_QI); + + ftype = build_function_type_list (short_integer_type_node, ptr_type_node, + short_integer_type_node, + unsigned_type_node, + unsigned_type_node, + unsigned_type_node, NULL_TREE); + aarch64_builtin_decls[AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_SIGNED_HI] + = aarch64_general_add_builtin ("__builtin_aarch64_atomic_hints_fetch_signed_hi", + ftype, + AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_SIGNED_HI); + + ftype = build_function_type_list (integer_type_node, ptr_type_node, + integer_type_node, + unsigned_type_node, + unsigned_type_node, + unsigned_type_node, NULL_TREE); + aarch64_builtin_decls[AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_SIGNED_SI] + = aarch64_general_add_builtin ("__builtin_aarch64_atomic_hints_fetch_signed_si", + ftype, + AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_SIGNED_SI); + + ftype = build_function_type_list (long_long_integer_type_node, ptr_type_node, + long_long_integer_type_node, + unsigned_type_node, + unsigned_type_node, + unsigned_type_node, NULL_TREE); + aarch64_builtin_decls[AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_SIGNED_DI] + = aarch64_general_add_builtin ("__builtin_aarch64_atomic_hints_fetch_signed_di", + ftype, + AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_SIGNED_DI); + + ftype = build_function_type_list (ptr_type_node, ptr_type_node, + ptr_type_node, + unsigned_type_node, + unsigned_type_node, + unsigned_type_node, NULL_TREE); + aarch64_builtin_decls[AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_PTR] + = aarch64_general_add_builtin ("__builtin_aarch64_atomic_hints_fetch_ptr", + ftype, + AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_PTR); + } /* Initialize all builtins in the AARCH64_BUILTIN_GENERAL group. */ @@ -3996,6 +4106,47 @@ aarch64_expand_atomic_hints_builtins (tree exp, int fcode) expand_insn (icode, 4, ops); } +static rtx +aarch64_expand_atomic_hints_builtins_fetch (tree exp) +{ + machine_mode mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1))); + rtx val = expand_normal (CALL_EXPR_ARG (exp, 1)); + rtx mem_order = expand_normal (CALL_EXPR_ARG (exp, 2)); + rtx hint = expand_normal (CALL_EXPR_ARG (exp, 3)); + rtx fetch_type = expand_normal (CALL_EXPR_ARG (exp, 4)); + + require_const_argument (exp, 3, 0, 2); + require_const_argument (exp, 2, 0, 6); + require_const_argument (exp, 4, 0, 6); + if (seen_error ()) + return const0_rtx; + + if (!TARGET_LSE) + { + error_at (EXPR_LOCATION (exp), + "%qs must be enabled for this builtin", "TARGET_LSE"); + return const0_rtx; + } + + val = force_reg (mode, val); + rtx addr = expand_normal (CALL_EXPR_ARG (exp, 0)); + addr = force_reg (Pmode, addr); + rtx mem = gen_rtx_MEM (mode, addr); + + rtx return_val = gen_reg_rtx (mode); + expand_operand ops[6]; + enum insn_code icode; + create_output_operand (&ops[0], return_val, mode); + create_input_operand (&ops[1], mem, mode); + create_input_operand (&ops[2], val, mode); + create_input_operand (&ops[3], mem_order, SImode); + create_input_operand (&ops[4], hint, SImode); + create_input_operand (&ops[5], fetch_type, SImode); + icode = code_for_aarch64_atomic_hints_fetch (mode); + expand_insn (icode, 6, ops); + return (ops[0].value); +} + void aarch64_expand_pldir_builtin (tree exp) { @@ -4473,6 +4624,17 @@ aarch64_general_expand_builtin (unsigned int fcode, tree exp, rtx target, case AARCH64_BUILTIN_ATOMIC_HINTS_STORE_PTR: aarch64_expand_atomic_hints_builtins (exp, fcode); return target; + + case AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_QI: + case AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_HI: + case AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_SI: + case AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_DI: + case AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_SIGNED_QI: + case AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_SIGNED_HI: + case AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_SIGNED_SI: + case AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_SIGNED_DI: + case AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_PTR: + return aarch64_expand_atomic_hints_builtins_fetch (exp); } if (fcode >= AARCH64_SIMD_BUILTIN_BASE && fcode <= AARCH64_SIMD_BUILTIN_MAX) @@ -5449,7 +5611,7 @@ aarch64_resolve_overloaded_memtag (location_t loc, } static tree -aarch64_resolve_overloaded_builtin_atomic_hints (void *pass_params) +aarch64_resolve_overloaded_builtin_atomic_hint_store (void *pass_params) { vec<tree, va_gc> *params = static_cast<vec<tree, va_gc> *> (pass_params); @@ -5488,6 +5650,57 @@ aarch64_resolve_overloaded_builtin_atomic_hints (void *pass_params) } } +static tree +aarch64_resolve_overloaded_builtin_atomic_hint_fetch (void *pass_params) +{ + vec<tree, va_gc> *params = static_cast<vec<tree, va_gc> *> (pass_params); + + tree addr = (*params)[0]; + + 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 (vec_safe_length (params) != 5) + return NULL_TREE; + if (POINTER_TYPE_P (ptr_type)) + return aarch64_builtin_decls[AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_PTR]; + if (TYPE_UNSIGNED (ptr_type)) + { + switch (TYPE_MODE (ptr_type)) + { + case QImode: + return aarch64_builtin_decls[AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_QI]; + case HImode: + return aarch64_builtin_decls[AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_HI]; + case SImode: + return aarch64_builtin_decls[AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_SI]; + case DImode: + return aarch64_builtin_decls[AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_DI]; + default: + return NULL_TREE; + } + } + else + { + switch (TYPE_MODE (ptr_type)) + { + case QImode: + return aarch64_builtin_decls[AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_SIGNED_QI]; + case HImode: + return aarch64_builtin_decls[AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_SIGNED_HI]; + case SImode: + return aarch64_builtin_decls[AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_SIGNED_SI]; + case DImode: + return aarch64_builtin_decls[AARCH64_BUILTIN_ATOMIC_HINTS_FETCH_SIGNED_DI]; + 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, @@ -5500,7 +5713,10 @@ aarch64_resolve_overloaded_builtin_general (location_t loc, tree function, return aarch64_resolve_overloaded_memtag(loc, function, pass_params); if (fcode == AARCH64_BUILTIN_ATOMIC_HINTS_STORE) - return aarch64_resolve_overloaded_builtin_atomic_hints (pass_params); + return aarch64_resolve_overloaded_builtin_atomic_hint_store (pass_params); + + if (fcode == AARCH64_BUILTIN_ATOMIC_HINTS_FETCH) + return aarch64_resolve_overloaded_builtin_atomic_hint_fetch (pass_params); return NULL_TREE; } diff --git a/gcc/config/aarch64/arm_acle.h b/gcc/config/aarch64/arm_acle.h index 9317f1d2371c..84ba62e33189 100644 --- a/gcc/config/aarch64/arm_acle.h +++ b/gcc/config/aarch64/arm_acle.h @@ -46,6 +46,15 @@ NAME (TYPE __value, uint32_t __rotate) \ return __value >> __rotate | __value << ((__size - __rotate) % __size); \ } +enum atomic_fetch +{ + FETCH_ADD, + FETCH_SUB, + FETCH_AND, + FETCH_XOR, + FETCH_OR, +}; + _GCC_ARM_ACLE_ROR_FN (__ror, uint32_t) _GCC_ARM_ACLE_ROR_FN (__rorl, unsigned long) _GCC_ARM_ACLE_ROR_FN (__rorll, uint64_t) @@ -106,6 +115,36 @@ __sqrtf (float __x) __builtin_aarch64_atomic_hints_store ((__addr), (__value), \ (__memory_order), (__hint)) +#define __arm_atomic_fetch_add_with_hint(__addr, __value, __memory_order, \ + __hint) \ + __builtin_aarch64_atomic_hints_fetch ((__addr), (__value), \ + (__memory_order), (__hint), \ + (FETCH_ADD)) + +#define __arm_atomic_fetch_sub_with_hint(__addr, __value, __memory_order, \ + __hint) \ + __builtin_aarch64_atomic_hints_fetch ((__addr), (__value), \ + (__memory_order), (__hint), \ + (FETCH_SUB)) + +#define __arm_atomic_fetch_and_with_hint(__addr, __value, __memory_order, \ + __hint) \ + __builtin_aarch64_atomic_hints_fetch ((__addr), (__value), \ + (__memory_order), (__hint), \ + (FETCH_AND)) + +#define __arm_atomic_fetch_xor_with_hint(__addr, __value, __memory_order, \ + __hint) \ + __builtin_aarch64_atomic_hints_fetch ((__addr), (__value), \ + (__memory_order), (__hint), \ + (FETCH_XOR)) + +#define __arm_atomic_fetch_or_with_hint(__addr, __value, __memory_order, \ + __hint) \ + __builtin_aarch64_atomic_hints_fetch ((__addr), (__value), \ + (__memory_order), (__hint), \ + (FETCH_OR)) + #pragma GCC push_options #pragma GCC target ("+nothing+jscvt") __extension__ extern __inline int32_t diff --git a/gcc/config/aarch64/atomics.md b/gcc/config/aarch64/atomics.md index dca36242cb01..940aa15ac718 100644 --- a/gcc/config/aarch64/atomics.md +++ b/gcc/config/aarch64/atomics.md @@ -791,6 +791,83 @@ [(set_attr "arch" "*,rcpc8_4")] ) +(define_insn "aarch64_atomic_fetch_<atomic_ldoptab><mode>_atomic_hint" + [(set (match_operand:ALLI 0 "register_operand" "=r") + (match_operand:ALLI 1 "aarch64_sync_memory_operand" "+Q")) + (set (match_dup 1) + (unspec_volatile:ALLI + [(match_dup 1) + (match_operand:ALLI 2 "register_operand" "r") + (match_operand:SI 3 "const_int_operand") + (match_operand:SI 4 "const_int_operand")] + ATOMIC_LDOP))] + "TARGET_LSE" + { + switch (INTVAL (operands[4])) + { + case 0: + output_asm_insn ("shuh", operands); + break; + case 1: + output_asm_insn ("shuh\tph", operands); + break; + default: + gcc_unreachable (); + } + enum memmodel model = memmodel_from_int (INTVAL (operands[3])); + if (is_mm_relaxed (model)) + return "ld<atomic_ldop><atomic_sfx>\t%<w>2, %<w>0, %1"; + else if (is_mm_acquire (model) || is_mm_consume (model)) + return "ld<atomic_ldop>a<atomic_sfx>\t%<w>2, %<w>0, %1"; + else if (is_mm_release (model)) + return "ld<atomic_ldop>l<atomic_sfx>\t%<w>2, %<w>0, %1"; + else + return "ld<atomic_ldop>al<atomic_sfx>\t%<w>2, %<w>0, %1"; + } +) + +(define_expand "@aarch64_atomic_hints_fetch<mode>" +[(set (match_operand:ALLI 0 "register_operand") + (unspec_volatile:ALLI + [(match_operand:ALLI 1 "aarch64_sync_memory_operand") + (match_operand:ALLI 2 "aarch64_reg_or_zero") + (match_operand:SI 3 "const_int_operand") ;; model + (match_operand:SI 4 "const_int_operand") ;; hint + (match_operand:SI 5 "const_int_operand")] ;; fetch_type + UNSPECV_ATOMIC_HINTS_FETCH))] + "TARGET_LSE" + { + rtx (*gen) (rtx, rtx, rtx, rtx, rtx); + switch (INTVAL (operands[5])) + { + case 1: + operands[2] = expand_simple_unop (<MODE>mode, NEG, operands[2], + NULL, 1); + /* fallthrough. */ + case 0: + gen = gen_aarch64_atomic_fetch_add<mode>_atomic_hint; + break; + case 2: + operands[2] = expand_simple_unop (<MODE>mode, NOT, operands[2], + NULL, 1); + gen = gen_aarch64_atomic_fetch_bic<mode>_atomic_hint; + break; + case 3: + gen = gen_aarch64_atomic_fetch_xor<mode>_atomic_hint; + break; + case 4: + gen = gen_aarch64_atomic_fetch_ior<mode>_atomic_hint; + break; + default: + gcc_unreachable (); + } + operands[2] = force_reg (<MODE>mode, operands[2]); + emit_insn (gen (operands[0], operands[1], operands[2], operands[3], + operands[4])); + DONE; + } +) + (define_insn "@aarch64_load_exclusive<mode>" [(set (match_operand:SI 0 "register_operand" "=r") (zero_extend:SI diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md index eea783ffc081..d41c8921d162 100644 --- a/gcc/config/aarch64/iterators.md +++ b/gcc/config/aarch64/iterators.md @@ -1479,6 +1479,8 @@ UNSPECV_LDAP ; Represent an atomic acquire load with RCpc semantics. UNSPECV_STL ; Represent an atomic store or store-release. UNSPECV_ATOMIC_HINTS_STORE ; Represent an atomic store with a hint. + UNSPECV_ATOMIC_HINTS_FETCH ; Represent an atomic fetch with a hint. + UNSPECV_HINTS_FETCH ; Likewise. UNSPECV_ATOMIC_CMPSW ; Represent an atomic compare swap. UNSPECV_ATOMIC_EXCHG ; Represent an atomic exchange. UNSPECV_ATOMIC_CAS ; Represent an atomic CAS. diff --git a/gcc/testsuite/gcc.target/aarch64/atomic_fetch_add_with_shuh.c b/gcc/testsuite/gcc.target/aarch64/atomic_fetch_add_with_shuh.c new file mode 100644 index 000000000000..9844979848c6 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/atomic_fetch_add_with_shuh.c @@ -0,0 +1,151 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=armv8.1-a -save-temps" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +#include <arm_acle.h> + +/* +** testFun1: +** ... +** shuh +** ldaddb (w[0-9]+), \1, \[x[0-9]+\] +** ... +*/ +char +testFun1 () +{ + char item1 = 0; + char* ptr1 = &item1; + char test1 = 1; + + return __arm_atomic_fetch_add_with_hint (ptr1, test1, __ATOMIC_RELAXED, 0); +} + +/* +** testFun2: +** ... +** shuh +** ldaddlh (w[0-9]+), \1, \[x[0-9]+\] +** ... +*/ +short +testFun2 () +{ + short item2 = 10; + short* ptr2 = &item2; + short test2 = 11; + return __arm_atomic_fetch_add_with_hint (ptr2, test2, __ATOMIC_RELEASE, 0); +} + +/* +** testFun3: +** ... +** shuh ph +** ldaddal (w[0-9]+), \1, \[x[0-9]+\] +** ... +*/ +int +testFun3 () +{ + unsigned int item3 = 10; + unsigned int* ptr3 = &item3; + unsigned int test3 = 11; + return __arm_atomic_fetch_add_with_hint (ptr3, test3, __ATOMIC_SEQ_CST, 1); +} + +/* +** testFun4: +** ... +** shuh ph +** ldadd (x[0-9]+), \1, \[x[0-9]+\] +** ... +*/ +void +testFun4 () +{ + long item4 = 10; + long* ptr4 = &item4; + long test4 = 11; + __arm_atomic_fetch_add_with_hint (ptr4, test4, __ATOMIC_RELAXED, 1); +} + +/* +** testFun5: +** ... +** shuh +** ldaddal (x[0-9]+), \1, \[x[0-9]+\] +** ... +*/ +void +testFun5 () +{ + long item5 = 10; + long *ptritem = &item5; + long **ptr5 = &ptritem; + long test5item = 11; + long *test5 = &test5item; + __arm_atomic_fetch_add_with_hint (ptr5, test5, __ATOMIC_SEQ_CST, 0); +} + +/* +** testFun6: +** ... +** shuh +** ldaddb (w[0-9]+), \1, \[x[0-9]+\] +** ... +*/ +void +testFun6 () +{ + char item8 = 0; + char* ptr8 = &item8; + long test8 = 1; + + __arm_atomic_fetch_add_with_hint (ptr8, test8, __ATOMIC_RELAXED, 0); +} + +/* +** testFun7: +** ... +** add (x[0-9]+), \1, 1 +** mov (w[0-9]+), 7 +** shuh ph +** ldaddb \2, \2, \[x[0-9]+\] +** ... +*/ +static char buf[8]; +void +testFun7 (void) +{ + __arm_atomic_fetch_add_with_hint((buf + 1), (char)7, __ATOMIC_RELAXED, 1); +} + + +/* +** signed_fetch_add_hint: +** ... +** shuh ph +** ldadd (w[0-9]+), \1, \[x[0-9]+\] +** sxtw x[0-9]+, \1 +** ... +*/ +long +signed_fetch_add_hint (int x, int *p) +{ + return __arm_atomic_fetch_add_with_hint (p, x, __ATOMIC_RELAXED, 1); +} + + +/* +** unsigned_fetch_add_hint: +** ... +** shuh ph +** ldadd (w[0-9]+), \1, \[x[0-9]+\] +** uxtw x[0-9]+, \1 +** ... +*/ +long +unsigned_fetch_add_hint (unsigned int x, unsigned int *p) +{ + return __arm_atomic_fetch_add_with_hint (p, x, __ATOMIC_RELAXED, 1); +} \ No newline at end of file diff --git a/gcc/testsuite/gcc.target/aarch64/atomic_fetch_and_with_shuh.c b/gcc/testsuite/gcc.target/aarch64/atomic_fetch_and_with_shuh.c new file mode 100644 index 000000000000..35c919ca7698 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/atomic_fetch_and_with_shuh.c @@ -0,0 +1,150 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=armv8.1-a -save-temps" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +#include <arm_acle.h> + +/* +** testFun1: +** ... +** shuh +** ldclrb (w[0-9]+), \1, \[x[0-9]+\] +** ... +*/ +char +testFun1 () +{ + char item1 = 0; + char* ptr1 = &item1; + char test1 = 1; + + return __arm_atomic_fetch_and_with_hint (ptr1, test1, __ATOMIC_RELAXED, 0); +} + +/* +** testFun2: +** ... +** shuh +** ldclrlh (w[0-9]+), \1, \[x[0-9]+\] +** ... +*/ +short +testFun2 () +{ + short item2 = 10; + short* ptr2 = &item2; + short test2 = 11; + return __arm_atomic_fetch_and_with_hint (ptr2, test2, __ATOMIC_RELEASE, 0); +} + +/* +** testFun3: +** ... +** shuh ph +** ldclral (w[0-9]+), \1, \[x[0-9]+\] +** ... +*/ +int +testFun3 () +{ + unsigned int item3 = 10; + unsigned int* ptr3 = &item3; + unsigned int test3 = 11; + return __arm_atomic_fetch_and_with_hint (ptr3, test3, __ATOMIC_SEQ_CST, 1); +} + +/* +** testFun4: +** ... +** shuh ph +** ldclr (x[0-9]+), \1, \[x[0-9]+\] +** ... +*/ +void +testFun4 () +{ + long item4 = 10; + long* ptr4 = &item4; + long test4 = 11; + __arm_atomic_fetch_and_with_hint (ptr4, test4, __ATOMIC_RELAXED, 1); +} + +/* +** testFun5: +** ... +** shuh +** ldclral (x[0-9]+), \1, \[x[0-9]+\] +** ... +*/ +void +testFun5 () +{ + long item5 = 10; + long *ptritem = &item5; + long **ptr5 = &ptritem; + long test5item = 11; + long *test5 = &test5item; + __arm_atomic_fetch_and_with_hint (ptr5, test5, __ATOMIC_SEQ_CST, 0); +} + +/* +** testFun6: +** ... +** shuh +** ldclrb (w[0-9]+), \1, \[x[0-9]+\] +** ... +*/ +void +testFun6 () +{ + char item8 = 0; + char* ptr8 = &item8; + long test8 = 1; + + __arm_atomic_fetch_and_with_hint (ptr8, test8, __ATOMIC_RELAXED, 0); +} + +/* +** testFun7: +** ... +** add (x[0-9]+), \1, 1 +** mov (w[0-9]+), -8 +** shuh ph +** ldclrb \2, \2, \[x[0-9]+\] +** ... +*/ +static char buf[8]; +void +testFun7 (void) +{ + __arm_atomic_fetch_and_with_hint((buf + 1), (char)7, __ATOMIC_RELAXED, 1); +} + +/* +** signed_fetch_and_hint: +** ... +** shuh ph +** ldclr (w[0-9]+), \1, \[x[0-9]+\] +** sxtw x[0-9]+, \1 +** ... +*/ +long +signed_fetch_and_hint (int x, int *p) +{ + return __arm_atomic_fetch_and_with_hint (p, x, __ATOMIC_RELAXED, 1); +} + + +/* +** unsigned_fetch_and_hint: +** ... +** shuh ph +** ldclr (w[0-9]+), \1, \[x[0-9]+\] +** uxtw x[0-9]+, \1 +** ... +*/ +long +unsigned_fetch_and_hint (unsigned int x, unsigned int *p) +{ + return __arm_atomic_fetch_and_with_hint (p, x, __ATOMIC_RELAXED, 1); +} \ No newline at end of file diff --git a/gcc/testsuite/gcc.target/aarch64/atomic_fetch_or_with_shuh.c b/gcc/testsuite/gcc.target/aarch64/atomic_fetch_or_with_shuh.c new file mode 100644 index 000000000000..02661254ad0f --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/atomic_fetch_or_with_shuh.c @@ -0,0 +1,150 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=armv8.1-a -save-temps" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +#include <arm_acle.h> + +/* +** testFun1: +** ... +** shuh +** ldsetb (w[0-9]+), \1, \[x[0-9]+\] +** ... +*/ +char +testFun1 () +{ + char item1 = 0; + char* ptr1 = &item1; + char test1 = 1; + + return __arm_atomic_fetch_or_with_hint (ptr1, test1, __ATOMIC_RELAXED, 0); +} + +/* +** testFun2: +** ... +** shuh +** ldsetlh (w[0-9]+), \1, \[x[0-9]+\] +** ... +*/ +short +testFun2 () +{ + short item2 = 10; + short* ptr2 = &item2; + short test2 = 11; + return __arm_atomic_fetch_or_with_hint (ptr2, test2, __ATOMIC_RELEASE, 0); +} + +/* +** testFun3: +** ... +** shuh ph +** ldsetal (w[0-9]+), \1, \[x[0-9]+\] +** ... +*/ +int +testFun3 () +{ + unsigned int item3 = 10; + unsigned int* ptr3 = &item3; + unsigned int test3 = 11; + return __arm_atomic_fetch_or_with_hint (ptr3, test3, __ATOMIC_SEQ_CST, 1); +} + +/* +** testFun4: +** ... +** shuh ph +** ldset (x[0-9]+), \1, \[x[0-9]+\] +** ... +*/ +void +testFun4 () +{ + long item4 = 10; + long* ptr4 = &item4; + long test4 = 11; + __arm_atomic_fetch_or_with_hint (ptr4, test4, __ATOMIC_RELAXED, 1); +} + +/* +** testFun5: +** ... +** shuh +** ldsetal (x[0-9]+), \1, \[x[0-9]+\] +** ... +*/ +void +testFun5 () +{ + long item5 = 10; + long *ptritem = &item5; + long **ptr5 = &ptritem; + long test5item = 11; + long *test5 = &test5item; + __arm_atomic_fetch_or_with_hint (ptr5, test5, __ATOMIC_SEQ_CST, 0); +} + +/* +** testFun6: +** ... +** shuh +** ldsetb (w[0-9]+), \1, \[x[0-9]+\] +** ... +*/ +void +testFun6 () +{ + char item8 = 0; + char* ptr8 = &item8; + long test8 = 1; + + __arm_atomic_fetch_or_with_hint (ptr8, test8, __ATOMIC_RELAXED, 0); +} + +/* +** testFun7: +** ... +** add (x[0-9]+), \1, 1 +** mov (w[0-9]+), 7 +** shuh ph +** ldsetb \2, \2, \[x[0-9]+\] +** ... +*/ +static char buf[8]; +void +testFun7 (void) +{ + __arm_atomic_fetch_or_with_hint((buf + 1), (char)7, __ATOMIC_RELAXED, 1); +} + +/* +** signed_fetch_or_hint: +** ... +** shuh ph +** ldset (w[0-9]+), \1, \[x[0-9]+\] +** sxtw x[0-9]+, \1 +** ... +*/ +long +signed_fetch_or_hint (int x, int *p) +{ + return __arm_atomic_fetch_or_with_hint (p, x, __ATOMIC_RELAXED, 1); +} + + +/* +** unsigned_fetch_or_hint: +** ... +** shuh ph +** ldset (w[0-9]+), \1, \[x[0-9]+\] +** uxtw x[0-9]+, \1 +** ... +*/ +long +unsigned_fetch_or_hint (unsigned int x, unsigned int *p) +{ + return __arm_atomic_fetch_or_with_hint (p, x, __ATOMIC_RELAXED, 1); +} \ No newline at end of file diff --git a/gcc/testsuite/gcc.target/aarch64/atomic_fetch_sub_with_shuh.c b/gcc/testsuite/gcc.target/aarch64/atomic_fetch_sub_with_shuh.c new file mode 100644 index 000000000000..04b400fe7b36 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/atomic_fetch_sub_with_shuh.c @@ -0,0 +1,162 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=armv8.1-a -save-temps" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +#include <arm_acle.h> + +/* +** testFun1: +** ... +** mov (w[0-9]+), -1 +** add (x[0-9]+), sp, 15 +** strb wzr, \[sp, 15\] +** shuh +** ldaddb \1, \1, \[\2\] +** ... +*/ +char +testFun1 () +{ + char item1 = 0; + char* ptr1 = &item1; + char test1 = 1; + + return __arm_atomic_fetch_sub_with_hint (ptr1, test1, __ATOMIC_RELAXED, 0); +} + +/* +** testFun2: +** ... +** mov (w[0-9]+), -11 +** shuh +** ldaddlh (w[0-9]+), \1, \[x[0-9]+\] +** ... +*/ +short +testFun2 () +{ + short item2 = 10; + short* ptr2 = &item2; + short test2 = 11; + return __arm_atomic_fetch_sub_with_hint (ptr2, test2, __ATOMIC_RELEASE, 0); +} + +/* +** testFun3: +** ... +** mov (w[0-9]+), -11 +** shuh ph +** ldaddal (w[0-9]+), \1, \[x[0-9]+\] +** ... +*/ +int +testFun3 () +{ + unsigned int item3 = 10; + unsigned int* ptr3 = &item3; + unsigned int test3 = 11; + return __arm_atomic_fetch_sub_with_hint (ptr3, test3, __ATOMIC_SEQ_CST, 1); +} + +/* +** testFun4: +** ... +** mov (x[0-9]+), -11 +** str (x[0-9]+), \[sp, 8\] +** add \2, sp, 8 +** shuh ph +** ldadd \1, \1, \[\2\] +** ... +*/ +void +testFun4 () +{ + long item4 = 10; + long* ptr4 = &item4; + long test4 = 11; + __arm_atomic_fetch_sub_with_hint (ptr4, test4, __ATOMIC_RELAXED, 1); +} + +/* +** testFun5: +** ... +** neg (x[0-9]+), \1 +** shuh +** ldaddal \1, \1, \[x[0-9]+\] +** ... +*/ +void +testFun5 () +{ + long item5 = 10; + long *ptritem = &item5; + long **ptr5 = &ptritem; + long test5item = 11; + long *test5 = &test5item; + __arm_atomic_fetch_sub_with_hint (ptr5, test5, __ATOMIC_SEQ_CST, 0); +} + +/* +** testFun6: +** ... +** mov (w[0-9]+), -1 +** add (x[0-9]+), sp, 15 +** strb wzr, \[sp, 15\] +** shuh +** ldaddb (w[0-9]+), \1, \[\2\] +** ... +*/ +void +testFun6 () +{ + char item8 = 0; + char* ptr8 = &item8; + long test8 = 1; + + __arm_atomic_fetch_sub_with_hint (ptr8, test8, __ATOMIC_RELAXED, 0); +} + +/* +** testFun7: +** ... +** add (x[0-9]+), \1, 1 +** mov (w[0-9]+), -7 +** shuh ph +** ldaddb \2, \2, \[\1\] +** ... +*/ +static char buf[8]; +void +testFun7 (void) +{ + __arm_atomic_fetch_sub_with_hint((buf + 1), (char)7, __ATOMIC_RELAXED, 1); +} + +/* +** signed_fetch_sub_hint: +** ... +** shuh ph +** ldadd (w[0-9]+), \1, \[x[0-9]+\] +** sxtw x[0-9]+, \1 +** ... +*/ +long +signed_fetch_sub_hint (int x, int *p) +{ + return __arm_atomic_fetch_sub_with_hint (p, x, __ATOMIC_RELAXED, 1); +} + + +/* +** unsigned_fetch_sub_hint: +** ... +** shuh ph +** ldadd (w[0-9]+), \1, \[x[0-9]+\] +** uxtw x[0-9]+, \1 +** ... +*/ +long +unsigned_fetch_sub_hint (unsigned int x, unsigned int *p) +{ + return __arm_atomic_fetch_sub_with_hint (p, x, __ATOMIC_RELAXED, 1); +} \ No newline at end of file diff --git a/gcc/testsuite/gcc.target/aarch64/atomic_fetch_xor_with_shuh.c b/gcc/testsuite/gcc.target/aarch64/atomic_fetch_xor_with_shuh.c new file mode 100644 index 000000000000..2aa4f8daee25 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/atomic_fetch_xor_with_shuh.c @@ -0,0 +1,150 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=armv8.1-a -save-temps" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +#include <arm_acle.h> + +/* +** testFun1: +** ... +** shuh +** ldeorb (w[0-9]+), \1, \[x[0-9]+\] +** ... +*/ +char +testFun1 () +{ + char item1 = 0; + char* ptr1 = &item1; + char test1 = 1; + + return __arm_atomic_fetch_xor_with_hint (ptr1, test1, __ATOMIC_RELAXED, 0); +} + +/* +** testFun2: +** ... +** shuh +** ldeorlh (w[0-9]+), \1, \[x[0-9]+\] +** ... +*/ +short +testFun2 () +{ + short item2 = 10; + short* ptr2 = &item2; + short test2 = 11; + return __arm_atomic_fetch_xor_with_hint (ptr2, test2, __ATOMIC_RELEASE, 0); +} + +/* +** testFun3: +** ... +** shuh ph +** ldeoral (w[0-9]+), \1, \[x[0-9]+\] +** ... +*/ +int +testFun3 () +{ + unsigned int item3 = 10; + unsigned int* ptr3 = &item3; + unsigned int test3 = 11; + return __arm_atomic_fetch_xor_with_hint (ptr3, test3, __ATOMIC_SEQ_CST, 1); +} + +/* +** testFun4: +** ... +** shuh ph +** ldeor (x[0-9]+), \1, \[x[0-9]+\] +** ... +*/ +void +testFun4 () +{ + long item4 = 10; + long* ptr4 = &item4; + long test4 = 11; + __arm_atomic_fetch_xor_with_hint (ptr4, test4, __ATOMIC_RELAXED, 1); +} + +/* +** testFun5: +** ... +** shuh +** ldeoral (x[0-9]+), \1, \[x[0-9]+\] +** ... +*/ +void +testFun5 () +{ + long item5 = 10; + long *ptritem = &item5; + long **ptr5 = &ptritem; + long test5item = 11; + long *test5 = &test5item; + __arm_atomic_fetch_xor_with_hint (ptr5, test5, __ATOMIC_SEQ_CST, 0); +} + +/* +** testFun6: +** ... +** shuh +** ldeorb (w[0-9]+), \1, \[x[0-9]+\] +** ... +*/ +void +testFun6 () +{ + char item8 = 0; + char* ptr8 = &item8; + long test8 = 1; + + __arm_atomic_fetch_xor_with_hint (ptr8, test8, __ATOMIC_RELAXED, 0); +} + +/* +** testFun7: +** ... +** add (x[0-9]+), \1, 1 +** mov (w[0-9]+), 7 +** shuh ph +** ldeorb \2, \2, \[x[0-9]+\] +** ... +*/ +static char buf[8]; +void +testFun7 (void) +{ + __arm_atomic_fetch_xor_with_hint((buf + 1), (char)7, __ATOMIC_RELAXED, 1); +} + +/* +** signed_fetch_xor_hint: +** ... +** shuh ph +** ldeor (w[0-9]+), \1, \[x[0-9]+\] +** sxtw x[0-9]+, \1 +** ... +*/ +long +signed_fetch_xor_hint (int x, int *p) +{ + return __arm_atomic_fetch_xor_with_hint (p, x, __ATOMIC_RELAXED, 1); +} + + +/* +** unsigned_fetch_xor_hint: +** ... +** shuh ph +** ldeor (w[0-9]+), \1, \[x[0-9]+\] +** uxtw x[0-9]+, \1 +** ... +*/ +long +unsigned_fetch_xor_hint (unsigned int x, unsigned int *p) +{ + return __arm_atomic_fetch_xor_with_hint (p, x, __ATOMIC_RELAXED, 1); +} \ No newline at end of file
