Improved value forwarding across conditiona branches
This commit is contained in:
parent
3a94be4a35
commit
8de4bef436
|
@ -199,6 +199,14 @@ public:
|
|||
for (i = 0; i < size; i++) array[i] = a.array[i];
|
||||
}
|
||||
|
||||
GrowingArray & operator=(const GrowingArray& a)
|
||||
{
|
||||
Grow(a.size, true);
|
||||
int i;
|
||||
for (i = 0; i < size; i++) array[i] = a.array[i];
|
||||
return *this;
|
||||
}
|
||||
|
||||
~GrowingArray(void)
|
||||
{
|
||||
delete[] array;
|
||||
|
|
|
@ -55,38 +55,11 @@ bool ByteCodeInstruction::IsStore(void) const
|
|||
|
||||
bool ByteCodeInstruction::ChangesAccu(void) const
|
||||
{
|
||||
if (mCode == BC_LOAD_REG_16 || mCode == BC_LOAD_REG_32)
|
||||
return true;
|
||||
if (mCode >= BC_BINOP_ADDR_16 && mCode <= BC_BINOP_SHRR_I16)
|
||||
return true;
|
||||
if (mCode >= BC_BINOP_CMPUR_16 && mCode <= BC_BINOP_CMPSI_16)
|
||||
return true;
|
||||
if (mCode >= BC_OP_NEGATE_16 && mCode <= BC_OP_INVERT_16)
|
||||
return true;
|
||||
if (mCode >= BC_BINOP_ADD_F32 && mCode <= BC_OP_CEIL_F32)
|
||||
return true;
|
||||
if (mCode >= BC_CONV_U16_F32 && mCode <= BC_CONV_F32_I16)
|
||||
return true;
|
||||
if (mCode >= BC_BINOP_SHLI_16 && mCode <= BC_BINOP_SHRI_U16)
|
||||
return true;
|
||||
if (mCode >= BC_SET_EQ && mCode <= BC_SET_LE)
|
||||
return true;
|
||||
if (mCode == BC_JSR || mCode == BC_CALL)
|
||||
return true;
|
||||
|
||||
return ChangesRegister(BC_REG_ACCU);
|
||||
|
||||
}
|
||||
|
||||
bool ByteCodeInstruction::ChangesAddr(void) const
|
||||
{
|
||||
if (mCode == BC_ADDR_REG)
|
||||
return true;
|
||||
if (mCode >= BC_LOAD_ABS_U8 && mCode <= BC_STORE_ABS_32)
|
||||
return true;
|
||||
if (mCode == BC_JSR || mCode == BC_CALL)
|
||||
return true;
|
||||
|
||||
return ChangesRegister(BC_REG_ADDR);
|
||||
}
|
||||
|
||||
|
@ -160,6 +133,38 @@ bool ByteCodeInstruction::ChangesRegister(uint32 reg) const
|
|||
return true;
|
||||
}
|
||||
|
||||
if (reg == BC_REG_ACCU)
|
||||
{
|
||||
if (mCode == BC_LOAD_REG_16 || mCode == BC_LOAD_REG_32)
|
||||
return true;
|
||||
if (mCode >= BC_BINOP_ADDR_16 && mCode <= BC_BINOP_SHRR_I16)
|
||||
return true;
|
||||
if (mCode >= BC_BINOP_CMPUR_16 && mCode <= BC_BINOP_CMPSI_16)
|
||||
return true;
|
||||
if (mCode >= BC_OP_NEGATE_16 && mCode <= BC_OP_INVERT_16)
|
||||
return true;
|
||||
if (mCode >= BC_BINOP_ADD_F32 && mCode <= BC_OP_CEIL_F32)
|
||||
return true;
|
||||
if (mCode >= BC_CONV_U16_F32 && mCode <= BC_CONV_F32_I16)
|
||||
return true;
|
||||
if (mCode >= BC_BINOP_SHLI_16 && mCode <= BC_BINOP_SHRI_U16)
|
||||
return true;
|
||||
if (mCode >= BC_SET_EQ && mCode <= BC_SET_LE)
|
||||
return true;
|
||||
if (mCode == BC_JSR || mCode == BC_CALL)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (reg == BC_REG_ADDR)
|
||||
{
|
||||
if (mCode == BC_ADDR_REG)
|
||||
return true;
|
||||
if (mCode >= BC_LOAD_ABS_U8 && mCode <= BC_STORE_ABS_32)
|
||||
return true;
|
||||
if (mCode == BC_JSR || mCode == BC_CALL)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2537,6 +2542,16 @@ void ByteCodeBasicBlock::PeepHoleOptimizer(void)
|
|||
mIns[i + 0].mCode = BC_NOP;
|
||||
mBranch = TransposeBranchCondition(mBranch);
|
||||
}
|
||||
else if (mIns[i + 0].mCode == BC_LOAD_REG_16 &&
|
||||
mIns[i + 1].mCode == BC_STORE_REG_16 &&
|
||||
mIns[i + 2].mCode == BC_LOAD_REG_16 && mIns[i + 0].mRegister == mIns[i + 2].mRegister)
|
||||
{
|
||||
mIns[i + 2].mCode = BC_NOP;
|
||||
}
|
||||
else if (mIns[i + 0].mCode == BC_CONST_16 && mIns[i + 2].mCode == BC_CONST_16 && mIns[i + 0].mRegister == mIns[i + 2].mRegister && mIns[i + 0].mValue == mIns[i + 2].mValue && !mIns[i + 1].ChangesRegister(mIns[i + 0].mRegister))
|
||||
{
|
||||
mIns[i + 2].mCode = BC_NOP;
|
||||
}
|
||||
}
|
||||
if (i + 1 < mIns.Size())
|
||||
{
|
||||
|
@ -2601,6 +2616,13 @@ void ByteCodeBasicBlock::PeepHoleOptimizer(void)
|
|||
mIns[i + 1].mCode = BC_NOP;
|
||||
progress = true;
|
||||
}
|
||||
else if (mIns[i].mCode == BC_LOAD_LOCAL_16 && mIns[i + 1].mCode == BC_ADDR_REG && mIns[i].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal)
|
||||
{
|
||||
mIns[i].mRegister = BC_REG_ADDR;
|
||||
mIns[i + 1].mCode = BC_NOP;
|
||||
progress = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ((mIns[i].mCode == BC_LOAD_REG_16 || mIns[i].mCode == BC_STORE_REG_16 || mIns[i].mCode == BC_LOAD_REG_32 || mIns[i].mCode == BC_STORE_REG_32) && accuTemp == mIns[i].mRegister)
|
||||
|
@ -2948,9 +2970,12 @@ const char* ByteCodeProcedure::TempName(uint8 tmp, char* buffer, InterCodeProced
|
|||
else if (tmp >= BC_REG_TMP && tmp < BC_REG_TMP + proc->mTempSize)
|
||||
{
|
||||
int i = 0;
|
||||
while (i + 1 < proc->mTempOffset.Size() && proc->mTempOffset[i + 1] <= tmp - BC_REG_TMP)
|
||||
while (i < proc->mTempOffset.Size() && proc->mTempOffset[i] != tmp - BC_REG_TMP)
|
||||
i++;
|
||||
sprintf_s(buffer, 10, "T%d", i);
|
||||
if (i < proc->mTempOffset.Size())
|
||||
sprintf_s(buffer, 10, "T%d", i);
|
||||
else
|
||||
sprintf_s(buffer, 10, "$%02x", tmp);
|
||||
return buffer;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -24,6 +24,24 @@ ValueSet::ValueSet(const ValueSet& values)
|
|||
mInstructions[i] = values.mInstructions[i];
|
||||
}
|
||||
|
||||
ValueSet& ValueSet::operator=(const ValueSet& values)
|
||||
{
|
||||
int i;
|
||||
|
||||
mNum = values.mNum;
|
||||
if (mSize != values.mSize)
|
||||
{
|
||||
delete[] mInstructions;
|
||||
mSize = values.mSize;
|
||||
mInstructions = new InterInstructionPtr[mSize];
|
||||
}
|
||||
|
||||
for (i = 0; i < mNum; i++)
|
||||
mInstructions[i] = values.mInstructions[i];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ValueSet::~ValueSet(void)
|
||||
{
|
||||
delete[] mInstructions;
|
||||
|
@ -265,7 +283,7 @@ static bool MemRange(const InterInstruction * ins, const GrowingInstructionPtrAr
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool StoreAliasing(const InterInstruction * lins, const InterInstruction* sins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals)
|
||||
static bool StoreAliasing(const InterInstruction * lins, const InterInstruction* sins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams)
|
||||
{
|
||||
InterMemory lmem, smem;
|
||||
int lvindex, svindex;
|
||||
|
@ -286,12 +304,31 @@ static bool StoreAliasing(const InterInstruction * lins, const InterInstruction*
|
|||
|
||||
if (lmem == IM_LOCAL)
|
||||
return aliasedLocals[lvindex];
|
||||
else if (lmem == IM_PARAM)
|
||||
return aliasedParams[lvindex];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals)
|
||||
void ValueSet::Intersect(ValueSet& set)
|
||||
{
|
||||
int k = 0;
|
||||
for(int i=0; i<mNum; i++)
|
||||
{
|
||||
int j = 0;
|
||||
while (j < set.mNum && mInstructions[i] != set.mInstructions[j])
|
||||
j++;
|
||||
if (j < set.mNum)
|
||||
{
|
||||
mInstructions[k] = mInstructions[i];
|
||||
k++;
|
||||
}
|
||||
}
|
||||
mNum = k;
|
||||
}
|
||||
|
||||
void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams)
|
||||
{
|
||||
int i, value, temp;
|
||||
|
||||
|
@ -383,7 +420,7 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr
|
|||
i = 0;
|
||||
while (i < mNum)
|
||||
{
|
||||
if ((mInstructions[i]->mCode == IC_LOAD || mInstructions[i]->mCode == IC_STORE) && StoreAliasing(mInstructions[i], &ins, tvalue, aliasedLocals))
|
||||
if ((mInstructions[i]->mCode == IC_LOAD || mInstructions[i]->mCode == IC_STORE) && StoreAliasing(mInstructions[i], &ins, tvalue, aliasedLocals, aliasedParams))
|
||||
{
|
||||
mNum--;
|
||||
if (mNum > 0)
|
||||
|
@ -399,7 +436,7 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr
|
|||
i = 0;
|
||||
while (i < mNum)
|
||||
{
|
||||
if ((mInstructions[i]->mCode == IC_LOAD || mInstructions[i]->mCode == IC_STORE) && StoreAliasing(mInstructions[i], &ins, tvalue, aliasedLocals))
|
||||
if ((mInstructions[i]->mCode == IC_LOAD || mInstructions[i]->mCode == IC_STORE) && StoreAliasing(mInstructions[i], &ins, tvalue, aliasedLocals, aliasedParams))
|
||||
{
|
||||
mNum--;
|
||||
if (mNum > 0)
|
||||
|
@ -556,7 +593,7 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr
|
|||
ins.mSTemp[0] = -1;
|
||||
ins.mSTemp[1] = -1;
|
||||
|
||||
UpdateValue(ins, tvalue, aliasedLocals);
|
||||
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -575,7 +612,7 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr
|
|||
ins.mSTemp[1] = -1;
|
||||
assert(ins.mSTemp[0] >= 0);
|
||||
|
||||
UpdateValue(ins, tvalue, aliasedLocals);
|
||||
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -586,7 +623,7 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr
|
|||
ins.mSTemp[0] = -1;
|
||||
ins.mSTemp[1] = -1;
|
||||
|
||||
UpdateValue(ins, tvalue, aliasedLocals);
|
||||
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -601,7 +638,7 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr
|
|||
ins.mSTemp[1] = -1;
|
||||
assert(ins.mSTemp[0] >= 0);
|
||||
|
||||
UpdateValue(ins, tvalue, aliasedLocals);
|
||||
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -613,7 +650,7 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr
|
|||
ins.mSTemp[0] = -1;
|
||||
ins.mSTemp[1] = -1;
|
||||
|
||||
UpdateValue(ins, tvalue, aliasedLocals);
|
||||
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -623,7 +660,7 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr
|
|||
ins.mOperator = IA_NEG;
|
||||
ins.mSTemp[1] = -1;
|
||||
|
||||
UpdateValue(ins, tvalue, aliasedLocals);
|
||||
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -637,7 +674,7 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr
|
|||
ins.mSTemp[0] = -1;
|
||||
ins.mSTemp[1] = -1;
|
||||
|
||||
UpdateValue(ins, tvalue, aliasedLocals);
|
||||
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -647,7 +684,7 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr
|
|||
ins.mSTemp[1] = -1;
|
||||
assert(ins.mSTemp[0] >= 0);
|
||||
|
||||
UpdateValue(ins, tvalue, aliasedLocals);
|
||||
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -864,7 +901,7 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr
|
|||
ins.mSTemp[0] = -1;
|
||||
ins.mSTemp[1] = -1;
|
||||
|
||||
UpdateValue(ins, tvalue, aliasedLocals);
|
||||
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
|
||||
}
|
||||
break;
|
||||
case IT_POINTER:
|
||||
|
@ -878,7 +915,7 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr
|
|||
ins.mSTemp[0] = -1;
|
||||
ins.mSTemp[1] = -1;
|
||||
|
||||
UpdateValue(ins, tvalue, aliasedLocals);
|
||||
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
|
||||
}
|
||||
else if (ins.mSTemp[1] == ins.mSTemp[0])
|
||||
{
|
||||
|
@ -904,7 +941,7 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr
|
|||
ins.mSTemp[0] = -1;
|
||||
ins.mSTemp[1] = -1;
|
||||
|
||||
UpdateValue(ins, tvalue, aliasedLocals);
|
||||
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1006,31 +1043,39 @@ static void FilterTempDefineUsage(NumberSet& requiredTemps, NumberSet& providedT
|
|||
}
|
||||
}
|
||||
|
||||
void InterInstruction::CollectLocalAddressTemps(GrowingIntArray& localTable)
|
||||
void InterInstruction::CollectLocalAddressTemps(GrowingIntArray& localTable, GrowingIntArray& paramTable)
|
||||
{
|
||||
if (mCode == IC_CONSTANT)
|
||||
{
|
||||
if (mTType == IT_POINTER && mMemory == IM_LOCAL)
|
||||
localTable[mTTemp] = mVarIndex;
|
||||
else if (mTType == IT_POINTER && mMemory == IM_PARAM)
|
||||
paramTable[mTTemp] = mVarIndex;
|
||||
}
|
||||
else if (mCode == IC_LEA)
|
||||
{
|
||||
if (mMemory == IM_LOCAL)
|
||||
localTable[mTTemp] = localTable[mSTemp[1]];
|
||||
else if (mMemory == IM_PARAM)
|
||||
paramTable[mTTemp] = paramTable[mSTemp[1]];
|
||||
}
|
||||
else if (mCode == IC_LOAD_TEMPORARY)
|
||||
{
|
||||
localTable[mTTemp] = localTable[mSTemp[0]];
|
||||
paramTable[mTTemp] = paramTable[mSTemp[0]];
|
||||
}
|
||||
}
|
||||
|
||||
void InterInstruction::MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals)
|
||||
void InterInstruction::MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals, const GrowingIntArray& paramTable, NumberSet& aliasedParams)
|
||||
{
|
||||
if (mCode == IC_STORE)
|
||||
{
|
||||
int l = localTable[mSTemp[0]];
|
||||
if (l >= 0)
|
||||
aliasedLocals += l;
|
||||
l = paramTable[mSTemp[0]];
|
||||
if (l >= 0)
|
||||
aliasedParams += l;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1156,7 +1201,7 @@ void InterInstruction::BuildCallerSaveTempSet(NumberSet& requiredTemps, NumberSe
|
|||
if (mSTemp[2] >= 0) requiredTemps += mSTemp[2];
|
||||
}
|
||||
|
||||
bool InterInstruction::RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars, InterInstruction* pre, NumberSet& requiredTemps)
|
||||
bool InterInstruction::RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars, NumberSet& requiredTemps)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
|
@ -1328,7 +1373,7 @@ void InterInstruction::ShrinkActiveTemporaries(FastNumberSet& set, GrowingTypeAr
|
|||
if (mSTemp[2] >= 0) mSTemp[2] = set.Index(mSTemp[2]);
|
||||
}
|
||||
|
||||
void InterInstruction::CollectSimpleLocals(FastNumberSet& complexLocals, FastNumberSet& simpleLocals, GrowingTypeArray& localTypes)
|
||||
void InterInstruction::CollectSimpleLocals(FastNumberSet& complexLocals, FastNumberSet& simpleLocals, GrowingTypeArray& localTypes, FastNumberSet& complexParams, FastNumberSet& simpleParams, GrowingTypeArray& paramTypes)
|
||||
{
|
||||
switch (mCode)
|
||||
{
|
||||
|
@ -1341,6 +1386,14 @@ void InterInstruction::CollectSimpleLocals(FastNumberSet& complexLocals, FastNum
|
|||
else
|
||||
complexLocals += mVarIndex;
|
||||
}
|
||||
else if (mMemory == IM_PARAM && mSTemp[0] < 0)
|
||||
{
|
||||
paramTypes[mVarIndex] = mTType;
|
||||
if (mOperandSize == 2)
|
||||
simpleParams += mVarIndex;
|
||||
else
|
||||
complexParams += mVarIndex;
|
||||
}
|
||||
break;
|
||||
case IC_STORE:
|
||||
if (mMemory == IM_LOCAL && mSTemp[1] < 0)
|
||||
|
@ -1351,14 +1404,26 @@ void InterInstruction::CollectSimpleLocals(FastNumberSet& complexLocals, FastNum
|
|||
else
|
||||
complexLocals += mVarIndex;
|
||||
}
|
||||
else if (mMemory == IM_PARAM && mSTemp[1] < 0)
|
||||
{
|
||||
paramTypes[mVarIndex] = mSType[0];
|
||||
if (mOperandSize == 2)
|
||||
simpleParams += mVarIndex;
|
||||
else
|
||||
complexParams += mVarIndex;
|
||||
}
|
||||
break;
|
||||
case IC_LEA:
|
||||
if (mMemory == IM_LOCAL && mSTemp[1] < 0)
|
||||
complexLocals += mVarIndex;
|
||||
else if (mMemory == IM_PARAM && mSTemp[1] < 0)
|
||||
complexParams += mVarIndex;
|
||||
break;
|
||||
case IC_CONSTANT:
|
||||
if (mTType == IT_POINTER && mMemory == IM_LOCAL)
|
||||
complexLocals += mVarIndex;
|
||||
else if (mTType == IT_POINTER && mMemory == IM_PARAM)
|
||||
complexParams += mVarIndex;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1476,8 +1541,14 @@ void InterInstruction::Disassemble(FILE* file)
|
|||
if (mTTemp >= 0) fprintf(file, "R%d(%c)", mTTemp, typechars[mTType]);
|
||||
fprintf(file, "\t<-\t");
|
||||
if (mSTemp[2] >= 0) fprintf(file, "R%d(%c%c), ", mSTemp[2], typechars[mSType[2]], mSFinal[2] ? 'F' : '-');
|
||||
if (mSTemp[1] >= 0) fprintf(file, "R%d(%c%c), ", mSTemp[1], typechars[mSType[1]], mSFinal[1] ? 'F' : '-');
|
||||
if (mSTemp[0] >= 0) fprintf(file, "R%d(%c%c)", mSTemp[0], typechars[mSType[0]], mSFinal[0] ? 'F' : '-');
|
||||
if (mSTemp[1] >= 0)
|
||||
fprintf(file, "R%d(%c%c), ", mSTemp[1], typechars[mSType[1]], mSFinal[1] ? 'F' : '-');
|
||||
else if (this->mCode == IC_STORE)
|
||||
fprintf(file, "V%d+%d, ", mVarIndex, mSIntConst[1]);
|
||||
if (mSTemp[0] >= 0)
|
||||
fprintf(file, "R%d(%c%c)", mSTemp[0], typechars[mSType[0]], mSFinal[0] ? 'F' : '-');
|
||||
else if (this->mCode == IC_LOAD)
|
||||
fprintf(file, "V%d+%d", mVarIndex, mSIntConst[0]);
|
||||
if (this->mCode == IC_CONSTANT)
|
||||
{
|
||||
if (mTType == IT_POINTER)
|
||||
|
@ -1495,8 +1566,10 @@ void InterInstruction::Disassemble(FILE* file)
|
|||
}
|
||||
|
||||
InterCodeBasicBlock::InterCodeBasicBlock(void)
|
||||
: mInstructions(InterInstruction()), mEntryRenameTable(-1), mExitRenameTable(-1)
|
||||
: mInstructions(InterInstruction()), mEntryRenameTable(-1), mExitRenameTable(-1), mMergeTValues(nullptr)
|
||||
{
|
||||
mInPath = false;
|
||||
mLoopHead = false;
|
||||
}
|
||||
|
||||
InterCodeBasicBlock::~InterCodeBasicBlock(void)
|
||||
|
@ -1533,9 +1606,13 @@ void InterCodeBasicBlock::GenerateTraces(void)
|
|||
{
|
||||
int i;
|
||||
|
||||
if (mInPath)
|
||||
mLoopHead = true;
|
||||
|
||||
if (!mVisited)
|
||||
{
|
||||
mVisited = true;
|
||||
mInPath = true;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
|
@ -1575,6 +1652,8 @@ void InterCodeBasicBlock::GenerateTraces(void)
|
|||
|
||||
if (mTrueJump) mTrueJump->GenerateTraces();
|
||||
if (mFalseJump) mFalseJump->GenerateTraces();
|
||||
|
||||
mInPath = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2076,7 +2155,7 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction& ins, const GrowingIn
|
|||
}
|
||||
|
||||
|
||||
void InterCodeBasicBlock::CollectLocalAddressTemps(GrowingIntArray& localTable)
|
||||
void InterCodeBasicBlock::CollectLocalAddressTemps(GrowingIntArray& localTable, GrowingIntArray& paramTable)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -2085,14 +2164,14 @@ void InterCodeBasicBlock::CollectLocalAddressTemps(GrowingIntArray& localTable)
|
|||
mVisited = true;
|
||||
|
||||
for (i = 0; i < mInstructions.Size(); i++)
|
||||
mInstructions[i].CollectLocalAddressTemps(localTable);
|
||||
mInstructions[i].CollectLocalAddressTemps(localTable, paramTable);
|
||||
|
||||
if (mTrueJump) mTrueJump->CollectLocalAddressTemps(localTable);
|
||||
if (mFalseJump) mFalseJump->CollectLocalAddressTemps(localTable);
|
||||
if (mTrueJump) mTrueJump->CollectLocalAddressTemps(localTable, paramTable);
|
||||
if (mFalseJump) mFalseJump->CollectLocalAddressTemps(localTable, paramTable);
|
||||
}
|
||||
}
|
||||
|
||||
void InterCodeBasicBlock::MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals)
|
||||
void InterCodeBasicBlock::MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals, const GrowingIntArray& paramTable, NumberSet& aliasedParams)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -2101,10 +2180,10 @@ void InterCodeBasicBlock::MarkAliasedLocalTemps(const GrowingIntArray& localTabl
|
|||
mVisited = true;
|
||||
|
||||
for (i = 0; i < mInstructions.Size(); i++)
|
||||
mInstructions[i].MarkAliasedLocalTemps(localTable, aliasedLocals);
|
||||
mInstructions[i].MarkAliasedLocalTemps(localTable, aliasedLocals, paramTable, aliasedParams);
|
||||
|
||||
if (mTrueJump) mTrueJump->MarkAliasedLocalTemps(localTable, aliasedLocals);
|
||||
if (mFalseJump) mFalseJump->MarkAliasedLocalTemps(localTable, aliasedLocals);
|
||||
if (mTrueJump) mTrueJump->MarkAliasedLocalTemps(localTable, aliasedLocals, paramTable, aliasedParams);
|
||||
if (mFalseJump) mFalseJump->MarkAliasedLocalTemps(localTable, aliasedLocals, paramTable, aliasedParams);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2351,13 +2430,11 @@ bool InterCodeBasicBlock::RemoveUnusedStoreInstructions(const GrowingVariableArr
|
|||
NumberSet requiredVars(mExitRequiredVars);
|
||||
int i;
|
||||
|
||||
for (i = mInstructions.Size() - 1; i > 0; i--)
|
||||
for (i = mInstructions.Size() - 1; i >= 0; i--)
|
||||
{
|
||||
if (mInstructions[i].RemoveUnusedStoreInstructions(localVars, &(mInstructions[i - 1]), requiredVars))
|
||||
if (mInstructions[i].RemoveUnusedStoreInstructions(localVars, requiredVars))
|
||||
changed = true;
|
||||
}
|
||||
if (mInstructions[0].RemoveUnusedStoreInstructions(localVars, nullptr, requiredVars))
|
||||
changed = true;
|
||||
|
||||
if (mTrueJump)
|
||||
{
|
||||
|
@ -2375,7 +2452,7 @@ bool InterCodeBasicBlock::RemoveUnusedStoreInstructions(const GrowingVariableArr
|
|||
|
||||
}
|
||||
|
||||
void InterCodeBasicBlock::PerformValueForwarding(const GrowingInstructionPtrArray& tvalue, const ValueSet& values, FastNumberSet& tvalid, const NumberSet& aliasedLocals)
|
||||
void InterCodeBasicBlock::PerformValueForwarding(const GrowingInstructionPtrArray& tvalue, const ValueSet& values, FastNumberSet& tvalid, const NumberSet& aliasedLocals, const NumberSet& aliasedParams)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -2384,32 +2461,57 @@ void InterCodeBasicBlock::PerformValueForwarding(const GrowingInstructionPtrArra
|
|||
GrowingInstructionPtrArray ltvalue(tvalue);
|
||||
ValueSet lvalues(values);
|
||||
|
||||
mVisited = true;
|
||||
|
||||
tvalid.Clear();
|
||||
|
||||
if (mNumEntries != 1)
|
||||
if (mLoopHead)
|
||||
{
|
||||
lvalues.FlushAll();
|
||||
ltvalue.Clear();
|
||||
}
|
||||
else
|
||||
#if 0
|
||||
else if (mNumEntries > 1)
|
||||
{
|
||||
for (i = 0; i < ltvalue.Size(); i++)
|
||||
lvalues.FlushAll();
|
||||
ltvalue.Clear();
|
||||
}
|
||||
#endif
|
||||
else if (mNumEntries > 0)
|
||||
{
|
||||
if (mNumEntered > 0)
|
||||
{
|
||||
if (ltvalue[i])
|
||||
tvalid += i;
|
||||
lvalues.Intersect(mMergeValues);
|
||||
for (int i = 0; i < ltvalue.Size(); i++)
|
||||
{
|
||||
if (mMergeTValues[i] != ltvalue[i])
|
||||
ltvalue[i] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
mNumEntered++;
|
||||
|
||||
if (mNumEntered < mNumEntries)
|
||||
{
|
||||
mMergeTValues = ltvalue;
|
||||
mMergeValues = lvalues;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mVisited = true;
|
||||
|
||||
tvalid.Clear();
|
||||
for (i = 0; i < ltvalue.Size(); i++)
|
||||
{
|
||||
if (ltvalue[i])
|
||||
tvalid += i;
|
||||
}
|
||||
|
||||
for (i = 0; i < mInstructions.Size(); i++)
|
||||
{
|
||||
lvalues.UpdateValue(mInstructions[i], ltvalue, aliasedLocals);
|
||||
lvalues.UpdateValue(mInstructions[i], ltvalue, aliasedLocals, aliasedParams);
|
||||
mInstructions[i].PerformValueForwarding(ltvalue, tvalid);
|
||||
}
|
||||
|
||||
if (mTrueJump) mTrueJump->PerformValueForwarding(ltvalue, lvalues, tvalid, aliasedLocals);
|
||||
if (mFalseJump) mFalseJump->PerformValueForwarding(ltvalue, lvalues, tvalid, aliasedLocals);
|
||||
if (mTrueJump) mTrueJump->PerformValueForwarding(ltvalue, lvalues, tvalid, aliasedLocals, aliasedParams);
|
||||
if (mFalseJump) mFalseJump->PerformValueForwarding(ltvalue, lvalues, tvalid, aliasedLocals, aliasedParams);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2974,7 +3076,7 @@ void InterCodeBasicBlock::CollectVariables(GrowingVariableArray& globalVars, Gro
|
|||
}
|
||||
}
|
||||
|
||||
void InterCodeBasicBlock::CollectSimpleLocals(FastNumberSet& complexLocals, FastNumberSet& simpleLocals, GrowingTypeArray& localTypes)
|
||||
void InterCodeBasicBlock::CollectSimpleLocals(FastNumberSet& complexLocals, FastNumberSet& simpleLocals, GrowingTypeArray& localTypes, FastNumberSet& complexParams, FastNumberSet& simpleParams, GrowingTypeArray& paramTypes)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -2984,11 +3086,11 @@ void InterCodeBasicBlock::CollectSimpleLocals(FastNumberSet& complexLocals, Fast
|
|||
|
||||
for (i = 0; i < mInstructions.Size(); i++)
|
||||
{
|
||||
mInstructions[i].CollectSimpleLocals(complexLocals, simpleLocals, localTypes);
|
||||
mInstructions[i].CollectSimpleLocals(complexLocals, simpleLocals, localTypes, complexParams, simpleParams, paramTypes);
|
||||
}
|
||||
|
||||
if (mTrueJump) mTrueJump->CollectSimpleLocals(complexLocals, simpleLocals, localTypes);
|
||||
if (mFalseJump) mFalseJump->CollectSimpleLocals(complexLocals, simpleLocals, localTypes);
|
||||
if (mTrueJump) mTrueJump->CollectSimpleLocals(complexLocals, simpleLocals, localTypes, complexParams, simpleParams, paramTypes);
|
||||
if (mFalseJump) mFalseJump->CollectSimpleLocals(complexLocals, simpleLocals, localTypes, complexParams, simpleParams, paramTypes);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3055,7 +3157,8 @@ void InterCodeBasicBlock::Disassemble(FILE* file, bool dumpSets)
|
|||
{
|
||||
mVisited = true;
|
||||
|
||||
fprintf(file, "L%d: (%d)\n", mIndex, mNumEntries);
|
||||
const char* s = mLoopHead ? "Head" : "";
|
||||
fprintf(file, "L%d: (%d) %s\n", mIndex, mNumEntries, s);
|
||||
|
||||
if (dumpSets)
|
||||
{
|
||||
|
@ -3106,7 +3209,10 @@ void InterCodeProcedure::ResetVisited(void)
|
|||
int i;
|
||||
|
||||
for (i = 0; i < mBlocks.Size(); i++)
|
||||
{
|
||||
mBlocks[i]->mVisited = false;
|
||||
mBlocks[i]->mNumEntered = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void InterCodeProcedure::Append(InterCodeBasicBlock* block)
|
||||
|
@ -3331,18 +3437,22 @@ void InterCodeProcedure::Close(void)
|
|||
//
|
||||
// Find all local variables that are never aliased
|
||||
//
|
||||
GrowingIntArray localTable(-1);
|
||||
GrowingIntArray localTable(-1), paramTable(-1);
|
||||
ResetVisited();
|
||||
mBlocks[0]->CollectLocalAddressTemps(localTable);
|
||||
mBlocks[0]->CollectLocalAddressTemps(localTable, paramTable);
|
||||
|
||||
int nlocals = 0;
|
||||
int nlocals = 0, nparams = 0;
|
||||
for (int i = 0; i < localTable.Size(); i++)
|
||||
if (localTable[i] + 1 > nlocals)
|
||||
nlocals = localTable[i] + 1;
|
||||
for (int i = 0; i < paramTable.Size(); i++)
|
||||
if (paramTable[i] + 1 > nparams)
|
||||
nparams = paramTable[i] + 1;
|
||||
|
||||
mLocalAliasedSet.Reset(nlocals);
|
||||
mParamAliasedSet.Reset(nparams);
|
||||
ResetVisited();
|
||||
mBlocks[0]->MarkAliasedLocalTemps(localTable, mLocalAliasedSet);
|
||||
mBlocks[0]->MarkAliasedLocalTemps(localTable, mLocalAliasedSet, paramTable, mParamAliasedSet);
|
||||
|
||||
//
|
||||
// Now forward constant values
|
||||
|
@ -3353,7 +3463,7 @@ void InterCodeProcedure::Close(void)
|
|||
mValueForwardingTable.SetSize(numTemps, true);
|
||||
|
||||
ResetVisited();
|
||||
mBlocks[0]->PerformValueForwarding(mValueForwardingTable, valueSet, tvalidSet, mLocalAliasedSet);
|
||||
mBlocks[0]->PerformValueForwarding(mValueForwardingTable, valueSet, tvalidSet, mLocalAliasedSet, mParamAliasedSet);
|
||||
|
||||
DisassembleDebug("value forwarding");
|
||||
|
||||
|
@ -3441,8 +3551,11 @@ void InterCodeProcedure::Close(void)
|
|||
FastNumberSet simpleLocals(nlocals), complexLocals(nlocals);
|
||||
GrowingTypeArray localTypes(IT_NONE);
|
||||
|
||||
FastNumberSet simpleParams(nparams), complexParams(nparams);
|
||||
GrowingTypeArray paramTypes(IT_NONE);
|
||||
|
||||
ResetVisited();
|
||||
mBlocks[0]->CollectSimpleLocals(complexLocals, simpleLocals, localTypes);
|
||||
mBlocks[0]->CollectSimpleLocals(complexLocals, simpleLocals, localTypes, complexParams, simpleParams, paramTypes);
|
||||
|
||||
for (int i = 0; i < simpleLocals.Num(); i++)
|
||||
{
|
||||
|
|
|
@ -123,13 +123,16 @@ public:
|
|||
ValueSet(const ValueSet& values);
|
||||
~ValueSet(void);
|
||||
|
||||
ValueSet& operator=(const ValueSet& values);
|
||||
|
||||
void FlushAll(void);
|
||||
void FlushCallAliases(void);
|
||||
|
||||
void RemoveValue(int index);
|
||||
void InsertValue(InterInstruction& ins);
|
||||
|
||||
void UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals);
|
||||
void UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams);
|
||||
void Intersect(ValueSet& set);
|
||||
};
|
||||
|
||||
class TempForwardingTable
|
||||
|
@ -276,13 +279,13 @@ public:
|
|||
InterInstruction(void);
|
||||
void SetCode(const Location & loc, InterCode code);
|
||||
|
||||
void CollectLocalAddressTemps(GrowingIntArray& localTable);
|
||||
void MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals);
|
||||
void CollectLocalAddressTemps(GrowingIntArray& localTable, GrowingIntArray& paramTable);
|
||||
void MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals, const GrowingIntArray& paramTable, NumberSet& aliasedParams);
|
||||
|
||||
void FilterTempUsage(NumberSet& requiredVars, NumberSet& providedVars);
|
||||
void FilterVarsUsage(const GrowingVariableArray& localVars, NumberSet& requiredTemps, NumberSet& providedTemps);
|
||||
bool RemoveUnusedResultInstructions(InterInstruction* pre, NumberSet& requiredTemps, int numStaticTemps);
|
||||
bool RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars, InterInstruction* pre, NumberSet& requiredTemps);
|
||||
bool RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars, NumberSet& requiredTemps);
|
||||
void PerformValueForwarding(GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid);
|
||||
void BuildCallerSaveTempSet(NumberSet& requiredTemps, NumberSet& callerSaveTemps);
|
||||
|
||||
|
@ -297,7 +300,7 @@ public:
|
|||
void CollectActiveTemporaries(FastNumberSet& set);
|
||||
void ShrinkActiveTemporaries(FastNumberSet& set, GrowingTypeArray& temporaries);
|
||||
|
||||
void CollectSimpleLocals(FastNumberSet& complexLocals, FastNumberSet& simpleLocals, GrowingTypeArray& localTypes);
|
||||
void CollectSimpleLocals(FastNumberSet& complexLocals, FastNumberSet& simpleLocals, GrowingTypeArray& localTypes, FastNumberSet& complexParams, FastNumberSet& simpleParams, GrowingTypeArray& paramTypes);
|
||||
void SimpleLocalToTemp(int vindex, int temp);
|
||||
|
||||
void Disassemble(FILE* file);
|
||||
|
@ -351,11 +354,11 @@ public:
|
|||
class InterCodeBasicBlock
|
||||
{
|
||||
public:
|
||||
int mIndex, mNumEntries;
|
||||
int mIndex, mNumEntries, mNumEntered;
|
||||
InterCodeBasicBlock* mTrueJump, * mFalseJump;
|
||||
GrowingInstructionArray mInstructions;
|
||||
|
||||
bool mVisited;
|
||||
bool mVisited, mInPath, mLoopHead;
|
||||
|
||||
NumberSet mLocalRequiredTemps, mLocalProvidedTemps;
|
||||
NumberSet mEntryRequiredTemps, mEntryProvidedTemps;
|
||||
|
@ -365,6 +368,9 @@ public:
|
|||
NumberSet mEntryRequiredVars, mEntryProvidedVars;
|
||||
NumberSet mExitRequiredVars, mExitProvidedVars;
|
||||
|
||||
GrowingInstructionPtrArray mMergeTValues;
|
||||
ValueSet mMergeValues;
|
||||
|
||||
InterCodeBasicBlock(void);
|
||||
~InterCodeBasicBlock(void);
|
||||
|
||||
|
@ -376,8 +382,8 @@ public:
|
|||
|
||||
void LocalToTemp(int vindex, int temp);
|
||||
|
||||
void CollectLocalAddressTemps(GrowingIntArray& localTable);
|
||||
void MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals);
|
||||
void CollectLocalAddressTemps(GrowingIntArray& localTable, GrowingIntArray& paramTable);
|
||||
void MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals, const GrowingIntArray& paramTable, NumberSet& aliasedParams);
|
||||
|
||||
void BuildLocalTempSets(int num, int numFixed);
|
||||
void BuildGlobalProvidedTempSet(NumberSet fromProvidedTemps);
|
||||
|
@ -399,13 +405,13 @@ public:
|
|||
|
||||
void CheckValueUsage(InterInstruction& ins, const GrowingInstructionPtrArray& tvalue);
|
||||
void PerformTempForwarding(TempForwardingTable& forwardingTable);
|
||||
void PerformValueForwarding(const GrowingInstructionPtrArray& tvalue, const ValueSet& values, FastNumberSet& tvalid, const NumberSet& aliasedLocals);
|
||||
void PerformValueForwarding(const GrowingInstructionPtrArray& tvalue, const ValueSet& values, FastNumberSet& tvalid, const NumberSet& aliasedLocals, const NumberSet& aliasedParams);
|
||||
void PerformMachineSpecificValueUsageCheck(const GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid);
|
||||
|
||||
void BuildCollisionTable(NumberSet* collisionSets);
|
||||
void ReduceTemporaries(const GrowingIntArray& renameTable, GrowingTypeArray& temporaries);
|
||||
|
||||
void CollectSimpleLocals(FastNumberSet& complexLocals, FastNumberSet& simpleLocals, GrowingTypeArray & localTypes);
|
||||
void CollectSimpleLocals(FastNumberSet& complexLocals, FastNumberSet& simpleLocals, GrowingTypeArray & localTypes, FastNumberSet& complexParams, FastNumberSet& simpleParams, GrowingTypeArray& paramTypes);
|
||||
void SimpleLocalToTemp(int vindex, int temp);
|
||||
|
||||
void CollectActiveTemporaries(FastNumberSet& set);
|
||||
|
@ -434,7 +440,7 @@ protected:
|
|||
TempForwardingTable mTempForwardingTable;
|
||||
GrowingInstructionPtrArray mValueForwardingTable;
|
||||
int numFixedTemporaries;
|
||||
NumberSet mLocalAliasedSet;
|
||||
NumberSet mLocalAliasedSet, mParamAliasedSet;
|
||||
|
||||
void ResetVisited(void);
|
||||
public:
|
||||
|
|
|
@ -445,6 +445,28 @@ bool NativeCodeInstruction::ChangesAddress(void) const
|
|||
}
|
||||
|
||||
|
||||
bool NativeCodeInstruction::SameEffectiveAddress(const NativeCodeInstruction& ins) const
|
||||
{
|
||||
if (mMode != ins.mMode)
|
||||
return false;
|
||||
|
||||
switch (mMode)
|
||||
{
|
||||
case ASMIM_ZERO_PAGE:
|
||||
case ASMIM_ZERO_PAGE_X:
|
||||
case ASMIM_ZERO_PAGE_Y:
|
||||
case ASMIM_INDIRECT_X:
|
||||
case ASMIM_INDIRECT_Y:
|
||||
return ins.mAddress == mAddress;
|
||||
case ASMIM_ABSOLUTE:
|
||||
case ASMIM_ABSOLUTE_X:
|
||||
case ASMIM_ABSOLUTE_Y:
|
||||
return (ins.mVarIndex == mVarIndex && ins.mAddress == mAddress && ins.mFunction == mFunction && ins.mRuntime == mRuntime);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data)
|
||||
{
|
||||
bool changed = false;
|
||||
|
@ -2645,10 +2667,10 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterI
|
|||
{
|
||||
if (sins0)
|
||||
{
|
||||
insl = NativeCodeInstruction(ASMIT_SBC, ASMIM_ZERO_PAGE, treg);
|
||||
insh = NativeCodeInstruction(ASMIT_SBC, ASMIM_ZERO_PAGE, treg + 1);
|
||||
insl = NativeCodeInstruction(ASMIT_SBC, ASMIM_ZERO_PAGE, BC_REG_WORK + 0);
|
||||
insh = NativeCodeInstruction(ASMIT_SBC, ASMIM_ZERO_PAGE, BC_REG_WORK + 1);
|
||||
|
||||
LoadValueToReg(proc, *sins0, treg, nullptr, nullptr);
|
||||
LoadValueToReg(proc, *sins0, BC_REG_WORK, nullptr, nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3784,8 +3806,35 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
|
|||
mIns[i].mType = ASMIT_NOP;
|
||||
progress = true;
|
||||
}
|
||||
else if (mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
||||
mIns[i + 2].mType == ASMIT_LDA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && mIns[i + 0].mAddress == mIns[i + 2].mAddress &&
|
||||
mIns[i + 1].mType == ASMIT_INC && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 0].mAddress == mIns[i + 1].mAddress && (mIns[i + 2].mLive & LIVE_CPU_REG_C) == 0)
|
||||
{
|
||||
mIns[i + 0].mType = ASMIT_CLC;
|
||||
mIns[i + 0].mMode = ASMIM_IMPLIED;
|
||||
mIns[i + 1].mType = ASMIT_ADC;
|
||||
mIns[i + 1].mMode = ASMIM_IMMEDIATE;
|
||||
mIns[i + 1].mAddress = 1;
|
||||
mIns[i + 2].mType = ASMIT_STA;
|
||||
progress = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (i + 3 < mIns.Size())
|
||||
{
|
||||
if (mIns[i + 0].mType == ASMIT_LDA && mIns[i + 3].mType == ASMIT_STA && mIns[i + 0].SameEffectiveAddress(mIns[i + 3]) &&
|
||||
mIns[i + 1].mType == ASMIT_CLC && mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 1 &&
|
||||
(mIns[i + 0].mMode == ASMIM_ABSOLUTE || mIns[i + 0].mMode == ASMIM_ZERO_PAGE) &&
|
||||
(mIns[i + 3].mLive & (LIVE_CPU_REG_C | LIVE_CPU_REG_A)) == 0)
|
||||
{
|
||||
mIns[i + 0].mType = ASMIT_NOP;
|
||||
mIns[i + 1].mType = ASMIT_NOP;
|
||||
mIns[i + 2].mType = ASMIT_NOP;
|
||||
mIns[i + 3].mType = ASMIT_INC;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (i + 4 < mIns.Size())
|
||||
{
|
||||
if (mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
||||
|
|
|
@ -46,6 +46,7 @@ public:
|
|||
|
||||
bool LoadsAccu(void) const;
|
||||
bool ChangesAddress(void) const;
|
||||
bool SameEffectiveAddress(const NativeCodeInstruction& ins) const;
|
||||
};
|
||||
|
||||
class NativeCodeBasicBlock
|
||||
|
|
|
@ -549,6 +549,7 @@ Expression* Parser::ParseInitExpression(Declaration* dtype)
|
|||
{
|
||||
dtype->mFlags |= DTF_DEFINED;
|
||||
dtype->mSize = index;
|
||||
dec->mSize = index;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
Loading…
Reference in New Issue