mirror of
https://github.com/cc65/cc65.git
synced 2025-01-14 16:33:00 +00:00
More shift optimizations.
git-svn-id: svn://svn.cc65.org/cc65/trunk@5770 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
ae42e3b491
commit
49905d74bd
@ -1086,6 +1086,7 @@ static unsigned RunOptGroup3 (CodeSeg* S)
|
||||
C += RunOptFunc (S, &DOptNegAX1, 1);
|
||||
C += RunOptFunc (S, &DOptNegAX2, 1);
|
||||
C += RunOptFunc (S, &DOptStackOps, 3);
|
||||
C += RunOptFunc (S, &DOptShift1, 1);
|
||||
C += RunOptFunc (S, &DOptShift4, 1);
|
||||
C += RunOptFunc (S, &DOptSub1, 1);
|
||||
C += RunOptFunc (S, &DOptSub2, 1);
|
||||
|
@ -128,10 +128,10 @@ enum {
|
||||
|
||||
|
||||
/* Macros to extract values from a shift type */
|
||||
#define SHIFT_COUNT(S) ((S) & SHIFT_MASK_COUNT)
|
||||
#define SHIFT_DIR(S) ((S) & SHIFT_MASK_DIR)
|
||||
#define SHIFT_MODE(S) ((S) & SHIFT_MASK_MODE)
|
||||
#define SHIFT_TYPE(S) ((S) & SHIFT_MASK_TYPE)
|
||||
#define SHIFT_COUNT(S) ((S) & SHIFT_MASK_COUNT)
|
||||
#define SHIFT_DIR(S) ((S) & SHIFT_MASK_DIR)
|
||||
#define SHIFT_MODE(S) ((S) & SHIFT_MASK_MODE)
|
||||
#define SHIFT_TYPE(S) ((S) & SHIFT_MASK_TYPE)
|
||||
|
||||
|
||||
|
||||
@ -208,7 +208,6 @@ unsigned OptShift1 (CodeSeg* S)
|
||||
while (I < CS_GetEntryCount (S)) {
|
||||
|
||||
unsigned Shift;
|
||||
unsigned Count;
|
||||
CodeEntry* N;
|
||||
CodeEntry* X;
|
||||
CodeLabel* L;
|
||||
@ -219,23 +218,53 @@ unsigned OptShift1 (CodeSeg* S)
|
||||
/* Check for the sequence */
|
||||
if (E->OPC == OP65_JSR &&
|
||||
(Shift = GetShift (E->Arg)) != SHIFT_NONE &&
|
||||
SHIFT_DIR (Shift) == SHIFT_DIR_LEFT &&
|
||||
(Count = SHIFT_COUNT (Shift)) > 0) {
|
||||
SHIFT_DIR (Shift) == SHIFT_DIR_LEFT) {
|
||||
|
||||
|
||||
unsigned Count = SHIFT_COUNT (Shift);
|
||||
if (!RegXUsed (S, I+1)) {
|
||||
|
||||
/* Insert shift insns */
|
||||
while (Count--) {
|
||||
if (Count == SHIFT_COUNT_Y) {
|
||||
|
||||
CodeLabel* L;
|
||||
|
||||
if (S->CodeSizeFactor < 200) {
|
||||
goto NextEntry;
|
||||
}
|
||||
|
||||
/* Change into
|
||||
*
|
||||
* L1: asl a
|
||||
* dey
|
||||
* bpl L1
|
||||
* ror a
|
||||
*/
|
||||
|
||||
/* asl a */
|
||||
X = NewCodeEntry (OP65_ASL, AM65_ACC, "a", 0, E->LI);
|
||||
CS_InsertEntry (S, X, I+1);
|
||||
L = CS_GenLabel (S, X);
|
||||
|
||||
/* dey */
|
||||
X = NewCodeEntry (OP65_DEY, AM65_IMP, 0, 0, E->LI);
|
||||
CS_InsertEntry (S, X, I+2);
|
||||
|
||||
/* bpl L1 */
|
||||
X = NewCodeEntry (OP65_BPL, AM65_BRA, L->Name, L, E->LI);
|
||||
CS_InsertEntry (S, X, I+3);
|
||||
|
||||
/* ror a */
|
||||
X = NewCodeEntry (OP65_ROR, AM65_ACC, "a", 0, E->LI);
|
||||
CS_InsertEntry (S, X, I+4);
|
||||
|
||||
} else {
|
||||
/* Insert shift insns */
|
||||
while (Count--) {
|
||||
X = NewCodeEntry (OP65_ASL, AM65_ACC, "a", 0, E->LI);
|
||||
CS_InsertEntry (S, X, I+1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Delete the call to shlax */
|
||||
CS_DelEntry (S, I);
|
||||
|
||||
/* Remember, we had changes */
|
||||
++Changes;
|
||||
|
||||
} else if (E->RI->In.RegX == 0 &&
|
||||
Count == 1 &&
|
||||
(N = CS_GetNextEntry (S, I)) != 0) {
|
||||
@ -253,15 +282,21 @@ unsigned OptShift1 (CodeSeg* S)
|
||||
X = NewCodeEntry (OP65_INX, AM65_IMP, 0, 0, E->LI);
|
||||
CS_InsertEntry (S, X, I+3);
|
||||
|
||||
/* Delete the call to shlax */
|
||||
CS_DelEntry (S, I);
|
||||
} else {
|
||||
|
||||
/* We won't handle this one */
|
||||
goto NextEntry;
|
||||
|
||||
/* Remember, we had changes */
|
||||
++Changes;
|
||||
}
|
||||
|
||||
/* Delete the call to shlax */
|
||||
CS_DelEntry (S, I);
|
||||
|
||||
/* Remember, we had changes */
|
||||
++Changes;
|
||||
}
|
||||
|
||||
NextEntry:
|
||||
/* Next entry */
|
||||
++I;
|
||||
|
||||
@ -438,19 +473,25 @@ unsigned OptShift4 (CodeSeg* S)
|
||||
Count = SHIFT_COUNT (Shift);
|
||||
if (Count == SHIFT_COUNT_Y) {
|
||||
|
||||
CodeLabel* L;
|
||||
|
||||
if (S->CodeSizeFactor < 200) {
|
||||
/* Not acceptable */
|
||||
goto NextEntry;
|
||||
}
|
||||
|
||||
/* Generate:
|
||||
*
|
||||
* L1: lsr a
|
||||
* dey
|
||||
* bpl L1
|
||||
* rol a
|
||||
*
|
||||
* A negative shift count or one that is greater or equal than
|
||||
* the bit width of the left operand (which is promoted to
|
||||
*
|
||||
* A negative shift count or one that is greater or equal than
|
||||
* the bit width of the left operand (which is promoted to
|
||||
* integer before the operation) causes undefined behaviour, so
|
||||
* above transformation is safe.
|
||||
*/
|
||||
CodeLabel* L;
|
||||
|
||||
/* lsr a */
|
||||
X = NewCodeEntry (OP65_LSR, AM65_ACC, "a", 0, E->LI);
|
||||
@ -486,6 +527,7 @@ unsigned OptShift4 (CodeSeg* S)
|
||||
|
||||
}
|
||||
|
||||
NextEntry:
|
||||
/* Next entry */
|
||||
++I;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user