]> git.sur5r.net Git - cc65/commitdiff
Moved part of codeopt into coptptrload for better modularization.
authoruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Fri, 14 Aug 2009 17:09:24 +0000 (17:09 +0000)
committeruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Fri, 14 Aug 2009 17:09:24 +0000 (17:09 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@4000 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/cc65/codeopt.c
src/cc65/coptptrload.c [new file with mode: 0644]
src/cc65/coptptrload.h [new file with mode: 0644]
src/cc65/make/gcc.mak
src/cc65/make/watcom.mak

index 6650dd483b1df159c83216fb99d4c68af6e7251b..4542e44a24df78a3d5f194106eb4848614c23032 100644 (file)
@@ -6,8 +6,8 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2001-2006 Ullrich von Bassewitz                                       */
-/*               Römerstraße 52                                              */
+/* (C) 2001-2009 Ullrich von Bassewitz                                       */
+/*               Roemerstrasse 52                                            */
 /*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
@@ -52,6 +52,7 @@
 #include "coptcmp.h"
 #include "coptind.h"
 #include "coptneg.h"
+#include "coptptrload.h"
 #include "coptpush.h"
 #include "coptsize.h"
 #include "coptstop.h"
@@ -685,943 +686,6 @@ static unsigned OptPtrStore2 (CodeSeg* S)
 
 
 
-/*****************************************************************************/
-/*                     Optimize loads through pointers                      */
-/*****************************************************************************/
-
-
-
-static unsigned OptPtrLoad1 (CodeSeg* S)
-/* Search for the sequence:
- *
- *      clc
- *      adc            xxx
- *      tay
- *      txa
- *      adc     yyy
- *      tax
- *      tya
- *      ldy
- *     jsr     ldauidx
- *
- * and replace it by:
- *
- *      clc
- *      adc            xxx
- *      sta     ptr1
- *      txa
- *      adc     yyy
- *      sta     ptr1+1
- *      ldy
- *             ldx     #$00
- *      lda     (ptr1),y
- */
-{
-    unsigned Changes = 0;
-
-    /* Walk over the entries */
-    unsigned I = 0;
-    while (I < CS_GetEntryCount (S)) {
-
-       CodeEntry* L[9];
-
-       /* Get next entry */
-               L[0] = CS_GetEntry (S, I);
-
-       /* Check for the sequence */
-               if (L[0]->OPC == OP65_CLC               &&
-                   CS_GetEntries (S, L+1, I+1, 8)      &&
-           L[1]->OPC == OP65_ADC               &&
-                   L[2]->OPC == OP65_TAY               &&
-           L[3]->OPC == OP65_TXA               &&
-           L[4]->OPC == OP65_ADC               &&
-           L[5]->OPC == OP65_TAX               &&
-           L[6]->OPC == OP65_TYA               &&
-           L[7]->OPC == OP65_LDY               &&
-                   CE_IsCallTo (L[8], "ldauidx")       &&
-            !CS_RangeHasLabel (S, I+1, 8)) {
-
-           CodeEntry* X;
-           CodeEntry* P;
-
-            /* Track the insertion point */
-            unsigned IP = I+2;
-
-            /* sta ptr1 */
-            X = NewCodeEntry (OP65_STA, AM65_ZP, "ptr1", 0, L[2]->LI);
-            CS_InsertEntry (S, X, IP++);
-
-           /* If the instruction before the clc is a ldx, replace the
-            * txa by an lda with the same location of the ldx. Otherwise
-             * transfer the value in X to A.
-            */
-           if ((P = CS_GetPrevEntry (S, I)) != 0 &&
-               P->OPC == OP65_LDX                &&
-               !CE_HasLabel (P)) {
-               X = NewCodeEntry (OP65_LDA, P->AM, P->Arg, 0, P->LI);
-           } else {
-                X = NewCodeEntry (OP65_TXA, AM65_IMP, 0, 0, L[3]->LI);
-            }
-            CS_InsertEntry (S, X, IP++);
-
-            /* adc yyy */
-            X = NewCodeEntry (OP65_ADC, L[4]->AM, L[4]->Arg, 0, L[4]->LI);
-            CS_InsertEntry (S, X, IP++);
-
-            /* sta ptr1+1 */
-            X = NewCodeEntry (OP65_STA, AM65_ZP, "ptr1+1", 0, L[5]->LI);
-            CS_InsertEntry (S, X, IP++);
-
-            /* ldy ... */
-            X = NewCodeEntry (OP65_LDY, L[7]->AM, L[7]->Arg, 0, L[7]->LI);
-            CS_InsertEntry (S, X, IP++);
-
-            /* ldx #$00 */
-            X = NewCodeEntry (OP65_LDX, AM65_IMM, "$00", 0, L[8]->LI);
-            CS_InsertEntry (S, X, IP++);
-
-            /* lda (ptr1),y */
-           X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "ptr1", 0, L[8]->LI);
-           CS_InsertEntry (S, X, IP++);
-
-            /* Remove the old instructions */
-            CS_DelEntries (S, IP, 7);
-
-           /* Remember, we had changes */
-           ++Changes;
-
-       }
-
-       /* Next entry */
-       ++I;
-
-    }
-
-    /* Return the number of changes made */
-    return Changes;
-}
-
-
-
-static unsigned OptPtrLoad2 (CodeSeg* S)
-/* Search for the sequence:
- *
- *      adc            xxx
- *      pha
- *      txa
- *      iny
- *      adc     yyy
- *      tax
- *      pla
- *      ldy
- *     jsr     ldauidx
- *
- * and replace it by:
- *
- *      adc            xxx
- *      sta     ptr1
- *      txa
- *      iny
- *      adc     yyy
- *      sta     ptr1+1
- *      ldy
- *             ldx     #$00
- *      lda     (ptr1),y
- */
-{
-    unsigned Changes = 0;
-
-    /* Walk over the entries */
-    unsigned I = 0;
-    while (I < CS_GetEntryCount (S)) {
-
-       CodeEntry* L[9];
-
-       /* Get next entry */
-               L[0] = CS_GetEntry (S, I);
-
-       /* Check for the sequence */
-               if (L[0]->OPC == OP65_ADC               &&
-                   CS_GetEntries (S, L+1, I+1, 8)      &&
-                   L[1]->OPC == OP65_PHA               &&
-           L[2]->OPC == OP65_TXA               &&
-           L[3]->OPC == OP65_INY               &&
-                   L[4]->OPC == OP65_ADC               &&
-           L[5]->OPC == OP65_TAX               &&
-           L[6]->OPC == OP65_PLA               &&
-           L[7]->OPC == OP65_LDY               &&
-                   CE_IsCallTo (L[8], "ldauidx")       &&
-                   !CS_RangeHasLabel (S, I+1, 8)) {
-
-           CodeEntry* X;
-
-                   /* Store the low byte and remove the PHA instead */
-           X = NewCodeEntry (OP65_STA, AM65_ZP, "ptr1", 0, L[0]->LI);
-           CS_InsertEntry (S, X, I+1);
-
-           /* Store the high byte */
-           X = NewCodeEntry (OP65_STA, AM65_ZP, "ptr1+1", 0, L[4]->LI);
-           CS_InsertEntry (S, X, I+6);
-
-           /* Load high and low byte */
-           X = NewCodeEntry (OP65_LDX, AM65_IMM, "$00", 0, L[6]->LI);
-           CS_InsertEntry (S, X, I+10);
-           X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "ptr1", 0, L[6]->LI);
-           CS_InsertEntry (S, X, I+11);
-
-           /* Delete the old code */
-           CS_DelEntry (S, I+12);      /* jsr ldauidx */
-           CS_DelEntry (S, I+8);       /* pla */
-           CS_DelEntry (S, I+7);       /* tax */
-           CS_DelEntry (S, I+2);       /* pha */
-
-           /* Remember, we had changes */
-           ++Changes;
-
-       }
-
-       /* Next entry */
-       ++I;
-
-    }
-
-    /* Return the number of changes made */
-    return Changes;
-}
-
-
-
-static unsigned OptPtrLoad3 (CodeSeg* S)
-/* Search for the sequence:
- *
- *      lda     #<(label+0)
- *      ldx     #>(label+0)
- *      clc
- *      adc     xxx
- *      bcc     L
- *      inx
- * L:   ldy     #$00
- *      jsr     ldauidx
- *
- * and replace it by:
- *
- *      ldy     xxx
- *      ldx     #$00
- *      lda     label,y
- */
-{
-    unsigned Changes = 0;
-
-    /* Walk over the entries */
-    unsigned I = 0;
-    while (I < CS_GetEntryCount (S)) {
-
-       CodeEntry* L[8];
-       unsigned Len;
-
-       /* Get next entry */
-               L[0] = CS_GetEntry (S, I);
-
-       /* Check for the sequence */
-               if (L[0]->OPC == OP65_LDA                            &&
-           L[0]->AM == AM65_IMM                             &&
-                   CS_GetEntries (S, L+1, I+1, 7)                   &&
-                   L[1]->OPC == OP65_LDX                            &&
-           L[1]->AM == AM65_IMM                             &&
-           L[2]->OPC == OP65_CLC                            &&
-           L[3]->OPC == OP65_ADC                            &&
-           (L[3]->AM == AM65_ABS || L[3]->AM == AM65_ZP)    &&
-                   (L[4]->OPC == OP65_BCC || L[4]->OPC == OP65_JCC) &&
-                   L[4]->JumpTo != 0                                &&
-                   L[4]->JumpTo->Owner == L[6]                      &&
-           L[5]->OPC == OP65_INX                            &&
-           L[6]->OPC == OP65_LDY                            &&
-           CE_IsKnownImm (L[6], 0)                          &&
-                   CE_IsCallTo (L[7], "ldauidx")                    &&
-                   !CS_RangeHasLabel (S, I+1, 5)                    &&
-            !CE_HasLabel (L[7])                              &&
-           /* Check the label last because this is quite costly */
-           (Len = strlen (L[0]->Arg)) > 3                   &&
-           L[0]->Arg[0] == '<'                              &&
-           L[0]->Arg[1] == '('                              &&
-           strlen (L[1]->Arg) == Len                        &&
-           L[1]->Arg[0] == '>'                              &&
-                   memcmp (L[0]->Arg+1, L[1]->Arg+1, Len-1) == 0) {
-
-           CodeEntry* X;
-           char* Label;
-
-           /* We will create all the new stuff behind the current one so
-            * we keep the line references.
-            */
-           X = NewCodeEntry (OP65_LDY, L[3]->AM, L[3]->Arg, 0, L[0]->LI);
-           CS_InsertEntry (S, X, I+8);
-
-           X = NewCodeEntry (OP65_LDX, AM65_IMM, "$00", 0, L[0]->LI);
-           CS_InsertEntry (S, X, I+9);
-
-           Label = memcpy (xmalloc (Len-2), L[0]->Arg+2, Len-3);
-           Label[Len-3] = '\0';
-           X = NewCodeEntry (OP65_LDA, AM65_ABSY, Label, 0, L[0]->LI);
-           CS_InsertEntry (S, X, I+10);
-           xfree (Label);
-
-           /* Remove the old code */
-           CS_DelEntries (S, I, 8);
-
-           /* Remember, we had changes */
-           ++Changes;
-
-       }
-
-       /* Next entry */
-       ++I;
-
-    }
-
-    /* Return the number of changes made */
-    return Changes;
-}
-
-
-
-static unsigned OptPtrLoad4 (CodeSeg* S)
-/* Search for the sequence:
- *
- *      lda     #<(label+0)
- *      ldx     #>(label+0)
- *      ldy     #$xx
- *      clc
- *      adc     (sp),y
- *      bcc     L
- *      inx
- * L:   ldy     #$00
- *      jsr     ldauidx
- *
- * and replace it by:
- *
- *      ldy     #$xx
- *      lda     (sp),y
- *      tay
- *      ldx     #$00
- *      lda     label,y
- */
-{
-    unsigned Changes = 0;
-
-    /* Walk over the entries */
-    unsigned I = 0;
-    while (I < CS_GetEntryCount (S)) {
-
-       CodeEntry* L[9];
-       unsigned Len;
-
-       /* Get next entry */
-               L[0] = CS_GetEntry (S, I);
-
-       /* Check for the sequence */
-               if (L[0]->OPC == OP65_LDA                            &&
-           L[0]->AM == AM65_IMM                             &&
-                   CS_GetEntries (S, L+1, I+1, 8)                   &&
-                   L[1]->OPC == OP65_LDX                            &&
-           L[1]->AM == AM65_IMM                             &&
-           !CE_HasLabel (L[1])                              &&
-           L[2]->OPC == OP65_LDY                            &&
-           CE_IsConstImm (L[2])                             &&
-           !CE_HasLabel (L[2])                              &&
-           L[3]->OPC == OP65_CLC                            &&
-           !CE_HasLabel (L[3])                              &&
-           L[4]->OPC == OP65_ADC                            &&
-           L[4]->AM == AM65_ZP_INDY                         &&
-           !CE_HasLabel (L[4])                              &&
-                   (L[5]->OPC == OP65_BCC || L[5]->OPC == OP65_JCC) &&
-                   L[5]->JumpTo != 0                                &&
-                   L[5]->JumpTo->Owner == L[7]                      &&
-           !CE_HasLabel (L[5])                              &&
-           L[6]->OPC == OP65_INX                            &&
-           !CE_HasLabel (L[6])                              &&
-           L[7]->OPC == OP65_LDY                            &&
-           CE_IsKnownImm (L[7], 0)                          &&
-                   CE_IsCallTo (L[8], "ldauidx")                    &&
-           !CE_HasLabel (L[8])                              &&
-           /* Check the label last because this is quite costly */
-           (Len = strlen (L[0]->Arg)) > 3                   &&
-           L[0]->Arg[0] == '<'                              &&
-           L[0]->Arg[1] == '('                              &&
-           strlen (L[1]->Arg) == Len                        &&
-           L[1]->Arg[0] == '>'                              &&
-                   memcmp (L[0]->Arg+1, L[1]->Arg+1, Len-1) == 0) {
-
-           CodeEntry* X;
-           char* Label;
-
-           /* Add the lda */
-           X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, L[4]->Arg, 0, L[0]->LI);
-           CS_InsertEntry (S, X, I+3);
-
-           /* Add the tay */
-           X = NewCodeEntry (OP65_TAY, AM65_IMP, 0, 0, L[0]->LI);
-           CS_InsertEntry (S, X, I+4);
-
-           /* Add the ldx */
-           X = NewCodeEntry (OP65_LDX, AM65_IMM, "$00", 0, L[0]->LI);
-           CS_InsertEntry (S, X, I+5);
-
-           /* Add the lda */
-           Label = memcpy (xmalloc (Len-2), L[0]->Arg+2, Len-3);
-           Label[Len-3] = '\0';
-           X = NewCodeEntry (OP65_LDA, AM65_ABSY, Label, 0, L[0]->LI);
-           CS_InsertEntry (S, X, I+6);
-           xfree (Label);
-
-           /* Remove the old code */
-           CS_DelEntries (S, I, 2);
-           CS_DelEntries (S, I+5, 6);
-
-           /* Remember, we had changes */
-           ++Changes;
-
-       }
-
-       /* Next entry */
-       ++I;
-
-    }
-
-    /* Return the number of changes made */
-    return Changes;
-}
-
-
-
-static unsigned OptPtrLoad5 (CodeSeg* S)
-/* Search for the sequence:
- *
- *      clc
- *      adc     xxx
- *      bcc     L
- *      inx
- * L:   ldy     #$00
- *      jsr     ldauidx
- *
- * and replace it by:
- *
- *      ldy     xxx
- *      sta     ptr1
- *      stx     ptr1+1
- *      ldx     #$00
- *      lda     (ptr1),y
- */
-{
-    unsigned Changes = 0;
-
-    /* Walk over the entries */
-    unsigned I = 0;
-    while (I < CS_GetEntryCount (S)) {
-
-       CodeEntry* L[6];
-
-       /* Get next entry */
-               L[0] = CS_GetEntry (S, I);
-
-       /* Check for the sequence */
-               if (L[0]->OPC == OP65_CLC                            &&
-                   CS_GetEntries (S, L+1, I+1, 5)                   &&
-                   L[1]->OPC == OP65_ADC                            &&
-           (L[1]->AM == AM65_ABS || L[1]->AM == AM65_ZP || L[1]->AM == AM65_IMM)    &&
-                   (L[2]->OPC == OP65_BCC || L[2]->OPC == OP65_JCC) &&
-                   L[2]->JumpTo != 0                                &&
-                   L[2]->JumpTo->Owner == L[4]                      &&
-                   L[3]->OPC == OP65_INX                            &&
-           L[4]->OPC == OP65_LDY                            &&
-           CE_IsKnownImm (L[4], 0)                          &&
-                   CE_IsCallTo (L[5], "ldauidx")                    &&
-                   !CS_RangeHasLabel (S, I+1, 3)                    &&
-            !CE_HasLabel (L[5])) {
-
-           CodeEntry* X;
-
-           /* We will create all the new stuff behind the current one so
-            * we keep the line references.
-            */
-           X = NewCodeEntry (OP65_LDY, L[1]->AM, L[1]->Arg, 0, L[0]->LI);
-           CS_InsertEntry (S, X, I+6);
-
-            /* sta ptr1 */
-           X = NewCodeEntry (OP65_STA, AM65_ZP, "ptr1", 0, L[0]->LI);
-           CS_InsertEntry (S, X, I+7);
-
-            /* stx ptr1+1 */
-           X = NewCodeEntry (OP65_STX, AM65_ZP, "ptr1+1", 0, L[0]->LI);
-           CS_InsertEntry (S, X, I+8);
-
-            /* ldx #$00 */
-           X = NewCodeEntry (OP65_LDX, AM65_IMM, "$00", 0, L[0]->LI);
-           CS_InsertEntry (S, X, I+9);
-
-           X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "ptr1", 0, L[0]->LI);
-           CS_InsertEntry (S, X, I+10);
-
-           /* Remove the old code */
-           CS_DelEntries (S, I, 6);
-
-           /* Remember, we had changes */
-           ++Changes;
-
-       }
-
-       /* Next entry */
-       ++I;
-
-    }
-
-    /* Return the number of changes made */
-    return Changes;
-}
-
-
-
-static unsigned OptPtrLoad6 (CodeSeg* S)
-/* Search for the sequence:
- *
- *      lda     regbank+n
- *      ldx     regbank+n+1
- *      sta     regsave
- *      stx     regsave+1
- *      clc
- *      adc     #$01
- *      bcc     L0005
- *      inx
- * L:   sta     regbank+n
- *      stx     regbank+n+1
- *      lda     regsave
- *      ldx     regsave+1
- *      ldy     #$00
- *      jsr     ldauidx
- *
- * and replace it by:
- *
- *      ldy     #$00
- *      ldx     #$00
- *      lda     (regbank+n),y
- *      inc     regbank+n
- *      bne     L1
- *      inc     regbank+n+1
- * L1:  tay                     <- only if flags are used
- *
- * This function must execute before OptPtrLoad7!
- *
- */
-{
-    unsigned Changes = 0;
-
-    /* Walk over the entries */
-    unsigned I = 0;
-    while (I < CS_GetEntryCount (S)) {
-
-               CodeEntry* L[15];
-       unsigned Len;
-
-       /* Get next entry */
-               L[0] = CS_GetEntry (S, I);
-
-       /* Check for the sequence */
-               if (L[0]->OPC == OP65_LDA                               &&
-            L[0]->AM == AM65_ZP                                 &&
-            strncmp (L[0]->Arg, "regbank+", 8) == 0             &&
-            (Len = strlen (L[0]->Arg)) > 0                      &&
-                   CS_GetEntries (S, L+1, I+1, 14)                     &&
-            !CS_RangeHasLabel (S, I+1, 7)                       &&
-            !CS_RangeHasLabel (S, I+9, 5)                       &&
-            L[1]->OPC == OP65_LDX                               &&
-            L[1]->AM == AM65_ZP                                 &&
-            strncmp (L[1]->Arg, L[0]->Arg, Len) == 0            &&
-            strcmp (L[1]->Arg+Len, "+1") == 0                   &&
-            L[2]->OPC == OP65_STA                               &&
-            L[2]->AM == AM65_ZP                                 &&
-            strcmp (L[2]->Arg, "regsave") == 0                  &&
-            L[3]->OPC == OP65_STX                               &&
-            L[3]->AM == AM65_ZP                                 &&
-            strcmp (L[3]->Arg, "regsave+1") == 0                &&
-            L[4]->OPC == OP65_CLC                               &&
-            L[5]->OPC == OP65_ADC                               &&
-            CE_IsKnownImm (L[5], 1)                             &&
-            L[6]->OPC == OP65_BCC                               &&
-            L[6]->JumpTo != 0                                   &&
-            L[6]->JumpTo->Owner == L[8]                         &&
-            L[7]->OPC == OP65_INX                               &&
-            L[8]->OPC == OP65_STA                               &&
-            L[8]->AM == AM65_ZP                                 &&
-            strcmp (L[8]->Arg, L[0]->Arg) == 0                  &&
-            L[9]->OPC == OP65_STX                               &&
-            L[9]->AM == AM65_ZP                                 &&
-            strcmp (L[9]->Arg, L[1]->Arg) == 0                  &&
-            L[10]->OPC == OP65_LDA                              &&
-            L[10]->AM == AM65_ZP                                &&
-            strcmp (L[10]->Arg, "regsave") == 0                 &&
-            L[11]->OPC == OP65_LDX                              &&
-            L[11]->AM == AM65_ZP                                &&
-            strcmp (L[11]->Arg, "regsave+1") == 0               &&
-            L[12]->OPC == OP65_LDY                              &&
-            CE_IsConstImm (L[12])                               &&
-            CE_IsCallTo (L[13], "ldauidx")) {
-
-           CodeEntry* X;
-            CodeLabel* Label;
-
-            /* Check if the instruction following the sequence uses the flags
-             * set by the load. If so, insert a test of the value in the
-             * accumulator.
-             */
-            if (CE_UseLoadFlags (L[14])) {
-                X = NewCodeEntry (OP65_TAY, AM65_IMP, 0, 0, L[13]->LI);
-                CS_InsertEntry (S, X, I+14);
-            }
-
-            /* Attach a label to L[14]. This may be either the just inserted
-             * instruction, or the one following the sequence.
-             */
-            Label = CS_GenLabel (S, L[14]);
-
-           /* ldy #$xx */
-           X = NewCodeEntry (OP65_LDY, AM65_IMM, L[12]->Arg, 0, L[12]->LI);
-           CS_InsertEntry (S, X, I+14);
-
-           /* ldx #$xx */
-           X = NewCodeEntry (OP65_LDX, AM65_IMM, "$00", 0, L[13]->LI);
-           CS_InsertEntry (S, X, I+15);
-
-            /* lda (regbank+n),y */
-            X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, L[0]->Arg, 0, L[13]->LI);
-            CS_InsertEntry (S, X, I+16);
-
-            /* inc regbank+n */
-            X = NewCodeEntry (OP65_INC, AM65_ZP, L[0]->Arg, 0, L[5]->LI);
-            CS_InsertEntry (S, X, I+17);
-
-            /* bne ... */
-            X = NewCodeEntry (OP65_BNE, AM65_BRA, Label->Name, Label, L[6]->LI);
-            CS_InsertEntry (S, X, I+18);
-
-            /* inc regbank+n+1 */
-            X = NewCodeEntry (OP65_INC, AM65_ZP, L[1]->Arg, 0, L[7]->LI);
-            CS_InsertEntry (S, X, I+19);
-
-            /* Delete the old code */
-           CS_DelEntries (S, I, 14);
-
-           /* Remember, we had changes */
-           ++Changes;
-
-       }
-
-       /* Next entry */
-       ++I;
-
-    }
-
-    /* Return the number of changes made */
-    return Changes;
-}
-
-
-
-static unsigned OptPtrLoad7 (CodeSeg* S)
-/* Search for the sequence:
- *
- *      lda     zp
- *      ldx     zp+1
- *      ldy     xx
- *      jsr     ldauidx
- *
- * and replace it by:
- *
- *      ldy     xx
- *      ldx     #$00
- *      lda     (zp),y
- */
-{
-    unsigned Changes = 0;
-
-    /* Walk over the entries */
-    unsigned I = 0;
-    while (I < CS_GetEntryCount (S)) {
-
-       CodeEntry* L[4];
-       unsigned Len;
-
-       /* Get next entry */
-               L[0] = CS_GetEntry (S, I);
-
-       /* Check for the sequence */
-               if (L[0]->OPC == OP65_LDA && L[0]->AM == AM65_ZP        &&
-                   CS_GetEntries (S, L+1, I+1, 3)                      &&
-            !CS_RangeHasLabel (S, I+1, 3)                       &&
-                   L[1]->OPC == OP65_LDX && L[1]->AM == AM65_ZP        &&
-            (Len = strlen (L[0]->Arg)) > 0                      &&
-            strncmp (L[0]->Arg, L[1]->Arg, Len) == 0            &&
-            strcmp (L[1]->Arg + Len, "+1") == 0                 &&
-           L[2]->OPC == OP65_LDY                               &&
-                   CE_IsCallTo (L[3], "ldauidx")) {
-
-           CodeEntry* X;
-
-           /* ldx #$00 */
-           X = NewCodeEntry (OP65_LDX, AM65_IMM, "$00", 0, L[3]->LI);
-           CS_InsertEntry (S, X, I+3);
-
-           /* lda (zp),y */
-           X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, L[0]->Arg, 0, L[3]->LI);
-           CS_InsertEntry (S, X, I+4);
-
-           /* Remove the old code */
-           CS_DelEntry (S, I+5);
-           CS_DelEntries (S, I, 2);
-
-           /* Remember, we had changes */
-           ++Changes;
-
-       }
-
-       /* Next entry */
-       ++I;
-
-    }
-
-    /* Return the number of changes made */
-    return Changes;
-}
-
-
-
-static unsigned OptPtrLoad8 (CodeSeg* S)
-/* Search for the sequence:
- *
- *      lda     zp
- *      ldx     zp+1
- *      (anything that doesn't change a/x)
- *      ldy     xx
- *      jsr     ldauidx
- *
- * and replace it by:
- *
- *      lda     zp
- *      ldx     zp+1
- *      (anything that doesn't change a/x)
- *      ldy     xx
- *      ldx     #$00
- *      lda     (zp),y
- *
- * Must execute before OptPtrLoad10!
- */
-{
-    unsigned Changes = 0;
-    unsigned I;
-
-    /* Generate register info */
-    CS_GenRegInfo (S);
-
-    /* Walk over the entries */
-    I = 0;
-    while (I < CS_GetEntryCount (S)) {
-
-       CodeEntry* L[5];
-       unsigned Len;
-
-       /* Get next entry */
-               L[0] = CS_GetEntry (S, I);
-
-       /* Check for the sequence */
-               if (L[0]->OPC == OP65_LDA && L[0]->AM == AM65_ZP        &&
-                   CS_GetEntries (S, L+1, I+1, 4)                      &&
-            !CS_RangeHasLabel (S, I+1, 4)                       &&
-                   L[1]->OPC == OP65_LDX && L[1]->AM == AM65_ZP        &&
-            (Len = strlen (L[0]->Arg)) > 0                      &&
-            strncmp (L[0]->Arg, L[1]->Arg, Len) == 0            &&
-            strcmp (L[1]->Arg + Len, "+1") == 0                 &&
-            (L[2]->Chg & REG_AX) == 0                           &&
-                   L[3]->OPC == OP65_LDY                               &&
-                   CE_IsCallTo (L[4], "ldauidx")) {
-
-           CodeEntry* X;
-
-           /* ldx #$00 */
-           X = NewCodeEntry (OP65_LDX, AM65_IMM, "$00", 0, L[3]->LI);
-           CS_InsertEntry (S, X, I+5);
-
-           /* lda (zp),y */
-           X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, L[0]->Arg, 0, L[3]->LI);
-           CS_InsertEntry (S, X, I+6);
-
-           /* Remove the old code */
-           CS_DelEntry (S, I+4);
-
-           /* Remember, we had changes */
-           ++Changes;
-
-       }
-
-       /* Next entry */
-       ++I;
-
-    }
-
-    /* Free the register info */
-    CS_FreeRegInfo (S);
-
-    /* Return the number of changes made */
-    return Changes;
-}
-
-
-
-static unsigned OptPtrLoad9 (CodeSeg* S)
-/* Search for the sequence:
- *
- *      lda     zp
- *      ldx     zp+1
- *      ldy     xx
- *      jsr     ldaxidx
- *
- * and replace it by:
- *
- *      ldy     xx
- *      lda     (zp),y
- *      tax
- *      dey
- *      lda     (zp),y
- */
-{
-    unsigned Changes = 0;
-
-    /* Walk over the entries */
-    unsigned I = 0;
-    while (I < CS_GetEntryCount (S)) {
-
-       CodeEntry* L[4];
-       unsigned Len;
-
-       /* Get next entry */
-               L[0] = CS_GetEntry (S, I);
-
-       /* Check for the sequence */
-               if (L[0]->OPC == OP65_LDA && L[0]->AM == AM65_ZP        &&
-                   CS_GetEntries (S, L+1, I+1, 3)                      &&
-            !CS_RangeHasLabel (S, I+1, 3)                       &&
-                   L[1]->OPC == OP65_LDX && L[1]->AM == AM65_ZP        &&
-            (Len = strlen (L[0]->Arg)) > 0                      &&
-            strncmp (L[0]->Arg, L[1]->Arg, Len) == 0            &&
-            strcmp (L[1]->Arg + Len, "+1") == 0                 &&
-           L[2]->OPC == OP65_LDY                               &&
-                   CE_IsCallTo (L[3], "ldaxidx")) {
-
-           CodeEntry* X;
-
-                   /* lda (zp),y */
-           X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, L[0]->Arg, 0, L[3]->LI);
-           CS_InsertEntry (S, X, I+4);
-
-           /* tax */
-            X = NewCodeEntry (OP65_TAX, AM65_IMP, 0, 0, L[3]->LI);
-            CS_InsertEntry (S, X, I+5);
-
-           /* dey */
-            X = NewCodeEntry (OP65_DEY, AM65_IMP, 0, 0, L[3]->LI);
-            CS_InsertEntry (S, X, I+6);
-
-                   /* lda (zp),y */
-           X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, L[0]->Arg, 0, L[3]->LI);
-           CS_InsertEntry (S, X, I+7);
-
-           /* Remove the old code */
-           CS_DelEntry (S, I+3);
-           CS_DelEntries (S, I, 2);
-
-           /* Remember, we had changes */
-           ++Changes;
-
-       }
-
-       /* Next entry */
-       ++I;
-
-    }
-
-    /* Return the number of changes made */
-    return Changes;
-}
-
-
-
-static unsigned OptPtrLoad10 (CodeSeg* S)
-/* Search for the sequence
- *
- *      ldy     ...
- *      jsr     ldauidx
- *
- * and replace it by:
- *
- *      ldy     ...
- *      stx     ptr1+1
- *      sta     ptr1
- *      ldx     #$00
- *      lda     (ptr1),y
- *
- * This step must be executed *after* OptPtrLoad1!
- */
-{
-    unsigned Changes = 0;
-
-    /* Walk over the entries */
-    unsigned I = 0;
-    while (I < CS_GetEntryCount (S)) {
-
-       CodeEntry* L[2];
-
-       /* Get next entry */
-               L[0] = CS_GetEntry (S, I);
-
-       /* Check for the sequence */
-               if (L[0]->OPC == OP65_LDY               &&
-                   CS_GetEntries (S, L+1, I+1, 1)      &&
-                   CE_IsCallTo (L[1], "ldauidx")       &&
-           !CE_HasLabel (L[1])) {
-
-           CodeEntry* X;
-
-                   /* Store the high byte */
-                   X = NewCodeEntry (OP65_STA, AM65_ZP, "ptr1", 0, L[0]->LI);
-           CS_InsertEntry (S, X, I+1);
-
-           /* Store the low byte */
-           X = NewCodeEntry (OP65_STX, AM65_ZP, "ptr1+1", 0, L[0]->LI);
-           CS_InsertEntry (S, X, I+2);
-
-           /* Delete the call to ldauidx */
-           CS_DelEntry (S, I+3);
-
-           /* Load the high and low byte */
-           X = NewCodeEntry (OP65_LDX, AM65_IMM, "$00", 0, L[0]->LI);
-           CS_InsertEntry (S, X, I+3);
-           X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "ptr1", 0, L[0]->LI);
-           CS_InsertEntry (S, X, I+4);
-
-           /* Remember, we had changes */
-           ++Changes;
-
-       }
-
-       /* Next entry */
-       ++I;
-
-    }
-
-    /* Return the number of changes made */
-    return Changes;
-}
-
-
-
 /*****************************************************************************/
 /*                           Decouple operations                            */
 /*****************************************************************************/
diff --git a/src/cc65/coptptrload.c b/src/cc65/coptptrload.c
new file mode 100644 (file)
index 0000000..b3a8212
--- /dev/null
@@ -0,0 +1,984 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                               coptptrload.c                               */
+/*                                                                           */
+/*                      Optimize loads through pointers                      */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 2001-2009 Ullrich von Bassewitz                                       */
+/*               Roemerstrasse 52                                            */
+/*               D-70794 Filderstadt                                         */
+/* EMail:        uz@cc65.org                                                 */
+/*                                                                           */
+/*                                                                           */
+/* This software is provided 'as-is', without any expressed or implied       */
+/* warranty.  In no event will the authors be held liable for any damages    */
+/* arising from the use of this software.                                    */
+/*                                                                           */
+/* Permission is granted to anyone to use this software for any purpose,     */
+/* including commercial applications, and to alter it and redistribute it    */
+/* freely, subject to the following restrictions:                            */
+/*                                                                           */
+/* 1. The origin of this software must not be misrepresented; you must not   */
+/*    claim that you wrote the original software. If you use this software   */
+/*    in a product, an acknowledgment in the product documentation would be  */
+/*    appreciated but is not required.                                       */
+/* 2. Altered source versions must be plainly marked as such, and must not   */
+/*    be misrepresented as being the original software.                      */
+/* 3. This notice may not be removed or altered from any source              */
+/*    distribution.                                                          */
+/*                                                                           */
+/*****************************************************************************/
+
+
+
+#include <string.h>
+
+/* common */
+#include "xmalloc.h"
+
+/* cc65 */
+#include "codeent.h"
+#include "codeinfo.h"
+#include "coptptrload.h"
+
+
+
+/*****************************************************************************/
+/*                                  Code                                    */
+/*****************************************************************************/
+
+
+
+unsigned OptPtrLoad1 (CodeSeg* S)
+/* Search for the sequence:
+ *
+ *      clc
+ *      adc            xxx
+ *      tay
+ *      txa
+ *      adc     yyy
+ *      tax
+ *      tya
+ *      ldy
+ *     jsr     ldauidx
+ *
+ * and replace it by:
+ *
+ *      clc
+ *      adc            xxx
+ *      sta     ptr1
+ *      txa
+ *      adc     yyy
+ *      sta     ptr1+1
+ *      ldy
+ *             ldx     #$00
+ *      lda     (ptr1),y
+ */
+{
+    unsigned Changes = 0;
+
+    /* Walk over the entries */
+    unsigned I = 0;
+    while (I < CS_GetEntryCount (S)) {
+
+       CodeEntry* L[9];
+
+       /* Get next entry */
+               L[0] = CS_GetEntry (S, I);
+
+       /* Check for the sequence */
+               if (L[0]->OPC == OP65_CLC               &&
+                   CS_GetEntries (S, L+1, I+1, 8)      &&
+           L[1]->OPC == OP65_ADC               &&
+                   L[2]->OPC == OP65_TAY               &&
+           L[3]->OPC == OP65_TXA               &&
+           L[4]->OPC == OP65_ADC               &&
+           L[5]->OPC == OP65_TAX               &&
+           L[6]->OPC == OP65_TYA               &&
+           L[7]->OPC == OP65_LDY               &&
+                   CE_IsCallTo (L[8], "ldauidx")       &&
+            !CS_RangeHasLabel (S, I+1, 8)) {
+
+           CodeEntry* X;
+           CodeEntry* P;
+
+            /* Track the insertion point */
+            unsigned IP = I+2;
+
+            /* sta ptr1 */
+            X = NewCodeEntry (OP65_STA, AM65_ZP, "ptr1", 0, L[2]->LI);
+            CS_InsertEntry (S, X, IP++);
+
+           /* If the instruction before the clc is a ldx, replace the
+            * txa by an lda with the same location of the ldx. Otherwise
+             * transfer the value in X to A.
+            */
+           if ((P = CS_GetPrevEntry (S, I)) != 0 &&
+               P->OPC == OP65_LDX                &&
+               !CE_HasLabel (P)) {
+               X = NewCodeEntry (OP65_LDA, P->AM, P->Arg, 0, P->LI);
+           } else {
+                X = NewCodeEntry (OP65_TXA, AM65_IMP, 0, 0, L[3]->LI);
+            }
+            CS_InsertEntry (S, X, IP++);
+
+            /* adc yyy */
+            X = NewCodeEntry (OP65_ADC, L[4]->AM, L[4]->Arg, 0, L[4]->LI);
+            CS_InsertEntry (S, X, IP++);
+
+            /* sta ptr1+1 */
+            X = NewCodeEntry (OP65_STA, AM65_ZP, "ptr1+1", 0, L[5]->LI);
+            CS_InsertEntry (S, X, IP++);
+
+            /* ldy ... */
+            X = NewCodeEntry (OP65_LDY, L[7]->AM, L[7]->Arg, 0, L[7]->LI);
+            CS_InsertEntry (S, X, IP++);
+
+            /* ldx #$00 */
+            X = NewCodeEntry (OP65_LDX, AM65_IMM, "$00", 0, L[8]->LI);
+            CS_InsertEntry (S, X, IP++);
+
+            /* lda (ptr1),y */
+           X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "ptr1", 0, L[8]->LI);
+           CS_InsertEntry (S, X, IP++);
+
+            /* Remove the old instructions */
+            CS_DelEntries (S, IP, 7);
+
+           /* Remember, we had changes */
+           ++Changes;
+
+       }
+
+       /* Next entry */
+       ++I;
+
+    }
+
+    /* Return the number of changes made */
+    return Changes;
+}
+
+
+
+unsigned OptPtrLoad2 (CodeSeg* S)
+/* Search for the sequence:
+ *
+ *      adc            xxx
+ *      pha
+ *      txa
+ *      iny
+ *      adc     yyy
+ *      tax
+ *      pla
+ *      ldy
+ *     jsr     ldauidx
+ *
+ * and replace it by:
+ *
+ *      adc            xxx
+ *      sta     ptr1
+ *      txa
+ *      iny
+ *      adc     yyy
+ *      sta     ptr1+1
+ *      ldy
+ *             ldx     #$00
+ *      lda     (ptr1),y
+ */
+{
+    unsigned Changes = 0;
+
+    /* Walk over the entries */
+    unsigned I = 0;
+    while (I < CS_GetEntryCount (S)) {
+
+       CodeEntry* L[9];
+
+       /* Get next entry */
+               L[0] = CS_GetEntry (S, I);
+
+       /* Check for the sequence */
+               if (L[0]->OPC == OP65_ADC               &&
+                   CS_GetEntries (S, L+1, I+1, 8)      &&
+                   L[1]->OPC == OP65_PHA               &&
+           L[2]->OPC == OP65_TXA               &&
+           L[3]->OPC == OP65_INY               &&
+                   L[4]->OPC == OP65_ADC               &&
+           L[5]->OPC == OP65_TAX               &&
+           L[6]->OPC == OP65_PLA               &&
+           L[7]->OPC == OP65_LDY               &&
+                   CE_IsCallTo (L[8], "ldauidx")       &&
+                   !CS_RangeHasLabel (S, I+1, 8)) {
+
+           CodeEntry* X;
+
+                   /* Store the low byte and remove the PHA instead */
+           X = NewCodeEntry (OP65_STA, AM65_ZP, "ptr1", 0, L[0]->LI);
+           CS_InsertEntry (S, X, I+1);
+
+           /* Store the high byte */
+           X = NewCodeEntry (OP65_STA, AM65_ZP, "ptr1+1", 0, L[4]->LI);
+           CS_InsertEntry (S, X, I+6);
+
+           /* Load high and low byte */
+           X = NewCodeEntry (OP65_LDX, AM65_IMM, "$00", 0, L[6]->LI);
+           CS_InsertEntry (S, X, I+10);
+           X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "ptr1", 0, L[6]->LI);
+           CS_InsertEntry (S, X, I+11);
+
+           /* Delete the old code */
+           CS_DelEntry (S, I+12);      /* jsr ldauidx */
+           CS_DelEntry (S, I+8);       /* pla */
+           CS_DelEntry (S, I+7);       /* tax */
+           CS_DelEntry (S, I+2);       /* pha */
+
+           /* Remember, we had changes */
+           ++Changes;
+
+       }
+
+       /* Next entry */
+       ++I;
+
+    }
+
+    /* Return the number of changes made */
+    return Changes;
+}
+
+
+
+unsigned OptPtrLoad3 (CodeSeg* S)
+/* Search for the sequence:
+ *
+ *      lda     #<(label+0)
+ *      ldx     #>(label+0)
+ *      clc
+ *      adc     xxx
+ *      bcc     L
+ *      inx
+ * L:   ldy     #$00
+ *      jsr     ldauidx
+ *
+ * and replace it by:
+ *
+ *      ldy     xxx
+ *      ldx     #$00
+ *      lda     label,y
+ */
+{
+    unsigned Changes = 0;
+
+    /* Walk over the entries */
+    unsigned I = 0;
+    while (I < CS_GetEntryCount (S)) {
+
+       CodeEntry* L[8];
+       unsigned Len;
+
+       /* Get next entry */
+               L[0] = CS_GetEntry (S, I);
+
+       /* Check for the sequence */
+               if (L[0]->OPC == OP65_LDA                            &&
+           L[0]->AM == AM65_IMM                             &&
+                   CS_GetEntries (S, L+1, I+1, 7)                   &&
+                   L[1]->OPC == OP65_LDX                            &&
+           L[1]->AM == AM65_IMM                             &&
+           L[2]->OPC == OP65_CLC                            &&
+           L[3]->OPC == OP65_ADC                            &&
+           (L[3]->AM == AM65_ABS || L[3]->AM == AM65_ZP)    &&
+                   (L[4]->OPC == OP65_BCC || L[4]->OPC == OP65_JCC) &&
+                   L[4]->JumpTo != 0                                &&
+                   L[4]->JumpTo->Owner == L[6]                      &&
+           L[5]->OPC == OP65_INX                            &&
+           L[6]->OPC == OP65_LDY                            &&
+           CE_IsKnownImm (L[6], 0)                          &&
+                   CE_IsCallTo (L[7], "ldauidx")                    &&
+                   !CS_RangeHasLabel (S, I+1, 5)                    &&
+            !CE_HasLabel (L[7])                              &&
+           /* Check the label last because this is quite costly */
+           (Len = strlen (L[0]->Arg)) > 3                   &&
+           L[0]->Arg[0] == '<'                              &&
+           L[0]->Arg[1] == '('                              &&
+           strlen (L[1]->Arg) == Len                        &&
+           L[1]->Arg[0] == '>'                              &&
+                   memcmp (L[0]->Arg+1, L[1]->Arg+1, Len-1) == 0) {
+
+           CodeEntry* X;
+           char* Label;
+
+           /* We will create all the new stuff behind the current one so
+            * we keep the line references.
+            */
+           X = NewCodeEntry (OP65_LDY, L[3]->AM, L[3]->Arg, 0, L[0]->LI);
+           CS_InsertEntry (S, X, I+8);
+
+           X = NewCodeEntry (OP65_LDX, AM65_IMM, "$00", 0, L[0]->LI);
+           CS_InsertEntry (S, X, I+9);
+
+           Label = memcpy (xmalloc (Len-2), L[0]->Arg+2, Len-3);
+           Label[Len-3] = '\0';
+           X = NewCodeEntry (OP65_LDA, AM65_ABSY, Label, 0, L[0]->LI);
+           CS_InsertEntry (S, X, I+10);
+           xfree (Label);
+
+           /* Remove the old code */
+           CS_DelEntries (S, I, 8);
+
+           /* Remember, we had changes */
+           ++Changes;
+
+       }
+
+       /* Next entry */
+       ++I;
+
+    }
+
+    /* Return the number of changes made */
+    return Changes;
+}
+
+
+
+unsigned OptPtrLoad4 (CodeSeg* S)
+/* Search for the sequence:
+ *
+ *      lda     #<(label+0)
+ *      ldx     #>(label+0)
+ *      ldy     #$xx
+ *      clc
+ *      adc     (sp),y
+ *      bcc     L
+ *      inx
+ * L:   ldy     #$00
+ *      jsr     ldauidx
+ *
+ * and replace it by:
+ *
+ *      ldy     #$xx
+ *      lda     (sp),y
+ *      tay
+ *      ldx     #$00
+ *      lda     label,y
+ */
+{
+    unsigned Changes = 0;
+
+    /* Walk over the entries */
+    unsigned I = 0;
+    while (I < CS_GetEntryCount (S)) {
+
+       CodeEntry* L[9];
+       unsigned Len;
+
+       /* Get next entry */
+               L[0] = CS_GetEntry (S, I);
+
+       /* Check for the sequence */
+               if (L[0]->OPC == OP65_LDA                            &&
+           L[0]->AM == AM65_IMM                             &&
+                   CS_GetEntries (S, L+1, I+1, 8)                   &&
+                   L[1]->OPC == OP65_LDX                            &&
+           L[1]->AM == AM65_IMM                             &&
+           !CE_HasLabel (L[1])                              &&
+           L[2]->OPC == OP65_LDY                            &&
+           CE_IsConstImm (L[2])                             &&
+           !CE_HasLabel (L[2])                              &&
+           L[3]->OPC == OP65_CLC                            &&
+           !CE_HasLabel (L[3])                              &&
+           L[4]->OPC == OP65_ADC                            &&
+           L[4]->AM == AM65_ZP_INDY                         &&
+           !CE_HasLabel (L[4])                              &&
+                   (L[5]->OPC == OP65_BCC || L[5]->OPC == OP65_JCC) &&
+                   L[5]->JumpTo != 0                                &&
+                   L[5]->JumpTo->Owner == L[7]                      &&
+           !CE_HasLabel (L[5])                              &&
+           L[6]->OPC == OP65_INX                            &&
+           !CE_HasLabel (L[6])                              &&
+           L[7]->OPC == OP65_LDY                            &&
+           CE_IsKnownImm (L[7], 0)                          &&
+                   CE_IsCallTo (L[8], "ldauidx")                    &&
+           !CE_HasLabel (L[8])                              &&
+           /* Check the label last because this is quite costly */
+           (Len = strlen (L[0]->Arg)) > 3                   &&
+           L[0]->Arg[0] == '<'                              &&
+           L[0]->Arg[1] == '('                              &&
+           strlen (L[1]->Arg) == Len                        &&
+           L[1]->Arg[0] == '>'                              &&
+                   memcmp (L[0]->Arg+1, L[1]->Arg+1, Len-1) == 0) {
+
+           CodeEntry* X;
+           char* Label;
+
+           /* Add the lda */
+           X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, L[4]->Arg, 0, L[0]->LI);
+           CS_InsertEntry (S, X, I+3);
+
+           /* Add the tay */
+           X = NewCodeEntry (OP65_TAY, AM65_IMP, 0, 0, L[0]->LI);
+           CS_InsertEntry (S, X, I+4);
+
+           /* Add the ldx */
+           X = NewCodeEntry (OP65_LDX, AM65_IMM, "$00", 0, L[0]->LI);
+           CS_InsertEntry (S, X, I+5);
+
+           /* Add the lda */
+           Label = memcpy (xmalloc (Len-2), L[0]->Arg+2, Len-3);
+           Label[Len-3] = '\0';
+           X = NewCodeEntry (OP65_LDA, AM65_ABSY, Label, 0, L[0]->LI);
+           CS_InsertEntry (S, X, I+6);
+           xfree (Label);
+
+           /* Remove the old code */
+           CS_DelEntries (S, I, 2);
+           CS_DelEntries (S, I+5, 6);
+
+           /* Remember, we had changes */
+           ++Changes;
+
+       }
+
+       /* Next entry */
+       ++I;
+
+    }
+
+    /* Return the number of changes made */
+    return Changes;
+}
+
+
+
+unsigned OptPtrLoad5 (CodeSeg* S)
+/* Search for the sequence:
+ *
+ *      clc
+ *      adc     xxx
+ *      bcc     L
+ *      inx
+ * L:   ldy     #$00
+ *      jsr     ldauidx
+ *
+ * and replace it by:
+ *
+ *      ldy     xxx
+ *      sta     ptr1
+ *      stx     ptr1+1
+ *      ldx     #$00
+ *      lda     (ptr1),y
+ */
+{
+    unsigned Changes = 0;
+
+    /* Walk over the entries */
+    unsigned I = 0;
+    while (I < CS_GetEntryCount (S)) {
+
+       CodeEntry* L[6];
+
+       /* Get next entry */
+               L[0] = CS_GetEntry (S, I);
+
+       /* Check for the sequence */
+               if (L[0]->OPC == OP65_CLC                            &&
+                   CS_GetEntries (S, L+1, I+1, 5)                   &&
+                   L[1]->OPC == OP65_ADC                            &&
+           (L[1]->AM == AM65_ABS || L[1]->AM == AM65_ZP || L[1]->AM == AM65_IMM)    &&
+                   (L[2]->OPC == OP65_BCC || L[2]->OPC == OP65_JCC) &&
+                   L[2]->JumpTo != 0                                &&
+                   L[2]->JumpTo->Owner == L[4]                      &&
+                   L[3]->OPC == OP65_INX                            &&
+           L[4]->OPC == OP65_LDY                            &&
+           CE_IsKnownImm (L[4], 0)                          &&
+                   CE_IsCallTo (L[5], "ldauidx")                    &&
+                   !CS_RangeHasLabel (S, I+1, 3)                    &&
+            !CE_HasLabel (L[5])) {
+
+           CodeEntry* X;
+
+           /* We will create all the new stuff behind the current one so
+            * we keep the line references.
+            */
+           X = NewCodeEntry (OP65_LDY, L[1]->AM, L[1]->Arg, 0, L[0]->LI);
+           CS_InsertEntry (S, X, I+6);
+
+            /* sta ptr1 */
+           X = NewCodeEntry (OP65_STA, AM65_ZP, "ptr1", 0, L[0]->LI);
+           CS_InsertEntry (S, X, I+7);
+
+            /* stx ptr1+1 */
+           X = NewCodeEntry (OP65_STX, AM65_ZP, "ptr1+1", 0, L[0]->LI);
+           CS_InsertEntry (S, X, I+8);
+
+            /* ldx #$00 */
+           X = NewCodeEntry (OP65_LDX, AM65_IMM, "$00", 0, L[0]->LI);
+           CS_InsertEntry (S, X, I+9);
+
+           X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "ptr1", 0, L[0]->LI);
+           CS_InsertEntry (S, X, I+10);
+
+           /* Remove the old code */
+           CS_DelEntries (S, I, 6);
+
+           /* Remember, we had changes */
+           ++Changes;
+
+       }
+
+       /* Next entry */
+       ++I;
+
+    }
+
+    /* Return the number of changes made */
+    return Changes;
+}
+
+
+
+unsigned OptPtrLoad6 (CodeSeg* S)
+/* Search for the sequence:
+ *
+ *      lda     regbank+n
+ *      ldx     regbank+n+1
+ *      sta     regsave
+ *      stx     regsave+1
+ *      clc
+ *      adc     #$01
+ *      bcc     L0005
+ *      inx
+ * L:   sta     regbank+n
+ *      stx     regbank+n+1
+ *      lda     regsave
+ *      ldx     regsave+1
+ *      ldy     #$00
+ *      jsr     ldauidx
+ *
+ * and replace it by:
+ *
+ *      ldy     #$00
+ *      ldx     #$00
+ *      lda     (regbank+n),y
+ *      inc     regbank+n
+ *      bne     L1
+ *      inc     regbank+n+1
+ * L1:  tay                     <- only if flags are used
+ *
+ * This function must execute before OptPtrLoad7!
+ *
+ */
+{
+    unsigned Changes = 0;
+
+    /* Walk over the entries */
+    unsigned I = 0;
+    while (I < CS_GetEntryCount (S)) {
+
+               CodeEntry* L[15];
+       unsigned Len;
+
+       /* Get next entry */
+               L[0] = CS_GetEntry (S, I);
+
+       /* Check for the sequence */
+               if (L[0]->OPC == OP65_LDA                               &&
+            L[0]->AM == AM65_ZP                                 &&
+            strncmp (L[0]->Arg, "regbank+", 8) == 0             &&
+            (Len = strlen (L[0]->Arg)) > 0                      &&
+                   CS_GetEntries (S, L+1, I+1, 14)                     &&
+            !CS_RangeHasLabel (S, I+1, 7)                       &&
+            !CS_RangeHasLabel (S, I+9, 5)                       &&
+            L[1]->OPC == OP65_LDX                               &&
+            L[1]->AM == AM65_ZP                                 &&
+            strncmp (L[1]->Arg, L[0]->Arg, Len) == 0            &&
+            strcmp (L[1]->Arg+Len, "+1") == 0                   &&
+            L[2]->OPC == OP65_STA                               &&
+            L[2]->AM == AM65_ZP                                 &&
+            strcmp (L[2]->Arg, "regsave") == 0                  &&
+            L[3]->OPC == OP65_STX                               &&
+            L[3]->AM == AM65_ZP                                 &&
+            strcmp (L[3]->Arg, "regsave+1") == 0                &&
+            L[4]->OPC == OP65_CLC                               &&
+            L[5]->OPC == OP65_ADC                               &&
+            CE_IsKnownImm (L[5], 1)                             &&
+            L[6]->OPC == OP65_BCC                               &&
+            L[6]->JumpTo != 0                                   &&
+            L[6]->JumpTo->Owner == L[8]                         &&
+            L[7]->OPC == OP65_INX                               &&
+            L[8]->OPC == OP65_STA                               &&
+            L[8]->AM == AM65_ZP                                 &&
+            strcmp (L[8]->Arg, L[0]->Arg) == 0                  &&
+            L[9]->OPC == OP65_STX                               &&
+            L[9]->AM == AM65_ZP                                 &&
+            strcmp (L[9]->Arg, L[1]->Arg) == 0                  &&
+            L[10]->OPC == OP65_LDA                              &&
+            L[10]->AM == AM65_ZP                                &&
+            strcmp (L[10]->Arg, "regsave") == 0                 &&
+            L[11]->OPC == OP65_LDX                              &&
+            L[11]->AM == AM65_ZP                                &&
+            strcmp (L[11]->Arg, "regsave+1") == 0               &&
+            L[12]->OPC == OP65_LDY                              &&
+            CE_IsConstImm (L[12])                               &&
+            CE_IsCallTo (L[13], "ldauidx")) {
+
+           CodeEntry* X;
+            CodeLabel* Label;
+
+            /* Check if the instruction following the sequence uses the flags
+             * set by the load. If so, insert a test of the value in the
+             * accumulator.
+             */
+            if (CE_UseLoadFlags (L[14])) {
+                X = NewCodeEntry (OP65_TAY, AM65_IMP, 0, 0, L[13]->LI);
+                CS_InsertEntry (S, X, I+14);
+            }
+
+            /* Attach a label to L[14]. This may be either the just inserted
+             * instruction, or the one following the sequence.
+             */
+            Label = CS_GenLabel (S, L[14]);
+
+           /* ldy #$xx */
+           X = NewCodeEntry (OP65_LDY, AM65_IMM, L[12]->Arg, 0, L[12]->LI);
+           CS_InsertEntry (S, X, I+14);
+
+           /* ldx #$xx */
+           X = NewCodeEntry (OP65_LDX, AM65_IMM, "$00", 0, L[13]->LI);
+           CS_InsertEntry (S, X, I+15);
+
+            /* lda (regbank+n),y */
+            X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, L[0]->Arg, 0, L[13]->LI);
+            CS_InsertEntry (S, X, I+16);
+
+            /* inc regbank+n */
+            X = NewCodeEntry (OP65_INC, AM65_ZP, L[0]->Arg, 0, L[5]->LI);
+            CS_InsertEntry (S, X, I+17);
+
+            /* bne ... */
+            X = NewCodeEntry (OP65_BNE, AM65_BRA, Label->Name, Label, L[6]->LI);
+            CS_InsertEntry (S, X, I+18);
+
+            /* inc regbank+n+1 */
+            X = NewCodeEntry (OP65_INC, AM65_ZP, L[1]->Arg, 0, L[7]->LI);
+            CS_InsertEntry (S, X, I+19);
+
+            /* Delete the old code */
+           CS_DelEntries (S, I, 14);
+
+           /* Remember, we had changes */
+           ++Changes;
+
+       }
+
+       /* Next entry */
+       ++I;
+
+    }
+
+    /* Return the number of changes made */
+    return Changes;
+}
+
+
+
+unsigned OptPtrLoad7 (CodeSeg* S)
+/* Search for the sequence:
+ *
+ *      lda     zp
+ *      ldx     zp+1
+ *      ldy     xx
+ *      jsr     ldauidx
+ *
+ * and replace it by:
+ *
+ *      ldy     xx
+ *      ldx     #$00
+ *      lda     (zp),y
+ */
+{
+    unsigned Changes = 0;
+
+    /* Walk over the entries */
+    unsigned I = 0;
+    while (I < CS_GetEntryCount (S)) {
+
+       CodeEntry* L[4];
+       unsigned Len;
+
+       /* Get next entry */
+               L[0] = CS_GetEntry (S, I);
+
+       /* Check for the sequence */
+               if (L[0]->OPC == OP65_LDA && L[0]->AM == AM65_ZP        &&
+                   CS_GetEntries (S, L+1, I+1, 3)                      &&
+            !CS_RangeHasLabel (S, I+1, 3)                       &&
+                   L[1]->OPC == OP65_LDX && L[1]->AM == AM65_ZP        &&
+            (Len = strlen (L[0]->Arg)) > 0                      &&
+            strncmp (L[0]->Arg, L[1]->Arg, Len) == 0            &&
+            strcmp (L[1]->Arg + Len, "+1") == 0                 &&
+           L[2]->OPC == OP65_LDY                               &&
+                   CE_IsCallTo (L[3], "ldauidx")) {
+
+           CodeEntry* X;
+
+           /* ldx #$00 */
+           X = NewCodeEntry (OP65_LDX, AM65_IMM, "$00", 0, L[3]->LI);
+           CS_InsertEntry (S, X, I+3);
+
+           /* lda (zp),y */
+           X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, L[0]->Arg, 0, L[3]->LI);
+           CS_InsertEntry (S, X, I+4);
+
+           /* Remove the old code */
+           CS_DelEntry (S, I+5);
+           CS_DelEntries (S, I, 2);
+
+           /* Remember, we had changes */
+           ++Changes;
+
+       }
+
+       /* Next entry */
+       ++I;
+
+    }
+
+    /* Return the number of changes made */
+    return Changes;
+}
+
+
+
+unsigned OptPtrLoad8 (CodeSeg* S)
+/* Search for the sequence:
+ *
+ *      lda     zp
+ *      ldx     zp+1
+ *      (anything that doesn't change a/x)
+ *      ldy     xx
+ *      jsr     ldauidx
+ *
+ * and replace it by:
+ *
+ *      lda     zp
+ *      ldx     zp+1
+ *      (anything that doesn't change a/x)
+ *      ldy     xx
+ *      ldx     #$00
+ *      lda     (zp),y
+ *
+ * Must execute before OptPtrLoad10!
+ */
+{
+    unsigned Changes = 0;
+    unsigned I;
+
+    /* Generate register info */
+    CS_GenRegInfo (S);
+
+    /* Walk over the entries */
+    I = 0;
+    while (I < CS_GetEntryCount (S)) {
+
+       CodeEntry* L[5];
+       unsigned Len;
+
+       /* Get next entry */
+               L[0] = CS_GetEntry (S, I);
+
+       /* Check for the sequence */
+               if (L[0]->OPC == OP65_LDA && L[0]->AM == AM65_ZP        &&
+                   CS_GetEntries (S, L+1, I+1, 4)                      &&
+            !CS_RangeHasLabel (S, I+1, 4)                       &&
+                   L[1]->OPC == OP65_LDX && L[1]->AM == AM65_ZP        &&
+            (Len = strlen (L[0]->Arg)) > 0                      &&
+            strncmp (L[0]->Arg, L[1]->Arg, Len) == 0            &&
+            strcmp (L[1]->Arg + Len, "+1") == 0                 &&
+            (L[2]->Chg & REG_AX) == 0                           &&
+                   L[3]->OPC == OP65_LDY                               &&
+                   CE_IsCallTo (L[4], "ldauidx")) {
+
+           CodeEntry* X;
+
+           /* ldx #$00 */
+           X = NewCodeEntry (OP65_LDX, AM65_IMM, "$00", 0, L[3]->LI);
+           CS_InsertEntry (S, X, I+5);
+
+           /* lda (zp),y */
+           X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, L[0]->Arg, 0, L[3]->LI);
+           CS_InsertEntry (S, X, I+6);
+
+           /* Remove the old code */
+           CS_DelEntry (S, I+4);
+
+           /* Remember, we had changes */
+           ++Changes;
+
+       }
+
+       /* Next entry */
+       ++I;
+
+    }
+
+    /* Free the register info */
+    CS_FreeRegInfo (S);
+
+    /* Return the number of changes made */
+    return Changes;
+}
+
+
+
+unsigned OptPtrLoad9 (CodeSeg* S)
+/* Search for the sequence:
+ *
+ *      lda     zp
+ *      ldx     zp+1
+ *      ldy     xx
+ *      jsr     ldaxidx
+ *
+ * and replace it by:
+ *
+ *      ldy     xx
+ *      lda     (zp),y
+ *      tax
+ *      dey
+ *      lda     (zp),y
+ */
+{
+    unsigned Changes = 0;
+
+    /* Walk over the entries */
+    unsigned I = 0;
+    while (I < CS_GetEntryCount (S)) {
+
+       CodeEntry* L[4];
+       unsigned Len;
+
+       /* Get next entry */
+               L[0] = CS_GetEntry (S, I);
+
+       /* Check for the sequence */
+               if (L[0]->OPC == OP65_LDA && L[0]->AM == AM65_ZP        &&
+                   CS_GetEntries (S, L+1, I+1, 3)                      &&
+            !CS_RangeHasLabel (S, I+1, 3)                       &&
+                   L[1]->OPC == OP65_LDX && L[1]->AM == AM65_ZP        &&
+            (Len = strlen (L[0]->Arg)) > 0                      &&
+            strncmp (L[0]->Arg, L[1]->Arg, Len) == 0            &&
+            strcmp (L[1]->Arg + Len, "+1") == 0                 &&
+           L[2]->OPC == OP65_LDY                               &&
+                   CE_IsCallTo (L[3], "ldaxidx")) {
+
+           CodeEntry* X;
+
+                   /* lda (zp),y */
+           X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, L[0]->Arg, 0, L[3]->LI);
+           CS_InsertEntry (S, X, I+4);
+
+           /* tax */
+            X = NewCodeEntry (OP65_TAX, AM65_IMP, 0, 0, L[3]->LI);
+            CS_InsertEntry (S, X, I+5);
+
+           /* dey */
+            X = NewCodeEntry (OP65_DEY, AM65_IMP, 0, 0, L[3]->LI);
+            CS_InsertEntry (S, X, I+6);
+
+                   /* lda (zp),y */
+           X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, L[0]->Arg, 0, L[3]->LI);
+           CS_InsertEntry (S, X, I+7);
+
+           /* Remove the old code */
+           CS_DelEntry (S, I+3);
+           CS_DelEntries (S, I, 2);
+
+           /* Remember, we had changes */
+           ++Changes;
+
+       }
+
+       /* Next entry */
+       ++I;
+
+    }
+
+    /* Return the number of changes made */
+    return Changes;
+}
+
+
+
+unsigned OptPtrLoad10 (CodeSeg* S)
+/* Search for the sequence
+ *
+ *      ldy     ...
+ *      jsr     ldauidx
+ *
+ * and replace it by:
+ *
+ *      ldy     ...
+ *      stx     ptr1+1
+ *      sta     ptr1
+ *      ldx     #$00
+ *      lda     (ptr1),y
+ *
+ * This step must be executed *after* OptPtrLoad1!
+ */
+{
+    unsigned Changes = 0;
+
+    /* Walk over the entries */
+    unsigned I = 0;
+    while (I < CS_GetEntryCount (S)) {
+
+       CodeEntry* L[2];
+
+       /* Get next entry */
+               L[0] = CS_GetEntry (S, I);
+
+       /* Check for the sequence */
+               if (L[0]->OPC == OP65_LDY               &&
+                   CS_GetEntries (S, L+1, I+1, 1)      &&
+                   CE_IsCallTo (L[1], "ldauidx")       &&
+           !CE_HasLabel (L[1])) {
+
+           CodeEntry* X;
+
+                   /* Store the high byte */
+                   X = NewCodeEntry (OP65_STA, AM65_ZP, "ptr1", 0, L[0]->LI);
+           CS_InsertEntry (S, X, I+1);
+
+           /* Store the low byte */
+           X = NewCodeEntry (OP65_STX, AM65_ZP, "ptr1+1", 0, L[0]->LI);
+           CS_InsertEntry (S, X, I+2);
+
+           /* Delete the call to ldauidx */
+           CS_DelEntry (S, I+3);
+
+           /* Load the high and low byte */
+           X = NewCodeEntry (OP65_LDX, AM65_IMM, "$00", 0, L[0]->LI);
+           CS_InsertEntry (S, X, I+3);
+           X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "ptr1", 0, L[0]->LI);
+           CS_InsertEntry (S, X, I+4);
+
+           /* Remember, we had changes */
+           ++Changes;
+
+       }
+
+       /* Next entry */
+       ++I;
+
+    }
+
+    /* Return the number of changes made */
+    return Changes;
+}
+
+
+
diff --git a/src/cc65/coptptrload.h b/src/cc65/coptptrload.h
new file mode 100644 (file)
index 0000000..c2fc76a
--- /dev/null
@@ -0,0 +1,272 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                               coptptrload.h                               */
+/*                                                                           */
+/*                      Optimize loads through pointers                      */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 2001-2009 Ullrich von Bassewitz                                       */
+/*               Roemerstrasse 52                                            */
+/*               D-70794 Filderstadt                                         */
+/* EMail:        uz@cc65.org                                                 */
+/*                                                                           */
+/*                                                                           */
+/* This software is provided 'as-is', without any expressed or implied       */
+/* warranty.  In no event will the authors be held liable for any damages    */
+/* arising from the use of this software.                                    */
+/*                                                                           */
+/* Permission is granted to anyone to use this software for any purpose,     */
+/* including commercial applications, and to alter it and redistribute it    */
+/* freely, subject to the following restrictions:                            */
+/*                                                                           */
+/* 1. The origin of this software must not be misrepresented; you must not   */
+/*    claim that you wrote the original software. If you use this software   */
+/*    in a product, an acknowledgment in the product documentation would be  */
+/*    appreciated but is not required.                                       */
+/* 2. Altered source versions must be plainly marked as such, and must not   */
+/*    be misrepresented as being the original software.                      */
+/* 3. This notice may not be removed or altered from any source              */
+/*    distribution.                                                          */
+/*                                                                           */
+/*****************************************************************************/
+
+
+
+#ifndef COPTPTRLOAD_H
+#define COPTPTRLOAD_H
+
+
+
+/* cc65 */
+#include "codeseg.h"
+
+
+
+/*****************************************************************************/
+/*                                  Code                                    */
+/*****************************************************************************/
+
+
+
+unsigned OptPtrLoad1 (CodeSeg* S);
+/* Search for the sequence:
+ *
+ *      clc
+ *      adc            xxx
+ *      tay
+ *      txa
+ *      adc     yyy
+ *      tax
+ *      tya
+ *      ldy
+ *     jsr     ldauidx
+ *
+ * and replace it by:
+ *
+ *      clc
+ *      adc            xxx
+ *      sta     ptr1
+ *      txa
+ *      adc     yyy
+ *      sta     ptr1+1
+ *      ldy
+ *             ldx     #$00
+ *      lda     (ptr1),y
+ */
+
+unsigned OptPtrLoad2 (CodeSeg* S);
+/* Search for the sequence:
+ *
+ *      adc            xxx
+ *      pha
+ *      txa
+ *      iny
+ *      adc     yyy
+ *      tax
+ *      pla
+ *      ldy
+ *     jsr     ldauidx
+ *
+ * and replace it by:
+ *
+ *      adc            xxx
+ *      sta     ptr1
+ *      txa
+ *      iny
+ *      adc     yyy
+ *      sta     ptr1+1
+ *      ldy
+ *             ldx     #$00
+ *      lda     (ptr1),y
+ */
+
+unsigned OptPtrLoad3 (CodeSeg* S);
+/* Search for the sequence:
+ *
+ *      lda     #<(label+0)
+ *      ldx     #>(label+0)
+ *      clc
+ *      adc     xxx
+ *      bcc     L
+ *      inx
+ * L:   ldy     #$00
+ *      jsr     ldauidx
+ *
+ * and replace it by:
+ *
+ *      ldy     xxx
+ *      ldx     #$00
+ *      lda     label,y
+ */                               
+
+unsigned OptPtrLoad4 (CodeSeg* S);
+/* Search for the sequence:
+ *
+ *      lda     #<(label+0)
+ *      ldx     #>(label+0)
+ *      ldy     #$xx
+ *      clc
+ *      adc     (sp),y
+ *      bcc     L
+ *      inx
+ * L:   ldy     #$00
+ *      jsr     ldauidx
+ *
+ * and replace it by:
+ *
+ *      ldy     #$xx
+ *      lda     (sp),y
+ *      tay
+ *      ldx     #$00
+ *      lda     label,y
+ */
+
+unsigned OptPtrLoad5 (CodeSeg* S);
+/* Search for the sequence:
+ *
+ *      clc
+ *      adc     xxx
+ *      bcc     L
+ *      inx
+ * L:   ldy     #$00
+ *      jsr     ldauidx
+ *
+ * and replace it by:
+ *
+ *      ldy     xxx
+ *      sta     ptr1
+ *      stx     ptr1+1
+ *      ldx     #$00
+ *      lda     (ptr1),y
+ */
+
+unsigned OptPtrLoad6 (CodeSeg* S);
+/* Search for the sequence:
+ *
+ *      lda     regbank+n
+ *      ldx     regbank+n+1
+ *      sta     regsave
+ *      stx     regsave+1
+ *      clc
+ *      adc     #$01
+ *      bcc     L0005
+ *      inx
+ * L:   sta     regbank+n
+ *      stx     regbank+n+1
+ *      lda     regsave
+ *      ldx     regsave+1
+ *      ldy     #$00
+ *      jsr     ldauidx
+ *
+ * and replace it by:
+ *
+ *      ldy     #$00
+ *      ldx     #$00
+ *      lda     (regbank+n),y
+ *      inc     regbank+n
+ *      bne     L1
+ *      inc     regbank+n+1
+ * L1:  tay                     <- only if flags are used
+ *
+ * This function must execute before OptPtrLoad7!
+ *
+ */
+
+unsigned OptPtrLoad7 (CodeSeg* S);
+/* Search for the sequence:
+ *
+ *      lda     zp
+ *      ldx     zp+1
+ *      ldy     xx
+ *      jsr     ldauidx
+ *
+ * and replace it by:
+ *
+ *      ldy     xx
+ *      ldx     #$00
+ *      lda     (zp),y
+ */
+
+unsigned OptPtrLoad8 (CodeSeg* S);
+/* Search for the sequence:
+ *
+ *      lda     zp
+ *      ldx     zp+1
+ *      (anything that doesn't change a/x)
+ *      ldy     xx
+ *      jsr     ldauidx
+ *
+ * and replace it by:
+ *
+ *      lda     zp
+ *      ldx     zp+1
+ *      (anything that doesn't change a/x)
+ *      ldy     xx
+ *      ldx     #$00
+ *      lda     (zp),y
+ *
+ * Must execute before OptPtrLoad10!
+ */
+
+unsigned OptPtrLoad9 (CodeSeg* S);
+/* Search for the sequence:
+ *
+ *      lda     zp
+ *      ldx     zp+1
+ *      ldy     xx
+ *      jsr     ldaxidx
+ *
+ * and replace it by:
+ *
+ *      ldy     xx
+ *      lda     (zp),y
+ *      tax
+ *      dey
+ *      lda     (zp),y
+ */
+
+unsigned OptPtrLoad10 (CodeSeg* S);
+/* Search for the sequence
+ *
+ *      ldy     ...
+ *      jsr     ldauidx
+ *
+ * and replace it by:
+ *
+ *      ldy     ...
+ *      stx     ptr1+1
+ *      sta     ptr1
+ *      ldx     #$00
+ *      lda     (ptr1),y
+ *
+ * This step must be executed *after* OptPtrLoad1!
+ */
+
+
+
+/* End of coptptrload.h */
+#endif
+
+
+
index 2bae8a73ae256b4584a05809a70541a0fe3dab7f..882f1898cddf8e5a1e3e626b53bcc8947c49515a 100644 (file)
@@ -43,6 +43,7 @@ OBJS =        anonname.o      \
        coptcmp.o       \
        coptind.o       \
        coptneg.o       \
+        coptptrload.o   \
        coptpush.o      \
         coptsize.o      \
        coptstop.o      \
index b861e169cb2656303298a57573f0d5439f25707c..2aaefbbfc63dd41b2442ea591e629dfccc1b29fc 100644 (file)
@@ -78,6 +78,7 @@ OBJS =        anonname.obj    \
        coptcmp.obj     \
        coptind.obj     \
        coptneg.obj     \
+        coptptrload.obj \
        coptpush.obj    \
         coptsize.obj    \
        coptstop.obj    \