diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index 875b6617f..a99b507c6 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -1427,8 +1427,10 @@ static OptFunc DOptShift3 = { OptShift3, "OptShift3", 110, 0, static OptFunc DOptSize1 = { OptSize1, "OptSize1", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptSize2 = { OptSize2, "OptSize2", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptStackOps = { OptStackOps, "OptStackOps", 100, 0, 0, 0, 0, 0 }; -static OptFunc DOptStore1 = { OptStore1, "OptStore1", 220, 0, 0, 0, 0, 0 }; -static OptFunc DOptStore2 = { OptStore2, "OptStore2", 120, 0, 0, 0, 0, 0 }; +static OptFunc DOptStore1 = { OptStore1, "OptStore1", 70, 0, 0, 0, 0, 0 }; +static OptFunc DOptStore2 = { OptStore2, "OptStore2", 220, 0, 0, 0, 0, 0 }; +static OptFunc DOptStore3 = { OptStore3, "OptStore3", 120, 0, 0, 0, 0, 0 }; +static OptFunc DOptStore4 = { OptStore4, "OptStore4", 50, 0, 0, 0, 0, 0 }; static OptFunc DOptStoreLoad = { OptStoreLoad, "OptStoreLoad", 0, 0, 0, 0, 0, 0 }; static OptFunc DOptSub1 = { OptSub1, "OptSub1", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptSub2 = { OptSub2, "OptSub2", 100, 0, 0, 0, 0, 0 }; @@ -1493,6 +1495,8 @@ static OptFunc* OptFuncs[] = { &DOptStackOps, &DOptStore1, &DOptStore2, + &DOptStore3, + &DOptStore4, &DOptStoreLoad, &DOptSub1, &DOptSub2, @@ -1750,8 +1754,10 @@ static unsigned RunOptGroup1 (CodeSeg* S) Changes += RunOptFunc (S, &DOptShift1, 1); Changes += RunOptFunc (S, &DOptShift2, 1); Changes += RunOptFunc (S, &DOptShift3, 1); - Changes += RunOptFunc (S, &DOptStore1, 5); + Changes += RunOptFunc (S, &DOptStore1, 1); Changes += RunOptFunc (S, &DOptStore2, 5); + Changes += RunOptFunc (S, &DOptStore3, 5); + Changes += RunOptFunc (S, &DOptStore4, 1); /* Return the number of changes */ return Changes; diff --git a/src/cc65/compile.c b/src/cc65/compile.c index 858f855b1..ca3175baa 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -284,7 +284,7 @@ void Compile (const char* FileName) }; /* Add macros that are always defined */ - DefineNumericMacro ("__CC65__", (VER_MAJOR * 0x100) + (VER_MINOR * 0x10) + VER_PATCH); + DefineNumericMacro ("__CC65__", VERSION); /* Strict ANSI macro */ if (ANSI) { @@ -349,3 +349,4 @@ void Compile (const char* FileName) + diff --git a/src/cc65/coptstore.c b/src/cc65/coptstore.c index 66e1a7a66..6a4916be5 100644 --- a/src/cc65/coptstore.c +++ b/src/cc65/coptstore.c @@ -6,9 +6,9 @@ /* */ /* */ /* */ -/* (C) 2002 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ +/* (C) 2002-2003 Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ /* */ @@ -41,7 +41,7 @@ /*****************************************************************************/ -/* Code */ +/* Code */ /*****************************************************************************/ @@ -55,6 +55,61 @@ static void InsertStore (CodeSeg* S, unsigned* IP, LineInfo* LI) unsigned OptStore1 (CodeSeg* S) +/* Search for the sequence + * + * ldy #n + * jsr staxysp + * ldy #n+1 + * jsr ldaxysp + * + * and remove the useless load, provided that the next insn doesn't use flags + * from the load. + */ +{ + unsigned Changes = 0; + + /* Walk over the entries */ + unsigned I = 0; + while (I < CS_GetEntryCount (S)) { + + CodeEntry* L[5]; + + /* Get next entry */ + L[0] = CS_GetEntry (S, I); + + /* Check for the sequence */ + if (L[0]->OPC == OP65_LDY && + CE_KnownImm (L[0]) && + L[0]->Num < 0xFF && + !CS_RangeHasLabel (S, I+1, 3) && + CS_GetEntries (S, L+1, I+1, 4) && + CE_IsCallTo (L[1], "staxysp") && + L[2]->OPC == OP65_LDY && + CE_KnownImm (L[2]) && + L[2]->Num == L[0]->Num + 1 && + CE_IsCallTo (L[3], "ldaxysp") && + !CE_UseLoadFlags (L[4])) { + + /* Register has already the correct value, remove the loads */ + CS_DelEntries (S, I+2, 2); + + /* Remember, we had changes */ + ++Changes; + + } + + /* Next entry */ + ++I; + + } + + /* Return the number of changes made */ + return Changes; +} + + + +unsigned OptStore2 (CodeSeg* S) /* Search for a call to staxysp. If the ax register is not used later, and * the value is constant, just use the A register and store directly into the * stack. @@ -130,7 +185,7 @@ unsigned OptStore1 (CodeSeg* S) -unsigned OptStore2 (CodeSeg* S) +unsigned OptStore3 (CodeSeg* S) /* Search for a call to steaxysp. If the eax register is not used later, and * the value is constant, just use the A register and store directly into the * stack. @@ -275,3 +330,60 @@ unsigned OptStore2 (CodeSeg* S) +unsigned OptStore4 (CodeSeg* S) +/* Search for the sequence + * + * sta xx + * stx yy + * lda xx + * ldx yy + * + * and remove the useless load, provided that the next insn doesn't use flags + * from the load. + */ +{ + unsigned Changes = 0; + + /* Walk over the entries */ + unsigned I = 0; + while (I < CS_GetEntryCount (S)) { + + CodeEntry* L[5]; + + /* Get next entry */ + L[0] = CS_GetEntry (S, I); + + /* Check for the sequence */ + if (L[0]->OPC == OP65_STA && + (L[0]->AM == AM65_ABS || L[0]->AM == AM65_ZP) && + !CS_RangeHasLabel (S, I+1, 3) && + CS_GetEntries (S, L+1, I+1, 4) && + L[1]->OPC == OP65_STX && + L[1]->AM == L[0]->AM && + L[2]->OPC == OP65_LDA && + L[2]->AM == L[0]->AM && + L[3]->OPC == OP65_LDX && + L[3]->AM == L[1]->AM && + strcmp (L[0]->Arg, L[2]->Arg) == 0 && + strcmp (L[1]->Arg, L[3]->Arg) == 0 && + !CE_UseLoadFlags (L[4])) { + + /* Register has already the correct value, remove the loads */ + CS_DelEntries (S, I+2, 2); + + /* Remember, we had changes */ + ++Changes; + + } + + /* Next entry */ + ++I; + + } + + /* Return the number of changes made */ + return Changes; +} + + + diff --git a/src/cc65/coptstore.h b/src/cc65/coptstore.h index 29a97de7d..85042279f 100644 --- a/src/cc65/coptstore.h +++ b/src/cc65/coptstore.h @@ -6,9 +6,9 @@ /* */ /* */ /* */ -/* (C) 2002 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ +/* (C) 2002-2003 Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ /* */ @@ -44,23 +44,47 @@ /*****************************************************************************/ -/* Code */ +/* Code */ /*****************************************************************************/ unsigned OptStore1 (CodeSeg* S); +/* Search for the sequence + * + * ldy #n + * jsr staxysp + * ldy #n+1 + * jsr ldaxysp + * + * and remove the useless load, provided that the next insn doesn't use flags + * from the load. + */ + +unsigned OptStore2 (CodeSeg* S); /* Search for a call to staxysp. If the ax register is not used later, and * the value is constant, just use the A register and store directly into the * stack. */ -unsigned OptStore2 (CodeSeg* S); +unsigned OptStore3 (CodeSeg* S); /* Search for a call to steaxysp. If the eax register is not used later, and * the value is constant, just use the A register and store directly into the * stack. */ +unsigned OptStore4 (CodeSeg* S); +/* Search for the sequence + * + * sta xx + * stx yy + * lda xx + * ldx yy + * + * and remove the useless load, provided that the next insn doesn't use flags + * from the load. + */ + /* End of coptstore.h */