diff options
Diffstat (limited to 'meta-xilinx-bsp/recipes-microblaze/gcc/gcc-7/0003-microblaze-sync.md-Correct-behaviour-and-define-side.patch')
-rw-r--r-- | meta-xilinx-bsp/recipes-microblaze/gcc/gcc-7/0003-microblaze-sync.md-Correct-behaviour-and-define-side.patch | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/meta-xilinx-bsp/recipes-microblaze/gcc/gcc-7/0003-microblaze-sync.md-Correct-behaviour-and-define-side.patch b/meta-xilinx-bsp/recipes-microblaze/gcc/gcc-7/0003-microblaze-sync.md-Correct-behaviour-and-define-side.patch new file mode 100644 index 00000000..9336291b --- /dev/null +++ b/meta-xilinx-bsp/recipes-microblaze/gcc/gcc-7/0003-microblaze-sync.md-Correct-behaviour-and-define-side.patch @@ -0,0 +1,76 @@ +From 6c7a10a9e077d0221cc9a6c5f5a6365815c1dca4 Mon Sep 17 00:00:00 2001 +From: Nathan Rossi <nathan@nathanrossi.com> +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 <nathan@nathanrossi.com> +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 @@ + ;; <http://www.gnu.org/licenses/>. + + (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 + |