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) 2015 Andrey Semashev 7 */ 8 /*! 9 * \file atomic/detail/extra_ops_gcc_x86.hpp 10 * 11 * This header contains implementation of the extra atomic operations for x86. 12 */ 13 14 #ifndef BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_X86_HPP_INCLUDED_ 15 #define BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_X86_HPP_INCLUDED_ 16 17 #include <cstddef> 18 #include <boost/memory_order.hpp> 19 #include <boost/atomic/detail/config.hpp> 20 #include <boost/atomic/detail/storage_type.hpp> 21 #include <boost/atomic/detail/extra_operations_fwd.hpp> 22 #include <boost/atomic/capabilities.hpp> 23 24 #ifdef BOOST_HAS_PRAGMA_ONCE 25 #pragma once 26 #endif 27 28 namespace boost { 29 namespace atomics { 30 namespace detail { 31 32 template< typename Base > 33 struct gcc_x86_extra_operations_common : 34 public Base 35 { 36 typedef Base base_type; 37 typedef typename base_type::storage_type storage_type; 38 bit_test_and_setboost::atomics::detail::gcc_x86_extra_operations_common39 static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order) BOOST_NOEXCEPT 40 { 41 bool res; 42 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) 43 __asm__ __volatile__ 44 ( 45 "lock; bts %[bit_number], %[storage]\n\t" 46 : [storage] "+m" (storage), [result] "=@ccc" (res) 47 : [bit_number] "Kq" (bit_number) 48 : "memory" 49 ); 50 #else 51 __asm__ __volatile__ 52 ( 53 "lock; bts %[bit_number], %[storage]\n\t" 54 "setc %[result]\n\t" 55 : [storage] "+m" (storage), [result] "=q" (res) 56 : [bit_number] "Kq" (bit_number) 57 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 58 ); 59 #endif 60 return res; 61 } 62 bit_test_and_resetboost::atomics::detail::gcc_x86_extra_operations_common63 static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order) BOOST_NOEXCEPT 64 { 65 bool res; 66 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) 67 __asm__ __volatile__ 68 ( 69 "lock; btr %[bit_number], %[storage]\n\t" 70 : [storage] "+m" (storage), [result] "=@ccc" (res) 71 : [bit_number] "Kq" (bit_number) 72 : "memory" 73 ); 74 #else 75 __asm__ __volatile__ 76 ( 77 "lock; btr %[bit_number], %[storage]\n\t" 78 "setc %[result]\n\t" 79 : [storage] "+m" (storage), [result] "=q" (res) 80 : [bit_number] "Kq" (bit_number) 81 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 82 ); 83 #endif 84 return res; 85 } 86 bit_test_and_complementboost::atomics::detail::gcc_x86_extra_operations_common87 static BOOST_FORCEINLINE bool bit_test_and_complement(storage_type volatile& storage, unsigned int bit_number, memory_order) BOOST_NOEXCEPT 88 { 89 bool res; 90 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) 91 __asm__ __volatile__ 92 ( 93 "lock; btc %[bit_number], %[storage]\n\t" 94 : [storage] "+m" (storage), [result] "=@ccc" (res) 95 : [bit_number] "Kq" (bit_number) 96 : "memory" 97 ); 98 #else 99 __asm__ __volatile__ 100 ( 101 "lock; btc %[bit_number], %[storage]\n\t" 102 "setc %[result]\n\t" 103 : [storage] "+m" (storage), [result] "=q" (res) 104 : [bit_number] "Kq" (bit_number) 105 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 106 ); 107 #endif 108 return res; 109 } 110 }; 111 112 template< typename Base, bool Signed > 113 struct extra_operations< Base, 1u, Signed > : 114 public gcc_x86_extra_operations_common< Base > 115 { 116 typedef gcc_x86_extra_operations_common< Base > base_type; 117 typedef typename base_type::storage_type storage_type; 118 typedef typename make_storage_type< 4u, Signed >::type temp_storage_type; 119 120 #define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, result)\ 121 temp_storage_type new_val;\ 122 __asm__ __volatile__\ 123 (\ 124 ".align 16\n\t"\ 125 "1: movzbl %[res], %2\n\t"\ 126 op " %b2\n\t"\ 127 "lock; cmpxchgb %b2, %[storage]\n\t"\ 128 "jne 1b"\ 129 : [res] "+a" (result), [storage] "+m" (storage), "=&q" (new_val)\ 130 : \ 131 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 132 ) 133 fetch_negateboost::atomics::detail::extra_operations134 static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT 135 { 136 storage_type res = storage; 137 BOOST_ATOMIC_DETAIL_CAS_LOOP("negb", res); 138 return res; 139 } 140 fetch_complementboost::atomics::detail::extra_operations141 static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT 142 { 143 storage_type res = storage; 144 BOOST_ATOMIC_DETAIL_CAS_LOOP("notb", res); 145 return res; 146 } 147 148 #undef BOOST_ATOMIC_DETAIL_CAS_LOOP 149 opaque_addboost::atomics::detail::extra_operations150 static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 151 { 152 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) 153 { 154 __asm__ __volatile__ 155 ( 156 "lock; incb %[storage]\n\t" 157 : [storage] "+m" (storage) 158 : 159 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 160 ); 161 } 162 else 163 { 164 __asm__ __volatile__ 165 ( 166 "lock; addb %[argument], %[storage]\n\t" 167 : [storage] "+m" (storage) 168 : [argument] "iq" (v) 169 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 170 ); 171 } 172 } 173 opaque_subboost::atomics::detail::extra_operations174 static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 175 { 176 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) 177 { 178 __asm__ __volatile__ 179 ( 180 "lock; decb %[storage]\n\t" 181 : [storage] "+m" (storage) 182 : 183 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 184 ); 185 } 186 else 187 { 188 __asm__ __volatile__ 189 ( 190 "lock; subb %[argument], %[storage]\n\t" 191 : [storage] "+m" (storage) 192 : [argument] "iq" (v) 193 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 194 ); 195 } 196 } 197 opaque_negateboost::atomics::detail::extra_operations198 static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT 199 { 200 __asm__ __volatile__ 201 ( 202 "lock; negb %[storage]\n\t" 203 : [storage] "+m" (storage) 204 : 205 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 206 ); 207 } 208 opaque_andboost::atomics::detail::extra_operations209 static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 210 { 211 __asm__ __volatile__ 212 ( 213 "lock; andb %[argument], %[storage]\n\t" 214 : [storage] "+m" (storage) 215 : [argument] "iq" (v) 216 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 217 ); 218 } 219 opaque_orboost::atomics::detail::extra_operations220 static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 221 { 222 __asm__ __volatile__ 223 ( 224 "lock; orb %[argument], %[storage]\n\t" 225 : [storage] "+m" (storage) 226 : [argument] "iq" (v) 227 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 228 ); 229 } 230 opaque_xorboost::atomics::detail::extra_operations231 static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 232 { 233 __asm__ __volatile__ 234 ( 235 "lock; xorb %[argument], %[storage]\n\t" 236 : [storage] "+m" (storage) 237 : [argument] "iq" (v) 238 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 239 ); 240 } 241 opaque_complementboost::atomics::detail::extra_operations242 static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT 243 { 244 __asm__ __volatile__ 245 ( 246 "lock; notb %[storage]\n\t" 247 : [storage] "+m" (storage) 248 : 249 : "memory" 250 ); 251 } 252 add_and_testboost::atomics::detail::extra_operations253 static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 254 { 255 bool res; 256 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) 257 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) 258 { 259 __asm__ __volatile__ 260 ( 261 "lock; incb %[storage]\n\t" 262 : [storage] "+m" (storage), [result] "=@ccz" (res) 263 : 264 : "memory" 265 ); 266 } 267 else 268 { 269 __asm__ __volatile__ 270 ( 271 "lock; addb %[argument], %[storage]\n\t" 272 : [storage] "+m" (storage), [result] "=@ccz" (res) 273 : [argument] "iq" (v) 274 : "memory" 275 ); 276 } 277 #else 278 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) 279 { 280 __asm__ __volatile__ 281 ( 282 "lock; incb %[storage]\n\t" 283 "setz %[result]\n\t" 284 : [storage] "+m" (storage), [result] "=q" (res) 285 : 286 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 287 ); 288 } 289 else 290 { 291 __asm__ __volatile__ 292 ( 293 "lock; addb %[argument], %[storage]\n\t" 294 "setz %[result]\n\t" 295 : [storage] "+m" (storage), [result] "=q" (res) 296 : [argument] "iq" (v) 297 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 298 ); 299 } 300 #endif 301 return res; 302 } 303 sub_and_testboost::atomics::detail::extra_operations304 static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 305 { 306 bool res; 307 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) 308 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) 309 { 310 __asm__ __volatile__ 311 ( 312 "lock; decb %[storage]\n\t" 313 : [storage] "+m" (storage), [result] "=@ccz" (res) 314 : 315 : "memory" 316 ); 317 } 318 else 319 { 320 __asm__ __volatile__ 321 ( 322 "lock; subb %[argument], %[storage]\n\t" 323 : [storage] "+m" (storage), [result] "=@ccz" (res) 324 : [argument] "iq" (v) 325 : "memory" 326 ); 327 } 328 #else 329 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) 330 { 331 __asm__ __volatile__ 332 ( 333 "lock; decb %[storage]\n\t" 334 "setz %[result]\n\t" 335 : [storage] "+m" (storage), [result] "=q" (res) 336 : 337 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 338 ); 339 } 340 else 341 { 342 __asm__ __volatile__ 343 ( 344 "lock; subb %[argument], %[storage]\n\t" 345 "setz %[result]\n\t" 346 : [storage] "+m" (storage), [result] "=q" (res) 347 : [argument] "iq" (v) 348 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 349 ); 350 } 351 #endif 352 return res; 353 } 354 and_and_testboost::atomics::detail::extra_operations355 static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 356 { 357 bool res; 358 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) 359 __asm__ __volatile__ 360 ( 361 "lock; andb %[argument], %[storage]\n\t" 362 : [storage] "+m" (storage), [result] "=@ccz" (res) 363 : [argument] "iq" (v) 364 : "memory" 365 ); 366 #else 367 __asm__ __volatile__ 368 ( 369 "lock; andb %[argument], %[storage]\n\t" 370 "setz %[result]\n\t" 371 : [storage] "+m" (storage), [result] "=q" (res) 372 : [argument] "iq" (v) 373 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 374 ); 375 #endif 376 return res; 377 } 378 or_and_testboost::atomics::detail::extra_operations379 static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 380 { 381 bool res; 382 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) 383 __asm__ __volatile__ 384 ( 385 "lock; orb %[argument], %[storage]\n\t" 386 : [storage] "+m" (storage), [result] "=@ccz" (res) 387 : [argument] "iq" (v) 388 : "memory" 389 ); 390 #else 391 __asm__ __volatile__ 392 ( 393 "lock; orb %[argument], %[storage]\n\t" 394 "setz %[result]\n\t" 395 : [storage] "+m" (storage), [result] "=q" (res) 396 : [argument] "iq" (v) 397 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 398 ); 399 #endif 400 return res; 401 } 402 xor_and_testboost::atomics::detail::extra_operations403 static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 404 { 405 bool res; 406 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) 407 __asm__ __volatile__ 408 ( 409 "lock; xorb %[argument], %[storage]\n\t" 410 : [storage] "+m" (storage), [result] "=@ccz" (res) 411 : [argument] "iq" (v) 412 : "memory" 413 ); 414 #else 415 __asm__ __volatile__ 416 ( 417 "lock; xorb %[argument], %[storage]\n\t" 418 "setz %[result]\n\t" 419 : [storage] "+m" (storage), [result] "=q" (res) 420 : [argument] "iq" (v) 421 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 422 ); 423 #endif 424 return res; 425 } 426 }; 427 428 template< typename Base, bool Signed > 429 struct extra_operations< Base, 2u, Signed > : 430 public gcc_x86_extra_operations_common< Base > 431 { 432 typedef gcc_x86_extra_operations_common< Base > base_type; 433 typedef typename base_type::storage_type storage_type; 434 typedef typename make_storage_type< 4u, Signed >::type temp_storage_type; 435 436 #define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, result)\ 437 temp_storage_type new_val;\ 438 __asm__ __volatile__\ 439 (\ 440 ".align 16\n\t"\ 441 "1: movzwl %[res], %2\n\t"\ 442 op " %w2\n\t"\ 443 "lock; cmpxchgw %w2, %[storage]\n\t"\ 444 "jne 1b"\ 445 : [res] "+a" (result), [storage] "+m" (storage), "=&q" (new_val)\ 446 : \ 447 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 448 ) 449 fetch_negateboost::atomics::detail::extra_operations450 static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT 451 { 452 storage_type res = storage; 453 BOOST_ATOMIC_DETAIL_CAS_LOOP("negw", res); 454 return res; 455 } 456 fetch_complementboost::atomics::detail::extra_operations457 static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT 458 { 459 storage_type res = storage; 460 BOOST_ATOMIC_DETAIL_CAS_LOOP("notw", res); 461 return res; 462 } 463 464 #undef BOOST_ATOMIC_DETAIL_CAS_LOOP 465 opaque_addboost::atomics::detail::extra_operations466 static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 467 { 468 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) 469 { 470 __asm__ __volatile__ 471 ( 472 "lock; incw %[storage]\n\t" 473 : [storage] "+m" (storage) 474 : 475 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 476 ); 477 } 478 else 479 { 480 __asm__ __volatile__ 481 ( 482 "lock; addw %[argument], %[storage]\n\t" 483 : [storage] "+m" (storage) 484 : [argument] "iq" (v) 485 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 486 ); 487 } 488 } 489 opaque_subboost::atomics::detail::extra_operations490 static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 491 { 492 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) 493 { 494 __asm__ __volatile__ 495 ( 496 "lock; decw %[storage]\n\t" 497 : [storage] "+m" (storage) 498 : 499 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 500 ); 501 } 502 else 503 { 504 __asm__ __volatile__ 505 ( 506 "lock; subw %[argument], %[storage]\n\t" 507 : [storage] "+m" (storage) 508 : [argument] "iq" (v) 509 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 510 ); 511 } 512 } 513 opaque_negateboost::atomics::detail::extra_operations514 static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT 515 { 516 __asm__ __volatile__ 517 ( 518 "lock; negw %[storage]\n\t" 519 : [storage] "+m" (storage) 520 : 521 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 522 ); 523 } 524 opaque_andboost::atomics::detail::extra_operations525 static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 526 { 527 __asm__ __volatile__ 528 ( 529 "lock; andw %[argument], %[storage]\n\t" 530 : [storage] "+m" (storage) 531 : [argument] "iq" (v) 532 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 533 ); 534 } 535 opaque_orboost::atomics::detail::extra_operations536 static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 537 { 538 __asm__ __volatile__ 539 ( 540 "lock; orw %[argument], %[storage]\n\t" 541 : [storage] "+m" (storage) 542 : [argument] "iq" (v) 543 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 544 ); 545 } 546 opaque_xorboost::atomics::detail::extra_operations547 static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 548 { 549 __asm__ __volatile__ 550 ( 551 "lock; xorw %[argument], %[storage]\n\t" 552 : [storage] "+m" (storage) 553 : [argument] "iq" (v) 554 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 555 ); 556 } 557 opaque_complementboost::atomics::detail::extra_operations558 static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT 559 { 560 __asm__ __volatile__ 561 ( 562 "lock; notw %[storage]\n\t" 563 : [storage] "+m" (storage) 564 : 565 : "memory" 566 ); 567 } 568 add_and_testboost::atomics::detail::extra_operations569 static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 570 { 571 bool res; 572 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) 573 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) 574 { 575 __asm__ __volatile__ 576 ( 577 "lock; incw %[storage]\n\t" 578 : [storage] "+m" (storage), [result] "=@ccz" (res) 579 : 580 : "memory" 581 ); 582 } 583 else 584 { 585 __asm__ __volatile__ 586 ( 587 "lock; addw %[argument], %[storage]\n\t" 588 : [storage] "+m" (storage), [result] "=@ccz" (res) 589 : [argument] "iq" (v) 590 : "memory" 591 ); 592 } 593 #else 594 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) 595 { 596 __asm__ __volatile__ 597 ( 598 "lock; incw %[storage]\n\t" 599 "setz %[result]\n\t" 600 : [storage] "+m" (storage), [result] "=q" (res) 601 : 602 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 603 ); 604 } 605 else 606 { 607 __asm__ __volatile__ 608 ( 609 "lock; addw %[argument], %[storage]\n\t" 610 "setz %[result]\n\t" 611 : [storage] "+m" (storage), [result] "=q" (res) 612 : [argument] "iq" (v) 613 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 614 ); 615 } 616 #endif 617 return res; 618 } 619 sub_and_testboost::atomics::detail::extra_operations620 static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 621 { 622 bool res; 623 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) 624 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) 625 { 626 __asm__ __volatile__ 627 ( 628 "lock; decw %[storage]\n\t" 629 : [storage] "+m" (storage), [result] "=@ccz" (res) 630 : 631 : "memory" 632 ); 633 } 634 else 635 { 636 __asm__ __volatile__ 637 ( 638 "lock; subw %[argument], %[storage]\n\t" 639 : [storage] "+m" (storage), [result] "=@ccz" (res) 640 : [argument] "iq" (v) 641 : "memory" 642 ); 643 } 644 #else 645 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) 646 { 647 __asm__ __volatile__ 648 ( 649 "lock; decw %[storage]\n\t" 650 "setz %[result]\n\t" 651 : [storage] "+m" (storage), [result] "=q" (res) 652 : 653 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 654 ); 655 } 656 else 657 { 658 __asm__ __volatile__ 659 ( 660 "lock; subw %[argument], %[storage]\n\t" 661 "setz %[result]\n\t" 662 : [storage] "+m" (storage), [result] "=q" (res) 663 : [argument] "iq" (v) 664 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 665 ); 666 } 667 #endif 668 return res; 669 } 670 and_and_testboost::atomics::detail::extra_operations671 static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 672 { 673 bool res; 674 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) 675 __asm__ __volatile__ 676 ( 677 "lock; andw %[argument], %[storage]\n\t" 678 : [storage] "+m" (storage), [result] "=@ccz" (res) 679 : [argument] "iq" (v) 680 : "memory" 681 ); 682 #else 683 __asm__ __volatile__ 684 ( 685 "lock; andw %[argument], %[storage]\n\t" 686 "setz %[result]\n\t" 687 : [storage] "+m" (storage), [result] "=q" (res) 688 : [argument] "iq" (v) 689 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 690 ); 691 #endif 692 return res; 693 } 694 or_and_testboost::atomics::detail::extra_operations695 static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 696 { 697 bool res; 698 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) 699 __asm__ __volatile__ 700 ( 701 "lock; orw %[argument], %[storage]\n\t" 702 : [storage] "+m" (storage), [result] "=@ccz" (res) 703 : [argument] "iq" (v) 704 : "memory" 705 ); 706 #else 707 __asm__ __volatile__ 708 ( 709 "lock; orw %[argument], %[storage]\n\t" 710 "setz %[result]\n\t" 711 : [storage] "+m" (storage), [result] "=q" (res) 712 : [argument] "iq" (v) 713 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 714 ); 715 #endif 716 return res; 717 } 718 xor_and_testboost::atomics::detail::extra_operations719 static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 720 { 721 bool res; 722 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) 723 __asm__ __volatile__ 724 ( 725 "lock; xorw %[argument], %[storage]\n\t" 726 : [storage] "+m" (storage), [result] "=@ccz" (res) 727 : [argument] "iq" (v) 728 : "memory" 729 ); 730 #else 731 __asm__ __volatile__ 732 ( 733 "lock; xorw %[argument], %[storage]\n\t" 734 "setz %[result]\n\t" 735 : [storage] "+m" (storage), [result] "=q" (res) 736 : [argument] "iq" (v) 737 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 738 ); 739 #endif 740 return res; 741 } 742 }; 743 744 template< typename Base, bool Signed > 745 struct extra_operations< Base, 4u, Signed > : 746 public gcc_x86_extra_operations_common< Base > 747 { 748 typedef gcc_x86_extra_operations_common< Base > base_type; 749 typedef typename base_type::storage_type storage_type; 750 751 #define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, result)\ 752 storage_type new_val;\ 753 __asm__ __volatile__\ 754 (\ 755 ".align 16\n\t"\ 756 "1: mov %[res], %[new_val]\n\t"\ 757 op " %[new_val]\n\t"\ 758 "lock; cmpxchgl %[new_val], %[storage]\n\t"\ 759 "jne 1b"\ 760 : [res] "+a" (result), [storage] "+m" (storage), [new_val] "=&r" (new_val)\ 761 : \ 762 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 763 ) 764 fetch_negateboost::atomics::detail::extra_operations765 static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT 766 { 767 storage_type res = storage; 768 BOOST_ATOMIC_DETAIL_CAS_LOOP("negl", res); 769 return res; 770 } 771 fetch_complementboost::atomics::detail::extra_operations772 static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT 773 { 774 storage_type res = storage; 775 BOOST_ATOMIC_DETAIL_CAS_LOOP("notl", res); 776 return res; 777 } 778 779 #undef BOOST_ATOMIC_DETAIL_CAS_LOOP 780 opaque_addboost::atomics::detail::extra_operations781 static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 782 { 783 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) 784 { 785 __asm__ __volatile__ 786 ( 787 "lock; incl %[storage]\n\t" 788 : [storage] "+m" (storage) 789 : 790 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 791 ); 792 } 793 else 794 { 795 __asm__ __volatile__ 796 ( 797 "lock; addl %[argument], %[storage]\n\t" 798 : [storage] "+m" (storage) 799 : [argument] "ir" (v) 800 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 801 ); 802 } 803 } 804 opaque_subboost::atomics::detail::extra_operations805 static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 806 { 807 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) 808 { 809 __asm__ __volatile__ 810 ( 811 "lock; decl %[storage]\n\t" 812 : [storage] "+m" (storage) 813 : 814 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 815 ); 816 } 817 else 818 { 819 __asm__ __volatile__ 820 ( 821 "lock; subl %[argument], %[storage]\n\t" 822 : [storage] "+m" (storage) 823 : [argument] "ir" (v) 824 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 825 ); 826 } 827 } 828 opaque_negateboost::atomics::detail::extra_operations829 static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT 830 { 831 __asm__ __volatile__ 832 ( 833 "lock; negl %[storage]\n\t" 834 : [storage] "+m" (storage) 835 : 836 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 837 ); 838 } 839 opaque_andboost::atomics::detail::extra_operations840 static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 841 { 842 __asm__ __volatile__ 843 ( 844 "lock; andl %[argument], %[storage]\n\t" 845 : [storage] "+m" (storage) 846 : [argument] "ir" (v) 847 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 848 ); 849 } 850 opaque_orboost::atomics::detail::extra_operations851 static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 852 { 853 __asm__ __volatile__ 854 ( 855 "lock; orl %[argument], %[storage]\n\t" 856 : [storage] "+m" (storage) 857 : [argument] "ir" (v) 858 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 859 ); 860 } 861 opaque_xorboost::atomics::detail::extra_operations862 static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 863 { 864 __asm__ __volatile__ 865 ( 866 "lock; xorl %[argument], %[storage]\n\t" 867 : [storage] "+m" (storage) 868 : [argument] "ir" (v) 869 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 870 ); 871 } 872 opaque_complementboost::atomics::detail::extra_operations873 static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT 874 { 875 __asm__ __volatile__ 876 ( 877 "lock; notl %[storage]\n\t" 878 : [storage] "+m" (storage) 879 : 880 : "memory" 881 ); 882 } 883 add_and_testboost::atomics::detail::extra_operations884 static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 885 { 886 bool res; 887 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) 888 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) 889 { 890 __asm__ __volatile__ 891 ( 892 "lock; incl %[storage]\n\t" 893 : [storage] "+m" (storage), [result] "=@ccz" (res) 894 : 895 : "memory" 896 ); 897 } 898 else 899 { 900 __asm__ __volatile__ 901 ( 902 "lock; addl %[argument], %[storage]\n\t" 903 : [storage] "+m" (storage), [result] "=@ccz" (res) 904 : [argument] "ir" (v) 905 : "memory" 906 ); 907 } 908 #else 909 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) 910 { 911 __asm__ __volatile__ 912 ( 913 "lock; incl %[storage]\n\t" 914 "setz %[result]\n\t" 915 : [storage] "+m" (storage), [result] "=q" (res) 916 : 917 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 918 ); 919 } 920 else 921 { 922 __asm__ __volatile__ 923 ( 924 "lock; addl %[argument], %[storage]\n\t" 925 "setz %[result]\n\t" 926 : [storage] "+m" (storage), [result] "=q" (res) 927 : [argument] "ir" (v) 928 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 929 ); 930 } 931 #endif 932 return res; 933 } 934 sub_and_testboost::atomics::detail::extra_operations935 static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 936 { 937 bool res; 938 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) 939 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) 940 { 941 __asm__ __volatile__ 942 ( 943 "lock; decl %[storage]\n\t" 944 : [storage] "+m" (storage), [result] "=@ccz" (res) 945 : 946 : "memory" 947 ); 948 } 949 else 950 { 951 __asm__ __volatile__ 952 ( 953 "lock; subl %[argument], %[storage]\n\t" 954 : [storage] "+m" (storage), [result] "=@ccz" (res) 955 : [argument] "ir" (v) 956 : "memory" 957 ); 958 } 959 #else 960 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) 961 { 962 __asm__ __volatile__ 963 ( 964 "lock; decl %[storage]\n\t" 965 "setz %[result]\n\t" 966 : [storage] "+m" (storage), [result] "=q" (res) 967 : 968 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 969 ); 970 } 971 else 972 { 973 __asm__ __volatile__ 974 ( 975 "lock; subl %[argument], %[storage]\n\t" 976 "setz %[result]\n\t" 977 : [storage] "+m" (storage), [result] "=q" (res) 978 : [argument] "ir" (v) 979 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 980 ); 981 } 982 #endif 983 return res; 984 } 985 and_and_testboost::atomics::detail::extra_operations986 static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 987 { 988 bool res; 989 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) 990 __asm__ __volatile__ 991 ( 992 "lock; andl %[argument], %[storage]\n\t" 993 : [storage] "+m" (storage), [result] "=@ccz" (res) 994 : [argument] "ir" (v) 995 : "memory" 996 ); 997 #else 998 __asm__ __volatile__ 999 ( 1000 "lock; andl %[argument], %[storage]\n\t" 1001 "setz %[result]\n\t" 1002 : [storage] "+m" (storage), [result] "=q" (res) 1003 : [argument] "ir" (v) 1004 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 1005 ); 1006 #endif 1007 return res; 1008 } 1009 or_and_testboost::atomics::detail::extra_operations1010 static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 1011 { 1012 bool res; 1013 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) 1014 __asm__ __volatile__ 1015 ( 1016 "lock; orl %[argument], %[storage]\n\t" 1017 : [storage] "+m" (storage), [result] "=@ccz" (res) 1018 : [argument] "ir" (v) 1019 : "memory" 1020 ); 1021 #else 1022 __asm__ __volatile__ 1023 ( 1024 "lock; orl %[argument], %[storage]\n\t" 1025 "setz %[result]\n\t" 1026 : [storage] "+m" (storage), [result] "=q" (res) 1027 : [argument] "ir" (v) 1028 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 1029 ); 1030 #endif 1031 return res; 1032 } 1033 xor_and_testboost::atomics::detail::extra_operations1034 static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 1035 { 1036 bool res; 1037 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) 1038 __asm__ __volatile__ 1039 ( 1040 "lock; xorl %[argument], %[storage]\n\t" 1041 : [storage] "+m" (storage), [result] "=@ccz" (res) 1042 : [argument] "ir" (v) 1043 : "memory" 1044 ); 1045 #else 1046 __asm__ __volatile__ 1047 ( 1048 "lock; xorl %[argument], %[storage]\n\t" 1049 "setz %[result]\n\t" 1050 : [storage] "+m" (storage), [result] "=q" (res) 1051 : [argument] "ir" (v) 1052 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 1053 ); 1054 #endif 1055 return res; 1056 } 1057 }; 1058 1059 #if defined(__x86_64__) 1060 1061 template< typename Base, bool Signed > 1062 struct extra_operations< Base, 8u, Signed > : 1063 public gcc_x86_extra_operations_common< Base > 1064 { 1065 typedef gcc_x86_extra_operations_common< Base > base_type; 1066 typedef typename base_type::storage_type storage_type; 1067 1068 #define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, result)\ 1069 storage_type new_val;\ 1070 __asm__ __volatile__\ 1071 (\ 1072 ".align 16\n\t"\ 1073 "1: mov %[res], %[new_val]\n\t"\ 1074 op " %[new_val]\n\t"\ 1075 "lock; cmpxchgq %[new_val], %[storage]\n\t"\ 1076 "jne 1b"\ 1077 : [res] "+a" (result), [storage] "+m" (storage), [new_val] "=&r" (new_val)\ 1078 : \ 1079 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ 1080 ) 1081 fetch_negateboost::atomics::detail::extra_operations1082 static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT 1083 { 1084 storage_type res = storage; 1085 BOOST_ATOMIC_DETAIL_CAS_LOOP("negq", res); 1086 return res; 1087 } 1088 fetch_complementboost::atomics::detail::extra_operations1089 static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT 1090 { 1091 storage_type res = storage; 1092 BOOST_ATOMIC_DETAIL_CAS_LOOP("notq", res); 1093 return res; 1094 } 1095 1096 #undef BOOST_ATOMIC_DETAIL_CAS_LOOP 1097 opaque_addboost::atomics::detail::extra_operations1098 static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 1099 { 1100 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) 1101 { 1102 __asm__ __volatile__ 1103 ( 1104 "lock; incq %[storage]\n\t" 1105 : [storage] "+m" (storage) 1106 : 1107 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 1108 ); 1109 } 1110 else 1111 { 1112 __asm__ __volatile__ 1113 ( 1114 "lock; addq %[argument], %[storage]\n\t" 1115 : [storage] "+m" (storage) 1116 : [argument] "er" (v) 1117 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 1118 ); 1119 } 1120 } 1121 opaque_subboost::atomics::detail::extra_operations1122 static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 1123 { 1124 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) 1125 { 1126 __asm__ __volatile__ 1127 ( 1128 "lock; decq %[storage]\n\t" 1129 : [storage] "+m" (storage) 1130 : 1131 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 1132 ); 1133 } 1134 else 1135 { 1136 __asm__ __volatile__ 1137 ( 1138 "lock; subq %[argument], %[storage]\n\t" 1139 : [storage] "+m" (storage) 1140 : [argument] "er" (v) 1141 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 1142 ); 1143 } 1144 } 1145 opaque_negateboost::atomics::detail::extra_operations1146 static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT 1147 { 1148 __asm__ __volatile__ 1149 ( 1150 "lock; negq %[storage]\n\t" 1151 : [storage] "+m" (storage) 1152 : 1153 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 1154 ); 1155 } 1156 opaque_andboost::atomics::detail::extra_operations1157 static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 1158 { 1159 __asm__ __volatile__ 1160 ( 1161 "lock; andq %[argument], %[storage]\n\t" 1162 : [storage] "+m" (storage) 1163 : [argument] "er" (v) 1164 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 1165 ); 1166 } 1167 opaque_orboost::atomics::detail::extra_operations1168 static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 1169 { 1170 __asm__ __volatile__ 1171 ( 1172 "lock; orq %[argument], %[storage]\n\t" 1173 : [storage] "+m" (storage) 1174 : [argument] "er" (v) 1175 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 1176 ); 1177 } 1178 opaque_xorboost::atomics::detail::extra_operations1179 static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 1180 { 1181 __asm__ __volatile__ 1182 ( 1183 "lock; xorq %[argument], %[storage]\n\t" 1184 : [storage] "+m" (storage) 1185 : [argument] "er" (v) 1186 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 1187 ); 1188 } 1189 opaque_complementboost::atomics::detail::extra_operations1190 static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT 1191 { 1192 __asm__ __volatile__ 1193 ( 1194 "lock; notq %[storage]\n\t" 1195 : [storage] "+m" (storage) 1196 : 1197 : "memory" 1198 ); 1199 } 1200 add_and_testboost::atomics::detail::extra_operations1201 static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 1202 { 1203 bool res; 1204 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) 1205 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) 1206 { 1207 __asm__ __volatile__ 1208 ( 1209 "lock; incq %[storage]\n\t" 1210 : [storage] "+m" (storage), [result] "=@ccz" (res) 1211 : 1212 : "memory" 1213 ); 1214 } 1215 else 1216 { 1217 __asm__ __volatile__ 1218 ( 1219 "lock; addq %[argument], %[storage]\n\t" 1220 : [storage] "+m" (storage), [result] "=@ccz" (res) 1221 : [argument] "er" (v) 1222 : "memory" 1223 ); 1224 } 1225 #else 1226 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) 1227 { 1228 __asm__ __volatile__ 1229 ( 1230 "lock; incq %[storage]\n\t" 1231 "setz %[result]\n\t" 1232 : [storage] "+m" (storage), [result] "=q" (res) 1233 : 1234 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 1235 ); 1236 } 1237 else 1238 { 1239 __asm__ __volatile__ 1240 ( 1241 "lock; addq %[argument], %[storage]\n\t" 1242 "setz %[result]\n\t" 1243 : [storage] "+m" (storage), [result] "=q" (res) 1244 : [argument] "er" (v) 1245 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 1246 ); 1247 } 1248 #endif 1249 return res; 1250 } 1251 sub_and_testboost::atomics::detail::extra_operations1252 static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 1253 { 1254 bool res; 1255 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) 1256 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) 1257 { 1258 __asm__ __volatile__ 1259 ( 1260 "lock; decq %[storage]\n\t" 1261 : [storage] "+m" (storage), [result] "=@ccz" (res) 1262 : 1263 : "memory" 1264 ); 1265 } 1266 else 1267 { 1268 __asm__ __volatile__ 1269 ( 1270 "lock; subq %[argument], %[storage]\n\t" 1271 : [storage] "+m" (storage), [result] "=@ccz" (res) 1272 : [argument] "er" (v) 1273 : "memory" 1274 ); 1275 } 1276 #else 1277 if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) 1278 { 1279 __asm__ __volatile__ 1280 ( 1281 "lock; decq %[storage]\n\t" 1282 "setz %[result]\n\t" 1283 : [storage] "+m" (storage), [result] "=q" (res) 1284 : 1285 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 1286 ); 1287 } 1288 else 1289 { 1290 __asm__ __volatile__ 1291 ( 1292 "lock; subq %[argument], %[storage]\n\t" 1293 "setz %[result]\n\t" 1294 : [storage] "+m" (storage), [result] "=q" (res) 1295 : [argument] "er" (v) 1296 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 1297 ); 1298 } 1299 #endif 1300 return res; 1301 } 1302 and_and_testboost::atomics::detail::extra_operations1303 static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 1304 { 1305 bool res; 1306 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) 1307 __asm__ __volatile__ 1308 ( 1309 "lock; andq %[argument], %[storage]\n\t" 1310 : [storage] "+m" (storage), [result] "=@ccz" (res) 1311 : [argument] "er" (v) 1312 : "memory" 1313 ); 1314 #else 1315 __asm__ __volatile__ 1316 ( 1317 "lock; andq %[argument], %[storage]\n\t" 1318 "setz %[result]\n\t" 1319 : [storage] "+m" (storage), [result] "=q" (res) 1320 : [argument] "er" (v) 1321 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 1322 ); 1323 #endif 1324 return res; 1325 } 1326 or_and_testboost::atomics::detail::extra_operations1327 static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 1328 { 1329 bool res; 1330 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) 1331 __asm__ __volatile__ 1332 ( 1333 "lock; orq %[argument], %[storage]\n\t" 1334 : [storage] "+m" (storage), [result] "=@ccz" (res) 1335 : [argument] "er" (v) 1336 : "memory" 1337 ); 1338 #else 1339 __asm__ __volatile__ 1340 ( 1341 "lock; orq %[argument], %[storage]\n\t" 1342 "setz %[result]\n\t" 1343 : [storage] "+m" (storage), [result] "=q" (res) 1344 : [argument] "er" (v) 1345 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 1346 ); 1347 #endif 1348 return res; 1349 } 1350 xor_and_testboost::atomics::detail::extra_operations1351 static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 1352 { 1353 bool res; 1354 #if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) 1355 __asm__ __volatile__ 1356 ( 1357 "lock; xorq %[argument], %[storage]\n\t" 1358 : [storage] "+m" (storage), [result] "=@ccz" (res) 1359 : [argument] "er" (v) 1360 : "memory" 1361 ); 1362 #else 1363 __asm__ __volatile__ 1364 ( 1365 "lock; xorq %[argument], %[storage]\n\t" 1366 "setz %[result]\n\t" 1367 : [storage] "+m" (storage), [result] "=q" (res) 1368 : [argument] "er" (v) 1369 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" 1370 ); 1371 #endif 1372 return res; 1373 } 1374 }; 1375 1376 #endif // defined(__x86_64__) 1377 1378 } // namespace detail 1379 } // namespace atomics 1380 } // namespace boost 1381 1382 #endif // BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_X86_HPP_INCLUDED_ 1383