sub genCode()

in maxas/MaxAs/MaxAsGrammar.pm [1174:1259]


sub genCode
{
    my ($op, $grammar, $capData, $test) = @_;

    my $flags     = $flags{$op};
    my $code      = $grammar->{code};
    my $reuse     = 0;
    my $immedCode = $immedCodes{$code >> 56};

    #print map "$_: $capData->{$_}\n", keys %capData if $op eq 'I2I';

    # process the instruction predicate (if valid for this instuction)
    if (exists $capData->{noPred})
    {
        delete $capData->{noPred};
        push @$test, 'noPred' if $test;
    }
    else
    {
        my $p = defined($capData->{predNum}) ? $capData->{predNum} : 7;
        push @$test, 'predNum' if $test;
        if (exists $capData->{predNot})
        {
            $p |= 8;
            push @$test, 'predNot' if $test;
        }
        $code ^= $p << 16;
        delete @{$capData}{qw(predNum predNot)};

    }
    # process the register reuse flags
    foreach my $rcode (qw(reuse1 reuse2 reuse3))
    {
        if (delete $capData->{$rcode})
        {
            $reuse |= $reuseCodes{$rcode};
            push @$test, $rcode if $test;
        }
    }

    foreach my $capture (keys %$capData)
    {
        # change the base code for immediate versions of the op
        if (exists $immedOps{$capture})
            { $code ^= $immedCode << 56; }
        # change the base code for constant versions of the op
        elsif (exists $constCodes{$capture})
            { $code ^= $constCodes{$capture} << 56; }

        # if capture group is an operand then process and add that data to code
        if (exists $operands{$capture})
        {
            # don't process the r20 that comes with the r39s20 capture
            unless ($capture eq 'r20' && exists $capData->{r39s20})
            {
                $code ^= $operands{$capture}->($capData->{$capture});
                push @$test, $capture if $test;
            }
        }

        # Add matching flags (an operand might also add/remove a flag)
        if (exists $flags->{$capture})
        {
            # a named multivalue flag
            if (ref $flags->{$capture})
            {
                $code ^= $flags->{$capture}{$capData->{$capture}};
                push @$test, "$capture:$capData->{$capture}" if $test;
            }
            # a simple exists flag
            else
            {
                $code ^= $flags->{$capture};
                push @$test, $capture if $test;
            }
        }
        elsif (!exists $operands{$capture} && !$test)
        {
            # Every capture group should be acted upon.  Missing one is a bug.
            warn "UNUSED: $op: $capture: $capData->{$capture}\n";
            warn Dumper($flags);
        }
    }

    return $code, $reuse;
}