builtins.c (expand_builtin_atomic_compare_exchange): Pass old value operand as MEM...
authorUlrich Weigand <uweigand@de.ibm.com>
Wed, 8 Aug 2012 18:03:37 +0000 (18:03 +0000)
committerUlrich Weigand <uweigand@gcc.gnu.org>
Wed, 8 Aug 2012 18:03:37 +0000 (18:03 +0000)
* 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<mode>"): 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
gcc/builtins.c
gcc/config/s390/s390.c
gcc/config/s390/s390.md

index 4bd66d6d0bfe11c2d7270f988d3e04bda38af37b..b8eb055a2029e8134b832579fe9a9223bc793008 100644 (file)
@@ -1,3 +1,14 @@
+2012-08-08  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>
+
+       * 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<mode>"): 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  <steven@gcc.gnu.org>
 
        PR middle-end/54146
index ba0655bea8e0ad5b4b3a122509846fd41f518a8a..4b177c48e65e9c09261ce152a8ed7e02294e4d37 100644 (file)
@@ -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;
 }
 
index 20a2db66042b13830fe8ee3993ec5aec58d3cf11..5297ff3ff8dfe9a8f46a2d5427c1ecee031ae50b 100644 (file)
@@ -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);
index 0e43e51a486f8357b8514c951953e034ff31507d..b3d096c9ef7c6f4a61b29f211b276cec1beb6633 100644 (file)
 
 (define_expand "atomic_compare_and_swap<mode>"
   [(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
    (match_operand:SI 7 "const_int_operand")]   ;; failure model
   ""
 {
-  rtx cc, cmp;
+  rtx cc, cmp, output = operands[1];
+
+  if (!register_operand (output, <MODE>mode))
+    output = gen_reg_rtx (<MODE>mode);
+
   emit_insn (gen_atomic_compare_and_swap<mode>_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));
 
 (define_expand "atomic_compare_and_swap<mode>"
   [(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