Commit a6de595f by Richard Henderson Committed by Richard Henderson

optabs.c (expand_atomic_test_and_set): Honor atomic_test_and_set_trueval even…

optabs.c (expand_atomic_test_and_set): Honor atomic_test_and_set_trueval even when atomic_test_and_set optab is not in use.

	* optabs.c (expand_atomic_test_and_set): Honor
	atomic_test_and_set_trueval even when atomic_test_and_set
	optab is not in use.

From-SVN: r184862
parent 6ecbd3a7
2012-03-02 Richard Henderson <rth@redhat.com>
* optabs.c (expand_atomic_test_and_set): Honor
atomic_test_and_set_trueval even when atomic_test_and_set
optab is not in use.
2012-03-02 Kaz Kojima <kkojima@gcc.gnu.org> 2012-03-02 Kaz Kojima <kkojima@gcc.gnu.org>
PR target/48596 PR target/48596
......
...@@ -7384,34 +7384,57 @@ rtx ...@@ -7384,34 +7384,57 @@ rtx
expand_atomic_test_and_set (rtx target, rtx mem, enum memmodel model) expand_atomic_test_and_set (rtx target, rtx mem, enum memmodel model)
{ {
enum machine_mode mode = GET_MODE (mem); enum machine_mode mode = GET_MODE (mem);
rtx ret; rtx ret, trueval, subtarget;
ret = maybe_emit_atomic_test_and_set (target, mem, model); ret = maybe_emit_atomic_test_and_set (target, mem, model);
if (ret) if (ret)
return ret; return ret;
if (target == NULL_RTX) /* Be binary compatible with non-default settings of trueval, and different
target = gen_reg_rtx (mode); cpu revisions. E.g. one revision may have atomic-test-and-set, but
another only has atomic-exchange. */
if (targetm.atomic_test_and_set_trueval == 1)
{
trueval = const1_rtx;
subtarget = target ? target : gen_reg_rtx (mode);
}
else
{
trueval = gen_int_mode (targetm.atomic_test_and_set_trueval, mode);
subtarget = gen_reg_rtx (mode);
}
/* If there is no test and set, try exchange, then a compare_and_swap loop, /* Try the atomic-exchange optab... */
then __sync_test_and_set. */ ret = maybe_emit_atomic_exchange (subtarget, mem, trueval, model);
ret = maybe_emit_atomic_exchange (target, mem, const1_rtx, model);
if (ret)
return ret;
ret = maybe_emit_compare_and_swap_exchange_loop (target, mem, const1_rtx); /* ... then an atomic-compare-and-swap loop ... */
if (ret) if (!ret)
return ret; ret = maybe_emit_compare_and_swap_exchange_loop (subtarget, mem, trueval);
ret = maybe_emit_sync_lock_test_and_set (target, mem, const1_rtx, model); /* ... before trying the vaguely defined legacy lock_test_and_set. */
if (ret) if (!ret)
return ret; ret = maybe_emit_sync_lock_test_and_set (subtarget, mem, trueval, model);
/* Failing all else, assume a single threaded environment and simply perform /* Recall that the legacy lock_test_and_set optab was allowed to do magic
the operation. */ things with the value 1. Thus we try again without trueval. */
emit_move_insn (target, mem); if (!ret && targetm.atomic_test_and_set_trueval != 1)
emit_move_insn (mem, const1_rtx); ret = maybe_emit_sync_lock_test_and_set (subtarget, mem, const1_rtx, model);
return target;
/* Failing all else, assume a single threaded environment and simply
perform the operation. */
if (!ret)
{
emit_move_insn (subtarget, mem);
emit_move_insn (mem, trueval);
ret = subtarget;
}
/* Recall that have to return a boolean value; rectify if trueval
is not exactly one. */
if (targetm.atomic_test_and_set_trueval != 1)
ret = emit_store_flag_force (target, NE, ret, const0_rtx, mode, 0, 1);
return ret;
} }
/* This function expands the atomic exchange operation: /* This function expands the atomic exchange operation:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment