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_expand "sync_<sync_optab>si"
107 [(match_operand:SI 0 "memory_operand")
108 (match_operand:SI 1 "s_register_operand")
109 (syncop:SI (match_dup 0) (match_dup 1))]
110 "TARGET_HAVE_LDREX && TARGET_HAVE_MEMORY_BARRIER"
112 struct arm_sync_generator generator;
113 generator.op = arm_sync_generator_omn;
114 generator.u.omn = gen_arm_sync_new_<sync_optab>si;
115 arm_expand_sync (SImode, &generator, NULL, operands[0], NULL, operands[1]);
119 (define_expand "sync_nandsi"
120 [(match_operand:SI 0 "memory_operand")
121 (match_operand:SI 1 "s_register_operand")
122 (not:SI (and:SI (match_dup 0) (match_dup 1)))]
123 "TARGET_HAVE_LDREX && TARGET_HAVE_MEMORY_BARRIER"
125 struct arm_sync_generator generator;
126 generator.op = arm_sync_generator_omn;
127 generator.u.omn = gen_arm_sync_new_nandsi;
128 arm_expand_sync (SImode, &generator, NULL, operands[0], NULL, operands[1]);
132 (define_expand "sync_<sync_optab><mode>"
133 [(match_operand:NARROW 0 "memory_operand")
134 (match_operand:NARROW 1 "s_register_operand")
135 (syncop:NARROW (match_dup 0) (match_dup 1))]
136 "TARGET_HAVE_LDREXBHD && TARGET_HAVE_MEMORY_BARRIER"
138 struct arm_sync_generator generator;
139 generator.op = arm_sync_generator_omn;
140 generator.u.omn = gen_arm_sync_new_<sync_optab><mode>;
141 arm_expand_sync (<MODE>mode, &generator, NULL, operands[0], NULL,
146 (define_expand "sync_nand<mode>"
147 [(match_operand:NARROW 0 "memory_operand")
148 (match_operand:NARROW 1 "s_register_operand")
149 (not:NARROW (and:NARROW (match_dup 0) (match_dup 1)))]
150 "TARGET_HAVE_LDREXBHD && TARGET_HAVE_MEMORY_BARRIER"
152 struct arm_sync_generator generator;
153 generator.op = arm_sync_generator_omn;
154 generator.u.omn = gen_arm_sync_new_nand<mode>;
155 arm_expand_sync (<MODE>mode, &generator, NULL, operands[0], NULL,
160 (define_expand "sync_new_<sync_optab>si"
161 [(match_operand:SI 0 "s_register_operand")
162 (match_operand:SI 1 "memory_operand")
163 (match_operand:SI 2 "s_register_operand")
164 (syncop:SI (match_dup 1) (match_dup 2))]
165 "TARGET_HAVE_LDREX && TARGET_HAVE_MEMORY_BARRIER"
167 struct arm_sync_generator generator;
168 generator.op = arm_sync_generator_omn;
169 generator.u.omn = gen_arm_sync_new_<sync_optab>si;
170 arm_expand_sync (SImode, &generator, operands[0], operands[1], NULL,
175 (define_expand "sync_new_nandsi"
176 [(match_operand:SI 0 "s_register_operand")
177 (match_operand:SI 1 "memory_operand")
178 (match_operand:SI 2 "s_register_operand")
179 (not:SI (and:SI (match_dup 1) (match_dup 2)))]
180 "TARGET_HAVE_LDREX && TARGET_HAVE_MEMORY_BARRIER"
182 struct arm_sync_generator generator;
183 generator.op = arm_sync_generator_omn;
184 generator.u.omn = gen_arm_sync_new_nandsi;
185 arm_expand_sync (SImode, &generator, operands[0], operands[1], NULL,
190 (define_expand "sync_new_<sync_optab><mode>"
191 [(match_operand:NARROW 0 "s_register_operand")
192 (match_operand:NARROW 1 "memory_operand")
193 (match_operand:NARROW 2 "s_register_operand")
194 (syncop:NARROW (match_dup 1) (match_dup 2))]
195 "TARGET_HAVE_LDREXBHD && TARGET_HAVE_MEMORY_BARRIER"
197 struct arm_sync_generator generator;
198 generator.op = arm_sync_generator_omn;
199 generator.u.omn = gen_arm_sync_new_<sync_optab><mode>;
200 arm_expand_sync (<MODE>mode, &generator, operands[0], operands[1],
205 (define_expand "sync_new_nand<mode>"
206 [(match_operand:NARROW 0 "s_register_operand")
207 (match_operand:NARROW 1 "memory_operand")
208 (match_operand:NARROW 2 "s_register_operand")
209 (not:NARROW (and:NARROW (match_dup 1) (match_dup 2)))]
210 "TARGET_HAVE_LDREXBHD && TARGET_HAVE_MEMORY_BARRIER"
212 struct arm_sync_generator generator;
213 generator.op = arm_sync_generator_omn;
214 generator.u.omn = gen_arm_sync_new_nand<mode>;
215 arm_expand_sync (<MODE>mode, &generator, operands[0], operands[1],
220 (define_expand "sync_old_<sync_optab>si"
221 [(match_operand:SI 0 "s_register_operand")
222 (match_operand:SI 1 "memory_operand")
223 (match_operand:SI 2 "s_register_operand")
224 (syncop:SI (match_dup 1) (match_dup 2))]
225 "TARGET_HAVE_LDREX && TARGET_HAVE_MEMORY_BARRIER"
227 struct arm_sync_generator generator;
228 generator.op = arm_sync_generator_omn;
229 generator.u.omn = gen_arm_sync_old_<sync_optab>si;
230 arm_expand_sync (SImode, &generator, operands[0], operands[1], NULL,
235 (define_expand "sync_old_nandsi"
236 [(match_operand:SI 0 "s_register_operand")
237 (match_operand:SI 1 "memory_operand")
238 (match_operand:SI 2 "s_register_operand")
239 (not:SI (and:SI (match_dup 1) (match_dup 2)))]
240 "TARGET_HAVE_LDREX && TARGET_HAVE_MEMORY_BARRIER"
242 struct arm_sync_generator generator;
243 generator.op = arm_sync_generator_omn;
244 generator.u.omn = gen_arm_sync_old_nandsi;
245 arm_expand_sync (SImode, &generator, operands[0], operands[1], NULL,
250 (define_expand "sync_old_<sync_optab><mode>"
251 [(match_operand:NARROW 0 "s_register_operand")
252 (match_operand:NARROW 1 "memory_operand")
253 (match_operand:NARROW 2 "s_register_operand")
254 (syncop:NARROW (match_dup 1) (match_dup 2))]
255 "TARGET_HAVE_LDREXBHD && TARGET_HAVE_MEMORY_BARRIER"
257 struct arm_sync_generator generator;
258 generator.op = arm_sync_generator_omn;
259 generator.u.omn = gen_arm_sync_old_<sync_optab><mode>;
260 arm_expand_sync (<MODE>mode, &generator, operands[0], operands[1],
265 (define_expand "sync_old_nand<mode>"
266 [(match_operand:NARROW 0 "s_register_operand")
267 (match_operand:NARROW 1 "memory_operand")
268 (match_operand:NARROW 2 "s_register_operand")
269 (not:NARROW (and:NARROW (match_dup 1) (match_dup 2)))]
270 "TARGET_HAVE_LDREXBHD && TARGET_HAVE_MEMORY_BARRIER"
272 struct arm_sync_generator generator;
273 generator.op = arm_sync_generator_omn;
274 generator.u.omn = gen_arm_sync_old_nand<mode>;
275 arm_expand_sync (<MODE>mode, &generator, operands[0], operands[1],
280 (define_insn "arm_sync_compare_and_swapsi"
281 [(set (match_operand:SI 0 "s_register_operand" "=&r")
283 [(match_operand:SI 1 "arm_sync_memory_operand" "+Q")
284 (match_operand:SI 2 "s_register_operand" "r")
285 (match_operand:SI 3 "s_register_operand" "r")]
286 VUNSPEC_SYNC_COMPARE_AND_SWAP))
287 (set (match_dup 1) (unspec_volatile:SI [(match_dup 2)]
288 VUNSPEC_SYNC_COMPARE_AND_SWAP))
289 (clobber:SI (match_scratch:SI 4 "=&r"))
290 (set (reg:CC CC_REGNUM) (unspec_volatile:CC [(match_dup 1)]
291 VUNSPEC_SYNC_COMPARE_AND_SWAP))
293 "TARGET_HAVE_LDREX && TARGET_HAVE_MEMORY_BARRIER"
295 return arm_output_sync_insn (insn, operands);
297 [(set_attr "sync_result" "0")
298 (set_attr "sync_memory" "1")
299 (set_attr "sync_required_value" "2")
300 (set_attr "sync_new_value" "3")
301 (set_attr "sync_t1" "0")
302 (set_attr "sync_t2" "4")
303 (set_attr "conds" "clob")
304 (set_attr "predicable" "no")])
306 (define_insn "arm_sync_compare_and_swap<mode>"
307 [(set (match_operand:SI 0 "s_register_operand" "=&r")
309 (unspec_volatile:NARROW
310 [(match_operand:NARROW 1 "arm_sync_memory_operand" "+Q")
311 (match_operand:SI 2 "s_register_operand" "r")
312 (match_operand:SI 3 "s_register_operand" "r")]
313 VUNSPEC_SYNC_COMPARE_AND_SWAP)))
314 (set (match_dup 1) (unspec_volatile:NARROW [(match_dup 2)]
315 VUNSPEC_SYNC_COMPARE_AND_SWAP))
316 (clobber:SI (match_scratch:SI 4 "=&r"))
317 (set (reg:CC CC_REGNUM) (unspec_volatile:CC [(match_dup 1)]
318 VUNSPEC_SYNC_COMPARE_AND_SWAP))
320 "TARGET_HAVE_LDREXBHD && TARGET_HAVE_MEMORY_BARRIER"
322 return arm_output_sync_insn (insn, operands);
324 [(set_attr "sync_result" "0")
325 (set_attr "sync_memory" "1")
326 (set_attr "sync_required_value" "2")
327 (set_attr "sync_new_value" "3")
328 (set_attr "sync_t1" "0")
329 (set_attr "sync_t2" "4")
330 (set_attr "conds" "clob")
331 (set_attr "predicable" "no")])
333 (define_insn "arm_sync_lock_test_and_setsi"
334 [(set (match_operand:SI 0 "s_register_operand" "=&r")
335 (match_operand:SI 1 "arm_sync_memory_operand" "+Q"))
337 (unspec_volatile:SI [(match_operand:SI 2 "s_register_operand" "r")]
339 (clobber (reg:CC CC_REGNUM))
340 (clobber (match_scratch:SI 3 "=&r"))]
341 "TARGET_HAVE_LDREX && TARGET_HAVE_MEMORY_BARRIER"
343 return arm_output_sync_insn (insn, operands);
345 [(set_attr "sync_release_barrier" "no")
346 (set_attr "sync_result" "0")
347 (set_attr "sync_memory" "1")
348 (set_attr "sync_new_value" "2")
349 (set_attr "sync_t1" "0")
350 (set_attr "sync_t2" "3")
351 (set_attr "conds" "clob")
352 (set_attr "predicable" "no")])
354 (define_insn "arm_sync_lock_test_and_set<mode>"
355 [(set (match_operand:SI 0 "s_register_operand" "=&r")
356 (zero_extend:SI (match_operand:NARROW 1 "arm_sync_memory_operand" "+Q")))
358 (unspec_volatile:NARROW [(match_operand:SI 2 "s_register_operand" "r")]
360 (clobber (reg:CC CC_REGNUM))
361 (clobber (match_scratch:SI 3 "=&r"))]
362 "TARGET_HAVE_LDREX && TARGET_HAVE_MEMORY_BARRIER"
364 return arm_output_sync_insn (insn, operands);
366 [(set_attr "sync_release_barrier" "no")
367 (set_attr "sync_result" "0")
368 (set_attr "sync_memory" "1")
369 (set_attr "sync_new_value" "2")
370 (set_attr "sync_t1" "0")
371 (set_attr "sync_t2" "3")
372 (set_attr "conds" "clob")
373 (set_attr "predicable" "no")])
375 (define_insn "arm_sync_new_<sync_optab>si"
376 [(set (match_operand:SI 0 "s_register_operand" "=&r")
377 (unspec_volatile:SI [(syncop:SI
378 (match_operand:SI 1 "arm_sync_memory_operand" "+Q")
379 (match_operand:SI 2 "s_register_operand" "r"))
381 VUNSPEC_SYNC_NEW_OP))
383 (unspec_volatile:SI [(match_dup 1) (match_dup 2)]
384 VUNSPEC_SYNC_NEW_OP))
385 (clobber (reg:CC CC_REGNUM))
386 (clobber (match_scratch:SI 3 "=&r"))]
387 "TARGET_HAVE_LDREX && TARGET_HAVE_MEMORY_BARRIER"
389 return arm_output_sync_insn (insn, operands);
391 [(set_attr "sync_result" "0")
392 (set_attr "sync_memory" "1")
393 (set_attr "sync_new_value" "2")
394 (set_attr "sync_t1" "0")
395 (set_attr "sync_t2" "3")
396 (set_attr "sync_op" "<sync_optab>")
397 (set_attr "conds" "clob")
398 (set_attr "predicable" "no")])
400 (define_insn "arm_sync_new_nandsi"
401 [(set (match_operand:SI 0 "s_register_operand" "=&r")
402 (unspec_volatile:SI [(not:SI (and:SI
403 (match_operand:SI 1 "arm_sync_memory_operand" "+Q")
404 (match_operand:SI 2 "s_register_operand" "r")))
406 VUNSPEC_SYNC_NEW_OP))
408 (unspec_volatile:SI [(match_dup 1) (match_dup 2)]
409 VUNSPEC_SYNC_NEW_OP))
410 (clobber (reg:CC CC_REGNUM))
411 (clobber (match_scratch:SI 3 "=&r"))]
412 "TARGET_HAVE_LDREX && TARGET_HAVE_MEMORY_BARRIER"
414 return arm_output_sync_insn (insn, operands);
416 [(set_attr "sync_result" "0")
417 (set_attr "sync_memory" "1")
418 (set_attr "sync_new_value" "2")
419 (set_attr "sync_t1" "0")
420 (set_attr "sync_t2" "3")
421 (set_attr "sync_op" "nand")
422 (set_attr "conds" "clob")
423 (set_attr "predicable" "no")])
425 (define_insn "arm_sync_new_<sync_optab><mode>"
426 [(set (match_operand:SI 0 "s_register_operand" "=&r")
427 (unspec_volatile:SI [(syncop:SI
429 (match_operand:NARROW 1 "arm_sync_memory_operand" "+Q"))
430 (match_operand:SI 2 "s_register_operand" "r"))
432 VUNSPEC_SYNC_NEW_OP))
434 (unspec_volatile:NARROW [(match_dup 1) (match_dup 2)]
435 VUNSPEC_SYNC_NEW_OP))
436 (clobber (reg:CC CC_REGNUM))
437 (clobber (match_scratch:SI 3 "=&r"))]
438 "TARGET_HAVE_LDREXBHD && TARGET_HAVE_MEMORY_BARRIER"
440 return arm_output_sync_insn (insn, operands);
442 [(set_attr "sync_result" "0")
443 (set_attr "sync_memory" "1")
444 (set_attr "sync_new_value" "2")
445 (set_attr "sync_t1" "0")
446 (set_attr "sync_t2" "3")
447 (set_attr "sync_op" "<sync_optab>")
448 (set_attr "conds" "clob")
449 (set_attr "predicable" "no")])
451 (define_insn "arm_sync_new_nand<mode>"
452 [(set (match_operand:SI 0 "s_register_operand" "=&r")
457 (match_operand:NARROW 1 "arm_sync_memory_operand" "+Q"))
458 (match_operand:SI 2 "s_register_operand" "r")))
459 ] VUNSPEC_SYNC_NEW_OP))
461 (unspec_volatile:NARROW [(match_dup 1) (match_dup 2)]
462 VUNSPEC_SYNC_NEW_OP))
463 (clobber (reg:CC CC_REGNUM))
464 (clobber (match_scratch:SI 3 "=&r"))]
465 "TARGET_HAVE_LDREX && TARGET_HAVE_MEMORY_BARRIER"
467 return arm_output_sync_insn (insn, operands);
469 [(set_attr "sync_result" "0")
470 (set_attr "sync_memory" "1")
471 (set_attr "sync_new_value" "2")
472 (set_attr "sync_t1" "0")
473 (set_attr "sync_t2" "3")
474 (set_attr "sync_op" "nand")
475 (set_attr "conds" "clob")
476 (set_attr "predicable" "no")])
478 (define_insn "arm_sync_old_<sync_optab>si"
479 [(set (match_operand:SI 0 "s_register_operand" "=&r")
480 (unspec_volatile:SI [(syncop:SI
481 (match_operand:SI 1 "arm_sync_memory_operand" "+Q")
482 (match_operand:SI 2 "s_register_operand" "r"))
484 VUNSPEC_SYNC_OLD_OP))
486 (unspec_volatile:SI [(match_dup 1) (match_dup 2)]
487 VUNSPEC_SYNC_OLD_OP))
488 (clobber (reg:CC CC_REGNUM))
489 (clobber (match_scratch:SI 3 "=&r"))
490 (clobber (match_scratch:SI 4 "=&r"))]
491 "TARGET_HAVE_LDREX && TARGET_HAVE_MEMORY_BARRIER"
493 return arm_output_sync_insn (insn, operands);
495 [(set_attr "sync_result" "0")
496 (set_attr "sync_memory" "1")
497 (set_attr "sync_new_value" "2")
498 (set_attr "sync_t1" "3")
499 (set_attr "sync_t2" "4")
500 (set_attr "sync_op" "<sync_optab>")
501 (set_attr "conds" "clob")
502 (set_attr "predicable" "no")])
504 (define_insn "arm_sync_old_nandsi"
505 [(set (match_operand:SI 0 "s_register_operand" "=&r")
506 (unspec_volatile:SI [(not:SI (and:SI
507 (match_operand:SI 1 "arm_sync_memory_operand" "+Q")
508 (match_operand:SI 2 "s_register_operand" "r")))
510 VUNSPEC_SYNC_OLD_OP))
512 (unspec_volatile:SI [(match_dup 1) (match_dup 2)]
513 VUNSPEC_SYNC_OLD_OP))
514 (clobber (reg:CC CC_REGNUM))
515 (clobber (match_scratch:SI 3 "=&r"))
516 (clobber (match_scratch:SI 4 "=&r"))]
517 "TARGET_HAVE_LDREX && TARGET_HAVE_MEMORY_BARRIER"
519 return arm_output_sync_insn (insn, operands);
521 [(set_attr "sync_result" "0")
522 (set_attr "sync_memory" "1")
523 (set_attr "sync_new_value" "2")
524 (set_attr "sync_t1" "3")
525 (set_attr "sync_t2" "4")
526 (set_attr "sync_op" "nand")
527 (set_attr "conds" "clob")
528 (set_attr "predicable" "no")])
530 (define_insn "arm_sync_old_<sync_optab><mode>"
531 [(set (match_operand:SI 0 "s_register_operand" "=&r")
532 (unspec_volatile:SI [(syncop:SI
534 (match_operand:NARROW 1 "arm_sync_memory_operand" "+Q"))
535 (match_operand:SI 2 "s_register_operand" "r"))
537 VUNSPEC_SYNC_OLD_OP))
539 (unspec_volatile:NARROW [(match_dup 1) (match_dup 2)]
540 VUNSPEC_SYNC_OLD_OP))
541 (clobber (reg:CC CC_REGNUM))
542 (clobber (match_scratch:SI 3 "=&r"))
543 (clobber (match_scratch:SI 4 "=&r"))]
544 "TARGET_HAVE_LDREXBHD && TARGET_HAVE_MEMORY_BARRIER"
546 return arm_output_sync_insn (insn, operands);
548 [(set_attr "sync_result" "0")
549 (set_attr "sync_memory" "1")
550 (set_attr "sync_new_value" "2")
551 (set_attr "sync_t1" "3")
552 (set_attr "sync_t2" "4")
553 (set_attr "sync_op" "<sync_optab>")
554 (set_attr "conds" "clob")
555 (set_attr "predicable" "no")])
557 (define_insn "arm_sync_old_nand<mode>"
558 [(set (match_operand:SI 0 "s_register_operand" "=&r")
559 (unspec_volatile:SI [(not:SI (and:SI
561 (match_operand:NARROW 1 "arm_sync_memory_operand" "+Q"))
562 (match_operand:SI 2 "s_register_operand" "r")))
564 VUNSPEC_SYNC_OLD_OP))
566 (unspec_volatile:NARROW [(match_dup 1) (match_dup 2)]
567 VUNSPEC_SYNC_OLD_OP))
568 (clobber (reg:CC CC_REGNUM))
569 (clobber (match_scratch:SI 3 "=&r"))
570 (clobber (match_scratch:SI 4 "=&r"))]
571 "TARGET_HAVE_LDREXBHD && TARGET_HAVE_MEMORY_BARRIER"
573 return arm_output_sync_insn (insn, operands);
575 [(set_attr "sync_result" "0")
576 (set_attr "sync_memory" "1")
577 (set_attr "sync_new_value" "2")
578 (set_attr "sync_t1" "3")
579 (set_attr "sync_t2" "4")
580 (set_attr "sync_op" "nand")
581 (set_attr "conds" "clob")
582 (set_attr "predicable" "no")])
584 (define_insn "*memory_barrier"
585 [(set (match_operand:BLK 0 "" "")
586 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))]
587 "TARGET_HAVE_MEMORY_BARRIER"
589 return arm_output_memory_barrier (operands);
591 [(set_attr "length" "4")
592 (set_attr "conds" "unconditional")
593 (set_attr "predicable" "no")])