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) 2017 - 2018 Andrey Semashev
9 * \file atomic/detail/extra_ops_gcc_ppc.hpp
11 * This header contains implementation of the extra atomic operations for PowerPC.
14 #ifndef BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_PPC_HPP_INCLUDED_
15 #define BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_PPC_HPP_INCLUDED_
18 #include <boost/memory_order.hpp>
19 #include <boost/atomic/detail/config.hpp>
20 #include <boost/atomic/detail/storage_traits.hpp>
21 #include <boost/atomic/detail/extra_operations_fwd.hpp>
22 #include <boost/atomic/detail/extra_ops_generic.hpp>
23 #include <boost/atomic/detail/ops_gcc_ppc_common.hpp>
24 #include <boost/atomic/detail/capabilities.hpp>
25 #include <boost/atomic/detail/header.hpp>
27 #ifdef BOOST_HAS_PRAGMA_ONCE
35 template< typename Base >
36 struct extra_operations_gcc_ppc_common :
39 typedef Base base_type;
40 typedef typename base_type::storage_type storage_type;
42 static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
44 base_type::fetch_negate(storage, order);
47 static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
49 base_type::fetch_complement(storage, order);
52 static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
54 return !!base_type::negate(storage, order);
57 static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
59 return !!base_type::add(storage, v, order);
62 static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
64 return !!base_type::sub(storage, v, order);
67 static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
69 return !!base_type::bitwise_and(storage, v, order);
72 static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
74 return !!base_type::bitwise_or(storage, v, order);
77 static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
79 return !!base_type::bitwise_xor(storage, v, order);
82 static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
84 return !!base_type::bitwise_complement(storage, order);
88 template< typename Base, std::size_t Size, bool Signed >
89 struct extra_operations_gcc_ppc;
91 #if defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LBARX_STBCX)
93 template< typename Base, bool Signed >
94 struct extra_operations_gcc_ppc< Base, 1u, Signed > :
95 public extra_operations_generic< Base, 1u, Signed >
97 typedef extra_operations_generic< Base, 1u, Signed > base_type;
98 typedef typename base_type::storage_type storage_type;
100 static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
102 core_arch_operations_gcc_ppc_base::fence_before(order);
103 storage_type original, result;
111 : "=&b" (original), "=&b" (result), "+Z" (storage)
113 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
115 core_arch_operations_gcc_ppc_base::fence_after(order);
119 static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
121 core_arch_operations_gcc_ppc_base::fence_before(order);
122 storage_type original, result;
130 : "=&b" (original), "=&b" (result), "+Z" (storage)
132 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
134 core_arch_operations_gcc_ppc_base::fence_after(order);
138 static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
140 storage_type original, result;
141 core_arch_operations_gcc_ppc_base::fence_before(order);
149 : "=&b" (original), "=&b" (result), "+Z" (storage)
151 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
153 core_arch_operations_gcc_ppc_base::fence_after(order);
157 static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
159 storage_type original, result;
160 core_arch_operations_gcc_ppc_base::fence_before(order);
168 : "=&b" (original), "=&b" (result), "+Z" (storage)
170 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
172 core_arch_operations_gcc_ppc_base::fence_after(order);
176 static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
178 storage_type original, result;
179 core_arch_operations_gcc_ppc_base::fence_before(order);
187 : "=&b" (original), "=&b" (result), "+Z" (storage)
189 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
191 core_arch_operations_gcc_ppc_base::fence_after(order);
195 static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
197 storage_type original, result;
198 core_arch_operations_gcc_ppc_base::fence_before(order);
206 : "=&b" (original), "=&b" (result), "+Z" (storage)
208 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
210 core_arch_operations_gcc_ppc_base::fence_after(order);
214 static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
216 storage_type original, result;
217 core_arch_operations_gcc_ppc_base::fence_before(order);
225 : "=&b" (original), "=&b" (result), "+Z" (storage)
227 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
229 core_arch_operations_gcc_ppc_base::fence_after(order);
233 static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
235 core_arch_operations_gcc_ppc_base::fence_before(order);
236 storage_type original, result;
244 : "=&b" (original), "=&b" (result), "+Z" (storage)
246 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
248 core_arch_operations_gcc_ppc_base::fence_after(order);
252 static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
254 core_arch_operations_gcc_ppc_base::fence_before(order);
255 storage_type original, result;
263 : "=&b" (original), "=&b" (result), "+Z" (storage)
265 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
267 core_arch_operations_gcc_ppc_base::fence_after(order);
272 template< typename Base, bool Signed >
273 struct extra_operations< Base, 1u, Signed, true > :
274 public extra_operations_gcc_ppc_common< extra_operations_gcc_ppc< Base, 1u, Signed > >
278 #endif // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LBARX_STBCX)
280 #if defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LHARX_STHCX)
282 template< typename Base, bool Signed >
283 struct extra_operations_gcc_ppc< Base, 2u, Signed > :
284 public extra_operations_generic< Base, 2u, Signed >
286 typedef extra_operations_generic< Base, 2u, Signed > base_type;
287 typedef typename base_type::storage_type storage_type;
289 static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
291 core_arch_operations_gcc_ppc_base::fence_before(order);
292 storage_type original, result;
300 : "=&b" (original), "=&b" (result), "+Z" (storage)
302 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
304 core_arch_operations_gcc_ppc_base::fence_after(order);
308 static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
310 core_arch_operations_gcc_ppc_base::fence_before(order);
311 storage_type original, result;
319 : "=&b" (original), "=&b" (result), "+Z" (storage)
321 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
323 core_arch_operations_gcc_ppc_base::fence_after(order);
327 static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
329 storage_type original, result;
330 core_arch_operations_gcc_ppc_base::fence_before(order);
338 : "=&b" (original), "=&b" (result), "+Z" (storage)
340 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
342 core_arch_operations_gcc_ppc_base::fence_after(order);
346 static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
348 storage_type original, result;
349 core_arch_operations_gcc_ppc_base::fence_before(order);
357 : "=&b" (original), "=&b" (result), "+Z" (storage)
359 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
361 core_arch_operations_gcc_ppc_base::fence_after(order);
365 static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
367 storage_type original, result;
368 core_arch_operations_gcc_ppc_base::fence_before(order);
376 : "=&b" (original), "=&b" (result), "+Z" (storage)
378 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
380 core_arch_operations_gcc_ppc_base::fence_after(order);
384 static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
386 storage_type original, result;
387 core_arch_operations_gcc_ppc_base::fence_before(order);
395 : "=&b" (original), "=&b" (result), "+Z" (storage)
397 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
399 core_arch_operations_gcc_ppc_base::fence_after(order);
403 static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
405 storage_type original, result;
406 core_arch_operations_gcc_ppc_base::fence_before(order);
414 : "=&b" (original), "=&b" (result), "+Z" (storage)
416 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
418 core_arch_operations_gcc_ppc_base::fence_after(order);
422 static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
424 core_arch_operations_gcc_ppc_base::fence_before(order);
425 storage_type original, result;
433 : "=&b" (original), "=&b" (result), "+Z" (storage)
435 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
437 core_arch_operations_gcc_ppc_base::fence_after(order);
441 static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
443 core_arch_operations_gcc_ppc_base::fence_before(order);
444 storage_type original, result;
452 : "=&b" (original), "=&b" (result), "+Z" (storage)
454 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
456 core_arch_operations_gcc_ppc_base::fence_after(order);
461 #endif // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LHARX_STHCX)
463 template< typename Base, bool Signed >
464 struct extra_operations_gcc_ppc< Base, 4u, Signed > :
465 public extra_operations_generic< Base, 4u, Signed >
467 typedef extra_operations_generic< Base, 4u, Signed > base_type;
468 typedef typename base_type::storage_type storage_type;
470 static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
472 core_arch_operations_gcc_ppc_base::fence_before(order);
473 storage_type original, result;
481 : "=&b" (original), "=&b" (result), "+Z" (storage)
483 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
485 core_arch_operations_gcc_ppc_base::fence_after(order);
489 static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
491 core_arch_operations_gcc_ppc_base::fence_before(order);
492 storage_type original, result;
500 : "=&b" (original), "=&b" (result), "+Z" (storage)
502 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
504 core_arch_operations_gcc_ppc_base::fence_after(order);
508 static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
510 storage_type original, result;
511 core_arch_operations_gcc_ppc_base::fence_before(order);
519 : "=&b" (original), "=&b" (result), "+Z" (storage)
521 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
523 core_arch_operations_gcc_ppc_base::fence_after(order);
527 static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
529 storage_type original, result;
530 core_arch_operations_gcc_ppc_base::fence_before(order);
538 : "=&b" (original), "=&b" (result), "+Z" (storage)
540 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
542 core_arch_operations_gcc_ppc_base::fence_after(order);
546 static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
548 storage_type original, result;
549 core_arch_operations_gcc_ppc_base::fence_before(order);
557 : "=&b" (original), "=&b" (result), "+Z" (storage)
559 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
561 core_arch_operations_gcc_ppc_base::fence_after(order);
565 static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
567 storage_type original, result;
568 core_arch_operations_gcc_ppc_base::fence_before(order);
576 : "=&b" (original), "=&b" (result), "+Z" (storage)
578 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
580 core_arch_operations_gcc_ppc_base::fence_after(order);
584 static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
586 storage_type original, result;
587 core_arch_operations_gcc_ppc_base::fence_before(order);
595 : "=&b" (original), "=&b" (result), "+Z" (storage)
597 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
599 core_arch_operations_gcc_ppc_base::fence_after(order);
603 static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
605 core_arch_operations_gcc_ppc_base::fence_before(order);
606 storage_type original, result;
614 : "=&b" (original), "=&b" (result), "+Z" (storage)
616 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
618 core_arch_operations_gcc_ppc_base::fence_after(order);
622 static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
624 core_arch_operations_gcc_ppc_base::fence_before(order);
625 storage_type original, result;
633 : "=&b" (original), "=&b" (result), "+Z" (storage)
635 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
637 core_arch_operations_gcc_ppc_base::fence_after(order);
642 template< typename Base, bool Signed >
643 struct extra_operations< Base, 4u, Signed, true > :
644 public extra_operations_gcc_ppc_common< extra_operations_gcc_ppc< Base, 4u, Signed > >
648 #if defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LDARX_STDCX)
650 template< typename Base, bool Signed >
651 struct extra_operations_gcc_ppc< Base, 8u, Signed > :
652 public extra_operations_generic< Base, 8u, Signed >
654 typedef extra_operations_generic< Base, 8u, Signed > base_type;
655 typedef typename base_type::storage_type storage_type;
657 static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
659 core_arch_operations_gcc_ppc_base::fence_before(order);
660 storage_type original, result;
668 : "=&b" (original), "=&b" (result), "+Z" (storage)
670 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
672 core_arch_operations_gcc_ppc_base::fence_after(order);
676 static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
678 core_arch_operations_gcc_ppc_base::fence_before(order);
679 storage_type original, result;
687 : "=&b" (original), "=&b" (result), "+Z" (storage)
689 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
691 core_arch_operations_gcc_ppc_base::fence_after(order);
695 static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
697 storage_type original, result;
698 core_arch_operations_gcc_ppc_base::fence_before(order);
706 : "=&b" (original), "=&b" (result), "+Z" (storage)
708 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
710 core_arch_operations_gcc_ppc_base::fence_after(order);
714 static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
716 storage_type original, result;
717 core_arch_operations_gcc_ppc_base::fence_before(order);
725 : "=&b" (original), "=&b" (result), "+Z" (storage)
727 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
729 core_arch_operations_gcc_ppc_base::fence_after(order);
733 static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
735 storage_type original, result;
736 core_arch_operations_gcc_ppc_base::fence_before(order);
744 : "=&b" (original), "=&b" (result), "+Z" (storage)
746 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
748 core_arch_operations_gcc_ppc_base::fence_after(order);
752 static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
754 storage_type original, result;
755 core_arch_operations_gcc_ppc_base::fence_before(order);
763 : "=&b" (original), "=&b" (result), "+Z" (storage)
765 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
767 core_arch_operations_gcc_ppc_base::fence_after(order);
771 static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
773 storage_type original, result;
774 core_arch_operations_gcc_ppc_base::fence_before(order);
782 : "=&b" (original), "=&b" (result), "+Z" (storage)
784 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
786 core_arch_operations_gcc_ppc_base::fence_after(order);
790 static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
792 core_arch_operations_gcc_ppc_base::fence_before(order);
793 storage_type original, result;
801 : "=&b" (original), "=&b" (result), "+Z" (storage)
803 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
805 core_arch_operations_gcc_ppc_base::fence_after(order);
809 static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
811 core_arch_operations_gcc_ppc_base::fence_before(order);
812 storage_type original, result;
820 : "=&b" (original), "=&b" (result), "+Z" (storage)
822 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
824 core_arch_operations_gcc_ppc_base::fence_after(order);
829 template< typename Base, bool Signed >
830 struct extra_operations< Base, 8u, Signed, true > :
831 public extra_operations_gcc_ppc_common< extra_operations_gcc_ppc< Base, 8u, Signed > >
835 #endif // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LDARX_STDCX)
837 } // namespace detail
838 } // namespace atomics
841 #include <boost/atomic/detail/footer.hpp>
843 #endif // BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_ARM_PPC_INCLUDED_