diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index f4fe3f435..c8f8eb3b0 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -1352,6 +1352,7 @@ struct OptFunc { #define OptFuncEntry(func) static OptFuncDesc D##func = { func, #func, 0 } /* A list of all the function descriptions */ +static OptFunc DOpt65C02BitOps = { Opt65C02BitOps, "Opt65C02BitOps", 66, 0, 0, 0, 0, 0 }; static OptFunc DOpt65C02Ind = { Opt65C02Ind, "Opt65C02Ind", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptAdd1 = { OptAdd1, "OptAdd1", 60, 0, 0, 0, 0, 0 }; static OptFunc DOptAdd2 = { OptAdd2, "OptAdd2", 200, 0, 0, 0, 0, 0 }; @@ -1406,6 +1407,7 @@ static OptFunc DOptUnusedStores = { OptUnusedStores, "OptUnusedStores", 0, 0, /* Table containing all the steps in alphabetical order */ static OptFunc* OptFuncs[] = { + &DOpt65C02BitOps, &DOpt65C02Ind, &DOptAdd1, &DOptAdd2, @@ -1775,14 +1777,16 @@ static unsigned RunOptGroup3 (CodeSeg* S) static unsigned RunOptGroup4 (CodeSeg* S) /* 65C02 specific optimizations. */ -{ +{ + unsigned C; unsigned Changes = 0; if (CPU >= CPU_65C02) { + Changes += RunOptFunc (S, &DOpt65C02BitOps, 1); /* Replace (zp),y by (zp) if Y is zero. If we have changes, run register * load optimization again, since loads of Y may have become unnecessary. */ - unsigned C = RunOptFunc (S, &DOpt65C02Ind, 1); + C = RunOptFunc (S, &DOpt65C02Ind, 1); Changes += C; if (C) { Changes += RunOptFunc (S, &DOptUnusedLoads, 1); diff --git a/src/cc65/coptc02.c b/src/cc65/coptc02.c index 61ab10d4f..b7f765c63 100644 --- a/src/cc65/coptc02.c +++ b/src/cc65/coptc02.c @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 2001 Ullrich von Bassewitz */ +/* (C) 2001-2002 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@cc65.org */ @@ -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,81 @@ 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_KnownImm (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); + + /* TRB */ + X = NewCodeEntry (OP65_TRB, L[0]->AM, L[0]->Arg, 0, L[0]->LI); + CS_InsertEntry (S, X, I+1); + + } 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); + + /* TRB */ + X = NewCodeEntry (OP65_TSB, L[0]->AM, L[0]->Arg, 0, L[0]->LI); + CS_InsertEntry (S, X, I+1); + } + + /* Delete the old stuff */ + CS_DelEntries (S, I+2, 3); + + /* We had changes */ + ++Changes; + } + + /* Next entry */ + ++I; + + } + + /* Free register info */ + CS_FreeRegInfo (S); + + /* Return the number of changes made */ + return Changes; +} + + diff --git a/src/cc65/coptc02.h b/src/cc65/coptc02.h index 4ad470406..743efb971 100644 --- a/src/cc65/coptc02.h +++ b/src/cc65/coptc02.h @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 2001 Ullrich von Bassewitz */ +/* (C) 2001-2002 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@cc65.org */ @@ -52,6 +52,9 @@ unsigned Opt65C02Ind (CodeSeg* S); /* Try to use the indirect addressing mode where possible */ +unsigned Opt65C02BitOps (CodeSeg* S); +/* Use special bit op instructions of the C02 */ + /* End of coptc02.h */