extra_ops_msvc_x86.hpp 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301
  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_