From 4716083f3f2ac66db2d1457daae252000adf7c60 Mon Sep 17 00:00:00 2001 From: Greg King Date: Sun, 13 Dec 2015 07:17:41 -0500 Subject: [PATCH] Fixed a signed char shift optimization so that it won't be used on signed int also. (It would lose significant bits from the high byte.) --- src/cc65/coptshift.c | 54 +++++++++++++++++++++++++++----------------- src/cc65/coptshift.h | 13 ++++++++--- 2 files changed, 43 insertions(+), 24 deletions(-) diff --git a/src/cc65/coptshift.c b/src/cc65/coptshift.c index a4b993073..2f8c2f833 100644 --- a/src/cc65/coptshift.c +++ b/src/cc65/coptshift.c @@ -307,51 +307,63 @@ NextEntry: -unsigned OptShift2(CodeSeg* S) -/* A call to the asrax1 routines may get replaced by something simpler, if -** X is not used later: +unsigned OptShift2 (CodeSeg* S) +/* The sequence +** +** bpl L +** dex +** L: jsr asraxN +** +** might be replaced by N copies of ** ** cmp #$80 ** ror a +** +** if X is not used later (X is assumed to be zero on entry). */ { unsigned Changes = 0; - unsigned I; + unsigned I = 0; /* Walk over the entries */ - I = 0; while (I < CS_GetEntryCount (S)) { unsigned Shift; unsigned Count; + CodeEntry* L[3]; /* Get next entry */ - CodeEntry* E = CS_GetEntry (S, I); + L[0] = CS_GetEntry (S, I); /* Check for the sequence */ - if (E->OPC == OP65_JSR && - (Shift = GetShift (E->Arg)) != SHIFT_NONE && - SHIFT_TYPE (Shift) == SHIFT_TYPE_ASR && - (Count = SHIFT_COUNT (Shift)) > 0 && - Count * 100 <= S->CodeSizeFactor && - !RegXUsed (S, I+1)) { + if (L[0]->OPC == OP65_BPL && + L[0]->JumpTo != 0 && + CS_GetEntries (S, L+1, I+1, 2) && + L[1]->OPC == OP65_DEX && + L[0]->JumpTo->Owner == L[2] && + !CS_RangeHasLabel (S, I, 2) && + L[2]->OPC == OP65_JSR && + SHIFT_TYPE (Shift = GetShift (L[2]->Arg)) == SHIFT_TYPE_ASR && + (Count = SHIFT_COUNT (Shift)) > 0 && + Count * 100 <= S->CodeSizeFactor && + !RegXUsed (S, I+3)) { CodeEntry* X; - unsigned J = I+1; + unsigned J = I+2; /* Generate the replacement sequence */ while (Count--) { /* cmp #$80 */ - X = NewCodeEntry (OP65_CMP, AM65_IMM, "$80", 0, E->LI); - CS_InsertEntry (S, X, J++); + X = NewCodeEntry (OP65_CMP, AM65_IMM, "$80", 0, L[2]->LI); + CS_InsertEntry (S, X, ++J); /* ror a */ - X = NewCodeEntry (OP65_ROR, AM65_ACC, "a", 0, E->LI); - CS_InsertEntry (S, X, J++); + X = NewCodeEntry (OP65_ROR, AM65_ACC, "a", 0, L[2]->LI); + CS_InsertEntry (S, X, ++J); } - /* Delete the call to asrax */ - CS_DelEntry (S, I); + /* Remove the bpl/dex/jsr */ + CS_DelEntries (S, I, 3); /* Remember, we had changes */ ++Changes; @@ -412,7 +424,7 @@ unsigned OptShift3 (CodeSeg* S) (Shift = GetShift (L[2]->Arg)) != SHIFT_NONE && SHIFT_DIR (Shift) == SHIFT_DIR_RIGHT && (Count = SHIFT_COUNT (Shift)) > 0) { - + /* Add the replacement insn instead */ CodeEntry* X = NewCodeEntry (OP65_ROR, AM65_ACC, "a", 0, L[2]->LI); CS_InsertEntry (S, X, I+3); @@ -421,7 +433,7 @@ unsigned OptShift3 (CodeSeg* S) CS_InsertEntry (S, X, I+4); } - /* Remove the bcs/dex/jsr */ + /* Remove the bcc/inx/jsr */ CS_DelEntries (S, I, 3); /* Remember, we had changes */ diff --git a/src/cc65/coptshift.h b/src/cc65/coptshift.h index 0410652a1..e7f9cc359 100644 --- a/src/cc65/coptshift.h +++ b/src/cc65/coptshift.h @@ -60,12 +60,19 @@ unsigned OptShift1 (CodeSeg* S); ** L1: */ -unsigned OptShift2(CodeSeg* S); -/* A call to the asrax1 routines may get replaced by something simpler, if -** X is not used later: +unsigned OptShift2 (CodeSeg* S); +/* The sequence +** +** bpl L +** dex +** L: jsr asraxN +** +** might be replaced by N copies of ** ** cmp #$80 ** ror a +** +** if X is not used later (X is assumed to be zero on entry). */ unsigned OptShift3 (CodeSeg* S);