diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index a3b49ef48..31bcfb390 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -1515,6 +1515,7 @@ static OptFunc DOptNegAX1 = { OptNegAX1, "OptNegAX1", 100, 0, static OptFunc DOptNegAX2 = { OptNegAX2, "OptNegAX2", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptNegAX3 = { OptNegAX3, "OptNegAX3", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptNegAX4 = { OptNegAX4, "OptNegAX4", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptPrecalc = { OptPrecalc, "OptPrecalc", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptPtrLoad1 = { OptPtrLoad1, "OptPtrLoad1", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptPtrLoad2 = { OptPtrLoad2, "OptPtrLoad2", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptPtrLoad3 = { OptPtrLoad3, "OptPtrLoad3", 100, 0, 0, 0, 0, 0 }; @@ -1579,6 +1580,7 @@ static OptFunc* OptFuncs[] = { &DOptNegAX2, &DOptNegAX3, &DOptNegAX4, + &DOptPrecalc, &DOptPtrLoad1, &DOptPtrLoad2, &DOptPtrLoad3, @@ -1846,6 +1848,7 @@ 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); diff --git a/src/cc65/coptind.c b/src/cc65/coptind.c index b14b27ed9..4b366f3c4 100644 --- a/src/cc65/coptind.c +++ b/src/cc65/coptind.c @@ -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 */ /* */ /* */ @@ -1206,6 +1206,75 @@ unsigned OptPushPop (CodeSeg* S) +unsigned OptPrecalc (CodeSeg* S) +/* Replace immediate operations with the accu where the current contents are + * known by a load of the final value. + */ +{ + 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); + + /* Get a pointer to the input registers of the insn */ + const RegContents* In = &E->RI->In; + + /* Check for a known register value and known operand */ + if (RegValIsKnown (In->RegA) && CE_KnownImm (E)) { + + const char* Arg; + + /* Handle the different instructions */ + switch (E->OPC) { + + case OP65_AND: + Arg = MakeHexArg (In->RegA & E->Num); + break; + + case OP65_EOR: + Arg = MakeHexArg (In->RegA ^ E->Num); + break; + + case OP65_ORA: + Arg = MakeHexArg (In->RegA | E->Num); + break; + + default: + Arg = 0; + 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 */ + ++I; + } + + /* Free register info */ + CS_FreeRegInfo (S); + + /* Return the number of changes made */ + return Changes; +} + + + /*****************************************************************************/ /* Optimize branch types */ /*****************************************************************************/ diff --git a/src/cc65/coptind.h b/src/cc65/coptind.h index 0eb4cf33c..abad65359 100644 --- a/src/cc65/coptind.h +++ b/src/cc65/coptind.h @@ -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 */ /* */ /* */ @@ -108,6 +108,11 @@ unsigned OptTransfers (CodeSeg* S); unsigned OptPushPop (CodeSeg* S); /* Remove a PHA/PLA sequence were A is not used later */ +unsigned OptPrecalc (CodeSeg* S); +/* Replace immediate operations with the accu where the current contents are + * known by a load of the final value. + */ + unsigned OptBranchDist (CodeSeg* S); /* Change branches for the distance needed. */