]> git.ipfire.org Git - thirdparty/glibc.git/blob - ports/sysdeps/m68k/m680x0/m68020/bits/atomic.h
Update copyright notices with scripts/update-copyrights
[thirdparty/glibc.git] / ports / sysdeps / m68k / m680x0 / m68020 / bits / atomic.h
1 /* Copyright (C) 2003-2014 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Andreas Schwab <schwab@suse.de>, 2003.
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
16 License along with the GNU C Library. If not, see
17 <http://www.gnu.org/licenses/>. */
18
19 #include <stdint.h>
20
21
22 typedef int8_t atomic8_t;
23 typedef uint8_t uatomic8_t;
24 typedef int_fast8_t atomic_fast8_t;
25 typedef uint_fast8_t uatomic_fast8_t;
26
27 typedef int16_t atomic16_t;
28 typedef uint16_t uatomic16_t;
29 typedef int_fast16_t atomic_fast16_t;
30 typedef uint_fast16_t uatomic_fast16_t;
31
32 typedef int32_t atomic32_t;
33 typedef uint32_t uatomic32_t;
34 typedef int_fast32_t atomic_fast32_t;
35 typedef uint_fast32_t uatomic_fast32_t;
36
37 typedef int64_t atomic64_t;
38 typedef uint64_t uatomic64_t;
39 typedef int_fast64_t atomic_fast64_t;
40 typedef uint_fast64_t uatomic_fast64_t;
41
42 typedef intptr_t atomicptr_t;
43 typedef uintptr_t uatomicptr_t;
44 typedef intmax_t atomic_max_t;
45 typedef uintmax_t uatomic_max_t;
46
47 #define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \
48 ({ __typeof (*(mem)) __ret; \
49 __asm __volatile ("cas%.b %0,%2,%1" \
50 : "=d" (__ret), "+m" (*(mem)) \
51 : "d" (newval), "0" (oldval)); \
52 __ret; })
53
54 #define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \
55 ({ __typeof (*(mem)) __ret; \
56 __asm __volatile ("cas%.w %0,%2,%1" \
57 : "=d" (__ret), "+m" (*(mem)) \
58 : "d" (newval), "0" (oldval)); \
59 __ret; })
60
61 #define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \
62 ({ __typeof (*(mem)) __ret; \
63 __asm __volatile ("cas%.l %0,%2,%1" \
64 : "=d" (__ret), "+m" (*(mem)) \
65 : "d" (newval), "0" (oldval)); \
66 __ret; })
67
68 # define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
69 ({ __typeof (*(mem)) __ret; \
70 __typeof (mem) __memp = (mem); \
71 __asm __volatile ("cas2%.l %0:%R0,%1:%R1,(%2):(%3)" \
72 : "=d" (__ret) \
73 : "d" (newval), "r" (__memp), \
74 "r" ((char *) __memp + 4), "0" (oldval) \
75 : "memory"); \
76 __ret; })
77
78 #define atomic_exchange_acq(mem, newvalue) \
79 ({ __typeof (*(mem)) __result = *(mem); \
80 if (sizeof (*(mem)) == 1) \
81 __asm __volatile ("1: cas%.b %0,%2,%1;" \
82 " jbne 1b" \
83 : "=d" (__result), "+m" (*(mem)) \
84 : "d" (newvalue), "0" (__result)); \
85 else if (sizeof (*(mem)) == 2) \
86 __asm __volatile ("1: cas%.w %0,%2,%1;" \
87 " jbne 1b" \
88 : "=d" (__result), "+m" (*(mem)) \
89 : "d" (newvalue), "0" (__result)); \
90 else if (sizeof (*(mem)) == 4) \
91 __asm __volatile ("1: cas%.l %0,%2,%1;" \
92 " jbne 1b" \
93 : "=d" (__result), "+m" (*(mem)) \
94 : "d" (newvalue), "0" (__result)); \
95 else \
96 { \
97 __typeof (mem) __memp = (mem); \
98 __asm __volatile ("1: cas2%.l %0:%R0,%1:%R1,(%2):(%3);" \
99 " jbne 1b" \
100 : "=d" (__result) \
101 : "d" (newvalue), "r" (__memp), \
102 "r" ((char *) __memp + 4), "0" (__result) \
103 : "memory"); \
104 } \
105 __result; })
106
107 #define atomic_exchange_and_add(mem, value) \
108 ({ __typeof (*(mem)) __result = *(mem); \
109 __typeof (*(mem)) __temp; \
110 if (sizeof (*(mem)) == 1) \
111 __asm __volatile ("1: move%.b %0,%2;" \
112 " add%.b %3,%2;" \
113 " cas%.b %0,%2,%1;" \
114 " jbne 1b" \
115 : "=d" (__result), "+m" (*(mem)), \
116 "=&d" (__temp) \
117 : "d" (value), "0" (__result)); \
118 else if (sizeof (*(mem)) == 2) \
119 __asm __volatile ("1: move%.w %0,%2;" \
120 " add%.w %3,%2;" \
121 " cas%.w %0,%2,%1;" \
122 " jbne 1b" \
123 : "=d" (__result), "+m" (*(mem)), \
124 "=&d" (__temp) \
125 : "d" (value), "0" (__result)); \
126 else if (sizeof (*(mem)) == 4) \
127 __asm __volatile ("1: move%.l %0,%2;" \
128 " add%.l %3,%2;" \
129 " cas%.l %0,%2,%1;" \
130 " jbne 1b" \
131 : "=d" (__result), "+m" (*(mem)), \
132 "=&d" (__temp) \
133 : "d" (value), "0" (__result)); \
134 else \
135 { \
136 __typeof (mem) __memp = (mem); \
137 __asm __volatile ("1: move%.l %0,%1;" \
138 " move%.l %R0,%R1;" \
139 " add%.l %2,%1;" \
140 " addx%.l %R2,%R1;" \
141 " cas2%.l %0:%R0,%1:%R1,(%3):(%4);" \
142 " jbne 1b" \
143 : "=d" (__result), "=&d" (__temp) \
144 : "d" (value), "r" (__memp), \
145 "r" ((char *) __memp + 4), "0" (__result) \
146 : "memory"); \
147 } \
148 __result; })
149
150 #define atomic_add(mem, value) \
151 (void) ({ if (sizeof (*(mem)) == 1) \
152 __asm __volatile ("add%.b %1,%0" \
153 : "+m" (*(mem)) \
154 : "id" (value)); \
155 else if (sizeof (*(mem)) == 2) \
156 __asm __volatile ("add%.w %1,%0" \
157 : "+m" (*(mem)) \
158 : "id" (value)); \
159 else if (sizeof (*(mem)) == 4) \
160 __asm __volatile ("add%.l %1,%0" \
161 : "+m" (*(mem)) \
162 : "id" (value)); \
163 else \
164 { \
165 __typeof (mem) __memp = (mem); \
166 __typeof (*(mem)) __oldval = *__memp; \
167 __typeof (*(mem)) __temp; \
168 __asm __volatile ("1: move%.l %0,%1;" \
169 " move%.l %R0,%R1;" \
170 " add%.l %2,%1;" \
171 " addx%.l %R2,%R1;" \
172 " cas2%.l %0:%R0,%1:%R1,(%3):(%4);" \
173 " jbne 1b" \
174 : "=d" (__oldval), "=&d" (__temp) \
175 : "d" (value), "r" (__memp), \
176 "r" ((char *) __memp + 4), "0" (__oldval) \
177 : "memory"); \
178 } \
179 })
180
181 #define atomic_increment_and_test(mem) \
182 ({ char __result; \
183 if (sizeof (*(mem)) == 1) \
184 __asm __volatile ("addq%.b %#1,%1; seq %0" \
185 : "=dm" (__result), "+m" (*(mem))); \
186 else if (sizeof (*(mem)) == 2) \
187 __asm __volatile ("addq%.w %#1,%1; seq %0" \
188 : "=dm" (__result), "+m" (*(mem))); \
189 else if (sizeof (*(mem)) == 4) \
190 __asm __volatile ("addq%.l %#1,%1; seq %0" \
191 : "=dm" (__result), "+m" (*(mem))); \
192 else \
193 { \
194 __typeof (mem) __memp = (mem); \
195 __typeof (*(mem)) __oldval = *__memp; \
196 __typeof (*(mem)) __temp; \
197 __asm __volatile ("1: move%.l %1,%2;" \
198 " move%.l %R1,%R2;" \
199 " addq%.l %#1,%2;" \
200 " addx%.l %5,%R2;" \
201 " seq %0;" \
202 " cas2%.l %1:%R1,%2:%R2,(%3):(%4);" \
203 " jbne 1b" \
204 : "=&dm" (__result), "=d" (__oldval), \
205 "=&d" (__temp) \
206 : "r" (__memp), "r" ((char *) __memp + 4), \
207 "d" (0), "1" (__oldval) \
208 : "memory"); \
209 } \
210 __result; })
211
212 #define atomic_decrement_and_test(mem) \
213 ({ char __result; \
214 if (sizeof (*(mem)) == 1) \
215 __asm __volatile ("subq%.b %#1,%1; seq %0" \
216 : "=dm" (__result), "+m" (*(mem))); \
217 else if (sizeof (*(mem)) == 2) \
218 __asm __volatile ("subq%.w %#1,%1; seq %0" \
219 : "=dm" (__result), "+m" (*(mem))); \
220 else if (sizeof (*(mem)) == 4) \
221 __asm __volatile ("subq%.l %#1,%1; seq %0" \
222 : "=dm" (__result), "+m" (*(mem))); \
223 else \
224 { \
225 __typeof (mem) __memp = (mem); \
226 __typeof (*(mem)) __oldval = *__memp; \
227 __typeof (*(mem)) __temp; \
228 __asm __volatile ("1: move%.l %1,%2;" \
229 " move%.l %R1,%R2;" \
230 " subq%.l %#1,%2;" \
231 " subx%.l %5,%R2;" \
232 " seq %0;" \
233 " cas2%.l %1:%R1,%2:%R2,(%3):(%4);" \
234 " jbne 1b" \
235 : "=&dm" (__result), "=d" (__oldval), \
236 "=&d" (__temp) \
237 : "r" (__memp), "r" ((char *) __memp + 4), \
238 "d" (0), "1" (__oldval) \
239 : "memory"); \
240 } \
241 __result; })
242
243 #define atomic_bit_set(mem, bit) \
244 __asm __volatile ("bfset %0{%1,#1}" \
245 : "+m" (*(mem)) \
246 : "di" (sizeof (*(mem)) * 8 - (bit) - 1))
247
248 #define atomic_bit_test_set(mem, bit) \
249 ({ char __result; \
250 __asm __volatile ("bfset %1{%2,#1}; sne %0" \
251 : "=dm" (__result), "+m" (*(mem)) \
252 : "di" (sizeof (*(mem)) * 8 - (bit) - 1)); \
253 __result; })