Prepare access to local variables in inline assembler

This commit is contained in:
drmortalwombat 2021-10-07 10:42:18 +02:00
parent df152c2f9b
commit fb4ae26afb
11 changed files with 179 additions and 65 deletions

View File

@ -1899,6 +1899,27 @@ void ByteCodeBasicBlock::CallFunction(InterCodeProcedure* proc, const InterInstr
} }
void ByteCodeBasicBlock::CallAssembler(InterCodeProcedure* proc, const InterInstruction * ins) 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) if (ins->mSrc[0].mTemp < 0)
{ {
@ -2879,6 +2900,8 @@ void ByteCodeBasicBlock::Compile(InterCodeProcedure* iproc, ByteCodeProcedure* p
CallFunction(iproc, ins); CallFunction(iproc, ins);
break; break;
case IC_CALL_NATIVE: case IC_CALL_NATIVE:
CallNative(iproc, ins);
break;
case IC_ASSEMBLER: case IC_ASSEMBLER:
CallAssembler(iproc, ins); CallAssembler(iproc, ins);
break; break;

View File

@ -261,6 +261,7 @@ public:
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);
void CallNative(InterCodeProcedure* proc, const InterInstruction* ins);
void BinaryOperator(InterCodeProcedure* proc, const InterInstruction * ins); void BinaryOperator(InterCodeProcedure* proc, const InterInstruction * ins);
void UnaryOperator(InterCodeProcedure* proc, const InterInstruction * ins); void UnaryOperator(InterCodeProcedure* proc, const InterInstruction * ins);
void BinaryRROperator(InterCodeProcedure* proc, const InterInstruction * ins); void BinaryRROperator(InterCodeProcedure* proc, const InterInstruction * ins);

View File

@ -83,13 +83,13 @@ void Compiler::RegisterRuntime(const Location & loc, const Ident* ident)
if (bcdec->mType == DT_CONST_ASSEMBLER) if (bcdec->mType == DT_CONST_ASSEMBLER)
{ {
if (!bcdec->mLinkerObject) if (!bcdec->mLinkerObject)
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue); mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue, nullptr);
linkerObject = bcdec->mLinkerObject; linkerObject = bcdec->mLinkerObject;
} }
else if (bcdec->mType == DT_LABEL) else if (bcdec->mType == DT_LABEL)
{ {
if (!bcdec->mBase->mLinkerObject) if (!bcdec->mBase->mLinkerObject)
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase->mValue); mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase->mValue, nullptr);
linkerObject = bcdec->mBase->mLinkerObject; linkerObject = bcdec->mBase->mLinkerObject;
offset = bcdec->mInteger; offset = bcdec->mInteger;
@ -157,7 +157,7 @@ bool Compiler::GenerateCode(void)
dcrtstart->mSection = sectionStartup; dcrtstart->mSection = sectionStartup;
mInterCodeGenerator->mForceNativeCode = mNativeCode; mInterCodeGenerator->mForceNativeCode = mNativeCode;
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, dcrtstart->mValue); mInterCodeGenerator->TranslateAssembler(mInterCodeModule, dcrtstart->mValue, nullptr);
if (mErrors->mErrorCount != 0) if (mErrors->mErrorCount != 0)
return false; return false;
@ -201,7 +201,7 @@ bool Compiler::GenerateCode(void)
if (bcdec->mType == DT_CONST_ASSEMBLER) if (bcdec->mType == DT_CONST_ASSEMBLER)
{ {
if (!bcdec->mLinkerObject) if (!bcdec->mLinkerObject)
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue); mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue, nullptr);
mByteCodeGenerator->mExtByteCodes[i] = bcdec->mLinkerObject; mByteCodeGenerator->mExtByteCodes[i] = bcdec->mLinkerObject;
} }
} }
@ -252,13 +252,13 @@ bool Compiler::GenerateCode(void)
if (bcdec->mType == DT_CONST_ASSEMBLER) if (bcdec->mType == DT_CONST_ASSEMBLER)
{ {
if (!bcdec->mLinkerObject) if (!bcdec->mLinkerObject)
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue); mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue, nullptr);
linkerObject = bcdec->mLinkerObject; linkerObject = bcdec->mLinkerObject;
} }
else if (bcdec->mType == DT_LABEL) else if (bcdec->mType == DT_LABEL)
{ {
if (!bcdec->mBase->mLinkerObject) if (!bcdec->mBase->mLinkerObject)
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase->mValue); mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase->mValue, nullptr);
linkerObject = bcdec->mBase->mLinkerObject; linkerObject = bcdec->mBase->mLinkerObject;
offset = bcdec->mInteger; offset = bcdec->mInteger;
} }

View File

@ -61,7 +61,6 @@ static const uint32 DTF_UPPER_BYTE = 0x00000400;
static const uint32 DTF_LOWER_BYTE = 0x00000800; static const uint32 DTF_LOWER_BYTE = 0x00000800;
static const uint32 DTF_SECTION_START = 0x00001000; static const uint32 DTF_SECTION_START = 0x00001000;
static const uint32 DTF_SECTION_END = 0x00002000; static const uint32 DTF_SECTION_END = 0x00002000;
static const uint32 DTF_PARAM_PTR = 0x00004000;
static const uint32 DTF_INLINE = 0x00008000; static const uint32 DTF_INLINE = 0x00008000;
class Declaration; class Declaration;

View File

@ -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<Declaration*> * refvars)
{ {
int offset = 0, osize = 0; int offset = 0, osize = 0;
Expression* cexp = exp; Expression* cexp = exp;
@ -257,6 +257,8 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * e
uint8* d = dec->mLinkerObject->AddSpace(osize); uint8* d = dec->mLinkerObject->AddSpace(osize);
GrowingArray<Declaration*> refVars(nullptr);
cexp = exp; cexp = exp;
while (cexp) while (cexp)
{ {
@ -280,7 +282,7 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * e
else if (aexp->mType == DT_LABEL_REF) else if (aexp->mType == DT_LABEL_REF)
{ {
if (!aexp->mBase->mBase->mLinkerObject) if (!aexp->mBase->mBase->mLinkerObject)
TranslateAssembler(mod, aexp->mBase->mBase->mValue); TranslateAssembler(mod, aexp->mBase->mBase->mValue, nullptr);
LinkerReference ref; LinkerReference ref;
ref.mObject = dec->mLinkerObject; ref.mObject = dec->mLinkerObject;
@ -344,17 +346,57 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * e
case ASMIM_ZERO_PAGE_X: case ASMIM_ZERO_PAGE_X:
case ASMIM_INDIRECT_X: case ASMIM_INDIRECT_X:
case ASMIM_INDIRECT_Y: case ASMIM_INDIRECT_Y:
if (aexp->mFlags & DTF_PARAM_PTR) if (aexp->mType == DT_VARIABLE_REF)
{ {
LinkerReference ref; if (refvars)
ref.mObject = dec->mLinkerObject; {
ref.mOffset = offset; int j = 0;
ref.mFlags = LREF_PARAM_PTR; while (j < refvars->Size() && (*refvars)[j] != aexp->mBase)
ref.mRefObject = dec->mLinkerObject; j++;
ref.mRefOffset = 0; if (j == refvars->Size())
dec->mLinkerObject->AddReference(ref); 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 else
d[offset++] = aexp->mInteger; d[offset++] = aexp->mInteger;
@ -373,7 +415,7 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * e
if (aexp->mBase) if (aexp->mBase)
{ {
if (!aexp->mBase->mLinkerObject) if (!aexp->mBase->mLinkerObject)
TranslateAssembler(mod, aexp->mBase->mValue); TranslateAssembler(mod, aexp->mBase->mValue, nullptr);
LinkerReference ref; LinkerReference ref;
ref.mObject = dec->mLinkerObject; ref.mObject = dec->mLinkerObject;
@ -391,7 +433,7 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * e
else if (aexp->mType == DT_LABEL_REF) else if (aexp->mType == DT_LABEL_REF)
{ {
if (!aexp->mBase->mBase->mLinkerObject) if (!aexp->mBase->mBase->mLinkerObject)
TranslateAssembler(mod, aexp->mBase->mBase->mValue); TranslateAssembler(mod, aexp->mBase->mBase->mValue, nullptr);
LinkerReference ref; LinkerReference ref;
ref.mObject = dec->mLinkerObject; ref.mObject = dec->mLinkerObject;
@ -406,7 +448,7 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * e
else if (aexp->mType == DT_CONST_ASSEMBLER) else if (aexp->mType == DT_CONST_ASSEMBLER)
{ {
if (!aexp->mLinkerObject) if (!aexp->mLinkerObject)
TranslateAssembler(mod, aexp->mValue); TranslateAssembler(mod, aexp->mValue, nullptr);
LinkerReference ref; LinkerReference ref;
ref.mObject = dec->mLinkerObject; ref.mObject = dec->mLinkerObject;
@ -1860,7 +1902,9 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
case EX_ASSEMBLER: case EX_ASSEMBLER:
{ {
TranslateAssembler(proc->mModule, exp); GrowingArray<Declaration*> refvars(nullptr);
TranslateAssembler(proc->mModule, exp, &refvars);
Declaration* dec = exp->mDecValue; Declaration* dec = exp->mDecValue;
@ -1883,6 +1927,40 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
jins->mCode = IC_ASSEMBLER; jins->mCode = IC_ASSEMBLER;
jins->mSrc[0].mType = IT_POINTER; jins->mSrc[0].mType = IT_POINTER;
jins->mSrc[0].mTemp = ins->mDst.mTemp; 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); block->Append(jins);
} }
@ -2505,7 +2583,7 @@ void InterCodeGenerator::BuildInitializer(InterCodeModule * mod, uint8* dp, int
else if (data->mType == DT_CONST_ASSEMBLER) else if (data->mType == DT_CONST_ASSEMBLER)
{ {
if (!data->mLinkerObject) if (!data->mLinkerObject)
TranslateAssembler(mod, data->mValue); TranslateAssembler(mod, data->mValue, nullptr);
LinkerReference ref; LinkerReference ref;
ref.mObject = variable->mLinkerObject; ref.mObject = variable->mLinkerObject;

View File

@ -23,7 +23,7 @@ public:
bool mForceNativeCode; bool mForceNativeCode;
InterCodeProcedure* TranslateProcedure(InterCodeModule* mod, Expression* exp, Declaration * dec); InterCodeProcedure* TranslateProcedure(InterCodeModule* mod, Expression* exp, Declaration * dec);
void TranslateAssembler(InterCodeModule* mod, Expression * exp); void TranslateAssembler(InterCodeModule* mod, Expression * exp, GrowingArray<Declaration *> * refvars);
void InitGlobalVariable(InterCodeModule* mod, Declaration* dec); void InitGlobalVariable(InterCodeModule* mod, Declaration* dec);
protected: protected:

View File

@ -12,7 +12,7 @@ LinkerSection::LinkerSection(void)
{} {}
LinkerObject::LinkerObject(void) LinkerObject::LinkerObject(void)
: mReferences(nullptr) : mReferences(nullptr), mNumTemporaries(0)
{} {}
LinkerObject::~LinkerObject(void) LinkerObject::~LinkerObject(void)
@ -285,13 +285,8 @@ void Linker::Link(void)
*dp++ = raddr & 0xff; *dp++ = raddr & 0xff;
if (ref->mFlags & LREF_HIGHBYTE) if (ref->mFlags & LREF_HIGHBYTE)
*dp++ = (raddr >> 8) & 0xff; *dp++ = (raddr >> 8) & 0xff;
if (ref->mFlags & LREF_PARAM_PTR) if (ref->mFlags & LREF_TEMPORARY)
{ *dp += obj->mTemporaries[ref->mRefOffset];
if (obj->mFlags & LOBJF_NO_FRAME)
*dp++ = BC_REG_STACK;
else
*dp++ = BC_REG_LOCALS;
}
} }
} }
} }

View File

@ -50,7 +50,7 @@ public:
static const uint32 LREF_LOWBYTE = 0x00000001; static const uint32 LREF_LOWBYTE = 0x00000001;
static const uint32 LREF_HIGHBYTE = 0x00000002; static const uint32 LREF_HIGHBYTE = 0x00000002;
static const uint32 LREF_PARAM_PTR = 0x00000004; static const uint32 LREF_TEMPORARY = 0x00000004;
class LinkerReference class LinkerReference
{ {
@ -92,6 +92,8 @@ public:
uint8 * mData; uint8 * mData;
InterCodeProcedure* mProc; InterCodeProcedure* mProc;
uint32 mFlags; uint32 mFlags;
uint8 mTemporaries[16], mTempSizes[16];
int mNumTemporaries;
LinkerObject(void); LinkerObject(void);
~LinkerObject(void); ~LinkerObject(void);

View File

@ -87,6 +87,14 @@ bool NativeCodeInstruction::IsUsedResultInstructions(NumberSet& requiredTemps)
{ {
requiredTemps += BC_REG_LOCALS; requiredTemps += BC_REG_LOCALS;
requiredTemps += BC_REG_LOCALS + 1; 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; return true;
@ -1968,13 +1976,20 @@ void NativeCodeInstruction::Assemble(NativeCodeBasicBlock* block)
for (int i = 0; i < mLinkerObject->mReferences.Size(); i++) for (int i = 0; i < mLinkerObject->mReferences.Size(); i++)
{ {
LinkerReference rl = *(mLinkerObject->mReferences[i]); LinkerReference rl = *(mLinkerObject->mReferences[i]);
rl.mOffset += pos; if (rl.mFlags & LREF_TEMPORARY)
if (rl.mRefObject == rl.mObject)
{ {
rl.mRefObject = nullptr; block->mCode[pos + rl.mOffset] += mLinkerObject->mTemporaries[rl.mRefOffset];
rl.mRefOffset += pos; }
else
{
rl.mOffset += pos;
if (rl.mRefObject == rl.mObject)
{
rl.mRefObject = nullptr;
rl.mRefOffset += pos;
}
block->mRelocations.Push(rl);
} }
block->mRelocations.Push(rl);
} }
} }
else else
@ -2047,13 +2062,13 @@ void NativeCodeInstruction::Assemble(NativeCodeBasicBlock* block)
void NativeCodeBasicBlock::PutByte(uint8 code) void NativeCodeBasicBlock::PutByte(uint8 code)
{ {
this->mCode.Insert(code); this->mCode.Push(code);
} }
void NativeCodeBasicBlock::PutWord(uint16 code) void NativeCodeBasicBlock::PutWord(uint16 code)
{ {
this->mCode.Insert((uint8)(code & 0xff)); this->mCode.Push((uint8)(code & 0xff));
this->mCode.Insert((uint8)(code >> 8)); this->mCode.Push((uint8)(code >> 8));
} }
static AsmInsType InvertBranchCondition(AsmInsType code) static AsmInsType InvertBranchCondition(AsmInsType code)
@ -5940,8 +5955,15 @@ void NativeCodeBasicBlock::CallFunction(InterCodeProcedure* proc, NativeCodeProc
void NativeCodeBasicBlock::CallAssembler(InterCodeProcedure* proc, const InterInstruction * ins) void NativeCodeBasicBlock::CallAssembler(InterCodeProcedure* proc, const InterInstruction * ins)
{ {
if (ins->mCode == IC_ASSEMBLER && mNoFrame) if (ins->mCode == IC_ASSEMBLER)
ins->mLinkerObject->mFlags |= LOBJF_NO_FRAME; {
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); assert(ins->mLinkerObject);
mIns.Push(NativeCodeInstruction(ASMIT_JSR, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst, 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++) 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++) for (int i = 0; i < mRelocations.Size(); i++)
@ -7650,7 +7672,7 @@ void NativeCodeBasicBlock::CalculateOffset(int& total)
} }
NativeCodeBasicBlock::NativeCodeBasicBlock(void) 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; mTrueJump = mFalseJump = NULL;
mOffset = 0x7fffffff; mOffset = 0x7fffffff;

View File

@ -81,7 +81,7 @@ public:
NativeCodeBasicBlock(void); NativeCodeBasicBlock(void);
~NativeCodeBasicBlock(void); ~NativeCodeBasicBlock(void);
DynamicArray<uint8> mCode; GrowingArray<uint8> mCode;
int mIndex; int mIndex;
NativeCodeBasicBlock* mTrueJump, * mFalseJump, * mFromJump; NativeCodeBasicBlock* mTrueJump, * mFalseJump, * mFromJump;

View File

@ -1896,10 +1896,6 @@ Expression* Parser::ParseAssemblerBaseOperand(void)
exp = new Expression(mScanner->mLocation, EX_CONSTANT); exp = new Expression(mScanner->mLocation, EX_CONSTANT);
if (dec->mType == DT_ARGUMENT) 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; exp->mDecType = TheUnsignedIntTypeDeclaration;
} }
else if (dec->mType == DT_CONST_ASSEMBLER) else if (dec->mType == DT_CONST_ASSEMBLER)
@ -2171,14 +2167,6 @@ Expression* Parser::ParseAssembler(void)
mScanner->SetAssemblerMode(true); 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); Declaration* decaccu = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
decaccu->mIdent = Ident::Unique("accu"); decaccu->mIdent = Ident::Unique("accu");
decaccu->mBase = TheUnsignedIntTypeDeclaration; 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)) if ((ilast->mLeft->mDecValue->mType == DT_CONST_INTEGER && ilast->mLeft->mDecValue->mInteger < 256) ||
ilast->mAsmInsMode = ASMIM_ZERO_PAGE; (ilast->mLeft->mDecValue->mType == DT_VARIABLE_REF && !(ilast->mLeft->mDecValue->mBase->mFlags & DTF_GLOBAL)) ||
else if (ilast->mAsmInsMode == ASMIM_ABSOLUTE_X && HasAsmInstructionMode(ilast->mAsmInsType, ASMIM_ZERO_PAGE_X)) (ilast->mLeft->mDecValue->mType == DT_VARIABLE && !(ilast->mLeft->mDecValue->mFlags & DTF_GLOBAL)) ||
ilast->mAsmInsMode = ASMIM_ZERO_PAGE_X; ilast->mLeft->mDecValue->mType == DT_ARGUMENT)
else if (ilast->mAsmInsMode == ASMIM_ABSOLUTE_Y && HasAsmInstructionMode(ilast->mAsmInsType, ASMIM_ZERO_PAGE_Y)) {
ilast->mAsmInsMode = ASMIM_ZERO_PAGE_Y; 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) if (ilast->mAsmInsType == ASMIT_BYTE)