From 17b86453606315afd5539a30be1ab8430ea3ed41 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Sun, 20 Jul 2025 12:24:24 +0200 Subject: [PATCH 1/3] Optimize ldax?sp/sta/stx to ldptr1?sp --- libsrc/runtime/ldptr1sp.s | 20 ++++++++++++ src/cc65/codeinfo.c | 2 ++ src/cc65/codeopt.c | 4 +++ src/cc65/coptptrload.c | 64 +++++++++++++++++++++++++++++++++++++++ src/cc65/coptptrload.h | 13 ++++++++ 5 files changed, 103 insertions(+) create mode 100644 libsrc/runtime/ldptr1sp.s diff --git a/libsrc/runtime/ldptr1sp.s b/libsrc/runtime/ldptr1sp.s new file mode 100644 index 000000000..549568923 --- /dev/null +++ b/libsrc/runtime/ldptr1sp.s @@ -0,0 +1,20 @@ +; +; Ullrich von Bassewitz, 31.08.1998 +; +; CC65 runtime: Load ptr1 from offset in stack +; + + .export ldptr10sp, ldptr1ysp + .importzp c_sp, ptr1 + +; Beware: The optimizer knows about the value in Y after return! + +ldptr10sp: + ldy #1 +ldptr1ysp: + lda (c_sp),y ; get high byte + sta ptr1+1 ; and save it + dey ; point to lo byte + lda (c_sp),y ; load low byte + sta ptr1 + rts diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index 25712d546..ba4350da6 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -190,6 +190,8 @@ static const FuncInfo FuncInfoTable[] = { { "ldeaxi", REG_AX, PSTATE_ALL | REG_EAXY | REG_PTR1 }, { "ldeaxidx", REG_AXY, PSTATE_ALL | REG_EAXY | REG_PTR1 }, { "ldeaxysp", SLV_IND | REG_Y, PSTATE_ALL | REG_EAXY }, + { "ldptr10sp", SLV_TOP, PSTATE_ALL | REG_AY | REG_PTR1 }, + { "ldptr1ysp", REG_Y | SLV_TOP, PSTATE_ALL | REG_AY | REG_PTR1 }, { "leaa0sp", REG_SP | REG_A, PSTATE_ALL | REG_AX }, { "leaaxsp", REG_SP | REG_AX, PSTATE_ALL | REG_AX }, { "leave", REG_SP, PSTATE_ALL | REG_SP | REG_Y }, diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index eccceccb3..6559ed1e7 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -177,6 +177,7 @@ static OptFunc DOptPtrLoad17 = { OptPtrLoad17, "OptPtrLoad17", 190, 0, static OptFunc DOptPtrLoad18 = { OptPtrLoad18, "OptPtrLoad18", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptPtrLoad19 = { OptPtrLoad19, "OptPtrLoad19", 65, 0, 0, 0, 0, 0 }; static OptFunc DOptPtrLoad2 = { OptPtrLoad2, "OptPtrLoad2", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptPtrLoad20 = { OptPtrLoad20, "OptPtrLoad20", 90, 0, 0, 0, 0, 0 }; static OptFunc DOptPtrLoad3 = { OptPtrLoad3, "OptPtrLoad3", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptPtrLoad4 = { OptPtrLoad4, "OptPtrLoad4", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptPtrLoad5 = { OptPtrLoad5, "OptPtrLoad5", 50, 0, 0, 0, 0, 0 }; @@ -301,6 +302,7 @@ static OptFunc* OptFuncs[] = { &DOptPtrLoad18, &DOptPtrLoad19, &DOptPtrLoad2, + &DOptPtrLoad20, &DOptPtrLoad3, &DOptPtrLoad4, &DOptPtrLoad5, @@ -895,6 +897,8 @@ static unsigned RunOptGroup7 (CodeSeg* S) Changes += RunOptFunc (S, &DOptTransfers3, 1); } + Changes += RunOptFunc (S, &DOptPtrLoad20, 1); + /* Adjust branch distances */ Changes += RunOptFunc (S, &DOptBranchDist, 3); diff --git a/src/cc65/coptptrload.c b/src/cc65/coptptrload.c index e28bf5d39..87b9191e2 100644 --- a/src/cc65/coptptrload.c +++ b/src/cc65/coptptrload.c @@ -1671,3 +1671,67 @@ unsigned OptPtrLoad19 (CodeSeg* S) /* Return the number of changes made */ return Changes; } + + + +unsigned OptPtrLoad20 (CodeSeg* S) +/* Search for the sequence: +** +** jsr ldax?sp +** sta ptr1 +** stx ptr1+1 +** +** and replace it by: +** +** jsr ldptr1?sp +*/ +{ + unsigned Changes = 0; + unsigned I; + + /* Walk over the entries */ + I = 0; + while (I < CS_GetEntryCount (S)) { + + CodeEntry* E[3]; + + /* Get the next entry */ + E[0] = CS_GetEntry (S, I); + + if (E[0]->OPC == OP65_JSR && + (strcmp (E[0]->Arg, "ldax0sp") == 0 || + strcmp (E[0]->Arg, "ldaxysp") == 0) && + CS_GetEntries (S, E+1, I+1, 2) != 0 && + E[1]->OPC == OP65_STA && + strcmp(E[1]->Arg, "ptr1") == 0 && + E[2]->OPC == OP65_STX && + strcmp(E[2]->Arg, "ptr1+1") == 0 && + !CS_RangeHasLabel (S, I+1, 2)) { + + if (strcmp (E[0]->Arg, "ldaxysp") == 0) { + xfree(E[0]->Arg); + E[0]->Arg = xstrdup("ldptr1ysp"); + } else { + xfree(E[0]->Arg); + E[0]->Arg = xstrdup("ldptr10sp"); + } + /* Delete the sta/stx */ + CS_DelEntries (S, I+1, 2); + + /* Regenerate register info */ + CS_GenRegInfo (S); + + /* Remember we had changes */ + ++Changes; + + } else { + + /* Next entry */ + ++I; + } + + } + + /* Return the number of changes made */ + return Changes; +} diff --git a/src/cc65/coptptrload.h b/src/cc65/coptptrload.h index 259d1587b..fed04fdea 100644 --- a/src/cc65/coptptrload.h +++ b/src/cc65/coptptrload.h @@ -405,6 +405,19 @@ unsigned OptPtrLoad19 (CodeSeg* S); */ +unsigned OptPtrLoad20 (CodeSeg* S); +/* Search for the sequence: +** +** jsr ldax?sp +** sta ptr1 +** stx ptr1+1 +** +** and replace it by: +** +** jsr ldptr1?sp +*/ + + /* End of coptptrload.h */ #endif From 8a793796d72fcffe7af86d0937f557600822c655 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Sun, 20 Jul 2025 16:14:35 +0200 Subject: [PATCH 2/3] Coding style --- src/cc65/coptptrload.c | 41 +++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/src/cc65/coptptrload.c b/src/cc65/coptptrload.c index 87b9191e2..e680a1d5a 100644 --- a/src/cc65/coptptrload.c +++ b/src/cc65/coptptrload.c @@ -1529,8 +1529,8 @@ unsigned OptPtrLoad18 (CodeSeg* S) X = NewCodeEntry (OP65_LDX, AM65_IMM, "$00", 0, L[0]->LI); CS_InsertEntry (S, X, I+9); - Label = xmalloc(6); - sprintf(Label, "$%s%s", L[0]->Arg+1, L[1]->Arg+1); + Label = xmalloc (6); + sprintf (Label, "$%s%s", L[0]->Arg+1, L[1]->Arg+1); X = NewCodeEntry (OP65_LDA, AM65_ABSY, Label, 0, L[0]->LI); CS_InsertEntry (S, X, I+10); xfree (Label); @@ -1593,7 +1593,7 @@ unsigned OptPtrLoad19 (CodeSeg* S) /* Check for the sequence */ if (L[0]->OPC == OP65_LDX && - CE_IsKnownImm(L[0], 0) && + CE_IsKnownImm (L[0], 0) && CS_GetEntries (S, L+1, I+1, 11) && L[1]->OPC == OP65_AND && L[1]->AM == AM65_IMM && @@ -1607,12 +1607,12 @@ unsigned OptPtrLoad19 (CodeSeg* S) L[8]->OPC == OP65_TAX && L[9]->OPC == OP65_TYA && L[10]->OPC == OP65_LDY && - CE_IsKnownImm(L[10], 1) && + CE_IsKnownImm (L[10], 1) && L[4]->Arg[0] == '<' && L[7]->Arg[0] == '>' && - strlen(L[4]->Arg) > 3 && - strlen(L[7]->Arg) > 3 && - strcmp(L[4]->Arg+1, L[7]->Arg+1) == 0 && + strlen (L[4]->Arg) > 3 && + strlen (L[7]->Arg) > 3 && + strcmp (L[4]->Arg+1, L[7]->Arg+1) == 0 && (strcmp (L[2]->Arg, "aslax1") == 0 || strcmp (L[2]->Arg, "shlax1") == 0) && CE_IsCallTo (L[11], "ldaxidx") && @@ -1620,7 +1620,7 @@ unsigned OptPtrLoad19 (CodeSeg* S) CodeEntry* X; char* Label; - int Len = strlen(L[4]->Arg); + int Len = strlen (L[4]->Arg); /* Track the insertion point */ unsigned IP = I + 12; @@ -1641,7 +1641,7 @@ unsigned OptPtrLoad19 (CodeSeg* S) CS_InsertEntry (S, X, IP++); /* ldx label+1,y */ - strcpy(&Label[Len-3], "+1"); + strcpy (&Label[Len-3], "+1"); X = NewCodeEntry (OP65_LDX, AM65_ABSY, Label, 0, L[10]->LI); CS_InsertEntry (S, X, IP++); /* free Label memory */ @@ -1656,7 +1656,7 @@ unsigned OptPtrLoad19 (CodeSeg* S) } /* Remove the ldx #0 */ - CS_DelEntry(S, I); + CS_DelEntry (S, I); /* Remember, we had changes */ ++Changes; @@ -1698,22 +1698,19 @@ unsigned OptPtrLoad20 (CodeSeg* S) /* Get the next entry */ E[0] = CS_GetEntry (S, I); - if (E[0]->OPC == OP65_JSR && - (strcmp (E[0]->Arg, "ldax0sp") == 0 || - strcmp (E[0]->Arg, "ldaxysp") == 0) && - CS_GetEntries (S, E+1, I+1, 2) != 0 && - E[1]->OPC == OP65_STA && - strcmp(E[1]->Arg, "ptr1") == 0 && - E[2]->OPC == OP65_STX && - strcmp(E[2]->Arg, "ptr1+1") == 0 && + if ((CE_IsCallTo(E[0], "ldax0sp") || + CE_IsCallTo(E[0], "ldaxysp")) && + CS_GetEntries (S, E+1, I+1, 2) != 0 && + E[1]->OPC == OP65_STA && + strcmp (E[1]->Arg, "ptr1") == 0 && + E[2]->OPC == OP65_STX && + strcmp (E[2]->Arg, "ptr1+1") == 0 && !CS_RangeHasLabel (S, I+1, 2)) { if (strcmp (E[0]->Arg, "ldaxysp") == 0) { - xfree(E[0]->Arg); - E[0]->Arg = xstrdup("ldptr1ysp"); + CE_SetArg (E[0], "ldptr1ysp"); } else { - xfree(E[0]->Arg); - E[0]->Arg = xstrdup("ldptr10sp"); + CE_SetArg (E[0], "ldptr10sp"); } /* Delete the sta/stx */ CS_DelEntries (S, I+1, 2); From aa936b6d12ac2e6e78ee24783ded74a0e35a21bc Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Sat, 26 Jul 2025 23:59:02 +0200 Subject: [PATCH 3/3] Fix copyright --- libsrc/runtime/ldptr1sp.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/runtime/ldptr1sp.s b/libsrc/runtime/ldptr1sp.s index 549568923..998190246 100644 --- a/libsrc/runtime/ldptr1sp.s +++ b/libsrc/runtime/ldptr1sp.s @@ -1,5 +1,5 @@ ; -; Ullrich von Bassewitz, 31.08.1998 +; Colin Leroy-Mira, 2025-07-26 ; ; CC65 runtime: Load ptr1 from offset in stack ;