Makefile.in (libgcc.mvars): Add LIBGCC_SYNC and LIBGCC_SYNC_CFLAGS.

gcc/
	* Makefile.in (libgcc.mvars): Add LIBGCC_SYNC and LIBGCC_SYNC_CFLAGS.
	* libgcc-std.ver (GCC_4.4.0): New version, inherited from GCC_4.3.0.
	Add synchronization functions.
	* config/sync.c: New file.
	* config/mips/t-libgcc-mips16 (LIBGCC_SYNC): Define.
	(LIBGCC_SYNC_CFLAGS): Likewise.

libgcc/
	* Makefile.in: Add support for __sync_* libgcc functions.

From-SVN: r137431
This commit is contained in:
Richard Sandiford 2008-07-03 19:37:45 +00:00 committed by Richard Sandiford
parent d0aede1456
commit f92518d7ae
7 changed files with 336 additions and 0 deletions

View file

@ -1,3 +1,12 @@
2008-07-03 Richard Sandiford <rdsandiford@googlemail.com>
* Makefile.in (libgcc.mvars): Add LIBGCC_SYNC and LIBGCC_SYNC_CFLAGS.
* libgcc-std.ver (GCC_4.4.0): New version, inherited from GCC_4.3.0.
Add synchronization functions.
* config/sync.c: New file.
* config/mips/t-libgcc-mips16 (LIBGCC_SYNC): Define.
(LIBGCC_SYNC_CFLAGS): Likewise.
2008-07-03 Uros Bizjak <ubizjak@gmail.com>
PR target/36710

View file

@ -1664,6 +1664,8 @@ libgcc.mvars: config.status Makefile $(LIB2ADD) $(LIB2ADD_ST) specs \
echo SHLIB_MAPFILES = '$(call srcdirify,$(SHLIB_MAPFILES))' >> tmp-libgcc.mvars
echo SHLIB_NM_FLAGS = '$(SHLIB_NM_FLAGS)' >> tmp-libgcc.mvars
echo LIBGCC2_CFLAGS = '$(LIBGCC2_CFLAGS)' >> tmp-libgcc.mvars
echo LIBGCC_SYNC = '$(LIBGCC_SYNC)' >> tmp-libgcc.mvars
echo LIBGCC_SYNC_CFLAGS = '$(LIBGCC_SYNC_CFLAGS)' >> tmp-libgcc.mvars
echo CRTSTUFF_CFLAGS = '$(CRTSTUFF_CFLAGS)' >> tmp-libgcc.mvars
echo CRTSTUFF_T_CFLAGS = '$(CRTSTUFF_T_CFLAGS)' >> tmp-libgcc.mvars
echo CRTSTUFF_T_CFLAGS_S = '$(CRTSTUFF_T_CFLAGS_S)' >> tmp-libgcc.mvars

View file

@ -19,3 +19,6 @@ LIB1ASMFUNCS = _m16addsf3 _m16subsf3 _m16mulsf3 _m16divsf3 \
_m16stubsc9 _m16stubsc10 \
_m16stubdc0 _m16stubdc1 _m16stubdc2 _m16stubdc5 _m16stubdc6 \
_m16stubdc9 _m16stubdc10
LIBGCC_SYNC = yes
LIBGCC_SYNC_CFLAGS = -mno-mips16

185
gcc/config/sync.c Normal file
View file

@ -0,0 +1,185 @@
/* Out-of-line libgcc versions of __sync_* builtins. */
/* Copyright (C) 2008 Free Software Foundation, Inc.
This file is part of GCC.
GCC 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 2, or (at your option) any later
version.
In addition to the permissions in the GNU General Public License, the
Free Software Foundation gives you unlimited permission to link the
compiled version of this file into combinations with other programs,
and to distribute those combinations without any restriction coming
from the use of this file. (The General Public License restrictions
do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)
GCC 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.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */
/* This file is used by targets whose makefiles define LIBGCC_SYNC
to "yes". It is compiled with LIBGCC_SYNC_CFLAGS and provides
out-of-line versions of all relevant __sync_* primitives.
These routines are intended for targets like MIPS that have two
ISA encodings (the "normal" ISA and the MIPS16 ISA). The normal
ISA provides full synchronization capabilities but the MIPS16 ISA
has no encoding for them. MIPS16 code must therefore call external
non-MIPS16 implementations of the __sync_* routines.
The file is compiled once for each routine. The following __foo
routines are selected by defining a macro called L<foo>:
__sync_synchronize
The following __foo_N routines are selected by defining FN=foo
and SIZE=N:
__sync_fetch_and_add_N
__sync_fetch_and_sub_N
__sync_fetch_and_or_N
__sync_fetch_and_and_N
__sync_fetch_and_xor_N
__sync_fetch_and_nand_N
__sync_add_and_fetch_N
__sync_sub_and_fetch_N
__sync_or_and_fetch_N
__sync_and_and_fetch_N
__sync_xor_and_fetch_N
__sync_nand_and_fetch_N
__sync_bool_compare_and_swap_N
__sync_val_compare_and_swap_N
__sync_lock_test_and_set_N
SIZE can be 1, 2, 4, 8 or 16. __foo_N is omitted if the target does
not provide __sync_compare_and_swap_N.
Note that __sync_lock_release does not fall back on external
__sync_lock_release_N functions. The default implementation
of __sync_lock_release is a call to __sync_synchronize followed
by a store of zero, so we don't need separate library functions
for it. */
#if defined FN
/* Define macros for each __sync_* function type. Each macro defines a
local function called <NAME>_<UNITS> that acts like __<NAME>_<UNITS>.
TYPE is a type that has UNITS bytes. */
#define DEFINE_V_PV(NAME, UNITS, TYPE) \
static TYPE \
NAME##_##UNITS (TYPE *ptr, TYPE value) \
{ \
return __##NAME (ptr, value); \
}
#define DEFINE_V_PVV(NAME, UNITS, TYPE) \
static TYPE \
NAME##_##UNITS (TYPE *ptr, TYPE value1, TYPE value2) \
{ \
return __##NAME (ptr, value1, value2); \
}
#define DEFINE_BOOL_PVV(NAME, UNITS, TYPE) \
static _Bool \
NAME##_##UNITS (TYPE *ptr, TYPE value1, TYPE value2) \
{ \
return __##NAME (ptr, value1, value2); \
}
/* Map function names to the appropriate DEFINE_* macro. */
#define local_sync_fetch_and_add DEFINE_V_PV
#define local_sync_fetch_and_sub DEFINE_V_PV
#define local_sync_fetch_and_or DEFINE_V_PV
#define local_sync_fetch_and_and DEFINE_V_PV
#define local_sync_fetch_and_xor DEFINE_V_PV
#define local_sync_fetch_and_nand DEFINE_V_PV
#define local_sync_add_and_fetch DEFINE_V_PV
#define local_sync_sub_and_fetch DEFINE_V_PV
#define local_sync_or_and_fetch DEFINE_V_PV
#define local_sync_and_and_fetch DEFINE_V_PV
#define local_sync_xor_and_fetch DEFINE_V_PV
#define local_sync_nand_and_fetch DEFINE_V_PV
#define local_sync_bool_compare_and_swap DEFINE_BOOL_PVV
#define local_sync_val_compare_and_swap DEFINE_V_PVV
#define local_sync_lock_test_and_set DEFINE_V_PV
/* Define the function __<NAME>_<UNITS>, given that TYPE is a type with
UNITS bytes. */
#define DEFINE1(NAME, UNITS, TYPE) \
static int unused[sizeof (TYPE) == UNITS ? 1 : -1] \
__attribute__((unused)); \
local_##NAME (NAME, UNITS, TYPE); \
typeof (NAME##_##UNITS) __##NAME##_##UNITS \
__attribute__((alias (#NAME "_" #UNITS)));
/* As above, but performing macro expansion on the arguments. */
#define DEFINE(NAME, UNITS, TYPE) DEFINE1 (NAME, UNITS, TYPE)
/* Find an appropriate type TYPE for SIZE and invoke DEFINE (FN, SIZE, TYPE).
The types chosen here may be incorrect for some targets.
For example, targets with 16-byte atomicity support might not
support OImode. We would need some kind of target-specific
override if that becomes a problem. */
#if SIZE == 1 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1
typedef unsigned int UQItype __attribute__((mode (QI)));
DEFINE (FN, 1, UQItype)
#elif SIZE == 2 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2
typedef unsigned int UHItype __attribute__((mode (HI)));
DEFINE (FN, 2, UHItype)
#elif SIZE == 4 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
typedef unsigned int USItype __attribute__((mode (SI)));
DEFINE (FN, 4, USItype)
#elif SIZE == 8 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
typedef unsigned int UDItype __attribute__((mode (DI)));
DEFINE (FN, 8, UDItype)
#elif SIZE == 16 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16
typedef unsigned int UOItype __attribute__((mode (OI)));
DEFINE (FN, 8, UOItype)
#endif
#elif __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 \
|| __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 \
|| __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 \
|| __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 \
|| __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16
#if defined Lsync_synchronize
static void
sync_synchronize (void)
{
__sync_synchronize ();
}
typeof (sync_synchronize) __sync_synchronize \
__attribute__((alias ("sync_synchronize")));
#endif
#endif

View file

@ -1804,3 +1804,88 @@ GCC_4.3.0 {
%inherit GCC_4.4.0 GCC_4.3.0
GCC_4.4.0 {
}
%inherit GCC_4.4.0 GCC_4.3.0
GCC_4.4.0 {
__sync_fetch_and_add_1
__sync_fetch_and_sub_1
__sync_fetch_and_or_1
__sync_fetch_and_and_1
__sync_fetch_and_xor_1
__sync_fetch_and_nand_1
__sync_add_and_fetch_1
__sync_sub_and_fetch_1
__sync_or_and_fetch_1
__sync_and_and_fetch_1
__sync_xor_and_fetch_1
__sync_nand_and_fetch_1
__sync_bool_compare_and_swap_1
__sync_val_compare_and_swap_1
__sync_lock_test_and_set_1
__sync_fetch_and_add_2
__sync_fetch_and_sub_2
__sync_fetch_and_or_2
__sync_fetch_and_and_2
__sync_fetch_and_xor_2
__sync_fetch_and_nand_2
__sync_add_and_fetch_2
__sync_sub_and_fetch_2
__sync_or_and_fetch_2
__sync_and_and_fetch_2
__sync_xor_and_fetch_2
__sync_nand_and_fetch_2
__sync_bool_compare_and_swap_2
__sync_val_compare_and_swap_2
__sync_lock_test_and_set_2
__sync_fetch_and_add_4
__sync_fetch_and_sub_4
__sync_fetch_and_or_4
__sync_fetch_and_and_4
__sync_fetch_and_xor_4
__sync_fetch_and_nand_4
__sync_add_and_fetch_4
__sync_sub_and_fetch_4
__sync_or_and_fetch_4
__sync_and_and_fetch_4
__sync_xor_and_fetch_4
__sync_nand_and_fetch_4
__sync_bool_compare_and_swap_4
__sync_val_compare_and_swap_4
__sync_lock_test_and_set_4
__sync_fetch_and_add_8
__sync_fetch_and_sub_8
__sync_fetch_and_or_8
__sync_fetch_and_and_8
__sync_fetch_and_xor_8
__sync_fetch_and_nand_8
__sync_add_and_fetch_8
__sync_sub_and_fetch_8
__sync_or_and_fetch_8
__sync_and_and_fetch_8
__sync_xor_and_fetch_8
__sync_nand_and_fetch_8
__sync_bool_compare_and_swap_8
__sync_val_compare_and_swap_8
__sync_lock_test_and_set_8
__sync_fetch_and_add_16
__sync_fetch_and_sub_16
__sync_fetch_and_or_16
__sync_fetch_and_and_16
__sync_fetch_and_xor_16
__sync_fetch_and_nand_16
__sync_add_and_fetch_16
__sync_sub_and_fetch_16
__sync_or_and_fetch_16
__sync_and_and_fetch_16
__sync_xor_and_fetch_16
__sync_nand_and_fetch_16
__sync_bool_compare_and_swap_16
__sync_val_compare_and_swap_16
__sync_lock_test_and_set_16
__sync_synchronize
}

View file

@ -1,3 +1,7 @@
2008-07-03 Richard Sandiford <rdsandiford@googlemail.com>
* Makefile.in: Add support for __sync_* libgcc functions.
2008-07-03 H.J. Lu <hongjiu.lu@intel.com>
* shared-object.mk ($(base)_s$(objext)): Remove -DSHARED.

View file

@ -577,6 +577,54 @@ endif
endif
ifeq ($(LIBGCC_SYNC),yes)
libgcc-sync-size-funcs := $(foreach op, add sub or and xor nand, \
sync_fetch_and_$(op) \
sync_$(op)_and_fetch) \
sync_bool_compare_and_swap \
sync_val_compare_and_swap \
sync_lock_test_and_set
libgcc-sync-size-funcs := $(foreach prefix, $(libgcc-sync-size-funcs), \
$(foreach suffix, 1 2 4 8 16, \
$(prefix)_$(suffix)))
libgcc-sync-size-funcs-o = $(patsubst %,%$(objext),$(libgcc-sync-size-funcs))
$(libgcc-sync-size-funcs-o): %$(objext): $(gcc_srcdir)/config/sync.c
$(gcc_compile) $(LIBGCC_SYNC_CFLAGS) \
-DFN=`echo "$*" | sed 's/_[^_]*$$//'` \
-DSIZE=`echo "$*" | sed 's/.*_//'` \
-c $(gcc_srcdir)/config/sync.c $(vis_hide)
libgcc-objects += $(libgcc-sync-size-funcs-o)
libgcc-sync-funcs := sync_synchronize
libgcc-sync-funcs-o = $(patsubst %,%$(objext),$(libgcc-sync-funcs))
$(libgcc-sync-funcs-o): %$(objext): $(gcc_srcdir)/config/sync.c
$(gcc_compile) $(LIBGCC_SYNC_CFLAGS) \
-DL$* \
-c $(gcc_srcdir)/config/sync.c $(vis_hide)
libgcc-objects += $(libgcc-sync-funcs-o)
ifeq ($(enable_shared),yes)
libgcc-sync-size-funcs-s-o = $(patsubst %,%_s$(objext), \
$(libgcc-sync-size-funcs))
$(libgcc-sync-size-funcs-s-o): %_s$(objext): $(gcc_srcdir)/config/sync.c
$(gcc_s_compile) $(LIBGCC_SYNC_CFLAGS) \
-DFN=`echo "$*" | sed 's/_[^_]*$$//'` \
-DSIZE=`echo "$*" | sed 's/.*_//'` \
-c $(gcc_srcdir)/config/sync.c
libgcc-s-objects += $(libgcc-sync-size-funcs-s-o)
libgcc-sync-funcs-s-o = $(patsubst %,%_s$(objext),$(libgcc-sync-funcs))
$(libgcc-sync-funcs-s-o): %_s$(objext): $(gcc_srcdir)/config/sync.c
$(gcc_s_compile) $(LIBGCC_SYNC_CFLAGS) \
-DL$* \
-c $(gcc_srcdir)/config/sync.c
libgcc-s-objects += $(libgcc-sync-funcs-s-o)
endif
endif
# Build fixed-point support.
ifeq ($(fixed_point),yes)