From a65c8024853b82009147ab4e2c007bfa2c77e13f Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Mon, 14 Mar 2022 08:35:59 +0100 Subject: [PATCH] Address promotion into struct copy inter instructions --- autotest/cplxstructtest.c | 2 +- oscar64/ByteCodeGenerator.cpp | 104 ++++++++++++++++++++++++-- oscar64/ByteCodeGenerator.h | 2 + oscar64/InterCode.cpp | 117 ++++++++++++++++++++++++++++- oscar64/InterCode.h | 2 - oscar64/InterCodeGenerator.cpp | 10 +++ oscar64/NativeCodeGenerator.cpp | 127 +++++++++++++++++++++++++++++++- 7 files changed, 349 insertions(+), 15 deletions(-) diff --git a/autotest/cplxstructtest.c b/autotest/cplxstructtest.c index 1fb8a7f..07b76c5 100644 --- a/autotest/cplxstructtest.c +++ b/autotest/cplxstructtest.c @@ -84,7 +84,7 @@ int main(void) } q[i] = sqrt(sumr * sumr + sumi * sumi); } -#if 0 +#if 1 for(int i=0; i<20; i++) { printf("%d, %f - %f\n", i, p[i], q[i]); diff --git a/oscar64/ByteCodeGenerator.cpp b/oscar64/ByteCodeGenerator.cpp index bce918d..2b4189d 100644 --- a/oscar64/ByteCodeGenerator.cpp +++ b/oscar64/ByteCodeGenerator.cpp @@ -1363,6 +1363,99 @@ void ByteCodeBasicBlock::IntConstToAddr(int64 val) 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) { 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) { - ByteCodeInstruction sins(BC_ADDR_REG); - sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]; - 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); + LoadOperandAddress(proc, ins->mSrc[0], BC_REG_ACCU); + LoadOperandAddress(proc, ins->mSrc[1], BC_REG_ADDR); + ByteCodeInstruction cins(BC_COPY); cins.mValue = ins->mConst.mOperandSize; mIns.Push(cins); diff --git a/oscar64/ByteCodeGenerator.h b/oscar64/ByteCodeGenerator.h index 07604dd..04c03b3 100644 --- a/oscar64/ByteCodeGenerator.h +++ b/oscar64/ByteCodeGenerator.h @@ -287,6 +287,8 @@ public: void LoadDirectValue(InterCodeProcedure* proc, const InterInstruction * ins); 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 CallFunction(InterCodeProcedure* proc, const InterInstruction * ins); void CallAssembler(InterCodeProcedure* proc, const InterInstruction * ins); diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 5dc6053..3578b68 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -2040,6 +2040,36 @@ void InterInstruction::FilterVarsUsage(const GrowingVariableArray& localVars, Nu 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) { 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; } @@ -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) complexParams += mSrc[1].mVarIndex; 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: if (mDst.mType == IT_POINTER && mConst.mMemory == IM_LOCAL) complexLocals += mConst.mVarIndex; @@ -3289,6 +3373,10 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI } OptimizeAddress(ins, tvalue, 1); break; + case IC_COPY: + OptimizeAddress(ins, tvalue, 0); + OptimizeAddress(ins, tvalue, 1); + break; case IC_LEA: 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; } 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++) { 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) { @@ -6993,6 +7094,7 @@ void ApplyStaticStack(InterOperand & iop, const GrowingVariableArray& localVars) { iop.mMemory = IM_GLOBAL; 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); else if (mInstructions[i]->mCode == IC_CONSTANT && mInstructions[i]->mDst.mType == IT_POINTER) 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); @@ -8546,7 +8653,9 @@ void InterCodeBasicBlock::CollectVariables(GrowingVariableArray& globalVars, Gro break; case IC_STORE: - case IC_LOAD: + case IC_LOAD: + case IC_COPY: + case IC_STRCPY: case IC_CALL_NATIVE: 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->AddSpace(var->mSize); + var->mIndex = mModule->mGlobalVars.Size(); + mModule->mGlobalVars.Push(var); } } @@ -9491,7 +9602,7 @@ void InterCodeProcedure::Close(void) MergeBasicBlocks(); BuildTraces(false); - DisassembleDebug("Merged basic blocks"); + DisassembleDebug("Final Merged basic blocks"); } diff --git a/oscar64/InterCode.h b/oscar64/InterCode.h index de5a6da..36bdb03 100644 --- a/oscar64/InterCode.h +++ b/oscar64/InterCode.h @@ -423,8 +423,6 @@ public: void CollectActiveTemporaries(FastNumberSet& set); void ShrinkActiveTemporaries(FastNumberSet& set, GrowingTypeArray& temporaries); - void ApplyExceptionStackChanges(GrowingInterCodeBasicBlockPtrArray& exceptionStack); - void Disassemble(FILE* file, bool dumpSets); void CollectVariables(GrowingVariableArray & globalVars, GrowingVariableArray & localVars, GrowingVariableArray& paramVars, InterMemory paramMemory); diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index 3e71b1a..56bdf62 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -1004,6 +1004,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* ins->mSrc[1].mType = IT_POINTER; ins->mSrc[1].mTemp = vl.mTemp; 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; block->Append(ins); } @@ -1952,6 +1954,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* ins->mSrc[0].mTemp = vr.mTemp; ins->mSrc[1].mType = IT_POINTER; 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; block->Append(ins); @@ -2089,6 +2093,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* cins->mSrc[1].mType = IT_POINTER; cins->mSrc[1].mTemp = ains->mDst.mTemp; 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; block->Append(cins); } @@ -2352,6 +2358,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* cins->mSrc[1].mType = IT_POINTER; cins->mSrc[1].mTemp = ains->mDst.mTemp; 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; block->Append(cins); } @@ -2621,6 +2629,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* cins->mSrc[1].mType = IT_POINTER; cins->mSrc[1].mTemp = ains->mDst.mTemp; 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; block->Append(cins); } diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 18d6160..b069c9e 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -5124,7 +5124,132 @@ void NativeCodeBasicBlock::LoadValue(InterCodeProcedure* proc, const InterInstru 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 msize = 4;