OSDN Git Service

Add NIOS2 support. Code from SourceyG++.
[pf3gnuchains/gcc-fork.git] / gcc / config / mips / sync.md
1 ;;  Machine Description for MIPS based processor synchronization
2 ;;  instructions.
3 ;;  Copyright (C) 2007, 2008, 2009
4 ;;  Free Software Foundation, Inc.
5
6 ;; This file is part of GCC.
7
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
11 ;; any later version.
12
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
17
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3.  If not see
20 ;; <http://www.gnu.org/licenses/>.
21
22 ;; Atomic fetch bitwise operations.
23 (define_code_iterator fetchop_bit [ior xor and])
24
25 ;; Atomic HI and QI operations
26 (define_code_iterator atomic_hiqi_op [plus minus ior xor and])
27
28 ;; Atomic memory operations.
29
30 (define_expand "memory_barrier"
31   [(set (match_dup 0)
32         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))]
33   "GENERATE_SYNC"
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_MEMORY_BARRIER))]
42   "GENERATE_SYNC"
43   { return mips_output_sync (); })
44
45 (define_insn "sync_compare_and_swap<mode>"
46   [(set (match_operand:GPR 0 "register_operand" "=&d,&d")
47         (match_operand:GPR 1 "memory_operand" "+R,R"))
48    (set (match_dup 1)
49         (unspec_volatile:GPR [(match_operand:GPR 2 "reg_or_0_operand" "dJ,dJ")
50                               (match_operand:GPR 3 "arith_operand" "I,d")]
51          UNSPEC_COMPARE_AND_SWAP))]
52   "GENERATE_LL_SC"
53   { return mips_output_sync_loop (insn, operands); }
54   [(set_attr "sync_insn1" "li,move")
55    (set_attr "sync_oldval" "0")
56    (set_attr "sync_mem" "1")
57    (set_attr "sync_required_oldval" "2")
58    (set_attr "sync_insn1_op2" "3")])
59
60 (define_expand "sync_compare_and_swap<mode>"
61   [(match_operand:SHORT 0 "register_operand")
62    (match_operand:SHORT 1 "memory_operand")
63    (match_operand:SHORT 2 "general_operand")
64    (match_operand:SHORT 3 "general_operand")]
65   "GENERATE_LL_SC"
66 {
67   union mips_gen_fn_ptrs generator;
68   generator.fn_6 = gen_compare_and_swap_12;
69   mips_expand_atomic_qihi (generator,
70                            operands[0], operands[1], operands[2], operands[3]);
71   DONE;
72 })
73
74 ;; Helper insn for mips_expand_atomic_qihi.
75 (define_insn "compare_and_swap_12"
76   [(set (match_operand:SI 0 "register_operand" "=&d,&d")
77         (match_operand:SI 1 "memory_operand" "+R,R"))
78    (set (match_dup 1)
79         (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "d,d")
80                              (match_operand:SI 3 "register_operand" "d,d")
81                              (match_operand:SI 4 "reg_or_0_operand" "dJ,dJ")
82                              (match_operand:SI 5 "reg_or_0_operand" "d,J")]
83                             UNSPEC_COMPARE_AND_SWAP_12))]
84   "GENERATE_LL_SC"
85   { return mips_output_sync_loop (insn, operands); }
86   [(set_attr "sync_oldval" "0")
87    (set_attr "sync_mem" "1")
88    (set_attr "sync_inclusive_mask" "2")
89    (set_attr "sync_exclusive_mask" "3")
90    (set_attr "sync_required_oldval" "4")
91    (set_attr "sync_insn1_op2" "5")])
92
93 (define_insn "sync_add<mode>"
94   [(set (match_operand:GPR 0 "memory_operand" "+R,R")
95         (unspec_volatile:GPR
96           [(plus:GPR (match_dup 0)
97                      (match_operand:GPR 1 "arith_operand" "I,d"))]
98           UNSPEC_SYNC_OLD_OP))]
99   "GENERATE_LL_SC"
100   { return mips_output_sync_loop (insn, operands); }
101   [(set_attr "sync_insn1" "addiu,addu")
102    (set_attr "sync_mem" "0")
103    (set_attr "sync_insn1_op2" "1")])
104
105 (define_expand "sync_<optab><mode>"
106   [(set (match_operand:SHORT 0 "memory_operand")
107         (unspec_volatile:SHORT
108           [(atomic_hiqi_op:SHORT (match_dup 0)
109                                  (match_operand:SHORT 1 "general_operand"))]
110           UNSPEC_SYNC_OLD_OP))]
111   "GENERATE_LL_SC"
112 {
113   union mips_gen_fn_ptrs generator;
114   generator.fn_4 = gen_sync_<optab>_12;
115   mips_expand_atomic_qihi (generator,
116                            NULL, operands[0], operands[1], NULL);
117   DONE;
118 })
119
120 ;; Helper insn for sync_<optab><mode>
121 (define_insn "sync_<optab>_12"
122   [(set (match_operand:SI 0 "memory_operand" "+R")
123         (unspec_volatile:SI
124           [(match_operand:SI 1 "register_operand" "d")
125            (match_operand:SI 2 "register_operand" "d")
126            (atomic_hiqi_op:SI (match_dup 0)
127                               (match_operand:SI 3 "register_operand" "dJ"))]
128           UNSPEC_SYNC_OLD_OP_12))
129    (clobber (match_scratch:SI 4 "=&d"))]
130   "GENERATE_LL_SC"
131   { return mips_output_sync_loop (insn, operands); }
132   [(set_attr "sync_insn1" "<insn>")
133    (set_attr "sync_insn2" "and")
134    (set_attr "sync_mem" "0")
135    (set_attr "sync_inclusive_mask" "1")
136    (set_attr "sync_exclusive_mask" "2")
137    (set_attr "sync_insn1_op2" "3")
138    (set_attr "sync_oldval" "4")
139    (set_attr "sync_newval" "4")])
140
141 (define_expand "sync_old_<optab><mode>"
142   [(parallel [
143      (set (match_operand:SHORT 0 "register_operand")
144           (match_operand:SHORT 1 "memory_operand"))
145      (set (match_dup 1)
146           (unspec_volatile:SHORT [(atomic_hiqi_op:SHORT
147                                     (match_dup 1)
148                                     (match_operand:SHORT 2 "general_operand"))]
149             UNSPEC_SYNC_OLD_OP))])]
150   "GENERATE_LL_SC"
151 {
152   union mips_gen_fn_ptrs generator;
153   generator.fn_5 = gen_sync_old_<optab>_12;
154   mips_expand_atomic_qihi (generator,
155                            operands[0], operands[1], operands[2], NULL);
156   DONE;
157 })
158
159 ;; Helper insn for sync_old_<optab><mode>
160 (define_insn "sync_old_<optab>_12"
161   [(set (match_operand:SI 0 "register_operand" "=&d")
162         (match_operand:SI 1 "memory_operand" "+R"))
163    (set (match_dup 1)
164         (unspec_volatile:SI
165           [(match_operand:SI 2 "register_operand" "d")
166            (match_operand:SI 3 "register_operand" "d")
167            (atomic_hiqi_op:SI (match_dup 0)
168                               (match_operand:SI 4 "register_operand" "dJ"))]
169           UNSPEC_SYNC_OLD_OP_12))
170    (clobber (match_scratch:SI 5 "=&d"))]
171   "GENERATE_LL_SC"
172   { return mips_output_sync_loop (insn, operands); }
173   [(set_attr "sync_insn1" "<insn>")
174    (set_attr "sync_insn2" "and")
175    (set_attr "sync_oldval" "0")
176    (set_attr "sync_mem" "1")
177    (set_attr "sync_inclusive_mask" "2")
178    (set_attr "sync_exclusive_mask" "3")
179    (set_attr "sync_insn1_op2" "4")
180    (set_attr "sync_newval" "5")])
181
182 (define_expand "sync_new_<optab><mode>"
183   [(parallel [
184      (set (match_operand:SHORT 0 "register_operand")
185           (unspec_volatile:SHORT [(atomic_hiqi_op:SHORT
186                                     (match_operand:SHORT 1 "memory_operand")
187                                     (match_operand:SHORT 2 "general_operand"))]
188             UNSPEC_SYNC_NEW_OP))
189      (set (match_dup 1)
190           (unspec_volatile:SHORT [(match_dup 1) (match_dup 2)]
191             UNSPEC_SYNC_NEW_OP))])]
192   "GENERATE_LL_SC"
193 {
194   union mips_gen_fn_ptrs generator;
195   generator.fn_5 = gen_sync_new_<optab>_12;
196   mips_expand_atomic_qihi (generator,
197                            operands[0], operands[1], operands[2], NULL);
198   DONE;
199 })
200
201 ;; Helper insn for sync_new_<optab><mode>
202 (define_insn "sync_new_<optab>_12"
203   [(set (match_operand:SI 0 "register_operand" "=&d")
204         (unspec_volatile:SI
205           [(match_operand:SI 1 "memory_operand" "+R")
206            (match_operand:SI 2 "register_operand" "d")
207            (match_operand:SI 3 "register_operand" "d")
208            (atomic_hiqi_op:SI (match_dup 0)
209                               (match_operand:SI 4 "register_operand" "dJ"))]
210           UNSPEC_SYNC_NEW_OP_12))
211    (set (match_dup 1)
212         (unspec_volatile:SI
213           [(match_dup 1)
214            (match_dup 2)
215            (match_dup 3)
216            (match_dup 4)] UNSPEC_SYNC_NEW_OP_12))]
217   "GENERATE_LL_SC"
218   { return mips_output_sync_loop (insn, operands); }
219   [(set_attr "sync_insn1" "<insn>")
220    (set_attr "sync_insn2" "and")
221    (set_attr "sync_oldval" "0")
222    (set_attr "sync_newval" "0")
223    (set_attr "sync_mem" "1")
224    (set_attr "sync_inclusive_mask" "2")
225    (set_attr "sync_exclusive_mask" "3")
226    (set_attr "sync_insn1_op2" "4")])
227
228 (define_expand "sync_nand<mode>"
229   [(set (match_operand:SHORT 0 "memory_operand")
230         (unspec_volatile:SHORT
231           [(match_dup 0)
232            (match_operand:SHORT 1 "general_operand")]
233           UNSPEC_SYNC_OLD_OP))]
234   "GENERATE_LL_SC"
235 {
236   union mips_gen_fn_ptrs generator;
237   generator.fn_4 = gen_sync_nand_12;
238   mips_expand_atomic_qihi (generator,
239                            NULL, operands[0], operands[1], NULL);
240   DONE;
241 })
242
243 ;; Helper insn for sync_nand<mode>
244 (define_insn "sync_nand_12"
245   [(set (match_operand:SI 0 "memory_operand" "+R")
246         (unspec_volatile:SI
247           [(match_operand:SI 1 "register_operand" "d")
248            (match_operand:SI 2 "register_operand" "d")
249            (match_dup 0)
250            (match_operand:SI 3 "register_operand" "dJ")]
251           UNSPEC_SYNC_OLD_OP_12))
252    (clobber (match_scratch:SI 4 "=&d"))]
253   "GENERATE_LL_SC"
254   { return mips_output_sync_loop (insn, operands); }
255   [(set_attr "sync_insn1" "and")
256    (set_attr "sync_insn2" "xor")
257    (set_attr "sync_mem" "0")
258    (set_attr "sync_inclusive_mask" "1")
259    (set_attr "sync_exclusive_mask" "2")
260    (set_attr "sync_insn1_op2" "3")
261    (set_attr "sync_oldval" "4")
262    (set_attr "sync_newval" "4")])
263
264 (define_expand "sync_old_nand<mode>"
265   [(parallel [
266      (set (match_operand:SHORT 0 "register_operand")
267           (match_operand:SHORT 1 "memory_operand"))
268      (set (match_dup 1)
269           (unspec_volatile:SHORT [(match_dup 1)
270                                   (match_operand:SHORT 2 "general_operand")]
271             UNSPEC_SYNC_OLD_OP))])]
272   "GENERATE_LL_SC"
273 {
274   union mips_gen_fn_ptrs generator;
275   generator.fn_5 = gen_sync_old_nand_12;
276   mips_expand_atomic_qihi (generator,
277                            operands[0], operands[1], operands[2], NULL);
278   DONE;
279 })
280
281 ;; Helper insn for sync_old_nand<mode>
282 (define_insn "sync_old_nand_12"
283   [(set (match_operand:SI 0 "register_operand" "=&d")
284         (match_operand:SI 1 "memory_operand" "+R"))
285    (set (match_dup 1)
286         (unspec_volatile:SI
287           [(match_operand:SI 2 "register_operand" "d")
288            (match_operand:SI 3 "register_operand" "d")
289            (match_operand:SI 4 "register_operand" "dJ")]
290           UNSPEC_SYNC_OLD_OP_12))
291    (clobber (match_scratch:SI 5 "=&d"))]
292   "GENERATE_LL_SC"
293   { return mips_output_sync_loop (insn, operands); }
294   [(set_attr "sync_insn1" "and")
295    (set_attr "sync_insn2" "xor")
296    (set_attr "sync_oldval" "0")
297    (set_attr "sync_mem" "1")
298    (set_attr "sync_inclusive_mask" "2")
299    (set_attr "sync_exclusive_mask" "3")
300    (set_attr "sync_insn1_op2" "4")
301    (set_attr "sync_newval" "5")])
302
303 (define_expand "sync_new_nand<mode>"
304   [(parallel [
305      (set (match_operand:SHORT 0 "register_operand")
306           (unspec_volatile:SHORT [(match_operand:SHORT 1 "memory_operand")
307                                   (match_operand:SHORT 2 "general_operand")]
308             UNSPEC_SYNC_NEW_OP))
309      (set (match_dup 1)
310           (unspec_volatile:SHORT [(match_dup 1) (match_dup 2)]
311             UNSPEC_SYNC_NEW_OP))])]
312   "GENERATE_LL_SC"
313 {
314   union mips_gen_fn_ptrs generator;
315   generator.fn_5 = gen_sync_new_nand_12;
316   mips_expand_atomic_qihi (generator,
317                            operands[0], operands[1], operands[2], NULL);
318   DONE;
319 })
320
321 ;; Helper insn for sync_new_nand<mode>
322 (define_insn "sync_new_nand_12"
323   [(set (match_operand:SI 0 "register_operand" "=&d")
324         (unspec_volatile:SI
325           [(match_operand:SI 1 "memory_operand" "+R")
326            (match_operand:SI 2 "register_operand" "d")
327            (match_operand:SI 3 "register_operand" "d")
328            (match_operand:SI 4 "register_operand" "dJ")]
329           UNSPEC_SYNC_NEW_OP_12))
330    (set (match_dup 1)
331         (unspec_volatile:SI
332           [(match_dup 1)
333            (match_dup 2)
334            (match_dup 3)
335            (match_dup 4)] UNSPEC_SYNC_NEW_OP_12))]
336   "GENERATE_LL_SC"
337   { return mips_output_sync_loop (insn, operands); }
338   [(set_attr "sync_insn1" "and")
339    (set_attr "sync_insn2" "xor")
340    (set_attr "sync_oldval" "0")
341    (set_attr "sync_newval" "0")
342    (set_attr "sync_mem" "1")
343    (set_attr "sync_inclusive_mask" "2")
344    (set_attr "sync_exclusive_mask" "3")
345    (set_attr "sync_insn1_op2" "4")])
346
347 (define_insn "sync_sub<mode>"
348   [(set (match_operand:GPR 0 "memory_operand" "+R")
349         (unspec_volatile:GPR
350           [(minus:GPR (match_dup 0)
351                       (match_operand:GPR 1 "register_operand" "d"))]
352          UNSPEC_SYNC_OLD_OP))]
353   "GENERATE_LL_SC"
354   { return mips_output_sync_loop (insn, operands); }
355   [(set_attr "sync_insn1" "subu")
356    (set_attr "sync_mem" "0")
357    (set_attr "sync_insn1_op2" "1")])
358
359 (define_insn "sync_old_add<mode>"
360   [(set (match_operand:GPR 0 "register_operand" "=&d,&d")
361         (match_operand:GPR 1 "memory_operand" "+R,R"))
362    (set (match_dup 1)
363         (unspec_volatile:GPR
364           [(plus:GPR (match_dup 1)
365                      (match_operand:GPR 2 "arith_operand" "I,d"))]
366          UNSPEC_SYNC_OLD_OP))]
367   "GENERATE_LL_SC"
368   { return mips_output_sync_loop (insn, operands); }
369   [(set_attr "sync_insn1" "addiu,addu")
370    (set_attr "sync_oldval" "0")
371    (set_attr "sync_mem" "1")
372    (set_attr "sync_insn1_op2" "2")])
373
374 (define_insn "sync_old_sub<mode>"
375   [(set (match_operand:GPR 0 "register_operand" "=&d")
376         (match_operand:GPR 1 "memory_operand" "+R"))
377    (set (match_dup 1)
378         (unspec_volatile:GPR
379           [(minus:GPR (match_dup 1)
380                       (match_operand:GPR 2 "register_operand" "d"))]
381          UNSPEC_SYNC_OLD_OP))]
382   "GENERATE_LL_SC"
383   { return mips_output_sync_loop (insn, operands); }
384   [(set_attr "sync_insn1" "subu")
385    (set_attr "sync_oldval" "0")
386    (set_attr "sync_mem" "1")
387    (set_attr "sync_insn1_op2" "2")])
388
389 (define_insn "sync_new_add<mode>"
390   [(set (match_operand:GPR 0 "register_operand" "=&d,&d")
391         (plus:GPR (match_operand:GPR 1 "memory_operand" "+R,R")
392                   (match_operand:GPR 2 "arith_operand" "I,d")))
393    (set (match_dup 1)
394         (unspec_volatile:GPR
395           [(plus:GPR (match_dup 1) (match_dup 2))]
396          UNSPEC_SYNC_NEW_OP))]
397   "GENERATE_LL_SC"
398   { return mips_output_sync_loop (insn, operands); }
399   [(set_attr "sync_insn1" "addiu,addu")
400    (set_attr "sync_oldval" "0")
401    (set_attr "sync_newval" "0")
402    (set_attr "sync_mem" "1")
403    (set_attr "sync_insn1_op2" "2")])
404
405 (define_insn "sync_new_sub<mode>"
406   [(set (match_operand:GPR 0 "register_operand" "=&d")
407         (minus:GPR (match_operand:GPR 1 "memory_operand" "+R")
408                    (match_operand:GPR 2 "register_operand" "d")))
409    (set (match_dup 1)
410         (unspec_volatile:GPR
411           [(minus:GPR (match_dup 1) (match_dup 2))]
412          UNSPEC_SYNC_NEW_OP))]
413   "GENERATE_LL_SC"
414   { return mips_output_sync_loop (insn, operands); }
415   [(set_attr "sync_insn1" "subu")
416    (set_attr "sync_oldval" "0")
417    (set_attr "sync_newval" "0")
418    (set_attr "sync_mem" "1")
419    (set_attr "sync_insn1_op2" "2")])
420
421 (define_insn "sync_<optab><mode>"
422   [(set (match_operand:GPR 0 "memory_operand" "+R,R")
423         (unspec_volatile:GPR
424           [(fetchop_bit:GPR (match_operand:GPR 1 "uns_arith_operand" "K,d")
425                               (match_dup 0))]
426          UNSPEC_SYNC_OLD_OP))]
427   "GENERATE_LL_SC"
428   { return mips_output_sync_loop (insn, operands); }
429   [(set_attr "sync_insn1" "<immediate_insn>,<insn>")
430    (set_attr "sync_mem" "0")
431    (set_attr "sync_insn1_op2" "1")])
432
433 (define_insn "sync_old_<optab><mode>"
434   [(set (match_operand:GPR 0 "register_operand" "=&d,&d")
435         (match_operand:GPR 1 "memory_operand" "+R,R"))
436    (set (match_dup 1)
437         (unspec_volatile:GPR
438           [(fetchop_bit:GPR (match_operand:GPR 2 "uns_arith_operand" "K,d")
439                             (match_dup 1))]
440          UNSPEC_SYNC_OLD_OP))]
441   "GENERATE_LL_SC"
442   { return mips_output_sync_loop (insn, operands); }
443   [(set_attr "sync_insn1" "<immediate_insn>,<insn>")
444    (set_attr "sync_oldval" "0")
445    (set_attr "sync_mem" "1")
446    (set_attr "sync_insn1_op2" "2")])
447
448 (define_insn "sync_new_<optab><mode>"
449   [(set (match_operand:GPR 0 "register_operand" "=&d,&d")
450         (match_operand:GPR 1 "memory_operand" "+R,R"))
451    (set (match_dup 1)
452         (unspec_volatile:GPR
453           [(fetchop_bit:GPR (match_operand:GPR 2 "uns_arith_operand" "K,d")
454                             (match_dup 1))]
455          UNSPEC_SYNC_NEW_OP))]
456   "GENERATE_LL_SC"
457   { return mips_output_sync_loop (insn, operands); }
458   [(set_attr "sync_insn1" "<immediate_insn>,<insn>")
459    (set_attr "sync_oldval" "0")
460    (set_attr "sync_newval" "0")
461    (set_attr "sync_mem" "1")
462    (set_attr "sync_insn1_op2" "2")])
463
464 (define_insn "sync_nand<mode>"
465   [(set (match_operand:GPR 0 "memory_operand" "+R,R")
466         (unspec_volatile:GPR [(match_operand:GPR 1 "uns_arith_operand" "K,d")]
467          UNSPEC_SYNC_OLD_OP))]
468   "GENERATE_LL_SC"
469   { return mips_output_sync_loop (insn, operands); }
470   [(set_attr "sync_insn1" "andi,and")
471    (set_attr "sync_insn2" "not")
472    (set_attr "sync_mem" "0")
473    (set_attr "sync_insn1_op2" "1")])
474
475 (define_insn "sync_old_nand<mode>"
476   [(set (match_operand:GPR 0 "register_operand" "=&d,&d")
477         (match_operand:GPR 1 "memory_operand" "+R,R"))
478    (set (match_dup 1)
479         (unspec_volatile:GPR [(match_operand:GPR 2 "uns_arith_operand" "K,d")]
480          UNSPEC_SYNC_OLD_OP))]
481   "GENERATE_LL_SC"
482   { return mips_output_sync_loop (insn, operands); }
483   [(set_attr "sync_insn1" "andi,and")
484    (set_attr "sync_insn2" "not")
485    (set_attr "sync_oldval" "0")
486    (set_attr "sync_mem" "1")
487    (set_attr "sync_insn1_op2" "2")])
488
489 (define_insn "sync_new_nand<mode>"
490   [(set (match_operand:GPR 0 "register_operand" "=&d,&d")
491         (match_operand:GPR 1 "memory_operand" "+R,R"))
492    (set (match_dup 1)
493         (unspec_volatile:GPR [(match_operand:GPR 2 "uns_arith_operand" "K,d")]
494          UNSPEC_SYNC_NEW_OP))]
495   "GENERATE_LL_SC"
496   { return mips_output_sync_loop (insn, operands); }
497   [(set_attr "sync_insn1" "andi,and")
498    (set_attr "sync_insn2" "not")
499    (set_attr "sync_oldval" "0")
500    (set_attr "sync_newval" "0")
501    (set_attr "sync_mem" "1")
502    (set_attr "sync_insn1_op2" "2")])
503
504 (define_insn "sync_lock_test_and_set<mode>"
505   [(set (match_operand:GPR 0 "register_operand" "=&d,&d")
506         (match_operand:GPR 1 "memory_operand" "+R,R"))
507    (set (match_dup 1)
508         (unspec_volatile:GPR [(match_operand:GPR 2 "arith_operand" "I,d")]
509          UNSPEC_SYNC_EXCHANGE))]
510   "GENERATE_LL_SC"
511   { return mips_output_sync_loop (insn, operands); }
512   [(set_attr "sync_release_barrier" "no")
513    (set_attr "sync_insn1" "li,move")
514    (set_attr "sync_oldval" "0")
515    (set_attr "sync_mem" "1")
516    (set_attr "sync_insn1_op2" "2")])
517
518 (define_expand "sync_lock_test_and_set<mode>"
519   [(match_operand:SHORT 0 "register_operand")
520    (match_operand:SHORT 1 "memory_operand")
521    (match_operand:SHORT 2 "general_operand")]
522   "GENERATE_LL_SC"
523 {
524   union mips_gen_fn_ptrs generator;
525   generator.fn_5 = gen_test_and_set_12;
526   mips_expand_atomic_qihi (generator,
527                            operands[0], operands[1], operands[2], NULL);
528   DONE;
529 })
530
531 (define_insn "test_and_set_12"
532   [(set (match_operand:SI 0 "register_operand" "=&d")
533         (match_operand:SI 1 "memory_operand" "+R"))
534    (set (match_dup 1)
535         (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "d")
536                              (match_operand:SI 3 "register_operand" "d")
537                              (match_operand:SI 4 "arith_operand" "dJ")]
538           UNSPEC_SYNC_EXCHANGE_12))]
539   "GENERATE_LL_SC"
540   { return mips_output_sync_loop (insn, operands); }
541   [(set_attr "sync_release_barrier" "no")
542    (set_attr "sync_oldval" "0")
543    (set_attr "sync_mem" "1")
544    ;; Unused, but needed to give the number of operands expected by
545    ;; the expander.
546    (set_attr "sync_inclusive_mask" "2")
547    (set_attr "sync_exclusive_mask" "3")
548    (set_attr "sync_insn1_op2" "4")])