aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/rs6000
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2011-11-28 20:50:13 -0800
committerRichard Henderson <rth@gcc.gnu.org>2011-11-28 20:50:13 -0800
commitdb4e52814df0022e937794d28cca0d159c76a890 (patch)
treeebd00c31c8855b827d6a4da8ba9c5025b767e461 /gcc/config/rs6000
parent20bc9eb1b8cd7e8fe9a3685d3183077ae160c821 (diff)
downloadgcc-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.c25
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. */