Sync usage with man page.
[netbsd-mini2440.git] / gnu / dist / gcc4 / gcc / config / rs6000 / sync.md
blob71351dbfbdd0735d15ac3011c1e3270f0283ab44
1 ;; Machine description for PowerPC synchronization instructions.
2 ;; Copyright (C) 2005 Free Software Foundation, Inc.
3 ;; Contributed by Geoffrey Keating.
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published
9 ;; by the Free Software Foundation; either version 2, or (at your
10 ;; option) any later version.
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15 ;; 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 the
19 ;; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
20 ;; MA 02110-1301, USA.
22 (define_mode_attr larx [(SI "lwarx") (DI "ldarx")])
23 (define_mode_attr stcx [(SI "stwcx.") (DI "stdcx.")])
25 (define_code_macro FETCHOP [plus minus ior xor and])
26 (define_code_attr fetchop_name
27   [(plus "add") (minus "sub") (ior "ior") (xor "xor") (and "and")])
28 (define_code_attr fetchop_pred
29   [(plus "add_operand") (minus "gpc_reg_operand")
30    (ior "logical_operand") (xor "logical_operand") (and "and_operand")])
31 (define_code_attr fetchopsi_constr
32   [(plus "rIL") (minus "r") (ior "rKL") (xor "rKL") (and "rTKL")])
33 (define_code_attr fetchopdi_constr
34   [(plus "rIL") (minus "r") (ior "rKJF") (xor "rKJF") (and "rSTKJ")])
36 (define_expand "memory_barrier"
37   [(set (mem:BLK (match_dup 0))
38         (unspec:BLK [(mem:BLK (match_dup 0))] UNSPEC_SYNC))]
39   ""
41   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
42   MEM_VOLATILE_P (operands[0]) = 1;
45 (define_insn "*sync_internal"
46   [(set (match_operand:BLK 0 "" "")
47         (unspec:BLK [(match_operand:BLK 1 "" "")] UNSPEC_SYNC))]
48   ""
49   "{dcs|sync}"
50   [(set_attr "type" "sync")])
52 (define_insn "load_locked_<mode>"
53   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
54         (unspec_volatile:GPR
55           [(match_operand:GPR 1 "memory_operand" "Z")] UNSPECV_LL))]
56   "TARGET_POWERPC"
57   "<larx> %0,%y1"
58   [(set_attr "type" "load_l")])
60 (define_insn "store_conditional_<mode>"
61   [(set (match_operand:CC 0 "cc_reg_operand" "=x")
62         (unspec_volatile:CC [(const_int 0)] UNSPECV_SC))
63    (set (match_operand:GPR 1 "memory_operand" "=Z")
64         (match_operand:GPR 2 "gpc_reg_operand" "r"))]
65   "TARGET_POWERPC"
66   "<stcx> %2,%y1"
67   [(set_attr "type" "store_c")])
69 (define_insn_and_split "sync_compare_and_swap<mode>"
70   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
71         (match_operand:GPR 1 "memory_operand" "+Z"))
72    (set (match_dup 1)
73         (unspec:GPR
74           [(match_operand:GPR 2 "reg_or_short_operand" "rI")
75            (match_operand:GPR 3 "gpc_reg_operand" "r")]
76           UNSPEC_CMPXCHG))
77    (clobber (match_scratch:GPR 4 "=&r"))
78    (clobber (match_scratch:CC 5 "=&x"))]
79   "TARGET_POWERPC"
80   "#"
81   "&& reload_completed"
82   [(const_int 0)]
84   rs6000_split_compare_and_swap (operands[0], operands[1], operands[2],
85                                  operands[3], operands[4]);
86   DONE;
89 (define_insn_and_split "sync_lock_test_and_set<mode>"
90   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
91         (match_operand:GPR 1 "memory_operand" "+Z"))
92    (set (match_dup 1)
93         (unspec:GPR
94           [(match_operand:GPR 2 "reg_or_short_operand" "rL")]
95           UNSPEC_XCHG))
96    (clobber (match_scratch:GPR 3 "=&r"))
97    (clobber (match_scratch:CC 4 "=&x"))]
98   "TARGET_POWERPC"
99   "#"
100   "&& reload_completed"
101   [(const_int 0)]
103   rs6000_split_lock_test_and_set (operands[0], operands[1], operands[2],
104                                   operands[3]);
105   DONE;
108 (define_expand "sync_<fetchop_name><mode>"
109   [(parallel [(set (match_operand:INT1 0 "memory_operand" "")
110                    (unspec:INT1
111                      [(FETCHOP:INT1 (match_dup 0)
112                         (match_operand:INT1 1 "<fetchop_pred>" ""))]
113                      UNSPEC_ATOMIC))
114               (clobber (scratch:INT1))
115               (clobber (scratch:CC))])]
116   "TARGET_POWERPC"
117   "
119   if (<MODE>mode != SImode && <MODE>mode != DImode)
120     {
121       if (PPC405_ERRATUM77)
122         FAIL;
123       rs6000_emit_sync (<CODE>, <MODE>mode, operands[0], operands[1],
124                         NULL_RTX, NULL_RTX, true);
125       DONE;
126     }
129 (define_insn_and_split "*sync_<fetchop_name>si_internal"
130   [(set (match_operand:SI 0 "memory_operand" "+Z")
131         (unspec:SI
132           [(FETCHOP:SI (match_dup 0)
133              (match_operand:SI 1 "<fetchop_pred>" "<fetchopsi_constr>"))]
134           UNSPEC_ATOMIC))
135    (clobber (match_scratch:SI 2 "=&b"))
136    (clobber (match_scratch:CC 3 "=&x"))]
137   "TARGET_POWERPC"
138   "#"
139   "&& reload_completed"
140   [(const_int 0)]
142   rs6000_split_atomic_op (<CODE>, operands[0], operands[1],
143                           NULL_RTX, NULL_RTX, operands[2]);
144   DONE;
147 (define_insn_and_split "*sync_<fetchop_name>di_internal"
148   [(set (match_operand:DI 0 "memory_operand" "+Z")
149         (unspec:DI
150           [(FETCHOP:DI (match_dup 0)
151              (match_operand:DI 1 "<fetchop_pred>" "<fetchopdi_constr>"))]
152           UNSPEC_ATOMIC))
153    (clobber (match_scratch:DI 2 "=&b"))
154    (clobber (match_scratch:CC 3 "=&x"))]
155   "TARGET_POWERPC"
156   "#"
157   "&& reload_completed"
158   [(const_int 0)]
160   rs6000_split_atomic_op (<CODE>, operands[0], operands[1],
161                           NULL_RTX, NULL_RTX, operands[2]);
162   DONE;
165 (define_expand "sync_nand<mode>"
166   [(parallel [(set (match_operand:INT1 0 "memory_operand" "")
167               (unspec:INT1
168                 [(and:INT1 (not:INT1 (match_dup 0))
169                    (match_operand:INT1 1 "gpc_reg_operand" ""))]
170                 UNSPEC_ATOMIC))
171               (clobber (scratch:INT1))
172               (clobber (scratch:CC))])]
173   "TARGET_POWERPC"
174   "
176   if (<MODE>mode != SImode && <MODE>mode != DImode)
177     {
178       if (PPC405_ERRATUM77)
179         FAIL;
180       rs6000_emit_sync (AND, <MODE>mode,
181                         gen_rtx_NOT (<MODE>mode, operands[0]),
182                         operands[1],
183                         NULL_RTX, NULL_RTX, true);
184       DONE;
185     }
188 (define_insn_and_split "*sync_nand<mode>_internal"
189   [(set (match_operand:GPR 0 "memory_operand" "+Z")
190         (unspec:GPR
191           [(and:GPR (not:GPR (match_dup 0))
192              (match_operand:GPR 1 "gpc_reg_operand" "r"))]
193           UNSPEC_ATOMIC))
194    (clobber (match_scratch:GPR 2 "=&r"))
195    (clobber (match_scratch:CC 3 "=&x"))]
196   "TARGET_POWERPC"
197   "#"
198   "&& reload_completed"
199   [(const_int 0)]
201   rs6000_split_atomic_op (NOT, operands[0], operands[1],
202                           NULL_RTX, NULL_RTX, operands[2]);
203   DONE;
206 (define_expand "sync_old_<fetchop_name><mode>"
207   [(parallel [(set (match_operand:INT1 0 "gpc_reg_operand" "")
208                    (match_operand:INT1 1 "memory_operand" ""))
209               (set (match_dup 1)
210                    (unspec:INT1
211                      [(FETCHOP:INT1 (match_dup 1)
212                         (match_operand:INT1 2 "<fetchop_pred>" ""))]
213                      UNSPEC_ATOMIC))
214               (clobber (scratch:INT1))
215               (clobber (scratch:CC))])]
216   "TARGET_POWERPC"
217   "
219   if (<MODE>mode != SImode && <MODE>mode != DImode)
220     {
221       if (PPC405_ERRATUM77)
222         FAIL;
223       rs6000_emit_sync (<CODE>, <MODE>mode, operands[1], operands[2],
224                         operands[0], NULL_RTX, true);
225       DONE;
226     }
229 (define_insn_and_split "*sync_old_<fetchop_name>si_internal"
230   [(set (match_operand:SI 0 "gpc_reg_operand" "=&r")
231         (match_operand:SI 1 "memory_operand" "+Z"))
232    (set (match_dup 1)
233         (unspec:SI
234           [(FETCHOP:SI (match_dup 1)
235              (match_operand:SI 2 "<fetchop_pred>" "<fetchopsi_constr>"))]
236           UNSPEC_ATOMIC))
237    (clobber (match_scratch:SI 3 "=&b"))
238    (clobber (match_scratch:CC 4 "=&x"))]
239   "TARGET_POWERPC"
240   "#"
241   "&& reload_completed"
242   [(const_int 0)]
244   rs6000_split_atomic_op (<CODE>, operands[1], operands[2],
245                           operands[0], NULL_RTX, operands[3]);
246   DONE;
249 (define_insn_and_split "*sync_old_<fetchop_name>di_internal"
250   [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
251         (match_operand:DI 1 "memory_operand" "+Z"))
252    (set (match_dup 1)
253         (unspec:DI
254           [(FETCHOP:DI (match_dup 1)
255              (match_operand:DI 2 "<fetchop_pred>" "<fetchopdi_constr>"))]
256           UNSPEC_ATOMIC))
257    (clobber (match_scratch:DI 3 "=&b"))
258    (clobber (match_scratch:CC 4 "=&x"))]
259   "TARGET_POWERPC"
260   "#"
261   "&& reload_completed"
262   [(const_int 0)]
264   rs6000_split_atomic_op (<CODE>, operands[1], operands[2],
265                           operands[0], NULL_RTX, operands[3]);
266   DONE;
269 (define_expand "sync_old_nand<mode>"
270   [(parallel [(set (match_operand:INT1 0 "gpc_reg_operand" "")
271                    (match_operand:INT1 1 "memory_operand" ""))
272               (set (match_dup 1)
273                    (unspec:INT1
274                      [(and:INT1 (not:INT1 (match_dup 1))
275                         (match_operand:INT1 2 "gpc_reg_operand" ""))]
276                      UNSPEC_ATOMIC))
277               (clobber (scratch:INT1))
278               (clobber (scratch:CC))])]
279   "TARGET_POWERPC"
280   "
282   if (<MODE>mode != SImode && <MODE>mode != DImode)
283     {
284       if (PPC405_ERRATUM77)
285         FAIL;
286       rs6000_emit_sync (AND, <MODE>mode,
287                         gen_rtx_NOT (<MODE>mode, operands[1]),
288                         operands[2],
289                         operands[0], NULL_RTX, true);
290       DONE;
291     }
294 (define_insn_and_split "*sync_old_nand<mode>_internal"
295   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
296         (match_operand:GPR 1 "memory_operand" "+Z"))
297    (set (match_dup 1)
298         (unspec:GPR
299           [(and:GPR (not:GPR (match_dup 1))
300              (match_operand:GPR 2 "gpc_reg_operand" "r"))]
301           UNSPEC_ATOMIC))
302    (clobber (match_scratch:GPR 3 "=&r"))
303    (clobber (match_scratch:CC 4 "=&x"))]
304   "TARGET_POWERPC"
305   "#"
306   "&& reload_completed"
307   [(const_int 0)]
309   rs6000_split_atomic_op (NOT, operands[1], operands[2],
310                           operands[0], NULL_RTX, operands[3]);
311   DONE;
314 (define_expand "sync_new_<fetchop_name><mode>"
315   [(parallel [(set (match_operand:INT1 0 "gpc_reg_operand" "")
316                    (FETCHOP:INT1
317                      (match_operand:INT1 1 "memory_operand" "")
318                      (match_operand:INT1 2 "<fetchop_pred>" "")))
319               (set (match_dup 1)
320                    (unspec:INT1
321                      [(FETCHOP:INT1 (match_dup 1) (match_dup 2))]
322                      UNSPEC_ATOMIC))
323               (clobber (scratch:INT1))
324               (clobber (scratch:CC))])]
325   "TARGET_POWERPC"
326   "
328   if (<MODE>mode != SImode && <MODE>mode != DImode)
329     {
330       if (PPC405_ERRATUM77)
331         FAIL;
332       rs6000_emit_sync (<CODE>, <MODE>mode, operands[1], operands[2],
333                         NULL_RTX, operands[0], true);
334       DONE;
335     }
338 (define_insn_and_split "*sync_new_<fetchop_name>si_internal"
339   [(set (match_operand:SI 0 "gpc_reg_operand" "=&r")
340         (FETCHOP:SI
341           (match_operand:SI 1 "memory_operand" "+Z")
342           (match_operand:SI 2 "<fetchop_pred>" "<fetchopsi_constr>")))
343    (set (match_dup 1)
344         (unspec:SI
345           [(FETCHOP:SI (match_dup 1) (match_dup 2))]
346           UNSPEC_ATOMIC))
347    (clobber (match_scratch:SI 3 "=&b"))
348    (clobber (match_scratch:CC 4 "=&x"))]
349   "TARGET_POWERPC"
350   "#"
351   "&& reload_completed"
352   [(const_int 0)]
354   rs6000_split_atomic_op (<CODE>, operands[1], operands[2],
355                           NULL_RTX, operands[0], operands[3]);
356   DONE;
359 (define_insn_and_split "*sync_new_<fetchop_name>di_internal"
360   [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
361         (FETCHOP:DI
362           (match_operand:DI 1 "memory_operand" "+Z")
363           (match_operand:DI 2 "<fetchop_pred>" "<fetchopdi_constr>")))
364    (set (match_dup 1)
365         (unspec:DI
366           [(FETCHOP:DI (match_dup 1) (match_dup 2))]
367           UNSPEC_ATOMIC))
368    (clobber (match_scratch:DI 3 "=&b"))
369    (clobber (match_scratch:CC 4 "=&x"))]
370   "TARGET_POWERPC"
371   "#"
372   "&& reload_completed"
373   [(const_int 0)]
375   rs6000_split_atomic_op (<CODE>, operands[1], operands[2],
376                           NULL_RTX, operands[0], operands[3]);
377   DONE;
380 (define_expand "sync_new_nand<mode>"
381   [(parallel [(set (match_operand:INT1 0 "gpc_reg_operand" "")
382                    (and:INT1
383                      (not:INT1 (match_operand:INT1 1 "memory_operand" ""))
384                      (match_operand:INT1 2 "gpc_reg_operand" "")))
385               (set (match_dup 1)
386                    (unspec:INT1
387                      [(and:INT1 (not:INT1 (match_dup 1)) (match_dup 2))]
388                      UNSPEC_ATOMIC))
389               (clobber (scratch:INT1))
390               (clobber (scratch:CC))])]
391   "TARGET_POWERPC"
392   "
394   if (<MODE>mode != SImode && <MODE>mode != DImode)
395     {
396       if (PPC405_ERRATUM77)
397         FAIL;
398       rs6000_emit_sync (AND, <MODE>mode,
399                         gen_rtx_NOT (<MODE>mode, operands[1]),
400                         operands[2],
401                         NULL_RTX, operands[0], true);
402       DONE;
403     }
406 (define_insn_and_split "*sync_new_nand<mode>_internal"
407   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
408         (and:GPR
409           (not:GPR (match_operand:GPR 1 "memory_operand" "+Z"))
410           (match_operand:GPR 2 "gpc_reg_operand" "r")))
411    (set (match_dup 1)
412         (unspec:GPR
413           [(and:GPR (not:GPR (match_dup 1)) (match_dup 2))]
414           UNSPEC_ATOMIC))
415    (clobber (match_scratch:GPR 3 "=&r"))
416    (clobber (match_scratch:CC 4 "=&x"))]
417   "TARGET_POWERPC"
418   "#"
419   "&& reload_completed"
420   [(const_int 0)]
422   rs6000_split_atomic_op (NOT, operands[1], operands[2],
423                           NULL_RTX, operands[0], operands[3]);
424   DONE;
427 ; and<mode> without cr0 clobber to avoid generation of additional clobber 
428 ; in atomic splitters causing internal consistency failure.
429 ; cr0 already clobbered by larx/stcx.
430 (define_insn "*atomic_andsi"
431   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
432         (unspec:SI [(match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r")
433                     (match_operand:SI 2 "and_operand" "?r,T,K,L")]
434                     UNSPEC_AND))]
435   ""
436   "@
437    and %0,%1,%2
438    {rlinm|rlwinm} %0,%1,0,%m2,%M2
439    {andil.|andi.} %0,%1,%b2
440    {andiu.|andis.} %0,%1,%u2"
441   [(set_attr "type" "*,*,compare,compare")])
443 (define_insn "*atomic_anddi"
444   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r")
445         (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r")
446                     (match_operand:DI 2 "and_operand" "?r,S,T,K,J")]
447                     UNSPEC_AND))]
448   "TARGET_POWERPC64"
449   "@
450    and %0,%1,%2
451    rldic%B2 %0,%1,0,%S2
452    rlwinm %0,%1,0,%m2,%M2
453    andi. %0,%1,%b2
454    andis. %0,%1,%u2"
455   [(set_attr "type" "*,*,*,compare,compare")
456    (set_attr "length" "4,4,4,4,4")])
458 ; the sync_*_internal patterns all have these operands:
459 ; 0 - memory location
460 ; 1 - operand
461 ; 2 - value in memory after operation
462 ; 3 - value in memory immediately before operation
464 (define_insn "*sync_addshort_internal"
465   [(set (match_operand:SI 2 "gpc_reg_operand" "=&r")
466         (ior:SI (and:SI (plus:SI (match_operand:SI 0 "memory_operand" "+Z")
467                                  (match_operand:SI 1 "add_operand" "rI"))
468                         (match_operand:SI 4 "gpc_reg_operand" "r"))
469                 (and:SI (not:SI (match_dup 4)) (match_dup 0))))
470    (set (match_operand:SI 3 "gpc_reg_operand" "=&b") (match_dup 0))
471    (set (match_dup 0)
472         (unspec:SI [(ior:SI (and:SI (plus:SI (match_dup 0) (match_dup 1))
473                                     (match_dup 4))
474                             (and:SI (not:SI (match_dup 4)) (match_dup 0)))]
475                    UNSPEC_SYNC_OP))
476    (clobber (match_scratch:CC 5 "=&x"))
477    (clobber (match_scratch:SI 6 "=&r"))]
478   "TARGET_POWERPC && !PPC405_ERRATUM77"
479   "lwarx %3,%y0\n\tadd%I1 %2,%3,%1\n\tandc %6,%3,%4\n\tand %2,%2,%4\n\tor %2,%2,%6\n\tstwcx. %2,%y0\n\tbne- $-24"
480   [(set_attr "length" "28")])
482 (define_insn "*sync_subshort_internal"
483   [(set (match_operand:SI 2 "gpc_reg_operand" "=&r")
484         (ior:SI (and:SI (minus:SI (match_operand:SI 0 "memory_operand" "+Z")
485                                   (match_operand:SI 1 "add_operand" "rI"))
486                         (match_operand:SI 4 "gpc_reg_operand" "r"))
487                 (and:SI (not:SI (match_dup 4)) (match_dup 0))))
488    (set (match_operand:SI 3 "gpc_reg_operand" "=&b") (match_dup 0))
489    (set (match_dup 0)
490         (unspec:SI [(ior:SI (and:SI (minus:SI (match_dup 0) (match_dup 1))
491                                     (match_dup 4))
492                             (and:SI (not:SI (match_dup 4)) (match_dup 0)))]
493                    UNSPEC_SYNC_OP))
494    (clobber (match_scratch:CC 5 "=&x"))
495    (clobber (match_scratch:SI 6 "=&r"))]
496   "TARGET_POWERPC && !PPC405_ERRATUM77"
497   "lwarx %3,%y0\n\tsubf %2,%1,%3\n\tandc %6,%3,%4\n\tand %2,%2,%4\n\tor %2,%2,%6\n\tstwcx. %2,%y0\n\tbne- $-24"
498   [(set_attr "length" "28")])
500 (define_insn "*sync_andsi_internal"
501   [(set (match_operand:SI 2 "gpc_reg_operand" "=&r,&r,&r,&r")
502         (and:SI (match_operand:SI 0 "memory_operand" "+Z,Z,Z,Z")
503                 (match_operand:SI 1 "and_operand" "r,T,K,L")))
504    (set (match_operand:SI 3 "gpc_reg_operand" "=&b,&b,&b,&b") (match_dup 0))
505    (set (match_dup 0)
506         (unspec:SI [(and:SI (match_dup 0) (match_dup 1))]
507                    UNSPEC_SYNC_OP))
508    (clobber (match_scratch:CC 4 "=&x,&x,&x,&x"))]
509   "TARGET_POWERPC && !PPC405_ERRATUM77"
510   "@
511    lwarx %3,%y0\n\tand %2,%3,%1\n\tstwcx. %2,%y0\n\tbne- $-12
512    lwarx %3,%y0\n\trlwinm %2,%3,0,%m1,%M1\n\tstwcx. %2,%y0\n\tbne- $-12
513    lwarx %3,%y0\n\tandi. %2,%3,%b1\n\tstwcx. %2,%y0\n\tbne- $-12
514    lwarx %3,%y0\n\tandis. %2,%3,%u1\n\tstwcx. %2,%y0\n\tbne- $-12"
515   [(set_attr "length" "16,16,16,16")])
517 (define_insn "*sync_boolsi_internal"
518   [(set (match_operand:SI 2 "gpc_reg_operand" "=&r,&r,&r")
519         (match_operator:SI 4 "boolean_or_operator"
520          [(match_operand:SI 0 "memory_operand" "+Z,Z,Z")
521           (match_operand:SI 1 "logical_operand" "r,K,L")]))
522    (set (match_operand:SI 3 "gpc_reg_operand" "=&b,&b,&b") (match_dup 0))
523    (set (match_dup 0) (unspec:SI [(match_dup 4)] UNSPEC_SYNC_OP))
524    (clobber (match_scratch:CC 5 "=&x,&x,&x"))]
525   "TARGET_POWERPC && !PPC405_ERRATUM77"
526   "@
527    lwarx %3,%y0\n\t%q4 %2,%3,%1\n\tstwcx. %2,%y0\n\tbne- $-12
528    lwarx %3,%y0\n\t%q4i %2,%3,%b1\n\tstwcx. %2,%y0\n\tbne- $-12
529    lwarx %3,%y0\n\t%q4is %2,%3,%u1\n\tstwcx. %2,%y0\n\tbne- $-12"
530   [(set_attr "length" "16,16,16")])
532 ; This pattern could also take immediate values of operand 1,
533 ; since the non-NOT version of the operator is used; but this is not
534 ; very useful, since in practice operand 1 is a full 32-bit value.
535 ; Likewise, operand 5 is in practice either <= 2^16 or it is a register.
536 (define_insn "*sync_boolcshort_internal"
537   [(set (match_operand:SI 2 "gpc_reg_operand" "=&r")
538         (match_operator:SI 4 "boolean_operator"
539          [(xor:SI (match_operand:SI 0 "memory_operand" "+Z")
540                   (match_operand:SI 5 "logical_operand" "rK"))
541           (match_operand:SI 1 "gpc_reg_operand" "r")]))
542    (set (match_operand:SI 3 "gpc_reg_operand" "=&b") (match_dup 0))
543    (set (match_dup 0) (unspec:SI [(match_dup 4)] UNSPEC_SYNC_OP))
544    (clobber (match_scratch:CC 6 "=&x"))]
545   "TARGET_POWERPC && !PPC405_ERRATUM77"
546   "lwarx %3,%y0\n\txor%I2 %2,%3,%5\n\t%q4 %2,%2,%1\n\tstwcx. %2,%y0\n\tbne- $-16"
547   [(set_attr "length" "20")])
549 (define_insn "isync"
550   [(set (mem:BLK (match_scratch 0 "X"))
551         (unspec_volatile:BLK [(mem:BLK (match_scratch 1 "X"))] UNSPEC_ISYNC))]
552   ""
553   "{ics|isync}"
554   [(set_attr "type" "isync")])
556 (define_expand "sync_lock_release<mode>"
557   [(set (match_operand:INT 0 "memory_operand")
558         (match_operand:INT 1 "any_operand"))]
559   ""
560   "
562   emit_insn (gen_lwsync ());
563   emit_move_insn (operands[0], operands[1]);
564   DONE;
567 ; Some AIX assemblers don't accept lwsync, so we use a .long.
568 (define_insn "lwsync"
569   [(set (mem:BLK (match_scratch 0 "X"))
570         (unspec_volatile:BLK [(mem:BLK (match_scratch 1 "X"))] UNSPEC_LWSYNC))]
571   ""
573   if (TARGET_NO_LWSYNC)
574     return "sync";
575   else
576     return ".long 0x7c2004ac";
578   [(set_attr "type" "sync")])