This is the main patch which implements all the code for the new
__sync_mem routines which take a memory model as a parameter.
I used the previously approved and checked in __sync_mem_exchange
routine as the model and added all the rest. The only difference is I'm
not adding the x86 patterns yet. I decided to implement just the generic
routines first so that we will know they all pass the tests on their
own. Then we'll get the target specific patterns for x86, ppc, arm and
whatever else people are worried about seperately..
Once these are in place, the c++ atomic.h wrappers can be changed to use
them as and we'll finally have C++0x support.
A couple of caveats.
* __sync_mem_compare_exchange has the skeleton in place, but not the
guts. There are some issues that rth and I will work out later, I just
don't want to hold up the rest of the patch for that. Right now it will
fail the compare_exchange tests.
* I will revisit exactly where synchronization fences need to be
issued for each of these routines later as well. This is a first cut and
again I want to get the code into the codebase so other things can get
started. Fine tuning can be made later.
Bootstraps on x86-64-unknown-linux-gnu and causes no new regression.
Ok for the branch?
* expr.h (expand_sync_mem_exchange): Change parameter order.
(expand_sync_mem_*): New prototypes.
* optabs.h (DOI_sync_mem_*): Add new optable enums.
(sync_mem_*_optab): Add new #defines for table entries.
* genopinit.c (const optabs[]): Add direct optab handlers.
* optabs.c (expand_sync_mem_exchange): Change parameter order, and use
mem_thread_fence if it exists.
(expand_sync_mem_compare_exchange, expand_sync_mem_load,
expand_sync_mem_store, expand_sync_mem_fetch_op): New. Expand
__sync_mem functions which handle multiple integral types.
* builtins.c (maybe_convert_modes): New. Factor out common code for
ensuring an integer argument is in the proper mode.
(expand_builtin_sync_operation, expand_builtin_compare_and_swap,
expand_builtin_sync_lock_test_and_set): Use maybe_convert_modes.
(expand_builtin_sync_lock_release): Relocate higher in the file.
(get_memmodel): Don't assume the memmodel is the 3rd argument.
(expand_builtin_sync_mem_exchange): Change error check and use
maybe_convert_modes.
(expand_builtin_sync_mem_compare_exchange): New.
(expand_builtin_sync_mem_load, expand_builtin_sync_mem_store): New.
(expand_builtin_sync_mem_fetch_op): New.
(expand_builtin_sync_mem_flag_test_and_set): New.
(expand_builtin_sync_mem_flag_clear): New.
(expand_builtin_sync_mem_thread_fence): New.
(expand_builtin_sync_mem_signal_fence): New.
(expand_builtin): Handle BUILT_IN_SYNC_MEM_* types.
* c-family/c-common.c (resolve_overloaded_builtin): Handle
BUILT_IN_SYNC_MEM_* types.
* builtin-types.def (BT_FN_I{1,2,4,8,16}_VPTR_INT): New builtin type.
(BT_FN_VOID_VPTR_INT, BT_FN_BOOL_VPTR_INT): New builtin types.
(BT_FN_VOID_VPTR_I{1,2,4,8,16}_INT: New builtin type.
(BT_FN_BOOL_VPTR_PTR_I{1,2,4,8,16}_INT_INT): New builtin type.
* fortran/types.def (BT_FN_VOID_INT): New type.
(BT_FN_I{1,2,4,8,16}_VPTR_INT): New builtin type.
(BT_FN_VOID_VPTR_INT, BT_FN_BOOL_VPTR_INT): New builtin types.
(BT_FN_VOID_VPTR_I{1,2,4,8,16}_INT: New builtin type.
(BT_FN_BOOL_VPTR_PTR_I{1,2,4,8,16}_INT_INT): New builtin type.
* sync-builtins.def (BUILT_IN_SYNC_MEM_*): New sync builtins.
Index: expr.h
===================================================================
*** expr.h (revision 175331)
--- expr.h (working copy)
*************** rtx expand_bool_compare_and_swap (rtx, r
*** 217,223 ****
rtx expand_sync_operation (rtx, rtx, enum rtx_code);
rtx expand_sync_fetch_operation (rtx, rtx, enum rtx_code, bool, rtx);
rtx expand_sync_lock_test_and_set (rtx, rtx, rtx);
! rtx expand_sync_mem_exchange (enum memmodel, rtx, rtx, rtx);
/* Functions from expmed.c: */
--- 217,234 ----
rtx expand_sync_operation (rtx, rtx, enum rtx_code);
rtx expand_sync_fetch_operation (rtx, rtx, enum rtx_code, bool, rtx);
rtx expand_sync_lock_test_and_set (rtx, rtx, rtx);
!
! rtx expand_sync_mem_exchange (rtx, rtx, rtx, enum memmodel);
! rtx expand_sync_mem_compare_exchange (rtx, rtx, rtx, rtx, enum memmodel,
! enum memmodel);
! rtx expand_sync_mem_load (rtx, rtx, enum memmodel);
! void expand_sync_mem_store (rtx, rtx, enum memmodel);
! rtx expand_sync_mem_fetch_op (rtx, rtx, rtx, enum rtx_code, enum memmodel);
! rtx expand_sync_mem_flag_test_and_set (rtx, rtx, enum memmodel);
! void expand_sync_mem_flag_clear (rtx, enum memmodel);
! void expand_sync_mem_thread_fence (enum memmodel);
! void expand_sync_mem_signal_fence (enum memmodel);
!
/* Functions from expmed.c: */
Index: optabs.h
===================================================================
*** optabs.h (revision 175331)
--- optabs.h (working copy)
*************** enum direct_optab_index
*** 679,684 ****
--- 679,696 ----
/* Atomic operations with C++0x memory model parameters. */
DOI_sync_mem_exchange,
+ DOI_sync_mem_compare_exchange,
+ DOI_sync_mem_load,
+ DOI_sync_mem_store,
+ DOI_sync_mem_fetch_add,
+ DOI_sync_mem_fetch_sub,
+ DOI_sync_mem_fetch_and,
+ DOI_sync_mem_fetch_xor,
+ DOI_sync_mem_fetch_or,
+ DOI_sync_mem_flag_test_and_set,
+ DOI_sync_mem_flag_clear,
+ DOI_sync_mem_thread_fence,
+ DOI_sync_mem_signal_fence,
DOI_MAX
};
*************** typedef struct direct_optab_d *direct_op
*** 730,735 ****
--- 742,771 ----
#define sync_mem_exchange_optab \
(&direct_optab_table[(int) DOI_sync_mem_exchange])
+ #define sync_mem_compare_exchange_optab \
+ (&direct_optab_table[(int) DOI_sync_mem_compare_exchange])
+ #define sync_mem_load_optab \
+ (&direct_optab_table[(int) DOI_sync_mem_load])
+ #define sync_mem_store_optab \
+ (&direct_optab_table[(int) DOI_sync_mem_store])
+ #define sync_mem_fetch_add_optab \
+ (&direct_optab_table[(int) DOI_sync_mem_fetch_add])
+ #define sync_mem_fetch_sub_optab \
+ (&direct_optab_table[(int) DOI_sync_mem_fetch_sub])
+ #define sync_mem_fetch_and_optab \
+ (&direct_optab_table[(int) DOI_sync_mem_fetch_and])
+ #define sync_mem_fetch_xor_optab \
+ (&direct_optab_table[(int) DOI_sync_mem_fetch_xor])
+ #define sync_mem_fetch_or_optab \
+ (&direct_optab_table[(int) DOI_sync_mem_fetch_or])
+ #define sync_mem_flag_test_and_set_optab \
+ (&direct_optab_table[(int) DOI_sync_mem_flag_test_and_set])
+ #define sync_mem_flag_clear_optab \
+ (&direct_optab_table[(int) DOI_sync_mem_flag_clear])
+ #define sync_mem_thread_fence_optab \
+ (&direct_optab_table[(int) DOI_sync_mem_thread_fence])
+ #define sync_mem_signal_fence_optab \
+ (&direct_optab_table[(int) DOI_sync_mem_signal_fence])
/* Target-dependent globals. */
struct target_optabs {
Index: genopinit.c
===================================================================
*** genopinit.c (revision 175331)
--- genopinit.c (working copy)
*************** static const char * const optabs[] =
*** 242,247 ****
--- 242,255 ----
"set_direct_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_mem_exchange_optab, $A,
CODE_FOR_$(sync_mem_exchange$I$a$))",
+ "set_direct_optab_handler (sync_mem_compare_exchange_optab, $A,
CODE_FOR_$(sync_mem_compare_exchange$I$a$))",
+ "set_direct_optab_handler (sync_mem_load_optab, $A,
CODE_FOR_$(sync_mem_load$I$a$))",
+ "set_direct_optab_handler (sync_mem_store_optab, $A,
CODE_FOR_$(sync_mem_store$I$a$))",
+ "set_direct_optab_handler (sync_mem_fetch_add_optab, $A,
CODE_FOR_$(sync_mem_fetch_add$I$a$))",
+ "set_direct_optab_handler (sync_mem_fetch_sub_optab, $A,
CODE_FOR_$(sync_mem_fetch_sub$I$a$))",
+ "set_direct_optab_handler (sync_mem_fetch_and_optab, $A,
CODE_FOR_$(sync_mem_fetch_and$I$a$))",
+ "set_direct_optab_handler (sync_mem_fetch_xor_optab, $A,
CODE_FOR_$(sync_mem_fetch_xor$I$a$))",
+ "set_direct_optab_handler (sync_mem_fetch_or_optab, $A,
CODE_FOR_$(sync_mem_fetch_or$I$a$))",
"set_optab_handler (vec_set_optab, $A, CODE_FOR_$(vec_set$a$))",
"set_optab_handler (vec_extract_optab, $A, CODE_FOR_$(vec_extract$a$))",
"set_optab_handler (vec_extract_even_optab, $A,
CODE_FOR_$(vec_extract_even$a$))",
Index: optabs.c
===================================================================
*** optabs.c (revision 175331)
--- optabs.c (working copy)
*************** expand_sync_lock_test_and_set (rtx mem,
*** 7064,7070 ****
TARGET is an option place to stick the return value. */
rtx
! expand_sync_mem_exchange (enum memmodel model, rtx mem, rtx val, rtx target)
{
enum machine_mode mode = GET_MODE (mem);
enum insn_code icode;
--- 7064,7070 ----
TARGET is an option place to stick the return value. */
rtx
! expand_sync_mem_exchange (rtx target, rtx mem, rtx val, enum memmodel model)
{
enum machine_mode mode = GET_MODE (mem);
enum insn_code icode;
*************** expand_sync_mem_exchange (enum memmodel
*** 7092,7101 ****
--- 7092,7343 ----
icode = direct_optab_handler (sync_lock_test_and_set_optab, mode);
if ((icode != CODE_FOR_nothing) && (model == MEMMODEL_SEQ_CST ||
model == MEMMODEL_ACQ_REL))
+ #ifdef HAVE_sync_mem_thread_fence
+ emit_mem_thread_fence (model);
+ #else
expand_builtin_sync_synchronize ();
+ #endif
return expand_sync_lock_test_and_set (mem, val, target);
}
+
+ /* This function expands the atomic compare exchange operation:
+
+ MEMMODEL is the memory model variant to use.
+ TARGET is an option place to stick the return value. */
+
+ rtx
+ expand_sync_mem_compare_exchange (rtx target, rtx mem, rtx expected,
+ rtx desired, enum memmodel success,
+ enum memmodel failure)
+ {
+ enum machine_mode mode = GET_MODE (mem);
+ enum insn_code icode;
+
+ /* If the target supports the exchange directly, great. */
+ icode = direct_optab_handler (sync_mem_compare_exchange_optab, mode);
+ if (icode != CODE_FOR_nothing)
+ {
+ struct expand_operand ops[6];
+
+ create_output_operand (&ops[0], target, QImode);
+ create_output_operand (&ops[1], mem, mode);
+ /* VAL may have been promoted to a wider mode. Shrink it if so. */
+ create_convert_operand_to (&ops[2], expected, mode, true);
+ create_convert_operand_to (&ops[3], desired, mode, true);
+ create_integer_operand (&ops[4], success);
+ create_integer_operand (&ops[5], failure);
+ if (maybe_expand_insn (icode, 6, ops))
+ return ops[0].value;
+ }
+
+ /* Instead try the instruction with a compare_ swap instruction and
+ barriers assuming success (which must be the strongest model). */
+
+
+ icode = direct_optab_handler (sync_compare_and_swap_optab, mode);
+ if (icode == CODE_FOR_nothing)
+ return NULL_RTX;
+
+ return NULL_RTX;
+
+ #if 0
+
+ /* We're punting on implementing compare_exchange to get everything else
+ checked in, then we'll come back and implement this, as well as provide
+ the weak and strong variations. */
+
+ #ifdef HAVE_sync_mem_thread_fence
+ emit_mem_thread_fence (success);
+ #else
+ expand_builtin_sync_synchronize ();
+ #endif
+
+ /* Load '*expected into a register for the compare and swap */
+
+ /* Issue the compare and swap */
+ /* cmp = expand_CAS (mem, expected, desired, target, &result); */
+
+ /* If (cmp) target = cmp; return true if success. */
+
+ /* else { *expected = result; target = !cmp } */
+ /* Otherwise, copy old value into expected and return false; */
+
+ #ifdef HAVE_sync_mem_thread_fence
+ emit_mem_thread_fence (success);
+ #else
+ expand_builtin_sync_synchronize ();
+ #endif
+
+ return target;
+ #endif
+ }
+
+
+ /* This function expands the atomic load operation:
+ return the atomically loaded value in MEM.
+
+ MEMMODEL is the memory model variant to use.
+ TARGET is an option place to stick the return value. */
+
+ rtx
+ expand_sync_mem_load (rtx target, rtx mem, enum memmodel model)
+ {
+ enum machine_mode mode = GET_MODE (mem);
+ enum insn_code icode;
+
+ /* If the target supports the load directly, great. */
+ icode = direct_optab_handler (sync_mem_load_optab, mode);
+ if (icode != CODE_FOR_nothing)
+ {
+ struct expand_operand ops[3];
+
+ create_output_operand (&ops[0], target, mode);
+ create_fixed_operand (&ops[1], mem);
+ create_integer_operand (&ops[2], model);
+ if (maybe_expand_insn (icode, 3, ops))
+ return ops[0].value;
+ }
+
+ /* If there is no load, default to a move with barriers. */
+ if (target == const0_rtx)
+ target = gen_reg_rtx (mode);
+
+ /* Emit the appropriate barrier before the load. */
+ #ifdef HAVE_sync_mem_thread_fence
+ emit_mem_thread_fence (model);
+ #else
+ if (model != MEMMODEL_RELAXED)
+ expand_builtin_sync_synchronize ();
+ #endif
+
+ emit_move_insn (target, mem);
+
+ /* For SEQ_CST, also emit a barrier after the load. */
+ if (model == MEMMODEL_SEQ_CST)
+ #ifdef HAVE_sync_mem_thread_fence
+ emit_mem_thread_fence (model);
+ #else
+ expand_builtin_sync_synchronize ();
+ #endif
+
+ return target;
+ }
+
+ /* This function expands the atomic load operation:
+ return the atomically loaded value in MEM.
+
+ MEMMODEL is the memory model variant to use.
+ TARGET is an option place to stick the return value. */
+
+ void
+ expand_sync_mem_store (rtx mem, rtx val, enum memmodel model)
+ {
+ enum machine_mode mode = GET_MODE (mem);
+ enum insn_code icode;
+
+ /* If the target supports the store directly, great. */
+ icode = direct_optab_handler (sync_mem_store_optab, mode);
+ if (icode != CODE_FOR_nothing)
+ {
+ struct expand_operand ops[3];
+
+ create_output_operand (&ops[0], mem, mode);
+ create_fixed_operand (&ops[1], val);
+ create_integer_operand (&ops[2], model);
+ if (maybe_expand_insn (icode, 3, ops))
+ return;
+ }
+
+ /* If there is no mem_store, default to a move with barriers */
+
+ if (model == MEMMODEL_SEQ_CST)
+ #ifdef HAVE_sync_mem_thread_fence
+ emit_mem_thread_fence (model);
+ #else
+ expand_builtin_sync_synchronize ();
+ #endif
+
+ emit_move_insn (mem, val);
+
+ /* For SEQ_CST, also emit a barrier after the load. */
+ #ifdef HAVE_sync_mem_thread_fence
+ emit_mem_thread_fence (model);
+ #else
+ if (model != MEMMODEL_RELAXED)
+ expand_builtin_sync_synchronize ();
+ #endif
+ }
+
+ /* This function expands an atomic fetch_OP operation:
+ CODE is the operation to be performed.
+ atomically fetch MEM, perform the operation with VAL and return it to MEM.
+ return the previous value of MEM.
+
+ MEMMODEL is the memory model variant to use.
+ TARGET is an option place to stick the return value. */
+
+ rtx
+ expand_sync_mem_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code,
+ enum memmodel model)
+ {
+ enum machine_mode mode = GET_MODE (mem);
+ enum insn_code icode;
+
+ switch (code)
+ {
+ case PLUS:
+ icode = direct_optab_handler (sync_mem_fetch_add_optab, mode);
+ break;
+ case MINUS:
+ icode = direct_optab_handler (sync_mem_fetch_sub_optab, mode);
+ break;
+ case AND:
+ icode = direct_optab_handler (sync_mem_fetch_and_optab, mode);
+ break;
+ case XOR:
+ icode = direct_optab_handler (sync_mem_fetch_xor_optab, mode);
+ break;
+ case IOR:
+ icode = direct_optab_handler (sync_mem_fetch_or_optab, mode);
+ break;
+ default:
+ icode = CODE_FOR_nothing;
+ }
+
+ /* If the target supports the operation directly, great. */
+ if (icode != CODE_FOR_nothing)
+ {
+ struct expand_operand ops[4];
+
+ create_output_operand (&ops[0], target, mode);
+ create_fixed_operand (&ops[1], mem);
+ /* VAL may have been promoted to a wider mode. Shrink it if so. */
+ create_convert_operand_to (&ops[2], val, mode, true);
+ create_integer_operand (&ops[3], model);
+ if (maybe_expand_insn (icode, 4, ops))
+ return ops[0].value;
+ }
+
+ #ifdef HAVE_sync_mem_thread_fence
+ emit_mem_thread_fence (model);
+ #else
+ if (model != MEMMODEL_RELAXED)
+ expand_builtin_sync_synchronize ();
+ #endif
+
+ target = expand_sync_fetch_operation (mem, val, code, false, target);
+
+ #ifdef HAVE_sync_mem_thread_fence
+ emit_mem_thread_fence (model);
+ #else
+ if (model != MEMMODEL_RELAXED)
+ expand_builtin_sync_synchronize ();
+ #endif
+ return target;
+ }
+
+
/* Return true if OPERAND is suitable for operand number OPNO of
instruction ICODE. */
Index: builtins.c
===================================================================
*** builtins.c (revision 175331)
--- builtins.c (working copy)
*************** get_builtin_sync_mem (tree loc, enum mac
*** 5057,5062 ****
--- 5057,5084 ----
return mem;
}
+ /* Make sure an argument is in the right mode.
+ EXP is the tree argument.
+ MODE is the mode it should be in. */
+
+ static rtx
+ maybe_convert_modes (tree exp, enum machine_mode mode)
+ {
+ rtx val;
+ enum machine_mode old_mode;
+
+ val = expand_expr (exp, NULL_RTX, mode, EXPAND_NORMAL);
+ /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
+ of CONST_INTs, where we know the old_mode only from the call argument.
*/
+
+ old_mode = GET_MODE (val);
+ if (old_mode == VOIDmode)
+ old_mode = TYPE_MODE (TREE_TYPE (exp));
+ val = convert_modes (mode, old_mode, val, 1);
+ return val;
+ }
+
+
/* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
EXP is the CALL_EXPR. CODE is the rtx code
that corresponds to the arithmetic or logical operation from the name;
*************** expand_builtin_sync_operation (enum mach
*** 5071,5077 ****
rtx target, bool ignore)
{
rtx val, mem;
- enum machine_mode old_mode;
location_t loc = EXPR_LOCATION (exp);
if (code == NOT && warn_sync_nand)
--- 5093,5098 ----
*************** expand_builtin_sync_operation (enum mach
*** 5118,5131 ****
/* Expand the operands. */
mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
!
! val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX, mode, EXPAND_NORMAL);
! /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
! of CONST_INTs, where we know the old_mode only from the call argument.
*/
! old_mode = GET_MODE (val);
! if (old_mode == VOIDmode)
! old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1)));
! val = convert_modes (mode, old_mode, val, 1);
if (ignore)
return expand_sync_operation (mem, val, code);
--- 5139,5145 ----
/* Expand the operands. */
mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
! val = maybe_convert_modes (CALL_EXPR_ARG (exp, 1), mode);
if (ignore)
return expand_sync_operation (mem, val, code);
*************** expand_builtin_compare_and_swap (enum ma
*** 5143,5171 ****
bool is_bool, rtx target)
{
rtx old_val, new_val, mem;
- enum machine_mode old_mode;
/* Expand the operands. */
mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
!
!
! old_val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX,
! mode, EXPAND_NORMAL);
! /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
! of CONST_INTs, where we know the old_mode only from the call argument.
*/
! old_mode = GET_MODE (old_val);
! if (old_mode == VOIDmode)
! old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1)));
! old_val = convert_modes (mode, old_mode, old_val, 1);
!
! new_val = expand_expr (CALL_EXPR_ARG (exp, 2), NULL_RTX,
! mode, EXPAND_NORMAL);
! /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
! of CONST_INTs, where we know the old_mode only from the call argument.
*/
! old_mode = GET_MODE (new_val);
! if (old_mode == VOIDmode)
! old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 2)));
! new_val = convert_modes (mode, old_mode, new_val, 1);
if (is_bool)
return expand_bool_compare_and_swap (mem, old_val, new_val, target);
--- 5157,5167 ----
bool is_bool, rtx target)
{
rtx old_val, new_val, mem;
/* Expand the operands. */
mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
! old_val = maybe_convert_modes (CALL_EXPR_ARG (exp, 1), mode);
! new_val = maybe_convert_modes (CALL_EXPR_ARG (exp, 2), mode);
if (is_bool)
return expand_bool_compare_and_swap (mem, old_val, new_val, target);
*************** expand_builtin_sync_lock_test_and_set (e
*** 5184,5204 ****
rtx target)
{
rtx val, mem;
- enum machine_mode old_mode;
/* Expand the operands. */
mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
! val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX, mode, EXPAND_NORMAL);
! /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
! of CONST_INTs, where we know the old_mode only from the call argument.
*/
! old_mode = GET_MODE (val);
! if (old_mode == VOIDmode)
! old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1)));
! val = convert_modes (mode, old_mode, val, 1);
return expand_sync_lock_test_and_set (mem, val, target);
}
/* Given an integer representing an ``enum memmodel'', verify its
correctness and return the memory model enum. */
--- 5180,5221 ----
rtx target)
{
rtx val, mem;
/* Expand the operands. */
mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
! val = maybe_convert_modes (CALL_EXPR_ARG (exp, 1), mode);
return expand_sync_lock_test_and_set (mem, val, target);
}
+ /* Expand the __sync_lock_release intrinsic. EXP is the CALL_EXPR. */
+
+ static void
+ expand_builtin_sync_lock_release (enum machine_mode mode, tree exp)
+ {
+ struct expand_operand ops[2];
+ enum insn_code icode;
+ rtx mem;
+
+ /* Expand the operands. */
+ mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
+
+ /* If there is an explicit operation in the md file, use it. */
+ icode = direct_optab_handler (sync_lock_release_optab, mode);
+ if (icode != CODE_FOR_nothing)
+ {
+ create_fixed_operand (&ops[0], mem);
+ create_input_operand (&ops[1], const0_rtx, mode);
+ if (maybe_expand_insn (icode, 2, ops))
+ return;
+ }
+
+ /* Otherwise we can implement this operation by emitting a barrier
+ followed by a store of zero. */
+ expand_builtin_sync_synchronize ();
+ emit_move_insn (mem, const0_rtx);
+ }
+
/* Given an integer representing an ``enum memmodel'', verify its
correctness and return the memory model enum. */
*************** get_memmodel (tree exp)
*** 5209,5230 ****
if (TREE_CODE (exp) != INTEGER_CST)
{
! error ("third argument to builtin is an invalid memory model");
! return MEMMODEL_SEQ_CST;
}
op = expand_normal (exp);
if (INTVAL (op) < 0 || INTVAL (op) >= MEMMODEL_LAST)
{
! error ("third argument to builtin is an invalid memory model");
! return MEMMODEL_SEQ_CST;
}
return (enum memmodel) INTVAL (op);
}
/* Expand the __sync_mem_exchange intrinsic:
!
! TYPE __sync_mem_exchange (TYPE *to, TYPE from, enum memmodel)
!
EXP is the CALL_EXPR.
TARGET is an optional place for us to store the results. */
--- 5226,5245 ----
if (TREE_CODE (exp) != INTEGER_CST)
{
! error ("invalid memory model argument to builtin");
! return MEMMODEL_RELAXED;
}
op = expand_normal (exp);
if (INTVAL (op) < 0 || INTVAL (op) >= MEMMODEL_LAST)
{
! error ("invalid memory model argument to builtin");
! return MEMMODEL_RELAXED;
}
return (enum memmodel) INTVAL (op);
}
/* Expand the __sync_mem_exchange intrinsic:
! TYPE __sync_mem_exchange (TYPE *object, TYPE desired, enum memmodel)
EXP is the CALL_EXPR.
TARGET is an optional place for us to store the results. */
*************** static rtx
*** 5232,5246 ****
expand_builtin_sync_mem_exchange (enum machine_mode mode, tree exp, rtx
target)
{
rtx val, mem;
- enum machine_mode old_mode;
enum memmodel model;
model = get_memmodel (CALL_EXPR_ARG (exp, 2));
! if (model != MEMMODEL_RELAXED
! && model != MEMMODEL_SEQ_CST
! && model != MEMMODEL_ACQ_REL
! && model != MEMMODEL_RELEASE
! && model != MEMMODEL_ACQUIRE)
{
error ("invalid memory model for %<__sync_mem_exchange%>");
return NULL_RTX;
--- 5247,5256 ----
expand_builtin_sync_mem_exchange (enum machine_mode mode, tree exp, rtx
target)
{
rtx val, mem;
enum memmodel model;
model = get_memmodel (CALL_EXPR_ARG (exp, 2));
! if (model == MEMMODEL_CONSUME)
{
error ("invalid memory model for %<__sync_mem_exchange%>");
return NULL_RTX;
*************** expand_builtin_sync_mem_exchange (enum m
*** 5248,5262 ****
/* Expand the operands. */
mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
! val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX, mode, EXPAND_NORMAL);
! /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
! of CONST_INTs, where we know the old_mode only from the call argument.
*/
! old_mode = GET_MODE (val);
! if (old_mode == VOIDmode)
! old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1)));
! val = convert_modes (mode, old_mode, val, 1);
! return expand_sync_mem_exchange (model, mem, val, target);
}
/* Expand the __sync_synchronize intrinsic. */
--- 5258,5461 ----
/* Expand the operands. */
mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
! val = maybe_convert_modes (CALL_EXPR_ARG (exp, 1), mode);
!
! return expand_sync_mem_exchange (target, mem, val, model);
! }
!
! /* Expand the __sync_mem_compare_exchange intrinsic:
! bool __sync_mem_compare_exchange (TYPE *object, TYPE *expect,
! TYPE desired, enum memmodel success,
! enum memmodel failure)
! EXP is the CALL_EXPR.
! TARGET is an optional place for us to store the results. */
!
! static rtx
! expand_builtin_sync_mem_compare_exchange (enum machine_mode mode, tree exp,
! rtx target)
! {
! rtx expect, desired, mem;
! enum memmodel success, failure;
!
! success = get_memmodel (CALL_EXPR_ARG (exp, 3));
! failure = get_memmodel (CALL_EXPR_ARG (exp, 4));
!
! if (failure == MEMMODEL_RELEASE || failure == MEMMODEL_ACQ_REL)
! {
! error ("invalid failure memory model for
%<__sync_mem_compare_exchange%>");
! return NULL_RTX;
! }
!
! if (failure > success)
! {
! error ("failure memory model cannot be stronger than success memory
model for %<__sync_mem_compare_exchange%>");
! return NULL_RTX;
! }
!
! /* Expand the operands. */
! mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
!
! expect = expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX, ptr_mode,
! EXPAND_NORMAL);
! expect = convert_memory_address (Pmode, expect);
!
! desired = maybe_convert_modes (CALL_EXPR_ARG (exp, 2), mode);
!
! return expand_sync_mem_compare_exchange (target, mem, expect, desired,
! success, failure);
! }
!
! /* Expand the __sync_mem_load intrinsic:
! TYPE __sync_mem_load (TYPE *object, enum memmodel)
! EXP is the CALL_EXPR.
! TARGET is an optional place for us to store the results. */
!
! static rtx
! expand_builtin_sync_mem_load (enum machine_mode mode, tree exp, rtx target)
! {
! rtx mem;
! enum memmodel model;
!
! model = get_memmodel (CALL_EXPR_ARG (exp, 1));
! if (model == MEMMODEL_RELEASE
! || model == MEMMODEL_ACQ_REL)
! {
! error ("invalid memory model for %<__sync_mem_load%>");
! return NULL_RTX;
! }
!
! /* Expand the operand. */
! mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
!
! return expand_sync_mem_load (target, mem, model);
! }
!
!
! /* Expand the __sync_mem_store intrinsic:
! void __sync_mem_store (TYPE *object, TYPE desired, enum memmodel)
! EXP is the CALL_EXPR.
! TARGET is an optional place for us to store the results. */
!
! static void
! expand_builtin_sync_mem_store (enum machine_mode mode, tree exp)
! {
! rtx mem, val;
! enum memmodel model;
!
! model = get_memmodel (CALL_EXPR_ARG (exp, 2));
! if (model != MEMMODEL_RELAXED
! && model != MEMMODEL_SEQ_CST
! && model != MEMMODEL_RELEASE)
! {
! error ("invalid memory model for %<__sync_mem_store%>");
! return;
! }
!
! /* Expand the operands. */
! mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
! val = maybe_convert_modes (CALL_EXPR_ARG (exp, 1), mode);
!
! expand_sync_mem_store (mem, val, model);
! }
!
! /* Expand the __sync_mem_fetch_XXX intrinsic:
! TYPE __sync_mem_fetch_XXX (TYPE *object, TYPE val, enum memmodel)
! EXP is the CALL_EXPR.
! TARGET is an optional place for us to store the results.
! CODE is the operation, PLUS, MINUS, ADD, XOR, or IOR. */
!
! static rtx
! expand_builtin_sync_mem_fetch_op (enum machine_mode mode, tree exp, rtx
target,
! enum rtx_code code)
! {
! rtx val, mem;
! enum memmodel model;
!
! model = get_memmodel (CALL_EXPR_ARG (exp, 2));
!
! /* Expand the operands. */
! mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
! val = maybe_convert_modes (CALL_EXPR_ARG (exp, 1), mode);
!
! return expand_sync_mem_fetch_op (target, mem, val, code, model);
! }
!
! /* Expand the __sync_mem_flag_test_and_set intrinsic:
! bool __sync_mem_flag_test_and_set (char *object, enum memmodel)
! EXP is the CALL_EXPR.
! TARGET is an optional place for us to store the results. */
!
! static rtx
! expand_builtin_sync_mem_flag_test_and_set (tree exp, rtx target)
! {
! rtx mem;
! enum memmodel model;
!
! model = get_memmodel (CALL_EXPR_ARG (exp, 1));
! /* sync_lock_test_and_set is an acquire barrier, so a barrier may be needed
! before. */
!
! if (model == MEMMODEL_SEQ_CST || model == MEMMODEL_ACQ_REL
! || model == MEMMODEL_RELEASE)
! expand_builtin_sync_synchronize ();
!
! /* Expand the operand. */
! mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), QImode);
!
! return expand_sync_lock_test_and_set (mem, const1_rtx, target);
! }
!
! /* Expand the __sync_mem_flag_clear intrinsic:
! void __sync_mem_flag_clear (char *object, enum memmodel)
! EXP is the CALL_EXPR. */
!
! static void
! expand_builtin_sync_mem_flag_clear (tree exp)
! {
! enum memmodel model;
!
! model = get_memmodel (CALL_EXPR_ARG (exp, 1));
!
! if (model == MEMMODEL_ACQUIRE || model == MEMMODEL_ACQ_REL)
! {
! error ("invalid memory model for %<__sync_mem_flag_clear%>");
! return;
! }
!
! expand_builtin_sync_lock_release (QImode, exp);
! /* sync_lock_release is a release barrier, so we may need a seq-cst
! barrier afterwards. */
! if (model == MEMMODEL_SEQ_CST)
! expand_builtin_sync_synchronize ();
! }
!
! /* Expand the __sync_mem_thread_fence intrinsic:
! void __sync_mem_thread_fence (enum memmodel)
! EXP is the CALL_EXPR. */
!
! static void
! expand_builtin_sync_mem_thread_fence (tree exp)
! {
! enum memmodel model;
!
! model = get_memmodel (CALL_EXPR_ARG (exp, 0));
! if (model != MEMMODEL_RELAXED)
! expand_builtin_sync_synchronize ();
! }
!
! /* Expand the __sync_mem_signal_fence intrinsic:
! void __sync_mem_signal_fence (enum memmodel)
! EXP is the CALL_EXPR. */
!
! static void
! expand_builtin_sync_mem_signal_fence (tree exp)
! {
! enum memmodel model;
!
! model = get_memmodel (CALL_EXPR_ARG (exp, 0));
! if (model != MEMMODEL_RELAXED)
! expand_builtin_sync_synchronize ();
}
/* Expand the __sync_synchronize intrinsic. */
*************** expand_builtin_sync_synchronize (void)
*** 5291,5323 ****
expand_asm_stmt (x);
}
- /* Expand the __sync_lock_release intrinsic. EXP is the CALL_EXPR. */
-
- static void
- expand_builtin_sync_lock_release (enum machine_mode mode, tree exp)
- {
- struct expand_operand ops[2];
- enum insn_code icode;
- rtx mem;
-
- /* Expand the operands. */
- mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
-
- /* If there is an explicit operation in the md file, use it. */
- icode = direct_optab_handler (sync_lock_release_optab, mode);
- if (icode != CODE_FOR_nothing)
- {
- create_fixed_operand (&ops[0], mem);
- create_input_operand (&ops[1], const0_rtx, mode);
- if (maybe_expand_insn (icode, 2, ops))
- return;
- }
-
- /* Otherwise we can implement this operation by emitting a barrier
- followed by a store of zero. */
- expand_builtin_sync_synchronize ();
- emit_move_insn (mem, const0_rtx);
- }
/* Expand an expression EXP that calls a built-in function,
with result going to TARGET if that's convenient
--- 5490,5495 ----
*************** expand_builtin (tree exp, rtx target, rt
*** 6077,6093 ****
return target;
break;
- case BUILT_IN_SYNC_MEM_EXCHANGE_1:
- case BUILT_IN_SYNC_MEM_EXCHANGE_2:
- case BUILT_IN_SYNC_MEM_EXCHANGE_4:
- case BUILT_IN_SYNC_MEM_EXCHANGE_8:
- case BUILT_IN_SYNC_MEM_EXCHANGE_16:
- mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_MEM_EXCHANGE_1);
- target = expand_builtin_sync_mem_exchange (mode, exp, target);
- if (target)
- return target;
- break;
-
case BUILT_IN_SYNC_LOCK_TEST_AND_SET_1:
case BUILT_IN_SYNC_LOCK_TEST_AND_SET_2:
case BUILT_IN_SYNC_LOCK_TEST_AND_SET_4:
--- 6249,6254 ----
*************** expand_builtin (tree exp, rtx target, rt
*** 6112,6117 ****
--- 6273,6394 ----
expand_builtin_sync_synchronize ();
return const0_rtx;
+ case BUILT_IN_SYNC_MEM_EXCHANGE_1:
+ case BUILT_IN_SYNC_MEM_EXCHANGE_2:
+ case BUILT_IN_SYNC_MEM_EXCHANGE_4:
+ case BUILT_IN_SYNC_MEM_EXCHANGE_8:
+ case BUILT_IN_SYNC_MEM_EXCHANGE_16:
+ mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_MEM_EXCHANGE_1);
+ target = expand_builtin_sync_mem_exchange (mode, exp, target);
+ if (target)
+ return target;
+ break;
+
+ case BUILT_IN_SYNC_MEM_COMPARE_EXCHANGE_1:
+ case BUILT_IN_SYNC_MEM_COMPARE_EXCHANGE_2:
+ case BUILT_IN_SYNC_MEM_COMPARE_EXCHANGE_4:
+ case BUILT_IN_SYNC_MEM_COMPARE_EXCHANGE_8:
+ case BUILT_IN_SYNC_MEM_COMPARE_EXCHANGE_16:
+ mode =
+ get_builtin_sync_mode (fcode - BUILT_IN_SYNC_MEM_COMPARE_EXCHANGE_1);
+ target = expand_builtin_sync_mem_compare_exchange (mode, exp, target);
+ if (target)
+ return target;
+ break;
+
+ case BUILT_IN_SYNC_MEM_LOAD_1:
+ case BUILT_IN_SYNC_MEM_LOAD_2:
+ case BUILT_IN_SYNC_MEM_LOAD_4:
+ case BUILT_IN_SYNC_MEM_LOAD_8:
+ case BUILT_IN_SYNC_MEM_LOAD_16:
+ mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_MEM_LOAD_1);
+ target = expand_builtin_sync_mem_load (mode, exp, target);
+ if (target)
+ return target;
+ break;
+
+ case BUILT_IN_SYNC_MEM_STORE_1:
+ case BUILT_IN_SYNC_MEM_STORE_2:
+ case BUILT_IN_SYNC_MEM_STORE_4:
+ case BUILT_IN_SYNC_MEM_STORE_8:
+ case BUILT_IN_SYNC_MEM_STORE_16:
+ mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_MEM_STORE_1);
+ expand_builtin_sync_mem_store (mode, exp);
+ return const0_rtx;
+
+ case BUILT_IN_SYNC_MEM_FETCH_ADD_1:
+ case BUILT_IN_SYNC_MEM_FETCH_ADD_2:
+ case BUILT_IN_SYNC_MEM_FETCH_ADD_4:
+ case BUILT_IN_SYNC_MEM_FETCH_ADD_8:
+ case BUILT_IN_SYNC_MEM_FETCH_ADD_16:
+ mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_MEM_FETCH_ADD_1);
+ target = expand_builtin_sync_mem_fetch_op (mode, exp, target, PLUS);
+ if (target)
+ return target;
+ break;
+
+ case BUILT_IN_SYNC_MEM_FETCH_SUB_1:
+ case BUILT_IN_SYNC_MEM_FETCH_SUB_2:
+ case BUILT_IN_SYNC_MEM_FETCH_SUB_4:
+ case BUILT_IN_SYNC_MEM_FETCH_SUB_8:
+ case BUILT_IN_SYNC_MEM_FETCH_SUB_16:
+ mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_MEM_FETCH_SUB_1);
+ target = expand_builtin_sync_mem_fetch_op (mode, exp, target, MINUS);
+ if (target)
+ return target;
+ break;
+
+ case BUILT_IN_SYNC_MEM_FETCH_AND_1:
+ case BUILT_IN_SYNC_MEM_FETCH_AND_2:
+ case BUILT_IN_SYNC_MEM_FETCH_AND_4:
+ case BUILT_IN_SYNC_MEM_FETCH_AND_8:
+ case BUILT_IN_SYNC_MEM_FETCH_AND_16:
+ mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_MEM_FETCH_AND_1);
+ target = expand_builtin_sync_mem_fetch_op (mode, exp, target, AND);
+ if (target)
+ return target;
+ break;
+
+ case BUILT_IN_SYNC_MEM_FETCH_XOR_1:
+ case BUILT_IN_SYNC_MEM_FETCH_XOR_2:
+ case BUILT_IN_SYNC_MEM_FETCH_XOR_4:
+ case BUILT_IN_SYNC_MEM_FETCH_XOR_8:
+ case BUILT_IN_SYNC_MEM_FETCH_XOR_16:
+ mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_MEM_FETCH_XOR_1);
+ target = expand_builtin_sync_mem_fetch_op (mode, exp, target, XOR);
+ if (target)
+ return target;
+ break;
+
+ case BUILT_IN_SYNC_MEM_FETCH_OR_1:
+ case BUILT_IN_SYNC_MEM_FETCH_OR_2:
+ case BUILT_IN_SYNC_MEM_FETCH_OR_4:
+ case BUILT_IN_SYNC_MEM_FETCH_OR_8:
+ case BUILT_IN_SYNC_MEM_FETCH_OR_16:
+ mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_MEM_FETCH_OR_1);
+ target = expand_builtin_sync_mem_fetch_op (mode, exp, target, IOR);
+ if (target)
+ return target;
+ break;
+
+ case BUILT_IN_SYNC_MEM_FLAG_TEST_AND_SET:
+ target = expand_builtin_sync_mem_flag_test_and_set (exp, target);
+ if (target)
+ return target;
+ break;
+
+ case BUILT_IN_SYNC_MEM_FLAG_CLEAR:
+ expand_builtin_sync_mem_flag_clear (exp);
+ return const0_rtx;
+
+ case BUILT_IN_SYNC_MEM_THREAD_FENCE:
+ expand_builtin_sync_mem_thread_fence (exp);
+ return const0_rtx;
+
+ case BUILT_IN_SYNC_MEM_SIGNAL_FENCE:
+ expand_builtin_sync_mem_signal_fence (exp);
+ return const0_rtx;
+
case BUILT_IN_OBJECT_SIZE:
return expand_builtin_object_size (exp);
Index: c-family/c-common.c
===================================================================
*** c-family/c-common.c (revision 175331)
--- c-family/c-common.c (working copy)
*************** resolve_overloaded_builtin (location_t l
*** 9061,9066 ****
--- 9061,9074 ----
case BUILT_IN_SYNC_LOCK_TEST_AND_SET_N:
case BUILT_IN_SYNC_LOCK_RELEASE_N:
case BUILT_IN_SYNC_MEM_EXCHANGE_N:
+ case BUILT_IN_SYNC_MEM_COMPARE_EXCHANGE_N:
+ case BUILT_IN_SYNC_MEM_LOAD_N:
+ case BUILT_IN_SYNC_MEM_STORE_N:
+ case BUILT_IN_SYNC_MEM_FETCH_ADD_N:
+ case BUILT_IN_SYNC_MEM_FETCH_SUB_N:
+ case BUILT_IN_SYNC_MEM_FETCH_AND_N:
+ case BUILT_IN_SYNC_MEM_FETCH_XOR_N:
+ case BUILT_IN_SYNC_MEM_FETCH_OR_N:
{
int n = sync_resolve_size (function, params);
tree new_function, first_param, result;
*************** resolve_overloaded_builtin (location_t l
*** 9075,9081 ****
first_param = VEC_index (tree, params, 0);
result = build_function_call_vec (loc, new_function, params, NULL);
if (orig_code != BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_N
! && orig_code != BUILT_IN_SYNC_LOCK_RELEASE_N)
result = sync_resolve_return (first_param, result);
return result;
--- 9083,9090 ----
first_param = VEC_index (tree, params, 0);
result = build_function_call_vec (loc, new_function, params, NULL);
if (orig_code != BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_N
! && orig_code != BUILT_IN_SYNC_LOCK_RELEASE_N
! && orig_code != BUILT_IN_SYNC_MEM_STORE_N)
result = sync_resolve_return (first_param, result);
return result;
Index: builtin-types.def
===================================================================
*** builtin-types.def (revision 175331)
--- builtin-types.def (working copy)
*************** DEF_FUNCTION_TYPE_2 (BT_FN_BOOL_LONGPTR_
*** 315,320 ****
--- 315,327 ----
BT_BOOL, BT_PTR_LONG, BT_PTR_LONG)
DEF_FUNCTION_TYPE_2 (BT_FN_BOOL_ULONGLONGPTR_ULONGLONGPTR,
BT_BOOL, BT_PTR_ULONGLONG, BT_PTR_ULONGLONG)
+ DEF_FUNCTION_TYPE_2 (BT_FN_I1_VPTR_INT, BT_I1, BT_VOLATILE_PTR, BT_INT)
+ DEF_FUNCTION_TYPE_2 (BT_FN_I2_VPTR_INT, BT_I2, BT_VOLATILE_PTR, BT_INT)
+ DEF_FUNCTION_TYPE_2 (BT_FN_I4_VPTR_INT, BT_I4, BT_VOLATILE_PTR, BT_INT)
+ DEF_FUNCTION_TYPE_2 (BT_FN_I8_VPTR_INT, BT_I8, BT_VOLATILE_PTR, BT_INT)
+ DEF_FUNCTION_TYPE_2 (BT_FN_I16_VPTR_INT, BT_I16, BT_VOLATILE_PTR, BT_INT)
+ DEF_FUNCTION_TYPE_2 (BT_FN_VOID_VPTR_INT, BT_VOID, BT_VOLATILE_PTR, BT_INT)
+ DEF_FUNCTION_TYPE_2 (BT_FN_BOOL_VPTR_INT, BT_BOOL, BT_VOLATILE_PTR, BT_INT)
DEF_POINTER_TYPE (BT_PTR_FN_VOID_PTR_PTR, BT_FN_VOID_PTR_PTR)
*************** DEF_FUNCTION_TYPE_3 (BT_FN_I2_VPTR_I2_IN
*** 388,393 ****
--- 395,406 ----
DEF_FUNCTION_TYPE_3 (BT_FN_I4_VPTR_I4_INT, BT_I4, BT_VOLATILE_PTR, BT_I4,
BT_INT)
DEF_FUNCTION_TYPE_3 (BT_FN_I8_VPTR_I8_INT, BT_I8, BT_VOLATILE_PTR, BT_I8,
BT_INT)
DEF_FUNCTION_TYPE_3 (BT_FN_I16_VPTR_I16_INT, BT_I16, BT_VOLATILE_PTR, BT_I16,
BT_INT)
+ DEF_FUNCTION_TYPE_3 (BT_FN_VOID_VPTR_I1_INT, BT_VOID, BT_VOLATILE_PTR, BT_I1,
BT_INT)
+ DEF_FUNCTION_TYPE_3 (BT_FN_VOID_VPTR_I2_INT, BT_VOID, BT_VOLATILE_PTR, BT_I2,
BT_INT)
+ DEF_FUNCTION_TYPE_3 (BT_FN_VOID_VPTR_I4_INT, BT_VOID, BT_VOLATILE_PTR, BT_I4,
BT_INT)
+ DEF_FUNCTION_TYPE_3 (BT_FN_VOID_VPTR_I8_INT, BT_VOID, BT_VOLATILE_PTR, BT_I8,
BT_INT)
+ DEF_FUNCTION_TYPE_3 (BT_FN_VOID_VPTR_I16_INT, BT_VOID, BT_VOLATILE_PTR,
BT_I16, BT_INT)
+
DEF_FUNCTION_TYPE_4 (BT_FN_SIZE_CONST_PTR_SIZE_SIZE_FILEPTR,
BT_SIZE, BT_CONST_PTR, BT_SIZE, BT_SIZE, BT_FILEPTR)
*************** DEF_FUNCTION_TYPE_5 (BT_FN_INT_STRING_IN
*** 414,419 ****
--- 427,443 ----
DEF_FUNCTION_TYPE_5 (BT_FN_BOOL_LONG_LONG_LONG_LONGPTR_LONGPTR,
BT_BOOL, BT_LONG, BT_LONG, BT_LONG,
BT_PTR_LONG, BT_PTR_LONG)
+ DEF_FUNCTION_TYPE_5 (BT_FN_BOOL_VPTR_PTR_I1_INT_INT,
+ BT_BOOL, BT_VOLATILE_PTR, BT_PTR, BT_I1, BT_INT, BT_INT)
+ DEF_FUNCTION_TYPE_5 (BT_FN_BOOL_VPTR_PTR_I2_INT_INT,
+ BT_BOOL, BT_VOLATILE_PTR, BT_PTR, BT_I2, BT_INT, BT_INT)
+ DEF_FUNCTION_TYPE_5 (BT_FN_BOOL_VPTR_PTR_I4_INT_INT,
+ BT_BOOL, BT_VOLATILE_PTR, BT_PTR, BT_I4, BT_INT, BT_INT)
+ DEF_FUNCTION_TYPE_5 (BT_FN_BOOL_VPTR_PTR_I8_INT_INT,
+ BT_BOOL, BT_VOLATILE_PTR, BT_PTR, BT_I8, BT_INT, BT_INT)
+ DEF_FUNCTION_TYPE_5 (BT_FN_BOOL_VPTR_PTR_I16_INT_INT,
+ BT_BOOL, BT_VOLATILE_PTR, BT_PTR, BT_I16, BT_INT, BT_INT)
+
DEF_FUNCTION_TYPE_6 (BT_FN_INT_STRING_SIZE_INT_SIZE_CONST_STRING_VALIST_ARG,
BT_INT, BT_STRING, BT_SIZE, BT_INT, BT_SIZE,
Index: fortran/types.def
===================================================================
*** fortran/types.def (revision 175331)
--- fortran/types.def (working copy)
*************** DEF_FUNCTION_TYPE_1 (BT_FN_VOID_PTRPTR,
*** 85,90 ****
--- 85,92 ----
DEF_FUNCTION_TYPE_1 (BT_FN_VOID_VPTR, BT_VOID, BT_VOLATILE_PTR)
DEF_FUNCTION_TYPE_1 (BT_FN_UINT_UINT, BT_UINT, BT_UINT)
DEF_FUNCTION_TYPE_1 (BT_FN_PTR_PTR, BT_PTR, BT_PTR)
+ DEF_FUNCTION_TYPE_1 (BT_FN_VOID_INT, BT_VOID, BT_INT)
+
DEF_POINTER_TYPE (BT_PTR_FN_VOID_PTR, BT_FN_VOID_PTR)
*************** DEF_FUNCTION_TYPE_2 (BT_FN_I4_VPTR_I4, B
*** 98,103 ****
--- 100,113 ----
DEF_FUNCTION_TYPE_2 (BT_FN_I8_VPTR_I8, BT_I8, BT_VOLATILE_PTR, BT_I8)
DEF_FUNCTION_TYPE_2 (BT_FN_I16_VPTR_I16, BT_I16, BT_VOLATILE_PTR, BT_I16)
DEF_FUNCTION_TYPE_2 (BT_FN_VOID_PTR_PTR, BT_VOID, BT_PTR, BT_PTR)
+ DEF_FUNCTION_TYPE_2 (BT_FN_I1_VPTR_INT, BT_I1, BT_VOLATILE_PTR, BT_INT)
+ DEF_FUNCTION_TYPE_2 (BT_FN_I2_VPTR_INT, BT_I2, BT_VOLATILE_PTR, BT_INT)
+ DEF_FUNCTION_TYPE_2 (BT_FN_I4_VPTR_INT, BT_I4, BT_VOLATILE_PTR, BT_INT)
+ DEF_FUNCTION_TYPE_2 (BT_FN_I8_VPTR_INT, BT_I8, BT_VOLATILE_PTR, BT_INT)
+ DEF_FUNCTION_TYPE_2 (BT_FN_I16_VPTR_INT, BT_I16, BT_VOLATILE_PTR, BT_INT)
+ DEF_FUNCTION_TYPE_2 (BT_FN_VOID_VPTR_INT, BT_VOID, BT_VOLATILE_PTR, BT_INT)
+ DEF_FUNCTION_TYPE_2 (BT_FN_BOOL_VPTR_INT, BT_BOOL, BT_VOLATILE_PTR, BT_INT)
+
DEF_POINTER_TYPE (BT_PTR_FN_VOID_PTR_PTR, BT_FN_VOID_PTR_PTR)
*************** DEF_FUNCTION_TYPE_3 (BT_FN_I16_VPTR_I16_
*** 119,131 ****
BT_I16, BT_I16)
DEF_FUNCTION_TYPE_3 (BT_FN_VOID_OMPFN_PTR_UINT, BT_VOID, BT_PTR_FN_VOID_PTR,
BT_PTR, BT_UINT)
-
DEF_FUNCTION_TYPE_3 (BT_FN_I1_VPTR_I1_INT, BT_I1, BT_VOLATILE_PTR, BT_I1,
BT_INT)
DEF_FUNCTION_TYPE_3 (BT_FN_I2_VPTR_I2_INT, BT_I2, BT_VOLATILE_PTR, BT_I2,
BT_INT)
DEF_FUNCTION_TYPE_3 (BT_FN_I4_VPTR_I4_INT, BT_I4, BT_VOLATILE_PTR, BT_I4,
BT_INT)
DEF_FUNCTION_TYPE_3 (BT_FN_I8_VPTR_I8_INT, BT_I8, BT_VOLATILE_PTR, BT_I8,
BT_INT)
DEF_FUNCTION_TYPE_3 (BT_FN_I16_VPTR_I16_INT, BT_I16, BT_VOLATILE_PTR, BT_I16,
BT_INT)
!
DEF_FUNCTION_TYPE_4 (BT_FN_VOID_OMPFN_PTR_UINT_UINT,
BT_VOID, BT_PTR_FN_VOID_PTR, BT_PTR, BT_UINT, BT_UINT)
--- 129,144 ----
BT_I16, BT_I16)
DEF_FUNCTION_TYPE_3 (BT_FN_VOID_OMPFN_PTR_UINT, BT_VOID, BT_PTR_FN_VOID_PTR,
BT_PTR, BT_UINT)
DEF_FUNCTION_TYPE_3 (BT_FN_I1_VPTR_I1_INT, BT_I1, BT_VOLATILE_PTR, BT_I1,
BT_INT)
DEF_FUNCTION_TYPE_3 (BT_FN_I2_VPTR_I2_INT, BT_I2, BT_VOLATILE_PTR, BT_I2,
BT_INT)
DEF_FUNCTION_TYPE_3 (BT_FN_I4_VPTR_I4_INT, BT_I4, BT_VOLATILE_PTR, BT_I4,
BT_INT)
DEF_FUNCTION_TYPE_3 (BT_FN_I8_VPTR_I8_INT, BT_I8, BT_VOLATILE_PTR, BT_I8,
BT_INT)
DEF_FUNCTION_TYPE_3 (BT_FN_I16_VPTR_I16_INT, BT_I16, BT_VOLATILE_PTR, BT_I16,
BT_INT)
! DEF_FUNCTION_TYPE_3 (BT_FN_VOID_VPTR_I1_INT, BT_VOID, BT_VOLATILE_PTR, BT_I1,
BT_INT)
! DEF_FUNCTION_TYPE_3 (BT_FN_VOID_VPTR_I2_INT, BT_VOID, BT_VOLATILE_PTR, BT_I2,
BT_INT)
! DEF_FUNCTION_TYPE_3 (BT_FN_VOID_VPTR_I4_INT, BT_VOID, BT_VOLATILE_PTR, BT_I4,
BT_INT)
! DEF_FUNCTION_TYPE_3 (BT_FN_VOID_VPTR_I8_INT, BT_VOID, BT_VOLATILE_PTR, BT_I8,
BT_INT)
! DEF_FUNCTION_TYPE_3 (BT_FN_VOID_VPTR_I16_INT, BT_VOID, BT_VOLATILE_PTR,
BT_I16, BT_INT)
DEF_FUNCTION_TYPE_4 (BT_FN_VOID_OMPFN_PTR_UINT_UINT,
BT_VOID, BT_PTR_FN_VOID_PTR, BT_PTR, BT_UINT, BT_UINT)
*************** DEF_FUNCTION_TYPE_4 (BT_FN_VOID_PTR_WORD
*** 135,140 ****
--- 148,163 ----
DEF_FUNCTION_TYPE_5 (BT_FN_BOOL_LONG_LONG_LONG_LONGPTR_LONGPTR,
BT_BOOL, BT_LONG, BT_LONG, BT_LONG,
BT_PTR_LONG, BT_PTR_LONG)
+ DEF_FUNCTION_TYPE_5 (BT_FN_BOOL_VPTR_PTR_I1_INT_INT,
+ BT_BOOL, BT_VOLATILE_PTR, BT_PTR, BT_I1, BT_INT, BT_INT)
+ DEF_FUNCTION_TYPE_5 (BT_FN_BOOL_VPTR_PTR_I2_INT_INT,
+ BT_BOOL, BT_VOLATILE_PTR, BT_PTR, BT_I2, BT_INT, BT_INT)
+ DEF_FUNCTION_TYPE_5 (BT_FN_BOOL_VPTR_PTR_I4_INT_INT,
+ BT_BOOL, BT_VOLATILE_PTR, BT_PTR, BT_I4, BT_INT, BT_INT)
+ DEF_FUNCTION_TYPE_5 (BT_FN_BOOL_VPTR_PTR_I8_INT_INT,
+ BT_BOOL, BT_VOLATILE_PTR, BT_PTR, BT_I8, BT_INT, BT_INT)
+ DEF_FUNCTION_TYPE_5 (BT_FN_BOOL_VPTR_PTR_I16_INT_INT,
+ BT_BOOL, BT_VOLATILE_PTR, BT_PTR, BT_I16, BT_INT, BT_INT)
DEF_FUNCTION_TYPE_6 (BT_FN_BOOL_LONG_LONG_LONG_LONG_LONGPTR_LONGPTR,
BT_BOOL, BT_LONG, BT_LONG, BT_LONG, BT_LONG,
Index: sync-builtins.def
===================================================================
*** sync-builtins.def (revision 175331)
--- sync-builtins.def (working copy)
*************** DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_EXCH
*** 277,279 ****
--- 277,452 ----
DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_EXCHANGE_16,
"__sync_mem_exchange_16",
BT_FN_I16_VPTR_I16_INT, ATTR_NOTHROW_LEAF_LIST)
+
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_LOAD_N,
+ "__sync_mem_load",
+ BT_FN_VOID_VAR, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_LOAD_1,
+ "__sync_mem_load_1",
+ BT_FN_I1_VPTR_INT, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_LOAD_2,
+ "__sync_mem_load_2",
+ BT_FN_I2_VPTR_INT, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_LOAD_4,
+ "__sync_mem_load_4",
+ BT_FN_I4_VPTR_INT, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_LOAD_8,
+ "__sync_mem_load_8",
+ BT_FN_I8_VPTR_INT, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_LOAD_16,
+ "__sync_mem_load_16",
+ BT_FN_I16_VPTR_INT, ATTR_NOTHROW_LEAF_LIST)
+
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_COMPARE_EXCHANGE_N,
+ "__sync_mem_compare_exchange",
+ BT_FN_VOID_VAR, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_COMPARE_EXCHANGE_1,
+ "__sync_mem_compare_exchange_1",
+ BT_FN_BOOL_VPTR_PTR_I1_INT_INT, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_COMPARE_EXCHANGE_2,
+ "__sync_mem_compare_exchange_2",
+ BT_FN_BOOL_VPTR_PTR_I2_INT_INT, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_COMPARE_EXCHANGE_4,
+ "__sync_mem_compare_exchange_4",
+ BT_FN_BOOL_VPTR_PTR_I4_INT_INT, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_COMPARE_EXCHANGE_8,
+ "__sync_mem_compare_exchange_8",
+ BT_FN_BOOL_VPTR_PTR_I8_INT_INT, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_COMPARE_EXCHANGE_16,
+ "__sync_mem_compare_exchange_16",
+ BT_FN_BOOL_VPTR_PTR_I16_INT_INT, ATTR_NOTHROW_LEAF_LIST)
+
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_STORE_N,
+ "__sync_mem_store",
+ BT_FN_VOID_VAR, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_STORE_1,
+ "__sync_mem_store_1",
+ BT_FN_VOID_VPTR_I1_INT, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_STORE_2,
+ "__sync_mem_store_2",
+ BT_FN_VOID_VPTR_I2_INT, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_STORE_4,
+ "__sync_mem_store_4",
+ BT_FN_VOID_VPTR_I4_INT, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_STORE_8,
+ "__sync_mem_store_8",
+ BT_FN_VOID_VPTR_I8_INT, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_STORE_16,
+ "__sync_mem_store_16",
+ BT_FN_VOID_VPTR_I16_INT, ATTR_NOTHROW_LEAF_LIST)
+
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_FETCH_ADD_N,
+ "__sync_mem_fetch_add",
+ BT_FN_VOID_VAR, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_FETCH_ADD_1,
+ "__sync_mem_fetch_add_1",
+ BT_FN_I1_VPTR_I1_INT, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_FETCH_ADD_2,
+ "__sync_mem_fetch_add_2",
+ BT_FN_I2_VPTR_I2_INT, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_FETCH_ADD_4,
+ "__sync_mem_fetch_add_4",
+ BT_FN_I4_VPTR_I4_INT, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_FETCH_ADD_8,
+ "__sync_mem_fetch_add_8",
+ BT_FN_I8_VPTR_I8_INT, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_FETCH_ADD_16,
+ "__sync_mem_fetch_add_16",
+ BT_FN_I16_VPTR_I16_INT, ATTR_NOTHROW_LEAF_LIST)
+
+
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_FETCH_SUB_N,
+ "__sync_mem_fetch_sub",
+ BT_FN_VOID_VAR, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_FETCH_SUB_1,
+ "__sync_mem_fetch_sub_1",
+ BT_FN_I1_VPTR_I1_INT, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_FETCH_SUB_2,
+ "__sync_mem_fetch_sub_2",
+ BT_FN_I2_VPTR_I2_INT, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_FETCH_SUB_4,
+ "__sync_mem_fetch_sub_4",
+ BT_FN_I4_VPTR_I4_INT, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_FETCH_SUB_8,
+ "__sync_mem_fetch_sub_8",
+ BT_FN_I8_VPTR_I8_INT, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_FETCH_SUB_16,
+ "__sync_mem_fetch_sub_16",
+ BT_FN_I16_VPTR_I16_INT, ATTR_NOTHROW_LEAF_LIST)
+
+
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_FETCH_AND_N,
+ "__sync_mem_fetch_and",
+ BT_FN_VOID_VAR, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_FETCH_AND_1,
+ "__sync_mem_fetch_and_1",
+ BT_FN_I1_VPTR_I1_INT, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_FETCH_AND_2,
+ "__sync_mem_fetch_and_2",
+ BT_FN_I2_VPTR_I2_INT, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_FETCH_AND_4,
+ "__sync_mem_fetch_and_4",
+ BT_FN_I4_VPTR_I4_INT, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_FETCH_AND_8,
+ "__sync_mem_fetch_and_8",
+ BT_FN_I8_VPTR_I8_INT, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_FETCH_AND_16,
+ "__sync_mem_fetch_and_16",
+ BT_FN_I16_VPTR_I16_INT, ATTR_NOTHROW_LEAF_LIST)
+
+
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_FETCH_XOR_N,
+ "__sync_mem_fetch_xor",
+ BT_FN_VOID_VAR, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_FETCH_XOR_1,
+ "__sync_mem_fetch_xor_1",
+ BT_FN_I1_VPTR_I1_INT, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_FETCH_XOR_2,
+ "__sync_mem_fetch_xor_2",
+ BT_FN_I2_VPTR_I2_INT, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_FETCH_XOR_4,
+ "__sync_mem_fetch_xor_4",
+ BT_FN_I4_VPTR_I4_INT, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_FETCH_XOR_8,
+ "__sync_mem_fetch_xor_8",
+ BT_FN_I8_VPTR_I8_INT, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_FETCH_XOR_16,
+ "__sync_mem_fetch_xor_16",
+ BT_FN_I16_VPTR_I16_INT, ATTR_NOTHROW_LEAF_LIST)
+
+
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_FETCH_OR_N,
+ "__sync_mem_fetch_or",
+ BT_FN_VOID_VAR, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_FETCH_OR_1,
+ "__sync_mem_fetch_or_1",
+ BT_FN_I1_VPTR_I1_INT, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_FETCH_OR_2,
+ "__sync_mem_fetch_or_2",
+ BT_FN_I2_VPTR_I2_INT, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_FETCH_OR_4,
+ "__sync_mem_fetch_or_4",
+ BT_FN_I4_VPTR_I4_INT, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_FETCH_OR_8,
+ "__sync_mem_fetch_or_8",
+ BT_FN_I8_VPTR_I8_INT, ATTR_NOTHROW_LEAF_LIST)
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_FETCH_OR_16,
+ "__sync_mem_fetch_or_16",
+ BT_FN_I16_VPTR_I16_INT, ATTR_NOTHROW_LEAF_LIST)
+
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_FLAG_TEST_AND_SET,
+ "__sync_mem_flag_test_and_set",
+ BT_FN_BOOL_VPTR_INT, ATTR_NOTHROW_LEAF_LIST)
+
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_FLAG_CLEAR,
+ "__sync_mem_flag_clear",
+ BT_FN_VOID_VPTR_INT, ATTR_NOTHROW_LEAF_LIST)
+
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_THREAD_FENCE,
+ "__sync_mem_thread_fence",
+ BT_FN_VOID_INT, ATTR_NOTHROW_LEAF_LIST)
+
+ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_MEM_SIGNAL_FENCE,
+ "__sync_mem_signal_fence",
+ BT_FN_VOID_INT, ATTR_NOTHROW_LEAF_LIST)
+