diff --git a/oscar64/Compiler.cpp b/oscar64/Compiler.cpp index ddffc9e..040f200 100644 --- a/oscar64/Compiler.cpp +++ b/oscar64/Compiler.cpp @@ -174,13 +174,13 @@ void Compiler::RegisterRuntime(const Location & loc, const Ident* ident) if (bcdec->mType == DT_CONST_ASSEMBLER) { if (!bcdec->mLinkerObject) - mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue, nullptr); + mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec, nullptr); linkerObject = bcdec->mLinkerObject; } else if (bcdec->mType == DT_LABEL) { if (!bcdec->mBase->mLinkerObject) - mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase->mValue, nullptr); + mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase, nullptr); linkerObject = bcdec->mBase->mLinkerObject; offset = int(bcdec->mInteger); @@ -910,7 +910,7 @@ bool Compiler::GenerateCode(void) if (mCompilerOptions & COPT_VERBOSE) printf("Generate intermediate code\n"); - mInterCodeGenerator->TranslateAssembler(mInterCodeModule, dcrtstart->mValue, nullptr); + mInterCodeGenerator->TranslateAssembler(mInterCodeModule, dcrtstart, nullptr); for (int i = 0; i < mCompilationUnits->mReferenced.Size(); i++) { Declaration* dec = mCompilationUnits->mReferenced[i]; @@ -993,7 +993,7 @@ bool Compiler::GenerateCode(void) if (bcdec->mType == DT_CONST_ASSEMBLER) { if (!bcdec->mLinkerObject) - mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue, nullptr); + mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec, nullptr); mByteCodeGenerator->mExtByteCodes[i] = bcdec->mLinkerObject; } } @@ -1068,13 +1068,13 @@ bool Compiler::GenerateCode(void) if (bcdec->mType == DT_CONST_ASSEMBLER) { if (!bcdec->mLinkerObject) - mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue, nullptr); + mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec, nullptr); linkerObject = bcdec->mLinkerObject; } else if (bcdec->mType == DT_LABEL) { if (!bcdec->mBase->mLinkerObject) - mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase->mValue, nullptr); + mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase, nullptr); linkerObject = bcdec->mBase->mLinkerObject; offset = int(bcdec->mInteger); } diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index d5a712b..6004d88 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -825,16 +825,46 @@ void InterCodeGenerator::InitGlobalVariable(InterCodeModule * mod, Declaration* } } -void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* exp, GrowingArray * refvars) +void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Declaration * adec,GrowingArray * refvars) { - int offset = 0, osize = 0; + Expression* exp = adec->mValue; + + GrowingArray offsetMap(-1); + + int offset = 0, osize = 0, rsize = 0; Expression* cexp = exp; while (cexp) { + offsetMap[rsize] = osize; + rsize += AsmInsSize(cexp->mAsmInsType, cexp->mAsmInsMode); +#if 1 + Declaration* aexp = nullptr; + if (cexp->mLeft) + aexp = cexp->mLeft->mDecValue; + + if (cexp->mAsmInsMode == ASMIM_ABSOLUTE && HasAsmInstructionMode(cexp->mAsmInsType, ASMIM_ZERO_PAGE) && aexp->mType == DT_VARIABLE && (aexp->mFlags & DTF_GLOBAL) && (aexp->mFlags & DTF_ZEROPAGE)) + { + cexp->mAsmInsMode = ASMIM_ZERO_PAGE; + } + else if (cexp->mAsmInsMode == ASMIM_ABSOLUTE && HasAsmInstructionMode(cexp->mAsmInsType, ASMIM_ZERO_PAGE) && aexp->mType == DT_VARIABLE_REF && (aexp->mBase->mFlags & DTF_GLOBAL) && (aexp->mBase->mFlags & DTF_ZEROPAGE)) + { + cexp->mAsmInsMode = ASMIM_ZERO_PAGE; + } +#endif + osize += AsmInsSize(cexp->mAsmInsType, cexp->mAsmInsMode); cexp = cexp->mRight; } + // Check if remapping of lables due to operand address size change + if (osize != rsize) + { + adec->mBase->mScope->Iterate([=](const Ident* ident, Declaration* dec) { + if (dec->mType == DT_LABEL) + dec->mInteger = offsetMap[int(dec->mInteger)]; + }); + } + Declaration* dec = exp->mDecValue; dec->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mQualIdent, dec->mSection, LOT_NATIVE_CODE, dec->mAlignment); @@ -846,16 +876,16 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex cexp = exp; while (cexp) { + Declaration* aexp = nullptr; + if (cexp->mLeft) + aexp = cexp->mLeft->mDecValue; + if (cexp->mAsmInsType != ASMIT_BYTE) { int opcode = AsmInsOpcodes[cexp->mAsmInsType][cexp->mAsmInsMode]; d[offset++] = opcode; } - Declaration* aexp = nullptr; - if (cexp->mLeft) - aexp = cexp->mLeft->mDecValue; - switch (cexp->mAsmInsMode) { case ASMIM_IMPLIED: @@ -870,7 +900,7 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex if (aexp->mBase->mBase) { if (!aexp->mBase->mBase->mLinkerObject) - TranslateAssembler(mod, aexp->mBase->mBase->mValue, nullptr); + TranslateAssembler(mod, aexp->mBase->mBase, nullptr); LinkerReference ref; ref.mObject = dec->mLinkerObject; @@ -977,7 +1007,20 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex mErrors->Error(cexp->mLocation, EERR_ASM_INVALD_OPERAND, "Missing assembler operand"); else if (aexp->mType == DT_VARIABLE_REF) { - if (refvars) + if (aexp->mBase->mFlags & DTF_GLOBAL) + { + InitGlobalVariable(mod, aexp->mBase); + + LinkerReference ref; + ref.mObject = dec->mLinkerObject; + ref.mOffset = offset; + ref.mFlags = LREF_LOWBYTE; + ref.mRefObject = aexp->mBase->mLinkerObject; + ref.mRefOffset = aexp->mOffset; + ref.mRefObject->mFlags |= LOBJF_RELEVANT; + dec->mLinkerObject->AddReference(ref); + } + else if (refvars) { int j = 0; while (j < refvars->Size() && (*refvars)[j] != aexp->mBase) @@ -1056,7 +1099,7 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex if (aexp->mBase) { if (!aexp->mBase->mLinkerObject) - TranslateAssembler(mod, aexp->mBase->mValue, nullptr); + TranslateAssembler(mod, aexp->mBase, nullptr); LinkerReference ref; ref.mObject = dec->mLinkerObject; @@ -1075,7 +1118,7 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex if (aexp->mBase->mBase) { if (!aexp->mBase->mBase->mLinkerObject) - TranslateAssembler(mod, aexp->mBase->mBase->mValue, nullptr); + TranslateAssembler(mod, aexp->mBase->mBase, nullptr); LinkerReference ref; ref.mObject = dec->mLinkerObject; @@ -1092,7 +1135,7 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex else if (aexp->mType == DT_CONST_ASSEMBLER) { if (!aexp->mLinkerObject) - TranslateAssembler(mod, aexp->mValue, nullptr); + TranslateAssembler(mod, aexp, nullptr); LinkerReference ref; ref.mObject = dec->mLinkerObject; @@ -1203,7 +1246,7 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex cexp = cexp->mRight; } - assert(offset == osize); + assert(offset < osize); } void InterCodeGenerator::BuildSwitchTree(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock* block, InlineMapper * inlineMapper, ExValue v, const SwitchNodeArray& nodes, int left, int right, int vleft, int vright, InterCodeBasicBlock* dblock) @@ -2234,7 +2277,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* case DT_CONST_ASSEMBLER: { if (!dec->mLinkerObject) - TranslateAssembler(proc->mModule, dec->mValue, nullptr); + TranslateAssembler(proc->mModule, dec, nullptr); InterInstruction* ins = new InterInstruction(MapLocation(exp, inlineMapper), IC_CONSTANT); ins->mDst.mType = IT_POINTER; @@ -2251,7 +2294,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* case DT_LABEL: { if (!dec->mBase->mLinkerObject) - TranslateAssembler(proc->mModule, dec->mBase->mValue, nullptr); + TranslateAssembler(proc->mModule, dec->mBase, nullptr); InterInstruction* ins = new InterInstruction(MapLocation(exp, inlineMapper), IC_CONSTANT); ins->mDst.mType = IT_POINTER; @@ -4222,7 +4265,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* { GrowingArray refvars(nullptr); - TranslateAssembler(proc->mModule, exp, &refvars); + TranslateAssembler(proc->mModule, exp->mDecValue, &refvars); Declaration* dec = exp->mDecValue; @@ -5627,7 +5670,7 @@ void InterCodeGenerator::BuildInitializer(InterCodeModule * mod, uint8* dp, int else if (data->mType == DT_CONST_ASSEMBLER) { if (!data->mLinkerObject) - TranslateAssembler(mod, data->mValue, nullptr); + TranslateAssembler(mod, data, nullptr); LinkerReference ref; ref.mObject = variable->mLinkerObject; diff --git a/oscar64/InterCodeGenerator.h b/oscar64/InterCodeGenerator.h index 4a203d4..55cfe04 100644 --- a/oscar64/InterCodeGenerator.h +++ b/oscar64/InterCodeGenerator.h @@ -45,7 +45,7 @@ public: uint64 mCompilerOptions; InterCodeProcedure* TranslateProcedure(InterCodeModule* mod, Expression* exp, Declaration * dec); - void TranslateAssembler(InterCodeModule* mod, Expression * exp, GrowingArray * refvars); + void TranslateAssembler(InterCodeModule* mod, Declaration* adec,GrowingArray * refvars); void InitGlobalVariable(InterCodeModule* mod, Declaration* dec); void InitLocalVariable(InterCodeProcedure* proc, Declaration* dec, int index); void InitParameter(InterCodeProcedure* proc, Declaration* dec, int index); diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index e2e7754..225f06e 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -14021,6 +14021,11 @@ NativeCodeInstruction NativeCodeBasicBlock::DecodeNative(const InterInstruction* address = lobj->mData[offset++]; if (lref && (lref->mFlags & LREF_TEMPORARY)) address += lobj->mTemporaries[lref->mRefOffset]; + else if (lref) + { + linkerObject = lref->mRefObject; + address = lref->mRefOffset; + } else if (address >= BC_REG_TMP) flags |= NCIF_VOLATILE; break; @@ -14124,6 +14129,11 @@ void NativeCodeBasicBlock::CallAssembler(InterCodeProcedure* proc, NativeCodePro if (dins.mMode == ASMIM_ZERO_PAGE && dins.mAddress >= BC_REG_WORK && dins.mAddress < BC_REG_WORK + 8) uflags |= NICF_USE_WORKREGS; + + // Make sure we are not aliasing zeropage globals + if (dins.mMode == ASMIM_ZERO_PAGE && dins.mLinkerObject) + dins.mMode = ASMIM_ABSOLUTE; + if (dins.ChangesAccu()) uflags |= NCIF_USE_CPU_REG_A; if (dins.ChangesXReg())