1 /*
2  * Distributed under the Boost Software License, Version 1.0.
3  * (See accompanying file LICENSE_1_0.txt or copy at
4  * http://www.boost.org/LICENSE_1_0.txt)
5  *
6  * Copyright (c) 2009 Helge Bahmann
7  * Copyright (c) 2013 Tim Blechmann
8  * Copyright (c) 2014 Andrey Semashev
9  */
10 /*!
11  * \file   atomic/detail/ops_gcc_alpha.hpp
12  *
13  * This header contains implementation of the \c operations template.
14  */
15 
16 #ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_ALPHA_HPP_INCLUDED_
17 #define BOOST_ATOMIC_DETAIL_OPS_GCC_ALPHA_HPP_INCLUDED_
18 
19 #include <boost/memory_order.hpp>
20 #include <boost/atomic/detail/config.hpp>
21 #include <boost/atomic/detail/storage_type.hpp>
22 #include <boost/atomic/detail/operations_fwd.hpp>
23 #include <boost/atomic/capabilities.hpp>
24 
25 #ifdef BOOST_HAS_PRAGMA_ONCE
26 #pragma once
27 #endif
28 
29 namespace boost {
30 namespace atomics {
31 namespace detail {
32 
33 /*
34   Refer to http://h71000.www7.hp.com/doc/82final/5601/5601pro_004.html
35   (HP OpenVMS systems documentation) and the Alpha Architecture Reference Manual.
36  */
37 
38 /*
39     NB: The most natural thing would be to write the increment/decrement
40     operators along the following lines:
41 
42     __asm__ __volatile__
43     (
44         "1: ldl_l %0,%1 \n"
45         "addl %0,1,%0 \n"
46         "stl_c %0,%1 \n"
47         "beq %0,1b\n"
48         : "=&b" (tmp)
49         : "m" (value)
50         : "cc"
51     );
52 
53     However according to the comments on the HP website and matching
54     comments in the Linux kernel sources this defies branch prediction,
55     as the cpu assumes that backward branches are always taken; so
56     instead copy the trick from the Linux kernel, introduce a forward
57     branch and back again.
58 
59     I have, however, had a hard time measuring the difference between
60     the two versions in microbenchmarks -- I am leaving it in nevertheless
61     as it apparently does not hurt either.
62 */
63 
64 struct gcc_alpha_operations_base
65 {
fence_beforeboost::atomics::detail::gcc_alpha_operations_base66     static BOOST_FORCEINLINE void fence_before(memory_order order) BOOST_NOEXCEPT
67     {
68         if ((order & memory_order_release) != 0)
69             __asm__ __volatile__ ("mb" ::: "memory");
70     }
71 
fence_afterboost::atomics::detail::gcc_alpha_operations_base72     static BOOST_FORCEINLINE void fence_after(memory_order order) BOOST_NOEXCEPT
73     {
74         if ((order & (memory_order_consume | memory_order_acquire)) != 0)
75             __asm__ __volatile__ ("mb" ::: "memory");
76     }
77 
fence_after_storeboost::atomics::detail::gcc_alpha_operations_base78     static BOOST_FORCEINLINE void fence_after_store(memory_order order) BOOST_NOEXCEPT
79     {
80         if (order == memory_order_seq_cst)
81             __asm__ __volatile__ ("mb" ::: "memory");
82     }
83 };
84 
85 
86 template< bool Signed >
87 struct operations< 4u, Signed > :
88     public gcc_alpha_operations_base
89 {
90     typedef typename make_storage_type< 4u, Signed >::type storage_type;
91 
storeboost::atomics::detail::operations92     static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
93     {
94         fence_before(order);
95         storage = v;
96         fence_after_store(order);
97     }
98 
loadboost::atomics::detail::operations99     static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
100     {
101         storage_type v = storage;
102         fence_after(order);
103         return v;
104     }
105 
exchangeboost::atomics::detail::operations106     static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
107     {
108         storage_type original, tmp;
109         fence_before(order);
110         __asm__ __volatile__
111         (
112             "1:\n"
113             "mov %3, %1\n"
114             "ldl_l %0, %2\n"
115             "stl_c %1, %2\n"
116             "beq %1, 2f\n"
117 
118             ".subsection 2\n"
119             "2: br 1b\n"
120             ".previous\n"
121 
122             : "=&r" (original),  // %0
123               "=&r" (tmp)        // %1
124             : "m" (storage),     // %2
125               "r" (v)            // %3
126             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
127         );
128         fence_after(order);
129         return original;
130     }
131 
compare_exchange_weakboost::atomics::detail::operations132     static BOOST_FORCEINLINE bool compare_exchange_weak(
133         storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
134     {
135         fence_before(success_order);
136         int success;
137         storage_type current;
138         __asm__ __volatile__
139         (
140             "1:\n"
141             "ldl_l %2, %4\n"                // current = *(&storage)
142             "cmpeq %2, %0, %3\n"            // success = current == expected
143             "mov %2, %0\n"                  // expected = current
144             "beq %3, 2f\n"                  // if (success == 0) goto end
145             "stl_c %1, %4\n"                // storage = desired; desired = store succeeded
146             "mov %1, %3\n"                  // success = desired
147             "2:\n"
148             : "+&r" (expected),  // %0
149               "+&r" (desired),   // %1
150               "=&r" (current),   // %2
151               "=&r" (success)    // %3
152             : "m" (storage)      // %4
153             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
154         );
155         if (success)
156             fence_after(success_order);
157         else
158             fence_after(failure_order);
159         return !!success;
160     }
161 
compare_exchange_strongboost::atomics::detail::operations162     static BOOST_FORCEINLINE bool compare_exchange_strong(
163         storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
164     {
165         int success;
166         storage_type current, tmp;
167         fence_before(success_order);
168         __asm__ __volatile__
169         (
170             "1:\n"
171             "mov %5, %1\n"                  // tmp = desired
172             "ldl_l %2, %4\n"                // current = *(&storage)
173             "cmpeq %2, %0, %3\n"            // success = current == expected
174             "mov %2, %0\n"                  // expected = current
175             "beq %3, 2f\n"                  // if (success == 0) goto end
176             "stl_c %1, %4\n"                // storage = tmp; tmp = store succeeded
177             "beq %1, 3f\n"                  // if (tmp == 0) goto retry
178             "mov %1, %3\n"                  // success = tmp
179             "2:\n"
180 
181             ".subsection 2\n"
182             "3: br 1b\n"
183             ".previous\n"
184 
185             : "+&r" (expected),  // %0
186               "=&r" (tmp),       // %1
187               "=&r" (current),   // %2
188               "=&r" (success)    // %3
189             : "m" (storage),     // %4
190               "r" (desired)      // %5
191             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
192         );
193         if (success)
194             fence_after(success_order);
195         else
196             fence_after(failure_order);
197         return !!success;
198     }
199 
fetch_addboost::atomics::detail::operations200     static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
201     {
202         storage_type original, modified;
203         fence_before(order);
204         __asm__ __volatile__
205         (
206             "1:\n"
207             "ldl_l %0, %2\n"
208             "addl %0, %3, %1\n"
209             "stl_c %1, %2\n"
210             "beq %1, 2f\n"
211 
212             ".subsection 2\n"
213             "2: br 1b\n"
214             ".previous\n"
215 
216             : "=&r" (original),  // %0
217               "=&r" (modified)   // %1
218             : "m" (storage),     // %2
219               "r" (v)            // %3
220             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
221         );
222         fence_after(order);
223         return original;
224     }
225 
fetch_subboost::atomics::detail::operations226     static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
227     {
228         storage_type original, modified;
229         fence_before(order);
230         __asm__ __volatile__
231         (
232             "1:\n"
233             "ldl_l %0, %2\n"
234             "subl %0, %3, %1\n"
235             "stl_c %1, %2\n"
236             "beq %1, 2f\n"
237 
238             ".subsection 2\n"
239             "2: br 1b\n"
240             ".previous\n"
241 
242             : "=&r" (original),  // %0
243               "=&r" (modified)   // %1
244             : "m" (storage),     // %2
245               "r" (v)            // %3
246             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
247         );
248         fence_after(order);
249         return original;
250     }
251 
fetch_andboost::atomics::detail::operations252     static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
253     {
254         storage_type original, modified;
255         fence_before(order);
256         __asm__ __volatile__
257         (
258             "1:\n"
259             "ldl_l %0, %2\n"
260             "and %0, %3, %1\n"
261             "stl_c %1, %2\n"
262             "beq %1, 2f\n"
263 
264             ".subsection 2\n"
265             "2: br 1b\n"
266             ".previous\n"
267 
268             : "=&r" (original),  // %0
269               "=&r" (modified)   // %1
270             : "m" (storage),     // %2
271               "r" (v)            // %3
272             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
273         );
274         fence_after(order);
275         return original;
276     }
277 
fetch_orboost::atomics::detail::operations278     static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
279     {
280         storage_type original, modified;
281         fence_before(order);
282         __asm__ __volatile__
283         (
284             "1:\n"
285             "ldl_l %0, %2\n"
286             "bis %0, %3, %1\n"
287             "stl_c %1, %2\n"
288             "beq %1, 2f\n"
289 
290             ".subsection 2\n"
291             "2: br 1b\n"
292             ".previous\n"
293 
294             : "=&r" (original),  // %0
295               "=&r" (modified)   // %1
296             : "m" (storage),     // %2
297               "r" (v)            // %3
298             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
299         );
300         fence_after(order);
301         return original;
302     }
303 
fetch_xorboost::atomics::detail::operations304     static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
305     {
306         storage_type original, modified;
307         fence_before(order);
308         __asm__ __volatile__
309         (
310             "1:\n"
311             "ldl_l %0, %2\n"
312             "xor %0, %3, %1\n"
313             "stl_c %1, %2\n"
314             "beq %1, 2f\n"
315 
316             ".subsection 2\n"
317             "2: br 1b\n"
318             ".previous\n"
319 
320             : "=&r" (original),  // %0
321               "=&r" (modified)   // %1
322             : "m" (storage),     // %2
323               "r" (v)            // %3
324             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
325         );
326         fence_after(order);
327         return original;
328     }
329 
test_and_setboost::atomics::detail::operations330     static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
331     {
332         return !!exchange(storage, (storage_type)1, order);
333     }
334 
clearboost::atomics::detail::operations335     static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
336     {
337         store(storage, 0, order);
338     }
339 
is_lock_freeboost::atomics::detail::operations340     static BOOST_FORCEINLINE bool is_lock_free(storage_type const volatile&) BOOST_NOEXCEPT
341     {
342         return true;
343     }
344 };
345 
346 
347 template< >
348 struct operations< 1u, false > :
349     public operations< 4u, false >
350 {
351     typedef operations< 4u, false > base_type;
352     typedef base_type::storage_type storage_type;
353 
fetch_addboost::atomics::detail::operations354     static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
355     {
356         storage_type original, modified;
357         fence_before(order);
358         __asm__ __volatile__
359         (
360             "1:\n"
361             "ldl_l %0, %2\n"
362             "addl %0, %3, %1\n"
363             "zapnot %1, #1, %1\n"
364             "stl_c %1, %2\n"
365             "beq %1, 2f\n"
366 
367             ".subsection 2\n"
368             "2: br 1b\n"
369             ".previous\n"
370 
371             : "=&r" (original),  // %0
372               "=&r" (modified)   // %1
373             : "m" (storage),     // %2
374               "r" (v)            // %3
375             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
376         );
377         fence_after(order);
378         return original;
379     }
380 
fetch_subboost::atomics::detail::operations381     static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
382     {
383         storage_type original, modified;
384         fence_before(order);
385         __asm__ __volatile__
386         (
387             "1:\n"
388             "ldl_l %0, %2\n"
389             "subl %0, %3, %1\n"
390             "zapnot %1, #1, %1\n"
391             "stl_c %1, %2\n"
392             "beq %1, 2f\n"
393 
394             ".subsection 2\n"
395             "2: br 1b\n"
396             ".previous\n"
397 
398             : "=&r" (original),  // %0
399               "=&r" (modified)   // %1
400             : "m" (storage),     // %2
401               "r" (v)            // %3
402             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
403         );
404         fence_after(order);
405         return original;
406     }
407 };
408 
409 template< >
410 struct operations< 1u, true > :
411     public operations< 4u, true >
412 {
413     typedef operations< 4u, true > base_type;
414     typedef base_type::storage_type storage_type;
415 
fetch_addboost::atomics::detail::operations416     static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
417     {
418         storage_type original, modified;
419         fence_before(order);
420         __asm__ __volatile__
421         (
422             "1:\n"
423             "ldl_l %0, %2\n"
424             "addl %0, %3, %1\n"
425             "sextb %1, %1\n"
426             "stl_c %1, %2\n"
427             "beq %1, 2f\n"
428 
429             ".subsection 2\n"
430             "2: br 1b\n"
431             ".previous\n"
432 
433             : "=&r" (original),  // %0
434               "=&r" (modified)   // %1
435             : "m" (storage),     // %2
436               "r" (v)            // %3
437             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
438         );
439         fence_after(order);
440         return original;
441     }
442 
fetch_subboost::atomics::detail::operations443     static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
444     {
445         storage_type original, modified;
446         fence_before(order);
447         __asm__ __volatile__
448         (
449             "1:\n"
450             "ldl_l %0, %2\n"
451             "subl %0, %3, %1\n"
452             "sextb %1, %1\n"
453             "stl_c %1, %2\n"
454             "beq %1, 2f\n"
455 
456             ".subsection 2\n"
457             "2: br 1b\n"
458             ".previous\n"
459 
460             : "=&r" (original),  // %0
461               "=&r" (modified)   // %1
462             : "m" (storage),     // %2
463               "r" (v)            // %3
464             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
465         );
466         fence_after(order);
467         return original;
468     }
469 };
470 
471 
472 template< >
473 struct operations< 2u, false > :
474     public operations< 4u, false >
475 {
476     typedef operations< 4u, false > base_type;
477     typedef base_type::storage_type storage_type;
478 
fetch_addboost::atomics::detail::operations479     static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
480     {
481         storage_type original, modified;
482         fence_before(order);
483         __asm__ __volatile__
484         (
485             "1:\n"
486             "ldl_l %0, %2\n"
487             "addl %0, %3, %1\n"
488             "zapnot %1, #3, %1\n"
489             "stl_c %1, %2\n"
490             "beq %1, 2f\n"
491 
492             ".subsection 2\n"
493             "2: br 1b\n"
494             ".previous\n"
495 
496             : "=&r" (original),  // %0
497               "=&r" (modified)   // %1
498             : "m" (storage),     // %2
499               "r" (v)            // %3
500             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
501         );
502         fence_after(order);
503         return original;
504     }
505 
fetch_subboost::atomics::detail::operations506     static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
507     {
508         storage_type original, modified;
509         fence_before(order);
510         __asm__ __volatile__
511         (
512             "1:\n"
513             "ldl_l %0, %2\n"
514             "subl %0, %3, %1\n"
515             "zapnot %1, #3, %1\n"
516             "stl_c %1, %2\n"
517             "beq %1, 2f\n"
518 
519             ".subsection 2\n"
520             "2: br 1b\n"
521             ".previous\n"
522 
523             : "=&r" (original),  // %0
524               "=&r" (modified)   // %1
525             : "m" (storage),     // %2
526               "r" (v)            // %3
527             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
528         );
529         fence_after(order);
530         return original;
531     }
532 };
533 
534 template< >
535 struct operations< 2u, true > :
536     public operations< 4u, true >
537 {
538     typedef operations< 4u, true > base_type;
539     typedef base_type::storage_type storage_type;
540 
fetch_addboost::atomics::detail::operations541     static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
542     {
543         storage_type original, modified;
544         fence_before(order);
545         __asm__ __volatile__
546         (
547             "1:\n"
548             "ldl_l %0, %2\n"
549             "addl %0, %3, %1\n"
550             "sextw %1, %1\n"
551             "stl_c %1, %2\n"
552             "beq %1, 2f\n"
553 
554             ".subsection 2\n"
555             "2: br 1b\n"
556             ".previous\n"
557 
558             : "=&r" (original),  // %0
559               "=&r" (modified)   // %1
560             : "m" (storage),     // %2
561               "r" (v)            // %3
562             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
563         );
564         fence_after(order);
565         return original;
566     }
567 
fetch_subboost::atomics::detail::operations568     static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
569     {
570         storage_type original, modified;
571         fence_before(order);
572         __asm__ __volatile__
573         (
574             "1:\n"
575             "ldl_l %0, %2\n"
576             "subl %0, %3, %1\n"
577             "sextw %1, %1\n"
578             "stl_c %1, %2\n"
579             "beq %1, 2f\n"
580 
581             ".subsection 2\n"
582             "2: br 1b\n"
583             ".previous\n"
584 
585             : "=&r" (original),  // %0
586               "=&r" (modified)   // %1
587             : "m" (storage),     // %2
588               "r" (v)            // %3
589             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
590         );
591         fence_after(order);
592         return original;
593     }
594 };
595 
596 
597 template< bool Signed >
598 struct operations< 8u, Signed > :
599     public gcc_alpha_operations_base
600 {
601     typedef typename make_storage_type< 8u, Signed >::type storage_type;
602 
storeboost::atomics::detail::operations603     static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
604     {
605         fence_before(order);
606         storage = v;
607         fence_after_store(order);
608     }
609 
loadboost::atomics::detail::operations610     static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
611     {
612         storage_type v = storage;
613         fence_after(order);
614         return v;
615     }
616 
exchangeboost::atomics::detail::operations617     static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
618     {
619         storage_type original, tmp;
620         fence_before(order);
621         __asm__ __volatile__
622         (
623             "1:\n"
624             "mov %3, %1\n"
625             "ldq_l %0, %2\n"
626             "stq_c %1, %2\n"
627             "beq %1, 2f\n"
628 
629             ".subsection 2\n"
630             "2: br 1b\n"
631             ".previous\n"
632 
633             : "=&r" (original),  // %0
634               "=&r" (tmp)        // %1
635             : "m" (storage),     // %2
636               "r" (v)            // %3
637             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
638         );
639         fence_after(order);
640         return original;
641     }
642 
compare_exchange_weakboost::atomics::detail::operations643     static BOOST_FORCEINLINE bool compare_exchange_weak(
644         storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
645     {
646         fence_before(success_order);
647         int success;
648         storage_type current;
649         __asm__ __volatile__
650         (
651             "1:\n"
652             "ldq_l %2, %4\n"                // current = *(&storage)
653             "cmpeq %2, %0, %3\n"            // success = current == expected
654             "mov %2, %0\n"                  // expected = current
655             "beq %3, 2f\n"                  // if (success == 0) goto end
656             "stq_c %1, %4\n"                // storage = desired; desired = store succeeded
657             "mov %1, %3\n"                  // success = desired
658             "2:\n"
659             : "+&r" (expected),  // %0
660               "+&r" (desired),   // %1
661               "=&r" (current),   // %2
662               "=&r" (success)    // %3
663             : "m" (storage)      // %4
664             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
665         );
666         if (success)
667             fence_after(success_order);
668         else
669             fence_after(failure_order);
670         return !!success;
671     }
672 
compare_exchange_strongboost::atomics::detail::operations673     static BOOST_FORCEINLINE bool compare_exchange_strong(
674         storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
675     {
676         int success;
677         storage_type current, tmp;
678         fence_before(success_order);
679         __asm__ __volatile__
680         (
681             "1:\n"
682             "mov %5, %1\n"                  // tmp = desired
683             "ldq_l %2, %4\n"                // current = *(&storage)
684             "cmpeq %2, %0, %3\n"            // success = current == expected
685             "mov %2, %0\n"                  // expected = current
686             "beq %3, 2f\n"                  // if (success == 0) goto end
687             "stq_c %1, %4\n"                // storage = tmp; tmp = store succeeded
688             "beq %1, 3f\n"                  // if (tmp == 0) goto retry
689             "mov %1, %3\n"                  // success = tmp
690             "2:\n"
691 
692             ".subsection 2\n"
693             "3: br 1b\n"
694             ".previous\n"
695 
696             : "+&r" (expected),  // %0
697               "=&r" (tmp),       // %1
698               "=&r" (current),   // %2
699               "=&r" (success)    // %3
700             : "m" (storage),     // %4
701               "r" (desired)      // %5
702             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
703         );
704         if (success)
705             fence_after(success_order);
706         else
707             fence_after(failure_order);
708         return !!success;
709     }
710 
fetch_addboost::atomics::detail::operations711     static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
712     {
713         storage_type original, modified;
714         fence_before(order);
715         __asm__ __volatile__
716         (
717             "1:\n"
718             "ldq_l %0, %2\n"
719             "addq %0, %3, %1\n"
720             "stq_c %1, %2\n"
721             "beq %1, 2f\n"
722 
723             ".subsection 2\n"
724             "2: br 1b\n"
725             ".previous\n"
726 
727             : "=&r" (original),  // %0
728               "=&r" (modified)   // %1
729             : "m" (storage),     // %2
730               "r" (v)            // %3
731             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
732         );
733         fence_after(order);
734         return original;
735     }
736 
fetch_subboost::atomics::detail::operations737     static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
738     {
739         storage_type original, modified;
740         fence_before(order);
741         __asm__ __volatile__
742         (
743             "1:\n"
744             "ldq_l %0, %2\n"
745             "subq %0, %3, %1\n"
746             "stq_c %1, %2\n"
747             "beq %1, 2f\n"
748 
749             ".subsection 2\n"
750             "2: br 1b\n"
751             ".previous\n"
752 
753             : "=&r" (original),  // %0
754               "=&r" (modified)   // %1
755             : "m" (storage),     // %2
756               "r" (v)            // %3
757             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
758         );
759         fence_after(order);
760         return original;
761     }
762 
fetch_andboost::atomics::detail::operations763     static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
764     {
765         storage_type original, modified;
766         fence_before(order);
767         __asm__ __volatile__
768         (
769             "1:\n"
770             "ldq_l %0, %2\n"
771             "and %0, %3, %1\n"
772             "stq_c %1, %2\n"
773             "beq %1, 2f\n"
774 
775             ".subsection 2\n"
776             "2: br 1b\n"
777             ".previous\n"
778 
779             : "=&r" (original),  // %0
780               "=&r" (modified)   // %1
781             : "m" (storage),     // %2
782               "r" (v)            // %3
783             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
784         );
785         fence_after(order);
786         return original;
787     }
788 
fetch_orboost::atomics::detail::operations789     static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
790     {
791         storage_type original, modified;
792         fence_before(order);
793         __asm__ __volatile__
794         (
795             "1:\n"
796             "ldq_l %0, %2\n"
797             "bis %0, %3, %1\n"
798             "stq_c %1, %2\n"
799             "beq %1, 2f\n"
800 
801             ".subsection 2\n"
802             "2: br 1b\n"
803             ".previous\n"
804 
805             : "=&r" (original),  // %0
806               "=&r" (modified)   // %1
807             : "m" (storage),     // %2
808               "r" (v)            // %3
809             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
810         );
811         fence_after(order);
812         return original;
813     }
814 
fetch_xorboost::atomics::detail::operations815     static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
816     {
817         storage_type original, modified;
818         fence_before(order);
819         __asm__ __volatile__
820         (
821             "1:\n"
822             "ldq_l %0, %2\n"
823             "xor %0, %3, %1\n"
824             "stq_c %1, %2\n"
825             "beq %1, 2f\n"
826 
827             ".subsection 2\n"
828             "2: br 1b\n"
829             ".previous\n"
830 
831             : "=&r" (original),  // %0
832               "=&r" (modified)   // %1
833             : "m" (storage),     // %2
834               "r" (v)            // %3
835             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
836         );
837         fence_after(order);
838         return original;
839     }
840 
test_and_setboost::atomics::detail::operations841     static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
842     {
843         return !!exchange(storage, (storage_type)1, order);
844     }
845 
clearboost::atomics::detail::operations846     static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
847     {
848         store(storage, 0, order);
849     }
850 
is_lock_freeboost::atomics::detail::operations851     static BOOST_FORCEINLINE bool is_lock_free(storage_type const volatile&) BOOST_NOEXCEPT
852     {
853         return true;
854     }
855 };
856 
857 
thread_fence(memory_order order)858 BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT
859 {
860     if (order != memory_order_relaxed)
861         __asm__ __volatile__ ("mb" ::: "memory");
862 }
863 
signal_fence(memory_order order)864 BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT
865 {
866     if (order != memory_order_relaxed)
867         __asm__ __volatile__ ("" ::: "memory");
868 }
869 
870 } // namespace detail
871 } // namespace atomics
872 } // namespace boost
873 
874 #endif // BOOST_ATOMIC_DETAIL_OPS_GCC_ALPHA_HPP_INCLUDED_
875