sub Test()

in maxas/MaxAs/MaxAs.pm [522:621]


sub Test
{
    my ($fh, $printConflicts, $all) = @_;

    my @instructs;
    my %reuseHistory;
    my ($pass, $fail) = (0,0);

    while (my $line = <$fh>)
    {
        my (@ctrl, @reuse);

        next unless processSassCtrlLine($line, \@ctrl, \@reuse);

        foreach my $fileReuse (@reuse)
        {
            $line = <$fh>;

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

            $inst->{reuse} = $fileReuse;
            my $fileCode = $inst->{code};

            if (exists $relOffset{$inst->{op}})
            {
                # these ops need to be converted from absolute addresses to relative in the sass output by cuobjdump
                $inst->{inst} =~ s/(0x[0-9a-f]+)/sprintf '0x%06x', ((hex($1) - $inst->{num} - 8) & 0xffffff)/e;
            }

            my $match = 0;
            foreach my $gram (@{$grammar{$inst->{op}}})
            {
                my $capData = parseInstruct($inst->{inst}, $gram) or next;
                my @caps;

                # Run in test mode to list what capture groups were captured
                my ($code, $reuse) = genCode($inst->{op}, $gram, $capData, \@caps);

                # Detect register bank conflicts but only for reuse type instructions.
                # If a bank conflict is avoided by a reuse flag then ignore it.
                registerHealth(\%reuseHistory, $reuse, $capData, $inst->{num}, $printConflicts ? $inst->{inst} : '') if $gram->{type}{reuse};

                $inst->{caps}      = join ', ', sort @caps;
                $inst->{codeDiff}  = $fileCode  ^ $code;
                $inst->{reuseDiff} = $fileReuse ^ $reuse;

                # compare calculated and file values
                if ($code == $fileCode && $reuse == $fileReuse)
                {
                    $inst->{grade} = 'PASS';
                    push @instructs, $inst if $all;
                    $pass++;
                }
                else
                {
                    $inst->{grade} = 'FAIL';
                    push @instructs, $inst;
                    $fail++;
                }
                $match = 1;
                last;
            }
            unless ($match)
            {
                $inst->{grade}     = 'FAIL';
                $inst->{codeDiff}  = $fileCode;
                $inst->{reuseDiff} = $fileReuse;
                push @instructs, $inst;
                $fail++;
            }
        }
    }
    my %maxLen;
    foreach (@instructs)
    {
        $maxLen{$_->{op}} = length($_->{ins}) if length($_->{ins}) > $maxLen{$_->{op}};
    }
    my ($lastOp, $template);
    foreach my $inst (sort {
        $a->{op}        cmp $b->{op}        ||
        $a->{codeDiff}  <=> $b->{codeDiff}  ||
        $a->{reuseDiff} <=> $b->{reuseDiff} ||
        $a->{ins}       cmp $b->{ins}
        } @instructs)
    {
        if ($lastOp ne $inst->{op})
        {
            $lastOp   = $inst->{op};
            $template = "%s 0x%016x %x 0x%016x %x %5s%-$maxLen{$lastOp}s   %s\n";
            printf "\n%s %-18s %s %-18s %s %-5s%-$maxLen{$lastOp}s   %s\n", qw(Grad OpCode R opCodeDiff r Pred Instruction Captures);
        }
        printf $template, @{$inst}{qw(grade code reuse codeDiff reuseDiff pred ins caps)};
    }
    my $reusePct = $reuseHistory{total} ? 100 * $reuseHistory{reuse} / $reuseHistory{total} : 0;

    printf "\nRegister Bank Conflicts: %d, Reuse: %.1f% (%d/%d)\nOp Code Coverage Totals: Pass: $pass Fail: $fail\n",
        $reuseHistory{conflicts}, $reusePct, $reuseHistory{reuse}, $reuseHistory{total};

    return $fail;
}