]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/uclibc/lib/contrib/uclibc/libc/sysdeps/linux/xtensa/bits/atomic.h
update
[l4.git] / l4 / pkg / uclibc / lib / contrib / uclibc / libc / sysdeps / linux / xtensa / bits / atomic.h
1 /* Copyright (C) 2012 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
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
15    License along with the GNU C Library; if not, see
16    <http://www.gnu.org/licenses/>.  */
17
18 #ifndef _BITS_ATOMIC_H
19 #define _BITS_ATOMIC_H  1
20
21 #include <inttypes.h>
22
23 typedef int32_t atomic32_t;
24 typedef uint32_t uatomic32_t;
25 typedef int_fast32_t atomic_fast32_t;
26 typedef uint_fast32_t uatomic_fast32_t;
27
28 typedef int64_t atomic64_t;
29 typedef uint64_t uatomic64_t;
30 typedef int_fast64_t atomic_fast64_t;
31 typedef uint_fast64_t uatomic_fast64_t;
32
33 typedef intptr_t atomicptr_t;
34 typedef uintptr_t uatomicptr_t;
35 typedef intmax_t atomic_max_t;
36 typedef uintmax_t uatomic_max_t;
37
38
39 /* Xtensa has only a 32-bit form of a store-conditional instruction.  */
40
41 #define __arch_compare_and_exchange_bool_8_acq(mem, newval, oldval) \
42       (abort (), 0)
43
44 #define __arch_compare_and_exchange_bool_16_acq(mem, newval, oldval) \
45       (abort (), 0)
46
47 #define __arch_compare_and_exchange_bool_8_rel(mem, newval, oldval) \
48       (abort (), 0)
49
50 #define __arch_compare_and_exchange_bool_16_rel(mem, newval, oldval) \
51       (abort (), 0)
52
53 /* Atomically store NEWVAL in *MEM if *MEM is equal to OLDVAL.
54    Return the old *MEM value.  */
55
56 #define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval)  \
57   ({__typeof__(*(mem)) __tmp, __value;                               \
58     __asm__ __volatile__(                                            \
59       "1:     l32i    %1, %2, 0               \n"                    \
60       "       bne     %1, %4, 2f              \n"                    \
61       "       wsr     %1, SCOMPARE1           \n"                    \
62       "       mov     %0, %1                  \n"                    \
63       "       mov     %1, %3                  \n"                    \
64       "       s32c1i  %1, %2, 0               \n"                    \
65       "       bne     %0, %1, 1b              \n"                    \
66       "2:                                     \n"                    \
67       : "=&a" (__value), "=&a" (__tmp)                               \
68       : "a" (mem), "a" (newval), "a" (oldval)                        \
69       : "memory" );                                                  \
70     __tmp;                                                           \
71   })
72
73 /* Atomically store NEWVAL in *MEM if *MEM is equal to OLDVAL.
74    Return zero if *MEM was changed or non-zero if no exchange happened.  */
75
76 #define __arch_compare_and_exchange_bool_32_acq(mem, newval, oldval) \
77   ({__typeof__(*(mem)) __tmp, __value;                               \
78     __asm__ __volatile__(                                            \
79       "1:     l32i    %0, %2, 0               \n"                    \
80       "       sub     %1, %4, %0              \n"                    \
81       "       bnez    %1, 2f                  \n"                    \
82       "       wsr     %0, SCOMPARE1           \n"                    \
83       "       mov     %1, %3                  \n"                    \
84       "       s32c1i  %1, %2, 0               \n"                    \
85       "       bne     %0, %1, 1b              \n"                    \
86       "       movi    %1, 0                   \n"                    \
87       "2:                                     \n"                    \
88       : "=&a" (__value), "=&a" (__tmp)                               \
89       : "a" (mem), "a" (newval), "a" (oldval)                        \
90       : "memory" );                                                  \
91     __tmp != 0;                                                      \
92   })
93
94 /* Store NEWVALUE in *MEM and return the old value.  */
95
96 #define __arch_exchange_32_acq(mem, newval)                          \
97   ({__typeof__(*(mem)) __tmp, __value;                               \
98     __asm__ __volatile__(                                            \
99       "1:     l32i    %0, %2, 0               \n"                    \
100       "       wsr     %0, SCOMPARE1           \n"                    \
101       "       mov     %1, %3                  \n"                    \
102       "       s32c1i  %1, %2, 0               \n"                    \
103       "       bne     %0, %1, 1b              \n"                    \
104       : "=&a" (__value), "=&a" (__tmp)                               \
105       : "a" (mem), "a" (newval)                                      \
106       : "memory" );                                                  \
107     __tmp;                                                           \
108   })
109
110 /* Add VALUE to *MEM and return the old value of *MEM.  */
111
112 #define __arch_atomic_exchange_and_add_32(mem, value)                \
113   ({__typeof__(*(mem)) __tmp, __value;                               \
114     __asm__ __volatile__(                                            \
115       "1:     l32i    %0, %2, 0               \n"                    \
116       "       wsr     %0, SCOMPARE1           \n"                    \
117       "       add     %1, %0, %3              \n"                    \
118       "       s32c1i  %1, %2, 0               \n"                    \
119       "       bne     %0, %1, 1b              \n"                    \
120       : "=&a" (__value), "=&a" (__tmp)                               \
121       : "a" (mem), "a" (value)                                       \
122       : "memory" );                                                  \
123     __tmp;                                                           \
124   })
125
126 /* Subtract VALUE from *MEM and return the old value of *MEM.  */
127
128 #define __arch_atomic_exchange_and_sub_32(mem, value)                \
129   ({__typeof__(*(mem)) __tmp, __value;                               \
130     __asm__ __volatile__(                                            \
131       "1:     l32i    %0, %2, 0               \n"                    \
132       "       wsr     %0, SCOMPARE1           \n"                    \
133       "       sub     %1, %0, %3              \n"                    \
134       "       s32c1i  %1, %2, 0               \n"                    \
135       "       bne     %0, %1, 1b              \n"                    \
136       : "=&a" (__value), "=&a" (__tmp)                               \
137       : "a" (mem), "a" (value)                                       \
138       : "memory" );                                                  \
139     __tmp;                                                           \
140   })
141
142 /* Decrement *MEM if it is > 0, and return the old value.  */
143
144 #define __arch_atomic_decrement_if_positive_32(mem)                  \
145   ({__typeof__(*(mem)) __tmp, __value;                               \
146     __asm__ __volatile__(                                            \
147       "1:     l32i    %0, %2, 0               \n"                    \
148       "       blti    %0, 1, 2f               \n"                    \
149       "       wsr     %0, SCOMPARE1           \n"                    \
150       "       addi    %1, %0, -1              \n"                    \
151       "       s32c1i  %1, %2, 0               \n"                    \
152       "       bne     %0, %1, 1b              \n"                    \
153       "2:                                     \n"                    \
154       : "=&a" (__value), "=&a" (__tmp)                               \
155       : "a" (mem)                                                    \
156       : "memory" );                                                  \
157     __value;                                                         \
158   })
159
160
161 /* These are the preferred public interfaces: */
162
163 #define atomic_compare_and_exchange_val_acq(mem, newval, oldval)     \
164   ({                                                                 \
165     if (sizeof (*mem) != 4)                                          \
166       abort();                                                       \
167     __arch_compare_and_exchange_val_32_acq(mem, newval, oldval);     \
168   })
169
170 #define atomic_exchange_acq(mem, newval)                             \
171   ({                                                                 \
172     if (sizeof(*(mem)) != 4)                                         \
173       abort();                                                       \
174     __arch_exchange_32_acq(mem, newval);                             \
175   })
176
177 #define atomic_exchange_and_add(mem, newval)                         \
178   ({                                                                 \
179     if (sizeof(*(mem)) != 4)                                         \
180       abort();                                                       \
181     __arch_atomic_exchange_and_add_32(mem, newval);                  \
182   })
183
184 #define atomic_exchange_and_sub(mem, newval)                         \
185   ({                                                                 \
186     if (sizeof(*(mem)) != 4)                                         \
187       abort();                                                       \
188     __arch_atomic_exchange_and_sub_32(mem, newval);                  \
189   })
190
191 #define atomic_decrement_if_positive(mem)                            \
192   ({                                                                 \
193     if (sizeof(*(mem)) != 4)                                         \
194       abort();                                                       \
195     __arch_atomic_decrement_if_positive_32(mem);                     \
196   })
197
198
199 # define __arch_compare_and_exchange_bool_64_acq(mem, newval, oldval) \
200     (abort (), 0)
201
202 # define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
203     (abort (), (__typeof (*mem)) 0)
204
205 # define __arch_compare_and_exchange_bool_64_rel(mem, newval, oldval) \
206     (abort (), 0)
207
208 # define __arch_compare_and_exchange_val_64_rel(mem, newval, oldval) \
209     (abort (), (__typeof (*mem)) 0)
210
211 # define __arch_atomic_exchange_64_acq(mem, value) \
212     ({ abort (); (*mem) = (value); })
213
214 # define __arch_atomic_exchange_64_rel(mem, value) \
215     ({ abort (); (*mem) = (value); })
216
217 # define __arch_atomic_exchange_and_add_64(mem, value) \
218     ({ abort (); (*mem) = (value); })
219
220 # define __arch_atomic_increment_val_64(mem) \
221     ({ abort (); (*mem)++; })
222
223 # define __arch_atomic_decrement_val_64(mem) \
224     ({ abort (); (*mem)--; })
225
226 # define __arch_atomic_decrement_if_positive_64(mem) \
227     ({ abort (); (*mem)--; })
228
229
230
231 #endif /* _BITS_ATOMIC_H */
232