OLD | NEW |
| (Empty) |
1 #!/bin/sh | |
2 self=$0 | |
3 | |
4 usage() { | |
5 cat <<EOF >&2 | |
6 Usage: $self [options] FILE | |
7 | |
8 Reads the Run Time CPU Detections definitions from FILE and generates a | |
9 C header file on stdout. | |
10 | |
11 Options: | |
12 --arch=ARCH Architecture to generate defs for (required) | |
13 --disable-EXT Disable support for EXT extensions | |
14 --require-EXT Require support for EXT extensions | |
15 --sym=SYMBOL Unique symbol to use for RTCD initialization function | |
16 --config=FILE File with CONFIG_FOO=yes lines to parse | |
17 EOF | |
18 exit 1 | |
19 } | |
20 | |
21 die() { | |
22 echo "$@" >&2 | |
23 exit 1 | |
24 } | |
25 | |
26 die_argument_required() { | |
27 die "Option $opt requires argument" | |
28 } | |
29 | |
30 for opt; do | |
31 optval="${opt#*=}" | |
32 case "$opt" in | |
33 --arch) die_argument_required;; | |
34 --arch=*) arch=${optval};; | |
35 --disable-*) eval "disable_${opt#--disable-}=true";; | |
36 --require-*) REQUIRES="${REQUIRES}${opt#--require-} ";; | |
37 --sym) die_argument_required;; | |
38 --sym=*) symbol=${optval};; | |
39 --config=*) config_file=${optval};; | |
40 -h|--help) | |
41 usage | |
42 ;; | |
43 -*) | |
44 die "Unrecognized option: ${opt%%=*}" | |
45 ;; | |
46 *) | |
47 defs_file="$defs_file $opt" | |
48 ;; | |
49 esac | |
50 shift | |
51 done | |
52 for f in $defs_file; do [ -f "$f" ] || usage; done | |
53 [ -n "$arch" ] || usage | |
54 | |
55 # Import the configuration | |
56 [ -f "$config_file" ] && eval $(grep CONFIG_ "$config_file") | |
57 | |
58 # | |
59 # Routines for the RTCD DSL to call | |
60 # | |
61 prototype() { | |
62 rtyp="" | |
63 case "$1" in | |
64 unsigned) rtyp="$1 "; shift;; | |
65 esac | |
66 rtyp="${rtyp}$1" | |
67 fn="$2" | |
68 args="$3" | |
69 | |
70 eval "${2}_rtyp='$rtyp'" | |
71 eval "${2}_args='$3'" | |
72 ALL_FUNCS="$ALL_FUNCS $fn" | |
73 specialize $fn c | |
74 } | |
75 | |
76 specialize() { | |
77 fn="$1" | |
78 shift | |
79 for opt in "$@"; do | |
80 eval "${fn}_${opt}=${fn}_${opt}" | |
81 done | |
82 } | |
83 | |
84 require() { | |
85 for fn in $ALL_FUNCS; do | |
86 for opt in "$@"; do | |
87 ofn=$(eval "echo \$${fn}_${opt}") | |
88 [ -z "$ofn" ] && continue | |
89 | |
90 # if we already have a default, then we can disable it, as we know | |
91 # we can do better. | |
92 best=$(eval "echo \$${fn}_default") | |
93 best_ofn=$(eval "echo \$${best}") | |
94 [ -n "$best" ] && [ "$best_ofn" != "$ofn" ] && eval "${best}_link=false" | |
95 eval "${fn}_default=${fn}_${opt}" | |
96 eval "${fn}_${opt}_link=true" | |
97 done | |
98 done | |
99 } | |
100 | |
101 forward_decls() { | |
102 ALL_FORWARD_DECLS="$ALL_FORWARD_DECLS $1" | |
103 } | |
104 | |
105 # | |
106 # Include the user's directives | |
107 # | |
108 for f in $defs_file; do | |
109 . $f | |
110 done | |
111 | |
112 # | |
113 # Process the directives according to the command line | |
114 # | |
115 process_forward_decls() { | |
116 for fn in $ALL_FORWARD_DECLS; do | |
117 eval $fn | |
118 done | |
119 } | |
120 | |
121 determine_indirection() { | |
122 [ "$CONFIG_RUNTIME_CPU_DETECT" = "yes" ] || require $ALL_ARCHS | |
123 for fn in $ALL_FUNCS; do | |
124 n="" | |
125 rtyp="$(eval "echo \$${fn}_rtyp")" | |
126 args="$(eval "echo \"\$${fn}_args\"")" | |
127 dfn="$(eval "echo \$${fn}_default")" | |
128 dfn=$(eval "echo \$${dfn}") | |
129 for opt in "$@"; do | |
130 ofn=$(eval "echo \$${fn}_${opt}") | |
131 [ -z "$ofn" ] && continue | |
132 link=$(eval "echo \$${fn}_${opt}_link") | |
133 [ "$link" = "false" ] && continue | |
134 n="${n}x" | |
135 done | |
136 if [ "$n" = "x" ]; then | |
137 eval "${fn}_indirect=false" | |
138 else | |
139 eval "${fn}_indirect=true" | |
140 fi | |
141 done | |
142 } | |
143 | |
144 declare_function_pointers() { | |
145 for fn in $ALL_FUNCS; do | |
146 rtyp="$(eval "echo \$${fn}_rtyp")" | |
147 args="$(eval "echo \"\$${fn}_args\"")" | |
148 dfn="$(eval "echo \$${fn}_default")" | |
149 dfn=$(eval "echo \$${dfn}") | |
150 for opt in "$@"; do | |
151 ofn=$(eval "echo \$${fn}_${opt}") | |
152 [ -z "$ofn" ] && continue | |
153 echo "$rtyp ${ofn}($args);" | |
154 done | |
155 if [ "$(eval "echo \$${fn}_indirect")" = "false" ]; then | |
156 echo "#define ${fn} ${dfn}" | |
157 else | |
158 echo "RTCD_EXTERN $rtyp (*${fn})($args);" | |
159 fi | |
160 echo | |
161 done | |
162 } | |
163 | |
164 set_function_pointers() { | |
165 for fn in $ALL_FUNCS; do | |
166 n="" | |
167 rtyp="$(eval "echo \$${fn}_rtyp")" | |
168 args="$(eval "echo \"\$${fn}_args\"")" | |
169 dfn="$(eval "echo \$${fn}_default")" | |
170 dfn=$(eval "echo \$${dfn}") | |
171 if $(eval "echo \$${fn}_indirect"); then | |
172 echo " $fn = $dfn;" | |
173 for opt in "$@"; do | |
174 ofn=$(eval "echo \$${fn}_${opt}") | |
175 [ -z "$ofn" ] && continue | |
176 [ "$ofn" = "$dfn" ] && continue; | |
177 link=$(eval "echo \$${fn}_${opt}_link") | |
178 [ "$link" = "false" ] && continue | |
179 cond="$(eval "echo \$have_${opt}")" | |
180 echo " if (${cond}) $fn = $ofn;" | |
181 done | |
182 fi | |
183 echo | |
184 done | |
185 } | |
186 | |
187 filter() { | |
188 filtered="" | |
189 for opt in "$@"; do | |
190 [ -z $(eval "echo \$disable_${opt}") ] && filtered="$filtered $opt" | |
191 done | |
192 echo $filtered | |
193 } | |
194 | |
195 # | |
196 # Helper functions for generating the arch specific RTCD files | |
197 # | |
198 common_top() { | |
199 outfile_basename=$(basename ${symbol:-rtcd}) | |
200 include_guard=$(echo $outfile_basename | tr '[a-z]' '[A-Z]' | \ | |
201 tr -c '[A-Z0-9]' _)H_ | |
202 cat <<EOF | |
203 #ifndef ${include_guard} | |
204 #define ${include_guard} | |
205 | |
206 #ifdef RTCD_C | |
207 #define RTCD_EXTERN | |
208 #else | |
209 #define RTCD_EXTERN extern | |
210 #endif | |
211 | |
212 #ifdef __cplusplus | |
213 extern "C" { | |
214 #endif | |
215 | |
216 $(process_forward_decls) | |
217 | |
218 $(declare_function_pointers c $ALL_ARCHS) | |
219 | |
220 void ${symbol:-rtcd}(void); | |
221 EOF | |
222 } | |
223 | |
224 common_bottom() { | |
225 cat <<EOF | |
226 | |
227 #ifdef __cplusplus | |
228 } // extern "C" | |
229 #endif | |
230 | |
231 #endif | |
232 EOF | |
233 } | |
234 | |
235 x86() { | |
236 determine_indirection c $ALL_ARCHS | |
237 | |
238 # Assign the helper variable for each enabled extension | |
239 for opt in $ALL_ARCHS; do | |
240 uc=$(echo $opt | tr '[a-z]' '[A-Z]') | |
241 eval "have_${opt}=\"flags & HAS_${uc}\"" | |
242 done | |
243 | |
244 cat <<EOF | |
245 $(common_top) | |
246 | |
247 #ifdef RTCD_C | |
248 #include "vpx_ports/x86.h" | |
249 static void setup_rtcd_internal(void) | |
250 { | |
251 int flags = x86_simd_caps(); | |
252 | |
253 (void)flags; | |
254 | |
255 $(set_function_pointers c $ALL_ARCHS) | |
256 } | |
257 #endif | |
258 $(common_bottom) | |
259 EOF | |
260 } | |
261 | |
262 arm() { | |
263 determine_indirection c $ALL_ARCHS | |
264 | |
265 # Assign the helper variable for each enabled extension | |
266 for opt in $ALL_ARCHS; do | |
267 uc=$(echo $opt | tr '[a-z]' '[A-Z]') | |
268 eval "have_${opt}=\"flags & HAS_${uc}\"" | |
269 done | |
270 | |
271 cat <<EOF | |
272 $(common_top) | |
273 #include "vpx_config.h" | |
274 | |
275 #ifdef RTCD_C | |
276 #include "vpx_ports/arm.h" | |
277 static void setup_rtcd_internal(void) | |
278 { | |
279 int flags = arm_cpu_caps(); | |
280 | |
281 (void)flags; | |
282 | |
283 $(set_function_pointers c $ALL_ARCHS) | |
284 } | |
285 #endif | |
286 $(common_bottom) | |
287 EOF | |
288 } | |
289 | |
290 | |
291 mips() { | |
292 determine_indirection c $ALL_ARCHS | |
293 cat <<EOF | |
294 $(common_top) | |
295 #include "vpx_config.h" | |
296 | |
297 #ifdef RTCD_C | |
298 static void setup_rtcd_internal(void) | |
299 { | |
300 $(set_function_pointers c $ALL_ARCHS) | |
301 #if HAVE_DSPR2 | |
302 #if CONFIG_VP8 | |
303 void dsputil_static_init(); | |
304 dsputil_static_init(); | |
305 #endif | |
306 #if CONFIG_VP9 | |
307 void vp9_dsputil_static_init(); | |
308 vp9_dsputil_static_init(); | |
309 #endif | |
310 #endif | |
311 } | |
312 #endif | |
313 $(common_bottom) | |
314 EOF | |
315 } | |
316 | |
317 unoptimized() { | |
318 determine_indirection c | |
319 cat <<EOF | |
320 $(common_top) | |
321 #include "vpx_config.h" | |
322 | |
323 #ifdef RTCD_C | |
324 static void setup_rtcd_internal(void) | |
325 { | |
326 $(set_function_pointers c) | |
327 } | |
328 #endif | |
329 $(common_bottom) | |
330 EOF | |
331 | |
332 } | |
333 # | |
334 # Main Driver | |
335 # | |
336 ALL_FUNCS=$(export LC_ALL=C; echo $ALL_FUNCS | tr ' ' '\n' | sort |tr '\n' ' ') | |
337 require c | |
338 case $arch in | |
339 x86) | |
340 ALL_ARCHS=$(filter mmx sse sse2 sse3 ssse3 sse4_1 avx avx2) | |
341 x86 | |
342 ;; | |
343 x86_64) | |
344 ALL_ARCHS=$(filter mmx sse sse2 sse3 ssse3 sse4_1 avx avx2) | |
345 REQUIRES=${REQUIRES:-mmx sse sse2} | |
346 require $(filter $REQUIRES) | |
347 x86 | |
348 ;; | |
349 mips32) | |
350 ALL_ARCHS=$(filter mips32) | |
351 dspr2=$([ -f "$config_file" ] && eval echo $(grep HAVE_DSPR2 "$config_file")
) | |
352 HAVE_DSPR2="${dspr2#*=}" | |
353 if [ "$HAVE_DSPR2" = "yes" ]; then | |
354 ALL_ARCHS=$(filter mips32 dspr2) | |
355 fi | |
356 mips | |
357 ;; | |
358 armv5te) | |
359 ALL_ARCHS=$(filter edsp) | |
360 arm | |
361 ;; | |
362 armv6) | |
363 ALL_ARCHS=$(filter edsp media) | |
364 arm | |
365 ;; | |
366 armv7) | |
367 ALL_ARCHS=$(filter edsp media neon) | |
368 arm | |
369 ;; | |
370 *) | |
371 unoptimized | |
372 ;; | |
373 esac | |
OLD | NEW |