From fb4ae26afb74f96dee5d2335702bd4cdf2cc8258 Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Thu, 7 Oct 2021 10:42:18 +0200 Subject: [PATCH] Prepare access to local variables in inline assembler --- oscar64/ByteCodeGenerator.cpp | 23 +++++++ oscar64/ByteCodeGenerator.h | 1 + oscar64/Compiler.cpp | 12 ++-- oscar64/Declaration.h | 1 - oscar64/InterCodeGenerator.cpp | 110 +++++++++++++++++++++++++++----- oscar64/InterCodeGenerator.h | 2 +- oscar64/Linker.cpp | 11 +--- oscar64/Linker.h | 4 +- oscar64/NativeCodeGenerator.cpp | 46 +++++++++---- oscar64/NativeCodeGenerator.h | 2 +- oscar64/Parser.cpp | 32 ++++------ 11 files changed, 179 insertions(+), 65 deletions(-) diff --git a/oscar64/ByteCodeGenerator.cpp b/oscar64/ByteCodeGenerator.cpp index 062d60b..97a459c 100644 --- a/oscar64/ByteCodeGenerator.cpp +++ b/oscar64/ByteCodeGenerator.cpp @@ -1899,6 +1899,27 @@ void ByteCodeBasicBlock::CallFunction(InterCodeProcedure* proc, const InterInstr } void ByteCodeBasicBlock::CallAssembler(InterCodeProcedure* proc, const InterInstruction * ins) +{ + if (ins->mSrc[0].mTemp < 0) + { + ByteCodeInstruction bins(BC_JSR); + bins.mRelocate = true; + bins.mLinkerObject = ins->mLinkerObject; + bins.mValue = ins->mSrc[0].mIntConst; + for (int i = 1; i < ins->mNumOperands; i++) + ins->mLinkerObject->mTemporaries[i - 1] = BC_REG_TMP + proc->mTempOffset[ins->mSrc[i].mTemp]; + mIns.Push(bins); + } + + if (ins->mDst.mTemp >= 0) + { + ByteCodeInstruction bins(StoreTypedTmpCodes[ins->mDst.mType]); + bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp]; + mIns.Push(bins); + } +} + +void ByteCodeBasicBlock::CallNative(InterCodeProcedure* proc, const InterInstruction* ins) { if (ins->mSrc[0].mTemp < 0) { @@ -2879,6 +2900,8 @@ void ByteCodeBasicBlock::Compile(InterCodeProcedure* iproc, ByteCodeProcedure* p CallFunction(iproc, ins); break; case IC_CALL_NATIVE: + CallNative(iproc, ins); + break; case IC_ASSEMBLER: CallAssembler(iproc, ins); break; diff --git a/oscar64/ByteCodeGenerator.h b/oscar64/ByteCodeGenerator.h index a15d332..103e69d 100644 --- a/oscar64/ByteCodeGenerator.h +++ b/oscar64/ByteCodeGenerator.h @@ -261,6 +261,7 @@ public: void LoadEffectiveAddress(InterCodeProcedure* proc, const InterInstruction * ins); void CallFunction(InterCodeProcedure* proc, const InterInstruction * ins); void CallAssembler(InterCodeProcedure* proc, const InterInstruction * ins); + void CallNative(InterCodeProcedure* proc, const InterInstruction* ins); void BinaryOperator(InterCodeProcedure* proc, const InterInstruction * ins); void UnaryOperator(InterCodeProcedure* proc, const InterInstruction * ins); void BinaryRROperator(InterCodeProcedure* proc, const InterInstruction * ins); diff --git a/oscar64/Compiler.cpp b/oscar64/Compiler.cpp index 7e6398a..28def4f 100644 --- a/oscar64/Compiler.cpp +++ b/oscar64/Compiler.cpp @@ -83,13 +83,13 @@ void Compiler::RegisterRuntime(const Location & loc, const Ident* ident) if (bcdec->mType == DT_CONST_ASSEMBLER) { if (!bcdec->mLinkerObject) - mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue); + mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue, nullptr); linkerObject = bcdec->mLinkerObject; } else if (bcdec->mType == DT_LABEL) { if (!bcdec->mBase->mLinkerObject) - mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase->mValue); + mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase->mValue, nullptr); linkerObject = bcdec->mBase->mLinkerObject; offset = bcdec->mInteger; @@ -157,7 +157,7 @@ bool Compiler::GenerateCode(void) dcrtstart->mSection = sectionStartup; mInterCodeGenerator->mForceNativeCode = mNativeCode; - mInterCodeGenerator->TranslateAssembler(mInterCodeModule, dcrtstart->mValue); + mInterCodeGenerator->TranslateAssembler(mInterCodeModule, dcrtstart->mValue, nullptr); if (mErrors->mErrorCount != 0) return false; @@ -201,7 +201,7 @@ bool Compiler::GenerateCode(void) if (bcdec->mType == DT_CONST_ASSEMBLER) { if (!bcdec->mLinkerObject) - mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue); + mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue, nullptr); mByteCodeGenerator->mExtByteCodes[i] = bcdec->mLinkerObject; } } @@ -252,13 +252,13 @@ bool Compiler::GenerateCode(void) if (bcdec->mType == DT_CONST_ASSEMBLER) { if (!bcdec->mLinkerObject) - mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue); + mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue, nullptr); linkerObject = bcdec->mLinkerObject; } else if (bcdec->mType == DT_LABEL) { if (!bcdec->mBase->mLinkerObject) - mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase->mValue); + mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase->mValue, nullptr); linkerObject = bcdec->mBase->mLinkerObject; offset = bcdec->mInteger; } diff --git a/oscar64/Declaration.h b/oscar64/Declaration.h index 13ec55c..6650d06 100644 --- a/oscar64/Declaration.h +++ b/oscar64/Declaration.h @@ -61,7 +61,6 @@ static const uint32 DTF_UPPER_BYTE = 0x00000400; static const uint32 DTF_LOWER_BYTE = 0x00000800; static const uint32 DTF_SECTION_START = 0x00001000; static const uint32 DTF_SECTION_END = 0x00002000; -static const uint32 DTF_PARAM_PTR = 0x00004000; static const uint32 DTF_INLINE = 0x00008000; class Declaration; diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index 24550e2..2d17224 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -241,7 +241,7 @@ void InterCodeGenerator::InitGlobalVariable(InterCodeModule * mod, Declaration* } } -void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * exp) +void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* exp, GrowingArray * refvars) { int offset = 0, osize = 0; Expression* cexp = exp; @@ -257,6 +257,8 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * e uint8* d = dec->mLinkerObject->AddSpace(osize); + GrowingArray refVars(nullptr); + cexp = exp; while (cexp) { @@ -280,7 +282,7 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * e else if (aexp->mType == DT_LABEL_REF) { if (!aexp->mBase->mBase->mLinkerObject) - TranslateAssembler(mod, aexp->mBase->mBase->mValue); + TranslateAssembler(mod, aexp->mBase->mBase->mValue, nullptr); LinkerReference ref; ref.mObject = dec->mLinkerObject; @@ -344,17 +346,57 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * e case ASMIM_ZERO_PAGE_X: case ASMIM_INDIRECT_X: case ASMIM_INDIRECT_Y: - if (aexp->mFlags & DTF_PARAM_PTR) + if (aexp->mType == DT_VARIABLE_REF) { - LinkerReference ref; - ref.mObject = dec->mLinkerObject; - ref.mOffset = offset; - ref.mFlags = LREF_PARAM_PTR; - ref.mRefObject = dec->mLinkerObject; - ref.mRefOffset = 0; - dec->mLinkerObject->AddReference(ref); + if (refvars) + { + int j = 0; + while (j < refvars->Size() && (*refvars)[j] != aexp->mBase) + j++; + if (j == refvars->Size()) + refvars->Push(aexp->mBase); - offset += 1; + LinkerReference ref; + ref.mObject = dec->mLinkerObject; + ref.mOffset = offset; + ref.mFlags = LREF_TEMPORARY; + ref.mRefObject = dec->mLinkerObject; + ref.mRefOffset = j; + dec->mLinkerObject->AddReference(ref); + + d[offset++] = aexp->mOffset; + } + else + { + mErrors->Error(aexp->mLocation, EERR_ASM_INVALD_OPERAND, "Local variable outside scope"); + offset += 1; + } + } + else if (aexp->mType == DT_ARGUMENT || aexp->mType == DT_VARIABLE) + { + if (refvars) + { + int j = 0; + while (j < refvars->Size() && (*refvars)[j] != aexp) + j++; + if (j == refvars->Size()) + refvars->Push(aexp); + + LinkerReference ref; + ref.mObject = dec->mLinkerObject; + ref.mOffset = offset; + ref.mFlags = LREF_TEMPORARY; + ref.mRefObject = dec->mLinkerObject; + ref.mRefOffset = j; + dec->mLinkerObject->AddReference(ref); + + d[offset++] = 0; + } + else + { + mErrors->Error(aexp->mLocation, EERR_ASM_INVALD_OPERAND, "Local variable outside scope"); + offset += 1; + } } else d[offset++] = aexp->mInteger; @@ -373,7 +415,7 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * e if (aexp->mBase) { if (!aexp->mBase->mLinkerObject) - TranslateAssembler(mod, aexp->mBase->mValue); + TranslateAssembler(mod, aexp->mBase->mValue, nullptr); LinkerReference ref; ref.mObject = dec->mLinkerObject; @@ -391,7 +433,7 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * e else if (aexp->mType == DT_LABEL_REF) { if (!aexp->mBase->mBase->mLinkerObject) - TranslateAssembler(mod, aexp->mBase->mBase->mValue); + TranslateAssembler(mod, aexp->mBase->mBase->mValue, nullptr); LinkerReference ref; ref.mObject = dec->mLinkerObject; @@ -406,7 +448,7 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * e else if (aexp->mType == DT_CONST_ASSEMBLER) { if (!aexp->mLinkerObject) - TranslateAssembler(mod, aexp->mValue); + TranslateAssembler(mod, aexp->mValue, nullptr); LinkerReference ref; ref.mObject = dec->mLinkerObject; @@ -1860,7 +1902,9 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* case EX_ASSEMBLER: { - TranslateAssembler(proc->mModule, exp); + GrowingArray refvars(nullptr); + + TranslateAssembler(proc->mModule, exp, &refvars); Declaration* dec = exp->mDecValue; @@ -1883,6 +1927,40 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* jins->mCode = IC_ASSEMBLER; jins->mSrc[0].mType = IT_POINTER; jins->mSrc[0].mTemp = ins->mDst.mTemp; + jins->mNumOperands = 1; + + for (int i = 0; i < refvars.Size(); i++) + { + InterInstruction* vins = new InterInstruction(); + vins->mCode = IC_CONSTANT; + vins->mDst.mType = IT_POINTER; + vins->mDst.mTemp = proc->AddTemporary(ins->mDst.mType); + + Declaration* vdec = refvars[i]; + if (vdec->mType == DT_ARGUMENT) + { + vins->mMemory = IM_PARAM; + vins->mOperandSize = vdec->mSize; + vins->mIntValue = vdec->mOffset; + vins->mVarIndex = vdec->mVarIndex; + } + + block->Append(vins); + + InterInstruction* lins = new InterInstruction(); + lins->mCode = IC_LOAD; + lins->mMemory = IM_INDIRECT; + lins->mSrc[0].mType = IT_POINTER; + lins->mSrc[0].mTemp = vins->mDst.mTemp; + lins->mDst.mType = InterTypeOf(vdec->mBase); + lins->mDst.mTemp = proc->AddTemporary(lins->mDst.mType); + lins->mOperandSize = vdec->mSize; + block->Append(lins); + + jins->mSrc[jins->mNumOperands].mType = InterTypeOf(vdec->mBase); + jins->mSrc[jins->mNumOperands].mTemp = lins->mDst.mTemp; + jins->mNumOperands++; + } block->Append(jins); } @@ -2505,7 +2583,7 @@ void InterCodeGenerator::BuildInitializer(InterCodeModule * mod, uint8* dp, int else if (data->mType == DT_CONST_ASSEMBLER) { if (!data->mLinkerObject) - TranslateAssembler(mod, data->mValue); + TranslateAssembler(mod, data->mValue, nullptr); LinkerReference ref; ref.mObject = variable->mLinkerObject; diff --git a/oscar64/InterCodeGenerator.h b/oscar64/InterCodeGenerator.h index 3da75a6..29e4c12 100644 --- a/oscar64/InterCodeGenerator.h +++ b/oscar64/InterCodeGenerator.h @@ -23,7 +23,7 @@ public: bool mForceNativeCode; InterCodeProcedure* TranslateProcedure(InterCodeModule* mod, Expression* exp, Declaration * dec); - void TranslateAssembler(InterCodeModule* mod, Expression * exp); + void TranslateAssembler(InterCodeModule* mod, Expression * exp, GrowingArray * refvars); void InitGlobalVariable(InterCodeModule* mod, Declaration* dec); protected: diff --git a/oscar64/Linker.cpp b/oscar64/Linker.cpp index aa052ce..cc46ed4 100644 --- a/oscar64/Linker.cpp +++ b/oscar64/Linker.cpp @@ -12,7 +12,7 @@ LinkerSection::LinkerSection(void) {} LinkerObject::LinkerObject(void) - : mReferences(nullptr) + : mReferences(nullptr), mNumTemporaries(0) {} LinkerObject::~LinkerObject(void) @@ -285,13 +285,8 @@ void Linker::Link(void) *dp++ = raddr & 0xff; if (ref->mFlags & LREF_HIGHBYTE) *dp++ = (raddr >> 8) & 0xff; - if (ref->mFlags & LREF_PARAM_PTR) - { - if (obj->mFlags & LOBJF_NO_FRAME) - *dp++ = BC_REG_STACK; - else - *dp++ = BC_REG_LOCALS; - } + if (ref->mFlags & LREF_TEMPORARY) + *dp += obj->mTemporaries[ref->mRefOffset]; } } } diff --git a/oscar64/Linker.h b/oscar64/Linker.h index 363efc7..feadad9 100644 --- a/oscar64/Linker.h +++ b/oscar64/Linker.h @@ -50,7 +50,7 @@ public: static const uint32 LREF_LOWBYTE = 0x00000001; static const uint32 LREF_HIGHBYTE = 0x00000002; -static const uint32 LREF_PARAM_PTR = 0x00000004; +static const uint32 LREF_TEMPORARY = 0x00000004; class LinkerReference { @@ -92,6 +92,8 @@ public: uint8 * mData; InterCodeProcedure* mProc; uint32 mFlags; + uint8 mTemporaries[16], mTempSizes[16]; + int mNumTemporaries; LinkerObject(void); ~LinkerObject(void); diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index a6401d6..a907813 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -87,6 +87,14 @@ bool NativeCodeInstruction::IsUsedResultInstructions(NumberSet& requiredTemps) { requiredTemps += BC_REG_LOCALS; requiredTemps += BC_REG_LOCALS + 1; + if (mLinkerObject) + { + for (int i = 0; i < mLinkerObject->mNumTemporaries; i++) + { + for (int j = 0; j < mLinkerObject->mTempSizes[i]; j++) + requiredTemps += mLinkerObject->mTemporaries[i] + j; + } + } } return true; @@ -1968,13 +1976,20 @@ void NativeCodeInstruction::Assemble(NativeCodeBasicBlock* block) for (int i = 0; i < mLinkerObject->mReferences.Size(); i++) { LinkerReference rl = *(mLinkerObject->mReferences[i]); - rl.mOffset += pos; - if (rl.mRefObject == rl.mObject) + if (rl.mFlags & LREF_TEMPORARY) { - rl.mRefObject = nullptr; - rl.mRefOffset += pos; + block->mCode[pos + rl.mOffset] += mLinkerObject->mTemporaries[rl.mRefOffset]; + } + else + { + rl.mOffset += pos; + if (rl.mRefObject == rl.mObject) + { + rl.mRefObject = nullptr; + rl.mRefOffset += pos; + } + block->mRelocations.Push(rl); } - block->mRelocations.Push(rl); } } else @@ -2047,13 +2062,13 @@ void NativeCodeInstruction::Assemble(NativeCodeBasicBlock* block) void NativeCodeBasicBlock::PutByte(uint8 code) { - this->mCode.Insert(code); + this->mCode.Push(code); } void NativeCodeBasicBlock::PutWord(uint16 code) { - this->mCode.Insert((uint8)(code & 0xff)); - this->mCode.Insert((uint8)(code >> 8)); + this->mCode.Push((uint8)(code & 0xff)); + this->mCode.Push((uint8)(code >> 8)); } static AsmInsType InvertBranchCondition(AsmInsType code) @@ -5940,8 +5955,15 @@ void NativeCodeBasicBlock::CallFunction(InterCodeProcedure* proc, NativeCodeProc void NativeCodeBasicBlock::CallAssembler(InterCodeProcedure* proc, const InterInstruction * ins) { - if (ins->mCode == IC_ASSEMBLER && mNoFrame) - ins->mLinkerObject->mFlags |= LOBJF_NO_FRAME; + if (ins->mCode == IC_ASSEMBLER) + { + for (int i = 1; i < ins->mNumOperands; i++) + { + ins->mLinkerObject->mTemporaries[i - 1] = BC_REG_TMP + proc->mTempOffset[ins->mSrc[i].mTemp]; + ins->mLinkerObject->mTempSizes[i - 1] = InterTypeSize[ins->mSrc[i].mType]; + } + ins->mLinkerObject->mNumTemporaries = ins->mNumOperands - 1; + } assert(ins->mLinkerObject); mIns.Push(NativeCodeInstruction(ASMIT_JSR, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst, ins->mLinkerObject)); @@ -7503,7 +7525,7 @@ void NativeCodeBasicBlock::CopyCode(NativeCodeProcedure * proc, uint8* target) for (i = 0; i < mCode.Size(); i++) { - mCode.Lookup(i, target[i + mOffset]); + target[i + mOffset] = mCode[i]; } for (int i = 0; i < mRelocations.Size(); i++) @@ -7650,7 +7672,7 @@ void NativeCodeBasicBlock::CalculateOffset(int& total) } NativeCodeBasicBlock::NativeCodeBasicBlock(void) - : mIns(NativeCodeInstruction(ASMIT_INV, ASMIM_IMPLIED)), mRelocations({ 0 }), mEntryBlocks(nullptr) + : mIns(NativeCodeInstruction(ASMIT_INV, ASMIM_IMPLIED)), mRelocations({ 0 }), mEntryBlocks(nullptr), mCode(0) { mTrueJump = mFalseJump = NULL; mOffset = 0x7fffffff; diff --git a/oscar64/NativeCodeGenerator.h b/oscar64/NativeCodeGenerator.h index f891aac..c816e0e 100644 --- a/oscar64/NativeCodeGenerator.h +++ b/oscar64/NativeCodeGenerator.h @@ -81,7 +81,7 @@ public: NativeCodeBasicBlock(void); ~NativeCodeBasicBlock(void); - DynamicArray mCode; + GrowingArray mCode; int mIndex; NativeCodeBasicBlock* mTrueJump, * mFalseJump, * mFromJump; diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index f7fbb41..f8cfcf6 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -1896,10 +1896,6 @@ Expression* Parser::ParseAssemblerBaseOperand(void) exp = new Expression(mScanner->mLocation, EX_CONSTANT); if (dec->mType == DT_ARGUMENT) { - Declaration* ndec = new Declaration(exp->mLocation, DT_CONST_INTEGER); - ndec->mBase = TheUnsignedIntTypeDeclaration; - ndec->mInteger = 2 + dec->mVarIndex; - dec = ndec; exp->mDecType = TheUnsignedIntTypeDeclaration; } else if (dec->mType == DT_CONST_ASSEMBLER) @@ -2171,14 +2167,6 @@ Expression* Parser::ParseAssembler(void) mScanner->SetAssemblerMode(true); - Declaration* decfp = new Declaration(mScanner->mLocation, DT_CONST_INTEGER); - decfp->mIdent = Ident::Unique("fp"); - decfp->mBase = TheUnsignedIntTypeDeclaration; - decfp->mSize = 2; - decfp->mInteger = BC_REG_LOCALS; - decfp->mFlags = DTF_PARAM_PTR; - mScope->Insert(decfp->mIdent, decfp); - Declaration* decaccu = new Declaration(mScanner->mLocation, DT_CONST_INTEGER); decaccu->mIdent = Ident::Unique("accu"); decaccu->mBase = TheUnsignedIntTypeDeclaration; @@ -2314,14 +2302,20 @@ Expression* Parser::ParseAssembler(void) } } - if (ilast->mLeft && ilast->mLeft->mDecValue && ilast->mLeft->mDecValue->mType == DT_CONST_INTEGER && ilast->mLeft->mDecValue->mInteger < 256) + if (ilast->mLeft && ilast->mLeft->mDecValue) { - if (ilast->mAsmInsMode == ASMIM_ABSOLUTE && HasAsmInstructionMode(ilast->mAsmInsType, ASMIM_ZERO_PAGE)) - ilast->mAsmInsMode = ASMIM_ZERO_PAGE; - else if (ilast->mAsmInsMode == ASMIM_ABSOLUTE_X && HasAsmInstructionMode(ilast->mAsmInsType, ASMIM_ZERO_PAGE_X)) - ilast->mAsmInsMode = ASMIM_ZERO_PAGE_X; - else if (ilast->mAsmInsMode == ASMIM_ABSOLUTE_Y && HasAsmInstructionMode(ilast->mAsmInsType, ASMIM_ZERO_PAGE_Y)) - ilast->mAsmInsMode = ASMIM_ZERO_PAGE_Y; + if ((ilast->mLeft->mDecValue->mType == DT_CONST_INTEGER && ilast->mLeft->mDecValue->mInteger < 256) || + (ilast->mLeft->mDecValue->mType == DT_VARIABLE_REF && !(ilast->mLeft->mDecValue->mBase->mFlags & DTF_GLOBAL)) || + (ilast->mLeft->mDecValue->mType == DT_VARIABLE && !(ilast->mLeft->mDecValue->mFlags & DTF_GLOBAL)) || + ilast->mLeft->mDecValue->mType == DT_ARGUMENT) + { + if (ilast->mAsmInsMode == ASMIM_ABSOLUTE && HasAsmInstructionMode(ilast->mAsmInsType, ASMIM_ZERO_PAGE)) + ilast->mAsmInsMode = ASMIM_ZERO_PAGE; + else if (ilast->mAsmInsMode == ASMIM_ABSOLUTE_X && HasAsmInstructionMode(ilast->mAsmInsType, ASMIM_ZERO_PAGE_X)) + ilast->mAsmInsMode = ASMIM_ZERO_PAGE_X; + else if (ilast->mAsmInsMode == ASMIM_ABSOLUTE_Y && HasAsmInstructionMode(ilast->mAsmInsType, ASMIM_ZERO_PAGE_Y)) + ilast->mAsmInsMode = ASMIM_ZERO_PAGE_Y; + } } if (ilast->mAsmInsType == ASMIT_BYTE)