Address promotion into struct copy inter instructions

This commit is contained in:
drmortalwombat 2022-03-14 08:35:59 +01:00
parent ea09c2aa7b
commit a65c802485
7 changed files with 349 additions and 15 deletions

View File

@ -84,7 +84,7 @@ int main(void)
} }
q[i] = sqrt(sumr * sumr + sumi * sumi); q[i] = sqrt(sumr * sumr + sumi * sumi);
} }
#if 0 #if 1
for(int i=0; i<20; i++) for(int i=0; i<20; i++)
{ {
printf("%d, %f - %f\n", i, p[i], q[i]); printf("%d, %f - %f\n", i, p[i], q[i]);

View File

@ -1363,6 +1363,99 @@ void ByteCodeBasicBlock::IntConstToAddr(int64 val)
mIns.Push(ins); mIns.Push(ins);
} }
void ByteCodeBasicBlock::LoadOperandAddress(InterCodeProcedure* proc, const InterOperand& op, int reg)
{
if (op.mTemp < 0)
{
if (op.mMemory == IM_GLOBAL)
{
ByteCodeInstruction bins(BC_LEA_ABS);
bins.mRegister = reg;
bins.mLinkerObject = op.mLinkerObject;
bins.mValue = op.mIntConst;
bins.mRelocate = true;
mIns.Push(bins);
}
else if (op.mMemory == IM_ABSOLUTE)
{
ByteCodeInstruction bins(BC_LEA_ABS);
bins.mRegister = reg;
bins.mValue = op.mIntConst;
mIns.Push(bins);
}
else if (op.mMemory == IM_LOCAL)
{
ByteCodeInstruction bins(BC_LEA_LOCAL);
bins.mRegister = reg;
bins.mValue = op.mIntConst + proc->mLocalVars[op.mVarIndex]->mOffset;
mIns.Push(bins);
}
else if (op.mMemory == IM_PARAM)
{
ByteCodeInstruction bins(BC_LEA_LOCAL);
bins.mRegister = reg;
bins.mValue = op.mIntConst + op.mVarIndex + proc->mLocalSize + 2;
mIns.Push(bins);
}
else if (op.mMemory == IM_FPARAM || op.mMemory == IM_FFRAME)
{
ByteCodeInstruction bins(BC_LEA_ABS);
bins.mRegister = reg;
bins.mValue = BC_REG_FPARAMS + op.mIntConst + op.mVarIndex;
mIns.Push(bins);
}
else if (op.mMemory == IM_FRAME)
{
ByteCodeInstruction bins(BC_LEA_FRAME);
bins.mRegister = reg;
bins.mValue = op.mVarIndex + op.mIntConst + 2;
mIns.Push(bins);
}
else if (op.mMemory == IM_PROCEDURE)
{
ByteCodeInstruction bins(BC_CONST_16);
bins.mRegister = reg;
bins.mLinkerObject = op.mLinkerObject;
bins.mValue = 0;
bins.mRelocate = true;
mIns.Push(bins);
}
}
else if (reg == BC_REG_ADDR)
{
if (op.mIntConst == 0)
{
ByteCodeInstruction sins(BC_ADDR_REG);
sins.mRegister = BC_REG_TMP + proc->mTempOffset[op.mTemp];
sins.mRegisterFinal = op.mFinal;
mIns.Push(sins);
}
else
{
ByteCodeInstruction lins(BC_LEA_ABS_INDEX);
lins.mRegister = BC_REG_TMP + proc->mTempOffset[op.mTemp];
lins.mRegisterFinal = op.mFinal;
lins.mValue = op.mIntConst;
mIns.Push(lins);
}
}
else if (reg == BC_REG_ACCU)
{
ByteCodeInstruction dins(BC_LOAD_REG_16);
dins.mRegister = BC_REG_TMP + proc->mTempOffset[op.mTemp];
dins.mRegisterFinal = op.mFinal;
mIns.Push(dins);
if (op.mIntConst)
{
ByteCodeInstruction iins(BC_BINOP_ADDI_16);
iins.mRegister = BC_REG_ACCU;
iins.mValue = op.mIntConst;
mIns.Push(iins);
}
}
}
void ByteCodeBasicBlock::LoadConstant(InterCodeProcedure* proc, const InterInstruction * ins) void ByteCodeBasicBlock::LoadConstant(InterCodeProcedure* proc, const InterInstruction * ins)
{ {
if (ins->mDst.mType == IT_FLOAT) if (ins->mDst.mType == IT_FLOAT)
@ -1456,14 +1549,9 @@ void ByteCodeBasicBlock::LoadConstant(InterCodeProcedure* proc, const InterInstr
void ByteCodeBasicBlock::CopyValue(InterCodeProcedure* proc, const InterInstruction * ins) void ByteCodeBasicBlock::CopyValue(InterCodeProcedure* proc, const InterInstruction * ins)
{ {
ByteCodeInstruction sins(BC_ADDR_REG); LoadOperandAddress(proc, ins->mSrc[0], BC_REG_ACCU);
sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]; LoadOperandAddress(proc, ins->mSrc[1], BC_REG_ADDR);
sins.mRegisterFinal = ins->mSrc[1].mFinal;
mIns.Push(sins);
ByteCodeInstruction dins(BC_LOAD_REG_16);
dins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
dins.mRegisterFinal = ins->mSrc[0].mFinal;
mIns.Push(dins);
ByteCodeInstruction cins(BC_COPY); ByteCodeInstruction cins(BC_COPY);
cins.mValue = ins->mConst.mOperandSize; cins.mValue = ins->mConst.mOperandSize;
mIns.Push(cins); mIns.Push(cins);

View File

@ -287,6 +287,8 @@ public:
void LoadDirectValue(InterCodeProcedure* proc, const InterInstruction * ins); void LoadDirectValue(InterCodeProcedure* proc, const InterInstruction * ins);
void LoadStoreIndirectValue(InterCodeProcedure* proc, const InterInstruction* rins, const InterInstruction* wins); void LoadStoreIndirectValue(InterCodeProcedure* proc, const InterInstruction* rins, const InterInstruction* wins);
void LoadOperandAddress(InterCodeProcedure* proc, const InterOperand& op, int reg);
void LoadEffectiveAddress(InterCodeProcedure* proc, const InterInstruction * ins); void LoadEffectiveAddress(InterCodeProcedure* proc, const InterInstruction * ins);
void CallFunction(InterCodeProcedure* proc, const InterInstruction * ins); void CallFunction(InterCodeProcedure* proc, const InterInstruction * ins);
void CallAssembler(InterCodeProcedure* proc, const InterInstruction * ins); void CallAssembler(InterCodeProcedure* proc, const InterInstruction * ins);

View File

@ -2040,6 +2040,36 @@ void InterInstruction::FilterVarsUsage(const GrowingVariableArray& localVars, Nu
providedParams += mSrc[1].mVarIndex; providedParams += mSrc[1].mVarIndex;
} }
} }
else if (mCode == IC_COPY || mCode == IC_STRCPY)
{
if (mSrc[0].mMemory == IM_LOCAL)
{
assert(mSrc[0].mTemp < 0);
if (!providedVars[mSrc[0].mVarIndex])
requiredVars += mSrc[0].mVarIndex;
}
else if (mSrc[0].mMemory == paramMemory)
{
assert(mSrc[0].mTemp < 0);
if (!providedParams[mSrc[0].mVarIndex])
requiredParams += mSrc[0].mVarIndex;
}
if (mSrc[1].mMemory == IM_LOCAL)
{
assert(mSrc[1].mTemp < 0);
if (!providedVars[mSrc[1].mVarIndex] && (mSrc[1].mIntConst != 0 || mSrc[1].mOperandSize != localVars[mSrc[1].mVarIndex]->mSize))
requiredVars += mSrc[1].mVarIndex;
providedVars += mSrc[1].mVarIndex;
}
else if (mSrc[1].mMemory == paramMemory)
{
assert(mSrc[1].mTemp < 0);
if (!providedParams[mSrc[1].mVarIndex] && (mSrc[1].mIntConst != 0 || mSrc[1].mOperandSize != params[mSrc[1].mVarIndex]->mSize))
requiredParams += mSrc[1].mVarIndex;
providedParams += mSrc[1].mVarIndex;
}
}
else if (mCode == IC_ASSEMBLER) else if (mCode == IC_ASSEMBLER)
{ {
for (int i = 1; i < mNumOperands; i++) for (int i = 1; i < mNumOperands; i++)
@ -2309,6 +2339,50 @@ bool InterInstruction::RemoveUnusedStoreInstructions(const GrowingVariableArray&
} }
} }
} }
else if (mCode == IC_COPY)
{
if (mSrc[1].mMemory == IM_LOCAL)
{
if (localVars[mSrc[1].mVarIndex]->mAliased)
;
else if (requiredVars[mSrc[1].mVarIndex])
{
if (mSrc[1].mIntConst == 0 && mSrc[1].mOperandSize == localVars[mSrc[1].mVarIndex]->mSize)
requiredVars -= mSrc[1].mVarIndex;
}
else
{
mSrc[0].mTemp = -1;
mCode = IC_NONE;
changed = true;
}
}
else if (mSrc[1].mMemory == paramMemory)
{
if (params[mSrc[1].mVarIndex]->mAliased)
;
else if (requiredParams[mSrc[1].mVarIndex])
{
if (mSrc[1].mIntConst == 0 && mSrc[1].mOperandSize == params[mSrc[1].mVarIndex]->mSize)
requiredParams -= mSrc[1].mVarIndex;
}
else
{
mSrc[0].mTemp = -1;
mCode = IC_NONE;
changed = true;
}
}
if (mSrc[0].mMemory == IM_LOCAL)
{
requiredVars += mSrc[0].mVarIndex;
}
else if (mSrc[0].mMemory == paramMemory)
{
requiredParams += mSrc[0].mVarIndex;
}
}
return changed; return changed;
} }
@ -2565,6 +2639,16 @@ void InterInstruction::CollectSimpleLocals(FastNumberSet& complexLocals, FastNum
else if ((mSrc[1].mMemory == IM_PARAM || mSrc[1].mMemory == IM_FPARAM) && mSrc[1].mTemp < 0) else if ((mSrc[1].mMemory == IM_PARAM || mSrc[1].mMemory == IM_FPARAM) && mSrc[1].mTemp < 0)
complexParams += mSrc[1].mVarIndex; complexParams += mSrc[1].mVarIndex;
break; break;
case IC_COPY:
if (mSrc[1].mMemory == IM_LOCAL && mSrc[1].mTemp < 0)
complexLocals += mSrc[1].mVarIndex;
else if ((mSrc[1].mMemory == IM_PARAM || mSrc[1].mMemory == IM_FPARAM) && mSrc[1].mTemp < 0)
complexParams += mSrc[1].mVarIndex;
if (mSrc[0].mMemory == IM_LOCAL && mSrc[0].mTemp < 0)
complexLocals += mSrc[0].mVarIndex;
else if ((mSrc[0].mMemory == IM_PARAM || mSrc[0].mMemory == IM_FPARAM) && mSrc[0].mTemp < 0)
complexParams += mSrc[0].mVarIndex;
break;
case IC_CONSTANT: case IC_CONSTANT:
if (mDst.mType == IT_POINTER && mConst.mMemory == IM_LOCAL) if (mDst.mType == IT_POINTER && mConst.mMemory == IM_LOCAL)
complexLocals += mConst.mVarIndex; complexLocals += mConst.mVarIndex;
@ -3289,6 +3373,10 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI
} }
OptimizeAddress(ins, tvalue, 1); OptimizeAddress(ins, tvalue, 1);
break; break;
case IC_COPY:
OptimizeAddress(ins, tvalue, 0);
OptimizeAddress(ins, tvalue, 1);
break;
case IC_LEA: case IC_LEA:
if (ins->mSrc[0].mTemp >= 0 && tvalue[ins->mSrc[0].mTemp] && tvalue[ins->mSrc[0].mTemp]->mCode == IC_CONSTANT) if (ins->mSrc[0].mTemp >= 0 && tvalue[ins->mSrc[0].mTemp] && tvalue[ins->mSrc[0].mTemp]->mCode == IC_CONSTANT)
{ {
@ -6358,6 +6446,19 @@ void InterCodeBasicBlock::MapVariables(GrowingVariableArray& globalVars, Growing
localVars[mInstructions[i]->mSrc[0].mVarIndex]->mUsed = true; localVars[mInstructions[i]->mSrc[0].mVarIndex]->mUsed = true;
} }
break; break;
case IC_COPY:
case IC_STRCPY:
if (mInstructions[i]->mSrc[0].mMemory == IM_LOCAL)
{
localVars[mInstructions[i]->mSrc[0].mVarIndex]->mUsed = true;
}
if (mInstructions[i]->mSrc[1].mMemory == IM_LOCAL)
{
localVars[mInstructions[i]->mSrc[1].mVarIndex]->mUsed = true;
}
break;
} }
} }
@ -6571,7 +6672,7 @@ void InterCodeBasicBlock::RemoveNonRelevantStatics(void)
for (i = 0; i < mInstructions.Size(); i++) for (i = 0; i < mInstructions.Size(); i++)
{ {
InterInstruction* ins(mInstructions[i]); InterInstruction* ins(mInstructions[i]);
if (ins->mCode == IC_STORE) if (ins->mCode == IC_STORE || ins->mCode == IC_COPY)
{ {
if (ins->mSrc[1].mTemp < 0 && ins->mSrc[1].mMemory == IM_GLOBAL && !ins->mVolatile) if (ins->mSrc[1].mTemp < 0 && ins->mSrc[1].mMemory == IM_GLOBAL && !ins->mVolatile)
{ {
@ -6993,6 +7094,7 @@ void ApplyStaticStack(InterOperand & iop, const GrowingVariableArray& localVars)
{ {
iop.mMemory = IM_GLOBAL; iop.mMemory = IM_GLOBAL;
iop.mLinkerObject = localVars[iop.mVarIndex]->mLinkerObject; iop.mLinkerObject = localVars[iop.mVarIndex]->mLinkerObject;
iop.mVarIndex = localVars[iop.mVarIndex]->mIndex;
} }
} }
@ -7013,6 +7115,11 @@ void InterCodeBasicBlock::CollectStaticStack(LinkerObject* lobj, const GrowingVa
ApplyStaticStack(mInstructions[i]->mSrc[1], localVars); ApplyStaticStack(mInstructions[i]->mSrc[1], localVars);
else if (mInstructions[i]->mCode == IC_CONSTANT && mInstructions[i]->mDst.mType == IT_POINTER) else if (mInstructions[i]->mCode == IC_CONSTANT && mInstructions[i]->mDst.mType == IT_POINTER)
ApplyStaticStack(mInstructions[i]->mConst, localVars); ApplyStaticStack(mInstructions[i]->mConst, localVars);
else if (mInstructions[i]->mCode == IC_COPY)
{
ApplyStaticStack(mInstructions[i]->mSrc[0], localVars);
ApplyStaticStack(mInstructions[i]->mSrc[1], localVars);
}
} }
if (mTrueJump) mTrueJump->CollectStaticStack(lobj, localVars); if (mTrueJump) mTrueJump->CollectStaticStack(lobj, localVars);
@ -8547,6 +8654,8 @@ void InterCodeBasicBlock::CollectVariables(GrowingVariableArray& globalVars, Gro
case IC_STORE: case IC_STORE:
case IC_LOAD: case IC_LOAD:
case IC_COPY:
case IC_STRCPY:
case IC_CALL_NATIVE: case IC_CALL_NATIVE:
case IC_ASSEMBLER: case IC_ASSEMBLER:
@ -9471,6 +9580,8 @@ void InterCodeProcedure::Close(void)
{ {
var->mLinkerObject = mModule->mLinker->AddObject(mLocation, var->mIdent, mLinkerObject->mStackSection, LOT_BSS); var->mLinkerObject = mModule->mLinker->AddObject(mLocation, var->mIdent, mLinkerObject->mStackSection, LOT_BSS);
var->mLinkerObject->AddSpace(var->mSize); var->mLinkerObject->AddSpace(var->mSize);
var->mIndex = mModule->mGlobalVars.Size();
mModule->mGlobalVars.Push(var);
} }
} }
@ -9491,7 +9602,7 @@ void InterCodeProcedure::Close(void)
MergeBasicBlocks(); MergeBasicBlocks();
BuildTraces(false); BuildTraces(false);
DisassembleDebug("Merged basic blocks"); DisassembleDebug("Final Merged basic blocks");
} }

View File

@ -423,8 +423,6 @@ public:
void CollectActiveTemporaries(FastNumberSet& set); void CollectActiveTemporaries(FastNumberSet& set);
void ShrinkActiveTemporaries(FastNumberSet& set, GrowingTypeArray& temporaries); void ShrinkActiveTemporaries(FastNumberSet& set, GrowingTypeArray& temporaries);
void ApplyExceptionStackChanges(GrowingInterCodeBasicBlockPtrArray& exceptionStack);
void Disassemble(FILE* file, bool dumpSets); void Disassemble(FILE* file, bool dumpSets);
void CollectVariables(GrowingVariableArray & globalVars, GrowingVariableArray & localVars, GrowingVariableArray& paramVars, InterMemory paramMemory); void CollectVariables(GrowingVariableArray & globalVars, GrowingVariableArray & localVars, GrowingVariableArray& paramVars, InterMemory paramMemory);

View File

@ -1004,6 +1004,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
ins->mSrc[1].mType = IT_POINTER; ins->mSrc[1].mType = IT_POINTER;
ins->mSrc[1].mTemp = vl.mTemp; ins->mSrc[1].mTemp = vl.mTemp;
ins->mSrc[1].mMemory = IM_INDIRECT; ins->mSrc[1].mMemory = IM_INDIRECT;
ins->mSrc[0].mOperandSize = vl.mType->mSize;
ins->mSrc[1].mOperandSize = vl.mType->mSize;
ins->mConst.mOperandSize = vl.mType->mSize; ins->mConst.mOperandSize = vl.mType->mSize;
block->Append(ins); block->Append(ins);
} }
@ -1952,6 +1954,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
ins->mSrc[0].mTemp = vr.mTemp; ins->mSrc[0].mTemp = vr.mTemp;
ins->mSrc[1].mType = IT_POINTER; ins->mSrc[1].mType = IT_POINTER;
ins->mSrc[1].mTemp = vl.mTemp; ins->mSrc[1].mTemp = vl.mTemp;
ins->mSrc[0].mOperandSize = nex->mDecValue->mInteger;
ins->mSrc[1].mOperandSize = nex->mDecValue->mInteger;
ins->mConst.mOperandSize = nex->mDecValue->mInteger; ins->mConst.mOperandSize = nex->mDecValue->mInteger;
block->Append(ins); block->Append(ins);
@ -2089,6 +2093,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
cins->mSrc[1].mType = IT_POINTER; cins->mSrc[1].mType = IT_POINTER;
cins->mSrc[1].mTemp = ains->mDst.mTemp; cins->mSrc[1].mTemp = ains->mDst.mTemp;
cins->mSrc[1].mMemory = IM_INDIRECT; cins->mSrc[1].mMemory = IM_INDIRECT;
cins->mSrc[0].mOperandSize = vr.mType->mSize;
cins->mSrc[1].mOperandSize = vr.mType->mSize;
cins->mConst.mOperandSize = vr.mType->mSize; cins->mConst.mOperandSize = vr.mType->mSize;
block->Append(cins); block->Append(cins);
} }
@ -2352,6 +2358,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
cins->mSrc[1].mType = IT_POINTER; cins->mSrc[1].mType = IT_POINTER;
cins->mSrc[1].mTemp = ains->mDst.mTemp; cins->mSrc[1].mTemp = ains->mDst.mTemp;
cins->mSrc[1].mMemory = IM_INDIRECT; cins->mSrc[1].mMemory = IM_INDIRECT;
cins->mSrc[0].mOperandSize = vr.mType->mSize;
cins->mSrc[1].mOperandSize = vr.mType->mSize;
cins->mConst.mOperandSize = vr.mType->mSize; cins->mConst.mOperandSize = vr.mType->mSize;
block->Append(cins); block->Append(cins);
} }
@ -2621,6 +2629,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
cins->mSrc[1].mType = IT_POINTER; cins->mSrc[1].mType = IT_POINTER;
cins->mSrc[1].mTemp = ains->mDst.mTemp; cins->mSrc[1].mTemp = ains->mDst.mTemp;
cins->mSrc[1].mMemory = IM_INDIRECT; cins->mSrc[1].mMemory = IM_INDIRECT;
cins->mSrc[0].mOperandSize = vr.mType->mSize;
cins->mSrc[1].mOperandSize = vr.mType->mSize;
cins->mConst.mOperandSize = vr.mType->mSize; cins->mConst.mOperandSize = vr.mType->mSize;
block->Append(cins); block->Append(cins);
} }

View File

@ -5124,7 +5124,132 @@ void NativeCodeBasicBlock::LoadValue(InterCodeProcedure* proc, const InterInstru
NativeCodeBasicBlock * NativeCodeBasicBlock::CopyValue(InterCodeProcedure* proc, const InterInstruction * ins, NativeCodeProcedure* nproc) NativeCodeBasicBlock * NativeCodeBasicBlock::CopyValue(InterCodeProcedure* proc, const InterInstruction * ins, NativeCodeProcedure* nproc)
{ {
int sreg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp], dreg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]; int sreg, dreg;
if (ins->mSrc[0].mTemp < 0)
{
if (ins->mSrc[0].mMemory == IM_GLOBAL)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mSrc[0].mIntConst, ins->mSrc[0].mLinkerObject, NCIF_LOWER));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mSrc[0].mIntConst, ins->mSrc[0].mLinkerObject, NCIF_UPPER));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
sreg = BC_REG_ACCU;
}
else if (ins->mSrc[0].mMemory == IM_ABSOLUTE)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 8) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
sreg = BC_REG_ACCU;
}
else if (ins->mSrc[0].mMemory == IM_FPARAM)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, BC_REG_FPARAMS + ins->mSrc[0].mVarIndex + ins->mSrc[0].mIntConst));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
sreg = BC_REG_ACCU;
}
else if (ins->mSrc[0].mMemory == IM_LOCAL || ins->mSrc[0].mMemory == IM_PARAM)
{
int index = ins->mSrc[0].mIntConst;
int areg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
if (ins->mSrc[0].mMemory == IM_LOCAL)
index += proc->mLocalVars[ins->mSrc[0].mVarIndex]->mOffset;
else
index += ins->mSrc[0].mVarIndex + proc->mLocalSize + 2;
index += mFrameOffset;
CheckFrameIndex(areg, index, 256, BC_REG_ACCU);
sreg = BC_REG_ACCU;
}
}
else if (ins->mSrc[0].mIntConst != 0)
{
int index = ins->mSrc[0].mIntConst;
mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]));
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, index & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, (index >> 8) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
sreg = BC_REG_ACCU;
}
else
{
sreg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
}
if (ins->mSrc[1].mTemp < 0)
{
if (ins->mSrc[1].mMemory == IM_GLOBAL)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mSrc[1].mIntConst, ins->mSrc[1].mLinkerObject, NCIF_LOWER));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR + 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mSrc[1].mIntConst, ins->mSrc[1].mLinkerObject, NCIF_UPPER));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR + 1));
dreg = BC_REG_ADDR;
}
else if (ins->mSrc[1].mMemory == IM_ABSOLUTE)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[1].mIntConst & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR + 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[1].mIntConst >> 8) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR + 1));
dreg = BC_REG_ADDR;
}
else if (ins->mSrc[1].mMemory == IM_FPARAM)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, BC_REG_FPARAMS + ins->mSrc[1].mVarIndex + ins->mSrc[1].mIntConst));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR + 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR + 1));
dreg = BC_REG_ADDR;
}
else if (ins->mSrc[1].mMemory == IM_LOCAL || ins->mSrc[1].mMemory == IM_PARAM)
{
int index = ins->mSrc[0].mIntConst;
int areg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
if (ins->mSrc[1].mMemory == IM_LOCAL)
index += proc->mLocalVars[ins->mSrc[1].mVarIndex]->mOffset;
else
index += ins->mSrc[1].mVarIndex + proc->mLocalSize + 2;
index += mFrameOffset;
CheckFrameIndex(areg, index, 256, BC_REG_ADDR);
dreg = BC_REG_ADDR;
}
else if (ins->mSrc[1].mMemory == IM_FRAME)
{
int index = ins->mSrc[1].mVarIndex + ins->mSrc[1].mIntConst + 2;
mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, index & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, (index >> 8) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR + 1));
dreg = BC_REG_ADDR;
}
}
else if (ins->mSrc[1].mIntConst != 0)
{
int index = ins->mSrc[0].mIntConst;
mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]));
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, index & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, (index >> 8) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR + 1));
sreg = BC_REG_ADDR;
}
else
{
dreg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
}
int size = ins->mConst.mOperandSize; int size = ins->mConst.mOperandSize;
int msize = 4; int msize = 4;