Merge pull request #2811 from colinleroy/OptTosLoadPop
Optimize jsr ldax0sp/incsp2
This commit is contained in:
@@ -244,6 +244,12 @@ static inline int CE_IsCallTo (const CodeEntry* E, const char* Name)
|
||||
return (E->OPC == OP65_JSR && strcmp (E->Arg, Name) == 0);
|
||||
}
|
||||
|
||||
static inline int CE_IsJumpTo (const CodeEntry* E, const char* Name)
|
||||
/* Check if this is a jump to the given function */
|
||||
{
|
||||
return (E->OPC == OP65_JMP && strcmp (E->Arg, Name) == 0);
|
||||
}
|
||||
|
||||
int CE_UseLoadFlags (CodeEntry* E);
|
||||
/* Return true if the instruction uses any flags that are set by a load of
|
||||
** a register (N and Z).
|
||||
|
||||
@@ -217,6 +217,8 @@ 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 DOptTosPushPop = { OptTosPushPop, "OptTosPushPop", 33, 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 };
|
||||
@@ -343,6 +345,8 @@ static OptFunc* OptFuncs[] = {
|
||||
&DOptSub3,
|
||||
&DOptTest1,
|
||||
&DOptTest2,
|
||||
&DOptTosLoadPop,
|
||||
&DOptTosPushPop,
|
||||
&DOptTransfers1,
|
||||
&DOptTransfers2,
|
||||
&DOptTransfers3,
|
||||
@@ -635,6 +639,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 +925,8 @@ 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);
|
||||
C += RunOptFunc (S, &DOptTosPushPop, 5);
|
||||
|
||||
Changes += C;
|
||||
/* If we had changes, we must run dead code elimination again,
|
||||
|
||||
@@ -486,14 +486,14 @@ static unsigned OptIncDecOps (CodeSeg* S, const char* dec, const char* inc, cons
|
||||
|
||||
unsigned OptStackPtrOps (CodeSeg* S)
|
||||
{
|
||||
return OptIncDecOps(S, "decsp", "incsp", "subysp", "addysp");
|
||||
return OptIncDecOps (S, "decsp", "incsp", "subysp", "addysp");
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned OptAXOps (CodeSeg* S)
|
||||
{
|
||||
return OptIncDecOps(S, "decax", "incax", "decaxy", "incaxy");
|
||||
return OptIncDecOps (S, "decax", "incax", "decaxy", "incaxy");
|
||||
}
|
||||
|
||||
|
||||
@@ -557,6 +557,52 @@ 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 (CE_IsCallTo (E, "ldax0sp") &&
|
||||
(N = CS_GetNextEntry (S, I)) != 0 &&
|
||||
(CE_IsCallTo (N, "incsp2") || CE_IsJumpTo (N, "incsp2")) &&
|
||||
!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);
|
||||
|
||||
/* 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 */
|
||||
{
|
||||
@@ -1150,3 +1196,49 @@ unsigned OptBinOps2 (CodeSeg* S)
|
||||
/* Return the number of changes made */
|
||||
return Changes;
|
||||
}
|
||||
|
||||
|
||||
unsigned OptTosPushPop (CodeSeg* S)
|
||||
/* Merge jsr pushax/j?? 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 decspn, incspn, subysp or addysp */
|
||||
if (CE_IsCallTo (E, "pushax") &&
|
||||
(N = CS_GetNextEntry (S, I)) != 0 &&
|
||||
(CE_IsCallTo (N, "popax") || CE_IsJumpTo (N, "popax")) &&
|
||||
!CE_HasLabel (N)) {
|
||||
|
||||
/* Insert an rts if jmp popax */
|
||||
if (N->OPC == OP65_JMP) {
|
||||
CodeEntry* X = NewCodeEntry (OP65_RTS, AM65_IMP, 0, 0, E->LI);
|
||||
CS_InsertEntry (S, X, I);
|
||||
}
|
||||
|
||||
/* Delete the old code */
|
||||
CS_DelEntries (S, I+1, 2);
|
||||
|
||||
/* Remember we had changes */
|
||||
++Changes;
|
||||
|
||||
} else {
|
||||
|
||||
/* Next entry */
|
||||
++I;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Return the number of changes made */
|
||||
return Changes;
|
||||
}
|
||||
|
||||
@@ -131,7 +131,11 @@ unsigned OptBinOps2 (CodeSeg* S);
|
||||
** by something simpler.
|
||||
*/
|
||||
|
||||
unsigned OptTosLoadPop (CodeSeg* S);
|
||||
/* Merge jsr ldax0sp / jsr|jmp incsp2 into jsr|jmp popax */
|
||||
|
||||
unsigned OptTosPushPop (CodeSeg* S);
|
||||
/* Merge jsr pushax/j?? popax */
|
||||
|
||||
/* End of coptmisc.h */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user