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) 2015 Andrey Semashev
7  */
8 /*!
9  * \file   atomic/detail/extra_ops_gcc_x86.hpp
10  *
11  * This header contains implementation of the extra atomic operations for x86.
12  */
13 
14 #ifndef BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_X86_HPP_INCLUDED_
15 #define BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_X86_HPP_INCLUDED_
16 
17 #include <cstddef>
18 #include <boost/memory_order.hpp>
19 #include <boost/atomic/detail/config.hpp>
20 #include <boost/atomic/detail/storage_type.hpp>
21 #include <boost/atomic/detail/extra_operations_fwd.hpp>
22 #include <boost/atomic/capabilities.hpp>
23 
24 #ifdef BOOST_HAS_PRAGMA_ONCE
25 #pragma once
26 #endif
27 
28 namespace boost {
29 namespace atomics {
30 namespace detail {
31 
32 template< typename Base >
33 struct gcc_x86_extra_operations_common :
34     public Base
35 {
36     typedef Base base_type;
37     typedef typename base_type::storage_type storage_type;
38 
bit_test_and_setboost::atomics::detail::gcc_x86_extra_operations_common39     static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order) BOOST_NOEXCEPT
40     {
41         bool res;
42 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
43         __asm__ __volatile__
44         (
45             "lock; bts %[bit_number], %[storage]\n\t"
46             : [storage] "+m" (storage), [result] "=@ccc" (res)
47             : [bit_number] "Kq" (bit_number)
48             : "memory"
49         );
50 #else
51         __asm__ __volatile__
52         (
53             "lock; bts %[bit_number], %[storage]\n\t"
54             "setc %[result]\n\t"
55             : [storage] "+m" (storage), [result] "=q" (res)
56             : [bit_number] "Kq" (bit_number)
57             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
58         );
59 #endif
60         return res;
61     }
62 
bit_test_and_resetboost::atomics::detail::gcc_x86_extra_operations_common63     static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order) BOOST_NOEXCEPT
64     {
65         bool res;
66 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
67         __asm__ __volatile__
68         (
69             "lock; btr %[bit_number], %[storage]\n\t"
70             : [storage] "+m" (storage), [result] "=@ccc" (res)
71             : [bit_number] "Kq" (bit_number)
72             : "memory"
73         );
74 #else
75         __asm__ __volatile__
76         (
77             "lock; btr %[bit_number], %[storage]\n\t"
78             "setc %[result]\n\t"
79             : [storage] "+m" (storage), [result] "=q" (res)
80             : [bit_number] "Kq" (bit_number)
81             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
82         );
83 #endif
84         return res;
85     }
86 
bit_test_and_complementboost::atomics::detail::gcc_x86_extra_operations_common87     static BOOST_FORCEINLINE bool bit_test_and_complement(storage_type volatile& storage, unsigned int bit_number, memory_order) BOOST_NOEXCEPT
88     {
89         bool res;
90 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
91         __asm__ __volatile__
92         (
93             "lock; btc %[bit_number], %[storage]\n\t"
94             : [storage] "+m" (storage), [result] "=@ccc" (res)
95             : [bit_number] "Kq" (bit_number)
96             : "memory"
97         );
98 #else
99         __asm__ __volatile__
100         (
101             "lock; btc %[bit_number], %[storage]\n\t"
102             "setc %[result]\n\t"
103             : [storage] "+m" (storage), [result] "=q" (res)
104             : [bit_number] "Kq" (bit_number)
105             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
106         );
107 #endif
108         return res;
109     }
110 };
111 
112 template< typename Base, bool Signed >
113 struct extra_operations< Base, 1u, Signed > :
114     public gcc_x86_extra_operations_common< Base >
115 {
116     typedef gcc_x86_extra_operations_common< Base > base_type;
117     typedef typename base_type::storage_type storage_type;
118     typedef typename make_storage_type< 4u, Signed >::type temp_storage_type;
119 
120 #define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, result)\
121     temp_storage_type new_val;\
122     __asm__ __volatile__\
123     (\
124         ".align 16\n\t"\
125         "1: movzbl %[res], %2\n\t"\
126         op " %b2\n\t"\
127         "lock; cmpxchgb %b2, %[storage]\n\t"\
128         "jne 1b"\
129         : [res] "+a" (result), [storage] "+m" (storage), "=&q" (new_val)\
130         : \
131         : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\
132     )
133 
fetch_negateboost::atomics::detail::extra_operations134     static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
135     {
136         storage_type res = storage;
137         BOOST_ATOMIC_DETAIL_CAS_LOOP("negb", res);
138         return res;
139     }
140 
fetch_complementboost::atomics::detail::extra_operations141     static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
142     {
143         storage_type res = storage;
144         BOOST_ATOMIC_DETAIL_CAS_LOOP("notb", res);
145         return res;
146     }
147 
148 #undef BOOST_ATOMIC_DETAIL_CAS_LOOP
149 
opaque_addboost::atomics::detail::extra_operations150     static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
151     {
152         if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
153         {
154             __asm__ __volatile__
155             (
156                 "lock; incb %[storage]\n\t"
157                 : [storage] "+m" (storage)
158                 :
159                 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
160             );
161         }
162         else
163         {
164             __asm__ __volatile__
165             (
166                 "lock; addb %[argument], %[storage]\n\t"
167                 : [storage] "+m" (storage)
168                 : [argument] "iq" (v)
169                 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
170             );
171         }
172     }
173 
opaque_subboost::atomics::detail::extra_operations174     static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
175     {
176         if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
177         {
178             __asm__ __volatile__
179             (
180                 "lock; decb %[storage]\n\t"
181                 : [storage] "+m" (storage)
182                 :
183                 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
184             );
185         }
186         else
187         {
188             __asm__ __volatile__
189             (
190                 "lock; subb %[argument], %[storage]\n\t"
191                 : [storage] "+m" (storage)
192                 : [argument] "iq" (v)
193                 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
194             );
195         }
196     }
197 
opaque_negateboost::atomics::detail::extra_operations198     static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
199     {
200         __asm__ __volatile__
201         (
202             "lock; negb %[storage]\n\t"
203             : [storage] "+m" (storage)
204             :
205             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
206         );
207     }
208 
opaque_andboost::atomics::detail::extra_operations209     static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
210     {
211         __asm__ __volatile__
212         (
213             "lock; andb %[argument], %[storage]\n\t"
214             : [storage] "+m" (storage)
215             : [argument] "iq" (v)
216             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
217         );
218     }
219 
opaque_orboost::atomics::detail::extra_operations220     static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
221     {
222         __asm__ __volatile__
223         (
224             "lock; orb %[argument], %[storage]\n\t"
225             : [storage] "+m" (storage)
226             : [argument] "iq" (v)
227             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
228         );
229     }
230 
opaque_xorboost::atomics::detail::extra_operations231     static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
232     {
233         __asm__ __volatile__
234         (
235             "lock; xorb %[argument], %[storage]\n\t"
236             : [storage] "+m" (storage)
237             : [argument] "iq" (v)
238             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
239         );
240     }
241 
opaque_complementboost::atomics::detail::extra_operations242     static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
243     {
244         __asm__ __volatile__
245         (
246             "lock; notb %[storage]\n\t"
247             : [storage] "+m" (storage)
248             :
249             : "memory"
250         );
251     }
252 
add_and_testboost::atomics::detail::extra_operations253     static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
254     {
255         bool res;
256 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
257         if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
258         {
259             __asm__ __volatile__
260             (
261                 "lock; incb %[storage]\n\t"
262                 : [storage] "+m" (storage), [result] "=@ccz" (res)
263                 :
264                 : "memory"
265             );
266         }
267         else
268         {
269             __asm__ __volatile__
270             (
271                 "lock; addb %[argument], %[storage]\n\t"
272                 : [storage] "+m" (storage), [result] "=@ccz" (res)
273                 : [argument] "iq" (v)
274                 : "memory"
275             );
276         }
277 #else
278         if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
279         {
280             __asm__ __volatile__
281             (
282                 "lock; incb %[storage]\n\t"
283                 "setz %[result]\n\t"
284                 : [storage] "+m" (storage), [result] "=q" (res)
285                 :
286                 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
287             );
288         }
289         else
290         {
291             __asm__ __volatile__
292             (
293                 "lock; addb %[argument], %[storage]\n\t"
294                 "setz %[result]\n\t"
295                 : [storage] "+m" (storage), [result] "=q" (res)
296                 : [argument] "iq" (v)
297                 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
298             );
299         }
300 #endif
301         return res;
302     }
303 
sub_and_testboost::atomics::detail::extra_operations304     static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
305     {
306         bool res;
307 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
308         if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
309         {
310             __asm__ __volatile__
311             (
312                 "lock; decb %[storage]\n\t"
313                 : [storage] "+m" (storage), [result] "=@ccz" (res)
314                 :
315                 : "memory"
316             );
317         }
318         else
319         {
320             __asm__ __volatile__
321             (
322                 "lock; subb %[argument], %[storage]\n\t"
323                 : [storage] "+m" (storage), [result] "=@ccz" (res)
324                 : [argument] "iq" (v)
325                 : "memory"
326             );
327         }
328 #else
329         if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
330         {
331             __asm__ __volatile__
332             (
333                 "lock; decb %[storage]\n\t"
334                 "setz %[result]\n\t"
335                 : [storage] "+m" (storage), [result] "=q" (res)
336                 :
337                 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
338             );
339         }
340         else
341         {
342             __asm__ __volatile__
343             (
344                 "lock; subb %[argument], %[storage]\n\t"
345                 "setz %[result]\n\t"
346                 : [storage] "+m" (storage), [result] "=q" (res)
347                 : [argument] "iq" (v)
348                 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
349             );
350         }
351 #endif
352         return res;
353     }
354 
and_and_testboost::atomics::detail::extra_operations355     static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
356     {
357         bool res;
358 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
359         __asm__ __volatile__
360         (
361             "lock; andb %[argument], %[storage]\n\t"
362             : [storage] "+m" (storage), [result] "=@ccz" (res)
363             : [argument] "iq" (v)
364             : "memory"
365         );
366 #else
367         __asm__ __volatile__
368         (
369             "lock; andb %[argument], %[storage]\n\t"
370             "setz %[result]\n\t"
371             : [storage] "+m" (storage), [result] "=q" (res)
372             : [argument] "iq" (v)
373             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
374         );
375 #endif
376         return res;
377     }
378 
or_and_testboost::atomics::detail::extra_operations379     static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
380     {
381         bool res;
382 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
383         __asm__ __volatile__
384         (
385             "lock; orb %[argument], %[storage]\n\t"
386             : [storage] "+m" (storage), [result] "=@ccz" (res)
387             : [argument] "iq" (v)
388             : "memory"
389         );
390 #else
391         __asm__ __volatile__
392         (
393             "lock; orb %[argument], %[storage]\n\t"
394             "setz %[result]\n\t"
395             : [storage] "+m" (storage), [result] "=q" (res)
396             : [argument] "iq" (v)
397             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
398         );
399 #endif
400         return res;
401     }
402 
xor_and_testboost::atomics::detail::extra_operations403     static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
404     {
405         bool res;
406 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
407         __asm__ __volatile__
408         (
409             "lock; xorb %[argument], %[storage]\n\t"
410             : [storage] "+m" (storage), [result] "=@ccz" (res)
411             : [argument] "iq" (v)
412             : "memory"
413         );
414 #else
415         __asm__ __volatile__
416         (
417             "lock; xorb %[argument], %[storage]\n\t"
418             "setz %[result]\n\t"
419             : [storage] "+m" (storage), [result] "=q" (res)
420             : [argument] "iq" (v)
421             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
422         );
423 #endif
424         return res;
425     }
426 };
427 
428 template< typename Base, bool Signed >
429 struct extra_operations< Base, 2u, Signed > :
430     public gcc_x86_extra_operations_common< Base >
431 {
432     typedef gcc_x86_extra_operations_common< Base > base_type;
433     typedef typename base_type::storage_type storage_type;
434     typedef typename make_storage_type< 4u, Signed >::type temp_storage_type;
435 
436 #define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, result)\
437     temp_storage_type new_val;\
438     __asm__ __volatile__\
439     (\
440         ".align 16\n\t"\
441         "1: movzwl %[res], %2\n\t"\
442         op " %w2\n\t"\
443         "lock; cmpxchgw %w2, %[storage]\n\t"\
444         "jne 1b"\
445         : [res] "+a" (result), [storage] "+m" (storage), "=&q" (new_val)\
446         : \
447         : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\
448     )
449 
fetch_negateboost::atomics::detail::extra_operations450     static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
451     {
452         storage_type res = storage;
453         BOOST_ATOMIC_DETAIL_CAS_LOOP("negw", res);
454         return res;
455     }
456 
fetch_complementboost::atomics::detail::extra_operations457     static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
458     {
459         storage_type res = storage;
460         BOOST_ATOMIC_DETAIL_CAS_LOOP("notw", res);
461         return res;
462     }
463 
464 #undef BOOST_ATOMIC_DETAIL_CAS_LOOP
465 
opaque_addboost::atomics::detail::extra_operations466     static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
467     {
468         if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
469         {
470             __asm__ __volatile__
471             (
472                 "lock; incw %[storage]\n\t"
473                 : [storage] "+m" (storage)
474                 :
475                 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
476             );
477         }
478         else
479         {
480             __asm__ __volatile__
481             (
482                 "lock; addw %[argument], %[storage]\n\t"
483                 : [storage] "+m" (storage)
484                 : [argument] "iq" (v)
485                 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
486             );
487         }
488     }
489 
opaque_subboost::atomics::detail::extra_operations490     static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
491     {
492         if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
493         {
494             __asm__ __volatile__
495             (
496                 "lock; decw %[storage]\n\t"
497                 : [storage] "+m" (storage)
498                 :
499                 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
500             );
501         }
502         else
503         {
504             __asm__ __volatile__
505             (
506                 "lock; subw %[argument], %[storage]\n\t"
507                 : [storage] "+m" (storage)
508                 : [argument] "iq" (v)
509                 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
510             );
511         }
512     }
513 
opaque_negateboost::atomics::detail::extra_operations514     static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
515     {
516         __asm__ __volatile__
517         (
518             "lock; negw %[storage]\n\t"
519             : [storage] "+m" (storage)
520             :
521             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
522         );
523     }
524 
opaque_andboost::atomics::detail::extra_operations525     static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
526     {
527         __asm__ __volatile__
528         (
529             "lock; andw %[argument], %[storage]\n\t"
530             : [storage] "+m" (storage)
531             : [argument] "iq" (v)
532             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
533         );
534     }
535 
opaque_orboost::atomics::detail::extra_operations536     static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
537     {
538         __asm__ __volatile__
539         (
540             "lock; orw %[argument], %[storage]\n\t"
541             : [storage] "+m" (storage)
542             : [argument] "iq" (v)
543             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
544         );
545     }
546 
opaque_xorboost::atomics::detail::extra_operations547     static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
548     {
549         __asm__ __volatile__
550         (
551             "lock; xorw %[argument], %[storage]\n\t"
552             : [storage] "+m" (storage)
553             : [argument] "iq" (v)
554             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
555         );
556     }
557 
opaque_complementboost::atomics::detail::extra_operations558     static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
559     {
560         __asm__ __volatile__
561         (
562             "lock; notw %[storage]\n\t"
563             : [storage] "+m" (storage)
564             :
565             : "memory"
566         );
567     }
568 
add_and_testboost::atomics::detail::extra_operations569     static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
570     {
571         bool res;
572 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
573         if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
574         {
575             __asm__ __volatile__
576             (
577                 "lock; incw %[storage]\n\t"
578                 : [storage] "+m" (storage), [result] "=@ccz" (res)
579                 :
580                 : "memory"
581             );
582         }
583         else
584         {
585             __asm__ __volatile__
586             (
587                 "lock; addw %[argument], %[storage]\n\t"
588                 : [storage] "+m" (storage), [result] "=@ccz" (res)
589                 : [argument] "iq" (v)
590                 : "memory"
591             );
592         }
593 #else
594         if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
595         {
596             __asm__ __volatile__
597             (
598                 "lock; incw %[storage]\n\t"
599                 "setz %[result]\n\t"
600                 : [storage] "+m" (storage), [result] "=q" (res)
601                 :
602                 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
603             );
604         }
605         else
606         {
607             __asm__ __volatile__
608             (
609                 "lock; addw %[argument], %[storage]\n\t"
610                 "setz %[result]\n\t"
611                 : [storage] "+m" (storage), [result] "=q" (res)
612                 : [argument] "iq" (v)
613                 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
614             );
615         }
616 #endif
617         return res;
618     }
619 
sub_and_testboost::atomics::detail::extra_operations620     static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
621     {
622         bool res;
623 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
624         if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
625         {
626             __asm__ __volatile__
627             (
628                 "lock; decw %[storage]\n\t"
629                 : [storage] "+m" (storage), [result] "=@ccz" (res)
630                 :
631                 : "memory"
632             );
633         }
634         else
635         {
636             __asm__ __volatile__
637             (
638                 "lock; subw %[argument], %[storage]\n\t"
639                 : [storage] "+m" (storage), [result] "=@ccz" (res)
640                 : [argument] "iq" (v)
641                 : "memory"
642             );
643         }
644 #else
645         if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
646         {
647             __asm__ __volatile__
648             (
649                 "lock; decw %[storage]\n\t"
650                 "setz %[result]\n\t"
651                 : [storage] "+m" (storage), [result] "=q" (res)
652                 :
653                 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
654             );
655         }
656         else
657         {
658             __asm__ __volatile__
659             (
660                 "lock; subw %[argument], %[storage]\n\t"
661                 "setz %[result]\n\t"
662                 : [storage] "+m" (storage), [result] "=q" (res)
663                 : [argument] "iq" (v)
664                 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
665             );
666         }
667 #endif
668         return res;
669     }
670 
and_and_testboost::atomics::detail::extra_operations671     static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
672     {
673         bool res;
674 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
675         __asm__ __volatile__
676         (
677             "lock; andw %[argument], %[storage]\n\t"
678             : [storage] "+m" (storage), [result] "=@ccz" (res)
679             : [argument] "iq" (v)
680             : "memory"
681         );
682 #else
683         __asm__ __volatile__
684         (
685             "lock; andw %[argument], %[storage]\n\t"
686             "setz %[result]\n\t"
687             : [storage] "+m" (storage), [result] "=q" (res)
688             : [argument] "iq" (v)
689             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
690         );
691 #endif
692         return res;
693     }
694 
or_and_testboost::atomics::detail::extra_operations695     static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
696     {
697         bool res;
698 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
699         __asm__ __volatile__
700         (
701             "lock; orw %[argument], %[storage]\n\t"
702             : [storage] "+m" (storage), [result] "=@ccz" (res)
703             : [argument] "iq" (v)
704             : "memory"
705         );
706 #else
707         __asm__ __volatile__
708         (
709             "lock; orw %[argument], %[storage]\n\t"
710             "setz %[result]\n\t"
711             : [storage] "+m" (storage), [result] "=q" (res)
712             : [argument] "iq" (v)
713             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
714         );
715 #endif
716         return res;
717     }
718 
xor_and_testboost::atomics::detail::extra_operations719     static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
720     {
721         bool res;
722 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
723         __asm__ __volatile__
724         (
725             "lock; xorw %[argument], %[storage]\n\t"
726             : [storage] "+m" (storage), [result] "=@ccz" (res)
727             : [argument] "iq" (v)
728             : "memory"
729         );
730 #else
731         __asm__ __volatile__
732         (
733             "lock; xorw %[argument], %[storage]\n\t"
734             "setz %[result]\n\t"
735             : [storage] "+m" (storage), [result] "=q" (res)
736             : [argument] "iq" (v)
737             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
738         );
739 #endif
740         return res;
741     }
742 };
743 
744 template< typename Base, bool Signed >
745 struct extra_operations< Base, 4u, Signed > :
746     public gcc_x86_extra_operations_common< Base >
747 {
748     typedef gcc_x86_extra_operations_common< Base > base_type;
749     typedef typename base_type::storage_type storage_type;
750 
751 #define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, result)\
752     storage_type new_val;\
753     __asm__ __volatile__\
754     (\
755         ".align 16\n\t"\
756         "1: mov %[res], %[new_val]\n\t"\
757         op " %[new_val]\n\t"\
758         "lock; cmpxchgl %[new_val], %[storage]\n\t"\
759         "jne 1b"\
760         : [res] "+a" (result), [storage] "+m" (storage), [new_val] "=&r" (new_val)\
761         : \
762         : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\
763     )
764 
fetch_negateboost::atomics::detail::extra_operations765     static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
766     {
767         storage_type res = storage;
768         BOOST_ATOMIC_DETAIL_CAS_LOOP("negl", res);
769         return res;
770     }
771 
fetch_complementboost::atomics::detail::extra_operations772     static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
773     {
774         storage_type res = storage;
775         BOOST_ATOMIC_DETAIL_CAS_LOOP("notl", res);
776         return res;
777     }
778 
779 #undef BOOST_ATOMIC_DETAIL_CAS_LOOP
780 
opaque_addboost::atomics::detail::extra_operations781     static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
782     {
783         if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
784         {
785             __asm__ __volatile__
786             (
787                 "lock; incl %[storage]\n\t"
788                 : [storage] "+m" (storage)
789                 :
790                 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
791             );
792         }
793         else
794         {
795             __asm__ __volatile__
796             (
797                 "lock; addl %[argument], %[storage]\n\t"
798                 : [storage] "+m" (storage)
799                 : [argument] "ir" (v)
800                 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
801             );
802         }
803     }
804 
opaque_subboost::atomics::detail::extra_operations805     static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
806     {
807         if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
808         {
809             __asm__ __volatile__
810             (
811                 "lock; decl %[storage]\n\t"
812                 : [storage] "+m" (storage)
813                 :
814                 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
815             );
816         }
817         else
818         {
819             __asm__ __volatile__
820             (
821                 "lock; subl %[argument], %[storage]\n\t"
822                 : [storage] "+m" (storage)
823                 : [argument] "ir" (v)
824                 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
825             );
826         }
827     }
828 
opaque_negateboost::atomics::detail::extra_operations829     static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
830     {
831         __asm__ __volatile__
832         (
833             "lock; negl %[storage]\n\t"
834             : [storage] "+m" (storage)
835             :
836             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
837         );
838     }
839 
opaque_andboost::atomics::detail::extra_operations840     static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
841     {
842         __asm__ __volatile__
843         (
844             "lock; andl %[argument], %[storage]\n\t"
845             : [storage] "+m" (storage)
846             : [argument] "ir" (v)
847             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
848         );
849     }
850 
opaque_orboost::atomics::detail::extra_operations851     static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
852     {
853         __asm__ __volatile__
854         (
855             "lock; orl %[argument], %[storage]\n\t"
856             : [storage] "+m" (storage)
857             : [argument] "ir" (v)
858             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
859         );
860     }
861 
opaque_xorboost::atomics::detail::extra_operations862     static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
863     {
864         __asm__ __volatile__
865         (
866             "lock; xorl %[argument], %[storage]\n\t"
867             : [storage] "+m" (storage)
868             : [argument] "ir" (v)
869             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
870         );
871     }
872 
opaque_complementboost::atomics::detail::extra_operations873     static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
874     {
875         __asm__ __volatile__
876         (
877             "lock; notl %[storage]\n\t"
878             : [storage] "+m" (storage)
879             :
880             : "memory"
881         );
882     }
883 
add_and_testboost::atomics::detail::extra_operations884     static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
885     {
886         bool res;
887 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
888         if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
889         {
890             __asm__ __volatile__
891             (
892                 "lock; incl %[storage]\n\t"
893                 : [storage] "+m" (storage), [result] "=@ccz" (res)
894                 :
895                 : "memory"
896             );
897         }
898         else
899         {
900             __asm__ __volatile__
901             (
902                 "lock; addl %[argument], %[storage]\n\t"
903                 : [storage] "+m" (storage), [result] "=@ccz" (res)
904                 : [argument] "ir" (v)
905                 : "memory"
906             );
907         }
908 #else
909         if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
910         {
911             __asm__ __volatile__
912             (
913                 "lock; incl %[storage]\n\t"
914                 "setz %[result]\n\t"
915                 : [storage] "+m" (storage), [result] "=q" (res)
916                 :
917                 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
918             );
919         }
920         else
921         {
922             __asm__ __volatile__
923             (
924                 "lock; addl %[argument], %[storage]\n\t"
925                 "setz %[result]\n\t"
926                 : [storage] "+m" (storage), [result] "=q" (res)
927                 : [argument] "ir" (v)
928                 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
929             );
930         }
931 #endif
932         return res;
933     }
934 
sub_and_testboost::atomics::detail::extra_operations935     static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
936     {
937         bool res;
938 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
939         if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
940         {
941             __asm__ __volatile__
942             (
943                 "lock; decl %[storage]\n\t"
944                 : [storage] "+m" (storage), [result] "=@ccz" (res)
945                 :
946                 : "memory"
947             );
948         }
949         else
950         {
951             __asm__ __volatile__
952             (
953                 "lock; subl %[argument], %[storage]\n\t"
954                 : [storage] "+m" (storage), [result] "=@ccz" (res)
955                 : [argument] "ir" (v)
956                 : "memory"
957             );
958         }
959 #else
960         if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
961         {
962             __asm__ __volatile__
963             (
964                 "lock; decl %[storage]\n\t"
965                 "setz %[result]\n\t"
966                 : [storage] "+m" (storage), [result] "=q" (res)
967                 :
968                 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
969             );
970         }
971         else
972         {
973             __asm__ __volatile__
974             (
975                 "lock; subl %[argument], %[storage]\n\t"
976                 "setz %[result]\n\t"
977                 : [storage] "+m" (storage), [result] "=q" (res)
978                 : [argument] "ir" (v)
979                 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
980             );
981         }
982 #endif
983         return res;
984     }
985 
and_and_testboost::atomics::detail::extra_operations986     static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
987     {
988         bool res;
989 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
990         __asm__ __volatile__
991         (
992             "lock; andl %[argument], %[storage]\n\t"
993             : [storage] "+m" (storage), [result] "=@ccz" (res)
994             : [argument] "ir" (v)
995             : "memory"
996         );
997 #else
998         __asm__ __volatile__
999         (
1000             "lock; andl %[argument], %[storage]\n\t"
1001             "setz %[result]\n\t"
1002             : [storage] "+m" (storage), [result] "=q" (res)
1003             : [argument] "ir" (v)
1004             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1005         );
1006 #endif
1007         return res;
1008     }
1009 
or_and_testboost::atomics::detail::extra_operations1010     static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
1011     {
1012         bool res;
1013 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
1014         __asm__ __volatile__
1015         (
1016             "lock; orl %[argument], %[storage]\n\t"
1017             : [storage] "+m" (storage), [result] "=@ccz" (res)
1018             : [argument] "ir" (v)
1019             : "memory"
1020         );
1021 #else
1022         __asm__ __volatile__
1023         (
1024             "lock; orl %[argument], %[storage]\n\t"
1025             "setz %[result]\n\t"
1026             : [storage] "+m" (storage), [result] "=q" (res)
1027             : [argument] "ir" (v)
1028             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1029         );
1030 #endif
1031         return res;
1032     }
1033 
xor_and_testboost::atomics::detail::extra_operations1034     static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
1035     {
1036         bool res;
1037 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
1038         __asm__ __volatile__
1039         (
1040             "lock; xorl %[argument], %[storage]\n\t"
1041             : [storage] "+m" (storage), [result] "=@ccz" (res)
1042             : [argument] "ir" (v)
1043             : "memory"
1044         );
1045 #else
1046         __asm__ __volatile__
1047         (
1048             "lock; xorl %[argument], %[storage]\n\t"
1049             "setz %[result]\n\t"
1050             : [storage] "+m" (storage), [result] "=q" (res)
1051             : [argument] "ir" (v)
1052             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1053         );
1054 #endif
1055         return res;
1056     }
1057 };
1058 
1059 #if defined(__x86_64__)
1060 
1061 template< typename Base, bool Signed >
1062 struct extra_operations< Base, 8u, Signed > :
1063     public gcc_x86_extra_operations_common< Base >
1064 {
1065     typedef gcc_x86_extra_operations_common< Base > base_type;
1066     typedef typename base_type::storage_type storage_type;
1067 
1068 #define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, result)\
1069     storage_type new_val;\
1070     __asm__ __volatile__\
1071     (\
1072         ".align 16\n\t"\
1073         "1: mov %[res], %[new_val]\n\t"\
1074         op " %[new_val]\n\t"\
1075         "lock; cmpxchgq %[new_val], %[storage]\n\t"\
1076         "jne 1b"\
1077         : [res] "+a" (result), [storage] "+m" (storage), [new_val] "=&r" (new_val)\
1078         : \
1079         : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\
1080     )
1081 
fetch_negateboost::atomics::detail::extra_operations1082     static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
1083     {
1084         storage_type res = storage;
1085         BOOST_ATOMIC_DETAIL_CAS_LOOP("negq", res);
1086         return res;
1087     }
1088 
fetch_complementboost::atomics::detail::extra_operations1089     static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
1090     {
1091         storage_type res = storage;
1092         BOOST_ATOMIC_DETAIL_CAS_LOOP("notq", res);
1093         return res;
1094     }
1095 
1096 #undef BOOST_ATOMIC_DETAIL_CAS_LOOP
1097 
opaque_addboost::atomics::detail::extra_operations1098     static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
1099     {
1100         if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
1101         {
1102             __asm__ __volatile__
1103             (
1104                 "lock; incq %[storage]\n\t"
1105                 : [storage] "+m" (storage)
1106                 :
1107                 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1108             );
1109         }
1110         else
1111         {
1112             __asm__ __volatile__
1113             (
1114                 "lock; addq %[argument], %[storage]\n\t"
1115                 : [storage] "+m" (storage)
1116                 : [argument] "er" (v)
1117                 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1118             );
1119         }
1120     }
1121 
opaque_subboost::atomics::detail::extra_operations1122     static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
1123     {
1124         if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
1125         {
1126             __asm__ __volatile__
1127             (
1128                 "lock; decq %[storage]\n\t"
1129                 : [storage] "+m" (storage)
1130                 :
1131                 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1132             );
1133         }
1134         else
1135         {
1136             __asm__ __volatile__
1137             (
1138                 "lock; subq %[argument], %[storage]\n\t"
1139                 : [storage] "+m" (storage)
1140                 : [argument] "er" (v)
1141                 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1142             );
1143         }
1144     }
1145 
opaque_negateboost::atomics::detail::extra_operations1146     static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
1147     {
1148         __asm__ __volatile__
1149         (
1150             "lock; negq %[storage]\n\t"
1151             : [storage] "+m" (storage)
1152             :
1153             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1154         );
1155     }
1156 
opaque_andboost::atomics::detail::extra_operations1157     static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
1158     {
1159         __asm__ __volatile__
1160         (
1161             "lock; andq %[argument], %[storage]\n\t"
1162             : [storage] "+m" (storage)
1163             : [argument] "er" (v)
1164             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1165         );
1166     }
1167 
opaque_orboost::atomics::detail::extra_operations1168     static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
1169     {
1170         __asm__ __volatile__
1171         (
1172             "lock; orq %[argument], %[storage]\n\t"
1173             : [storage] "+m" (storage)
1174             : [argument] "er" (v)
1175             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1176         );
1177     }
1178 
opaque_xorboost::atomics::detail::extra_operations1179     static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
1180     {
1181         __asm__ __volatile__
1182         (
1183             "lock; xorq %[argument], %[storage]\n\t"
1184             : [storage] "+m" (storage)
1185             : [argument] "er" (v)
1186             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1187         );
1188     }
1189 
opaque_complementboost::atomics::detail::extra_operations1190     static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
1191     {
1192         __asm__ __volatile__
1193         (
1194             "lock; notq %[storage]\n\t"
1195             : [storage] "+m" (storage)
1196             :
1197             : "memory"
1198         );
1199     }
1200 
add_and_testboost::atomics::detail::extra_operations1201     static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
1202     {
1203         bool res;
1204 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
1205         if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
1206         {
1207             __asm__ __volatile__
1208             (
1209                 "lock; incq %[storage]\n\t"
1210                 : [storage] "+m" (storage), [result] "=@ccz" (res)
1211                 :
1212                 : "memory"
1213             );
1214         }
1215         else
1216         {
1217             __asm__ __volatile__
1218             (
1219                 "lock; addq %[argument], %[storage]\n\t"
1220                 : [storage] "+m" (storage), [result] "=@ccz" (res)
1221                 : [argument] "er" (v)
1222                 : "memory"
1223             );
1224         }
1225 #else
1226         if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
1227         {
1228             __asm__ __volatile__
1229             (
1230                 "lock; incq %[storage]\n\t"
1231                 "setz %[result]\n\t"
1232                 : [storage] "+m" (storage), [result] "=q" (res)
1233                 :
1234                 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1235             );
1236         }
1237         else
1238         {
1239             __asm__ __volatile__
1240             (
1241                 "lock; addq %[argument], %[storage]\n\t"
1242                 "setz %[result]\n\t"
1243                 : [storage] "+m" (storage), [result] "=q" (res)
1244                 : [argument] "er" (v)
1245                 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1246             );
1247         }
1248 #endif
1249         return res;
1250     }
1251 
sub_and_testboost::atomics::detail::extra_operations1252     static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
1253     {
1254         bool res;
1255 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
1256         if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
1257         {
1258             __asm__ __volatile__
1259             (
1260                 "lock; decq %[storage]\n\t"
1261                 : [storage] "+m" (storage), [result] "=@ccz" (res)
1262                 :
1263                 : "memory"
1264             );
1265         }
1266         else
1267         {
1268             __asm__ __volatile__
1269             (
1270                 "lock; subq %[argument], %[storage]\n\t"
1271                 : [storage] "+m" (storage), [result] "=@ccz" (res)
1272                 : [argument] "er" (v)
1273                 : "memory"
1274             );
1275         }
1276 #else
1277         if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
1278         {
1279             __asm__ __volatile__
1280             (
1281                 "lock; decq %[storage]\n\t"
1282                 "setz %[result]\n\t"
1283                 : [storage] "+m" (storage), [result] "=q" (res)
1284                 :
1285                 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1286             );
1287         }
1288         else
1289         {
1290             __asm__ __volatile__
1291             (
1292                 "lock; subq %[argument], %[storage]\n\t"
1293                 "setz %[result]\n\t"
1294                 : [storage] "+m" (storage), [result] "=q" (res)
1295                 : [argument] "er" (v)
1296                 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1297             );
1298         }
1299 #endif
1300         return res;
1301     }
1302 
and_and_testboost::atomics::detail::extra_operations1303     static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
1304     {
1305         bool res;
1306 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
1307         __asm__ __volatile__
1308         (
1309             "lock; andq %[argument], %[storage]\n\t"
1310             : [storage] "+m" (storage), [result] "=@ccz" (res)
1311             : [argument] "er" (v)
1312             : "memory"
1313         );
1314 #else
1315         __asm__ __volatile__
1316         (
1317             "lock; andq %[argument], %[storage]\n\t"
1318             "setz %[result]\n\t"
1319             : [storage] "+m" (storage), [result] "=q" (res)
1320             : [argument] "er" (v)
1321             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1322         );
1323 #endif
1324         return res;
1325     }
1326 
or_and_testboost::atomics::detail::extra_operations1327     static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
1328     {
1329         bool res;
1330 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
1331         __asm__ __volatile__
1332         (
1333             "lock; orq %[argument], %[storage]\n\t"
1334             : [storage] "+m" (storage), [result] "=@ccz" (res)
1335             : [argument] "er" (v)
1336             : "memory"
1337         );
1338 #else
1339         __asm__ __volatile__
1340         (
1341             "lock; orq %[argument], %[storage]\n\t"
1342             "setz %[result]\n\t"
1343             : [storage] "+m" (storage), [result] "=q" (res)
1344             : [argument] "er" (v)
1345             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1346         );
1347 #endif
1348         return res;
1349     }
1350 
xor_and_testboost::atomics::detail::extra_operations1351     static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
1352     {
1353         bool res;
1354 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
1355         __asm__ __volatile__
1356         (
1357             "lock; xorq %[argument], %[storage]\n\t"
1358             : [storage] "+m" (storage), [result] "=@ccz" (res)
1359             : [argument] "er" (v)
1360             : "memory"
1361         );
1362 #else
1363         __asm__ __volatile__
1364         (
1365             "lock; xorq %[argument], %[storage]\n\t"
1366             "setz %[result]\n\t"
1367             : [storage] "+m" (storage), [result] "=q" (res)
1368             : [argument] "er" (v)
1369             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1370         );
1371 #endif
1372         return res;
1373     }
1374 };
1375 
1376 #endif // defined(__x86_64__)
1377 
1378 } // namespace detail
1379 } // namespace atomics
1380 } // namespace boost
1381 
1382 #endif // BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_X86_HPP_INCLUDED_
1383