Commit cedb4a1a by Richard Henderson Committed by Richard Henderson

Allow libcalls to be installed for legacy __sync optabs.

This allows a target which implements the __sync interfaces
in libgcc to continue to use them transparently with the
new __atomic builtins.

It is assumed that these libgcc routines DO NOT use spinlocks.
This is true of all extant libgcc instances.

        * optabs.h (OTI_sync_compare_and_swap, OTI_sync_lock_test_and_set,
        OTI_sync_old_add, OTI_sync_old_sub, OTI_sync_old_ior,
        OTI_sync_old_and, OTI_sync_old_xor, OTI_sync_old_nand,
        OTI_sync_new_add, OTI_sync_new_sub, OTI_sync_new_ior,
        OTI_sync_new_and, OTI_sync_new_xor, OTI_sync_new_nand): Move and
        rename from the direct_optab_index enum.
        (sync_compare_and_swap_optab, sync_lock_test_and_set_optab,
        sync_old_add_optab, sync_old_sub_optab, sync_old_ior_optab,
        sync_old_and_optab, sync_old_xor_optab, sync_old_nand_optab,
        sync_new_add_optab, sync_new_sub_optab, sync_new_ior_optab,
        sync_new_and_optab, sync_new_xor_optab, sync_new_nand_optab): Read
        from the optab_table, not the direct_optab_table.
        (init_sync_libfuncs): Declare.
        (can_compare_and_swap_p): Update parameters.
        * optabs.c (init_sync_libfuncs_1, init_sync_libfuncs): New.
        (can_compare_and_swap_p): Add allow_libcall parameter; if true,
        test for the legacy compare-and-swap libcall.
        (expand_atomic_exchange): Use the legacy test-and-set libcall.
        (expand_atomic_compare_and_swap): Use the legacy CAS libcall.
        (struct atomic_op_functions): Update for optab type changes.
        (maybe_emit_op): Likewise.
        (expand_atomic_fetch_op): Use the legacy fetch-op libcalls.
        * builtins.c (fold_builtin_atomic_always_lock_free): Update call
        to can_compare_and_swap_p.
        * omp-low.c (expand_omp_atomic_fetch_op): Likewise.
        (expand_omp_atomic_pipeline): Likewise.
        * genopinit.c (optabs): Make sync_old_*_optab, sync_new_*_optab,
        sync_compare_and_swap_optab, sync_lock_test_and_set_optab regular
        optabs.

From-SVN: r181134
parent 13fc31c2
2011-11-07 Richard Henderson <rth@redhat.com>
* optabs.h (OTI_sync_compare_and_swap, OTI_sync_lock_test_and_set,
OTI_sync_old_add, OTI_sync_old_sub, OTI_sync_old_ior,
OTI_sync_old_and, OTI_sync_old_xor, OTI_sync_old_nand,
OTI_sync_new_add, OTI_sync_new_sub, OTI_sync_new_ior,
OTI_sync_new_and, OTI_sync_new_xor, OTI_sync_new_nand): Move and
rename from the direct_optab_index enum.
(sync_compare_and_swap_optab, sync_lock_test_and_set_optab,
sync_old_add_optab, sync_old_sub_optab, sync_old_ior_optab,
sync_old_and_optab, sync_old_xor_optab, sync_old_nand_optab,
sync_new_add_optab, sync_new_sub_optab, sync_new_ior_optab,
sync_new_and_optab, sync_new_xor_optab, sync_new_nand_optab): Read
from the optab_table, not the direct_optab_table.
(init_sync_libfuncs): Declare.
(can_compare_and_swap_p): Update parameters.
* optabs.c (init_sync_libfuncs_1, init_sync_libfuncs): New.
(can_compare_and_swap_p): Add allow_libcall parameter; if true,
test for the legacy compare-and-swap libcall.
(expand_atomic_exchange): Use the legacy test-and-set libcall.
(expand_atomic_compare_and_swap): Use the legacy CAS libcall.
(struct atomic_op_functions): Update for optab type changes.
(maybe_emit_op): Likewise.
(expand_atomic_fetch_op): Use the legacy fetch-op libcalls.
* builtins.c (fold_builtin_atomic_always_lock_free): Update call
to can_compare_and_swap_p.
* omp-low.c (expand_omp_atomic_fetch_op): Likewise.
(expand_omp_atomic_pipeline): Likewise.
* genopinit.c (optabs): Make sync_old_*_optab, sync_new_*_optab,
sync_compare_and_swap_optab, sync_lock_test_and_set_optab regular
optabs.
* doc/md.texi (sync_compare_and_swap): Update docs for libcalls.
2011-11-07 Jakub Jelinek <jakub@redhat.com> 2011-11-07 Jakub Jelinek <jakub@redhat.com>
* config/i386/i386-bultin-types.def (V8SI_FTYPE_V4DF_V4DF): Add. * config/i386/i386-bultin-types.def (V8SI_FTYPE_V4DF_V4DF): Add.
...@@ -5512,7 +5512,7 @@ fold_builtin_atomic_always_lock_free (tree arg0, tree arg1) ...@@ -5512,7 +5512,7 @@ fold_builtin_atomic_always_lock_free (tree arg0, tree arg1)
/* Check if a compare_and_swap pattern exists for the mode which represents /* Check if a compare_and_swap pattern exists for the mode which represents
the required size. The pattern is not allowed to fail, so the existence the required size. The pattern is not allowed to fail, so the existence
of the pattern indicates support is present. */ of the pattern indicates support is present. */
if (can_compare_and_swap_p (mode)) if (can_compare_and_swap_p (mode, true))
return integer_one_node; return integer_one_node;
else else
return integer_zero_node; return integer_zero_node;
......
...@@ -5595,6 +5595,17 @@ be able to take the destination of the @code{MODE_CC} set and pass it ...@@ -5595,6 +5595,17 @@ be able to take the destination of the @code{MODE_CC} set and pass it
to the @code{cbranchcc4} or @code{cstorecc4} pattern as the first to the @code{cbranchcc4} or @code{cstorecc4} pattern as the first
operand of the comparison (the second will be @code{(const_int 0)}). operand of the comparison (the second will be @code{(const_int 0)}).
For targets where the operating system may provide support for this
operation via library calls, the @code{sync_compare_and_swap_optab}
may be initialized to a function with the same interface as the
@code{__sync_val_compare_and_swap_@var{n}} built-in. If the entire
set of @var{__sync} builtins are supported via library calls, the
target can initialize all of the optabs at once with
@code{init_sync_libfuncs}.
For the purposes of C++11 @code{std::atomic::is_lock_free}, it is
assumed that these library calls do @emph{not} use any kind of
interruptable locking.
@cindex @code{sync_add@var{mode}} instruction pattern @cindex @code{sync_add@var{mode}} instruction pattern
@cindex @code{sync_sub@var{mode}} instruction pattern @cindex @code{sync_sub@var{mode}} instruction pattern
@cindex @code{sync_ior@var{mode}} instruction pattern @cindex @code{sync_ior@var{mode}} instruction pattern
......
...@@ -228,20 +228,20 @@ static const char * const optabs[] = ...@@ -228,20 +228,20 @@ static const char * const optabs[] =
"set_direct_optab_handler (sync_and_optab, $A, CODE_FOR_$(sync_and$I$a$))", "set_direct_optab_handler (sync_and_optab, $A, CODE_FOR_$(sync_and$I$a$))",
"set_direct_optab_handler (sync_xor_optab, $A, CODE_FOR_$(sync_xor$I$a$))", "set_direct_optab_handler (sync_xor_optab, $A, CODE_FOR_$(sync_xor$I$a$))",
"set_direct_optab_handler (sync_nand_optab, $A, CODE_FOR_$(sync_nand$I$a$))", "set_direct_optab_handler (sync_nand_optab, $A, CODE_FOR_$(sync_nand$I$a$))",
"set_direct_optab_handler (sync_old_add_optab, $A, CODE_FOR_$(sync_old_add$I$a$))", "set_optab_handler (sync_old_add_optab, $A, CODE_FOR_$(sync_old_add$I$a$))",
"set_direct_optab_handler (sync_old_sub_optab, $A, CODE_FOR_$(sync_old_sub$I$a$))", "set_optab_handler (sync_old_sub_optab, $A, CODE_FOR_$(sync_old_sub$I$a$))",
"set_direct_optab_handler (sync_old_ior_optab, $A, CODE_FOR_$(sync_old_ior$I$a$))", "set_optab_handler (sync_old_ior_optab, $A, CODE_FOR_$(sync_old_ior$I$a$))",
"set_direct_optab_handler (sync_old_and_optab, $A, CODE_FOR_$(sync_old_and$I$a$))", "set_optab_handler (sync_old_and_optab, $A, CODE_FOR_$(sync_old_and$I$a$))",
"set_direct_optab_handler (sync_old_xor_optab, $A, CODE_FOR_$(sync_old_xor$I$a$))", "set_optab_handler (sync_old_xor_optab, $A, CODE_FOR_$(sync_old_xor$I$a$))",
"set_direct_optab_handler (sync_old_nand_optab, $A, CODE_FOR_$(sync_old_nand$I$a$))", "set_optab_handler (sync_old_nand_optab, $A, CODE_FOR_$(sync_old_nand$I$a$))",
"set_direct_optab_handler (sync_new_add_optab, $A, CODE_FOR_$(sync_new_add$I$a$))", "set_optab_handler (sync_new_add_optab, $A, CODE_FOR_$(sync_new_add$I$a$))",
"set_direct_optab_handler (sync_new_sub_optab, $A, CODE_FOR_$(sync_new_sub$I$a$))", "set_optab_handler (sync_new_sub_optab, $A, CODE_FOR_$(sync_new_sub$I$a$))",
"set_direct_optab_handler (sync_new_ior_optab, $A, CODE_FOR_$(sync_new_ior$I$a$))", "set_optab_handler (sync_new_ior_optab, $A, CODE_FOR_$(sync_new_ior$I$a$))",
"set_direct_optab_handler (sync_new_and_optab, $A, CODE_FOR_$(sync_new_and$I$a$))", "set_optab_handler (sync_new_and_optab, $A, CODE_FOR_$(sync_new_and$I$a$))",
"set_direct_optab_handler (sync_new_xor_optab, $A, CODE_FOR_$(sync_new_xor$I$a$))", "set_optab_handler (sync_new_xor_optab, $A, CODE_FOR_$(sync_new_xor$I$a$))",
"set_direct_optab_handler (sync_new_nand_optab, $A, CODE_FOR_$(sync_new_nand$I$a$))", "set_optab_handler (sync_new_nand_optab, $A, CODE_FOR_$(sync_new_nand$I$a$))",
"set_direct_optab_handler (sync_compare_and_swap_optab, $A, CODE_FOR_$(sync_compare_and_swap$I$a$))", "set_optab_handler (sync_compare_and_swap_optab, $A, CODE_FOR_$(sync_compare_and_swap$I$a$))",
"set_direct_optab_handler (sync_lock_test_and_set_optab, $A, CODE_FOR_$(sync_lock_test_and_set$I$a$))", "set_optab_handler (sync_lock_test_and_set_optab, $A, CODE_FOR_$(sync_lock_test_and_set$I$a$))",
"set_direct_optab_handler (sync_lock_release_optab, $A, CODE_FOR_$(sync_lock_release$I$a$))", "set_direct_optab_handler (sync_lock_release_optab, $A, CODE_FOR_$(sync_lock_release$I$a$))",
"set_direct_optab_handler (atomic_exchange_optab, $A, CODE_FOR_$(atomic_exchange$I$a$))", "set_direct_optab_handler (atomic_exchange_optab, $A, CODE_FOR_$(atomic_exchange$I$a$))",
"set_direct_optab_handler (atomic_compare_and_swap_optab, $A, CODE_FOR_$(atomic_compare_and_swap$I$a$))", "set_direct_optab_handler (atomic_compare_and_swap_optab, $A, CODE_FOR_$(atomic_compare_and_swap$I$a$))",
......
2011-11-07 Richard Henderson <rth@redhat.com>
* builtins.c (compareAndSwapInt_builtin): Use can_compare_and_swap_p.
(compareAndSwapLong_builtin): Likewise.
(compareAndSwapObject_builtin): Likewise.
(VMSupportsCS8_builtin): Likewise.
2011-11-02 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> 2011-11-02 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* Make-lang.in (jvspec.o): Pass SHLIB instead of SHLIB_LINK. * Make-lang.in (jvspec.o): Pass SHLIB instead of SHLIB_LINK.
......
...@@ -319,9 +319,7 @@ compareAndSwapInt_builtin (tree method_return_type ATTRIBUTE_UNUSED, ...@@ -319,9 +319,7 @@ compareAndSwapInt_builtin (tree method_return_type ATTRIBUTE_UNUSED,
tree orig_call) tree orig_call)
{ {
enum machine_mode mode = TYPE_MODE (int_type_node); enum machine_mode mode = TYPE_MODE (int_type_node);
if (direct_optab_handler (sync_compare_and_swap_optab, mode) if (can_compare_and_swap_p (mode, flag_use_atomic_builtins))
!= CODE_FOR_nothing
|| flag_use_atomic_builtins)
{ {
tree addr, stmt; tree addr, stmt;
enum built_in_function fncode = BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_4; enum built_in_function fncode = BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_4;
...@@ -342,13 +340,12 @@ compareAndSwapLong_builtin (tree method_return_type ATTRIBUTE_UNUSED, ...@@ -342,13 +340,12 @@ compareAndSwapLong_builtin (tree method_return_type ATTRIBUTE_UNUSED,
tree orig_call) tree orig_call)
{ {
enum machine_mode mode = TYPE_MODE (long_type_node); enum machine_mode mode = TYPE_MODE (long_type_node);
if (direct_optab_handler (sync_compare_and_swap_optab, mode) /* We don't trust flag_use_atomic_builtins for multi-word compareAndSwap.
!= CODE_FOR_nothing Some machines such as ARM have atomic libfuncs but not the multi-word
|| (GET_MODE_SIZE (mode) <= GET_MODE_SIZE (word_mode) versions. */
&& flag_use_atomic_builtins)) if (can_compare_and_swap_p (mode,
/* We don't trust flag_use_atomic_builtins for multi-word (flag_use_atomic_builtins
compareAndSwap. Some machines such as ARM have atomic libfuncs && GET_MODE_SIZE (mode) <= UNITS_PER_WORD)))
but not the multi-word versions. */
{ {
tree addr, stmt; tree addr, stmt;
enum built_in_function fncode = BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_8; enum built_in_function fncode = BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_8;
...@@ -368,9 +365,7 @@ compareAndSwapObject_builtin (tree method_return_type ATTRIBUTE_UNUSED, ...@@ -368,9 +365,7 @@ compareAndSwapObject_builtin (tree method_return_type ATTRIBUTE_UNUSED,
tree orig_call) tree orig_call)
{ {
enum machine_mode mode = TYPE_MODE (ptr_type_node); enum machine_mode mode = TYPE_MODE (ptr_type_node);
if (direct_optab_handler (sync_compare_and_swap_optab, mode) if (can_compare_and_swap_p (mode, flag_use_atomic_builtins))
!= CODE_FOR_nothing
|| flag_use_atomic_builtins)
{ {
tree addr, stmt; tree addr, stmt;
enum built_in_function builtin; enum built_in_function builtin;
...@@ -448,8 +443,7 @@ VMSupportsCS8_builtin (tree method_return_type, ...@@ -448,8 +443,7 @@ VMSupportsCS8_builtin (tree method_return_type,
{ {
enum machine_mode mode = TYPE_MODE (long_type_node); enum machine_mode mode = TYPE_MODE (long_type_node);
gcc_assert (method_return_type == boolean_type_node); gcc_assert (method_return_type == boolean_type_node);
if (direct_optab_handler (sync_compare_and_swap_optab, mode) if (can_compare_and_swap_p (mode, false))
!= CODE_FOR_nothing)
return boolean_true_node; return boolean_true_node;
else else
return boolean_false_node; return boolean_false_node;
......
...@@ -5097,7 +5097,7 @@ expand_omp_atomic_fetch_op (basic_block load_bb, ...@@ -5097,7 +5097,7 @@ expand_omp_atomic_fetch_op (basic_block load_bb,
matter is that (with the exception of i486 vs i586 and xadd) all targets matter is that (with the exception of i486 vs i586 and xadd) all targets
that support any atomic operaton optab also implements compare-and-swap. that support any atomic operaton optab also implements compare-and-swap.
Let optabs.c take care of expanding any compare-and-swap loop. */ Let optabs.c take care of expanding any compare-and-swap loop. */
if (!can_compare_and_swap_p (imode)) if (!can_compare_and_swap_p (imode, true))
return false; return false;
gsi = gsi_last_bb (load_bb); gsi = gsi_last_bb (load_bb);
...@@ -5168,7 +5168,7 @@ expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb, ...@@ -5168,7 +5168,7 @@ expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb,
type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr))); type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
itype = TREE_TYPE (TREE_TYPE (cmpxchg)); itype = TREE_TYPE (TREE_TYPE (cmpxchg));
if (!can_compare_and_swap_p (TYPE_MODE (itype))) if (!can_compare_and_swap_p (TYPE_MODE (itype), true))
return false; return false;
/* Load the initial value, replacing the GIMPLE_OMP_ATOMIC_LOAD. */ /* Load the initial value, replacing the GIMPLE_OMP_ATOMIC_LOAD. */
......
...@@ -386,6 +386,30 @@ enum optab_index ...@@ -386,6 +386,30 @@ enum optab_index
/* Perform a raise to the power of integer. */ /* Perform a raise to the power of integer. */
OTI_powi, OTI_powi,
/* Atomic compare and swap. */
OTI_sync_compare_and_swap,
/* Atomic exchange with acquire semantics. */
OTI_sync_lock_test_and_set,
/* This second set is atomic operations in which we return the value
that existed in memory before the operation. */
OTI_sync_old_add,
OTI_sync_old_sub,
OTI_sync_old_ior,
OTI_sync_old_and,
OTI_sync_old_xor,
OTI_sync_old_nand,
/* This third set is atomic operations in which we return the value
that resulted after performing the operation. */
OTI_sync_new_add,
OTI_sync_new_sub,
OTI_sync_new_ior,
OTI_sync_new_and,
OTI_sync_new_xor,
OTI_sync_new_nand,
OTI_MAX OTI_MAX
}; };
...@@ -570,6 +594,23 @@ enum optab_index ...@@ -570,6 +594,23 @@ enum optab_index
#define powi_optab (&optab_table[OTI_powi]) #define powi_optab (&optab_table[OTI_powi])
#define sync_compare_and_swap_optab \
(&optab_table[(int) OTI_sync_compare_and_swap])
#define sync_lock_test_and_set_optab \
(&optab_table[(int) OTI_sync_lock_test_and_set])
#define sync_old_add_optab (&optab_table[(int) OTI_sync_old_add])
#define sync_old_sub_optab (&optab_table[(int) OTI_sync_old_sub])
#define sync_old_ior_optab (&optab_table[(int) OTI_sync_old_ior])
#define sync_old_and_optab (&optab_table[(int) OTI_sync_old_and])
#define sync_old_xor_optab (&optab_table[(int) OTI_sync_old_xor])
#define sync_old_nand_optab (&optab_table[(int) OTI_sync_old_nand])
#define sync_new_add_optab (&optab_table[(int) OTI_sync_new_add])
#define sync_new_sub_optab (&optab_table[(int) OTI_sync_new_sub])
#define sync_new_ior_optab (&optab_table[(int) OTI_sync_new_ior])
#define sync_new_and_optab (&optab_table[(int) OTI_sync_new_and])
#define sync_new_xor_optab (&optab_table[(int) OTI_sync_new_xor])
#define sync_new_nand_optab (&optab_table[(int) OTI_sync_new_nand])
/* Conversion optabs have their own table and indexes. */ /* Conversion optabs have their own table and indexes. */
enum convert_optab_index enum convert_optab_index
{ {
...@@ -659,8 +700,10 @@ enum direct_optab_index ...@@ -659,8 +700,10 @@ enum direct_optab_index
DOI_cmpstrn, DOI_cmpstrn,
DOI_cmpmem, DOI_cmpmem,
/* Synchronization primitives. This first set is atomic operation for /* Atomic clear with release semantics. */
which we don't care about the resulting value. */ DOI_sync_lock_release,
/* Atomic operation with no resulting value. */
DOI_sync_add, DOI_sync_add,
DOI_sync_sub, DOI_sync_sub,
DOI_sync_ior, DOI_sync_ior,
...@@ -668,33 +711,6 @@ enum direct_optab_index ...@@ -668,33 +711,6 @@ enum direct_optab_index
DOI_sync_xor, DOI_sync_xor,
DOI_sync_nand, DOI_sync_nand,
/* This second set is atomic operations in which we return the value
that existed in memory before the operation. */
DOI_sync_old_add,
DOI_sync_old_sub,
DOI_sync_old_ior,
DOI_sync_old_and,
DOI_sync_old_xor,
DOI_sync_old_nand,
/* This third set is atomic operations in which we return the value
that resulted after performing the operation. */
DOI_sync_new_add,
DOI_sync_new_sub,
DOI_sync_new_ior,
DOI_sync_new_and,
DOI_sync_new_xor,
DOI_sync_new_nand,
/* Atomic compare and swap. */
DOI_sync_compare_and_swap,
/* Atomic exchange with acquire semantics. */
DOI_sync_lock_test_and_set,
/* Atomic clear with release semantics. */
DOI_sync_lock_release,
/* Atomic operations with memory model parameters. */ /* Atomic operations with memory model parameters. */
DOI_atomic_exchange, DOI_atomic_exchange,
DOI_atomic_compare_and_swap, DOI_atomic_compare_and_swap,
...@@ -748,30 +764,14 @@ typedef struct direct_optab_d *direct_optab; ...@@ -748,30 +764,14 @@ typedef struct direct_optab_d *direct_optab;
#define cmpstr_optab (&direct_optab_table[(int) DOI_cmpstr]) #define cmpstr_optab (&direct_optab_table[(int) DOI_cmpstr])
#define cmpstrn_optab (&direct_optab_table[(int) DOI_cmpstrn]) #define cmpstrn_optab (&direct_optab_table[(int) DOI_cmpstrn])
#define cmpmem_optab (&direct_optab_table[(int) DOI_cmpmem]) #define cmpmem_optab (&direct_optab_table[(int) DOI_cmpmem])
#define sync_lock_release_optab \
(&direct_optab_table[(int) DOI_sync_lock_release])
#define sync_add_optab (&direct_optab_table[(int) DOI_sync_add]) #define sync_add_optab (&direct_optab_table[(int) DOI_sync_add])
#define sync_sub_optab (&direct_optab_table[(int) DOI_sync_sub]) #define sync_sub_optab (&direct_optab_table[(int) DOI_sync_sub])
#define sync_ior_optab (&direct_optab_table[(int) DOI_sync_ior]) #define sync_ior_optab (&direct_optab_table[(int) DOI_sync_ior])
#define sync_and_optab (&direct_optab_table[(int) DOI_sync_and]) #define sync_and_optab (&direct_optab_table[(int) DOI_sync_and])
#define sync_xor_optab (&direct_optab_table[(int) DOI_sync_xor]) #define sync_xor_optab (&direct_optab_table[(int) DOI_sync_xor])
#define sync_nand_optab (&direct_optab_table[(int) DOI_sync_nand]) #define sync_nand_optab (&direct_optab_table[(int) DOI_sync_nand])
#define sync_old_add_optab (&direct_optab_table[(int) DOI_sync_old_add])
#define sync_old_sub_optab (&direct_optab_table[(int) DOI_sync_old_sub])
#define sync_old_ior_optab (&direct_optab_table[(int) DOI_sync_old_ior])
#define sync_old_and_optab (&direct_optab_table[(int) DOI_sync_old_and])
#define sync_old_xor_optab (&direct_optab_table[(int) DOI_sync_old_xor])
#define sync_old_nand_optab (&direct_optab_table[(int) DOI_sync_old_nand])
#define sync_new_add_optab (&direct_optab_table[(int) DOI_sync_new_add])
#define sync_new_sub_optab (&direct_optab_table[(int) DOI_sync_new_sub])
#define sync_new_ior_optab (&direct_optab_table[(int) DOI_sync_new_ior])
#define sync_new_and_optab (&direct_optab_table[(int) DOI_sync_new_and])
#define sync_new_xor_optab (&direct_optab_table[(int) DOI_sync_new_xor])
#define sync_new_nand_optab (&direct_optab_table[(int) DOI_sync_new_nand])
#define sync_compare_and_swap_optab \
(&direct_optab_table[(int) DOI_sync_compare_and_swap])
#define sync_lock_test_and_set_optab \
(&direct_optab_table[(int) DOI_sync_lock_test_and_set])
#define sync_lock_release_optab \
(&direct_optab_table[(int) DOI_sync_lock_release])
#define atomic_exchange_optab \ #define atomic_exchange_optab \
(&direct_optab_table[(int) DOI_atomic_exchange]) (&direct_optab_table[(int) DOI_atomic_exchange])
...@@ -956,6 +956,9 @@ extern void set_optab_libfunc (optab, enum machine_mode, const char *); ...@@ -956,6 +956,9 @@ extern void set_optab_libfunc (optab, enum machine_mode, const char *);
extern void set_conv_libfunc (convert_optab, enum machine_mode, extern void set_conv_libfunc (convert_optab, enum machine_mode,
enum machine_mode, const char *); enum machine_mode, const char *);
/* Call this to install all of the __sync libcalls up to size MAX. */
extern void init_sync_libfuncs (int max);
/* Generate code for a FIXED_CONVERT_EXPR. */ /* Generate code for a FIXED_CONVERT_EXPR. */
extern void expand_fixed_convert (rtx, rtx, int, int); extern void expand_fixed_convert (rtx, rtx, int, int);
...@@ -966,7 +969,7 @@ extern void expand_float (rtx, rtx, int); ...@@ -966,7 +969,7 @@ extern void expand_float (rtx, rtx, int);
enum insn_code can_float_p (enum machine_mode, enum machine_mode, int); enum insn_code can_float_p (enum machine_mode, enum machine_mode, int);
/* Return true if there is an inline compare and swap pattern. */ /* Return true if there is an inline compare and swap pattern. */
extern bool can_compare_and_swap_p (enum machine_mode); extern bool can_compare_and_swap_p (enum machine_mode, bool);
/* Generate code for a compare and swap. */ /* Generate code for a compare and swap. */
extern bool expand_atomic_compare_and_swap (rtx *, rtx *, rtx, rtx, rtx, bool, extern bool expand_atomic_compare_and_swap (rtx *, rtx *, rtx, rtx, rtx, bool,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment