+unsigned Opt65C02BitOps (CodeSeg* S)
+/* Use special bit op instructions of the C02 */
+{
+ 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)) {
+
+ CodeEntry* L[3];
+
+ /* Get next entry */
+ L[0] = CS_GetEntry (S, I);
+
+ /* Check for the sequence */
+ if (L[0]->OPC == OP65_LDA &&
+ (L[0]->AM == AM65_ZP || L[0]->AM == AM65_ABS) &&
+ !CS_RangeHasLabel (S, I+1, 2) &&
+ CS_GetEntries (S, L+1, I+1, 2) &&
+ (L[1]->OPC == OP65_AND || L[1]->OPC == OP65_ORA) &&
+ CE_IsConstImm (L[1]) &&
+ L[2]->OPC == OP65_STA &&
+ L[2]->AM == L[0]->AM &&
+ strcmp (L[2]->Arg, L[0]->Arg) == 0 &&
+ !RegAUsed (S, I+3)) {
+
+ char Buf[32];
+ CodeEntry* X;
+
+ /* Use TRB for AND and TSB for ORA */
+ if (L[1]->OPC == OP65_AND) {
+
+ /* 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+3);
+
+ /* TRB */
+ X = NewCodeEntry (OP65_TRB, L[0]->AM, L[0]->Arg, 0, L[0]->LI);
+ 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+3);
+
+ /* TSB */
+ X = NewCodeEntry (OP65_TSB, L[0]->AM, L[0]->Arg, 0, L[0]->LI);
+ CS_InsertEntry (S, X, I+4);
+ }
+
+ /* Delete the old stuff */
+ 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 a store with a register value of zero and an addressing
+ * mode available with STZ.
+ */
+ if (((E->OPC == OP65_STA && E->RI->In.RegA == 0) ||
+ (E->OPC == OP65_STX && E->RI->In.RegX == 0) ||
+ (E->OPC == OP65_STY && E->RI->In.RegY == 0)) &&
+ (E->AM == AM65_ZP || E->AM == AM65_ABS ||
+ E->AM == AM65_ZPX || E->AM == AM65_ABSX)) {
+
+ /* 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;
+ }
+
+ /* Next entry */
+ ++I;
+
+ }
+
+ /* Free register info */
+ CS_FreeRegInfo (S);
+
+ /* Return the number of changes made */
+ return Changes;
+}
+
+