diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index bc3390227..fd909434d 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -1732,13 +1732,14 @@ static OptFunc DOptAdd4 = { OptAdd4, "OptAdd4", 100, 0, static OptFunc DOptAdd5 = { OptAdd5, "OptAdd5", 40, 0, 0, 0, 0, 0 }; static OptFunc DOptBoolTrans = { OptBoolTrans, "OptBoolTrans", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptBranchDist = { OptBranchDist, "OptBranchDist", 0, 0, 0, 0, 0, 0 }; -static OptFunc DOptCmp1 = { OptCmp1, "OptCmp1", 85, 0, 0, 0, 0, 0 }; -static OptFunc DOptCmp2 = { OptCmp2, "OptCmp2", 75, 0, 0, 0, 0, 0 }; +static OptFunc DOptCmp1 = { OptCmp1, "OptCmp1", 42, 0, 0, 0, 0, 0 }; +static OptFunc DOptCmp2 = { OptCmp2, "OptCmp2", 85, 0, 0, 0, 0, 0 }; static OptFunc DOptCmp3 = { OptCmp3, "OptCmp3", 75, 0, 0, 0, 0, 0 }; -static OptFunc DOptCmp4 = { OptCmp4, "OptCmp4", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptCmp4 = { OptCmp4, "OptCmp4", 75, 0, 0, 0, 0, 0 }; static OptFunc DOptCmp5 = { OptCmp5, "OptCmp5", 100, 0, 0, 0, 0, 0 }; -static OptFunc DOptCmp6 = { OptCmp6, "OptCmp6", 85, 0, 0, 0, 0, 0 }; -static OptFunc DOptCmp7 = { OptCmp7, "OptCmp7", 50, 0, 0, 0, 0, 0 }; +static OptFunc DOptCmp6 = { OptCmp6, "OptCmp6", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptCmp7 = { OptCmp7, "OptCmp7", 85, 0, 0, 0, 0, 0 }; +static OptFunc DOptCmp8 = { OptCmp8, "OptCmp8", 50, 0, 0, 0, 0, 0 }; static OptFunc DOptCondBranches = { OptCondBranches, "OptCondBranches", 80, 0, 0, 0, 0, 0 }; static OptFunc DOptDeadCode = { OptDeadCode, "OptDeadCode", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptDeadJumps = { OptDeadJumps, "OptDeadJumps", 100, 0, 0, 0, 0, 0 }; @@ -1809,6 +1810,7 @@ static OptFunc* OptFuncs[] = { &DOptCmp5, &DOptCmp6, &DOptCmp7, + &DOptCmp8, &DOptCondBranches, &DOptDeadCode, &DOptDeadJumps, @@ -2173,6 +2175,7 @@ static unsigned RunOptGroup3 (CodeSeg* S) C += RunOptFunc (S, &DOptCmp5, 1); C += RunOptFunc (S, &DOptCmp6, 1); C += RunOptFunc (S, &DOptCmp7, 1); + C += RunOptFunc (S, &DOptCmp8, 1); C += RunOptFunc (S, &DOptTest1, 1); C += RunOptFunc (S, &DOptLoad1, 1); C += RunOptFunc (S, &DOptUnusedLoads, 1); diff --git a/src/cc65/coptcmp.c b/src/cc65/coptcmp.c index 91f929b5d..a7bd187ef 100644 --- a/src/cc65/coptcmp.c +++ b/src/cc65/coptcmp.c @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 2001-2003 Ullrich von Bassewitz */ +/* (C) 2001-2004 Ullrich von Bassewitz */ /* Römerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ @@ -279,6 +279,63 @@ unsigned OptBoolTrans (CodeSeg* S) unsigned OptCmp1 (CodeSeg* S) +/* Search for the sequence + * + * ldx xx + * stx tmp1 + * ora tmp1 + * + * and replace it by + * + * ora xx + */ +{ + unsigned Changes = 0; + + /* Walk over the entries */ + unsigned 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_LDX && + !CS_RangeHasLabel (S, I+1, 2) && + CS_GetEntries (S, L+1, I+1, 2) && + L[1]->OPC == OP65_STX && + strcmp (L[1]->Arg, "tmp1") == 0 && + L[2]->OPC == OP65_ORA && + strcmp (L[2]->Arg, "tmp1") == 0) { + + CodeEntry* X; + + /* Insert the ora instead */ + X = NewCodeEntry (OP65_ORA, L[0]->AM, L[0]->Arg, 0, L[0]->LI); + CS_InsertEntry (S, X, I); + + /* Remove all other instructions */ + CS_DelEntries (S, I+1, 3); + + /* Remember, we had changes */ + ++Changes; + + } + + /* Next entry */ + ++I; + + } + + /* Return the number of changes made */ + return Changes; +} + + + +unsigned OptCmp2 (CodeSeg* S) /* Search for the sequence * * stx xx @@ -303,12 +360,12 @@ unsigned OptCmp1 (CodeSeg* S) CodeEntry* E = CS_GetEntry (S, I); /* Check for the sequence */ - if (E->OPC == OP65_STX && + if (E->OPC == OP65_STX && !CS_RangeHasLabel (S, I+1, 2) && CS_GetEntries (S, L, I+1, 2) && - L[0]->OPC == OP65_STX && + L[0]->OPC == OP65_STX && strcmp (L[0]->Arg, "tmp1") == 0 && - L[1]->OPC == OP65_ORA && + L[1]->OPC == OP65_ORA && strcmp (L[1]->Arg, "tmp1") == 0) { /* Remove the remaining instructions */ @@ -333,7 +390,7 @@ unsigned OptCmp1 (CodeSeg* S) -unsigned OptCmp2 (CodeSeg* S) +unsigned OptCmp3 (CodeSeg* S) /* Search for * * lda/and/ora/eor ... @@ -455,7 +512,7 @@ unsigned OptCmp2 (CodeSeg* S) -unsigned OptCmp3 (CodeSeg* S) +unsigned OptCmp4 (CodeSeg* S) /* Search for * * lda x @@ -533,7 +590,7 @@ unsigned OptCmp3 (CodeSeg* S) -unsigned OptCmp4 (CodeSeg* S) +unsigned OptCmp5 (CodeSeg* S) /* Optimize compares of local variables: * * ldy #o @@ -642,7 +699,7 @@ unsigned OptCmp4 (CodeSeg* S) -unsigned OptCmp5 (CodeSeg* S) +unsigned OptCmp6 (CodeSeg* S) /* Search for calls to compare subroutines followed by a conditional branch * and replace them by cheaper versions, since the branch means that the * boolean value returned by these routines is not needed (we may also check @@ -704,7 +761,7 @@ unsigned OptCmp5 (CodeSeg* S) -unsigned OptCmp6 (CodeSeg* S) +unsigned OptCmp7 (CodeSeg* S) /* Search for a sequence ldx/txa/branch and remove the txa if A is not * used later. */ @@ -748,7 +805,7 @@ unsigned OptCmp6 (CodeSeg* S) -unsigned OptCmp7 (CodeSeg* S) +unsigned OptCmp8 (CodeSeg* S) /* Check for register compares where the contents of the register and therefore * the result of the compare is known. */ diff --git a/src/cc65/coptcmp.h b/src/cc65/coptcmp.h index 13ef99807..39a79121f 100644 --- a/src/cc65/coptcmp.h +++ b/src/cc65/coptcmp.h @@ -6,9 +6,9 @@ /* */ /* */ /* */ -/* (C) 2001 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ +/* (C) 2001-2004 Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ /* */ @@ -63,6 +63,18 @@ unsigned OptBoolTrans (CodeSeg* S); unsigned OptCmp1 (CodeSeg* S); +/* Search for the sequence + * + * ldx xx + * stx tmp1 + * ora tmp1 + * + * and replace it by + * + * ora xx + */ + +unsigned OptCmp2 (CodeSeg* S); /* Search for the sequence * * stx xx @@ -75,7 +87,7 @@ unsigned OptCmp1 (CodeSeg* S); * ora xx */ -unsigned OptCmp2 (CodeSeg* S); +unsigned OptCmp3 (CodeSeg* S); /* Search for * * lda/and/ora/eor ... @@ -89,7 +101,7 @@ unsigned OptCmp2 (CodeSeg* S); * and remove the cmp. */ -unsigned OptCmp3 (CodeSeg* S); +unsigned OptCmp4 (CodeSeg* S); /* Search for * * lda x @@ -110,7 +122,7 @@ unsigned OptCmp3 (CodeSeg* S); * of this instruction. */ -unsigned OptCmp4 (CodeSeg* S); +unsigned OptCmp5 (CodeSeg* S); /* Optimize compares of local variables: * * ldy #o @@ -124,19 +136,19 @@ unsigned OptCmp4 (CodeSeg* S); * jne/jeq L2 */ -unsigned OptCmp5 (CodeSeg* S); +unsigned OptCmp6 (CodeSeg* S); /* Search for calls to compare subroutines followed by a conditional branch * and replace them by cheaper versions, since the branch means that the * boolean value returned by these routines is not needed (we may also check * that explicitly, but for the current code generator it is always true). */ -unsigned OptCmp6 (CodeSeg* S); +unsigned OptCmp7 (CodeSeg* S); /* Search for a sequence ldx/txa/branch and remove the txa if A is not * used later. */ -unsigned OptCmp7 (CodeSeg* S); +unsigned OptCmp8 (CodeSeg* S); /* Check for register compares where the contents of the register and therefore * the result of the compare is known. */