sub Extract()

in maxas/MaxAs/MaxAs.pm [624:723]


sub Extract
{
    my ($in, $out, $params) = @_;

    my %paramMap;
    my %constants =
    (
        blockDimX => 'c[0x0][0x8]',
        blockDimY => 'c[0x0][0xc]',
        blockDimZ => 'c[0x0][0x10]',
        gridDimX  => 'c[0x0][0x14]',
        gridDimY  => 'c[0x0][0x18]',
        gridDimZ  => 'c[0x0][0x1c]',
    );
    print $out "<CONSTANT_MAPPING>\n";

    foreach my $const (sort keys %constants)
    {
        print $out "    $const : $constants{$const}\n";
        $paramMap{$constants{$const}} = $const;
    }
    print $out "\n";

    foreach my $p (@$params)
    {
        my ($ord,$offset,$size,$align) = split ':', $p;

        if ($size > 4)
        {
            my $num = 0;
            $offset = hex $offset;
            while ($size > 0)
            {
                my $param = sprintf 'param_%d[%d]', $ord, $num;
                my $const = sprintf 'c[0x0][0x%x]', $offset;
                $paramMap{$const} = $param;
                print $out "    $param : $const\n";
                $size   -= 4;
                $offset += 4;
                $num    += 1;
            }
        }
        else
        {
            my $param = sprintf 'param_%d', $ord;
            my $const = sprintf 'c[0x0][%s]', $offset;
            $paramMap{$const} = $param;
            print $out "    $param : $const\n";
        }
    }
    print $out "</CONSTANT_MAPPING>\n\n";

    my %labels;
    my $labelnum = 1;

    my @data;
    FILE: while (my $line = <$in>)
    {
        my (@ctrl, @ruse);
        next unless processSassCtrlLine($line, \@ctrl, \@ruse);

        CTRL: foreach my $ctrl (@ctrl)
        {
            $line = <$in>;

            my $inst = processSassLine($line) or next CTRL;

            # Convert branch/jump/call addresses to labels
            if (exists($jumpOp{$inst->{op}}) && $inst->{ins} =~ m'(0x[0-9a-f]+)')
            {
                my $target = hex($1);

                # skip the final BRA and stop processing the file
                last FILE if $inst->{op} eq 'BRA' && ($target == $inst->{num} || $target == $inst->{num}-8);

                # check to see if we've already generated a label for this target address
                my $label = $labels{$target};
                unless ($label)
                {
                    # generate a label name and cache it
                    $label = $labels{$target} = "TARGET$labelnum";
                    $labelnum++;
                }
                # replace address with name
                $inst->{ins} =~ s/(0x[0-9a-f]+)/$label/;
            }
            $inst->{ins} =~ s/(c\[0x0\])\s*(\[0x[0-9a-f]+\])/ $paramMap{$1 . $2} || $1 . $2 /eg;

            $inst->{ctrl} = printCtrl($ctrl);

            push @data, $inst;
        }
    }
    # make a second pass now that we have the complete instruction address to label mapping
    foreach my $inst (@data)
    {
        print $out "$labels{$inst->{num}}:\n" if exists $labels{$inst->{num}};
        printf $out "%s %5s%s\n", @{$inst}{qw(ctrl pred ins)};
    }
}