Improve zero page addressing of global variables in inline assembler
This commit is contained in:
parent
907452d918
commit
803b868356
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -825,16 +825,46 @@ void InterCodeGenerator::InitGlobalVariable(InterCodeModule * mod, Declaration*
|
|||
}
|
||||
}
|
||||
|
||||
void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* exp, GrowingArray<Declaration*> * refvars)
|
||||
void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Declaration * adec,GrowingArray<Declaration*> * refvars)
|
||||
{
|
||||
int offset = 0, osize = 0;
|
||||
Expression* exp = adec->mValue;
|
||||
|
||||
GrowingArray<int> 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<Declaration*> 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;
|
||||
|
|
|
@ -45,7 +45,7 @@ public:
|
|||
uint64 mCompilerOptions;
|
||||
|
||||
InterCodeProcedure* TranslateProcedure(InterCodeModule* mod, Expression* exp, Declaration * dec);
|
||||
void TranslateAssembler(InterCodeModule* mod, Expression * exp, GrowingArray<Declaration *> * refvars);
|
||||
void TranslateAssembler(InterCodeModule* mod, Declaration* adec,GrowingArray<Declaration *> * refvars);
|
||||
void InitGlobalVariable(InterCodeModule* mod, Declaration* dec);
|
||||
void InitLocalVariable(InterCodeProcedure* proc, Declaration* dec, int index);
|
||||
void InitParameter(InterCodeProcedure* proc, Declaration* dec, int index);
|
||||
|
|
|
@ -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())
|
||||
|
|
Loading…
Reference in New Issue