1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-15 17:30:06 +00:00

Added new opt OptPushPop2.

Also renamed OptPushPop to OptPushPop1.
This commit is contained in:
acqn 2020-09-18 20:22:58 +08:00 committed by Oliver Schmidt
parent 0f66f7569e
commit 4f3a96a535
3 changed files with 101 additions and 7 deletions

View File

@ -167,7 +167,8 @@ static OptFunc DOptPtrStore2 = { OptPtrStore2, "OptPtrStore2", 65, 0,
static OptFunc DOptPtrStore3 = { OptPtrStore3, "OptPtrStore3", 100, 0, 0, 0, 0, 0 };
static OptFunc DOptPush1 = { OptPush1, "OptPush1", 65, 0, 0, 0, 0, 0 };
static OptFunc DOptPush2 = { OptPush2, "OptPush2", 50, 0, 0, 0, 0, 0 };
static OptFunc DOptPushPop = { OptPushPop, "OptPushPop", 0, 0, 0, 0, 0, 0 };
static OptFunc DOptPushPop1 = { OptPushPop1, "OptPushPop1", 0, 0, 0, 0, 0, 0 };
static OptFunc DOptPushPop2 = { OptPushPop2, "OptPushPop2", 0, 0, 0, 0, 0, 0 };
static OptFunc DOptRTS = { OptRTS, "OptRTS", 100, 0, 0, 0, 0, 0 };
static OptFunc DOptRTSJumps1 = { OptRTSJumps1, "OptRTSJumps1", 100, 0, 0, 0, 0, 0 };
static OptFunc DOptRTSJumps2 = { OptRTSJumps2, "OptRTSJumps2", 100, 0, 0, 0, 0, 0 };
@ -269,7 +270,7 @@ static OptFunc* OptFuncs[] = {
&DOptPtrStore3,
&DOptPush1,
&DOptPush2,
&DOptPushPop,
&DOptPushPop1,
&DOptRTS,
&DOptRTSJumps1,
&DOptRTSJumps2,
@ -709,7 +710,8 @@ static unsigned RunOptGroup3 (CodeSeg* S)
C += RunOptFunc (S, &DOptTransfers4, 1);
C += RunOptFunc (S, &DOptStore1, 1);
C += RunOptFunc (S, &DOptStore5, 1);
C += RunOptFunc (S, &DOptPushPop, 1);
C += RunOptFunc (S, &DOptPushPop1, 1);
C += RunOptFunc (S, &DOptPushPop2, 1);
C += RunOptFunc (S, &DOptPrecalc, 1);
Changes += C;

View File

@ -1069,8 +1069,8 @@ unsigned OptTransfers4 (CodeSeg* S)
unsigned OptPushPop (CodeSeg* S)
/* Remove a PHA/PLA sequence were A is not used later */
unsigned OptPushPop1 (CodeSeg* S)
/* Remove a PHA/PLA sequence were A not used later */
{
unsigned Changes = 0;
unsigned Push = 0; /* Index of push insn */
@ -1199,6 +1199,95 @@ unsigned OptPushPop (CodeSeg* S)
unsigned OptPushPop2 (CodeSeg* S)
/* Remove a PHP/PLP sequence were no processor flags changed inside */
{
unsigned Changes = 0;
unsigned Push = 0; /* Index of push insn */
unsigned Pop = 0; /* Index of pop insn */
enum {
Searching,
FoundPush,
FoundPop
} State = Searching;
/* Walk over the entries. Look for a push instruction that is followed by
** a pop later, where the pop is not followed by an conditional branch,
** and where the value of the A register is not used later on.
** Look out for the following problems:
**
** - There may be another PHP/PLP inside the sequence: Restart it.
** - All jumps inside the sequence must not go outside the sequence,
** otherwise it would be too complicated to remove the PHP/PLP.
*/
unsigned I = 0;
while (I < CS_GetEntryCount (S)) {
/* Get next entry */
CodeEntry* E = CS_GetEntry (S, I);
switch (State) {
case Searching:
if (E->OPC == OP65_PHP) {
/* Found start of sequence */
Push = I;
State = FoundPush;
}
break;
case FoundPush:
if (E->OPC == OP65_PHP) {
/* Inner push/pop, restart */
Push = I;
} else if (E->OPC == OP65_PLP) {
/* Found a matching pop */
Pop = I;
/* Check that the block between Push and Pop is a basic
** block (one entry, one exit). Otherwise ignore it.
*/
if (CS_IsBasicBlock (S, Push, Pop)) {
State = FoundPop;
} else {
/* Go into searching mode again */
State = Searching;
}
} else if ((E->Info & OF_BRA) == 0 &&
(E->Info & OF_STORE) == 0 &&
E->OPC != OP65_NOP &&
E->OPC != OP65_TSX) {
/* Don't bother skipping dead code */
State = Searching;
}
break;
case FoundPop:
/* We can remove the PHP and PLP instructions */
CS_DelEntry (S, Pop);
CS_DelEntry (S, Push);
/* Correct I so we continue with THIS insn */
I -= 3;
/* Remember we had changes */
++Changes;
/* Go into search mode again */
State = Searching;
break;
}
/* Next entry */
++I;
}
/* Return the number of changes made */
return Changes;
}
unsigned OptPrecalc (CodeSeg* S)
/* Replace immediate operations with the accu where the current contents are
** known by a load of the final value.

View File

@ -82,8 +82,11 @@ unsigned OptTransfers4 (CodeSeg* S);
** by a load of the second register if possible.
*/
unsigned OptPushPop (CodeSeg* S);
/* Remove a PHA/PLA sequence were A is not used later */
unsigned OptPushPop1 (CodeSeg* S);
/* Remove a PHA/PLA sequence were A not used later */
unsigned OptPushPop2 (CodeSeg* S);
/* Remove a PHP/PLP sequence were no processor flags changed inside */
unsigned OptPrecalc (CodeSeg* S);
/* Replace immediate operations with the accu where the current contents are