annotate DEPENDENCIES/generic/include/boost/atomic/detail/ops_gcc_alpha.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents f46d142149f5
children
rev   line source
Chris@102 1 /*
Chris@102 2 * Distributed under the Boost Software License, Version 1.0.
Chris@102 3 * (See accompanying file LICENSE_1_0.txt or copy at
Chris@102 4 * http://www.boost.org/LICENSE_1_0.txt)
Chris@102 5 *
Chris@102 6 * Copyright (c) 2009 Helge Bahmann
Chris@102 7 * Copyright (c) 2013 Tim Blechmann
Chris@102 8 * Copyright (c) 2014 Andrey Semashev
Chris@102 9 */
Chris@102 10 /*!
Chris@102 11 * \file atomic/detail/ops_gcc_alpha.hpp
Chris@102 12 *
Chris@102 13 * This header contains implementation of the \c operations template.
Chris@102 14 */
Chris@102 15
Chris@102 16 #ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_ALPHA_HPP_INCLUDED_
Chris@102 17 #define BOOST_ATOMIC_DETAIL_OPS_GCC_ALPHA_HPP_INCLUDED_
Chris@102 18
Chris@102 19 #include <boost/memory_order.hpp>
Chris@102 20 #include <boost/atomic/detail/config.hpp>
Chris@102 21 #include <boost/atomic/detail/storage_type.hpp>
Chris@102 22 #include <boost/atomic/detail/operations_fwd.hpp>
Chris@102 23 #include <boost/atomic/capabilities.hpp>
Chris@102 24
Chris@102 25 #ifdef BOOST_HAS_PRAGMA_ONCE
Chris@102 26 #pragma once
Chris@102 27 #endif
Chris@102 28
Chris@102 29 namespace boost {
Chris@102 30 namespace atomics {
Chris@102 31 namespace detail {
Chris@102 32
Chris@102 33 /*
Chris@102 34 Refer to http://h71000.www7.hp.com/doc/82final/5601/5601pro_004.html
Chris@102 35 (HP OpenVMS systems documentation) and the Alpha Architecture Reference Manual.
Chris@102 36 */
Chris@102 37
Chris@102 38 /*
Chris@102 39 NB: The most natural thing would be to write the increment/decrement
Chris@102 40 operators along the following lines:
Chris@102 41
Chris@102 42 __asm__ __volatile__
Chris@102 43 (
Chris@102 44 "1: ldl_l %0,%1 \n"
Chris@102 45 "addl %0,1,%0 \n"
Chris@102 46 "stl_c %0,%1 \n"
Chris@102 47 "beq %0,1b\n"
Chris@102 48 : "=&b" (tmp)
Chris@102 49 : "m" (value)
Chris@102 50 : "cc"
Chris@102 51 );
Chris@102 52
Chris@102 53 However according to the comments on the HP website and matching
Chris@102 54 comments in the Linux kernel sources this defies branch prediction,
Chris@102 55 as the cpu assumes that backward branches are always taken; so
Chris@102 56 instead copy the trick from the Linux kernel, introduce a forward
Chris@102 57 branch and back again.
Chris@102 58
Chris@102 59 I have, however, had a hard time measuring the difference between
Chris@102 60 the two versions in microbenchmarks -- I am leaving it in nevertheless
Chris@102 61 as it apparently does not hurt either.
Chris@102 62 */
Chris@102 63
Chris@102 64 struct gcc_alpha_operations_base
Chris@102 65 {
Chris@102 66 static BOOST_FORCEINLINE void fence_before(memory_order order) BOOST_NOEXCEPT
Chris@102 67 {
Chris@102 68 if ((order & memory_order_release) != 0)
Chris@102 69 __asm__ __volatile__ ("mb" ::: "memory");
Chris@102 70 }
Chris@102 71
Chris@102 72 static BOOST_FORCEINLINE void fence_after(memory_order order) BOOST_NOEXCEPT
Chris@102 73 {
Chris@102 74 if ((order & (memory_order_consume | memory_order_acquire)) != 0)
Chris@102 75 __asm__ __volatile__ ("mb" ::: "memory");
Chris@102 76 }
Chris@102 77
Chris@102 78 static BOOST_FORCEINLINE void fence_after_store(memory_order order) BOOST_NOEXCEPT
Chris@102 79 {
Chris@102 80 if (order == memory_order_seq_cst)
Chris@102 81 __asm__ __volatile__ ("mb" ::: "memory");
Chris@102 82 }
Chris@102 83 };
Chris@102 84
Chris@102 85
Chris@102 86 template< bool Signed >
Chris@102 87 struct operations< 4u, Signed > :
Chris@102 88 public gcc_alpha_operations_base
Chris@102 89 {
Chris@102 90 typedef typename make_storage_type< 4u, Signed >::type storage_type;
Chris@102 91
Chris@102 92 static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
Chris@102 93 {
Chris@102 94 fence_before(order);
Chris@102 95 storage = v;
Chris@102 96 fence_after_store(order);
Chris@102 97 }
Chris@102 98
Chris@102 99 static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
Chris@102 100 {
Chris@102 101 storage_type v = storage;
Chris@102 102 fence_after(order);
Chris@102 103 return v;
Chris@102 104 }
Chris@102 105
Chris@102 106 static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
Chris@102 107 {
Chris@102 108 storage_type original, tmp;
Chris@102 109 fence_before(order);
Chris@102 110 __asm__ __volatile__
Chris@102 111 (
Chris@102 112 "1:\n"
Chris@102 113 "mov %3, %1\n"
Chris@102 114 "ldl_l %0, %2\n"
Chris@102 115 "stl_c %1, %2\n"
Chris@102 116 "beq %1, 2f\n"
Chris@102 117
Chris@102 118 ".subsection 2\n"
Chris@102 119 "2: br 1b\n"
Chris@102 120 ".previous\n"
Chris@102 121
Chris@102 122 : "=&r" (original), // %0
Chris@102 123 "=&r" (tmp) // %1
Chris@102 124 : "m" (storage), // %2
Chris@102 125 "r" (v) // %3
Chris@102 126 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
Chris@102 127 );
Chris@102 128 fence_after(order);
Chris@102 129 return original;
Chris@102 130 }
Chris@102 131
Chris@102 132 static BOOST_FORCEINLINE bool compare_exchange_weak(
Chris@102 133 storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
Chris@102 134 {
Chris@102 135 fence_before(success_order);
Chris@102 136 int success;
Chris@102 137 storage_type current;
Chris@102 138 __asm__ __volatile__
Chris@102 139 (
Chris@102 140 "1:\n"
Chris@102 141 "ldl_l %2, %4\n" // current = *(&storage)
Chris@102 142 "cmpeq %2, %0, %3\n" // success = current == expected
Chris@102 143 "mov %2, %0\n" // expected = current
Chris@102 144 "beq %3, 2f\n" // if (success == 0) goto end
Chris@102 145 "stl_c %1, %4\n" // storage = desired; desired = store succeeded
Chris@102 146 "mov %1, %3\n" // success = desired
Chris@102 147 "2:\n"
Chris@102 148 : "+&r" (expected), // %0
Chris@102 149 "+&r" (desired), // %1
Chris@102 150 "=&r" (current), // %2
Chris@102 151 "=&r" (success) // %3
Chris@102 152 : "m" (storage) // %4
Chris@102 153 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
Chris@102 154 );
Chris@102 155 if (success)
Chris@102 156 fence_after(success_order);
Chris@102 157 else
Chris@102 158 fence_after(failure_order);
Chris@102 159 return !!success;
Chris@102 160 }
Chris@102 161
Chris@102 162 static BOOST_FORCEINLINE bool compare_exchange_strong(
Chris@102 163 storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
Chris@102 164 {
Chris@102 165 int success;
Chris@102 166 storage_type current, tmp;
Chris@102 167 fence_before(success_order);
Chris@102 168 __asm__ __volatile__
Chris@102 169 (
Chris@102 170 "1:\n"
Chris@102 171 "mov %5, %1\n" // tmp = desired
Chris@102 172 "ldl_l %2, %4\n" // current = *(&storage)
Chris@102 173 "cmpeq %2, %0, %3\n" // success = current == expected
Chris@102 174 "mov %2, %0\n" // expected = current
Chris@102 175 "beq %3, 2f\n" // if (success == 0) goto end
Chris@102 176 "stl_c %1, %4\n" // storage = tmp; tmp = store succeeded
Chris@102 177 "beq %1, 3f\n" // if (tmp == 0) goto retry
Chris@102 178 "mov %1, %3\n" // success = tmp
Chris@102 179 "2:\n"
Chris@102 180
Chris@102 181 ".subsection 2\n"
Chris@102 182 "3: br 1b\n"
Chris@102 183 ".previous\n"
Chris@102 184
Chris@102 185 : "+&r" (expected), // %0
Chris@102 186 "=&r" (tmp), // %1
Chris@102 187 "=&r" (current), // %2
Chris@102 188 "=&r" (success) // %3
Chris@102 189 : "m" (storage), // %4
Chris@102 190 "r" (desired) // %5
Chris@102 191 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
Chris@102 192 );
Chris@102 193 if (success)
Chris@102 194 fence_after(success_order);
Chris@102 195 else
Chris@102 196 fence_after(failure_order);
Chris@102 197 return !!success;
Chris@102 198 }
Chris@102 199
Chris@102 200 static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
Chris@102 201 {
Chris@102 202 storage_type original, modified;
Chris@102 203 fence_before(order);
Chris@102 204 __asm__ __volatile__
Chris@102 205 (
Chris@102 206 "1:\n"
Chris@102 207 "ldl_l %0, %2\n"
Chris@102 208 "addl %0, %3, %1\n"
Chris@102 209 "stl_c %1, %2\n"
Chris@102 210 "beq %1, 2f\n"
Chris@102 211
Chris@102 212 ".subsection 2\n"
Chris@102 213 "2: br 1b\n"
Chris@102 214 ".previous\n"
Chris@102 215
Chris@102 216 : "=&r" (original), // %0
Chris@102 217 "=&r" (modified) // %1
Chris@102 218 : "m" (storage), // %2
Chris@102 219 "r" (v) // %3
Chris@102 220 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
Chris@102 221 );
Chris@102 222 fence_after(order);
Chris@102 223 return original;
Chris@102 224 }
Chris@102 225
Chris@102 226 static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
Chris@102 227 {
Chris@102 228 storage_type original, modified;
Chris@102 229 fence_before(order);
Chris@102 230 __asm__ __volatile__
Chris@102 231 (
Chris@102 232 "1:\n"
Chris@102 233 "ldl_l %0, %2\n"
Chris@102 234 "subl %0, %3, %1\n"
Chris@102 235 "stl_c %1, %2\n"
Chris@102 236 "beq %1, 2f\n"
Chris@102 237
Chris@102 238 ".subsection 2\n"
Chris@102 239 "2: br 1b\n"
Chris@102 240 ".previous\n"
Chris@102 241
Chris@102 242 : "=&r" (original), // %0
Chris@102 243 "=&r" (modified) // %1
Chris@102 244 : "m" (storage), // %2
Chris@102 245 "r" (v) // %3
Chris@102 246 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
Chris@102 247 );
Chris@102 248 fence_after(order);
Chris@102 249 return original;
Chris@102 250 }
Chris@102 251
Chris@102 252 static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
Chris@102 253 {
Chris@102 254 storage_type original, modified;
Chris@102 255 fence_before(order);
Chris@102 256 __asm__ __volatile__
Chris@102 257 (
Chris@102 258 "1:\n"
Chris@102 259 "ldl_l %0, %2\n"
Chris@102 260 "and %0, %3, %1\n"
Chris@102 261 "stl_c %1, %2\n"
Chris@102 262 "beq %1, 2f\n"
Chris@102 263
Chris@102 264 ".subsection 2\n"
Chris@102 265 "2: br 1b\n"
Chris@102 266 ".previous\n"
Chris@102 267
Chris@102 268 : "=&r" (original), // %0
Chris@102 269 "=&r" (modified) // %1
Chris@102 270 : "m" (storage), // %2
Chris@102 271 "r" (v) // %3
Chris@102 272 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
Chris@102 273 );
Chris@102 274 fence_after(order);
Chris@102 275 return original;
Chris@102 276 }
Chris@102 277
Chris@102 278 static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
Chris@102 279 {
Chris@102 280 storage_type original, modified;
Chris@102 281 fence_before(order);
Chris@102 282 __asm__ __volatile__
Chris@102 283 (
Chris@102 284 "1:\n"
Chris@102 285 "ldl_l %0, %2\n"
Chris@102 286 "bis %0, %3, %1\n"
Chris@102 287 "stl_c %1, %2\n"
Chris@102 288 "beq %1, 2f\n"
Chris@102 289
Chris@102 290 ".subsection 2\n"
Chris@102 291 "2: br 1b\n"
Chris@102 292 ".previous\n"
Chris@102 293
Chris@102 294 : "=&r" (original), // %0
Chris@102 295 "=&r" (modified) // %1
Chris@102 296 : "m" (storage), // %2
Chris@102 297 "r" (v) // %3
Chris@102 298 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
Chris@102 299 );
Chris@102 300 fence_after(order);
Chris@102 301 return original;
Chris@102 302 }
Chris@102 303
Chris@102 304 static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
Chris@102 305 {
Chris@102 306 storage_type original, modified;
Chris@102 307 fence_before(order);
Chris@102 308 __asm__ __volatile__
Chris@102 309 (
Chris@102 310 "1:\n"
Chris@102 311 "ldl_l %0, %2\n"
Chris@102 312 "xor %0, %3, %1\n"
Chris@102 313 "stl_c %1, %2\n"
Chris@102 314 "beq %1, 2f\n"
Chris@102 315
Chris@102 316 ".subsection 2\n"
Chris@102 317 "2: br 1b\n"
Chris@102 318 ".previous\n"
Chris@102 319
Chris@102 320 : "=&r" (original), // %0
Chris@102 321 "=&r" (modified) // %1
Chris@102 322 : "m" (storage), // %2
Chris@102 323 "r" (v) // %3
Chris@102 324 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
Chris@102 325 );
Chris@102 326 fence_after(order);
Chris@102 327 return original;
Chris@102 328 }
Chris@102 329
Chris@102 330 static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
Chris@102 331 {
Chris@102 332 return !!exchange(storage, (storage_type)1, order);
Chris@102 333 }
Chris@102 334
Chris@102 335 static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
Chris@102 336 {
Chris@102 337 store(storage, 0, order);
Chris@102 338 }
Chris@102 339
Chris@102 340 static BOOST_FORCEINLINE bool is_lock_free(storage_type const volatile&) BOOST_NOEXCEPT
Chris@102 341 {
Chris@102 342 return true;
Chris@102 343 }
Chris@102 344 };
Chris@102 345
Chris@102 346
Chris@102 347 template< >
Chris@102 348 struct operations< 1u, false > :
Chris@102 349 public operations< 4u, false >
Chris@102 350 {
Chris@102 351 typedef operations< 4u, false > base_type;
Chris@102 352 typedef base_type::storage_type storage_type;
Chris@102 353
Chris@102 354 static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
Chris@102 355 {
Chris@102 356 storage_type original, modified;
Chris@102 357 fence_before(order);
Chris@102 358 __asm__ __volatile__
Chris@102 359 (
Chris@102 360 "1:\n"
Chris@102 361 "ldl_l %0, %2\n"
Chris@102 362 "addl %0, %3, %1\n"
Chris@102 363 "zapnot %1, #1, %1\n"
Chris@102 364 "stl_c %1, %2\n"
Chris@102 365 "beq %1, 2f\n"
Chris@102 366
Chris@102 367 ".subsection 2\n"
Chris@102 368 "2: br 1b\n"
Chris@102 369 ".previous\n"
Chris@102 370
Chris@102 371 : "=&r" (original), // %0
Chris@102 372 "=&r" (modified) // %1
Chris@102 373 : "m" (storage), // %2
Chris@102 374 "r" (v) // %3
Chris@102 375 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
Chris@102 376 );
Chris@102 377 fence_after(order);
Chris@102 378 return original;
Chris@102 379 }
Chris@102 380
Chris@102 381 static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
Chris@102 382 {
Chris@102 383 storage_type original, modified;
Chris@102 384 fence_before(order);
Chris@102 385 __asm__ __volatile__
Chris@102 386 (
Chris@102 387 "1:\n"
Chris@102 388 "ldl_l %0, %2\n"
Chris@102 389 "subl %0, %3, %1\n"
Chris@102 390 "zapnot %1, #1, %1\n"
Chris@102 391 "stl_c %1, %2\n"
Chris@102 392 "beq %1, 2f\n"
Chris@102 393
Chris@102 394 ".subsection 2\n"
Chris@102 395 "2: br 1b\n"
Chris@102 396 ".previous\n"
Chris@102 397
Chris@102 398 : "=&r" (original), // %0
Chris@102 399 "=&r" (modified) // %1
Chris@102 400 : "m" (storage), // %2
Chris@102 401 "r" (v) // %3
Chris@102 402 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
Chris@102 403 );
Chris@102 404 fence_after(order);
Chris@102 405 return original;
Chris@102 406 }
Chris@102 407 };
Chris@102 408
Chris@102 409 template< >
Chris@102 410 struct operations< 1u, true > :
Chris@102 411 public operations< 4u, true >
Chris@102 412 {
Chris@102 413 typedef operations< 4u, true > base_type;
Chris@102 414 typedef base_type::storage_type storage_type;
Chris@102 415
Chris@102 416 static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
Chris@102 417 {
Chris@102 418 storage_type original, modified;
Chris@102 419 fence_before(order);
Chris@102 420 __asm__ __volatile__
Chris@102 421 (
Chris@102 422 "1:\n"
Chris@102 423 "ldl_l %0, %2\n"
Chris@102 424 "addl %0, %3, %1\n"
Chris@102 425 "sextb %1, %1\n"
Chris@102 426 "stl_c %1, %2\n"
Chris@102 427 "beq %1, 2f\n"
Chris@102 428
Chris@102 429 ".subsection 2\n"
Chris@102 430 "2: br 1b\n"
Chris@102 431 ".previous\n"
Chris@102 432
Chris@102 433 : "=&r" (original), // %0
Chris@102 434 "=&r" (modified) // %1
Chris@102 435 : "m" (storage), // %2
Chris@102 436 "r" (v) // %3
Chris@102 437 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
Chris@102 438 );
Chris@102 439 fence_after(order);
Chris@102 440 return original;
Chris@102 441 }
Chris@102 442
Chris@102 443 static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
Chris@102 444 {
Chris@102 445 storage_type original, modified;
Chris@102 446 fence_before(order);
Chris@102 447 __asm__ __volatile__
Chris@102 448 (
Chris@102 449 "1:\n"
Chris@102 450 "ldl_l %0, %2\n"
Chris@102 451 "subl %0, %3, %1\n"
Chris@102 452 "sextb %1, %1\n"
Chris@102 453 "stl_c %1, %2\n"
Chris@102 454 "beq %1, 2f\n"
Chris@102 455
Chris@102 456 ".subsection 2\n"
Chris@102 457 "2: br 1b\n"
Chris@102 458 ".previous\n"
Chris@102 459
Chris@102 460 : "=&r" (original), // %0
Chris@102 461 "=&r" (modified) // %1
Chris@102 462 : "m" (storage), // %2
Chris@102 463 "r" (v) // %3
Chris@102 464 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
Chris@102 465 );
Chris@102 466 fence_after(order);
Chris@102 467 return original;
Chris@102 468 }
Chris@102 469 };
Chris@102 470
Chris@102 471
Chris@102 472 template< >
Chris@102 473 struct operations< 2u, false > :
Chris@102 474 public operations< 4u, false >
Chris@102 475 {
Chris@102 476 typedef operations< 4u, false > base_type;
Chris@102 477 typedef base_type::storage_type storage_type;
Chris@102 478
Chris@102 479 static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
Chris@102 480 {
Chris@102 481 storage_type original, modified;
Chris@102 482 fence_before(order);
Chris@102 483 __asm__ __volatile__
Chris@102 484 (
Chris@102 485 "1:\n"
Chris@102 486 "ldl_l %0, %2\n"
Chris@102 487 "addl %0, %3, %1\n"
Chris@102 488 "zapnot %1, #3, %1\n"
Chris@102 489 "stl_c %1, %2\n"
Chris@102 490 "beq %1, 2f\n"
Chris@102 491
Chris@102 492 ".subsection 2\n"
Chris@102 493 "2: br 1b\n"
Chris@102 494 ".previous\n"
Chris@102 495
Chris@102 496 : "=&r" (original), // %0
Chris@102 497 "=&r" (modified) // %1
Chris@102 498 : "m" (storage), // %2
Chris@102 499 "r" (v) // %3
Chris@102 500 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
Chris@102 501 );
Chris@102 502 fence_after(order);
Chris@102 503 return original;
Chris@102 504 }
Chris@102 505
Chris@102 506 static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
Chris@102 507 {
Chris@102 508 storage_type original, modified;
Chris@102 509 fence_before(order);
Chris@102 510 __asm__ __volatile__
Chris@102 511 (
Chris@102 512 "1:\n"
Chris@102 513 "ldl_l %0, %2\n"
Chris@102 514 "subl %0, %3, %1\n"
Chris@102 515 "zapnot %1, #3, %1\n"
Chris@102 516 "stl_c %1, %2\n"
Chris@102 517 "beq %1, 2f\n"
Chris@102 518
Chris@102 519 ".subsection 2\n"
Chris@102 520 "2: br 1b\n"
Chris@102 521 ".previous\n"
Chris@102 522
Chris@102 523 : "=&r" (original), // %0
Chris@102 524 "=&r" (modified) // %1
Chris@102 525 : "m" (storage), // %2
Chris@102 526 "r" (v) // %3
Chris@102 527 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
Chris@102 528 );
Chris@102 529 fence_after(order);
Chris@102 530 return original;
Chris@102 531 }
Chris@102 532 };
Chris@102 533
Chris@102 534 template< >
Chris@102 535 struct operations< 2u, true > :
Chris@102 536 public operations< 4u, true >
Chris@102 537 {
Chris@102 538 typedef operations< 4u, true > base_type;
Chris@102 539 typedef base_type::storage_type storage_type;
Chris@102 540
Chris@102 541 static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
Chris@102 542 {
Chris@102 543 storage_type original, modified;
Chris@102 544 fence_before(order);
Chris@102 545 __asm__ __volatile__
Chris@102 546 (
Chris@102 547 "1:\n"
Chris@102 548 "ldl_l %0, %2\n"
Chris@102 549 "addl %0, %3, %1\n"
Chris@102 550 "sextw %1, %1\n"
Chris@102 551 "stl_c %1, %2\n"
Chris@102 552 "beq %1, 2f\n"
Chris@102 553
Chris@102 554 ".subsection 2\n"
Chris@102 555 "2: br 1b\n"
Chris@102 556 ".previous\n"
Chris@102 557
Chris@102 558 : "=&r" (original), // %0
Chris@102 559 "=&r" (modified) // %1
Chris@102 560 : "m" (storage), // %2
Chris@102 561 "r" (v) // %3
Chris@102 562 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
Chris@102 563 );
Chris@102 564 fence_after(order);
Chris@102 565 return original;
Chris@102 566 }
Chris@102 567
Chris@102 568 static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
Chris@102 569 {
Chris@102 570 storage_type original, modified;
Chris@102 571 fence_before(order);
Chris@102 572 __asm__ __volatile__
Chris@102 573 (
Chris@102 574 "1:\n"
Chris@102 575 "ldl_l %0, %2\n"
Chris@102 576 "subl %0, %3, %1\n"
Chris@102 577 "sextw %1, %1\n"
Chris@102 578 "stl_c %1, %2\n"
Chris@102 579 "beq %1, 2f\n"
Chris@102 580
Chris@102 581 ".subsection 2\n"
Chris@102 582 "2: br 1b\n"
Chris@102 583 ".previous\n"
Chris@102 584
Chris@102 585 : "=&r" (original), // %0
Chris@102 586 "=&r" (modified) // %1
Chris@102 587 : "m" (storage), // %2
Chris@102 588 "r" (v) // %3
Chris@102 589 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
Chris@102 590 );
Chris@102 591 fence_after(order);
Chris@102 592 return original;
Chris@102 593 }
Chris@102 594 };
Chris@102 595
Chris@102 596
Chris@102 597 template< bool Signed >
Chris@102 598 struct operations< 8u, Signed > :
Chris@102 599 public gcc_alpha_operations_base
Chris@102 600 {
Chris@102 601 typedef typename make_storage_type< 8u, Signed >::type storage_type;
Chris@102 602
Chris@102 603 static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
Chris@102 604 {
Chris@102 605 fence_before(order);
Chris@102 606 storage = v;
Chris@102 607 fence_after_store(order);
Chris@102 608 }
Chris@102 609
Chris@102 610 static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
Chris@102 611 {
Chris@102 612 storage_type v = storage;
Chris@102 613 fence_after(order);
Chris@102 614 return v;
Chris@102 615 }
Chris@102 616
Chris@102 617 static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
Chris@102 618 {
Chris@102 619 storage_type original, tmp;
Chris@102 620 fence_before(order);
Chris@102 621 __asm__ __volatile__
Chris@102 622 (
Chris@102 623 "1:\n"
Chris@102 624 "mov %3, %1\n"
Chris@102 625 "ldq_l %0, %2\n"
Chris@102 626 "stq_c %1, %2\n"
Chris@102 627 "beq %1, 2f\n"
Chris@102 628
Chris@102 629 ".subsection 2\n"
Chris@102 630 "2: br 1b\n"
Chris@102 631 ".previous\n"
Chris@102 632
Chris@102 633 : "=&r" (original), // %0
Chris@102 634 "=&r" (tmp) // %1
Chris@102 635 : "m" (storage), // %2
Chris@102 636 "r" (v) // %3
Chris@102 637 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
Chris@102 638 );
Chris@102 639 fence_after(order);
Chris@102 640 return original;
Chris@102 641 }
Chris@102 642
Chris@102 643 static BOOST_FORCEINLINE bool compare_exchange_weak(
Chris@102 644 storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
Chris@102 645 {
Chris@102 646 fence_before(success_order);
Chris@102 647 int success;
Chris@102 648 storage_type current;
Chris@102 649 __asm__ __volatile__
Chris@102 650 (
Chris@102 651 "1:\n"
Chris@102 652 "ldq_l %2, %4\n" // current = *(&storage)
Chris@102 653 "cmpeq %2, %0, %3\n" // success = current == expected
Chris@102 654 "mov %2, %0\n" // expected = current
Chris@102 655 "beq %3, 2f\n" // if (success == 0) goto end
Chris@102 656 "stq_c %1, %4\n" // storage = desired; desired = store succeeded
Chris@102 657 "mov %1, %3\n" // success = desired
Chris@102 658 "2:\n"
Chris@102 659 : "+&r" (expected), // %0
Chris@102 660 "+&r" (desired), // %1
Chris@102 661 "=&r" (current), // %2
Chris@102 662 "=&r" (success) // %3
Chris@102 663 : "m" (storage) // %4
Chris@102 664 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
Chris@102 665 );
Chris@102 666 if (success)
Chris@102 667 fence_after(success_order);
Chris@102 668 else
Chris@102 669 fence_after(failure_order);
Chris@102 670 return !!success;
Chris@102 671 }
Chris@102 672
Chris@102 673 static BOOST_FORCEINLINE bool compare_exchange_strong(
Chris@102 674 storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
Chris@102 675 {
Chris@102 676 int success;
Chris@102 677 storage_type current, tmp;
Chris@102 678 fence_before(success_order);
Chris@102 679 __asm__ __volatile__
Chris@102 680 (
Chris@102 681 "1:\n"
Chris@102 682 "mov %5, %1\n" // tmp = desired
Chris@102 683 "ldq_l %2, %4\n" // current = *(&storage)
Chris@102 684 "cmpeq %2, %0, %3\n" // success = current == expected
Chris@102 685 "mov %2, %0\n" // expected = current
Chris@102 686 "beq %3, 2f\n" // if (success == 0) goto end
Chris@102 687 "stq_c %1, %4\n" // storage = tmp; tmp = store succeeded
Chris@102 688 "beq %1, 3f\n" // if (tmp == 0) goto retry
Chris@102 689 "mov %1, %3\n" // success = tmp
Chris@102 690 "2:\n"
Chris@102 691
Chris@102 692 ".subsection 2\n"
Chris@102 693 "3: br 1b\n"
Chris@102 694 ".previous\n"
Chris@102 695
Chris@102 696 : "+&r" (expected), // %0
Chris@102 697 "=&r" (tmp), // %1
Chris@102 698 "=&r" (current), // %2
Chris@102 699 "=&r" (success) // %3
Chris@102 700 : "m" (storage), // %4
Chris@102 701 "r" (desired) // %5
Chris@102 702 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
Chris@102 703 );
Chris@102 704 if (success)
Chris@102 705 fence_after(success_order);
Chris@102 706 else
Chris@102 707 fence_after(failure_order);
Chris@102 708 return !!success;
Chris@102 709 }
Chris@102 710
Chris@102 711 static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
Chris@102 712 {
Chris@102 713 storage_type original, modified;
Chris@102 714 fence_before(order);
Chris@102 715 __asm__ __volatile__
Chris@102 716 (
Chris@102 717 "1:\n"
Chris@102 718 "ldq_l %0, %2\n"
Chris@102 719 "addq %0, %3, %1\n"
Chris@102 720 "stq_c %1, %2\n"
Chris@102 721 "beq %1, 2f\n"
Chris@102 722
Chris@102 723 ".subsection 2\n"
Chris@102 724 "2: br 1b\n"
Chris@102 725 ".previous\n"
Chris@102 726
Chris@102 727 : "=&r" (original), // %0
Chris@102 728 "=&r" (modified) // %1
Chris@102 729 : "m" (storage), // %2
Chris@102 730 "r" (v) // %3
Chris@102 731 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
Chris@102 732 );
Chris@102 733 fence_after(order);
Chris@102 734 return original;
Chris@102 735 }
Chris@102 736
Chris@102 737 static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
Chris@102 738 {
Chris@102 739 storage_type original, modified;
Chris@102 740 fence_before(order);
Chris@102 741 __asm__ __volatile__
Chris@102 742 (
Chris@102 743 "1:\n"
Chris@102 744 "ldq_l %0, %2\n"
Chris@102 745 "subq %0, %3, %1\n"
Chris@102 746 "stq_c %1, %2\n"
Chris@102 747 "beq %1, 2f\n"
Chris@102 748
Chris@102 749 ".subsection 2\n"
Chris@102 750 "2: br 1b\n"
Chris@102 751 ".previous\n"
Chris@102 752
Chris@102 753 : "=&r" (original), // %0
Chris@102 754 "=&r" (modified) // %1
Chris@102 755 : "m" (storage), // %2
Chris@102 756 "r" (v) // %3
Chris@102 757 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
Chris@102 758 );
Chris@102 759 fence_after(order);
Chris@102 760 return original;
Chris@102 761 }
Chris@102 762
Chris@102 763 static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
Chris@102 764 {
Chris@102 765 storage_type original, modified;
Chris@102 766 fence_before(order);
Chris@102 767 __asm__ __volatile__
Chris@102 768 (
Chris@102 769 "1:\n"
Chris@102 770 "ldq_l %0, %2\n"
Chris@102 771 "and %0, %3, %1\n"
Chris@102 772 "stq_c %1, %2\n"
Chris@102 773 "beq %1, 2f\n"
Chris@102 774
Chris@102 775 ".subsection 2\n"
Chris@102 776 "2: br 1b\n"
Chris@102 777 ".previous\n"
Chris@102 778
Chris@102 779 : "=&r" (original), // %0
Chris@102 780 "=&r" (modified) // %1
Chris@102 781 : "m" (storage), // %2
Chris@102 782 "r" (v) // %3
Chris@102 783 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
Chris@102 784 );
Chris@102 785 fence_after(order);
Chris@102 786 return original;
Chris@102 787 }
Chris@102 788
Chris@102 789 static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
Chris@102 790 {
Chris@102 791 storage_type original, modified;
Chris@102 792 fence_before(order);
Chris@102 793 __asm__ __volatile__
Chris@102 794 (
Chris@102 795 "1:\n"
Chris@102 796 "ldq_l %0, %2\n"
Chris@102 797 "bis %0, %3, %1\n"
Chris@102 798 "stq_c %1, %2\n"
Chris@102 799 "beq %1, 2f\n"
Chris@102 800
Chris@102 801 ".subsection 2\n"
Chris@102 802 "2: br 1b\n"
Chris@102 803 ".previous\n"
Chris@102 804
Chris@102 805 : "=&r" (original), // %0
Chris@102 806 "=&r" (modified) // %1
Chris@102 807 : "m" (storage), // %2
Chris@102 808 "r" (v) // %3
Chris@102 809 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
Chris@102 810 );
Chris@102 811 fence_after(order);
Chris@102 812 return original;
Chris@102 813 }
Chris@102 814
Chris@102 815 static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
Chris@102 816 {
Chris@102 817 storage_type original, modified;
Chris@102 818 fence_before(order);
Chris@102 819 __asm__ __volatile__
Chris@102 820 (
Chris@102 821 "1:\n"
Chris@102 822 "ldq_l %0, %2\n"
Chris@102 823 "xor %0, %3, %1\n"
Chris@102 824 "stq_c %1, %2\n"
Chris@102 825 "beq %1, 2f\n"
Chris@102 826
Chris@102 827 ".subsection 2\n"
Chris@102 828 "2: br 1b\n"
Chris@102 829 ".previous\n"
Chris@102 830
Chris@102 831 : "=&r" (original), // %0
Chris@102 832 "=&r" (modified) // %1
Chris@102 833 : "m" (storage), // %2
Chris@102 834 "r" (v) // %3
Chris@102 835 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
Chris@102 836 );
Chris@102 837 fence_after(order);
Chris@102 838 return original;
Chris@102 839 }
Chris@102 840
Chris@102 841 static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
Chris@102 842 {
Chris@102 843 return !!exchange(storage, (storage_type)1, order);
Chris@102 844 }
Chris@102 845
Chris@102 846 static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
Chris@102 847 {
Chris@102 848 store(storage, 0, order);
Chris@102 849 }
Chris@102 850
Chris@102 851 static BOOST_FORCEINLINE bool is_lock_free(storage_type const volatile&) BOOST_NOEXCEPT
Chris@102 852 {
Chris@102 853 return true;
Chris@102 854 }
Chris@102 855 };
Chris@102 856
Chris@102 857
Chris@102 858 BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT
Chris@102 859 {
Chris@102 860 if (order != memory_order_relaxed)
Chris@102 861 __asm__ __volatile__ ("mb" ::: "memory");
Chris@102 862 }
Chris@102 863
Chris@102 864 BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT
Chris@102 865 {
Chris@102 866 if (order != memory_order_relaxed)
Chris@102 867 __asm__ __volatile__ ("" ::: "memory");
Chris@102 868 }
Chris@102 869
Chris@102 870 } // namespace detail
Chris@102 871 } // namespace atomics
Chris@102 872 } // namespace boost
Chris@102 873
Chris@102 874 #endif // BOOST_ATOMIC_DETAIL_OPS_GCC_ALPHA_HPP_INCLUDED_