sub getI()

in maxas/MaxAs/MaxAsGrammar.pm [19:57]


sub getI
{
    my ($orig, $pos, $mask) = @_;
    my $val = $orig;
    my $neg = $val =~ s|^\-||;

    # parse out our custom index immediates for addresses
    if ($val  =~ m'^(\d+)[xX]<([^>]+)>')
    {
        # allow any perl expression and multiply result by leading decimal.
        # also allow global scalar varibles in the expression.
        my $mul = $1;
        my $exp = $2;
        # strip leading zeros (don't interpret numbers as octal)
        $exp =~ s/(?<!\d)0+(?=[1-9])//g;
        my @globals = $exp =~ m'\$\w+'g;
        my $our = @globals ? ' our (' . join(',',@globals) . ');' : '';
        $val = $mul * eval "package MaxAs::MaxAs::CODE;$our $exp";
        #print "$val = $mul x $exp\n"; # if $our;
    }
    # hexidecial value
    elsif ($val  =~ m'^0x[0-9a-zA-Z]+')
    {
        $val = hex($val);
    }
    # otherwise val is a simple decimal value that doesn't need to be modified

    if ( $neg )
    {
        # if the mask removes the sign bit the "neg" flag adds it back on the code somewhere else
        $val = -$val;
        $val &= $mask;
    }
    if (($val & $mask) != $val)
    {
        die sprintf "Immediate value out of range(0x%x): 0x%x ($orig)\n", $mask, $val;
    }
    return $val << $pos;
}