File indexing completed on 2025-01-30 09:33:55
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
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
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
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
0837
0838 }
0839 }
0840 }
0841
0842 #include <boost/atomic/detail/footer.hpp>
0843
0844 #endif