From 6c7a10a9e077d0221cc9a6c5f5a6365815c1dca4 Mon Sep 17 00:00:00 2001 From: Nathan Rossi Date: Mon, 12 Jun 2017 00:28:42 +1000 Subject: [PATCH 3/4] microblaze/sync.md: Correct behaviour and define side-effects This change corrects the behaviour with regards to the bool output. Previously the definition would set the bool operand to true (non-zero) on failure, specifically at the 'cmp' against the expected operand which would be set non-zero when the memory != expected value. Instead of using the bool operand as the compare result use the clobbered %8 operand for temporary comparison result and set the bool operand at the end of the definition to true (in this case the immediate value of 1). Also to ensure that the bool operand is 0 in all other cases the first instruction which is intended as a clear of the carry bit is reused to set the bool operand to 0 at the same time as clearing the carry bit. And finally the jump offsets were updated Additional to the behaviour change this change defines the side-effects of the atomic_compare_and_swap. Specifically the side effects where the bool and val operands are modified/set based on the value of the memory content. This prevents certain optimization behaviour from incorrectly optimizing away code. An example of this is the snippet below, where in certain cases the comparison is optimized away entirely. mem = 2; if (atomic_compare_and_swap(&mem, ...) == 2) ... Signed-off-by: Nathan Rossi Upstream-Status: Unsubmitted --- gcc/config/microblaze/sync.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/gcc/config/microblaze/sync.md b/gcc/config/microblaze/sync.md index 8125bd8d63..605a9a969e 100644 --- a/gcc/config/microblaze/sync.md +++ b/gcc/config/microblaze/sync.md @@ -18,9 +18,10 @@ ;; . (define_insn "atomic_compare_and_swapsi" - [(match_operand:SI 0 "register_operand" "=&d") ;; bool output - (match_operand:SI 1 "register_operand" "=&d") ;; val output - (match_operand:SI 2 "nonimmediate_operand" "+Q") ;; memory + [(set (match_operand:SI 0 "register_operand" "=&d") ;; bool output + (match_operand:SI 2 "nonimmediate_operand" "+Q")) ;; memory + (set (match_operand:SI 1 "register_operand" "=&d") ;; val output + (match_dup 2)) (match_operand:SI 3 "register_operand" "d") ;; expected value (match_operand:SI 4 "register_operand" "d") ;; desired value (match_operand:SI 5 "const_int_operand" "") ;; is_weak @@ -29,15 +30,16 @@ (clobber (match_scratch:SI 8 "=&d"))] "" { - output_asm_insn ("addc \tr0,r0,r0", operands); + output_asm_insn ("add \t%0,r0,r0", operands); output_asm_insn ("lwx \t%1,%y2,r0", operands); output_asm_insn ("addic\t%8,r0,0", operands); output_asm_insn ("bnei \t%8,.-8", operands); - output_asm_insn ("cmp \t%0,%1,%3", operands); - output_asm_insn ("bnei \t%0,.+16", operands); + output_asm_insn ("cmp \t%8,%1,%3", operands); + output_asm_insn ("bnei \t%8,.+20", operands); output_asm_insn ("swx \t%4,%y2,r0", operands); output_asm_insn ("addic\t%8,r0,0", operands); output_asm_insn ("bnei \t%8,.-28", operands); + output_asm_insn ("addi \t%0,r0,1", operands); return ""; } ) -- 2.11.0