Added new opt OptPushPop2.
Also renamed OptPushPop to OptPushPop1.
This commit is contained in:
@@ -167,7 +167,8 @@ static OptFunc DOptPtrStore2 = { OptPtrStore2, "OptPtrStore2", 65, 0,
|
|||||||
static OptFunc DOptPtrStore3 = { OptPtrStore3, "OptPtrStore3", 100, 0, 0, 0, 0, 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 DOptPush1 = { OptPush1, "OptPush1", 65, 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptPush2 = { OptPush2, "OptPush2", 50, 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 DOptRTS = { OptRTS, "OptRTS", 100, 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptRTSJumps1 = { OptRTSJumps1, "OptRTSJumps1", 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 };
|
static OptFunc DOptRTSJumps2 = { OptRTSJumps2, "OptRTSJumps2", 100, 0, 0, 0, 0, 0 };
|
||||||
@@ -269,7 +270,7 @@ static OptFunc* OptFuncs[] = {
|
|||||||
&DOptPtrStore3,
|
&DOptPtrStore3,
|
||||||
&DOptPush1,
|
&DOptPush1,
|
||||||
&DOptPush2,
|
&DOptPush2,
|
||||||
&DOptPushPop,
|
&DOptPushPop1,
|
||||||
&DOptRTS,
|
&DOptRTS,
|
||||||
&DOptRTSJumps1,
|
&DOptRTSJumps1,
|
||||||
&DOptRTSJumps2,
|
&DOptRTSJumps2,
|
||||||
@@ -709,7 +710,8 @@ static unsigned RunOptGroup3 (CodeSeg* S)
|
|||||||
C += RunOptFunc (S, &DOptTransfers4, 1);
|
C += RunOptFunc (S, &DOptTransfers4, 1);
|
||||||
C += RunOptFunc (S, &DOptStore1, 1);
|
C += RunOptFunc (S, &DOptStore1, 1);
|
||||||
C += RunOptFunc (S, &DOptStore5, 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);
|
C += RunOptFunc (S, &DOptPrecalc, 1);
|
||||||
|
|
||||||
Changes += C;
|
Changes += C;
|
||||||
|
|||||||
@@ -1069,8 +1069,8 @@ unsigned OptTransfers4 (CodeSeg* S)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned OptPushPop (CodeSeg* S)
|
unsigned OptPushPop1 (CodeSeg* S)
|
||||||
/* Remove a PHA/PLA sequence were A is not used later */
|
/* Remove a PHA/PLA sequence were A not used later */
|
||||||
{
|
{
|
||||||
unsigned Changes = 0;
|
unsigned Changes = 0;
|
||||||
unsigned Push = 0; /* Index of push insn */
|
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)
|
unsigned OptPrecalc (CodeSeg* S)
|
||||||
/* Replace immediate operations with the accu where the current contents are
|
/* Replace immediate operations with the accu where the current contents are
|
||||||
** known by a load of the final value.
|
** known by a load of the final value.
|
||||||
|
|||||||
@@ -82,8 +82,11 @@ unsigned OptTransfers4 (CodeSeg* S);
|
|||||||
** by a load of the second register if possible.
|
** by a load of the second register if possible.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
unsigned OptPushPop (CodeSeg* S);
|
unsigned OptPushPop1 (CodeSeg* S);
|
||||||
/* Remove a PHA/PLA sequence were A is not used later */
|
/* 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);
|
unsigned OptPrecalc (CodeSeg* S);
|
||||||
/* Replace immediate operations with the accu where the current contents are
|
/* Replace immediate operations with the accu where the current contents are
|
||||||
|
|||||||
Reference in New Issue
Block a user