aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2005-04-14 16:53:02 -0700
committerRichard Henderson <rth@gcc.gnu.org>2005-04-14 16:53:02 -0700
commitaf795c3cac686b80f842a66e8bd836c01654dce5 (patch)
tree82f8ab5a2bb454f3279533ed84e6f0989b9069b3 /gcc
parent1ef45b7773cfcce6e6e952b8a15713bd321adc9e (diff)
downloadgcc-af795c3cac686b80f842a66e8bd836c01654dce5.zip
gcc-af795c3cac686b80f842a66e8bd836c01654dce5.tar.gz
gcc-af795c3cac686b80f842a66e8bd836c01654dce5.tar.bz2
ia64.h (enum fetchop_code): Remove.
* config/ia64/ia64.h (enum fetchop_code): Remove. (enum ia64_builtins): Move ... * config/ia64/ia64.c (enum ia64_builtins): ... here. Remove all members except BSP and FLUSHRS. (ia64_init_builtins): Remove __sync builtins. (ia64_expand_builtin): Likewise. (ia64_expand_fetch_and_op, ia64_expand_op_and_fetch): Remove. (ia64_expand_compare_and_swap, ia64_expand_lock_test_and_set): Remove. (ia64_expand_lock_release): Remove. * config/ia64/ia64.md (mf): Move to sync.md. (mf_internal, fetchadd_acq_si, fetchadd_acq_di, cmpxchg_acq_si, cmpxchg_acq_di, xchgsi, xchgdi): Likewise. * config/ia64/sync.md: New file. (memory_barrier): Rename from mf. (fetchadd_acq_<I48MODE>): Macroize from _si/_di patterns. (cmpxchg_acq_<I48MODE>): Likewise. (sync_lock_test_and_set<I48MODE>): Likewise. * config/ia64/ia64intrin.h: Define nothing for C; limit #defines to c++. Remove __sync* declarations. s/_si/_4/. s/_di/_8/. From-SVN: r98156
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog23
-rw-r--r--gcc/config/ia64/ia64.c516
-rw-r--r--gcc/config/ia64/ia64.h61
-rw-r--r--gcc/config/ia64/ia64.md84
-rw-r--r--gcc/config/ia64/ia64intrin.h109
-rw-r--r--gcc/config/ia64/sync.md121
6 files changed, 187 insertions, 727 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2e0aa6c..eb8f4db 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,28 @@
2004-04-14 Richard Henderson <rth@redhat.com>
+ * config/ia64/ia64.h (enum fetchop_code): Remove.
+ (enum ia64_builtins): Move ...
+ * config/ia64/ia64.c (enum ia64_builtins): ... here. Remove all
+ members except BSP and FLUSHRS.
+ (ia64_init_builtins): Remove __sync builtins.
+ (ia64_expand_builtin): Likewise.
+ (ia64_expand_fetch_and_op, ia64_expand_op_and_fetch): Remove.
+ (ia64_expand_compare_and_swap, ia64_expand_lock_test_and_set): Remove.
+ (ia64_expand_lock_release): Remove.
+ * config/ia64/ia64.md (mf): Move to sync.md.
+ (mf_internal, fetchadd_acq_si, fetchadd_acq_di, cmpxchg_acq_si,
+ cmpxchg_acq_di, xchgsi, xchgdi): Likewise.
+ * config/ia64/sync.md: New file.
+ (memory_barrier): Rename from mf.
+ (fetchadd_acq_<I48MODE>): Macroize from _si/_di patterns.
+ (cmpxchg_acq_<I48MODE>): Likewise.
+ (sync_lock_test_and_set<I48MODE>): Likewise.
+
+ * config/ia64/ia64intrin.h: Define nothing for C; limit #defines
+ to c++. Remove __sync* declarations. s/_si/_4/. s/_di/_8/.
+
+2004-04-14 Richard Henderson <rth@redhat.com>
+
* config/i386/i386.c (x86_cmpxchg, x86_xadd): New.
(ix86_compare_emitted): New.
(ix86_expand_compare): Use ix86_compare_emitted if set.
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index fef3729..55fde10 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -199,12 +199,6 @@ static bool ia64_in_small_data_p (tree);
static void process_epilogue (void);
static int process_set (FILE *, rtx);
-static rtx ia64_expand_fetch_and_op (optab, enum machine_mode, tree, rtx);
-static rtx ia64_expand_op_and_fetch (optab, enum machine_mode, tree, rtx);
-static rtx ia64_expand_compare_and_swap (enum machine_mode, enum machine_mode,
- int, tree, rtx);
-static rtx ia64_expand_lock_test_and_set (enum machine_mode, tree, rtx);
-static rtx ia64_expand_lock_release (enum machine_mode, tree, rtx);
static bool ia64_assemble_integer (rtx, unsigned int, int);
static void ia64_output_function_prologue (FILE *, HOST_WIDE_INT);
static void ia64_output_function_epilogue (FILE *, HOST_WIDE_INT);
@@ -7854,51 +7848,15 @@ process_for_unwind_directive (FILE *asm_out_file, rtx insn)
}
+enum ia64_builtins
+{
+ IA64_BUILTIN_BSP,
+ IA64_BUILTIN_FLUSHRS
+};
+
void
ia64_init_builtins (void)
{
- tree psi_type_node = build_pointer_type (integer_type_node);
- tree pdi_type_node = build_pointer_type (long_integer_type_node);
-
- /* __sync_val_compare_and_swap_si, __sync_bool_compare_and_swap_si */
- tree si_ftype_psi_si_si
- = build_function_type_list (integer_type_node,
- psi_type_node, integer_type_node,
- integer_type_node, NULL_TREE);
-
- /* __sync_val_compare_and_swap_di */
- tree di_ftype_pdi_di_di
- = build_function_type_list (long_integer_type_node,
- pdi_type_node, long_integer_type_node,
- long_integer_type_node, NULL_TREE);
- /* __sync_bool_compare_and_swap_di */
- tree si_ftype_pdi_di_di
- = build_function_type_list (integer_type_node,
- pdi_type_node, long_integer_type_node,
- long_integer_type_node, NULL_TREE);
- /* __sync_synchronize */
- tree void_ftype_void
- = build_function_type (void_type_node, void_list_node);
-
- /* __sync_lock_test_and_set_si */
- tree si_ftype_psi_si
- = build_function_type_list (integer_type_node,
- psi_type_node, integer_type_node, NULL_TREE);
-
- /* __sync_lock_test_and_set_di */
- tree di_ftype_pdi_di
- = build_function_type_list (long_integer_type_node,
- pdi_type_node, long_integer_type_node,
- NULL_TREE);
-
- /* __sync_lock_release_si */
- tree void_ftype_psi
- = build_function_type_list (void_type_node, psi_type_node, NULL_TREE);
-
- /* __sync_lock_release_di */
- tree void_ftype_pdi
- = build_function_type_list (void_type_node, pdi_type_node, NULL_TREE);
-
tree fpreg_type;
tree float80_type;
@@ -7933,27 +7891,6 @@ ia64_init_builtins (void)
lang_hooks.builtin_function ((name), (type), (code), BUILT_IN_MD, \
NULL, NULL_TREE)
- def_builtin ("__sync_val_compare_and_swap_si", si_ftype_psi_si_si,
- IA64_BUILTIN_VAL_COMPARE_AND_SWAP_SI);
- def_builtin ("__sync_val_compare_and_swap_di", di_ftype_pdi_di_di,
- IA64_BUILTIN_VAL_COMPARE_AND_SWAP_DI);
- def_builtin ("__sync_bool_compare_and_swap_si", si_ftype_psi_si_si,
- IA64_BUILTIN_BOOL_COMPARE_AND_SWAP_SI);
- def_builtin ("__sync_bool_compare_and_swap_di", si_ftype_pdi_di_di,
- IA64_BUILTIN_BOOL_COMPARE_AND_SWAP_DI);
-
- def_builtin ("__sync_synchronize", void_ftype_void,
- IA64_BUILTIN_SYNCHRONIZE);
-
- def_builtin ("__sync_lock_test_and_set_si", si_ftype_psi_si,
- IA64_BUILTIN_LOCK_TEST_AND_SET_SI);
- def_builtin ("__sync_lock_test_and_set_di", di_ftype_pdi_di,
- IA64_BUILTIN_LOCK_TEST_AND_SET_DI);
- def_builtin ("__sync_lock_release_si", void_ftype_psi,
- IA64_BUILTIN_LOCK_RELEASE_SI);
- def_builtin ("__sync_lock_release_di", void_ftype_pdi,
- IA64_BUILTIN_LOCK_RELEASE_DI);
-
def_builtin ("__builtin_ia64_bsp",
build_function_type (ptr_type_node, void_list_node),
IA64_BUILTIN_BSP);
@@ -7962,322 +7899,9 @@ ia64_init_builtins (void)
build_function_type (void_type_node, void_list_node),
IA64_BUILTIN_FLUSHRS);
- def_builtin ("__sync_fetch_and_add_si", si_ftype_psi_si,
- IA64_BUILTIN_FETCH_AND_ADD_SI);
- def_builtin ("__sync_fetch_and_sub_si", si_ftype_psi_si,
- IA64_BUILTIN_FETCH_AND_SUB_SI);
- def_builtin ("__sync_fetch_and_or_si", si_ftype_psi_si,
- IA64_BUILTIN_FETCH_AND_OR_SI);
- def_builtin ("__sync_fetch_and_and_si", si_ftype_psi_si,
- IA64_BUILTIN_FETCH_AND_AND_SI);
- def_builtin ("__sync_fetch_and_xor_si", si_ftype_psi_si,
- IA64_BUILTIN_FETCH_AND_XOR_SI);
- def_builtin ("__sync_fetch_and_nand_si", si_ftype_psi_si,
- IA64_BUILTIN_FETCH_AND_NAND_SI);
-
- def_builtin ("__sync_add_and_fetch_si", si_ftype_psi_si,
- IA64_BUILTIN_ADD_AND_FETCH_SI);
- def_builtin ("__sync_sub_and_fetch_si", si_ftype_psi_si,
- IA64_BUILTIN_SUB_AND_FETCH_SI);
- def_builtin ("__sync_or_and_fetch_si", si_ftype_psi_si,
- IA64_BUILTIN_OR_AND_FETCH_SI);
- def_builtin ("__sync_and_and_fetch_si", si_ftype_psi_si,
- IA64_BUILTIN_AND_AND_FETCH_SI);
- def_builtin ("__sync_xor_and_fetch_si", si_ftype_psi_si,
- IA64_BUILTIN_XOR_AND_FETCH_SI);
- def_builtin ("__sync_nand_and_fetch_si", si_ftype_psi_si,
- IA64_BUILTIN_NAND_AND_FETCH_SI);
-
- def_builtin ("__sync_fetch_and_add_di", di_ftype_pdi_di,
- IA64_BUILTIN_FETCH_AND_ADD_DI);
- def_builtin ("__sync_fetch_and_sub_di", di_ftype_pdi_di,
- IA64_BUILTIN_FETCH_AND_SUB_DI);
- def_builtin ("__sync_fetch_and_or_di", di_ftype_pdi_di,
- IA64_BUILTIN_FETCH_AND_OR_DI);
- def_builtin ("__sync_fetch_and_and_di", di_ftype_pdi_di,
- IA64_BUILTIN_FETCH_AND_AND_DI);
- def_builtin ("__sync_fetch_and_xor_di", di_ftype_pdi_di,
- IA64_BUILTIN_FETCH_AND_XOR_DI);
- def_builtin ("__sync_fetch_and_nand_di", di_ftype_pdi_di,
- IA64_BUILTIN_FETCH_AND_NAND_DI);
-
- def_builtin ("__sync_add_and_fetch_di", di_ftype_pdi_di,
- IA64_BUILTIN_ADD_AND_FETCH_DI);
- def_builtin ("__sync_sub_and_fetch_di", di_ftype_pdi_di,
- IA64_BUILTIN_SUB_AND_FETCH_DI);
- def_builtin ("__sync_or_and_fetch_di", di_ftype_pdi_di,
- IA64_BUILTIN_OR_AND_FETCH_DI);
- def_builtin ("__sync_and_and_fetch_di", di_ftype_pdi_di,
- IA64_BUILTIN_AND_AND_FETCH_DI);
- def_builtin ("__sync_xor_and_fetch_di", di_ftype_pdi_di,
- IA64_BUILTIN_XOR_AND_FETCH_DI);
- def_builtin ("__sync_nand_and_fetch_di", di_ftype_pdi_di,
- IA64_BUILTIN_NAND_AND_FETCH_DI);
-
#undef def_builtin
}
-/* Expand fetch_and_op intrinsics. The basic code sequence is:
-
- mf
- tmp = [ptr];
- do {
- ret = tmp;
- ar.ccv = tmp;
- tmp <op>= value;
- cmpxchgsz.acq tmp = [ptr], tmp
- } while (tmp != ret)
-*/
-
-static rtx
-ia64_expand_fetch_and_op (optab binoptab, enum machine_mode mode,
- tree arglist, rtx target)
-{
- rtx ret, label, tmp, ccv, insn, mem, value;
- tree arg0, arg1;
-
- arg0 = TREE_VALUE (arglist);
- arg1 = TREE_VALUE (TREE_CHAIN (arglist));
- mem = expand_expr (arg0, NULL_RTX, Pmode, 0);
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (GET_MODE(mem) != Pmode)
- mem = convert_memory_address (Pmode, mem);
-#endif
- value = expand_expr (arg1, NULL_RTX, mode, 0);
-
- mem = gen_rtx_MEM (mode, force_reg (Pmode, mem));
- MEM_VOLATILE_P (mem) = 1;
-
- if (target && register_operand (target, mode))
- ret = target;
- else
- ret = gen_reg_rtx (mode);
-
- emit_insn (gen_mf ());
-
- /* Special case for fetchadd instructions. */
- if (binoptab == add_optab && fetchadd_operand (value, VOIDmode))
- {
- if (mode == SImode)
- insn = gen_fetchadd_acq_si (ret, mem, value);
- else
- insn = gen_fetchadd_acq_di (ret, mem, value);
- emit_insn (insn);
- return ret;
- }
-
- tmp = gen_reg_rtx (mode);
- /* ar.ccv must always be loaded with a zero-extended DImode value. */
- ccv = gen_rtx_REG (DImode, AR_CCV_REGNUM);
- emit_move_insn (tmp, mem);
-
- label = gen_label_rtx ();
- emit_label (label);
- emit_move_insn (ret, tmp);
- convert_move (ccv, tmp, /*unsignedp=*/1);
-
- /* Perform the specific operation. Special case NAND by noticing
- one_cmpl_optab instead. */
- if (binoptab == one_cmpl_optab)
- {
- tmp = expand_unop (mode, binoptab, tmp, NULL, OPTAB_WIDEN);
- binoptab = and_optab;
- }
- tmp = expand_binop (mode, binoptab, tmp, value, tmp, 1, OPTAB_WIDEN);
-
- if (mode == SImode)
- insn = gen_cmpxchg_acq_si (tmp, mem, tmp, ccv);
- else
- insn = gen_cmpxchg_acq_di (tmp, mem, tmp, ccv);
- emit_insn (insn);
-
- emit_cmp_and_jump_insns (tmp, ret, NE, 0, mode, 1, label);
-
- return ret;
-}
-
-/* Expand op_and_fetch intrinsics. The basic code sequence is:
-
- mf
- tmp = [ptr];
- do {
- old = tmp;
- ar.ccv = tmp;
- ret = tmp <op> value;
- cmpxchgsz.acq tmp = [ptr], ret
- } while (tmp != old)
-*/
-
-static rtx
-ia64_expand_op_and_fetch (optab binoptab, enum machine_mode mode,
- tree arglist, rtx target)
-{
- rtx old, label, tmp, ret, ccv, insn, mem, value;
- tree arg0, arg1;
-
- arg0 = TREE_VALUE (arglist);
- arg1 = TREE_VALUE (TREE_CHAIN (arglist));
- mem = expand_expr (arg0, NULL_RTX, Pmode, 0);
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (GET_MODE(mem) != Pmode)
- mem = convert_memory_address (Pmode, mem);
-#endif
-
- value = expand_expr (arg1, NULL_RTX, mode, 0);
-
- mem = gen_rtx_MEM (mode, force_reg (Pmode, mem));
- MEM_VOLATILE_P (mem) = 1;
-
- if (target && ! register_operand (target, mode))
- target = NULL_RTX;
-
- emit_insn (gen_mf ());
- tmp = gen_reg_rtx (mode);
- old = gen_reg_rtx (mode);
- /* ar.ccv must always be loaded with a zero-extended DImode value. */
- ccv = gen_rtx_REG (DImode, AR_CCV_REGNUM);
-
- emit_move_insn (tmp, mem);
-
- label = gen_label_rtx ();
- emit_label (label);
- emit_move_insn (old, tmp);
- convert_move (ccv, tmp, /*unsignedp=*/1);
-
- /* Perform the specific operation. Special case NAND by noticing
- one_cmpl_optab instead. */
- if (binoptab == one_cmpl_optab)
- {
- tmp = expand_unop (mode, binoptab, tmp, NULL, OPTAB_WIDEN);
- binoptab = and_optab;
- }
- ret = expand_binop (mode, binoptab, tmp, value, target, 1, OPTAB_WIDEN);
-
- if (mode == SImode)
- insn = gen_cmpxchg_acq_si (tmp, mem, ret, ccv);
- else
- insn = gen_cmpxchg_acq_di (tmp, mem, ret, ccv);
- emit_insn (insn);
-
- emit_cmp_and_jump_insns (tmp, old, NE, 0, mode, 1, label);
-
- return ret;
-}
-
-/* Expand val_ and bool_compare_and_swap. For val_ we want:
-
- ar.ccv = oldval
- mf
- cmpxchgsz.acq ret = [ptr], newval, ar.ccv
- return ret
-
- For bool_ it's the same except return ret == oldval.
-*/
-
-static rtx
-ia64_expand_compare_and_swap (enum machine_mode rmode, enum machine_mode mode,
- int boolp, tree arglist, rtx target)
-{
- tree arg0, arg1, arg2;
- rtx mem, old, new, ccv, tmp, insn;
-
- arg0 = TREE_VALUE (arglist);
- arg1 = TREE_VALUE (TREE_CHAIN (arglist));
- arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
- mem = expand_expr (arg0, NULL_RTX, ptr_mode, 0);
- old = expand_expr (arg1, NULL_RTX, mode, 0);
- new = expand_expr (arg2, NULL_RTX, mode, 0);
-
- mem = gen_rtx_MEM (mode, force_reg (ptr_mode, mem));
- MEM_VOLATILE_P (mem) = 1;
-
- if (GET_MODE (old) != mode)
- old = convert_to_mode (mode, old, /*unsignedp=*/1);
- if (GET_MODE (new) != mode)
- new = convert_to_mode (mode, new, /*unsignedp=*/1);
-
- if (! register_operand (old, mode))
- old = copy_to_mode_reg (mode, old);
- if (! register_operand (new, mode))
- new = copy_to_mode_reg (mode, new);
-
- if (! boolp && target && register_operand (target, mode))
- tmp = target;
- else
- tmp = gen_reg_rtx (mode);
-
- ccv = gen_rtx_REG (DImode, AR_CCV_REGNUM);
- convert_move (ccv, old, /*unsignedp=*/1);
- emit_insn (gen_mf ());
- if (mode == SImode)
- insn = gen_cmpxchg_acq_si (tmp, mem, new, ccv);
- else
- insn = gen_cmpxchg_acq_di (tmp, mem, new, ccv);
- emit_insn (insn);
-
- if (boolp)
- {
- if (! target)
- target = gen_reg_rtx (rmode);
- return emit_store_flag_force (target, EQ, tmp, old, mode, 1, 1);
- }
- else
- return tmp;
-}
-
-/* Expand lock_test_and_set. I.e. `xchgsz ret = [ptr], new'. */
-
-static rtx
-ia64_expand_lock_test_and_set (enum machine_mode mode, tree arglist,
- rtx target)
-{
- tree arg0, arg1;
- rtx mem, new, ret, insn;
-
- arg0 = TREE_VALUE (arglist);
- arg1 = TREE_VALUE (TREE_CHAIN (arglist));
- mem = expand_expr (arg0, NULL_RTX, ptr_mode, 0);
- new = expand_expr (arg1, NULL_RTX, mode, 0);
-
- mem = gen_rtx_MEM (mode, force_reg (ptr_mode, mem));
- MEM_VOLATILE_P (mem) = 1;
- if (! register_operand (new, mode))
- new = copy_to_mode_reg (mode, new);
-
- if (target && register_operand (target, mode))
- ret = target;
- else
- ret = gen_reg_rtx (mode);
-
- if (mode == SImode)
- insn = gen_xchgsi (ret, mem, new);
- else
- insn = gen_xchgdi (ret, mem, new);
- emit_insn (insn);
-
- return ret;
-}
-
-/* Expand lock_release. I.e. `stsz.rel [ptr] = r0'. */
-
-static rtx
-ia64_expand_lock_release (enum machine_mode mode, tree arglist,
- rtx target ATTRIBUTE_UNUSED)
-{
- tree arg0;
- rtx mem;
-
- arg0 = TREE_VALUE (arglist);
- mem = expand_expr (arg0, NULL_RTX, ptr_mode, 0);
-
- mem = gen_rtx_MEM (mode, force_reg (ptr_mode, mem));
- MEM_VOLATILE_P (mem) = 1;
-
- emit_move_insn (mem, const0_rtx);
-
- return const0_rtx;
-}
-
rtx
ia64_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
enum machine_mode mode ATTRIBUTE_UNUSED,
@@ -8285,89 +7909,9 @@ ia64_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
{
tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
- tree arglist = TREE_OPERAND (exp, 1);
- enum machine_mode rmode = VOIDmode;
switch (fcode)
{
- case IA64_BUILTIN_BOOL_COMPARE_AND_SWAP_SI:
- case IA64_BUILTIN_VAL_COMPARE_AND_SWAP_SI:
- mode = SImode;
- rmode = SImode;
- break;
-
- case IA64_BUILTIN_LOCK_TEST_AND_SET_SI:
- case IA64_BUILTIN_LOCK_RELEASE_SI:
- case IA64_BUILTIN_FETCH_AND_ADD_SI:
- case IA64_BUILTIN_FETCH_AND_SUB_SI:
- case IA64_BUILTIN_FETCH_AND_OR_SI:
- case IA64_BUILTIN_FETCH_AND_AND_SI:
- case IA64_BUILTIN_FETCH_AND_XOR_SI:
- case IA64_BUILTIN_FETCH_AND_NAND_SI:
- case IA64_BUILTIN_ADD_AND_FETCH_SI:
- case IA64_BUILTIN_SUB_AND_FETCH_SI:
- case IA64_BUILTIN_OR_AND_FETCH_SI:
- case IA64_BUILTIN_AND_AND_FETCH_SI:
- case IA64_BUILTIN_XOR_AND_FETCH_SI:
- case IA64_BUILTIN_NAND_AND_FETCH_SI:
- mode = SImode;
- break;
-
- case IA64_BUILTIN_BOOL_COMPARE_AND_SWAP_DI:
- mode = DImode;
- rmode = SImode;
- break;
-
- case IA64_BUILTIN_VAL_COMPARE_AND_SWAP_DI:
- mode = DImode;
- rmode = DImode;
- break;
-
- case IA64_BUILTIN_LOCK_TEST_AND_SET_DI:
- case IA64_BUILTIN_LOCK_RELEASE_DI:
- case IA64_BUILTIN_FETCH_AND_ADD_DI:
- case IA64_BUILTIN_FETCH_AND_SUB_DI:
- case IA64_BUILTIN_FETCH_AND_OR_DI:
- case IA64_BUILTIN_FETCH_AND_AND_DI:
- case IA64_BUILTIN_FETCH_AND_XOR_DI:
- case IA64_BUILTIN_FETCH_AND_NAND_DI:
- case IA64_BUILTIN_ADD_AND_FETCH_DI:
- case IA64_BUILTIN_SUB_AND_FETCH_DI:
- case IA64_BUILTIN_OR_AND_FETCH_DI:
- case IA64_BUILTIN_AND_AND_FETCH_DI:
- case IA64_BUILTIN_XOR_AND_FETCH_DI:
- case IA64_BUILTIN_NAND_AND_FETCH_DI:
- mode = DImode;
- break;
-
- default:
- break;
- }
-
- switch (fcode)
- {
- case IA64_BUILTIN_BOOL_COMPARE_AND_SWAP_SI:
- case IA64_BUILTIN_BOOL_COMPARE_AND_SWAP_DI:
- return ia64_expand_compare_and_swap (rmode, mode, 1, arglist,
- target);
-
- case IA64_BUILTIN_VAL_COMPARE_AND_SWAP_SI:
- case IA64_BUILTIN_VAL_COMPARE_AND_SWAP_DI:
- return ia64_expand_compare_and_swap (rmode, mode, 0, arglist,
- target);
-
- case IA64_BUILTIN_SYNCHRONIZE:
- emit_insn (gen_mf ());
- return const0_rtx;
-
- case IA64_BUILTIN_LOCK_TEST_AND_SET_SI:
- case IA64_BUILTIN_LOCK_TEST_AND_SET_DI:
- return ia64_expand_lock_test_and_set (mode, arglist, target);
-
- case IA64_BUILTIN_LOCK_RELEASE_SI:
- case IA64_BUILTIN_LOCK_RELEASE_DI:
- return ia64_expand_lock_release (mode, arglist, target);
-
case IA64_BUILTIN_BSP:
if (! target || ! register_operand (target, DImode))
target = gen_reg_rtx (DImode);
@@ -8381,54 +7925,6 @@ ia64_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
emit_insn (gen_flushrs ());
return const0_rtx;
- case IA64_BUILTIN_FETCH_AND_ADD_SI:
- case IA64_BUILTIN_FETCH_AND_ADD_DI:
- return ia64_expand_fetch_and_op (add_optab, mode, arglist, target);
-
- case IA64_BUILTIN_FETCH_AND_SUB_SI:
- case IA64_BUILTIN_FETCH_AND_SUB_DI:
- return ia64_expand_fetch_and_op (sub_optab, mode, arglist, target);
-
- case IA64_BUILTIN_FETCH_AND_OR_SI:
- case IA64_BUILTIN_FETCH_AND_OR_DI:
- return ia64_expand_fetch_and_op (ior_optab, mode, arglist, target);
-
- case IA64_BUILTIN_FETCH_AND_AND_SI:
- case IA64_BUILTIN_FETCH_AND_AND_DI:
- return ia64_expand_fetch_and_op (and_optab, mode, arglist, target);
-
- case IA64_BUILTIN_FETCH_AND_XOR_SI:
- case IA64_BUILTIN_FETCH_AND_XOR_DI:
- return ia64_expand_fetch_and_op (xor_optab, mode, arglist, target);
-
- case IA64_BUILTIN_FETCH_AND_NAND_SI:
- case IA64_BUILTIN_FETCH_AND_NAND_DI:
- return ia64_expand_fetch_and_op (one_cmpl_optab, mode, arglist, target);
-
- case IA64_BUILTIN_ADD_AND_FETCH_SI:
- case IA64_BUILTIN_ADD_AND_FETCH_DI:
- return ia64_expand_op_and_fetch (add_optab, mode, arglist, target);
-
- case IA64_BUILTIN_SUB_AND_FETCH_SI:
- case IA64_BUILTIN_SUB_AND_FETCH_DI:
- return ia64_expand_op_and_fetch (sub_optab, mode, arglist, target);
-
- case IA64_BUILTIN_OR_AND_FETCH_SI:
- case IA64_BUILTIN_OR_AND_FETCH_DI:
- return ia64_expand_op_and_fetch (ior_optab, mode, arglist, target);
-
- case IA64_BUILTIN_AND_AND_FETCH_SI:
- case IA64_BUILTIN_AND_AND_FETCH_DI:
- return ia64_expand_op_and_fetch (and_optab, mode, arglist, target);
-
- case IA64_BUILTIN_XOR_AND_FETCH_SI:
- case IA64_BUILTIN_XOR_AND_FETCH_DI:
- return ia64_expand_op_and_fetch (xor_optab, mode, arglist, target);
-
- case IA64_BUILTIN_NAND_AND_FETCH_SI:
- case IA64_BUILTIN_NAND_AND_FETCH_DI:
- return ia64_expand_op_and_fetch (one_cmpl_optab, mode, arglist, target);
-
default:
break;
}
diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h
index 65b3b5b..857de66 100644
--- a/gcc/config/ia64/ia64.h
+++ b/gcc/config/ia64/ia64.h
@@ -2034,66 +2034,6 @@ struct machine_function GTY(())
int state_num;
};
-
-enum ia64_builtins
-{
- IA64_BUILTIN_SYNCHRONIZE,
-
- IA64_BUILTIN_FETCH_AND_ADD_SI,
- IA64_BUILTIN_FETCH_AND_SUB_SI,
- IA64_BUILTIN_FETCH_AND_OR_SI,
- IA64_BUILTIN_FETCH_AND_AND_SI,
- IA64_BUILTIN_FETCH_AND_XOR_SI,
- IA64_BUILTIN_FETCH_AND_NAND_SI,
-
- IA64_BUILTIN_ADD_AND_FETCH_SI,
- IA64_BUILTIN_SUB_AND_FETCH_SI,
- IA64_BUILTIN_OR_AND_FETCH_SI,
- IA64_BUILTIN_AND_AND_FETCH_SI,
- IA64_BUILTIN_XOR_AND_FETCH_SI,
- IA64_BUILTIN_NAND_AND_FETCH_SI,
-
- IA64_BUILTIN_BOOL_COMPARE_AND_SWAP_SI,
- IA64_BUILTIN_VAL_COMPARE_AND_SWAP_SI,
-
- IA64_BUILTIN_SYNCHRONIZE_SI,
-
- IA64_BUILTIN_LOCK_TEST_AND_SET_SI,
-
- IA64_BUILTIN_LOCK_RELEASE_SI,
-
- IA64_BUILTIN_FETCH_AND_ADD_DI,
- IA64_BUILTIN_FETCH_AND_SUB_DI,
- IA64_BUILTIN_FETCH_AND_OR_DI,
- IA64_BUILTIN_FETCH_AND_AND_DI,
- IA64_BUILTIN_FETCH_AND_XOR_DI,
- IA64_BUILTIN_FETCH_AND_NAND_DI,
-
- IA64_BUILTIN_ADD_AND_FETCH_DI,
- IA64_BUILTIN_SUB_AND_FETCH_DI,
- IA64_BUILTIN_OR_AND_FETCH_DI,
- IA64_BUILTIN_AND_AND_FETCH_DI,
- IA64_BUILTIN_XOR_AND_FETCH_DI,
- IA64_BUILTIN_NAND_AND_FETCH_DI,
-
- IA64_BUILTIN_BOOL_COMPARE_AND_SWAP_DI,
- IA64_BUILTIN_VAL_COMPARE_AND_SWAP_DI,
-
- IA64_BUILTIN_SYNCHRONIZE_DI,
-
- IA64_BUILTIN_LOCK_TEST_AND_SET_DI,
-
- IA64_BUILTIN_LOCK_RELEASE_DI,
-
- IA64_BUILTIN_BSP,
- IA64_BUILTIN_FLUSHRS
-};
-
-/* Codes for expand_compare_and_swap and expand_swap_and_compare. */
-enum fetchop_code {
- IA64_ADD_OP, IA64_SUB_OP, IA64_OR_OP, IA64_AND_OP, IA64_XOR_OP, IA64_NAND_OP
-};
-
#define DONT_USE_BUILTIN_SETJMP
/* Output any profiling code before the prologue. */
@@ -2104,7 +2044,6 @@ enum fetchop_code {
/* Initialize library function table. */
#undef TARGET_INIT_LIBFUNCS
#define TARGET_INIT_LIBFUNCS ia64_init_libfuncs
-
/* Switch on code for querying unit reservations. */
diff --git a/gcc/config/ia64/ia64.md b/gcc/config/ia64/ia64.md
index 485c3ff..d4ab9ff 100644
--- a/gcc/config/ia64/ia64.md
+++ b/gcc/config/ia64/ia64.md
@@ -6048,88 +6048,6 @@
})
-;;; Intrinsics support.
-
-(define_expand "mf"
- [(set (mem:BLK (match_dup 0))
- (unspec:BLK [(mem:BLK (match_dup 0))] UNSPEC_MF))]
- ""
-{
- operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (DImode));
- MEM_VOLATILE_P (operands[0]) = 1;
-})
-
-(define_insn "*mf_internal"
- [(set (match_operand:BLK 0 "" "")
- (unspec:BLK [(match_operand:BLK 1 "" "")] UNSPEC_MF))]
- ""
- "mf"
- [(set_attr "itanium_class" "syst_m")])
-
-(define_insn "fetchadd_acq_si"
- [(set (match_operand:SI 0 "gr_register_operand" "=r")
- (match_operand:SI 1 "not_postinc_memory_operand" "+S"))
- (set (match_dup 1)
- (unspec:SI [(match_dup 1)
- (match_operand:SI 2 "fetchadd_operand" "n")]
- UNSPEC_FETCHADD_ACQ))]
- ""
- "fetchadd4.acq %0 = %1, %2"
- [(set_attr "itanium_class" "sem")])
-
-(define_insn "fetchadd_acq_di"
- [(set (match_operand:DI 0 "gr_register_operand" "=r")
- (match_operand:DI 1 "not_postinc_memory_operand" "+S"))
- (set (match_dup 1)
- (unspec:DI [(match_dup 1)
- (match_operand:DI 2 "fetchadd_operand" "n")]
- UNSPEC_FETCHADD_ACQ))]
- ""
- "fetchadd8.acq %0 = %1, %2"
- [(set_attr "itanium_class" "sem")])
-
-(define_insn "cmpxchg_acq_si"
- [(set (match_operand:SI 0 "gr_register_operand" "=r")
- (match_operand:SI 1 "not_postinc_memory_operand" "+S"))
- (set (match_dup 1)
- (unspec:SI [(match_dup 1)
- (match_operand:SI 2 "gr_register_operand" "r")
- (match_operand:DI 3 "ar_ccv_reg_operand" "")]
- UNSPEC_CMPXCHG_ACQ))]
- ""
- "cmpxchg4.acq %0 = %1, %2, %3"
- [(set_attr "itanium_class" "sem")])
-
-(define_insn "cmpxchg_acq_di"
- [(set (match_operand:DI 0 "gr_register_operand" "=r")
- (match_operand:DI 1 "not_postinc_memory_operand" "+S"))
- (set (match_dup 1)
- (unspec:DI [(match_dup 1)
- (match_operand:DI 2 "gr_register_operand" "r")
- (match_operand:DI 3 "ar_ccv_reg_operand" "")]
- UNSPEC_CMPXCHG_ACQ))]
- ""
- "cmpxchg8.acq %0 = %1, %2, %3"
- [(set_attr "itanium_class" "sem")])
-
-(define_insn "xchgsi"
- [(set (match_operand:SI 0 "gr_register_operand" "=r")
- (match_operand:SI 1 "not_postinc_memory_operand" "+S"))
- (set (match_dup 1)
- (match_operand:SI 2 "gr_register_operand" "r"))]
- ""
- "xchg4 %0 = %1, %2"
- [(set_attr "itanium_class" "sem")])
-
-(define_insn "xchgdi"
- [(set (match_operand:DI 0 "gr_register_operand" "=r")
- (match_operand:DI 1 "not_postinc_memory_operand" "+S"))
- (set (match_dup 1)
- (match_operand:DI 2 "gr_register_operand" "r"))]
- ""
- "xchg8 %0 = %1, %2"
- [(set_attr "itanium_class" "sem")])
-
;; Predication.
(define_cond_exec
@@ -6200,3 +6118,5 @@
;; Vector operations
(include "vect.md")
+;; Atomic operations
+(include "sync.md")
diff --git a/gcc/config/ia64/ia64intrin.h b/gcc/config/ia64/ia64intrin.h
index 2397c4c..6054219 100644
--- a/gcc/config/ia64/ia64intrin.h
+++ b/gcc/config/ia64/ia64intrin.h
@@ -1,130 +1,91 @@
#ifndef _IA64INTRIN_H_INCLUDED
#define _IA64INTRIN_H_INCLUDED
-/* Actually, everything is a compiler builtin, but just so
- there's no confusion... */
+/* ??? Overloaded builtins havn't been ported to C++ yet. */
#ifdef __cplusplus
-extern "C" {
-#endif
-extern void __sync_synchronize (void);
-
-extern int __sync_val_compare_and_swap_si (int *, int, int);
-extern long __sync_val_compare_and_swap_di (long *, long, long);
#define __sync_val_compare_and_swap(PTR, OLD, NEW) \
((sizeof (*(PTR)) == sizeof(int)) \
? (__typeof__(*(PTR))) \
- __sync_val_compare_and_swap_si((int *)(void *)(PTR),(int)(OLD),(int)(NEW)) \
+ __sync_val_compare_and_swap_4((int *)(void *)(PTR),(int)(OLD),(int)(NEW)) \
: (__typeof__(*(PTR))) \
- __sync_val_compare_and_swap_di((long *)(void *)(PTR),(long)(OLD),(long)(NEW)))
+ __sync_val_compare_and_swap_8((long *)(void *)(PTR),(long)(OLD),(long)(NEW)))
-extern int __sync_bool_compare_and_swap_si (int *, int, int);
-extern int __sync_bool_compare_and_swap_di (long *, long, long);
#define __sync_bool_compare_and_swap(PTR, OLD, NEW) \
((sizeof (*(PTR)) == sizeof(int)) \
- ? __sync_bool_compare_and_swap_si((int *)(void *)(PTR),(int)(OLD),(int)(NEW)) \
- : __sync_bool_compare_and_swap_di((long *)(void *)(PTR),(long)(OLD),(long)(NEW)))
+ ? __sync_bool_compare_and_swap_4((int *)(void *)(PTR),(int)(OLD),(int)(NEW)) \
+ : __sync_bool_compare_and_swap_8((long *)(void *)(PTR),(long)(OLD),(long)(NEW)))
-extern void __sync_lock_release_si (int *);
-extern void __sync_lock_release_di (long *);
#define __sync_lock_release(PTR) \
((sizeof (*(PTR)) == sizeof(int)) \
- ? __sync_lock_release_si((int *)(void *)(PTR)) \
- : __sync_lock_release_di((long *)(void *)(PTR)))
+ ? __sync_lock_release_4((int *)(void *)(PTR)) \
+ : __sync_lock_release_8((long *)(void *)(PTR)))
-extern int __sync_lock_test_and_set_si (int *, int);
-extern long __sync_lock_test_and_set_di (long *, long);
#define __sync_lock_test_and_set(PTR,VAL) \
((sizeof (*(PTR)) == sizeof(int)) \
- ? (__typeof__(*(PTR))) __sync_lock_test_and_set_si((int *)(void *)(PTR),(int)(VAL)) \
- : (__typeof__(*(PTR))) __sync_lock_test_and_set_di((long *)(void *)(PTR),(long)(VAL)))
+ ? (__typeof__(*(PTR))) __sync_lock_test_and_set_4((int *)(void *)(PTR),(int)(VAL)) \
+ : (__typeof__(*(PTR))) __sync_lock_test_and_set_8((long *)(void *)(PTR),(long)(VAL)))
-extern int __sync_fetch_and_add_si (int *, int);
-extern long __sync_fetch_and_add_di (long *, long);
#define __sync_fetch_and_add(PTR,VAL) \
((sizeof (*(PTR)) == sizeof(int)) \
- ? (__typeof__(*(PTR))) __sync_fetch_and_add_si((int *)(void *)(PTR),(int)(VAL)) \
- : (__typeof__(*(PTR))) __sync_fetch_and_add_di((long *)(void *)(PTR),(long)(VAL)))
+ ? (__typeof__(*(PTR))) __sync_fetch_and_add_4((int *)(void *)(PTR),(int)(VAL)) \
+ : (__typeof__(*(PTR))) __sync_fetch_and_add_8((long *)(void *)(PTR),(long)(VAL)))
-extern int __sync_fetch_and_sub_si (int *, int);
-extern long __sync_fetch_and_sub_di (long *, long);
#define __sync_fetch_and_sub(PTR,VAL) \
((sizeof (*(PTR)) == sizeof(int)) \
- ? (__typeof__(*(PTR))) __sync_fetch_and_sub_si((int *)(void *)(PTR),(int)(VAL)) \
- : (__typeof__(*(PTR))) __sync_fetch_and_sub_di((long *)(void *)(PTR),(long)(VAL)))
+ ? (__typeof__(*(PTR))) __sync_fetch_and_sub_4((int *)(void *)(PTR),(int)(VAL)) \
+ : (__typeof__(*(PTR))) __sync_fetch_and_sub_8((long *)(void *)(PTR),(long)(VAL)))
-extern int __sync_fetch_and_and_si (int *, int);
-extern long __sync_fetch_and_and_di (long *, long);
#define __sync_fetch_and_and(PTR,VAL) \
((sizeof (*(PTR)) == sizeof(int)) \
- ? (__typeof__(*(PTR))) __sync_fetch_and_and_si((int *)(void *)(PTR),(int)(VAL)) \
- : (__typeof__(*(PTR))) __sync_fetch_and_and_di((long *)(void *)(PTR),(long)(VAL)))
+ ? (__typeof__(*(PTR))) __sync_fetch_and_and_4((int *)(void *)(PTR),(int)(VAL)) \
+ : (__typeof__(*(PTR))) __sync_fetch_and_and_8((long *)(void *)(PTR),(long)(VAL)))
-extern int __sync_fetch_and_or_si (int *, int);
-extern long __sync_fetch_and_or_di (long *, long);
#define __sync_fetch_and_or(PTR,VAL) \
((sizeof (*(PTR)) == sizeof(int)) \
- ? (__typeof__(*(PTR))) __sync_fetch_and_or_si((int *)(void *)(PTR),(int)(VAL)) \
- : (__typeof__(*(PTR))) __sync_fetch_and_or_di((long *)(void *)(PTR),(long)(VAL)))
+ ? (__typeof__(*(PTR))) __sync_fetch_and_or_4((int *)(void *)(PTR),(int)(VAL)) \
+ : (__typeof__(*(PTR))) __sync_fetch_and_or_8((long *)(void *)(PTR),(long)(VAL)))
-extern int __sync_fetch_and_xor_si (int *, int);
-extern long __sync_fetch_and_xor_di (long *, long);
#define __sync_fetch_and_xor(PTR,VAL) \
((sizeof (*(PTR)) == sizeof(int)) \
- ? (__typeof__(*(PTR))) __sync_fetch_and_xor_si((int *)(void *)(PTR),(int)(VAL)) \
- : (__typeof__(*(PTR))) __sync_fetch_and_xor_di((long *)(void *)(PTR),(long)(VAL)))
+ ? (__typeof__(*(PTR))) __sync_fetch_and_xor_4((int *)(void *)(PTR),(int)(VAL)) \
+ : (__typeof__(*(PTR))) __sync_fetch_and_xor_8((long *)(void *)(PTR),(long)(VAL)))
-extern int __sync_fetch_and_nand_si (int *, int);
-extern long __sync_fetch_and_nand_di (long *, long);
#define __sync_fetch_and_nand(PTR,VAL) \
((sizeof (*(PTR)) == sizeof(int)) \
- ? (__typeof__(*(PTR))) __sync_fetch_and_nand_si((int *)(void *)(PTR),(int)(VAL)) \
- : (__typeof__(*(PTR))) __sync_fetch_and_nand_di((long *)(void *)(PTR),(long)(VAL)))
+ ? (__typeof__(*(PTR))) __sync_fetch_and_nand_4((int *)(void *)(PTR),(int)(VAL)) \
+ : (__typeof__(*(PTR))) __sync_fetch_and_nand_8((long *)(void *)(PTR),(long)(VAL)))
-extern int __sync_add_and_fetch_si (int *, int);
-extern long __sync_add_and_fetch_di (long *, long);
#define __sync_add_and_fetch(PTR,VAL) \
((sizeof (*(PTR)) == sizeof(int)) \
- ? (__typeof__(*(PTR))) __sync_add_and_fetch_si((int *)(void *)(PTR),(int)(VAL)) \
- : (__typeof__(*(PTR))) __sync_add_and_fetch_di((long *)(void *)(PTR),(long)(VAL)))
+ ? (__typeof__(*(PTR))) __sync_add_and_fetch_4((int *)(void *)(PTR),(int)(VAL)) \
+ : (__typeof__(*(PTR))) __sync_add_and_fetch_8((long *)(void *)(PTR),(long)(VAL)))
-extern int __sync_sub_and_fetch_si (int *, int);
-extern long __sync_sub_and_fetch_di (long *, long);
#define __sync_sub_and_fetch(PTR,VAL) \
((sizeof (*(PTR)) == sizeof(int)) \
- ? (__typeof__(*(PTR))) __sync_sub_and_fetch_si((int *)(void *)(PTR),(int)(VAL)) \
- : (__typeof__(*(PTR))) __sync_sub_and_fetch_di((long *)(void *)(PTR),(long)(VAL)))
+ ? (__typeof__(*(PTR))) __sync_sub_and_fetch_4((int *)(void *)(PTR),(int)(VAL)) \
+ : (__typeof__(*(PTR))) __sync_sub_and_fetch_8((long *)(void *)(PTR),(long)(VAL)))
-extern int __sync_and_and_fetch_si (int *, int);
-extern long __sync_and_and_fetch_di (long *, long);
#define __sync_and_and_fetch(PTR,VAL) \
((sizeof (*(PTR)) == sizeof(int)) \
- ? (__typeof__(*(PTR))) __sync_and_and_fetch_si((int *)(void *)(PTR),(int)(VAL)) \
- : (__typeof__(*(PTR))) __sync_and_and_fetch_di((long *)(void *)(PTR),(long)(VAL)))
+ ? (__typeof__(*(PTR))) __sync_and_and_fetch_4((int *)(void *)(PTR),(int)(VAL)) \
+ : (__typeof__(*(PTR))) __sync_and_and_fetch_8((long *)(void *)(PTR),(long)(VAL)))
-extern int __sync_or_and_fetch_si (int *, int);
-extern long __sync_or_and_fetch_di (long *, long);
#define __sync_or_and_fetch(PTR,VAL) \
((sizeof (*(PTR)) == sizeof(int)) \
- ? (__typeof__(*(PTR))) __sync_or_and_fetch_si((int *)(void *)(PTR),(int)(VAL)) \
- : (__typeof__(*(PTR))) __sync_or_and_fetch_di((long *)(void *)(PTR),(long)(VAL)))
+ ? (__typeof__(*(PTR))) __sync_or_and_fetch_4((int *)(void *)(PTR),(int)(VAL)) \
+ : (__typeof__(*(PTR))) __sync_or_and_fetch_8((long *)(void *)(PTR),(long)(VAL)))
-extern int __sync_xor_and_fetch_si (int *, int);
-extern long __sync_xor_and_fetch_di (long *, long);
#define __sync_xor_and_fetch(PTR,VAL) \
((sizeof (*(PTR)) == sizeof(int)) \
- ? (__typeof__(*(PTR))) __sync_xor_and_fetch_si((int *)(void *)(PTR),(int)(VAL)) \
- : (__typeof__(*(PTR))) __sync_xor_and_fetch_di((long *)(void *)(PTR),(long)(VAL)))
+ ? (__typeof__(*(PTR))) __sync_xor_and_fetch_4((int *)(void *)(PTR),(int)(VAL)) \
+ : (__typeof__(*(PTR))) __sync_xor_and_fetch_8((long *)(void *)(PTR),(long)(VAL)))
-extern int __sync_nand_and_fetch_si (int *, int);
-extern long __sync_nand_and_fetch_di (long *, long);
#define __sync_nand_and_fetch(PTR,VAL) \
((sizeof (*(PTR)) == sizeof(int)) \
- ? (__typeof__(*(PTR))) __sync_nand_and_fetch_si((int *)(void *)(PTR),(int)(VAL)) \
- : (__typeof__(*(PTR))) __sync_nand_and_fetch_di((long *)(void *)(PTR),(long)(VAL)))
+ ? (__typeof__(*(PTR))) __sync_nand_and_fetch_4((int *)(void *)(PTR),(int)(VAL)) \
+ : (__typeof__(*(PTR))) __sync_nand_and_fetch_8((long *)(void *)(PTR),(long)(VAL)))
-#ifdef __cplusplus
-}
-#endif
+#endif /* __cplusplus */
-#endif
+#endif /* _IA64INTRIN_H_INCLUDED */
diff --git a/gcc/config/ia64/sync.md b/gcc/config/ia64/sync.md
new file mode 100644
index 0000000..ed3304a
--- /dev/null
+++ b/gcc/config/ia64/sync.md
@@ -0,0 +1,121 @@
+;; GCC machine description for IA-64 synchronization instructions.
+;; Copyright (C) 2005
+;; 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.
+;;
+;; 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, 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+(define_mode_macro I48MODE [SI DI])
+(define_mode_attr modesuffix [(SI "4") (DI "8")])
+
+
+(define_expand "memory_barrier"
+ [(set (mem:BLK (match_dup 0))
+ (unspec:BLK [(mem:BLK (match_dup 0))] UNSPEC_MF))]
+ ""
+{
+ operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (DImode));
+ MEM_VOLATILE_P (operands[0]) = 1;
+})
+
+(define_insn "*mf_internal"
+ [(set (match_operand:BLK 0 "" "")
+ (unspec:BLK [(match_operand:BLK 1 "" "")] UNSPEC_MF))]
+ ""
+ "mf"
+ [(set_attr "itanium_class" "syst_m")])
+
+(define_expand "sync_add<mode>"
+ [(match_operand:I48MODE 0 "gr_register_operand" "")
+ (match_operand:I48MODE 1 "memory_operand" "")
+ (match_operand:I48MODE 2 "general_operand" "")]
+ ""
+{
+ if (!fetchadd_operand (operands[2], <MODE>mode))
+ FAIL;
+ emit_insn (gen_memory_barrier ());
+ emit_insn (gen_fetchadd_acq_<mode> (operands[0], operands[1], operands[2]));
+ DONE;
+})
+
+(define_expand "sync_old_add<mode>"
+ [(match_operand:I48MODE 0 "gr_register_operand" "")
+ (match_operand:I48MODE 1 "memory_operand" "")
+ (match_operand:I48MODE 2 "general_operand" "")]
+ ""
+{
+ if (!fetchadd_operand (operands[2], <MODE>mode))
+ FAIL;
+ emit_insn (gen_memory_barrier ());
+ emit_insn (gen_fetchadd_acq_<mode> (operands[0], operands[1], operands[2]));
+ DONE;
+})
+
+(define_insn "fetchadd_acq_<mode>"
+ [(set (match_operand:I48MODE 0 "gr_register_operand" "=r")
+ (match_operand:I48MODE 1 "not_postinc_memory_operand" "+S"))
+ (set (match_dup 1)
+ (unspec:I48MODE [(match_dup 1)
+ (match_operand:I48MODE 2 "fetchadd_operand" "n")]
+ UNSPEC_FETCHADD_ACQ))]
+ ""
+ "fetchadd<modesuffix>.acq %0 = %1, %2"
+ [(set_attr "itanium_class" "sem")])
+
+(define_expand "sync_compare_and_swap<mode>"
+ [(match_operand:I48MODE 0 "gr_register_operand" "")
+ (match_operand:I48MODE 1 "memory_operand" "")
+ (match_operand:I48MODE 2 "gr_register_operand" "")
+ (match_operand:I48MODE 3 "gr_register_operand" "")]
+ ""
+{
+ rtx ccv = gen_rtx_REG (DImode, AR_CCV_REGNUM);
+ convert_move (ccv, operands[2], 1);
+ emit_insn (gen_memory_barrier ());
+ emit_insn (gen_cmpxchg_acq_<mode> (operands[0], operands[1],
+ ccv, operands[3]));
+ DONE;
+})
+
+(define_insn "cmpxchg_acq_<mode>"
+ [(set (match_operand:I48MODE 0 "gr_register_operand" "=r")
+ (match_operand:I48MODE 1 "not_postinc_memory_operand" "+S"))
+ (set (match_dup 1)
+ (unspec:I48MODE [(match_dup 1)
+ (match_operand:DI 2 "ar_ccv_reg_operand" "")
+ (match_operand:I48MODE 3 "gr_register_operand" "r")]
+ UNSPEC_CMPXCHG_ACQ))]
+ ""
+ "cmpxchg<modesuffix>.acq %0 = %1, %3, %2"
+ [(set_attr "itanium_class" "sem")])
+
+(define_insn "sync_lock_test_and_set<mode>"
+ [(set (match_operand:I48MODE 0 "gr_register_operand" "=r")
+ (match_operand:I48MODE 1 "not_postinc_memory_operand" "+S"))
+ (set (match_dup 1)
+ (match_operand:I48MODE 2 "gr_register_operand" "r"))]
+ ""
+ "xchg<modesuffix> %0 = %1, %2"
+ [(set_attr "itanium_class" "sem")])
+
+(define_expand "sync_lock_release<mode>"
+ [(set (match_operand:I48MODE 0 "memory_operand" "")
+ (const_int 0))]
+ ""
+{
+ gcc_assert (MEM_VOLATILE_P (operands[0]));
+})