1ace9bad4SMark Rutland#!/bin/sh
2ace9bad4SMark Rutland# SPDX-License-Identifier: GPL-2.0
3ace9bad4SMark Rutland
4ace9bad4SMark RutlandATOMICDIR=$(dirname $0)
5ace9bad4SMark Rutland
6ace9bad4SMark Rutland. ${ATOMICDIR}/atomic-tbl.sh
7ace9bad4SMark Rutland
8f3e615b4SMark Rutland#gen_template_fallback(template, meta, pfx, name, sfx, order, atomic, int, args...)
9ace9bad4SMark Rutlandgen_template_fallback()
10ace9bad4SMark Rutland{
11ace9bad4SMark Rutland	local template="$1"; shift
12ace9bad4SMark Rutland	local meta="$1"; shift
13ace9bad4SMark Rutland	local pfx="$1"; shift
14ace9bad4SMark Rutland	local name="$1"; shift
15ace9bad4SMark Rutland	local sfx="$1"; shift
16ace9bad4SMark Rutland	local order="$1"; shift
17ace9bad4SMark Rutland	local atomic="$1"; shift
18ace9bad4SMark Rutland	local int="$1"; shift
19ace9bad4SMark Rutland
20ace9bad4SMark Rutland	local ret="$(gen_ret_type "${meta}" "${int}")"
21ace9bad4SMark Rutland	local retstmt="$(gen_ret_stmt "${meta}")"
22ace9bad4SMark Rutland	local params="$(gen_params "${int}" "${atomic}" "$@")"
23ace9bad4SMark Rutland	local args="$(gen_args "$@")"
24ace9bad4SMark Rutland
25ace9bad4SMark Rutland	. ${template}
26ace9bad4SMark Rutland}
27ace9bad4SMark Rutland
287ed7a156SMark Rutland#gen_order_fallback(meta, pfx, name, sfx, order, atomic, int, args...)
297ed7a156SMark Rutlandgen_order_fallback()
307ed7a156SMark Rutland{
317ed7a156SMark Rutland	local meta="$1"; shift
327ed7a156SMark Rutland	local pfx="$1"; shift
337ed7a156SMark Rutland	local name="$1"; shift
347ed7a156SMark Rutland	local sfx="$1"; shift
357ed7a156SMark Rutland	local order="$1"; shift
367ed7a156SMark Rutland
377ed7a156SMark Rutland	local tmpl_order=${order#_}
387ed7a156SMark Rutland	local tmpl="${ATOMICDIR}/fallbacks/${tmpl_order:-fence}"
397ed7a156SMark Rutland	gen_template_fallback "${tmpl}" "${meta}" "${pfx}" "${name}" "${sfx}" "${order}" "$@"
407ed7a156SMark Rutland}
417ed7a156SMark Rutland
42f3e615b4SMark Rutland#gen_proto_fallback(meta, pfx, name, sfx, order, atomic, int, args...)
43ace9bad4SMark Rutlandgen_proto_fallback()
44ace9bad4SMark Rutland{
45ace9bad4SMark Rutland	local meta="$1"; shift
46ace9bad4SMark Rutland	local pfx="$1"; shift
47ace9bad4SMark Rutland	local name="$1"; shift
48ace9bad4SMark Rutland	local sfx="$1"; shift
49ace9bad4SMark Rutland	local order="$1"; shift
50ace9bad4SMark Rutland
51ace9bad4SMark Rutland	local tmpl="$(find_fallback_template "${pfx}" "${name}" "${sfx}" "${order}")"
52ace9bad4SMark Rutland	gen_template_fallback "${tmpl}" "${meta}" "${pfx}" "${name}" "${sfx}" "${order}" "$@"
53ace9bad4SMark Rutland}
54ace9bad4SMark Rutland
559257959aSMark Rutland#gen_proto_order_variant(meta, pfx, name, sfx, order, atomic, int, args...)
569257959aSMark Rutlandgen_proto_order_variant()
57ace9bad4SMark Rutland{
589257959aSMark Rutland	local meta="$1"; shift
599257959aSMark Rutland	local pfx="$1"; shift
609257959aSMark Rutland	local name="$1"; shift
619257959aSMark Rutland	local sfx="$1"; shift
629257959aSMark Rutland	local order="$1"; shift
631d78814dSMark Rutland	local atomic="$1"; shift
641d78814dSMark Rutland	local int="$1"; shift
659257959aSMark Rutland
669257959aSMark Rutland	local atomicname="${atomic}_${pfx}${name}${sfx}${order}"
679257959aSMark Rutland	local basename="${atomic}_${pfx}${name}${sfx}"
689257959aSMark Rutland
699257959aSMark Rutland	local template="$(find_fallback_template "${pfx}" "${name}" "${sfx}" "${order}")"
709257959aSMark Rutland
711d78814dSMark Rutland	local ret="$(gen_ret_type "${meta}" "${int}")"
721d78814dSMark Rutland	local retstmt="$(gen_ret_stmt "${meta}")"
731d78814dSMark Rutland	local params="$(gen_params "${int}" "${atomic}" "$@")"
741d78814dSMark Rutland	local args="$(gen_args "$@")"
751d78814dSMark Rutland
76ad811070SMark Rutland	gen_kerneldoc "raw_" "${meta}" "${pfx}" "${name}" "${sfx}" "${order}" "${atomic}" "${int}" "$@"
77ad811070SMark Rutland
781d78814dSMark Rutland	printf "static __always_inline ${ret}\n"
791d78814dSMark Rutland	printf "raw_${atomicname}(${params})\n"
801d78814dSMark Rutland	printf "{\n"
811d78814dSMark Rutland
829257959aSMark Rutland	# Where there is no possible fallback, this order variant is mandatory
839257959aSMark Rutland	# and must be provided by arch code. Add a comment to the header to
849257959aSMark Rutland	# make this obvious.
859257959aSMark Rutland	#
869257959aSMark Rutland	# Ideally we'd error on a missing definition, but arch code might
879257959aSMark Rutland	# define this order variant as a C function without a preprocessor
889257959aSMark Rutland	# symbol.
899257959aSMark Rutland	if [ -z ${template} ] && [ -z "${order}" ] && ! meta_has_relaxed "${meta}"; then
901d78814dSMark Rutland		printf "\t${retstmt}arch_${atomicname}(${args});\n"
911d78814dSMark Rutland		printf "}\n\n"
929257959aSMark Rutland		return
939257959aSMark Rutland	fi
949257959aSMark Rutland
959257959aSMark Rutland	printf "#if defined(arch_${atomicname})\n"
961d78814dSMark Rutland	printf "\t${retstmt}arch_${atomicname}(${args});\n"
979257959aSMark Rutland
989257959aSMark Rutland	# Allow FULL/ACQUIRE/RELEASE ops to be defined in terms of RELAXED ops
999257959aSMark Rutland	if [ "${order}" != "_relaxed" ] && meta_has_relaxed "${meta}"; then
1009257959aSMark Rutland		printf "#elif defined(arch_${basename}_relaxed)\n"
1011d78814dSMark Rutland		gen_order_fallback "${meta}" "${pfx}" "${name}" "${sfx}" "${order}" "${atomic}" "${int}" "$@"
1029257959aSMark Rutland	fi
1039257959aSMark Rutland
1049257959aSMark Rutland	# Allow ACQUIRE/RELEASE/RELAXED ops to be defined in terms of FULL ops
1056d2779ecSMark Rutland	if [ ! -z "${order}" ] && ! meta_is_implicitly_relaxed "${meta}"; then
1069257959aSMark Rutland		printf "#elif defined(arch_${basename})\n"
1071d78814dSMark Rutland		printf "\t${retstmt}arch_${basename}(${args});\n"
1089257959aSMark Rutland	fi
1099257959aSMark Rutland
1109257959aSMark Rutland	printf "#else\n"
1119257959aSMark Rutland	if [ ! -z "${template}" ]; then
1121d78814dSMark Rutland		gen_proto_fallback "${meta}" "${pfx}" "${name}" "${sfx}" "${order}" "${atomic}" "${int}" "$@"
1139257959aSMark Rutland	else
1149257959aSMark Rutland		printf "#error \"Unable to define raw_${atomicname}\"\n"
1159257959aSMark Rutland	fi
1169257959aSMark Rutland
1171d78814dSMark Rutland	printf "#endif\n"
1181d78814dSMark Rutland	printf "}\n\n"
119ace9bad4SMark Rutland}
120ace9bad4SMark Rutland
1219257959aSMark Rutland
122f3e615b4SMark Rutland#gen_proto_order_variants(meta, pfx, name, sfx, atomic, int, args...)
123ace9bad4SMark Rutlandgen_proto_order_variants()
124ace9bad4SMark Rutland{
125ace9bad4SMark Rutland	local meta="$1"; shift
126ace9bad4SMark Rutland	local pfx="$1"; shift
127ace9bad4SMark Rutland	local name="$1"; shift
128ace9bad4SMark Rutland	local sfx="$1"; shift
129f3e615b4SMark Rutland	local atomic="$1"
130ace9bad4SMark Rutland
1319257959aSMark Rutland	gen_proto_order_variant "${meta}" "${pfx}" "${name}" "${sfx}" "" "$@"
132ace9bad4SMark Rutland
133ace9bad4SMark Rutland	if meta_has_acquire "${meta}"; then
1349257959aSMark Rutland		gen_proto_order_variant "${meta}" "${pfx}" "${name}" "${sfx}" "_acquire" "$@"
135ace9bad4SMark Rutland	fi
136ace9bad4SMark Rutland
137ace9bad4SMark Rutland	if meta_has_release "${meta}"; then
1389257959aSMark Rutland		gen_proto_order_variant "${meta}" "${pfx}" "${name}" "${sfx}" "_release" "$@"
139ace9bad4SMark Rutland	fi
140ace9bad4SMark Rutland
1419257959aSMark Rutland	if meta_has_relaxed "${meta}"; then
1429257959aSMark Rutland		gen_proto_order_variant "${meta}" "${pfx}" "${name}" "${sfx}" "_relaxed" "$@"
143ace9bad4SMark Rutland	fi
1449257959aSMark Rutland}
145ace9bad4SMark Rutland
1469257959aSMark Rutland#gen_basic_fallbacks(basename)
1479257959aSMark Rutlandgen_basic_fallbacks()
1489257959aSMark Rutland{
1499257959aSMark Rutland	local basename="$1"; shift
1509257959aSMark Rutlandcat << EOF
1519257959aSMark Rutland#define raw_${basename}_acquire arch_${basename}
1529257959aSMark Rutland#define raw_${basename}_release arch_${basename}
1539257959aSMark Rutland#define raw_${basename}_relaxed arch_${basename}
1549257959aSMark RutlandEOF
155ace9bad4SMark Rutland}
156ace9bad4SMark Rutland
15729f006fdSPeter Zijlstragen_order_fallbacks()
158ace9bad4SMark Rutland{
159ace9bad4SMark Rutland	local xchg="$1"; shift
16029f006fdSPeter Zijlstra
161ace9bad4SMark Rutlandcat <<EOF
162ace9bad4SMark Rutland
1639257959aSMark Rutland#define raw_${xchg}_relaxed arch_${xchg}_relaxed
1649257959aSMark Rutland
1659257959aSMark Rutland#ifdef arch_${xchg}_acquire
1669257959aSMark Rutland#define raw_${xchg}_acquire arch_${xchg}_acquire
1679257959aSMark Rutland#else
1689257959aSMark Rutland#define raw_${xchg}_acquire(...) \\
1699257959aSMark Rutland	__atomic_op_acquire(arch_${xchg}, __VA_ARGS__)
170ace9bad4SMark Rutland#endif
171ace9bad4SMark Rutland
1729257959aSMark Rutland#ifdef arch_${xchg}_release
1739257959aSMark Rutland#define raw_${xchg}_release arch_${xchg}_release
1749257959aSMark Rutland#else
1759257959aSMark Rutland#define raw_${xchg}_release(...) \\
1769257959aSMark Rutland	__atomic_op_release(arch_${xchg}, __VA_ARGS__)
177ace9bad4SMark Rutland#endif
178ace9bad4SMark Rutland
1799257959aSMark Rutland#ifdef arch_${xchg}
1809257959aSMark Rutland#define raw_${xchg} arch_${xchg}
1819257959aSMark Rutland#else
1829257959aSMark Rutland#define raw_${xchg}(...) \\
1839257959aSMark Rutland	__atomic_op_fence(arch_${xchg}, __VA_ARGS__)
184ace9bad4SMark Rutland#endif
185ace9bad4SMark Rutland
18629f006fdSPeter ZijlstraEOF
18729f006fdSPeter Zijlstra}
18829f006fdSPeter Zijlstra
1899257959aSMark Rutlandgen_xchg_order_fallback()
1909257959aSMark Rutland{
1919257959aSMark Rutland	local xchg="$1"; shift
1929257959aSMark Rutland	local order="$1"; shift
1939257959aSMark Rutland	local forder="${order:-_fence}"
1949257959aSMark Rutland
1959257959aSMark Rutland	printf "#if defined(arch_${xchg}${order})\n"
1969257959aSMark Rutland	printf "#define raw_${xchg}${order} arch_${xchg}${order}\n"
1979257959aSMark Rutland
1989257959aSMark Rutland	if [ "${order}" != "_relaxed" ]; then
1999257959aSMark Rutland		printf "#elif defined(arch_${xchg}_relaxed)\n"
2009257959aSMark Rutland		printf "#define raw_${xchg}${order}(...) \\\\\n"
2019257959aSMark Rutland		printf "	__atomic_op${forder}(arch_${xchg}, __VA_ARGS__)\n"
2029257959aSMark Rutland	fi
2039257959aSMark Rutland
2049257959aSMark Rutland	if [ ! -z "${order}" ]; then
2059257959aSMark Rutland		printf "#elif defined(arch_${xchg})\n"
2069257959aSMark Rutland		printf "#define raw_${xchg}${order} arch_${xchg}\n"
2079257959aSMark Rutland	fi
2089257959aSMark Rutland
2099257959aSMark Rutland	printf "#else\n"
2109257959aSMark Rutland	printf "extern void raw_${xchg}${order}_not_implemented(void);\n"
2119257959aSMark Rutland	printf "#define raw_${xchg}${order}(...) raw_${xchg}${order}_not_implemented()\n"
2129257959aSMark Rutland	printf "#endif\n\n"
2139257959aSMark Rutland}
2149257959aSMark Rutland
21529f006fdSPeter Zijlstragen_xchg_fallbacks()
21629f006fdSPeter Zijlstra{
21729f006fdSPeter Zijlstra	local xchg="$1"; shift
21829f006fdSPeter Zijlstra
2199257959aSMark Rutland	for order in "" "_acquire" "_release" "_relaxed"; do
2209257959aSMark Rutland		gen_xchg_order_fallback "${xchg}" "${order}"
2219257959aSMark Rutland	done
22229f006fdSPeter Zijlstra}
22329f006fdSPeter Zijlstra
22429f006fdSPeter Zijlstragen_try_cmpxchg_fallback()
22529f006fdSPeter Zijlstra{
226*e01cc1e8SUros Bizjak	local prefix="$1"; shift
2270aa7be05SUros Bizjak	local cmpxchg="$1"; shift;
228*e01cc1e8SUros Bizjak	local suffix="$1"; shift;
22929f006fdSPeter Zijlstra
23029f006fdSPeter Zijlstracat <<EOF
231*e01cc1e8SUros Bizjak#define raw_${prefix}try_${cmpxchg}${suffix}(_ptr, _oldp, _new) \\
23229f006fdSPeter Zijlstra({ \\
23329f006fdSPeter Zijlstra	typeof(*(_ptr)) *___op = (_oldp), ___o = *___op, ___r; \\
234*e01cc1e8SUros Bizjak	___r = raw_${prefix}${cmpxchg}${suffix}((_ptr), ___o, (_new)); \\
23529f006fdSPeter Zijlstra	if (unlikely(___r != ___o)) \\
23629f006fdSPeter Zijlstra		*___op = ___r; \\
23729f006fdSPeter Zijlstra	likely(___r == ___o); \\
23829f006fdSPeter Zijlstra})
239ace9bad4SMark RutlandEOF
240ace9bad4SMark Rutland}
241ace9bad4SMark Rutland
2429257959aSMark Rutlandgen_try_cmpxchg_order_fallback()
2439257959aSMark Rutland{
2449257959aSMark Rutland	local cmpxchg="$1"; shift
2459257959aSMark Rutland	local order="$1"; shift
2469257959aSMark Rutland	local forder="${order:-_fence}"
2479257959aSMark Rutland
2489257959aSMark Rutland	printf "#if defined(arch_try_${cmpxchg}${order})\n"
2499257959aSMark Rutland	printf "#define raw_try_${cmpxchg}${order} arch_try_${cmpxchg}${order}\n"
2509257959aSMark Rutland
2519257959aSMark Rutland	if [ "${order}" != "_relaxed" ]; then
2529257959aSMark Rutland		printf "#elif defined(arch_try_${cmpxchg}_relaxed)\n"
2539257959aSMark Rutland		printf "#define raw_try_${cmpxchg}${order}(...) \\\\\n"
2549257959aSMark Rutland		printf "	__atomic_op${forder}(arch_try_${cmpxchg}, __VA_ARGS__)\n"
2559257959aSMark Rutland	fi
2569257959aSMark Rutland
2579257959aSMark Rutland	if [ ! -z "${order}" ]; then
2589257959aSMark Rutland		printf "#elif defined(arch_try_${cmpxchg})\n"
2599257959aSMark Rutland		printf "#define raw_try_${cmpxchg}${order} arch_try_${cmpxchg}\n"
2609257959aSMark Rutland	fi
2619257959aSMark Rutland
2629257959aSMark Rutland	printf "#else\n"
263*e01cc1e8SUros Bizjak	gen_try_cmpxchg_fallback "" "${cmpxchg}" "${order}"
2649257959aSMark Rutland	printf "#endif\n\n"
2659257959aSMark Rutland}
2669257959aSMark Rutland
267*e01cc1e8SUros Bizjakgen_try_cmpxchg_order_fallbacks()
26829f006fdSPeter Zijlstra{
2690aa7be05SUros Bizjak	local cmpxchg="$1"; shift;
27029f006fdSPeter Zijlstra
27129f006fdSPeter Zijlstra	for order in "" "_acquire" "_release" "_relaxed"; do
2729257959aSMark Rutland		gen_try_cmpxchg_order_fallback "${cmpxchg}" "${order}"
27329f006fdSPeter Zijlstra	done
2749257959aSMark Rutland}
27529f006fdSPeter Zijlstra
276*e01cc1e8SUros Bizjakgen_def_and_try_cmpxchg_fallback()
2779257959aSMark Rutland{
278*e01cc1e8SUros Bizjak	local prefix="$1"; shift
2799257959aSMark Rutland	local cmpxchg="$1"; shift
280*e01cc1e8SUros Bizjak	local suffix="$1"; shift
28129f006fdSPeter Zijlstra
282*e01cc1e8SUros Bizjak	printf "#define raw_${prefix}${cmpxchg}${suffix} arch_${prefix}${cmpxchg}${suffix}\n\n"
283*e01cc1e8SUros Bizjak	printf "#ifdef arch_${prefix}try_${cmpxchg}${suffix}\n"
284*e01cc1e8SUros Bizjak	printf "#define raw_${prefix}try_${cmpxchg}${suffix} arch_${prefix}try_${cmpxchg}${suffix}\n"
2859257959aSMark Rutland	printf "#else\n"
286*e01cc1e8SUros Bizjak	gen_try_cmpxchg_fallback "${prefix}" "${cmpxchg}" "${suffix}"
2879257959aSMark Rutland	printf "#endif\n\n"
28829f006fdSPeter Zijlstra}
28929f006fdSPeter Zijlstra
290ace9bad4SMark Rutlandcat << EOF
291ace9bad4SMark Rutland// SPDX-License-Identifier: GPL-2.0
292ace9bad4SMark Rutland
293ace9bad4SMark Rutland// Generated by $0
294ace9bad4SMark Rutland// DO NOT MODIFY THIS FILE DIRECTLY
295ace9bad4SMark Rutland
296ace9bad4SMark Rutland#ifndef _LINUX_ATOMIC_FALLBACK_H
297ace9bad4SMark Rutland#define _LINUX_ATOMIC_FALLBACK_H
298ace9bad4SMark Rutland
299765dcd20SMarco Elver#include <linux/compiler.h>
300765dcd20SMarco Elver
301ace9bad4SMark RutlandEOF
302ace9bad4SMark Rutland
3039257959aSMark Rutlandfor xchg in "xchg" "cmpxchg" "cmpxchg64" "cmpxchg128"; do
304ace9bad4SMark Rutland	gen_xchg_fallbacks "${xchg}"
305ace9bad4SMark Rutlanddone
306ace9bad4SMark Rutland
3078c8b096aSPeter Zijlstrafor cmpxchg in "cmpxchg" "cmpxchg64" "cmpxchg128"; do
308*e01cc1e8SUros Bizjak	gen_try_cmpxchg_order_fallbacks "${cmpxchg}"
3090aa7be05SUros Bizjakdone
31029f006fdSPeter Zijlstra
311*e01cc1e8SUros Bizjakfor cmpxchg in "cmpxchg" "cmpxchg64" "cmpxchg128"; do
312*e01cc1e8SUros Bizjak	gen_def_and_try_cmpxchg_fallback "" "${cmpxchg}" "_local"
3139257959aSMark Rutlanddone
3149257959aSMark Rutland
315*e01cc1e8SUros Bizjakfor cmpxchg in "cmpxchg"; do
316*e01cc1e8SUros Bizjak	gen_def_and_try_cmpxchg_fallback "sync_" "${cmpxchg}" ""
317e6ce9d74SUros Bizjakdone
318e6ce9d74SUros Bizjak
319ace9bad4SMark Rutlandgrep '^[a-z]' "$1" | while read name meta args; do
320f3e615b4SMark Rutland	gen_proto "${meta}" "${name}" "atomic" "int" ${args}
321ace9bad4SMark Rutlanddone
322ace9bad4SMark Rutland
323ace9bad4SMark Rutlandcat <<EOF
324ace9bad4SMark Rutland#ifdef CONFIG_GENERIC_ATOMIC64
325ace9bad4SMark Rutland#include <asm-generic/atomic64.h>
326ace9bad4SMark Rutland#endif
327ace9bad4SMark Rutland
328ace9bad4SMark RutlandEOF
329ace9bad4SMark Rutland
330ace9bad4SMark Rutlandgrep '^[a-z]' "$1" | while read name meta args; do
331f3e615b4SMark Rutland	gen_proto "${meta}" "${name}" "atomic64" "s64" ${args}
332ace9bad4SMark Rutlanddone
333ace9bad4SMark Rutland
334ace9bad4SMark Rutlandcat <<EOF
335ace9bad4SMark Rutland#endif /* _LINUX_ATOMIC_FALLBACK_H */
336ace9bad4SMark RutlandEOF
337