Annotation of uae/src/md-68k/cpuopti, revision 1.1.1.1

1.1       root        1: #!/bin/perl
                      2: #
                      3: # Usage: $0 <cpu?.s
                      4: #
                      5: # Small perl script to optimise cpu?.s
                      6: # Note: some optimisations done here are not safe! It is a chance
                      7: # if everything works fine...
                      8: #
                      9: # 05/04/97: Modified to make it work with perl5.
                     10: # 25/10/97: Removed some optimisations suspected to introduce bugs.
                     11: #
                     12: # (c) By Samuel Devulder, 04/97.
                     13: #
                     14: 
                     15: # uncomment the next 2 lines if you experience problems with the
                     16: # optimized code:
                     17: #while(<>) { print; }
                     18: #exit 0;
                     19: 
                     20: ###############################################################################
                     21: 
                     22: if($#ARGV >= $[) {
                     23:     &usage;
                     24: } 
                     25: 
                     26: ###############################################################################
                     27: 
                     28: while(<>) {
                     29:     print;
                     30:     last if /^_op_[0-9a-f]+:$/;
                     31: }
                     32: 
                     33: ###############################################################################
                     34: 
                     35: chop;
                     36: print STDERR "$_\r";
                     37: $num_opt = 0;
                     38: while($last_func = &analyse_function) {
                     39:     while(&optimize_function) {}
                     40:     &dump_function;
                     41:     print $last_func;$_ = $last_func;chop;
                     42:     print STDERR "$_\r";
                     43: }
                     44: while(&optimize_function) {}
                     45: &dump_function;
                     46: 
                     47: print STDERR "$num_opt optimisations\n";
                     48: 
                     49: exit 0;
                     50: 
                     51: ###############################################################################
                     52: 
                     53: sub delete_line {
                     54:     local($i) = @_;
                     55:     for(; $i < $lineno; ++$i) {
                     56:         $line[$i] = $line[1+$i];
                     57:     }
                     58:     $line[--$lineno] = "";
                     59: }
                     60:     
                     61: ###############################################################################
                     62: 
                     63: sub optimize_function {
                     64:     local($i, $j, $ext, $adr, $reg, $opt, $tmp);
                     65:     $opt = $num_opt;
                     66:     for($i = 0; $i < $lineno; ++$i) {
                     67:         study($line[$i]);
                     68:         #################################################################
                     69:         #   INST.x  X,Dn            =>  INST.x  X,Dn
                     70:         #   TST.x   Dn                  <deleted>
                     71:         #################################################################
                     72:         if(($line[$i] =~/(mov[e]?|or|and|add|sub|tst)([bwl])\s+.+,(d[0-7])$/)
                     73:         && ($line[$i+1]=~ /tst$2\s+$3/)) {
                     74:             &delete_line($i+1);
                     75:             ++$num_opt;
                     76:         } 
                     77:         #################################################################
                     78:         #   MOVE.x  Dn,X            =>  MOVE.x  Dn,X
                     79:         #   TST.x   Dn                  <deleted>
                     80:         #################################################################
                     81:         if(($line[$i]  =~ /mov[e]?([bwl])\s+(d[0-7]),(.+)$/)
                     82:         && ($line[$i+1]=~ /tst$1\s+$2/)) {
                     83:             &delete_line($i+1);
                     84:             ++$num_opt;
                     85:         }
                     86:         #################################################################
                     87:         #   MOVE.B  1(An),Dr        =>  MOVE.W  (An)+,Dr
                     88:         #   ADDQ.x  #2,AN               <deleted>
                     89:         # This is allowed since An always points on (B1,B2) With B1==0
                     90:         #################################################################
                     91:         if($line[$i]   =~ /moveb\s+(a[0-7])@\(1\),(d[0-7])$/) {
                     92:             $adr=$1; $reg=$2;
                     93:             if($line[$i+1] =~ /addq.\s+#2,$adr/) {
                     94:                 $line[$i] = "\tmovew $adr@+,$reg\n";
                     95:                 &delete_line($i+1);
                     96:                 ++$num_opt;
                     97:         #################################################################
                     98:         #   CLR.W   Dn              =>  <deleted>
                     99:         #   MOVE.W  X,Dn                MOVE.W  X,Dn
                    100:         #################################################################
                    101:                 if(($i>1) && ($line[$i-1] =~ /clrw\s+$reg/)) {
                    102:                 &delete_line($i-1);
                    103:                 ++$num_opt;
                    104:             }
                    105:         }       
                    106:         }       
                    107:         #################################################################
                    108:         #   TST.x   Dn              =>  MOVE.x  Dn,X
                    109:         #   ..(Dn not used)..           ..(Dn not used)..
                    110:         #   MOVE.x  Dn,X                <deleted>
                    111:         #################################################################
                    112: #        if(($line[$i] =~ /tst([bwl])\s+(d[0-7])$/)) {
                    113: #            $ext = $1; $reg = $2;
                    114: #            $line[$lineno] = "rts"; # sentinel
                    115: #            $tmp = "(^.+:)|rts|\sj.+\s|$reg";
                    116: #            for($j = $i+1; $line[$j] !~ /$tmp/; ++$j) {}
                    117: #            if($line[$j] =~ /mov[e]?$ext\s+$reg,(.+)$/) {
                    118: #                $adr = $1;
                    119: #                $tmp = "";
                    120: #                if($adr =~ /(a[0-7])/) {if($tmp eq "") {$tmp = "$1";} else {$tmp = "$tmp|$1"}}
                    121: #                if($adr =~ /(d[0-7])/) {if($tmp eq "") {$tmp = "$1";} else {$tmp = "$tmp|$1"}}
                    122: #                if(!($tmp eq "")) {
                    123: #                    for($k = $i+1; $k<$j && ($line[$k]!~/$tmp/); ++$k) {}
                    124: #                } else {$k = $j;}
                    125: #                if($k == $j) {
                    126: #                    $line[$i] = $line[$j];
                    127: #                    &delete_line($j);
                    128: #                    ++$num_opt;
                    129: #                }
                    130: #            }
                    131: #        }
                    132:         if($line[$i] =~ /_regs/) { # some speedup
                    133:         #################################################################
                    134:         #   INST   .._regs+N1..     =>  lea     _regs+N2,An
                    135:         #   ..(no refs to _regs)..      INST    ..N1-N2(An)..
                    136:         #   lea     _regs+N2,An         ..(no refs to _regs)..
                    137:         #################################################################
                    138:         if($line[$i] =~ /_regs(\+\d+)?/) {
                    139:             $N1 = $1;
                    140:             $line[$lineno] = "rts"; # sentinel
                    141:             $tmp = "_regs|rts|\s+j.+\s|(^.+:)";
                    142:             for($j = $i+1; $line[$j] !~ /$tmp/; ++$j) {}
                    143:             if($line[$j] =~ /lea\s+_regs(\+\d+)?,(a[0-7])$/) {
                    144:                 $N2 = $1; $An = $2;
                    145:                 for($k = $i; $line[$k] !~ /$An/; $k++) {}
                    146:                 if($k == $j) {
                    147:                     $N1 =~ s/^\+//; $N2 =~ y/+/-/;
                    148:                     $line[$i] =~ s/_regs(\+?)$N1/$An@\($N1$N2\)/g;
                    149:                     $ext = $line[$j];
                    150:                     for($k=$j; $k>$i; --$k) {$line[$k] = $line[$k-1];}
                    151:                     $line[$i] = $ext;
                    152:                     ++$num_opt;
                    153:                 }
                    154:             }
                    155:         }
                    156:         #################################################################
                    157:         #   LEA     _regs+N1,An     =>  LEA     _regs+N1,An
                    158:         #   ..An not modified..         ...
                    159:         #   INST    .._regs+N2..        INST    ..(N2-N1)An..
                    160:         #################################################################
                    161:         if($line[$i] =~ /lea\s+_regs(\+\d+)?,(a[0-7])/) {
                    162:             $N1 = $1;$An = $2;
                    163:             $line[$lineno] = "rts"; # sentinel
                    164:             $tmp = "_regs|$An@[-+]|,$An|\sj.+\s|rts|(^.+:)";
                    165:             for($j = $i+1; $line[$j] !~ /$tmp/; ++$j) {}
                    166:             if($line[$j] =~ /_regs(\+\d+)?/) {
                    167:                 $N2 = $1; $N1 =~ y/+/-/;
                    168:                 $tmp = $N2; $tmp =~ s/[+]/\\+/;
                    169:                 $line[$j] =~ s/_regs$tmp/$An@\($N2$N1\)/g;
                    170:                 $line[$j] =~ s/\(\)//g;
                    171:                 ++$num_opt;
                    172:             }
                    173:         }
                    174:         }
                    175:         #################################################################
                    176:         #   MOVE.x  X,Dp            =>  MOVE.x  X,Dp
                    177:         #   ..Dp not used..             MOVE.W  CCR,Y
                    178:         #   TST.x   Dp                  ..Dp not used..
                    179:         #   MOVE.W  ccr,Y
                    180:         #################################################################
                    181: #        if($line[$i] =~ /mov[e]?([bwl])\s+.+,(d[0-7])$/) {
                    182: #            $ext = $1;$reg = $2;
                    183: #            $line[$lineno] = "rts"; # sentinel
                    184: #            $tmp = "$reg|rts|\sj.+\s|(^.+:)";
                    185: #            for($j = $i+1; $line[$j] !~ /$tmp/; $j++) {}
                    186: #            if(($line[$j] =~ /tst$ext\s+$reg$/)
                    187: #            && ($line[$j+1] =~ /mov[e]?w\s+ccr,/)) {
                    188: #                &delete_line($j);
                    189: #                $ext = $line[$j];
                    190: #                for($k=$j;$k>$i+1;--$k) {$line[$k] = $line[$k-1];}
                    191: #                $line[$i+1] = $ext;
                    192: #                ++$num_opt;
                    193: #            }
                    194: #        }
                    195:         #################################################################
                    196:         # General instruction scheduling optimisation:
                    197:         #   INST1   <memory op>     =>  INST1   <memory op>
                    198:         #   INST2   <memory op>         INST3   [R1,]R2
                    199:         #   INST3   [R1,]R2             INST2   <memory op>
                    200:         #################################################################
                    201:         if(($i>=2)
                    202:         && ($line[$i] =~ /\s+(([ad][0-7]),)?([ad][0-7])$/)
                    203:         && ($line[$i] !~ /^.+:/)
                    204:         && ($line[$i+1] !~ /ccr|jb[^s]/)) {
                    205:             $adr = $2?$2:"a8"; # unused register
                    206:             $reg = $3;
                    207:             study($line[$i-1]);
                    208:             study($line[$i-2]);
                    209:             if(($line[$i-1] =~ /@|_regflags/)
                    210:             && ($line[$i-2] =~ /@|_regflags/)
                    211:             && ($line[$i-1] !~ /(^[^\s]+:)|$adr|$reg|jb|ccr|lea|pea/)
                    212:             && ($line[$i-2] !~ /$adr|$reg|lea|pea/)) {
                    213:                 $tmp        = $line[$i-1];
                    214:                 $line[$i-1] = $line[$i];
                    215:                 $line[$i]   = $tmp;
                    216:                 ++$num_opt;
                    217:             }
                    218:         }
                    219:     }
                    220:     return $num_opt-$opt;
                    221: }
                    222: 
                    223: ###############################################################################
                    224: 
                    225: sub not_used {
                    226:     local($i, $reg) = @_;
                    227: 
                    228:     while($i < $lineno) {
                    229:         $line[$i]=~/$reg/ && return 0;
                    230:         ++$i;
                    231:     }
                    232:     return 1;
                    233: }
                    234: 
                    235: ###############################################################################
                    236: 
                    237: sub not_used_before {
                    238:     local($i, $reg) = @_;
                    239: 
                    240:     while($i--) {
                    241:         $line[$i]=~/$reg/ && return 0;
                    242:     }
                    243:     return 1;
                    244: }
                    245: 
                    246: ###############################################################################
                    247: 
                    248: sub analyse_function {
                    249:     $lineno = 0;
                    250:     while(<>) {
                    251:         next if /^#(NO_)?APP/;
                    252:         last if /^_op_[0-9a-f]+:$/;
                    253:         $line[$lineno++] = $_;
                    254:     }
                    255:     return $_;
                    256: }
                    257: 
                    258: ###############################################################################
                    259: 
                    260: sub dump_function {
                    261:     local($i);
                    262:     for($i=0;$i < $lineno; ++$i) {
                    263:         print $line[$i];
                    264:     }
                    265: }
                    266: 
                    267: ###############################################################################
                    268: 
                    269: sub usage {
                    270:     open(FILE,__FILE__);
                    271:     open(OUT,"|less");
                    272:     <FILE>;
                    273:     while(<FILE>) {
                    274:         last if !/^#/;
                    275:         s/^#[ ]?//;
                    276:         s/\$0/$0/;
                    277:         print OUT;
                    278:     }
                    279:     close OUT;
                    280:     exit;
                    281: }
                    282:     
                    283: ###############################################################################
                    284:     

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.