mirror of
https://github.com/cc65/cc65.git
synced 2025-01-11 11:30:13 +00:00
Fixed OptStackOps when the stuff pushed on stack top is accessed before the op.
This commit is contained in:
parent
79be6dec16
commit
4d5fe38540
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user