]> git.sur5r.net Git - cc65/blobdiff - src/cc65/coptpush.c
Merge remote-tracking branch 'upstream/master' into a5200
[cc65] / src / cc65 / coptpush.c
index 1be755f9ef1a4697629421948e0d1b0277d23e7d..c17dd30dfb792494db1a5f8a0e24e53ed8636b38 100644 (file)
@@ -1,15 +1,15 @@
 /*****************************************************************************/
 /*                                                                           */
-/*                               coptpush.c                                 */
+/*                                coptpush.c                                 */
 /*                                                                           */
-/*                         Optimize push sequences                          */
+/*                          Optimize push sequences                          */
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2001-2002 Ullrich von Bassewitz                                       */
-/*               Wacholderweg 14                                             */
-/*               D-70597 Stuttgart                                           */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 2001-2012, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -41,7 +41,7 @@
 
 
 /*****************************************************************************/
-/*                                  Code                                    */
+/*                                   Code                                    */
 /*****************************************************************************/
 
 
 unsigned OptPush1 (CodeSeg* S)
 /* Given a sequence
  *
- *     ldy     #xx
  *     jsr     ldaxysp
  *     jsr     pushax
  *
- * If a/x are not used later, replace that by
+ * If a/x are not used later, and Y is known, replace that by
  *
  *     ldy     #xx+2
  *     jsr     pushwysp
@@ -61,50 +60,50 @@ unsigned OptPush1 (CodeSeg* S)
  * saving 3 bytes and several cycles.
  */
 {
+    unsigned I;
     unsigned Changes = 0;
 
     /* Walk over the entries */
-    unsigned I = 0;
+    I = 0;
     while (I < CS_GetEntryCount (S)) {
 
-       CodeEntry* L[3];
+        CodeEntry* L[2];
 
-       /* Get next entry */
-               L[0] = CS_GetEntry (S, I);
+        /* Get next entry */
+        L[0] = CS_GetEntry (S, I);
 
-       /* Check for the sequence */
-       if (L[0]->OPC == OP65_LDY               &&
-           CE_KnownImm (L[0])                  &&
-           L[0]->Num < 0xFE                    &&
-           !CS_RangeHasLabel (S, I+1, 2)       &&
-                   CS_GetEntries (S, L+1, I+1, 2)      &&
-           CE_IsCall (L[1], "ldaxysp")         &&
-                   CE_IsCall (L[2], "pushax")          &&
-                   (GetRegInfo (S, I+3, REG_AX) & REG_AX) == 0) {
+        /* Check for the sequence */
+        if (CE_IsCallTo (L[0], "ldaxysp")               &&
+            RegValIsKnown (L[0]->RI->In.RegY)           &&
+            L[0]->RI->In.RegY < 0xFE                    &&
+            (L[1] = CS_GetNextEntry (S, I)) != 0        &&
+            !CE_HasLabel (L[1])                         &&
+            CE_IsCallTo (L[1], "pushax")                &&
+            !RegAXUsed (S, I+2)) {
 
-           /* Insert new code behind the pushax */
-           const char* Arg;
-           CodeEntry* X;
+            /* Insert new code behind the pushax */
+            const char* Arg;
+            CodeEntry* X;
 
-           /* ldy     #xx+1 */
-           Arg = MakeHexArg (L[0]->Num+2);
-           X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, L[0]->LI);
-           CS_InsertEntry (S, X, I+3);
+            /* ldy     #xx+1 */
+            Arg = MakeHexArg (L[0]->RI->In.RegY+2);
+            X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, L[0]->LI);
+            CS_InsertEntry (S, X, I+2);
 
-           /* jsr pushwysp */
-           X = NewCodeEntry (OP65_JSR, AM65_ABS, "pushwysp", 0, L[2]->LI);
-           CS_InsertEntry (S, X, I+4);
+            /* jsr pushwysp */
+            X = NewCodeEntry (OP65_JSR, AM65_ABS, "pushwysp", 0, L[1]->LI);
+            CS_InsertEntry (S, X, I+3);
 
-           /* Delete the old code */
-           CS_DelEntries (S, I, 3);
+            /* Delete the old code */
+            CS_DelEntries (S, I, 2);
 
-           /* Remember, we had changes */
-           ++Changes;
+            /* Remember, we had changes */
+            ++Changes;
 
-       }
+        }
 
-       /* Next entry */
-       ++I;
+        /* Next entry */
+        ++I;
 
     }
 
@@ -114,3 +113,56 @@ unsigned OptPush1 (CodeSeg* S)
 
 
 
+unsigned OptPush2 (CodeSeg* S)
+/* A sequence
+ *
+ *     jsr     ldaxidx
+ *     jsr     pushax
+ *
+ * may get replaced by
+ *
+ *     jsr     pushwidx
+ *
+ */
+{
+    unsigned I;
+    unsigned Changes = 0;
+
+    /* Walk over the entries */
+    I = 0;
+    while (I < CS_GetEntryCount (S)) {
+
+        CodeEntry* L[2];
+
+        /* Get next entry */
+        L[0] = CS_GetEntry (S, I);
+
+        /* Check for the sequence */
+        if (CE_IsCallTo (L[0], "ldaxidx")               &&
+            (L[1] = CS_GetNextEntry (S, I)) != 0        &&
+            !CE_HasLabel (L[1])                         &&
+            CE_IsCallTo (L[1], "pushax")) {
+
+            /* Insert new code behind the pushax */
+            CodeEntry* X;
+
+            /* jsr pushwidx */
+            X = NewCodeEntry (OP65_JSR, AM65_ABS, "pushwidx", 0, L[1]->LI);
+            CS_InsertEntry (S, X, I+2);
+
+            /* Delete the old code */
+            CS_DelEntries (S, I, 2);
+
+            /* Remember, we had changes */
+            ++Changes;
+
+        }
+
+        /* Next entry */
+        ++I;
+
+    }
+
+    /* Return the number of changes made */
+    return Changes;
+}