OSDN Git Service

* config/alpha/predicates.md (aligned_memory_operand): Mark
[pf3gnuchains/gcc-fork.git] / gcc / config / alpha / sync.md
1 ;; GCC machine description for Alpha synchronization instructions.
2 ;; Copyright (C) 2005
3 ;; Free Software Foundation, Inc.
4 ;;
5 ;; This file is part of GCC.
6 ;;
7 ;; GCC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 2, or (at your option)
10 ;; any later version.
11 ;;
12 ;; GCC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ;; GNU General Public License for more details.
16 ;;
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING.  If not, write to
19 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
20 ;; Boston, MA 02110-1301, USA.
21
22 (define_code_macro FETCHOP [plus minus ior xor and])
23 (define_code_attr fetchop_name
24   [(plus "add") (minus "sub") (ior "ior") (xor "xor") (and "and")])
25 (define_code_attr fetchop_pred
26   [(plus "add_operand") (minus "reg_or_8bit_operand")
27    (ior "or_operand") (xor "or_operand") (and "and_operand")])
28 (define_code_attr fetchop_constr
29   [(plus "rKL") (minus "rI") (ior "rIN") (xor "rIN") (and "riNHM")])
30
31
32 (define_expand "memory_barrier"
33   [(set (mem:BLK (match_dup 0))
34         (unspec:BLK [(mem:BLK (match_dup 0))] UNSPEC_MB))]
35   ""
36 {
37   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (DImode));
38   MEM_VOLATILE_P (operands[0]) = 1;
39 })
40
41 (define_insn "*mb_internal"
42   [(set (match_operand:BLK 0 "" "")
43         (unspec:BLK [(match_operand:BLK 1 "" "")] UNSPEC_MB))]
44   ""
45   "mb"
46   [(set_attr "type" "mb")])
47
48 (define_insn "load_locked_<mode>"
49   [(set (match_operand:I48MODE 0 "register_operand" "=r")
50         (unspec_volatile:I48MODE
51           [(match_operand:I48MODE 1 "memory_operand" "m")]
52           UNSPECV_LL))]
53   ""
54   "ld<modesuffix>_l %0,%1"
55   [(set_attr "type" "ld_l")])
56
57 (define_insn "store_conditional_<mode>"
58   [(set (match_operand:DI 0 "register_operand" "=r")
59         (unspec_volatile:DI [(const_int 0)] UNSPECV_SC))
60    (set (match_operand:I48MODE 1 "memory_operand" "=m")
61         (match_operand:I48MODE 2 "reg_or_0_operand" "0"))]
62   ""
63   "st<modesuffix>_c %0,%1"
64   [(set_attr "type" "st_c")])
65
66 ;; The Alpha Architecture Handbook says that it is UNPREDICTABLE whether
67 ;; the lock is cleared by a TAKEN branch.  If we were to honor that, it
68 ;; would mean that we could not expand a ll/sc sequence until after the
69 ;; final basic-block reordering pass.  Fortunately, it appears that no
70 ;; Alpha implementation ever built actually clears the lock on branches,
71 ;; taken or not.
72
73 (define_insn_and_split "sync_<fetchop_name><mode>"
74   [(set (match_operand:I48MODE 0 "memory_operand" "+m")
75         (unspec:I48MODE
76           [(FETCHOP:I48MODE (match_dup 0)
77              (match_operand:I48MODE 1 "<fetchop_pred>" "<fetchop_constr>"))]
78           UNSPEC_ATOMIC))
79    (clobber (match_scratch:I48MODE 2 "=&r"))]
80   ""
81   "#"
82   "reload_completed"
83   [(const_int 0)]
84 {
85   alpha_split_atomic_op (<CODE>, operands[0], operands[1],
86                          NULL, NULL, operands[2]);
87   DONE;
88 }
89   [(set_attr "type" "multi")])
90
91 (define_insn_and_split "sync_nand<mode>"
92   [(set (match_operand:I48MODE 0 "memory_operand" "+m")
93         (unspec:I48MODE
94           [(and:I48MODE (not:I48MODE (match_dup 0))
95              (match_operand:I48MODE 1 "register_operand" "r"))]
96           UNSPEC_ATOMIC))
97    (clobber (match_scratch:I48MODE 2 "=&r"))]
98   ""
99   "#"
100   "reload_completed"
101   [(const_int 0)]
102 {
103   alpha_split_atomic_op (NOT, operands[0], operands[1],
104                          NULL, NULL, operands[2]);
105   DONE;
106 }
107   [(set_attr "type" "multi")])
108
109 (define_insn_and_split "sync_old_<fetchop_name><mode>"
110   [(set (match_operand:I48MODE 0 "register_operand" "=&r")
111         (match_operand:I48MODE 1 "memory_operand" "+m"))
112    (set (match_dup 1)
113         (unspec:I48MODE
114           [(FETCHOP:I48MODE (match_dup 1)
115              (match_operand:I48MODE 2 "<fetchop_pred>" "<fetchop_constr>"))]
116           UNSPEC_ATOMIC))
117    (clobber (match_scratch:I48MODE 3 "=&r"))]
118   ""
119   "#"
120   "reload_completed"
121   [(const_int 0)]
122 {
123   alpha_split_atomic_op (<CODE>, operands[1], operands[2],
124                          operands[0], NULL, operands[3]);
125   DONE;
126 }
127   [(set_attr "type" "multi")])
128
129 (define_insn_and_split "sync_old_nand<mode>"
130   [(set (match_operand:I48MODE 0 "register_operand" "=&r")
131         (match_operand:I48MODE 1 "memory_operand" "+m"))
132    (set (match_dup 1)
133         (unspec:I48MODE
134           [(and:I48MODE (not: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         (and:I48MODE 
173           (not: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           [(and:I48MODE (not: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")])