Merge pull request #2813 from colinleroy/fix-pr-2778
Fix bug in PR #2778
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -434,7 +434,7 @@ static unsigned OptIncDecOps (CodeSeg* S, const char* dec, const char* inc, cons
|
||||
(N = CS_GetNextEntry (S, I)) != 0 &&
|
||||
(N->OPC == OP65_JSR || N->OPC == OP65_JMP) &&
|
||||
(Val2 = IsShift (N, dec, inc, sub, add)) != 0 &&
|
||||
abs(Val1 += Val2) <= 255 &&
|
||||
abs (Val1 += Val2) <= 255 &&
|
||||
!CE_HasLabel (N)) {
|
||||
|
||||
CodeEntry* X;
|
||||
@@ -442,14 +442,14 @@ static unsigned OptIncDecOps (CodeSeg* S, const char* dec, const char* inc, cons
|
||||
|
||||
if (Val1 != 0) {
|
||||
/* We can combine the two */
|
||||
if (abs(Val1) <= 8) {
|
||||
if (abs (Val1) <= 8) {
|
||||
/* Insert a call to inc/dec using the last OPC */
|
||||
xsprintf (Buf, sizeof (Buf), "%s%u", Val1 < 0 ? dec:inc, abs(Val1));
|
||||
xsprintf (Buf, sizeof (Buf), "%s%u", Val1 < 0 ? dec:inc, abs (Val1));
|
||||
X = NewCodeEntry (N->OPC, AM65_ABS, Buf, 0, N->LI);
|
||||
CS_InsertEntry (S, X, I+2);
|
||||
} else {
|
||||
/* Insert a call to add/sub */
|
||||
const char* Arg = MakeHexArg (abs(Val1));
|
||||
const char* Arg = MakeHexArg (abs (Val1));
|
||||
X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, N->LI);
|
||||
CS_InsertEntry (S, X, I+2);
|
||||
if (Val1 < 0) {
|
||||
@@ -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' */
|
||||
{
|
||||
|
||||
@@ -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' */
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user