162306a36Sopenharmony_ci#!/bin/sh 262306a36Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0 362306a36Sopenharmony_ci 462306a36Sopenharmony_ciATOMICDIR=$(dirname $0) 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci. ${ATOMICDIR}/atomic-tbl.sh 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#gen_template_fallback(template, meta, pfx, name, sfx, order, atomic, int, args...) 962306a36Sopenharmony_cigen_template_fallback() 1062306a36Sopenharmony_ci{ 1162306a36Sopenharmony_ci local template="$1"; shift 1262306a36Sopenharmony_ci local meta="$1"; shift 1362306a36Sopenharmony_ci local pfx="$1"; shift 1462306a36Sopenharmony_ci local name="$1"; shift 1562306a36Sopenharmony_ci local sfx="$1"; shift 1662306a36Sopenharmony_ci local order="$1"; shift 1762306a36Sopenharmony_ci local atomic="$1"; shift 1862306a36Sopenharmony_ci local int="$1"; shift 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci local ret="$(gen_ret_type "${meta}" "${int}")" 2162306a36Sopenharmony_ci local retstmt="$(gen_ret_stmt "${meta}")" 2262306a36Sopenharmony_ci local params="$(gen_params "${int}" "${atomic}" "$@")" 2362306a36Sopenharmony_ci local args="$(gen_args "$@")" 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci . ${template} 2662306a36Sopenharmony_ci} 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci#gen_order_fallback(meta, pfx, name, sfx, order, atomic, int, args...) 2962306a36Sopenharmony_cigen_order_fallback() 3062306a36Sopenharmony_ci{ 3162306a36Sopenharmony_ci local meta="$1"; shift 3262306a36Sopenharmony_ci local pfx="$1"; shift 3362306a36Sopenharmony_ci local name="$1"; shift 3462306a36Sopenharmony_ci local sfx="$1"; shift 3562306a36Sopenharmony_ci local order="$1"; shift 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci local tmpl_order=${order#_} 3862306a36Sopenharmony_ci local tmpl="${ATOMICDIR}/fallbacks/${tmpl_order:-fence}" 3962306a36Sopenharmony_ci gen_template_fallback "${tmpl}" "${meta}" "${pfx}" "${name}" "${sfx}" "${order}" "$@" 4062306a36Sopenharmony_ci} 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci#gen_proto_fallback(meta, pfx, name, sfx, order, atomic, int, args...) 4362306a36Sopenharmony_cigen_proto_fallback() 4462306a36Sopenharmony_ci{ 4562306a36Sopenharmony_ci local meta="$1"; shift 4662306a36Sopenharmony_ci local pfx="$1"; shift 4762306a36Sopenharmony_ci local name="$1"; shift 4862306a36Sopenharmony_ci local sfx="$1"; shift 4962306a36Sopenharmony_ci local order="$1"; shift 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci local tmpl="$(find_fallback_template "${pfx}" "${name}" "${sfx}" "${order}")" 5262306a36Sopenharmony_ci gen_template_fallback "${tmpl}" "${meta}" "${pfx}" "${name}" "${sfx}" "${order}" "$@" 5362306a36Sopenharmony_ci} 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci#gen_proto_order_variant(meta, pfx, name, sfx, order, atomic, int, args...) 5662306a36Sopenharmony_cigen_proto_order_variant() 5762306a36Sopenharmony_ci{ 5862306a36Sopenharmony_ci local meta="$1"; shift 5962306a36Sopenharmony_ci local pfx="$1"; shift 6062306a36Sopenharmony_ci local name="$1"; shift 6162306a36Sopenharmony_ci local sfx="$1"; shift 6262306a36Sopenharmony_ci local order="$1"; shift 6362306a36Sopenharmony_ci local atomic="$1"; shift 6462306a36Sopenharmony_ci local int="$1"; shift 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci local atomicname="${atomic}_${pfx}${name}${sfx}${order}" 6762306a36Sopenharmony_ci local basename="${atomic}_${pfx}${name}${sfx}" 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci local template="$(find_fallback_template "${pfx}" "${name}" "${sfx}" "${order}")" 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci local ret="$(gen_ret_type "${meta}" "${int}")" 7262306a36Sopenharmony_ci local retstmt="$(gen_ret_stmt "${meta}")" 7362306a36Sopenharmony_ci local params="$(gen_params "${int}" "${atomic}" "$@")" 7462306a36Sopenharmony_ci local args="$(gen_args "$@")" 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci gen_kerneldoc "raw_" "${meta}" "${pfx}" "${name}" "${sfx}" "${order}" "${atomic}" "${int}" "$@" 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci printf "static __always_inline ${ret}\n" 7962306a36Sopenharmony_ci printf "raw_${atomicname}(${params})\n" 8062306a36Sopenharmony_ci printf "{\n" 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci # Where there is no possible fallback, this order variant is mandatory 8362306a36Sopenharmony_ci # and must be provided by arch code. Add a comment to the header to 8462306a36Sopenharmony_ci # make this obvious. 8562306a36Sopenharmony_ci # 8662306a36Sopenharmony_ci # Ideally we'd error on a missing definition, but arch code might 8762306a36Sopenharmony_ci # define this order variant as a C function without a preprocessor 8862306a36Sopenharmony_ci # symbol. 8962306a36Sopenharmony_ci if [ -z ${template} ] && [ -z "${order}" ] && ! meta_has_relaxed "${meta}"; then 9062306a36Sopenharmony_ci printf "\t${retstmt}arch_${atomicname}(${args});\n" 9162306a36Sopenharmony_ci printf "}\n\n" 9262306a36Sopenharmony_ci return 9362306a36Sopenharmony_ci fi 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci printf "#if defined(arch_${atomicname})\n" 9662306a36Sopenharmony_ci printf "\t${retstmt}arch_${atomicname}(${args});\n" 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci # Allow FULL/ACQUIRE/RELEASE ops to be defined in terms of RELAXED ops 9962306a36Sopenharmony_ci if [ "${order}" != "_relaxed" ] && meta_has_relaxed "${meta}"; then 10062306a36Sopenharmony_ci printf "#elif defined(arch_${basename}_relaxed)\n" 10162306a36Sopenharmony_ci gen_order_fallback "${meta}" "${pfx}" "${name}" "${sfx}" "${order}" "${atomic}" "${int}" "$@" 10262306a36Sopenharmony_ci fi 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci # Allow ACQUIRE/RELEASE/RELAXED ops to be defined in terms of FULL ops 10562306a36Sopenharmony_ci if [ ! -z "${order}" ] && ! meta_is_implicitly_relaxed "${meta}"; then 10662306a36Sopenharmony_ci printf "#elif defined(arch_${basename})\n" 10762306a36Sopenharmony_ci printf "\t${retstmt}arch_${basename}(${args});\n" 10862306a36Sopenharmony_ci fi 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci printf "#else\n" 11162306a36Sopenharmony_ci if [ ! -z "${template}" ]; then 11262306a36Sopenharmony_ci gen_proto_fallback "${meta}" "${pfx}" "${name}" "${sfx}" "${order}" "${atomic}" "${int}" "$@" 11362306a36Sopenharmony_ci else 11462306a36Sopenharmony_ci printf "#error \"Unable to define raw_${atomicname}\"\n" 11562306a36Sopenharmony_ci fi 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci printf "#endif\n" 11862306a36Sopenharmony_ci printf "}\n\n" 11962306a36Sopenharmony_ci} 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci#gen_proto_order_variants(meta, pfx, name, sfx, atomic, int, args...) 12362306a36Sopenharmony_cigen_proto_order_variants() 12462306a36Sopenharmony_ci{ 12562306a36Sopenharmony_ci local meta="$1"; shift 12662306a36Sopenharmony_ci local pfx="$1"; shift 12762306a36Sopenharmony_ci local name="$1"; shift 12862306a36Sopenharmony_ci local sfx="$1"; shift 12962306a36Sopenharmony_ci local atomic="$1" 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci gen_proto_order_variant "${meta}" "${pfx}" "${name}" "${sfx}" "" "$@" 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci if meta_has_acquire "${meta}"; then 13462306a36Sopenharmony_ci gen_proto_order_variant "${meta}" "${pfx}" "${name}" "${sfx}" "_acquire" "$@" 13562306a36Sopenharmony_ci fi 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci if meta_has_release "${meta}"; then 13862306a36Sopenharmony_ci gen_proto_order_variant "${meta}" "${pfx}" "${name}" "${sfx}" "_release" "$@" 13962306a36Sopenharmony_ci fi 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci if meta_has_relaxed "${meta}"; then 14262306a36Sopenharmony_ci gen_proto_order_variant "${meta}" "${pfx}" "${name}" "${sfx}" "_relaxed" "$@" 14362306a36Sopenharmony_ci fi 14462306a36Sopenharmony_ci} 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci#gen_basic_fallbacks(basename) 14762306a36Sopenharmony_cigen_basic_fallbacks() 14862306a36Sopenharmony_ci{ 14962306a36Sopenharmony_ci local basename="$1"; shift 15062306a36Sopenharmony_cicat << EOF 15162306a36Sopenharmony_ci#define raw_${basename}_acquire arch_${basename} 15262306a36Sopenharmony_ci#define raw_${basename}_release arch_${basename} 15362306a36Sopenharmony_ci#define raw_${basename}_relaxed arch_${basename} 15462306a36Sopenharmony_ciEOF 15562306a36Sopenharmony_ci} 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_cigen_order_fallbacks() 15862306a36Sopenharmony_ci{ 15962306a36Sopenharmony_ci local xchg="$1"; shift 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_cicat <<EOF 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci#define raw_${xchg}_relaxed arch_${xchg}_relaxed 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci#ifdef arch_${xchg}_acquire 16662306a36Sopenharmony_ci#define raw_${xchg}_acquire arch_${xchg}_acquire 16762306a36Sopenharmony_ci#else 16862306a36Sopenharmony_ci#define raw_${xchg}_acquire(...) \\ 16962306a36Sopenharmony_ci __atomic_op_acquire(arch_${xchg}, __VA_ARGS__) 17062306a36Sopenharmony_ci#endif 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci#ifdef arch_${xchg}_release 17362306a36Sopenharmony_ci#define raw_${xchg}_release arch_${xchg}_release 17462306a36Sopenharmony_ci#else 17562306a36Sopenharmony_ci#define raw_${xchg}_release(...) \\ 17662306a36Sopenharmony_ci __atomic_op_release(arch_${xchg}, __VA_ARGS__) 17762306a36Sopenharmony_ci#endif 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci#ifdef arch_${xchg} 18062306a36Sopenharmony_ci#define raw_${xchg} arch_${xchg} 18162306a36Sopenharmony_ci#else 18262306a36Sopenharmony_ci#define raw_${xchg}(...) \\ 18362306a36Sopenharmony_ci __atomic_op_fence(arch_${xchg}, __VA_ARGS__) 18462306a36Sopenharmony_ci#endif 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ciEOF 18762306a36Sopenharmony_ci} 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_cigen_xchg_order_fallback() 19062306a36Sopenharmony_ci{ 19162306a36Sopenharmony_ci local xchg="$1"; shift 19262306a36Sopenharmony_ci local order="$1"; shift 19362306a36Sopenharmony_ci local forder="${order:-_fence}" 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ci printf "#if defined(arch_${xchg}${order})\n" 19662306a36Sopenharmony_ci printf "#define raw_${xchg}${order} arch_${xchg}${order}\n" 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci if [ "${order}" != "_relaxed" ]; then 19962306a36Sopenharmony_ci printf "#elif defined(arch_${xchg}_relaxed)\n" 20062306a36Sopenharmony_ci printf "#define raw_${xchg}${order}(...) \\\\\n" 20162306a36Sopenharmony_ci printf " __atomic_op${forder}(arch_${xchg}, __VA_ARGS__)\n" 20262306a36Sopenharmony_ci fi 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci if [ ! -z "${order}" ]; then 20562306a36Sopenharmony_ci printf "#elif defined(arch_${xchg})\n" 20662306a36Sopenharmony_ci printf "#define raw_${xchg}${order} arch_${xchg}\n" 20762306a36Sopenharmony_ci fi 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci printf "#else\n" 21062306a36Sopenharmony_ci printf "extern void raw_${xchg}${order}_not_implemented(void);\n" 21162306a36Sopenharmony_ci printf "#define raw_${xchg}${order}(...) raw_${xchg}${order}_not_implemented()\n" 21262306a36Sopenharmony_ci printf "#endif\n\n" 21362306a36Sopenharmony_ci} 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_cigen_xchg_fallbacks() 21662306a36Sopenharmony_ci{ 21762306a36Sopenharmony_ci local xchg="$1"; shift 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci for order in "" "_acquire" "_release" "_relaxed"; do 22062306a36Sopenharmony_ci gen_xchg_order_fallback "${xchg}" "${order}" 22162306a36Sopenharmony_ci done 22262306a36Sopenharmony_ci} 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_cigen_try_cmpxchg_fallback() 22562306a36Sopenharmony_ci{ 22662306a36Sopenharmony_ci local cmpxchg="$1"; shift; 22762306a36Sopenharmony_ci local order="$1"; shift; 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_cicat <<EOF 23062306a36Sopenharmony_ci#define raw_try_${cmpxchg}${order}(_ptr, _oldp, _new) \\ 23162306a36Sopenharmony_ci({ \\ 23262306a36Sopenharmony_ci typeof(*(_ptr)) *___op = (_oldp), ___o = *___op, ___r; \\ 23362306a36Sopenharmony_ci ___r = raw_${cmpxchg}${order}((_ptr), ___o, (_new)); \\ 23462306a36Sopenharmony_ci if (unlikely(___r != ___o)) \\ 23562306a36Sopenharmony_ci *___op = ___r; \\ 23662306a36Sopenharmony_ci likely(___r == ___o); \\ 23762306a36Sopenharmony_ci}) 23862306a36Sopenharmony_ciEOF 23962306a36Sopenharmony_ci} 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_cigen_try_cmpxchg_order_fallback() 24262306a36Sopenharmony_ci{ 24362306a36Sopenharmony_ci local cmpxchg="$1"; shift 24462306a36Sopenharmony_ci local order="$1"; shift 24562306a36Sopenharmony_ci local forder="${order:-_fence}" 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_ci printf "#if defined(arch_try_${cmpxchg}${order})\n" 24862306a36Sopenharmony_ci printf "#define raw_try_${cmpxchg}${order} arch_try_${cmpxchg}${order}\n" 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ci if [ "${order}" != "_relaxed" ]; then 25162306a36Sopenharmony_ci printf "#elif defined(arch_try_${cmpxchg}_relaxed)\n" 25262306a36Sopenharmony_ci printf "#define raw_try_${cmpxchg}${order}(...) \\\\\n" 25362306a36Sopenharmony_ci printf " __atomic_op${forder}(arch_try_${cmpxchg}, __VA_ARGS__)\n" 25462306a36Sopenharmony_ci fi 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ci if [ ! -z "${order}" ]; then 25762306a36Sopenharmony_ci printf "#elif defined(arch_try_${cmpxchg})\n" 25862306a36Sopenharmony_ci printf "#define raw_try_${cmpxchg}${order} arch_try_${cmpxchg}\n" 25962306a36Sopenharmony_ci fi 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_ci printf "#else\n" 26262306a36Sopenharmony_ci gen_try_cmpxchg_fallback "${cmpxchg}" "${order}" 26362306a36Sopenharmony_ci printf "#endif\n\n" 26462306a36Sopenharmony_ci} 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_cigen_try_cmpxchg_fallbacks() 26762306a36Sopenharmony_ci{ 26862306a36Sopenharmony_ci local cmpxchg="$1"; shift; 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci for order in "" "_acquire" "_release" "_relaxed"; do 27162306a36Sopenharmony_ci gen_try_cmpxchg_order_fallback "${cmpxchg}" "${order}" 27262306a36Sopenharmony_ci done 27362306a36Sopenharmony_ci} 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_cigen_cmpxchg_local_fallbacks() 27662306a36Sopenharmony_ci{ 27762306a36Sopenharmony_ci local cmpxchg="$1"; shift 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci printf "#define raw_${cmpxchg} arch_${cmpxchg}\n\n" 28062306a36Sopenharmony_ci printf "#ifdef arch_try_${cmpxchg}\n" 28162306a36Sopenharmony_ci printf "#define raw_try_${cmpxchg} arch_try_${cmpxchg}\n" 28262306a36Sopenharmony_ci printf "#else\n" 28362306a36Sopenharmony_ci gen_try_cmpxchg_fallback "${cmpxchg}" "" 28462306a36Sopenharmony_ci printf "#endif\n\n" 28562306a36Sopenharmony_ci} 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_cicat << EOF 28862306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28962306a36Sopenharmony_ci 29062306a36Sopenharmony_ci// Generated by $0 29162306a36Sopenharmony_ci// DO NOT MODIFY THIS FILE DIRECTLY 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ci#ifndef _LINUX_ATOMIC_FALLBACK_H 29462306a36Sopenharmony_ci#define _LINUX_ATOMIC_FALLBACK_H 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_ci#include <linux/compiler.h> 29762306a36Sopenharmony_ci 29862306a36Sopenharmony_ciEOF 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_cifor xchg in "xchg" "cmpxchg" "cmpxchg64" "cmpxchg128"; do 30162306a36Sopenharmony_ci gen_xchg_fallbacks "${xchg}" 30262306a36Sopenharmony_cidone 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_cifor cmpxchg in "cmpxchg" "cmpxchg64" "cmpxchg128"; do 30562306a36Sopenharmony_ci gen_try_cmpxchg_fallbacks "${cmpxchg}" 30662306a36Sopenharmony_cidone 30762306a36Sopenharmony_ci 30862306a36Sopenharmony_cifor cmpxchg in "cmpxchg_local" "cmpxchg64_local" "cmpxchg128_local"; do 30962306a36Sopenharmony_ci gen_cmpxchg_local_fallbacks "${cmpxchg}" "" 31062306a36Sopenharmony_cidone 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_cifor cmpxchg in "sync_cmpxchg"; do 31362306a36Sopenharmony_ci printf "#define raw_${cmpxchg} arch_${cmpxchg}\n\n" 31462306a36Sopenharmony_cidone 31562306a36Sopenharmony_ci 31662306a36Sopenharmony_cigrep '^[a-z]' "$1" | while read name meta args; do 31762306a36Sopenharmony_ci gen_proto "${meta}" "${name}" "atomic" "int" ${args} 31862306a36Sopenharmony_cidone 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_cicat <<EOF 32162306a36Sopenharmony_ci#ifdef CONFIG_GENERIC_ATOMIC64 32262306a36Sopenharmony_ci#include <asm-generic/atomic64.h> 32362306a36Sopenharmony_ci#endif 32462306a36Sopenharmony_ci 32562306a36Sopenharmony_ciEOF 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_cigrep '^[a-z]' "$1" | while read name meta args; do 32862306a36Sopenharmony_ci gen_proto "${meta}" "${name}" "atomic64" "s64" ${args} 32962306a36Sopenharmony_cidone 33062306a36Sopenharmony_ci 33162306a36Sopenharmony_cicat <<EOF 33262306a36Sopenharmony_ci#endif /* _LINUX_ATOMIC_FALLBACK_H */ 33362306a36Sopenharmony_ciEOF 334