From: laubzega Date: Sun, 14 Oct 2018 08:07:59 +0000 (-0700) Subject: Even more optimization, cleanup, bugfix, comments. X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=cf7f3abadd27567ec3950ac82b0f6c3f9fbfd4c8;p=cc65 Even more optimization, cleanup, bugfix, comments. --- diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index 6e547f16d..f87d44900 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -614,8 +614,7 @@ static unsigned OptStackPtrOps (CodeSeg* S) } static unsigned OptGotoSPAdj (CodeSeg* S) -/* Remove unnecessary SP adjustment while gotoing -*/ +/* Optimize SP adjustment for forward 'goto' */ { unsigned Changes = 0; unsigned I; @@ -631,7 +630,7 @@ static unsigned OptGotoSPAdj (CodeSeg* S) /* Get next entry */ L[0] = CS_GetEntry (S, I); - /* Check for the sequence */ + /* Check for the sequence generated by g_lateadjustSP */ if (L[0]->OPC == OP65_PHA && CS_GetEntries (S, L+1, I+1, 9) && L[1]->OPC == OP65_LDA && @@ -640,48 +639,78 @@ static unsigned OptGotoSPAdj (CodeSeg* S) L[3]->OPC == OP65_ADC && strcmp (L[3]->Arg, "sp") == 0 && L[6]->OPC == OP65_ADC && - strcmp (L[6]->Arg, "sp+1") == 0 && - L[9]->OPC == OP65_JMP - ) { - printf("Goto SP adjustment found. Jump to: %s, data Label: %s\n", L[9]->Arg, L[1]->Arg); - adjustment = FindSPAdjustment(L[1]->Arg); + strcmp (L[6]->Arg, "sp+1") == 0 && + L[9]->OPC == OP65_JMP) { + adjustment = FindSPAdjustment (L[1]->Arg); 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); } 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); 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); 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); - CS_DelEntry(S, I + 6); + /* Delete the old code */ + CS_DelEntry (S, I + 2); + CS_DelEntry (S, I + 6); } else if (adjustment > 8) { + /* For range (8, 255] we have ldy #0, jsr addysp */ Arg = MakeHexArg (adjustment & 0xff); 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); - 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 { + /* If adjustment is in range (0, 8] we use incsp* calls */ char Buf[20]; xsprintf (Buf, sizeof (Buf), "incsp%u", adjustment); 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 */ CS_GenRegInfo (S); /* Remember we had changes */ Changes++; + } else { /* Next entry */ @@ -1311,7 +1340,6 @@ static unsigned RunOptGroup3 (CodeSeg* S) C += RunOptFunc (S, &DOptCmp6, 1); C += RunOptFunc (S, &DOptCmp7, 1); C += RunOptFunc (S, &DOptCmp9, 1); - C += RunOptFunc (S, &DOptTest1, 1); C += RunOptFunc (S, &DOptLoad1, 1); C += RunOptFunc (S, &DOptJumpTarget3, 1); /* After OptCondBranches2 */ diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 630ca944c..3d4bcdcc1 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -140,6 +140,7 @@ struct SymEntry { Collection *DefsOrRefs; } L; + /* Value of SP adjustment needed after forward 'goto' */ struct { unsigned short SPAdjustment; } G; diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 8db6a741c..11314b53a 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -226,6 +226,7 @@ void EnterGlobalLevel (void) /* Create and assign the tag table */ TagTab0 = TagTab = NewSymTable (SYMTAB_SIZE_GLOBAL); + /* Create and assign the table of SP adjustment symbols */ SPAdjustTab = NewSymTable (SYMTAB_SIZE_GLOBAL); } @@ -681,16 +682,14 @@ DefOrRef* AddDefOrRef (SymEntry* E, unsigned Flags) unsigned short FindSPAdjustment (const char* Name) { +/* Search for an entry in the table of SP adjustments */ SymEntry* Entry = FindSymInTable (SPAdjustTab, Name, HashStr (Name)); - if (Entry) { - printf("L: %s sa: %d\n", Name, Entry->V.G.SPAdjustment); - return Entry->V.G.SPAdjustment; + if (!Entry) { + Internal ("No SP adjustment label entry found"); } - Fatal("ICE: No label entry found"); - - return 0; + return Entry->V.G.SPAdjustment; } SymEntry* AddLabelSym (const char* Name, unsigned Flags) @@ -748,11 +747,13 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) g_userodata(); g_defdatalabel (DOR->LateSP_Label); 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; AddSymEntry (SPAdjustTab, E); - /* Are we jumping into a block with initalization of an object that ** has automatic storage duration? Let's emit a warning. */