diff options
author | Richard Henderson <rth@redhat.com> | 2011-11-07 15:11:55 -0800 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2011-11-07 15:11:55 -0800 |
commit | cedb4a1ad0ff0cfbcbd29a1066b440bc66887f4d (patch) | |
tree | 52678eae26470ab300ea093fc393e910585625cb /gcc/optabs.h | |
parent | 13fc31c2c49bbe4ca18bb1bf90007d03ba7ab13b (diff) | |
download | gcc-cedb4a1ad0ff0cfbcbd29a1066b440bc66887f4d.zip gcc-cedb4a1ad0ff0cfbcbd29a1066b440bc66887f4d.tar.gz gcc-cedb4a1ad0ff0cfbcbd29a1066b440bc66887f4d.tar.bz2 |
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
Diffstat (limited to 'gcc/optabs.h')
-rw-r--r-- | gcc/optabs.h | 99 |
1 files changed, 51 insertions, 48 deletions
diff --git a/gcc/optabs.h b/gcc/optabs.h index d70b3fa..bc705dc 100644 --- a/gcc/optabs.h +++ b/gcc/optabs.h @@ -386,6 +386,30 @@ enum optab_index /* Perform a raise to the power of integer. */ 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 }; @@ -570,6 +594,23 @@ enum optab_index #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. */ enum convert_optab_index { @@ -659,8 +700,10 @@ enum direct_optab_index DOI_cmpstrn, DOI_cmpmem, - /* Synchronization primitives. This first set is atomic operation for - which we don't care about the resulting value. */ + /* Atomic clear with release semantics. */ + DOI_sync_lock_release, + + /* Atomic operation with no resulting value. */ DOI_sync_add, DOI_sync_sub, DOI_sync_ior, @@ -668,33 +711,6 @@ enum direct_optab_index DOI_sync_xor, 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. */ DOI_atomic_exchange, DOI_atomic_compare_and_swap, @@ -748,30 +764,14 @@ typedef struct direct_optab_d *direct_optab; #define cmpstr_optab (&direct_optab_table[(int) DOI_cmpstr]) #define cmpstrn_optab (&direct_optab_table[(int) DOI_cmpstrn]) #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_sub_optab (&direct_optab_table[(int) DOI_sync_sub]) #define sync_ior_optab (&direct_optab_table[(int) DOI_sync_ior]) #define sync_and_optab (&direct_optab_table[(int) DOI_sync_and]) #define sync_xor_optab (&direct_optab_table[(int) DOI_sync_xor]) #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 \ (&direct_optab_table[(int) DOI_atomic_exchange]) @@ -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, 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. */ extern void expand_fixed_convert (rtx, rtx, int, 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); /* 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. */ extern bool expand_atomic_compare_and_swap (rtx *, rtx *, rtx, rtx, rtx, bool, |