1 ;; GCC machine description for C6X synchronization instructions.
2 ;; Copyright (C) 2011-2017 Free Software Foundation, Inc.
4 ;; This file is part of GCC.
6 ;; GCC is free software; you can redistribute it and/or modify
7 ;; it under the terms of the GNU General Public License as published by
8 ;; the Free Software Foundation; either version 3, or (at your option)
11 ;; GCC is distributed in the hope that it will be useful,
12 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ;; GNU General Public License for more details.
16 ;; You should have received a copy of the GNU General Public License
17 ;; along with GCC; see the file COPYING3. If not see
18 ;; <http://www.gnu.org/licenses/>.
20 ;; C64X+ has atomic instructions, but they are not atomic on all
21 ;; devices and have other problems. We use normal loads and stores,
22 ;; and place them in overlapping branch shadows to ensure interrupts
23 ;; are disabled during the sequence, which guarantees atomicity on all
24 ;; single-core systems.
26 (define_code_iterator FETCHOP [plus minus ior xor and])
27 (define_code_attr fetchop_name
28 [(plus "add") (minus "sub") (ior "ior") (xor "xor") (and "and")])
29 (define_code_attr fetchop_pred
30 [(plus "reg_or_scst5_operand") (minus "register_operand")
31 (ior "reg_or_scst5_operand") (xor "reg_or_scst5_operand")
32 (and "reg_or_scst5_operand")])
33 (define_code_attr fetchop_constr
34 [(plus "bIs5") (minus "b") (ior "bIs5") (xor "bIs5") (and "bIs5")])
35 (define_code_attr fetchop_opcode
36 [(plus "add") (minus "sub") (ior "or") (xor "xor") (and "and")])
37 (define_code_attr fetchop_inops02
38 [(plus "%2, %0") (minus "%0, %2") (ior "%2, %0") (xor "%2, %0")
40 (define_code_attr fetchop_inops21
41 [(plus "%1, %2") (minus "%2, %1") (ior "%1, %2") (xor "%1, %2")
44 (define_expand "sync_compare_and_swapsi"
46 [(set (match_operand:SI 0 "register_operand" "")
47 (match_operand:SI 1 "memory_operand" ""))
50 [(match_operand:SI 2 "register_operand" "")
51 (match_operand:SI 3 "register_operand" "")]
53 (clobber (match_scratch:SI 4 ""))])]
58 (define_expand "sync_<fetchop_name>si"
60 [(set (match_operand:SI 0 "memory_operand" "")
62 [(FETCHOP:SI (match_dup 0)
63 (match_operand:SI 1 "<fetchop_pred>" ""))]
65 (clobber (match_scratch:SI 2 ""))])]
70 (define_expand "sync_old_<fetchop_name>si"
72 [(set (match_operand:SI 0 "register_operand" "")
73 (match_operand:SI 1 "memory_operand" ""))
76 [(FETCHOP:SI (match_dup 1)
77 (match_operand:SI 2 "<fetchop_pred>" ""))]
79 (clobber (match_scratch:SI 3 ""))])]
84 (define_expand "sync_new_<fetchop_name>si"
86 [(set (match_operand:SI 0 "register_operand" "")
87 (FETCHOP:SI (match_operand:SI 1 "memory_operand" "")
88 (match_operand:SI 2 "<fetchop_pred>" "")))
90 (unspec:SI [(FETCHOP:SI (match_dup 1) (match_dup 2))]
92 (clobber (match_scratch:SI 3 ""))])]
97 (define_expand "sync_nandsi"
99 [(set (match_operand:SI 0 "memory_operand" "")
101 [(not:SI (and:SI (match_dup 0)
102 (match_operand:SI 1 "reg_or_scst5_operand" "")))]
104 (clobber (match_scratch:SI 2 ""))])]
109 (define_expand "sync_old_nandsi"
111 [(set (match_operand:SI 0 "register_operand" "")
112 (match_operand:SI 1 "memory_operand" ""))
115 [(not:SI (and:SI (match_dup 1)
116 (match_operand:SI 2 "reg_or_scst5_operand" "")))]
118 (clobber (match_scratch:SI 3 ""))])]
123 (define_expand "sync_new_nandsi"
125 [(set (match_operand:SI 0 "register_operand" "")
126 (not:SI (and:SI (match_operand:SI 1 "memory_operand" "")
127 (match_operand:SI 2 "reg_or_scst5_operand" ""))))
129 (unspec:SI [(not:SI (and:SI (match_dup 1) (match_dup 2)))]
131 (clobber (match_scratch:SI 3 ""))])]
136 (define_insn "*sync_compare_and_swapsi"
137 [(set (match_operand:SI 0 "register_operand" "=&b")
138 (match_operand:SI 1 "memory_operand" "+m"))
141 [(match_operand:SI 2 "register_operand" "B")
142 (match_operand:SI 3 "register_operand" "b")]
144 (clobber (match_scratch:SI 4 "=&B"))]
147 || ldw .d%U1t%U0 %1, %0\n\\
150 cmpeq .l2 %0, %2, %2 ; 5\n\\
151 1: [%2] stw .d%U1t%U3 %3, %1 ; 6\n\\
153 [(set_attr "type" "atomic")])
155 (define_insn "sync_<fetchop_name>si_insn"
156 [(set (match_operand:SI 0 "memory_operand" "+m")
158 [(FETCHOP:SI (match_dup 0)
159 (match_operand:SI 1 "<fetchop_pred>" "<fetchop_constr>"))]
161 (clobber (match_scratch:SI 2 "=&B"))]
164 || ldw .d%U0t%U2 %0, %2\n\\
167 <fetchop_opcode> .l2 <fetchop_inops21>, %2 ; 5\n\\
168 1: stw .d%U0t%U2 %2, %0 ; 6\n\\
170 [(set_attr "type" "atomic")])
172 (define_insn "sync_old_<fetchop_name>si_insn"
173 [(set (match_operand:SI 0 "register_operand" "=&b")
174 (match_operand:SI 1 "memory_operand" "+m"))
177 [(FETCHOP:SI (match_dup 1)
178 (match_operand:SI 2 "<fetchop_pred>" "<fetchop_constr>"))]
180 (clobber (match_scratch:SI 3 "=&B"))]
183 || ldw .d%U1t%U0 %1, %0\n\\
186 <fetchop_opcode> .l2 <fetchop_inops02>, %3 ; 5\n\\
187 1: stw .d%U1t%U3 %3, %1 ; 6\n\\
189 [(set_attr "type" "atomic")])
191 (define_insn "sync_new_<fetchop_name>si_insn"
192 [(set (match_operand:SI 0 "register_operand" "=&b")
193 (FETCHOP:SI (match_operand:SI 1 "memory_operand" "+m")
194 (match_operand:SI 2 "<fetchop_pred>" "<fetchop_constr>")))
197 [(FETCHOP:SI (match_dup 1)
200 (clobber (match_scratch:SI 3 "=&B"))]
203 || ldw .d%U1t%U0 %1, %0\n\\
206 <fetchop_opcode> .l2 <fetchop_inops02>, %0 ; 5\n\\
207 1: stw .d%U1t%U0 %0, %1 ; 6\n\\
209 [(set_attr "type" "atomic")])
211 (define_insn "sync_nandsi_insn"
212 [(set (match_operand:SI 0 "memory_operand" "+m")
214 [(not:SI (and:SI (match_dup 0)
215 (match_operand:SI 1 "reg_or_scst5_operand" "bIs5")))]
217 (clobber (match_scratch:SI 2 "=&B"))]
220 || ldw .d%U0t%U2 %0, %2\n\\
224 and .l2 %1, %2, %2 ; 5\n\\
225 1: not .l2 %2, %2 ; 6\n\\
226 stw .d%U0t%U2 %2, %0 ; 7\n\\
228 [(set_attr "type" "atomic")])
230 (define_insn "sync_old_nandsi_insn"
231 [(set (match_operand:SI 0 "register_operand" "=&b")
232 (match_operand:SI 1 "memory_operand" "+m"))
235 [(not:SI (and:SI (match_dup 1)
236 (match_operand:SI 2 "reg_or_scst5_operand" "bIs5")))]
238 (clobber (match_scratch:SI 3 "=&B"))]
241 || ldw .d%U1t%U0 %1, %0\n\\
245 and .l2 %2, %0, %3 ; 5\n\\
246 1: not .l2 %3, %3 ; 6\n\\
247 stw .d%U1t%U3 %3, %1 ; 7\n\\
249 [(set_attr "type" "atomic")])
251 (define_insn "sync_new_nandsi_insn"
252 [(set (match_operand:SI 0 "register_operand" "=&b")
253 (not:SI (and:SI (match_operand:SI 1 "memory_operand" "+m")
254 (match_operand:SI 2 "reg_or_scst5_operand" "bIs5"))))
257 [(not:SI (and:SI (match_dup 1) (match_dup 2)))]
259 (clobber (match_scratch:SI 3 "=&B"))]
262 || ldw .d%U1t%U0 %1, %0\n\\
266 and .l2 %2, %0, %0 ; 5\n\\
267 1: not .l2 %0, %0 ; 6\n\\
268 stw .d%U1t%U0 %0, %1 ; 7\n\\
270 [(set_attr "type" "atomic")])