]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/powerpc/atomic-machine.h
Remove "Contributed by" lines
[thirdparty/glibc.git] / sysdeps / powerpc / atomic-machine.h
CommitLineData
94c24227 1/* Atomic operations. PowerPC Common version.
2b778ceb 2 Copyright (C) 2003-2021 Free Software Foundation, Inc.
f3c13160 3 This file is part of the GNU C Library.
f3c13160
RM
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
59ba27a6 16 License along with the GNU C Library; if not, see
5a82c748 17 <https://www.gnu.org/licenses/>. */
f3c13160 18
94c24227 19/*
de071d19 20 * Never include sysdeps/powerpc/atomic-machine.h directly.
949ec764 21 * Alway use include/atomic.h which will include either
de071d19 22 * sysdeps/powerpc/powerpc32/atomic-machine.h
949ec764 23 * or
de071d19 24 * sysdeps/powerpc/powerpc64/atomic-machine.h
94c24227
UD
25 * as appropriate and which in turn include this file.
26 */
f3c13160 27
94c24227 28#include <stdint.h>
f3c13160
RM
29
30typedef int32_t atomic32_t;
31typedef uint32_t uatomic32_t;
32typedef int_fast32_t atomic_fast32_t;
33typedef uint_fast32_t uatomic_fast32_t;
34
35typedef int64_t atomic64_t;
36typedef uint64_t uatomic64_t;
37typedef int_fast64_t atomic_fast64_t;
38typedef uint_fast64_t uatomic_fast64_t;
39
40typedef intptr_t atomicptr_t;
41typedef uintptr_t uatomicptr_t;
42typedef intmax_t atomic_max_t;
43typedef uintmax_t uatomic_max_t;
44
949ec764
UD
45/*
46 * Powerpc does not have byte and halfword forms of load and reserve and
94c24227
UD
47 * store conditional. So for powerpc we stub out the 8- and 16-bit forms.
48 */
5a3ab2fc 49#define __arch_compare_and_exchange_bool_8_acq(mem, newval, oldval) \
f3c13160
RM
50 (abort (), 0)
51
5a3ab2fc 52#define __arch_compare_and_exchange_bool_16_acq(mem, newval, oldval) \
f3c13160 53 (abort (), 0)
ecb2b2fb 54
d5c4cce9
FW
55#define __ARCH_ACQ_INSTR "isync"
56#ifndef __ARCH_REL_INSTR
57# define __ARCH_REL_INSTR "sync"
f3c13160
RM
58#endif
59
fa6e3bc3
UD
60#ifndef MUTEX_HINT_ACQ
61# define MUTEX_HINT_ACQ
62#endif
63#ifndef MUTEX_HINT_REL
64# define MUTEX_HINT_REL
65#endif
66
94c24227 67#define atomic_full_barrier() __asm ("sync" ::: "memory")
94c24227 68
7158eae4
UD
69#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \
70 ({ \
71 __typeof (*(mem)) __tmp; \
72 __typeof (mem) __memp = (mem); \
73 __asm __volatile ( \
fa6e3bc3 74 "1: lwarx %0,0,%1" MUTEX_HINT_ACQ "\n" \
7158eae4
UD
75 " cmpw %0,%2\n" \
76 " bne 2f\n" \
77 " stwcx. %3,0,%1\n" \
78 " bne- 1b\n" \
79 "2: " __ARCH_ACQ_INSTR \
80 : "=&r" (__tmp) \
81 : "b" (__memp), "r" (oldval), "r" (newval) \
82 : "cr0", "memory"); \
83 __tmp; \
84 })
f3c13160 85
7158eae4 86#define __arch_compare_and_exchange_val_32_rel(mem, newval, oldval) \
6087c485
UD
87 ({ \
88 __typeof (*(mem)) __tmp; \
89 __typeof (mem) __memp = (mem); \
90 __asm __volatile (__ARCH_REL_INSTR "\n" \
fa6e3bc3 91 "1: lwarx %0,0,%1" MUTEX_HINT_REL "\n" \
6087c485
UD
92 " cmpw %0,%2\n" \
93 " bne 2f\n" \
94 " stwcx. %3,0,%1\n" \
95 " bne- 1b\n" \
7158eae4 96 "2: " \
6087c485
UD
97 : "=&r" (__tmp) \
98 : "b" (__memp), "r" (oldval), "r" (newval) \
99 : "cr0", "memory"); \
100 __tmp; \
101 })
102
7158eae4
UD
103#define __arch_atomic_exchange_32_acq(mem, value) \
104 ({ \
105 __typeof (*mem) __val; \
106 __asm __volatile ( \
fa6e3bc3 107 "1: lwarx %0,0,%2" MUTEX_HINT_ACQ "\n" \
7158eae4
UD
108 " stwcx. %3,0,%2\n" \
109 " bne- 1b\n" \
110 " " __ARCH_ACQ_INSTR \
111 : "=&r" (__val), "=m" (*mem) \
ecb2b2fb 112 : "b" (mem), "r" (value), "m" (*mem) \
7158eae4
UD
113 : "cr0", "memory"); \
114 __val; \
115 })
116
117#define __arch_atomic_exchange_32_rel(mem, value) \
3e195d93
RM
118 ({ \
119 __typeof (*mem) __val; \
120 __asm __volatile (__ARCH_REL_INSTR "\n" \
fa6e3bc3 121 "1: lwarx %0,0,%2" MUTEX_HINT_REL "\n" \
859e708f
RM
122 " stwcx. %3,0,%2\n" \
123 " bne- 1b" \
3e195d93 124 : "=&r" (__val), "=m" (*mem) \
ecb2b2fb 125 : "b" (mem), "r" (value), "m" (*mem) \
7158eae4 126 : "cr0", "memory"); \
3e195d93
RM
127 __val; \
128 })
f79466a8 129
6087c485 130#define __arch_atomic_exchange_and_add_32(mem, value) \
3e195d93
RM
131 ({ \
132 __typeof (*mem) __val, __tmp; \
133 __asm __volatile ("1: lwarx %0,0,%3\n" \
859e708f
RM
134 " add %1,%0,%4\n" \
135 " stwcx. %1,0,%3\n" \
136 " bne- 1b" \
3e195d93 137 : "=&b" (__val), "=&r" (__tmp), "=m" (*mem) \
ecb2b2fb 138 : "b" (mem), "r" (value), "m" (*mem) \
7158eae4 139 : "cr0", "memory"); \
3e195d93
RM
140 __val; \
141 })
448163ba 142
704f7947
AZ
143#define __arch_atomic_exchange_and_add_32_acq(mem, value) \
144 ({ \
145 __typeof (*mem) __val, __tmp; \
146 __asm __volatile ("1: lwarx %0,0,%3" MUTEX_HINT_ACQ "\n" \
147 " add %1,%0,%4\n" \
148 " stwcx. %1,0,%3\n" \
149 " bne- 1b\n" \
150 __ARCH_ACQ_INSTR \
151 : "=&b" (__val), "=&r" (__tmp), "=m" (*mem) \
152 : "b" (mem), "r" (value), "m" (*mem) \
153 : "cr0", "memory"); \
154 __val; \
155 })
156
157#define __arch_atomic_exchange_and_add_32_rel(mem, value) \
158 ({ \
159 __typeof (*mem) __val, __tmp; \
160 __asm __volatile (__ARCH_REL_INSTR "\n" \
161 "1: lwarx %0,0,%3" MUTEX_HINT_REL "\n" \
162 " add %1,%0,%4\n" \
163 " stwcx. %1,0,%3\n" \
164 " bne- 1b" \
165 : "=&b" (__val), "=&r" (__tmp), "=m" (*mem) \
166 : "b" (mem), "r" (value), "m" (*mem) \
167 : "cr0", "memory"); \
168 __val; \
169 })
170
7ba0e52c
UD
171#define __arch_atomic_increment_val_32(mem) \
172 ({ \
173 __typeof (*(mem)) __val; \
174 __asm __volatile ("1: lwarx %0,0,%2\n" \
175 " addi %0,%0,1\n" \
176 " stwcx. %0,0,%2\n" \
177 " bne- 1b" \
178 : "=&b" (__val), "=m" (*mem) \
179 : "b" (mem), "m" (*mem) \
180 : "cr0", "memory"); \
181 __val; \
182 })
183
184#define __arch_atomic_decrement_val_32(mem) \
185 ({ \
186 __typeof (*(mem)) __val; \
187 __asm __volatile ("1: lwarx %0,0,%2\n" \
188 " subi %0,%0,1\n" \
189 " stwcx. %0,0,%2\n" \
190 " bne- 1b" \
191 : "=&b" (__val), "=m" (*mem) \
192 : "b" (mem), "m" (*mem) \
193 : "cr0", "memory"); \
194 __val; \
195 })
196
6087c485 197#define __arch_atomic_decrement_if_positive_32(mem) \
3171ae99
UD
198 ({ int __val, __tmp; \
199 __asm __volatile ("1: lwarx %0,0,%3\n" \
200 " cmpwi 0,%0,0\n" \
201 " addi %1,%0,-1\n" \
202 " ble 2f\n" \
203 " stwcx. %1,0,%3\n" \
204 " bne- 1b\n" \
205 "2: " __ARCH_ACQ_INSTR \
206 : "=&b" (__val), "=&r" (__tmp), "=m" (*mem) \
ecb2b2fb 207 : "b" (mem), "m" (*mem) \
7158eae4 208 : "cr0", "memory"); \
3171ae99
UD
209 __val; \
210 })
211
6087c485
UD
212#define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \
213 ({ \
214 __typeof (*(mem)) __result; \
215 if (sizeof (*mem) == 4) \
216 __result = __arch_compare_and_exchange_val_32_acq(mem, newval, oldval); \
217 else if (sizeof (*mem) == 8) \
218 __result = __arch_compare_and_exchange_val_64_acq(mem, newval, oldval); \
219 else \
220 abort (); \
221 __result; \
222 })
ecb2b2fb 223
7158eae4
UD
224#define atomic_compare_and_exchange_val_rel(mem, newval, oldval) \
225 ({ \
226 __typeof (*(mem)) __result; \
227 if (sizeof (*mem) == 4) \
228 __result = __arch_compare_and_exchange_val_32_rel(mem, newval, oldval); \
229 else if (sizeof (*mem) == 8) \
230 __result = __arch_compare_and_exchange_val_64_rel(mem, newval, oldval); \
231 else \
232 abort (); \
233 __result; \
234 })
6087c485 235
949ec764 236#define atomic_exchange_acq(mem, value) \
3e195d93
RM
237 ({ \
238 __typeof (*(mem)) __result; \
239 if (sizeof (*mem) == 4) \
7158eae4
UD
240 __result = __arch_atomic_exchange_32_acq (mem, value); \
241 else if (sizeof (*mem) == 8) \
242 __result = __arch_atomic_exchange_64_acq (mem, value); \
243 else \
244 abort (); \
245 __result; \
246 })
247
248#define atomic_exchange_rel(mem, value) \
249 ({ \
250 __typeof (*(mem)) __result; \
251 if (sizeof (*mem) == 4) \
252 __result = __arch_atomic_exchange_32_rel (mem, value); \
3e195d93 253 else if (sizeof (*mem) == 8) \
7158eae4 254 __result = __arch_atomic_exchange_64_rel (mem, value); \
3e195d93
RM
255 else \
256 abort (); \
257 __result; \
258 })
f79466a8 259
6087c485 260#define atomic_exchange_and_add(mem, value) \
3e195d93
RM
261 ({ \
262 __typeof (*(mem)) __result; \
263 if (sizeof (*mem) == 4) \
6087c485 264 __result = __arch_atomic_exchange_and_add_32 (mem, value); \
3e195d93 265 else if (sizeof (*mem) == 8) \
6087c485 266 __result = __arch_atomic_exchange_and_add_64 (mem, value); \
3e195d93 267 else \
f79466a8 268 abort (); \
3e195d93 269 __result; \
f79466a8 270 })
704f7947
AZ
271#define atomic_exchange_and_add_acq(mem, value) \
272 ({ \
273 __typeof (*(mem)) __result; \
274 if (sizeof (*mem) == 4) \
275 __result = __arch_atomic_exchange_and_add_32_acq (mem, value); \
276 else if (sizeof (*mem) == 8) \
277 __result = __arch_atomic_exchange_and_add_64_acq (mem, value); \
278 else \
279 abort (); \
280 __result; \
281 })
282#define atomic_exchange_and_add_rel(mem, value) \
283 ({ \
284 __typeof (*(mem)) __result; \
285 if (sizeof (*mem) == 4) \
286 __result = __arch_atomic_exchange_and_add_32_rel (mem, value); \
287 else if (sizeof (*mem) == 8) \
288 __result = __arch_atomic_exchange_and_add_64_rel (mem, value); \
289 else \
290 abort (); \
291 __result; \
292 })
f79466a8 293
7ba0e52c
UD
294#define atomic_increment_val(mem) \
295 ({ \
296 __typeof (*(mem)) __result; \
297 if (sizeof (*(mem)) == 4) \
298 __result = __arch_atomic_increment_val_32 (mem); \
299 else if (sizeof (*(mem)) == 8) \
300 __result = __arch_atomic_increment_val_64 (mem); \
301 else \
302 abort (); \
303 __result; \
304 })
305
306#define atomic_increment(mem) ({ atomic_increment_val (mem); (void) 0; })
307
308#define atomic_decrement_val(mem) \
309 ({ \
310 __typeof (*(mem)) __result; \
311 if (sizeof (*(mem)) == 4) \
312 __result = __arch_atomic_decrement_val_32 (mem); \
313 else if (sizeof (*(mem)) == 8) \
314 __result = __arch_atomic_decrement_val_64 (mem); \
315 else \
316 abort (); \
317 __result; \
318 })
319
320#define atomic_decrement(mem) ({ atomic_decrement_val (mem); (void) 0; })
321
f79466a8
UD
322
323/* Decrement *MEM if it is > 0, and return the old value. */
6087c485 324#define atomic_decrement_if_positive(mem) \
448163ba 325 ({ __typeof (*(mem)) __result; \
3171ae99 326 if (sizeof (*mem) == 4) \
448163ba 327 __result = __arch_atomic_decrement_if_positive_32 (mem); \
3171ae99 328 else if (sizeof (*mem) == 8) \
448163ba
RM
329 __result = __arch_atomic_decrement_if_positive_64 (mem); \
330 else \
f79466a8 331 abort (); \
3171ae99 332 __result; \
f79466a8 333 })