]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/m68k/m680x0/m68020/atomic-machine.h
Update copyright dates with scripts/update-copyrights
[thirdparty/glibc.git] / sysdeps / m68k / m680x0 / m68020 / atomic-machine.h
CommitLineData
dff8da6b 1/* Copyright (C) 2003-2024 Free Software Foundation, Inc.
d9a3227e 2 This file is part of the GNU C Library.
d9a3227e
AS
3
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
ab84e3ff 15 License along with the GNU C Library. If not, see
5a82c748 16 <https://www.gnu.org/licenses/>. */
d9a3227e 17
1ea339b6
TR
18#define __HAVE_64B_ATOMICS 1
19#define USE_ATOMIC_COMPILER_BUILTINS 0
20
12d2dd70
SL
21/* XXX Is this actually correct? */
22#define ATOMIC_EXCHANGE_USES_CAS 1
23
d9a3227e
AS
24#define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \
25 ({ __typeof (*(mem)) __ret; \
26 __asm __volatile ("cas%.b %0,%2,%1" \
945ec979
AS
27 : "=d" (__ret), "+m" (*(mem)) \
28 : "d" (newval), "0" (oldval)); \
d9a3227e
AS
29 __ret; })
30
31#define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \
32 ({ __typeof (*(mem)) __ret; \
33 __asm __volatile ("cas%.w %0,%2,%1" \
945ec979
AS
34 : "=d" (__ret), "+m" (*(mem)) \
35 : "d" (newval), "0" (oldval)); \
d9a3227e
AS
36 __ret; })
37
38#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \
39 ({ __typeof (*(mem)) __ret; \
40 __asm __volatile ("cas%.l %0,%2,%1" \
945ec979
AS
41 : "=d" (__ret), "+m" (*(mem)) \
42 : "d" (newval), "0" (oldval)); \
d9a3227e
AS
43 __ret; })
44
45# define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
46 ({ __typeof (*(mem)) __ret; \
47 __typeof (mem) __memp = (mem); \
48 __asm __volatile ("cas2%.l %0:%R0,%1:%R1,(%2):(%3)" \
49 : "=d" (__ret) \
64ae9fe4 50 : "d" ((__typeof (*(mem))) (newval)), "r" (__memp), \
d9a3227e
AS
51 "r" ((char *) __memp + 4), "0" (oldval) \
52 : "memory"); \
53 __ret; })
54
25e5f254 55#define atomic_exchange_acq(mem, newvalue) \
d9a3227e
AS
56 ({ __typeof (*(mem)) __result = *(mem); \
57 if (sizeof (*(mem)) == 1) \
58 __asm __volatile ("1: cas%.b %0,%2,%1;" \
59 " jbne 1b" \
945ec979
AS
60 : "=d" (__result), "+m" (*(mem)) \
61 : "d" (newvalue), "0" (__result)); \
d9a3227e
AS
62 else if (sizeof (*(mem)) == 2) \
63 __asm __volatile ("1: cas%.w %0,%2,%1;" \
64 " jbne 1b" \
945ec979
AS
65 : "=d" (__result), "+m" (*(mem)) \
66 : "d" (newvalue), "0" (__result)); \
d9a3227e
AS
67 else if (sizeof (*(mem)) == 4) \
68 __asm __volatile ("1: cas%.l %0,%2,%1;" \
69 " jbne 1b" \
945ec979
AS
70 : "=d" (__result), "+m" (*(mem)) \
71 : "d" (newvalue), "0" (__result)); \
d9a3227e
AS
72 else \
73 { \
74 __typeof (mem) __memp = (mem); \
75 __asm __volatile ("1: cas2%.l %0:%R0,%1:%R1,(%2):(%3);" \
76 " jbne 1b" \
77 : "=d" (__result) \
64ae9fe4
AS
78 : "d" ((__typeof (*(mem))) (newvalue)), \
79 "r" (__memp), "r" ((char *) __memp + 4), \
80 "0" (__result) \
d9a3227e
AS
81 : "memory"); \
82 } \
83 __result; })
84
85#define atomic_exchange_and_add(mem, value) \
86 ({ __typeof (*(mem)) __result = *(mem); \
87 __typeof (*(mem)) __temp; \
88 if (sizeof (*(mem)) == 1) \
89 __asm __volatile ("1: move%.b %0,%2;" \
90 " add%.b %3,%2;" \
91 " cas%.b %0,%2,%1;" \
92 " jbne 1b" \
945ec979 93 : "=d" (__result), "+m" (*(mem)), \
d9a3227e 94 "=&d" (__temp) \
945ec979 95 : "d" (value), "0" (__result)); \
d9a3227e
AS
96 else if (sizeof (*(mem)) == 2) \
97 __asm __volatile ("1: move%.w %0,%2;" \
98 " add%.w %3,%2;" \
99 " cas%.w %0,%2,%1;" \
100 " jbne 1b" \
945ec979 101 : "=d" (__result), "+m" (*(mem)), \
d9a3227e 102 "=&d" (__temp) \
945ec979 103 : "d" (value), "0" (__result)); \
d9a3227e
AS
104 else if (sizeof (*(mem)) == 4) \
105 __asm __volatile ("1: move%.l %0,%2;" \
106 " add%.l %3,%2;" \
107 " cas%.l %0,%2,%1;" \
108 " jbne 1b" \
945ec979 109 : "=d" (__result), "+m" (*(mem)), \
d9a3227e 110 "=&d" (__temp) \
945ec979 111 : "d" (value), "0" (__result)); \
d9a3227e
AS
112 else \
113 { \
114 __typeof (mem) __memp = (mem); \
115 __asm __volatile ("1: move%.l %0,%1;" \
116 " move%.l %R0,%R1;" \
a3905fd9
AS
117 " add%.l %R2,%R1;" \
118 " addx%.l %2,%1;" \
d9a3227e
AS
119 " cas2%.l %0:%R0,%1:%R1,(%3):(%4);" \
120 " jbne 1b" \
121 : "=d" (__result), "=&d" (__temp) \
64ae9fe4 122 : "d" ((__typeof (*(mem))) (value)), "r" (__memp), \
d9a3227e
AS
123 "r" ((char *) __memp + 4), "0" (__result) \
124 : "memory"); \
125 } \
126 __result; })
127
128#define atomic_add(mem, value) \
129 (void) ({ if (sizeof (*(mem)) == 1) \
130 __asm __volatile ("add%.b %1,%0" \
945ec979
AS
131 : "+m" (*(mem)) \
132 : "id" (value)); \
d9a3227e
AS
133 else if (sizeof (*(mem)) == 2) \
134 __asm __volatile ("add%.w %1,%0" \
945ec979
AS
135 : "+m" (*(mem)) \
136 : "id" (value)); \
d9a3227e
AS
137 else if (sizeof (*(mem)) == 4) \
138 __asm __volatile ("add%.l %1,%0" \
945ec979
AS
139 : "+m" (*(mem)) \
140 : "id" (value)); \
d9a3227e
AS
141 else \
142 { \
143 __typeof (mem) __memp = (mem); \
144 __typeof (*(mem)) __oldval = *__memp; \
145 __typeof (*(mem)) __temp; \
146 __asm __volatile ("1: move%.l %0,%1;" \
147 " move%.l %R0,%R1;" \
a3905fd9
AS
148 " add%.l %R2,%R1;" \
149 " addx%.l %2,%1;" \
d9a3227e
AS
150 " cas2%.l %0:%R0,%1:%R1,(%3):(%4);" \
151 " jbne 1b" \
152 : "=d" (__oldval), "=&d" (__temp) \
64ae9fe4
AS
153 : "d" ((__typeof (*(mem))) (value)), \
154 "r" (__memp), "r" ((char *) __memp + 4), \
155 "0" (__oldval) \
d9a3227e
AS
156 : "memory"); \
157 } \
158 })
159
28d6ca4b
AS
160#define atomic_increment_and_test(mem) \
161 ({ char __result; \
162 if (sizeof (*(mem)) == 1) \
163 __asm __volatile ("addq%.b %#1,%1; seq %0" \
945ec979 164 : "=dm" (__result), "+m" (*(mem))); \
28d6ca4b
AS
165 else if (sizeof (*(mem)) == 2) \
166 __asm __volatile ("addq%.w %#1,%1; seq %0" \
945ec979 167 : "=dm" (__result), "+m" (*(mem))); \
28d6ca4b
AS
168 else if (sizeof (*(mem)) == 4) \
169 __asm __volatile ("addq%.l %#1,%1; seq %0" \
945ec979 170 : "=dm" (__result), "+m" (*(mem))); \
28d6ca4b
AS
171 else \
172 { \
173 __typeof (mem) __memp = (mem); \
174 __typeof (*(mem)) __oldval = *__memp; \
175 __typeof (*(mem)) __temp; \
176 __asm __volatile ("1: move%.l %1,%2;" \
177 " move%.l %R1,%R2;" \
a3905fd9
AS
178 " addq%.l %#1,%R2;" \
179 " addx%.l %5,%2;" \
28d6ca4b
AS
180 " seq %0;" \
181 " cas2%.l %1:%R1,%2:%R2,(%3):(%4);" \
182 " jbne 1b" \
183 : "=&dm" (__result), "=d" (__oldval), \
184 "=&d" (__temp) \
185 : "r" (__memp), "r" ((char *) __memp + 4), \
186 "d" (0), "1" (__oldval) \
187 : "memory"); \
188 } \
189 __result; })
190
d9a3227e
AS
191#define atomic_decrement_and_test(mem) \
192 ({ char __result; \
193 if (sizeof (*(mem)) == 1) \
28d6ca4b 194 __asm __volatile ("subq%.b %#1,%1; seq %0" \
945ec979 195 : "=dm" (__result), "+m" (*(mem))); \
d9a3227e 196 else if (sizeof (*(mem)) == 2) \
28d6ca4b 197 __asm __volatile ("subq%.w %#1,%1; seq %0" \
945ec979 198 : "=dm" (__result), "+m" (*(mem))); \
d9a3227e 199 else if (sizeof (*(mem)) == 4) \
28d6ca4b 200 __asm __volatile ("subq%.l %#1,%1; seq %0" \
945ec979 201 : "=dm" (__result), "+m" (*(mem))); \
d9a3227e
AS
202 else \
203 { \
97b729d3 204 __typeof (mem) __memp = (mem); \
d9a3227e
AS
205 __typeof (*(mem)) __oldval = *__memp; \
206 __typeof (*(mem)) __temp; \
207 __asm __volatile ("1: move%.l %1,%2;" \
208 " move%.l %R1,%R2;" \
a3905fd9
AS
209 " subq%.l %#1,%R2;" \
210 " subx%.l %5,%2;" \
28d6ca4b 211 " seq %0;" \
d9a3227e
AS
212 " cas2%.l %1:%R1,%2:%R2,(%3):(%4);" \
213 " jbne 1b" \
214 : "=&dm" (__result), "=d" (__oldval), \
215 "=&d" (__temp) \
216 : "r" (__memp), "r" ((char *) __memp + 4), \
217 "d" (0), "1" (__oldval) \
218 : "memory"); \
219 } \
220 __result; })
221
222#define atomic_bit_set(mem, bit) \
223 __asm __volatile ("bfset %0{%1,#1}" \
945ec979
AS
224 : "+m" (*(mem)) \
225 : "di" (sizeof (*(mem)) * 8 - (bit) - 1))
d9a3227e
AS
226
227#define atomic_bit_test_set(mem, bit) \
228 ({ char __result; \
229 __asm __volatile ("bfset %1{%2,#1}; sne %0" \
945ec979
AS
230 : "=dm" (__result), "+m" (*(mem)) \
231 : "di" (sizeof (*(mem)) * 8 - (bit) - 1)); \
d9a3227e 232 __result; })