Annotation of uae/src/md-68k/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: # 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.