Merge pull request #2813 from colinleroy/fix-pr-2778

Fix bug in PR #2778
This commit is contained in:
Bob Andrews
2025-07-24 13:21:56 +02:00
committed by GitHub
4 changed files with 79 additions and 9 deletions

View File

@@ -108,6 +108,7 @@ static OptFunc DOpt65C02BitOps = { Opt65C02BitOps, "Opt65C02BitOps", 66, 0,
static OptFunc DOpt65C02Ind = { Opt65C02Ind, "Opt65C02Ind", 100, 0, 0, 0, 0, 0 };
static OptFunc DOpt65C02Stores = { Opt65C02Stores, "Opt65C02Stores", 100, 0, 0, 0, 0, 0 };
static OptFunc DOptAXLoad = { OptAXLoad, "OptAXLoad", 50, 0, 0, 0, 0, 0 };
static OptFunc DOptAXLoad2 = { OptAXLoad2, "OptAXLoad2", 66, 0, 0, 0, 0, 0 };
static OptFunc DOptAXOps = { OptAXOps, "OptAXOps", 50, 0, 0, 0, 0, 0 };
static OptFunc DOptAdd1 = { OptAdd1, "OptAdd1", 125, 0, 0, 0, 0, 0 };
static OptFunc DOptAdd2 = { OptAdd2, "OptAdd2", 200, 0, 0, 0, 0, 0 };
@@ -233,6 +234,7 @@ static OptFunc* OptFuncs[] = {
&DOpt65C02Ind,
&DOpt65C02Stores,
&DOptAXLoad,
&DOptAXLoad2,
&DOptAXOps,
&DOptAdd1,
&DOptAdd2,
@@ -877,6 +879,7 @@ static unsigned RunOptGroup7 (CodeSeg* S)
*/
Changes += RunOptFunc (S, &DOptUnusedLoads, 1);
Changes += RunOptFunc (S, &DOptAXLoad, 5);
Changes += RunOptFunc (S, &DOptAXLoad2, 5);
Changes += RunOptFunc (S, &DOptUnusedStores, 1);
Changes += RunOptFunc (S, &DOptJumpTarget1, 5);
Changes += RunOptFunc (S, &DOptStore5, 1);

View File

@@ -499,7 +499,7 @@ unsigned OptAXOps (CodeSeg* S)
unsigned OptAXLoad (CodeSeg* S)
/* Merge jsr incax/jsr ldaxi into ldy/jsr ldaxidx */
/* Merge jsr incax[1-8]/jsr ldaxi into ldy/jsr ldaxidx */
{
unsigned Changes = 0;
unsigned I;
@@ -514,9 +514,11 @@ unsigned OptAXLoad (CodeSeg* S)
/* Get the next entry */
const CodeEntry* E = CS_GetEntry (S, I);
/* Check for incax followed by jsr/jmp ldaxi */
/* Check for incax[1-8] followed by jsr/jmp ldaxi */
if (E->OPC == OP65_JSR &&
strncmp (E->Arg, "incax", 5) == 0 &&
E->Arg[5] >= '1' && E->Arg[5] <= '8' &&
E->Arg[6] == '\0' &&
(N = CS_GetNextEntry (S, I)) != 0 &&
(N->OPC == OP65_JSR || N->OPC == OP65_JMP) &&
strcmp (N->Arg, "ldaxi") == 0 &&
@@ -555,6 +557,63 @@ unsigned OptAXLoad (CodeSeg* S)
unsigned OptAXLoad2 (CodeSeg* S)
/* Merge ldy/jsr incaxy/jsr ldaxi into ldy/jsr ldaxidx */
{
unsigned Changes = 0;
unsigned I;
/* Walk over the entries */
I = 0;
while (I < CS_GetEntryCount (S)) {
signed Val;
CodeEntry* E[3];
CodeEntry* X;
/* Get the next entry */
E[0] = CS_GetEntry (S, I);
/* Check for ldy followed by incaxy followed by jsr/jmp ldaxi */
if (E[0]->OPC == OP65_LDY &&
CE_IsConstImm (E[0]) &&
CS_GetEntries (S, E+1, I+1, 2) &&
E[1]->OPC == OP65_JSR &&
strcmp (E[1]->Arg, "incaxy") == 0 &&
(E[2]->OPC == OP65_JSR || E[2]->OPC == OP65_JMP) &&
strcmp (E[2]->Arg, "ldaxi") == 0 &&
!CS_RangeHasLabel (S, I, 3)) {
/* Replace with ldy (y+1) / jsr ldaxidx */
Val = E[0]->Num + 1;
X = NewCodeEntry (OP65_LDY, AM65_IMM, MakeHexArg (Val), 0, E[0]->LI);
CS_InsertEntry (S, X, I+3);
X = NewCodeEntry (E[2]->OPC, AM65_ABS, "ldaxidx", 0, E[0]->LI);
CS_InsertEntry (S, X, I+4);
CS_DelEntries (S, I, 3);
/* Regenerate register info */
CS_GenRegInfo (S);
/* Remember we had changes */
++Changes;
} else {
/* Next entry */
++I;
}
}
/* Return the number of changes made */
return Changes;
}
unsigned OptGotoSPAdj (CodeSeg* S)
/* Optimize SP adjustment for forward 'goto' */
{

View File

@@ -102,7 +102,10 @@ unsigned OptAXOps (CodeSeg* S);
*/
unsigned OptAXLoad (CodeSeg* S);
/* Merge adjacent calls to incax/ldaxi into ldy/ldaxidx */
/* Merge jsr incax[1-8]/jsr ldaxi into ldy/jsr ldaxidx */
unsigned OptAXLoad2 (CodeSeg* S);
/* Merge ldy/jsr incaxy/jsr ldaxi into ldy/jsr ldaxidx */
unsigned OptGotoSPAdj (CodeSeg* S);
/* Optimize SP adjustment for forward 'goto' */

View File

@@ -3,18 +3,23 @@
struct Object
{
int a;
int data[10];
int data[20];
};
struct Object object_data = { 0x0102, {0x0304, 0x0506,
0x0708, 0x090A, 0x0B0C,
0x0D0E, 0x0F10, 0x1112,
0x1314, 0x1516}};
0x1314, 0x1516, 0x1718,
0x1920, 0x2122, 0x2324,
0x2526, 0x2728, 0x2930,
0x3132, 0x3334, 0x3536}};
TEST
{
struct Object *o = &object_data;
ASSERT_IsTrue(o->a == 0x0102, "Wrong value for a");
ASSERT_IsTrue(o->data[2] == 0x0708, "Wrong value for data[2]");
ASSERT_IsTrue(o->data[8] == 0x1314, "Wrong value for data[8]");
ASSERT_IsTrue(o->data[19] == 0x3536, "Wrong value for data[19]");
}
ENDTEST