]> git.sur5r.net Git - cc65/commitdiff
Improved optimizations
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Wed, 5 Nov 2003 19:09:53 +0000 (19:09 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Wed, 5 Nov 2003 19:09:53 +0000 (19:09 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@2613 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/cc65/codegen.c
src/cc65/coptind.c
src/cc65/coptstop.c

index c94ae2bfca1fe98f1b0714c09a7a133946969724..ef8405cc0ad0fcfb3f7d8ce842ffaa25defa6d41 100644 (file)
@@ -2772,7 +2772,7 @@ void g_or (unsigned flags, unsigned long val)
 
            case CF_CHAR:
                if (flags & CF_FORCECHAR) {
-                   if ((val & 0xFF) != 0xFF) {
+                   if ((val & 0xFF) != 0) {
                                AddCodeLine ("ora #$%02X", (unsigned char)val);
                    }
                    return;
@@ -2780,15 +2780,25 @@ void g_or (unsigned flags, unsigned long val)
                /* FALLTHROUGH */
 
            case CF_INT:
-               if (val <= 0xFF) {
-                   AddCodeLine ("ora #$%02X", (unsigned char)val);
+               if (val <= 0xFF) {       
+                    if ((val & 0xFF) != 0) {
+                       AddCodeLine ("ora #$%02X", (unsigned char)val);
+                    }
                    return;
-               }
+               } else if ((val & 0xFF00) == 0xFF00) {
+                    if ((val & 0xFF) != 0) {
+                       AddCodeLine ("ora #$%02X", (unsigned char)val);
+                    }
+                    ldxconst (0xFF);
+                    return;
+                }
                break;
 
            case CF_LONG:
                if (val <= 0xFF) {
-                   AddCodeLine ("ora #$%02X", (unsigned char)val);
+                    if ((val & 0xFF) != 0) {
+                        AddCodeLine ("ora #$%02X", (unsigned char)val);
+                    }
                    return;
                }
                break;
@@ -2881,68 +2891,70 @@ void g_xor (unsigned flags, unsigned long val)
 
 
 
-void g_and (unsigned flags, unsigned long val)
+void g_and (unsigned Flags, unsigned long Val)
 /* Primary = TOS & Primary */
 {
     static char* ops [12] = {
-       0,              "tosanda0",     "tosandax",
-       0,              "tosanda0",     "tosandax",
-       0,              0,              "tosandeax",
-       0,              0,              "tosandeax",
+       0,              "tosanda0",     "tosandax",
+       0,              "tosanda0",     "tosandax",
+       0,              0,              "tosandeax",
+       0,              0,              "tosandeax",
     };
-
+                    
     /* If the right hand side is const, the lhs is not on stack but still
      * in the primary register.
      */
-    if (flags & CF_CONST) {
+    if (Flags & CF_CONST) {
 
-       switch (flags & CF_TYPE) {
+       switch (Flags & CF_TYPE) {
 
            case CF_CHAR:
-               if (flags & CF_FORCECHAR) {
-                   AddCodeLine ("and #$%02X", (unsigned char)val);
-                   return;
-               }
-               /* FALLTHROUGH */
+               if (Flags & CF_FORCECHAR) {
+                    if ((Val & 0xFF) != 0xFF) {
+                        AddCodeLine ("and #$%02X", (unsigned char)Val);
+                    }
+                   return;
+               }
+               /* FALLTHROUGH */
            case CF_INT:
-               if ((val & 0xFFFF) != 0xFFFF) {
-                           if (val <= 0xFF) {
-                       ldxconst (0);
-                       if (val == 0) {
-                           ldaconst (0);
-                       } else if (val != 0xFF) {
-                           AddCodeLine ("and #$%02X", (unsigned char)val);
-                       }
-                   } else if ((val & 0xFF00) == 0xFF00) {
-                       AddCodeLine ("and #$%02X", (unsigned char)val);
-                   } else if ((val & 0x00FF) == 0x0000) {
-                       AddCodeLine ("txa");
-                       AddCodeLine ("and #$%02X", (unsigned char)(val >> 8));
-                       AddCodeLine ("tax");
-                       ldaconst (0);
+               if ((Val & 0xFFFF) != 0xFFFF) {
+                           if (Val <= 0xFF) {
+                       ldxconst (0);
+                       if (Val == 0) {
+                           ldaconst (0);
+                       } else if (Val != 0xFF) {
+                           AddCodeLine ("and #$%02X", (unsigned char)Val);
+                       }
+                   } else if ((Val & 0xFF00) == 0xFF00) {
+                       AddCodeLine ("and #$%02X", (unsigned char)Val);
+                   } else if ((Val & 0x00FF) == 0x0000) {
+                       AddCodeLine ("txa");
+                       AddCodeLine ("and #$%02X", (unsigned char)(Val >> 8));
+                       AddCodeLine ("tax");
+                       ldaconst (0);
                    } else {
-                       AddCodeLine ("tay");
-                       AddCodeLine ("txa");
-                       AddCodeLine ("and #$%02X", (unsigned char)(val >> 8));
-                       AddCodeLine ("tax");
-                       AddCodeLine ("tya");
-                       if ((val & 0x00FF) != 0x00FF) {
-                           AddCodeLine ("and #$%02X", (unsigned char)val);
-                       }
-                   }
-               }
+                       AddCodeLine ("tay");
+                       AddCodeLine ("txa");
+                       AddCodeLine ("and #$%02X", (unsigned char)(Val >> 8));
+                       AddCodeLine ("tax");
+                       AddCodeLine ("tya");
+                       if ((Val & 0x00FF) != 0x00FF) {
+                           AddCodeLine ("and #$%02X", (unsigned char)Val);
+                       }
+                   }
+               }
                return;
 
            case CF_LONG:
-               if (val <= 0xFF) {
+               if (Val <= 0xFF) {
                    ldxconst (0);
                    AddCodeLine ("stx sreg+1");
                    AddCodeLine ("stx sreg");
-                   if ((val & 0xFF) != 0xFF) {
-                        AddCodeLine ("and #$%02X", (unsigned char)val);
+                   if ((Val & 0xFF) != 0xFF) {
+                        AddCodeLine ("and #$%02X", (unsigned char)Val);
                    }
                    return;
-               } else if (val == 0xFF00) {
+               } else if (Val == 0xFF00) {
                    ldaconst (0);
                    AddCodeLine ("sta sreg+1");
                    AddCodeLine ("sta sreg");
@@ -2951,19 +2963,19 @@ void g_and (unsigned flags, unsigned long val)
                break;
 
            default:
-               typeerror (flags);
+               typeerror (Flags);
        }
 
        /* If we go here, we didn't emit code. Push the lhs on stack and fall
         * into the normal, non-optimized stuff. Note: The standard stuff will
          * always work with ints.
         */
-        flags &= ~CF_FORCECHAR;
-               g_push (flags & ~CF_CONST, 0);
+        Flags &= ~CF_FORCECHAR;
+               g_push (Flags & ~CF_CONST, 0);
     }
-
+                              
     /* Use long way over the stack */
-    oper (flags, val, ops);
+    oper (Flags, Val, ops);
 }
 
 
index aaddfeb856a21aee5caef329b4a137dd0d6f5eef..6941a2c024efcecc644ac1344d3548e3cdda9258 100644 (file)
@@ -1315,6 +1315,9 @@ unsigned OptPrecalc (CodeSeg* S)
                /* Get a pointer to the output registers of the insn */
                const RegContents* Out = &E->RI->Out;
 
+        /* Argument for LDA and flag */
+        const char* Arg = 0;
+
         /* Handle the different instructions */
         switch (E->OPC) {
 
@@ -1328,19 +1331,35 @@ unsigned OptPrecalc (CodeSeg* S)
                 /* FALLTHROUGH */
 
             case OP65_ADC:
-            case OP65_AND:
             case OP65_ASL:
             case OP65_EOR:
             case OP65_LSR:
-            case OP65_ORA:
             case OP65_SBC:
                 if (RegValIsKnown (Out->RegA)) {
                     /* Accu AND zp with known contents */
-                    const char* Arg = MakeHexArg (Out->RegA);
-                    CodeEntry* X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, E->LI);
-                    CS_InsertEntry (S, X, I+1);
+                    Arg = MakeHexArg (Out->RegA);
+                }
+                break;
+
+            case OP65_AND:
+                if (CE_KnownImm (E) && E->Num == 0xFF) {
+                    /* AND with 0xFF, remove */
                     CS_DelEntry (S, I);
                     ++Changes;
+                } else if (RegValIsKnown (Out->RegA)) {
+                    /* Accu AND zp with known contents */
+                    Arg = MakeHexArg (Out->RegA);
+                }
+                break;
+
+            case OP65_ORA:
+                if (CE_KnownImm (E) && E->Num == 0x00) {
+                    /* ORA with zero, remove */
+                    CS_DelEntry (S, I);
+                    ++Changes;
+                } else if (RegValIsKnown (Out->RegA)) {
+                    /* Accu AND zp with known contents */
+                    Arg = MakeHexArg (Out->RegA);
                 }
                 break;
 
@@ -1349,6 +1368,14 @@ unsigned OptPrecalc (CodeSeg* S)
 
         }
 
+        /* Check if we have to replace the insn by LDA */
+        if (Arg) {
+            CodeEntry* X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, E->LI);
+            CS_InsertEntry (S, X, I+1);
+            CS_DelEntry (S, I);
+            ++Changes;
+        }
+
        /* Next entry */
        ++I;
     }
index cd05efa1b79198797f928dce8784745596d4cbb9..cdeab844d8944afbfec7fd85d58f5d4b42c15db1 100644 (file)
@@ -287,7 +287,7 @@ static void AddOpLow (StackOpData* D, opc_t OPC)
     InsertEntry (D, X, D->IP++);
 }
 
-
+            
 
 static void AddOpHigh (StackOpData* D, opc_t OPC)
 /* Add an op for the high byte of an operator. Special cases (constant values
@@ -552,9 +552,10 @@ static unsigned Opt_tosorax (StackOpData* D)
     if (RegValIsKnown (D->PushEntry->RI->In.RegX) &&
         RegValIsKnown (D->OpEntry->RI->In.RegX)) {
        /* Both values known, precalculate the result */
-       const char* Arg = MakeHexArg (D->PushEntry->RI->In.RegX | D->OpEntry->RI->In.RegX);
-               X = NewCodeEntry (OP65_LDX, AM65_IMM, Arg, 0, D->OpEntry->LI);
-       InsertEntry (D, X, D->IP++);
+        unsigned char Result = D->PushEntry->RI->In.RegX | D->OpEntry->RI->In.RegX;
+        const char* Arg = MakeHexArg (Result);
+        X = NewCodeEntry (OP65_LDX, AM65_IMM, Arg, 0, D->OpEntry->LI);
+        InsertEntry (D, X, D->IP++);
     } else if (D->PushEntry->RI->In.RegX != 0) {
        /* High byte is unknown */
         AddOpHigh (D, OP65_ORA);