Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:33:55

0001 /*
0002  * Distributed under the Boost Software License, Version 1.0.
0003  * (See accompanying file LICENSE_1_0.txt or copy at
0004  * http://www.boost.org/LICENSE_1_0.txt)
0005  *
0006  * Copyright (c) 2017 - 2018 Andrey Semashev
0007  */
0008 /*!
0009  * \file   atomic/detail/extra_ops_gcc_ppc.hpp
0010  *
0011  * This header contains implementation of the extra atomic operations for PowerPC.
0012  */
0013 
0014 #ifndef BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_PPC_HPP_INCLUDED_
0015 #define BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_PPC_HPP_INCLUDED_
0016 
0017 #include <cstddef>
0018 #include <boost/memory_order.hpp>
0019 #include <boost/atomic/detail/config.hpp>
0020 #include <boost/atomic/detail/storage_traits.hpp>
0021 #include <boost/atomic/detail/extra_operations_fwd.hpp>
0022 #include <boost/atomic/detail/extra_ops_generic.hpp>
0023 #include <boost/atomic/detail/ops_gcc_ppc_common.hpp>
0024 #include <boost/atomic/detail/gcc_ppc_asm_common.hpp>
0025 #include <boost/atomic/detail/capabilities.hpp>
0026 #include <boost/atomic/detail/header.hpp>
0027 
0028 #ifdef BOOST_HAS_PRAGMA_ONCE
0029 #pragma once
0030 #endif
0031 
0032 namespace boost {
0033 namespace atomics {
0034 namespace detail {
0035 
0036 template< typename Base >
0037 struct extra_operations_gcc_ppc_common :
0038     public Base
0039 {
0040     typedef Base base_type;
0041     typedef typename base_type::storage_type storage_type;
0042 
0043     static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0044     {
0045         base_type::fetch_negate(storage, order);
0046     }
0047 
0048     static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0049     {
0050         base_type::fetch_complement(storage, order);
0051     }
0052 
0053     static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0054     {
0055         return !!base_type::negate(storage, order);
0056     }
0057 
0058     static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0059     {
0060         return !!base_type::add(storage, v, order);
0061     }
0062 
0063     static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0064     {
0065         return !!base_type::sub(storage, v, order);
0066     }
0067 
0068     static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0069     {
0070         return !!base_type::bitwise_and(storage, v, order);
0071     }
0072 
0073     static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0074     {
0075         return !!base_type::bitwise_or(storage, v, order);
0076     }
0077 
0078     static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0079     {
0080         return !!base_type::bitwise_xor(storage, v, order);
0081     }
0082 
0083     static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0084     {
0085         return !!base_type::bitwise_complement(storage, order);
0086     }
0087 };
0088 
0089 template< typename Base, std::size_t Size, bool Signed >
0090 struct extra_operations_gcc_ppc;
0091 
0092 #if defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LBARX_STBCX)
0093 
0094 template< typename Base, bool Signed >
0095 struct extra_operations_gcc_ppc< Base, 1u, Signed > :
0096     public extra_operations_generic< Base, 1u, Signed >
0097 {
0098     typedef extra_operations_generic< Base, 1u, Signed > base_type;
0099     typedef typename base_type::storage_type storage_type;
0100 
0101     static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0102     {
0103         core_arch_operations_gcc_ppc_base::fence_before(order);
0104         storage_type original, result;
0105         __asm__ __volatile__
0106         (
0107             BOOST_ATOMIC_DETAIL_PPC_ASM_LABEL("1")
0108             "lbarx %0,%y2\n\t"
0109             "neg %1,%0\n\t"
0110             "stbcx. %1,%y2\n\t"
0111             BOOST_ATOMIC_DETAIL_PPC_ASM_JUMP("bne-", "1b", "-12")
0112             : "=&b" (original), "=&b" (result), "+Z" (storage)
0113             :
0114             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0115         );
0116         core_arch_operations_gcc_ppc_base::fence_after(order);
0117         return original;
0118     }
0119 
0120     static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0121     {
0122         core_arch_operations_gcc_ppc_base::fence_before(order);
0123         storage_type original, result;
0124         __asm__ __volatile__
0125         (
0126             BOOST_ATOMIC_DETAIL_PPC_ASM_LABEL("1")
0127             "lbarx %0,%y2\n\t"
0128             "neg %1,%0\n\t"
0129             "stbcx. %1,%y2\n\t"
0130             BOOST_ATOMIC_DETAIL_PPC_ASM_JUMP("bne-", "1b", "-12")
0131             : "=&b" (original), "=&b" (result), "+Z" (storage)
0132             :
0133             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0134         );
0135         core_arch_operations_gcc_ppc_base::fence_after(order);
0136         return result;
0137     }
0138 
0139     static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0140     {
0141         storage_type original, result;
0142         core_arch_operations_gcc_ppc_base::fence_before(order);
0143         __asm__ __volatile__
0144         (
0145             BOOST_ATOMIC_DETAIL_PPC_ASM_LABEL("1")
0146             "lbarx %0,%y2\n\t"
0147             "add %1,%0,%3\n\t"
0148             "stbcx. %1,%y2\n\t"
0149             BOOST_ATOMIC_DETAIL_PPC_ASM_JUMP("bne-", "1b", "-12")
0150             : "=&b" (original), "=&b" (result), "+Z" (storage)
0151             : "b" (v)
0152             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0153         );
0154         core_arch_operations_gcc_ppc_base::fence_after(order);
0155         return result;
0156     }
0157 
0158     static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0159     {
0160         storage_type original, result;
0161         core_arch_operations_gcc_ppc_base::fence_before(order);
0162         __asm__ __volatile__
0163         (
0164             BOOST_ATOMIC_DETAIL_PPC_ASM_LABEL("1")
0165             "lbarx %0,%y2\n\t"
0166             "sub %1,%0,%3\n\t"
0167             "stbcx. %1,%y2\n\t"
0168             BOOST_ATOMIC_DETAIL_PPC_ASM_JUMP("bne-", "1b", "-12")
0169             : "=&b" (original), "=&b" (result), "+Z" (storage)
0170             : "b" (v)
0171             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0172         );
0173         core_arch_operations_gcc_ppc_base::fence_after(order);
0174         return result;
0175     }
0176 
0177     static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0178     {
0179         storage_type original, result;
0180         core_arch_operations_gcc_ppc_base::fence_before(order);
0181         __asm__ __volatile__
0182         (
0183             BOOST_ATOMIC_DETAIL_PPC_ASM_LABEL("1")
0184             "lbarx %0,%y2\n\t"
0185             "and %1,%0,%3\n\t"
0186             "stbcx. %1,%y2\n\t"
0187             BOOST_ATOMIC_DETAIL_PPC_ASM_JUMP("bne-", "1b", "-12")
0188             : "=&b" (original), "=&b" (result), "+Z" (storage)
0189             : "b" (v)
0190             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0191         );
0192         core_arch_operations_gcc_ppc_base::fence_after(order);
0193         return result;
0194     }
0195 
0196     static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0197     {
0198         storage_type original, result;
0199         core_arch_operations_gcc_ppc_base::fence_before(order);
0200         __asm__ __volatile__
0201         (
0202             BOOST_ATOMIC_DETAIL_PPC_ASM_LABEL("1")
0203             "lbarx %0,%y2\n\t"
0204             "or %1,%0,%3\n\t"
0205             "stbcx. %1,%y2\n\t"
0206             BOOST_ATOMIC_DETAIL_PPC_ASM_JUMP("bne-", "1b", "-12")
0207             : "=&b" (original), "=&b" (result), "+Z" (storage)
0208             : "b" (v)
0209             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0210         );
0211         core_arch_operations_gcc_ppc_base::fence_after(order);
0212         return result;
0213     }
0214 
0215     static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0216     {
0217         storage_type original, result;
0218         core_arch_operations_gcc_ppc_base::fence_before(order);
0219         __asm__ __volatile__
0220         (
0221             BOOST_ATOMIC_DETAIL_PPC_ASM_LABEL("1")
0222             "lbarx %0,%y2\n\t"
0223             "xor %1,%0,%3\n\t"
0224             "stbcx. %1,%y2\n\t"
0225             BOOST_ATOMIC_DETAIL_PPC_ASM_JUMP("bne-", "1b", "-12")
0226             : "=&b" (original), "=&b" (result), "+Z" (storage)
0227             : "b" (v)
0228             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0229         );
0230         core_arch_operations_gcc_ppc_base::fence_after(order);
0231         return result;
0232     }
0233 
0234     static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0235     {
0236         core_arch_operations_gcc_ppc_base::fence_before(order);
0237         storage_type original, result;
0238         __asm__ __volatile__
0239         (
0240             BOOST_ATOMIC_DETAIL_PPC_ASM_LABEL("1")
0241             "lbarx %0,%y2\n\t"
0242             "nor %1,%0,%0\n\t"
0243             "stbcx. %1,%y2\n\t"
0244             BOOST_ATOMIC_DETAIL_PPC_ASM_JUMP("bne-", "1b", "-12")
0245             : "=&b" (original), "=&b" (result), "+Z" (storage)
0246             :
0247             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0248         );
0249         core_arch_operations_gcc_ppc_base::fence_after(order);
0250         return original;
0251     }
0252 
0253     static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0254     {
0255         core_arch_operations_gcc_ppc_base::fence_before(order);
0256         storage_type original, result;
0257         __asm__ __volatile__
0258         (
0259             BOOST_ATOMIC_DETAIL_PPC_ASM_LABEL("1")
0260             "lbarx %0,%y2\n\t"
0261             "nor %1,%0,%0\n\t"
0262             "stbcx. %1,%y2\n\t"
0263             BOOST_ATOMIC_DETAIL_PPC_ASM_JUMP("bne-", "1b", "-12")
0264             : "=&b" (original), "=&b" (result), "+Z" (storage)
0265             :
0266             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0267         );
0268         core_arch_operations_gcc_ppc_base::fence_after(order);
0269         return result;
0270     }
0271 };
0272 
0273 template< typename Base, bool Signed >
0274 struct extra_operations< Base, 1u, Signed, true > :
0275     public extra_operations_gcc_ppc_common< extra_operations_gcc_ppc< Base, 1u, Signed > >
0276 {
0277 };
0278 
0279 #endif // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LBARX_STBCX)
0280 
0281 #if defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LHARX_STHCX)
0282 
0283 template< typename Base, bool Signed >
0284 struct extra_operations_gcc_ppc< Base, 2u, Signed > :
0285     public extra_operations_generic< Base, 2u, Signed >
0286 {
0287     typedef extra_operations_generic< Base, 2u, Signed > base_type;
0288     typedef typename base_type::storage_type storage_type;
0289 
0290     static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0291     {
0292         core_arch_operations_gcc_ppc_base::fence_before(order);
0293         storage_type original, result;
0294         __asm__ __volatile__
0295         (
0296             BOOST_ATOMIC_DETAIL_PPC_ASM_LABEL("1")
0297             "lharx %0,%y2\n\t"
0298             "neg %1,%0\n\t"
0299             "sthcx. %1,%y2\n\t"
0300             BOOST_ATOMIC_DETAIL_PPC_ASM_JUMP("bne-", "1b", "-12")
0301             : "=&b" (original), "=&b" (result), "+Z" (storage)
0302             :
0303             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0304         );
0305         core_arch_operations_gcc_ppc_base::fence_after(order);
0306         return original;
0307     }
0308 
0309     static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0310     {
0311         core_arch_operations_gcc_ppc_base::fence_before(order);
0312         storage_type original, result;
0313         __asm__ __volatile__
0314         (
0315             BOOST_ATOMIC_DETAIL_PPC_ASM_LABEL("1")
0316             "lharx %0,%y2\n\t"
0317             "neg %1,%0\n\t"
0318             "sthcx. %1,%y2\n\t"
0319             BOOST_ATOMIC_DETAIL_PPC_ASM_JUMP("bne-", "1b", "-12")
0320             : "=&b" (original), "=&b" (result), "+Z" (storage)
0321             :
0322             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0323         );
0324         core_arch_operations_gcc_ppc_base::fence_after(order);
0325         return result;
0326     }
0327 
0328     static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0329     {
0330         storage_type original, result;
0331         core_arch_operations_gcc_ppc_base::fence_before(order);
0332         __asm__ __volatile__
0333         (
0334             BOOST_ATOMIC_DETAIL_PPC_ASM_LABEL("1")
0335             "lharx %0,%y2\n\t"
0336             "add %1,%0,%3\n\t"
0337             "sthcx. %1,%y2\n\t"
0338             BOOST_ATOMIC_DETAIL_PPC_ASM_JUMP("bne-", "1b", "-12")
0339             : "=&b" (original), "=&b" (result), "+Z" (storage)
0340             : "b" (v)
0341             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0342         );
0343         core_arch_operations_gcc_ppc_base::fence_after(order);
0344         return result;
0345     }
0346 
0347     static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0348     {
0349         storage_type original, result;
0350         core_arch_operations_gcc_ppc_base::fence_before(order);
0351         __asm__ __volatile__
0352         (
0353             BOOST_ATOMIC_DETAIL_PPC_ASM_LABEL("1")
0354             "lharx %0,%y2\n\t"
0355             "sub %1,%0,%3\n\t"
0356             "sthcx. %1,%y2\n\t"
0357             BOOST_ATOMIC_DETAIL_PPC_ASM_JUMP("bne-", "1b", "-12")
0358             : "=&b" (original), "=&b" (result), "+Z" (storage)
0359             : "b" (v)
0360             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0361         );
0362         core_arch_operations_gcc_ppc_base::fence_after(order);
0363         return result;
0364     }
0365 
0366     static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0367     {
0368         storage_type original, result;
0369         core_arch_operations_gcc_ppc_base::fence_before(order);
0370         __asm__ __volatile__
0371         (
0372             BOOST_ATOMIC_DETAIL_PPC_ASM_LABEL("1")
0373             "lharx %0,%y2\n\t"
0374             "and %1,%0,%3\n\t"
0375             "sthcx. %1,%y2\n\t"
0376             BOOST_ATOMIC_DETAIL_PPC_ASM_JUMP("bne-", "1b", "-12")
0377             : "=&b" (original), "=&b" (result), "+Z" (storage)
0378             : "b" (v)
0379             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0380         );
0381         core_arch_operations_gcc_ppc_base::fence_after(order);
0382         return result;
0383     }
0384 
0385     static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0386     {
0387         storage_type original, result;
0388         core_arch_operations_gcc_ppc_base::fence_before(order);
0389         __asm__ __volatile__
0390         (
0391             BOOST_ATOMIC_DETAIL_PPC_ASM_LABEL("1")
0392             "lharx %0,%y2\n\t"
0393             "or %1,%0,%3\n\t"
0394             "sthcx. %1,%y2\n\t"
0395             BOOST_ATOMIC_DETAIL_PPC_ASM_JUMP("bne-", "1b", "-12")
0396             : "=&b" (original), "=&b" (result), "+Z" (storage)
0397             : "b" (v)
0398             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0399         );
0400         core_arch_operations_gcc_ppc_base::fence_after(order);
0401         return result;
0402     }
0403 
0404     static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0405     {
0406         storage_type original, result;
0407         core_arch_operations_gcc_ppc_base::fence_before(order);
0408         __asm__ __volatile__
0409         (
0410             BOOST_ATOMIC_DETAIL_PPC_ASM_LABEL("1")
0411             "lharx %0,%y2\n\t"
0412             "xor %1,%0,%3\n\t"
0413             "sthcx. %1,%y2\n\t"
0414             BOOST_ATOMIC_DETAIL_PPC_ASM_JUMP("bne-", "1b", "-12")
0415             : "=&b" (original), "=&b" (result), "+Z" (storage)
0416             : "b" (v)
0417             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0418         );
0419         core_arch_operations_gcc_ppc_base::fence_after(order);
0420         return result;
0421     }
0422 
0423     static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0424     {
0425         core_arch_operations_gcc_ppc_base::fence_before(order);
0426         storage_type original, result;
0427         __asm__ __volatile__
0428         (
0429             BOOST_ATOMIC_DETAIL_PPC_ASM_LABEL("1")
0430             "lharx %0,%y2\n\t"
0431             "nor %1,%0,%0\n\t"
0432             "sthcx. %1,%y2\n\t"
0433             BOOST_ATOMIC_DETAIL_PPC_ASM_JUMP("bne-", "1b", "-12")
0434             : "=&b" (original), "=&b" (result), "+Z" (storage)
0435             :
0436             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0437         );
0438         core_arch_operations_gcc_ppc_base::fence_after(order);
0439         return original;
0440     }
0441 
0442     static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0443     {
0444         core_arch_operations_gcc_ppc_base::fence_before(order);
0445         storage_type original, result;
0446         __asm__ __volatile__
0447         (
0448             BOOST_ATOMIC_DETAIL_PPC_ASM_LABEL("1")
0449             "lharx %0,%y2\n\t"
0450             "nor %1,%0,%0\n\t"
0451             "sthcx. %1,%y2\n\t"
0452             BOOST_ATOMIC_DETAIL_PPC_ASM_JUMP("bne-", "1b", "-12")
0453             : "=&b" (original), "=&b" (result), "+Z" (storage)
0454             :
0455             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0456         );
0457         core_arch_operations_gcc_ppc_base::fence_after(order);
0458         return result;
0459     }
0460 };
0461 
0462 #endif // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LHARX_STHCX)
0463 
0464 template< typename Base, bool Signed >
0465 struct extra_operations_gcc_ppc< Base, 4u, Signed > :
0466     public extra_operations_generic< Base, 4u, Signed >
0467 {
0468     typedef extra_operations_generic< Base, 4u, Signed > base_type;
0469     typedef typename base_type::storage_type storage_type;
0470 
0471     static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0472     {
0473         core_arch_operations_gcc_ppc_base::fence_before(order);
0474         storage_type original, result;
0475         __asm__ __volatile__
0476         (
0477             BOOST_ATOMIC_DETAIL_PPC_ASM_LABEL("1")
0478             "lwarx %0,%y2\n\t"
0479             "neg %1,%0\n\t"
0480             "stwcx. %1,%y2\n\t"
0481             BOOST_ATOMIC_DETAIL_PPC_ASM_JUMP("bne-", "1b", "-12")
0482             : "=&b" (original), "=&b" (result), "+Z" (storage)
0483             :
0484             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0485         );
0486         core_arch_operations_gcc_ppc_base::fence_after(order);
0487         return original;
0488     }
0489 
0490     static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0491     {
0492         core_arch_operations_gcc_ppc_base::fence_before(order);
0493         storage_type original, result;
0494         __asm__ __volatile__
0495         (
0496             BOOST_ATOMIC_DETAIL_PPC_ASM_LABEL("1")
0497             "lwarx %0,%y2\n\t"
0498             "neg %1,%0\n\t"
0499             "stwcx. %1,%y2\n\t"
0500             BOOST_ATOMIC_DETAIL_PPC_ASM_JUMP("bne-", "1b", "-12")
0501             : "=&b" (original), "=&b" (result), "+Z" (storage)
0502             :
0503             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0504         );
0505         core_arch_operations_gcc_ppc_base::fence_after(order);
0506         return result;
0507     }
0508 
0509     static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0510     {
0511         storage_type original, result;
0512         core_arch_operations_gcc_ppc_base::fence_before(order);
0513         __asm__ __volatile__
0514         (
0515             BOOST_ATOMIC_DETAIL_PPC_ASM_LABEL("1")
0516             "lwarx %0,%y2\n\t"
0517             "add %1,%0,%3\n\t"
0518             "stwcx. %1,%y2\n\t"
0519             BOOST_ATOMIC_DETAIL_PPC_ASM_JUMP("bne-", "1b", "-12")
0520             : "=&b" (original), "=&b" (result), "+Z" (storage)
0521             : "b" (v)
0522             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0523         );
0524         core_arch_operations_gcc_ppc_base::fence_after(order);
0525         return result;
0526     }
0527 
0528     static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0529     {
0530         storage_type original, result;
0531         core_arch_operations_gcc_ppc_base::fence_before(order);
0532         __asm__ __volatile__
0533         (
0534             BOOST_ATOMIC_DETAIL_PPC_ASM_LABEL("1")
0535             "lwarx %0,%y2\n\t"
0536             "sub %1,%0,%3\n\t"
0537             "stwcx. %1,%y2\n\t"
0538             BOOST_ATOMIC_DETAIL_PPC_ASM_JUMP("bne-", "1b", "-12")
0539             : "=&b" (original), "=&b" (result), "+Z" (storage)
0540             : "b" (v)
0541             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0542         );
0543         core_arch_operations_gcc_ppc_base::fence_after(order);
0544         return result;
0545     }
0546 
0547     static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0548     {
0549         storage_type original, result;
0550         core_arch_operations_gcc_ppc_base::fence_before(order);
0551         __asm__ __volatile__
0552         (
0553             BOOST_ATOMIC_DETAIL_PPC_ASM_LABEL("1")
0554             "lwarx %0,%y2\n\t"
0555             "and %1,%0,%3\n\t"
0556             "stwcx. %1,%y2\n\t"
0557             BOOST_ATOMIC_DETAIL_PPC_ASM_JUMP("bne-", "1b", "-12")
0558             : "=&b" (original), "=&b" (result), "+Z" (storage)
0559             : "b" (v)
0560             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0561         );
0562         core_arch_operations_gcc_ppc_base::fence_after(order);
0563         return result;
0564     }
0565 
0566     static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0567     {
0568         storage_type original, result;
0569         core_arch_operations_gcc_ppc_base::fence_before(order);
0570         __asm__ __volatile__
0571         (
0572             BOOST_ATOMIC_DETAIL_PPC_ASM_LABEL("1")
0573             "lwarx %0,%y2\n\t"
0574             "or %1,%0,%3\n\t"
0575             "stwcx. %1,%y2\n\t"
0576             BOOST_ATOMIC_DETAIL_PPC_ASM_JUMP("bne-", "1b", "-12")
0577             : "=&b" (original), "=&b" (result), "+Z" (storage)
0578             : "b" (v)
0579             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0580         );
0581         core_arch_operations_gcc_ppc_base::fence_after(order);
0582         return result;
0583     }
0584 
0585     static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0586     {
0587         storage_type original, result;
0588         core_arch_operations_gcc_ppc_base::fence_before(order);
0589         __asm__ __volatile__
0590         (
0591             BOOST_ATOMIC_DETAIL_PPC_ASM_LABEL("1")
0592             "lwarx %0,%y2\n\t"
0593             "xor %1,%0,%3\n\t"
0594             "stwcx. %1,%y2\n\t"
0595             BOOST_ATOMIC_DETAIL_PPC_ASM_JUMP("bne-", "1b", "-12")
0596             : "=&b" (original), "=&b" (result), "+Z" (storage)
0597             : "b" (v)
0598             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0599         );
0600         core_arch_operations_gcc_ppc_base::fence_after(order);
0601         return result;
0602     }
0603 
0604     static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0605     {
0606         core_arch_operations_gcc_ppc_base::fence_before(order);
0607         storage_type original, result;
0608         __asm__ __volatile__
0609         (
0610             BOOST_ATOMIC_DETAIL_PPC_ASM_LABEL("1")
0611             "lwarx %0,%y2\n\t"
0612             "nor %1,%0,%0\n\t"
0613             "stwcx. %1,%y2\n\t"
0614             BOOST_ATOMIC_DETAIL_PPC_ASM_JUMP("bne-", "1b", "-12")
0615             : "=&b" (original), "=&b" (result), "+Z" (storage)
0616             :
0617             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0618         );
0619         core_arch_operations_gcc_ppc_base::fence_after(order);
0620         return original;
0621     }
0622 
0623     static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0624     {
0625         core_arch_operations_gcc_ppc_base::fence_before(order);
0626         storage_type original, result;
0627         __asm__ __volatile__
0628         (
0629             BOOST_ATOMIC_DETAIL_PPC_ASM_LABEL("1")
0630             "lwarx %0,%y2\n\t"
0631             "nor %1,%0,%0\n\t"
0632             "stwcx. %1,%y2\n\t"
0633             BOOST_ATOMIC_DETAIL_PPC_ASM_JUMP("bne-", "1b", "-12")
0634             : "=&b" (original), "=&b" (result), "+Z" (storage)
0635             :
0636             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0637         );
0638         core_arch_operations_gcc_ppc_base::fence_after(order);
0639         return result;
0640     }
0641 };
0642 
0643 template< typename Base, bool Signed >
0644 struct extra_operations< Base, 4u, Signed, true > :
0645     public extra_operations_gcc_ppc_common< extra_operations_gcc_ppc< Base, 4u, Signed > >
0646 {
0647 };
0648 
0649 #if defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LDARX_STDCX)
0650 
0651 template< typename Base, bool Signed >
0652 struct extra_operations_gcc_ppc< Base, 8u, Signed > :
0653     public extra_operations_generic< Base, 8u, Signed >
0654 {
0655     typedef extra_operations_generic< Base, 8u, Signed > base_type;
0656     typedef typename base_type::storage_type storage_type;
0657 
0658     static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0659     {
0660         core_arch_operations_gcc_ppc_base::fence_before(order);
0661         storage_type original, result;
0662         __asm__ __volatile__
0663         (
0664             BOOST_ATOMIC_DETAIL_PPC_ASM_LABEL("1")
0665             "ldarx %0,%y2\n\t"
0666             "neg %1,%0\n\t"
0667             "stdcx. %1,%y2\n\t"
0668             BOOST_ATOMIC_DETAIL_PPC_ASM_JUMP("bne-", "1b", "-12")
0669             : "=&b" (original), "=&b" (result), "+Z" (storage)
0670             :
0671             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0672         );
0673         core_arch_operations_gcc_ppc_base::fence_after(order);
0674         return original;
0675     }
0676 
0677     static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0678     {
0679         core_arch_operations_gcc_ppc_base::fence_before(order);
0680         storage_type original, result;
0681         __asm__ __volatile__
0682         (
0683             BOOST_ATOMIC_DETAIL_PPC_ASM_LABEL("1")
0684             "ldarx %0,%y2\n\t"
0685             "neg %1,%0\n\t"
0686             "stdcx. %1,%y2\n\t"
0687             BOOST_ATOMIC_DETAIL_PPC_ASM_JUMP("bne-", "1b", "-12")
0688             : "=&b" (original), "=&b" (result), "+Z" (storage)
0689             :
0690             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0691         );
0692         core_arch_operations_gcc_ppc_base::fence_after(order);
0693         return result;
0694     }
0695 
0696     static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0697     {
0698         storage_type original, result;
0699         core_arch_operations_gcc_ppc_base::fence_before(order);
0700         __asm__ __volatile__
0701         (
0702             BOOST_ATOMIC_DETAIL_PPC_ASM_LABEL("1")
0703             "ldarx %0,%y2\n\t"
0704             "add %1,%0,%3\n\t"
0705             "stdcx. %1,%y2\n\t"
0706             BOOST_ATOMIC_DETAIL_PPC_ASM_JUMP("bne-", "1b", "-12")
0707             : "=&b" (original), "=&b" (result), "+Z" (storage)
0708             : "b" (v)
0709             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0710         );
0711         core_arch_operations_gcc_ppc_base::fence_after(order);
0712         return result;
0713     }
0714 
0715     static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0716     {
0717         storage_type original, result;
0718         core_arch_operations_gcc_ppc_base::fence_before(order);
0719         __asm__ __volatile__
0720         (
0721             BOOST_ATOMIC_DETAIL_PPC_ASM_LABEL("1")
0722             "ldarx %0,%y2\n\t"
0723             "sub %1,%0,%3\n\t"
0724             "stdcx. %1,%y2\n\t"
0725             BOOST_ATOMIC_DETAIL_PPC_ASM_JUMP("bne-", "1b", "-12")
0726             : "=&b" (original), "=&b" (result), "+Z" (storage)
0727             : "b" (v)
0728             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0729         );
0730         core_arch_operations_gcc_ppc_base::fence_after(order);
0731         return result;
0732     }
0733 
0734     static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0735     {
0736         storage_type original, result;
0737         core_arch_operations_gcc_ppc_base::fence_before(order);
0738         __asm__ __volatile__
0739         (
0740             BOOST_ATOMIC_DETAIL_PPC_ASM_LABEL("1")
0741             "ldarx %0,%y2\n\t"
0742             "and %1,%0,%3\n\t"
0743             "stdcx. %1,%y2\n\t"
0744             BOOST_ATOMIC_DETAIL_PPC_ASM_JUMP("bne-", "1b", "-12")
0745             : "=&b" (original), "=&b" (result), "+Z" (storage)
0746             : "b" (v)
0747             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0748         );
0749         core_arch_operations_gcc_ppc_base::fence_after(order);
0750         return result;
0751     }
0752 
0753     static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0754     {
0755         storage_type original, result;
0756         core_arch_operations_gcc_ppc_base::fence_before(order);
0757         __asm__ __volatile__
0758         (
0759             BOOST_ATOMIC_DETAIL_PPC_ASM_LABEL("1")
0760             "ldarx %0,%y2\n\t"
0761             "or %1,%0,%3\n\t"
0762             "stdcx. %1,%y2\n\t"
0763             BOOST_ATOMIC_DETAIL_PPC_ASM_JUMP("bne-", "1b", "-12")
0764             : "=&b" (original), "=&b" (result), "+Z" (storage)
0765             : "b" (v)
0766             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0767         );
0768         core_arch_operations_gcc_ppc_base::fence_after(order);
0769         return result;
0770     }
0771 
0772     static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0773     {
0774         storage_type original, result;
0775         core_arch_operations_gcc_ppc_base::fence_before(order);
0776         __asm__ __volatile__
0777         (
0778             BOOST_ATOMIC_DETAIL_PPC_ASM_LABEL("1")
0779             "ldarx %0,%y2\n\t"
0780             "xor %1,%0,%3\n\t"
0781             "stdcx. %1,%y2\n\t"
0782             BOOST_ATOMIC_DETAIL_PPC_ASM_JUMP("bne-", "1b", "-12")
0783             : "=&b" (original), "=&b" (result), "+Z" (storage)
0784             : "b" (v)
0785             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0786         );
0787         core_arch_operations_gcc_ppc_base::fence_after(order);
0788         return result;
0789     }
0790 
0791     static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0792     {
0793         core_arch_operations_gcc_ppc_base::fence_before(order);
0794         storage_type original, result;
0795         __asm__ __volatile__
0796         (
0797             BOOST_ATOMIC_DETAIL_PPC_ASM_LABEL("1")
0798             "ldarx %0,%y2\n\t"
0799             "nor %1,%0,%0\n\t"
0800             "stdcx. %1,%y2\n\t"
0801             BOOST_ATOMIC_DETAIL_PPC_ASM_JUMP("bne-", "1b", "-12")
0802             : "=&b" (original), "=&b" (result), "+Z" (storage)
0803             :
0804             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0805         );
0806         core_arch_operations_gcc_ppc_base::fence_after(order);
0807         return original;
0808     }
0809 
0810     static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0811     {
0812         core_arch_operations_gcc_ppc_base::fence_before(order);
0813         storage_type original, result;
0814         __asm__ __volatile__
0815         (
0816             BOOST_ATOMIC_DETAIL_PPC_ASM_LABEL("1")
0817             "ldarx %0,%y2\n\t"
0818             "nor %1,%0,%0\n\t"
0819             "stdcx. %1,%y2\n\t"
0820             BOOST_ATOMIC_DETAIL_PPC_ASM_JUMP("bne-", "1b", "-12")
0821             : "=&b" (original), "=&b" (result), "+Z" (storage)
0822             :
0823             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0824         );
0825         core_arch_operations_gcc_ppc_base::fence_after(order);
0826         return result;
0827     }
0828 };
0829 
0830 template< typename Base, bool Signed >
0831 struct extra_operations< Base, 8u, Signed, true > :
0832     public extra_operations_gcc_ppc_common< extra_operations_gcc_ppc< Base, 8u, Signed > >
0833 {
0834 };
0835 
0836 #endif // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LDARX_STDCX)
0837 
0838 } // namespace detail
0839 } // namespace atomics
0840 } // namespace boost
0841 
0842 #include <boost/atomic/detail/footer.hpp>
0843 
0844 #endif // BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_ARM_PPC_INCLUDED_