]>
Commit | Line | Data |
---|---|---|
5aa04b01 | 1 | ;; GCC machine description for C6X synchronization instructions. |
fbd26352 | 2 | ;; Copyright (C) 2011-2019 Free Software Foundation, Inc. |
5aa04b01 | 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. | |
10 | ;; | |
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. | |
15 | ;; | |
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/>. | |
19 | ||
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. | |
25 | ||
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")]) | |
43 | ||
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 | "" | |
55 | { | |
56 | }) | |
57 | ||
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 | "" | |
67 | { | |
68 | }) | |
69 | ||
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 | "" | |
81 | { | |
82 | }) | |
83 | ||
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 | "" | |
94 | { | |
95 | }) | |
96 | ||
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 | "" | |
106 | { | |
107 | }) | |
108 | ||
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 | "" | |
120 | { | |
121 | }) | |
122 | ||
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 | "" | |
133 | { | |
134 | }) | |
135 | ||
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\\ | |
152 | 2:" | |
153 | [(set_attr "type" "atomic")]) | |
154 | ||
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\\ | |
169 | 2:" | |
170 | [(set_attr "type" "atomic")]) | |
171 | ||
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\\ | |
188 | 2:" | |
189 | [(set_attr "type" "atomic")]) | |
190 | ||
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\\ | |
208 | 2:" | |
209 | [(set_attr "type" "atomic")]) | |
210 | ||
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\\ | |
227 | 2:" | |
228 | [(set_attr "type" "atomic")]) | |
229 | ||
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\\ | |
248 | 2:" | |
249 | [(set_attr "type" "atomic")]) | |
250 | ||
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\\ | |
269 | 2:" | |
270 | [(set_attr "type" "atomic")]) |