diff --git a/src/cc65/coptstop.c b/src/cc65/coptstop.c index 50fd73b4e..620a73504 100644 --- a/src/cc65/coptstop.c +++ b/src/cc65/coptstop.c @@ -58,6 +58,7 @@ typedef enum { LI_DIRECT = 0x01, /* Direct op may be used */ LI_RELOAD_Y = 0x02, /* Reload index register Y */ LI_REMOVE = 0x04, /* Load may be removed */ + LI_DUP_LOAD = 0x08, /* Duplicate load */ } LI_FLAGS; /* Structure that tells us how to load the lhs values */ @@ -258,9 +259,17 @@ static void TrackLoads (LoadInfo* LI, CodeEntry* E, int I) RI = &LI->X; } else if (E->Chg & REG_Y) { RI = &LI->Y; - } + } CHECK (RI != 0); + /* If we had a load or xfer op before, this is a duplicate load which + * can cause problems if it encountered between the pushax and the op, + * so remember it. + */ + if (RI->LoadIndex >= 0 || RI->XferIndex >= 0) { + RI->Flags |= LI_DUP_LOAD; + } + /* Remember the load */ RI->LoadIndex = I; RI->XferIndex = -1; @@ -299,6 +308,14 @@ static void TrackLoads (LoadInfo* LI, CodeEntry* E, int I) default: Internal ("Unknown XFR insn in TrackLoads"); } + /* If we had a load or xfer op before, this is a duplicate load which + * can cause problems if it encountered between the pushax and the op, + * so remember it. + */ + if (Tgt->LoadIndex >= 0 || Tgt->XferIndex >= 0) { + Tgt->Flags |= LI_DUP_LOAD; + } + /* Transfer the data */ Tgt->LoadIndex = Src->LoadIndex; Tgt->XferIndex = I; @@ -308,6 +325,17 @@ static void TrackLoads (LoadInfo* LI, CodeEntry* E, int I) } else if (CE_IsCallTo (E, "ldaxysp") && RegValIsKnown (E->RI->In.RegY)) { + /* If we had a load or xfer op before, this is a duplicate load which + * can cause problems if it encountered between the pushax and the op, + * so remember it for both registers involved. + */ + if (LI->A.LoadIndex >= 0 || LI->A.XferIndex >= 0) { + LI->A.Flags |= LI_DUP_LOAD; + } + if (LI->X.LoadIndex >= 0 || LI->X.XferIndex >= 0) { + LI->X.Flags |= LI_DUP_LOAD; + } + /* Both registers set, Y changed */ LI->A.LoadIndex = I; LI->A.XferIndex = -1; @@ -1659,6 +1687,10 @@ static int PreCondOk (StackOpData* D) } } } + if ((D->Rhs.A.Flags | D->Rhs.X.Flags) & LI_DUP_LOAD) { + /* Cannot optimize */ + return 0; + } /* Determine the zero page locations to use */ if ((D->UsedRegs & REG_PTR1) == REG_NONE) {