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) 2017 Andrey Semashev
9 * \file atomic/detail/extra_ops_msvc_x86.hpp
11 * This header contains implementation of the extra atomic operations for x86.
14 #ifndef BOOST_ATOMIC_DETAIL_EXTRA_OPS_MSVC_X86_HPP_INCLUDED_
15 #define BOOST_ATOMIC_DETAIL_EXTRA_OPS_MSVC_X86_HPP_INCLUDED_
18 #include <boost/memory_order.hpp>
19 #include <boost/atomic/detail/config.hpp>
20 #include <boost/atomic/detail/interlocked.hpp>
21 #include <boost/atomic/detail/storage_type.hpp>
22 #include <boost/atomic/detail/extra_operations_fwd.hpp>
23 #include <boost/atomic/detail/extra_ops_generic.hpp>
24 #include <boost/atomic/capabilities.hpp>
26 #ifdef BOOST_HAS_PRAGMA_ONCE
30 #if defined(BOOST_MSVC)
32 // frame pointer register 'ebx' modified by inline assembly code
33 #pragma warning(disable: 4731)
40 #if defined(_M_IX86) || (defined(BOOST_ATOMIC_INTERLOCKED_BTS) && defined(BOOST_ATOMIC_INTERLOCKED_BTR))
42 template< typename Base, std::size_t Size, bool Signed >
43 struct msvc_x86_extra_operations_common :
44 public generic_extra_operations< Base, Size, Signed >
46 typedef generic_extra_operations< Base, Size, Signed > base_type;
47 typedef typename base_type::storage_type storage_type;
49 #if defined(BOOST_ATOMIC_INTERLOCKED_BTS)
50 static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order) BOOST_NOEXCEPT
52 return !!BOOST_ATOMIC_INTERLOCKED_BTS(&storage, bit_number);
55 static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
57 base_type::fence_before(order);
66 base_type::fence_after(order);
71 #if defined(BOOST_ATOMIC_INTERLOCKED_BTR)
72 static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order) BOOST_NOEXCEPT
74 return !!BOOST_ATOMIC_INTERLOCKED_BTR(&storage, bit_number);
77 static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
79 base_type::fence_before(order);
88 base_type::fence_after(order);
94 static BOOST_FORCEINLINE bool bit_test_and_complement(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
96 base_type::fence_before(order);
105 base_type::fence_after(order);
111 template< typename Base, bool Signed >
112 struct extra_operations< Base, 1u, Signed > :
113 public msvc_x86_extra_operations_common< Base, 1u, Signed >
115 typedef msvc_x86_extra_operations_common< Base, 1u, Signed > base_type;
116 typedef typename base_type::storage_type storage_type;
119 static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
121 base_type::fence_before(order);
122 storage_type old_val;
126 movzx eax, byte ptr [ecx]
131 lock cmpxchg byte ptr [ecx], dl
135 base_type::fence_after(order);
139 static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
141 base_type::fence_before(order);
145 movzx eax, byte ptr [ecx]
150 lock cmpxchg byte ptr [ecx], dl
153 base_type::fence_after(order);
156 static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
158 base_type::fence_before(order);
159 storage_type old_val;
163 movzx eax, byte ptr [ecx]
168 lock cmpxchg byte ptr [ecx], dl
172 base_type::fence_after(order);
176 static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
178 base_type::fence_before(order);
182 movzx eax, byte ptr [ecx]
187 lock cmpxchg byte ptr [ecx], dl
190 base_type::fence_after(order);
193 static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
195 base_type::fence_before(order);
200 lock add byte ptr [edx], al
202 base_type::fence_after(order);
205 static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
207 base_type::fence_before(order);
212 lock sub byte ptr [edx], al
214 base_type::fence_after(order);
217 static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
219 base_type::fence_before(order);
223 lock neg byte ptr [edx]
225 base_type::fence_after(order);
228 static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
230 base_type::fence_before(order);
235 lock and byte ptr [edx], al
237 base_type::fence_after(order);
240 static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
242 base_type::fence_before(order);
247 lock or byte ptr [edx], al
249 base_type::fence_after(order);
252 static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
254 base_type::fence_before(order);
259 lock xor byte ptr [edx], al
261 base_type::fence_after(order);
264 static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
266 base_type::fence_before(order);
270 lock not byte ptr [edx]
272 base_type::fence_after(order);
275 static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
277 base_type::fence_before(order);
283 lock add byte ptr [edx], al
286 base_type::fence_after(order);
290 static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
292 base_type::fence_before(order);
298 lock sub byte ptr [edx], al
301 base_type::fence_after(order);
305 static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
307 base_type::fence_before(order);
313 lock and byte ptr [edx], al
316 base_type::fence_after(order);
320 static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
322 base_type::fence_before(order);
328 lock or byte ptr [edx], al
331 base_type::fence_after(order);
335 static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
337 base_type::fence_before(order);
343 lock xor byte ptr [edx], al
346 base_type::fence_after(order);
349 #endif // defined(_M_IX86)
352 template< typename Base, bool Signed >
353 struct extra_operations< Base, 2u, Signed > :
354 public msvc_x86_extra_operations_common< Base, 2u, Signed >
356 typedef msvc_x86_extra_operations_common< Base, 2u, Signed > base_type;
357 typedef typename base_type::storage_type storage_type;
360 static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
362 base_type::fence_before(order);
363 storage_type old_val;
367 movzx eax, word ptr [ecx]
372 lock cmpxchg word ptr [ecx], dx
376 base_type::fence_after(order);
380 static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
382 base_type::fence_before(order);
386 movzx eax, word ptr [ecx]
391 lock cmpxchg word ptr [ecx], dx
394 base_type::fence_after(order);
397 static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
399 base_type::fence_before(order);
400 storage_type old_val;
404 movzx eax, word ptr [ecx]
409 lock cmpxchg word ptr [ecx], dx
413 base_type::fence_after(order);
417 static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
419 base_type::fence_before(order);
423 movzx eax, word ptr [ecx]
428 lock cmpxchg word ptr [ecx], dx
431 base_type::fence_after(order);
434 static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
436 base_type::fence_before(order);
441 lock add word ptr [edx], ax
443 base_type::fence_after(order);
446 static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
448 base_type::fence_before(order);
453 lock sub word ptr [edx], ax
455 base_type::fence_after(order);
458 static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
460 base_type::fence_before(order);
464 lock neg word ptr [edx]
466 base_type::fence_after(order);
469 static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
471 base_type::fence_before(order);
476 lock and word ptr [edx], ax
478 base_type::fence_after(order);
481 static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
483 base_type::fence_before(order);
488 lock or word ptr [edx], ax
490 base_type::fence_after(order);
493 static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
495 base_type::fence_before(order);
500 lock xor word ptr [edx], ax
502 base_type::fence_after(order);
505 static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
507 base_type::fence_before(order);
511 lock not word ptr [edx]
513 base_type::fence_after(order);
516 static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
518 base_type::fence_before(order);
524 lock add word ptr [edx], ax
527 base_type::fence_after(order);
531 static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
533 base_type::fence_before(order);
539 lock sub word ptr [edx], ax
542 base_type::fence_after(order);
546 static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
548 base_type::fence_before(order);
554 lock and word ptr [edx], ax
557 base_type::fence_after(order);
561 static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
563 base_type::fence_before(order);
569 lock or word ptr [edx], ax
572 base_type::fence_after(order);
576 static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
578 base_type::fence_before(order);
584 lock xor word ptr [edx], ax
587 base_type::fence_after(order);
590 #endif // defined(_M_IX86)
593 template< typename Base, bool Signed >
594 struct extra_operations< Base, 4u, Signed > :
595 public msvc_x86_extra_operations_common< Base, 4u, Signed >
597 typedef msvc_x86_extra_operations_common< Base, 4u, Signed > base_type;
598 typedef typename base_type::storage_type storage_type;
601 static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
603 base_type::fence_before(order);
604 storage_type old_val;
608 mov eax, dword ptr [ecx]
613 lock cmpxchg dword ptr [ecx], edx
617 base_type::fence_after(order);
621 static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
623 base_type::fence_before(order);
627 mov eax, dword ptr [ecx]
632 lock cmpxchg dword ptr [ecx], edx
635 base_type::fence_after(order);
638 static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
640 base_type::fence_before(order);
641 storage_type old_val;
645 mov eax, dword ptr [ecx]
650 lock cmpxchg dword ptr [ecx], edx
654 base_type::fence_after(order);
658 static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
660 base_type::fence_before(order);
664 mov eax, dword ptr [ecx]
669 lock cmpxchg dword ptr [ecx], edx
672 base_type::fence_after(order);
675 static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
677 base_type::fence_before(order);
682 lock add dword ptr [edx], eax
684 base_type::fence_after(order);
687 static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
689 base_type::fence_before(order);
694 lock sub dword ptr [edx], eax
696 base_type::fence_after(order);
699 static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
701 base_type::fence_before(order);
705 lock neg dword ptr [edx]
707 base_type::fence_after(order);
710 static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
712 base_type::fence_before(order);
717 lock and dword ptr [edx], eax
719 base_type::fence_after(order);
722 static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
724 base_type::fence_before(order);
729 lock or dword ptr [edx], eax
731 base_type::fence_after(order);
734 static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
736 base_type::fence_before(order);
741 lock xor dword ptr [edx], eax
743 base_type::fence_after(order);
746 static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
748 base_type::fence_before(order);
752 lock not dword ptr [edx]
754 base_type::fence_after(order);
757 static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
759 base_type::fence_before(order);
765 lock add dword ptr [edx], eax
768 base_type::fence_after(order);
772 static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
774 base_type::fence_before(order);
780 lock sub dword ptr [edx], eax
783 base_type::fence_after(order);
787 static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
789 base_type::fence_before(order);
795 lock and dword ptr [edx], eax
798 base_type::fence_after(order);
802 static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
804 base_type::fence_before(order);
810 lock or dword ptr [edx], eax
813 base_type::fence_after(order);
817 static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
819 base_type::fence_before(order);
825 lock xor dword ptr [edx], eax
828 base_type::fence_after(order);
831 #endif // defined(_M_IX86)
834 #endif // defined(_M_IX86) || (defined(BOOST_ATOMIC_INTERLOCKED_BTS) && defined(BOOST_ATOMIC_INTERLOCKED_BTR))
836 #if defined(BOOST_ATOMIC_INTERLOCKED_BTS64) && defined(BOOST_ATOMIC_INTERLOCKED_BTR64)
838 template< typename Base, bool Signed >
839 struct extra_operations< Base, 8u, Signed > :
840 public generic_extra_operations< Base, 8u, Signed >
842 typedef generic_extra_operations< Base, 8u, Signed > base_type;
843 typedef typename base_type::storage_type storage_type;
845 static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
847 return !!BOOST_ATOMIC_INTERLOCKED_BTS64(&storage, bit_number);
850 static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
852 return !!BOOST_ATOMIC_INTERLOCKED_BTR64(&storage, bit_number);
856 #endif // defined(BOOST_ATOMIC_INTERLOCKED_BTS64) && defined(BOOST_ATOMIC_INTERLOCKED_BTR64)
858 } // namespace detail
859 } // namespace atomics
862 #if defined(BOOST_MSVC)
866 #endif // BOOST_ATOMIC_DETAIL_EXTRA_OPS_MSVC_X86_HPP_INCLUDED_