diff options
author | Richard Henderson <rth@redhat.com> | 2011-11-28 20:50:13 -0800 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2011-11-28 20:50:13 -0800 |
commit | db4e52814df0022e937794d28cca0d159c76a890 (patch) | |
tree | ebd00c31c8855b827d6a4da8ba9c5025b767e461 /gcc/config/rs6000 | |
parent | 20bc9eb1b8cd7e8fe9a3685d3183077ae160c821 (diff) | |
download | gcc-db4e52814df0022e937794d28cca0d159c76a890.zip gcc-db4e52814df0022e937794d28cca0d159c76a890.tar.gz gcc-db4e52814df0022e937794d28cca0d159c76a890.tar.bz2 |
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
Diffstat (limited to 'gcc/config/rs6000')
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 25 |
1 files changed, 12 insertions, 13 deletions
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index f01353b..5a33f91 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. */ |