More integer value range optimizations
This commit is contained in:
parent
6b7dc15d30
commit
71c574478c
|
@ -2318,7 +2318,14 @@ void InterOperand::Disassemble(FILE* file)
|
||||||
|
|
||||||
if (mTemp >= 0)
|
if (mTemp >= 0)
|
||||||
{
|
{
|
||||||
|
if (mFinal)
|
||||||
|
fprintf(file, "R%d(%cF)", mTemp, typechars[mType]);
|
||||||
|
else
|
||||||
fprintf(file, "R%d(%c)", mTemp, typechars[mType]);
|
fprintf(file, "R%d(%c)", mTemp, typechars[mType]);
|
||||||
|
|
||||||
|
if (mType == IT_POINTER && mMemory == IM_INDIRECT)
|
||||||
|
fprintf(file, "+%d", int(mIntConst));
|
||||||
|
|
||||||
if (mRange.mMinState >= IntegerValueRange::S_WEAK || mRange.mMaxState >= IntegerValueRange::S_WEAK)
|
if (mRange.mMinState >= IntegerValueRange::S_WEAK || mRange.mMaxState >= IntegerValueRange::S_WEAK)
|
||||||
{
|
{
|
||||||
fprintf(file, "[");
|
fprintf(file, "[");
|
||||||
|
@ -3412,6 +3419,9 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void)
|
||||||
vr.mMaxState = vr.mMinState = IntegerValueRange::S_BOUND;
|
vr.mMaxState = vr.mMinState = IntegerValueRange::S_BOUND;
|
||||||
vr.mMinValue = vr.mMaxValue = ins->mConst.mIntConst;
|
vr.mMinValue = vr.mMaxValue = ins->mConst.mIntConst;
|
||||||
break;
|
break;
|
||||||
|
case IC_LOAD_TEMPORARY:
|
||||||
|
vr = ins->mSrc[0].mRange;
|
||||||
|
break;
|
||||||
case IC_UNARY_OPERATOR:
|
case IC_UNARY_OPERATOR:
|
||||||
{
|
{
|
||||||
switch (ins->mOperator)
|
switch (ins->mOperator)
|
||||||
|
@ -3722,9 +3732,11 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void)
|
||||||
}
|
}
|
||||||
else if (mInstructions[sz - 2]->mOperator == IA_CMPLU)
|
else if (mInstructions[sz - 2]->mOperator == IA_CMPLU)
|
||||||
{
|
{
|
||||||
if (mInstructions[sz - 2]->mSrc[0].mTemp < 0)
|
if (mInstructions[sz - 2]->mSrc[1].mTemp >= 0)
|
||||||
{
|
{
|
||||||
int t = mInstructions[sz - 2]->mSrc[1].mTemp;
|
int t = mInstructions[sz - 2]->mSrc[1].mTemp;
|
||||||
|
if (mInstructions[sz - 2]->mSrc[0].mTemp < 0)
|
||||||
|
{
|
||||||
mTrueValueRange[t].mMaxState = IntegerValueRange::S_BOUND;
|
mTrueValueRange[t].mMaxState = IntegerValueRange::S_BOUND;
|
||||||
mTrueValueRange[t].mMaxValue = mInstructions[sz - 2]->mSrc[0].mIntConst - 1;
|
mTrueValueRange[t].mMaxValue = mInstructions[sz - 2]->mSrc[0].mIntConst - 1;
|
||||||
mTrueValueRange[t].mMinState = IntegerValueRange::S_BOUND;
|
mTrueValueRange[t].mMinState = IntegerValueRange::S_BOUND;
|
||||||
|
@ -3736,6 +3748,20 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void)
|
||||||
mFalseValueRange[t].mMinValue = mInstructions[sz - 2]->mSrc[0].mIntConst;
|
mFalseValueRange[t].mMinValue = mInstructions[sz - 2]->mSrc[0].mIntConst;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (mInstructions[sz - 2]->mSrc[0].mRange.mMaxState == IntegerValueRange::S_BOUND)
|
||||||
|
{
|
||||||
|
mTrueValueRange[t].mMaxState = IntegerValueRange::S_BOUND;
|
||||||
|
mTrueValueRange[t].mMaxValue = mInstructions[sz - 2]->mSrc[0].mRange.mMaxValue - 1;
|
||||||
|
mTrueValueRange[t].mMinState = IntegerValueRange::S_BOUND;
|
||||||
|
mTrueValueRange[t].mMinValue = 0;
|
||||||
|
|
||||||
|
if (mFalseValueRange[t].mMinState == IntegerValueRange::S_BOUND && mFalseValueRange[t].mMinValue >= 0)
|
||||||
|
{
|
||||||
|
mFalseValueRange[t].mMinState = IntegerValueRange::S_BOUND;
|
||||||
|
mFalseValueRange[t].mMinValue = mInstructions[sz - 2]->mSrc[0].mRange.mMaxValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (mInstructions[sz - 2]->mOperator == IA_CMPLEU)
|
else if (mInstructions[sz - 2]->mOperator == IA_CMPLEU)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1056,7 +1056,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Declaration * otype = vll.mType;
|
Declaration * otype = vll.mType;
|
||||||
if (exp->mToken != IA_ADD && exp->mToken != IA_SUB && otype->mSize < 2)
|
if (exp->mToken != TK_ADD && exp->mToken != TK_SUB && otype->mSize < 2)
|
||||||
{
|
{
|
||||||
if ((vll.mType->mFlags | vr.mType->mFlags) & DTF_SIGNED)
|
if ((vll.mType->mFlags | vr.mType->mFlags) & DTF_SIGNED)
|
||||||
otype = TheSignedIntTypeDeclaration;
|
otype = TheSignedIntTypeDeclaration;
|
||||||
|
|
|
@ -3857,12 +3857,46 @@ void NativeCodeBasicBlock::LoadStoreValue(InterCodeProcedure* proc, const InterI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NativeCodeBasicBlock::LoadLoadOpStoreIndirectValue(InterCodeProcedure* proc, const InterInstruction* rins1, const InterInstruction* rins0, const InterInstruction* oins, const InterInstruction* wins)
|
||||||
|
{
|
||||||
|
if (rins1->mSrc[0].mMemory == IM_INDIRECT && rins0->mSrc[0].mMemory == IM_INDIRECT && wins->mSrc[1].mMemory == IM_INDIRECT)
|
||||||
|
{
|
||||||
|
int size = InterTypeSize[wins->mSrc[0].mType];
|
||||||
|
|
||||||
|
switch (oins->mOperator)
|
||||||
|
{
|
||||||
|
case IA_ADD:
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_CLC));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, rins1->mSrc[0].mIntConst + i));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[rins1->mSrc[0].mTemp]));
|
||||||
|
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, rins0->mSrc[0].mIntConst + i));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[rins0->mSrc[0].mTemp]));
|
||||||
|
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, wins->mSrc[1].mIntConst + i));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[wins->mSrc[1].mTemp]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool NativeCodeBasicBlock::LoadOpStoreIndirectValue(InterCodeProcedure* proc, const InterInstruction* rins, const InterInstruction* oins, int oindex, const InterInstruction* wins)
|
bool NativeCodeBasicBlock::LoadOpStoreIndirectValue(InterCodeProcedure* proc, const InterInstruction* rins, const InterInstruction* oins, int oindex, const InterInstruction* wins)
|
||||||
{
|
{
|
||||||
int size = InterTypeSize[wins->mSrc[0].mType];
|
int size = InterTypeSize[wins->mSrc[0].mType];
|
||||||
|
|
||||||
AsmInsType at = ASMIT_ADC, an = ASMIT_ADC;
|
AsmInsType at = ASMIT_ADC, an = ASMIT_ADC;
|
||||||
AsmInsMode am = oins->mSrc[oindex].mTemp < 0 ? ASMIM_IMMEDIATE : ASMIM_ZERO_PAGE;
|
AsmInsMode am = oins->mSrc[oindex].mTemp < 0 ? ASMIM_IMMEDIATE : ASMIM_ZERO_PAGE, ram = ASMIM_INDIRECT_Y, wam = ASMIM_INDIRECT_Y;
|
||||||
|
bool reverse = false;
|
||||||
|
|
||||||
switch (oins->mOperator)
|
switch (oins->mOperator)
|
||||||
{
|
{
|
||||||
|
@ -3873,6 +3907,8 @@ bool NativeCodeBasicBlock::LoadOpStoreIndirectValue(InterCodeProcedure* proc, co
|
||||||
case IA_SUB:
|
case IA_SUB:
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_SEC));
|
mIns.Push(NativeCodeInstruction(ASMIT_SEC));
|
||||||
at = an = ASMIT_SBC;
|
at = an = ASMIT_SBC;
|
||||||
|
if (oindex == 1)
|
||||||
|
reverse = true;
|
||||||
break;
|
break;
|
||||||
case IA_AND:
|
case IA_AND:
|
||||||
at = an = ASMIT_AND;
|
at = an = ASMIT_AND;
|
||||||
|
@ -3900,26 +3936,46 @@ bool NativeCodeBasicBlock::LoadOpStoreIndirectValue(InterCodeProcedure* proc, co
|
||||||
int rindex = rins->mSrc[0].mIntConst;
|
int rindex = rins->mSrc[0].mIntConst;
|
||||||
int rareg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
|
int rareg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
|
||||||
|
|
||||||
if (rins->mSrc[0].mMemory == IM_INDIRECT)
|
switch (rins->mSrc[0].mMemory)
|
||||||
|
{
|
||||||
|
case IM_INDIRECT:
|
||||||
rareg = BC_REG_TMP + proc->mTempOffset[rins->mSrc[0].mTemp];
|
rareg = BC_REG_TMP + proc->mTempOffset[rins->mSrc[0].mTemp];
|
||||||
else if (rins->mSrc[0].mMemory == IM_LOCAL)
|
break;
|
||||||
|
case IM_LOCAL:
|
||||||
rindex += proc->mLocalVars[rins->mSrc[0].mVarIndex]->mOffset + mFrameOffset;
|
rindex += proc->mLocalVars[rins->mSrc[0].mVarIndex]->mOffset + mFrameOffset;
|
||||||
else if (rins->mSrc[0].mMemory == IM_PARAM)
|
break;
|
||||||
|
case IM_PARAM:
|
||||||
rindex += rins->mSrc[0].mVarIndex + proc->mLocalSize + 2 + mFrameOffset;
|
rindex += rins->mSrc[0].mVarIndex + proc->mLocalSize + 2 + mFrameOffset;
|
||||||
else
|
break;
|
||||||
|
case IM_FPARAM:
|
||||||
|
ram = ASMIM_ZERO_PAGE;
|
||||||
|
rareg = BC_REG_FPARAMS + rins->mSrc[0].mVarIndex + rins->mSrc[0].mIntConst;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int windex = wins->mSrc[1].mIntConst;
|
int windex = wins->mSrc[1].mIntConst;
|
||||||
int wareg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
|
int wareg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
|
||||||
|
|
||||||
if (wins->mSrc[1].mMemory == IM_INDIRECT)
|
switch (wins->mSrc[1].mMemory)
|
||||||
|
{
|
||||||
|
case IM_INDIRECT:
|
||||||
wareg = BC_REG_TMP + proc->mTempOffset[wins->mSrc[1].mTemp];
|
wareg = BC_REG_TMP + proc->mTempOffset[wins->mSrc[1].mTemp];
|
||||||
else if (wins->mSrc[1].mMemory == IM_LOCAL)
|
break;
|
||||||
|
case IM_LOCAL:
|
||||||
windex += proc->mLocalVars[wins->mSrc[1].mVarIndex]->mOffset + mFrameOffset;
|
windex += proc->mLocalVars[wins->mSrc[1].mVarIndex]->mOffset + mFrameOffset;
|
||||||
else if (wins->mSrc[1].mMemory == IM_PARAM)
|
break;
|
||||||
|
case IM_PARAM:
|
||||||
windex += wins->mSrc[1].mVarIndex + proc->mLocalSize + 2 + mFrameOffset;
|
windex += wins->mSrc[1].mVarIndex + proc->mLocalSize + 2 + mFrameOffset;
|
||||||
else
|
break;
|
||||||
|
case IM_FPARAM:
|
||||||
|
wam = ASMIM_ZERO_PAGE;
|
||||||
|
wareg = BC_REG_FPARAMS + +wins->mSrc[1].mVarIndex + wins->mSrc[1].mIntConst;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
uint32 rflags = NCIF_LOWER | NCIF_UPPER;
|
uint32 rflags = NCIF_LOWER | NCIF_UPPER;
|
||||||
if (rins->mVolatile)
|
if (rins->mVolatile)
|
||||||
|
@ -3929,24 +3985,57 @@ bool NativeCodeBasicBlock::LoadOpStoreIndirectValue(InterCodeProcedure* proc, co
|
||||||
if (wins->mVolatile)
|
if (wins->mVolatile)
|
||||||
wflags |= NCIF_VOLATILE;
|
wflags |= NCIF_VOLATILE;
|
||||||
|
|
||||||
|
if (ram == ASMIM_INDIRECT_Y)
|
||||||
CheckFrameIndex(rareg, rindex, size, BC_REG_ADDR);
|
CheckFrameIndex(rareg, rindex, size, BC_REG_ADDR);
|
||||||
|
if (wam == ASMIM_INDIRECT_Y)
|
||||||
CheckFrameIndex(wareg, windex, size, BC_REG_ACCU);
|
CheckFrameIndex(wareg, windex, size, BC_REG_ACCU);
|
||||||
|
|
||||||
for (int i = 0; i < size; i++)
|
for (int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
if (reverse)
|
||||||
|
{
|
||||||
|
if (am == ASMIM_IMPLIED)
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMPLIED));
|
||||||
|
else if (am == ASMIM_IMMEDIATE)
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (oins->mSrc[oindex].mIntConst >> (8 * i)) & 0xff));
|
||||||
|
else
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[oins->mSrc[oindex].mTemp] + i));
|
||||||
|
|
||||||
|
if (ram == ASMIM_INDIRECT_Y)
|
||||||
{
|
{
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, rindex + i));
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, rindex + i));
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, rareg));
|
mIns.Push(NativeCodeInstruction(at, ram, rareg));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mIns.Push(NativeCodeInstruction(at, ram, rareg + i));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ram == ASMIM_INDIRECT_Y)
|
||||||
|
{
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, rindex + i));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ram, rareg));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ram, rareg + i));
|
||||||
|
|
||||||
if (am == ASMIM_IMPLIED)
|
if (am == ASMIM_IMPLIED)
|
||||||
mIns.Push(NativeCodeInstruction(at, ASMIM_IMPLIED));
|
mIns.Push(NativeCodeInstruction(at, ASMIM_IMPLIED));
|
||||||
else if (am == ASMIM_IMMEDIATE)
|
else if (am == ASMIM_IMMEDIATE)
|
||||||
mIns.Push(NativeCodeInstruction(at, ASMIM_IMMEDIATE, (oins->mSrc[oindex].mIntConst >> (8 * i)) & 0xff));
|
mIns.Push(NativeCodeInstruction(at, ASMIM_IMMEDIATE, (oins->mSrc[oindex].mIntConst >> (8 * i)) & 0xff));
|
||||||
else
|
else
|
||||||
mIns.Push(NativeCodeInstruction(at, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[oins->mSrc[oindex].mTemp] + i));
|
mIns.Push(NativeCodeInstruction(at, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[oins->mSrc[oindex].mTemp] + i));
|
||||||
at = an;
|
}
|
||||||
if (rindex != windex)
|
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, windex + i));
|
|
||||||
|
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, wareg));
|
at = an;
|
||||||
|
if (wam == ASMIM_INDIRECT_Y)
|
||||||
|
{
|
||||||
|
if (ram != ASMIM_INDIRECT_Y || rindex != windex)
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, windex + i));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, wam, wareg));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, wam, wareg + i));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -5878,6 +5967,54 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
|
||||||
{
|
{
|
||||||
reg = ShortMultiply(proc, nproc, ins, sins1, 1, ins->mSrc[0].mIntConst);
|
reg = ShortMultiply(proc, nproc, ins, sins1, 1, ins->mSrc[0].mIntConst);
|
||||||
}
|
}
|
||||||
|
else if (ins->mOperator == IA_MUL && ins->mSrc[0].IsUByte())
|
||||||
|
{
|
||||||
|
if (sins1)
|
||||||
|
LoadValueToReg(proc, sins1, BC_REG_ACCU, nullptr, nullptr);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 1));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sins0)
|
||||||
|
LoadValueToReg(proc, sins0, BC_REG_WORK, nullptr, nullptr);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
NativeCodeGenerator::Runtime& frt(nproc->mGenerator->ResolveRuntime(Ident::Unique("mul16by8")));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_JSR, ASMIM_ABSOLUTE, frt.mOffset, frt.mLinkerObject, NCIF_RUNTIME));
|
||||||
|
reg = BC_REG_WORK + 2;
|
||||||
|
}
|
||||||
|
else if (ins->mOperator == IA_MUL && ins->mSrc[1].IsUByte())
|
||||||
|
{
|
||||||
|
if (sins0)
|
||||||
|
LoadValueToReg(proc, sins0, BC_REG_ACCU, nullptr, nullptr);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sins1)
|
||||||
|
LoadValueToReg(proc, sins1, BC_REG_WORK, nullptr, nullptr);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
NativeCodeGenerator::Runtime& frt(nproc->mGenerator->ResolveRuntime(Ident::Unique("mul16by8")));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_JSR, ASMIM_ABSOLUTE, frt.mOffset, frt.mLinkerObject, NCIF_RUNTIME));
|
||||||
|
reg = BC_REG_WORK + 2;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (sins1)
|
if (sins1)
|
||||||
|
@ -9235,6 +9372,37 @@ bool NativeCodeBasicBlock::MoveAddHighByteDown(int at)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NativeCodeBasicBlock::MoveLoadImmStoreAbsoluteUp(int at)
|
||||||
|
{
|
||||||
|
int j = at;
|
||||||
|
while (j > 0)
|
||||||
|
{
|
||||||
|
if (mIns[j - 1].mType == ASMIT_LDA && (mIns[j - 1].mMode == ASMIM_IMMEDIATE || mIns[j - 1].mMode == ASMIM_ZERO_PAGE))
|
||||||
|
{
|
||||||
|
if (mIns[j - 1].mMode == mIns[at + 0].mMode && mIns[j - 1].mAddress == mIns[at + 0].mAddress)
|
||||||
|
{
|
||||||
|
while (j < at && mIns[j].mType == ASMIT_STA)
|
||||||
|
j++;
|
||||||
|
|
||||||
|
NativeCodeInstruction sins = mIns[at + 1];
|
||||||
|
mIns.Remove(at + 1);
|
||||||
|
if (!(sins.mLive & LIVE_CPU_REG_A))
|
||||||
|
mIns.Remove(at);
|
||||||
|
|
||||||
|
mIns.Insert(j, sins);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
j--;
|
||||||
|
}
|
||||||
|
else if (mIns[j - 1].mType == ASMIT_STA && mIns[j - 1].mMode == mIns[at + 1].mMode && mIns[j - 1].mLinkerObject == mIns[at + 1].mLinkerObject && mIns[j - 1].mAddress != mIns[at + 1].mAddress)
|
||||||
|
j--;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool NativeCodeBasicBlock::MoveLoadStoreUp(int at)
|
bool NativeCodeBasicBlock::MoveLoadStoreUp(int at)
|
||||||
{
|
{
|
||||||
int j = at;
|
int j = at;
|
||||||
|
@ -10780,6 +10948,8 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
{
|
{
|
||||||
if (i + 2 < mIns.Size() && mIns[i + 1].mType == ASMIT_LDA && (mIns[i + 1].mMode == ASMIM_IMMEDIATE || mIns[i + 1].mMode == ASMIM_IMMEDIATE_ADDRESS || mIns[i + 1].mMode == ASMIM_ZERO_PAGE) && mIns[i + 2].RequiresCarry())
|
if (i + 2 < mIns.Size() && mIns[i + 1].mType == ASMIT_LDA && (mIns[i + 1].mMode == ASMIM_IMMEDIATE || mIns[i + 1].mMode == ASMIM_IMMEDIATE_ADDRESS || mIns[i + 1].mMode == ASMIM_ZERO_PAGE) && mIns[i + 2].RequiresCarry())
|
||||||
;
|
;
|
||||||
|
else if (i + 2 < mIns.Size() && mIns[i + 1].mType == ASMIT_LDY && mIns[i + 1].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mMode == ASMIM_INDIRECT_Y)
|
||||||
|
;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NativeCodeInstruction pins = mIns[i];
|
NativeCodeInstruction pins = mIns[i];
|
||||||
|
@ -10861,6 +11031,17 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
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) &&
|
||||||
|
mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ABSOLUTE)
|
||||||
|
{
|
||||||
|
if (MoveLoadImmStoreAbsoluteUp(i + 0))
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool progress = false;
|
bool progress = false;
|
||||||
do {
|
do {
|
||||||
progress = false;
|
progress = false;
|
||||||
|
@ -13605,6 +13786,30 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
|
||||||
{
|
{
|
||||||
i += 2;
|
i += 2;
|
||||||
}
|
}
|
||||||
|
else if (i + 3 < iblock->mInstructions.Size() &&
|
||||||
|
(ins->mDst.mType == IT_INT8 || ins->mDst.mType == IT_INT16 || ins->mDst.mType == IT_INT32) &&
|
||||||
|
iblock->mInstructions[i + 1]->mCode == IC_LOAD &&
|
||||||
|
iblock->mInstructions[i + 2]->mCode == IC_BINARY_OPERATOR &&
|
||||||
|
iblock->mInstructions[i + 2]->mSrc[0].mTemp == ins->mDst.mTemp && iblock->mInstructions[i + 2]->mSrc[0].mFinal &&
|
||||||
|
iblock->mInstructions[i + 2]->mSrc[1].mTemp == iblock->mInstructions[i + 1]->mDst.mTemp && iblock->mInstructions[i + 2]->mSrc[1].mFinal &&
|
||||||
|
iblock->mInstructions[i + 3]->mCode == IC_STORE &&
|
||||||
|
iblock->mInstructions[i + 3]->mSrc[0].mTemp == iblock->mInstructions[i + 2]->mDst.mTemp && iblock->mInstructions[i + 3]->mSrc[0].mFinal &&
|
||||||
|
block->LoadLoadOpStoreIndirectValue(iproc, ins, iblock->mInstructions[i + 1], iblock->mInstructions[i + 2], iblock->mInstructions[i + 3]))
|
||||||
|
{
|
||||||
|
i += 3;
|
||||||
|
}
|
||||||
|
else if (i + 3 < iblock->mInstructions.Size() &&
|
||||||
|
(ins->mDst.mType == IT_INT8 || ins->mDst.mType == IT_INT16 || ins->mDst.mType == IT_INT32) &&
|
||||||
|
iblock->mInstructions[i + 1]->mCode == IC_LOAD &&
|
||||||
|
iblock->mInstructions[i + 2]->mCode == IC_BINARY_OPERATOR &&
|
||||||
|
iblock->mInstructions[i + 2]->mSrc[1].mTemp == ins->mDst.mTemp && iblock->mInstructions[i + 2]->mSrc[1].mFinal &&
|
||||||
|
iblock->mInstructions[i + 2]->mSrc[0].mTemp == iblock->mInstructions[i + 1]->mDst.mTemp && iblock->mInstructions[i + 2]->mSrc[0].mFinal &&
|
||||||
|
iblock->mInstructions[i + 3]->mCode == IC_STORE &&
|
||||||
|
iblock->mInstructions[i + 3]->mSrc[0].mTemp == iblock->mInstructions[i + 2]->mDst.mTemp && iblock->mInstructions[i + 3]->mSrc[0].mFinal &&
|
||||||
|
block->LoadLoadOpStoreIndirectValue(iproc, iblock->mInstructions[i + 1], ins, iblock->mInstructions[i + 2], iblock->mInstructions[i + 3]))
|
||||||
|
{
|
||||||
|
i += 3;
|
||||||
|
}
|
||||||
else if (i + 1 < iblock->mInstructions.Size() &&
|
else if (i + 1 < iblock->mInstructions.Size() &&
|
||||||
InterTypeSize[ins->mDst.mType] >= 2 &&
|
InterTypeSize[ins->mDst.mType] >= 2 &&
|
||||||
iblock->mInstructions[i + 1]->mCode == IC_BINARY_OPERATOR &&
|
iblock->mInstructions[i + 1]->mCode == IC_BINARY_OPERATOR &&
|
||||||
|
|
|
@ -159,6 +159,7 @@ public:
|
||||||
void LoadValue(InterCodeProcedure* proc, const InterInstruction * ins);
|
void LoadValue(InterCodeProcedure* proc, const InterInstruction * ins);
|
||||||
void LoadStoreValue(InterCodeProcedure* proc, const InterInstruction * rins, const InterInstruction * wins);
|
void LoadStoreValue(InterCodeProcedure* proc, const InterInstruction * rins, const InterInstruction * wins);
|
||||||
bool LoadOpStoreIndirectValue(InterCodeProcedure* proc, const InterInstruction* rins, const InterInstruction* oins, int oindex, const InterInstruction* wins);
|
bool LoadOpStoreIndirectValue(InterCodeProcedure* proc, const InterInstruction* rins, const InterInstruction* oins, int oindex, const InterInstruction* wins);
|
||||||
|
bool LoadLoadOpStoreIndirectValue(InterCodeProcedure* proc, const InterInstruction* rins1, const InterInstruction* rins0, const InterInstruction* oins, const InterInstruction* wins);
|
||||||
void LoadStoreIndirectValue(InterCodeProcedure* proc, const InterInstruction* rins, const InterInstruction* wins);
|
void LoadStoreIndirectValue(InterCodeProcedure* proc, const InterInstruction* rins, const InterInstruction* wins);
|
||||||
NativeCodeBasicBlock* BinaryOperator(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins, const InterInstruction* sins1, const InterInstruction* sins0);
|
NativeCodeBasicBlock* BinaryOperator(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins, const InterInstruction* sins1, const InterInstruction* sins0);
|
||||||
void UnaryOperator(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins);
|
void UnaryOperator(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins);
|
||||||
|
@ -191,6 +192,7 @@ public:
|
||||||
|
|
||||||
bool MoveLoadStoreUp(int at);
|
bool MoveLoadStoreUp(int at);
|
||||||
bool MoveLoadStoreXUp(int at);
|
bool MoveLoadStoreXUp(int at);
|
||||||
|
bool MoveLoadImmStoreAbsoluteUp(int at);
|
||||||
|
|
||||||
bool MoveIndirectLoadStoreUp(int at);
|
bool MoveIndirectLoadStoreUp(int at);
|
||||||
bool MoveAbsoluteLoadStoreUp(int at);
|
bool MoveAbsoluteLoadStoreUp(int at);
|
||||||
|
|
Loading…
Reference in New Issue