]> git.sur5r.net Git - cc65/commitdiff
More zeropage variable tracking in the optimizer
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Wed, 1 Oct 2003 13:05:35 +0000 (13:05 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Wed, 1 Oct 2003 13:05:35 +0000 (13:05 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@2460 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/cc65/codeent.c
src/cc65/codeinfo.c
src/cc65/codeopt.c
src/cc65/coptind.c
src/cc65/reginfo.c
src/cc65/reginfo.h

index b4a567b72bda399dda749764b029c807985256a3..b74c1e8d37fd8ec9df4d1bf2d29aed367c9a4902 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2001-2002 Ullrich von Bassewitz                                       */
-/*               Wacholderweg 14                                             */
-/*               D-70597 Stuttgart                                           */
-/* EMail:        uz@musoftware.de                                            */
+/* (C) 2001-2003 Ullrich von Bassewitz                                       */
+/*               Römerstrasse 52                                             */
+/*               D-70794 Filderstadt                                         */
+/* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -427,6 +427,19 @@ void CE_FreeRegInfo (CodeEntry* E)
 
 
 
+#if 0   /* Used for debugging */
+static void DumpRegInfo (const char* Desc, const RegInfo* RI)
+{
+    fprintf (stdout, "%s:\n", Desc);
+    fprintf (stdout, "In:  ");
+    RC_Dump (stdout, &RI->In);
+    fprintf (stdout, "Out: ");
+    RC_Dump (stdout, &RI->Out);
+}
+#endif
+
+
+
 void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
 /* Generate register info for this instruction. If an old info exists, it is
  * overwritten.
@@ -470,10 +483,16 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
                if (CE_KnownImm (E)) {
                    Out->RegA = In->RegA & (short) E->Num;
                } else if (E->AM == AM65_ZP) {
-                   switch (GetKnownReg (E->Use, In)) {
+                   switch (GetKnownReg (E->Use & REG_ZP, In)) {
                        case REG_TMP1:
                            Out->RegA = In->RegA & In->Tmp1;
                            break;
+                       case REG_PTR1_LO:
+                           Out->RegA = In->RegA & In->Ptr1Lo;
+                           break;
+                       case REG_PTR1_HI:
+                           Out->RegA = In->RegA & In->Ptr1Hi;
+                           break;
                        case REG_SREG_LO:
                            Out->RegA = In->RegA & In->SRegLo;
                            break;
@@ -482,7 +501,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
                            break;
                        default:
                            Out->RegA = UNKNOWN_REGVAL;
-                           break;
+                           break;
                    }
                } else {
                    Out->RegA = UNKNOWN_REGVAL;
@@ -494,10 +513,16 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
            if (E->AM == AM65_ACC && In->RegA >= 0) {
                Out->RegA = (In->RegA << 1) & 0xFF;
            } else if (E->AM == AM65_ZP) {
-               switch (GetKnownReg (E->Chg, In)) {
+               switch (GetKnownReg (E->Chg & REG_ZP, In)) {
                    case REG_TMP1:
                        Out->Tmp1 = (In->Tmp1 << 1) & 0xFF;
                        break;
+                   case REG_PTR1_LO:
+                       Out->Ptr1Lo = (In->Ptr1Lo << 1) & 0xFF;
+                       break;
+                   case REG_PTR1_HI:
+                       Out->Ptr1Hi = (In->Ptr1Hi << 1) & 0xFF;
+                       break;
                    case REG_SREG_LO:
                        Out->SRegLo = (In->SRegLo << 1) & 0xFF;
                        break;
@@ -575,10 +600,16 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
            if (E->AM == AM65_ACC && In->RegA >= 0) {
                Out->RegA = (In->RegA - 1) & 0xFF;
            } else if (E->AM == AM65_ZP) {
-               switch (GetKnownReg (E->Chg, In)) {
+               switch (GetKnownReg (E->Chg & REG_ZP, In)) {
                    case REG_TMP1:
                        Out->Tmp1 = (In->Tmp1 - 1) & 0xFF;
                        break;
+                   case REG_PTR1_LO:
+                       Out->Ptr1Lo = (In->Ptr1Lo - 1) & 0xFF;
+                       break;
+                   case REG_PTR1_HI:
+                       Out->Ptr1Hi = (In->Ptr1Hi - 1) & 0xFF;
+                       break;
                    case REG_SREG_LO:
                        Out->SRegLo = (In->SRegLo - 1) & 0xFF;
                        break;
@@ -609,10 +640,16 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
                if (CE_KnownImm (E)) {
                    Out->RegA = In->RegA ^ (short) E->Num;
                } else if (E->AM == AM65_ZP) {
-                   switch (GetKnownReg (E->Use, In)) {
+                   switch (GetKnownReg (E->Use & REG_ZP, In)) {
                        case REG_TMP1:
                            Out->RegA = In->RegA ^ In->Tmp1;
                            break;
+                       case REG_PTR1_LO:
+                           Out->RegA = In->RegA ^ In->Ptr1Lo;
+                           break;
+                       case REG_PTR1_HI:
+                           Out->RegA = In->RegA ^ In->Ptr1Hi;
+                           break;
                        case REG_SREG_LO:
                            Out->RegA = In->RegA ^ In->SRegLo;
                            break;
@@ -639,10 +676,16 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
            if (E->AM == AM65_ACC && In->RegA >= 0) {
                Out->RegA = (In->RegA + 1) & 0xFF;
            } else if (E->AM == AM65_ZP) {
-               switch (GetKnownReg (E->Chg, In)) {
+               switch (GetKnownReg (E->Chg & REG_ZP, In)) {
                    case REG_TMP1:
                        Out->Tmp1 = (In->Tmp1 + 1) & 0xFF;
                        break;
+                   case REG_PTR1_LO:
+                       Out->Ptr1Lo = (In->Ptr1Lo + 1) & 0xFF;
+                       break;
+                   case REG_PTR1_HI:
+                       Out->Ptr1Hi = (In->Ptr1Hi + 1) & 0xFF;
+                       break;
                    case REG_SREG_LO:
                        Out->SRegLo = (In->SRegLo + 1) & 0xFF;
                        break;
@@ -704,6 +747,12 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
            if (Chg & REG_TMP1) {
                Out->Tmp1 = UNKNOWN_REGVAL;
            }
+            if (Chg & REG_PTR1_LO) {
+               Out->Ptr1Lo = UNKNOWN_REGVAL;
+           }
+           if (Chg & REG_PTR1_HI) {
+               Out->Ptr1Hi = UNKNOWN_REGVAL;
+           }
             if (Chg & REG_SREG_LO) {
                Out->SRegLo = UNKNOWN_REGVAL;
            }
@@ -740,10 +789,16 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
            if (CE_KnownImm (E)) {
                Out->RegA = (unsigned char) E->Num;
            } else if (E->AM == AM65_ZP) {
-               switch (GetKnownReg (E->Use, In)) {
+               switch (GetKnownReg (E->Use & REG_ZP, In)) {
                    case REG_TMP1:
                        Out->RegA = In->Tmp1;
                        break;
+                   case REG_PTR1_LO:
+                       Out->RegA = In->Ptr1Lo;
+                       break;
+                   case REG_PTR1_HI:
+                       Out->RegA = In->Ptr1Hi;
+                       break;
                    case REG_SREG_LO:
                        Out->RegA = In->SRegLo;
                        break;
@@ -764,10 +819,16 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
            if (CE_KnownImm (E)) {
                Out->RegX = (unsigned char) E->Num;
            } else if (E->AM == AM65_ZP) {
-               switch (GetKnownReg (E->Use, In)) {
+               switch (GetKnownReg (E->Use & REG_ZP, In)) {
                    case REG_TMP1:
                        Out->RegX = In->Tmp1;
                        break;
+                   case REG_PTR1_LO:
+                       Out->RegX = In->Ptr1Lo;
+                       break;
+                   case REG_PTR1_HI:
+                       Out->RegX = In->Ptr1Hi;
+                       break;
                    case REG_SREG_LO:
                        Out->RegX = In->SRegLo;
                        break;
@@ -788,10 +849,16 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
            if (CE_KnownImm (E)) {
                Out->RegY = (unsigned char) E->Num;
            } else if (E->AM == AM65_ZP) {
-               switch (GetKnownReg (E->Use, In)) {
+               switch (GetKnownReg (E->Use & REG_ZP, In)) {
                    case REG_TMP1:
                        Out->RegY = In->Tmp1;
                        break;
+                   case REG_PTR1_LO:
+                       Out->RegY = In->Ptr1Lo;
+                       break;
+                   case REG_PTR1_HI:
+                       Out->RegY = In->Ptr1Hi;
+                       break;
                    case REG_SREG_LO:
                        Out->RegY = In->SRegLo;
                        break;
@@ -812,10 +879,16 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
            if (E->AM == AM65_ACC && In->RegA >= 0) {
                Out->RegA = (In->RegA >> 1) & 0xFF;
            } else if (E->AM == AM65_ZP) {
-               switch (GetKnownReg (E->Chg, In)) {
+               switch (GetKnownReg (E->Chg & REG_ZP, In)) {
                    case REG_TMP1:
                        Out->Tmp1 = (In->Tmp1 >> 1) & 0xFF;
                        break;
+                   case REG_PTR1_LO:
+                       Out->Ptr1Lo = (In->Ptr1Lo >> 1) & 0xFF;
+                       break;
+                   case REG_PTR1_HI:
+                       Out->Ptr1Hi = (In->Ptr1Hi >> 1) & 0xFF;
+                       break;
                    case REG_SREG_LO:
                        Out->SRegLo = (In->SRegLo >> 1) & 0xFF;
                        break;
@@ -834,27 +907,33 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
 
        case OP65_ORA:
            if (RegValIsKnown (In->RegA)) {
-               if (CE_KnownImm (E)) {
-                   Out->RegA = In->RegA | (short) E->Num;
-               } else if (E->AM == AM65_ZP) {
-                   switch (GetKnownReg (E->Use, In)) {
-                       case REG_TMP1:
-                           Out->RegA = In->RegA | In->Tmp1;
-                           break;
-                       case REG_SREG_LO:
-                           Out->RegA = In->RegA | In->SRegLo;
-                           break;
-                       case REG_SREG_HI:
-                           Out->RegA = In->RegA | In->SRegHi;
-                           break;
-                       default:
-                           Out->RegA = UNKNOWN_REGVAL;
-                           break;
-                   }
-               } else {
-                   /* A is now unknown */
-                   Out->RegA = UNKNOWN_REGVAL;
-               }
+               if (CE_KnownImm (E)) {
+                   Out->RegA = In->RegA | (short) E->Num;
+               } else if (E->AM == AM65_ZP) {
+                   switch (GetKnownReg (E->Use & REG_ZP, In)) {
+                       case REG_TMP1:
+                           Out->RegA = In->RegA | In->Tmp1;
+                           break;
+                       case REG_PTR1_LO:
+                           Out->RegA = In->RegA | In->Ptr1Lo;
+                           break;
+                       case REG_PTR1_HI:
+                           Out->RegA = In->RegA | In->Ptr1Hi;
+                           break;
+                       case REG_SREG_LO:
+                           Out->RegA = In->RegA | In->SRegLo;
+                           break;
+                       case REG_SREG_HI:
+                           Out->RegA = In->RegA | In->SRegHi;
+                           break;
+                       default:
+                           Out->RegA = UNKNOWN_REGVAL;
+                           break;
+                   }
+               } else {
+                   /* A is now unknown */
+                   Out->RegA = UNKNOWN_REGVAL;
+               }
            }
            break;
 
@@ -871,18 +950,18 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
            break;
 
        case OP65_PLA:
-           Out->RegA = -1;
+           Out->RegA = UNKNOWN_REGVAL;
            break;
 
        case OP65_PLP:
            break;
 
        case OP65_PLX:
-           Out->RegX = -1;
+           Out->RegX = UNKNOWN_REGVAL;
            break;
 
        case OP65_PLY:
-           Out->RegY = -1;
+           Out->RegY = UNKNOWN_REGVAL;
            break;
 
        case OP65_ROL:
@@ -890,9 +969,15 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
            if (E->AM == AM65_ACC) {
                Out->RegA = UNKNOWN_REGVAL;
            } else if (E->AM == AM65_ZP) {
-               switch (GetKnownReg (E->Chg, In)) {
+               switch (GetKnownReg (E->Chg & REG_ZP, In)) {
                    case REG_TMP1:
-                       Out->Tmp1 = UNKNOWN_REGVAL;
+                       Out->Tmp1 = UNKNOWN_REGVAL;
+                       break;
+                   case REG_PTR1_LO:
+                       Out->Ptr1Lo = UNKNOWN_REGVAL;
+                       break;
+                   case REG_PTR1_HI:
+                       Out->Ptr1Hi = UNKNOWN_REGVAL;
                        break;
                    case REG_SREG_LO:
                        Out->SRegLo = UNKNOWN_REGVAL;
@@ -912,10 +997,16 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
            if (E->AM == AM65_ACC) {
                Out->RegA = UNKNOWN_REGVAL;
            } else if (E->AM == AM65_ZP) {
-               switch (GetKnownReg (E->Chg, In)) {
+               switch (GetKnownReg (E->Chg & REG_ZP, In)) {
                    case REG_TMP1:
                        Out->Tmp1 = UNKNOWN_REGVAL;
                        break;
+                   case REG_PTR1_LO:
+                       Out->Ptr1Lo = UNKNOWN_REGVAL;
+                       break;
+                   case REG_PTR1_HI:
+                       Out->Ptr1Hi = UNKNOWN_REGVAL;
+                       break;
                    case REG_SREG_LO:
                        Out->SRegLo = UNKNOWN_REGVAL;
                        break;
@@ -937,7 +1028,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
 
        case OP65_SBC:
            /* We don't know the value of the carry bit */
-           Out->RegA = -1;
+           Out->RegA = UNKNOWN_REGVAL;
            break;
 
        case OP65_SEC:
@@ -951,16 +1042,22 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
 
        case OP65_STA:
            if (E->AM == AM65_ZP) {
-               switch (GetKnownReg (E->Chg, 0)) {
+               switch (GetKnownReg (E->Chg & REG_ZP, 0)) {
                    case REG_TMP1:
                        Out->Tmp1 = In->RegA;
                        break;
+                   case REG_PTR1_LO:
+                       Out->Ptr1Lo = In->RegA;
+                       break;
+                   case REG_PTR1_HI:
+                       Out->Ptr1Hi = In->RegA;
+                       break;
                    case REG_SREG_LO:
                        Out->SRegLo = In->RegA;
                        break;
                    case REG_SREG_HI:
                        Out->SRegHi = In->RegA;
-                       break;
+                       break;
                }
            } else if (E->AM == AM65_ZPX) {
                 /* Invalidates all ZP registers */
@@ -970,10 +1067,16 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
 
        case OP65_STX:
            if (E->AM == AM65_ZP) {
-               switch (GetKnownReg (E->Chg, 0)) {
+               switch (GetKnownReg (E->Chg & REG_ZP, 0)) {
                    case REG_TMP1:
                        Out->Tmp1 = In->RegX;
                        break;
+                   case REG_PTR1_LO:
+                       Out->Ptr1Lo = In->RegX;
+                       break;
+                   case REG_PTR1_HI:
+                       Out->Ptr1Hi = In->RegX;
+                       break;
                    case REG_SREG_LO:
                        Out->SRegLo = In->RegX;
                        break;
@@ -989,10 +1092,16 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
 
        case OP65_STY:
            if (E->AM == AM65_ZP) {
-               switch (GetKnownReg (E->Chg, 0)) {
+               switch (GetKnownReg (E->Chg & REG_ZP, 0)) {
                    case REG_TMP1:
                        Out->Tmp1 = In->RegY;
                        break;
+                   case REG_PTR1_LO:
+                       Out->Ptr1Lo = In->RegY;
+                       break;
+                   case REG_PTR1_HI:
+                       Out->Ptr1Hi = In->RegY;
+                       break;
                    case REG_SREG_LO:
                        Out->SRegLo = In->RegY;
                        break;
@@ -1008,9 +1117,15 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
 
        case OP65_STZ:
            if (E->AM == AM65_ZP) {
-               switch (GetKnownReg (E->Chg, 0)) {
+               switch (GetKnownReg (E->Chg & REG_ZP, 0)) {
                    case REG_TMP1:
-                       Out->Tmp1 = 0;
+                       Out->Tmp1 = 0;
+                       break;
+                   case REG_PTR1_LO:
+                       Out->Ptr1Lo = 0;
+                       break;
+                   case REG_PTR1_HI:
+                       Out->Ptr1Hi = 0;
                        break;
                    case REG_SREG_LO:
                        Out->SRegLo = 0;
@@ -1039,10 +1154,16 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
                RC_InvalidateZP (Out);
            } else if (E->AM == AM65_ZP) {
                if (In->RegA >= 0) {
-                   switch (GetKnownReg (E->Chg, In)) {
+                   switch (GetKnownReg (E->Chg & REG_ZP, In)) {
                        case REG_TMP1:
                            Out->Tmp1 &= ~In->RegA;
                            break;
+                       case REG_PTR1_LO:
+                           Out->Ptr1Lo &= ~In->RegA;
+                           break;
+                       case REG_PTR1_HI:
+                           Out->Ptr1Hi &= ~In->RegA;
+                           break;
                        case REG_SREG_LO:
                            Out->SRegLo &= ~In->RegA;
                            break;
@@ -1051,14 +1172,20 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
                            break;
                    }
                } else {
-                   switch (GetKnownReg (E->Chg, In)) {
+                   switch (GetKnownReg (E->Chg & REG_ZP, In)) {
                        case REG_TMP1:
                            Out->Tmp1 = UNKNOWN_REGVAL;
                            break;
+                       case REG_PTR1_LO:
+                           Out->Ptr1Lo = UNKNOWN_REGVAL;
+                           break;
+                       case REG_PTR1_HI:
+                           Out->Ptr1Hi = UNKNOWN_REGVAL;
+                           break;
                        case REG_SREG_LO:
                            Out->SRegLo = UNKNOWN_REGVAL;
                            break;
-                       case REG_SREG_HI:
+                       case REG_SREG_HI:
                            Out->SRegHi = UNKNOWN_REGVAL;
                            break;
                    }
@@ -1072,10 +1199,16 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
                RC_InvalidateZP (Out);
            } else if (E->AM == AM65_ZP) {
                if (In->RegA >= 0) {
-                   switch (GetKnownReg (E->Chg, In)) {
+                   switch (GetKnownReg (E->Chg & REG_ZP, In)) {
                        case REG_TMP1:
                            Out->Tmp1 |= In->RegA;
                            break;
+                       case REG_PTR1_LO:
+                           Out->Ptr1Lo |= In->RegA;
+                           break;
+                       case REG_PTR1_HI:
+                           Out->Ptr1Hi |= In->RegA;
+                           break;
                        case REG_SREG_LO:
                            Out->SRegLo |= In->RegA;
                            break;
@@ -1084,12 +1217,18 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
                            break;
                    }
                } else {
-                   switch (GetKnownReg (E->Chg, In)) {
+                   switch (GetKnownReg (E->Chg & REG_ZP, In)) {
                        case REG_TMP1:
                            Out->Tmp1 = UNKNOWN_REGVAL;
                            break;
+                       case REG_PTR1_LO:
+                           Out->Ptr1Lo = UNKNOWN_REGVAL;
+                           break;
+                       case REG_PTR1_HI:
+                           Out->Ptr1Hi = UNKNOWN_REGVAL;
+                           break;
                        case REG_SREG_LO:
-                           Out->SRegLo = UNKNOWN_REGVAL;
+                           Out->SRegLo = UNKNOWN_REGVAL;
                            break;
                        case REG_SREG_HI:
                            Out->SRegHi = UNKNOWN_REGVAL;
index ed4fae03b3b5cd6344dd545f9cc97854e99fdb75..322b471ff0e8109a9bfb0d906d870ff67a7cb614 100644 (file)
@@ -616,6 +616,10 @@ unsigned GetKnownReg (unsigned Use, const RegContents* RC)
        return (RC == 0 || RC->RegY >= 0)? REG_Y : REG_NONE;
     } else if ((Use & REG_TMP1) != 0) {
        return (RC == 0 || RC->Tmp1 >= 0)? REG_TMP1 : REG_NONE;
+    } else if ((Use & REG_PTR1_LO) != 0) {
+       return (RC == 0 || RC->Ptr1Lo >= 0)? REG_PTR1_LO : REG_NONE;
+    } else if ((Use & REG_PTR1_HI) != 0) {
+       return (RC == 0 || RC->Ptr1Hi >= 0)? REG_PTR1_HI : REG_NONE;
     } else if ((Use & REG_SREG_LO) != 0) {
        return (RC == 0 || RC->SRegLo >= 0)? REG_SREG_LO : REG_NONE;
     } else if ((Use & REG_SREG_HI) != 0) {
@@ -625,7 +629,7 @@ unsigned GetKnownReg (unsigned Use, const RegContents* RC)
     }
 }
 
-
+                              
 
 static cmp_t FindCmpCond (const char* Code, unsigned CodeLen)
 /* Search for a compare condition by the given code using the given length */
index cfa114f9774de37caf03c5a3facbb7533eecddb7..a7b46ca1b8258f9d2b11bc8f62fa8036cd96a5cf 100644 (file)
@@ -1308,42 +1308,66 @@ static unsigned OptDecouple (CodeSeg* S)
        /* Check the instruction */
        switch (E->OPC) {
 
+           case OP65_DEA:
+               if (RegValIsKnown (In->RegA)) {
+                   Arg = MakeHexArg ((In->RegA - 1) & 0xFF);
+                   X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, E->LI);
+               }
+               break;
+
            case OP65_DEX:
-               if (E->RI->In.RegX >= 0) {
-                   Arg = MakeHexArg ((E->RI->In.RegX - 1) & 0xFF);
+               if (RegValIsKnown (In->RegX)) {
+                   Arg = MakeHexArg ((In->RegX - 1) & 0xFF);
                    X = NewCodeEntry (OP65_LDX, AM65_IMM, Arg, 0, E->LI);
                }
                break;
 
            case OP65_DEY:
-               if (E->RI->In.RegY >= 0) {
-                   Arg = MakeHexArg ((E->RI->In.RegY - 1) & 0xFF);
+               if (RegValIsKnown (In->RegY)) {
+                   Arg = MakeHexArg ((In->RegY - 1) & 0xFF);
                    X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI);
                }
                break;
 
+           case OP65_INA:
+               if (RegValIsKnown (In->RegA)) {
+                   Arg = MakeHexArg ((In->RegA + 1) & 0xFF);
+                   X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, E->LI);
+               }
+               break;
+
            case OP65_INX:
-               if (E->RI->In.RegX >= 0) {
-                   Arg = MakeHexArg ((E->RI->In.RegX + 1) & 0xFF);
+               if (RegValIsKnown (In->RegX)) {
+                   Arg = MakeHexArg ((In->RegX + 1) & 0xFF);
                    X = NewCodeEntry (OP65_LDX, AM65_IMM, Arg, 0, E->LI);
                }
                break;
 
            case OP65_INY:
-               if (E->RI->In.RegY >= 0) {
-                   Arg = MakeHexArg ((E->RI->In.RegY + 1) & 0xFF);
+               if (RegValIsKnown (In->RegY)) {
+                   Arg = MakeHexArg ((In->RegY + 1) & 0xFF);
                    X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI);
                }
                break;
 
            case OP65_LDA:
                if (E->AM == AM65_ZP) {
-                   switch (GetKnownReg (E->Use, In)) {
+                   switch (GetKnownReg (E->Use & REG_ZP, In)) {
                        case REG_TMP1:
                            Arg = MakeHexArg (In->Tmp1);
                            X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, E->LI);
                            break;
 
+                       case REG_PTR1_LO:
+                           Arg = MakeHexArg (In->Ptr1Lo);
+                           X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, E->LI);
+                           break;
+
+                       case REG_PTR1_HI:
+                           Arg = MakeHexArg (In->Ptr1Hi);
+                           X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, E->LI);
+                           break;
+
                        case REG_SREG_LO:
                            Arg = MakeHexArg (In->SRegLo);
                            X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, E->LI);
@@ -1359,12 +1383,22 @@ static unsigned OptDecouple (CodeSeg* S)
 
            case OP65_LDX:
                if (E->AM == AM65_ZP) {
-                   switch (GetKnownReg (E->Use, In)) {
+                   switch (GetKnownReg (E->Use & REG_ZP, In)) {
                        case REG_TMP1:
                            Arg = MakeHexArg (In->Tmp1);
                            X = NewCodeEntry (OP65_LDX, AM65_IMM, Arg, 0, E->LI);
                            break;
 
+                       case REG_PTR1_LO:
+                           Arg = MakeHexArg (In->Ptr1Lo);
+                           X = NewCodeEntry (OP65_LDX, AM65_IMM, Arg, 0, E->LI);
+                           break;
+
+                       case REG_PTR1_HI:
+                           Arg = MakeHexArg (In->Ptr1Hi);
+                           X = NewCodeEntry (OP65_LDX, AM65_IMM, Arg, 0, E->LI);
+                           break;
+
                        case REG_SREG_LO:
                            Arg = MakeHexArg (In->SRegLo);
                            X = NewCodeEntry (OP65_LDX, AM65_IMM, Arg, 0, E->LI);
@@ -1386,6 +1420,16 @@ static unsigned OptDecouple (CodeSeg* S)
                            X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI);
                            break;
 
+                       case REG_PTR1_LO:
+                           Arg = MakeHexArg (In->Ptr1Lo);
+                           X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI);
+                           break;
+
+                       case REG_PTR1_HI:
+                           Arg = MakeHexArg (In->Ptr1Hi);
+                           X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI);
+                           break;
+
                        case REG_SREG_LO:
                            Arg = MakeHexArg (In->SRegLo);
                            X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI);
@@ -1784,7 +1828,7 @@ static void WriteOptStats (const char* Name)
     /* Write a header */
     fprintf (F,
             "; Optimizer               Total      Last       Total      Last\n"
-                    ";   Step                  Runs       Runs        Chg       Chg\n");        
+                    ";   Step                  Runs       Runs        Chg       Chg\n");
 
 
     /* Write the data */
@@ -1850,7 +1894,6 @@ static unsigned RunOptGroup1 (CodeSeg* S)
 
     Changes += RunOptFunc (S, &DOptPtrStore1, 1);
     Changes += RunOptFunc (S, &DOptPtrStore2, 1);
-    Changes += RunOptFunc (S, &DOptPrecalc, 1);
     Changes += RunOptFunc (S, &DOptPtrLoad1, 1);
     Changes += RunOptFunc (S, &DOptPtrLoad2, 1);
     Changes += RunOptFunc (S, &DOptPtrLoad3, 1);
@@ -1938,6 +1981,7 @@ static unsigned RunOptGroup3 (CodeSeg* S)
                C += RunOptFunc (S, &DOptStoreLoad, 1);
                C += RunOptFunc (S, &DOptTransfers1, 1);
         C += RunOptFunc (S, &DOptPushPop, 1);
+        C += RunOptFunc (S, &DOptPrecalc, 1);
 
        Changes += C;
 
index 3bfb879df96153fd9e7ec8b7ea7e75c903593a7f..f1478b9a9083196ef71c7e4b41014cb66dbc3b1c 100644 (file)
@@ -96,6 +96,10 @@ static short ZPRegVal (unsigned short Use, const RegContents* RC)
 {
     if ((Use & REG_TMP1) != 0) {
        return RC->Tmp1;
+    } else if ((Use & REG_PTR1_LO) != 0) {
+       return RC->Ptr1Lo;
+    } else if ((Use & REG_PTR1_HI) != 0) {
+       return RC->Ptr1Hi;
     } else if ((Use & REG_SREG_LO) != 0) {
        return RC->SRegLo;
     } else if ((Use & REG_SREG_HI) != 0) {
@@ -1102,7 +1106,7 @@ unsigned OptTransfers1 (CodeSeg* S)
                }
                 if (CE_UseLoadFlags (X)) {
                    if (I == 0) {
-                       /* No preceeding entry */
+                       /* No preceeding entry */
                        goto NextEntry;
                    }
                    P = CS_GetEntry (S, I-1);
@@ -1308,66 +1312,28 @@ unsigned OptPrecalc (CodeSeg* S)
        /* Get next entry */
                CodeEntry* E = CS_GetEntry (S, I);
 
-               /* Get a pointer to the input registers of the insn */
-       const RegContents* In  = &E->RI->In;
-
-        /* Maybe we can handle it better if the contents of A are known */
-        if (RegValIsKnown (In->RegA)) {
-
-            const char* Arg = 0;
-
-            /* Handle the different instructions */
-            switch (E->OPC) {
-
-                case OP65_AND:
-                    if (CE_KnownImm (E)) {
-                        /* Accu AND immediate */
-                        Arg = MakeHexArg (In->RegA & E->Num);
-                    } else if (E->AM == AM65_ZP) {
-                        int R = ZPRegVal (E->Use, In);
-                        if (RegValIsKnown (R)) {
-                            /* Accu AND zp with known contents */
-                            Arg = MakeHexArg (In->RegA & R);
-                        }
-                    }
-                    break;
-
-                case OP65_EOR:
-                    if (CE_KnownImm (E)) {
-                        Arg = MakeHexArg (In->RegA ^ E->Num);
-                    } else if (E->AM == AM65_ZP) {
-                        int R = ZPRegVal (E->Use, In);
-                        if (RegValIsKnown (R)) {
-                            /* Accu EOR zp with known contents */
-                            Arg = MakeHexArg (In->RegA ^ R);
-                        }
-                    }
-                    break;
-
-                case OP65_ORA:
-                    if (CE_KnownImm (E)) {
-                        Arg = MakeHexArg (In->RegA | E->Num);
-                    } else if (E->AM == AM65_ZP) {
-                        int R = ZPRegVal (E->Use, In);
-                        if (RegValIsKnown (R)) {
-                            /* Accu ORA zp with known contents */
-                            Arg = MakeHexArg (In->RegA | R);
-                        }
-                    }
-                    break;
-
-                default:
-                    break;
+               /* Get a pointer to the output registers of the insn */
+               const RegContents* Out = &E->RI->Out;
+
+        /* Handle the different instructions */
+        switch (E->OPC) {
+
+            case OP65_AND:
+            case OP65_EOR:
+            case OP65_ORA:
+                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);
+                    CS_DelEntry (S, I);
+                    ++Changes;
+                }
+                break;
 
-            }
+            default:
+                break;
 
-            /* If we have a new entry, replace the old one */
-            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 */
index 8de716ddfb77f0083d96239a253d40032b1ae33a..a90da923152a5d98da7da79f51a0baf4a7c2ac27 100644 (file)
@@ -6,9 +6,9 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2001-2002 Ullrich von Bassewitz                                       */
-/*               Wacholderweg 14                                             */
-/*               D-70597 Stuttgart                                           */
+/* (C) 2001-2003 Ullrich von Bassewitz                                       */
+/*               Römerstrasse 52                                             */
+/*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
 /*                                                                           */
@@ -55,6 +55,8 @@ void RC_Invalidate (RegContents* C)
     C->RegY   = UNKNOWN_REGVAL;
     C->SRegLo = UNKNOWN_REGVAL;
     C->SRegHi = UNKNOWN_REGVAL;
+    C->Ptr1Lo = UNKNOWN_REGVAL;
+    C->Ptr1Hi = UNKNOWN_REGVAL;
     C->Tmp1   = UNKNOWN_REGVAL;
 }
 
@@ -65,11 +67,41 @@ void RC_InvalidateZP (RegContents* C)
 {
     C->SRegLo = UNKNOWN_REGVAL;
     C->SRegHi = UNKNOWN_REGVAL;
+    C->Ptr1Lo = UNKNOWN_REGVAL;
+    C->Ptr1Hi = UNKNOWN_REGVAL;
     C->Tmp1   = UNKNOWN_REGVAL;
 }
 
 
 
+static void RC_Dump1 (FILE* F, const char* Desc, short Val)
+/* Dump one register value */
+{
+    if (RegValIsKnown (Val)) {
+        fprintf (F, "%s=$%02X ", Desc, Val);
+    } else {
+        fprintf (F, "%s=$XX ", Desc);
+    }
+}
+
+
+
+void RC_Dump (FILE* F, const RegContents* RC)
+/* Dump the contents of the given RegContents struct */
+{
+    RC_Dump1 (F, "A", RC->RegA);
+    RC_Dump1 (F, "X", RC->RegX);
+    RC_Dump1 (F, "Y", RC->RegY);
+    RC_Dump1 (F, "SREG", RC->SRegLo);
+    RC_Dump1 (F, "SREG+1", RC->SRegHi);
+    RC_Dump1 (F, "PTR1", RC->Ptr1Lo);
+    RC_Dump1 (F, "PTR1+1", RC->Ptr1Hi);
+    RC_Dump1 (F, "TMP1", RC->Tmp1);
+    fprintf (F, "\n");
+}
+
+
+
 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
@@ -104,4 +136,3 @@ void FreeRegInfo (RegInfo* RI)
 
 
 
-
index ad49043d357683a56bfb48fbb34be126c6c62e44..fd2034fce814cff46aa2997924586c2eec33a3cf 100644 (file)
@@ -1,15 +1,15 @@
 /*****************************************************************************/
 /*                                                                           */
-/*                                reginfo.h                                 */
+/*                                reginfo.h                                 */
 /*                                                                           */
-/*                       6502 register tracking info                        */
+/*                       6502 register tracking info                        */
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2001-2002  Ullrich von Bassewitz                                      */
-/*                Wacholderweg 14                                            */
-/*                D-70597 Stuttgart                                          */
-/* EMail:         uz@cc65.org                                                */
+/* (C) 2001-2003 Ullrich von Bassewitz                                       */
+/*               Römerstrasse 52                                             */
+/*               D-70794 Filderstadt                                         */
+/* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -38,6 +38,8 @@
 
 
 
+#include <stdio.h>      /* ### */
+
 /* common */
 #include "inline.h"
 
@@ -60,6 +62,8 @@ struct RegContents {
     short       RegY;
     short       SRegLo;
     short       SRegHi;
+    short       Ptr1Lo;
+    short       Ptr1Hi;
     short      Tmp1;
 };
 
@@ -85,6 +89,9 @@ void RC_Invalidate (RegContents* C);
 void RC_InvalidateZP (RegContents* C);
 /* Invalidate all ZP registers */
 
+void RC_Dump (FILE* F, const RegContents* RC);
+/* Dump the contents of the given RegContents struct */
+
 #if defined(HAVE_INLINE)
 INLINE int RegValIsKnown (short Val)
 /* Return true if the register value is known */
@@ -116,8 +123,6 @@ void FreeRegInfo (RegInfo* RI);
 
 
 
-
-
 /* End of reginfo.h */
 #endif