mirror of
https://github.com/cc65/cc65.git
synced 2025-08-08 22:25:28 +00:00
Even more optimization, cleanup, bugfix, comments.
This commit is contained in:
@@ -614,8 +614,7 @@ static unsigned OptStackPtrOps (CodeSeg* S)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static unsigned OptGotoSPAdj (CodeSeg* S)
|
static unsigned OptGotoSPAdj (CodeSeg* S)
|
||||||
/* Remove unnecessary SP adjustment while gotoing
|
/* Optimize SP adjustment for forward 'goto' */
|
||||||
*/
|
|
||||||
{
|
{
|
||||||
unsigned Changes = 0;
|
unsigned Changes = 0;
|
||||||
unsigned I;
|
unsigned I;
|
||||||
@@ -631,7 +630,7 @@ static unsigned OptGotoSPAdj (CodeSeg* S)
|
|||||||
/* Get next entry */
|
/* Get next entry */
|
||||||
L[0] = CS_GetEntry (S, I);
|
L[0] = CS_GetEntry (S, I);
|
||||||
|
|
||||||
/* Check for the sequence */
|
/* Check for the sequence generated by g_lateadjustSP */
|
||||||
if (L[0]->OPC == OP65_PHA &&
|
if (L[0]->OPC == OP65_PHA &&
|
||||||
CS_GetEntries (S, L+1, I+1, 9) &&
|
CS_GetEntries (S, L+1, I+1, 9) &&
|
||||||
L[1]->OPC == OP65_LDA &&
|
L[1]->OPC == OP65_LDA &&
|
||||||
@@ -640,48 +639,78 @@ static unsigned OptGotoSPAdj (CodeSeg* S)
|
|||||||
L[3]->OPC == OP65_ADC &&
|
L[3]->OPC == OP65_ADC &&
|
||||||
strcmp (L[3]->Arg, "sp") == 0 &&
|
strcmp (L[3]->Arg, "sp") == 0 &&
|
||||||
L[6]->OPC == OP65_ADC &&
|
L[6]->OPC == OP65_ADC &&
|
||||||
strcmp (L[6]->Arg, "sp+1") == 0 &&
|
strcmp (L[6]->Arg, "sp+1") == 0 &&
|
||||||
L[9]->OPC == OP65_JMP
|
L[9]->OPC == OP65_JMP) {
|
||||||
) {
|
adjustment = FindSPAdjustment (L[1]->Arg);
|
||||||
printf("Goto SP adjustment found. Jump to: %s, data Label: %s\n", L[9]->Arg, L[1]->Arg);
|
|
||||||
adjustment = FindSPAdjustment(L[1]->Arg);
|
|
||||||
|
|
||||||
if (adjustment == 0) {
|
if (adjustment == 0) {
|
||||||
|
/* No SP adjustment needed, remove the whole sequence */
|
||||||
|
CS_DelEntries (S, I, 9);
|
||||||
|
}
|
||||||
|
else if (adjustment >= 65536 - 8) {
|
||||||
|
/* If adjustment is in range [-8, 0) we use decsp* calls */
|
||||||
|
char Buf[20];
|
||||||
|
adjustment = 65536 - adjustment;
|
||||||
|
xsprintf (Buf, sizeof (Buf), "decsp%u", adjustment);
|
||||||
|
X = NewCodeEntry (OP65_JSR, AM65_ABS, Buf, 0, L[1]->LI);
|
||||||
|
CS_InsertEntry (S, X, I + 9);
|
||||||
|
|
||||||
|
/* Delete the old code */
|
||||||
|
CS_DelEntries (S, I, 9);
|
||||||
|
}
|
||||||
|
else if (adjustment >= 65536 - 255) {
|
||||||
|
/* For range [-255, -8) we have ldy #, jsr subysp */
|
||||||
|
adjustment = 65536 - adjustment;
|
||||||
|
Arg = MakeHexArg (adjustment);
|
||||||
|
X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, L[1]->LI);
|
||||||
|
CS_InsertEntry (S, X, I + 9);
|
||||||
|
X = NewCodeEntry (OP65_JSR, AM65_ABS, "subysp", 0, L[1]->LI);
|
||||||
|
CS_InsertEntry (S, X, I + 10);
|
||||||
|
|
||||||
|
/* Delete the old code */
|
||||||
CS_DelEntries (S, I, 9);
|
CS_DelEntries (S, I, 9);
|
||||||
}
|
}
|
||||||
else if (adjustment > 255) {
|
else if (adjustment > 255) {
|
||||||
|
/* For ranges [-32768, 255) and (255, 32767) the only modification
|
||||||
|
** is to replace the absolute with immediate addressing */
|
||||||
Arg = MakeHexArg (adjustment & 0xff);
|
Arg = MakeHexArg (adjustment & 0xff);
|
||||||
X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, L[1]->LI);
|
X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, L[1]->LI);
|
||||||
CS_InsertEntry(S, X, I + 1);
|
CS_InsertEntry (S, X, I + 1);
|
||||||
Arg = MakeHexArg (adjustment >> 8);
|
Arg = MakeHexArg (adjustment >> 8);
|
||||||
X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, L[5]->LI);
|
X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, L[5]->LI);
|
||||||
CS_InsertEntry(S, X, I + 6);
|
CS_InsertEntry (S, X, I + 6);
|
||||||
|
|
||||||
CS_DelEntry(S, I + 2);
|
/* Delete the old code */
|
||||||
CS_DelEntry(S, I + 6);
|
CS_DelEntry (S, I + 2);
|
||||||
|
CS_DelEntry (S, I + 6);
|
||||||
}
|
}
|
||||||
else if (adjustment > 8) {
|
else if (adjustment > 8) {
|
||||||
|
/* For range (8, 255] we have ldy #0, jsr addysp */
|
||||||
Arg = MakeHexArg (adjustment & 0xff);
|
Arg = MakeHexArg (adjustment & 0xff);
|
||||||
X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, L[1]->LI);
|
X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, L[1]->LI);
|
||||||
CS_InsertEntry (S, X, I);
|
CS_InsertEntry (S, X, I + 9);
|
||||||
X = NewCodeEntry (OP65_JSR, AM65_ABS, "addysp", 0, L[1]->LI);
|
X = NewCodeEntry (OP65_JSR, AM65_ABS, "addysp", 0, L[1]->LI);
|
||||||
CS_InsertEntry (S, X, I + 1);
|
CS_InsertEntry (S, X, I + 10);
|
||||||
|
|
||||||
CS_DelEntries(S, I + 2, 9);
|
/* Delete the old code */
|
||||||
|
CS_DelEntries (S, I, 9);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
/* If adjustment is in range (0, 8] we use incsp* calls */
|
||||||
char Buf[20];
|
char Buf[20];
|
||||||
xsprintf (Buf, sizeof (Buf), "incsp%u", adjustment);
|
xsprintf (Buf, sizeof (Buf), "incsp%u", adjustment);
|
||||||
X = NewCodeEntry (OP65_JSR, AM65_ABS, Buf, 0, L[1]->LI);
|
X = NewCodeEntry (OP65_JSR, AM65_ABS, Buf, 0, L[1]->LI);
|
||||||
CS_InsertEntry (S, X, I);
|
CS_InsertEntry (S, X, I + 9);
|
||||||
|
|
||||||
CS_DelEntries(S, I + 1, 9);
|
/* Delete the old code */
|
||||||
|
CS_DelEntries (S, I, 9);
|
||||||
}
|
}
|
||||||
/* Regenerate register info */
|
/* Regenerate register info */
|
||||||
CS_GenRegInfo (S);
|
CS_GenRegInfo (S);
|
||||||
|
|
||||||
/* Remember we had changes */
|
/* Remember we had changes */
|
||||||
Changes++;
|
Changes++;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* Next entry */
|
/* Next entry */
|
||||||
@@ -1311,7 +1340,6 @@ static unsigned RunOptGroup3 (CodeSeg* S)
|
|||||||
C += RunOptFunc (S, &DOptCmp6, 1);
|
C += RunOptFunc (S, &DOptCmp6, 1);
|
||||||
C += RunOptFunc (S, &DOptCmp7, 1);
|
C += RunOptFunc (S, &DOptCmp7, 1);
|
||||||
C += RunOptFunc (S, &DOptCmp9, 1);
|
C += RunOptFunc (S, &DOptCmp9, 1);
|
||||||
|
|
||||||
C += RunOptFunc (S, &DOptTest1, 1);
|
C += RunOptFunc (S, &DOptTest1, 1);
|
||||||
C += RunOptFunc (S, &DOptLoad1, 1);
|
C += RunOptFunc (S, &DOptLoad1, 1);
|
||||||
C += RunOptFunc (S, &DOptJumpTarget3, 1); /* After OptCondBranches2 */
|
C += RunOptFunc (S, &DOptJumpTarget3, 1); /* After OptCondBranches2 */
|
||||||
|
@@ -140,6 +140,7 @@ struct SymEntry {
|
|||||||
Collection *DefsOrRefs;
|
Collection *DefsOrRefs;
|
||||||
} L;
|
} L;
|
||||||
|
|
||||||
|
/* Value of SP adjustment needed after forward 'goto' */
|
||||||
struct {
|
struct {
|
||||||
unsigned short SPAdjustment;
|
unsigned short SPAdjustment;
|
||||||
} G;
|
} G;
|
||||||
|
@@ -226,6 +226,7 @@ void EnterGlobalLevel (void)
|
|||||||
/* Create and assign the tag table */
|
/* Create and assign the tag table */
|
||||||
TagTab0 = TagTab = NewSymTable (SYMTAB_SIZE_GLOBAL);
|
TagTab0 = TagTab = NewSymTable (SYMTAB_SIZE_GLOBAL);
|
||||||
|
|
||||||
|
/* Create and assign the table of SP adjustment symbols */
|
||||||
SPAdjustTab = NewSymTable (SYMTAB_SIZE_GLOBAL);
|
SPAdjustTab = NewSymTable (SYMTAB_SIZE_GLOBAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -681,16 +682,14 @@ DefOrRef* AddDefOrRef (SymEntry* E, unsigned Flags)
|
|||||||
|
|
||||||
unsigned short FindSPAdjustment (const char* Name)
|
unsigned short FindSPAdjustment (const char* Name)
|
||||||
{
|
{
|
||||||
|
/* Search for an entry in the table of SP adjustments */
|
||||||
SymEntry* Entry = FindSymInTable (SPAdjustTab, Name, HashStr (Name));
|
SymEntry* Entry = FindSymInTable (SPAdjustTab, Name, HashStr (Name));
|
||||||
|
|
||||||
if (Entry) {
|
if (!Entry) {
|
||||||
printf("L: %s sa: %d\n", Name, Entry->V.G.SPAdjustment);
|
Internal ("No SP adjustment label entry found");
|
||||||
return Entry->V.G.SPAdjustment;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Fatal("ICE: No label entry found");
|
return Entry->V.G.SPAdjustment;
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SymEntry* AddLabelSym (const char* Name, unsigned Flags)
|
SymEntry* AddLabelSym (const char* Name, unsigned Flags)
|
||||||
@@ -748,11 +747,13 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags)
|
|||||||
g_userodata();
|
g_userodata();
|
||||||
g_defdatalabel (DOR->LateSP_Label);
|
g_defdatalabel (DOR->LateSP_Label);
|
||||||
g_defdata (CF_CONST | CF_INT, StackPtr - DOR->StackPtr, 0);
|
g_defdata (CF_CONST | CF_INT, StackPtr - DOR->StackPtr, 0);
|
||||||
E = NewSymEntry (LocalLabelName(DOR->LateSP_Label), SC_SPADJUSTMENT);
|
|
||||||
|
/* Optimizer will need the information about the value of SP adjustment
|
||||||
|
** later, so let's preserve it. */
|
||||||
|
E = NewSymEntry (LocalLabelName (DOR->LateSP_Label), SC_SPADJUSTMENT);
|
||||||
E->V.G.SPAdjustment = StackPtr - DOR->StackPtr;
|
E->V.G.SPAdjustment = StackPtr - DOR->StackPtr;
|
||||||
AddSymEntry (SPAdjustTab, E);
|
AddSymEntry (SPAdjustTab, E);
|
||||||
|
|
||||||
|
|
||||||
/* Are we jumping into a block with initalization of an object that
|
/* Are we jumping into a block with initalization of an object that
|
||||||
** has automatic storage duration? Let's emit a warning.
|
** has automatic storage duration? Let's emit a warning.
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user