Optimize X and Y usage
This commit is contained in:
parent
0ba2ddf195
commit
f9eb91e980
|
@ -706,6 +706,107 @@ bool NativeCodeInstruction::ReplaceYRegWithXReg(void)
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NativeCodeInstruction::CanSwapXYReg(void)
|
||||||
|
{
|
||||||
|
if (mMode == ASMIM_INDIRECT_X || mMode == ASMIM_INDIRECT_Y || mMode == ASMIM_ZERO_PAGE_X || mMode == ASMIM_ZERO_PAGE_Y)
|
||||||
|
return false;
|
||||||
|
else if (mMode == ASMIM_ABSOLUTE_X)
|
||||||
|
return HasAsmInstructionMode(mType, ASMIM_ABSOLUTE_Y);
|
||||||
|
else if (mMode == ASMIM_ABSOLUTE_Y)
|
||||||
|
return HasAsmInstructionMode(mType, ASMIM_ABSOLUTE_X);
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NativeCodeInstruction::SwapXYReg(void)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
switch (mType)
|
||||||
|
{
|
||||||
|
case ASMIT_LDX:
|
||||||
|
mType = ASMIT_LDY;
|
||||||
|
changed = true;
|
||||||
|
break;
|
||||||
|
case ASMIT_STX:
|
||||||
|
mType = ASMIT_STY;
|
||||||
|
changed = true;
|
||||||
|
break;
|
||||||
|
case ASMIT_CPX:
|
||||||
|
mType = ASMIT_CPY;
|
||||||
|
changed = true;
|
||||||
|
break;
|
||||||
|
case ASMIT_TXA:
|
||||||
|
mType = ASMIT_TYA;
|
||||||
|
changed = true;
|
||||||
|
break;
|
||||||
|
case ASMIT_TAX:
|
||||||
|
mType = ASMIT_TAY;
|
||||||
|
changed = true;
|
||||||
|
break;
|
||||||
|
case ASMIT_INX:
|
||||||
|
mType = ASMIT_INY;
|
||||||
|
changed = true;
|
||||||
|
break;
|
||||||
|
case ASMIT_DEX:
|
||||||
|
mType = ASMIT_DEY;
|
||||||
|
changed = true;
|
||||||
|
break;
|
||||||
|
case ASMIT_LDY:
|
||||||
|
mType = ASMIT_LDX;
|
||||||
|
changed = true;
|
||||||
|
break;
|
||||||
|
case ASMIT_STY:
|
||||||
|
mType = ASMIT_STX;
|
||||||
|
changed = true;
|
||||||
|
break;
|
||||||
|
case ASMIT_CPY:
|
||||||
|
mType = ASMIT_CPX;
|
||||||
|
changed = true;
|
||||||
|
break;
|
||||||
|
case ASMIT_TYA:
|
||||||
|
mType = ASMIT_TXA;
|
||||||
|
changed = true;
|
||||||
|
break;
|
||||||
|
case ASMIT_TAY:
|
||||||
|
mType = ASMIT_TAX;
|
||||||
|
changed = true;
|
||||||
|
break;
|
||||||
|
case ASMIT_INY:
|
||||||
|
mType = ASMIT_INX;
|
||||||
|
changed = true;
|
||||||
|
break;
|
||||||
|
case ASMIT_DEY:
|
||||||
|
mType = ASMIT_DEX;
|
||||||
|
changed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mMode == ASMIM_ABSOLUTE_X)
|
||||||
|
{
|
||||||
|
assert(HasAsmInstructionMode(mType, ASMIM_ABSOLUTE_Y));
|
||||||
|
mMode = ASMIM_ABSOLUTE_Y;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else if (mMode == ASMIM_ABSOLUTE_Y)
|
||||||
|
{
|
||||||
|
assert(HasAsmInstructionMode(mType, ASMIM_ABSOLUTE_X));
|
||||||
|
mMode = ASMIM_ABSOLUTE_X;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 live = mLive;
|
||||||
|
mLive &= ~(LIVE_CPU_REG_X | LIVE_CPU_REG_Y);
|
||||||
|
if (live & LIVE_CPU_REG_X)
|
||||||
|
mLive |= LIVE_CPU_REG_Y;
|
||||||
|
if (live & LIVE_CPU_REG_Y)
|
||||||
|
mLive |= LIVE_CPU_REG_X;
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool NativeCodeInstruction::ReplaceXRegWithYReg(void)
|
bool NativeCodeInstruction::ReplaceXRegWithYReg(void)
|
||||||
{
|
{
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
@ -11316,6 +11417,94 @@ bool NativeCodeBasicBlock::CanReplaceXRegWithYReg(int start, int end)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NativeCodeBasicBlock::OptimizeXYPairUsage(void)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
if (!mVisited)
|
||||||
|
{
|
||||||
|
mVisited = true;
|
||||||
|
|
||||||
|
CheckLive();
|
||||||
|
|
||||||
|
if (!mExitRequiredRegs[CPU_REG_X] && !mExitRequiredRegs[CPU_REG_Y])
|
||||||
|
{
|
||||||
|
int yreg = -1, xreg = -1, areg = -1;
|
||||||
|
for (int i = 0; i < mIns.Size(); i++)
|
||||||
|
{
|
||||||
|
NativeCodeInstruction & ins(mIns[i]);
|
||||||
|
|
||||||
|
if (ins.mType == ASMIT_LDY && ins.mMode == ASMIM_ZERO_PAGE && ins.mAddress == xreg ||
|
||||||
|
ins.mType == ASMIT_LDX && ins.mMode == ASMIM_ZERO_PAGE && ins.mAddress == yreg)
|
||||||
|
{
|
||||||
|
int j = i;
|
||||||
|
while (j + 1 < mIns.Size() && (mIns[j].mLive & (LIVE_CPU_REG_X | LIVE_CPU_REG_Y)) && mIns[j + 1].CanSwapXYReg())
|
||||||
|
j++;
|
||||||
|
if (j + 1 == mIns.Size() || !(mIns[j].mLive & (LIVE_CPU_REG_X | LIVE_CPU_REG_Y)))
|
||||||
|
{
|
||||||
|
for (int k = i; k <= j; k++)
|
||||||
|
mIns[k].SwapXYReg();
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ins.mType == ASMIT_LDY)
|
||||||
|
{
|
||||||
|
if (ins.mMode == ASMIM_ZERO_PAGE)
|
||||||
|
yreg = ins.mAddress;
|
||||||
|
else
|
||||||
|
yreg = -1;
|
||||||
|
}
|
||||||
|
else if (ins.mType == ASMIT_LDX)
|
||||||
|
{
|
||||||
|
if (ins.mMode == ASMIM_ZERO_PAGE)
|
||||||
|
xreg = ins.mAddress;
|
||||||
|
else
|
||||||
|
xreg = -1;
|
||||||
|
}
|
||||||
|
else if (ins.mMode == ASMIT_LDA)
|
||||||
|
{
|
||||||
|
if (ins.mMode == ASMIM_ZERO_PAGE)
|
||||||
|
areg = ins.mAddress;
|
||||||
|
else
|
||||||
|
areg = -1;
|
||||||
|
}
|
||||||
|
else if (ins.mType == ASMIT_TAX)
|
||||||
|
xreg = areg;
|
||||||
|
else if (ins.mType == ASMIT_TAY)
|
||||||
|
yreg = areg;
|
||||||
|
else if (ins.mType == ASMIT_JSR)
|
||||||
|
xreg = yreg = areg = false;
|
||||||
|
else if (ins.ChangesAccu())
|
||||||
|
areg = -1;
|
||||||
|
else if (ins.ChangesXReg())
|
||||||
|
xreg = -1;
|
||||||
|
else if (ins.ChangesYReg())
|
||||||
|
yreg = -1;
|
||||||
|
else if (ins.mMode == ASMIM_ZERO_PAGE && ins.ChangesAddress())
|
||||||
|
{
|
||||||
|
if (ins.mAddress == areg)
|
||||||
|
areg = -1;
|
||||||
|
if (ins.mAddress == xreg)
|
||||||
|
xreg = -1;
|
||||||
|
if (ins.mAddress == yreg)
|
||||||
|
yreg = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CheckLive();
|
||||||
|
|
||||||
|
if (mTrueJump && mTrueJump->OptimizeXYPairUsage())
|
||||||
|
changed = true;
|
||||||
|
|
||||||
|
if (mFalseJump && mFalseJump->OptimizeXYPairUsage())
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
bool NativeCodeBasicBlock::AlternateXYUsage(void)
|
bool NativeCodeBasicBlock::AlternateXYUsage(void)
|
||||||
{
|
{
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
@ -24573,6 +24762,9 @@ void NativeCodeProcedure::Optimize(void)
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
if (mEntryBlock->AlternateXYUsage())
|
if (mEntryBlock->AlternateXYUsage())
|
||||||
changed = true;
|
changed = true;
|
||||||
|
ResetVisited();
|
||||||
|
if (mEntryBlock->OptimizeXYPairUsage())
|
||||||
|
changed = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -126,6 +126,9 @@ public:
|
||||||
|
|
||||||
bool ReplaceYRegWithXReg(void);
|
bool ReplaceYRegWithXReg(void);
|
||||||
bool ReplaceXRegWithYReg(void);
|
bool ReplaceXRegWithYReg(void);
|
||||||
|
|
||||||
|
bool CanSwapXYReg(void);
|
||||||
|
bool SwapXYReg(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
class NativeCodeBasicBlock
|
class NativeCodeBasicBlock
|
||||||
|
@ -339,6 +342,7 @@ public:
|
||||||
bool Split16BitLoopCount(NativeCodeProcedure* proc);
|
bool Split16BitLoopCount(NativeCodeProcedure* proc);
|
||||||
|
|
||||||
bool AlternateXYUsage(void);
|
bool AlternateXYUsage(void);
|
||||||
|
bool OptimizeXYPairUsage(void);
|
||||||
bool ForwardAbsoluteLoadStores(void);
|
bool ForwardAbsoluteLoadStores(void);
|
||||||
|
|
||||||
bool CheckPatchFail(const NativeCodeBasicBlock* block, int reg);
|
bool CheckPatchFail(const NativeCodeBasicBlock* block, int reg);
|
||||||
|
|
Loading…
Reference in New Issue