extra_ops_msvc_x86.hpp 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302
  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. #ifndef BOOST_ATOMIC_DETAIL_EXTRA_OPS_MSVC_X86_HPP_INCLUDED_
  14. #define BOOST_ATOMIC_DETAIL_EXTRA_OPS_MSVC_X86_HPP_INCLUDED_
  15. #include <cstddef>
  16. #include <boost/memory_order.hpp>
  17. #include <boost/atomic/detail/config.hpp>
  18. #include <boost/atomic/detail/interlocked.hpp>
  19. #include <boost/atomic/detail/storage_type.hpp>
  20. #include <boost/atomic/detail/extra_operations_fwd.hpp>
  21. #include <boost/atomic/detail/extra_ops_generic.hpp>
  22. #include <boost/atomic/capabilities.hpp>
  23. #ifdef BOOST_HAS_PRAGMA_ONCE
  24. #pragma once
  25. #endif
  26. #if defined(BOOST_MSVC)
  27. #pragma warning(push)
  28. // frame pointer register 'ebx' modified by inline assembly code
  29. #pragma warning(disable: 4731)
  30. #endif
  31. namespace boost {
  32. namespace atomics {
  33. namespace detail {
  34. #if defined(_M_IX86) || (defined(BOOST_ATOMIC_INTERLOCKED_BTS) && defined(BOOST_ATOMIC_INTERLOCKED_BTR))
  35. template< typename Base, std::size_t Size, bool Signed >
  36. struct msvc_x86_extra_operations_common :
  37. public generic_extra_operations< Base, Size, Signed >
  38. {
  39. typedef generic_extra_operations< Base, Size, Signed > base_type;
  40. typedef typename base_type::storage_type storage_type;
  41. #if defined(BOOST_ATOMIC_INTERLOCKED_BTS)
  42. static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order) BOOST_NOEXCEPT
  43. {
  44. return !!BOOST_ATOMIC_INTERLOCKED_BTS(&storage, bit_number);
  45. }
  46. #else
  47. static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
  48. {
  49. base_type::fence_before(order);
  50. bool result;
  51. __asm
  52. {
  53. mov edx, storage
  54. mov eax, bit_number
  55. lock bts [edx], eax
  56. setc result
  57. };
  58. base_type::fence_after(order);
  59. return result;
  60. }
  61. #endif
  62. #if defined(BOOST_ATOMIC_INTERLOCKED_BTR)
  63. static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order) BOOST_NOEXCEPT
  64. {
  65. return !!BOOST_ATOMIC_INTERLOCKED_BTR(&storage, bit_number);
  66. }
  67. #else
  68. static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
  69. {
  70. base_type::fence_before(order);
  71. bool result;
  72. __asm
  73. {
  74. mov edx, storage
  75. mov eax, bit_number
  76. lock btr [edx], eax
  77. setc result
  78. };
  79. base_type::fence_after(order);
  80. return result;
  81. }
  82. #endif
  83. #if defined(_M_IX86)
  84. static BOOST_FORCEINLINE bool bit_test_and_complement(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
  85. {
  86. base_type::fence_before(order);
  87. bool result;
  88. __asm
  89. {
  90. mov edx, storage
  91. mov eax, bit_number
  92. lock btc [edx], eax
  93. setc result
  94. };
  95. base_type::fence_after(order);
  96. return result;
  97. }
  98. #endif
  99. };
  100. template< typename Base, bool Signed >
  101. struct extra_operations< Base, 1u, Signed, true > :
  102. public msvc_x86_extra_operations_common< Base, 1u, Signed >
  103. {
  104. typedef msvc_x86_extra_operations_common< Base, 1u, Signed > base_type;
  105. typedef typename base_type::storage_type storage_type;
  106. #if defined(_M_IX86)
  107. static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
  108. {
  109. base_type::fence_before(order);
  110. storage_type old_val;
  111. __asm
  112. {
  113. mov ecx, storage
  114. movzx eax, byte ptr [ecx]
  115. align 16
  116. again:
  117. mov edx, eax
  118. neg dl
  119. lock cmpxchg byte ptr [ecx], dl
  120. jne again
  121. mov old_val, al
  122. };
  123. base_type::fence_after(order);
  124. return old_val;
  125. }
  126. static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
  127. {
  128. base_type::fence_before(order);
  129. storage_type new_val;
  130. __asm
  131. {
  132. mov ecx, storage
  133. movzx eax, byte ptr [ecx]
  134. align 16
  135. again:
  136. mov edx, eax
  137. neg dl
  138. lock cmpxchg byte ptr [ecx], dl
  139. jne again
  140. mov new_val, dl
  141. };
  142. base_type::fence_after(order);
  143. return new_val;
  144. }
  145. static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
  146. {
  147. base_type::fence_before(order);
  148. bool result;
  149. __asm
  150. {
  151. mov ecx, storage
  152. movzx eax, byte ptr [ecx]
  153. align 16
  154. again:
  155. mov edx, eax
  156. neg dl
  157. lock cmpxchg byte ptr [ecx], dl
  158. jne again
  159. test dl, dl
  160. setnz result
  161. };
  162. base_type::fence_after(order);
  163. return result;
  164. }
  165. static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
  166. {
  167. base_type::fence_before(order);
  168. __asm
  169. {
  170. mov ecx, storage
  171. movzx eax, byte ptr [ecx]
  172. align 16
  173. again:
  174. mov edx, eax
  175. neg dl
  176. lock cmpxchg byte ptr [ecx], dl
  177. jne again
  178. };
  179. base_type::fence_after(order);
  180. }
  181. static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  182. {
  183. base_type::fence_before(order);
  184. __asm
  185. {
  186. mov edi, storage
  187. movzx ecx, v
  188. xor edx, edx
  189. movzx eax, byte ptr [edi]
  190. align 16
  191. again:
  192. mov dl, al
  193. and dl, cl
  194. lock cmpxchg byte ptr [edi], dl
  195. jne again
  196. mov v, dl
  197. };
  198. base_type::fence_after(order);
  199. return v;
  200. }
  201. static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  202. {
  203. base_type::fence_before(order);
  204. __asm
  205. {
  206. mov edi, storage
  207. movzx ecx, v
  208. xor edx, edx
  209. movzx eax, byte ptr [edi]
  210. align 16
  211. again:
  212. mov dl, al
  213. or dl, cl
  214. lock cmpxchg byte ptr [edi], dl
  215. jne again
  216. mov v, dl
  217. };
  218. base_type::fence_after(order);
  219. return v;
  220. }
  221. static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  222. {
  223. base_type::fence_before(order);
  224. __asm
  225. {
  226. mov edi, storage
  227. movzx ecx, v
  228. xor edx, edx
  229. movzx eax, byte ptr [edi]
  230. align 16
  231. again:
  232. mov dl, al
  233. xor dl, cl
  234. lock cmpxchg byte ptr [edi], dl
  235. jne again
  236. mov v, dl
  237. };
  238. base_type::fence_after(order);
  239. return v;
  240. }
  241. static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
  242. {
  243. base_type::fence_before(order);
  244. storage_type old_val;
  245. __asm
  246. {
  247. mov ecx, storage
  248. movzx eax, byte ptr [ecx]
  249. align 16
  250. again:
  251. mov edx, eax
  252. not dl
  253. lock cmpxchg byte ptr [ecx], dl
  254. jne again
  255. mov old_val, al
  256. };
  257. base_type::fence_after(order);
  258. return old_val;
  259. }
  260. static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
  261. {
  262. base_type::fence_before(order);
  263. storage_type new_val;
  264. __asm
  265. {
  266. mov ecx, storage
  267. movzx eax, byte ptr [ecx]
  268. align 16
  269. again:
  270. mov edx, eax
  271. not dl
  272. lock cmpxchg byte ptr [ecx], dl
  273. jne again
  274. mov new_val, dl
  275. };
  276. base_type::fence_after(order);
  277. return new_val;
  278. }
  279. static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
  280. {
  281. base_type::fence_before(order);
  282. bool result;
  283. __asm
  284. {
  285. mov ecx, storage
  286. movzx eax, byte ptr [ecx]
  287. align 16
  288. again:
  289. mov edx, eax
  290. not dl
  291. lock cmpxchg byte ptr [ecx], dl
  292. jne again
  293. test dl, dl
  294. setnz result
  295. };
  296. base_type::fence_after(order);
  297. return result;
  298. }
  299. static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
  300. {
  301. base_type::fence_before(order);
  302. __asm
  303. {
  304. mov ecx, storage
  305. movzx eax, byte ptr [ecx]
  306. align 16
  307. again:
  308. mov edx, eax
  309. not dl
  310. lock cmpxchg byte ptr [ecx], dl
  311. jne again
  312. };
  313. base_type::fence_after(order);
  314. }
  315. static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  316. {
  317. base_type::fence_before(order);
  318. __asm
  319. {
  320. mov edx, storage
  321. movzx eax, v
  322. lock add byte ptr [edx], al
  323. };
  324. base_type::fence_after(order);
  325. }
  326. static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  327. {
  328. base_type::fence_before(order);
  329. __asm
  330. {
  331. mov edx, storage
  332. movzx eax, v
  333. lock sub byte ptr [edx], al
  334. };
  335. base_type::fence_after(order);
  336. }
  337. static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
  338. {
  339. base_type::fence_before(order);
  340. __asm
  341. {
  342. mov edx, storage
  343. lock neg byte ptr [edx]
  344. };
  345. base_type::fence_after(order);
  346. }
  347. static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  348. {
  349. base_type::fence_before(order);
  350. __asm
  351. {
  352. mov edx, storage
  353. movzx eax, v
  354. lock and byte ptr [edx], al
  355. };
  356. base_type::fence_after(order);
  357. }
  358. static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  359. {
  360. base_type::fence_before(order);
  361. __asm
  362. {
  363. mov edx, storage
  364. movzx eax, v
  365. lock or byte ptr [edx], al
  366. };
  367. base_type::fence_after(order);
  368. }
  369. static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  370. {
  371. base_type::fence_before(order);
  372. __asm
  373. {
  374. mov edx, storage
  375. movzx eax, v
  376. lock xor byte ptr [edx], al
  377. };
  378. base_type::fence_after(order);
  379. }
  380. static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
  381. {
  382. base_type::fence_before(order);
  383. __asm
  384. {
  385. mov edx, storage
  386. lock not byte ptr [edx]
  387. };
  388. base_type::fence_after(order);
  389. }
  390. static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  391. {
  392. base_type::fence_before(order);
  393. bool result;
  394. __asm
  395. {
  396. mov edx, storage
  397. movzx eax, v
  398. lock add byte ptr [edx], al
  399. setnz result
  400. };
  401. base_type::fence_after(order);
  402. return result;
  403. }
  404. static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  405. {
  406. base_type::fence_before(order);
  407. bool result;
  408. __asm
  409. {
  410. mov edx, storage
  411. movzx eax, v
  412. lock sub byte ptr [edx], al
  413. setnz result
  414. };
  415. base_type::fence_after(order);
  416. return result;
  417. }
  418. static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  419. {
  420. base_type::fence_before(order);
  421. bool result;
  422. __asm
  423. {
  424. mov edx, storage
  425. movzx eax, v
  426. lock and byte ptr [edx], al
  427. setnz result
  428. };
  429. base_type::fence_after(order);
  430. return result;
  431. }
  432. static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  433. {
  434. base_type::fence_before(order);
  435. bool result;
  436. __asm
  437. {
  438. mov edx, storage
  439. movzx eax, v
  440. lock or byte ptr [edx], al
  441. setnz result
  442. };
  443. base_type::fence_after(order);
  444. return result;
  445. }
  446. static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  447. {
  448. base_type::fence_before(order);
  449. bool result;
  450. __asm
  451. {
  452. mov edx, storage
  453. movzx eax, v
  454. lock xor byte ptr [edx], al
  455. setnz result
  456. };
  457. base_type::fence_after(order);
  458. return result;
  459. }
  460. #endif // defined(_M_IX86)
  461. };
  462. template< typename Base, bool Signed >
  463. struct extra_operations< Base, 2u, Signed, true > :
  464. public msvc_x86_extra_operations_common< Base, 2u, Signed >
  465. {
  466. typedef msvc_x86_extra_operations_common< Base, 2u, Signed > base_type;
  467. typedef typename base_type::storage_type storage_type;
  468. #if defined(_M_IX86)
  469. static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
  470. {
  471. base_type::fence_before(order);
  472. storage_type old_val;
  473. __asm
  474. {
  475. mov ecx, storage
  476. movzx eax, word ptr [ecx]
  477. align 16
  478. again:
  479. mov edx, eax
  480. neg dx
  481. lock cmpxchg word ptr [ecx], dx
  482. jne again
  483. mov old_val, ax
  484. };
  485. base_type::fence_after(order);
  486. return old_val;
  487. }
  488. static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
  489. {
  490. base_type::fence_before(order);
  491. storage_type new_val;
  492. __asm
  493. {
  494. mov ecx, storage
  495. movzx eax, word ptr [ecx]
  496. align 16
  497. again:
  498. mov edx, eax
  499. neg dx
  500. lock cmpxchg word ptr [ecx], dx
  501. jne again
  502. mov new_val, dx
  503. };
  504. base_type::fence_after(order);
  505. return new_val;
  506. }
  507. static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
  508. {
  509. base_type::fence_before(order);
  510. bool result;
  511. __asm
  512. {
  513. mov ecx, storage
  514. movzx eax, word ptr [ecx]
  515. align 16
  516. again:
  517. mov edx, eax
  518. neg dx
  519. lock cmpxchg word ptr [ecx], dx
  520. jne again
  521. test dx, dx
  522. setnz result
  523. };
  524. base_type::fence_after(order);
  525. return result;
  526. }
  527. static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
  528. {
  529. base_type::fence_before(order);
  530. __asm
  531. {
  532. mov ecx, storage
  533. movzx eax, word ptr [ecx]
  534. align 16
  535. again:
  536. mov edx, eax
  537. neg dx
  538. lock cmpxchg word ptr [ecx], dx
  539. jne again
  540. };
  541. base_type::fence_after(order);
  542. }
  543. static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  544. {
  545. base_type::fence_before(order);
  546. __asm
  547. {
  548. mov edi, storage
  549. movzx ecx, v
  550. xor edx, edx
  551. movzx eax, word ptr [edi]
  552. align 16
  553. again:
  554. mov dx, ax
  555. and dx, cx
  556. lock cmpxchg word ptr [edi], dx
  557. jne again
  558. mov v, dx
  559. };
  560. base_type::fence_after(order);
  561. return v;
  562. }
  563. static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  564. {
  565. base_type::fence_before(order);
  566. __asm
  567. {
  568. mov edi, storage
  569. movzx ecx, v
  570. xor edx, edx
  571. movzx eax, word ptr [edi]
  572. align 16
  573. again:
  574. mov dx, ax
  575. or dx, cx
  576. lock cmpxchg word ptr [edi], dx
  577. jne again
  578. mov v, dx
  579. };
  580. base_type::fence_after(order);
  581. return v;
  582. }
  583. static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  584. {
  585. base_type::fence_before(order);
  586. __asm
  587. {
  588. mov edi, storage
  589. movzx ecx, v
  590. xor edx, edx
  591. movzx eax, word ptr [edi]
  592. align 16
  593. again:
  594. mov dx, ax
  595. xor dx, cx
  596. lock cmpxchg word ptr [edi], dx
  597. jne again
  598. mov v, dx
  599. };
  600. base_type::fence_after(order);
  601. return v;
  602. }
  603. static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
  604. {
  605. base_type::fence_before(order);
  606. storage_type old_val;
  607. __asm
  608. {
  609. mov ecx, storage
  610. movzx eax, word ptr [ecx]
  611. align 16
  612. again:
  613. mov edx, eax
  614. not dx
  615. lock cmpxchg word ptr [ecx], dx
  616. jne again
  617. mov old_val, ax
  618. };
  619. base_type::fence_after(order);
  620. return old_val;
  621. }
  622. static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
  623. {
  624. base_type::fence_before(order);
  625. storage_type new_val;
  626. __asm
  627. {
  628. mov ecx, storage
  629. movzx eax, word ptr [ecx]
  630. align 16
  631. again:
  632. mov edx, eax
  633. not dx
  634. lock cmpxchg word ptr [ecx], dx
  635. jne again
  636. mov new_val, dx
  637. };
  638. base_type::fence_after(order);
  639. return new_val;
  640. }
  641. static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
  642. {
  643. base_type::fence_before(order);
  644. bool result;
  645. __asm
  646. {
  647. mov ecx, storage
  648. movzx eax, word ptr [ecx]
  649. align 16
  650. again:
  651. mov edx, eax
  652. not dx
  653. lock cmpxchg word ptr [ecx], dx
  654. jne again
  655. test dx, dx
  656. setnz result
  657. };
  658. base_type::fence_after(order);
  659. return result;
  660. }
  661. static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
  662. {
  663. base_type::fence_before(order);
  664. __asm
  665. {
  666. mov ecx, storage
  667. movzx eax, word ptr [ecx]
  668. align 16
  669. again:
  670. mov edx, eax
  671. not dx
  672. lock cmpxchg word ptr [ecx], dx
  673. jne again
  674. };
  675. base_type::fence_after(order);
  676. }
  677. static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  678. {
  679. base_type::fence_before(order);
  680. __asm
  681. {
  682. mov edx, storage
  683. movzx eax, v
  684. lock add word ptr [edx], ax
  685. };
  686. base_type::fence_after(order);
  687. }
  688. static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  689. {
  690. base_type::fence_before(order);
  691. __asm
  692. {
  693. mov edx, storage
  694. movzx eax, v
  695. lock sub word ptr [edx], ax
  696. };
  697. base_type::fence_after(order);
  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 word ptr [edx]
  706. };
  707. base_type::fence_after(order);
  708. }
  709. static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  710. {
  711. base_type::fence_before(order);
  712. __asm
  713. {
  714. mov edx, storage
  715. movzx eax, v
  716. lock and word ptr [edx], ax
  717. };
  718. base_type::fence_after(order);
  719. }
  720. static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  721. {
  722. base_type::fence_before(order);
  723. __asm
  724. {
  725. mov edx, storage
  726. movzx eax, v
  727. lock or word ptr [edx], ax
  728. };
  729. base_type::fence_after(order);
  730. }
  731. static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  732. {
  733. base_type::fence_before(order);
  734. __asm
  735. {
  736. mov edx, storage
  737. movzx eax, v
  738. lock xor word ptr [edx], ax
  739. };
  740. base_type::fence_after(order);
  741. }
  742. static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
  743. {
  744. base_type::fence_before(order);
  745. __asm
  746. {
  747. mov edx, storage
  748. lock not word ptr [edx]
  749. };
  750. base_type::fence_after(order);
  751. }
  752. static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  753. {
  754. base_type::fence_before(order);
  755. bool result;
  756. __asm
  757. {
  758. mov edx, storage
  759. movzx eax, v
  760. lock add word ptr [edx], ax
  761. setnz result
  762. };
  763. base_type::fence_after(order);
  764. return result;
  765. }
  766. static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  767. {
  768. base_type::fence_before(order);
  769. bool result;
  770. __asm
  771. {
  772. mov edx, storage
  773. movzx eax, v
  774. lock sub word ptr [edx], ax
  775. setnz result
  776. };
  777. base_type::fence_after(order);
  778. return result;
  779. }
  780. static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  781. {
  782. base_type::fence_before(order);
  783. bool result;
  784. __asm
  785. {
  786. mov edx, storage
  787. movzx eax, v
  788. lock and word ptr [edx], ax
  789. setnz result
  790. };
  791. base_type::fence_after(order);
  792. return result;
  793. }
  794. static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  795. {
  796. base_type::fence_before(order);
  797. bool result;
  798. __asm
  799. {
  800. mov edx, storage
  801. movzx eax, v
  802. lock or word ptr [edx], ax
  803. setnz result
  804. };
  805. base_type::fence_after(order);
  806. return result;
  807. }
  808. static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  809. {
  810. base_type::fence_before(order);
  811. bool result;
  812. __asm
  813. {
  814. mov edx, storage
  815. movzx eax, v
  816. lock xor word ptr [edx], ax
  817. setnz result
  818. };
  819. base_type::fence_after(order);
  820. return result;
  821. }
  822. #endif // defined(_M_IX86)
  823. };
  824. template< typename Base, bool Signed >
  825. struct extra_operations< Base, 4u, Signed, true > :
  826. public msvc_x86_extra_operations_common< Base, 4u, Signed >
  827. {
  828. typedef msvc_x86_extra_operations_common< Base, 4u, Signed > base_type;
  829. typedef typename base_type::storage_type storage_type;
  830. #if defined(_M_IX86)
  831. static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
  832. {
  833. base_type::fence_before(order);
  834. storage_type old_val;
  835. __asm
  836. {
  837. mov ecx, storage
  838. mov eax, dword ptr [ecx]
  839. align 16
  840. again:
  841. mov edx, eax
  842. neg edx
  843. lock cmpxchg dword ptr [ecx], edx
  844. jne again
  845. mov old_val, eax
  846. };
  847. base_type::fence_after(order);
  848. return old_val;
  849. }
  850. static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
  851. {
  852. base_type::fence_before(order);
  853. storage_type new_val;
  854. __asm
  855. {
  856. mov ecx, storage
  857. mov eax, dword ptr [ecx]
  858. align 16
  859. again:
  860. mov edx, eax
  861. neg edx
  862. lock cmpxchg dword ptr [ecx], edx
  863. jne again
  864. mov new_val, edx
  865. };
  866. base_type::fence_after(order);
  867. return new_val;
  868. }
  869. static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
  870. {
  871. base_type::fence_before(order);
  872. bool result;
  873. __asm
  874. {
  875. mov ecx, storage
  876. mov eax, dword ptr [ecx]
  877. align 16
  878. again:
  879. mov edx, eax
  880. neg edx
  881. lock cmpxchg dword ptr [ecx], edx
  882. jne again
  883. test edx, edx
  884. setnz result
  885. };
  886. base_type::fence_after(order);
  887. return result;
  888. }
  889. static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
  890. {
  891. base_type::fence_before(order);
  892. __asm
  893. {
  894. mov ecx, storage
  895. mov eax, dword ptr [ecx]
  896. align 16
  897. again:
  898. mov edx, eax
  899. neg edx
  900. lock cmpxchg dword ptr [ecx], edx
  901. jne again
  902. };
  903. base_type::fence_after(order);
  904. }
  905. static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  906. {
  907. base_type::fence_before(order);
  908. __asm
  909. {
  910. mov edi, storage
  911. mov ecx, v
  912. xor edx, edx
  913. mov eax, dword ptr [edi]
  914. align 16
  915. again:
  916. mov edx, eax
  917. and edx, ecx
  918. lock cmpxchg dword ptr [edi], edx
  919. jne again
  920. mov v, edx
  921. };
  922. base_type::fence_after(order);
  923. return v;
  924. }
  925. static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  926. {
  927. base_type::fence_before(order);
  928. __asm
  929. {
  930. mov edi, storage
  931. mov ecx, v
  932. xor edx, edx
  933. mov eax, dword ptr [edi]
  934. align 16
  935. again:
  936. mov edx, eax
  937. or edx, ecx
  938. lock cmpxchg dword ptr [edi], edx
  939. jne again
  940. mov v, edx
  941. };
  942. base_type::fence_after(order);
  943. return v;
  944. }
  945. static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  946. {
  947. base_type::fence_before(order);
  948. __asm
  949. {
  950. mov edi, storage
  951. mov ecx, v
  952. xor edx, edx
  953. mov eax, dword ptr [edi]
  954. align 16
  955. again:
  956. mov edx, eax
  957. xor edx, ecx
  958. lock cmpxchg dword ptr [edi], edx
  959. jne again
  960. mov v, edx
  961. };
  962. base_type::fence_after(order);
  963. return v;
  964. }
  965. static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
  966. {
  967. base_type::fence_before(order);
  968. storage_type old_val;
  969. __asm
  970. {
  971. mov ecx, storage
  972. mov eax, dword ptr [ecx]
  973. align 16
  974. again:
  975. mov edx, eax
  976. not edx
  977. lock cmpxchg dword ptr [ecx], edx
  978. jne again
  979. mov old_val, eax
  980. };
  981. base_type::fence_after(order);
  982. return old_val;
  983. }
  984. static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
  985. {
  986. base_type::fence_before(order);
  987. storage_type new_val;
  988. __asm
  989. {
  990. mov ecx, storage
  991. mov eax, dword ptr [ecx]
  992. align 16
  993. again:
  994. mov edx, eax
  995. not edx
  996. lock cmpxchg dword ptr [ecx], edx
  997. jne again
  998. mov new_val, edx
  999. };
  1000. base_type::fence_after(order);
  1001. return new_val;
  1002. }
  1003. static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
  1004. {
  1005. base_type::fence_before(order);
  1006. bool result;
  1007. __asm
  1008. {
  1009. mov ecx, storage
  1010. mov eax, dword ptr [ecx]
  1011. align 16
  1012. again:
  1013. mov edx, eax
  1014. not edx
  1015. lock cmpxchg dword ptr [ecx], edx
  1016. jne again
  1017. test edx, edx
  1018. setnz result
  1019. };
  1020. base_type::fence_after(order);
  1021. return result;
  1022. }
  1023. static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
  1024. {
  1025. base_type::fence_before(order);
  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. };
  1037. base_type::fence_after(order);
  1038. }
  1039. static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  1040. {
  1041. base_type::fence_before(order);
  1042. __asm
  1043. {
  1044. mov edx, storage
  1045. mov eax, v
  1046. lock add dword ptr [edx], eax
  1047. };
  1048. base_type::fence_after(order);
  1049. }
  1050. static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  1051. {
  1052. base_type::fence_before(order);
  1053. __asm
  1054. {
  1055. mov edx, storage
  1056. mov eax, v
  1057. lock sub dword ptr [edx], eax
  1058. };
  1059. base_type::fence_after(order);
  1060. }
  1061. static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
  1062. {
  1063. base_type::fence_before(order);
  1064. __asm
  1065. {
  1066. mov edx, storage
  1067. lock neg dword ptr [edx]
  1068. };
  1069. base_type::fence_after(order);
  1070. }
  1071. static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  1072. {
  1073. base_type::fence_before(order);
  1074. __asm
  1075. {
  1076. mov edx, storage
  1077. mov eax, v
  1078. lock and dword ptr [edx], eax
  1079. };
  1080. base_type::fence_after(order);
  1081. }
  1082. static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  1083. {
  1084. base_type::fence_before(order);
  1085. __asm
  1086. {
  1087. mov edx, storage
  1088. mov eax, v
  1089. lock or dword ptr [edx], eax
  1090. };
  1091. base_type::fence_after(order);
  1092. }
  1093. static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  1094. {
  1095. base_type::fence_before(order);
  1096. __asm
  1097. {
  1098. mov edx, storage
  1099. mov eax, v
  1100. lock xor dword ptr [edx], eax
  1101. };
  1102. base_type::fence_after(order);
  1103. }
  1104. static BOOST_FORCEINLINE void opaque_complement(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 not dword ptr [edx]
  1111. };
  1112. base_type::fence_after(order);
  1113. }
  1114. static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  1115. {
  1116. base_type::fence_before(order);
  1117. bool result;
  1118. __asm
  1119. {
  1120. mov edx, storage
  1121. mov eax, v
  1122. lock add dword ptr [edx], eax
  1123. setnz result
  1124. };
  1125. base_type::fence_after(order);
  1126. return result;
  1127. }
  1128. static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  1129. {
  1130. base_type::fence_before(order);
  1131. bool result;
  1132. __asm
  1133. {
  1134. mov edx, storage
  1135. mov eax, v
  1136. lock sub dword ptr [edx], eax
  1137. setnz result
  1138. };
  1139. base_type::fence_after(order);
  1140. return result;
  1141. }
  1142. static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  1143. {
  1144. base_type::fence_before(order);
  1145. bool result;
  1146. __asm
  1147. {
  1148. mov edx, storage
  1149. mov eax, v
  1150. lock and dword ptr [edx], eax
  1151. setnz result
  1152. };
  1153. base_type::fence_after(order);
  1154. return result;
  1155. }
  1156. static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  1157. {
  1158. base_type::fence_before(order);
  1159. bool result;
  1160. __asm
  1161. {
  1162. mov edx, storage
  1163. mov eax, v
  1164. lock or dword ptr [edx], eax
  1165. setnz result
  1166. };
  1167. base_type::fence_after(order);
  1168. return result;
  1169. }
  1170. static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
  1171. {
  1172. base_type::fence_before(order);
  1173. bool result;
  1174. __asm
  1175. {
  1176. mov edx, storage
  1177. mov eax, v
  1178. lock xor dword ptr [edx], eax
  1179. setnz result
  1180. };
  1181. base_type::fence_after(order);
  1182. return result;
  1183. }
  1184. #endif // defined(_M_IX86)
  1185. };
  1186. #endif // defined(_M_IX86) || (defined(BOOST_ATOMIC_INTERLOCKED_BTS) && defined(BOOST_ATOMIC_INTERLOCKED_BTR))
  1187. #if defined(BOOST_ATOMIC_INTERLOCKED_BTS64) && defined(BOOST_ATOMIC_INTERLOCKED_BTR64)
  1188. template< typename Base, bool Signed >
  1189. struct extra_operations< Base, 8u, Signed, true > :
  1190. public generic_extra_operations< Base, 8u, Signed >
  1191. {
  1192. typedef generic_extra_operations< Base, 8u, Signed > base_type;
  1193. typedef typename base_type::storage_type storage_type;
  1194. static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
  1195. {
  1196. return !!BOOST_ATOMIC_INTERLOCKED_BTS64(&storage, bit_number);
  1197. }
  1198. static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
  1199. {
  1200. return !!BOOST_ATOMIC_INTERLOCKED_BTR64(&storage, bit_number);
  1201. }
  1202. };
  1203. #endif // defined(BOOST_ATOMIC_INTERLOCKED_BTS64) && defined(BOOST_ATOMIC_INTERLOCKED_BTR64)
  1204. } // namespace detail
  1205. } // namespace atomics
  1206. } // namespace boost
  1207. #if defined(BOOST_MSVC)
  1208. #pragma warning(pop)
  1209. #endif
  1210. #endif // BOOST_ATOMIC_DETAIL_EXTRA_OPS_MSVC_X86_HPP_INCLUDED_