Fixed OptStackOps when the stuff pushed on stack top is accessed before the op.

This commit is contained in:
acqn 2020-09-18 20:23:03 +08:00 committed by Oliver Schmidt
parent 79be6dec16
commit 4d5fe38540
3 changed files with 48 additions and 68 deletions

View File

@ -1224,66 +1224,43 @@ static int CmpHarmless (const void* Key, const void* Entry)
int HarmlessCall (const char* Name)
int HarmlessCall (const CodeEntry* E, int PushedBytes)
/* Check if this is a call to a harmless subroutine that will not interrupt
** the pushax/op sequence when encountered.
*/
{
static const char* const Tab[] = {
"aslax1",
"aslax2",
"aslax3",
"aslax4",
"aslaxy",
"asrax1",
"asrax2",
"asrax3",
"asrax4",
"asraxy",
"bcastax",
"bnegax",
"complax",
"decax1",
"decax2",
"decax3",
"decax4",
"decax5",
"decax6",
"decax7",
"decax8",
"decaxy",
"incax1",
"incax2",
"incax3",
"incax4",
"incax5",
"incax6",
"incax7",
"incax8",
"incaxy",
"ldaidx",
"ldauidx",
"ldaxidx",
"ldaxysp",
"negax",
"shlax1",
"shlax2",
"shlax3",
"shlax4",
"shlaxy",
"shrax1",
"shrax2",
"shrax3",
"shrax4",
"shraxy",
};
unsigned Use = 0, Chg = 0;
if (GetFuncInfo (E->Arg, &Use, &Chg) == FNCLS_BUILTIN) {
if ((Chg & REG_SP) != 0) {
return 0;
}
if ((Use & REG_SP) != 0 &&
((Use & (SLV_IND | SLV_TOP)) != SLV_IND ||
RegValIsUnknown (E->RI->In.RegY) ||
E->RI->In.RegY < PushedBytes)) {
/* If we are using the stack, and we don't have "indirect"
** addressing mode, or the value of Y is unknown, or less
** than two, we cannot cope with this piece of code. Having
** an unknown value of Y means that we cannot correct the
** stack offset, while having an offset less than PushedBytes
** means that the code works with the value on stack which
** is to be removed.
*/
return 0;
}
return 1;
} else {
static const char* const Tab[] = {
"_abs",
};
void* R = bsearch (Name,
Tab,
sizeof (Tab) / sizeof (Tab[0]),
sizeof (Tab[0]),
CmpHarmless);
return (R != 0);
void* R = bsearch (E->Arg,
Tab,
sizeof (Tab) / sizeof (Tab[0]),
sizeof (Tab[0]),
CmpHarmless);
return (R != 0);
}
}

View File

@ -261,7 +261,7 @@ void RemoveRegLoads (StackOpData* D, LoadInfo* LI);
void RemoveRemainders (StackOpData* D);
/* Remove the code that is unnecessary after translation of the sequence */
int HarmlessCall (const char* Name);
int HarmlessCall (const CodeEntry* E, int PushedBytes);
/* Check if this is a call to a harmless subroutine that will not interrupt
** the pushax/op sequence when encountered.
*/

View File

@ -1820,20 +1820,18 @@ unsigned OptStackOps (CodeSeg* S)
Data.OpEntry = E;
State = FoundOp;
break;
} else if (!HarmlessCall (E->Arg)) {
/* A call to an unkown subroutine: We need to start
** over after the last pushax. Note: This will also
** happen if we encounter a call to pushax!
} else if (!HarmlessCall (E, 2)) {
/* The call might use or change the content that we are
** going to access later via the stack pointer. In any
** case, we need to start over after the last pushax.
** Note: This will also happen if we encounter a call
** to pushax!
*/
I = Data.PushIndex;
State = Initialize;
break;
}
} else if ((E->Use & REG_SP) != 0 &&
(E->AM != AM65_ZP_INDY ||
RegValIsUnknown (E->RI->In.RegY) ||
E->RI->In.RegY < 2)) {
} else if (((E->Chg | E->Use) & REG_SP) != 0) {
/* If we are using the stack, and we don't have "indirect Y"
** addressing mode, or the value of Y is unknown, or less
@ -1843,9 +1841,14 @@ unsigned OptStackOps (CodeSeg* S)
** that the code works with the value on stack which is to
** be removed.
*/
I = Data.PushIndex;
State = Initialize;
break;
if (E->AM == AM65_ZPX_IND ||
((E->Chg | E->Use) & SLV_IND) == 0 ||
(RegValIsUnknown (E->RI->In.RegY) ||
E->RI->In.RegY < 2)) {
I = Data.PushIndex;
State = Initialize;
break;
}
}