Annotation of uae/src/md-amiga/cpuopti, revision 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: # (c) By Samuel Devulder, 01/97.
        !            10: #
        !            11: 
        !            12: #while(<>) { print; }
        !            13: #exit 0;
        !            14: 
        !            15: ###############################################################################
        !            16: 
        !            17: if($#ARGV >= $[) {
        !            18:     &usage;
        !            19: } 
        !            20: 
        !            21: ###############################################################################
        !            22: 
        !            23: while(<>) {
        !            24:     print;
        !            25:     last if /^_op_[0-9a-f]+:$/;
        !            26: }
        !            27: 
        !            28: ###############################################################################
        !            29: 
        !            30: chop;
        !            31: print STDERR "$_\r";
        !            32: $num_opt = 0;
        !            33: while($last_func = &analyse_function) {
        !            34:     while(&optimize_function) {}
        !            35:     &dump_function;
        !            36:     print $last_func;$_ = $last_func;chop;
        !            37:     print STDERR "$_\r";
        !            38: }
        !            39: while(&optimize_function) {}
        !            40: &dump_function;
        !            41: 
        !            42: print STDERR "$num_opt optimisations\n";
        !            43: 
        !            44: exit 0;
        !            45: 
        !            46: ###############################################################################
        !            47: 
        !            48: sub delete_line {
        !            49:     local($i) = @_;
        !            50:     for(; $i < $lineno; ++$i) {
        !            51:         $line[$i] = $line[1+$i];
        !            52:     }
        !            53:     $line[--$lineno] = "";
        !            54: }
        !            55:     
        !            56: ###############################################################################
        !            57: 
        !            58: sub optimize_function {
        !            59:     local($i, $j, $ext, $adr, $reg, $opt, $tmp);
        !            60:     $opt = $num_opt;
        !            61:     for($i = 0; $i < $lineno; ++$i) {
        !            62:         #################################################################
        !            63:         #   INST.x  X,Dn            =>  INST.x  X,Dn
        !            64:         #   TST.x   Dn                  <deleted>
        !            65:         #################################################################
        !            66:         if(($line[$i] =~/(mov[e]?|or|and|add|sub|tst)([bwl])\s+.+,(d[0-7])$/)
        !            67:         && ($line[$i+1]=~ /tst$2\s+$3/)) {
        !            68:             &delete_line($i+1);
        !            69:             ++$num_opt;
        !            70:         } 
        !            71:         #################################################################
        !            72:         #   MOVE.x  Dn,X            =>  MOVE.x  Dn,X
        !            73:         #   TST.x   Dn                  <deleted>
        !            74:         #################################################################
        !            75:         if(($line[$i]  =~ /mov[e]?([bwl])\s+(d[0-7]),(.+)$/)
        !            76:         && ($line[$i+1]=~ /tst$1\s+$2/)) {
        !            77:             &delete_line($i+1);
        !            78:             ++$num_opt;
        !            79:         }
        !            80:         #################################################################
        !            81:         #   MOVE.B  1(An),Dr        =>  MOVE.W  (An)+,Dr
        !            82:         #   ADDQ.x  #2,AN               <deleted>
        !            83:         # This is allowed since An always points on (B1,B2) With B1==0
        !            84:         #################################################################
        !            85:         if(($line[$i]   =~ /moveb\s+(a[0-7])@\(1\),(d[0-7])$/)
        !            86:         && ($line[$i+1] =~ /addq.\s+#2,$1/)) {
        !            87:             $line[$i] = "\tmovew $1@+,$2\n";
        !            88:             &delete_line($i+1);
        !            89:             ++$num_opt;
        !            90:         #################################################################
        !            91:         #   CLR.W   Dn              =>  <deleted>
        !            92:         #   MOVE.W  X,Dn                MOVE.W  X,Dn
        !            93:         #################################################################
        !            94:             if(($i>1) && ($line[$i-1] =~ /clrw\s+$2/)) {
        !            95:                 &delete_line($i-1);
        !            96:                 ++$num_opt;
        !            97:             }
        !            98:         }       
        !            99:         #################################################################
        !           100:         #   INST.x  X,Dn            =>  INST.x  Dn,X
        !           101:         #   ..(Dn not used)..           ..(Dn not used)..
        !           102:         #   MOVE.x  Dn,X                <deleted>
        !           103:         #   ..Dn dead..
        !           104:         # INST = or | and | add
        !           105:         #################################################################
        !           106: # too much unsafe
        !           107: #        if(($line[$i] =~ /(or|and|add)([bwl])\s+(.+),(d[2-7])$/)) {
        !           108: #            $ext = $2; $adr = $3; $reg = $4;
        !           109: #            $adr =~s/([()])/\\\1/g;
        !           110: #            $tmp = "$reg|\sj.+\s|rts|(^.+:)";
        !           111: #            #            ^       ^   ^
        !           112: #            #         No jump nor rts nor label
        !           113: #            for($j = $i+1; $line[$j] !~ /$tmp/; ++$j) {}
        !           114: #            if($line[$j] =~ /mov[e]?$ext\s+$reg,$adr$/) {
        !           115: #                $line[$i] =~ s/($adr),($reg)$/ \2,\1/;
        !           116: #                &delete_line($j);
        !           117: #                ++$num_opt;
        !           118: #            }
        !           119: #        }
        !           120:         #################################################################
        !           121:         #   MOVE.x  X,Dn            =>  MOVE.x  X,Y
        !           122:         #   ..(Dn not used)..           ..(Dn not used)..
        !           123:         #   MOVE.x  Dn,Y                <deleted>
        !           124:         # The ..(Dn ...).. part must not modify regs of Y
        !           125:         #################################################################
        !           126: #        if(($line[$i] =~ /mov[e]?([bwl])\s+.+,(d[2-7])$/)) {
        !           127: #            $ext = $1; $reg = $2;
        !           128: #            $tmp = "$reg|(^\sj.+\s)|rts|(^.+:)";
        !           129: #            for($j = $i+1; $line[$j] !~ /$tmp/; ++$j) {}
        !           130: #            if($line[$j] =~ /mov[e]?$ext\s+$reg,(.+)$/) {
        !           131: #                $adr = $1;
        !           132: #                $tmp = "";
        !           133: #                if($adr =~ /(a[0-7])/) {if($tmp eq "") {$tmp = "$1";} else {$tmp = "$tmp|$1"}}
        !           134: #                if($adr =~ /(d[0-7])/) {if($tmp eq "") {$tmp = "$1";} else {$tmp = "$tmp|$1"}}
        !           135: #                if(!($tmp eq "")) {
        !           136: #                    for($k = $i+1; $k<$j && ($line[$k]!~/$tmp/); ++$k) {}
        !           137: #                } else {$k = $j;}
        !           138: #                if($k == $j) {
        !           139: #                    $line[$i] =~ s/,$reg$/,$adr/;
        !           140: #                    &delete_line($j);
        !           141: #                    ++$num_opt;
        !           142: #                }
        !           143: #            }
        !           144: #        }
        !           145:         #################################################################
        !           146:         #   TST.x   Dn              =>  MOVE.x  Dn,X
        !           147:         #   ..(Dn not used)..           ..(Dn not used)..
        !           148:         #   MOVE.x  Dn,X                <deleted>
        !           149:         #################################################################
        !           150:         if(($line[$i] =~ /tst([bwl])\s+(d[0-7])$/)) {
        !           151:             $ext = $1; $reg = $2;
        !           152:             $line[$lineno] = "rts"; # sentinel
        !           153:             $tmp = "(^.+:)|rts|\sj.+\s|$reg";
        !           154:             for($j = $i+1; $line[$j] !~ /$tmp/; ++$j) {}
        !           155:             if($line[$j] =~ /mov[e]?$ext\s+$reg,(.+)$/) {
        !           156:                 $adr = $1;
        !           157:                 $tmp = "";
        !           158:                 if($adr =~ /(a[0-7])/) {if($tmp eq "") {$tmp = "$1";} else {$tmp = "$tmp|$1"}}
        !           159:                 if($adr =~ /(d[0-7])/) {if($tmp eq "") {$tmp = "$1";} else {$tmp = "$tmp|$1"}}
        !           160:                 if(!($tmp eq "")) {
        !           161:                     for($k = $i+1; $k<$j && ($line[$k]!~/$tmp/); ++$k) {}
        !           162:                 } else {$k = $j;}
        !           163:                 if($k == $j) {
        !           164:                     $line[$i] = $line[$j];
        !           165:                     &delete_line($j);
        !           166:                     ++$num_opt;
        !           167:                 }
        !           168:             }
        !           169:         }
        !           170:         if($line[$i] =~ /_regs/) { # some speedup
        !           171:         #################################################################
        !           172:         #   movel   X,_regs+N1      => <deleted>
        !           173:         #   ...no refs to _regs+N1..   ..stuff..
        !           174:         #   movel   Y,_regs+N1         movel    Y,_regs+N1
        !           175:         #################################################################
        !           176:         if($line[$i] =~ /movel\s+.+,_regs(.*)$/) {
        !           177:             $N1 = $1; $N1 =~ s/^[+]/\\+/;
        !           178:             $line[$lineno] = "_regs$1"; # sentinel
        !           179:             $tmp = "_regs$N1|\sj.+\s|rts|(^.+:)";
        !           180:             for($k=$i+1;$line[$k] !~ /$tmp/;++$k) {}
        !           181:             if($line[$k] =~ /movel\s+.+,_regs$N1$/) {
        !           182:                 &delete_line($i);
        !           183:                 ++$num_opt;
        !           184:             }
        !           185:         }
        !           186:         #################################################################
        !           187:         #   INST   .._regs+N1..     =>  lea     _regs+N2,An
        !           188:         #   ..(no refs to _regs)..      INST    ..N1-N2(An)..
        !           189:         #   lea     _regs+N2,An         ..(no refs to _regs)..
        !           190:         #################################################################
        !           191:         if($line[$i] =~ /_regs(\+\d+)?/) {
        !           192:             $N1 = $1;
        !           193:             $line[$lineno] = "rts"; # sentinel
        !           194:             $tmp = "_regs|rts|\s+j.+\s|(^.+:)";
        !           195:             for($j = $i+1; $line[$j] !~ /$tmp/; ++$j) {}
        !           196:             if($line[$j] =~ /lea\s+_regs(\+\d+)?,(a[0-7])$/) {
        !           197:                 $N2 = $1; $An = $2;
        !           198:                 for($k = $i; $line[$k] !~ /$An/; $k++) {}
        !           199:                 if($k == $j) {
        !           200:                     $N1 =~ s/^\+//; $N2 =~ y/+/-/;
        !           201:                     $line[$i] =~ s/_regs(\+?)$N1/$An@\($N1$N2\)/g;
        !           202:                     $ext = $line[$j];
        !           203:                     for($k=$j; $k>$i; --$k) {$line[$k] = $line[$k-1];}
        !           204:                     $line[$i] = $ext;
        !           205:                     ++$num_opt;
        !           206:                 }
        !           207:             }
        !           208:         }
        !           209:         #################################################################
        !           210:         #   LEA     _regs+N1,An     =>  LEA     _regs+N1,An
        !           211:         #   ..An not modified..         ...
        !           212:         #   INST    .._regs+N2..        INST    ..(N2-N1)An..
        !           213:         #################################################################
        !           214:         if($line[$i] =~ /lea\s+_regs(\+\d+)?,(a[0-7])/) {
        !           215:             $N1 = $1;$An = $2;
        !           216:             $line[$lineno] = "rts"; # sentinel
        !           217:             $tmp = "_regs|$An@[-+]|,$An|\sj.+\s|rts|(^.+:)";
        !           218:             for($j = $i+1; $line[$j] !~ /$tmp/; ++$j) {}
        !           219:             if($line[$j] =~ /_regs(\+\d+)?/) {
        !           220:                 $N2 = $1; $N1 =~ y/+/-/;
        !           221:                 $tmp = $N2; $tmp =~ s/[+]/\\+/;
        !           222:                 $line[$j] =~ s/_regs$tmp/$An@\($N2$N1\)/g;
        !           223:                 $line[$j] =~ s/\(\)//g;
        !           224:                 ++$num_opt;
        !           225:             }
        !           226:         }
        !           227:         #################################################################
        !           228:         #   ..<A1> not used..           ..<A1> not used..
        !           229:         #   MOVE.L  _regs+N1,A0     =>  MOVE.L  _regs+N1,A1
        !           230:         #   MOVE.x  (A0)+,Dp            MOVE.x  (A1)+,Dp
        !           231:         #   MOVE.L  A0,_regs+N          MOVE.L  A1,_regs+N1
        !           232:         #   LEA     _regs+N2,A0          LEA     _regs+N2,A0
        !           233:         #################################################################
        !           234:         if(($line[$i] =~ /mov[e]?l\s+_regs(\+\d+)?,a0$/)
        !           235:         && &not_used_before($i,"a1")) {
        !           236:             if(($line[$i+1] =~ /mov[e]?[bwl]\s+a0@\+,d[0-7]$/)
        !           237:             && ($line[$i+2] =~ /mov[e]?l\s+a0,_regs(\+\d+)?/)
        !           238:             && ($line[$i+3] =~ /lea\s+_regs(\+\d+)?,a0/)) {
        !           239:                 $line[$i]   =~ s/a0/a1/;
        !           240:                 $line[$i+1] =~ s/a0/a1/;
        !           241:                 $line[$i+2] =~ s/a0/a1/;
        !           242:                 ++$num_opt;
        !           243:             }
        !           244:         }
        !           245:         }
        !           246:         #################################################################
        !           247:         #   MOVE.x  X,Dp            =>  MOVE.x  X,Dp
        !           248:         #   ..Dp not used..             MOVE.W  CCR,Y
        !           249:         #   TST.x   Dp                  ..Dp not used..
        !           250:         #   movew   ccr,Y
        !           251:         #################################################################
        !           252:         if($line[$i] =~ /mov[e]?([bwl])\s+.+,(d[0-7])$/) {
        !           253:             $ext = $1;$reg = $2;
        !           254:             $line[$lineno] = "rts"; # sentinel
        !           255:             $tmp = "$reg|rts|\sj.+\s|(^.+:)";
        !           256:             for($j = $i+1; $line[$j] !~ /$tmp/; $j++) {}
        !           257:             if(($line[$j] =~ /tst$ext\s+$reg$/)
        !           258:             && ($line[$j+1] =~ /mov[e]?w\s+ccr,/)) {
        !           259:                 &delete_line($j);
        !           260:                 $ext = $line[$j];
        !           261:                 for($k=$j;$k>$i+1;--$k) {$line[$k] = $line[$k-1];}
        !           262:                 $line[$i+1] = $ext;
        !           263:                 ++$num_opt;
        !           264:             }
        !           265:         }
        !           266:     }
        !           267:     return $num_opt-$opt;
        !           268: }
        !           269: 
        !           270: ###############################################################################
        !           271: 
        !           272: sub not_used {
        !           273:     local($i, $reg) = @_;
        !           274: 
        !           275:     while($i < $lineno) {
        !           276:         $line[$i]=~/$reg/ && return 0;
        !           277:         ++$i;
        !           278:     }
        !           279:     return 1;
        !           280: }
        !           281: 
        !           282: ###############################################################################
        !           283: 
        !           284: sub not_used_before {
        !           285:     local($i, $reg) = @_;
        !           286: 
        !           287:     while($i--) {
        !           288:         $line[$i]=~/$reg/ && return 0;
        !           289:     }
        !           290:     return 1;
        !           291: }
        !           292: 
        !           293: ###############################################################################
        !           294: 
        !           295: sub analyse_function {
        !           296:     $lineno = 0;
        !           297:     while(<>) {
        !           298:         next if /^#(NO_)?APP/;
        !           299:         last if /^_op_[0-9a-f]+:$/;
        !           300:         $line[$lineno++] = $_;
        !           301:     }
        !           302:     return $_;
        !           303: }
        !           304: 
        !           305: ###############################################################################
        !           306: 
        !           307: sub dump_function {
        !           308:     local($i);
        !           309:     for($i=0;$i < $lineno; ++$i) {
        !           310:         print $line[$i];
        !           311:     }
        !           312: }
        !           313: 
        !           314: ###############################################################################
        !           315: 
        !           316: sub usage {
        !           317:     open(FILE,__FILE__);
        !           318:     open(OUT,"|less");
        !           319:     <FILE>;
        !           320:     while(<FILE>) {
        !           321:         last if !/^#/;
        !           322:         s/^#[ ]?//;
        !           323:         s/\$0/$0/;
        !           324:         print OUT;
        !           325:     }
        !           326:     close OUT;
        !           327:     exit;
        !           328: }
        !           329:     
        !           330: ###############################################################################
        !           331:     

unix.superglobalmegacorp.com

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