Merge tag 's390-6.10-7' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
[linux-block.git] / scripts / atomic / atomic-tbl.sh
1 #!/bin/sh
2 # SPDX-License-Identifier: GPL-2.0
3 # helpers for dealing with atomics.tbl
4
5 #meta_in(meta, match)
6 meta_in()
7 {
8         case "$1" in
9         [$2]) return 0;;
10         esac
11
12         return 1
13 }
14
15 #meta_has_ret(meta)
16 meta_has_ret()
17 {
18         meta_in "$1" "bBiIfFlR"
19 }
20
21 #meta_has_acquire(meta)
22 meta_has_acquire()
23 {
24         meta_in "$1" "BFIlR"
25 }
26
27 #meta_has_release(meta)
28 meta_has_release()
29 {
30         meta_in "$1" "BFIRs"
31 }
32
33 #meta_has_relaxed(meta)
34 meta_has_relaxed()
35 {
36         meta_in "$1" "BFIR"
37 }
38
39 #meta_is_implicitly_relaxed(meta)
40 meta_is_implicitly_relaxed()
41 {
42         meta_in "$1" "vls"
43 }
44
45 #find_template(tmpltype, pfx, name, sfx, order)
46 find_template()
47 {
48         local tmpltype="$1"; shift
49         local pfx="$1"; shift
50         local name="$1"; shift
51         local sfx="$1"; shift
52         local order="$1"; shift
53
54         local base=""
55         local file=""
56
57         # We may have fallbacks for a specific case (e.g. read_acquire()), or
58         # an entire class, e.g. *inc*().
59         #
60         # Start at the most specific, and fall back to the most general. Once
61         # we find a specific fallback, don't bother looking for more.
62         for base in "${pfx}${name}${sfx}${order}" "${pfx}${name}${sfx}" "${name}"; do
63                 file="${ATOMICDIR}/${tmpltype}/${base}"
64
65                 if [ -f "${file}" ]; then
66                         printf "${file}"
67                         break
68                 fi
69         done
70 }
71
72 #find_fallback_template(pfx, name, sfx, order)
73 find_fallback_template()
74 {
75         find_template "fallbacks" "$@"
76 }
77
78 #find_kerneldoc_template(pfx, name, sfx, order)
79 find_kerneldoc_template()
80 {
81         find_template "kerneldoc" "$@"
82 }
83
84 #gen_ret_type(meta, int)
85 gen_ret_type() {
86         local meta="$1"; shift
87         local int="$1"; shift
88
89         case "${meta}" in
90         [sv]) printf "void";;
91         [bB]) printf "bool";;
92         [aiIfFlR]) printf "${int}";;
93         esac
94 }
95
96 #gen_ret_stmt(meta)
97 gen_ret_stmt()
98 {
99         if meta_has_ret "${meta}"; then
100                 printf "return ";
101         fi
102 }
103
104 # gen_param_name(arg)
105 gen_param_name()
106 {
107         # strip off the leading 'c' for 'cv'
108         local name="${1#c}"
109         printf "${name#*:}"
110 }
111
112 # gen_param_type(arg, int, atomic)
113 gen_param_type()
114 {
115         local type="${1%%:*}"; shift
116         local int="$1"; shift
117         local atomic="$1"; shift
118
119         case "${type}" in
120         i) type="${int} ";;
121         p) type="${int} *";;
122         v) type="${atomic}_t *";;
123         cv) type="const ${atomic}_t *";;
124         esac
125
126         printf "${type}"
127 }
128
129 #gen_param(arg, int, atomic)
130 gen_param()
131 {
132         local arg="$1"; shift
133         local int="$1"; shift
134         local atomic="$1"; shift
135         local name="$(gen_param_name "${arg}")"
136         local type="$(gen_param_type "${arg}" "${int}" "${atomic}")"
137
138         printf "${type}${name}"
139 }
140
141 #gen_params(int, atomic, arg...)
142 gen_params()
143 {
144         local int="$1"; shift
145         local atomic="$1"; shift
146
147         while [ "$#" -gt 0 ]; do
148                 gen_param "$1" "${int}" "${atomic}"
149                 [ "$#" -gt 1 ] && printf ", "
150                 shift;
151         done
152 }
153
154 #gen_args(arg...)
155 gen_args()
156 {
157         while [ "$#" -gt 0 ]; do
158                 printf "$(gen_param_name "$1")"
159                 [ "$#" -gt 1 ] && printf ", "
160                 shift;
161         done
162 }
163
164 #gen_desc_return(meta)
165 gen_desc_return()
166 {
167         local meta="$1"; shift
168
169         case "${meta}" in
170         [v])
171                 printf "Return: Nothing."
172                 ;;
173         [Ff])
174                 printf "Return: The original value of @v."
175                 ;;
176         [R])
177                 printf "Return: The updated value of @v."
178                 ;;
179         [l])
180                 printf "Return: The value of @v."
181                 ;;
182         esac
183 }
184
185 #gen_template_kerneldoc(template, class, meta, pfx, name, sfx, order, atomic, int, args...)
186 gen_template_kerneldoc()
187 {
188         local template="$1"; shift
189         local class="$1"; shift
190         local meta="$1"; shift
191         local pfx="$1"; shift
192         local name="$1"; shift
193         local sfx="$1"; shift
194         local order="$1"; shift
195         local atomic="$1"; shift
196         local int="$1"; shift
197
198         local atomicname="${atomic}_${pfx}${name}${sfx}${order}"
199
200         local ret="$(gen_ret_type "${meta}" "${int}")"
201         local retstmt="$(gen_ret_stmt "${meta}")"
202         local params="$(gen_params "${int}" "${atomic}" "$@")"
203         local args="$(gen_args "$@")"
204         local desc_order=""
205         local desc_instrumentation=""
206         local desc_return=""
207
208         if [ ! -z "${order}" ]; then
209                 desc_order="${order##_}"
210         elif meta_is_implicitly_relaxed "${meta}"; then
211                 desc_order="relaxed"
212         else
213                 desc_order="full"
214         fi
215
216         if [ -z "${class}" ]; then
217                 desc_noinstr="Unsafe to use in noinstr code; use raw_${atomicname}() there."
218         else
219                 desc_noinstr="Safe to use in noinstr code; prefer ${atomicname}() elsewhere."
220         fi
221
222         desc_return="$(gen_desc_return "${meta}")"
223
224         . ${template}
225 }
226
227 #gen_kerneldoc(class, meta, pfx, name, sfx, order, atomic, int, args...)
228 gen_kerneldoc()
229 {
230         local class="$1"; shift
231         local meta="$1"; shift
232         local pfx="$1"; shift
233         local name="$1"; shift
234         local sfx="$1"; shift
235         local order="$1"; shift
236
237         local atomicname="${atomic}_${pfx}${name}${sfx}${order}"
238
239         local tmpl="$(find_kerneldoc_template "${pfx}" "${name}" "${sfx}" "${order}")"
240         if [ -z "${tmpl}" ]; then
241                 printf "/*\n"
242                 printf " * No kerneldoc available for ${class}${atomicname}\n"
243                 printf " */\n"
244         else
245         gen_template_kerneldoc "${tmpl}" "${class}" "${meta}" "${pfx}" "${name}" "${sfx}" "${order}" "$@"
246         fi
247 }
248
249 #gen_proto_order_variants(meta, pfx, name, sfx, ...)
250 gen_proto_order_variants()
251 {
252         local meta="$1"; shift
253         local pfx="$1"; shift
254         local name="$1"; shift
255         local sfx="$1"; shift
256
257         gen_proto_order_variant "${meta}" "${pfx}" "${name}" "${sfx}" "" "$@"
258
259         if meta_has_acquire "${meta}"; then
260                 gen_proto_order_variant "${meta}" "${pfx}" "${name}" "${sfx}" "_acquire" "$@"
261         fi
262         if meta_has_release "${meta}"; then
263                 gen_proto_order_variant "${meta}" "${pfx}" "${name}" "${sfx}" "_release" "$@"
264         fi
265         if meta_has_relaxed "${meta}"; then
266                 gen_proto_order_variant "${meta}" "${pfx}" "${name}" "${sfx}" "_relaxed" "$@"
267         fi
268 }
269
270 #gen_proto_variants(meta, name, ...)
271 gen_proto_variants()
272 {
273         local meta="$1"; shift
274         local name="$1"; shift
275         local pfx=""
276         local sfx=""
277
278         meta_in "${meta}" "fF" && pfx="fetch_"
279         meta_in "${meta}" "R" && sfx="_return"
280
281         gen_proto_order_variants "${meta}" "${pfx}" "${name}" "${sfx}" "$@"
282 }
283
284 #gen_proto(meta, ...)
285 gen_proto() {
286         local meta="$1"; shift
287         for m in $(echo "${meta}" | grep -o .); do
288                 gen_proto_variants "${m}" "$@"
289         done
290 }