From 0e07cb7f7d43282f601820a149eec66ea99a541f Mon Sep 17 00:00:00 2001 From: Oleg Endo Date: Tue, 31 May 2016 15:06:25 +0000 Subject: [PATCH] Fix wrong-code issues of RX atomic operations. gcc/ * config/rx/rx.md (FETCHOP_NO_MINUS): New code iterator. (atomic__fetchsi): Extract minus operator into ... (atomic_sub_fetchsi): ... this new pattern. (mvtc): Add CC_REG clobber. From-SVN: r236926 --- gcc/ChangeLog | 7 +++++++ gcc/config/rx/rx.md | 38 +++++++++++++++++++++++++++++--------- 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 59aae29bdc4..bdc3d172c4e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2016-05-31 Oleg Endo + + * config/rx/rx.md (FETCHOP_NO_MINUS): New code iterator. + (atomic__fetchsi): Extract minus operator into ... + (atomic_sub_fetchsi): ... this new pattern. + (mvtc): Add CC_REG clobber. + 2016-05-31 Marek Polacek * gimplify.c (gimplify_switch_expr): Also handle GIMPLE_TRY. diff --git a/gcc/config/rx/rx.md b/gcc/config/rx/rx.md index 9af16828b8c..b63f17708ce 100644 --- a/gcc/config/rx/rx.md +++ b/gcc/config/rx/rx.md @@ -2158,6 +2158,7 @@ ;; Atomic operations. (define_code_iterator FETCHOP [plus minus ior xor and]) +(define_code_iterator FETCHOP_NO_MINUS [plus ior xor and]) (define_code_attr fetchop_name [(plus "add") (minus "sub") (ior "or") (xor "xor") (and "and")]) @@ -2258,12 +2259,14 @@ }) ;; read - modify - write - return new value +;; Because subtraction is not commutative we need to specify a different +;; set of patterns for it. (define_expand "atomic__fetchsi" [(set (match_operand:SI 0 "register_operand") - (FETCHOP:SI (match_operand:SI 1 "rx_restricted_mem_operand") - (match_operand:SI 2 "register_operand"))) + (FETCHOP_NO_MINUS:SI (match_operand:SI 1 "rx_restricted_mem_operand") + (match_operand:SI 2 "register_operand"))) (set (match_dup 1) - (FETCHOP:SI (match_dup 1) (match_dup 2))) + (FETCHOP_NO_MINUS:SI (match_dup 1) (match_dup 2))) (match_operand:SI 3 "const_int_operand")] ;; memory model "" { @@ -2277,6 +2280,25 @@ DONE; }) +(define_expand "atomic_sub_fetchsi" + [(set (match_operand:SI 0 "register_operand") + (minus:SI (match_operand:SI 1 "rx_restricted_mem_operand") + (match_operand:SI 2 "rx_source_operand"))) + (set (match_dup 1) + (minus:SI (match_dup 1) (match_dup 2))) + (match_operand:SI 3 "const_int_operand")] ;; memory model + "" +{ + { + rx_atomic_sequence seq (current_function_decl); + + emit_move_insn (operands[0], operands[1]); + emit_insn (gen_subsi3 (operands[0], operands[0], operands[2])); + emit_move_insn (operands[1], operands[0]); + } + DONE; +}) + (define_expand "atomic_nand_fetchsi" [(set (match_operand:SI 0 "register_operand") (not:SI (and:SI (match_operand:SI 1 "rx_restricted_mem_operand") @@ -2674,18 +2696,16 @@ ) ;; Move to control register +;; This insn can be used in atomic sequences to restore the previous PSW +;; and re-enable interrupts. Because of that it always clobbers the CC_REG. (define_insn "mvtc" [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i,i") (match_operand:SI 1 "nonmemory_operand" "r,i")] - UNSPEC_BUILTIN_MVTC)] + UNSPEC_BUILTIN_MVTC) + (clobber (reg:CC CC_REG))] "" "mvtc\t%1, %C0" [(set_attr "length" "3,7")] - ;; Ignore possible clobbering of the comparison flags in the - ;; PSW register. This is a cc0 target so any cc0 setting - ;; instruction will always be paired with a cc0 user, without - ;; the possibility of this instruction being placed in between - ;; them. ) ;; Move to interrupt priority level -- 2.30.2