aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOleg Endo <olegendo@gcc.gnu.org>2016-05-31 15:06:25 +0000
committerOleg Endo <olegendo@gcc.gnu.org>2016-05-31 15:06:25 +0000
commit0e07cb7f7d43282f601820a149eec66ea99a541f (patch)
tree317adf2d4cf5b5acdcf536be2fb79f44646379aa
parentd6439e085433332e60145d535e98f599d7889808 (diff)
downloadgcc-0e07cb7f7d43282f601820a149eec66ea99a541f.zip
gcc-0e07cb7f7d43282f601820a149eec66ea99a541f.tar.gz
gcc-0e07cb7f7d43282f601820a149eec66ea99a541f.tar.bz2
Fix wrong-code issues of RX atomic operations.
gcc/ * config/rx/rx.md (FETCHOP_NO_MINUS): New code iterator. (atomic_<fetchop_name>_fetchsi): Extract minus operator into ... (atomic_sub_fetchsi): ... this new pattern. (mvtc): Add CC_REG clobber. From-SVN: r236926
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/rx/rx.md38
2 files changed, 36 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 59aae29..bdc3d17 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2016-05-31 Oleg Endo <olegendo@gcc.gnu.org>
+
+ * config/rx/rx.md (FETCHOP_NO_MINUS): New code iterator.
+ (atomic_<fetchop_name>_fetchsi): Extract minus operator into ...
+ (atomic_sub_fetchsi): ... this new pattern.
+ (mvtc): Add CC_REG clobber.
+
2016-05-31 Marek Polacek <polacek@redhat.com>
* gimplify.c (gimplify_switch_expr): Also handle GIMPLE_TRY.
diff --git a/gcc/config/rx/rx.md b/gcc/config/rx/rx.md
index 9af1682..b63f177 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_<fetchop_name>_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