diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index 0ba8a90d6..728e76d88 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -217,6 +217,7 @@ static OptFunc DOptSub2 = { OptSub2, "OptSub2", 100, 0, static OptFunc DOptSub3 = { OptSub3, "OptSub3", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptTest1 = { OptTest1, "OptTest1", 65, 0, 0, 0, 0, 0 }; static OptFunc DOptTest2 = { OptTest2, "OptTest2", 50, 0, 0, 0, 0, 0 }; +static OptFunc DOptTosLoadPop = { OptTosLoadPop, "OptTosLoadPop", 50, 0, 0, 0, 0, 0 }; static OptFunc DOptTransfers1 = { OptTransfers1, "OptTransfers1", 0, 0, 0, 0, 0, 0 }; static OptFunc DOptTransfers2 = { OptTransfers2, "OptTransfers2", 60, 0, 0, 0, 0, 0 }; static OptFunc DOptTransfers3 = { OptTransfers3, "OptTransfers3", 65, 0, 0, 0, 0, 0 }; @@ -347,6 +348,7 @@ static OptFunc* OptFuncs[] = { &DOptTransfers2, &DOptTransfers3, &DOptTransfers4, + &DOptTosLoadPop, &DOptUnusedLoads, &DOptUnusedStores, /* END SORTED_CODEOPT.SH */ @@ -635,6 +637,7 @@ static unsigned RunOptGroup1 (CodeSeg* S) Changes += RunOptFunc (S, &DOptGotoSPAdj, 1); Changes += RunOptFunc (S, &DOptStackPtrOps, 5); + Changes += RunOptFunc (S, &DOptTosLoadPop, 5); Changes += RunOptFunc (S, &DOptAXOps, 5); Changes += RunOptFunc (S, &DOptAdd3, 1); /* Before OptPtrLoad5! */ Changes += RunOptFunc (S, &DOptPtrStore1, 1); @@ -920,6 +923,7 @@ static unsigned RunOptGroup7 (CodeSeg* S) C += RunOptFunc (S, &DOptStackPtrOps, 5); /* Re-optimize JSR/RTS that may now be grouped */ C += RunOptFunc (S, &DOptRTS, 1); + C += RunOptFunc (S, &DOptTosLoadPop, 5); Changes += C; /* If we had changes, we must run dead code elimination again, diff --git a/src/cc65/coptmisc.c b/src/cc65/coptmisc.c index f52999285..0110dae4e 100644 --- a/src/cc65/coptmisc.c +++ b/src/cc65/coptmisc.c @@ -557,6 +557,57 @@ unsigned OptAXLoad (CodeSeg* S) +unsigned OptTosLoadPop (CodeSeg* S) +/* Merge jsr ldax0sp / jsr|jmp incsp2 into jsr|jmp popax */ +{ + unsigned Changes = 0; + unsigned I; + + /* Walk over the entries */ + I = 0; + while (I < CS_GetEntryCount (S)) { + + const CodeEntry* N; + + /* Get the next entry */ + const CodeEntry* E = CS_GetEntry (S, I); + + /* Check for the sequence */ + if (E->OPC == OP65_JSR && + strncmp (E->Arg, "ldax0sp", 5) == 0 && + (N = CS_GetNextEntry (S, I)) != 0 && + (N->OPC == OP65_JSR || N->OPC == OP65_JMP) && + strcmp (N->Arg, "incsp2") == 0 && + !CE_HasLabel (N)) { + + CodeEntry* X; + + X = NewCodeEntry (N->OPC, AM65_ABS, "popax", 0, N->LI); + CS_InsertEntry (S, X, I+2); + + /* Delete the old code */ + CS_DelEntries (S, I, 2); + + /* Regenerate register info */ + CS_GenRegInfo (S); + + /* Remember we had changes */ + ++Changes; + + } else { + + /* Next entry */ + ++I; + } + + } + + /* Return the number of changes made */ + return Changes; +} + + + unsigned OptAXLoad2 (CodeSeg* S) /* Merge ldy/jsr incaxy/jsr ldaxi into ldy/jsr ldaxidx */ { diff --git a/src/cc65/coptmisc.h b/src/cc65/coptmisc.h index df76e84f4..ea678ea67 100644 --- a/src/cc65/coptmisc.h +++ b/src/cc65/coptmisc.h @@ -131,6 +131,9 @@ unsigned OptBinOps2 (CodeSeg* S); ** by something simpler. */ +unsigned OptTosLoadPop (CodeSeg* S); +/* Merge jsr ldax0sp / jsr|jmp incsp2 into jsr|jmp popax */ + /* End of coptmisc.h */