Commit 7b644df8 authored by Andy Polyakov's avatar Andy Polyakov
Browse files

perlasm/arm-xlate.pl update (fix end-less loop and prepare for 32-bit iOS).



Reviewed-by: default avatarRich Salz <rsalz@openssl.org>
parent 449e3f26
Loading
Loading
Loading
Loading
+49 −24
Original line number Diff line number Diff line
@@ -18,6 +18,32 @@ my $arch = sub {
    if ($flavour =~ /linux/)	{ ".arch\t".join(',',@_); }
    else			{ ""; }
};
my $fpu = sub {
    if ($flavour =~ /linux/)	{ ".fpu\t".join(',',@_); }
    else			{ ""; }
};
my $hidden = sub {
    if ($flavour =~ /ios/)	{ ".private_extern\t".join(',',@_); }
    else			{ ".hidden\t".join(',',@_); }
};
my $comm = sub {
    my @args = split(/,\s*/,shift);
    my $name = @args[0];
    my $global = \$GLOBALS{$name};
    my $ret;

    if ($flavour =~ /ios32/)	{
	$ret = ".comm\t_$name,@args[1]\n";
	$ret .= ".non_lazy_symbol_pointer\n";
	$ret .= "$name:\n";
	$ret .= ".indirect_symbol\t_$name\n";
	$ret .= ".long\t0";
	$name = "_$name";
    } else			{ $ret = ".comm\t".join(',',@args); }

    $$global = $name;
    $ret;
};
my $globl = sub {
    my $name = shift;
    my $global = \$GLOBALS{$name};
@@ -64,44 +90,43 @@ sub range {
    join(",",map("$r$_$sfx",($start..$end)));
}

sub parse_args {
sub expand_line {
  my $line = shift;
  my @ret = ();

    pos($line)=0;

    while (1) {
	if ($line =~ m/\G\[/gc) {
	    $line =~ m/\G([^\]]+\][^,]*)\s*/g;
	    push @ret,"[$1";
    while ($line =~ m/\G[^@\/\{\"]*/g) {
	if ($line =~ m/\G(@|\/\/|$)/gc) {
	    last;
	}
	elsif ($line =~ m/\G\{/gc) {
	    $line =~ m/\G([^\}]+\}[^,]*)\s*/g;
	    my $arg = $1;
	    $arg =~ s/([rdqv])([0-9]+)([^\-]*)\-\1([0-9]+)\3/range($1,$3,$2,$4)/ge;
	    push @ret,"{$arg";
	    my $saved_pos = pos($line);
	    $line =~ s/\G([rdqv])([0-9]+)([^\-]*)\-\1([0-9]+)\3/range($1,$3,$2,$4)/e;
	    pos($line) = $saved_pos;
	    $line =~ m/\G[^\}]*\}/g;
	}
	elsif ($line =~ m/\G([^,]+)\s*/g) {
	    push @ret,$1;
	elsif ($line =~ m/\G\"/gc) {
	    $line =~ m/\G[^\"]*\"/g;
	}

	last if ($line =~ m/\G$/gc);

	$line =~ m/\G,\s*/g;
    }

    map {my $s=$_;$s=~s/\b(\w+)/$GLOBALS{$1} or $1/ge;$s} @ret;
    $line =~ s/\b(\w+)/$GLOBALS{$1} or $1/ge;

    return $line;
}

while($line=<>) {

    if ($line =~ m/^\s*(#|@|\/\/)/)	{ print $line; next; }

    $line =~ s|/\*.*\*/||;	# get rid of C-style comments...
    $line =~ s|^\s+||;		# ... and skip white spaces in beginning...
    $line =~ s|\s+$||;		# ... and at the end

    {
	$line =~ s|[\b\.]L(\w+)|L$1|g;	# common denominator for Locallabel
	$line =~ s|\bL(\w+)|\.L$1|g	if ($dotinlocallabels);
	$line =~ s|[\b\.]L(\w{2,})|L$1|g;	# common denominator for Locallabel
	$line =~ s|\bL(\w{2,})|\.L$1|g	if ($dotinlocallabels);
    }

    {
@@ -112,24 +137,24 @@ while($line=<>) {
	}
    }

    if ($line !~ m/^#/o) {
	$line =~ s|^\s*(\.?)(\S+)\s*||o;
    if ($line !~ m/^[#@]/) {
	$line =~ s|^\s*(\.?)(\S+)\s*||;
	my $c = $1; $c = "\t" if ($c eq "");
	my $mnemonic = $2;
	my $opcode;
	if ($mnemonic =~ m/([^\.]+)\.([^\.]+)/o) {
	if ($mnemonic =~ m/([^\.]+)\.([^\.]+)/) {
	    $opcode = eval("\$$1_$2");
	} else {
	    $opcode = eval("\$$mnemonic");
	}

	my @args=parse_args($line);
	my $arg=expand_line($line);

	if (ref($opcode) eq 'CODE') {
		$line = &$opcode(@args);
		$line = &$opcode($arg);
	} elsif ($mnemonic)         {
		$line = $c.$mnemonic;
		$line.= "\t".join(',',@args) if ($#args>=0);
		$line.= "\t$arg" if ($arg);
	}
    }