|
|
|
@ -244,6 +244,10 @@ NativeCodeInstruction::NativeCodeInstruction(AsmInsType type, AsmInsMode mode, i
|
|
|
|
|
assert((mFlags & (NCIF_LOWER | NCIF_UPPER)) != (NCIF_LOWER | NCIF_UPPER));
|
|
|
|
|
assert(HasAsmInstructionMode(mType, ASMIM_IMMEDIATE));
|
|
|
|
|
}
|
|
|
|
|
if (mode == ASMIM_IMMEDIATE)
|
|
|
|
|
{
|
|
|
|
|
assert(address >= 0 && address < 256);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NativeCodeInstruction::NativeCodeInstruction(AsmInsType type, const NativeCodeInstruction& addr)
|
|
|
|
@ -1326,6 +1330,8 @@ bool NativeCodeInstruction::MayBeSameAddress(const NativeCodeInstruction& ins, b
|
|
|
|
|
{
|
|
|
|
|
if (mLinkerObject != ins.mLinkerObject)
|
|
|
|
|
return false;
|
|
|
|
|
else if (mAddress >= ins.mAddress + 256 || ins.mAddress >= mAddress + 256)
|
|
|
|
|
return false;
|
|
|
|
|
else
|
|
|
|
|
return mMode != ins.mMode || !sameXY || mAddress == ins.mAddress;
|
|
|
|
|
}
|
|
|
|
@ -4441,6 +4447,8 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
|
|
|
|
|
|
|
|
|
|
if (ins->mSrc[0].mType == IT_FLOAT)
|
|
|
|
|
{
|
|
|
|
|
int stride = ins->mSrc[1].mStride;
|
|
|
|
|
|
|
|
|
|
if (ins->mSrc[1].mTemp < 0)
|
|
|
|
|
{
|
|
|
|
|
if (ins->mSrc[0].mTemp < 0)
|
|
|
|
@ -4453,22 +4461,22 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, cc.v & 0xff));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst, ins->mSrc[1].mLinkerObject, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 8) & 0xff));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 1, ins->mSrc[1].mLinkerObject, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 1 * stride, ins->mSrc[1].mLinkerObject, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 16) & 0xff));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 2, ins->mSrc[1].mLinkerObject, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 2 * stride, ins->mSrc[1].mLinkerObject, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 24) & 0xff));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 3, ins->mSrc[1].mLinkerObject, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 3 * stride, ins->mSrc[1].mLinkerObject, flags));
|
|
|
|
|
}
|
|
|
|
|
else if (ins->mSrc[1].mMemory == IM_ABSOLUTE)
|
|
|
|
|
{
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, cc.v & 0xff));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst, nullptr, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 8) & 0xff));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 1, nullptr, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 1 * stride, nullptr, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 16) & 0xff));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 2, nullptr, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 2 * stride, nullptr, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 24) & 0xff));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 3, nullptr, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 3 * stride, nullptr, flags));
|
|
|
|
|
}
|
|
|
|
|
else if (ins->mSrc[1].mMemory == IM_FPARAM || ins->mSrc[1].mMemory == IM_FFRAME)
|
|
|
|
|
{
|
|
|
|
@ -4539,22 +4547,22 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst, ins->mSrc[1].mLinkerObject, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 1));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 1, ins->mSrc[1].mLinkerObject, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 1 * stride, ins->mSrc[1].mLinkerObject, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 2));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 2, ins->mSrc[1].mLinkerObject, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 2 * stride, ins->mSrc[1].mLinkerObject, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 3));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 3, ins->mSrc[1].mLinkerObject, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 3 * stride, ins->mSrc[1].mLinkerObject, flags));
|
|
|
|
|
}
|
|
|
|
|
else if (ins->mSrc[1].mMemory == IM_ABSOLUTE)
|
|
|
|
|
{
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst, nullptr, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 1));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 1, nullptr, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 1 * stride, nullptr, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 2));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 2, nullptr, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 2 * stride, nullptr, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 3));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 3, nullptr, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 3 * stride, nullptr, flags));
|
|
|
|
|
}
|
|
|
|
|
else if (ins->mSrc[1].mMemory == IM_FPARAM || ins->mSrc[1].mMemory == IM_FFRAME)
|
|
|
|
|
{
|
|
|
|
@ -4621,21 +4629,32 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
|
|
|
|
|
|
|
|
|
|
int reg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
|
|
|
|
|
int index = ins->mSrc[1].mIntConst;
|
|
|
|
|
int stride = ins->mSrc[1].mStride;
|
|
|
|
|
|
|
|
|
|
CheckFrameIndex(reg, index, 4);
|
|
|
|
|
if (stride * 4 <= 256)
|
|
|
|
|
{
|
|
|
|
|
CheckFrameIndex(reg, index, stride * 4);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
|
|
|
{
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + i * stride));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> (8 * i)) & 0xff));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
|
|
|
{
|
|
|
|
|
CheckFrameIndex(reg, index, 1);
|
|
|
|
|
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, cc.v & 0xff));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 1));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 8) & 0xff));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 2));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 16) & 0xff));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 3));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 24) & 0xff));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> (8 * i)) & 0xff));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
|
|
|
|
|
|
|
|
|
|
index += stride;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
@ -4644,27 +4663,40 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
|
|
|
|
|
{
|
|
|
|
|
int reg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
|
|
|
|
|
int index = ins->mSrc[1].mIntConst;
|
|
|
|
|
int stride = ins->mSrc[1].mStride;
|
|
|
|
|
|
|
|
|
|
CheckFrameIndex(reg, index, 4);
|
|
|
|
|
if (stride * 4 <= 256)
|
|
|
|
|
{
|
|
|
|
|
CheckFrameIndex(reg, index, stride * 4);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
|
|
|
{
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + i * stride));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + i));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
|
|
|
{
|
|
|
|
|
CheckFrameIndex(reg, index, 1);
|
|
|
|
|
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 1));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 2));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 2));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 3));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 3));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + i));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
|
|
|
|
|
|
|
|
|
|
index += stride;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (ins->mSrc[0].mType == IT_POINTER)
|
|
|
|
|
{
|
|
|
|
|
int stride = ins->mSrc[1].mStride;
|
|
|
|
|
|
|
|
|
|
if (ins->mSrc[1].mTemp < 0)
|
|
|
|
|
{
|
|
|
|
|
if (ins->mSrc[0].mTemp < 0)
|
|
|
|
@ -4674,14 +4706,14 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst & 0xff));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst, ins->mSrc[1].mLinkerObject, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 8) & 0xff));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 1, ins->mSrc[1].mLinkerObject, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + stride, ins->mSrc[1].mLinkerObject, flags));
|
|
|
|
|
}
|
|
|
|
|
else if (ins->mSrc[1].mMemory == IM_ABSOLUTE)
|
|
|
|
|
{
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst & 0xff));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst, nullptr, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 8) & 0xff));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 1, nullptr, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + stride, nullptr, flags));
|
|
|
|
|
}
|
|
|
|
|
else if (ins->mSrc[1].mMemory == IM_FPARAM || ins->mSrc[1].mMemory == IM_FFRAME)
|
|
|
|
|
{
|
|
|
|
@ -4727,14 +4759,14 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst, ins->mSrc[1].mLinkerObject, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 1, ins->mSrc[1].mLinkerObject, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + stride, ins->mSrc[1].mLinkerObject, flags));
|
|
|
|
|
}
|
|
|
|
|
else if (ins->mSrc[1].mMemory == IM_ABSOLUTE)
|
|
|
|
|
{
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst, nullptr, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 1, nullptr, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + stride, nullptr, flags));
|
|
|
|
|
}
|
|
|
|
|
else if (ins->mSrc[1].mMemory == IM_FPARAM || ins->mSrc[1].mMemory == IM_FFRAME)
|
|
|
|
|
{
|
|
|
|
@ -4782,15 +4814,32 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
|
|
|
|
|
{
|
|
|
|
|
int reg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
|
|
|
|
|
int index = ins->mSrc[1].mIntConst;
|
|
|
|
|
int stride = ins->mSrc[1].mStride;
|
|
|
|
|
|
|
|
|
|
CheckFrameIndex(reg, index, 2);
|
|
|
|
|
if (2 * stride <= 256)
|
|
|
|
|
{
|
|
|
|
|
CheckFrameIndex(reg, index, 2 * stride);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 2; i++)
|
|
|
|
|
{
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + i * stride));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> (8 * i)) & 0xff));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < 2; i++)
|
|
|
|
|
{
|
|
|
|
|
CheckFrameIndex(reg, index, 1);
|
|
|
|
|
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst & 0xff));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 1));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 8) & 0xff));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> (8 * i)) & 0xff));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
|
|
|
|
|
|
|
|
|
|
index += stride;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
@ -4799,15 +4848,32 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
|
|
|
|
|
{
|
|
|
|
|
int reg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
|
|
|
|
|
int index = ins->mSrc[1].mIntConst;
|
|
|
|
|
int stride = ins->mSrc[1].mStride;
|
|
|
|
|
|
|
|
|
|
CheckFrameIndex(reg, index, 2);
|
|
|
|
|
if (2 * stride <= 256)
|
|
|
|
|
{
|
|
|
|
|
CheckFrameIndex(reg, index, 2 * stride);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 2; i++)
|
|
|
|
|
{
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + i * stride));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + i));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < 2; i++)
|
|
|
|
|
{
|
|
|
|
|
CheckFrameIndex(reg, index, 1);
|
|
|
|
|
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 1));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + i));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
|
|
|
|
|
|
|
|
|
|
index += stride;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -5183,33 +5249,32 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
|
|
|
|
|
{
|
|
|
|
|
int reg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
|
|
|
|
|
int index = ins->mSrc[1].mIntConst;
|
|
|
|
|
|
|
|
|
|
CheckFrameIndex(reg, index, InterTypeSize[ins->mSrc[0].mType]);
|
|
|
|
|
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index));
|
|
|
|
|
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst & 0xff));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
|
|
|
|
|
|
|
|
|
|
int stride = ins->mSrc[1].mStride;
|
|
|
|
|
int size = InterTypeSize[ins->mSrc[0].mType];
|
|
|
|
|
|
|
|
|
|
if (InterTypeSize[ins->mSrc[0].mType] == 2)
|
|
|
|
|
if (stride * size <= 256)
|
|
|
|
|
{
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 1 * stride));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 8) & 0xff));
|
|
|
|
|
CheckFrameIndex(reg, index, stride * size);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < size; i++)
|
|
|
|
|
{
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + i * stride));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> (8 * i)) & 0xff));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
|
|
|
|
|
}
|
|
|
|
|
else if (InterTypeSize[ins->mSrc[0].mType] == 4)
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 1 * stride));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 8) & 0xff));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 2 * stride));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 16) & 0xff));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 3 * stride));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 24) & 0xff));
|
|
|
|
|
for (int i = 0; i < size; i++)
|
|
|
|
|
{
|
|
|
|
|
CheckFrameIndex(reg, index, 1);
|
|
|
|
|
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> (8 * i)) & 0xff));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
|
|
|
|
|
|
|
|
|
|
index += stride;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -5219,33 +5284,32 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
|
|
|
|
|
{
|
|
|
|
|
int reg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
|
|
|
|
|
int index = ins->mSrc[1].mIntConst;
|
|
|
|
|
|
|
|
|
|
CheckFrameIndex(reg, index, InterTypeSize[ins->mSrc[0].mType]);
|
|
|
|
|
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index));
|
|
|
|
|
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
|
|
|
|
|
|
|
|
|
|
int stride = ins->mSrc[1].mStride;
|
|
|
|
|
int size = InterTypeSize[ins->mSrc[0].mType];
|
|
|
|
|
|
|
|
|
|
if (InterTypeSize[ins->mSrc[0].mType] == 2)
|
|
|
|
|
if (stride * size <= 256)
|
|
|
|
|
{
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 1 * stride));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1));
|
|
|
|
|
CheckFrameIndex(reg, index, stride * size);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < size; i++)
|
|
|
|
|
{
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + i * stride));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + i));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
|
|
|
|
|
}
|
|
|
|
|
else if (InterTypeSize[ins->mSrc[0].mType] == 4)
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 1 * stride));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 2 * stride));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 2));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 3 * stride));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 3));
|
|
|
|
|
for (int i = 0; i < size; i++)
|
|
|
|
|
{
|
|
|
|
|
CheckFrameIndex(reg, index, 1);
|
|
|
|
|
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + i));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
|
|
|
|
|
|
|
|
|
|
index += stride;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -5377,33 +5441,35 @@ void NativeCodeBasicBlock::LoadStoreIndirectValue(InterCodeProcedure* proc, cons
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (rmode == ASMIM_INDIRECT_Y)
|
|
|
|
|
CheckFrameIndex(rareg, rindex, size, BC_REG_ADDR);
|
|
|
|
|
|
|
|
|
|
if (wmode == ASMIM_INDIRECT_Y)
|
|
|
|
|
CheckFrameIndex(wareg, windex, size, BC_REG_ACCU);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < size; i++)
|
|
|
|
|
{
|
|
|
|
|
if (rmode == ASMIM_INDIRECT_Y)
|
|
|
|
|
CheckFrameIndex(rareg, rindex, 1, BC_REG_ADDR);
|
|
|
|
|
if (wmode == ASMIM_INDIRECT_Y)
|
|
|
|
|
CheckFrameIndex(wareg, windex, 1, BC_REG_ACCU);
|
|
|
|
|
|
|
|
|
|
if (rmode == ASMIM_INDIRECT_Y)
|
|
|
|
|
{
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, rindex + i * rstride));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, rindex));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, rareg, nullptr, rflags));
|
|
|
|
|
}
|
|
|
|
|
else if (rmode == ASMIM_ZERO_PAGE)
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, rareg + i));
|
|
|
|
|
else
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, rindex + i * rstride, rlobject, rflags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, rindex, rlobject, rflags));
|
|
|
|
|
|
|
|
|
|
if (wmode == ASMIM_INDIRECT_Y)
|
|
|
|
|
{
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, windex + i * wstride));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, windex));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, wareg, nullptr, wflags));
|
|
|
|
|
}
|
|
|
|
|
else if (wmode == ASMIM_ZERO_PAGE)
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, wareg + i));
|
|
|
|
|
else
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, windex + i * wstride, wlobject, wflags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, windex, wlobject, wflags));
|
|
|
|
|
|
|
|
|
|
rindex += rstride;
|
|
|
|
|
windex += wstride;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -5736,6 +5802,7 @@ bool NativeCodeBasicBlock::LoadOpStoreIndirectValue(InterCodeProcedure* proc, co
|
|
|
|
|
|
|
|
|
|
int rindex = rins->mSrc[0].mIntConst;
|
|
|
|
|
int rareg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
|
|
|
|
|
int rstride = rins->mSrc[0].mStride;
|
|
|
|
|
|
|
|
|
|
switch (rins->mSrc[0].mMemory)
|
|
|
|
|
{
|
|
|
|
@ -5759,6 +5826,7 @@ bool NativeCodeBasicBlock::LoadOpStoreIndirectValue(InterCodeProcedure* proc, co
|
|
|
|
|
|
|
|
|
|
int windex = wins->mSrc[1].mIntConst;
|
|
|
|
|
int wareg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
|
|
|
|
|
int wstride = wins->mSrc[1].mStride;
|
|
|
|
|
|
|
|
|
|
switch (wins->mSrc[1].mMemory)
|
|
|
|
|
{
|
|
|
|
@ -5780,6 +5848,9 @@ bool NativeCodeBasicBlock::LoadOpStoreIndirectValue(InterCodeProcedure* proc, co
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (rstride * size >= 256 || wstride * size >= 256)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
uint32 rflags = NCIF_LOWER | NCIF_UPPER;
|
|
|
|
|
if (rins->mVolatile)
|
|
|
|
|
rflags |= NCIF_VOLATILE;
|
|
|
|
@ -5825,7 +5896,7 @@ bool NativeCodeBasicBlock::LoadOpStoreIndirectValue(InterCodeProcedure* proc, co
|
|
|
|
|
|
|
|
|
|
if (ram == ASMIM_INDIRECT_Y)
|
|
|
|
|
{
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, rindex + i));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, rindex + i * rstride));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(at, ram, rareg));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
@ -5835,7 +5906,7 @@ bool NativeCodeBasicBlock::LoadOpStoreIndirectValue(InterCodeProcedure* proc, co
|
|
|
|
|
{
|
|
|
|
|
if (ram == ASMIM_INDIRECT_Y)
|
|
|
|
|
{
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, rindex + i));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, rindex + i * rstride));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ram, rareg));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
@ -5856,7 +5927,7 @@ bool NativeCodeBasicBlock::LoadOpStoreIndirectValue(InterCodeProcedure* proc, co
|
|
|
|
|
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_LDY, ASMIM_IMMEDIATE, windex + i * wstride));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, wam, wareg));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
@ -5874,28 +5945,30 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
|
|
|
|
|
|
|
|
|
|
if (ins->mDst.mType == IT_FLOAT)
|
|
|
|
|
{
|
|
|
|
|
int stride = ins->mSrc[0].mStride;
|
|
|
|
|
|
|
|
|
|
if (ins->mSrc[0].mTemp < 0)
|
|
|
|
|
{
|
|
|
|
|
if (ins->mSrc[0].mMemory == IM_GLOBAL)
|
|
|
|
|
{
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst, ins->mSrc[0].mLinkerObject, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst + 1, ins->mSrc[0].mLinkerObject, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst + 1 * stride, ins->mSrc[0].mLinkerObject, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst + 2, ins->mSrc[0].mLinkerObject, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst + 2 * stride, ins->mSrc[0].mLinkerObject, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 2));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst + 3, ins->mSrc[0].mLinkerObject, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst + 3 * stride, ins->mSrc[0].mLinkerObject, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 3));
|
|
|
|
|
}
|
|
|
|
|
else if (ins->mSrc[0].mMemory == IM_ABSOLUTE)
|
|
|
|
|
{
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst, nullptr, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst + 1, nullptr, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst + 1 * stride, nullptr, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst + 2, nullptr, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst + 2 * stride, nullptr, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 2));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst + 3, nullptr, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst + 3 * stride, nullptr, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 3));
|
|
|
|
|
}
|
|
|
|
|
else if (ins->mSrc[0].mMemory == IM_FPARAM)
|
|
|
|
@ -5940,22 +6013,32 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
|
|
|
|
|
{
|
|
|
|
|
int areg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
|
|
|
|
|
int index = ins->mSrc[0].mIntConst;
|
|
|
|
|
int stride = ins->mSrc[0].mStride;
|
|
|
|
|
|
|
|
|
|
CheckFrameIndex(areg, index, 4);
|
|
|
|
|
if (stride * 4 <= 256)
|
|
|
|
|
{
|
|
|
|
|
CheckFrameIndex(areg, index, stride * 4);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
|
|
|
{
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + i * stride));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + i));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
|
|
|
{
|
|
|
|
|
CheckFrameIndex(areg, index, 1);
|
|
|
|
|
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + i));
|
|
|
|
|
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 1));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 2));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 2));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 3));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 3));
|
|
|
|
|
index += stride;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -6276,13 +6359,23 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
|
|
|
|
|
{
|
|
|
|
|
int areg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
|
|
|
|
|
int index = ins->mSrc[0].mIntConst;
|
|
|
|
|
int stride = ins->mSrc[0].mStride;
|
|
|
|
|
int size = InterTypeSize[ins->mDst.mType];
|
|
|
|
|
bool accu = false;
|
|
|
|
|
|
|
|
|
|
CheckFrameIndex(areg, index, InterTypeSize[ins->mDst.mType]);
|
|
|
|
|
|
|
|
|
|
if (InterTypeSize[ins->mDst.mType] == 1)
|
|
|
|
|
if (size * stride <= 256)
|
|
|
|
|
{
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index));
|
|
|
|
|
CheckFrameIndex(areg, index, size * stride);
|
|
|
|
|
|
|
|
|
|
accu = reg == areg;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < size; i++)
|
|
|
|
|
{
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + i * stride));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg, nullptr, flags));
|
|
|
|
|
|
|
|
|
|
if (i == 0)
|
|
|
|
|
{
|
|
|
|
|
if (ainsl)
|
|
|
|
|
{
|
|
|
|
|
if (ainsl->mType == ASMIT_ADC)
|
|
|
|
@ -6291,66 +6384,45 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED));
|
|
|
|
|
mIns.Push(*ainsl);
|
|
|
|
|
}
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
|
|
|
|
|
if (InterTypeSize[ins->mDst.mType] > 1)
|
|
|
|
|
{
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
|
|
|
|
if (ainsh) mIns.Push(*ainsh);
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (InterTypeSize[ins->mDst.mType] == 2)
|
|
|
|
|
{
|
|
|
|
|
int stride = ins->mSrc[0].mStride;
|
|
|
|
|
else if (ainsh)
|
|
|
|
|
mIns.Push(*ainsh);
|
|
|
|
|
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg, nullptr, flags));
|
|
|
|
|
if (ainsl)
|
|
|
|
|
{
|
|
|
|
|
if (ainsl->mType == ASMIT_ADC)
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED));
|
|
|
|
|
else if (ainsl->mType == ASMIT_SBC)
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED));
|
|
|
|
|
mIns.Push(*ainsl);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (InterTypeSize[ins->mDst.mType] > 1)
|
|
|
|
|
{
|
|
|
|
|
if (reg == areg)
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK_Y));
|
|
|
|
|
if (accu)
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + i));
|
|
|
|
|
else
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
|
|
|
|
|
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 1 * stride));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg, nullptr, flags));
|
|
|
|
|
if (ainsh) mIns.Push(*ainsh);
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1));
|
|
|
|
|
if (reg == areg)
|
|
|
|
|
{
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_WORK_Y));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + i));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
|
|
|
|
|
}
|
|
|
|
|
else if (InterTypeSize[ins->mDst.mType] == 4)
|
|
|
|
|
{
|
|
|
|
|
int stride = ins->mSrc[0].mStride;
|
|
|
|
|
assert(ainsl == nullptr && ainsh == nullptr);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < size; i++)
|
|
|
|
|
{
|
|
|
|
|
CheckFrameIndex(areg, index, i * stride);
|
|
|
|
|
if (reg == areg)
|
|
|
|
|
accu = true;
|
|
|
|
|
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg, nullptr, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
|
|
|
|
|
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 1 * stride));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg, nullptr, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 2 * stride));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg, nullptr, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 2));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 3 * stride));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg, nullptr, flags));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 3));
|
|
|
|
|
if (accu)
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + i));
|
|
|
|
|
else
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + i));
|
|
|
|
|
|
|
|
|
|
index += stride;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (accu)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < size; i++)
|
|
|
|
|
{
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + i));
|
|
|
|
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + i));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -29218,7 +29290,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|
|
|
|
mIns[i + 5].mType = ASMIT_NOP; mIns[i + 5].mMode = ASMIM_IMPLIED;
|
|
|
|
|
|
|
|
|
|
proc->ResetPatched();
|
|
|
|
|
if (PatchGlobalAddressSumYPointer(this, mIns[i + 2].mAddress, mIns[i + 2].mAddress, i + 6, -1, mIns[i + 3].mLinkerObject, mIns[i + 3].mAddress))
|
|
|
|
|
if (PatchGlobalAddressSumYPointer(this, mIns[i + 2].mAddress, mIns[i + 2].mAddress, i + 6, -1, mIns[i + 3].mLinkerObject, mIns[i + 3].mAddress + mIns[i + 4].mAddress * 256))
|
|
|
|
|
progress = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -29266,6 +29338,21 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
#if 1
|
|
|
|
|
else if (
|
|
|
|
|
mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_IMMEDIATE_ADDRESS && (mIns[i + 1].mFlags & NCIF_UPPER) &&
|
|
|
|
|
mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
|
|
|
|
|
!(mIns[i + 1].mLive & LIVE_CPU_REG_A))
|
|
|
|
|
{
|
|
|
|
|
proc->ResetPatched();
|
|
|
|
|
if (CheckGlobalAddressSumYPointer(this, mIns[i + 1].mAddress - 1, mIns[i + 1].mAddress - 1, i + 2, -1))
|
|
|
|
|
{
|
|
|
|
|
proc->ResetPatched();
|
|
|
|
|
if (PatchGlobalAddressSumYPointer(this, mIns[i + 1].mAddress - 1, mIns[i + 1].mAddress - 1, i + 2, -1, mIns[i + 0].mLinkerObject, mIns[i + 0].mAddress))
|
|
|
|
|
progress = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -29336,7 +29423,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|
|
|
|
mIns[i + 2].mType == ASMIT_ADC &&
|
|
|
|
|
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE &&
|
|
|
|
|
mIns[i + 4].mType == ASMIT_LDA && mIns[i + 4].mMode == ASMIM_IMMEDIATE_ADDRESS && (mIns[i + 4].mFlags & NCIF_UPPER) && mIns[i + 4].mLinkerObject == mIns[i + 1].mLinkerObject && mIns[i + 4].mAddress == mIns[i + 1].mAddress &&
|
|
|
|
|
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_IMMEDIATE &&
|
|
|
|
|
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))
|
|
|
|
|
{
|
|
|
|
@ -29351,7 +29438,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|
|
|
|
mIns[i + 6].mType = ASMIT_NOP; mIns[i + 6].mMode = ASMIM_IMPLIED;
|
|
|
|
|
|
|
|
|
|
proc->ResetPatched();
|
|
|
|
|
if (PatchGlobalAddressSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 3].mAddress, i + 7, -1, mIns[i + 1].mLinkerObject, mIns[i + 1].mAddress))
|
|
|
|
|
if (PatchGlobalAddressSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 3].mAddress, i + 7, -1, mIns[i + 1].mLinkerObject, mIns[i + 1].mAddress + mIns[i + 5].mAddress * 256))
|
|
|
|
|
progress = true;
|
|
|
|
|
}
|
|
|
|
|
else if (mIns[i + 2].mMode == ASMIM_ZERO_PAGE && mIns[i + 2].mAddress != mIns[i + 3].mAddress)
|
|
|
|
@ -29360,7 +29447,44 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|
|
|
|
if (CheckGlobalAddressSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 2].mAddress, i + 7, -1))
|
|
|
|
|
{
|
|
|
|
|
proc->ResetPatched();
|
|
|
|
|
if (PatchGlobalAddressSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 2].mAddress, i + 7, -1, mIns[i + 1].mLinkerObject, mIns[i + 1].mAddress))
|
|
|
|
|
if (PatchGlobalAddressSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 2].mAddress, i + 7, -1, mIns[i + 1].mLinkerObject, mIns[i + 1].mAddress + mIns[i + 5].mAddress * 256))
|
|
|
|
|
progress = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
#if 1
|
|
|
|
|
if (pass == 0 &&
|
|
|
|
|
mIns[i + 0].mType == ASMIT_CLC &&
|
|
|
|
|
mIns[i + 1].mType == ASMIT_LDA &&
|
|
|
|
|
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE_ADDRESS && (mIns[i + 2].mFlags & NCIF_LOWER) &&
|
|
|
|
|
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE &&
|
|
|
|
|
mIns[i + 4].mType == ASMIT_LDA && mIns[i + 4].mMode == ASMIM_IMMEDIATE &&
|
|
|
|
|
mIns[i + 5].mType == ASMIT_ADC && mIns[i + 5].mMode == ASMIM_IMMEDIATE_ADDRESS && (mIns[i + 5].mFlags & NCIF_UPPER) && mIns[i + 5].mLinkerObject == mIns[i + 2].mLinkerObject && mIns[i + 5].mAddress == mIns[i + 2].mAddress &&
|
|
|
|
|
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))
|
|
|
|
|
{
|
|
|
|
|
proc->ResetPatched();
|
|
|
|
|
if (CheckGlobalAddressSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 3].mAddress, i + 7, -1))
|
|
|
|
|
{
|
|
|
|
|
mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED;
|
|
|
|
|
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
|
|
|
|
|
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();
|
|
|
|
|
if (PatchGlobalAddressSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 3].mAddress, i + 7, -1, mIns[i + 2].mLinkerObject, mIns[i + 2].mAddress + mIns[i + 4].mAddress * 256))
|
|
|
|
|
progress = true;
|
|
|
|
|
}
|
|
|
|
|
else if (mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mAddress != mIns[i + 3].mAddress)
|
|
|
|
|
{
|
|
|
|
|
proc->ResetPatched();
|
|
|
|
|
if (CheckGlobalAddressSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 1].mAddress, i + 7, -1))
|
|
|
|
|
{
|
|
|
|
|
proc->ResetPatched();
|
|
|
|
|
if (PatchGlobalAddressSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 1].mAddress, i + 7, -1, mIns[i + 2].mLinkerObject, mIns[i + 2].mAddress + mIns[i + 4].mAddress * 256))
|
|
|
|
|
progress = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -29374,7 +29498,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|
|
|
|
mIns[i + 2].mType == ASMIT_ADC &&
|
|
|
|
|
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE &&
|
|
|
|
|
mIns[i + 4].mType == ASMIT_LDA && mIns[i + 4].mMode == ASMIM_IMMEDIATE &&
|
|
|
|
|
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_IMMEDIATE &&
|
|
|
|
|
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))
|
|
|
|
|
{
|
|
|
|
@ -29389,7 +29513,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|
|
|
|
mIns[i + 6].mType = ASMIT_NOP; mIns[i + 6].mMode = ASMIM_IMPLIED;
|
|
|
|
|
|
|
|
|
|
proc->ResetPatched();
|
|
|
|
|
if (PatchGlobalAddressSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 3].mAddress, i + 7, -1, nullptr, mIns[i + 1].mAddress + 256 * mIns[i + 4].mAddress))
|
|
|
|
|
if (PatchGlobalAddressSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 3].mAddress, i + 7, -1, nullptr, mIns[i + 1].mAddress + 256 * mIns[i + 4].mAddress + mIns[i + 5].mAddress * 25))
|
|
|
|
|
progress = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -31118,8 +31242,7 @@ void NativeCodeProcedure::RebuildEntry(void)
|
|
|
|
|
|
|
|
|
|
void NativeCodeProcedure::Optimize(void)
|
|
|
|
|
{
|
|
|
|
|
CheckFunc = !strcmp(mInterProc->mIdent->mString, "menu_draw_color_line");
|
|
|
|
|
|
|
|
|
|
CheckFunc = !strcmp(mInterProc->mIdent->mString, "test_ab256");
|
|
|
|
|
#if 1
|
|
|
|
|
int step = 0;
|
|
|
|
|
int cnt = 0;
|
|
|
|
@ -31199,7 +31322,15 @@ void NativeCodeProcedure::Optimize(void)
|
|
|
|
|
ResetVisited();
|
|
|
|
|
changed = mEntryBlock->RemoveUnusedResultInstructions();
|
|
|
|
|
|
|
|
|
|
if (step == 0)
|
|
|
|
|
{
|
|
|
|
|
ResetVisited();
|
|
|
|
|
if (mEntryBlock->Propagate16BitSum())
|
|
|
|
|
changed = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!changed)
|
|
|
|
|
{
|
|
|
|
|
ResetVisited();
|
|
|
|
|
NativeRegisterDataSet data;
|
|
|
|
|
if (mEntryBlock->ValueForwarding(data, step > 0, step == 7))
|
|
|
|
@ -31219,11 +31350,6 @@ void NativeCodeProcedure::Optimize(void)
|
|
|
|
|
changed = true;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
if (!changed)
|
|
|
|
|
{
|
|
|
|
|
ResetVisited();
|
|
|
|
|
if (mEntryBlock->Propagate16BitSum())
|
|
|
|
|
changed = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -31810,6 +31936,7 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
|
|
|
|
|
}
|
|
|
|
|
else if (i + 1 < iblock->mInstructions.Size() &&
|
|
|
|
|
InterTypeSize[ins->mDst.mType] >= 2 &&
|
|
|
|
|
InterTypeSize[ins->mDst.mType] * ins->mSrc[0].mStride <= 256 &&
|
|
|
|
|
iblock->mInstructions[i + 1]->mCode == IC_BINARY_OPERATOR &&
|
|
|
|
|
iblock->mInstructions[i + 1]->mSrc[0].mTemp == ins->mDst.mTemp && iblock->mInstructions[i + 1]->mSrc[0].mFinal)
|
|
|
|
|
{
|
|
|
|
@ -31818,6 +31945,7 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
|
|
|
|
|
}
|
|
|
|
|
else if (i + 1 < iblock->mInstructions.Size() &&
|
|
|
|
|
InterTypeSize[ins->mDst.mType] >= 2 &&
|
|
|
|
|
InterTypeSize[ins->mDst.mType] * ins->mSrc[0].mStride < 256 &&
|
|
|
|
|
iblock->mInstructions[i + 1]->mCode == IC_BINARY_OPERATOR &&
|
|
|
|
|
iblock->mInstructions[i + 1]->mSrc[1].mTemp == ins->mDst.mTemp && iblock->mInstructions[i + 1]->mSrc[1].mFinal)
|
|
|
|
|
{
|
|
|
|
@ -31826,7 +31954,9 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
|
|
|
|
|
}
|
|
|
|
|
else if (i + 2 < iblock->mInstructions.Size() &&
|
|
|
|
|
InterTypeSize[ins->mDst.mType] >= 2 &&
|
|
|
|
|
InterTypeSize[ins->mDst.mType] * ins->mSrc[0].mStride <= 256 &&
|
|
|
|
|
iblock->mInstructions[i + 1]->mCode == IC_LOAD && InterTypeSize[iblock->mInstructions[i + 1]->mDst.mType] >= 2 &&
|
|
|
|
|
InterTypeSize[iblock->mInstructions[i + 1]->mDst.mType] * iblock->mInstructions[i + 1]->mSrc[0].mStride <= 256 &&
|
|
|
|
|
iblock->mInstructions[i + 1]->mDst.mTemp != ins->mDst.mTemp &&
|
|
|
|
|
iblock->mInstructions[i + 2]->mCode == IC_BINARY_OPERATOR &&
|
|
|
|
|
iblock->mInstructions[i + 2]->mSrc[0].mTemp == iblock->mInstructions[i + 1]->mDst.mTemp && iblock->mInstructions[i + 2]->mSrc[0].mFinal &&
|
|
|
|
@ -31837,7 +31967,9 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
|
|
|
|
|
}
|
|
|
|
|
else if (i + 2 < iblock->mInstructions.Size() &&
|
|
|
|
|
InterTypeSize[ins->mDst.mType] >= 2 &&
|
|
|
|
|
InterTypeSize[ins->mDst.mType] * ins->mSrc[0].mStride <= 256 &&
|
|
|
|
|
iblock->mInstructions[i + 1]->mCode == IC_LOAD && InterTypeSize[iblock->mInstructions[i + 1]->mDst.mType] >= 2 &&
|
|
|
|
|
InterTypeSize[iblock->mInstructions[i + 1]->mDst.mType] * iblock->mInstructions[i + 1]->mSrc[0].mStride <= 256 &&
|
|
|
|
|
iblock->mInstructions[i + 1]->mDst.mTemp != ins->mDst.mTemp &&
|
|
|
|
|
iblock->mInstructions[i + 2]->mCode == IC_BINARY_OPERATOR &&
|
|
|
|
|
iblock->mInstructions[i + 2]->mSrc[1].mTemp == iblock->mInstructions[i + 1]->mDst.mTemp && iblock->mInstructions[i + 2]->mSrc[1].mFinal &&
|
|
|
|
@ -31934,7 +32066,8 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
|
|
|
|
|
iblock->mInstructions[i + 1]->mCode == IC_LOAD && iblock->mInstructions[i + 1]->mSrc[0].mTemp == ins->mDst.mTemp && iblock->mInstructions[i + 1]->mSrc[0].mFinal &&
|
|
|
|
|
ins->mSrc[1].mTemp >= 0 && ins->mSrc[0].IsUByte() && ins->mSrc[0].mTemp >= 0 &&
|
|
|
|
|
iblock->mInstructions[i + 1]->mSrc[0].mIntConst == 0 &&
|
|
|
|
|
(InterTypeSize[iblock->mInstructions[i + 1]->mDst.mType] == 1 || ins->mSrc[1].mTemp != iblock->mInstructions[i + 1]->mDst.mTemp))
|
|
|
|
|
(InterTypeSize[iblock->mInstructions[i + 1]->mDst.mType] == 1 || ins->mSrc[1].mTemp != iblock->mInstructions[i + 1]->mDst.mTemp) &&
|
|
|
|
|
(InterTypeSize[iblock->mInstructions[i + 1]->mDst.mType] == 1 || iblock->mInstructions[i + 1]->mSrc[0].mStride == 1))
|
|
|
|
|
{
|
|
|
|
|
block->LoadByteIndexedValue(iproc, ins, iblock->mInstructions[i + 1]);
|
|
|
|
|
i++;
|
|
|
|
@ -31942,7 +32075,8 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
|
|
|
|
|
else if (i + 1 < iblock->mInstructions.Size() &&
|
|
|
|
|
iblock->mInstructions[i + 1]->mCode == IC_STORE && iblock->mInstructions[i + 1]->mSrc[1].mTemp == ins->mDst.mTemp && iblock->mInstructions[i + 1]->mSrc[1].mFinal &&
|
|
|
|
|
ins->mSrc[1].mTemp >= 0 && ins->mSrc[0].IsUByte() && ins->mSrc[0].mTemp >= 0 &&
|
|
|
|
|
iblock->mInstructions[i + 1]->mSrc[1].mIntConst == 0 && iblock->mInstructions[i + 1]->mSrc[0].mTemp >= 0)
|
|
|
|
|
iblock->mInstructions[i + 1]->mSrc[1].mIntConst == 0 && iblock->mInstructions[i + 1]->mSrc[0].mTemp >= 0 &&
|
|
|
|
|
(InterTypeSize[iblock->mInstructions[i + 1]->mSrc[0].mType] == 1 || iblock->mInstructions[i + 1]->mSrc[1].mStride == 1))
|
|
|
|
|
{
|
|
|
|
|
block->StoreByteIndexedValue(iproc, ins, iblock->mInstructions[i + 1]);
|
|
|
|
|
i++;
|
|
|
|
|