* builtins.c (expand_builtin_sync_operation): Revert last change.
* optabs.c (expand_bool_compare_and_swap): Compare vs old value,
not vs new value.
(expand_compare_and_swap_loop): Likewise.
(expand_sync_operation): Remove fallback from NAND to AND; invert
memory operand when expanding from cmpxchg.
(expand_sync_fetch_operation): Likewise.
* doc/extend.texi (Atomic Builtins): Fix docs for nand and
compare-and-swap.
* config/alpha/alpha.c (alpha_split_atomic_op): Invert memory operand
when implementing NAND. Fix double-add for AFTER.
* config/alpha/sync.md (sync_nand<I48MODE>): Invert memory operand.
(sync_old_nand<I48MODE>, sync_new_nand<I48MODE>): Likewise.
(sync_compare_and_swap<I48MODE>): Fix compare vs zero. Return old
memory value.
(sync_lock_test_and_set<I48MODE>): Remove extra label and last
memory barrier.
* config/i386/sync.md (sync_compare_and_swap<IMODE>): Fix pattern
to return old memory value.
(sync_compare_and_swap_cc<IMODE>): Likewise.
* config/ia64/ia64.c (ia64_dependencies_evaluation_hook): Early
return pre-reload. Don't consider output or anti dependencies.
* config/ia64/sync.md (IMODE): New.
(modesuffix): Add QI and HI.
(memory_barrier): Simplify expansion.
(sync_compare_and_swap<IMODE>): Use IMODE, not I48MODE.
(cmpxchg_acq_<IMODE>): Likewise.
(sync_lock_test_and_set<IMODE>): Likewise.
(sync_lock_release<IMODE>): Likewise.
From-SVN: r98436
+2005-04-19 Richard Henderson <rth@redhat.com>
+
+ * builtins.c (expand_builtin_sync_operation): Revert last change.
+ * optabs.c (expand_bool_compare_and_swap): Compare vs old value,
+ not vs new value.
+ (expand_compare_and_swap_loop): Likewise.
+ (expand_sync_operation): Remove fallback from NAND to AND; invert
+ memory operand when expanding from cmpxchg.
+ (expand_sync_fetch_operation): Likewise.
+ * doc/extend.texi (Atomic Builtins): Fix docs for nand and
+ compare-and-swap.
+
+ * config/alpha/alpha.c (alpha_split_atomic_op): Invert memory operand
+ when implementing NAND. Fix double-add for AFTER.
+ * config/alpha/sync.md (sync_nand<I48MODE>): Invert memory operand.
+ (sync_old_nand<I48MODE>, sync_new_nand<I48MODE>): Likewise.
+ (sync_compare_and_swap<I48MODE>): Fix compare vs zero. Return old
+ memory value.
+ (sync_lock_test_and_set<I48MODE>): Remove extra label and last
+ memory barrier.
+
+ * config/i386/sync.md (sync_compare_and_swap<IMODE>): Fix pattern
+ to return old memory value.
+ (sync_compare_and_swap_cc<IMODE>): Likewise.
+
+ * config/ia64/ia64.c (ia64_dependencies_evaluation_hook): Early
+ return pre-reload. Don't consider output or anti dependencies.
+ * config/ia64/sync.md (IMODE): New.
+ (modesuffix): Add QI and HI.
+ (memory_barrier): Simplify expansion.
+ (sync_compare_and_swap<IMODE>): Use IMODE, not I48MODE.
+ (cmpxchg_acq_<IMODE>): Likewise.
+ (sync_lock_test_and_set<IMODE>): Likewise.
+ (sync_lock_release<IMODE>): Likewise.
+
2005-04-19 James A. Morrison <phython@gcc.gnu.org>
* fold-const.c (fold_binary): Fold ~(X ^ Y) to ~X ^ Y or X ^ ~Y if
{
enum machine_mode mode;
rtx addr, val, mem;
- tree valt;
/* Expand the operands. */
addr = expand_expr (TREE_VALUE (arglist), NULL, Pmode, EXPAND_SUM);
mode = TYPE_MODE (TREE_TYPE (TREE_TYPE (TREE_VALUE (arglist))));
arglist = TREE_CHAIN (arglist);
- valt = TREE_VALUE (arglist);
- if (code == NOT && TREE_CONSTANT (valt))
- {
- valt = fold_build1 (BIT_NOT_EXPR, TREE_TYPE (valt), valt);
- code = AND;
- }
- val = expand_expr (valt, NULL, mode, EXPAND_NORMAL);
+ val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
/* Note that we explicitly do not want any alias information for this
memory, so that we kill all other live memories. Otherwise we don't
if (code == NOT)
{
- x = gen_rtx_NOT (mode, val);
- x = gen_rtx_AND (mode, x, before);
+ x = gen_rtx_NOT (mode, before);
+ x = gen_rtx_AND (mode, x, val);
}
else
x = gen_rtx_fmt_ee (code, mode, before, val);
- emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
if (after)
emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
+ emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
cond = gen_rtx_REG (DImode, REGNO (scratch));
if (mode == SImode)
(define_insn_and_split "sync_nand<mode>"
[(set (match_operand:I48MODE 0 "memory_operand" "+m")
(unspec_volatile:I48MODE
- [(and:I48MODE
- (not:I48MODE
- (match_operand:I48MODE 1 "reg_or_8bit_operand" "rI"))
- (match_dup 0))]
+ [(and:I48MODE (not:I48MODE (match_dup 0))
+ (match_operand:I48MODE 1 "register_operand" "r"))]
UNSPECV_ATOMIC))
(clobber (match_scratch:I48MODE 2 "=&r"))]
""
(match_operand:I48MODE 1 "memory_operand" "+m"))
(set (match_dup 1)
(unspec_volatile:I48MODE
- [(and:I48MODE
- (not:I48MODE
- (match_operand:I48MODE 2 "reg_or_8bit_operand" "rI"))
- (match_dup 1))]
+ [(and:I48MODE (not:I48MODE (match_dup 1))
+ (match_operand:I48MODE 2 "register_operand" "r"))]
UNSPECV_ATOMIC))
(clobber (match_scratch:I48MODE 3 "=&r"))]
""
(define_insn_and_split "sync_new_nand<mode>"
[(set (match_operand:I48MODE 0 "register_operand" "=&r")
(and:I48MODE
- (not:I48MODE
- (match_operand:I48MODE 2 "reg_or_8bit_operand" "rI"))
- (match_operand:I48MODE 1 "memory_operand" "+m")))
+ (not:I48MODE (match_operand:I48MODE 1 "memory_operand" "+m"))
+ (match_operand:I48MODE 2 "reg_or_8bit_operand" "rI")))
(set (match_dup 1)
(unspec_volatile:I48MODE
- [(and:I48MODE (not:I48MODE (match_dup 2)) (match_dup 1))]
+ [(and:I48MODE (not:I48MODE (match_dup 1)) (match_dup 2))]
UNSPECV_ATOMIC))
(clobber (match_scratch:I48MODE 3 "=&r"))]
""
emit_insn (gen_load_locked_<mode> (retval, mem));
x = gen_lowpart (DImode, retval);
- x = gen_rtx_EQ (DImode, x, oldval);
- if (oldval != const0_rtx)
+ if (oldval == const0_rtx)
+ x = gen_rtx_NE (DImode, x, const0_rtx);
+ else
{
+ x = gen_rtx_EQ (DImode, x, oldval);
emit_insn (gen_rtx_SET (VOIDmode, cond, x));
x = gen_rtx_EQ (DImode, cond, const0_rtx);
}
REG_NOTES (x) = gen_rtx_EXPR_LIST (REG_BR_PROB, very_unlikely, NULL_RTX);
emit_move_insn (scratch, newval);
- emit_move_insn (retval, newval);
-
+
emit_insn (gen_store_conditional_<mode> (cond, mem, scratch));
x = gen_rtx_EQ (DImode, cond, const0_rtx);
x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
REG_NOTES (x) = gen_rtx_EXPR_LIST (REG_BR_PROB, very_unlikely, NULL_RTX);
- emit_label (XEXP (label2, 0));
emit_insn (gen_memory_barrier ());
+ emit_label (XEXP (label2, 0));
DONE;
}
[(set_attr "type" "multi")])
[(const_int 0)]
{
rtx retval, mem, val, scratch;
- rtx cond, label1, label2, x;
+ rtx cond, label1, x;
rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
retval = operands[0];
emit_insn (gen_memory_barrier ());
label1 = gen_rtx_LABEL_REF (DImode, gen_label_rtx ());
- label2 = gen_rtx_LABEL_REF (DImode, gen_label_rtx ());
emit_label (XEXP (label1, 0));
emit_insn (gen_load_locked_<mode> (retval, mem));
x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
REG_NOTES (x) = gen_rtx_EXPR_LIST (REG_BR_PROB, very_unlikely, NULL_RTX);
- emit_label (XEXP (label2, 0));
- emit_insn (gen_memory_barrier ());
DONE;
}
[(set_attr "type" "multi")])
(define_insn "sync_compare_and_swap<mode>"
[(set (match_operand:IMODE 0 "register_operand" "=a")
+ (match_operand:IMODE 1 "memory_operand" "+m"))
+ (set (match_dup 1)
(unspec_volatile:IMODE
- [(match_operand:IMODE 1 "memory_operand" "+m")
+ [(match_dup 1)
(match_operand:IMODE 2 "register_operand" "a")
(match_operand:IMODE 3 "register_operand" "<modeconstraint>")]
UNSPECV_CMPXCHG_1))
- (set (match_dup 1)
- (unspec_volatile:IMODE
- [(match_dup 1) (match_dup 2) (match_dup 3)] UNSPECV_CMPXCHG_2))
(clobber (reg:CC FLAGS_REG))]
"TARGET_CMPXCHG"
"lock\;cmpxchg{<modesuffix>}\t{%3, %1|%1, %3}")
(define_expand "sync_compare_and_swap_cc<mode>"
[(parallel
[(set (match_operand:IMODE 0 "register_operand" "")
+ (match_operand:IMODE 1 "memory_operand" ""))
+ (set (match_dup 1)
(unspec_volatile:IMODE
- [(match_operand:IMODE 1 "memory_operand" "")
+ [(match_dup 1)
(match_operand:IMODE 2 "register_operand" "")
(match_operand:IMODE 3 "register_operand" "")]
UNSPECV_CMPXCHG_1))
- (set (match_dup 1)
- (unspec_volatile:IMODE
- [(match_dup 1) (match_dup 2) (match_dup 3)] UNSPECV_CMPXCHG_2))
(set (match_dup 4)
(compare:CCZ
(unspec_volatile:IMODE
- [(match_dup 1) (match_dup 2) (match_dup 3)] UNSPECV_CMPXCHG_1)
- (match_dup 3)))])]
+ [(match_dup 1) (match_dup 2) (match_dup 3)] UNSPECV_CMPXCHG_2)
+ (match_dup 2)))])]
"TARGET_CMPXCHG"
{
operands[4] = gen_rtx_REG (CCZmode, FLAGS_REG);
(define_insn "*sync_compare_and_swap_cc<mode>"
[(set (match_operand:IMODE 0 "register_operand" "=a")
+ (match_operand:IMODE 1 "memory_operand" "+m"))
+ (set (match_dup 1)
(unspec_volatile:IMODE
- [(match_operand:IMODE 1 "memory_operand" "+m")
+ [(match_dup 1)
(match_operand:IMODE 2 "register_operand" "a")
(match_operand:IMODE 3 "register_operand" "<modeconstraint>")]
UNSPECV_CMPXCHG_1))
- (set (match_dup 1)
- (unspec_volatile:IMODE
- [(match_dup 1) (match_dup 2) (match_dup 3)] UNSPECV_CMPXCHG_2))
(set (reg:CCZ FLAGS_REG)
(compare:CCZ
(unspec_volatile:IMODE
- [(match_dup 1) (match_dup 2) (match_dup 3)] UNSPECV_CMPXCHG_1)
- (match_dup 3)))]
+ [(match_dup 1) (match_dup 2) (match_dup 3)] UNSPECV_CMPXCHG_2)
+ (match_dup 2)))]
"TARGET_CMPXCHG"
"lock\;cmpxchg{<modesuffix>}\t{%3, %1|%1, %3}")
{
rtx insn, link, next, next_tail;
+ /* Before reload, which_alternative is not set, which means that
+ ia64_safe_itanium_class will produce wrong results for (at least)
+ move instructions. */
+ if (!reload_completed)
+ return;
+
next_tail = NEXT_INSN (tail);
for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
if (INSN_P (insn))
{
for (link = INSN_DEPEND (insn); link != 0; link = XEXP (link, 1))
{
+ if (REG_NOTE_KIND (link) != REG_DEP_TRUE)
+ continue;
next = XEXP (link, 0);
if ((ia64_safe_itanium_class (next) == ITANIUM_CLASS_ST
|| ia64_safe_itanium_class (next) == ITANIUM_CLASS_STF)
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
+(define_mode_macro IMODE [QI HI SI DI])
(define_mode_macro I48MODE [SI DI])
-(define_mode_attr modesuffix [(SI "4") (DI "8")])
+(define_mode_attr modesuffix [(QI "1") (HI "2") (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))]
+(define_insn "memory_barrier"
+ [(set (mem:BLK (match_scratch:DI 0 "X"))
+ (unspec:BLK [(mem:BLK (match_scratch:DI 1 "X"))] UNSPEC_MF))]
""
"mf"
[(set_attr "itanium_class" "syst_m")])
[(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" "")]
+ [(match_operand:IMODE 0 "gr_register_operand" "")
+ (match_operand:IMODE 1 "memory_operand" "")
+ (match_operand:IMODE 2 "gr_register_operand" "")
+ (match_operand:IMODE 3 "gr_register_operand" "")]
""
{
rtx ccv = gen_rtx_REG (DImode, AR_CCV_REGNUM);
})
(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_operand:IMODE 0 "gr_register_operand" "=r")
+ (match_operand:IMODE 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))]
+ (unspec:IMODE [(match_dup 1)
+ (match_operand:DI 2 "ar_ccv_reg_operand" "")
+ (match_operand:IMODE 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_operand:IMODE 0 "gr_register_operand" "=r")
+ (match_operand:IMODE 1 "not_postinc_memory_operand" "+S"))
(set (match_dup 1)
- (match_operand:I48MODE 2 "gr_register_operand" "r"))]
+ (match_operand:IMODE 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" "")
- (match_operand:I48MODE 1 "gr_reg_or_0_operand" ""))]
+ [(set (match_operand:IMODE 0 "memory_operand" "")
+ (match_operand:IMODE 1 "gr_reg_or_0_operand" ""))]
""
{
gcc_assert (MEM_VOLATILE_P (operands[0]));
@smallexample
@{ tmp = *ptr; *ptr @var{op}= value; return tmp; @}
+@{ tmp = *ptr; *ptr = ~tmp & value; return tmp; @} // nand
@end smallexample
-The builtin @code{__sync_fetch_and_nand} could be implemented by
-@code{__sync_fetch_and_and(ptr, ~value)}.
-
@item @var{type} __sync_add_and_fetch (@var{type} *ptr, @var{type} value, ...)
@itemx @var{type} __sync_sub_and_fetch (@var{type} *ptr, @var{type} value, ...)
@itemx @var{type} __sync_or_and_fetch (@var{type} *ptr, @var{type} value, ...)
@smallexample
@{ *ptr @var{op}= value; return *ptr; @}
+@{ *ptr = ~*ptr & value; return *ptr; @} // nand
@end smallexample
@item bool __sync_bool_compare_and_swap (@var{type} *ptr, @var{type} oldval @var{type} newval, ...)
The ``bool'' version returns true if the comparison is successful and
@var{newval} was written. The ``val'' version returns the contents
-of @code{*@var{ptr}} after the operation.
+of @code{*@var{ptr}} before the operation.
@item __sync_synchronize (...)
@findex __sync_synchronize
if (icode == CODE_FOR_nothing)
return NULL_RTX;
+ /* Ensure that if old_val == mem, that we're not comparing
+ against an old value. */
+ if (GET_CODE (old_val) == MEM)
+ old_val = force_reg (mode, old_val);
+
subtarget = expand_val_compare_and_swap_1 (mem, old_val, new_val,
NULL_RTX, icode);
if (subtarget == NULL_RTX)
return NULL_RTX;
- emit_cmp_insn (subtarget, new_val, EQ, const0_rtx, mode, true);
+ emit_cmp_insn (subtarget, old_val, EQ, const0_rtx, mode, true);
}
/* If the target has a sane STORE_FLAG_VALUE, then go ahead and use a
if (subtarget == NULL_RTX)
return false;
- emit_cmp_insn (subtarget, new_reg, EQ, const0_rtx, mode, true);
+ emit_cmp_insn (subtarget, old_reg, EQ, const0_rtx, mode, true);
}
/* ??? Mark this jump predicted not taken? */
case AND:
icode = sync_and_optab[mode];
break;
+ case NOT:
+ icode = sync_nand_optab[mode];
+ break;
case MINUS:
icode = sync_sub_optab[mode];
}
break;
- case NOT:
- icode = sync_nand_optab[mode];
- if (icode == CODE_FOR_nothing)
- {
- icode = sync_and_optab[mode];
- if (icode != CODE_FOR_nothing)
- {
- val = expand_simple_unop (mode, NOT, val, NULL_RTX, 1);
- code = AND;
- }
- }
- break;
-
default:
gcc_unreachable ();
}
start_sequence ();
+ t1 = t0;
if (code == NOT)
{
- val = expand_simple_unop (mode, NOT, val, NULL_RTX, true);
+ t1 = expand_simple_unop (mode, NOT, t1, NULL_RTX, true);
code = AND;
}
- t1 = expand_simple_binop (mode, code, t0, val, NULL_RTX,
+ t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX,
true, OPTAB_LIB_WIDEN);
insn = get_insns ();
old_code = sync_old_and_optab[mode];
new_code = sync_new_and_optab[mode];
break;
+ case NOT:
+ old_code = sync_old_nand_optab[mode];
+ new_code = sync_new_nand_optab[mode];
+ break;
case MINUS:
old_code = sync_old_sub_optab[mode];
}
break;
- case NOT:
- old_code = sync_old_nand_optab[mode];
- new_code = sync_new_nand_optab[mode];
- if (old_code == CODE_FOR_nothing && new_code == CODE_FOR_nothing)
- {
- old_code = sync_old_sub_optab[mode];
- new_code = sync_new_sub_optab[mode];
- if (old_code != CODE_FOR_nothing || new_code != CODE_FOR_nothing)
- {
- val = expand_simple_unop (mode, NOT, val, NULL_RTX, 1);
- code = AND;
- }
- }
- break;
-
default:
gcc_unreachable ();
}
else if (code == MINUS)
code = PLUS;
}
+
+ if (code == NOT)
+ target = expand_simple_unop (mode, NOT, target, NULL_RTX, true);
target = expand_simple_binop (mode, code, target, val, NULL_RTX,
true, OPTAB_LIB_WIDEN);
}
start_sequence ();
+ if (!after)
+ emit_move_insn (target, t0);
+ t1 = t0;
if (code == NOT)
{
- val = expand_simple_unop (mode, NOT, val, NULL_RTX, true);
+ t1 = expand_simple_unop (mode, NOT, t1, NULL_RTX, true);
code = AND;
}
- if (!after)
- emit_move_insn (target, t0);
- t1 = expand_simple_binop (mode, code, t0, val, NULL_RTX,
+ t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX,
true, OPTAB_LIB_WIDEN);
if (after)
emit_move_insn (target, t1);
+2005-04-19 Richard Henderson <rth@redhat.com>
+
+ * lib/target-supports.exp (check_effective_target_vect_int_mult):
+ Fix typo in exists check.
+ (check_effective_target_sync_int_long): New.
+ * gcc.dg/ia64-sync-1.c: Enable for all effective-target sync_int_long.
+ * gcc.dg/ia64-sync-2.c: Likewise.
+ * gcc.dg/ia64-sync-3.c: Likewise.
+ * gcc.dg/ia64-sync-4.c: Likewise.
+
2005-04-19 James A. Morrison <phython@gcc.gnu.org>
* gcc.dg/fold-xor-1.c: New test.
-/* { dg-do run { target ia64-*-* } } */
+/* { dg-do run } */
+/* { dg-require-effective-target sync_int_long } */
/* { dg-options } */
+/* { dg-options "-march=i486" { target i?86-*-* } } */
+/* { dg-options "-march=i486" { target { x86_64-*-* && ilp32 } } } */
/* Test basic functionality of the intrinsics. The operations should
not be optimized away if no one checks the return values. */
-#include <ia64intrin.h>
-
extern void abort (void);
extern void *memcpy (void *, const void *, __SIZE_TYPE__);
-/* { dg-do run { target ia64-*-* } } */
+/* { dg-do run } */
+/* { dg-require-effective-target sync_int_long } */
/* { dg-options } */
+/* { dg-options "-march=i486" { target i?86-*-* } } */
+/* { dg-options "-march=i486" { target { x86_64-*-* && ilp32 } } } */
/* Test basic functionality of the intrinsics. */
-#include <ia64intrin.h>
-
extern void abort (void);
extern void *memcpy (void *, const void *, __SIZE_TYPE__);
-/* { dg-do run { target ia64-*-* } } */
+/* { dg-do run } */
+/* { dg-require-effective-target sync_int_long } */
/* { dg-options } */
+/* { dg-options "-march=i486" { target i?86-*-* } } */
+/* { dg-options "-march=i486" { target { x86_64-*-* && ilp32 } } } */
/* Test basic functionality of the intrinsics. */
-#include <ia64intrin.h>
-
extern void abort (void);
extern void *memcpy (void *, const void *, __SIZE_TYPE__);
-/* { dg-do compile { target ia64-*-* } } */
+/* { dg-do compile } */
+/* { dg-require-effective-target sync_int_long } */
/* { dg-options "-O2 -finline-functions" } */
+/* { dg-options "-march=i486" { target i?86-*-* } } */
+/* { dg-options "-march=i486" { target { x86_64-*-* && ilp32 } } } */
-/* Test inlining __sync_bool_compare_and_swap_di. */
+/* Test inlining __sync_bool_compare_and_swap. */
#include <stdbool.h>
-#include <ia64intrin.h>
static bool
compare_and_swap(long *addr, long old, long new_val)
{
- return __sync_bool_compare_and_swap_di(addr, old, new_val);
+ return __sync_bool_compare_and_swap(addr, old, new_val);
}
void
proc check_effective_target_vect_int_mult { } {
global et_vect_int_mult_saved
- if [info exists et_vect_int_mult] {
+ if [info exists et_vect_int_mult_saved] {
verbose "check_effective_target_vect_int_mult: using cached result" 2
} else {
set et_vect_int_mult_saved 0
return $et_vect_int_mult_saved
}
+# Return 1 if the target supports atomic operations on "int" and "long".
+
+proc check_effective_target_sync_int_long { } {
+ global et_sync_int_long_saved
+
+ if [info exists et_sync_int_long_saved] {
+ verbose "check_effective_target_sync_int_long: using cached result" 2
+ } else {
+ set et_sync_int_long_saved 0
+ if { [istarget ia64-*-*]
+ || [istarget i?86-*-*]
+ || [istarget x86_64-*-*]
+ || [istarget alpha*-*-*] } {
+ set et_sync_int_long_saved 1
+ }
+ }
+
+ verbose "check_effective_target_sync_int_long: returning $et_sync_int_long_saved" 2
+ return $et_sync_int_long_saved
+}
+
# Return 1 if the target matches the effective target 'arg', 0 otherwise.
# This can be used with any check_* proc that takes no argument and
# returns only 1 or 0. It could be used with check_* procs that take