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