|
71 | 71 | * store NEW in MEM. Return the initial value in MEM. Success is
|
72 | 72 | * indicated by comparing RETURN with OLD.
|
73 | 73 | */
|
74 |
| -#define __cmpxchg_relaxed(ptr, old, new, size) \ |
75 |
| -({ \ |
76 |
| - __typeof__(ptr) __ptr = (ptr); \ |
77 |
| - __typeof__(*(ptr)) __old = (old); \ |
78 |
| - __typeof__(*(ptr)) __new = (new); \ |
79 |
| - __typeof__(*(ptr)) __ret; \ |
80 |
| - register unsigned int __rc; \ |
81 |
| - switch (size) { \ |
82 |
| - case 4: \ |
83 |
| - __asm__ __volatile__ ( \ |
84 |
| - "0: lr.w %0, %2\n" \ |
85 |
| - " bne %0, %z3, 1f\n" \ |
86 |
| - " sc.w %1, %z4, %2\n" \ |
87 |
| - " bnez %1, 0b\n" \ |
88 |
| - "1:\n" \ |
89 |
| - : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \ |
90 |
| - : "rJ" ((long)__old), "rJ" (__new) \ |
91 |
| - : "memory"); \ |
92 |
| - break; \ |
93 |
| - case 8: \ |
94 |
| - __asm__ __volatile__ ( \ |
95 |
| - "0: lr.d %0, %2\n" \ |
96 |
| - " bne %0, %z3, 1f\n" \ |
97 |
| - " sc.d %1, %z4, %2\n" \ |
98 |
| - " bnez %1, 0b\n" \ |
99 |
| - "1:\n" \ |
100 |
| - : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \ |
101 |
| - : "rJ" (__old), "rJ" (__new) \ |
102 |
| - : "memory"); \ |
103 |
| - break; \ |
104 |
| - default: \ |
105 |
| - BUILD_BUG(); \ |
106 |
| - } \ |
107 |
| - __ret; \ |
108 |
| -}) |
109 | 74 |
|
110 |
| -#define arch_cmpxchg_relaxed(ptr, o, n) \ |
111 |
| -({ \ |
112 |
| - __typeof__(*(ptr)) _o_ = (o); \ |
113 |
| - __typeof__(*(ptr)) _n_ = (n); \ |
114 |
| - (__typeof__(*(ptr))) __cmpxchg_relaxed((ptr), \ |
115 |
| - _o_, _n_, sizeof(*(ptr))); \ |
116 |
| -}) |
117 | 75 |
|
118 |
| -#define __cmpxchg_acquire(ptr, old, new, size) \ |
| 76 | +#define __arch_cmpxchg(lr_sfx, sc_sfx, prepend, append, r, p, co, o, n) \ |
119 | 77 | ({ \
|
120 |
| - __typeof__(ptr) __ptr = (ptr); \ |
121 |
| - __typeof__(*(ptr)) __old = (old); \ |
122 |
| - __typeof__(*(ptr)) __new = (new); \ |
123 |
| - __typeof__(*(ptr)) __ret; \ |
124 | 78 | register unsigned int __rc; \
|
125 |
| - switch (size) { \ |
126 |
| - case 4: \ |
127 |
| - __asm__ __volatile__ ( \ |
128 |
| - "0: lr.w %0, %2\n" \ |
129 |
| - " bne %0, %z3, 1f\n" \ |
130 |
| - " sc.w %1, %z4, %2\n" \ |
131 |
| - " bnez %1, 0b\n" \ |
132 |
| - RISCV_ACQUIRE_BARRIER \ |
133 |
| - "1:\n" \ |
134 |
| - : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \ |
135 |
| - : "rJ" ((long)__old), "rJ" (__new) \ |
136 |
| - : "memory"); \ |
137 |
| - break; \ |
138 |
| - case 8: \ |
139 |
| - __asm__ __volatile__ ( \ |
140 |
| - "0: lr.d %0, %2\n" \ |
141 |
| - " bne %0, %z3, 1f\n" \ |
142 |
| - " sc.d %1, %z4, %2\n" \ |
143 |
| - " bnez %1, 0b\n" \ |
144 |
| - RISCV_ACQUIRE_BARRIER \ |
145 |
| - "1:\n" \ |
146 |
| - : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \ |
147 |
| - : "rJ" (__old), "rJ" (__new) \ |
148 |
| - : "memory"); \ |
149 |
| - break; \ |
150 |
| - default: \ |
151 |
| - BUILD_BUG(); \ |
152 |
| - } \ |
153 |
| - __ret; \ |
154 |
| -}) |
155 |
| - |
156 |
| -#define arch_cmpxchg_acquire(ptr, o, n) \ |
157 |
| -({ \ |
158 |
| - __typeof__(*(ptr)) _o_ = (o); \ |
159 |
| - __typeof__(*(ptr)) _n_ = (n); \ |
160 |
| - (__typeof__(*(ptr))) __cmpxchg_acquire((ptr), \ |
161 |
| - _o_, _n_, sizeof(*(ptr))); \ |
| 79 | + \ |
| 80 | + __asm__ __volatile__ ( \ |
| 81 | + prepend \ |
| 82 | + "0: lr" lr_sfx " %0, %2\n" \ |
| 83 | + " bne %0, %z3, 1f\n" \ |
| 84 | + " sc" sc_sfx " %1, %z4, %2\n" \ |
| 85 | + " bnez %1, 0b\n" \ |
| 86 | + append \ |
| 87 | + "1:\n" \ |
| 88 | + : "=&r" (r), "=&r" (__rc), "+A" (*(p)) \ |
| 89 | + : "rJ" (co o), "rJ" (n) \ |
| 90 | + : "memory"); \ |
162 | 91 | })
|
163 | 92 |
|
164 |
| -#define __cmpxchg_release(ptr, old, new, size) \ |
| 93 | +#define _arch_cmpxchg(ptr, old, new, sc_sfx, prepend, append) \ |
165 | 94 | ({ \
|
166 | 95 | __typeof__(ptr) __ptr = (ptr); \
|
167 |
| - __typeof__(*(ptr)) __old = (old); \ |
168 |
| - __typeof__(*(ptr)) __new = (new); \ |
169 |
| - __typeof__(*(ptr)) __ret; \ |
170 |
| - register unsigned int __rc; \ |
171 |
| - switch (size) { \ |
| 96 | + __typeof__(*(__ptr)) __old = (old); \ |
| 97 | + __typeof__(*(__ptr)) __new = (new); \ |
| 98 | + __typeof__(*(__ptr)) __ret; \ |
| 99 | + \ |
| 100 | + switch (sizeof(*__ptr)) { \ |
172 | 101 | case 4: \
|
173 |
| - __asm__ __volatile__ ( \ |
174 |
| - RISCV_RELEASE_BARRIER \ |
175 |
| - "0: lr.w %0, %2\n" \ |
176 |
| - " bne %0, %z3, 1f\n" \ |
177 |
| - " sc.w %1, %z4, %2\n" \ |
178 |
| - " bnez %1, 0b\n" \ |
179 |
| - "1:\n" \ |
180 |
| - : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \ |
181 |
| - : "rJ" ((long)__old), "rJ" (__new) \ |
182 |
| - : "memory"); \ |
| 102 | + __arch_cmpxchg(".w", ".w" sc_sfx, prepend, append, \ |
| 103 | + __ret, __ptr, (long), __old, __new); \ |
183 | 104 | break; \
|
184 | 105 | case 8: \
|
185 |
| - __asm__ __volatile__ ( \ |
186 |
| - RISCV_RELEASE_BARRIER \ |
187 |
| - "0: lr.d %0, %2\n" \ |
188 |
| - " bne %0, %z3, 1f\n" \ |
189 |
| - " sc.d %1, %z4, %2\n" \ |
190 |
| - " bnez %1, 0b\n" \ |
191 |
| - "1:\n" \ |
192 |
| - : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \ |
193 |
| - : "rJ" (__old), "rJ" (__new) \ |
194 |
| - : "memory"); \ |
| 106 | + __arch_cmpxchg(".d", ".d" sc_sfx, prepend, append, \ |
| 107 | + __ret, __ptr, /**/, __old, __new); \ |
195 | 108 | break; \
|
196 | 109 | default: \
|
197 | 110 | BUILD_BUG(); \
|
198 | 111 | } \
|
199 |
| - __ret; \ |
| 112 | + (__typeof__(*(__ptr)))__ret; \ |
200 | 113 | })
|
201 | 114 |
|
202 |
| -#define arch_cmpxchg_release(ptr, o, n) \ |
203 |
| -({ \ |
204 |
| - __typeof__(*(ptr)) _o_ = (o); \ |
205 |
| - __typeof__(*(ptr)) _n_ = (n); \ |
206 |
| - (__typeof__(*(ptr))) __cmpxchg_release((ptr), \ |
207 |
| - _o_, _n_, sizeof(*(ptr))); \ |
208 |
| -}) |
| 115 | +#define arch_cmpxchg_relaxed(ptr, o, n) \ |
| 116 | + _arch_cmpxchg((ptr), (o), (n), "", "", "") |
209 | 117 |
|
210 |
| -#define __cmpxchg(ptr, old, new, size) \ |
211 |
| -({ \ |
212 |
| - __typeof__(ptr) __ptr = (ptr); \ |
213 |
| - __typeof__(*(ptr)) __old = (old); \ |
214 |
| - __typeof__(*(ptr)) __new = (new); \ |
215 |
| - __typeof__(*(ptr)) __ret; \ |
216 |
| - register unsigned int __rc; \ |
217 |
| - switch (size) { \ |
218 |
| - case 4: \ |
219 |
| - __asm__ __volatile__ ( \ |
220 |
| - "0: lr.w %0, %2\n" \ |
221 |
| - " bne %0, %z3, 1f\n" \ |
222 |
| - " sc.w.rl %1, %z4, %2\n" \ |
223 |
| - " bnez %1, 0b\n" \ |
224 |
| - " fence rw, rw\n" \ |
225 |
| - "1:\n" \ |
226 |
| - : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \ |
227 |
| - : "rJ" ((long)__old), "rJ" (__new) \ |
228 |
| - : "memory"); \ |
229 |
| - break; \ |
230 |
| - case 8: \ |
231 |
| - __asm__ __volatile__ ( \ |
232 |
| - "0: lr.d %0, %2\n" \ |
233 |
| - " bne %0, %z3, 1f\n" \ |
234 |
| - " sc.d.rl %1, %z4, %2\n" \ |
235 |
| - " bnez %1, 0b\n" \ |
236 |
| - " fence rw, rw\n" \ |
237 |
| - "1:\n" \ |
238 |
| - : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \ |
239 |
| - : "rJ" (__old), "rJ" (__new) \ |
240 |
| - : "memory"); \ |
241 |
| - break; \ |
242 |
| - default: \ |
243 |
| - BUILD_BUG(); \ |
244 |
| - } \ |
245 |
| - __ret; \ |
246 |
| -}) |
| 118 | +#define arch_cmpxchg_acquire(ptr, o, n) \ |
| 119 | + _arch_cmpxchg((ptr), (o), (n), "", "", RISCV_ACQUIRE_BARRIER) |
| 120 | + |
| 121 | +#define arch_cmpxchg_release(ptr, o, n) \ |
| 122 | + _arch_cmpxchg((ptr), (o), (n), "", RISCV_RELEASE_BARRIER, "") |
247 | 123 |
|
248 | 124 | #define arch_cmpxchg(ptr, o, n) \
|
249 |
| -({ \ |
250 |
| - __typeof__(*(ptr)) _o_ = (o); \ |
251 |
| - __typeof__(*(ptr)) _n_ = (n); \ |
252 |
| - (__typeof__(*(ptr))) __cmpxchg((ptr), \ |
253 |
| - _o_, _n_, sizeof(*(ptr))); \ |
254 |
| -}) |
| 125 | + _arch_cmpxchg((ptr), (o), (n), ".rl", "", " fence rw, rw\n") |
255 | 126 |
|
256 | 127 | #define arch_cmpxchg_local(ptr, o, n) \
|
257 |
| - (__cmpxchg_relaxed((ptr), (o), (n), sizeof(*(ptr)))) |
| 128 | + arch_cmpxchg_relaxed((ptr), (o), (n)) |
258 | 129 |
|
259 | 130 | #define arch_cmpxchg64(ptr, o, n) \
|
260 | 131 | ({ \
|
|
0 commit comments