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:
Richard Henderson 2011-11-28 20:50:13 -08:00 committed by Richard Henderson
parent 20bc9eb1b8
commit db4e52814d
2 changed files with 18 additions and 13 deletions

View File

@ -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

View File

@ -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. */