6 Getopt::Long::Configure("auto_help") if $Getopt::Long::VERSION > 2.32;
10 my @ALL_FORWARD_DECLS;
19 $disabled{$1} = 1, next if /--disable-(.*)/;
20 $required{$1} = 1, next if /--require-(.*)/;
24 # NB: use GetOptions() instead of GetOptionsFromArray() for compatibility.
33 foreach my $opt (qw/arch config/) {
34 if (!defined($opts{$opt})) {
35 warn "--$opt is required!\n";
36 Getopt::Long::HelpMessage('-exit' => 1);
40 foreach my $defs_file (@ARGV) {
42 warn "$defs_file: $!\n";
43 Getopt::Long::HelpMessage('-exit' => 1);
47 open CONFIG_FILE, $opts{config} or
48 die "Error opening config file '$opts{config}': $!\n";
51 while (<CONFIG_FILE>) {
55 $config{$pair[0]} = $pair[1];
60 # Routines for the RTCD DSL to call
63 return (defined $config{$_[0]}) ? $config{$_[0]} : "";
69 foreach my $opt (@_) {
70 eval "\$${fn}_${opt}=${fn}_${opt}";
75 my $fn = splice(@_, -2, 1);
76 $ALL_FUNCS{$fn} = \@_;
81 foreach my $fn (keys %ALL_FUNCS) {
82 foreach my $opt (@_) {
83 my $ofn = eval "\$${fn}_${opt}";
86 # if we already have a default, then we can disable it, as we know
88 my $best = eval "\$${fn}_default";
90 my $best_ofn = eval "\$${best}";
91 if ($best_ofn && "$best_ofn" ne "$ofn") {
92 eval "\$${best}_link = 'false'";
95 eval "\$${fn}_default=${fn}_${opt}";
96 eval "\$${fn}_${opt}_link='true'";
102 push @ALL_FORWARD_DECLS, @_;
106 # Include the user's directives
108 foreach my $f (@ARGV) {
109 open FILE, "<", $f or die "cannot open $f: $!\n";
110 my $contents = join('', <FILE>);
112 eval $contents or warn "eval failed: $@\n";
116 # Process the directives according to the command line
118 sub process_forward_decls() {
119 foreach (@ALL_FORWARD_DECLS) {
124 sub determine_indirection {
125 vpx_config("CONFIG_RUNTIME_CPU_DETECT") eq "yes" or &require(@ALL_ARCHS);
126 foreach my $fn (keys %ALL_FUNCS) {
128 my @val = @{$ALL_FUNCS{$fn}};
131 my $dfn = eval "\$${fn}_default";
132 $dfn = eval "\$${dfn}";
133 foreach my $opt (@_) {
134 my $ofn = eval "\$${fn}_${opt}";
136 my $link = eval "\$${fn}_${opt}_link";
137 next if $link && $link eq "false";
141 eval "\$${fn}_indirect = 'false'";
143 eval "\$${fn}_indirect = 'true'";
148 sub declare_function_pointers {
149 foreach my $fn (sort keys %ALL_FUNCS) {
150 my @val = @{$ALL_FUNCS{$fn}};
153 my $dfn = eval "\$${fn}_default";
154 $dfn = eval "\$${dfn}";
155 foreach my $opt (@_) {
156 my $ofn = eval "\$${fn}_${opt}";
158 print "$rtyp ${ofn}($args);\n";
160 if (eval "\$${fn}_indirect" eq "false") {
161 print "#define ${fn} ${dfn}\n";
163 print "RTCD_EXTERN $rtyp (*${fn})($args);\n";
169 sub set_function_pointers {
170 foreach my $fn (sort keys %ALL_FUNCS) {
171 my @val = @{$ALL_FUNCS{$fn}};
174 my $dfn = eval "\$${fn}_default";
175 $dfn = eval "\$${dfn}";
176 if (eval "\$${fn}_indirect" eq "true") {
177 print " $fn = $dfn;\n";
178 foreach my $opt (@_) {
179 my $ofn = eval "\$${fn}_${opt}";
181 next if "$ofn" eq "$dfn";
182 my $link = eval "\$${fn}_${opt}_link";
183 next if $link && $link eq "false";
184 my $cond = eval "\$have_${opt}";
185 print " if (${cond}) $fn = $ofn;\n"
193 foreach (@_) { push @filtered, $_ unless $disabled{$_}; }
198 # Helper functions for generating the arch specific RTCD files
201 my $include_guard = uc($opts{sym})."_H_";
203 #ifndef ${include_guard}
204 #define ${include_guard}
209 #define RTCD_EXTERN extern
218 process_forward_decls();
220 declare_function_pointers("c", @ALL_ARCHS);
223 void $opts{sym}(void);
228 sub common_bottom() {
240 determine_indirection("c", @ALL_ARCHS);
242 # Assign the helper variable for each enabled extension
243 foreach my $opt (@ALL_ARCHS) {
244 my $opt_uc = uc $opt;
245 eval "\$have_${opt}=\"flags & HAS_${opt_uc}\"";
251 #include "vpx_ports/x86.h"
252 static void setup_rtcd_internal(void)
254 int flags = x86_simd_caps();
260 set_function_pointers("c", @ALL_ARCHS);
270 determine_indirection("c", @ALL_ARCHS);
272 # Assign the helper variable for each enabled extension
273 foreach my $opt (@ALL_ARCHS) {
274 my $opt_uc = uc $opt;
275 # Enable neon assembly based on HAVE_NEON logic instead of adding new
276 # HAVE_NEON_ASM logic
277 if ($opt eq 'neon_asm') { $opt_uc = 'NEON' }
278 eval "\$have_${opt}=\"flags & HAS_${opt_uc}\"";
283 #include "vpx_config.h"
286 #include "vpx_ports/arm.h"
287 static void setup_rtcd_internal(void)
289 int flags = arm_cpu_caps();
295 set_function_pointers("c", @ALL_ARCHS);
305 determine_indirection("c", @ALL_ARCHS);
309 #include "vpx_config.h"
312 static void setup_rtcd_internal(void)
316 set_function_pointers("c", @ALL_ARCHS);
321 void dsputil_static_init();
322 dsputil_static_init();
325 void vp9_dsputil_static_init();
326 vp9_dsputil_static_init();
336 determine_indirection "c";
339 #include "vpx_config.h"
342 static void setup_rtcd_internal(void)
346 set_function_pointers "c";
360 if ($opts{arch} eq 'x86') {
361 @ALL_ARCHS = filter(qw/mmx sse sse2 sse3 ssse3 sse4_1 avx avx2/);
363 } elsif ($opts{arch} eq 'x86_64') {
364 @ALL_ARCHS = filter(qw/mmx sse sse2 sse3 ssse3 sse4_1 avx avx2/);
365 @REQUIRES = filter(keys %required ? keys %required : qw/mmx sse sse2/);
368 } elsif ($opts{arch} eq 'mips32') {
369 @ALL_ARCHS = filter(qw/mips32/);
370 open CONFIG_FILE, $opts{config} or
371 die "Error opening config file '$opts{config}': $!\n";
372 while (<CONFIG_FILE>) {
373 if (/HAVE_DSPR2=yes/) {
374 @ALL_ARCHS = filter(qw/mips32 dspr2/);
380 } elsif ($opts{arch} eq 'armv5te') {
381 @ALL_ARCHS = filter(qw/edsp/);
383 } elsif ($opts{arch} eq 'armv6') {
384 @ALL_ARCHS = filter(qw/edsp media/);
386 } elsif ($opts{arch} eq 'armv7') {
387 @ALL_ARCHS = filter(qw/edsp media neon_asm neon/);
388 @REQUIRES = filter(keys %required ? keys %required : qw/media/);
391 } elsif ($opts{arch} eq 'armv8') {
392 @ALL_ARCHS = filter(qw/neon/);
406 Usage: rtcd.pl [options] FILE
408 See 'perldoc rtcd.pl' for more details.
412 Reads the Run Time CPU Detections definitions from FILE and generates a
413 C header file on stdout.
418 --arch=ARCH Architecture to generate defs for (required)
419 --disable-EXT Disable support for EXT extensions
420 --require-EXT Require support for EXT extensions
421 --sym=SYMBOL Unique symbol to use for RTCD initialization function
422 --config=FILE File with CONFIG_FOO=yes lines to parse