summaryrefslogtreecommitdiffstats
path: root/crypto/perlasm/ppc-xlate.pl
diff options
context:
space:
mode:
authorAndy Polyakov <appro@openssl.org>2006-04-30 21:15:29 +0000
committerAndy Polyakov <appro@openssl.org>2006-04-30 21:15:29 +0000
commit2c5d4daac5d23416ab619bfbcb0189227ffdf71f (patch)
treea7e6dbaba67a395b68a2a738654504a2929640f3 /crypto/perlasm/ppc-xlate.pl
parentb46343583c1172c6e0fcad3227cf50622aae7998 (diff)
Yet another "teaser" Montgomery multiplication module, for PowerPC.
Diffstat (limited to 'crypto/perlasm/ppc-xlate.pl')
-rwxr-xr-xcrypto/perlasm/ppc-xlate.pl113
1 files changed, 113 insertions, 0 deletions
diff --git a/crypto/perlasm/ppc-xlate.pl b/crypto/perlasm/ppc-xlate.pl
new file mode 100755
index 0000000000..31876e56b2
--- /dev/null
+++ b/crypto/perlasm/ppc-xlate.pl
@@ -0,0 +1,113 @@
+#!/usr/bin/env perl
+
+# PowerPC assembler distiller by <appro>.
+
+my $output = shift;
+open STDOUT,">$output" || die "can't open $output: $!";
+
+my $flavour = $output;
+my %GLOBALS;
+my $dotinlocallabels=0;
+
+################################################################
+# directives which need special treatment on different platforms
+################################################################
+my $globl = sub {
+ my $junk = shift;
+ my $name = shift;
+ my $global = \$GLOBALS{$name};
+ my $ret;
+
+ $name =~ s|^[\.\_]||;
+
+ SWITCH: for ($flavour) {
+ /aix/ && do { $name = ".$name";
+ last;
+ };
+ /osx/ && do { $name = "_$name";
+ last;
+ };
+ /linux.*32/ && do { $ret .= ".globl $name\n";
+ $ret .= ".type $name,\@function";
+ $dotinlocallabels = 1;
+ last;
+ };
+ /linux.*64/ && do { $ret .= ".globl .$name\n";
+ $ret .= ".type .$name,\@function\n";
+ $ret .= ".section \".opd\",\"aw\"\n";
+ $ret .= ".globl $name\n";
+ $ret .= ".align 3\n";
+ $ret .= "$name:\n";
+ $ret .= ".quad .$name,.TOC.\@tocbase,0\n";
+ $ret .= ".size $name,24\n";
+ $ret .= ".previous\n";
+
+ $name = ".$name";
+ $dotinlocallabels = 1;
+ last;
+ };
+ }
+
+ $ret = ".globl $name" if (!$ret);
+ $$global = $name;
+ $ret;
+};
+my $machine = sub {
+ my $junk = shift;
+ my $arch = shift;
+ $arch = "ppc970" if ($arch eq "any" and $flavour =~ /osx/);
+ ".machine $arch";
+};
+
+################################################################
+# simplified mnemonics not handled by at least one assembler
+################################################################
+my $cmplw = sub {
+ my $f = shift;
+ my $cr = 0; $cr = shift if ($#_>1);
+ " cmpl$f ".join(',',$cr,0,@_);
+};
+my $cmpld = sub {
+ my $f = shift;
+ my $cr = 0; $cr = shift if ($#_>1);
+ " cmpl$f ".join(',',$cr,1,@_);
+};
+my $bdnz = sub {
+ my $f = shift;
+ my $bo = $f=~/[\+\-]/ ? 17 : 16;
+ " bc $bo,0,".shift;
+};
+
+while($line=<>) {
+
+ $line =~ s|[#!;].*$||; # get rid of asm-style comments...
+ $line =~ s|/\*.*\*/||; # ... and 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;
+ printf "%s:",($GLOBALS{$label} or $label) if ($label);
+ }
+
+ {
+ $line =~ s|^\s*(\.?)(\w+)([\.\+\-]?)\s*||;
+ my $c = $1; $c = "\t" if ($c eq "");
+ my $mnemonic = $2;
+ my $f = $3;
+ my $opcode = eval("\$$mnemonic");
+ if (ref($opcode) eq 'CODE') { $line = &$opcode($f,split(',',$line)); }
+ elsif ($mnemonic) { $line = $c.$mnemonic.$f."\t".$line; }
+ }
+
+ print $line if ($line);
+ print "\n";
+}
+
+close STDOUT;