Fix PR target/63209.
[official-gcc.git] / gcc / config / c6x / sync.md
blobfff6c43944950958ac1f91ba2ede0fc3d5204468
1 ;; GCC machine description for C6X synchronization instructions.
2 ;; Copyright (C) 2011-2014 Free Software Foundation, Inc.
3 ;;
4 ;; This file is part of GCC.
5 ;;
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)
9 ;; any later version.
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")
39    (and "%2, %0")])
40 (define_code_attr fetchop_inops21
41   [(plus "%1, %2") (minus "%2, %1") (ior "%1, %2") (xor "%1, %2")
42    (and "%1, %2")])
44 (define_expand "sync_compare_and_swapsi"
45   [(parallel
46      [(set (match_operand:SI 0 "register_operand" "")
47            (match_operand:SI 1 "memory_operand" ""))
48       (set (match_dup 1)
49            (unspec_volatile:SI
50              [(match_operand:SI 2 "register_operand" "")
51               (match_operand:SI 3 "register_operand" "")]
52              UNSPECV_CAS))
53       (clobber (match_scratch:SI 4 ""))])]
54   ""
58 (define_expand "sync_<fetchop_name>si"
59   [(parallel
60     [(set (match_operand:SI 0 "memory_operand" "")
61           (unspec:SI
62            [(FETCHOP:SI (match_dup 0)
63                         (match_operand:SI 1 "<fetchop_pred>" ""))]
64            UNSPEC_ATOMIC))
65      (clobber (match_scratch:SI 2 ""))])]
66   ""
70 (define_expand "sync_old_<fetchop_name>si"
71   [(parallel
72     [(set (match_operand:SI 0 "register_operand" "")
73           (match_operand:SI 1 "memory_operand" ""))
74      (set (match_dup 1)
75           (unspec:SI
76            [(FETCHOP:SI (match_dup 1)
77                         (match_operand:SI 2 "<fetchop_pred>" ""))]
78            UNSPEC_ATOMIC))
79      (clobber (match_scratch:SI 3 ""))])]
80   ""
84 (define_expand "sync_new_<fetchop_name>si"
85   [(parallel
86     [(set (match_operand:SI 0 "register_operand" "")
87           (FETCHOP:SI (match_operand:SI 1 "memory_operand" "")
88                       (match_operand:SI 2 "<fetchop_pred>" "")))
89      (set (match_dup 1)
90           (unspec:SI [(FETCHOP:SI (match_dup 1) (match_dup 2))]
91                      UNSPEC_ATOMIC))
92      (clobber (match_scratch:SI 3 ""))])]
93   ""
97 (define_expand "sync_nandsi"
98   [(parallel
99     [(set (match_operand:SI 0 "memory_operand" "")
100           (unspec:SI
101            [(not:SI (and:SI (match_dup 0)
102                             (match_operand:SI 1 "reg_or_scst5_operand" "")))]
103            UNSPEC_ATOMIC))
104      (clobber (match_scratch:SI 2 ""))])]
105   ""
109 (define_expand "sync_old_nandsi"
110   [(parallel
111     [(set (match_operand:SI 0 "register_operand" "")
112           (match_operand:SI 1 "memory_operand" ""))
113      (set (match_dup 1)
114           (unspec:SI
115            [(not:SI (and:SI (match_dup 1)
116                     (match_operand:SI 2 "reg_or_scst5_operand" "")))]
117            UNSPEC_ATOMIC))
118      (clobber (match_scratch:SI 3 ""))])]
119   ""
123 (define_expand "sync_new_nandsi"
124   [(parallel
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" ""))))
128      (set (match_dup 1)
129           (unspec:SI [(not:SI (and:SI (match_dup 1) (match_dup 2)))]
130                      UNSPEC_ATOMIC))
131      (clobber (match_scratch:SI 3 ""))])]
132   ""
136 (define_insn "*sync_compare_and_swapsi"
137   [(set (match_operand:SI 0 "register_operand" "=&b")
138         (match_operand:SI 1 "memory_operand" "+m"))
139    (set (match_dup 1)
140         (unspec_volatile:SI
141           [(match_operand:SI 2 "register_operand" "B")
142            (match_operand:SI 3 "register_operand" "b")]
143           UNSPECV_CAS))
144    (clobber (match_scratch:SI 4 "=&B"))]
145   ""
146   "0: b .s2 1f ; 0\n\\
147    || ldw .d%U1t%U0 %1, %0\n\\
148    nop 4\n\\
149 || b .s2 2f ; 1\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")
157         (unspec:SI
158           [(FETCHOP:SI (match_dup 0)
159              (match_operand:SI 1 "<fetchop_pred>" "<fetchop_constr>"))]
160           UNSPEC_ATOMIC))
161    (clobber (match_scratch:SI 2 "=&B"))]
162   ""
163   "0: b .s2 1f ; 0\n\\
164 || ldw .d%U0t%U2 %0, %2\n\\
165    nop 4\n\\
166 || b .s2 2f ; 1\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"))
175    (set (match_dup 1)
176         (unspec:SI
177           [(FETCHOP:SI (match_dup 1)
178              (match_operand:SI 2 "<fetchop_pred>" "<fetchop_constr>"))]
179           UNSPEC_ATOMIC))
180    (clobber (match_scratch:SI 3 "=&B"))]
181   ""
182   "0: b .s2 1f ; 0\n\\
183 || ldw .d%U1t%U0 %1, %0\n\\
184    nop 4\n\\
185 || b .s2 2f ; 1\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>")))
195    (set (match_dup 1)
196         (unspec:SI
197           [(FETCHOP:SI (match_dup 1)
198                        (match_dup 2))]
199           UNSPEC_ATOMIC))
200    (clobber (match_scratch:SI 3 "=&B"))]
201   ""
202   "0: b .s2 1f ; 0\n\\
203 || ldw .d%U1t%U0 %1, %0\n\\
204    nop 4\n\\
205 || b .s2 2f ; 1\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")
213         (unspec:SI
214           [(not:SI (and:SI (match_dup 0)
215                            (match_operand:SI 1 "reg_or_scst5_operand" "bIs5")))]
216           UNSPEC_ATOMIC))
217    (clobber (match_scratch:SI 2 "=&B"))]
218   ""
219   "0: b .s2 1f ; 0\n\\
220 || ldw .d%U0t%U2 %0, %2\n\\
221    nop 1\n\\
222    nop 3\n\\
223 || b .s2 2f ; 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"))
233    (set (match_dup 1)
234         (unspec:SI
235           [(not:SI (and:SI (match_dup 1)
236                            (match_operand:SI 2 "reg_or_scst5_operand" "bIs5")))]
237           UNSPEC_ATOMIC))
238    (clobber (match_scratch:SI 3 "=&B"))]
239   ""
240   "0: b .s2 1f ; 0\n\\
241 || ldw .d%U1t%U0 %1, %0\n\\
242    nop 1\n\\
243    nop 3\n\\
244 || b .s2 2f ; 2\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"))))
255    (set (match_dup 1)
256         (unspec:SI
257           [(not:SI (and:SI (match_dup 1) (match_dup 2)))]
258           UNSPEC_ATOMIC))
259    (clobber (match_scratch:SI 3 "=&B"))]
260   ""
261   "0: b .s2 1f ; 0\n\\
262 || ldw .d%U1t%U0 %1, %0\n\\
263    nop 1\n\\
264    nop 3\n\\
265 || b .s2 2f ; 2\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")])