Victor Do Nascimento <[email protected]> writes:
> The introduction of further architectural-feature dependent ifuncs
> for AArch64 makes hard-coding ifunc `_i<n>' suffixes to functions
> cumbersome to work with. It is awkward to remember which ifunc maps
> onto which arch feature and makes the code harder to maintain when new
> ifuncs are added and their suffixes possibly altered.
>
> This patch uses pre-processor `#define' statements to map each suffix to
> a descriptive feature name macro, for example:
>
> #define LSE2 _i1
>
> and reconstructs function names with the pre-processor's token
> concatenation feature, such that for `MACRO(<name>_i<n>)', we would
> now have `MACRO_FEAT(name, feature)' and in the macro definition body
> we replace `name` with `name##feature`.
FWIW, another way of doing this would be to have:
#define CORE(NAME) NAME
#define LSE2(NAME) NAME##_i1
and use feature(name) instead of name##feature. This has the slight
advantage of not using ## on empty tokens, and the maybe slightly
better advantage of not needing the extra forwarding step in:
#define ENTRY_FEAT(name, feat) \
ENTRY_FEAT1(name, feat)
#define ENTRY_FEAT1(name, feat) \
WDYT?
Richard
> Consequently, for base functionality, where the ifunc suffix is
> absent, the macro interface remains the same. For example, the entry
> and endpoints of `libat_store_16' remain defined by:
>
> - ENTRY (libat_store_16)
> and
> - END (libat_store_16)
>
> For the LSE2 implementation of the same 16-byte atomic store, we now
> have:
>
> - ENTRY_FEAT (libat_store_16, LSE2)
> and
> - END_FEAT (libat_store_16, LSE2)
>
> For the alising of ifunc names, we define the following new
> implementation of the ALIAS macro:
>
> - ALIAS (FN_BASE_NAME, FROM_SUFFIX, TO_SUFFIX)
>
> Defining the base feature name macro to map `CORE' to the empty string,
> mapping LSE2 to the base implementation, we'd alias the LSE2
> `libat_exchange_16' to it base implementation with:
>
> - ALIAS (libat_exchange_16, LSE2, CORE)
>
> libatomic/ChangeLog:
> * config/linux/aarch64/atomic_16.S (CORE): New macro.
> (LSE2): Likewise.
> (ENTRY_FEAT): Likewise.
> (END_FEAT): Likewise.
> (ENTRY_FEAT1): Likewise.
> (END_FEAT1): Likewise.
> (ALIAS): Modify macro to take in `arch' arguments.
> ---
> libatomic/config/linux/aarch64/atomic_16.S | 83 +++++++++++++---------
> 1 file changed, 49 insertions(+), 34 deletions(-)
>
> diff --git a/libatomic/config/linux/aarch64/atomic_16.S
> b/libatomic/config/linux/aarch64/atomic_16.S
> index a099037179b..eb8e749b8a2 100644
> --- a/libatomic/config/linux/aarch64/atomic_16.S
> +++ b/libatomic/config/linux/aarch64/atomic_16.S
> @@ -40,22 +40,38 @@
>
> .arch armv8-a+lse
>
> -#define ENTRY(name) \
> - .global name; \
> - .hidden name; \
> - .type name,%function; \
> - .p2align 4; \
> -name: \
> - .cfi_startproc; \
> +#define ENTRY(name) ENTRY_FEAT (name, CORE)
> +
> +#define ENTRY_FEAT(name, feat) \
> + ENTRY_FEAT1(name, feat)
> +
> +#define ENTRY_FEAT1(name, feat) \
> + .global name##feat; \
> + .hidden name##feat; \
> + .type name##feat,%function; \
> + .p2align 4; \
> +name##feat: \
> + .cfi_startproc; \
> hint 34 // bti c
>
> -#define END(name) \
> - .cfi_endproc; \
> - .size name, .-name;
> +#define END(name) END_FEAT (name, CORE)
>
> -#define ALIAS(alias,name) \
> - .global alias; \
> - .set alias, name;
> +#define END_FEAT(name, feat) \
> + END_FEAT1(name, feat)
> +
> +#define END_FEAT1(name, feat) \
> + .cfi_endproc; \
> + .size name##feat, .-name##feat;
> +
> +#define ALIAS(alias, from, to) \
> + ALIAS1(alias,from,to)
> +
> +#define ALIAS1(alias, from, to) \
> + .global alias##from; \
> + .set alias##from, alias##to;
> +
> +#define CORE
> +#define LSE2 _i1
>
> #define res0 x0
> #define res1 x1
> @@ -108,7 +124,7 @@ ENTRY (libat_load_16)
> END (libat_load_16)
>
>
> -ENTRY (libat_load_16_i1)
> +ENTRY_FEAT (libat_load_16, LSE2)
> cbnz w1, 1f
>
> /* RELAXED. */
> @@ -128,7 +144,7 @@ ENTRY (libat_load_16_i1)
> ldp res0, res1, [x0]
> dmb ishld
> ret
> -END (libat_load_16_i1)
> +END_FEAT (libat_load_16, LSE2)
>
>
> ENTRY (libat_store_16)
> @@ -148,7 +164,7 @@ ENTRY (libat_store_16)
> END (libat_store_16)
>
>
> -ENTRY (libat_store_16_i1)
> +ENTRY_FEAT (libat_store_16, LSE2)
> cbnz w4, 1f
>
> /* RELAXED. */
> @@ -160,7 +176,7 @@ ENTRY (libat_store_16_i1)
> stlxp w4, in0, in1, [x0]
> cbnz w4, 1b
> ret
> -END (libat_store_16_i1)
> +END_FEAT (libat_store_16, LSE2)
>
>
> ENTRY (libat_exchange_16)
> @@ -237,7 +253,7 @@ ENTRY (libat_compare_exchange_16)
> END (libat_compare_exchange_16)
>
>
> -ENTRY (libat_compare_exchange_16_i1)
> +ENTRY_FEAT (libat_compare_exchange_16, LSE2)
> ldp exp0, exp1, [x1]
> mov tmp0, exp0
> mov tmp1, exp1
> @@ -270,7 +286,7 @@ ENTRY (libat_compare_exchange_16_i1)
> /* ACQ_REL/SEQ_CST. */
> 4: caspal exp0, exp1, in0, in1, [x0]
> b 0b
> -END (libat_compare_exchange_16_i1)
> +END_FEAT (libat_compare_exchange_16, LSE2)
>
>
> ENTRY (libat_fetch_add_16)
> @@ -556,21 +572,20 @@ END (libat_test_and_set_16)
>
> /* Alias entry points which are the same in baseline and LSE2. */
>
> -ALIAS (libat_exchange_16_i1, libat_exchange_16)
> -ALIAS (libat_fetch_add_16_i1, libat_fetch_add_16)
> -ALIAS (libat_add_fetch_16_i1, libat_add_fetch_16)
> -ALIAS (libat_fetch_sub_16_i1, libat_fetch_sub_16)
> -ALIAS (libat_sub_fetch_16_i1, libat_sub_fetch_16)
> -ALIAS (libat_fetch_or_16_i1, libat_fetch_or_16)
> -ALIAS (libat_or_fetch_16_i1, libat_or_fetch_16)
> -ALIAS (libat_fetch_and_16_i1, libat_fetch_and_16)
> -ALIAS (libat_and_fetch_16_i1, libat_and_fetch_16)
> -ALIAS (libat_fetch_xor_16_i1, libat_fetch_xor_16)
> -ALIAS (libat_xor_fetch_16_i1, libat_xor_fetch_16)
> -ALIAS (libat_fetch_nand_16_i1, libat_fetch_nand_16)
> -ALIAS (libat_nand_fetch_16_i1, libat_nand_fetch_16)
> -ALIAS (libat_test_and_set_16_i1, libat_test_and_set_16)
> -
> +ALIAS (libat_exchange_16, LSE2, CORE)
> +ALIAS (libat_fetch_add_16, LSE2, CORE)
> +ALIAS (libat_add_fetch_16, LSE2, CORE)
> +ALIAS (libat_fetch_sub_16, LSE2, CORE)
> +ALIAS (libat_sub_fetch_16, LSE2, CORE)
> +ALIAS (libat_fetch_or_16, LSE2, CORE)
> +ALIAS (libat_or_fetch_16, LSE2, CORE)
> +ALIAS (libat_fetch_and_16, LSE2, CORE)
> +ALIAS (libat_and_fetch_16, LSE2, CORE)
> +ALIAS (libat_fetch_xor_16, LSE2, CORE)
> +ALIAS (libat_xor_fetch_16, LSE2, CORE)
> +ALIAS (libat_fetch_nand_16, LSE2, CORE)
> +ALIAS (libat_nand_fetch_16, LSE2, CORE)
> +ALIAS (libat_test_and_set_16, LSE2, CORE)
>
> /* GNU_PROPERTY_AARCH64_* macros from elf.h for use in asm code. */
> #define FEATURE_1_AND 0xc0000000