Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/alpha/sync.md @ 0:a06113de4d67
first commit
author | kent <kent@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 17 Jul 2009 14:47:48 +0900 |
parents | |
children | 855418dad1a3 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:a06113de4d67 |
---|---|
1 ;; GCC machine description for Alpha synchronization instructions. | |
2 ;; Copyright (C) 2005, 2007, 2008, 2009 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. | |
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 (define_code_iterator FETCHOP [plus minus ior xor and]) | |
21 (define_code_attr fetchop_name | |
22 [(plus "add") (minus "sub") (ior "ior") (xor "xor") (and "and")]) | |
23 (define_code_attr fetchop_pred | |
24 [(plus "add_operand") (minus "reg_or_8bit_operand") | |
25 (ior "or_operand") (xor "or_operand") (and "and_operand")]) | |
26 (define_code_attr fetchop_constr | |
27 [(plus "rKL") (minus "rI") (ior "rIN") (xor "rIN") (and "riNHM")]) | |
28 | |
29 | |
30 (define_expand "memory_barrier" | |
31 [(set (match_dup 0) | |
32 (unspec:BLK [(match_dup 0)] UNSPEC_MB))] | |
33 "" | |
34 { | |
35 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); | |
36 MEM_VOLATILE_P (operands[0]) = 1; | |
37 }) | |
38 | |
39 (define_insn "*memory_barrier" | |
40 [(set (match_operand:BLK 0 "" "") | |
41 (unspec:BLK [(match_dup 0)] UNSPEC_MB))] | |
42 "" | |
43 "mb" | |
44 [(set_attr "type" "mb")]) | |
45 | |
46 (define_insn "load_locked_<mode>" | |
47 [(set (match_operand:I48MODE 0 "register_operand" "=r") | |
48 (unspec_volatile:I48MODE | |
49 [(match_operand:I48MODE 1 "memory_operand" "m")] | |
50 UNSPECV_LL))] | |
51 "" | |
52 "ld<modesuffix>_l %0,%1" | |
53 [(set_attr "type" "ld_l")]) | |
54 | |
55 (define_insn "store_conditional_<mode>" | |
56 [(set (match_operand:DI 0 "register_operand" "=r") | |
57 (unspec_volatile:DI [(const_int 0)] UNSPECV_SC)) | |
58 (set (match_operand:I48MODE 1 "memory_operand" "=m") | |
59 (match_operand:I48MODE 2 "reg_or_0_operand" "0"))] | |
60 "" | |
61 "st<modesuffix>_c %0,%1" | |
62 [(set_attr "type" "st_c")]) | |
63 | |
64 ;; The Alpha Architecture Handbook says that it is UNPREDICTABLE whether | |
65 ;; the lock is cleared by a TAKEN branch. If we were to honor that, it | |
66 ;; would mean that we could not expand a ll/sc sequence until after the | |
67 ;; final basic-block reordering pass. Fortunately, it appears that no | |
68 ;; Alpha implementation ever built actually clears the lock on branches, | |
69 ;; taken or not. | |
70 | |
71 (define_insn_and_split "sync_<fetchop_name><mode>" | |
72 [(set (match_operand:I48MODE 0 "memory_operand" "+m") | |
73 (unspec:I48MODE | |
74 [(FETCHOP:I48MODE (match_dup 0) | |
75 (match_operand:I48MODE 1 "<fetchop_pred>" "<fetchop_constr>"))] | |
76 UNSPEC_ATOMIC)) | |
77 (clobber (match_scratch:I48MODE 2 "=&r"))] | |
78 "" | |
79 "#" | |
80 "reload_completed" | |
81 [(const_int 0)] | |
82 { | |
83 alpha_split_atomic_op (<CODE>, operands[0], operands[1], | |
84 NULL, NULL, operands[2]); | |
85 DONE; | |
86 } | |
87 [(set_attr "type" "multi")]) | |
88 | |
89 (define_insn_and_split "sync_nand<mode>" | |
90 [(set (match_operand:I48MODE 0 "memory_operand" "+m") | |
91 (unspec:I48MODE | |
92 [(not:I48MODE | |
93 (and:I48MODE (match_dup 0) | |
94 (match_operand:I48MODE 1 "register_operand" "r")))] | |
95 UNSPEC_ATOMIC)) | |
96 (clobber (match_scratch:I48MODE 2 "=&r"))] | |
97 "" | |
98 "#" | |
99 "reload_completed" | |
100 [(const_int 0)] | |
101 { | |
102 alpha_split_atomic_op (NOT, operands[0], operands[1], | |
103 NULL, NULL, operands[2]); | |
104 DONE; | |
105 } | |
106 [(set_attr "type" "multi")]) | |
107 | |
108 (define_insn_and_split "sync_old_<fetchop_name><mode>" | |
109 [(set (match_operand:I48MODE 0 "register_operand" "=&r") | |
110 (match_operand:I48MODE 1 "memory_operand" "+m")) | |
111 (set (match_dup 1) | |
112 (unspec:I48MODE | |
113 [(FETCHOP:I48MODE (match_dup 1) | |
114 (match_operand:I48MODE 2 "<fetchop_pred>" "<fetchop_constr>"))] | |
115 UNSPEC_ATOMIC)) | |
116 (clobber (match_scratch:I48MODE 3 "=&r"))] | |
117 "" | |
118 "#" | |
119 "reload_completed" | |
120 [(const_int 0)] | |
121 { | |
122 alpha_split_atomic_op (<CODE>, operands[1], operands[2], | |
123 operands[0], NULL, operands[3]); | |
124 DONE; | |
125 } | |
126 [(set_attr "type" "multi")]) | |
127 | |
128 (define_insn_and_split "sync_old_nand<mode>" | |
129 [(set (match_operand:I48MODE 0 "register_operand" "=&r") | |
130 (match_operand:I48MODE 1 "memory_operand" "+m")) | |
131 (set (match_dup 1) | |
132 (unspec:I48MODE | |
133 [(not:I48MODE | |
134 (and:I48MODE (match_dup 1) | |
135 (match_operand:I48MODE 2 "register_operand" "r")))] | |
136 UNSPEC_ATOMIC)) | |
137 (clobber (match_scratch:I48MODE 3 "=&r"))] | |
138 "" | |
139 "#" | |
140 "reload_completed" | |
141 [(const_int 0)] | |
142 { | |
143 alpha_split_atomic_op (NOT, operands[1], operands[2], | |
144 operands[0], NULL, operands[3]); | |
145 DONE; | |
146 } | |
147 [(set_attr "type" "multi")]) | |
148 | |
149 (define_insn_and_split "sync_new_<fetchop_name><mode>" | |
150 [(set (match_operand:I48MODE 0 "register_operand" "=&r") | |
151 (FETCHOP:I48MODE | |
152 (match_operand:I48MODE 1 "memory_operand" "+m") | |
153 (match_operand:I48MODE 2 "<fetchop_pred>" "<fetchop_constr>"))) | |
154 (set (match_dup 1) | |
155 (unspec:I48MODE | |
156 [(FETCHOP:I48MODE (match_dup 1) (match_dup 2))] | |
157 UNSPEC_ATOMIC)) | |
158 (clobber (match_scratch:I48MODE 3 "=&r"))] | |
159 "" | |
160 "#" | |
161 "reload_completed" | |
162 [(const_int 0)] | |
163 { | |
164 alpha_split_atomic_op (<CODE>, operands[1], operands[2], | |
165 NULL, operands[0], operands[3]); | |
166 DONE; | |
167 } | |
168 [(set_attr "type" "multi")]) | |
169 | |
170 (define_insn_and_split "sync_new_nand<mode>" | |
171 [(set (match_operand:I48MODE 0 "register_operand" "=&r") | |
172 (not:I48MODE | |
173 (and:I48MODE (match_operand:I48MODE 1 "memory_operand" "+m") | |
174 (match_operand:I48MODE 2 "register_operand" "r")))) | |
175 (set (match_dup 1) | |
176 (unspec:I48MODE | |
177 [(not:I48MODE (and:I48MODE (match_dup 1) (match_dup 2)))] | |
178 UNSPEC_ATOMIC)) | |
179 (clobber (match_scratch:I48MODE 3 "=&r"))] | |
180 "" | |
181 "#" | |
182 "reload_completed" | |
183 [(const_int 0)] | |
184 { | |
185 alpha_split_atomic_op (NOT, operands[1], operands[2], | |
186 NULL, operands[0], operands[3]); | |
187 DONE; | |
188 } | |
189 [(set_attr "type" "multi")]) | |
190 | |
191 (define_expand "sync_compare_and_swap<mode>" | |
192 [(match_operand:I12MODE 0 "register_operand" "") | |
193 (match_operand:I12MODE 1 "memory_operand" "") | |
194 (match_operand:I12MODE 2 "register_operand" "") | |
195 (match_operand:I12MODE 3 "add_operand" "")] | |
196 "" | |
197 { | |
198 alpha_expand_compare_and_swap_12 (operands[0], operands[1], | |
199 operands[2], operands[3]); | |
200 DONE; | |
201 }) | |
202 | |
203 (define_insn_and_split "sync_compare_and_swap<mode>_1" | |
204 [(set (match_operand:DI 0 "register_operand" "=&r,&r") | |
205 (zero_extend:DI | |
206 (mem:I12MODE (match_operand:DI 1 "register_operand" "r,r")))) | |
207 (set (mem:I12MODE (match_dup 1)) | |
208 (unspec:I12MODE | |
209 [(match_operand:DI 2 "reg_or_8bit_operand" "J,rI") | |
210 (match_operand:DI 3 "register_operand" "r,r") | |
211 (match_operand:DI 4 "register_operand" "r,r")] | |
212 UNSPEC_CMPXCHG)) | |
213 (clobber (match_scratch:DI 5 "=&r,&r")) | |
214 (clobber (match_scratch:DI 6 "=X,&r"))] | |
215 "" | |
216 "#" | |
217 "reload_completed" | |
218 [(const_int 0)] | |
219 { | |
220 alpha_split_compare_and_swap_12 (<MODE>mode, operands[0], operands[1], | |
221 operands[2], operands[3], operands[4], | |
222 operands[5], operands[6]); | |
223 DONE; | |
224 } | |
225 [(set_attr "type" "multi")]) | |
226 | |
227 (define_expand "sync_compare_and_swap<mode>" | |
228 [(parallel | |
229 [(set (match_operand:I48MODE 0 "register_operand" "") | |
230 (match_operand:I48MODE 1 "memory_operand" "")) | |
231 (set (match_dup 1) | |
232 (unspec:I48MODE | |
233 [(match_operand:I48MODE 2 "reg_or_8bit_operand" "") | |
234 (match_operand:I48MODE 3 "add_operand" "rKL")] | |
235 UNSPEC_CMPXCHG)) | |
236 (clobber (match_scratch:I48MODE 4 "=&r"))])] | |
237 "" | |
238 { | |
239 if (<MODE>mode == SImode) | |
240 operands[2] = convert_modes (DImode, SImode, operands[2], 0); | |
241 }) | |
242 | |
243 (define_insn_and_split "*sync_compare_and_swap<mode>" | |
244 [(set (match_operand:I48MODE 0 "register_operand" "=&r") | |
245 (match_operand:I48MODE 1 "memory_operand" "+m")) | |
246 (set (match_dup 1) | |
247 (unspec:I48MODE | |
248 [(match_operand:DI 2 "reg_or_8bit_operand" "rI") | |
249 (match_operand:I48MODE 3 "add_operand" "rKL")] | |
250 UNSPEC_CMPXCHG)) | |
251 (clobber (match_scratch:I48MODE 4 "=&r"))] | |
252 "" | |
253 "#" | |
254 "reload_completed" | |
255 [(const_int 0)] | |
256 { | |
257 alpha_split_compare_and_swap (operands[0], operands[1], operands[2], | |
258 operands[3], operands[4]); | |
259 DONE; | |
260 } | |
261 [(set_attr "type" "multi")]) | |
262 | |
263 (define_expand "sync_lock_test_and_set<mode>" | |
264 [(match_operand:I12MODE 0 "register_operand" "") | |
265 (match_operand:I12MODE 1 "memory_operand" "") | |
266 (match_operand:I12MODE 2 "register_operand" "")] | |
267 "" | |
268 { | |
269 alpha_expand_lock_test_and_set_12 (operands[0], operands[1], operands[2]); | |
270 DONE; | |
271 }) | |
272 | |
273 (define_insn_and_split "sync_lock_test_and_set<mode>_1" | |
274 [(set (match_operand:DI 0 "register_operand" "=&r") | |
275 (zero_extend:DI | |
276 (mem:I12MODE (match_operand:DI 1 "register_operand" "r")))) | |
277 (set (mem:I12MODE (match_dup 1)) | |
278 (unspec:I12MODE | |
279 [(match_operand:DI 2 "reg_or_8bit_operand" "rI") | |
280 (match_operand:DI 3 "register_operand" "r")] | |
281 UNSPEC_XCHG)) | |
282 (clobber (match_scratch:DI 4 "=&r"))] | |
283 "" | |
284 "#" | |
285 "reload_completed" | |
286 [(const_int 0)] | |
287 { | |
288 alpha_split_lock_test_and_set_12 (<MODE>mode, operands[0], operands[1], | |
289 operands[2], operands[3], operands[4]); | |
290 DONE; | |
291 } | |
292 [(set_attr "type" "multi")]) | |
293 | |
294 (define_insn_and_split "sync_lock_test_and_set<mode>" | |
295 [(set (match_operand:I48MODE 0 "register_operand" "=&r") | |
296 (match_operand:I48MODE 1 "memory_operand" "+m")) | |
297 (set (match_dup 1) | |
298 (unspec:I48MODE | |
299 [(match_operand:I48MODE 2 "add_operand" "rKL")] | |
300 UNSPEC_XCHG)) | |
301 (clobber (match_scratch:I48MODE 3 "=&r"))] | |
302 "" | |
303 "#" | |
304 "reload_completed" | |
305 [(const_int 0)] | |
306 { | |
307 alpha_split_lock_test_and_set (operands[0], operands[1], | |
308 operands[2], operands[3]); | |
309 DONE; | |
310 } | |
311 [(set_attr "type" "multi")]) |