Merge pull request #2812 from colinleroy/Opt-ldptr1

Optimize ldax?sp/sta/stx to ldptr1?sp
This commit is contained in:
Bob Andrews
2025-07-27 00:22:21 +02:00
committed by GitHub
5 changed files with 110 additions and 10 deletions

20
libsrc/runtime/ldptr1sp.s Normal file
View File

@@ -0,0 +1,20 @@
;
; Colin Leroy-Mira, 2025-07-26
;
; 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

View File

@@ -190,6 +190,8 @@ static const FuncInfo FuncInfoTable[] = {
{ "ldeaxi", REG_AX, PSTATE_ALL | REG_EAXY | REG_PTR1 }, { "ldeaxi", REG_AX, PSTATE_ALL | REG_EAXY | REG_PTR1 },
{ "ldeaxidx", REG_AXY, PSTATE_ALL | REG_EAXY | REG_PTR1 }, { "ldeaxidx", REG_AXY, PSTATE_ALL | REG_EAXY | REG_PTR1 },
{ "ldeaxysp", SLV_IND | REG_Y, PSTATE_ALL | REG_EAXY }, { "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 }, { "leaa0sp", REG_SP | REG_A, PSTATE_ALL | REG_AX },
{ "leaaxsp", REG_SP | REG_AX, PSTATE_ALL | REG_AX }, { "leaaxsp", REG_SP | REG_AX, PSTATE_ALL | REG_AX },
{ "leave", REG_SP, PSTATE_ALL | REG_SP | REG_Y }, { "leave", REG_SP, PSTATE_ALL | REG_SP | REG_Y },

View File

@@ -178,6 +178,7 @@ static OptFunc DOptPtrLoad17 = { OptPtrLoad17, "OptPtrLoad17", 190, 0,
static OptFunc DOptPtrLoad18 = { OptPtrLoad18, "OptPtrLoad18", 100, 0, 0, 0, 0, 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 DOptPtrLoad19 = { OptPtrLoad19, "OptPtrLoad19", 65, 0, 0, 0, 0, 0 };
static OptFunc DOptPtrLoad2 = { OptPtrLoad2, "OptPtrLoad2", 100, 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 DOptPtrLoad3 = { OptPtrLoad3, "OptPtrLoad3", 100, 0, 0, 0, 0, 0 };
static OptFunc DOptPtrLoad4 = { OptPtrLoad4, "OptPtrLoad4", 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 }; static OptFunc DOptPtrLoad5 = { OptPtrLoad5, "OptPtrLoad5", 50, 0, 0, 0, 0, 0 };
@@ -306,6 +307,7 @@ static OptFunc* OptFuncs[] = {
&DOptPtrLoad18, &DOptPtrLoad18,
&DOptPtrLoad19, &DOptPtrLoad19,
&DOptPtrLoad2, &DOptPtrLoad2,
&DOptPtrLoad20,
&DOptPtrLoad3, &DOptPtrLoad3,
&DOptPtrLoad4, &DOptPtrLoad4,
&DOptPtrLoad5, &DOptPtrLoad5,
@@ -904,6 +906,8 @@ static unsigned RunOptGroup7 (CodeSeg* S)
Changes += RunOptFunc (S, &DOptTransfers3, 1); Changes += RunOptFunc (S, &DOptTransfers3, 1);
} }
Changes += RunOptFunc (S, &DOptPtrLoad20, 1);
/* Adjust branch distances */ /* Adjust branch distances */
Changes += RunOptFunc (S, &DOptBranchDist, 3); Changes += RunOptFunc (S, &DOptBranchDist, 3);

View File

@@ -1529,8 +1529,8 @@ unsigned OptPtrLoad18 (CodeSeg* S)
X = NewCodeEntry (OP65_LDX, AM65_IMM, "$00", 0, L[0]->LI); X = NewCodeEntry (OP65_LDX, AM65_IMM, "$00", 0, L[0]->LI);
CS_InsertEntry (S, X, I+9); CS_InsertEntry (S, X, I+9);
Label = xmalloc(6); Label = xmalloc (6);
sprintf(Label, "$%s%s", L[0]->Arg+1, L[1]->Arg+1); sprintf (Label, "$%s%s", L[0]->Arg+1, L[1]->Arg+1);
X = NewCodeEntry (OP65_LDA, AM65_ABSY, Label, 0, L[0]->LI); X = NewCodeEntry (OP65_LDA, AM65_ABSY, Label, 0, L[0]->LI);
CS_InsertEntry (S, X, I+10); CS_InsertEntry (S, X, I+10);
xfree (Label); xfree (Label);
@@ -1593,7 +1593,7 @@ unsigned OptPtrLoad19 (CodeSeg* S)
/* Check for the sequence */ /* Check for the sequence */
if (L[0]->OPC == OP65_LDX && if (L[0]->OPC == OP65_LDX &&
CE_IsKnownImm(L[0], 0) && CE_IsKnownImm (L[0], 0) &&
CS_GetEntries (S, L+1, I+1, 11) && CS_GetEntries (S, L+1, I+1, 11) &&
L[1]->OPC == OP65_AND && L[1]->OPC == OP65_AND &&
L[1]->AM == AM65_IMM && L[1]->AM == AM65_IMM &&
@@ -1607,12 +1607,12 @@ unsigned OptPtrLoad19 (CodeSeg* S)
L[8]->OPC == OP65_TAX && L[8]->OPC == OP65_TAX &&
L[9]->OPC == OP65_TYA && L[9]->OPC == OP65_TYA &&
L[10]->OPC == OP65_LDY && L[10]->OPC == OP65_LDY &&
CE_IsKnownImm(L[10], 1) && CE_IsKnownImm (L[10], 1) &&
L[4]->Arg[0] == '<' && L[4]->Arg[0] == '<' &&
L[7]->Arg[0] == '>' && L[7]->Arg[0] == '>' &&
strlen(L[4]->Arg) > 3 && strlen (L[4]->Arg) > 3 &&
strlen(L[7]->Arg) > 3 && strlen (L[7]->Arg) > 3 &&
strcmp(L[4]->Arg+1, L[7]->Arg+1) == 0 && strcmp (L[4]->Arg+1, L[7]->Arg+1) == 0 &&
(strcmp (L[2]->Arg, "aslax1") == 0 || (strcmp (L[2]->Arg, "aslax1") == 0 ||
strcmp (L[2]->Arg, "shlax1") == 0) && strcmp (L[2]->Arg, "shlax1") == 0) &&
CE_IsCallTo (L[11], "ldaxidx") && CE_IsCallTo (L[11], "ldaxidx") &&
@@ -1620,7 +1620,7 @@ unsigned OptPtrLoad19 (CodeSeg* S)
CodeEntry* X; CodeEntry* X;
char* Label; char* Label;
int Len = strlen(L[4]->Arg); int Len = strlen (L[4]->Arg);
/* Track the insertion point */ /* Track the insertion point */
unsigned IP = I + 12; unsigned IP = I + 12;
@@ -1641,7 +1641,7 @@ unsigned OptPtrLoad19 (CodeSeg* S)
CS_InsertEntry (S, X, IP++); CS_InsertEntry (S, X, IP++);
/* ldx label+1,y */ /* 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); X = NewCodeEntry (OP65_LDX, AM65_ABSY, Label, 0, L[10]->LI);
CS_InsertEntry (S, X, IP++); CS_InsertEntry (S, X, IP++);
/* free Label memory */ /* free Label memory */
@@ -1656,7 +1656,7 @@ unsigned OptPtrLoad19 (CodeSeg* S)
} }
/* Remove the ldx #0 */ /* Remove the ldx #0 */
CS_DelEntry(S, I); CS_DelEntry (S, I);
/* Remember, we had changes */ /* Remember, we had changes */
++Changes; ++Changes;
@@ -1671,3 +1671,64 @@ unsigned OptPtrLoad19 (CodeSeg* S)
/* Return the number of changes made */ /* Return the number of changes made */
return Changes; 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 ((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) {
CE_SetArg (E[0], "ldptr1ysp");
} else {
CE_SetArg (E[0], "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;
}

View File

@@ -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 */ /* End of coptptrload.h */
#endif #endif