1 ;; Machine description for ARM processor synchronization primitives.
2 ;; Copyright (C) 2010 Free Software Foundation, Inc.
3 ;; Written by Marcus Shawcroft (marcus.shawcroft@arm.com)
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 by
9 ;; the Free Software Foundation; either version 3, or (at your option)
12 ;; GCC is distributed in the hope that it will be useful, but
13 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 ;; 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 COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>. */
21 ;; ARMV6 introduced ldrex and strex instruction. These instruction
22 ;; access SI width data. In order to implement synchronization
23 ;; primitives for the narrower QI and HI modes we insert appropriate
24 ;; AND/OR sequences into the synchronization loop to mask out the
25 ;; relevant component of an SI access.
27 (define_expand "memory_barrier"
29 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))]
30 "TARGET_HAVE_MEMORY_BARRIER"
32 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
33 MEM_VOLATILE_P (operands[0]) = 1;
36 (define_expand "sync_compare_and_swapsi"
37 [(set (match_operand:SI 0 "s_register_operand")
38 (unspec_volatile:SI [(match_operand:SI 1 "memory_operand")
39 (match_operand:SI 2 "s_register_operand")
40 (match_operand:SI 3 "s_register_operand")]
41 VUNSPEC_SYNC_COMPARE_AND_SWAP))]
42 "TARGET_HAVE_LDREX && TARGET_HAVE_MEMORY_BARRIER"
44 struct arm_sync_generator generator;
45 generator.op = arm_sync_generator_omrn;
46 generator.u.omrn = gen_arm_sync_compare_and_swapsi;
47 arm_expand_sync (SImode, &generator, operands[0], operands[1], operands[2],
52 (define_mode_iterator NARROW [QI HI])
54 (define_expand "sync_compare_and_swap<mode>"
55 [(set (match_operand:NARROW 0 "s_register_operand")
56 (unspec_volatile:NARROW [(match_operand:NARROW 1 "memory_operand")
57 (match_operand:NARROW 2 "s_register_operand")
58 (match_operand:NARROW 3 "s_register_operand")]
59 VUNSPEC_SYNC_COMPARE_AND_SWAP))]
60 "TARGET_HAVE_LDREXBHD && TARGET_HAVE_MEMORY_BARRIER"
62 struct arm_sync_generator generator;
63 generator.op = arm_sync_generator_omrn;
64 generator.u.omrn = gen_arm_sync_compare_and_swap<mode>;
65 arm_expand_sync (<MODE>mode, &generator, operands[0], operands[1],
66 operands[2], operands[3]);
70 (define_expand "sync_lock_test_and_setsi"
71 [(match_operand:SI 0 "s_register_operand")
72 (match_operand:SI 1 "memory_operand")
73 (match_operand:SI 2 "s_register_operand")]
74 "TARGET_HAVE_LDREX && TARGET_HAVE_MEMORY_BARRIER"
76 struct arm_sync_generator generator;
77 generator.op = arm_sync_generator_omn;
78 generator.u.omn = gen_arm_sync_lock_test_and_setsi;
79 arm_expand_sync (SImode, &generator, operands[0], operands[1], NULL,
84 (define_expand "sync_lock_test_and_set<mode>"
85 [(match_operand:NARROW 0 "s_register_operand")
86 (match_operand:NARROW 1 "memory_operand")
87 (match_operand:NARROW 2 "s_register_operand")]
88 "TARGET_HAVE_LDREXBHD && TARGET_HAVE_MEMORY_BARRIER"
90 struct arm_sync_generator generator;
91 generator.op = arm_sync_generator_omn;
92 generator.u.omn = gen_arm_sync_lock_test_and_set<mode>;
93 arm_expand_sync (<MODE>mode, &generator, operands[0], operands[1], NULL,
98 (define_code_iterator syncop [plus minus ior xor and])
100 (define_code_attr sync_optab [(ior "ior")
106 (define_code_attr sync_clobber [(ior "=&r")
112 (define_code_attr sync_t2_reqd [(ior "4")
118 (define_expand "sync_<sync_optab>si"
119 [(match_operand:SI 0 "memory_operand")
120 (match_operand:SI 1 "s_register_operand")
121 (syncop:SI (match_dup 0) (match_dup 1))]
122 "TARGET_HAVE_LDREX && TARGET_HAVE_MEMORY_BARRIER"
124 struct arm_sync_generator generator;
125 generator.op = arm_sync_generator_omn;
126 generator.u.omn = gen_arm_sync_new_<sync_optab>si;
127 arm_expand_sync (SImode, &generator, NULL, operands[0], NULL, operands[1]);
131 (define_expand "sync_nandsi"
132 [(match_operand:SI 0 "memory_operand")
133 (match_operand:SI 1 "s_register_operand")
134 (not:SI (and:SI (match_dup 0) (match_dup 1)))]
135 "TARGET_HAVE_LDREX && TARGET_HAVE_MEMORY_BARRIER"
137 struct arm_sync_generator generator;
138 generator.op = arm_sync_generator_omn;
139 generator.u.omn = gen_arm_sync_new_nandsi;
140 arm_expand_sync (SImode, &generator, NULL, operands[0], NULL, operands[1]);
144 (define_expand "sync_<sync_optab><mode>"
145 [(match_operand:NARROW 0 "memory_operand")
146 (match_operand:NARROW 1 "s_register_operand")
147 (syncop:NARROW (match_dup 0) (match_dup 1))]
148 "TARGET_HAVE_LDREXBHD && TARGET_HAVE_MEMORY_BARRIER"
150 struct arm_sync_generator generator;
151 generator.op = arm_sync_generator_omn;
152 generator.u.omn = gen_arm_sync_new_<sync_optab><mode>;
153 arm_expand_sync (<MODE>mode, &generator, NULL, operands[0], NULL,
158 (define_expand "sync_nand<mode>"
159 [(match_operand:NARROW 0 "memory_operand")
160 (match_operand:NARROW 1 "s_register_operand")
161 (not:NARROW (and:NARROW (match_dup 0) (match_dup 1)))]
162 "TARGET_HAVE_LDREXBHD && TARGET_HAVE_MEMORY_BARRIER"
164 struct arm_sync_generator generator;
165 generator.op = arm_sync_generator_omn;
166 generator.u.omn = gen_arm_sync_new_nand<mode>;
167 arm_expand_sync (<MODE>mode, &generator, NULL, operands[0], NULL,
172 (define_expand "sync_new_<sync_optab>si"
173 [(match_operand:SI 0 "s_register_operand")
174 (match_operand:SI 1 "memory_operand")
175 (match_operand:SI 2 "s_register_operand")
176 (syncop:SI (match_dup 1) (match_dup 2))]
177 "TARGET_HAVE_LDREX && TARGET_HAVE_MEMORY_BARRIER"
179 struct arm_sync_generator generator;
180 generator.op = arm_sync_generator_omn;
181 generator.u.omn = gen_arm_sync_new_<sync_optab>si;
182 arm_expand_sync (SImode, &generator, operands[0], operands[1], NULL,
187 (define_expand "sync_new_nandsi"
188 [(match_operand:SI 0 "s_register_operand")
189 (match_operand:SI 1 "memory_operand")
190 (match_operand:SI 2 "s_register_operand")
191 (not:SI (and:SI (match_dup 1) (match_dup 2)))]
192 "TARGET_HAVE_LDREX && TARGET_HAVE_MEMORY_BARRIER"
194 struct arm_sync_generator generator;
195 generator.op = arm_sync_generator_omn;
196 generator.u.omn = gen_arm_sync_new_nandsi;
197 arm_expand_sync (SImode, &generator, operands[0], operands[1], NULL,
202 (define_expand "sync_new_<sync_optab><mode>"
203 [(match_operand:NARROW 0 "s_register_operand")
204 (match_operand:NARROW 1 "memory_operand")
205 (match_operand:NARROW 2 "s_register_operand")
206 (syncop:NARROW (match_dup 1) (match_dup 2))]
207 "TARGET_HAVE_LDREXBHD && TARGET_HAVE_MEMORY_BARRIER"
209 struct arm_sync_generator generator;
210 generator.op = arm_sync_generator_omn;
211 generator.u.omn = gen_arm_sync_new_<sync_optab><mode>;
212 arm_expand_sync (<MODE>mode, &generator, operands[0], operands[1],
217 (define_expand "sync_new_nand<mode>"
218 [(match_operand:NARROW 0 "s_register_operand")
219 (match_operand:NARROW 1 "memory_operand")
220 (match_operand:NARROW 2 "s_register_operand")
221 (not:NARROW (and:NARROW (match_dup 1) (match_dup 2)))]
222 "TARGET_HAVE_LDREXBHD && TARGET_HAVE_MEMORY_BARRIER"
224 struct arm_sync_generator generator;
225 generator.op = arm_sync_generator_omn;
226 generator.u.omn = gen_arm_sync_new_nand<mode>;
227 arm_expand_sync (<MODE>mode, &generator, operands[0], operands[1],
232 (define_expand "sync_old_<sync_optab>si"
233 [(match_operand:SI 0 "s_register_operand")
234 (match_operand:SI 1 "memory_operand")
235 (match_operand:SI 2 "s_register_operand")
236 (syncop:SI (match_dup 1) (match_dup 2))]
237 "TARGET_HAVE_LDREX && TARGET_HAVE_MEMORY_BARRIER"
239 struct arm_sync_generator generator;
240 generator.op = arm_sync_generator_omn;
241 generator.u.omn = gen_arm_sync_old_<sync_optab>si;
242 arm_expand_sync (SImode, &generator, operands[0], operands[1], NULL,
247 (define_expand "sync_old_nandsi"
248 [(match_operand:SI 0 "s_register_operand")
249 (match_operand:SI 1 "memory_operand")
250 (match_operand:SI 2 "s_register_operand")
251 (not:SI (and:SI (match_dup 1) (match_dup 2)))]
252 "TARGET_HAVE_LDREX && TARGET_HAVE_MEMORY_BARRIER"
254 struct arm_sync_generator generator;
255 generator.op = arm_sync_generator_omn;
256 generator.u.omn = gen_arm_sync_old_nandsi;
257 arm_expand_sync (SImode, &generator, operands[0], operands[1], NULL,
262 (define_expand "sync_old_<sync_optab><mode>"
263 [(match_operand:NARROW 0 "s_register_operand")
264 (match_operand:NARROW 1 "memory_operand")
265 (match_operand:NARROW 2 "s_register_operand")
266 (syncop:NARROW (match_dup 1) (match_dup 2))]
267 "TARGET_HAVE_LDREXBHD && TARGET_HAVE_MEMORY_BARRIER"
269 struct arm_sync_generator generator;
270 generator.op = arm_sync_generator_omn;
271 generator.u.omn = gen_arm_sync_old_<sync_optab><mode>;
272 arm_expand_sync (<MODE>mode, &generator, operands[0], operands[1],
277 (define_expand "sync_old_nand<mode>"
278 [(match_operand:NARROW 0 "s_register_operand")
279 (match_operand:NARROW 1 "memory_operand")
280 (match_operand:NARROW 2 "s_register_operand")
281 (not:NARROW (and:NARROW (match_dup 1) (match_dup 2)))]
282 "TARGET_HAVE_LDREXBHD && TARGET_HAVE_MEMORY_BARRIER"
284 struct arm_sync_generator generator;
285 generator.op = arm_sync_generator_omn;
286 generator.u.omn = gen_arm_sync_old_nand<mode>;
287 arm_expand_sync (<MODE>mode, &generator, operands[0], operands[1],
292 (define_insn "arm_sync_compare_and_swapsi"
293 [(set (match_operand:SI 0 "s_register_operand" "=&r")
295 [(match_operand:SI 1 "arm_sync_memory_operand" "+Q")
296 (match_operand:SI 2 "s_register_operand" "r")
297 (match_operand:SI 3 "s_register_operand" "r")]
298 VUNSPEC_SYNC_COMPARE_AND_SWAP))
299 (set (match_dup 1) (unspec_volatile:SI [(match_dup 2)]
300 VUNSPEC_SYNC_COMPARE_AND_SWAP))
301 (set (reg:CC CC_REGNUM) (unspec_volatile:CC [(match_dup 1)]
302 VUNSPEC_SYNC_COMPARE_AND_SWAP))
304 "TARGET_HAVE_LDREX && TARGET_HAVE_MEMORY_BARRIER"
306 return arm_output_sync_insn (insn, operands);
308 [(set_attr "sync_result" "0")
309 (set_attr "sync_memory" "1")
310 (set_attr "sync_required_value" "2")
311 (set_attr "sync_new_value" "3")
312 (set_attr "sync_t1" "0")
313 (set_attr "conds" "clob")
314 (set_attr "predicable" "no")])
316 (define_insn "arm_sync_compare_and_swap<mode>"
317 [(set (match_operand:SI 0 "s_register_operand" "=&r")
319 (unspec_volatile:NARROW
320 [(match_operand:NARROW 1 "arm_sync_memory_operand" "+Q")
321 (match_operand:SI 2 "s_register_operand" "r")
322 (match_operand:SI 3 "s_register_operand" "r")]
323 VUNSPEC_SYNC_COMPARE_AND_SWAP)))
324 (set (match_dup 1) (unspec_volatile:NARROW [(match_dup 2)]
325 VUNSPEC_SYNC_COMPARE_AND_SWAP))
326 (set (reg:CC CC_REGNUM) (unspec_volatile:CC [(match_dup 1)]
327 VUNSPEC_SYNC_COMPARE_AND_SWAP))
329 "TARGET_HAVE_LDREXBHD && TARGET_HAVE_MEMORY_BARRIER"
331 return arm_output_sync_insn (insn, operands);
333 [(set_attr "sync_result" "0")
334 (set_attr "sync_memory" "1")
335 (set_attr "sync_required_value" "2")
336 (set_attr "sync_new_value" "3")
337 (set_attr "sync_t1" "0")
338 (set_attr "conds" "clob")
339 (set_attr "predicable" "no")])
341 (define_insn "arm_sync_lock_test_and_setsi"
342 [(set (match_operand:SI 0 "s_register_operand" "=&r")
343 (match_operand:SI 1 "arm_sync_memory_operand" "+Q"))
345 (unspec_volatile:SI [(match_operand:SI 2 "s_register_operand" "r")]
347 (clobber (reg:CC CC_REGNUM))
348 (clobber (match_scratch:SI 3 "=&r"))]
349 "TARGET_HAVE_LDREX && TARGET_HAVE_MEMORY_BARRIER"
351 return arm_output_sync_insn (insn, operands);
353 [(set_attr "sync_release_barrier" "no")
354 (set_attr "sync_result" "0")
355 (set_attr "sync_memory" "1")
356 (set_attr "sync_new_value" "2")
357 (set_attr "sync_t1" "0")
358 (set_attr "sync_t2" "3")
359 (set_attr "conds" "clob")
360 (set_attr "predicable" "no")])
362 (define_insn "arm_sync_lock_test_and_set<mode>"
363 [(set (match_operand:SI 0 "s_register_operand" "=&r")
364 (zero_extend:SI (match_operand:NARROW 1 "arm_sync_memory_operand" "+Q")))
366 (unspec_volatile:NARROW [(match_operand:SI 2 "s_register_operand" "r")]
368 (clobber (reg:CC CC_REGNUM))
369 (clobber (match_scratch:SI 3 "=&r"))]
370 "TARGET_HAVE_LDREX && TARGET_HAVE_MEMORY_BARRIER"
372 return arm_output_sync_insn (insn, operands);
374 [(set_attr "sync_release_barrier" "no")
375 (set_attr "sync_result" "0")
376 (set_attr "sync_memory" "1")
377 (set_attr "sync_new_value" "2")
378 (set_attr "sync_t1" "0")
379 (set_attr "sync_t2" "3")
380 (set_attr "conds" "clob")
381 (set_attr "predicable" "no")])
383 (define_insn "arm_sync_new_<sync_optab>si"
384 [(set (match_operand:SI 0 "s_register_operand" "=&r")
385 (unspec_volatile:SI [(syncop:SI
386 (match_operand:SI 1 "arm_sync_memory_operand" "+Q")
387 (match_operand:SI 2 "s_register_operand" "r"))
389 VUNSPEC_SYNC_NEW_OP))
391 (unspec_volatile:SI [(match_dup 1) (match_dup 2)]
392 VUNSPEC_SYNC_NEW_OP))
393 (clobber (reg:CC CC_REGNUM))
394 (clobber (match_scratch:SI 3 "=&r"))]
395 "TARGET_HAVE_LDREX && TARGET_HAVE_MEMORY_BARRIER"
397 return arm_output_sync_insn (insn, operands);
399 [(set_attr "sync_result" "0")
400 (set_attr "sync_memory" "1")
401 (set_attr "sync_new_value" "2")
402 (set_attr "sync_t1" "0")
403 (set_attr "sync_t2" "3")
404 (set_attr "sync_op" "<sync_optab>")
405 (set_attr "conds" "clob")
406 (set_attr "predicable" "no")])
408 (define_insn "arm_sync_new_nandsi"
409 [(set (match_operand:SI 0 "s_register_operand" "=&r")
410 (unspec_volatile:SI [(not:SI (and:SI
411 (match_operand:SI 1 "arm_sync_memory_operand" "+Q")
412 (match_operand:SI 2 "s_register_operand" "r")))
414 VUNSPEC_SYNC_NEW_OP))
416 (unspec_volatile:SI [(match_dup 1) (match_dup 2)]
417 VUNSPEC_SYNC_NEW_OP))
418 (clobber (reg:CC CC_REGNUM))
419 (clobber (match_scratch:SI 3 "=&r"))]
420 "TARGET_HAVE_LDREX && TARGET_HAVE_MEMORY_BARRIER"
422 return arm_output_sync_insn (insn, operands);
424 [(set_attr "sync_result" "0")
425 (set_attr "sync_memory" "1")
426 (set_attr "sync_new_value" "2")
427 (set_attr "sync_t1" "0")
428 (set_attr "sync_t2" "3")
429 (set_attr "sync_op" "nand")
430 (set_attr "conds" "clob")
431 (set_attr "predicable" "no")])
433 (define_insn "arm_sync_new_<sync_optab><mode>"
434 [(set (match_operand:SI 0 "s_register_operand" "=&r")
435 (unspec_volatile:SI [(syncop:SI
437 (match_operand:NARROW 1 "arm_sync_memory_operand" "+Q"))
438 (match_operand:SI 2 "s_register_operand" "r"))
440 VUNSPEC_SYNC_NEW_OP))
442 (unspec_volatile:NARROW [(match_dup 1) (match_dup 2)]
443 VUNSPEC_SYNC_NEW_OP))
444 (clobber (reg:CC CC_REGNUM))
445 (clobber (match_scratch:SI 3 "=&r"))]
446 "TARGET_HAVE_LDREXBHD && TARGET_HAVE_MEMORY_BARRIER"
448 return arm_output_sync_insn (insn, operands);
450 [(set_attr "sync_result" "0")
451 (set_attr "sync_memory" "1")
452 (set_attr "sync_new_value" "2")
453 (set_attr "sync_t1" "0")
454 (set_attr "sync_t2" "3")
455 (set_attr "sync_op" "<sync_optab>")
456 (set_attr "conds" "clob")
457 (set_attr "predicable" "no")])
459 (define_insn "arm_sync_new_nand<mode>"
460 [(set (match_operand:SI 0 "s_register_operand" "=&r")
465 (match_operand:NARROW 1 "arm_sync_memory_operand" "+Q"))
466 (match_operand:SI 2 "s_register_operand" "r")))
467 ] VUNSPEC_SYNC_NEW_OP))
469 (unspec_volatile:NARROW [(match_dup 1) (match_dup 2)]
470 VUNSPEC_SYNC_NEW_OP))
471 (clobber (reg:CC CC_REGNUM))
472 (clobber (match_scratch:SI 3 "=&r"))]
473 "TARGET_HAVE_LDREX && TARGET_HAVE_MEMORY_BARRIER"
475 return arm_output_sync_insn (insn, operands);
477 [(set_attr "sync_result" "0")
478 (set_attr "sync_memory" "1")
479 (set_attr "sync_new_value" "2")
480 (set_attr "sync_t1" "0")
481 (set_attr "sync_t2" "3")
482 (set_attr "sync_op" "nand")
483 (set_attr "conds" "clob")
484 (set_attr "predicable" "no")])
486 (define_insn "arm_sync_old_<sync_optab>si"
487 [(set (match_operand:SI 0 "s_register_operand" "=&r")
488 (unspec_volatile:SI [(syncop:SI
489 (match_operand:SI 1 "arm_sync_memory_operand" "+Q")
490 (match_operand:SI 2 "s_register_operand" "r"))
492 VUNSPEC_SYNC_OLD_OP))
494 (unspec_volatile:SI [(match_dup 1) (match_dup 2)]
495 VUNSPEC_SYNC_OLD_OP))
496 (clobber (reg:CC CC_REGNUM))
497 (clobber (match_scratch:SI 3 "=&r"))
498 (clobber (match_scratch:SI 4 "<sync_clobber>"))]
499 "TARGET_HAVE_LDREX && TARGET_HAVE_MEMORY_BARRIER"
501 return arm_output_sync_insn (insn, operands);
503 [(set_attr "sync_result" "0")
504 (set_attr "sync_memory" "1")
505 (set_attr "sync_new_value" "2")
506 (set_attr "sync_t1" "3")
507 (set_attr "sync_t2" "<sync_t2_reqd>")
508 (set_attr "sync_op" "<sync_optab>")
509 (set_attr "conds" "clob")
510 (set_attr "predicable" "no")])
512 (define_insn "arm_sync_old_nandsi"
513 [(set (match_operand:SI 0 "s_register_operand" "=&r")
514 (unspec_volatile:SI [(not:SI (and:SI
515 (match_operand:SI 1 "arm_sync_memory_operand" "+Q")
516 (match_operand:SI 2 "s_register_operand" "r")))
518 VUNSPEC_SYNC_OLD_OP))
520 (unspec_volatile:SI [(match_dup 1) (match_dup 2)]
521 VUNSPEC_SYNC_OLD_OP))
522 (clobber (reg:CC CC_REGNUM))
523 (clobber (match_scratch:SI 3 "=&r"))
524 (clobber (match_scratch:SI 4 "=&r"))]
525 "TARGET_HAVE_LDREX && TARGET_HAVE_MEMORY_BARRIER"
527 return arm_output_sync_insn (insn, operands);
529 [(set_attr "sync_result" "0")
530 (set_attr "sync_memory" "1")
531 (set_attr "sync_new_value" "2")
532 (set_attr "sync_t1" "3")
533 (set_attr "sync_t2" "4")
534 (set_attr "sync_op" "nand")
535 (set_attr "conds" "clob")
536 (set_attr "predicable" "no")])
538 (define_insn "arm_sync_old_<sync_optab><mode>"
539 [(set (match_operand:SI 0 "s_register_operand" "=&r")
540 (unspec_volatile:SI [(syncop:SI
542 (match_operand:NARROW 1 "arm_sync_memory_operand" "+Q"))
543 (match_operand:SI 2 "s_register_operand" "r"))
545 VUNSPEC_SYNC_OLD_OP))
547 (unspec_volatile:NARROW [(match_dup 1) (match_dup 2)]
548 VUNSPEC_SYNC_OLD_OP))
549 (clobber (reg:CC CC_REGNUM))
550 (clobber (match_scratch:SI 3 "=&r"))
551 (clobber (match_scratch:SI 4 "<sync_clobber>"))]
552 "TARGET_HAVE_LDREXBHD && TARGET_HAVE_MEMORY_BARRIER"
554 return arm_output_sync_insn (insn, operands);
556 [(set_attr "sync_result" "0")
557 (set_attr "sync_memory" "1")
558 (set_attr "sync_new_value" "2")
559 (set_attr "sync_t1" "3")
560 (set_attr "sync_t2" "<sync_t2_reqd>")
561 (set_attr "sync_op" "<sync_optab>")
562 (set_attr "conds" "clob")
563 (set_attr "predicable" "no")])
565 (define_insn "arm_sync_old_nand<mode>"
566 [(set (match_operand:SI 0 "s_register_operand" "=&r")
567 (unspec_volatile:SI [(not:SI (and:SI
569 (match_operand:NARROW 1 "arm_sync_memory_operand" "+Q"))
570 (match_operand:SI 2 "s_register_operand" "r")))
572 VUNSPEC_SYNC_OLD_OP))
574 (unspec_volatile:NARROW [(match_dup 1) (match_dup 2)]
575 VUNSPEC_SYNC_OLD_OP))
576 (clobber (reg:CC CC_REGNUM))
577 (clobber (match_scratch:SI 3 "=&r"))
578 (clobber (match_scratch:SI 4 "=&r"))]
579 "TARGET_HAVE_LDREXBHD && TARGET_HAVE_MEMORY_BARRIER"
581 return arm_output_sync_insn (insn, operands);
583 [(set_attr "sync_result" "0")
584 (set_attr "sync_memory" "1")
585 (set_attr "sync_new_value" "2")
586 (set_attr "sync_t1" "3")
587 (set_attr "sync_t2" "4")
588 (set_attr "sync_op" "nand")
589 (set_attr "conds" "clob")
590 (set_attr "predicable" "no")])
592 (define_insn "*memory_barrier"
593 [(set (match_operand:BLK 0 "" "")
594 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))]
595 "TARGET_HAVE_MEMORY_BARRIER"
597 return arm_output_memory_barrier (operands);
599 [(set_attr "length" "4")
600 (set_attr "conds" "unconditional")
601 (set_attr "predicable" "no")])