aboutsummaryrefslogtreecommitdiff
path: root/libatomic/config/linux
AgeCommit message (Collapse)AuthorFilesLines
2024-06-25libatomic: Add rcpc3 128-bit atomic operations for AArch64Victor Do Nascimento2-6/+74
The introduction of the optional RCPC3 architectural extension for Armv8.2-A upwards provides additional support for the release consistency model, introducing the Load-Acquire RCpc Pair Ordered, and Store-Release Pair Ordered operations in the form of LDIAPP and STILP. These operations are single-copy atomic on cores which also implement LSE2 and, as such, support for these operations is added to Libatomic and employed accordingly when the LSE2 and RCPC3 features are detected in a given core at runtime. libatomic/ChangeLog: * config/linux/aarch64/atomic_16.S (libat_load_16): Add LRCPC3 variant. (libat_store_16): Likewise. * config/linux/aarch64/host-config.h (HWCAP2_LRCPC3): New. (LSE2_LRCPC3_ATOP): Previously LSE2_ATOP. New ifuncs guarded under it. (has_rcpc3): New.
2024-06-12Libatomic: Clean up AArch64 `atomic_16.S' implementation fileVictor Do Nascimento1-222/+223
At present, `atomic_16.S' groups different implementations of the same functions together in the file. Therefore, as an example, the LSE2 implementation of `load_16' follows on immediately from its core implementation, as does the `store_16' LSE2 implementation. Such architectural extension-dependent implementations are dependent on ifunc support, such that they are guarded by the relevant preprocessor macro, i.e. `#if HAVE_IFUNC'. Having to apply these guards on a per-function basis adds unnecessary clutter to the file and makes its maintenance more error-prone. We therefore reorganize the layout of the file in such a way that all core implementations needing no `#ifdef's are placed first, followed by all ifunc-dependent implementations, which can all be guarded by a single `#if HAVE_IFUNC', greatly reducing the overall number of required `#ifdef' macros. libatomic/ChangeLog: * config/linux/aarch64/atomic_16.S: Reorganize functions in file. (HAVE_FEAT_LSE2): Delete.
2024-06-12Libatomic: Make ifunc selector behavior contingent on importing fileVictor Do Nascimento2-54/+45
By querying previously-defined file-identifier macros, `host-config.h' is able to get information about its environment and, based on this information, select more appropriate function-specific ifunc selectors. This reduces the number of unnecessary feature tests that need to be carried out in order to find the best atomic implementation for a function at run-time. An immediate benefit of this is that we can further fine-tune the architectural requirements for each atomic function without risk of incurring the maintenance and runtime-performance penalties of having to maintain an ifunc selector with a huge number of alternatives, most of which are irrelevant for any particular function. Consequently, for AArch64 targets, we relax the architectural requirements of `compare_exchange_16', which now requires only LSE as opposed to the newer LSE2. The new flexibility provided by this approach also means that certain functions can now be called directly, doing away with ifunc selectors altogether when only a single implementation is available for it on a given target. As per the macro expansion framework laid out in `libatomic_i.h', such functions should have their names prefixed with `__atomic_' as opposed to `libat_'. This is the same prefix applied to function names when Libatomic is configured with `--disable-gnu-indirect-function'. To achieve this, these functions unconditionally apply the aliasing rule that at present is conditionally applied only when libatomic is built without ifunc support, which ensures that the default `libat_##NAME' is accessible via the equivalent `__atomic_##NAME' too. This is ensured by using the new `ENTRY_ALIASED' macro. Finally, this means we are able to do away with a whole set of function aliases that were needed until now, thus considerably cleaning up the implementation. libatomic/ChangeLog: * config/linux/aarch64/atomic_16.S: Remove unnecessary aliasing. (LSE): New. (ENTRY_ALIASED): Likewise. * config/linux/aarch64/host-config.h (LSE_ATOP): New. (LSE2_ATOP): Likewise. (LSE128_ATOP): Likewise. (IFUNC_COND_1): Make its definition conditional on above 3 macros. (IFUNC_NCOND): Likewise.
2024-06-12Libatomic: AArch64: Convert all lse128 assembly to .insn directivesVictor Do Nascimento1-44/+32
Given the lack of support for the LSE128 instructions in all but the the most up-to-date version of Binutils (2.42), having the build-time test for assembler support for these instructions often leads to the building of Libatomic without support for LSE128-dependent atomic function implementations. This ultimately leads to different people having different versions of Libatomic on their machines, depending on which assembler was available at compilation time. Furthermore, the conditional inclusion of these atomic function implementations predicated on assembler support leads to a series of `#if HAVE_FEAT_LSE128' guards scattered throughout the codebase and the need for a series of aliases when the feature flag evaluates to false. The preprocessor macro guards, together with the conditional aliasing leads to code that is cumbersome to understand and maintain. Both of the issues highlighted above will only get worse with the coming support for LRCPC3 atomics which under the current scheme will also require build-time checks. Consequently, a better option for both consistency across builds and code cleanness is to make recourse to the `.inst' directive. By replacing all novel assembly instructions for their hexadecimal representation within `.inst's, we ensure that the Libatomic code is both considerably cleaner and all machines build the same binary, irrespective of binutils version available at compile time. This patch therefore removes all configure checks for LSE128-support in the assembler and all the guards and aliases that were associated with `HAVE_FEAT_LSE128' libatomic/ChangeLog: * acinclude.m4 (LIBAT_TEST_FEAT_AARCH64_LSE128): Delete. * auto-config.h.in (HAVE_FEAT_LSE128): Likewise * config/linux/aarch64/atomic_16.S: Replace all LSE128 instructions with equivalent `.inst' directives. (HAVE_FEAT_LSE128): Remove all references. * configure: Regenerate. * configure.ac: Remove call to LIBAT_TEST_FEAT_AARCH64_LSE128.
2024-04-26libatomic: Cleanup macros in atomic_16.SWilco Dijkstra1-118/+102
Cleanup the macros to add the libat_ prefixes in atomic_16.S. Emit the alias to __atomic_<op> when ifuncs are not enabled in the ENTRY macro. libatomic: * config/linux/aarch64/atomic_16.S: Add __libat_ prefix in the LSE2/LSE128/CORE macros, remove elsewhere. Add ATOMIC macro.
2024-04-04libatomic: Fix build for --disable-gnu-indirect-function [PR113986]Wilco Dijkstra2-29/+70
Fix libatomic build to support --disable-gnu-indirect-function on AArch64. Always build atomic_16.S, add aliases to the __atomic_ functions if !HAVE_IFUNC. Include auto-config.h in atomic_16.S to avoid having to pass defines via makefiles. Fix build if HWCAP_ATOMICS/CPUID are not defined. libatomic: PR target/113986 * Makefile.in: Regenerated. * Makefile.am: Make atomic_16.S not depend on HAVE_IFUNC. Remove predefine of HAVE_FEAT_LSE128. * acinclude.m4: Remove ARCH_AARCH64_HAVE_LSE128. * configure: Regenerated. * config/linux/aarch64/atomic_16.S: Add __atomic_ alias if !HAVE_IFUNC. * config/linux/aarch64/host-config.h: Correctly handle !HAVE_IFUNC. Add defines for HWCAP_ATOMICS and HWCAP_CPUID.
2024-01-28Libatomic: Add checks in ifunc selectors for LSE/LSE2 requirements.Victor Do Nascimento1-3/+10
At present, Evaluation of both `has_lse2(hwcap)' and `has_lse128(hwcap)' may require issuing an `mrs' instruction to query a system register. This instruction, when issued from user-space results in a trap by the kernel which then returns the value read in by the system register. Given the undesirable nature of the computational expense associated with the context switch, it is important to implement mechanisms to, wherever possible, forgo the operation. In light of this, given how other architectural requirements serving as prerequisites have long been assigned HWCAP bits by the kernel, we can inexpensively query for their availability before attempting to read any system registers. Where one of these early tests fail, we can assert that the main feature of interest (be it LSE2 or LSE128) cannot be present, allowing us to return from the function early and skip the unnecessary expensive kernel-mediated access to system registers. libatomic/ChangeLog: * config/linux/aarch64/host-config.h (has_lse2): Add test for LSE. (has_lse128): Add test for LSE2.
2024-01-28libatomic: Enable LSE128 128-bit atomics for Armv9.4-aVictor Do Nascimento2-7/+205
The armv9.4-a architectural revision adds three new atomic operations associated with the LSE128 feature: * LDCLRP - Atomic AND NOT (bitclear) of a location with 128-bit value held in a pair of registers, with original data loaded into the same 2 registers. * LDSETP - Atomic OR (bitset) of a location with 128-bit value held in a pair of registers, with original data loaded into the same 2 registers. * SWPP - Atomic swap of one 128-bit value with 128-bit value held in a pair of registers. It is worth noting that in keeping with existing 128-bit atomic operations in `atomic_16.S', we have chosen to merge certain less-restrictive orderings into more restrictive ones. This is done to minimize the number of branches in the atomic functions, minimizing both the likelihood of branch mispredictions and, in keeping code small, limit the need for extra fetch cycles. Past benchmarking has revealed that acquire is typically slightly faster than release (5-10%), such that for the most frequently used atomics (CAS and SWP) it makes sense to add support for acquire, as well as release. Likewise, it was identified that combining acquire and release typically results in little to no penalty, such that it is of negligible benefit to distinguish between release and acquire-release, making the combining release/acq_rel/seq_cst a worthwhile design choice. This patch adds the logic required to make use of these when the architectural feature is present and a suitable assembler available. In order to do this, the following changes are made: 1. Add a configure-time check to check for LSE128 support in the assembler. 2. Edit host-config.h so that when N == 16, nifunc = 2. 3. Where available due to LSE128, implement the second ifunc, making use of the novel instructions. 4. For atomic functions unable to make use of these new instructions, define a new alias which causes the _i1 function variant to point ahead to the corresponding _i2 implementation. libatomic/ChangeLog: * Makefile.am (AM_CPPFLAGS): add conditional setting of -DHAVE_FEAT_LSE128. * acinclude.m4 (LIBAT_TEST_FEAT_AARCH64_LSE128): New. * config/linux/aarch64/atomic_16.S (LSE128): New macro definition. (libat_exchange_16): New LSE128 variant. (libat_fetch_or_16): Likewise. (libat_or_fetch_16): Likewise. (libat_fetch_and_16): Likewise. (libat_and_fetch_16): Likewise. * config/linux/aarch64/host-config.h (IFUNC_COND_2): New. (IFUNC_NCOND): Add operand size checking. (has_lse2): Renamed from `ifunc1`. (has_lse128): New. (HWCAP2_LSE128): Likewise. * configure.ac: Add call to LIBAT_TEST_FEAT_AARCH64_LSE128. * configure (ac_subst_vars): Regenerated via autoreconf. * Makefile.in: Likewise. * auto-config.h.in: Likewise.
2024-01-28libatomic: Add support for __ifunc_arg_t arg in ifunc resolverVictor Do Nascimento1-2/+13
With support for new atomic features in Armv9.4-a being indicated by HWCAP2 bits, Libatomic's ifunc resolver must now query its second argument, of type __ifunc_arg_t*. We therefore make this argument known to libatomic, allowing us to query hwcap2 bits in the following manner: bool resolver (unsigned long hwcap, const __ifunc_arg_t *features); { return (features->hwcap2 & HWCAP2_<FEAT_NAME>); } libatomic/ChangeLog: * config/linux/aarch64/host-config.h (__ifunc_arg_t): Conditionally-defined if `sys/ifunc.h' not found. (_IFUNC_ARG_HWCAP): Likewise. (IFUNC_COND_1): Pass __ifunc_arg_t argument to ifunc. (ifunc1): Modify function signature to accept __ifunc_arg_t argument. * configure.tgt: Add second `const __ifunc_arg_t *features' argument to IFUNC_RESOLVER_ARGS.
2024-01-28libatomic: atomic_16.S: Improve ENTRY, END and ALIAS macro interfaceVictor Do Nascimento1-32/+43
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 LSE(NAME) NAME##_i1 Where we wish to generate ifunc names with the pre-processor's token concatenation feature, we add a level of indirection to previous macro calls. If before we would have had`MACRO(<name>_i<n>)', we now have `MACRO_FEAT(name, feature)'. Where we wish to refer to base functionality (i.e., functions where ifunc suffixes are absent), the original `MACRO(<name>)' may be used to bypass suffixing. 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 aliasing of function names, we define the following new implementation of the ALIAS macro: ALIAS (FN_BASE_NAME, FROM_SUFFIX, TO_SUFFIX) Defining the `CORE(NAME)' macro to be the identity operator, it returns the base function name unaltered and allows us to alias target-specific ifuncs to the corresponding base implementation. For example, 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. (ENTRY_FEAT1): Likewise. (END_FEAT): Likewise. (END_FEAT1): Likewise. (ALIAS): Modify macro to take in `arch' arguments. (ALIAS1): New.
2024-01-03Update copyright years.Jakub Jelinek6-6/+6
2023-12-15libatomic: Enable lock-free 128-bit atomics on AArch64Wilco Dijkstra2-50/+161
Enable lock-free 128-bit atomics on AArch64. This is backwards compatible with existing binaries (as for these GCC always calls into libatomic, so all 128-bit atomic uses in a process are switched), gives better performance than locking atomics and is what most users expect. 128-bit atomic loads use a load/store exclusive loop if LSE2 is not supported. This results in an implicit store which is invisible to software as long as the given address is writeable (which will be true when using atomics in real code). This doesn't yet change __atomic_is_lock_free eventhough all atomics are finally lock-free on AArch64. libatomic: * config/linux/aarch64/atomic_16.S: Implement lock-free ARMv8.0 atomics. (libat_exchange_16): Merge RELEASE and ACQ_REL/SEQ_CST cases. * config/linux/aarch64/host-config.h: Use atomic_16.S for baseline v8.0.
2023-11-10libatomic: Improve ifunc selection on AArch64Wilco Dijkstra1-1/+25
Add support for ifunc selection based on CPUID register. Neoverse N1 supports atomic 128-bit load/store, so use the FEAT_USCAT ifunc like newer Neoverse cores. Reviewed-by: Kyrylo.Tkachov@arm.com libatomic: * config/linux/aarch64/host-config.h (ifunc1): Use CPUID in ifunc selection.
2023-03-24libatomic: Fix SEQ_CST 128-bit atomic load [PR108891]Wilco Dijkstra1-74/+115
The LSE2 ifunc for 16-byte atomic load requires a barrier before the LDP - without it, it effectively has Load-AcquirePC semantics similar to LDAPR, which is less restrictive than what __ATOMIC_SEQ_CST requires. This patch fixes this and adds comments to make it easier to see which sequence is used for each case. Use a load/store exclusive loop for store to simplify testing memory ordering is correct (it is slightly faster too). libatomic/ PR libgcc/108891 * config/linux/aarch64/atomic_16.S: Fix libat_load_16_i1. Add comments describing the memory order.
2023-01-16Update copyright years.Jakub Jelinek6-6/+6
2022-11-15libatomic: Add support for LSE and LSE2Wilco Dijkstra2-5/+475
Add support for AArch64 LSE and LSE2 to libatomic. Disable outline atomics, and use LSE ifuncs for 1-8 byte atomics and LSE2 ifuncs for 16-byte atomics. On Neoverse V1, 16-byte atomics are ~4x faster due to avoiding locks. Note this is safe since we swap all 16-byte atomics using the same ifunc, so they either use locks or LSE2 atomics, but never a mix. This also improves ABI compatibility with LLVM: its inlined 16-byte atomics are compatible with the new libatomic if LSE2 is supported. libatomic/ * Makefile.in: Regenerated with automake 1.15.1. * Makefile.am: Add atomic_16.S for AArch64. * configure.tgt: Disable outline atomics in AArch64 build. * config/linux/aarch64/atomic_16.S: New file - implementation of ifuncs for 16-byte atomics. * config/linux/aarch64/host-config.h: Enable ifuncs, use LSE (HWCAP_ATOMICS) for 1-8-byte atomics and LSE2 (HWCAP_USCAT) for 16-byte atomics.
2022-01-03Update copyright years.Jakub Jelinek5-5/+5
2021-07-21Adjust macro to avoid warning [PR101379].Martin Sebor1-1/+7
Resolves: PR bootstrap/101379 - libatomic arm build failure after r12-2132 due to -Warray-bounds on a constant address libatomic/ChangeLog: PR bootstrap/101379 * config/linux/arm/host-config.h (__kernel_helper_version): New function. Adjust shadow macro.
2021-01-04Update copyright years.Jakub Jelinek5-5/+5
2020-01-01Update copyright years.Jakub Jelinek5-5/+5
From-SVN: r279813
2019-01-01Update copyright years.Jakub Jelinek5-5/+5
From-SVN: r267494
2018-01-03Update copyright years.Jakub Jelinek5-5/+5
From-SVN: r256169
2017-12-05Makefile.am (ARCH_AARCH64_LINUX): Add IFUNC_OPTIONS and libatomic_la_LIBADD.Steve Ellcey1-0/+36
2017-12-04 Steve Ellcey <sellcey@cavium.com> * Makefile.am (ARCH_AARCH64_LINUX): Add IFUNC_OPTIONS and libatomic_la_LIBADD. * config/linux/aarch64/host-config.h: New file. * configure.ac (IFUNC_RESOLVER_ARGS): Define. (ARCH_AARCH64_LINUX): New conditional for IFUNC builds. * configure.tgt (aarch64): Set ARCH and try_ifunc. (aarch64*-*-linux*) Update config_path. (aarch64*-*-linux*) Set IFUNC_RESOLVER_ARGS. * libatomic_i.h (GEN_SELECTOR): Add IFUNC_RESOLVER_ARGS argument. * Makefile.in: Regenerate. * auto-config.h.in: Regenerate. * configure: Regenerate. From-SVN: r255399
2017-01-01Update copyright years.Jakub Jelinek4-4/+4
From-SVN: r243994
2016-01-04Update copyright years.Jakub Jelinek4-4/+4
From-SVN: r232055
2015-01-05Update copyright years.Jakub Jelinek4-4/+4
From-SVN: r219188
2014-01-02Update copyright years in libatomic/Richard Sandiford4-4/+4
From-SVN: r206291
2013-01-14Update copyright years in libatomic.Richard Sandiford4-4/+4
From-SVN: r195164
2012-05-01Add libatomic as a target library.Richard Henderson4-0/+310
From-SVN: r187018