Optimize static and global variable usage
This commit is contained in:
parent
b9cbf525e9
commit
7e340cc816
|
@ -99,6 +99,9 @@ if %errorlevel% neq 0 goto :error
|
||||||
call :test structmembertest.c
|
call :test structmembertest.c
|
||||||
if %errorlevel% neq 0 goto :error
|
if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
|
call :test randsumtest.c
|
||||||
|
if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
exit /b 0
|
exit /b 0
|
||||||
|
|
||||||
:error
|
:error
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
// randsumtest
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
long lsum = 0;
|
||||||
|
for(unsigned i=0; i<1000; i++)
|
||||||
|
lsum += rand();
|
||||||
|
|
||||||
|
assert(lsum == 32157742L);
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
|
@ -1291,6 +1291,40 @@ void InterInstruction::FilterTempUsage(NumberSet& requiredTemps, NumberSet& prov
|
||||||
FilterTempDefineUsage(requiredTemps, providedTemps, mDst.mTemp);
|
FilterTempDefineUsage(requiredTemps, providedTemps, mDst.mTemp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InterInstruction::FilterStaticVarsUsage(const GrowingVariableArray& staticVars, NumberSet& requiredVars, NumberSet& providedVars)
|
||||||
|
{
|
||||||
|
if (mCode == IC_LOAD)
|
||||||
|
{
|
||||||
|
if (mSrc[0].mMemory == IM_INDIRECT)
|
||||||
|
{
|
||||||
|
requiredVars.OrNot(providedVars);
|
||||||
|
}
|
||||||
|
else if (mSrc[0].mMemory == IM_GLOBAL)
|
||||||
|
{
|
||||||
|
if (!providedVars[mSrc[0].mVarIndex])
|
||||||
|
requiredVars += mSrc[0].mVarIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mCode == IC_STORE)
|
||||||
|
{
|
||||||
|
if (mSrc[1].mMemory == IM_INDIRECT)
|
||||||
|
{
|
||||||
|
requiredVars.OrNot(providedVars);
|
||||||
|
}
|
||||||
|
else if (mSrc[1].mMemory == IM_GLOBAL)
|
||||||
|
{
|
||||||
|
if (mSrc[1].mIntConst == 0 && mSrc[1].mOperandSize == staticVars[mSrc[1].mVarIndex]->mSize)
|
||||||
|
providedVars += mSrc[1].mVarIndex;
|
||||||
|
else if (!providedVars[mSrc[1].mVarIndex])
|
||||||
|
requiredVars += mSrc[1].mVarIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mCode == IC_COPY || mCode == IC_CALL || mCode == IC_CALL_NATIVE || mCode == IC_RETURN || mCode == IC_RETURN_STRUCT || mCode == IC_RETURN_VALUE)
|
||||||
|
{
|
||||||
|
requiredVars.OrNot(providedVars);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void InterInstruction::FilterVarsUsage(const GrowingVariableArray& localVars, NumberSet& requiredVars, NumberSet& providedVars, const GrowingVariableArray& params, NumberSet& requiredParams, NumberSet& providedParams, InterMemory paramMemory)
|
void InterInstruction::FilterVarsUsage(const GrowingVariableArray& localVars, NumberSet& requiredVars, NumberSet& providedVars, const GrowingVariableArray& params, NumberSet& requiredParams, NumberSet& providedParams, InterMemory paramMemory)
|
||||||
{
|
{
|
||||||
if (mCode == IC_LOAD)
|
if (mCode == IC_LOAD)
|
||||||
|
@ -1522,6 +1556,49 @@ bool InterInstruction::RemoveUnusedStoreInstructions(const GrowingVariableArray&
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool InterInstruction::RemoveUnusedStaticStoreInstructions(const GrowingVariableArray& staticVars, NumberSet& requiredVars)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
if (mCode == IC_LOAD)
|
||||||
|
{
|
||||||
|
if (mSrc[0].mMemory == IM_INDIRECT)
|
||||||
|
{
|
||||||
|
requiredVars.Fill();
|
||||||
|
}
|
||||||
|
else if (mSrc[0].mMemory == IM_GLOBAL)
|
||||||
|
{
|
||||||
|
requiredVars += mSrc[0].mVarIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mCode == IC_STORE)
|
||||||
|
{
|
||||||
|
if (mSrc[1].mMemory == IM_GLOBAL)
|
||||||
|
{
|
||||||
|
if (requiredVars[mSrc[1].mVarIndex])
|
||||||
|
{
|
||||||
|
if (mSrc[1].mIntConst == 0 && mSrc[1].mOperandSize == staticVars[mSrc[1].mVarIndex]->mSize)
|
||||||
|
requiredVars -= mSrc[1].mVarIndex;
|
||||||
|
}
|
||||||
|
else if (!mVolatile)
|
||||||
|
{
|
||||||
|
mCode = IC_NONE;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mCode == IC_COPY)
|
||||||
|
{
|
||||||
|
requiredVars.Fill();
|
||||||
|
}
|
||||||
|
else if (mCode == IC_CALL || mCode == IC_CALL_NATIVE || mCode == IC_RETURN || mCode == IC_RETURN_STRUCT || mCode == IC_RETURN_VALUE)
|
||||||
|
{
|
||||||
|
requiredVars.Fill();
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
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++)
|
||||||
|
@ -1789,13 +1866,13 @@ void InterInstruction::Disassemble(FILE* file)
|
||||||
fprintf(file, "BINOP%d", mOperator);
|
fprintf(file, "BINOP%d", mOperator);
|
||||||
break;
|
break;
|
||||||
case IC_UNARY_OPERATOR:
|
case IC_UNARY_OPERATOR:
|
||||||
fprintf(file, "UNOP");
|
fprintf(file, "UNOP%d", mOperator);
|
||||||
break;
|
break;
|
||||||
case IC_RELATIONAL_OPERATOR:
|
case IC_RELATIONAL_OPERATOR:
|
||||||
fprintf(file, "RELOP");
|
fprintf(file, "RELOP%d", mOperator);
|
||||||
break;
|
break;
|
||||||
case IC_CONVERSION_OPERATOR:
|
case IC_CONVERSION_OPERATOR:
|
||||||
fprintf(file, "CONV");
|
fprintf(file, "CONV%d", mOperator);
|
||||||
break;
|
break;
|
||||||
case IC_STORE:
|
case IC_STORE:
|
||||||
fprintf(file, "STORE%c%d", memchars[mSrc[1].mMemory], mSrc[1].mOperandSize);
|
fprintf(file, "STORE%c%d", memchars[mSrc[1].mMemory], mSrc[1].mOperandSize);
|
||||||
|
@ -2874,6 +2951,108 @@ void InterCodeBasicBlock::BuildCallerSaveTempSet(NumberSet& callerSaveTemps)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void InterCodeBasicBlock::BuildStaticVariableSet(const GrowingVariableArray& staticVars)
|
||||||
|
{
|
||||||
|
if (!mVisited)
|
||||||
|
{
|
||||||
|
mVisited = true;
|
||||||
|
|
||||||
|
mLocalRequiredStatics = NumberSet(staticVars.Size());
|
||||||
|
mLocalProvidedStatics = NumberSet(staticVars.Size());
|
||||||
|
|
||||||
|
mEntryRequiredStatics = NumberSet(staticVars.Size());
|
||||||
|
mEntryProvidedStatics = NumberSet(staticVars.Size());
|
||||||
|
mExitRequiredStatics = NumberSet(staticVars.Size());
|
||||||
|
mExitProvidedStatics = NumberSet(staticVars.Size());
|
||||||
|
|
||||||
|
for (int i = 0; i < mInstructions.Size(); i++)
|
||||||
|
mInstructions[i]->FilterStaticVarsUsage(staticVars, mLocalRequiredStatics, mLocalProvidedStatics);
|
||||||
|
|
||||||
|
mEntryRequiredStatics = mLocalRequiredStatics;
|
||||||
|
mExitProvidedStatics = mLocalProvidedStatics;
|
||||||
|
|
||||||
|
if (mTrueJump) mTrueJump->BuildStaticVariableSet(staticVars);
|
||||||
|
if (mFalseJump) mFalseJump->BuildStaticVariableSet(staticVars);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InterCodeBasicBlock::BuildGlobalProvidedStaticVariableSet(const GrowingVariableArray& staticVars, NumberSet fromProvidedVars)
|
||||||
|
{
|
||||||
|
if (!mVisited || !(fromProvidedVars <= mEntryProvidedStatics))
|
||||||
|
{
|
||||||
|
mEntryProvidedStatics |= fromProvidedVars;
|
||||||
|
fromProvidedVars |= mExitProvidedStatics;
|
||||||
|
|
||||||
|
mVisited = true;
|
||||||
|
|
||||||
|
if (mTrueJump) mTrueJump->BuildGlobalProvidedStaticVariableSet(staticVars, fromProvidedVars);
|
||||||
|
if (mFalseJump) mFalseJump->BuildGlobalProvidedStaticVariableSet(staticVars, fromProvidedVars);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InterCodeBasicBlock::BuildGlobalRequiredStaticVariableSet(const GrowingVariableArray& staticVars, NumberSet& fromRequiredVars)
|
||||||
|
{
|
||||||
|
bool revisit = false;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!mVisited)
|
||||||
|
{
|
||||||
|
mVisited = true;
|
||||||
|
|
||||||
|
NumberSet newRequiredVars(mExitRequiredStatics);
|
||||||
|
|
||||||
|
if (mTrueJump && mTrueJump->BuildGlobalRequiredStaticVariableSet(staticVars, newRequiredVars)) revisit = true;
|
||||||
|
if (mFalseJump && mFalseJump->BuildGlobalRequiredStaticVariableSet(staticVars, newRequiredVars)) revisit = true;
|
||||||
|
|
||||||
|
if (!(newRequiredVars <= mExitRequiredStatics))
|
||||||
|
{
|
||||||
|
revisit = true;
|
||||||
|
|
||||||
|
mExitRequiredStatics = newRequiredVars;
|
||||||
|
newRequiredVars -= mLocalProvidedStatics;
|
||||||
|
mEntryRequiredStatics |= newRequiredVars;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fromRequiredVars |= mEntryRequiredStatics;
|
||||||
|
|
||||||
|
return revisit;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InterCodeBasicBlock::RemoveUnusedStaticStoreInstructions(const GrowingVariableArray& staticVars)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
if (!mVisited)
|
||||||
|
{
|
||||||
|
mVisited = true;
|
||||||
|
|
||||||
|
NumberSet requiredVars(mExitRequiredStatics);
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = mInstructions.Size() - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (mInstructions[i]->RemoveUnusedStaticStoreInstructions(staticVars, requiredVars))
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mTrueJump)
|
||||||
|
{
|
||||||
|
if (mTrueJump->RemoveUnusedStaticStoreInstructions(staticVars))
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
if (mFalseJump)
|
||||||
|
{
|
||||||
|
if (mFalseJump->RemoveUnusedStaticStoreInstructions(staticVars))
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
void InterCodeBasicBlock::BuildLocalVariableSets(const GrowingVariableArray& localVars, const GrowingVariableArray& params, InterMemory paramMemory)
|
void InterCodeBasicBlock::BuildLocalVariableSets(const GrowingVariableArray& localVars, const GrowingVariableArray& params, InterMemory paramMemory)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -4809,6 +4988,30 @@ void InterCodeProcedure::Close(void)
|
||||||
DisassembleDebug("removed unused local stores");
|
DisassembleDebug("removed unused local stores");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove unused global stores
|
||||||
|
|
||||||
|
if (mModule->mGlobalVars.Size())
|
||||||
|
{
|
||||||
|
do {
|
||||||
|
ResetVisited();
|
||||||
|
mEntryBlock->BuildStaticVariableSet(mModule->mGlobalVars);
|
||||||
|
|
||||||
|
ResetVisited();
|
||||||
|
mEntryBlock->BuildGlobalProvidedStaticVariableSet(mModule->mGlobalVars, NumberSet(mModule->mGlobalVars.Size()));
|
||||||
|
|
||||||
|
NumberSet totalRequired2(mModule->mGlobalVars.Size());
|
||||||
|
|
||||||
|
do {
|
||||||
|
ResetVisited();
|
||||||
|
} while (mEntryBlock->BuildGlobalRequiredStaticVariableSet(mModule->mGlobalVars, totalRequired2));
|
||||||
|
|
||||||
|
ResetVisited();
|
||||||
|
} while (mEntryBlock->RemoveUnusedStaticStoreInstructions(mModule->mGlobalVars));
|
||||||
|
|
||||||
|
DisassembleDebug("removed unused static stores");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Promote local variables to temporaries
|
// Promote local variables to temporaries
|
||||||
//
|
//
|
||||||
|
|
|
@ -332,9 +332,11 @@ public:
|
||||||
|
|
||||||
void FilterTempUsage(NumberSet& requiredTemps, NumberSet& providedTemps);
|
void FilterTempUsage(NumberSet& requiredTemps, NumberSet& providedTemps);
|
||||||
void FilterVarsUsage(const GrowingVariableArray& localVars, NumberSet& requiredVars, NumberSet& providedVars, const GrowingVariableArray& params, NumberSet& requiredParams, NumberSet& providedParams, InterMemory paramMemory);
|
void FilterVarsUsage(const GrowingVariableArray& localVars, NumberSet& requiredVars, NumberSet& providedVars, const GrowingVariableArray& params, NumberSet& requiredParams, NumberSet& providedParams, InterMemory paramMemory);
|
||||||
|
void FilterStaticVarsUsage(const GrowingVariableArray& staticVars, NumberSet& requiredVars, NumberSet& providedVars);
|
||||||
|
|
||||||
bool RemoveUnusedResultInstructions(InterInstruction* pre, NumberSet& requiredTemps);
|
bool RemoveUnusedResultInstructions(InterInstruction* pre, NumberSet& requiredTemps);
|
||||||
bool RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars, NumberSet& requiredVars, const GrowingVariableArray& params, NumberSet& requiredParams, InterMemory paramMemory);
|
bool RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars, NumberSet& requiredVars, const GrowingVariableArray& params, NumberSet& requiredParams, InterMemory paramMemory);
|
||||||
|
bool RemoveUnusedStaticStoreInstructions(const GrowingVariableArray& staticVars, NumberSet& requiredVars);
|
||||||
void PerformValueForwarding(GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid);
|
void PerformValueForwarding(GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid);
|
||||||
void BuildCallerSaveTempSet(NumberSet& requiredTemps, NumberSet& callerSaveTemps);
|
void BuildCallerSaveTempSet(NumberSet& requiredTemps, NumberSet& callerSaveTemps);
|
||||||
|
|
||||||
|
@ -418,6 +420,10 @@ public:
|
||||||
NumberSet mEntryRequiredVars, mEntryProvidedVars;
|
NumberSet mEntryRequiredVars, mEntryProvidedVars;
|
||||||
NumberSet mExitRequiredVars, mExitProvidedVars;
|
NumberSet mExitRequiredVars, mExitProvidedVars;
|
||||||
|
|
||||||
|
NumberSet mLocalRequiredStatics, mLocalProvidedStatics;
|
||||||
|
NumberSet mEntryRequiredStatics, mEntryProvidedStatics;
|
||||||
|
NumberSet mExitRequiredStatics, mExitProvidedStatics;
|
||||||
|
|
||||||
NumberSet mLocalRequiredParams, mLocalProvidedParams;
|
NumberSet mLocalRequiredParams, mLocalProvidedParams;
|
||||||
NumberSet mEntryRequiredParams, mEntryProvidedParams;
|
NumberSet mEntryRequiredParams, mEntryProvidedParams;
|
||||||
NumberSet mExitRequiredParams, mExitProvidedParams;
|
NumberSet mExitRequiredParams, mExitProvidedParams;
|
||||||
|
@ -454,6 +460,11 @@ public:
|
||||||
bool BuildGlobalRequiredVariableSet(const GrowingVariableArray& localVars, NumberSet& fromRequiredVars, const GrowingVariableArray& params, NumberSet& fromRequiredParams, InterMemory paramMemory);
|
bool BuildGlobalRequiredVariableSet(const GrowingVariableArray& localVars, NumberSet& fromRequiredVars, const GrowingVariableArray& params, NumberSet& fromRequiredParams, InterMemory paramMemory);
|
||||||
bool RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars, const GrowingVariableArray& params, InterMemory paramMemory);
|
bool RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars, const GrowingVariableArray& params, InterMemory paramMemory);
|
||||||
|
|
||||||
|
void BuildStaticVariableSet(const GrowingVariableArray& staticVars);
|
||||||
|
void BuildGlobalProvidedStaticVariableSet(const GrowingVariableArray& staticVars, NumberSet fromProvidedVars);
|
||||||
|
bool BuildGlobalRequiredStaticVariableSet(const GrowingVariableArray& staticVars, NumberSet& fromRequiredVars);
|
||||||
|
bool RemoveUnusedStaticStoreInstructions(const GrowingVariableArray& staticVars);
|
||||||
|
|
||||||
GrowingIntArray mEntryRenameTable;
|
GrowingIntArray mEntryRenameTable;
|
||||||
GrowingIntArray mExitRenameTable;
|
GrowingIntArray mExitRenameTable;
|
||||||
|
|
||||||
|
|
|
@ -564,6 +564,8 @@ bool NativeCodeInstruction::UsesZeroPage(int address) const
|
||||||
{
|
{
|
||||||
if (mMode == ASMIM_ZERO_PAGE && mAddress == address)
|
if (mMode == ASMIM_ZERO_PAGE && mAddress == address)
|
||||||
return true;
|
return true;
|
||||||
|
else if (mMode == ASMIM_INDIRECT_Y && (mAddress == address || mAddress == address + 1))
|
||||||
|
return true;
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -9168,28 +9170,28 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
|
||||||
}
|
}
|
||||||
else if (
|
else if (
|
||||||
mIns[i + 0].mType == ASMIT_TXA &&
|
mIns[i + 0].mType == ASMIT_TXA &&
|
||||||
mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE)
|
mIns[i + 1].mType == ASMIT_STA && (mIns[i + 1].mMode == ASMIM_ZERO_PAGE || mIns[i + 1].mMode == ASMIM_ABSOLUTE))
|
||||||
{
|
{
|
||||||
mIns[i + 1].mType = ASMIT_STX;
|
mIns[i + 1].mType = ASMIT_STX;
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
else if (
|
else if (
|
||||||
mIns[i + 0].mType == ASMIT_TYA &&
|
mIns[i + 0].mType == ASMIT_TYA &&
|
||||||
mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE)
|
mIns[i + 1].mType == ASMIT_STA && (mIns[i + 1].mMode == ASMIM_ZERO_PAGE || mIns[i + 1].mMode == ASMIM_ABSOLUTE))
|
||||||
{
|
{
|
||||||
mIns[i + 1].mType = ASMIT_STY;
|
mIns[i + 1].mType = ASMIT_STY;
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
else if (
|
else if (
|
||||||
mIns[i + 0].mType == ASMIT_TAX &&
|
mIns[i + 0].mType == ASMIT_TAX &&
|
||||||
mIns[i + 1].mType == ASMIT_STX && mIns[i + 1].mMode == ASMIM_ZERO_PAGE)
|
mIns[i + 1].mType == ASMIT_STX && (mIns[i + 1].mMode == ASMIM_ZERO_PAGE || mIns[i + 1].mMode == ASMIM_ABSOLUTE))
|
||||||
{
|
{
|
||||||
mIns[i + 1].mType = ASMIT_STA;
|
mIns[i + 1].mType = ASMIT_STA;
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
else if (
|
else if (
|
||||||
mIns[i + 0].mType == ASMIT_TAY &&
|
mIns[i + 0].mType == ASMIT_TAY &&
|
||||||
mIns[i + 1].mType == ASMIT_STY && mIns[i + 1].mMode == ASMIM_ZERO_PAGE)
|
mIns[i + 1].mType == ASMIT_STY && (mIns[i + 1].mMode == ASMIM_ZERO_PAGE || mIns[i + 1].mMode == ASMIM_ABSOLUTE))
|
||||||
{
|
{
|
||||||
mIns[i + 1].mType = ASMIT_STA;
|
mIns[i + 1].mType = ASMIT_STA;
|
||||||
progress = true;
|
progress = true;
|
||||||
|
@ -9223,7 +9225,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
else if (
|
else if (
|
||||||
mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
mIns[i + 0].mType == ASMIT_LDA && (mIns[i + 0].mMode == ASMIM_ZERO_PAGE || mIns[i + 0].mMode == ASMIM_ABSOLUTE) &&
|
||||||
mIns[i + 1].mType == ASMIT_TAY && !(mIns[i + 1].mLive & LIVE_CPU_REG_A))
|
mIns[i + 1].mType == ASMIT_TAY && !(mIns[i + 1].mLive & LIVE_CPU_REG_A))
|
||||||
{
|
{
|
||||||
mIns[i + 0].mType = ASMIT_LDY; mIns[i + 0].mLive |= mIns[i + 1].mLive;
|
mIns[i + 0].mType = ASMIT_LDY; mIns[i + 0].mLive |= mIns[i + 1].mLive;
|
||||||
|
@ -9231,7 +9233,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
else if (
|
else if (
|
||||||
mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
mIns[i + 0].mType == ASMIT_LDA && (mIns[i + 0].mMode == ASMIM_ZERO_PAGE || mIns[i + 0].mMode == ASMIM_ABSOLUTE) &&
|
||||||
mIns[i + 1].mType == ASMIT_TAX && !(mIns[i + 1].mLive & LIVE_CPU_REG_A))
|
mIns[i + 1].mType == ASMIT_TAX && !(mIns[i + 1].mLive & LIVE_CPU_REG_A))
|
||||||
{
|
{
|
||||||
mIns[i + 0].mType = ASMIT_LDX; mIns[i + 0].mLive |= mIns[i + 1].mLive;
|
mIns[i + 0].mType = ASMIT_LDX; mIns[i + 0].mLive |= mIns[i + 1].mLive;
|
||||||
|
@ -10682,19 +10684,10 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
|
||||||
{
|
{
|
||||||
if (ins->mSrc[0].mTemp != ins->mDst.mTemp)
|
if (ins->mSrc[0].mTemp != ins->mDst.mTemp)
|
||||||
{
|
{
|
||||||
block->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mSrc[0].mTemp]));
|
for (int i = 0; i < InterTypeSize[ins->mDst.mType]; i++)
|
||||||
block->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mDst.mTemp]));
|
|
||||||
if (InterTypeSize[ins->mDst.mType] > 1)
|
|
||||||
{
|
{
|
||||||
block->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mSrc[0].mTemp] + 1));
|
block->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mSrc[0].mTemp] + i));
|
||||||
block->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mDst.mTemp] + 1));
|
block->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mDst.mTemp] + i));
|
||||||
}
|
|
||||||
if (ins->mSrc[0].mType == IT_FLOAT)
|
|
||||||
{
|
|
||||||
block->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mSrc[0].mTemp] + 2));
|
|
||||||
block->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mDst.mTemp] + 2));
|
|
||||||
block->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mSrc[0].mTemp] + 3));
|
|
||||||
block->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mDst.mTemp] + 3));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
|
@ -68,6 +68,22 @@ void NumberSet::Reset(int size, bool set)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NumberSet::Fill(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < dwsize; i++)
|
||||||
|
bits[i] = 0xffffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NumberSet::OrNot(const NumberSet& set)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < dwsize; i++)
|
||||||
|
bits[i] |= ~set.bits[i];
|
||||||
|
}
|
||||||
|
|
||||||
void NumberSet::Clear(void)
|
void NumberSet::Clear(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
|
@ -30,7 +30,10 @@ public:
|
||||||
|
|
||||||
bool operator<=(const NumberSet& set);
|
bool operator<=(const NumberSet& set);
|
||||||
|
|
||||||
|
void OrNot(const NumberSet& set);
|
||||||
|
|
||||||
void Clear(void);
|
void Clear(void);
|
||||||
|
void Fill(void);
|
||||||
|
|
||||||
int Size(void) { return size; }
|
int Size(void) { return size; }
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue