From f3d74cd166e3d5102480c84165365719fe6b842e Mon Sep 17 00:00:00 2001
From: Oliver Schmidt
Date: Wed, 9 Oct 2013 21:55:44 +0200
Subject: [PATCH] Added optimizer fix originating from Ullrich von Bassewitz
prepared by Greg King.
---
src/cc65/coptstop.c | 41 ++++++++++++++++++++++++-----------------
1 file changed, 24 insertions(+), 17 deletions(-)
diff --git a/src/cc65/coptstop.c b/src/cc65/coptstop.c
index 4d3fe76e6..dfa14d3f8 100644
--- a/src/cc65/coptstop.c
+++ b/src/cc65/coptstop.c
@@ -6,10 +6,10 @@
/* */
/* */
/* */
-/* (C) 2001-2009 Ullrich von Bassewitz */
-/* Roemerstrasse 52 */
-/* D-70794 Filderstadt */
-/* EMail: uz@cc65.org */
+/* (C) 2001-2013, Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
@@ -58,7 +58,8 @@ 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_DONT_REMOVE = 0x08, /* Load may not be removed */
+ LI_DUP_LOAD = 0x10, /* Duplicate load */
} LI_FLAGS;
/* Structure that tells us how to load the lhs values */
@@ -245,6 +246,18 @@ static void AdjustLoadInfo (LoadInfo* LI, int Index, int Change)
+static void HonourUseAndChg (LoadRegInfo* RI, unsigned Reg, const CodeEntry* E)
+/* Honour use and change flags for an instruction */
+{
+ if (E->Chg & Reg) {
+ ClearLoadRegInfo (RI);
+ } else if ((E->Use & Reg) && RI->LoadIndex >= 0) {
+ RI->Flags |= LI_DONT_REMOVE;
+ }
+}
+
+
+
static void TrackLoads (LoadInfo* LI, CodeEntry* E, int I)
/* Track loads for a code entry */
{
@@ -349,15 +362,9 @@ static void TrackLoads (LoadInfo* LI, CodeEntry* E, int I)
ClearLoadRegInfo (&LI->Y);
} else {
- if (E->Chg & REG_A) {
- ClearLoadRegInfo (&LI->A);
- }
- if (E->Chg & REG_X) {
- ClearLoadRegInfo (&LI->X);
- }
- if (E->Chg & REG_Y) {
- ClearLoadRegInfo (&LI->Y);
- }
+ HonourUseAndChg (&LI->A, REG_A, E);
+ HonourUseAndChg (&LI->X, REG_X, E);
+ HonourUseAndChg (&LI->Y, REG_Y, E);
}
}
@@ -646,7 +653,7 @@ static void RemoveRegLoads (StackOpData* D, LoadInfo* LI)
/* Both registers may be loaded with one insn, but DelEntry will in this
* case clear the other one.
*/
- if (LI->A.Flags & LI_REMOVE) {
+ if ((LI->A.Flags & (LI_REMOVE | LI_DONT_REMOVE)) == LI_REMOVE) {
if (LI->A.LoadIndex >= 0) {
DelEntry (D, LI->A.LoadIndex);
}
@@ -654,7 +661,7 @@ static void RemoveRegLoads (StackOpData* D, LoadInfo* LI)
DelEntry (D, LI->A.XferIndex);
}
}
- if (LI->X.Flags & LI_REMOVE) {
+ if ((LI->X.Flags & (LI_REMOVE | LI_DONT_REMOVE)) == LI_REMOVE) {
if (LI->X.LoadIndex >= 0) {
DelEntry (D, LI->X.LoadIndex);
}
@@ -875,7 +882,7 @@ static unsigned Opt_tosshift (StackOpData* D, const char* Name)
AddStoreA (D);
/* Be sure to setup IP after adding the stores, otherwise it will get
- * messed up.
+ * messed up.
*/
D->IP = D->OpIndex+1;