]> git.sur5r.net Git - cc65/commitdiff
More register tracking
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Tue, 24 Jul 2001 20:13:10 +0000 (20:13 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Tue, 24 Jul 2001 20:13:10 +0000 (20:13 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@815 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/cc65/codeent.c
src/cc65/codeinfo.c
src/cc65/codeseg.c
src/cc65/codeseg.h
src/cc65/reginfo.c
src/cc65/reginfo.h

index e6f9fe542949073ea7fc99f0b6ad69636d5f1398..1594c80330e2df96779bc212b7436d509a3d78d8 100644 (file)
@@ -317,7 +317,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
        } else {
            RC_Invalidate (&E->RI->In);
        }
-       E->RI->Out = E->RI->In;
+               E->RI->Out2 = E->RI->Out = E->RI->In;
     }
 
     /* Get pointers to the register contents */
index 7702a37ec0851655329e50f85134e53151b6a24c..d3dee341d464c9eebef051ae6b6d6db87ff8dd75 100644 (file)
@@ -130,8 +130,17 @@ static const FuncInfo FuncInfoTable[] = {
     { "shreax3",        REG_AX,         REG_AX          },
     { "staspidx",       REG_A | REG_Y,  REG_Y           },
     { "tosicmp",       REG_AX,         REG_AXY         },
+    { "tosdiva0",       REG_AX,                REG_AXY         },
+    { "tosdivax",       REG_AX,                REG_AXY         },
+    { "tosdiveax",      REG_AX,                REG_AXY         },
+    { "tosmula0",       REG_AX,                REG_AXY         },
+    { "tosmulax",       REG_AX,                REG_AXY         },
+    { "tosmuleax",      REG_AX,                REG_AXY         },
     { "tosshreax",      REG_AX,                REG_AXY         },
-};
+    { "tosumula0",      REG_AX,                REG_AXY         },
+    { "tosumulax",      REG_AX,                REG_AXY         },
+    { "tosumuleax",     REG_AX,                REG_AXY         },
+};          
 #define FuncInfoCount  (sizeof(FuncInfoTable) / sizeof(FuncInfoTable[0]))
 
 /* Table with names of zero page locations used by the compiler */
index 84c32797ccabecb0909cf0bf1eb336429ac48f64..325eee20f67558d14d682df3d9a156fce59d73ab 100644 (file)
@@ -586,6 +586,22 @@ void CS_MoveEntries (CodeSeg* S, unsigned Start, unsigned Count, unsigned NewPos
 
 
 
+struct CodeEntry* CS_GetPrevEntry (CodeSeg* S, unsigned Index)
+/* Get the code entry preceeding the one with the index Index. If there is no
+ * preceeding code entry, return NULL.
+ */
+{
+    if (Index == 0) {
+       /* This is the first entry */
+       return 0;
+    } else {
+       /* Previous entry available */
+               return CollAtUnchecked (&S->Entries, Index-1);
+    }
+}
+
+
+
 struct CodeEntry* CS_GetNextEntry (CodeSeg* S, unsigned Index)
 /* Get the code entry following the one with the index Index. If there is no
  * following code entry, return NULL.
@@ -1032,6 +1048,8 @@ void CS_GenRegInfo (CodeSeg* S)
     WasJump = 0;
     for (I = 0; I < CS_GetEntryCount (S); ++I) {
 
+       CodeEntry* P;
+
        /* Get the next instruction */
        CodeEntry* E = CollAtUnchecked (&S->Entries, I);
 
@@ -1053,7 +1071,7 @@ void CS_GenRegInfo (CodeSeg* S)
                /* Preceeding insn was an unconditional branch */
                CodeEntry* J = CL_GetRef(Label, 0);
                if (J->RI) {
-                   Regs = J->RI->Out;
+                   Regs = J->RI->Out2;
                } else {
                    RC_Invalidate (&Regs);
                }
@@ -1071,13 +1089,13 @@ void CS_GenRegInfo (CodeSeg* S)
                    RC_Invalidate (&Regs);
                    break;
                }
-               if (J->RI->Out.RegA != Regs.RegA) {
+               if (J->RI->Out2.RegA != Regs.RegA) {
                    Regs.RegA = -1;
                }
-               if (J->RI->Out.RegX != Regs.RegX) {
+               if (J->RI->Out2.RegX != Regs.RegX) {
                    Regs.RegX = -1;
                }
-               if (J->RI->Out.RegY != Regs.RegY) {
+               if (J->RI->Out2.RegY != Regs.RegY) {
                    Regs.RegY = -1;
                }
                ++Entry;
@@ -1091,11 +1109,135 @@ void CS_GenRegInfo (CodeSeg* S)
        /* Generate register info for this instruction */
         CE_GenRegInfo (E, CurrentRegs);
 
+       /* Remember for the next insn if this insn was an uncondition branch */
+       WasJump = (E->Info & OF_UBRA) != 0;
+
        /* Output registers for this insn are input for the next */
        CurrentRegs = &E->RI->Out;
 
-       /* Remember for the next insn if this insn was an uncondition branch */
-       WasJump = (E->Info & OF_UBRA) != 0;
+       /* If this insn is a branch on zero flag, we may have more info on
+        * register contents for one of both flow directions, but only if
+        * there is a previous instruction.
+        */
+       if ((E->Info & OF_ZBRA) != 0 && (P = CS_GetPrevEntry (S, I)) != 0) {
+
+           /* Get the branch condition */
+           bc_t BC = GetBranchCond (E->OPC);
+
+           /* Check the previous instruction */
+           switch (P->OPC) {
+
+               case OP65_ADC:
+               case OP65_AND:
+               case OP65_DEA:
+               case OP65_EOR:
+               case OP65_INA:
+               case OP65_LDA:
+               case OP65_ORA:
+               case OP65_PLA:
+               case OP65_SBC:
+                   /* A is zero in one execution flow direction */
+                   if (BC == BC_EQ) {
+                               E->RI->Out2.RegA = 0;
+                   } else {
+                       E->RI->Out.RegA = 0;
+                   }
+                   break;
+
+               case OP65_CMP:
+                   /* If this is an immidiate compare, the A register has
+                    * the value of the compare later.
+                    */
+                   if (CE_KnownImm (P)) {
+                       if (BC == BC_EQ) {
+                           E->RI->Out2.RegA = (unsigned char)P->Num;
+                       } else {
+                           E->RI->Out.RegA = (unsigned char)P->Num;
+                       }
+                   }
+                   break;
+
+               case OP65_CPX:
+                   /* If this is an immidiate compare, the X register has
+                    * the value of the compare later.
+                    */
+                   if (CE_KnownImm (P)) {
+                       if (BC == BC_EQ) {
+                           E->RI->Out2.RegX = (unsigned char)P->Num;
+                       } else {
+                           E->RI->Out.RegX = (unsigned char)P->Num;
+                       }
+                   }
+                   break;
+
+               case OP65_CPY:
+                   /* If this is an immidiate compare, the Y register has
+                    * the value of the compare later.
+                    */
+                   if (CE_KnownImm (P)) {
+                       if (BC == BC_EQ) {
+                           E->RI->Out2.RegY = (unsigned char)P->Num;
+                       } else {
+                           E->RI->Out.RegY = (unsigned char)P->Num;
+                       }
+                   }
+                   break;
+
+               case OP65_DEX:
+               case OP65_INX:
+               case OP65_LDX:
+               case OP65_PLX:
+                   /* X is zero in one execution flow direction */
+                   if (BC == BC_EQ) {
+                               E->RI->Out2.RegX = 0;
+                   } else {
+                       E->RI->Out.RegX = 0;
+                   }
+                   break;
+
+               case OP65_DEY:
+               case OP65_INY:
+               case OP65_LDY:
+               case OP65_PLY:
+                   /* X is zero in one execution flow direction */
+                   if (BC == BC_EQ) {
+                               E->RI->Out2.RegY = 0;
+                   } else {
+                       E->RI->Out.RegY = 0;
+                   }
+                   break;
+
+               case OP65_TAX:
+               case OP65_TXA:
+                   /* If the branch is a beq, both A and X are zero at the
+                    * branch target, otherwise they are zero at the next
+                    * insn.
+                    */
+                   if (BC == BC_EQ) {
+                       E->RI->Out2.RegA = E->RI->Out2.RegX = 0;
+                   } else {
+                       E->RI->Out.RegA = E->RI->Out.RegX = 0;
+                   }
+                   break;
+
+               case OP65_TAY:
+               case OP65_TYA:
+                   /* If the branch is a beq, both A and Y are zero at the
+                    * branch target, otherwise they are zero at the next
+                    * insn.
+                    */
+                   if (BC == BC_EQ) {
+                       E->RI->Out2.RegA = E->RI->Out2.RegY = 0;
+                   } else {
+                       E->RI->Out.RegA = E->RI->Out.RegY = 0;
+                   }
+                   break;
+
+               default:
+                   break;
+
+           }
+       }
     }
 }
 
index 99342f4234d11c1837d3c2deb6993c21647be69f..f09c0d1179ac7e9f4e7fa4353cc614eaba670860 100644 (file)
@@ -149,6 +149,11 @@ INLINE struct CodeEntry* CS_GetEntry (CodeSeg* S, unsigned Index)
 #  define CS_GetEntry(S, Index)        CollAt(&(S)->Entries, (Index))
 #endif
 
+struct CodeEntry* CS_GetPrevEntry (CodeSeg* S, unsigned Index);
+/* Get the code entry preceeding the one with the index Index. If there is no
+ * preceeding code entry, return NULL.
+ */
+
 struct CodeEntry* CS_GetNextEntry (CodeSeg* S, unsigned Index);
 /* Get the code entry following the one with the index Index. If there is no
  * following code entry, return NULL.
index f62dd3791e144df0f6333e91483d298e81b53b86..c8a6d094b4bfec40008f7372c649cf2f7dcd4078 100644 (file)
@@ -70,11 +70,13 @@ RegInfo* NewRegInfo (const RegContents* RC)
 
     /* Initialize the registers */
     if (RC) {
-       RI->In  = *RC;
-       RI->Out = *RC;
+       RI->In   = *RC;
+       RI->Out  = *RC;
+       RI->Out2 = *RC;
     } else {
        RC_Invalidate (&RI->In);
        RC_Invalidate (&RI->Out);
+       RC_Invalidate (&RI->Out2);
     }
 
     /* Return the new struct */
index 21415a819f19e72cc21109400535b90a7c5a89c5..bcf760b1691209ee099f555477a5acd4365b9c02 100644 (file)
@@ -62,8 +62,9 @@ struct RegContents {
 /* Register change info */
 typedef struct RegInfo RegInfo;
 struct RegInfo {
-    RegContents        In;                     /* Incoming register values */
-    RegContents Out;                    /* Outgoing register values */
+    RegContents        In;             /* Incoming register values */
+    RegContents Out;            /* Outgoing register values */
+    RegContents Out2;          /* Alternative outgoing reg values for branches */
 };