]> git.sur5r.net Git - cc65/blobdiff - src/cc65/optimize.c
Added the io module
[cc65] / src / cc65 / optimize.c
index dce39dbac5956c5b739db30d6af0093db6d50005..48ce3fbb61233acae5c3c8dd4c2f05f0f501069d 100644 (file)
 
 
 #include <stdarg.h>
+#include <stdio.h>
 #include <string.h>
 #include <ctype.h>
 
+/* common */
+#include "attrib.h"
+#include "xmalloc.h"
+
+/* cc65 */
 #include "asmlabel.h"
 #include "asmline.h"
 #include "check.h"
 #include "cpu.h"
 #include "error.h"
 #include "global.h"
-#include "io.h"
-#include "mem.h"
 #include "optimize.h"
 
 
@@ -125,7 +129,7 @@ static const struct {
     { "\tcpx\t",                 0,    REG_X,      REG_NONE      },
     { "\tcpy\t",                 0,    REG_Y,      REG_NONE      },
     { "\tdea",           1,    REG_A,      REG_NONE      },
-    { "\tdec\ta",        1,    REG_A,      REG_NONE      },
+    { "\tdec\ta",        1,    REG_A,      REG_NONE      },
     { "\tdec\t",                 0,    REG_NONE,   REG_NONE      },
     { "\tdex",                   1,    REG_X,      REG_NONE      },
     { "\tdey",                   1,    REG_Y,      REG_NONE      },
@@ -225,7 +229,7 @@ static const char* LongBranches [] = {
 
 
 /*****************************************************************************/
-/*                                        Forwards                                  */
+/*                                        Forwards                                  */
 /*****************************************************************************/
 
 
@@ -242,10 +246,19 @@ static unsigned GetLabelNum (const char* L);
 static unsigned RVUInt1 (Line* L, LineColl* LC, unsigned Used, unsigned Unused);
 /* Subfunction for RegValUsed. Will be called recursively in case of branches. */
 
+static Line* NewLineAfter (Line* LineBefore, const char* Format, ...) attribute ((format(printf,2,3)));
+/* Create a new line, insert it after L and return it. The new line is marked
+ * as code line.
+ */
+
+static Line* ReplaceLine (Line* L, const char* Format, ...)
+       attribute ((format(printf,2,3)));
+/* Replace one line by another */
+
 
 
 /*****************************************************************************/
-/*                                       List stuff                                 */
+/*                                       List stuff                                 */
 /*****************************************************************************/
 
 
@@ -1218,7 +1231,7 @@ static unsigned RegValUsed (Line* Start)
  * If the end of the lookahead is reached, all registers that are uncertain
  * are marked as used.
  * The result of the search is returned.
- */                                                            
+ */
 {
     unsigned R;
 
@@ -1844,8 +1857,8 @@ static int OptPtrOps1 (Line** Start)
            /* Cannot get lines */
            return 0;
        }
-       if (LineFullMatch (L2[3], "\tclc")                      &&
-           LineMatch (L2[4], "\tadc\t#$")                      &&
+       if (LineFullMatch (L2[3], "\tclc")                      &&
+           LineMatch (L2[4], "\tadc\t#$")                      &&
            LineFullMatch (L2[5], "\tbcc\t*+3")                 &&
            LineFullMatch (L2[6], "\tinx")) {
            /* Inlined increment */
@@ -1859,9 +1872,9 @@ static int OptPtrOps1 (Line** Start)
     }
 
     /* Check for the remainder */
-    if (!LineMatch (L3[0], "\tsta\t")                          ||
+    if (!LineMatch (L3[0], "\tsta\t")                          ||
        strcmp (L3[0]->Line+5, L->Line+5) != 0                  ||
-       !LineMatch (L3[1], "\tstx\t")                           ||
+       !LineMatch (L3[1], "\tstx\t")                           ||
        strcmp (L3[1]->Line+5, L2[0]->Line+5) != 0              ||
        !LineFullMatch (L3[2], "\tlda\tregsave")                ||
        !LineFullMatch (L3[3], "\tldx\tregsave+1")) {
@@ -1871,18 +1884,14 @@ static int OptPtrOps1 (Line** Start)
     }
 
     /* Check if AX is actually used following the code above. If not,
-     * we don't need to load A/X from regsave. Since X will never by
+     * we don't need to load A/X from regsave. Since X will never be
      * used without A, check just for A.
      */
-    NeedLoad = 1;
-    if (!RegAUsed (L3[3])) {
-       /* We don't need to load regsave */
-       NeedLoad = 0;
-    }
+    NeedLoad = RegAUsed (L3[3]);
 
     /* Special code for register variables */
     Done = 0;
-    if (LineMatch (L, "\tlda\tregbank+")       &&
+    if (LineMatch (L, "\tlda\tregbank+")       &&
                GetNextCodeLines (L3[3], &L3[4], 1)     &&
        Inc == 1) {
 
@@ -2041,8 +2050,8 @@ static int OptPtrOps1 (Line** Start)
 
        /* If we need to load a/x, add the code */
        if (NeedLoad) {
-           L = NewLineAfter (L, "\ttax");
            L = NewLineAfter (L, "\tlda\tptr1");
+           L = NewLineAfter (L, "\tldx\tptr1+1");
        }
     }
 
@@ -2156,11 +2165,7 @@ static int OptPtrOps2 (Line** Start)
      * we don't need to load A/X from regsave. Since X will never by
      * used without A, check just for A.
      */
-    NeedLoad = 1;
-    if (!RegAUsed (L3[0])) {
-       /* We don't need to load regsave */
-       NeedLoad = 0;
-    }
+    NeedLoad = RegAUsed (L3[0]);
 
     /* Replace the ldy instruction, offset must point to the low byte */
     sprintf (L->Line+7, "%02X", Offs);
@@ -2250,8 +2255,8 @@ static int OptPtrOps2 (Line** Start)
 
     /* If we need to load a/x, add the code */
     if (NeedLoad) {
-       L = NewLineAfter (L, "\ttax");
        L = NewLineAfter (L, "\tlda\tptr1");
+       L = NewLineAfter (L, "\tldx\tptr1+1");
     }
 
     /* Remove the code that is no longer needed */
@@ -3635,6 +3640,9 @@ static Line* OptOneBlock (Line* L)
                }
            }
                } else if (LineMatch (L, "\tadc\t")) {
+           if (CPU == CPU_65C02 && Y == 0 && L->Line[5] == '(' && IsYAddrMode(L)) {
+               L->Line[strlen(L->Line)-2] = '\0';
+           }
            A = -1;
        } else if (LineMatch (L, "\tand\t")) {
            A = -1;
@@ -3642,7 +3650,10 @@ static Line* OptOneBlock (Line* L)
            if (A != -1) {
                A = (A << 1) & 0xFF;
            }
-       } else if (CPU == CPU_65C02 && LineFullMatch (L, "\tdea")) {
+               } else if (CPU == CPU_65C02 && Y == 0 && L->Line[5] == '(' && IsYAddrMode(L)) {
+           L->Line[strlen(L->Line)-2] = '\0';
+       } else if (CPU == CPU_65C02 && (LineFullMatch (L, "\tdea") ||
+                                       LineFullMatch (L, "\tdec\ta"))) {
            DEC (A, 1);
        } else if (LineFullMatch (L, "\tdex")) {
            DEC (X, 1);
@@ -3650,7 +3661,8 @@ static Line* OptOneBlock (Line* L)
            DEC (Y, 1);
        } else if (LineMatch (L, "\teor")) {
            A = -1;
-       } else if (CPU == CPU_65C02 && LineFullMatch (L, "\tina")) {
+       } else if (CPU == CPU_65C02 && (LineFullMatch (L, "\tina") ||
+                                       LineFullMatch (L, "\tinc\ta"))) {
            INC (A, 1);
        } else if (LineFullMatch (L, "\tinx")) {
            INC (X, 1);
@@ -4092,6 +4104,9 @@ static Line* OptOneBlock (Line* L)
        } else if (LineFullMatch (L, "\trti")) {
            A = X = Y = -1;
        } else if (LineMatch (L, "\tsbc\t")) {
+           if (CPU == CPU_65C02 && Y == 0 && L->Line[5] == '(' && IsYAddrMode(L)) {
+               L->Line[strlen(L->Line)-2] = '\0';
+           }
            A = -1;
        } else if (CPU == CPU_65C02 && LineMatch (L, "\tst")) {
            /* Try to replace by stz if possible */
@@ -4099,7 +4114,7 @@ static Line* OptOneBlock (Line* L)
                /* Not indirect and not Y allowed */
                if (L->Line[5] != '(' && !IsYAddrMode (L)) {
                    L->Line[3] = 'z';
-               }
+               }
            } else if (X == 0 && LineMatch (L, "\tstx\t")) {
                /* absolute,y not allowed */
                if (!IsYAddrMode (L)) {