Shuffle temp moves to avoid duplicates

This commit is contained in:
drmortalwombat 2023-01-21 08:42:22 +01:00
parent 16faec8627
commit 677de2508b
6 changed files with 277 additions and 84 deletions

View File

@ -1162,8 +1162,11 @@ void bmu_bitblit(const Bitmap * dbm, int dx, int dy, const Bitmap * sbm, int sx,
int sstride = 8 * sbm->cwidth - 8;
int dstride = 8 * dbm->cwidth - 8;
if (pattern)
if (op & BLIT_SRC)
{
if (!pattern)
pattern = sp;
if (reverse)
{
sstride = -sstride;
@ -1202,41 +1205,29 @@ void bmu_bitblit(const Bitmap * dbm, int dx, int dy, const Bitmap * sbm, int sx,
}
}
}
else
{
if (reverse)
{
sstride = -sstride;
dstride = -dstride;
for(char y=h; y>0; y--)
{
if (((int)sp & 7) == 0)
sp += sstride;
sp--;
if (((int)dp & 7) == 0)
dp += dstride;
dp--;
callddop(sp, dp, 0);
}
}
else
else if (op & BLIT_PATTERN)
{
for(char y=h; y>0; y--)
{
callddop(sp, dp, 0);
char pi = (int)dp & 7;
sp++;
if (((int)sp & 7) == 0)
sp += sstride;
callddop(dp, dp, pat[pi]);
dp++;
if (((int)dp & 7) == 0)
dp += dstride;
}
}
else
{
for(char y=h; y>0; y--)
{
callddop(dp, dp, 0);
dp++;
if (((int)dp & 7) == 0)
dp += dstride;
}
}
}
@ -1244,30 +1235,35 @@ void bmu_bitblit(const Bitmap * dbm, int dx, int dy, const Bitmap * sbm, int sx,
void bm_bitblit(const Bitmap * dbm, const ClipRect * clip, int dx, int dy, const Bitmap * sbm, int sx, int sy, int w, int h, const char * pattern, BlitOp op)
{
if (dx >= clip->right || dy >= clip->bottom)
return;
int d;
if (dx < clip->left)
d = dx - clip->left;
if (d < 0)
{
int d = clip->left - dx;
dx += d;
sx += d;
w -= d;
dx -= d;
sx -= d;
w += d;
}
if (dy < clip->top)
d = dy - clip->top;
if (d < 0)
{
int d = clip->top - dy;
dy += d;
sy += d;
h -= d;
dy -= d;
sy -= d;
h += d;
}
if (dx + w > clip->right)
w = clip->right - dx;
d = clip->right - dx - w;
if (dy + h > clip->bottom)
h = clip->bottom - dy;
if (d < 0)
w += d;
d = clip->bottom - dy - h;
if (d < 0)
h += d;
if (w > 0 && h > 0)
bmu_bitblit(dbm, dx, dy, sbm, sx, sy, w, h, pattern, op);

View File

@ -160,8 +160,11 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec)
int numfpzero = BC_REG_FPARAMS_END - BC_REG_FPARAMS;
int fplimit = numfpzero;
if ((procDec->mFlags & DTF_NATIVE) || (mCompilerOptions & COPT_NATIVE))
{
if (!(procDec->mFlags & DTF_FUNC_INTRCALLED))
fplimit += 256;
}
if (procDec->mBase->mBase->mType == DT_TYPE_STRUCT)
{

View File

@ -1578,7 +1578,7 @@ bool InterInstruction::IsEqualSource(const InterInstruction* ins) const
void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams, const GrowingVariableArray& staticVars)
{
int i, value, temp;
int i, temp;
temp = ins->mDst.mTemp;
@ -3004,7 +3004,7 @@ bool InterInstruction::PropagateConstTemps(const GrowingInstructionPtrArray& cte
return false;
}
void InterInstruction::PerformTempForwarding(TempForwardingTable& forwardingTable)
void InterInstruction::PerformTempForwarding(TempForwardingTable& forwardingTable, bool reverse)
{
if (mCode != IC_NONE)
{
@ -3014,6 +3014,9 @@ void InterInstruction::PerformTempForwarding(TempForwardingTable& forwardingTabl
}
if (mCode == IC_LOAD_TEMPORARY && mDst.mTemp != mSrc[0].mTemp)
{
if (reverse)
forwardingTable.Build(mSrc[0].mTemp, mDst.mTemp);
else
forwardingTable.Build(mDst.mTemp, mSrc[0].mTemp);
}
}
@ -7050,7 +7053,7 @@ bool InterCodeBasicBlock::CalculateSingleAssignmentTemps(FastNumberSet& tassigne
return changed;
}
void InterCodeBasicBlock::PerformTempForwarding(const TempForwardingTable& forwardingTable)
void InterCodeBasicBlock::PerformTempForwarding(const TempForwardingTable& forwardingTable, bool reverse)
{
int i;
@ -7089,11 +7092,11 @@ void InterCodeBasicBlock::PerformTempForwarding(const TempForwardingTable& forwa
for (i = 0; i < mInstructions.Size(); i++)
{
mInstructions[i]->PerformTempForwarding(mMergeForwardingTable);
mInstructions[i]->PerformTempForwarding(mMergeForwardingTable, reverse);
}
if (mTrueJump) mTrueJump->PerformTempForwarding(mMergeForwardingTable);
if (mFalseJump) mFalseJump->PerformTempForwarding(mMergeForwardingTable);
if (mTrueJump) mTrueJump->PerformTempForwarding(mMergeForwardingTable, reverse);
if (mFalseJump) mFalseJump->PerformTempForwarding(mMergeForwardingTable, reverse);
}
}
@ -9008,7 +9011,8 @@ void InterCodeBasicBlock::MapVariables(GrowingVariableArray& globalVars, Growing
break;
case IC_STORE:
if (mInstructions[i]->mSrc[1].mMemory == IM_LOCAL)
case IC_LEA:
if (mInstructions[i]->mSrc[1].mTemp < 0 && mInstructions[i]->mSrc[1].mMemory == IM_LOCAL)
{
localVars[mInstructions[i]->mSrc[1].mVarIndex]->mUsed = true;
}
@ -9016,7 +9020,7 @@ void InterCodeBasicBlock::MapVariables(GrowingVariableArray& globalVars, Growing
case IC_LOAD:
case IC_CALL_NATIVE:
if (mInstructions[i]->mSrc[0].mMemory == IM_LOCAL)
if (mInstructions[i]->mSrc[0].mTemp < 0 && mInstructions[i]->mSrc[0].mMemory == IM_LOCAL)
{
localVars[mInstructions[i]->mSrc[0].mVarIndex]->mUsed = true;
}
@ -9024,11 +9028,11 @@ void InterCodeBasicBlock::MapVariables(GrowingVariableArray& globalVars, Growing
case IC_COPY:
case IC_STRCPY:
if (mInstructions[i]->mSrc[0].mMemory == IM_LOCAL)
if (mInstructions[i]->mSrc[0].mTemp < 0 && mInstructions[i]->mSrc[0].mMemory == IM_LOCAL)
{
localVars[mInstructions[i]->mSrc[0].mVarIndex]->mUsed = true;
}
if (mInstructions[i]->mSrc[1].mMemory == IM_LOCAL)
if (mInstructions[i]->mSrc[1].mTemp < 0 && mInstructions[i]->mSrc[1].mMemory == IM_LOCAL)
{
localVars[mInstructions[i]->mSrc[1].mVarIndex]->mUsed = true;
}
@ -9687,8 +9691,6 @@ bool InterCodeBasicBlock::IsTempReferencedOnPath(int temp, int at) const
bool InterCodeBasicBlock::PushSinglePathResultInstructions(void)
{
int i;
bool changed = false;
if (!mVisited)
@ -13451,7 +13453,7 @@ void InterCodeProcedure::WarnUsedUndefinedVariables(void)
}
void InterCodeProcedure::TempForwarding(void)
void InterCodeProcedure::TempForwarding(bool reverse)
{
int numTemps = mTemporaries.Size();
@ -13468,7 +13470,7 @@ void InterCodeProcedure::TempForwarding(void)
mTempForwardingTable.Reset();
ResetVisited();
mEntryBlock->PerformTempForwarding(mTempForwardingTable);
mEntryBlock->PerformTempForwarding(mTempForwardingTable, reverse);
DisassembleDebug("temp forwarding");
}
@ -14000,7 +14002,7 @@ void InterCodeProcedure::Close(void)
mTempForwardingTable.SetSize(numTemps);
ResetVisited();
mEntryBlock->PerformTempForwarding(mTempForwardingTable);
mEntryBlock->PerformTempForwarding(mTempForwardingTable, false);
DisassembleDebug("temp forwarding 2");
@ -14404,7 +14406,7 @@ void InterCodeProcedure::Close(void)
#if 1
ResetVisited();
if (!mInterruptCalled && mEntryBlock->CheckStaticStack())
if (!mInterruptCalled && mNativeProcedure && mEntryBlock->CheckStaticStack())
{
mLinkerObject->mFlags |= LOBJF_STATIC_STACK;
mLinkerObject->mStackSection = mModule->mLinker->AddSection(mIdent->Mangle("@stack"), LST_STATIC_STACK);
@ -14467,10 +14469,22 @@ void InterCodeProcedure::Close(void)
MergeBasicBlocks();
DisassembleDebug("TempForward Rev 1");
BuildDataFlowSets();
TempForwarding(true);
RemoveUnusedInstructions();
BuildDataFlowSets();
DisassembleDebug("TempForward Rev 2");
TempForwarding();
DisassembleDebug("TempForward Rev 3");
BuildLoopPrefix();
BuildDataFlowSets();
@ -14578,6 +14592,14 @@ void InterCodeProcedure::MapVariables(void)
mLocalSize = 0;
for (int i = 0; i < mLocalVars.Size(); i++)
{
#if 0
if (mLocalVars[i])
{
printf("MapVars %s, %d: %s %d %d\n",
mIdent->mString, i, mLocalVars[i]->mIdent ? mLocalVars[i]->mIdent->mString : "?",
mLocalVars[i]->mUsed, mLocalVars[i]->mSize);
}
#endif
if (mLocalVars[i] && mLocalVars[i]->mUsed && !mLocalVars[i]->mLinkerObject)
{
mLocalVars[i]->mOffset = mLocalSize;

View File

@ -316,7 +316,7 @@ public:
void LocalRenameRegister(GrowingIntArray& renameTable, int& num);
void GlobalRenameRegister(const GrowingIntArray& renameTable, GrowingTypeArray& temporaries);
void PerformTempForwarding(TempForwardingTable& forwardingTable);
void PerformTempForwarding(TempForwardingTable& forwardingTable, bool reverse);
bool PropagateConstTemps(const GrowingInstructionPtrArray& ctemps);
void BuildCollisionTable(NumberSet& liveTemps, NumberSet* collisionSets);
@ -435,7 +435,7 @@ public:
void GlobalRenameRegister(const GrowingIntArray& renameTable, GrowingTypeArray& temporaries);
void CheckValueUsage(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue, const GrowingVariableArray& staticVars);
void PerformTempForwarding(const TempForwardingTable& forwardingTable);
void PerformTempForwarding(const TempForwardingTable& forwardingTable, bool reverse);
void PerformValueForwarding(const GrowingInstructionPtrArray& tvalue, const ValueSet& values, FastNumberSet& tvalid, const NumberSet& aliasedLocals, const NumberSet& aliasedParams, int & spareTemps, const GrowingVariableArray& staticVars);
void PerformMachineSpecificValueUsageCheck(const GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid, const GrowingVariableArray& staticVars);
bool EliminateDeadBranches(void);
@ -587,7 +587,7 @@ protected:
void BuildTraces(bool expand, bool dominators = true, bool compact = false);
void BuildDataFlowSets(void);
void RenameTemporaries(void);
void TempForwarding(void);
void TempForwarding(bool reverse = false);
void RemoveUnusedInstructions(void);
bool GlobalConstantPropagation(void);
bool PropagateNonLocalUsedTemps(void);

View File

@ -713,7 +713,7 @@ bool NativeCodeInstruction::ChangesAccuAndFlag(void) const
{
if (mType == ASMIT_LDA || mType == ASMIT_TXA || mType == ASMIT_TYA ||
mType == ASMIT_ORA || mType == ASMIT_AND || mType == ASMIT_EOR ||
mType == ASMIT_SBC || mType == ASMIT_ADC || mType == ASMIT_JSR)
mType == ASMIT_SBC || mType == ASMIT_ADC)
return true;
else if (mType == ASMIT_LSR || mType == ASMIT_ASL || mType == ASMIT_ROR || mType == ASMIT_ROL)
return mMode == ASMIM_IMPLIED;
@ -721,6 +721,34 @@ bool NativeCodeInstruction::ChangesAccuAndFlag(void) const
return false;
}
uint32 NativeCodeInstruction::NeedsLive(void) const
{
uint32 live = mLive;
if (mMode == ASMIM_ABSOLUTE_Y || mMode == ASMIM_INDIRECT_Y || mMode == ASMIM_ZERO_PAGE_Y)
live |= LIVE_CPU_REG_Y;
if (mMode == ASMIM_ABSOLUTE_X || mMode == ASMIM_INDIRECT_X || mMode == ASMIM_ZERO_PAGE_X)
live |= LIVE_CPU_REG_X;
if (mType == ASMIT_TYA || mType == ASMIT_STY || mType == ASMIT_CPY || mType == ASMIT_INY || mType == ASMIT_DEY)
live |= LIVE_CPU_REG_Y;
if (mType == ASMIT_TXA || mType == ASMIT_STX || mType == ASMIT_CPX || mType == ASMIT_INX || mType == ASMIT_DEX)
live |= LIVE_CPU_REG_X;
if (mMode == ASMIM_IMPLIED && (mType == ASMIT_TAX || mType == ASMIT_TAY ||
mType == ASMIT_ASL || mType == ASMIT_LSR || mType == ASMIT_ROL || mType == ASMIT_ROR))
live |= LIVE_CPU_REG_A;
if (mType == ASMIT_STA ||
mType == ASMIT_ORA || mType == ASMIT_AND || mType == ASMIT_EOR ||
mType == ASMIT_SBC || mType == ASMIT_ADC || mType == ASMIT_CMP)
live |= LIVE_CPU_REG_A;
if (mType == ASMIT_ADC || mType == ASMIT_SBC || mType == ASMIT_ROL || mType == ASMIT_ROR)
live |= LIVE_CPU_REG_C;
return live;
}
bool NativeCodeInstruction::RequiresYReg(void) const
{
if (mMode == ASMIM_ABSOLUTE_Y || mMode == ASMIM_INDIRECT_Y || mMode == ASMIM_ZERO_PAGE_Y)
@ -6590,12 +6618,25 @@ NativeCodeBasicBlock * NativeCodeBasicBlock::CopyValue(InterCodeProcedure* proc,
#if 1
if (ins->mSrc[0].mTemp < 0 && ins->mSrc[1].mTemp < 0)
{
if (ins->mSrc[0].mMemory == IM_GLOBAL && ins->mSrc[1].mMemory == IM_FRAME)
if (ins->mSrc[0].mMemory == IM_GLOBAL && (ins->mSrc[1].mMemory == IM_FRAME || ins->mSrc[1].mMemory == IM_LOCAL || ins->mSrc[1].mMemory == IM_PARAM) && size < 256 && dstride == 1 && sstride == 1)
{
int index = ins->mSrc[1].mVarIndex + ins->mSrc[1].mIntConst + 2;
int areg = BC_REG_STACK;
CheckFrameIndex(areg, index, size);
int index = ins->mSrc[1].mIntConst;
if (ins->mSrc[1].mMemory == IM_FRAME)
index += ins->mSrc[1].mVarIndex + 2;
else
{
if (!mNoFrame)
areg = BC_REG_LOCALS;
if (ins->mSrc[1].mMemory == IM_LOCAL)
index += proc->mLocalVars[ins->mSrc[1].mVarIndex]->mOffset;
else
index += ins->mSrc[1].mVarIndex + proc->mLocalSize + 2;
index += mFrameOffset;
}
CheckFrameIndex(areg, index, size, BC_REG_ADDR);
if (size <= msize)
{
@ -12173,11 +12214,15 @@ bool NativeCodeBasicBlock::ReduceLocalYPressure(void)
{
if (CanReplaceYRegWithXReg(0, mIns.Size()))
{
mEntryRequiredRegs += CPU_REG_X; mEntryRequiredRegs -= CPU_REG_Y;
mExitRequiredRegs += CPU_REG_X; mExitRequiredRegs -= CPU_REG_Y;
mEntryRequiredRegs += CPU_REG_X;
mExitRequiredRegs += CPU_REG_X;
pblock->mExitRequiredRegs += CPU_REG_X; pblock->mExitRequiredRegs -= CPU_REG_Y;
ReplaceYRegWithXReg(0, mIns.Size());
mEntryRequiredRegs -= CPU_REG_Y;
mExitRequiredRegs -= CPU_REG_Y;
pblock->mIns[pz - 1].mType = ASMIT_LDX;
changed = true;
}
@ -14294,6 +14339,55 @@ bool NativeCodeBasicBlock::ExpandADCToBranch(NativeCodeProcedure* proc)
mIns.SetSize(i + 1);
break;
}
else if (mIns[i + 5].mType == ASMIT_TAX && HasAsmInstructionMode(ASMIT_LDX, mIns[i + 11].mMode) && HasAsmInstructionMode(ASMIT_STX, mIns[i + 12].mMode))
{
// Can't do direct inc, so fallback to x register
changed = true;
NativeCodeBasicBlock* iblock = proc->AllocateBlock();
NativeCodeBasicBlock* dblock = proc->AllocateBlock();
NativeCodeBasicBlock* ablock = proc->AllocateBlock();
NativeCodeBasicBlock* fblock = proc->AllocateBlock();
fblock->mTrueJump = mTrueJump;
fblock->mFalseJump = mFalseJump;
fblock->mBranch = mBranch;
dblock->mIns.Push(NativeCodeInstruction(ASMIT_DEX));
dblock->mTrueJump = ablock;
dblock->mBranch = ASMIT_JMP;
ablock->mIns.Push(mIns[i + 7]);
ablock->mIns.Push(mIns[i + 8]);
ablock->mIns.Push(mIns[i + 9]);
if (mIns[i + 8].SameEffectiveAddress(mIns[i + 0]))
{
ablock->mIns[1].CopyMode(mIns[i + 6]);
}
ablock->mBranch = ASMIT_BCC;
ablock->mTrueJump = fblock;
ablock->mFalseJump = iblock;
iblock->mIns.Push(NativeCodeInstruction(ASMIT_INX));
iblock->mTrueJump = fblock;
iblock->mBranch = ASMIT_JMP;
mTrueJump = ablock;
mFalseJump = dblock;
mBranch = ASMIT_BPL;
fblock->mIns.Push(NativeCodeInstruction(ASMIT_STX, mIns[i + 12]));
for (int j = i + 13; j < mIns.Size(); j++)
fblock->mIns.Push(mIns[j]);
mIns.Insert(i, NativeCodeInstruction(ASMIT_LDX, mIns[i + 11]));
mIns[i + 1].mLive |= LIVE_CPU_REG_X;
mIns.SetSize(i + 2);
break;
}
}
}
}
@ -15589,6 +15683,19 @@ static bool ChangedOnPath(const NativeCodeBasicBlock* block, int start, int end,
return false;
}
void NativeCodeBasicBlock::PrependInstruction(const NativeCodeInstruction& ins)
{
mIns.Insert(0, ins);
if (mEntryRequiredRegs[CPU_REG_A])
mIns[0].mLive |= LIVE_CPU_REG_A;
if (mEntryRequiredRegs[CPU_REG_X])
mIns[0].mLive |= LIVE_CPU_REG_X;
if (mEntryRequiredRegs[CPU_REG_Y])
mIns[0].mLive |= LIVE_CPU_REG_Y;
if (mEntryRequiredRegs[CPU_REG_C])
mIns[0].mLive |= LIVE_CPU_REG_C;
}
bool NativeCodeBasicBlock::PropagateSinglePath(void)
{
bool changed = false;
@ -15620,9 +15727,9 @@ bool NativeCodeBasicBlock::PropagateSinglePath(void)
mFalseJump->mEntryRequiredRegs[addr] && !mTrueJump->mEntryRequiredRegs[addr] && mFalseJump->mNumEntries == 1 && !mFalseJump->mEntryRequiredRegs[CPU_REG_Z] && !mFalseJump->mEntryRequiredRegs[CPU_REG_C])
{
if (mTrueJump->mEntryRequiredRegs[addr])
mTrueJump->mIns.Insert(0, mIns[i]);
mTrueJump->PrependInstruction(mIns[i]);
else
mFalseJump->mIns.Insert(0, mIns[i]);
mFalseJump->PrependInstruction(mIns[i]);
mIns.Remove(i);
}
}
@ -15653,9 +15760,9 @@ bool NativeCodeBasicBlock::PropagateSinglePath(void)
if (mIns[i - 1].mMode == ASMIM_IMMEDIATE || (mIns[i - 1].mMode == ASMIM_ZERO_PAGE && !ChangedOnPath(this, i, mIns.Size(), mIns[i - 1].mAddress)))
{
if (mTrueJump->mEntryRequiredRegs[CPU_REG_X])
mTrueJump->mIns.Insert(0, mIns[i - 1]);
mTrueJump->PrependInstruction(mIns[i - 1]);
else
mFalseJump->mIns.Insert(0, mIns[i - 1]);
mFalseJump->PrependInstruction(mIns[i - 1]);
mIns.Remove(i - 1);
changed = true;
}
@ -15672,9 +15779,9 @@ bool NativeCodeBasicBlock::PropagateSinglePath(void)
if (mIns[i - 1].mMode == ASMIM_IMMEDIATE || (mIns[i - 1].mMode == ASMIM_ZERO_PAGE && !ChangedOnPath(this, i, mIns.Size(), mIns[i - 1].mAddress)))
{
if (mTrueJump->mEntryRequiredRegs[CPU_REG_Y])
mTrueJump->mIns.Insert(0, mIns[i - 1]);
mTrueJump->PrependInstruction(mIns[i - 1]);
else
mFalseJump->mIns.Insert(0, mIns[i - 1]);
mFalseJump->PrependInstruction(mIns[i - 1]);
mIns.Remove(i - 1);
changed = true;
}
@ -16399,6 +16506,10 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool
for (int i = index; i < mIns.Size(); i++)
mIns[i].mLive |= LIVE_CPU_REG_X;
mIns[index].mLive |= mIns[mIns.Size() - 1].mLive;
mExitRequiredRegs += CPU_REG_X;
mTrueJump->mEntryRequiredRegs += CPU_REG_X;
mTrueJump->mIns.Insert(0, mIns[index]);
mIns.Remove(index);
changed = true;
@ -16413,6 +16524,10 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool
for (int i = index; i < mIns.Size(); i++)
mIns[i].mLive |= LIVE_CPU_REG_X;
mIns[index].mLive |= mIns[mIns.Size() - 1].mLive;
mExitRequiredRegs += CPU_REG_X;
mFalseJump->mEntryRequiredRegs += CPU_REG_X;
mFalseJump->mIns.Insert(0, mIns[index]);
mIns.Remove(index);
changed = true;
@ -16444,6 +16559,10 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool
pblock->mIns.Push(mIns[0]);
mIns.Remove(0);
pblock->mExitRequiredRegs += CPU_REG_Y;
mEntryRequiredRegs += CPU_REG_Y;
mExitRequiredRegs += CPU_REG_Y;
changed = true;
}
else if (lblock->mIns[ls - 1].mType == ASMIT_LDA && lblock->mIns[ls - 1].mMode == ASMIM_ZERO_PAGE && lblock->mIns[ls - 1].mAddress == mIns[0].mAddress &&
@ -16456,6 +16575,10 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool
pblock->mIns.Push(mIns[0]);
mIns.Remove(0);
pblock->mExitRequiredRegs += CPU_REG_Y;
mEntryRequiredRegs += CPU_REG_Y;
mExitRequiredRegs += CPU_REG_Y;
changed = true;
}
}
@ -16472,6 +16595,10 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool
pblock->mIns.Push(mIns[0]);
mIns.Remove(0);
pblock->mExitRequiredRegs += CPU_REG_X;
mEntryRequiredRegs += CPU_REG_X;
mExitRequiredRegs += CPU_REG_X;
changed = true;
}
}
@ -16485,6 +16612,10 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool
pblock->mIns.Push(mIns[0]);
mIns.Remove(0);
pblock->mExitRequiredRegs += CPU_REG_A;
mEntryRequiredRegs += CPU_REG_A;
mExitRequiredRegs += CPU_REG_A;
lblock->mIns[ls - 1].mLive |= LIVE_CPU_REG_A;
changed = true;
@ -22378,6 +22509,21 @@ bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data, bo
}
}
else if (lins.mType == ASMIT_CPY && lins.mMode == ASMIM_IMMEDIATE)
{
mFDataSet.mRegs[CPU_REG_Y].mMode = NRDM_IMMEDIATE;
mFDataSet.mRegs[CPU_REG_Y].mValue = lins.mAddress;
}
else if (lins.mType == ASMIT_CPX && lins.mMode == ASMIM_IMMEDIATE)
{
mFDataSet.mRegs[CPU_REG_X].mMode = NRDM_IMMEDIATE;
mFDataSet.mRegs[CPU_REG_X].mValue = lins.mAddress;
}
else if (lins.mType == ASMIT_CMP && lins.mMode == ASMIM_IMMEDIATE)
{
mFDataSet.mRegs[CPU_REG_A].mMode = NRDM_IMMEDIATE;
mFDataSet.mRegs[CPU_REG_A].mValue = lins.mAddress;
}
else if (lins.mType == ASMIT_TXA || lins.mType == ASMIT_TAX)
{
mFDataSet.mRegs[CPU_REG_A].mMode = NRDM_IMMEDIATE;
@ -22446,6 +22592,21 @@ bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data, bo
mNDataSet.mRegs[lins.mAddress].mValue = 0;
}
}
else if (lins.mType == ASMIT_CPY && lins.mMode == ASMIM_IMMEDIATE)
{
mNDataSet.mRegs[CPU_REG_Y].mMode = NRDM_IMMEDIATE;
mNDataSet.mRegs[CPU_REG_Y].mValue = lins.mAddress;
}
else if (lins.mType == ASMIT_CPX && lins.mMode == ASMIM_IMMEDIATE)
{
mNDataSet.mRegs[CPU_REG_X].mMode = NRDM_IMMEDIATE;
mNDataSet.mRegs[CPU_REG_X].mValue = lins.mAddress;
}
else if (lins.mType == ASMIT_CMP && lins.mMode == ASMIM_IMMEDIATE)
{
mNDataSet.mRegs[CPU_REG_A].mMode = NRDM_IMMEDIATE;
mNDataSet.mRegs[CPU_REG_A].mValue = lins.mAddress;
}
else if (lins.mType == ASMIT_TXA || lins.mType == ASMIT_TAX)
{
mNDataSet.mRegs[CPU_REG_A].mMode = NRDM_IMMEDIATE;
@ -32091,6 +32252,14 @@ void NativeCodeBasicBlock::CheckLive(void)
if (mIns[j].RequiresCarry()) live |= LIVE_CPU_REG_C;
}
}
if (mEntryRequiredRegs.Size() > 0)
{
if (live & LIVE_CPU_REG_X)
assert(mEntryRequiredRegs[CPU_REG_X]);
if (live & LIVE_CPU_REG_Y)
assert(mEntryRequiredRegs[CPU_REG_Y]);
}
#endif
}
@ -33121,7 +33290,7 @@ void NativeCodeProcedure::RebuildEntry(void)
void NativeCodeProcedure::Optimize(void)
{
CheckFunc = !strcmp(mInterProc->mIdent->mString, "checkKeys");
CheckFunc = !strcmp(mInterProc->mIdent->mString, "hcw_irq");
#if 1
int step = 0;

View File

@ -153,6 +153,7 @@ public:
void BuildCollisionTable(NumberSet& liveTemps, NumberSet* collisionSets);
uint32 NeedsLive(void) const;
};
class NativeCodeBasicBlock
@ -198,6 +199,8 @@ public:
void Assemble(void);
void Close(NativeCodeBasicBlock* trueJump, NativeCodeBasicBlock* falseJump, AsmInsType branch);
void PrependInstruction(const NativeCodeInstruction& ins);
void ShortcutTailRecursion();
bool ReferencesAccu(int from = 0) const;