Commit | Line | Data |
---|---|---|
ace9bad4 MR |
1 | #!/bin/sh |
2 | # SPDX-License-Identifier: GPL-2.0 | |
3 | ||
4 | ATOMICDIR=$(dirname $0) | |
5 | ||
6 | . ${ATOMICDIR}/atomic-tbl.sh | |
7 | ||
f3e615b4 | 8 | #gen_template_fallback(template, meta, pfx, name, sfx, order, atomic, int, args...) |
ace9bad4 MR |
9 | gen_template_fallback() |
10 | { | |
11 | local template="$1"; shift | |
12 | local meta="$1"; shift | |
13 | local pfx="$1"; shift | |
14 | local name="$1"; shift | |
15 | local sfx="$1"; shift | |
16 | local order="$1"; shift | |
17 | local atomic="$1"; shift | |
18 | local int="$1"; shift | |
19 | ||
ace9bad4 MR |
20 | local ret="$(gen_ret_type "${meta}" "${int}")" |
21 | local retstmt="$(gen_ret_stmt "${meta}")" | |
22 | local params="$(gen_params "${int}" "${atomic}" "$@")" | |
23 | local args="$(gen_args "$@")" | |
24 | ||
9257959a | 25 | . ${template} |
ace9bad4 MR |
26 | } |
27 | ||
7ed7a156 MR |
28 | #gen_order_fallback(meta, pfx, name, sfx, order, atomic, int, args...) |
29 | gen_order_fallback() | |
30 | { | |
31 | local meta="$1"; shift | |
32 | local pfx="$1"; shift | |
33 | local name="$1"; shift | |
34 | local sfx="$1"; shift | |
35 | local order="$1"; shift | |
36 | ||
37 | local tmpl_order=${order#_} | |
38 | local tmpl="${ATOMICDIR}/fallbacks/${tmpl_order:-fence}" | |
39 | gen_template_fallback "${tmpl}" "${meta}" "${pfx}" "${name}" "${sfx}" "${order}" "$@" | |
40 | } | |
41 | ||
f3e615b4 | 42 | #gen_proto_fallback(meta, pfx, name, sfx, order, atomic, int, args...) |
ace9bad4 MR |
43 | gen_proto_fallback() |
44 | { | |
45 | local meta="$1"; shift | |
46 | local pfx="$1"; shift | |
47 | local name="$1"; shift | |
48 | local sfx="$1"; shift | |
49 | local order="$1"; shift | |
50 | ||
51 | local tmpl="$(find_fallback_template "${pfx}" "${name}" "${sfx}" "${order}")" | |
52 | gen_template_fallback "${tmpl}" "${meta}" "${pfx}" "${name}" "${sfx}" "${order}" "$@" | |
53 | } | |
54 | ||
9257959a MR |
55 | #gen_proto_order_variant(meta, pfx, name, sfx, order, atomic, int, args...) |
56 | gen_proto_order_variant() | |
ace9bad4 MR |
57 | { |
58 | local meta="$1"; shift | |
59 | local pfx="$1"; shift | |
60 | local name="$1"; shift | |
61 | local sfx="$1"; shift | |
9257959a | 62 | local order="$1"; shift |
1d78814d MR |
63 | local atomic="$1"; shift |
64 | local int="$1"; shift | |
ace9bad4 | 65 | |
9257959a MR |
66 | local atomicname="${atomic}_${pfx}${name}${sfx}${order}" |
67 | local basename="${atomic}_${pfx}${name}${sfx}" | |
ace9bad4 | 68 | |
9257959a | 69 | local template="$(find_fallback_template "${pfx}" "${name}" "${sfx}" "${order}")" |
ace9bad4 | 70 | |
1d78814d MR |
71 | local ret="$(gen_ret_type "${meta}" "${int}")" |
72 | local retstmt="$(gen_ret_stmt "${meta}")" | |
73 | local params="$(gen_params "${int}" "${atomic}" "$@")" | |
74 | local args="$(gen_args "$@")" | |
75 | ||
ad811070 MR |
76 | gen_kerneldoc "raw_" "${meta}" "${pfx}" "${name}" "${sfx}" "${order}" "${atomic}" "${int}" "$@" |
77 | ||
1d78814d MR |
78 | printf "static __always_inline ${ret}\n" |
79 | printf "raw_${atomicname}(${params})\n" | |
80 | printf "{\n" | |
81 | ||
9257959a MR |
82 | # Where there is no possible fallback, this order variant is mandatory |
83 | # and must be provided by arch code. Add a comment to the header to | |
84 | # make this obvious. | |
85 | # | |
86 | # Ideally we'd error on a missing definition, but arch code might | |
87 | # define this order variant as a C function without a preprocessor | |
88 | # symbol. | |
89 | if [ -z ${template} ] && [ -z "${order}" ] && ! meta_has_relaxed "${meta}"; then | |
1d78814d MR |
90 | printf "\t${retstmt}arch_${atomicname}(${args});\n" |
91 | printf "}\n\n" | |
9257959a MR |
92 | return |
93 | fi | |
ace9bad4 | 94 | |
9257959a | 95 | printf "#if defined(arch_${atomicname})\n" |
1d78814d | 96 | printf "\t${retstmt}arch_${atomicname}(${args});\n" |
ace9bad4 | 97 | |
9257959a MR |
98 | # Allow FULL/ACQUIRE/RELEASE ops to be defined in terms of RELAXED ops |
99 | if [ "${order}" != "_relaxed" ] && meta_has_relaxed "${meta}"; then | |
100 | printf "#elif defined(arch_${basename}_relaxed)\n" | |
1d78814d | 101 | gen_order_fallback "${meta}" "${pfx}" "${name}" "${sfx}" "${order}" "${atomic}" "${int}" "$@" |
ace9bad4 MR |
102 | fi |
103 | ||
9257959a | 104 | # Allow ACQUIRE/RELEASE/RELAXED ops to be defined in terms of FULL ops |
6d2779ec | 105 | if [ ! -z "${order}" ] && ! meta_is_implicitly_relaxed "${meta}"; then |
9257959a | 106 | printf "#elif defined(arch_${basename})\n" |
1d78814d | 107 | printf "\t${retstmt}arch_${basename}(${args});\n" |
9257959a | 108 | fi |
ace9bad4 | 109 | |
9257959a | 110 | printf "#else\n" |
ace9bad4 | 111 | if [ ! -z "${template}" ]; then |
1d78814d | 112 | gen_proto_fallback "${meta}" "${pfx}" "${name}" "${sfx}" "${order}" "${atomic}" "${int}" "$@" |
9257959a MR |
113 | else |
114 | printf "#error \"Unable to define raw_${atomicname}\"\n" | |
ace9bad4 MR |
115 | fi |
116 | ||
1d78814d MR |
117 | printf "#endif\n" |
118 | printf "}\n\n" | |
9257959a | 119 | } |
ace9bad4 | 120 | |
9257959a MR |
121 | |
122 | #gen_proto_order_variants(meta, pfx, name, sfx, atomic, int, args...) | |
123 | gen_proto_order_variants() | |
124 | { | |
125 | local meta="$1"; shift | |
126 | local pfx="$1"; shift | |
127 | local name="$1"; shift | |
128 | local sfx="$1"; shift | |
129 | local atomic="$1" | |
130 | ||
131 | gen_proto_order_variant "${meta}" "${pfx}" "${name}" "${sfx}" "" "$@" | |
132 | ||
133 | if meta_has_acquire "${meta}"; then | |
134 | gen_proto_order_variant "${meta}" "${pfx}" "${name}" "${sfx}" "_acquire" "$@" | |
ace9bad4 MR |
135 | fi |
136 | ||
9257959a MR |
137 | if meta_has_release "${meta}"; then |
138 | gen_proto_order_variant "${meta}" "${pfx}" "${name}" "${sfx}" "_release" "$@" | |
139 | fi | |
ace9bad4 | 140 | |
9257959a MR |
141 | if meta_has_relaxed "${meta}"; then |
142 | gen_proto_order_variant "${meta}" "${pfx}" "${name}" "${sfx}" "_relaxed" "$@" | |
143 | fi | |
144 | } | |
ace9bad4 | 145 | |
9257959a MR |
146 | #gen_basic_fallbacks(basename) |
147 | gen_basic_fallbacks() | |
148 | { | |
149 | local basename="$1"; shift | |
150 | cat << EOF | |
151 | #define raw_${basename}_acquire arch_${basename} | |
152 | #define raw_${basename}_release arch_${basename} | |
153 | #define raw_${basename}_relaxed arch_${basename} | |
154 | EOF | |
ace9bad4 MR |
155 | } |
156 | ||
29f006fd | 157 | gen_order_fallbacks() |
ace9bad4 MR |
158 | { |
159 | local xchg="$1"; shift | |
29f006fd | 160 | |
ace9bad4 | 161 | cat <<EOF |
ace9bad4 | 162 | |
9257959a MR |
163 | #define raw_${xchg}_relaxed arch_${xchg}_relaxed |
164 | ||
165 | #ifdef arch_${xchg}_acquire | |
166 | #define raw_${xchg}_acquire arch_${xchg}_acquire | |
167 | #else | |
168 | #define raw_${xchg}_acquire(...) \\ | |
169 | __atomic_op_acquire(arch_${xchg}, __VA_ARGS__) | |
ace9bad4 MR |
170 | #endif |
171 | ||
9257959a MR |
172 | #ifdef arch_${xchg}_release |
173 | #define raw_${xchg}_release arch_${xchg}_release | |
174 | #else | |
175 | #define raw_${xchg}_release(...) \\ | |
176 | __atomic_op_release(arch_${xchg}, __VA_ARGS__) | |
ace9bad4 MR |
177 | #endif |
178 | ||
9257959a MR |
179 | #ifdef arch_${xchg} |
180 | #define raw_${xchg} arch_${xchg} | |
181 | #else | |
182 | #define raw_${xchg}(...) \\ | |
183 | __atomic_op_fence(arch_${xchg}, __VA_ARGS__) | |
ace9bad4 MR |
184 | #endif |
185 | ||
29f006fd PZ |
186 | EOF |
187 | } | |
188 | ||
9257959a | 189 | gen_xchg_order_fallback() |
29f006fd PZ |
190 | { |
191 | local xchg="$1"; shift | |
9257959a MR |
192 | local order="$1"; shift |
193 | local forder="${order:-_fence}" | |
29f006fd | 194 | |
9257959a MR |
195 | printf "#if defined(arch_${xchg}${order})\n" |
196 | printf "#define raw_${xchg}${order} arch_${xchg}${order}\n" | |
29f006fd | 197 | |
9257959a MR |
198 | if [ "${order}" != "_relaxed" ]; then |
199 | printf "#elif defined(arch_${xchg}_relaxed)\n" | |
200 | printf "#define raw_${xchg}${order}(...) \\\\\n" | |
201 | printf " __atomic_op${forder}(arch_${xchg}, __VA_ARGS__)\n" | |
202 | fi | |
29f006fd | 203 | |
9257959a MR |
204 | if [ ! -z "${order}" ]; then |
205 | printf "#elif defined(arch_${xchg})\n" | |
206 | printf "#define raw_${xchg}${order} arch_${xchg}\n" | |
207 | fi | |
29f006fd | 208 | |
9257959a MR |
209 | printf "#else\n" |
210 | printf "extern void raw_${xchg}${order}_not_implemented(void);\n" | |
211 | printf "#define raw_${xchg}${order}(...) raw_${xchg}${order}_not_implemented()\n" | |
212 | printf "#endif\n\n" | |
213 | } | |
214 | ||
215 | gen_xchg_fallbacks() | |
216 | { | |
217 | local xchg="$1"; shift | |
218 | ||
219 | for order in "" "_acquire" "_release" "_relaxed"; do | |
220 | gen_xchg_order_fallback "${xchg}" "${order}" | |
221 | done | |
29f006fd PZ |
222 | } |
223 | ||
224 | gen_try_cmpxchg_fallback() | |
225 | { | |
e01cc1e8 | 226 | local prefix="$1"; shift |
0aa7be05 | 227 | local cmpxchg="$1"; shift; |
e01cc1e8 | 228 | local suffix="$1"; shift; |
29f006fd PZ |
229 | |
230 | cat <<EOF | |
e01cc1e8 | 231 | #define raw_${prefix}try_${cmpxchg}${suffix}(_ptr, _oldp, _new) \\ |
29f006fd PZ |
232 | ({ \\ |
233 | typeof(*(_ptr)) *___op = (_oldp), ___o = *___op, ___r; \\ | |
e01cc1e8 | 234 | ___r = raw_${prefix}${cmpxchg}${suffix}((_ptr), ___o, (_new)); \\ |
29f006fd PZ |
235 | if (unlikely(___r != ___o)) \\ |
236 | *___op = ___r; \\ | |
237 | likely(___r == ___o); \\ | |
238 | }) | |
ace9bad4 MR |
239 | EOF |
240 | } | |
241 | ||
9257959a | 242 | gen_try_cmpxchg_order_fallback() |
29f006fd | 243 | { |
9257959a MR |
244 | local cmpxchg="$1"; shift |
245 | local order="$1"; shift | |
246 | local forder="${order:-_fence}" | |
29f006fd | 247 | |
9257959a MR |
248 | printf "#if defined(arch_try_${cmpxchg}${order})\n" |
249 | printf "#define raw_try_${cmpxchg}${order} arch_try_${cmpxchg}${order}\n" | |
29f006fd | 250 | |
9257959a MR |
251 | if [ "${order}" != "_relaxed" ]; then |
252 | printf "#elif defined(arch_try_${cmpxchg}_relaxed)\n" | |
253 | printf "#define raw_try_${cmpxchg}${order}(...) \\\\\n" | |
254 | printf " __atomic_op${forder}(arch_try_${cmpxchg}, __VA_ARGS__)\n" | |
255 | fi | |
256 | ||
257 | if [ ! -z "${order}" ]; then | |
258 | printf "#elif defined(arch_try_${cmpxchg})\n" | |
259 | printf "#define raw_try_${cmpxchg}${order} arch_try_${cmpxchg}\n" | |
260 | fi | |
0aa7be05 | 261 | |
9257959a | 262 | printf "#else\n" |
e01cc1e8 | 263 | gen_try_cmpxchg_fallback "" "${cmpxchg}" "${order}" |
9257959a MR |
264 | printf "#endif\n\n" |
265 | } | |
266 | ||
e01cc1e8 | 267 | gen_try_cmpxchg_order_fallbacks() |
9257959a MR |
268 | { |
269 | local cmpxchg="$1"; shift; | |
29f006fd PZ |
270 | |
271 | for order in "" "_acquire" "_release" "_relaxed"; do | |
9257959a | 272 | gen_try_cmpxchg_order_fallback "${cmpxchg}" "${order}" |
29f006fd | 273 | done |
9257959a | 274 | } |
29f006fd | 275 | |
e01cc1e8 | 276 | gen_def_and_try_cmpxchg_fallback() |
9257959a | 277 | { |
e01cc1e8 | 278 | local prefix="$1"; shift |
9257959a | 279 | local cmpxchg="$1"; shift |
e01cc1e8 | 280 | local suffix="$1"; shift |
29f006fd | 281 | |
e01cc1e8 UB |
282 | printf "#define raw_${prefix}${cmpxchg}${suffix} arch_${prefix}${cmpxchg}${suffix}\n\n" |
283 | printf "#ifdef arch_${prefix}try_${cmpxchg}${suffix}\n" | |
284 | printf "#define raw_${prefix}try_${cmpxchg}${suffix} arch_${prefix}try_${cmpxchg}${suffix}\n" | |
9257959a | 285 | printf "#else\n" |
e01cc1e8 | 286 | gen_try_cmpxchg_fallback "${prefix}" "${cmpxchg}" "${suffix}" |
9257959a | 287 | printf "#endif\n\n" |
29f006fd PZ |
288 | } |
289 | ||
ace9bad4 MR |
290 | cat << EOF |
291 | // SPDX-License-Identifier: GPL-2.0 | |
292 | ||
293 | // Generated by $0 | |
294 | // DO NOT MODIFY THIS FILE DIRECTLY | |
295 | ||
296 | #ifndef _LINUX_ATOMIC_FALLBACK_H | |
297 | #define _LINUX_ATOMIC_FALLBACK_H | |
298 | ||
765dcd20 ME |
299 | #include <linux/compiler.h> |
300 | ||
ace9bad4 MR |
301 | EOF |
302 | ||
9257959a | 303 | for xchg in "xchg" "cmpxchg" "cmpxchg64" "cmpxchg128"; do |
ace9bad4 MR |
304 | gen_xchg_fallbacks "${xchg}" |
305 | done | |
306 | ||
8c8b096a | 307 | for cmpxchg in "cmpxchg" "cmpxchg64" "cmpxchg128"; do |
e01cc1e8 | 308 | gen_try_cmpxchg_order_fallbacks "${cmpxchg}" |
0aa7be05 | 309 | done |
29f006fd | 310 | |
e01cc1e8 UB |
311 | for cmpxchg in "cmpxchg" "cmpxchg64" "cmpxchg128"; do |
312 | gen_def_and_try_cmpxchg_fallback "" "${cmpxchg}" "_local" | |
9257959a MR |
313 | done |
314 | ||
e01cc1e8 UB |
315 | for cmpxchg in "cmpxchg"; do |
316 | gen_def_and_try_cmpxchg_fallback "sync_" "${cmpxchg}" "" | |
e6ce9d74 UB |
317 | done |
318 | ||
ace9bad4 | 319 | grep '^[a-z]' "$1" | while read name meta args; do |
f3e615b4 | 320 | gen_proto "${meta}" "${name}" "atomic" "int" ${args} |
ace9bad4 MR |
321 | done |
322 | ||
323 | cat <<EOF | |
ace9bad4 MR |
324 | #ifdef CONFIG_GENERIC_ATOMIC64 |
325 | #include <asm-generic/atomic64.h> | |
326 | #endif | |
327 | ||
328 | EOF | |
329 | ||
330 | grep '^[a-z]' "$1" | while read name meta args; do | |
f3e615b4 | 331 | gen_proto "${meta}" "${name}" "atomic64" "s64" ${args} |
ace9bad4 MR |
332 | done |
333 | ||
334 | cat <<EOF | |
ace9bad4 MR |
335 | #endif /* _LINUX_ATOMIC_FALLBACK_H */ |
336 | EOF |