Statistics
| Revision:

root / tmp / org.txm.statsengine.r.core.win32 / res / win32 / library / BH / include / boost / atomic / detail / ops_gcc_alpha.hpp @ 2486

History | View | Annotate | Download (25.9 kB)

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) 2009 Helge Bahmann
7
 * Copyright (c) 2013 Tim Blechmann
8
 * Copyright (c) 2014 Andrey Semashev
9
 */
10
/*!
11
 * \file   atomic/detail/ops_gcc_alpha.hpp
12
 *
13
 * This header contains implementation of the \c operations template.
14
 */
15

    
16
#ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_ALPHA_HPP_INCLUDED_
17
#define BOOST_ATOMIC_DETAIL_OPS_GCC_ALPHA_HPP_INCLUDED_
18

    
19
#include <boost/memory_order.hpp>
20
#include <boost/atomic/detail/config.hpp>
21
#include <boost/atomic/detail/storage_type.hpp>
22
#include <boost/atomic/detail/operations_fwd.hpp>
23
#include <boost/atomic/capabilities.hpp>
24

    
25
#ifdef BOOST_HAS_PRAGMA_ONCE
26
#pragma once
27
#endif
28

    
29
namespace boost {
30
namespace atomics {
31
namespace detail {
32

    
33
/*
34
  Refer to http://h71000.www7.hp.com/doc/82final/5601/5601pro_004.html
35
  (HP OpenVMS systems documentation) and the Alpha Architecture Reference Manual.
36
 */
37

    
38
/*
39
    NB: The most natural thing would be to write the increment/decrement
40
    operators along the following lines:
41

42
    __asm__ __volatile__
43
    (
44
        "1: ldl_l %0,%1 \n"
45
        "addl %0,1,%0 \n"
46
        "stl_c %0,%1 \n"
47
        "beq %0,1b\n"
48
        : "=&b" (tmp)
49
        : "m" (value)
50
        : "cc"
51
    );
52

53
    However according to the comments on the HP website and matching
54
    comments in the Linux kernel sources this defies branch prediction,
55
    as the cpu assumes that backward branches are always taken; so
56
    instead copy the trick from the Linux kernel, introduce a forward
57
    branch and back again.
58

59
    I have, however, had a hard time measuring the difference between
60
    the two versions in microbenchmarks -- I am leaving it in nevertheless
61
    as it apparently does not hurt either.
62
*/
63

    
64
struct gcc_alpha_operations_base
65
{
66
    static BOOST_FORCEINLINE void fence_before(memory_order order) BOOST_NOEXCEPT
67
    {
68
        if ((order & memory_order_release) != 0)
69
            __asm__ __volatile__ ("mb" ::: "memory");
70
    }
71

    
72
    static BOOST_FORCEINLINE void fence_after(memory_order order) BOOST_NOEXCEPT
73
    {
74
        if ((order & (memory_order_consume | memory_order_acquire)) != 0)
75
            __asm__ __volatile__ ("mb" ::: "memory");
76
    }
77

    
78
    static BOOST_FORCEINLINE void fence_after_store(memory_order order) BOOST_NOEXCEPT
79
    {
80
        if (order == memory_order_seq_cst)
81
            __asm__ __volatile__ ("mb" ::: "memory");
82
    }
83
};
84

    
85

    
86
template< bool Signed >
87
struct operations< 4u, Signed > :
88
    public gcc_alpha_operations_base
89
{
90
    typedef typename make_storage_type< 4u, Signed >::type storage_type;
91
    typedef typename make_storage_type< 4u, Signed >::aligned aligned_storage_type;
92

    
93
    static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
94
    {
95
        fence_before(order);
96
        storage = v;
97
        fence_after_store(order);
98
    }
99

    
100
    static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
101
    {
102
        storage_type v = storage;
103
        fence_after(order);
104
        return v;
105
    }
106

    
107
    static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
108
    {
109
        storage_type original, tmp;
110
        fence_before(order);
111
        __asm__ __volatile__
112
        (
113
            "1:\n"
114
            "mov %3, %1\n"
115
            "ldl_l %0, %2\n"
116
            "stl_c %1, %2\n"
117
            "beq %1, 2f\n"
118

    
119
            ".subsection 2\n"
120
            "2: br 1b\n"
121
            ".previous\n"
122

    
123
            : "=&r" (original),  // %0
124
              "=&r" (tmp)        // %1
125
            : "m" (storage),     // %2
126
              "r" (v)            // %3
127
            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
128
        );
129
        fence_after(order);
130
        return original;
131
    }
132

    
133
    static BOOST_FORCEINLINE bool compare_exchange_weak(
134
        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
135
    {
136
        fence_before(success_order);
137
        int success;
138
        storage_type current;
139
        __asm__ __volatile__
140
        (
141
            "1:\n"
142
            "ldl_l %2, %4\n"                // current = *(&storage)
143
            "cmpeq %2, %0, %3\n"            // success = current == expected
144
            "mov %2, %0\n"                  // expected = current
145
            "beq %3, 2f\n"                  // if (success == 0) goto end
146
            "stl_c %1, %4\n"                // storage = desired; desired = store succeeded
147
            "mov %1, %3\n"                  // success = desired
148
            "2:\n"
149
            : "+&r" (expected),  // %0
150
              "+&r" (desired),   // %1
151
              "=&r" (current),   // %2
152
              "=&r" (success)    // %3
153
            : "m" (storage)      // %4
154
            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
155
        );
156
        if (success)
157
            fence_after(success_order);
158
        else
159
            fence_after(failure_order);
160
        return !!success;
161
    }
162

    
163
    static BOOST_FORCEINLINE bool compare_exchange_strong(
164
        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
165
    {
166
        int success;
167
        storage_type current, tmp;
168
        fence_before(success_order);
169
        __asm__ __volatile__
170
        (
171
            "1:\n"
172
            "mov %5, %1\n"                  // tmp = desired
173
            "ldl_l %2, %4\n"                // current = *(&storage)
174
            "cmpeq %2, %0, %3\n"            // success = current == expected
175
            "mov %2, %0\n"                  // expected = current
176
            "beq %3, 2f\n"                  // if (success == 0) goto end
177
            "stl_c %1, %4\n"                // storage = tmp; tmp = store succeeded
178
            "beq %1, 3f\n"                  // if (tmp == 0) goto retry
179
            "mov %1, %3\n"                  // success = tmp
180
            "2:\n"
181

    
182
            ".subsection 2\n"
183
            "3: br 1b\n"
184
            ".previous\n"
185

    
186
            : "+&r" (expected),  // %0
187
              "=&r" (tmp),       // %1
188
              "=&r" (current),   // %2
189
              "=&r" (success)    // %3
190
            : "m" (storage),     // %4
191
              "r" (desired)      // %5
192
            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
193
        );
194
        if (success)
195
            fence_after(success_order);
196
        else
197
            fence_after(failure_order);
198
        return !!success;
199
    }
200

    
201
    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
202
    {
203
        storage_type original, modified;
204
        fence_before(order);
205
        __asm__ __volatile__
206
        (
207
            "1:\n"
208
            "ldl_l %0, %2\n"
209
            "addl %0, %3, %1\n"
210
            "stl_c %1, %2\n"
211
            "beq %1, 2f\n"
212

    
213
            ".subsection 2\n"
214
            "2: br 1b\n"
215
            ".previous\n"
216

    
217
            : "=&r" (original),  // %0
218
              "=&r" (modified)   // %1
219
            : "m" (storage),     // %2
220
              "r" (v)            // %3
221
            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
222
        );
223
        fence_after(order);
224
        return original;
225
    }
226

    
227
    static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
228
    {
229
        storage_type original, modified;
230
        fence_before(order);
231
        __asm__ __volatile__
232
        (
233
            "1:\n"
234
            "ldl_l %0, %2\n"
235
            "subl %0, %3, %1\n"
236
            "stl_c %1, %2\n"
237
            "beq %1, 2f\n"
238

    
239
            ".subsection 2\n"
240
            "2: br 1b\n"
241
            ".previous\n"
242

    
243
            : "=&r" (original),  // %0
244
              "=&r" (modified)   // %1
245
            : "m" (storage),     // %2
246
              "r" (v)            // %3
247
            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
248
        );
249
        fence_after(order);
250
        return original;
251
    }
252

    
253
    static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
254
    {
255
        storage_type original, modified;
256
        fence_before(order);
257
        __asm__ __volatile__
258
        (
259
            "1:\n"
260
            "ldl_l %0, %2\n"
261
            "and %0, %3, %1\n"
262
            "stl_c %1, %2\n"
263
            "beq %1, 2f\n"
264

    
265
            ".subsection 2\n"
266
            "2: br 1b\n"
267
            ".previous\n"
268

    
269
            : "=&r" (original),  // %0
270
              "=&r" (modified)   // %1
271
            : "m" (storage),     // %2
272
              "r" (v)            // %3
273
            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
274
        );
275
        fence_after(order);
276
        return original;
277
    }
278

    
279
    static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
280
    {
281
        storage_type original, modified;
282
        fence_before(order);
283
        __asm__ __volatile__
284
        (
285
            "1:\n"
286
            "ldl_l %0, %2\n"
287
            "bis %0, %3, %1\n"
288
            "stl_c %1, %2\n"
289
            "beq %1, 2f\n"
290

    
291
            ".subsection 2\n"
292
            "2: br 1b\n"
293
            ".previous\n"
294

    
295
            : "=&r" (original),  // %0
296
              "=&r" (modified)   // %1
297
            : "m" (storage),     // %2
298
              "r" (v)            // %3
299
            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
300
        );
301
        fence_after(order);
302
        return original;
303
    }
304

    
305
    static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
306
    {
307
        storage_type original, modified;
308
        fence_before(order);
309
        __asm__ __volatile__
310
        (
311
            "1:\n"
312
            "ldl_l %0, %2\n"
313
            "xor %0, %3, %1\n"
314
            "stl_c %1, %2\n"
315
            "beq %1, 2f\n"
316

    
317
            ".subsection 2\n"
318
            "2: br 1b\n"
319
            ".previous\n"
320

    
321
            : "=&r" (original),  // %0
322
              "=&r" (modified)   // %1
323
            : "m" (storage),     // %2
324
              "r" (v)            // %3
325
            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
326
        );
327
        fence_after(order);
328
        return original;
329
    }
330

    
331
    static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
332
    {
333
        return !!exchange(storage, (storage_type)1, order);
334
    }
335

    
336
    static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
337
    {
338
        store(storage, 0, order);
339
    }
340

    
341
    static BOOST_FORCEINLINE bool is_lock_free(storage_type const volatile&) BOOST_NOEXCEPT
342
    {
343
        return true;
344
    }
345
};
346

    
347

    
348
template< >
349
struct operations< 1u, false > :
350
    public operations< 4u, false >
351
{
352
    typedef operations< 4u, false > base_type;
353
    typedef base_type::storage_type storage_type;
354

    
355
    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
356
    {
357
        storage_type original, modified;
358
        fence_before(order);
359
        __asm__ __volatile__
360
        (
361
            "1:\n"
362
            "ldl_l %0, %2\n"
363
            "addl %0, %3, %1\n"
364
            "zapnot %1, #1, %1\n"
365
            "stl_c %1, %2\n"
366
            "beq %1, 2f\n"
367

    
368
            ".subsection 2\n"
369
            "2: br 1b\n"
370
            ".previous\n"
371

    
372
            : "=&r" (original),  // %0
373
              "=&r" (modified)   // %1
374
            : "m" (storage),     // %2
375
              "r" (v)            // %3
376
            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
377
        );
378
        fence_after(order);
379
        return original;
380
    }
381

    
382
    static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
383
    {
384
        storage_type original, modified;
385
        fence_before(order);
386
        __asm__ __volatile__
387
        (
388
            "1:\n"
389
            "ldl_l %0, %2\n"
390
            "subl %0, %3, %1\n"
391
            "zapnot %1, #1, %1\n"
392
            "stl_c %1, %2\n"
393
            "beq %1, 2f\n"
394

    
395
            ".subsection 2\n"
396
            "2: br 1b\n"
397
            ".previous\n"
398

    
399
            : "=&r" (original),  // %0
400
              "=&r" (modified)   // %1
401
            : "m" (storage),     // %2
402
              "r" (v)            // %3
403
            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
404
        );
405
        fence_after(order);
406
        return original;
407
    }
408
};
409

    
410
template< >
411
struct operations< 1u, true > :
412
    public operations< 4u, true >
413
{
414
    typedef operations< 4u, true > base_type;
415
    typedef base_type::storage_type storage_type;
416

    
417
    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
418
    {
419
        storage_type original, modified;
420
        fence_before(order);
421
        __asm__ __volatile__
422
        (
423
            "1:\n"
424
            "ldl_l %0, %2\n"
425
            "addl %0, %3, %1\n"
426
            "sextb %1, %1\n"
427
            "stl_c %1, %2\n"
428
            "beq %1, 2f\n"
429

    
430
            ".subsection 2\n"
431
            "2: br 1b\n"
432
            ".previous\n"
433

    
434
            : "=&r" (original),  // %0
435
              "=&r" (modified)   // %1
436
            : "m" (storage),     // %2
437
              "r" (v)            // %3
438
            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
439
        );
440
        fence_after(order);
441
        return original;
442
    }
443

    
444
    static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
445
    {
446
        storage_type original, modified;
447
        fence_before(order);
448
        __asm__ __volatile__
449
        (
450
            "1:\n"
451
            "ldl_l %0, %2\n"
452
            "subl %0, %3, %1\n"
453
            "sextb %1, %1\n"
454
            "stl_c %1, %2\n"
455
            "beq %1, 2f\n"
456

    
457
            ".subsection 2\n"
458
            "2: br 1b\n"
459
            ".previous\n"
460

    
461
            : "=&r" (original),  // %0
462
              "=&r" (modified)   // %1
463
            : "m" (storage),     // %2
464
              "r" (v)            // %3
465
            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
466
        );
467
        fence_after(order);
468
        return original;
469
    }
470
};
471

    
472

    
473
template< >
474
struct operations< 2u, false > :
475
    public operations< 4u, false >
476
{
477
    typedef operations< 4u, false > base_type;
478
    typedef base_type::storage_type storage_type;
479

    
480
    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
481
    {
482
        storage_type original, modified;
483
        fence_before(order);
484
        __asm__ __volatile__
485
        (
486
            "1:\n"
487
            "ldl_l %0, %2\n"
488
            "addl %0, %3, %1\n"
489
            "zapnot %1, #3, %1\n"
490
            "stl_c %1, %2\n"
491
            "beq %1, 2f\n"
492

    
493
            ".subsection 2\n"
494
            "2: br 1b\n"
495
            ".previous\n"
496

    
497
            : "=&r" (original),  // %0
498
              "=&r" (modified)   // %1
499
            : "m" (storage),     // %2
500
              "r" (v)            // %3
501
            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
502
        );
503
        fence_after(order);
504
        return original;
505
    }
506

    
507
    static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
508
    {
509
        storage_type original, modified;
510
        fence_before(order);
511
        __asm__ __volatile__
512
        (
513
            "1:\n"
514
            "ldl_l %0, %2\n"
515
            "subl %0, %3, %1\n"
516
            "zapnot %1, #3, %1\n"
517
            "stl_c %1, %2\n"
518
            "beq %1, 2f\n"
519

    
520
            ".subsection 2\n"
521
            "2: br 1b\n"
522
            ".previous\n"
523

    
524
            : "=&r" (original),  // %0
525
              "=&r" (modified)   // %1
526
            : "m" (storage),     // %2
527
              "r" (v)            // %3
528
            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
529
        );
530
        fence_after(order);
531
        return original;
532
    }
533
};
534

    
535
template< >
536
struct operations< 2u, true > :
537
    public operations< 4u, true >
538
{
539
    typedef operations< 4u, true > base_type;
540
    typedef base_type::storage_type storage_type;
541

    
542
    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
543
    {
544
        storage_type original, modified;
545
        fence_before(order);
546
        __asm__ __volatile__
547
        (
548
            "1:\n"
549
            "ldl_l %0, %2\n"
550
            "addl %0, %3, %1\n"
551
            "sextw %1, %1\n"
552
            "stl_c %1, %2\n"
553
            "beq %1, 2f\n"
554

    
555
            ".subsection 2\n"
556
            "2: br 1b\n"
557
            ".previous\n"
558

    
559
            : "=&r" (original),  // %0
560
              "=&r" (modified)   // %1
561
            : "m" (storage),     // %2
562
              "r" (v)            // %3
563
            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
564
        );
565
        fence_after(order);
566
        return original;
567
    }
568

    
569
    static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
570
    {
571
        storage_type original, modified;
572
        fence_before(order);
573
        __asm__ __volatile__
574
        (
575
            "1:\n"
576
            "ldl_l %0, %2\n"
577
            "subl %0, %3, %1\n"
578
            "sextw %1, %1\n"
579
            "stl_c %1, %2\n"
580
            "beq %1, 2f\n"
581

    
582
            ".subsection 2\n"
583
            "2: br 1b\n"
584
            ".previous\n"
585

    
586
            : "=&r" (original),  // %0
587
              "=&r" (modified)   // %1
588
            : "m" (storage),     // %2
589
              "r" (v)            // %3
590
            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
591
        );
592
        fence_after(order);
593
        return original;
594
    }
595
};
596

    
597

    
598
template< bool Signed >
599
struct operations< 8u, Signed > :
600
    public gcc_alpha_operations_base
601
{
602
    typedef typename make_storage_type< 8u, Signed >::type storage_type;
603
    typedef typename make_storage_type< 8u, Signed >::aligned aligned_storage_type;
604

    
605
    static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
606
    {
607
        fence_before(order);
608
        storage = v;
609
        fence_after_store(order);
610
    }
611

    
612
    static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
613
    {
614
        storage_type v = storage;
615
        fence_after(order);
616
        return v;
617
    }
618

    
619
    static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
620
    {
621
        storage_type original, tmp;
622
        fence_before(order);
623
        __asm__ __volatile__
624
        (
625
            "1:\n"
626
            "mov %3, %1\n"
627
            "ldq_l %0, %2\n"
628
            "stq_c %1, %2\n"
629
            "beq %1, 2f\n"
630

    
631
            ".subsection 2\n"
632
            "2: br 1b\n"
633
            ".previous\n"
634

    
635
            : "=&r" (original),  // %0
636
              "=&r" (tmp)        // %1
637
            : "m" (storage),     // %2
638
              "r" (v)            // %3
639
            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
640
        );
641
        fence_after(order);
642
        return original;
643
    }
644

    
645
    static BOOST_FORCEINLINE bool compare_exchange_weak(
646
        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
647
    {
648
        fence_before(success_order);
649
        int success;
650
        storage_type current;
651
        __asm__ __volatile__
652
        (
653
            "1:\n"
654
            "ldq_l %2, %4\n"                // current = *(&storage)
655
            "cmpeq %2, %0, %3\n"            // success = current == expected
656
            "mov %2, %0\n"                  // expected = current
657
            "beq %3, 2f\n"                  // if (success == 0) goto end
658
            "stq_c %1, %4\n"                // storage = desired; desired = store succeeded
659
            "mov %1, %3\n"                  // success = desired
660
            "2:\n"
661
            : "+&r" (expected),  // %0
662
              "+&r" (desired),   // %1
663
              "=&r" (current),   // %2
664
              "=&r" (success)    // %3
665
            : "m" (storage)      // %4
666
            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
667
        );
668
        if (success)
669
            fence_after(success_order);
670
        else
671
            fence_after(failure_order);
672
        return !!success;
673
    }
674

    
675
    static BOOST_FORCEINLINE bool compare_exchange_strong(
676
        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
677
    {
678
        int success;
679
        storage_type current, tmp;
680
        fence_before(success_order);
681
        __asm__ __volatile__
682
        (
683
            "1:\n"
684
            "mov %5, %1\n"                  // tmp = desired
685
            "ldq_l %2, %4\n"                // current = *(&storage)
686
            "cmpeq %2, %0, %3\n"            // success = current == expected
687
            "mov %2, %0\n"                  // expected = current
688
            "beq %3, 2f\n"                  // if (success == 0) goto end
689
            "stq_c %1, %4\n"                // storage = tmp; tmp = store succeeded
690
            "beq %1, 3f\n"                  // if (tmp == 0) goto retry
691
            "mov %1, %3\n"                  // success = tmp
692
            "2:\n"
693

    
694
            ".subsection 2\n"
695
            "3: br 1b\n"
696
            ".previous\n"
697

    
698
            : "+&r" (expected),  // %0
699
              "=&r" (tmp),       // %1
700
              "=&r" (current),   // %2
701
              "=&r" (success)    // %3
702
            : "m" (storage),     // %4
703
              "r" (desired)      // %5
704
            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
705
        );
706
        if (success)
707
            fence_after(success_order);
708
        else
709
            fence_after(failure_order);
710
        return !!success;
711
    }
712

    
713
    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
714
    {
715
        storage_type original, modified;
716
        fence_before(order);
717
        __asm__ __volatile__
718
        (
719
            "1:\n"
720
            "ldq_l %0, %2\n"
721
            "addq %0, %3, %1\n"
722
            "stq_c %1, %2\n"
723
            "beq %1, 2f\n"
724

    
725
            ".subsection 2\n"
726
            "2: br 1b\n"
727
            ".previous\n"
728

    
729
            : "=&r" (original),  // %0
730
              "=&r" (modified)   // %1
731
            : "m" (storage),     // %2
732
              "r" (v)            // %3
733
            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
734
        );
735
        fence_after(order);
736
        return original;
737
    }
738

    
739
    static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
740
    {
741
        storage_type original, modified;
742
        fence_before(order);
743
        __asm__ __volatile__
744
        (
745
            "1:\n"
746
            "ldq_l %0, %2\n"
747
            "subq %0, %3, %1\n"
748
            "stq_c %1, %2\n"
749
            "beq %1, 2f\n"
750

    
751
            ".subsection 2\n"
752
            "2: br 1b\n"
753
            ".previous\n"
754

    
755
            : "=&r" (original),  // %0
756
              "=&r" (modified)   // %1
757
            : "m" (storage),     // %2
758
              "r" (v)            // %3
759
            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
760
        );
761
        fence_after(order);
762
        return original;
763
    }
764

    
765
    static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
766
    {
767
        storage_type original, modified;
768
        fence_before(order);
769
        __asm__ __volatile__
770
        (
771
            "1:\n"
772
            "ldq_l %0, %2\n"
773
            "and %0, %3, %1\n"
774
            "stq_c %1, %2\n"
775
            "beq %1, 2f\n"
776

    
777
            ".subsection 2\n"
778
            "2: br 1b\n"
779
            ".previous\n"
780

    
781
            : "=&r" (original),  // %0
782
              "=&r" (modified)   // %1
783
            : "m" (storage),     // %2
784
              "r" (v)            // %3
785
            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
786
        );
787
        fence_after(order);
788
        return original;
789
    }
790

    
791
    static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
792
    {
793
        storage_type original, modified;
794
        fence_before(order);
795
        __asm__ __volatile__
796
        (
797
            "1:\n"
798
            "ldq_l %0, %2\n"
799
            "bis %0, %3, %1\n"
800
            "stq_c %1, %2\n"
801
            "beq %1, 2f\n"
802

    
803
            ".subsection 2\n"
804
            "2: br 1b\n"
805
            ".previous\n"
806

    
807
            : "=&r" (original),  // %0
808
              "=&r" (modified)   // %1
809
            : "m" (storage),     // %2
810
              "r" (v)            // %3
811
            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
812
        );
813
        fence_after(order);
814
        return original;
815
    }
816

    
817
    static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
818
    {
819
        storage_type original, modified;
820
        fence_before(order);
821
        __asm__ __volatile__
822
        (
823
            "1:\n"
824
            "ldq_l %0, %2\n"
825
            "xor %0, %3, %1\n"
826
            "stq_c %1, %2\n"
827
            "beq %1, 2f\n"
828

    
829
            ".subsection 2\n"
830
            "2: br 1b\n"
831
            ".previous\n"
832

    
833
            : "=&r" (original),  // %0
834
              "=&r" (modified)   // %1
835
            : "m" (storage),     // %2
836
              "r" (v)            // %3
837
            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
838
        );
839
        fence_after(order);
840
        return original;
841
    }
842

    
843
    static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
844
    {
845
        return !!exchange(storage, (storage_type)1, order);
846
    }
847

    
848
    static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
849
    {
850
        store(storage, 0, order);
851
    }
852

    
853
    static BOOST_FORCEINLINE bool is_lock_free(storage_type const volatile&) BOOST_NOEXCEPT
854
    {
855
        return true;
856
    }
857
};
858

    
859

    
860
BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT
861
{
862
    if (order != memory_order_relaxed)
863
        __asm__ __volatile__ ("mb" ::: "memory");
864
}
865

    
866
BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT
867
{
868
    if (order != memory_order_relaxed)
869
        __asm__ __volatile__ ("" ::: "memory");
870
}
871

    
872
} // namespace detail
873
} // namespace atomics
874
} // namespace boost
875

    
876
#endif // BOOST_ATOMIC_DETAIL_OPS_GCC_ALPHA_HPP_INCLUDED_