1#!/bin/sh 2# SPDX-License-Identifier: GPL-2.0 3 4ATOMICDIR=$(dirname $0) 5 6. ${ATOMICDIR}/atomic-tbl.sh 7 8#gen_template_fallback(template, meta, pfx, name, sfx, order, atomic, int, args...) 9gen_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 20 local atomicname="arch_${atomic}_${pfx}${name}${sfx}${order}" 21 22 local ret="$(gen_ret_type "${meta}" "${int}")" 23 local retstmt="$(gen_ret_stmt "${meta}")" 24 local params="$(gen_params "${int}" "${atomic}" "$@")" 25 local args="$(gen_args "$@")" 26 27 if [ ! -z "${template}" ]; then 28 printf "#ifndef ${atomicname}\n" 29 . ${template} 30 printf "#define ${atomicname} ${atomicname}\n" 31 printf "#endif\n\n" 32 fi 33} 34 35#gen_proto_fallback(meta, pfx, name, sfx, order, atomic, int, args...) 36gen_proto_fallback() 37{ 38 local meta="$1"; shift 39 local pfx="$1"; shift 40 local name="$1"; shift 41 local sfx="$1"; shift 42 local order="$1"; shift 43 44 local tmpl="$(find_fallback_template "${pfx}" "${name}" "${sfx}" "${order}")" 45 gen_template_fallback "${tmpl}" "${meta}" "${pfx}" "${name}" "${sfx}" "${order}" "$@" 46} 47 48#gen_basic_fallbacks(basename) 49gen_basic_fallbacks() 50{ 51 local basename="$1"; shift 52cat << EOF 53#define ${basename}_acquire ${basename} 54#define ${basename}_release ${basename} 55#define ${basename}_relaxed ${basename} 56EOF 57} 58 59gen_proto_order_variant() 60{ 61 local meta="$1"; shift 62 local pfx="$1"; shift 63 local name="$1"; shift 64 local sfx="$1"; shift 65 local order="$1"; shift 66 local atomic="$1" 67 68 local basename="arch_${atomic}_${pfx}${name}${sfx}" 69 70 printf "#define ${basename}${order} ${basename}${order}\n" 71} 72 73#gen_proto_order_variants(meta, pfx, name, sfx, atomic, int, args...) 74gen_proto_order_variants() 75{ 76 local meta="$1"; shift 77 local pfx="$1"; shift 78 local name="$1"; shift 79 local sfx="$1"; shift 80 local atomic="$1" 81 82 local basename="arch_${atomic}_${pfx}${name}${sfx}" 83 84 local template="$(find_fallback_template "${pfx}" "${name}" "${sfx}" "${order}")" 85 86 # If we don't have relaxed atomics, then we don't bother with ordering fallbacks 87 # read_acquire and set_release need to be templated, though 88 if ! meta_has_relaxed "${meta}"; then 89 gen_proto_fallback "${meta}" "${pfx}" "${name}" "${sfx}" "" "$@" 90 91 if meta_has_acquire "${meta}"; then 92 gen_proto_fallback "${meta}" "${pfx}" "${name}" "${sfx}" "_acquire" "$@" 93 fi 94 95 if meta_has_release "${meta}"; then 96 gen_proto_fallback "${meta}" "${pfx}" "${name}" "${sfx}" "_release" "$@" 97 fi 98 99 return 100 fi 101 102 printf "#ifndef ${basename}_relaxed\n" 103 104 if [ ! -z "${template}" ]; then 105 printf "#ifdef ${basename}\n" 106 fi 107 108 gen_basic_fallbacks "${basename}" 109 110 if [ ! -z "${template}" ]; then 111 printf "#endif /* ${basename} */\n\n" 112 gen_proto_fallback "${meta}" "${pfx}" "${name}" "${sfx}" "" "$@" 113 gen_proto_fallback "${meta}" "${pfx}" "${name}" "${sfx}" "_acquire" "$@" 114 gen_proto_fallback "${meta}" "${pfx}" "${name}" "${sfx}" "_release" "$@" 115 gen_proto_fallback "${meta}" "${pfx}" "${name}" "${sfx}" "_relaxed" "$@" 116 fi 117 118 printf "#else /* ${basename}_relaxed */\n\n" 119 120 gen_template_fallback "${ATOMICDIR}/fallbacks/acquire" "${meta}" "${pfx}" "${name}" "${sfx}" "_acquire" "$@" 121 gen_template_fallback "${ATOMICDIR}/fallbacks/release" "${meta}" "${pfx}" "${name}" "${sfx}" "_release" "$@" 122 gen_template_fallback "${ATOMICDIR}/fallbacks/fence" "${meta}" "${pfx}" "${name}" "${sfx}" "" "$@" 123 124 printf "#endif /* ${basename}_relaxed */\n\n" 125} 126 127gen_order_fallbacks() 128{ 129 local xchg="$1"; shift 130 131cat <<EOF 132 133#ifndef ${xchg}_acquire 134#define ${xchg}_acquire(...) \\ 135 __atomic_op_acquire(${xchg}, __VA_ARGS__) 136#endif 137 138#ifndef ${xchg}_release 139#define ${xchg}_release(...) \\ 140 __atomic_op_release(${xchg}, __VA_ARGS__) 141#endif 142 143#ifndef ${xchg} 144#define ${xchg}(...) \\ 145 __atomic_op_fence(${xchg}, __VA_ARGS__) 146#endif 147 148EOF 149} 150 151gen_xchg_fallbacks() 152{ 153 local xchg="$1"; shift 154 printf "#ifndef ${xchg}_relaxed\n" 155 156 gen_basic_fallbacks ${xchg} 157 158 printf "#else /* ${xchg}_relaxed */\n" 159 160 gen_order_fallbacks ${xchg} 161 162 printf "#endif /* ${xchg}_relaxed */\n\n" 163} 164 165gen_try_cmpxchg_fallback() 166{ 167 local cmpxchg="$1"; shift; 168 local order="$1"; shift; 169 170cat <<EOF 171#ifndef arch_try_${cmpxchg}${order} 172#define arch_try_${cmpxchg}${order}(_ptr, _oldp, _new) \\ 173({ \\ 174 typeof(*(_ptr)) *___op = (_oldp), ___o = *___op, ___r; \\ 175 ___r = arch_${cmpxchg}${order}((_ptr), ___o, (_new)); \\ 176 if (unlikely(___r != ___o)) \\ 177 *___op = ___r; \\ 178 likely(___r == ___o); \\ 179}) 180#endif /* arch_try_${cmpxchg}${order} */ 181 182EOF 183} 184 185gen_try_cmpxchg_fallbacks() 186{ 187 local cmpxchg="$1"; shift; 188 189 printf "#ifndef arch_try_${cmpxchg}_relaxed\n" 190 printf "#ifdef arch_try_${cmpxchg}\n" 191 192 gen_basic_fallbacks "arch_try_${cmpxchg}" 193 194 printf "#endif /* arch_try_${cmpxchg} */\n\n" 195 196 for order in "" "_acquire" "_release" "_relaxed"; do 197 gen_try_cmpxchg_fallback "${cmpxchg}" "${order}" 198 done 199 200 printf "#else /* arch_try_${cmpxchg}_relaxed */\n" 201 202 gen_order_fallbacks "arch_try_${cmpxchg}" 203 204 printf "#endif /* arch_try_${cmpxchg}_relaxed */\n\n" 205} 206 207cat << EOF 208// SPDX-License-Identifier: GPL-2.0 209 210// Generated by $0 211// DO NOT MODIFY THIS FILE DIRECTLY 212 213#ifndef _LINUX_ATOMIC_FALLBACK_H 214#define _LINUX_ATOMIC_FALLBACK_H 215 216#include <linux/compiler.h> 217 218EOF 219 220for xchg in "arch_xchg" "arch_cmpxchg" "arch_cmpxchg64"; do 221 gen_xchg_fallbacks "${xchg}" 222done 223 224for cmpxchg in "cmpxchg" "cmpxchg64"; do 225 gen_try_cmpxchg_fallbacks "${cmpxchg}" 226done 227 228for cmpxchg in "cmpxchg_local" "cmpxchg64_local"; do 229 gen_try_cmpxchg_fallback "${cmpxchg}" "" 230done 231 232grep '^[a-z]' "$1" | while read name meta args; do 233 gen_proto "${meta}" "${name}" "atomic" "int" ${args} 234done 235 236cat <<EOF 237#ifdef CONFIG_GENERIC_ATOMIC64 238#include <asm-generic/atomic64.h> 239#endif 240 241EOF 242 243grep '^[a-z]' "$1" | while read name meta args; do 244 gen_proto "${meta}" "${name}" "atomic64" "s64" ${args} 245done 246 247cat <<EOF 248#endif /* _LINUX_ATOMIC_FALLBACK_H */ 249EOF 250