BVB Source Codes

mars Show ops_gcc_x86_dcas.hpp Source code

Return Download mars: download ops_gcc_x86_dcas.hpp Source code - Download mars Source code - Type:.hpp
  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) 2009 Helge Bahmann
  7.  * Copyright (c) 2012 Tim Blechmann
  8.  * Copyright (c) 2014 Andrey Semashev
  9.  */
  10. /*!
  11.  * \file   atomic/detail/ops_gcc_x86_dcas.hpp
  12.  *
  13.  * This header contains implementation of the double-width CAS primitive for x86.
  14.  */
  15.  
  16. #ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_X86_DCAS_HPP_INCLUDED_
  17. #define BOOST_ATOMIC_DETAIL_OPS_GCC_X86_DCAS_HPP_INCLUDED_
  18.  
  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>
  24.  
  25. #ifdef BOOST_HAS_PRAGMA_ONCE
  26. #pragma once
  27. #endif
  28.  
  29. namespace mars_boost {} namespace boost = mars_boost; namespace mars_boost {
  30. namespace atomics {
  31. namespace detail {
  32.  
  33. #if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B)
  34.  
  35. template< bool Signed >
  36. struct gcc_dcas_x86
  37. {
  38.     typedef typename make_storage_type< 8u, Signed >::type storage_type;
  39.     typedef typename make_storage_type< 8u, Signed >::aligned aligned_storage_type;
  40.  
  41.     static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
  42.     {
  43.         if ((((uint32_t)&storage) & 0x00000007) == 0)
  44.         {
  45. #if defined(__SSE2__)
  46.             __asm__ __volatile__
  47.             (
  48. #if defined(__AVX__)
  49.                 "vmovq %1, %%xmm4\n\t"
  50.                 "vmovq %%xmm4, %0\n\t"
  51. #else
  52.                 "movq %1, %%xmm4\n\t"
  53.                 "movq %%xmm4, %0\n\t"
  54. #endif
  55.                 : "=m" (storage)
  56.                 : "m" (v)
  57.                 : "memory", "xmm4"
  58.             );
  59. #else
  60.             __asm__ __volatile__
  61.             (
  62.                 "fildll %1\n\t"
  63.                 "fistpll %0\n\t"
  64.                 : "=m" (storage)
  65.                 : "m" (v)
  66.                 : "memory"
  67.             );
  68. #endif
  69.         }
  70.         else
  71.         {
  72. #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
  73. #if defined(__PIC__)
  74.             uint32_t scratch;
  75.             __asm__ __volatile__
  76.             (
  77.                 "movl %%ebx, %[scratch]\n\t"
  78.                 "movl %[value_lo], %%ebx\n\t"
  79.                 "movl %[dest], %%eax\n\t"
  80.                 "movl 4+%[dest], %%edx\n\t"
  81.                 ".align 16\n\t"
  82.                 "1: lock; cmpxchg8b %[dest]\n\t"
  83.                 "jne 1b\n\t"
  84.                 "movl %[scratch], %%ebx\n\t"
  85.                 : [scratch] "=m" (scratch), [dest] "=o" (storage)
  86.                 : [value_lo] "a" ((uint32_t)v), "c" ((uint32_t)(v >> 32))
  87.                 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "edx", "memory"
  88.             );
  89. #else // defined(__PIC__)
  90.             __asm__ __volatile__
  91.             (
  92.                 "movl %[dest], %%eax\n\t"
  93.                 "movl 4+%[dest], %%edx\n\t"
  94.                 ".align 16\n\t"
  95.                 "1: lock; cmpxchg8b %[dest]\n\t"
  96.                 "jne 1b\n\t"
  97.                 : [dest] "=o" (storage)
  98.                 : [value_lo] "b" ((uint32_t)v), "c" ((uint32_t)(v >> 32))
  99.                 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "eax", "edx", "memory"
  100.             );
  101. #endif // defined(__PIC__)
  102. #else // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
  103. #if defined(__PIC__)
  104.             uint32_t scratch;
  105.             __asm__ __volatile__
  106.             (
  107.                 "movl %%ebx, %[scratch]\n\t"
  108.                 "movl %[value_lo], %%ebx\n\t"
  109.                 "movl 0(%[dest]), %%eax\n\t"
  110.                 "movl 4(%[dest]), %%edx\n\t"
  111.                 ".align 16\n\t"
  112.                 "1: lock; cmpxchg8b 0(%[dest])\n\t"
  113.                 "jne 1b\n\t"
  114.                 "movl %[scratch], %%ebx\n\t"
  115. #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_CONSTRAINT_ALTERNATIVES)
  116.                 : [scratch] "=m,m" (scratch)
  117.                 : [value_lo] "a,a" ((uint32_t)v), "c,c" ((uint32_t)(v >> 32)), [dest] "D,S" (&storage)
  118. #else
  119.                 : [scratch] "=m" (scratch)
  120.                 : [value_lo] "a" ((uint32_t)v), "c" ((uint32_t)(v >> 32)), [dest] "D" (&storage)
  121. #endif
  122.                 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "edx", "memory"
  123.             );
  124. #else // defined(__PIC__)
  125.             __asm__ __volatile__
  126.             (
  127.                 "movl 0(%[dest]), %%eax\n\t"
  128.                 "movl 4(%[dest]), %%edx\n\t"
  129.                 ".align 16\n\t"
  130.                 "1: lock; cmpxchg8b 0(%[dest])\n\t"
  131.                 "jne 1b\n\t"
  132.                 :
  133. #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_CONSTRAINT_ALTERNATIVES)
  134.                 : [value_lo] "b,b" ((uint32_t)v), "c,c" ((uint32_t)(v >> 32)), [dest] "D,S" (&storage)
  135. #else
  136.                 : [value_lo] "b" ((uint32_t)v), "c" ((uint32_t)(v >> 32)), [dest] "D" (&storage)
  137. #endif
  138.                 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "eax", "edx", "memory"
  139.             );
  140. #endif // defined(__PIC__)
  141. #endif // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
  142.         }
  143.     }
  144.  
  145.     static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order) BOOST_NOEXCEPT
  146.     {
  147.         storage_type value;
  148.  
  149.         if ((((uint32_t)&storage) & 0x00000007) == 0)
  150.         {
  151. #if defined(__SSE2__)
  152.             __asm__ __volatile__
  153.             (
  154. #if defined(__AVX__)
  155.                 "vmovq %1, %%xmm4\n\t"
  156.                 "vmovq %%xmm4, %0\n\t"
  157. #else
  158.                 "movq %1, %%xmm4\n\t"
  159.                 "movq %%xmm4, %0\n\t"
  160. #endif
  161.                 : "=m" (value)
  162.                 : "m" (storage)
  163.                 : "memory", "xmm4"
  164.             );
  165. #else
  166.             __asm__ __volatile__
  167.             (
  168.                 "fildll %1\n\t"
  169.                 "fistpll %0\n\t"
  170.                 : "=m" (value)
  171.                 : "m" (storage)
  172.                 : "memory"
  173.             );
  174. #endif
  175.         }
  176.         else
  177.         {
  178. #if defined(__clang__)
  179.             // Clang cannot allocate eax:edx register pairs but it has sync intrinsics
  180.             value = __sync_val_compare_and_swap(&storage, (storage_type)0, (storage_type)0);
  181. #else
  182.             // We don't care for comparison result here; the previous value will be stored into value anyway.
  183.             // Also we don't care for ebx and ecx values, they just have to be equal to eax and edx before cmpxchg8b.
  184.             __asm__ __volatile__
  185.             (
  186.                 "movl %%ebx, %%eax\n\t"
  187.                 "movl %%ecx, %%edx\n\t"
  188.                 "lock; cmpxchg8b %[storage]\n\t"
  189.                 : "=&A" (value)
  190.                 : [storage] "m" (storage)
  191.                 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
  192.             );
  193. #endif
  194.         }
  195.  
  196.         return value;
  197.     }
  198.  
  199.     static BOOST_FORCEINLINE bool compare_exchange_strong(
  200.         storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT
  201.     {
  202. #if defined(__clang__)
  203.         // Clang cannot allocate eax:edx register pairs but it has sync intrinsics
  204.         storage_type old_expected = expected;
  205.         expected = __sync_val_compare_and_swap(&storage, old_expected, desired);
  206.         return expected == old_expected;
  207. #elif defined(__PIC__)
  208.         // Make sure ebx is saved and restored properly in case
  209.         // of position independent code. To make this work
  210.         // setup register constraints such that ebx can not be
  211.         // used by accident e.g. as base address for the variable
  212.         // to be modified. Accessing "scratch" should always be okay,
  213.         // as it can only be placed on the stack (and therefore
  214.         // accessed through ebp or esp only).
  215.         //
  216.         // In theory, could push/pop ebx onto/off the stack, but movs
  217.         // to a prepared stack slot turn out to be faster.
  218.  
  219.         uint32_t scratch;
  220.         bool success;
  221.         __asm__ __volatile__
  222.         (
  223.             "movl %%ebx, %[scratch]\n\t"
  224.             "movl %[desired_lo], %%ebx\n\t"
  225.             "lock; cmpxchg8b %[dest]\n\t"
  226.             "movl %[scratch], %%ebx\n\t"
  227.             "sete %[success]\n\t"
  228. #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_CONSTRAINT_ALTERNATIVES)
  229.             : "+A,A,A,A,A,A" (expected), [dest] "+m,m,m,m,m,m" (storage), [scratch] "=m,m,m,m,m,m" (scratch), [success] "=q,m,q,m,q,m" (success)
  230.             : [desired_lo] "S,S,D,D,m,m" ((uint32_t)desired), "c,c,c,c,c,c" ((uint32_t)(desired >> 32))
  231. #else
  232.             : "+A" (expected), [dest] "+m" (storage), [scratch] "=m" (scratch), [success] "=q" (success)
  233.             : [desired_lo] "S" ((uint32_t)desired), "c" ((uint32_t)(desired >> 32))
  234. #endif
  235.             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
  236.         );
  237.         return success;
  238. #else
  239.         bool success;
  240.         __asm__ __volatile__
  241.         (
  242.             "lock; cmpxchg8b %[dest]\n\t"
  243.             "sete %[success]\n\t"
  244. #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_CONSTRAINT_ALTERNATIVES)
  245.             : "+A,A" (expected), [dest] "+m,m" (storage), [success] "=q,m" (success)
  246.             : "b,b" ((uint32_t)desired), "c,c" ((uint32_t)(desired >> 32))
  247. #else
  248.             : "+A" (expected), [dest] "+m" (storage), [success] "=q" (success)
  249.             : "b" ((uint32_t)desired), "c" ((uint32_t)(desired >> 32))
  250. #endif
  251.             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
  252.         );
  253.         return success;
  254. #endif
  255.     }
  256.  
  257.     static BOOST_FORCEINLINE bool compare_exchange_weak(
  258.         storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
  259.     {
  260.         return compare_exchange_strong(storage, expected, desired, success_order, failure_order);
  261.     }
  262.  
  263.     static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  264.     {
  265. #if defined(__clang__)
  266.         // Clang cannot allocate eax:edx register pairs but it has sync intrinsics
  267.         storage_type old_val = storage;
  268.         while (true)
  269.         {
  270.             storage_type val = __sync_val_compare_and_swap(&storage, old_val, v);
  271.             if (val == old_val)
  272.                 return val;
  273.             old_val = val;
  274.         }
  275. #elif !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
  276. #if defined(__PIC__)
  277.         uint32_t scratch;
  278.         __asm__ __volatile__
  279.         (
  280.             "movl %%ebx, %[scratch]\n\t"
  281.             "movl %%eax, %%ebx\n\t"
  282.             "movl %%edx, %%ecx\n\t"
  283.             "movl %[dest], %%eax\n\t"
  284.             "movl 4+%[dest], %%edx\n\t"
  285.             ".align 16\n\t"
  286.             "1: lock; cmpxchg8b %[dest]\n\t"
  287.             "jne 1b\n\t"
  288.             "movl %[scratch], %%ebx\n\t"
  289.             : "+A" (v), [scratch] "=m" (scratch), [dest] "+o" (storage)
  290.             :
  291.             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "ecx", "memory"
  292.         );
  293.         return v;
  294. #else // defined(__PIC__)
  295.         __asm__ __volatile__
  296.         (
  297.             "movl %[dest], %%eax\n\t"
  298.             "movl 4+%[dest], %%edx\n\t"
  299.             ".align 16\n\t"
  300.             "1: lock; cmpxchg8b %[dest]\n\t"
  301.             "jne 1b\n\t"
  302.             : "=A" (v), [dest] "+o" (storage)
  303.             : "b" ((uint32_t)v), "c" ((uint32_t)(v >> 32))
  304.             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
  305.         );
  306.         return v;
  307. #endif // defined(__PIC__)
  308. #else // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
  309. #if defined(__PIC__)
  310.         uint32_t scratch;
  311.         __asm__ __volatile__
  312.         (
  313.             "movl %%ebx, %[scratch]\n\t"
  314.             "movl %%eax, %%ebx\n\t"
  315.             "movl %%edx, %%ecx\n\t"
  316.             "movl 0(%[dest]), %%eax\n\t"
  317.             "movl 4(%[dest]), %%edx\n\t"
  318.             ".align 16\n\t"
  319.             "1: lock; cmpxchg8b 0(%[dest])\n\t"
  320.             "jne 1b\n\t"
  321.             "movl %[scratch], %%ebx\n\t"
  322. #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_CONSTRAINT_ALTERNATIVES)
  323.             : "+A,A" (v), [scratch] "=m,m" (scratch)
  324.             : [dest] "D,S" (&storage)
  325. #else
  326.             : "+A" (v), [scratch] "=m" (scratch)
  327.             : [dest] "D" (&storage)
  328. #endif
  329.             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "ecx", "memory"
  330.         );
  331.         return v;
  332. #else // defined(__PIC__)
  333.         __asm__ __volatile__
  334.         (
  335.             "movl 0(%[dest]), %%eax\n\t"
  336.             "movl 4(%[dest]), %%edx\n\t"
  337.             ".align 16\n\t"
  338.             "1: lock; cmpxchg8b 0(%[dest])\n\t"
  339.             "jne 1b\n\t"
  340. #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_CONSTRAINT_ALTERNATIVES)
  341.             : "=A,A" (v)
  342.             : "b,b" ((uint32_t)v), "c,c" ((uint32_t)(v >> 32)), [dest] "D,S" (&storage)
  343. #else
  344.             : "=A" (v)
  345.             : "b" ((uint32_t)v), "c" ((uint32_t)(v >> 32)), [dest] "D" (&storage)
  346. #endif
  347.             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
  348.         );
  349.         return v;
  350. #endif // defined(__PIC__)
  351. #endif
  352.     }
  353.  
  354.     static BOOST_FORCEINLINE bool is_lock_free(storage_type const volatile&) BOOST_NOEXCEPT
  355.     {
  356.         return true;
  357.     }
  358. };
  359.  
  360. #endif // defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B)
  361.  
  362. #if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B)
  363.  
  364. template< bool Signed >
  365. struct gcc_dcas_x86_64
  366. {
  367.     typedef typename make_storage_type< 16u, Signed >::type storage_type;
  368.     typedef typename make_storage_type< 16u, Signed >::aligned aligned_storage_type;
  369.  
  370.     static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
  371.     {
  372.         uint64_t const* p_value = (uint64_t const*)&v;
  373. #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
  374.         __asm__ __volatile__
  375.         (
  376.             "movq %[dest], %%rax\n\t"
  377.             "movq 8+%[dest], %%rdx\n\t"
  378.             ".align 16\n\t"
  379.             "1: lock; cmpxchg16b %[dest]\n\t"
  380.             "jne 1b\n\t"
  381.             : [dest] "=o" (storage)
  382.             : "b" (p_value[0]), "c" (p_value[1])
  383.             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "rax", "rdx", "memory"
  384.         );
  385. #else // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
  386.         __asm__ __volatile__
  387.         (
  388.             "movq 0(%[dest]), %%rax\n\t"
  389.             "movq 8(%[dest]), %%rdx\n\t"
  390.             ".align 16\n\t"
  391.             "1: lock; cmpxchg16b 0(%[dest])\n\t"
  392.             "jne 1b\n\t"
  393.             :
  394.             : "b" (p_value[0]), "c" (p_value[1]), [dest] "r" (&storage)
  395.             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "rax", "rdx", "memory"
  396.         );
  397. #endif // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
  398.     }
  399.  
  400.     static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order) BOOST_NOEXCEPT
  401.     {
  402. #if defined(__clang__)
  403.         // Clang cannot allocate rax:rdx register pairs but it has sync intrinsics
  404.         storage_type value = storage_type();
  405.         return __sync_val_compare_and_swap(&storage, value, value);
  406. #elif defined(BOOST_ATOMIC_DETAIL_NO_ASM_RAX_RDX_PAIRS)
  407.         // GCC 4.4 can't allocate rax:rdx register pair either but it also doesn't support 128-bit __sync_val_compare_and_swap
  408.         storage_type value;
  409.  
  410.         // We don't care for comparison result here; the previous value will be stored into value anyway.
  411.         // Also we don't care for rbx and rcx values, they just have to be equal to rax and rdx before cmpxchg16b.
  412. #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
  413.         __asm__ __volatile__
  414.         (
  415.             "movq %%rbx, %%rax\n\t"
  416.             "movq %%rcx, %%rdx\n\t"
  417.             "lock; cmpxchg16b %[storage]\n\t"
  418.             "movq %%rax, %[value]\n\t"
  419.             "movq %%rdx, 8+%[value]\n\t"
  420.             : [value] "=o" (value)
  421.             : [storage] "m" (storage)
  422.             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory", "rax", "rdx"
  423.         );
  424. #else // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
  425.         __asm__ __volatile__
  426.         (
  427.             "movq %%rbx, %%rax\n\t"
  428.             "movq %%rcx, %%rdx\n\t"
  429.             "lock; cmpxchg16b %[storage]\n\t"
  430.             "movq %%rax, 0(%[value])\n\t"
  431.             "movq %%rdx, 8(%[value])\n\t"
  432.             :
  433.             : [storage] "m" (storage), [value] "r" (&value)
  434.             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory", "rax", "rdx"
  435.         );
  436. #endif // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
  437.  
  438.         return value;
  439. #else // defined(BOOST_ATOMIC_DETAIL_NO_ASM_RAX_RDX_PAIRS)
  440.         storage_type value;
  441.  
  442.         // We don't care for comparison result here; the previous value will be stored into value anyway.
  443.         // Also we don't care for rbx and rcx values, they just have to be equal to rax and rdx before cmpxchg16b.
  444.         __asm__ __volatile__
  445.         (
  446.             "movq %%rbx, %%rax\n\t"
  447.             "movq %%rcx, %%rdx\n\t"
  448.             "lock; cmpxchg16b %[storage]\n\t"
  449.             : "=&A" (value)
  450.             : [storage] "m" (storage)
  451.             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
  452.         );
  453.  
  454.         return value;
  455. #endif
  456.     }
  457.  
  458.     static BOOST_FORCEINLINE bool compare_exchange_strong(
  459.         storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT
  460.     {
  461. #if defined(__clang__)
  462.         // Clang cannot allocate rax:rdx register pairs but it has sync intrinsics
  463.         storage_type old_expected = expected;
  464.         expected = __sync_val_compare_and_swap(&storage, old_expected, desired);
  465.         return expected == old_expected;
  466. #elif defined(BOOST_ATOMIC_DETAIL_NO_ASM_RAX_RDX_PAIRS)
  467.         // GCC 4.4 can't allocate rax:rdx register pair either but it also doesn't support 128-bit __sync_val_compare_and_swap
  468.         uint64_t const* p_desired = (uint64_t const*)&desired;
  469.         bool success;
  470. #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
  471.         __asm__ __volatile__
  472.         (
  473.             "movq %[expected], %%rax\n\t"
  474.             "movq 8+%[expected], %%rdx\n\t"
  475.             "lock; cmpxchg16b %[dest]\n\t"
  476.             "sete %[success]\n\t"
  477.             "movq %%rax, %[expected]\n\t"
  478.             "movq %%rdx, 8+%[expected]\n\t"
  479.             : [dest] "+m" (storage), [expected] "+o" (expected), [success] "=q" (success)
  480.             : "b" (p_desired[0]), "c" (p_desired[1])
  481.             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory", "rax", "rdx"
  482.         );
  483. #else // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
  484.         __asm__ __volatile__
  485.         (
  486.             "movq 0(%[expected]), %%rax\n\t"
  487.             "movq 8(%[expected]), %%rdx\n\t"
  488.             "lock; cmpxchg16b %[dest]\n\t"
  489.             "sete %[success]\n\t"
  490.             "movq %%rax, 0(%[expected])\n\t"
  491.             "movq %%rdx, 8(%[expected])\n\t"
  492.             : [dest] "+m" (storage), [success] "=q" (success)
  493.             : "b" (p_desired[0]), "c" (p_desired[1]), [expected] "r" (&expected)
  494.             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory", "rax", "rdx"
  495.         );
  496. #endif // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
  497.  
  498.         return success;
  499. #else // defined(BOOST_ATOMIC_DETAIL_NO_ASM_RAX_RDX_PAIRS)
  500.         uint64_t const* p_desired = (uint64_t const*)&desired;
  501.         bool success;
  502.         __asm__ __volatile__
  503.         (
  504.             "lock; cmpxchg16b %[dest]\n\t"
  505.             "sete %[success]\n\t"
  506. #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_CONSTRAINT_ALTERNATIVES)
  507.             : "+A,A" (expected), [dest] "+m,m" (storage), [success] "=q,m" (success)
  508.             : "b,b" (p_desired[0]), "c,c" (p_desired[1])
  509. #else
  510.             : "+A" (expected), [dest] "+m" (storage), [success] "=q" (success)
  511.             : "b" (p_desired[0]), "c" (p_desired[1])
  512. #endif
  513.             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
  514.         );
  515.         return success;
  516. #endif
  517.     }
  518.  
  519.     static BOOST_FORCEINLINE bool compare_exchange_weak(
  520.         storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
  521.     {
  522.         return compare_exchange_strong(storage, expected, desired, success_order, failure_order);
  523.     }
  524.  
  525.     static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  526.     {
  527. #if defined(__clang__)
  528.         // Clang cannot allocate eax:edx register pairs but it has sync intrinsics
  529.         storage_type old_val = storage;
  530.         while (true)
  531.         {
  532.             storage_type val = __sync_val_compare_and_swap(&storage, old_val, v);
  533.             if (val == old_val)
  534.                 return val;
  535.             old_val = val;
  536.         }
  537. #elif defined(BOOST_ATOMIC_DETAIL_NO_ASM_RAX_RDX_PAIRS)
  538.         // GCC 4.4 can't allocate rax:rdx register pair either but it also doesn't support 128-bit __sync_val_compare_and_swap
  539.         storage_type old_value;
  540.         uint64_t const* p_value = (uint64_t const*)&v;
  541. #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
  542.         __asm__ __volatile__
  543.         (
  544.             "movq %[dest], %%rax\n\t"
  545.             "movq 8+%[dest], %%rdx\n\t"
  546.             ".align 16\n\t"
  547.             "1: lock; cmpxchg16b %[dest]\n\t"
  548.             "jne 1b\n\t"
  549.             "movq %%rax, %[old_value]\n\t"
  550.             "movq %%rdx, 8+%[old_value]\n\t"
  551.             : [dest] "+o" (storage), [old_value] "=o" (old_value)
  552.             : "b" (p_value[0]), "c" (p_value[1])
  553.             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory", "rax", "rdx"
  554.         );
  555. #else // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
  556.         __asm__ __volatile__
  557.         (
  558.             "movq 0(%[dest]), %%rax\n\t"
  559.             "movq 8(%[dest]), %%rdx\n\t"
  560.             ".align 16\n\t"
  561.             "1: lock; cmpxchg16b 0(%[dest])\n\t"
  562.             "jne 1b\n\t"
  563.             "movq %%rax, 0(%[old_value])\n\t"
  564.             "movq %%rdx, 8(%[old_value])\n\t"
  565.             :
  566.             : "b" (p_value[0]), "c" (p_value[1]), [dest] "r" (&storage), [old_value] "r" (&old_value)
  567.             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory", "rax", "rdx"
  568.         );
  569. #endif // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
  570.  
  571.         return old_value;
  572. #else // defined(BOOST_ATOMIC_DETAIL_NO_ASM_RAX_RDX_PAIRS)
  573.         uint64_t const* p_value = (uint64_t const*)&v;
  574. #if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
  575.         __asm__ __volatile__
  576.         (
  577.             "movq %[dest], %%rax\n\t"
  578.             "movq 8+%[dest], %%rdx\n\t"
  579.             ".align 16\n\t"
  580.             "1: lock; cmpxchg16b %[dest]\n\t"
  581.             "jne 1b\n\t"
  582.             : "=&A" (v), [dest] "+o" (storage)
  583.             : "b" (p_value[0]), "c" (p_value[1])
  584.             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
  585.         );
  586. #else // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
  587.         __asm__ __volatile__
  588.         (
  589.             "movq 0(%[dest]), %%rax\n\t"
  590.             "movq 8(%[dest]), %%rdx\n\t"
  591.             ".align 16\n\t"
  592.             "1: lock; cmpxchg16b 0(%[dest])\n\t"
  593.             "jne 1b\n\t"
  594.             : "=&A" (v)
  595.             : "b" (p_value[0]), "c" (p_value[1]), [dest] "r" (&storage)
  596.             : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
  597.         );
  598. #endif // !defined(BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS)
  599.  
  600.         return v;
  601. #endif
  602.     }
  603.  
  604.     static BOOST_FORCEINLINE bool is_lock_free(storage_type const volatile&) BOOST_NOEXCEPT
  605.     {
  606.         return true;
  607.     }
  608. };
  609.  
  610. #endif // defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B)
  611.  
  612. } // namespace detail
  613. } // namespace atomics
  614. } // namespace mars_boost
  615.  
  616. #endif // BOOST_ATOMIC_DETAIL_OPS_GCC_X86_DCAS_HPP_INCLUDED_
  617.  
downloadops_gcc_x86_dcas.hpp Source code - Download mars Source code
Related Source Codes/Software:
Hero - Elegant transition library for iOS & tvOS 2017-06-09
deep-photo-styletransfer - Code and data for paper "Deep Photo Style Transfer... 2017-06-09
mastodon - A GNU Social-compatible microblogging server ... 2017-06-09
plyr - A simple HTML5, YouTube and Vimeo player ... 2017-06-08
prepack - Prepack is a partial evaluator for JavaScript. Pre... 2017-06-08
Public-APIs - 2017-06-09
lottie-ios - An iOS library to natively render After Effects ve... 2017-06-09
Awesome-Hacking - A collection of various awesome lists for hackers,... 2017-06-09
algorithms - Minimal examples of data structures and algorithms... 2017-06-10
lectures - Oxford Deep NLP 2017 course 2017-06-10
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top