
 *|   Version 0.09
 *|   Must be run before asmtidy and preferably after fpinline.
 *|   Optymyze is designed to spot some of the more obvious
 *|     optimisations that stupid GCC misses.
 *|   It's also been upgraded to spot some soft-float optimisations.
 *|   This is not really expected to work with anything other
 *|     than ARM GCC versions 2.95.2 and 2.95.4
 *|   I accept no responsibility for it being useless.
 *|   I make no excuses for it being ugly either.  :-)
 *|         <mech@toth.org.uk> 2001, 2002

 ONERROR PRINTREPORT$+" at "+STR$ERL:END

 SYS "OS_GetEnv" TO env$
 pos%=INSTR(env$,"optymyze")+9
 name$=RIGHT$(env$,LENenv$-pos%)
 fh%=OPENIN name$
 sz%=EXT#fh%
 CLOSE#fh%
 DIM in% sz%
 SYS "OS_File", 255, name$, in%
 out%=OPENOUT name$

 ONERROR CLOSE#out%:PRINTREPORT$+" at "+STR$ERL:END

 sv%=0:pos%=0:lastline$="":line$=""
 REPEAT
 lastline$=line$
 line$="":REPEATchr$=CHR$(in%?pos%):line$+=chr$:pos%+=1:UNTIL chr$=CHR$10 OR pos%=sz%
 line$=LEFT$(line$)
 test1$=MID$(lastline$,2,4)
 IF (test1$="rsb"+CHR$9 OR test1$="add"+CHR$9 OR test1$="sub"+CHR$9 OR test1$="and"+CHR$9 OR test1$="eor"+CHR$9 OR test1$="orr"+CHR$9 OR test1$="bic"+CHR$9 OR test1$="mov"+CHR$9) AND MID$(line$,2,4)="cmp"+CHR$9 AND MID$(line$,6,4)=MID$(lastline$,6,4) AND MID$(line$,12,2)="#0" THEN
    line$=LEFT$(lastline$,4)+"s"+RIGHT$(lastline$,LENlastline$-4)
    sv%+=1
 ELSE
    IF test1$="str"+CHR$9 AND MID$(line$,2,4)="ldr"+CHR$9 AND RIGHT$(lastline$,LENlastline$-9)=RIGHT$(line$,LENline$-9) AND RIGHT$(line$)="]" THEN
       IF MID$(line$,6,4)=MID$(lastline$,6,4) THEN
          line$=lastline$
          sv%+=1
       ELSE
          BPUT#out%,lastline$
          line$=" mov "+MID$(line$,6,4)+", "+MID$(lastline$,6,4)
          REMPRINT "LDR replaced with MOV"
       ENDIF
    ELSE
       IF test1$="ldr"+CHR$9 AND MID$(line$,2,4)="ldr"+CHR$9 AND RIGHT$(lastline$,LENlastline$-9)=RIGHT$(line$,LENline$-9) AND RIGHT$(line$)="]" AND MID$(line$,13,4)<>MID$(lastline$,6,4) THEN
          BPUT#out%,lastline$
          line$=" mov "+MID$(line$,6,4)+", "+MID$(lastline$,6,4)
          REMPRINT "LDR replaced with MOV"
       ELSE
          IF MID$(line$,2,5) = "mvfd"+CHR$9 AND MID$(line$,7,4)=MID$(line$,13,4) THEN
             line$=lastline$
             REMPRINT "FP instruction removed":sv%+=1
          ELSE
             IF lastline$=CHR$9+"mov"+CHR$9+"__a4, __a2" AND line$=CHR$9+"mov"+CHR$9+"__a3, __a1" THEN
                t1pos%=  pos%:line1$="":REPEATchr$=CHR$(in%?t1pos%):line1$+=chr$:t1pos%+=1:UNTIL chr$=CHR$10 OR t1pos%=sz%
                t2pos%=t1pos%:line2$="":REPEATchr$=CHR$(in%?t2pos%):line2$+=chr$:t2pos%+=1:UNTIL chr$=CHR$10 OR t2pos%=sz%
                t3pos%=t2pos%:line3$="":REPEATchr$=CHR$(in%?t3pos%):line3$+=chr$:t3pos%+=1:UNTIL chr$=CHR$10 OR t3pos%=sz%
                line1$=LEFT$(line1$)
                line2$=LEFT$(line2$)
                line3$=LEFT$(line3$)
                IF (INSTR(line1$,(CHR$9+"mov"+CHR$9+"__a2, __")) <>0) AND (INSTR(line2$,(CHR$9+"mov"+CHR$9+"__a1, __")) <>0) AND (line3$=CHR$9+"bl"+CHR$9+"|__adddf3|" OR line3$=CHR$9+"bl"+CHR$9+"|__muldf3|" OR line3$=CHR$9+"bl"+CHR$9+"|__subdf3|") THEN
                   BPUT#out%,CHR$9+"mov"+CHR$9+"__a3, __"+MID$(line2$,14,2)
                   BPUT#out%,CHR$9+"mov"+CHR$9+"__a4, __"+MID$(line1$,14,2)
                   IF line3$=CHR$9+"bl"+CHR$9+"|__subdf3|" THEN
                      BPUT#out%,line3$
                      line$=CHR$9+"eor"+CHR$9+"__a1, __a1, #1<<31"
                      sv%+=1
                   ELSE
                      line$=line3$
                      sv%+=2
                   ENDIF
                   pos%=t3pos%
                ELSE
                   IF MID$(line1$,2,3)="ldm" AND MID$(line1$,14,11)="{__a1-__a2}" AND (line2$=CHR$9+"bl"+CHR$9+"|__adddf3|" OR line2$=CHR$9+"bl"+CHR$9+"|__muldf3|" OR line2$=CHR$9+"bl"+CHR$9+"|__subdf3|") THEN
                      BPUT#out%,MID$(line1$,1,14)+"__a3 - __a4}"
                      IF line2$=CHR$9+"bl"+CHR$9+"|__subdf3|" THEN
                         BPUT#out%,line2$
                         line$=CHR$9+"eor"+CHR$9+"__a1, __a1, #1<<31"
                         sv%+=1
                      ELSE
                         line$=line2$
                         sv%+=2
                      ENDIF
                      pos%=t2pos%
                   ELSE
                      IF MID$(line2$,2,3)="ldm" AND MID$(line2$,14,11)="{__a1-__a2}" AND (line3$=CHR$9+"bl"+CHR$9+"|__adddf3|" OR line3$=CHR$9+"bl"+CHR$9+"|__muldf3|" OR line3$=CHR$9+"bl"+CHR$9+"|__subdf3|") AND (INSTR(line1$,"__a")=0) THEN
                         BPUT#out%,line1$
                         BPUT#out%,MID$(line2$,1,14)+"__a3 - __a4}"
                         IF line3$=CHR$9+"bl"+CHR$9+"|__subdf3|" THEN
                            BPUT#out%,line3$
                            line$=CHR$9+"eor"+CHR$9+"__a1, __a1, #1<<31"
                            sv%+=1
                         ELSE
                            line$=line3$
                            sv%+=2
                         ENDIF
                         pos%=t3pos%
                      ELSE
                         IF line1$=CHR$9+"bl"+CHR$9+"|__adddf3|" THEN
                            BPUT#out%,(CHR$9+"movs"+CHR$9+"__a4, __a1, lsl #1")
                            BPUT#out%,(CHR$9+"addne"+CHR$9+"__a1, __a1, #1")
                            line$=line2$
                            pos%=t2pos%
                            REMPRINT "Twotimes fiddle"
                         ELSE
                            IF line1$=CHR$9+"bl"+CHR$9+"|__muldf3|" THEN
                               BPUT#out%,(CHR$9+"bl"+CHR$9+"|__squaredf|")
                               line$=line2$
                               pos%=t2pos%
                               REMPRINT "Squaring detected":sv%+=2
                            ELSE
                               IF lastline$<>"" BPUT#out%,lastline$
                            ENDIF
                         ENDIF
                      ENDIF
                   ENDIF
                ENDIF
             ELSE
                IF lastline$<>"" BPUT#out%,lastline$
             ENDIF
          ENDIF
       ENDIF
    ENDIF
 ENDIF
 UNTILpos%=sz%
 BPUT#out%,line$
 CLOSE#out%
 IF sv%<>0 AND sv%>1 PRINT sv% " instructions saved"
 IF sv%<>0 AND sv%=1 PRINT sv% " instruction saved"
 END
