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