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_ARM_HPP_INCLUDED_
0015 #define BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_ARM_HPP_INCLUDED_
0016
0017 #include <cstddef>
0018 #include <boost/cstdint.hpp>
0019 #include <boost/memory_order.hpp>
0020 #include <boost/atomic/detail/config.hpp>
0021 #include <boost/atomic/detail/platform.hpp>
0022 #include <boost/atomic/detail/storage_traits.hpp>
0023 #include <boost/atomic/detail/extra_operations_fwd.hpp>
0024 #include <boost/atomic/detail/extra_ops_generic.hpp>
0025 #include <boost/atomic/detail/ops_gcc_arm_common.hpp>
0026 #include <boost/atomic/detail/gcc_arm_asm_common.hpp>
0027 #include <boost/atomic/detail/capabilities.hpp>
0028 #include <boost/atomic/detail/header.hpp>
0029
0030 #ifdef BOOST_HAS_PRAGMA_ONCE
0031 #pragma once
0032 #endif
0033
0034 namespace boost {
0035 namespace atomics {
0036 namespace detail {
0037
0038 template< typename Base >
0039 struct extra_operations_gcc_arm_common :
0040 public Base
0041 {
0042 typedef Base base_type;
0043 typedef typename base_type::storage_type storage_type;
0044
0045 static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0046 {
0047 base_type::fetch_negate(storage, order);
0048 }
0049
0050 static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0051 {
0052 base_type::fetch_complement(storage, order);
0053 }
0054
0055 static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0056 {
0057 return !!base_type::negate(storage, order);
0058 }
0059
0060 static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0061 {
0062 return !!base_type::add(storage, v, order);
0063 }
0064
0065 static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0066 {
0067 return !!base_type::sub(storage, v, order);
0068 }
0069
0070 static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0071 {
0072 return !!base_type::bitwise_and(storage, v, order);
0073 }
0074
0075 static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0076 {
0077 return !!base_type::bitwise_or(storage, v, order);
0078 }
0079
0080 static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0081 {
0082 return !!base_type::bitwise_xor(storage, v, order);
0083 }
0084
0085 static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0086 {
0087 return !!base_type::bitwise_complement(storage, order);
0088 }
0089 };
0090
0091 template< typename Base, std::size_t Size, bool Signed >
0092 struct extra_operations_gcc_arm;
0093
0094 #if defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXB_STREXB)
0095
0096 template< typename Base, bool Signed >
0097 struct extra_operations_gcc_arm< Base, 1u, Signed > :
0098 public extra_operations_generic< Base, 1u, Signed >
0099 {
0100 typedef extra_operations_generic< Base, 1u, Signed > base_type;
0101 typedef typename base_type::storage_type storage_type;
0102 typedef typename storage_traits< 4u >::type extended_storage_type;
0103
0104 static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0105 {
0106 core_arch_operations_gcc_arm_base::fence_before(order);
0107 uint32_t tmp;
0108 extended_storage_type original, result;
0109 __asm__ __volatile__
0110 (
0111 BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
0112 "1:\n\t"
0113 "ldrexb %[original], %[storage]\n\t"
0114 "rsb %[result], %[original], #0\n\t"
0115 "strexb %[tmp], %[result], %[storage]\n\t"
0116 "teq %[tmp], #0\n\t"
0117 "bne 1b\n\t"
0118 BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
0119 : [original] "=&r" (original),
0120 [result] "=&r" (result),
0121 [tmp] "=&l" (tmp),
0122 [storage] "+Q" (storage)
0123 :
0124 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0125 );
0126 core_arch_operations_gcc_arm_base::fence_after(order);
0127 return static_cast< storage_type >(original);
0128 }
0129
0130 static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0131 {
0132 core_arch_operations_gcc_arm_base::fence_before(order);
0133 uint32_t tmp;
0134 extended_storage_type original, result;
0135 __asm__ __volatile__
0136 (
0137 BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
0138 "1:\n\t"
0139 "ldrexb %[original], %[storage]\n\t"
0140 "rsb %[result], %[original], #0\n\t"
0141 "strexb %[tmp], %[result], %[storage]\n\t"
0142 "teq %[tmp], #0\n\t"
0143 "bne 1b\n\t"
0144 BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
0145 : [original] "=&r" (original),
0146 [result] "=&r" (result),
0147 [tmp] "=&l" (tmp),
0148 [storage] "+Q" (storage)
0149 :
0150 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0151 );
0152 core_arch_operations_gcc_arm_base::fence_after(order);
0153 return static_cast< storage_type >(result);
0154 }
0155
0156 static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0157 {
0158 core_arch_operations_gcc_arm_base::fence_before(order);
0159 uint32_t tmp;
0160 extended_storage_type original, result;
0161 __asm__ __volatile__
0162 (
0163 BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
0164 "1:\n\t"
0165 "ldrexb %[original], %[storage]\n\t"
0166 "add %[result], %[original], %[value]\n\t"
0167 "strexb %[tmp], %[result], %[storage]\n\t"
0168 "teq %[tmp], #0\n\t"
0169 "bne 1b\n\t"
0170 BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
0171 : [original] "=&r" (original),
0172 [result] "=&r" (result),
0173 [tmp] "=&l" (tmp),
0174 [storage] "+Q" (storage)
0175 : [value] "Ir" (v)
0176 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0177 );
0178 core_arch_operations_gcc_arm_base::fence_after(order);
0179 return static_cast< storage_type >(result);
0180 }
0181
0182 static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0183 {
0184 core_arch_operations_gcc_arm_base::fence_before(order);
0185 uint32_t tmp;
0186 extended_storage_type original, result;
0187 __asm__ __volatile__
0188 (
0189 BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
0190 "1:\n\t"
0191 "ldrexb %[original], %[storage]\n\t"
0192 "sub %[result], %[original], %[value]\n\t"
0193 "strexb %[tmp], %[result], %[storage]\n\t"
0194 "teq %[tmp], #0\n\t"
0195 "bne 1b\n\t"
0196 BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
0197 : [original] "=&r" (original),
0198 [result] "=&r" (result),
0199 [tmp] "=&l" (tmp),
0200 [storage] "+Q" (storage)
0201 : [value] "Ir" (v)
0202 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0203 );
0204 core_arch_operations_gcc_arm_base::fence_after(order);
0205 return static_cast< storage_type >(result);
0206 }
0207
0208 static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0209 {
0210 core_arch_operations_gcc_arm_base::fence_before(order);
0211 uint32_t tmp;
0212 extended_storage_type original, result;
0213 __asm__ __volatile__
0214 (
0215 BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
0216 "1:\n\t"
0217 "ldrexb %[original], %[storage]\n\t"
0218 "and %[result], %[original], %[value]\n\t"
0219 "strexb %[tmp], %[result], %[storage]\n\t"
0220 "teq %[tmp], #0\n\t"
0221 "bne 1b\n\t"
0222 BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
0223 : [original] "=&r" (original),
0224 [result] "=&r" (result),
0225 [tmp] "=&l" (tmp),
0226 [storage] "+Q" (storage)
0227 : [value] "Ir" (v)
0228 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0229 );
0230 core_arch_operations_gcc_arm_base::fence_after(order);
0231 return static_cast< storage_type >(result);
0232 }
0233
0234 static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0235 {
0236 core_arch_operations_gcc_arm_base::fence_before(order);
0237 uint32_t tmp;
0238 extended_storage_type original, result;
0239 __asm__ __volatile__
0240 (
0241 BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
0242 "1:\n\t"
0243 "ldrexb %[original], %[storage]\n\t"
0244 "orr %[result], %[original], %[value]\n\t"
0245 "strexb %[tmp], %[result], %[storage]\n\t"
0246 "teq %[tmp], #0\n\t"
0247 "bne 1b\n\t"
0248 BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
0249 : [original] "=&r" (original),
0250 [result] "=&r" (result),
0251 [tmp] "=&l" (tmp),
0252 [storage] "+Q" (storage)
0253 : [value] "Ir" (v)
0254 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0255 );
0256 core_arch_operations_gcc_arm_base::fence_after(order);
0257 return static_cast< storage_type >(result);
0258 }
0259
0260 static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0261 {
0262 core_arch_operations_gcc_arm_base::fence_before(order);
0263 uint32_t tmp;
0264 extended_storage_type original, result;
0265 __asm__ __volatile__
0266 (
0267 BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
0268 "1:\n\t"
0269 "ldrexb %[original], %[storage]\n\t"
0270 "eor %[result], %[original], %[value]\n\t"
0271 "strexb %[tmp], %[result], %[storage]\n\t"
0272 "teq %[tmp], #0\n\t"
0273 "bne 1b\n\t"
0274 BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
0275 : [original] "=&r" (original),
0276 [result] "=&r" (result),
0277 [tmp] "=&l" (tmp),
0278 [storage] "+Q" (storage)
0279 : [value] "Ir" (v)
0280 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0281 );
0282 core_arch_operations_gcc_arm_base::fence_after(order);
0283 return static_cast< storage_type >(result);
0284 }
0285
0286 static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0287 {
0288 core_arch_operations_gcc_arm_base::fence_before(order);
0289 uint32_t tmp;
0290 extended_storage_type original, result;
0291 __asm__ __volatile__
0292 (
0293 BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
0294 "1:\n\t"
0295 "ldrexb %[original], %[storage]\n\t"
0296 "mvn %[result], %[original]\n\t"
0297 "strexb %[tmp], %[result], %[storage]\n\t"
0298 "teq %[tmp], #0\n\t"
0299 "bne 1b\n\t"
0300 BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
0301 : [original] "=&r" (original),
0302 [result] "=&r" (result),
0303 [tmp] "=&l" (tmp),
0304 [storage] "+Q" (storage)
0305 :
0306 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0307 );
0308 core_arch_operations_gcc_arm_base::fence_after(order);
0309 return static_cast< storage_type >(original);
0310 }
0311
0312 static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0313 {
0314 core_arch_operations_gcc_arm_base::fence_before(order);
0315 uint32_t tmp;
0316 extended_storage_type original, result;
0317 __asm__ __volatile__
0318 (
0319 BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
0320 "1:\n\t"
0321 "ldrexb %[original], %[storage]\n\t"
0322 "mvn %[result], %[original]\n\t"
0323 "strexb %[tmp], %[result], %[storage]\n\t"
0324 "teq %[tmp], #0\n\t"
0325 "bne 1b\n\t"
0326 BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
0327 : [original] "=&r" (original),
0328 [result] "=&r" (result),
0329 [tmp] "=&l" (tmp),
0330 [storage] "+Q" (storage)
0331 :
0332 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0333 );
0334 core_arch_operations_gcc_arm_base::fence_after(order);
0335 return static_cast< storage_type >(result);
0336 }
0337 };
0338
0339 template< typename Base, bool Signed >
0340 struct extra_operations< Base, 1u, Signed, true > :
0341 public extra_operations_gcc_arm_common< extra_operations_gcc_arm< Base, 1u, Signed > >
0342 {
0343 };
0344
0345 #endif
0346
0347 #if defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXH_STREXH)
0348
0349 template< typename Base, bool Signed >
0350 struct extra_operations_gcc_arm< Base, 2u, Signed > :
0351 public extra_operations_generic< Base, 2u, Signed >
0352 {
0353 typedef extra_operations_generic< Base, 2u, Signed > base_type;
0354 typedef typename base_type::storage_type storage_type;
0355 typedef typename storage_traits< 4u >::type extended_storage_type;
0356
0357 static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0358 {
0359 core_arch_operations_gcc_arm_base::fence_before(order);
0360 uint32_t tmp;
0361 extended_storage_type original, result;
0362 __asm__ __volatile__
0363 (
0364 BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
0365 "1:\n\t"
0366 "ldrexh %[original], %[storage]\n\t"
0367 "rsb %[result], %[original], #0\n\t"
0368 "strexh %[tmp], %[result], %[storage]\n\t"
0369 "teq %[tmp], #0\n\t"
0370 "bne 1b\n\t"
0371 BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
0372 : [original] "=&r" (original),
0373 [result] "=&r" (result),
0374 [tmp] "=&l" (tmp),
0375 [storage] "+Q" (storage)
0376 :
0377 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0378 );
0379 core_arch_operations_gcc_arm_base::fence_after(order);
0380 return static_cast< storage_type >(original);
0381 }
0382
0383 static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0384 {
0385 core_arch_operations_gcc_arm_base::fence_before(order);
0386 uint32_t tmp;
0387 extended_storage_type original, result;
0388 __asm__ __volatile__
0389 (
0390 BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
0391 "1:\n\t"
0392 "ldrexh %[original], %[storage]\n\t"
0393 "rsb %[result], %[original], #0\n\t"
0394 "strexh %[tmp], %[result], %[storage]\n\t"
0395 "teq %[tmp], #0\n\t"
0396 "bne 1b\n\t"
0397 BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
0398 : [original] "=&r" (original),
0399 [result] "=&r" (result),
0400 [tmp] "=&l" (tmp),
0401 [storage] "+Q" (storage)
0402 :
0403 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0404 );
0405 core_arch_operations_gcc_arm_base::fence_after(order);
0406 return static_cast< storage_type >(result);
0407 }
0408
0409 static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0410 {
0411 core_arch_operations_gcc_arm_base::fence_before(order);
0412 uint32_t tmp;
0413 extended_storage_type original, result;
0414 __asm__ __volatile__
0415 (
0416 BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
0417 "1:\n\t"
0418 "ldrexh %[original], %[storage]\n\t"
0419 "add %[result], %[original], %[value]\n\t"
0420 "strexh %[tmp], %[result], %[storage]\n\t"
0421 "teq %[tmp], #0\n\t"
0422 "bne 1b\n\t"
0423 BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
0424 : [original] "=&r" (original),
0425 [result] "=&r" (result),
0426 [tmp] "=&l" (tmp),
0427 [storage] "+Q" (storage)
0428 : [value] "Ir" (v)
0429 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0430 );
0431 core_arch_operations_gcc_arm_base::fence_after(order);
0432 return static_cast< storage_type >(result);
0433 }
0434
0435 static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0436 {
0437 core_arch_operations_gcc_arm_base::fence_before(order);
0438 uint32_t tmp;
0439 extended_storage_type original, result;
0440 __asm__ __volatile__
0441 (
0442 BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
0443 "1:\n\t"
0444 "ldrexh %[original], %[storage]\n\t"
0445 "sub %[result], %[original], %[value]\n\t"
0446 "strexh %[tmp], %[result], %[storage]\n\t"
0447 "teq %[tmp], #0\n\t"
0448 "bne 1b\n\t"
0449 BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
0450 : [original] "=&r" (original),
0451 [result] "=&r" (result),
0452 [tmp] "=&l" (tmp),
0453 [storage] "+Q" (storage)
0454 : [value] "Ir" (v)
0455 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0456 );
0457 core_arch_operations_gcc_arm_base::fence_after(order);
0458 return static_cast< storage_type >(result);
0459 }
0460
0461 static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0462 {
0463 core_arch_operations_gcc_arm_base::fence_before(order);
0464 uint32_t tmp;
0465 extended_storage_type original, result;
0466 __asm__ __volatile__
0467 (
0468 BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
0469 "1:\n\t"
0470 "ldrexh %[original], %[storage]\n\t"
0471 "and %[result], %[original], %[value]\n\t"
0472 "strexh %[tmp], %[result], %[storage]\n\t"
0473 "teq %[tmp], #0\n\t"
0474 "bne 1b\n\t"
0475 BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
0476 : [original] "=&r" (original),
0477 [result] "=&r" (result),
0478 [tmp] "=&l" (tmp),
0479 [storage] "+Q" (storage)
0480 : [value] "Ir" (v)
0481 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0482 );
0483 core_arch_operations_gcc_arm_base::fence_after(order);
0484 return static_cast< storage_type >(result);
0485 }
0486
0487 static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0488 {
0489 core_arch_operations_gcc_arm_base::fence_before(order);
0490 uint32_t tmp;
0491 extended_storage_type original, result;
0492 __asm__ __volatile__
0493 (
0494 BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
0495 "1:\n\t"
0496 "ldrexh %[original], %[storage]\n\t"
0497 "orr %[result], %[original], %[value]\n\t"
0498 "strexh %[tmp], %[result], %[storage]\n\t"
0499 "teq %[tmp], #0\n\t"
0500 "bne 1b\n\t"
0501 BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
0502 : [original] "=&r" (original),
0503 [result] "=&r" (result),
0504 [tmp] "=&l" (tmp),
0505 [storage] "+Q" (storage)
0506 : [value] "Ir" (v)
0507 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0508 );
0509 core_arch_operations_gcc_arm_base::fence_after(order);
0510 return static_cast< storage_type >(result);
0511 }
0512
0513 static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0514 {
0515 core_arch_operations_gcc_arm_base::fence_before(order);
0516 uint32_t tmp;
0517 extended_storage_type original, result;
0518 __asm__ __volatile__
0519 (
0520 BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
0521 "1:\n\t"
0522 "ldrexh %[original], %[storage]\n\t"
0523 "eor %[result], %[original], %[value]\n\t"
0524 "strexh %[tmp], %[result], %[storage]\n\t"
0525 "teq %[tmp], #0\n\t"
0526 "bne 1b\n\t"
0527 BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
0528 : [original] "=&r" (original),
0529 [result] "=&r" (result),
0530 [tmp] "=&l" (tmp),
0531 [storage] "+Q" (storage)
0532 : [value] "Ir" (v)
0533 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0534 );
0535 core_arch_operations_gcc_arm_base::fence_after(order);
0536 return static_cast< storage_type >(result);
0537 }
0538
0539 static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0540 {
0541 core_arch_operations_gcc_arm_base::fence_before(order);
0542 uint32_t tmp;
0543 extended_storage_type original, result;
0544 __asm__ __volatile__
0545 (
0546 BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
0547 "1:\n\t"
0548 "ldrexh %[original], %[storage]\n\t"
0549 "mvn %[result], %[original]\n\t"
0550 "strexh %[tmp], %[result], %[storage]\n\t"
0551 "teq %[tmp], #0\n\t"
0552 "bne 1b\n\t"
0553 BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
0554 : [original] "=&r" (original),
0555 [result] "=&r" (result),
0556 [tmp] "=&l" (tmp),
0557 [storage] "+Q" (storage)
0558 :
0559 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0560 );
0561 core_arch_operations_gcc_arm_base::fence_after(order);
0562 return static_cast< storage_type >(original);
0563 }
0564
0565 static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0566 {
0567 core_arch_operations_gcc_arm_base::fence_before(order);
0568 uint32_t tmp;
0569 extended_storage_type original, result;
0570 __asm__ __volatile__
0571 (
0572 BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
0573 "1:\n\t"
0574 "ldrexh %[original], %[storage]\n\t"
0575 "mvn %[result], %[original]\n\t"
0576 "strexh %[tmp], %[result], %[storage]\n\t"
0577 "teq %[tmp], #0\n\t"
0578 "bne 1b\n\t"
0579 BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
0580 : [original] "=&r" (original),
0581 [result] "=&r" (result),
0582 [tmp] "=&l" (tmp),
0583 [storage] "+Q" (storage)
0584 :
0585 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0586 );
0587 core_arch_operations_gcc_arm_base::fence_after(order);
0588 return static_cast< storage_type >(result);
0589 }
0590 };
0591
0592 template< typename Base, bool Signed >
0593 struct extra_operations< Base, 2u, Signed, true > :
0594 public extra_operations_gcc_arm_common< extra_operations_gcc_arm< Base, 2u, Signed > >
0595 {
0596 };
0597
0598 #endif
0599
0600 template< typename Base, bool Signed >
0601 struct extra_operations_gcc_arm< Base, 4u, Signed > :
0602 public extra_operations_generic< Base, 4u, Signed >
0603 {
0604 typedef extra_operations_generic< Base, 4u, Signed > base_type;
0605 typedef typename base_type::storage_type storage_type;
0606
0607 static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0608 {
0609 core_arch_operations_gcc_arm_base::fence_before(order);
0610 uint32_t tmp;
0611 storage_type original, result;
0612 __asm__ __volatile__
0613 (
0614 BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
0615 "1:\n\t"
0616 "ldrex %[original], %[storage]\n\t"
0617 "rsb %[result], %[original], #0\n\t"
0618 "strex %[tmp], %[result], %[storage]\n\t"
0619 "teq %[tmp], #0\n\t"
0620 "bne 1b\n\t"
0621 BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
0622 : [original] "=&r" (original),
0623 [result] "=&r" (result),
0624 [tmp] "=&l" (tmp),
0625 [storage] "+Q" (storage)
0626 :
0627 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0628 );
0629 core_arch_operations_gcc_arm_base::fence_after(order);
0630 return original;
0631 }
0632
0633 static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0634 {
0635 core_arch_operations_gcc_arm_base::fence_before(order);
0636 uint32_t tmp;
0637 storage_type original, result;
0638 __asm__ __volatile__
0639 (
0640 BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
0641 "1:\n\t"
0642 "ldrex %[original], %[storage]\n\t"
0643 "rsb %[result], %[original], #0\n\t"
0644 "strex %[tmp], %[result], %[storage]\n\t"
0645 "teq %[tmp], #0\n\t"
0646 "bne 1b\n\t"
0647 BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
0648 : [original] "=&r" (original),
0649 [result] "=&r" (result),
0650 [tmp] "=&l" (tmp),
0651 [storage] "+Q" (storage)
0652 :
0653 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0654 );
0655 core_arch_operations_gcc_arm_base::fence_after(order);
0656 return result;
0657 }
0658
0659 static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0660 {
0661 core_arch_operations_gcc_arm_base::fence_before(order);
0662 uint32_t tmp;
0663 storage_type original, result;
0664 __asm__ __volatile__
0665 (
0666 BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
0667 "1:\n\t"
0668 "ldrex %[original], %[storage]\n\t"
0669 "add %[result], %[original], %[value]\n\t"
0670 "strex %[tmp], %[result], %[storage]\n\t"
0671 "teq %[tmp], #0\n\t"
0672 "bne 1b\n\t"
0673 BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
0674 : [original] "=&r" (original),
0675 [result] "=&r" (result),
0676 [tmp] "=&l" (tmp),
0677 [storage] "+Q" (storage)
0678 : [value] "Ir" (v)
0679 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0680 );
0681 core_arch_operations_gcc_arm_base::fence_after(order);
0682 return result;
0683 }
0684
0685 static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0686 {
0687 core_arch_operations_gcc_arm_base::fence_before(order);
0688 uint32_t tmp;
0689 storage_type original, result;
0690 __asm__ __volatile__
0691 (
0692 BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
0693 "1:\n\t"
0694 "ldrex %[original], %[storage]\n\t"
0695 "sub %[result], %[original], %[value]\n\t"
0696 "strex %[tmp], %[result], %[storage]\n\t"
0697 "teq %[tmp], #0\n\t"
0698 "bne 1b\n\t"
0699 BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
0700 : [original] "=&r" (original),
0701 [result] "=&r" (result),
0702 [tmp] "=&l" (tmp),
0703 [storage] "+Q" (storage)
0704 : [value] "Ir" (v)
0705 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0706 );
0707 core_arch_operations_gcc_arm_base::fence_after(order);
0708 return result;
0709 }
0710
0711 static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0712 {
0713 core_arch_operations_gcc_arm_base::fence_before(order);
0714 uint32_t tmp;
0715 storage_type original, result;
0716 __asm__ __volatile__
0717 (
0718 BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
0719 "1:\n\t"
0720 "ldrex %[original], %[storage]\n\t"
0721 "and %[result], %[original], %[value]\n\t"
0722 "strex %[tmp], %[result], %[storage]\n\t"
0723 "teq %[tmp], #0\n\t"
0724 "bne 1b\n\t"
0725 BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
0726 : [original] "=&r" (original),
0727 [result] "=&r" (result),
0728 [tmp] "=&l" (tmp),
0729 [storage] "+Q" (storage)
0730 : [value] "Ir" (v)
0731 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0732 );
0733 core_arch_operations_gcc_arm_base::fence_after(order);
0734 return result;
0735 }
0736
0737 static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0738 {
0739 core_arch_operations_gcc_arm_base::fence_before(order);
0740 uint32_t tmp;
0741 storage_type original, result;
0742 __asm__ __volatile__
0743 (
0744 BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
0745 "1:\n\t"
0746 "ldrex %[original], %[storage]\n\t"
0747 "orr %[result], %[original], %[value]\n\t"
0748 "strex %[tmp], %[result], %[storage]\n\t"
0749 "teq %[tmp], #0\n\t"
0750 "bne 1b\n\t"
0751 BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
0752 : [original] "=&r" (original),
0753 [result] "=&r" (result),
0754 [tmp] "=&l" (tmp),
0755 [storage] "+Q" (storage)
0756 : [value] "Ir" (v)
0757 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0758 );
0759 core_arch_operations_gcc_arm_base::fence_after(order);
0760 return result;
0761 }
0762
0763 static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0764 {
0765 core_arch_operations_gcc_arm_base::fence_before(order);
0766 uint32_t tmp;
0767 storage_type original, result;
0768 __asm__ __volatile__
0769 (
0770 BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
0771 "1:\n\t"
0772 "ldrex %[original], %[storage]\n\t"
0773 "eor %[result], %[original], %[value]\n\t"
0774 "strex %[tmp], %[result], %[storage]\n\t"
0775 "teq %[tmp], #0\n\t"
0776 "bne 1b\n\t"
0777 BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
0778 : [original] "=&r" (original),
0779 [result] "=&r" (result),
0780 [tmp] "=&l" (tmp),
0781 [storage] "+Q" (storage)
0782 : [value] "Ir" (v)
0783 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0784 );
0785 core_arch_operations_gcc_arm_base::fence_after(order);
0786 return result;
0787 }
0788
0789 static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0790 {
0791 core_arch_operations_gcc_arm_base::fence_before(order);
0792 uint32_t tmp;
0793 storage_type original, result;
0794 __asm__ __volatile__
0795 (
0796 BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
0797 "1:\n\t"
0798 "ldrex %[original], %[storage]\n\t"
0799 "mvn %[result], %[original]\n\t"
0800 "strex %[tmp], %[result], %[storage]\n\t"
0801 "teq %[tmp], #0\n\t"
0802 "bne 1b\n\t"
0803 BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
0804 : [original] "=&r" (original),
0805 [result] "=&r" (result),
0806 [tmp] "=&l" (tmp),
0807 [storage] "+Q" (storage)
0808 :
0809 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0810 );
0811 core_arch_operations_gcc_arm_base::fence_after(order);
0812 return original;
0813 }
0814
0815 static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0816 {
0817 core_arch_operations_gcc_arm_base::fence_before(order);
0818 uint32_t tmp;
0819 storage_type original, result;
0820 __asm__ __volatile__
0821 (
0822 BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
0823 "1:\n\t"
0824 "ldrex %[original], %[storage]\n\t"
0825 "mvn %[result], %[original]\n\t"
0826 "strex %[tmp], %[result], %[storage]\n\t"
0827 "teq %[tmp], #0\n\t"
0828 "bne 1b\n\t"
0829 BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
0830 : [original] "=&r" (original),
0831 [result] "=&r" (result),
0832 [tmp] "=&l" (tmp),
0833 [storage] "+Q" (storage)
0834 :
0835 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0836 );
0837 core_arch_operations_gcc_arm_base::fence_after(order);
0838 return result;
0839 }
0840 };
0841
0842 template< typename Base, bool Signed >
0843 struct extra_operations< Base, 4u, Signed, true > :
0844 public extra_operations_gcc_arm_common< extra_operations_gcc_arm< Base, 4u, Signed > >
0845 {
0846 };
0847
0848 #if defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXD_STREXD)
0849
0850 template< typename Base, bool Signed >
0851 struct extra_operations_gcc_arm< Base, 8u, Signed > :
0852 public extra_operations_generic< Base, 8u, Signed >
0853 {
0854 typedef extra_operations_generic< Base, 8u, Signed > base_type;
0855 typedef typename base_type::storage_type storage_type;
0856
0857 static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0858 {
0859 core_arch_operations_gcc_arm_base::fence_before(order);
0860 storage_type original, result;
0861 uint32_t tmp;
0862 __asm__ __volatile__
0863 (
0864 BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0)
0865 "1:\n\t"
0866 "ldrexd %1, %H1, %3\n\t"
0867 "mvn %2, %1\n\t"
0868 "mvn %H2, %H1\n\t"
0869 "adds " BOOST_ATOMIC_DETAIL_ARM_ASM_ARG_LO(2) ", " BOOST_ATOMIC_DETAIL_ARM_ASM_ARG_LO(2) ", #1\n\t"
0870 "adc " BOOST_ATOMIC_DETAIL_ARM_ASM_ARG_HI(2) ", " BOOST_ATOMIC_DETAIL_ARM_ASM_ARG_HI(2) ", #0\n\t"
0871 "strexd %0, %2, %H2, %3\n\t"
0872 "teq %0, #0\n\t"
0873 "bne 1b\n\t"
0874 BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0)
0875 : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp),
0876 "=&r" (original),
0877 "=&r" (result),
0878 "+Q" (storage)
0879 :
0880 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0881 );
0882 core_arch_operations_gcc_arm_base::fence_after(order);
0883 return original;
0884 }
0885
0886 static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0887 {
0888 core_arch_operations_gcc_arm_base::fence_before(order);
0889 storage_type original, result;
0890 uint32_t tmp;
0891 __asm__ __volatile__
0892 (
0893 BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0)
0894 "1:\n\t"
0895 "ldrexd %1, %H1, %3\n\t"
0896 "mvn %2, %1\n\t"
0897 "mvn %H2, %H1\n\t"
0898 "adds " BOOST_ATOMIC_DETAIL_ARM_ASM_ARG_LO(2) ", " BOOST_ATOMIC_DETAIL_ARM_ASM_ARG_LO(2) ", #1\n\t"
0899 "adc " BOOST_ATOMIC_DETAIL_ARM_ASM_ARG_HI(2) ", " BOOST_ATOMIC_DETAIL_ARM_ASM_ARG_HI(2) ", #0\n\t"
0900 "strexd %0, %2, %H2, %3\n\t"
0901 "teq %0, #0\n\t"
0902 "bne 1b\n\t"
0903 BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0)
0904 : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp),
0905 "=&r" (original),
0906 "=&r" (result),
0907 "+Q" (storage)
0908 :
0909 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0910 );
0911 core_arch_operations_gcc_arm_base::fence_after(order);
0912 return result;
0913 }
0914
0915 static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0916 {
0917 core_arch_operations_gcc_arm_base::fence_before(order);
0918 storage_type original, result;
0919 uint32_t tmp;
0920 __asm__ __volatile__
0921 (
0922 BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0)
0923 "1:\n\t"
0924 "ldrexd %1, %H1, %3\n\t"
0925 "adds " BOOST_ATOMIC_DETAIL_ARM_ASM_ARG_LO(2) ", " BOOST_ATOMIC_DETAIL_ARM_ASM_ARG_LO(1) ", " BOOST_ATOMIC_DETAIL_ARM_ASM_ARG_LO(4) "\n\t"
0926 "adc " BOOST_ATOMIC_DETAIL_ARM_ASM_ARG_HI(2) ", " BOOST_ATOMIC_DETAIL_ARM_ASM_ARG_HI(1) ", " BOOST_ATOMIC_DETAIL_ARM_ASM_ARG_HI(4) "\n\t"
0927 "strexd %0, %2, %H2, %3\n\t"
0928 "teq %0, #0\n\t"
0929 "bne 1b\n\t"
0930 BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0)
0931 : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp),
0932 "=&r" (original),
0933 "=&r" (result),
0934 "+Q" (storage)
0935 : "r" (v)
0936 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0937 );
0938 core_arch_operations_gcc_arm_base::fence_after(order);
0939 return result;
0940 }
0941
0942 static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0943 {
0944 core_arch_operations_gcc_arm_base::fence_before(order);
0945 storage_type original, result;
0946 uint32_t tmp;
0947 __asm__ __volatile__
0948 (
0949 BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0)
0950 "1:\n\t"
0951 "ldrexd %1, %H1, %3\n\t"
0952 "subs " BOOST_ATOMIC_DETAIL_ARM_ASM_ARG_LO(2) ", " BOOST_ATOMIC_DETAIL_ARM_ASM_ARG_LO(1) ", " BOOST_ATOMIC_DETAIL_ARM_ASM_ARG_LO(4) "\n\t"
0953 "sbc " BOOST_ATOMIC_DETAIL_ARM_ASM_ARG_HI(2) ", " BOOST_ATOMIC_DETAIL_ARM_ASM_ARG_HI(1) ", " BOOST_ATOMIC_DETAIL_ARM_ASM_ARG_HI(4) "\n\t"
0954 "strexd %0, %2, %H2, %3\n\t"
0955 "teq %0, #0\n\t"
0956 "bne 1b\n\t"
0957 BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0)
0958 : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp),
0959 "=&r" (original),
0960 "=&r" (result),
0961 "+Q" (storage)
0962 : "r" (v)
0963 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0964 );
0965 core_arch_operations_gcc_arm_base::fence_after(order);
0966 return result;
0967 }
0968
0969 static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0970 {
0971 core_arch_operations_gcc_arm_base::fence_before(order);
0972 storage_type original, result;
0973 uint32_t tmp;
0974 __asm__ __volatile__
0975 (
0976 BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0)
0977 "1:\n\t"
0978 "ldrexd %1, %H1, %3\n\t"
0979 "and %2, %1, %4\n\t"
0980 "and %H2, %H1, %H4\n\t"
0981 "strexd %0, %2, %H2, %3\n\t"
0982 "teq %0, #0\n\t"
0983 "bne 1b\n\t"
0984 BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0)
0985 : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp),
0986 "=&r" (original),
0987 "=&r" (result),
0988 "+Q" (storage)
0989 : "r" (v)
0990 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
0991 );
0992 core_arch_operations_gcc_arm_base::fence_after(order);
0993 return result;
0994 }
0995
0996 static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0997 {
0998 core_arch_operations_gcc_arm_base::fence_before(order);
0999 storage_type original, result;
1000 uint32_t tmp;
1001 __asm__ __volatile__
1002 (
1003 BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0)
1004 "1:\n\t"
1005 "ldrexd %1, %H1, %3\n\t"
1006 "orr %2, %1, %4\n\t"
1007 "orr %H2, %H1, %H4\n\t"
1008 "strexd %0, %2, %H2, %3\n\t"
1009 "teq %0, #0\n\t"
1010 "bne 1b\n\t"
1011 BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0)
1012 : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp),
1013 "=&r" (original),
1014 "=&r" (result),
1015 "+Q" (storage)
1016 : "r" (v)
1017 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
1018 );
1019 core_arch_operations_gcc_arm_base::fence_after(order);
1020 return result;
1021 }
1022
1023 static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
1024 {
1025 core_arch_operations_gcc_arm_base::fence_before(order);
1026 storage_type original, result;
1027 uint32_t tmp;
1028 __asm__ __volatile__
1029 (
1030 BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0)
1031 "1:\n\t"
1032 "ldrexd %1, %H1, %3\n\t"
1033 "eor %2, %1, %4\n\t"
1034 "eor %H2, %H1, %H4\n\t"
1035 "strexd %0, %2, %H2, %3\n\t"
1036 "teq %0, #0\n\t"
1037 "bne 1b\n\t"
1038 BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0)
1039 : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp),
1040 "=&r" (original),
1041 "=&r" (result),
1042 "+Q" (storage)
1043 : "r" (v)
1044 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
1045 );
1046 core_arch_operations_gcc_arm_base::fence_after(order);
1047 return result;
1048 }
1049
1050 static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
1051 {
1052 core_arch_operations_gcc_arm_base::fence_before(order);
1053 storage_type original, result;
1054 uint32_t tmp;
1055 __asm__ __volatile__
1056 (
1057 BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0)
1058 "1:\n\t"
1059 "ldrexd %1, %H1, %3\n\t"
1060 "mvn %2, %1\n\t"
1061 "mvn %H2, %H1\n\t"
1062 "strexd %0, %2, %H2, %3\n\t"
1063 "teq %0, #0\n\t"
1064 "bne 1b\n\t"
1065 BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0)
1066 : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp),
1067 "=&r" (original),
1068 "=&r" (result),
1069 "+Q" (storage)
1070 :
1071 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
1072 );
1073 core_arch_operations_gcc_arm_base::fence_after(order);
1074 return original;
1075 }
1076
1077 static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
1078 {
1079 core_arch_operations_gcc_arm_base::fence_before(order);
1080 storage_type original, result;
1081 uint32_t tmp;
1082 __asm__ __volatile__
1083 (
1084 BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0)
1085 "1:\n\t"
1086 "ldrexd %1, %H1, %3\n\t"
1087 "mvn %2, %1\n\t"
1088 "mvn %H2, %H1\n\t"
1089 "strexd %0, %2, %H2, %3\n\t"
1090 "teq %0, #0\n\t"
1091 "bne 1b\n\t"
1092 BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0)
1093 : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp),
1094 "=&r" (original),
1095 "=&r" (result),
1096 "+Q" (storage)
1097 :
1098 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
1099 );
1100 core_arch_operations_gcc_arm_base::fence_after(order);
1101 return result;
1102 }
1103 };
1104
1105 template< typename Base, bool Signed >
1106 struct extra_operations< Base, 8u, Signed, true > :
1107 public extra_operations_gcc_arm_common< extra_operations_gcc_arm< Base, 8u, Signed > >
1108 {
1109 };
1110
1111 #endif
1112
1113 }
1114 }
1115 }
1116
1117 #include <boost/atomic/detail/footer.hpp>
1118
1119 #endif