diff options
Diffstat (limited to 'boost/atomic/detail/ops_gcc_x86.hpp')
-rw-r--r-- | boost/atomic/detail/ops_gcc_x86.hpp | 141 |
1 files changed, 96 insertions, 45 deletions
diff --git a/boost/atomic/detail/ops_gcc_x86.hpp b/boost/atomic/detail/ops_gcc_x86.hpp index 74e45c1f61..baf4d5757d 100644 --- a/boost/atomic/detail/ops_gcc_x86.hpp +++ b/boost/atomic/detail/ops_gcc_x86.hpp @@ -16,6 +16,7 @@ #ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_X86_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_OPS_GCC_X86_HPP_INCLUDED_ +#include <cstddef> #include <boost/memory_order.hpp> #include <boost/atomic/detail/config.hpp> #include <boost/atomic/detail/storage_type.hpp> @@ -30,12 +31,6 @@ #pragma once #endif -#if defined(__x86_64__) -#define BOOST_ATOMIC_DETAIL_TEMP_CAS_REGISTER "rdx" -#else -#define BOOST_ATOMIC_DETAIL_TEMP_CAS_REGISTER "edx" -#endif - namespace boost { namespace atomics { namespace detail { @@ -57,11 +52,11 @@ struct gcc_x86_operations_base } }; -template< typename T, typename Derived > +template< std::size_t Size, bool Signed, typename Derived > struct gcc_x86_operations : public gcc_x86_operations_base { - typedef T storage_type; + typedef typename make_storage_type< Size, Signed >::type storage_type; static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { @@ -108,11 +103,15 @@ struct gcc_x86_operations : template< bool Signed > struct operations< 1u, Signed > : - public gcc_x86_operations< typename make_storage_type< 1u, Signed >::type, operations< 1u, Signed > > + public gcc_x86_operations< 1u, Signed, operations< 1u, Signed > > { - typedef gcc_x86_operations< typename make_storage_type< 1u, Signed >::type, operations< 1u, Signed > > base_type; + typedef gcc_x86_operations< 1u, Signed, operations< 1u, Signed > > base_type; typedef typename base_type::storage_type storage_type; typedef typename make_storage_type< 1u, Signed >::aligned aligned_storage_type; + typedef typename make_storage_type< 4u, Signed >::type temp_storage_type; + + static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 1u; + static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed; static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { @@ -143,6 +142,15 @@ struct operations< 1u, Signed > : { storage_type previous = expected; bool success; +#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + __asm__ __volatile__ + ( + "lock; cmpxchgb %3, %1" + : "+a" (previous), "+m" (storage), "=@ccz" (success) + : "q" (desired) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); +#else // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) __asm__ __volatile__ ( "lock; cmpxchgb %3, %1\n\t" @@ -151,22 +159,23 @@ struct operations< 1u, Signed > : : "q" (desired) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" ); +#endif // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) expected = previous; return success; } #define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, argument, result)\ + temp_storage_type new_val;\ __asm__ __volatile__\ (\ - "xor %%" BOOST_ATOMIC_DETAIL_TEMP_CAS_REGISTER ", %%" BOOST_ATOMIC_DETAIL_TEMP_CAS_REGISTER "\n\t"\ ".align 16\n\t"\ - "1: movb %[arg], %%dl\n\t"\ - op " %%al, %%dl\n\t"\ - "lock; cmpxchgb %%dl, %[storage]\n\t"\ + "1: mov %[arg], %2\n\t"\ + op " %%al, %b2\n\t"\ + "lock; cmpxchgb %b2, %[storage]\n\t"\ "jne 1b"\ - : [res] "+a" (result), [storage] "+m" (storage)\ - : [arg] "q" (argument)\ - : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA BOOST_ATOMIC_DETAIL_TEMP_CAS_REGISTER, "memory"\ + : [res] "+a" (result), [storage] "+m" (storage), "=&q" (new_val)\ + : [arg] "ir" ((temp_storage_type)argument)\ + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ ) static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT @@ -195,11 +204,15 @@ struct operations< 1u, Signed > : template< bool Signed > struct operations< 2u, Signed > : - public gcc_x86_operations< typename make_storage_type< 2u, Signed >::type, operations< 2u, Signed > > + public gcc_x86_operations< 2u, Signed, operations< 2u, Signed > > { - typedef gcc_x86_operations< typename make_storage_type< 2u, Signed >::type, operations< 2u, Signed > > base_type; + typedef gcc_x86_operations< 2u, Signed, operations< 2u, Signed > > base_type; typedef typename base_type::storage_type storage_type; typedef typename make_storage_type< 2u, Signed >::aligned aligned_storage_type; + typedef typename make_storage_type< 4u, Signed >::type temp_storage_type; + + static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 2u; + static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed; static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { @@ -230,6 +243,15 @@ struct operations< 2u, Signed > : { storage_type previous = expected; bool success; +#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + __asm__ __volatile__ + ( + "lock; cmpxchgw %3, %1" + : "+a" (previous), "+m" (storage), "=@ccz" (success) + : "q" (desired) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); +#else // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) __asm__ __volatile__ ( "lock; cmpxchgw %3, %1\n\t" @@ -238,22 +260,23 @@ struct operations< 2u, Signed > : : "q" (desired) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" ); +#endif // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) expected = previous; return success; } #define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, argument, result)\ + temp_storage_type new_val;\ __asm__ __volatile__\ (\ - "xor %%" BOOST_ATOMIC_DETAIL_TEMP_CAS_REGISTER ", %%" BOOST_ATOMIC_DETAIL_TEMP_CAS_REGISTER "\n\t"\ ".align 16\n\t"\ - "1: movw %[arg], %%dx\n\t"\ - op " %%ax, %%dx\n\t"\ - "lock; cmpxchgw %%dx, %[storage]\n\t"\ + "1: mov %[arg], %2\n\t"\ + op " %%ax, %w2\n\t"\ + "lock; cmpxchgw %w2, %[storage]\n\t"\ "jne 1b"\ - : [res] "+a" (result), [storage] "+m" (storage)\ - : [arg] "q" (argument)\ - : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA BOOST_ATOMIC_DETAIL_TEMP_CAS_REGISTER, "memory"\ + : [res] "+a" (result), [storage] "+m" (storage), "=&q" (new_val)\ + : [arg] "ir" ((temp_storage_type)argument)\ + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ ) static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT @@ -282,12 +305,15 @@ struct operations< 2u, Signed > : template< bool Signed > struct operations< 4u, Signed > : - public gcc_x86_operations< typename make_storage_type< 4u, Signed >::type, operations< 4u, Signed > > + public gcc_x86_operations< 4u, Signed, operations< 4u, Signed > > { - typedef gcc_x86_operations< typename make_storage_type< 4u, Signed >::type, operations< 4u, Signed > > base_type; + typedef gcc_x86_operations< 4u, Signed, operations< 4u, Signed > > base_type; typedef typename base_type::storage_type storage_type; typedef typename make_storage_type< 4u, Signed >::aligned aligned_storage_type; + static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 4u; + static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed; + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { __asm__ __volatile__ @@ -317,6 +343,15 @@ struct operations< 4u, Signed > : { storage_type previous = expected; bool success; +#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + __asm__ __volatile__ + ( + "lock; cmpxchgl %3, %1" + : "+a" (previous), "+m" (storage), "=@ccz" (success) + : "r" (desired) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); +#else // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) __asm__ __volatile__ ( "lock; cmpxchgl %3, %1\n\t" @@ -325,22 +360,23 @@ struct operations< 4u, Signed > : : "r" (desired) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" ); +#endif // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) expected = previous; return success; } #define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, argument, result)\ + storage_type new_val;\ __asm__ __volatile__\ (\ - "xor %%" BOOST_ATOMIC_DETAIL_TEMP_CAS_REGISTER ", %%" BOOST_ATOMIC_DETAIL_TEMP_CAS_REGISTER "\n\t"\ ".align 16\n\t"\ - "1: movl %[arg], %%edx\n\t"\ - op " %%eax, %%edx\n\t"\ - "lock; cmpxchgl %%edx, %[storage]\n\t"\ + "1: mov %[arg], %[new_val]\n\t"\ + op " %%eax, %[new_val]\n\t"\ + "lock; cmpxchgl %[new_val], %[storage]\n\t"\ "jne 1b"\ - : [res] "+a" (result), [storage] "+m" (storage)\ - : [arg] "r" (argument)\ - : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA BOOST_ATOMIC_DETAIL_TEMP_CAS_REGISTER, "memory"\ + : [res] "+a" (result), [storage] "+m" (storage), [new_val] "=&r" (new_val)\ + : [arg] "ir" (argument)\ + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ ) static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT @@ -373,18 +409,23 @@ template< bool Signed > struct operations< 8u, Signed > : public cas_based_operations< gcc_dcas_x86< Signed > > { + static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 8u; + static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed; }; #elif defined(__x86_64__) template< bool Signed > struct operations< 8u, Signed > : - public gcc_x86_operations< typename make_storage_type< 8u, Signed >::type, operations< 8u, Signed > > + public gcc_x86_operations< 8u, Signed, operations< 8u, Signed > > { - typedef gcc_x86_operations< typename make_storage_type< 8u, Signed >::type, operations< 8u, Signed > > base_type; + typedef gcc_x86_operations< 8u, Signed, operations< 8u, Signed > > base_type; typedef typename base_type::storage_type storage_type; typedef typename make_storage_type< 8u, Signed >::aligned aligned_storage_type; + static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 8u; + static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed; + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT { __asm__ __volatile__ @@ -414,6 +455,15 @@ struct operations< 8u, Signed > : { storage_type previous = expected; bool success; +#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + __asm__ __volatile__ + ( + "lock; cmpxchgq %3, %1" + : "+a" (previous), "+m" (storage), "=@ccz" (success) + : "r" (desired) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); +#else // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) __asm__ __volatile__ ( "lock; cmpxchgq %3, %1\n\t" @@ -422,22 +472,23 @@ struct operations< 8u, Signed > : : "r" (desired) : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" ); +#endif // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) expected = previous; return success; } #define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, argument, result)\ + storage_type new_val;\ __asm__ __volatile__\ (\ - "xor %%" BOOST_ATOMIC_DETAIL_TEMP_CAS_REGISTER ", %%" BOOST_ATOMIC_DETAIL_TEMP_CAS_REGISTER "\n\t"\ ".align 16\n\t"\ - "1: movq %[arg], %%rdx\n\t"\ - op " %%rax, %%rdx\n\t"\ - "lock; cmpxchgq %%rdx, %[storage]\n\t"\ + "1: movq %[arg], %[new_val]\n\t"\ + op " %%rax, %[new_val]\n\t"\ + "lock; cmpxchgq %[new_val], %[storage]\n\t"\ "jne 1b"\ - : [res] "+a" (result), [storage] "+m" (storage)\ + : [res] "+a" (result), [storage] "+m" (storage), [new_val] "=&r" (new_val)\ : [arg] "r" (argument)\ - : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA BOOST_ATOMIC_DETAIL_TEMP_CAS_REGISTER, "memory"\ + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ ) static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT @@ -472,6 +523,8 @@ template< bool Signed > struct operations< 16u, Signed > : public cas_based_operations< gcc_dcas_x86_64< Signed > > { + static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 16u; + static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed; }; #endif // defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B) @@ -506,6 +559,4 @@ BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT } // namespace atomics } // namespace boost -#undef BOOST_ATOMIC_DETAIL_TEMP_CAS_REGISTER - #endif // BOOST_ATOMIC_DETAIL_OPS_GCC_X86_HPP_INCLUDED_ |