Dataflow optimizations
This commit is contained in:
parent
2f4b2790f6
commit
0b30258f80
|
@ -735,6 +735,9 @@ void bm_line(const Bitmap * bm, const ClipRect * clip, int x0, int y0, int x1, i
|
||||||
|
|
||||||
if (dx > 0)
|
if (dx > 0)
|
||||||
{
|
{
|
||||||
|
__assume(clip->left >= 0);
|
||||||
|
__assume(clip->right >= 0);
|
||||||
|
|
||||||
if (x1 < clip->left || x0 >= clip->right)
|
if (x1 < clip->left || x0 >= clip->right)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -752,6 +755,9 @@ void bm_line(const Bitmap * bm, const ClipRect * clip, int x0, int y0, int x1, i
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
__assume(clip->left >= 0);
|
||||||
|
__assume(clip->right >= 0);
|
||||||
|
|
||||||
if (x0 < clip->left || x1 >= clip->right)
|
if (x0 < clip->left || x1 >= clip->right)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -770,6 +776,9 @@ void bm_line(const Bitmap * bm, const ClipRect * clip, int x0, int y0, int x1, i
|
||||||
|
|
||||||
if (dy > 0)
|
if (dy > 0)
|
||||||
{
|
{
|
||||||
|
__assume(clip->top >= 0);
|
||||||
|
__assume(clip->bottom >= 0);
|
||||||
|
|
||||||
if (y1 < clip->top || y0 >= clip->bottom)
|
if (y1 < clip->top || y0 >= clip->bottom)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -787,6 +796,9 @@ void bm_line(const Bitmap * bm, const ClipRect * clip, int x0, int y0, int x1, i
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
__assume(clip->top >= 0);
|
||||||
|
__assume(clip->bottom >= 0);
|
||||||
|
|
||||||
if (y0 < clip->top || y1 >= clip->bottom)
|
if (y0 < clip->top || y1 >= clip->bottom)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -376,7 +376,13 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec)
|
||||||
case EX_VARIABLE:
|
case EX_VARIABLE:
|
||||||
if ((exp->mDecValue->mFlags & DTF_STATIC) || (exp->mDecValue->mFlags & DTF_GLOBAL))
|
if ((exp->mDecValue->mFlags & DTF_STATIC) || (exp->mDecValue->mFlags & DTF_GLOBAL))
|
||||||
{
|
{
|
||||||
|
Declaration* type = exp->mDecValue->mBase;
|
||||||
|
while (type->mType == DT_TYPE_ARRAY)
|
||||||
|
type = type->mBase;
|
||||||
|
|
||||||
|
if (!(type->mFlags & DTF_CONST))
|
||||||
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
|
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
|
||||||
|
|
||||||
AnalyzeGlobalVariable(exp->mDecValue);
|
AnalyzeGlobalVariable(exp->mDecValue);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -388,10 +388,10 @@ static bool CollidingMemType(InterType type1, InterType type2)
|
||||||
{
|
{
|
||||||
if (type1 == IT_NONE || type2 == IT_NONE)
|
if (type1 == IT_NONE || type2 == IT_NONE)
|
||||||
return true;
|
return true;
|
||||||
else if (type1 == IT_POINTER || type1 == IT_FLOAT || type2 == IT_POINTER || type2 == IT_FLOAT)
|
else// if (type1 == IT_POINTER || type1 == IT_FLOAT || type2 == IT_POINTER || type2 == IT_FLOAT)
|
||||||
return type1 == type2;
|
return type1 == type2;
|
||||||
else
|
// else
|
||||||
return false;
|
// return false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,7 +403,7 @@ static bool CollidingMem(const InterOperand& op1, InterType type1, const InterOp
|
||||||
{
|
{
|
||||||
if (op2.mMemory == IM_GLOBAL)
|
if (op2.mMemory == IM_GLOBAL)
|
||||||
return staticVars[op2.mVarIndex]->mAliased;
|
return staticVars[op2.mVarIndex]->mAliased;
|
||||||
else if (op2.mMemory == IM_FPARAM)
|
else if (op2.mMemory == IM_FPARAM || op2.mMemory == IM_FFRAME)
|
||||||
return false;
|
return false;
|
||||||
else
|
else
|
||||||
return CollidingMemType(type1, type2);
|
return CollidingMemType(type1, type2);
|
||||||
|
@ -412,7 +412,7 @@ static bool CollidingMem(const InterOperand& op1, InterType type1, const InterOp
|
||||||
{
|
{
|
||||||
if (op1.mMemory == IM_GLOBAL)
|
if (op1.mMemory == IM_GLOBAL)
|
||||||
return staticVars[op1.mVarIndex]->mAliased;
|
return staticVars[op1.mVarIndex]->mAliased;
|
||||||
else if (op1.mMemory == IM_FPARAM)
|
else if (op1.mMemory == IM_FPARAM || op1.mMemory == IM_FFRAME)
|
||||||
return false;
|
return false;
|
||||||
else
|
else
|
||||||
return CollidingMemType(type1, type2);
|
return CollidingMemType(type1, type2);
|
||||||
|
@ -2648,6 +2648,8 @@ InterInstruction::InterInstruction(const Location& loc, InterCode code)
|
||||||
mVolatile = false;
|
mVolatile = false;
|
||||||
mInvariant = false;
|
mInvariant = false;
|
||||||
mSingleAssignment = false;
|
mSingleAssignment = false;
|
||||||
|
mNoSideEffects = false;
|
||||||
|
mConstExpr = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool TypeInteger(InterType t)
|
static bool TypeInteger(InterType t)
|
||||||
|
@ -3278,6 +3280,15 @@ bool InterInstruction::RemoveUnusedStaticStoreInstructions(const GrowingVariable
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int InterInstruction::NumUsedTemps(void) const
|
||||||
|
{
|
||||||
|
int n = 0;
|
||||||
|
for (int i = 0; i < mNumOperands; i++)
|
||||||
|
if (mSrc[i].mTemp >= 0)
|
||||||
|
n++;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
bool InterInstruction::UsesTemp(int temp) const
|
bool InterInstruction::UsesTemp(int temp) const
|
||||||
{
|
{
|
||||||
for (int i = 0; i < mNumOperands; i++)
|
for (int i = 0; i < mNumOperands; i++)
|
||||||
|
@ -3894,6 +3905,10 @@ void InterInstruction::Disassemble(FILE* file)
|
||||||
fprintf(file, "I");
|
fprintf(file, "I");
|
||||||
if (mVolatile)
|
if (mVolatile)
|
||||||
fprintf(file, "V");
|
fprintf(file, "V");
|
||||||
|
if (mNoSideEffects)
|
||||||
|
fprintf(file, "E");
|
||||||
|
if (mConstExpr)
|
||||||
|
fprintf(file, "C");
|
||||||
if (mSingleAssignment)
|
if (mSingleAssignment)
|
||||||
fprintf(file, "S");
|
fprintf(file, "S");
|
||||||
fprintf(file, "}\n");
|
fprintf(file, "}\n");
|
||||||
|
@ -11026,7 +11041,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
|
||||||
for (int i = 0; i < mInstructions.Size(); i++)
|
for (int i = 0; i < mInstructions.Size(); i++)
|
||||||
{
|
{
|
||||||
InterInstruction* ins = mInstructions[i];
|
InterInstruction* ins = mInstructions[i];
|
||||||
if (ins->mCode == IC_CALL || ins->mCode == IC_CALL_NATIVE)
|
if ((ins->mCode == IC_CALL || ins->mCode == IC_CALL_NATIVE) && !ins->mConstExpr)
|
||||||
hasCall = true;
|
hasCall = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11119,7 +11134,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
|
||||||
ins->mInvariant = false;
|
ins->mInvariant = false;
|
||||||
else if (ins->mCode == IC_LOAD)
|
else if (ins->mCode == IC_LOAD)
|
||||||
{
|
{
|
||||||
if ((ins->mSrc[0].mTemp >= 0 && mLocalModifiedTemps[ins->mSrc[0].mTemp]) || ins->mVolatile)
|
if ((ins->mSrc[0].mTemp >= 0 && mLocalModifiedTemps[ins->mSrc[0].mTemp]) || ins->mVolatile || hasCall)
|
||||||
{
|
{
|
||||||
ins->mInvariant = false;
|
ins->mInvariant = false;
|
||||||
}
|
}
|
||||||
|
@ -12641,32 +12656,45 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
|
||||||
} while (changed);
|
} while (changed);
|
||||||
|
|
||||||
// build trains
|
// build trains
|
||||||
|
#if 1
|
||||||
for(int i = mInstructions.Size() - 1; i > 0; i--)
|
for(int i = mInstructions.Size() - 1; i > 0; i--)
|
||||||
{
|
{
|
||||||
InterInstruction* tins = mInstructions[i];
|
InterInstruction* tins = mInstructions[i];
|
||||||
|
|
||||||
|
int ti = i;
|
||||||
|
|
||||||
j = i - 1;
|
j = i - 1;
|
||||||
while (j >= 0 && !tins->ReferencesTemp(mInstructions[j]->mDst.mTemp))
|
while (j >= 0 && !tins->ReferencesTemp(mInstructions[j]->mDst.mTemp))
|
||||||
j--;
|
j--;
|
||||||
if (j >= 0 && j < i - 1)
|
while (j >= 0)
|
||||||
{
|
{
|
||||||
if (CanMoveInstructionDown(j, i))
|
if (j < ti - 1)
|
||||||
|
{
|
||||||
|
if (CanMoveInstructionDown(j, ti))
|
||||||
{
|
{
|
||||||
InterInstruction* jins = mInstructions[j];
|
InterInstruction* jins = mInstructions[j];
|
||||||
for (int k = j; k < i - 1; k++)
|
for (int k = j; k < ti - 1; k++)
|
||||||
{
|
{
|
||||||
SwapInstructions(jins, mInstructions[k + 1]);
|
SwapInstructions(jins, mInstructions[k + 1]);
|
||||||
mInstructions[k] = mInstructions[k + 1];
|
mInstructions[k] = mInstructions[k + 1];
|
||||||
}
|
}
|
||||||
mInstructions[i - 1] = jins;
|
mInstructions[ti - 1] = jins;
|
||||||
|
if (mInstructions[ti - 1]->NumUsedTemps() <= 1)
|
||||||
|
ti--;
|
||||||
|
|
||||||
// mInstructions.Insert(i, mInstructions[j]);
|
// mInstructions.Insert(i, mInstructions[j]);
|
||||||
// mInstructions.Remove(j);
|
// mInstructions.Remove(j);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (mInstructions[j]->NumUsedTemps() <= 1)
|
||||||
|
ti--;
|
||||||
|
|
||||||
|
j--;
|
||||||
|
while (j >= 0 && !tins->ReferencesTemp(mInstructions[j]->mDst.mTemp))
|
||||||
|
j--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
CheckFinalLocal();
|
CheckFinalLocal();
|
||||||
|
|
||||||
// sort stores up
|
// sort stores up
|
||||||
|
|
|
@ -287,7 +287,7 @@ public:
|
||||||
InterOperator mOperator;
|
InterOperator mOperator;
|
||||||
int mNumOperands;
|
int mNumOperands;
|
||||||
|
|
||||||
bool mInUse, mInvariant, mVolatile, mExpensive, mSingleAssignment;
|
bool mInUse, mInvariant, mVolatile, mExpensive, mSingleAssignment, mNoSideEffects, mConstExpr;
|
||||||
|
|
||||||
InterInstruction(const Location& loc, InterCode code);
|
InterInstruction(const Location& loc, InterCode code);
|
||||||
|
|
||||||
|
@ -298,6 +298,7 @@ public:
|
||||||
|
|
||||||
bool ReferencesTemp(int temp) const;
|
bool ReferencesTemp(int temp) const;
|
||||||
bool UsesTemp(int temp) const;
|
bool UsesTemp(int temp) const;
|
||||||
|
int NumUsedTemps(void) const;
|
||||||
|
|
||||||
void CollectLocalAddressTemps(GrowingIntArray& localTable, GrowingIntArray& paramTable);
|
void CollectLocalAddressTemps(GrowingIntArray& localTable, GrowingIntArray& paramTable);
|
||||||
void MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals, const GrowingIntArray& paramTable, NumberSet& aliasedParams);
|
void MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals, const GrowingIntArray& paramTable, NumberSet& aliasedParams);
|
||||||
|
|
|
@ -2413,7 +2413,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
{
|
{
|
||||||
if (vr.mType->mType == DT_TYPE_ARRAY || vr.mType->mType == DT_TYPE_FUNCTION)
|
if (vr.mType->mType == DT_TYPE_ARRAY || vr.mType->mType == DT_TYPE_FUNCTION)
|
||||||
vr = Dereference(proc, texp, block, vr, 1);
|
vr = Dereference(proc, texp, block, vr, 1);
|
||||||
else if (pdec && pdec->mBase->mType == DT_TYPE_POINTER && vr.mType->mType == DT_TYPE_INTEGER && texp->mDecValue->mType == DT_CONST_INTEGER && texp->mDecValue->mInteger == 0)
|
else if (pdec && pdec->mBase->mType == DT_TYPE_POINTER && vr.mType->mType == DT_TYPE_INTEGER && texp->mType == EX_CONSTANT && texp->mDecValue->mType == DT_CONST_INTEGER && texp->mDecValue->mInteger == 0)
|
||||||
vr = CoerceType(proc, texp, block, vr, pdec->mBase);
|
vr = CoerceType(proc, texp, block, vr, pdec->mBase);
|
||||||
else
|
else
|
||||||
vr = Dereference(proc, texp, block, vr);
|
vr = Dereference(proc, texp, block, vr);
|
||||||
|
@ -2474,6 +2474,10 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
cins->mCode = IC_CALL_NATIVE;
|
cins->mCode = IC_CALL_NATIVE;
|
||||||
else
|
else
|
||||||
cins->mCode = IC_CALL;
|
cins->mCode = IC_CALL;
|
||||||
|
|
||||||
|
if (exp->mLeft->mType == EX_CONSTANT && exp->mLeft->mDecValue->mFlags & DTF_FUNC_CONSTEXPR)
|
||||||
|
cins->mConstExpr = true;
|
||||||
|
|
||||||
cins->mSrc[0].mType = IT_POINTER;
|
cins->mSrc[0].mType = IT_POINTER;
|
||||||
cins->mSrc[0].mTemp = vl.mTemp;
|
cins->mSrc[0].mTemp = vl.mTemp;
|
||||||
if (ftype->mBase->mType != DT_TYPE_VOID && ftype->mBase->mType != DT_TYPE_STRUCT)
|
if (ftype->mBase->mType != DT_TYPE_VOID && ftype->mBase->mType != DT_TYPE_STRUCT)
|
||||||
|
|
|
@ -2305,6 +2305,65 @@ bool NativeCodeInstruction::BitFieldForwarding(NativeRegisterDataSet& data, AsmI
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ASMIT_LDX:
|
||||||
|
if (mMode == ASMIM_ZERO_PAGE)
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_X].mMask = data.mRegs[mAddress].mMask;
|
||||||
|
data.mRegs[CPU_REG_X].mValue = data.mRegs[mAddress].mValue;
|
||||||
|
|
||||||
|
if (data.mRegs[CPU_REG_X].mMask == 0xff)
|
||||||
|
{
|
||||||
|
mType = ASMIT_LDX;
|
||||||
|
mMode = ASMIM_IMMEDIATE;
|
||||||
|
mAddress = data.mRegs[CPU_REG_X].mValue;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mMode == ASMIM_IMMEDIATE)
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_X].mMask = 0xff;
|
||||||
|
data.mRegs[CPU_REG_X].mValue = mAddress & 0xff;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
data.mRegs[CPU_REG_X].mMask = 0;
|
||||||
|
break;
|
||||||
|
case ASMIT_STX:
|
||||||
|
if (mMode == ASMIM_ZERO_PAGE)
|
||||||
|
{
|
||||||
|
data.mRegs[mAddress].mMask = data.mRegs[CPU_REG_X].mMask;
|
||||||
|
data.mRegs[mAddress].mValue = data.mRegs[CPU_REG_X].mValue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASMIT_LDY:
|
||||||
|
if (mMode == ASMIM_ZERO_PAGE)
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_Y].mMask = data.mRegs[mAddress].mMask;
|
||||||
|
data.mRegs[CPU_REG_Y].mValue = data.mRegs[mAddress].mValue;
|
||||||
|
|
||||||
|
if (data.mRegs[CPU_REG_Y].mMask == 0xff)
|
||||||
|
{
|
||||||
|
mType = ASMIT_LDY;
|
||||||
|
mMode = ASMIM_IMMEDIATE;
|
||||||
|
mAddress = data.mRegs[CPU_REG_Y].mValue;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mMode == ASMIM_IMMEDIATE)
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_Y].mMask = 0xff;
|
||||||
|
data.mRegs[CPU_REG_Y].mValue = mAddress & 0xff;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
data.mRegs[CPU_REG_Y].mMask = 0;
|
||||||
|
break;
|
||||||
|
case ASMIT_STY:
|
||||||
|
if (mMode == ASMIM_ZERO_PAGE)
|
||||||
|
{
|
||||||
|
data.mRegs[mAddress].mMask = data.mRegs[CPU_REG_Y].mMask;
|
||||||
|
data.mRegs[mAddress].mValue = data.mRegs[CPU_REG_Y].mValue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case ASMIT_AND:
|
case ASMIT_AND:
|
||||||
if (mMode == ASMIM_ZERO_PAGE)
|
if (mMode == ASMIM_ZERO_PAGE)
|
||||||
|
@ -2439,8 +2498,6 @@ bool NativeCodeInstruction::BitFieldForwarding(NativeRegisterDataSet& data, AsmI
|
||||||
|
|
||||||
case ASMIT_INC:
|
case ASMIT_INC:
|
||||||
case ASMIT_DEC:
|
case ASMIT_DEC:
|
||||||
case ASMIT_STX:
|
|
||||||
case ASMIT_STY:
|
|
||||||
if (mMode == ASMIM_ZERO_PAGE)
|
if (mMode == ASMIM_ZERO_PAGE)
|
||||||
data.mRegs[mAddress].mMask = 0;
|
data.mRegs[mAddress].mMask = 0;
|
||||||
break;
|
break;
|
||||||
|
@ -3743,8 +3800,6 @@ void NativeCodeInstruction::FilterRegUsage(NumberSet& requiredTemps, NumberSet&
|
||||||
requiredTemps += BC_REG_ACCU + i;
|
requiredTemps += BC_REG_ACCU + i;
|
||||||
if (!providedTemps[BC_REG_WORK + i])
|
if (!providedTemps[BC_REG_WORK + i])
|
||||||
requiredTemps += BC_REG_WORK + i;
|
requiredTemps += BC_REG_WORK + i;
|
||||||
if (!providedTemps[BC_REG_ADDR + i])
|
|
||||||
requiredTemps += BC_REG_ADDR + i;
|
|
||||||
}
|
}
|
||||||
if (mFlags & NCIF_USE_ZP_32_X)
|
if (mFlags & NCIF_USE_ZP_32_X)
|
||||||
{
|
{
|
||||||
|
@ -8747,9 +8802,14 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_ZERO_PAGE, treg));
|
mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_ZERO_PAGE, treg));
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg));
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg));
|
||||||
if (InterTypeSize[ins->mDst.mType] > 1)
|
if (InterTypeSize[ins->mDst.mType] > 1)
|
||||||
|
{
|
||||||
|
if (ins->mDst.IsUByte())
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
||||||
|
else
|
||||||
{
|
{
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[1].mIntConst >> 8) & 0xff));
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[1].mIntConst >> 8) & 0xff));
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_ZERO_PAGE, treg + 1));
|
mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_ZERO_PAGE, treg + 1));
|
||||||
|
}
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8760,9 +8820,14 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]));
|
mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]));
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg));
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg));
|
||||||
if (InterTypeSize[ins->mDst.mType] > 1)
|
if (InterTypeSize[ins->mDst.mType] > 1)
|
||||||
|
{
|
||||||
|
if (ins->mDst.IsUByte())
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
||||||
|
else
|
||||||
{
|
{
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[1].mIntConst >> 8) & 0xff));
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[1].mIntConst >> 8) & 0xff));
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1));
|
mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1));
|
||||||
|
}
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13241,6 +13306,8 @@ bool NativeCodeBasicBlock::MoveAccuTrainUp(int at, int end)
|
||||||
{
|
{
|
||||||
CheckLive();
|
CheckLive();
|
||||||
|
|
||||||
|
bool needXY = (mIns[end - 1].mLive & (LIVE_CPU_REG_X | LIVE_CPU_REG_Y)) != 0;
|
||||||
|
|
||||||
int i = at;
|
int i = at;
|
||||||
while (i > 0)
|
while (i > 0)
|
||||||
{
|
{
|
||||||
|
@ -13270,7 +13337,7 @@ bool NativeCodeBasicBlock::MoveAccuTrainUp(int at, int end)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mIns[i].mType == ASMIT_JSR)
|
if (mIns[i].mType == ASMIT_JSR && needXY)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (int j = at; j < end; j++)
|
for (int j = at; j < end; j++)
|
||||||
|
@ -13330,7 +13397,13 @@ bool NativeCodeBasicBlock::MoveAccuTrainsUp(void)
|
||||||
}
|
}
|
||||||
else if (mIns[i].mType == ASMIT_JSR)
|
else if (mIns[i].mType == ASMIT_JSR)
|
||||||
{
|
{
|
||||||
wzero.Clear();
|
for (int j = 0; j < 4; j++)
|
||||||
|
{
|
||||||
|
wzero -= BC_REG_ACCU + j;
|
||||||
|
wzero -= BC_REG_WORK + j;
|
||||||
|
}
|
||||||
|
|
||||||
|
// wzero.Clear();
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
else if (mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].ChangesAddress())
|
else if (mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].ChangesAddress())
|
||||||
|
@ -16943,6 +17016,9 @@ void NativeCodeBasicBlock::DoCrossBlockAShortcut(int addr)
|
||||||
|
|
||||||
bool NativeCodeBasicBlock::CanCrossBlockAShortcut(int addr)
|
bool NativeCodeBasicBlock::CanCrossBlockAShortcut(int addr)
|
||||||
{
|
{
|
||||||
|
if (mExitRequiredRegs[CPU_REG_A])
|
||||||
|
return false;
|
||||||
|
|
||||||
int i = mIns.Size();
|
int i = mIns.Size();
|
||||||
while (i > 0)
|
while (i > 0)
|
||||||
{
|
{
|
||||||
|
@ -16980,6 +17056,9 @@ void NativeCodeBasicBlock::DoCrossBlockXShortcut(int addr)
|
||||||
|
|
||||||
bool NativeCodeBasicBlock::CanCrossBlockXShortcut(int addr)
|
bool NativeCodeBasicBlock::CanCrossBlockXShortcut(int addr)
|
||||||
{
|
{
|
||||||
|
if (mExitRequiredRegs[CPU_REG_X])
|
||||||
|
return false;
|
||||||
|
|
||||||
int i = mIns.Size();
|
int i = mIns.Size();
|
||||||
while (i > 0)
|
while (i > 0)
|
||||||
{
|
{
|
||||||
|
@ -17018,6 +17097,9 @@ void NativeCodeBasicBlock::DoCrossBlockYShortcut(int addr)
|
||||||
|
|
||||||
bool NativeCodeBasicBlock::CanCrossBlockYShortcut(int addr)
|
bool NativeCodeBasicBlock::CanCrossBlockYShortcut(int addr)
|
||||||
{
|
{
|
||||||
|
if (mExitRequiredRegs[CPU_REG_Y])
|
||||||
|
return false;
|
||||||
|
|
||||||
int i = mIns.Size();
|
int i = mIns.Size();
|
||||||
while (i > 0)
|
while (i > 0)
|
||||||
{
|
{
|
||||||
|
@ -21586,6 +21668,7 @@ bool NativeCodeBasicBlock::MoveCLCLoadAddZPStoreDown(int at)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//static bool PeepCheck = false;
|
||||||
//static bool PeepCheck = false;
|
//static bool PeepCheck = false;
|
||||||
|
|
||||||
bool NativeCodeBasicBlock::ReverseBitfieldForwarding(void)
|
bool NativeCodeBasicBlock::ReverseBitfieldForwarding(void)
|
||||||
|
@ -22411,7 +22494,7 @@ bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data, bo
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc)
|
bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc, bool full)
|
||||||
{
|
{
|
||||||
NativeCodeBasicBlock* lblock = proc->AllocateBlock();
|
NativeCodeBasicBlock* lblock = proc->AllocateBlock();
|
||||||
NativeCodeBasicBlock* eblock = proc->AllocateBlock();
|
NativeCodeBasicBlock* eblock = proc->AllocateBlock();
|
||||||
|
@ -22441,7 +22524,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
mTrueJump = lblock;
|
mTrueJump = lblock;
|
||||||
mFalseJump = nullptr;
|
mFalseJump = nullptr;
|
||||||
|
|
||||||
return lblock->OptimizeSimpleLoopInvariant(proc, this, eblock);
|
return lblock->OptimizeSimpleLoopInvariant(proc, this, eblock, full);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NativeCodeBasicBlock::RemoveSimpleLoopUnusedIndex(void)
|
bool NativeCodeBasicBlock::RemoveSimpleLoopUnusedIndex(void)
|
||||||
|
@ -22538,7 +22621,7 @@ bool NativeCodeBasicBlock::RemoveSimpleLoopUnusedIndex(void)
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc, NativeCodeBasicBlock* prevBlock, NativeCodeBasicBlock* exitBlock)
|
bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc, NativeCodeBasicBlock* prevBlock, NativeCodeBasicBlock* exitBlock, bool full)
|
||||||
{
|
{
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
|
||||||
|
@ -22552,7 +22635,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
if (sz == 2 && (mBranch == ASMIT_BEQ || mBranch == ASMIT_BNE) && mIns[0].mType == ASMIT_LDA && mIns[1].mType == ASMIT_CMP && !(mIns[1].mFlags & NCIF_VOLATILE) && !(mIns[1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)))
|
if (sz == 2 && (mBranch == ASMIT_BEQ || mBranch == ASMIT_BNE) && mIns[0].mType == ASMIT_LDA && mIns[1].mType == ASMIT_CMP && !(mIns[1].mFlags & NCIF_VOLATILE) && !(mIns[1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)))
|
||||||
{
|
{
|
||||||
if (!prevBlock)
|
if (!prevBlock)
|
||||||
return OptimizeSimpleLoopInvariant(proc);
|
return OptimizeSimpleLoopInvariant(proc, full);
|
||||||
mIns[1].mType = ASMIT_LDA; mIns[1].mLive |= LIVE_CPU_REG_A;
|
mIns[1].mType = ASMIT_LDA; mIns[1].mLive |= LIVE_CPU_REG_A;
|
||||||
mIns[0].mType = ASMIT_CMP; mIns[0].mLive |= LIVE_CPU_REG_Z;
|
mIns[0].mType = ASMIT_CMP; mIns[0].mLive |= LIVE_CPU_REG_Z;
|
||||||
prevBlock->mIns.Push(mIns[1]);
|
prevBlock->mIns.Push(mIns[1]);
|
||||||
|
@ -22563,10 +22646,36 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
if (full && mEntryRequiredRegs.Size() && !mEntryRequiredRegs[CPU_REG_C] && (mBranch == ASMIT_BCC || mBranch == ASMIT_BCS))
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
while (i < mIns.Size() && !mIns[i].ChangesCarry())
|
||||||
|
i++;
|
||||||
|
if (i < mIns.Size() &&
|
||||||
|
mIns[i].mType == ASMIT_CLC && ((mBranch == ASMIT_BCC && mTrueJump == this) || (mBranch == ASMIT_BCS && mFalseJump == this)) ||
|
||||||
|
mIns[i].mType == ASMIT_SEC && ((mBranch == ASMIT_BCS && mTrueJump == this) || (mBranch == ASMIT_BCC && mFalseJump == this)))
|
||||||
|
{
|
||||||
|
if (!prevBlock)
|
||||||
|
return OptimizeSimpleLoopInvariant(proc, full);
|
||||||
|
|
||||||
|
prevBlock->mIns.Push(mIns[i]);
|
||||||
|
prevBlock->mExitRequiredRegs += CPU_REG_C;
|
||||||
|
for (int j = 0; j < i; j++)
|
||||||
|
mIns[j].mLive |= LIVE_CPU_REG_C;
|
||||||
|
mEntryRequiredRegs += CPU_REG_C;
|
||||||
|
mIns.Remove(i);
|
||||||
|
|
||||||
|
CheckLive();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (sz >= 3 && mIns[0].mType == ASMIT_LDA && mIns[sz - 2].mType == ASMIT_LDA && mIns[0].SameEffectiveAddress(mIns[sz - 2]) && mIns[sz - 1].mType == ASMIT_CMP)
|
if (sz >= 3 && mIns[0].mType == ASMIT_LDA && mIns[sz - 2].mType == ASMIT_LDA && mIns[0].SameEffectiveAddress(mIns[sz - 2]) && mIns[sz - 1].mType == ASMIT_CMP)
|
||||||
{
|
{
|
||||||
if (!prevBlock)
|
if (!prevBlock)
|
||||||
return OptimizeSimpleLoopInvariant(proc);
|
return OptimizeSimpleLoopInvariant(proc, full);
|
||||||
|
|
||||||
prevBlock->mIns.Push(mIns[0]);
|
prevBlock->mIns.Push(mIns[0]);
|
||||||
mIns.Remove(0);
|
mIns.Remove(0);
|
||||||
|
@ -22580,7 +22689,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
mIns[sz - 1].mType == ASMIT_CMP && HasAsmInstructionMode(ASMIT_CPY, mIns[sz - 1].mMode) && !(mIns[sz - 1].mLive & LIVE_CPU_REG_A))
|
mIns[sz - 1].mType == ASMIT_CMP && HasAsmInstructionMode(ASMIT_CPY, mIns[sz - 1].mMode) && !(mIns[sz - 1].mLive & LIVE_CPU_REG_A))
|
||||||
{
|
{
|
||||||
if (!prevBlock)
|
if (!prevBlock)
|
||||||
return OptimizeSimpleLoopInvariant(proc);
|
return OptimizeSimpleLoopInvariant(proc, full);
|
||||||
|
|
||||||
mIns[sz - 2].mType = ASMIT_LDY; mIns[sz - 2].mLive |= LIVE_CPU_REG_Y;
|
mIns[sz - 2].mType = ASMIT_LDY; mIns[sz - 2].mLive |= LIVE_CPU_REG_Y;
|
||||||
mIns[sz - 1].mType = ASMIT_CPY; mIns[sz - 1].mLive |= LIVE_CPU_REG_Y;
|
mIns[sz - 1].mType = ASMIT_CPY; mIns[sz - 1].mLive |= LIVE_CPU_REG_Y;
|
||||||
|
@ -22600,7 +22709,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
if (sz >= 2 && mIns[0].mType == ASMIT_LDY && mIns[sz - 1].mType == ASMIT_LDA && mIns[0].SameEffectiveAddress(mIns[sz - 1]) && !(mIns[sz - 1].mLive & LIVE_CPU_REG_A))
|
if (sz >= 2 && mIns[0].mType == ASMIT_LDY && mIns[sz - 1].mType == ASMIT_LDA && mIns[0].SameEffectiveAddress(mIns[sz - 1]) && !(mIns[sz - 1].mLive & LIVE_CPU_REG_A))
|
||||||
{
|
{
|
||||||
if (!prevBlock)
|
if (!prevBlock)
|
||||||
return OptimizeSimpleLoopInvariant(proc);
|
return OptimizeSimpleLoopInvariant(proc, full);
|
||||||
|
|
||||||
mIns[sz - 1].mType = ASMIT_LDY; mIns[sz - 1].mLive |= LIVE_CPU_REG_Y;
|
mIns[sz - 1].mType = ASMIT_LDY; mIns[sz - 1].mLive |= LIVE_CPU_REG_Y;
|
||||||
|
|
||||||
|
@ -22620,7 +22729,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
mIns[sz - 1].mType == ASMIT_CMP && HasAsmInstructionMode(ASMIT_CPX, mIns[sz - 1].mMode) && !(mIns[sz - 1].mLive & LIVE_CPU_REG_A))
|
mIns[sz - 1].mType == ASMIT_CMP && HasAsmInstructionMode(ASMIT_CPX, mIns[sz - 1].mMode) && !(mIns[sz - 1].mLive & LIVE_CPU_REG_A))
|
||||||
{
|
{
|
||||||
if (!prevBlock)
|
if (!prevBlock)
|
||||||
return OptimizeSimpleLoopInvariant(proc);
|
return OptimizeSimpleLoopInvariant(proc, full);
|
||||||
|
|
||||||
mIns[sz - 2].mType = ASMIT_LDX; mIns[sz - 2].mLive |= LIVE_CPU_REG_X;
|
mIns[sz - 2].mType = ASMIT_LDX; mIns[sz - 2].mLive |= LIVE_CPU_REG_X;
|
||||||
mIns[sz - 1].mType = ASMIT_CPX; mIns[sz - 1].mLive |= LIVE_CPU_REG_X;
|
mIns[sz - 1].mType = ASMIT_CPX; mIns[sz - 1].mLive |= LIVE_CPU_REG_X;
|
||||||
|
@ -22658,7 +22767,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
if (i == mIns.Size())
|
if (i == mIns.Size())
|
||||||
{
|
{
|
||||||
if (!prevBlock)
|
if (!prevBlock)
|
||||||
return OptimizeSimpleLoopInvariant(proc);
|
return OptimizeSimpleLoopInvariant(proc, full);
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < si)
|
while (i < si)
|
||||||
|
@ -22692,7 +22801,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
if (j == mIns.Size())
|
if (j == mIns.Size())
|
||||||
{
|
{
|
||||||
if (!prevBlock)
|
if (!prevBlock)
|
||||||
return OptimizeSimpleLoopInvariant(proc);
|
return OptimizeSimpleLoopInvariant(proc, full);
|
||||||
exitBlock->mIns.Insert(0, mIns[ei]);
|
exitBlock->mIns.Insert(0, mIns[ei]);
|
||||||
mIns.Remove(ei);
|
mIns.Remove(ei);
|
||||||
|
|
||||||
|
@ -22724,7 +22833,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
if (i == mIns.Size())
|
if (i == mIns.Size())
|
||||||
{
|
{
|
||||||
if (!prevBlock)
|
if (!prevBlock)
|
||||||
return OptimizeSimpleLoopInvariant(proc);
|
return OptimizeSimpleLoopInvariant(proc, full);
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < si)
|
while (i < si)
|
||||||
|
@ -22777,7 +22886,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
{
|
{
|
||||||
// So we have an LDX from ZP, and exactly one INC/DECof this ZP and X never changes in the loop
|
// So we have an LDX from ZP, and exactly one INC/DECof this ZP and X never changes in the loop
|
||||||
if (!prevBlock)
|
if (!prevBlock)
|
||||||
return OptimizeSimpleLoopInvariant(proc);
|
return OptimizeSimpleLoopInvariant(proc, full);
|
||||||
prevBlock->mIns.Push(mIns[si]);
|
prevBlock->mIns.Push(mIns[si]);
|
||||||
exitBlock->mIns.Insert(0, NativeCodeInstruction(ASMIT_STX, mIns[si]));
|
exitBlock->mIns.Insert(0, NativeCodeInstruction(ASMIT_STX, mIns[si]));
|
||||||
mIns[si].mType = ASMIT_NOP;
|
mIns[si].mType = ASMIT_NOP;
|
||||||
|
@ -22813,7 +22922,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
if (j == mIns.Size())
|
if (j == mIns.Size())
|
||||||
{
|
{
|
||||||
if (!prevBlock)
|
if (!prevBlock)
|
||||||
return OptimizeSimpleLoopInvariant(proc);
|
return OptimizeSimpleLoopInvariant(proc, full);
|
||||||
exitBlock->mIns.Insert(0, mIns[ei]);
|
exitBlock->mIns.Insert(0, mIns[ei]);
|
||||||
mIns.Remove(ei);
|
mIns.Remove(ei);
|
||||||
|
|
||||||
|
@ -22845,7 +22954,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
if (i == mIns.Size())
|
if (i == mIns.Size())
|
||||||
{
|
{
|
||||||
if (!prevBlock)
|
if (!prevBlock)
|
||||||
return OptimizeSimpleLoopInvariant(proc);
|
return OptimizeSimpleLoopInvariant(proc, full);
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < si)
|
while (i < si)
|
||||||
|
@ -22890,7 +22999,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
if (i == mIns.Size())
|
if (i == mIns.Size())
|
||||||
{
|
{
|
||||||
if (!prevBlock)
|
if (!prevBlock)
|
||||||
return OptimizeSimpleLoopInvariant(proc);
|
return OptimizeSimpleLoopInvariant(proc, full);
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < si)
|
while (i < si)
|
||||||
|
@ -22907,6 +23016,12 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
}
|
}
|
||||||
|
|
||||||
mIns[si + 2].CopyMode(mIns[si + 0]);
|
mIns[si + 2].CopyMode(mIns[si + 0]);
|
||||||
|
|
||||||
|
if (mIns[si + 2].RequiresYReg())
|
||||||
|
mIns[si + 1].mLive |= LIVE_CPU_REG_Y;
|
||||||
|
if (mIns[si + 2].RequiresXReg())
|
||||||
|
mIns[si + 1].mLive |= LIVE_CPU_REG_X;
|
||||||
|
|
||||||
mIns[si + 0].CopyMode(mIns[ei]);
|
mIns[si + 0].CopyMode(mIns[ei]);
|
||||||
prevBlock->mIns.Push(mIns[si]);
|
prevBlock->mIns.Push(mIns[si]);
|
||||||
mIns.Remove(si);
|
mIns.Remove(si);
|
||||||
|
@ -22927,7 +23042,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
if (j == mIns.Size())
|
if (j == mIns.Size())
|
||||||
{
|
{
|
||||||
if (!prevBlock)
|
if (!prevBlock)
|
||||||
return OptimizeSimpleLoopInvariant(proc);
|
return OptimizeSimpleLoopInvariant(proc, full);
|
||||||
exitBlock->mIns.Insert(0, mIns[ei]);
|
exitBlock->mIns.Insert(0, mIns[ei]);
|
||||||
mIns.Remove(ei);
|
mIns.Remove(ei);
|
||||||
|
|
||||||
|
@ -22950,7 +23065,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
(mIns[i].mType == ASMIT_TAY && (mIns[i - 1].mType == ASMIT_LDA || mIns[i - 1].mType == ASMIT_STA) && mIns[i - 1].mMode == ASMIM_ZERO_PAGE && mIns[i - 1].mAddress == mIns[0].mAddress))
|
(mIns[i].mType == ASMIT_TAY && (mIns[i - 1].mType == ASMIT_LDA || mIns[i - 1].mType == ASMIT_STA) && mIns[i - 1].mMode == ASMIM_ZERO_PAGE && mIns[i - 1].mAddress == mIns[0].mAddress))
|
||||||
{
|
{
|
||||||
if (!prevBlock)
|
if (!prevBlock)
|
||||||
return OptimizeSimpleLoopInvariant(proc);
|
return OptimizeSimpleLoopInvariant(proc, full);
|
||||||
while (i < mIns.Size())
|
while (i < mIns.Size())
|
||||||
{
|
{
|
||||||
mIns[i].mLive |= LIVE_CPU_REG_Y;
|
mIns[i].mLive |= LIVE_CPU_REG_Y;
|
||||||
|
@ -22977,7 +23092,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
(mIns[i].mType == ASMIT_TAX && (mIns[i - 1].mType == ASMIT_LDA || mIns[i - 1].mType == ASMIT_STA) && mIns[i - 1].mMode == ASMIM_ZERO_PAGE && mIns[i - 1].mAddress == mIns[0].mAddress))
|
(mIns[i].mType == ASMIT_TAX && (mIns[i - 1].mType == ASMIT_LDA || mIns[i - 1].mType == ASMIT_STA) && mIns[i - 1].mMode == ASMIM_ZERO_PAGE && mIns[i - 1].mAddress == mIns[0].mAddress))
|
||||||
{
|
{
|
||||||
if (!prevBlock)
|
if (!prevBlock)
|
||||||
return OptimizeSimpleLoopInvariant(proc);
|
return OptimizeSimpleLoopInvariant(proc, full);
|
||||||
while (i < mIns.Size())
|
while (i < mIns.Size())
|
||||||
{
|
{
|
||||||
mIns[i].mLive |= LIVE_CPU_REG_X;
|
mIns[i].mLive |= LIVE_CPU_REG_X;
|
||||||
|
@ -23009,7 +23124,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mAddress == mIns[0].mAddress && !(mIns[1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)))
|
mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mAddress == mIns[0].mAddress && !(mIns[1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)))
|
||||||
{
|
{
|
||||||
if (!prevBlock)
|
if (!prevBlock)
|
||||||
return OptimizeSimpleLoopInvariant(proc);
|
return OptimizeSimpleLoopInvariant(proc, full);
|
||||||
|
|
||||||
prevBlock->mIns.Push(mIns[0]);
|
prevBlock->mIns.Push(mIns[0]);
|
||||||
prevBlock->mIns.Push(mIns[1]);
|
prevBlock->mIns.Push(mIns[1]);
|
||||||
|
@ -23043,7 +23158,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
if (i == mIns.Size())
|
if (i == mIns.Size())
|
||||||
{
|
{
|
||||||
if (!prevBlock)
|
if (!prevBlock)
|
||||||
return OptimizeSimpleLoopInvariant(proc);
|
return OptimizeSimpleLoopInvariant(proc, full);
|
||||||
|
|
||||||
prevBlock->mIns.Push(mIns[ai]);
|
prevBlock->mIns.Push(mIns[ai]);
|
||||||
mIns.Remove(ai);
|
mIns.Remove(ai);
|
||||||
|
@ -23059,7 +23174,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
if (i == mIns.Size())
|
if (i == mIns.Size())
|
||||||
{
|
{
|
||||||
if (!prevBlock)
|
if (!prevBlock)
|
||||||
return OptimizeSimpleLoopInvariant(proc);
|
return OptimizeSimpleLoopInvariant(proc, full);
|
||||||
|
|
||||||
prevBlock->mIns.Push(mIns[ai]);
|
prevBlock->mIns.Push(mIns[ai]);
|
||||||
mIns.Remove(ai);
|
mIns.Remove(ai);
|
||||||
|
@ -23073,7 +23188,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
if (i >= 0 && mIns[i].mType == ASMIT_STA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == mIns[ai].mAddress)
|
if (i >= 0 && mIns[i].mType == ASMIT_STA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == mIns[ai].mAddress)
|
||||||
{
|
{
|
||||||
if (!prevBlock)
|
if (!prevBlock)
|
||||||
return OptimizeSimpleLoopInvariant(proc);
|
return OptimizeSimpleLoopInvariant(proc, full);
|
||||||
|
|
||||||
prevBlock->mIns.Push(mIns[ai]);
|
prevBlock->mIns.Push(mIns[ai]);
|
||||||
mIns.Remove(ai);
|
mIns.Remove(ai);
|
||||||
|
@ -23097,7 +23212,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
if (i == mIns.Size())
|
if (i == mIns.Size())
|
||||||
{
|
{
|
||||||
if (!prevBlock)
|
if (!prevBlock)
|
||||||
return OptimizeSimpleLoopInvariant(proc);
|
return OptimizeSimpleLoopInvariant(proc, full);
|
||||||
|
|
||||||
for (int i = 0; i < mIns.Size(); i++)
|
for (int i = 0; i < mIns.Size(); i++)
|
||||||
mIns[i].mLive |= LIVE_CPU_REG_Y;
|
mIns[i].mLive |= LIVE_CPU_REG_Y;
|
||||||
|
@ -23142,7 +23257,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
if (!fail)
|
if (!fail)
|
||||||
{
|
{
|
||||||
if (!prevBlock)
|
if (!prevBlock)
|
||||||
return OptimizeSimpleLoopInvariant(proc);
|
return OptimizeSimpleLoopInvariant(proc, full);
|
||||||
|
|
||||||
changed = true;
|
changed = true;
|
||||||
|
|
||||||
|
@ -23196,7 +23311,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
if (j == mIns.Size())
|
if (j == mIns.Size())
|
||||||
{
|
{
|
||||||
if (!prevBlock)
|
if (!prevBlock)
|
||||||
return OptimizeSimpleLoopInvariant(proc);
|
return OptimizeSimpleLoopInvariant(proc, full);
|
||||||
prevBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, mIns[i + 0].mAddress));
|
prevBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, mIns[i + 0].mAddress));
|
||||||
prevBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, mIns[i + 1].mAddress));
|
prevBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, mIns[i + 1].mAddress));
|
||||||
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
@ -23220,7 +23335,8 @@ bool NativeCodeBasicBlock::SimpleLoopReversal(NativeCodeProcedure* proc)
|
||||||
|
|
||||||
CheckLive();
|
CheckLive();
|
||||||
|
|
||||||
if (mTrueJump && !mFalseJump && mTrueJump->mTrueJump == mTrueJump && mIns.Size() > 0 && mTrueJump->mIns.Size() > 1 && mTrueJump->mBranch == ASMIT_BCC)
|
if (mTrueJump && !mFalseJump && mTrueJump->mTrueJump == mTrueJump && mIns.Size() > 0 && mTrueJump->mIns.Size() > 1 &&
|
||||||
|
mTrueJump->mBranch == ASMIT_BCC && !mExitRequiredRegs[CPU_REG_C])
|
||||||
{
|
{
|
||||||
NativeCodeBasicBlock* lb = mTrueJump;
|
NativeCodeBasicBlock* lb = mTrueJump;
|
||||||
int lbs = lb->mIns.Size();
|
int lbs = lb->mIns.Size();
|
||||||
|
@ -23466,7 +23582,7 @@ bool NativeCodeBasicBlock::OptimizeXYSimpleLoop(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc)
|
bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc, bool full)
|
||||||
{
|
{
|
||||||
if (!mVisited)
|
if (!mVisited)
|
||||||
{
|
{
|
||||||
|
@ -23517,7 +23633,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc)
|
||||||
|
|
||||||
if (sz == 2 && mTrueJump == this)
|
if (sz == 2 && mTrueJump == this)
|
||||||
{
|
{
|
||||||
changed = OptimizeSimpleLoopInvariant(proc, nullptr, nullptr);
|
changed = OptimizeSimpleLoopInvariant(proc, nullptr, nullptr, full);
|
||||||
|
|
||||||
CheckLive();
|
CheckLive();
|
||||||
}
|
}
|
||||||
|
@ -23656,7 +23772,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc)
|
||||||
mTrueJump = lblock;
|
mTrueJump = lblock;
|
||||||
mFalseJump = nullptr;
|
mFalseJump = nullptr;
|
||||||
|
|
||||||
lblock->OptimizeSimpleLoopInvariant(proc, this, eblock);
|
lblock->OptimizeSimpleLoopInvariant(proc, this, eblock, full);
|
||||||
|
|
||||||
lblock->CheckLive();
|
lblock->CheckLive();
|
||||||
|
|
||||||
|
@ -23729,7 +23845,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc)
|
||||||
|
|
||||||
lblock->CheckLive();
|
lblock->CheckLive();
|
||||||
|
|
||||||
lblock->OptimizeSimpleLoopInvariant(proc, this, eblock);
|
lblock->OptimizeSimpleLoopInvariant(proc, this, eblock, full);
|
||||||
|
|
||||||
lblock->CheckLive();
|
lblock->CheckLive();
|
||||||
|
|
||||||
|
@ -23835,7 +23951,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc)
|
||||||
mTrueJump = lblock;
|
mTrueJump = lblock;
|
||||||
mFalseJump = nullptr;
|
mFalseJump = nullptr;
|
||||||
|
|
||||||
lblock->OptimizeSimpleLoopInvariant(proc, this, eblock);
|
lblock->OptimizeSimpleLoopInvariant(proc, this, eblock, full);
|
||||||
|
|
||||||
lblock->CheckLive();
|
lblock->CheckLive();
|
||||||
|
|
||||||
|
@ -23927,7 +24043,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc)
|
||||||
mTrueJump = lblock;
|
mTrueJump = lblock;
|
||||||
mFalseJump = nullptr;
|
mFalseJump = nullptr;
|
||||||
|
|
||||||
lblock->OptimizeSimpleLoopInvariant(proc, this, eblock);
|
lblock->OptimizeSimpleLoopInvariant(proc, this, eblock, full);
|
||||||
|
|
||||||
lblock->CheckLive();
|
lblock->CheckLive();
|
||||||
|
|
||||||
|
@ -23965,7 +24081,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc)
|
||||||
mTrueJump = lblock;
|
mTrueJump = lblock;
|
||||||
mFalseJump = nullptr;
|
mFalseJump = nullptr;
|
||||||
|
|
||||||
lblock->OptimizeSimpleLoopInvariant(proc, this, eblock);
|
lblock->OptimizeSimpleLoopInvariant(proc, this, eblock, full);
|
||||||
|
|
||||||
lblock->CheckLive();
|
lblock->CheckLive();
|
||||||
|
|
||||||
|
@ -23979,7 +24095,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc)
|
||||||
#if 1
|
#if 1
|
||||||
assert(mBranch != ASMIT_JMP || mFalseJump == nullptr);
|
assert(mBranch != ASMIT_JMP || mFalseJump == nullptr);
|
||||||
if (!changed)
|
if (!changed)
|
||||||
changed = OptimizeSimpleLoopInvariant(proc, nullptr, nullptr);
|
changed = OptimizeSimpleLoopInvariant(proc, nullptr, nullptr, full);
|
||||||
assert(mBranch != ASMIT_JMP || mFalseJump == nullptr);
|
assert(mBranch != ASMIT_JMP || mFalseJump == nullptr);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -23988,9 +24104,9 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc)
|
||||||
|
|
||||||
CheckLive();
|
CheckLive();
|
||||||
|
|
||||||
if (mTrueJump && mTrueJump->OptimizeSimpleLoop(proc))
|
if (mTrueJump && mTrueJump->OptimizeSimpleLoop(proc, full))
|
||||||
changed = true;
|
changed = true;
|
||||||
if (mFalseJump && mFalseJump->OptimizeSimpleLoop(proc))
|
if (mFalseJump && mFalseJump->OptimizeSimpleLoop(proc, full))
|
||||||
changed = true;
|
changed = true;
|
||||||
|
|
||||||
assert(mIns.Size() == 0 || mIns[0].mType != ASMIT_INV);
|
assert(mIns.Size() == 0 || mIns[0].mType != ASMIT_INV);
|
||||||
|
@ -26953,7 +27069,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
for (int i = 2; i + 1 < mIns.Size(); i++)
|
for (int i = 2; i + 1 < mIns.Size(); i++)
|
||||||
{
|
{
|
||||||
if (mIns[i + 0].mType == ASMIT_LDA && (mIns[i + 0].mMode == ASMIM_IMMEDIATE || mIns[i + 0].mMode == ASMIM_ZERO_PAGE) &&
|
if (mIns[i + 0].mType == ASMIT_LDA && (mIns[i + 0].mMode == ASMIM_IMMEDIATE || mIns[i + 0].mMode == ASMIM_ZERO_PAGE) &&
|
||||||
mIns[i + 1].mType == ASMIT_STA && (mIns[i + 1].mMode == ASMIM_ABSOLUTE || mIns[i + 1].mMode == ASMIM_ZERO_PAGE) && !(mIns[i + 1].mFlags & NCIF_VOLATILE))
|
mIns[i + 1].mType == ASMIT_STA && (mIns[i + 1].mMode == ASMIM_ABSOLUTE || mIns[i + 1].mMode == ASMIM_ABSOLUTE_X || mIns[i + 1].mMode == ASMIM_ABSOLUTE_Y || mIns[i + 1].mMode == ASMIM_ZERO_PAGE) && !(mIns[i + 1].mFlags & NCIF_VOLATILE))
|
||||||
{
|
{
|
||||||
if (MoveLoadImmStoreAbsoluteUp(i + 0))
|
if (MoveLoadImmStoreAbsoluteUp(i + 0))
|
||||||
changed = true;
|
changed = true;
|
||||||
|
@ -29895,6 +30011,17 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
|
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0 &&
|
||||||
|
mIns[i + 1].mType == ASMIT_SBC && mIns[i + 1].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mAddress == 0 &&
|
||||||
|
mIns[i + 2].mType == ASMIT_CLC &&
|
||||||
|
mIns[i + 3].mType == ASMIT_ADC)
|
||||||
|
{
|
||||||
|
mIns[i + 0].mAddress = 0xff;
|
||||||
|
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
#if 1
|
#if 1
|
||||||
else if (
|
else if (
|
||||||
mIns[i + 0].mType == ASMIT_LDX && mIns[i + 0].mMode == ASMIM_ABSOLUTE_Y &&
|
mIns[i + 0].mType == ASMIT_LDX && mIns[i + 0].mMode == ASMIM_ABSOLUTE_Y &&
|
||||||
|
@ -30985,32 +31112,56 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0
|
#if 1
|
||||||
|
if (mIns[i + 0].mType == ASMIT_CLC &&
|
||||||
|
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && mIns[i + 3].mAddress == mIns[i + 2].mAddress &&
|
||||||
|
mIns[i + 4].mType == ASMIT_LDA && mIns[i + 4].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
mIns[i + 5].mType == ASMIT_ADC && mIns[i + 5].mMode == ASMIM_ZERO_PAGE && mIns[i + 5].mAddress == mIns[i + 2].mAddress + 1 &&
|
||||||
|
mIns[i + 6].mType == ASMIT_STA && mIns[i + 6].mMode == ASMIM_ZERO_PAGE && mIns[i + 6].mAddress == mIns[i + 5].mAddress &&
|
||||||
|
!(mIns[i + 6].mLive & LIVE_CPU_REG_A))
|
||||||
|
{
|
||||||
|
int yval = RetrieveYValue(i);
|
||||||
|
proc->ResetPatched();
|
||||||
|
if (CheckForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 3].mAddress, mIns[i + 1], i + 7, yval))
|
||||||
|
{
|
||||||
|
proc->ResetPatched();
|
||||||
|
if (PatchForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 3].mAddress, mIns[i + 1], i + 7, yval))
|
||||||
|
{
|
||||||
|
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 3].mType = ASMIT_NOP; mIns[i + 3].mMode = ASMIM_IMPLIED;
|
||||||
|
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if 1
|
||||||
if (mIns[i + 0].mType == ASMIT_CLC &&
|
if (mIns[i + 0].mType == ASMIT_CLC &&
|
||||||
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
|
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
|
||||||
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_ZERO_PAGE &&
|
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_ZERO_PAGE &&
|
||||||
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && mIns[i + 3].mAddress != mIns[i + 1].mAddress &&
|
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && mIns[i + 3].mAddress != mIns[i + 1].mAddress &&
|
||||||
mIns[i + 4].mType == ASMIT_LDA && mIns[i + 4].mMode == ASMIM_ZERO_PAGE && mIns[i + 4].mAddress == mIns[i + 1].mAddress + 1 &&
|
mIns[i + 4].mType == ASMIT_LDA && mIns[i + 4].mMode == ASMIM_ZERO_PAGE &&
|
||||||
mIns[i + 5].mType == ASMIT_ADC && mIns[i + 5].mMode == ASMIM_IMMEDIATE && mIns[i + 5].mAddress == 0 &&
|
mIns[i + 5].mType == ASMIT_ADC && mIns[i + 5].mMode == ASMIM_ZERO_PAGE &&
|
||||||
mIns[i + 6].mType == ASMIT_STA && mIns[i + 6].mMode == ASMIM_ZERO_PAGE && mIns[i + 6].mAddress == mIns[i + 3].mAddress + 1 &&
|
mIns[i + 6].mType == ASMIT_STA && mIns[i + 6].mMode == ASMIM_ZERO_PAGE && mIns[i + 6].mAddress == mIns[i + 3].mAddress + 1 &&
|
||||||
!(mIns[i + 6].mLive & LIVE_CPU_REG_A))
|
!(mIns[i + 6].mLive & LIVE_CPU_REG_A))
|
||||||
{
|
{
|
||||||
|
int yval = RetrieveYValue(i);
|
||||||
proc->ResetPatched();
|
proc->ResetPatched();
|
||||||
if (CheckForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 1].mAddress, mIns[i + 3].mAddress, i + 7, -1))
|
if (CheckForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 3].mAddress, mIns[i + 1], i + 7, yval))
|
||||||
{
|
{
|
||||||
mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED;
|
|
||||||
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
|
||||||
mIns[i + 2].mType = ASMIT_LDA; mIns[i + 2].mLive |= LIVE_CPU_REG_A;
|
|
||||||
|
|
||||||
mIns[i + 4].mType = ASMIT_NOP; mIns[i + 4].mMode = ASMIM_IMPLIED;
|
|
||||||
mIns[i + 5].mType = ASMIT_NOP; mIns[i + 5].mMode = ASMIM_IMPLIED;
|
|
||||||
mIns[i + 6].mType = ASMIT_NOP; mIns[i + 6].mMode = ASMIM_IMPLIED;
|
|
||||||
|
|
||||||
proc->ResetPatched();
|
proc->ResetPatched();
|
||||||
if (PatchForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 1].mAddress, mIns[i + 3].mAddress, i + 7, -1))
|
if (PatchForwardSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 3].mAddress, mIns[i + 1], i + 7, yval))
|
||||||
|
{
|
||||||
|
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 2].mType = ASMIT_LDA;
|
||||||
|
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#if 1
|
#if 1
|
||||||
if (mIns[i + 0].mType == ASMIT_CLC &&
|
if (mIns[i + 0].mType == ASMIT_CLC &&
|
||||||
|
@ -31331,6 +31482,20 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
else if (sz >= 2 &&
|
||||||
|
mIns[sz - 2].ChangesAccuAndFlag() &&
|
||||||
|
mIns[sz - 1].mType == ASMIT_CMP && mIns[sz - 1].mMode == ASMIM_IMMEDIATE && mIns[sz - 1].mAddress == 1 &&
|
||||||
|
(mBranch == ASMIT_BCC || mBranch == ASMIT_BCS) && !mExitRequiredRegs[CPU_REG_Z] && !mExitRequiredRegs[CPU_REG_C])
|
||||||
|
{
|
||||||
|
if (mBranch == ASMIT_BCC)
|
||||||
|
mBranch = ASMIT_BEQ;
|
||||||
|
else
|
||||||
|
mBranch = ASMIT_BNE;
|
||||||
|
|
||||||
|
mIns[sz - 1].mType = ASMIT_NOP; mIns[sz - 1].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[sz - 2].mLive |= LIVE_CPU_REG_Z;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
#if 1
|
#if 1
|
||||||
else if (sz >= 2 &&
|
else if (sz >= 2 &&
|
||||||
mIns[sz - 2].ChangesAccuAndFlag() &&
|
mIns[sz - 2].ChangesAccuAndFlag() &&
|
||||||
|
@ -32764,7 +32929,7 @@ void NativeCodeProcedure::RebuildEntry(void)
|
||||||
|
|
||||||
void NativeCodeProcedure::Optimize(void)
|
void NativeCodeProcedure::Optimize(void)
|
||||||
{
|
{
|
||||||
CheckFunc = !strcmp(mInterProc->mIdent->mString, "main");
|
CheckFunc = !strcmp(mInterProc->mIdent->mString, "bmu_line");
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
int step = 0;
|
int step = 0;
|
||||||
|
@ -32890,6 +33055,7 @@ void NativeCodeProcedure::Optimize(void)
|
||||||
if (mEntryBlock->PeepHoleOptimizer(this, step))
|
if (mEntryBlock->PeepHoleOptimizer(this, step))
|
||||||
changed = true;
|
changed = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
if (step >= 3)
|
if (step >= 3)
|
||||||
{
|
{
|
||||||
|
@ -32939,7 +33105,7 @@ void NativeCodeProcedure::Optimize(void)
|
||||||
if (step > 0)
|
if (step > 0)
|
||||||
{
|
{
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
if (mEntryBlock->OptimizeSimpleLoop(this))
|
if (mEntryBlock->OptimizeSimpleLoop(this, step > 4))
|
||||||
changed = true;
|
changed = true;
|
||||||
|
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
|
@ -33004,7 +33170,6 @@ void NativeCodeProcedure::Optimize(void)
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
mEntryBlock->CheckBlocks(true);
|
mEntryBlock->CheckBlocks(true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
if (step == 3)
|
if (step == 3)
|
||||||
{
|
{
|
||||||
|
@ -33053,7 +33218,6 @@ void NativeCodeProcedure::Optimize(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (step > 3 && !changed)
|
if (step > 3 && !changed)
|
||||||
{
|
{
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
|
|
|
@ -79,6 +79,7 @@ static const uint32 NCIF_USE_CPU_REG_Y = 0x00004000;
|
||||||
|
|
||||||
// use a 32bit zero page register indexed by X for JSR
|
// use a 32bit zero page register indexed by X for JSR
|
||||||
static const uint32 NCIF_USE_ZP_32_X = 0x00008000;
|
static const uint32 NCIF_USE_ZP_32_X = 0x00008000;
|
||||||
|
static const uint32 NICF_USE_ZP_ADDR = 0x00010000;
|
||||||
|
|
||||||
class NativeCodeInstruction
|
class NativeCodeInstruction
|
||||||
{
|
{
|
||||||
|
@ -217,11 +218,11 @@ public:
|
||||||
void BlockSizeReduction(NativeCodeProcedure* proc, int xenter, int yenter);
|
void BlockSizeReduction(NativeCodeProcedure* proc, int xenter, int yenter);
|
||||||
bool BlockSizeCopyReduction(NativeCodeProcedure* proc, int & si, int & di);
|
bool BlockSizeCopyReduction(NativeCodeProcedure* proc, int & si, int & di);
|
||||||
|
|
||||||
bool OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc);
|
bool OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc, bool full);
|
||||||
bool OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc, NativeCodeBasicBlock * prevBlock, NativeCodeBasicBlock* exitBlock);
|
bool OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc, NativeCodeBasicBlock * prevBlock, NativeCodeBasicBlock* exitBlock, bool full);
|
||||||
bool RemoveSimpleLoopUnusedIndex(void);
|
bool RemoveSimpleLoopUnusedIndex(void);
|
||||||
|
|
||||||
bool OptimizeSimpleLoop(NativeCodeProcedure* proc);
|
bool OptimizeSimpleLoop(NativeCodeProcedure* proc, bool full);
|
||||||
bool SimpleLoopReversal(NativeCodeProcedure* proc);
|
bool SimpleLoopReversal(NativeCodeProcedure* proc);
|
||||||
bool OptimizeInnerLoop(NativeCodeProcedure* proc, NativeCodeBasicBlock* head, NativeCodeBasicBlock* tail, GrowingArray<NativeCodeBasicBlock*>& blocks);
|
bool OptimizeInnerLoop(NativeCodeProcedure* proc, NativeCodeBasicBlock* head, NativeCodeBasicBlock* tail, GrowingArray<NativeCodeBasicBlock*>& blocks);
|
||||||
bool OptimizeXYSimpleLoop(void);
|
bool OptimizeXYSimpleLoop(void);
|
||||||
|
@ -484,6 +485,11 @@ public:
|
||||||
bool CheckSingleUseGlobalLoad(const NativeCodeBasicBlock* block, int reg, int at, const NativeCodeInstruction& ains, int cycles);
|
bool CheckSingleUseGlobalLoad(const NativeCodeBasicBlock* block, int reg, int at, const NativeCodeInstruction& ains, int cycles);
|
||||||
bool PatchSingleUseGlobalLoad(const NativeCodeBasicBlock* block, int reg, int at, const NativeCodeInstruction& ains);
|
bool PatchSingleUseGlobalLoad(const NativeCodeBasicBlock* block, int reg, int at, const NativeCodeInstruction& ains);
|
||||||
|
|
||||||
|
// reg : base register pair to replace
|
||||||
|
// base: new base register
|
||||||
|
// iins : indexing instruction
|
||||||
|
// at : start position in block
|
||||||
|
// yval: known y immediate value of -1 if not known
|
||||||
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);
|
||||||
|
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue