From f45d2515eb9191f21bc21c8449e407ebfb3ee415 Mon Sep 17 00:00:00 2001 From: acqn Date: Mon, 31 Aug 2020 01:56:57 +0800 Subject: [PATCH] Fixed OptPush1 in case later code would rely on that pushax zeroes register Y. --- src/cc65/coptpush.c | 19 +++++++++++++++++-- src/cc65/coptpush.h | 6 +++--- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/cc65/coptpush.c b/src/cc65/coptpush.c index 5c3daffca..34d794c64 100644 --- a/src/cc65/coptpush.c +++ b/src/cc65/coptpush.c @@ -56,12 +56,14 @@ unsigned OptPush1 (CodeSeg* S) ** ** ldy #xx+2 ** jsr pushwysp +** ldy #$00 ; present if later code expects Y = 0 ** -** saving 3 bytes and several cycles. +** saving several cycles. */ { unsigned I; unsigned Changes = 0; + unsigned R; /* Walk over the entries */ I = 0; @@ -79,7 +81,7 @@ unsigned OptPush1 (CodeSeg* S) (L[1] = CS_GetNextEntry (S, I)) != 0 && !CE_HasLabel (L[1]) && CE_IsCallTo (L[1], "pushax") && - !RegAXUsed (S, I+2)) { + ((R = (GetRegInfo (S, I+2, REG_AXY))) & REG_AX) == 0) { /* Insert new code behind the pushax */ const char* Arg; @@ -94,12 +96,25 @@ unsigned OptPush1 (CodeSeg* S) X = NewCodeEntry (OP65_JSR, AM65_ABS, "pushwysp", 0, L[1]->LI); CS_InsertEntry (S, X, I+3); + /* pushax sets Y = 0 and following code might rely on this */ + if ((R & REG_Y) != 0) { + /* ldy #0 */ + X = NewCodeEntry (OP65_LDY, AM65_IMM, MakeHexArg (0), 0, L[1]->LI); + CS_InsertEntry (S, X, I+4); + } + /* Delete the old code */ CS_DelEntries (S, I, 2); /* Remember, we had changes */ ++Changes; + /* Skip the handled lines */ + if ((R & REG_Y) == 0) { + ++I; + } else { + I += 2; + } } /* Next entry */ diff --git a/src/cc65/coptpush.h b/src/cc65/coptpush.h index 0d637e824..aa5548517 100644 --- a/src/cc65/coptpush.h +++ b/src/cc65/coptpush.h @@ -52,16 +52,16 @@ unsigned OptPush1 (CodeSeg* S); /* Given a sequence ** -** ldy #xx ** jsr ldaxysp ** jsr pushax ** -** If a/x are not used later, replace that by +** If a/x are not used later, and Y is known, replace that by ** ** ldy #xx+2 ** jsr pushwysp +** ldy #$00 ; present if later code expects Y = 0 ** -** saving 3 bytes and several cycles. +** saving several cycles. */ unsigned OptPush2 (CodeSeg* S);