]> git.sur5r.net Git - cc65/blobdiff - src/cc65/coptadd.c
Comment and indentation changes
[cc65] / src / cc65 / coptadd.c
index 7e9f92d6c9ac14b68c2af040ce8249738f1f3073..d490574d9cdff5dd96091097d4d017bf41945c22 100644 (file)
@@ -6,7 +6,7 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2001      Ullrich von Bassewitz                                       */
+/* (C) 2001-2002 Ullrich von Bassewitz                                       */
 /*               Wacholderweg 14                                             */
 /*               D-70597 Stuttgart                                           */
 /* EMail:        uz@cc65.org                                                 */
@@ -34,7 +34,7 @@
 
 
 /* common */
-#include "xsprintf.h"
+#include "chartype.h"
 
 /* cc65 */
 #include "codeent.h"
 unsigned OptAdd1 (CodeSeg* S)
 /* Search for the sequence
  *
- *             jsr     pushax
- *      ldy     xxx
- *     ldx     #$00
- *      lda     (sp),y
+ *      ldy     #xx
+ *      jsr     ldaxysp
+ *      jsr     pushax
+ *      ldy     #yy
+ *      jsr     ldaxysp
  *      jsr     tosaddax
  *
  * and replace it by:
  *
- *      ldy     xxx-2
+ *      ldy     #xx-1
+ *      lda     (sp),y
  *      clc
+ *      ldy     #yy-3
  *      adc     (sp),y
- *      bcc     L
- *      inx
- * L:
+ *      pha
+ *      ldy     #xx
+ *      lda     (sp),y
+ *      ldy     #yy-2
+ *      adc     (sp),y
+ *      tax
+ *      pla
  */
 {
     unsigned Changes = 0;
@@ -74,58 +81,78 @@ unsigned OptAdd1 (CodeSeg* S)
     unsigned I = 0;
     while (I < CS_GetEntryCount (S)) {
 
-       CodeEntry* L[5];
+       CodeEntry* L[6];
 
        /* Get next entry */
-               CodeEntry* E = CS_GetEntry (S, I);
+               L[0] = CS_GetEntry (S, I);
 
        /* Check for the sequence */
-               if (CE_IsCall (E, "pushax")          &&
-                   CS_GetEntries (S, L, I+1, 5)     &&
-                   L[0]->OPC == OP65_LDY            &&
+               if (L[0]->OPC == OP65_LDY            &&
            CE_KnownImm (L[0])               &&
-           !CE_HasLabel (L[0])              &&
-           L[1]->OPC == OP65_LDX            &&
-           CE_KnownImm (L[1])               &&
-           L[1]->Num == 0                   &&
-           !CE_HasLabel (L[1])              &&
-           L[2]->OPC == OP65_LDA            &&
-           !CE_HasLabel (L[2])              &&
-           CE_IsCall (L[3], "tosaddax")     &&
-           !CE_HasLabel (L[3])) {
+           !CS_RangeHasLabel (S, I+1, 5)    &&
+                   CS_GetEntries (S, L+1, I+1, 5)   &&
+                   CE_IsCallTo (L[1], "ldaxysp")    &&
+                   CE_IsCallTo (L[2], "pushax")     &&
+                   L[3]->OPC == OP65_LDY            &&
+           CE_KnownImm (L[3])               &&
+                   CE_IsCallTo (L[4], "ldaxysp")    &&
+                   CE_IsCallTo (L[5], "tosaddax")) {
 
            CodeEntry* X;
-           CodeLabel* Label;
+            const char* Arg;
 
-           /* Remove the call to pushax */
-           CS_DelEntry (S, I);
+                   /* Correct the stack of the first Y register load */
+           CE_SetNumArg (L[0], L[0]->Num - 1);
 
-           /* Correct the stack offset (needed since pushax was removed) */
-           CE_SetNumArg (L[0], L[0]->Num - 2);
+            /* lda (sp),y */
+            X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[1]->LI);
+            CS_InsertEntry (S, X, I+1);
 
-           /* Add the clc . */
-           X = NewCodeEntry (OP65_CLC, AM65_IMP, 0, 0, L[3]->LI);
-           CS_InsertEntry (S, X, I+1);
-
-           /* Remove the load */
-           CS_DelEntry (S, I+3);      /* lda */
-           CS_DelEntry (S, I+2);      /* ldx */
-
-           /* Add the adc */
-           X = NewCodeEntry (OP65_ADC, AM65_ZP_INDY, "sp", 0, L[3]->LI);
+                   /* clc */
+           X = NewCodeEntry (OP65_CLC, AM65_IMP, 0, 0, L[5]->LI);
            CS_InsertEntry (S, X, I+2);
 
-           /* Generate the branch label and the branch */
-           Label = CS_GenLabel (S, L[4]);
-           X = NewCodeEntry (OP65_BCC, AM65_BRA, Label->Name, Label, L[3]->LI);
+            /* ldy #yy-3 */
+           Arg = MakeHexArg (L[3]->Num - 3);
+            X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, L[4]->LI);
            CS_InsertEntry (S, X, I+3);
 
-           /* Generate the increment of the high byte */
-           X = NewCodeEntry (OP65_INX, AM65_IMP, 0, 0, L[3]->LI);
+           /* adc (sp),y */
+           X = NewCodeEntry (OP65_ADC, AM65_ZP_INDY, "sp", 0, L[5]->LI);
            CS_InsertEntry (S, X, I+4);
 
-           /* Delete the call to tosaddax */
-           CS_DelEntry (S, I+5);
+            /* pha */
+            X = NewCodeEntry (OP65_PHA, AM65_IMP, 0, 0, L[5]->LI);
+            CS_InsertEntry (S, X, I+5);
+
+            /* ldy #xx (beware: L[0] has changed) */
+           Arg = MakeHexArg (L[0]->Num + 1);
+            X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, L[1]->LI);
+           CS_InsertEntry (S, X, I+6);
+
+            /* lda (sp),y */
+            X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[1]->LI);
+            CS_InsertEntry (S, X, I+7);
+
+            /* ldy #yy-2 */
+           Arg = MakeHexArg (L[3]->Num - 2);
+            X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, L[4]->LI);
+           CS_InsertEntry (S, X, I+8);
+
+           /* adc (sp),y */
+           X = NewCodeEntry (OP65_ADC, AM65_ZP_INDY, "sp", 0, L[5]->LI);
+           CS_InsertEntry (S, X, I+9);
+
+            /* tax */
+            X = NewCodeEntry (OP65_TAX, AM65_IMP, 0, 0, L[5]->LI);
+            CS_InsertEntry (S, X, I+10);
+
+            /* pla */
+            X = NewCodeEntry (OP65_PLA, AM65_IMP, 0, 0, L[5]->LI);
+            CS_InsertEntry (S, X, I+11);
+
+           /* Delete the old code */
+           CS_DelEntries (S, I+12, 5);
 
            /* Remember, we had changes */
            ++Changes;
@@ -184,19 +211,19 @@ unsigned OptAdd2 (CodeSeg* S)
            CE_KnownImm (L[0])                  &&
            !CS_RangeHasLabel (S, I+1, 3)       &&
                    CS_GetEntries (S, L+1, I+1, 3)      &&
-           CE_IsCall (L[1], "ldaxysp")         &&
+           CE_IsCallTo (L[1], "ldaxysp")       &&
                    L[2]->OPC == OP65_LDY               &&
            CE_KnownImm (L[2])                  &&
-                   CE_IsCall (L[3], "addeqysp")        &&
+                   CE_IsCallTo (L[3], "addeqysp")      &&
                    (GetRegInfo (S, I+4, REG_AX) & REG_AX) == 0) {
 
            /* Insert new code behind the addeqysp */
-           char Buf [20];
+           const char* Arg;
            CodeEntry* X;
 
            /* ldy     #xx-1 */
-           xsprintf (Buf, sizeof (Buf), "$%02X", (int)(L[0]->Num-1));
-           X = NewCodeEntry (OP65_LDY, AM65_IMM, Buf, 0, L[0]->LI);
+           Arg = MakeHexArg (L[0]->Num-1);
+           X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, L[0]->LI);
            CS_InsertEntry (S, X, I+4);
 
            /* lda     (sp),y */
@@ -228,8 +255,8 @@ unsigned OptAdd2 (CodeSeg* S)
            CS_InsertEntry (S, X, I+11);
 
            /* ldy     #yy+1 */
-           xsprintf (Buf, sizeof (Buf), "$%02X", (int)(L[2]->Num+1));
-           X = NewCodeEntry (OP65_LDY, AM65_IMM, Buf, 0, L[2]->LI);
+           Arg = MakeHexArg (L[2]->Num+1);
+           X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, L[2]->LI);
            CS_InsertEntry (S, X, I+12);
 
            /* adc     (sp),y */
@@ -260,6 +287,148 @@ unsigned OptAdd2 (CodeSeg* S)
 
 
 unsigned OptAdd3 (CodeSeg* S)
+/* Search for the sequence
+ *
+ *     jsr     pushax
+ *      lda     xxx
+ *             ldx     yyy
+ *      jsr     tosaddax
+ *
+ * and replace it by
+ *
+ *      clc
+ *      adc     xxx
+ *      pha
+ *      txa
+ *      adc     yyy
+ *      tax
+ *      pla
+ */
+{
+    unsigned Changes = 0;
+
+    /* Walk over the entries */
+    unsigned I = 0;
+    while (I < CS_GetEntryCount (S)) {
+
+       CodeEntry* L[4];
+
+       /* Get next entry */
+               L[0] = CS_GetEntry (S, I);
+
+       /* Check for the sequence */
+        if (CE_IsCallTo (L[0], "pushax")                        &&
+                   CS_GetEntries (S, L+1, I+1, 3)                      &&
+            !CS_RangeHasLabel (S, I+1, 3)                       &&
+            L[1]->OPC == OP65_LDA                               &&
+            (L[1]->AM == AM65_ABS || L[1]->AM == AM65_ZP)       &&
+            L[2]->OPC == OP65_LDX                               &&
+            (L[2]->AM == AM65_ABS || L[2]->AM == AM65_ZP)       &&
+            CE_IsCallTo (L[3], "tosaddax")) {
+
+            CodeEntry* X;
+
+            /* Insert new code behind the sequence */
+           X = NewCodeEntry (OP65_CLC, AM65_IMP, 0, 0, L[3]->LI);
+           CS_InsertEntry (S, X, I+4);
+
+            /* adc xxx */
+           X = NewCodeEntry (OP65_ADC, L[1]->AM, L[1]->Arg, 0, L[3]->LI);
+           CS_InsertEntry (S, X, I+5);
+
+            /* pha */
+           X = NewCodeEntry (OP65_PHA, AM65_IMP, 0, 0, L[3]->LI);
+           CS_InsertEntry (S, X, I+6);
+
+            /* txa */
+           X = NewCodeEntry (OP65_TXA, AM65_IMP, 0, 0, L[3]->LI);
+           CS_InsertEntry (S, X, I+7);
+
+            /* adc yyy */
+           X = NewCodeEntry (OP65_ADC, L[2]->AM, L[2]->Arg, 0, L[3]->LI);
+           CS_InsertEntry (S, X, I+8);
+
+            /* tax */
+           X = NewCodeEntry (OP65_TAX, AM65_IMP, 0, 0, L[3]->LI);
+           CS_InsertEntry (S, X, I+9);
+
+            /* pla */
+           X = NewCodeEntry (OP65_PLA, AM65_IMP, 0, 0, L[3]->LI);
+           CS_InsertEntry (S, X, I+10);
+
+           /* Delete the old code */
+           CS_DelEntries (S, I, 4);
+
+           /* Remember, we had changes */
+           ++Changes;
+
+       }
+
+       /* Next entry */
+       ++I;
+
+    }
+
+    /* Return the number of changes made */
+    return Changes;
+}
+
+
+
+unsigned OptAdd4 (CodeSeg* S)
+/* Search for a call to incaxn and replace it by an 8 bit add if the X register
+ * is not used later.
+ */
+{
+    unsigned Changes = 0;
+
+    /* Walk over the entries */
+    unsigned I = 0;
+    while (I < CS_GetEntryCount (S)) {
+
+       CodeEntry* E;
+
+       /* Get next entry */
+               E = CS_GetEntry (S, I);
+
+       /* Check for the sequence */
+        if (E->OPC == OP65_JSR                          &&
+            strncmp (E->Arg, "incax", 5) == 0           &&
+            IsDigit (E->Arg[5])                         &&
+            E->Arg[6] == '\0'                           &&
+            !RegXUsed (S, I+1)) {
+
+            CodeEntry* X;
+            const char* Arg;
+
+            /* Insert new code behind the sequence */
+           X = NewCodeEntry (OP65_CLC, AM65_IMP, 0, 0, E->LI);
+           CS_InsertEntry (S, X, I+1);
+
+           Arg = MakeHexArg (E->Arg[5] - '0');
+                   X = NewCodeEntry (OP65_ADC, AM65_IMM, Arg, 0, E->LI);
+           CS_InsertEntry (S, X, I+2);
+
+                   /* Delete the old code */
+           CS_DelEntry (S, I);
+
+           /* Remember, we had changes */
+           ++Changes;
+
+       }
+
+       /* Next entry */
+       ++I;
+
+    }
+
+    /* Return the number of changes made */
+    return Changes;
+}
+
+
+
+unsigned OptAdd5 (CodeSeg* S)
 /* Search for the sequence
  *
  *     adc     ...
@@ -282,7 +451,7 @@ unsigned OptAdd3 (CodeSeg* S)
                CodeEntry* E = CS_GetEntry (S, I);
 
        /* Check for the sequence */
-               if (E->OPC == OP65_ADC                               &&
+               if (E->OPC == OP65_ADC                               &&
            CS_GetEntries (S, L, I+1, 3)                     &&
                    (L[0]->OPC == OP65_BCC || L[0]->OPC == OP65_JCC) &&
            L[0]->JumpTo != 0                                &&
@@ -311,4 +480,3 @@ unsigned OptAdd3 (CodeSeg* S)
 
 
 
-