Commit 215770ad by Ulrich Weigand Committed by Ulrich Weigand

builtins.c (expand_builtin_atomic_compare_exchange): Pass old value operand as…

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<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
parent 07c5a154
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> 2012-08-08 Steven Bosscher <steven@gcc.gnu.org>
PR middle-end/54146 PR middle-end/54146
......
...@@ -5376,6 +5376,7 @@ expand_builtin_atomic_compare_exchange (enum machine_mode mode, tree exp, ...@@ -5376,6 +5376,7 @@ expand_builtin_atomic_compare_exchange (enum machine_mode mode, tree exp,
expect = expand_normal (CALL_EXPR_ARG (exp, 1)); expect = expand_normal (CALL_EXPR_ARG (exp, 1));
expect = convert_memory_address (Pmode, expect); expect = convert_memory_address (Pmode, expect);
expect = gen_rtx_MEM (mode, expect);
desired = expand_expr_force_mode (CALL_EXPR_ARG (exp, 2), mode); desired = expand_expr_force_mode (CALL_EXPR_ARG (exp, 2), mode);
weak = CALL_EXPR_ARG (exp, 3); weak = CALL_EXPR_ARG (exp, 3);
...@@ -5383,14 +5384,15 @@ expand_builtin_atomic_compare_exchange (enum machine_mode mode, tree exp, ...@@ -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) if (host_integerp (weak, 0) && tree_low_cst (weak, 0) != 0)
is_weak = true; 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), if (!expand_atomic_compare_and_swap ((target == const0_rtx ? NULL : &target),
&oldval, mem, oldval, desired, &oldval, mem, oldval, desired,
is_weak, success, failure)) is_weak, success, failure))
return NULL_RTX; return NULL_RTX;
emit_move_insn (gen_rtx_MEM (mode, expect), oldval); if (oldval != expect)
emit_move_insn (expect, oldval);
return target; return target;
} }
......
...@@ -4825,7 +4825,6 @@ s390_expand_cs_hqi (enum machine_mode mode, rtx btarget, rtx vtarget, rtx mem, ...@@ -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 res = gen_reg_rtx (SImode);
rtx csloop = NULL, csend = NULL; rtx csloop = NULL, csend = NULL;
gcc_assert (register_operand (vtarget, VOIDmode));
gcc_assert (MEM_P (mem)); gcc_assert (MEM_P (mem));
init_alignment_context (&ac, mem, mode); init_alignment_context (&ac, mem, mode);
......
...@@ -8870,7 +8870,7 @@ ...@@ -8870,7 +8870,7 @@
(define_expand "atomic_compare_and_swap<mode>" (define_expand "atomic_compare_and_swap<mode>"
[(match_operand:SI 0 "register_operand") ;; bool success output [(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 2 "memory_operand") ;; memory
(match_operand:DGPR 3 "register_operand") ;; expected intput (match_operand:DGPR 3 "register_operand") ;; expected intput
(match_operand:DGPR 4 "register_operand") ;; newval intput (match_operand:DGPR 4 "register_operand") ;; newval intput
...@@ -8879,9 +8879,22 @@ ...@@ -8879,9 +8879,22 @@
(match_operand:SI 7 "const_int_operand")] ;; failure model (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 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); cc = gen_rtx_REG (CCZ1mode, CC_REGNUM);
cmp = gen_rtx_EQ (SImode, cc, const0_rtx); cmp = gen_rtx_EQ (SImode, cc, const0_rtx);
emit_insn (gen_cstorecc4 (operands[0], cmp, cc, const0_rtx)); emit_insn (gen_cstorecc4 (operands[0], cmp, cc, const0_rtx));
...@@ -8890,7 +8903,7 @@ ...@@ -8890,7 +8903,7 @@
(define_expand "atomic_compare_and_swap<mode>" (define_expand "atomic_compare_and_swap<mode>"
[(match_operand:SI 0 "register_operand") ;; bool success output [(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 2 "memory_operand") ;; memory
(match_operand:HQI 3 "general_operand") ;; expected intput (match_operand:HQI 3 "general_operand") ;; expected intput
(match_operand:HQI 4 "general_operand") ;; newval intput (match_operand:HQI 4 "general_operand") ;; newval intput
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment