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, &DOptNegAX1, 1);
|
||||||
C += RunOptFunc (S, &DOptNegAX2, 1);
|
C += RunOptFunc (S, &DOptNegAX2, 1);
|
||||||
C += RunOptFunc (S, &DOptStackOps, 3);
|
C += RunOptFunc (S, &DOptStackOps, 3);
|
||||||
|
C += RunOptFunc (S, &DOptShift1, 1);
|
||||||
C += RunOptFunc (S, &DOptShift4, 1);
|
C += RunOptFunc (S, &DOptShift4, 1);
|
||||||
C += RunOptFunc (S, &DOptSub1, 1);
|
C += RunOptFunc (S, &DOptSub1, 1);
|
||||||
C += RunOptFunc (S, &DOptSub2, 1);
|
C += RunOptFunc (S, &DOptSub2, 1);
|
||||||
|
@ -128,10 +128,10 @@ enum {
|
|||||||
|
|
||||||
|
|
||||||
/* Macros to extract values from a shift type */
|
/* Macros to extract values from a shift type */
|
||||||
#define SHIFT_COUNT(S) ((S) & SHIFT_MASK_COUNT)
|
#define SHIFT_COUNT(S) ((S) & SHIFT_MASK_COUNT)
|
||||||
#define SHIFT_DIR(S) ((S) & SHIFT_MASK_DIR)
|
#define SHIFT_DIR(S) ((S) & SHIFT_MASK_DIR)
|
||||||
#define SHIFT_MODE(S) ((S) & SHIFT_MASK_MODE)
|
#define SHIFT_MODE(S) ((S) & SHIFT_MASK_MODE)
|
||||||
#define SHIFT_TYPE(S) ((S) & SHIFT_MASK_TYPE)
|
#define SHIFT_TYPE(S) ((S) & SHIFT_MASK_TYPE)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -208,7 +208,6 @@ unsigned OptShift1 (CodeSeg* S)
|
|||||||
while (I < CS_GetEntryCount (S)) {
|
while (I < CS_GetEntryCount (S)) {
|
||||||
|
|
||||||
unsigned Shift;
|
unsigned Shift;
|
||||||
unsigned Count;
|
|
||||||
CodeEntry* N;
|
CodeEntry* N;
|
||||||
CodeEntry* X;
|
CodeEntry* X;
|
||||||
CodeLabel* L;
|
CodeLabel* L;
|
||||||
@ -219,23 +218,53 @@ unsigned OptShift1 (CodeSeg* S)
|
|||||||
/* Check for the sequence */
|
/* Check for the sequence */
|
||||||
if (E->OPC == OP65_JSR &&
|
if (E->OPC == OP65_JSR &&
|
||||||
(Shift = GetShift (E->Arg)) != SHIFT_NONE &&
|
(Shift = GetShift (E->Arg)) != SHIFT_NONE &&
|
||||||
SHIFT_DIR (Shift) == SHIFT_DIR_LEFT &&
|
SHIFT_DIR (Shift) == SHIFT_DIR_LEFT) {
|
||||||
(Count = SHIFT_COUNT (Shift)) > 0) {
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned Count = SHIFT_COUNT (Shift);
|
||||||
if (!RegXUsed (S, I+1)) {
|
if (!RegXUsed (S, I+1)) {
|
||||||
|
|
||||||
/* Insert shift insns */
|
if (Count == SHIFT_COUNT_Y) {
|
||||||
while (Count--) {
|
|
||||||
|
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);
|
X = NewCodeEntry (OP65_ASL, AM65_ACC, "a", 0, E->LI);
|
||||||
CS_InsertEntry (S, X, I+1);
|
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 &&
|
} else if (E->RI->In.RegX == 0 &&
|
||||||
Count == 1 &&
|
Count == 1 &&
|
||||||
(N = CS_GetNextEntry (S, I)) != 0) {
|
(N = CS_GetNextEntry (S, I)) != 0) {
|
||||||
@ -253,15 +282,21 @@ unsigned OptShift1 (CodeSeg* S)
|
|||||||
X = NewCodeEntry (OP65_INX, AM65_IMP, 0, 0, E->LI);
|
X = NewCodeEntry (OP65_INX, AM65_IMP, 0, 0, E->LI);
|
||||||
CS_InsertEntry (S, X, I+3);
|
CS_InsertEntry (S, X, I+3);
|
||||||
|
|
||||||
/* Delete the call to shlax */
|
} else {
|
||||||
CS_DelEntry (S, I);
|
|
||||||
|
/* 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 */
|
/* Next entry */
|
||||||
++I;
|
++I;
|
||||||
|
|
||||||
@ -438,19 +473,25 @@ unsigned OptShift4 (CodeSeg* S)
|
|||||||
Count = SHIFT_COUNT (Shift);
|
Count = SHIFT_COUNT (Shift);
|
||||||
if (Count == SHIFT_COUNT_Y) {
|
if (Count == SHIFT_COUNT_Y) {
|
||||||
|
|
||||||
|
CodeLabel* L;
|
||||||
|
|
||||||
|
if (S->CodeSizeFactor < 200) {
|
||||||
|
/* Not acceptable */
|
||||||
|
goto NextEntry;
|
||||||
|
}
|
||||||
|
|
||||||
/* Generate:
|
/* Generate:
|
||||||
*
|
*
|
||||||
* L1: lsr a
|
* L1: lsr a
|
||||||
* dey
|
* dey
|
||||||
* bpl L1
|
* bpl L1
|
||||||
* rol a
|
* rol a
|
||||||
*
|
*
|
||||||
* A negative shift count or one that is greater or equal than
|
* A negative shift count or one that is greater or equal than
|
||||||
* the bit width of the left operand (which is promoted to
|
* the bit width of the left operand (which is promoted to
|
||||||
* integer before the operation) causes undefined behaviour, so
|
* integer before the operation) causes undefined behaviour, so
|
||||||
* above transformation is safe.
|
* above transformation is safe.
|
||||||
*/
|
*/
|
||||||
CodeLabel* L;
|
|
||||||
|
|
||||||
/* lsr a */
|
/* lsr a */
|
||||||
X = NewCodeEntry (OP65_LSR, AM65_ACC, "a", 0, E->LI);
|
X = NewCodeEntry (OP65_LSR, AM65_ACC, "a", 0, E->LI);
|
||||||
@ -486,6 +527,7 @@ unsigned OptShift4 (CodeSeg* S)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NextEntry:
|
||||||
/* Next entry */
|
/* Next entry */
|
||||||
++I;
|
++I;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user