SH: Consolidate nptl/ subdirectories under linux/.....
[platform/upstream/glibc.git] / sysdeps / unix / sysv / linux / m68k / coldfire / nptl / bits / atomic.h
1 /* Copyright (C) 2010-2014 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Maxim Kuvyrkov <maxim@codesourcery.com>, 2010.
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 #ifndef _BITS_ATOMIC_H
20 #define _BITS_ATOMIC_H  1
21
22 #include <stdint.h>
23 #include <sysdep.h>
24 #include <bits/m68k-vdso.h>
25
26 /* Coldfire has no atomic compare-and-exchange operation, but the
27    kernel provides userspace atomicity operations.  Use them.  */
28
29 typedef int32_t atomic32_t;
30 typedef uint32_t uatomic32_t;
31 typedef int_fast32_t atomic_fast32_t;
32 typedef uint_fast32_t uatomic_fast32_t;
33
34 typedef intptr_t atomicptr_t;
35 typedef uintptr_t uatomicptr_t;
36 typedef intmax_t atomic_max_t;
37 typedef uintmax_t uatomic_max_t;
38
39 /* The only basic operation needed is compare and exchange.  */
40 /* For ColdFire we'll have to trap into the kernel mode anyway,
41    so trap from the library rather then from the kernel wrapper.  */
42 #ifdef SHARED
43 # define atomic_compare_and_exchange_val_acq(mem, newval, oldval)       \
44   ({                                                                    \
45     /* Use temporary variables to workaround call-clobberness of        \
46        the registers.  */                                               \
47     __typeof (mem) _mem = mem;                                          \
48     __typeof (oldval) _oldval = oldval;                                 \
49     __typeof (newval) _newval = newval;                                 \
50     register __typeof (mem) _a0 asm ("a0") = _mem;                      \
51     register __typeof (oldval) _d0 asm ("d0") = _oldval;                \
52     register __typeof (newval) _d1 asm ("d1") = _newval;                \
53     void *tmp;                                                          \
54                                                                         \
55     asm ("movel #_GLOBAL_OFFSET_TABLE_@GOTPC, %2\n\t"                   \
56          "lea (-6, %%pc, %2), %2\n\t"                                   \
57          "movel " STR_M68K_VDSO_SYMBOL (__vdso_atomic_cmpxchg_32)       \
58          "@GOT(%2), %2\n\t"                                             \
59          "movel (%2), %2\n\t"                                           \
60          "jsr (%2)\n\t"                                                 \
61          : "+d" (_d0), "+m" (*_a0), "=&a" (tmp)                         \
62          : "a" (_a0), "d" (_d1));                                       \
63     _d0;                                                                \
64   })
65 #else
66 # define atomic_compare_and_exchange_val_acq(mem, newval, oldval)       \
67   ({                                                                    \
68     /* Use temporary variables to workaround call-clobberness of        \
69        the registers.  */                                               \
70     __typeof (mem) _mem = mem;                                          \
71     __typeof (oldval) _oldval = oldval;                                 \
72     __typeof (newval) _newval = newval;                                 \
73     register __typeof (oldval) _d0 asm ("d0")                           \
74       = (__typeof (oldval)) SYS_ify (atomic_cmpxchg_32);                \
75     register __typeof (mem) _a0 asm ("a0") = _mem;                      \
76     register __typeof (oldval) _d2 asm ("d2") = _oldval;                \
77     register __typeof (newval) _d1 asm ("d1") = _newval;                \
78                                                                         \
79     asm ("trap #0"                                                      \
80          : "+d" (_d0), "+m" (*_a0)                                      \
81          : "a" (_a0), "d" (_d2), "d" (_d1));                            \
82     _d0;                                                                \
83   })
84 #endif
85
86 #ifdef SHARED
87 # define atomic_full_barrier()                                   \
88   ({                                                             \
89     void *tmp;                                                   \
90                                                                  \
91     asm ("movel #_GLOBAL_OFFSET_TABLE_@GOTPC, %0\n\t"            \
92          "lea (-6, %pc, %0), %0\n\t"                             \
93          "movel " STR_M68K_VDSO_SYMBOL (__vdso_atomic_barrier)   \
94          "@GOT(%0), %0\n\t"                                      \
95          "movel (%0), %0\n\t"                                    \
96          "jsr (%0)\n\t"                                          \
97          : "=&a" (tmp));                                         \
98   })
99 #else
100 # define atomic_full_barrier()                          \
101   (INTERNAL_SYSCALL (atomic_barrier, , 0), (void) 0)
102 #endif
103
104 #endif