1d47c0512a
As mentioned in the PR, the latest Intel SDM has added: "Processors that enumerate support for Intel® AVX (by setting the feature flag CPUID.01H:ECX.AVX[bit 28]) guarantee that the 16-byte memory operations performed by the following instructions will always be carried out atomically: • MOVAPD, MOVAPS, and MOVDQA. • VMOVAPD, VMOVAPS, and VMOVDQA when encoded with VEX.128. • VMOVAPD, VMOVAPS, VMOVDQA32, and VMOVDQA64 when encoded with EVEX.128 and k0 (masking disabled). (Note that these instructions require the linear addresses of their memory operands to be 16-byte aligned.)" The following patch deals with it just on the libatomic library side so far, currently (since ~ 2017) we emit all the __atomic_* 16-byte builtins as library calls since and this is something that we can hopefully backport. The patch simply introduces yet another ifunc variant that takes priority over the pure CMPXCHG16B one, one that checks AVX and CMPXCHG16B bits and on non-Intel clears the AVX bit during detection for now (if AMD comes with the same guarantee, we could revert the config/x86/init.c hunk), which implements 16-byte atomic load as vmovdqa and 16-byte atomic store as vmovdqa followed by mfence. 2022-03-17 Jakub Jelinek <jakub@redhat.com> PR target/104688 * Makefile.am (IFUNC_OPTIONS): Change on x86_64 to -mcx16 -mcx16. (libatomic_la_LIBADD): Add $(addsuffix _16_2_.lo,$(SIZEOBJS)) for x86_64. * Makefile.in: Regenerated. * config/x86/host-config.h (IFUNC_COND_1): For x86_64 define to both AVX and CMPXCHG16B bits. (IFUNC_COND_2): Define. (IFUNC_NCOND): For x86_64 define to 2 * (N == 16). (MAYBE_HAVE_ATOMIC_CAS_16, MAYBE_HAVE_ATOMIC_EXCHANGE_16, MAYBE_HAVE_ATOMIC_LDST_16): Define to IFUNC_COND_2 rather than IFUNC_COND_1. (HAVE_ATOMIC_CAS_16): Redefine to 1 whenever IFUNC_ALT != 0. (HAVE_ATOMIC_LDST_16): Redefine to 1 whenever IFUNC_ALT == 1. (atomic_compare_exchange_n): Define whenever IFUNC_ALT != 0 on x86_64 for N == 16. (__atomic_load_n, __atomic_store_n): Redefine whenever IFUNC_ALT == 1 on x86_64 for N == 16. (atomic_load_n, atomic_store_n): New functions. * config/x86/init.c (__libat_feat1_init): On x86_64 clear bit_AVX if CPU vendor is not Intel.
161 lines
5.9 KiB
Makefile
161 lines
5.9 KiB
Makefile
## Copyright (C) 2012-2022 Free Software Foundation, Inc.
|
|
## Contributed by Richard Henderson <rth@redhat.com>.
|
|
##
|
|
## 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
|
|
## <http://www.gnu.org/licenses/>.
|
|
|
|
ACLOCAL_AMFLAGS = -I .. -I ../config
|
|
SUBDIRS = testsuite
|
|
|
|
## May be used by toolexeclibdir.
|
|
gcc_version := $(shell @get_gcc_base_ver@ $(top_srcdir)/../gcc/BASE-VER)
|
|
|
|
config_path= @config_path@
|
|
search_path = $(addprefix $(top_srcdir)/config/, $(config_path)) \
|
|
$(top_srcdir) $(top_builddir)
|
|
|
|
vpath % $(strip $(search_path))
|
|
|
|
DEFAULT_INCLUDES = $(addprefix -I, $(search_path))
|
|
AM_CFLAGS = $(XCFLAGS)
|
|
AM_CCASFLAGS = $(XCFLAGS)
|
|
AM_LDFLAGS = $(XLDFLAGS) $(SECTION_LDFLAGS) $(OPT_LDFLAGS)
|
|
|
|
toolexeclib_LTLIBRARIES = libatomic.la
|
|
noinst_LTLIBRARIES = libatomic_convenience.la
|
|
|
|
if LIBAT_BUILD_VERSIONED_SHLIB
|
|
if LIBAT_BUILD_VERSIONED_SHLIB_GNU
|
|
libatomic_version_script = -Wl,--version-script,$(top_srcdir)/libatomic.map
|
|
libatomic_version_dep = $(top_srcdir)/libatomic.map
|
|
endif
|
|
if LIBAT_BUILD_VERSIONED_SHLIB_SUN
|
|
libatomic_version_script = -Wl,-M,libatomic.map-sun
|
|
libatomic_version_dep = libatomic.map-sun
|
|
libatomic.map-sun : $(top_srcdir)/libatomic.map \
|
|
$(top_srcdir)/../contrib/make_sunver.pl \
|
|
$(libatomic_la_OBJECTS) $(libatomic_la_LIBADD)
|
|
perl $(top_srcdir)/../contrib/make_sunver.pl \
|
|
$(top_srcdir)/libatomic.map \
|
|
$(libatomic_la_OBJECTS:%.lo=.libs/%.o) \
|
|
`echo $(libatomic_la_LIBADD) | \
|
|
sed 's,\([^/ ]*\)\.l\([ao]\),.libs/\1.\2,g'` \
|
|
> $@ || (rm -f $@ ; exit 1)
|
|
endif
|
|
else
|
|
libatomic_version_script =
|
|
libatomic_version_dep =
|
|
endif
|
|
libatomic_version_info = -version-info $(libtool_VERSION)
|
|
|
|
libatomic_la_LDFLAGS = $(libatomic_version_info) $(libatomic_version_script) $(lt_host_flags)
|
|
libatomic_la_SOURCES = gload.c gstore.c gcas.c gexch.c glfree.c lock.c init.c \
|
|
fenv.c fence.c flag.c
|
|
|
|
SIZEOBJS = load store cas exch fadd fsub fand fior fxor fnand tas
|
|
SIZES = @SIZES@
|
|
|
|
EXTRA_libatomic_la_SOURCES = $(addsuffix _n.c,$(SIZEOBJS))
|
|
libatomic_la_DEPENDENCIES = $(libatomic_la_LIBADD) $(libatomic_version_dep)
|
|
|
|
## And now our custom target patterns that allow us not to have tons of
|
|
## extra source files hanging about. Unfortunately, the complex relation
|
|
## between source and object filenames doesn't allow us to add an explicit
|
|
## dependency here. Fortunately that doesn't matter since auto-generated
|
|
## dependencies do the job just as well:
|
|
-include $(wildcard $(DEPDIR)/*.Ppo)
|
|
|
|
## Naming pattern: base_n_i_.lo
|
|
##
|
|
## N size of data
|
|
## I IFUNC alternative, index beginning at 1.
|
|
##
|
|
## The trailing _ in the output object file name is required to differentiate
|
|
## these objects from those which should be compiled normally. We can only
|
|
## have one stem in the implicit rule.
|
|
|
|
empty =
|
|
space = $(empty) $(empty)
|
|
PAT_SPLIT = $(subst _,$(space),$(*F))
|
|
PAT_BASE = $(word 1,$(PAT_SPLIT))
|
|
PAT_N = $(word 2,$(PAT_SPLIT))
|
|
PAT_S = $(word 3,$(PAT_SPLIT))
|
|
IFUNC_DEF = -DIFUNC_ALT=$(PAT_S)
|
|
IFUNC_OPT = $(word $(PAT_S),$(IFUNC_OPTIONS))
|
|
|
|
@AMDEP_TRUE@M_DEPS = -MT $@ -MD -MP -MF $(DEPDIR)/$(@F).Ppo
|
|
@AMDEP_FALSE@M_DEPS =
|
|
|
|
M_SIZE = -DN=$(PAT_N)
|
|
M_IFUNC = $(if $(PAT_S),$(IFUNC_DEF) $(IFUNC_OPT))
|
|
M_FILE = $(PAT_BASE)_n.c
|
|
|
|
# The lack of explicit dependency on the source file means that VPATH cannot
|
|
# work properly. Instead, perform this operation by hand. First, collect a
|
|
# list of all .c files in the search path.
|
|
all_c_files := $(foreach dir,$(search_path),$(wildcard $(dir)/*.c))
|
|
|
|
# Then sort through them to find the one we want, and select the first.
|
|
M_SRC = $(firstword $(filter %/$(M_FILE), $(all_c_files)))
|
|
|
|
%_.lo: Makefile
|
|
$(LTCOMPILE) $(M_DEPS) $(M_SIZE) $(M_IFUNC) -c -o $@ $(M_SRC)
|
|
|
|
## Include all of the sizes in the "normal" set of compilation flags.
|
|
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
|
|
IFUNC_OPTIONS = -march=armv8-a+lse
|
|
libatomic_la_LIBADD += $(foreach s,$(SIZES),$(addsuffix _$(s)_1_.lo,$(SIZEOBJS)))
|
|
endif
|
|
if ARCH_ARM_LINUX
|
|
IFUNC_OPTIONS = -march=armv7-a+fp -DHAVE_KERNEL64
|
|
libatomic_la_LIBADD += $(foreach s,$(SIZES),$(addsuffix _$(s)_1_.lo,$(SIZEOBJS)))
|
|
libatomic_la_LIBADD += $(addsuffix _8_2_.lo,$(SIZEOBJS))
|
|
endif
|
|
if ARCH_I386
|
|
IFUNC_OPTIONS = -march=i586
|
|
libatomic_la_LIBADD += $(addsuffix _8_1_.lo,$(SIZEOBJS))
|
|
endif
|
|
if ARCH_X86_64
|
|
IFUNC_OPTIONS = -mcx16 -mcx16
|
|
libatomic_la_LIBADD += $(addsuffix _16_1_.lo,$(SIZEOBJS)) \
|
|
$(addsuffix _16_2_.lo,$(SIZEOBJS))
|
|
endif
|
|
endif
|
|
|
|
libatomic_convenience_la_SOURCES = $(libatomic_la_SOURCES)
|
|
libatomic_convenience_la_LIBADD = $(libatomic_la_LIBADD)
|
|
|
|
# Override the automake generated all-multi rule to guarantee that all-multi
|
|
# is not run in parallel with the %_.lo rules which generate $(DEPDIR)/*.Ppo
|
|
# makefile fragments to avoid broken *.Ppo getting included into the Makefile
|
|
# when it is reloaded during the build of all-multi.
|
|
all-multi: $(libatomic_la_LIBADD)
|
|
$(MULTIDO) $(AM_MAKEFLAGS) DO=all multi-do # $(MAKE)
|
|
|
|
# target overrides
|
|
-include $(tmake_file)
|
|
|
|
include $(top_srcdir)/../multilib.am
|