1 /* Copyright (C) 2003-2021 Free Software Foundation, Inc.
2 
3    This file is part of the GNU C Library.
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    <https://www.gnu.org/licenses/>.  */
18 
19 #ifndef _AARCH64_ATOMIC_MACHINE_H
20 #define _AARCH64_ATOMIC_MACHINE_H	1
21 
22 #define __HAVE_64B_ATOMICS 1
23 #define USE_ATOMIC_COMPILER_BUILTINS 1
24 #define ATOMIC_EXCHANGE_USES_CAS 0
25 
26 /* Compare and exchange.
27    For all "bool" routines, we return FALSE if exchange succesful.  */
28 
29 # define __arch_compare_and_exchange_bool_8_int(mem, newval, oldval, model) \
30   ({									\
31     typeof (*mem) __oldval = (oldval);					\
32     !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0,	\
33 				  model, __ATOMIC_RELAXED);		\
34   })
35 
36 # define __arch_compare_and_exchange_bool_16_int(mem, newval, oldval, model) \
37   ({									\
38     typeof (*mem) __oldval = (oldval);					\
39     !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0,	\
40 				  model, __ATOMIC_RELAXED);		\
41   })
42 
43 # define __arch_compare_and_exchange_bool_32_int(mem, newval, oldval, model) \
44   ({									\
45     typeof (*mem) __oldval = (oldval);					\
46     !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0,	\
47 				  model, __ATOMIC_RELAXED);		\
48   })
49 
50 #  define __arch_compare_and_exchange_bool_64_int(mem, newval, oldval, model) \
51   ({									\
52     typeof (*mem) __oldval = (oldval);					\
53     !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0,	\
54 				  model, __ATOMIC_RELAXED);		\
55   })
56 
57 # define __arch_compare_and_exchange_val_8_int(mem, newval, oldval, model) \
58   ({									\
59     typeof (*mem) __oldval = (oldval);					\
60     __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0,	\
61 				 model, __ATOMIC_RELAXED);		\
62     __oldval;								\
63   })
64 
65 # define __arch_compare_and_exchange_val_16_int(mem, newval, oldval, model) \
66   ({									\
67     typeof (*mem) __oldval = (oldval);					\
68     __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0,	\
69 				 model, __ATOMIC_RELAXED);		\
70     __oldval;								\
71   })
72 
73 # define __arch_compare_and_exchange_val_32_int(mem, newval, oldval, model) \
74   ({									\
75     typeof (*mem) __oldval = (oldval);					\
76     __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0,	\
77 				 model, __ATOMIC_RELAXED);		\
78     __oldval;								\
79   })
80 
81 #  define __arch_compare_and_exchange_val_64_int(mem, newval, oldval, model) \
82   ({									\
83     typeof (*mem) __oldval = (oldval);					\
84     __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0,	\
85 				 model, __ATOMIC_RELAXED);		\
86     __oldval;								\
87   })
88 
89 
90 /* Compare and exchange with "acquire" semantics, ie barrier after.  */
91 
92 # define atomic_compare_and_exchange_bool_acq(mem, new, old)	\
93   __atomic_bool_bysize (__arch_compare_and_exchange_bool, int,	\
94 			mem, new, old, __ATOMIC_ACQUIRE)
95 
96 # define atomic_compare_and_exchange_val_acq(mem, new, old)	\
97   __atomic_val_bysize (__arch_compare_and_exchange_val, int,	\
98 		       mem, new, old, __ATOMIC_ACQUIRE)
99 
100 /* Compare and exchange with "release" semantics, ie barrier before.  */
101 
102 # define atomic_compare_and_exchange_val_rel(mem, new, old)	 \
103   __atomic_val_bysize (__arch_compare_and_exchange_val, int,    \
104                        mem, new, old, __ATOMIC_RELEASE)
105 
106 
107 /* Atomic exchange (without compare).  */
108 
109 # define __arch_exchange_8_int(mem, newval, model)	\
110   __atomic_exchange_n (mem, newval, model)
111 
112 # define __arch_exchange_16_int(mem, newval, model)	\
113   __atomic_exchange_n (mem, newval, model)
114 
115 # define __arch_exchange_32_int(mem, newval, model)	\
116   __atomic_exchange_n (mem, newval, model)
117 
118 #  define __arch_exchange_64_int(mem, newval, model)	\
119   __atomic_exchange_n (mem, newval, model)
120 
121 # define atomic_exchange_acq(mem, value)				\
122   __atomic_val_bysize (__arch_exchange, int, mem, value, __ATOMIC_ACQUIRE)
123 
124 # define atomic_exchange_rel(mem, value)				\
125   __atomic_val_bysize (__arch_exchange, int, mem, value, __ATOMIC_RELEASE)
126 
127 
128 /* Atomically add value and return the previous (unincremented) value.  */
129 
130 # define __arch_exchange_and_add_8_int(mem, value, model)	\
131   __atomic_fetch_add (mem, value, model)
132 
133 # define __arch_exchange_and_add_16_int(mem, value, model)	\
134   __atomic_fetch_add (mem, value, model)
135 
136 # define __arch_exchange_and_add_32_int(mem, value, model)	\
137   __atomic_fetch_add (mem, value, model)
138 
139 #  define __arch_exchange_and_add_64_int(mem, value, model)	\
140   __atomic_fetch_add (mem, value, model)
141 
142 # define atomic_exchange_and_add_acq(mem, value)			\
143   __atomic_val_bysize (__arch_exchange_and_add, int, mem, value,	\
144 		       __ATOMIC_ACQUIRE)
145 
146 # define atomic_exchange_and_add_rel(mem, value)			\
147   __atomic_val_bysize (__arch_exchange_and_add, int, mem, value,	\
148 		       __ATOMIC_RELEASE)
149 
150 /* Barrier macro. */
151 #define atomic_full_barrier() __sync_synchronize()
152 
153 #endif
154