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