1#ifndef __ASM_METAG_ATOMIC_LNKGET_H
2#define __ASM_METAG_ATOMIC_LNKGET_H
3
4#define ATOMIC_INIT(i) { (i) }
5
6#define atomic_set(v, i) ((v)->counter = (i))
7
8#include <linux/compiler.h>
9
10#include <asm/barrier.h>
11
12
13
14
15
16
17
18static inline int atomic_read(const atomic_t *v)
19{
20 int temp;
21
22 asm volatile (
23 "LNKGETD %0, [%1]\n"
24 : "=da" (temp)
25 : "da" (&v->counter));
26
27 return temp;
28}
29
30static inline void atomic_add(int i, atomic_t *v)
31{
32 int temp;
33
34 asm volatile (
35 "1: LNKGETD %0, [%1]\n"
36 " ADD %0, %0, %2\n"
37 " LNKSETD [%1], %0\n"
38 " DEFR %0, TXSTAT\n"
39 " ANDT %0, %0, #HI(0x3f000000)\n"
40 " CMPT %0, #HI(0x02000000)\n"
41 " BNZ 1b\n"
42 : "=&d" (temp)
43 : "da" (&v->counter), "bd" (i)
44 : "cc");
45}
46
47static inline void atomic_sub(int i, atomic_t *v)
48{
49 int temp;
50
51 asm volatile (
52 "1: LNKGETD %0, [%1]\n"
53 " SUB %0, %0, %2\n"
54 " LNKSETD [%1], %0\n"
55 " DEFR %0, TXSTAT\n"
56 " ANDT %0, %0, #HI(0x3f000000)\n"
57 " CMPT %0, #HI(0x02000000)\n"
58 " BNZ 1b\n"
59 : "=&d" (temp)
60 : "da" (&v->counter), "bd" (i)
61 : "cc");
62}
63
64static inline int atomic_add_return(int i, atomic_t *v)
65{
66 int result, temp;
67
68 smp_mb();
69
70 asm volatile (
71 "1: LNKGETD %1, [%2]\n"
72 " ADD %1, %1, %3\n"
73 " LNKSETD [%2], %1\n"
74 " DEFR %0, TXSTAT\n"
75 " ANDT %0, %0, #HI(0x3f000000)\n"
76 " CMPT %0, #HI(0x02000000)\n"
77 " BNZ 1b\n"
78 : "=&d" (temp), "=&da" (result)
79 : "da" (&v->counter), "bd" (i)
80 : "cc");
81
82 smp_mb();
83
84 return result;
85}
86
87static inline int atomic_sub_return(int i, atomic_t *v)
88{
89 int result, temp;
90
91 smp_mb();
92
93 asm volatile (
94 "1: LNKGETD %1, [%2]\n"
95 " SUB %1, %1, %3\n"
96 " LNKSETD [%2], %1\n"
97 " DEFR %0, TXSTAT\n"
98 " ANDT %0, %0, #HI(0x3f000000)\n"
99 " CMPT %0, #HI(0x02000000)\n"
100 " BNZ 1b\n"
101 : "=&d" (temp), "=&da" (result)
102 : "da" (&v->counter), "bd" (i)
103 : "cc");
104
105 smp_mb();
106
107 return result;
108}
109
110static inline void atomic_clear_mask(unsigned int mask, atomic_t *v)
111{
112 int temp;
113
114 asm volatile (
115 "1: LNKGETD %0, [%1]\n"
116 " AND %0, %0, %2\n"
117 " LNKSETD [%1] %0\n"
118 " DEFR %0, TXSTAT\n"
119 " ANDT %0, %0, #HI(0x3f000000)\n"
120 " CMPT %0, #HI(0x02000000)\n"
121 " BNZ 1b\n"
122 : "=&d" (temp)
123 : "da" (&v->counter), "bd" (~mask)
124 : "cc");
125}
126
127static inline void atomic_set_mask(unsigned int mask, atomic_t *v)
128{
129 int temp;
130
131 asm volatile (
132 "1: LNKGETD %0, [%1]\n"
133 " OR %0, %0, %2\n"
134 " LNKSETD [%1], %0\n"
135 " DEFR %0, TXSTAT\n"
136 " ANDT %0, %0, #HI(0x3f000000)\n"
137 " CMPT %0, #HI(0x02000000)\n"
138 " BNZ 1b\n"
139 : "=&d" (temp)
140 : "da" (&v->counter), "bd" (mask)
141 : "cc");
142}
143
144static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
145{
146 int result, temp;
147
148 smp_mb();
149
150 asm volatile (
151 "1: LNKGETD %1, [%2]\n"
152 " CMP %1, %3\n"
153 " LNKSETDEQ [%2], %4\n"
154 " BNE 2f\n"
155 " DEFR %0, TXSTAT\n"
156 " ANDT %0, %0, #HI(0x3f000000)\n"
157 " CMPT %0, #HI(0x02000000)\n"
158 " BNZ 1b\n"
159 "2:\n"
160 : "=&d" (temp), "=&d" (result)
161 : "da" (&v->counter), "bd" (old), "da" (new)
162 : "cc");
163
164 smp_mb();
165
166 return result;
167}
168
169static inline int atomic_xchg(atomic_t *v, int new)
170{
171 int temp, old;
172
173 asm volatile (
174 "1: LNKGETD %1, [%2]\n"
175 " LNKSETD [%2], %3\n"
176 " DEFR %0, TXSTAT\n"
177 " ANDT %0, %0, #HI(0x3f000000)\n"
178 " CMPT %0, #HI(0x02000000)\n"
179 " BNZ 1b\n"
180 : "=&d" (temp), "=&d" (old)
181 : "da" (&v->counter), "da" (new)
182 : "cc");
183
184 return old;
185}
186
187static inline int __atomic_add_unless(atomic_t *v, int a, int u)
188{
189 int result, temp;
190
191 smp_mb();
192
193 asm volatile (
194 "1: LNKGETD %1, [%2]\n"
195 " CMP %1, %3\n"
196 " ADD %0, %1, %4\n"
197 " LNKSETDNE [%2], %0\n"
198 " BEQ 2f\n"
199 " DEFR %0, TXSTAT\n"
200 " ANDT %0, %0, #HI(0x3f000000)\n"
201 " CMPT %0, #HI(0x02000000)\n"
202 " BNZ 1b\n"
203 "2:\n"
204 : "=&d" (temp), "=&d" (result)
205 : "da" (&v->counter), "bd" (u), "bd" (a)
206 : "cc");
207
208 smp_mb();
209
210 return result;
211}
212
213static inline int atomic_sub_if_positive(int i, atomic_t *v)
214{
215 int result, temp;
216
217 asm volatile (
218 "1: LNKGETD %1, [%2]\n"
219 " SUBS %1, %1, %3\n"
220 " LNKSETDGE [%2], %1\n"
221 " BLT 2f\n"
222 " DEFR %0, TXSTAT\n"
223 " ANDT %0, %0, #HI(0x3f000000)\n"
224 " CMPT %0, #HI(0x02000000)\n"
225 " BNZ 1b\n"
226 "2:\n"
227 : "=&d" (temp), "=&da" (result)
228 : "da" (&v->counter), "bd" (i)
229 : "cc");
230
231 return result;
232}
233
234#endif
235