1 /* 2 * Distributed under the Boost Software License, Version 1.0. 3 * (See accompanying file LICENSE_1_0.txt or copy at 4 * http://www.boost.org/LICENSE_1_0.txt) 5 * 6 * Copyright (c) 2020 Andrey Semashev 7 */ 8 /*! 9 * \file atomic/detail/extra_ops_gcc_aarch32.hpp 10 * 11 * This header contains implementation of the extra atomic operations for AArch32. 12 */ 13 14 #ifndef BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_AARCH32_HPP_INCLUDED_ 15 #define BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_AARCH32_HPP_INCLUDED_ 16 17 #include <cstddef> 18 #include <boost/cstdint.hpp> 19 #include <boost/memory_order.hpp> 20 #include <boost/atomic/detail/config.hpp> 21 #include <boost/atomic/detail/platform.hpp> 22 #include <boost/atomic/detail/storage_traits.hpp> 23 #include <boost/atomic/detail/extra_operations_fwd.hpp> 24 #include <boost/atomic/detail/extra_ops_generic.hpp> 25 #include <boost/atomic/detail/ops_gcc_aarch32_common.hpp> 26 #include <boost/atomic/detail/capabilities.hpp> 27 #include <boost/atomic/detail/header.hpp> 28 29 #ifdef BOOST_HAS_PRAGMA_ONCE 30 #pragma once 31 #endif 32 33 namespace boost { 34 namespace atomics { 35 namespace detail { 36 37 template< typename Base > 38 struct extra_operations_gcc_aarch32_common : 39 public Base 40 { 41 typedef Base base_type; 42 typedef typename base_type::storage_type storage_type; 43 44 // Note: For opaque operations prefer operations returning the resulting values instead of the original values 45 // as these operations require less registers. opaque_negateboost::atomics::detail::extra_operations_gcc_aarch32_common46 static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT 47 { 48 base_type::negate(storage, order); 49 } 50 opaque_complementboost::atomics::detail::extra_operations_gcc_aarch32_common51 static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT 52 { 53 base_type::bitwise_complement(storage, order); 54 } 55 opaque_addboost::atomics::detail::extra_operations_gcc_aarch32_common56 static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT 57 { 58 base_type::add(storage, v, order); 59 } 60 opaque_subboost::atomics::detail::extra_operations_gcc_aarch32_common61 static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT 62 { 63 base_type::sub(storage, v, order); 64 } 65 opaque_andboost::atomics::detail::extra_operations_gcc_aarch32_common66 static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT 67 { 68 base_type::bitwise_and(storage, v, order); 69 } 70 opaque_orboost::atomics::detail::extra_operations_gcc_aarch32_common71 static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT 72 { 73 base_type::bitwise_or(storage, v, order); 74 } 75 opaque_xorboost::atomics::detail::extra_operations_gcc_aarch32_common76 static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT 77 { 78 base_type::bitwise_xor(storage, v, order); 79 } 80 negate_and_testboost::atomics::detail::extra_operations_gcc_aarch32_common81 static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT 82 { 83 return !!base_type::negate(storage, order); 84 } 85 add_and_testboost::atomics::detail::extra_operations_gcc_aarch32_common86 static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT 87 { 88 return !!base_type::add(storage, v, order); 89 } 90 sub_and_testboost::atomics::detail::extra_operations_gcc_aarch32_common91 static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT 92 { 93 return !!base_type::sub(storage, v, order); 94 } 95 and_and_testboost::atomics::detail::extra_operations_gcc_aarch32_common96 static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT 97 { 98 return !!base_type::bitwise_and(storage, v, order); 99 } 100 or_and_testboost::atomics::detail::extra_operations_gcc_aarch32_common101 static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT 102 { 103 return !!base_type::bitwise_or(storage, v, order); 104 } 105 xor_and_testboost::atomics::detail::extra_operations_gcc_aarch32_common106 static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT 107 { 108 return !!base_type::bitwise_xor(storage, v, order); 109 } 110 complement_and_testboost::atomics::detail::extra_operations_gcc_aarch32_common111 static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT 112 { 113 return !!base_type::bitwise_complement(storage, order); 114 } 115 }; 116 117 template< typename Base, std::size_t Size, bool Signed > 118 struct extra_operations_gcc_aarch32; 119 120 template< typename Base, bool Signed > 121 struct extra_operations_gcc_aarch32< Base, 1u, Signed > : 122 public extra_operations_generic< Base, 1u, Signed > 123 { 124 typedef extra_operations_generic< Base, 1u, Signed > base_type; 125 typedef typename base_type::storage_type storage_type; 126 fetch_negateboost::atomics::detail::extra_operations_gcc_aarch32127 static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT 128 { 129 storage_type original, result; 130 uint32_t tmp; 131 #define BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN(ld_mo, st_mo)\ 132 __asm__ __volatile__\ 133 (\ 134 "1:\n\t"\ 135 "ld" ld_mo "exb %[original], %[storage]\n\t"\ 136 "rsb %[result], %[original], #0\n\t"\ 137 "st" st_mo "exb %[tmp], %[result], %[storage]\n\t"\ 138 "teq %[tmp], #0\n\t"\ 139 "bne 1b\n\t"\ 140 : [original] "=&r" (original), [result] "=&r" (result), [tmp] "=&r" (tmp), [storage] "+Q" (storage)\ 141 : \ 142 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 143 ); 144 145 BOOST_ATOMIC_DETAIL_AARCH32_MO_SWITCH(order) 146 #undef BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN 147 148 return original; 149 } 150 negateboost::atomics::detail::extra_operations_gcc_aarch32151 static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT 152 { 153 storage_type result; 154 uint32_t tmp; 155 #define BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN(ld_mo, st_mo)\ 156 __asm__ __volatile__\ 157 (\ 158 "1:\n\t"\ 159 "ld" ld_mo "exb %[result], %[storage]\n\t"\ 160 "rsb %[result], %[result], #0\n\t"\ 161 "st" st_mo "exb %[tmp], %[result], %[storage]\n\t"\ 162 "teq %[tmp], #0\n\t"\ 163 "bne 1b\n\t"\ 164 : [result] "=&r" (result), [tmp] "=&r" (tmp), [storage] "+Q" (storage)\ 165 : \ 166 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 167 ); 168 169 BOOST_ATOMIC_DETAIL_AARCH32_MO_SWITCH(order) 170 #undef BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN 171 172 return result; 173 } 174 addboost::atomics::detail::extra_operations_gcc_aarch32175 static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT 176 { 177 storage_type result; 178 uint32_t tmp; 179 #define BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN(ld_mo, st_mo)\ 180 __asm__ __volatile__\ 181 (\ 182 "1:\n\t"\ 183 "ld" ld_mo "exb %[result], %[storage]\n\t"\ 184 "add %[result], %[result], %[value]\n\t"\ 185 "st" st_mo "exb %[tmp], %[result], %[storage]\n\t"\ 186 "teq %[tmp], #0\n\t"\ 187 "bne 1b\n\t"\ 188 : [result] "=&r" (result), [tmp] "=&r" (tmp), [storage] "+Q" (storage)\ 189 : [value] "Ir" (v)\ 190 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 191 ); 192 193 BOOST_ATOMIC_DETAIL_AARCH32_MO_SWITCH(order) 194 #undef BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN 195 196 return result; 197 } 198 subboost::atomics::detail::extra_operations_gcc_aarch32199 static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT 200 { 201 storage_type result; 202 uint32_t tmp; 203 #define BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN(ld_mo, st_mo)\ 204 __asm__ __volatile__\ 205 (\ 206 "1:\n\t"\ 207 "ld" ld_mo "exb %[result], %[storage]\n\t"\ 208 "sub %[result], %[result], %[value]\n\t"\ 209 "st" st_mo "exb %[tmp], %[result], %[storage]\n\t"\ 210 "teq %[tmp], #0\n\t"\ 211 "bne 1b\n\t"\ 212 : [result] "=&r" (result), [tmp] "=&r" (tmp), [storage] "+Q" (storage)\ 213 : [value] "Ir" (v)\ 214 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 215 ); 216 217 BOOST_ATOMIC_DETAIL_AARCH32_MO_SWITCH(order) 218 #undef BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN 219 220 return result; 221 } 222 bitwise_andboost::atomics::detail::extra_operations_gcc_aarch32223 static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT 224 { 225 storage_type result; 226 uint32_t tmp; 227 #define BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN(ld_mo, st_mo)\ 228 __asm__ __volatile__\ 229 (\ 230 "1:\n\t"\ 231 "ld" ld_mo "exb %[result], %[storage]\n\t"\ 232 "and %[result], %[result], %[value]\n\t"\ 233 "st" st_mo "exb %[tmp], %[result], %[storage]\n\t"\ 234 "teq %[tmp], #0\n\t"\ 235 "bne 1b\n\t"\ 236 : [result] "=&r" (result), [tmp] "=&r" (tmp), [storage] "+Q" (storage)\ 237 : [value] "Ir" (v)\ 238 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 239 ); 240 241 BOOST_ATOMIC_DETAIL_AARCH32_MO_SWITCH(order) 242 #undef BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN 243 244 return result; 245 } 246 bitwise_orboost::atomics::detail::extra_operations_gcc_aarch32247 static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT 248 { 249 storage_type result; 250 uint32_t tmp; 251 #define BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN(ld_mo, st_mo)\ 252 __asm__ __volatile__\ 253 (\ 254 "1:\n\t"\ 255 "ld" ld_mo "exb %[result], %[storage]\n\t"\ 256 "orr %[result], %[result], %[value]\n\t"\ 257 "st" st_mo "exb %[tmp], %[result], %[storage]\n\t"\ 258 "teq %[tmp], #0\n\t"\ 259 "bne 1b\n\t"\ 260 : [result] "=&r" (result), [tmp] "=&r" (tmp), [storage] "+Q" (storage)\ 261 : [value] "Ir" (v)\ 262 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 263 ); 264 265 BOOST_ATOMIC_DETAIL_AARCH32_MO_SWITCH(order) 266 #undef BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN 267 268 return result; 269 } 270 bitwise_xorboost::atomics::detail::extra_operations_gcc_aarch32271 static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT 272 { 273 storage_type result; 274 uint32_t tmp; 275 #define BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN(ld_mo, st_mo)\ 276 __asm__ __volatile__\ 277 (\ 278 "1:\n\t"\ 279 "ld" ld_mo "exb %[result], %[storage]\n\t"\ 280 "eor %[result], %[result], %[value]\n\t"\ 281 "st" st_mo "exb %[tmp], %[result], %[storage]\n\t"\ 282 "teq %[tmp], #0\n\t"\ 283 "bne 1b\n\t"\ 284 : [result] "=&r" (result), [tmp] "=&r" (tmp), [storage] "+Q" (storage)\ 285 : [value] "Ir" (v)\ 286 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 287 ); 288 289 BOOST_ATOMIC_DETAIL_AARCH32_MO_SWITCH(order) 290 #undef BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN 291 292 return result; 293 } 294 fetch_complementboost::atomics::detail::extra_operations_gcc_aarch32295 static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT 296 { 297 storage_type original, result; 298 uint32_t tmp; 299 #define BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN(ld_mo, st_mo)\ 300 __asm__ __volatile__\ 301 (\ 302 "1:\n\t"\ 303 "ld" ld_mo "exb %[original], %[storage]\n\t"\ 304 "mvn %[result], %[original]\n\t"\ 305 "st" st_mo "exb %[tmp], %[result], %[storage]\n\t"\ 306 "teq %[tmp], #0\n\t"\ 307 "bne 1b\n\t"\ 308 : [original] "=&r" (original), [result] "=&r" (result), [tmp] "=&r" (tmp), [storage] "+Q" (storage)\ 309 : \ 310 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 311 ); 312 313 BOOST_ATOMIC_DETAIL_AARCH32_MO_SWITCH(order) 314 #undef BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN 315 316 return original; 317 } 318 bitwise_complementboost::atomics::detail::extra_operations_gcc_aarch32319 static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT 320 { 321 storage_type result; 322 uint32_t tmp; 323 #define BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN(ld_mo, st_mo)\ 324 __asm__ __volatile__\ 325 (\ 326 "1:\n\t"\ 327 "ld" ld_mo "exb %[result], %[storage]\n\t"\ 328 "mvn %[result], %[result]\n\t"\ 329 "st" st_mo "exb %[tmp], %[result], %[storage]\n\t"\ 330 "teq %[tmp], #0\n\t"\ 331 "bne 1b\n\t"\ 332 : [result] "=&r" (result), [tmp] "=&r" (tmp), [storage] "+Q" (storage)\ 333 : \ 334 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 335 ); 336 337 BOOST_ATOMIC_DETAIL_AARCH32_MO_SWITCH(order) 338 #undef BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN 339 340 return result; 341 } 342 }; 343 344 template< typename Base, bool Signed > 345 struct extra_operations< Base, 1u, Signed, true > : 346 public extra_operations_gcc_aarch32_common< extra_operations_gcc_aarch32< Base, 1u, Signed > > 347 { 348 }; 349 350 351 template< typename Base, bool Signed > 352 struct extra_operations_gcc_aarch32< Base, 2u, Signed > : 353 public extra_operations_generic< Base, 2u, Signed > 354 { 355 typedef extra_operations_generic< Base, 2u, Signed > base_type; 356 typedef typename base_type::storage_type storage_type; 357 fetch_negateboost::atomics::detail::extra_operations_gcc_aarch32358 static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT 359 { 360 storage_type original, result; 361 uint32_t tmp; 362 #define BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN(ld_mo, st_mo)\ 363 __asm__ __volatile__\ 364 (\ 365 "1:\n\t"\ 366 "ld" ld_mo "exh %[original], %[storage]\n\t"\ 367 "rsb %[result], %[original], #0\n\t"\ 368 "st" st_mo "exh %[tmp], %[result], %[storage]\n\t"\ 369 "teq %[tmp], #0\n\t"\ 370 "bne 1b\n\t"\ 371 : [original] "=&r" (original), [result] "=&r" (result), [tmp] "=&r" (tmp), [storage] "+Q" (storage)\ 372 : \ 373 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 374 ); 375 376 BOOST_ATOMIC_DETAIL_AARCH32_MO_SWITCH(order) 377 #undef BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN 378 379 return original; 380 } 381 negateboost::atomics::detail::extra_operations_gcc_aarch32382 static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT 383 { 384 storage_type result; 385 uint32_t tmp; 386 #define BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN(ld_mo, st_mo)\ 387 __asm__ __volatile__\ 388 (\ 389 "1:\n\t"\ 390 "ld" ld_mo "exh %[result], %[storage]\n\t"\ 391 "rsb %[result], %[result], #0\n\t"\ 392 "st" st_mo "exh %[tmp], %[result], %[storage]\n\t"\ 393 "teq %[tmp], #0\n\t"\ 394 "bne 1b\n\t"\ 395 : [result] "=&r" (result), [tmp] "=&r" (tmp), [storage] "+Q" (storage)\ 396 : \ 397 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 398 ); 399 400 BOOST_ATOMIC_DETAIL_AARCH32_MO_SWITCH(order) 401 #undef BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN 402 403 return result; 404 } 405 addboost::atomics::detail::extra_operations_gcc_aarch32406 static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT 407 { 408 storage_type result; 409 uint32_t tmp; 410 #define BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN(ld_mo, st_mo)\ 411 __asm__ __volatile__\ 412 (\ 413 "1:\n\t"\ 414 "ld" ld_mo "exh %[result], %[storage]\n\t"\ 415 "add %[result], %[result], %[value]\n\t"\ 416 "st" st_mo "exh %[tmp], %[result], %[storage]\n\t"\ 417 "teq %[tmp], #0\n\t"\ 418 "bne 1b\n\t"\ 419 : [result] "=&r" (result), [tmp] "=&r" (tmp), [storage] "+Q" (storage)\ 420 : [value] "Ir" (v)\ 421 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 422 ); 423 424 BOOST_ATOMIC_DETAIL_AARCH32_MO_SWITCH(order) 425 #undef BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN 426 427 return result; 428 } 429 subboost::atomics::detail::extra_operations_gcc_aarch32430 static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT 431 { 432 storage_type result; 433 uint32_t tmp; 434 #define BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN(ld_mo, st_mo)\ 435 __asm__ __volatile__\ 436 (\ 437 "1:\n\t"\ 438 "ld" ld_mo "exh %[result], %[storage]\n\t"\ 439 "sub %[result], %[result], %[value]\n\t"\ 440 "st" st_mo "exh %[tmp], %[result], %[storage]\n\t"\ 441 "teq %[tmp], #0\n\t"\ 442 "bne 1b\n\t"\ 443 : [result] "=&r" (result), [tmp] "=&r" (tmp), [storage] "+Q" (storage)\ 444 : [value] "Ir" (v)\ 445 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 446 ); 447 448 BOOST_ATOMIC_DETAIL_AARCH32_MO_SWITCH(order) 449 #undef BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN 450 451 return result; 452 } 453 bitwise_andboost::atomics::detail::extra_operations_gcc_aarch32454 static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT 455 { 456 storage_type result; 457 uint32_t tmp; 458 #define BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN(ld_mo, st_mo)\ 459 __asm__ __volatile__\ 460 (\ 461 "1:\n\t"\ 462 "ld" ld_mo "exh %[result], %[storage]\n\t"\ 463 "and %[result], %[result], %[value]\n\t"\ 464 "st" st_mo "exh %[tmp], %[result], %[storage]\n\t"\ 465 "teq %[tmp], #0\n\t"\ 466 "bne 1b\n\t"\ 467 : [result] "=&r" (result), [tmp] "=&r" (tmp), [storage] "+Q" (storage)\ 468 : [value] "Ir" (v)\ 469 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 470 ); 471 472 BOOST_ATOMIC_DETAIL_AARCH32_MO_SWITCH(order) 473 #undef BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN 474 475 return result; 476 } 477 bitwise_orboost::atomics::detail::extra_operations_gcc_aarch32478 static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT 479 { 480 storage_type result; 481 uint32_t tmp; 482 #define BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN(ld_mo, st_mo)\ 483 __asm__ __volatile__\ 484 (\ 485 "1:\n\t"\ 486 "ld" ld_mo "exh %[result], %[storage]\n\t"\ 487 "orr %[result], %[result], %[value]\n\t"\ 488 "st" st_mo "exh %[tmp], %[result], %[storage]\n\t"\ 489 "teq %[tmp], #0\n\t"\ 490 "bne 1b\n\t"\ 491 : [result] "=&r" (result), [tmp] "=&r" (tmp), [storage] "+Q" (storage)\ 492 : [value] "Ir" (v)\ 493 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 494 ); 495 496 BOOST_ATOMIC_DETAIL_AARCH32_MO_SWITCH(order) 497 #undef BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN 498 499 return result; 500 } 501 bitwise_xorboost::atomics::detail::extra_operations_gcc_aarch32502 static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT 503 { 504 storage_type result; 505 uint32_t tmp; 506 #define BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN(ld_mo, st_mo)\ 507 __asm__ __volatile__\ 508 (\ 509 "1:\n\t"\ 510 "ld" ld_mo "exh %[result], %[storage]\n\t"\ 511 "eor %[result], %[result], %[value]\n\t"\ 512 "st" st_mo "exh %[tmp], %[result], %[storage]\n\t"\ 513 "teq %[tmp], #0\n\t"\ 514 "bne 1b\n\t"\ 515 : [result] "=&r" (result), [tmp] "=&r" (tmp), [storage] "+Q" (storage)\ 516 : [value] "Ir" (v)\ 517 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 518 ); 519 520 BOOST_ATOMIC_DETAIL_AARCH32_MO_SWITCH(order) 521 #undef BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN 522 523 return result; 524 } 525 fetch_complementboost::atomics::detail::extra_operations_gcc_aarch32526 static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT 527 { 528 storage_type original, result; 529 uint32_t tmp; 530 #define BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN(ld_mo, st_mo)\ 531 __asm__ __volatile__\ 532 (\ 533 "1:\n\t"\ 534 "ld" ld_mo "exh %[original], %[storage]\n\t"\ 535 "mvn %[result], %[original]\n\t"\ 536 "st" st_mo "exh %[tmp], %[result], %[storage]\n\t"\ 537 "teq %[tmp], #0\n\t"\ 538 "bne 1b\n\t"\ 539 : [original] "=&r" (original), [result] "=&r" (result), [tmp] "=&r" (tmp), [storage] "+Q" (storage)\ 540 : \ 541 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 542 ); 543 544 BOOST_ATOMIC_DETAIL_AARCH32_MO_SWITCH(order) 545 #undef BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN 546 547 return original; 548 } 549 bitwise_complementboost::atomics::detail::extra_operations_gcc_aarch32550 static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT 551 { 552 storage_type result; 553 uint32_t tmp; 554 #define BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN(ld_mo, st_mo)\ 555 __asm__ __volatile__\ 556 (\ 557 "1:\n\t"\ 558 "ld" ld_mo "exh %[result], %[storage]\n\t"\ 559 "mvn %[result], %[result]\n\t"\ 560 "st" st_mo "exh %[tmp], %[result], %[storage]\n\t"\ 561 "teq %[tmp], #0\n\t"\ 562 "bne 1b\n\t"\ 563 : [result] "=&r" (result), [tmp] "=&r" (tmp), [storage] "+Q" (storage)\ 564 : \ 565 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 566 ); 567 568 BOOST_ATOMIC_DETAIL_AARCH32_MO_SWITCH(order) 569 #undef BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN 570 571 return result; 572 } 573 }; 574 575 template< typename Base, bool Signed > 576 struct extra_operations< Base, 2u, Signed, true > : 577 public extra_operations_gcc_aarch32_common< extra_operations_gcc_aarch32< Base, 2u, Signed > > 578 { 579 }; 580 581 template< typename Base, bool Signed > 582 struct extra_operations_gcc_aarch32< Base, 4u, Signed > : 583 public extra_operations_generic< Base, 4u, Signed > 584 { 585 typedef extra_operations_generic< Base, 4u, Signed > base_type; 586 typedef typename base_type::storage_type storage_type; 587 fetch_negateboost::atomics::detail::extra_operations_gcc_aarch32588 static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT 589 { 590 storage_type original, result; 591 uint32_t tmp; 592 #define BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN(ld_mo, st_mo)\ 593 __asm__ __volatile__\ 594 (\ 595 "1:\n\t"\ 596 "ld" ld_mo "ex %[original], %[storage]\n\t"\ 597 "rsb %[result], %[original], #0\n\t"\ 598 "st" st_mo "ex %[tmp], %[result], %[storage]\n\t"\ 599 "teq %[tmp], #0\n\t"\ 600 "bne 1b\n\t"\ 601 : [original] "=&r" (original), [result] "=&r" (result), [tmp] "=&r" (tmp), [storage] "+Q" (storage)\ 602 : \ 603 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 604 ); 605 606 BOOST_ATOMIC_DETAIL_AARCH32_MO_SWITCH(order) 607 #undef BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN 608 609 return original; 610 } 611 negateboost::atomics::detail::extra_operations_gcc_aarch32612 static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT 613 { 614 storage_type result; 615 uint32_t tmp; 616 #define BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN(ld_mo, st_mo)\ 617 __asm__ __volatile__\ 618 (\ 619 "1:\n\t"\ 620 "ld" ld_mo "ex %[result], %[storage]\n\t"\ 621 "rsb %[result], %[result], #0\n\t"\ 622 "st" st_mo "ex %[tmp], %[result], %[storage]\n\t"\ 623 "teq %[tmp], #0\n\t"\ 624 "bne 1b\n\t"\ 625 : [result] "=&r" (result), [tmp] "=&r" (tmp), [storage] "+Q" (storage)\ 626 : \ 627 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 628 ); 629 630 BOOST_ATOMIC_DETAIL_AARCH32_MO_SWITCH(order) 631 #undef BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN 632 633 return result; 634 } 635 addboost::atomics::detail::extra_operations_gcc_aarch32636 static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT 637 { 638 storage_type result; 639 uint32_t tmp; 640 #define BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN(ld_mo, st_mo)\ 641 __asm__ __volatile__\ 642 (\ 643 "1:\n\t"\ 644 "ld" ld_mo "ex %[result], %[storage]\n\t"\ 645 "add %[result], %[result], %[value]\n\t"\ 646 "st" st_mo "ex %[tmp], %[result], %[storage]\n\t"\ 647 "teq %[tmp], #0\n\t"\ 648 "bne 1b\n\t"\ 649 : [result] "=&r" (result), [tmp] "=&r" (tmp), [storage] "+Q" (storage)\ 650 : [value] "Ir" (v)\ 651 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 652 ); 653 654 BOOST_ATOMIC_DETAIL_AARCH32_MO_SWITCH(order) 655 #undef BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN 656 657 return result; 658 } 659 subboost::atomics::detail::extra_operations_gcc_aarch32660 static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT 661 { 662 storage_type result; 663 uint32_t tmp; 664 #define BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN(ld_mo, st_mo)\ 665 __asm__ __volatile__\ 666 (\ 667 "1:\n\t"\ 668 "ld" ld_mo "ex %[result], %[storage]\n\t"\ 669 "sub %[result], %[result], %[value]\n\t"\ 670 "st" st_mo "ex %[tmp], %[result], %[storage]\n\t"\ 671 "teq %[tmp], #0\n\t"\ 672 "bne 1b\n\t"\ 673 : [result] "=&r" (result), [tmp] "=&r" (tmp), [storage] "+Q" (storage)\ 674 : [value] "Ir" (v)\ 675 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 676 ); 677 678 BOOST_ATOMIC_DETAIL_AARCH32_MO_SWITCH(order) 679 #undef BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN 680 681 return result; 682 } 683 bitwise_andboost::atomics::detail::extra_operations_gcc_aarch32684 static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT 685 { 686 storage_type result; 687 uint32_t tmp; 688 #define BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN(ld_mo, st_mo)\ 689 __asm__ __volatile__\ 690 (\ 691 "1:\n\t"\ 692 "ld" ld_mo "ex %[result], %[storage]\n\t"\ 693 "and %[result], %[result], %[value]\n\t"\ 694 "st" st_mo "ex %[tmp], %[result], %[storage]\n\t"\ 695 "teq %[tmp], #0\n\t"\ 696 "bne 1b\n\t"\ 697 : [result] "=&r" (result), [tmp] "=&r" (tmp), [storage] "+Q" (storage)\ 698 : [value] "Ir" (v)\ 699 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 700 ); 701 702 BOOST_ATOMIC_DETAIL_AARCH32_MO_SWITCH(order) 703 #undef BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN 704 705 return result; 706 } 707 bitwise_orboost::atomics::detail::extra_operations_gcc_aarch32708 static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT 709 { 710 storage_type result; 711 uint32_t tmp; 712 #define BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN(ld_mo, st_mo)\ 713 __asm__ __volatile__\ 714 (\ 715 "1:\n\t"\ 716 "ld" ld_mo "ex %[result], %[storage]\n\t"\ 717 "orr %[result], %[result], %[value]\n\t"\ 718 "st" st_mo "ex %[tmp], %[result], %[storage]\n\t"\ 719 "teq %[tmp], #0\n\t"\ 720 "bne 1b\n\t"\ 721 : [result] "=&r" (result), [tmp] "=&r" (tmp), [storage] "+Q" (storage)\ 722 : [value] "Ir" (v)\ 723 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 724 ); 725 726 BOOST_ATOMIC_DETAIL_AARCH32_MO_SWITCH(order) 727 #undef BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN 728 729 return result; 730 } 731 bitwise_xorboost::atomics::detail::extra_operations_gcc_aarch32732 static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT 733 { 734 storage_type result; 735 uint32_t tmp; 736 #define BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN(ld_mo, st_mo)\ 737 __asm__ __volatile__\ 738 (\ 739 "1:\n\t"\ 740 "ld" ld_mo "ex %[result], %[storage]\n\t"\ 741 "eor %[result], %[result], %[value]\n\t"\ 742 "st" st_mo "ex %[tmp], %[result], %[storage]\n\t"\ 743 "teq %[tmp], #0\n\t"\ 744 "bne 1b\n\t"\ 745 : [result] "=&r" (result), [tmp] "=&r" (tmp), [storage] "+Q" (storage)\ 746 : [value] "Ir" (v)\ 747 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 748 ); 749 750 BOOST_ATOMIC_DETAIL_AARCH32_MO_SWITCH(order) 751 #undef BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN 752 753 return result; 754 } 755 fetch_complementboost::atomics::detail::extra_operations_gcc_aarch32756 static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT 757 { 758 storage_type original, result; 759 uint32_t tmp; 760 #define BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN(ld_mo, st_mo)\ 761 __asm__ __volatile__\ 762 (\ 763 "1:\n\t"\ 764 "ld" ld_mo "ex %[original], %[storage]\n\t"\ 765 "mvn %[result], %[original]\n\t"\ 766 "st" st_mo "ex %[tmp], %[result], %[storage]\n\t"\ 767 "teq %[tmp], #0\n\t"\ 768 "bne 1b\n\t"\ 769 : [original] "=&r" (original), [result] "=&r" (result), [tmp] "=&r" (tmp), [storage] "+Q" (storage)\ 770 : \ 771 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 772 ); 773 774 BOOST_ATOMIC_DETAIL_AARCH32_MO_SWITCH(order) 775 #undef BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN 776 777 return original; 778 } 779 bitwise_complementboost::atomics::detail::extra_operations_gcc_aarch32780 static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT 781 { 782 storage_type result; 783 uint32_t tmp; 784 #define BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN(ld_mo, st_mo)\ 785 __asm__ __volatile__\ 786 (\ 787 "1:\n\t"\ 788 "ld" ld_mo "ex %[result], %[storage]\n\t"\ 789 "mvn %[result], %[result]\n\t"\ 790 "st" st_mo "ex %[tmp], %[result], %[storage]\n\t"\ 791 "teq %[tmp], #0\n\t"\ 792 "bne 1b\n\t"\ 793 : [result] "=&r" (result), [tmp] "=&r" (tmp), [storage] "+Q" (storage)\ 794 : \ 795 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 796 ); 797 798 BOOST_ATOMIC_DETAIL_AARCH32_MO_SWITCH(order) 799 #undef BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN 800 801 return result; 802 } 803 }; 804 805 template< typename Base, bool Signed > 806 struct extra_operations< Base, 4u, Signed, true > : 807 public extra_operations_gcc_aarch32_common< extra_operations_gcc_aarch32< Base, 4u, Signed > > 808 { 809 }; 810 811 template< typename Base, bool Signed > 812 struct extra_operations_gcc_aarch32< Base, 8u, Signed > : 813 public extra_operations_generic< Base, 8u, Signed > 814 { 815 typedef extra_operations_generic< Base, 8u, Signed > base_type; 816 typedef typename base_type::storage_type storage_type; 817 fetch_negateboost::atomics::detail::extra_operations_gcc_aarch32818 static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT 819 { 820 storage_type original, result; 821 uint32_t tmp; 822 #define BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN(ld_mo, st_mo)\ 823 __asm__ __volatile__\ 824 (\ 825 "1:\n\t"\ 826 "ld" ld_mo "exd %0, %H0, %2\n\t"\ 827 "mvn %3, %0\n\t"\ 828 "mvn %H3, %H0\n\t"\ 829 "adds " BOOST_ATOMIC_DETAIL_AARCH32_ASM_ARG_LO(3) ", " BOOST_ATOMIC_DETAIL_AARCH32_ASM_ARG_LO(3) ", #1\n\t"\ 830 "adc " BOOST_ATOMIC_DETAIL_AARCH32_ASM_ARG_HI(3) ", " BOOST_ATOMIC_DETAIL_AARCH32_ASM_ARG_HI(3) ", #0\n\t"\ 831 "st" st_mo "exd %1, %3, %H3, %2\n\t"\ 832 "teq %1, #0\n\t"\ 833 "bne 1b\n\t"\ 834 : "=&r" (original), "=&r" (tmp), "+Q" (storage), "=&r" (result)\ 835 : \ 836 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 837 ); 838 839 BOOST_ATOMIC_DETAIL_AARCH32_MO_SWITCH(order) 840 #undef BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN 841 842 return original; 843 } 844 negateboost::atomics::detail::extra_operations_gcc_aarch32845 static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT 846 { 847 storage_type result; 848 uint32_t tmp; 849 #define BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN(ld_mo, st_mo)\ 850 __asm__ __volatile__\ 851 (\ 852 "1:\n\t"\ 853 "ld" ld_mo "exd %0, %H0, %2\n\t"\ 854 "mvn %0, %0\n\t"\ 855 "mvn %H0, %H0\n\t"\ 856 "adds " BOOST_ATOMIC_DETAIL_AARCH32_ASM_ARG_LO(0) ", " BOOST_ATOMIC_DETAIL_AARCH32_ASM_ARG_LO(0) ", #1\n\t"\ 857 "adc " BOOST_ATOMIC_DETAIL_AARCH32_ASM_ARG_HI(0) ", " BOOST_ATOMIC_DETAIL_AARCH32_ASM_ARG_HI(0) ", #0\n\t"\ 858 "st" st_mo "exd %1, %0, %H0, %2\n\t"\ 859 "teq %1, #0\n\t"\ 860 "bne 1b\n\t"\ 861 : "=&r" (result), "=&r" (tmp), "+Q" (storage)\ 862 : \ 863 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 864 ); 865 866 BOOST_ATOMIC_DETAIL_AARCH32_MO_SWITCH(order) 867 #undef BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN 868 869 return result; 870 } 871 addboost::atomics::detail::extra_operations_gcc_aarch32872 static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT 873 { 874 storage_type result; 875 uint32_t tmp; 876 #define BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN(ld_mo, st_mo)\ 877 __asm__ __volatile__\ 878 (\ 879 "1:\n\t"\ 880 "ld" ld_mo "exd %0, %H0, %2\n\t"\ 881 "adds " BOOST_ATOMIC_DETAIL_AARCH32_ASM_ARG_LO(0) ", " BOOST_ATOMIC_DETAIL_AARCH32_ASM_ARG_LO(0) ", " BOOST_ATOMIC_DETAIL_AARCH32_ASM_ARG_LO(3) "\n\t"\ 882 "adc " BOOST_ATOMIC_DETAIL_AARCH32_ASM_ARG_HI(0) ", " BOOST_ATOMIC_DETAIL_AARCH32_ASM_ARG_HI(0) ", " BOOST_ATOMIC_DETAIL_AARCH32_ASM_ARG_HI(3) "\n\t"\ 883 "st" st_mo "exd %1, %0, %H0, %2\n\t"\ 884 "teq %1, #0\n\t"\ 885 "bne 1b\n\t"\ 886 : "=&r" (result), "=&r" (tmp), "+Q" (storage)\ 887 : "r" (v)\ 888 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 889 ); 890 891 BOOST_ATOMIC_DETAIL_AARCH32_MO_SWITCH(order) 892 #undef BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN 893 894 return result; 895 } 896 subboost::atomics::detail::extra_operations_gcc_aarch32897 static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT 898 { 899 storage_type result; 900 uint32_t tmp; 901 #define BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN(ld_mo, st_mo)\ 902 __asm__ __volatile__\ 903 (\ 904 "1:\n\t"\ 905 "ld" ld_mo "exd %0, %H0, %2\n\t"\ 906 "subs " BOOST_ATOMIC_DETAIL_AARCH32_ASM_ARG_LO(0) ", " BOOST_ATOMIC_DETAIL_AARCH32_ASM_ARG_LO(0) ", " BOOST_ATOMIC_DETAIL_AARCH32_ASM_ARG_LO(3) "\n\t"\ 907 "sbc " BOOST_ATOMIC_DETAIL_AARCH32_ASM_ARG_HI(0) ", " BOOST_ATOMIC_DETAIL_AARCH32_ASM_ARG_HI(0) ", " BOOST_ATOMIC_DETAIL_AARCH32_ASM_ARG_HI(3) "\n\t"\ 908 "st" st_mo "exd %1, %0, %H0, %2\n\t"\ 909 "teq %1, #0\n\t"\ 910 "bne 1b\n\t"\ 911 : "=&r" (result), "=&r" (tmp), "+Q" (storage)\ 912 : "r" (v)\ 913 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 914 ); 915 916 BOOST_ATOMIC_DETAIL_AARCH32_MO_SWITCH(order) 917 #undef BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN 918 919 return result; 920 } 921 bitwise_andboost::atomics::detail::extra_operations_gcc_aarch32922 static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT 923 { 924 storage_type result; 925 uint32_t tmp; 926 #define BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN(ld_mo, st_mo)\ 927 __asm__ __volatile__\ 928 (\ 929 "1:\n\t"\ 930 "ld" ld_mo "exd %0, %H0, %2\n\t"\ 931 "and %0, %0, %3\n\t"\ 932 "and %H0, %H0, %H3\n\t"\ 933 "st" st_mo "exd %1, %0, %H0, %2\n\t"\ 934 "teq %1, #0\n\t"\ 935 "bne 1b\n\t"\ 936 : "=&r" (result), "=&r" (tmp), "+Q" (storage)\ 937 : "r" (v)\ 938 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 939 ); 940 941 BOOST_ATOMIC_DETAIL_AARCH32_MO_SWITCH(order) 942 #undef BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN 943 944 return result; 945 } 946 bitwise_orboost::atomics::detail::extra_operations_gcc_aarch32947 static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT 948 { 949 storage_type result; 950 uint32_t tmp; 951 #define BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN(ld_mo, st_mo)\ 952 __asm__ __volatile__\ 953 (\ 954 "1:\n\t"\ 955 "ld" ld_mo "exd %0, %H0, %2\n\t"\ 956 "orr %0, %0, %3\n\t"\ 957 "orr %H0, %H0, %H3\n\t"\ 958 "st" st_mo "exd %1, %0, %H0, %2\n\t"\ 959 "teq %1, #0\n\t"\ 960 "bne 1b\n\t"\ 961 : "=&r" (result), "=&r" (tmp), "+Q" (storage)\ 962 : "r" (v)\ 963 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 964 ); 965 966 BOOST_ATOMIC_DETAIL_AARCH32_MO_SWITCH(order) 967 #undef BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN 968 969 return result; 970 } 971 bitwise_xorboost::atomics::detail::extra_operations_gcc_aarch32972 static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT 973 { 974 storage_type result; 975 uint32_t tmp; 976 #define BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN(ld_mo, st_mo)\ 977 __asm__ __volatile__\ 978 (\ 979 "1:\n\t"\ 980 "ld" ld_mo "exd %0, %H0, %2\n\t"\ 981 "eor %0, %0, %3\n\t"\ 982 "eor %H0, %H0, %H3\n\t"\ 983 "st" st_mo "exd %1, %0, %H0, %2\n\t"\ 984 "teq %1, #0\n\t"\ 985 "bne 1b\n\t"\ 986 : "=&r" (result), "=&r" (tmp), "+Q" (storage)\ 987 : "r" (v)\ 988 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 989 ); 990 991 BOOST_ATOMIC_DETAIL_AARCH32_MO_SWITCH(order) 992 #undef BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN 993 994 return result; 995 } 996 fetch_complementboost::atomics::detail::extra_operations_gcc_aarch32997 static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT 998 { 999 storage_type original, result; 1000 uint32_t tmp; 1001 #define BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN(ld_mo, st_mo)\ 1002 __asm__ __volatile__\ 1003 (\ 1004 "1:\n\t"\ 1005 "ld" ld_mo "exd %0, %H0, %2\n\t"\ 1006 "mvn %3, %0\n\t"\ 1007 "mvn %H3, %H0\n\t"\ 1008 "st" st_mo "exd %1, %3, %H3, %2\n\t"\ 1009 "teq %1, #0\n\t"\ 1010 "bne 1b\n\t"\ 1011 : "=&r" (original), "=&r" (tmp), "+Q" (storage), "=&r" (result)\ 1012 : \ 1013 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 1014 ); 1015 1016 BOOST_ATOMIC_DETAIL_AARCH32_MO_SWITCH(order) 1017 #undef BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN 1018 1019 return original; 1020 } 1021 bitwise_complementboost::atomics::detail::extra_operations_gcc_aarch321022 static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT 1023 { 1024 storage_type result; 1025 uint32_t tmp; 1026 #define BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN(ld_mo, st_mo)\ 1027 __asm__ __volatile__\ 1028 (\ 1029 "1:\n\t"\ 1030 "ld" ld_mo "exd %0, %H0, %2\n\t"\ 1031 "mvn %0, %0\n\t"\ 1032 "mvn %H0, %H0\n\t"\ 1033 "st" st_mo "exd %1, %0, %H0, %2\n\t"\ 1034 "teq %1, #0\n\t"\ 1035 "bne 1b\n\t"\ 1036 : "=&r" (result), "=&r" (tmp), "+Q" (storage)\ 1037 : \ 1038 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 1039 ); 1040 1041 BOOST_ATOMIC_DETAIL_AARCH32_MO_SWITCH(order) 1042 #undef BOOST_ATOMIC_DETAIL_AARCH32_MO_INSN 1043 1044 return result; 1045 } 1046 }; 1047 1048 template< typename Base, bool Signed > 1049 struct extra_operations< Base, 8u, Signed, true > : 1050 public extra_operations_gcc_aarch32_common< extra_operations_gcc_aarch32< Base, 8u, Signed > > 1051 { 1052 }; 1053 1054 } // namespace detail 1055 } // namespace atomics 1056 } // namespace boost 1057 1058 #include <boost/atomic/detail/footer.hpp> 1059 1060 #endif // BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_AARCH32_HPP_INCLUDED_ 1061