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)
6 * Copyright (c) 2009 Helge Bahmann
7 * Copyright (c) 2013 Tim Blechmann
8 * Copyright (c) 2014 Andrey Semashev
11 * \file atomic/detail/core_arch_ops_gcc_ppc.hpp
13 * This header contains implementation of the \c core_arch_operations template.
16 #ifndef BOOST_ATOMIC_DETAIL_CORE_ARCH_OPS_GCC_PPC_HPP_INCLUDED_
17 #define BOOST_ATOMIC_DETAIL_CORE_ARCH_OPS_GCC_PPC_HPP_INCLUDED_
20 #include <boost/memory_order.hpp>
21 #include <boost/atomic/detail/config.hpp>
22 #include <boost/atomic/detail/storage_traits.hpp>
23 #include <boost/atomic/detail/core_arch_operations_fwd.hpp>
24 #include <boost/atomic/detail/ops_gcc_ppc_common.hpp>
25 #include <boost/atomic/detail/capabilities.hpp>
26 #include <boost/atomic/detail/header.hpp>
28 #ifdef BOOST_HAS_PRAGMA_ONCE
36 // The implementation below uses information from this document:
37 // http://www.rdrop.com/users/paulmck/scalability/paper/N2745r.2010.02.19a.html
40 Refer to: Motorola: "Programming Environments Manual for 32-Bit
41 Implementations of the PowerPC Architecture", Appendix E:
42 "Synchronization Programming Examples" for an explanation of what is
43 going on here (can be found on the web at various places by the
44 name "MPCFPE32B.pdf", Google is your friend...)
46 Most of the atomic operations map to instructions in a relatively
47 straight-forward fashion, but "load"s may at first glance appear
48 a bit strange as they map to:
55 That is, the CPU is forced to perform a branch that "formally" depends
56 on the value retrieved from memory. This scheme has an overhead of
57 about 1-2 clock cycles per load, but it allows to map "acquire" to
58 the "isync" instruction instead of "sync" uniformly and for all type
59 of atomic operations. Since "isync" has a cost of about 15 clock
60 cycles, while "sync" hast a cost of about 50 clock cycles, the small
61 penalty to atomic loads more than compensates for this.
63 Byte- and halfword-sized atomic values are implemented in two ways.
64 When 8 and 16-bit instructions are available (in Power8 and later),
65 they are used. Otherwise operations are realized by encoding the
66 value to be represented into a word, performing sign/zero extension
67 as appropriate. This means that after add/sub operations the value
68 needs fixing up to accurately preserve the wrap-around semantic of
69 the smaller type. (Nothing special needs to be done for the bit-wise
70 and the "exchange type" operators as the compiler already sees to
71 it that values carried in registers are extended appropriately and
72 everything falls into place naturally).
74 The register constraint "b" instructs gcc to use any register
75 except r0; this is sometimes required because the encoding for
76 r0 is used to signify "constant zero" in a number of instructions,
77 making r0 unusable in this place. For simplicity this constraint
78 is used everywhere since I am to lazy to look this up on a
79 per-instruction basis, and ppc has enough registers for this not
83 template< bool Signed, bool Interprocess >
84 struct core_arch_operations< 4u, Signed, Interprocess > :
85 public core_arch_operations_gcc_ppc_base
87 typedef typename storage_traits< 4u >::type storage_type;
89 static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 4u;
90 static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 4u;
91 static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
92 static BOOST_CONSTEXPR_OR_CONST bool is_interprocess = Interprocess;
94 static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
105 static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
108 if (order == memory_order_seq_cst)
109 __asm__ __volatile__ ("sync" ::: "memory");
110 if ((static_cast< unsigned int >(order) & (static_cast< unsigned int >(memory_order_consume) | static_cast< unsigned int >(memory_order_acquire))) != 0u)
136 static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
138 storage_type original;
146 : "=&b" (original), "+Z" (storage)
154 static BOOST_FORCEINLINE bool compare_exchange_weak(
155 storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
158 fence_before(success_order);
169 : "=&b" (expected), "=&b" (success), "+Z" (storage)
170 : "b" (expected), "b" (desired)
174 fence_after(success_order);
176 fence_after(failure_order);
180 static BOOST_FORCEINLINE bool compare_exchange_strong(
181 storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
184 fence_before(success_order);
188 "0: lwarx %0,%y2\n\t"
195 : "=&b" (expected), "=&b" (success), "+Z" (storage)
196 : "b" (expected), "b" (desired)
200 fence_after(success_order);
202 fence_after(failure_order);
206 static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
208 storage_type original, result;
217 : "=&b" (original), "=&b" (result), "+Z" (storage)
219 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
225 static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
227 storage_type original, result;
236 : "=&b" (original), "=&b" (result), "+Z" (storage)
238 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
244 static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
246 storage_type original, result;
255 : "=&b" (original), "=&b" (result), "+Z" (storage)
257 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
263 static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
265 storage_type original, result;
274 : "=&b" (original), "=&b" (result), "+Z" (storage)
276 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
282 static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
284 storage_type original, result;
293 : "=&b" (original), "=&b" (result), "+Z" (storage)
295 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
301 static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
303 return !!exchange(storage, (storage_type)1, order);
306 static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
308 store(storage, (storage_type)0, order);
312 #if defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LBARX_STBCX)
314 template< bool Signed, bool Interprocess >
315 struct core_arch_operations< 1u, Signed, Interprocess > :
316 public core_arch_operations_gcc_ppc_base
318 typedef typename storage_traits< 1u >::type storage_type;
320 static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 1u;
321 static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 1u;
322 static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
323 static BOOST_CONSTEXPR_OR_CONST bool is_interprocess = Interprocess;
325 static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
336 static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
339 if (order == memory_order_seq_cst)
340 __asm__ __volatile__ ("sync" ::: "memory");
341 if ((static_cast< unsigned int >(order) & (static_cast< unsigned int >(memory_order_consume) | static_cast< unsigned int >(memory_order_acquire))) != 0u)
367 static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
369 storage_type original;
377 : "=&b" (original), "+Z" (storage)
385 static BOOST_FORCEINLINE bool compare_exchange_weak(
386 storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
389 fence_before(success_order);
400 : "=&b" (expected), "=&b" (success), "+Z" (storage)
401 : "b" (expected), "b" (desired)
405 fence_after(success_order);
407 fence_after(failure_order);
411 static BOOST_FORCEINLINE bool compare_exchange_strong(
412 storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
415 fence_before(success_order);
419 "0: lbarx %0,%y2\n\t"
426 : "=&b" (expected), "=&b" (success), "+Z" (storage)
427 : "b" (expected), "b" (desired)
431 fence_after(success_order);
433 fence_after(failure_order);
437 static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
439 storage_type original, result;
448 : "=&b" (original), "=&b" (result), "+Z" (storage)
450 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
456 static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
458 storage_type original, result;
467 : "=&b" (original), "=&b" (result), "+Z" (storage)
469 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
475 static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
477 storage_type original, result;
486 : "=&b" (original), "=&b" (result), "+Z" (storage)
488 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
494 static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
496 storage_type original, result;
505 : "=&b" (original), "=&b" (result), "+Z" (storage)
507 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
513 static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
515 storage_type original, result;
524 : "=&b" (original), "=&b" (result), "+Z" (storage)
526 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
532 static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
534 return !!exchange(storage, (storage_type)1, order);
537 static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
539 store(storage, (storage_type)0, order);
543 #else // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LBARX_STBCX)
545 template< bool Interprocess >
546 struct core_arch_operations< 1u, false, Interprocess > :
547 public core_arch_operations< 4u, false, Interprocess >
549 typedef core_arch_operations< 4u, false, Interprocess > base_type;
550 typedef typename base_type::storage_type storage_type;
552 static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
554 storage_type original, result;
555 base_type::fence_before(order);
561 "rlwinm %1, %1, 0, 0xff\n\t"
564 : "=&b" (original), "=&b" (result), "+Z" (storage)
566 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
568 base_type::fence_after(order);
572 static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
574 storage_type original, result;
575 base_type::fence_before(order);
581 "rlwinm %1, %1, 0, 0xff\n\t"
584 : "=&b" (original), "=&b" (result), "+Z" (storage)
586 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
588 base_type::fence_after(order);
593 template< bool Interprocess >
594 struct core_arch_operations< 1u, true, Interprocess > :
595 public core_arch_operations< 4u, true, Interprocess >
597 typedef core_arch_operations< 4u, true, Interprocess > base_type;
598 typedef typename base_type::storage_type storage_type;
600 static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
602 storage_type original, result;
603 base_type::fence_before(order);
612 : "=&b" (original), "=&b" (result), "+Z" (storage)
614 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
616 base_type::fence_after(order);
620 static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
622 storage_type original, result;
623 base_type::fence_before(order);
632 : "=&b" (original), "=&b" (result), "+Z" (storage)
634 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
636 base_type::fence_after(order);
641 #endif // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LBARX_STBCX)
643 #if defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LHARX_STHCX)
645 template< bool Signed, bool Interprocess >
646 struct core_arch_operations< 2u, Signed, Interprocess > :
647 public core_arch_operations_gcc_ppc_base
649 typedef typename storage_traits< 2u >::type storage_type;
651 static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 2u;
652 static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 2u;
653 static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
654 static BOOST_CONSTEXPR_OR_CONST bool is_interprocess = Interprocess;
656 static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
667 static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
670 if (order == memory_order_seq_cst)
671 __asm__ __volatile__ ("sync" ::: "memory");
672 if ((static_cast< unsigned int >(order) & (static_cast< unsigned int >(memory_order_consume) | static_cast< unsigned int >(memory_order_acquire))) != 0u)
698 static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
700 storage_type original;
708 : "=&b" (original), "+Z" (storage)
716 static BOOST_FORCEINLINE bool compare_exchange_weak(
717 storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
720 fence_before(success_order);
731 : "=&b" (expected), "=&b" (success), "+Z" (storage)
732 : "b" (expected), "b" (desired)
736 fence_after(success_order);
738 fence_after(failure_order);
742 static BOOST_FORCEINLINE bool compare_exchange_strong(
743 storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
746 fence_before(success_order);
750 "0: lharx %0,%y2\n\t"
757 : "=&b" (expected), "=&b" (success), "+Z" (storage)
758 : "b" (expected), "b" (desired)
762 fence_after(success_order);
764 fence_after(failure_order);
768 static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
770 storage_type original, result;
779 : "=&b" (original), "=&b" (result), "+Z" (storage)
781 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
787 static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
789 storage_type original, result;
798 : "=&b" (original), "=&b" (result), "+Z" (storage)
800 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
806 static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
808 storage_type original, result;
817 : "=&b" (original), "=&b" (result), "+Z" (storage)
819 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
825 static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
827 storage_type original, result;
836 : "=&b" (original), "=&b" (result), "+Z" (storage)
838 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
844 static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
846 storage_type original, result;
855 : "=&b" (original), "=&b" (result), "+Z" (storage)
857 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
863 static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
865 return !!exchange(storage, (storage_type)1, order);
868 static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
870 store(storage, (storage_type)0, order);
874 #else // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LHARX_STHCX)
876 template< bool Interprocess >
877 struct core_arch_operations< 2u, false, Interprocess > :
878 public core_arch_operations< 4u, false, Interprocess >
880 typedef core_arch_operations< 4u, false, Interprocess > base_type;
881 typedef typename base_type::storage_type storage_type;
883 static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
885 storage_type original, result;
886 base_type::fence_before(order);
892 "rlwinm %1, %1, 0, 0xffff\n\t"
895 : "=&b" (original), "=&b" (result), "+Z" (storage)
897 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
899 base_type::fence_after(order);
903 static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
905 storage_type original, result;
906 base_type::fence_before(order);
912 "rlwinm %1, %1, 0, 0xffff\n\t"
915 : "=&b" (original), "=&b" (result), "+Z" (storage)
917 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
919 base_type::fence_after(order);
924 template< bool Interprocess >
925 struct core_arch_operations< 2u, true, Interprocess > :
926 public core_arch_operations< 4u, true, Interprocess >
928 typedef core_arch_operations< 4u, true, Interprocess > base_type;
929 typedef typename base_type::storage_type storage_type;
931 static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
933 storage_type original, result;
934 base_type::fence_before(order);
943 : "=&b" (original), "=&b" (result), "+Z" (storage)
945 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
947 base_type::fence_after(order);
951 static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
953 storage_type original, result;
954 base_type::fence_before(order);
963 : "=&b" (original), "=&b" (result), "+Z" (storage)
965 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
967 base_type::fence_after(order);
972 #endif // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LHARX_STHCX)
974 #if defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LDARX_STDCX)
976 template< bool Signed, bool Interprocess >
977 struct core_arch_operations< 8u, Signed, Interprocess > :
978 public core_arch_operations_gcc_ppc_base
980 typedef typename storage_traits< 8u >::type storage_type;
982 static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 8u;
983 static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 8u;
984 static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
985 static BOOST_CONSTEXPR_OR_CONST bool is_interprocess = Interprocess;
987 static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
998 static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
1001 if (order == memory_order_seq_cst)
1002 __asm__ __volatile__ ("sync" ::: "memory");
1003 if ((static_cast< unsigned int >(order) & (static_cast< unsigned int >(memory_order_consume) | static_cast< unsigned int >(memory_order_acquire))) != 0u)
1005 __asm__ __volatile__
1019 __asm__ __volatile__
1029 static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
1031 storage_type original;
1032 fence_before(order);
1033 __asm__ __volatile__
1039 : "=&b" (original), "+Z" (storage)
1047 static BOOST_FORCEINLINE bool compare_exchange_weak(
1048 storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
1051 fence_before(success_order);
1052 __asm__ __volatile__
1062 : "=&b" (expected), "=&b" (success), "+Z" (storage)
1063 : "b" (expected), "b" (desired)
1067 fence_after(success_order);
1069 fence_after(failure_order);
1073 static BOOST_FORCEINLINE bool compare_exchange_strong(
1074 storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
1077 fence_before(success_order);
1078 __asm__ __volatile__
1081 "0: ldarx %0,%y2\n\t"
1088 : "=&b" (expected), "=&b" (success), "+Z" (storage)
1089 : "b" (expected), "b" (desired)
1093 fence_after(success_order);
1095 fence_after(failure_order);
1099 static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
1101 storage_type original, result;
1102 fence_before(order);
1103 __asm__ __volatile__
1110 : "=&b" (original), "=&b" (result), "+Z" (storage)
1112 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
1118 static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
1120 storage_type original, result;
1121 fence_before(order);
1122 __asm__ __volatile__
1129 : "=&b" (original), "=&b" (result), "+Z" (storage)
1131 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
1137 static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
1139 storage_type original, result;
1140 fence_before(order);
1141 __asm__ __volatile__
1148 : "=&b" (original), "=&b" (result), "+Z" (storage)
1150 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
1156 static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
1158 storage_type original, result;
1159 fence_before(order);
1160 __asm__ __volatile__
1167 : "=&b" (original), "=&b" (result), "+Z" (storage)
1169 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
1175 static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
1177 storage_type original, result;
1178 fence_before(order);
1179 __asm__ __volatile__
1186 : "=&b" (original), "=&b" (result), "+Z" (storage)
1188 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
1194 static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
1196 return !!exchange(storage, (storage_type)1, order);
1199 static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
1201 store(storage, (storage_type)0, order);
1205 #endif // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LDARX_STDCX)
1207 } // namespace detail
1208 } // namespace atomics
1209 } // namespace boost
1211 #include <boost/atomic/detail/footer.hpp>
1213 #endif // BOOST_ATOMIC_DETAIL_CORE_ARCH_OPS_GCC_PPC_HPP_INCLUDED_