mirror of
https://github.com/cc65/cc65.git
synced 2025-08-08 06:25:17 +00:00
Added OptShiftBack for shifting the C flag into register A and back.
This commit is contained in:
@@ -178,6 +178,7 @@ static OptFunc DOptShift3 = { OptShift3, "OptShift3", 17, 0,
|
|||||||
static OptFunc DOptShift4 = { OptShift4, "OptShift4", 100, 0, 0, 0, 0, 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 DOptShift5 = { OptShift5, "OptShift5", 110, 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptShift6 = { OptShift6, "OptShift6", 200, 0, 0, 0, 0, 0 };
|
static OptFunc DOptShift6 = { OptShift6, "OptShift6", 200, 0, 0, 0, 0, 0 };
|
||||||
|
static OptFunc DOptShiftBack = { OptShiftBack, "OptShiftBack", 0, 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptSignExtended = { OptSignExtended, "OptSignExtended", 0, 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 DOptSize1 = { OptSize1, "OptSize1", 100, 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptSize2 = { OptSize2, "OptSize2", 100, 0, 0, 0, 0, 0 };
|
static OptFunc DOptSize2 = { OptSize2, "OptSize2", 100, 0, 0, 0, 0, 0 };
|
||||||
@@ -281,6 +282,7 @@ static OptFunc* OptFuncs[] = {
|
|||||||
&DOptShift4,
|
&DOptShift4,
|
||||||
&DOptShift5,
|
&DOptShift5,
|
||||||
&DOptShift6,
|
&DOptShift6,
|
||||||
|
&DOptShiftBack,
|
||||||
&DOptSignExtended,
|
&DOptSignExtended,
|
||||||
&DOptSize1,
|
&DOptSize1,
|
||||||
&DOptSize2,
|
&DOptSize2,
|
||||||
@@ -715,6 +717,7 @@ static unsigned RunOptGroup3 (CodeSeg* S)
|
|||||||
C += RunOptFunc (S, &DOptPushPop1, 1);
|
C += RunOptFunc (S, &DOptPushPop1, 1);
|
||||||
C += RunOptFunc (S, &DOptPushPop2, 1);
|
C += RunOptFunc (S, &DOptPushPop2, 1);
|
||||||
C += RunOptFunc (S, &DOptPrecalc, 1);
|
C += RunOptFunc (S, &DOptPrecalc, 1);
|
||||||
|
C += RunOptFunc (S, &DOptShiftBack, 1);
|
||||||
C += RunOptFunc (S, &DOptSignExtended, 1);
|
C += RunOptFunc (S, &DOptSignExtended, 1);
|
||||||
|
|
||||||
Changes += C;
|
Changes += C;
|
||||||
|
@@ -1477,6 +1477,60 @@ unsigned OptPrecalc (CodeSeg* S)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned OptShiftBack (CodeSeg* S)
|
||||||
|
/* Remove a pair of shifts to the opposite directions if none of the bits of
|
||||||
|
** the register A or the Z/N flags modified by these shifts are used later.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
unsigned Changes = 0;
|
||||||
|
CodeEntry* E;
|
||||||
|
CodeEntry* N;
|
||||||
|
unsigned CheckStates;
|
||||||
|
|
||||||
|
/* Walk over the entries */
|
||||||
|
unsigned I = 0;
|
||||||
|
while (I < CS_GetEntryCount (S)) {
|
||||||
|
|
||||||
|
/* Get next entry */
|
||||||
|
E = CS_GetEntry (S, I);
|
||||||
|
|
||||||
|
/* Check if it's a register load or transfer insn */
|
||||||
|
if (E->OPC == OP65_ROL &&
|
||||||
|
(N = CS_GetNextEntry (S, I)) != 0 &&
|
||||||
|
(N->OPC == OP65_LSR ||
|
||||||
|
N->OPC == OP65_ROR) &&
|
||||||
|
!CE_HasLabel (N)) {
|
||||||
|
|
||||||
|
CheckStates = PSTATE_ZN;
|
||||||
|
|
||||||
|
if (N->OPC == OP65_LSR &&
|
||||||
|
!PStatesAreClear (E->RI->Out.PFlags, PSTATE_C)) {
|
||||||
|
CheckStates |= REG_A;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((GetRegInfo (S, I+2, CheckStates) & CheckStates) == 0) {
|
||||||
|
|
||||||
|
/* Remove the shifts */
|
||||||
|
CS_DelEntries (S, I, 2);
|
||||||
|
|
||||||
|
/* Remember, we had changes */
|
||||||
|
++Changes;
|
||||||
|
|
||||||
|
/* Continue with next insn */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Next entry */
|
||||||
|
++I;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the number of changes made */
|
||||||
|
return Changes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned OptSignExtended (CodeSeg* S)
|
unsigned OptSignExtended (CodeSeg* S)
|
||||||
/* Change
|
/* Change
|
||||||
**
|
**
|
||||||
|
@@ -93,6 +93,11 @@ unsigned OptPrecalc (CodeSeg* S);
|
|||||||
** known by a load of the final value.
|
** known by a load of the final value.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
unsigned OptShiftBack (CodeSeg* S);
|
||||||
|
/* Remove a pair of shifts to the opposite directions if none of the bits of
|
||||||
|
** the register A or the Z/N flags modified by these shifts are used later.
|
||||||
|
*/
|
||||||
|
|
||||||
unsigned OptSignExtended (CodeSeg* S);
|
unsigned OptSignExtended (CodeSeg* S);
|
||||||
/* Change
|
/* Change
|
||||||
**
|
**
|
||||||
|
Reference in New Issue
Block a user