1
0
mirror of https://github.com/cc65/cc65.git synced 2024-09-27 19:55:09 +00:00

A few size optimizations

git-svn-id: svn://svn.cc65.org/cc65/trunk@1606 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2002-11-23 16:33:35 +00:00
parent 222d3d1f23
commit c61729a15a
6 changed files with 111 additions and 23 deletions

View File

@ -161,7 +161,9 @@ static const FuncInfo FuncInfoTable[] = {
{ "pushc1", REG_NONE, REG_A | REG_Y },
{ "pushc2", REG_NONE, REG_A | REG_Y },
{ "pusheax", REG_EAX, REG_Y },
{ "pushw", REG_AX, REG_AXY | REG_PTR1 },
{ "pushw0sp", REG_NONE, REG_AXY },
{ "pushwidx", REG_AXY, REG_AXY | REG_PTR1 },
{ "pushwysp", REG_Y, REG_AXY },
{ "shlax1", REG_AX, REG_AX | REG_TMP1 },
{ "shlax2", REG_AX, REG_AX | REG_TMP1 },

View File

@ -1438,6 +1438,7 @@ static OptFunc DOptPtrLoad6 = { OptPtrLoad6, "OptPtrLoad6", 100, 0,
static OptFunc DOptPtrStore1 = { OptPtrStore1, "OptPtrStore1", 100, 0, 0, 0, 0, 0 };
static OptFunc DOptPtrStore2 = { OptPtrStore2, "OptPtrStore2", 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 DOptShift1 = { OptShift1, "OptShift1", 100, 0, 0, 0, 0, 0 };
static OptFunc DOptShift2 = { OptShift2, "OptShift2", 100, 0, 0, 0, 0, 0 };
@ -1496,6 +1497,7 @@ static OptFunc* OptFuncs[] = {
&DOptPtrStore1,
&DOptPtrStore2,
&DOptPush1,
&DOptPush2,
&DOptPushPop,
&DOptRTS,
&DOptRTSJumps1,
@ -1875,6 +1877,8 @@ static unsigned RunOptGroup5 (CodeSeg* S)
unsigned Changes = 0;
Changes += RunOptFunc (S, &DOptPush1, 1);
Changes += RunOptFunc (S, &DOptPush2, 1);
Changes += RunOptFunc (S, &DOptUnusedLoads, 1);
/* Return the number of changes */
return Changes;

View File

@ -49,11 +49,10 @@
unsigned OptPush1 (CodeSeg* S)
/* Given a sequence
*
* ldy #xx
* jsr ldaxysp
* jsr pushax
*
* If a/x are not used later, replace that by
* If a/x are not used later, and Y is known, replace that by
*
* ldy #xx+2
* jsr pushwysp
@ -61,42 +60,45 @@ unsigned OptPush1 (CodeSeg* S)
* saving 3 bytes and several cycles.
*/
{
unsigned I;
unsigned Changes = 0;
/* Generate register info */
CS_GenRegInfo (S);
/* Walk over the entries */
unsigned I = 0;
I = 0;
while (I < CS_GetEntryCount (S)) {
CodeEntry* L[3];
CodeEntry* L[2];
/* Get next entry */
L[0] = CS_GetEntry (S, I);
/* Check for the sequence */
if (L[0]->OPC == OP65_LDY &&
CE_KnownImm (L[0]) &&
L[0]->Num < 0xFE &&
!CS_RangeHasLabel (S, I+1, 2) &&
CS_GetEntries (S, L+1, I+1, 2) &&
CE_IsCallTo (L[1], "ldaxysp") &&
CE_IsCallTo (L[2], "pushax") &&
!RegAXUsed (S, I+3)) {
if (CE_IsCallTo (L[0], "ldaxysp") &&
RegValIsKnown (L[0]->RI->In.RegY) &&
L[0]->RI->In.RegY < 0xFE &&
(L[1] = CS_GetNextEntry (S, I)) != 0 &&
!CE_HasLabel (L[1]) &&
CE_IsCallTo (L[1], "pushax") &&
!RegAXUsed (S, I+2)) {
/* Insert new code behind the pushax */
const char* Arg;
CodeEntry* X;
/* ldy #xx+1 */
Arg = MakeHexArg (L[0]->Num+2);
Arg = MakeHexArg (L[0]->RI->In.RegY+2);
X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, L[0]->LI);
CS_InsertEntry (S, X, I+3);
CS_InsertEntry (S, X, I+2);
/* jsr pushwysp */
X = NewCodeEntry (OP65_JSR, AM65_ABS, "pushwysp", 0, L[2]->LI);
CS_InsertEntry (S, X, I+4);
X = NewCodeEntry (OP65_JSR, AM65_ABS, "pushwysp", 0, L[1]->LI);
CS_InsertEntry (S, X, I+3);
/* Delete the old code */
CS_DelEntries (S, I, 3);
CS_DelEntries (S, I, 2);
/* Remember, we had changes */
++Changes;
@ -108,6 +110,71 @@ unsigned OptPush1 (CodeSeg* S)
}
/* Free the register info */
CS_FreeRegInfo (S);
/* Return the number of changes made */
return Changes;
}
unsigned OptPush2 (CodeSeg* S)
/* A sequence
*
* jsr ldaxidx
* jsr pushax
*
* may get replaced by
*
* jsr pushwidx
*
*/
{
unsigned I;
unsigned Changes = 0;
/* Generate register info */
CS_GenRegInfo (S);
/* Walk over the entries */
I = 0;
while (I < CS_GetEntryCount (S)) {
CodeEntry* L[2];
/* Get next entry */
L[0] = CS_GetEntry (S, I);
/* Check for the sequence */
if (CE_IsCallTo (L[0], "ldaxidx") &&
(L[1] = CS_GetNextEntry (S, I)) != 0 &&
!CE_HasLabel (L[1]) &&
CE_IsCallTo (L[1], "pushax")) {
/* Insert new code behind the pushax */
CodeEntry* X;
/* jsr pushwidx */
X = NewCodeEntry (OP65_JSR, AM65_ABS, "pushwidx", 0, L[1]->LI);
CS_InsertEntry (S, X, I+2);
/* Delete the old code */
CS_DelEntries (S, I, 2);
/* Remember, we had changes */
++Changes;
}
/* Next entry */
++I;
}
/* Free the register info */
CS_FreeRegInfo (S);
/* Return the number of changes made */
return Changes;
}

View File

@ -6,7 +6,7 @@
/* */
/* */
/* */
/* (C) 2001 Ullrich von Bassewitz */
/* (C) 2001-2002 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@cc65.org */
@ -64,6 +64,18 @@ unsigned OptPush1 (CodeSeg* S);
* saving 3 bytes and several cycles.
*/
unsigned OptPush2 (CodeSeg* S);
/* A sequence
*
* jsr ldaxidx
* jsr pushax
*
* may get replaced by
*
* jsr pushwidx
*
*/
/* End of coptpush.h */

View File

@ -82,6 +82,8 @@ static const CallDesc CallTable [] = {
{ "pushax", -1, 0, -1, "pusha0" },
{ "pushax", -1, 0xFF, -1, "pushaFF" },
{ "pushaysp", -1, -1, 0, "pusha0sp" },
{ "pushwidx", -1, -1, 1, "pushw" },
{ "pushwysp", -1, -1, 3, "pushw0sp" },
{ "staxysp", -1, -1, 0, "stax0sp" },
{ "tosaddax", -1, 0, -1, "tosadda0" },
{ "tosandax", -1, 0, -1, "tosanda0" },

View File

@ -607,7 +607,7 @@ static int HarmlessCall (const char* Name)
*/
{
static const char* Tab[] = {
"ldaxidx",
"ldaxidx",
"ldaxysp",
};
@ -699,7 +699,7 @@ unsigned OptStackOps (CodeSeg* S)
Data.ZPLo = "ptr1";
Data.ZPHi = "ptr1+1";
} else if ((UsedRegs & REG_PTR2) == REG_NONE) {
Data.ZPLo = "ptr2";
Data.ZPLo = "ptr2";
Data.ZPHi = "ptr2+1";
} else {
/* No registers available */
@ -741,16 +741,17 @@ unsigned OptStackOps (CodeSeg* S)
/* Restart the sequence */
Push = I;
UsedRegs = REG_NONE;
} else if (!HarmlessCall (E->Arg)) {
} else if (HarmlessCall (E->Arg)) {
/* Track zeropage register usage */
UsedRegs |= (E->Use | E->Chg);
} else {
/* A call to an unkown subroutine ends the sequence */
InSeq = 0;
}
} else {
/* Other stuff: Track zeropage register usage */
UsedRegs |= (E->Use | E->Chg);
}
} else if (CE_IsCallTo (E, "pushax")) {