Optimize cross block XY register usage
This commit is contained in:
parent
d15fd8a451
commit
932a65be8c
|
@ -8523,7 +8523,7 @@ void InterCodeBasicBlock::PerformValueForwarding(const GrowingInstructionPtrArra
|
||||||
else if (li0->mCode == IC_CONSTANT && li1->mCode == IC_LEA)
|
else if (li0->mCode == IC_CONSTANT && li1->mCode == IC_LEA)
|
||||||
{
|
{
|
||||||
InterInstruction* ai0 = ltvalue[li1->mSrc[0].mTemp], * ai1 = ltvalue[li1->mSrc[1].mTemp];
|
InterInstruction* ai0 = ltvalue[li1->mSrc[0].mTemp], * ai1 = ltvalue[li1->mSrc[1].mTemp];
|
||||||
if (ai0 && ai1 && ai0->mCode == IC_CONSTANT && ai0->mConst.mIntConst >= 0)
|
if (ai0 && ai1 && ai0->mCode == IC_CONSTANT)// && ai0->mConst.mIntConst >= 0)
|
||||||
{
|
{
|
||||||
InterInstruction* cai = new InterInstruction(ins->mLocation, IC_CONSTANT);
|
InterInstruction* cai = new InterInstruction(ins->mLocation, IC_CONSTANT);
|
||||||
cai->mDst.mTemp = spareTemps++;
|
cai->mDst.mTemp = spareTemps++;
|
||||||
|
|
|
@ -126,6 +126,17 @@ void NativeRegisterDataSet::ResetZeroPage(int addr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int NativeRegisterDataSet::FindAbsolute(LinkerObject* linkerObject, int addr)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
if (mRegs[i].mMode == NRDM_ABSOLUTE && mRegs[i].mLinkerObject == linkerObject && mRegs[i].mValue == addr)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
void NativeRegisterDataSet::ResetAbsolute(LinkerObject* linkerObject, int addr)
|
void NativeRegisterDataSet::ResetAbsolute(LinkerObject* linkerObject, int addr)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < NUM_REGS; i++)
|
for (int i = 0; i < NUM_REGS; i++)
|
||||||
|
@ -1198,6 +1209,28 @@ bool NativeCodeInstruction::UsesZeroPage(int address) const
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
else if (mType == ASMIT_RTS)
|
||||||
|
{
|
||||||
|
if (mFlags & NCIF_LOWER)
|
||||||
|
{
|
||||||
|
if (address == BC_REG_ACCU + 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (mFlags & NCIF_UPPER)
|
||||||
|
{
|
||||||
|
if (address == BC_REG_ACCU + 1)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (mFlags & NCIF_LONG)
|
||||||
|
{
|
||||||
|
if (address == BC_REG_ACCU + 2 || address == BC_REG_ACCU + 3)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -3203,6 +3236,21 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsT
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
if (mMode == ASMIM_ABSOLUTE && final && !(mFlags & NCIF_VOLATILE) && !ChangesAddress() && HasAsmInstructionMode(mType, ASMIM_ZERO_PAGE))
|
||||||
|
{
|
||||||
|
int i = data.FindAbsolute(mLinkerObject, mAddress);
|
||||||
|
if (i >= 0)
|
||||||
|
{
|
||||||
|
mMode = ASMIM_ZERO_PAGE;
|
||||||
|
mAddress = i;
|
||||||
|
mLinkerObject = nullptr;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (mMode == ASMIM_ZERO_PAGE)
|
if (mMode == ASMIM_ZERO_PAGE)
|
||||||
{
|
{
|
||||||
switch (mType)
|
switch (mType)
|
||||||
|
@ -3434,7 +3482,7 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsT
|
||||||
mAddress = data.mRegs[mAddress].mValue;
|
mAddress = data.mRegs[mAddress].mValue;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
else if (data.mRegs[mAddress].mMode == NRDM_ABSOLUTE)
|
else if (data.mRegs[mAddress].mMode == NRDM_ABSOLUTE && !final)
|
||||||
{
|
{
|
||||||
mMode = ASMIM_ABSOLUTE;
|
mMode = ASMIM_ABSOLUTE;
|
||||||
mLinkerObject = data.mRegs[mAddress].mLinkerObject;
|
mLinkerObject = data.mRegs[mAddress].mLinkerObject;
|
||||||
|
@ -13930,6 +13978,8 @@ bool NativeCodeBasicBlock::SimplifyDiamond(NativeCodeProcedure* proc)
|
||||||
{
|
{
|
||||||
if (!mTrueJump->mFalseJump && !mFalseJump->mFalseJump && mTrueJump->mTrueJump && mTrueJump->mTrueJump == mFalseJump->mTrueJump && mTrueJump->mNumEntries == 1 && mFalseJump->mNumEntries == 1 && mTrueJump->mTrueJump->mNumEntries == 2)
|
if (!mTrueJump->mFalseJump && !mFalseJump->mFalseJump && mTrueJump->mTrueJump && mTrueJump->mTrueJump == mFalseJump->mTrueJump && mTrueJump->mNumEntries == 1 && mFalseJump->mNumEntries == 1 && mTrueJump->mTrueJump->mNumEntries == 2)
|
||||||
{
|
{
|
||||||
|
NativeCodeBasicBlock* mblock = mTrueJump->mTrueJump;
|
||||||
|
|
||||||
if (mTrueJump->mIns.Size() == 1 && mFalseJump->mIns.Size() == 1 &&
|
if (mTrueJump->mIns.Size() == 1 && mFalseJump->mIns.Size() == 1 &&
|
||||||
mTrueJump->mIns[0].mMode == ASMIM_IMMEDIATE && mFalseJump->mIns[0].mMode == ASMIM_IMMEDIATE)
|
mTrueJump->mIns[0].mMode == ASMIM_IMMEDIATE && mFalseJump->mIns[0].mMode == ASMIM_IMMEDIATE)
|
||||||
{
|
{
|
||||||
|
@ -13976,6 +14026,15 @@ bool NativeCodeBasicBlock::SimplifyDiamond(NativeCodeProcedure* proc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mblock->mIns.Size() > 0 && mblock->mIns[0].mType == ASMIT_STX && !(mblock->mIns[0].mLive & LIVE_CPU_REG_X) &&
|
||||||
|
!mTrueJump->ChangesXReg() && !mFalseJump->ChangesXReg())
|
||||||
|
{
|
||||||
|
mIns.Push(mblock->mIns[0]);
|
||||||
|
mblock->mIns.Remove(0);
|
||||||
|
mIns[mIns.Size() - 1].mLive |= LIVE_CPU_REG_X;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#if 1
|
#if 1
|
||||||
if (mTrueJump->mEntryRequiredRegs[CPU_REG_Y] && !mFalseJump->mEntryRequiredRegs[CPU_REG_Y] && !mTrueJump->mEntryRequiredRegs[CPU_REG_Z] && mTrueJump->mNumEntries == 1)
|
if (mTrueJump->mEntryRequiredRegs[CPU_REG_Y] && !mFalseJump->mEntryRequiredRegs[CPU_REG_Y] && !mTrueJump->mEntryRequiredRegs[CPU_REG_Z] && mTrueJump->mNumEntries == 1)
|
||||||
|
@ -14777,6 +14836,34 @@ bool NativeCodeBasicBlock::ExpandADCToBranch(NativeCodeProcedure* proc)
|
||||||
mBranch = ASMIT_BCC;
|
mBranch = ASMIT_BCC;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
else if (mIns[i + 0].mType == ASMIT_LDA &&
|
||||||
|
mIns[i + 1].mType == ASMIT_ADC && mIns[i + 1].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mAddress == 0xff &&
|
||||||
|
mIns[i + 2].mType == ASMIT_STA && mIns[i + 0].SameEffectiveAddress(mIns[i + 2]) &&
|
||||||
|
HasAsmInstructionMode(ASMIT_DEC, mIns[i + 2].mMode) &&
|
||||||
|
!(mIns[i + 2].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C | LIVE_CPU_REG_Z)))
|
||||||
|
{
|
||||||
|
changed = true;
|
||||||
|
|
||||||
|
NativeCodeBasicBlock* iblock = proc->AllocateBlock();
|
||||||
|
NativeCodeBasicBlock* fblock = proc->AllocateBlock();
|
||||||
|
|
||||||
|
fblock->mTrueJump = mTrueJump;
|
||||||
|
fblock->mFalseJump = mFalseJump;
|
||||||
|
fblock->mBranch = mBranch;
|
||||||
|
|
||||||
|
for (int j = i + 3; j < mIns.Size(); j++)
|
||||||
|
fblock->mIns.Push(mIns[j]);
|
||||||
|
iblock->mIns.Push(mIns[i + 2]);
|
||||||
|
mIns.SetSize(i);
|
||||||
|
iblock->mIns[0].mType = ASMIT_DEC;
|
||||||
|
iblock->mTrueJump = fblock;
|
||||||
|
iblock->mBranch = ASMIT_JMP;
|
||||||
|
|
||||||
|
mTrueJump = fblock;
|
||||||
|
mFalseJump = iblock;
|
||||||
|
mBranch = ASMIT_BCS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
else if (mIns[i + 0].mType == ASMIT_TXA &&
|
else if (mIns[i + 0].mType == ASMIT_TXA &&
|
||||||
mIns[i + 1].mType == ASMIT_ADC && mIns[i + 1].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mAddress == 0 &&
|
mIns[i + 1].mType == ASMIT_ADC && mIns[i + 1].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mAddress == 0 &&
|
||||||
mIns[i + 2].mType == ASMIT_TAX &&
|
mIns[i + 2].mType == ASMIT_TAX &&
|
||||||
|
@ -18417,6 +18504,578 @@ bool NativeCodeBasicBlock::PatchForwardSumYPointer(const NativeCodeBasicBlock* b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool NativeCodeBasicBlock::CrossBlockXYFlood(NativeCodeProcedure* proc)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
if (!mVisited)
|
||||||
|
{
|
||||||
|
mVisited = true;
|
||||||
|
|
||||||
|
for (int i = 0; i < mIns.Size(); i++)
|
||||||
|
{
|
||||||
|
if ((mIns[i].mType == ASMIT_STA || mIns[i].mType == ASMIT_STX || mIns[i].mType == ASMIT_STY) && mIns[i].mMode == ASMIM_ZERO_PAGE && !(mIns[i].mLive & LIVE_CPU_REG_Z))
|
||||||
|
{
|
||||||
|
proc->ResetPatched();
|
||||||
|
if (mIns[i].mType != ASMIT_STY && !(mIns[i].mLive & LIVE_CPU_REG_X) &&CheckCrossBlockXFlood(this, mIns[i].mAddress, i + 1))
|
||||||
|
{
|
||||||
|
if (mIns[i].mType == ASMIT_STX)
|
||||||
|
mIns[i].mType = ASMIT_NOP;
|
||||||
|
else
|
||||||
|
mIns[i].mType = ASMIT_TAX;
|
||||||
|
mIns[i].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i].mLive |= LIVE_CPU_REG_X;
|
||||||
|
|
||||||
|
proc->ResetPatched();
|
||||||
|
if (PatchCrossBlockXFlood(this, mIns[i].mAddress, i + 1))
|
||||||
|
{
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
proc->ResetPatched();
|
||||||
|
if (mIns[i].mType != ASMIT_STX && !(mIns[i].mLive & LIVE_CPU_REG_Y) && CheckCrossBlockYFlood(this, mIns[i].mAddress, i + 1))
|
||||||
|
{
|
||||||
|
if (mIns[i].mType == ASMIT_STY)
|
||||||
|
mIns[i].mType = ASMIT_NOP;
|
||||||
|
else
|
||||||
|
mIns[i].mType = ASMIT_TAY;
|
||||||
|
mIns[i].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i].mLive |= LIVE_CPU_REG_Y;
|
||||||
|
|
||||||
|
proc->ResetPatched();
|
||||||
|
if (PatchCrossBlockYFlood(this, mIns[i].mAddress, i + 1))
|
||||||
|
{
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mTrueJump && mTrueJump->CrossBlockXYFlood(proc))
|
||||||
|
changed = true;
|
||||||
|
if (mFalseJump && mFalseJump->CrossBlockXYFlood(proc))
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NativeCodeBasicBlock::CheckCrossBlockXFlood(const NativeCodeBasicBlock* block, int reg, int at)
|
||||||
|
{
|
||||||
|
if (at == 0 && this == block)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!mPatched)
|
||||||
|
{
|
||||||
|
mPatched = true;
|
||||||
|
|
||||||
|
if (at == 0)
|
||||||
|
{
|
||||||
|
if (!mEntryRequiredRegs[reg])
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (mNumEntries > 1)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < mEntryBlocks.Size(); i++)
|
||||||
|
if (!mEntryBlocks[i]->CheckCrossBlockXFloodExit(block, reg))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (at < mIns.Size())
|
||||||
|
{
|
||||||
|
NativeCodeInstruction& ins(mIns[at]);
|
||||||
|
|
||||||
|
if (ins.mMode == ASMIM_INDIRECT_Y && (ins.mAddress == reg || ins.mAddress == reg + 1))
|
||||||
|
return false;
|
||||||
|
else if (ins.mMode == ASMIM_ZERO_PAGE && ins.mAddress == reg)
|
||||||
|
{
|
||||||
|
if (ins.mType == ASMIT_LDA)
|
||||||
|
{
|
||||||
|
if (!(ins.mLive & LIVE_MEM))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (ins.mType == ASMIT_INC || ins.mType == ASMIT_DEC)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else if (ins.mType == ASMIT_LDX)
|
||||||
|
{
|
||||||
|
return !(ins.mLive & (LIVE_MEM | LIVE_CPU_REG_Z));
|
||||||
|
}
|
||||||
|
else if (ins.mType == ASMIT_INC || ins.mType == ASMIT_DEC)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (ins.ChangesXReg() || ins.RequiresXReg() || ins.ChangesZeroPage(reg) || ins.ReferencesZeroPage(reg))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
at++;
|
||||||
|
}
|
||||||
|
|
||||||
|
mPatchExit = true;
|
||||||
|
|
||||||
|
if (mTrueJump && !mTrueJump->CheckCrossBlockXFlood(block, reg, 0))
|
||||||
|
return false;
|
||||||
|
if (mFalseJump && !mFalseJump->CheckCrossBlockXFlood(block, reg, 0))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NativeCodeBasicBlock::CheckCrossBlockXFloodExit(const NativeCodeBasicBlock* block, int reg)
|
||||||
|
{
|
||||||
|
if (!mPatchExit)
|
||||||
|
{
|
||||||
|
mPatchExit = true;
|
||||||
|
|
||||||
|
if (mTrueJump && !mTrueJump->CheckCrossBlockXFlood(block, reg, 0))
|
||||||
|
return false;
|
||||||
|
if (mFalseJump && !mFalseJump->CheckCrossBlockXFlood(block, reg, 0))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int at = mIns.Size() - 1;
|
||||||
|
while (at >= 0)
|
||||||
|
{
|
||||||
|
NativeCodeInstruction& ins(mIns[at]);
|
||||||
|
|
||||||
|
if (ins.mMode == ASMIM_INDIRECT_Y && (ins.mAddress == reg || ins.mAddress == reg + 1))
|
||||||
|
return false;
|
||||||
|
else if (ins.mMode == ASMIM_ZERO_PAGE && ins.mAddress == reg)
|
||||||
|
{
|
||||||
|
if (ins.mType == ASMIT_LDA)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else if (ins.mType == ASMIT_INC || ins.mType == ASMIT_DEC)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else if (ins.mType == ASMIT_STA || ins.mType == ASMIT_STX)
|
||||||
|
{
|
||||||
|
return !(ins.mLive & LIVE_CPU_REG_Z);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (ins.ChangesXReg() || ins.RequiresXReg() || ins.ChangesZeroPage(reg) || ins.ReferencesZeroPage(reg))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
at--;
|
||||||
|
}
|
||||||
|
|
||||||
|
mPatched = true;
|
||||||
|
|
||||||
|
for (int i = 0; i < mEntryBlocks.Size(); i++)
|
||||||
|
if (!mEntryBlocks[i]->CheckCrossBlockXFloodExit(block, reg))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NativeCodeBasicBlock::PatchCrossBlockXFloodExit(const NativeCodeBasicBlock* block, int reg)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
if (!mPatchExit)
|
||||||
|
{
|
||||||
|
mPatchExit = true;
|
||||||
|
|
||||||
|
mExitRequiredRegs += CPU_REG_X;
|
||||||
|
|
||||||
|
if (mTrueJump && mTrueJump->PatchCrossBlockXFlood(block, reg, 0))
|
||||||
|
changed = true;
|
||||||
|
if (mFalseJump && mFalseJump->PatchCrossBlockXFlood(block, reg, 0))
|
||||||
|
changed = true;
|
||||||
|
|
||||||
|
int at = mIns.Size() - 1;
|
||||||
|
while (at >= 0)
|
||||||
|
{
|
||||||
|
NativeCodeInstruction& ins(mIns[at]);
|
||||||
|
|
||||||
|
ins.mLive |= LIVE_CPU_REG_X;
|
||||||
|
|
||||||
|
if (ins.mMode == ASMIM_ZERO_PAGE && ins.mAddress == reg)
|
||||||
|
{
|
||||||
|
if (ins.mType == ASMIT_LDA)
|
||||||
|
{
|
||||||
|
ins.mType = ASMIT_TXA;
|
||||||
|
ins.mMode = ASMIM_IMPLIED;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else if (ins.mType == ASMIT_INC)
|
||||||
|
{
|
||||||
|
ins.mType = ASMIT_INX;
|
||||||
|
ins.mMode = ASMIM_IMPLIED;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else if (ins.mType == ASMIT_DEC)
|
||||||
|
{
|
||||||
|
ins.mType = ASMIT_DEX;
|
||||||
|
ins.mMode = ASMIM_IMPLIED;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else if (ins.mType == ASMIT_STA)
|
||||||
|
{
|
||||||
|
ins.mType = ASMIT_TAX;
|
||||||
|
ins.mMode = ASMIM_IMPLIED;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (ins.mType == ASMIT_STX)
|
||||||
|
{
|
||||||
|
ins.mType = ASMIT_NOP;
|
||||||
|
ins.mMode = ASMIM_IMPLIED;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
at--;
|
||||||
|
}
|
||||||
|
|
||||||
|
mPatched = true;
|
||||||
|
mEntryRequiredRegs += CPU_REG_X;
|
||||||
|
|
||||||
|
for (int i = 0; i < mEntryBlocks.Size(); i++)
|
||||||
|
if (mEntryBlocks[i]->PatchCrossBlockXFloodExit(block, reg))
|
||||||
|
changed = true;
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NativeCodeBasicBlock::PatchCrossBlockXFlood(const NativeCodeBasicBlock* block, int reg, int at)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
if (!mPatched)
|
||||||
|
{
|
||||||
|
mPatched = true;
|
||||||
|
|
||||||
|
if (at == 0)
|
||||||
|
{
|
||||||
|
if (!mEntryRequiredRegs[reg])
|
||||||
|
return false;
|
||||||
|
for (int i = 0; i < mEntryBlocks.Size(); i++)
|
||||||
|
if (mEntryBlocks[i]->PatchCrossBlockXFloodExit(block, reg))
|
||||||
|
changed = true;
|
||||||
|
mEntryRequiredRegs += CPU_REG_X;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (at < mIns.Size())
|
||||||
|
{
|
||||||
|
NativeCodeInstruction& ins(mIns[at]);
|
||||||
|
|
||||||
|
if (ins.mMode == ASMIM_ZERO_PAGE && ins.mAddress == reg)
|
||||||
|
{
|
||||||
|
if (ins.mType == ASMIT_LDA)
|
||||||
|
{
|
||||||
|
ins.mType = ASMIT_TXA;
|
||||||
|
ins.mMode = ASMIM_IMPLIED;
|
||||||
|
if (!(ins.mLive & LIVE_MEM))
|
||||||
|
return true;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else if (ins.mType == ASMIT_INC)
|
||||||
|
{
|
||||||
|
ins.mType = ASMIT_INX;
|
||||||
|
ins.mMode = ASMIM_IMPLIED;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else if (ins.mType == ASMIT_DEC)
|
||||||
|
{
|
||||||
|
ins.mType = ASMIT_DEX;
|
||||||
|
ins.mMode = ASMIM_IMPLIED;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else if (ins.mType == ASMIT_LDX)
|
||||||
|
{
|
||||||
|
ins.mType = ASMIT_NOP;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ins.mLive |= LIVE_CPU_REG_X;
|
||||||
|
|
||||||
|
at++;
|
||||||
|
}
|
||||||
|
|
||||||
|
mPatchExit = true;
|
||||||
|
|
||||||
|
mExitRequiredRegs |= CPU_REG_X;
|
||||||
|
|
||||||
|
if (mTrueJump && mTrueJump->PatchCrossBlockXFlood(block, reg, 0))
|
||||||
|
changed = true;
|
||||||
|
if (mFalseJump && mFalseJump->PatchCrossBlockXFlood(block, reg, 0))
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool NativeCodeBasicBlock::CheckCrossBlockYFlood(const NativeCodeBasicBlock* block, int reg, int at)
|
||||||
|
{
|
||||||
|
if (at == 0 && this == block)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!mPatched)
|
||||||
|
{
|
||||||
|
mPatched = true;
|
||||||
|
|
||||||
|
if (at == 0)
|
||||||
|
{
|
||||||
|
if (!mEntryRequiredRegs[reg])
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (mNumEntries > 1)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < mEntryBlocks.Size(); i++)
|
||||||
|
if (!mEntryBlocks[i]->CheckCrossBlockYFloodExit(block, reg))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (at < mIns.Size())
|
||||||
|
{
|
||||||
|
NativeCodeInstruction& ins(mIns[at]);
|
||||||
|
|
||||||
|
if (ins.mMode == ASMIM_INDIRECT_Y && (ins.mAddress == reg || ins.mAddress == reg + 1))
|
||||||
|
return false;
|
||||||
|
else if (ins.mMode == ASMIM_ZERO_PAGE && ins.mAddress == reg)
|
||||||
|
{
|
||||||
|
if (ins.mType == ASMIT_LDA)
|
||||||
|
{
|
||||||
|
if (!(ins.mLive & LIVE_MEM))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (ins.mType == ASMIT_INC || ins.mType == ASMIT_DEC)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else if (ins.mType == ASMIT_LDY)
|
||||||
|
{
|
||||||
|
return !(ins.mLive & (LIVE_MEM | LIVE_CPU_REG_Z));
|
||||||
|
}
|
||||||
|
else if (ins.mType == ASMIT_INC || ins.mType == ASMIT_DEC)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (ins.ChangesYReg() || ins.RequiresYReg() || ins.ChangesZeroPage(reg) || ins.ReferencesZeroPage(reg))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
at++;
|
||||||
|
}
|
||||||
|
|
||||||
|
mPatchExit = true;
|
||||||
|
|
||||||
|
if (mTrueJump && !mTrueJump->CheckCrossBlockYFlood(block, reg, 0))
|
||||||
|
return false;
|
||||||
|
if (mFalseJump && !mFalseJump->CheckCrossBlockYFlood(block, reg, 0))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NativeCodeBasicBlock::CheckCrossBlockYFloodExit(const NativeCodeBasicBlock* block, int reg)
|
||||||
|
{
|
||||||
|
if (!mPatchExit)
|
||||||
|
{
|
||||||
|
mPatchExit = true;
|
||||||
|
|
||||||
|
if (mTrueJump && !mTrueJump->CheckCrossBlockYFlood(block, reg, 0))
|
||||||
|
return false;
|
||||||
|
if (mFalseJump && !mFalseJump->CheckCrossBlockYFlood(block, reg, 0))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int at = mIns.Size() - 1;
|
||||||
|
while (at >= 0)
|
||||||
|
{
|
||||||
|
NativeCodeInstruction& ins(mIns[at]);
|
||||||
|
|
||||||
|
if (ins.mMode == ASMIM_INDIRECT_Y && (ins.mAddress == reg || ins.mAddress == reg + 1))
|
||||||
|
return false;
|
||||||
|
else if (ins.mMode == ASMIM_ZERO_PAGE && ins.mAddress == reg)
|
||||||
|
{
|
||||||
|
if (ins.mType == ASMIT_LDA)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else if (ins.mType == ASMIT_INC || ins.mType == ASMIT_DEC)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else if (ins.mType == ASMIT_STA || ins.mType == ASMIT_STY)
|
||||||
|
{
|
||||||
|
return !(ins.mLive & LIVE_CPU_REG_Z);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (ins.ChangesYReg() || ins.RequiresYReg() || ins.ChangesZeroPage(reg) || ins.ReferencesZeroPage(reg))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
at--;
|
||||||
|
}
|
||||||
|
|
||||||
|
mPatched = true;
|
||||||
|
|
||||||
|
for (int i = 0; i < mEntryBlocks.Size(); i++)
|
||||||
|
if (!mEntryBlocks[i]->CheckCrossBlockYFloodExit(block, reg))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NativeCodeBasicBlock::PatchCrossBlockYFloodExit(const NativeCodeBasicBlock* block, int reg)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
if (!mPatchExit)
|
||||||
|
{
|
||||||
|
mPatchExit = true;
|
||||||
|
|
||||||
|
mExitRequiredRegs += CPU_REG_Y;
|
||||||
|
|
||||||
|
if (mTrueJump && mTrueJump->PatchCrossBlockYFlood(block, reg, 0))
|
||||||
|
changed = true;
|
||||||
|
if (mFalseJump && mFalseJump->PatchCrossBlockYFlood(block, reg, 0))
|
||||||
|
changed = true;
|
||||||
|
|
||||||
|
int at = mIns.Size() - 1;
|
||||||
|
while (at >= 0)
|
||||||
|
{
|
||||||
|
NativeCodeInstruction& ins(mIns[at]);
|
||||||
|
|
||||||
|
ins.mLive |= LIVE_CPU_REG_Y;
|
||||||
|
|
||||||
|
if (ins.mMode == ASMIM_ZERO_PAGE && ins.mAddress == reg)
|
||||||
|
{
|
||||||
|
if (ins.mType == ASMIT_LDA)
|
||||||
|
{
|
||||||
|
ins.mType = ASMIT_TYA;
|
||||||
|
ins.mMode = ASMIM_IMPLIED;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else if (ins.mType == ASMIT_INC)
|
||||||
|
{
|
||||||
|
ins.mType = ASMIT_INY;
|
||||||
|
ins.mMode = ASMIM_IMPLIED;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else if (ins.mType == ASMIT_DEC)
|
||||||
|
{
|
||||||
|
ins.mType = ASMIT_DEY;
|
||||||
|
ins.mMode = ASMIM_IMPLIED;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else if (ins.mType == ASMIT_STA)
|
||||||
|
{
|
||||||
|
ins.mType = ASMIT_TAY;
|
||||||
|
ins.mMode = ASMIM_IMPLIED;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (ins.mType == ASMIT_STY)
|
||||||
|
{
|
||||||
|
ins.mType = ASMIT_NOP;
|
||||||
|
ins.mMode = ASMIM_IMPLIED;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
at--;
|
||||||
|
}
|
||||||
|
|
||||||
|
mPatched = true;
|
||||||
|
mEntryRequiredRegs += CPU_REG_Y;
|
||||||
|
|
||||||
|
for (int i = 0; i < mEntryBlocks.Size(); i++)
|
||||||
|
if (mEntryBlocks[i]->PatchCrossBlockYFloodExit(block, reg))
|
||||||
|
changed = true;
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NativeCodeBasicBlock::PatchCrossBlockYFlood(const NativeCodeBasicBlock* block, int reg, int at)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
if (!mPatched)
|
||||||
|
{
|
||||||
|
mPatched = true;
|
||||||
|
|
||||||
|
if (at == 0)
|
||||||
|
{
|
||||||
|
if (!mEntryRequiredRegs[reg])
|
||||||
|
return false;
|
||||||
|
for (int i = 0; i < mEntryBlocks.Size(); i++)
|
||||||
|
if (mEntryBlocks[i]->PatchCrossBlockYFloodExit(block, reg))
|
||||||
|
changed = true;
|
||||||
|
mEntryRequiredRegs += CPU_REG_Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (at < mIns.Size())
|
||||||
|
{
|
||||||
|
NativeCodeInstruction& ins(mIns[at]);
|
||||||
|
|
||||||
|
if (ins.mMode == ASMIM_ZERO_PAGE && ins.mAddress == reg)
|
||||||
|
{
|
||||||
|
if (ins.mType == ASMIT_LDA)
|
||||||
|
{
|
||||||
|
ins.mType = ASMIT_TYA;
|
||||||
|
ins.mMode = ASMIM_IMPLIED;
|
||||||
|
if (!(ins.mLive & LIVE_MEM))
|
||||||
|
return true;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else if (ins.mType == ASMIT_INC)
|
||||||
|
{
|
||||||
|
ins.mType = ASMIT_INY;
|
||||||
|
ins.mMode = ASMIM_IMPLIED;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else if (ins.mType == ASMIT_DEC)
|
||||||
|
{
|
||||||
|
ins.mType = ASMIT_DEY;
|
||||||
|
ins.mMode = ASMIM_IMPLIED;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else if (ins.mType == ASMIT_LDY)
|
||||||
|
{
|
||||||
|
ins.mType = ASMIT_NOP;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ins.mLive |= LIVE_CPU_REG_Y;
|
||||||
|
|
||||||
|
at++;
|
||||||
|
}
|
||||||
|
|
||||||
|
mPatchExit = true;
|
||||||
|
|
||||||
|
mExitRequiredRegs |= CPU_REG_Y;
|
||||||
|
|
||||||
|
if (mTrueJump && mTrueJump->PatchCrossBlockYFlood(block, reg, 0))
|
||||||
|
changed = true;
|
||||||
|
if (mFalseJump && mFalseJump->PatchCrossBlockYFlood(block, reg, 0))
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool NativeCodeBasicBlock::IsDominatedBy(const NativeCodeBasicBlock* block) const
|
bool NativeCodeBasicBlock::IsDominatedBy(const NativeCodeBasicBlock* block) const
|
||||||
{
|
{
|
||||||
|
@ -22580,7 +23239,7 @@ bool NativeCodeBasicBlock::BitFieldForwarding(const NativeRegisterDataSet& data)
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NativeCodeBasicBlock::GlobalValueForwarding(void)
|
bool NativeCodeBasicBlock::GlobalValueForwarding(bool final)
|
||||||
{
|
{
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
|
||||||
|
@ -22610,16 +23269,16 @@ bool NativeCodeBasicBlock::GlobalValueForwarding(void)
|
||||||
{
|
{
|
||||||
AsmInsType carryop;
|
AsmInsType carryop;
|
||||||
|
|
||||||
if (mIns[i].ValueForwarding(mDataSet, carryop, true, false))
|
if (mIns[i].ValueForwarding(mDataSet, carryop, true, final))
|
||||||
changed = true;
|
changed = true;
|
||||||
if (carryop != ASMIT_NOP)
|
if (carryop != ASMIT_NOP)
|
||||||
mIns.Insert(i + 1, NativeCodeInstruction(carryop));
|
mIns.Insert(i + 1, NativeCodeInstruction(carryop));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (this->mTrueJump && this->mTrueJump->GlobalValueForwarding())
|
if (this->mTrueJump && this->mTrueJump->GlobalValueForwarding(final))
|
||||||
changed = true;
|
changed = true;
|
||||||
if (this->mFalseJump && this->mFalseJump->GlobalValueForwarding())
|
if (this->mFalseJump && this->mFalseJump->GlobalValueForwarding(final))
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30720,6 +31379,21 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
mIns[i + 2].mLive |= LIVE_CPU_REG_A;
|
mIns[i + 2].mLive |= LIVE_CPU_REG_A;
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
mIns[i + 1].mType == ASMIT_SEC &&
|
||||||
|
mIns[i + 2].mType == ASMIT_LDA && !mIns[i + 2].SameEffectiveAddress(mIns[i + 0]) &&
|
||||||
|
mIns[i + 3].mType == ASMIT_SBC && mIns[i + 3].SameEffectiveAddress(mIns[i + 0]) && !(mIns[i + 3].mLive & LIVE_MEM))
|
||||||
|
{
|
||||||
|
mIns[i + 0].mType = ASMIT_EOR;
|
||||||
|
mIns[i + 0].mMode = ASMIM_IMMEDIATE;
|
||||||
|
mIns[i + 0].mAddress = 0xff;
|
||||||
|
mIns[i + 0].mLive |= LIVE_CPU_REG_A;
|
||||||
|
mIns[i + 1].mLive |= LIVE_CPU_REG_A;
|
||||||
|
mIns[i + 2].mType = ASMIT_ADC;
|
||||||
|
mIns[i + 3].mType = ASMIT_NOP; mIns[i + 3].mMode = ASMIM_IMPLIED;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
else if (
|
else if (
|
||||||
mIns[i + 0].mType == ASMIT_CLC &&
|
mIns[i + 0].mType == ASMIT_CLC &&
|
||||||
mIns[i + 1].mType == ASMIT_ADC && mIns[i + 1].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mAddress < 4 &&
|
mIns[i + 1].mType == ASMIT_ADC && mIns[i + 1].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mAddress < 4 &&
|
||||||
|
@ -31487,7 +32161,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
if (mFalseJump)
|
if (mFalseJump)
|
||||||
mFalseJump->CheckLive();
|
mFalseJump->CheckLive();
|
||||||
#if 1
|
#if 1
|
||||||
if (i + 1 < mIns.Size())
|
if (pass < 7 && i + 1 < mIns.Size())
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
mIns[i + 0].mType == ASMIT_LDA && (mIns[i + 0].mMode == ASMIM_ABSOLUTE || mIns[i + 0].mMode == ASMIM_ABSOLUTE_X || mIns[i + 0].mMode == ASMIM_ABSOLUTE_Y || mIns[i + 0].mMode == ASMIM_INDIRECT_Y) &&
|
mIns[i + 0].mType == ASMIT_LDA && (mIns[i + 0].mMode == ASMIM_ABSOLUTE || mIns[i + 0].mMode == ASMIM_ABSOLUTE_X || mIns[i + 0].mMode == ASMIM_ABSOLUTE_Y || mIns[i + 0].mMode == ASMIM_INDIRECT_Y) &&
|
||||||
|
@ -33797,7 +34471,7 @@ void NativeCodeProcedure::RebuildEntry(void)
|
||||||
|
|
||||||
void NativeCodeProcedure::Optimize(void)
|
void NativeCodeProcedure::Optimize(void)
|
||||||
{
|
{
|
||||||
CheckFunc = !strcmp(mInterProc->mIdent->mString, "missile_animate");
|
CheckFunc = !strcmp(mInterProc->mIdent->mString, "heapcheck");
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
int step = 0;
|
int step = 0;
|
||||||
|
@ -33903,7 +34577,7 @@ void NativeCodeProcedure::Optimize(void)
|
||||||
if (step > 1)
|
if (step > 1)
|
||||||
{
|
{
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
if (mEntryBlock->GlobalValueForwarding())
|
if (mEntryBlock->GlobalValueForwarding(step == 7))
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -34289,6 +34963,15 @@ void NativeCodeProcedure::Optimize(void)
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
if (step == 7)
|
||||||
|
{
|
||||||
|
ResetVisited();
|
||||||
|
if (mEntryBlock->CrossBlockXYFlood(this))
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
if (step >= 6)
|
if (step >= 6)
|
||||||
{
|
{
|
||||||
|
@ -34369,7 +35052,7 @@ void NativeCodeProcedure::Optimize(void)
|
||||||
mEntryBlock->CheckVisited();
|
mEntryBlock->CheckVisited();
|
||||||
|
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
if (mEntryBlock->GlobalValueForwarding())
|
if (mEntryBlock->GlobalValueForwarding(true))
|
||||||
changed = true;
|
changed = true;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -34468,6 +35151,7 @@ void NativeCodeProcedure::ResetPatched(void)
|
||||||
mBlocks[i]->mPatchStart = false;
|
mBlocks[i]->mPatchStart = false;
|
||||||
mBlocks[i]->mPatchLoop = false;
|
mBlocks[i]->mPatchLoop = false;
|
||||||
mBlocks[i]->mPatchLoopChanged = false;
|
mBlocks[i]->mPatchLoopChanged = false;
|
||||||
|
mBlocks[i]->mPatchExit = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ struct NativeRegisterDataSet
|
||||||
|
|
||||||
void ResetZeroPage(int addr);
|
void ResetZeroPage(int addr);
|
||||||
void ResetAbsolute(LinkerObject * linkerObject, int addr);
|
void ResetAbsolute(LinkerObject * linkerObject, int addr);
|
||||||
|
int FindAbsolute(LinkerObject* linkerObject, int addr);
|
||||||
void ResetIndirect(int reg);
|
void ResetIndirect(int reg);
|
||||||
void ResetX(void);
|
void ResetX(void);
|
||||||
void ResetY(void);
|
void ResetY(void);
|
||||||
|
@ -177,7 +178,7 @@ public:
|
||||||
GrowingArray<NativeCodeBasicBlock*> mEntryBlocks;
|
GrowingArray<NativeCodeBasicBlock*> mEntryBlocks;
|
||||||
|
|
||||||
int mOffset, mSize, mPlace, mNumEntries, mNumEntered, mFrameOffset, mTemp;
|
int mOffset, mSize, mPlace, mNumEntries, mNumEntered, mFrameOffset, mTemp;
|
||||||
bool mPlaced, mCopied, mKnownShortBranch, mBypassed, mAssembled, mNoFrame, mVisited, mLoopHead, mVisiting, mLocked, mPatched, mPatchFail, mPatchChecked, mPatchStart, mPatchLoop, mPatchLoopChanged;
|
bool mPlaced, mCopied, mKnownShortBranch, mBypassed, mAssembled, mNoFrame, mVisited, mLoopHead, mVisiting, mLocked, mPatched, mPatchFail, mPatchChecked, mPatchStart, mPatchLoop, mPatchLoopChanged, mPatchExit;
|
||||||
bool mEntryRegA, mEntryRegX, mEntryRegY, mExitRegA, mExitRegX;
|
bool mEntryRegA, mEntryRegX, mEntryRegY, mExitRegA, mExitRegX;
|
||||||
NativeCodeBasicBlock * mDominator, * mSameBlock;
|
NativeCodeBasicBlock * mDominator, * mSameBlock;
|
||||||
|
|
||||||
|
@ -386,7 +387,7 @@ public:
|
||||||
bool ReverseReplaceTAX(int at);
|
bool ReverseReplaceTAX(int at);
|
||||||
|
|
||||||
bool ValueForwarding(const NativeRegisterDataSet& data, bool global, bool final);
|
bool ValueForwarding(const NativeRegisterDataSet& data, bool global, bool final);
|
||||||
bool GlobalValueForwarding(void);
|
bool GlobalValueForwarding(bool final);
|
||||||
bool BitFieldForwarding(const NativeRegisterDataSet& data);
|
bool BitFieldForwarding(const NativeRegisterDataSet& data);
|
||||||
bool ReverseBitfieldForwarding(void);
|
bool ReverseBitfieldForwarding(void);
|
||||||
|
|
||||||
|
@ -501,11 +502,24 @@ public:
|
||||||
bool CheckForwardSumYPointer(const NativeCodeBasicBlock* block, int reg, int base, const NativeCodeInstruction & iins, int at, int yval);
|
bool CheckForwardSumYPointer(const NativeCodeBasicBlock* block, int reg, int base, const NativeCodeInstruction & iins, int at, int yval);
|
||||||
bool PatchForwardSumYPointer(const NativeCodeBasicBlock* block, int reg, int base, const NativeCodeInstruction & iins, int at, int yval);
|
bool PatchForwardSumYPointer(const NativeCodeBasicBlock* block, int reg, int base, const NativeCodeInstruction & iins, int at, int yval);
|
||||||
|
|
||||||
|
bool CrossBlockXYFlood(NativeCodeProcedure * proc);
|
||||||
|
|
||||||
|
bool CheckCrossBlockXFlood(const NativeCodeBasicBlock* block, int reg, int at);
|
||||||
|
bool CheckCrossBlockXFloodExit(const NativeCodeBasicBlock* block, int reg);
|
||||||
|
bool PatchCrossBlockXFlood(const NativeCodeBasicBlock* block, int reg, int at);
|
||||||
|
bool PatchCrossBlockXFloodExit(const NativeCodeBasicBlock* block, int reg);
|
||||||
|
|
||||||
|
bool CheckCrossBlockYFlood(const NativeCodeBasicBlock* block, int reg, int at);
|
||||||
|
bool CheckCrossBlockYFloodExit(const NativeCodeBasicBlock* block, int reg);
|
||||||
|
bool PatchCrossBlockYFlood(const NativeCodeBasicBlock* block, int reg, int at);
|
||||||
|
bool PatchCrossBlockYFloodExit(const NativeCodeBasicBlock* block, int reg);
|
||||||
|
|
||||||
bool IsDominatedBy(const NativeCodeBasicBlock* block) const;
|
bool IsDominatedBy(const NativeCodeBasicBlock* block) const;
|
||||||
|
|
||||||
void CheckLive(void);
|
void CheckLive(void);
|
||||||
void CheckBlocks(bool sequence = false);
|
void CheckBlocks(bool sequence = false);
|
||||||
void CheckVisited(void);
|
void CheckVisited(void);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class NativeCodeProcedure
|
class NativeCodeProcedure
|
||||||
|
|
|
@ -74,7 +74,7 @@ int main2(int argc, const char** argv)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
strcpy(strProductName, "oscar64");
|
strcpy(strProductName, "oscar64");
|
||||||
strcpy(strProductVersion, "1.15.182");
|
strcpy(strProductVersion, "1.15.183");
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
uint32_t length = sizeof(basePath);
|
uint32_t length = sizeof(basePath);
|
||||||
|
|
|
@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,15,182,0
|
FILEVERSION 1,15,183,0
|
||||||
PRODUCTVERSION 1,15,182,0
|
PRODUCTVERSION 1,15,183,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -43,12 +43,12 @@ BEGIN
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "oscar64"
|
VALUE "CompanyName", "oscar64"
|
||||||
VALUE "FileDescription", "oscar64 compiler"
|
VALUE "FileDescription", "oscar64 compiler"
|
||||||
VALUE "FileVersion", "1.15.182.0"
|
VALUE "FileVersion", "1.15.183.0"
|
||||||
VALUE "InternalName", "oscar64.exe"
|
VALUE "InternalName", "oscar64.exe"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2021"
|
VALUE "LegalCopyright", "Copyright (C) 2021"
|
||||||
VALUE "OriginalFilename", "oscar64.exe"
|
VALUE "OriginalFilename", "oscar64.exe"
|
||||||
VALUE "ProductName", "oscar64"
|
VALUE "ProductName", "oscar64"
|
||||||
VALUE "ProductVersion", "1.15.182.0"
|
VALUE "ProductVersion", "1.15.183.0"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
|
@ -4554,15 +4554,15 @@
|
||||||
{
|
{
|
||||||
"Name" = "8:Microsoft Visual Studio"
|
"Name" = "8:Microsoft Visual Studio"
|
||||||
"ProductName" = "8:oscar64"
|
"ProductName" = "8:oscar64"
|
||||||
"ProductCode" = "8:{D9D7E97A-B793-4546-B204-9518010E2DB9}"
|
"ProductCode" = "8:{0316346F-2B7D-478A-BD0C-8AAF6E0371EA}"
|
||||||
"PackageCode" = "8:{40E0B5C5-53B2-4285-802B-FBA08B4E661D}"
|
"PackageCode" = "8:{BAD074A9-2FC1-4FF7-B987-B330F1B645A2}"
|
||||||
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
|
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
|
||||||
"AspNetVersion" = "8:2.0.50727.0"
|
"AspNetVersion" = "8:2.0.50727.0"
|
||||||
"RestartWWWService" = "11:FALSE"
|
"RestartWWWService" = "11:FALSE"
|
||||||
"RemovePreviousVersions" = "11:TRUE"
|
"RemovePreviousVersions" = "11:TRUE"
|
||||||
"DetectNewerInstalledVersion" = "11:TRUE"
|
"DetectNewerInstalledVersion" = "11:TRUE"
|
||||||
"InstallAllUsers" = "11:FALSE"
|
"InstallAllUsers" = "11:FALSE"
|
||||||
"ProductVersion" = "8:1.15.182"
|
"ProductVersion" = "8:1.15.183"
|
||||||
"Manufacturer" = "8:oscar64"
|
"Manufacturer" = "8:oscar64"
|
||||||
"ARPHELPTELEPHONE" = "8:"
|
"ARPHELPTELEPHONE" = "8:"
|
||||||
"ARPHELPLINK" = "8:"
|
"ARPHELPLINK" = "8:"
|
||||||
|
|
Loading…
Reference in New Issue