]> git.sur5r.net Git - cc65/commitdiff
Added more optimizations
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Tue, 17 Jul 2001 20:13:33 +0000 (20:13 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Tue, 17 Jul 2001 20:13:33 +0000 (20:13 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@804 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/cc65/codeinfo.c
src/cc65/codeopt.c
src/cc65/coptind.c
src/cc65/coptind.h
src/cc65/opcodes.c
src/cc65/opcodes.h

index 1885306dea10fe1a3d48c1d8328be472c420b3cc..7702a37ec0851655329e50f85134e53151b6a24c 100644 (file)
@@ -67,6 +67,9 @@ struct FuncInfo {
 
 static const FuncInfo FuncInfoTable[] = {
     { "addysp",                REG_Y,          REG_NONE        },
+    { "bnega",          REG_A,          REG_AX          },
+    { "bnegax",         REG_AX,         REG_AX          },
+    { "bnegeax",        REG_AX,         REG_AX          },
     { "booleq",                REG_NONE,       REG_AX          },
     { "boolge",                REG_NONE,       REG_AX          },
     { "boolgt",                REG_NONE,       REG_AX          },
@@ -77,6 +80,7 @@ static const FuncInfo FuncInfoTable[] = {
     { "boolugt",       REG_NONE,       REG_AX          },
     { "boolule",       REG_NONE,       REG_AX          },
     { "boolult",       REG_NONE,       REG_AX          },
+    { "complax",        REG_AX,         REG_AX          },
     { "decax1",        REG_AX,         REG_AX          },
     { "decax2",        REG_AX,         REG_AX          },
     { "decax3",        REG_AX,         REG_AX          },
@@ -94,6 +98,8 @@ static const FuncInfo FuncInfoTable[] = {
     { "decsp6",        REG_NONE,       REG_A           },
     { "decsp7",        REG_NONE,       REG_A           },
     { "decsp8",        REG_NONE,       REG_A           },
+    { "incax1",         REG_AX,         REG_AX          },
+    { "incax2",         REG_AX,         REG_AX          },
     { "incsp1",                REG_NONE,       REG_NONE        },
     { "incsp2",                REG_NONE,       REG_Y           },
     { "incsp3",                REG_NONE,       REG_Y           },
@@ -109,12 +115,22 @@ static const FuncInfo FuncInfoTable[] = {
     { "ldaxidx",        REG_AXY,        REG_AX          },
     { "ldaxysp",       REG_Y,          REG_AX          },
     { "leaasp",         REG_A,          REG_AX          },
+    { "negax",          REG_AX,         REG_AX          },
     { "pusha",         REG_A,          REG_Y           },
     { "pusha0",                REG_A,          REG_XY          },
     { "pushax",                REG_AX,         REG_Y           },
+    { "pusheax",        REG_AX,         REG_Y           },
     { "pushw0sp",      REG_NONE,       REG_AXY         },
     { "pushwysp",      REG_Y,          REG_AXY         },
+    { "shrax1",         REG_AX,         REG_AX          },
+    { "shrax2",         REG_AX,         REG_AX          },
+    { "shrax3",         REG_AX,         REG_AX          },
+    { "shreax1",        REG_AX,         REG_AX          },
+    { "shreax2",        REG_AX,         REG_AX          },
+    { "shreax3",        REG_AX,         REG_AX          },
+    { "staspidx",       REG_A | REG_Y,  REG_Y           },
     { "tosicmp",       REG_AX,         REG_AXY         },
+    { "tosshreax",      REG_AX,                REG_AXY         },
 };
 #define FuncInfoCount  (sizeof(FuncInfoTable) / sizeof(FuncInfoTable[0]))
 
index 470836942a82b92d81e25670a3e8a82d38e7217a..c596068be0f280b9200f1378ed2d7a2142e82100 100644 (file)
@@ -1297,6 +1297,7 @@ static OptFunc OptFuncs [] = {
     /* Remove unused loads */
     { OptUnusedLoads,      "OptUnusedLoads",           0       },
     { OptDuplicateLoads,    "OptDuplicateLoads",        0       },
+    { OptStoreLoad,         "OptStoreLoad",             0       },
     /* Optimize branch distance */
     { OptBranchDist,               "OptBranchDist",            0       },
 };
index 0987d37db61ebc4c129d24e9b53ed5f0f4557473..ba1ffdc7fb87f4b3c51e88d91b9478ac676146e4 100644 (file)
@@ -682,7 +682,7 @@ unsigned OptDuplicateLoads (CodeSeg* S)
 
        unsigned char Use, Chg;
        CodeEntry* N;
-                                    
+
        /* Get next entry */
                CodeEntry* E = CS_GetEntry (S, I);
 
@@ -797,7 +797,7 @@ unsigned OptDuplicateLoads (CodeSeg* S)
                                RegA ^= (int) E->Num;
                    } else {
                        RegA = -1;
-                   }
+                   }
                }
                break;
 
@@ -994,10 +994,16 @@ unsigned OptDuplicateLoads (CodeSeg* S)
                /* 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
                 * optimizer will then remove the load instruction for Y
-                * later.
+                * later. If replacement by A is not possible try a
+                * replacement by X, but check for invalid addressing modes
+                * in this case.
                 */
-                       if (RegY >= 0 && RegY == RegA) {
-                   CE_ReplaceOPC (E, OP65_STA);
+                       if (RegY >= 0) {
+                   if (RegY == RegA) {
+                       CE_ReplaceOPC (E, OP65_STA);
+                   } else if (RegY == RegX && E->AM != AM65_ABSX && E->AM != AM65_ZPX) {
+                       CE_ReplaceOPC (E, OP65_STX);
+                   }
                }
                break;
 
@@ -1012,7 +1018,7 @@ unsigned OptDuplicateLoads (CodeSeg* S)
                break;
 
            case OP65_TAY:
-               N = CS_GetNextEntry (S, I);
+               N = CS_GetNextEntry (S, I);
                        if (RegA >= 0 && RegA == RegY && N && (N->Info & OF_FBRA) == 0) {
                    /* Value is identical and not followed by a branch */
                    Delete = 1;
@@ -1083,6 +1089,50 @@ unsigned OptDuplicateLoads (CodeSeg* S)
 
 
 
+unsigned OptStoreLoad (CodeSeg* S)
+/* Remove a store followed by a load from the same location. */
+{
+    unsigned Changes = 0;
+
+    /* Walk over the entries */
+    unsigned I = 0;
+    while (I < CS_GetEntryCount (S)) {
+
+       CodeEntry* N;
+       CodeEntry* X;
+
+       /* Get next entry */
+               CodeEntry* E = CS_GetEntry (S, I);
+
+       /* Check if it is a store instruction followed by a load from the
+        * same address which is itself not followed by a conditional branch.
+        */
+       if ((E->Info & OF_STORE) != 0                 &&
+           (N = CS_GetNextEntry (S, I)) != 0         &&
+                   (N->Info & OF_LOAD) != 0                  &&
+           strcmp (E->Arg, N->Arg) == 0              &&
+           (X = CS_GetNextEntry (S, I+1)) != 0       &&
+                   (X->Info & OF_FBRA) == 0) {
+
+           /* Register value is not used, remove the load */
+           CS_DelEntry (S, I+1);
+
+           /* Remember, we had changes */
+           ++Changes;
+
+       }
+
+       /* Next entry */
+       ++I;
+
+    }
+
+    /* Return the number of changes made */
+    return Changes;
+}
+
+
+
 /*****************************************************************************/
 /*                          Optimize branch types                           */
 /*****************************************************************************/
index a5bb5635b8c6cbc34392db819a3d5acdc4da5a31..30d9d157742da755bb420e16e6afa0d3fe1ab2c7 100644 (file)
@@ -92,6 +92,9 @@ unsigned OptUnusedLoads (CodeSeg* S);
 unsigned OptDuplicateLoads (CodeSeg* S);
 /* Remove loads of registers where the value loaded is already in the register. */
 
+unsigned OptStoreLoad (CodeSeg* S);
+/* Remove a store followed by a load from the same location. */
+
 unsigned OptBranchDist (CodeSeg* S);
 /* Change branches for the distance needed. */
 
index 167e1f19c0aeab85051a2446f4beb22c2a8c216c..f702078710748b36f12272ed9acb6bdd2f42142a 100644 (file)
@@ -611,21 +611,21 @@ const OPCDesc OPCTable[OPCODE_COUNT] = {
                0,                                      /* size */
                REG_A,                                  /* use */
                REG_NONE,                               /* chg */
-       OF_NONE                                 /* flags */
+       OF_STORE                                /* flags */
     },
     {   OP65_STX,                                      /* opcode */
                "stx",                                  /* mnemonic */
                0,                                      /* size */
                REG_X,                                  /* use */
                REG_NONE,                               /* chg */
-       OF_NONE                                 /* flags */
+       OF_STORE                                /* flags */
     },
     {   OP65_STY,                                      /* opcode */
                "sty",                                  /* mnemonic */
                0,                                      /* size */
                REG_Y,                                  /* use */
                REG_NONE,                               /* chg */
-       OF_NONE                                 /* flags */
+       OF_STORE                                /* flags */
     },
     {   OP65_TAX,                                      /* opcode */
                "tax",                                  /* mnemonic */
index e2369aa19da90761bd17d9c2b2c4726e5e43625d..990a878e50c6aae852fcc105c8576732b13158de 100644 (file)
@@ -203,8 +203,9 @@ typedef enum {
 #define OF_LBRA         0x0100U        /* Jump/branch is long */
 #define OF_RET                 0x0200U /* Return from function */
 #define OF_LOAD         0x0400U        /* Register load */
-#define OF_XFR          0x0800U /* Transfer instruction */
-#define OF_CALL         0x1000U /* A subroutine call */
+#define OF_STORE        0x0800U /* Register store */
+#define OF_XFR          0x1000U /* Transfer instruction */
+#define OF_CALL         0x2000U /* A subroutine call */
 
 /* Combined infos */
 #define OF_BRA         (OF_UBRA | OF_CBRA)     /* Operation is a jump/branch */