* arm.c (emit_set_insn): New function.
[official-gcc.git] / gcc / config / alpha / sync.md
blob1c34ce54b1c34462812f93f0dbed19cccc69e66e
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.
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.
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.
22 (define_mode_macro I12MODE [QI HI])
23 (define_mode_macro I48MODE [SI DI])
24 (define_mode_attr modesuffix [(SI "l") (DI "q")])
26 (define_code_macro 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 "add_operand") (minus "reg_or_8bit_operand")
31    (ior "or_operand") (xor "or_operand") (and "and_operand")])
32 (define_code_attr fetchop_constr
33   [(plus "rKL") (minus "rI") (ior "rIN") (xor "rIN") (and "riNHM")])
36 (define_expand "memory_barrier"
37   [(set (mem:BLK (match_dup 0))
38         (unspec:BLK [(mem:BLK (match_dup 0))] UNSPEC_MB))]
39   ""
41   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (DImode));
42   MEM_VOLATILE_P (operands[0]) = 1;
45 (define_insn "*mb_internal"
46   [(set (match_operand:BLK 0 "" "")
47         (unspec:BLK [(match_operand:BLK 1 "" "")] UNSPEC_MB))]
48   ""
49   "mb"
50   [(set_attr "type" "mb")])
52 (define_insn "load_locked_<mode>"
53   [(set (match_operand:I48MODE 0 "register_operand" "=r")
54         (unspec_volatile:I48MODE
55           [(match_operand:I48MODE 1 "memory_operand" "m")]
56           UNSPECV_LL))]
57   ""
58   "ld<modesuffix>_l %0,%1"
59   [(set_attr "type" "ld_l")])
61 (define_insn "store_conditional_<mode>"
62   [(set (match_operand:DI 0 "register_operand" "=r")
63         (unspec_volatile:DI [(const_int 0)] UNSPECV_SC))
64    (set (match_operand:I48MODE 1 "memory_operand" "=m")
65         (match_operand:I48MODE 2 "reg_or_0_operand" "0"))]
66   ""
67   "st<modesuffix>_c %0,%1"
68   [(set_attr "type" "st_c")])
70 ;; The Alpha Architecture Handbook says that it is UNPREDICTABLE whether
71 ;; the lock is cleared by a TAKEN branch.  If we were to honor that, it
72 ;; would mean that we could not expand a ll/sc sequence until after the
73 ;; final basic-block reordering pass.  Fortunately, it appears that no
74 ;; Alpha implementation ever built actually clears the lock on branches,
75 ;; taken or not.
77 (define_insn_and_split "sync_<fetchop_name><mode>"
78   [(set (match_operand:I48MODE 0 "memory_operand" "+m")
79         (unspec:I48MODE
80           [(FETCHOP:I48MODE (match_dup 0)
81              (match_operand:I48MODE 1 "<fetchop_pred>" "<fetchop_constr>"))]
82           UNSPEC_ATOMIC))
83    (clobber (match_scratch:I48MODE 2 "=&r"))]
84   ""
85   "#"
86   "reload_completed"
87   [(const_int 0)]
89   alpha_split_atomic_op (<CODE>, operands[0], operands[1],
90                          NULL, NULL, operands[2]);
91   DONE;
93   [(set_attr "type" "multi")])
95 (define_insn_and_split "sync_nand<mode>"
96   [(set (match_operand:I48MODE 0 "memory_operand" "+m")
97         (unspec:I48MODE
98           [(and:I48MODE (not:I48MODE (match_dup 0))
99              (match_operand:I48MODE 1 "register_operand" "r"))]
100           UNSPEC_ATOMIC))
101    (clobber (match_scratch:I48MODE 2 "=&r"))]
102   ""
103   "#"
104   "reload_completed"
105   [(const_int 0)]
107   alpha_split_atomic_op (NOT, operands[0], operands[1],
108                          NULL, NULL, operands[2]);
109   DONE;
111   [(set_attr "type" "multi")])
113 (define_insn_and_split "sync_old_<fetchop_name><mode>"
114   [(set (match_operand:I48MODE 0 "register_operand" "=&r")
115         (match_operand:I48MODE 1 "memory_operand" "+m"))
116    (set (match_dup 1)
117         (unspec:I48MODE
118           [(FETCHOP:I48MODE (match_dup 1)
119              (match_operand:I48MODE 2 "<fetchop_pred>" "<fetchop_constr>"))]
120           UNSPEC_ATOMIC))
121    (clobber (match_scratch:I48MODE 3 "=&r"))]
122   ""
123   "#"
124   "reload_completed"
125   [(const_int 0)]
127   alpha_split_atomic_op (<CODE>, operands[1], operands[2],
128                          operands[0], NULL, operands[3]);
129   DONE;
131   [(set_attr "type" "multi")])
133 (define_insn_and_split "sync_old_nand<mode>"
134   [(set (match_operand:I48MODE 0 "register_operand" "=&r")
135         (match_operand:I48MODE 1 "memory_operand" "+m"))
136    (set (match_dup 1)
137         (unspec:I48MODE
138           [(and:I48MODE (not:I48MODE (match_dup 1))
139              (match_operand:I48MODE 2 "register_operand" "r"))]
140           UNSPEC_ATOMIC))
141    (clobber (match_scratch:I48MODE 3 "=&r"))]
142   ""
143   "#"
144   "reload_completed"
145   [(const_int 0)]
147   alpha_split_atomic_op (NOT, operands[1], operands[2],
148                          operands[0], NULL, operands[3]);
149   DONE;
151   [(set_attr "type" "multi")])
153 (define_insn_and_split "sync_new_<fetchop_name><mode>"
154   [(set (match_operand:I48MODE 0 "register_operand" "=&r")
155         (FETCHOP:I48MODE 
156           (match_operand:I48MODE 1 "memory_operand" "+m")
157           (match_operand:I48MODE 2 "<fetchop_pred>" "<fetchop_constr>")))
158    (set (match_dup 1)
159         (unspec:I48MODE
160           [(FETCHOP:I48MODE (match_dup 1) (match_dup 2))]
161           UNSPEC_ATOMIC))
162    (clobber (match_scratch:I48MODE 3 "=&r"))]
163   ""
164   "#"
165   "reload_completed"
166   [(const_int 0)]
168   alpha_split_atomic_op (<CODE>, operands[1], operands[2],
169                          NULL, operands[0], operands[3]);
170   DONE;
172   [(set_attr "type" "multi")])
174 (define_insn_and_split "sync_new_nand<mode>"
175   [(set (match_operand:I48MODE 0 "register_operand" "=&r")
176         (and:I48MODE 
177           (not:I48MODE (match_operand:I48MODE 1 "memory_operand" "+m"))
178           (match_operand:I48MODE 2 "register_operand" "r")))
179    (set (match_dup 1)
180         (unspec:I48MODE
181           [(and:I48MODE (not:I48MODE (match_dup 1)) (match_dup 2))]
182           UNSPEC_ATOMIC))
183    (clobber (match_scratch:I48MODE 3 "=&r"))]
184   ""
185   "#"
186   "reload_completed"
187   [(const_int 0)]
189   alpha_split_atomic_op (NOT, operands[1], operands[2],
190                          NULL, operands[0], operands[3]);
191   DONE;
193   [(set_attr "type" "multi")])
195 (define_expand "sync_compare_and_swap<mode>"
196   [(match_operand:I12MODE 0 "register_operand" "")
197    (match_operand:I12MODE 1 "memory_operand" "")
198    (match_operand:I12MODE 2 "register_operand" "")
199    (match_operand:I12MODE 3 "add_operand" "")]
200   ""
202   alpha_expand_compare_and_swap_12 (operands[0], operands[1],
203                                     operands[2], operands[3]);
204   DONE;
207 (define_insn_and_split "sync_compare_and_swap<mode>_1"
208   [(set (match_operand:DI 0 "register_operand" "=&r,&r")
209         (zero_extend:DI
210           (mem:I12MODE (match_operand:DI 1 "register_operand" "r,r"))))
211    (set (mem:I12MODE (match_dup 1))
212         (unspec:I12MODE
213           [(match_operand:DI 2 "reg_or_8bit_operand" "J,rI")
214            (match_operand:DI 3 "register_operand" "r,r")
215            (match_operand:DI 4 "register_operand" "r,r")]
216           UNSPEC_CMPXCHG))
217    (clobber (match_scratch:DI 5 "=&r,&r"))
218    (clobber (match_scratch:DI 6 "=X,&r"))]
219   ""
220   "#"
221   "reload_completed"
222   [(const_int 0)]
224   alpha_split_compare_and_swap_12 (<MODE>mode, operands[0], operands[1],
225                                    operands[2], operands[3], operands[4],
226                                    operands[5], operands[6]);
227   DONE;
229   [(set_attr "type" "multi")])
231 (define_expand "sync_compare_and_swap<mode>"
232   [(parallel
233      [(set (match_operand:I48MODE 0 "register_operand" "")
234            (match_operand:I48MODE 1 "memory_operand" ""))
235       (set (match_dup 1)
236            (unspec:I48MODE
237              [(match_operand:I48MODE 2 "reg_or_8bit_operand" "")
238               (match_operand:I48MODE 3 "add_operand" "rKL")]
239              UNSPEC_CMPXCHG))
240       (clobber (match_scratch:I48MODE 4 "=&r"))])]
241   ""
243   if (<MODE>mode == SImode)
244     operands[2] = convert_modes (DImode, SImode, operands[2], 0);
247 (define_insn_and_split "*sync_compare_and_swap<mode>"
248   [(set (match_operand:I48MODE 0 "register_operand" "=&r")
249         (match_operand:I48MODE 1 "memory_operand" "+m"))
250    (set (match_dup 1)
251         (unspec:I48MODE
252           [(match_operand:DI 2 "reg_or_8bit_operand" "rI")
253            (match_operand:I48MODE 3 "add_operand" "rKL")]
254           UNSPEC_CMPXCHG))
255    (clobber (match_scratch:I48MODE 4 "=&r"))]
256   ""
257   "#"
258   "reload_completed"
259   [(const_int 0)]
261   alpha_split_compare_and_swap (operands[0], operands[1], operands[2],
262                                 operands[3], operands[4]);
263   DONE;
265   [(set_attr "type" "multi")])
267 (define_expand "sync_lock_test_and_set<mode>"
268   [(match_operand:I12MODE 0 "register_operand" "")
269    (match_operand:I12MODE 1 "memory_operand" "")
270    (match_operand:I12MODE 2 "register_operand" "")]
271   ""
273   alpha_expand_lock_test_and_set_12 (operands[0], operands[1], operands[2]);
274   DONE;
277 (define_insn_and_split "sync_lock_test_and_set<mode>_1"
278   [(set (match_operand:DI 0 "register_operand" "=&r")
279         (zero_extend:DI
280           (mem:I12MODE (match_operand:DI 1 "register_operand" "r"))))
281    (set (mem:I12MODE (match_dup 1))
282         (unspec:I12MODE
283           [(match_operand:DI 2 "reg_or_8bit_operand" "rI")
284            (match_operand:DI 3 "register_operand" "r")]
285           UNSPEC_XCHG))
286    (clobber (match_scratch:DI 4 "=&r"))]
287   ""
288   "#"
289   "reload_completed"
290   [(const_int 0)]
292   alpha_split_lock_test_and_set_12 (<MODE>mode, operands[0], operands[1],
293                                     operands[2], operands[3], operands[4]);
294   DONE;
296   [(set_attr "type" "multi")])
298 (define_insn_and_split "sync_lock_test_and_set<mode>"
299   [(set (match_operand:I48MODE 0 "register_operand" "=&r")
300         (match_operand:I48MODE 1 "memory_operand" "+m"))
301    (set (match_dup 1)
302         (unspec:I48MODE
303           [(match_operand:I48MODE 2 "add_operand" "rKL")]
304           UNSPEC_XCHG))
305    (clobber (match_scratch:I48MODE 3 "=&r"))]
306   ""
307   "#"
308   "reload_completed"
309   [(const_int 0)]
311   alpha_split_lock_test_and_set (operands[0], operands[1],
312                                  operands[2], operands[3]);
313   DONE;
315   [(set_attr "type" "multi")])