https://gcc.gnu.org/g:c49950f196b8124addf8f3dcbeaa51ae322ec6c8
commit r17-4018-gc49950f196b8124addf8f3dcbeaa51ae322ec6c8 Author: Dhruv Chawla <[email protected]> Date: Thu Sep 3 06:00:05 2026 +0000 aarch64: Make NEON_FUNCTION a variadic macro This patch changes the NEON_FUNCTION macro used with the pragma-based framework to be a variadic macro which can accept (currently) up to 10 intrinsics which map to the same GIMPLE handler class (including the arguments). It ports the existing intrinsics to this new macro. This helps in reducing the redundancy in specifying what the intrinsics map to. The trailing comma is still required when there are no arguments to the handler class. Bootstrapped and regtested on aarch64-linux.gnu. Signed-off-by: Dhruv Chawla <[email protected]> gcc/ChangeLog: * config/aarch64/aarch64-neon-builtins-base.cc: Merge NEON_FUNCTION macro instances having the same CLASS and ARGS arguments. * config/aarch64/aarch64-neon-builtins-functions.h (NEON_FUNCTION): Convert to a variadic macro and rename from this ... (NEON_FUNCTION_IMPL): ... to this. (NEON_FUNCTION_COUNT_IMPL): New macro. (NEON_FUNCTION_COUNT): Likewise. (NEON_FUNCTION_N_3): Likewise. (NEON_FUNCTION_N_4): Likewise. (NEON_FUNCTION_N_5): Likewise. (NEON_FUNCTION_N_6): Likewise. (NEON_FUNCTION_N_7): Likewise. (NEON_FUNCTION_N_8): Likewise. (NEON_FUNCTION_N_9): Likewise. (NEON_FUNCTION_N_10): Likewise. (NEON_FUNCTION_N_11): Likewise. (NEON_FUNCTION_N_12): Likewise. (NEON_FUNCTION_2): Likewise. (NEON_FUNCTION_1): Likewise. Diff: --- gcc/config/aarch64/aarch64-neon-builtins-base.cc | 105 +++++++-------------- .../aarch64/aarch64-neon-builtins-functions.h | 54 ++++++++++- 2 files changed, 85 insertions(+), 74 deletions(-) diff --git a/gcc/config/aarch64/aarch64-neon-builtins-base.cc b/gcc/config/aarch64/aarch64-neon-builtins-base.cc index d8fae81388e5..0313eb49759e 100644 --- a/gcc/config/aarch64/aarch64-neon-builtins-base.cc +++ b/gcc/config/aarch64/aarch64-neon-builtins-base.cc @@ -721,32 +721,17 @@ struct gimple_reinterpret : public gimple_function_base }; // Reinterpret -NEON_FUNCTION (vreinterpret, gimple_reinterpret,) -NEON_FUNCTION (vreinterpretq, gimple_reinterpret,) +NEON_FUNCTION (vreinterpret, vreinterpretq, gimple_reinterpret,) // Lane get/set -NEON_FUNCTION (vget_lane, gimple_get_lane,) -NEON_FUNCTION (vgetq_lane, gimple_get_lane,) -NEON_FUNCTION (vget_low, gimple_get_half<false>,) -NEON_FUNCTION (vget_high, gimple_get_half<true>,) -NEON_FUNCTION (vset_lane, gimple_set_lane,) -NEON_FUNCTION (vsetq_lane, gimple_set_lane,) -NEON_FUNCTION (vcopy_lane, gimple_copy_lane,) -NEON_FUNCTION (vcopy_laneq, gimple_copy_lane,) -NEON_FUNCTION (vcopyq_laneq, gimple_copy_lane,) -NEON_FUNCTION (vcopyq_lane, gimple_copy_lane,) -NEON_FUNCTION (vdup_lane, gimple_dup_lane,) -NEON_FUNCTION (vdupq_lane, gimple_dup_lane,) -NEON_FUNCTION (vdup_laneq, gimple_dup_lane,) -NEON_FUNCTION (vdupq_laneq, gimple_dup_lane,) -NEON_FUNCTION (vdupb_lane, gimple_get_lane,) -NEON_FUNCTION (vdupb_laneq, gimple_get_lane,) -NEON_FUNCTION (vduph_lane, gimple_get_lane,) -NEON_FUNCTION (vduph_laneq, gimple_get_lane,) -NEON_FUNCTION (vdups_lane, gimple_get_lane,) -NEON_FUNCTION (vdups_laneq, gimple_get_lane,) -NEON_FUNCTION (vdupd_lane, gimple_get_lane,) -NEON_FUNCTION (vdupd_laneq, gimple_get_lane,) +NEON_FUNCTION (vget_lane, vgetq_lane, gimple_get_lane,) +NEON_FUNCTION (vget_low, gimple_get_half<false>,) +NEON_FUNCTION (vget_high, gimple_get_half<true>,) +NEON_FUNCTION (vset_lane, vsetq_lane, gimple_set_lane,) +NEON_FUNCTION (vcopy_lane, vcopy_laneq, vcopyq_laneq, vcopyq_lane, gimple_copy_lane,) +NEON_FUNCTION (vdup_lane, vdupq_lane, vdup_laneq, vdupq_laneq, gimple_dup_lane,) +NEON_FUNCTION (vdupb_lane, vdupb_laneq, vduph_lane, vduph_laneq, + vdups_lane, vdups_laneq, vdupd_lane, vdupd_laneq, gimple_get_lane,) // Lanewise arithmetic NEON_FUNCTION (vaddd, gimple_expr, (PLUS_EXPR)) @@ -754,22 +739,14 @@ NEON_FUNCTION (vadd, gimple_expr, (PLUS_EXPR, PLUS_EXPR, BIT_XOR_EXPR)) NEON_FUNCTION (vaddq, gimple_expr, (PLUS_EXPR, PLUS_EXPR, BIT_XOR_EXPR)) // Bitwise operations -NEON_FUNCTION (vand, gimple_expr, (BIT_AND_EXPR)) -NEON_FUNCTION (vandq, gimple_expr, (BIT_AND_EXPR)) -NEON_FUNCTION (vbic, gimple_not_rhs, (BIT_AND_EXPR)) -NEON_FUNCTION (vbicq, gimple_not_rhs, (BIT_AND_EXPR)) -NEON_FUNCTION (vbsl, gimple_bsl,) -NEON_FUNCTION (vbslq, gimple_bsl,) -NEON_FUNCTION (veor, gimple_expr, (BIT_XOR_EXPR)) -NEON_FUNCTION (veorq, gimple_expr, (BIT_XOR_EXPR)) -NEON_FUNCTION (vmvn, gimple_expr, (BIT_NOT_EXPR)) -NEON_FUNCTION (vmvnq, gimple_expr, (BIT_NOT_EXPR)) -NEON_FUNCTION (vorn, gimple_not_rhs, (BIT_IOR_EXPR)) -NEON_FUNCTION (vornq, gimple_not_rhs, (BIT_IOR_EXPR)) -NEON_FUNCTION (vorr, gimple_expr, (BIT_IOR_EXPR)) -NEON_FUNCTION (vorrq, gimple_expr, (BIT_IOR_EXPR)) -NEON_FUNCTION (vrbit, gimple_ifn, (IFN_BITREVERSE)) -NEON_FUNCTION (vrbitq, gimple_ifn, (IFN_BITREVERSE)) +NEON_FUNCTION (vand, vandq, gimple_expr, (BIT_AND_EXPR)) +NEON_FUNCTION (vbic, vbicq, gimple_not_rhs, (BIT_AND_EXPR)) +NEON_FUNCTION (vbsl, vbslq, gimple_bsl,) +NEON_FUNCTION (veor, veorq, gimple_expr, (BIT_XOR_EXPR)) +NEON_FUNCTION (vmvn, vmvnq, gimple_expr, (BIT_NOT_EXPR)) +NEON_FUNCTION (vorn, vornq, gimple_not_rhs, (BIT_IOR_EXPR)) +NEON_FUNCTION (vorr, vorrq, gimple_expr, (BIT_IOR_EXPR)) +NEON_FUNCTION (vrbit, vrbitq, gimple_ifn, (IFN_BITREVERSE)) // Bitwise operations (SHA3) NEON_FUNCTION (vbcaxq, gimple_bcax,) @@ -778,47 +755,31 @@ NEON_FUNCTION (vrax1q, gimple_rax1,) NEON_FUNCTION (vxarq, gimple_xar,) // Bit counting operations -NEON_FUNCTION (vcls, gimple_ifn, (IFN_CLRSB)) -NEON_FUNCTION (vclsq, gimple_ifn, (IFN_CLRSB)) -NEON_FUNCTION (vclz, gimple_ifn, (IFN_CLZ)) -NEON_FUNCTION (vclzq, gimple_ifn, (IFN_CLZ)) -NEON_FUNCTION (vcnt, gimple_ifn, (IFN_POPCOUNT)) -NEON_FUNCTION (vcntq, gimple_ifn, (IFN_POPCOUNT)) +NEON_FUNCTION (vcls, vclsq, gimple_ifn, (IFN_CLRSB)) +NEON_FUNCTION (vclz, vclzq, gimple_ifn, (IFN_CLZ)) +NEON_FUNCTION (vcnt, vcntq, gimple_ifn, (IFN_POPCOUNT)) // Permutations // Extract -NEON_FUNCTION (vext, gimple_permute, (ext_mask)) -NEON_FUNCTION (vextq, gimple_permute, (ext_mask)) +NEON_FUNCTION (vext, vextq, gimple_permute, (ext_mask)) // Reverse -NEON_FUNCTION (vrev16, gimple_permute, (rev_mask<16>)) -NEON_FUNCTION (vrev16q, gimple_permute, (rev_mask<16>)) -NEON_FUNCTION (vrev32, gimple_permute, (rev_mask<32>)) -NEON_FUNCTION (vrev32q, gimple_permute, (rev_mask<32>)) -NEON_FUNCTION (vrev64, gimple_permute, (rev_mask<64>)) -NEON_FUNCTION (vrev64q, gimple_permute, (rev_mask<64>)) +NEON_FUNCTION (vrev16, vrev16q, gimple_permute, (rev_mask<16>)) +NEON_FUNCTION (vrev32, vrev32q, gimple_permute, (rev_mask<32>)) +NEON_FUNCTION (vrev64, vrev64q, gimple_permute, (rev_mask<64>)) // Transpose -NEON_FUNCTION (vtrn1, gimple_permute, (trn_mask<false>)) -NEON_FUNCTION (vtrn1q, gimple_permute, (trn_mask<false>)) -NEON_FUNCTION (vtrn2, gimple_permute, (trn_mask<true>)) -NEON_FUNCTION (vtrn2q, gimple_permute, (trn_mask<true>)) -NEON_FUNCTION (vtrn, gimple_permute_pair, (trn_mask<false>, trn_mask<true>)) -NEON_FUNCTION (vtrnq, gimple_permute_pair, (trn_mask<false>, trn_mask<true>)) +NEON_FUNCTION (vtrn1, vtrn1q, gimple_permute, (trn_mask<false>)) +NEON_FUNCTION (vtrn2, vtrn2q, gimple_permute, (trn_mask<true>)) +NEON_FUNCTION (vtrn, vtrnq, gimple_permute_pair, (trn_mask<false>, trn_mask<true>)) // Unzip -NEON_FUNCTION (vuzp1, gimple_permute, (uzp_mask<false>)) -NEON_FUNCTION (vuzp1q, gimple_permute, (uzp_mask<false>)) -NEON_FUNCTION (vuzp2, gimple_permute, (uzp_mask<true>)) -NEON_FUNCTION (vuzp2q, gimple_permute, (uzp_mask<true>)) -NEON_FUNCTION (vuzp, gimple_permute_pair, (uzp_mask<false>, uzp_mask<true>)) -NEON_FUNCTION (vuzpq, gimple_permute_pair, (uzp_mask<false>, uzp_mask<true>)) +NEON_FUNCTION (vuzp1, vuzp1q, gimple_permute, (uzp_mask<false>)) +NEON_FUNCTION (vuzp2, vuzp2q, gimple_permute, (uzp_mask<true>)) +NEON_FUNCTION (vuzp, vuzpq, gimple_permute_pair, (uzp_mask<false>, uzp_mask<true>)) // Zip -NEON_FUNCTION (vzip1, gimple_permute, (zip_mask<false>)) -NEON_FUNCTION (vzip1q, gimple_permute, (zip_mask<false>)) -NEON_FUNCTION (vzip2, gimple_permute, (zip_mask<true>)) -NEON_FUNCTION (vzip2q, gimple_permute, (zip_mask<true>)) -NEON_FUNCTION (vzip, gimple_permute_pair, (zip_mask<false>, zip_mask<true>)) -NEON_FUNCTION (vzipq, gimple_permute_pair, (zip_mask<false>, zip_mask<true>)) +NEON_FUNCTION (vzip1, vzip1q, gimple_permute, (zip_mask<false>)) +NEON_FUNCTION (vzip2, vzip2q, gimple_permute, (zip_mask<true>)) +NEON_FUNCTION (vzip, vzipq, gimple_permute_pair, (zip_mask<false>, zip_mask<true>)) } diff --git a/gcc/config/aarch64/aarch64-neon-builtins-functions.h b/gcc/config/aarch64/aarch64-neon-builtins-functions.h index 58a631ac54e0..b5677f64a862 100644 --- a/gcc/config/aarch64/aarch64-neon-builtins-functions.h +++ b/gcc/config/aarch64/aarch64-neon-builtins-functions.h @@ -22,8 +22,58 @@ /* Declare the global function base NAME, creating it from an instance of class CLASS with constructor arguments ARGS. */ -#define NEON_FUNCTION(NAME, CLASS, ARGS) \ - namespace { static constexpr const CLASS NAME##_obj ARGS; } \ +#define NEON_FUNCTION_IMPL(NAME, CLASS, ARGS) \ + namespace { static constexpr const CLASS NAME##_obj ARGS; } \ const function_base *const aarch64_acle::functions::NAME = &NAME##_obj; +/* Count the number of arguments passed as input (upto 12). Push a sequence + rightwards using __VA_ARGS__ and have N fall onto the correct element in + it. */ +#define NEON_FUNCTION_COUNT_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, \ + _12, N, ...) N +#define NEON_FUNCTION_COUNT(...) \ + NEON_FUNCTION_COUNT_IMPL (__VA_ARGS__, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, \ + 1, 0) + +/* Base case, where only one intrinsic is being mapped. The sequence must start + with 3 as there are three minimum arguments: NAME, CLASS, ARGS (even if + ARGS is empty). */ +#define NEON_FUNCTION_N_3(N1, C, A) NEON_FUNCTION_IMPL (N1, C, A) +/* For all other cases: define 1..(N-1) intrinsics by falling through, then + define the Nth one. */ +#define NEON_FUNCTION_N_4(N1, N2, C, A) \ + NEON_FUNCTION_N_3 (N1, C, A) \ + NEON_FUNCTION_IMPL (N2, C, A) +#define NEON_FUNCTION_N_5(N1, N2, N3, C, A) \ + NEON_FUNCTION_N_4 (N1, N2, C, A) \ + NEON_FUNCTION_IMPL (N3, C, A) +#define NEON_FUNCTION_N_6(N1, N2, N3, N4, C, A) \ + NEON_FUNCTION_N_5 (N1, N2, N3, C, A) \ + NEON_FUNCTION_IMPL (N4, C, A) +#define NEON_FUNCTION_N_7(N1, N2, N3, N4, N5, C, A) \ + NEON_FUNCTION_N_6 (N1, N2, N3, N4, C, A) \ + NEON_FUNCTION_IMPL (N5, C, A) +#define NEON_FUNCTION_N_8(N1, N2, N3, N4, N5, N6, C, A) \ + NEON_FUNCTION_N_7 (N1, N2, N3, N4, N5, C, A) \ + NEON_FUNCTION_IMPL (N6, C, A) +#define NEON_FUNCTION_N_9(N1, N2, N3, N4, N5, N6, N7, C, A) \ + NEON_FUNCTION_N_8 (N1, N2, N3, N4, N5, N6, C, A) \ + NEON_FUNCTION_IMPL (N7, C, A) +#define NEON_FUNCTION_N_10(N1, N2, N3, N4, N5, N6, N7, N8, C, A) \ + NEON_FUNCTION_N_9 (N1, N2, N3, N4, N5, N6, N7, C, A) \ + NEON_FUNCTION_IMPL (N8, C, A) +#define NEON_FUNCTION_N_11(N1, N2, N3, N4, N5, N6, N7, N8, N9, C, A) \ + NEON_FUNCTION_N_10 (N1, N2, N3, N4, N5, N6, N7, N8, C, A) \ + NEON_FUNCTION_IMPL (N9, C, A) +#define NEON_FUNCTION_N_12(N1, N2, N3, N4, N5, N6, N7, N8, N9, N10, C, A) \ + NEON_FUNCTION_N_11 (N1, N2, N3, N4, N5, N6, N7, N8, N9, C, A) \ + NEON_FUNCTION_IMPL (N10, C, A) + +/* Count the number of arguments (including CLASS and ARGS) and dispatch to the + relevant handler macro. */ +#define NEON_FUNCTION_2(N, ...) NEON_FUNCTION_N_##N (__VA_ARGS__) +#define NEON_FUNCTION_1(N, ...) NEON_FUNCTION_2 (N, __VA_ARGS__) +#define NEON_FUNCTION(...) \ + NEON_FUNCTION_1 (NEON_FUNCTION_COUNT (__VA_ARGS__), __VA_ARGS__) + #endif
