Commit | Line | Data |
---|---|---|
24f287e4 | 1 | /* atomic.S: These things are too big to do inline. |
1da177e4 | 2 | * |
193d2aad | 3 | * Copyright (C) 1999, 2007 2012 David S. Miller (davem@davemloft.net) |
1da177e4 LT |
4 | */ |
5 | ||
8695c37d | 6 | #include <linux/linkage.h> |
1da177e4 | 7 | #include <asm/asi.h> |
24f287e4 | 8 | #include <asm/backoff.h> |
1da177e4 | 9 | |
1da177e4 LT |
10 | .text |
11 | ||
12 | /* Two versions of the atomic routines, one that | |
13 | * does not return a value and does not perform | |
14 | * memory barriers, and a second which returns | |
15 | * a value and does the barriers. | |
16 | */ | |
8695c37d | 17 | ENTRY(atomic_add) /* %o0 = increment, %o1 = atomic_ptr */ |
24f287e4 | 18 | BACKOFF_SETUP(%o2) |
1da177e4 LT |
19 | 1: lduw [%o1], %g1 |
20 | add %g1, %o0, %g7 | |
21 | cas [%o1], %g1, %g7 | |
22 | cmp %g1, %g7 | |
0f58189d | 23 | bne,pn %icc, BACKOFF_LABEL(2f, 1b) |
1da177e4 LT |
24 | nop |
25 | retl | |
26 | nop | |
24f287e4 | 27 | 2: BACKOFF_SPIN(%o2, %o3, 1b) |
8695c37d | 28 | ENDPROC(atomic_add) |
1da177e4 | 29 | |
8695c37d | 30 | ENTRY(atomic_sub) /* %o0 = decrement, %o1 = atomic_ptr */ |
24f287e4 | 31 | BACKOFF_SETUP(%o2) |
1da177e4 LT |
32 | 1: lduw [%o1], %g1 |
33 | sub %g1, %o0, %g7 | |
34 | cas [%o1], %g1, %g7 | |
35 | cmp %g1, %g7 | |
0f58189d | 36 | bne,pn %icc, BACKOFF_LABEL(2f, 1b) |
1da177e4 LT |
37 | nop |
38 | retl | |
39 | nop | |
24f287e4 | 40 | 2: BACKOFF_SPIN(%o2, %o3, 1b) |
8695c37d | 41 | ENDPROC(atomic_sub) |
1da177e4 | 42 | |
8695c37d | 43 | ENTRY(atomic_add_ret) /* %o0 = increment, %o1 = atomic_ptr */ |
24f287e4 | 44 | BACKOFF_SETUP(%o2) |
1da177e4 LT |
45 | 1: lduw [%o1], %g1 |
46 | add %g1, %o0, %g7 | |
47 | cas [%o1], %g1, %g7 | |
48 | cmp %g1, %g7 | |
0f58189d | 49 | bne,pn %icc, BACKOFF_LABEL(2f, 1b) |
6ec27475 | 50 | add %g1, %o0, %g1 |
1da177e4 | 51 | retl |
6ec27475 | 52 | sra %g1, 0, %o0 |
24f287e4 | 53 | 2: BACKOFF_SPIN(%o2, %o3, 1b) |
8695c37d | 54 | ENDPROC(atomic_add_ret) |
1da177e4 | 55 | |
8695c37d | 56 | ENTRY(atomic_sub_ret) /* %o0 = decrement, %o1 = atomic_ptr */ |
24f287e4 | 57 | BACKOFF_SETUP(%o2) |
1da177e4 LT |
58 | 1: lduw [%o1], %g1 |
59 | sub %g1, %o0, %g7 | |
60 | cas [%o1], %g1, %g7 | |
61 | cmp %g1, %g7 | |
0f58189d | 62 | bne,pn %icc, BACKOFF_LABEL(2f, 1b) |
6ec27475 | 63 | sub %g1, %o0, %g1 |
1da177e4 | 64 | retl |
6ec27475 | 65 | sra %g1, 0, %o0 |
24f287e4 | 66 | 2: BACKOFF_SPIN(%o2, %o3, 1b) |
8695c37d | 67 | ENDPROC(atomic_sub_ret) |
1da177e4 | 68 | |
8695c37d | 69 | ENTRY(atomic64_add) /* %o0 = increment, %o1 = atomic_ptr */ |
24f287e4 | 70 | BACKOFF_SETUP(%o2) |
1da177e4 LT |
71 | 1: ldx [%o1], %g1 |
72 | add %g1, %o0, %g7 | |
73 | casx [%o1], %g1, %g7 | |
74 | cmp %g1, %g7 | |
0f58189d | 75 | bne,pn %xcc, BACKOFF_LABEL(2f, 1b) |
1da177e4 LT |
76 | nop |
77 | retl | |
78 | nop | |
24f287e4 | 79 | 2: BACKOFF_SPIN(%o2, %o3, 1b) |
8695c37d | 80 | ENDPROC(atomic64_add) |
1da177e4 | 81 | |
8695c37d | 82 | ENTRY(atomic64_sub) /* %o0 = decrement, %o1 = atomic_ptr */ |
24f287e4 | 83 | BACKOFF_SETUP(%o2) |
1da177e4 LT |
84 | 1: ldx [%o1], %g1 |
85 | sub %g1, %o0, %g7 | |
86 | casx [%o1], %g1, %g7 | |
87 | cmp %g1, %g7 | |
0f58189d | 88 | bne,pn %xcc, BACKOFF_LABEL(2f, 1b) |
1da177e4 LT |
89 | nop |
90 | retl | |
91 | nop | |
24f287e4 | 92 | 2: BACKOFF_SPIN(%o2, %o3, 1b) |
8695c37d | 93 | ENDPROC(atomic64_sub) |
1da177e4 | 94 | |
8695c37d | 95 | ENTRY(atomic64_add_ret) /* %o0 = increment, %o1 = atomic_ptr */ |
24f287e4 | 96 | BACKOFF_SETUP(%o2) |
1da177e4 LT |
97 | 1: ldx [%o1], %g1 |
98 | add %g1, %o0, %g7 | |
99 | casx [%o1], %g1, %g7 | |
100 | cmp %g1, %g7 | |
0f58189d | 101 | bne,pn %xcc, BACKOFF_LABEL(2f, 1b) |
b445e26c | 102 | nop |
6ec27475 MP |
103 | retl |
104 | add %g1, %o0, %o0 | |
24f287e4 | 105 | 2: BACKOFF_SPIN(%o2, %o3, 1b) |
8695c37d | 106 | ENDPROC(atomic64_add_ret) |
1da177e4 | 107 | |
8695c37d | 108 | ENTRY(atomic64_sub_ret) /* %o0 = decrement, %o1 = atomic_ptr */ |
24f287e4 | 109 | BACKOFF_SETUP(%o2) |
1da177e4 LT |
110 | 1: ldx [%o1], %g1 |
111 | sub %g1, %o0, %g7 | |
112 | casx [%o1], %g1, %g7 | |
113 | cmp %g1, %g7 | |
0f58189d | 114 | bne,pn %xcc, BACKOFF_LABEL(2f, 1b) |
b445e26c | 115 | nop |
6ec27475 MP |
116 | retl |
117 | sub %g1, %o0, %o0 | |
24f287e4 | 118 | 2: BACKOFF_SPIN(%o2, %o3, 1b) |
8695c37d | 119 | ENDPROC(atomic64_sub_ret) |
193d2aad DM |
120 | |
121 | ENTRY(atomic64_dec_if_positive) /* %o0 = atomic_ptr */ | |
122 | BACKOFF_SETUP(%o2) | |
123 | 1: ldx [%o0], %g1 | |
124 | brlez,pn %g1, 3f | |
125 | sub %g1, 1, %g7 | |
126 | casx [%o0], %g1, %g7 | |
127 | cmp %g1, %g7 | |
128 | bne,pn %xcc, BACKOFF_LABEL(2f, 1b) | |
129 | nop | |
130 | 3: retl | |
131 | sub %g1, 1, %o0 | |
132 | 2: BACKOFF_SPIN(%o2, %o3, 1b) | |
133 | ENDPROC(atomic64_dec_if_positive) |