Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

crypto: p10-aes-gcm - A perl script to process PowerPC assembler source.

Signed-off-by: Danny Tsen <dtsen@linux.ibm.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Danny Tsen and committed by
Herbert Xu
08b50d84 55d762da

+229
+229
arch/powerpc/crypto/ppc-xlate.pl
··· 1 + #!/usr/bin/env perl 2 + # SPDX-License-Identifier: GPL-2.0 3 + 4 + # PowerPC assembler distiller by <appro>. 5 + 6 + my $flavour = shift; 7 + my $output = shift; 8 + open STDOUT,">$output" || die "can't open $output: $!"; 9 + 10 + my %GLOBALS; 11 + my $dotinlocallabels=($flavour=~/linux/)?1:0; 12 + 13 + ################################################################ 14 + # directives which need special treatment on different platforms 15 + ################################################################ 16 + my $globl = sub { 17 + my $junk = shift; 18 + my $name = shift; 19 + my $global = \$GLOBALS{$name}; 20 + my $ret; 21 + 22 + $name =~ s|^[\.\_]||; 23 + 24 + SWITCH: for ($flavour) { 25 + /aix/ && do { $name = ".$name"; 26 + last; 27 + }; 28 + /osx/ && do { $name = "_$name"; 29 + last; 30 + }; 31 + /linux/ 32 + && do { $ret = "_GLOBAL($name)"; 33 + last; 34 + }; 35 + } 36 + 37 + $ret = ".globl $name\nalign 5\n$name:" if (!$ret); 38 + $$global = $name; 39 + $ret; 40 + }; 41 + my $text = sub { 42 + my $ret = ($flavour =~ /aix/) ? ".csect\t.text[PR],7" : ".text"; 43 + $ret = ".abiversion 2\n".$ret if ($flavour =~ /linux.*64le/); 44 + $ret; 45 + }; 46 + my $machine = sub { 47 + my $junk = shift; 48 + my $arch = shift; 49 + if ($flavour =~ /osx/) 50 + { $arch =~ s/\"//g; 51 + $arch = ($flavour=~/64/) ? "ppc970-64" : "ppc970" if ($arch eq "any"); 52 + } 53 + ".machine $arch"; 54 + }; 55 + my $size = sub { 56 + if ($flavour =~ /linux/) 57 + { shift; 58 + my $name = shift; $name =~ s|^[\.\_]||; 59 + my $ret = ".size $name,.-".($flavour=~/64$/?".":"").$name; 60 + $ret .= "\n.size .$name,.-.$name" if ($flavour=~/64$/); 61 + $ret; 62 + } 63 + else 64 + { ""; } 65 + }; 66 + my $asciz = sub { 67 + shift; 68 + my $line = join(",",@_); 69 + if ($line =~ /^"(.*)"$/) 70 + { ".byte " . join(",",unpack("C*",$1),0) . "\n.align 2"; } 71 + else 72 + { ""; } 73 + }; 74 + my $quad = sub { 75 + shift; 76 + my @ret; 77 + my ($hi,$lo); 78 + for (@_) { 79 + if (/^0x([0-9a-f]*?)([0-9a-f]{1,8})$/io) 80 + { $hi=$1?"0x$1":"0"; $lo="0x$2"; } 81 + elsif (/^([0-9]+)$/o) 82 + { $hi=$1>>32; $lo=$1&0xffffffff; } # error-prone with 32-bit perl 83 + else 84 + { $hi=undef; $lo=$_; } 85 + 86 + if (defined($hi)) 87 + { push(@ret,$flavour=~/le$/o?".long\t$lo,$hi":".long\t$hi,$lo"); } 88 + else 89 + { push(@ret,".quad $lo"); } 90 + } 91 + join("\n",@ret); 92 + }; 93 + 94 + ################################################################ 95 + # simplified mnemonics not handled by at least one assembler 96 + ################################################################ 97 + my $cmplw = sub { 98 + my $f = shift; 99 + my $cr = 0; $cr = shift if ($#_>1); 100 + # Some out-of-date 32-bit GNU assembler just can't handle cmplw... 101 + ($flavour =~ /linux.*32/) ? 102 + " .long ".sprintf "0x%x",31<<26|$cr<<23|$_[0]<<16|$_[1]<<11|64 : 103 + " cmplw ".join(',',$cr,@_); 104 + }; 105 + my $bdnz = sub { 106 + my $f = shift; 107 + my $bo = $f=~/[\+\-]/ ? 16+9 : 16; # optional "to be taken" hint 108 + " bc $bo,0,".shift; 109 + } if ($flavour!~/linux/); 110 + my $bltlr = sub { 111 + my $f = shift; 112 + my $bo = $f=~/\-/ ? 12+2 : 12; # optional "not to be taken" hint 113 + ($flavour =~ /linux/) ? # GNU as doesn't allow most recent hints 114 + " .long ".sprintf "0x%x",19<<26|$bo<<21|16<<1 : 115 + " bclr $bo,0"; 116 + }; 117 + my $bnelr = sub { 118 + my $f = shift; 119 + my $bo = $f=~/\-/ ? 4+2 : 4; # optional "not to be taken" hint 120 + ($flavour =~ /linux/) ? # GNU as doesn't allow most recent hints 121 + " .long ".sprintf "0x%x",19<<26|$bo<<21|2<<16|16<<1 : 122 + " bclr $bo,2"; 123 + }; 124 + my $beqlr = sub { 125 + my $f = shift; 126 + my $bo = $f=~/-/ ? 12+2 : 12; # optional "not to be taken" hint 127 + ($flavour =~ /linux/) ? # GNU as doesn't allow most recent hints 128 + " .long ".sprintf "0x%X",19<<26|$bo<<21|2<<16|16<<1 : 129 + " bclr $bo,2"; 130 + }; 131 + # GNU assembler can't handle extrdi rA,rS,16,48, or when sum of last two 132 + # arguments is 64, with "operand out of range" error. 133 + my $extrdi = sub { 134 + my ($f,$ra,$rs,$n,$b) = @_; 135 + $b = ($b+$n)&63; $n = 64-$n; 136 + " rldicl $ra,$rs,$b,$n"; 137 + }; 138 + my $vmr = sub { 139 + my ($f,$vx,$vy) = @_; 140 + " vor $vx,$vy,$vy"; 141 + }; 142 + 143 + # Some ABIs specify vrsave, special-purpose register #256, as reserved 144 + # for system use. 145 + my $no_vrsave = ($flavour =~ /linux-ppc64le/); 146 + my $mtspr = sub { 147 + my ($f,$idx,$ra) = @_; 148 + if ($idx == 256 && $no_vrsave) { 149 + " or $ra,$ra,$ra"; 150 + } else { 151 + " mtspr $idx,$ra"; 152 + } 153 + }; 154 + my $mfspr = sub { 155 + my ($f,$rd,$idx) = @_; 156 + if ($idx == 256 && $no_vrsave) { 157 + " li $rd,-1"; 158 + } else { 159 + " mfspr $rd,$idx"; 160 + } 161 + }; 162 + 163 + # PowerISA 2.06 stuff 164 + sub vsxmem_op { 165 + my ($f, $vrt, $ra, $rb, $op) = @_; 166 + " .long ".sprintf "0x%X",(31<<26)|($vrt<<21)|($ra<<16)|($rb<<11)|($op*2+1); 167 + } 168 + # made-up unaligned memory reference AltiVec/VMX instructions 169 + my $lvx_u = sub { vsxmem_op(@_, 844); }; # lxvd2x 170 + my $stvx_u = sub { vsxmem_op(@_, 972); }; # stxvd2x 171 + my $lvdx_u = sub { vsxmem_op(@_, 588); }; # lxsdx 172 + my $stvdx_u = sub { vsxmem_op(@_, 716); }; # stxsdx 173 + my $lvx_4w = sub { vsxmem_op(@_, 780); }; # lxvw4x 174 + my $stvx_4w = sub { vsxmem_op(@_, 908); }; # stxvw4x 175 + 176 + # PowerISA 2.07 stuff 177 + sub vcrypto_op { 178 + my ($f, $vrt, $vra, $vrb, $op) = @_; 179 + " .long ".sprintf "0x%X",(4<<26)|($vrt<<21)|($vra<<16)|($vrb<<11)|$op; 180 + } 181 + my $vcipher = sub { vcrypto_op(@_, 1288); }; 182 + my $vcipherlast = sub { vcrypto_op(@_, 1289); }; 183 + my $vncipher = sub { vcrypto_op(@_, 1352); }; 184 + my $vncipherlast= sub { vcrypto_op(@_, 1353); }; 185 + my $vsbox = sub { vcrypto_op(@_, 0, 1480); }; 186 + my $vshasigmad = sub { my ($st,$six)=splice(@_,-2); vcrypto_op(@_, $st<<4|$six, 1730); }; 187 + my $vshasigmaw = sub { my ($st,$six)=splice(@_,-2); vcrypto_op(@_, $st<<4|$six, 1666); }; 188 + my $vpmsumb = sub { vcrypto_op(@_, 1032); }; 189 + my $vpmsumd = sub { vcrypto_op(@_, 1224); }; 190 + my $vpmsubh = sub { vcrypto_op(@_, 1096); }; 191 + my $vpmsumw = sub { vcrypto_op(@_, 1160); }; 192 + my $vaddudm = sub { vcrypto_op(@_, 192); }; 193 + my $vadduqm = sub { vcrypto_op(@_, 256); }; 194 + 195 + my $mtsle = sub { 196 + my ($f, $arg) = @_; 197 + " .long ".sprintf "0x%X",(31<<26)|($arg<<21)|(147*2); 198 + }; 199 + 200 + print "#include <asm/ppc_asm.h>\n" if $flavour =~ /linux/; 201 + 202 + while($line=<>) { 203 + 204 + $line =~ s|[#!;].*$||; # get rid of asm-style comments... 205 + $line =~ s|/\*.*\*/||; # ... and C-style comments... 206 + $line =~ s|^\s+||; # ... and skip white spaces in beginning... 207 + $line =~ s|\s+$||; # ... and at the end 208 + 209 + { 210 + $line =~ s|\b\.L(\w+)|L$1|g; # common denominator for Locallabel 211 + $line =~ s|\bL(\w+)|\.L$1|g if ($dotinlocallabels); 212 + } 213 + 214 + { 215 + $line =~ s|^\s*(\.?)(\w+)([\.\+\-]?)\s*||; 216 + my $c = $1; $c = "\t" if ($c eq ""); 217 + my $mnemonic = $2; 218 + my $f = $3; 219 + my $opcode = eval("\$$mnemonic"); 220 + $line =~ s/\b(c?[rf]|v|vs)([0-9]+)\b/$2/g if ($c ne "." and $flavour !~ /osx/); 221 + if (ref($opcode) eq 'CODE') { $line = &$opcode($f,split(',',$line)); } 222 + elsif ($mnemonic) { $line = $c.$mnemonic.$f."\t".$line; } 223 + } 224 + 225 + print $line if ($line); 226 + print "\n"; 227 + } 228 + 229 + close STDOUT;