diff --git a/build/make/rtcd.pl b/build/make/rtcd.pl new file mode 100755 index 000000000..18ee80d36 --- /dev/null +++ b/build/make/rtcd.pl @@ -0,0 +1,414 @@ +#!/usr/bin/env perl + +no strict 'refs'; +use warnings; +use Getopt::Long; +Getopt::Long::Configure("auto_help"); + +my %ALL_FUNCS = (); +my @ALL_ARCHS; +my @ALL_FORWARD_DECLS; +my @REQUIRES; + +my %opts = (); +my %disabled = (); +my %required = (); + +my @argv; +foreach (@ARGV) { + $disabled{$1} = 1, next if /--disable-(.*)/; + $required{$1} = 1, next if /--require-(.*)/; + push @argv, $_; +} + +# NB: use GetOptions() instead of GetOptionsFromArray() for compatibility. +@ARGV = @argv; +GetOptions( + \%opts, + 'arch=s', + 'sym=s', + 'config=s', +); + +foreach my $opt (qw/arch config/) { + if (!defined($opts{$opt})) { + warn "--$opt is required!\n"; + Getopt::Long::HelpMessage('-exit' => 1); + } +} + +foreach my $defs_file (@ARGV) { + if (!-f $defs_file) { + warn "$defs_file: $!\n"; + Getopt::Long::HelpMessage('-exit' => 1); + } +} + +open CONFIG_FILE, $opts{config} or + die "Error opening config file '$opts{config}': $!\n"; + +my %config = (); +while () { + next if !/^CONFIG_/; + chomp; + my @pair = split /=/; + $config{$pair[0]} = $pair[1]; +} +close CONFIG_FILE; + +# +# Routines for the RTCD DSL to call +# +sub vpx_config($) { + return (defined $config{$_[0]}) ? $config{$_[0]} : ""; +} + +sub specialize { + my $fn=$_[0]; + shift; + foreach my $opt (@_) { + eval "\$${fn}_${opt}=${fn}_${opt}"; + } +} + +sub add_proto { + my $fn = splice(@_, -2, 1); + $ALL_FUNCS{$fn} = \@_; + specialize $fn, "c"; +} + +sub require { + foreach my $fn (keys %ALL_FUNCS) { + foreach my $opt (@_) { + my $ofn = eval "\$${fn}_${opt}"; + next if !$ofn; + + # if we already have a default, then we can disable it, as we know + # we can do better. + my $best = eval "\$${fn}_default"; + if ($best) { + my $best_ofn = eval "\$${best}"; + if ($best_ofn && "$best_ofn" ne "$ofn") { + eval "\$${best}_link = 'false'"; + } + } + eval "\$${fn}_default=${fn}_${opt}"; + eval "\$${fn}_${opt}_link='true'"; + } + } +} + +sub forward_decls { + push @ALL_FORWARD_DECLS, @_; +} + +# +# Include the user's directives +# +foreach my $f (@ARGV) { + open FILE, "<", $f or die "cannot open $f: $!\n"; + my $contents = join('', ); + close FILE; + eval $contents or warn "eval failed: $@\n"; +} + +# +# Process the directives according to the command line +# +sub process_forward_decls() { + foreach (@ALL_FORWARD_DECLS) { + $_->(); + } +} + +sub determine_indirection { + vpx_config("CONFIG_RUNTIME_CPU_DETECT") eq "yes" or &require(@ALL_ARCHS); + foreach my $fn (keys %ALL_FUNCS) { + my $n = ""; + my @val = @{$ALL_FUNCS{$fn}}; + my $args = pop @val; + my $rtyp = "@val"; + my $dfn = eval "\$${fn}_default"; + $dfn = eval "\$${dfn}"; + foreach my $opt (@_) { + my $ofn = eval "\$${fn}_${opt}"; + next if !$ofn; + my $link = eval "\$${fn}_${opt}_link"; + next if $link && $link eq "false"; + $n .= "x"; + } + if ($n eq "x") { + eval "\$${fn}_indirect = 'false'"; + } else { + eval "\$${fn}_indirect = 'true'"; + } + } +} + +sub declare_function_pointers { + foreach my $fn (sort keys %ALL_FUNCS) { + my @val = @{$ALL_FUNCS{$fn}}; + my $args = pop @val; + my $rtyp = "@val"; + my $dfn = eval "\$${fn}_default"; + $dfn = eval "\$${dfn}"; + foreach my $opt (@_) { + my $ofn = eval "\$${fn}_${opt}"; + next if !$ofn; + print "$rtyp ${ofn}($args);\n"; + } + if (eval "\$${fn}_indirect" eq "false") { + print "#define ${fn} ${dfn}\n"; + } else { + print "RTCD_EXTERN $rtyp (*${fn})($args);\n"; + } + print "\n"; + } +} + +sub set_function_pointers { + foreach my $fn (sort keys %ALL_FUNCS) { + my @val = @{$ALL_FUNCS{$fn}}; + my $args = pop @val; + my $rtyp = "@val"; + my $dfn = eval "\$${fn}_default"; + $dfn = eval "\$${dfn}"; + if (eval "\$${fn}_indirect" eq "true") { + print " $fn = $dfn;\n"; + foreach my $opt (@_) { + my $ofn = eval "\$${fn}_${opt}"; + next if !$ofn; + next if "$ofn" eq "$dfn"; + my $link = eval "\$${fn}_${opt}_link"; + next if $link && $link eq "false"; + my $cond = eval "\$have_${opt}"; + print " if (${cond}) $fn = $ofn;\n" + } + } + } +} + +sub filter { + my @filtered; + foreach (@_) { push @filtered, $_ unless $disabled{$_}; } + return @filtered; +} + +# +# Helper functions for generating the arch specific RTCD files +# +sub common_top() { + my $include_guard = uc($opts{sym})."_H_"; + print <) { + if (/HAVE_DSPR2=yes/) { + @ALL_ARCHS = filter(qw/mips32 dspr2/); + last; + } + } + close CONFIG_FILE; + mips; +} elsif ($opts{arch} eq 'armv5te') { + @ALL_ARCHS = filter(qw/edsp/); + arm; +} elsif ($opts{arch} eq 'armv6') { + @ALL_ARCHS = filter(qw/edsp media/); + arm; +} elsif ($opts{arch} eq 'armv7') { + @ALL_ARCHS = filter(qw/edsp media neon/); + arm; +} else { + unoptimized; +} + +__END__ + +=head1 NAME + +rtcd - + +=head1 SYNOPSIS + +Usage: rtcd.pl [options] FILE + +See 'perldoc rtcd.pl' for more details. + +=head1 DESCRIPTION + +Reads the Run Time CPU Detections definitions from FILE and generates a +C header file on stdout. + +=head1 OPTIONS + +Options: + --arch=ARCH Architecture to generate defs for (required) + --disable-EXT Disable support for EXT extensions + --require-EXT Require support for EXT extensions + --sym=SYMBOL Unique symbol to use for RTCD initialization function + --config=FILE File with CONFIG_FOO=yes lines to parse diff --git a/build/make/rtcd.sh b/build/make/rtcd.sh deleted file mode 100755 index 93c9adcac..000000000 --- a/build/make/rtcd.sh +++ /dev/null @@ -1,373 +0,0 @@ -#!/bin/sh -self=$0 - -usage() { - cat <&2 -Usage: $self [options] FILE - -Reads the Run Time CPU Detections definitions from FILE and generates a -C header file on stdout. - -Options: - --arch=ARCH Architecture to generate defs for (required) - --disable-EXT Disable support for EXT extensions - --require-EXT Require support for EXT extensions - --sym=SYMBOL Unique symbol to use for RTCD initialization function - --config=FILE File with CONFIG_FOO=yes lines to parse -EOF - exit 1 -} - -die() { - echo "$@" >&2 - exit 1 -} - -die_argument_required() { - die "Option $opt requires argument" -} - -for opt; do - optval="${opt#*=}" - case "$opt" in - --arch) die_argument_required;; - --arch=*) arch=${optval};; - --disable-*) eval "disable_${opt#--disable-}=true";; - --require-*) REQUIRES="${REQUIRES}${opt#--require-} ";; - --sym) die_argument_required;; - --sym=*) symbol=${optval};; - --config=*) config_file=${optval};; - -h|--help) - usage - ;; - -*) - die "Unrecognized option: ${opt%%=*}" - ;; - *) - defs_file="$defs_file $opt" - ;; - esac - shift -done -for f in $defs_file; do [ -f "$f" ] || usage; done -[ -n "$arch" ] || usage - -# Import the configuration -[ -f "$config_file" ] && eval $(grep CONFIG_ "$config_file") - -# -# Routines for the RTCD DSL to call -# -prototype() { - rtyp="" - case "$1" in - unsigned) rtyp="$1 "; shift;; - esac - rtyp="${rtyp}$1" - fn="$2" - args="$3" - - eval "${2}_rtyp='$rtyp'" - eval "${2}_args='$3'" - ALL_FUNCS="$ALL_FUNCS $fn" - specialize $fn c -} - -specialize() { - fn="$1" - shift - for opt in "$@"; do - eval "${fn}_${opt}=${fn}_${opt}" - done -} - -require() { - for fn in $ALL_FUNCS; do - for opt in "$@"; do - ofn=$(eval "echo \$${fn}_${opt}") - [ -z "$ofn" ] && continue - - # if we already have a default, then we can disable it, as we know - # we can do better. - best=$(eval "echo \$${fn}_default") - best_ofn=$(eval "echo \$${best}") - [ -n "$best" ] && [ "$best_ofn" != "$ofn" ] && eval "${best}_link=false" - eval "${fn}_default=${fn}_${opt}" - eval "${fn}_${opt}_link=true" - done - done -} - -forward_decls() { - ALL_FORWARD_DECLS="$ALL_FORWARD_DECLS $1" -} - -# -# Include the user's directives -# -for f in $defs_file; do - . $f -done - -# -# Process the directives according to the command line -# -process_forward_decls() { - for fn in $ALL_FORWARD_DECLS; do - eval $fn - done -} - -determine_indirection() { - [ "$CONFIG_RUNTIME_CPU_DETECT" = "yes" ] || require $ALL_ARCHS - for fn in $ALL_FUNCS; do - n="" - rtyp="$(eval "echo \$${fn}_rtyp")" - args="$(eval "echo \"\$${fn}_args\"")" - dfn="$(eval "echo \$${fn}_default")" - dfn=$(eval "echo \$${dfn}") - for opt in "$@"; do - ofn=$(eval "echo \$${fn}_${opt}") - [ -z "$ofn" ] && continue - link=$(eval "echo \$${fn}_${opt}_link") - [ "$link" = "false" ] && continue - n="${n}x" - done - if [ "$n" = "x" ]; then - eval "${fn}_indirect=false" - else - eval "${fn}_indirect=true" - fi - done -} - -declare_function_pointers() { - for fn in $ALL_FUNCS; do - rtyp="$(eval "echo \$${fn}_rtyp")" - args="$(eval "echo \"\$${fn}_args\"")" - dfn="$(eval "echo \$${fn}_default")" - dfn=$(eval "echo \$${dfn}") - for opt in "$@"; do - ofn=$(eval "echo \$${fn}_${opt}") - [ -z "$ofn" ] && continue - echo "$rtyp ${ofn}($args);" - done - if [ "$(eval "echo \$${fn}_indirect")" = "false" ]; then - echo "#define ${fn} ${dfn}" - else - echo "RTCD_EXTERN $rtyp (*${fn})($args);" - fi - echo - done -} - -set_function_pointers() { - for fn in $ALL_FUNCS; do - n="" - rtyp="$(eval "echo \$${fn}_rtyp")" - args="$(eval "echo \"\$${fn}_args\"")" - dfn="$(eval "echo \$${fn}_default")" - dfn=$(eval "echo \$${dfn}") - if $(eval "echo \$${fn}_indirect"); then - echo " $fn = $dfn;" - for opt in "$@"; do - ofn=$(eval "echo \$${fn}_${opt}") - [ -z "$ofn" ] && continue - [ "$ofn" = "$dfn" ] && continue; - link=$(eval "echo \$${fn}_${opt}_link") - [ "$link" = "false" ] && continue - cond="$(eval "echo \$have_${opt}")" - echo " if (${cond}) $fn = $ofn;" - done - fi - echo - done -} - -filter() { - filtered="" - for opt in "$@"; do - [ -z $(eval "echo \$disable_${opt}") ] && filtered="$filtered $opt" - done - echo $filtered -} - -# -# Helper functions for generating the arch specific RTCD files -# -common_top() { - outfile_basename=$(basename ${symbol:-rtcd}) - include_guard=$(echo $outfile_basename | tr '[a-z]' '[A-Z]' | \ - tr -c '[A-Z0-9]' _)H_ - cat </dev/null; then + die "Perl is required to build" +fi + # check installed doxygen version doxy_version=$(doxygen --version 2>/dev/null) doxy_major=${doxy_version%%.*} diff --git a/libs.mk b/libs.mk index b6f641371..a5c4b760d 100644 --- a/libs.mk +++ b/libs.mk @@ -49,7 +49,7 @@ endif # !gcc define rtcd_h_template $$(BUILD_PFX)$(1).h: $$(SRC_PATH_BARE)/$(2) @echo " [CREATE] $$@" - $$(qexec)$$(SRC_PATH_BARE)/build/make/rtcd.sh --arch=$$(TGT_ISA) \ + $$(qexec)$$(SRC_PATH_BARE)/build/make/rtcd.pl --arch=$$(TGT_ISA) \ --sym=$(1) \ --config=$$(CONFIG_DIR)$$(target)$$(if $$(FAT_ARCHS),,-$$(TOOLCHAIN)).mk \ $$(RTCD_OPTIONS) $$^ > $$@ @@ -162,7 +162,7 @@ INSTALL_MAPS += $(foreach p,$(VS_PLATFORMS),$(LIBSUBDIR)/$(p)/% $(p)/Debug/%) endif CODEC_SRCS-$(BUILD_LIBVPX) += build/make/version.sh -CODEC_SRCS-$(BUILD_LIBVPX) += build/make/rtcd.sh +CODEC_SRCS-$(BUILD_LIBVPX) += build/make/rtcd.pl CODEC_SRCS-$(BUILD_LIBVPX) += vpx_ports/emmintrin_compat.h CODEC_SRCS-$(BUILD_LIBVPX) += vpx_ports/mem_ops.h CODEC_SRCS-$(BUILD_LIBVPX) += vpx_ports/mem_ops_aligned.h diff --git a/vp8/common/rtcd_defs.pl b/vp8/common/rtcd_defs.pl new file mode 100644 index 000000000..130d96535 --- /dev/null +++ b/vp8/common/rtcd_defs.pl @@ -0,0 +1,541 @@ +sub vp8_common_forward_decls() { +print <