]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/atomic/detail/extra_ops_gcc_x86.hpp
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / boost / boost / atomic / detail / extra_ops_gcc_x86.hpp
CommitLineData
b32b8144
FG
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
28namespace boost {
29namespace atomics {
30namespace detail {
31
32template< typename Base >
33struct gcc_x86_extra_operations_common :
34 public Base
35{
36 typedef Base base_type;
37 typedef typename base_type::storage_type storage_type;
38
11fdf7f2
TL
39 static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
40 {
41 return static_cast< storage_type >(Base::fetch_add(storage, v, order) + v);
42 }
43
44 static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
45 {
46 return static_cast< storage_type >(Base::fetch_sub(storage, v, order) - v);
47 }
48
b32b8144
FG
49 static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order) BOOST_NOEXCEPT
50 {
51 bool res;
52#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
53 __asm__ __volatile__
54 (
55 "lock; bts %[bit_number], %[storage]\n\t"
56 : [storage] "+m" (storage), [result] "=@ccc" (res)
57 : [bit_number] "Kq" (bit_number)
58 : "memory"
59 );
60#else
61 __asm__ __volatile__
62 (
63 "lock; bts %[bit_number], %[storage]\n\t"
64 "setc %[result]\n\t"
65 : [storage] "+m" (storage), [result] "=q" (res)
66 : [bit_number] "Kq" (bit_number)
67 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
68 );
69#endif
70 return res;
71 }
72
73 static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order) BOOST_NOEXCEPT
74 {
75 bool res;
76#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
77 __asm__ __volatile__
78 (
79 "lock; btr %[bit_number], %[storage]\n\t"
80 : [storage] "+m" (storage), [result] "=@ccc" (res)
81 : [bit_number] "Kq" (bit_number)
82 : "memory"
83 );
84#else
85 __asm__ __volatile__
86 (
87 "lock; btr %[bit_number], %[storage]\n\t"
88 "setc %[result]\n\t"
89 : [storage] "+m" (storage), [result] "=q" (res)
90 : [bit_number] "Kq" (bit_number)
91 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
92 );
93#endif
94 return res;
95 }
96
97 static BOOST_FORCEINLINE bool bit_test_and_complement(storage_type volatile& storage, unsigned int bit_number, memory_order) BOOST_NOEXCEPT
98 {
99 bool res;
100#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
101 __asm__ __volatile__
102 (
103 "lock; btc %[bit_number], %[storage]\n\t"
104 : [storage] "+m" (storage), [result] "=@ccc" (res)
105 : [bit_number] "Kq" (bit_number)
106 : "memory"
107 );
108#else
109 __asm__ __volatile__
110 (
111 "lock; btc %[bit_number], %[storage]\n\t"
112 "setc %[result]\n\t"
113 : [storage] "+m" (storage), [result] "=q" (res)
114 : [bit_number] "Kq" (bit_number)
115 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
116 );
117#endif
118 return res;
119 }
120};
121
122template< typename Base, bool Signed >
11fdf7f2 123struct extra_operations< Base, 1u, Signed, true > :
b32b8144
FG
124 public gcc_x86_extra_operations_common< Base >
125{
126 typedef gcc_x86_extra_operations_common< Base > base_type;
127 typedef typename base_type::storage_type storage_type;
11fdf7f2 128 typedef typename make_storage_type< 4u >::type temp_storage_type;
b32b8144 129
11fdf7f2 130#define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, original, result)\
b32b8144
FG
131 __asm__ __volatile__\
132 (\
133 ".align 16\n\t"\
11fdf7f2 134 "1: movzbl %[orig], %2\n\t"\
b32b8144
FG
135 op " %b2\n\t"\
136 "lock; cmpxchgb %b2, %[storage]\n\t"\
137 "jne 1b"\
11fdf7f2 138 : [orig] "+a" (original), [storage] "+m" (storage), "=&q" (result)\
b32b8144
FG
139 : \
140 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\
141 )
142
143 static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
144 {
11fdf7f2
TL
145 storage_type original = storage;
146 temp_storage_type result;
147 BOOST_ATOMIC_DETAIL_CAS_LOOP("negb", original, result);
148 return original;
b32b8144
FG
149 }
150
151 static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
152 {
11fdf7f2
TL
153 storage_type original = storage;
154 temp_storage_type result;
155 BOOST_ATOMIC_DETAIL_CAS_LOOP("notb", original, result);
156 return original;
157 }
158
159 static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
160 {
161 storage_type original = storage;
162 temp_storage_type result;
163 BOOST_ATOMIC_DETAIL_CAS_LOOP("negb", original, result);
164 return static_cast< storage_type >(result);
165 }
166
167 static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
168 {
169 storage_type original = storage;
170 temp_storage_type result;
171 BOOST_ATOMIC_DETAIL_CAS_LOOP("notb", original, result);
172 return static_cast< storage_type >(result);
173 }
174
175#undef BOOST_ATOMIC_DETAIL_CAS_LOOP
176
177#define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, argument, original, result)\
178 __asm__ __volatile__\
179 (\
180 ".align 16\n\t"\
181 "1: mov %[arg], %2\n\t"\
182 op " %%al, %b2\n\t"\
183 "lock; cmpxchgb %b2, %[storage]\n\t"\
184 "jne 1b"\
185 : [orig] "+a" (original), [storage] "+m" (storage), "=&q" (result)\
186 : [arg] "ir" ((temp_storage_type)argument)\
187 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\
188 )
189
190 static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
191 {
192 storage_type original = storage;
193 temp_storage_type result;
194 BOOST_ATOMIC_DETAIL_CAS_LOOP("andb", v, original, result);
195 return static_cast< storage_type >(result);
196 }
197
198 static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
199 {
200 storage_type original = storage;
201 temp_storage_type result;
202 BOOST_ATOMIC_DETAIL_CAS_LOOP("orb", v, original, result);
203 return static_cast< storage_type >(result);
204 }
205
206 static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
207 {
208 storage_type original = storage;
209 temp_storage_type result;
210 BOOST_ATOMIC_DETAIL_CAS_LOOP("xorb", v, original, result);
211 return static_cast< storage_type >(result);
b32b8144
FG
212 }
213
214#undef BOOST_ATOMIC_DETAIL_CAS_LOOP
215
11fdf7f2
TL
216 static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
217 {
218 return !!negate(storage, order);
219 }
220
221 static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
222 {
223 return !!bitwise_complement(storage, order);
224 }
225
b32b8144
FG
226 static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
227 {
228 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
229 {
230 __asm__ __volatile__
231 (
232 "lock; incb %[storage]\n\t"
233 : [storage] "+m" (storage)
234 :
235 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
236 );
237 }
238 else
239 {
240 __asm__ __volatile__
241 (
242 "lock; addb %[argument], %[storage]\n\t"
243 : [storage] "+m" (storage)
244 : [argument] "iq" (v)
245 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
246 );
247 }
248 }
249
250 static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
251 {
252 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
253 {
254 __asm__ __volatile__
255 (
256 "lock; decb %[storage]\n\t"
257 : [storage] "+m" (storage)
258 :
259 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
260 );
261 }
262 else
263 {
264 __asm__ __volatile__
265 (
266 "lock; subb %[argument], %[storage]\n\t"
267 : [storage] "+m" (storage)
268 : [argument] "iq" (v)
269 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
270 );
271 }
272 }
273
274 static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
275 {
276 __asm__ __volatile__
277 (
278 "lock; negb %[storage]\n\t"
279 : [storage] "+m" (storage)
280 :
281 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
282 );
283 }
284
285 static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
286 {
287 __asm__ __volatile__
288 (
289 "lock; andb %[argument], %[storage]\n\t"
290 : [storage] "+m" (storage)
291 : [argument] "iq" (v)
292 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
293 );
294 }
295
296 static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
297 {
298 __asm__ __volatile__
299 (
300 "lock; orb %[argument], %[storage]\n\t"
301 : [storage] "+m" (storage)
302 : [argument] "iq" (v)
303 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
304 );
305 }
306
307 static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
308 {
309 __asm__ __volatile__
310 (
311 "lock; xorb %[argument], %[storage]\n\t"
312 : [storage] "+m" (storage)
313 : [argument] "iq" (v)
314 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
315 );
316 }
317
318 static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
319 {
320 __asm__ __volatile__
321 (
322 "lock; notb %[storage]\n\t"
323 : [storage] "+m" (storage)
324 :
325 : "memory"
326 );
327 }
328
329 static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
330 {
331 bool res;
332#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
333 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
334 {
335 __asm__ __volatile__
336 (
337 "lock; incb %[storage]\n\t"
11fdf7f2 338 : [storage] "+m" (storage), [result] "=@ccnz" (res)
b32b8144
FG
339 :
340 : "memory"
341 );
342 }
343 else
344 {
345 __asm__ __volatile__
346 (
347 "lock; addb %[argument], %[storage]\n\t"
11fdf7f2 348 : [storage] "+m" (storage), [result] "=@ccnz" (res)
b32b8144
FG
349 : [argument] "iq" (v)
350 : "memory"
351 );
352 }
353#else
354 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
355 {
356 __asm__ __volatile__
357 (
358 "lock; incb %[storage]\n\t"
11fdf7f2 359 "setnz %[result]\n\t"
b32b8144
FG
360 : [storage] "+m" (storage), [result] "=q" (res)
361 :
362 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
363 );
364 }
365 else
366 {
367 __asm__ __volatile__
368 (
369 "lock; addb %[argument], %[storage]\n\t"
11fdf7f2 370 "setnz %[result]\n\t"
b32b8144
FG
371 : [storage] "+m" (storage), [result] "=q" (res)
372 : [argument] "iq" (v)
373 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
374 );
375 }
376#endif
377 return res;
378 }
379
380 static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
381 {
382 bool res;
383#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
384 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
385 {
386 __asm__ __volatile__
387 (
388 "lock; decb %[storage]\n\t"
11fdf7f2 389 : [storage] "+m" (storage), [result] "=@ccnz" (res)
b32b8144
FG
390 :
391 : "memory"
392 );
393 }
394 else
395 {
396 __asm__ __volatile__
397 (
398 "lock; subb %[argument], %[storage]\n\t"
11fdf7f2 399 : [storage] "+m" (storage), [result] "=@ccnz" (res)
b32b8144
FG
400 : [argument] "iq" (v)
401 : "memory"
402 );
403 }
404#else
405 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
406 {
407 __asm__ __volatile__
408 (
409 "lock; decb %[storage]\n\t"
11fdf7f2 410 "setnz %[result]\n\t"
b32b8144
FG
411 : [storage] "+m" (storage), [result] "=q" (res)
412 :
413 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
414 );
415 }
416 else
417 {
418 __asm__ __volatile__
419 (
420 "lock; subb %[argument], %[storage]\n\t"
11fdf7f2 421 "setnz %[result]\n\t"
b32b8144
FG
422 : [storage] "+m" (storage), [result] "=q" (res)
423 : [argument] "iq" (v)
424 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
425 );
426 }
427#endif
428 return res;
429 }
430
431 static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
432 {
433 bool res;
434#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
435 __asm__ __volatile__
436 (
437 "lock; andb %[argument], %[storage]\n\t"
11fdf7f2 438 : [storage] "+m" (storage), [result] "=@ccnz" (res)
b32b8144
FG
439 : [argument] "iq" (v)
440 : "memory"
441 );
442#else
443 __asm__ __volatile__
444 (
445 "lock; andb %[argument], %[storage]\n\t"
11fdf7f2 446 "setnz %[result]\n\t"
b32b8144
FG
447 : [storage] "+m" (storage), [result] "=q" (res)
448 : [argument] "iq" (v)
449 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
450 );
451#endif
452 return res;
453 }
454
455 static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
456 {
457 bool res;
458#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
459 __asm__ __volatile__
460 (
461 "lock; orb %[argument], %[storage]\n\t"
11fdf7f2 462 : [storage] "+m" (storage), [result] "=@ccnz" (res)
b32b8144
FG
463 : [argument] "iq" (v)
464 : "memory"
465 );
466#else
467 __asm__ __volatile__
468 (
469 "lock; orb %[argument], %[storage]\n\t"
11fdf7f2 470 "setnz %[result]\n\t"
b32b8144
FG
471 : [storage] "+m" (storage), [result] "=q" (res)
472 : [argument] "iq" (v)
473 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
474 );
475#endif
476 return res;
477 }
478
479 static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
480 {
481 bool res;
482#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
483 __asm__ __volatile__
484 (
485 "lock; xorb %[argument], %[storage]\n\t"
11fdf7f2 486 : [storage] "+m" (storage), [result] "=@ccnz" (res)
b32b8144
FG
487 : [argument] "iq" (v)
488 : "memory"
489 );
490#else
491 __asm__ __volatile__
492 (
493 "lock; xorb %[argument], %[storage]\n\t"
11fdf7f2 494 "setnz %[result]\n\t"
b32b8144
FG
495 : [storage] "+m" (storage), [result] "=q" (res)
496 : [argument] "iq" (v)
497 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
498 );
499#endif
500 return res;
501 }
502};
503
504template< typename Base, bool Signed >
11fdf7f2 505struct extra_operations< Base, 2u, Signed, true > :
b32b8144
FG
506 public gcc_x86_extra_operations_common< Base >
507{
508 typedef gcc_x86_extra_operations_common< Base > base_type;
509 typedef typename base_type::storage_type storage_type;
11fdf7f2 510 typedef typename make_storage_type< 4u >::type temp_storage_type;
b32b8144 511
11fdf7f2 512#define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, original, result)\
b32b8144
FG
513 __asm__ __volatile__\
514 (\
515 ".align 16\n\t"\
11fdf7f2 516 "1: movzwl %[orig], %2\n\t"\
b32b8144
FG
517 op " %w2\n\t"\
518 "lock; cmpxchgw %w2, %[storage]\n\t"\
519 "jne 1b"\
11fdf7f2 520 : [orig] "+a" (original), [storage] "+m" (storage), "=&q" (result)\
b32b8144
FG
521 : \
522 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\
523 )
524
525 static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
526 {
11fdf7f2
TL
527 storage_type original = storage;
528 temp_storage_type result;
529 BOOST_ATOMIC_DETAIL_CAS_LOOP("negw", original, result);
530 return original;
b32b8144
FG
531 }
532
533 static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
534 {
11fdf7f2
TL
535 storage_type original = storage;
536 temp_storage_type result;
537 BOOST_ATOMIC_DETAIL_CAS_LOOP("notw", original, result);
538 return original;
539 }
540
541 static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
542 {
543 storage_type original = storage;
544 temp_storage_type result;
545 BOOST_ATOMIC_DETAIL_CAS_LOOP("negw", original, result);
546 return static_cast< storage_type >(result);
547 }
548
549 static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
550 {
551 storage_type original = storage;
552 temp_storage_type result;
553 BOOST_ATOMIC_DETAIL_CAS_LOOP("notw", original, result);
554 return static_cast< storage_type >(result);
555 }
556
557#undef BOOST_ATOMIC_DETAIL_CAS_LOOP
558
559#define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, argument, original, result)\
560 __asm__ __volatile__\
561 (\
562 ".align 16\n\t"\
563 "1: mov %[arg], %2\n\t"\
564 op " %%ax, %w2\n\t"\
565 "lock; cmpxchgw %w2, %[storage]\n\t"\
566 "jne 1b"\
567 : [orig] "+a" (original), [storage] "+m" (storage), "=&q" (result)\
568 : [arg] "ir" ((temp_storage_type)argument)\
569 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\
570 )
571
572 static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
573 {
574 storage_type original = storage;
575 temp_storage_type result;
576 BOOST_ATOMIC_DETAIL_CAS_LOOP("andw", v, original, result);
577 return static_cast< storage_type >(result);
578 }
579
580 static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
581 {
582 storage_type original = storage;
583 temp_storage_type result;
584 BOOST_ATOMIC_DETAIL_CAS_LOOP("orw", v, original, result);
585 return static_cast< storage_type >(result);
586 }
587
588 static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
589 {
590 storage_type original = storage;
591 temp_storage_type result;
592 BOOST_ATOMIC_DETAIL_CAS_LOOP("xorw", v, original, result);
593 return static_cast< storage_type >(result);
b32b8144
FG
594 }
595
596#undef BOOST_ATOMIC_DETAIL_CAS_LOOP
597
11fdf7f2
TL
598 static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
599 {
600 return !!negate(storage, order);
601 }
602
603 static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
604 {
605 return !!bitwise_complement(storage, order);
606 }
607
b32b8144
FG
608 static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
609 {
610 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
611 {
612 __asm__ __volatile__
613 (
614 "lock; incw %[storage]\n\t"
615 : [storage] "+m" (storage)
616 :
617 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
618 );
619 }
620 else
621 {
622 __asm__ __volatile__
623 (
624 "lock; addw %[argument], %[storage]\n\t"
625 : [storage] "+m" (storage)
626 : [argument] "iq" (v)
627 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
628 );
629 }
630 }
631
632 static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
633 {
634 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
635 {
636 __asm__ __volatile__
637 (
638 "lock; decw %[storage]\n\t"
639 : [storage] "+m" (storage)
640 :
641 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
642 );
643 }
644 else
645 {
646 __asm__ __volatile__
647 (
648 "lock; subw %[argument], %[storage]\n\t"
649 : [storage] "+m" (storage)
650 : [argument] "iq" (v)
651 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
652 );
653 }
654 }
655
656 static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
657 {
658 __asm__ __volatile__
659 (
660 "lock; negw %[storage]\n\t"
661 : [storage] "+m" (storage)
662 :
663 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
664 );
665 }
666
667 static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
668 {
669 __asm__ __volatile__
670 (
671 "lock; andw %[argument], %[storage]\n\t"
672 : [storage] "+m" (storage)
673 : [argument] "iq" (v)
674 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
675 );
676 }
677
678 static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
679 {
680 __asm__ __volatile__
681 (
682 "lock; orw %[argument], %[storage]\n\t"
683 : [storage] "+m" (storage)
684 : [argument] "iq" (v)
685 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
686 );
687 }
688
689 static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
690 {
691 __asm__ __volatile__
692 (
693 "lock; xorw %[argument], %[storage]\n\t"
694 : [storage] "+m" (storage)
695 : [argument] "iq" (v)
696 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
697 );
698 }
699
700 static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
701 {
702 __asm__ __volatile__
703 (
704 "lock; notw %[storage]\n\t"
705 : [storage] "+m" (storage)
706 :
707 : "memory"
708 );
709 }
710
711 static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
712 {
713 bool res;
714#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
715 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
716 {
717 __asm__ __volatile__
718 (
719 "lock; incw %[storage]\n\t"
11fdf7f2 720 : [storage] "+m" (storage), [result] "=@ccnz" (res)
b32b8144
FG
721 :
722 : "memory"
723 );
724 }
725 else
726 {
727 __asm__ __volatile__
728 (
729 "lock; addw %[argument], %[storage]\n\t"
11fdf7f2 730 : [storage] "+m" (storage), [result] "=@ccnz" (res)
b32b8144
FG
731 : [argument] "iq" (v)
732 : "memory"
733 );
734 }
735#else
736 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
737 {
738 __asm__ __volatile__
739 (
740 "lock; incw %[storage]\n\t"
11fdf7f2 741 "setnz %[result]\n\t"
b32b8144
FG
742 : [storage] "+m" (storage), [result] "=q" (res)
743 :
744 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
745 );
746 }
747 else
748 {
749 __asm__ __volatile__
750 (
751 "lock; addw %[argument], %[storage]\n\t"
11fdf7f2 752 "setnz %[result]\n\t"
b32b8144
FG
753 : [storage] "+m" (storage), [result] "=q" (res)
754 : [argument] "iq" (v)
755 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
756 );
757 }
758#endif
759 return res;
760 }
761
762 static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
763 {
764 bool res;
765#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
766 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
767 {
768 __asm__ __volatile__
769 (
770 "lock; decw %[storage]\n\t"
11fdf7f2 771 : [storage] "+m" (storage), [result] "=@ccnz" (res)
b32b8144
FG
772 :
773 : "memory"
774 );
775 }
776 else
777 {
778 __asm__ __volatile__
779 (
780 "lock; subw %[argument], %[storage]\n\t"
11fdf7f2 781 : [storage] "+m" (storage), [result] "=@ccnz" (res)
b32b8144
FG
782 : [argument] "iq" (v)
783 : "memory"
784 );
785 }
786#else
787 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
788 {
789 __asm__ __volatile__
790 (
791 "lock; decw %[storage]\n\t"
11fdf7f2 792 "setnz %[result]\n\t"
b32b8144
FG
793 : [storage] "+m" (storage), [result] "=q" (res)
794 :
795 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
796 );
797 }
798 else
799 {
800 __asm__ __volatile__
801 (
802 "lock; subw %[argument], %[storage]\n\t"
11fdf7f2 803 "setnz %[result]\n\t"
b32b8144
FG
804 : [storage] "+m" (storage), [result] "=q" (res)
805 : [argument] "iq" (v)
806 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
807 );
808 }
809#endif
810 return res;
811 }
812
813 static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
814 {
815 bool res;
816#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
817 __asm__ __volatile__
818 (
819 "lock; andw %[argument], %[storage]\n\t"
11fdf7f2 820 : [storage] "+m" (storage), [result] "=@ccnz" (res)
b32b8144
FG
821 : [argument] "iq" (v)
822 : "memory"
823 );
824#else
825 __asm__ __volatile__
826 (
827 "lock; andw %[argument], %[storage]\n\t"
11fdf7f2 828 "setnz %[result]\n\t"
b32b8144
FG
829 : [storage] "+m" (storage), [result] "=q" (res)
830 : [argument] "iq" (v)
831 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
832 );
833#endif
834 return res;
835 }
836
837 static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
838 {
839 bool res;
840#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
841 __asm__ __volatile__
842 (
843 "lock; orw %[argument], %[storage]\n\t"
11fdf7f2 844 : [storage] "+m" (storage), [result] "=@ccnz" (res)
b32b8144
FG
845 : [argument] "iq" (v)
846 : "memory"
847 );
848#else
849 __asm__ __volatile__
850 (
851 "lock; orw %[argument], %[storage]\n\t"
11fdf7f2 852 "setnz %[result]\n\t"
b32b8144
FG
853 : [storage] "+m" (storage), [result] "=q" (res)
854 : [argument] "iq" (v)
855 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
856 );
857#endif
858 return res;
859 }
860
861 static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
862 {
863 bool res;
864#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
865 __asm__ __volatile__
866 (
867 "lock; xorw %[argument], %[storage]\n\t"
11fdf7f2 868 : [storage] "+m" (storage), [result] "=@ccnz" (res)
b32b8144
FG
869 : [argument] "iq" (v)
870 : "memory"
871 );
872#else
873 __asm__ __volatile__
874 (
875 "lock; xorw %[argument], %[storage]\n\t"
11fdf7f2 876 "setnz %[result]\n\t"
b32b8144
FG
877 : [storage] "+m" (storage), [result] "=q" (res)
878 : [argument] "iq" (v)
879 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
880 );
881#endif
882 return res;
883 }
884};
885
886template< typename Base, bool Signed >
11fdf7f2 887struct extra_operations< Base, 4u, Signed, true > :
b32b8144
FG
888 public gcc_x86_extra_operations_common< Base >
889{
890 typedef gcc_x86_extra_operations_common< Base > base_type;
891 typedef typename base_type::storage_type storage_type;
892
11fdf7f2 893#define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, original, result)\
b32b8144
FG
894 __asm__ __volatile__\
895 (\
896 ".align 16\n\t"\
11fdf7f2
TL
897 "1: mov %[orig], %[res]\n\t"\
898 op " %[res]\n\t"\
899 "lock; cmpxchgl %[res], %[storage]\n\t"\
b32b8144 900 "jne 1b"\
11fdf7f2 901 : [orig] "+a" (original), [storage] "+m" (storage), [res] "=&r" (result)\
b32b8144
FG
902 : \
903 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\
904 )
905
906 static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
907 {
11fdf7f2
TL
908 storage_type original = storage;
909 storage_type result;
910 BOOST_ATOMIC_DETAIL_CAS_LOOP("negl", original, result);
911 return original;
b32b8144
FG
912 }
913
914 static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
915 {
11fdf7f2
TL
916 storage_type original = storage;
917 storage_type result;
918 BOOST_ATOMIC_DETAIL_CAS_LOOP("notl", original, result);
919 return original;
920 }
921
922 static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
923 {
924 storage_type original = storage;
925 storage_type result;
926 BOOST_ATOMIC_DETAIL_CAS_LOOP("negl", original, result);
927 return result;
928 }
929
930 static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
931 {
932 storage_type original = storage;
933 storage_type result;
934 BOOST_ATOMIC_DETAIL_CAS_LOOP("notl", original, result);
935 return result;
936 }
937
938#undef BOOST_ATOMIC_DETAIL_CAS_LOOP
939
940#define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, argument, original, result)\
941 __asm__ __volatile__\
942 (\
943 ".align 16\n\t"\
944 "1: mov %[arg], %[res]\n\t"\
945 op " %%eax, %[res]\n\t"\
946 "lock; cmpxchgl %[res], %[storage]\n\t"\
947 "jne 1b"\
948 : [orig] "+a" (original), [storage] "+m" (storage), [res] "=&r" (result)\
949 : [arg] "ir" (argument)\
950 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\
951 )
952
953 static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
954 {
955 storage_type original = storage;
956 storage_type result;
957 BOOST_ATOMIC_DETAIL_CAS_LOOP("andl", v, original, result);
958 return static_cast< storage_type >(result);
959 }
960
961 static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
962 {
963 storage_type original = storage;
964 storage_type result;
965 BOOST_ATOMIC_DETAIL_CAS_LOOP("orl", v, original, result);
966 return static_cast< storage_type >(result);
967 }
968
969 static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
970 {
971 storage_type original = storage;
972 storage_type result;
973 BOOST_ATOMIC_DETAIL_CAS_LOOP("xorl", v, original, result);
974 return static_cast< storage_type >(result);
b32b8144
FG
975 }
976
977#undef BOOST_ATOMIC_DETAIL_CAS_LOOP
978
11fdf7f2
TL
979 static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
980 {
981 return !!negate(storage, order);
982 }
983
984 static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
985 {
986 return !!bitwise_complement(storage, order);
987 }
988
b32b8144
FG
989 static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
990 {
991 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
992 {
993 __asm__ __volatile__
994 (
995 "lock; incl %[storage]\n\t"
996 : [storage] "+m" (storage)
997 :
998 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
999 );
1000 }
1001 else
1002 {
1003 __asm__ __volatile__
1004 (
1005 "lock; addl %[argument], %[storage]\n\t"
1006 : [storage] "+m" (storage)
1007 : [argument] "ir" (v)
1008 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1009 );
1010 }
1011 }
1012
1013 static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
1014 {
1015 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
1016 {
1017 __asm__ __volatile__
1018 (
1019 "lock; decl %[storage]\n\t"
1020 : [storage] "+m" (storage)
1021 :
1022 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1023 );
1024 }
1025 else
1026 {
1027 __asm__ __volatile__
1028 (
1029 "lock; subl %[argument], %[storage]\n\t"
1030 : [storage] "+m" (storage)
1031 : [argument] "ir" (v)
1032 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1033 );
1034 }
1035 }
1036
1037 static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
1038 {
1039 __asm__ __volatile__
1040 (
1041 "lock; negl %[storage]\n\t"
1042 : [storage] "+m" (storage)
1043 :
1044 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1045 );
1046 }
1047
1048 static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
1049 {
1050 __asm__ __volatile__
1051 (
1052 "lock; andl %[argument], %[storage]\n\t"
1053 : [storage] "+m" (storage)
1054 : [argument] "ir" (v)
1055 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1056 );
1057 }
1058
1059 static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
1060 {
1061 __asm__ __volatile__
1062 (
1063 "lock; orl %[argument], %[storage]\n\t"
1064 : [storage] "+m" (storage)
1065 : [argument] "ir" (v)
1066 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1067 );
1068 }
1069
1070 static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
1071 {
1072 __asm__ __volatile__
1073 (
1074 "lock; xorl %[argument], %[storage]\n\t"
1075 : [storage] "+m" (storage)
1076 : [argument] "ir" (v)
1077 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1078 );
1079 }
1080
1081 static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
1082 {
1083 __asm__ __volatile__
1084 (
1085 "lock; notl %[storage]\n\t"
1086 : [storage] "+m" (storage)
1087 :
1088 : "memory"
1089 );
1090 }
1091
1092 static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
1093 {
1094 bool res;
1095#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
1096 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
1097 {
1098 __asm__ __volatile__
1099 (
1100 "lock; incl %[storage]\n\t"
11fdf7f2 1101 : [storage] "+m" (storage), [result] "=@ccnz" (res)
b32b8144
FG
1102 :
1103 : "memory"
1104 );
1105 }
1106 else
1107 {
1108 __asm__ __volatile__
1109 (
1110 "lock; addl %[argument], %[storage]\n\t"
11fdf7f2 1111 : [storage] "+m" (storage), [result] "=@ccnz" (res)
b32b8144
FG
1112 : [argument] "ir" (v)
1113 : "memory"
1114 );
1115 }
1116#else
1117 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
1118 {
1119 __asm__ __volatile__
1120 (
1121 "lock; incl %[storage]\n\t"
11fdf7f2 1122 "setnz %[result]\n\t"
b32b8144
FG
1123 : [storage] "+m" (storage), [result] "=q" (res)
1124 :
1125 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1126 );
1127 }
1128 else
1129 {
1130 __asm__ __volatile__
1131 (
1132 "lock; addl %[argument], %[storage]\n\t"
11fdf7f2 1133 "setnz %[result]\n\t"
b32b8144
FG
1134 : [storage] "+m" (storage), [result] "=q" (res)
1135 : [argument] "ir" (v)
1136 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1137 );
1138 }
1139#endif
1140 return res;
1141 }
1142
1143 static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
1144 {
1145 bool res;
1146#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
1147 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
1148 {
1149 __asm__ __volatile__
1150 (
1151 "lock; decl %[storage]\n\t"
11fdf7f2 1152 : [storage] "+m" (storage), [result] "=@ccnz" (res)
b32b8144
FG
1153 :
1154 : "memory"
1155 );
1156 }
1157 else
1158 {
1159 __asm__ __volatile__
1160 (
1161 "lock; subl %[argument], %[storage]\n\t"
11fdf7f2 1162 : [storage] "+m" (storage), [result] "=@ccnz" (res)
b32b8144
FG
1163 : [argument] "ir" (v)
1164 : "memory"
1165 );
1166 }
1167#else
1168 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
1169 {
1170 __asm__ __volatile__
1171 (
1172 "lock; decl %[storage]\n\t"
11fdf7f2 1173 "setnz %[result]\n\t"
b32b8144
FG
1174 : [storage] "+m" (storage), [result] "=q" (res)
1175 :
1176 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1177 );
1178 }
1179 else
1180 {
1181 __asm__ __volatile__
1182 (
1183 "lock; subl %[argument], %[storage]\n\t"
11fdf7f2 1184 "setnz %[result]\n\t"
b32b8144
FG
1185 : [storage] "+m" (storage), [result] "=q" (res)
1186 : [argument] "ir" (v)
1187 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1188 );
1189 }
1190#endif
1191 return res;
1192 }
1193
1194 static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
1195 {
1196 bool res;
1197#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
1198 __asm__ __volatile__
1199 (
1200 "lock; andl %[argument], %[storage]\n\t"
11fdf7f2 1201 : [storage] "+m" (storage), [result] "=@ccnz" (res)
b32b8144
FG
1202 : [argument] "ir" (v)
1203 : "memory"
1204 );
1205#else
1206 __asm__ __volatile__
1207 (
1208 "lock; andl %[argument], %[storage]\n\t"
11fdf7f2 1209 "setnz %[result]\n\t"
b32b8144
FG
1210 : [storage] "+m" (storage), [result] "=q" (res)
1211 : [argument] "ir" (v)
1212 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1213 );
1214#endif
1215 return res;
1216 }
1217
1218 static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
1219 {
1220 bool res;
1221#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
1222 __asm__ __volatile__
1223 (
1224 "lock; orl %[argument], %[storage]\n\t"
11fdf7f2 1225 : [storage] "+m" (storage), [result] "=@ccnz" (res)
b32b8144
FG
1226 : [argument] "ir" (v)
1227 : "memory"
1228 );
1229#else
1230 __asm__ __volatile__
1231 (
1232 "lock; orl %[argument], %[storage]\n\t"
11fdf7f2 1233 "setnz %[result]\n\t"
b32b8144
FG
1234 : [storage] "+m" (storage), [result] "=q" (res)
1235 : [argument] "ir" (v)
1236 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1237 );
1238#endif
1239 return res;
1240 }
1241
1242 static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
1243 {
1244 bool res;
1245#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
1246 __asm__ __volatile__
1247 (
1248 "lock; xorl %[argument], %[storage]\n\t"
11fdf7f2 1249 : [storage] "+m" (storage), [result] "=@ccnz" (res)
b32b8144
FG
1250 : [argument] "ir" (v)
1251 : "memory"
1252 );
1253#else
1254 __asm__ __volatile__
1255 (
1256 "lock; xorl %[argument], %[storage]\n\t"
11fdf7f2 1257 "setnz %[result]\n\t"
b32b8144
FG
1258 : [storage] "+m" (storage), [result] "=q" (res)
1259 : [argument] "ir" (v)
1260 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1261 );
1262#endif
1263 return res;
1264 }
1265};
1266
1267#if defined(__x86_64__)
1268
1269template< typename Base, bool Signed >
11fdf7f2 1270struct extra_operations< Base, 8u, Signed, true > :
b32b8144
FG
1271 public gcc_x86_extra_operations_common< Base >
1272{
1273 typedef gcc_x86_extra_operations_common< Base > base_type;
1274 typedef typename base_type::storage_type storage_type;
1275
11fdf7f2 1276#define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, original, result)\
b32b8144
FG
1277 __asm__ __volatile__\
1278 (\
1279 ".align 16\n\t"\
11fdf7f2
TL
1280 "1: mov %[orig], %[res]\n\t"\
1281 op " %[res]\n\t"\
1282 "lock; cmpxchgq %[res], %[storage]\n\t"\
b32b8144 1283 "jne 1b"\
11fdf7f2 1284 : [orig] "+a" (original), [storage] "+m" (storage), [res] "=&r" (result)\
b32b8144
FG
1285 : \
1286 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\
1287 )
1288
1289 static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
1290 {
11fdf7f2
TL
1291 storage_type original = storage;
1292 storage_type result;
1293 BOOST_ATOMIC_DETAIL_CAS_LOOP("negq", original, result);
1294 return original;
b32b8144
FG
1295 }
1296
1297 static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
1298 {
11fdf7f2
TL
1299 storage_type original = storage;
1300 storage_type result;
1301 BOOST_ATOMIC_DETAIL_CAS_LOOP("notq", original, result);
1302 return original;
1303 }
1304
1305 static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
1306 {
1307 storage_type original = storage;
1308 storage_type result;
1309 BOOST_ATOMIC_DETAIL_CAS_LOOP("negq", original, result);
1310 return result;
1311 }
1312
1313 static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
1314 {
1315 storage_type original = storage;
1316 storage_type result;
1317 BOOST_ATOMIC_DETAIL_CAS_LOOP("notq", original, result);
1318 return result;
1319 }
1320
1321#undef BOOST_ATOMIC_DETAIL_CAS_LOOP
1322
1323#define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, argument, original, result)\
1324 __asm__ __volatile__\
1325 (\
1326 ".align 16\n\t"\
1327 "1: mov %[arg], %[res]\n\t"\
1328 op " %%rax, %[res]\n\t"\
1329 "lock; cmpxchgq %[res], %[storage]\n\t"\
1330 "jne 1b"\
1331 : [orig] "+a" (original), [storage] "+m" (storage), [res] "=&r" (result)\
1332 : [arg] "r" (argument)\
1333 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\
1334 )
1335
1336 static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
1337 {
1338 storage_type original = storage;
1339 storage_type result;
1340 BOOST_ATOMIC_DETAIL_CAS_LOOP("andq", v, original, result);
1341 return static_cast< storage_type >(result);
1342 }
1343
1344 static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
1345 {
1346 storage_type original = storage;
1347 storage_type result;
1348 BOOST_ATOMIC_DETAIL_CAS_LOOP("orq", v, original, result);
1349 return static_cast< storage_type >(result);
1350 }
1351
1352 static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
1353 {
1354 storage_type original = storage;
1355 storage_type result;
1356 BOOST_ATOMIC_DETAIL_CAS_LOOP("xorq", v, original, result);
1357 return static_cast< storage_type >(result);
b32b8144
FG
1358 }
1359
1360#undef BOOST_ATOMIC_DETAIL_CAS_LOOP
1361
11fdf7f2
TL
1362 static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
1363 {
1364 return !!negate(storage, order);
1365 }
1366
1367 static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
1368 {
1369 return !!bitwise_complement(storage, order);
1370 }
1371
b32b8144
FG
1372 static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
1373 {
1374 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
1375 {
1376 __asm__ __volatile__
1377 (
1378 "lock; incq %[storage]\n\t"
1379 : [storage] "+m" (storage)
1380 :
1381 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1382 );
1383 }
1384 else
1385 {
1386 __asm__ __volatile__
1387 (
1388 "lock; addq %[argument], %[storage]\n\t"
1389 : [storage] "+m" (storage)
1390 : [argument] "er" (v)
1391 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1392 );
1393 }
1394 }
1395
1396 static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
1397 {
1398 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
1399 {
1400 __asm__ __volatile__
1401 (
1402 "lock; decq %[storage]\n\t"
1403 : [storage] "+m" (storage)
1404 :
1405 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1406 );
1407 }
1408 else
1409 {
1410 __asm__ __volatile__
1411 (
1412 "lock; subq %[argument], %[storage]\n\t"
1413 : [storage] "+m" (storage)
1414 : [argument] "er" (v)
1415 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1416 );
1417 }
1418 }
1419
1420 static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
1421 {
1422 __asm__ __volatile__
1423 (
1424 "lock; negq %[storage]\n\t"
1425 : [storage] "+m" (storage)
1426 :
1427 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1428 );
1429 }
1430
1431 static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
1432 {
1433 __asm__ __volatile__
1434 (
1435 "lock; andq %[argument], %[storage]\n\t"
1436 : [storage] "+m" (storage)
1437 : [argument] "er" (v)
1438 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1439 );
1440 }
1441
1442 static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
1443 {
1444 __asm__ __volatile__
1445 (
1446 "lock; orq %[argument], %[storage]\n\t"
1447 : [storage] "+m" (storage)
1448 : [argument] "er" (v)
1449 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1450 );
1451 }
1452
1453 static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
1454 {
1455 __asm__ __volatile__
1456 (
1457 "lock; xorq %[argument], %[storage]\n\t"
1458 : [storage] "+m" (storage)
1459 : [argument] "er" (v)
1460 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1461 );
1462 }
1463
1464 static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
1465 {
1466 __asm__ __volatile__
1467 (
1468 "lock; notq %[storage]\n\t"
1469 : [storage] "+m" (storage)
1470 :
1471 : "memory"
1472 );
1473 }
1474
1475 static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
1476 {
1477 bool res;
1478#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
1479 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
1480 {
1481 __asm__ __volatile__
1482 (
1483 "lock; incq %[storage]\n\t"
11fdf7f2 1484 : [storage] "+m" (storage), [result] "=@ccnz" (res)
b32b8144
FG
1485 :
1486 : "memory"
1487 );
1488 }
1489 else
1490 {
1491 __asm__ __volatile__
1492 (
1493 "lock; addq %[argument], %[storage]\n\t"
11fdf7f2 1494 : [storage] "+m" (storage), [result] "=@ccnz" (res)
b32b8144
FG
1495 : [argument] "er" (v)
1496 : "memory"
1497 );
1498 }
1499#else
1500 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
1501 {
1502 __asm__ __volatile__
1503 (
1504 "lock; incq %[storage]\n\t"
11fdf7f2 1505 "setnz %[result]\n\t"
b32b8144
FG
1506 : [storage] "+m" (storage), [result] "=q" (res)
1507 :
1508 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1509 );
1510 }
1511 else
1512 {
1513 __asm__ __volatile__
1514 (
1515 "lock; addq %[argument], %[storage]\n\t"
11fdf7f2 1516 "setnz %[result]\n\t"
b32b8144
FG
1517 : [storage] "+m" (storage), [result] "=q" (res)
1518 : [argument] "er" (v)
1519 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1520 );
1521 }
1522#endif
1523 return res;
1524 }
1525
1526 static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
1527 {
1528 bool res;
1529#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
1530 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
1531 {
1532 __asm__ __volatile__
1533 (
1534 "lock; decq %[storage]\n\t"
11fdf7f2 1535 : [storage] "+m" (storage), [result] "=@ccnz" (res)
b32b8144
FG
1536 :
1537 : "memory"
1538 );
1539 }
1540 else
1541 {
1542 __asm__ __volatile__
1543 (
1544 "lock; subq %[argument], %[storage]\n\t"
11fdf7f2 1545 : [storage] "+m" (storage), [result] "=@ccnz" (res)
b32b8144
FG
1546 : [argument] "er" (v)
1547 : "memory"
1548 );
1549 }
1550#else
1551 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
1552 {
1553 __asm__ __volatile__
1554 (
1555 "lock; decq %[storage]\n\t"
11fdf7f2 1556 "setnz %[result]\n\t"
b32b8144
FG
1557 : [storage] "+m" (storage), [result] "=q" (res)
1558 :
1559 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1560 );
1561 }
1562 else
1563 {
1564 __asm__ __volatile__
1565 (
1566 "lock; subq %[argument], %[storage]\n\t"
11fdf7f2 1567 "setnz %[result]\n\t"
b32b8144
FG
1568 : [storage] "+m" (storage), [result] "=q" (res)
1569 : [argument] "er" (v)
1570 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1571 );
1572 }
1573#endif
1574 return res;
1575 }
1576
1577 static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
1578 {
1579 bool res;
1580#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
1581 __asm__ __volatile__
1582 (
1583 "lock; andq %[argument], %[storage]\n\t"
11fdf7f2 1584 : [storage] "+m" (storage), [result] "=@ccnz" (res)
b32b8144
FG
1585 : [argument] "er" (v)
1586 : "memory"
1587 );
1588#else
1589 __asm__ __volatile__
1590 (
1591 "lock; andq %[argument], %[storage]\n\t"
11fdf7f2 1592 "setnz %[result]\n\t"
b32b8144
FG
1593 : [storage] "+m" (storage), [result] "=q" (res)
1594 : [argument] "er" (v)
1595 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1596 );
1597#endif
1598 return res;
1599 }
1600
1601 static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
1602 {
1603 bool res;
1604#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
1605 __asm__ __volatile__
1606 (
1607 "lock; orq %[argument], %[storage]\n\t"
11fdf7f2 1608 : [storage] "+m" (storage), [result] "=@ccnz" (res)
b32b8144
FG
1609 : [argument] "er" (v)
1610 : "memory"
1611 );
1612#else
1613 __asm__ __volatile__
1614 (
1615 "lock; orq %[argument], %[storage]\n\t"
11fdf7f2 1616 "setnz %[result]\n\t"
b32b8144
FG
1617 : [storage] "+m" (storage), [result] "=q" (res)
1618 : [argument] "er" (v)
1619 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1620 );
1621#endif
1622 return res;
1623 }
1624
1625 static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
1626 {
1627 bool res;
1628#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
1629 __asm__ __volatile__
1630 (
1631 "lock; xorq %[argument], %[storage]\n\t"
11fdf7f2 1632 : [storage] "+m" (storage), [result] "=@ccnz" (res)
b32b8144
FG
1633 : [argument] "er" (v)
1634 : "memory"
1635 );
1636#else
1637 __asm__ __volatile__
1638 (
1639 "lock; xorq %[argument], %[storage]\n\t"
11fdf7f2 1640 "setnz %[result]\n\t"
b32b8144
FG
1641 : [storage] "+m" (storage), [result] "=q" (res)
1642 : [argument] "er" (v)
1643 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
1644 );
1645#endif
1646 return res;
1647 }
1648};
1649
1650#endif // defined(__x86_64__)
1651
1652} // namespace detail
1653} // namespace atomics
1654} // namespace boost
1655
1656#endif // BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_X86_HPP_INCLUDED_