diff options
author | Wilco Dijkstra <wilco.dijkstra@arm.com> | 2024-10-14 16:53:44 +0000 |
---|---|---|
committer | Wilco Dijkstra <wilco.dijkstra@arm.com> | 2024-10-23 12:45:10 +0000 |
commit | 22a37534c640ca5ff2f0e947dfe60df59fb6bba1 (patch) | |
tree | c230fa08200dc836f5a56a210f4d3d9fc8fb05e7 /gcc | |
parent | 756890d66cf4971fc11187ccdf5893681aa661a1 (diff) | |
download | gcc-22a37534c640ca5ff2f0e947dfe60df59fb6bba1.zip gcc-22a37534c640ca5ff2f0e947dfe60df59fb6bba1.tar.gz gcc-22a37534c640ca5ff2f0e947dfe60df59fb6bba1.tar.bz2 |
AArch64: Add support for SIMD xor immediate (3/3)
Add support for SVE xor immediate when generating AdvSIMD code and SVE is
available.
gcc/ChangeLog:
* config/aarch64/aarch64.cc (enum simd_immediate_check): Add
AARCH64_CHECK_XOR.
(aarch64_simd_valid_xor_imm): New function.
(aarch64_output_simd_imm): Add AARCH64_CHECK_XOR support.
(aarch64_output_simd_xor_imm): New function.
* config/aarch64/aarch64-protos.h (aarch64_output_simd_xor_imm): New
prototype.
(aarch64_simd_valid_xor_imm): New prototype.
* config/aarch64/aarch64-simd.md (xor<mode>3<vczle><vczbe>):
Use aarch64_reg_or_xor_imm predicate and add an immediate alternative.
* config/aarch64/predicates.md (aarch64_reg_or_xor_imm): Add new
predicate.
gcc/testsuite/ChangeLog:
* gcc.target/aarch64/sve/simd_imm.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/aarch64/aarch64-protos.h | 2 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64-simd.md | 12 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64.cc | 22 | ||||
-rw-r--r-- | gcc/config/aarch64/predicates.md | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/sve/simd_imm.c | 35 |
5 files changed, 70 insertions, 6 deletions
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index e789ca9..06aa0aa 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -827,6 +827,7 @@ char *aarch64_output_scalar_simd_mov_immediate (rtx, scalar_int_mode); char *aarch64_output_simd_mov_imm (rtx, unsigned); char *aarch64_output_simd_orr_imm (rtx, unsigned); char *aarch64_output_simd_and_imm (rtx, unsigned); +char *aarch64_output_simd_xor_imm (rtx, unsigned); char *aarch64_output_sve_mov_immediate (rtx); char *aarch64_output_sve_ptrues (rtx); @@ -844,6 +845,7 @@ bool aarch64_sve_ptrue_svpattern_p (rtx, struct simd_immediate_info *); bool aarch64_simd_valid_and_imm (rtx); bool aarch64_simd_valid_mov_imm (rtx); bool aarch64_simd_valid_orr_imm (rtx); +bool aarch64_simd_valid_xor_imm (rtx); bool aarch64_valid_sysreg_name_p (const char *); const char *aarch64_retrieve_sysreg (const char *, bool, bool); rtx aarch64_check_zero_based_sve_index_immediate (rtx); diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index bf48634..8826f9d 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -1144,12 +1144,16 @@ [(set_attr "type" "neon_logic<q>")] ) +;; For EOR (vector, register) and SVE EOR (vector, immediate) (define_insn "xor<mode>3<vczle><vczbe>" - [(set (match_operand:VDQ_I 0 "register_operand" "=w") - (xor:VDQ_I (match_operand:VDQ_I 1 "register_operand" "w") - (match_operand:VDQ_I 2 "register_operand" "w")))] + [(set (match_operand:VDQ_I 0 "register_operand") + (xor:VDQ_I (match_operand:VDQ_I 1 "register_operand") + (match_operand:VDQ_I 2 "aarch64_reg_or_xor_imm")))] "TARGET_SIMD" - "eor\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>" + {@ [ cons: =0 , 1 , 2 ] + [ w , w , w ] eor\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype> + [ w , 0 , Do ] << aarch64_output_simd_xor_imm (operands[2], <bitsize>); + } [(set_attr "type" "neon_logic<q>")] ) diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index 614f99e..3e1d674 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -134,7 +134,8 @@ constexpr auto AARCH64_STATE_OUT = 1U << 2; enum simd_immediate_check { AARCH64_CHECK_MOV, AARCH64_CHECK_ORR, - AARCH64_CHECK_AND + AARCH64_CHECK_AND, + AARCH64_CHECK_XOR }; /* Information about a legitimate vector immediate operand. */ @@ -23354,6 +23355,13 @@ aarch64_simd_valid_and_imm (rtx op) return aarch64_simd_valid_imm (op, NULL, AARCH64_CHECK_AND); } +/* Return true if OP is a valid SIMD xor immediate for SVE. */ +bool +aarch64_simd_valid_xor_imm (rtx op) +{ + return aarch64_simd_valid_imm (op, NULL, AARCH64_CHECK_XOR); +} + /* Check whether X is a VEC_SERIES-like constant that starts at 0 and has a step in the range of INDEX. Return the index expression if so, otherwise return null. */ @@ -25460,10 +25468,12 @@ aarch64_output_simd_imm (rtx const_vector, unsigned width, } else { - /* AARCH64_CHECK_ORR or AARCH64_CHECK_AND. */ + /* AARCH64_CHECK_ORR, AARCH64_CHECK_AND or AARCH64_CHECK_XOR. */ mnemonic = "orr"; if (which == AARCH64_CHECK_AND) mnemonic = info.insn == simd_immediate_info::MVN ? "bic" : "and"; + else if (which == AARCH64_CHECK_XOR) + mnemonic = "eor"; if (info.insn == simd_immediate_info::SVE_MOV) { @@ -25501,6 +25511,14 @@ aarch64_output_simd_and_imm (rtx const_vector, unsigned width) return aarch64_output_simd_imm (const_vector, width, AARCH64_CHECK_AND); } +/* Returns the string with the EOR instruction for the SIMD immediate + CONST_VECTOR of WIDTH bits. */ +char* +aarch64_output_simd_xor_imm (rtx const_vector, unsigned width) +{ + return aarch64_output_simd_imm (const_vector, width, AARCH64_CHECK_XOR); +} + /* Returns the string with the MOV instruction for the SIMD immediate CONST_VECTOR of WIDTH bits. */ char* diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md index 2c18af9..6ad9a4b 100644 --- a/gcc/config/aarch64/predicates.md +++ b/gcc/config/aarch64/predicates.md @@ -125,6 +125,11 @@ (and (match_code "const_vector") (match_test "aarch64_simd_valid_and_imm (op)")))) +(define_predicate "aarch64_reg_or_xor_imm" + (ior (match_operand 0 "register_operand") + (and (match_code "const_vector") + (match_test "aarch64_simd_valid_xor_imm (op)")))) + (define_predicate "aarch64_fp_compare_operand" (ior (match_operand 0 "register_operand") (and (match_code "const_double") diff --git a/gcc/testsuite/gcc.target/aarch64/sve/simd_imm.c b/gcc/testsuite/gcc.target/aarch64/sve/simd_imm.c new file mode 100644 index 0000000..9d151d4 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/simd_imm.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ + +#include <arm_neon.h> + +/* +** t1: +** and z[0-9]+.s, z[0-9]+.s, #?3 +** ret +*/ +uint32x2_t t1 (uint32x2_t a) +{ + return vand_u32 (a, vdup_n_u32 (3)); +} + +/* +** t2: +** orr z[0-9]+.s, z[0-9]+.s, #?-3 +** ret +*/ +uint32x2_t t2 (uint32x2_t a) +{ + return vorr_u32 (a, vdup_n_u32 (~2)); +} + +/* +** t3: +** eor z[0-9]+.s, z[0-9]+.s, #?3 +** ret +*/ +uint32x2_t t3 (uint32x2_t a) +{ + return veor_u32 (a, vdup_n_u32 (3)); +} |