]> git.sur5r.net Git - cc65/commitdiff
First support for STZ
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Mon, 11 Mar 2002 06:29:54 +0000 (06:29 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Mon, 11 Mar 2002 06:29:54 +0000 (06:29 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@1187 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/cc65/codeent.c
src/cc65/codeopt.c
src/cc65/coptc02.c
src/cc65/coptc02.h
src/cc65/coptind.c
src/cc65/opcodes.c
src/cc65/opcodes.h
src/cc65/reginfo.c
src/cc65/reginfo.h

index 7cca0bd788863c11b41a2b60a53314736de64d02..bf568565ba577e954460e739de32e60055f0dc5d 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2001     Ullrich von Bassewitz                                        */
-/*              Wacholderweg 14                                              */
-/*              D-70597 Stuttgart                                            */
-/* EMail:       uz@musoftware.de                                             */
+/* (C) 2001-2002 Ullrich von Bassewitz                                       */
+/*               Wacholderweg 14                                             */
+/*               D-70597 Stuttgart                                           */
+/* EMail:        uz@musoftware.de                                            */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -420,6 +420,9 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
                } else if ((E->Chg & REG_SREG_HI) != 0 && In->SRegHi >= 0) {
                    Out->SRegHi = (In->SRegHi << 1) & 0xFF;
                }
+           } else if (E->AM == AM65_ZPX) {
+                /* Invalidates all ZP registers */
+                RC_InvalidateZP (Out);
            }
            break;
 
@@ -492,6 +495,9 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
                } else if ((E->Chg & REG_SREG_HI) != 0 && In->SRegHi >= 0) {
                    Out->SRegHi = (In->SRegHi - 1) & 0xFF;
                }
+           } else if (E->AM == AM65_ZPX) {
+                /* Invalidates all ZP registers */
+                RC_InvalidateZP (Out);
            }
            break;
 
@@ -532,6 +538,9 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
                } else if ((E->Chg & REG_SREG_HI) != 0 && In->SRegHi >= 0) {
                    Out->SRegHi = (In->SRegHi + 1) & 0xFF;
                }
+           } else if (E->AM == AM65_ZPX) {
+                /* Invalidates all ZP registers */
+                RC_InvalidateZP (Out);
            }
            break;
 
@@ -654,6 +663,9 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
                } else if (E->Chg & REG_SREG_HI) {
                    Out->SRegHi = (In->SRegHi >> 1) & 0xFF;
                }
+           } else if (E->AM == AM65_ZPX) {
+                /* Invalidates all ZP registers */
+                RC_InvalidateZP (Out);
            }
            break;
 
@@ -707,6 +719,9 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
                } else if (E->Chg & REG_SREG_HI) {
                    Out->SRegHi = -1;
                }
+           } else if (E->AM == AM65_ZPX) {
+                /* Invalidates all ZP registers */
+                RC_InvalidateZP (Out);
            }
            break;
 
@@ -719,6 +734,9 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
                } else if (E->Chg & REG_SREG_HI) {
                    Out->SRegHi = -1;
                }
+           } else if (E->AM == AM65_ZPX) {
+                /* Invalidates all ZP registers */
+                RC_InvalidateZP (Out);
            }
            break;
 
@@ -749,27 +767,49 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
                } else if (E->Chg & REG_SREG_HI) {
                    Out->SRegHi = In->RegA;
                }
+           } else if (E->AM == AM65_ZPX) {
+                /* Invalidates all ZP registers */
+                RC_InvalidateZP (Out);
            }
            break;
 
        case OP65_STX:
            if (E->AM == AM65_ZP) {
-               if (E->Chg & REG_SREG_LO) {
-                   Out->SRegLo = In->RegX;
-               } else if (E->Chg & REG_SREG_HI) {
-                   Out->SRegHi = In->RegX;
-               }
+               if (E->Chg & REG_SREG_LO) {
+                   Out->SRegLo = In->RegX;
+               } else if (E->Chg & REG_SREG_HI) {
+                   Out->SRegHi = In->RegX;
+               }
+           } else if (E->AM == AM65_ZPX) {
+                /* Invalidates all ZP registers */
+                RC_InvalidateZP (Out);
            }
            break;
 
        case OP65_STY:
            if (E->AM == AM65_ZP) {
-               if (E->Chg & REG_SREG_LO) {
-                   Out->SRegLo = In->RegY;
-               } else if (E->Chg & REG_SREG_HI) {
-                   Out->SRegHi = In->RegY;
-               }
-           }
+               if (E->Chg & REG_SREG_LO) {
+                   Out->SRegLo = In->RegY;
+               } else if (E->Chg & REG_SREG_HI) {
+                   Out->SRegHi = In->RegY;
+               }
+           } else if (E->AM == AM65_ZPX) {
+                /* Invalidates all ZP registers */
+                RC_InvalidateZP (Out);
+            }
+           break;
+
+       case OP65_STZ:
+           if (E->AM == AM65_ZP) {
+               if (E->Chg & REG_SREG_LO) {
+                   Out->SRegLo = 0;
+               } else if (E->Chg & REG_SREG_HI) {
+                   Out->SRegHi = 0;
+               }
+           } else if (E->AM == AM65_ZPX) {
+                /* Invalidates all ZP registers */
+                RC_InvalidateZP (Out);
+            }
            break;
 
        case OP65_TAX:
index 9bf94bbd0a67fe54da433a1ee671878974c5e515..a964f7482f49af455c7f61b8162ec6cef70e2a04 100644 (file)
@@ -1278,7 +1278,7 @@ static unsigned OptSize2 (CodeSeg* S)
                        X = NewCodeEntry (OP65_INX, AM65_IMP, 0, 0, E->LI);
                    } else if (Val == E->RI->In.RegA) {
                        X = NewCodeEntry (OP65_TAX, AM65_IMP, 0, 0, E->LI);
-                   }
+                    }
                }
                break;
 
@@ -1351,6 +1351,7 @@ struct OptFunc {
 /* A list of all the function descriptions */
 static OptFunc DOpt65C02BitOps  = { Opt65C02BitOps,  "Opt65C02BitOps",   66, 0, 0, 0, 0, 0 };
 static OptFunc DOpt65C02Ind            = { Opt65C02Ind,     "Opt65C02Ind",     100, 0, 0, 0, 0, 0 };
+static OptFunc DOpt65C02Stores  = { Opt65C02Stores,  "Opt65C02Stores",  100, 0, 0, 0, 0, 0 };
 static OptFunc DOptAdd1                = { OptAdd1,         "OptAdd1",          60, 0, 0, 0, 0, 0 };
 static OptFunc DOptAdd2                = { OptAdd2,         "OptAdd2",         200, 0, 0, 0, 0, 0 };
 static OptFunc DOptAdd3                = { OptAdd3,         "OptAdd3",          40, 0, 0, 0, 0, 0 };
@@ -1406,6 +1407,7 @@ static OptFunc DOptUnusedStores   = { OptUnusedStores, "OptUnusedStores",   0, 0,
 static OptFunc* OptFuncs[] = {
     &DOpt65C02BitOps,
     &DOpt65C02Ind,
+    &DOpt65C02Stores,
     &DOptAdd1,
     &DOptAdd2,
     &DOptAdd3,
@@ -1775,17 +1777,17 @@ static unsigned RunOptGroup3 (CodeSeg* S)
 static unsigned RunOptGroup4 (CodeSeg* S)
 /* 65C02 specific optimizations. */
 {
-    unsigned C;
     unsigned Changes = 0;
 
     if (CPU >= CPU_65C02) {
         Changes += RunOptFunc (S, &DOpt65C02BitOps, 1);
-       /* Replace (zp),y by (zp) if Y is zero. If we have changes, run register
-        * load optimization again, since loads of Y may have become unnecessary.
-        */
-       C = RunOptFunc (S, &DOpt65C02Ind, 1);
-       Changes += C;
-       if (C) {
+       Changes += RunOptFunc (S, &DOpt65C02Ind, 1);
+        Changes += RunOptFunc (S, &DOpt65C02Stores, 1);
+               if (Changes) {
+            /* The 65C02 replacement codes do often make the use of a register
+             * value unnecessary, so if we have changes, run another load
+             * removal pass.
+             */
            Changes += RunOptFunc (S, &DOptUnusedLoads, 1);
        }
     }
index b7f765c63b4bcb226e4792d4dca8383f8ddc29c0..816f92c52e95f6c44f080ff248eb86efbafe57f3 100644 (file)
@@ -146,26 +146,73 @@ unsigned Opt65C02BitOps (CodeSeg* S)
                 /* LDA #XX */
                 sprintf (Buf, "$%02X", (int) ((~L[1]->Num) & 0xFF));
                 X = NewCodeEntry (OP65_LDA, AM65_IMM, Buf, 0, L[1]->LI);
-                CS_InsertEntry (S, X, I);
+                CS_InsertEntry (S, X, I+3);
 
                 /* TRB */
                 X = NewCodeEntry (OP65_TRB, L[0]->AM, L[0]->Arg, 0, L[0]->LI);
-                CS_InsertEntry (S, X, I+1);
+                CS_InsertEntry (S, X, I+4);
 
             } else {
 
                 /* LDA #XX */
                 sprintf (Buf, "$%02X", (int) L[1]->Num);
                 X = NewCodeEntry (OP65_LDA, AM65_IMM, Buf, 0, L[1]->LI);
-                CS_InsertEntry (S, X, I);
+                CS_InsertEntry (S, X, I+3);
 
-                /* TRB */
+                /* TSB */
                 X = NewCodeEntry (OP65_TSB, L[0]->AM, L[0]->Arg, 0, L[0]->LI);
-                CS_InsertEntry (S, X, I+1);
+                CS_InsertEntry (S, X, I+4);
             }
 
             /* Delete the old stuff */
-            CS_DelEntries (S, I+2, 3);
+            CS_DelEntries (S, I, 3);
+
+           /* We had changes */
+           ++Changes;
+       }
+
+       /* Next entry */
+       ++I;
+
+    }
+
+    /* Free register info */
+    CS_FreeRegInfo (S);
+
+    /* Return the number of changes made */
+    return Changes;
+}
+
+
+
+unsigned Opt65C02Stores (CodeSeg* S)
+/* Use STZ where possible */
+{
+    unsigned Changes = 0;
+    unsigned I;
+
+    /* Generate register info for this step */
+    CS_GenRegInfo (S);
+
+    /* Walk over the entries */
+    I = 0;
+    while (I < CS_GetEntryCount (S)) {
+
+       /* Get next entry */
+               CodeEntry* E = CS_GetEntry (S, I);
+
+       /* Check for the sequence */
+       if (E->OPC == OP65_STA                          &&
+            (E->AM == AM65_ZP  || E->AM == AM65_ABS ||
+             E->AM == AM65_ZPX || E->AM == AM65_ABSX )  &&
+            E->RI->In.RegA == 0) {
+
+            /* Replace by STZ */
+            CodeEntry* X = NewCodeEntry (OP65_STZ, E->AM, E->Arg, 0, E->LI);
+            CS_InsertEntry (S, X, I+1);
+
+            /* Delete the old stuff */
+            CS_DelEntry (S, I);
 
            /* We had changes */
            ++Changes;
index 743efb971b274a109e3e4331c7c1bd472f29f2bb..309e4578a98f9e6bdae65c7d34b5e8ea09cc08ac 100644 (file)
@@ -55,6 +55,9 @@ unsigned Opt65C02Ind (CodeSeg* S);
 unsigned Opt65C02BitOps (CodeSeg* S);
 /* Use special bit op instructions of the C02 */
 
+unsigned Opt65C02Stores (CodeSeg* S);
+/* Use STZ where possible */
+
 
 
 /* End of coptc02.h */
index 605c70317ca0e78511477e76aa906cba5dd65e89..c68918363a89b28658e844cca5b257b6c1fde12b 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                                                 */
@@ -850,12 +850,12 @@ unsigned OptDupLoads (CodeSeg* S)
                 * location does already contain the value to be stored,
                 * remove the store.
                 */
-               if (In->RegX >= 0                     && /* Value of A is known */
+               if (In->RegY >= 0                     && /* Value of Y is known */
                    E->AM == AM65_ZP                  && /* Store into zp */
                    (((E->Chg & REG_SREG_LO) != 0 &&     /* Store into sreg */
-                     In->RegX == In->SRegLo)       ||   /* Value identical */
+                     In->RegY == In->SRegLo)       ||   /* Value identical */
                             ((E->Chg & REG_SREG_HI) != 0 &&     /* Store into sreg+1 */
-                             In->RegX == In->SRegHi))) {        /* Value identical */
+                             In->RegY == In->SRegHi))) {        /* Value identical */
                    Delete = 1;
                /* If the value in the Y register is known and the same as
                 * that in the A register, replace the store by a STA. The
@@ -866,15 +866,28 @@ unsigned OptDupLoads (CodeSeg* S)
                 */
                        } else if (In->RegY >= 0) {
                    if (In->RegY == In->RegA) {
-                       CE_ReplaceOPC (E, OP65_STA);
+                       CE_ReplaceOPC (E, OP65_STA);
                    } else if (In->RegY == In->RegX   &&
-                              E->AM != AM65_ABSX     &&
-                              E->AM != AM65_ZPX) {
+                              E->AM != AM65_ABSX     &&
+                              E->AM != AM65_ZPX) {
                        CE_ReplaceOPC (E, OP65_STX);
                    }
                }
                break;
 
+           case OP65_STZ:
+               /* If we store into a known zero page location, and this
+                * location does already contain the value to be stored,
+                * remove the store.
+                */
+                       if (CPU >= CPU_65C02 && E->AM == AM65_ZP) {
+                    if (((E->Chg & REG_SREG_LO) != 0 && In->SRegLo == 0) ||
+                        ((E->Chg & REG_SREG_HI) != 0 && In->SRegHi == 0)) {
+                        Delete = 1;
+                    }
+               }
+               break;
+
            case OP65_TAX:
                 if (In->RegA >= 0                     &&
                    In->RegA == In->RegX              &&
index 6704bef3b5a29eb41470c87ca12502b1f08e6482..d55a5371fffa950320486e4693c54d36d0740b12 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                                                 */
@@ -513,6 +513,13 @@ const OPCDesc OPCTable[OPCODE_COUNT] = {
                REG_NONE,                               /* chg */
        OF_STORE                                /* flags */
     },
+    {   OP65_STZ,                                      /* opcode */
+               "stz",                                  /* mnemonic */
+               0,                                      /* size */
+               REG_NONE,                               /* use */
+               REG_NONE,                               /* chg */
+       OF_STORE                                /* flags */
+    },
     {   OP65_TAX,                                      /* opcode */
                "tax",                                  /* mnemonic */
                1,                                      /* size */
@@ -777,7 +784,7 @@ bc_t GetBranchCond (opc_t OPC)
                case OP65_JPL:  return BC_PL;
                case OP65_JVC:  return BC_VC;
                case OP65_JVS:  return BC_VS;
-       default:        
+       default:
            Internal ("GetBranchCond: Invalid opcode: %d", OPC);
            return 0;
     }
@@ -805,4 +812,4 @@ bc_t GetInverseCond (bc_t BC)
 
 
 
-           
+
index ec798db22c217ce5e9ea05484c20eb3e60b66a89..89a7c4117ee417dd30f05f69c32c716ee8fe9436 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                                                 */
@@ -118,6 +118,7 @@ typedef enum {
     OP65_STA,
     OP65_STX,
     OP65_STY,
+    OP65_STZ,
     OP65_TAX,
     OP65_TAY,
     OP65_TRB,
index c8a6d094b4bfec40008f7372c649cf2f7dcd4078..ab60e7315c92c0b2458ba126a0c777eb3e9c1f2a 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                                                 */
@@ -59,6 +59,15 @@ void RC_Invalidate (RegContents* C)
 
 
 
+void RC_InvalidateZP (RegContents* C)
+/* Invalidate all ZP registers */    
+{
+    C->SRegLo = -1;
+    C->SRegHi = -1;
+}
+
+
+
 RegInfo* NewRegInfo (const RegContents* RC)
 /* Allocate a new register info, initialize and return it. If RC is not
  * a NULL pointer, it is used to initialize both, the input and output
index bcf760b1691209ee099f555477a5acd4365b9c02..aac4c7c8159bdb5f5c742c7665e7d7676884b2ae 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2001      Ullrich von Bassewitz                                       */
-/*               Wacholderweg 14                                             */
-/*               D-70597 Stuttgart                                           */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 2001-2002  Ullrich von Bassewitz                                      */
+/*                Wacholderweg 14                                            */
+/*                D-70597 Stuttgart                                          */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -78,6 +78,9 @@ struct RegInfo {
 void RC_Invalidate (RegContents* C);
 /* Invalidate all registers */
 
+void RC_InvalidateZP (RegContents* C);
+/* Invalidate all ZP registers */
+
 RegInfo* NewRegInfo (const RegContents* RC);
 /* Allocate a new register info, initialize and return it. If RC is not
  * a NULL pointer, it is used to initialize both, the input and output