OSDN Git Service

Add NIOS2 support. Code from SourceyG++.
[pf3gnuchains/gcc-fork.git] / gcc / config / alpha / sync.md
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.  This means that we can not
66 ;; expand a ll/sc sequence until after the final basic-block reordering pass.
67
68 (define_insn_and_split "sync_<fetchop_name><mode>"
69   [(set (match_operand:I48MODE 0 "memory_operand" "+m")
70         (unspec:I48MODE
71           [(FETCHOP:I48MODE (match_dup 0)
72              (match_operand:I48MODE 1 "<fetchop_pred>" "<fetchop_constr>"))]
73           UNSPEC_ATOMIC))
74    (clobber (match_scratch:I48MODE 2 "=&r"))]
75   ""
76   "#"
77   "epilogue_completed"
78   [(const_int 0)]
79 {
80   alpha_split_atomic_op (<CODE>, operands[0], operands[1],
81                          NULL, NULL, operands[2]);
82   DONE;
83 }
84   [(set_attr "type" "multi")])
85
86 (define_insn_and_split "sync_nand<mode>"
87   [(set (match_operand:I48MODE 0 "memory_operand" "+m")
88         (unspec:I48MODE
89           [(not:I48MODE
90              (and:I48MODE (match_dup 0)
91                (match_operand:I48MODE 1 "register_operand" "r")))]
92           UNSPEC_ATOMIC))
93    (clobber (match_scratch:I48MODE 2 "=&r"))]
94   ""
95   "#"
96   "epilogue_completed"
97   [(const_int 0)]
98 {
99   alpha_split_atomic_op (NOT, operands[0], operands[1],
100                          NULL, NULL, operands[2]);
101   DONE;
102 }
103   [(set_attr "type" "multi")])
104
105 (define_insn_and_split "sync_old_<fetchop_name><mode>"
106   [(set (match_operand:I48MODE 0 "register_operand" "=&r")
107         (match_operand:I48MODE 1 "memory_operand" "+m"))
108    (set (match_dup 1)
109         (unspec:I48MODE
110           [(FETCHOP:I48MODE (match_dup 1)
111              (match_operand:I48MODE 2 "<fetchop_pred>" "<fetchop_constr>"))]
112           UNSPEC_ATOMIC))
113    (clobber (match_scratch:I48MODE 3 "=&r"))]
114   ""
115   "#"
116   "epilogue_completed"
117   [(const_int 0)]
118 {
119   alpha_split_atomic_op (<CODE>, operands[1], operands[2],
120                          operands[0], NULL, operands[3]);
121   DONE;
122 }
123   [(set_attr "type" "multi")])
124
125 (define_insn_and_split "sync_old_nand<mode>"
126   [(set (match_operand:I48MODE 0 "register_operand" "=&r")
127         (match_operand:I48MODE 1 "memory_operand" "+m"))
128    (set (match_dup 1)
129         (unspec:I48MODE
130           [(not:I48MODE
131              (and:I48MODE (match_dup 1)
132                (match_operand:I48MODE 2 "register_operand" "r")))]
133           UNSPEC_ATOMIC))
134    (clobber (match_scratch:I48MODE 3 "=&r"))]
135   ""
136   "#"
137   "epilogue_completed"
138   [(const_int 0)]
139 {
140   alpha_split_atomic_op (NOT, operands[1], operands[2],
141                          operands[0], NULL, operands[3]);
142   DONE;
143 }
144   [(set_attr "type" "multi")])
145
146 (define_insn_and_split "sync_new_<fetchop_name><mode>"
147   [(set (match_operand:I48MODE 0 "register_operand" "=&r")
148         (FETCHOP:I48MODE 
149           (match_operand:I48MODE 1 "memory_operand" "+m")
150           (match_operand:I48MODE 2 "<fetchop_pred>" "<fetchop_constr>")))
151    (set (match_dup 1)
152         (unspec:I48MODE
153           [(FETCHOP:I48MODE (match_dup 1) (match_dup 2))]
154           UNSPEC_ATOMIC))
155    (clobber (match_scratch:I48MODE 3 "=&r"))]
156   ""
157   "#"
158   "epilogue_completed"
159   [(const_int 0)]
160 {
161   alpha_split_atomic_op (<CODE>, operands[1], operands[2],
162                          NULL, operands[0], operands[3]);
163   DONE;
164 }
165   [(set_attr "type" "multi")])
166
167 (define_insn_and_split "sync_new_nand<mode>"
168   [(set (match_operand:I48MODE 0 "register_operand" "=&r")
169         (not:I48MODE
170           (and:I48MODE (match_operand:I48MODE 1 "memory_operand" "+m")
171             (match_operand:I48MODE 2 "register_operand" "r"))))
172    (set (match_dup 1)
173         (unspec:I48MODE
174           [(not:I48MODE (and:I48MODE (match_dup 1) (match_dup 2)))]
175           UNSPEC_ATOMIC))
176    (clobber (match_scratch:I48MODE 3 "=&r"))]
177   ""
178   "#"
179   "epilogue_completed"
180   [(const_int 0)]
181 {
182   alpha_split_atomic_op (NOT, operands[1], operands[2],
183                          NULL, operands[0], operands[3]);
184   DONE;
185 }
186   [(set_attr "type" "multi")])
187
188 (define_expand "sync_compare_and_swap<mode>"
189   [(match_operand:I12MODE 0 "register_operand" "")
190    (match_operand:I12MODE 1 "memory_operand" "")
191    (match_operand:I12MODE 2 "register_operand" "")
192    (match_operand:I12MODE 3 "add_operand" "")]
193   ""
194 {
195   alpha_expand_compare_and_swap_12 (operands[0], operands[1],
196                                     operands[2], operands[3]);
197   DONE;
198 })
199
200 (define_insn_and_split "sync_compare_and_swap<mode>_1"
201   [(set (match_operand:DI 0 "register_operand" "=&r,&r")
202         (zero_extend:DI
203           (mem:I12MODE (match_operand:DI 1 "register_operand" "r,r"))))
204    (set (mem:I12MODE (match_dup 1))
205         (unspec:I12MODE
206           [(match_operand:DI 2 "reg_or_8bit_operand" "J,rI")
207            (match_operand:DI 3 "register_operand" "r,r")
208            (match_operand:DI 4 "register_operand" "r,r")]
209           UNSPEC_CMPXCHG))
210    (clobber (match_scratch:DI 5 "=&r,&r"))
211    (clobber (match_scratch:DI 6 "=X,&r"))]
212   ""
213   "#"
214   "epilogue_completed"
215   [(const_int 0)]
216 {
217   alpha_split_compare_and_swap_12 (<MODE>mode, operands[0], operands[1],
218                                    operands[2], operands[3], operands[4],
219                                    operands[5], operands[6]);
220   DONE;
221 }
222   [(set_attr "type" "multi")])
223
224 (define_expand "sync_compare_and_swap<mode>"
225   [(parallel
226      [(set (match_operand:I48MODE 0 "register_operand" "")
227            (match_operand:I48MODE 1 "memory_operand" ""))
228       (set (match_dup 1)
229            (unspec:I48MODE
230              [(match_operand:I48MODE 2 "reg_or_8bit_operand" "")
231               (match_operand:I48MODE 3 "add_operand" "rKL")]
232              UNSPEC_CMPXCHG))
233       (clobber (match_scratch:I48MODE 4 "=&r"))])]
234   ""
235 {
236   if (<MODE>mode == SImode)
237     operands[2] = convert_modes (DImode, SImode, operands[2], 0);
238 })
239
240 (define_insn_and_split "*sync_compare_and_swap<mode>"
241   [(set (match_operand:I48MODE 0 "register_operand" "=&r")
242         (match_operand:I48MODE 1 "memory_operand" "+m"))
243    (set (match_dup 1)
244         (unspec:I48MODE
245           [(match_operand:DI 2 "reg_or_8bit_operand" "rI")
246            (match_operand:I48MODE 3 "add_operand" "rKL")]
247           UNSPEC_CMPXCHG))
248    (clobber (match_scratch:I48MODE 4 "=&r"))]
249   ""
250   "#"
251   "epilogue_completed"
252   [(const_int 0)]
253 {
254   alpha_split_compare_and_swap (operands[0], operands[1], operands[2],
255                                 operands[3], operands[4]);
256   DONE;
257 }
258   [(set_attr "type" "multi")])
259
260 (define_expand "sync_lock_test_and_set<mode>"
261   [(match_operand:I12MODE 0 "register_operand" "")
262    (match_operand:I12MODE 1 "memory_operand" "")
263    (match_operand:I12MODE 2 "register_operand" "")]
264   ""
265 {
266   alpha_expand_lock_test_and_set_12 (operands[0], operands[1], operands[2]);
267   DONE;
268 })
269
270 (define_insn_and_split "sync_lock_test_and_set<mode>_1"
271   [(set (match_operand:DI 0 "register_operand" "=&r")
272         (zero_extend:DI
273           (mem:I12MODE (match_operand:DI 1 "register_operand" "r"))))
274    (set (mem:I12MODE (match_dup 1))
275         (unspec:I12MODE
276           [(match_operand:DI 2 "reg_or_8bit_operand" "rI")
277            (match_operand:DI 3 "register_operand" "r")]
278           UNSPEC_XCHG))
279    (clobber (match_scratch:DI 4 "=&r"))]
280   ""
281   "#"
282   "epilogue_completed"
283   [(const_int 0)]
284 {
285   alpha_split_lock_test_and_set_12 (<MODE>mode, operands[0], operands[1],
286                                     operands[2], operands[3], operands[4]);
287   DONE;
288 }
289   [(set_attr "type" "multi")])
290
291 (define_insn_and_split "sync_lock_test_and_set<mode>"
292   [(set (match_operand:I48MODE 0 "register_operand" "=&r")
293         (match_operand:I48MODE 1 "memory_operand" "+m"))
294    (set (match_dup 1)
295         (unspec:I48MODE
296           [(match_operand:I48MODE 2 "add_operand" "rKL")]
297           UNSPEC_XCHG))
298    (clobber (match_scratch:I48MODE 3 "=&r"))]
299   ""
300   "#"
301   "epilogue_completed"
302   [(const_int 0)]
303 {
304   alpha_split_lock_test_and_set (operands[0], operands[1],
305                                  operands[2], operands[3]);
306   DONE;
307 }
308   [(set_attr "type" "multi")])