Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:33:56

0001 /*
0002  * Distributed under the Boost Software License, Version 1.0.
0003  * (See accompanying file LICENSE_1_0.txt or copy at
0004  * http://www.boost.org/LICENSE_1_0.txt)
0005  *
0006  * Copyright (c) 2017 Andrey Semashev
0007  */
0008 /*!
0009  * \file   atomic/detail/extra_ops_msvc_x86.hpp
0010  *
0011  * This header contains implementation of the extra atomic operations for x86.
0012  */
0013 
0014 #ifndef BOOST_ATOMIC_DETAIL_EXTRA_OPS_MSVC_X86_HPP_INCLUDED_
0015 #define BOOST_ATOMIC_DETAIL_EXTRA_OPS_MSVC_X86_HPP_INCLUDED_
0016 
0017 #include <cstddef>
0018 #include <boost/memory_order.hpp>
0019 #include <boost/atomic/detail/config.hpp>
0020 #include <boost/atomic/detail/interlocked.hpp>
0021 #include <boost/atomic/detail/storage_traits.hpp>
0022 #include <boost/atomic/detail/extra_operations_fwd.hpp>
0023 #include <boost/atomic/detail/extra_ops_generic.hpp>
0024 #include <boost/atomic/detail/header.hpp>
0025 
0026 #ifdef BOOST_HAS_PRAGMA_ONCE
0027 #pragma once
0028 #endif
0029 
0030 namespace boost {
0031 namespace atomics {
0032 namespace detail {
0033 
0034 #if defined(_M_IX86)
0035 
0036 template< typename Base, bool Signed >
0037 struct extra_operations< Base, 1u, Signed, true > :
0038     public extra_operations_generic< Base, 1u, Signed >
0039 {
0040     typedef extra_operations_generic< Base, 1u, Signed > base_type;
0041     typedef typename base_type::storage_type storage_type;
0042 
0043     static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0044     {
0045         base_type::fence_before(order);
0046         storage_type old_val;
0047         __asm
0048         {
0049             mov ecx, storage
0050             movzx eax, byte ptr [ecx]
0051             align 16
0052         again:
0053             mov edx, eax
0054             neg dl
0055             lock cmpxchg byte ptr [ecx], dl
0056             jne again
0057             mov old_val, al
0058         };
0059         base_type::fence_after(order);
0060         return old_val;
0061     }
0062 
0063     static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0064     {
0065         base_type::fence_before(order);
0066         storage_type new_val;
0067         __asm
0068         {
0069             mov ecx, storage
0070             movzx eax, byte ptr [ecx]
0071             align 16
0072         again:
0073             mov edx, eax
0074             neg dl
0075             lock cmpxchg byte ptr [ecx], dl
0076             jne again
0077             mov new_val, dl
0078         };
0079         base_type::fence_after(order);
0080         return new_val;
0081     }
0082 
0083     static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0084     {
0085         base_type::fence_before(order);
0086         bool result;
0087         __asm
0088         {
0089             mov ecx, storage
0090             movzx eax, byte ptr [ecx]
0091             align 16
0092         again:
0093             mov edx, eax
0094             neg dl
0095             lock cmpxchg byte ptr [ecx], dl
0096             jne again
0097             test dl, dl
0098             setnz result
0099         };
0100         base_type::fence_after(order);
0101         return result;
0102     }
0103 
0104     static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0105     {
0106         base_type::fence_before(order);
0107         __asm
0108         {
0109             mov ecx, storage
0110             movzx eax, byte ptr [ecx]
0111             align 16
0112         again:
0113             mov edx, eax
0114             neg dl
0115             lock cmpxchg byte ptr [ecx], dl
0116             jne again
0117         };
0118         base_type::fence_after(order);
0119     }
0120 
0121     static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0122     {
0123         base_type::fence_before(order);
0124         __asm
0125         {
0126             mov edi, storage
0127             movzx ecx, v
0128             xor edx, edx
0129             movzx eax, byte ptr [edi]
0130             align 16
0131         again:
0132             mov dl, al
0133             and dl, cl
0134             lock cmpxchg byte ptr [edi], dl
0135             jne again
0136             mov v, dl
0137         };
0138         base_type::fence_after(order);
0139         return v;
0140     }
0141 
0142     static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0143     {
0144         base_type::fence_before(order);
0145         __asm
0146         {
0147             mov edi, storage
0148             movzx ecx, v
0149             xor edx, edx
0150             movzx eax, byte ptr [edi]
0151             align 16
0152         again:
0153             mov dl, al
0154             or dl, cl
0155             lock cmpxchg byte ptr [edi], dl
0156             jne again
0157             mov v, dl
0158         };
0159         base_type::fence_after(order);
0160         return v;
0161     }
0162 
0163     static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0164     {
0165         base_type::fence_before(order);
0166         __asm
0167         {
0168             mov edi, storage
0169             movzx ecx, v
0170             xor edx, edx
0171             movzx eax, byte ptr [edi]
0172             align 16
0173         again:
0174             mov dl, al
0175             xor dl, cl
0176             lock cmpxchg byte ptr [edi], dl
0177             jne again
0178             mov v, dl
0179         };
0180         base_type::fence_after(order);
0181         return v;
0182     }
0183 
0184     static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0185     {
0186         base_type::fence_before(order);
0187         storage_type old_val;
0188         __asm
0189         {
0190             mov ecx, storage
0191             movzx eax, byte ptr [ecx]
0192             align 16
0193         again:
0194             mov edx, eax
0195             not dl
0196             lock cmpxchg byte ptr [ecx], dl
0197             jne again
0198             mov old_val, al
0199         };
0200         base_type::fence_after(order);
0201         return old_val;
0202     }
0203 
0204     static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0205     {
0206         base_type::fence_before(order);
0207         storage_type new_val;
0208         __asm
0209         {
0210             mov ecx, storage
0211             movzx eax, byte ptr [ecx]
0212             align 16
0213         again:
0214             mov edx, eax
0215             not dl
0216             lock cmpxchg byte ptr [ecx], dl
0217             jne again
0218             mov new_val, dl
0219         };
0220         base_type::fence_after(order);
0221         return new_val;
0222     }
0223 
0224     static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0225     {
0226         base_type::fence_before(order);
0227         bool result;
0228         __asm
0229         {
0230             mov ecx, storage
0231             movzx eax, byte ptr [ecx]
0232             align 16
0233         again:
0234             mov edx, eax
0235             not dl
0236             lock cmpxchg byte ptr [ecx], dl
0237             jne again
0238             test dl, dl
0239             setnz result
0240         };
0241         base_type::fence_after(order);
0242         return result;
0243     }
0244 
0245     static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0246     {
0247         base_type::fence_before(order);
0248         __asm
0249         {
0250             mov ecx, storage
0251             movzx eax, byte ptr [ecx]
0252             align 16
0253         again:
0254             mov edx, eax
0255             not dl
0256             lock cmpxchg byte ptr [ecx], dl
0257             jne again
0258         };
0259         base_type::fence_after(order);
0260     }
0261 
0262     static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0263     {
0264         base_type::fence_before(order);
0265         __asm
0266         {
0267             mov edx, storage
0268             movzx eax, v
0269             lock add byte ptr [edx], al
0270         };
0271         base_type::fence_after(order);
0272     }
0273 
0274     static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0275     {
0276         base_type::fence_before(order);
0277         __asm
0278         {
0279             mov edx, storage
0280             movzx eax, v
0281             lock sub byte ptr [edx], al
0282         };
0283         base_type::fence_after(order);
0284     }
0285 
0286     static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0287     {
0288         base_type::fence_before(order);
0289         __asm
0290         {
0291             mov edx, storage
0292             lock neg byte ptr [edx]
0293         };
0294         base_type::fence_after(order);
0295     }
0296 
0297     static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0298     {
0299         base_type::fence_before(order);
0300         __asm
0301         {
0302             mov edx, storage
0303             movzx eax, v
0304             lock and byte ptr [edx], al
0305         };
0306         base_type::fence_after(order);
0307     }
0308 
0309     static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0310     {
0311         base_type::fence_before(order);
0312         __asm
0313         {
0314             mov edx, storage
0315             movzx eax, v
0316             lock or byte ptr [edx], al
0317         };
0318         base_type::fence_after(order);
0319     }
0320 
0321     static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0322     {
0323         base_type::fence_before(order);
0324         __asm
0325         {
0326             mov edx, storage
0327             movzx eax, v
0328             lock xor byte ptr [edx], al
0329         };
0330         base_type::fence_after(order);
0331     }
0332 
0333     static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0334     {
0335         base_type::fence_before(order);
0336         __asm
0337         {
0338             mov edx, storage
0339             lock not byte ptr [edx]
0340         };
0341         base_type::fence_after(order);
0342     }
0343 
0344     static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0345     {
0346         base_type::fence_before(order);
0347         bool result;
0348         __asm
0349         {
0350             mov edx, storage
0351             movzx eax, v
0352             lock add byte ptr [edx], al
0353             setnz result
0354         };
0355         base_type::fence_after(order);
0356         return result;
0357     }
0358 
0359     static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0360     {
0361         base_type::fence_before(order);
0362         bool result;
0363         __asm
0364         {
0365             mov edx, storage
0366             movzx eax, v
0367             lock sub byte ptr [edx], al
0368             setnz result
0369         };
0370         base_type::fence_after(order);
0371         return result;
0372     }
0373 
0374     static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0375     {
0376         base_type::fence_before(order);
0377         bool result;
0378         __asm
0379         {
0380             mov edx, storage
0381             movzx eax, v
0382             lock and byte ptr [edx], al
0383             setnz result
0384         };
0385         base_type::fence_after(order);
0386         return result;
0387     }
0388 
0389     static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0390     {
0391         base_type::fence_before(order);
0392         bool result;
0393         __asm
0394         {
0395             mov edx, storage
0396             movzx eax, v
0397             lock or byte ptr [edx], al
0398             setnz result
0399         };
0400         base_type::fence_after(order);
0401         return result;
0402     }
0403 
0404     static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0405     {
0406         base_type::fence_before(order);
0407         bool result;
0408         __asm
0409         {
0410             mov edx, storage
0411             movzx eax, v
0412             lock xor byte ptr [edx], al
0413             setnz result
0414         };
0415         base_type::fence_after(order);
0416         return result;
0417     }
0418 };
0419 
0420 template< typename Base, bool Signed >
0421 struct extra_operations< Base, 2u, Signed, true > :
0422     public extra_operations_generic< Base, 2u, Signed >
0423 {
0424     typedef extra_operations_generic< Base, 2u, Signed > base_type;
0425     typedef typename base_type::storage_type storage_type;
0426 
0427     static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0428     {
0429         base_type::fence_before(order);
0430         storage_type old_val;
0431         __asm
0432         {
0433             mov ecx, storage
0434             movzx eax, word ptr [ecx]
0435             align 16
0436         again:
0437             mov edx, eax
0438             neg dx
0439             lock cmpxchg word ptr [ecx], dx
0440             jne again
0441             mov old_val, ax
0442         };
0443         base_type::fence_after(order);
0444         return old_val;
0445     }
0446 
0447     static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0448     {
0449         base_type::fence_before(order);
0450         storage_type new_val;
0451         __asm
0452         {
0453             mov ecx, storage
0454             movzx eax, word ptr [ecx]
0455             align 16
0456         again:
0457             mov edx, eax
0458             neg dx
0459             lock cmpxchg word ptr [ecx], dx
0460             jne again
0461             mov new_val, dx
0462         };
0463         base_type::fence_after(order);
0464         return new_val;
0465     }
0466 
0467     static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0468     {
0469         base_type::fence_before(order);
0470         bool result;
0471         __asm
0472         {
0473             mov ecx, storage
0474             movzx eax, word ptr [ecx]
0475             align 16
0476         again:
0477             mov edx, eax
0478             neg dx
0479             lock cmpxchg word ptr [ecx], dx
0480             jne again
0481             test dx, dx
0482             setnz result
0483         };
0484         base_type::fence_after(order);
0485         return result;
0486     }
0487 
0488     static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0489     {
0490         base_type::fence_before(order);
0491         __asm
0492         {
0493             mov ecx, storage
0494             movzx eax, word ptr [ecx]
0495             align 16
0496         again:
0497             mov edx, eax
0498             neg dx
0499             lock cmpxchg word ptr [ecx], dx
0500             jne again
0501         };
0502         base_type::fence_after(order);
0503     }
0504 
0505     static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0506     {
0507         base_type::fence_before(order);
0508         __asm
0509         {
0510             mov edi, storage
0511             movzx ecx, v
0512             xor edx, edx
0513             movzx eax, word ptr [edi]
0514             align 16
0515         again:
0516             mov dx, ax
0517             and dx, cx
0518             lock cmpxchg word ptr [edi], dx
0519             jne again
0520             mov v, dx
0521         };
0522         base_type::fence_after(order);
0523         return v;
0524     }
0525 
0526     static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0527     {
0528         base_type::fence_before(order);
0529         __asm
0530         {
0531             mov edi, storage
0532             movzx ecx, v
0533             xor edx, edx
0534             movzx eax, word ptr [edi]
0535             align 16
0536         again:
0537             mov dx, ax
0538             or dx, cx
0539             lock cmpxchg word ptr [edi], dx
0540             jne again
0541             mov v, dx
0542         };
0543         base_type::fence_after(order);
0544         return v;
0545     }
0546 
0547     static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0548     {
0549         base_type::fence_before(order);
0550         __asm
0551         {
0552             mov edi, storage
0553             movzx ecx, v
0554             xor edx, edx
0555             movzx eax, word ptr [edi]
0556             align 16
0557         again:
0558             mov dx, ax
0559             xor dx, cx
0560             lock cmpxchg word ptr [edi], dx
0561             jne again
0562             mov v, dx
0563         };
0564         base_type::fence_after(order);
0565         return v;
0566     }
0567 
0568     static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0569     {
0570         base_type::fence_before(order);
0571         storage_type old_val;
0572         __asm
0573         {
0574             mov ecx, storage
0575             movzx eax, word ptr [ecx]
0576             align 16
0577         again:
0578             mov edx, eax
0579             not dx
0580             lock cmpxchg word ptr [ecx], dx
0581             jne again
0582             mov old_val, ax
0583         };
0584         base_type::fence_after(order);
0585         return old_val;
0586     }
0587 
0588     static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0589     {
0590         base_type::fence_before(order);
0591         storage_type new_val;
0592         __asm
0593         {
0594             mov ecx, storage
0595             movzx eax, word ptr [ecx]
0596             align 16
0597         again:
0598             mov edx, eax
0599             not dx
0600             lock cmpxchg word ptr [ecx], dx
0601             jne again
0602             mov new_val, dx
0603         };
0604         base_type::fence_after(order);
0605         return new_val;
0606     }
0607 
0608     static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0609     {
0610         base_type::fence_before(order);
0611         bool result;
0612         __asm
0613         {
0614             mov ecx, storage
0615             movzx eax, word ptr [ecx]
0616             align 16
0617         again:
0618             mov edx, eax
0619             not dx
0620             lock cmpxchg word ptr [ecx], dx
0621             jne again
0622             test dx, dx
0623             setnz result
0624         };
0625         base_type::fence_after(order);
0626         return result;
0627     }
0628 
0629     static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0630     {
0631         base_type::fence_before(order);
0632         __asm
0633         {
0634             mov ecx, storage
0635             movzx eax, word ptr [ecx]
0636             align 16
0637         again:
0638             mov edx, eax
0639             not dx
0640             lock cmpxchg word ptr [ecx], dx
0641             jne again
0642         };
0643         base_type::fence_after(order);
0644     }
0645 
0646     static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0647     {
0648         base_type::fence_before(order);
0649         __asm
0650         {
0651             mov edx, storage
0652             movzx eax, v
0653             lock add word ptr [edx], ax
0654         };
0655         base_type::fence_after(order);
0656     }
0657 
0658     static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0659     {
0660         base_type::fence_before(order);
0661         __asm
0662         {
0663             mov edx, storage
0664             movzx eax, v
0665             lock sub word ptr [edx], ax
0666         };
0667         base_type::fence_after(order);
0668     }
0669 
0670     static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0671     {
0672         base_type::fence_before(order);
0673         __asm
0674         {
0675             mov edx, storage
0676             lock neg word ptr [edx]
0677         };
0678         base_type::fence_after(order);
0679     }
0680 
0681     static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0682     {
0683         base_type::fence_before(order);
0684         __asm
0685         {
0686             mov edx, storage
0687             movzx eax, v
0688             lock and word ptr [edx], ax
0689         };
0690         base_type::fence_after(order);
0691     }
0692 
0693     static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0694     {
0695         base_type::fence_before(order);
0696         __asm
0697         {
0698             mov edx, storage
0699             movzx eax, v
0700             lock or word ptr [edx], ax
0701         };
0702         base_type::fence_after(order);
0703     }
0704 
0705     static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0706     {
0707         base_type::fence_before(order);
0708         __asm
0709         {
0710             mov edx, storage
0711             movzx eax, v
0712             lock xor word ptr [edx], ax
0713         };
0714         base_type::fence_after(order);
0715     }
0716 
0717     static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0718     {
0719         base_type::fence_before(order);
0720         __asm
0721         {
0722             mov edx, storage
0723             lock not word ptr [edx]
0724         };
0725         base_type::fence_after(order);
0726     }
0727 
0728     static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0729     {
0730         base_type::fence_before(order);
0731         bool result;
0732         __asm
0733         {
0734             mov edx, storage
0735             movzx eax, v
0736             lock add word ptr [edx], ax
0737             setnz result
0738         };
0739         base_type::fence_after(order);
0740         return result;
0741     }
0742 
0743     static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0744     {
0745         base_type::fence_before(order);
0746         bool result;
0747         __asm
0748         {
0749             mov edx, storage
0750             movzx eax, v
0751             lock sub word ptr [edx], ax
0752             setnz result
0753         };
0754         base_type::fence_after(order);
0755         return result;
0756     }
0757 
0758     static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0759     {
0760         base_type::fence_before(order);
0761         bool result;
0762         __asm
0763         {
0764             mov edx, storage
0765             movzx eax, v
0766             lock and word ptr [edx], ax
0767             setnz result
0768         };
0769         base_type::fence_after(order);
0770         return result;
0771     }
0772 
0773     static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0774     {
0775         base_type::fence_before(order);
0776         bool result;
0777         __asm
0778         {
0779             mov edx, storage
0780             movzx eax, v
0781             lock or word ptr [edx], ax
0782             setnz result
0783         };
0784         base_type::fence_after(order);
0785         return result;
0786     }
0787 
0788     static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0789     {
0790         base_type::fence_before(order);
0791         bool result;
0792         __asm
0793         {
0794             mov edx, storage
0795             movzx eax, v
0796             lock xor word ptr [edx], ax
0797             setnz result
0798         };
0799         base_type::fence_after(order);
0800         return result;
0801     }
0802 
0803     static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
0804     {
0805         base_type::fence_before(order);
0806         bool result;
0807         __asm
0808         {
0809             mov edx, storage
0810             mov eax, bit_number
0811             lock bts word ptr [edx], ax
0812             setc result
0813         };
0814         base_type::fence_after(order);
0815         return result;
0816     }
0817 
0818     static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
0819     {
0820         base_type::fence_before(order);
0821         bool result;
0822         __asm
0823         {
0824             mov edx, storage
0825             mov eax, bit_number
0826             lock btr word ptr [edx], ax
0827             setc result
0828         };
0829         base_type::fence_after(order);
0830         return result;
0831     }
0832 
0833     static BOOST_FORCEINLINE bool bit_test_and_complement(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
0834     {
0835         base_type::fence_before(order);
0836         bool result;
0837         __asm
0838         {
0839             mov edx, storage
0840             mov eax, bit_number
0841             lock btc word ptr [edx], ax
0842             setc result
0843         };
0844         base_type::fence_after(order);
0845         return result;
0846     }
0847 };
0848 
0849 #endif // defined(_M_IX86)
0850 
0851 #if defined(_M_IX86) || (defined(BOOST_ATOMIC_INTERLOCKED_BTS) && defined(BOOST_ATOMIC_INTERLOCKED_BTR))
0852 
0853 template< typename Base, bool Signed >
0854 struct extra_operations< Base, 4u, Signed, true > :
0855     public extra_operations_generic< Base, 4u, Signed >
0856 {
0857     typedef extra_operations_generic< Base, 4u, Signed > base_type;
0858     typedef typename base_type::storage_type storage_type;
0859 
0860 #if defined(_M_IX86)
0861     static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0862     {
0863         base_type::fence_before(order);
0864         storage_type old_val;
0865         __asm
0866         {
0867             mov ecx, storage
0868             mov eax, dword ptr [ecx]
0869             align 16
0870         again:
0871             mov edx, eax
0872             neg edx
0873             lock cmpxchg dword ptr [ecx], edx
0874             jne again
0875             mov old_val, eax
0876         };
0877         base_type::fence_after(order);
0878         return old_val;
0879     }
0880 
0881     static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0882     {
0883         base_type::fence_before(order);
0884         storage_type new_val;
0885         __asm
0886         {
0887             mov ecx, storage
0888             mov eax, dword ptr [ecx]
0889             align 16
0890         again:
0891             mov edx, eax
0892             neg edx
0893             lock cmpxchg dword ptr [ecx], edx
0894             jne again
0895             mov new_val, edx
0896         };
0897         base_type::fence_after(order);
0898         return new_val;
0899     }
0900 
0901     static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0902     {
0903         base_type::fence_before(order);
0904         bool result;
0905         __asm
0906         {
0907             mov ecx, storage
0908             mov eax, dword ptr [ecx]
0909             align 16
0910         again:
0911             mov edx, eax
0912             neg edx
0913             lock cmpxchg dword ptr [ecx], edx
0914             jne again
0915             test edx, edx
0916             setnz result
0917         };
0918         base_type::fence_after(order);
0919         return result;
0920     }
0921 
0922     static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0923     {
0924         base_type::fence_before(order);
0925         __asm
0926         {
0927             mov ecx, storage
0928             mov eax, dword ptr [ecx]
0929             align 16
0930         again:
0931             mov edx, eax
0932             neg edx
0933             lock cmpxchg dword ptr [ecx], edx
0934             jne again
0935         };
0936         base_type::fence_after(order);
0937     }
0938 
0939     static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0940     {
0941         base_type::fence_before(order);
0942         __asm
0943         {
0944             mov edi, storage
0945             mov ecx, v
0946             xor edx, edx
0947             mov eax, dword ptr [edi]
0948             align 16
0949         again:
0950             mov edx, eax
0951             and edx, ecx
0952             lock cmpxchg dword ptr [edi], edx
0953             jne again
0954             mov v, edx
0955         };
0956         base_type::fence_after(order);
0957         return v;
0958     }
0959 
0960     static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0961     {
0962         base_type::fence_before(order);
0963         __asm
0964         {
0965             mov edi, storage
0966             mov ecx, v
0967             xor edx, edx
0968             mov eax, dword ptr [edi]
0969             align 16
0970         again:
0971             mov edx, eax
0972             or edx, ecx
0973             lock cmpxchg dword ptr [edi], edx
0974             jne again
0975             mov v, edx
0976         };
0977         base_type::fence_after(order);
0978         return v;
0979     }
0980 
0981     static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0982     {
0983         base_type::fence_before(order);
0984         __asm
0985         {
0986             mov edi, storage
0987             mov ecx, v
0988             xor edx, edx
0989             mov eax, dword ptr [edi]
0990             align 16
0991         again:
0992             mov edx, eax
0993             xor edx, ecx
0994             lock cmpxchg dword ptr [edi], edx
0995             jne again
0996             mov v, edx
0997         };
0998         base_type::fence_after(order);
0999         return v;
1000     }
1001 
1002     static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
1003     {
1004         base_type::fence_before(order);
1005         storage_type old_val;
1006         __asm
1007         {
1008             mov ecx, storage
1009             mov eax, dword ptr [ecx]
1010             align 16
1011         again:
1012             mov edx, eax
1013             not edx
1014             lock cmpxchg dword ptr [ecx], edx
1015             jne again
1016             mov old_val, eax
1017         };
1018         base_type::fence_after(order);
1019         return old_val;
1020     }
1021 
1022     static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
1023     {
1024         base_type::fence_before(order);
1025         storage_type new_val;
1026         __asm
1027         {
1028             mov ecx, storage
1029             mov eax, dword ptr [ecx]
1030             align 16
1031         again:
1032             mov edx, eax
1033             not edx
1034             lock cmpxchg dword ptr [ecx], edx
1035             jne again
1036             mov new_val, edx
1037         };
1038         base_type::fence_after(order);
1039         return new_val;
1040     }
1041 
1042     static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
1043     {
1044         base_type::fence_before(order);
1045         bool result;
1046         __asm
1047         {
1048             mov ecx, storage
1049             mov eax, dword ptr [ecx]
1050             align 16
1051         again:
1052             mov edx, eax
1053             not edx
1054             lock cmpxchg dword ptr [ecx], edx
1055             jne again
1056             test edx, edx
1057             setnz result
1058         };
1059         base_type::fence_after(order);
1060         return result;
1061     }
1062 
1063     static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
1064     {
1065         base_type::fence_before(order);
1066         __asm
1067         {
1068             mov ecx, storage
1069             mov eax, dword ptr [ecx]
1070             align 16
1071         again:
1072             mov edx, eax
1073             not edx
1074             lock cmpxchg dword ptr [ecx], edx
1075             jne again
1076         };
1077         base_type::fence_after(order);
1078     }
1079 
1080     static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
1081     {
1082         base_type::fence_before(order);
1083         __asm
1084         {
1085             mov edx, storage
1086             mov eax, v
1087             lock add dword ptr [edx], eax
1088         };
1089         base_type::fence_after(order);
1090     }
1091 
1092     static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
1093     {
1094         base_type::fence_before(order);
1095         __asm
1096         {
1097             mov edx, storage
1098             mov eax, v
1099             lock sub dword ptr [edx], eax
1100         };
1101         base_type::fence_after(order);
1102     }
1103 
1104     static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
1105     {
1106         base_type::fence_before(order);
1107         __asm
1108         {
1109             mov edx, storage
1110             lock neg dword ptr [edx]
1111         };
1112         base_type::fence_after(order);
1113     }
1114 
1115     static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
1116     {
1117         base_type::fence_before(order);
1118         __asm
1119         {
1120             mov edx, storage
1121             mov eax, v
1122             lock and dword ptr [edx], eax
1123         };
1124         base_type::fence_after(order);
1125     }
1126 
1127     static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
1128     {
1129         base_type::fence_before(order);
1130         __asm
1131         {
1132             mov edx, storage
1133             mov eax, v
1134             lock or dword ptr [edx], eax
1135         };
1136         base_type::fence_after(order);
1137     }
1138 
1139     static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
1140     {
1141         base_type::fence_before(order);
1142         __asm
1143         {
1144             mov edx, storage
1145             mov eax, v
1146             lock xor dword ptr [edx], eax
1147         };
1148         base_type::fence_after(order);
1149     }
1150 
1151     static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
1152     {
1153         base_type::fence_before(order);
1154         __asm
1155         {
1156             mov edx, storage
1157             lock not dword ptr [edx]
1158         };
1159         base_type::fence_after(order);
1160     }
1161 
1162     static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
1163     {
1164         base_type::fence_before(order);
1165         bool result;
1166         __asm
1167         {
1168             mov edx, storage
1169             mov eax, v
1170             lock add dword ptr [edx], eax
1171             setnz result
1172         };
1173         base_type::fence_after(order);
1174         return result;
1175     }
1176 
1177     static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
1178     {
1179         base_type::fence_before(order);
1180         bool result;
1181         __asm
1182         {
1183             mov edx, storage
1184             mov eax, v
1185             lock sub dword ptr [edx], eax
1186             setnz result
1187         };
1188         base_type::fence_after(order);
1189         return result;
1190     }
1191 
1192     static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
1193     {
1194         base_type::fence_before(order);
1195         bool result;
1196         __asm
1197         {
1198             mov edx, storage
1199             mov eax, v
1200             lock and dword ptr [edx], eax
1201             setnz result
1202         };
1203         base_type::fence_after(order);
1204         return result;
1205     }
1206 
1207     static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
1208     {
1209         base_type::fence_before(order);
1210         bool result;
1211         __asm
1212         {
1213             mov edx, storage
1214             mov eax, v
1215             lock or dword ptr [edx], eax
1216             setnz result
1217         };
1218         base_type::fence_after(order);
1219         return result;
1220     }
1221 
1222     static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
1223     {
1224         base_type::fence_before(order);
1225         bool result;
1226         __asm
1227         {
1228             mov edx, storage
1229             mov eax, v
1230             lock xor dword ptr [edx], eax
1231             setnz result
1232         };
1233         base_type::fence_after(order);
1234         return result;
1235     }
1236 
1237     static BOOST_FORCEINLINE bool bit_test_and_complement(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
1238     {
1239         base_type::fence_before(order);
1240         bool result;
1241         __asm
1242         {
1243             mov edx, storage
1244             mov eax, bit_number
1245             lock btc dword ptr [edx], eax
1246             setc result
1247         };
1248         base_type::fence_after(order);
1249         return result;
1250     }
1251 #endif // defined(_M_IX86)
1252 
1253 #if defined(BOOST_ATOMIC_INTERLOCKED_BTS)
1254     static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order) BOOST_NOEXCEPT
1255     {
1256         return !!BOOST_ATOMIC_INTERLOCKED_BTS(&storage, bit_number);
1257     }
1258 #elif defined(_M_IX86)
1259     static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
1260     {
1261         base_type::fence_before(order);
1262         bool result;
1263         __asm
1264         {
1265             mov edx, storage
1266             mov eax, bit_number
1267             lock bts dword ptr [edx], eax
1268             setc result
1269         };
1270         base_type::fence_after(order);
1271         return result;
1272     }
1273 #endif
1274 
1275 #if defined(BOOST_ATOMIC_INTERLOCKED_BTR)
1276     static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order) BOOST_NOEXCEPT
1277     {
1278         return !!BOOST_ATOMIC_INTERLOCKED_BTR(&storage, bit_number);
1279     }
1280 #elif defined(_M_IX86)
1281     static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
1282     {
1283         base_type::fence_before(order);
1284         bool result;
1285         __asm
1286         {
1287             mov edx, storage
1288             mov eax, bit_number
1289             lock btr dword ptr [edx], eax
1290             setc result
1291         };
1292         base_type::fence_after(order);
1293         return result;
1294     }
1295 #endif
1296 };
1297 
1298 #endif // defined(_M_IX86) || (defined(BOOST_ATOMIC_INTERLOCKED_BTS) && defined(BOOST_ATOMIC_INTERLOCKED_BTR))
1299 
1300 #if defined(BOOST_ATOMIC_INTERLOCKED_BTS64) && defined(BOOST_ATOMIC_INTERLOCKED_BTR64)
1301 
1302 template< typename Base, bool Signed >
1303 struct extra_operations< Base, 8u, Signed, true > :
1304     public extra_operations_generic< Base, 8u, Signed >
1305 {
1306     typedef extra_operations_generic< Base, 8u, Signed > base_type;
1307     typedef typename base_type::storage_type storage_type;
1308 
1309     static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
1310     {
1311         return !!BOOST_ATOMIC_INTERLOCKED_BTS64(&storage, bit_number);
1312     }
1313 
1314     static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
1315     {
1316         return !!BOOST_ATOMIC_INTERLOCKED_BTR64(&storage, bit_number);
1317     }
1318 };
1319 
1320 #endif // defined(BOOST_ATOMIC_INTERLOCKED_BTS64) && defined(BOOST_ATOMIC_INTERLOCKED_BTR64)
1321 
1322 } // namespace detail
1323 } // namespace atomics
1324 } // namespace boost
1325 
1326 #include <boost/atomic/detail/footer.hpp>
1327 
1328 #endif // BOOST_ATOMIC_DETAIL_EXTRA_OPS_MSVC_X86_HPP_INCLUDED_