OSDN Git Service

* config/alpha/sync.md (fetchop_name): Change ior attribute to "or".
[pf3gnuchains/gcc-fork.git] / gcc / config / alpha / sync.md
1 ;; GCC machine description for Alpha synchronization instructions.
2 ;; Copyright (C) 2005, 2007, 2008, 2009, 2011 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 "or") (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 normal load or store.  This means we cannot
66 ;; expand a ll/sc sequence before reload, lest a register spill is
67 ;; inserted inside the sequence.  It is also UNPREDICTABLE whether the
68 ;; lock is cleared by a TAKEN branch.  This means that we can not expand
69 ;; a ll/sc sequence containing a branch (i.e. compare-and-swap) until after
70 ;; the final basic-block reordering pass.
71
72 (define_expand "atomic_compare_and_swap<mode>"
73   [(parallel
74      [(set (match_operand:DI 0 "register_operand" "")             ;; bool out
75            (unspec_volatile:DI [(const_int 0)] UNSPECV_CMPXCHG))
76       (set (match_operand:I48MODE 1 "register_operand" "")        ;; val out
77            (unspec_volatile:I48MODE [(const_int 0)] UNSPECV_CMPXCHG))
78       (set (match_operand:I48MODE 2 "memory_operand" "")          ;; memory
79            (unspec_volatile:I48MODE
80              [(match_dup 2)
81               (match_operand:I48MODE 3 "reg_or_8bit_operand" "")  ;; expected
82               (match_operand:I48MODE 4 "add_operand" "")          ;; desired
83               (match_operand:SI 5 "const_int_operand" "")         ;; is_weak
84               (match_operand:SI 6 "const_int_operand" "")         ;; succ model
85               (match_operand:SI 7 "const_int_operand" "")]        ;; fail model
86              UNSPECV_CMPXCHG))])]
87   ""
88 {
89   if (<MODE>mode == SImode)
90     {
91       operands[3] = convert_modes (DImode, SImode, operands[3], 0);
92       operands[4] = convert_modes (DImode, SImode, operands[4], 0);
93     }
94 })
95
96 (define_insn_and_split "*atomic_compare_and_swap<mode>"
97   [(set (match_operand:DI 0 "register_operand" "=&r")           ;; bool out
98         (unspec_volatile:DI [(const_int 0)] UNSPECV_CMPXCHG))
99    (set (match_operand:I48MODE 1 "register_operand" "=&r")      ;; val out
100         (unspec_volatile:I48MODE [(const_int 0)] UNSPECV_CMPXCHG))
101    (set (match_operand:I48MODE 2 "memory_operand" "+m")         ;; memory
102         (unspec_volatile:I48MODE
103           [(match_dup 2)
104            (match_operand:DI 3 "reg_or_8bit_operand" "rI")      ;; expected
105            (match_operand:DI 4 "add_operand" "rKL")             ;; desired
106            (match_operand:SI 5 "const_int_operand" "")          ;; is_weak
107            (match_operand:SI 6 "const_int_operand" "")          ;; succ model
108            (match_operand:SI 7 "const_int_operand" "")]         ;; fail model
109           UNSPECV_CMPXCHG))]
110   ""
111   "#"
112   "epilogue_completed"
113   [(const_int 0)]
114 {
115   alpha_split_compare_and_swap (operands);
116   DONE;
117 }
118   [(set_attr "type" "multi")])
119
120 (define_expand "atomic_compare_and_swap<mode>"
121   [(match_operand:DI 0 "register_operand" "")                   ;; bool out
122    (match_operand:I12MODE 1 "register_operand" "")              ;; val out
123    (match_operand:I12MODE 2 "mem_noofs_operand" "")             ;; memory
124    (match_operand:I12MODE 3 "register_operand" "")              ;; expected
125    (match_operand:I12MODE 4 "add_operand" "")                   ;; desired
126    (match_operand:SI 5 "const_int_operand" "")                  ;; is_weak
127    (match_operand:SI 6 "const_int_operand" "")                  ;; succ model
128    (match_operand:SI 7 "const_int_operand" "")]                 ;; fail model
129   ""
130 {
131   alpha_expand_compare_and_swap_12 (operands);
132   DONE;
133 })
134
135 (define_insn_and_split "atomic_compare_and_swap<mode>_1"
136   [(set (match_operand:DI 0 "register_operand" "=&r")           ;; bool out
137         (unspec_volatile:DI [(const_int 0)] UNSPECV_CMPXCHG))
138    (set (match_operand:DI 1 "register_operand" "=&r")           ;; val out
139         (zero_extend:DI
140           (unspec_volatile:I12MODE [(const_int 0)] UNSPECV_CMPXCHG)))
141    (set (match_operand:I12MODE 2 "mem_noofs_operand" "+w")      ;; memory
142         (unspec_volatile:I12MODE
143           [(match_dup 2)
144            (match_operand:DI 3 "reg_or_8bit_operand" "rI")      ;; expected
145            (match_operand:DI 4 "reg_or_0_operand" "rJ")         ;; desired
146            (match_operand:DI 5 "register_operand" "r")          ;; align
147            (match_operand:SI 6 "const_int_operand" "")          ;; is_weak
148            (match_operand:SI 7 "const_int_operand" "")          ;; succ model
149            (match_operand:SI 8 "const_int_operand" "")]         ;; fail model
150           UNSPECV_CMPXCHG))
151    (clobber (match_scratch:DI 9 "=&r"))]
152   ""
153   "#"
154   "epilogue_completed"
155   [(const_int 0)]
156 {
157   alpha_split_compare_and_swap_12 (operands);
158   DONE;
159 }
160   [(set_attr "type" "multi")])
161
162 (define_insn_and_split "atomic_exchange<mode>"
163   [(set (match_operand:I48MODE 0 "register_operand" "=&r")      ;; output
164         (match_operand:I48MODE 1 "memory_operand" "+m"))        ;; memory
165    (set (match_dup 1)
166         (unspec:I48MODE
167           [(match_operand:I48MODE 2 "add_operand" "rKL")        ;; input
168            (match_operand:SI 3 "const_int_operand" "")]         ;; model
169           UNSPEC_XCHG))
170    (clobber (match_scratch:I48MODE 4 "=&r"))]
171   ""
172   "#"
173   "epilogue_completed"
174   [(const_int 0)]
175 {
176   alpha_split_atomic_exchange (operands);
177   DONE;
178 }
179   [(set_attr "type" "multi")])
180
181 (define_expand "atomic_exchange<mode>"
182   [(match_operand:I12MODE 0 "register_operand" "")              ;; output
183    (match_operand:I12MODE 1 "mem_noofs_operand" "")             ;; memory
184    (match_operand:I12MODE 2 "reg_or_0_operand" "")              ;; input
185    (match_operand:SI 3 "const_int_operand" "")]                 ;; model
186   ""
187 {
188   alpha_expand_atomic_exchange_12 (operands);
189   DONE;
190 })
191
192 (define_insn_and_split "atomic_exchange<mode>_1"
193   [(set (match_operand:DI 0 "register_operand" "=&r")           ;; output
194         (zero_extend:DI
195           (match_operand:I12MODE 1 "mem_noofs_operand" "+w")))  ;; memory
196    (set (match_dup 1)
197         (unspec:I12MODE
198           [(match_operand:DI 2 "reg_or_8bit_operand" "rI")      ;; input
199            (match_operand:DI 3 "register_operand" "r")          ;; align
200            (match_operand:SI 4 "const_int_operand" "")]         ;; model
201           UNSPEC_XCHG))
202    (clobber (match_scratch:DI 5 "=&r"))]
203   ""
204   "#"
205   "epilogue_completed"
206   [(const_int 0)]
207 {
208   alpha_split_atomic_exchange_12 (operands);
209   DONE;
210 }
211   [(set_attr "type" "multi")])
212
213 (define_insn_and_split "atomic_<fetchop_name><mode>"
214   [(set (match_operand:I48MODE 0 "memory_operand" "+m")
215         (unspec:I48MODE
216           [(FETCHOP:I48MODE (match_dup 0)
217              (match_operand:I48MODE 1 "<fetchop_pred>" "<fetchop_constr>"))
218            (match_operand:SI 2 "const_int_operand" "")]
219           UNSPEC_ATOMIC))
220    (clobber (match_scratch:I48MODE 3 "=&r"))]
221   ""
222   "#"
223   "epilogue_completed"
224   [(const_int 0)]
225 {
226   alpha_split_atomic_op (<CODE>, operands[0], operands[1],
227                          NULL, NULL, operands[3],
228                          (enum memmodel) INTVAL (operands[2]));
229   DONE;
230 }
231   [(set_attr "type" "multi")])
232
233 (define_insn_and_split "atomic_nand<mode>"
234   [(set (match_operand:I48MODE 0 "memory_operand" "+m")
235         (unspec:I48MODE
236           [(not:I48MODE
237              (and:I48MODE (match_dup 0)
238                (match_operand:I48MODE 1 "register_operand" "r")))
239            (match_operand:SI 2 "const_int_operand" "")]
240           UNSPEC_ATOMIC))
241    (clobber (match_scratch:I48MODE 3 "=&r"))]
242   ""
243   "#"
244   "epilogue_completed"
245   [(const_int 0)]
246 {
247   alpha_split_atomic_op (NOT, operands[0], operands[1],
248                          NULL, NULL, operands[3],
249                          (enum memmodel) INTVAL (operands[2]));
250   DONE;
251 }
252   [(set_attr "type" "multi")])
253
254 (define_insn_and_split "atomic_fetch_<fetchop_name><mode>"
255   [(set (match_operand:I48MODE 0 "register_operand" "=&r")
256         (match_operand:I48MODE 1 "memory_operand" "+m"))
257    (set (match_dup 1)
258         (unspec:I48MODE
259           [(FETCHOP:I48MODE (match_dup 1)
260              (match_operand:I48MODE 2 "<fetchop_pred>" "<fetchop_constr>"))
261            (match_operand:SI 3 "const_int_operand" "")]
262           UNSPEC_ATOMIC))
263    (clobber (match_scratch:I48MODE 4 "=&r"))]
264   ""
265   "#"
266   "epilogue_completed"
267   [(const_int 0)]
268 {
269   alpha_split_atomic_op (<CODE>, operands[1], operands[2],
270                          operands[0], NULL, operands[4],
271                          (enum memmodel) INTVAL (operands[3]));
272   DONE;
273 }
274   [(set_attr "type" "multi")])
275
276 (define_insn_and_split "atomic_fetch_nand<mode>"
277   [(set (match_operand:I48MODE 0 "register_operand" "=&r")
278         (match_operand:I48MODE 1 "memory_operand" "+m"))
279    (set (match_dup 1)
280         (unspec:I48MODE
281           [(not:I48MODE
282              (and:I48MODE (match_dup 1)
283                (match_operand:I48MODE 2 "register_operand" "r")))
284            (match_operand:SI 3 "const_int_operand" "")]
285           UNSPEC_ATOMIC))
286    (clobber (match_scratch:I48MODE 4 "=&r"))]
287   ""
288   "#"
289   "epilogue_completed"
290   [(const_int 0)]
291 {
292   alpha_split_atomic_op (NOT, operands[1], operands[2],
293                          operands[0], NULL, operands[4],
294                          (enum memmodel) INTVAL (operands[3]));
295   DONE;
296 }
297   [(set_attr "type" "multi")])
298
299 (define_insn_and_split "atomic_<fetchop_name>_fetch<mode>"
300   [(set (match_operand:I48MODE 0 "register_operand" "=&r")
301         (FETCHOP:I48MODE 
302           (match_operand:I48MODE 1 "memory_operand" "+m")
303           (match_operand:I48MODE 2 "<fetchop_pred>" "<fetchop_constr>")))
304    (set (match_dup 1)
305         (unspec:I48MODE
306           [(FETCHOP:I48MODE (match_dup 1) (match_dup 2))
307            (match_operand:SI 3 "const_int_operand" "")]
308           UNSPEC_ATOMIC))
309    (clobber (match_scratch:I48MODE 4 "=&r"))]
310   ""
311   "#"
312   "epilogue_completed"
313   [(const_int 0)]
314 {
315   alpha_split_atomic_op (<CODE>, operands[1], operands[2],
316                          NULL, operands[0], operands[4],
317                          (enum memmodel) INTVAL (operands[3]));
318   DONE;
319 }
320   [(set_attr "type" "multi")])
321
322 (define_insn_and_split "atomic_nand_fetch<mode>"
323   [(set (match_operand:I48MODE 0 "register_operand" "=&r")
324         (not:I48MODE
325           (and:I48MODE (match_operand:I48MODE 1 "memory_operand" "+m")
326             (match_operand:I48MODE 2 "register_operand" "r"))))
327    (set (match_dup 1)
328         (unspec:I48MODE
329           [(not:I48MODE (and:I48MODE (match_dup 1) (match_dup 2)))
330            (match_operand:SI 3 "const_int_operand" "")]
331           UNSPEC_ATOMIC))
332    (clobber (match_scratch:I48MODE 4 "=&r"))]
333   ""
334   "#"
335   "epilogue_completed"
336   [(const_int 0)]
337 {
338   alpha_split_atomic_op (NOT, operands[1], operands[2],
339                          NULL, operands[0], operands[4],
340                          (enum memmodel) INTVAL (operands[3]));
341   DONE;
342 }
343   [(set_attr "type" "multi")])