• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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