1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-24 11:31:31 +00:00

Added OptSignExtened for testing signness right after sign extention.

This commit is contained in:
acqn 2020-09-18 20:22:58 +08:00 committed by Oliver Schmidt
parent 9c776a24e5
commit 0354322413
3 changed files with 120 additions and 0 deletions

View File

@ -178,6 +178,7 @@ static OptFunc DOptShift3 = { OptShift3, "OptShift3", 17, 0,
static OptFunc DOptShift4 = { OptShift4, "OptShift4", 100, 0, 0, 0, 0, 0 };
static OptFunc DOptShift5 = { OptShift5, "OptShift5", 110, 0, 0, 0, 0, 0 };
static OptFunc DOptShift6 = { OptShift6, "OptShift6", 200, 0, 0, 0, 0, 0 };
static OptFunc DOptSignExtended = { OptSignExtended, "OptSignExtended", 0, 0, 0, 0, 0, 0 };
static OptFunc DOptSize1 = { OptSize1, "OptSize1", 100, 0, 0, 0, 0, 0 };
static OptFunc DOptSize2 = { OptSize2, "OptSize2", 100, 0, 0, 0, 0, 0 };
static OptFunc DOptStackOps = { OptStackOps, "OptStackOps", 100, 0, 0, 0, 0, 0 };
@ -280,6 +281,7 @@ static OptFunc* OptFuncs[] = {
&DOptShift4,
&DOptShift5,
&DOptShift6,
&DOptSignExtended,
&DOptSize1,
&DOptSize2,
&DOptStackOps,
@ -713,6 +715,7 @@ static unsigned RunOptGroup3 (CodeSeg* S)
C += RunOptFunc (S, &DOptPushPop1, 1);
C += RunOptFunc (S, &DOptPushPop2, 1);
C += RunOptFunc (S, &DOptPrecalc, 1);
C += RunOptFunc (S, &DOptSignExtended, 1);
Changes += C;

View File

@ -1474,3 +1474,95 @@ unsigned OptPrecalc (CodeSeg* S)
/* Return the number of changes made */
return Changes;
}
unsigned OptSignExtended (CodeSeg* S)
/* Change
**
** lda xxx ; X is 0
** bpl L1
** dex/ldx #$FF
** L1: cpx #$00
** bpl L2
**
** or
**
** lda xxx ; X is 0
** bpl L1
** dex/ldx #$FF
** L1: cpx #$80
** bcc/bmi L2
**
** into
** lda xxx ; X is 0
** bpl L2
** dex/ldx #$FF
**
** provided the C flag isn't used later.
*/
{
unsigned Changes = 0;
CodeEntry* L[5];
CodeEntry* X;
unsigned CheckStates;
/* Walk over the entries */
unsigned I = 0;
while (I < CS_GetEntryCount (S)) {
/* Get next entry */
L[0] = CS_GetEntry (S, I);
/* Check if it's a register load or transfer insn */
if (L[0]->OPC == OP65_LDA &&
CS_GetEntries (S, L+1, I+1, 4) &&
!CS_RangeHasLabel (S, I+1, 2) &&
CE_GetLabelCount (L[3]) == 1 &&
L[1]->JumpTo == CE_GetLabel (L[3], 0) &&
(L[1]->Info & OF_CBRA) != 0 &&
GetBranchCond (L[1]->OPC) == BC_PL &&
RegValIsKnown (L[2]->RI->Out.RegX) &&
L[2]->RI->Out.RegX == 0xFF &&
L[2]->OPC != OP65_JSR &&
(L[2]->Chg & REG_AXY) == REG_X) {
/* We find a sign extention */
CheckStates = PSTATE_CZN;
if (L[3]->OPC == OP65_CPX &&
CE_IsConstImm (L[3]) &&
(L[4]->Info & OF_CBRA) != 0 &&
((L[3]->Num == 0x00 &&
GetBranchCond (L[4]->OPC) == BC_PL) ||
((L[3]->Num == 0x80 &&
GetBranchCond (L[4]->OPC) == BC_CC &&
GetBranchCond (L[4]->OPC) == BC_MI)))) {
/* Check if the processor states set by the CPX are unused later */
if ((GetRegInfo (S, I+5, CheckStates) & CheckStates) == 0) {
/* Change the target of the sign extention branch */
X = NewCodeEntry (OP65_JPL, L[4]->AM, L[4]->Arg, L[4]->JumpTo, L[4]->LI);
CS_InsertEntry (S, X, I+1);
CS_DelEntry (S, I+2);
/* Remove the old conditional branch */
CS_DelEntries (S, I+3, 2);
/* Remember, we had changes */
++Changes;
/* Continue with the current insn */
continue;
}
}
}
/* Next entry */
++I;
}
/* Return the number of changes made */
return Changes;
}

View File

@ -93,6 +93,31 @@ unsigned OptPrecalc (CodeSeg* S);
** known by a load of the final value.
*/
unsigned OptSignExtended (CodeSeg* S);
/* Change
**
** lda xxx ; X is 0
** bpl L1
** dex/ldx #$FF
** L1: cpx #$00
** bpl L2
**
** or
**
** lda xxx ; X is 0
** bpl L1
** dex/ldx #$FF
** L1: cpx #$80
** bcc/bmi L2
**
** into
** lda xxx ; X is 0
** bpl L2
** dex/ldx #$FF
**
** provided the C flag isn't used later.
*/
/* End of coptind.h */