X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fcc65%2Fcoptc02.c;h=bffb5acc8da8a3578e5c93fb35a4d4943b042af4;hb=112ae0e3db511ddd92e769c11328646ebe2a6240;hp=61ab10d4f7851628678ebb0b7e0e9765b9f3054e;hpb=2435aa63b5dcab10267aca7cf0d6f236d2d5b37c;p=cc65 diff --git a/src/cc65/coptc02.c b/src/cc65/coptc02.c index 61ab10d4f..bffb5acc8 100644 --- a/src/cc65/coptc02.c +++ b/src/cc65/coptc02.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 2001 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@cc65.org */ +/* (C) 2001-2005, Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -77,7 +77,7 @@ unsigned Opt65C02Ind (CodeSeg* S) /* Get next entry */ CodeEntry* E = CS_GetEntry (S, I); - /* Check for addressing mode indirect indexed Y where Y is zero. + /* Check for addressing mode indirect indexed Y where Y is zero. * Note: All opcodes that are available as (zp),y are also available * as (zp), so we can ignore the actual opcode here. */ @@ -107,4 +107,131 @@ unsigned Opt65C02Ind (CodeSeg* S) +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; +} + +