rs6000: Streamline boolval output for compare-and-swap.
* config/rs6000/rs6000.c (rs6000_expand_atomic_compare_and_swap): Handle overlap between retval and oldval. Always compute boolval from CR0 EQ value. From-SVN: r181796
This commit is contained in:
parent
20bc9eb1b8
commit
db4e52814d
@ -1,3 +1,9 @@
|
|||||||
|
2011-11-28 Richard Henderson <rth@redhat.com>
|
||||||
|
|
||||||
|
* config/rs6000/rs6000.c (rs6000_expand_atomic_compare_and_swap):
|
||||||
|
Handle overlap between retval and oldval. Always compute boolval
|
||||||
|
from CR0 EQ value.
|
||||||
|
|
||||||
2011-11-28 Jakub Jelinek <jakub@redhat.com>
|
2011-11-28 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
PR debug/50317
|
PR debug/50317
|
||||||
|
@ -17352,11 +17352,11 @@ rs6000_expand_atomic_compare_and_swap (rtx operands[])
|
|||||||
retval = gen_reg_rtx (SImode);
|
retval = gen_reg_rtx (SImode);
|
||||||
mode = SImode;
|
mode = SImode;
|
||||||
}
|
}
|
||||||
|
else if (reg_overlap_mentioned_p (retval, oldval))
|
||||||
|
oldval = copy_to_reg (oldval);
|
||||||
|
|
||||||
rs6000_pre_atomic_barrier (mod_s);
|
rs6000_pre_atomic_barrier (mod_s);
|
||||||
|
|
||||||
emit_move_insn (boolval, const0_rtx);
|
|
||||||
|
|
||||||
label1 = NULL_RTX;
|
label1 = NULL_RTX;
|
||||||
if (!is_weak)
|
if (!is_weak)
|
||||||
{
|
{
|
||||||
@ -17374,28 +17374,23 @@ rs6000_expand_atomic_compare_and_swap (rtx operands[])
|
|||||||
NULL_RTX, 1, OPTAB_LIB_WIDEN);
|
NULL_RTX, 1, OPTAB_LIB_WIDEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
x = gen_rtx_NE (VOIDmode, x, oldval);
|
cond = gen_reg_rtx (CCmode);
|
||||||
x = rs6000_generate_compare (x, mode);
|
x = gen_rtx_COMPARE (CCmode, x, oldval);
|
||||||
|
emit_insn (gen_rtx_SET (VOIDmode, cond, x));
|
||||||
|
|
||||||
|
x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
|
||||||
emit_unlikely_jump (x, label2);
|
emit_unlikely_jump (x, label2);
|
||||||
|
|
||||||
x = newval;
|
x = newval;
|
||||||
if (mask)
|
if (mask)
|
||||||
x = rs6000_mask_atomic_subword (retval, newval, mask);
|
x = rs6000_mask_atomic_subword (retval, newval, mask);
|
||||||
|
|
||||||
cond = gen_reg_rtx (CCmode);
|
|
||||||
emit_store_conditional (mode, cond, mem, x);
|
emit_store_conditional (mode, cond, mem, x);
|
||||||
|
|
||||||
if (is_weak)
|
if (!is_weak)
|
||||||
{
|
|
||||||
/* ??? It's either this or an unlikely jump over (set bool 1). */
|
|
||||||
x = gen_rtx_EQ (SImode, cond, const0_rtx);
|
|
||||||
emit_insn (gen_rtx_SET (VOIDmode, boolval, x));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
|
x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
|
||||||
emit_unlikely_jump (x, label1);
|
emit_unlikely_jump (x, label1);
|
||||||
emit_move_insn (boolval, const1_rtx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mod_f != MEMMODEL_RELAXED)
|
if (mod_f != MEMMODEL_RELAXED)
|
||||||
@ -17408,6 +17403,10 @@ rs6000_expand_atomic_compare_and_swap (rtx operands[])
|
|||||||
|
|
||||||
if (shift)
|
if (shift)
|
||||||
rs6000_finish_atomic_subword (operands[1], retval, shift);
|
rs6000_finish_atomic_subword (operands[1], retval, shift);
|
||||||
|
|
||||||
|
/* In all cases, CR0 contains EQ on success, and NE on failure. */
|
||||||
|
x = gen_rtx_EQ (SImode, cond, const0_rtx);
|
||||||
|
emit_insn (gen_rtx_SET (VOIDmode, boolval, x));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Expand an atomic exchange operation. */
|
/* Expand an atomic exchange operation. */
|
||||||
|
Loading…
Reference in New Issue
Block a user