Update copyright dates with scripts/update-copyrights.
[platform/upstream/glibc.git] / sysdeps / unix / sysv / linux / m68k / coldfire / bits / atomic.h
1 /* Copyright (C) 2010-2015 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 #define __HAVE_64B_ATOMICS 0
40 #define USE_ATOMIC_COMPILER_BUILTINS 0
41
42 /* The only basic operation needed is compare and exchange.  */
43 /* For ColdFire we'll have to trap into the kernel mode anyway,
44    so trap from the library rather then from the kernel wrapper.  */
45 #ifdef SHARED
46 # define atomic_compare_and_exchange_val_acq(mem, newval, oldval)       \
47   ({                                                                    \
48     /* Use temporary variables to workaround call-clobberness of        \
49        the registers.  */                                               \
50     __typeof (mem) _mem = mem;                                          \
51     __typeof (oldval) _oldval = oldval;                                 \
52     __typeof (newval) _newval = newval;                                 \
53     register __typeof (mem) _a0 asm ("a0") = _mem;                      \
54     register __typeof (oldval) _d0 asm ("d0") = _oldval;                \
55     register __typeof (newval) _d1 asm ("d1") = _newval;                \
56     void *tmp;                                                          \
57                                                                         \
58     asm ("movel #_GLOBAL_OFFSET_TABLE_@GOTPC, %2\n\t"                   \
59          "lea (-6, %%pc, %2), %2\n\t"                                   \
60          "movel " STR_M68K_VDSO_SYMBOL (__vdso_atomic_cmpxchg_32)       \
61          "@GOT(%2), %2\n\t"                                             \
62          "movel (%2), %2\n\t"                                           \
63          "jsr (%2)\n\t"                                                 \
64          : "+d" (_d0), "+m" (*_a0), "=&a" (tmp)                         \
65          : "a" (_a0), "d" (_d1));                                       \
66     _d0;                                                                \
67   })
68 #else
69 # define atomic_compare_and_exchange_val_acq(mem, newval, oldval)       \
70   ({                                                                    \
71     /* Use temporary variables to workaround call-clobberness of        \
72        the registers.  */                                               \
73     __typeof (mem) _mem = mem;                                          \
74     __typeof (oldval) _oldval = oldval;                                 \
75     __typeof (newval) _newval = newval;                                 \
76     register __typeof (oldval) _d0 asm ("d0")                           \
77       = (__typeof (oldval)) SYS_ify (atomic_cmpxchg_32);                \
78     register __typeof (mem) _a0 asm ("a0") = _mem;                      \
79     register __typeof (oldval) _d2 asm ("d2") = _oldval;                \
80     register __typeof (newval) _d1 asm ("d1") = _newval;                \
81                                                                         \
82     asm ("trap #0"                                                      \
83          : "+d" (_d0), "+m" (*_a0)                                      \
84          : "a" (_a0), "d" (_d2), "d" (_d1));                            \
85     _d0;                                                                \
86   })
87 #endif
88
89 #ifdef SHARED
90 # define atomic_full_barrier()                                   \
91   ({                                                             \
92     void *tmp;                                                   \
93                                                                  \
94     asm ("movel #_GLOBAL_OFFSET_TABLE_@GOTPC, %0\n\t"            \
95          "lea (-6, %pc, %0), %0\n\t"                             \
96          "movel " STR_M68K_VDSO_SYMBOL (__vdso_atomic_barrier)   \
97          "@GOT(%0), %0\n\t"                                      \
98          "movel (%0), %0\n\t"                                    \
99          "jsr (%0)\n\t"                                          \
100          : "=&a" (tmp));                                         \
101   })
102 #else
103 # define atomic_full_barrier()                          \
104   (INTERNAL_SYSCALL (atomic_barrier, , 0), (void) 0)
105 #endif
106
107 #endif