blob: dd5e7141a457696d15a8a707ad35c52e2eeb453f [file] [log] [blame]
xf.libdd93d52023-05-12 07:10:14 -07001/* Atomic operations. Pure ARM version.
2 Copyright (C) 2002-2016 Free Software Foundation, Inc.
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 <http://www.gnu.org/licenses/>. */
18
19#include <stdint.h>
20
21typedef int8_t atomic8_t;
22typedef uint8_t uatomic8_t;
23typedef int_fast8_t atomic_fast8_t;
24typedef uint_fast8_t uatomic_fast8_t;
25
26typedef int32_t atomic32_t;
27typedef uint32_t uatomic32_t;
28typedef int_fast32_t atomic_fast32_t;
29typedef uint_fast32_t uatomic_fast32_t;
30
31typedef intptr_t atomicptr_t;
32typedef uintptr_t uatomicptr_t;
33typedef intmax_t atomic_max_t;
34typedef uintmax_t uatomic_max_t;
35
36#define __HAVE_64B_ATOMICS 0
37#define USE_ATOMIC_COMPILER_BUILTINS 0
38
39void __arm_link_error (void);
40
41#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
42# define atomic_full_barrier() __sync_synchronize ()
43#else
44# define atomic_full_barrier() __arm_assisted_full_barrier ()
45#endif
46
47/* An OS-specific atomic-machine.h file will define this macro if
48 the OS can provide something. If not, we'll fail to build
49 with a compiler that doesn't supply the operation. */
50#ifndef __arm_assisted_full_barrier
51# define __arm_assisted_full_barrier() __arm_link_error()
52#endif
53
54/* Use the atomic builtins provided by GCC in case the backend provides
55 a pattern to do this efficiently. */
56#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
57
58# define atomic_exchange_acq(mem, value) \
59 __atomic_val_bysize (__arch_exchange, int, mem, value, __ATOMIC_ACQUIRE)
60
61# define atomic_exchange_rel(mem, value) \
62 __atomic_val_bysize (__arch_exchange, int, mem, value, __ATOMIC_RELEASE)
63
64/* Atomic exchange (without compare). */
65
66# define __arch_exchange_8_int(mem, newval, model) \
67 (__arm_link_error (), (typeof (*mem)) 0)
68
69# define __arch_exchange_16_int(mem, newval, model) \
70 (__arm_link_error (), (typeof (*mem)) 0)
71
72# define __arch_exchange_32_int(mem, newval, model) \
73 __atomic_exchange_n (mem, newval, model)
74
75# define __arch_exchange_64_int(mem, newval, model) \
76 (__arm_link_error (), (typeof (*mem)) 0)
77
78/* Compare and exchange with "acquire" semantics, ie barrier after. */
79
80# define atomic_compare_and_exchange_bool_acq(mem, new, old) \
81 __atomic_bool_bysize (__arch_compare_and_exchange_bool, int, \
82 mem, new, old, __ATOMIC_ACQUIRE)
83
84# define atomic_compare_and_exchange_val_acq(mem, new, old) \
85 __atomic_val_bysize (__arch_compare_and_exchange_val, int, \
86 mem, new, old, __ATOMIC_ACQUIRE)
87
88/* Compare and exchange with "release" semantics, ie barrier before. */
89
90# define atomic_compare_and_exchange_bool_rel(mem, new, old) \
91 __atomic_bool_bysize (__arch_compare_and_exchange_bool, int, \
92 mem, new, old, __ATOMIC_RELEASE)
93
94# define atomic_compare_and_exchange_val_rel(mem, new, old) \
95 __atomic_val_bysize (__arch_compare_and_exchange_val, int, \
96 mem, new, old, __ATOMIC_RELEASE)
97
98/* Compare and exchange.
99 For all "bool" routines, we return FALSE if exchange succesful. */
100
101# define __arch_compare_and_exchange_bool_8_int(mem, newval, oldval, model) \
102 ({__arm_link_error (); 0; })
103
104# define __arch_compare_and_exchange_bool_16_int(mem, newval, oldval, model) \
105 ({__arm_link_error (); 0; })
106
107# define __arch_compare_and_exchange_bool_32_int(mem, newval, oldval, model) \
108 ({ \
109 typeof (*mem) __oldval = (oldval); \
110 !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \
111 model, __ATOMIC_RELAXED); \
112 })
113
114# define __arch_compare_and_exchange_bool_64_int(mem, newval, oldval, model) \
115 ({__arm_link_error (); 0; })
116
117# define __arch_compare_and_exchange_val_8_int(mem, newval, oldval, model) \
118 ({__arm_link_error (); oldval; })
119
120# define __arch_compare_and_exchange_val_16_int(mem, newval, oldval, model) \
121 ({__arm_link_error (); oldval; })
122
123# define __arch_compare_and_exchange_val_32_int(mem, newval, oldval, model) \
124 ({ \
125 typeof (*mem) __oldval = (oldval); \
126 __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \
127 model, __ATOMIC_RELAXED); \
128 __oldval; \
129 })
130
131# define __arch_compare_and_exchange_val_64_int(mem, newval, oldval, model) \
132 ({__arm_link_error (); oldval; })
133
134#else
135# define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \
136 __arm_assisted_compare_and_exchange_val_32_acq ((mem), (newval), (oldval))
137#endif
138
139#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
140/* We don't support atomic operations on any non-word types.
141 So make them link errors. */
142# define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \
143 ({ __arm_link_error (); oldval; })
144
145# define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \
146 ({ __arm_link_error (); oldval; })
147
148# define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
149 ({ __arm_link_error (); oldval; })
150#endif
151
152/* An OS-specific atomic-machine.h file will define this macro if
153 the OS can provide something. If not, we'll fail to build
154 with a compiler that doesn't supply the operation. */
155#ifndef __arm_assisted_compare_and_exchange_val_32_acq
156# define __arm_assisted_compare_and_exchange_val_32_acq(mem, newval, oldval) \
157 ({ __arm_link_error (); oldval; })
158#endif