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
|
/* Check if this is a call to a harmless subroutine that will not interrupt
|
||||||
** the pushax/op sequence when encountered.
|
** the pushax/op sequence when encountered.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
static const char* const Tab[] = {
|
unsigned Use = 0, Chg = 0;
|
||||||
"aslax1",
|
if (GetFuncInfo (E->Arg, &Use, &Chg) == FNCLS_BUILTIN) {
|
||||||
"aslax2",
|
if ((Chg & REG_SP) != 0) {
|
||||||
"aslax3",
|
return 0;
|
||||||
"aslax4",
|
}
|
||||||
"aslaxy",
|
if ((Use & REG_SP) != 0 &&
|
||||||
"asrax1",
|
((Use & (SLV_IND | SLV_TOP)) != SLV_IND ||
|
||||||
"asrax2",
|
RegValIsUnknown (E->RI->In.RegY) ||
|
||||||
"asrax3",
|
E->RI->In.RegY < PushedBytes)) {
|
||||||
"asrax4",
|
/* If we are using the stack, and we don't have "indirect"
|
||||||
"asraxy",
|
** addressing mode, or the value of Y is unknown, or less
|
||||||
"bcastax",
|
** than two, we cannot cope with this piece of code. Having
|
||||||
"bnegax",
|
** an unknown value of Y means that we cannot correct the
|
||||||
"complax",
|
** stack offset, while having an offset less than PushedBytes
|
||||||
"decax1",
|
** means that the code works with the value on stack which
|
||||||
"decax2",
|
** is to be removed.
|
||||||
"decax3",
|
*/
|
||||||
"decax4",
|
return 0;
|
||||||
"decax5",
|
}
|
||||||
"decax6",
|
return 1;
|
||||||
"decax7",
|
} else {
|
||||||
"decax8",
|
static const char* const Tab[] = {
|
||||||
"decaxy",
|
"_abs",
|
||||||
"incax1",
|
};
|
||||||
"incax2",
|
|
||||||
"incax3",
|
|
||||||
"incax4",
|
|
||||||
"incax5",
|
|
||||||
"incax6",
|
|
||||||
"incax7",
|
|
||||||
"incax8",
|
|
||||||
"incaxy",
|
|
||||||
"ldaidx",
|
|
||||||
"ldauidx",
|
|
||||||
"ldaxidx",
|
|
||||||
"ldaxysp",
|
|
||||||
"negax",
|
|
||||||
"shlax1",
|
|
||||||
"shlax2",
|
|
||||||
"shlax3",
|
|
||||||
"shlax4",
|
|
||||||
"shlaxy",
|
|
||||||
"shrax1",
|
|
||||||
"shrax2",
|
|
||||||
"shrax3",
|
|
||||||
"shrax4",
|
|
||||||
"shraxy",
|
|
||||||
};
|
|
||||||
|
|
||||||
void* R = bsearch (Name,
|
void* R = bsearch (E->Arg,
|
||||||
Tab,
|
Tab,
|
||||||
sizeof (Tab) / sizeof (Tab[0]),
|
sizeof (Tab) / sizeof (Tab[0]),
|
||||||
sizeof (Tab[0]),
|
sizeof (Tab[0]),
|
||||||
CmpHarmless);
|
CmpHarmless);
|
||||||
return (R != 0);
|
return (R != 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -261,7 +261,7 @@ void RemoveRegLoads (StackOpData* D, LoadInfo* LI);
|
|||||||
void RemoveRemainders (StackOpData* D);
|
void RemoveRemainders (StackOpData* D);
|
||||||
/* Remove the code that is unnecessary after translation of the sequence */
|
/* 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
|
/* Check if this is a call to a harmless subroutine that will not interrupt
|
||||||
** the pushax/op sequence when encountered.
|
** the pushax/op sequence when encountered.
|
||||||
*/
|
*/
|
||||||
|
@ -1820,20 +1820,18 @@ unsigned OptStackOps (CodeSeg* S)
|
|||||||
Data.OpEntry = E;
|
Data.OpEntry = E;
|
||||||
State = FoundOp;
|
State = FoundOp;
|
||||||
break;
|
break;
|
||||||
} else if (!HarmlessCall (E->Arg)) {
|
} else if (!HarmlessCall (E, 2)) {
|
||||||
/* A call to an unkown subroutine: We need to start
|
/* The call might use or change the content that we are
|
||||||
** over after the last pushax. Note: This will also
|
** going to access later via the stack pointer. In any
|
||||||
** happen if we encounter a call to pushax!
|
** 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;
|
I = Data.PushIndex;
|
||||||
State = Initialize;
|
State = Initialize;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
} else if (((E->Chg | E->Use) & REG_SP) != 0) {
|
||||||
} else if ((E->Use & REG_SP) != 0 &&
|
|
||||||
(E->AM != AM65_ZP_INDY ||
|
|
||||||
RegValIsUnknown (E->RI->In.RegY) ||
|
|
||||||
E->RI->In.RegY < 2)) {
|
|
||||||
|
|
||||||
/* If we are using the stack, and we don't have "indirect Y"
|
/* If we are using the stack, and we don't have "indirect Y"
|
||||||
** addressing mode, or the value of Y is unknown, or less
|
** 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
|
** that the code works with the value on stack which is to
|
||||||
** be removed.
|
** be removed.
|
||||||
*/
|
*/
|
||||||
I = Data.PushIndex;
|
if (E->AM == AM65_ZPX_IND ||
|
||||||
State = Initialize;
|
((E->Chg | E->Use) & SLV_IND) == 0 ||
|
||||||
break;
|
(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