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/ops_gcc_ppc.hpp
13 * This header contains implementation of the \c operations template.
16 #ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_PPC_HPP_INCLUDED_
17 #define BOOST_ATOMIC_DETAIL_OPS_GCC_PPC_HPP_INCLUDED_
20 #include <boost/memory_order.hpp>
21 #include <boost/atomic/detail/config.hpp>
22 #include <boost/atomic/detail/storage_type.hpp>
23 #include <boost/atomic/detail/operations_fwd.hpp>
24 #include <boost/atomic/detail/ops_gcc_ppc_common.hpp>
25 #include <boost/atomic/capabilities.hpp>
27 #ifdef BOOST_HAS_PRAGMA_ONCE
35 // The implementation below uses information from this document:
36 // http://www.rdrop.com/users/paulmck/scalability/paper/N2745r.2010.02.19a.html
39 Refer to: Motorola: "Programming Environments Manual for 32-Bit
40 Implementations of the PowerPC Architecture", Appendix E:
41 "Synchronization Programming Examples" for an explanation of what is
42 going on here (can be found on the web at various places by the
43 name "MPCFPE32B.pdf", Google is your friend...)
45 Most of the atomic operations map to instructions in a relatively
46 straight-forward fashion, but "load"s may at first glance appear
47 a bit strange as they map to:
54 That is, the CPU is forced to perform a branch that "formally" depends
55 on the value retrieved from memory. This scheme has an overhead of
56 about 1-2 clock cycles per load, but it allows to map "acquire" to
57 the "isync" instruction instead of "sync" uniformly and for all type
58 of atomic operations. Since "isync" has a cost of about 15 clock
59 cycles, while "sync" hast a cost of about 50 clock cycles, the small
60 penalty to atomic loads more than compensates for this.
62 Byte- and halfword-sized atomic values are implemented in two ways.
63 When 8 and 16-bit instructions are available (in Power8 and later),
64 they are used. Otherwise operations are realized by encoding the
65 value to be represented into a word, performing sign/zero extension
66 as appropriate. This means that after add/sub operations the value
67 needs fixing up to accurately preserve the wrap-around semantic of
68 the smaller type. (Nothing special needs to be done for the bit-wise
69 and the "exchange type" operators as the compiler already sees to
70 it that values carried in registers are extended appropriately and
71 everything falls into place naturally).
73 The register constraint "b" instructs gcc to use any register
74 except r0; this is sometimes required because the encoding for
75 r0 is used to signify "constant zero" in a number of instructions,
76 making r0 unusable in this place. For simplicity this constraint
77 is used everywhere since I am to lazy to look this up on a
78 per-instruction basis, and ppc has enough registers for this not
82 template< bool Signed >
83 struct operations< 4u, Signed > :
84 public gcc_ppc_operations_base
86 typedef typename make_storage_type< 4u, Signed >::type storage_type;
87 typedef typename make_storage_type< 4u, Signed >::aligned aligned_storage_type;
89 static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 4u;
90 static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
92 static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
103 static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
106 if (order == memory_order_seq_cst)
107 __asm__ __volatile__ ("sync" ::: "memory");
108 if ((order & (memory_order_consume | memory_order_acquire)) != 0)
134 static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
136 storage_type original;
144 : "=&b" (original), "+Z" (storage)
152 static BOOST_FORCEINLINE bool compare_exchange_weak(
153 storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
156 fence_before(success_order);
167 : "=&b" (expected), "=&b" (success), "+Z" (storage)
168 : "b" (expected), "b" (desired)
172 fence_after(success_order);
174 fence_after(failure_order);
178 static BOOST_FORCEINLINE bool compare_exchange_strong(
179 storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
182 fence_before(success_order);
186 "0: lwarx %0,%y2\n\t"
193 : "=&b" (expected), "=&b" (success), "+Z" (storage)
194 : "b" (expected), "b" (desired)
198 fence_after(success_order);
200 fence_after(failure_order);
204 static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
206 storage_type original, tmp;
215 : "=&b" (original), "=&b" (tmp), "+Z" (storage)
217 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
223 static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
225 storage_type original, tmp;
234 : "=&b" (original), "=&b" (tmp), "+Z" (storage)
236 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
242 static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
244 storage_type original, tmp;
253 : "=&b" (original), "=&b" (tmp), "+Z" (storage)
255 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
261 static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
263 storage_type original, tmp;
272 : "=&b" (original), "=&b" (tmp), "+Z" (storage)
274 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
280 static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
282 storage_type original, tmp;
291 : "=&b" (original), "=&b" (tmp), "+Z" (storage)
293 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
299 static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
301 return !!exchange(storage, (storage_type)1, order);
304 static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
306 store(storage, 0, order);
310 #if defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LBARX_STBCX)
312 template< bool Signed >
313 struct operations< 1u, Signed > :
314 public gcc_ppc_operations_base
316 typedef typename make_storage_type< 1u, Signed >::type storage_type;
317 typedef typename make_storage_type< 1u, Signed >::aligned aligned_storage_type;
318 typedef typename make_storage_type< 1u, false >::type unsigned_storage_type;
320 static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 1u;
321 static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
323 static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
334 static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
337 if (order == memory_order_seq_cst)
338 __asm__ __volatile__ ("sync" ::: "memory");
339 if ((order & (memory_order_consume | memory_order_acquire)) != 0)
365 static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
367 storage_type original;
375 : "=&b" (original), "+Z" (storage)
383 static BOOST_FORCEINLINE bool compare_exchange_weak(
384 storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
387 fence_before(success_order);
398 : "=&b" (expected), "=&b" (success), "+Z" (storage)
399 : "b" ((unsigned_storage_type)expected), "b" (desired)
403 fence_after(success_order);
405 fence_after(failure_order);
409 static BOOST_FORCEINLINE bool compare_exchange_strong(
410 storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
413 fence_before(success_order);
417 "0: lbarx %0,%y2\n\t"
424 : "=&b" (expected), "=&b" (success), "+Z" (storage)
425 : "b" ((unsigned_storage_type)expected), "b" (desired)
429 fence_after(success_order);
431 fence_after(failure_order);
435 static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
437 storage_type original, tmp;
446 : "=&b" (original), "=&b" (tmp), "+Z" (storage)
448 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
454 static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
456 storage_type original, tmp;
465 : "=&b" (original), "=&b" (tmp), "+Z" (storage)
467 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
473 static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
475 storage_type original, tmp;
484 : "=&b" (original), "=&b" (tmp), "+Z" (storage)
486 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
492 static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
494 storage_type original, tmp;
503 : "=&b" (original), "=&b" (tmp), "+Z" (storage)
505 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
511 static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
513 storage_type original, tmp;
522 : "=&b" (original), "=&b" (tmp), "+Z" (storage)
524 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
530 static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
532 return !!exchange(storage, (storage_type)1, order);
535 static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
537 store(storage, 0, order);
541 #else // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LBARX_STBCX)
544 struct operations< 1u, false > :
545 public operations< 4u, false >
547 typedef operations< 4u, false > base_type;
548 typedef base_type::storage_type storage_type;
550 static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
552 storage_type original, tmp;
559 "rlwinm %1, %1, 0, 0xff\n\t"
562 : "=&b" (original), "=&b" (tmp), "+Z" (storage)
564 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
570 static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
572 storage_type original, tmp;
579 "rlwinm %1, %1, 0, 0xff\n\t"
582 : "=&b" (original), "=&b" (tmp), "+Z" (storage)
584 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
592 struct operations< 1u, true > :
593 public operations< 4u, true >
595 typedef operations< 4u, true > base_type;
596 typedef base_type::storage_type storage_type;
598 static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
600 storage_type original, tmp;
610 : "=&b" (original), "=&b" (tmp), "+Z" (storage)
612 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
618 static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
620 storage_type original, tmp;
630 : "=&b" (original), "=&b" (tmp), "+Z" (storage)
632 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
639 #endif // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LBARX_STBCX)
641 #if defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LHARX_STHCX)
643 template< bool Signed >
644 struct operations< 2u, Signed > :
645 public gcc_ppc_operations_base
647 typedef typename make_storage_type< 2u, Signed >::type storage_type;
648 typedef typename make_storage_type< 2u, Signed >::aligned aligned_storage_type;
649 typedef typename make_storage_type< 2u, false >::type unsigned_storage_type;
651 static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 2u;
652 static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
654 static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
665 static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
668 if (order == memory_order_seq_cst)
669 __asm__ __volatile__ ("sync" ::: "memory");
670 if ((order & (memory_order_consume | memory_order_acquire)) != 0)
696 static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
698 storage_type original;
706 : "=&b" (original), "+Z" (storage)
714 static BOOST_FORCEINLINE bool compare_exchange_weak(
715 storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
718 fence_before(success_order);
729 : "=&b" (expected), "=&b" (success), "+Z" (storage)
730 : "b" ((unsigned_storage_type)expected), "b" (desired)
734 fence_after(success_order);
736 fence_after(failure_order);
740 static BOOST_FORCEINLINE bool compare_exchange_strong(
741 storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
744 fence_before(success_order);
748 "0: lharx %0,%y2\n\t"
755 : "=&b" (expected), "=&b" (success), "+Z" (storage)
756 : "b" ((unsigned_storage_type)expected), "b" (desired)
760 fence_after(success_order);
762 fence_after(failure_order);
766 static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
768 storage_type original, tmp;
777 : "=&b" (original), "=&b" (tmp), "+Z" (storage)
779 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
785 static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
787 storage_type original, tmp;
796 : "=&b" (original), "=&b" (tmp), "+Z" (storage)
798 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
804 static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
806 storage_type original, tmp;
815 : "=&b" (original), "=&b" (tmp), "+Z" (storage)
817 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
823 static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
825 storage_type original, tmp;
834 : "=&b" (original), "=&b" (tmp), "+Z" (storage)
836 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
842 static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
844 storage_type original, tmp;
853 : "=&b" (original), "=&b" (tmp), "+Z" (storage)
855 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
861 static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
863 return !!exchange(storage, (storage_type)1, order);
866 static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
868 store(storage, 0, order);
872 #else // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LHARX_STHCX)
875 struct operations< 2u, false > :
876 public operations< 4u, false >
878 typedef operations< 4u, false > base_type;
879 typedef base_type::storage_type storage_type;
881 static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
883 storage_type original, tmp;
890 "rlwinm %1, %1, 0, 0xffff\n\t"
893 : "=&b" (original), "=&b" (tmp), "+Z" (storage)
895 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
901 static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
903 storage_type original, tmp;
910 "rlwinm %1, %1, 0, 0xffff\n\t"
913 : "=&b" (original), "=&b" (tmp), "+Z" (storage)
915 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
923 struct operations< 2u, true > :
924 public operations< 4u, true >
926 typedef operations< 4u, true > base_type;
927 typedef base_type::storage_type storage_type;
929 static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
931 storage_type original, tmp;
941 : "=&b" (original), "=&b" (tmp), "+Z" (storage)
943 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
949 static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
951 storage_type original, tmp;
961 : "=&b" (original), "=&b" (tmp), "+Z" (storage)
963 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
970 #endif // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LHARX_STHCX)
972 #if defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LDARX_STDCX)
974 template< bool Signed >
975 struct operations< 8u, Signed > :
976 public gcc_ppc_operations_base
978 typedef typename make_storage_type< 8u, Signed >::type storage_type;
979 typedef typename make_storage_type< 8u, Signed >::aligned aligned_storage_type;
981 static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 8u;
982 static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
984 static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
995 static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
998 if (order == memory_order_seq_cst)
999 __asm__ __volatile__ ("sync" ::: "memory");
1000 if ((order & (memory_order_consume | memory_order_acquire)) != 0)
1002 __asm__ __volatile__
1016 __asm__ __volatile__
1026 static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
1028 storage_type original;
1029 fence_before(order);
1030 __asm__ __volatile__
1036 : "=&b" (original), "+Z" (storage)
1044 static BOOST_FORCEINLINE bool compare_exchange_weak(
1045 storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
1048 fence_before(success_order);
1049 __asm__ __volatile__
1059 : "=&b" (expected), "=&b" (success), "+Z" (storage)
1060 : "b" (expected), "b" (desired)
1064 fence_after(success_order);
1066 fence_after(failure_order);
1070 static BOOST_FORCEINLINE bool compare_exchange_strong(
1071 storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
1074 fence_before(success_order);
1075 __asm__ __volatile__
1078 "0: ldarx %0,%y2\n\t"
1085 : "=&b" (expected), "=&b" (success), "+Z" (storage)
1086 : "b" (expected), "b" (desired)
1090 fence_after(success_order);
1092 fence_after(failure_order);
1096 static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
1098 storage_type original, tmp;
1099 fence_before(order);
1100 __asm__ __volatile__
1107 : "=&b" (original), "=&b" (tmp), "+Z" (storage)
1109 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
1115 static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
1117 storage_type original, tmp;
1118 fence_before(order);
1119 __asm__ __volatile__
1126 : "=&b" (original), "=&b" (tmp), "+Z" (storage)
1128 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
1134 static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
1136 storage_type original, tmp;
1137 fence_before(order);
1138 __asm__ __volatile__
1145 : "=&b" (original), "=&b" (tmp), "+Z" (storage)
1147 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
1153 static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
1155 storage_type original, tmp;
1156 fence_before(order);
1157 __asm__ __volatile__
1164 : "=&b" (original), "=&b" (tmp), "+Z" (storage)
1166 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
1172 static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
1174 storage_type original, tmp;
1175 fence_before(order);
1176 __asm__ __volatile__
1183 : "=&b" (original), "=&b" (tmp), "+Z" (storage)
1185 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
1191 static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
1193 return !!exchange(storage, (storage_type)1, order);
1196 static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
1198 store(storage, 0, order);
1202 #endif // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LDARX_STDCX)
1205 BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT
1209 case memory_order_consume:
1210 case memory_order_acquire:
1211 case memory_order_release:
1212 case memory_order_acq_rel:
1213 #if defined(__powerpc64__) || defined(__PPC64__)
1214 __asm__ __volatile__ ("lwsync" ::: "memory");
1217 case memory_order_seq_cst:
1218 __asm__ __volatile__ ("sync" ::: "memory");
1224 BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT
1226 if (order != memory_order_relaxed)
1227 #if defined(__ibmxl__) || defined(__IBMCPP__)
1230 __asm__ __volatile__ ("" ::: "memory");
1234 } // namespace detail
1235 } // namespace atomics
1236 } // namespace boost
1238 #endif // BOOST_ATOMIC_DETAIL_OPS_GCC_PPC_HPP_INCLUDED_