mirror of
https://github.com/cc65/cc65.git
synced 2024-11-19 06:31:31 +00:00
Extended a signed char shift optimization, to handle shifts that are longer than 4 bits.
This commit is contained in:
parent
4716083f3f
commit
651b1b40ec
@ -320,6 +320,11 @@ unsigned OptShift2 (CodeSeg* S)
|
|||||||
** ror a
|
** ror a
|
||||||
**
|
**
|
||||||
** if X is not used later (X is assumed to be zero on entry).
|
** if X is not used later (X is assumed to be zero on entry).
|
||||||
|
** If the sequence is followed immediately by another
|
||||||
|
**
|
||||||
|
** jsr asraxN
|
||||||
|
**
|
||||||
|
** then their shifts are combined.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
unsigned Changes = 0;
|
unsigned Changes = 0;
|
||||||
@ -327,10 +332,10 @@ unsigned OptShift2 (CodeSeg* S)
|
|||||||
|
|
||||||
/* Walk over the entries */
|
/* Walk over the entries */
|
||||||
while (I < CS_GetEntryCount (S)) {
|
while (I < CS_GetEntryCount (S)) {
|
||||||
|
|
||||||
unsigned Shift;
|
unsigned Shift;
|
||||||
unsigned Count;
|
unsigned Count, Count2;
|
||||||
CodeEntry* L[3];
|
unsigned K;
|
||||||
|
CodeEntry* L[4];
|
||||||
|
|
||||||
/* Get next entry */
|
/* Get next entry */
|
||||||
L[0] = CS_GetEntry (S, I);
|
L[0] = CS_GetEntry (S, I);
|
||||||
@ -338,40 +343,51 @@ unsigned OptShift2 (CodeSeg* S)
|
|||||||
/* Check for the sequence */
|
/* Check for the sequence */
|
||||||
if (L[0]->OPC == OP65_BPL &&
|
if (L[0]->OPC == OP65_BPL &&
|
||||||
L[0]->JumpTo != 0 &&
|
L[0]->JumpTo != 0 &&
|
||||||
CS_GetEntries (S, L+1, I+1, 2) &&
|
CS_GetEntries (S, L+1, I+1, 3) &&
|
||||||
L[1]->OPC == OP65_DEX &&
|
L[1]->OPC == OP65_DEX &&
|
||||||
L[0]->JumpTo->Owner == L[2] &&
|
L[0]->JumpTo->Owner == L[2] &&
|
||||||
!CS_RangeHasLabel (S, I, 2) &&
|
!CS_RangeHasLabel (S, I, 2) &&
|
||||||
L[2]->OPC == OP65_JSR &&
|
L[2]->OPC == OP65_JSR &&
|
||||||
SHIFT_TYPE (Shift = GetShift (L[2]->Arg)) == SHIFT_TYPE_ASR &&
|
SHIFT_TYPE (Shift = GetShift (L[2]->Arg)) == SHIFT_TYPE_ASR &&
|
||||||
(Count = SHIFT_COUNT (Shift)) > 0 &&
|
(Count = SHIFT_COUNT (Shift)) > 0) {
|
||||||
Count * 100 <= S->CodeSizeFactor &&
|
|
||||||
!RegXUsed (S, I+3)) {
|
if (L[3]->OPC == OP65_JSR &&
|
||||||
|
SHIFT_TYPE (Shift = GetShift (L[3]->Arg)) == SHIFT_TYPE_ASR &&
|
||||||
|
(Count2 = SHIFT_COUNT (Shift)) > 0) {
|
||||||
|
|
||||||
|
/* Found a second jsr asraxN */
|
||||||
|
Count += Count2;
|
||||||
|
K = 4;
|
||||||
|
} else {
|
||||||
|
K = 3;
|
||||||
|
}
|
||||||
|
if (Count * 100 <= S->CodeSizeFactor &&
|
||||||
|
!RegXUsed (S, I+K)) {
|
||||||
|
|
||||||
CodeEntry* X;
|
CodeEntry* X;
|
||||||
unsigned J = I+2;
|
unsigned J = I+K;
|
||||||
|
|
||||||
/* Generate the replacement sequence */
|
/* Generate the replacement sequence */
|
||||||
while (Count--) {
|
do {
|
||||||
/* cmp #$80 */
|
/* cmp #$80 */
|
||||||
X = NewCodeEntry (OP65_CMP, AM65_IMM, "$80", 0, L[2]->LI);
|
X = NewCodeEntry (OP65_CMP, AM65_IMM, "$80", 0, L[2]->LI);
|
||||||
CS_InsertEntry (S, X, ++J);
|
CS_InsertEntry (S, X, J++);
|
||||||
|
|
||||||
/* ror a */
|
/* ror a */
|
||||||
X = NewCodeEntry (OP65_ROR, AM65_ACC, "a", 0, L[2]->LI);
|
X = NewCodeEntry (OP65_ROR, AM65_ACC, "a", 0, L[2]->LI);
|
||||||
CS_InsertEntry (S, X, ++J);
|
CS_InsertEntry (S, X, J++);
|
||||||
}
|
} while (--Count);
|
||||||
|
|
||||||
/* Remove the bpl/dex/jsr */
|
/* Remove the bpl/dex/jsr */
|
||||||
CS_DelEntries (S, I, 3);
|
CS_DelEntries (S, I, K);
|
||||||
|
|
||||||
/* Remember, we had changes */
|
/* Remember, we had changes */
|
||||||
++Changes;
|
++Changes;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Next entry */
|
/* Next entry */
|
||||||
++I;
|
++I;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the number of changes made */
|
/* Return the number of changes made */
|
||||||
|
Loading…
Reference in New Issue
Block a user