| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336 |
- #!/bin/sh
- # SPDX-License-Identifier: GPL-2.0
- ATOMICDIR=$(dirname $0)
- . ${ATOMICDIR}/atomic-tbl.sh
- #gen_template_fallback(template, meta, pfx, name, sfx, order, atomic, int, args...)
- gen_template_fallback()
- {
- local template="$1"; shift
- local meta="$1"; shift
- local pfx="$1"; shift
- local name="$1"; shift
- local sfx="$1"; shift
- local order="$1"; shift
- local atomic="$1"; shift
- local int="$1"; shift
- local ret="$(gen_ret_type "${meta}" "${int}")"
- local retstmt="$(gen_ret_stmt "${meta}")"
- local params="$(gen_params "${int}" "${atomic}" "$@")"
- local args="$(gen_args "$@")"
- . ${template}
- }
- #gen_order_fallback(meta, pfx, name, sfx, order, atomic, int, args...)
- gen_order_fallback()
- {
- local meta="$1"; shift
- local pfx="$1"; shift
- local name="$1"; shift
- local sfx="$1"; shift
- local order="$1"; shift
- local tmpl_order=${order#_}
- local tmpl="${ATOMICDIR}/fallbacks/${tmpl_order:-fence}"
- gen_template_fallback "${tmpl}" "${meta}" "${pfx}" "${name}" "${sfx}" "${order}" "$@"
- }
- #gen_proto_fallback(meta, pfx, name, sfx, order, atomic, int, args...)
- gen_proto_fallback()
- {
- local meta="$1"; shift
- local pfx="$1"; shift
- local name="$1"; shift
- local sfx="$1"; shift
- local order="$1"; shift
- local tmpl="$(find_fallback_template "${pfx}" "${name}" "${sfx}" "${order}")"
- gen_template_fallback "${tmpl}" "${meta}" "${pfx}" "${name}" "${sfx}" "${order}" "$@"
- }
- #gen_proto_order_variant(meta, pfx, name, sfx, order, atomic, int, args...)
- gen_proto_order_variant()
- {
- local meta="$1"; shift
- local pfx="$1"; shift
- local name="$1"; shift
- local sfx="$1"; shift
- local order="$1"; shift
- local atomic="$1"; shift
- local int="$1"; shift
- local atomicname="${atomic}_${pfx}${name}${sfx}${order}"
- local basename="${atomic}_${pfx}${name}${sfx}"
- local template="$(find_fallback_template "${pfx}" "${name}" "${sfx}" "${order}")"
- local ret="$(gen_ret_type "${meta}" "${int}")"
- local retstmt="$(gen_ret_stmt "${meta}")"
- local params="$(gen_params "${int}" "${atomic}" "$@")"
- local args="$(gen_args "$@")"
- gen_kerneldoc "raw_" "${meta}" "${pfx}" "${name}" "${sfx}" "${order}" "${atomic}" "${int}" "$@"
- printf "static __always_inline ${ret}\n"
- printf "raw_${atomicname}(${params})\n"
- printf "{\n"
- # Where there is no possible fallback, this order variant is mandatory
- # and must be provided by arch code. Add a comment to the header to
- # make this obvious.
- #
- # Ideally we'd error on a missing definition, but arch code might
- # define this order variant as a C function without a preprocessor
- # symbol.
- if [ -z ${template} ] && [ -z "${order}" ] && ! meta_has_relaxed "${meta}"; then
- printf "\t${retstmt}arch_${atomicname}(${args});\n"
- printf "}\n\n"
- return
- fi
- printf "#if defined(arch_${atomicname})\n"
- printf "\t${retstmt}arch_${atomicname}(${args});\n"
- # Allow FULL/ACQUIRE/RELEASE ops to be defined in terms of RELAXED ops
- if [ "${order}" != "_relaxed" ] && meta_has_relaxed "${meta}"; then
- printf "#elif defined(arch_${basename}_relaxed)\n"
- gen_order_fallback "${meta}" "${pfx}" "${name}" "${sfx}" "${order}" "${atomic}" "${int}" "$@"
- fi
- # Allow ACQUIRE/RELEASE/RELAXED ops to be defined in terms of FULL ops
- if [ ! -z "${order}" ] && ! meta_is_implicitly_relaxed "${meta}"; then
- printf "#elif defined(arch_${basename})\n"
- printf "\t${retstmt}arch_${basename}(${args});\n"
- fi
- printf "#else\n"
- if [ ! -z "${template}" ]; then
- gen_proto_fallback "${meta}" "${pfx}" "${name}" "${sfx}" "${order}" "${atomic}" "${int}" "$@"
- else
- printf "#error \"Unable to define raw_${atomicname}\"\n"
- fi
- printf "#endif\n"
- printf "}\n\n"
- }
- #gen_proto_order_variants(meta, pfx, name, sfx, atomic, int, args...)
- gen_proto_order_variants()
- {
- local meta="$1"; shift
- local pfx="$1"; shift
- local name="$1"; shift
- local sfx="$1"; shift
- local atomic="$1"
- gen_proto_order_variant "${meta}" "${pfx}" "${name}" "${sfx}" "" "$@"
- if meta_has_acquire "${meta}"; then
- gen_proto_order_variant "${meta}" "${pfx}" "${name}" "${sfx}" "_acquire" "$@"
- fi
- if meta_has_release "${meta}"; then
- gen_proto_order_variant "${meta}" "${pfx}" "${name}" "${sfx}" "_release" "$@"
- fi
- if meta_has_relaxed "${meta}"; then
- gen_proto_order_variant "${meta}" "${pfx}" "${name}" "${sfx}" "_relaxed" "$@"
- fi
- }
- #gen_basic_fallbacks(basename)
- gen_basic_fallbacks()
- {
- local basename="$1"; shift
- cat << EOF
- #define raw_${basename}_acquire arch_${basename}
- #define raw_${basename}_release arch_${basename}
- #define raw_${basename}_relaxed arch_${basename}
- EOF
- }
- gen_order_fallbacks()
- {
- local xchg="$1"; shift
- cat <<EOF
- #define raw_${xchg}_relaxed arch_${xchg}_relaxed
- #ifdef arch_${xchg}_acquire
- #define raw_${xchg}_acquire arch_${xchg}_acquire
- #else
- #define raw_${xchg}_acquire(...) \\
- __atomic_op_acquire(arch_${xchg}, __VA_ARGS__)
- #endif
- #ifdef arch_${xchg}_release
- #define raw_${xchg}_release arch_${xchg}_release
- #else
- #define raw_${xchg}_release(...) \\
- __atomic_op_release(arch_${xchg}, __VA_ARGS__)
- #endif
- #ifdef arch_${xchg}
- #define raw_${xchg} arch_${xchg}
- #else
- #define raw_${xchg}(...) \\
- __atomic_op_fence(arch_${xchg}, __VA_ARGS__)
- #endif
- EOF
- }
- gen_xchg_order_fallback()
- {
- local xchg="$1"; shift
- local order="$1"; shift
- local forder="${order:-_fence}"
- printf "#if defined(arch_${xchg}${order})\n"
- printf "#define raw_${xchg}${order} arch_${xchg}${order}\n"
- if [ "${order}" != "_relaxed" ]; then
- printf "#elif defined(arch_${xchg}_relaxed)\n"
- printf "#define raw_${xchg}${order}(...) \\\\\n"
- printf " __atomic_op${forder}(arch_${xchg}, __VA_ARGS__)\n"
- fi
- if [ ! -z "${order}" ]; then
- printf "#elif defined(arch_${xchg})\n"
- printf "#define raw_${xchg}${order} arch_${xchg}\n"
- fi
- printf "#else\n"
- printf "extern void raw_${xchg}${order}_not_implemented(void);\n"
- printf "#define raw_${xchg}${order}(...) raw_${xchg}${order}_not_implemented()\n"
- printf "#endif\n\n"
- }
- gen_xchg_fallbacks()
- {
- local xchg="$1"; shift
- for order in "" "_acquire" "_release" "_relaxed"; do
- gen_xchg_order_fallback "${xchg}" "${order}"
- done
- }
- gen_try_cmpxchg_fallback()
- {
- local prefix="$1"; shift
- local cmpxchg="$1"; shift;
- local suffix="$1"; shift;
- cat <<EOF
- #define raw_${prefix}try_${cmpxchg}${suffix}(_ptr, _oldp, _new) \\
- ({ \\
- typeof(*(_ptr)) *___op = (_oldp), ___o = *___op, ___r; \\
- ___r = raw_${prefix}${cmpxchg}${suffix}((_ptr), ___o, (_new)); \\
- if (unlikely(___r != ___o)) \\
- *___op = ___r; \\
- likely(___r == ___o); \\
- })
- EOF
- }
- gen_try_cmpxchg_order_fallback()
- {
- local cmpxchg="$1"; shift
- local order="$1"; shift
- local forder="${order:-_fence}"
- printf "#if defined(arch_try_${cmpxchg}${order})\n"
- printf "#define raw_try_${cmpxchg}${order} arch_try_${cmpxchg}${order}\n"
- if [ "${order}" != "_relaxed" ]; then
- printf "#elif defined(arch_try_${cmpxchg}_relaxed)\n"
- printf "#define raw_try_${cmpxchg}${order}(...) \\\\\n"
- printf " __atomic_op${forder}(arch_try_${cmpxchg}, __VA_ARGS__)\n"
- fi
- if [ ! -z "${order}" ]; then
- printf "#elif defined(arch_try_${cmpxchg})\n"
- printf "#define raw_try_${cmpxchg}${order} arch_try_${cmpxchg}\n"
- fi
- printf "#else\n"
- gen_try_cmpxchg_fallback "" "${cmpxchg}" "${order}"
- printf "#endif\n\n"
- }
- gen_try_cmpxchg_order_fallbacks()
- {
- local cmpxchg="$1"; shift;
- for order in "" "_acquire" "_release" "_relaxed"; do
- gen_try_cmpxchg_order_fallback "${cmpxchg}" "${order}"
- done
- }
- gen_def_and_try_cmpxchg_fallback()
- {
- local prefix="$1"; shift
- local cmpxchg="$1"; shift
- local suffix="$1"; shift
- printf "#define raw_${prefix}${cmpxchg}${suffix} arch_${prefix}${cmpxchg}${suffix}\n\n"
- printf "#ifdef arch_${prefix}try_${cmpxchg}${suffix}\n"
- printf "#define raw_${prefix}try_${cmpxchg}${suffix} arch_${prefix}try_${cmpxchg}${suffix}\n"
- printf "#else\n"
- gen_try_cmpxchg_fallback "${prefix}" "${cmpxchg}" "${suffix}"
- printf "#endif\n\n"
- }
- cat << EOF
- // SPDX-License-Identifier: GPL-2.0
- // Generated by $0
- // DO NOT MODIFY THIS FILE DIRECTLY
- #ifndef _LINUX_ATOMIC_FALLBACK_H
- #define _LINUX_ATOMIC_FALLBACK_H
- #include <linux/compiler.h>
- EOF
- for xchg in "xchg" "cmpxchg" "cmpxchg64" "cmpxchg128"; do
- gen_xchg_fallbacks "${xchg}"
- done
- for cmpxchg in "cmpxchg" "cmpxchg64" "cmpxchg128"; do
- gen_try_cmpxchg_order_fallbacks "${cmpxchg}"
- done
- for cmpxchg in "cmpxchg" "cmpxchg64" "cmpxchg128"; do
- gen_def_and_try_cmpxchg_fallback "" "${cmpxchg}" "_local"
- done
- for cmpxchg in "cmpxchg"; do
- gen_def_and_try_cmpxchg_fallback "sync_" "${cmpxchg}" ""
- done
- grep '^[a-z]' "$1" | while read name meta args; do
- gen_proto "${meta}" "${name}" "atomic" "int" ${args}
- done
- cat <<EOF
- #ifdef CONFIG_GENERIC_ATOMIC64
- #include <asm-generic/atomic64.h>
- #endif
- EOF
- grep '^[a-z]' "$1" | while read name meta args; do
- gen_proto "${meta}" "${name}" "atomic64" "s64" ${args}
- done
- cat <<EOF
- #endif /* _LINUX_ATOMIC_FALLBACK_H */
- EOF
|