From 215770ada8310953eb90e2369b796263dcf5f770 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Wed, 8 Aug 2012 18:03:37 +0000 Subject: [PATCH] builtins.c (expand_builtin_atomic_compare_exchange): Pass old value operand as MEM to expand_atomic_compare_and_swap. * builtins.c (expand_builtin_atomic_compare_exchange): Pass old value operand as MEM to expand_atomic_compare_and_swap. * config/s390/s390.md ("atomic_compare_and_swap"): Accept nonimmediate_operand for old value; generate load and store if needed. * config/s390/s390.c (s390_expand_cs_hqi): Accept any operand as vtarget. From-SVN: r190236 --- gcc/ChangeLog | 11 +++++++++++ gcc/builtins.c | 8 +++++--- gcc/config/s390/s390.c | 1 - gcc/config/s390/s390.md | 21 +++++++++++++++++---- 4 files changed, 33 insertions(+), 8 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4bd66d6d0bf..b8eb055a202 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2012-08-08 Ulrich Weigand + + * builtins.c (expand_builtin_atomic_compare_exchange): Pass old + value operand as MEM to expand_atomic_compare_and_swap. + + * config/s390/s390.md ("atomic_compare_and_swap"): Accept + nonimmediate_operand for old value; generate load and store if + needed. + * config/s390/s390.c (s390_expand_cs_hqi): Accept any operand + as vtarget. + 2012-08-08 Steven Bosscher PR middle-end/54146 diff --git a/gcc/builtins.c b/gcc/builtins.c index ba0655bea8e..4b177c48e65 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -5376,6 +5376,7 @@ expand_builtin_atomic_compare_exchange (enum machine_mode mode, tree exp, expect = expand_normal (CALL_EXPR_ARG (exp, 1)); expect = convert_memory_address (Pmode, expect); + expect = gen_rtx_MEM (mode, expect); desired = expand_expr_force_mode (CALL_EXPR_ARG (exp, 2), mode); weak = CALL_EXPR_ARG (exp, 3); @@ -5383,14 +5384,15 @@ expand_builtin_atomic_compare_exchange (enum machine_mode mode, tree exp, if (host_integerp (weak, 0) && tree_low_cst (weak, 0) != 0) is_weak = true; - oldval = copy_to_reg (gen_rtx_MEM (mode, expect)); - + oldval = expect; if (!expand_atomic_compare_and_swap ((target == const0_rtx ? NULL : &target), &oldval, mem, oldval, desired, is_weak, success, failure)) return NULL_RTX; - emit_move_insn (gen_rtx_MEM (mode, expect), oldval); + if (oldval != expect) + emit_move_insn (expect, oldval); + return target; } diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 20a2db66042..5297ff3ff8d 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -4825,7 +4825,6 @@ s390_expand_cs_hqi (enum machine_mode mode, rtx btarget, rtx vtarget, rtx mem, rtx res = gen_reg_rtx (SImode); rtx csloop = NULL, csend = NULL; - gcc_assert (register_operand (vtarget, VOIDmode)); gcc_assert (MEM_P (mem)); init_alignment_context (&ac, mem, mode); diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 0e43e51a486..b3d096c9ef7 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -8870,7 +8870,7 @@ (define_expand "atomic_compare_and_swap" [(match_operand:SI 0 "register_operand") ;; bool success output - (match_operand:DGPR 1 "register_operand") ;; oldval output + (match_operand:DGPR 1 "nonimmediate_operand");; oldval output (match_operand:DGPR 2 "memory_operand") ;; memory (match_operand:DGPR 3 "register_operand") ;; expected intput (match_operand:DGPR 4 "register_operand") ;; newval intput @@ -8879,9 +8879,22 @@ (match_operand:SI 7 "const_int_operand")] ;; failure model "" { - rtx cc, cmp; + rtx cc, cmp, output = operands[1]; + + if (!register_operand (output, mode)) + output = gen_reg_rtx (mode); + emit_insn (gen_atomic_compare_and_swap_internal - (operands[1], operands[2], operands[3], operands[4])); + (output, operands[2], operands[3], operands[4])); + + /* We deliberately accept non-register operands in the predicate + to ensure the write back to the output operand happens *before* + the store-flags code below. This makes it easier for combine + to merge the store-flags code with a potential test-and-branch + pattern following (immediately!) afterwards. */ + if (output != operands[1]) + emit_move_insn (operands[1], output); + cc = gen_rtx_REG (CCZ1mode, CC_REGNUM); cmp = gen_rtx_EQ (SImode, cc, const0_rtx); emit_insn (gen_cstorecc4 (operands[0], cmp, cc, const0_rtx)); @@ -8890,7 +8903,7 @@ (define_expand "atomic_compare_and_swap" [(match_operand:SI 0 "register_operand") ;; bool success output - (match_operand:HQI 1 "register_operand") ;; oldval output + (match_operand:HQI 1 "nonimmediate_operand") ;; oldval output (match_operand:HQI 2 "memory_operand") ;; memory (match_operand:HQI 3 "general_operand") ;; expected intput (match_operand:HQI 4 "general_operand") ;; newval intput -- 2.30.2