* target.def (can_compare_and_swap_p): Define target hook. * targhooks.c (default_can_compare_and_swap_p): Provide default hook. * targhooks.h (default_can_compare_and_swap_p): Provide prototype. * doc/tm.texi (target_can_compare_and_swap_p): Provide description. * doc/tm.texi.in (TARGET_CAN_COMPARE_AND_SWAP_P): Provide location. * java/builtins.c. Remove backend includes, include target.h. (compareAndSwapInt_builtin, compareAndSwapLong_builtin, compareAndSwapObject_builtin, VMSupportsCS8_builtin): Use compare_and_swap_p target hook. Index: target.def =================================================================== *** target.def (revision 217057) --- target.def (working copy) *************** specific target options and the caller d *** 5185,5190 **** --- 5185,5199 ---- bool, (tree caller, tree callee), default_target_can_inline_p) + DEFHOOK + (can_compare_and_swap_p, + "This macro returns true if the target can perform an atomic\n\ + compare_and_swap operation on an object of machine mode @var{mode}.\n\ + @var{allow_libcall} is a boolean which is used to indicate whether the\n\ + operation is allowed to be performed with a libcall.", + bool, (machine_mode mode, bool allow_libcall), + default_can_compare_and_swap_p) + HOOK_VECTOR_END (target_option) /* For targets that need to mark extra registers as live on entry to Index: targhooks.c =================================================================== *** targhooks.c (revision 217057) --- targhooks.c (working copy) *************** default_target_can_inline_p (tree caller *** 1322,1327 **** --- 1322,1334 ---- return ret; } + bool + default_can_compare_and_swap_p (machine_mode mode, bool allow_libcall) + { + return can_compare_and_swap_p (mode, allow_libcall); + } + + #ifndef HAVE_casesi # define HAVE_casesi 0 #endif Index: targhooks.h =================================================================== *** targhooks.h (revision 217057) --- targhooks.h (working copy) *************** extern tree std_gimplify_va_arg_expr (tr *** 220,224 **** --- 220,226 ---- extern bool can_use_doloop_if_innermost (const widest_int &, const widest_int &, unsigned int, bool); + extern bool default_can_compare_and_swap_p (machine_mode, bool); + #endif /* GCC_TARGHOOKS_H */ Index: doc/tm.texi =================================================================== *** doc/tm.texi (revision 217057) --- doc/tm.texi (working copy) *************** default, inlining is not allowed if the *** 9742,9747 **** --- 9742,9754 ---- specific target options and the caller does not use the same options. @end deftypefn + @deftypefn {Target Hook} bool TARGET_CAN_COMPARE_AND_SWAP_P (machine_mode @var{mode}, bool @var{allow_libcall}) + This macro returns true if the target can perform an atomic + compare_and_swap operation on an object of machine mode @var{mode}. + @var{allow_libcall} is a boolean which is used to indicate whether the + operation is allowed to be performed with a libcall. + @end deftypefn + @node Emulated TLS @section Emulating TLS @cindex Emulated TLS Index: doc/tm.texi.in =================================================================== *** doc/tm.texi.in (revision 217057) --- doc/tm.texi.in (working copy) *************** on this implementation detail. *** 7227,7232 **** --- 7227,7234 ---- @hook TARGET_CAN_INLINE_P + @hook TARGET_CAN_COMPARE_AND_SWAP_P + @node Emulated TLS @section Emulating TLS @cindex Emulated TLS Index: java/builtins.c =================================================================== *** java/builtins.c (revision 217057) --- java/builtins.c (working copy) *************** The Free Software Foundation is independ *** 37,49 **** #include "flags.h" #include "langhooks.h" #include "java-tree.h" ! ! /* FIXME: All these headers are necessary for sync_compare_and_swap. ! Front ends should never have to look at that. */ ! #include "rtl.h" ! #include "insn-codes.h" ! #include "expr.h" ! #include "optabs.h" static tree max_builtin (tree, tree); static tree min_builtin (tree, tree); --- 37,43 ---- #include "flags.h" #include "langhooks.h" #include "java-tree.h" ! #include "target.h" static tree max_builtin (tree, tree); static tree min_builtin (tree, tree); *************** compareAndSwapInt_builtin (tree method_r *** 320,326 **** tree orig_call) { machine_mode mode = TYPE_MODE (int_type_node); ! if (can_compare_and_swap_p (mode, flag_use_atomic_builtins)) { tree addr, stmt; enum built_in_function fncode = BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_4; --- 314,321 ---- tree orig_call) { machine_mode mode = TYPE_MODE (int_type_node); ! if (targetm.target_option.can_compare_and_swap_p (mode, ! flag_use_atomic_builtins)) { tree addr, stmt; enum built_in_function fncode = BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_4; *************** compareAndSwapLong_builtin (tree method_ *** 344,352 **** /* We don't trust flag_use_atomic_builtins for multi-word compareAndSwap. Some machines such as ARM have atomic libfuncs but not the multi-word versions. */ ! if (can_compare_and_swap_p (mode, ! (flag_use_atomic_builtins ! && GET_MODE_SIZE (mode) <= UNITS_PER_WORD))) { tree addr, stmt; enum built_in_function fncode = BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_8; --- 339,347 ---- /* We don't trust flag_use_atomic_builtins for multi-word compareAndSwap. Some machines such as ARM have atomic libfuncs but not the multi-word versions. */ ! if (targetm.target_option.can_compare_and_swap_p (mode, ! (flag_use_atomic_builtins ! && GET_MODE_SIZE (mode) <= UNITS_PER_WORD))) { tree addr, stmt; enum built_in_function fncode = BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_8; *************** compareAndSwapObject_builtin (tree metho *** 366,372 **** tree orig_call) { machine_mode mode = TYPE_MODE (ptr_type_node); ! if (can_compare_and_swap_p (mode, flag_use_atomic_builtins)) { tree addr, stmt; enum built_in_function builtin; --- 361,368 ---- tree orig_call) { machine_mode mode = TYPE_MODE (ptr_type_node); ! if (targetm.target_option.can_compare_and_swap_p (mode, ! flag_use_atomic_builtins)) { tree addr, stmt; enum built_in_function builtin; *************** VMSupportsCS8_builtin (tree method_retur *** 446,452 **** { machine_mode mode = TYPE_MODE (long_type_node); gcc_assert (method_return_type == boolean_type_node); ! if (can_compare_and_swap_p (mode, false)) return boolean_true_node; else return boolean_false_node; --- 442,448 ---- { machine_mode mode = TYPE_MODE (long_type_node); gcc_assert (method_return_type == boolean_type_node); ! if (targetm.target_option.can_compare_and_swap_p (mode, false)) return boolean_true_node; else return boolean_false_node;