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;
}