diff --git a/libatomic/Makefile.am b/libatomic/Makefile.am index d731406..a35df1e 100644 --- a/libatomic/Makefile.am +++ b/libatomic/Makefile.am @@ -122,6 +122,10 @@ libatomic_la_LIBADD = $(foreach s,$(SIZES),$(addsuffix _$(s)_.lo,$(SIZEOBJS))) ## On a target-specific basis, include alternates to be selected by IFUNC. if HAVE_IFUNC +if ARCH_AARCH64_LINUX_LSE +IFUNC_OPTIONS = -mcpu=thunderx2t99 +libatomic_la_LIBADD += $(foreach s,$(SIZES),$(addsuffix _$(s)_1_.lo,$(SIZEOBJS))) +endif if ARCH_ARM_LINUX IFUNC_OPTIONS = -march=armv7-a -DHAVE_KERNEL64 libatomic_la_LIBADD += $(foreach s,$(SIZES),$(addsuffix _$(s)_1_.lo,$(SIZEOBJS))) diff --git a/libatomic/config/linux/aarch64/host-config.h b/libatomic/config/linux/aarch64/host-config.h index e69de29..2e5e97a 100644 --- a/libatomic/config/linux/aarch64/host-config.h +++ b/libatomic/config/linux/aarch64/host-config.h @@ -0,0 +1,39 @@ +/* Copyright (C) 2017 Free Software Foundation, Inc. + + This file is part of the GNU Atomic Library (libatomic). + + Libatomic is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Libatomic is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + . */ + +#if HAVE_IFUNC +#include +#ifdef HAVE_SYS_AUXV_H +# include +#endif + +# ifdef HWCAP_ATOMICS +# define IFUNC_COND_1 (hwcap & HWCAP_ATOMICS) +# else +# define IFUNC_COND_1 (false) +# endif +# define IFUNC_NCOND(N) (1) + +#endif /* HAVE_IFUNC */ + +#include_next diff --git a/libatomic/configure.ac b/libatomic/configure.ac index 023f172..4e06ffe 100644 --- a/libatomic/configure.ac +++ b/libatomic/configure.ac @@ -163,6 +163,10 @@ if test -n "$UNSUPPORTED"; then AC_MSG_ERROR([Configuration ${target} is unsupported.]) fi +# Write out the ifunc resolver arg type. +AC_DEFINE_UNQUOTED(HWCAP_TYPE, $HWCAP_TYPE, + [Define type of ifunc resolver function argument.]) + # Disable fallbacks to __sync routines from libgcc. Otherwise we'll # make silly decisions about what the cpu can do. CFLAGS="$save_CFLAGS -fno-sync-libcalls $XCFLAGS" @@ -171,7 +175,8 @@ CFLAGS="$save_CFLAGS -fno-sync-libcalls $XCFLAGS" AC_STDC_HEADERS ACX_HEADER_STRING GCC_HEADER_STDINT(gstdint.h) -AC_CHECK_HEADERS([fenv.h]) +AC_CHECK_HEADERS([fenv.h sys/auxv.h]) +AC_CHECK_FUNCS(getauxval) # Check for common type sizes LIBAT_FORALL_MODES([LIBAT_HAVE_INT_MODE]) @@ -247,6 +252,8 @@ AC_SUBST(LIBS) AC_SUBST(SIZES) AM_CONDITIONAL(HAVE_IFUNC, test x$libat_cv_have_ifunc = xyes) +AM_CONDITIONAL(ARCH_AARCH64_LINUX_LSE, + [expr "$config_path" : ".* linux/aarch64 .*" > /dev/null]) AM_CONDITIONAL(ARCH_ARM_LINUX, [expr "$config_path" : ".* linux/arm .*" > /dev/null]) AM_CONDITIONAL(ARCH_I386, diff --git a/libatomic/configure.tgt b/libatomic/configure.tgt index b8af3ab..0bb5c66 100644 --- a/libatomic/configure.tgt +++ b/libatomic/configure.tgt @@ -40,6 +40,14 @@ case "${target_cpu}" in riscv*) ARCH=riscv ;; sh*) ARCH=sh ;; + aarch64*) + ARCH=aarch64 + case "${target}" in + aarch64*-*-linux*) + try_ifunc=yes + ;; + esac + ;; arm*) ARCH=arm case "${target}" in @@ -109,6 +117,11 @@ fi # Other system configury case "${target}" in + aarch64*-*-linux*) + # OS support for atomic primitives. + config_path="${config_path} linux/aarch64 posix" + ;; + arm*-*-linux*) # OS support for atomic primitives. config_path="${config_path} linux/arm posix" @@ -153,3 +166,14 @@ case "${target}" in UNSUPPORTED=1 ;; esac + +# glibc will pass hwcap to ifunc resolver functions as an argument. +# The type may be different on different architectures. +case "${target}" in + aarch64*-*-*) + HWCAP_TYPE=uint64_t + ;; + *) + HWCAP_TYPE="unsigned long int" + ;; +esac diff --git a/libatomic/libatomic_i.h b/libatomic/libatomic_i.h index 4eb372a..e7f2050 100644 --- a/libatomic/libatomic_i.h +++ b/libatomic/libatomic_i.h @@ -240,7 +240,7 @@ bool libat_is_lock_free (size_t, void *) MAN(is_lock_free); # if IFUNC_NCOND(N) == 1 # define GEN_SELECTOR(X) \ extern typeof(C2(libat_,X)) C3(libat_,X,_i1) HIDDEN; \ - static void * C2(select_,X) (void) \ + static void * C2(select_,X) (HWCAP_TYPE hwcap) \ { \ if (IFUNC_COND_1) \ return C3(libat_,X,_i1); \ @@ -250,7 +250,7 @@ bool libat_is_lock_free (size_t, void *) MAN(is_lock_free); # define GEN_SELECTOR(X) \ extern typeof(C2(libat_,X)) C3(libat_,X,_i1) HIDDEN; \ extern typeof(C2(libat_,X)) C3(libat_,X,_i2) HIDDEN; \ - static void * C2(select_,X) (void) \ + static void * C2(select_,X) (HWCAP_TYPE hwcap) \ { \ if (IFUNC_COND_1) \ return C3(libat_,X,_i1); \ @@ -263,7 +263,7 @@ bool libat_is_lock_free (size_t, void *) MAN(is_lock_free); extern typeof(C2(libat_,X)) C3(libat_,X,_i1) HIDDEN; \ extern typeof(C2(libat_,X)) C3(libat_,X,_i2) HIDDEN; \ extern typeof(C2(libat_,X)) C3(libat_,X,_i3) HIDDEN; \ - static void * C2(select_,X) (void) \ + static void * C2(select_,X) (HWCAP_TYPE hwcap) \ { \ if (IFUNC_COND_1) \ return C3(libat_,X,_i1); \