diff options
author | Andy Polyakov <appro@openssl.org> | 2015-01-05 11:25:10 +0100 |
---|---|---|
committer | Andy Polyakov <appro@openssl.org> | 2015-01-23 15:38:41 +0100 |
commit | 9b05cbc33e7895ed033b1119e300782d9e0cf23c (patch) | |
tree | c3dca986e01d13b3ca7ac8d6ff776ca5e0183026 /crypto/perlasm/arm-xlate.pl | |
parent | 27c7609cf8e72dfa2956bc00f166301ee983581a (diff) |
Add assembly support to ios64-cross.
Fix typos in ios64-cross config line.
Reviewed-by: Tim Hudson <tjh@openssl.org>
Diffstat (limited to 'crypto/perlasm/arm-xlate.pl')
-rwxr-xr-x | crypto/perlasm/arm-xlate.pl | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/crypto/perlasm/arm-xlate.pl b/crypto/perlasm/arm-xlate.pl new file mode 100755 index 0000000000..fd185e9c1f --- /dev/null +++ b/crypto/perlasm/arm-xlate.pl @@ -0,0 +1,140 @@ +#!/usr/bin/env perl + +# ARM assembler distiller by <appro>. + +my $flavour = shift; +my $output = shift; +open STDOUT,">$output" || die "can't open $output: $!"; + +$flavour = "linux32" if (!$flavour or $flavour eq "void"); + +my %GLOBALS; +my $dotinlocallabels=($flavour=~/linux/)?1:0; + +################################################################ +# directives which need special treatment on different platforms +################################################################ +my $arch = sub { + if ($flavour =~ /linux/) { ".arch\t".join(',',@_); } + else { ""; } +}; +my $globl = sub { + my $name = shift; + my $global = \$GLOBALS{$name}; + my $ret; + + SWITCH: for ($flavour) { + /ios/ && do { $name = "_$name"; + last; + }; + } + + $ret = ".globl $name" if (!$ret); + $$global = $name; + $ret; +}; +my $global = $globl; +my $extern = sub { + &$globl(@_); + return; # return nothing +}; +my $type = sub { + if ($flavour =~ /linux/) { ".type\t".join(',',@_); } + else { ""; } +}; +my $size = sub { + if ($flavour =~ /linux/) { ".size\t".join(',',@_); } + else { ""; } +}; +my $inst = sub { + if ($flavour =~ /linux/) { ".inst\t".join(',',@_); } + else { ".long\t".join(',',@_); } +}; +my $asciz = sub { + my $line = join(",",@_); + if ($line =~ /^"(.*)"$/) + { ".byte " . join(",",unpack("C*",$1),0) . "\n.align 2"; } + else + { ""; } +}; + +sub range { + my ($r,$sfx,$start,$end) = @_; + + join(",",map("$r$_$sfx",($start..$end))); +} + +sub parse_args { + my $line = shift; + my @ret = (); + + pos($line)=0; + + while (1) { + if ($line =~ m/\G\[/gc) { + $line =~ m/\G([^\]]+\][^,]*)\s*/g; + push @ret,"[$1"; + } + 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"; + } + elsif ($line =~ m/\G([^,]+)\s*/g) { + push @ret,$1; + } + + 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; +} + +while($line=<>) { + + $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|(^[\.\w]+)\:\s*||; + my $label = $1; + if ($label) { + printf "%s:",($GLOBALS{$label} or $label); + } + } + + if ($line !~ m/^#/o) { + $line =~ s|^\s*(\.?)(\S+)\s*||o; + my $c = $1; $c = "\t" if ($c eq ""); + my $mnemonic = $2; + my $opcode; + if ($mnemonic =~ m/([^\.]+)\.([^\.]+)/o) { + $opcode = eval("\$$1_$2"); + } else { + $opcode = eval("\$$mnemonic"); + } + + my @args=parse_args($line); + + if (ref($opcode) eq 'CODE') { + $line = &$opcode(@args); + } elsif ($mnemonic) { + $line = $c.$mnemonic; + $line.= "\t".join(',',@args) if ($#args>=0); + } + } + + print $line if ($line); + print "\n"; +} + +close STDOUT; |