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)
6 * Copyright (c) 2009 Helge Bahmann
7 * Copyright (c) 2012 Tim Blechmann
8 * Copyright (c) 2014 Andrey Semashev
11 * \file atomic/detail/ops_gcc_x86_dcas.hpp
13 * This header contains implementation of the double-width CAS primitive for x86.
16 #ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_X86_DCAS_HPP_INCLUDED_
17 #define BOOST_ATOMIC_DETAIL_OPS_GCC_X86_DCAS_HPP_INCLUDED_
19 #include <boost/cstdint.hpp>
20 #include <boost/memory_order.hpp>
21 #include <boost/atomic/detail/config.hpp>
22 #include <boost/atomic/detail/storage_type.hpp>
23 #include <boost/atomic/capabilities.hpp>
25 #ifdef BOOST_HAS_PRAGMA_ONCE
33 #if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B)
35 template< bool Signed >
38 typedef typename make_storage_type< 8u, Signed >::type storage_type;
39 typedef typename make_storage_type< 8u, Signed >::aligned aligned_storage_type;
41 static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true;
43 static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
45 if ((((uint32_t)&storage) & 0x00000007) == 0)
51 "vmovq %1, %%xmm4\n\t"
52 "vmovq %%xmm4, %0\n\t"
74 #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
76 uint32_t v_lo = (uint32_t)v;
80 "movl %%ebx, %[scratch]\n\t"
81 "movl %[value_lo], %%ebx\n\t"
82 "movl %[dest], %%eax\n\t"
83 "movl 4+%[dest], %%edx\n\t"
85 "1: lock; cmpxchg8b %[dest]\n\t"
87 "movl %[scratch], %%ebx\n\t"
88 : [scratch] "=m" (scratch), [dest] "=o" (storage), [value_lo] "+a" (v_lo)
89 : "c" ((uint32_t)(v >> 32))
90 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "edx", "memory"
92 #else // defined(__PIC__)
95 "movl %[dest], %%eax\n\t"
96 "movl 4+%[dest], %%edx\n\t"
98 "1: lock; cmpxchg8b %[dest]\n\t"
100 : [dest] "=o" (storage)
101 : [value_lo] "b" ((uint32_t)v), "c" ((uint32_t)(v >> 32))
102 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "eax", "edx", "memory"
104 #endif // defined(__PIC__)
105 #else // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
107 uint32_t v_lo = (uint32_t)v;
111 "movl %%ebx, %[scratch]\n\t"
112 "movl %[value_lo], %%ebx\n\t"
113 "movl 0(%[dest]), %%eax\n\t"
114 "movl 4(%[dest]), %%edx\n\t"
116 "1: lock; cmpxchg8b 0(%[dest])\n\t"
118 "movl %[scratch], %%ebx\n\t"
119 #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_CONSTRAINT_ALTERNATIVES)
120 : [scratch] "=m,m" (scratch), [value_lo] "+a,a" (v_lo)
121 : "c,c" ((uint32_t)(v >> 32)), [dest] "D,S" (&storage)
123 : [scratch] "=m" (scratch), [value_lo] "+a" (v_lo)
124 : "c" ((uint32_t)(v >> 32)), [dest] "D" (&storage)
126 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "edx", "memory"
128 #else // defined(__PIC__)
131 "movl 0(%[dest]), %%eax\n\t"
132 "movl 4(%[dest]), %%edx\n\t"
134 "1: lock; cmpxchg8b 0(%[dest])\n\t"
137 #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_CONSTRAINT_ALTERNATIVES)
138 : [value_lo] "b,b" ((uint32_t)v), "c,c" ((uint32_t)(v >> 32)), [dest] "D,S" (&storage)
140 : [value_lo] "b" ((uint32_t)v), "c" ((uint32_t)(v >> 32)), [dest] "D" (&storage)
142 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "eax", "edx", "memory"
144 #endif // defined(__PIC__)
145 #endif // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
149 static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order) BOOST_NOEXCEPT
153 if ((((uint32_t)&storage) & 0x00000007) == 0)
155 #if defined(__SSE2__)
159 "vmovq %1, %%xmm4\n\t"
160 "vmovq %%xmm4, %0\n\t"
162 "movq %1, %%xmm4\n\t"
163 "movq %%xmm4, %0\n\t"
182 #if defined(__clang__)
183 // Clang cannot allocate eax:edx register pairs but it has sync intrinsics
184 value = __sync_val_compare_and_swap(&storage, (storage_type)0, (storage_type)0);
186 // We don't care for comparison result here; the previous value will be stored into value anyway.
187 // Also we don't care for ebx and ecx values, they just have to be equal to eax and edx before cmpxchg8b.
190 "movl %%ebx, %%eax\n\t"
191 "movl %%ecx, %%edx\n\t"
192 "lock; cmpxchg8b %[storage]\n\t"
194 : [storage] "m" (storage)
195 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
203 static BOOST_FORCEINLINE bool compare_exchange_strong(
204 storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT
206 #if defined(__clang__)
208 // Clang cannot allocate eax:edx register pairs but it has sync intrinsics
209 storage_type old_expected = expected;
210 expected = __sync_val_compare_and_swap(&storage, old_expected, desired);
211 return expected == old_expected;
213 #elif defined(__PIC__)
215 // Make sure ebx is saved and restored properly in case
216 // of position independent code. To make this work
217 // setup register constraints such that ebx can not be
218 // used by accident e.g. as base address for the variable
219 // to be modified. Accessing "scratch" should always be okay,
220 // as it can only be placed on the stack (and therefore
221 // accessed through ebp or esp only).
223 // In theory, could push/pop ebx onto/off the stack, but movs
224 // to a prepared stack slot turn out to be faster.
228 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
231 "movl %%ebx, %[scratch]\n\t"
232 "movl %[desired_lo], %%ebx\n\t"
233 "lock; cmpxchg8b (%[dest])\n\t"
234 "movl %[scratch], %%ebx\n\t"
235 : "+A" (expected), [scratch] "=m" (scratch), [success] "=@ccz" (success)
236 : [desired_lo] "Sm" ((uint32_t)desired), "c" ((uint32_t)(desired >> 32)), [dest] "D" (&storage)
237 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
239 #else // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
242 "movl %%ebx, %[scratch]\n\t"
243 "movl %[desired_lo], %%ebx\n\t"
244 "lock; cmpxchg8b (%[dest])\n\t"
245 "movl %[scratch], %%ebx\n\t"
246 "sete %[success]\n\t"
247 #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_CONSTRAINT_ALTERNATIVES)
248 : "+A,A,A,A,A,A" (expected), [scratch] "=m,m,m,m,m,m" (scratch), [success] "=q,m,q,m,q,m" (success)
249 : [desired_lo] "S,S,D,D,m,m" ((uint32_t)desired), "c,c,c,c,c,c" ((uint32_t)(desired >> 32)), [dest] "D,D,S,S,D,D" (&storage)
251 : "+A" (expected), [scratch] "=m" (scratch), [success] "=q" (success)
252 : [desired_lo] "S" ((uint32_t)desired), "c" ((uint32_t)(desired >> 32)), [dest] "D" (&storage)
254 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
256 #endif // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
260 #else // defined(__PIC__)
263 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
266 "lock; cmpxchg8b %[dest]\n\t"
267 : "+A" (expected), [dest] "+m" (storage), [success] "=@ccz" (success)
268 : "b" ((uint32_t)desired), "c" ((uint32_t)(desired >> 32))
269 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
271 #else // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
274 "lock; cmpxchg8b %[dest]\n\t"
275 "sete %[success]\n\t"
276 #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_CONSTRAINT_ALTERNATIVES)
277 : "+A,A" (expected), [dest] "+m,m" (storage), [success] "=q,m" (success)
278 : "b,b" ((uint32_t)desired), "c,c" ((uint32_t)(desired >> 32))
280 : "+A" (expected), [dest] "+m" (storage), [success] "=q" (success)
281 : "b" ((uint32_t)desired), "c" ((uint32_t)(desired >> 32))
283 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
285 #endif // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
289 #endif // defined(__PIC__)
292 static BOOST_FORCEINLINE bool compare_exchange_weak(
293 storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
295 return compare_exchange_strong(storage, expected, desired, success_order, failure_order);
298 static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
300 #if defined(__clang__)
301 // Clang cannot allocate eax:edx register pairs but it has sync intrinsics
302 storage_type old_val = storage;
305 storage_type val = __sync_val_compare_and_swap(&storage, old_val, v);
310 #elif !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
315 "movl %%ebx, %[scratch]\n\t"
316 "movl %%eax, %%ebx\n\t"
317 "movl %%edx, %%ecx\n\t"
318 "movl %[dest], %%eax\n\t"
319 "movl 4+%[dest], %%edx\n\t"
321 "1: lock; cmpxchg8b %[dest]\n\t"
323 "movl %[scratch], %%ebx\n\t"
324 : "+A" (v), [scratch] "=m" (scratch), [dest] "+o" (storage)
326 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "ecx", "memory"
329 #else // defined(__PIC__)
332 "movl %[dest], %%eax\n\t"
333 "movl 4+%[dest], %%edx\n\t"
335 "1: lock; cmpxchg8b %[dest]\n\t"
337 : "=A" (v), [dest] "+o" (storage)
338 : "b" ((uint32_t)v), "c" ((uint32_t)(v >> 32))
339 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
342 #endif // defined(__PIC__)
343 #else // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
348 "movl %%ebx, %[scratch]\n\t"
349 "movl %%eax, %%ebx\n\t"
350 "movl %%edx, %%ecx\n\t"
351 "movl 0(%[dest]), %%eax\n\t"
352 "movl 4(%[dest]), %%edx\n\t"
354 "1: lock; cmpxchg8b 0(%[dest])\n\t"
356 "movl %[scratch], %%ebx\n\t"
357 #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_CONSTRAINT_ALTERNATIVES)
358 : "+A,A" (v), [scratch] "=m,m" (scratch)
359 : [dest] "D,S" (&storage)
361 : "+A" (v), [scratch] "=m" (scratch)
362 : [dest] "D" (&storage)
364 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "ecx", "memory"
367 #else // defined(__PIC__)
370 "movl 0(%[dest]), %%eax\n\t"
371 "movl 4(%[dest]), %%edx\n\t"
373 "1: lock; cmpxchg8b 0(%[dest])\n\t"
375 #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_CONSTRAINT_ALTERNATIVES)
377 : "b,b" ((uint32_t)v), "c,c" ((uint32_t)(v >> 32)), [dest] "D,S" (&storage)
380 : "b" ((uint32_t)v), "c" ((uint32_t)(v >> 32)), [dest] "D" (&storage)
382 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
385 #endif // defined(__PIC__)
390 #endif // defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B)
392 #if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B)
394 template< bool Signed >
395 struct gcc_dcas_x86_64
397 typedef typename make_storage_type< 16u, Signed >::type storage_type;
398 typedef typename make_storage_type< 16u, Signed >::aligned aligned_storage_type;
400 static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true;
402 static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
404 uint64_t const* p_value = (uint64_t const*)&v;
405 const uint64_t v_lo = p_value[0], v_hi = p_value[1];
406 #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
409 "movq %[dest], %%rax\n\t"
410 "movq 8+%[dest], %%rdx\n\t"
412 "1: lock; cmpxchg16b %[dest]\n\t"
414 : [dest] "=o" (storage)
415 : "b" (v_lo), "c" (v_hi)
416 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "rax", "rdx", "memory"
418 #else // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
421 "movq 0(%[dest]), %%rax\n\t"
422 "movq 8(%[dest]), %%rdx\n\t"
424 "1: lock; cmpxchg16b 0(%[dest])\n\t"
427 : "b" (v_lo), "c" (v_hi), [dest] "r" (&storage)
428 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "rax", "rdx", "memory"
430 #endif // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
433 static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order) BOOST_NOEXCEPT
435 #if defined(__clang__)
436 // Clang cannot allocate rax:rdx register pairs but it has sync intrinsics
437 storage_type value = storage_type();
438 return __sync_val_compare_and_swap(&storage, value, value);
439 #elif defined(BOOST_ATOMIC_DETAIL_NO_ASM_RAX_RDX_PAIRS)
440 // GCC 4.4 can't allocate rax:rdx register pair either but it also doesn't support 128-bit __sync_val_compare_and_swap
443 // We don't care for comparison result here; the previous value will be stored into value anyway.
444 // Also we don't care for rbx and rcx values, they just have to be equal to rax and rdx before cmpxchg16b.
445 #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
448 "movq %%rbx, %%rax\n\t"
449 "movq %%rcx, %%rdx\n\t"
450 "lock; cmpxchg16b %[storage]\n\t"
451 "movq %%rax, %[value]\n\t"
452 "movq %%rdx, 8+%[value]\n\t"
453 : [value] "=o" (value)
454 : [storage] "m" (storage)
455 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory", "rax", "rdx"
457 #else // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
460 "movq %%rbx, %%rax\n\t"
461 "movq %%rcx, %%rdx\n\t"
462 "lock; cmpxchg16b %[storage]\n\t"
463 "movq %%rax, 0(%[value])\n\t"
464 "movq %%rdx, 8(%[value])\n\t"
466 : [storage] "m" (storage), [value] "r" (&value)
467 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory", "rax", "rdx"
469 #endif // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
472 #else // defined(BOOST_ATOMIC_DETAIL_NO_ASM_RAX_RDX_PAIRS)
475 // We don't care for comparison result here; the previous value will be stored into value anyway.
476 // Also we don't care for rbx and rcx values, they just have to be equal to rax and rdx before cmpxchg16b.
479 "movq %%rbx, %%rax\n\t"
480 "movq %%rcx, %%rdx\n\t"
481 "lock; cmpxchg16b %[storage]\n\t"
483 : [storage] "m" (storage)
484 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
491 static BOOST_FORCEINLINE bool compare_exchange_strong(
492 storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT
494 #if defined(__clang__)
496 // Clang cannot allocate rax:rdx register pairs but it has sync intrinsics
497 storage_type old_expected = expected;
498 expected = __sync_val_compare_and_swap(&storage, old_expected, desired);
499 return expected == old_expected;
501 #elif defined(BOOST_ATOMIC_DETAIL_NO_ASM_RAX_RDX_PAIRS)
503 // GCC 4.4 can't allocate rax:rdx register pair either but it also doesn't support 128-bit __sync_val_compare_and_swap
504 uint64_t const* p_desired = (uint64_t const*)&desired;
505 const uint64_t desired_lo = p_desired[0], desired_hi = p_desired[1];
507 #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
510 "movq %[expected], %%rax\n\t"
511 "movq 8+%[expected], %%rdx\n\t"
512 "lock; cmpxchg16b %[dest]\n\t"
513 "sete %[success]\n\t"
514 "movq %%rax, %[expected]\n\t"
515 "movq %%rdx, 8+%[expected]\n\t"
516 : [dest] "+m" (storage), [expected] "+o" (expected), [success] "=q" (success)
517 : "b" (desired_lo), "c" (desired_hi)
518 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory", "rax", "rdx"
520 #else // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
523 "movq 0(%[expected]), %%rax\n\t"
524 "movq 8(%[expected]), %%rdx\n\t"
525 "lock; cmpxchg16b %[dest]\n\t"
526 "sete %[success]\n\t"
527 "movq %%rax, 0(%[expected])\n\t"
528 "movq %%rdx, 8(%[expected])\n\t"
529 : [dest] "+m" (storage), [success] "=q" (success)
530 : "b" (desired_lo), "c" (desired_hi), [expected] "r" (&expected)
531 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory", "rax", "rdx"
533 #endif // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
537 #else // defined(BOOST_ATOMIC_DETAIL_NO_ASM_RAX_RDX_PAIRS)
539 uint64_t const* p_desired = (uint64_t const*)&desired;
540 const uint64_t desired_lo = p_desired[0], desired_hi = p_desired[1];
542 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
545 "lock; cmpxchg16b %[dest]\n\t"
546 : "+A" (expected), [dest] "+m" (storage), [success] "=@ccz" (success)
547 : "b" (desired_lo), "c" (desired_hi)
548 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
550 #else // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
553 "lock; cmpxchg16b %[dest]\n\t"
554 "sete %[success]\n\t"
555 #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_CONSTRAINT_ALTERNATIVES)
556 : "+A,A" (expected), [dest] "+m,m" (storage), [success] "=q,m" (success)
557 : "b,b" (desired_lo), "c,c" (desired_hi)
559 : "+A" (expected), [dest] "+m" (storage), [success] "=q" (success)
560 : "b" (desired_lo), "c" (desired_hi)
562 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
564 #endif // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
568 #endif // defined(BOOST_ATOMIC_DETAIL_NO_ASM_RAX_RDX_PAIRS)
571 static BOOST_FORCEINLINE bool compare_exchange_weak(
572 storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
574 return compare_exchange_strong(storage, expected, desired, success_order, failure_order);
577 static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
579 #if defined(__clang__)
580 // Clang cannot allocate eax:edx register pairs but it has sync intrinsics
581 storage_type old_val = storage;
584 storage_type val = __sync_val_compare_and_swap(&storage, old_val, v);
589 #elif defined(BOOST_ATOMIC_DETAIL_NO_ASM_RAX_RDX_PAIRS)
590 // GCC 4.4 can't allocate rax:rdx register pair either but it also doesn't support 128-bit __sync_val_compare_and_swap
591 storage_type old_value;
592 uint64_t const* p_value = (uint64_t const*)&v;
593 const uint64_t v_lo = p_value[0], v_hi = p_value[1];
594 #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
597 "movq %[dest], %%rax\n\t"
598 "movq 8+%[dest], %%rdx\n\t"
600 "1: lock; cmpxchg16b %[dest]\n\t"
602 "movq %%rax, %[old_value]\n\t"
603 "movq %%rdx, 8+%[old_value]\n\t"
604 : [dest] "+o" (storage), [old_value] "=o" (old_value)
605 : "b" (v_lo), "c" (v_hi)
606 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory", "rax", "rdx"
608 #else // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
611 "movq 0(%[dest]), %%rax\n\t"
612 "movq 8(%[dest]), %%rdx\n\t"
614 "1: lock; cmpxchg16b 0(%[dest])\n\t"
616 "movq %%rax, 0(%[old_value])\n\t"
617 "movq %%rdx, 8(%[old_value])\n\t"
619 : "b" (v_lo), "c" (v_hi), [dest] "r" (&storage), [old_value] "r" (&old_value)
620 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory", "rax", "rdx"
622 #endif // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
625 #else // defined(BOOST_ATOMIC_DETAIL_NO_ASM_RAX_RDX_PAIRS)
626 uint64_t const* p_value = (uint64_t const*)&v;
627 const uint64_t v_lo = p_value[0], v_hi = p_value[1];
628 #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
631 "movq %[dest], %%rax\n\t"
632 "movq 8+%[dest], %%rdx\n\t"
634 "1: lock; cmpxchg16b %[dest]\n\t"
636 : "=&A" (v), [dest] "+o" (storage)
637 : "b" (v_lo), "c" (v_hi)
638 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
640 #else // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
643 "movq 0(%[dest]), %%rax\n\t"
644 "movq 8(%[dest]), %%rdx\n\t"
646 "1: lock; cmpxchg16b 0(%[dest])\n\t"
649 : "b" (v_lo), "c" (v_hi), [dest] "r" (&storage)
650 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
652 #endif // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
659 #endif // defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B)
661 } // namespace detail
662 } // namespace atomics
665 #endif // BOOST_ATOMIC_DETAIL_OPS_GCC_X86_DCAS_HPP_INCLUDED_