]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/atomic/detail/extra_ops_msvc_x86.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / atomic / detail / extra_ops_msvc_x86.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) 2017 Andrey Semashev
7 */
8 /*!
9 * \file atomic/detail/extra_ops_msvc_x86.hpp
10 *
11 * This header contains implementation of the extra atomic operations for x86.
12 */
13
14 #ifndef BOOST_ATOMIC_DETAIL_EXTRA_OPS_MSVC_X86_HPP_INCLUDED_
15 #define BOOST_ATOMIC_DETAIL_EXTRA_OPS_MSVC_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/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>
25
26 #ifdef BOOST_HAS_PRAGMA_ONCE
27 #pragma once
28 #endif
29
30 #if defined(BOOST_MSVC)
31 #pragma warning(push)
32 // frame pointer register 'ebx' modified by inline assembly code
33 #pragma warning(disable: 4731)
34 #endif
35
36 namespace boost {
37 namespace atomics {
38 namespace detail {
39
40 #if defined(_M_IX86) || (defined(BOOST_ATOMIC_INTERLOCKED_BTS) && defined(BOOST_ATOMIC_INTERLOCKED_BTR))
41
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 >
45 {
46 typedef generic_extra_operations< Base, Size, Signed > base_type;
47 typedef typename base_type::storage_type storage_type;
48
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
51 {
52 return !!BOOST_ATOMIC_INTERLOCKED_BTS(&storage, bit_number);
53 }
54 #else
55 static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
56 {
57 base_type::fence_before(order);
58 bool result;
59 __asm
60 {
61 mov edx, storage
62 mov eax, bit_number
63 lock bts [edx], eax
64 setc result
65 };
66 base_type::fence_after(order);
67 return result;
68 }
69 #endif
70
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
73 {
74 return !!BOOST_ATOMIC_INTERLOCKED_BTR(&storage, bit_number);
75 }
76 #else
77 static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
78 {
79 base_type::fence_before(order);
80 bool result;
81 __asm
82 {
83 mov edx, storage
84 mov eax, bit_number
85 lock btr [edx], eax
86 setc result
87 };
88 base_type::fence_after(order);
89 return result;
90 }
91 #endif
92
93 #if defined(_M_IX86)
94 static BOOST_FORCEINLINE bool bit_test_and_complement(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
95 {
96 base_type::fence_before(order);
97 bool result;
98 __asm
99 {
100 mov edx, storage
101 mov eax, bit_number
102 lock btc [edx], eax
103 setc result
104 };
105 base_type::fence_after(order);
106 return result;
107 }
108 #endif
109 };
110
111 template< typename Base, bool Signed >
112 struct extra_operations< Base, 1u, Signed > :
113 public msvc_x86_extra_operations_common< Base, 1u, Signed >
114 {
115 typedef msvc_x86_extra_operations_common< Base, 1u, Signed > base_type;
116 typedef typename base_type::storage_type storage_type;
117
118 #if defined(_M_IX86)
119 static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
120 {
121 base_type::fence_before(order);
122 storage_type old_val;
123 __asm
124 {
125 mov ecx, storage
126 movzx eax, byte ptr [ecx]
127 align 16
128 again:
129 mov edx, eax
130 neg dl
131 lock cmpxchg byte ptr [ecx], dl
132 jne again
133 mov old_val, al
134 };
135 base_type::fence_after(order);
136 return old_val;
137 }
138
139 static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
140 {
141 base_type::fence_before(order);
142 __asm
143 {
144 mov ecx, storage
145 movzx eax, byte ptr [ecx]
146 align 16
147 again:
148 mov edx, eax
149 neg dl
150 lock cmpxchg byte ptr [ecx], dl
151 jne again
152 };
153 base_type::fence_after(order);
154 }
155
156 static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
157 {
158 base_type::fence_before(order);
159 storage_type old_val;
160 __asm
161 {
162 mov ecx, storage
163 movzx eax, byte ptr [ecx]
164 align 16
165 again:
166 mov edx, eax
167 not dl
168 lock cmpxchg byte ptr [ecx], dl
169 jne again
170 mov old_val, al
171 };
172 base_type::fence_after(order);
173 return old_val;
174 }
175
176 static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
177 {
178 base_type::fence_before(order);
179 __asm
180 {
181 mov ecx, storage
182 movzx eax, byte ptr [ecx]
183 align 16
184 again:
185 mov edx, eax
186 not dl
187 lock cmpxchg byte ptr [ecx], dl
188 jne again
189 };
190 base_type::fence_after(order);
191 }
192
193 static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
194 {
195 base_type::fence_before(order);
196 __asm
197 {
198 mov edx, storage
199 movzx eax, v
200 lock add byte ptr [edx], al
201 };
202 base_type::fence_after(order);
203 }
204
205 static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
206 {
207 base_type::fence_before(order);
208 __asm
209 {
210 mov edx, storage
211 movzx eax, v
212 lock sub byte ptr [edx], al
213 };
214 base_type::fence_after(order);
215 }
216
217 static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
218 {
219 base_type::fence_before(order);
220 __asm
221 {
222 mov edx, storage
223 lock neg byte ptr [edx]
224 };
225 base_type::fence_after(order);
226 }
227
228 static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
229 {
230 base_type::fence_before(order);
231 __asm
232 {
233 mov edx, storage
234 movzx eax, v
235 lock and byte ptr [edx], al
236 };
237 base_type::fence_after(order);
238 }
239
240 static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
241 {
242 base_type::fence_before(order);
243 __asm
244 {
245 mov edx, storage
246 movzx eax, v
247 lock or byte ptr [edx], al
248 };
249 base_type::fence_after(order);
250 }
251
252 static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
253 {
254 base_type::fence_before(order);
255 __asm
256 {
257 mov edx, storage
258 movzx eax, v
259 lock xor byte ptr [edx], al
260 };
261 base_type::fence_after(order);
262 }
263
264 static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
265 {
266 base_type::fence_before(order);
267 __asm
268 {
269 mov edx, storage
270 lock not byte ptr [edx]
271 };
272 base_type::fence_after(order);
273 }
274
275 static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
276 {
277 base_type::fence_before(order);
278 bool result;
279 __asm
280 {
281 mov edx, storage
282 movzx eax, v
283 lock add byte ptr [edx], al
284 setz result
285 };
286 base_type::fence_after(order);
287 return result;
288 }
289
290 static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
291 {
292 base_type::fence_before(order);
293 bool result;
294 __asm
295 {
296 mov edx, storage
297 movzx eax, v
298 lock sub byte ptr [edx], al
299 setz result
300 };
301 base_type::fence_after(order);
302 return result;
303 }
304
305 static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
306 {
307 base_type::fence_before(order);
308 bool result;
309 __asm
310 {
311 mov edx, storage
312 movzx eax, v
313 lock and byte ptr [edx], al
314 setz result
315 };
316 base_type::fence_after(order);
317 return result;
318 }
319
320 static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
321 {
322 base_type::fence_before(order);
323 bool result;
324 __asm
325 {
326 mov edx, storage
327 movzx eax, v
328 lock or byte ptr [edx], al
329 setz result
330 };
331 base_type::fence_after(order);
332 return result;
333 }
334
335 static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
336 {
337 base_type::fence_before(order);
338 bool result;
339 __asm
340 {
341 mov edx, storage
342 movzx eax, v
343 lock xor byte ptr [edx], al
344 setz result
345 };
346 base_type::fence_after(order);
347 return result;
348 }
349 #endif // defined(_M_IX86)
350 };
351
352 template< typename Base, bool Signed >
353 struct extra_operations< Base, 2u, Signed > :
354 public msvc_x86_extra_operations_common< Base, 2u, Signed >
355 {
356 typedef msvc_x86_extra_operations_common< Base, 2u, Signed > base_type;
357 typedef typename base_type::storage_type storage_type;
358
359 #if defined(_M_IX86)
360 static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
361 {
362 base_type::fence_before(order);
363 storage_type old_val;
364 __asm
365 {
366 mov ecx, storage
367 movzx eax, word ptr [ecx]
368 align 16
369 again:
370 mov edx, eax
371 neg dx
372 lock cmpxchg word ptr [ecx], dx
373 jne again
374 mov old_val, ax
375 };
376 base_type::fence_after(order);
377 return old_val;
378 }
379
380 static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
381 {
382 base_type::fence_before(order);
383 __asm
384 {
385 mov ecx, storage
386 movzx eax, word ptr [ecx]
387 align 16
388 again:
389 mov edx, eax
390 neg dx
391 lock cmpxchg word ptr [ecx], dx
392 jne again
393 };
394 base_type::fence_after(order);
395 }
396
397 static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
398 {
399 base_type::fence_before(order);
400 storage_type old_val;
401 __asm
402 {
403 mov ecx, storage
404 movzx eax, word ptr [ecx]
405 align 16
406 again:
407 mov edx, eax
408 not dx
409 lock cmpxchg word ptr [ecx], dx
410 jne again
411 mov old_val, ax
412 };
413 base_type::fence_after(order);
414 return old_val;
415 }
416
417 static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
418 {
419 base_type::fence_before(order);
420 __asm
421 {
422 mov ecx, storage
423 movzx eax, word ptr [ecx]
424 align 16
425 again:
426 mov edx, eax
427 not dx
428 lock cmpxchg word ptr [ecx], dx
429 jne again
430 };
431 base_type::fence_after(order);
432 }
433
434 static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
435 {
436 base_type::fence_before(order);
437 __asm
438 {
439 mov edx, storage
440 movzx eax, v
441 lock add word ptr [edx], ax
442 };
443 base_type::fence_after(order);
444 }
445
446 static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
447 {
448 base_type::fence_before(order);
449 __asm
450 {
451 mov edx, storage
452 movzx eax, v
453 lock sub word ptr [edx], ax
454 };
455 base_type::fence_after(order);
456 }
457
458 static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
459 {
460 base_type::fence_before(order);
461 __asm
462 {
463 mov edx, storage
464 lock neg word ptr [edx]
465 };
466 base_type::fence_after(order);
467 }
468
469 static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
470 {
471 base_type::fence_before(order);
472 __asm
473 {
474 mov edx, storage
475 movzx eax, v
476 lock and word ptr [edx], ax
477 };
478 base_type::fence_after(order);
479 }
480
481 static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
482 {
483 base_type::fence_before(order);
484 __asm
485 {
486 mov edx, storage
487 movzx eax, v
488 lock or word ptr [edx], ax
489 };
490 base_type::fence_after(order);
491 }
492
493 static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
494 {
495 base_type::fence_before(order);
496 __asm
497 {
498 mov edx, storage
499 movzx eax, v
500 lock xor word ptr [edx], ax
501 };
502 base_type::fence_after(order);
503 }
504
505 static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
506 {
507 base_type::fence_before(order);
508 __asm
509 {
510 mov edx, storage
511 lock not word ptr [edx]
512 };
513 base_type::fence_after(order);
514 }
515
516 static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
517 {
518 base_type::fence_before(order);
519 bool result;
520 __asm
521 {
522 mov edx, storage
523 movzx eax, v
524 lock add word ptr [edx], ax
525 setz result
526 };
527 base_type::fence_after(order);
528 return result;
529 }
530
531 static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
532 {
533 base_type::fence_before(order);
534 bool result;
535 __asm
536 {
537 mov edx, storage
538 movzx eax, v
539 lock sub word ptr [edx], ax
540 setz result
541 };
542 base_type::fence_after(order);
543 return result;
544 }
545
546 static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
547 {
548 base_type::fence_before(order);
549 bool result;
550 __asm
551 {
552 mov edx, storage
553 movzx eax, v
554 lock and word ptr [edx], ax
555 setz result
556 };
557 base_type::fence_after(order);
558 return result;
559 }
560
561 static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
562 {
563 base_type::fence_before(order);
564 bool result;
565 __asm
566 {
567 mov edx, storage
568 movzx eax, v
569 lock or word ptr [edx], ax
570 setz result
571 };
572 base_type::fence_after(order);
573 return result;
574 }
575
576 static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
577 {
578 base_type::fence_before(order);
579 bool result;
580 __asm
581 {
582 mov edx, storage
583 movzx eax, v
584 lock xor word ptr [edx], ax
585 setz result
586 };
587 base_type::fence_after(order);
588 return result;
589 }
590 #endif // defined(_M_IX86)
591 };
592
593 template< typename Base, bool Signed >
594 struct extra_operations< Base, 4u, Signed > :
595 public msvc_x86_extra_operations_common< Base, 4u, Signed >
596 {
597 typedef msvc_x86_extra_operations_common< Base, 4u, Signed > base_type;
598 typedef typename base_type::storage_type storage_type;
599
600 #if defined(_M_IX86)
601 static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
602 {
603 base_type::fence_before(order);
604 storage_type old_val;
605 __asm
606 {
607 mov ecx, storage
608 mov eax, dword ptr [ecx]
609 align 16
610 again:
611 mov edx, eax
612 neg edx
613 lock cmpxchg dword ptr [ecx], edx
614 jne again
615 mov old_val, eax
616 };
617 base_type::fence_after(order);
618 return old_val;
619 }
620
621 static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
622 {
623 base_type::fence_before(order);
624 __asm
625 {
626 mov ecx, storage
627 mov eax, dword ptr [ecx]
628 align 16
629 again:
630 mov edx, eax
631 neg edx
632 lock cmpxchg dword ptr [ecx], edx
633 jne again
634 };
635 base_type::fence_after(order);
636 }
637
638 static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
639 {
640 base_type::fence_before(order);
641 storage_type old_val;
642 __asm
643 {
644 mov ecx, storage
645 mov eax, dword ptr [ecx]
646 align 16
647 again:
648 mov edx, eax
649 not edx
650 lock cmpxchg dword ptr [ecx], edx
651 jne again
652 mov old_val, eax
653 };
654 base_type::fence_after(order);
655 return old_val;
656 }
657
658 static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
659 {
660 base_type::fence_before(order);
661 __asm
662 {
663 mov ecx, storage
664 mov eax, dword ptr [ecx]
665 align 16
666 again:
667 mov edx, eax
668 not edx
669 lock cmpxchg dword ptr [ecx], edx
670 jne again
671 };
672 base_type::fence_after(order);
673 }
674
675 static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
676 {
677 base_type::fence_before(order);
678 __asm
679 {
680 mov edx, storage
681 mov eax, v
682 lock add dword ptr [edx], eax
683 };
684 base_type::fence_after(order);
685 }
686
687 static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
688 {
689 base_type::fence_before(order);
690 __asm
691 {
692 mov edx, storage
693 mov eax, v
694 lock sub dword ptr [edx], eax
695 };
696 base_type::fence_after(order);
697 }
698
699 static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
700 {
701 base_type::fence_before(order);
702 __asm
703 {
704 mov edx, storage
705 lock neg dword ptr [edx]
706 };
707 base_type::fence_after(order);
708 }
709
710 static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
711 {
712 base_type::fence_before(order);
713 __asm
714 {
715 mov edx, storage
716 mov eax, v
717 lock and dword ptr [edx], eax
718 };
719 base_type::fence_after(order);
720 }
721
722 static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
723 {
724 base_type::fence_before(order);
725 __asm
726 {
727 mov edx, storage
728 mov eax, v
729 lock or dword ptr [edx], eax
730 };
731 base_type::fence_after(order);
732 }
733
734 static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
735 {
736 base_type::fence_before(order);
737 __asm
738 {
739 mov edx, storage
740 mov eax, v
741 lock xor dword ptr [edx], eax
742 };
743 base_type::fence_after(order);
744 }
745
746 static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
747 {
748 base_type::fence_before(order);
749 __asm
750 {
751 mov edx, storage
752 lock not dword ptr [edx]
753 };
754 base_type::fence_after(order);
755 }
756
757 static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
758 {
759 base_type::fence_before(order);
760 bool result;
761 __asm
762 {
763 mov edx, storage
764 mov eax, v
765 lock add dword ptr [edx], eax
766 setz result
767 };
768 base_type::fence_after(order);
769 return result;
770 }
771
772 static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
773 {
774 base_type::fence_before(order);
775 bool result;
776 __asm
777 {
778 mov edx, storage
779 mov eax, v
780 lock sub dword ptr [edx], eax
781 setz result
782 };
783 base_type::fence_after(order);
784 return result;
785 }
786
787 static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
788 {
789 base_type::fence_before(order);
790 bool result;
791 __asm
792 {
793 mov edx, storage
794 mov eax, v
795 lock and dword ptr [edx], eax
796 setz result
797 };
798 base_type::fence_after(order);
799 return result;
800 }
801
802 static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
803 {
804 base_type::fence_before(order);
805 bool result;
806 __asm
807 {
808 mov edx, storage
809 mov eax, v
810 lock or dword ptr [edx], eax
811 setz result
812 };
813 base_type::fence_after(order);
814 return result;
815 }
816
817 static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
818 {
819 base_type::fence_before(order);
820 bool result;
821 __asm
822 {
823 mov edx, storage
824 mov eax, v
825 lock xor dword ptr [edx], eax
826 setz result
827 };
828 base_type::fence_after(order);
829 return result;
830 }
831 #endif // defined(_M_IX86)
832 };
833
834 #endif // defined(_M_IX86) || (defined(BOOST_ATOMIC_INTERLOCKED_BTS) && defined(BOOST_ATOMIC_INTERLOCKED_BTR))
835
836 #if defined(BOOST_ATOMIC_INTERLOCKED_BTS64) && defined(BOOST_ATOMIC_INTERLOCKED_BTR64)
837
838 template< typename Base, bool Signed >
839 struct extra_operations< Base, 8u, Signed > :
840 public generic_extra_operations< Base, 8u, Signed >
841 {
842 typedef generic_extra_operations< Base, 8u, Signed > base_type;
843 typedef typename base_type::storage_type storage_type;
844
845 static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
846 {
847 return !!BOOST_ATOMIC_INTERLOCKED_BTS64(&storage, bit_number);
848 }
849
850 static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
851 {
852 return !!BOOST_ATOMIC_INTERLOCKED_BTR64(&storage, bit_number);
853 }
854 };
855
856 #endif // defined(BOOST_ATOMIC_INTERLOCKED_BTS64) && defined(BOOST_ATOMIC_INTERLOCKED_BTR64)
857
858 } // namespace detail
859 } // namespace atomics
860 } // namespace boost
861
862 #if defined(BOOST_MSVC)
863 #pragma warning(pop)
864 #endif
865
866 #endif // BOOST_ATOMIC_DETAIL_EXTRA_OPS_MSVC_X86_HPP_INCLUDED_