From db4e52814df0022e937794d28cca0d159c76a890 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 28 Nov 2011 20:50:13 -0800 Subject: [PATCH] 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 --- gcc/ChangeLog | 6 ++++++ gcc/config/rs6000/rs6000.c | 25 ++++++++++++------------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 30506838756..e8204e5dcd6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2011-11-28 Richard Henderson + + * 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 PR debug/50317 diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index f01353b8942..5a33f91d94c 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -17352,11 +17352,11 @@ rs6000_expand_atomic_compare_and_swap (rtx operands[]) retval = gen_reg_rtx (SImode); mode = SImode; } + else if (reg_overlap_mentioned_p (retval, oldval)) + oldval = copy_to_reg (oldval); rs6000_pre_atomic_barrier (mod_s); - emit_move_insn (boolval, const0_rtx); - label1 = NULL_RTX; if (!is_weak) { @@ -17374,28 +17374,23 @@ rs6000_expand_atomic_compare_and_swap (rtx operands[]) NULL_RTX, 1, OPTAB_LIB_WIDEN); } - x = gen_rtx_NE (VOIDmode, x, oldval); - x = rs6000_generate_compare (x, mode); + cond = gen_reg_rtx (CCmode); + 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); x = newval; if (mask) x = rs6000_mask_atomic_subword (retval, newval, mask); - cond = gen_reg_rtx (CCmode); emit_store_conditional (mode, cond, mem, x); - 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 + if (!is_weak) { x = gen_rtx_NE (VOIDmode, cond, const0_rtx); emit_unlikely_jump (x, label1); - emit_move_insn (boolval, const1_rtx); } if (mod_f != MEMMODEL_RELAXED) @@ -17408,6 +17403,10 @@ rs6000_expand_atomic_compare_and_swap (rtx operands[]) if (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. */